/* The hidden attribute is how panels, modals and locked reveals are toggled
   across this site. A class that sets its own display - .pv-unlock's flex, for
   instance - beats the browser's built-in [hidden] rule, so the element keeps
   rendering and the attribute does nothing. That is how the unlock panel went
   on offering to unlock a race that was already open. State it once, here. */
[hidden] { display: none !important; }

/* ==========================================================================
   ACE PODIUM  -  design system
   --------------------------------------------------------------------------
   Direction: "the form book". A printed racecard / form book for a data-led
   UK & Ireland racing model. Ruled columns, tabular figures, a narrow
   annotation rail carrying real metadata, one accent, no decorative motion.

   Craft rules enforced in this file (do not break them casually):
     1. ONE accent (--accent). Semantic win/place/lose marks are the only
        other colours and they are marks, never fills.
     2. ONE radius value (--radius). 0 for full-bleed bands and hairlines.
     3. ONE theme per page. Light "paper" and dark "floodlit" are token swaps;
        no section inverts.
     4. Nothing animates except transform and opacity.
     5. Every interactive element has hover, active, focus-visible and
        disabled states.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  /* light: "paper" */
  --l-bg:        #f4f4f1;
  --l-bg-tint:   #eceae4;
  --l-surface:   #fbfbf9;
  --l-sunken:    #e7e6e0;
  --l-ink:       #14181a;
  --l-ink-2:     #4c5459;
  --l-ink-3:     #757d81;
  --l-rule:      rgba(20, 24, 26, 0.14);
  --l-rule-soft: rgba(20, 24, 26, 0.07);
  --l-accent:    #0f5132;
  --l-accent-2:  #14603c;
  --l-accent-in: #ffffff;
  --l-shadow:    0 1px 2px rgba(14, 28, 22, 0.06), 0 12px 32px -18px rgba(14, 28, 22, 0.22);
  --l-shadow-sm: 0 1px 2px rgba(14, 28, 22, 0.10);

  /* dark: "floodlit" */
  --d-bg:        #0f1311;
  --d-bg-tint:   #141917;
  --d-surface:   #171d1a;
  --d-sunken:    #0a0e0c;
  --d-ink:       #e9ebe7;
  --d-ink-2:     #a7b0aa;
  --d-ink-3:     #7c857f;
  --d-rule:      rgba(233, 235, 231, 0.16);
  --d-rule-soft: rgba(233, 235, 231, 0.08);
  --d-accent:    #59b98d;
  --d-accent-2:  #6fcaa0;
  --d-accent-in: #08130d;
  --d-shadow:    0 1px 2px rgba(0, 0, 0, 0.4), 0 18px 40px -22px rgba(0, 0, 0, 0.7);
  --d-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);

  /* active mapping (defaults to paper; see the two overrides at the end) */
  --bg: var(--l-bg);
  --bg-tint: var(--l-bg-tint);
  --surface: var(--l-surface);
  --sunken: var(--l-sunken);
  --ink: var(--l-ink);
  --ink-2: var(--l-ink-2);
  --ink-3: var(--l-ink-3);
  --rule: var(--l-rule);
  --rule-soft: var(--l-rule-soft);
  --accent: var(--l-accent);
  --accent-2: var(--l-accent-2);
  --accent-ink: var(--l-accent-in);
  --shadow: var(--l-shadow);
  --shadow-sm: var(--l-shadow-sm);
  --on-photo: #ffffff;
  /* The accent has to be the light one wherever it sits on a photograph: the
     light-theme accent is a dark green and disappears against a dark image. */
  --accent-on-photo: #59b98d;

  /* type */
  --sans: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --fs-xs:   0.75rem;
  --fs-sm:   0.8125rem;
  --fs-base: 1rem;
  --fs-md:   1.0625rem;
  --fs-lg:   clamp(1.125rem, 1.4vw, 1.25rem);
  --fs-xl:   clamp(1.375rem, 2vw, 1.625rem);
  --fs-2xl:  clamp(1.75rem, 3.2vw, 2.5rem);
  --fs-3xl:  clamp(2.25rem, 5vw, 3.75rem);
  --fs-4xl:  clamp(2.375rem, 5.4vw, 4.25rem);

  /* space scale (4px base) */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 2.5rem;   --s-8: 3rem;
  --s-9: 4rem;     --s-10: 5rem;    --s-11: 6rem;    --s-12: 8rem;

  --radius: 3px;
  --container: 1240px;
  --rail: 172px;
  --measure: 65ch;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --t-fast: 140ms var(--ease);
  --t: 240ms var(--ease);

  --z-base: 1; --z-sticky: 100; --z-drawer: 200; --z-modal: 300; --z-toast: 400;
}

/* explicit dark, and system dark for no-JS pages */
:root[data-theme="dark"] {
  --bg: var(--d-bg); --bg-tint: var(--d-bg-tint); --surface: var(--d-surface);
  --sunken: var(--d-sunken); --ink: var(--d-ink); --ink-2: var(--d-ink-2);
  --ink-3: var(--d-ink-3); --rule: var(--d-rule); --rule-soft: var(--d-rule-soft);
  --accent: var(--d-accent); --accent-2: var(--d-accent-2);
  --accent-ink: var(--d-accent-in); --shadow: var(--d-shadow);
  --shadow-sm: var(--d-shadow-sm);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg: var(--d-bg); --bg-tint: var(--d-bg-tint); --surface: var(--d-surface);
    --sunken: var(--d-sunken); --ink: var(--d-ink); --ink-2: var(--d-ink-2);
    --ink-3: var(--d-ink-3); --rule: var(--d-rule); --rule-soft: var(--d-rule-soft);
    --accent: var(--d-accent); --accent-2: var(--d-accent-2);
    --accent-ink: var(--d-accent-in); --shadow: var(--d-shadow);
    color-scheme: dark;
  }
}

/* ---------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }
img, picture, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }
table { border-collapse: collapse; width: 100%; }
:target { scroll-margin-top: 6rem; }

body {
  font-family: var(--sans);
  font-size: var(--fs-base);
  font-weight: 400;
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------------------------------------------------------- typography */
h1, h2, h3, h4 { font-weight: 600; line-height: 1.08; letter-spacing: -0.022em; text-wrap: balance; }
h1 { font-size: var(--fs-4xl); font-weight: 700; letter-spacing: -0.035em; }
h2 { font-size: var(--fs-2xl); letter-spacing: -0.028em; }
h3 { font-size: var(--fs-xl); line-height: 1.2; }
h4 { font-size: var(--fs-md); line-height: 1.3; letter-spacing: -0.01em; }
p  { text-wrap: pretty; }
strong, b { font-weight: 600; }
small { font-size: var(--fs-sm); }

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--s-4); }
.prose p { color: var(--ink-2); }

/* the mono voice: all figures, times, odds, probabilities, codes */
.fig, .mono { font-family: var(--mono); font-feature-settings: "tnum" 1, "zero" 1; }
.fig { font-variant-numeric: tabular-nums; }

/* a label. used sparingly - see the eyebrow budget in the brief. */
.label {
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.label--ink { color: var(--ink-2); }

/* Rail heading. Deliberately NOT an uppercase tracking eyebrow: it is a
   column heading in the annotation rail, set in sentence case so the page
   does not develop the templated "eyebrow above every section" rhythm. */
.rail-title {
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin-bottom: var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule);
}

.lede { font-size: var(--fs-lg); color: var(--ink-2); line-height: 1.55; }
.muted { color: var(--ink-3); }
.tnum { font-variant-numeric: tabular-nums; }

/* App surfaces are tools, not landing pages. The display scale drops a step so
   an internal page header does not shout over the data it introduces. */
body[data-area="admin"] h1,
body[data-area="user"] h1 { font-size: var(--fs-2xl); letter-spacing: -0.03em; }
body[data-area="admin"] h2,
body[data-area="user"] h2 { font-size: var(--fs-xl); }

/* ------------------------------------------------------------- layout */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--s-5);
}
@media (min-width: 900px) { .container { padding-inline: var(--s-7); } }

.band { padding-block: var(--s-9) var(--s-10); }
.band--tight { padding-block: var(--s-8); }
.band--loose { padding-block: var(--s-10) var(--s-12); }
.band--tint { background: var(--bg-tint); }
.band--rule { border-top: 1px solid var(--rule); }
.band--sunken { background: var(--sunken); }

/* the annotation rail: narrow metadata column + wide content column.
   This is the signature layout of the site.

   Both tracks are declared minmax(0, 1fr) even in the single-column base case.
   A grid item's default min-width is auto, which means a wide child (the
   racecard ledger, a long code, a table) expands the track instead of scrolling
   inside its own overflow container, and the whole page grows sideways. */
.grid-rail { display: grid; gap: var(--s-5); grid-template-columns: minmax(0, 1fr); }
.grid-rail > *, .split > *, .stack > *, .pv-auth > *, .field > * { min-width: 0; }
@media (min-width: 900px) {
  .grid-rail { grid-template-columns: var(--rail) minmax(0, 1fr); gap: var(--s-8); align-items: start; }
  .grid-rail--flip > :first-child { order: 2; }
  .grid-rail--wide { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); }
}
.rail-sticky { position: static; }
@media (min-width: 900px) { .rail-sticky { position: sticky; top: 5.5rem; } }

.split { display: grid; gap: var(--s-6); grid-template-columns: minmax(0, 1fr); }
.split > * { min-width: 0; }
@media (min-width: 900px) { .split { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); } }
.split--hero { align-items: center; }
@media (min-width: 1000px) { .split--hero { grid-template-columns: minmax(0, 1.06fr) minmax(0, 0.94fr); gap: var(--s-8); } }
.split--offset > :nth-child(2) { position: static; }
@media (min-width: 900px) { .split--offset > :nth-child(2) { margin-top: var(--s-9); } }

.stack > * + * { margin-top: var(--s-4); }
.stack-lg > * + * { margin-top: var(--s-6); }
.stack-sm > * + * { margin-top: var(--s-2); }
.row { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.row--end { justify-content: flex-end; }

/* -------------------------------------------------------------- masthead */
.masthead {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  border-bottom: 1px solid var(--rule);
}
/* The brand stripe: three tints of the one accent, drawn once at the very top
   of the page like the colour band on a set of silks. It is the only place the
   accent appears as pure decoration, which is what keeps it a signature rather
   than wallpaper. Derived from --accent, so the single-colour lock holds. */
.masthead::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg,
    var(--accent) 0 33.34%,
    color-mix(in srgb, var(--accent) 70%, var(--bg)) 33.34% 66.67%,
    color-mix(in srgb, var(--accent) 42%, var(--bg)) 66.67% 100%);
  pointer-events: none;
}
/* the double rule: a masthead device borrowed from printed racecards */
.masthead::after {
  content: ""; display: block; height: 1px; background: var(--rule-soft);
  margin-top: 1px;
}
.masthead__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); height: 64px;
}
.masthead__brand { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; }
.masthead__brand:hover .mark { transform: translateY(-1px); }
.masthead__name {
  font-weight: 700; font-size: 1rem; letter-spacing: -0.02em; white-space: nowrap;
}
.masthead__name span { font-weight: 400; color: var(--ink-3); }
.mark { transition: transform var(--t); flex: none; color: var(--accent); }
.mark--sm { width: 22px; height: 22px; }
.mark--md { width: 28px; height: 28px; }

.nav { display: flex; align-items: center; gap: var(--s-1); }
.nav__link {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-sm); font-weight: 500; color: var(--ink-2);
  padding: var(--s-2) var(--s-3); text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
  white-space: nowrap;
}
.nav__link:hover { color: var(--ink); }
.nav__link.is-active { color: var(--ink); border-bottom-color: var(--accent); }
.nav__link[aria-current="page"] { color: var(--ink); border-bottom-color: var(--accent); }
.nav__link svg { width: 15px; height: 15px; }

.nav__chip {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--mono); font-size: 0.75rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); text-decoration: none;
  transition: border-color var(--t-fast), background var(--t-fast);
  white-space: nowrap;
}
.nav__chip:hover { border-color: var(--accent); }
.nav__chip--accent { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.nav__chip--accent:hover { background: var(--accent-2); }

.masthead__side { display: flex; align-items: center; gap: var(--s-3); }
.masthead__toggle-mobile { display: inline-flex; }
@media (min-width: 1000px) { .masthead__toggle-mobile { display: none; } }

/* Below the breakpoint the inline nav is replaced by the drawer. Without this
   the nav and the burger compete for the same width and the trailing control
   gets clipped off the edge of the masthead. */
@media (max-width: 999px) { .nav { display: none; } }

/* mobile nav: a slide-over, not a hamburger accordion */
.mobile-nav { position: fixed; inset: 0; z-index: var(--z-drawer); display: none; }
.mobile-nav.is-open { display: block; }
.mobile-nav__scrim { position: absolute; inset: 0; background: rgba(8, 12, 10, 0.5); }
.mobile-nav__panel {
  position: absolute; top: 0; right: 0; height: 100%; width: min(88vw, 340px);
  background: var(--bg); border-left: 1px solid var(--rule);
  padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-2);
  overflow-y: auto;
}
.mobile-nav__panel a, .mobile-nav__panel button {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-2); font-size: var(--fs-md);
  color: var(--ink); text-decoration: none; text-align: left;
  border-bottom: 1px solid var(--rule-soft);
}
.mobile-nav__panel a:hover { color: var(--accent); }

/* --------------------------------------------------------------- buttons */
.btn {
  --btn-bg: transparent; --btn-ink: var(--ink); --btn-bd: var(--rule);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.005em;
  padding: 0.6875rem 1.25rem; border-radius: var(--radius);
  border: 1px solid var(--btn-bd); background: var(--btn-bg); color: var(--btn-ink);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform var(--t-fast), background var(--t-fast),
              border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; }

.btn--primary { --btn-bg: var(--accent); --btn-ink: var(--accent-ink); --btn-bd: var(--accent); }
.btn--primary:hover { --btn-bg: var(--accent-2); --btn-bd: var(--accent-2); }
.btn--ghost { --btn-bg: transparent; --btn-ink: var(--ink); --btn-bd: var(--rule); }
.btn--ghost:hover { --btn-bd: var(--ink-3); }
.btn--quiet { --btn-bd: transparent; --btn-ink: var(--ink-2); padding-inline: var(--s-3); }
.btn--quiet:hover { --btn-ink: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.btn--danger { --btn-bg: transparent; --btn-ink: #9c3a2f; --btn-bd: rgba(156, 58, 47, 0.4); }
.btn--danger:hover { --btn-bg: #9c3a2f; --btn-ink: #fff; --btn-bd: #9c3a2f; }
:root[data-theme="dark"] .btn--danger { --btn-ink: #e2877a; --btn-bd: rgba(226, 135, 122, 0.4); }
:root[data-theme="dark"] .btn--danger:hover { --btn-bg: #b04a3c; --btn-ink: #fff; }
.btn--sm { padding: 0.4375rem 0.75rem; font-size: var(--fs-xs); }
.btn--lg { padding: 0.9375rem 1.75rem; font-size: var(--fs-base); }
.btn--block { width: 100%; }

/* icon-only control */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: var(--radius);
  border: 1px solid var(--rule); color: var(--ink-2); background: transparent;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.icon-btn:hover { color: var(--ink); border-color: var(--ink-3); transform: translateY(-1px); }
.icon-btn:active { transform: translateY(1px); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.icon-btn svg { width: 16px; height: 16px; }
.icon-btn--plain { border-color: transparent; }
.icon-btn--plain:hover { border-color: var(--rule); }

/* text link with a rule that draws in */
.link {
  color: var(--accent); text-decoration: none; font-weight: 500;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size var(--t);
}
.link:hover { background-size: 100% 1px; }
.link-arrow { display: inline-flex; align-items: center; gap: var(--s-2); color: var(--accent); text-decoration: none; font-weight: 500; }
.link-arrow svg { width: 15px; height: 15px; transition: transform var(--t); }
.link-arrow:hover svg { transform: translateX(3px); }

/* ------------------------------------------------------------ surfaces */
.panel {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.panel__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.panel__body { padding: var(--s-5); }
.panel__foot { padding: var(--s-4) var(--s-5); border-top: 1px solid var(--rule); }

/* a ruled block: no border, no shadow, just a top rule. the default grouping. */
.ruled { border-top: 1px solid var(--rule); padding-top: var(--s-4); }
.ruled-list > * { border-bottom: 1px solid var(--rule-soft); padding-block: var(--s-4); }
.ruled-list > *:last-child { border-bottom: 0; }

/* --------------------------------------------------------------- ledger */
/* the data table of the site: a racecard. one rule per row, columns with
   real horizontal breathing room so adjacent values never touch. */
.ledger { font-variant-numeric: tabular-nums; }
.ledger thead th {
  font-family: var(--mono); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3);
  text-align: left; padding: 0 var(--s-5) var(--s-3) 0;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.ledger tbody td, .ledger tbody th {
  padding: var(--s-4) var(--s-5) var(--s-4) 0;
  border-bottom: 1px solid var(--rule-soft);
  text-align: left; vertical-align: top; font-weight: 400;
}
.ledger thead th:last-child, .ledger tbody td:last-child { padding-right: 0; }
.ledger tbody tr:last-child td, .ledger tbody tr:last-child th { border-bottom: 0; }
.ledger tbody tr { transition: background var(--t-fast); }
.ledger tbody tr:hover { background: color-mix(in srgb, var(--ink) 4%, transparent); }
.ledger .num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ledger .rank {
  font-family: var(--mono); font-size: var(--fs-sm); color: var(--ink-3);
  width: 2.5rem; padding-right: var(--s-3);
}
.ledger .rank--first { color: var(--accent); font-weight: 600; }
.ledger__wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
/* a stacked cell: course over race name, so the meeting column never
   needs four wrapped lines to be readable */
.ledger__meeting { display: grid; gap: 2px; min-width: 15rem; }
.ledger__course { font-weight: 600; }
.ledger__race { color: var(--ink-3); font-size: var(--fs-sm); max-width: 34ch; }
.ledger__time { font-family: var(--mono); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* -- hit / miss marks. This is semantic state, not decoration: one glyph
      per result row, and nothing else on the site uses these colours. */
.mark-hit  { color: var(--accent); font-family: var(--mono); font-weight: 600; }
.mark-miss { color: var(--ink-3); font-family: var(--mono); }
:root[data-theme="dark"] .mark-hit { color: var(--d-accent); }
.place-tag {
  display: inline-block; font-family: var(--mono); font-size: 0.625rem; font-weight: 500;
  letter-spacing: 0.06em; padding: 1px 5px; border: 1px solid currentColor;
  border-radius: var(--radius); color: var(--ink-3);
}

/* a form-figure strip: recent finishing positions, newest first */
.formfig { display: inline-flex; gap: 2px; font-family: var(--mono); font-size: var(--fs-xs); }
.formfig span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.25rem; height: 1.25rem; border: 1px solid var(--rule);
  color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.formfig span.is-win { border-color: var(--accent); color: var(--accent); font-weight: 600; }

/* progress-free probability readout: number + thin rule, no filled track */
.prob { display: inline-flex; align-items: baseline; gap: var(--s-2); font-family: var(--mono); }
.prob__val { font-size: var(--fs-md); font-weight: 600; font-variant-numeric: tabular-nums; }
.prob__bar { display: block; height: 3px; background: currentColor; opacity: 0.85; }
.prob--top { color: var(--accent); }

/* ---------------------------------------------------------------- stats */
.stat { display: block; }
.stat__val {
  font-family: var(--mono); font-size: clamp(1.75rem, 3.4vw, 2.75rem);
  font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.03em;
  line-height: 1; display: block;
}
.stat__label { display: block; margin-top: var(--s-2); font-size: var(--fs-sm); color: var(--ink-3); }
.stat-rule {
  display: grid; gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
}
.stat-rule > * { border-top: 1px solid var(--rule); padding-top: var(--s-4); }

/* ---------------------------------------------------------------- forms */
.field { display: grid; gap: var(--s-2); }
.field > label, .label-above {
  font-size: var(--fs-sm); font-weight: 500; color: var(--ink);
}
.input, .select, .textarea {
  width: 100%; padding: 0.6875rem 0.875rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--radius);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
  font-size: var(--fs-base);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-3); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"] { border-color: #9c3a2f; }
.input[disabled], .select[disabled] { opacity: 0.55; cursor: not-allowed; }
.select { appearance: none; padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23757d81' stroke-width='1.5'%3E%3Cpath d='M4 6.5 8 10.5l4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.75rem center; background-size: 16px; }
.help { font-size: var(--fs-xs); color: var(--ink-3); }
.error-text { font-size: var(--fs-xs); color: #9c3a2f; font-weight: 500; }
:root[data-theme="dark"] .error-text, :root[data-theme="dark"] .input[aria-invalid="true"] { color: #e2877a; }
:root[data-theme="dark"] .input[aria-invalid="true"] { border-color: #e2877a; }
.field-row { display: grid; gap: var(--s-4); }
@media (min-width: 700px) { .field-row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.check { display: flex; align-items: flex-start; gap: var(--s-3); font-size: var(--fs-sm); color: var(--ink-2); }
.check input { margin-top: 0.2rem; accent-color: var(--accent); width: 16px; height: 16px; flex: none; }

.form-note {
  padding: var(--s-3) var(--s-4); border-left: 2px solid var(--accent);
  background: var(--bg-tint); font-size: var(--fs-sm); color: var(--ink-2);
}
.form-note--warn { border-left-color: #9c6e2a; }
.form-note--error { border-left-color: #9c3a2f; }

/* --------------------------------------------------------------- pieces */
.eyebrow {
  font-family: var(--mono); font-size: 0.6875rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent);
  display: inline-flex; align-items: center; gap: var(--s-2);
}
.hatch {
  height: 6px;
  background-image: repeating-linear-gradient(-45deg, var(--rule) 0 1px, transparent 1px 5px);
}
.badge {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--mono); font-size: 0.625rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 2px var(--s-2); border: 1px solid var(--rule);
  border-radius: var(--radius); color: var(--ink-2);
}
.badge--accent { border-color: var(--accent); color: var(--accent); }
.badge--solid { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.notice {
  border: 1px solid var(--rule); border-left-width: 3px; border-left-color: var(--ink-3);
  background: var(--bg-tint); padding: var(--s-5); border-radius: var(--radius);
}
.notice--caution { border-left-color: #9c6e2a; }
.notice h2, .notice h3 { font-size: var(--fs-md); }
:root[data-theme="dark"] .notice--caution { border-left-color: #c9963f; }

/* figure with a caption, used for real photography */
.figure { margin: 0; }
.figure img { width: 100%; height: auto; border-radius: var(--radius); }
.figure figcaption {
  margin-top: var(--s-3); font-size: var(--fs-xs); color: var(--ink-3);
  font-family: var(--mono); letter-spacing: 0.01em;
}
.figure--band img { border-radius: 0; }
.photo-band { position: relative; overflow: hidden; background: var(--sunken); }
.photo-band img { width: 100%; height: clamp(240px, 46vw, 460px); object-fit: cover; }
/* The band overlay is the page's clearest 60-30-10 moment: the photograph holds
   the 60 as the dominant field, the white type carries the 30, and a single
   accent element carries the 10 - a keyline above the heading, in the light
   accent because it has to read on a photograph. Nothing else takes the accent,
   which is what keeps the split intact. */
.photo-band__overlay {
  position: absolute; inset: auto 0 0 0;
  padding: var(--s-6) var(--s-6) var(--s-6) calc(var(--s-6) + var(--s-4));
  background: linear-gradient(to top,
    rgba(8, 14, 11, 0.92) 0%,
    rgba(8, 14, 11, 0.70) 44%,
    rgba(8, 14, 11, 0.24) 100%);
  color: var(--on-photo);
}
/* The accent sits BESIDE the text, not above it: the scrim is transparent at the
   overlay's top edge, so anything placed there lands on bare grass. A light green
   line on green grass is no line at all. */
.photo-band__overlay::before {
  content: "";
  position: absolute;
  left: var(--s-6);
  top: var(--s-6);
  bottom: var(--s-6);
  width: 4px;
  border-radius: 1px;
  background: var(--accent-on-photo);
}
.photo-band__overlay h2,
.photo-band__overlay h3 { color: var(--on-photo); }
.photo-band__overlay p { color: rgba(255, 255, 255, 0.78); }

/* ---------------------------------------------------- loading/empty/error */
.skeleton {
  background: linear-gradient(90deg, var(--sunken) 25%, var(--bg-tint) 37%, var(--sunken) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius);
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
.skeleton--line { height: 12px; margin-block: var(--s-2); }
.skeleton--line.short { width: 45%; }
.skeleton--block { height: 72px; }

.empty {
  border: 1px dashed var(--rule); border-radius: var(--radius);
  padding: var(--s-7) var(--s-5); text-align: center;
}
.empty__title { font-weight: 600; font-size: var(--fs-md); }
.empty p { color: var(--ink-3); font-size: var(--fs-sm); margin-top: var(--s-2); }

.state-error {
  border: 1px solid var(--rule); border-left-width: 3px; border-left-color: #9c3a2f;
  padding: var(--s-5); border-radius: var(--radius); background: var(--bg-tint);
}

/* --------------------------------------------------------------- toasts */
.toast-host {
  position: fixed; right: var(--s-4); bottom: var(--s-4); z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: var(--s-2); width: min(92vw, 360px);
  pointer-events: none;
}
.toast {
  pointer-events: auto; display: flex; align-items: flex-start; gap: var(--s-3);
  background: var(--surface); border: 1px solid var(--rule); border-left-width: 3px;
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: var(--s-3) var(--s-4); font-size: var(--fs-sm); color: var(--ink);
  animation: toast-in 220ms var(--ease) both;
}
.toast--ok { border-left-color: var(--accent); }
.toast--warn { border-left-color: #9c6e2a; }
.toast--error { border-left-color: #9c3a2f; }
.toast--out { animation: toast-out 180ms var(--ease) both; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px); } }

/* -------------------------------------------------------- modal / drawer */
.overlay {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background: rgba(8, 12, 10, 0.55); display: none;
  align-items: center; justify-content: center; padding: var(--s-4);
}
.overlay.is-open { display: flex; }
.modal {
  width: min(100%, 520px); max-height: 90dvh; overflow-y: auto;
  background: var(--bg); border: 1px solid var(--rule);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.modal__head { padding: var(--s-5) var(--s-5) var(--s-3); display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-4); }
.modal__body { padding: 0 var(--s-5) var(--s-5); }
.modal__foot { padding: var(--s-4) var(--s-5); border-top: 1px solid var(--rule); display: flex; gap: var(--s-3); justify-content: flex-end; }

.drawer {
  position: fixed; top: 0; right: 0; height: 100%; width: min(92vw, 420px);
  z-index: var(--z-drawer); background: var(--bg); border-left: 1px solid var(--rule);
  transform: translateX(100%); transition: transform var(--t); display: flex; flex-direction: column;
}
.drawer.is-open { transform: none; }
.drawer__head { padding: var(--s-5); border-bottom: 1px solid var(--rule); display: flex; align-items: center; justify-content: space-between; }
.drawer__body { padding: var(--s-5); overflow-y: auto; flex: 1; }

/* --------------------------------------------------------------- footer */
.footer { border-top: 1px solid var(--rule); background: var(--bg-tint); margin-top: auto; }
.footer__inner { padding-block: var(--s-8) var(--s-6); }
.footer__grid { display: grid; gap: var(--s-6); }
@media (min-width: 760px) { .footer__grid { grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr)); } }
.footer h2, .footer h3 { font-size: var(--fs-sm); font-weight: 600; }
.footer__list { display: grid; gap: var(--s-2); margin-top: var(--s-4); }
.footer__list a { font-size: var(--fs-sm); color: var(--ink-2); text-decoration: none; }
.footer__list a:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.footer__base {
  margin-top: var(--s-7); padding-top: var(--s-4); border-top: 1px solid var(--rule-soft);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  align-items: baseline; justify-content: space-between;
  font-size: var(--fs-xs); color: var(--ink-3);
}

/* --------------------------------------------------------------- icons */
/* Generated <svg class="icon"> from the sprite. Sized by context. */
.icon { width: 16px; height: 16px; flex: none; vertical-align: -0.15em; }
.btn .icon { width: 16px; height: 16px; }
.btn--sm .icon { width: 14px; height: 14px; }
.nav__link .icon { width: 15px; height: 15px; }
.nav__chip .icon { width: 14px; height: 14px; }
.toast .icon { width: 17px; height: 17px; margin-top: 2px; }
.lede .icon, .panel__head .icon { width: 18px; height: 18px; }

/* theme toggle shows one glyph per mode; the markup carries both */
.i-dark { display: none; }
:root[data-theme="dark"] .i-dark { display: block; }
:root[data-theme="dark"] .i-light { display: none; }

/* ------------------------------------------------------------------ pieces */
.toolbar {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
  padding-block: var(--s-4); border-bottom: 1px solid var(--rule);
}
.toolbar__spacer { flex: 1; }

/* segmented control: view switching that is not a tab bar with a pill */
.segmented {
  display: inline-flex; border: 1px solid var(--rule);
  border-radius: var(--radius); overflow-x: auto; background: var(--surface);
  max-width: 100%;
}
.segmented button, .segmented a {
  font-size: var(--fs-xs); font-weight: 500; color: var(--ink-2);
  padding: var(--s-2) var(--s-3); text-decoration: none;
  border-right: 1px solid var(--rule); background: transparent;
  transition: background var(--t-fast), color var(--t-fast);
  white-space: nowrap;
}
/* at phone widths the labels are the only thing that can give; tighten the
   horizontal padding so a three-way switcher fits without scrolling */
@media (max-width: 430px) {
  .segmented button, .segmented a { padding: var(--s-2) 0.5rem; font-size: 0.6875rem; }
}
.segmented > :last-child { border-right: 0; }
.segmented button:hover, .segmented a:hover { color: var(--ink); background: var(--bg-tint); }
.segmented [aria-pressed="true"], .segmented [aria-current="page"] {
  background: var(--accent); color: var(--accent-ink); font-weight: 600;
}
.segmented [aria-pressed="true"]:hover, .segmented [aria-current="page"]:hover {
  background: var(--accent-2); color: var(--accent-ink);
}

/* key/value rows: race metadata in the annotation rail or a detail panel */
.kv { display: grid; gap: var(--s-2); }
.kv__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
.kv__k { font-size: var(--fs-xs); color: var(--ink-3); }
.kv__v { font-family: var(--mono); font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }

/* a pick row: rank, runner (+ form figures), probability. The core repeating unit. */
.pick {
  display: grid; grid-template-columns: 1.75rem minmax(0, 1fr) auto;
  align-items: center; gap: var(--s-3);
  padding: var(--s-3) 0; border-bottom: 1px solid var(--rule-soft);
}
.pick:last-child { border-bottom: 0; }
.pick__rank {
  font-family: var(--mono); font-size: var(--fs-sm); color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.pick--top .pick__rank { color: var(--accent); font-weight: 600; }
.pick__body { min-width: 0; display: grid; gap: 3px; }
.pick__name { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick--top .pick__name { font-weight: 600; }
.pick__prob { font-family: var(--mono); font-size: var(--fs-md); font-weight: 600; font-variant-numeric: tabular-nums; }
.pick--top .pick__prob { color: var(--accent); }
.pick__meta { font-size: var(--fs-xs); color: var(--ink-3); font-family: var(--mono); }
/* A pick's reason can run to a sentence, so let it wrap inside the row rather
   than stretching it. */
.pick__facts { line-height: 1.5; }
.pick__facts > span { min-width: 0; }

.pick__facts { font-size: var(--fs-xs); color: var(--ink-3); display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }

/* spec strip: hairline-separated facts. Avoids stacking middle dots. */
.factstrip {
  display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3);
  font-size: var(--fs-xs); color: var(--ink-3);
  font-family: var(--mono); letter-spacing: 0.01em;
}
.factstrip > span { padding-left: var(--s-3); border-left: 1px solid var(--rule); }
.factstrip > span:first-child { padding-left: 0; border-left: 0; }

/* index rows: the "today's meetings" table rendered as ruled rows */
.meeting { border-bottom: 1px solid var(--rule); padding-block: var(--s-5); }
.meeting:last-child { border-bottom: 0; }
.meeting__head { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.meeting__time {
  font-family: var(--mono); font-size: var(--fs-sm); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.meeting__course { font-weight: 600; font-size: var(--fs-md); }
.meeting__race { color: var(--ink-3); font-size: var(--fs-sm); }

/* ---------------------------------------------------------------- utilities */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--s-4); top: -100px; z-index: var(--z-toast);
  background: var(--accent); color: var(--accent-ink); padding: var(--s-3) var(--s-4);
  border-radius: var(--radius); font-size: var(--fs-sm); font-weight: 600; text-decoration: none;
  transition: top var(--t);
}
.skip:focus { top: var(--s-4); }
.hide { display: none !important; }
.hide-sm { display: none; }
@media (min-width: 700px) { .hide-sm { display: initial; } }
@media (min-width: 700px) { .only-sm { display: none; } }
.nowrap { white-space: nowrap; }
.tight { letter-spacing: -0.03em; }
/* Type and colour utilities. These exist so pages never need a static inline
   style for a font size or an ink tone. Dynamic values computed in JS are the
   only inline styles permitted. */
.t-xs { font-size: var(--fs-xs); }   .t-sm { font-size: var(--fs-sm); }
.t-base { font-size: var(--fs-base); } .t-md { font-size: var(--fs-md); }
.t-lg { font-size: var(--fs-lg); }   .t-xl { font-size: var(--fs-xl); }
.t-2xl { font-size: var(--fs-2xl); } .t-3xl { font-size: var(--fs-3xl); }
.ink { color: var(--ink); } .ink-2 { color: var(--ink-2); } .ink-3 { color: var(--ink-3); }
.accent-ink { color: var(--accent); }
.lead-13 { line-height: 1.3; } .lead-15 { line-height: 1.55; }
.maxw-24 { max-width: 24ch; } .maxw-34 { max-width: 34ch; }
.maxw-52 { max-width: 52ch; } .maxw-65 { max-width: var(--measure); }
.narrow { max-width: 30rem; }
.sep { margin: 0 0.4rem; }
.mt-1 { margin-top: var(--s-1); } .mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); } .mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); } .mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); } .mt-8 { margin-top: var(--s-8); }
.mb-2 { margin-bottom: var(--s-2); } .mb-4 { margin-bottom: var(--s-4); }
.mb-6 { margin-bottom: var(--s-6); }
.w-full { width: 100%; }
.center { text-align: center; }
.center-x { margin-inline: auto; }
.hairline { height: 1px; background: var(--rule); }

/* ======================================================================
   PLATFORM INTEGRATION
   Cross-cutting details from the Web Interface Guidelines audit: touch
   behaviour, notch/home-indicator insets, scroll behaviour under the sticky
   masthead, and long-content containment. Kept together because each one
   applies to the whole shell rather than one component.
   ====================================================================== */

/* Sticky masthead is 64px + 1px rule. Reserve that when anything scrolls an
   element into view, so a focused field or an anchor target never lands
   underneath the header. */
html { scroll-padding-top: 5.25rem; }

/* Remove the 300ms double-tap delay on touch devices. */
a, button, [role="button"], input, select, textarea, label, summary {
  touch-action: manipulation;
}

/* Deliberate tap highlight rather than the platform default flash. */
a, button, [role="button"] { -webkit-tap-highlight-color: transparent; }

/* Overlays must not chain their scroll to the page behind them. */
.overlay, .drawer, .mobile-nav__panel { overscroll-behavior: contain; }

/* Safe areas: the masthead and footer are full-bleed, so on a notched device
   the content needs to clear the sensor housing and the home indicator. */
.container {
  padding-left: max(var(--s-5), env(safe-area-inset-left));
  padding-right: max(var(--s-5), env(safe-area-inset-right));
}
@media (min-width: 900px) {
  .container {
    padding-left: max(var(--s-7), env(safe-area-inset-left));
    padding-right: max(var(--s-7), env(safe-area-inset-right));
  }
}
.footer__inner { padding-bottom: max(var(--s-6), env(safe-area-inset-bottom)); }
.mobile-nav__panel, .drawer__body {
  padding-bottom: max(var(--s-5), env(safe-area-inset-bottom));
}
.toast-host { bottom: max(var(--s-4), env(safe-area-inset-bottom)); }

/* Long unbroken content: horse names, course names and race titles are the
   worst offenders, so text cells wrap rather than widening the table. */
.ledger tbody td, .ledger tbody th, .ledger__race, .meeting__race,
.prose, .notice p, .empty p { overflow-wrap: break-word; }
.ledger tbody td { min-width: 0; }

/* Focus must stay visible on touch and keyboard alike. */
a:focus-visible, button:focus-visible, [role="button"]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------------------------------------------------------------- motion */
/* Entry reveals. Only transform + opacity. Reduced motion collapses these
   to their final state, no exceptions. */
.reveal { opacity: 1; transform: none; }
@media (prefers-reduced-motion: no-preference) {
  .js .reveal { opacity: 0; transform: translateY(14px); }
  .js .reveal.is-in {
    opacity: 1; transform: none;
    transition: opacity 620ms var(--ease), transform 620ms var(--ease);
    transition-delay: calc(var(--i, 0) * 55ms);
  }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .skeleton { animation: none; }
}

/* solid fallback when translucency is unwelcome */
@media (prefers-reduced-transparency: reduce) {
  .masthead { background: var(--bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
}


/* ============================================================== landing */
/* Interaction language borrowed from Vengeance UI (MIT), Skiper UI and
   Animmaster Lib: a perspective grid, kinetic headline type, glow-bordered
   surfaces, a running marquee and counting statistics.
   Rebuilt in plain CSS and vanilla JS - no framework, no build step, nothing
   to install, so the site still ships as files. */

.hero { position: relative; overflow: hidden; padding-block: clamp(2.75rem, 6vw, 5rem) clamp(3rem, 6vw, 5.5rem); }

.hero__bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
/* a floor grid in perspective at the foot of the hero, receding into the page */
.hero__bg::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 56%;
  background-image:
    linear-gradient(to right, color-mix(in srgb, var(--ink) 17%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--ink) 17%, transparent) 1px, transparent 1px);
  background-size: 48px 48px;
  transform: perspective(400px) rotateX(62deg);
  transform-origin: 50% 100%;
  -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, .5) 44%, transparent 90%);
          mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, .5) 44%, transparent 90%);
}
/* a bloom of the brand accent behind the headline */
.hero__bg::after {
  content: "";
  position: absolute;
  top: -36%;
  right: -14%;
  width: min(62vw, 760px);
  aspect-ratio: 1;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 30%, transparent) 0%, transparent 62%);
  opacity: .5;
}
.hero__inner { position: relative; z-index: 1; }

/* kinetic headline: each word rises and sharpens in turn */
.kinetic span { display: inline-block; }
.js .kinetic.is-armed span { opacity: 0; transform: translateY(.4em); filter: blur(7px); }
.js .kinetic.is-in span {
  opacity: 1;
  transform: none;
  filter: none;
  transition: opacity 680ms var(--ease), transform 680ms var(--ease), filter 680ms var(--ease);
  transition-delay: calc(var(--i, 0) * 85ms);
}

/* a surface whose hairline wakes up under the pointer */
.glow { position: relative; }
.glow::before,
.glow::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 320ms var(--ease);
}
.glow::before {
  background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
              color-mix(in srgb, var(--accent) 15%, transparent), transparent 66%);
}
.glow::after {
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--accent) 50%, transparent),
    0 22px 54px -26px color-mix(in srgb, var(--accent) 60%, transparent);
}
.glow:hover::before, .glow:hover::after,
.glow:focus-within::before, .glow:focus-within::after { opacity: 1; }

/* running marquee, paused on hover */
.marquee {
  position: relative;
  overflow: hidden;
  padding-block: var(--s-4);
  background: var(--bg-tint);
  border-block: 1px solid var(--rule);
}
.marquee__track { display: flex; width: max-content; animation: lnd-marquee 38s linear infinite; }
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-5);
  padding-inline: var(--s-5);
  font-family: var(--mono);
  font-size: var(--fs-sm);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}
.marquee__item::after {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
  opacity: .45;
}
@keyframes lnd-marquee { to { transform: translateX(-50%); } }

/* the method: the photograph sits as a modest plate in its own column beside the
   cards, instead of a full-width block that dominates the section.
   The column centres it vertically so it has room to drift on scroll (see
   landing.js) without ever colliding with the heading above or the cards. */
.method-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.5rem);
  align-items: center;
}
.method-grid > .figure { will-change: transform; }
@media (max-width: 1040px) {
  .method-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s-7); }
  .method-grid > .figure { max-width: 40rem; }
}

/* the method, as a bento of glow cards */
.bento { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); }
.bcard {
  padding: var(--s-6);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.bcard__num { font-family: var(--mono); font-size: var(--fs-xs); letter-spacing: .14em; color: var(--accent); }
.bcard h3 { margin-top: var(--s-3); font-size: var(--fs-lg); }
.bcard p { margin-top: var(--s-2); color: var(--ink-2); }
.bento > .bcard:first-child,
.bento > .bcard:last-child { grid-column: 1 / -1; }

/* the record counters, given room to land */
[data-page="index"] #record-stats .stat__val {
  font-size: clamp(2.5rem, 6vw, 4.25rem);
  letter-spacing: -.04em;
}

@media (max-width: 620px) {
  .bento { grid-template-columns: minmax(0, 1fr); }
  .bento > .bcard:first-child,
  .bento > .bcard:last-child { grid-column: auto; }
}

/* The notice keeps its place in the rail grid; only its content is centred, so
   the copy reads as a standalone statement rather than a left-aligned block. */
.notice--center { text-align: center; }
.notice--center p { max-width: 58ch; margin-inline: auto; }

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .js .kinetic.is-armed span { opacity: 1; transform: none; filter: none; }
}


/* =============================================================== accordion */
/* Meetings collapse to a single line, so a day's record opens as a short list
   of meetings instead of every race on one long page. */
.acc { display: grid; gap: var(--s-2); }

.acc__item {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.acc__head { margin: 0; }

.acc__btn {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  padding: var(--s-4) var(--s-5);
  background: none;
  border: 0;
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: background var(--t-fast);
}
.acc__btn:hover { background: var(--bg-tint); }
.acc__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.acc__caret { display: inline-flex; color: var(--ink-3); transition: transform var(--t); }
.acc__btn[aria-expanded="true"] .acc__caret { transform: rotate(90deg); }

.acc__name { flex: 1; min-width: 0; font-weight: 600; }

.acc__meta {
  font-family: var(--mono);
  font-size: var(--fs-xs);
  letter-spacing: .04em;
  color: var(--ink-3);
  white-space: nowrap;
  /* these carry short, fixed labels; the flexible column is .acc__name. Letting
     them shrink squeezes "3 of 3 Hit" into a 23px box and the label wraps under
     its own icon. */
  flex: 0 0 auto;
}
.acc__meta--hit { color: var(--accent); }
/* the icon is display:block, so it needs a flex context to sit beside the word */
.acc__meta .mark-hit,
.acc__meta .mark-miss { display: inline-flex; align-items: center; gap: var(--s-1); }

.acc__panel { border-top: 1px solid var(--rule); padding: var(--s-5); }

/* tighter rows: a whole day's meetings should read as one short list */
.acc--index .acc__btn { padding: var(--s-3) var(--s-4); gap: var(--s-3); }
.acc--index .acc__name { font-size: var(--fs-base); }

/* controls row above the list */
.viewbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
  margin-top: var(--s-6);
}


@media (max-width: 620px) {
  .acc__btn { gap: var(--s-3); padding: var(--s-4); }
  .acc--index .acc__btn { padding: var(--s-3) var(--s-4); }
}


/* ============================================== race times, laid out sideways */
/* A meeting's races run across one row instead of down the page: the whole
   card occupies the height of a single strip, and picking a time swaps the
   detail underneath. Overflow scrolls, so a 12-race meeting still fits. */
.acc__panel--tabs { padding: 0; }

.timetabs {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--rule);
}
.timetab {
  /* A control, not a label: its own fill (the panel is --surface, so a
     --surface tab had no face at all), a readable border, a small lift, and
     the same hover/press behaviour as .btn. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  flex: 0 0 auto;
  min-width: 4.75rem;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--bg-tint);
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--fs-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-fast), background var(--t-fast),
              border-color var(--t-fast), color var(--t-fast), box-shadow var(--t-fast);
}
.timetab:hover {
  background: var(--surface);
  border-color: var(--ink-3);
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}
.timetab:active { transform: translateY(1px); box-shadow: none; }
.timetab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.timetab[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  box-shadow: none;
}
.timetab[aria-selected="true"]:active { transform: translateY(1px); }
.timetab__time { font-variant-numeric: tabular-nums; }
.timetab__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: .3;
}
.timetab__dot[data-hit="1"] { opacity: .9; }

.racedetail { padding: var(--s-5); }
.racedetail__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin: 0 0 var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--rule-soft);
}
.racedetail__off { font-family: var(--mono); font-weight: 600; }
.racedetail__name { color: var(--ink-2); }

@media (max-width: 620px) {
  .timetabs { padding: var(--s-3) var(--s-4); }
  .racedetail { padding: var(--s-4); }
}
