/* ==========================================================================
   TrackSide TV — live timing board
   Loaded after style.css. Everything here is scoped to .timing-page and uses
   the site tokens, so the board follows the light/dark toggle like the rest
   of the site.

   The board is monochrome apart from three functional encodings: class,
   compound and energy. Those are data, not brand colour — the same exception
   --live already makes for the on-air dot.
   ========================================================================== */

.timing-page {
  --tt-row: 44px;
  --tt-hair: var(--line);
  --tt-panel: color-mix(in srgb, var(--fg) 3%, var(--bg));
  --tt-panel-2: color-mix(in srgb, var(--fg) 6%, var(--bg));
  --purple: #b96cff;
  --green: #00c95e;
  --yellow: #ffd000;
  --amber: #ffa030;

  /* Tyre compounds, keyed by the compound's INITIAL. */
  --ty-s: #f2f2f7;   /* Soft   */
  --ty-m: #ffd000;   /* Medium */
  --ty-h: #ff4b4b;   /* Hard   */
  --ty-i: #3cde74;   /* Inter  */
  --ty-w: #5bb8e8;   /* Wet    */
}

/* The functional palette is calibrated for a near-black board. On the light
   theme the same values wash out (Hard is #e6e6f0, which is invisible on
   white), so the whole set is darkened rather than fought with per rule. */
[data-theme="light"] .timing-page {
  --purple: #7b3fd4;
  --green: #0e8a3c;
  --yellow: #9a7600;
  --amber: #b25e00;

  --ty-s: #55555f;
  --ty-m: #9a7600;
  --ty-h: #d21f1f;
  --ty-i: #0e8a3c;
  --ty-w: #1b7aa8;
}

.timing-main {
  /* The board carries far more across than a marketing page, so it gets its
     own width. At 1280 the tyre, energy and status columns end up behind a
     scrollbar on a desktop that had room for them. */
  --tt-maxw: 2100px;
  /* An app view, not a marketing page: the board wants the screen, so the
     gutter is tighter here than the site default. Every pixel saved goes to
     the track map. */
  --gutter: clamp(1rem, 2vw, 1.75rem);
  padding-top: var(--header-h);
  padding-bottom: clamp(3rem, 7vw, 5rem);
}

.timing-wrap { padding-inline: var(--gutter); max-width: var(--tt-maxw); margin-inline: auto; }

/* Several components below set an explicit `display`, which beats the UA
   stylesheet's [hidden] rule. The board toggles visibility with .hidden, so
   this has to win. */
.timing-page [hidden] { display: none !important; }

/* Visually hidden, still read out. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   1. Session bar — sticky under the site header
   -------------------------------------------------------------------------- */
/* Sits directly under the site header, which is fixed at var(--header-h).
   The background is fully opaque on purpose: at 88% the table ghosted through
   the bar as it scrolled past and the whole thing read as broken. */
.tbar {
  position: sticky;
  top: var(--header-h);
  z-index: 60;
  background: var(--bg);
  border-bottom: 1px solid var(--tt-hair);
}

.tbar__inner {
  max-width: var(--tt-maxw);
  margin-inline: auto;
  padding: 0.85rem var(--gutter);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2.25rem);
  flex-wrap: wrap;
}

.tbar__block { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }

.tbar__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-50);
}

.tbar__value {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tbar__value--track { max-width: 34ch; text-transform: uppercase; }

.tbar__clock {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

.tbar__spacer { flex: 1 1 auto; }

.tbar__cta { flex: none; }
.tbar__cta .btn__icon { width: 15px; height: 15px; }

/* Connection dot */
.tconn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.64rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-50);
  white-space: nowrap;
}

.tconn::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--fg-30);
  flex: none;
}

.tconn[data-conn="live"] { color: var(--fg-70); }
.tconn[data-conn="live"]::before { background: var(--green); box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 60%, transparent); animation: tconn-pulse 2s var(--ease-out) infinite; }
.tconn[data-conn="wait"]::before { background: var(--yellow); animation: tconn-blink 1s steps(2, jump-none) infinite; }
/* Connected to the relay, but nothing is being broadcast. */
.tconn[data-conn="idle"]::before { background: var(--fg-30); }
.tconn[data-conn="down"]::before { background: var(--live); }

@keyframes tconn-pulse { to { box-shadow: 0 0 0 9px transparent; } }
@keyframes tconn-blink { 50% { opacity: 0.25; } }

/* --------------------------------------------------------------------------
   2. Standby (no broadcast on air)
   -------------------------------------------------------------------------- */
.standby {
  min-height: 68vh;
  display: grid;
  place-items: center;
  padding: clamp(3rem, 8vw, 6rem) var(--gutter);
}

.standby__card { width: 100%; max-width: 460px; text-align: center; }

/* The mark laps its own outline while the page waits, the same way the
   preloader does. */
.standby__mark {
  width: 64px;
  height: 64px;
  margin: 0 auto 1.75rem;
  display: block;
  color: var(--fg);
  overflow: visible;
}

.standby__mark .mark__play,
.standby__mark .mark__chase {
  fill: none;
  stroke: currentColor;
  stroke-width: 13;
  stroke-linejoin: miter;
  stroke-miterlimit: 6;
}

/* Same seamless loop as the preloader: a dim outline, and a lit segment
   lapping it linearly (mark-loop in style.css), so there is no reset. */
.standby__mark .mark__play {
  stroke-dasharray: 100;
  stroke-dashoffset: 0;
  opacity: 0.25;
}

.standby__mark .mark__chase {
  stroke-linecap: round;
  stroke-dasharray: 28 72;
  stroke-dashoffset: 100;
  animation: mark-loop 1.4s linear infinite;
}

.standby h1 { font-size: clamp(1.7rem, 4.5vw, 2.4rem); margin-bottom: 1.1rem; }

.standby__lead {
  color: var(--fg-50);
  font-size: 0.92rem;
  line-height: 1.65;
  margin: 0 auto 1.75rem;
  max-width: 40ch;
}

.standby__conn { justify-content: center; }

.standby__note {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0;
  line-height: 1.6;
  color: var(--fg-50);
  margin: 1.25rem auto 0;
  max-width: 44ch;
}

.standby__actions { justify-content: center; margin-top: 2.25rem; }

/* --------------------------------------------------------------------------
   3. Stale / empty notices
   -------------------------------------------------------------------------- */
.notice {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.8rem 1rem;
  margin-top: 1.5rem;
  border: 1px solid color-mix(in srgb, var(--live) 45%, transparent);
  background: color-mix(in srgb, var(--live) 9%, transparent);
  border-radius: var(--radius);
  font-family: var(--font-display);
  font-size: 0.8rem;
  letter-spacing: 0;
  color: var(--fg-70);
}

.notice__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--live); flex: none; }

.notice--quiet {
  border-color: var(--line);
  background: var(--tt-panel);
  color: var(--fg-50);
  justify-content: center;
  padding-block: 2.5rem;
}

/* --------------------------------------------------------------------------
   4. Layout: map + board
   -------------------------------------------------------------------------- */
.timing-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(400px, 33vw, 660px);
  gap: clamp(1.25rem, 2.5vw, 2rem);
  align-items: start;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}

/* A grid track's automatic minimum is min-content, and the board column's
   min-content is the table's 1180px min-width. Without this the table's width
   escapes .tb__scroll and the whole PAGE scrolls sideways on a phone, which is
   exactly what the scroll container exists to prevent. */
.timing-grid > * { min-width: 0; }

.timing-grid__side { position: sticky; top: calc(var(--header-h) + 92px); }

/* --------------------------------------------------------------------------
   5. Track map
   -------------------------------------------------------------------------- */
.tmap {
  background: var(--tt-panel);
  border: 1px solid var(--tt-hair);
  border-radius: var(--radius-lg);
  padding: 1.15rem 1.25rem 1.35rem;
}

.tmap__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.tmap__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-50);
}

.tmap__name {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--fg-70);
  text-align: right;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tmap__svg { display: block; width: 100%; height: auto; aspect-ratio: 5 / 4; overflow: visible; }

.tmap__track {
  fill: none;
  stroke: var(--line-2);
  stroke-linejoin: round;
  stroke-linecap: round;
}

.tmap__svg:not([data-ready]) .tmap__track { stroke-dasharray: 4 3; opacity: 0.55; }

.mc { transition: opacity var(--dur-fast) linear; }
.mc circle { paint-order: stroke; }
.mc text { font-family: var(--font-mono); font-weight: 700; pointer-events: none; }
.mc.is-dim { opacity: 0.35; }
/* Selecting a car must not cost it the contrast ring it needs to stay visible
   against the track line. */
.mc.is-sel { filter: drop-shadow(0 0 5px var(--fg)); }

/* --------------------------------------------------------------------------
   7. Class blocks
   -------------------------------------------------------------------------- */
.classes { display: flex; flex-direction: column; gap: clamp(1.25rem, 2.5vw, 1.75rem); }

.tb {
  --cc: var(--fg);
  border: 1px solid var(--tt-hair);
  border-left: 3px solid var(--cc);
  border-radius: var(--radius);
  background: var(--tt-panel);
  overflow: hidden;
}

.tb__head {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--tt-hair);
}

.tb__pill {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg);
}

.tb__count {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-30);
}

/* The table scrolls inside its own container so the page never scrolls
   sideways on mobile. */
.tb__scroll { overflow-x: auto; overscroll-behavior-x: contain; }

/* --------------------------------------------------------------------------
   8. The table
   -------------------------------------------------------------------------- */
.tt {
  width: 100%;
  /* The two optional columns add their own width, so the table is only as
     wide as the columns actually on screen. See --tt-extra below. */
  min-width: calc(1180px + var(--tt-extra, 0px) + var(--tt-vote, 0px));
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.tt th {
  padding: 0.5rem 0.6rem;
  text-align: left;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-30);
  border-bottom: 1px solid var(--tt-hair);
  white-space: nowrap;
}

.tt td {
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid color-mix(in srgb, var(--fg) 6%, transparent);
  vertical-align: middle;
  height: var(--tt-row);
  font-size: 0.8rem;
}

.tt tbody tr:last-child td { border-bottom: 0; }
.tt__row { cursor: pointer; transition: background var(--dur-fast) linear; }
.tt__row:hover { background: var(--tt-panel-2); }
.tt__row.is-selected { background: color-mix(in srgb, var(--fg) 9%, transparent); }
.tt__row:focus-visible { outline: 2px solid var(--fg); outline-offset: -2px; }
.tt__row.is-out { opacity: 0.45; }

/* Position */
.tt__pos {
  width: 44px;
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--fg);
  text-align: center;
}

th.tt__pos { text-align: center; }

/* Car number, printed plain with no hash */
.tt__no {
  width: 50px;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--fg);
}

/* Marque: the mark sits straight on the row, with no plate behind it. The
   relay's artwork is white-filled (the "-dark" variants are never requested),
   which reads on the dark board as-is. On the light theme that same white
   artwork would vanish and only two marques ship a dark variant, so it is
   drawn as a black silhouette instead: legible for every marque, and
   monochrome, which is what the rest of the site is. */
.tt__logo { width: 42px; text-align: center; }

.tt__logo-img {
  width: 26px;
  height: 26px;
  object-fit: contain;
  display: inline-block;
  vertical-align: middle;
}

[data-theme="light"] .timing-page .tt__logo-img { filter: brightness(0); }

/* --------------------------------------------------------------------------
   Rating and nationality, both from the relay, both immediately left of the
   name. They carry wider side padding than the rest of the row on purpose:
   the pair has to read as its own group, not as an extension of the car
   number on one side or the driver on the other.

   Neither column exists until a car actually carries the field. renderBoard()
   puts has-rating / has-nat on .classes, and hiding the th and the td together
   removes the column from every class block at once.
   -------------------------------------------------------------------------- */
.classes { --tt-extra: 0px; }
.classes.has-rating { --tt-extra: 80px; }
.classes.has-nat { --tt-extra: 66px; }
.classes.has-rating.has-nat { --tt-extra: 146px; }

.classes:not(.has-rating) .tt__rating,
.classes:not(.has-nat) .tt__nat { display: none; }

/* Wide enough for the live feed's longest badge, "SLV 3" plus its outline,
   without the cell's own side padding closing in on it. */
.tt__rating { width: 80px; }
.tt__nat { width: 66px; }

.tt__rating, .tt__nat { padding-inline: 0.8rem; white-space: nowrap; }
th.tt__rating, th.tt__nat { padding-inline: 0.8rem; }

/* A category badge. Monochrome like the rest of the board: colour on this page
   only ever means class, tyre compound or sector, and a metal-tinted rating
   would read as one of those. */
.tt__badge {
  display: inline-block;
  min-width: 2.9em;
  padding: 0.14rem 0.3rem;
  border: 1px solid color-mix(in srgb, var(--fg) 26%, transparent);
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-align: center;
  color: var(--fg-70);
}

/* An empty badge would still draw its outline, so the no-value state is the
   bare dash. */
.tt__badge.is-empty {
  border-color: transparent;
  padding-inline: 0;
  min-width: 0;
  color: var(--fg-30);
}

.tt__nat-code {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--fg-70);
}

.tt__nat-code.is-empty { color: var(--fg-30); letter-spacing: 0; }

/* Driver: who is at the wheel first, the rest of the crew under it */
.tt__driver { width: 170px; }
td.tt__driver { white-space: nowrap; }
.tt__driver > * { vertical-align: middle; }

.tt__accent {
  display: inline-block;
  width: 3px;
  height: 26px;
  border-radius: 2px;
  margin-right: 0.6rem;
  /* Several marque colours are pure white or near-black, so the bar always
     carries a contrasting outline. */
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--fg) 38%, transparent);
}

.tt__driver-text { display: inline-flex; flex-direction: column; gap: 1px; max-width: 132px; }

.tt__name {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tt__crew {
  font-size: 0.6rem;
  color: var(--fg-30);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Team, in its own column */
.tt__team-cell { width: 175px; }
td.tt__team-cell { white-space: nowrap; }

.tt__team {
  display: block;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--fg);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 163px;
}

.tt__model {
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.62rem;
  letter-spacing: 0.02em;
  color: var(--fg-30);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 163px;
}

/* Gaps and times */
.tt__gap, .tt__int, .tt__t, .tt__s {
  font-family: var(--font-mono);
  white-space: nowrap;
}

.tt__gap { width: 84px; font-size: 0.78rem; color: var(--fg-70); }
.tt__gap.is-leader { color: var(--fg); font-weight: 700; letter-spacing: 0.06em; }
.tt__gap.is-notime { color: var(--fg-30); }

.tt__int { width: 80px; font-size: 0.78rem; color: var(--fg-50); }
.tt__int.is-close { color: var(--fg); font-weight: 700; }

.tt__t { width: 86px; font-size: 0.78rem; color: var(--fg-70); }
.tt__t--best { color: var(--fg); }

.tt__s { width: 60px; font-size: 0.7rem; color: var(--fg-50); }
.tt__s.is-purple { color: var(--purple); }
.tt__s.is-green  { color: var(--green); }
.tt__s.is-yellow { color: var(--fg-70); }

/* Tyres: four round badges laid out like the car, FL FR over RL RR */
.tt__tyres { width: 82px; }

.tt__tyre-none { color: var(--fg-30); font-family: var(--font-mono); }

.tt__tyre-grid {
  display: inline-grid;
  grid-template-columns: repeat(2, 18px);
  gap: 3px;
}

.tt__tyre {
  --tc: var(--fg-50);
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  font-weight: 700;
  line-height: 1;
  color: var(--tc);
  border: 1.5px solid var(--tc);
  background: color-mix(in srgb, var(--tc) 16%, transparent);
}

/* Energy */
.tt__energy { width: 104px; }

td.tt__energy { display: flex; align-items: center; gap: 0.45rem; }

.tt__bar {
  display: block;
  flex: 1 1 auto;
  height: 5px;
  border-radius: 3px;
  background: color-mix(in srgb, var(--fg) 12%, transparent);
  overflow: hidden;
}

.tt__bar-fill {
  display: block;
  height: 100%;
  background: var(--fg-70);
  border-radius: 3px;
  transition: width var(--dur-fast) linear;
}


.tt__bar.is-mid .tt__bar-fill { background: var(--amber); }
.tt__bar.is-low .tt__bar-fill { background: var(--live); }

.tt__pct {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  color: var(--fg-70);
  flex: none;
  width: 30px;
  text-align: right;
}

.tt__pct.is-mid { color: var(--amber); }
.tt__pct.is-low { color: var(--live); font-weight: 700; }

.timing-note {
  margin-top: 1.5rem;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fg-30);
  line-height: 1.7;
}

/* --------------------------------------------------------------------------
   9. Lap history panel
   -------------------------------------------------------------------------- */
.dt {
  margin-top: 1rem;
  border: 1px solid var(--tt-hair);
  border-radius: var(--radius-lg);
  background: var(--tt-panel);
  overflow: hidden;
}

.dt__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--tt-hair);
}

.dt__title { font-size: 0.85rem; font-weight: 700; text-transform: uppercase; letter-spacing: -0.01em; }

.dt__close {
  background: none;
  border: 0;
  color: var(--fg-50);
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.25rem;
}
.dt__close:hover { color: var(--fg); }

.dt__body { padding: 1rem; max-height: 460px; overflow-y: auto; }

.dt__meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; margin-bottom: 1rem; }
.dt__meta span { display: block; font-family: var(--font-display); font-weight: 600; font-size: 0.58rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-30); margin-bottom: 2px; }
.dt__meta strong { font-size: 0.78rem; font-weight: 600; display: block; overflow: hidden; text-overflow: ellipsis; }
.dt__meta .mono { font-family: var(--font-mono); }

.dt__crew { margin-bottom: 1rem; }
.dt__crew span { display: block; font-family: var(--font-display); font-weight: 600; font-size: 0.58rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-30); margin-bottom: 2px; }
.dt__crew p { font-size: 0.74rem; color: var(--fg-70); margin: 0; line-height: 1.5; }

.dt__empty { font-family: var(--font-display); font-size: 0.72rem; color: var(--fg-30); letter-spacing: 0.08em; }

.dt__laps { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.dt__laps th { text-align: left; font-family: var(--font-display); font-weight: 600; font-size: 0.58rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-30); font-weight: 500; padding: 0.35rem 0.4rem; border-bottom: 1px solid var(--tt-hair); }
.dt__laps td { padding: 0.32rem 0.4rem; font-size: 0.72rem; color: var(--fg-70); border-bottom: 1px solid color-mix(in srgb, var(--fg) 5%, transparent); }
.dt__laps .mono { font-family: var(--font-mono); }
.dt__laps tr.is-best td { color: var(--purple); font-weight: 700; }

/* --------------------------------------------------------------------------
   9b. Team of the Day vote
   A button at the start of every row, shown only while voting is open: the
   relay toggles .is-voting on .classes. Monochrome, like the rest of the
   board: an empty ring to vote, a filled one with a tick once picked.
   -------------------------------------------------------------------------- */
.classes { --tt-vote: 0px; }
.classes.is-voting { --tt-vote: 52px; }
.classes:not(.is-voting) .tt__vote { display: none; }

.tt__vote { width: 52px; text-align: center; padding-inline: 0.4rem; }

.tt__vote-btn {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1.5px solid var(--fg-30);
  border-radius: 50%;
  background: none;
  color: var(--bg);
  cursor: pointer;
  transition: border-color var(--dur-fast) linear, background var(--dur-fast) linear;
}
.tt__vote-btn::after {
  content: "";
  width: 9px;
  height: 5px;
  border: solid currentColor;
  border-width: 0 0 2px 2px;
  transform: translateY(-1px) rotate(-45deg);
  opacity: 0;
}
.tt__vote-btn:hover { border-color: var(--fg); }
.tt__vote-btn:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.tt__vote-btn[aria-pressed="true"] { background: var(--fg); border-color: var(--fg); }
.tt__vote-btn[aria-pressed="true"]::after { opacity: 1; }
.tt__vote-btn:disabled { cursor: default; opacity: 0.4; }

/* The banner reuses .notice, but it is news rather than a warning. */
.notice--vote {
  border-color: var(--tt-hair);
  background: var(--tt-panel);
}
.notice--vote strong { text-transform: uppercase; margin-right: 0.4rem; }
.notice--vote.is-error { border-color: color-mix(in srgb, var(--live) 45%, transparent); }

/* --------------------------------------------------------------------------
   10. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1400px) {
  .timing-grid { grid-template-columns: minmax(0, 1fr); }
  .timing-grid__side { position: static; }
  .tmap__svg { aspect-ratio: 16 / 9; }
}

@media (max-width: 860px) {
  .tbar__inner { gap: 0.85rem 1.25rem; padding-block: 0.7rem; }
  .tbar__value--track { max-width: 18ch; }
  .tbar__spacer { display: none; }
}

@media (max-width: 640px) {
  .tbar__block--session { display: none; }
  .tbar__clock { font-size: 1.15rem; }
}

/* --------------------------------------------------------------------------
   11. Motion preferences — matches the rest of the site
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .standby__mark .mark__play,
  .tconn::before { animation: none !important; }
  .standby__mark .mark__chase { animation: none; opacity: 0; }
  .standby__mark .mark__play { opacity: 1; }
  .tt__bar-fill { transition: none; }
}
