/* ============================================
   RALLYKIT · the night session program
   ============================================ */

:root {
  --bg: #0b0b0e;
  --void: #08080a;
  --surface: #101015;
  --surface-2: #14141a;
  --line: rgba(255, 255, 255, 0.08);
  --line-strong: rgba(255, 255, 255, 0.14);

  --ink: #f4f0e6;
  --ink-soft: #d5cfbf;
  --mute: #8a8476;
  /* Muted ink for type set ON Warm Paper (the lookup field). --mute is tuned
     for the dark ground and drops to 2.2:1 here. */
  --paper-mute: #6a6456;

  --accent: #d88a2f;
  --accent-2: #8478f0;
  --clay: #c25a24;
  --graph-context: #5aa58c;

  --font-display: "Fraunces", "Times New Roman", serif;
  --font-body: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  --container: 1240px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  /* One column gap for every two-up section, so the hero, the pillars and the
     access spec all break on the same vertical line. */
  --col-gap: clamp(2rem, 5vw, 5rem);
  /* One vertical rhythm for every band */
  --section: clamp(4rem, 8vh, 6rem);
  /* Distance from the container's right edge out to the viewport edge */
  --bleed: max(var(--gutter), calc((100vw - var(--container)) / 2 + var(--gutter)));

  /* Tracking carries as much of the voice as size does: negative on display,
     strongly positive on small uppercase mono. Tokened so it survives a
     redesign instead of dying as scattered one-off values. */
  --track-display: -0.025em;
  --track-headline: -0.02em;
  --track-title: -0.015em;
  --track-dek: -0.01em;
  --track-wordmark: -0.028em;
  --track-wordmark-italic: 0.02em;
  --track-label: 0.08em;

  --radius-sm: 8px;
  --radius: 14px;
  --radius-glass: 16px;
  --radius-lg: 20px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  color-scheme: dark;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
body { overflow-x: hidden; }

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--mute);
}

/* Screen-reader-only, for the lookup label */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Supporting copy. One rule for every section, so the page cannot drift back
   into setting the same role in two different faces. */
.copy {
  margin: 0;
  max-width: 46ch;
  color: var(--ink-soft);
}

.eyebrow {
  display: inline-block;
  color: var(--accent);
  margin-bottom: 1rem;
}


/* ============================================
   SKIP
   ============================================ */
.skip-link {
  position: absolute;
  left: var(--gutter);
  top: 0.75rem;
  z-index: 40;
  /* 42px tall before this; the one control on the page under the 44px floor */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.65rem 1.15rem;
  background: var(--ink);
  color: var(--bg);
  border-radius: 999px;
  font-size: 0.85rem;
  transform: translateY(-160%);
}
.skip-link:focus {
  transform: translateY(0);
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ============================================
   NAV
   ============================================ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  padding: 1rem 0;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  background: color-mix(in oklab, var(--bg) 65%, transparent);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s, background 0.3s;
}
/* Near-opaque once scrolled: the warm-paper sheet passes under the bar, and a
   65%-transparent ground would drop the nav ink well below 4.5:1 against it. */
.nav[data-scrolled] {
  border-bottom-color: var(--line);
  background: color-mix(in oklab, var(--bg) 94%, transparent);
}
.nav__inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.nav__logo {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink);
}
/* Keeps a trailing .stop tied to its last word — an inline-block is a wrap
   opportunity even with no whitespace before it, so the dot can orphan. */
.nowrap { white-space: nowrap; }

/* The full stop. It is the ball, the thing that stops the rally, and the one
   place Floodlight appears at brand scale.
   Drawn rather than typed: Fraunces sets its period light and ~4px at wordmark
   size, which disappears. Sized in em so the same rule terminates the lockup
   (8px at 1.98rem) and the closing headline (15px at 3.6rem). Inline, so it
   rides the real text baseline. */
.stop {
  display: inline-block;
  width: 0.26em;
  height: 0.26em;
  margin-left: 0.09em;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: baseline;
}
.nav__wordmark {
  font-family: var(--font-display);
  font-size: 2.3rem;
  /* "Kit" is the light half — the object the rally is played with */
  font-weight: 300;
  letter-spacing: var(--track-wordmark);
  line-height: 1;
}
/* Italic carries "Rally" — the motion — and now the weight as well, so the
   stress lands on the verb and "Kit" recedes into the object. */
.nav__wordmark em {
  font-style: italic;
  font-weight: 600;
  /* Fraunces flares its ascender terminals as the optical size climbs. At the
     wordmark's size the two l's flared into each other and the word read as
     "Raffy". A text optical size plus positive tracking pulls them apart. */
  font-variation-settings: "opsz" 9;
  letter-spacing: var(--track-wordmark-italic);
  /* the italic y's tail would otherwise clip the upright K; the bolder cut
     swings wider, so it needs a touch more room than the light one did */
  margin-right: 0.07em;
}
.nav__link {
  font-size: 0.92rem;
  /* At 320px the bar squeezes it and "Log in" breaks across two lines. */
  white-space: nowrap;
  color: var(--ink-soft);
  transition: color 0.2s;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.nav__link:hover { color: var(--accent); }
.nav__link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}
.nav__actions {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 1.75rem);
}

.nav__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  font-size: 0.92rem;
  padding: 0.7rem 1.3rem;
  border: 1px solid transparent;
  border-radius: 999px;
  /* Filled paper, same fill and same amber hover as .btn--primary — the nav
     action and the page's primary action are one component at two sizes. */
  background: var(--ink);
  color: var(--bg);
  white-space: nowrap;
  transition: background 0.2s, color 0.2s;
}
.nav__cta:hover {
  background: var(--accent);
}

/* ============================================
   BUTTONS
   ============================================ */
.btn {
  /* <button> does not inherit font-family; every other .btn is an <a>, so the
     lookup's submit was silently rendering in the UA default (Arial). */
  font-family: var(--font-body);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.85rem 1.4rem;
  border-radius: 999px;
  font-size: 0.9rem;
  border: 1px solid transparent;
  white-space: nowrap;
  transition: transform 0.2s, background 0.2s, border-color 0.2s, color 0.2s;
}
.btn--primary {
  background: var(--ink);
  color: var(--bg);
}
.btn--primary:hover {
  background: var(--accent);
}
.btn--ghost {
  color: var(--ink);
  border-color: var(--line-strong);
}
.btn--ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.btn:active {
  transform: scale(0.98);
}

.nav__logo:focus-visible,
.nav__cta:focus-visible,
.btn:focus-visible,
.footer__brand a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}
.nav__cta:focus-visible,
.btn:focus-visible {
  border-radius: 999px;
}
.nav__logo:focus:not(:focus-visible),
.nav__cta:focus:not(:focus-visible),
.btn:focus:not(:focus-visible),
.footer__brand a:focus:not(:focus-visible) {
  outline: none;
}

/* ============================================
   HERO
   ============================================ */
.hero {
  position: relative;
  /* Clears the fixed nav with 40px of air. */
  padding: 6.25rem 0 0;
  overflow: hidden;
}
/* The hero stays inside the container like every other section; only the
   sheet escapes it. That is what keeps one column line down the whole page. */
.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  /* Shared top line with the sheet. Centred, the copy sat 191px below the nav
     while the sheet sat 16px below it — the artifact began immediately and the
     headline began much later, which read as dead space in the header. */
  align-items: start;
}
/* Centred, search-first. The product is carried by the named home panels
   below rather than by an artifact beside the headline. */
.hero__copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 48rem;
  margin: 0 auto;
}
.hero__copy .copy { margin-inline: auto; }
/* The home sits directly under the search: the answer beneath the question,
   close enough that the first viewport carries both. */
.hero__panel { margin-top: clamp(0.9rem, 1.6vw, 1.4rem); }

.hero__headline {
  text-wrap: balance;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.4rem, 4vw + 0.5rem, 4.6rem);
  line-height: 1.02;
  letter-spacing: var(--track-display);
  margin: 0 0 1.5rem;
}
.hero__headline em {
  font-style: italic;
  color: var(--accent);
  font-weight: 300;
  /* Fraunces gets swashier as opsz climbs; at 73px the display cut reads
     ornate against an otherwise restrained page. A text optical size keeps
     the italic without the flourish. */
  font-variation-settings: "opsz" 16;
}
/* The hero's proposition, sitting directly on the field that tests it. Display
   face so it reads as a statement rather than more supporting copy. */
.hero__prompt {
  margin: 1.15rem 0 1.35rem;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.3rem, 1.4vw + 0.9rem, 1.9rem);
  line-height: 1.3;
  letter-spacing: var(--track-dek);
  color: var(--ink);
  max-width: 30ch;
}


@media (prefers-reduced-motion: no-preference) {
  .hero__panel {
    animation: sheetIn 1.2s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
}
/* Vertical only. The panel is centred under the search now, so any horizontal
   component would slide it off the page's own centre line on the way in. */


/* ============================================
   TOURGRAPH BAND
   ============================================ */
.band {
  position: relative;
  padding: var(--section) 0;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--void);
  isolation: isolate;
}
/* Full-bleed and unscrimmed. The credit sits underneath rather than over the
   hub, so the constellation needs no darkening to keep text legible — which is
   the better trade: a scrim to protect two lines of type was dimming the one
   thing the band exists to show. */
.band__canvas {
  display: block;
  width: 100%;
  /* Sized off width, never vh: iOS grows and shrinks the viewport height as
     its URL bar hides on scroll, which would resize this box mid-scroll. */
  height: clamp(14rem, 24vw, 21rem);
  filter: saturate(1.08);
}
/* Claim then credit then artwork. The statement is read first, the machine is
   named second, and the constellation is the evidence you look at after both. */
.band__head { text-align: center; margin-bottom: 1.75rem; }
.band__head .band__credit { margin-top: 0.55rem; }
/* The benefit word leads and the machine is credited underneath, not the other
   way round — the visitor is being told they have to do nothing, and TourGraph
   is why that is true. Stated at headline scale in full-strength ink so the
   band lands as a claim rather than as a logo credit with art above it. */
.band__word {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.8rem, 2.5vw + 0.8rem, 2.8rem);
  line-height: 1.1;
  letter-spacing: var(--track-headline);
}
.band__credit { margin: 0; color: var(--mute); }
/* The name carries the Floodlight; "Powered by" stays mute, so the credit
   reads as a mark rather than as another line of small print. */
.tg { color: var(--accent); }
.band__legend {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2rem);
  margin: 1.25rem auto 0;
  padding: 0 var(--gutter);
  list-style: none;
  color: var(--mute);
  font-size: 0.78rem;
}
.band__key {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.band__key::before {
  content: '';
  width: 1.1rem;
  height: 2px;
  border-radius: 999px;
  background: currentColor;
}
.band__key--match { color: var(--accent); }
.band__key--media { color: var(--clay); }
.band__key--tournament { color: var(--accent-2); }
.band__key--context { color: var(--graph-context); }

/* ============================================
   PILLARS — Record + Kit
   ============================================ */
.pillars {
  padding: var(--section) 0;
  background: var(--bg);
  border-top: 1px solid var(--line);
}
.pillars__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--col-gap);
  align-items: start;
}
.pillar { display: flex; flex-direction: column; }
.pillar__lede {
  color: var(--ink-soft);
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.3rem, 1.4vw + 0.9rem, 1.9rem);
  line-height: 1.3;
  letter-spacing: var(--track-dek);
  margin: 0 0 0.9rem;
  max-width: 34ch;
}
.pillar__lede em {
  font-style: italic;
  color: var(--ink);
  font-variation-settings: "opsz" 16;
}

/* One panel, cropped to the mock's own inked band (170 → 1260 of 1400) so the
   page's content starts at the sheet edge instead of 120px inside it. */
.home--wide { width: 100%; max-width: 1060px; margin-inline: auto; }
.home--wide img {
  width: calc(100% * 1400 / 1120);
  max-width: none;
  height: auto;
  margin-left: calc(-100% * 156 / 1120);
  aspect-ratio: 1400 / 950;
  object-fit: cover;
  object-position: 50% 0%;
}
.home--wide picture {
  display: block;
  overflow: hidden;
  border-radius: var(--radius-sm);
  box-shadow:
    0 34px 80px rgba(0, 0, 0, 0.62),
    0 0 0 1px rgba(255, 255, 255, 0.09);
}
.home--wide img { box-shadow: none; border-radius: 0; }
/* Level, not staggered. The stair gave rhythm when the frames were unlabelled;
   with a caption under each one it only knocks the labels out of line, and
   like-for-like comparison is the entire point of the row. */
/* A stair, not a fan. The old rotated stack read as a stock screenshot
   carousel; a consistent vertical step gives rhythm and still lets all three
   be compared like-for-like, which is the entire point of the band. */
.home { margin: 0; width: 100%; }
/* Naming the styles is what turns three screenshots into three products. */
.home__label {
  display: block;
  margin-top: 1rem;
  text-align: center;
}
.home__label .mono {
  display: block;
  color: var(--accent);
  margin-bottom: 0.4rem;
}
.home__note {
  display: block;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

/* ============================================
   THE LIVING RECORD — the sequence, not the assertion
   ============================================ */
.living {
  padding: var(--section) 0;
  border-bottom: 1px solid var(--line);
}
.living__head {
  text-align: center;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.living__title {
  margin: 0 0 0.9rem;
  text-wrap: balance;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.8rem, 2.5vw + 0.8rem, 2.8rem);
  line-height: 1.15;
  letter-spacing: var(--track-headline);
}
.living__title em {
  font-style: italic;
  color: var(--accent);
  font-variation-settings: "opsz" 16;
}
.living__head .copy { margin-inline: auto; }

.steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--col-gap);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}
.step {
  position: relative;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  column-gap: 1rem;
  align-items: start;
}
/* Everything after the icon occupies the second column, so the three icons sit
   on one horizontal axis and the stages read as a line rather than three
   stacked blocks. */
.step > *:not(.step__icon) { grid-column: 2; }
/* The connector is the record moving between stages, so it belongs to the
   gap rather than to either step. */
.step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 20px;
  left: calc(100% + 0.75rem);
  width: calc(var(--col-gap) - 1.5rem);
  height: 1px;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--accent) 20%, transparent));
}
.step__icon {
  grid-column: 1;
  grid-row: 1 / span 6;
  display: block;
  width: 40px;
  height: 40px;
  color: var(--accent);
}
.step__icon svg { width: 100%; height: 100%; display: block; }
.step__icon--live { filter: drop-shadow(0 0 12px color-mix(in oklab, var(--accent) 55%, transparent)); }
.step__n {
  display: block;
  color: var(--accent);
  margin: 0.5rem 0 0.55rem;
}
.step__title {
  margin: 0 0 0.6rem;
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.2rem, 1vw + 0.8rem, 1.6rem);
  line-height: 1.2;
  letter-spacing: var(--track-title);
}
.step__meta {
  margin: 0 0 0.25rem;
  color: var(--ink-soft);
  text-transform: none;
  letter-spacing: 0.02em;
}
.step__body { margin-top: 0.2rem; }

/* Captured to size, so no vertical crop is needed — the source already ends on
   the season-facts table. Inked band is 156 → 1243 of 1400; mirrored, so the
   mock's RIGHT content edge lands on the sheet's right edge, and therefore on
   the left column's boundary. */
/* The hero sheet is the page's one authored entrance; this one is simply there. */


/* ============================================
   ACCESS
   ============================================ */
.access {
  padding: var(--section) 0;
}
.access {
  border-top: 1px solid var(--line);
  background: var(--void);
}
.access__col {
  /* Single column now that the spec has its own band — so the closing
     statement carries the width instead of a list sitting beside it. */
  max-width: 46rem;
}
.access__title {
  font-family: var(--font-display);
  font-weight: 300;
  /* keeps the three sentences from breaking as "...One / record" */
  text-wrap: balance;
  font-size: clamp(2rem, 3.5vw + 0.5rem, 3.6rem);
  line-height: 1.1;
  letter-spacing: var(--track-headline);
  margin: 0 0 1.25rem;
}
/* The close's promise made actionable. "We might have already built yours" is
   a claim until there is somewhere to type a name. */
.lookup {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  margin: 0 auto 0.85rem;
  width: 100%;
  max-width: 34rem;
}
/* Warm Paper slab (operator direction, 2026-08-15). The field is where the
   visitor types their own name, so it is the one place on the page that should
   read as an invitation rather than as chrome — paper on court, the same stock
   the product mock is printed on. The amber submit still sits beside it as the
   only filled Floodlight surface. */
.lookup__wrap {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 18rem;
  min-width: 0;
}
.lookup__icon {
  position: absolute;
  left: 1.15rem;
  width: 20px;
  height: 20px;
  color: var(--paper-mute);
  pointer-events: none;
}
.lookup__field {
  width: 100%;
  min-width: 0;
  min-height: 56px;
  padding: 0.9rem 1.4rem 0.9rem 3.1rem;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-body);
  font-size: 1rem;
  transition: box-shadow 0.2s;
}
/* Held blank: the visible prompt is .lookup__ph, which the placeholder alone
   could not carry because it has to end in a real .stop element. A single
   space keeps :placeholder-shown true while the field is empty, which is what
   swaps the two — no JS, and it survives autofill. */
.lookup__field::placeholder { color: transparent; }
.lookup__field:hover { box-shadow: 0 0 0 3px color-mix(in oklab, var(--ink) 18%, transparent); }
.lookup__field:focus {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.lookup__ph {
  position: absolute;
  left: 3.1rem;
  color: var(--paper-mute);
  font-size: 1rem;
  pointer-events: none;
  transition: opacity 0.15s;
}
.lookup__field:not(:placeholder-shown) + .lookup__ph { opacity: 0; }
/* Amber submit — operator direction, 2026-08-15. It is the one filled amber
   surface on the page; see the Floodlight Rule note. */
.lookup__go {
  min-height: 56px;
  padding: 1rem 1.75rem;
  font-size: 0.95rem;
  background: var(--accent);
  color: var(--bg);
}
.lookup__go:hover { background: color-mix(in oklab, var(--accent) 86%, var(--ink)); }
.lookup__note {
  text-wrap: balance;
  max-width: 64ch;
  font-size: 0.92rem;
  color: var(--mute);
}

/* Result strip. Two honest states — a home exists, or it does not yet — each
   ending in the same thing: an email. The page reveals nothing about the home
   itself; asking is the point. */
.lookup__result {
  margin: 1.25rem auto 0;
  max-width: 34rem;
  text-align: left;
}
.lookup__result:empty { display: none; }
.lookup__result[data-state] {
  padding: 1.15rem 1.35rem 1.35rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--bg) 60%, transparent);
}
.lookup__state {
  margin: 0 0 0.5rem;
  color: var(--mute);
}
.lookup__result[data-state='yes'] .lookup__state { color: var(--accent); }
.lookup__line {
  margin: 0 0 1.1rem;
  color: var(--ink-soft);
  max-width: 40ch;
}
.lookup__line strong { color: var(--ink); font-weight: 400; }

.access__actions {
  margin-top: 1.75rem;
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.access__actions .btn { padding: 1rem 1.6rem; font-size: 0.95rem; }



/* ============================================
   FOOTER
   ============================================ */
.footer {
  border-top: 1px solid var(--line);
  padding: 2.5rem 0;
  background: var(--void);
}
.footer__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.footer__brand {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.footer__tag { color: var(--mute); }
.footer__legal { color: var(--mute); }

/* ============================================
   LOGIN HOLDING PAGE
   ============================================ */
.login-page {
  min-height: 100svh;
  overflow-x: hidden;
}
.login-shell {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100svh;
  overflow: hidden;
  background:
    radial-gradient(circle at 76% 48%, color-mix(in oklab, var(--accent) 8%, transparent), transparent 30rem),
    var(--bg);
}
.login-shell::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 50%;
  right: clamp(-26rem, -18vw, -8rem);
  width: clamp(28rem, 58vw, 54rem);
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 50%;
  transform: translateY(-50%);
}
.login__header,
.login,
.login__footer {
  width: min(100%, var(--container));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.login__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}
.login__logo {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
}
.login__return {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  color: var(--ink-soft);
  font-size: 0.92rem;
  transition: color 0.2s;
}
.login__return:hover { color: var(--accent); }
.login__return:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}
.login {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(18rem, 0.72fr);
  align-items: center;
  gap: var(--col-gap);
  padding-top: clamp(3rem, 8vh, 7rem);
  padding-bottom: clamp(4rem, 10vh, 8rem);
}
.login__content { max-width: 42rem; }
.login__title {
  max-width: 9ch;
  margin: 0 0 1.25rem;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 4vw + 0.5rem, 4.6rem);
  font-weight: 300;
  letter-spacing: var(--track-display);
  line-height: 0.94;
  text-wrap: balance;
}
.login__title em {
  color: var(--accent);
  font-weight: 500;
}
.login__title span { color: var(--accent); }
.login__copy {
  max-width: 52ch;
  margin: 0;
  color: var(--ink-soft);
  font-size: clamp(1rem, 1.6vw, 1.15rem);
}
.login__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}
.login__court {
  position: relative;
  width: min(100%, 26rem);
  aspect-ratio: 0.78;
  justify-self: end;
  border: 1px solid var(--line-strong);
}
.login__court::before {
  content: "";
  position: absolute;
  inset: 50% 0 auto;
  border-top: 1px solid var(--line-strong);
}
.login__court-line {
  position: absolute;
  display: block;
}
.login__court-line--base {
  inset: 0 50% 0 auto;
  border-right: 1px solid var(--line-strong);
}
.login__court-line--service {
  inset: 25% 18% 25%;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.login__ball {
  position: absolute;
  top: 47%;
  left: 47%;
  width: 0.8rem;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0.45rem 1.25rem color-mix(in oklab, var(--accent) 25%, transparent);
}
.login__footer {
  padding-top: 1.25rem;
  padding-bottom: 1.5rem;
  border-top: 1px solid var(--line);
}

@media (max-width: 720px) {
  .login {
    grid-template-columns: 1fr;
    padding-top: 4rem;
  }
  .login__court {
    width: min(82vw, 22rem);
    justify-self: center;
    opacity: 0.7;
  }
}

@media (max-width: 480px) {
  .login__header { align-items: flex-start; }
  .login__header .nav__wordmark { font-size: 1.9rem; }
  .login__return { font-size: 0.85rem; }
  .login__title { font-size: clamp(2.2rem, 10vw, 3.4rem); }
  .login__actions { flex-direction: column; }
  .login__actions .btn { width: 100%; }
}

/* ============================================
   RESPONSIVE
   ============================================ */
@media (max-width: 1100px) {
  .hero__inner { min-height: 480px; }
  .hero__headline { font-size: clamp(2rem, 3.5vw + 0.5rem, 3.6rem); }
}
@media (max-width: 900px) {
  .hero { padding: 4.5rem 0 0; }
  .hero__inner {
    grid-template-columns: 1fr;
    gap: 2.5rem;
    min-height: 0;
  }
  .hero__copy {
    padding: 3.5rem 0 0;
    justify-content: flex-start;
  }
  .steps { grid-template-columns: 1fr; gap: 2.5rem; }
  .step:not(:last-child)::after { display: none; }
  .pillars__grid { grid-template-columns: 1fr; gap: 2.5rem; }

}
/* Under ~620px the full overview renders at roughly 2px type — a proof no one
   can read. The crop is VERTICAL only: the mock keeps its whole inked width so
   nothing runs off the right edge, and the frame simply ends after the header
   band — name, ranking, and the next/latest pair, which is exactly what the
   caption underneath promises. An earlier version zoomed 1.85x as well and
   sliced "No. 178" and the whole photo column off the right. */
@media (max-width: 620px) {
  .home--wide picture { max-height: 17rem; }
  .home--wide img { aspect-ratio: auto; }
}
@media (max-width: 560px) {
  .hero { padding-top: 6rem; }
  .nav__wordmark { font-size: 1.9rem; }
  .nav__cta { font-size: 0.85rem; padding: 0.6rem 1rem; }
  .hero__headline { font-size: clamp(2.2rem, 10vw, 3.4rem); }
  .band { padding: 3rem 0; }
  .band__head { margin-bottom: 1rem; }
  .band__canvas { height: 12.5rem; }
  .band__legend {
    gap: 0.8rem;
    margin-top: 0.8rem;
    font-size: 0.78rem;
    letter-spacing: 0.045em;
  }
  .band__key { gap: 0.35rem; }
  .band__key::before { width: 0.75rem; }
  .access__actions {
    flex-direction: column;
    align-items: stretch;
  }
  .access__actions .btn {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .btn:active { transform: none; }
}
