/* The site is dark, and only dark. A light palette existed and was never as
   good: the photograph, the class colours and the timing-screen look all
   assume a black ground. */
:root {
  /* The sport's red, used by the wordmark whatever class is being read. */
  --mark-red: #e10600;
  color-scheme: dark;
  --bg: #0f1115;
  --surface: #181b21;
  --text: #e8eaef;
  --muted: #9aa3b2;
  --border: #2a2f38;
  --hover: #20242c;
  --accent: #e10600;
  --p1: rgba(255, 196, 0, 0.55);
  --p2: rgba(170, 176, 184, 0.55);
  --p3: rgba(205, 127, 50, 0.5);
  --scored: rgba(46, 160, 67, 0.28);
  --classified: rgba(120, 150, 230, 0.16);
  --dnf: rgba(160, 160, 160, 0.16);
  --warn-bg: #3a2f10;
  --warn-border: #a8842a;
}

/* The raw accent is for filled pills, where white sits on it. As text on a
   surface it falls under 4.5:1, so it is pulled toward the page's own text
   colour.

   Declared on body, not :root: a custom property resolves its var() at the
   element it is declared on, so on :root it would have locked to the default
   accent and ignored the per-league override below. */
body {
  --accent-text: color-mix(in srgb, var(--accent) 78%, var(--text));
}

/* The championship takes the sport's own red, and the two classes follow in
   the order they sit in the switcher. */
body[data-league="official"] { --accent: #e10600; }
body[data-league="front-runners"] { --accent: #7b3fbf; }
body[data-league="midfield"] { --accent: #1e88e5; }

* { box-sizing: border-box; }

/* An author rule that sets `display` beats the browser's own [hidden] rule, so
   anything given display: block or flex below would stay visible after
   `el.hidden = true`. Several things rely on that: the chart tooltips, and
   every image that hides itself when its file is missing. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  line-height: 1.4;
}

.container {
  --gutter: 1.25rem;
  max-width: 1320px;
  margin: 0 auto;
  padding: 1.5rem var(--gutter) 3rem;
}

.site-header {
  min-width: 0;
  margin-bottom: 1.7rem;
}

/* ---- wordmark ----------------------------------------------------------- */

/* Barlow Condensed, kept in the repo rather than linked from Google, so the
   page still makes no network request of its own. Two cuts only, latin only,
   about 23KB each. tools/fetch-fonts.sh re-fetches them; fonts/OFL.txt is the
   licence they come under. */
@font-face {
  font-family: 'Barlow Condensed';
  font-style: italic;
  font-weight: 800;
  font-display: swap;
  src: url('../fonts/barlow-condensed-800-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/barlow-condensed-700.woff2') format('woff2');
}

/* Heavy italic, cut by three leaning bars. The bars are drawn rather than
   typed: a slash is a different shape in every font, and these have to match
   the slant of the letters beside them. */
.wordmark {
  --bar-w: 10px;
  --bar-gap: 5px;
  --bar-lean: 0.7rem;
  margin: 0;
  line-height: 1;
}

/* On the standings page the mark is the way home. It is a name, not a link,
   so it takes none of the colouring or the underline links carry. */
.wordmark,
.wordmark-link {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: inherit;
  text-decoration: none;
}

/* The bars belong to the name, not to the block: they stand exactly as tall
   as SPLIT GRID, and the year sits above the S rather than above them. */
.mark-row {
  display: flex;
  align-items: stretch;
  gap: var(--bar-lean);
}
.mark-bars {
  display: flex;
  align-items: stretch;
  gap: var(--bar-gap);
  flex: none;
}
.mark-bars i {
  display: block;
  width: var(--bar-w);
  border-radius: 1px;
  background: var(--mark-red);
  transform: skewX(-18deg);
}
.mark-bars i:nth-child(1) { opacity: 0.35; }
.mark-bars i:nth-child(2) { opacity: 0.65; }

/* Nudged past the foot of the S: the letters lean, so the top of the S stands
   further right than the box it sits in, and lining the year up with the box
   left it hanging over the bars. */
.mark-year {
  margin-left: calc(3 * var(--bar-w) + 2 * var(--bar-gap) + var(--bar-lean) + 0.6rem);
  margin-bottom: 0.12rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The mark keeps the sport's red whichever class you are reading, since it is
   the name of the site rather than a part of the page's colouring. The two
   words are pulled together: at this weight and slant the space between them
   opens up more than it should. */
.mark-name {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: clamp(2.6rem, 7.5vw, 64px);
  font-weight: 800;
  font-style: italic;
  line-height: 0.85;
  letter-spacing: -0.035em;
  word-spacing: -0.05em;
  text-transform: uppercase;
  transform: skewX(-2deg);
  transform-origin: left bottom;
}
.mark-name span { color: var(--mark-red); }

/* ---- the line under it --------------------------------------------------- */

.strap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.65rem 0.95rem;
  margin: 1.15rem 0 0;
  font-size: 0.85rem;
  color: var(--muted);
}
.strap-tag { color: var(--text); }
.strap-rule {
  width: 1px;
  height: 0.95rem;
  background: var(--border);
}
.subtitle {
  margin: 0;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Below about this width the strapline wraps, and the divider before the last
   item is left dangling at the end of the line above it. */
@media (max-width: 880px) {
}

@media (max-width: 700px) {
  .wordmark { --bar-w: 7px; --bar-gap: 4px; --bar-lean: 0.5rem; }
  .strap-rule { display: none; }
}
/* Line icons: no fills, stroked in whatever colour the surrounding text is. */
.icon {
  width: 15px;
  height: 15px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* League and view sit on one line: two stacked rows of pills was most of the
   weight at the top of the page, and the heading underneath then repeated
   both of them back. */
.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem 1.4rem;
  margin: 0 0 2rem;
}

/* One segmented control rather than three separate pills. Shared, so the
   stat scope picker on a profile is recognisably the same control. */
.segmented {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}
.segmented button {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  border: 0;
  border-radius: 999px;
  padding: 0.34rem 0.9rem;
  background: transparent;
  color: var(--muted);
}
.segmented button:hover { background: var(--hover); color: var(--text); }
.segmented button.active { background: color-mix(in srgb, var(--accent) 82%, #000); color: #fff; }

/* Which class you are reading is the biggest decision on the page, so the
   control takes the landing page's cut-corner button rather than the quiet
   pill the view tabs use, and each choice wears its own colour. */
.league-nav {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.league-nav button {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 0.42rem 1.1rem;
  border: 1px solid color-mix(in srgb, var(--class-colour) 55%, var(--border));
  border-radius: 0;
  background: transparent;
  color: color-mix(in srgb, var(--class-colour) 62%, var(--text));
  clip-path: polygon(0 0, 100% 0, calc(100% - 11px) 100%, 0 100%);
  padding-right: 1.5rem;
  transition: background 150ms ease, border-color 150ms ease;
}
.league-nav button[data-league="official"] { --class-colour: #e10600; }
.league-nav button[data-league="front-runners"] { --class-colour: #7b3fbf; }
.league-nav button[data-league="midfield"] { --class-colour: #1e88e5; }
.league-nav button:hover {
  border-color: var(--class-colour);
  background: color-mix(in srgb, var(--class-colour) 14%, transparent);
}
/* Filled, but mixed toward black first: the raw blue cannot carry white text
   at this size. */
.league-nav button.active {
  border-color: color-mix(in srgb, var(--class-colour) 82%, #000);
  background: color-mix(in srgb, var(--class-colour) 82%, #000);
  color: #fff;
}

/* Views are quieter: they change what you are looking at, not which class you
   are in. So they keep the switcher's type but not its button — two controls
   shouting side by side would leave neither leading. */
.view-nav {
  display: inline-flex;
  gap: 1.4rem;
}
.view-nav button {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 0.3rem 0;
  background: none;
  color: var(--muted);
}
.view-nav button:hover { color: var(--text); }
.view-nav button.active {
  color: var(--accent-text);
  border-bottom-color: var(--accent);
}

.warnings {
  --lean: 10px;
  background: var(--warn-bg);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  padding: 0.6rem 1.5rem;
  margin: 0.5rem 0 1rem;
}
.warnings ul { margin: 0.3rem 0 0; padding-left: 1.2rem; }

.loader {
  --lean: 10px;
  background: var(--surface);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  padding: 1rem 1.5rem;
  margin: 1rem 0;
}

h2 {
  font-size: 1.35rem;
  margin: 1rem 0 0.5rem;
}
h3 {
  font-size: 1.1rem;
  margin: 1.2rem 0 0.4rem;
}
.muted { color: var(--muted); font-weight: 400; }

.legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
  font-size: 0.85rem;
  color: var(--muted);
}

/* The key and the note explain the table they sit under. */
.table-note {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  color: var(--muted);
}

/* A key and the sentence under it belong together. */
.table-note + .table-note {
  margin-top: 0.35rem;
}

/* The heading names the table under it, so it sits between the podium and
   the table rather than over the whole page. */
.view-title {
  margin: 0 0 0.7rem;
}
.legend .chip { --chip-lean: 3px; height: 1.4rem; min-width: 1.85rem; font-size: 0.75rem; }
.legend .cell { color: var(--muted); padding: 0 0.25rem; }

.table-wrap {
  overflow-x: auto;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}

table.standings {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.9rem;
  white-space: nowrap;
}

/* Numeric and result columns shrink to their content, so the slack from a
   full-width table lands on the text columns rather than pushing a single
   digit miles from its heading. */
.standings .pos, .standings .num, .standings .pts, .standings .tot,
.standings th.num, .standings th.pts, .standings th.tot,
.standings td.cell, .standings th.session {
  width: 1%;
}
.standings th, .standings td {
  padding: 0.85rem 0.7rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: middle;
}
.standings thead th {
  font-weight: 600;
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--surface);
}
.standings tbody tr:hover { background: var(--hover); }
/* The row goes where the link inside it goes, so it says so. */
.standings tbody tr[data-href] { cursor: pointer; }
.standings tbody tr:last-child td { border-bottom: none; }

.standings th.session {
  text-align: center;
  padding: 0.3rem 0.2rem;
}
.standings th.session span { display: block; }
.standings th.session small {
  display: block;
  font-size: 0.65rem;
  color: var(--muted);
  text-transform: none;
}

/* Short count columns centre, because a heading like "Podiums" is far wider
   than the single digit under it and right-aligning both reads as an offset.
   Points and running totals stay right-aligned so magnitudes line up. */
.standings .pos, .standings .num, .standings th.num {
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.standings .pts, .standings th.pts, .standings .tot, .standings th.tot {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.standings .tot { color: var(--muted); }
.standings .pts { font-weight: 700; }
.standings .driver { min-width: 12rem; }

/* Cross-league footnote, kept to an icon so it cannot widen the column. */
.info {
  display: inline-grid;
  place-items: center;
  width: 15px;
  height: 15px;
  margin-left: 0.3rem;
  border: 1px solid var(--muted);
  border-radius: 50%;
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  line-height: 1;
  cursor: help;
  vertical-align: 1px;
}
.info:hover, .info:focus-visible {
  border-color: var(--accent);
  color: var(--accent-text);
}
.code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 700;
  margin-right: 0.25rem;
}
.arrow { color: var(--muted); }


/* ---- links -------------------------------------------------------------- */

/* One hover treatment everywhere: an accent underline that sweeps in from the
   left, drawn as a background so it sits clear of the descenders instead of
   cutting through them the way text-decoration does. */
.driver-link,
.team-link,
.gp-name,
.row-name a,
.cross-league a {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(var(--accent-text), var(--accent-text));
  background-repeat: no-repeat;
  background-position: 0 calc(100% - 1px);
  background-size: 0 1.5px;
  transition: background-size 180ms ease, color 180ms ease;
}
.row-name a { font-weight: 600; }
.cross-league a { color: var(--accent-text); }

.driver-link:hover,
.driver-link:focus-visible,
.gp-cell:hover .gp-name,
.gp-cell:focus-visible .gp-name,
.team-link:hover,
.team-link:focus-visible,
.row-name a:hover,
.row-name a:focus-visible,
.cross-league a:hover,
.cross-league a:focus-visible,
/* Hovering the row is hovering its link, since pressing either does the same
   thing. Only the link the row actually goes to lights up: a driver's row
   holds a link to their team as well, and that one is still its own. */
tr[data-target="driver"]:hover .driver-link,
tr[data-target="team"]:hover .team-link,
tr[data-target="round"]:hover .gp-name {
  color: var(--accent-text);
  background-size: 100% 1.5px;
}

@media (prefers-reduced-motion: reduce) {
  .driver-link, .team-link, .row-name a, .cross-league a { transition: none; }
}

/* ---- artwork ---------------------------------------------------------- */

/* One driver identity used everywhere: head shot, then the code, then the
   name. The team colour ring comes from an inline style on the avatar. */
.ident {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}
.ident-text { min-width: 0; }

.avatar {
  display: block;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--hover);
  box-shadow: 0 0 0 2px var(--team, #888);
}

.logo {
  width: 22px;
  height: 22px;
  flex: none;
  object-fit: contain;
}

.team-name {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  gap: 0.4rem;
  border-left: 3px solid var(--team, #888);
  padding-left: 0.5rem;
}



/* ---- podium ----------------------------------------------------------- */

.podium {
  list-style: none;
  margin: 0 0 1.35rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.podium-slot {
  position: relative;
  display: flex;
  min-width: 0;
}

/* The whole card is the link. Nothing else inside it is clickable, so there is
   no nested-link problem, and the ink is already set per card. */
a.podium-card {
  flex: 1;
  min-width: 0;
  text-decoration: none;
  color: var(--ink);
  transition: transform 160ms ease, box-shadow 160ms ease;
}
a.podium-card:hover,
a.podium-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 10px 22px rgba(0, 0, 0, 0.32);
}
a.podium-card:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  a.podium-card { transition: none; }
  a.podium-card:hover, a.podium-card:focus-visible { transform: none; }
}

/* Team-coloured brand panel, in both themes: podium cards and profile heroes
   are the same thing at different sizes. --ink is set per panel to whichever
   of near-black or white the colour can carry. */
.team-panel {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.5rem;
  overflow: hidden;
  background-color: var(--team);
  background-image: linear-gradient(105deg,
    color-mix(in srgb, var(--team) 91%, #fff) 0%,
    var(--team) 48%,
    color-mix(in srgb, var(--team) 92%, #000) 100%);
  color: var(--ink);
}

/* Halftone speed dots: a one-dot SVG tile repeated at a fixed pixel size, so
   they stay crisp at any width or pixel density, masked to fade in. */
.team-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='6' height='6'%3E%3Ccircle cx='3' cy='3' r='1.35' fill='%23000'/%3E%3C/svg%3E");
  background-size: 6px 6px;
  -webkit-mask-image: linear-gradient(100deg, transparent 10%, #000 70%);
  mask-image: linear-gradient(100deg, transparent 10%, #000 70%);
}

.podium-card {
  --lean: 14px;
  min-height: 128px;
  padding: 0.7rem 0 0 1.1rem;
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
}

/* Panel content sits above the dot layer. */
.podium-text, .podium-img, .podium-car, .profile-text, .profile-img, .profile-car {
  position: relative;
  z-index: 1;
}

.podium-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-bottom: 0.7rem;
  min-width: 0;
}
/* The badge straddles the corner rather than sitting inside the card, so
   that these are the top three reads at a glance instead of having to be
   found in the text. The ring is the page colour, which cuts the badge out of
   the card cleanly in either theme, and it is see-through to the pointer so
   the whole card stays one click. */
.podium-rank {
  position: absolute;
  top: -0.55rem;
  left: -0.2rem;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 2px solid var(--bg);
  border-radius: 50%;
  font-weight: 800;
  font-size: 1rem;
  pointer-events: none;
}
.rank1 .podium-rank { background: #e8b923; color: #2a2000; }
.rank2 .podium-rank { background: #b8bcc4; color: #1c1f24; }
.rank3 .podium-rank { background: #cd7f32; color: #241200; }

.podium-name {
  font-weight: 800;
  font-size: 1.05rem;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.podium-team {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--ink);
  opacity: 0.8;
  font-size: 0.82rem;
}
.podium-pts {
  font-weight: 800;
  font-size: 1.45rem;
  line-height: 1.1;
  margin-top: 0.1rem;
  font-variant-numeric: tabular-nums;
}
.podium-pts small { font-size: 0.6em; font-weight: 600; opacity: 0.7; }

/* Racing number sitting behind the driver. White mask like the logos, so it
   is inverted to match whichever ink the card's colour takes. */
/* Inset far enough that the card's slanted right edge does not cut the
   numeral on its way down, and a little stronger than it was: at 0.15 over a
   leaning card it read as a fragment rather than a watermark. */
.podium-number {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: 1.5rem;
  transform: translateY(-50%);
  height: 76%;
  width: auto;
  opacity: 0.22;
  pointer-events: none;
}

.podium-img {
  height: 128px;
  width: auto;
  align-self: flex-end;
  /* Clear of the slanted right edge, which was cutting the driver off at the
     shoulder on the way down. */
  margin-right: 1.4rem;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.35));
}

/* Constructor cards stack the text over a full-bleed car render. */
.podium-teams .podium-card {
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: 0;
  min-height: 0;
  padding: 0.7rem 0.9rem 0.9rem;
}
.podium-teams .podium-text {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  padding-bottom: 0.45rem;
}
.podium-teams .podium-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.podium-teams .podium-pts { font-size: 1.35rem; margin-top: 0; }

/* Inset rather than full-bleed: the car reads as sitting on the card instead
   of being cropped by it. */
.podium-car {
  display: block;
  width: 100%;
  height: auto;
  margin: 0.45rem 0 0;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.3));
}

@media (max-width: 700px) {
  .podium { grid-template-columns: 1fr; }
}

.standings td.cell {
  text-align: center;
  min-width: 2.6rem;
  padding: 0.25rem 0.2rem;
}
.cell.absent { color: var(--muted); }

/* Each result is a rounded chip rather than a tinted cell, so the grid reads
   as a row of badges. Podium colours are solid and theme-independent; the
   quieter states follow the theme. */
/* Every result on the site is one of these, and they lean like everything
   else now. The extra width pays for the two slices the lean takes out of a
   box this small. */
.chip {
  --chip-lean: 4px;
  display: inline-grid;
  place-items: center;
  min-width: 2rem;
  height: 1.6rem;
  padding: 0 0.45rem;
  clip-path: polygon(var(--chip-lean) 0, 100% 0, calc(100% - var(--chip-lean)) 100%, 0 100%);
  font-size: 0.82rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.chip.p1 { background: #e0a800; color: #2a2000; }
.chip.p2 { background: #aeb4bd; color: #1c1f24; }
.chip.p3 { background: #c2803f; color: #2a1500; }
.chip.scored { background: #1f6b45; color: #ffffff; }
.chip.classified {
  background: var(--classified);
  color: var(--muted);
  font-weight: 600;
}
/* A sprint is worth a third of a Grand Prix, so its chips are hatched rather
   than filled: the same colours, read at a glance as the lesser race. The
   stripes are drawn from the chip's own ink, which is chosen to contrast with
   its background, so they show on gold and on dark green alike. */
.sprint-row .chip,
.sprint-cell .chip {
  background-image: repeating-linear-gradient(135deg,
    color-mix(in srgb, currentColor 26%, transparent) 0 2px,
    transparent 2px 6px);
}

.chip.dnf {
  background: var(--dnf);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
}
.dagger { font-size: 0.7em; vertical-align: super; color: var(--muted); }

.round-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.4rem 0 0.6rem;
}
/* Leaning like everything else, so the border goes: an outline cannot follow
   a clipped edge. The fill carries the shape instead, one step up from the
   surface it sits on so it still reads as a control. */
.pill {
  --lean: 9px;
  display: inline-block;
  padding: 0.25rem 1.1rem;
  background: var(--hover);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  color: var(--text);
  text-decoration: none;
  font-size: 0.85rem;
}
.pill:hover { background: color-mix(in srgb, var(--text) 16%, var(--hover)); }
.pill.active {
  background: color-mix(in srgb, var(--accent) 82%, #000);
  color: #fff;
}

.session-table tr.dnf-row td { color: var(--muted); }
.session-table .driver { min-width: 10rem; }

.site-footer {
  margin-top: 2.4rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.site-footer summary { cursor: pointer; color: var(--text); }
.site-footer ul { padding-left: 1.2rem; }

/* The date rides with the race type rather than taking a column of its own:
   that cell held one of two words and had room to spare. */
.race-cell {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}
.race-cell small { font-size: 0.78rem; }

/* Flag, circuit and sprint badge on one line, the same trio the round rail
   carries, so a row is recognisable without reading it. */
.gp-cell {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.gp-cell .flag { flex: none; }
.gp-cell .round-spr {
  flex: none;
  color: var(--muted);
}

/* ---- the explainer ------------------------------------------------------ */


/* In-page links glide rather than jump. The section stops short of the very
   top so it does not sit flush against the edge of the window. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}
#how,
#grid {
  scroll-margin-top: 1.5rem;
}

/* ---- landing page ------------------------------------------------------- */

/* The bar across the top: mark, sections, and how far the season has got. */
.site-bar {
  /* The year sits above the name, so centring against the whole mark puts
     everything else above the middle of SPLIT GRID. The nav drops by the
     height of that year line, which lands it on the big text's own centre. */
  --mark-year-h: 1.12rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
}
.site-nav {
  display: flex;
  flex-wrap: wrap;
  margin-top: var(--mark-year-h, 0);
  gap: 1.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.site-nav a {
  color: var(--muted);
  text-decoration: none;
}
.site-nav a:hover { color: var(--text); }
.site-status { margin: var(--mark-year-h, 0) 0 0 auto; }
.is-home .site-header { margin-bottom: 4.6rem; }

/* ---- hero ---------------------------------------------------------------- */

/* The photograph carries the split: one line in, three out, one for each
   class. It is behind the copy rather than beside it, and the page's own
   colour is drawn across the left of it so the words have something quiet to
   sit on while the picture emerges to their right. No frame: it should read
   as the top of the page, not as an illustration placed on it. */
.hero {
  display: flex;
  align-items: center;
  min-height: clamp(300px, 32vw, 430px);
  margin: 0 calc(-1 * var(--gutter)) 3.4rem;
  padding: 2rem var(--gutter);
  background-repeat: no-repeat;
  background-position: right center;
  background-size: auto 100%;
  /* Four fades, one per edge, so the photograph has no cut edges anywhere and
     appears to be part of the page rather than laid on top of it. The left is
     the deepest, because that is where the words are. */
  background-image:
    linear-gradient(95deg, var(--bg) 4%, color-mix(in srgb, var(--bg) 82%, transparent) 30%, transparent 58%),
    linear-gradient(to bottom, var(--bg) 0%, transparent 22%),
    linear-gradient(to top, var(--bg) 0%, transparent 24%),
    linear-gradient(to left, var(--bg) 0%, transparent 14%),
    url('../img/home/hero.webp');
  background-image:
    linear-gradient(95deg, var(--bg) 4%, color-mix(in srgb, var(--bg) 82%, transparent) 30%, transparent 58%),
    linear-gradient(to bottom, var(--bg) 0%, transparent 22%),
    linear-gradient(to top, var(--bg) 0%, transparent 24%),
    linear-gradient(to left, var(--bg) 0%, transparent 14%),
    image-set(url('../img/home/hero.avif') type('image/avif'), url('../img/home/hero.webp') type('image/webp'));
}
.hero-copy {
  position: relative;
  max-width: 34rem;
}

.hero-title {
  margin: 0 0 1.1rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: clamp(2.9rem, 5.5vw, 4.7rem);
  font-weight: 800;
  font-style: italic;
  line-height: 0.94;
  letter-spacing: 0.012em;
  text-transform: uppercase;
  transform: skewX(-2deg);
  transform-origin: left bottom;
}
.hero-title em {
  font-style: italic;
  color: var(--mark-red);
}
/* Brighter than the muted grey the rest of the page uses for secondary text:
   this paragraph has a photograph behind it, and at the muted weight it was
   disappearing into the track. */
.hero-lead {
  margin: 0 0 1.7rem;
  font-size: 1.06rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--text) 80%, var(--muted));
}
.hero-lead b { color: var(--text); }

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin: 0;
}

/* The primary one is cut off at the corner, the way a racing graphic would
   be, rather than rounded like the controls in the standings. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.8rem 1.5rem;
  border: 1px solid var(--border);
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1.05rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none;
  clip-path: polygon(0 0, 100% 0, calc(100% - 14px) 100%, 0 100%);
  transition: background 150ms ease, color 150ms ease;
}
.btn:hover { background: var(--hover); }
.btn-go {
  border-color: var(--mark-red);
  background: var(--mark-red);
  color: #fff;
  padding-right: 1.9rem;
}
.btn-go:hover { background: #ff1a0d; }
.btn-go span { transition: transform 150ms ease; }
.btn-go:hover span { transform: translateX(3px); }

/* The way back to the explainer, as a control rather than a line of underlined
   text at the bottom of a long table. Quieter than the landing page's buttons:
   it is an offer, not the thing the page is for. */
.btn-quiet {
  padding: 0.55rem 1.6rem 0.55rem 1.1rem;
  font-size: 0.92rem;
  letter-spacing: 0.09em;
  color: var(--muted);
  clip-path: polygon(0 0, 100% 0, calc(100% - 11px) 100%, 0 100%);
}
.btn-quiet:hover { color: var(--text); }
.btn-quiet .mark-bars {
  --bar-w: 5px;
  --bar-gap: 2px;
  height: 0.8rem;
  opacity: 0.75;
}

/* ---- the three ways in ---------------------------------------------------- */

/* The picture names the three classes; these are the ones you can press, so
   they carry what the picture cannot: who is leading each one today. */
/* Three across or one down. Letting them wrap on their own put two on a row
   and left the third sitting under a gap. */
.hero-classes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.9rem;
  margin-bottom: 1.3rem;
}
@media (max-width: 760px) {
  .hero-classes { grid-template-columns: 1fr; }
}

/* How far the season has got, under the standings it applies to rather than
   up in the bar where it was a fact about nothing in particular. */
.season-line {
  margin: 0 0 3.8rem;
}
/* Leaning like the cards on the standings pages. The class colour was the
   left border; clipped, that would be cut into a triangle, so it becomes a
   rule cut to the same geometry, the way the round rail's is. */
.hero-class {
  --lean: 14px;
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem 1.2rem 0.7rem 1.6rem;
  background: var(--surface);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  color: inherit;
  text-decoration: none;
  transition: background 150ms ease, transform 150ms ease;
}
.hero-class::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: calc(var(--lean) + 3px);
  background: var(--class-colour);
  clip-path: polygon(var(--lean) 0, calc(var(--lean) + 3px) 0, 3px 100%, 0 100%);
}
.hero-class[data-league="official"] { --class-colour: #e10600; }
.hero-class[data-league="front-runners"] { --class-colour: #7b3fbf; }
.hero-class[data-league="midfield"] { --class-colour: #1e88e5; }
.hero-class:hover {
  background: color-mix(in srgb, var(--class-colour) 12%, var(--surface));
  transform: translateY(-2px);
}
.hero-class:focus-visible {
  outline: 2px solid var(--class-colour);
  outline-offset: 2px;
}
.hero-class-body {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.hero-class-name {
  color: color-mix(in srgb, var(--class-colour) 78%, var(--text));
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1.2rem;
  font-weight: 800;
  font-style: italic;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.hero-class-leader {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 0.4rem;
  font-size: 0.8rem;
  min-width: 0;
}
.hero-class-leader .logo { flex: none; }
.hero-class-sep { color: color-mix(in srgb, var(--muted) 60%, transparent); }
.hero-class-leader:empty { display: none; }
.hero-class-leader .avatar { width: 22px; height: 22px; }
.hero-class-leader b {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hero-class-leader small { flex: none; color: var(--muted); }

/* A line between the sections of a long page, fading out rather than running
   the full width: a solid rule across would cut the page into slabs, which is
   the opposite of what the rest of it is doing. */
.is-home .how::before,
.is-home #grid::before {
  content: '';
  display: block;
  height: 1px;
  margin: 0 0 3.8rem;
  background: linear-gradient(to right,
    var(--border),
    color-mix(in srgb, var(--border) 30%, transparent) 58%,
    transparent);
}

/* ---- how it works -------------------------------------------------------- */

.how { margin-bottom: 3.8rem; }
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin: 0 0 0.9rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow .mark-bars {
  --bar-w: 6px;
  --bar-gap: 3px;
  height: 0.85rem;
}
/* Set below the hero deliberately: this is a section heading, and at the size
   it was it read as a second headline arguing with the first. */
.how-title {
  margin: 0 0 3.1rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: clamp(1.65rem, 3.2vw, 2.35rem);
  font-weight: 800;
  font-style: italic;
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  transform: skewX(-2deg);
  transform-origin: left bottom;
}
.how-title em {
  font-style: italic;
  color: var(--mark-red);
}

.how-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 2.4rem 2.6rem;
  margin: 0 0 3.1rem;
  padding: 0;
  list-style: none;
}
.how-step[data-league="official"] { --class-colour: #e10600; }
.how-step[data-league="front-runners"] { --class-colour: #7b3fbf; }
.how-step[data-league="midfield"] { --class-colour: #1e88e5; }
.how-step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 0.9rem;
}
.how-step-no {
  grid-row: 1 / span 2;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 3.2rem;
  font-weight: 800;
  font-style: italic;
  line-height: 0.8;
  color: var(--class-colour);
}
.how-step h3 {
  margin: 0 0 0.3rem;
  font-size: 1.05rem;
  border-bottom: 1px solid var(--class-colour);
  padding-bottom: 0.35rem;
}
.how-step p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--muted);
}

/* ---- one race, re-scored ------------------------------------------------- */

/* The argument the whole site makes, in one panel: two real cars from one real
   afternoon, each read twice. It is the loudest thing on the page on purpose,
   so it is built like a timing graphic rather than a paragraph - cut corners,
   skewed cards, the class in its own colour.

   The frame is two elements: the outer one is the border, the inner one the
   fill, both cut to the same shape. A border cannot follow a clip-path, so
   this is the way to get an outline around a notched box. */
.rescore {
  --notch: 16px;
  --ex-blue: #1e88e5;
  --ex-ink: #1e88e5;
  --ex-gold: #f0b429;
  margin: 0 0 3.1rem;
  background: color-mix(in srgb, var(--ex-blue) 35%, var(--border));
  clip-path: polygon(
    var(--notch) 0, calc(100% - var(--notch)) 0, 100% var(--notch),
    100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%,
    var(--notch) 100%, 0 calc(100% - var(--notch)), 0 var(--notch));
}
.rescore-in {
  margin: 1px;
  padding: 1.1rem 1.8rem 1.2rem;
  clip-path: inherit;
  background:
    radial-gradient(120% 150% at 100% 50%,
      color-mix(in srgb, var(--ex-blue) 12%, transparent), transparent 60%),
    var(--surface);
}

/* Which race, and what has been done to it. */
.rescore-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
  margin: 0 0 0.9rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.rescore-race { color: var(--text); }
.rescore-race::after {
  content: '·';
  margin-left: 0.55rem;
  color: var(--muted);
}
.rescore-class { color: var(--ex-ink); }
.rescore-rule {
  flex: 1;
  min-width: 1.5rem;
  height: 1px;
  background: linear-gradient(to right,
    color-mix(in srgb, var(--ex-blue) 55%, transparent),
    color-mix(in srgb, var(--border) 60%, transparent) 45%,
    transparent);
}
.rescore-note {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--muted) 80%, transparent);
}

/* Two cars, side by side, split by a line on the same lean as the cards. */
/* The two cars sit together in the middle of the panel with the line between
   them, rather than being pushed to opposite ends: spread across the full
   width, the gap in the middle read as something missing. */
.rescore-runs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.6rem 6rem;
}
.rescore-run {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.6rem 1.3rem;
  min-width: 0;
}
.rescore-run + .rescore-run::before {
  content: '';
  position: absolute;
  top: -0.5rem;
  bottom: -0.5rem;
  left: -3rem;
  width: 2px;
  background: linear-gradient(to bottom,
    transparent,
    color-mix(in srgb, var(--ex-blue) 55%, transparent) 22%,
    color-mix(in srgb, var(--ex-blue) 55%, transparent) 78%,
    transparent);
  transform: skewX(-9deg);
}

/* The name, with the three bars of the mark cut down to one. */
.rescore-driver {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1.75rem;
  font-weight: 800;
  font-style: italic;
  line-height: 1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--text);
}
.rescore-driver::before {
  content: '';
  width: 7px;
  height: 1.35em;
  background: var(--ex-blue);
  transform: skewX(-12deg);
}

/* Each reading of the afternoon is a card on a lean; the text inside leans
   back so it stays upright. */
.rescore-card {
  display: grid;
  justify-items: center;
  gap: 0.1rem;
  padding: 0.5rem 1.35rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: color-mix(in srgb, var(--text) 5%, transparent);
  transform: skewX(-9deg);
}
.rescore-card > * { transform: skewX(9deg); }
.rescore-card.is-class {
  border-color: var(--ex-blue);
  background:
    linear-gradient(150deg,
      color-mix(in srgb, var(--ex-blue) 26%, transparent),
      color-mix(in srgb, var(--ex-blue) 9%, transparent));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ex-blue) 25%, transparent);
}
.rescore-label {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.rescore-card.is-class .rescore-label { color: var(--ex-ink); }
.rescore-pos {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 2.3rem;
  font-weight: 800;
  font-style: italic;
  line-height: 0.95;
  letter-spacing: 0.01em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.rescore-card.is-class .rescore-pos { color: var(--ex-blue); }
.rescore-pts {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.95rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.rescore-pts b {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--text);
}
.rescore-card.is-class .rescore-pts b { color: var(--ex-ink); }

/* A win is the whole point of the exercise, so it gets the one warm colour on
   the page. */
.rescore-win {
  display: grid;
  justify-items: center;
  gap: 0.12rem;
  margin-left: 0.15rem;
  padding-left: 0.5rem;
  border-left: 1px solid color-mix(in srgb, var(--ex-blue) 40%, transparent);
  color: var(--ex-gold);
}
.rescore-win b {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.rescore-trophy {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rescore-chevrons {
  flex: none;
  width: 34px;
  height: 17px;
  fill: none;
  stroke: var(--ex-blue);
  stroke-width: 3.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rescore-chevrons path:first-child { opacity: 0.4; }
.rescore-chevrons path:nth-child(2) { opacity: 0.7; }

.rescore-foot {
  margin: 1rem 0 0;
  padding-top: 0.8rem;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  color: color-mix(in srgb, var(--muted) 85%, transparent);
}

/* One car under the other once there is no room for two abreast; the line
   between them turns with them. */
@media (max-width: 860px) {
  /* The spacing that gives the panel its swagger across a desktop is what
     breaks the row up into wrapped pieces on a phone, so it comes back in. */
  .rescore-in { padding: 0.9rem 1rem 1rem; }
  .rescore-runs {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem 0;
  }
  .rescore-run { gap: 0.5rem 0.6rem; }
  .rescore-driver { font-size: 1.45rem; }
  .rescore-card { padding: 0.4rem 0.8rem 0.45rem; }
  .rescore-pos { font-size: 1.9rem; }
  .rescore-chevrons { width: 26px; height: 13px; }
  .rescore-foot { margin-top: 0.9rem; font-size: 0.8rem; letter-spacing: 0.06em; }
  .rescore-run + .rescore-run::before {
    top: -0.6rem;
    bottom: auto;
    left: 0;
    right: 0;
    width: auto;
    height: 1px;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rescore-card,
  .rescore-card > *,
  .rescore-driver::before { transform: none; }
}

@media (max-width: 900px) {
  /* Too narrow to stand the picture beside the words, so it lies behind them
     and fades from the bottom instead of the side. */
  .hero {
    min-height: 0;
    background-size: cover;
    background-position: 68% center;
    background-image:
      linear-gradient(to bottom, var(--bg) 0%, color-mix(in srgb, var(--bg) 88%, transparent) 30%, color-mix(in srgb, var(--bg) 88%, transparent) 62%, var(--bg) 100%),
      url('../img/home/hero.webp');
    background-image:
      linear-gradient(to bottom, var(--bg) 0%, color-mix(in srgb, var(--bg) 88%, transparent) 30%, color-mix(in srgb, var(--bg) 88%, transparent) 62%, var(--bg) 100%),
      image-set(url('../img/home/hero.avif') type('image/avif'), url('../img/home/hero.webp') type('image/webp'));
  }
}

@media (prefers-reduced-motion: reduce) {
  .btn, .btn-go span, .hero-class { transition: none; }
  .hero-class:hover { transform: none; }
}

/* ---- the grid ------------------------------------------------------------ */

/* On the landing page this is a section like the others, so it runs the full
   width and holds its own prose to a readable measure. In the standings it is
   still a column of notes. */
.about { max-width: 46rem; }
.is-home .about { max-width: none; }
.is-home .about .panel { margin-bottom: 3.1rem; }
.is-home .about .panel p { max-width: 40rem; }

.about h2 {
  margin: 0.2rem 0 0.6rem;
  font-size: 1.6rem;
  letter-spacing: -0.01em;
}
.about-lead {
  margin: 0 0 1.6rem;
  font-size: 1.05rem;
  line-height: 1.55;
}
.about p { line-height: 1.55; }
.about .panel > p:last-child { margin-bottom: 0; }
.about .round-nav { margin-top: 1.6rem; }

/* Display type for the headings, over the same fading rule the sections of
   the page are divided by. */
.is-home .about .panel h3 {
  position: relative;
  margin: 0 0 0.9rem;
  padding-bottom: 0.5rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1.45rem;
  font-weight: 800;
  font-style: italic;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.is-home .about .panel h3::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(to right,
    var(--mark-red),
    color-mix(in srgb, var(--border) 50%, transparent) 38%,
    transparent);
}
.is-home .about .panel > .muted { margin-bottom: 1.2rem; }

.about-classes {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 1.1rem;
}
.about-classes li { line-height: 1.5; }

/* Each class named in its own colour, so the switcher's colours are learnt
   here rather than guessed at later. */
.about-class {
  font-weight: 700;
  color: var(--accent);
}
.about-class[data-league="official"] { color: #e10600; }
.about-class[data-league="front-runners"] { color: #7b3fbf; }
.about-class[data-league="midfield"] { color: #1e88e5; }

.is-home .about-classes li[data-league="official"] { --class-colour: #e10600; }
.is-home .about-classes li[data-league="front-runners"] { --class-colour: #7b3fbf; }
.is-home .about-classes li[data-league="midfield"] { --class-colour: #1e88e5; }
.is-home .about-classes li {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: 0.3rem 0.7rem;
  padding-left: 0.95rem;
  border-left: 2px solid var(--class-colour);
}
/* Pulled toward the page's text the way the accent is: the raw purple sits
   just under 3:1 on this ground. */
.is-home .about-class {
  color: color-mix(in srgb, var(--class-colour) 78%, var(--text));
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1.2rem;
  font-weight: 800;
  font-style: italic;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.about-class-meta {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.about-class-teams {
  grid-column: 1 / -1;
  font-size: 0.9rem;
  color: var(--muted);
}

/* Three ways into the standings, in the same cut-corner control as the hero,
   each wearing the colour of the class it leads to. The label is mixed toward
   the page's text colour before it is used: the raw red and purple are fine
   as a rule but too dark to read as small bold type on this ground. */
.about-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
}
.about-cta .btn[data-league="official"] { --class-colour: #e10600; }
.about-cta .btn[data-league="front-runners"] { --class-colour: #7b3fbf; }
.about-cta .btn[data-league="midfield"] { --class-colour: #1e88e5; }
.about-cta .btn[data-league] {
  border-color: color-mix(in srgb, var(--class-colour) 60%, var(--border));
  color: color-mix(in srgb, var(--class-colour) 62%, var(--text));
}
.about-cta .btn[data-league]:hover {
  border-color: var(--class-colour);
  background: color-mix(in srgb, var(--class-colour) 14%, transparent);
}

/* ---- race tabs ---------------------------------------------------------- */

/* A sprint weekend has two races. One table at a time, flipped here, rather
   than both stacked down the page. */
.race-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}
.race-head h2 { margin: 0.9rem 0 0.2rem; }

.race-tabs {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin-top: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}
.race-tabs button {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.92rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  border: 0;
  border-radius: 999px;
  padding: 0.25rem 0.8rem;
  background: transparent;
  color: var(--muted);
}
.race-tabs button:hover { background: var(--hover); color: var(--text); }
.race-tabs button.active { background: color-mix(in srgb, var(--accent) 82%, #000); color: #fff; }

.race-date {
  margin: 0 0 0.9rem;
  font-size: 0.88rem;
}

/* ---- frozen columns ----------------------------------------------------- */

/* The identifying columns stay put while the matrix scrolls under them. They
   need their own background, or the scrolling cells show through, and they
   need to follow the row hover so the row still reads as one row. */
.standings td.frozen,
.standings th.frozen {
  position: sticky;
  z-index: 2;
  background: var(--surface);
}
.standings thead th.frozen { z-index: 3; }
.standings tbody tr:hover td.frozen { background: var(--hover); }

/* A hairline plus a soft shadow, so it is obvious the rest slides underneath. */
.standings .frozen-edge {
  box-shadow: 1px 0 0 var(--border), 7px 0 7px -7px rgba(0, 0, 0, 0.35);
}

/* ---- driver page ------------------------------------------------------- */



/* Same panel, sized for a page header. */
.profile-hero {
  --lean: 18px;
  min-height: 150px;
  margin-bottom: 1rem;
  padding: 0.9rem 0 0 1.4rem;
  /* The same lean as the podium it was reached from, a little deeper for the
     extra height. */
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
}

/* Who this page is about, once the card itself has scrolled away. A strip of
   its own rather than the card folded up: the card keeps its size and its
   place in the flow, so the page below it never moves, and the handover is a
   fade and a slide instead of an attempt to animate one layout into another.
   The colour runs to both edges, the way a title bar should. */
.hero-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 6;
  display: block;
  border-radius: 0;
  opacity: 0;
  transform: translateY(-100%);
  /* This is the going transition: a rule's own transition runs when the
     element arrives at that rule's state. Leaving is the gentler of the two,
     whether it goes because the reader moved on or because the card came
     back, since both happen while their attention is elsewhere. */
  transition: opacity 300ms ease, transform 300ms ease;
  pointer-events: none;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}
/* Coming is quicker: they have just turned back and are looking for it. */
.hero-bar.on {
  opacity: 1;
  transform: none;
  transition: opacity 160ms ease, transform 200ms ease;
}

.hero-bar-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 1320px;
  margin: 0 auto;
  padding: 0.4rem 1.25rem 0.45rem;
}
.hero-bar-text {
  flex: 1;
  min-width: 0;
}
.hero-bar-line {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  min-width: 0;
}
/* Which class this standing is in. A fifth place means nothing without it,
   and the strip is all that is on screen by then. Under the line rather than
   in it: the name and the score are what a glance is for, and this is what
   they are a name and a score within. */
/* One ink for the whole strip. Only the class is set back, because it is the
   one thing on the line that is not about this team. */
.hero-bar-class {
  opacity: 0.72;
  display: block;
  margin-top: 0.05rem;
  font-size: 0.68rem;
  letter-spacing: 0.02em;
}
/* The place and the score bookend the strip, both at its full height. */
.hero-bar-rank {
  flex: none;
  display: flex;
  align-items: baseline;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 800;
  font-style: italic;
  font-size: 2.3rem;
  line-height: 1;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}
.hero-bar-rank small {
  font-size: 0.4em;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
/* One line of text with the badge set in it, rather than a flex row holding
   a picture and some words. A flex container takes its baseline from its
   first item, which was the badge, so the name sat off the line every other
   part of the strip was on; and an ellipsis needs inline content to trim, so
   a long name was being cut off mid-letter instead. */
.hero-bar-name {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 800;
  font-size: 1.05rem;
}
.hero-bar-team {
  flex: none;
  white-space: nowrap;
  font-size: 0.82rem;
}
.hero-bar-name .logo,
.hero-bar-team .logo {
  vertical-align: -0.15em;
  margin-right: 0.35rem;
}
/* As tall as the strip, which is the only thing a glance at a fixed bar is
   really for. */
.hero-bar-pts {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 0.2rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 800;
  font-style: italic;
  font-size: 2.3rem;
  line-height: 1;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}
.hero-bar-pts small {
  font-size: 0.36em;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .hero-bar { transition: opacity 300ms ease; transform: none; }
}


.profile-text {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-bottom: 0.9rem;
  min-width: 0;
}
.profile-rank { font-weight: 800; font-size: 0.95rem; opacity: 0.85; }
.profile-rank small { font-weight: 600; opacity: 0.8; }
.profile-name {
  margin: 0.1rem 0 0.15rem;
  font-size: 1.9rem;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.profile-team {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.88rem;
  opacity: 0.85;
}
/* The shared hover underline is drawn in the accent, which has nothing to do
   with the colour this panel is painted in. On here it takes the panel's own
   ink. */
.profile-team .team-link {
  background-image: linear-gradient(currentColor, currentColor);
}
.profile-team .team-link:hover,
.profile-team .team-link:focus-visible { color: inherit; }
.profile-pts {
  display: flex;
  align-items: baseline;
  margin-top: 0.35rem;
  font-size: 2rem;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.profile-pts small { font-size: 0.45em; font-weight: 600; opacity: 0.75; }
/* Which class this standing is in: a first of seven means nothing without it.
   On the same line as the score, after an interpunct, rather than stacked
   under it. */
.profile-class {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0.75;
}
.profile-class::before {
  content: '·';
  margin: 0 0.45rem 0 0.55rem;
  opacity: 0.7;
}
.profile-number {
  position: absolute;
  z-index: 0;
  top: 50%;
  right: 2rem;
  transform: translateY(-50%);
  height: 80%;
  width: auto;
  opacity: 0.22;
  pointer-events: none;
}
.profile-img {
  position: relative;
  z-index: 1;
  height: 150px;
  width: auto;
  align-self: flex-end;
  margin-right: 1.9rem;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.35));
}

.cross-league {
  position: relative;
  --lean: 10px;
  margin: 0 0 1rem;
  padding: 0.55rem 1.3rem;
  background: var(--surface);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  font-size: 0.9rem;
}
.cross-league::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: calc(var(--lean) + 3px);
  background: var(--accent);
  clip-path: polygon(var(--lean) 0, calc(var(--lean) + 3px) 0, 3px 100%, 0 100%);
}

/* Smaller than the class switcher, which picks the page you are on: these
   only change what is already in front of you. Doubled class so the size
   survives the narrow-screen rule further down the sheet. */
.segmented.small {
  padding: 2px;
}
.segmented.small button {
  font-size: 0.78rem;
  padding: 0.2rem 0.62rem;
}

/* Which races the tiles below are counting. */
.stat-modes {
  margin: 0 0 0.55rem;
}

.tiles {
  display: grid;
  /* Eight of these is a full set, and at a desktop width they have to fit on
     one row: any wider a minimum and the eighth wraps on its own. The widest
     label is "Classifications" at 100px, so the padding leaves room for it in
     a column this narrow. */
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}
/* Leaning like the cards. The border goes with the radius: an outline cannot
   follow a clipped edge, and against the page the fill draws the shape on its
   own. A little more side padding keeps the longer labels off the slants. */
.tile {
  --lean: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  padding: 0.7rem 1rem;
  background: var(--surface);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  text-align: center;
}
.tile-value {
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.tile-label {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
}
/* The footnote under a tile qualifies the number above it, so it sits back
   from both the figure and its label. The muted span inside has to be named
   too, or it paints its own colour back over this one. */
.tile-sub,
.tile-sub .muted {
  font-size: 0.72rem;
  /* As light as it can go and still clear 4.5:1 against the tile. */
  color: color-mix(in srgb, var(--muted) 90%, transparent);
}

.neighbours { margin-bottom: 1.2rem; }

.panel { margin: 0 0 1.4rem; }
.panel h3 { margin: 0 0 0.5rem; }
.panel > .muted { margin: 0 0 0.7rem; font-size: 0.85rem; }

/* ---- chart -------------------------------------------------------------- */

.chart-wrap {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  padding: 0.5rem 0.4rem 0.2rem;
  overflow-x: auto;
}
.chart { display: block; width: 100%; min-width: 520px; height: auto; }
.chart-grid { stroke: var(--border); stroke-width: 1; }
.chart-tick { fill: var(--muted); font-size: 10px; text-anchor: end; }
.chart-tick-x { text-anchor: middle; font-size: 9px; }

/* A sprint label sits a little over a circuit's width from its Grand Prix, so
   it is set smaller and quieter to keep the pair apart. */
.chart-tick-spr {
  font-size: 7.5px;
  opacity: 0.75;
}
/* Lines take their driver's or team's colour, with a little of the page's own
   text colour mixed in to lift the darker liveries off the black. */
.chart-line {
  fill: none;
  stroke: color-mix(in srgb, var(--line, var(--accent)) 82%, var(--text));
  stroke-width: 2.2;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.chart-line-ref {
  stroke-width: 1.7;
  stroke-dasharray: 4 3;
  opacity: 0.85;
}
.chart-dot {
  fill: var(--surface);
  stroke: color-mix(in srgb, var(--line, var(--accent)) 82%, var(--text));
  stroke-width: 1.6;
}
.chart-dot.scored { fill: color-mix(in srgb, var(--line, var(--accent)) 82%, var(--text)); }

/* A reference line's own race markers, shown only while it is hovered. */
.chart-dots-ref {
  opacity: 0;
  pointer-events: none;
}
.chart-dots-ref.hot { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .chart-dots-ref { transition: opacity 130ms ease; }
}
/* Which line the chart is comparing against. */
.chart-modes {
  margin: 0 0 0.6rem;
}
.chart-line-faint {
  stroke-width: 1.4;
  stroke-dasharray: none;
  opacity: 0.42;
}
.chart-line-ref.hot {
  stroke-width: 2.6;
  stroke-dasharray: none;
  opacity: 1;
}
.key-line.key-faint { opacity: 0.45; }

.chart-key {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0.5rem 0 0;
  font-size: 0.82rem;
  color: var(--text);
}
.key-line {
  display: inline-block;
  width: 18px;
  height: 0;
  border-top: 2.2px solid color-mix(in srgb, var(--line, var(--accent)) 82%, var(--text));
}
.key-line.key-ref {
  margin-left: 0.8rem;
  border-top-width: 1.7px;
  border-top-style: dashed;
}
.key-line.key-faint { border-top-color: var(--muted); opacity: 0.6; }

/* ---- row lists: team-mate head to head, and a team's points split -------- */

.rows {
  --lean: 14px;
  background: var(--surface);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
}
.row {
  display: grid;
  align-items: center;
  gap: 0.8rem;
  padding: 0.6rem 0.8rem;
  border-bottom: 1px solid var(--border);
}
.row:last-child { border-bottom: none; }
.row-h2h { grid-template-columns: minmax(13rem, 1.1fr) minmax(11rem, 2fr); }
.row-share { grid-template-columns: minmax(13rem, 1fr) minmax(6rem, 1.6fr) auto auto; }
.row-name {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
}
.row-name small { margin-left: 0.1rem; }
.row-tail { font-size: 0.85rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.row-share .row-tail { font-size: 1rem; font-weight: 800; }
.row-meta { font-size: 0.8rem; white-space: nowrap; }

.row-bar { display: flex; }

/* Two bars per team-mate: who finished ahead, and how the points split. Each
   bar's width matches the numbers printed in it. */
.h2h-bars {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.h2h-bars .row-bar + .bar-label { margin-top: 0.35rem; }
.bar-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: 600;
}
.h2h-bar {
  --h2h-h: 22px;
  --lean: 4px;
  display: flex;
  height: var(--h2h-h);
  font-size: 0.74rem;
  font-weight: 700;
}

/* Both sides are cut to the same parallelogram, so the join between them
   leans and the two outer ends lean with it. Adjacent copies of one shape
   meet along parallel edges, so the two halves still fit together exactly. */
.h2h-bar > span {
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
}

/* The code and the number share one line box rather than being centred
   separately. As two flex items each was centred on its own, and since the
   code is smaller and monospace its line box is a different height, so the
   two never sat on the same baseline. Direct children only: the code inside
   has to stay inline. */
.h2h-bar > span {
  display: block;
  line-height: var(--h2h-h);
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}

/* Each driver's code sits at the outer edge of its own side. */
.h2h-bar .h2h-mine { text-align: left; padding-left: 0.85rem; }
.h2h-bar .h2h-theirs { text-align: right; padding-right: 0.85rem; }
.h2h-mine .h2h-who { margin-right: 0.4rem; }
.h2h-theirs .h2h-who { margin-left: 0.4rem; }
.h2h-who {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  opacity: 0.75;
}
/* The class's colour, split: the driver whose page this is takes the filled
   side and the team-mate a wash of the same. Mixed toward black before it is
   filled, as every other filled control is, because white on the raw midfield
   blue is 3.6:1. */
.h2h-mine {
  background: color-mix(in srgb, var(--accent) 82%, #000);
  color: #fff;
}
.h2h-theirs {
  background: color-mix(in srgb, var(--accent) 26%, var(--surface));
  color: var(--text);
}
.share-bar {
  --lean: 4px;
  height: 22px;
  background: var(--hover);
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
}
.share-bar span {
  display: grid;
  place-items: center;
  height: 100%;
  min-width: 1.4rem;
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  /* The class's colour, like the head-to-head bars. */
  background: color-mix(in srgb, var(--accent) 82%, #000);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
}

@media (max-width: 700px) {
  .row { grid-template-columns: 1fr; gap: 0.4rem; }
  .profile-name { font-size: 1.5rem; }
}

/* ---- constructor page --------------------------------------------------- */


.team-hero { min-height: 132px; align-items: center; }
.team-hero .profile-name {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 1.7rem;
}
.profile-car {
  position: relative;
  z-index: 1;
  width: 58%;
  max-width: 460px;
  height: auto;
  align-self: center;
  margin-right: 1.6rem;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.3));
}


.standings .cars {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 1rem;
}
/* A driver's column is headed by their face beside their code, and the whole
   head is a link to their page. */
.standings th.car-col {
  text-align: center;
  padding: 0.3rem 0.5rem;
}
.standings th.car-col a {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: inherit;
  text-decoration: none;
}
.standings th.car-col .avatar { width: 22px; height: 22px; }
.standings th.car-col .code { margin: 0; }
.standings th.car-col a:hover .code { color: var(--accent-text); }

/* Only a handful of columns here, so the table has width to spare. Left to
   itself the whole surplus went to the circuit name and pushed every number
   into a huddle at the right edge; the drivers' columns take a share of it
   instead. */
.car-table th.car-col,
.car-table td.cell {
  width: auto;
  min-width: 4.5rem;
}

@media (max-width: 700px) {
  
  .profile-car { width: 45%; }
}


/* A pill carrying a full driver identity needs to lay out as a row rather
   than as inline text, or the arrow and the gap wrap onto their own lines. */
.pill-ident {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 1.2rem 0.3rem 1rem;
  white-space: nowrap;
}
.pill-ident .ident { gap: 0.45rem; }
.neighbours { align-items: center; }

/* Every pill in the neighbour nav matches the tallest, which is the one
   carrying a driver's head shot. The gap is set rather than left to the
   spaces in the markup: a flex container drops whitespace between its items,
   so a team pill ran its arrow, badge, name and points together. */
.neighbours .pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.4rem;
}

/* Where a driver or a team is not: reached by switching class on their page,
   so it says who they are, why they are not here, and where they are instead,
   in the same card the rest of the site is built from. */
/* The only thing on the page when a team or driver is looked up in a class
   they do not race in, so it leans like the card it stands in for. */
.not-here {
  --lean: 18px;
  background: var(--surface);
  padding: 1.1rem 2rem 1.2rem;
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
}
.not-here h2 {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 1.75rem;
  font-weight: 800;
  font-style: italic;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.not-here p { margin: 0 0 0.9rem; }

/* A face or a badge set into the line of text, not a flex row beside it: a
   flex row takes its baseline from the picture, which left the class name
   sitting off the line it shares. */
.pill-face {
  display: inline-block;
  padding: 0.3rem 0.85rem 0.3rem 0.5rem;
}
.pill-face .avatar,
.pill-face .logo {
  display: inline-block;
  width: 20px;
  height: 20px;
  vertical-align: -0.4em;
  margin-right: 0.45rem;
}
.not-here .round-nav { margin: 0; }

/* ---- chart hover -------------------------------------------------------- */

.chart-area { position: relative; }

/* A transparent fat stroke over each reference line: a 1px line is almost
   impossible to hit with a pointer. */
.chart-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 11;
  stroke-linejoin: round;
  pointer-events: stroke;
  cursor: pointer;
}

/* The same trick for the dots, which are smaller still. */
.chart-hit-dot {
  fill: transparent;
  stroke: none;
  cursor: pointer;
}



/* Who the line belongs to on top, what the race under the pointer was worth
   underneath, with the face beside both. Explicit columns rather than source
   order, so a portrait that failed to load leaves the two lines stacked
   instead of dropping them side by side. */
.chart-tip {
  position: absolute;
  z-index: 5;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 0.55rem;
  row-gap: 0.02rem;
  padding: 0.4rem 1rem 0.45rem 0.9rem;
  /* A clip takes the border and the shadow with it, and the tip sits on a
     panel its own colour, so it is lifted off that panel instead. */
  --lean: 10px;
  background: color-mix(in srgb, var(--text) 15%, var(--surface));
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  font-size: 0.85rem;
  white-space: nowrap;
  pointer-events: none;
}
.chart-tip .avatar,
.chart-tip .logo {
  grid-column: 1;
  grid-row: 1 / span 3;
  width: 32px;
  height: 32px;
}
.tip-name {
  grid-column: 2;
  grid-row: 1;
}
.tip-race {
  grid-column: 2;
  grid-row: 2;
  font-size: 0.8rem;
}
.tip-value {
  grid-column: 2;
  grid-row: 3;
  font-size: 0.78rem;
  color: var(--muted);
}

/* ---- round pills -------------------------------------------------------- */

.flag {
  width: 20px;
  height: 15px;
  flex: none;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
}

/* The calendar is a rail rather than a wrapped list: a season reads left to
   right, and thirteen rounds across three rows of pills was a lot of page
   spent on a picker. */
.round-rail {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding: 0.2rem 0.15rem 0.3rem;
  margin-bottom: 0.5rem;

  /* No scrollbar. The fade at each end says the season carries on, the wheel
     and the drag both move it, and a bar under a row of cards was a piece of
     window furniture rather than part of the calendar. */
  scrollbar-width: none;
  -ms-overflow-style: none;

  /* The cards dissolve at whichever end there are more rounds, which is set
     from the scroll position. A mask rather than a gradient overlay, so it
     needs no knowledge of the colour behind it and works in both themes. */
  --fade-l: 0px;
  --fade-r: 0px;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--fade-l),
    #000 calc(100% - var(--fade-r)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 var(--fade-l),
    #000 calc(100% - var(--fade-r)), transparent 100%);
}
.round-rail::-webkit-scrollbar { display: none; }

/* With no scrollbar, something has to say the rail moves. A quiet pair of
   chevrons does it without claiming the attention a filled control would,
   and gives the wheel-less and the trackpad-shy a way through the season. */
.rail-steps {
  display: flex;
  justify-content: center;
  gap: 0.45rem;
  margin: -0.1rem 0 0.8rem;
}
.rail-step {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  cursor: pointer;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  transition: color 150ms ease, border-color 150ms ease, opacity 150ms ease;
}
.rail-step:hover:not(:disabled) {
  color: var(--text);
  border-color: var(--accent);
}
.rail-step:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* At the end of the season in that direction. Left in place rather than
   hidden, so the pair does not jump about as the rail moves. */
.rail-step:disabled {
  cursor: default;
  opacity: 0.3;
}

@media (prefers-reduced-motion: reduce) {
  .rail-step { transition: none; }
}

/* Draggable with a mouse. The grab cursor is the only thing that advertises
   it, so it is worth showing wherever the drag actually works. */
@media (hover: hover) and (pointer: fine) {
  .round-rail { cursor: grab; }
  /* The cards are links, so their own pointer cursor was winning over the
     rail's for the whole of a drag — which is exactly when the closed hand
     matters. Every descendant takes it while the drag is live. */
  .round-rail.dragging,
  .round-rail.dragging * { cursor: grabbing; }
}

/* A drag has to track the pointer exactly, so no smoothing, and no text
   selection running away with it. */
.round-rail.dragging {
  scroll-behavior: auto;
  user-select: none;
}

/* Every card the same size, so the rail reads as a calendar rather than as a
   row of differently shaped buttons. */
.round-card {
  position: relative;
  flex: none;
  /* Wider than it was: the lean costs a slice of usable width at each end. */
  width: 11rem;
  height: 5.1rem;
  display: grid;
  align-content: space-between;
  gap: 0.2rem;
  --lean: 14px;
  padding: 0.55rem 1.35rem;
  border: 1px solid var(--border);
  background: var(--surface);
  /* Both ends slant the same way, so the rail leans like a set of timing
     boards rather than a row of boxes with one corner sliced off. */
  clip-path: polygon(var(--lean) 0, 100% 0, calc(100% - var(--lean)) 100%, 0 100%);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  transition: border-color 150ms ease, transform 150ms ease;
}
.round-head {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
}
/* The class colour arrives as a rule down the leading edge, which is what
   squares the card off against the cut-corner controls above it. */
.round-card::before {
  content: '';
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: 0;
  width: calc(var(--lean) + 3px);
  background: var(--accent);
  clip-path: polygon(var(--lean) 0, calc(var(--lean) + 3px) 0, 3px 100%, 0 100%);
  opacity: 0;
  transition: opacity 150ms ease;
}
.round-card:hover::before,
.round-card.active::before { opacity: 1; }
.round-card.active::before { background: rgba(255, 255, 255, 0.75); }

.round-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}
.round-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.round-card .flag {
  width: 26px;
  height: 19px;
}
/* The round number is a label, so it takes the display face the rest of the
   site labels things in. The circuit name below it stays in the body face: it
   is the content of the card, and it has to sit beside a flag and scroll when
   it is too long. */
.round-no {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-size: 0.82rem;
  font-weight: 700;
  font-style: italic;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.round-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.15;
}
.round-name > span {
  display: inline-block;
  white-space: nowrap;
}

/* Long names slide far enough to show their tail, hold at each end, and come
   back. The distance and duration are set per card from the measured overflow. */
.round-name.scrolls > span {
  animation: name-slide var(--slide, 6s) ease-in-out infinite;
}
@keyframes name-slide {
  0%, 16% { transform: translateX(0); }
  50%, 66% { transform: translateX(var(--shift, 0)); }
  100% { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .round-name > span { text-overflow: ellipsis; max-width: 100%; overflow: hidden; }
  .round-name.scrolls > span { animation: none; }
}
.round-date {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  color: var(--muted);
}
.round-spr {
  padding: 0 0.25rem;
  border: 1px solid var(--border);
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.05em;
}

/* Mixed toward black before it is filled, for the same reason the class
   switcher is: white on the raw midfield blue is 3.6:1. */
.round-card.active {
  background: color-mix(in srgb, var(--accent) 82%, #000);
  border-color: color-mix(in srgb, var(--accent) 82%, #000);
  color: #fff;
}
.round-card.active .round-no,
.round-card.active .round-date { color: rgba(255, 255, 255, 0.92); }
.round-card.active .round-spr { border-color: rgba(255, 255, 255, 0.5); }

@media (prefers-reduced-motion: reduce) {
  .round-card { transition: none; }
  .round-card:hover { transform: none; }
}

/* A driver who changed team shows each in turn. Every slide sits in the same
   grid cell, so the column is as wide as the widest name and stays that width
   as they swap, rather than resizing on every change. */
.team-rotate {
  display: inline-grid;
  vertical-align: middle;
  cursor: help;
}
.team-slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transition: opacity 420ms ease;
}
.team-slide.on {
  opacity: 1;
  visibility: visible;
}
@media (prefers-reduced-motion: reduce) {
  .team-slide { transition: none; }
}

/* ---- small screens ------------------------------------------------------ */

/* Below about a phone's width everything competes for the same few hundred
   pixels, so trim the chrome and give the blocks more room to breathe from
   each other rather than from the edges. */
@media (max-width: 700px) {
  .container { --gutter: 0.85rem; padding: 0.75rem var(--gutter) 2.5rem; }

  .site-header h1 { font-size: 1.45rem; }
  .subtitle { font-size: 0.85rem; margin-bottom: 0.8rem; }

  .controls { gap: 0.5rem 1rem; margin-bottom: 0.9rem; }
  .league-nav button,
  .segmented button { font-size: 0.85rem; padding: 0.3rem 0.7rem; }
  .view-nav { gap: 0.9rem; }
  .view-nav button { font-size: 0.85rem; }

  h2 { font-size: 1.2rem; margin: 0.9rem 0 0.6rem; }
  h3 { font-size: 1.02rem; }

  /* The legend has to wrap to three lines here, so give the rows space of
     their own rather than letting them run together. */
  .legend {
    gap: 0.45rem 0.5rem;
    font-size: 0.78rem;
    line-height: 1.2;
    margin-bottom: 0.9rem;
  }

  .standings th, .standings td { padding: 0.72rem 0.5rem; }
  .standings .driver { min-width: 10.5rem; }
  .standings thead th { font-size: 0.68rem; }

  .tiles { grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: 0.5rem; }
  .tile { padding: 0.55rem 0.65rem; }
  .tile-value { font-size: 1.3rem; }

  .panel { margin-bottom: 1.2rem; }
  .round-card { width: 9rem; height: 4.8rem; padding: 0.5rem 0.6rem; }

  /* The chart fits the screen instead of scrolling sideways. It has a viewBox,
     so it simply draws smaller, which shrinks the labels with it: they are set
     larger in the drawing's own units to come out the same size on the glass.
     There is no room for eighteen of them at this width, so the sprints drop
     out and the circuits stay. */
  /* The class and the name matter more than the car on a narrow strip, and
     the strip's own colour already says which team it is. */
  .hero-bar-team { display: none; }

  .chart { min-width: 0; }
  .chart-tick { font-size: 17px; }
  .chart-tick-x { font-size: 16px; }
  .chart-tick-spr { display: none; }
  .chart-dot { stroke-width: 2.6; }
  .chart-line { stroke-width: 3.4; }

  /* A circuit name is the widest thing in a frozen column, and at "Barcelona-
     Catalunya GP" it took more than half a phone's screen, so the pair of
     frozen columns no longer fitted and the round lost its circuit. The name
     gives way instead; the flag beside it still says where. */
  .gp-cell > span {
    max-width: 5.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Half the width each, side by side, rather than one pill per line eating
     two rows of a small screen. A driver with nobody above or below them takes
     the row on their own instead of leaving half of it empty. */
  .neighbours {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 0.4rem;
  }
  .neighbours .pill { min-width: 0; }
  .neighbours .ident { min-width: 0; }

  /* The arrow, the face, the code and the gap are all fixed and worth more
     than the surname, so the name is what gives way. Everything beside it has
     to be told not to shrink, or a flex row shares the shortfall out and the
     portrait comes back a squashed oval. */
  .neighbours .avatar,
  .neighbours .logo,
  .neighbours .code,
  .neighbours .pill > .muted { flex: none; }
  .neighbours .ident-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .profile-hero { --lean: 12px; min-height: 128px; padding: 0.75rem 0 0 1.1rem; }
  .profile-name { font-size: 1.35rem; }
  .profile-pts { font-size: 1.6rem; }
  .profile-img { height: 128px; }
}

/* Matrix cells carry their detail in a tooltip, so say so with the cursor. */
.standings td.cell[title] { cursor: help; }
.standings td.pts[title] { cursor: help; }
