  :root {
    --bg: #0e0d0b;
    --card-bg: #17150f;
    --accent: #c98a3e;
    --text: #1a1a1a;
  }
  * { box-sizing: border-box; }
  html, body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: -apple-system, "Segoe UI", sans-serif;
    overflow-x: hidden;
  }
  header {
    position: fixed;
    top: 0; left: 0; right: 0;
    padding: 24px 40px;
    z-index: 10;
    font-size: 13px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text);
    pointer-events: none;
  }

  /* ---- Scroll container ---- */
  #scroll-track {
    height: 100vh;
    width: 100vw;
    margin-left: calc(50% - 50vw); /* breaks out of any boxed/padded
      Elementor container so the track truly spans the viewport,
      regardless of the widget's ancestor width */
    display: flex;
    flex-direction: row;
    overflow-x: scroll;
    overflow-y: hidden;
    /* No CSS scroll-snap-type here — it fights the manual
       scrollLeft increments in the wheel handler below.
       Snapping is instead done in JS after scrolling settles. */
  }
  .mask-section {
    height: 100vh;
    width: 100vw;
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
    padding: 40px;
  }

  /* ---- Frame holding the stage + any number of hotspots.
     Fixed size so each hotspot's top/left % in the data
     resolves to a predictable, reusable position. ---- */
  .mask-frame {
    position: relative;
    width: 1000px;
    height: 640px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .stage {
    position: relative;
    width: 560px;
    height: 560px;
    perspective: 900px; /* gives the drag-rotate a sense of depth */
    flex: 0 0 auto;
  }
  .layer {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    will-change: transform;
    transition: transform 0.1s linear;
  }
  /* depth 0 = furthest back (moves least), depth 1 = closest (moves most) */
  .layer-bg   { z-index: 1; }
  .layer-mask { z-index: 2; }
  .layer-fg   { z-index: 3; }

  .mask-shape {
    width: 320px; height: 400px;
    background: var(--card-bg);
    border: 1px solid rgba(236,230,216,0.25);
    border-radius: 160px 160px 40px 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    color: rgba(236,230,216,0.6);
    text-align: center;
    padding: 20px;
    cursor: grab;
    touch-action: none;
    user-select: none;
    will-change: transform;
    object-fit: contain; /* has no effect on a div, but keeps this rule ready if
      .mask-shape is an <img> once you've swapped in a real photo — see below */
  }
  .mask-shape:active { cursor: grabbing; }

  /* ---- Hotspots: any number, positioned by top/left % from
     the data, each with a hover-revealed detail card ---- */
  .hotspots {
    position: absolute;
    inset: 0;
    pointer-events: none; /* only the hotspots themselves are clickable */
  }
  .hotspot {
    position: absolute;
    transform: translate(-50%, -50%); /* top/left mark the hotspot's center point */
    width: 110px;
    background: transparent;
    border: none;
    color: var(--text);
    cursor: pointer;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    pointer-events: auto;
    will-change: transform;
    transition: transform 0.1s linear;
    z-index: 6;
  }
  .hotspot-thumb {
    width: 96px;
    height: 120px;
    background: var(--card-bg);
    border: 1px solid rgba(236,230,216,0.25);
    border-radius: 6px;
    overflow: hidden;
    transition: border-color 0.2s, transform 0.2s;
  }
  .hotspot-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .hotspot:hover .hotspot-thumb,
  .hotspot.active .hotspot-thumb {
    border-color: var(--accent);
    transform: scale(1.06);
  }
  .hotspot-label {
    font-size: 11px;
    letter-spacing: 0.04em;
    color: rgba(26,26,26,0.7);
    text-align: center;
  }

  /* Detail card, anchored above the thumb by default */
  .hotspot-card {
    position: absolute;
    bottom: calc(100% + 12px);
    left: 50%;
    transform: translateX(-50%) translateY(6px);
    width: 200px;
    padding: 0;
    font-size: 12px;
    line-height: 1.6;
    color: #1a1a1a;
    text-align: left;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease;
  }
  .hotspot.active .hotspot-card {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
  /* For hotspots near the top of the frame — add class "cardBelow: true"
     in the data to flip the card so it opens downward instead of
     off the top of the screen. */
  .hotspot.card-below .hotspot-card {
    bottom: auto;
    top: calc(100% + 12px);
    transform: translateX(-50%) translateY(-6px);
  }
  .hotspot.card-below.active .hotspot-card {
    transform: translateX(-50%) translateY(0);
  }

  /* ---- Floating text layers: any number, positioned by
     top/left % from the data, drifting with the mouse ---- */
  .text-layers {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .text-layer {
    position: absolute;
    transform: translate(-50%, -50%);
    color: rgba(26,26,26,0.75);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: 14px;
    white-space: nowrap;
    will-change: transform;
    transition: transform 0.1s linear;
  }

  /* ---- Caption ---- */
  .caption {
    text-align: center;
    margin-top: 8px;
  }
  .caption .index { color: var(--accent); font-size: 13px; letter-spacing: 0.1em; }
  .caption h2 { margin: 6px 0 0; font-weight: 400; font-size: 26px; }

  .loop-flag {
    position: absolute;
    top: 16px; right: 24px;
    font-size: 11px;
    color: var(--accent);
    opacity: 0;
    transition: opacity 0.4s;
  }
  .loop-flag.show { opacity: 1; }
