/* ==========================================================================
   Engage | Season 01
   Category-canon shooter landing page. One accent, disciplined scale,
   12-degree cuts, code-drawn art. Finish bar: VALORANT.
   ========================================================================== */

/* --- Font ----------------------------------------------------------------
   Self-hosted latin subset of the Archivo variable font (88KB). Previously two
   preconnects and a render-blocking stylesheet on a third-party origin, for a
   page that otherwise ships zero dependencies. The width axis is the identity
   here: without it every font-stretch declaration below silently does nothing.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url("fonts/archivo-latin-var.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

/* --- Reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 6rem;
}

[hidden] { display: none !important; }

html, body, h1, h2, h3, p, ul, ol, li, dl, dt, dd, figure, figcaption, form {
  margin: 0;
  padding: 0;
}

ul, ol { list-style: none; }

img, svg { display: block; max-width: 100%; }

button, input { font: inherit; color: inherit; }

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* The page is committed dark. Without this the UA still paints form chrome,
     autofill, caret and scrollbars from the light theme. */
  color-scheme: dark;

  --ink-900: #07090e;
  --ink-850: #090c13;
  --ink-800: #0c1017;
  --ink-700: #111722;
  --line:    #232c3b;
  --line-soft: #1a2231;

  --chalk:  #edf1f6;
  --steel:  #93a0b4;
  --steel-soft:  #7e8b9e;  /* placeholders and other de-emphasised UI text */
  --steel-quiet: #74808f;  /* legal copy: the quietest text that still clears AA */
  --volt:   #d8ff3e;
  --volt-lit: #e6ff70;     /* volt under the pointer, never at rest */
  --volt-dim: #a9c92e;
  --ember:  #ff6b3d;
  --ember-wash: #180d0a;   /* invalid field ground */

  /* env() resolves to 0 where there is no notch, so this is the plain
     gutter everywhere except a landscape phone. */
  --shell: min(1240px, 100% - 3rem - env(safe-area-inset-left) - env(safe-area-inset-right));
  --shell-narrow: min(720px, 100% - 3rem - env(safe-area-inset-left) - env(safe-area-inset-right));

  --step-0: 1rem;
  --step-1: 1.125rem;
  --step-2: clamp(1.25rem, 0.4vw + 1.15rem, 1.5rem);
  --step-3: clamp(1.75rem, 1.4vw + 1.4rem, 2.5rem);
  --step-4: clamp(2.25rem, 3vw + 1.5rem, 4rem);

  /* One notation for the 12-degree corner. Components that need a deeper cut
     override --cut locally rather than restating the clip-path. */
  --cut: 12px;

  --ease: cubic-bezier(.16, 1, .3, 1);
  --t-quick: .2s;   /* colour and border state changes */
  --t-slide: .35s;  /* transform, reveal, and underline */

  --shadow-panel: 0 18px 44px -22px rgb(0 0 0 / .9);
  --shadow-lift:  0 26px 60px -28px rgb(0 0 0 / .95);
}

/* --- Base ----------------------------------------------------------------- */

body {
  background: var(--ink-900);
  color: var(--chalk);
  font-family: "Archivo", "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--volt); color: var(--ink-900); }

a { color: inherit; }

:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--volt);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 100;
  padding: .75rem 1.25rem;
  background: var(--volt);
  color: var(--ink-900);
  font-weight: 700;
  text-decoration: none;
  transition: top var(--t-quick) var(--ease);
}
.skip:focus { top: 1rem; }

/* --- Typography ----------------------------------------------------------- */

h1, h2, h3 {
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -.03em;
  text-wrap: balance;
}

h3 { font-size: var(--step-2); line-height: 1.2; letter-spacing: -.02em; }

p { text-wrap: pretty; }

.section__title {
  font-size: var(--step-4);
  font-stretch: 112%;
  text-transform: uppercase;
  letter-spacing: -.035em;
}

.lede {
  max-width: 62ch;
  margin-top: 1.5rem;
  font-size: var(--step-2);
  line-height: 1.5;
  color: var(--steel);
}

/* --- Layout --------------------------------------------------------------- */

.wrap { width: var(--shell); margin-inline: auto; }
.wrap--narrow { width: var(--shell-narrow); }

.section { padding-block: clamp(5rem, 11vw, 9.5rem); }

.section + .section { border-top: 1px solid var(--line-soft); }

/* --- Buttons -------------------------------------------------------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: 1.0625rem 2.25rem;
  border: 0;
  background: none;
  font-size: .9375rem;
  font-weight: 800;
  font-stretch: 108%;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  isolation: isolate;
  transition: transform var(--t-slide) var(--ease), color var(--t-quick) linear;
}

/* The clipped shape lives on a pseudo-element so the focus ring is never cut. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%);
  transition: background-color var(--t-quick) linear, box-shadow var(--t-slide) var(--ease);
}

.btn--primary { color: var(--ink-900); }
.btn--primary::before { background: var(--volt); }
.btn--primary:hover::before {
  background: var(--volt-lit);
  box-shadow: 0 10px 30px -14px color-mix(in srgb, var(--volt) 70%, transparent);
}

/* Stays an outlined secondary. It carries just enough veil to keep the
   traversal trace off the label, never enough to read as a second solid. */
.btn--ghost { color: var(--chalk); }
.btn--ghost::before {
  background: color-mix(in srgb, var(--ink-900) 34%, transparent);
  box-shadow: inset 0 0 0 1px var(--steel);
}

@supports (backdrop-filter: blur(1px)) {
  .btn--ghost::before { backdrop-filter: blur(7px); }
}
.btn--ghost:hover::before { background: var(--ink-700); box-shadow: inset 0 0 0 1px var(--steel); }

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--compact { padding: .75rem 1.375rem; font-size: .8125rem; --cut: 9px; }

.btn[disabled], .btn[aria-disabled="true"] {
  cursor: not-allowed;
  transform: none;
  color: var(--ink-900);
}
.btn[disabled]::before { background: var(--volt-dim); box-shadow: none; }

/* --- Masthead ------------------------------------------------------------- */

.masthead {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  width: 100%;
  padding-block: 1rem;
  padding-inline:
    max(clamp(1.25rem, 4vw, 2.5rem), env(safe-area-inset-left))
    max(clamp(1.25rem, 4vw, 2.5rem), env(safe-area-inset-right));
  background: color-mix(in srgb, var(--ink-900) 82%, transparent);
  border-bottom: 1px solid transparent;
  transition: background-color var(--t-slide) linear, border-color var(--t-slide) linear;
}

@supports (backdrop-filter: blur(1px)) {
  .masthead { backdrop-filter: blur(14px) saturate(140%); }
}

.masthead[data-stuck] {
  background: color-mix(in srgb, var(--ink-900) 94%, transparent);
  border-bottom-color: var(--line-soft);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: 1.25rem;
  font-weight: 900;
  font-stretch: 118%;
  letter-spacing: .12em;
  text-transform: uppercase;
  text-decoration: none;
}

.masthead__nav { margin-inline-start: auto; }

.masthead__menu { display: flex; gap: clamp(1.25rem, 2.5vw, 2.25rem); }

.masthead__menu a {
  position: relative;
  display: inline-block;
  padding-block: .4375rem; /* keeps the 24px minimum target height of WCAG 2.5.8 */
  font-size: .875rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--steel);
  transition: color var(--t-quick) linear;
}

.masthead__menu a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -.5rem;
  width: 100%;
  height: 2px;
  background: var(--volt);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-slide) var(--ease);
}

.masthead__menu a:hover { color: var(--chalk); }
.masthead__menu a:hover::after { transform: scaleX(1); }

.masthead__toggle { display: none; }

/* --- Hero ----------------------------------------------------------------- */

.hero {
  position: relative;
  display: grid;
  align-items: center;
  min-height: min(88svh, 860px);
  padding-block: clamp(6.5rem, 12vh, 8rem) clamp(3rem, 7vh, 5rem);
  overflow: hidden;
}

.hero__art { position: absolute; inset: 0; }

.arena { width: 100%; height: 100%; }
.arena__far polygon    { fill: #1c2b45; }
.arena__mid polygon    { fill: #131e30; }
.arena__near polygon   { fill: #0b111c; }
.arena__lights rect    { fill: var(--volt); opacity: .85; }

/* The glow is a blurred 14px stroke. Animating stroke-dashoffset on it meant
   re-rasterising a full-hero blur every frame for 2.4s, competing with font
   swap during load. It now rasterises once and only its opacity animates, so
   the glow arrives as the line lands instead of dragging behind it. */
.trace__shadow {
  fill: none;
  stroke: var(--volt);
  stroke-width: 14;
  opacity: .12;
  filter: blur(9px);
}

.trace__line {
  fill: none;
  stroke: var(--volt);
  stroke-width: 3;
  stroke-linecap: round;
}

.trace__nodes circle {
  fill: var(--ink-900);
  stroke: var(--volt);
  stroke-width: 3;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top,
      var(--ink-900) 2%,
      color-mix(in srgb, var(--ink-900) 62%, transparent) 26%,
      color-mix(in srgb, var(--ink-900)  5%, transparent) 62%,
      color-mix(in srgb, var(--ink-900) 45%, transparent) 100%),
    linear-gradient(to right,
      color-mix(in srgb, var(--ink-900) 80%, transparent) 0%,
      color-mix(in srgb, var(--ink-900) 42%, transparent) 38%,
      transparent 72%);
}

.hero__body {
  position: relative;
  width: var(--shell);
  margin-inline: auto;
}

/* The floor is deliberately low: ENGAGE is one unbreakable word at wdth 125%,
   so a fixed minimum larger than the gutter allows would overflow the shell on
   a 320px screen with nothing able to wrap. */
.hero__logotype {
  font-size: clamp(2.75rem, 15vw, 7.75rem);
  font-weight: 900;
  font-stretch: 125%;
  letter-spacing: -.045em;
  text-transform: uppercase;
  line-height: .88;
}

.hero__pitch {
  margin-top: 1.25rem;
  font-size: clamp(1.375rem, 3.2vw, 2rem);
  font-weight: 800;
  font-stretch: 108%;
  letter-spacing: -.02em;
  text-transform: uppercase;
  color: var(--volt);
}

.hero__sub {
  max-width: 46ch;
  margin-top: 1rem;
  font-size: var(--step-1);
  color: var(--steel);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: .875rem;
  margin-top: 2.5rem;
}

.countdown {
  display: flex;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  margin-top: 3.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}

.countdown__cell dt {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
}

.countdown__cell dd {
  margin-top: .25rem;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 800;
  font-stretch: 112%;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  line-height: 1;
}

.countdown__live {
  margin-top: 3.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
  font-size: var(--step-2);
  font-weight: 800;
  text-transform: uppercase;
  color: var(--volt);
}

.platforms {
  margin-top: 1.75rem;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--steel);
}

/* --- Reveal frame --------------------------------------------------------- */

.frame {
  --cut: 40px;
  position: relative;
  margin-top: 3rem;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--ink-850);
  box-shadow: var(--shadow-lift);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%);
}

.frame__art { width: 100%; height: 100%; }
.frame__grid path { fill: none; stroke: #1b2740; stroke-width: 1.5; }
.frame__skyline polygon { fill: #16223a; }
.frame__ridge { fill: #0d1524; }
.frame__pillars rect { fill: #1e2c47; }
.frame__route path {
  fill: none;
  stroke: var(--volt);
  stroke-width: 4;
  stroke-linecap: round;
  opacity: .95;
}
.frame__pulse circle { fill: var(--volt); opacity: .9; }

.frame__play {
  position: absolute;
  inset-block-end: clamp(1.5rem, 4vw, 2.75rem);
  inset-inline-start: clamp(1.5rem, 4vw, 2.75rem);
  display: inline-flex;
  align-items: center;
  gap: .875rem;
  padding: .875rem 1.5rem .875rem 1.125rem;
  background: color-mix(in srgb, var(--ink-900) 78%, transparent);
  border: 1px solid var(--line);
  color: var(--chalk);
  font-size: .8125rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--t-quick) linear, border-color var(--t-quick) linear;
}

.frame__play:hover { background: var(--ink-900); border-color: var(--steel); }

.frame__play-icon {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 7px 0 7px 12px;
  border-color: transparent transparent transparent var(--volt);
}

.frame__play[data-playing] .frame__play-icon {
  width: 12px;
  height: 14px;
  background: none;
  border-style: solid;
  border-width: 0 4px;
  border-color: var(--volt);
}

.frame__caption {
  margin-top: 1rem;
  font-size: .8125rem;
  color: var(--steel);
}

/* --- Movement ------------------------------------------------------------- */

.techniques { margin-top: clamp(3rem, 6vw, 4.5rem); }

.technique {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(1.5rem, 5vw, 4rem);
  align-items: center;
  padding-block: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--line-soft);
}

.technique:last-child { border-bottom: 1px solid var(--line-soft); }

.technique__diagram {
  padding: 1.25rem;
  background: var(--ink-800);
  box-shadow: var(--shadow-panel);
}

.technique__ground { stroke: var(--line); stroke-width: 2; }
.technique__block  { fill: #172131; }
.technique__path {
  fill: none;
  stroke: var(--volt);
  stroke-width: 3.5;
  stroke-linecap: round;
}

.technique__copy p {
  max-width: 68ch;
  margin-top: .875rem;
  color: var(--steel);
}

/* --- Roster --------------------------------------------------------------- */

.roster {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin-top: clamp(3rem, 6vw, 4.5rem);
}

.op {
  padding-bottom: 1.75rem;
  background: var(--ink-800);
  box-shadow: var(--shadow-panel);
}

/* Plates are artwork, not controls. No hover affordance, because there is nowhere to go. */

.op__plate { overflow: hidden; }

/* Operator names are open canon: a longer one than SLIPSTREAM must not
   push out of its card rather than wrapping. */
.op h3 { overflow-wrap: break-word; }

.op__field     { fill: #0d1420; }
.op__mark      { stroke: #1a273a; stroke-width: 2; fill: #101a28; opacity: .62; }
.op__mark [fill="none"] { fill: none; }
.op__shoulder  { fill: #131d2c; }
.op__helm      { fill: #1b2739; }
.op__helm-lit  { fill: #27384f; }
.op__helm-shade{ fill: #121a27; }
.op__crest     { fill: #223146; }
.op__fin       { fill: #1c2a3d; }
.op__brow      { fill: #2a3b53; }
.op__jaw       { fill: #16202f; }
.op__collar    { fill: #1a2537; }
.op__disc      { fill: #22314a; }
.op__detail    { stroke: #2c3d55; stroke-width: 2; fill: none; stroke-linecap: round; }
.op__visor     { fill: var(--volt); }

.op h3 {
  margin-top: 1.5rem;
  padding-inline: 1.5rem;
  text-transform: uppercase;
  font-stretch: 112%;
  letter-spacing: -.01em;
}

.op__role {
  margin-top: .375rem;
  padding-inline: 1.5rem;
  font-size: .6875rem;
  font-weight: 800;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--volt);
}

.op__kit {
  margin-top: .875rem;
  padding-inline: 1.5rem;
  font-size: .9375rem;
  color: var(--steel);
}

/* --- Seasons -------------------------------------------------------------- */

/* A scrollable region has to be reachable by keyboard. Chrome now focuses
   overflow containers on its own; Firefox and Safari do not, so the markup
   carries tabindex and this gives that focus somewhere to show. */
.timeline {
  margin-top: clamp(3rem, 6vw, 4rem);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--ink-800);
  box-shadow: var(--shadow-panel);
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.timeline:focus-visible { outline: 2px solid var(--volt); outline-offset: 3px; }

.timeline svg { min-width: 560px; }

/* Under 620px the timeline stacks instead of scrolling, so day 60, the whole
   point of the section, is on screen at first read. */
.timeline-stack { display: none; margin-top: 2.5rem; }

.timeline-stack li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .5rem 1rem;
  padding-block: 1rem;
  border-top: 1px solid var(--line-soft);
}

.timeline-stack__when {
  font-size: .6875rem;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
}

.timeline-stack__what { font-size: 1.0625rem; font-weight: 700; }

.timeline-stack__end { border-top-color: var(--volt); }
.timeline-stack__end .timeline-stack__when,
.timeline-stack__end .timeline-stack__what { color: var(--volt); }

.timeline__rule { stroke: var(--line); stroke-width: 2; }

.timeline__span rect { fill: #1c2739; }
.timeline__span[data-span="3"] rect { fill: var(--volt); }

.timeline text {
  fill: var(--steel);
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.timeline .timeline__label { fill: var(--chalk); font-size: 17px; letter-spacing: -.01em; text-transform: none; }

.timeline__mark line { stroke: var(--volt); stroke-width: 2; }
.timeline__mark text { fill: var(--volt); text-anchor: middle; }
.timeline__mark .timeline__label { fill: var(--volt); }

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(1.75rem, 4vw, 3rem);
  margin-top: clamp(3rem, 6vw, 4rem);
}

.fact h3 { padding-top: 1.5rem; border-top: 2px solid var(--volt); }
.fact p { margin-top: .875rem; color: var(--steel); }

/* --- Integrity ------------------------------------------------------------ */

.review {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  margin-top: clamp(3rem, 6vw, 4.5rem);
  align-items: start;
}

.review__steps { counter-reset: step; }

.review__steps li {
  counter-increment: step;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 1.5rem;
  padding-block: 1.75rem;
  border-top: 1px solid var(--line-soft);
}

.review__steps li:first-child { border-top: 0; padding-top: 0; }

.review__steps li::before {
  content: counter(step, decimal-leading-zero);
  font-size: 1.125rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: .05em;
  color: var(--volt);
}

.review__body p { margin-top: .75rem; max-width: 68ch; color: var(--steel); }

.review__note {
  --cut: 28px;
  padding: clamp(1.75rem, 3vw, 2.25rem);
  background: var(--ink-800);
  box-shadow: var(--shadow-panel);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%);
}

.review__note p { margin-top: .875rem; color: var(--steel); }

/* --- Signup --------------------------------------------------------------- */

.signup { margin-top: clamp(2.5rem, 5vw, 3.5rem); }

.signup__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .875rem;
  align-items: start;
}

.signup__field label {
  display: block;
  margin-bottom: .5rem;
  font-size: .6875rem;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--steel);
}

.signup__field input {
  width: 100%;
  padding: 1rem 1.125rem;
  background: var(--ink-800);
  border: 1px solid var(--line);
  color: var(--chalk);
  transition: border-color var(--t-quick) linear, background-color var(--t-quick) linear;
}

.signup__field input::placeholder { color: var(--steel-soft); }
.signup__field input:hover { border-color: var(--steel); }
.signup__field input[aria-invalid="true"] { border-color: var(--ember); background: var(--ember-wash); }

.btn--submit { align-self: end; min-width: 13.5rem; }

.signup__error {
  margin-top: .625rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--ember);
}

.signup__note { margin-top: 1rem; font-size: .8125rem; color: var(--steel); }

.signup__success {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding: 1.5rem 1.75rem;
  background: var(--ink-800);
  border-top: 2px solid var(--volt);
  font-size: var(--step-1);
  font-weight: 600;
}

.is-busy [data-submit-label] { opacity: .55; }

/* --- Footer --------------------------------------------------------------- */

.footer {
  padding-top: clamp(3rem, 6vw, 4.5rem);
  padding-bottom: max(clamp(3rem, 6vw, 4.5rem), env(safe-area-inset-bottom));
  border-top: 1px solid var(--line-soft);
  background: var(--ink-850);
}

.footer__inner { display: grid; gap: 1.75rem; }

.footer__mark {
  font-size: 1.125rem;
  font-weight: 900;
  font-stretch: 118%;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* Negative margin absorbs the taller hit area so the row reads at its old
   density while each link still clears 44px for a thumb. */
.footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem 1.5rem;
  margin-block: -.75rem;
}

.footer__nav a {
  display: inline-block;
  padding-block: .75rem;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--steel);
  transition: color var(--t-quick) linear;
}
.footer__nav a:hover { color: var(--chalk); }

.footer__legal {
  max-width: 68ch;
  font-size: .8125rem;
  line-height: 1.7;
  color: var(--steel-quiet);
}

/* --- Authored motion ------------------------------------------------------
   One orchestrated moment: the traversal trace draws through the hero on load.
   Everything else is a state change, not an entrance.
   -------------------------------------------------------------------------- */

@keyframes trace-draw {
  from { stroke-dashoffset: var(--trace-length); }
  to   { stroke-dashoffset: 0; }
}

@keyframes node-in {
  from { opacity: 0; transform: scale(.4); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes glow-in {
  to { opacity: .12; }
}

[data-trace][data-animate] .trace__line {
  stroke-dasharray: var(--trace-length);
  animation: trace-draw 2.4s var(--ease) forwards;
}

/* Only reached when script runs. Without it the glow simply sits at rest. */
[data-trace][data-animate] .trace__shadow {
  opacity: 0;
  animation: glow-in .9s var(--ease) 1.75s forwards;
}

[data-trace][data-animate] .trace__nodes circle {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  animation: node-in .5s var(--ease) forwards;
}
[data-trace][data-animate] .trace__nodes circle:nth-child(1) { animation-delay: .95s; }
[data-trace][data-animate] .trace__nodes circle:nth-child(2) { animation-delay: 1.6s; }
[data-trace][data-animate] .trace__nodes circle:nth-child(3) { animation-delay: 2.15s; }

[data-frame-route][data-animate] path {
  stroke-dasharray: var(--trace-length);
  animation: trace-draw 3s var(--ease) forwards;
}

/* --- Responsive ----------------------------------------------------------- */

@media (max-width: 860px) {
  .masthead { gap: 1rem; }

  /* Matches the 45px height of the adjacent wishlist button, and clears the
     44px touch minimum this breakpoint exists for. min-height holds that floor
     when the label is dropped at 430px and only the bars remain. */
  .masthead__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .625rem;
    min-height: 2.75rem;
    padding: .8125rem .875rem;
    background: none;
    border: 1px solid var(--line);
    font-size: .75rem;
    font-weight: 800;
    letter-spacing: .12em;
    text-transform: uppercase;
    cursor: pointer;
  }

  .masthead__toggle-bars { display: grid; gap: 4px; }
  .masthead__toggle-bars i { display: block; width: 16px; height: 2px; background: var(--chalk); }

  .masthead__menu {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    display: grid;
    gap: 0;
    padding: .5rem clamp(1.25rem, 4vw, 2.5rem) 1.25rem;
    background: var(--ink-900);
    border-bottom: 1px solid var(--line-soft);
  }

  .masthead__menu[hidden] { display: none; }
  .masthead__menu a { display: block; padding-block: .875rem; font-size: 1rem; }
  .masthead__menu a::after { display: none; }

  .technique { grid-template-columns: minmax(0, 1fr); }
  .review { grid-template-columns: minmax(0, 1fr); }
  .roster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  :root {
    --shell: min(1240px, 100% - 2.25rem - env(safe-area-inset-left) - env(safe-area-inset-right));
    --shell-narrow: min(720px, 100% - 2.25rem - env(safe-area-inset-left) - env(safe-area-inset-right));
  }

  .hero { min-height: auto; padding-block: clamp(5rem, 18vh, 8rem) 3.5rem; }
  .hero__actions .btn { flex: 1 1 100%; }

  .countdown { flex-wrap: wrap; gap: 1.25rem 2rem; }
  .countdown__cell { flex: 1 1 34%; }

  .roster { gap: 1rem; }
  .op h3, .op__role, .op__kit { padding-inline: 1rem; }

  .timeline { display: none; }
  .timeline-stack { display: block; }

  /* The arena is the first viewport's promise; on a narrow screen the scrim
     steps back, the geometry brightens, and the art scales up so the skyline
     clears the copy instead of hiding behind it. */
  .hero__scrim {
    background:
      linear-gradient(to top,
        var(--ink-900) 6%,
        color-mix(in srgb, var(--ink-900) 52%, transparent) 28%,
        color-mix(in srgb, var(--ink-900)  8%, transparent) 64%,
        color-mix(in srgb, var(--ink-900) 38%, transparent) 100%);
  }

  .hero__art {
    transform: scale(1.22) translateY(-7%);
    transform-origin: center top;
  }

  .arena__far polygon  { fill: #2a3f66; }
  .arena__mid polygon  { fill: #1c2c48; }
  .arena__near polygon { fill: #0e1626; }
  .arena__lights rect  { opacity: 1; }
  .trace__line { stroke-width: 4; }

  .signup__row { grid-template-columns: minmax(0, 1fr); }
  .btn--submit { width: 100%; }

  .frame { --cut: 24px; }
}

/* --- Narrow bar ------------------------------------------------------------
   Wordmark, menu control and the persistent wishlist action come to about
   387px of unshrinkable flex content, so below this the bar ran off the right
   edge and clipped the CTA. Nothing is dropped: the menu label goes, since the
   two bars already say the same thing, and the rest tightens to fit.
   -------------------------------------------------------------------------- */

@media (max-width: 430px) {
  .masthead {
    gap: .75rem;
    padding-inline:
      max(1rem, env(safe-area-inset-left))
      max(1rem, env(safe-area-inset-right));
  }

  .wordmark { font-size: 1.125rem; letter-spacing: .08em; }

  .masthead__toggle { gap: 0; padding-inline: .75rem; }
  .masthead__toggle-text { display: none; }

  .masthead__menu { padding-inline: 1rem; }

  .masthead__cta { padding-inline: 1rem; }
}

/* --- Narrow phones ---------------------------------------------------------
   Portrait plates in one column would run the roster past 3000px of scroll, and
   two columns cannot hold an operator name at this width. So the card turns on
   its side: the plate becomes an identifying chip beside the name it belongs to.
   -------------------------------------------------------------------------- */

@media (max-width: 480px) {
  .roster { grid-template-columns: minmax(0, 1fr); gap: .75rem; }

  /* Name and role sit beside the plate; the kit sentence runs under both, so
     the plate never leaves a column of dead ground beneath it. */
  .op {
    display: grid;
    grid-template-columns: clamp(88px, 27vw, 116px) minmax(0, 1fr);
    column-gap: 1rem;
    padding: 0 1rem 1.25rem 0;
  }

  .op__plate { grid-column: 1; grid-row: 1 / span 2; align-self: start; }

  .op h3 {
    grid-column: 2;
    align-self: end;
    margin-top: 0;
    padding-inline: 0;
    font-size: 1.125rem;
  }

  .op__role { grid-column: 2; align-self: start; padding-inline: 0; }

  .op__kit {
    grid-column: 1 / -1;
    margin-top: 1rem;
    padding-inline: 1rem 0;
  }
}

/* --- Reduced motion --------------------------------------------------------
   The trace still delivers its meaning: it arrives fully drawn instead of
   drawing itself. Nothing is hidden from a visitor who opts out.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    /* Without this the staged delays survive, so a visitor who opted out of
       motion still waits two seconds for the trace nodes and the glow. */
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  [data-trace][data-animate] .trace__line,
  [data-trace][data-animate] .trace__shadow,
  [data-frame-route][data-animate] path {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }

  [data-trace][data-animate] .trace__nodes circle { opacity: 1; transform: none; }

  .btn:hover { transform: none; }
}
