/* Nav glass: mobile + desktop scroll choreography.
   Mobile (≤640): bar scrub + always-on fixed burger + terminal pane.
   Desktop (≥641): sticky bar; Phase A words fade → B retract+split+burger
   fade-in → B2 chip glides column-left→17px seat → C holds until homepage
   .ticker band crosses it (clip bottom-up; then visibility:hidden under).
   Burger reparented to <body> when fixed so backdrop-filter ancestors
   cannot create a containing block (Safari/iOS + desktop glass).
   Chip + burger: matched 52px glass tiles; burger glyph ~21px (chip logo 26);
   17px seat insets. Desktop left-glide is JS scroll-scrub (no CSS hop). */

/* ---- timing tokens (open ~1.1–1.3s; close scaled; anim=slow = 5x) ----
   Half-speed of prior choreography. Open: bar contracts first; wordmark
   split starts at ~50% of bar duration and finishes with the chip. Panel
   trails the bar. Chip left-glide after collapse is JS-only (~220ms open;
   scroll-scrub on mobile + desktop). Close: reverse. */
:root{
  --nav-ease:cubic-bezier(0.22,1,0.36,1);
  --nav-ease-settle:cubic-bezier(0.16,1,0.3,1);
  /* Bar clip-path needs a gentler ease than the settle curve — the
     aggressive ease-out made mid-flight frames look fully collapsed. */
  --nav-ease-bar:cubic-bezier(0.4,0,0.2,1);

  /* open: bar 0–640; split 320–640; panel 560–1160; links from ~600 */
  --nav-t-bar:640ms;
  --nav-t-bar-delay:0ms;
  --nav-t-word:320ms;
  --nav-t-word-delay:320ms; /* ~50% of bar */
  --nav-t-panel:600ms;
  --nav-t-panel-delay:560ms;
  --nav-t-backdrop:600ms;
  --nav-t-backdrop-delay:80ms;
  --nav-t-link:360ms;
  --nav-t-link-stagger:60ms;
  --nav-t-link-base:600ms; /* first link ~600; last ~1140 with stagger */

  /* close: words return 0–280; bar expand 0–560; panel 0–400 */
  --nav-t-word-close:280ms;
  --nav-t-word-delay-close:0ms;
  --nav-t-bar-close:560ms;
  --nav-t-bar-delay-close:0ms;
  --nav-t-panel-close:400ms;
  --nav-t-panel-delay-close:0ms;
  --nav-t-backdrop-close:400ms;
  --nav-t-link-close:200ms;
}

html.menu-anim-slow{
  /* 5× the half-speed open/close targets for mid-flight QA capture */
  --nav-t-bar:3200ms;
  --nav-t-bar-delay:0ms;
  --nav-t-word:1600ms;
  --nav-t-word-delay:1600ms;
  --nav-t-panel:3000ms;
  --nav-t-panel-delay:2800ms;
  --nav-t-backdrop:3000ms;
  --nav-t-backdrop-delay:400ms;
  --nav-t-link:1800ms;
  --nav-t-link-stagger:300ms;
  --nav-t-link-base:3000ms;

  --nav-t-word-close:1400ms;
  --nav-t-word-delay-close:0ms;
  --nav-t-bar-close:2800ms;
  --nav-t-bar-delay-close:0ms;
  --nav-t-panel-close:2000ms;
  --nav-t-panel-delay-close:0ms;
  --nav-t-backdrop-close:2000ms;
  --nav-t-link-close:1000ms;
}

/* ---- Normalize header geometry (blog templates leak min-height / wrap /
   unscoped nav margin into the glass bar). Desktop matches homepage. ---- */
header.nav-glass nav.nav-links{
  flex-wrap:nowrap;
  margin:0;
  margin-bottom:0;
}
header.nav-glass nav.nav-links a{
  min-height:0;
  border-bottom:none;
  margin:0;
}
/* Content-area breadcrumb/nav styles must never hit the glass header */
header.nav-glass .brandmark,
header.nav-glass .brandmark-word,
header.nav-glass .wm-shell,
header.nav-glass .wm-drop{
  white-space:nowrap;
}

/* ---- burger button (self-contained glass; survives reparent to body) ----
   Geometry: JS pins from bar + chip seat. Outer tile mirrors the 52px
   icon chip (same glass/border/radius family); bars glyph ~21px (not the logo).
   Fallbacks until first measure. */
.nav-burger{
  display:none;
  align-items:center;
  justify-content:center;
  flex-shrink:0;
  width:52px;
  height:52px;
  margin:0;
  padding:0;
  border:1px solid var(--glass-border, rgba(255,255,255,.12));
  border-radius:14px;
  background:var(--glass, rgba(14,29,54,.72));
  color:var(--ink, #fff);
  cursor:pointer;
  position:relative;
  z-index:90;
  -webkit-tap-highlight-color:transparent;
  transition:background .15s ease,border-color .15s ease,color .15s ease;
  /* Own glass — not dependent on header/bar ancestors after reparent */
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  box-sizing:border-box;
  opacity:0;
  pointer-events:none;
  visibility:hidden;
}
.nav-burger.nav-burger-live{
  opacity:1;
  pointer-events:auto;
  visibility:visible;
}
.nav-burger:hover,
.nav-burger:focus-visible{
  background:var(--glass-strong);
  border-color:var(--cyan-dim);
  color:var(--cyan);
  outline:none;
}
.nav-burger:active{
  background:var(--cyan-faint);
  transform:scale(.96);
}
.nav-burger-icon{
  display:block;
  /* Glyph ~21px (~20% under prior 26px); 52px glass body unchanged */
  width:21px;
  height:14px;
  position:relative;
}
.nav-burger-icon .bar{
  position:absolute;
  left:0;
  height:2px;
  border-radius:1px;
  background:currentColor;
  transform-origin:center;
  transition:
    transform 260ms var(--nav-ease),
    top 260ms var(--nav-ease),
    width 260ms var(--nav-ease),
    opacity 180ms ease;
}
/* Unequal widths — prompt lines, not a generic hamburger */
.nav-burger-icon .bar-1{top:0;width:100%}
.nav-burger-icon .bar-2{top:6px;width:68%}
.nav-burger-icon .bar-3{top:12px;width:86%}

.nav-burger[aria-expanded="true"]{
  border-color:var(--cyan-dim);
  color:var(--cyan);
  background:var(--cyan-faint);
}
.nav-burger[aria-expanded="true"] .bar-1{
  top:6px;width:100%;transform:rotate(45deg);
}
.nav-burger[aria-expanded="true"] .bar-2{
  opacity:0;width:0;transform:scaleX(0);
}
.nav-burger[aria-expanded="true"] .bar-3{
  top:6px;width:100%;transform:rotate(-45deg);
}

/* ---- backdrop ---- */
.nav-backdrop{
  display:none;
  position:fixed;
  inset:0;
  z-index:60;
  background:rgba(2,7,15,.55);
  -webkit-backdrop-filter:blur(4px);
  backdrop-filter:blur(4px);
  opacity:0;
  pointer-events:none;
  transition:opacity var(--nav-t-backdrop-close) var(--nav-ease) 0ms;
}
.nav-backdrop.is-open{
  opacity:1;
  pointer-events:auto;
  transition:opacity var(--nav-t-backdrop) var(--nav-ease) var(--nav-t-backdrop-delay);
}

/* Icon chip + burger above dim when open */
body.nav-menu-open .nav-glass{
  position:relative;
  z-index:80;
}

/* ---- wordmark split (markup from sync; resting look = "ShellDrop") ---- */
.brandmark-word{
  display:inline-flex;
  align-items:baseline;
  white-space:nowrap;
  /* inherit type from .brandmark span rules on each page */
}
.brandmark-word .wm-shell,
.brandmark-word .wm-drop{
  display:inline-block;
  /* no extra spacing — adjacent inline-blocks read as ShellDrop */
}

/* ---- terminal pane (shared; mobile always-on off-screen, desktop on open) ----
   Selectors use nav.nav-links so styles still apply after JS reparents
   the pane to document.body (escapes the glass-inner filter container). */
nav.nav-links.nav-pane-mode{
  position:fixed;
  top:0;
  right:0;
  bottom:0;
  left:auto;
  width:min(80vw,340px);
  height:100%;
  height:100dvh;
  margin:0;
  /* full-height panel; top pad clears floating × only */
  padding:calc(env(safe-area-inset-top,0px) + 72px) 22px calc(env(safe-area-inset-bottom,0px) + 28px);
  display:flex;
  flex-direction:column;
  flex-wrap:nowrap;
  align-items:stretch;
  justify-content:flex-start;
  gap:4px;
  background-color:#060f1f;
  background-color:var(--bg-base);
  background-image:
    linear-gradient(180deg, #0e1d36 0%, #060f1f 38%, #02070f 100%);
  background-image:
    linear-gradient(180deg, var(--bg-rise) 0%, var(--bg-base) 38%, var(--bg-deep) 100%);
  border:none;
  border-left:1px solid rgba(0,212,255,.24);
  border-left-color:var(--cyan-dim);
  box-shadow:
    -1px 0 0 rgba(0,212,255,.08),
    -18px 0 48px rgba(0,0,0,.5),
    inset 1px 0 0 rgba(0,212,255,.06);
  transform:translateX(100%);
  visibility:hidden;
  pointer-events:none;
  z-index:70;
  transition:
    transform var(--nav-t-panel-close) var(--nav-ease) var(--nav-t-panel-delay-close),
    visibility 0s linear var(--nav-t-panel-close);
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
}
nav.nav-links.nav-pane-mode.is-open{
  transform:translateX(0);
  visibility:visible;
  pointer-events:auto;
  transition:
    transform var(--nav-t-panel) var(--nav-ease-settle) var(--nav-t-panel-delay),
    visibility 0s linear 0s;
}

nav.nav-links.nav-pane-mode a{
  display:flex;
  align-items:center;
  gap:0;
  min-height:48px;
  padding:12px 14px;
  font-family:var(--mono),'Geist Mono','SF Mono',ui-monospace,monospace;
  font-size:15px;
  font-weight:500;
  letter-spacing:.02em;
  color:rgba(255,255,255,.72);
  color:var(--ink-soft);
  border-radius:8px;
  border:1px solid transparent;
  border-bottom:none;
  text-decoration:none;
  opacity:0;
  transform:translateX(14px);
  transition:
    opacity var(--nav-t-link-close) ease 0ms,
    transform var(--nav-t-link-close) var(--nav-ease) 0ms,
    color 120ms ease,
    background 120ms ease,
    border-color 120ms ease;
}
/* Prompt-line prefix — decorative only */
nav.nav-links.nav-pane-mode a::before{
  content:">";
  color:#00d4ff;
  color:var(--cyan);
  font-family:var(--mono),'Geist Mono','SF Mono',ui-monospace,monospace;
  font-weight:600;
  margin-right:10px;
  flex-shrink:0;
  opacity:.9;
}
nav.nav-links.nav-pane-mode.is-open a{
  opacity:1;
  transform:translateX(0);
}
/* Stagger after panel begins sliding */
nav.nav-links.nav-pane-mode.is-open a:nth-child(1){
  transition-delay:var(--nav-t-link-base);
  transition-duration:var(--nav-t-link);
  transition-timing-function:var(--nav-ease);
}
nav.nav-links.nav-pane-mode.is-open a:nth-child(2){
  transition-delay:calc(var(--nav-t-link-base) + var(--nav-t-link-stagger));
  transition-duration:var(--nav-t-link);
  transition-timing-function:var(--nav-ease);
}
nav.nav-links.nav-pane-mode.is-open a:nth-child(3){
  transition-delay:calc(var(--nav-t-link-base) + var(--nav-t-link-stagger) * 2);
  transition-duration:var(--nav-t-link);
  transition-timing-function:var(--nav-ease);
}
nav.nav-links.nav-pane-mode.is-open a:nth-child(4){
  transition-delay:calc(var(--nav-t-link-base) + var(--nav-t-link-stagger) * 3);
  transition-duration:var(--nav-t-link);
  transition-timing-function:var(--nav-ease);
}
nav.nav-links.nav-pane-mode.is-open a:nth-child(5){
  transition-delay:calc(var(--nav-t-link-base) + var(--nav-t-link-stagger) * 4);
  transition-duration:var(--nav-t-link);
  transition-timing-function:var(--nav-ease);
}
nav.nav-links.nav-pane-mode.is-open a:nth-child(6){
  transition-delay:calc(var(--nav-t-link-base) + var(--nav-t-link-stagger) * 5);
  transition-duration:var(--nav-t-link);
  transition-timing-function:var(--nav-ease);
}

nav.nav-links.nav-pane-mode a:hover,
nav.nav-links.nav-pane-mode a:focus-visible{
  color:#fff;
  color:var(--ink);
  background:rgba(0,212,255,.08);
  background:var(--cyan-faint);
  border-color:rgba(0,212,255,.24);
  border-color:var(--cyan-dim);
  outline:none;
}
nav.nav-links.nav-pane-mode a:active{
  background:rgba(0,212,255,.24);
  background:var(--cyan-dim);
  color:#fff;
  color:var(--ink);
  transform:scale(.98);
}

/* Desktop pane slightly wider */
@media (min-width:641px){
  nav.nav-links.nav-pane-mode{
    width:min(92vw,380px);
  }
}

/* ========== MOBILE (≤640) ========== */
@media (max-width:640px){
  .nav-burger{
    display:inline-flex;
    /* Always live on mobile */
    opacity:1;
    pointer-events:auto;
    visibility:visible;
  }
  .nav-backdrop{display:block}

  /*
   * Burger: FIXED top-right always on mobile (scroll-detached).
   * Must be a direct body child (JS reparents) — any ancestor with
   * backdrop-filter / filter / transform creates a containing block
   * and breaks viewport-fixed on Safari/iOS.
   * top/right/width/height/radius: set by nav-burger.js from live
   * bar + icon tile rects (no magic numbers that drift per page).
   * Fallbacks approximate rest geometry until first measure.
   * z-index 90 > panel 70 > backdrop 60.
   */
  .nav-burger{
    position:fixed;
    top:calc(env(safe-area-inset-top,0px) + 24px);
    right:max(17px, env(safe-area-inset-right,0px) + 17px);
    width:52px;
    height:52px;
    border-radius:14px;
    z-index:90;
    /* isolation so fixed stacking is predictable vs body siblings */
    isolation:isolate;
  }

  /* ---- bar collapse: right edge sweeps left → icon chip ----
     Default open/close still driven by body.nav-menu-open + CSS transitions.
     Scroll scrub (nav-burger.js) sets html.nav-scrub-drive and drives the same
     properties via inline styles + --nav-collapse / --nav-chip-opacity. */
  .nav-glass-inner{
    transform-origin:left center;
    /* overflow visible so Shell/Drop can fly ±24px outside the bar;
       clip-path alone owns the right→left chip collapse */
    overflow:visible;
    /* closed: fully visible; close choreography on resting rule */
    clip-path:inset(0 0% 0 0 round 16px);
    transition:
      clip-path var(--nav-t-bar-close) var(--nav-ease-bar) var(--nav-t-bar-delay-close),
      padding var(--nav-t-bar-close) var(--nav-ease) var(--nav-t-bar-delay-close),
      gap var(--nav-t-bar-close) var(--nav-ease) var(--nav-t-bar-delay-close),
      border-radius var(--nav-t-bar-close) var(--nav-ease) var(--nav-t-bar-delay-close),
      opacity var(--nav-t-bar-close) linear;
  }
  body.nav-menu-open .nav-glass-inner{
    /* Solid chip (not clip): border 1 + pad 12 + icon 26 + pad 12 + border 1
       → 52×52. Full border paints on all four sides so icon is centered. */
    clip-path:none;
    width:52px;
    max-width:52px;
    overflow:hidden;
    border-radius:14px;
    padding:12px;
    gap:0;
    justify-content:flex-start;
    /* chip must not steal taps from the full-height panel */
    pointer-events:none;
    transition:
      width var(--nav-t-bar) var(--nav-ease-bar) var(--nav-t-bar-delay),
      max-width var(--nav-t-bar) var(--nav-ease-bar) var(--nav-t-bar-delay),
      clip-path var(--nav-t-bar) var(--nav-ease-bar) var(--nav-t-bar-delay),
      padding var(--nav-t-bar) var(--nav-ease) var(--nav-t-bar-delay),
      gap var(--nav-t-bar) var(--nav-ease) var(--nav-t-bar-delay),
      border-radius var(--nav-t-bar) var(--nav-ease) var(--nav-t-bar-delay),
      opacity var(--nav-t-bar) linear;
  }
  body.nav-menu-open .nav-glass-inner .brandmark{
    pointer-events:auto;
  }

  /* brandmark: icon stays; wordmark splits out */
  .brandmark{
    min-width:0;
    overflow:visible;
  }
  .brandmark img{
    flex-shrink:0;
    opacity:1;
    /* icon never fades */
  }
  .brandmark-word{
    /* width stays; bar clip-path is what sweeps the chip.
       Split spans do the fly-apart — don't zero max-width or the
       mid-flight "Shell"/"Drop" glyphs get clipped away. */
    overflow:visible;
  }
  .brandmark-word .wm-shell,
  .brandmark-word .wm-drop{
    /* opacity linear so mid-flight frames still read "Shell"/"Drop";
       transform keeps the decisive ease-out settle */
    transition:
      transform var(--nav-t-word-close) var(--nav-ease-settle) var(--nav-t-word-delay-close),
      opacity var(--nav-t-word-close) linear var(--nav-t-word-delay-close);
    will-change:transform,opacity;
  }
  body.nav-menu-open .brandmark-word{
    pointer-events:none;
  }
  body.nav-menu-open .brandmark-word .wm-shell{
    /* ±12px stays inside the bar (clip-path would eat ±24 outside the box) */
    transform:translateY(-12px);
    opacity:0;
    transition:
      transform var(--nav-t-word) var(--nav-ease-settle) var(--nav-t-word-delay),
      opacity var(--nav-t-word) linear var(--nav-t-word-delay);
  }
  body.nav-menu-open .brandmark-word .wm-drop{
    transform:translateY(12px);
    opacity:0;
    transition:
      transform var(--nav-t-word) var(--nav-ease-settle) var(--nav-t-word-delay),
      opacity var(--nav-t-word) linear var(--nav-t-word-delay);
  }
  body.nav-menu-open .brandmark{
    gap:0;
  }

  /* Scroll-driven collapse: kill CSS transitions so rAF scrub is jank-free.
     JS owns clip-path / padding / gap / radius / wordmark / opacity. */
  html.nav-scrub-drive .nav-glass-inner,
  html.nav-scrub-drive .brandmark-word .wm-shell,
  html.nav-scrub-drive .brandmark-word .wm-drop{
    transition:none!important;
  }
  /* While scrub-driving, ignore body.nav-menu-open bar rules (panel still uses CSS). */
  html.nav-scrub-drive body.nav-menu-open .nav-glass-inner{
    /* leave geometry to inline; keep pointer-events rule */
    clip-path:unset;
    border-radius:unset;
    padding:unset;
    gap:unset;
    width:unset;
    max-width:unset;
    overflow:unset;
  }
  html.nav-scrub-drive body.nav-menu-open .brandmark-word .wm-shell,
  html.nav-scrub-drive body.nav-menu-open .brandmark-word .wm-drop{
    transform:unset;
    opacity:unset;
  }
  /* Fixed chip shell while collapsed/scrolled (JS also sets geometry).
     z-index below .ticker (50) so the band occludes the chip mid-cross. */
  .nav-glass-inner.nav-bar-fixed{
    position:fixed;
    z-index:40;
    margin:0;
    max-width:none;
  }
  .nav-glass.nav-bar-spacer-on{
    /* height set inline from measured rest bar */
  }
}

/* ========== DESKTOP (≥641) ========== */
@media (min-width:641px){
  /* Sticky glass header — bar stays at top through Phase A/B */
  header.nav-glass{
    position:sticky;
    top:0;
    z-index:50;
    /* keep page paint from flashing above the sticky bar */
    background:transparent;
  }

  .nav-burger{
    display:inline-flex;
    position:fixed;
    top:calc(env(safe-area-inset-top,0px) + 24px);
    right:max(17px, env(safe-area-inset-right,0px) + 17px);
    /* Same 52 glass tile as the icon chip (mobile + desktop) */
    width:52px;
    height:52px;
    border-radius:14px;
    z-index:90;
    isolation:isolate;
    /* opacity/visibility driven by JS (nav-burger-live + inline opacity) */
  }

  .nav-backdrop{display:block}

  .nav-glass-inner{
    transform-origin:left center;
    overflow:visible;
  }

  /* Inline nav words: JS drives opacity during Phase A */
  header.nav-glass nav.nav-links:not(.nav-pane-mode){
    transition:none; /* scrub owns opacity */
  }
  header.nav-glass nav.nav-links:not(.nav-pane-mode) a{
    /* no min-height inflation — match homepage */
    min-height:0;
    line-height:1.2;
  }

  /* brandmark split during scrub */
  .brandmark{
    min-width:0;
    overflow:visible;
  }
  .brandmark img{flex-shrink:0}
  .brandmark-word{overflow:visible}
  .brandmark-word .wm-shell,
  .brandmark-word .wm-drop{
    will-change:transform,opacity;
  }

  /* Scrub: kill transitions; JS owns geometry */
  html.nav-scrub-drive .nav-glass-inner,
  html.nav-scrub-drive .brandmark-word .wm-shell,
  html.nav-scrub-drive .brandmark-word .wm-drop{
    transition:none!important;
  }
  html.nav-scrub-drive body.nav-menu-open .nav-glass-inner{
    clip-path:unset;
    border-radius:unset;
    padding:unset;
    gap:unset;
    width:unset;
    max-width:unset;
    overflow:unset;
  }
  html.nav-scrub-drive body.nav-menu-open .brandmark-word .wm-shell,
  html.nav-scrub-drive body.nav-menu-open .brandmark-word .wm-drop{
    transform:unset;
    opacity:unset;
  }

  /* Below .ticker so the band occludes the chip mid-cross (same as mobile). */
  .nav-glass-inner.nav-bar-fixed{
    position:fixed;
    z-index:40;
    margin:0;
    max-width:none;
  }

  /* When menu open on desktop, don't let sticky header fight panel z */
  body.nav-menu-open header.nav-glass{
    z-index:80;
  }
}

/* Homepage agent ticker: above fixed chip (40), below burger (90).
   Solid --bg-deep for z-occlusion; JS also clip-path's the chip to the
   band's top edge so a short band never leaves a poke-out below. */
.ticker{
  position:relative;
  z-index:50;
  background:var(--bg-deep, #02070f);
}

body.nav-menu-open{
  overflow:hidden;
  touch-action:none;
}

/* ---- reduced motion: instant state swap ---- */
@media (prefers-reduced-motion:reduce){
  .nav-burger-icon .bar,
  .nav-backdrop,
  nav.nav-links.nav-pane-mode,
  nav.nav-links.nav-pane-mode a,
  .nav-glass-inner,
  .brandmark-word,
  .brandmark-word .wm-shell,
  .brandmark-word .wm-drop{
    transition:none!important;
    animation:none!important;
  }
  nav.nav-links.nav-pane-mode a{
    opacity:1;
    transform:none;
  }
  body.nav-menu-open .brandmark-word .wm-shell,
  body.nav-menu-open .brandmark-word .wm-drop{
    transform:none;
    opacity:0;
  }
}

/* Headless QA (?menu=open, no anim=slow): end-state, skip cascade */
html.menu-open-qa:not(.menu-anim-slow) nav.nav-links.nav-pane-mode,
html.menu-open-qa:not(.menu-anim-slow) nav.nav-links.nav-pane-mode a,
html.menu-open-qa:not(.menu-anim-slow) .nav-glass-inner,
html.menu-open-qa:not(.menu-anim-slow) .brandmark-word,
html.menu-open-qa:not(.menu-anim-slow) .brandmark-word .wm-shell,
html.menu-open-qa:not(.menu-anim-slow) .brandmark-word .wm-drop,
html.menu-open-qa:not(.menu-anim-slow) .nav-backdrop{
  transition:none!important;
  transition-delay:0s!important;
}
html.menu-open-qa:not(.menu-anim-slow) nav.nav-links.nav-pane-mode a{
  opacity:1!important;
  transform:none!important;
}
html.menu-open-qa:not(.menu-anim-slow) body.nav-menu-open .brandmark-word .wm-shell,
html.menu-open-qa:not(.menu-anim-slow) body.nav-menu-open .brandmark-word .wm-drop{
  opacity:0!important;
  transform:none!important;
}
