/* ============================================================
   THROTTLECROSS — global chrome
   Reset · base type · a11y · header/RPM · footer · forms ·
   gate wipe · texture utilities. Hand-authored, token-driven.
   ============================================================ */

/* ---- reset ------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html {
  -webkit-text-size-adjust: 100%;
  /* T-001: body's clip alone leaves the viewport pannable a few px
     on ≤320 screens (root stays visible, so the UA never applies
     the clip to the viewport). Clipping the root itself kills the
     sideways wiggle without creating a scroll container. */
  overflow-x: clip;
}
body {
  min-height: 100svh;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--font-text);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img, picture, svg, canvas { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
h1, h2, h3, h4 { line-height: 1.05; overflow-wrap: break-word; }
p { overflow-wrap: break-word; }
ul[class], ol[class] { list-style: none; padding: 0; }
a { color: inherit; }

::selection { background: var(--throttle-red); color: var(--bone); }

/* scrollbar — pit-lane thin */
html { scrollbar-color: var(--dirt-mid) var(--ink); }
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--ink); }
::-webkit-scrollbar-thumb {
  background: var(--dirt-mid);
  border: 2px solid var(--ink);
  border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: var(--throttle-red-dim); }

/* ---- a11y -------------------------------------------------- */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--holeshot-blue-bright);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px oklch(95.5% 0.007 90 / .22); /* bone halo — two-tone ring */
  border-radius: 2px;
}

/* Hidden by clipping, not by an off-screen translate: the old
   -100%-1.2rem park cleared the viewport top by ~10px, and iOS
   Safari hands that back during rubber-band scroll and under the
   status-bar overlay, so the red slab peeked over the header.
   Clipped geometry cannot leak at any viewport offset, and the link
   stays focusable and announced. */
.skip-link {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + .6rem);
  left: calc(env(safe-area-inset-left, 0px) + .6rem);
  z-index: 300;
  padding: .7rem 1.2rem;
  background: var(--throttle-red-deep);
  color: var(--bone);
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  text-decoration: none;
  clip-path: inset(50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out-expo);
}
.skip-link:focus,
.skip-link:focus-visible {
  clip-path: none;
  opacity: 1;
  pointer-events: auto;
}

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- type utilities ---------------------------------------- */
.display {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .01em;
  line-height: .92;
}
.display--slant { transform: skewX(var(--slant)); }
.mono {
  font-family: var(--font-data);
  font-weight: 500;
  font-size: var(--text-micro);
  letter-spacing: .075em;
  text-transform: uppercase;
}

/* section kicker — printed running head. Inside a .section-head it
   sits under the thick-thin rule pair (see pages.css); on its own
   it is a quiet data label. The old gradient tail is gone. */
.kicker {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  color: var(--bone-mute);
  font-family: var(--font-data);
  font-weight: 600;
  font-size: var(--text-micro);
  letter-spacing: .075em;
  text-transform: uppercase;
  white-space: nowrap;
}
.kicker__no { color: var(--throttle-red-bright); font-weight: 700; }

/* ---- layout ------------------------------------------------ */
.wrap {
  width: min(100% - 2 * var(--gutter), var(--page-max));
  margin-inline: auto;
}
main { display: block; }

/* ---- texture utilities ------------------------------------- */
/* film grain: inline SVG turbulence, fixed overlay, cheap.
   Motion mode: the grain LIVES (D2.7) — 8-step steps(1) shuffle,
   transform-only so it stays on the compositor. Reduced motion:
   frozen by the global kill.                                   */
.grain::after {
  content: "";
  position: fixed;
  inset: -50%;
  z-index: 250;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity: .05;
  mix-blend-mode: overlay;
}
html.motion-ok.grain::after {
  opacity: .06;
  will-change: transform;
  animation: grain-shift .72s steps(1, end) infinite;
}
@keyframes grain-shift {
  0%    { transform: translate(0, 0); }
  12.5% { transform: translate(-7%, 6%); }
  25%   { transform: translate(9%, -8%); }
  37.5% { transform: translate(-12%, -10%); }
  50%   { transform: translate(11%, 12%); }
  62.5% { transform: translate(-6%, 13%); }
  75%   { transform: translate(13%, -6%); }
  87.5% { transform: translate(-10%, 9%); }
  100%  { transform: translate(0, 0); }
}
/* halftone print texture for poster moments */
.halftone {
  background-image: radial-gradient(oklch(0% 0 0 / .5) 1px, transparent 1.4px);
  background-size: 5px 5px;
}
/* broadcast scanlines */
.scanlines {
  background-image: repeating-linear-gradient(
    0deg, oklch(0% 0 0 / .22) 0 1px, transparent 1px 4px);
}

/* ============================================================
   HEADER — slim bar + RPM scroll meter
   ============================================================ */
.site-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 200;
  /* the bar spans the notch strip too: its veil paints from the true
     top of the screen while the logo/nav row sits below the status
     bar. env() is 0 without viewport-fit=cover, so desktop is
     unchanged. */
  height: var(--head-total);
  padding-top: env(safe-area-inset-top, 0px);
  padding-inline: env(safe-area-inset-left, 0px) env(safe-area-inset-right, 0px);
  display: flex;
  align-items: center;
  background: transparent;
  transition: background var(--dur-base) ease, box-shadow var(--dur-base) ease;
}
.site-head.is-solid {
  background: var(--ink-veil);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--ink-line);
}
/* T-003: Firefox claims backdrop-filter support but paints no blur
   on this fixed header, so the 82%-alpha veil alone must separate
   CONTACT from the billboard's giant display type. @supports can't
   catch a silent paint failure — scope a near-solid veil through
   the only Gecko-reachable probe. Blur engines keep the glass. */
@supports (-moz-appearance: none) {
  .site-head.is-solid,
  .sticky-register { background: var(--ink-veil-solid); }
}
.site-head__inner {
  width: min(100% - 2 * var(--gutter), 96rem);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.site-head__brand {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}
.site-head__brand img {
  height: 3.2rem; width: auto;
  filter: brightness(1.32) contrast(1.05)
          drop-shadow(0 0 10px oklch(95.5% 0.007 90 / .12));
}

.site-head__nav {
  display: flex;
  align-items: center;
  gap: clamp(.9rem, 2vw, 1.9rem);
  margin-left: auto;
}
.nav-link {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .95rem;
  letter-spacing: .075em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--bone-dim);
  padding: .35rem .1rem;
  position: relative;
  transition: color var(--dur-fast) ease;
}
.nav-link::after {
  content: "";
  position: absolute;
  left: 0; right: 100%; bottom: 0;
  height: 2px;
  background: var(--throttle-red);
  transition: right var(--dur-fast) var(--ease-snap);
}
.nav-link:hover, .nav-link[aria-current="page"] { color: var(--bone); }
.nav-link:hover::after, .nav-link[aria-current="page"]::after { right: 0; }

/* quiet utility cluster */
.nav-util {
  font-family: var(--font-text);
  font-weight: 500;
  font-size: .8rem;
  letter-spacing: .075em;
  text-transform: uppercase;
  color: var(--bone-mute);
  text-decoration: none;
  transition: color var(--dur-fast) ease;
}
.nav-util:hover { color: var(--bone); }
.nav-util--pill {
  border: 1px solid var(--ink-line);
  padding: .38rem .85rem;
  border-radius: 99px;
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.nav-util--pill:hover { border-color: var(--bone-mute); }

/* the one filled element in the bar */
.register-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center; /* label centers inside the D3.1 min-width lock */
  gap: .5rem;
  background: var(--throttle-red-deep);
  color: var(--bone);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .95rem;
  letter-spacing: .075em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .5rem 1.15rem;
  border-radius: 99px;
  position: relative;
  overflow: hidden;
  transition: background var(--dur-fast) ease, translate var(--dur-fast) var(--ease-impact);
}
.register-pill::before { /* headlight sweep */
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 30%, oklch(100% 0 0 / .28) 48%, transparent 62%);
  translate: -110% 0;
  transition: translate .5s var(--ease-out-expo);
}
.register-pill:hover { background: var(--throttle-red); }
.register-pill:hover::before { translate: 110% 0; }
/* designed press (D2.5): darken + compress — scale/translate props
   compose with the magnet's inline transform, no writer conflict */
.register-pill:active {
  translate: 0 1px;
  scale: .965;
  background: var(--throttle-red-press);
  transition-duration: 60ms;
}
/* magnet label wrapper (JS-injected): counter-translates for the
   parallax pull on fine pointers */
.magnet-label { display: inline-flex; align-items: center; gap: inherit; pointer-events: none; }
/* pill journey (D3.1): the flip board is its own inner node so the
   magnet's translate and the board's rotateX never share a transform */
.pill-flip { display: inline-flex; align-items: center; gap: inherit; pointer-events: none; white-space: nowrap; }
/* one-shot headlight sweep, fired by the landing slam (D3.1b) —
   reuses the hover sweep's ::before band, keyframed edge to edge */
html.motion-ok .register-pill.is-sweeping::before { animation: pill-sweep .6s var(--ease-out-expo) both; }
@keyframes pill-sweep { from { translate: -110% 0; } to { translate: 110% 0; } }

.nav-link:active, .nav-util:active { color: var(--bone); }

/* RPM meter — scroll progress as a tach strip on the bar's bottom edge */
.rpm {
  position: absolute;
  left: 0; right: 0; bottom: calc(-1 * var(--rpm-h));
  height: var(--rpm-h);
  background:
    repeating-linear-gradient(90deg,
      oklch(95.5% 0.007 90 / .16) 0 1px, transparent 1px 5%);
}
.rpm__fill {
  height: 100%;
  width: 100%;
  /* clip (not scale) so the redline only shows near 100% */
  clip-path: inset(0 calc((1 - var(--scroll-progress)) * 100%) 0 0);
  background: linear-gradient(90deg,
    var(--dirt-high) 0%,
    var(--throttle-red) 58%,
    var(--throttle-red) 88%,
    var(--caution) 96%); /* redline */
}
/* redline blink (D2.8): main.js toggles html.at-redline at ≥.96
   (hysteresis: off below .94) — the last 4% of the tach strobes  */
.rpm::after {
  content: "";
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 4%;
  background: var(--caution);
  opacity: 0;
  pointer-events: none;
}
html.motion-ok.at-redline .rpm::after { animation: rpm-blink 1s steps(2, start) infinite; }
@keyframes rpm-blink { 0%, 49.9% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* while the gate menu is open, the chrome rides above it so the
   brand mark and the Close control stay visible and tappable    */
html.menu-open .site-head { z-index: 246; }

/* mobile menu trigger */
.menu-btn {
  display: none;
  background: none;
  border: 1px solid var(--ink-line);
  border-radius: var(--radius-chip);
  color: var(--bone);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: .075em;
  text-transform: uppercase;
  padding: .5rem .8rem;
  cursor: pointer;
}

/* full-screen gate-drop menu overlay */
.gate-menu {
  position: fixed;
  inset: 0;
  z-index: 240;
  display: none;
  flex-direction: column;
  background:
    linear-gradient(180deg, var(--dirt-deep), var(--ink) 55%);
  padding:
    calc(var(--head-total) + var(--space-6))
    calc(var(--gutter) + env(safe-area-inset-right, 0px))
    calc(var(--space-6) + env(safe-area-inset-bottom, 0px))
    calc(var(--gutter) + env(safe-area-inset-left, 0px));
  overflow-y: auto;
}
.gate-menu.is-open { display: flex; }
.gate-menu::before { /* gate slat */
  content: "";
  position: absolute;
  top: calc(var(--head-total) + .4rem);
  left: var(--gutter); right: var(--gutter);
  height: 4px;
  background: var(--throttle-red);
}
/* the slat DROPS like a gate on open (D2.11) — then the link
   stagger fires (JS shifts its start ~100ms). Motion mode only. */
html.motion-ok .gate-menu.is-open::before {
  animation: slat-drop .24s var(--ease-snap) .05s both;
}
@keyframes slat-drop {
  from { transform: translateY(-2.6rem) scaleY(0); opacity: 0; }
  to   { transform: translateY(0) scaleY(1); opacity: 1; }
}
.gate-menu__nav {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  margin-top: var(--space-6);
}
.gate-menu__link {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(2.4rem, 9vw, 3.6rem);
  line-height: 1.04;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--bone);
  display: flex;
  align-items: baseline;
  gap: .8rem;
}
.gate-menu__link small {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--bone-mute);
  letter-spacing: .075em;
}
.gate-menu__link:active { color: var(--throttle-red); }
.gate-menu__register {
  margin-top: var(--space-6);
  display: flex;
  justify-content: center;
  background: var(--throttle-red-deep);
  color: var(--bone);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.3rem;
  letter-spacing: .075em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 1rem;
  border-radius: var(--radius-chip);
}
/* the menu carries the next gate (D3.10) — one honest fact + path
   in the dead space between the register block and the foot line */
.gate-menu__next {
  margin-top: var(--space-5);
  align-self: flex-start;
  color: var(--bone-mute);
  text-decoration: none;
}
.gate-menu__next:hover, .gate-menu__next:active { color: var(--bone); }
.gate-menu__foot {
  margin-top: auto;
  padding-top: var(--space-6);
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--bone-mute);
}

@media (max-width: 900px) {
  .site-head__nav .nav-link,
  .site-head__nav .nav-util { display: none; }
  .menu-btn { display: inline-block; }
  .register-pill { font-size: .85rem; padding: .42rem .9rem; }
}

/* ---- mobile sticky register bar ----------------------------- */
.sticky-register {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 190;
  display: none;
  padding: .55rem var(--gutter) calc(.55rem + env(safe-area-inset-bottom, 0px));
  background: var(--ink-veil);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: 0 -1px 0 var(--ink-line);
  translate: 0 110%;
  transition: translate .45s var(--ease-out-expo);
}
.sticky-register.is-live { translate: 0 0; }
/* yield to typing (D3.4c): while any capture field has focus the bar
   slides out — it must never pin against an input over the keyboard */
.sticky-register.is-suppressed { translate: 0 110%; }
.sticky-register__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: var(--throttle-red-deep);
  color: var(--bone);
  text-decoration: none;
  border-radius: var(--radius-chip);
  padding: .7rem 1rem;
}
.sticky-register__cta strong {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.sticky-register__cta span {
  font-family: var(--font-mono);
  font-size: .56rem;
  line-height: 1.45;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: right;
  color: oklch(95.5% 0.007 90 / .85);
  min-width: 0;
}
@media (min-width: 761px) { .sticky-register { display: none !important; } }
@media (max-width: 760px) { .sticky-register { display: block; } }

/* ============================================================
   BUTTONS + FORMS
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.02rem;
  letter-spacing: .075em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .95rem 1.9rem;
  border: 0;
  border-radius: var(--radius-chip);
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background var(--dur-fast) ease, color var(--dur-fast) ease,
              translate var(--dur-fast) var(--ease-impact),
              scale var(--dur-fast) var(--ease-impact), box-shadow var(--dur-fast) ease;
}
/* designed press (D2.5) — scale/translate props stay clear of the
   magnet's inline transform; 60ms in, impact-ease back out       */
.btn:active {
  scale: .965;
  translate: 0 1px;
  transition-duration: 60ms;
}
.btn--red {
  background: var(--throttle-red-deep);
  color: var(--bone);
  /* angled speed-cut corner */
}
.btn--red:hover { background: var(--throttle-red); box-shadow: 0 10px 34px -12px var(--throttle-red); }
.btn--red:active { background: var(--throttle-red-press); }
/* press flash — the headlight sweep's instant version */
.btn--red::after {
  content: "";
  position: absolute;
  inset: 0;
  background: oklch(100% 0 0);
  opacity: 0;
  pointer-events: none;
}
.btn--red:active::after { animation: btn-flash 90ms ease-out both; }
@keyframes btn-flash { from { opacity: .18; } to { opacity: 0; } }
/* secondary action — underlined display link, not a ghost box.
   Keeps .btn padding so the touch target stays ≥44px. */
.btn--ghost {
  background: transparent;
  color: var(--bone);
  padding-inline: .4rem;
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-decoration-color: var(--throttle-red);
  text-underline-offset: 7px;
}
.btn--ghost:hover { color: var(--throttle-red-bright); text-decoration-color: var(--throttle-red-bright); }
.btn--ghost:active { color: var(--throttle-red-bright); translate: 0 1px; }
.btn .btn__arrow { transition: translate var(--dur-fast) var(--ease-out-expo); }
.btn:hover .btn__arrow { translate: .3rem 0; }

/* stacked field + button capture rows (newsletter / ticket alerts) */
.capture {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
}
.capture input[type="email"] {
  flex: 1 1 14rem;
  background: var(--ink-raise);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius-chip);
  color: var(--bone);
  padding: .9rem 1rem;
  min-width: 0;
  transition: border-color var(--dur-fast) ease;
}
.capture input[type="email"]::placeholder { color: var(--bone-mute); }
.capture input[type="email"]:hover { border-color: var(--bone-mute); }
/* focus stays blue (protected); the surface also LIFTS so focus
   reads on dim screens (D2.5) */
.capture input[type="email"]:focus { background: oklch(19% 0.006 300); }
.capture label:not(.sr-only) { width: 100%; }
.form-note {
  margin-top: .6rem;
  font-size: var(--text-small);
  color: var(--bone-mute);
}
/* the ON THE LIST moment (D3.3): the machine acknowledges — red
   edge bar + micro pack-stamp (1.06→1). Focus lands here (JS sets
   tabindex=-1); role="status" announces. Reduced motion: instant. */
.form-success {
  display: none;
  margin-top: .8rem;
  padding: .7rem 1rem;
  border: 2px solid var(--throttle-red); /* stamped, not striped */
  border-radius: 3px;
  color: var(--bone);
  font-weight: 600;
  outline: none;
}
.form-success.is-shown { display: block; }
html.motion-ok .form-success.is-shown { animation: success-stamp 380ms var(--ease-out-expo) both; }
@keyframes success-stamp {
  from { opacity: 0; scale: 1.06; }
  to   { opacity: 1; scale: 1; }
}
/* the honest next action: calendar links inside the acknowledgment
   (billboard + scheduled event pages only — blue = data utility)  */
.form-success__cal {
  display: block;
  margin-top: .55rem;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: 400;
  letter-spacing: .075em;
  text-transform: uppercase;
  color: var(--bone-dim);
}
.form-success__cal a {
  color: var(--holeshot-blue-bright);
  text-decoration: none;
  border-bottom: 1px solid oklch(70% 0.12 252 / .45);
  margin-left: .5rem;
  padding-bottom: .1em;
}
.form-success__cal a:hover { border-bottom-color: var(--holeshot-blue-bright); }
/* the spent form yields the floor: its row collapses (the success
   names what happened); an adjacent note goes with it            */
form[data-form-stub].is-done > :not(.form-success) { display: none; }
form[data-form-stub].is-done + .form-note { display: none; }

/* ============================================================
   LAST-CALL BAND (D3.7) — home only, between GET IN TOUCH and the
   footer grid. The R2 redline blink finally has a target: tach
   pinned, gate named, button. Red/bone only — no amber here.
   ============================================================ */
.redline-band {
  position: relative;
  background: var(--ink-raise);
}
.redline-band::before { /* the edge rule the redline tach blinks */
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--throttle-red);
}
html.motion-ok.at-redline .redline-band::before {
  animation: rpm-blink 1s steps(2, start) infinite;
}
.redline-band__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4) var(--space-5);
  padding: var(--space-5) 0;
}
.redline-band__line {
  color: var(--bone);
  font-size: .78rem;
  text-decoration: none;
}
.redline-band__line:hover .redline-band__gate { color: var(--bone); }
.redline-band__flag { color: var(--throttle-red-bright); font-weight: 700; }
.redline-band__gate { color: var(--bone-mute); transition: color var(--dur-fast) ease; }
@media (max-width: 760px) {
  /* the fixed sticky bar stays the ONE red button on phones (D3.4
     discipline) — the whole band becomes the link instead        */
  .redline-band__btn { display: none; }
  .redline-band__row { padding: 0; }
  .redline-band__line { display: block; width: 100%; padding: var(--space-5) 0; }
}

/* ============================================================
   FOOTER — four zones, universal recovery surface
   ============================================================ */
.site-foot {
  position: relative;
  border-top: 1px solid var(--ink-line);
  background:
    linear-gradient(180deg, var(--ink), oklch(11% 0.008 310));
  padding: var(--space-8) 0 var(--space-6);
  overflow: clip;
}
.site-foot::before { /* faint X watermark */
  content: "";
  position: absolute;
  right: -6rem; bottom: -8rem;
  width: 30rem; height: 30rem;
  /* x-mark-wm.png (D4.8): same 330px composition, palette-encoded
     6.8KB derivative — at 5% opacity the 48KB master was pure wire
     tax on every page. Master stays at brand/x-mark.png.          */
  background: url("../img/brand/x-mark-wm.png") center / contain no-repeat;
  opacity: .05;
  pointer-events: none;
}
.site-foot__grid {
  display: grid;
  grid-template-columns: 1.35fr .8fr 1fr 1.2fr;
  gap: var(--space-7) var(--space-6);
}
@media (max-width: 980px) { .site-foot__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .site-foot__grid { grid-template-columns: 1fr; } }

.site-foot h2 {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: 400;
  letter-spacing: .075em;
  text-transform: uppercase;
  color: var(--bone-mute);
  margin-bottom: var(--space-5);
}
.site-foot__brand img {
  height: 3.8rem; width: auto;
  filter: brightness(1.32) contrast(1.05);
}
.site-foot__tagline {
  margin-top: var(--space-5);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  line-height: 1.1;
  text-transform: uppercase;
  color: var(--bone);
  max-width: 16ch;
}
.site-foot__pos {
  margin-top: var(--space-4);
  color: var(--bone-mute);
  font-size: var(--text-small);
  max-width: 34ch;
}
.foot-list { display: grid; gap: .55rem; }
.foot-list a {
  text-decoration: none;
  color: var(--bone-dim);
  font-size: var(--text-small);
  display: inline-flex;
  align-items: baseline;
  gap: .6rem;
  transition: color var(--dur-fast) ease;
}
.foot-list a:hover, .foot-list a:active { color: var(--bone); }
.foot-list .mono { color: var(--bone-mute); font-size: .62rem; }
.foot-flag {
  color: var(--caution);
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .075em;
}
.site-foot__signals p { color: var(--bone-dim); font-size: var(--text-small); margin-bottom: var(--space-4); max-width: 36ch; }
.social-row { display: flex; gap: .8rem; margin-top: var(--space-5); }
.social-row a {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  color: var(--bone-mute);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: .075em;
  text-transform: uppercase;
  border: 1px solid var(--ink-line);
  border-radius: 99px;
  padding: .45rem .95rem;
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}
.social-row a:hover { color: var(--bone); border-color: var(--bone-mute); }
.social-row a:active { color: var(--bone); border-color: var(--bone-mute); scale: .96; }
.site-foot__legal {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--ink-line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-6);
  justify-content: space-between;
  color: var(--bone-mute);
  font-size: var(--text-micro);
  font-family: var(--font-mono);
  letter-spacing: .075em;
  text-transform: uppercase;
}
.site-foot__legal a { color: inherit; text-decoration: none; }
.site-foot__legal a:hover { color: var(--bone); }

/* ------------------------------------------------------------
   FOOTER, PHONE — the colophon, not a stack of lists.
   Measured 1576px (2.4 screens) at 390px wide, up to 45% of a
   short page. The link lists become wrapped indexes the way a
   printed program sets its back matter, and the generous desktop
   rhythm tightens. Every link survives; desktop is untouched.
   ------------------------------------------------------------ */
@media (max-width: 560px) {
  /* the header is one row: logo + Register + Menu, and it is already
     tight at 320px. Scale the logo with the viewport so it grows on the
     phones that have room and falls back to the original size on the
     ones that don't; the desktop bar keeps the full size. */
  .site-head__brand img { height: clamp(1.6rem, 8vw, 2.2rem); }

  .site-foot { padding: var(--space-7) 0 var(--space-5); }
  .site-foot__grid { gap: var(--space-6) var(--space-5); }
  .site-foot h2 { margin-bottom: var(--space-4); }
  .site-foot__brand img { height: 3.4rem; }
  .site-foot__tagline { margin-top: var(--space-4); }

  /* vertical list -> flowing index */
  .foot-list { display: flex; flex-wrap: wrap; gap: 0; }
  .foot-list li { display: flex; align-items: baseline; }
  /* the separator trails its own item, so a wrapped line never
     opens with a stray dot the way ::before would leave it */
  .foot-list li:not(:last-child)::after {
    content: "·";
    color: var(--bone-mute);
    opacity: .55;
    padding-inline: .5rem;
    align-self: center;
  }
  .foot-list a { padding-block: .5rem; }

  .site-foot__signals p { margin-bottom: var(--space-3); }
  .social-row { margin-top: var(--space-4); }
  .site-foot__legal { margin-top: var(--space-6); padding-top: var(--space-4); }
}

/* ============================================================
   GATE WIPE — page transition overlay (JS-driven)
   ============================================================ */
.gate-wipe {
  position: fixed;
  inset: 0;
  z-index: 280;
  display: grid;
  grid-template-rows: 1fr 6px 1fr;
  pointer-events: none;
  visibility: hidden;
}
.gate-wipe__slab { background: var(--dirt-deep); }
.gate-wipe__bar { background: var(--throttle-red); }
.gate-wipe.is-armed { visibility: visible; pointer-events: all; }

/* fallback-engine ARRIVAL (D2.6): the departing page set
   sessionStorage.tcWipe; the inline head gate adds html.wipe-in
   pre-paint so the slabs start covering (zero flash), then lift —
   red bar exits last. Pure CSS so a slow module can't strand it. */
html.wipe-in .gate-wipe { visibility: visible; }
html.motion-ok.wipe-in .gate-wipe__slab { animation: gw-lift .38s var(--ease-snap) .1s both; }
html.motion-ok.wipe-in .gate-wipe__bar { animation: gw-lift .4s var(--ease-snap) .16s both; }
@keyframes gw-lift {
  from { transform: translateY(0); }
  to   { transform: translateY(-110vh); }
}

/* View-Transition ARRIVAL (D2.6): the real red bar rides just
   ahead of the vt-gate-in clip edge (WAAPI drives the transform) */
.gate-wipe.is-revealing { visibility: visible; }
.gate-wipe.is-revealing .gate-wipe__slab { opacity: 0; }
.gate-wipe.is-revealing .gate-wipe__bar {
  position: fixed;
  top: -6px; left: 0; right: 0;
  height: 6px;
  box-shadow: 0 0 22px oklch(55% 0.205 27 / .65), 0 0 60px oklch(55% 0.205 27 / .3);
}

/* cross-document View Transitions: gate wipes down from the top.
   Engines that don't take this path get the JS overlay above —
   the same slabs + red bar, so no one loses the gate-drop beat.
   SCOPED TO WEBKIT (T-005): QA-1's launch check found Chromium —
   including current stable Chrome 151, headed and headless —
   permanently freezing rendering after any cross-document VT
   arrival (reproduced with a minimal no-JS page, so it's the
   engine, not this site). Until a hands-on-real-Chrome pass
   proves the wedge is automation-only, Chromium rides the JS
   fallback; -webkit-hyphens is true only in WebKit (measured
   against all three engines). main.js mirrors this exact probe
   when deciding whether to arm the fallback — keep them in sync.
   Re-enable Chromium by widening both probes together. */
@supports (-webkit-hyphens: none) {
  @view-transition { navigation: auto; }
  /* RM: no transition at all — navigation lands instantly (T-004);
     last matching @view-transition rule wins */
  @media (prefers-reduced-motion: reduce) {
    @view-transition { navigation: none; }
  }
}
::view-transition-old(root) { animation: none; opacity: 0; }
::view-transition-new(root) { animation: vt-gate-in .42s var(--ease-snap); }
@keyframes vt-gate-in {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* ============================================================
   CONSENT — a strip, not a lightbox

   It sits on the bottom edge and does not trap the page: nothing
   here is load-bearing enough to hold someone hostage over, and a
   modal that blocks a race schedule to ask about analytics is the
   kind of thing this whole rebuild is a reaction to. Above the
   sticky register bar on phones, since that bar is the page's job
   and this is ours.
   ============================================================ */
.consent {
  position: fixed; z-index: 200;   /* over the sticky register, which hides while this is up */
  left: 0; right: 0; bottom: 0;
  background: var(--ink-veil-solid);
  border-top: 2px solid var(--throttle-red);
  padding: 1rem calc(var(--gutter) + env(safe-area-inset-right, 0px))
           calc(1rem + env(safe-area-inset-bottom, 0px))
           calc(var(--gutter) + env(safe-area-inset-left, 0px));
  transform: translateY(100%);
  transition: transform .4s var(--ease-snap);
}
@supports (backdrop-filter: blur(8px)) {
  .consent { background: var(--ink-veil); backdrop-filter: blur(10px); }
}
.consent.is-up { transform: translateY(0); }

.consent__inner {
  width: min(100%, var(--page-max)); margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .9rem var(--space-4);
}
.consent__say { flex: 1 1 22rem; min-width: 0; }
.consent__title {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.15rem; line-height: 1.1; text-transform: uppercase;
  letter-spacing: .01em; margin: 0 0 .2rem; color: var(--bone);
}
.consent__body {
  margin: 0; font-size: .92rem; line-height: 1.45; color: var(--bone-dim);
  max-width: 54ch;
}
.consent__body a { color: var(--holeshot-blue-bright); }

.consent__act { display: flex; align-items: center; gap: .9rem 1.1rem; flex: none; }
.consent__act .btn { flex: none; }
.consent__no {
  background: none; border: 0; padding: .5rem .2rem; cursor: pointer;
  font-family: var(--font-data); font-size: .82rem; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--bone-mute);
  text-decoration: underline; text-underline-offset: .3em;
  text-decoration-color: var(--bone-ghost);
}
.consent__no:hover { color: var(--bone); text-decoration-color: var(--throttle-red); }

/* One bar at a time. The register bar is the page's job and it can
   wait the few seconds this takes; two stacked bottom bars on a
   phone is nobody's idea of a good time. */
body.consent-open .sticky-register { translate: 0 110%; }

@media (max-width: 900px) {
  .consent__act { width: 100%; justify-content: space-between; }
}

/* ============================================================
   REDUCED MOTION — global collapse
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}
