/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */
/* Flat and honest. Extends nothing external: no framework, no gradients.
 *
 * Colour carries exactly one meaning here — time pressure, or how much we
 * trust a date. Nothing is coloured for decoration, because a row that shouts
 * for aesthetic reasons is a row that cannot shout when it matters. See #29.
 *
 * There are two palettes now (ADR-0017). The warning that used to stand here —
 * that a second palette is a second place to get the urgency contrast wrong —
 * was right, so the answer is measurement rather than restraint: every pair is
 * checked against WCAG AA by test/models/palette_contrast_test.rb, which reads
 * these tokens rather than restating them.
 */

/* Two palettes, one meaning. Colour says exactly one thing here — time
 * pressure — and the dark set is not the light one inverted: red loses more
 * luminance against a dark ground than amber or green do, so the three would
 * have stopped being equals. Every pair below is measured against WCAG AA,
 * and the urgency triple sits within 0.3 of itself on dark, which puts the
 * distinction in the hue where it belongs. See ADR-0017.
 *
 * Values live once, in the -l- and -d- tokens. The two mapping blocks under
 * them carry no colours, so a colour is only ever edited in one place. */
:root {
  --l-bg:#fdfdfc; --l-surface:#fff; --l-surface-2:#f9fafb; --l-surface-3:#f4f4f5;
  --l-ink:#1a1a1a; --l-ink-2:#3f3f46; --l-muted:#6b7280; --l-faint:#83898f;
  --l-line:#e5e7eb; --l-line-strong:#d4d4d8;
  --l-ok:#067647; --l-ok-bg:#ecfdf3; --l-warn:#b45309; --l-warn-bg:#fffbeb;
  --l-crit:#b42318; --l-crit-bg:#fef2f2;
  --l-shadow:0 8px 24px rgb(0 0 0 / .08);

  /* Series colours. Red and green stay out of reach: they already mean critical
   * and verified, and a series borrowing one would say something about urgency
   * it does not know. Orange is the deliberate exception, asked for by name —
   * it is the closest to --warn amber, so it is pitched brighter and more
   * saturated than the amber a badge uses, and the two sit side by side in a
   * race row. If they ever start reading as one thing, change this shade.
   *
   * Two sets, for the same reason the urgency triple has two (ADR-0017): the
   * light values are dark ink on a pale tint, and reusing them on the dark
   * ground would paint five bright rectangles into a dark page. The dark set
   * inverts the relationship rather than the colours — light ink on a deep
   * tint of the same hue — and keeps orange clear of --d-warn. */
  --l-acc-blue:#1d4ed8;   --l-acc-blue-bg:#eff6ff;   --l-acc-blue-line:#bfdbfe;
  --l-acc-violet:#6d28d9; --l-acc-violet-bg:#f5f3ff; --l-acc-violet-line:#ddd6fe;
  --l-acc-teal:#0f766e;   --l-acc-teal-bg:#f0fdfa;   --l-acc-teal-line:#99f6e4;
  --l-acc-orange:#ea580c; --l-acc-orange-bg:#fff7ed; --l-acc-orange-line:#fed7aa;
  --l-acc-slate:#475569;  --l-acc-slate-bg:#f8fafc;  --l-acc-slate-line:#cbd5e1;

  --d-bg:#131316; --d-surface:#1b1b1f; --d-surface-2:#222227; --d-surface-3:#2a2a30;
  --d-ink:#f4f4f5; --d-ink-2:#d4d4d8; --d-muted:#a1a1aa; --d-faint:#8b8b95;
  --d-line:#2c2c33; --d-line-strong:#42424b;
  --d-ok:#3fbf70; --d-ok-bg:#0f2a1c; --d-warn:#d69b1c; --d-warn-bg:#2a2010;
  --d-crit:#ff8577; --d-crit-bg:#2f1613;
  --d-shadow:0 8px 24px rgb(0 0 0 / .5);

  --d-acc-blue:#6ea8fe;   --d-acc-blue-bg:#111c33;   --d-acc-blue-line:#24406e;
  --d-acc-violet:#b39dfa; --d-acc-violet-bg:#1d1633; --d-acc-violet-line:#3d2f6b;
  --d-acc-teal:#45c9b8;   --d-acc-teal-bg:#0d2a28;   --d-acc-teal-line:#1d5450;
  --d-acc-orange:#ff9f5a; --d-acc-orange-bg:#2e1a0d; --d-acc-orange-line:#63381a;
  --d-acc-slate:#a3b1c2;  --d-acc-slate-bg:#1a1f26;  --d-acc-slate-line:#3a4450;

  /* `color-scheme` is load-bearing, not decoration: without it the browser
   * paints native inputs, checkboxes and scrollbars for the wrong theme on
   * top of these surfaces. */
  color-scheme: light;
  --bg:var(--l-bg); --surface:var(--l-surface); --surface-2:var(--l-surface-2);
  --surface-3:var(--l-surface-3); --ink:var(--l-ink); --ink-2:var(--l-ink-2);
  --muted:var(--l-muted); --faint:var(--l-faint);
  --line:var(--l-line); --line-strong:var(--l-line-strong);
  --ok:var(--l-ok); --ok-bg:var(--l-ok-bg); --warn:var(--l-warn); --warn-bg:var(--l-warn-bg);
  --crit:var(--l-crit); --crit-bg:var(--l-crit-bg); --shadow:var(--l-shadow);

  --acc-blue:var(--l-acc-blue); --acc-blue-bg:var(--l-acc-blue-bg); --acc-blue-line:var(--l-acc-blue-line);
  --acc-violet:var(--l-acc-violet); --acc-violet-bg:var(--l-acc-violet-bg); --acc-violet-line:var(--l-acc-violet-line);
  --acc-teal:var(--l-acc-teal); --acc-teal-bg:var(--l-acc-teal-bg); --acc-teal-line:var(--l-acc-teal-line);
  --acc-orange:var(--l-acc-orange); --acc-orange-bg:var(--l-acc-orange-bg); --acc-orange-line:var(--l-acc-orange-line);
  --acc-slate:var(--l-acc-slate); --acc-slate-bg:var(--l-acc-slate-bg); --acc-slate-line:var(--l-acc-slate-line);
  --r:.5rem; --r-sm:.375rem; --r-xs:.25rem;
  /* One height for everything a person types into, picks from or presses.
   * A button was 44px next to a 34px field for no reason anybody chose. */
  --control-h:40px; --control-h-sm:32px;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:var(--d-bg); --surface:var(--d-surface); --surface-2:var(--d-surface-2);
  --surface-3:var(--d-surface-3); --ink:var(--d-ink); --ink-2:var(--d-ink-2);
  --muted:var(--d-muted); --faint:var(--d-faint);
  --line:var(--d-line); --line-strong:var(--d-line-strong);
  --ok:var(--d-ok); --ok-bg:var(--d-ok-bg); --warn:var(--d-warn); --warn-bg:var(--d-warn-bg);
  --crit:var(--d-crit); --crit-bg:var(--d-crit-bg); --shadow:var(--d-shadow);
  --acc-blue:var(--d-acc-blue); --acc-blue-bg:var(--d-acc-blue-bg); --acc-blue-line:var(--d-acc-blue-line);
  --acc-violet:var(--d-acc-violet); --acc-violet-bg:var(--d-acc-violet-bg); --acc-violet-line:var(--d-acc-violet-line);
  --acc-teal:var(--d-acc-teal); --acc-teal-bg:var(--d-acc-teal-bg); --acc-teal-line:var(--d-acc-teal-line);
  --acc-orange:var(--d-acc-orange); --acc-orange-bg:var(--d-acc-orange-bg); --acc-orange-line:var(--d-acc-orange-line);
  --acc-slate:var(--d-acc-slate); --acc-slate-bg:var(--d-acc-slate-bg); --acc-slate-line:var(--d-acc-slate-line);
}

/* "System" is a real choice, not the absence of one: it follows the machine.
 * An explicit light or dark must win over it, which is why this is scoped to
 * the attribute rather than left as a bare media query. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    color-scheme: dark;
    --bg:var(--d-bg); --surface:var(--d-surface); --surface-2:var(--d-surface-2);
    --surface-3:var(--d-surface-3); --ink:var(--d-ink); --ink-2:var(--d-ink-2);
    --muted:var(--d-muted); --faint:var(--d-faint);
    --line:var(--d-line); --line-strong:var(--d-line-strong);
    --ok:var(--d-ok); --ok-bg:var(--d-ok-bg); --warn:var(--d-warn); --warn-bg:var(--d-warn-bg);
    --crit:var(--d-crit); --crit-bg:var(--d-crit-bg); --shadow:var(--d-shadow);
    --acc-blue:var(--d-acc-blue); --acc-blue-bg:var(--d-acc-blue-bg); --acc-blue-line:var(--d-acc-blue-line);
    --acc-violet:var(--d-acc-violet); --acc-violet-bg:var(--d-acc-violet-bg); --acc-violet-line:var(--d-acc-violet-line);
    --acc-teal:var(--d-acc-teal); --acc-teal-bg:var(--d-acc-teal-bg); --acc-teal-line:var(--d-acc-teal-line);
    --acc-orange:var(--d-acc-orange); --acc-orange-bg:var(--d-acc-orange-bg); --acc-orange-line:var(--d-acc-orange-line);
    --acc-slate:var(--d-acc-slate); --acc-slate-bg:var(--d-acc-slate-bg); --acc-slate-line:var(--d-acc-slate-line);
  }
}

* { box-sizing: border-box; }
/* The `hidden` attribute is `display: none` in the browser's own stylesheet,
   which means any author rule with a `display` beats it — `.nav__locale-links
   { display: inline-flex }` left the language links visible next to the select
   that replaced them, with the attribute correctly set the whole time. This
   restores the meaning of the attribute so hiding something is a matter of
   setting it, not of remembering which rules would win. */
[hidden] { display: none !important; }
body { max-width: 68rem; margin: 0 auto; padding: 0 1.25rem 4rem; color: var(--ink);
       background: var(--bg);
       font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
       /* Numbers in this product are read in columns and compared. */
       font-variant-numeric: tabular-nums; }

.display { font-size: 2.5rem; line-height: 1.08; letter-spacing: -.021em; margin: 0;
           font-weight: 620; text-wrap: balance; }
h1 { font-size: 1.6rem; margin: 0 0 .35rem; letter-spacing: -.012em; }
h2 { font-size: 1.1rem; margin: 2rem 0 .6rem; letter-spacing: -.006em; }
h3 { font-size: .95rem; margin: 1.25rem 0 .4rem; }
.lede { color: var(--muted); margin: 0 0 1.5rem; max-width: 46rem; }
.hint { color: var(--muted); font-size: .82rem; margin: .4rem 0 0; }
.muted { color: var(--muted); }
.faint { color: var(--faint); }
.small { font-size: .82rem; }
.nowrap { white-space: nowrap; }
.eyebrow { font-size: .72rem; text-transform: uppercase; letter-spacing: .07em;
           color: var(--muted); font-weight: 600; }
a { color: var(--ink); text-decoration-color: var(--line-strong); text-underline-offset: 2px; }
a:hover { text-decoration-color: var(--ink); }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .92em; }

/* -- nav ------------------------------------------------------------------ */
.nav { display: flex; align-items: center; gap: .75rem; padding: .85rem 0; margin-bottom: 2rem;
       border-bottom: 1px solid var(--line); font-size: .9rem; flex-wrap: wrap; }
.nav__brand { font-weight: 640; text-decoration: none; color: var(--ink); letter-spacing: -.01em;
              margin-right: .4rem; }
.nav__spacer { flex: 1; }
.nav a { text-decoration: none; color: var(--muted); }
.nav a:hover { color: var(--ink); }
/* `.nav a` is more specific than `.button`, so the sign-up button in the bar
   was drawing muted grey text on the filled dark ground — the one control on
   a public page that has to be legible was the least legible thing in the bar.
   Restated here rather than made more specific in `.button`: the exception
   belongs where the collision is. */
.nav .button { color: var(--bg); }
.nav .button:hover { color: var(--bg); }
.nav .button--quiet, .nav .button--quiet:hover { color: var(--ink); }
/* The places you go, as one group. Signed in there are four of them, so they
   need to read as a set rather than as four things scattered after the
   wordmark. */
.nav__primary { display: flex; align-items: center; gap: .9rem; }
/* Where you are. Weight rather than colour: colour in this product means time
   pressure and nothing else (ADR-0017), and the underline is what carries the
   mark for anybody who cannot see the weight. */
.nav__primary a.is-current { color: var(--ink); font-weight: 550;
                             text-decoration: underline; text-underline-offset: .3em;
                             text-decoration-thickness: 2px; }
/* Theme and language are settings, not destinations: one divider for both. */
.nav__utils { display: inline-flex; gap: .5rem; align-items: center;
              padding-left: .7rem; border-left: 1px solid var(--line); }
.nav__locales { display: inline-flex; gap: .35rem; align-items: center; }
.nav__select select { height: 28px; min-height: 28px; font-size: .85rem;
                      padding: 0 1.35rem 0 .4rem;
                      background-position: calc(100% - .8rem) calc(50% - 2px),
                                           calc(100% - .5rem) calc(50% - 2px);
                      border: 1px solid var(--line-strong); border-radius: var(--r-xs);
                      /* background-color, not the shorthand: this rule is more
                         specific than the generic `select` below, and the
                         shorthand would reset the chevron drawn there. */
                      background-color: var(--surface); color: var(--ink); }
.nav__locale-links { display: inline-flex; gap: .35rem; }

/* -- nav menu ------------------------------------------------------------- */
/* <details> rather than a scripted popover: it opens, closes and takes
   keyboard focus natively, so the account links stay reachable even if the
   JavaScript never arrives. */
.menu { position: relative; }
.menu__summary { display: inline-flex; align-items: center; gap: .25rem; cursor: pointer;
                 color: var(--muted); list-style: none; padding: .2rem .1rem; }
.menu__summary::-webkit-details-marker { display: none; }
.menu__summary:hover { color: var(--ink); }
.menu[open] .menu__summary { color: var(--ink); }
.menu__chevron { width: 14px; height: 14px; transition: transform .12s ease; }
.menu[open] .menu__chevron { transform: rotate(180deg); }
.menu__panel { position: absolute; right: 0; top: calc(100% + .4rem); z-index: 20;
               min-width: 12rem; padding: .35rem; background: var(--surface);
               border: 1px solid var(--line-strong); border-radius: var(--r);
               box-shadow: var(--shadow); }
.menu__who { margin: .25rem .55rem .4rem; font-size: .78rem; color: var(--faint);
             overflow: hidden; text-overflow: ellipsis; }
.menu__label { margin: .5rem .55rem .2rem; font-size: .7rem; letter-spacing: .04em;
               text-transform: uppercase; color: var(--faint); }
.menu__item { display: block; padding: .35rem .55rem; border-radius: var(--r-xs);
              color: var(--ink); text-decoration: none; font-size: .88rem; }
.nav .menu__item { color: var(--ink); }
.menu__item:hover { background: var(--surface-2); }
.menu__item--button { width: 100%; text-align: left; border: 0; background: none;
                      font: inherit; cursor: pointer; }
.menu__sep { height: 1px; background: var(--line); margin: .35rem .2rem; }
.menu--compact .menu__summary { padding: .2rem .3rem; }
.menu__item.is-current { color: var(--ink); font-weight: 550; }
.menu__tick { float: right; color: var(--muted); }

@media (max-width: 46rem) {
  /* Anchored to the nav rather than the summary, so a narrow screen does not
     push the panel off the right edge. */
  .menu__panel { right: 0; left: auto; min-width: 11rem; }
}

/* Present to a screen reader, absent to the eye. Used for labels that a
   sighted reader gets from context — the language select is next to its own
   options — but that a screen reader would otherwise announce unlabelled. */
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px;
                   padding: 0; overflow: hidden; clip: rect(0 0 0 0);
                   white-space: nowrap; border: 0; }

/* -- controls -------------------------------------------------------------
   One height, one radius, one border for every control on the page. Fields,
   dropdowns and buttons had drifted into three different boxes: a button was
   44px tall next to a 34px field, and in Safari a dropdown was taller than
   both.

   The dropdown is the reason this is one block rather than a rule per
   element. Safari applies its own appearance to a <select>, which means it
   ignores the height it is given and adds padding of its own — a filter bar
   came out with the dropdown visibly taller than the field beside it. Only
   `appearance: none` hands the box back, and it takes the native chevron with
   it, so the chevron is drawn here.

   It is drawn with two gradients rather than an SVG on purpose: gradients can
   use `currentColor`, so the arrow follows the text into the dark theme. A
   data URI would have the colour baked in, and painting a dark arrow onto a
   dark field is exactly the kind of thing ADR-0017 exists to prevent. */
.button { display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
          min-height: var(--control-h); border: 1px solid var(--ink);
          background: var(--ink); color: var(--bg);
          padding: 0 1.05rem; border-radius: var(--r-sm); font-size: .95rem; font-weight: 550;
          cursor: pointer; text-decoration: none; font-family: inherit;
          /* Also for `input[type="submit"]`, which carries this class: iOS
             Safari otherwise rounds it and pales it in its own way. */
          appearance: none; -webkit-appearance: none; }
.button--quiet { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.button--sm { min-height: var(--control-h-sm); font-size: .85rem; padding: 0 .7rem; }
.link-button { border: 0; background: none; padding: 0; color: var(--muted); cursor: pointer;
               text-decoration: underline; font: inherit; }

/* -- badges --------------------------------------------------------------- */
.badge { display: inline-flex; align-items: center; gap: .25rem; font-size: .72rem; line-height: 1.45;
         padding: .1rem .4rem; border-radius: var(--r-xs); border: 1px solid currentColor;
         white-space: nowrap; }
.badge--ok { color: var(--ok); }
.badge--warn { color: var(--warn); }
.badge--estimate { color: var(--warn); }
.badge--critical { color: var(--crit); background: var(--crit-bg); }
.badge--quiet { color: var(--faint); }

/* -- the urgency scale ---------------------------------------------------- */
/* Days remaining is the largest number in a row and the only element that
 * changes colour. Three days out and eight months out have to read
 * differently at a glance, which a date cannot do on its own. */
.group { margin-top: 1.8rem; }
/* A month that carries on from the page before keeps neither the heading nor
   the gap under it: the rows are a continuation of the same run. The border the
   first row of a group drops is put back for the same reason. */
.group--continued { margin-top: 0; }
.group--continued .race-row:first-of-type { border-top: 1px solid var(--line); }
.group__head { display: flex; align-items: baseline; gap: .6rem; padding-bottom: .4rem;
               border-bottom: 1px solid var(--line-strong); }
.group__head h2 { margin: 0; }
.group__count { color: var(--faint); font-size: .82rem; }

.row { display: grid; grid-template-columns: 62px 150px minmax(0, 1fr) 116px 172px;
       gap: 0 1rem; align-items: start; padding: .7rem .5rem .7rem .55rem;
       border-bottom: 1px solid var(--line); border-left: 3px solid transparent; }
.row--now { border-left-color: var(--crit); background: var(--crit-bg); }
.row--soon { border-left-color: var(--warn); }
.row--stale { background: var(--warn-bg); }

.days { text-align: right; }
.days__n { font-size: 1.35rem; line-height: 1.05; font-weight: 620; letter-spacing: -.02em;
           display: block; }
.days__u { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--faint); }
.u-now  .days__n { color: var(--crit); }
.u-soon .days__n { color: var(--warn); }
.u-near .days__n { color: var(--ink); }
.u-far  .days__n { color: var(--muted); font-weight: 550; }
.u-unknown .days__n { color: var(--warn); font-size: 1.1rem; }
.u-past .days__n { color: var(--faint); font-weight: 550; }
/* Open now: the row a reader can act on today. Green rather than amber — this
   is not a warning, it is the state the whole product is pointing at. */
.u-open .days__n { color: var(--ok); }

/* -- calendar grid -------------------------------------------------------- */
/* The catalogue page groups by horizon because that is the order a season is
   read in. This grid answers the other question: where the season is empty.
   Three deadlines in one week with nothing either side is obvious here and
   invisible in a list, and the gap is where the next race goes. */
.cal__bar { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
            margin-bottom: 1rem; }
.cal__head { display: flex; align-items: center; gap: .6rem; margin: 1rem 0 .4rem; }
.cal__head h2 { margin: 0; flex: 1; font-size: 1.15rem; }
.cal { width: 100%; border-collapse: collapse; table-layout: fixed; }
.cal th { font-size: .75rem; font-weight: 550; color: var(--muted); text-align: left;
          padding: .3rem .4rem; border-bottom: 1px solid var(--line); }
.cal__cell { border: 1px solid var(--line); vertical-align: top; height: 6.5rem;
             padding: .3rem; overflow: hidden; }
.cal__cell.is-outside { background: var(--surface-2); }
.cal__cell.is-outside .cal__day { color: var(--faint); }
.cal__cell.is-today { outline: 2px solid var(--ink); outline-offset: -2px; }
.cal__day { font-size: .78rem; color: var(--muted); margin-bottom: .2rem; }
.cal__event { font-size: .72rem; line-height: 1.25; padding: .12rem .25rem; margin-bottom: .15rem;
              border-radius: var(--r-xs); border-left: 3px solid var(--line-strong);
              background: var(--surface-2); overflow: hidden; text-overflow: ellipsis;
              white-space: nowrap; }
.cal__event .muted { display: block; font-size: .68rem; }
/* Same three colours as everywhere else, carrying the same one meaning. */
.cal__event.u-now  { border-left-color: var(--crit); background: var(--crit-bg); }
.cal__event.u-soon { border-left-color: var(--warn); background: var(--warn-bg); }
.cal__event.u-past { border-left-color: var(--line); color: var(--faint); }
.cal__event--race  { border-left-color: var(--ink); }

@media (max-width: 46rem) {
  /* A seven-column grid on a phone is unreadable. The cells stack, and an
     empty day is dropped entirely rather than shown as a blank row. */
  .cal, .cal tbody, .cal tr, .cal td { display: block; width: 100%; }
  .cal thead { display: none; }
  .cal__cell { height: auto; border: 0; border-bottom: 1px solid var(--line); }
  .cal__cell:not(:has(.cal__event)) { display: none; }
  .cal__day::after { content: " " attr(data-label); color: var(--faint); }
}

.when { font-size: .88rem; }
.when__tz { color: var(--muted); font-size: .78rem; display: block; }
/* An estimate is italic and prefixed, so false precision has nowhere to hide. */
.when--estimate { font-style: italic; color: var(--warn); }
.what__kind { font-weight: 550; }
.what__race { color: var(--muted); font-size: .86rem; }
.meta { display: flex; flex-direction: column; gap: .2rem; font-size: .78rem; }
.meta a { color: var(--muted); }

/* Two empty states that must never look like a bug, and read differently:
 * the organiser has not said, versus we have not collected it. */
.unpublished { font-style: italic; color: var(--faint); }

/* -- hero ----------------------------------------------------------------- */
.hero { display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr); gap: 2.5rem;
        align-items: start; padding: .5rem 0 2.4rem; border-bottom: 1px solid var(--line); }
.hero__actions { display: flex; gap: .6rem; flex-wrap: wrap; margin-top: 1.5rem; }
.hero__trust { display: flex; align-items: flex-start; gap: .5rem; margin-top: 1.2rem;
               color: var(--muted); font-size: .84rem; max-width: 34rem; }

.next { border: 1px solid var(--line-strong); border-radius: var(--r); overflow: hidden;
        background: var(--surface); }
.next__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
              padding: .55rem .9rem; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.next__body { padding: 1rem .9rem; border-left: 3px solid var(--line-strong); }
.next__body--now { border-left-color: var(--crit); }
.next__body--soon { border-left-color: var(--warn); }
.next__count { display: flex; align-items: baseline; gap: .5rem; }
.next__n { font-size: 3.4rem; line-height: .9; font-weight: 640; letter-spacing: -.035em; }
.next__body--now .next__n { color: var(--crit); }
.next__body--soon .next__n { color: var(--warn); }
.next__foot { display: flex; flex-wrap: wrap; gap: .4rem .8rem; align-items: center;
              padding: .55rem .9rem; border-top: 1px solid var(--line); font-size: .78rem;
              color: var(--muted); }

/* -- honesty band --------------------------------------------------------- */
.band { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem;
        padding: 1.6rem 0; border-bottom: 1px solid var(--line); }
.band__n { font-size: 1.5rem; font-weight: 620; letter-spacing: -.02em; display: block; }
.band__note { color: var(--muted); font-size: .84rem; }

/* -- calendar preview ----------------------------------------------------- */
.cal { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface-2);
       padding: 1rem; }
.cal__day { display: grid; grid-template-columns: 74px minmax(0, 1fr); gap: 1rem; padding: .55rem 0;
            border-top: 1px solid var(--line); align-items: start; }
.cal__day:first-of-type { border-top: 0; }
.cal__date { text-align: right; font-size: .8rem; color: var(--muted); padding-top: .15rem; }
.cal__date strong { display: block; font-size: 1.05rem; color: var(--ink); }
.evt { border-left: 3px solid var(--ink); background: var(--surface); padding: .4rem .6rem;
       border-radius: 0 var(--r-xs) var(--r-xs) 0; font-size: .86rem; }
.evt--crit { border-left-color: var(--crit); }
.evt__time { color: var(--muted); font-size: .76rem; display: block; }

/* -- filter --------------------------------------------------------------- */
/* Seven fieldsets of checkboxes were the first thing a visitor met. Same
 * facets, a fraction of the surface, and collapsed by default: the filter is a
 * second-visit tool. */
/* The race list's own two controls. The seven-facet grid below belongs to the
   home page, where the unit is a deadline and the facets are the whole point. */
.lookup { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-bottom: 1.6rem; }
.lookup__field { display: inline-flex; }
.lookup input[type="search"] { min-width: 14rem; }

.filters { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
           margin: 1.8rem 0 0; }
.filters > summary { display: flex; align-items: center; gap: .6rem; padding: .85rem 1rem;
                     cursor: pointer; font-weight: 550; flex-wrap: wrap; }
.filters > summary::-webkit-details-marker { display: none; }
.filters > summary::marker { content: ""; }
.filters__chevron { transition: transform .15s; flex-shrink: 0; }
.filters[open] .filters__chevron { transform: rotate(90deg); }
.filters__summary-note { color: var(--muted); font-weight: 400; font-size: .84rem; }
.filters__chips { display: flex; gap: .35rem; flex-wrap: wrap; margin-left: auto; }
.chip { font-size: .74rem; border: 1px solid var(--line-strong); border-radius: 999px;
        padding: .1rem .55rem; color: var(--muted); }
.filters__body { padding: 0 1rem 1rem; border-top: 1px solid var(--line); }
.filters__grid { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
                 padding-top: 1rem; }
.filters__actions { margin-top: 1.2rem; display: flex; gap: .5rem; flex-wrap: wrap; }
fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
legend { font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .05em;
         color: var(--muted); margin-bottom: .45rem; }
.facet { display: flex; gap: .35rem; flex-wrap: wrap; }
/* A tick box styled as a tag: same semantics, a quarter of the vertical run. */
.tag { position: relative; display: inline-flex; }
.tag input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.tag span { display: inline-flex; align-items: center; gap: .3rem; min-height: 30px; font-size: .82rem;
            border: 1px solid var(--line-strong); border-radius: 999px; padding: 0 .6rem;
            color: var(--ink); }
.tag input:checked + span { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.tag input:focus-visible + span { outline: 2px solid var(--ink); outline-offset: 2px; }
.check { display: block; font-size: .9rem; }
.field { display: inline-block; margin-right: .75rem; font-size: .9rem; }
.field input { width: 5.5rem; }
input[type="text"], input[type="email"], input[type="password"], input[type="search"],
input[type="url"], input[type="number"], input[type="date"], input[type="datetime-local"],
input[type="time"], select, textarea {
  height: var(--control-h); min-height: var(--control-h); border: 1px solid var(--line-strong);
  border-radius: var(--r-sm); background: var(--surface); color: var(--ink); font: inherit;
  line-height: 1.2; padding: 0 .6rem; }

/* Everything except the number field, which keeps its stepper: it is a real
   control on the distance filters, and unlike a select it already honours the
   height it is given. */
input[type="text"], input[type="email"], input[type="password"], input[type="search"],
input[type="url"], input[type="date"], input[type="datetime-local"], input[type="time"],
select, textarea { appearance: none; -webkit-appearance: none; }

/* A text area is the one control that must be free to be tall. */
textarea { height: auto; min-height: 5.5rem; padding: .5rem .6rem; line-height: 1.5;
           resize: vertical; }

select { padding-right: 2rem; cursor: pointer;
         background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                           linear-gradient(135deg, currentColor 50%, transparent 50%);
         background-position: calc(100% - 1.05rem) calc(50% - 2px),
                              calc(100% - .65rem) calc(50% - 2px);
         background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; }
select:disabled { color: var(--faint); cursor: default; }

/* Safari draws its own furniture inside a search field and ignores the box
   around it until the appearance is dropped above; these are what is left. */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-results-button { -webkit-appearance: none; }

/* Removing the appearance removes the focus ring with it in Safari, and a
   control nobody can see the focus on is a control nobody can use from a
   keyboard. One ring for all of them. */
.button:focus-visible, .link-button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--ink); outline-offset: 2px; }
/* A fieldset legend that carries a heading: strip the browser's own spacing so
   the heading sits where every other h2 on the page does. */
fieldset { border: 0; padding: 0; margin: 0; }
fieldset legend { padding: 0; }
fieldset legend h2 { margin: 0 0 .4rem; }

/* -- results and tables --------------------------------------------------- */
.results__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
                 flex-wrap: wrap; margin-top: 2rem; }
.results__head h2 { margin: 0; }
table.deadlines { width: 100%; border-collapse: collapse; margin-top: .75rem; }
table.deadlines th { text-align: left; font-size: .74rem; text-transform: uppercase;
                     letter-spacing: .05em; color: var(--muted); border-bottom: 1px solid var(--line-strong);
                     padding: .4rem .5rem; font-weight: 600; }
table.deadlines td { border-bottom: 1px solid var(--line); padding: .55rem .5rem; vertical-align: top; }
table.deadlines tr.is-stale { background: var(--warn-bg); }
td.meta { font-size: .8rem; }

/* -- cards, blocks, misc -------------------------------------------------- */
.card { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
        padding: 1.1rem 1.15rem; }
.empty { color: var(--muted); border: 1px dashed var(--line-strong); padding: 1rem;
         border-radius: var(--r); }
.flash { padding: .6rem .8rem; border-radius: var(--r-sm); border: 1px solid var(--warn);
         color: var(--warn); margin: 0 0 1rem; }
.errors { color: var(--crit); padding-left: 1.1rem; }
.crumbs { font-size: .82rem; color: var(--muted); margin-bottom: .75rem; }
.crumbs a { color: var(--muted); }
.stack { display: grid; gap: .75rem; max-width: 24rem; }
.stack--wide { max-width: 34rem; }
.field-block { display: grid; gap: .25rem; font-size: .9rem; }
.race-list { padding-left: 1.1rem; }
.race-list li { margin-bottom: .3rem; }
.feed-url { display: flex; align-items: center; gap: .6rem; border: 1px solid var(--line-strong);
            border-radius: var(--r-sm); background: var(--surface-2); padding: .6rem .7rem; }
.feed-url code { flex: 1; word-break: break-all; font-size: .84rem; }
.feed-list { padding-left: 1.1rem; }
.metric { border: 1px solid var(--line); border-left-width: 4px; border-radius: var(--r);
          padding: 1rem 1.25rem; margin: 1rem 0 2rem; }
.metric--ok { border-left-color: var(--ok); }
.metric--alarm { border-left-color: var(--crit); background: var(--crit-bg); }
.metric__value { font-size: 2.2rem; font-weight: 600; margin: 0; line-height: 1.1; }
.metric__note { color: var(--muted); margin: .35rem 0 0; font-size: .9rem; }
.subscribe-block { border: 1px solid var(--line); border-radius: var(--r); padding: 1.1rem 1.15rem;
                   margin-top: 2rem; background: var(--surface); }
.subscribe-block h2 { margin-top: 0; }
.content-choice .check { margin-bottom: .3rem; }
.content-choice .muted { font-size: .82rem; }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem;
         margin-top: .8rem; }
.step { border: 1px solid var(--line); border-radius: var(--r); padding: .9rem; background: var(--surface); }
.step h3 { margin-top: 0; }
.step ol { margin: .5rem 0 0; padding-left: 1.1rem; font-size: .86rem; color: var(--ink-2); }
.step li { margin-bottom: .3rem; }
/* A watched page's diff. Monospace because these are lines of somebody else's
   page, and proportional type hides that two of them differ by one character. */
.source-diff { list-style: none; margin: 0 0 1rem; padding: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .78rem; }
.source-diff li { padding: .15rem .5rem; border-left: 3px solid var(--line-strong);
  overflow-wrap: anywhere; }
.source-diff--added li { border-left-color: var(--ok); }
.source-diff--removed li { border-left-color: var(--warn);
  color: var(--muted); text-decoration: line-through; }

.expect { border-left: 3px solid var(--warn); background: var(--warn-bg);
          border-radius: 0 var(--r) var(--r) 0; padding: .9rem 1rem; margin-top: .8rem; }
.ico { width: 16px; height: 16px; flex-shrink: 0; stroke: currentColor; fill: none;
       stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* -- timeline (race page) ------------------------------------------------- */
.tl { position: relative; margin: 1rem 0 0; padding-left: 1.1rem; }
.tl::before { content: ""; position: absolute; left: 3px; top: .4rem; bottom: .4rem; width: 1px;
              background: var(--line-strong); }
.tl__item { position: relative; padding: .5rem 0; display: grid;
            grid-template-columns: 62px 150px minmax(0, 1fr) 172px; gap: 1rem; align-items: start; }
.tl__dot { position: absolute; left: -1.1rem; top: 1.05rem; width: 7px; height: 7px;
           border-radius: 50%; background: var(--line-strong); }
.tl__item--now .tl__dot { background: var(--crit); box-shadow: 0 0 0 3px var(--crit-bg); }
.tl__item--past .tl__dot { background: transparent; border: 1px solid var(--line-strong); }

@media (max-width: 46rem) {
  .hero, .band { grid-template-columns: 1fr; gap: 1.5rem; }
  .row, .tl__item { grid-template-columns: 54px minmax(0, 1fr); gap: .2rem .8rem; }
  .row .meta, .tl__item .meta { grid-column: 2; }
  .row .when, .tl__item .when { grid-column: 2; }
  .row .what, .tl__item .what { grid-column: 2; }
}

/* Race rows -------------------------------------------------------------- */
/* The catalogue list used to be a three-column table: date, name, city. What
   made one race different from another — its series, its distances, whether it
   is road or trail — was one click away on every row. */
.race-row { display: grid; grid-template-columns: 62px minmax(0, 1fr) auto; gap: 1rem;
  align-items: start; padding: .6rem 0; border-top: 1px solid var(--line); }
.race-row:first-of-type { border-top: 0; }
.race-row__date { text-align: right; font-size: .78rem; color: var(--muted); padding-top: .15rem; }
.race-row__date strong { display: block; font-size: 1.2rem; line-height: 1.1; color: var(--ink);
  letter-spacing: -.02em; font-weight: 620; }
.race-row__name { font-weight: 550; }
.race-row__meta { color: var(--muted); font-size: .82rem; margin-top: .1rem; }
.race-row__tags { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .4rem; }
.race-row__pick { display: flex; flex-wrap: wrap; gap: .3rem; justify-content: flex-end; }
.chip--link { text-decoration: none; color: var(--ink); }
.chip--link:hover { border-color: var(--ink); }
.chip--quiet { color: var(--muted); border-style: dashed; }

/* Only a handful of series carry a colour. Colouring all of them would be the
   same as colouring none: the point is that three names are recognisable
   without being read. */
.chip--blue   { color: var(--acc-blue);   background: var(--acc-blue-bg);   border-color: var(--acc-blue-line); }
.chip--violet { color: var(--acc-violet); background: var(--acc-violet-bg); border-color: var(--acc-violet-line); }
.chip--teal   { color: var(--acc-teal);   background: var(--acc-teal-bg);   border-color: var(--acc-teal-line); }
.chip--orange { color: var(--acc-orange); background: var(--acc-orange-bg); border-color: var(--acc-orange-line); }
.chip--slate  { color: var(--acc-slate);  background: var(--acc-slate-bg);  border-color: var(--acc-slate-line); }
.chip--blue:hover   { border-color: var(--acc-blue); }
.chip--violet:hover { border-color: var(--acc-violet); }
.chip--teal:hover   { border-color: var(--acc-teal); }
.chip--orange:hover { border-color: var(--acc-orange); }
.chip--slate:hover  { border-color: var(--acc-slate); }

/* The same colour on the row's left edge. A chip has to be read; an edge is
   seen, and scanning sixty rows for "which of these are Majors" is exactly
   what this page is for. */
.race-row--blue, .race-row--violet, .race-row--teal, .race-row--orange,
.race-row--slate { padding-left: .7rem; }
.race-row--blue   { box-shadow: inset 3px 0 0 var(--acc-blue); }
.race-row--violet { box-shadow: inset 3px 0 0 var(--acc-violet); }
.race-row--teal   { box-shadow: inset 3px 0 0 var(--acc-teal); }
.race-row--orange { box-shadow: inset 3px 0 0 var(--acc-orange); }
.race-row--slate  { box-shadow: inset 3px 0 0 var(--acc-slate); }

/* -- the series index ------------------------------------------------------
   Cards rather than a list. A bulleted name with a race count after it is true
   and gives nobody a reason to open one series over another; what tells them
   apart is what a season with it in it looks like. The grid is auto-fill so
   six series and sixteen both land somewhere sensible without a breakpoint per
   count. */
.series-grid { display: grid; gap: 1rem; margin-top: 1.5rem;
               grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr)); }
.series-card { border: 1px solid var(--line); border-radius: var(--r);
               background: var(--surface); padding: 1rem 1.1rem; }
.series-card__name { margin: 0; font-size: 1.05rem; letter-spacing: -.01em; }
.series-card__name a { text-decoration: none; color: var(--ink); }
.series-card__name a:hover { text-decoration: underline; }
.series-card__kind { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
                     margin: .45rem 0 .8rem; font-size: .84rem; }
/* Two facts, each a label above its value, so the eye can compare the same
   line across cards instead of reading each one as prose. */
.series-card__facts { display: grid; gap: .6rem; margin: 0;
                      border-top: 1px solid var(--line); padding-top: .7rem; }
.series-card__facts dt { font-size: .68rem; text-transform: uppercase;
                         letter-spacing: .07em; color: var(--faint); }
.series-card__facts dd { margin: .1rem 0 0; font-size: .88rem; }
.series-card__facts dd > .muted { min-width: 0; }
/* The countdown is the same number as everywhere else, one size down: a card
   is a summary, and a 1.35rem digit on it would outshout the season it
   summarises. */
.series-card__facts dd { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem; }
/* `days_cell` stacks the number over its unit, which is right in a 62px
   column and wrong in a sentence. Here the two sit on one line with the kind
   of deadline after them, and the pair never breaks apart. */
.series-card__days { white-space: nowrap; }
.series-card__days .days__n { display: inline; font-size: 1.05rem; }
.series-card__days .days__u { margin-left: .15rem; }
.series-card__foot { margin: .8rem 0 0; color: var(--muted); font-size: .8rem; min-height: 1.1em; }

/* The series' own colour on the card's edge, exactly as on a race row: an edge
   is seen rather than read, and this page is a page of six things to tell
   apart at a glance. */
.series-card--blue, .series-card--violet, .series-card--teal,
.series-card--orange, .series-card--slate { border-left-width: 3px; }
.series-card--blue   { border-left-color: var(--acc-blue); }
.series-card--violet { border-left-color: var(--acc-violet); }
.series-card--teal   { border-left-color: var(--acc-teal); }
.series-card--orange { border-left-color: var(--acc-orange); }
.series-card--slate  { border-left-color: var(--acc-slate); }

/* A race already in a calendar reads as a state, not as an action waiting to
   be taken — hence the filled button rather than another outline. */
.pick { display: flex; flex-wrap: wrap; gap: .3rem; justify-content: flex-end; }
.pick form { display: inline; }
.pick__on { background: var(--ok); border-color: var(--ok); color: var(--bg); }

/* The pick list on a feed's own page. */
.picked__row { display: flex; align-items: baseline; gap: .5rem; padding: .35rem 0;
  border-top: 1px solid var(--line); }
.picked__row:first-child { border-top: 0; }
.picked__add { display: flex; gap: .5rem; align-items: center; margin-top: .8rem; flex-wrap: wrap; }

/* The third column of a series row: what the race wants from the reader before
   it happens. Right-aligned against the row's own edge so the eye can scan the
   column on its own, and coloured by urgency through the same u-* classes the
   catalogue uses — one vocabulary for "how soon" across the product
   (ADR-0017). */
.race-row__next { text-align: right; min-width: 8.5rem; }
.race-row__next-link { text-decoration: none; display: block; }
.race-row__next-kind { display: block; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--faint); }
.race-row__next-days { display: block; }
.race-row__next .days__n { font-size: 1.05rem; }
.race-row__next-link:hover .race-row__next-kind { color: var(--muted); }

@media (max-width: 640px) {
  .race-row { grid-template-columns: 52px minmax(0, 1fr); }
  .race-row__pick { grid-column: 2; justify-content: flex-start; }
  /* Under the name rather than beside it, and left-aligned with everything
     else in that column: a right-aligned scrap of text on a narrow screen
     reads as a mistake. */
  .race-row__next { grid-column: 2; text-align: left; margin-top: .35rem; }
  .race-row__next-days { display: inline; }
  .race-row__next-kind { display: inline; }
}
