Can you add a menu to the top, right corner:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Realistic Rope Physics with HTML Elements</title>
  <style>
    /* Basic Reset */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    /* Body Styling */
    body {
      width: 100vw;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #222;
    }

    /* Container Styling */
    .container {
      position: relative;
      width: 800px;
      height: 600px;
      background-color: #444;
      border: 2px solid #555;
      border-radius: 10px;
      overflow: hidden;
    }

    /* SVG Styling */
    .rope-svg {
      position: absolute;
      top: 0;
      left: 0;
      pointer-events: none; /* Allow interactions to pass through */
      width: 100%;
      height: 100%;
      z-index: 1; /* Ensure SVG is below the dots */
    }

    /* Draggable Dots Styling */
    .dot {
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background-color: #f00;
      position: absolute;
      cursor: grab;
      transform: translate(-50%, -50%);
      transition: background-color 0.2s;
      z-index: 10; /* Ensure dots are on top */
      pointer-events: all; /* Enable mouse events */
    }

    .dot:hover {
      background-color: #ff5555;
    }

    .dot:active {
      cursor: grabbing;
      background-color: #ff0000;
    }

    #dot1 {
      left: 200px;
      top: 150px;
    }

    #dot2 {
      left: 600px;
      top: 150px;
    }

    /* Rope Nodes Styling */
    .node {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background-color: #fff;
      position: absolute;
      transform: translate(-50%, -50%);
      pointer-events: none; /* Prevent interference with dragging */
      display: none; /* Hide the nodes to prevent "skeleton" appearance */
    }
  </style>
</head>
<body>
  <div class="container">
    <svg class="rope-svg" width="100%" height="100%">
      <!-- Lines between nodes will be dynamically added here -->
    </svg>
    <div class="dot" id="dot1"></div>
    <div class="dot" id="dot2"></div>
    <!-- Rope nodes will be dynamically added here -->
  </div>

  <script>
    // Select Elements
    const container = document.querySelector('.container');
    const ropeSVG = document.querySelector('.rope-svg');
    const dot1 = document.getElementById('dot1');
    const dot2 = document.getElementById('dot2');

    // Physics Parameters
    const gravity = 0.5;          // Acceleration due to gravity
    const friction = 0.99;        // Friction for damping
    const constraintsIterations = 5; // Number of constraint solver iterations per frame

    // Rope Parameters
    const numSegments = 30;       // Number of segments (nodes - 1)
    const segmentLength = 20;     // Desired length between nodes in pixels

    // Node Class using Verlet Integration
    class Node {
      constructor(x, y, pinned = false) {
        this.x = x;              // Current X position
        this.y = y;              // Current Y position
        this.oldX = x;           // Previous X position
        this.oldY = y;           // Previous Y position
        this.pinned = pinned;    // If true, node position is fixed
        this.element = null;     // Corresponding HTML element (optional visualization)
      }

      update() {
        if (this.pinned && !this.isBeingDragged) return;

        // Calculate velocity based on current and previous positions
        let vx = (this.x - this.oldX) * friction;
        let vy = (this.y - this.oldY) * friction;

        // Update previous positions
        this.oldX = this.x;
        this.oldY = this.y;

        // Update current positions with velocity
        this.x += vx;
        this.y += vy;

        // Apply gravity
        this.y += gravity;
      }

      // Constrain node within container boundaries
      constrain(width, height) {
        if (this.x < 0) this.x = 0;
        if (this.x > width) this.x = width;
        if (this.y < 0) this.y = 0;
        if (this.y > height) this.y = height;
      }
    }

    // Constraint Class to maintain distance between two nodes
    class Constraint {
      constructor(a, b, length) {
        this.a = a;          // Node A
        this.b = b;          // Node B
        this.length = length; // Desired distance between Node A and Node B
      }

      solve() {
        const dx = this.b.x - this.a.x;
        const dy = this.b.y - this.a.y;
        const distance = Math.sqrt(dx * dx + dy * dy);
        if (distance === 0) return; // Prevent division by zero
        const difference = (this.length - distance) / distance;
        const halfDifference = difference * 0.5;

        // Apply correction only if nodes are not pinned
        if (!this.a.pinned) {
          this.a.x -= dx * halfDifference;
          this.a.y -= dy * halfDifference;
        }

        if (!this.b.pinned) {
          this.b.x += dx * halfDifference;
          this.b.y += dy * halfDifference;
        }
      }
    }

    // Initialize Nodes
    const nodes = [];
    for (let i = 0; i <= numSegments; i++) {
      // Linear distribution between dot1 and dot2 initially
      const x = dot1.offsetLeft + (dot2.offsetLeft - dot1.offsetLeft) * (i / numSegments);
      const y = dot1.offsetTop;
      const pinned = (i === 0 || i === numSegments); // Pin first and last nodes
      const node = new Node(x, y, pinned);
      nodes.push(node);
    }

    // Initialize Constraints between consecutive nodes
    const constraints = [];
    for (let i = 0; i < numSegments; i++) {
      constraints.push(new Constraint(nodes[i], nodes[i + 1], segmentLength));
    }

    // Create Visual Nodes (Hidden)
    nodes.forEach(node => {
      const span = document.createElement('span');
      span.classList.add('node');
      container.appendChild(span);
      node.element = span;
    });

    // Function to Update Nodes' HTML Elements Position (Optional)
    function updateNodeElements() {
      nodes.forEach(node => {
        if (node.element) {
          node.element.style.left = `${node.x}px`;
          node.element.style.top = `${node.y}px`;
        }
      });
    }

    // Function to Update SVG Lines between Nodes
    function updateSVG() {
      // Clear previous lines
      ropeSVG.innerHTML = '';

      for (let i = 0; i < numSegments; i++) {
        const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
        line.setAttribute('x1', nodes[i].x);
        line.setAttribute('y1', nodes[i].y);
        line.setAttribute('x2', nodes[i + 1].x);
        line.setAttribute('y2', nodes[i + 1].y);
        line.setAttribute('stroke', '#fff');
        line.setAttribute('stroke-width', '2');
        ropeSVG.appendChild(line);
      }
    }

    // Physics Simulation Function
    function simulate() {
      // Update node positions based on physics
      nodes.forEach(node => node.update());

      // Solve constraints multiple times for stability
      for (let i = 0; i < constraintsIterations; i++) {
        constraints.forEach(constraint => constraint.solve());
      }

      // Constrain nodes within container boundaries
      const containerWidth = container.clientWidth;
      const containerHeight = container.clientHeight;
      nodes.forEach(node => node.constrain(containerWidth, containerHeight));
    }

    // Rendering Function
    function render() {
      updateSVG();            // Update SVG lines
      // updateNodeElements();   // Update visual nodes (hidden)
      
      // Synchronize draggable dots with physics nodes
      synchronizeDots();
    }

    // Function to Synchronize Draggable Dots with Physics Nodes
    function synchronizeDots() {
      // Update dot1 position to match Node[0]
      dot1.style.left = `${nodes[0].x}px`;
      dot1.style.top = `${nodes[0].y}px`;

      // Update dot2 position to match Node[N]
      dot2.style.left = `${nodes[numSegments].x}px`;
      dot2.style.top = `${nodes[numSegments].y}px`;
    }

    // Animation Loop
    function animate() {
      simulate();
      render();
      requestAnimationFrame(animate);
    }

    // Start Animation
    animate();

    // Dragging Functionality
    let isDragging = false;
    let dragNode = null;
    let offsetX = 0;
    let offsetY = 0;

    // Utility Function to Get Mouse Position Relative to Container
    function getMousePos(event) {
      const rect = container.getBoundingClientRect();
      return {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top
      };
    }

    // Mouse Down Event
    container.addEventListener('mousedown', (e) => {
      e.preventDefault();
      const mousePos = getMousePos(e);
      const mouseX = mousePos.x;
      const mouseY = mousePos.y;

      // Check if mouse is close to dot1 or dot2
      const distanceToDot1 = Math.hypot(mouseX - nodes[0].x, mouseY - nodes[0].y);
      const distanceToDot2 = Math.hypot(mouseX - nodes[numSegments].x, mouseY - nodes[numSegments].y);

      const threshold = 20; // Click threshold in pixels

      if (distanceToDot1 < threshold) {
        isDragging = true;
        dragNode = nodes[0];
      } else if (distanceToDot2 < threshold) {
        isDragging = true;
        dragNode = nodes[numSegments];
      }

      if (isDragging && dragNode) {
        offsetX = dragNode.x - mouseX;
        offsetY = dragNode.y - mouseY;
      }
    });

    // Mouse Move Event
    document.addEventListener('mousemove', (e) => {
      if (!isDragging || !dragNode) return;

      const mousePos = getMousePos(e);
      const mouseX = mousePos.x;
      const mouseY = mousePos.y;

      // Update node position directly for draggable node
      dragNode.x = mouseX + offsetX;
      dragNode.y = mouseY + offsetY;
    });

    // Mouse Up Event
    document.addEventListener('mouseup', () => {
      if (isDragging) {
        isDragging = false;
        dragNode = null;
      }
    });

    // Touch Support for Mobile Devices
    container.addEventListener('touchstart', (e) => {
      e.preventDefault();
      const touch = e.touches[0];
      const mousePos = getMousePos(touch);
      const mouseX = mousePos.x;
      const mouseY = mousePos.y;

      // Check if touch is close to dot1 or dot2
      const distanceToDot1 = Math.hypot(mouseX - nodes[0].x, mouseY - nodes[0].y);
      const distanceToDot2 = Math.hypot(mouseX - nodes[numSegments].x, mouseY - nodes[numSegments].y);

      const threshold = 20; // Touch threshold in pixels

      if (distanceToDot1 < threshold) {
        isDragging = true;
        dragNode = nodes[0];
      } else if (distanceToDot2 < threshold) {
        isDragging = true;
        dragNode = nodes[numSegments];
      }

      if (isDragging && dragNode) {
        offsetX = dragNode.x - mouseX;
        offsetY = dragNode.y - mouseY;
      }
    }, { passive: false });

    document.addEventListener('touchmove', (e) => {
      if (!isDragging || !dragNode) return;
      e.preventDefault();

      const touch = e.touches[0];
      const mousePos = getMousePos(touch);
      const mouseX = mousePos.x;
      const mouseY = mousePos.y;

      // Update node position directly for draggable node
      dragNode.x = mouseX + offsetX;
      dragNode.y = mouseY + offsetY;
    }, { passive: false });

    document.addEventListener('touchend', () => {
      if (isDragging) {
        isDragging = false;
        dragNode = null;
      }
    });
  </script>
</body>
</html>
```

The menu should feature:

- Fixed/draggable UI
- Range inputs:
  - Manipulate the rope weight
  - Manipulate the gravity
- Material You dark UI for the menu
- Expandible/collapsible