/* ============================================================
   TUNLstack v2 — Site shared CSS (page chrome only)
   Composed pages inline each scene's styles scoped under
   [data-section="<name>"]; THIS file owns the page level:
   dark Void base, skip-link, nav shell (nav-minimal-utility),
   footer (footer-minimal-centered), section baseline.

   DELIBERATELY THIN — the choreography layer (Task 10) owns all
   scroll/motion logic. No animation logic lives here beyond the
   nav's hairline-on-scroll state and the blocks' own reveals.

   Tokens: ../assets/showroom/tokens/tokens.css (Ice Blue on
   Void, DARK ONLY — no light mode by design).
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  color-scheme: dark;
  background: var(--color-base);
  /* NO scroll-behavior: smooth — EVER, while Lenis drives the scroll. Lenis
     writes scrollTop every rAF; CSS smooth turns each write into a native
     animation the next write interrupts, so the real page crawls while
     Lenis's internal position races ahead, then snap-teleports on resync
     (measured 2026-07-09: 7,668px desync, the N5 rail pin jamming
     mid-traversal, free-spin flings — _scroll_probe.py). Wheel smoothing is
     Lenis's job; anchor jumps are deliberately instant on all inputs. */
  /* overflow-x on BOTH html and body — body alone doesn't suppress
     html-level horizontal scroll. */
  overflow-x: hidden;
}
body {
  min-height: 100vh;
  background: var(--color-base);
  color: var(--color-text-secondary);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* MUST be `clip`, never `hidden` — `overflow-x: hidden` forces computed
     `overflow-y: auto`, making <body> the NEAREST SCROLL CONTAINER, so the
     hero8 curtain's `position: sticky` descendant sticks to body's scrollport
     (which never scrolls) and the pin silently never engages (hero measured at
     -796px in the c01 probe). `clip` clips X without creating a scrollport
     (Chrome 90+/FF 81+/Safari 16+). See the hero8 CURTAIN block below.
     (html's overflow-x stays `hidden` above — it propagates to the viewport and
     is harmless there.) */
  overflow-x: clip;
}
a { color: inherit; }
img, svg, video { max-width: 100%; }

/* ---- composed sections baseline ---- */
main { display: block; }
.sec { display: block; position: relative; }

/* ============================================================================
   hero8 pinned-hero CURTAIN — page-level rules
   design: docs/plans/2026-07-12-tunlstack-hero8-curtain-reveal-design.md §1/§2/§4
   The homepage hero pins while every section below scrolls UP and over its held
   film, behind a soft leading-edge seam; once consumed (film ended + covered
   once) the hero is REMOVED so scroll-back never finds a blank end-state hero.
   The removal + chevron scroll-follow JS lives in the hero block's sequencer
   (assets/showroom/blocks/hero/hero-tunnel-split-video.html).

   WHY HERE, not in the block's <style>: _compose.py `scope_css()` prefixes every
   block-authored rule with `[data-section="hero"]`. Since the compose wrapper is
   `<section data-section="hero" class="sec sec--hero">`, `.sec--hero` IS that
   scope element — a block rule `.sec--hero{…}` would become
   `[data-section="hero"] .sec--hero{…}` (a descendant that never exists) and the
   sticky would silently die. These are page-level (unscoped) rules, so they live
   in shared.css. Homepage-only by construction: `.sec--hero` exists only on index
   (the /how-it-works first section is not a hero). The block owns only JS +
   its own `.hero`-scoped CSS.
   ============================================================================ */
/* the pin. `position: sticky` keeps the hero's flow slot exactly where it is —
   zero added page height, zero shifted trigger math for the IO reveals and the
   two ScrollTrigger rigs. <main> is the sticky containing block, so the hero
   stays pinned under every riser and releases only as main's bottom edge passes
   — fully covered by then, so the release is invisible; the footer (outside main)
   never overlaps. Later .sec siblings (position:relative, z-auto) paint above the
   pinned hero by plain DOM order — no z-index anywhere in the contract. */
.sec--hero { position: sticky; top: 0; }
/* risers must be opaque or the pinned film ghosts through them (Void-on-Void
   no-op today; future-proofs any non-opaque section). */
main > .sec:not(.sec--hero) { background: var(--color-base); }
/* SOFT seam (Robert lock, 3-tab compare): a paint-only leading-edge scrim hanging
   ABOVE the first riser's top edge, so the film dims progressively just ahead of
   the curtain line. Zero JS, zero scroll-coupled styling. The hero's own 34vh
   bottom fade (`.hero::after`) STAYS; the two compose cleanly (no banding). */
.sec--hero + .sec::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 100%;
  height: clamp(90px, 14vh, 180px);
  background: linear-gradient(to top, var(--color-base), transparent);
  pointer-events: none;
}
/* GONE return state (Robert Q6 pick): the sequencer adds `.is-gone` once the hero
   is consumed (film ended + covered), compensating scroll the same frame so the
   on-screen pixels don't move. Scroll-back then tops out on hero #2; reload
   restores the hero. */
.sec--hero.is-gone { display: none; }
/* Reduced-motion: NO curtain (content sliding over a fixed backdrop is the
   parallax/vestibular-trigger class). The sequencer never runs here, so there is
   no removal and no chevron either — static stacked text over the poster. The
   seam is gated off too (under normal flow it would paint a stray gradient band
   on the hero's bottom edge). */
@media (prefers-reduced-motion: reduce) {
  .sec--hero { position: relative; }
  .sec--hero + .sec::before { content: none; }
}

/* ============================================================
   Skip link — keyboard-first (from nav-minimal-utility)
   ============================================================ */
.skip-link {
  position: absolute;
  left: var(--space-5);
  top: -64px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--color-surface-2);
  color: var(--color-text-primary);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: top var(--dur-micro) var(--ease);
}
.skip-link:focus { top: var(--space-4); }

/* ============================================================
   NAV SHELL — minimal utility (locked nav-minimal-utility)
   Brand mark left · one primary CTA + slim menu trigger right.
   Solid Void bar (NO backdrop-filter). 1px Ash hairline once
   scrolled. Menu opens a quiet Void panel.
   ============================================================ */
/* FLOATING BLACK PILL (Rivian treatment, black instead of white — Robert #7).
   The shell is a transparent full-width positioner; the pill is __inner. */
.nav-shell {
  position: fixed;
  top: clamp(12px, 1.8vh, 20px); left: 0; right: 0;
  z-index: 50;
  padding: 0 clamp(14px, 4vw, 40px);
}
/* Pages whose first section is NOT a full-bleed hero clear the floating pill. */
body[data-first-hero="false"] main { padding-top: 94px; }
@media (max-width: 600px) { body[data-first-hero="false"] main { padding-top: 82px; } }

.nav-shell__inner {
  max-width: calc(var(--maxw-content) + 148px);   /* pill extends past the content column (Robert) */
  margin: 0 auto;
  height: 60px;
  padding: 0 30px;                                 /* symmetric — Menu inset matches the wordmark's left inset */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  /* the pill */
  background: #101013;
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: 999px;
  box-shadow: 0 10px 34px -10px rgba(0,0,0,0.62);
  transition: box-shadow var(--dur-micro) var(--ease), border-color var(--dur-micro) var(--ease);
}
.nav-shell[data-scrolled="true"] .nav-shell__inner {
  border-color: rgba(255,255,255,0.13);
  box-shadow: 0 12px 42px -8px rgba(0,0,0,0.74);
}

/* ---- brand mark — BESPOKE WORDMARK swap (compose-time promise):
   the block's inline SVG-glyph + text lockup is replaced with the
   identity asset media/identity/wordmark-bespoke.png (2400x280). ---- */
.brand-mark {
  display: inline-flex;
  align-items: center;
  flex: none;
  text-decoration: none;
  -webkit-user-select: none;
  user-select: none;
  border-radius: var(--radius-sm);
}
.brand-mark__img {
  display: block;
  height: 22px;
  width: auto;
}
.brand-mark:focus { outline: none; }
.brand-mark:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 6px;
}

/* ---- right utility group: single CTA + menu trigger ---- */
.nav-utility {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex: none;
}

.nav-shell .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: var(--weight-medium);
  line-height: 1;
  padding: 10px 18px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur-micro) var(--ease),
              border-color var(--dur-micro) var(--ease),
              color var(--dur-micro) var(--ease),
              transform var(--dur-micro) var(--ease),
              box-shadow var(--dur-micro) var(--ease);
}
.nav-shell .btn:focus { outline: none; }
.nav-shell .btn:focus-visible { outline: 2px solid var(--color-primary-frost); outline-offset: 2px; }
.nav-shell .btn .icon { width: 1.05em; height: 1.05em; flex: none; display: block; }

.nav-shell .btn--ghost {
  background-color: transparent;
  color: var(--color-text-primary);
  border-color: var(--color-border);
}
.nav-shell .btn--ghost:hover { color: var(--color-primary-light); border-color: var(--color-primary); background-color: var(--color-primary-tint); }
.nav-shell .btn--ghost:active { color: var(--color-primary-frost); border-color: var(--color-primary-deep); background-color: transparent; }

.nav-shell .btn--primary {
  background-color: var(--color-primary);
  color: var(--color-text-on-primary);
  border-color: var(--color-primary);
  font-weight: var(--weight-display);
}
.nav-shell .btn--primary:hover { background-color: var(--color-primary-light); border-color: var(--color-primary-light); transform: translateY(-1px); box-shadow: var(--karaoke-glow); }
.nav-shell .btn--primary:active { background-color: var(--color-primary-deep); border-color: var(--color-primary-deep); color: var(--color-primary-frost); transform: translateY(0); box-shadow: none; }

/* ---- slim line-icon menu trigger ---- */
.nav-menu-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
  height: 40px;
  padding: 0 14px 0 12px;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  font-family: var(--font-display);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--dur-micro) var(--ease), color var(--dur-micro) var(--ease);
}
.nav-menu-btn:hover { border-color: var(--color-text-tertiary); color: var(--color-text-primary); }
.nav-menu-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; }
.nav-menu-btn svg { width: 18px; height: 18px; display: block; }
.nav-menu-btn .icon-close { display: none; }
.nav-menu-btn[aria-expanded="true"] { border-color: var(--color-primary-deep); color: var(--color-text-primary); }
.nav-menu-btn[aria-expanded="true"] .icon-open  { display: none; }
.nav-menu-btn[aria-expanded="true"] .icon-close { display: block; }
.nav-menu-btn__label { line-height: 1; }

/* ---- the open menu — compact dropdown anchored right under the Menu button ----
   No "Navigate" label, no numbering, narrow (Robert menu feedback). ---- */
.nav-menu-wrap { position: relative; display: inline-flex; }
.nav-panel {
  display: none;
  position: absolute;
  top: calc(100% + 14px);
  right: 0;
  width: 212px;
  background: #141416;
  border: 1px solid rgba(255,255,255,0.09);
  border-radius: var(--radius-lg);
  box-shadow: 0 26px 64px -22px rgba(0,0,0,0.78);
  overflow: hidden;
}
.nav-panel[data-open="true"] { display: block; animation: nav-panel-in var(--dur-micro) var(--ease) both; }
@keyframes nav-panel-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.nav-panel__links { display: flex; flex-direction: column; gap: 2px; padding: var(--space-2); }
.nav-panel__link {
  display: flex; align-items: center;
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: var(--weight-medium);
  letter-spacing: -0.01em;
  color: var(--color-text-secondary);
  text-decoration: none;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  transition: color var(--dur-micro) var(--ease), background-color var(--dur-micro) var(--ease);
}
.nav-panel__link:hover,
.nav-panel__link:focus-visible { color: var(--color-text-primary); background: var(--color-primary-tint); }
.nav-panel__link:focus { outline: none; }
.nav-panel__link:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
/* "Buy now" + "Try now" read as the menu's CTAs — each with its own separator
   bar above it (the panel's overflow:hidden clips the rounded corners). */
.nav-panel__link--cta {
  color: var(--color-primary-light);
  font-weight: var(--weight-display);
  margin-top: 4px;
  border-top: 1px solid rgba(255,255,255,0.07);
  padding-top: 13px;
}
.nav-panel__link--cta:hover,
.nav-panel__link--cta:focus-visible { color: var(--color-text-on-primary); background: var(--color-primary); }

/* ============================================================
   FOOTER — minimal centered (locked footer-minimal-centered)
   Flat on Void, Ash top hairline, bespoke wordmark centered,
   one wrapped link row, reassurance + mono copyright.
   ============================================================ */
.site-footer {
  border-top: 1px solid var(--color-border);
  background: var(--color-base);
  padding: var(--space-8) var(--space-5);
}
.footer-inner {
  max-width: 760px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-6);
}
.site-footer .brand-mark__img { height: 26px; }

.footer-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--space-3) 0;
}
.footer-row a {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  color: var(--color-text-secondary);
  text-decoration: none;
  padding: 0 var(--space-5);
  transition: color var(--dur-micro) var(--ease);
}
.footer-row a:hover { color: var(--color-primary-light); }
.footer-row a:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
  color: var(--color-primary-light);
}
.footer-row a:focus { outline: none; }
.footer-row a + a { border-left: 1px solid var(--color-border); }

.reassurance {
  font-family: var(--font-display);
  font-size: var(--fs-mono-label);
  letter-spacing: var(--tracking-mono);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin: 0;
}
.reassurance .dot, .copyright .dot { color: var(--color-primary); margin: 0 0.7em; }

.copyright {
  font-family: var(--font-display);
  font-size: var(--fs-mono-label);
  letter-spacing: 0.02em;
  /* natural case — uppercase would mangle brand casing (aioLABS / TUNLstack) */
  text-transform: none;
  color: var(--color-text-muted);
  margin: 0;
}

/* third-party trademark attribution + non-affiliation notice (canonical block:
   docs/plans/2026-07-16-third-party-trademark-usage-decision.md). Subordinate
   to our own marks by design; natural case preserves brand casing. */
.site-footer .attribution {
  font-family: var(--font-display);
  font-size: var(--fs-mono-label);
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--color-text-muted);
  max-width: 68ch;
  line-height: 1.7;
  margin: 0;
}

/* ---- responsive ---- */
@media (max-width: 600px) {
  /* symmetric pill insets + tighter gaps + a trimmed wordmark so the
     wordmark · Download · Menu row FITS without the menu button crowding or
     overflowing the pill's right edge. (Was `padding: 0 8px 0 18px` — 8px right
     vs 18px left — on top of a ~163px-wide wordmark that pushed the row past the
     pill. Robert flagged the misalignment 2026-07-17.) */
  .nav-shell__inner { height: 60px; padding: 0 14px; gap: var(--space-3); }
  .nav-utility { gap: var(--space-3); }
  .nav-utility .btn--primary .label-full { display: none; }
  .nav-utility .btn--primary .label-short { display: inline; }
  .nav-shell .btn { padding: 9px 13px; font-size: 0.86rem; }
  .nav-menu-btn__label { display: none; }
  .nav-menu-btn { padding: 0; width: 40px; justify-content: center; }
  .nav-panel__links { grid-template-columns: 1fr; }
  .brand-mark__img { height: 16px; }
}
.label-short { display: none; }

/* very narrow phones (<=380px): the Download CTA collapses to its download-arrow
   icon so the wordmark + menu never crowd the pill. Rule G stays satisfied — the
   primary CTA is still present, blue, and tappable; the "Download" label returns
   above 380px, and the menu panel also carries Download / Buy now / Try now. */
@media (max-width: 380px) {
  .nav-utility .btn--primary .label-short { display: none; }
  .nav-shell .btn--primary { padding: 9px 11px; }
}

@media (max-width: 460px) {
  .footer-row a { padding: 0 var(--space-4); }
  .footer-row { gap: var(--space-4) 0; }
  .footer-row a + a { border-left: none; }
}

@media (prefers-reduced-motion: reduce) {
  .nav-shell, .skip-link, .nav-shell .btn, .nav-menu-btn,
  .nav-panel__link, .nav-panel__link::after, .nav-panel__link .idx,
  .footer-row a { transition-duration: 0.01ms; }
  .nav-shell .btn--primary:hover { transform: none; }
}
