/* =====================================================================
   COMPONENTS
   Reusable UI building blocks. Every rule references design tokens
   from style.css (:root) — never raw values.
   Naming: BEM  →  .block  .block__element  .block--modifier
   ===================================================================== */

/* ---- Icon ------------------------------------------------------------
   Named inline SVGs via partials/components/icon. Inherit currentColor.
   ---------------------------------------------------------------------- */
.icon {
  display: inline-block;
  flex: 0 0 auto;
  vertical-align: middle;
}

/* ---- Navbar ----------------------------------------------------------
   Full-width, transparent. Inner content capped at 1920px and centered.
   Partial: partials/components/navbar
   ---------------------------------------------------------------------- */
/* Outer wrapper: 16px padding on top/left/right (no bottom). Holds the fixed/
   sticky positioning on the pages that use it. */
.navbar-wrap {
  padding: var(--space-4) var(--space-4) 0; /* 16px top · 16px left/right · 0 bottom */
  transition: background 0.2s ease;
}
/* Once the page is scrolled, fade the top of the page behind the navbar:
   gray-950 (opaque) at the top → gray-950 (transparent) at the bottom. */
.navbar-wrap--scrolled {
  /* Solid gray-950 for the first 16px, then fade to transparent */
  background: linear-gradient(to bottom, rgba(15, 16, 17, 1) 0, rgba(15, 16, 17, 1) 16px, rgba(15, 16, 17, 0) 100%);
}
.navbar {
  background: transparent;
  border: 1px solid transparent; /* transparent at top; colored when scrolled (no layout shift) */
  border-radius: 4px;
  transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
/* Once the page is scrolled, give the navbar a solid background + border + shadow */
.navbar--scrolled {
  background: var(--gray-850);
  border-top-color: rgba(255, 255, 255, 0.04); /* white @ 4% */
  border-bottom-color: var(--gray-950);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}
.navbar__inner {
  max-width: 1920px;
  margin: 0 auto;
  padding: var(--space-4) var(--space-6) 17px; /* 16px top · 24px horizontal · 17px bottom (navbar 1px taller) */
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* logo · centered links · actions */
  align-items: center;
  gap: var(--space-6);
}
.navbar__left { justify-self: start; display: flex; align-items: center; }
.navbar__center { justify-self: center; display: flex; align-items: center; }
.navbar__right {
  justify-self: end;
  width: 202px; /* same width as the logo */
  display: flex;
  align-items: center;
  justify-content: flex-end; /* right-align the social icons */
}
.navbar__brand {
  display: inline-flex;
  align-items: center;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: var(--font-lg);
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text-primary);
  text-decoration: none;
}
.navbar__logo {
  display: block;
  height: 20px;
  width: auto;
}
.navbar__links {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  list-style: none;
  margin: 0;
  padding: 0;
}
.navbar__link {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 24px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.25px;
  color: #fff;
  text-decoration: none;
  transition: var(--transition);
}
.navbar__link:hover { color: var(--yellow-500); }
.navbar__link.is-active { color: var(--yellow-500); } /* current link — same as hover */
.navbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

/* Shrink the logo, nav links and social buttons when the navbar is scrolled.
   Logo scales from the left and social buttons from the right, so the outer
   spacing stays the same. */
.navbar__brand,
.navbar__center,
.navbar__actions {
  transition: transform 0.2s ease;
}
.navbar__brand { transform-origin: left center; }
.navbar__actions { transform-origin: right center; }
.navbar--scrolled .navbar__brand,
.navbar--scrolled .navbar__actions {
  transform: scale(0.84);
}
.navbar--scrolled .navbar__center {
  transform: scale(0.88);
}
/* Below 1140px wide the full-size navbar is crowded, so the logo, links and
   social buttons keep their smaller scrolled size even at the top of the page */
@media (max-width: 1139.98px) {
  .navbar__brand,
  .navbar__actions { transform: scale(0.84); }
  .navbar__center { transform: scale(0.88); }
  /* …and the links get more room so they never wrap: tighter gaps between
     the logo / links / social columns (24 → 8px) and between the links
     themselves (32 → 20px); link labels stay on one line */
  .navbar__inner { column-gap: var(--space-2); }
  .navbar__links { gap: var(--space-5); }
  .navbar__link { white-space: nowrap; }
}
/* Burger menu (below 1000px): the centred links and the social buttons are
   hidden and a burger button on the right opens a panel with the links and,
   below them, the social buttons. */
.navbar { position: relative; }
.navbar__burger.button, /* beats .button's own display */
.navbar__menu { display: none; }
@media (max-width: 999.98px) {
  .navbar__center,
  .navbar__right > .navbar__actions { display: none; }
  .navbar__right { grid-column: 3; } /* stays in the right column with the centre one gone */
  /* Icon button like the social buttons (button--ghost, --icon-only, --bare
     in navbar.ejs), at their size: 20px icon at the bar's 0.84 scale, from
     the right edge like .navbar__actions */
  .navbar__burger.button {
    display: inline-flex;
    transform: scale(0.84);
    transform-origin: right center;
  }
  .navbar__burger-icon { display: inline-flex; }
  .navbar__burger-icon--close,
  .navbar--menu-open .navbar__burger-icon--open { display: none; }
  .navbar--menu-open .navbar__burger-icon--close { display: inline-flex; }
  /* With the menu open the bar takes its solid scrolled look */
  .navbar--menu-open {
    background: var(--gray-850);
    border-top-color: rgba(255, 255, 255, 0.04);
    border-bottom-color: var(--gray-950);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  }
  .navbar__menu:not([hidden]) {
    display: block;
    position: absolute;
    top: 100%;
    left: -1px;
    right: -1px;
    padding: var(--space-2) var(--space-6) var(--space-6);
    background: var(--gray-850);
    border: 1px solid var(--gray-950);
    border-top: 0;
    border-radius: 0 0 4px 4px;
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.32);
  }
  .navbar__menu-links {
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .navbar__menu-links li + li { border-top: 1px solid var(--gray-800); }
  .navbar__menu-link {
    display: block;
    padding: var(--space-3) 0;
    font-size: 16px;
    line-height: 24px;
  }
  .navbar__menu-actions {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    margin-top: var(--space-4);
    padding-top: var(--space-5);
    border-top: 1px solid var(--gray-800);
  }
}
@media (max-width: 999.98px) and (prefers-reduced-motion: no-preference) {
  .navbar__menu:not([hidden]) { animation: fade-in 0.2s ease-out both; }
}
/* (Below 1000px the links and social buttons live in the burger menu, so
   the bar only holds the logo and the burger; its right column hugs the
   button instead of matching the logo's 202px) */
@media (max-width: 999.98px) {
  .navbar__right { width: auto; }
}

/* Page-load intro: logo and social icons fade in, then the nav links
   drop in together from 24px above while fading in. Animates the
   inner elements, not .navbar__brand / __center / __actions, so the
   scrolled-state scale transforms stay untouched — and the <li>s rather than
   .navbar__links, whose translateY is driven by the scroll script in
   home-v2.ejs (a filled animation there would override it). */
@media (prefers-reduced-motion: no-preference) {
  .navbar__logo,
  .navbar__actions > * {
    animation: fade-in 0.6s ease-out 0.1s both;
  }
  .navbar__links > li {
    animation: nav-link-in 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.6s both;
  }
}
@keyframes nav-link-in {
  from { opacity: 0; transform: translateY(calc(-1 * var(--space-6))); } /* -24px */
  to   { opacity: 1; transform: none; }
}

/* ---- TabBar ----------------------------------------------------------
   Horizontal row of tab links. Partial: partials/components/tabbar
   ---------------------------------------------------------------------- */
.tabbar__list {
  display: flex;
  align-items: center;
  gap: var(--space-8); /* 32px between tabs */
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Compact variant — wrap the tabbar in .tabbar--compact for a 20px gap */
/* Tabs with a shortLabel: full label normally, the short one below 800px */
.tabbar__label-short { display: none; }
@media (max-width: 799.98px) {
  .tabbar__label-full { display: none; }
  .tabbar__label-short { display: inline; }
}
.tabbar--compact .tabbar__list { gap: var(--space-5); /* 20px */ }
.tabbar__tab {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;      /* same as navbar links */
  line-height: 24px;    /* same as navbar links */
  font-weight: 400;     /* regular */
  text-transform: uppercase;
  color: #fff;          /* default */
  text-decoration: none;
  transition: var(--transition);
}
.tabbar__tab:hover,
.tabbar__tab.is-active {
  color: var(--yellow-500); /* hover + current */
}

/* ---- EventBanner -----------------------------------------------------
   TabBar on top of a bordered panel. Partial: partials/components/event-banner
   ---------------------------------------------------------------------- */
.event-banner {
  display: flex;
  flex-direction: column;
  gap: var(--space-12); /* 48px between tab bar and panel */
}
/* Page-load intro in the hero: slides up 48px from below while fading in,
   alongside the navbar intro */
@media (prefers-reduced-motion: no-preference) {
  .hero .event-banner {
    animation: event-banner-in 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.3s both;
  }
  /* Tabs: like the navbar links, one block moving 24px — here up from below —
     while fading in, on top of the banner's own slide */
  .hero .event-banner .tabbar__list {
    animation: event-tabs-in 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.6s both;
  }
  /* Red accent lines: once the banner has risen, each glides in along its
     own 45° axis while fading in — the top-right line up from the banner's
     bottom, the bottom-left line down from the banner's top */
  .hero .event-banner__line--tr {
    animation: event-line-tr-in 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.8s both;
  }
  .hero .event-banner__line--bl {
    animation: event-line-bl-in 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.8s both;
  }
  /* Car: drives in diagonally from the bottom left along its 45° heading
     (same direction as the top-right line), fading in */
  .hero .event-content__car {
    animation: event-car-in 1.3s cubic-bezier(0.22, 1, 0.36, 1) 0.3s both;
  }
  /* Scroll indicator below the banner fades in last (opacity only, so its
     centring transform is untouched) */
  .hero__scroll {
    animation: fade-in 0.6s ease-out 1s both;
  }
}
/* Start/end transforms repeat the lines' resting transforms
   (.event-banner__line--tr / --bl) plus a 160px diagonal offset */
@keyframes event-line-tr-in {
  from { opacity: 0; transform: translate(calc(-50% + 200px - 160px), calc(-50% - 4px + 160px)) rotate(-45deg); }
  to   { opacity: 1; transform: translate(calc(-50% + 200px), calc(-50% - 4px)) rotate(-45deg); }
}
@keyframes event-line-bl-in {
  from { opacity: 0; transform: translate(calc(-50% - 200px + 160px), calc(50% + 4px - 160px)) rotate(-45deg); }
  to   { opacity: 1; transform: translate(calc(-50% - 200px), calc(50% + 4px)) rotate(-45deg); }
}
/* Repeats .event-content__car's resting transform plus a 64px diagonal offset */
@keyframes event-car-in {
  from { opacity: 0; transform: translate(calc(-50% - 64px), calc(-50% + 64px)) rotate(45deg); }
  to   { opacity: 1; transform: translate(-50%, -50%) rotate(45deg); }
}
@keyframes event-tabs-in {
  from { opacity: 0; transform: translateY(var(--space-6)); } /* 24px */
  to   { opacity: 1; transform: none; }
}
@keyframes event-banner-in {
  from { opacity: 0; transform: translateY(var(--space-12)); } /* 48px */
  to   { opacity: 1; transform: none; }
}
.event-banner .tabbar__list {
  justify-content: center; /* center the tabs above the panel */
}
/* Below 1140px the tabs shrink like the main nav links (0.88). Uses the
   separate `scale` property, so it combines with the tabs' intro animation,
   which drives `transform`. */
@media (max-width: 1139.98px) {
  .event-banner .tabbar__list { scale: 0.88; }
}
/* A 32px gray-750 line at the far left and right of the tab row, vertically
   centred on the tabs — like the About section title (.content-header--lines) */
.event-banner .tabbar { position: relative; }
.event-banner .tabbar::before,
.event-banner .tabbar::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 32px;
  height: 1px;
  background: var(--gray-750);
  pointer-events: none;
}
.event-banner .tabbar::before { left: 0; }
.event-banner .tabbar::after { right: 0; }
/* Tabs never wrap or squeeze: each label stays on one line */
.event-banner .tabbar__list > li { flex-shrink: 0; }
.event-banner .tabbar__tab { white-space: nowrap; }
/* When the tabs don't fit between the side lines (.is-scrolling, set by
   home-v2.ejs from the measured widths), the lines go and the tab row
   scrolls sideways instead, starting at the left edge (scaled from the
   left, so nothing is pushed out of reach); no visible scrollbar */
.event-banner .tabbar.is-scrolling {
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.event-banner .tabbar.is-scrolling::-webkit-scrollbar { display: none; }
.event-banner .tabbar.is-scrolling::before,
.event-banner .tabbar.is-scrolling::after { display: none; }
.event-banner .tabbar.is-scrolling .tabbar__list {
  justify-content: flex-start;
  width: max-content;
  transform-origin: left center;
}
.event-banner__panel {
  position: relative;
  height: 180px;
  padding: var(--space-2); /* 8px */
  background: var(--gray-900);
  border: 1px solid var(--gray-850);
}
.event-banner__inner {
  position: relative;
  height: 100%;
  background-color: var(--gray-800);
  background-image: url('/assets/event-stripes-l.svg'), url('/assets/event-stripes-r.svg'), url('/assets/events-shadow.svg');
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-position: left center, right center, center center;
}
/* 64px × 1px lines, rotated -45°, centered on an edge, offset from center;
   fading out to transparent towards both ends, like the hero's centre line */
.event-banner__line {
  position: absolute;
  left: 50%;
  width: 64px;
  height: 1px;
  background: linear-gradient(to right, rgba(255, 27, 78, 0), var(--red-500) 30%, var(--red-500) 70%, rgba(255, 27, 78, 0));
  transform-origin: center;
  pointer-events: none;
}
/* top edge, 200px right of center, nudged 4px up */
.event-banner__line--tr {
  top: 0;
  transform: translate(calc(-50% + 200px), calc(-50% - 4px)) rotate(-45deg);
}
/* bottom edge, 200px left of center, nudged 4px down */
.event-banner__line--bl {
  bottom: 0;
  transform: translate(calc(-50% - 200px), calc(50% + 4px)) rotate(-45deg);
}

/* Glass shard (50 × 38px, ≈ 34% of its source), centred on the page in the
   gap between the event banner and the news cards: the banner's panel ends
   744px down and the news cards start 848px down, so the gap's middle is
   796px — 61px below the bottom of the banner's inner surface (735px), which
   it is positioned from. Paints over the News section (the hero sits above
   it). */
.event-banner__shard {
  position: absolute;
  left: 50%;
  top: calc(100% + 61px);
  width: 50px;
  height: 38px;
  transform: translate(-50%, -50%);
  z-index: 1;
  pointer-events: none;
}

/* Event content inside the inner surface — 3 equal columns, no gap:
   left info · middle car · right logo */
.event-content {
  display: none;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  align-items: center;
  height: 100%;
}
.event-content.is-active { display: grid; }
/* Tab switch (driven by home-v2.ejs): the outgoing panel's info and logo fade
   out, then the incoming panel's fade in */
.event-content__info,
.event-content__logo { transition: opacity 0.2s ease-in; }
.event-content.is-leaving .event-content__info,
.event-content.is-leaving .event-content__logo { opacity: 0; }
.event-content.is-entering .event-content__info,
.event-content.is-entering .event-content__logo { animation: fade-in 0.35s ease-out both; }
/* The car fades out too. Done as an animation (not opacity) because the
   hero's filled event-car-in animation would otherwise hold it at opacity 1;
   the incoming car then drives in again via event-car-in. */
.event-content.is-leaving .event-content__car { animation: event-car-out 0.2s ease-in forwards; }
/* On a tab switch the incoming car drives in straight away (no page-load delay) */
.event-content.is-entering .event-content__car { animation-delay: 0s; }
/* Accent lines on tab switch: slide back out along their 45° axis (the way
   they came in), then in again. Beats the hero's intro animation by
   specificity; switching animation names restarts them. */
.event-banner.is-lines-out .event-banner__line--tr { animation: event-line-tr-out 0.2s ease-in both; }
.event-banner.is-lines-out .event-banner__line--bl { animation: event-line-bl-out 0.2s ease-in both; }
.event-banner.is-lines-in .event-banner__line--tr { animation: event-line-tr-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) both; }
.event-banner.is-lines-in .event-banner__line--bl { animation: event-line-bl-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes event-line-tr-out {
  from { opacity: 1; transform: translate(calc(-50% + 200px), calc(-50% - 4px)) rotate(-45deg); }
  to   { opacity: 0; transform: translate(calc(-50% + 200px - 160px), calc(-50% - 4px + 160px)) rotate(-45deg); }
}
@keyframes event-line-bl-out {
  from { opacity: 1; transform: translate(calc(-50% - 200px), calc(50% + 4px)) rotate(-45deg); }
  to   { opacity: 0; transform: translate(calc(-50% - 200px + 160px), calc(50% + 4px - 160px)) rotate(-45deg); }
}
@keyframes event-car-out {
  from { opacity: 1; transform: translate(-50%, -50%) rotate(45deg); }
  to   { opacity: 0; transform: translate(-50%, -50%) rotate(45deg); } /* resting transform of .event-content__car */
}
.event-content__visual {
  position: relative;
  z-index: 1;
  height: 100%;
}
/* Absolutely centered so it doesn't stretch the row/column height */
/* Optional round before the event name, set off by a dash */
.event-content__round::after { content: ' \2013\00a0'; } /* " – " */
.event-content__round-short { display: none; }
@media (max-width: 999.98px) {
  .event-content__round-long { display: none; }
  .event-content__round-short { display: inline; }
}
/* Wider screens: "RD" only when "Round" would truncate the name (set by JS) */
.event-content__name.is-round-short .event-content__round-long { display: none; }
.event-content__name.is-round-short .event-content__round-short { display: inline; }
.event-content__car {
  position: absolute;
  top: 50%;
  left: 50%;
  height: 248px;
  width: auto;
  transform: translate(-50%, -50%) rotate(45deg);
  pointer-events: none;
}
.event-content__info {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;   /* vertically center content in the column */
  align-self: stretch;       /* fill the row height so centering has room */
  padding: 0 var(--space-8) var(--space-2); /* 0 top · 32px sides · 8px bottom */
}
.event-content__meta { margin-top: var(--space-1\.5); }      /* 6px below the name */
.event-content__info > .button { margin-top: var(--space-4); } /* 16px above the button */
.event-content__meta {
  display: flex;
  align-items: center;
  gap: var(--space-3); /* 12px between flag and date */
}
.event-content__flag-wrap {
  display: inline-flex;
  flex: 0 0 auto;
  /* 12px circle with a 1px white ring (like the lineup driver flag,
     .lineup-driver__flag-wrap). The 4:3 flag is cropped to fill it. */
  width: 12px;
  height: 12px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 1px #fff;
}
.event-content__flag {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover; /* crop the 4:3 flag to the circle, centred */
}
.event-content__date {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 20px;
  font-weight: 400; /* regular */
  text-transform: uppercase;
  text-align: left;
  color: var(--gray-400);
  min-width: 0;
  /* clamp to a single line with ellipsis, cut mid-word */
  word-break: break-all;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.event-content__name {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 20px;
  line-height: 32px;
  font-weight: 600; /* semi bold */
  text-transform: uppercase;
  text-align: left;
  color: #fff;
  /* clamp to a single line with ellipsis, cut mid-word ("SPA-FRANCORCH…")
     rather than wrapping the whole word away at the hyphen */
  word-break: break-all;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.event-content__logo {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.event-content__logo img {
  display: block;
  width: 248px;
  height: 124px;
  object-fit: contain;
}
/* Decorative L-shaped corner brackets */
.event-banner__corner {
  position: absolute;
  width: 32px;
  height: 32px;
  pointer-events: none;
}
.event-banner__corner--tl {
  top: 0;
  left: 0;
  border-top: 2px solid var(--red-500);
  border-left: 2px solid var(--red-500);
}
.event-banner__corner--tr {
  top: 0;
  right: 0;
  border-top: 2px solid var(--red-500);
  border-right: 2px solid var(--red-500);
}
.event-banner__corner--bl {
  bottom: 0;
  left: 0;
  border-bottom: 2px solid var(--red-500);
  border-left: 2px solid var(--red-500);
}
.event-banner__corner--br {
  bottom: 0;
  right: 0;
  border-bottom: 2px solid var(--red-500);
  border-right: 2px solid var(--red-500);
}

/* ---- Page shell (pinned title bar, no rubberbanding) -----------------
   For pages whose navbar stays put while the page scrolls (imprint, admin).
   Instead of a sticky navbar inside the document scroll — which macOS drags
   along during the overscroll bounce — the body itself never scrolls: it is a
   flex column with the navbar as a fixed row and a separate scroll container
   below it. The scroller reaches back up behind the navbar (negative margin +
   matching padding) so content still slides underneath and fades out beneath
   the navbar's gradient.
   Usage: <body class="page-shell"> navbar … <div class="page-scroll"> … </div>
   ---------------------------------------------------------------------- */
.page-shell {
  /* 16px wrap padding + 56px navbar inner + 2px borders */
  --navbar-h: 74px;
  height: 100dvh;
  min-height: 0; /* beat the base body { min-height: 100vh } */
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.page-shell > .navbar-wrap {
  position: relative; /* paint above the scroll container */
  z-index: 100;
  flex: 0 0 auto;
}
.page-shell > .page-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  /* 'contain', not 'none': keeps the container's own overscroll bounce (the
     navbar sits outside it, so it no longer rides along) while stopping the
     scroll from chaining out to the document. */
  overscroll-behavior: contain;
  scroll-behavior: smooth;   /* this is the scroller now, not <html> */
  /* Extend up behind the navbar, then push the content back down */
  margin-top: calc(-1 * var(--navbar-h));
  padding-top: var(--navbar-h);
}

/* ---- contentWrapper --------------------------------------------------
   Centered max-width layout container.
   Partial: partials/components/content-wrapper (or apply .content-wrapper directly)
   ---------------------------------------------------------------------- */
.content-wrapper {
  width: 100%;
  max-width: 1260px;
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--space-10);  /* 40px */
  padding-right: var(--space-10);
}

/* ---- Button (current) ------------------------------------------------
   Variants: primary | outlined. One size for now.
   Partial: partials/components/button
   ---------------------------------------------------------------------- */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-xs);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 20px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.25px;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition);
}

/* Primary */
.button--primary {
  background: var(--red-500);
  border-color: var(--red-500);
  color: #fff;
}
.button--primary:hover,
.button--primary.is-hover {
  background: var(--red-450);
  border-color: var(--red-450);
  color: #fff;
}
.button--primary:active,
.button--primary.is-active {
  background: var(--red-550);
  border-color: var(--red-550);
  color: #fff;
}

/* Outlined */
.button--outlined {
  background: transparent;
  border-color: var(--red-500);
  color: var(--red-500);
}
.button--outlined:hover,
.button--outlined.is-hover {
  background: var(--red-500);
  color: #fff;
}
.button--outlined:active,
.button--outlined.is-active {
  background: var(--red-550);
  border-color: var(--red-550);
  color: #fff;
}

/* Ghost */
.button--ghost {
  background: transparent;
  border-color: transparent;
  color: #fff;
}
.button--ghost:hover,
.button--ghost.is-hover {
  background: var(--red-500);
  color: #fff;
}
.button--ghost:active,
.button--ghost.is-active {
  background: var(--red-550);
  color: #fff;
}

/* Focus ring (keyboard focus + forced .is-focus for the styleguide) */
.button:focus-visible,
.button.is-focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 27, 78, 0.45);
}

/* Disabled */
.button:disabled,
.button.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
  box-shadow: none;
}

/* Icon support (left / right / icon-only) */
.button__icon {
  display: inline-flex;
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
}
.button__icon svg {
  display: block;
  width: 100%;
  height: 100%;
}
.button--icon-only {
  padding: var(--space-2); /* 16px icon + 8px = 32px square */
}

/* Bare — no padding, background or border; purely the icon.
   Rest color comes from the variant; hover shifts to the accent. */
.button--bare {
  padding: 0;
  background: transparent;
  border-color: transparent;
}
.button--bare:hover,
.button--bare.is-hover,
.button--bare:active,
.button--bare.is-active {
  background: transparent;
  border-color: transparent;
  color: var(--red-500);
}
/* Bare has no padding, so the icon size is the button size (20×20) */
.button--bare .button__icon {
  width: 20px;
  height: 20px;
}

/* ---- Button — OUTDATED ----------------------------------------------
   ⚠️ Kept temporarily for reference. Use `.button` above instead.
   Partial: partials/components/button-old
   ---------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: var(--font-md);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition);
}

.btn--primary {
  background: var(--accent-primary);
  color: #fff;
}
.btn--primary:hover {
  background: var(--accent-primary-hover);
}

.btn--ghost {
  background: transparent;
  border-color: var(--border-color);
  color: var(--text-primary);
}
.btn--ghost:hover {
  border-color: var(--border-hover);
}

.btn--sm { padding: var(--space-2) var(--space-4); font-size: var(--font-sm); }
.btn--lg { padding: var(--space-4) var(--space-8); font-size: var(--font-lg); }

/* ---- Hero ------------------------------------------------------------ */
/* ---- Page section ----------------------------------------------------
   Full-width section with a centered ContentWrapper. Shared by the News,
   Lineup, Achievements, About and Contact sections.
   Partials: partials/components/*-section
   ---------------------------------------------------------------------- */
.page-section {
  width: 100%;
  background: var(--gray-900);
}
.page-section--contact {
  padding-bottom: 0; /* social cards sit directly on the footer */
}
.page-section--imprint {
  padding-bottom: var(--space-16); /* 64px above the footer */
}

/* ---- Imprint (legal) content ----------------------------------------- */
.imprint {
  max-width: none; /* full ContentWrapper width, same as the contact section */
}
.imprint__heading {
  margin: var(--space-8) 0 var(--space-3); /* 32px top · 12px bottom */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
  color: #fff;
}
.imprint__subheading {
  margin: var(--space-6) 0 var(--space-2); /* 24px top · 8px bottom */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 22px;
  font-weight: 600;
  color: var(--gray-300);
}
.imprint__text {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 24px;
  font-weight: 400;
  color: var(--gray-400);
}

/* ---- Form field ------------------------------------------------------
   Label above an input/textarea. Partial: partials/components/form-field
   ---------------------------------------------------------------------- */
.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
/* Label row: label on the left, optional action (e.g. a text link) on the right */
.form-field__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.form-field__label {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 16px;
  font-weight: 400;
  letter-spacing: 0.25px;
  text-transform: uppercase;
  color: var(--gray-400);
}
/* Scroll reveal (driven by home-v2.ejs on the contact form): labels fade in
   0.3s after they are fully in view */
[data-label-reveal] .form-field__label {
  opacity: 0;
  transition: opacity 0.6s ease-out calc(300ms + var(--label-delay, 0ms));
}
[data-label-reveal] .form-field__label.is-revealed { opacity: 1; }
.form-field__action {
  flex: 0 0 auto;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.25px;
  text-transform: uppercase;
  color: var(--gray-500);
  text-decoration: underline;
  transition: color 0.15s ease;
}
.form-field__action:hover { color: var(--red-500); }
/* Live character counter, e.g. "1420 / 2000" on a field with maxlength.
   Turns red in the last 10% so the visitor sees the limit before hitting it. */
.form-field__counter {
  flex: 0 0 auto;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.25px;
  font-variant-numeric: tabular-nums;
  color: var(--gray-500);
  transition: color 0.15s ease;
}
.form-field__counter.is-near-limit { color: var(--red-500); }
.form-field__control {
  width: 100%;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  color: #fff;
  background: rgba(17, 18, 19, 0.64); /* --gray-900 (#111213) at 64% opacity */
  border: 1px solid var(--gray-850);
  border-radius: var(--radius-xs);
  padding: 12px 16px;
  outline: none;
  transition: border-color 0.15s ease;
}
.form-field__control::placeholder { color: var(--gray-700); }
.form-field__control:hover,
.form-field__control:focus { border-color: var(--red-500); }
/* Hovering the input highlights its label (only the input, not the label) */
.form-field:has(.form-field__control:hover) .form-field__label { color: #fff; }
textarea.form-field__control { resize: vertical; min-height: 120px; }

/* Contact form spam decoys. Positioned off-screen rather than display:none —
   bots filter out display:none inputs but happily fill off-screen ones, so
   this is what actually catches them. body already sets overflow-x: hidden, so
   the negative offsets can't produce a scrollbar. */
.form-honeypot {
  position: absolute !important;
  left: -9999px !important;
  top: -9999px !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---- Dropdown --------------------------------------------------------
   Toggle button + our own option menu, value held in a hidden input.
   Partial: partials/components/dropdown · behaviour: /js/dropdown.js
   ---------------------------------------------------------------------- */
.dropdown { position: relative; }
.dropdown__toggle {
  /* Same box as .form-field__control, so it lines up with the other fields */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  padding: 12px 16px;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
  text-align: left;
  color: #fff;
  background: rgba(17, 18, 19, 0.64); /* --gray-900 at 64% */
  border: 1px solid var(--gray-850);
  border-radius: var(--radius-xs);
  cursor: pointer;
  outline: none;
  transition: border-color 0.15s ease;
}
.dropdown__toggle:hover,
.dropdown__toggle:focus-visible,
.dropdown.is-open .dropdown__toggle { border-color: var(--red-500); }
.dropdown__toggle:disabled { cursor: not-allowed; color: var(--gray-700); }
.dropdown__value {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropdown__value.is-placeholder { color: var(--gray-700); }
/* Flag SVGs carry a viewBox but no intrinsic size, so width alone sets the scale */
.dropdown__flag {
  flex: 0 0 auto;
  width: 20px;
  height: auto;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18);
}
.dropdown__chevron {
  flex: 0 0 auto;
  display: flex;
  color: var(--gray-500);
  transition: color 0.15s ease, transform 0.15s ease;
}
.dropdown__toggle:hover .dropdown__chevron { color: #fff; }
.dropdown.is-open .dropdown__chevron { transform: rotate(180deg); color: #fff; }

.dropdown__menu {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  right: 0;
  z-index: 20;
  padding: var(--space-1);
  background: var(--gray-800);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-xs);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.48);
}
.dropdown__menu[hidden] { display: none; }

/* Only the option list scrolls, so a search box above it stays put. */
.dropdown__options {
  max-height: calc(36px * 7.5); /* 7½ of the 36px rows: the last visible one is cut through its middle, a hint that the list scrolls */
  overflow-y: auto;
  padding-right: var(--space-1); /* 4px between the options and the scrollbar */
}
.dropdown__options::-webkit-scrollbar { width: 6px; }
.dropdown__options::-webkit-scrollbar-track { background: transparent; }
.dropdown__options::-webkit-scrollbar-thumb { background: var(--gray-750); border-radius: var(--radius-xs); }

.dropdown__search { padding: var(--space-1); border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
.dropdown__search-input {
  width: 100%;
  padding: 8px 10px;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 13px;
  line-height: 18px;
  color: #fff;
  background: rgba(17, 18, 19, 0.64);
  border: 1px solid var(--gray-850);
  border-radius: var(--radius-xs);
  outline: none;
}
.dropdown__search-input::placeholder { color: var(--gray-700); }
.dropdown__search-input:focus-visible { border-color: var(--red-500); }
/* Hide the native clear affordance; it fights with the option list on dark UI */
.dropdown__search-input::-webkit-search-cancel-button { display: none; }

.dropdown__empty {
  margin: 0;
  padding: var(--space-3);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 13px;
  text-align: center;
  color: var(--gray-700);
}
.dropdown__empty[hidden] { display: none; }

.dropdown__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
  text-align: left;
  color: #fff;
  background: none;
  border: none;
  border-radius: var(--radius-xs);
  cursor: pointer;
  outline: none;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.dropdown__option:hover,
.dropdown__option:focus-visible { background: rgba(255, 255, 255, 0.08); }
/* Filtered out by the search box — needs to beat the display:flex above */
.dropdown__option.is-hidden { display: none; }
.dropdown__option-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dropdown__option-label.is-placeholder { color: var(--gray-700); }
.dropdown__option-check {
  flex: 0 0 auto;
  display: flex;
  color: var(--red-500);
  opacity: 0;
}
.dropdown__option.is-selected .dropdown__option-check { opacity: 1; }

/* Select: native control with our own chevron. Partial: partials/components/select */
.select { position: relative; }
.select__control {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--space-10); /* room for the chevron */
  cursor: pointer;
}
.select__control option {
  background: var(--gray-850);
  color: #fff;
}
.select__chevron {
  position: absolute;
  top: 50%;
  right: var(--space-3);
  transform: translateY(-50%);
  display: flex;
  color: var(--gray-500);
  pointer-events: none;
  transition: color 0.15s ease;
}
.select:hover .select__chevron { color: #fff; }

/* File input: the native "Choose file" button styled like an outlined button */
input[type="file"].form-field__control { padding: var(--space-2); cursor: pointer; }
input[type="file"].form-field__control::file-selector-button {
  margin-right: var(--space-4);
  padding: var(--space-2) var(--space-4);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 13px;
  line-height: 20px;
  color: #fff;
  background: transparent;
  border: 1px solid var(--gray-750);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: border-color 0.15s ease;
}
input[type="file"].form-field__control:hover::file-selector-button { border-color: var(--red-500); }

/* ---- Form layout -----------------------------------------------------
   The vertical rhythm every form built from these components shares: put
   .form-fields on the <form> (or any wrapper) and .form-fields__row around
   fields that sit side by side.
   ---------------------------------------------------------------------- */
.form-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-6); /* 24px between fields */
}
.form-fields__row {
  display: flex;
  gap: var(--space-10); /* 40px between fields on one line */
}
/* Contact form below 800px: Email address moves under Name (one column,
   with the form's usual 24px between fields) */
@media (max-width: 799.98px) {
  .contact-form-ds .form-fields__row {
    flex-direction: column;
    gap: var(--space-6);
  }
}
.form-fields__row > .form-field {
  flex: 1;
  min-width: 0;
}

/* ---- Calendar --------------------------------------------------------
   Month grid modelled on the macOS system date picker: month + year on the
   left, prev / today / next on the right, weekday row, fixed six-week grid.
   Partial: partials/components/calendar · behaviour: /js/calendar.js
   ---------------------------------------------------------------------- */
.calendar {
  display: inline-block;
  padding: var(--space-3);
  background: var(--gray-800);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px; /* macOS popover corner */
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.48);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Bai Jamjuree', sans-serif;
  user-select: none;
}
.calendar__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-1) var(--space-1) var(--space-2);
}
.calendar__title {
  font-size: 13px;
  line-height: 20px;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
}
.calendar__nav {
  display: flex;
  align-items: center;
  gap: var(--space-0\.5);
}
.calendar__nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  color: var(--gray-400);
  background: none;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: color 0.12s ease, background-color 0.12s ease;
}
.calendar__nav-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.08); }
.calendar__nav-btn:disabled { color: var(--gray-750); cursor: default; background: none; }
/* The small dot between the arrows jumps back to today (as on macOS) */
.calendar__today-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.calendar__weekdays,
.calendar__grid {
  display: grid;
  grid-template-columns: repeat(7, 32px);
  gap: 2px;
}
.calendar__weekday {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 22px;
  font-size: 11px;
  line-height: 16px;
  font-weight: 500;
  color: var(--gray-600);
}
.calendar__day {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  font: inherit;
  font-size: 13px;
  line-height: 16px;
  color: #fff;
  background: none;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.calendar__day:hover { background: rgba(255, 255, 255, 0.08); }
.calendar__day.is-outside { color: var(--gray-700); }
/* Today: accent-coloured number, filled once it is also the selection */
.calendar__day.is-today { color: var(--red-500); font-weight: 600; }
.calendar__day.is-selected,
.calendar__day.is-selected.is-today {
  color: #fff;
  background: var(--red-500);
  font-weight: 600;
}
.calendar__day.is-selected:hover { background: var(--red-500); }
.calendar__day:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(255, 27, 78, 0.48);
}
.calendar__day.is-disabled,
.calendar__day:disabled {
  color: var(--gray-750);
  cursor: default;
  background: none;
}

/* ---- DatePicker ------------------------------------------------------
   Date input with a ghost icon button that opens the native calendar.
   Partial: partials/components/date-picker · behaviour: /js/date-picker.js
   ---------------------------------------------------------------------- */
.date-picker { position: relative; }
.date-picker__input { padding-right: 48px; } /* room for the button */
/* Hide the browser's own calendar icon — the ghost button replaces it */
.date-picker__input::-webkit-calendar-picker-indicator {
  opacity: 0;
  display: none;
}
.date-picker__input::-webkit-inner-spin-button,
.date-picker__input::-webkit-clear-button { display: none; }
.date-picker__button {
  position: absolute;
  top: 50%;
  right: var(--space-1);
  transform: translateY(-50%);
  display: flex;
}
/* Calendar popover, anchored under the right edge of the field */
.date-picker__popover {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 20;
}
.date-picker__popover[hidden] { display: none; }

/* ---- TimeList / TimePicker -------------------------------------------
   A list of times at a fixed step, shown in a popover from the field's ghost
   clock button — the same arrangement as Calendar + DatePicker.
   Partials: partials/components/time-list · time-picker
   Behaviour: /js/time-list.js · /js/time-picker.js
   ---------------------------------------------------------------------- */
.time-list {
  display: inline-block;
  padding: var(--space-1);
  background: var(--gray-800);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px; /* matches the calendar popover */
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.48);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Bai Jamjuree', sans-serif;
}
.time-list__options {
  display: flex;
  flex-direction: column;
  gap: 1px;
  width: 104px;
  max-height: 240px;
  overflow-y: auto;
}
.time-list__options::-webkit-scrollbar { width: 6px; }
.time-list__options::-webkit-scrollbar-track { background: transparent; }
.time-list__options::-webkit-scrollbar-thumb { background: var(--gray-750); border-radius: var(--radius-xs); }
.time-list__option {
  flex: 0 0 auto;
  padding: var(--space-1) var(--space-3);
  font: inherit;
  font-size: 13px;
  line-height: 22px;
  text-align: center;
  color: #fff;
  background: none;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.time-list__option:hover { background: rgba(255, 255, 255, 0.08); }
.time-list__option:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(255, 27, 78, 0.48);
}
.time-list__option.is-selected {
  color: #fff;
  font-weight: 600;
  background: var(--red-500);
}

.time-picker { position: relative; }
.time-picker__input { padding-right: 48px; } /* room for the button */
/* Hide the browser's own time indicator — the ghost button replaces it */
.time-picker__input::-webkit-calendar-picker-indicator {
  opacity: 0;
  display: none;
}
.time-picker__input::-webkit-inner-spin-button,
.time-picker__input::-webkit-clear-button { display: none; }
.time-picker__button {
  position: absolute;
  top: 50%;
  right: var(--space-1);
  transform: translateY(-50%);
  display: flex;
}
.time-picker__popover {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: 20;
}
.time-picker__popover[hidden] { display: none; }

/* ---- FileDrop --------------------------------------------------------
   Drag & drop upload zone that also opens the file picker on click.
   Partial: partials/components/file-drop · behaviour: /js/file-drop.js
   ---------------------------------------------------------------------- */
.file-drop {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  padding: var(--space-6);
  background: rgba(17, 18, 19, 0.64); /* --gray-900 at 64%, same as inputs */
  border: 1px dashed var(--gray-750);
  border-radius: var(--radius-xs);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.file-drop:hover,
.file-drop:focus-visible { border-color: var(--red-500); outline: none; }
.file-drop.is-dragging {
  border-color: var(--red-500);
  border-style: solid;
  background: rgba(255, 27, 78, 0.06);
}
/* The real input stays in the DOM (form submit + validation) but out of sight */
.file-drop__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.file-drop__prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  text-align: center;
  pointer-events: none; /* clicks belong to the zone */
}
.file-drop__icon { color: var(--gray-700); transition: color 0.15s ease; }
.file-drop:hover .file-drop__icon,
.file-drop.is-dragging .file-drop__icon { color: var(--red-500); }
.file-drop__text {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: var(--gray-400);
}
.file-drop__browse { color: var(--red-500); text-decoration: underline; }
.file-drop__hint {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 16px;
  color: var(--gray-700);
}
/* Selected state */
.file-drop__selected {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  max-width: 100%;
}
.file-drop__selected[hidden] { display: none; }
.file-drop__name {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.file-drop__clear {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-1);
  color: var(--gray-500);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.15s ease;
}
.file-drop__clear:hover { color: var(--red-500); }

/* ---- Checkbox & Radio ------------------------------------------------
   Custom box/dot with the label on the right. The native input stays in the
   DOM (form submit, validation, keyboard) but is visually hidden.
   Partials: partials/components/checkbox · partials/components/radio
   ---------------------------------------------------------------------- */
.check-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-6);
}
.check-group--stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
}

.check {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
  color: var(--gray-400);
  transition: color 0.15s ease;
  user-select: none;
}
.check:hover { color: #fff; }
.check__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}
.check__box {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  color: transparent; /* the check icon, revealed when checked */
  background: rgba(17, 18, 19, 0.64); /* --gray-900 at 64%, same as inputs */
  border: 1px solid var(--gray-750);
  border-radius: var(--radius-xs);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.check:hover .check__box { border-color: var(--red-500); }
.check__input:checked + .check__box {
  color: var(--gray-900);
  background: var(--red-500);
  border-color: var(--red-500);
}
.check__input:focus-visible + .check__box {
  border-color: var(--red-500);
  box-shadow: 0 0 0 2px rgba(255, 27, 78, 0.32);
}

/* Radio: round box with a dot instead of a checkmark */
.check--radio .check__box { border-radius: 50%; }
.check--radio .check__box::after {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gray-900);
  transform: scale(0);
  transition: transform 0.15s ease;
}
.check--radio .check__input:checked + .check__box::after { transform: scale(1); }

/* Disabled */
.check.is-disabled { cursor: not-allowed; color: var(--gray-700); }
.check.is-disabled:hover { color: var(--gray-700); }
.check.is-disabled .check__box { border-color: var(--gray-800); background: var(--gray-900); }
.check.is-disabled:hover .check__box { border-color: var(--gray-800); }
.check.is-disabled .check__input:checked + .check__box {
  background: var(--gray-750);
  border-color: var(--gray-750);
  color: var(--gray-900);
}

/* ---- Contact form ----------------------------------------------------
   Partial: partials/components/contact-form
   ---------------------------------------------------------------------- */
.contact-form-wrap {
  position: relative;
  width: 100%;
  padding: var(--space-8); /* 32px all around */
  background: var(--gray-850);
}
/* Glass shards (64 × 58px, 40% of their source) centred 20px left of the
   panel's left edge, mostly outside it, 144px below its vertical middle */
.contact-form-wrap__shards {
  position: absolute;
  left: -20px; /* 20px left */
  top: calc(50% + 144px); /* 144px down */
  width: 64px;
  height: 58px;
  /* scroll parallax (--parallax on .contact-form-wrap, 0 = resting): rises,
     grows and turns slightly clockwise as you scroll down */
  transform: translate(-50%, calc(-50% + var(--parallax, 0) * -32px))
             scale(calc(1 + var(--parallax, 0) * 0.16))
             rotate(calc(var(--parallax, 0) * 16deg)); /* ≈ −20° → +12° */
  z-index: 1;
  pointer-events: none;
}

/* Social media cards below the contact form */
.social-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-5); /* 20px, same as the news cards */
  margin-top: var(--space-5);
}
.social-card {
  position: relative;
  display: block;
  text-decoration: none;
  color: var(--gray-600);
  transition: color 0.2s ease;
}
/* Red corner brackets — hidden until hover */
.social-card .ds-card__corner {
  opacity: 0;
  transition: opacity 0.2s ease;
}
.social-card:hover .ds-card__corner {
  opacity: 1;
}
/* Icon sits flush inside the card's image wrapper (striped-pattern block) */
.social-card .ds-card__content {
  padding: 0;
}
.social-card__image {
  display: flex;
  align-items: center;
  justify-content: center;
}
.social-card__icon {
  display: inline-flex;
  transition: transform 0.2s ease;
}
/* Below 800px the four cards become squares that shrink with the window
   (the image area takes the column width as its height instead of a fixed
   160px), with slightly smaller icons */
@media (max-width: 799.98px) {
  .social-card .social-card__image { height: auto; aspect-ratio: 1; }
  .social-card__icon svg { width: 28px; height: 28px; }
}
.social-card:hover .social-card__icon {
  transform: scale(1.1);
}
/* 2px outline around the icon shape in the card background color (gray-800),
   so the icon reads cleanly against the striped pattern */
.social-card__icon svg {
  paint-order: stroke;
  stroke: var(--gray-800);
  stroke-width: 8px;
  stroke-linejoin: round;
  overflow: visible; /* let the stroke paint beyond the 32×32 SVG box */
}
.social-card:hover { color: #fff; }

/* ---- Login page ------------------------------------------------------ */
.login-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8);
}
.login-card {
  width: 100%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding: var(--space-10); /* 40px */
  background: var(--gray-850);
  border-radius: var(--radius-sm);
}
.login-card__brand { display: inline-flex; align-self: center; margin-bottom: var(--space-2); /* +8px below the logo */ }
.login-card__logo { display: block; height: 20px; width: auto; }
.login-card__title {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 20px;
  line-height: 28px;
  font-weight: 600;
  text-transform: uppercase;
  color: #fff;
}
.login-card__error {
  font-size: 14px;
  line-height: 20px;
  color: var(--red-500);
  background: rgba(220, 0, 50, 0.08);
  border: 1px solid var(--red-500);
  border-radius: var(--radius-xs);
  padding: var(--space-3) var(--space-4);
}
.login-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
/* Full-width buttons within the login card */
.login-form .button,
.login-card > .button {
  width: 100%;
  justify-content: center;
}
/* Submit button: always shown, disabled until the form is ready
   (.is-ready added by contact-form.js). While disabled, hovering shows a
   tooltip with the reason — quickly, instead of the tooltip's usual 2s. The
   disabled button ignores the pointer, so the hover lands on the wrapper. */
/* Full width, and 46px tall like the inputs (.form-field__control: 12px
   padding + 20px line + 1px borders) */
.contact-form-ds__submit .tooltip { display: flex; }
.contact-form-ds__submit .tooltip > .button { flex: 1; padding-top: 12px; padding-bottom: 12px; }
.contact-form-ds__submit .tooltip:hover .tooltip__bubble { transition-delay: 0.2s; }
.contact-form-ds.is-ready .contact-form-ds__submit .tooltip__bubble { display: none; }
.contact-form-ds__submit .tooltip:has(.button:disabled) { cursor: not-allowed; }
/* Disabled look: gray outline instead of the faded red fill */
.contact-form-ds__submit .button:disabled {
  opacity: 1;
  background: transparent;
  border-color: var(--gray-750);
  color: var(--gray-700);
}
.form-message-ds {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 20px;
}
.form-message-ds:empty { display: none; }
.form-message-ds.is-success { color: #22c55e; }
.form-message-ds.is-error { color: var(--red-500); }

/* 3-column card grid (used in the News section) */
.news-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5); /* 20px */
}
/* Sliding news window: only items in the current window of 3 are shown */
.news-item { display: none; min-width: 0; }
.news-item.is-visible { display: block; }
/* Corner brackets follow the visible window's edges: hide all by default,
   reveal left brackets on the first visible item, right on the last. */
.news-item .ds-card__corner { display: none; }
/* Scroll reveal (driven by home-v2.ejs): the card's image and text fade in
   0.2s after the card comes into view, cards entering together 100ms apart.
   The card frame stays. */
[data-card-reveal] .news-item .ds-card__image,
[data-card-reveal] .news-item .ds-card__content {
  opacity: 0;
  transition: opacity 0.7s ease-out calc(200ms + var(--card-delay, 0ms));
}
[data-card-reveal] .news-item.is-revealed .ds-card__image,
[data-card-reveal] .news-item.is-revealed .ds-card__content { opacity: 1; }
.news-item.is-first .ds-card__corner--tl,
.news-item.is-first .ds-card__corner--bl,
.news-item.is-last .ds-card__corner--tr,
.news-item.is-last .ds-card__corner--br { display: block; }

.lineup-card {
  height: 592px;
}
/* Tiny splinter (18 × 29px, 50% of its source) just off the crystal's
   bottom-left corner: centred 10px beyond that corner (the crystal box is
   120 × 164px around the centre used in .lineup-layout__crystal) */
.lineup-layout__splinter {
  position: absolute;
  left: calc(100% - 0.5px - var(--space-4) - 60px - 10px - var(--space-4)); /* 16px further left by eye */
  top: calc(100% - 1px - var(--space-2) - 141px - var(--space-4) + 82px + 10px - 44px); /* 44px higher by eye */
  /* drifts up as you scroll, like the glass in the achievements header
     (--parallax set on .lineup-layout__main by home-v2.ejs; 0 = resting) */
  transform: translate(-50%, calc(-50% + var(--parallax, 0) * -40px));
  z-index: 3;
  width: 18px;
  height: 29px;
  pointer-events: none;
}
/* Glass shard (48 × 59px, 50% of its source) centred horizontally on the
   driver card's right info panel — the right half of the card's inner
   surface (inside the 1px border + 8px padding), whose content is centred
   with equal 48px side padding — and vertically on the card's bottom border,
   so half of it hangs below the card. */
.lineup-layout__main { position: relative; }
/* Crystal (120 × 164px, 50% of its source) centred on the driver card's right
   border, half over the card, and vertically on the card's bottom-right
   stripe triangle: along the right edge that triangle (lineup-stripes-r.svg,
   288px box, stripes from x + y ≈ 294) runs from 282px above the inner
   surface's bottom down to it → middle 141px up, + the 9px border/padding. */
.lineup-layout__crystal {
  position: absolute;
  left: calc(100% - 0.5px - var(--space-4)); /* the middle of the 1px right border, 16px left by eye */
  top: calc(100% - 1px - var(--space-2) - 141px - var(--space-4)); /* 16px higher by eye */
  /* scroll parallax (--parallax on .lineup-layout__main, 0 = resting): drifts
     diagonally up and right while growing slightly as you scroll down */
  transform: translate(calc(-50% + var(--parallax, 0) * 24px), calc(-50% + var(--parallax, 0) * -24px))
             scale(calc(1 + var(--parallax, 0) * 0.08));
  z-index: 3;
  width: 120px;
  height: 164px;
  pointer-events: none;
}
/* Glass shards (40 × 39px, ≈ 41% of their source) in the gap between the
   news cards and the driver card: vertically centred in it (the news cards
   end at the Lineup section's top, the card starts 104px below → 52px above
   the card), horizontally centred in the 20px gap between the first and
   second news card. Those are 3 columns of (W − 40) / 3 with 20px gaps, so
   that gap's middle is at (W − 40) / 3 + 10; the driver card starts at
   (W − 20) / 3 + 20 (1fr + 20px gap of the 1fr 2fr lineup grid) → always
   20 / 3 + 10 ≈ 16.67px left of the card's left edge. Then 2px higher. */
.lineup-layout__corner-shard {
  position: absolute;
  left: -16.67px;
  top: -54px;
  width: 40px;
  height: 39px;
  transform: translate(-50%, -50%) rotate(-6deg); /* tilted 6° counter-clockwise */
  z-index: 3;
  pointer-events: none;
  filter: brightness(0.75); /* a bit darker */
}
/* Glass shards (58 × 58px, 50% of their source) between the driver's head
   and the name: halfway between the head's right side (≈ 257px into the
   card) and the name's left edge (434px), level between the two (≈ 89px
   down), then 32px higher. The card is a fixed 773 × 592px, so plain pixel
   offsets hold. */
.lineup-layout__head-shard {
  position: absolute;
  left: 345px;
  top: 57px;
  width: 58px;
  height: 58px;
  /* tilted 4° clockwise; scroll parallax (--parallax on .lineup-layout__main,
     0 = resting): rises as you scroll down */
  transform: translate(-50%, calc(-50% + var(--parallax, 0) * -32px)) rotate(4deg);
  z-index: 3;
  pointer-events: none;
  filter: saturate(0.6); /* a bit less colourful */
}
.lineup-layout__shard {
  position: absolute;
  left: calc(1px + var(--space-2) + (100% - 2 * (1px + var(--space-2))) * 0.75 + var(--space-8)); /* +32px right */
  top: calc(100% - 0.5px - var(--space-2)); /* the middle of the 1px bottom border, 8px up */
  /* scroll parallax (--parallax on .lineup-layout__main, 0 = resting): drifts
     diagonally up and right while growing slightly as you scroll down */
  transform: translate(calc(-50% + var(--parallax, 0) * 16px), calc(-50% + var(--parallax, 0) * -16px))
             scale(calc(1 + var(--parallax, 0) * 0.1));
  z-index: 3;
  width: 48px;
  height: 59px;
  pointer-events: none;
}
/* Decorative diagonal stripes in the inner surface: left graphic pinned
   top-left, right graphic pinned bottom-right. */
.lineup-card .ds-card__inner {
  position: relative;
  overflow: hidden;
  background-image:
    url('/assets/lineup-stripes-l.svg'),
    url('/assets/lineup-stripes-r.svg');
  background-repeat: no-repeat, no-repeat;
  background-position: top left, bottom right;
}
/* Transparent variant — drop only the gray-800 fill; keep the diagonal stripes */
.lineup-card--transparent .ds-card__inner {
  background-color: transparent;
}

/* About card — two columns: big red headline (left) + body text (right) */
.about-card {
  height: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--space-12); /* 48px between headline and text */
  row-gap: var(--space-16); /* 64px between the headline/text row and the gallery */
  align-items: start;
  padding: var(--space-12); /* 48px */
  padding-top: 56px; /* above the headline (48px + 8px) */
}
.about-card__headline {
  display: flex;
  flex-direction: column;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 64px;
  line-height: 64px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--red-500);
  align-self: center; /* vertically centred against the text beside it */
}
/* Below 1080px wide: a bit smaller (64px → 56px type and lines), and the
   body text moves below the headline — one column, the text 24px under it
   (the grid's 64px row gap − 40px) */
@media (max-width: 1079.98px) {
  .about-card__headline { font-size: 56px; line-height: 56px; }
  .about-card { grid-template-columns: 1fr; padding-top: 44px; } /* 12px less above the headline (56px) */
  /* the headline's capitals end 7px above its box (56px type in 56px lines),
     the text's start 7.45px into its box: a 25px-shorter row gap (64 − 25 =
     39px of boxes) leaves the same ≈ 54px from the headline to the text as
     from the inner surface's top edge to the headline (44px padding + 9.8px
     to its caps) */
  .about-card__text { margin-top: -25px; }
  .about-video { margin-top: -12px; } /* 12px closer to the text (52px) */
}
/* Glass shards right of the headline, below 1080px only: centred in the space
   between the headline's right end ("PERFORMANCE" ends 467px into the card,
   407px below 960px) and the card's 48px right padding, and on the
   headline's height (it starts 44px down, 168px tall; 144px below 960px) */
.about-card { position: relative; }
.about-card__shard { display: none; }
@media (max-width: 1079.98px) {
  .about-card__shard {
    display: block;
    position: absolute;
    left: calc((467px + 100% - 48px) / 2 + 32px); /* centred, then 32px right */
    top: 128px;
    width: 192px;
    height: 128px;
    /* turned upside down, then 8° clockwise; scroll parallax (--parallax on
       .about-card, set by home-v2.ejs from the headline; 0 = resting): sinks
       and drifts right as you scroll down */
    transform: translate(calc(-50% + var(--parallax, 0) * 16px), calc(-50% + var(--parallax, 0) * 24px)) rotate(188deg);
    pointer-events: none;
  }
}
@media (max-width: 959.98px) {
  .about-card__shard { left: calc((407px + 100% - 48px) / 2 + 32px); top: 116px; }
}
/* …and below 960px: 48px */
@media (max-width: 959.98px) {
  .about-card__headline { font-size: 48px; line-height: 48px; }
}

.about-card__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-6); /* 24px between paragraphs */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 24px;
  font-weight: 400;
  color: #fff;
}
.about-card__text p { margin: 0; }
/* Below 1080px (text under the headline): the two paragraphs side by side,
   with the card's 48px column gap */
@media (max-width: 1079.98px) {
  .about-card__text {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--space-12);
  }
}
/* The about card grows with its content (the lineup card is fixed at 592px) */
.lineup-card:has(.about-card) { height: auto; }
/* Inner surface in gray-850 (like the achievements list's "and many more"
   row), under the corner stripe graphics */
.lineup-card:has(.about-card) .ds-card__inner { background-color: var(--gray-850); }
/* Image gallery below the headline + text, spanning both columns: a window
   of 3 images, slid by one with the prev/next button group below. */
/* YouTube video above the gallery: full card width, 16:9, on the gallery
   placeholders' gray-800; 20px above the gallery (the gallery's own image
   gap) instead of the card's 64px row gap */
.about-video {
  grid-column: 1 / -1;
  position: relative;
  aspect-ratio: 16 / 9;
  margin-bottom: calc(var(--space-5) - var(--space-16));
  background: var(--gray-800);
  overflow: hidden;
}
.about-video__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.about-gallery {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  gap: 28px; /* between images and buttons (20px image gap + 8px) */
}
.about-gallery__track {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5); /* 20px, like the news grid */
}
.about-gallery__item {
  display: none;
  min-width: 0;
  aspect-ratio: 16 / 10;
  background: var(--gray-800); /* placeholder fill, same as the news cards' surface (.ds-card__inner) */
  overflow: hidden;
}
.about-gallery__item.is-visible { display: block; }
.about-gallery__item { position: relative; }
/* Low-poly reveal (built by home-v2.ejs when an image slides in): triangles
   in the card's gray-900 cover the image, then shrink and fade away one by
   one with staggered delays */
.about-gallery__poly {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.about-gallery__poly polygon {
  fill: var(--gray-900);
  stroke: var(--gray-900);
  stroke-width: 0.02; /* hide hairline seams between neighbouring triangles */
  transform-box: fill-box;
  transform-origin: center;
  animation: poly-out 0.4s cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes poly-out {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.4); }
}
/* Pinned to the box's edges (it is position: relative) so the image always
   gets the 16:10 box's exact size, then cropped to fill it, centred */
.about-gallery__item img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  filter: brightness(0.55); /* in colour, darker by default… */
  transition: filter 0.4s ease-out;
}
.about-gallery__item:hover img { filter: brightness(1); } /* …full brightness on hover */
/* Red corner brackets (24px, 2px — like the cards' .ds-card__corner, a bit
   smaller) on each image while hovered or keyboard-focused; drawn as eight
   gradient strips on an overlay above the image */
.about-gallery__item::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  background:
    linear-gradient(var(--red-500), var(--red-500)) left top / 24px 2px,
    linear-gradient(var(--red-500), var(--red-500)) left top / 2px 24px,
    linear-gradient(var(--red-500), var(--red-500)) right top / 24px 2px,
    linear-gradient(var(--red-500), var(--red-500)) right top / 2px 24px,
    linear-gradient(var(--red-500), var(--red-500)) left bottom / 24px 2px,
    linear-gradient(var(--red-500), var(--red-500)) left bottom / 2px 24px,
    linear-gradient(var(--red-500), var(--red-500)) right bottom / 24px 2px,
    linear-gradient(var(--red-500), var(--red-500)) right bottom / 2px 24px;
  background-repeat: no-repeat;
}
.about-gallery__item:hover::after,
.about-gallery__item:has(.about-gallery__open:focus-visible)::after { opacity: 1; }
/* Image button filling its 16:10 box; zoom cursor hints at the lightbox */
.about-gallery__open {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.about-gallery__open:focus-visible { outline: 2px solid var(--red-500); outline-offset: -2px; }
/* ---- Lightbox (about gallery) -----------------------------------------
   Native <dialog> (top layer, focus handling, Esc to close): the image as
   large as fits (90vw × 82vh, contained), prev / next on the sides, close
   top-right, "3 / 13" counter below; dark backdrop, click it to close. */
.lightbox {
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #fff;
  overflow: hidden;
}
.lightbox[open] {
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fade-in 0.2s ease-out both;
}
.lightbox::backdrop { background: rgba(15, 16, 17, 0.94); } /* gray-950 */
.lightbox:focus { outline: none; } /* focused itself on opening (home-v2.ejs) */
.lightbox__figure { margin: 0; }
.lightbox__img {
  display: block;
  max-width: 90vw;
  max-height: 82vh;
  width: auto;
  height: auto;
  object-fit: contain;
}
.lightbox__counter {
  position: absolute;
  bottom: var(--space-6);
  left: 50%;
  transform: translateX(-50%);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.04em;
  color: var(--gray-400);
}
.lightbox__btn {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-xs);
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.lightbox__btn:hover { background: rgba(255, 255, 255, 0.12); color: var(--red-500); }
.lightbox__btn:focus-visible { outline: 2px solid var(--red-500); outline-offset: 2px; }
.lightbox__btn--close { top: var(--space-6); right: var(--space-6); }
.lightbox__btn--prev { left: var(--space-6); top: 50%; transform: translateY(-50%); }
.lightbox__btn--next { right: var(--space-6); top: 50%; transform: translateY(-50%); }
.about-gallery__bar { display: flex; justify-content: center; margin-bottom: var(--space-2); } /* 8px extra below, before the card's bottom padding */
/* Below 800px the card's content sits 32px in from its edges on all sides,
   like the contact form panel (no extra space under the gallery buttons).
   The shard keeps its place relative to the headline, which moves 16px left
   and 12px up: "PERFORMANCE" now ends 391px in, the headline starts 32px down */
@media (max-width: 799.98px) {
  .about-card { padding: var(--space-8); }
  .about-gallery__bar { margin-bottom: 0; }
  .about-card__shard { left: calc((391px + 100% - 32px) / 2 + 32px); top: 104px; }
  /* the two paragraphs stack again (one column, 24px apart) */
  .about-card__text {
    grid-template-columns: 1fr;
    row-gap: var(--space-6);
    margin-top: -37px; /* 12px closer to the headline */
  }
  .about-video { margin-top: -24px; } /* 12px closer to the text */
}
/* gallery prev/next group on gray-900 (the news section's group stays gray-850),
   so it stands out on the about card's gray-850 surface */
.about-gallery__bar .news-nav { background: var(--gray-900); }
/* Intro (driven by home-v2.ejs, one-shot): headline and body text fade in
   together. Hidden only once data-intro is set. */
.about-card[data-intro] .about-card__text,
.about-card[data-intro] .about-gallery { opacity: 0; }
/* Headline: shown in gray until the card is in view, then each line fills
   with red from left to right, one line after another. The words are
   text-clipped backgrounds: a red layer (growing 0 → 100% wide) over a gray
   one. Each line hugs its text so the fill ends with the word. Without JS
   (no data-intro) the headline is simply red. */
.about-card__headline > span { align-self: flex-start; }
.about-card[data-intro] .about-card__headline > span {
  color: transparent;
  -webkit-background-clip: text;
          background-clip: text;
  background-image: linear-gradient(var(--red-500), var(--red-500)), linear-gradient(var(--gray-750), var(--gray-750));
  background-repeat: no-repeat;
  background-size: 0% 100%, 100% 100%;
}
.about-card[data-intro="in"] .about-card__headline > span {
  animation: headline-fill 0.35s cubic-bezier(0.65, 0, 0.35, 1) both;
}
.about-card[data-intro="in"] .about-card__headline > span:nth-child(2) { animation-delay: 0.08s; }
.about-card[data-intro="in"] .about-card__headline > span:nth-child(3) { animation-delay: 0.16s; }
@keyframes headline-fill {
  to { background-size: 100% 100%, 100% 100%; }
}
.about-card[data-intro="in"] .about-card__text,
.about-card[data-intro="in"] .about-gallery {
  animation: fade-in 0.6s ease-out both;
}
/* StatsBanner below the about card */
.about-stats { margin-top: 52px; }
@media (max-width: 1079.98px) {
  .about-stats { margin-top: 40px; }
}

/* Lineup section layout — List (1/3) left, LineupCard (2/3) right */
.lineup-layout {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: var(--space-5); /* same as the news cards (20px) */
}
/* The driver list scrolls vertically within the card's height */
.lineup-layout__aside {
  max-height: 592px; /* matches the LineupCard height */
  overflow-y: auto;
  padding-right: var(--space-0\.5); /* 2px gap between rows and scrollbar */
  /* NOTE: intentionally not using the standard scrollbar-width/scrollbar-color
     here — in Chrome those switch to the overlay scrollbar that auto-hides.
     The ::-webkit-scrollbar rules below keep a colored bar always visible. */
}
/* Scrollbar color — WebKit (Chrome/Safari/Edge) */
.lineup-layout__aside::-webkit-scrollbar {
  width: 6px;
}
.lineup-layout__aside::-webkit-scrollbar-track {
  background: transparent;
}
.lineup-layout__aside::-webkit-scrollbar-thumb {
  background: var(--gray-750);
  border-radius: var(--radius-xs); /* 2px */
}
.lineup-layout__aside::-webkit-scrollbar-thumb:hover {
  background: var(--gray-700);
}

/* Driver stage inside the lineup card — one panel per driver, only one visible */
.lineup-driver-stage {
  position: relative;
  flex: 1;
  min-height: 0;
}
/* Red brush strokes behind the driver (inline SVG, partials/components/
   lineup-brush.ejs; 386 × 420px): centred on the driver image (a quarter into the stage + its 16px
   nudge) and on the card's height, then 24px lower. Behind the driver panels
   (first in the stage). */
.lineup-brush {
  position: absolute;
  left: calc(25% + 16px);
  top: calc(50% + 24px);
  width: 386px;
  height: 420px;
  transform: translate(-50%, -50%) rotate(-7deg); /* tilted 7° counter-clockwise */
  pointer-events: none;
}
/* Intro (with the card's, home-v2.ejs): the strokes are painted on in order —
   the mask's thick trace lines (lineup-brush.ejs) draw along the zigzag
   (stroke-dashoffset 1000 → 0, pathLength 1000), then along the last
   right-hand stroke; at the end a full mask layer fades in, so every edge the
   traces missed shows too. Without the intro (no JS / reduced motion) the
   mask is fully open from the start. */
.lineup-brush__trace { stroke-dasharray: 1000; stroke-dashoffset: 0; }
[data-lineup-intro] .lineup-brush__trace { stroke-dashoffset: 1000; }
[data-lineup-intro] .lineup-brush__fill { opacity: 0; }
[data-lineup-intro="in"] .lineup-brush__trace--a {
  animation: lineup-brush-trace 1.8s cubic-bezier(0.45, 0, 0.55, 1) 0.1s both;
}
[data-lineup-intro="in"] .lineup-brush__trace--b {
  animation: lineup-brush-trace 0.35s ease-out 1.85s both;
}
[data-lineup-intro="in"] .lineup-brush__fill {
  animation: fade-in 0.5s ease-out 2.1s both;
}
@keyframes lineup-brush-trace {
  from { stroke-dashoffset: 1000; }
  to   { stroke-dashoffset: 0; }
}
.lineup-driver {
  position: absolute;
  inset: 0;
  display: none;
}
.lineup-driver.is-active {
  display: block;
}
/* Category badges — stacked at the top-left, behind the driver image */
.lineup-driver__badges {
  position: absolute;
  top: var(--space-6); /* 24px */
  left: var(--space-6); /* 24px */
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch; /* all badges take the width of the widest one */
  gap: var(--space-3); /* 12px */
}
/* Driver photo — horizontally centered in the left column (the left half of the
   card, since the info panel is the right 50%), anchored to the bottom */
.lineup-driver__image {
  position: absolute;
  left: 25%;
  transform: translateX(calc(-50% + 16px)); /* centered in the left column, nudged 16px right */
  bottom: 0;
  height: 100%; /* fill the card height */
  width: auto;
  max-width: 50%;
  object-fit: contain;
  object-position: center bottom;
  display: block;
  z-index: 2;
  /* Same soft shadow as the stats banner driver (.stats-banner__driver):
     follows the cut-out's outline, offset 16px to the left */
  filter: drop-shadow(-16px 0 24px rgba(0, 0, 0, 0.28));
}
/* Name panel — right half of the card, 40px padding all around */
.lineup-driver__info {
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;
  padding: 40px 48px;
  display: flex;
  flex-direction: column;
}
.lineup-driver__name {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  text-transform: uppercase;
  line-height: 1;
}
.lineup-driver__first {
  font-size: 16px;
  line-height: 20px;
  font-weight: 500;
  color: var(--red-500);
}
.lineup-driver__last {
  font-size: 32px;
  line-height: 32px;
  font-weight: 700;
  color: #fff;
}
/* Country + age — same small style as the list's category meta */
.lineup-driver__meta {
  position: relative;
  margin-top: var(--space-6); /* 24px below the last name */
  font-size: 10px;
  line-height: 16px;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--gray-400);
}
/* Nationality flag, inlined before the country name in the meta line: a
   12px circle with a 1px white ring (ring as on the hero event banner's
   flag, .event-content__flag-wrap). The 4:3 flag is cropped to fill it. */
.lineup-driver__flag-wrap {
  display: inline-flex;
  width: 12px;
  height: 12px;
  margin-right: 10px; /* to the country name */
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 1px #fff;
  vertical-align: -2px; /* centred on the 16px line */
}
.lineup-driver__flag {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover; /* crop the 4:3 flag to the circle, centred */
}
/* Driver description */
.lineup-driver__desc {
  margin-top: var(--space-6); /* 24px below the country+age text */
  font-size: 13px;
  line-height: 22px;
  font-weight: 400;
  color: #fff;
}
/* Achievements CTA button */
/* Achievements button of a driver without achievements: gray outline and
   text instead of the faded red (same look as the disabled contact submit) */
.lineup-driver__cta .button:disabled {
  opacity: 1;
  background: transparent;
  border-color: var(--gray-750);
  color: var(--gray-700);
}
.lineup-driver__cta {
  margin-top: var(--space-8); /* 32px below the description */
}
/* X (Twitter) handle — clickable, pinned to the bottom; description style but uppercase */
.lineup-driver__x {
  margin-top: auto; /* push to the bottom of the info wrapper */
  display: inline-flex;
  align-items: center;
  gap: var(--space-3); /* 12px between icon and handle */
  font-size: 13px;
  line-height: 22px;
  font-weight: 400;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  transition: color 0.15s ease;
}
.lineup-driver__x:hover { color: var(--yellow-500); }
.lineup-driver__x-icon {
  display: inline-flex;
  flex: 0 0 auto;
}
/* 20px horizontal accent line, 56px to the left of the X handle */
.lineup-driver__x { position: relative; }
.lineup-driver__x::before {
  content: '';
  position: absolute;
  left: -56px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 1px;
  background: var(--gray-700);
  opacity: 0.48;
}
/* Text intro (driven by home-v2.ejs): the name fades in, then meta
   (flag + country), description, button and X handle rise in. Hidden until the section is in view; replays whenever a
   panel becomes .is-active. */
[data-lineup-intro] .lineup-driver__name,
[data-lineup-intro] .lineup-driver__meta,
[data-lineup-intro] .lineup-driver__desc,
[data-lineup-intro] .lineup-driver__cta,
[data-lineup-intro] .lineup-driver__x { opacity: 0; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__name {
  animation: fade-in 0.5s ease-out both;
}
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__meta,
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__desc,
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__cta,
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__x {
  animation: rise-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}
/* Meta (flag + country, age), description and button: a softer, longer
   rise — 0.9s, a shorter 8px travel and a gentle ease-out, 0.12s apart */
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__meta,
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__desc,
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__cta {
  animation: rise-in-soft 0.9s cubic-bezier(0.33, 1, 0.68, 1) both;
}
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__meta { animation-delay: 0.45s; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__desc { animation-delay: 0.57s; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__cta  { animation-delay: 0.69s; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__x    { animation-delay: 0s; } /* together with the name */
/* Category badges: only the text fades in (the badge box stays), one badge
   after another */
[data-lineup-intro] .lineup-driver__badges .bg-badge { color: transparent; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__badges .bg-badge {
  animation: badge-text-fade 0.6s ease-out both;
}
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__badges .bg-badge:nth-child(2) { animation-delay: 0.15s; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__badges .bg-badge:nth-child(3) { animation-delay: 0.3s; }
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__badges .bg-badge:nth-child(n+4) { animation-delay: 0.45s; }
/* Accent line left of the X handle: once the handle has risen in (with the
   name, 0.5s), fades in and slides from the left into its place */
[data-lineup-intro="in"] .lineup-driver.is-active .lineup-driver__x::before {
  animation: meta-line-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.5s both;
}
@keyframes meta-line-in {
  from { opacity: 0; transform: translate(calc(-1 * var(--space-6)), -50%); } /* 24px further left */
  to   { opacity: 0.48; transform: translate(0, -50%); } /* resting state of .lineup-driver__x::before */
}
@keyframes badge-text-fade {
  from { color: transparent; }
  to   { color: var(--gray-700); } /* .bg-badge text colour */
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* opacity is done by 60% while the movement keeps easing out → no "pop" */
@keyframes rise-in-soft {
  0%   { opacity: 0; transform: translateY(var(--space-2)); } /* 8px */
  60%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
@keyframes rise-in {
  from { opacity: 0; transform: translateY(var(--space-3)); } /* 12px */
  to   { opacity: 1; transform: none; }
}
/* Default content fills the info wrapper (so the X handle pins to the bottom) */
.lineup-driver__default {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* Achievements list inside the overlay body */
.lineup-driver__ach-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.lineup-driver__ach-item {
  display: flex;
  align-items: center;
  gap: var(--space-4); /* 16px between icon and text */
  padding: var(--space-2) 0; /* 8px */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 13px; /* same as the driver description */
  line-height: 22px;
  font-weight: 400;
  color: #fff;
  border-bottom: 1px solid var(--gray-800);
}
.lineup-driver__ach-item:first-child { padding-top: 0; }
.lineup-driver__ach-icon {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  object-fit: contain;
}
.lineup-driver__ach-empty {
  margin: 0;
  font-size: 14px;
  line-height: 24px;
  color: var(--gray-500);
}

/* ---- StatsBanner -----------------------------------------------------
   Full-width, 480px-tall banner with the card stripe-pattern background.
   Partial: partials/components/stats-banner
   ---------------------------------------------------------------------- */
/* Whole banner is the link */
.stats-banner-link {
  display: block;
  text-decoration: none;
  color: inherit;
}
.stats-banner {
  /* Outer frame like .ds-card (the about card above): gray-900, 1px gray-850
     border, 8px padding around the striped surface. No overflow: hidden —
     the driver image pokes out above the top edge. */
  position: relative;
  width: 100%;
  height: 480px;
  padding: var(--space-2); /* 8px */
  background: var(--gray-900);
  border: 1px solid var(--gray-850);
}
/* Glass crystal (100 × 89px, ≈ 35% of its source) on the banner's
   bottom-right corner: centred 16px left of the 1px right border, mostly over the banner,
   and sitting 56px above the bottom edge (the section ends at the banner's
   bottom and clips anything below it). Above the banner's content. */
.stats-banner__crystal {
  position: absolute;
  right: calc(var(--space-4) - 0.5px); /* 16px left */
  bottom: var(--space-16); /* 64px */
  width: 100px;
  height: 89px;
  /* scroll parallax (--parallax on .stats-banner, 0 = resting): rises and
     grows slightly as you scroll down */
  transform: translate(50%, calc(var(--parallax, 0) * -32px))
             scale(calc(1 + var(--parallax, 0) * 0.16)) /* ≈ 0.8 → 1.12 */
             rotate(-3deg); /* tilted 3° counter-clockwise */
  z-index: 6;
  pointer-events: none;
}
/* Striped inner surface — carries the pattern and corner triangles. Also a
   size container, so the driver can be positioned in surface widths (cqw). */
.stats-banner__surface {
  position: relative;
  container-type: inline-size;
  height: 100%;
  background-image: url('/assets/stripe-pattern.svg');
  background-repeat: repeat;
}
/* Corner brackets — always visible: mint by default, white on hover */
.stats-banner .ds-card__corner {
  z-index: 2;
  border-color: var(--mint-500);
  transition: border-color 0.2s ease;
}
.stats-banner-link:hover .ds-card__corner {
  border-color: #fff;
}
/* gray-850 triangles in the bottom-left and top-right corners, sized like the
   288px corner stripe SVGs of the about card */
.stats-banner__surface::before,
.stats-banner__surface::after {
  content: '';
  position: absolute;
  width: 288px;
  height: 288px;
  background: var(--gray-850);
  pointer-events: none;
}
.stats-banner__surface::before {
  bottom: 0;
  left: 0;
  clip-path: polygon(0 0, 0 100%, 100% 100%); /* bottom-left triangle */
}
.stats-banner__surface::after {
  top: 0;
  right: 0;
  clip-path: polygon(0 0, 100% 0, 100% 100%); /* top-right triangle */
}
/* Content: left column (1/3) + reserved image area (2/3) */
.stats-banner__inner {
  position: relative;
  z-index: 1; /* above the pattern + corner triangles */
  height: 100%;
  display: grid;
  grid-template-columns: 2fr minmax(392px, 1fr); /* image left (2/3), text right (≥392px) */
  align-items: stretch;
}
/* Put the media on the left, the text column on the right */
.stats-banner__media { order: -1; }
.stats-banner__col {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-6); /* 24px between heading · list · cta */
  padding: var(--space-12) var(--space-12) calc(var(--space-12) + 6px); /* 48px · 54px bottom */
  min-width: 0;
}
.stats-banner__heading {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 32px;
  line-height: 36px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--mint-500);
}
.stats-banner__list {
  list-style: none;
  margin: var(--space-1) 0 0; /* +4px on top of the 24px gap below the heading (28px) */
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px; /* between items */
}
.stats-banner__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3); /* 12px between check and text */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 22px;
  font-weight: 400;
  color: #fff;
}
.stats-banner__check {
  flex: 0 0 auto;
  display: inline-flex;
  margin: 2px 0; /* 18px icon + 2px top/bottom = 22px, matching the line height */
  color: var(--mint-500);
}
.stats-banner__cta { display: flex; margin-top: var(--space-3); } /* +12px on top of the 24px gap (36px) */
/* Mint variant of the primary button for this banner (matches the mint
   heading and checkmarks), dark gray-900 text. Hover lightens, press darkens,
   like the red one. */
.stats-banner__cta .button--primary {
  background: var(--mint-500);
  border-color: var(--mint-500);
  color: var(--gray-900);
}
.stats-banner__cta .button--primary:hover {
  background: var(--mint-400);
  border-color: var(--mint-400);
  color: var(--gray-900);
}
.stats-banner__cta .button--primary:active {
  background: var(--mint-550);
  border-color: var(--mint-550);
  color: var(--gray-900);
}
.stats-banner__media {
  position: relative;
  /* below 1200px the settled driver (and its target square / connector)
     sit further left, more of it clear of the fixed-width overlay panel */
  --driver-shift: 0px;
  min-width: 0;
  /* Rise to 26px above the banner's outer edge — the middle of the 52px gap
     to the about card (.about-stats) — so the driver breaks out of the top
     border. The surface sits 1px border + 8px padding inside that edge. */
  margin-top: calc(-1 * (26px + var(--space-2) + 1px));
}
/* Ranked driver list filling the media area left of the text column, behind
   the driver image. Centred on the surface (media is 35px taller at the
   top, hence +17.5px). The text column's own 48px padding is the gap on
   the right. */
.stats-banner__ranking {
  position: absolute;
  left: var(--space-12); /* 48px */
  right: 0;
  /* spans the media below its 35px top overhang and centres the card in it
     with flexbox (not a transform, which would make it a stacking context and
     trap the overlay panel below the driver) */
  top: calc(26px + var(--space-2) + 1px);
  bottom: 0;
  display: flex;
  align-items: center;
}
.stats-banner__ranking > .ds-card { flex: 1 1 auto; min-width: 0; }
/* Below 960px the banner stacks: the text column first, then the ranking
   list with its overlay below it (in normal flow, no longer positioned
   beside the text), and the banner grows to fit */
@media (max-width: 959.98px) {
  .stats-banner { height: auto; }
  .stats-banner__inner { height: auto; grid-template-columns: 1fr; }
  .stats-banner__media {
    order: 0;
    margin-top: 0;
    padding: 0 var(--space-12) var(--space-12);
  }
  /* Heading with the button to its right, the checklist below in 3 columns */
  .stats-banner__col {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "heading cta" "list list";
    align-items: center;
    column-gap: var(--space-6);
    padding-top: calc(var(--space-12) - 8px); /* 40px */
    padding-bottom: calc(var(--space-8) + 8px); /* 40px gap to the list below */
  }
  .stats-banner__heading { grid-area: heading; }
  .stats-banner__cta { grid-area: cta; margin-top: 0; }
  .stats-banner__list {
    grid-area: list;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--space-6);
  }
  .stats-banner__ranking { position: static; display: block; }
  /* Smaller (72 × 64px) and centred on the list card: the 388px card ends
     57px above the banner's bottom, so its centre is 251px up */
  .stats-banner__crystal {
    width: 72px;
    height: 64px;
    bottom: calc(57px + 388px / 2 - 64px / 2); /* 219px */
    right: calc(var(--space-4) - 0.5px - 8px); /* 8px further right */
  }
}
/* Below 800px the checklist drops to 2 columns and the heading breaks
   after "Check out" */
@media (max-width: 799.98px) {
  .stats-banner__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats-banner__heading-line { display: block; }
  /* Content inset 32px on all sides, like the contact form panel */
  .stats-banner__col { padding: var(--space-8) var(--space-8) calc(var(--space-8) + 8px); }
  .stats-banner__media { padding: 0 var(--space-8) var(--space-8); }
  /* Smaller crystal (56 × 50px), still centred on the card, which now ends
     41px (32 + 8 + 1) above the banner's bottom */
  .stats-banner__crystal { width: 56px; height: 50px; bottom: calc(41px + 388px / 2 - 50px / 2); } /* 210px */
}
/* Scroll-linked reveal (driven by home-v2.ejs): --reveal goes 0 → 1 between
   the list entering at the bottom of the viewport and the whole banner being
   in view. The card starts 64px lower (always fully opaque) and reaches its
   resting place at 1. Animates the card, not .stats-banner__ranking, so its
   centring transform stays untouched. */
.stats-banner[data-reveal] .stats-banner__ranking > .ds-card {
  transform: translateY(calc((1 - var(--reveal, 0)) * var(--space-16)));
}
/* Once settled the slide is done (its transform would be 0 anyway): dropping
   it removes the card's stacking context, so the overlay panel and its ring
   (z-index 3 / 4) stack above the driver image, while the list rows stay
   behind it */
.stats-banner.is-settled .stats-banner__ranking > .ds-card { transform: none; }
/* Overlay panel over the list, lined up with the second about gallery image
   above (card and banner share the same frame, so surface coordinates match
   the card's): gallery images are (surface − 2×48px padding − 2×20px gaps)
   / 3 wide, the second starts at 48px + one image + 20px. The overlay sits in
   the list card, whose padding box starts at 48px + 1px border, so its left
   is one image + 19px; it then runs to 24px from the card's right edge, the
   same inset as top and bottom. Fades in after the driver arrives. */
.stats-banner__overlay {
  position: absolute;
  top: var(--space-6);
  bottom: var(--space-6);
  left: calc((100cqw - 136px) / 3 + 19px);
  right: var(--space-6); /* same 24px as above and below */
  z-index: 3; /* above the rows and the card's corner brackets */
  /* Panel styling as the achievements overlay (.overlay__panel) */
  display: flex;
  flex-direction: column;
  overflow: hidden; /* clip children to the rounded corners */
  background: var(--gray-800);
  border: 1px solid transparent;
  border-top-color: rgba(255, 255, 255, 0.04); /* white @ 4% */
  border-bottom-color: var(--gray-900);
  border-radius: var(--radius-xs); /* 2px */
  box-shadow: 0 0 16px rgba(0, 0, 0, 0.24); /* 16px blur, black @ 24% */
  opacity: 0;
  transform: translateY(var(--space-2));
  pointer-events: none;
  transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}
/* Rotating mint border: same box as the overlay; a conic gradient (two
   bright mint arcs on opposite sides, each fading out behind it) masked down to a 1px ring turns half way around
   the panel's outline as soon as the list lands, while the target square opens,
   while the panel itself fades in from half way (0.3s). Needs @property for the animated angle; browsers
   without it just show a static arc briefly. */
@property --ring-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
.stats-banner__overlay-ring {
  position: absolute;
  top: var(--space-6);
  bottom: var(--space-6);
  left: calc((100cqw - 136px) / 3 + 19px);
  right: var(--space-6);
  z-index: 4; /* above the panel, which fades in while the ring is still turning */
  padding: 1px; /* ring thickness */
  border-radius: var(--radius-xs);
  /* two opposite arcs (half a turn apart), each a mint-700 → mint-500 tail */
  background: conic-gradient(from var(--ring-angle),
    transparent 0deg, transparent 100deg, var(--mint-700) 140deg, var(--mint-500) 175deg, transparent 180deg,
    transparent 280deg, var(--mint-700) 320deg, var(--mint-500) 355deg, transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .stats-banner.is-settled .stats-banner__overlay-ring {
    animation: overlay-ring 0.6s linear both; /* straight away, while the target square opens (0s–0.5s) */
  }
}
@keyframes overlay-ring {
  0%   { opacity: 0; --ring-angle: 0deg; }
  15%  { opacity: 1; }
  80%  { opacity: 1; }
  100% { opacity: 0; --ring-angle: 180deg; } /* half a turn: the two opposite arcs still cover the whole outline */
}
/* Overlay header: avatar · name over team · rank badge on the right */
.stats-banner__overlay-head {
  display: flex;
  align-items: center;
  gap: var(--space-3); /* 12px */
  flex: 0 0 auto;
  padding: var(--space-4) 14px; /* 16px top/bottom · 14px left/right */
  border-bottom: 1px solid var(--gray-900); /* page section background */
  font-family: 'Bai Jamjuree', sans-serif;
  text-transform: uppercase;
}
.stats-banner__avatar {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  margin-right: var(--space-1); /* 16px to the name: 4px on top of the 12px gap */
  border-radius: var(--radius-xs);
  background: var(--gray-900); /* page section background; placeholder until an avatar image is set */
  overflow: hidden;
}
.stats-banner__avatar img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Default avatar: the 3-line needracing logo, centred and contained */
.stats-banner__avatar:has(.stats-banner__avatar-logo) {
  display: flex;
  align-items: center;
  justify-content: center;
}
.stats-banner__avatar .stats-banner__avatar-logo {
  width: 20px;
  height: 20px;
  object-fit: contain;
}
.stats-banner__overlay-id {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0; /* name and team sit directly on top of each other */
}
.stats-banner__overlay-name {
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stats-banner__overlay-team {
  display: flex;
  align-items: center;
  font-size: 10px;
  line-height: 16px;
  color: var(--gray-500);
}
/* 32px bar below the header with Stats / Races tabs (TabBar styling, compact
   20px gap, 10px text like the team name), divided like the header */
.stats-banner__overlay-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  height: 32px;
  padding: 0;
  background: var(--gray-850); /* one step darker than the panel */
  border-bottom: 1px solid var(--gray-900);
}
.stats-banner__overlay-bar .tabbar__tab {
  display: flex;
  align-items: center;
  height: 100%; /* fill the 32px bar, no space above/below */
  padding: 0 14px; /* sides = the header's left padding */
  border-radius: var(--radius-xs); /* 2px */
  font-size: 10px; /* same as the team name (.stats-banner__overlay-team) */
  line-height: 16px;
}
.stats-banner__overlay-bar .tabbar__list { gap: 0; height: 100%; align-items: stretch; } /* tabs sit flush (overrides the compact 20px) and fill the bar height */
.stats-banner__overlay-bar .tabbar__list > li { display: flex; }
/* Inactive tabs in the team name's gray (.stats-banner__overlay-team); still
   yellow on hover like the TabBar */
.stats-banner__overlay-bar .tabbar__tab:not(.is-active) { color: var(--gray-500); }
.stats-banner__overlay-bar .tabbar__tab:not(.is-active):hover { color: var(--yellow-500); }
/* Divider after the first tab, same colour as the bar's bottom border */
.stats-banner__overlay-bar .tabbar__list > li:first-child .tabbar__tab { border-right: 1px solid var(--gray-900); }
/* Only the active tab gets the gray-800 wrapper. It reaches 1px further down
   to cover the bar's bottom border, so it opens into the panel below. */
.stats-banner__overlay-bar .tabbar__tab.is-active {
  position: relative;
  z-index: 1;
  height: calc(100% + 1px);
  background: var(--gray-800);
  border-radius: var(--radius-xs) var(--radius-xs) 0 0; /* square bottom corners where it meets the panel */
}
/* Stats tab: 30-bar chart filling the space between tabs and stats. Single series: mint-800 fill (dark on
   purpose; the mint-500 top line carries the contrast against gray-800), thin bars with
   rounded tops on a zero baseline, 2px gaps. Decorative preview, so no hover layer (the
   whole banner is one link and the overlay ignores the pointer). */
.stats-banner__chart {
  flex: 1; /* takes the remaining height, so the stats sit on the overlay's bottom edge */
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-4) 14px; /* 14px sides, aligned with the header */
  font-family: 'Bai Jamjuree', sans-serif;
}
.stats-banner__chart-plot {
  display: flex;
  gap: 2px;
  flex: 1; /* bars fill the chart area's height */
  min-height: 0;
}
.stats-banner__chart-track {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.stats-banner__chart-bar {
  width: 100%;
  background: linear-gradient(to bottom, var(--mint-800), var(--mint-900)); /* slightly darker towards the bottom */
  border-top: 1px solid var(--mint-500); /* brighter cap on each bar */
}
/* Tab panels below the tab bar: Stats (chart + key stats) and Races; the
   script in home-v2.ejs switches from Stats to Races. Each fills the rest of
   the overlay. */
.stats-banner__panel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.stats-banner__panel[hidden] { display: none; }
.stats-banner__panel[data-panel="races"]:not([hidden]) { animation: fade-in 0.4s ease-out both; }
/* Races list: header + one row per race in a 5-column grid, small uppercase
   text like the stats; +/− values in mint (up) or red (down) */
.stats-banner__races {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-2) 14px; /* sides aligned with the header */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 10px;
  line-height: 16px;
  text-transform: uppercase;
  color: #fff;
}
.stats-banner__race {
  display: grid;
  grid-template-columns: 24px minmax(0, 1.4fr) minmax(0, 1fr) 56px 44px;
  gap: var(--space-2);
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid var(--gray-900);
}
/* Clipped viewport for the rows; the track inside is moved up by the script */
.stats-banner__races-body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.stats-banner__races-track { will-change: transform; } /* glide timing is set by the script */
.stats-banner__race > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stats-banner__race > span:nth-child(n+4) { text-align: right; font-variant-numeric: tabular-nums; }
/* Small rank badge for the Pos column (same colours as .stats-banner__rank,
   whose 32px size is defined further down, hence the doubled class) */
.stats-banner__rank.stats-banner__rank--sm {
  width: 20px;
  height: 20px;
  font-weight: 600;
  vertical-align: middle;
}
.stats-banner__race--head { color: var(--gray-500); font-size: 9px; } /* a step smaller than the 10px rows */
.stats-banner__race .is-up { color: var(--mint-500); }
.stats-banner__race .is-down { color: var(--red-500); }
/* Key stats below the chart: 3 × 2 grid, small gray label over a white value.
   1px gray-900 divider lines between the cells (and above the grid), drawn
   by the grid's background showing through 1px gaps. */
.stats-banner__stats {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin: 0;
  padding: 0;
  background: var(--gray-900); /* the divider colour */
  border-top: 1px solid var(--gray-900);
  font-family: 'Bai Jamjuree', sans-serif;
  text-transform: uppercase;
}
.stats-banner__stat {
  min-width: 0;
  padding: var(--space-3) 14px; /* 12px · 14px sides (aligned with the header) */
  background: var(--gray-800);
  transition: background-color 0.3s ease-out;
}
.stats-banner__stat dt {
  font-size: 10px;
  line-height: 16px;
  color: var(--gray-500);
  transition: color 0.3s ease-out;
  white-space: nowrap;
}
/* The metric the chart currently shows (Rating, then Reputation): mint title
   on a dark mint cell */
.stats-banner__stat.is-active { background: color-mix(in srgb, var(--mint-900) 30%, var(--gray-800)); } /* a 30% hint of mint-900 in the cell gray, ≈ #162A27 */
.stats-banner__stat.is-active dt { color: var(--mint-500); }
.stats-banner__stat dd {
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
/* Bars grow up from the baseline when the overlay appears (list settled),
   one after another left → right, starting as the overlay fades in; they
   collapse again when it hides */
@media (prefers-reduced-motion: no-preference) {
  .stats-banner__chart-bar {
    transform: scaleY(0);
    transform-origin: bottom;
    transition: transform 0.2s ease-in, height 0.6s cubic-bezier(0.22, 1, 0.36, 1); /* height: metric switch */
  }
  .stats-banner.is-settled .stats-banner__chart-bar {
    transform: none;
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1) calc(0.4s + var(--i, 0) * 12ms),
                height 0.6s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--i, 0) * 12ms); /* metric switch, same left → right wave */
  }
}
.stats-banner.is-settled .stats-banner__overlay {
  opacity: 1;
  transform: none;
  transition-delay: 0.3s; /* half way through the rotating mint border (0s–0.6s) */
}
/* Target square: 4 mint corner brackets (8px) framing a 32px square centred on the
   settled driver (same x as .stats-banner.is-settled .stats-banner__driver,
   vertically the middle of the media = the driver's middle). As soon as the
   list (and with it the driver) has landed, the brackets travel from the square's centre out to its
   corners while fading in; they collapse back when the banner unsettles. */
.stats-banner__target {
  position: absolute;
  top: 50%;
  left: calc(var(--space-12) + (100cqw - 136px) / 6 + var(--space-4) + var(--driver-shift, 0px)); /* nudged 16px right of the driver's centre */
  width: 32px;
  height: 32px;
  transform: translate(-50%, -50%);
  z-index: 1; /* above the driver */
  pointer-events: none;
}
.stats-banner__target-corner {
  position: absolute;
  width: 8px;
  height: 8px;
  border: 0 solid var(--mint-500);
  opacity: 0;
  transition: opacity 0.3s ease-in, transform 0.3s ease-in;
}
/* Start at the centre: each bracket is shifted by half the square minus half its own size */
.stats-banner__target-corner--tl { top: 0; left: 0; border-top-width: 1px; border-left-width: 1px; transform: translate(12px, 12px); }
.stats-banner__target-corner--tr { top: 0; right: 0; border-top-width: 1px; border-right-width: 1px; transform: translate(-12px, 12px); }
.stats-banner__target-corner--bl { bottom: 0; left: 0; border-bottom-width: 1px; border-left-width: 1px; transform: translate(12px, -12px); }
.stats-banner__target-corner--br { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; transform: translate(-12px, -12px); }
.stats-banner.is-settled .stats-banner__target-corner {
  opacity: 1;
  transform: none;
  transition: opacity 0.3s ease-out, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); /* straight away: the driver has arrived with the list */
}
/* Dashed connector from the target square to the overlay, drawn left → right
   once the square has opened. In media coordinates: it starts 8px right of
   the square (driver centre 48px + (100cqw − 136px) / 6, + 16px half square
   + 8px) and ends on the overlay's left edge (list card at 48px + 1px border,
   + one gallery image + 19px → (100cqw − 136px) / 3 + 68px). */
.stats-banner__connector {
  position: absolute;
  top: 50%;
  left: calc(var(--space-12) + (100cqw - 136px) / 6 + 40px + var(--driver-shift, 0px)); /* square is nudged 16px right */
  width: calc((100cqw - 136px) / 6 - 20px);
  height: 1px;
  background-image: repeating-linear-gradient(to right, var(--mint-500) 0 4px, transparent 4px 8px); /* 4px dashes */
  z-index: 1;
  pointer-events: none;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.2s ease-in;
}
/* Below 1280px the overlay (and its ring) keep their full-width size: 335px
   wide, still 24px from the list card's right edge, so they reach further
   over the list as it narrows instead of getting thinner. The dashed
   connector then ends on the overlay's new left edge — media x = 100cqw −
   752px (list card from 48px, 100cqw − 440px wide, − 24px − 335px − 1px
   border) — i.e. it's (5/6 × 100cqw − 817.33px) long, never negative. */
@media (max-width: 1199.98px) {
  .stats-banner__media { --driver-shift: -64px; }
}
@media (max-width: 1279.98px) {
  .stats-banner__overlay,
  .stats-banner__overlay-ring { left: auto; width: 335px; }
  .stats-banner__connector { width: max(0px, 100cqw * 5 / 6 - 817.33px - var(--driver-shift, 0px)); }
}
/* Below 1080px: no driver, target square or dashed connector — the overlay
   panel (and its ring) sits centred over the ranking list instead (its
   335px width, centred in the list card) */
@media (max-width: 1079.98px) {
  .stats-banner__driver,
  .stats-banner__target,
  .stats-banner__connector { display: none; }
  .stats-banner__overlay,
  .stats-banner__overlay-ring { left: calc(50% - 167.5px); right: auto; }
}
.stats-banner.is-settled .stats-banner__connector {
  transform: none;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1) 0.4s; /* as the square finishes opening (0s–0.5s) */
}
/* Text column intro (driven by home-v2.ejs, one-shot): the heading flickers
   on like a failing neon tube, then the checklist items rise in one after
   another, then the button. Hidden states only apply once data-intro is set. */
.stats-banner[data-intro] .stats-banner__heading,
.stats-banner[data-intro] .stats-banner__item,
.stats-banner[data-intro] .stats-banner__cta { opacity: 0; }
.stats-banner[data-intro] .stats-banner__item,
.stats-banner[data-intro] .stats-banner__cta {
  transform: translateY(var(--space-3)); /* 12px */
  transition: opacity 0.5s ease-out, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.stats-banner[data-intro="in"] .stats-banner__heading {
  animation: stats-banner-flicker 0.6s linear forwards;
}
.stats-banner[data-intro="in"] .stats-banner__item,
.stats-banner[data-intro="in"] .stats-banner__cta {
  opacity: 1;
  transform: none;
}
.stats-banner[data-intro="in"] .stats-banner__item:nth-child(1) { transition-delay: 0.5s; }
.stats-banner[data-intro="in"] .stats-banner__item:nth-child(2) { transition-delay: 0.6s; }
.stats-banner[data-intro="in"] .stats-banner__item:nth-child(3) { transition-delay: 0.7s; }
.stats-banner[data-intro="in"] .stats-banner__item:nth-child(4) { transition-delay: 0.8s; }
.stats-banner[data-intro="in"] .stats-banner__item:nth-child(5) { transition-delay: 0.9s; }
.stats-banner[data-intro="in"] .stats-banner__cta { transition-delay: 1.1s; }
@keyframes stats-banner-flicker {
  0%   { opacity: 0; }
  15%  { opacity: 1; }
  25%  { opacity: 0; }
  40%  { opacity: 1; }
  50%  { opacity: 0.3; }
  65%  { opacity: 1; }
  100% { opacity: 1; }
}
/* Gray corner brackets on the list card — stay gray (the banner's own
   brackets turn red on hover) */
.stats-banner .stats-banner__ranking .ds-card__corner,
.stats-banner-link:hover .stats-banner__ranking .ds-card__corner { border-color: var(--gray-750); }
.stats-banner__ranking .ds-card__corner { width: 16px; height: 16px; border-width: 1px; } /* half the default 32px, 1px lines */
.stats-banner__ranking .list__row {
  gap: var(--space-5);
  transition: opacity 0.6s ease-out;
}
/* Settled (list landed, set by home-v2.ejs): while the overlay fades in
   (0.3s), rows dim to 48%, the title bar to 32% and the value placeholders
   fade out; undone straight away when unsettled */
.stats-banner.is-settled .stats-banner__ranking .list__row { opacity: 0.48; transition-delay: 0.3s; } /* with the overlay fade-in */
.stats-banner__ranking-head { transition: opacity 0.6s ease-out; }
.stats-banner.is-settled .stats-banner__ranking-head { opacity: 0.32; transition-delay: 0.3s; }
/* …and the Rating / Rep / Score placeholders fade out with it */
.stats-banner__rating .stats-banner__placeholder,
.stats-banner__rep .stats-banner__placeholder,
.stats-banner__score .stats-banner__placeholder { transition: opacity 0.6s ease-out; }
.stats-banner.is-settled .stats-banner__rating .stats-banner__placeholder,
.stats-banner.is-settled .stats-banner__rep .stats-banner__placeholder,
.stats-banner.is-settled .stats-banner__score .stats-banner__placeholder { opacity: 0; transition-delay: 0.3s; }
.stats-banner__rank {
  flex: 0 0 auto;
  /* 32px square wrapper: borderless, white at 6% over the row */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-xs); /* 2px */
  color: var(--gray-700);
}
/* Podium ranks use the light tones of the medal icons (/assets/medal-*.svg),
   with a 12% tint of the same colour as the wrapper */
.stats-banner__rank--1 { color: #E6C778; background: rgba(230, 199, 120, 0.12); } /* gold */
.stats-banner__rank--2 { color: #A3B6C9; background: rgba(163, 182, 201, 0.12); } /* silver */
.stats-banner__rank--3 { color: #EAB288; background: rgba(234, 178, 136, 0.12); } /* bronze */
.stats-banner__driver-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Placeholder bar shown in place of the driver name and the values. Inline
   so the right-aligned value columns push it to the right edge. */
.stats-banner__placeholder {
  display: inline-block;
  vertical-align: middle;
  max-width: 100%;
  height: 8px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-xs); /* 2px */
}
/* Numeric columns: fixed width + right-aligned so they line up with the
   title bar; Rep and Rank Score get 12px extra on top of the 20px gap (32px). */
.stats-banner__rating,
.stats-banner__rep,
.stats-banner__score,
.stats-banner__th--rating,
.stats-banner__th--rep,
.stats-banner__th--score {
  flex: 0 0 auto;
  width: 80px;
  text-align: right;
}
.stats-banner__rep,
.stats-banner__th--rep { width: 56px; } /* 2-digit values */
.stats-banner__rep,
.stats-banner__th--rep,
.stats-banner__score,
.stats-banner__th--score { margin-left: var(--space-3); }
.stats-banner__rating,
.stats-banner__rep {
  font-weight: 500; /* a step lighter than the row's 600 */
  color: var(--gray-400);
  font-variant-numeric: tabular-nums;
}
.stats-banner__score { font-variant-numeric: tabular-nums; }
/* Title bar above the rows — same columns + horizontal padding, shorter and
   in small muted caps */
.stats-banner__ranking-head {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 40px;
  margin-bottom: var(--space-0\.5); /* 2px, like the gap between rows */
  padding: 0 var(--space-5);
  background: var(--gray-850);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 10px;
  line-height: 16px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--gray-700);
}
.stats-banner__th--rank {
  flex: 0 0 auto;
  width: 32px;
  text-align: center;
}
.stats-banner__th--name { flex: 1; min-width: 0; }
.stats-banner__driver {
  position: absolute;
  top: 0;
  bottom: 0;
  /* Scroll-linked: moves with the list's slide-up (--reveal 0 → 1, set by
     home-v2.ejs) from the centre of the list (it spans the media from 48px
     in, so 50% + 24px) to its settled spot
     centred under the first about gallery image (48px + (100cqw − 136px) / 6:
     the image starts at the card's 48px padding and is (surface − 2×48px
     padding − 2×20px gaps) / 3 wide). Without JS --reveal is unset → stays
     over the list. */
  left: calc((50% + var(--space-12) / 2) * (1 - var(--reveal, 0)) + (var(--space-12) + (100cqw - 136px) / 6 + var(--driver-shift, 0px)) * var(--reveal, 0));
  transform: translateX(-50%);
  aspect-ratio: 2 / 3; /* the cut-out's proportions (683×1024) */
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  /* Soft shadow following the cut-out's outline, lifting the driver off the
     ranking list behind it */
  filter: drop-shadow(-16px 0 24px rgba(0, 0, 0, 0.4)); /* offset 16px left */
}

/* ---- AchievementsHeader ----------------------------------------------
   288px banner with the card stripe pattern.
   Partial: partials/components/achievements-header
   ---------------------------------------------------------------------- */
.achievements-header {
  position: relative;
  height: 288px; /* same as its corner triangles, so they meet top to bottom */
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* solid page-section gray under the stripes, so background decoration
     (the outlined square behind it) doesn't show through */
  background-color: var(--gray-900);
  background-image: url('/assets/stripe-pattern.svg');
  background-repeat: repeat;
}
/* gray-850 triangle in the top-right corner, like the stats banner's
   (.stats-banner__surface::after: 288px, clipped to the top-right half).
   ::before so it paints first, behind the tagline and driver. */
.achievements-header::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 288px;
  height: 288px;
  background: var(--gray-850);
  clip-path: polygon(0 0, 100% 0, 100% 100%); /* top-right triangle */
  pointer-events: none;
}
/* …and a matching gray-850 triangle in the bottom-left corner (like the
   stats banner's, .stats-banner__surface::before). The tagline is lifted
   above it with z-index, as the triangle comes later in paint order. */
.achievements-header::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 288px;
  height: 288px;
  background: var(--gray-850);
  clip-path: polygon(0 0, 0 100%, 100% 100%); /* bottom-left triangle */
  pointer-events: none;
}
/* Inside the shared achievements card frame: 8px above the list rows, the
   same as the frame's padding around the header */
.achievements-card > .achievements-header { margin-bottom: var(--space-2); }
.achievements-header__trophies {
  position: relative;
  z-index: 1; /* in front of the tagline */
  display: block;
  height: 240px;
  width: auto;
}
/* Tagline behind the trophies, same type as the about card's red headline
   (.about-card__headline: 64px / 64px Bai Jamjuree Bold, uppercase, red-500)
   left-aligned 57px in from the left edge like that headline (its offset
   inside the about card: 1px border + 8px padding + 48px content padding),
   and vertically centred in the banner. Two lines (one <span> each):
   "Winning is" / "in our DNA". */
.achievements-header__title {
  position: absolute;
  top: 50%; /* vertically centred in the banner */
  left: calc(1px + var(--space-2) + var(--space-12));
  transform: translateY(-50%);
  display: flex;
  flex-direction: column; /* one line per <span> */
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 64px;
  line-height: 64px;
  font-weight: 700;
  text-transform: uppercase;
  white-space: nowrap;
  text-align: left;
  color: var(--red-500);
  pointer-events: none;
  z-index: 1; /* above the bottom-left triangle (.achievements-header::after) */
}
/* Below 1080px wide: a bit smaller (64px → 56px type and lines) */
@media (max-width: 1079.98px) {
  .achievements-header__title { font-size: 56px; line-height: 56px; }
}
/* …and below 960px: 48px */
@media (max-width: 959.98px) {
  .achievements-header__title { font-size: 48px; line-height: 48px; }
}

/* Celebrating driver cut-out: on the banner's bottom edge, centred between
   the tagline's right edge and the banner's right edge. The tagline starts
   57px in and its longer line ("IN OUR DNA", 64px Bai Jamjuree Bold) is
   ≈ 371px wide → text ends at 428px; the centre sits half way from there to
   100% (+32px). Update 428px if the tagline text or size changes.
   384px tall in the 288px banner, so the raised fist breaks out 96px above
   its top edge. The image's top-left is transparent, so its box reaching
   into the "Achievements" title row doesn't cover the title itself. */
.achievements-header__driver {
  position: absolute;
  bottom: 0;
  left: calc((100% + 428px) / 2 + var(--space-8)); /* nudged 32px right */
  transform: translateX(-50%);
  z-index: 1;
  display: block;
  height: 384px;
  width: auto;
  cursor: pointer; /* clicking it fires the confetti (confetti.js) */
}
/* Extra layers sharing the driver's box exactly (same class): rocks behind
   the driver, shards in front. Both let clicks through to the driver, which
   fires the confetti. */
.achievements-header__driver--rocks {
  z-index: 0;
  pointer-events: none;
}
.achievements-header__driver--shards {
  z-index: 2;
  pointer-events: none;
}
/* Parallax (--parallax set by home-v2.ejs from the scroll position: about
   −1.3 as the banner enters, 0 at its resting point 64% through, ≈ 0.7 as it
   leaves). The driver stays put; the rocks behind drift one way, the glass
   pieces in front drift the other way, each at its own speed, so they read
   as separate depths. The glass pieces also grow into their size on the way
   in: scale 1 + 0.3 × --parallax (≈ 0.6 when the banner enters), held at
   full size from the resting point on. */
.achievements-header {
  --glass-scale: min(1, calc(1 + var(--parallax, 0) * 0.3));        /* small pieces: from ≈ 0.6 */
  --glass-scale-large: min(1, calc(1 + var(--parallax, 0) * 0.12)); /* big shard layer: from ≈ 0.85 */
}
.achievements-header__driver--rocks  { transform: translate(-50%, calc(var(--parallax, 0) * 20px)); } /* behind */
.achievements-header__driver--shards { transform: translate(-50%, calc(var(--parallax, 0) * -36px)) scale(var(--glass-scale-large)); } /* in front, grows less */
.achievements-header__shard          { transform: translate(-100%, calc(var(--parallax, 0) * -24px)) scale(var(--glass-scale)); } /* in front, slower */
.achievements-header__shard--right   { transform: translate(0, calc(var(--parallax, 0) * -52px)) scale(var(--glass-scale)); }      /* in front, fastest */
/* Crystal shard left of the driver: its right edge sits at the driver
   image's left edge (driver centre − half its width: 384px tall at 951:650
   → ≈ 562px wide → 281px), 16px above the banner's bottom edge. Shown at
   56 × 43px (2/3 of its 85 × 65px source, so it stays sharp). */
.achievements-header__shard {
  position: absolute;
  bottom: var(--space-4);
  left: calc((100% + 428px) / 2 + var(--space-8) - 281px + var(--space-2)); /* +8px: overlaps the driver image's edge a little */
  z-index: 1;
  display: block;
  width: 56px;
  height: 43px;
  pointer-events: none;
}
/* Second crystal pair at the banner's right edge, overlapping it by
   16px, 16px above the bottom. Shown at
   59 × 64px, 50% of its source. */
.achievements-header__shard--right {
  left: auto;
  right: calc(-1 * var(--space-4)); /* 16px past the banner's right edge */
  bottom: var(--space-4); /* 16px above the bottom, level with the left shard */
  width: 59px;
  height: 64px;
}
/* Glass shard (40 × 46px, ≈ 50% of its source) in the gap between the lineup
   driver card and the achievements header, centred under the driver image.
   It lives in the Achievements section (the Lineup section clips its bottom
   overflow), positioned against its content wrapper (content + 2 × 40px
   padding): the driver image is centred a quarter into the driver card's
   inner surface + 16px, the card being the right ⅔ of the lineup grid →
   50% + 30.5px of the wrapper. Vertically halfway between the card's bottom
   (the section top) and the header's top 113px below → 56.5px. */
.achievements-gap-shard {
  position: absolute;
  left: calc(50% + 30.5px);
  top: 56.5px;
  width: 40px;
  height: 46px;
  /* scroll parallax (--parallax on the content wrapper, set by home-v2.ejs
     from the heading row's position; 0 = resting): drifts diagonally up and
     to the left (45°) as you scroll down */
  transform: translate(calc(-50% + var(--parallax, 0) * -32px), calc(-50% + var(--parallax, 0) * -32px));
  z-index: 1;
  pointer-events: none;
}

/* Same gray → red fill as the about headline (see .about-card__headline):
   lines hug their text; driven by data-intro on the header (home-v2.ejs) */
.achievements-header__title > span { align-self: flex-start; }
.achievements-header[data-intro] .achievements-header__title > span {
  color: transparent;
  -webkit-background-clip: text;
          background-clip: text;
  background-image: linear-gradient(var(--red-500), var(--red-500)), linear-gradient(var(--gray-750), var(--gray-750));
  background-repeat: no-repeat;
  background-size: 0% 100%, 100% 100%;
}
.achievements-header[data-intro="in"] .achievements-header__title > span {
  animation: headline-fill 0.35s cubic-bezier(0.65, 0, 0.35, 1) both;
}
.achievements-header[data-intro="in"] .achievements-header__title > span:nth-child(2) { animation-delay: 0.08s; }

/* Scroll reveal (driven by home-v2.ejs): each row's content fades in once the
   row is in view; the row background stays. The "and many more" note row has
   only text, so its colour fades in instead. */
[data-row-reveal] .list__row .achievement-item {
  opacity: 0;
  transition: opacity 0.6s ease-out var(--row-delay, 0ms);
}
[data-row-reveal] .list__row.is-revealed .achievement-item { opacity: 1; }
[data-row-reveal] .list__row.list__row--note { /* beats .list__row.list__row--note further down */
  color: transparent;
  transition: color 0.6s ease-out var(--row-delay, 0ms);
}
[data-row-reveal] .list__row.list__row--note.is-revealed { color: var(--gray-700); }
/* Decorative crystals (68 × 70px, 50% of the source) outside the list, 16px
   left of the card's left border, vertically centred on the "P1 Gaming 24h
   Daytona" row. Anchored to that row's item, which starts 20px (row padding)
   + 8px (card padding) + 1px (border) in from the card edge → 45px total. */
.achievement-item--crystals { position: relative; }
.achievement-item__crystals {
  position: absolute;
  top: 50%;
  right: calc(100% + 20px + 1px + var(--space-2) + var(--space-4));
  /* drifts slightly up and turns clockwise as you scroll (--parallax set on
     the row by home-v2.ejs; 0 = resting): ≈ −20° → +12°, like the contact shards */
  transform: translateY(calc(-50% + var(--parallax, 0) * -24px))
             rotate(calc(var(--parallax, 0) * 16deg));
  width: 68px;
  height: 70px;
  pointer-events: none;
}
/* Achievement list row — series (logo + name) left, medals right */
.achievement-item {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}
.achievement-item__series {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-width: 0;
}
.achievement-item__logo {
  display: block;
  height: 20px;
  width: 20px;
  object-fit: contain;
  flex: 0 0 auto;
}
.achievement-item__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.achievement-item__medals {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex: 0 0 auto;
}
.achievement-item__medal {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
}
.achievement-item__medal img {
  display: block;
  height: 16px;
  width: auto;
}
.achievement-item__num {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  color: #fff;
}
.achievement-item__sep {
  width: 1px;
  height: 16px;
  background: var(--gray-700);
  flex: 0 0 auto;
}

/* ---- Footer ----------------------------------------------------------
   120px, full-width, gray-900. White logo left, links right.
   Partial: partials/components/footer
   ---------------------------------------------------------------------- */
.site-footer {
  width: 100%;
  height: 120px; /* content centred vertically */
  background: var(--gray-900);
}
.site-footer__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
/* Scroll reveal (driven by home-v2.ejs): logo + links fade in when the
   footer comes into view, and out again when it leaves; the footer
   background stays */
.site-footer[data-reveal] .site-footer__inner {
  opacity: 0;
  transition: opacity 0.6s ease-out;
}
.site-footer[data-reveal="in"] .site-footer__inner { opacity: 1; }
.site-footer__brand { display: inline-flex; align-items: center; }
.site-footer__logo { display: block; height: 16px; width: auto; }
.site-footer__links {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
.site-footer__link {
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  color: #fff;
  text-decoration: none;
  transition: var(--transition);
}
.site-footer__link:hover { color: var(--yellow-500); }

/* ---- List ------------------------------------------------------------
   Stacked rows. Partial: partials/components/list
   ---------------------------------------------------------------------- */
.list {
  display: flex;
  flex-direction: column;
  gap: var(--space-0\.5); /* 2px between rows */
}
/* Rows hidden by a filter (e.g. lineup category filter) */
.list__row.is-filtered-out { display: none; }
.list__row {
  display: flex;
  align-items: center; /* vertically center content */
  min-height: 64px;
  padding: var(--space-3) var(--space-5); /* 12px top/bottom · 20px left/right */
  background: var(--gray-850);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 24px;
  font-weight: 600; /* semibold */
  text-transform: uppercase;
  color: #fff;
}
/* Non-link rows use gray-800 */
.list__row:not(.list__row--link) {
  background: var(--gray-800);
}
/* Note row — centered muted text (e.g. "and many more") */
.list__row.list__row--note {
  justify-content: center;
  background: var(--gray-850);
  color: var(--gray-700);
}
/* Link row — chevron on the right, 2px accent border on the left */
.list__row--link {
  justify-content: space-between;
  gap: var(--space-4);
  border-left: 2px solid var(--gray-800);
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.list__label {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.list__label-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.list__label-meta {
  font-size: 10px;
  line-height: 16px;
  font-weight: 400;
  color: var(--gray-400);
}
.list__chevron {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--gray-700);
  transition: color 0.15s ease;
}
.list__row--link:hover {
  background: var(--gray-800);
  border-left-color: var(--gray-750);
  color: #fff;
}
.list__row--link:hover .list__chevron { color: #fff; }
/* Current/selected row — red accent border + chevron, hover background */
.list__row--link.is-active {
  background: var(--gray-800);
  border-left-color: var(--red-500);
  color: #fff;
}
.list__row--link.is-active .list__chevron { color: var(--red-500); }

/* Whole news card is the link; no hover effect on the card itself. The "Read more"
   is a span (styled like the outlined button) so it keeps its own :hover, and clicks
   on it still bubble up to activate the card link. */
.news-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
}
/* News card content */
.news-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.news-card__meta {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 10px;
  line-height: 16px;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--gray-400);
}
.news-card__title {
  margin: var(--space-2) 0 var(--space-4); /* 8px above (gap to meta), 16px below */
  height: 84px;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 16px;
  line-height: 28px;
  font-weight: 600;
  text-transform: uppercase;
  color: #fff;
  /* clamp to 3 lines with ellipsis */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- ContentHeader ---------------------------------------------------
   Full-width 96px header row with a left-aligned, vertically-centered title.
   Partial: partials/components/content-header
   ---------------------------------------------------------------------- */
.content-header {
  width: 100%;
  height: 104px;
  display: flex;
  align-items: center; /* vertically center the content */
}
/* Scroll reveal (driven by home-v2.ejs): fades in 0.2s after the heading is
   fully in view */
[data-heading-reveal] .content-header__title {
  opacity: 0;
  transition: opacity 0.6s ease-out 0.2s;
}
[data-heading-reveal] .content-header__title.is-revealed { opacity: 1; }
.content-header__title {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 20px;
  line-height: 28px;
  font-weight: 600; /* semibold */
  text-transform: uppercase;
  text-align: left;
  color: #fff;
}
/* Centered variant */
.content-header--center { justify-content: center; }
.content-header--center .content-header__title { text-align: center; }
/* Lines variant — a 32px line pinned to the left and right edges; title centered */
.content-header--lines { justify-content: space-between; }
.content-header--lines .content-header__line { margin: 0; } /* override the right-line auto margin */
/* Scroll reveal (with the heading fade, driven by home-v2.ejs): the two lines
   start at the centre of the header, transparent, and slide out to their
   edges while fading in. The header is a size container so the offset can
   be half its width (50cqw − half a line). */
.content-header--lines { container-type: inline-size; }
[data-heading-reveal] .content-header--lines .content-header__line {
  opacity: 0;
  transition: opacity 0.6s ease-out 0.2s, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.2s;
}
[data-heading-reveal] .content-header--lines .content-header__line:first-child { transform: translateX(calc(50cqw - 16px)); }
[data-heading-reveal] .content-header--lines .content-header__line:last-child { transform: translateX(calc(-50cqw + 16px)); }
[data-heading-reveal] .content-header--lines:has(.content-header__title.is-revealed) .content-header__line {
  opacity: 1;
  transform: none;
}
/* Red glow (.content-header--glow, added by home-v2.ejs to the About header):
   while the header is in the top half of the viewport (.is-lit) a red
   gradient sweeps along both lines from the title outwards, turning them
   red; it sweeps back when the header drops below the middle again. The red
   layer is twice the line's length with a soft tail, so at full size it
   covers the whole line. */
.content-header--glow .content-header__line {
  background-color: var(--gray-750);
  background-repeat: no-repeat;
  background-size: 0% 100%;
  transition: background-size 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.content-header--glow .content-header__line:first-child { /* fills right → left */
  background-image: linear-gradient(to left, var(--red-500) 50%, rgba(255, 27, 78, 0));
  background-position: right center;
}
.content-header--glow .content-header__line:last-child {  /* fills left → right */
  background-image: linear-gradient(to right, var(--red-500) 50%, rgba(255, 27, 78, 0));
  background-position: left center;
}
.content-header--glow.is-lit .content-header__line { background-size: 200% 100%; }
/* keep the scroll-reveal slide/fade transitions alongside the glow */
[data-heading-reveal] .content-header--glow .content-header__line {
  transition: opacity 0.6s ease-out 0.2s, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.2s,
              background-size 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Optional 32px line on the right side */
.content-header__line {
  flex: 0 0 auto;
  width: 32px;
  height: 1px;
  margin-left: auto;
  background: var(--gray-750);
}
/* Optional right-side actions (e.g. pager buttons) */
.content-header__actions {
  flex: 0 0 auto;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
/* Pager button group — segmented look, no gap between the buttons */
.news-nav {
  display: inline-flex;
  align-items: center;
  gap: 0;
  background: var(--gray-850);
  border-radius: var(--radius-xs); /* 2px */
  overflow: hidden;
}

.hero {
  position: relative;
  width: 100%;
  height: 744px; /* was 920px, 856px, 848px (8px off the top), then −104px: no bottom padding, so the gap from the event banner to the News title matches the one between the News cards and the Lineup title */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-6);
  padding: 56px 0 0; /* 56px top (was 64px: everything sits 8px higher) · no bottom padding (was 104px) */
  text-align: center;
  background: var(--gray-950);
  background-size: cover;
  background-position: center;
  overflow: visible; /* let the scroll indicator overflow the bottom edge */
}

/* Red diagonal line in the hero background, along the left edge of the
   home page's background artwork (its diagonal cut, which continues the left
   edge of the event banner's darker middle band: x + y = centre + 476.628px
   in the 848px hero, whose content sits 8px higher than in the 856px one),
   from level with the gap between the two big headline lines up to the
   hero's top edge. With the headline block centred in the area between the
   navbar and the tabs (+ its 20px nudge), "SIMRACING"'s letters end at 292px
   and "KARTING"'s start at 308px (Bai Jamjuree: 84px type in 76px lines,
   after the 28px kicker line; measured in the 920px hero, 32px higher in the
   856px one, 8px higher again in the 848px one), so the gap's middle is
   292.5px down (88px type in 80px lines: "SIMRACING" ends 284px down,
   "KARTING" starts 301px down; measured) → the line's bottom end is
   476.628 − 292.5 = 184.128px right of the centre on that diagonal. From there to the top: 292 × √2 ≈ 413px
   (capped by the space to the hero's right edge, so it never overflows
   sideways).
   Behind all hero content.
   These numbers depend on the hero layout; update them if it changes. */
.hero::before {
  content: '';
  position: absolute;
  left: calc(50% + 192.128px); /* on the artwork's edge, 8px right of the banner band's continuation */
  bottom: calc(744px - 292.5px); /* 292.5px down the 744px hero */
  width: calc(min(292.5px, 50% - 192.128px) * 1.4142);
  height: 1px;
  /* fades in from its bottom end: transparent there, full red 184px along
     the line (130px higher); solid above */
  background: linear-gradient(to right, rgba(255, 27, 78, 0) 0, var(--red-500) 184px);
  transform: rotate(-45deg);
  transform-origin: left bottom;
  pointer-events: none;
}
/* Below 1000px the hero is 129px shorter (744 → 615px) and the heading block
   moves up 81px (64.5px from the shorter centring area, 16.5px from a smaller
   nudge), so the space from the logo to "ADDICTED TO" equals the space from
   "SINCE 2010" to the event tabs. The red line from the top follows: the
   banner, and so the diagonal it continues, rose 129px (x + y = centre +
   355.628px), and the gap between the heading lines is now 211.5px down →
   its end is 144.128px right of the centre. */
@media (max-width: 999.98px) {
  /* 615px, + 4px that only push the event banner down (its margin), so the
     heading, car and driver stay put */
  .hero { height: 619px; }
  .hero:has(.hero__headline-area) .hero__content { margin-top: var(--space-1); }
  /* (the banner — and the diagonal the line continues — sits 4px lower than
     the 129px-higher spot: x + y = centre + 359.628px → end 148.128px right) */
  .hero::before {
    left: calc(50% + 148.128px);
    bottom: calc(619px - 211.5px);
    width: calc(min(211.5px, 50% - 148.128px) * 1.4142);
  }
}
/* Panel behind the red diagonal and the gray triangle, on the right half of
   the hero's content area: from the page centre to the content's right edge
   (ContentWrapper: 1260px max − 2 × 40px padding; see the diagonal below
   for the exact left edge). Its bottom is the
   triangle's bottom (515px down, 405px above the hero's bottom); its top
   leaves the same 52px gap below the nav links (their text box ends 87px
   down, incl. the 32px resting offset) as there is above the event tabs
   (text box starts 567px down) → 139px, so it is 376px tall.
   The left side is a 45° diagonal (parallel to the red line; the top-left
   corner sits one panel height, 376px, right of the bottom-left) collinear
   with the left edge of the darker diagonal band in the middle of the event
   banner (events-shadow.svg: 520×164, centred in the banner's inner surface,
   whose centre is 726px down; band edge x + y = 164.628 in SVG units →
   x + y = centre + 548.628px on the page → at the panel's bottom (515px)
   it is 33.628px right of the page centre).
   Plain gray-900 fill, no border.
   The panel and the gray triangle on its bottom-right corner sit in one
   group (.hero__panel-group) that fades in as a whole once the page has
   loaded (the hero partial's script holds it on .is-waiting until then).
   The hero is isolated so the group (z-index −1) sits above the hero's
   background but behind the line (::before) and all content. */
.hero { isolation: isolate; }
.hero__panel-group {
  --panel-h: 376px;
  position: absolute;
  left: calc(50% + 33.628px);
  right: calc((100% - min(1180px, 100% - 2 * var(--space-10))) / 2);
  top: 139px;
  height: var(--panel-h);
  z-index: -1;
  pointer-events: none;
}
.hero__panel {
  position: absolute;
  inset: 0;
  background: var(--gray-900);
  clip-path: polygon(var(--panel-h) 0, 100% 0, 100% 100%, 0 100%);
}
.hero__panel { display: none; } /* hidden for now — the video shows in the big centred triangle instead; remove this line to bring the panel back */
/* Base triangle styles (the corner triangle itself is no longer rendered;
   the big centred triangle below builds on these).
   Triangle in the event banner's surface colour (gray-800,
   .event-banner__inner), right-angled at the panel's bottom-right corner
   (the content's right edge). It continues the banner's lighter right side:
   its diagonal is collinear with the right edge of the darker middle band
   (events-shadow.svg, see the panel's left edge above: the band is
   251.429 SVG units wide perpendicular → 355.572px horizontally, so its
   right edge is x + y = centre + 904.2px → at the panel's bottom it is
   389.2px right of the page centre). The group starts 33.628px right of
   the centre, so the triangle is 100% − 355.572px of the group wide
   (≈ 201px at the full 1180px content width). */
.hero__panel-triangle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: calc(100% - 355.572px);
  aspect-ratio: 1;
  background: var(--gray-800);
  clip-path: polygon(100% 0, 100% 100%, 0 100%); /* bottom-right triangle */
}
/* Big triangle centred on the page, pointing down: its top edge on the
   panel's top line, its tip on the page centre and 45° sides, sized so its
   right side lies on the panel's left edge (x + y = centre + 548.628px): the
   tip is then 548.628px down, i.e. 376 + 33.628 = 409.628px below the top →
   819.256px wide. gray-900 like the panel; it sits behind the headline. */
.hero__panel-triangle--centre {
  --tri-h: calc(var(--panel-h) + 33.628px);
  right: auto;
  left: calc(-33.628px - var(--tri-h)); /* page centre (group starts 33.628px right of it) − half its width */
  top: 0;
  bottom: auto;
  width: calc(2 * var(--tri-h));
  height: var(--tri-h);
  aspect-ratio: auto;
  background: var(--gray-900);
  clip-path: polygon(0 0, 100% 0, 50% 100%); /* tip at the bottom */
}
@media (prefers-reduced-motion: no-preference) {
  .hero__panel-group { transition: opacity 1.4s ease-out; }
  .hero__panel-group.is-waiting { opacity: 0; }
}
/* Optional video (heroPanelVideo), now inside the big centred triangle:
   fills the whole triangle box (cut to its shape by the triangle's clip-path), desaturated to grayscale and
   at 20% opacity over the triangle's gray-900 fill so the red line and the triangle stay readable. */
.hero__panel-filter { position: absolute; width: 0; height: 0; overflow: hidden; }
.hero__panel-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.hero__panel-video {
  position: absolute;
  /* Extends 98px above the triangle box (clipped there) and ends at its
     bottom: the centred, covering frame then sits 49px higher than in the
     box itself (and ≈ 10% larger, cropping a little off the sides), with
     no gap at the tip */
  top: -98px;
  bottom: 0;
  left: 0;
  width: 100%;
  height: calc(100% + 98px);
  object-fit: cover;
  filter: grayscale(1); /* fallback: black & white */
  filter: url(#hero-video-tint); /* grayscale in the event banner's gray tone (SVG filter in hero.ejs) */
  opacity: 0.2; /* over the panel's gray-900 fill */
}
/* Gradients over the video's top and bottom halves in the hero background
   (gray-950 #0F1011) — solid at both edges, clear in the middle */
.hero__panel-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, var(--gray-950) 0, rgba(15, 16, 17, 0) 50%, var(--gray-950) calc(100% - 40px)); /* bottom: solid from 40px above the tip */
}
/* On page load the line draws itself from its top end down to its bottom end:
   clip-path works in the line's own (unrotated) box, where its top end is
   the right side, so the inset shrinks from 100% on the left to 0. */
@media (prefers-reduced-motion: no-preference) {
  .hero::before { animation: hero-line-draw 1.2s cubic-bezier(0.65, 0, 0.35, 1) 0.4s both; }
}
@keyframes hero-line-draw {
  from { clip-path: inset(0 0 0 100%); }
  to   { clip-path: inset(0 0 0 0); }
}
.hero__scroll {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 50%); /* center on the bottom edge */
  display: flex; /* hug the 32px icon exactly (no line-height gap) */
}
/* A 32px gray-750 line at the content's left edge, between the event banner
   and the News title, like the lines beside the event tabs — and as far
   below the event panel as those are above it: the tab lines run 575.5px →
   576.5px down, the panel 636px → 816px, so 59.5px gaps → this line at
   875.5px, i.e. 43.5px above the hero's bottom (its bottom edge). */
.hero:has(.event-banner)::after {
  content: none; /* removed: with no space below the event banner it would sit on it */
  position: absolute;
  left: calc((100% - min(1180px, 100% - 2 * var(--space-10))) / 2); /* content's left edge */
  bottom: 43.5px;
  width: 32px;
  height: 1px;
  background: var(--gray-750);
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .hero:has(.event-banner)::after { animation: fade-in 0.6s ease-out 1s both; }
}

/* ---- ScrollIndicator -------------------------------------------------
   Circular "scroll down" badge. Partial: partials/components/scroll-indicator
   ---------------------------------------------------------------------- */
.scroll-indicator {
  display: inline-flex;
  border-radius: 50%;
}
.scroll-indicator__svg { display: block; }
.scroll-indicator__ring { fill: none; stroke: var(--red-500); stroke-width: 1; } /* 1px ring inside the 32px box */
.scroll-indicator__chevron {
  fill: none;
  stroke: var(--red-500);
  stroke-width: 1.5;
}

.hero__title {
  margin: 0;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: var(--font-2xl);
  font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text-primary);
}

.hero__subtitle {
  margin: 0;
  max-width: 640px;
  font-size: var(--font-lg);
  color: var(--text-secondary);
}

.hero__actions {
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  justify-content: center;
}

/* Background video (optional, partials/components/hero heroVideo): fills the
   hero behind everything, cropped to cover. A dark overlay keeps the navbar
   and event banner readable and fades to the hero's gray-950 at the bottom so
   it blends into the next section. */
.hero__video,
.hero__video-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.hero__video { object-fit: cover; }
.hero__video-overlay {
  background: linear-gradient(to bottom,
    rgba(15, 16, 17, 0.6) 0%,      /* gray-950: darker under the navbar */
    rgba(15, 16, 17, 0.45) 35%,
    rgba(15, 16, 17, 0.7) 75%,     /* behind the event banner */
    var(--gray-950) 100%);
}
/* Hero content sits above the video + overlay */
.hero > :not(.hero__video):not(.hero__video-overlay):not(.hero__scroll):not(.hero__panel-group) { position: relative; z-index: 1; }
/* Optional headline (heroHeadline) on the left: the area spans the page
   content width (the ContentWrapper's 1260px max − 2 × 40px padding) and
   centres the headline vertically in the free space between the fixed main
   navbar and the event banner's tab row — it starts at the navbar's bottom
   (≈ 75px: 16px wrap padding + 59px bar, i.e. 11px below the hero's 64px top
   padding) and ends at the tabs (the hero's 24px gap is cancelled); the
   content below then only takes its own height. */
.hero__headline-area {
  flex: 1 1 auto;
  min-height: 0;
  width: min(1180px, 100% - 2 * var(--space-10));
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding-top: 11px;
  margin-bottom: calc(-1 * var(--space-6));
}
.hero:has(.hero__headline-area) .hero__content { flex: 0 0 auto; }
/* With an image beside it (heroAside): headline left, image right */
.hero__headline-area:has(.hero__aside) {
  justify-content: space-between;
  gap: var(--space-6);
}
/* Car on the right of the headline: up to 640px wide (≈ 271px tall for the
   1262 × 535 source, ~2x for that), shrinking with the window */
.hero__aside {
  display: block;
  flex: 0 1 640px;
  min-width: 0;
  width: 640px;
  max-width: 100%;
  height: auto;
  position: relative;
  left: var(--space-6); /* nudged 24px right, past the content edge */
  top: 38px; /* and 38px down */
  /* tilted 0.5° clockwise; mouse parallax (--hero-mx, −1 … 1, set on
     .page-hero by home-v2.ejs): drifts up to 10px against the mouse */
  transform: translateX(calc(var(--hero-mx, 0) * -10px)) rotate(0.5deg);
}
/* Car size on narrower screens (down to 1000px): instead of shrinking into
   the space left beside the heading (with a 24px gap), it may come closer —
   its transparent left part (the first 8.53% of the image) can overlap the
   gap, as long as the car body stays 12px clear of the wide heading's 484px:
   the car ends 24px past the area's right edge, so its body starts at
   area + 24 − 0.9147 × width ≥ 496px → width ≤ (area − 472px) / 0.9147.
   That keeps it full size (640px) down to the 1140px breakpoint; below it the
   same curve continues (no jump when the heading gets smaller there). The
   area is a size container so 100cqw = its width; the large negative margin
   lets the car overlap the gap instead of being squeezed by the flex row
   (space-between still places it at the right end). */
.hero__headline-area:has(.hero__aside) { container-type: inline-size; }
.hero__aside {
  flex: 0 0 auto;
  width: min(640px, (100cqw - 472px) / 0.9147);
  max-width: none;
  margin-left: -200px;
}
/* Driver standing in front of the car (heroAside.overlay): 340 × 358px
   (681 × 717 source), positioned from the headline area's bottom-right like
   the car (which hugs the area's right edge, 24px past it, and is centred
   vertically + 40px): feet just below the car's wheels, the figure
   horizontally centred on the car. The car (640px wide, 24px past the
   area's right edge) is centred 296px left of that edge; the figure spans
   x 75–321 of the 681px source → its middle is 96.6px into the 332px image,
   so the image's right edge is 296 − (332 − 96.6) ≈ 60.5px left of the area's. */
.hero__aside-overlay {
  position: absolute;
  right: -29.25px; /* centred on the car, then 84px right (at 340px wide) */
  /* vertically centred on the heading text: "ADDICTED TO" … "SINCE 2010"
     (and "SIMRACING & KARTING" alone) are centred 328.5px down the hero; the
     figure (helmet to feet, rows 3–705 of the 717px source) has its middle
     172.8px into the 350px image → image bottom 505.7px down, 57.3px above
     the headline area's bottom (563px); then 8px up, 8px down with the car
     and 4px up with it again, then 4px up, then 4px down with the car,
     then 4px up, then 4px down, then 2px up; −32px for the 64px shorter
     hero (the area's bottom rose 64px, the car — centred in it — only 32px);
     then 4px down */
  bottom: 27.3px;
  width: 340px;
  height: 358px; /* 8px taller; grows upward from the feet, figure stays put horizontally */
  z-index: 1; /* over the car */
  pointer-events: none;
  /* mouse parallax: drifts up to 24px against the mouse — more than the car
     behind it */
  transform: translateX(calc(var(--hero-mx, 0) * -24px)); /* was 16px */
}
/* Below 1080px the driver scales down with the window (--car-w: the width
   the car used to have here, 485px at the breakpoint), keeping
   its place in front of the car: size, right offset and the feet's height
   above the car's (fixed) vertical centre all proportional to the car width.
   The area is made a size container so 100cqw = its width. */
@media (max-width: 1079.98px) {
  .hero__aside-overlay {
    --car-w: min(50cqw - 11px, 100cqw - 442px);
    width: calc(var(--car-w) * 0.70103);          /* 340px at 485px */
    height: calc(var(--car-w) * 0.73814);         /* 358px at 485px */
    right: calc(var(--car-w) * -0.01085 - 24px);  /* −29.25px at 485px */
    bottom: calc(174px - var(--car-w) * 0.30247); /* 27.3px at 485px */
  }
}
/* Below 1000px the headline area is 97px shorter, the car's centre only
   48.5px higher (it's centred in it): the feet keep their place on the car;
   then 24px higher, clear of the event tabs, and 32px further right.
   The car itself is ≈ 10% bigger here (and may come 22px closer to the
   heading); the driver scales with it (same --car-w). */
@media (max-width: 999.98px) {
  .hero__aside,
  .hero__aside-overlay { --car-w: min(60cqw - 12px, 100cqw - 376px); } /* smaller heading (≈ 374px) + 24px gap − 22px */
  .hero__aside {
    width: var(--car-w);
    top: 18px; /* 20px higher than above 1000px (38px) */
  }
  /* The driver doesn't take the car's extra size: it keeps the size it has
     just above 1000px (--drv-w, the 1080px rule's car width) so it doesn't
     jump bigger at the breakpoint, while staying at the same spot on the
     (bigger) car — feet height and figure centre follow the car's width. */
  .hero__aside-overlay {
    --drv-w: min(50cqw - 11px, 100cqw - 442px);
    width: calc(var(--drv-w) * 0.70103);
    height: calc(var(--drv-w) * 0.73814);
    bottom: calc(157.5px - var(--car-w) * 0.30247); /* +24px: another 24px higher; −16px for the 32px shorter hero */
    right: calc(var(--car-w) * 0.48639 - var(--drv-w) * 0.49724 - 64px); /* 40px right of the centred spot */
  }
}
/* Large left-aligned headline: Bai Jamjuree Bold, uppercase, red-500 like the
   about card's headline, at 88px / 80px */
.hero__headline {
  margin: 0;
  position: relative;
  top: 20px; /* whole block 20px below its centred spot */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 88px;
  line-height: 80px; /* slightly tighter than the 88px type */
  font-weight: 700;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--red-500);
}
/* Below 1140px wide: a bit smaller (88px → 76px type, 80px → 70px lines) */
@media (max-width: 1139.98px) {
  .hero__headline { font-size: 76px; line-height: 70px; }
}
/* Below 1000px (shorter hero, see .hero::before): 16.5px less nudge, and a
   bit smaller again (76px → 68px type, 70px → 63px lines) */
@media (max-width: 999.98px) {
  .hero__headline { top: 3.5px; font-size: 68px; line-height: 63px; }
}
/* Big lines: word spacing tightened by 0.045em (4px at 88px) so the "K" of
   "& KARTING" starts exactly under the "M" of "SIMRACING" — measured from
   Bai Jamjuree Bold: M's ink starts 88px in (S + I + its side bearing); "&"
   is 61.2px wide and K's side bearing 5.5px, so the gap must be 21.3px
   instead of a 25.3px space. */
.hero__headline > span:not(.hero__kicker) { word-spacing: -0.045em; }
/* 2px white line under the headline, as long as the event banner's corner
   brackets are wide (.event-banner__corner: 32px) */
/* "EST. 2010" below the headline, where the short white line used to be:
   styled like the event banner's tab labels (.tabbar__tab: 14px / 24px,
   regular, uppercase), in white. Same visible gap to "& KARTING" as
   between "ADDICTED TO" and "SIMRACING" (Bai Jamjuree: ascent 1.0em, cap
   height 0.7em):
   - above: kicker baseline 25px − 16px nudge = 9px below the block top;
     "SIMRACING" cap top 32 − 15 (half-leading) + 88 − 61.6 = 43.4px → 34.4px
   - below: "& KARTING" baseline 7px above its line box's bottom; "EST."
     caps start 7.45px into its 24px line → margin + 14.45 = 34.4 → 20px.
   The short line took 43 + 2 = 45px of height, this takes 20 + 24 = 44px,
   so +1px at the bottom keeps the block's height — and the headline's
   centred position, which the red line and the shapes are aligned to —
   unchanged. */
.hero__headline > .hero__est {
  margin-top: 21px; /* measured: 33px of empty space above and below the heading's letters */
  margin-bottom: -5px; /* keeps the block's height (and centred position) as with the old 14px / 24px line and 20px margin */ /* keeps the block's height (and centred position) as with the old 14px / 24px line and 20px margin */
  /* same type as "ADDICTED TO" (.hero__kicker) */
  font-size: 20px;
  line-height: 28px;
  font-weight: 400;
  letter-spacing: 0.04em;
  word-spacing: normal;
  color: #fff;
}
/* Below 1140px (smaller heading): 2px less above keeps the gaps above and
   below the heading equal (measured: 31px each) */
@media (max-width: 1139.98px) {
  .hero__headline > .hero__est { margin-top: 19px; margin-bottom: -3px; }
}
/* Small white line above the headline ("ADDICTED TO"): 24px, regular weight */
.hero__kicker {
  position: relative;
  top: calc(-1 * var(--space-4)); /* sits 16px higher, leaving the big lines in place */
  font-size: 20px;
  line-height: 28px;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: #fff;
}
/* Below 1000px "ADDICTED TO" and "SINCE 2010" are smaller too (20px → 16px
   type, 28px → 24px lines) and sit closer to the heading */
@media (max-width: 999.98px) {
  .hero__kicker,
  .hero__headline > .hero__est { font-size: 16px; line-height: 24px; }
  .hero__kicker { top: -10px; }                                          /* 24px clear above the heading */
  .hero__headline > .hero__est { margin-top: 11px; margin-bottom: 5px; } /* 24px clear below it */
}
.hero__content {
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end; /* bottom-align the contentWrapper / EventBanner */
}

/* ---- Section heading ------------------------------------------------- */
.section-heading {
  margin: 0 0 var(--space-4);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: var(--font-xl);
  font-weight: 600;
  color: var(--text-primary);
}

/* ---- Card ------------------------------------------------------------
   Bordered panel with red corner brackets — the EventBanner panel look,
   without the tab bar or the background stripes. Partial: partials/components/card
   ---------------------------------------------------------------------- */
.ds-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--space-2); /* 8px */
  background: var(--gray-900);
  border: 1px solid var(--gray-850);
}
/* Plain variant — no outer frame or corner brackets, just the gray-800 inner */
.ds-card--plain {
  padding: 0;
  background: transparent;
  border: none;
}
.ds-card__inner {
  flex: 1; /* fill the card height (e.g. equal-height grid cells) */
  display: flex;
  flex-direction: column;
  background: var(--gray-800);
}
/* Content area — 32px padding all around (the image section stays flush) */
.ds-card__content {
  padding: var(--space-8); /* 32px */
}
/* Optional top image section — 160px, flush to the inner's top/left/right edges,
   striped-pattern background */
.ds-card__image {
  height: 160px;
  background-image: url('/assets/stripe-pattern.svg');
  background-repeat: repeat;
  overflow: hidden;
}
.ds-card__image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* News cards: the image area takes the shape of the latest news image
   (1128 × 640, ≈ 1.76 : 1) instead of the fixed 160px strip, so it shows in
   full; it scales with the card width. Older 690 × 480 banners fill it with a
   little cropped off their top and bottom. */
.news-item .ds-card__image {
  height: auto;
  aspect-ratio: 1128 / 640;
}
/* Decorative L-shaped corner brackets */
.ds-card__corner {
  position: absolute;
  width: 32px;
  height: 32px;
  pointer-events: none;
}
.ds-card__corner--tl { top: 0; left: 0; border-top: 2px solid var(--red-500); border-left: 2px solid var(--red-500); }
.ds-card__corner--tr { top: 0; right: 0; border-top: 2px solid var(--red-500); border-right: 2px solid var(--red-500); }
.ds-card__corner--bl { bottom: 0; left: 0; border-bottom: 2px solid var(--red-500); border-left: 2px solid var(--red-500); }
.ds-card__corner--br { bottom: 0; right: 0; border-bottom: 2px solid var(--red-500); border-right: 2px solid var(--red-500); }

/* ---- Overlay ---------------------------------------------------------
   Absolutely-positioned panel covering its positioned parent with a 16px
   inset. gray-800 bg, 2px radius, scrolled-navbar border + shadow, close (X)
   button top-right. Partial: partials/components/overlay
   ---------------------------------------------------------------------- */
/* Container — covers the positioned parent */
.overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: block;
}
.overlay[hidden] { pointer-events: none; }
/* Backdrop — dims the parent; fades in with the overlay */
.overlay__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(17, 18, 19, 0.64); /* gray-900 @ 64% */
  opacity: 1;
  transition: opacity 0.25s ease;
}
.overlay[hidden] .overlay__backdrop { opacity: 0; }
/* Panel — 346px, right-anchored with a 16px margin; slides in from the right */
.overlay__panel {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  width: 346px;
  display: flex;
  flex-direction: column;
  overflow: hidden; /* clip children to the rounded corners */
  background: var(--gray-800);
  border: 1px solid transparent;
  border-top-color: rgba(255, 255, 255, 0.04); /* white @ 4% (like scrolled navbar) */
  border-bottom-color: var(--gray-900);
  border-radius: var(--radius-xs); /* 2px */
  box-shadow: 0 0 16px rgba(0, 0, 0, 0.24); /* 16px blur, black @ 24% */
  transform: translateX(0);
  transition: transform 0.25s ease;
}
.overlay[hidden] .overlay__panel {
  transform: translateX(calc(100% + var(--space-4))); /* parked off to the right */
}
@media (prefers-reduced-motion: reduce) {
  .overlay__backdrop, .overlay__panel { transition: none; }
}
/* Header bar — title left, close X right */
.overlay__header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4) var(--space-3) var(--space-5); /* 12px · 16px right · 20px left */
  background: var(--gray-800);
  border-bottom: 1px solid var(--gray-900);
}
.overlay__title {
  min-width: 0; /* allow ellipsis inside the flex header */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 14px;
  line-height: 24px;
  font-weight: 600; /* semibold */
  text-transform: uppercase;
  color: #fff;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap; /* clamp to one line */
}
.overlay__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-6); /* 24px */
}
.overlay__body::-webkit-scrollbar { width: 6px; }
.overlay__body::-webkit-scrollbar-track { background: transparent; }
.overlay__body::-webkit-scrollbar-thumb { background: var(--gray-750); border-radius: var(--radius-xs); }

/* ---- BGBadge ---------------------------------------------------------
   Small badge: gray-800 fill, gray-700 border + text, 2px gray-800 outline
   (shadow) to sit cleanly over busy backgrounds. Partial: partials/components/bg-badge
   ---------------------------------------------------------------------- */
.bg-badge {
  display: inline-block;
  max-width: 100%;
  padding: var(--space-1) var(--space-2); /* 4px · 8px */
  background: var(--gray-800);
  border: 1px solid var(--gray-750);
  border-radius: var(--radius-xs); /* 2px */
  box-shadow: 0 0 0 2px var(--gray-800); /* 2px outer outline */
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 10px;
  line-height: 20px;
  color: var(--gray-700);
  text-transform: uppercase;
  text-align: center;
  /* clamp to a single line */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Tooltip ---------------------------------------------------------
   CSS-only. Appears 2s after hover/focus (transition-delay), hides
   instantly on leave. Wrap a trigger with partials/components/tooltip.
   ---------------------------------------------------------------------- */
.tooltip {
  position: relative;
  display: inline-flex;
}

.tooltip__bubble {
  position: absolute;
  left: 50%;
  z-index: 50;
  transform: translateX(-50%);
  padding: var(--space-1) var(--space-2);
  background: var(--bg-elevated);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 12px;
  line-height: 16px;
  white-space: nowrap;
  box-shadow: var(--shadow-md);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, visibility 0.15s ease;
  transition-delay: 0s; /* hide immediately on leave */
}

.tooltip__bubble--top { bottom: calc(100% + 8px); }
.tooltip__bubble--bottom { top: calc(100% + 8px); }

/* Arrow */
.tooltip__bubble::after {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
}
.tooltip__bubble--top::after { top: 100%; border-top-color: var(--border-color); }
.tooltip__bubble--bottom::after { bottom: 100%; border-bottom-color: var(--border-color); }

/* Reveal after a 2s delay on hover or keyboard focus */
.tooltip:hover .tooltip__bubble,
.tooltip:focus-within .tooltip__bubble {
  opacity: 1;
  visibility: visible;
  transition-delay: 2s;
}

/* Forced-visible (styleguide previews) — no delay */
.tooltip.is-open .tooltip__bubble {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

/* Below 640px: the checklist in one column and the "Go to stats" button
   below the list card. The text column dissolves (display: contents) so its
   heading, checklist and button become rows of the banner's grid next to the
   media; the 32px content inset moves onto the grid itself. */
@media (max-width: 639.98px) {
  .stats-banner__inner { padding: var(--space-8) var(--space-8) calc(var(--space-8) + 8px); grid-template-columns: minmax(0, 1fr); } /* 40px below the button */
  .stats-banner__col { display: contents; }
  .stats-banner__heading,
  .stats-banner__list,
  .stats-banner__cta { grid-area: auto; }
  .stats-banner__list {
    grid-template-columns: 1fr;
    margin-top: calc(var(--space-6) + var(--space-1)); /* 28px below the heading, as before */
  }
  .stats-banner__media { padding: 0; margin-top: var(--space-8); } /* 32px below the heading */
  .stats-banner__cta { order: 1; margin-top: calc(var(--space-8) + 8px); } /* 40px */
  .stats-banner__cta .button { flex: 1; } /* full width */
  /* Heading centred (still broken after "Check out"); no checklist */
  .stats-banner__heading { text-align: center; }
  .stats-banner__list { display: none; }
  /* The card now ends 40px + the button (40px) + 40px + 9px above the
     banner's bottom */
  .stats-banner__crystal { bottom: calc(129px + 388px / 2 - 50px / 2); }
  /* Overlay: still centred, but never closer than 24px (its top/bottom
     inset) to the list card's sides, so it narrows with the card */
  .stats-banner__overlay,
  .stats-banner__overlay-ring {
    left: max(var(--space-6), calc(50% - 167.5px));
    right: max(var(--space-6), calc(50% - 167.5px));
    width: auto;
  }
  /* Ranking table: only rank, name and score, with tighter gaps, so the
     rows fit the narrower card */
  .stats-banner__rating,
  .stats-banner__rep,
  .stats-banner__th--rating,
  .stats-banner__th--rep { display: none; }
  .stats-banner__ranking .list__row,
  .stats-banner__ranking-head { gap: var(--space-3); padding-left: var(--space-3); padding-right: var(--space-4); }
  .stats-banner__score,
  .stats-banner__th--score { flex: 0 1 80px; min-width: 0; margin-left: 0; overflow: hidden; }
}
/* Below 640px the page content's side padding halves (40px → 20px) */
@media (max-width: 639.98px) {
  .content-wrapper { padding-left: var(--space-5); padding-right: var(--space-5); }
}
/* Narrow overlay panel (below 640px it shrinks with the list card): below
   300px wide, tighter header, the key stats in 2 columns (3 rows) and the
   races list without its class column, so nothing overflows the panel */
.stats-banner__overlay { container-type: inline-size; }
@container (max-width: 299.98px) {
  .stats-banner__overlay-head { gap: var(--space-2); padding: var(--space-3) 10px; }
  .stats-banner__avatar { width: 32px; height: 32px; }
  .stats-banner__overlay-bar .tabbar__tab { padding: 0 10px; }
  .stats-banner__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats-banner__stat { padding: var(--space-2) 10px; }
  .stats-banner__races { padding-left: 10px; padding-right: 10px; }
  .stats-banner__race { grid-template-columns: 24px minmax(0, 1fr) 48px 40px; gap: 6px; }
  .stats-banner__race > span:nth-child(3) { display: none; }
}
/* Below 960px the list card doesn't slide up as the banner scrolls into
   view: it stays at its resting place (the overlay still appears once the
   banner is settled) */
@media (max-width: 959.98px) {
  .stats-banner[data-reveal] .stats-banner__ranking > .ds-card { transform: none; }
}
/* Below 640px: tighter About gallery — 12px between the video and the
   images and between the images (20px above) */
@media (max-width: 639.98px) {
  .about-video { margin-bottom: calc(var(--space-3) - var(--space-16)); }
  .about-gallery__track { gap: var(--space-3); }
}
/* Below 640px the About headline matches the stats banner heading (32px
   type, 36px lines); the shard stays centred between "PERFORMANCE" (ending
   ≈ 271px into the card) and the right padding, on the headline's height
   (108px from 32px down) */
@media (max-width: 639.98px) {
  .about-card__headline { font-size: 32px; line-height: 36px; }
  .about-card__shard { left: calc((271px + 100% - 32px) / 2 + 32px); top: 86px; }
}
/* Below 800px the achievements rows drop the gold / silver / bronze medal
   icons; their counts take the medals' light tones instead (as the stats
   banner's podium ranks). The championships trophy icon stays. */
@media (max-width: 799.98px) {
  .achievement-item__medal--gold img,
  .achievement-item__medal--silver img,
  .achievement-item__medal--bronze img { display: none; }
  .achievement-item__medal--gold .achievement-item__num { color: #E6C778; }
  .achievement-item__medal--silver .achievement-item__num { color: #A3B6C9; }
  .achievement-item__medal--bronze .achievement-item__num { color: #C9744A; } /* a deep, reddish bronze */
}
/* Below 640px each achievements row stacks, centred: series logo + name on
   top, the medals and championships below it. The medal icons come back
   with white counts (undoing the coloured counts below 800px). */
@media (max-width: 639.98px) {
  .achievement-item {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2); /* 8px */
    text-align: center;
  }
  .achievement-item__series { max-width: 100%; }
  .achievement-item__logo { display: none; } /* no series logo */
  .achievement-item__medal--gold img,
  .achievement-item__medal--silver img,
  .achievement-item__medal--bronze img { display: block; }
  .achievement-item__medal--gold .achievement-item__num,
  .achievement-item__medal--silver .achievement-item__num,
  .achievement-item__medal--bronze .achievement-item__num { color: #fff; }
}
/* Below 640px the achievements tagline matches the About headline (32px
   type, 36px lines) */
@media (max-width: 639.98px) {
  .achievements-header__title { font-size: 32px; line-height: 36px; }
}
/* Below 800px no rock formation behind the achievements driver */
@media (max-width: 799.98px) {
  .achievements-header__driver--rocks { display: none; }
}
/* Below 1140px the news card titles are a bit smaller (14px type, 24px
   lines; still 3 lines tall) */
@media (max-width: 1139.98px) {
  .news-card__title { font-size: 14px; line-height: 24px; height: 72px; }
}
/* Below 960px the news cards are tighter: 24px content padding (instead
   of 32px) and no gap between the cards */
@media (max-width: 959.98px) {
  .news-item .ds-card__content { padding: var(--space-6); }
  .news-grid { gap: 0; }
}
/* Below 840px the news window shows 2 cards (the pager script in
   home-v2.ejs shows 2 items at a time) */
@media (max-width: 839.98px) {
  .news-grid { grid-template-columns: repeat(2, 1fr); }
}
/* …and below 540px a single card */
@media (max-width: 539.98px) {
  .news-grid { grid-template-columns: 1fr; }
}
/* Below 960px the achievements tagline sits as far in from the header's
   left edge as the About headline from its card's inner edge: 48px, and
   32px below 800px (instead of the 57px above) */
@media (max-width: 959.98px) {
  .achievements-header__title { left: var(--space-12); }
}
@media (max-width: 799.98px) {
  .achievements-header__title { left: var(--space-8); }
}
/* Below 800px the achievements driver (and the layers sharing its box)
   shrinks with the window: 384px tall at 800px, 48vw below. Its centre is
   held at 90% of the header's width, so it scales in place instead of
   drifting right. The small shard beside it follows the
   image's left edge (half its width: 281px at full size → 35.125vw). */
@media (max-width: 799.98px) {
  .achievements-header__driver { height: min(384px, 48vw); left: 90%; }
  .achievements-header__shard:not(.achievements-header__shard--right) {
    left: calc(90% - min(281px, 35.125vw) + var(--space-2));
  }
}
/* Below 800px smaller gray corner triangles in the achievements header
   (192px instead of 288px; they no longer meet top to bottom) */
@media (max-width: 799.98px) {
  .achievements-header::before,
  .achievements-header::after { width: 192px; height: 192px; }
}
/* Below 640px a lower achievements header: 168px instead of 288px, with
   its corner triangles smaller again (128px) */
@media (max-width: 639.98px) {
  .achievements-header { height: 168px; }
  .achievements-header::before,
  .achievements-header::after { width: 128px; height: 128px; }
}
/* Below 640px the achievements driver is a bit smaller still (42vw instead
   of 48vw tall); the small shard keeps to the image's left edge (half its
   width: 0.7315 × height ≈ 30.72vw) */
@media (max-width: 639.98px) {
  /* 64px further left at 640px, sliding back right as the window narrows:
     the offset runs linearly from −64px at 640px to +16px at 375px
     (−64px + 0.3019 × (640px − 100vw)) */
  .achievements-header__driver { height: 42vw; left: calc(90% + 129.2px - 30.19vw); }
  .achievements-header__shard:not(.achievements-header__shard--right) {
    left: calc(90% - 30.72vw + var(--space-2));
  }
}
/* Below 640px the About shard is a bit smaller (144 × 96px instead of
   192 × 128px), centred on the same spot */
@media (max-width: 639.98px) {
  .about-card__shard { width: 144px; height: 96px; }
}
/* From 960px up the lineup driver photo keeps its full card height: no 50%
   width cap, which made it shrink as the card narrowed. Below 960px the cap
   applies again and it scales down. */
@media (min-width: 960px) {
  .lineup-driver__image { max-width: none; }
}
/* Below 640px the small shard at the bottom right of the achievements
   tagline is smaller (40 × 31px instead of 56 × 43px), 8px further right
   and 8px lower */
@media (max-width: 639.98px) {
  .achievements-header__shard:not(.achievements-header__shard--right) {
    width: 40px;
    height: 31px;
    bottom: calc(var(--space-4) + var(--space-1)); /* 20px */
    left: calc(90% - 30.72vw + var(--space-2) + var(--space-2));
  }
}
/* Below 1080px a lower lineup: the driver card and the driver list beside
   it are 512px tall instead of 592px */
@media (max-width: 1079.98px) {
  .lineup-card { height: 512px; }
  .lineup-layout__aside { max-height: 512px; }
}
/* Below 1080px the brush strokes shrink with the lower lineup card
   (512 / 592 ≈ 0.865): 334 × 363px instead of 386 × 420px, and 21px below
   the card's middle instead of 24px */
@media (max-width: 1079.98px) {
  .lineup-brush { width: 334px; height: 363px; top: calc(50% + 21px); }
}
/* Below 1080px the glass shards left of the driver name sit 32px further
   left and 16px higher */
@media (max-width: 1079.98px) {
  .lineup-layout__head-shard { left: calc(345px - var(--space-8)); top: calc(57px - var(--space-4)); }
}
/* Lineup driver picker (partials/components/lineup-section): hidden until
   below 960px, where it replaces the driver list on the left. In the section
   title row, left of the prev / next buttons, styled like them: same 34px
   height and gray-850 fill, no border. A fixed width that fits the longest
   driver name (set by the hidden name stack, .lineup-picker__sizer); its
   menu opens at the same width. */
.lineup-picker { display: none; }
@media (max-width: 959.98px) {
  .lineup-layout { grid-template-columns: minmax(0, 1fr); }
  .lineup-layout__aside { display: none; }
  .content-header__actions:has(.lineup-picker) { flex: 0 1 auto; min-width: 0; }
  .lineup-picker {
    display: block;
    flex: none;
    width: max-content;
    position: relative;
    z-index: 5; /* the open menu lies over the driver card below */
  }
  .lineup-nav { flex-shrink: 0; }
  /* every name in one grid cell, invisible and 0px tall: the widest one sets
     the width; the side padding matches the toggle's (12px + 1px border on
     the left; 12px gap + 16px chevron + 12px + 1px border on the right),
     plus 24px so the longest name isn't tight against the chevron */
  .lineup-picker__sizer {
    display: grid;
    height: 0;
    overflow: hidden;
    visibility: hidden;
    padding: 0 calc(var(--space-3) * 2 + 16px + 1px + var(--space-6)) 0 calc(var(--space-3) + 1px); /* +24px of extra room */
    font-family: 'Bai Jamjuree', sans-serif;
    font-size: 14px;
  }
  .lineup-picker__sizer > span { grid-area: 1 / 1; white-space: nowrap; }
  .lineup-picker .dropdown__toggle {
    height: 34px;
    padding: 0 var(--space-3);
    background: var(--gray-850);
    border-color: var(--gray-850);
  }
  /* red border on hover / focus / open, like the other dropdowns (the
     gray-850 border above would otherwise win) */
  .lineup-picker .dropdown__toggle:hover,
  .lineup-picker .dropdown__toggle:focus-visible,
  .lineup-picker .dropdown.is-open .dropdown__toggle { border-color: var(--red-500); }
  /* drivers hidden by the category filter are left out of the dropdown too */
  .lineup-picker .dropdown__option.is-filtered-out { display: none; }
}
/* Below 1000px no gap between the news cards */
@media (max-width: 999.98px) {
  .news-grid { gap: 0; }
}
/* Below 960px the lineup's category filter tabs in the section header are
   hidden; in their place: prev / next driver buttons (the News pager), only
   below 960px. */
.lineup-nav { display: none; }
@media (max-width: 959.98px) {
  .lineup-filter { display: none; }
  .lineup-nav { display: inline-flex; }
  /* the glass shard that overlapped the start of the "Lineup" title sits
     on the line of the second news card's left edge above instead: a third
     in while News shows 3 cards (840–960px), half way with 2 (below 840px;
     kept there below 540px, where News shows one) */
  .lineup-layout__corner-shard { left: calc(100% / 3); }
}
@media (max-width: 839.98px) {
  .lineup-layout__corner-shard { left: 50%; }
}
/* Optional content at the top of a dropdown's menu (dropdown.ejs menuHeader) */
.dropdown__menu-header {
  padding: var(--space-2) var(--space-3) var(--space-3);
  margin-bottom: var(--space-1);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08); /* same as the menu's border */
}
/* Below 1080px the lineup driver photo and the red brush strokes behind it
   sit 8px further right (24px instead of the 16px nudge) */
@media (max-width: 1079.98px) {
  .lineup-driver__image { transform: translateX(calc(-50% + 24px)); }
  .lineup-brush { left: calc(25% + 24px); }
}
/* Below 960px (full-width driver card) the glass shards by the driver's
   head sit halfway between the head and the name, at any card width: the
   head's right side is ≈ 25% + 78px into the card (photo centred a quarter
   in + 24px nudge + 9px frame, head ≈ 45px to the right of that), the name
   starts at 50% + 57px (info panel + 48px padding + 9px frame) → their
   middle is 37.5% + 67px, then 7px left by eye */
@media (max-width: 959.98px) {
  .lineup-layout__head-shard { left: calc(37.5% + 60px); }
}
/* Achievements button icons (lineup-section.ejs): the arrow beside the
   label; the trophy only below 720px, where the button is icon-only */
.lineup-driver__cta-arrow { display: inline-flex; }
.lineup-driver__cta-trophy { display: none; }
/* Below 720px the driver card is rearranged: the name runs upwards along
   the top left, the Achievements button sits top right with the flag +
   country + age running upwards below it, the photo (and brush strokes) centred below, and the
   category badges bottom left. No description or X handle. The info panel
   spans the card above the photo; only its links and buttons take clicks. */
@media (max-width: 719.98px) {
  .lineup-driver__info {
    width: 100%;
    padding: var(--space-8); /* 32px, as the achievements header's tagline inset */
    z-index: 3;
    pointer-events: none;
  }
  .lineup-driver__info a,
  .lineup-driver__info button { pointer-events: auto; }
  .lineup-driver__desc,
  .lineup-driver__x { display: none; }
  /* Name: first and last name the same size (28px) on one line, turned 90°
     to the left (reading upwards), top left. Vertical writing mode +
     `rotate` (not transform, which the intro animation would override). */
  .lineup-driver__name {
    position: absolute;
    top: var(--space-8);
    left: var(--space-8);
    display: block;
    writing-mode: vertical-rl;
    rotate: 180deg;
    white-space: nowrap;
  }
  .lineup-driver__first,
  .lineup-driver__last { font-size: 28px; line-height: 28px; }
  .lineup-driver__first { margin-inline-end: 0.25em; }
  /* Flag + country + age: turned 90° to the left too, centred under the
     34px trophy button, 16px below it */
  .lineup-driver__meta {
    position: absolute;
    top: calc(var(--space-8) + 34px + var(--space-4));
    right: calc(var(--space-8) + 17px);
    margin: 0;
    writing-mode: vertical-rl;
    translate: 50% 0;
    rotate: 180deg;
    white-space: nowrap;
  }
  /* the flag itself stays upright: undo the meta line's turn */
  .lineup-driver__flag-wrap { margin-right: 0; margin-inline-end: var(--space-4); vertical-align: 0; rotate: 180deg; } /* 16px to the country, as from the age to the trophy button */
  /* top right, its top level with the top of the name block (32px down) */
  .lineup-driver__cta {
    position: absolute;
    top: var(--space-8);
    right: var(--space-8);
    margin-top: 0;
  }
  /* …as an icon button: just a trophy in a square (padding as
     .button--icon-only). The label stays for screen readers, visually
     hidden, so the button keeps its name. */
  .lineup-driver__cta .button { padding: var(--space-2); }
  .lineup-driver__cta-arrow { display: none; }
  .lineup-driver__cta-trophy { display: inline-flex; }
  .lineup-driver__cta .button__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* photo: centred, bigger than the space below the ≈ 112px text block
     (its top reaches 96px into it, behind the text); the brush strokes
     grow with it (≈ +31%) and stay centred on it */
  .lineup-driver__image {
    left: 50%;
    transform: translateX(-50%);
    height: calc(100% - 16px);
    max-width: none;
  }
  .lineup-brush { left: 50%; top: calc(50% + 8px); width: 320px; height: 348px; }
  .lineup-driver__badges { top: auto; left: var(--space-8); bottom: var(--space-8); z-index: 3; } /* in front of the bigger photo */
  /* the shards between head and name have no place in this layout */
  .lineup-layout__head-shard { display: none; }
}
/* Below 720px the glass shard in the "Lineup" title row follows the free
   space as the window narrows: centred between the end of the title (71px
   in) and the start of the driver dropdown (the row's width − 68px buttons −
   8px gap − 196px dropdown) → 50% − 100.5px. Below 440px that gap is
   narrower than the shard, so it is hidden. The dropdown may also shrink
   there, so the row never runs past the content edge. */
@media (max-width: 719.98px) {
  .lineup-layout__corner-shard { left: calc(50% - 100.5px); }
  .lineup-picker { flex-shrink: 1; min-width: 0; }
}
@media (max-width: 439.98px) {
  .lineup-layout__corner-shard { display: none; }
}
/* Below 540px, where News shows a single card, its text is a bit bigger:
   the title back to 16px type / 28px lines (3 lines, 84px), the
   category + date line 12px */
@media (max-width: 539.98px) {
  .news-card__title { font-size: 16px; line-height: 28px; height: 84px; }
  .news-card__meta { font-size: 12px; line-height: 18px; }
}
/* Mobile (below 540px): no "Lineup" title (nor its glass shard); the title
   row holds just the driver dropdown on the left and the prev / next
   buttons on the right */
@media (max-width: 539.98px) {
  .content-header:has(.lineup-picker) .content-header__title { display: none; }
  .lineup-layout__corner-shard { display: none; }
  .content-header__actions:has(.lineup-picker) { flex: 1; margin-left: 0; }
  .lineup-nav { margin-left: auto; }
}
/* Mobile (below 540px): the footer stacks, centred — the logo on top, the
   Admin and Imprint links below it, one above the other — and grows to fit
   (40px above and below) */
@media (max-width: 539.98px) {
  .site-footer { height: auto; }
  .site-footer .site-footer__inner {
    flex-direction: column;
    justify-content: center;
    gap: var(--space-6);
    padding-top: var(--space-10);
    padding-bottom: var(--space-10);
  }
  .site-footer__links { flex-direction: column; gap: var(--space-3); }
}
/* Mobile (below 540px): the contact form panel's padding is a bit smaller
   (24px instead of 32px) */
@media (max-width: 539.98px) {
  .contact-form-wrap { padding: var(--space-6); }
}
/* Mobile (below 540px): the stats banner's content inset matches the
   contact form panel's (24px; 20px at the sides); the crystal stays
   centred on the list card */
@media (max-width: 539.98px) {
  .stats-banner__inner { padding: var(--space-6) calc(var(--space-6) - 4px); } /* 24px top/bottom, 20px left/right */
  /* tighter around the list card: 24px below the heading, 24px above
     the button */
  .stats-banner__media { margin-top: var(--space-6); }
  .stats-banner__cta { margin-top: var(--space-6); }
  .stats-banner__crystal { bottom: calc(97px + 388px / 2 - 50px / 2); } /* card ends 24 + 40 + 24 + 9px up */
}
/* Mobile (below 540px): the stats overlay panel (and its ring) is 8px
   wider: 4px less inset on each side (20px instead of 24px from the list
   card's edges, or 343px instead of 335px where it has room) */
@media (max-width: 539.98px) {
  .stats-banner__overlay,
  .stats-banner__overlay-ring {
    left: max(20px, calc(50% - 171.5px));
    right: max(20px, calc(50% - 171.5px));
  }
}
/* Mobile (below 540px): the About card's side padding matches the stats
   banner's (20px instead of 32px); the shard stays centred between
   "PERFORMANCE" (now ending ≈ 259px in) and the right padding */
@media (max-width: 539.98px) {
  .about-card { padding-left: calc(var(--space-6) - 4px); padding-right: calc(var(--space-6) - 4px); }
  .about-card__shard { left: calc((259px + 100% - 20px) / 2 + 32px); }
}
/* Mobile (below 540px): the achievements tagline in three lines —
   "Winning" / "is in our" / "DNA" (achievements-header.ejs has "is" at
   the end of line 1 and the start of line 2; one of them is shown) */
.achievements-header__title-narrow { display: none; }
@media (max-width: 539.98px) {
  .achievements-header__title-wide { display: none; }
  .achievements-header__title-narrow { display: inline; }
  .achievements-header__title-break { display: block; }
}
/* Mobile (below 540px): the achievements tagline sits 20px in from the
   header's left edge, as the About card's content */
@media (max-width: 539.98px) {
  .achievements-header__title { left: calc(var(--space-6) - 4px); }
}
/* Mobile (below 540px): the achievements driver bigger (50vw instead of
   42vw tall) and 36px further left */
@media (max-width: 539.98px) {
  .achievements-header__driver { height: 50vw; left: calc(90% + 129.2px - 30.19vw - 36px); }
}
/* Mobile (below 540px): the small shard at the bottom left of the driver
   sits 16px further left */
@media (max-width: 539.98px) {
  .achievements-header__shard:not(.achievements-header__shard--right) {
    left: calc(90% - 30.72vw + var(--space-2) + var(--space-2) - var(--space-4));
  }
}
/* The second copy of the shards layer (achievements-header.ejs) is only
   used on mobile (below 540px): there the two glass pieces left of the
   driver — right of the tagline, in the left 40% of the image — sit 24px
   further right on their own. The original layer is clipped to the pieces
   right of the driver, the copy to the two left ones. */
.achievements-header__driver--shards-left { display: none; }
@media (max-width: 539.98px) {
  .achievements-header__driver--shards { clip-path: inset(0 0 0 40%); }
  .achievements-header__driver--shards-left {
    display: block;
    clip-path: inset(0 60% 0 0);
    left: calc(90% + 129.2px - 30.19vw - 28px + var(--space-6)); /* where it was before the driver's last 8px of moves */
  }
}
/* Touch devices (phones, tablets: no hover): no focus ring on buttons —
   after a tap the ring would otherwise linger on the tapped button */
@media (hover: none) {
  .button:focus-visible { box-shadow: none; }
}
/* Touch devices: no hover look on the About gallery images (full
   brightness + red corner brackets) — a tap would leave it stuck on the
   tapped image, also when focus returns to it after the lightbox closes */
@media (hover: none) {
  .about-gallery__item:hover img { filter: brightness(0.55); }
  .about-gallery__item:hover::after,
  .about-gallery__item:has(.about-gallery__open:focus-visible)::after { opacity: 0; }
}
/* Touch devices (no hover): buttons keep their resting look after a tap —
   the hover colours would otherwise stick to the last tapped button. The
   pressed (:active) colours still show while the finger is down. */
@media (hover: none) {
  .button--primary:hover:not(:active) {
    background: var(--red-500);
    border-color: var(--red-500);
  }
  .button--outlined:hover:not(:active) {
    background: transparent;
    color: var(--red-500);
  }
  .button--ghost:hover:not(:active) { background: transparent; }
  .button--ghost.button--bare:hover:not(:active) { color: #fff; } /* bare is only used with ghost */
  .stats-banner__cta .button--primary:hover:not(:active) {
    background: var(--mint-500);
    border-color: var(--mint-500);
  }
  .dropdown__toggle:hover:not(:focus-visible),
  .lineup-picker .dropdown__toggle:hover:not(:focus-visible) { border-color: var(--gray-850); }
  .dropdown.is-open .dropdown__toggle,
  .lineup-picker .dropdown.is-open .dropdown__toggle { border-color: var(--red-500); }
}
/* Mobile (below 540px): the driver name is horizontal again, above the
   photo at the top left — first name (16px, red) over the last name (28px)
   — and the photo starts below it (the 32px inset + ≈ 52px name + 12px) */
@media (max-width: 539.98px) {
  .lineup-driver__name {
    writing-mode: horizontal-tb;
    rotate: none;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }
  .lineup-driver__first { font-size: 16px; line-height: 20px; margin-inline-end: 0; }
  .lineup-driver__last { font-size: 28px; line-height: 32px; }
  .lineup-driver__image { height: calc(100% - 96px); }
  .lineup-brush { top: calc(50% + 48px); width: 272px; height: 296px; }
}
/* Mobile (below 540px): flag + age below the name, horizontal, at the left
   (8px under it); the country name and the bullet before the age are
   hidden (the country stays readable to screen readers). The photo starts
   a bit lower again, below this line. */
@media (max-width: 539.98px) {
  .lineup-driver__meta {
    top: calc(var(--space-8) + 52px + var(--space-2));
    left: var(--space-8);
    right: auto;
    writing-mode: horizontal-tb;
    translate: none;
    rotate: none;
  }
  .lineup-driver__flag-wrap { rotate: none; margin-inline-end: var(--space-3); vertical-align: -1px; width: 10px; height: 10px; } /* 10px (was 12px), 12px to the age */
  .lineup-driver__meta-sep { display: none; }
  .lineup-driver__country {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .lineup-driver__image { height: calc(100% - 124px); }
  .lineup-brush { top: calc(50% + 62px); width: 256px; height: 279px; }
}
/* Mobile (below 540px): the driver card's insets match the About card's
   there — 32px top and bottom, 20px left and right */
@media (max-width: 539.98px) {
  .lineup-driver__info { padding: var(--space-8) calc(var(--space-6) - 4px); }
  .lineup-driver__name,
  .lineup-driver__meta { left: calc(var(--space-6) - 4px); }
  .lineup-driver__cta { right: calc(var(--space-6) - 4px); }
  .lineup-driver__badges { left: calc(var(--space-6) - 4px); }
}
/* Mobile (below 540px): a bit bigger photo, its head reaching up to the top
   edge of the flag (93px down): the photo starts 81px down (the head sits
   ≈ 2.9% into the image), 413px tall in the 494px panel; the brush strokes
   grow with it (×1.12) and stay centred on it */
@media (max-width: 539.98px) {
  .lineup-driver__image { height: calc(100% - 81px); }
  .lineup-brush { top: calc(50% + 40px); width: 286px; height: 311px; }
}
/* Mobile (below 540px): the driver's achievements overlay panel fits the
   card's inner surface — 16px in on the left as on the right, instead of
   its fixed 346px width */
@media (max-width: 539.98px) {
  .lineup-driver .overlay__panel { left: var(--space-4); width: auto; }
}
/* Mobile (below 540px): smaller category badges in the driver card (9px
   type, 16px lines, 2px · 6px padding, 8px apart), behind the photo again */
@media (max-width: 539.98px) {
  .lineup-driver__badges { z-index: 1; gap: var(--space-2); }
  .lineup-driver__badges .bg-badge { padding: 2px 6px; font-size: 9px; line-height: 16px; }
}
/* Below 1140px the darker diagonal band in the middle of the event banner
   narrows with the banner while keeping its 45° edges: instead of
   events-shadow.svg it is drawn as a 135° gradient — the same band (black,
   16% at its edges, 12% between 12% and 88% of its thickness), centred,
   251.429px thick at 1140px (inner surface 1042px wide) and scaling with
   the inner surface's width (the panel is a size container: inner = 100cqw
   − 18px), so only its thickness changes, never its angle */
@media (max-width: 1139.98px) {
  .event-banner__panel { container-type: inline-size; }
  .event-banner__inner {
    --band: calc((100cqw - 18px) * 251.429 / 1042);
    background-image:
      url('/assets/event-stripes-l.svg'),
      url('/assets/event-stripes-r.svg'),
      linear-gradient(135deg,
        transparent calc(50% - var(--band) / 2),
        rgba(0, 0, 0, 0.16) calc(50% - var(--band) / 2),
        rgba(0, 0, 0, 0.12) calc(50% - var(--band) / 2 + var(--band) * 0.120192),
        rgba(0, 0, 0, 0.12) calc(50% - var(--band) / 2 + var(--band) * 0.884615),
        rgba(0, 0, 0, 0.16) calc(50% + var(--band) / 2),
        transparent calc(50% + var(--band) / 2));
    background-size: auto, auto, 100% 100%;
  }
}
/* Below 960px the series' big logo on the right of the event banner is
   hidden; its small icon sits right of the car instead: a 58px square on a
   dark ground with a gray border, 32px in from the banner's right edge,
   vertically centred (positioned against the event panel). The text column
   keeps the name, date and Watch Live button. */
.event-content__series-icon { display: none; }
@media (max-width: 959.98px) {
  .event-content__logo { display: none; }
  .event-content { position: relative; }
  .event-content__info { position: static; } /* so the icon is placed against the panel */
  /* …which drops the column's own stacking: keep its text and button in
     front of the car */
  .event-content__name,
  .event-content__meta,
  .event-content__info > .button { position: relative; z-index: 2; }
  .event-content__series-icon {
    position: absolute;
    right: var(--space-8);
    top: 50%;
    translate: 0 -50%;
    z-index: 2;
    display: block;
    box-sizing: border-box;
    width: 58px;
    height: 58px;
    padding: var(--space-2);
    background: var(--gray-900);
    border: 1px solid var(--gray-750);
    border-radius: var(--radius-xs);
    object-fit: contain;
  }
  .event-content__meta { margin-top: 2px; } /* 4px closer to the name */
}

/* Below 960px the event banner's tabs sit 8px closer to its panel: the tab
   row moves down 8px (the panel stays put, so everything aligned with it —
   the hero's dark area, the News gap — is unaffected) */
@media (max-width: 959.98px) {
  .event-banner > .tabbar { margin-top: var(--space-2); margin-bottom: calc(-1 * var(--space-2)); }
}
/* Below 960px (big logo hidden): the car, the red accent lines and the
   darker band move into the free right half — the car's column takes the
   logo's space (2 columns: info · car), so everything centres on 75% of the
   width instead of 50% — and the band no longer ends on the right: from its
   left 45° edge on, the dark runs out to the banner's right edge, leaving
   no lighter gray strip there. The band's centre moves by a quarter of the
   inner width, i.e. (inner / 4) / √2 along the 135° gradient. */
@media (max-width: 959.98px) {
  .event-content { grid-template-columns: repeat(2, 1fr); }
  .event-banner__line { left: 75%; }
  .event-banner__inner {
    /* + its left edge 40px further left (40 / √2 ≈ 28.3px along the gradient) */
    --band-shift: calc((100cqw - 18px) / 4 / 1.41421 - 28.3px);
    background-image:
      url('/assets/event-stripes-l.svg'),
      url('/assets/event-stripes-r.svg'),
      linear-gradient(135deg,
        transparent calc(50% + var(--band-shift) - var(--band) / 2),
        rgba(0, 0, 0, 0.16) calc(50% + var(--band-shift) - var(--band) / 2),
        rgba(0, 0, 0, 0.12) calc(50% + var(--band-shift) - var(--band) / 2 + var(--band) * 0.120192),
        rgba(0, 0, 0, 0.12) 100%);
  }
}
/* Below 960px a slightly smaller flag in the event banner (10px circle
   instead of 12px) */
@media (max-width: 959.98px) {
  .event-content__flag-wrap { width: 10px; height: 10px; }
}
/* Below 960px the top-right red accent line keeps its place relative to
   the car: placed from the banner's right edge like the car, and moved
   left by the car's 24px + 16px more (`translate`, so its animations are
   untouched) */
@media (max-width: 959.98px) {
  .event-banner__line--tr { left: calc(100% - 215.5px); translate: -40px 0; }
}
/* Below 960px the event car sits 24px further left in the dark band (the
   separate `translate` property, so the car's transform-driven intro and
   tab-switch animations are untouched) */
@media (max-width: 959.98px) {
  .event-content__car { translate: -24px 0; }
}
/* Below 960px the bottom-left red accent line sits 12px further left
   (`translate`, so its transform-driven animations are untouched) */
@media (max-width: 959.98px) {
  .event-banner__line--bl { translate: -12px 0; }
}
/* Below 960px the dark area keeps the width it has at 960px instead of
   shrinking with the window (then made 16px narrower: 386.6px): measured
   at mid-height it ran ≈ 402.6px from
   its 45° left edge to the banner's right edge (inner 862px there: band
   centre 75% − 40px, band 208px thick → 294px wide horizontally). The left
   edge therefore sits at the inner width − 402.6px; along the 135°
   gradient that is (inner / 2 − 402.6px) / √2 from the centre. The edge's
   darker strip keeps its 960px thickness (12% of 208px). */
@media (max-width: 959.98px) {
  .event-banner__inner {
    --band-edge: calc(50% + ((100cqw - 18px) / 2 - 386.6px) / 1.41421); /* 16px narrower than at 960px */
    background-image:
      url('/assets/event-stripes-l.svg'),
      url('/assets/event-stripes-r.svg'),
      linear-gradient(135deg,
        transparent var(--band-edge),
        rgba(0, 0, 0, 0.16) var(--band-edge),
        rgba(0, 0, 0, 0.12) calc(var(--band-edge) + 208px * 0.120192),
        rgba(0, 0, 0, 0.12) 100%);
  }
}
/* Below 800px the dark area is 64px narrower still (322.6px) */
@media (max-width: 799.98px) {
  .event-banner__inner { --band-edge: calc(50% + ((100cqw - 18px) / 2 - 322.6px) / 1.41421); }
}
/* Below 960px the car and the bottom-left red line keep their 960px
   distances to the dark area's left edge, which is held at a fixed
   distance from the banner's right edge: instead of a share of the width
   they are placed from the right — 215.5px left of the right edge (the 25%
   they sit there at 960px, inner 862px). The car's column is the right half
   of the inner surface, so for it that is 100% − 215.5px of the column. */
@media (max-width: 959.98px) {
  .event-content__car { left: calc(100% - 215.5px); }
  .event-banner__line--bl { left: calc(100% - 215.5px); }
}
/* Below 880px the series icon is a bit smaller (44px square) */
@media (max-width: 879.98px) {
  .event-content__series-icon { width: 44px; height: 44px; padding: 6px; }
}
/* Below 800px the event car sits 32px further right than above (8px right
   of its base spot instead of 24px left), with the narrower dark area */
@media (max-width: 799.98px) {
  .event-content__car { translate: var(--space-2) 0; }
}
/* Below 800px the bottom-left red line sits 64px further right than above
   (52px right of its base spot instead of 12px left), following the car */
@media (max-width: 799.98px) {
  .event-banner__line--bl { translate: 52px 0; }
}
/* Below 800px the tabs sit another 16px closer to the panel (24px apart):
   the tab row moves down 24px in all, the panel stays put */
@media (max-width: 799.98px) {
  .event-banner > .tabbar { margin-top: var(--space-6); margin-bottom: calc(-1 * var(--space-6)); }
}
/* Below 640px the series icon moves back into the text column, above the
   event name, instead of sitting right of the car: 36px square, 8px above
   the name, so icon + name + date + button (156px) fit the 162px inner
   surface */
@media (max-width: 639.98px) {
  .event-content__series-icon {
    position: relative;
    right: auto;
    top: auto;
    translate: none;
    width: 36px;
    height: 36px;
    padding: 5px;
    margin-bottom: var(--space-2);
  }
}
/* Below 640px the event banner's height follows its content (series icon,
   name, date and button stacked) instead of the fixed 180px: 32px above and
   below the text column, as on its left */
@media (max-width: 639.98px) {
  .event-banner__panel { height: auto; }
  .event-banner__inner { height: auto; }
  .event-content { height: auto; }
  .event-content__info { padding-top: var(--space-8); padding-bottom: var(--space-8); }
}
/* …and the hero grows by the banner's extra 54px (234px instead of 180px),
   so the heading stays put and the banner only extends downwards */
@media (max-width: 639.98px) {
  .hero { height: calc(619px + 54px); }
}
/* Below 640px no red accent line on the top right of the event car */
@media (max-width: 639.98px) {
  .event-banner__line--tr { display: none; }
}
/* Below 640px (taller banner) the striped corner triangles sit in the
   corners: the left one top left, the right one bottom right */
@media (max-width: 639.98px) {
  .event-banner__inner { background-position: left top, right bottom, 0 0; }
}
/* Below 640px the dark area is narrower (177.3px: half of 290.6px, + 32px) and the car
   sits 112px further right (120px right of its base spot) and 4px lower */
@media (max-width: 639.98px) {
  .event-banner__inner { --band-edge: calc(50% + ((100cqw - 18px) / 2 - 177.3px) / 1.41421); }
  .event-content__car { translate: 120px var(--space-1); }
}
/* Below 640px the event text may use the banner's full width (it sits in
   front of the car where they meet), so the name isn't cut short at half
   the width: the text column spans both grid columns, the car's column
   stays the right half on the same row */
@media (max-width: 639.98px) {
  .event-content__info { grid-column: 1 / -1; grid-row: 1; }
  .event-content__visual { grid-column: 2; grid-row: 1; }
}
/* Below 640px a slightly smaller event car (208px instead of 248px) */
@media (max-width: 639.98px) {
  .event-content__car { height: 208px; }
}
/* Below 640px the bottom-left red line sits another 32px further right
   (84px right of its base spot), following the car */
@media (max-width: 639.98px) {
  .event-banner__line--bl { translate: 84px 0; }
}
/* Mobile (below 540px): the event banner's dark area 8px narrower again
   (169.3px) */
@media (max-width: 539.98px) {
  .event-banner__inner { --band-edge: calc(50% + ((100cqw - 18px) / 2 - 169.3px) / 1.41421); }
}
/* Mobile (below 540px): no bottom-left red accent line either */
@media (max-width: 539.98px) {
  .event-banner__line--bl { display: none; }
}
/* Mobile (below 540px): the car stands upright in its own column on the
   left — 32px in, 208px tall → ≈ 117px wide, centred 90.5px in — and the
   series icon, name, date and button sit to its right. The upright turn
   (45° back to the left) rotates the car's column around the car's centre,
   so the car's own transform (and its drive-in / tab-switch animations)
   stays as it is. */
@media (max-width: 539.98px) {
  .event-content { grid-template-columns: 119px minmax(0, 1fr); } /* 16px inset + 103px car */
  .event-content__visual {
    grid-column: 1;
    grid-row: 1;
    rotate: -45deg;
    transform-origin: calc(var(--space-4) + 51.5px) 50%;
  }
  .event-content__info { grid-column: 2; grid-row: 1; padding-left: var(--space-6); padding-right: var(--space-6); }
  .event-content__car {
    left: calc(var(--space-4) + 51.5px); /* 16px from the banner's left edge */
    height: 184px; /* a bit smaller: ≈ 103px wide upright */
    translate: none;
  }
}
/* Event date: "MAY 30, 2026" normally, MM/DD/YY ("05/30/26") on mobile
   (below 540px) */
.event-content__date-short { display: none; }
@media (max-width: 539.98px) {
  .event-content__date-long { display: none; }
  .event-content__date-short { display: inline; }
}
/* Mobile (below 540px): 4px more space at the bottom of the event banner's
   inner surface; the hero grows by it too, so nothing above moves */
@media (max-width: 539.98px) {
  .event-banner__inner { padding-bottom: var(--space-1); }
  .hero { height: calc(619px + 58px); }
}
/* Mobile (below 540px): the series icon, name, date and button are centred
   in the space right of the car */
@media (max-width: 539.98px) {
  .event-content__info { align-items: center; text-align: center; }
  .event-content__name { text-align: center; max-width: 100%; }
  .event-content__meta { justify-content: center; }
}
/* Mobile (below 540px): no flag before the event date */
@media (max-width: 539.98px) {
  .event-content__flag-wrap { display: none; }
}
/* Mobile (below 540px): the car lies sideways (turned another 90° to the
   left: −135° on its column, so −90° in all, nose to the left) in its own
   row above the series icon, centred; the icon, name, date and button are
   stacked below it, centred. The car row is the car's height lying down
   (184px long → ≈ 103px), 32px below the inner surface's top, 16px above
   the icon. */
@media (max-width: 539.98px) {
  .event-content { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; }
  .event-content__visual {
    grid-column: 1;
    grid-row: 1;
    height: 103px;
    margin-top: var(--space-8);
    rotate: -135deg;
    transform-origin: 50% 50%;
  }
  .event-content__car { left: 50%; }
  .event-content__info { grid-column: 1; grid-row: 2; padding-top: var(--space-4); }
  /* the banner is now 357px tall (177px more than its 180px): the hero
     grows by that, so the heading and tabs stay put */
  .hero { height: calc(619px + 177px); }
}
/* Mobile (below 540px): a bigger lying car — 216px long → ≈ 121px tall
   lying down; its row and the banner grow by 18px (375px tall), and the
   hero with it */
@media (max-width: 539.98px) {
  .event-content__car { height: 216px; }
  .event-content__visual { height: 121px; }
  .hero { height: calc(619px + 195px); }
}
/* Mobile (below 540px): 8px more space at the bottom of the event banner's
   inner surface (12px in all); the banner (383px) and hero grow by it */
@media (max-width: 539.98px) {
  .event-banner__inner { padding-bottom: var(--space-3); }
  .hero { height: calc(619px + 203px); }
}
/* Below 800px the hero heading is smaller again (68px → 56px type, 63px →
   52px lines), and "ADDICTED TO" / "SINCE 2010" with it (16px → 14px type,
   24px → 20px lines), their gaps to the heading scaled to match */
@media (max-width: 799.98px) {
  .hero__headline { font-size: 56px; line-height: 52px; }
  .hero__kicker,
  .hero__headline > .hero__est { font-size: 14px; line-height: 20px; }
  .hero__kicker { top: -8px; }
  .hero__headline > .hero__est { margin-top: 9px; margin-bottom: 4px; }
}
/* Below 800px the achievements driver — with its glass layers and the small
   shard beside him — sits 72px further left, and the driver and his glass
   are 10% smaller, shrunk towards his feet (the separate `translate` /
   `scale` properties, on top of each width's own placement and the
   parallax transforms) */
@media (max-width: 799.98px) {
  .achievements-header__driver,
  .achievements-header__shard:not(.achievements-header__shard--right) { translate: -72px 0; }
  .achievements-header__driver { scale: 0.9; transform-origin: 50% 100%; }
}
/* Below 800px a 64px shorter hero: the heading stays where it is, the tabs
   and event banner (bottom-aligned in .hero__content) move up 64px. Each
   width's hero height − 64px. */
@media (max-width: 799.98px) {
  .hero { height: calc(619px - 64px); padding-top: calc(56px + 64px); } /* +64px on top keeps the heading in place (the hero centres its content) */
}
@media (max-width: 639.98px) {
  .hero { height: calc(619px + 54px - 64px); }
}
@media (max-width: 539.98px) {
  .hero { height: calc(619px + 203px - 64px); }
}
/* Below 800px the heading sits 16.5px higher, centred between the logo and
   the tab row's gray side lines (79px above "ADDICTED TO" vs 46px below
   "SINCE 2010" → 62.5px each): 33px less top padding (the hero centres its
   content, so half of it moves the heading). The red line still ends in
   the gap between "SIMRACING" and "KARTING", now 195px down — placed from
   the hero's top (it was placed from the bottom of a fixed-height hero). */
@media (max-width: 799.98px) {
  .hero { padding-top: calc(56px + 64px - 33px); }
  /* …and it lies on the hero artwork's cut edge (x + y = centre + 359.628px,
     .page-hero::before): ending 195px down puts its end 164.628px right of
     the centre; it runs up to the top (195px) or the page's right edge */
  .hero::before {
    bottom: calc(100% - 195px);
    left: calc(50% + 164.628px);
    width: calc(min(195px, 50% - 164.628px) * 1.4142);
  }
}
/* Below 800px the hero's driver sits 56px lower (he rose 16.5px with the
   heading) and is 8% bigger, grown from his feet (`translate` / `scale`,
   so the mouse parallax transform is untouched) */
@media (max-width: 799.98px) {
  .hero__aside-overlay {
    translate: 0 56px;
    scale: 1.08;
    transform-origin: 50% 100%;
  }
}
/* Below 800px the hero's car and driver stop shrinking with the window: they
   keep the size they have at 800px (headline area 720px wide → car
   min(60% − 12px, 100% − 376px) = 344px, driver base 278px). The background
   artwork does the same (home-v2.ejs). */
@media (max-width: 799.98px) {
  .hero__aside,
  .hero__aside-overlay { --car-w: 344px; }
  .hero__aside-overlay { --drv-w: 278px; }
}
/* Below 640px the hero stacks: the heading ("ADDICTED TO" / "SIMRACING
   KARTING" / "SINCE 2010") centred on top, the car (with the driver) centred
   below it, 24px apart */
@media (max-width: 639.98px) {
  .hero__headline-area:has(.hero__aside) {
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-6);
    position: relative;
  }
  .hero__headline { align-items: center; text-align: center; }
  .hero__aside {
    margin-left: 0;
    left: 0;
    top: 0;
    align-self: center;
  }
}
/* …the stacked hero needs 230px more height: 90px for the car row and 140px
   more space above the car, so the standing driver (≈ 222px tall) clears
   the heading (the tabs and banner move down by that) */
@media (max-width: 639.98px) {
  .hero { height: calc(619px + 54px - 64px + 230px); }
  .hero__aside { margin-top: 140px; }
}
@media (max-width: 539.98px) {
  .hero { height: calc(619px + 203px - 64px + 230px); }
}
/* …the driver stays in front of the now centred car: his figure 40px right
   of the car's centre (the area's centre; 196px base width → right edge
   98px past it) and his feet just below its wheels (26px higher than his
   stacked spot); the red lines belong to the side-by-side layout and are
   left out */
@media (max-width: 639.98px) {
  .hero__aside-overlay {
    right: calc(50% - 40px - 98px);
    bottom: calc(157.5px - var(--car-w) * 0.30247 + 26px);
  }
  .hero::before { display: none; }
}
/* Below 640px (stacked hero) no driver in front of the car */
@media (max-width: 639.98px) {
  .hero__aside-overlay { display: none; }
}
/* Below 640px (stacked hero) a bigger car: 372px wide instead of 344px
   (≈ 108px tall instead of 100px, so the hero grows by 8px); the
   background artwork grows with it (home-v2.ejs) */
@media (max-width: 639.98px) {
  .hero__aside { --car-w: 420px; margin-top: 44px; } /* then bigger again: 420px (≈ 122px tall, +22px); 40px less space above it, the driver being hidden; 32px less again for the lower heading */
  .hero__headline { margin-top: var(--space-4); } /* heading 16px lower than stacked (the car's margin above makes up for changes here) */
  .hero { height: calc(619px + 54px - 64px + 190px + 22px); }
}
@media (max-width: 539.98px) {
  .hero { height: calc(619px + 203px - 64px + 190px + 22px); }
}
/* Below 640px the tabs and event banner sit 16px higher: the hero is 16px
   shorter (the heading and car keep their places) */
@media (max-width: 639.98px) {
  .hero { height: calc(619px + 54px - 64px + 190px + 22px - 16px); }
}
@media (max-width: 539.98px) {
  .hero { height: calc(619px + 203px - 64px + 190px + 22px - 16px); }
}
/* Mobile (below 540px): the stacked hero's car a little smaller (392px
   instead of 420px); the background artwork shrinks with it (home-v2.ejs) */
@media (max-width: 539.98px) {
  .hero__aside { --car-w: 392px; }
}
/* Mobile (below 540px): the logo sits centred in the navbar; the burger
   button only appears once the page is scrolled and the bar gets its solid
   background (or while the menu is open), fading in */
@media (max-width: 539.98px) {
  /* the logo's column spans the whole bar; the logo slides from its centre
     (left 50%, pulled back by half its width) to the left edge once the bar
     gets its background */
  .navbar__left { grid-column: 1 / -1; grid-row: 1; justify-self: stretch; }
  .navbar__right { grid-row: 1; width: auto; }
  .navbar__brand {
    position: relative;
    left: 50%;
    translate: -50% 0;
    transform-origin: center center;
    transition: left 0.3s ease, translate 0.3s ease, transform-origin 0.3s ease, transform 0.2s ease;
  }
  .navbar--scrolled .navbar__brand {
    left: 0;
    translate: 0 0;
    transform-origin: left center;
  }
  .navbar__burger.button {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
  }
  .navbar--scrolled .navbar__burger.button,
  .navbar--menu-open .navbar__burger.button {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.2s ease, visibility 0s;
  }
}
/* Mobile (below 540px): tighter social cards — 12px between them and 12px
   above them (to the contact form) */
@media (max-width: 539.98px) {
  .social-grid { gap: var(--space-3); margin-top: var(--space-3); }
}
/* Copyright on a gallery image: bottom left, white 8px text on a black
   wrapper, above the image (clicks pass through to it) */
.about-gallery__copyright {
  position: absolute;
  left: var(--space-2);   /* 8px in from the image's left edge */
  bottom: var(--space-2); /* 8px up from its bottom edge */
  z-index: 1;
  max-width: calc(100% - 2 * var(--space-2));
  padding: 2px 6px;
  background: #000;
  font-family: 'Bai Jamjuree', sans-serif;
  font-size: 8px;
  line-height: 12px;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
