/* ═══════════════════════════════════════════════════════════════
   The Fox Trail
   ---------------------------------------------------------------
   The day's races as a racecourse board game. Each race is a card
   laid on a track with white running rails that snakes down the
   board; the fox marker stands on the next race; every signal rides
   in its own silks; a winner gets a rosette, and the track ends at
   the winning post.

   Palette: the site's paper palette (paper.css). Off-white ground,
   white cards, navy ink, warm hairlines, one family of gold. Gold
   means one of two things, a winner or the strength of a signal;
   everything else is ink. The only other colours are the turf, the
   signals' racing colours, and a red dot on a race that is running.

   Type: DM Sans throughout, from the page; nothing here sets a face.

   Widths: the page steps at the site's own breakpoints (768px,
   1024px, 1280px). Inside those, the parts that sit in a column of
   varying width are containers and measure themselves: the board, a
   card, the course bar, the track record, the call to the next race.

   base.css resets margins, padding and box-sizing on every element,
   so rules here state only what they add to that.

   Scripts: trail_live, trail_flip, trail_filter, trail_drawer and
   trail_nav are the production ones and keep their hooks; trail_track,
   trail_course and trail_cards are this design's own. A rule that
   exists for one of them names it.

   Contents
     Tokens
     Page shell
     Shared drawings: icons, the signal meter, the silks
     Legend
     Masthead
     Proposition
     Track record
     Course bar
     The course: frame, board, track
     Race cards
     The results side
     Spotlight
     Card drawer
     Days without a full board
     Reduced motion
   ═══════════════════════════════════════════════════════════════ */

.page-trail {
  /* ── Ink ───────────────────────────────────────────────────── */
  --trail-ink-soft:      #5C6068;   /* labels: 6:1 on the ground */
  --trail-black:         #000000;
  --trail-on-dark:       #FFFFFF;   /* text and marks on ink */

  /* Ink and white at part strength, for hairlines, shadows and quiet
     text. Each is the full colour mixed towards nothing. */
  --trail-ink-5:         color-mix(in srgb, var(--c-ink) 5%, transparent);
  --trail-ink-8:         color-mix(in srgb, var(--c-ink) 8%, transparent);
  --trail-ink-13:        color-mix(in srgb, var(--c-ink) 13%, transparent);
  --trail-ink-16:        color-mix(in srgb, var(--c-ink) 16%, transparent);
  --trail-ink-22:        color-mix(in srgb, var(--c-ink) 22%, transparent);
  --trail-ink-32:        color-mix(in srgb, var(--c-ink) 32%, transparent);
  --trail-ink-42:        color-mix(in srgb, var(--c-ink) 42%, transparent);
  --trail-ink-50:        color-mix(in srgb, var(--c-ink) 50%, transparent);
  --trail-ink-65:        color-mix(in srgb, var(--c-ink) 65%, transparent);
  --trail-on-dark-14:    color-mix(in srgb, var(--trail-on-dark) 14%, transparent);
  --trail-on-dark-24:    color-mix(in srgb, var(--trail-on-dark) 24%, transparent);
  --trail-on-dark-50:    color-mix(in srgb, var(--trail-on-dark) 50%, transparent);
  --trail-on-dark-70:    color-mix(in srgb, var(--trail-on-dark) 70%, transparent);

  /* ── Surfaces ──────────────────────────────────────────────── */
  --trail-wash:          #F2F1EC;   /* price tags, quiet plaques */
  --trail-hover:         #EFEBE1;   /* a row or a link pointed at */
  --trail-rule-soft:     #EFEDE7;   /* a rule inside a card */

  /* ── Gold ──────────────────────────────────────────────────── */
  --trail-gold:          #C39A2B;   /* lit bars, rules, edges */
  --trail-gold-ink:      #896911;   /* gold text: 5:1 on white, 4.5:1 on the gold wash */
  --trail-gold-ink-dark: #5E4A10;   /* gold text on a gold ground */
  --trail-gold-deep:     #2B2104;   /* text on a gold fill */
  --trail-gold-fill:     #E8CB6A;   /* banners, the winner's cloth, gold on ink */
  --trail-gold-pale:     #F7E6AB;   /* the light on a medal */
  --trail-gold-wash:     #FBF5E4;   /* a tinted ground */
  --trail-gold-rule:     #EEDFB3;   /* a rule on a tinted ground */
  --trail-gold-ring:     color-mix(in srgb, var(--trail-gold-ink) 35%, transparent);

  /* Second and third: silver and bronze, as the winner is gold. A face,
     an edge, a fill for the cloth and the plaque, and the ink on it. */
  --trail-silver-face:   #F2F4F7;
  --trail-silver-edge:   #98A2B0;
  --trail-silver-fill:   #CBD2DB;
  --trail-silver-deep:   #1F252D;
  --trail-bronze-face:   #F9EDE1;
  --trail-bronze-edge:   #B37840;
  --trail-bronze-fill:   #DDA873;
  --trail-bronze-deep:   #33200C;
  --trail-rosette:       #D5B04A;   /* the rosette's pleats and tails */
  --trail-win-face:      #FFF9E8;   /* the winner's card... */
  --trail-win-edge:      #DDBF62;   /* ...and its edge */

  /* ── The course ────────────────────────────────────────────── */
  --trail-turf:          #4C7A3C;   /* under the turf tile */
  --trail-turf-edge:     #2F5228;   /* the dark line outside the rail */
  --trail-lawn:          #98BC82;   /* under the lawn tile */
  --trail-hoof:          rgba(12, 32, 12, 0.4);
  --trail-arrow:         rgba(255, 255, 255, 0.82);   /* the way round, ahead of the fox marker */

  /* ── The signals' racing colours ───────────────────────────── */
  /* A classic set, one for each of the four signals. Bet of the Day
     rides in gold, the two editorial overlays in black, and the Pick
     Winner fallback in plain grey. */
  --trail-royal:         #2F4FA2;   /* Top Rated: royal blue hoops */
  --trail-claret:        #8A2D3B;   /* Horses to Watch: claret spots */
  --trail-purple:        #5C3E95;   /* Top Steamer: purple chevrons */
  --trail-plain:         #B5AE9F;   /* Pick Winner */
  --trail-plain-edge:    #C4BFB0;   /* ...and the dashes round its card */

  /* ── Drawings, used as masks ───────────────────────────────── */
  /* All in this app's own img folder: the stylesheet asks for no file
     outside it. */
  --trail-silk-star:     url("../img/silk-star.a7b48ad90aa6.svg");
  --trail-silk-hoops:    url("../img/silk-hoops.9bfa232d75aa.svg");
  --trail-silk-spots:    url("../img/silk-spots.6181432851b8.svg");
  --trail-silk-chevrons: url("../img/silk-chevrons.1d5392ba8532.svg");
  --trail-silk-stripes:  url("../img/silk-stripes.62297fb107fb.svg");
  --trail-silk-diamond:  url("../img/silk-diamond.835436828c0b.svg");
  --trail-silk-plain:    url("../img/silk-plain.893fd4ce86cd.svg");
  --trail-silk-outline:  url("../img/silk-outline.bffbdd8bcbdb.svg");
  --trail-horseshoe:     url("../img/horseshoe.f5e7a2cd9164.svg");
  --trail-fox:           url("../img/fox.3f623d99d623.svg");

  /* ── Depth and distance ────────────────────────────────────── */
  --trail-shadow:
    0 1px 2px color-mix(in srgb, var(--c-ink) 4%, transparent),
    0 4px 14px -6px color-mix(in srgb, var(--c-ink) 10%, transparent);
  --trail-meter-off:     var(--trail-ink-13);   /* an unlit bar; re-pointed on ink */

  /* What a section or a card scrolled to must clear: the navigation,
     the tour banner while it is up, and the course bar, with some air. */
  --trail-scroll-clear:  calc(var(--nav-h) + var(--banner-h) + 82px);

  background: var(--c-paper);
  color: var(--c-ink);
}


/* ═══════════════════════════════════════════════════════════════
   Page shell
   ═══════════════════════════════════════════════════════════════ */

.trail {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 var(--space-3) 72px;
}

.trail__content { min-width: 0; }

/* From 1280px, where the site's full navigation appears, the legend
   stands beside the board as a rail. A day with nothing to show (no
   racing, or too early) renders no .trail__nav, so :has() leaves it
   in the single column above. */
@media (min-width: 1280px) {
  .trail:has(.trail__nav) {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    column-gap: 36px;
    align-items: start;
    max-width: 1720px;
    padding: 0 var(--space-5) 72px;
  }
}

/* One focus ring for every control on the page. Ink rather than the
   brand gold: gold on this ground is under 3:1. */
.trail :focus-visible {
  outline: 2px solid var(--c-ink);
  outline-offset: 2px;
}


/* ═══════════════════════════════════════════════════════════════
   Shared drawings — the icons, the signal meter, the silks
   ═══════════════════════════════════════════════════════════════ */

/* ── Icons ─────────────────────────────────────────────────── */
/* Drawn as masks: the element's background shows through the shape
   named by --mask. One rule carries the prefixed pair. */
.cell__chip::before,
.cell__pick--primary::before,
.cell__backup-tag::before,
.cell__now-glyph::after,
.cell-drawer__source-mark::before,
.trail__legend-head-icon,
.trail__nav-trigger-icon,
.trail__next-fox::after,
.course__fox-mark {
  -webkit-mask: var(--mask) center / contain no-repeat;
          mask: var(--mask) center / contain no-repeat;
}

/* ── The signal meter ──────────────────────────────────────── */
/* Four bars, like a phone's signal: as many lit as there are signals
   behind the pick. One drawing, used at three sizes. --meter-1 to
   --meter-4 are the bars' colours, set by the table underneath; each
   layer is a gradient of one colour, which is an image of that colour. */

.cell__head::after,
.cell__tier-name::before,
.record__tier-name::before,
.spotlight__title::before,
.trail__proposition-line::before {
  --meter-bar: 3px;                  /* a bar's width, and its step up to the next */
  --meter-pitch: 5px;                /* from one bar's left edge to the next */
  content: "";
  flex: 0 0 auto;
  width: calc(3 * var(--meter-pitch) + var(--meter-bar));
  height: calc(4 * var(--meter-bar) + 2px);
  background:
    linear-gradient(var(--meter-1, var(--trail-meter-off)) 0 0) 0 100% / var(--meter-bar) calc(1 * var(--meter-bar) + 2px) no-repeat,
    linear-gradient(var(--meter-2, var(--trail-meter-off)) 0 0) calc(1 * var(--meter-pitch)) 100% / var(--meter-bar) calc(2 * var(--meter-bar) + 2px) no-repeat,
    linear-gradient(var(--meter-3, var(--trail-meter-off)) 0 0) calc(2 * var(--meter-pitch)) 100% / var(--meter-bar) calc(3 * var(--meter-bar) + 2px) no-repeat,
    linear-gradient(var(--meter-4, var(--trail-meter-off)) 0 0) calc(3 * var(--meter-pitch)) 100% / var(--meter-bar) calc(4 * var(--meter-bar) + 2px) no-repeat;
}

.cell--tier-1 { --meter-1: var(--trail-gold); }

.cell--tier-2,
.record__tier--nod,
.spotlight__group--nods {
  --meter-1: var(--trail-gold);
  --meter-2: var(--trail-gold);
}

.cell--tier-3,
.record__tier--chorus,
.spotlight__group--chorus {
  --meter-1: var(--trail-gold);
  --meter-2: var(--trail-gold);
  --meter-3: var(--trail-gold);
}

.cell--tier-4,
.record__tier--smoker {
  --meter-1: var(--trail-gold);
  --meter-2: var(--trail-gold);
  --meter-3: var(--trail-gold);
  --meter-4: var(--trail-gold);
}

/* Pick Winner fills a race no signal backed: a Whisper by the numbers,
   with nothing lit. */
.cell--backup { --meter-1: var(--trail-meter-off); }

/* ── The silks ─────────────────────────────────────────────── */
/* Every signal rides in its own colours, as an owner's horses do: a
   jacket in the signal's pattern and colour, with its letter on a
   plate on the chest. They stand for the signal all over the page: in
   the legend, on the cards, in the drawer.

   The table runs weakest signal first. A chip or a drawer row belongs
   to one signal and matches one line. A card matches every signal
   behind its pick and the last match wins, so the silks beside the
   horse are the strongest signal's. Only those silks need the letter
   from here; a chip and a drawer row carry their own. */

.cell__chip--pick_winner,
.cell-drawer__source--pick_winner,
.cell[data-sources~="pick_winner"] {
  --silk: var(--trail-silk-plain);
  --silk-colour: var(--trail-plain);
  --silk-letter: "PW";
}

.cell__chip--letters,
.cell-drawer__source--letters,
.cell[data-sources~="letters"] {
  --silk: var(--trail-silk-stripes);
  --silk-colour: var(--c-ink);
  --silk-letter: "L";
}

.cell__chip--featured,
.cell-drawer__source--featured,
.cell[data-sources~="featured"] {
  --silk: var(--trail-silk-diamond);
  --silk-colour: var(--c-ink);
  --silk-letter: "F";
}

.cell__chip--htw,
.cell-drawer__source--htw,
.cell[data-sources~="htw"] {
  --silk: var(--trail-silk-spots);
  --silk-colour: var(--trail-claret);
  --silk-letter: "W";
}

.cell__chip--steamer,
.cell-drawer__source--steamer,
.cell[data-sources~="steamer"] {
  --silk: var(--trail-silk-chevrons);
  --silk-colour: var(--trail-purple);
  --silk-letter: "S";
}

.cell__chip--top_rated,
.cell-drawer__source--top_rated,
.cell[data-sources~="top_rated"] {
  --silk: var(--trail-silk-hoops);
  --silk-colour: var(--trail-royal);
  --silk-letter: "T";
}

.cell__chip--bod,
.cell-drawer__source--bod,
.cell[data-sources~="bod"] {
  --silk: var(--trail-silk-star);
  --silk-colour: var(--trail-gold);
  --silk-letter: "B";
}

/* A chip: the template's letter (B, T, W, S, L, F, PW), dressed. The
   letter is in the colour of the card it lies on. */
.cell__chip,
.cell-drawer__source-mark {
  --silk-size: 20px;
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--silk-size);
  height: var(--silk-size);
  padding-top: calc(var(--silk-size) * 0.24);   /* the chest is below the middle */
  color: var(--cell-face, var(--c-card));
  font-size: 7.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.02em;
}

/* The jacket */
.cell__chip::before,
.cell-drawer__source-mark::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
}

.cell__chip::before,
.cell-drawer__source-mark::before,
.cell__pick--primary::before {
  --mask: var(--silk, var(--trail-silk-plain));
  background: var(--silk-colour, var(--c-ink));
}

/* The plate under the letter. The pattern is cut out of the jacket, so
   the letter needs a ground of its own. */
.cell__chip::after,
.cell-drawer__source-mark::after {
  content: "";
  position: absolute;
  top: 62%;
  left: 50%;
  z-index: -1;
  width: 1.5em;
  height: 1.5em;
  border-radius: var(--r-pill);
  background: var(--silk-colour, var(--c-ink));
  translate: -50% -50%;
}

/* Pick Winner wears two letters: a longer plate. */
.cell__chip--pick_winner::after,
.cell-drawer__source--pick_winner .cell-drawer__source-mark::after { width: 2.15em; }

/* Not backing the pick: the jacket in outline, the letter in grey. */
.cell__chip.is-ghost,
.cell-drawer__source.is-off {
  --silk: var(--trail-silk-outline);
  --silk-colour: var(--trail-ink-32);
}

.cell__chip.is-ghost,
.cell-drawer__source.is-off .cell-drawer__source-mark { color: var(--trail-ink-50); }

.cell__chip.is-ghost::after,
.cell-drawer__source.is-off .cell-drawer__source-mark::after { content: none; }


/* ═══════════════════════════════════════════════════════════════
   Legend — the key to the board, and its filters
   ---------------------------------------------------------------
   Sly's flagship picks are gold medals; confidence is one scale of
   four steps, each the signal meter the cards carry; every signal
   is the silks it rides in. The rows are buttons (trail_filter.js).
   ═══════════════════════════════════════════════════════════════ */

/* ── The shell: a drawer below 1280px, a rail from there ───── */

.trail__nav {
  scrollbar-width: thin;
  scrollbar-color: var(--trail-ink-22) transparent;
  border-right: 1px solid var(--c-rule);
  background: var(--c-paper);
}

@media (max-width: 1279px) {
  /* Slides in from the left (trail_nav.js). It opens above the fixed
     site navigation, as the cell drawer does. */
  .trail__nav {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 400;
    width: min(320px, 88vw);
    padding: 22px 22px 24px;
    overflow-y: auto;
    overscroll-behavior: contain;
    visibility: hidden;
    transform: translateX(-100%);
    transition: transform 240ms ease;
  }

  .trail__nav.is-open {
    box-shadow: 4px 0 24px var(--trail-ink-22);
    visibility: visible;
    transform: translateX(0);
  }
}

@media (min-width: 1280px) {
  /* The whole key is in view on a laptop. On a shorter screen the rail
     scrolls by itself and a soft shadow at the edge says there is
     more: the two covers travel with the content and hide the shadow
     at whichever end has been reached. The scrollbar has a gutter of
     its own, so the key is the same width with or without it, and at
     the end of the rail the page carries on scrolling. A row reaches
     8px past its text when chosen or pointed at; the rail makes that
     room on the left rather than cutting the outline off. */
  .trail__nav {
    position: sticky;
    top: calc(var(--nav-h) + var(--banner-h) + 8px);
    max-height: calc(100vh - var(--nav-h) - var(--banner-h) - 20px);
    margin-left: -8px;
    padding: 20px 14px 20px 8px;
    overflow-y: auto;
    scrollbar-gutter: stable;
    background:
      linear-gradient(var(--c-paper) 35%, transparent) top / 100% 32px no-repeat local,
      linear-gradient(transparent, var(--c-paper) 65%) bottom / 100% 32px no-repeat local,
      radial-gradient(farthest-side at 50% 0, var(--trail-ink-16), transparent) top / 100% 9px no-repeat scroll,
      radial-gradient(farthest-side at 50% 100%, var(--trail-ink-16), transparent) bottom / 100% 9px no-repeat scroll;
  }
}

.trail__nav-backdrop {
  position: fixed;
  inset: 0;
  z-index: 390;
  background: var(--trail-ink-50);
  opacity: 0;
  visibility: hidden;
  transition: opacity 200ms ease, visibility 200ms;
}

.trail__nav-backdrop.is-open {
  opacity: 1;
  visibility: visible;
}

/* Stops the page scrolling behind the open drawer. */
body.trail-nav-lock { overflow: hidden; }

/* The chip that opens the drawer */
.trail__nav-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  margin: 9px 0 12px;
  padding: 8px 14px;
  border: 1px solid var(--c-rule-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
  color: var(--c-ink);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: border-color 140ms ease;
}

.trail__nav-trigger:hover,
.trail__nav-trigger:focus-visible { border-color: var(--c-ink); }

.trail__nav-trigger-icon {
  --mask: var(--trail-horseshoe);
  width: 16px;
  height: 16px;
  background: var(--trail-gold-ink);
}

/* The cross that closes it */
.trail__nav-close {
  margin-left: auto;
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--trail-ink-soft);
  font-size: 24px;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  transition: color 140ms ease;
}

.trail__nav-close:hover,
.trail__nav-close:focus-visible { color: var(--trail-gold-ink); }

/* A rail needs none of the drawer's controls. */
@media (min-width: 1280px) {
  .trail__nav-backdrop,
  .trail__nav-trigger,
  .trail__nav-close { display: none; }
}

/* ── The key itself ────────────────────────────────────────── */

.trail__legend {
  color: var(--c-ink-70);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
}

.trail__legend-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--c-rule);
  color: var(--c-ink);
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* A horseshoe heads the key. */
.trail__legend-head-icon {
  --mask: var(--trail-horseshoe);
  width: 20px;
  height: 20px;
  background: var(--trail-gold-ink);
}

.trail__legend-block + .trail__legend-block { margin-top: 15px; }

.trail__legend-title {
  margin-bottom: 8px;
  color: var(--trail-ink-soft);
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.trail__legend-sources {
  display: flex;
  flex-direction: column;
  gap: 6px;
  list-style: none;
}

/* A signal's row: its filter button, then a link to its own page. */
.trail__legend-sources li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.trail__legend-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  margin: -3px -8px;
  padding: 4px 8px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}

.trail__legend-row:hover,
.trail__legend-row:focus-visible {
  background: var(--trail-hover);
  color: var(--c-ink);
}

/* Chosen as the filter: the row becomes a card of its own. */
.trail__legend-row.is-active {
  background: var(--c-card);
  box-shadow: inset 0 0 0 2px var(--c-ink);
  color: var(--c-ink);
}

.trail__legend-source-label { font-weight: 600; }

/* A course: its name, and how many races it has today. */
.trail__legend-row--course { justify-content: space-between; }

.trail__legend-count {
  flex: 0 0 auto;
  min-width: 22px;
  padding: 3px 6px;
  border-radius: var(--r-pill);
  background: var(--trail-wash);
  color: var(--c-ink-70);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* "Sly's Bet · the day's single conviction bet": the name, and what it
   means on a line of its own. The dot between them stays in the text
   for anything that reads the page rather than looks at it. */
.trail__legend-sep { display: none; }

.trail__legend-hint {
  display: block;
  margin-top: 1px;
  color: var(--trail-ink-soft);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.3;
  text-wrap: balance;
}

.trail__legend-hint::first-letter { text-transform: uppercase; }

.trail__legend-goto {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  color: var(--trail-ink-soft);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  transition: background 140ms ease, color 140ms ease;
}

.trail__legend-goto:hover,
.trail__legend-goto:focus-visible {
  background: var(--trail-hover);
  color: var(--c-ink);
}

/* The silks, medals and meters lift when a row is pointed at. */
.trail__legend-row .cell__chip,
.trail__legend-row .trail__legend-star,
.trail__legend-row .trail__legend-pips { transition: transform 160ms ease; }

@media (hover: hover) {
  .trail__legend-row:hover .cell__chip,
  .trail__legend-row:hover .trail__legend-star,
  .trail__legend-row:hover .trail__legend-pips { transform: translateY(-3px); }
}

/* Silks at legend size */
.trail__legend-row .cell__chip {
  --silk-size: 28px;
  flex: 0 0 auto;
  font-size: 10px;
}

/* ── Sly's flagship picks: gold medals ─────────────────────── */

.trail__legend-star {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--trail-gold-pale), var(--trail-gold-fill) 72%);
  box-shadow: inset 0 0 0 1px var(--trail-gold-ring);
  color: var(--trail-gold-deep);
}

.trail__legend-star svg {
  width: 14px;
  height: 14px;
}

/* The template outlines its star; on the medal it is solid. */
.trail__legend-star svg path { stroke: none; }

/* ── Confidence: one scale of four steps ───────────────────── */

.trail__legend-tiers {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0 -8px;                     /* as wide as a chosen row */
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--c-card);
  box-shadow: inset 0 0 0 1px var(--c-rule-strong);
  list-style: none;
}

.trail__legend-tiers li {
  display: flex;
  min-width: 0;
}

.trail__legend-tiers li + li { border-left: 1px solid var(--c-rule); }

.trail__legend-tier {
  flex-direction: column;
  justify-content: flex-start;
  gap: 5px;
  flex: 1 1 auto;
  margin: 0;
  padding: 9px 0 8px;
  border-radius: 0;
  text-align: center;
}

.trail__legend-tier.is-active {
  --trail-meter-off: var(--trail-on-dark-24);
  background: var(--c-ink);
  box-shadow: none;
  color: var(--trail-on-dark);
}

/* The scale clips its corners, so the focus ring is drawn inside. */
.trail__legend-tier:focus-visible { outline-offset: -2px; }
.trail__legend-tier.is-active:focus-visible { outline-color: var(--trail-gold-fill); }

/* The meter, at legend size: as many bars lit as signals agree. The
   anatomy panel (see "Days without a full board") teaches the same
   meter, so it shares the drawing. */
.trail__legend-pips,
.anatomy__pips {
  display: inline-flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  flex: 0 0 auto;
  height: 18px;
}

.trail__legend-pips i,
.anatomy__pips i {
  width: 4px;
  height: 6px;
  border-radius: 1px;
  background: var(--trail-meter-off);
}

.trail__legend-pips i:nth-child(2),
.anatomy__pips i:nth-child(2) { height: 10px; }

.trail__legend-pips i:nth-child(3),
.anatomy__pips i:nth-child(3) { height: 14px; }

.trail__legend-pips i:nth-child(4),
.anatomy__pips i:nth-child(4) { height: 18px; }

.trail__legend-pips i.is-lit,
.anatomy__pips i.is-lit { background: var(--trail-gold); }

.trail__legend-tier.is-active .trail__legend-pips i.is-lit { background: var(--trail-gold-fill); }

.trail__legend-tier .trail__legend-source-label {
  display: block;
  min-width: 0;
  line-height: 1.2;
}

.trail__legend-tier .trail__legend-name {
  display: block;
  color: var(--c-ink);
  font-size: 10.5px;
  font-weight: 700;
}

/* "One source", "Two agree": two short lines under each step. */
.trail__legend-tier .trail__legend-hint {
  max-width: 40px;
  margin: 3px auto 0;
  font-size: 10px;
  line-height: 1.2;
}

.trail__legend-tier.is-active .trail__legend-name { color: var(--trail-on-dark); }
.trail__legend-tier.is-active .trail__legend-hint { color: var(--trail-on-dark-70); }

.trail__legend-note {
  margin-top: 15px;
  padding-top: 11px;
  border-top: 1px solid var(--c-rule);
  color: var(--trail-ink-soft);
  font-size: 11.5px;
  line-height: 1.5;
}


/* ═══════════════════════════════════════════════════════════════
   Masthead — the date, how fresh the board is, the day's tally
   ═══════════════════════════════════════════════════════════════ */

.trail__masthead {
  margin-bottom: 4px;
  padding: 24px 0 22px;
  border-bottom: 1px solid var(--c-rule);
}

/* The tally sits under the date until there is room for both on one
   line, which is from 1280px. */
.trail__masthead-inner {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.trail__masthead-lockup {
  display: flex;
  align-items: center;
  gap: 14px;
}

.trail__mark {
  display: inline-flex;
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  padding: 10px;
  border: 1px solid var(--c-rule);
  border-radius: var(--r-md);
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
  color: var(--c-ink);
}

.trail__mark svg {
  width: 100%;
  height: 100%;
}

.trail__masthead-title {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.trail__eyebrow {
  color: var(--trail-gold-ink);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.trail__date {
  color: var(--c-ink);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

/* ── Freshness pill (trail_live.js) ────────────────────────── */

.trail__freshness {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  margin-top: 6px;
  padding: 4px 10px 4px 8px;
  border: 1px solid var(--c-rule);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-ink-70);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  transition: color 200ms ease;
}

/* Red and beating while the feed is live; grey and still once it has
   gone stale or the day is final. */
.trail__freshness-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--c-red);
  animation: liveDotPulse 2s ease-in-out infinite;
}

.trail__freshness.is-stale,
.trail__freshness.is-final { color: var(--trail-ink-soft); }

.trail__freshness.is-stale .trail__freshness-dot,
.trail__freshness.is-final .trail__freshness-dot {
  background: var(--c-ink-40);
  animation: none;
}

/* A day that is not today says so where the live pill would be, with
   the way back: a reader sent to an old day by a search or a saved link
   should not take it for this afternoon's card. */
.trail__freshness--archive {
  border-color: var(--c-rule-strong);
  background: var(--trail-wash);
  color: var(--c-ink);
  font-weight: 700;
}

.trail__freshness--archive .trail__freshness-dot {
  border-radius: 2px;
  background: var(--c-ink-40);
  animation: none;
}

.trail__today-link {
  align-self: flex-start;
  margin-top: 6px;
  color: var(--trail-gold-ink);
  font-size: 12.5px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.trail__today-link:hover,
.trail__today-link:focus-visible { color: var(--c-ink); }

/* ── Other days (trail_day.js) ─────────────────────────────── */
/* Under the date: the race day before this one, a calendar to choose
   any day, and the race day after, up to today. Links and a small
   form; the script only tidies the form away behind the calendar. */

.trail__days {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
}

.trail__day {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  border: 1px solid var(--c-rule-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-ink);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}

.trail__day[hidden] { display: none; }
.trail__day:focus-visible { border-color: var(--c-ink); }

/* The date itself opens the calendar too, once the script is there. */
.trail__date.is-pickable { cursor: pointer; }

@media (hover: hover) {
  .trail__day:hover { border-color: var(--c-ink); }
}

.trail__day-arrow {
  font-size: 15px;
  line-height: 1;
}

/* The calendar: a page with a header band and two rows of days. */
.trail__day--pick {
  position: relative;
  width: 30px;
  padding: 0;
  justify-content: center;
}

.trail__day--pick::before {
  content: "";
  width: 14px;
  height: 13px;
  border: 1.5px solid currentColor;
  border-top-width: 4px;
  border-radius: 3px;
  background:
    radial-gradient(circle, currentColor 1px, transparent 1.4px) 0 0 / 4px 4px;
  background-origin: content-box;
  background-clip: content-box;
  padding: 1px;
}

.trail__day-form {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.trail__day-field {
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--c-rule-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-ink);
  font: inherit;
  font-size: 12px;
}

/* With the script: the calendar button stands for the form. The field
   stays in the page, out of sight, because the browser opens its date
   picker on the field and places it by it. */
.trail__day-form.is-enhanced { position: relative; }

.trail__day-form.is-enhanced .trail__day-field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

.trail__day-form.is-enhanced .trail__day--go { display: none; }

@media (pointer: coarse) {
  .trail__day { height: 36px; }
  .trail__day--pick { width: 36px; }
}

/* The beat of a live dot: here, and on a card whose race is running. */
@keyframes liveDotPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c-red) 40%, transparent); }
  50%      { box-shadow: 0 0 0 5px transparent; }
}

/* ── The tally ─────────────────────────────────────────────── */

.trail__counter {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  overflow: hidden;
  border: 1px solid var(--c-rule);
  border-radius: 14px;
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
}

.trail__stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  min-width: 0;
  padding: 10px 4px 9px;
  border-left: 1px solid var(--c-rule);
}

.trail__stat:first-child { border-left: 0; }

.trail__stat-num {
  color: var(--c-ink);
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.trail__stat-unit {
  margin-left: 1px;
  color: var(--trail-ink-soft);
  font-size: 0.6em;
  font-weight: 600;
}

.trail__stat--gold .trail__stat-num { color: var(--trail-gold-ink); }
.trail__stat-num--neg { color: var(--c-ink-70); }

.trail__stat-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--trail-ink-soft);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.07em;
  text-align: center;
  text-transform: uppercase;
}

/* Key dots: gold is a winner, red is running now. */
.trail__stat--gold .trail__stat-label::before,
.trail__stat--live .trail__stat-label::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--trail-gold-fill);
  box-shadow: inset 0 0 0 1px var(--trail-gold-ring);
}

.trail__stat--live .trail__stat-label::before {
  background: var(--c-red);
  box-shadow: none;
}

/* A count that has just changed (trail_live.js) */
[data-role="gold-count"].is-just-bumped,
[data-role="live-count"].is-just-bumped,
[data-role="pending-count"].is-just-bumped {
  display: inline-block;
  animation: numberBump 900ms ease-out;
}

@keyframes numberBump {
  30% {
    color: var(--trail-gold-ink);
    transform: scale(1.24);
  }
}

@media (min-width: 768px) {
  .trail__masthead-inner { gap: 18px; }
  .trail__date { font-size: 28px; }

  .trail__stat {
    align-items: flex-start;
    padding: 11px 18px 10px;
  }

  .trail__stat-num { font-size: 22px; }

  .trail__stat-label {
    font-size: 10.5px;
    text-align: left;
  }
}

@media (min-width: 1280px) {
  .trail__masthead-inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
  }

  .trail__stat { padding: 12px 20px 11px; }
  .trail__stat-num { font-size: 24px; }
}


/* ═══════════════════════════════════════════════════════════════
   Proposition — what the page is, and where the day has got to
   ═══════════════════════════════════════════════════════════════ */

.trail__proposition {
  max-width: 720px;
  margin: 30px auto 24px;
  padding: 0 6px;
  color: var(--c-ink-70);
  text-align: center;
}

.trail__proposition-line {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 10px;
  color: var(--c-ink);
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* The page's promise, "find the strongest signal", drawn: the meter
   with all four bars lit. */
.trail__proposition-line::before {
  --meter-bar: 4px;
  --meter-pitch: 6px;
  --meter-1: var(--trail-gold);
  --meter-2: var(--trail-gold);
  --meter-3: var(--trail-gold);
  --meter-4: var(--trail-gold);
}

.trail__proposition-body {
  max-width: 62ch;
  margin: 0 auto 12px;
  font-size: 15px;
  line-height: 1.6;
  text-wrap: pretty;
}

.trail__proposition-model {
  max-width: 68ch;
  margin: 6px auto 0;
  font-size: 13.5px;
  line-height: 2;
  text-wrap: pretty;
}

.trail__proposition-model strong { color: var(--c-ink); }

/* Each silk stays on the line with the name it stands for. */
.trail__proposition-pair { white-space: nowrap; }

.trail__proposition-pair .cell__chip {
  --silk-size: 18px;
  margin: -3px 3px 0 5px;
  vertical-align: middle;
}

/* ── The call to the next race (trail_course.js) ───────────── */
/* One line where it fits: "Next race: 14:00 Warwick · No More
   Teardrops". The paragraph measures itself to know. */

.trail__next {
  container: trail-next / inline-size;
  display: flex;
  justify-content: center;
  margin-top: 18px;
}

.trail__next-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
  padding: 7px 14px 7px 7px;
  border: 1px solid var(--c-rule-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
  color: var(--c-ink);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  text-align: left;
  text-decoration: none;
  transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}

.trail__next-link:hover,
.trail__next-link:focus-visible {
  border-color: var(--c-ink);
  box-shadow: 0 2px 4px var(--trail-ink-5), 0 18px 32px -16px var(--trail-ink-32);
  transform: translateY(-1px);
}

/* The fox marker's counter, as it stands on the board */
.trail__next-fox {
  position: relative;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--c-ink);
}

.trail__next-fox::after {
  --mask: var(--trail-fox);
  content: "";
  position: absolute;
  inset: 6px;
  background: var(--trail-gold-fill);
}

.trail__next-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.trail__next-text b { font-weight: 800; }

/* The horse, after a dot; nothing, when there is no horse to name. */
.trail__next-more::before { content: "· "; }
.trail__next-more:empty { display: none; }

.trail__next-arrow {
  flex: 0 0 auto;
  color: var(--trail-gold-ink);
  font-weight: 800;
  animation: nextNudge 1.8s ease-in-out infinite;
}

@keyframes nextNudge {
  0%, 100% { transform: translateY(-1px); }
  50%      { transform: translateY(3px); }
}

/* A phone: two lines, rather than lose the horse's name. */
@container trail-next (width < 444px) {
  .trail__next-link {
    padding-right: 16px;
    border-radius: 22px;
  }

  .trail__next-text {
    overflow: visible;
    white-space: normal;
  }

  .trail__next-more {
    display: block;
    margin-top: 2px;
    color: var(--c-ink-70);
    font-weight: 500;
  }

  .trail__next-more::before { content: none; }
  .trail__next-more::first-letter { text-transform: uppercase; }
}

@media (min-width: 768px) {
  .trail__proposition-line {
    flex-direction: row;
    gap: 12px;
    font-size: 27px;
  }
}


/* ═══════════════════════════════════════════════════════════════
   Track record — the tiers, as a receipt
   ---------------------------------------------------------------
   Two strips of three tiles: today so far (trail_live.js keeps it
   current) above the board, the last 30 days at the foot of the page.
   ═══════════════════════════════════════════════════════════════ */

.trail__record {
  container: trail-record / inline-size;
  max-width: 820px;
  margin: 10px auto 28px;
  scroll-margin-top: var(--trail-scroll-clear);
}

.trail__record--today { margin-bottom: 14px; }

.record__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  padding: 0 2px;
  color: var(--trail-ink-soft);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.record__eyebrow { color: var(--c-ink); }
.trail__record--today .record__window { color: var(--trail-gold-ink); }

.record__tiers {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  list-style: none;
}

.record__tier {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
  padding: 14px 16px 13px;
  border: 1px solid var(--c-rule);
  border-radius: var(--r-md);
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
}

/* The tier's name, after its meter */
.record__tier-name {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--c-ink);
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.record__tier-rate {
  color: var(--c-ink);
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

/* Too few results to quote a rate */
.record__tier-rate--thin {
  color: var(--c-ink-40);
  font-size: 24px;
  font-weight: 500;
}

.record__tier-unit {
  margin-left: 1px;
  color: var(--trail-ink-soft);
  font-size: 0.55em;
  font-weight: 600;
}

.record__tier-detail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  color: var(--trail-ink-soft);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

/* Profit and loss to level stakes: gold when ahead */
.record__tier-pl {
  padding: 2px 7px;
  border-radius: var(--r-sm);
  background: var(--trail-wash);
  color: var(--c-ink-70);
  font-weight: 700;
}

.record__tier-pl.is-up {
  background: var(--trail-gold-wash);
  color: var(--trail-gold-ink);
}

/* A tier's numbers have just changed (trail_live.js) */
.record__tier--just-updated { animation: recordTierPulse 1400ms ease-out; }

@keyframes recordTierPulse {
  20% { background: var(--trail-gold-wash); }
}

.record__caveat {
  margin-top: 12px;
  color: var(--trail-ink-soft);
  font-size: 12px;
  line-height: 1.4;
  text-align: center;
}

/* Three tiles across a phone: tighter tiles, the heading stacked. */
@container trail-record (width <= 496px) {
  .record__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  .record__tier { padding: 10px 10px 9px; }

  .record__tier-name {
    gap: 6px;
    font-size: 10px;
  }

  .record__tier-rate { font-size: 24px; }
  .record__tier-detail { gap: 5px; }
}


/* ═══════════════════════════════════════════════════════════════
   Course bar — getting about the race day (trail_course.js)
   ---------------------------------------------------------------
   It sits above the board and stays with the reader down it: back
   and forward one race, a map of the day (a tick a race), the race
   the reader is level with, a way back to the fox marker, the
   results side of the cards, and the page's other sections.

   One row at every width. What it shows follows its own width, not
   the window's, since the legend rail takes room beside it: the bar
   is a container and the steps below are measured on it.
   ═══════════════════════════════════════════════════════════════ */

.trail__course {
  container: trail-course / inline-size;
  position: sticky;
  top: calc(var(--nav-h) + var(--banner-h) + 8px);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 16px;
  padding: 7px 8px;
  border: 1px solid var(--c-rule-strong);
  border-radius: 14px;
  background: color-mix(in srgb, var(--c-card) 94%, transparent);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px -14px var(--trail-ink-32);
  color: var(--c-ink);
  font-size: 12.5px;
  line-height: 1;
}

@media (min-width: 768px) {
  .trail__course { padding: 8px 12px; }
}

/* ── Its buttons ───────────────────────────────────────────── */

.course__step,
.course__fox,
.trail__reveal-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  flex: 0 0 auto;
  min-width: 32px;
  height: 32px;
  border: 1px solid var(--c-rule-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  color: var(--c-ink);
  font: inherit;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease, color 140ms ease;
}

.course__step,
.course__fox,
.trail__reveal-chip { position: relative; }

/* Only where the pointer can hover: on a touch screen :hover latches
   after a tap, and the button would stay marked. */
@media (hover: hover) {
  .course__step:hover,
  .course__fox:hover,
  .trail__reveal-chip:hover { border-color: var(--c-ink); }
}

/* The step buttons are held back with aria-disabled, so one that runs
   out of races under the keyboard keeps the focus (trail_course.js). */
.course__step[aria-disabled="true"],
.trail__reveal-chip:disabled {
  border-color: var(--c-rule-strong);
  opacity: 0.38;
  cursor: default;
}

/* Under a finger the buttons keep their size and take a 44px target:
   the area round each one answers for it. */
@media (pointer: coarse) {
  .course__step::after,
  .course__fox::after,
  .trail__reveal-chip::after {
    content: "";
    position: absolute;
    inset: -6px;
  }
}

/* Back and forward one race */
.course__step { font-size: 15px; }

/* To the fox marker. Gone once the day is run: [hidden] has to be
   said again, because the display above outranks the browser's own. */
.course__fox {
  padding: 0 4px;
  border-color: var(--c-ink);
  background: var(--c-ink);
  color: var(--trail-on-dark);
}

.course__fox[hidden] { display: none; }

.course__fox-mark {
  --mask: var(--trail-fox);
  width: 14px;
  height: 14px;
  margin: 4px;
  background: var(--trail-gold-fill);
}

/* Reveal results (trail_flip.js): turns the settled cards over. It has
   nothing to turn until a race is settled. */
.trail__reveal-chip[aria-pressed="true"] {
  border-color: var(--c-ink);
  background: var(--c-ink);
  color: var(--trail-on-dark);
}

.trail__reveal-icon { font-size: 14px; }

/* Words on the two buttons, where there is room for them */
.course__label { display: none; }

/* ── The race the reader is level with ─────────────────────── */

/* It gives way first: when room is short it is cut short, and
   nothing drops to a second line. */
.course__readout {
  flex: 0 1 auto;
  min-width: 0;
  margin-right: auto;
  overflow: hidden;
  color: var(--c-ink-70);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.course__readout b {
  color: var(--c-ink);
  font-weight: 800;
}

/* "Race 3 of 44" is "3/44" until there is room for the words. */
.course__long { display: none; }

/* ── The map of the day: a tick a race ─────────────────────── */

.course__map {
  display: none;
  align-items: flex-end;
  gap: 2px;
  flex: 0 1 auto;                    /* a long day's ticks narrow to fit the bar */
  min-width: 0;
  height: 20px;
  padding: 0 2px;
  list-style: none;
}

/* Pale to come, dark run, gold won, red running; ringed where the fox
   marker stands, and tall where the reader is. */
.course__tick {
  flex: 0 1 auto;
  width: 5px;
  min-width: 2px;
  height: 11px;
  border-radius: 2px;
  background: var(--c-rule-strong);
  cursor: pointer;
  transition: height 140ms ease, background 140ms ease;
}

.course__tick.is-run  { background: var(--trail-ink-soft); }
.course__tick.is-won  { background: var(--trail-gold); }
.course__tick.is-second { background: var(--trail-silver-edge); }
.course__tick.is-third  { background: var(--trail-bronze-edge); }
.course__tick.is-live { background: var(--c-red); }

.course__tick.is-now {
  background: var(--c-ink);
  box-shadow: 0 0 0 2px var(--trail-gold-fill);
}

.course__tick.is-current { height: 20px; }

@media (hover: hover) {
  .course__tick:hover { height: 20px; }
}

/* ── The page's sections ───────────────────────────────────── */

.course__links {
  display: none;
  align-items: center;
  gap: 2px;
}

.course__link {
  padding: 8px 9px;
  border-radius: 8px;
  color: var(--trail-ink-soft);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-decoration: none;
  text-transform: uppercase;
}

.course__link:focus-visible {
  background: var(--trail-hover);
  color: var(--c-ink);
}

@media (hover: hover) {
  .course__link:hover {
    background: var(--trail-hover);
    color: var(--c-ink);
  }
}

/* ── What the bar has room for ─────────────────────────────── */

/* A phone: back, the race, forward; then the two buttons. */
@container trail-course (width < 678px) {
  .course__readout {
    flex-grow: 1;
    text-align: center;
  }

  .course__step--next { order: 1; }

  .course__fox,
  .trail__reveal-chip { order: 2; }
}

/* A tablet: the map, and the buttons set apart from the stepping. */
@container trail-course (width >= 678px) {
  .course__map { display: flex; }

  .course__fox,
  .trail__reveal-chip,
  .course__links { margin-left: 6px; }
}

@container trail-course (width >= 718px) {
  .course__long { display: inline; }
  .course__short { display: none; }
}

@container trail-course (width >= 810px) {
  .course__label { display: inline; }
  .course__fox { padding: 0 11px 0 5px; }
  .trail__reveal-chip { padding: 0 11px; }
}

@container trail-course (width >= 1030px) {
  .course__links { display: inline-flex; }
}

/* ── Filter status (trail_filter.js) ───────────────────────── */
/* The pill above the bar while a legend filter is on. [hidden] is said
   again for the same reason as on the fox button. */

.trail__filter-status {
  display: flex;
  align-items: center;
  gap: 12px;
  width: fit-content;
  margin-bottom: 12px;
  padding: 8px 14px;
  border: 1px solid var(--c-rule-strong);
  border-radius: var(--r-pill);
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
  color: var(--c-ink-70);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1;
}

.trail__filter-status[hidden] { display: none; }

.trail__filter-label strong { color: var(--c-ink); }

.trail__filter-clear {
  margin: -4px -6px -4px 0;
  padding: 4px 8px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--trail-ink-soft);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}

.trail__filter-clear:hover,
.trail__filter-clear:focus-visible {
  background: var(--trail-ink-8);
  color: var(--c-ink);
}


/* ═══════════════════════════════════════════════════════════════
   The course — a racecourse in a frame
   ---------------------------------------------------------------
   The day's races are cards laid along one track that snakes down
   the board: left to right, back, and on, at every width. The grid
   places the cards; trail_track.js draws the track underneath from
   where they land (the turf, the running rails, the start, the hoof
   prints, the winning post).
   ═══════════════════════════════════════════════════════════════ */

/* ── The frame ─────────────────────────────────────────────── */
/* Dark, with a black edge and a fine gold line let into it. It is the
   container the board measures itself on. */

.trail__frame {
  --frame-pad: 8px;
  --frame-line: 4px;                 /* how far in the gold line runs */
  --trail-track-band: 14px;          /* how far the track shows round a card (read by trail_track.js) */
  container: trail-board / inline-size;
  position: relative;
  isolation: isolate;
  padding: var(--frame-pad);
  border-radius: var(--r-lg);
  background: var(--c-ink);
  box-shadow:
    inset 0 0 0 1px var(--trail-black),
    inset 0 0 0 var(--frame-line) var(--c-ink),
    inset 0 0 0 calc(var(--frame-line) + 1px) color-mix(in srgb, var(--c-gold) 55%, transparent),
    0 22px 44px -28px var(--trail-ink-65);
  scroll-margin-top: var(--trail-scroll-clear);
}

/* ── The board ─────────────────────────────────────────────── */
/* A lawn, mown in bands. The gaps leave the track room to show: a
   band's width round every card, and a strip of lawn between rows. */

.trail__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-auto-flow: dense;             /* lets a row that runs back fill from the right */
  gap: 50px 10px;
  padding: 26px 22px 46px;
  border-radius: 11px;
  background: var(--trail-lawn) url("../img/lawn.1fa69eaa6d48.webp") 0 0 / 96px 96px;
}

@media (min-width: 768px) {
  .trail__frame {
    --frame-pad: 12px;
    --frame-line: 7px;
    --trail-track-band: 22px;
    border-radius: 22px;
  }

  .trail__grid {
    gap: 80px 14px;
    padding: 44px 42px 68px;
    border-radius: var(--r-md);
  }
}

@media (min-width: 1280px) {
  .trail__grid { column-gap: 16px; }
}

/* ── The snake ─────────────────────────────────────────────── */
/* The column count follows the board's own width, so a card is never
   much under 150px wide: one file on the smallest phones, then two,
   three, four, five and six abreast. From three abreast every other
   row runs back, right to left: its cards are placed by hand, last
   column first. Two abreast the rows all read left to right: with only
   two cards to a row, a row that runs back just puts the later race
   first.

   The cards are counted among themselves ("of .cell"), so anything
   else a template puts in the grid cannot shift a row.

   A long day (data-density="long" on the grid, which the template
   sets past 30 races) goes one more abreast from three up, with less
   lawn between the rows, so the board does not run to twice the
   length. */

@container trail-board (320px <= width < 520px) {
  .trail__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 34px;                   /* no bends to make room for */
  }
}

@container trail-board (520px <= width < 852px) {
  .trail__grid:not([data-density="long"]) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .trail__grid:not([data-density="long"]) .cell:nth-child(6n+4 of .cell) { grid-column: 3; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(6n+5 of .cell) { grid-column: 2; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(6n+6 of .cell) { grid-column: 1; }
}

@container trail-board (852px <= width < 1112px) {
  .trail__grid:not([data-density="long"]) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .trail__grid:not([data-density="long"]) .cell:nth-child(8n+5 of .cell) { grid-column: 4; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(8n+6 of .cell) { grid-column: 3; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(8n+7 of .cell) { grid-column: 2; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(8n+8 of .cell) { grid-column: 1; }
}

@container trail-board (1112px <= width < 1392px) {
  .trail__grid:not([data-density="long"]) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .trail__grid:not([data-density="long"]) .cell:nth-child(10n+6 of .cell) { grid-column: 5; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(10n+7 of .cell) { grid-column: 4; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(10n+8 of .cell) { grid-column: 3; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(10n+9 of .cell) { grid-column: 2; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(10n+10 of .cell) { grid-column: 1; }
}

@container trail-board (width >= 1392px) {
  .trail__grid:not([data-density="long"]) { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .trail__grid:not([data-density="long"]) .cell:nth-child(12n+7 of .cell) { grid-column: 6; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(12n+8 of .cell) { grid-column: 5; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(12n+9 of .cell) { grid-column: 4; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(12n+10 of .cell) { grid-column: 3; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(12n+11 of .cell) { grid-column: 2; }
  .trail__grid:not([data-density="long"]) .cell:nth-child(12n+12 of .cell) { grid-column: 1; }
}

/* A long day */

@container trail-board (width >= 520px) {
  .trail__grid[data-density="long"] { row-gap: 60px; }
}

@container trail-board (520px <= width < 700px) {
  .trail__grid[data-density="long"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .trail__grid[data-density="long"] .cell:nth-child(6n+4 of .cell) { grid-column: 3; }
  .trail__grid[data-density="long"] .cell:nth-child(6n+5 of .cell) { grid-column: 2; }
  .trail__grid[data-density="long"] .cell:nth-child(6n+6 of .cell) { grid-column: 1; }
}

@container trail-board (700px <= width < 880px) {
  .trail__grid[data-density="long"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .trail__grid[data-density="long"] .cell:nth-child(8n+5 of .cell) { grid-column: 4; }
  .trail__grid[data-density="long"] .cell:nth-child(8n+6 of .cell) { grid-column: 3; }
  .trail__grid[data-density="long"] .cell:nth-child(8n+7 of .cell) { grid-column: 2; }
  .trail__grid[data-density="long"] .cell:nth-child(8n+8 of .cell) { grid-column: 1; }
}

@container trail-board (880px <= width < 1080px) {
  .trail__grid[data-density="long"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .trail__grid[data-density="long"] .cell:nth-child(10n+6 of .cell) { grid-column: 5; }
  .trail__grid[data-density="long"] .cell:nth-child(10n+7 of .cell) { grid-column: 4; }
  .trail__grid[data-density="long"] .cell:nth-child(10n+8 of .cell) { grid-column: 3; }
  .trail__grid[data-density="long"] .cell:nth-child(10n+9 of .cell) { grid-column: 2; }
  .trail__grid[data-density="long"] .cell:nth-child(10n+10 of .cell) { grid-column: 1; }
}

@container trail-board (width >= 1080px) {
  .trail__grid[data-density="long"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .trail__grid[data-density="long"] .cell:nth-child(12n+7 of .cell) { grid-column: 6; }
  .trail__grid[data-density="long"] .cell:nth-child(12n+8 of .cell) { grid-column: 5; }
  .trail__grid[data-density="long"] .cell:nth-child(12n+9 of .cell) { grid-column: 4; }
  .trail__grid[data-density="long"] .cell:nth-child(12n+10 of .cell) { grid-column: 3; }
  .trail__grid[data-density="long"] .cell:nth-child(12n+11 of .cell) { grid-column: 2; }
  .trail__grid[data-density="long"] .cell:nth-child(12n+12 of .cell) { grid-column: 1; }
}

/* ── The track (trail_track.js) ────────────────────────────── */
/* A layer over the board's own box, under the cards. The markup holds
   its parts; the script gives them their geometry and switches the
   layer on once it has. Until then, or without the script, the cards
   stand on the lawn. */

.trail__track {
  position: absolute;
  inset: var(--frame-pad);
  visibility: hidden;
  pointer-events: none;
}

.trail__track.is-drawn { visibility: visible; }

/* The running rail. Three copies of the course's outline, each drawn
   over the last: a dark line, the posts, the white rail. The turf then
   covers all of it but what lies outside the outline. The posts are a
   dashed stroke wider than the rail, so only a short tick shows beyond
   it. */
.track__rails {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.track__edge {
  fill: var(--trail-turf-edge);
  stroke: var(--trail-turf-edge);
  stroke-width: 6px;
}

.track__posts {
  fill: none;
  stroke: var(--trail-on-dark);
  stroke-width: 9px;
  stroke-dasharray: 2 24;
}

.track__rail {
  fill: var(--trail-on-dark);
  stroke: var(--trail-on-dark);
  stroke-width: 4px;
}

/* The turf: a tile of close-mown grass, cut to the course's outline. */
.track__turf {
  position: absolute;
  inset: 0;
  background: var(--trail-turf) url("../img/turf.15f3c3c5a465.webp") 0 0 / 96px 96px;
}

/* The way round, along the running line: an arrow in the gap after
   each race and a larger one round each bend, turned by the script to
   point at the next race (--turn). Gold where the fox marker has been,
   pale ahead of it. They come up after the course does. (The class is
   still "hoof": these were hoof prints, which showed the line but not
   which way it ran.) */
.track__hoofs {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 900ms ease 250ms;
}

.trail__track.is-drawn .track__hoofs { opacity: 1; }

.track__hoof {
  --arrow: 15px;
  position: absolute;
  width: var(--arrow);
  height: var(--arrow);
  background: var(--trail-arrow);
  clip-path: polygon(14% 0, 52% 0, 100% 50%, 52% 100%, 14% 100%, 62% 50%);
  translate: -50% -50%;
  rotate: var(--turn, 0deg);
  filter: drop-shadow(0 1px 0 var(--trail-ink-32));
}

.track__hoof--bend { --arrow: 20px; }

.track__hoof.is-run { background: var(--trail-gold-fill); }

/* The start: a white line across the track before the first race... */
.track__start-line {
  position: absolute;
  width: 5px;
  background: var(--trail-on-dark);
  box-shadow: 0 0 0 1px var(--trail-ink-13);
  translate: -50% 0;
}

/* ...and a sign hung on the rail over that race, with a flag: the word,
   and the race the day starts with. The script puts it at the card's
   top left corner; it lifts itself clear. It is the first thing to find
   on the board, so it is as large as the lawn above the card allows. */
.track__start {
  position: absolute;
  z-index: 2;                        /* over the rail it hangs on */
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 24px;
  padding: 0 11px 0 10px;
  border: 2px solid var(--trail-gold-fill);
  border-radius: 6px;
  background: var(--c-ink);
  box-shadow: 0 4px 10px -4px var(--trail-ink-65);
  color: var(--trail-gold-fill);
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  translate: -4px calc(-100% + 3px);
}

.track__start::before {
  content: "";
  width: 12px;
  height: 14px;
  background: var(--trail-gold-fill);
  clip-path: polygon(0 100%, 0 0, 16% 0, 16% 10%, 100% 36%, 16% 62%, 16% 100%);
}

/* The first race, after the word. */
.track__start-race {
  padding-left: 8px;
  border-left: 1px solid color-mix(in srgb, var(--trail-gold-fill) 45%, transparent);
  color: var(--trail-on-dark);
  font-size: 0.84em;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.track__start-race:empty { display: none; }

/* The winning post, after the last race: a chequered line across the
   track. The script makes it a whole number of squares long. */
.track__post {
  --post-square: 3px;
  position: absolute;
  width: calc(2 * var(--post-square));
  background:
    repeating-conic-gradient(var(--trail-on-dark) 0 25%, var(--c-ink) 0 50%)
    0 0 / 100% calc(2 * var(--post-square));
  translate: -50% 0;
}

/* Its name, on the lawn under the end of the track. The script puts it
   at the track's corner and says which side the track ends on. */
.track__post-label {
  position: absolute;
  margin-top: 6px;
  color: var(--c-ink);
  font-size: 8.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  translate: 2px 0;
}

.track__post-label--end { translate: calc(-100% - 2px) 0; }

@media (min-width: 768px) {
  .track__posts {
    stroke-width: 11px;
    stroke-dasharray: 2.5 29.5;
  }

  .track__hoof { --arrow: 18px; }
  .track__hoof--bend { --arrow: 26px; }

  .track__start-line { width: 6px; }

  .track__start {
    gap: 9px;
    height: 38px;
    padding: 0 16px 0 13px;
    border-radius: 8px;
    font-size: 16px;
    letter-spacing: 0.2em;
    translate: -4px calc(-100% + 4px);
  }

  .track__start::before {
    width: 16px;
    height: 20px;
  }

  .track__post { --post-square: 7px; }

  .track__post-label {
    margin-top: 8px;
    font-size: 10px;
    letter-spacing: 0.16em;
  }
}


/* ═══════════════════════════════════════════════════════════════
   Race cards
   ---------------------------------------------------------------
   One card per race, laid on the track. Along the top: the race
   number on a saddle cloth, the time, and a status slot that shows
   the confidence before the off and the result after it. Then the
   course, the pick beside the silks of the strongest signal behind
   it, and along the foot the silks of every signal, filled in when
   they back the pick.

   A card is a container: what it has room for follows its own width
   (see "What a card has room for"), not the window's.

   Its colours are named once, on the card: the face, the edge, three
   strengths of ink, the gold, a rule and a tag. The parts on both
   sides read those names, so a kind of card or a state of its race
   re-points a few of them instead of restyling each part.

   The rules run from the general to the particular, and where two
   could apply the later one is meant to win: the card, its parts,
   the kind of card, the state of its race, the Smoker, then the
   banners.
   ═══════════════════════════════════════════════════════════════ */

.cell {
  --cell-pad: 11px;
  --cell-strip: 0px;                 /* a banner's height, on a card that carries one */
  --cell-face: var(--c-card);
  --cell-edge: var(--trail-ink-16);
  --cell-ink: var(--c-ink);
  --cell-ink-2: var(--c-ink-70);
  --cell-ink-3: var(--trail-ink-soft);
  --cell-gold: var(--trail-gold-ink);
  --cell-rule: var(--trail-rule-soft);
  --cell-tag: var(--trail-wash);     /* a price tag or a quiet plaque... */
  --cell-tag-ink: var(--c-ink-70);   /* ...and what is written on it */
  --cell-ring: 0 1px 0 var(--trail-ink-5);
  --cell-drop: 0 8px 16px -10px var(--trail-ink-42);
  container: trail-cell / inline-size;
  position: relative;
  z-index: 1;                        /* over the track */
  display: flex;
  flex-direction: column;
  min-height: 148px;
  padding: calc(var(--cell-pad) + var(--cell-strip)) var(--cell-pad) var(--cell-pad);
  border: 1px solid var(--cell-edge);
  border-radius: var(--r-md);
  background: var(--cell-face);
  box-shadow: var(--cell-ring), var(--cell-drop);
  cursor: pointer;                   /* opens the drawer (trail_drawer.js) */
  perspective: 1000px;               /* for the turn to the results side */
  scroll-margin-top: var(--trail-scroll-clear);
  transition:
    transform 160ms ease,
    box-shadow 160ms ease,
    translate 460ms cubic-bezier(0.2, 0.7, 0.2, 1),
    opacity 300ms ease;
}

@media (min-width: 768px) {
  .cell {
    --cell-pad: 14px;
    min-height: 158px;
  }
}

/* Pointing at a card picks it up; pressing puts it down. Only where
   the pointer can hover: on a touch screen :hover latches after a tap,
   and the card would stay up once its drawer was closed. */
@media (hover: hover) {
  .cell:hover {
    --cell-drop: 0 18px 26px -14px var(--trail-ink-50);
    transform: translateY(-3px);
  }
}

.cell:active { transform: none; }
.cell:focus-visible { outline-offset: 3px; }

/* ── The two sides (trail_flip.js) ─────────────────────────── */
/* Both faces share one grid cell, so the card keeps its height when it
   turns. The status slot's live mark is placed against this box. */

.cell__flip {
  position: relative;
  display: grid;
  grid-template: 1fr / minmax(0, 1fr);
  flex: 1 1 auto;
  min-width: 0;
  transform-style: preserve-3d;
  transition: transform 640ms cubic-bezier(0.35, 0.05, 0.25, 1);
}

.cell.is-flipped .cell__flip { transform: rotateY(180deg); }

.cell__face {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}

.cell__face--back { transform: rotateY(180deg); }

/* ── Head: saddle cloth, time, status slot, course ─────────── */

.cell__badge {
  position: absolute;
  top: calc(var(--cell-pad) + var(--cell-strip));
  left: var(--cell-pad);
  z-index: 2;
  min-width: 22px;
  height: 22px;
  padding: 0 4px;
  border-radius: 5px;
  background: var(--c-ink);
  color: var(--trail-on-dark);
  font-size: 11.5px;
  font-weight: 800;
  line-height: 22px;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

/* The time stands after the cloth; the course has a line to itself, so
   its name is not cut to fit beside the time. */
.cell__head {
  display: grid;
  grid-template: "time status" "course course" / minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 8px;
}

.cell__time {
  grid-area: time;
  margin-left: 30px;
  color: var(--cell-ink);
  font-size: 14px;
  font-weight: 700;
  line-height: 22px;
  white-space: nowrap;
}

.cell__course {
  grid-area: course;
  min-width: 0;
  overflow: hidden;
  color: var(--cell-ink-3);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.07em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The status slot before the off: the signal meter, and the confidence
   it stands for in a word, since four bars are hard to tell from three
   at a glance. Nod and above print their name in a strip along the
   foot of the card; a Whisper has no strip, so the word is given here. */
.cell--tier-1 { --cell-tier: "Whisper"; }
.cell--tier-2 { --cell-tier: "Nod"; }
.cell--tier-3 { --cell-tier: "Chorus"; }
.cell--tier-4 { --cell-tier: "Smoker"; }

.cell__head::after {
  content: var(--cell-tier, "");
  grid-area: status;
  display: inline-flex;
  align-items: center;
  justify-self: end;
  width: auto;
  min-width: 18px;
  padding-left: 23px;                /* past the meter */
  color: var(--cell-gold);
  font-size: 9.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The crown that marked Nod and above: the meter says it now. */
.cell__mark { display: none; }

/* Run, and the result declared: a chequered flag after the time, on
   every such card whatever became of the pick. Won, placed or beaten
   is the plaque's to say; this says only that the race is over, the
   one thing to tell apart from the races still to come. */
.cell--won .cell__time::after,
.cell--placed .cell__time::after,
.cell--lost .cell__time::after,
.cell--void .cell__time::after,
.cell--won .cell__course::before,
.cell--placed .cell__course::before,
.cell--lost .cell__course::before,
.cell--void .cell__course::before {
  --flag-square: 4px;
  content: "";
  display: inline-block;
  width: calc(4 * var(--flag-square) + 3px);
  height: calc(3 * var(--flag-square) + 5px);
  margin-left: 7px;
  vertical-align: -4px;
  /* a pole down the left, and three rows of four squares flying from
     it: black and white on any card, edged in the card's own ink */
  background:
    linear-gradient(var(--cell-ink) 0 0) 0 0 / 2px 100% no-repeat,
    repeating-conic-gradient(var(--c-ink) 0 25%, var(--trail-on-dark) 0 50%)
      3px 0 / calc(2 * var(--flag-square)) calc(2 * var(--flag-square));
  clip-path: polygon(0 0, 100% 0, 100% calc(3 * var(--flag-square)), 3px calc(3 * var(--flag-square)), 3px 100%, 0 100%);
  outline: 1px solid var(--cell-ink);
  outline-offset: -1px;
}

/* Beside the time on a card with room; on a narrow one (below) it
   stands before the course instead, clear of the result's plaque. */
.cell--won .cell__course::before,
.cell--placed .cell__course::before,
.cell--lost .cell__course::before,
.cell--void .cell__course::before { display: none; }

/* ── Body: the pick, beside its silks ──────────────────────── */

.cell__body {
  --pick-silk: 34px;                 /* the silks beside the horse */
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 0 auto;
  padding: 13px 0 14px;
}

.cell__pick {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.cell__pick--primary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 6px 9px;
}

/* The jacket, down the left of the name and the price... */
.cell__pick--primary::before {
  content: "";
  grid-area: 1 / 1 / span 2;
  width: var(--pick-silk);
  height: var(--pick-silk);
  margin-top: -3px;
  transition: transform 160ms ease;
}

/* ...and the signal's letter on its chest, laid over it. (A masked
   box paints above its unpositioned neighbours, hence the z-index.) */
.cell__pick--primary::after {
  content: var(--silk-letter);
  z-index: 1;
  grid-area: 1 / 1 / span 2;
  justify-self: center;
  min-width: 1.5em;
  height: 1.5em;
  margin-top: calc(var(--pick-silk) * 0.62 - 3px - 0.75em);
  padding: 0 0.25em;
  border-radius: var(--r-pill);
  background: var(--silk-colour, var(--c-ink));
  color: var(--cell-face);
  font-size: 12px;
  font-weight: 800;
  line-height: 1.5;
  letter-spacing: 0.02em;
  text-align: center;
  white-space: nowrap;
  transition: translate 160ms ease;
}

@media (hover: hover) {
  .cell:hover .cell__pick--primary::before { transform: translateY(-2px) rotate(-4deg); }
  .cell:hover .cell__pick--primary::after { translate: 0 -2px; }
}

/* The horse's own silks, where the race card has them, in place of the
   signal's jacket: the owner's colours are how a horse is known on the
   course. An image from the racing data (.cell__silk), or the two
   colours it gives, drawn on the plain jacket (.cell__silk--drawn). The
   signals behind the pick keep their jackets along the foot. */
.cell__silk {
  grid-area: 1 / 1 / span 2;
  width: var(--pick-silk);
  height: var(--pick-silk);
  margin-top: -3px;
  object-fit: contain;
  transition: transform 160ms ease;
}

.cell__silk--drawn {
  -webkit-mask: var(--trail-silk-plain) center / contain no-repeat;
          mask: var(--trail-silk-plain) center / contain no-repeat;
  /* body in the first colour, sleeves in the second */
  background: linear-gradient(90deg,
    var(--silk-2, var(--trail-on-dark)) 0 24%,
    var(--silk-1, var(--trail-royal)) 24% 76%,
    var(--silk-2, var(--trail-on-dark)) 76%);
  /* an edge, so white sleeves still show on a white card */
  filter: drop-shadow(0 0 0.6px var(--trail-ink-65)) drop-shadow(0 0 0.6px var(--trail-ink-65));
}

.cell__pick--primary:has(> .cell__silk)::before,
.cell__pick--primary:has(> .cell__silk)::after { content: none; }

@media (hover: hover) {
  .cell:hover .cell__silk { transform: translateY(-2px) rotate(-4deg); }
}

/* Two lines at most. A name that is one long word steps down in size
   until it fits (trail_cards.js sets --cell-horse-size); only below
   that script's floor does it break inside the word. */
.cell__horse {
  display: -webkit-box;
  overflow: hidden;
  color: var(--cell-ink);
  font-size: var(--cell-horse-size, 17px);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
  text-wrap: balance;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.cell__odds {
  align-self: flex-start;
  justify-self: start;
  padding: 3px 7px;
  border-radius: var(--r-sm);
  background: var(--cell-tag);
  color: var(--cell-tag-ink);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

/* A split: the signals are two against two, the second pick underneath,
   in line with the first one's name. */
.cell__split-rule {
  height: 1px;
  margin: 2px 0;
  background: var(--cell-rule);
}

.cell--split .cell__pick--alt { padding-left: calc(var(--pick-silk) + 9px); }

.cell--split .cell__pick--alt .cell__horse {
  color: var(--cell-ink-2);
  font-size: var(--cell-horse-size, 13.5px);
  font-weight: 600;
}

.cell--split .cell__pick--alt .cell__odds { font-size: 10px; }

/* ── Foot: every signal's silks, always in the same order ──── */

.cell__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  min-height: 29px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--cell-rule);
}

.cell__chips {
  display: inline-flex;
  gap: 3px;
}

/* A Pick Winner card wears a tag where the silks would be. */
.cell__backup-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 8px 4px 6px;
  border-radius: var(--r-sm);
  box-shadow: inset 0 0 0 1px var(--c-rule-strong);
  color: var(--trail-ink-soft);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.cell__backup-tag::before {
  --mask: var(--trail-silk-plain);
  content: "";
  width: 12px;
  height: 12px;
  background: var(--trail-plain);
}

/* The foot's old state glyphs. The poller still writes them, so they
   are styled here rather than removed: the result is the plaque in the
   status slot, and the two that have no plaque of their own, running
   and void, go up there to be one. */
.cell__state { display: contents; }

.cell__crown,
.cell__finish,
.cell__glyph--placed,
.cell__glyph--pending { display: none; }

.cell__glyph--live,
.cell__glyph--void {
  position: absolute;
  top: 1px;
  right: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--r-sm);
  font-size: 0;                      /* the void glyph's own "V" makes way for the word */
  line-height: 1;
}

.cell__glyph--live { background: var(--c-ink); }
.cell__glyph--void { background: var(--cell-tag); }

.cell__glyph--live::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-red-lt);
  animation: liveDotPulse 1.6s ease-in-out infinite;
}

.cell__glyph--live::after,
.cell__glyph--void::after {
  content: "Live";
  color: var(--trail-on-dark);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.cell__glyph--void::after {
  content: "Void";
  color: var(--cell-ink-3);
}

/* ── The result, in the status slot ────────────────────────── */

.cell__medal {
  position: absolute;
  top: calc(var(--cell-pad) + var(--cell-strip) + 1px);
  right: var(--cell-pad);
  z-index: 3;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--r-sm);
  font-size: 10.5px;
  font-weight: 800;
  line-height: 20px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Placed: outlined. Beaten: quiet. */
.cell__medal--silver,
.cell__medal--bronze {
  background: var(--cell-face);
  box-shadow: inset 0 0 0 1.5px var(--cell-ink);
  color: var(--cell-ink);
}

.cell__medal--lost {
  background: var(--cell-tag);
  color: var(--cell-ink-3);
}

/* A winner gets a rosette, pinned to the card's corner. The disc and
   the ribbon tails are drawn behind the word: the word stays on top,
   and the tails stay under the disc. They are sized in percentages, so
   the smaller rosette on a narrow card is the same drawing. */
.cell__medal--gold {
  top: -15px;
  right: 3px;
  z-index: 7;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--trail-gold-deep);
  font-size: 9.5px;
  line-height: 1;
  letter-spacing: 0.05em;
}

.cell__medal--gold::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 50%;
  background:
    radial-gradient(closest-side, var(--trail-gold-pale) 0 59%, var(--trail-gold) 61.4% 68.2%, transparent 70.5%),
    repeating-conic-gradient(var(--trail-rosette) 0 9deg, var(--trail-gold-fill) 9deg 18deg);
  box-shadow: 0 3px 8px -3px var(--trail-ink-50);
}

.cell__medal--gold::before {
  content: "";
  position: absolute;
  inset: 61.4% 13.6% auto;
  z-index: -2;
  height: 61.4%;
  background: var(--trail-rosette);
  clip-path: polygon(16.7% 0, 83.3% 0, 96.7% 91.7%, 80% 79.2%, 66.7% 100%, 50% 25%, 33.3% 100%, 20% 79.2%, 3.3% 91.7%);
}

/* The results side says it in full: the plaque steps aside. */
.cell.is-flipped .cell__medal {
  opacity: 0;
  transition: opacity 200ms ease;
}

/* Once a race is run, or running, the slot gives the meter up. */
.cell--live .cell__head::after,
.cell--won .cell__head::after,
.cell--placed .cell__head::after,
.cell--lost .cell__head::after,
.cell--void .cell__head::after { visibility: hidden; }

/* ── Nod, Chorus, Smoker: a strip along the foot ───────────── */
/* It carries the tier's name and meter, so the confidence still shows
   once the result has taken the status slot. */

.cell__tier-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 12px calc(-1 * var(--cell-pad)) calc(-1 * var(--cell-pad));
  padding: 8px var(--cell-pad);
  border-top: 1px solid var(--trail-gold-rule);
  border-radius: 0 0 11px 11px;
  background: var(--trail-gold-wash);
  color: var(--trail-gold-ink);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.cell__tier-label--chorus { background: var(--c-gold-wash); }

.cell__tier-name {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.cell__tier-name::before {
  --meter-bar: 2px;
  --meter-pitch: 3.6px;
}

.cell__tier-count {
  color: var(--trail-ink-soft);
  font-size: 0.9em;
  font-weight: 700;
  letter-spacing: 0.06em;
}

/* ── Kinds of card ─────────────────────────────────────────── */

/* Chorus, three signals: a gold edge. */
.cell--tier-3 {
  --cell-edge: var(--trail-gold);
  --cell-ring: 0 0 0 1px var(--trail-gold);
}

/* Pick Winner fills a race no signal backed: a dashed card in plain
   silks, lying flat, with no confidence to name. */
.cell--backup {
  --cell-face: var(--c-card-warm);
  --cell-edge: var(--trail-plain-edge);
  --cell-ring: 0 0 0 0 transparent;
  --cell-drop: 0 0 0 0 transparent;
  --cell-tier: "";
  border-style: dashed;
}

@media (hover: hover) {
  .cell--backup:not(.cell--won):hover { --cell-face: var(--c-card); }
}

/* On its warm card the cloth is a white plate, outlined; so is the
   plaque of one that was placed. */
.cell--backup .cell__badge {
  background: var(--c-card);
  box-shadow: inset 0 0 0 1.5px var(--trail-plain);
  color: var(--c-ink-70);
}

.cell--backup .cell__medal--silver,
.cell--backup .cell__medal--bronze { background: var(--c-card); }

.cell--backup .cell__horse {
  color: var(--cell-ink-2);
  font-weight: 600;
}

.cell--backup .cell__odds { color: var(--cell-ink-3); }

/* No fancy: no signal, and no Pick Winner either. An empty seat. */
.cell--no_fancy {
  --cell-face: color-mix(in srgb, var(--c-card) 60%, transparent);
  --cell-ring: 0 0 0 0 transparent;
  --cell-drop: 0 0 0 0 transparent;
  border-style: dashed;
}

.cell__body--ghost { align-items: center; }

.cell__ghost-label {
  color: var(--cell-ink-3);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Neither has a word for the slot: the meter alone, unlit. */
.cell--backup .cell__head::after,
.cell--no_fancy .cell__head::after { padding-left: 0; }

/* A seat that only padded out a short row (.cell--ghost) is not a card
   at all: the track ends at the last race instead. */
.cell--ghost { display: none; }

/* ── The state of the race ─────────────────────────────────── */

/* Running: ringed in ink. */
.cell--live {
  --cell-edge: var(--c-ink);
  --cell-ring: 0 0 0 2px var(--c-ink);
}

/* Beaten: a quieter card, still readable. Its colours fade, and it
   lies lower (a Pick Winner card lies flat already). */
.cell--lost,
.cell--void { --cell-face: var(--c-paper); }

.cell--lost:where(:not(.cell--backup)) {
  --cell-ring: 0 1px 0 var(--trail-ink-5);
  --cell-drop: 0 5px 10px -8px var(--trail-ink-32);
}

.cell--lost .cell__horse {
  color: var(--cell-ink-3);
  font-weight: 600;
}

.cell--void .cell__horse,
.cell--lost .cell__odds { color: var(--cell-ink-3); }

.cell--lost .cell__badge,
.cell--void .cell__badge { background: var(--c-ink-40); }

.cell--lost .cell__pick--primary::before,
.cell--void .cell__pick--primary::before { opacity: 0.38; }

.cell--lost .cell__chip:not(.is-ghost) { --silk-colour: color-mix(in srgb, var(--c-ink) 50%, var(--c-card)); }

.cell--backup.cell--lost .cell__badge {
  background: var(--c-card);
  color: var(--trail-ink-soft);
}

/* Won: the gold card, with the winner's cloth. A Pick Winner that wins
   is a winner like any other, so this undoes the dashes. */
.cell--won {
  --cell-face: var(--trail-win-face);
  --cell-edge: var(--trail-win-edge);
  --cell-rule: var(--trail-gold-rule);
  --cell-tag: var(--c-gold-wash);
  --cell-tag-ink: var(--trail-gold-ink-dark);
  --cell-ring: 0 0 0 1px var(--trail-win-edge);
  --cell-drop: 0 8px 18px -10px color-mix(in srgb, var(--trail-gold-ink) 55%, transparent);
  border-style: solid;
}

.cell--won .cell__badge {
  background: var(--trail-gold-fill);
  box-shadow: none;
  color: var(--trail-gold-deep);
}

.cell--won .cell__horse {
  color: var(--cell-ink);
  font-weight: 800;
}

/* Placed: the silver card for second, the bronze for third, made the
   way the gold one is: the face, the edge, the cloth and the plaque.
   (A place the result gives no number for keeps the plain card.) */
.cell--placed-2 {
  --place-face: var(--trail-silver-face);
  --place-edge: var(--trail-silver-edge);
  --place-fill: var(--trail-silver-fill);
  --place-deep: var(--trail-silver-deep);
}

.cell--placed-3 {
  --place-face: var(--trail-bronze-face);
  --place-edge: var(--trail-bronze-edge);
  --place-fill: var(--trail-bronze-fill);
  --place-deep: var(--trail-bronze-deep);
}

.cell--placed-2,
.cell--placed-3 {
  --cell-face: var(--place-face);
  --cell-edge: var(--place-edge);
  --cell-rule: color-mix(in srgb, var(--place-edge) 38%, transparent);
  --cell-tag: color-mix(in srgb, var(--place-fill) 45%, var(--place-face));
  --cell-tag-ink: var(--place-deep);
  --cell-ring: 0 0 0 1px var(--place-edge);
  --cell-drop: 0 8px 18px -10px color-mix(in srgb, var(--place-edge) 70%, transparent);
  border-style: solid;
}

.cell--placed-2 .cell__badge,
.cell--placed-3 .cell__badge,
.cell--placed-2 .cell__medal,
.cell--placed-3 .cell__medal {
  background: var(--place-fill);
  box-shadow: inset 0 0 0 1.5px var(--place-edge);
  color: var(--place-deep);
}

.cell--placed-2 .cell__horse,
.cell--placed-3 .cell__horse { font-weight: 800; }

/* A Pick Winner card that is running, or next: a card like the rest. */
.cell--backup.cell--live,
.cell--backup.cell--now {
  --cell-face: var(--c-card);
  border-style: solid;
}

/* ── The Smoker: every signal agrees ───────────────────────── */
/* The one black card on the board, whatever the state of its race:
   white on ink, and its gold the bright one. */

.cell--tier-4 {
  --cell-face: var(--c-ink);
  --cell-edge: var(--trail-black);
  --cell-ink: var(--trail-on-dark);
  --cell-ink-2: var(--trail-on-dark);
  --cell-ink-3: var(--trail-on-dark-70);
  --cell-gold: var(--trail-gold-fill);
  --cell-rule: var(--trail-on-dark-14);
  --cell-tag: var(--trail-on-dark-14);
  --cell-tag-ink: var(--trail-on-dark);
  --trail-meter-off: var(--trail-on-dark-24);
}

.cell--won.cell--tier-4 { --cell-edge: var(--trail-gold-fill); }

/* Placed, it is black still, edged in its silver or bronze. */
.cell--placed-2.cell--tier-4,
.cell--placed-3.cell--tier-4 {
  --cell-edge: var(--place-fill);
  --cell-ring: 0 0 0 1px var(--place-fill);
}

.cell--tier-4 .cell__badge {
  background: var(--trail-gold-fill);
  color: var(--trail-gold-deep);
}

.cell--tier-4 .cell__horse { font-weight: 800; }

/* Its silks are gold, the pick's and the foot's alike. */
.cell--tier-4 .cell__pick,
.cell--tier-4 .cell__chip { --silk-colour: var(--trail-gold-fill); }

.cell--tier-4 .cell__chip.is-ghost {
  --silk-colour: var(--trail-on-dark-24);
  color: var(--trail-on-dark-50);
}

.cell__tier-label--smoker {
  --meter-1: var(--trail-gold-deep);
  --meter-2: var(--trail-gold-deep);
  --meter-3: var(--trail-gold-deep);
  --meter-4: var(--trail-gold-deep);
  border-top: 0;
  background: var(--trail-gold-fill);
  color: var(--trail-gold-deep);
  letter-spacing: 0.12em;
}

.cell__tier-label--smoker .cell__tier-count { color: var(--trail-gold-ink-dark); }

/* ── Banners ───────────────────────────────────────────────── */
/* "You are here", the flagship picks and the Featured Tip race each
   put a banner across the top of their own card, and the card makes
   room for it. */

.cell--now,
.cell--flagship,
.cell--featured { --cell-strip: 22px; }

.cell__now,
.cell__flag,
.cell__ribbon {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 var(--cell-pad);
  border-radius: 11px 11px 0 0;
  font-size: 9.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* You are here (trail_live.js moves it): the fox marker stands on the
   next race, or the one that is running. */
.cell--now {
  --cell-edge: var(--c-ink);
  --cell-ring: 0 0 0 2px var(--c-ink), 0 0 0 8px var(--trail-ink-8);
  --cell-drop: 0 14px 24px -12px var(--trail-ink-50);
  z-index: 4;
}

.cell__now {
  z-index: 5;
  padding-left: 40px;                /* past the marker */
  background: var(--c-ink);
  color: var(--trail-gold-fill);
}

/* The marker: a counter on the corner of the card, with the site's fox
   on it. The template's emoji makes way for that. */
.cell__now-glyph {
  position: absolute;
  top: -14px;
  left: -5px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--c-ink) 88%, var(--trail-on-dark)), var(--c-ink) 70%);
  box-shadow:
    0 0 0 2px var(--trail-on-dark),
    0 3px 0 2px var(--trail-black),
    0 9px 14px -6px var(--trail-ink-65);
  font-size: 0;
  animation: foxHop 3.4s ease-in-out infinite;
}

.cell__now-glyph::after {
  --mask: var(--trail-fox);
  content: "";
  position: absolute;
  inset: 8px;
  background: var(--trail-gold-fill);
}

/* It waits, with a hop now and then. */
@keyframes foxHop {
  0%, 68%, 86%, 100% { transform: none; }
  77% { transform: translateY(-8px); }
  92% { transform: translateY(-3px); }
}

/* Flagship picks, Sly's Bet and the Lead Signal: a gold banner. */
.cell__flag {
  z-index: 6;
  background: var(--trail-gold-fill);
  color: var(--trail-gold-deep);
}

.cell__flag-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
}

/* The corner star stood in for the banner on a phone; the banner fits
   one now. */
.cell__star { display: none; }

/* Both at once: the flagship's star rides at the end of the "you are
   here" banner. */
.cell--now .cell__flag {
  right: 6px;
  left: auto;
  padding: 0;
  background: transparent;
  color: var(--trail-gold-fill);
}

.cell--now .cell__flag-label { display: none; }

/* The Featured Tip race: a gold edge with a halo, and its own banner
   unless one of the others has the place. */
.cell--featured {
  --cell-edge: var(--trail-gold);
  --cell-ring: 0 0 0 1px var(--trail-gold), 0 0 0 6px color-mix(in srgb, var(--trail-gold-fill) 28%, transparent);
}

.cell__ribbon {
  z-index: 4;
  background: var(--trail-gold-fill);
  color: var(--trail-gold-deep);
}

.cell--flagship .cell__ribbon,
.cell--now .cell__ribbon { display: none; }

/* A winner's rosette sits over the right end of a banner. */
.cell--won .cell__flag,
.cell--won .cell__ribbon { padding-right: 52px; }

/* ── Legend filters (trail_filter.js) ──────────────────────── */
/* A filter chosen in the legend dims every card that does not match;
   pointing at a legend row, or a silk on a card, previews the same more
   softly. The state is on the grid: a class and a data attribute. */

.trail__grid--filtered .cell { opacity: 0.28; }

.trail__grid[data-filter-tier="1"] .cell--tier-1,
.trail__grid[data-filter-tier="2"] .cell--tier-2,
.trail__grid[data-filter-tier="3"] .cell--tier-3,
.trail__grid[data-filter-tier="4"] .cell--tier-4,
.trail__grid[data-filter-source="bod"] .cell[data-sources~="bod"],
.trail__grid[data-filter-source="top_rated"] .cell[data-sources~="top_rated"],
.trail__grid[data-filter-source="htw"] .cell[data-sources~="htw"],
.trail__grid[data-filter-source="steamer"] .cell[data-sources~="steamer"],
.trail__grid[data-filter-source="letters"] .cell[data-sources~="letters"],
.trail__grid[data-filter-source="featured"] .cell[data-sources~="featured"],
.trail__grid[data-filter-source="pick_winner"] .cell[data-sources~="pick_winner"],
.trail__grid[data-filter-course] .cell--in-filter { opacity: 1; }

.trail__grid--hovered .cell { opacity: 0.4; }

.trail__grid[data-hover-source="bod"] .cell[data-sources~="bod"],
.trail__grid[data-hover-source="top_rated"] .cell[data-sources~="top_rated"],
.trail__grid[data-hover-source="htw"] .cell[data-sources~="htw"],
.trail__grid[data-hover-source="steamer"] .cell[data-sources~="steamer"],
.trail__grid[data-hover-source="letters"] .cell[data-sources~="letters"],
.trail__grid[data-hover-source="featured"] .cell[data-sources~="featured"] { opacity: 1; }

/* ── Coming up onto the track (trail_cards.js) ─────────────── */
/* Cards further down the board rise into place as the reader reaches
   them. The script switches this on only after it has marked the ones
   already on screen, and not at all for anyone who has asked for less
   motion. Never on paper. It sits after the filters and matches their
   weight, so a card not yet reached stays down whatever is chosen.
   Going down is not shown, only coming up: a card waiting below has no
   transition, and takes the card's own again when it is reached. */

@media screen and (prefers-reduced-motion: no-preference) {
  .trail--entrance .trail__grid .cell:not(.is-seen) {
    opacity: 0;
    translate: 0 18px;
    transition: none;
  }
}

/* ── Live moments ──────────────────────────────────────────── */
/* Short flashes when something changes as the reader watches. Each is
   a class a script adds and takes away again. */

/* A race has settled (trail_live.js) */
.cell--just-updated { animation: cellJustUpdated 1400ms ease-out; }

@keyframes cellJustUpdated {
  0%   { box-shadow: 0 0 0 0 var(--trail-ink-32); }
  40%  { box-shadow: 0 0 0 6px var(--trail-ink-8); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* ...and it was a winner: a gold ripple, and the rosette drops in. */
.cell--just-won {
  z-index: 3;
  animation: cellJustWon 1500ms ease-out;
}

@keyframes cellJustWon {
  0% {
    box-shadow:
      0 0 0 0 color-mix(in srgb, var(--trail-gold) 70%, transparent),
      0 0 0 0 color-mix(in srgb, var(--c-gold-lt) 55%, transparent);
    transform: translateY(0);
  }
  25% {
    box-shadow:
      0 0 0 4px color-mix(in srgb, var(--trail-gold) 55%, transparent),
      0 0 22px color-mix(in srgb, var(--c-gold-lt) 75%, transparent);
    transform: translateY(-2px);
  }
  60% {
    box-shadow:
      0 0 0 8px color-mix(in srgb, var(--trail-gold) 18%, transparent),
      0 0 32px color-mix(in srgb, var(--c-gold-lt) 45%, transparent);
    transform: translateY(-1px);
  }
  100% {
    box-shadow: 0 0 0 0 transparent, 0 0 0 0 transparent;
    transform: translateY(0);
  }
}

.cell--just-won .cell__medal--gold { animation: medalDropIn 600ms cubic-bezier(0.34, 1.56, 0.64, 1) 40ms both; }

@keyframes medalDropIn {
  from {
    opacity: 0;
    transform: translateY(-16px) scale(0.8);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* The fox marker has moved on to this card (trail_live.js) */
.cell--fox-arriving .cell__now {
  transform-origin: 22px 50%;
  animation: foxArriving 900ms cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes foxArriving {
  0% {
    opacity: 0;
    transform: scale(0.4) translateY(-6px);
  }
  55% {
    opacity: 1;
    transform: scale(1.08) translateY(0);
  }
  100% {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

/* The reader has been taken to this card (trail_course.js) */
.cell--just-reached { animation: cellJustReached 1500ms ease-out; }

@keyframes cellJustReached {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--trail-gold) 90%, transparent), var(--cell-drop); }
  35%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--trail-gold) 55%, transparent), var(--cell-drop); }
  100% { box-shadow: 0 0 0 12px transparent, var(--cell-drop); }
}

/* ── What a card has room for ──────────────────────────────── */
/* The widths are the card's content box, which is what a container
   query measures: a 133px card on a 360px phone is 109px inside, a
   180px card beside the legend on a small laptop is 150px. */

/* Roomy cards, on laptops and up: bigger silks. */
@container trail-cell (width >= 168px) {
  .cell__body { --pick-silk: 40px; }
  .cell__pick--primary::after { font-size: 14px; }
}

/* Narrow cards: the name takes the full width, the silks move down
   beside the price, and a long course name may take a second line. */
@container trail-cell (width <= 158px) {
  .cell__course {
    letter-spacing: 0.05em;
    white-space: normal;
  }

  .cell__body { --pick-silk: 24px; }

  .cell__pick--primary {
    align-items: center;
    column-gap: 7px;
  }

  .cell__horse {
    grid-area: 1 / 1 / auto / -1;
    font-size: var(--cell-horse-size, 16px);
  }

  .cell__pick--primary::before,
  .cell__pick--primary::after { grid-area: 2 / 1; }

  .cell__pick--primary::before { margin-top: 0; }

  .cell__pick--primary::after {
    align-self: start;
    margin-top: calc(var(--pick-silk) * 0.62 - 0.75em);
    font-size: 8.5px;
  }

  /* The horse's own silks go where the jacket did, a size up from it:
     there is a pattern to read. */
  .cell__body:has(.cell__silk) { --pick-silk: 30px; }

  .cell__silk {
    grid-area: 2 / 1;
    margin-top: 0;
  }

  .cell__odds { grid-area: 2 / 2; }
  .cell--split .cell__pick--alt { padding-left: 0; }
  .cell__chips { gap: 2px; }

  .cell__chip {
    --silk-size: 15px;
    font-size: 6px;
  }
}

/* "2/4 AGREE" beside CHORUS or SMOKER: room for the count, not for the
   word. The box is as wide as its longer word, the two words take a
   line each, and only the first line shows. */
@container trail-cell (width <= 146px) {
  .cell__tier-count {
    flex: 0 0 auto;
    width: min-content;
    height: 1.25em;
    overflow: hidden;
    line-height: 1.25;
    text-align: right;
    white-space: normal;
  }
}

/* The status slot on a narrow card: the confidence in a word, a size
   down, without the bars. A card with no word keeps its unlit bars. */
@container trail-cell (110px < width <= 146px) {
  .cell:not(.cell--backup, .cell--no_fancy) .cell__head::after {
    padding-left: 0;
    background: none;
    font-size: 8.5px;
    letter-spacing: 0.06em;
  }
}

/* On the smallest cards, the bars alone. Nod and above still have
   their strip to say the word. */
@container trail-cell (width <= 110px) {
  .cell__head::after {
    content: "";
    padding-left: 0;
  }
}

/* Phones: cloth, time and result share one line, so each gives a
   little; the silks lose their letters, and the rosette is a size down
   to clear the course name beneath it and the words of a banner. */
@container trail-cell (width <= 132px) {
  /* The flag of a race that is run, before the course: the time's line
     is full. */
  .cell--won .cell__time::after,
  .cell--placed .cell__time::after,
  .cell--lost .cell__time::after,
  .cell--void .cell__time::after { content: none; }

  .cell--won .cell__course::before,
  .cell--placed .cell__course::before,
  .cell--lost .cell__course::before,
  .cell--void .cell__course::before {
    --flag-square: 3px;
    display: inline-block;
    margin: 0 6px 0 0;
    vertical-align: -3px;
  }

  .cell__badge {
    min-width: 19px;
    height: 19px;
    font-size: 10.5px;
    line-height: 19px;
  }

  .cell__time {
    margin-left: 25px;
    font-size: 13px;
    line-height: 19px;
  }

  .cell__chip {
    --silk-size: 13px;
    font-size: 0;                    /* no room for a letter, or its plate */
  }

  .cell__glyph--live,
  .cell__glyph--void {
    gap: 4px;
    padding: 0 6px;
  }

  .cell__glyph--live::after,
  .cell__glyph--void::after {
    font-size: 9.5px;
    letter-spacing: 0.06em;
  }

  .cell__medal:not(.cell__medal--gold) {
    top: calc(var(--cell-pad) + var(--cell-strip));
    padding: 0 6px;
    font-size: 10px;
  }

  .cell__medal--gold {
    top: -12px;
    right: 2px;
    width: 36px;
    height: 36px;
    font-size: 8px;
    letter-spacing: 0.03em;
  }

  .cell__now,
  .cell__flag,
  .cell__ribbon {
    gap: 5px;
    font-size: 9px;
    letter-spacing: 0.08em;
  }

  .cell--won .cell__flag,
  .cell--won .cell__ribbon { padding-right: 40px; }

  .cell--won .cell__flag-glyph { display: none; }
}


/* ═══════════════════════════════════════════════════════════════
   The results side — what "Reveal results" turns a card over to
   ---------------------------------------------------------------
   The race again beside the saddle cloth, the first three home, and
   how the pick fared. Its colours are the card's own (see "Race
   cards"), so it reads on a winner's card and on the Smoker's alike.
   ═══════════════════════════════════════════════════════════════ */

.cell__back { gap: 8px; }

/* One line: the time and the course, after the cloth. */
.cell__back-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
  padding-left: 30px;
}

.cell__back-time {
  flex: 0 0 auto;
  color: var(--cell-ink);
  font-size: 14px;
  font-weight: 700;
  line-height: 22px;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.cell__back-course {
  min-width: 0;
  overflow: hidden;
  color: var(--cell-ink-3);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.07em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

/* "Result": 1st, 2nd and 3rd speak for themselves. */
.cell__back-title { display: none; }

/* ── The first three home ──────────────────────────────────── */

.cell__back-podium {
  display: flex;
  flex-direction: column;
  list-style: none;
}

.cell__back-slot {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 6px;
  padding: 3px 0;
  border-bottom: 1px solid var(--cell-rule);
}

.cell__back-pos {
  color: var(--cell-ink-3);
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.cell__back-slot--pos-1 .cell__back-pos { color: var(--cell-gold); }

.cell__back-slot--pos-2 .cell__back-pos,
.cell__back-slot--pos-3 .cell__back-pos { color: var(--cell-ink-2); }

.cell__back-horse {
  min-width: 0;
  overflow: hidden;
  color: var(--cell-ink);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cell__back-sp {
  color: var(--cell-ink-3);
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

/* The pick, where it made the first three */
.cell__back-slot.is-our-pick {
  margin: 0 -6px;
  padding: 3px 6px;
  border-bottom-color: transparent;
  border-radius: var(--r-sm);
  background: var(--cell-tag);
}

.cell__back-slot.is-our-pick .cell__back-horse { font-weight: 800; }

/* ── How the pick fared ────────────────────────────────────── */
/* The label, then "5th · LOST" with the starting price at the right,
   then the horse. */

.cell__back-pick {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--cell-rule);
}

.cell__back-pick-label {
  color: var(--cell-ink-3);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.cell__back-pick-fin {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  color: var(--cell-ink);
  font-size: 13px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cell__back-pick--won .cell__back-pick-fin { color: var(--cell-gold); }
.cell__back-pick--lost .cell__back-pick-fin { color: var(--cell-ink-2); }

.cell__back-pick-sp {
  color: var(--cell-ink-3);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
}

.cell__back-pick-horse {
  overflow: hidden;
  color: var(--cell-ink-2);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.15;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── A void race ───────────────────────────────────────────── */

.cell__back-void {
  align-self: center;
  margin-top: auto;
  color: var(--cell-ink-2);
  font-size: 16px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.01em;
}

.cell__back-note {
  align-self: center;
  margin-bottom: auto;
  padding-top: 4px;
  color: var(--cell-ink-3);
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
}

/* A phone's card: in step with the smaller cloth on the front. */
@container trail-cell (width <= 132px) {
  .cell__back-head { padding-left: 25px; }

  .cell__back-time {
    font-size: 13px;
    line-height: 19px;
  }
}


/* ═══════════════════════════════════════════════════════════════
   Spotlight — today's strongest signals, under the board
   ═══════════════════════════════════════════════════════════════ */

.trail__spotlight {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 820px;
  margin: 40px auto 0;
  scroll-margin-top: var(--trail-scroll-clear);
}

/* ── The Smoker: all four signals on one horse ─────────────── */
/* The black card from the board, writ large. Its silks are gold, with
   the letters in the card's own black. */

.smoker {
  --cell-face: var(--c-ink);
  padding: 18px 20px 20px;
  border: 1px solid var(--c-ink);
  border-radius: 14px;
  background: var(--c-ink);
  box-shadow: 0 18px 40px -22px var(--trail-ink-65);
  color: var(--trail-on-dark);
}

.smoker__eyebrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  color: var(--trail-gold-fill);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.smoker__flame { display: none; }

.smoker__meta {
  color: var(--trail-on-dark-70);
  font-weight: 500;
  letter-spacing: 0.1em;
}

.smoker__body {
  display: grid;
  grid-template-columns: 1fr;
  align-items: baseline;
  gap: 10px;
}

.smoker__horse {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
}

.smoker__horse-name {
  font-size: 26px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.smoker__odds {
  padding: 4px 10px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--trail-gold-fill) 16%, transparent);
  color: var(--trail-gold-fill);
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.smoker__race {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--trail-on-dark-70);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.smoker__chips {
  display: inline-flex;
  gap: 4px;
}

.smoker__chips .cell__chip {
  --silk-size: 22px;
  --silk-colour: var(--trail-gold-fill);
}

/* ── Chorus and Nods, side by side ─────────────────────────── */

.spotlight__strip {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.spotlight__group {
  padding: 16px 18px 10px;
  border: 1px solid var(--c-rule);
  border-radius: 14px;
  background: var(--c-card);
  box-shadow: var(--trail-shadow);
}

/* The meter, how many, the tier's name, and what it means */
.spotlight__title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--c-rule);
  line-height: 1;
}

.spotlight__title-num {
  color: var(--c-ink);
  font-size: 24px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.spotlight__title-name {
  color: var(--c-ink);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.spotlight__title-sub {
  margin-left: auto;
  color: var(--trail-ink-soft);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.spotlight__picks {
  display: flex;
  flex-direction: column;
  list-style: none;
}

/* A pick: the time over the course, the horse, the price */
.spotlight__pick {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 2px 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--trail-rule-soft);
  color: var(--c-ink);
  font-size: 14px;
  font-weight: 500;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}

.spotlight__pick-time { font-weight: 700; }

.spotlight__pick-course {
  grid-area: 2 / 1;
  align-self: center;
  color: var(--trail-ink-soft);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.spotlight__pick-horse {
  grid-column: 2;
  overflow: hidden;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.spotlight__pick-odds {
  padding: 3px 8px;
  border-radius: var(--r-sm);
  background: var(--trail-wash);
  font-size: 12px;
  font-weight: 600;
}

@media (min-width: 768px) {
  .smoker { padding: 26px 32px 28px; }

  .smoker__body {
    grid-template-columns: 1fr auto auto;
    gap: 24px;
  }

  .smoker__horse-name { font-size: 32px; }

  /* Two tiers side by side; one alone takes the full width. */
  .spotlight__strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
  }

  .spotlight__strip:has(> .spotlight__group:only-child) { grid-template-columns: minmax(0, 1fr); }
}


/* ═══════════════════════════════════════════════════════════════
   Card drawer — the evidence behind one race (trail_drawer.js)
   ---------------------------------------------------------------
   A panel from the right; a sheet from the bottom on a phone. It
   opens over everything, the site's fixed navigation and phone menu
   included (chrome.css has those at 200 and 300), on the page's own
   ground.
   ═══════════════════════════════════════════════════════════════ */

.cell-drawer {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  justify-content: flex-end;
}

/* Said again because the display above outranks the browser's own. */
.cell-drawer[hidden] { display: none; }

.cell-drawer__scrim {
  position: absolute;
  inset: 0;
  background: var(--trail-ink-42);
  animation: drawerScrimIn 180ms ease-out both;
}

.cell-drawer__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
  width: min(460px, 100%);
  max-height: 100vh;
  padding: 20px 22px 24px;
  overflow-y: auto;
  border-left: 1px solid var(--c-rule);
  background: var(--c-paper);
  animation: drawerPanelIn 220ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@keyframes drawerScrimIn {
  from { opacity: 0; }
}

@keyframes drawerPanelIn {
  from {
    opacity: 0;
    transform: translateX(24px);
  }
}

@keyframes drawerSheetIn {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
}

/* Stops the page scrolling behind the open drawer. */
body.has-cell-drawer-open { overflow: hidden; }

/* ── Head: which race, and how strong ──────────────────────── */

.cell-drawer__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.cell-drawer__eyebrow {
  color: var(--trail-gold-ink);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.cell-drawer__title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 4px;
  color: var(--c-ink);
  font-size: 24px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}

.cell-drawer__tier {
  margin-top: 6px;
  color: var(--trail-gold-ink);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.cell-drawer__tier--whisper { color: var(--trail-ink-soft); }

.cell-drawer__close {
  width: 34px;
  height: 34px;
  border: 1px solid var(--c-rule-strong);
  border-radius: 50%;
  background: var(--c-card);
  color: var(--c-ink);
  font-size: 22px;
  line-height: 30px;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}

.cell-drawer__close:hover,
.cell-drawer__close:focus-visible {
  background: var(--c-ink);
  color: var(--trail-on-dark);
}

/* ── The state of the race ─────────────────────────────────── */
/* The label takes the colours of the plaque on the card. */

.cell-drawer__state {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  border: 1px solid var(--c-rule);
  border-radius: var(--r-md);
  background: var(--c-card);
}

.cell-drawer__state-label {
  align-self: flex-start;
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--trail-wash);
  color: var(--trail-ink-soft);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.cell-drawer__state-label.is-won {
  background: var(--trail-gold-fill);
  color: var(--trail-gold-deep);
}

.cell-drawer__state-label.is-placed {
  background: var(--c-card);
  box-shadow: inset 0 0 0 1.5px var(--c-ink);
  color: var(--c-ink);
}

.cell-drawer__state-label.is-live {
  background: var(--c-ink);
  color: var(--trail-on-dark);
}

.cell-drawer__state-detail {
  color: var(--c-ink);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.4;
}

/* ── A row a signal ────────────────────────────────────────── */

.cell-drawer__sources {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
}

.cell-drawer__source {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px;
  border: 1px solid var(--c-rule);
  border-radius: var(--r-md);
  background: var(--c-card);
}

/* The signal whose horse the card shows */
.cell-drawer__source.is-anchor {
  padding-left: 12px;
  border-left: 3px solid var(--trail-gold);
}

/* A signal with no pick in this race */
.cell-drawer__source.is-off { background: transparent; }

.cell-drawer__source-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Each row carries its signal's silks. */
.cell-drawer__source-mark {
  --silk-size: 28px;
  font-size: 10px;
}

.cell-drawer__source-label {
  color: var(--c-ink-70);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.cell-drawer__source.is-off .cell-drawer__source-label { color: var(--trail-ink-soft); }

.cell-drawer__source-pick {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
}

.cell-drawer__source-horse {
  color: var(--c-ink);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.2;
}

.cell-drawer__source-horse--off {
  color: var(--trail-ink-soft);
  font-weight: 500;
}

.cell-drawer__source-odds {
  padding: 2px 7px;
  border-radius: 4px;
  background: var(--trail-wash);
  color: var(--c-ink);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.cell-drawer__source-reasoning {
  color: var(--c-ink-70);
  font-size: 13px;
  line-height: 1.5;
}

/* "Anchors consensus", "alternative pick", "didn't fancy this race" */
.cell-drawer__source-pill {
  align-self: flex-start;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: var(--trail-gold-wash);
  color: var(--trail-gold-ink);
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.cell-drawer__source-pill.is-alt,
.cell-drawer__source-pill.is-off {
  background: var(--trail-wash);
  color: var(--trail-ink-soft);
}

.cell-drawer__source-pill.is-off {
  border: 1px dashed var(--c-rule-strong);
  background: transparent;
}

/* ── Foot ──────────────────────────────────────────────────── */

.cell-drawer__foot {
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px dashed var(--c-rule);
}

.cell-drawer__caveat {
  color: var(--trail-ink-soft);
  font-size: 11px;
  line-height: 1.45;
}

/* A phone: a sheet from the bottom, with room left to see the board. */
@media (max-width: 767px) {
  .cell-drawer {
    align-items: flex-end;
    justify-content: stretch;
  }

  .cell-drawer__panel {
    width: 100%;
    max-height: 88vh;
    border-top: 1px solid var(--c-rule);
    border-left: 0;
    border-radius: var(--r-md) var(--r-md) 0 0;
    animation: drawerSheetIn 240ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
  }
}


/* ═══════════════════════════════════════════════════════════════
   Days without a full board
   ---------------------------------------------------------------
   No racing (empty), too early for the morning's signals
   (premature), and a thin card (early signals). Honest notices on a
   white card; never fabricated data.
   ═══════════════════════════════════════════════════════════════ */

/* ── No race cards: no course ──────────────────────────────── */
/* On a day with no racing the template puts its notice in the frame,
   where the board would be; on a day too early for the card it leaves
   the frame out. Either way the page has no race on it. The frame has
   no course to hold, and the course bar and the call to the next race
   have nowhere to go: they stand down, whether or not the template
   leaves them out, and the notice sits on the page. */

.trail:not(:has(.cell[data-race-id])) .trail__course,
.trail:not(:has(.cell[data-race-id])) .trail__next { display: none; }

.trail:not(:has(.cell[data-race-id])) .trail__frame,
.trail:not(:has(.cell[data-race-id])) .trail__grid {
  padding: 0;
  background: none;
  box-shadow: none;
}

/* With no board in between, the track record keeps its distance from
   the notice above it. */
.trail:not(:has(.cell[data-race-id])) .trail__record { margin-top: 28px; }

/* ── Empty, and too early ──────────────────────────────────── */

.trail__empty,
.trail__premature {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 56px 24px 60px;
  border: 1px dashed var(--c-rule-strong);
  border-radius: 14px;
  background: var(--c-card);
  color: var(--c-ink-70);
  text-align: center;
}

/* It stands in the frame, in the board's place. Rendered inside the
   grid instead, it would take the whole row. */
.trail__empty { grid-column: 1 / -1; }

.trail__empty-mark,
.trail__premature-mark {
  width: 48px;
  height: 48px;
  color: var(--trail-ink-soft);
  opacity: 0.55;
}

.trail__premature-mark { opacity: 0.65; }

.trail__empty-mark svg,
.trail__premature-mark svg,
.trail__early-signals-mark svg {
  width: 100%;
  height: 100%;
}

.trail__empty-title,
.trail__premature-title,
.anatomy__title {
  color: var(--c-ink);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
  text-wrap: balance;
}

.trail__empty-body,
.trail__premature-body {
  max-width: 44ch;
  font-size: 14px;
  line-height: 1.6;
  text-wrap: pretty;
}

.trail__premature-body { max-width: 52ch; }

/* Onward links: the racecards, the newsroom */
.trail__empty-links,
.trail__premature-links {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 6px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
}

.trail__empty-link,
.trail__premature-link {
  padding-bottom: 1px;
  border-bottom: 1px solid var(--trail-gold-ring);
  color: var(--trail-gold-ink);
  text-decoration: none;
  transition: border-color 140ms ease;
}

.trail__empty-link:hover,
.trail__premature-link:hover { border-color: var(--trail-gold-ink); }

.trail__empty-sep,
.trail__premature-sep {
  color: var(--trail-ink-soft);
  opacity: 0.55;
}

/* ── Early signals: a note above a thin board ──────────────── */

.trail__early-signals {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  max-width: 720px;
  margin: 14px auto 20px;
  padding: 14px 18px;
  border: 1px solid var(--c-rule);
  border-left: 3px solid var(--trail-gold-ink);
  border-radius: 8px;
  background: var(--c-card);
  color: var(--c-ink-70);
}

.trail__early-signals-mark {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  color: var(--trail-gold-ink);
}

.trail__early-signals-body {
  font-size: 14px;
  line-height: 1.55;
  text-wrap: pretty;
}

.trail__early-signals-lede {
  margin-right: 4px;
  color: var(--c-ink);
  font-weight: 600;
}

/* ── Anatomy: how to read the board, before it goes live ───── */
/* Shown with the too-early notice. Three cards: the confidence tiers,
   the results, the tally. Its tiers use the legend's meter and its
   results the cards' plaques, so it teaches the board as it is. */

.trail__anatomy {
  max-width: 1080px;
  margin: 22px auto 8px;
  padding: 22px 20px 6px;
  border: 1px solid var(--c-rule);
  border-radius: 14px;
  background: var(--c-card);
}

.anatomy__head {
  margin-bottom: 16px;
  text-align: center;
}

.anatomy__eyebrow {
  display: block;
  margin-bottom: 6px;
  color: var(--trail-ink-soft);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.anatomy__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
}

.anatomy__card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px 18px 16px;
  border: 1px solid var(--c-rule);
  border-radius: 10px;
  background: var(--c-paper);
}

.anatomy__card-title {
  color: var(--c-ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.02em;
}

.anatomy__card-lede {
  color: var(--c-ink-70);
  font-size: 13px;
  line-height: 1.55;
  text-wrap: pretty;
}

.anatomy__tiers,
.anatomy__medals,
.anatomy__tally {
  display: grid;
  gap: 8px;
  list-style: none;
}

/* A row in any of the three lists */
.anatomy__tier,
.anatomy__medals li,
.anatomy__tally > div {
  display: grid;
  grid-template-columns: 66px 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  background: var(--c-card);
}

.anatomy__medals li { grid-template-columns: 56px 1fr; }

.anatomy__tally > div {
  grid-template-columns: 76px 1fr;
  align-items: baseline;
}

.anatomy__tier-name,
.anatomy__tally dt {
  color: var(--c-ink);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
}

.anatomy__tally dt {
  font-size: 12px;
  letter-spacing: 0.02em;
}

.anatomy__tier-detail {
  justify-self: end;
  color: var(--trail-ink-soft);
  font-size: 12px;
  line-height: 1;
}

.anatomy__medal-detail,
.anatomy__tally dd {
  color: var(--c-ink-70);
  font-size: 13px;
  line-height: 1.35;
}

.anatomy__tally dd { font-size: 12px; }

/* Won, 2nd, 3rd: as the plaques on the cards */
.anatomy__medal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 8px;
  border-radius: 4px;
  background: var(--c-card);
  box-shadow: inset 0 0 0 1.5px var(--c-ink);
  color: var(--c-ink);
  font-size: 10px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.08em;
}

.anatomy__medal--gold {
  background: var(--trail-gold-fill);
  box-shadow: none;
  color: var(--trail-gold-deep);
}

.anatomy__foot {
  margin: 18px 0 4px;
  padding: 14px 12px 0;
  border-top: 1px solid var(--c-rule);
  color: var(--c-ink-70);
  font-size: 13px;
  line-height: 1.55;
  text-align: center;
  text-wrap: pretty;
}

@media (min-width: 768px) {
  .trail__empty,
  .trail__premature {
    gap: 18px;
    padding: 80px 40px 88px;
  }

  .trail__empty-title,
  .trail__premature-title,
  .anatomy__title { font-size: 28px; }

  .trail__early-signals {
    gap: 14px;
    padding: 16px 22px;
  }

  .trail__anatomy {
    margin-top: 28px;
    padding: 30px 32px 12px;
  }
}

@media (min-width: 1024px) {
  .anatomy__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 22px;
  }
}


/* ═══════════════════════════════════════════════════════════════
   Reduced motion
   ---------------------------------------------------------------
   chrome.css already brings every animation and transition on the
   site to a stop for a reader who has asked for less motion: nothing
   here pulses, hops or fades for them, a card turns to its results
   side at once, and trail_cards.js leaves the cards where they are.
   What is left is the movement that is neither: the lift under the
   pointer. And the flash on a card the course bar has gone to needs
   something still to stand in for it.
   ═══════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .cell:hover,
  .cell:hover .cell__pick--primary::before,
  .trail__next-link:hover,
  .trail__next-link:focus-visible,
  .trail__legend-row:hover .cell__chip,
  .trail__legend-row:hover .trail__legend-star,
  .trail__legend-row:hover .trail__legend-pips { transform: none; }

  .cell:hover .cell__pick--primary::after { translate: none; }

  .cell--just-reached {
    outline: 3px solid var(--trail-gold);
    outline-offset: 3px;
  }
}
