/*
 * Pitwall — the live timing wall, rebuilt from Pocket Pitwall in /aurora's design language.
 *
 * The system is /aurora's, the colours the wall's own:
 *   - one face, Figtree, at 400 for text and 600-700 for figures and titles, with tabular
 *     figures wherever a number changes, and nothing under 13 px;
 *   - one surface, the card: nearly opaque, 28-px corners, lit along its top edge and lifted
 *     by a soft shadow; anything nested in a card is an inset tile. No backdrop blur: the
 *     map under a card moves every frame, so a blur would be redone every frame;
 *   - pills for every control, a round + for what a card doesn't need to say at first;
 *   - spacing in steps of 4 px (--s-*).
 *
 * No accent hue. A selected control is inverted — ink fill, ground-coloured text — so every
 * colour on the page is data, each with one meaning: the flag's colour is the flag; purple
 * is a session best and green a personal one; amber is caution that isn't a flag; blue is
 * rain; red is a penalty, the pit lane and the red flag; and each team has its own. The
 * tyres are marked as the sidewalls are.
 *
 * Legibility first: the wall is read in glances, at arm's length, mid-race. Type is sized by
 * priority tier (--fs-*), the most important figures largest and stillest; urgency shows in
 * colour and motion, never in a change of size; and when space runs short a column leaves
 * rather than everything shrinking.
 *
 * Every literal colour is in the :root block below; nothing under it may name one
 * (tests/pitwall/lint.test.js holds the file to that, and to 4.5:1 for every text token).
 */

:root {
  --ground: #111214;
  --ink: #eceef0;
  --ink-soft: #a3a9b0;
  --ink-faint: #8a9097;

  --card: rgba(17, 18, 20, 0.9);
  --card-solid: #16181b;
  --row: #1d1f23; /* a car's row: an inset tile on the tower's solid card */
  --inset: rgba(236, 238, 240, 0.05);
  --grid: rgba(236, 238, 240, 0.07);
  --hover: rgba(236, 238, 240, 0.08);
  --line: rgba(236, 238, 240, 0.1);
  --rule: rgba(236, 238, 240, 0.12);
  --axis: rgba(236, 238, 240, 0.2);
  --rule-strong: rgba(236, 238, 240, 0.26);
  --shadow: rgba(4, 5, 6, 0.6);
  --lift: inset 0 1px 0 var(--rule), 0 24px 48px -20px var(--shadow);

  /* A selected control: inverted, never a hue. */
  --selected: var(--ink);
  --on-selected: var(--ground);

  /* The wordmark: chalk into steel, so it never reads as data. */
  --logo-from: #f6f7f8;
  --logo-mid: #c6cbd0;
  --logo-to: #8f969d;

  /* Flags, as race control shows them. */
  --flag-green: #3ecf78;
  --flag-yellow: #f5c518;
  --flag-red: #e8112d;
  --flag-chequered: #f6f7f8;

  /* Timing: a session best, a personal best. */
  --timing-best: #b47cff;
  --timing-personal: #3ecf78;
  --caution: #f5c518; /* careful, but not a flag: an investigation, a temperature rising */
  --rain: #3aa0ff;
  --alert: #e8112d; /* a penalty, the pit lane */
  --alert-fill: #c40f27; /* the same red as a fill under text, dark enough for it */
  --alert-soft: #ff4055; /* the same red as a mark on the ground: race control's serious messages */

  /* Tyres, as the sidewalls are marked; the soft's red lifted a step to read as a mark. */
  --tyre-soft: #ff4055;
  --tyre-medium: #f5c518;
  --tyre-hard: #f6f7f8;
  --tyre-inter: #3ecf78;
  --tyre-wet: #3aa0ff;

  /* The intro's tyre, side on, as the app's launcher icon draws it: rubber, the tread's lit
     and shaded edge, the wheel cover with its bolts, the rim's lip and the hub. */
  --rubber: #0b0c0e;
  --rubber-sheen: #1c1e22;
  --rubber-edge: #08090a;
  --tread-lit: #5a606a;
  --tread-shade: #191b1f;
  --wheel-cover: #1e2126;
  --wheel-line: #2c3036;
  --wheel-bolt: #3a3e45;
  --rim-lit: #9aa1ab;
  --rim-shade: #464b53;
  --hub: #a9afb8;
  --hub-nut: #2a2d32;

  --font: "Figtree", "Helvetica Neue", Arial, sans-serif;

  /* Six tiers, by how much a figure matters at a glance. */
  --fs-label: 0.8125rem;   /* 13 px: labels, the floor */
  --fs-context: 0.9375rem; /* 15 px: notes under headline figures */
  --fs-read: 1.0625rem;    /* 17 px: race control's words, titles */
  --fs-key: 1.1875rem;     /* 19 px: card figures */
  --fs-glance: 1.375rem;   /* 22 px: the clock, the fastest lap */
  --fs-state: 2.125rem;    /* 34 px: the flag and the lap */

  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;

  --r-card: 28px;
  --r-inset: 18px;
  --r-row: 10px;
  --r-pill: 999px;
  --pad: 1.25rem;
  --gutter: clamp(1rem, 2.4vw, 1.75rem);
  --top-h: 5.25rem;
  --dock-h: 4.75rem;
  --tower-w: 31.5rem;

  /* The running order's two slot sizes, stepped by the window's height (below). P1-P10 are
     the points places and get the larger slot. */
  --row-big: 26px;
  --row-small: 21px;
  --fs-row-big: 1.125rem;
  --fs-row-small: 0.9375rem;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --move-ms: 520ms;
}

/* The flag's colour, wherever the flag shows: the block, the word, the wash. */
:root[data-flag="GREEN"] { --flag: var(--flag-green); }
:root[data-flag="YELLOW"],
:root[data-flag="VSC"],
:root[data-flag="SAFETY_CAR"] { --flag: var(--flag-yellow); }
:root[data-flag="RED"] { --flag: var(--flag-red); }
:root[data-flag="CHEQUERED"] { --flag: var(--flag-chequered); }

:root[data-flag="YELLOW"] { --pulse: 1100ms; }
:root[data-flag="VSC"],
:root[data-flag="SAFETY_CAR"] { --pulse: 1600ms; }
:root[data-flag="RED"] { --pulse: 3400ms; }

@media (min-height: 745px) {
  :root {
    --row-big: 30px;
    --row-small: 24px;
    --fs-row-big: 1.25rem;
    --fs-row-small: 1.0625rem;
  }
}

@media (min-height: 860px) {
  :root {
    --row-big: 34px;
    --row-small: 28px;
    --fs-row-big: 1.375rem;
    --fs-row-small: 1.125rem;
  }
}

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

[hidden] {
  display: none !important;
}

html {
  height: 100%;
  background: var(--ground);
  -webkit-text-size-adjust: 100%;
}

body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
}

p {
  margin: 0;
}

button {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* ---------- Building blocks ---------- */

.card {
  padding: var(--pad);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  box-shadow: var(--lift);
}

.card-title {
  font-size: var(--fs-read);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.card-note {
  font-size: var(--fs-context);
  line-height: 1.55;
  color: var(--ink-soft);
}

.card-title + .card-note {
  margin-top: var(--s-2);
}

/* Chips: every other button. Pressed is inverted. */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  height: 2rem;
  padding: 0 0.875rem;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-pill);
  background: transparent;
  font-size: var(--fs-label);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease;
}

.chip:hover {
  border-color: var(--ink-soft);
  background: var(--hover);
}

.chip[aria-pressed="true"] {
  border-color: var(--selected);
  background: var(--selected);
  color: var(--on-selected);
}

/* Tags: pills that only say something. */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 1.5rem;
  padding: 0 0.625rem;
  border-radius: var(--r-pill);
  background: var(--hover);
  font-size: var(--fs-label);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink);
}

.tag::before {
  content: "";
  flex: none;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: currentColor;
}

.tag-rain::before {
  background: var(--rain);
}

/* Segmented switches. */
.seg {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card-solid);
  box-shadow: var(--lift);
}

.seg button {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  height: 2rem;
  padding: 0 1rem;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  font-size: var(--fs-label);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease;
}

.seg button:hover {
  color: var(--ink);
  background: var(--hover);
}

.seg button[aria-checked="true"] {
  background: var(--selected);
  color: var(--on-selected);
}

/* The round +. Turns to an x, inverted, while open. */
.more {
  position: relative;
  flex: none;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}

.more::before,
.more::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 1.5px;
  margin: -0.75px 0 0 -6px;
  border-radius: 1px;
  background: currentColor;
  transition: transform 220ms var(--ease);
}

.more::after {
  transform: rotate(90deg);
}

.more:hover {
  border-color: var(--ink-soft);
  background: var(--hover);
}

.more[aria-expanded="true"] {
  border-color: var(--selected);
  background: var(--selected);
  color: var(--on-selected);
}

.more[aria-expanded="true"]::before {
  transform: rotate(45deg);
}

.more[aria-expanded="true"]::after {
  transform: rotate(135deg);
}

/* What a + opens drops below its bar as a card of its own. It's read, not glanced at:
   body-size type and room around it. Opening, it eases out of the bar; closing, it eases
   back in, more slowly, so the eye follows it home (pitwall-ui.js marks it closing for
   --close-ms before hiding it). */
.top-more {
  --close-ms: 600;
  position: absolute;
  top: calc(100% + var(--s-3));
  right: 0;
  z-index: 20;
  width: min(25rem, calc(100vw - 2 * var(--gutter)));
  padding: var(--s-5) 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--r-inset);
  background: var(--card-solid);
  box-shadow: var(--lift);
  cursor: auto;
  text-align: left;
  white-space: normal;
  transition: opacity 320ms var(--ease), translate 320ms var(--ease);
}

.top-more[data-closing] {
  opacity: 0;
  translate: 0 -0.75rem;
  transition: opacity 600ms cubic-bezier(0.65, 0, 0.35, 1), translate 600ms cubic-bezier(0.65, 0, 0.35, 1);
}

@starting-style {
  .top-more {
    opacity: 0;
    translate: 0 -0.75rem;
  }
}

.panel-title {
  font-size: var(--fs-read);
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.panel-note {
  margin-top: var(--s-1);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--ink-soft);
}

.panel-foot {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-context);
}

/* The delay: steps either side of the figure, and a slider under it. */
.delay {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-4);
}

.step {
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--hover);
  font-size: var(--fs-context);
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 160ms ease;
}

.step:hover {
  background: var(--rule-strong);
}

.delay-value {
  flex: 1;
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.025em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.delay-range {
  display: block;
  width: 100%;
  margin: var(--s-4) 0 0;
  accent-color: var(--selected);
  cursor: pointer;
}

.panel-feed {
  min-height: 1.4rem;
  margin-top: var(--s-4);
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
  font-size: var(--fs-context);
  font-weight: 600;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.panel-feed:empty {
  display: none;
}

/* A setting: what it is and what it does, with its switch on the right. */
.setting {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-top: var(--s-4);
}

.setting-name {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
}

.setting .panel-note {
  font-size: var(--fs-context);
}

.setting .chip {
  min-width: 3.5rem;
}

/* A value that has gone stale says so, and fades, but never moves. */
[data-stale="true"] {
  opacity: 0.45;
}

/* ---------- The flag's wash ---------- */

/* The flag's colour washes down from the top of the window, as on the app: strongest at the
   very top, gone a little below the capsule. Urgent flags wash stronger, and a band along
   the top edge breathes at the flag's own cadence. It sits behind the cards, which are
   nearly opaque, so it colours the gaps and the edges and never the figures. */
.wash {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 0;
  height: 16rem;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--flag) 25%, transparent) 0,
    color-mix(in srgb, var(--flag) 15%, transparent) 2.125rem,
    color-mix(in srgb, var(--flag) 8%, transparent) 9rem,
    transparent 100%
  );
  transition: opacity 600ms var(--ease);
}

:root[data-flag] .wash {
  opacity: 1;
}

:root:is([data-flag="YELLOW"], [data-flag="VSC"], [data-flag="SAFETY_CAR"], [data-flag="RED"]) .wash {
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--flag) 46%, transparent) 0,
    color-mix(in srgb, var(--flag) 28%, transparent) 2.125rem,
    color-mix(in srgb, var(--flag) 14%, transparent) 9rem,
    transparent 100%
  );
}

.beacon {
  height: 3.5rem;
  opacity: 0;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--flag) 42%, transparent) 0,
    color-mix(in srgb, var(--flag) 16%, transparent) 55%,
    transparent 100%
  );
}

:root:is([data-flag="YELLOW"], [data-flag="VSC"], [data-flag="SAFETY_CAR"], [data-flag="RED"]) .beacon {
  animation: beacon var(--pulse) cubic-bezier(0.4, 0, 0.2, 1) infinite alternate;
}

@keyframes beacon {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---------- The frame ---------- */

/* The running order down the right, full height; everything else in the column beside it:
   the byline and switches, the capsule, race control's line, and the stage. */
.wall {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--tower-w);
  column-gap: var(--s-4);
  height: 100vh;
  height: 100dvh;
  padding: calc(var(--s-3) + env(safe-area-inset-top, 0px)) var(--gutter) var(--gutter);
}

.main {
  display: grid;
  grid-template-rows: auto var(--top-h) auto minmax(0, 1fr) var(--dock-h);
  row-gap: var(--s-3);
  min-width: 0;
  min-height: 0;
}

.topbar {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  min-width: 0;
  height: 2.625rem;
}

.brand {
  display: flex;
  flex: none;
  align-items: baseline;
  gap: var(--s-3);
}

.logo {
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  text-decoration: none;
  color: var(--logo-mid);
  background: linear-gradient(100deg, var(--logo-from) 0%, var(--logo-mid) 55%, var(--logo-to) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.brand-by {
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  color: var(--ink-soft);
  transition: color 160ms ease;
}

.brand-by b {
  font-weight: 600;
  color: var(--ink);
}

.brand-by:hover {
  color: var(--ink);
}

.session-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-size: var(--fs-read);
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.header-controls {
  position: relative;
  z-index: 3;
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--s-2);
}

/* ---------- The capsule ---------- */

/* The race's state in one pill: the flag, the lap, the fastest lap, and whether the wall
   is live. Small labels over large figures; hairlines between the parts. */
.capsule {
  position: relative;
  z-index: 2;
  display: grid;
  /* Flag, lap, fastest lap, badge. The flag never gives way; the badge does first. */
  grid-template-columns: minmax(max-content, 1fr) max-content max-content minmax(0, max-content);
  align-items: stretch;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--lift);
}

.cap {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  padding: 0 var(--s-5);
}

.cap + .cap::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.25rem;
  bottom: 1.25rem;
  width: 1px;
  background: var(--line);
}

.cap-label {
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1.3;
  color: var(--ink-soft);
}

.cap-sub {
  min-height: 1.1rem;
  font-size: var(--fs-label);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* The flag: its block, then its word over the note. */
.cap-flag {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-4);
  padding-left: 1.5rem;
}

/* Green is the normal state: a quiet dot. A local yellow is outlined; the neutralisations
   and the red flag are filled blocks, lettered where the flag is; the chequered flag is
   chequered. Before any flag, an empty ring. */
.flag-block {
  display: grid;
  place-items: center;
  flex: none;
  width: 3.25rem;
  height: 2.5rem;
  border: 2px solid var(--rule-strong);
  border-radius: 12px;
}

:root[data-flag="GREEN"] .flag-block {
  width: 1rem;
  height: 1rem;
  margin: 0 1.125rem;
  border: 0;
  border-radius: 50%;
  background: var(--flag);
}

:root[data-flag="YELLOW"] .flag-block {
  border: 3px solid var(--flag);
}

:root:is([data-flag="VSC"], [data-flag="SAFETY_CAR"], [data-flag="RED"]) .flag-block {
  border: 0;
  background: var(--flag);
}

:root[data-flag="CHEQUERED"] .flag-block {
  border: 1px solid var(--flag);
  background: repeating-conic-gradient(var(--flag) 0 25%, var(--ground) 0 50%) 0 0 / 0.8125rem 0.8125rem;
}

.flag-mark {
  font-size: var(--fs-context);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--on-selected);
}

.flag-text {
  min-width: 0;
}

.flag-word {
  overflow: hidden;
  font-size: var(--fs-state);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.025em;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink);
}

:root[data-flag] .flag-word {
  color: var(--flag);
}

/* The note takes whatever width the word leaves it, and no more: it never widens the
   flag's column, and a long one ends in an ellipsis. */
.flag-note {
  contain: inline-size;
  overflow: hidden;
  min-height: 1.3rem;
  font-size: var(--fs-context);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink-soft);
}

/* The lap: the one figure the race is counted in. */
.lap-value {
  font-size: var(--fs-state);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.lap-of {
  font-size: 0.53em;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink-soft);
}

.cap-sub.is-final {
  color: var(--ink);
}

.fastest-value {
  font-size: var(--fs-glance);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fastest-time {
  color: var(--timing-best);
}

.fastest-who {
  font-size: var(--fs-read);
  color: var(--team, var(--ink));
}

/* Whether the wall is live: the state as a tag, then the frame's own clock and the delay. */
.cap-badge {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-3);
  padding-right: 1.25rem;
}

.cap-badge > .more {
  margin-left: var(--s-2);
}

.tag-state {
  height: 1.75rem;
  padding: 0 0.75rem;
  background: var(--selected);
  color: var(--on-selected);
}

.tag-state::before {
  display: none;
}

.cap-badge[data-tone="warn"] .tag-state {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--caution);
  color: var(--caution);
}

.cap-badge[data-tone="quiet"] .tag-state,
.cap-badge[data-tone="demo"] .tag-state {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--rule-strong);
  color: var(--ink-soft);
}

.badge-clock {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.badge-clock > * {
  overflow: hidden;
  text-overflow: ellipsis;
}

.badge-clock b {
  font-size: var(--fs-glance);
  font-weight: 700;
  letter-spacing: -0.015em;
}

.badge-delay {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

/* ---------- Race control's line ---------- */

/* The newest message from race control, at reading size, as one inset line. */
.ticker {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  min-width: 0;
  padding: 0.5625rem var(--s-5);
  border-radius: var(--r-pill);
  background: var(--inset);
  font-size: var(--fs-read);
  line-height: 1.45;
}

.ticker-when {
  flex: none;
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.ticker-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ticker[data-empty] .ticker-text {
  color: var(--ink-soft);
}

/* It's a button: it opens the feed at that message. */
.ticker {
  width: 100%;
  border: 0;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 600ms var(--ease), box-shadow 600ms var(--ease);
}

.ticker:hover {
  background: var(--hover);
}

/* A message worth interrupting for lights the line for a few seconds, in the shade of its
   kind, with one pulse: colour and motion, never a change of size. */
.ticker[data-tone] {
  background: color-mix(in srgb, var(--tone) 22%, var(--card-solid));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tone) 55%, transparent);
  animation: ticker-in 900ms var(--ease) 1;
}

.ticker[data-tone="alert"] { --tone: var(--alert-soft); }
.ticker[data-tone="caution"] { --tone: var(--caution); }
.ticker[data-tone="good"] { --tone: var(--timing-personal); }
.ticker[data-tone="rain"] { --tone: var(--rain); }
.ticker[data-tone="plain"] { --tone: var(--ink-soft); }

@keyframes ticker-in {
  from { box-shadow: inset 0 0 0 3px var(--tone); }
}

.ticker-kind {
  flex: none;
  padding: 0.1rem 0.55rem;
  border-radius: var(--r-pill);
  background: var(--tone, var(--hover));
  font-size: var(--fs-label);
  font-weight: 700;
  color: var(--on-selected);
}

/* How many messages arrived while the feed was closed. */
.unread {
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.35rem;
  border-radius: var(--r-pill);
  background: var(--alert-fill);
  font-size: var(--fs-label);
  font-weight: 700;
  line-height: 1.25rem;
  text-align: center;
  color: var(--ink);
}

/* ---------- The feed ---------- */

.feed {
  position: absolute;
  inset: 0;
  display: none;
  grid-template-columns: minmax(0, 1.4fr) minmax(19rem, 1fr);
  gap: var(--s-3);
}

:root[data-view="feed"] .feed {
  display: grid;
}

.feed-rc {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: var(--s-4) var(--s-3) var(--s-3) var(--s-5);
  background: var(--card-solid);
}

.rc-list,
.clip-list {
  margin: var(--s-3) 0 0;
  padding: 0;
  list-style: none;
}

.rc-list {
  min-height: 0;
  padding-right: var(--s-2);
  overflow-y: auto;
}

.rc-row {
  --tone: var(--ink-faint);
  padding: var(--s-3) var(--s-4);
  border-radius: 14px;
  border-left: 3px solid var(--tone);
  background: var(--inset);
  transition: background-color 900ms var(--ease);
}

.rc-row + .rc-row {
  margin-top: var(--s-2);
}

.rc-row[data-tone="alert"] { --tone: var(--alert-soft); }
.rc-row[data-tone="caution"] { --tone: var(--caution); }
.rc-row[data-tone="good"] { --tone: var(--timing-personal); }
.rc-row[data-tone="rain"] { --tone: var(--rain); }

.rc-row[data-tone] {
  background: color-mix(in srgb, var(--tone) 12%, var(--card-solid));
}

.rc-row[data-lit] {
  background: color-mix(in srgb, var(--tone) 34%, var(--card-solid));
  transition-duration: 250ms;
}

.rc-when {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.rc-kind {
  color: var(--tone);
  font-weight: 700;
}

.rc-driver {
  padding: 0 0.4rem;
  border: 1px solid var(--team, var(--rule-strong));
  border-radius: 6px;
  font-weight: 700;
  color: var(--team, var(--ink));
}

.rc-text {
  margin-top: var(--s-1);
  font-size: var(--fs-read);
  line-height: 1.45;
}

.rc-empty {
  padding: var(--s-3) 0;
  font-size: var(--fs-context);
  color: var(--ink-soft);
}

.feed-side {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  min-height: 0;
  overflow-y: auto;
}

.cond,
.radio {
  padding: var(--s-4) var(--s-5);
  background: var(--card-solid);
}

.cond-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}

/* The track temperature large, with which way it has moved. */
.cond-track {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  font-variant-numeric: tabular-nums;
}

.cond-track b {
  font-size: 3rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.cond-track span {
  font-size: var(--fs-context);
  font-weight: 700;
}

.cond-track span[data-tone="warm"] { color: var(--caution); }
.cond-track span[data-tone="cool"] { color: var(--rain); }
.cond-track span[data-tone="quiet"] { color: var(--ink-soft); }

.cond-spark {
  display: block;
  width: 100%;
  height: 3rem;
  margin: var(--s-2) 0 var(--s-3);
}

.cond-tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-2);
  margin: 0;
}

.cond-tiles div {
  padding: var(--s-2) var(--s-3);
  border-radius: 12px;
  background: var(--inset);
}

.cond-tiles dt {
  overflow: hidden;
  font-size: var(--fs-label);
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink-soft);
}

.cond-tiles dd {
  margin: 0;
  font-size: var(--fs-key);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Rain: the whole card turns to it. */
.cond[data-rain] {
  border-color: color-mix(in srgb, var(--rain) 50%, transparent);
  background: color-mix(in srgb, var(--rain) 22%, var(--card-solid));
}

.tag-weather::before {
  background: var(--caution);
}

.cond[data-rain] .tag-weather::before {
  background: var(--rain);
}

.clip-list li + li {
  margin-top: var(--s-1);
}

.clip {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-2) var(--s-3);
  border: 0;
  border-radius: 12px;
  background: var(--inset);
  text-align: left;
  cursor: pointer;
  transition: background-color 160ms ease;
}

.clip:hover {
  background: var(--hover);
}

.clip[aria-pressed="true"] {
  background: var(--selected);
  color: var(--on-selected);
}

.clip-icon {
  width: 1rem;
  font-size: var(--fs-label);
}

.clip b {
  font-size: var(--fs-read);
  font-weight: 700;
  color: var(--team, inherit);
}

.clip[aria-pressed="true"] b {
  color: inherit;
}

.clip-when {
  margin-left: auto;
  font-size: var(--fs-label);
  font-weight: 600;
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

/* The voice's settings. */
.voice-kinds {
  margin-top: var(--s-3);
}

.voice-row {
  display: flex;
  gap: var(--s-2);
  margin-top: var(--s-3);
}

.voice-row select {
  flex: 1;
  min-width: 0;
  height: 2rem;
  padding: 0 var(--s-3);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-pill);
  background: var(--card-solid);
  font: inherit;
  font-size: var(--fs-label);
  color: var(--ink);
}

#settings-panel {
  max-height: calc(100vh - 7rem);
  overflow-y: auto;
}

@media (max-width: 1240px) {
  .feed {
    grid-template-columns: minmax(0, 1fr) minmax(16rem, 0.9fr);
  }
}

/* ---------- The stage ---------- */

.stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
  margin: 0;
}

.stage-note {
  max-width: 26rem;
}

/* ---------- The Wall ---------- */

/* The ring takes the whole stage; being round, it leaves the corners free, and its cards sit
   there: what a stop does and what it costs on the left, who can stop for free and the
   ring's own switches on the right. */
.ring {
  position: absolute;
  inset: 0;
  display: none;
}

:root[data-view="wall"] .ring {
  display: block;
}

.ring-side {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s-3);
  width: 15rem;
  min-height: 0;
  pointer-events: none;
}

.ring-side > * {
  pointer-events: auto;
}

.ring-side:first-child {
  left: 0;
}

.ring-side:last-of-type {
  right: 0;
}

.ring-card {
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-inset);
  background: var(--card-solid);
}

.ring-card .cap-label {
  margin-bottom: var(--s-2);
}

.ring-hint {
  font-size: var(--fs-context);
  line-height: 1.45;
  color: var(--ink-soft);
}

.ring-hint:empty {
  display: none;
}

.pit-move {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  margin-bottom: var(--s-1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pit-move span {
  font-size: var(--fs-context);
  font-weight: 600;
  color: var(--ink-soft);
}

.pit-move b {
  font-size: var(--fs-state);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--team, var(--ink));
}

/* One verdict: caution amber, good-news green, or quiet. */
.verdict {
  margin-bottom: var(--s-1);
  font-size: var(--fs-read);
  font-weight: 700;
}

.verdict[data-tone="caution"] {
  color: var(--caution);
}

.verdict[data-tone="good"] {
  color: var(--timing-personal);
}

.verdict[data-tone="quiet"] {
  color: var(--ink-soft);
}

.loss-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-1);
  margin-bottom: var(--s-2);
}

.loss-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--s-1) 0;
  border-radius: 12px;
  background: var(--inset);
  font-variant-numeric: tabular-nums;
}

.loss-tile span {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

.loss-tile b {
  font-size: var(--fs-key);
  font-weight: 700;
}

/* The flag that's out now: inverted, like any selected state. */
.loss-tile[aria-current="true"] {
  background: var(--selected);
  color: var(--on-selected);
}

.loss-tile[aria-current="true"] span {
  color: inherit;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

.chips + .ring-hint {
  margin-top: var(--s-3);
}

.chip-driver {
  font-size: var(--fs-context);
  font-weight: 700;
  color: var(--team, var(--ink));
}

.chip-driver[aria-pressed="true"] {
  color: var(--on-selected);
}

.ring-stage {
  position: absolute;
  inset: 0;
}

.ring-stage canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: pointer;
}

/* ‹ and › step to the car ahead or behind, for cars a tenth apart that even a dial can't
   split. */
.ring-step {
  font-size: var(--fs-read);
  font-weight: 700;
}

/* The stints: over the ring, every car's tyres by lap. */
.stints {
  position: absolute;
  inset: var(--s-4) 18rem;
  z-index: 5;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--card-solid);
}

.stints-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--s-3);
}

.stint-list {
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.stint-list li {
  display: grid;
  grid-template-columns: 1.6rem 3rem minmax(0, 1fr) 2.5rem;
  align-items: center;
  gap: var(--s-2);
  padding: 0.3125rem var(--s-2);
  border-radius: 10px;
  font-size: var(--fs-context);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.stint-list li:hover {
  background: var(--hover);
}

.stint-list li[aria-current="true"] {
  box-shadow: inset 0 0 0 2px var(--selected);
}

.stint-list b {
  text-align: right;
}

.stint-list span {
  font-weight: 700;
  color: var(--team, var(--ink));
}

.stint-list em {
  font-size: var(--fs-label);
  font-style: normal;
  font-weight: 700;
  color: var(--timing-personal);
}

.stint-bar {
  position: relative;
  height: 0.75rem;
  border-radius: 6px;
  background: var(--inset);
}

.stint-bar i {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 6px;
  background: var(--tyre, var(--ink-faint));
}

.stint-bar i[data-tyre="soft"] { --tyre: var(--tyre-soft); }
.stint-bar i[data-tyre="medium"] { --tyre: var(--tyre-medium); }
.stint-bar i[data-tyre="hard"] { --tyre: var(--tyre-hard); }
.stint-bar i[data-tyre="inter"] { --tyre: var(--tyre-inter); }
.stint-bar i[data-tyre="wet"] { --tyre: var(--tyre-wet); }

/* Too narrow for cards in the corners: the ring above, its cards in two columns under it. */
@media (max-width: 1240px) {
  :root[data-view="wall"] .ring {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    gap: var(--s-3);
  }

  .ring-stage {
    position: relative;
    grid-column: 1 / -1;
    grid-row: 1;
  }

  .ring-side {
    position: static;
    grid-row: 2;
    justify-content: flex-start;
    width: auto;
  }

  .stints {
    inset: var(--s-4);
  }
}

/* ---------- Signing in ---------- */

/* A card in the middle of the page, nothing of the wall behind it until it opens or the
   replays are picked instead. */
:root[data-locked] .wall,
:root[data-locked] .wash,
:root[data-locked] .backdrop,
:root[data-locked] .tag-demo {
  visibility: hidden;
}

.gate {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  overflow-y: auto;
  background: var(--ground);
}

.gate-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  width: min(22rem, 100%);
  padding: var(--s-6) 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card-solid);
  box-shadow: var(--lift);
}

.gate-word {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--logo-mid);
  background: linear-gradient(100deg, var(--logo-from) 0%, var(--logo-mid) 55%, var(--logo-to) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.gate-lede {
  margin-top: calc(-1 * var(--s-3));
  font-size: var(--fs-context);
  color: var(--ink-soft);
}

.gate-field {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

.gate-field input {
  height: 2.75rem;
  padding: 0 var(--s-4);
  border: 1px solid var(--rule-strong);
  border-radius: 14px;
  background: var(--inset);
  font: inherit;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
}

.gate-field input:focus-visible {
  border-color: var(--ink-soft);
}

/* The page's one selected state: ink fill, ground text. */
.gate-go {
  height: 2.75rem;
  margin-top: var(--s-2);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--selected);
  font: inherit;
  font-size: var(--fs-context);
  font-weight: 700;
  color: var(--on-selected);
  cursor: pointer;
}

.gate-note {
  min-height: 1.3em;
  margin-top: calc(-1 * var(--s-2));
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--alert-soft);
}

.gate-replay {
  height: 2.75rem;
  margin-top: calc(-1 * var(--s-2));
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-pill);
  background: none;
  font: inherit;
  font-size: var(--fs-context);
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.gate-replay:hover {
  background: var(--inset);
}

/* ---------- The intro ---------- */

/* The first seconds of a visit: the wordmark, and the five compounds popping in, spinning
   up and rolling off to the right, while the wall loads underneath (pitwall-intro.js). */
.intro {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.875rem;
  background: var(--ground);
  cursor: pointer;
}

.intro-word {
  font-size: 2.75rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--logo-mid);
  background: linear-gradient(100deg, var(--logo-from) 0%, var(--logo-mid) 55%, var(--logo-to) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  opacity: 0;
}

.intro canvas {
  display: block;
  width: 100%;
}

/* ---------- Between sessions ---------- */

/* The next venue's photograph behind the whole page, at nearly full strength: darkened
   under the header and across the foot, where the poster sits, and clear through the
   middle for the place itself. Fades in once it has loaded rather than drawing down. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: none;
  background-color: var(--ground);
  background-repeat: no-repeat;
  background-size: cover;
  opacity: 0;
  pointer-events: none;
  transition: opacity 900ms var(--ease);
}

.backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, color-mix(in srgb, var(--ground) 45%, transparent) 0, transparent 55%),
    linear-gradient(
      to bottom,
      color-mix(in srgb, var(--ground) 92%, transparent) 0,
      color-mix(in srgb, var(--ground) 40%, transparent) 16%,
      color-mix(in srgb, var(--ground) 8%, transparent) 30%,
      color-mix(in srgb, var(--ground) 18%, transparent) 40%,
      color-mix(in srgb, var(--ground) 62%, transparent) 54%,
      color-mix(in srgb, var(--ground) 84%, transparent) 70%,
      color-mix(in srgb, var(--ground) 96%, transparent) 100%
    );
}

:root[data-standby] .backdrop {
  display: block;
}

:root[data-standby] .backdrop[data-loaded] {
  opacity: 0.85;
}

/* Nothing on track: no running order, race control or timeline, only the poster. */
:root[data-standby] .wall {
  grid-template-columns: minmax(0, 1fr);
}

:root[data-standby] .main {
  grid-template-rows: auto var(--top-h) minmax(0, 1fr);
}

:root[data-standby] .capsule {
  grid-template-columns: minmax(max-content, 1fr) minmax(0, max-content);
}

:root[data-standby] .tower,
:root[data-standby] .ticker,
:root[data-standby] .dock,
:root[data-standby] .cap-lap,
:root[data-standby] .cap-fastest,
:root[data-standby] .flag-block,
:root[data-standby] .flag-note:empty,
:root[data-standby] .stage > :not(.standby) {
  display: none;
}

/* On a laptop, the capsule comes apart: "Standby" on the left and the badge on the right,
   each its own pill, with the photograph between them. */
@media (min-width: 901px) {
  :root[data-standby] .capsule {
    grid-template-columns: max-content minmax(0, 1fr) max-content;
    border: 0;
    background: none;
    box-shadow: none;
  }

  :root[data-standby] .cap-flag,
  :root[data-standby] .cap-badge {
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--card);
    box-shadow: var(--lift);
  }

  :root[data-standby] .cap-flag {
    padding: 0 var(--s-6);
  }

  :root[data-standby] .cap-badge {
    grid-column: 3;
    padding-left: var(--s-4);
  }

  :root[data-standby] .cap-badge::before {
    display: none;
  }
}

.standby {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-5);
  padding: 0 var(--s-2) var(--s-2);
}

/* Text straight on the photograph, with a soft shadow so a bright patch can't swallow it. */
.poster {
  min-width: 0;
  max-width: 48rem;
  text-shadow: 0 2px 12px var(--shadow);
}

.poster-when {
  font-size: var(--fs-read);
  font-weight: 600;
}

.poster-event {
  margin: var(--s-1) 0 0;
  font-size: clamp(2.25rem, 4.2vw, 3.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.poster-place {
  margin-top: var(--s-1);
  font-size: var(--fs-glance);
  font-weight: 600;
}

/* The countdown, biggest of all: each pair of digits over its unit, amber in the last hour. */
.countdown {
  margin-top: var(--s-5);
  font-variant-numeric: tabular-nums;
}

.countdown-days {
  font-size: var(--fs-state);
  font-weight: 700;
  line-height: 1.1;
}

.countdown-clock {
  display: flex;
  align-items: flex-start;
}

.countdown-clock[hidden] {
  display: none;
}

.countdown-unit {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.countdown-unit b,
.countdown-sep,
.countdown-now {
  font-size: 4.5rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.countdown-sep {
  padding: 0 0.08em;
  opacity: 0.6;
}

.countdown-unit span {
  margin-top: var(--s-1);
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

.countdown-now {
  font-size: 3rem;
}

.countdown[data-soon] .countdown-days,
.countdown[data-soon] .countdown-unit b,
.countdown[data-soon] .countdown-sep,
.countdown[data-soon] .countdown-now {
  color: var(--caution);
}

/* The weekend as a row of chips, like a calendar's: the day, the session, then a tick once
   it has run or its start time. The next one is inverted, the page's one selected state. */
.weekend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: var(--s-5) 0 0;
  padding: 0;
  list-style: none;
}

.weekend-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 5.5rem;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card);
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
  text-shadow: none;
}

.weekend-chip span {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

.weekend-chip b {
  font-size: var(--fs-context);
  font-weight: 700;
}

.weekend-chip[data-state="done"] b,
.weekend-chip[data-state="done"] span {
  color: var(--ink-faint);
}

.weekend-chip[data-state="next"] {
  border-color: var(--selected);
  background: var(--selected);
  color: var(--on-selected);
}

.weekend-chip[data-state="next"] span {
  color: var(--on-selected);
}

.poster-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-5);
}

.chip-poster {
  height: 2.5rem;
  padding: 0 1.125rem;
  background: var(--card);
  font-size: var(--fs-context);
  text-shadow: none;
}

.poster-note {
  min-height: 1.3em;
  margin-top: var(--s-2);
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--ink-soft);
}

/* What the photograph is and whose: the credit its licence asks for, linked to its page. */
.poster-credit {
  flex-shrink: 1;
  max-width: 22rem;
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1.4;
  text-align: right;
  color: var(--ink-faint);
  text-decoration: none;
}

.poster-credit:hover,
.poster-credit:focus-visible {
  color: var(--ink-soft);
  text-decoration: underline;
}

/* ---------- One car in full ---------- */

/* Over the stage's right edge, next to the tower: the car's code in its team colour on a
   shade of it, then its telemetry, figures, sectors and tyres as inset tiles. */
.driver {
  position: absolute;
  top: var(--s-3);
  right: var(--s-3);
  bottom: var(--s-3);
  z-index: 8;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  width: min(24rem, calc(100% - 2 * var(--s-3)));
  padding: var(--s-3);
  overflow-y: auto;
  background: var(--card-solid);
}

.driver-close {
  position: absolute;
  top: var(--s-4);
  right: var(--s-4);
  z-index: 1;
}

.driver-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) 3.5rem var(--s-3) var(--s-4);
  border-radius: var(--r-inset);
  background: color-mix(in srgb, var(--team) 22%, var(--card-solid));
}

.driver-code {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--team);
}

.driver-name {
  margin-top: var(--s-1);
  font-size: var(--fs-context);
  font-weight: 600;
  color: var(--ink);
}

.driver-pos {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-variant-numeric: tabular-nums;
}

.driver-pos b {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1;
}

.driver-note {
  padding: 0 var(--s-2);
  font-size: var(--fs-context);
  font-weight: 700;
  color: var(--alert-soft);
}

.tile {
  padding: var(--s-3) var(--s-4);
  border-radius: 14px;
  background: var(--inset);
}

.driver-figs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-2);
}

.fig {
  padding: var(--s-2) var(--s-3);
  border-radius: 14px;
  background: var(--inset);
}

.fig-value {
  font-size: var(--fs-glance);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.driver-sectors {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-2);
  margin-top: var(--s-2);
}

.driver-sectors i {
  display: block;
  height: 0.3125rem;
  border-radius: 3px;
  background: var(--ink);
}

.driver-sectors b {
  display: block;
  margin-top: var(--s-1);
  font-size: var(--fs-read);
  font-variant-numeric: tabular-nums;
}

.driver-sectors .is-none i {
  background: var(--rule-strong);
}

.driver-sectors .is-none b {
  color: var(--ink-faint);
}

.driver-sectors .is-best i { background: var(--timing-best); }
.driver-sectors .is-best b { color: var(--timing-best); }
.driver-sectors .is-personal i { background: var(--timing-personal); }
.driver-sectors .is-personal b { color: var(--timing-personal); }

.driver-tyre {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-read);
}

.driver-tyre .tyre-ring {
  font-size: 1.05rem;
}

.driver .stint-bar {
  margin: var(--s-3) 0 var(--s-1);
}

.driver .ring-hint {
  margin-top: var(--s-1);
}

/* Live telemetry, straight under the name: speed and gear large, throttle and brake as bars,
   the revs thin. */
.telemetry[data-none] .tel-read,
.telemetry[data-none] .tel-bars,
.telemetry:not([data-none]) .tel-none {
  display: none;
}

.tel-none {
  margin-top: var(--s-1);
  font-size: var(--fs-context);
  color: var(--ink-soft);
}

.tel-read {
  display: flex;
  justify-content: space-between;
  margin: var(--s-1) 0 var(--s-2);
}

.tel-big {
  display: flex;
  align-items: baseline;
  gap: var(--s-1);
  font-variant-numeric: tabular-nums;
}

.tel-big b {
  font-size: 2.75rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.tel-big span {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

.tel-bars {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  align-items: center;
  gap: var(--s-2) var(--s-3);
}

.tel-bars p {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.tel-bar {
  height: 0.875rem;
  overflow: hidden;
  border-radius: var(--r-pill);
  background: var(--inset);
}

.tel-thin {
  height: 0.375rem;
}

/* Eased between samples, so four a second read as motion. */
.tel-bar i {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--ink-soft);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 180ms linear;
}

.tel-bar i[data-tone="good"] { background: var(--timing-personal); }
.tel-bar i[data-tone="alert"] { background: var(--alert-soft); }

.driver-top,
.driver-body {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

/* Kept in reach at the foot while the card scrolls. */
.driver-actions {
  position: sticky;
  bottom: calc(-1 * var(--s-3));
  display: flex;
  gap: var(--s-2);
  margin: auto calc(-1 * var(--s-3)) calc(-1 * var(--s-3));
  padding: var(--s-2) var(--s-3) var(--s-3);
  background: var(--card-solid);
}

.driver-actions .chip {
  flex: 1;
}

/* ---------- The map ---------- */

/* The map fills the stage: borderless canvases in a rounded frame, with its few controls
   floating over the corners as small cards. */
.map {
  position: absolute;
  inset: 0;
  display: none;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--ground);
  touch-action: none;
  cursor: grab;
}

:root[data-view="map"] .map {
  display: block;
}

.map:active {
  cursor: grabbing;
}

.map:focus-visible {
  outline-offset: -2px;
}

.map canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.map-notice {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--s-6);
  font-size: var(--fs-context);
  font-weight: 600;
  text-align: center;
  color: var(--ink-soft);
}

/* The wind: an arrow turned with the map, the speed, and where it blows from. */
.map-wind {
  position: absolute;
  top: var(--s-3);
  right: var(--s-3);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) var(--s-4) var(--s-2) var(--s-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--lift);
  pointer-events: none;
}

.map-wind svg {
  flex: none;
  width: 2rem;
  height: 2rem;
  padding: 0.3rem;
  border-radius: 50%;
  background: var(--hover);
  color: var(--ink);
  transition: transform 600ms var(--ease);
}

.map-wind p {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  font-variant-numeric: tabular-nums;
}

.map-wind b {
  font-size: var(--fs-context);
  font-weight: 700;
}

.map-wind span {
  font-size: var(--fs-label);
  font-weight: 600;
  color: var(--ink-soft);
}

.map-whole,
.map-follow {
  position: absolute;
  background: var(--card);
  box-shadow: var(--lift);
}

.map-whole {
  top: var(--s-3);
  left: var(--s-3);
}

.map-follow {
  bottom: var(--s-3);
  left: var(--s-3);
}

.map-follow::before {
  content: "";
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--team, currentColor);
}

/* Following someone: inverted, like any selected control, with their team's dot. */
.map-follow[aria-pressed="true"] {
  border-color: var(--selected);
  background: var(--selected);
  color: var(--on-selected);
}

.map-note {
  position: absolute;
  bottom: var(--s-4);
  left: 50%;
  max-width: calc(100% - 22rem);
  transform: translateX(-50%);
  font-size: var(--fs-label);
  font-weight: 600;
  text-align: center;
  color: var(--ink-soft);
  pointer-events: none;
}

.map-credit {
  position: absolute;
  right: var(--s-4);
  bottom: var(--s-2);
  font-size: var(--fs-label);
  color: var(--ink-faint);
  pointer-events: none;
}

:root[data-view="map"] .stage-note:not([data-for="map"]),
:root[data-view="wall"] .stage-note:not([data-for="wall"]),
:root[data-view="feed"] .stage-note:not([data-for="feed"]) {
  display: none;
}

/* ---------- The dock ---------- */

/* A capsule along the foot of the stage: the session as a track. In replay, play, the
   track as a slider, the speed, the way back to live and a + for the jumps; live, the
   track is the session so far and the rest stand aside. */
.dock {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
  padding: var(--s-2) var(--s-4) var(--s-2) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--lift);
}

.dock[data-mode="live"] {
  padding-left: 1.75rem;
}

.dock[data-mode="live"] :is(.tl-play, .tl-speed, .dock-more-btn) {
  display: none;
}

.tl-play {
  display: grid;
  flex: none;
  place-items: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--selected);
  color: var(--on-selected);
  cursor: pointer;
  transition: transform 160ms ease, opacity 160ms ease;
}

.tl-play:hover:not([disabled]) {
  transform: scale(1.05);
}

.tl-play[disabled] {
  cursor: default;
  opacity: 0.35;
}

.tl-play svg {
  display: block;
  width: 0.875rem;
  height: 0.875rem;
}

.tl-track {
  position: relative;
  flex: 1;
  align-self: stretch;
  min-width: 0;
  cursor: pointer;
  touch-action: none;
}

.dock[data-mode="live"] .tl-track {
  cursor: default;
}

.tl-track:focus-visible {
  outline-offset: 4px;
  border-radius: var(--r-inset);
}

.tl-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* The thumb: an ink rule at the moment on screen, its time in a pill above. */
.tl-thumb {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  pointer-events: none;
}

.tl-thumb::after {
  content: "";
  position: absolute;
  top: 1.5rem;
  bottom: 0.25rem;
  left: -1px;
  width: 2px;
  border-radius: 1px;
  background: var(--selected);
}

.tl-thumb-label {
  position: absolute;
  top: 0;
  left: 0;
  height: 1.375rem;
  padding: 0 0.55rem;
  border-radius: var(--r-pill);
  background: var(--selected);
  font-size: var(--fs-label);
  font-weight: 600;
  line-height: 1.375rem;
  white-space: nowrap;
  color: var(--on-selected);
  font-variant-numeric: tabular-nums;
}

.tl-note {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  font-size: var(--fs-context);
  font-weight: 600;
  color: var(--ink-soft);
}

.tl-note:empty {
  display: none;
}

.tl-speed {
  min-width: 3.5rem;
  font-variant-numeric: tabular-nums;
}

/* Live: a quiet status while the wall is live, an inverted button to come back to it from
   a replay. The width never changes, so the track doesn't jump. */
.tl-live {
  min-width: 4.75rem;
  border-color: var(--selected);
  background: var(--selected);
  color: var(--on-selected);
}

.tl-live::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: currentColor;
}

.tl-live:hover {
  border-color: var(--selected);
  background: var(--selected);
  opacity: 0.9;
}

.tl-live[aria-disabled="true"] {
  border-color: var(--rule-strong);
  background: transparent;
  color: var(--ink-soft);
  cursor: default;
  opacity: 1;
}

/* What the dock's + opens rises above it, as a card of its own. */
.dock-more {
  --close-ms: 600;
  position: absolute;
  bottom: calc(100% + var(--s-3));
  right: 0;
  z-index: 20;
  width: min(25rem, calc(100vw - 2 * var(--gutter)));
  padding: var(--s-5) 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--r-inset);
  background: var(--card-solid);
  box-shadow: var(--lift);
  transition: opacity 320ms var(--ease), translate 320ms var(--ease);
}

.dock-more[data-closing] {
  opacity: 0;
  translate: 0 0.75rem;
  transition: opacity 600ms cubic-bezier(0.65, 0, 0.35, 1), translate 600ms cubic-bezier(0.65, 0, 0.35, 1);
}

@starting-style {
  .dock-more {
    opacity: 0;
    translate: 0 0.75rem;
  }
}

.panel-gap {
  margin-top: var(--s-5);
}

.jumps,
.nudges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-3);
}

/* A jump carries its flag's colour as a dot, never as the word's colour. */
.chip-jump::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--flag-yellow);
}

.chip-jump[data-flag-state="RED"]::before {
  background: var(--flag-red);
}

.chip-jump[data-flag-state="CHEQUERED"]::before {
  background: var(--flag-chequered);
}

/* ---------- Live or replay ---------- */

.seg-mode {
  display: flex;
  margin-bottom: var(--s-4);
  box-shadow: none;
}

.seg-mode button {
  flex: 1;
  justify-content: center;
}

:root:not([data-mode="replay"]) .mode-replay,
:root[data-mode="replay"] .mode-live {
  display: none;
}

.seg-years {
  margin: var(--s-3) 0 var(--s-3);
  box-shadow: none;
}

/* The sessions to replay, a weekend at a time, newest first. */
.picker {
  max-height: min(26rem, 55vh);
  margin: 0 -0.5rem;
  padding: 0 0.5rem;
  overflow-y: auto;
}

.picker-weekend + .picker-weekend {
  margin-top: var(--s-4);
}

.picker-weekend .cap-label {
  margin: 0 0 var(--s-2) var(--s-1);
}

.picker-list {
  overflow: hidden;
  border-radius: var(--r-inset);
  background: var(--inset);
}

.picker-session {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  width: 100%;
  padding: 0.6875rem var(--s-4);
  border: 0;
  background: transparent;
  font-size: 1rem;
  font-weight: 600;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 160ms ease;
}

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

.picker-session:hover {
  background: var(--hover);
}

.picker-session[aria-current="true"] {
  background: var(--selected);
  color: var(--on-selected);
}

.picker-session span {
  flex: none;
  font-size: var(--fs-label);
  font-weight: 600;
  color: inherit;
  opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

/* ---------- The running order ---------- */

/* Every car fits without scrolling: two slot sizes, stepped by the window's height, the
   points places taller. The slots are fixed, so a car crossing P10 moves into a smaller
   slot rather than the tower re-flowing; rows glide to their new places, so an overtake
   reads as two cars swapping. Columns are measured off the larger size, so both tiers line
   up, and when the tower is too narrow the sectors leave first, then the last lap. */
.tower {
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: var(--s-3) var(--s-3) var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card-solid);
  box-shadow: var(--lift);
  /* The larger slot's size, so the container queries below measure in it. */
  font-size: var(--fs-row-big);
  container: tower / inline-size;
}

.tower-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 2rem;
  margin: 0 0 var(--s-2);
  padding: 0 var(--s-1) 0 var(--s-3);
}

.tower-list {
  --u: var(--fs-row-big);
  --c-pos: calc(var(--u) * 1.3);
  --c-code: calc(var(--u) * 2.55);
  --c-fig: calc(var(--u) * 4.5);
  --c-last: calc(var(--u) * 4.3);
  --c-sec: 2.625rem;
  --c-tyre: calc(var(--u) * 2.7);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  list-style: none;
  font-size: var(--fs-row-big);
}

.tower-list.is-scrolling {
  overflow-y: auto;
}

.row {
  --team: var(--ink-soft);
  display: grid;
  grid-template-columns: var(--c-pos) 4px var(--c-code) minmax(0, 1fr) var(--c-fig) var(--c-last) var(--c-sec) var(--c-tyre);
  align-items: center;
  column-gap: 0.4rem;
  flex: none;
  height: var(--row-small);
  padding: 0 0.625rem 0 0.25rem;
  border-radius: var(--r-row);
  background: var(--row);
  font-size: var(--fs-row-small);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  transition: background-color 160ms ease;
}

.row.is-big {
  height: var(--row-big);
  font-size: var(--fs-row-big);
}

/* The break between the points places and the rest of the field. */
.row:nth-child(10) {
  margin-bottom: 6px;
}

.row:hover {
  background: color-mix(in srgb, var(--ink) 8%, var(--row));
}

/* A driver you follow is painted in their team's colour, like a route's block. */
.row.is-followed {
  background: color-mix(in srgb, var(--team) 30%, var(--card-solid));
}

/* The picked car is ringed, not filled, so its team, purple and green all still read. */
.row.is-picked {
  box-shadow: inset 0 0 0 2px var(--selected);
}

/* In the pit lane: dark red, hatched like the pit lane's own markings. */
.row.is-pit {
  background: repeating-linear-gradient(
    -45deg,
    color-mix(in srgb, var(--alert) 20%, var(--card-solid)) 0 7px,
    color-mix(in srgb, var(--alert) 36%, var(--card-solid)) 7px 10px
  );
}

.row.is-out {
  opacity: 0.4;
}

.row-pos {
  font-weight: 700;
  text-align: right;
}

.row-pos.is-fastest {
  color: var(--timing-best);
}

.row-bar {
  width: 4px;
  height: 62%;
  border-radius: 2px;
  background: var(--team);
}

.row-code {
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--team);
}

.row-marks {
  display: flex;
  align-items: center;
  gap: 3px;
  min-width: 0;
  overflow: hidden;
  font-size: max(var(--fs-label), 0.72em);
  font-weight: 700;
}

.mark {
  display: inline-grid;
  place-items: center;
  min-width: 1.45em;
  height: 1.45em;
  padding: 0 0.3em;
  border-radius: 5px;
  line-height: 1;
}

.mark-penalty,
.mark-p {
  background: var(--alert-fill);
  color: var(--ink);
}

.mark-investigation {
  background: var(--caution);
  color: var(--on-selected);
}

.mark-deletion {
  background: var(--rule-strong);
  color: var(--ink);
}

.row-fig,
.row-last {
  text-align: right;
}

.row-fig {
  font-weight: 700;
}

.row-last {
  font-weight: 600;
}

/* The part of a figure that hardly changes — the minute, the plus — set back, so the eye
   lands on the digits that move. Faded rather than greyed, so a purple time stays purple. */
.faint {
  opacity: 0.5;
}

.is-best {
  color: var(--timing-best);
}

.is-personal {
  color: var(--timing-personal);
}

.row-sectors {
  display: flex;
  gap: 3px;
}

.sector {
  flex: 1;
  height: 0.3125rem;
  border-radius: 3px;
  background: var(--line);
}

.sector.is-set {
  background: var(--axis);
}

.sector.is-personal {
  background: var(--timing-personal);
}

.sector.is-best {
  background: var(--timing-best);
}

.row-tyre {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.3em;
}

/* The tyre as the broadcast shows it: the compound's letter in a ring of its colour, and its
   age. */
.tyre-ring {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 1.6em;
  height: 1.6em;
  border: 0.14em solid var(--tyre, var(--ink-faint));
  border-radius: 50%;
  font-size: max(var(--fs-label), 0.72em);
  font-weight: 800;
  line-height: 1;
  color: var(--tyre, var(--ink-faint));
}

.tyre-ring[data-tyre="soft"] { --tyre: var(--tyre-soft); }
.tyre-ring[data-tyre="medium"] { --tyre: var(--tyre-medium); }
.tyre-ring[data-tyre="hard"] { --tyre: var(--tyre-hard); }
.tyre-ring[data-tyre="inter"] { --tyre: var(--tyre-inter); }
.tyre-ring[data-tyre="wet"] { --tyre: var(--tyre-wet); }

.tyre-age {
  min-width: 1.3em;
  font-size: max(var(--fs-label), 0.82em);
  font-weight: 600;
  color: var(--ink-soft);
}

.tyre-pit {
  padding: 0.15em 0.55em;
  border-radius: var(--r-pill);
  background: var(--alert-fill);
  font-size: max(var(--fs-label), 0.82em);
  font-weight: 700;
  color: var(--ink);
}

/* Narrower than the full set of columns: the sectors leave first, then the last lap. The
   widths are the columns above at the larger slot's size (em), plus their fixed parts. */
@container tower (max-width: calc(16.6em + 108px)) {
  .row {
    grid-template-columns: var(--c-pos) 4px var(--c-code) minmax(0, 1fr) var(--c-fig) var(--c-last) var(--c-tyre);
  }

  .row-sectors {
    display: none;
  }
}

@container tower (max-width: calc(16.6em + 60px)) {
  .row {
    grid-template-columns: var(--c-pos) 4px var(--c-code) minmax(0, 1fr) var(--c-fig) var(--c-tyre);
  }

  .row-sectors,
  .row-last {
    display: none;
  }
}

.tower-empty {
  margin: auto var(--s-4);
  text-align: center;
}

.tower.has-rows .tower-empty {
  display: none;
}

/* The tower head says what the figure column shows; with a choice, it is a chip that
   steps through them. */
.chip-figure::after {
  content: "⇅";
  font-size: var(--fs-context);
  line-height: 1;
}

/* A captured frame, not a live one. */
.tag-demo {
  position: fixed;
  left: 50%;
  bottom: calc(var(--gutter) + var(--dock-h) + var(--s-3));
  z-index: 30;
  height: 2rem;
  padding: 0 var(--s-4);
  transform: translateX(-50%);
  background: var(--selected);
  color: var(--on-selected);
}

.tag-demo::before {
  background: var(--caution);
}

/* ---------- Narrower windows ---------- */

@media (max-width: 1240px) {
  :root {
    --tower-w: 25rem;
  }

  .capsule {
    grid-template-columns: minmax(max-content, 1fr) max-content minmax(0, max-content);
  }

  .cap-fastest {
    display: none;
  }

  .brand-by {
    display: none;
  }
}

/* Narrower still: the tower takes a step in, and the badge keeps its state and delay but
   lets its clock go, so the flag's word keeps its room. */
@media (max-width: 1100px) {
  :root {
    --tower-w: 22rem;
  }

  .badge-clock b {
    display: none;
  }
}

/* The running order's own view exists only where it can't sit beside the stage. */
.view-tower {
  display: none !important;
}

/*
 * Portrait and phones: the app's own layout. The header and the capsule over the stage,
 * the replay timeline under it, and the views as tabs along the foot, the running order
 * now one of them: Tower, Map, Wall, Feed. A message worth interrupting for floats above
 * the timeline, and a car's card rises from the foot as a sheet. The page never scrolls;
 * the tower and the feed scroll inside the stage.
 */
@media (max-width: 900px) {
  :root {
    --tabs-h: 3.5rem;
    --dock-h: 3.75rem;
    --gutter: 1rem;
  }

  .view-tower {
    display: inline-flex !important;
  }

  .wall {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) var(--dock-h);
    grid-template-areas: "top" "capsule" "stage" "dock";
    row-gap: var(--s-3);
    padding-bottom: calc(var(--tabs-h) + var(--s-3) * 2 + env(safe-area-inset-bottom, 0px));
  }

  /* Its children join the wall's grid, so the tower can take the stage's place. */
  .main {
    display: contents;
  }

  .topbar { grid-area: top; }
  .capsule { grid-area: capsule; }
  .stage { grid-area: stage; }
  .dock { grid-area: dock; }

  /* Over the stage it shares a place with (positioned, so it would otherwise be under it). */
  .tower {
    position: relative;
    z-index: 1;
    grid-area: stage;
    display: none;
    min-width: 0;
  }

  :root[data-view="tower"] .tower {
    display: flex;
  }

  :root[data-view="tower"] .stage > :not(.driver) {
    display: none;
  }

  .session-title {
    display: none;
  }

  /* The views have gone to the foot, so the byline has its room back. */
  .brand-by {
    display: inline;
  }

  .topbar {
    gap: var(--s-3);
  }

  .header-controls {
    margin-left: auto;
  }

  /* The views as tabs along the foot. */
  #views {
    position: fixed;
    right: var(--gutter);
    bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
    left: var(--gutter);
    z-index: 25;
    display: flex;
    height: var(--tabs-h);
    padding: 4px;
  }

  #views button {
    flex: 1;
    justify-content: center;
    height: 100%;
    padding: 0 var(--s-2);
    font-size: var(--fs-context);
  }

  /* The flag's word never gives way (its note is contained, so it doesn't count). */
  .capsule {
    grid-template-columns: minmax(max-content, 1fr) auto;
    border-radius: var(--r-card);
  }

  .cap-badge {
    grid-column: 1 / -1;
    padding: var(--s-3) var(--s-5);
  }

  .cap-badge::before {
    display: none;
  }

  /* The badge has a row of its own again, with room for its clock. */
  .badge-clock b {
    display: inline;
  }

  /* Race control's line floats above the timeline only while it has news; the rest of the
     time its messages are in the Feed. */
  .ticker {
    position: fixed;
    right: var(--gutter);
    bottom: calc(var(--tabs-h) + var(--dock-h) + var(--s-3) * 3 + env(safe-area-inset-bottom, 0px));
    left: var(--gutter);
    z-index: 15;
    display: none;
    flex-wrap: wrap;
    width: auto;
    padding: var(--s-3) var(--s-4);
    border-radius: var(--r-inset);
    box-shadow: var(--lift);
  }

  .ticker[data-tone] {
    display: flex;
  }

  .ticker-text {
    flex-basis: 100%;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    white-space: normal;
  }

  /* The feed in one column that scrolls: race control first, its own list scrolling in
     most of the height, then the conditions and the radio. */
  :root[data-view="feed"] .feed {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    overflow-y: auto;
  }

  .feed-rc {
    flex: none;
    height: max(18rem, 62%);
  }

  .feed-side {
    flex: none;
  }

  /* On a narrow map the hint about race positions would cover the track, so it's left
     out. A note saying why the map is empty still shows, on its own line above Follow and
     the credit, on a card like the map's other overlays. */
  .map-note[data-hint] {
    display: none;
  }

  .map-note {
    bottom: calc(var(--s-3) + 2.75rem);
    width: max-content;
    max-width: calc(100% - 2 * var(--s-4));
    padding: var(--s-2) var(--s-4);
    border: 1px solid var(--line);
    border-radius: var(--r-inset);
    background: var(--card);
    box-shadow: var(--lift);
  }

  /* A car's card rises from the foot as a sheet, over the tabs. */
  .driver {
    position: fixed;
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 30;
    width: auto;
    max-height: min(82dvh, 46rem);
    padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
    border-radius: var(--r-card) var(--r-card) 0 0;
    box-shadow: 0 -24px 48px -12px var(--shadow);
    transition: translate 320ms var(--ease);
  }

  @starting-style {
    .driver {
      translate: 0 100%;
    }
  }

  .driver-actions {
    bottom: calc(-1 * var(--s-3) - env(safe-area-inset-bottom, 0px));
    padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
  }

  /* Between sessions the poster takes the stage, its credit under it. */
  :root[data-standby] .wall {
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas: "top" "capsule" "stage";
  }

  .standby {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-end;
    gap: var(--s-3);
    overflow-y: auto;
  }

  .poster-credit {
    max-width: none;
    text-align: left;
  }
}

/* Phones: aurora's small-screen settings — the byline under the wordmark, the panels
   across the screen — and the poster's clock a size down. */
@media (max-width: 560px) {
  :root {
    --gutter: 0.75rem;
    --r-card: 20px;
    --fs-state: 1.75rem;
  }

  .brand {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.125rem;
  }

  .brand-by {
    display: block;
    font-size: var(--fs-label);
    line-height: 1.2;
  }

  .top-more {
    position: fixed;
    top: calc(env(safe-area-inset-top, 0px) + 3.5rem);
    right: var(--gutter);
    left: var(--gutter);
    width: auto;
    max-height: calc(100dvh - 8rem);
    overflow-y: auto;
    padding: var(--s-4) var(--s-5);
  }

  #views button {
    font-size: var(--fs-label);
  }

  .cap {
    padding: 0 var(--s-4);
  }

  .cap-flag {
    gap: var(--s-3);
    padding-left: var(--s-4);
  }

  .cap-badge {
    padding: var(--s-2) var(--s-4);
  }

  /* The ring keeps a readable size; its cards follow under it, and the Wall scrolls. */
  :root[data-view="wall"] .ring {
    grid-template-rows: minmax(16rem, 1fr) auto;
    overflow-y: auto;
  }

  .tl-speed {
    padding: 0 0.7rem;
  }

  /* A replay's timeline gets a row of its own over its buttons; between them on one row it
     was a sliver. Live, the dock is only its strip and the Live chip, and keeps one row. */
  :root[data-mode="replay"] {
    --dock-h: 6.75rem;
  }

  .dock[data-mode="replay"] {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-rows: minmax(0, 1fr) auto;
    gap: var(--s-2);
    padding: var(--s-2) var(--s-3);
    border-radius: var(--r-card);
  }

  .dock[data-mode="replay"] .tl-track {
    grid-row: 1;
    grid-column: 1 / -1;
  }

  .dock[data-mode="replay"] .tl-play { grid-row: 2; grid-column: 1; }
  .dock[data-mode="replay"] .tl-speed { grid-row: 2; grid-column: 2; justify-self: start; }
  .dock[data-mode="replay"] .tl-live { grid-row: 2; grid-column: 3; }
  .dock[data-mode="replay"] .dock-more-btn { grid-row: 2; grid-column: 4; }

  .poster-event {
    font-size: 2rem;
  }

  .poster-place {
    font-size: var(--fs-read);
  }

  .countdown-unit b,
  .countdown-sep {
    font-size: 3.25rem;
  }

  .countdown-days {
    font-size: var(--fs-glance);
  }

  .weekend-chip {
    min-width: 0;
    flex: 1;
    padding: var(--s-2) var(--s-1);
  }

  .chip-poster {
    flex: 1 1 100%;
  }
}

/* A finger needs a bigger target than a pointer: the + and the chips grow to 2.5rem. */
@media (pointer: coarse) {
  .more {
    width: 2.5rem;
    height: 2.5rem;
  }

  .chip {
    height: 2.5rem;
  }
}

/*
 * Reduced motion, in one place: nothing slides, fades, pulses or glides. Panels and the
 * driver's sheet appear and go at once, the flag holds a steady wash instead of pulsing,
 * the telemetry's bars jump to each reading, and the photograph is simply there. The
 * scripts read the same preference (UI.calm): the tower's rows, the map's cars and the
 * ring's dots step straight to their places, and the ring repaints once a second.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
    animation-duration: 0s !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  .beacon {
    animation: none !important;
    opacity: 0.6;
  }
}
