/* GENERATED by hero-build.js — edit hero.src.html <style>, not this file */
/* ============================================================
     LAYOUT — identical scaffold strategy to file 14: a fixed full-screen
     canvas BEHIND a tall scroll scaffold. The scaffold (#scroll, N x 100vh)
     exists ONLY to create scroll RANGE; the 3D camera reads scroll progress
     each frame and FLIES forward through the starfield toward each floating
     weapon. No HTML copy overlay — all station copy lives IN the 3D world as
     labels (see makeLabel / §6.5).

     COLOUR DIRECTION — DARK COSMOS (ENKR Ba Zi brand):
       Abyss Black     #0A1A2F   — backgrounds
       Rising Sun Gold #E8A848   — the ONE accent (CTAs, eyebrow, glow)
       Moonlight Silver#F0F6FF   — primary text
       Muted Silver    #7A96B8   — secondary text / blurb
     The overlay tokens below are flipped to LIGHT text on a DARK ground
     (the inverse of file 14's dark-on-light daylight tokens).
     ============================================================ */
  * { margin: 0; padding: 0; box-sizing: border-box; }
  html { scroll-behavior: auto; }            /* JS damps motion, not the browser */
  /* Lenis smooth-scroll recommended CSS */
  html.lenis, html.lenis body { height: auto; }
  .lenis.lenis-smooth { scroll-behavior: auto !important; }
  .lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
  .lenis.lenis-stopped { overflow: hidden; }
  /* Deep-space palette — tokens as custom properties, no hardcoded hex in rules. */
  :root {
    --canvas:    #0A1A2F;   /* Abyss Black — matches the 3D scene background */
    --ink:       #F0F6FF;   /* Moonlight Silver — primary text on the dark scene */
    --ink-muted: #7A96B8;   /* Muted Silver — secondary text */
    --accent:    #E8A848;   /* Rising Sun Gold — the ONE warm accent */
    --accent-2:  #F4C06A;   /* Light Gold — hover / gradient end */
  }
  body {
    background: var(--canvas);
    color: var(--ink);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
  }

  /* Visually-hidden semantic content — present for crawlers + screen readers while the
     canvas owns the visual (see #fallback-content in <body>). */
  .sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
  }
  /* WebGL unavailable / scene failed to start → body.fallback reveals that block as a
     readable, on-brand page (Abyss + Gold) and hides the dead 3D shell + loader. */
  body.fallback #bg, body.fallback #loader, body.fallback #scroll, body.fallback #endcta,
  body.fallback #hint, body.fallback #progress, body.fallback #topbar { display: none !important; }
  body.fallback { overflow: auto; }
  body.fallback #fallback-content {
    position: static; width: auto; height: auto; clip: auto; clip-path: none;
    white-space: normal; overflow: visible; margin: 0 auto; padding: 14vh 7vw; max-width: 640px;
    line-height: 1.65;
  }
  /* KEYBOARD REVEAL — Tab into the sr-only fallback un-clips it into a readable fixed
     overlay (same abyss visual language as body.fallback above) so keyboard users get
     the real content + links without needing the WebGL scene to fail. The default
     .sr-only state is untouched; this only fires while a link inside has focus. */
  body:not(.fallback) #fallback-content:focus-within {
    position: fixed; inset: 0; z-index: 50;            /* above canvas/scroll/hint/progress/endcta, below #loader */
    width: auto; height: auto; clip: auto; clip-path: none;
    white-space: normal; overflow: auto; margin: 0;
    padding: 14vh max(7vw, calc((100vw - 640px) / 2)); /* same centred 640px column as body.fallback */
    background: var(--canvas); line-height: 1.65;
  }
  /* share the fallback page's typography with the keyboard-revealed overlay */
  body.fallback #fallback-content h1,  body:not(.fallback) #fallback-content:focus-within h1  { color: var(--accent); font-size: clamp(28px, 6vw, 46px); letter-spacing: -0.01em; margin-bottom: 0.5rem; }
  body.fallback #fallback-content h2,  body:not(.fallback) #fallback-content:focus-within h2  { color: var(--ink); font-size: 0.8rem; letter-spacing: 0.18em; text-transform: uppercase; margin: 2rem 0 0.6rem; }
  body.fallback #fallback-content p,   body:not(.fallback) #fallback-content:focus-within p   { color: var(--ink-muted); margin-bottom: 0.9rem; }
  body.fallback #fallback-content blockquote, body:not(.fallback) #fallback-content:focus-within blockquote {
    color: var(--ink-muted); font-style: italic; margin: 0 0 0.9rem;
    padding-left: 0.9rem; border-left: 2px solid rgba(232, 168, 72, 0.45);   /* the readable mirror of the 3D pull-quote framing */
  }
  body.fallback #fallback-content ul,  body:not(.fallback) #fallback-content:focus-within ul  { list-style: none; padding: 0; }
  body.fallback #fallback-content li,  body:not(.fallback) #fallback-content:focus-within li  { color: var(--ink-muted); margin-bottom: 0.7rem; }
  body.fallback #fallback-content a,   body:not(.fallback) #fallback-content:focus-within a   { color: var(--accent); text-decoration: none; border-bottom: 1px solid rgba(232, 168, 72, 0.4); }
  body.fallback #fallback-content nav, body:not(.fallback) #fallback-content:focus-within nav { display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem; margin-top: 0.5rem; }

  /* Visible keyboard focus on the interactive links — gold ring, on-brand */
  #endcta a:focus-visible, #fallback-content a:focus-visible,
  #topbar a:focus-visible, #topbar .tb-tick:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

  /* Fixed canvas: it never scrolls — only the camera flies through 3D space. */
  #bg {
    position: fixed; inset: 0;
    width: 100vw; height: 100vh;
    display: block; z-index: 0;
  }

  /* LOADING SCREEN — Abyss overlay shown immediately (before the ES module fetches
     three.js + builds the scene), faded out the instant the first frame renders so
     you never see the bare HTML / scroll scaffold. bg matches the scene's VOID_BG. */
  #loader {
    position: fixed; inset: 0; z-index: 100;
    background: #050D18;
    display: flex; align-items: center; justify-content: center;
    transition: opacity 0.7s ease;
  }
  #loader.done { opacity: 0; pointer-events: none; }
  #loader .lwrap { display: flex; flex-direction: column; align-items: center; gap: 30px; position: relative; z-index: 1; }
  /* count-up % — cinematic gold number ticking 0→100 */
  #loader .lpct {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-weight: 600; font-size: clamp(48px, 8vw, 90px); letter-spacing: 0.02em;
    color: #E8A848; text-shadow: 0 0 30px rgba(232, 168, 72, 0.45);
    font-variant-numeric: tabular-nums; line-height: 1;
  }
  /* warp + readout: a small LOADING eyebrow and the count-up % pinned near the
     bottom so the hyperspace stays clean (the number rides under the dive). */
  #loader.warp .lwrap { position: absolute; left: 50%; bottom: 13%; transform: translateX(-50%); gap: 14px; }
  #loader.warp .lpct { font-size: clamp(30px, 5vw, 46px); }
  #loader .lload {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: clamp(10px, 1.1vw, 12px); letter-spacing: 0.45em; text-indent: 0.45em;
    text-transform: uppercase; color: rgba(232, 168, 72, 0.75);   /* 0.75 alpha: AA contrast on the abyss */
  }
  /* warp — gold stars streaking outward (hyperspace into the galaxy). full-screen canvas. */
  #loader .lwarp { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }

  /* The scroll scaffold sits above the canvas. pointer-events:none lets
     drag/scroll pass through; we re-enable it only on the interactive bits. */
  #scroll { position: relative; z-index: 1; }

  .section {
    height: 130vh;   /* enough to dwell + read, but not so much that scrolling feels laborious */
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 8vw;
    pointer-events: none;
  }

  /* Scroll hint — a soft bouncing chevron + label, bottom centre */
  #hint {
    position: fixed; left: 50%; bottom: 30px;
    transform: translateX(-50%);
    z-index: 3; text-align: center; pointer-events: none;
    transition: opacity 0.4s ease;
  }
  #hint .label {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 10px; letter-spacing: 0.34em; text-transform: uppercase;
    color: var(--ink-muted); margin-bottom: 13px;
  }
  /* a thin vertical line with a gold segment drifting down — calmer + more premium
     than a bouncing chevron, and on-theme with the slow galaxy drift. */
  #hint .line {
    width: 1px; height: 42px; margin: 0 auto; position: relative;
    background: rgba(240, 246, 255, 0.10); overflow: hidden;
  }
  #hint .line::after {
    content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 45%;
    background: linear-gradient(180deg, transparent, var(--accent));
    animation: drift 2.0s cubic-bezier(0.6, 0, 0.2, 1) infinite;
  }
  @keyframes drift {
    0%   { transform: translateY(-100%); opacity: 0; }
    25%  { opacity: 1; }
    100% { transform: translateY(322%); opacity: 0; }
  }

  /* Premium hairline scroll-progress. A faint full-width TRACK (body::before) with
     a refined gold FILL that fades in at the left and glows softly at the leading tip. */
  body::before {
    content: ''; position: fixed; top: 0; left: 0; right: 0; height: 1.5px;
    background: rgba(240, 246, 255, 0.05); z-index: 3; pointer-events: none;
  }
  #progress {
    position: fixed; top: 0; left: 0; height: 1.5px; width: 0%;
    background: linear-gradient(90deg, rgba(232, 168, 72, 0) 0%, rgba(232, 168, 72, 0.5) 38%, var(--accent-2) 100%);
    z-index: 4;
    box-shadow: 0 0 6px rgba(232, 168, 72, 0.45);
  }
  /* Hide the native scrollbar — the gold hairline is the indicator (Lenis drives scroll). */
  ::-webkit-scrollbar { width: 0; height: 0; }
  html { scrollbar-width: none; -ms-overflow-style: none; }

  /* PERSISTENT HEADER — quick links + chapter tick dots, fixed just BELOW the 1.5px
     progress hairline. Hidden (opacity 0 + inert) at the landing so the wordmark beat
     stays clean; updateCamera turns it on once p > 0.04 (same write-style as #hint).
     Container is pointer-events:none so scroll/drag passes through; only the links
     and dot buttons re-enable events. */
  #topbar {
    position: fixed; top: 1.5px; left: 0; right: 0; z-index: 4;
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 18px;
    pointer-events: none;
    opacity: 0; transition: opacity 0.5s ease;
  }
  #topbar .tb-wordmark {
    display: inline-flex; align-items: center; gap: 12px;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 12px; letter-spacing: 0.08em; color: var(--ink-muted);
    padding: 10px 0;
    white-space: nowrap;
  }
  #topbar .tb-mark { height: 13px; width: auto; fill: var(--accent); opacity: 0.9; display: block; }   /* the mark stands alone (owner's call: logo only, no role text) — a touch larger */
  #topbar .tb-links { display: flex; align-items: center; gap: 12px; }
  #topbar .tb-links a { pointer-events: auto; }
  #topbar .tb-resume {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 12px; letter-spacing: 0.08em; color: var(--ink-muted);
    text-decoration: none; padding: 14px 8px;            /* ≥44px tap height */
    transition: color 0.2s ease;
  }
  #topbar .tb-resume:hover, #topbar .tb-resume:focus-visible { color: var(--accent); }
  /* "Let's talk" — ~0.8x of #endcta .cta-book: same gold-outline language, smaller */
  #topbar .tb-talk {
    display: inline-flex; align-items: center;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 11px; letter-spacing: 0.24em; text-indent: 0.24em; text-transform: uppercase;
    color: var(--accent); text-decoration: none; white-space: nowrap;
    border: 1px solid rgba(232, 168, 72, 0.55); border-radius: 6px;
    padding: 0.66rem 1.3rem; background: transparent;
    transition: color .28s ease, border-color .28s ease, background .28s ease, box-shadow .28s ease;
  }
  #topbar .tb-talk:hover, #topbar .tb-talk:focus-visible {
    color: var(--accent-2); border-color: var(--accent-2);
    background: rgba(232, 168, 72, 0.08);
    box-shadow: 0 0 18px rgba(232, 168, 72, 0.3), inset 0 0 14px rgba(232, 168, 72, 0.1);
  }
  /* chapter tick dots — 6 chapter starts on the journey; current one is gold.
     Each button is a 24px hit area around a 5px dot. */
  /* TRUE viewport centring: as a flex middle child the dots sat at the midpoint of
     the UNEQUAL side groups (small logo left vs Resume+pill right) → visibly
     off-centre. Absolute + translate centres them on the viewport itself. */
  #topbar .tb-ticks {
    display: flex; align-items: center; gap: 5px; pointer-events: auto;
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  }
  @media (max-width: 860px) { #topbar .tb-ticks { display: none; } }   /* centred dots would collide with the right links on narrow landscape windows */
  #topbar .tb-tick {
    width: 24px; height: 24px; padding: 0; border: 0; background: transparent;
    cursor: pointer; display: grid; place-items: center; border-radius: 50%;
  }
  #topbar .tb-tick::before {
    content: ''; width: 5px; height: 5px; border-radius: 50%;
    background: rgba(240, 246, 255, 0.35);
    transition: background 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
  }
  #topbar .tb-tick:hover::before { background: var(--accent-2); }
  #topbar .tb-tick.is-current::before {
    background: var(--accent); transform: scale(1.4);
    box-shadow: 0 0 8px rgba(232, 168, 72, 0.6);
  }
  /* Portrait/phone: wordmark + "Let's talk" only — Resume and the dots would crowd it */
  @media (max-aspect-ratio: 1/1) {
    #topbar { padding: 6px 14px; }
    #topbar .tb-resume, #topbar .tb-ticks { display: none; }
    #topbar .tb-talk { min-height: 44px; padding: 0.66rem 1.2rem; }   /* 44px tap target */
  }

  @media (prefers-reduced-motion: reduce) {
    #hint .line::after { animation: none; }
  }

  /* Final CTA — a single small clickable line that fades in only once the camera
     has settled at the LAST wall (Contact). The three wall HEADINGS themselves
     live in-scene as 3D labels (see makeWallLabel); this is just the closing
     mailto so the very end is actionable. */
  #endcta {
    position: fixed; left: 50%; top: 58%; transform: translateX(-50%);
    z-index: 5; text-align: center;
    opacity: 0; pointer-events: none;          /* JS reveals + enables clicks at the very end */
    transition: opacity 0.5s ease;
    display: flex; flex-direction: column; align-items: center; gap: 30px;
  }
  /* secondary tier — socials + email grouped tight, set well apart from the button
     so the close reads as [primary CTA] … [supporting links], not one cramped stack */
  #endcta .cta-secondary { display: flex; flex-direction: column; align-items: center; gap: 16px; }
  /* primary: Let’s talk → cal.com. A LUMINOUS gold outline that glows on hover — echoes the
     scene's glowing door frames + the card-frame hover, instead of a heavy solid-gold pill. */
  #endcta .cta-book {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: clamp(12px, 1.2vw, 15px); letter-spacing: 0.3em; text-indent: 0.3em;  /* tracked caps, indent re-centres them */
    text-transform: uppercase; color: var(--accent); text-decoration: none;
    border: 1px solid rgba(232, 168, 72, 0.5); border-radius: 6px;        /* architectural radius, not a 999px pill */
    padding: 0.82rem 1.95rem;
    background: rgba(232, 168, 72, 0.05);                                  /* a whisper of warmth, not a fill */
    box-shadow: inset 0 0 16px rgba(232, 168, 72, 0.06);
    transition: color .28s ease, border-color .28s ease, background .28s ease, box-shadow .28s ease, letter-spacing .28s ease;
  }
  #endcta .cta-book:hover {
    color: var(--accent-2); border-color: var(--accent-2);                /* brighter gold text + border (never navy-on-solid) */
    background: rgba(232, 168, 72, 0.1);
    box-shadow: 0 0 24px rgba(232, 168, 72, 0.33), inset 0 0 22px rgba(232, 168, 72, 0.12);  /* luminous glow, like the frames */
    letter-spacing: 0.34em; text-indent: 0.34em;
  }
  /* socials row */
  #endcta .cta-socials { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px 6px; }
  #endcta .cta-socials a {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--ink-muted); text-decoration: none; line-height: 1;
    padding: 0.55rem 0.72rem; border-radius: 6px;          /* roomier tap target; padding now does the spacing (gap trimmed) */
    transition: color 0.2s ease, background 0.2s ease;
  }
  #endcta .cta-socials a:hover  { color: var(--accent); background: rgba(232, 168, 72, 0.09); }
  #endcta .cta-socials a:active { color: var(--accent); background: rgba(232, 168, 72, 0.16); }   /* touch-tap feedback */
  /* email */
  #endcta .cta-email {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 12px; letter-spacing: 0.06em; color: var(--ink-muted);
    text-decoration: none; transition: color 0.2s ease;
  }
  #endcta .cta-email:hover { color: var(--accent); }
  /* Portrait: the framed stack is tall, so the CTA's `top` is driven by JS — anchored to
     the 3D door-frame's interior BOTTOM (see updateCamera) so socials + email can never
     spill out of the frame. Here we just compact the secondary links into ~2 tidy rows so
     the block is short enough to sit cleanly inside. */
  @media (max-aspect-ratio: 1/1) {
    #endcta { top: auto; bottom: 11vh; gap: 16px; }
    #endcta .cta-book { padding: 0.95rem 1.95rem; }   /* ~44px tap target on mobile */
    #endcta .cta-secondary { gap: 11px; }
    #endcta .cta-socials { width: 340px; max-width: 94vw; gap: 4px 2px; }
    #endcta .cta-socials a { font-size: 11px; letter-spacing: 0.04em; padding: 0.68rem 0.6rem; }
  }
