/* Palette pulled directly from tradeturestyle.css so this component
     drops into the site without looking like a foreign widget. */
  :root {
    --bg:#020202;
    --panel:rgba(22,22,22,0.74);
    --panel-2:rgba(32,32,32,0.85);
    --border:rgba(255,255,255,0.16);
    --border-hover:rgba(255,255,255,0.36);
    --text:#f2f2f0;
    --muted:#8f8f8c;
    --muted-dim:#5c5c5a;
    --accent:#FFC400;
    --accent-soft:#FFDD55;
    --accent-dim:#8a6d0f;
    --accent-deep:#C9A227;
    --glow:rgba(255,196,20,0.45);
    --ink:#120c02;
    --warn:#ff9f43;
    --radius:14px;
    --font-head:'Poppins','Segoe UI',system-ui,-apple-system,sans-serif;
    --font-body:'Segoe UI','Inter',system-ui,-apple-system,sans-serif;
    --font-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  }
  * { box-sizing: border-box; }
  html, body {
    margin: 0;
    background: var(--bg);
    font-family: var(--font-body);
    color: var(--text);
  }

  /* The canvas stays pinned to the viewport; the actual page scrolls
     via the tall #scroll-spacer below, which is what drives the camera. */
  #scene-canvas {
    position: fixed;
    inset: 0;
    display: block;
    z-index: 1;
  }
  /* Applied once free-look is available (the floor stage — see the
     free-look drag handling in the script) so the cursor hints that the
     scene is now draggable. */
  #scene-canvas.free-look-active { cursor: grabbing; }

  #scroll-spacer {
    position: relative;
    z-index: 0;
    width: 100%;
    /* height is set from JS once we know the scroll length */
  }

  .hud { position: fixed; z-index: 2; pointer-events: none; }

  .brand { top: 28px; left: 32px; font-family: var(--font-head); }
  .brand h1 {
    margin: 0;
    font-size: 15px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--muted);
  }
  .brand h1 span.accent { color: var(--accent); }
  .brand h1 .cursor { color: var(--accent); margin-left: 4px; animation: blink 1.1s steps(2, start) infinite; }
  @keyframes blink { 50% { opacity: 0; } }

  /* Feature card — image stack lives in the 3D scene; this is the small
     text readout beneath it, styled like the site's badge/pill system. */
  .feature-card {
    left: 50%;
    bottom: 40px;
    width: min(400px, 88vw);
    transform: translate(-50%, 8px);
    text-align: center;
    opacity: 0;
    position: fixed;
    transition: opacity 0.45s ease, transform 0.45s ease;
  }
  .feature-card.visible { opacity: 1; transform: translate(-50%, 0); }

  .feature-bgnum {
    position: absolute;
    left: 50%;
    top: -42px;
    transform: translateX(-50%);
    font-family: var(--font-head);
    font-weight: 800;
    font-size: 100px;
    line-height: 1;
    color: var(--accent);
    opacity: 0.08;
    letter-spacing: -0.02em;
    z-index: -1;
    pointer-events: none;
  }

  .feature-eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--accent-soft);
    margin-bottom: 8px;
    font-weight: 600;
  }
  .feature-card h2 {
    margin: 0 0 10px 0;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 20px;
    color: var(--text);
  }
  .feature-card .desc {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--muted);
    background: var(--panel);
    border: 1px solid var(--border);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    padding: 10px 16px;
    border-radius: var(--radius);
    display: inline-block;
  }

  .feature-tags { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 10px; }
  .feature-tag {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid rgba(255, 196, 20, 0.3);
    color: var(--accent-soft);
    background: rgba(255, 196, 20, 0.08);
  }
  .feature-tag--soon {
    border-color: rgba(255, 159, 67, 0.4);
    color: var(--warn);
    background: rgba(255, 159, 67, 0.08);
  }

  .card-dots { display: flex; gap: 6px; justify-content: center; margin-top: 12px; }
  .card-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: rgba(255,255,255,0.2);
    transition: background 0.2s ease, transform 0.2s ease;
  }
  .card-dot.active { background: var(--accent); transform: scale(1.5); box-shadow: 0 0 6px var(--glow); }

  /* Thin progress rail on the right edge of the viewport */
  .progress-rail { top: 14vh; right: 28px; height: 72vh; width: 2px; background: var(--border); }
  .progress-fill { position: absolute; top: 0; left: 0; width: 100%; height: 0%; background: var(--accent); box-shadow: 0 0 8px var(--glow); }
  .progress-dot {
    position: absolute; left: 50%; width: 8px; height: 8px; border-radius: 50%;
    background: var(--accent); box-shadow: 0 0 8px var(--glow); transform: translate(-50%, -50%);
  }

  .scroll-hint {
    left: 50%; bottom: 34px; transform: translateX(-50%);
    font-family: var(--font-mono);
    font-size: 11px; letter-spacing: 0.1em; color: var(--muted);
    text-align: center; opacity: 1; transition: opacity 0.5s ease;
    text-transform: uppercase;
  }
  .scroll-hint .arrow { display: block; margin-top: 6px; color: var(--accent); animation: bob 1.6s ease-in-out infinite; }
  @keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(6px); } }

  /* Keyboard-control legend */
  .key-hint {
    left: 32px;
    bottom: 40px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .key-hint .feature-tag { border-color: var(--border); color: var(--muted); background: var(--panel); }

  /* Autoplay transport — lets a visitor sit back and watch the whole
     descent play out on its own, like an opening title sequence, instead
     of scrolling by hand. Always visible (even during the hero band)
     since that's the most natural place to press play from. */
  .playback-controls {
    top: 24px;
    right: 28px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    pointer-events: auto;
  }
  .pb-row { display: flex; gap: 8px; }
  .pb-2d-link {
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
    text-decoration: none;
    padding: 2px 4px;
    transition: color 0.2s ease;
  }
  .pb-2d-link:hover { color: var(--accent-soft); }
  .pb-btn {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 9px 14px 7px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: rgba(10, 10, 9, 0.72);
    backdrop-filter: blur(6px);
    color: var(--muted);
    cursor: pointer;
    font-family: var(--font-mono);
    transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease, transform 0.15s ease;
  }
  .pb-btn:hover { border-color: var(--accent); color: var(--accent-soft); transform: translateY(-1px); }
  .pb-btn .pb-icon { font-size: 15px; line-height: 1; }
  .pb-btn .pb-label { font-size: 8.5px; letter-spacing: 0.12em; text-transform: uppercase; }
  .pb-btn.active { border-color: var(--accent); color: var(--ink); background: var(--accent); box-shadow: 0 0 18px var(--glow); }
  .pb-btn--play { min-width: 50px; }

  @media (max-width: 640px) {
    .progress-rail { display: none; }
    .key-hint { display: none; }
    .playback-controls { top: auto; bottom: 16px; right: 16px; }
    .pb-btn { padding: 7px 10px 6px; }
  }

  /* ============================================================
     HERO — ported from index.html's `hero-precision` section.
     It's a HUD overlay sitting on top of the exact opening 3D shot
     the scene already held at scroll position 0 (rails, helix
     text, ambient chart icons); it fades out continuously as the
     user scrolls through a dedicated hero band before the feature
     spiral's own descent begins, then hands off to the spiral's
     HUD chrome (key-hint / progress-rail), which stays hidden
     until that handoff happens.
     ============================================================ */
  .hero-hud {
    top: 0; left: 0; right: 0; bottom: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; padding: 0 24px;
  }
  /* Same full-viewport centering as .hero-hud (reuses its inner
     .hero-hud__* classes for typography) — this is the closing bookend,
     faded in/out by opacity rather than always laid out, since it only
     makes sense once the outro camera move has revealed the floor. */
  .outro-hud {
    top: 0; left: 0; right: 0; bottom: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center; padding: 0 24px;
    opacity: 0; transition: opacity 0.6s ease;
  }
  .outro-hud.visible { opacity: 1; }
  /* Pointer events are re-enabled on just the panel itself (not the
     full-viewport wrapper above, which stays click-through) — the floor
     stage also supports click-drag free-look directly on the canvas (see
     the free-look drag handling in the script), which would otherwise be
     blocked everywhere on screen by this wrapper once it's visible. */
  .outro-hud.visible .hero-hud__panel { pointer-events: auto; }
  /* Same glass-panel language as .feature-card — needed here because the
     scene's own background objects (helix letters, chart icons) sit
     directly behind the hero and would otherwise bleed through the text. */
  .hero-hud__panel {
    background: var(--panel);
    border: 1px solid var(--border);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border-radius: 24px;
    padding: 42px 52px 36px;
    max-width: 700px;
    display: flex; flex-direction: column; align-items: center;
    box-shadow: 0 24px 60px rgba(0,0,0,0.4);
  }
  .hero-hud__badge {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--accent-soft); background: rgba(255,196,20,0.08); border: 1px solid rgba(255,196,20,0.3);
    border-radius: 999px; padding: 7px 16px; display: inline-flex; align-items: center; gap: 8px; margin-bottom: 26px;
  }
  .hero-hud__badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--glow); flex: none; }
  .hero-hud__title {
    font-family: var(--font-head); font-weight: 700; color: var(--text);
    font-size: clamp(26px, 4vw, 44px); line-height: 1.16; margin: 0 0 20px 0;
  }
  .hero-hud__title em { font-style: italic; color: var(--accent); font-weight: 700; }
  .hero-hud__sub {
    font-family: var(--font-body); color: var(--muted); font-size: 14.5px; line-height: 1.65;
    margin: 0 0 28px 0;
  }
  /* The closing "Tradeture was built for you!" line under the outro's
     qualifier list — same block as __sub, just heavier and in the main
     text color so it reads as the payoff line, not more body copy. */
  .hero-hud__sub--strong {
    color: var(--text); font-weight: 700; font-size: 16px; margin-bottom: 30px;
  }
  /* The outro's "If you're a ... " qualifier list. Left-aligned even
     though the panel around it is centered — center-aligning six wrapped
     conditional sentences reads as a ragged mess, left-aligned reads as
     an actual list. */
  .hero-hud__list {
    font-family: var(--font-body); color: var(--muted); font-size: 14.5px; line-height: 1.6;
    text-align: left; list-style: none; margin: 0 0 24px 0; padding: 0;
    display: flex; flex-direction: column; gap: 11px;
  }
  .hero-hud__list li { position: relative; padding-left: 22px; }
  .hero-hud__list li::before {
    content: "\2192"; position: absolute; left: 0; top: 0; color: var(--accent);
  }
  .hero-hud__cta { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; margin-bottom: 34px; }
  .idxbtn {
    font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase;
    font-weight: 600; padding: 13px 28px; border-radius: 999px; text-decoration: none; display: inline-block;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, color 0.2s ease;
  }
  .idxbtn--gold { background: var(--accent); color: var(--ink); box-shadow: 0 0 24px var(--glow); }
  .idxbtn--gold:hover { transform: translateY(-2px); box-shadow: 0 0 32px var(--glow); }
  .idxbtn--ghost { background: transparent; color: var(--text); border: 1px solid var(--border-hover); }
  .idxbtn--ghost:hover { transform: translateY(-2px); border-color: var(--accent); color: var(--accent-soft); }
  .hero-hud__exchanges { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
  .hero-hud__exlabel { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; color: var(--muted-dim); text-transform: uppercase; margin-right: 4px; }
  .ex-badge {
    font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.04em; padding: 5px 12px; border-radius: 999px;
    border: 1px solid var(--border); color: var(--muted);
  }
  .ex-badge.ex--active { color: var(--text); border-color: rgba(255,196,20,0.35); }
  .ex-badge.ex--soon { color: var(--muted-dim); }

  /* ============================================================
     ACTION — collapsible CTA tab for the floor stage. Separate from
     .outro-hud (that panel stays exactly as-is); this is a small
     always-collapsed-by-default tab bottom-left that expands on click,
     so the floor reveal doesn't force the full CTA panel on the visitor
     while they're busy free-looking around the room (see the free-look
     drag handling in the script). Same fade-in gate as .outro-hud
     (outroT > 0.55) via the .visible class.
     ============================================================ */
  .action-hud {
    left: 28px; bottom: 28px;
    display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
    opacity: 0; transition: opacity 0.6s ease;
  }
  .action-hud.visible { opacity: 1; pointer-events: auto; }
  .action-toggle {
    font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase;
    font-weight: 600; color: var(--ink); background: var(--accent);
    border: none; border-radius: 999px; padding: 12px 22px;
    display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
    box-shadow: 0 0 24px var(--glow);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
  }
  .action-toggle:hover { transform: translateY(-2px); box-shadow: 0 0 32px var(--glow); }
  .action-toggle__icon { font-size: 9px; transition: transform 0.25s ease; }
  .action-hud.open .action-toggle__icon { transform: rotate(180deg); }
  .action-panel {
    display: flex; flex-direction: column; gap: 10px;
    background: var(--panel); border: 1px solid var(--border);
    backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
    border-radius: 18px; padding: 0 16px;
    max-height: 0; overflow: hidden; opacity: 0;
    transition: max-height 0.3s ease, opacity 0.25s ease, padding 0.3s ease;
  }
  .action-hud.open .action-panel {
    max-height: 280px; opacity: 1; padding: 16px; /* was 220px — 3 buttons now (added LEARN MORE) */
  }
  .action-panel .idxbtn { text-align: center; }
  .ex-badge.ex--soon em { font-style: normal; color: var(--accent-dim); margin-left: 3px; }

  /* The feature-spiral's own HUD chrome only makes sense once the hero
     band has been scrolled through. */
  .key-hint, .progress-rail { opacity: 0; transition: opacity 0.6s ease; }
  body.past-hero .key-hint, body.past-hero .progress-rail { opacity: 1; }

  @media (max-width: 640px) {
    .hero-hud__title { font-size: clamp(26px, 8vw, 38px); }
    .hero-hud__sub { font-size: 13.5px; }
    .hero-hud__list { font-size: 13.5px; }
  }

  /* ============================================================
     MONOLITH OVERLAY — click-to-read panel for a wall card. Full-
     viewport blurred/dimmed backdrop + a centered content panel; the
     backdrop click and the × button both close it (see the script,
     near openMonolithOverlay/closeMonolithOverlay). Not a .hud element
     (those default to pointer-events:none) since this needs to actively
     block interaction with the scene behind it while open.
     ============================================================ */
  .monolith-overlay {
    position: fixed; inset: 0; z-index: 40;
    display: flex; align-items: center; justify-content: center;
    padding: 24px;
    opacity: 0; pointer-events: none;
    transition: opacity 0.25s ease;
  }
  .monolith-overlay.visible { opacity: 1; pointer-events: auto; }
  .monolith-overlay__backdrop {
    position: absolute; inset: 0;
    background: rgba(4,4,3,0.7);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
  }
  .monolith-overlay__panel {
    position: relative;
    width: min(90vw, 620px);
    background: var(--panel-2);
    border: 1px solid rgba(255,196,20,0.4);
    border-radius: var(--radius);
    padding: 44px 44px 40px;
    box-shadow: 0 24px 70px rgba(0,0,0,0.55);
    transform: translateY(14px) scale(0.98);
    transition: transform 0.25s ease;
    /* The AI agents' enlarged photo (monolith-overlay__image) can push a
       short viewport's total content taller than the screen — this was
       previously unbounded (panel just grew with its content, off the
       top/bottom of a short window with no way to reach it) since only
       __desc had its own internal scroll. A general safety net now, not
       just for the image case. */
    max-height: calc(100vh - 48px);
    overflow-y: auto;
  }
  .monolith-overlay__image {
    display: none; /* shown + given a src only for kind:"ai" — see openMonolithOverlay */
    width: 100%;
    max-height: 38vh;
    object-fit: contain;
    border-radius: 10px;
    border: 1px solid rgba(255,196,20,0.35);
    background: rgba(0,0,0,0.35);
    margin: 0 0 20px 0;
  }
  .monolith-overlay.visible .monolith-overlay__panel { transform: translateY(0) scale(1); }
  .monolith-overlay__close {
    position: absolute; top: 14px; right: 14px;
    width: 34px; height: 34px; border-radius: 50%;
    background: rgba(255,255,255,0.06); border: 1px solid rgba(255,196,20,0.3);
    color: var(--accent); font-size: 20px; line-height: 1; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: border-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
  }
  .monolith-overlay__close:hover { border-color: var(--accent); color: var(--accent-soft); transform: scale(1.08); }
  .monolith-overlay__eyebrow {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--accent-soft); margin-bottom: 18px;
  }
  .monolith-overlay__badge {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 44px; height: 44px; padding: 0 4px; border-radius: 8px;
    background: rgba(255,196,20,0.08); border: 1px solid rgba(255,196,20,0.5);
    color: var(--accent); font-family: var(--font-mono); font-weight: 700; font-size: 17px;
    margin-bottom: 18px;
  }
  .monolith-overlay__title {
    font-family: var(--font-head); font-weight: 700; font-size: clamp(24px, 3.2vw, 32px);
    color: var(--accent); margin: 0 0 18px 0; line-height: 1.2;
  }
  .monolith-overlay__headline {
    /* Same modal popup this session's "titles are the only large text"
       fix applies to — the Acts' intro sentence used to double as this
       popup's <h2> title (large, bold). It now renders at the exact same
       size as the paragraph below it, keeping only its gold color to set
       it apart; the popup's actual title (monolith-overlay__title) is the
       group's real name, matching what Standards already did. Empty/no
       headline (Standards, outro) collapses to nothing via display:none,
       set in openMonolithOverlay. */
    font-family: var(--font-mono); font-size: 15px; line-height: 1.7;
    font-weight: 700; color: var(--accent); margin: 0 0 14px 0;
  }
  .monolith-overlay__desc {
    font-family: var(--font-mono); font-size: 15px; line-height: 1.7;
    color: var(--text); margin: 0;
    /* intro panels can carry several paragraphs (see openMonolithOverlay's
       "intro"/"outro" branches, which join them with blank lines) — pre-line
       renders those \n\n as real paragraph breaks, and the panel scrolls
       internally instead of overflowing the viewport on a long one. */
    white-space: pre-line;
    max-height: 42vh;
    overflow-y: auto;
  }
  @media (max-width: 640px) {
    .monolith-overlay__panel { padding: 36px 26px 32px; }
  }

  /* ============================================================
     LOADING SCREEN
     ============================================================ */
  html.is-loading, html.is-loading body { overflow: hidden; }
  .loading-screen {
    position: fixed; inset: 0; z-index: 50;
    background: var(--bg);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 22px;
    transition: opacity 0.6s ease, visibility 0.6s ease;
  }
  .loading-screen.hidden { opacity: 0; visibility: hidden; pointer-events: none; }
  .loading-screen__mark {
    font-family: var(--font-head); font-weight: 700; font-size: 20px; letter-spacing: 0.18em;
    color: var(--muted); text-transform: uppercase;
  }
  .loading-screen__mark .accent { color: var(--accent); }
  .loading-screen__status {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.14em; color: var(--muted-dim);
    text-transform: uppercase;
  }
  .loading-screen__status .cursor { color: var(--accent); margin-left: 3px; animation: blink 1.1s steps(2, start) infinite; }
  .loading-screen__bar { width: 220px; height: 2px; background: var(--border); border-radius: 999px; overflow: hidden; }
  .loading-screen__fill {
    width: 0%; height: 100%; background: var(--accent); box-shadow: 0 0 8px var(--glow);
    /* No CSS transition here on purpose — the bar and the "N%" text are
       driven from the same JS-eased value every frame (see tickLoadingPct)
       so they can never visibly desync the way they did when only the bar
       had a transition and the text jumped instantly. */
  }
  .loading-screen__pct { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; color: var(--muted-dim); }
  .loading-screen__2dlink {
    margin-top: 6px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
    text-decoration: none;
    padding: 4px 2px;
    transition: color 0.2s ease;
  }
  .loading-screen__2dlink:hover { color: var(--accent-soft); }

  /* ============================================================
     ROOM — the per-Act/Standard labeling used to be an HTML "hud
     act-card" overlay here (.act-card/.act-eyebrow/.act-headline).
     It's now built as in-scene 3D elements (gold bracket + floating
     gold title text mounted on the wall) instead, so there's no DOM
     overlay class left to style. The feature-spiral's key-hint
     (arrow-key feature switching) still isn't relevant once inside
     the room though, so it stays suppressed via body.in-room even
     though body.past-hero is still true.
     ============================================================ */
  body.in-room .key-hint { opacity: 0; }