/* BetTurtle turtle theme — design tokens and shell.
 *
 * Loaded outside {% compress %} because COMPRESS_OFFLINE cannot enumerate a conditional
 * block. Everything is scoped to .tt-wrap.fc so it cannot reach the existing UI; the only
 * unscoped rules are the :root scale/size tokens, which no other stylesheet reads.
 *
 * The authority for these values is .claude/skills/turtle-ui-design/SKILL.md.
 */

:root{ --fc-scale:1.15; }

:root[data-fc-size="compact"]{ --fc-scale:1; }

:root[data-fc-size="large"]{   --fc-scale:1.32; }

/* Tokens live on :root, not on the wrapper, so anything Bootstrap renders into <body>
   -- popovers, tooltips -- inherits them too. Declaring a custom property costs nothing
   where it is never referenced, and only turtle selectors reference these. */
:root{
  --fc-ink:#ffffff;
  --fc-ink-2:#e6f0e7;
  --fc-ink-3:#c0d3c4;
  /* Toned down from #b9dc4e (Kenny, 2 Sep): the accent is on 213 rules and read as glaring
     on the dark ground at 11.2:1, which is two and a half times what it needs. 9.2:1 here,
     and `--fc-accent-ink` on a filled one falls from 7.9 to 6.5. */
  --fc-accent:#a5c93f;
  --fc-accent-ink:#0a3d1f;
  --fc-surface:rgba(0,0,0,.24);
  --fc-pop-bg:#0e3b21;
  --fc-band-bg:#0e3b21;
  /* elements whose colour is fixed against a dark ground need a light-mode pair */
  --fc-tile-line:#eaf6ea;
  --fc-draw-line:#16351f;
  --fc-chip-bg:#0f5a2c; --fc-chip-ink:#ffffff; --fc-chip-line:#ffffff;
  --fc-warn:#ffd479; --fc-warn-line:rgba(255,212,121,.5);
  --fc-medal-1:#f2c75c; --fc-medal-2:#cfd6de; --fc-medal-3:#f0b98d;
  /* cell tints are derived from the good/fair/poor tokens, not the prototype's older pair */
  /* Rating VALUES are small text on the chip ground, so they need their own pair per
     theme: the good/fair/poor tokens are tuned for large glyphs and fail AA here. */
  /* val-r was #ffc9cc: 89% lightness at 6.66:1, bleached far past the 4.5 it needed,
     which read as pink beside the --fc-poor horseshoe red. 80% clears 4.75:1 on the
     worst ground (zebra over the lightest gradient stop) at the same hue 355. */
  /* The tables inside a sheet -- Race statistics, Summary statistics -- colour their
     horseshoes through these, not through --fc-good/fair/poor. The amber was BRIGHTER
     than the green here too (.65 against .62), which is 1.05:1: one colour, in effect.
     The same orange as the row takes it to 1.47. */
  --fc-val-g:#b0dc6b; --fc-val-a:#ff8c1a; --fc-val-r:#ff5347; --fc-move-out:#ff7f75;
  /* Small bold text on a saturated ground: accent-ink measures 3.89:1 on val-r. */
  --fc-pill-ink:#10261a;
  /* A badge sits on its own tint, so it needs a step more contrast than a value
     on the bare row does. */
  --fc-badge-g:#9ed62f; --fc-badge-a:#ffcd29; --fc-badge-r:#ffadb4;
  --fc-badge-bg-g:rgba(141,198,63,.16);
  --fc-badge-bg-a:rgba(242,197,49,.16);
  --fc-badge-bg-r:rgba(240,97,109,.16);
  --fc-cell-g:rgba(141,198,63,.16);
  --fc-cell-a:rgba(242,197,49,.16);
  --fc-cell-r:rgba(240,97,109,.18);
  /* Used by .tt-check; previously undefined, so both themes fell back to
     these dark values and light rendered pale lime on pale lime. */
  --fc-check-bg:rgba(166,206,57,.16); --fc-check-ink:#cfe9a8;
  /* Darker than the page ground, not lighter (Kenny, 30 Aug 2026). It used to be a 5% white
     wash, which put panels ABOVE the gradient in luminance and left red text nowhere to read:
     a true red measured 2.8 there and the only way up was to lighten it into pink. At 28%
     black the same panels sit near #0f1c14, where a real red reads 5.5 and the body ink
     improves from 12.4 to about 15. */
  --fc-surface-2:rgba(0,0,0,.28);
  --fc-line:rgba(255,255,255,.14);
  --fc-line-2:rgba(165,201,63,.34);
  --fc-head-bg:rgba(11,107,50,.45);
  --fc-thead:#0a4423;
  /* The performance key: star good, thumb-up moderate, thumb-down poor. They sit on a pale
     chip in a green head, so both themes use the values that read on white. */
  --fc-perf-good:#a37a00; --fc-perf-mid:#127500; --fc-perf-poor:#d10011;
  /* A star is always yellow (Kenny, 31 Aug). Bright, because on a dark ground it
     can be: #ffd23f is 10.7:1 on the row and 8.7:1 on the drawer panel. */
  --fc-star:#ffd23f; --fc-star-edge:none;
  /* Layer DARK surfaces with black, not white. A stripe on a row inside a sheet
     stacked two 7% whites to #3b5847, which is what forced val-r to a near-white
     pink to stay legible. */
  --fc-zebra:rgba(0,0,0,.16);
  --fc-hover:rgba(185,220,78,.12);
  --fc-inset:rgba(0,0,0,.22);
  --fc-well:rgba(0,0,0,.28);
  --fc-hair:rgba(255,255,255,.16);
  /* gold vs crimson, kept far apart in hue and lightness */
  /* A ladder, brightest to darkest: good, then fair, then poor. The amber used to be
     BRIGHTER than the green (.59 against .46), so the middling grade out-shone the good one
     and the two read as one colour -- 1.25:1 apart, which is hue alone (profiler, 1 Sep).
     Now 1.46 and 1.39 between neighbours, 2.03 end to end, all still clear of AA on the row
     ground (9.9, 6.8, 4.9). This is close to the ceiling: three inks that must each pass AA
     on one ground cannot be spread much further without one of them turning white. */
  /* Toned from #a8e05f (Kenny, 2 Sep). 10.4:1 on the row, and the gap to the amber falls
     from 1.50 to 1.38 -- level with the amber-to-red gap this ladder already accepts, and
     clear of the 1.25 that read as hue alone. Any calmer means moving the amber and red
     too, and the red has the least room. */
  --fc-good:#a0d854;
  --fc-fair:#ff8c1a;
  --fc-poor:#f0616d;
  /* the card's shoe palette follows the same separation */
  --shoe-green:var(--fc-good);
  --shoe-amber:var(--fc-fair);
  --shoe-red:var(--fc-poor);
  /* hot is a positive signal, so it is not the poor-red */
  --fc-hot:#ff9d80;
  --fc-cold:#9ac6e2;
}

/* Why the light inks did not move, 30 Aug 2026. Measured against the sheet (#f4f8f4):
   --fc-val-g at #127500 is 5.48; one step brighter (#0f8a00) is 4.21 and fails AA. The green
   and amber GLYPHS are the same story at the 3:1 non-text floor -- #00a828 reads 2.95 and
   #c08400 2.99. On a near-white ground, brighter and readable pull against each other, so
   what carries the colour in light mode is the AREA: the cell and badge tints go to .24-.26
   where they were .16-.20 -- .24 is the ceiling for the badges, measured: at .28
   the green and red inks fall to 4.42 and 4.36 and the card's WIN TIP and STRONG
   FAV badges failed. The cells sit behind ICONS, so they answer to the 3:1 non-text
   floor instead; .26 holds the red at 3.3 where .30 took it to 3.13.

   The DARK theme was measured and left alone. Brightening its inks reads fine against the
   card surface -- #ff7b87 is 6.91 there -- but those values also sit on the cell tints and on
   pale reused fragments, where the same change took eight items under AA (3.59 and 4.31) on
   Search Today's Runners and My Shortlisted Runners. Raising its tints instead did the same
   thing from the other side. A single-ground calculation says there is headroom; the audit
   across real pages says there is not, and the audit is the authority. */
:root:not([data-fc-theme="dark"]){
  --fc-ink:#10261a;
  --fc-ink-2:#12241a;
  --fc-ink-3:#38513f;
  /* was #1c6b33 at 59% saturation. The accent is on every chip, tab, link and panel
     border; a dark low-chroma green recedes on a light ground where dark's lime
     advances. Full saturation, still 4.92:1. */
  --fc-accent:#007521;
  --fc-accent-ink:#ffffff;
  --fc-surface:#ffffff;
  --fc-pop-bg:#ffffff;
  --fc-band-bg:#e8f2e9;
  --fc-tile-line:#0b4522;
  --fc-draw-line:#ffffff;
  --fc-chip-bg:#0f5a2c; --fc-chip-ink:#ffffff; --fc-chip-line:#0b4522;
  --fc-warn:#7a4a00; --fc-warn-line:rgba(122,74,0,.45);
  --fc-medal-1:#7a5c00; --fc-medal-2:#44505c; --fc-medal-3:#7a3c1a;
  /* Full saturation at the highest lightness that still clears 4.5:1. */
  --fc-val-g:#127500; --fc-val-a:#946200; --fc-val-r:#d10011; --fc-move-out:#d10011;
  --fc-pill-ink:#ffffff;
  --fc-badge-g:#0f6600; --fc-badge-a:#755200; --fc-badge-r:#ad000e;
  --fc-badge-bg-g:rgba(28,107,51,.24);
  --fc-badge-bg-a:rgba(150,105,0,.24);
  --fc-badge-bg-r:rgba(176,32,44,.24);
  /* Tints were .13-.14 against dark's .16-.18, so the horseshoe grid lost its
     at-a-glance colour block on white. .20 is the most the glyph on top can carry and
     still clear 3.3:1 against its own tint. */
  --fc-cell-g:rgba(28,107,51,.26);
  --fc-cell-a:rgba(216,160,23,.26);
  --fc-cell-r:rgba(176,32,44,.26);
  --fc-check-bg:rgba(28,107,51,.12); --fc-check-ink:#14512a;
  --fc-surface-2:#f4f8f4;
  /* Pale sage on near-white gave light no structure, where dark carries its accent hue
     into every border. Stronger, and line-2 picks the accent up. */
  --fc-line:#bcd0c2;
  --fc-line-2:#5f9a72;
  --fc-head-bg:#e8f2e9;
  --fc-thead:#1c6b33;
  --fc-perf-good:#a37a00; --fc-perf-mid:#127500; --fc-perf-poor:#d10011;
  /* Light cannot have a bright yellow as a flat ink -- the brightest that clears 3:1 on
     white is a mustard, which is the dull one. So the fill stays yellow and the SHAPE
     carries the contrast: a hairline dark edge, which is what an icon is measured on. */
  --fc-star:#f0b400;
  --fc-star-edge:0 0 1px rgba(58,38,0,.95), 0 0 2px rgba(58,38,0,.45);
  --fc-zebra:#e4ede6;
  --fc-hover:#dcecdf;
  --fc-inset:#eef4ef;
  --fc-well:#eef4ef;
  --fc-hair:#b7cdbe;
  /* The large horseshoe glyphs sat at 57-82% saturation inside a 27-39% lightness band,
     so green/amber/red differed by hue alone. Full saturation, each clearing 3.3:1. */
  --fc-good:#008a20;
  /* Orange, not gold (Kenny, 1 Sep). Deeper as well as oranger: 4.95:1 on the
     sheet where the old gold was 4.14 and short of AA. */
  --fc-fair:#946200;
  --fc-poor:#f5001a;
  --fc-hot:#9a3412;
  --fc-cold:#2a6f97;
  --shoe-green:var(--fc-good);
  --shoe-amber:var(--fc-fair);
  --shoe-red:var(--fc-poor);
}
:root:not([data-fc-theme="dark"]) .tt-wrap.fc{
  background:linear-gradient(180deg,#f7faf7 0%,#eef4ef 60%,#e9f0ea 100%) !important;
}

/* ---- shell ---- */
.tt-wrap.fc{
  background:linear-gradient(180deg,#1c3d2a 0%,#0d1f16 60%,#070f0a 100%);
  min-height:100vh;
  /* The wrap owns its inherited ink. Without this, every element the theme does not paint
     explicitly took `html[data-bs-theme="dark"] body`'s #E8E8E8 from the classic shell --
     harmless while that value sits 3% from `--fc-ink-2`, and the same borrowed-ink dependency
     that painted a turtle popover with a colour chosen for a white ground (2 Sep 2026). */
  color:var(--fc-ink-2);
}
/* The shell paints the ground and nothing else.
 *
 * It must NOT restyle text inside unmigrated bodies: those are Bootstrap/Hyper surfaces --
 * white cards, white accordions -- and giving them the shell's light-on-dark ink makes them
 * unreadable. Found on the FAQs page in Phase 0. Text colour arrives with a migrated
 * component, never from the shell.
 *
 * Only elements that opt in with a .tt-* class take turtle ink.
 */
.tt-wrap.fc > .tt-viewbar a,
.tt-wrap.fc .tt-ink{ color:var(--fc-accent); }
.tt-wrap.fc .tt-h1,.tt-wrap.fc .tt-h2,.tt-wrap.fc .tt-h3,.tt-wrap.fc .tt-h4{
  color:var(--fc-ink); font-family:Oswald,system-ui,sans-serif; font-weight:600;
  letter-spacing:.01em;
}
.tt-wrap.fc .tt-body{ color:var(--fc-ink-2); }

/* dark-on-light renders visually thinner than light-on-dark */
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-body,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-h1,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-h2,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-h3,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-h4{ font-weight:500; color:var(--fc-ink); }
/* Dark-on-light renders visually thinner than light-on-dark, so light needs more weight --
   the rule above already does that for prose. The coloured values, bands and badges are
   where "pop" is actually read, and they were left at the inherited weight. */
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .v-g,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .v-a,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .v-r,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-band-g,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-band-a,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-band-r,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-tags .badge,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-sheet .text-success,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-sheet .text-warning,
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-sheet .text-danger{ font-weight:600; }

/* ---- theme and text-size control ---- */
.tt-viewctl{ display:inline-flex; gap:3px; }
.tt-seg{ min-width:32px; padding:5px 8px; line-height:1;
         background:var(--fc-inset); border:1px solid var(--fc-hair);
         color:var(--fc-ink-2); border-radius:4px; cursor:pointer;
         font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-seg:hover{ border-color:var(--fc-accent); color:var(--fc-ink); }
.tt-seg[aria-pressed="true"]{ background:var(--fc-accent); border-color:var(--fc-accent);
                              color:var(--fc-accent-ink); font-weight:700; }
.tt-viewbar{ display:flex; align-items:center; justify-content:flex-end; gap:6px; padding:6px 0; }

@media print{ .tt-viewbar{ display:none !important; } }

/* ---- runner row ----
 * Mobile-first: a stack at 360px, two columns from 768px, one row from 992px. Named grid
 * areas on every child, because a bare column count silently collides when a child is
 * conditionally absent. Structure mirrors /betturtle/preview/fullcard/.
 */
.tt-runner{ background:var(--fc-surface-2); border:1px solid var(--fc-hair);
            border-radius:6px; padding:8px 10px; margin-bottom:6px; }
.tt-runner:nth-of-type(even){ background:var(--fc-zebra); }
.tt-runner.is-won{ box-shadow:inset 4px 0 0 var(--fc-accent); }
.tt-runner.is-top{ border-color:var(--fc-accent); box-shadow:0 0 0 2px var(--fc-line-2); }

/* The horseshoes, the pick number and MORE share the last line on a phone rather than taking
   two (Kenny, 31 Aug). Six columns so `pick`, `pos` and `act` each keep a cell of their own
   while the shoes span the rest; the tiles shrink below to pay for it. */
.tt-r1{ display:grid; gap:8px 10px; align-items:center;
        grid-template-columns:44px 40px 1fr 30px 30px auto;
        grid-template-areas:
          "cloth  silk   name   name  name  odds"
          "people people people people people people"
          "rates  rates  rates  rates rates rates"
          "shoes  shoes  shoes  pick  pos   act"; }

/* The number sits INSIDE the tile so it tilts with it; the draw badge sits outside. */
.tt-cloth{ position:relative; width:44px; height:44px; flex:0 0 44px; }
.tt-tile{ position:absolute; left:2px; top:2px; right:2px; bottom:2px;
          display:flex; align-items:center; justify-content:center;
          transform:rotate(-6deg); border-radius:5px;
          background:var(--fc-accent); color:var(--fc-accent-ink);
          border:2px solid var(--fc-tile-line); box-shadow:2px 3px 6px rgba(0,0,0,.45); }
.tt-tile b{ font-weight:800; line-height:1;
            font-size:max(13px, calc(19px * var(--fc-scale))); }
.tt-draw{ position:absolute; right:-6px; top:-6px; z-index:2;
          min-width:18px; height:18px; padding:0 4px; border-radius:9px;
          display:flex; align-items:center; justify-content:center;
          background:var(--fc-accent); color:var(--fc-accent-ink);
          border:2px solid var(--fc-draw-line); line-height:1; font-style:normal;
          font-size:max(10px, calc(10px * var(--fc-scale))); font-weight:700; }
/* The BADGE keeps the accent whatever the record says (Kenny, 1 Sep). The colour lives in the
   tooltip instead: on the row, red already means a trainer is in form, and a red draw pill beside
   it would have meant the opposite thing an inch away. `is-g`/`is-a`/`is-r` stay on the element
   because the tooltip is drawn from it. */

.tt-silk-slot{ display:flex; width:38px; height:38px; align-items:center; justify-content:center;
               background:var(--fc-inset); border:1px solid var(--fc-hair); border-radius:3px; }
/* No silk, no box: the slot held the row's alignment and drew an empty bordered square for
   every runner without an image. `:not(:has(img))` keeps the space and drops the frame. */
.tt-silk-slot:not(:has(img)){ border-color:transparent !important; background:none !important; }
.tt-silk{ width:38px; height:38px; object-fit:contain; display:block; border-radius:3px; }

.tt-name{ display:block; font-family:Oswald,system-ui,sans-serif; font-weight:600;
          color:var(--fc-ink) !important; text-decoration:none !important; line-height:1.1;
          font-size:max(14px, calc(17px * var(--fc-scale))); cursor:pointer; }
.tt-name:hover{ color:var(--fc-accent) !important; }
.tt-sub{ display:block; color:var(--fc-ink-3); font-family:var(--ct-font-monospace, monospace);
         letter-spacing:.04em; font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-tags{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-top:6px; }
.tt-tag{ border:1px solid var(--fc-line-2); border-radius:3px; padding:1px 6px;
         color:var(--fc-accent); text-transform:uppercase; letter-spacing:.04em; font-weight:600;
         font-size:max(10px, calc(10px * var(--fc-scale))); }
.tt-tag-fit{ color:var(--fc-accent-ink); background:var(--fc-accent); border-color:var(--fc-accent); }
.tt-tag-warn{ color:var(--fc-warn); border-color:var(--fc-warn-line); }

.tt-people{ display:flex; flex-wrap:wrap; gap:2px 14px; color:var(--fc-ink-3);
          margin-top:6px; font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-conn b{ color:var(--fc-ink-2); font-weight:500; }
/* Wrap rather than cut. A trainer or jockey whose name does not fit its column was being
   sliced mid-word; a second line costs nothing here because the row is as tall as the
   horseshoes beside it either way. */
.tt-connline{ display:block; min-width:0; overflow-wrap:anywhere; }

/* OR / FORM / SPEED. The value carries the colour; the rank is a superscript. */
/* Three equal columns at a fixed width: the chips were free-flowing, so OR/FORM/SPEED
   never lined up between rows. Narrower too, which is the other half of the ask. */
/* minmax(0,1fr), not 1fr: a bare 1fr is minmax(AUTO,1fr), so a wide SPEED value pushed its
   track past its share and the whole strip overflowed its grid column onto the horseshoes. */
.tt-rates{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:4px;
           align-items:stretch; margin-bottom:4px; width:100%; min-width:0; }
/* The widest case is a three-figure SPEED carrying an improvement superscript -- "SPEED 104
   11" needs 67px where an equal third of the strip gave 57. The value is the data and keeps
   its size; the label is a caption and gives up the letter-spacing and a little of its width,
   and the chip gives up two pixels of padding. `min-width:0` alone only stops the strip
   overflowing its grid column -- inside the track the text was still being cut. */
.tt-rate{ display:flex; align-items:baseline; justify-content:center; gap:2px; min-width:0;
          background:var(--fc-inset); border:1px solid transparent; border-radius:3px;
          padding:2px 2px; white-space:nowrap; cursor:pointer; color:var(--fc-ink);
          font-family:var(--ct-font-monospace, monospace);
          font-size:max(11px, calc(14px * var(--fc-scale))); }
.tt-rate:hover{ border-color:var(--fc-accent); }
.tt-rate span:not(.tt-ratefig){ color:var(--fc-ink-3); letter-spacing:0;
               font-size:max(9px, calc(8.5px * var(--fc-scale))); }
.tt-rate sup{ color:var(--fc-accent); font-size:max(10px, calc(9px * var(--fc-scale))); }
.tt-rate b{ font-weight:700; }
.tt-wrap.fc .v-g{ color:var(--fc-val-g); }
.tt-wrap.fc .v-a{ color:var(--fc-val-a); }
.tt-wrap.fc .v-r{ color:var(--fc-val-r); }
.tt-wrap.fc .v-n{ color:var(--fc-ink); }

/* Trainer and jockey flags. Each carries its own word, never colour alone. */
.tt-flags{ display:inline-flex; flex-wrap:wrap; gap:4px; margin-left:6px; vertical-align:middle; }
.tt-flag{ display:inline-flex; align-items:center; gap:3px; border-radius:3px; padding:0 5px;
          border:1px solid currentColor; text-transform:uppercase; letter-spacing:.03em;
          font-weight:600; font-size:max(10px, calc(9.5px * var(--fc-scale))); }
.tt-flag em{ font-style:normal; }
.tt-flag-hot{ color:var(--fc-hot); }
.tt-flag-cold{ color:var(--fc-cold); }
.tt-flag-mark{ color:var(--fc-accent); }

.tt-r3{ margin-top:8px; }
.tt-shoes{ display:grid; grid-template-columns:repeat(5,1fr); gap:4px; }
.tt-cellwrap{ text-align:center; background:none; border:0; padding:0; cursor:pointer; }
.tt-cellwrap small{ display:block; margin-top:2px; color:var(--fc-ink-3);
                    text-transform:uppercase; letter-spacing:.05em;
                    font-size:max(10px, calc(9px * var(--fc-scale))); }
.tt-cell{ display:flex; align-items:center; justify-content:center; position:relative;
          height:42px; border-radius:3px; background:var(--fc-inset); }
.tt-cell.g{ background:var(--fc-cell-g); } .tt-cell.a{ background:var(--fc-cell-a); }
.tt-cell.r{ background:var(--fc-cell-r); } .tt-cell.n{ background:var(--fc-inset); }
.tt-cell i{ font-size:max(16px, calc(22px * var(--fc-scale)));
            filter:drop-shadow(1px 2px 2px rgba(0,0,0,.5)); }
.tt-cell.g i{ color:var(--fc-good); } .tt-cell.a i{ color:var(--fc-fair); }
.tt-cell.r i{ color:var(--fc-poor); } .tt-cell.n i{ color:var(--fc-ink-3); opacity:.35; }
/* The letter stands in for the horseshoe, so it takes the horseshoe's size and the band's
   own ink. A 9px mark laid over a 22px glyph was the affordance without the legibility. */
.tt-letter{ font-weight:800; line-height:1; font-family:Oswald,system-ui,sans-serif;
            font-size:max(15px, calc(20px * var(--fc-scale))); }
.tt-cell.g .tt-letter{ color:var(--fc-val-g); } .tt-cell.a .tt-letter{ color:var(--fc-val-a); }
.tt-cell.r .tt-letter{ color:var(--fc-val-r); }
.tt-cell.n .tt-letter{ color:var(--fc-ink-3); }

.tt-odds{ display:inline-block; border:2px solid var(--fc-chip-line); border-radius:3px;
          background:var(--fc-chip-bg); color:var(--fc-chip-ink); padding:1px 9px;
          font-weight:600; white-space:nowrap; font-variant-numeric:tabular-nums;
          font-size:max(12px, calc(15px * var(--fc-scale))); }

/* Pick rank is a bare number in a box, as the prototype has it. */
.tt-pick{ display:inline-flex; align-items:center; justify-content:center;
          min-width:26px; padding:1px 6px; border-radius:3px;
          border:2px solid var(--fc-hair); background:var(--fc-inset); color:var(--fc-ink);
          font-weight:700; font-variant-numeric:tabular-nums;
          font-size:max(12px, calc(14px * var(--fc-scale))); }

.tt-place{ display:inline-flex; flex-direction:column; align-items:center; gap:1px; }
.tt-rosette{ width:42px; height:42px; filter:drop-shadow(0 1px 2px rgba(0,0,0,.45)); }
.tt-pos{ color:var(--fc-ink); letter-spacing:.01em; font-weight:600;
         font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-place .tt-pos{ line-height:1; }
/* `.tt-wrap.fc .tt-pos` carries three classes and these carried two, so NONE of the three
   placings had ever taken its colour -- the silver and bronze were dead on arrival too. */
.tt-wrap.fc .tt-place.is-1 .tt-pos{ color:var(--fc-first-ink); }
.tt-wrap.fc .tt-place.is-2 .tt-pos{ color:var(--fc-medal-2); }
.tt-wrap.fc .tt-place.is-3 .tt-pos{ color:var(--fc-medal-3); }

.tt-actcell{ display:flex; align-items:center; justify-content:center; gap:6px; }
.tt-heart .btn{ color:var(--fc-ink-3) !important; }
.tt-heart:has(.fas) .btn{ color:var(--fc-poor) !important; }
/* The bin, like the heart. Without this it keeps Hyper's #313a46 in both themes, which on
   the dark row ground is dark on dark. */
.tt-a-hide .btn{ color:var(--fc-ink-3) !important; }
.tt-more{ background:transparent; border:0; color:var(--fc-accent); cursor:pointer;
          font-weight:600; letter-spacing:.04em; text-transform:uppercase; padding:6px 0 0;
          font-size:max(11px, calc(12px * var(--fc-scale))); }

@media (min-width:768px) and (max-width:991.98px){
  .tt-r1{ grid-template-columns:46px 42px minmax(0,1fr) 118px 126px;
          grid-template-areas:
            "cloth  silk   name   odds   pos"
            "people people people people act"
            "rates  rates  rates  rates  act"
            "shoes  shoes  shoes  shoes  pick"; }
}

@media (min-width:992px){
  .tt-runner{ border-radius:0; border-left:0; border-right:0; border-top:0; margin-bottom:0; }
  /* `rates` is a FIXED width of three equal columns, so OR/FORM/SPEED line up as columns
     down the whole card. Trainer and jockey sit to their left in `people`, which is where
     the reading eye expects the horse's connections.

     One row only above 1400px. The widest chip is a three-figure SPEED carrying an
     improvement superscript, and a strip wide enough for it does not fit beside everything
     else below that -- squeezing it clipped the figure, and widening it pushed the row past
     its own width. Under 1400 the strip takes a line of its own instead, which is the only
     arrangement where nothing is cut. */
  .tt-r1{ grid-template-columns:46px 42px minmax(150px,1.3fr) minmax(150px,1fr) 290px 46px 118px 62px 86px;
          grid-template-areas:
            "cloth silk  name  people shoes pick odds pos act"
            "rates rates rates rates  shoes pick odds pos act"; }
  .tt-rates{ margin-bottom:0; }
}

@media (min-width:1400px){
  .tt-r1{ grid-template-columns:46px 42px minmax(170px,1.4fr) minmax(160px,1fr) minmax(212px,232px) 270px 46px 118px 62px 86px;
          grid-template-areas:"cloth silk name people rates shoes pick odds pos act"; }
  .tt-rates{ margin-bottom:4px; }
  .tt-people{ flex-direction:column; flex-wrap:nowrap; gap:2px; margin-top:0; }
  .tt-r3{ margin-top:0; }
  .tt-cellwrap small{ display:none; }
  /* Across, not down. Stacked, the heart, bin and menu made every row a line taller than
     its content needed -- eighteen runners paying for it. More wraps underneath. */
  .tt-actcell{ flex-direction:row; flex-wrap:wrap; gap:2px 6px; }
  .tt-actcell .tt-more{ flex:0 0 100%; text-align:center; }
}

/* ---- race header ---- */
.tt-card{ padding:8px 0 24px; }
.tt-head{ background:var(--fc-head-bg); border:2px solid var(--fc-hair);
          border-radius:6px; padding:12px 14px; margin-bottom:10px; }
.tt-head .tt-h1{ margin:0; font-size:max(20px, calc(26px * var(--fc-scale))); }
/* The race name and the control that folds everything under it. The arrow is on the left, so
   it reads as belonging to the whole block rather than to the last thing on the line. */
.tt-headline{ display:flex; align-items:center; gap:8px; }
.tt-headtoggle{ appearance:none; cursor:pointer; flex:0 0 auto; line-height:1;
          background:transparent; border:1px solid var(--fc-hair); border-radius:4px;
          color:var(--fc-ink-2); padding:3px 7px;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-headtoggle:hover{ border-color:var(--fc-accent); color:var(--fc-ink); }
.tt-headtoggle i{ display:block; transition:transform .12s ease; }
.tt-headtoggle[aria-expanded="false"] i{ transform:rotate(-90deg); }
.tt-head.is-shut .tt-headbody{ display:none; }
/* The whole thing is on the printed page whatever the screen was doing. */
@media print{ .tt-headtoggle{ display:none; }
              .tt-head.is-shut .tt-headbody{ display:block; } }
.tt-title{ margin:2px 0 8px; font-size:max(13px, calc(15px * var(--fc-scale))); }
.tt-chips{ display:flex; flex-wrap:wrap; gap:6px; }
.tt-chip{ border:2px solid var(--fc-hair); border-radius:4px; padding:2px 8px;
          background:var(--fc-inset); color:var(--fc-ink-2); font-weight:600;
          font-size:max(11px, calc(12px * var(--fc-scale))); }

/* ---- drawer ---- */
.tt-drawer{ display:none; margin-top:10px; padding-top:10px;
            border-top:1px solid var(--fc-hair); }
.tt-runner.is-open .tt-drawer{ display:block; }
.tt-more{ background:transparent; border:0; cursor:pointer; color:var(--fc-accent);
          font-size:max(11px, calc(12px * var(--fc-scale))); padding:2px 4px; }
.tt-more:hover{ text-decoration:underline; }

.tt-dtabs{ display:flex; flex-wrap:wrap; gap:4px; margin:0 0 10px; padding-bottom:8px;
           border-bottom:1px solid var(--fc-hair); }
.tt-dtab{ background:transparent; border:1px solid var(--fc-hair); border-radius:4px;
          color:var(--fc-ink-3); padding:4px 10px; cursor:pointer;
          font-family:Oswald,system-ui,sans-serif; text-transform:uppercase;
          letter-spacing:.05em; font-size:max(11px, calc(11.5px * var(--fc-scale))); }
.tt-dtab:hover{ border-color:var(--fc-accent); color:var(--fc-ink); }
.tt-dtab[aria-selected="true"]{ background:var(--fc-accent); border-color:var(--fc-accent);
                                color:var(--fc-accent-ink); font-weight:700; }
.tt-dpane[hidden]{ display:none; }

.tt-why-row{ display:grid; grid-template-columns:38px 1fr; gap:10px; align-items:start;
             padding:6px 0; border-bottom:1px solid var(--fc-hair); }
.tt-why-h{ margin:0 0 3px; color:var(--fc-accent); text-transform:uppercase;
           letter-spacing:.06em; font-family:Oswald,system-ui,sans-serif;
           font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-why-p{ margin:0; line-height:1.55; font-size:max(12px, calc(13px * var(--fc-scale))); }

.tt-sixline{ padding:3px 0; color:var(--fc-ink-2);
             font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-sixline b{ color:var(--fc-ink-3); font-weight:600; margin-right:6px; }

.tt-facts{ display:grid; grid-template-columns:auto 1fr; gap:3px 14px; margin:6px 0 0;
           font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-facts dt{ color:var(--fc-ink-3); font-weight:500; }
.tt-facts dd{ color:var(--fc-ink); font-weight:600; margin:0;
              font-variant-numeric:tabular-nums; }
@media (min-width:700px){ .tt-facts{ grid-template-columns:auto minmax(70px,1fr) auto minmax(70px,1fr);
                                     column-gap:22px; } }

/* Connections sit under the five factors in the Why tab, so they need a rule between
   them: one pane, two subjects. */
.tt-connections{ margin-top:12px; padding-top:10px; border-top:1px solid var(--fc-hair); }
.tt-connections .tt-subnav{ margin-top:10px; }
.tt-people{ display:grid; gap:8px; }
@media (min-width:768px){ .tt-people{ grid-template-columns:1fr 1fr; } }
.tt-person{ background:var(--fc-inset); border-radius:5px; padding:8px 10px; }
.tt-person-head{ color:var(--fc-ink); font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-person-head b{ color:var(--fc-accent); }
.tt-flag{ display:inline-flex; align-items:center; gap:3px; margin-left:5px;
          border:1px solid currentColor; border-radius:3px; padding:0 4px;
          font-size:max(10px, calc(10.5px * var(--fc-scale))); font-weight:600;
          text-transform:uppercase; letter-spacing:.03em; }
.tt-flag-hot{ color:var(--fc-hot); } .tt-flag-cold{ color:var(--fc-cold); }
.tt-flag-mark{ color:var(--fc-accent); }

/* Red in form, blue out of form: the pair the classic card has always used, white on both, so
   it reads the same in either theme -- 6.9:1 and 5.5:1. Read by `.tt-connname` and
   `.tt-hcname`. */
:root{ --fc-hc-hot-bg:#b0202c; --fc-hc-cold-bg:#2a6f97; --fc-hc-ink:#ffffff; }

.tt-comment{ margin:8px 0 0; line-height:1.55;
             font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-statnote{ color:var(--fc-ink-3); margin:4px 0 0;
              font-size:max(11px, calc(11.5px * var(--fc-scale))); }

/* ---- stat packs ---- */
.tt-subnav{ display:flex; flex-wrap:wrap; gap:4px; margin-bottom:10px; }
.tt-subbtn{ display:inline-flex; align-items:center; gap:5px; background:var(--fc-inset);
            border:1px solid var(--fc-hair); border-radius:4px; color:var(--fc-ink-2);
            padding:4px 9px; cursor:pointer;
            font-size:max(11px, calc(11.5px * var(--fc-scale))); }
.tt-subbtn i{ color:var(--fc-ink-3); }
.tt-subbtn:hover:not(:disabled){ border-color:var(--fc-accent); color:var(--fc-ink); }
/* Disabled says "nothing recorded for this runner", so it still has to be readable: .35
   opacity measured 2.8:1. The dashed border and the cursor carry the state instead. */
.tt-subbtn:disabled{ opacity:1; color:var(--fc-ink-3); border-style:dashed; cursor:default; }
.tt-subbtn:disabled i{ color:var(--fc-ink-3); }
.tt-subbtn.is-lit{ background:var(--fc-accent); border-color:var(--fc-accent);
                   color:var(--fc-accent-ink); font-weight:600; }
.tt-subbtn.is-lit i{ color:var(--fc-accent-ink); }
.tt-statpack{ display:none; background:var(--fc-surface); border-left:3px solid var(--fc-accent);
              border-radius:0 5px 5px 0; padding:8px 12px; }
.tt-statpack.is-open{ display:block; }

/* The VALUE inks, not the glyph ones. --fc-good/fair/poor are tuned for the large horseshoe
   and fail AA as ~14px text; --fc-val-* exist for exactly this size and are tuned per theme. */
.tt-band{ font-variant-numeric:tabular-nums; }
.tt-band-g{ color:var(--fc-val-g); } .tt-band-a{ color:var(--fc-val-a); }
.tt-band-r{ color:var(--fc-val-r); }
.qs-off-stat_colour .tt-band{ color:var(--fc-ink) !important; }

/* ---- charts ---- */
.tt-chart{ margin:0 0 10px; }
.tt-chart figcaption{ color:var(--fc-ink-3); margin-bottom:4px;
                      font-size:max(11px, calc(11px * var(--fc-scale))); }
.tt-chart svg{ display:block; overflow:visible; }
.tt-chart-line{ fill:none; stroke-width:1.6; opacity:.85;
                vector-effect:non-scaling-stroke; stroke-linejoin:round; }
.tt-chart-dot{ vector-effect:non-scaling-stroke; }
.tt-chart-win{ fill:none; stroke:var(--fc-ink); stroke-width:1.6;
               vector-effect:non-scaling-stroke; }
.tt-chart-key{ display:flex; flex-wrap:wrap; gap:4px 12px; margin-top:5px;
               color:var(--fc-ink-3); font-size:max(10px, calc(11px * var(--fc-scale))); }
.tt-chart-key i{ display:inline-block; width:9px; height:9px; border-radius:2px;
                 margin-right:4px; }
.tt-chart-key b{ color:var(--fc-ink-2); }

@media print{ .tt-dtabs, .tt-subnav, .tt-more{ display:none !important; }
              .tt-drawer, .tt-dpane, .tt-statpack{ display:block !important; } }

/* ---- race brief ---- */
.tt-briefbar{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 10px; }
.tt-brief-chip{ display:inline-flex; align-items:center; gap:7px; cursor:pointer;
                background:var(--fc-surface); border:1px solid var(--fc-line-2);
                border-radius:6px; padding:7px 12px; color:var(--fc-ink-2);
                font-family:Oswald,system-ui,sans-serif; text-transform:uppercase;
                letter-spacing:.04em;
                font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-brief-chip i{ color:var(--fc-accent); }
.tt-brief-chip em{ font-style:normal; text-transform:none; letter-spacing:0;
                   color:var(--fc-ink-3);
                   font-size:max(10px, calc(11px * var(--fc-scale))); }
.tt-brief-chip:hover{ border-color:var(--fc-accent); color:var(--fc-ink); }
.tt-brief-chip[aria-expanded="true"]{ background:var(--fc-accent); border-color:var(--fc-accent);
                                      color:var(--fc-accent-ink); font-weight:700; }
.tt-brief-chip[aria-expanded="true"] i,
.tt-brief-chip[aria-expanded="true"] em{ color:var(--fc-accent-ink); }
.tt-brief [data-tt-briefpane]{ display:none; }
.tt-brief [data-tt-briefpane].is-open{ display:block; }

.tt-panel{ background:var(--fc-surface); border-left:4px solid var(--fc-accent);
           border-radius:0 6px 6px 0; padding:12px 14px; margin-bottom:10px; }
.tt-panel-h{ display:flex; align-items:center; gap:7px; margin:0 0 8px;
             color:var(--fc-accent); text-transform:uppercase; letter-spacing:.05em;
             font-family:Oswald,system-ui,sans-serif;
             font-size:max(12px, calc(15px * var(--fc-scale))); }
.tt-verdict{ border-top:1px solid var(--fc-hair); padding-top:8px; margin-top:8px; }
.tt-notes{ display:grid; gap:5px; margin-top:8px; }
.tt-note{ color:var(--fc-ink-2); font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-note b{ color:var(--fc-accent); font-weight:600; }

.tt-rp-grid{ display:grid; gap:8px; grid-template-columns:1fr; margin:8px 0; }
@media (min-width:640px){ .tt-rp-grid{ grid-template-columns:repeat(3,1fr); } }
.tt-rp-stat{ background:var(--fc-inset); border-radius:5px; padding:8px 10px; }
.tt-rp-stat b{ display:block; color:var(--fc-ink); font-family:Oswald,system-ui,sans-serif;
               font-size:max(16px, calc(20px * var(--fc-scale))); }
.tt-rp-stat span{ color:var(--fc-ink-3); text-transform:uppercase; letter-spacing:.05em;
                  font-size:max(10px, calc(10.5px * var(--fc-scale))); }
/* Settings as a grid of options rather than a wrapped line of checkboxes.
   Crispy emits `.row > .col-auto > .mb-3 > .form-check`, so the grid goes on the row and
   each option becomes a card: tick, name, and the help text that was already there but read
   as a footnote to whatever sat beside it. Scoped to the two places settings are rendered,
   not to `.tt-sheet`, so no other reused Bootstrap form is restyled by accident. */
.tt-wrap.fc .tt-quicksettings .accordion-body .row,
.tt-wrap.fc .tt-settings .accordion-body .row,
.tt-wrap.fc .tt-quicksettings .accordion-body,
.tt-wrap.fc .tt-settings .accordion-body{ display:grid; gap:6px; margin:0;
          grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); }
/* Crispy emits several Rows per section. Dissolving them lets every option in a section
   flow into ONE grid, instead of each Row being its own and leaving a section ragged. */
.tt-wrap.fc .tt-quicksettings .accordion-body > .row,
.tt-wrap.fc .tt-settings .accordion-body > .row{ display:contents; }
/* Flex the whole way down so every card fills its cell: without it a two-line help text
   makes one card taller than the row and the grid reads as ragged. */
.tt-wrap.fc .tt-quicksettings .accordion-body .row > [class*="col"],
.tt-wrap.fc .tt-settings .accordion-body .row > [class*="col"]{ width:auto; max-width:none;
          padding:0; display:flex; }
.tt-wrap.fc .tt-quicksettings .accordion-body .row .mb-3,
.tt-wrap.fc .tt-settings .accordion-body .row .mb-3{ margin-bottom:0 !important;
          display:flex; flex:1; }

.tt-wrap.fc .tt-quicksettings .form-check,
.tt-wrap.fc .tt-settings .form-check{ display:grid; grid-template-columns:auto 1fr;
          gap:2px 9px; align-content:start; align-items:baseline; flex:1;
          padding:8px 10px; margin:0;
          background:var(--fc-inset); border:1px solid var(--fc-hair); border-radius:5px; }
.tt-wrap.fc .tt-quicksettings .form-check:hover,
.tt-wrap.fc .tt-settings .form-check:hover{ background:var(--fc-hover); }
/* The box is there at rest in BOTH themes -- an unticked option on the dark ground had only
   a 5%-white tint to show for itself and read as having no box at all. Ticked brightens it. */
.tt-wrap.fc .tt-quicksettings .form-check:has(:checked),
.tt-wrap.fc .tt-settings .form-check:has(:checked){ border-color:var(--fc-line-2); }

.tt-wrap.fc .tt-quicksettings .form-check .form-check-input,
.tt-wrap.fc .tt-settings .form-check .form-check-input{ margin:0; float:none; }
.tt-wrap.fc .tt-quicksettings .form-check-label,
.tt-wrap.fc .tt-settings .form-check-label{ color:var(--fc-ink); font-weight:600;
          cursor:pointer; font-size:max(12px, calc(13px * var(--fc-scale))); }
/* The help text sits under the name, in the name's column -- not under the tick. */
.tt-wrap.fc .tt-quicksettings .form-check .form-text,
.tt-wrap.fc .tt-settings .form-check .form-text{ grid-column:2; margin:2px 0 0;
          color:var(--fc-ink-3); font-size:max(11px, calc(11.5px * var(--fc-scale)));
          line-height:1.4; }

/* A toolbar item that states a fact rather than offering an action. */
.tt-wrap.fc .tt-tool.is-inert{ cursor:default; color:var(--fc-ink-3);
          border-style:dashed; background:transparent; }
.tt-wrap.fc .tt-tool.is-inert:hover{ background:transparent; border-color:var(--fc-hair); }

/* View modes. Cards rather than a select, because each one has to say what it will switch
   off before the customer presses it. */
.tt-wrap.fc .tt-viewmodes{ margin-bottom:14px; padding-bottom:12px;
          border-bottom:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-modegrid,
.tt-wrap.fc .tt-settings .tt-modegrid{ display:grid; gap:6px; margin-top:8px;
          grid-template-columns:repeat(auto-fill, minmax(230px, 1fr)); }
.tt-wrap.fc .tt-mode{ display:flex; flex-direction:column; gap:3px; text-align:left;
          background:var(--fc-inset); border:1px solid var(--fc-hair); border-radius:5px;
          padding:9px 11px; cursor:pointer; color:var(--fc-ink-2);
          font-size:max(12px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-mode:hover{ background:var(--fc-hover); border-color:var(--fc-accent); }
/* Where the customer is now. Marked by a border and a word, never colour alone. */
.tt-wrap.fc .tt-mode.is-current{ border-color:var(--fc-accent); background:var(--fc-hover); }
/* The accent on the is-current ground is 4.46:1 at 12.65px -- under the floor. The border
   and the tinted background already say which mode this is; the text does not have to. */
.tt-wrap.fc .tt-mode.is-current em{ color:var(--fc-ink); font-weight:600; }
.tt-wrap.fc .tt-modenow{ margin-top:6px; }
.tt-wrap.fc .tt-mode b{ color:var(--fc-ink); font-size:max(12px, calc(13px * var(--fc-scale))); }
/* ink-3 is the faintest of the three and measured 4.46:1 here in dark -- under the floor by
   four hundredths, at 12.7px and semibold, which is small enough that it has to clear it. */
.tt-wrap.fc .tt-mode em{ color:var(--fc-ink-2); font-style:normal;
          font-size:max(10px, calc(11px * var(--fc-scale))); }

/* Filter chips above the run-by-run tables. Reuses the stat-pack sub-nav so it reads as the
   same kind of control, with the count of what is left beside it. */
.tt-wrap.fc .tt-formfilter{ margin:10px 0 6px; align-items:center; }
.tt-wrap.fc .tt-formfilter-count{ margin-left:4px; white-space:nowrap; }

/* The customer's own comment on a horse. The label follows the tag's own icon state -- a
   solid message means one is already written -- exactly as the heart and bin labels do. */
.tt-wrap.fc .tt-a-comment .fa-message{ color:var(--fc-ink-3); }
/* Test the MESSAGE icon, not any solid glyph in the subtree: the panel's own close button
   is a fa-solid xmark, so a bare :has(.fa-solid) matched it the moment the panel opened --
   both halves of the label hid and the icon sat there unnamed. */
.tt-wrap.fc .tt-a-comment:has(.fa-message.fa-solid) .fa-message{ color:var(--fc-accent); }
.tt-wrap.fc .tt-a-comment:has(.fa-message.fa-solid) .tt-off,
.tt-wrap.fc .tt-a-comment:has(.fa-message.fa-regular) .tt-on{ display:none; }
/* The tag's own collapse panel is written for a white card in a Bootstrap column: a giant
   white slab with a Bootstrap-primary Submit. It opens on its own line under the actions,
   at a readable width, with the controls carrying the theme's own tokens.

   flex-wrap belongs on the CONTAINER. Setting it on the item -- which is what this did first
   -- wraps that item's own children and leaves the panel squeezed alongside the buttons,
   which is exactly how it shipped. */
.tt-wrap.fc .tt-commentacts{ flex-wrap:wrap; }
/* `display:contents` when open, so the span's children become items of the actions row
   itself: the icon and its label stay exactly where they were and only the panel wraps.
   Making the SPAN full-width instead -- which is what this did first -- moved the button
   down a line the moment it was pressed, which is a control running away from the cursor.
   The span's own styling has to be re-applied to the children, since it no longer has a box. */
.tt-wrap.fc .tt-a-comment:has(.collapse.show){ display:contents; }
.tt-wrap.fc .tt-a-comment:has(.collapse.show) > a,
.tt-wrap.fc .tt-a-comment:has(.collapse.show) > .tt-actlbl{
          color:var(--fc-ink-3); font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-a-comment .collapse{ flex:1 0 100%; width:100%; order:2; }
/* The tag emits the icon, then the panel, then our label -- so once the span wraps, the
   label lands UNDER the panel, away from the icon it names. Visual order only; the DOM
   order is the shared template's and stays as it is. */
.tt-wrap.fc .tt-a-comment .tt-actlbl{ order:1; }
.tt-wrap.fc .tt-a-comment .card{ background:var(--fc-inset) !important;
          border:1px solid var(--fc-hair) !important; border-radius:8px;
          margin-top:8px; box-shadow:none !important; max-width:560px; }
.tt-wrap.fc .tt-a-comment .card-body{ padding:10px 12px; position:relative; }
.tt-wrap.fc .tt-a-comment .card-title{ color:var(--fc-ink) !important; margin:0 0 8px;
          font-size:max(12px, calc(13px * var(--fc-scale))); font-weight:600; }

/* The controls. Crispy renders `form-control` and `btn btn-primary`, both written for a
   white page -- on this ground that is a white slab and an indigo button. */
/* The field needs its own token, because neither existing one works in both themes: in dark
   --fc-surface is rgba(0,0,0,.24) against a .22 card, two per cent apart, so the input reads
   as a bordered gap; in light --fc-well and --fc-inset are the SAME colour, so the input
   disappears into the card. Declared dark-first like the rest of this file, with the light
   value in the :not([data-fc-theme="dark"]) override. */
.tt-wrap.fc .tt-a-comment{ --tt-field:var(--fc-well); }
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-a-comment{ --tt-field:var(--fc-surface); }
.tt-wrap.fc .tt-a-comment textarea.form-control{ width:100%; height:104px; resize:vertical;
          background:var(--tt-field) !important; color:var(--fc-ink) !important;
          border:1px solid var(--fc-line) !important; border-radius:6px; padding:8px 10px;
          font-size:max(12px, calc(13px * var(--fc-scale))); line-height:1.5;
          box-shadow:none !important; }
.tt-wrap.fc .tt-a-comment textarea.form-control::placeholder{ color:var(--fc-ink-3); }
.tt-wrap.fc .tt-a-comment textarea.form-control:focus{ border-color:var(--fc-accent) !important;
          outline:2px solid color-mix(in srgb, var(--fc-accent) 40%, transparent);
          outline-offset:1px; }
.tt-wrap.fc .tt-a-comment .btn{ border-radius:6px; padding:6px 14px; box-shadow:none;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); font-weight:600; }
.tt-wrap.fc .tt-a-comment .btn-primary{ background:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; color:var(--fc-accent-ink) !important; }
.tt-wrap.fc .tt-a-comment .btn-danger{ background:transparent !important;
          border-color:var(--fc-line) !important; color:var(--fc-val-r) !important; }
.tt-wrap.fc .tt-a-comment .btn + .btn{ margin-left:8px; }
.tt-wrap.fc .tt-a-comment .messages{ margin-top:8px; color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }

/* Beside the heading, not off at the far edge of a full-width panel. */
.tt-wrap.fc .tt-commentclose{ position:absolute; top:8px; right:10px; z-index:1;
          border:1px solid var(--fc-hair); background:var(--fc-surface); cursor:pointer;
          color:var(--fc-ink-2); border-radius:6px; line-height:1; padding:4px 7px;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-commentclose:hover{ color:var(--fc-ink); border-color:var(--fc-line); }

/* Form sections. Native <details>, so the disclosure is the browser's and works without
   script; the marker is ours because the default triangle sits oddly against a heading. */
.tt-wrap.fc .tt-fsec{ border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-fsec:first-of-type{ border-top:0; }
.tt-wrap.fc .tt-fsec > summary{ display:flex; align-items:center; gap:8px; cursor:pointer;
          padding:9px 2px; color:var(--fc-ink); font-weight:600; list-style:none;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-fsec > summary::-webkit-details-marker{ display:none; }
.tt-wrap.fc .tt-fsec > summary > i{ color:var(--fc-ink-3); width:1.1em; text-align:center; }
/* A real <i>, not a pseudo-element with a hard-coded glyph: the family name was "Font
   Awesome 6 Pro" and this project self-hosts 7, so the chevron rendered as a tofu square. An
   element cannot drift from the font the rest of the card uses. */
/* A right-pointing chevron that swings down when the section opens: the shape people read as
   "there is more behind this". It sat at the far right of the row in --fc-ink-3, a muted
   green-grey, and it was pointing DOWN when closed -- so it read as decoration on the heading
   rather than a control, and Kenny asked for an arrow that had been there all along. It sits
   beside the label now, in the accent, at the size of the text. */
/* `> summary > i` two rules up is (0,3,2) and this was (0,3,0), so the caret kept the muted
   ink meant for the section's leading icon. Matched on the element as well, for the same
   reason the sheet's link default now uses :where(): a rule has to be able to lose. */
.tt-wrap.fc .tt-fsec > summary > i.tt-fsec-caret{ color:var(--fc-accent); font-size:.9em;
          transition:transform .15s ease; }
.tt-wrap.fc .tt-fsec[open] > summary .tt-fsec-caret{ transform:rotate(90deg); }
.tt-wrap.fc .tt-fsec > summary:hover{ color:var(--fc-accent); }
.tt-wrap.fc .tt-fsec-body{ padding-bottom:10px; }
/* The Horse Intel fragment is written for the white popover it used to live in: a 340px box
   with Bootstrap `.small` throughout. In a drawer section it is body copy, so it reads at the
   size everything around it does. */
.tt-wrap.fc .tt-hintel .bg-light{ background:var(--fc-inset) !important; }
.tt-wrap.fc .tt-hintel > div{ max-width:none !important; }
.tt-wrap.fc .tt-hintel h5{ font-size:max(13px, calc(14px * var(--fc-scale))); }
.tt-wrap.fc .tt-hintel,
.tt-wrap.fc .tt-hintel .small,
.tt-wrap.fc .tt-hintel small{ font-size:max(12px, calc(13px * var(--fc-scale))); }

/* Weather chip in the race header. It opens the racecourse guide, where the Open-Meteo
   attribution is written out in full. */
.tt-wrap.fc .tt-chip-weather{ display:inline-flex; align-items:baseline; gap:5px; }
.tt-wrap.fc .tt-chip-weather .tt-sub{ color:var(--fc-ink-3); }
.tt-wrap.fc .tt-chip-rain{ display:inline-flex; align-items:baseline; gap:3px;
          color:var(--fc-val-a); font-weight:600; }

/* An icon inside a settings label, so the toggle shows the marker it controls. */
.tt-wrap.fc .bt-optionicon{ color:var(--fc-ink-3); margin-right:2px; width:1.1em;
          text-align:center; }
.tt-wrap.fc .form-check:has(:checked) .bt-optionicon{ color:var(--fc-accent); }

/* Winner traits. The arrow and the lift both carry the direction, so the colour is not the
   only encoding. "Against" means winners showed it LESS often than the field. */
.tt-traits{ list-style:none; margin:6px 0 4px; padding:0; display:grid; gap:5px; }
.tt-trait{ display:grid; grid-template-columns:auto 1fr auto; gap:8px; align-items:baseline;
           background:var(--fc-inset); border-radius:5px; padding:6px 9px;
           font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-trait > i{ color:var(--fc-val-g); }
.tt-trait.is-against > i{ color:var(--fc-val-r); }
.tt-trait-say{ color:var(--fc-ink-2); }
.tt-trait-say b{ color:var(--fc-ink); font-variant-numeric:tabular-nums; }
.tt-trait-lift{ color:var(--fc-ink-3); font-variant-numeric:tabular-nums; font-weight:600;
                white-space:nowrap; }
.tt-trait.is-against .tt-trait-lift{ color:var(--fc-val-r); }

.tt-checkrow{ display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
.tt-check{ display:inline-flex; align-items:center; gap:5px;
           background:var(--fc-check-bg, rgba(166,206,57,.16)); color:var(--fc-check-ink, #cfe9a8);
           border-radius:4px; padding:3px 8px;
           font-size:max(11px, calc(12px * var(--fc-scale))); }

/* ---- tables ---- */
.tt-tablewrap{ overflow-x:auto; -webkit-overflow-scrolling:touch;
               border:1px solid var(--fc-line-2); border-radius:6px; }
.tt-table{ width:100%; border-collapse:collapse; white-space:nowrap;
           font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-table th{ position:sticky; top:0; background:var(--fc-thead); color:var(--fc-on-thead, var(--fc-accent));
              padding:6px 8px; text-align:center; text-transform:uppercase;
              letter-spacing:.06em; font-weight:700;
              font-size:max(10px, calc(10.5px * var(--fc-scale))); }
.tt-table td{ padding:6px 8px; text-align:center; font-weight:500;
              color:var(--fc-ink-2); border-top:1px solid var(--fc-hair); }
.tt-table th.l, .tt-table td.l{ text-align:left; }
.tt-table tbody tr:nth-child(odd){ background:var(--fc-zebra); }
.tt-year{ font-weight:700; color:var(--fc-ink); }
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-table th{ color:#fff; }
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-table td{ color:#12241a; }

@media print{ .tt-briefbar{ display:none !important; }
              .tt-brief [data-tt-briefpane]{ display:block !important; } }

/* ---- toolbar and filters ---- */
.tt-bar{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 14px; margin:0 0 10px; }
/* Two groups: what the runner list shows, and the utilities. The gap between them is the
   only thing saying they do different jobs, so it has to survive a narrow viewport. */
.tt-bargroup{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.tt-barutils{ margin-left:auto; }
@media (max-width:720px){ .tt-barutils{ margin-left:0; } }
/* !important on the ink: .tt-tool is often an <a>, and the classic sheet's
   html[data-bs-theme="dark"] a:not(.btn):not(.nav-link):not(.dropdown-item) is (0,4,2),
   which beat this and rendered the filter bar's link at 1.15:1 on its own ground. */
.tt-tool{ background:var(--fc-inset); border:1px solid var(--fc-hair); border-radius:4px;
          color:var(--fc-ink-2) !important; padding:6px 12px; cursor:pointer;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-tool:hover{ border-color:var(--fc-accent); color:var(--fc-ink) !important; }
.tt-tool.is-on{ background:var(--fc-accent); border-color:var(--fc-accent);
                color:var(--fc-accent-ink) !important; font-weight:700; }
.tt-tool.is-go{ background:var(--fc-accent); border-color:var(--fc-accent);
                color:var(--fc-accent-ink) !important; font-weight:700; }

.tt-filters{ background:var(--fc-well); border:1px solid var(--fc-line-2);
             border-radius:6px; padding:14px 16px; margin-bottom:12px; }
.tt-filters[hidden]{ display:none; }
.tt-filter-grid{ display:grid; gap:10px; grid-template-columns:1fr; }
@media (min-width:576px){ .tt-filter-grid{ grid-template-columns:repeat(2,1fr); } }
@media (min-width:992px){ .tt-filter-grid{ grid-template-columns:repeat(4,1fr); } }
.tt-filter{ display:flex; flex-direction:column; gap:5px; padding:8px 10px;
            background:var(--fc-inset); border:1px solid var(--fc-hair); border-radius:5px; }
.tt-filter:focus-within{ border-color:var(--fc-accent); }
.tt-filter-label{ color:var(--fc-ink-2); font-weight:600; text-transform:uppercase;
                  letter-spacing:.05em; line-height:1.2;
                  font-size:max(11px, calc(11px * var(--fc-scale))); }
.tt-filter-pair{ display:grid; grid-template-columns:1fr 1fr; gap:6px; }
.tt-filter input{ width:100%; background:var(--fc-surface); border:1px solid var(--fc-hair);
                  border-radius:3px; color:var(--fc-ink); padding:3px 6px;
                  font-family:var(--ct-font-monospace, monospace);
                  font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-filter input:focus{ outline:2px solid var(--fc-accent); outline-offset:0; }
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-filter input{ background:#fff; border-color:#9dbfa6; }
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-filter input::placeholder{ color:#5c7364; }
.tt-filter-foot{ display:flex; align-items:center; gap:8px; margin-top:12px; }
.tt-filter-count{ color:var(--fc-ink-3);
                  font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-runner[hidden]{ display:none; }

@media print{ .tt-bar, .tt-filters{ display:none !important; } }

/* ---- pick rank + runner actions ---- */

.tt-wrap.fc .tt-acts{ position:relative; }
.tt-wrap.fc .tt-acts > summary{ list-style:none; cursor:pointer; }
.tt-wrap.fc .tt-acts > summary::-webkit-details-marker{ display:none; }
.tt-wrap.fc .tt-actbtn{ display:inline-flex; align-items:center; justify-content:center;
          min-width:32px; min-height:32px; border:2px solid var(--fc-hair); border-radius:4px;
          background:var(--fc-inset); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-acts[open] .tt-actbtn{ border-color:var(--fc-accent); color:var(--fc-ink); }

.tt-wrap.fc .tt-actmenu{ position:absolute; right:0; top:calc(100% + 4px); z-index:30;
          min-width:196px; padding:4px; text-align:left;
          background:var(--fc-pop-bg); border:2px solid var(--fc-hair); border-radius:6px;
          box-shadow:0 6px 18px rgba(0,0,0,.28); }
.tt-wrap.fc .tt-actrow{ display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:4px; }
.tt-wrap.fc .tt-actrow:hover{ background:var(--fc-inset); }
.tt-wrap.fc .tt-actrow .btn{ flex:0 0 auto; min-width:20px; }
.tt-wrap.fc .tt-actlbl{ color:var(--fc-ink); font-weight:500;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
/* An empty row means the tier gate emitted no button -- do not leave a bare label. */
.tt-wrap.fc .tt-actrow:not(:has(button)){ display:none; }

/* The label follows the icon class the shared click handler toggles, so the two
   cannot drift apart. Shortlist and notebook swap far/fas; hide swaps the glyph. */
.tt-wrap.fc .tt-a-like:has(.far) .tt-on,
.tt-wrap.fc .tt-a-like:has(.fas) .tt-off,
.tt-wrap.fc .tt-a-note:has(.far) .tt-on,
.tt-wrap.fc .tt-a-note:has(.fas) .tt-off,
.tt-wrap.fc .tt-a-hide:has(.fa-trash) .tt-on,
.tt-wrap.fc .tt-a-hide:has(.fa-trash-restore) .tt-off{ display:none; }

@media (min-width:992px){
}

/* Hidden state is read from the icon class the shared handler toggles, not from the
   handler's own row lookup: betturtle-base.js and its .min twin have diverged, and the
   unminified build only finds a classic <tr>. Reading the icon works on either build. */
/* A binned runner says so in a word and carries a marked edge. Fading the horse's NAME was
   the whole signal before, which is both easy to miss and the contrast problem the non-runner
   row already had -- opacity drags ink toward its ground and the audit reads the token, not
   the result. The silk fades because it is decoration; the name does not. */
/* Scoped to the HIDE BUTTON's own icon, not to the glyph anywhere in the runner. A bare
   `:has(.fa-trash-restore)` matches the class being present in the DOM whether or not it is
   displayed -- so the ribbon's always-rendered Binned label, which carries that glyph, made
   every runner match and every row paint itself as binned (Kenny, 2 Sep). */
.tt-wrap.fc .tt-hidden-tag{ display:none; }
.tt-wrap.fc .tt-runner:has(i[class*="hide-"].fa-trash-restore) .tt-hidden-tag{
          display:inline-block; border-color:var(--fc-poor); color:var(--fc-poor);
          font-weight:600; }
.tt-wrap.fc .tt-runner:has(i[class*="hide-"].fa-trash-restore){ background:var(--fc-well);
          border-left:3px solid var(--fc-poor); }
/* `!important` because .tt-name carries `color` and `text-decoration` as !important itself --
   it is an anchor, and Bootstrap's link styling had to be beaten. Without matching that, a
   rule here is written and silently does nothing. */
.tt-wrap.fc .tt-runner:has(i[class*="hide-"].fa-trash-restore) .tt-name{ color:var(--fc-ink-3) !important;
          text-decoration:line-through !important; text-decoration-thickness:1px; }
.tt-wrap.fc .tt-runner:has(i[class*="hide-"].fa-trash-restore) .tt-silk{ opacity:.5; }

/* Bin beside the heart rather than inside the actions menu: it is a common action and a
   menu made it two clicks. */
.tt-wrap.fc .tt-binbtn{ display:inline-flex; align-items:center; }

/* Grid children default to min-width:auto and so refuse to shrink below their content,
   which pushed the row past 360px once the pick chip and actions button were added. */
.tt-wrap.fc .tt-r1 > *{ min-width:0; }
.tt-wrap.fc .tt-people{ min-width:0; flex-wrap:wrap; }
.tt-wrap.fc .tt-conn > span{ min-width:0; }

/* The shared button templates hardcode Bootstrap text-dark/danger/warning, and text-dark is
   near-black on the dark popover. Colour the icons from the tokens instead. */
.tt-wrap.fc .tt-actmenu .btn{ color:var(--fc-ink-3) !important; }
.tt-wrap.fc .tt-a-like:has(.fas) .btn{ color:var(--fc-poor) !important; }
.tt-wrap.fc .tt-a-note:has(.fas) .btn{ color:var(--fc-fair) !important; }
.tt-wrap.fc .tt-a-hide:has(.fa-trash-restore) .btn{ color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-actmenu .btn i{ width:1.1em; text-align:center; }
/* The count is how many customers have shortlisted the horse, and the icon legend
   documents it, so it stays on the row -- but not duplicated inside the menu. */
.tt-wrap.fc .tt-actmenu sup{ display:none; }
/* The shortlist count is a number to read, not a warning: the amber value ink is 3.5:1 on
   the row in dark and 4.2:1 in light at 10.8px. The body ink clears both. */
.tt-wrap.fc .tt-heart sup,
.tt-wrap.fc .tt-commentact sup,
.tt-wrap.fc .tt-actrow sup,
.tt-wrap.fc .tt-whymarks sup{ color:var(--fc-ink-2) !important; font-weight:700; }

/* The rosette artwork is drawn against a dark ground. */
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-rosette{
          filter:drop-shadow(0 1px 2px rgba(0,0,0,.35)) saturate(1.15) contrast(1.08); }

/* ---- meeting navigation ---- */
.tt-wrap.fc .tt-nav{ padding:12px 0 4px; }
.tt-wrap.fc .tt-nav-course{ color:var(--fc-ink); font-weight:600; text-transform:uppercase;
          font-size:max(13px, calc(17px * var(--fc-scale))); }
.tt-wrap.fc .tt-nav-course i{ color:var(--fc-poor); }
.tt-wrap.fc .tt-nav-date{ color:var(--fc-ink-3); text-transform:none; margin-left:6px;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-nav-times{ display:flex; flex-wrap:wrap; gap:6px; margin:8px 0; }
.tt-wrap.fc .tt-time-pill{ border:2px solid var(--fc-hair); border-radius:4px; padding:3px 9px;
          background:var(--fc-inset); color:var(--fc-ink) !important; text-decoration:none !important;
          font-weight:600; font-variant-numeric:tabular-nums;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-time-pill:hover{ border-color:var(--fc-accent); }
.tt-wrap.fc .tt-time-pill.is-now{ background:var(--fc-accent); color:var(--fc-accent-ink) !important;
          border-color:var(--fc-accent); }
.tt-wrap.fc .tt-time-pill.is-group{ border-color:var(--fc-fair); }
.tt-wrap.fc .tt-nav-other{ display:flex; flex-wrap:wrap; gap:6px; align-items:center;
          color:var(--fc-ink-3); font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-course-pill{ border:1px solid var(--fc-hair); border-radius:3px; padding:1px 7px;
          color:var(--fc-ink-2) !important; text-decoration:none !important; }
.tt-wrap.fc .tt-course-pill:hover{ border-color:var(--fc-accent); color:var(--fc-ink) !important; }

/* ---- icon help drawer ---- */
.tt-wrap.fc .tt-iscrim{ position:fixed; inset:0; z-index:1040; background:rgba(0,0,0,.5); }
.tt-wrap.fc .tt-idrawer{ position:fixed; top:0; right:0; bottom:0; z-index:1050;
          width:min(420px,92vw); display:flex; flex-direction:column;
          background:var(--fc-pop-bg); border-left:2px solid var(--fc-hair);
          box-shadow:-8px 0 24px rgba(0,0,0,.4); }
.tt-wrap.fc .tt-ihead{ display:flex; align-items:center; justify-content:space-between;
          gap:8px; padding:12px 14px; border-bottom:2px solid var(--fc-hair); }
.tt-wrap.fc .tt-ihead .tt-h3{ margin:0; font-size:max(14px, calc(16px * var(--fc-scale))); }
.tt-wrap.fc .tt-iclose{ background:none; border:0; color:var(--fc-ink-2); cursor:pointer;
          min-width:36px; min-height:36px; font-size:18px; }
.tt-wrap.fc .tt-iclose:hover{ color:var(--fc-ink); }
.tt-wrap.fc .tt-isearchwrap{ position:relative; padding:10px 14px; }
.tt-wrap.fc .tt-isearchwrap i{ position:absolute; left:24px; top:50%; transform:translateY(-50%);
          color:var(--fc-ink-3); pointer-events:none; }
.tt-wrap.fc .tt-isearch{ width:100%; padding:7px 10px 7px 30px; border-radius:4px;
          border:2px solid var(--fc-hair); background:var(--fc-inset); color:var(--fc-ink);
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-isearch:focus{ outline:2px solid var(--fc-accent); outline-offset:1px; }
.tt-wrap.fc .tt-inone{ margin:0; padding:0 14px 10px; color:var(--fc-ink-3); }
.tt-wrap.fc .tt-ibody{ overflow-y:auto; padding:0 14px 16px; }
.tt-wrap.fc .tt-isec .tt-h4{ position:sticky; top:0; margin:10px 0 6px; padding:4px 0;
          color:var(--fc-accent); text-transform:uppercase; letter-spacing:.05em;
          background:var(--fc-pop-bg);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-irow{ display:grid; grid-template-columns:46px 1fr; gap:10px; align-items:start;
          padding:7px 0; border-bottom:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-iglyph{ display:flex; align-items:center; justify-content:center;
          min-height:26px; color:var(--fc-ink-2); }
.tt-wrap.fc .tt-itext b{ color:var(--fc-ink); font-weight:600;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-itier{ margin-left:6px; border:1px solid var(--fc-line-2); border-radius:3px;
          padding:0 5px; color:var(--fc-accent); text-transform:uppercase;
          font-size:max(10px, calc(10px * var(--fc-scale))); }
.tt-wrap.fc .tt-idesc{ display:block; margin-top:2px; color:var(--fc-ink-3);
          font-size:max(11px, calc(12px * var(--fc-scale))); }

/* ---- print chooser ---- */
.tt-wrap.fc .tt-pmodal{ position:fixed; inset:0; z-index:1060; display:flex;
          align-items:center; justify-content:center; padding:16px;
          background:rgba(0,0,0,.5); }
.tt-wrap.fc .tt-pbox{ width:min(420px,96vw); background:var(--fc-pop-bg);
          border:2px solid var(--fc-hair); border-radius:6px;
          box-shadow:0 10px 30px rgba(0,0,0,.45); }
.tt-wrap.fc .tt-pbody{ padding:12px 14px; }
.tt-wrap.fc .tt-pintro{ margin:0 0 10px; color:var(--fc-ink-3);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-popt{ display:flex; align-items:center; gap:8px; padding:5px 0;
          color:var(--fc-ink); font-size:max(12px, calc(13px * var(--fc-scale))); cursor:pointer; }
.tt-wrap.fc .tt-pfoot{ display:flex; justify-content:flex-end; gap:8px;
          padding:10px 14px; border-top:2px solid var(--fc-hair); }
.tt-wrap.fc .tt-tool.is-go,
.tt-wrap.fc .tt-tool.is-hint{ background:var(--fc-accent); color:var(--fc-accent-ink);
          border-color:var(--fc-accent); }

/* ---- print ----
 * The chooser writes pr-no-* on :root; each rule below reads one of them. Collapsed
 * panes are forced open so what is on screen is what comes out of the printer.
 */
@media print{
  .tt-wrap.fc .tt-nav, .tt-wrap.fc .tt-bar, .tt-wrap.fc .tt-filters,
  .tt-wrap.fc .tt-idrawer, .tt-wrap.fc .tt-iscrim, .tt-wrap.fc .tt-pmodal,
  .tt-wrap.fc .tt-actcell, .tt-wrap.fc .tt-more{ display:none !important; }
  .tt-wrap.fc, .tt-wrap.fc .tt-runner, .tt-wrap.fc .tt-head{
          background:#fff !important; color:#000 !important; box-shadow:none !important; }
  .tt-wrap.fc .tt-name, .tt-wrap.fc .tt-sub, .tt-wrap.fc .tt-conn,
  .tt-wrap.fc .tt-connline, .tt-wrap.fc .tt-pos{ color:#000 !important; }
  .tt-wrap.fc .tt-runner{ break-inside:avoid; border-bottom:1px solid #999 !important; }
  /* greyscale keeps the horseshoe state as border weight, since the tint will not survive */
  .tt-wrap.fc .tt-cell{ background:#fff !important; border:1px solid #999; }
  .tt-wrap.fc .tt-cell.g{ border-width:3px; } .tt-wrap.fc .tt-cell.a{ border-width:2px; }
  .tt-wrap.fc .tt-cell.r{ border-style:dotted; }
  :root.pr-no-runners .tt-wrap.fc .tt-runners{ display:none !important; }
  :root.pr-no-analysis .tt-wrap.fc [data-tt-briefpane="analysis"]{ display:none !important; }
  :root.pr-no-rp .tt-wrap.fc [data-tt-briefpane="rp"]{ display:none !important; }
  :root.pr-no-trends .tt-wrap.fc [data-tt-briefpane="trends"]{ display:none !important; }
  :root.pr-no-stats .tt-wrap.fc [data-tt-statpane], :root.pr-no-stats .tt-wrap.fc .tt-table{ display:none !important; }
  :root.pr-no-comments .tt-wrap.fc .tt-comment{ display:none !important; }
}

/* The legend's sample glyphs were written for the white Bootstrap help page: bg-warning
   with white text is 1.59:1 anywhere, and text-success/danger/warning fail on one ground
   or the other. Restyle the samples inside the drawer so they stay legible while still
   reading as their colour family; the label beside each one carries the meaning. */
.tt-wrap.fc .tt-iglyph .badge{ color:#fff; font-weight:700; }
.tt-wrap.fc .tt-iglyph .badge.bg-danger{ background:#b0202c !important; }
.tt-wrap.fc .tt-iglyph .badge.bg-primary{ background:var(--fc-first-bg) !important; }
.tt-wrap.fc .tt-iglyph .badge.bg-success{ background:#1f6b12 !important; }
.tt-wrap.fc .tt-iglyph .badge.bg-warning{ background:#7a5300 !important; color:#fff !important; }
.tt-wrap.fc .tt-iglyph .text-success,
.tt-wrap.fc .tt-idesc .text-success{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .tt-iglyph .text-danger,
.tt-wrap.fc .tt-idesc .text-danger{ color:var(--fc-val-r) !important; }
.tt-wrap.fc .tt-iglyph .text-warning,
.tt-wrap.fc .tt-idesc .text-warning{ color:var(--fc-val-a) !important; }
.tt-wrap.fc .tt-iglyph .text-dark{ color:var(--fc-ink) !important; }

/* ---- meeting summary and today's racing ---- */
/* .tt-sub is monospace for form figures and stats; a sentence of prose is not that. */
.tt-wrap.fc .tt-body.tt-sub{ font-family:inherit; letter-spacing:normal; }
.tt-wrap.fc .tt-coursedesc{ margin:6px 0 0; font-family:inherit; letter-spacing:normal; }
.tt-wrap.fc .tt-seclbl{ margin:16px 0 8px; color:var(--fc-accent);
          text-transform:uppercase; letter-spacing:.05em;
          font-size:max(12px, calc(13px * var(--fc-scale))); }

.tt-wrap.fc .tt-meetrace,
.tt-wrap.fc .tt-meeting{ background:var(--fc-surface-2); border:1px solid var(--fc-hair);
          border-radius:6px; padding:10px 12px; margin-bottom:8px; }
.tt-wrap.fc .tt-meetrace.is-now{ border-color:var(--fc-accent); box-shadow:0 0 0 2px var(--fc-line-2); }
.tt-wrap.fc .tt-meeting.is-quiet{ border-style:dashed; }

.tt-wrap.fc .tt-meethead{ display:flex; gap:10px; align-items:flex-start; }
.tt-wrap.fc .tt-meettime{ flex:0 0 auto; border:2px solid var(--fc-chip-line); border-radius:4px;
          background:var(--fc-chip-bg); color:var(--fc-chip-ink) !important;
          text-decoration:none !important; padding:2px 9px; font-weight:700;
          font-variant-numeric:tabular-nums;
          font-size:max(13px, calc(16px * var(--fc-scale))); }
.tt-wrap.fc .tt-meettitle{ min-width:0; }
.tt-wrap.fc .tt-meettitle a{ color:var(--fc-ink) !important; text-decoration:none !important;
          font-weight:600; font-size:max(13px, calc(15px * var(--fc-scale))); }
.tt-wrap.fc .tt-meettitle a:hover{ color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-meetchips{ margin-top:5px; }
.tt-wrap.fc .tt-chip-prize{ color:var(--fc-val-g); }
.tt-wrap.fc .tt-chip-tv{ color:var(--fc-val-a); }

.tt-wrap.fc .tt-meettop{ margin-top:9px; padding-top:8px; border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-meetlbl{ display:block; margin-bottom:5px; color:var(--fc-ink-3);
          text-transform:uppercase; letter-spacing:.05em;
          font-size:max(10px, calc(10.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-pickrow{ display:flex; align-items:center; gap:8px; padding:4px 6px;
          border-radius:4px; text-decoration:none !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-pickrow:hover{ background:var(--fc-inset); }
.tt-wrap.fc .tt-picksaddle{ min-width:22px; text-align:center; color:var(--fc-ink-3);
          font-variant-numeric:tabular-nums;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-pickname{ flex:1 1 auto; min-width:0; font-weight:600;
          font-size:max(12px, calc(13.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-pickshoes{ display:inline-flex; gap:3px; flex:0 0 auto; }
/* the five factors as dots: the row is a summary, not the card */
.tt-wrap.fc .tt-dot{ width:10px; height:10px; border-radius:50%; display:inline-block;
          background:var(--fc-ink-3); opacity:.35; }
.tt-wrap.fc .tt-dot.g{ background:var(--fc-good); opacity:1; }
.tt-wrap.fc .tt-dot.a{ background:var(--fc-fair); opacity:1; }
.tt-wrap.fc .tt-dot.r{ background:var(--fc-poor); opacity:1; }
.tt-wrap.fc .tt-meetlocked{ margin:9px 0 0; padding-top:8px; border-top:1px solid var(--fc-hair);
          color:var(--fc-ink-3); font-size:max(11px, calc(12px * var(--fc-scale))); }

.tt-wrap.fc .tt-meetingtop{ display:flex; flex-wrap:wrap; gap:6px 12px; align-items:baseline;
          margin-bottom:8px; }
.tt-wrap.fc .tt-meetingname{ color:var(--fc-ink) !important; text-decoration:none !important;
          font-weight:600; text-transform:uppercase; letter-spacing:.02em;
          font-size:max(14px, calc(17px * var(--fc-scale))); }
.tt-wrap.fc .tt-meetingname:hover{ color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-meetlink{ display:inline-block; margin-top:8px; color:var(--fc-accent) !important;
          text-decoration:none !important; font-weight:600; text-transform:uppercase;
          letter-spacing:.04em; font-size:max(11px, calc(11.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-meetlink:hover{ text-decoration:underline !important; }
/* a race already run is dimmed, but keeps its border so it stays a target */
/* De-emphasise with colour, not opacity: fading text is the same as lowering its
   contrast, and .55 put this pill at 3.58:1. */
.tt-wrap.fc .tt-time-pill.is-done{ color:var(--fc-ink-3); border-style:dashed; }

.tt-wrap.fc .tt-nextrow{ display:grid; gap:8px;
          grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); }
.tt-wrap.fc .tt-nextcard{ display:flex; flex-direction:column; gap:2px; padding:9px 11px;
          border:2px solid var(--fc-hair); border-radius:6px; background:var(--fc-inset);
          text-decoration:none !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-nextcard:hover{ border-color:var(--fc-accent); }
.tt-wrap.fc .tt-nexttime{ font-weight:700; font-variant-numeric:tabular-nums;
          font-size:max(15px, calc(19px * var(--fc-scale))); }
.tt-wrap.fc .tt-nextcourse{ text-transform:uppercase; letter-spacing:.03em; font-weight:600;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }

/* ---- course index and hub ---- */
.tt-wrap.fc .tt-coursegrid{ display:grid; gap:8px;
          grid-template-columns:repeat(auto-fill,minmax(168px,1fr)); }
.tt-wrap.fc .tt-coursecard{ display:flex; flex-direction:column; gap:2px; padding:9px 11px;
          border:1px solid var(--fc-hair); border-radius:6px; background:var(--fc-surface-2);
          text-decoration:none !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-coursecard:hover{ border-color:var(--fc-accent); }
.tt-wrap.fc .tt-coursename{ font-weight:600;
          font-size:max(13px, calc(14.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-coursefacts{ display:flex; flex-wrap:wrap; gap:6px; }

.tt-wrap.fc .tt-recordgrid{ display:grid; gap:8px;
          grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); }
.tt-wrap.fc .tt-recrow{ display:flex; align-items:baseline; gap:8px; padding:4px 0;
          border-bottom:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-recrow:last-child{ border-bottom:0; }
.tt-wrap.fc .tt-recname{ flex:1 1 auto; min-width:0; color:var(--fc-ink);
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-recstrike{ flex:0 0 auto; font-weight:700; color:var(--fc-ink);
          font-variant-numeric:tabular-nums;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-recnote{ margin:6px 0 0; font-family:inherit; letter-spacing:normal; }

/* ---- shared chrome: navbar and footer ----
 * Scoped to .tt-wrap.fc so only the turtle theme sees it; the classic shell keeps the
 * Hyper look. Component classes only -- never bare p/li/td, which made unmigrated
 * Bootstrap panels unreadable when the shell was first built.
 */
.tt-wrap.fc .navbar-custom,
.tt-wrap.fc .topnav,
.tt-wrap.fc .footer{ background:var(--fc-band-bg) !important; border-color:var(--fc-hair) !important; }
.tt-wrap.fc .navbar-custom{ border-bottom:2px solid var(--fc-hair); }
.tt-wrap.fc .topnav{ border-bottom:2px solid var(--fc-hair); }
.tt-wrap.fc .topbar{ background:transparent !important; }

.tt-wrap.fc .navbar-custom .nav-link,
.tt-wrap.fc .topnav .nav-link,
.tt-wrap.fc .footer a{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .navbar-custom .nav-link:hover,
.tt-wrap.fc .topnav .nav-link:hover,
.tt-wrap.fc .topnav .nav-link.active,
.tt-wrap.fc .footer a:hover{ color:var(--fc-accent) !important; }
/* Bootstrap fills .nav-link.active with the brand green, and the rule above paints its text
   the accent green -- so the nav item for the page you are ON rendered as a solid green block
   with the word inside it invisible. The top nav marks the current page by colour and weight;
   it is not a pill. */
.tt-wrap.fc .topnav .nav-link.active,
.tt-wrap.fc .navbar-custom .nav-link.active,
.tt-wrap.fc .topnav .nav-link.dropdown-toggle.show,
.tt-wrap.fc .navbar-custom .nav-link.dropdown-toggle.show{ background-color:transparent !important;
          border-color:transparent !important; font-weight:700; }
/* An OPEN dropdown takes the same fill from Bootstrap and was the same 1.00:1 -- the word
   `RACES` measured rgb(0,117,33) on rgb(0,117,33) while its menu was down. */
.tt-wrap.fc .topnav .nav-link.dropdown-toggle.show,
.tt-wrap.fc .navbar-custom .nav-link.dropdown-toggle.show{ color:var(--fc-accent) !important; }
.tt-wrap.fc .navbar-custom .nav-user,
.tt-wrap.fc .topbar-menu .nav-link small,
.tt-wrap.fc .footer,
.tt-wrap.fc .footer .header-title{ color:var(--fc-ink-2) !important; }

/* dropdowns are popovers: they must be opaque or the page shows through */
.tt-wrap.fc .navbar-custom .dropdown-menu,
.tt-wrap.fc .topnav .dropdown-menu{ background:var(--fc-pop-bg) !important;
          border:2px solid var(--fc-hair) !important; box-shadow:0 6px 18px rgba(0,0,0,.35); }
.tt-wrap.fc .dropdown-item{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .dropdown-item:hover,
.tt-wrap.fc .dropdown-item:focus{ background:var(--fc-inset) !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .dropdown-divider{ border-color:var(--fc-hair) !important; }

/* The pre-footer "About Us" band is a section.bg-light-lighten sitting directly inside
   .content-page. Match it by that position: the same class is used INSIDE racehead.html
   and summary.html, and restyling those would wreck an unmigrated card. */
/* not transparent: the white sheet below sits inside .content-page too, and this band
   carries light turtle ink */
.tt-wrap.fc .content-page > .bg-light-lighten{ background:var(--fc-band-bg) !important; }
.tt-wrap.fc .content-page > .bg-light-lighten address,
.tt-wrap.fc .content-page > .bg-light-lighten p,
.tt-wrap.fc .content-page > .bg-light-lighten li,
.tt-wrap.fc .content-page > .bg-light-lighten .header-title{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .content-page > .bg-light-lighten a{ color:var(--fc-accent) !important; }
.tt-wrap.fc .footer .border-top,
.tt-wrap.fc .footer .border-bottom{ border-color:var(--fc-hair) !important; }

/* betturtle-base.css pairs the two logos to Hyper's data-bs-theme, which the turtle
   theme does not set. Pair them to data-fc-theme instead. Both carry d-lg-inline-block,
   so only re-show them at the width where they were meant to appear. */
@media (min-width:992px){
  .tt-wrap.fc .bt-logo-light{ display:none !important; }
  .tt-wrap.fc .bt-logo-dark{ display:inline-block !important; }
  :root:not([data-fc-theme="dark"]) .tt-wrap.fc .bt-logo-light{ display:inline-block !important; }
  :root:not([data-fc-theme="dark"]) .tt-wrap.fc .bt-logo-dark{ display:none !important; }
}

/* the signed-in card is a white Hyper panel */
.tt-wrap.fc .navbar-custom .nav-user{ background:var(--fc-inset) !important;
          border:1px solid var(--fc-hair) !important; border-radius:5px; }
.tt-wrap.fc .navbar-custom .nav-user .badge{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }

/* Pre-existing: topbar-menu overflows the viewport at 390px and clips the Profile icon.
   Let it wrap rather than run off the edge. */
.tt-wrap.fc .topbar-menu{ flex-wrap:wrap; justify-content:flex-end; }

/* Text inside the chrome that still carries a Hyper grey chosen for a white page.
   Scoped to the navbar and footer components, never to bare elements. */
.tt-wrap.fc .navbar-custom .account-user-name{ color:var(--fc-ink) !important; }
.tt-wrap.fc .navbar-custom .text-muted,
.tt-wrap.fc .footer .text-muted{ color:var(--fc-ink-3) !important; }
.tt-wrap.fc .footer .header-title{ color:var(--fc-ink) !important; }
.tt-wrap.fc .footer address,
.tt-wrap.fc .footer p,
.tt-wrap.fc .footer li{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .footer a{ color:var(--fc-accent) !important; }

/* ---- unmigrated bodies keep a white sheet ----
 * The shell paints a dark ground, but an unmigrated body is Bootstrap/Hyper markup whose
 * colours assume white. Rather than restyle that markup -- which is what made the FAQ
 * accordions unreadable when the shell was first built -- give any page without migrated
 * content its own light sheet, and let the turtle ground show only behind turtle content.
 * A page becomes turtle simply by containing .tt-card.
 */
.tt-wrap.fc .content-page:not(:has(.tt-card)){ background:#ffffff; }
.tt-wrap.fc .content-page:not(:has(.tt-card)) > .container-fluid,
.tt-wrap.fc .content-page:not(:has(.tt-card)) > .container{ background:#ffffff; }

/* ---- migrated Bootstrap surfaces ----
 * A page that has been migrated but keeps its existing Bootstrap markup -- pointer reports,
 * tips pages -- opts in by wrapping its content in .tt-card.tt-sheet. The page keeps its
 * DataTables machinery, cards and tier gating; only the surface is restyled. Nothing here
 * reaches an unmigrated page, which keeps its white sheet instead.
 */
/* A card that names a semantic colour keeps it. My Shortlisted Runners states its big-priced
   winners as red, green, amber and blue cards; repainting every card to the sheet surface took
   those colours away and left white text on a pale ground. `bg-light` and `bg-white` are NOT
   exempt -- those name a colour that does not survive a dark theme, and the sheet surface is
   the right answer for them. */
.tt-wrap.fc .tt-sheet .card:not(:where(.bg-primary, .bg-secondary, .bg-success, .bg-danger,
                                       .bg-warning, .bg-info, .bg-dark)),
.tt-wrap.fc .tt-sheet .card-body{ background:var(--fc-surface-2) !important;
          border-color:var(--fc-hair) !important; color:var(--fc-ink-2); }
/* Its body must not paint over it either -- same reason the landing pages' CTA needed this. */
.tt-wrap.fc .tt-sheet .card:is(.bg-primary, .bg-secondary, .bg-success, .bg-danger,
                               .bg-warning, .bg-info, .bg-dark) .card-body{
          background:transparent !important; }
/* A card that paints its OWN ground owns its body as well. Repainting the body to the sheet
   surface left the landing pages' final CTA as white text on a pale panel at 1.07, inside a
   card that was still green -- the ground and the text had different owners. */
.tt-wrap.fc .tt-sheet .card:is(.bg-primary, .bg-secondary, .bg-success, .bg-danger,
                               .bg-info, .bg-dark) > .card-body{ background:transparent !important; }
/* These card headers were bg-primary with white text, so the header ground must stay dark
   in BOTH themes -- the same treatment the table thead gets. */
.tt-wrap.fc .tt-sheet .card-header{ background:var(--fc-thead) !important;
          border-color:var(--fc-hair) !important; color:#ffffff !important; }
/* The generic link rule below carries two :not()s, so it out-specifies a plain
   `.card-header a`. In light mode the accent equals the header ground: a ratio of 1. */
.tt-wrap.fc .tt-sheet .card-header .card-title,
.tt-wrap.fc .tt-sheet .card-header h1,
.tt-wrap.fc .tt-sheet .card-header h2,
.tt-wrap.fc .tt-sheet .card-header h3,
.tt-wrap.fc .tt-sheet .card-header h4,
.tt-wrap.fc .tt-sheet .card-header h5,
.tt-wrap.fc .tt-sheet .card-header h6,
.tt-wrap.fc .tt-sheet .card-header p,
.tt-wrap.fc .tt-sheet .card-header .text-dark,
.tt-wrap.fc .tt-sheet .card-header span,
.tt-wrap.fc .tt-sheet .card-header a:not(.btn):not(.tt-chip),
.tt-wrap.fc .tt-sheet .card-header a:not(.btn):not(.tt-chip) span{ color:#ffffff !important; }
.tt-wrap.fc .tt-sheet .text-white-50{ color:rgba(255,255,255,.85) !important; }
.tt-wrap.fc .tt-sheet h1{ color:var(--fc-ink); }
.tt-wrap.fc .tt-sheet .form-text,
/* `.text-body-secondary` is Bootstrap 5.3's name for the same thing, and reused fragments
   carry both. Without it the AI-insights note stayed Bootstrap's grey, 2.83:1 on the light
   sheet. */
.tt-wrap.fc .tt-sheet .text-muted,
.tt-wrap.fc .tt-sheet .text-body-secondary,
.tt-wrap.fc .tt-sheet .text-secondary{ color:var(--fc-ink-2) !important; }

/* Bootstrap 5.3 drives table colour through its own variables and applies the striped
   and hover states as a colour PAIR. Overriding background on td alone leaves the striped
   rows carrying Bootstrap's dark stripe ink on a dark ground. Set the variables. */
.tt-wrap.fc .tt-sheet table.table{
          --bs-table-color:var(--fc-ink-2);
          --bs-table-bg:transparent;
          --bs-table-border-color:var(--fc-hair);
          --bs-table-striped-color:var(--fc-ink-2);
          --bs-table-striped-bg:var(--fc-zebra);
          --bs-table-hover-color:var(--fc-ink);
          --bs-table-hover-bg:var(--fc-hover);
          --bs-table-active-color:var(--fc-ink);
          --bs-table-active-bg:var(--fc-inset);
          color:var(--fc-ink-2); border-color:var(--fc-hair); }
/* This Bootstrap build stripes with `box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg)`
   rather than the 5.3 variables, so the stripe has to be cancelled at the cell and repainted. */
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *{
          box-shadow:none !important; background-color:transparent !important;
          color:var(--fc-ink-2) !important; border-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet table.table-striped > tbody > tr:nth-of-type(odd) > *{
          background-color:var(--fc-zebra) !important; }
.tt-wrap.fc .tt-sheet table.table > tbody > tr:hover > *{
          background-color:var(--fc-hover) !important; }
.tt-wrap.fc .tt-sheet table.table > thead th{ background-color:var(--fc-thead) !important;
          color:#ffffff !important; border-color:var(--fc-hair) !important;
          box-shadow:none !important; text-transform:uppercase; letter-spacing:.03em; }
/* Every reused table follows the A/A/A control, not a fixed px. The size is declared on the
   CONTAINER and inherited, so a sheet that wants its own can restate it on a nested element
   and win by proximity rather than by out-specifying a rule somewhere else in this file --
   which is how the career form and this rule would otherwise fight. The header carries
   `!important` because Hyper's `table.dataTable thead th` does.

   14px and 11px are today's 16px and 12.48px divided by the default scale, so the default
   setting looks exactly as it does now and only the other two settings move. */
.tt-wrap.fc .tt-sheet{ --tt-tsize:max(12px, calc(14px * var(--fc-scale)));
                       --tt-thsize:max(11px, calc(11px * var(--fc-scale))); }
.tt-wrap.fc .tt-sheet table.table,
.tt-wrap.fc .tt-sheet table.table > tbody > tr > td{ font-size:var(--tt-tsize) !important; }
.tt-wrap.fc .tt-sheet table.table > thead > tr > th{ font-size:var(--tt-thsize) !important; }

.tt-wrap.fc .tt-sheet table.table a{ color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet table.table a:hover{ color:var(--fc-accent) !important; }
/* The head paints itself green two rules above, so a link in it takes the head's ink, not the
   body's. Most stats tables wrap each column name in an <a> to hang a tooltip on, and the
   rule above is more specific than a `thead a` rule written elsewhere -- so the Odds table
   read as having no headings. The ground and the ink on it are decided in one place now. */
.tt-wrap.fc .tt-sheet table.table > thead a{ color:#ffffff !important; }
.tt-wrap.fc .tt-sheet table.table > thead a:hover{ color:#ffffff !important; }
/* And the icons in it. A column headed by a star or a key carried `text-warning`, which is
   amber on the head's green -- 1.17:1, the icons Kenny could not make out. The SHAPE is what
   distinguishes those columns (star, key, trophy) and each carries a tooltip naming it, so
   the head's own ink is right; the legend above the table keeps the amber, where it reads. */

/* DataTables' own controls */
.tt-wrap.fc .tt-sheet .dataTables_wrapper,
.tt-wrap.fc .tt-sheet .dataTables_info,
.tt-wrap.fc .tt-sheet .dataTables_length,
.tt-wrap.fc .tt-sheet .dataTables_filter{ color:var(--fc-ink-2); }
.tt-wrap.fc .tt-sheet .dataTables_filter input,
.tt-wrap.fc .tt-sheet .dataTables_length select,
.tt-wrap.fc .tt-sheet .form-control,
.tt-wrap.fc .tt-sheet .form-select{ background:var(--fc-inset) !important;
          border:2px solid var(--fc-hair) !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .page-link{ background:var(--fc-inset) !important;
          border-color:var(--fc-hair) !important; color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .page-item.active .page-link{ background:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; color:var(--fc-accent-ink) !important; }

/* the date radios and the guide/help strips these pages carry */
.tt-wrap.fc .tt-sheet .alert{ background:var(--fc-inset) !important;
          border-color:var(--fc-hair) !important; color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .btn-outline-secondary{ color:var(--fc-ink-2) !important;
          border-color:var(--fc-hair) !important; }

/* the guide strip and the DataTables buttons these pages carry */
.tt-wrap.fc .tt-sheet .alert-info,
.tt-wrap.fc .tt-sheet .bg-info,
.tt-wrap.fc .tt-sheet .bg-light,
.tt-wrap.fc .tt-sheet .bg-white{ background:var(--fc-inset) !important;
          color:var(--fc-ink-2) !important; border-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet .btn-primary{ background:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; color:var(--fc-accent-ink) !important; }
.tt-wrap.fc .tt-sheet .btn-secondary{ background:var(--fc-inset) !important;
          border-color:var(--fc-hair) !important; color:var(--fc-ink-2) !important; }

/* Rating values in a report carry the same Bootstrap classes the classic card uses, chosen
   against white. Map them to the value tokens, which are AA-tested per theme -- the same
   fix the runner row's OR/FORM/SPEED chips needed. */
/* Bootstrap's semantic inks are chosen against white. `.tt-sheet` covers the reused
   fragments; `.tt-panel` and `.tt-analysis` are turtle-native surfaces that also receive
   them -- convert_analysis emits exactly these three classes. */
.tt-wrap.fc .tt-sheet .text-success,
.tt-wrap.fc .tt-panel .text-success,
.tt-wrap.fc .tt-analysis .text-success{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .tt-sheet .text-warning,
.tt-wrap.fc .tt-panel .text-warning,
.tt-wrap.fc .tt-analysis .text-warning{ color:var(--fc-val-a) !important; }
.tt-wrap.fc .tt-sheet .text-danger,
.tt-wrap.fc .tt-panel .text-danger,
.tt-wrap.fc .tt-analysis .text-danger{ color:var(--fc-val-r) !important; }
/* convert_analysis upper-cases its bold run; keep the weight with it. */
.tt-wrap.fc .tt-analysis .text-success{ font-weight:700; }
.tt-wrap.fc .tt-sheet .text-primary{ color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .text-dark,
.tt-wrap.fc .tt-sheet .text-body{ color:var(--fc-ink) !important; }
/* The stripe reset names the cell, so it outranks the rules above and flattens a whole cell
   that carries a colour class -- a profit and a loss come out the same ink. Re-assert them
   where the class is on the cell itself. `.text-muted` and its two aliases already resolve to
   the same ink the reset uses, so they need no entry. */
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *.text-success{
          color:var(--fc-val-g) !important; }
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *.text-warning{
          color:var(--fc-val-a) !important; }
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *.text-danger{
          color:var(--fc-val-r) !important; }
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *.text-primary{
          color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *.text-dark,
.tt-wrap.fc .tt-sheet table.table > :not(caption) > * > *.text-body{
          color:var(--fc-ink) !important; }
/* small pill badges are white-on-tint and unreadable at 8.6px on any ground */
.tt-wrap.fc .tt-sheet .badge.bg-danger{ background:#b0202c !important; color:#fff !important; }
.tt-wrap.fc .tt-sheet .badge.bg-primary{ background:var(--fc-first-bg) !important; color:#fff !important; }
.tt-wrap.fc .tt-sheet .badge.bg-success{ background:#1f6b12 !important; color:#fff !important; }
.tt-wrap.fc .tt-sheet .badge.bg-warning{ background:#7a5300 !important; color:#fff !important; }
.tt-wrap.fc .tt-sheet .badge.bg-info{ background:#155e75 !important; color:#fff !important; }
.tt-wrap.fc .tt-sheet .badge.bg-secondary{ background:#3f5a48 !important; color:#fff !important; }

/* The report page body is migrated content now (it carries .tt-card), so its prose should
   inherit turtle ink rather than Bootstrap's dark default. Set it once at the root of the
   report and let inheritance do the rest -- elements with their own colour keep it. */
.tt-wrap.fc .tt-sheet{ color:var(--fc-ink-2); }
.tt-wrap.fc .tt-sheet .badge-outline-primary{ color:var(--fc-accent) !important;
          border:1px solid var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .badge-outline-danger{ color:var(--fc-val-r) !important;
          border:1px solid var(--fc-val-r) !important; }
.tt-wrap.fc .tt-sheet .badge-outline-success{ color:var(--fc-val-g) !important;
          border:1px solid var(--fc-val-g) !important; }
.tt-wrap.fc .tt-sheet .badge-outline-warning{ color:var(--fc-val-a) !important;
          border:1px solid var(--fc-val-a) !important; }

/* Bare links inside a report carry Bootstrap's indigo/rose, so they take the accent.

   This is a DEFAULT and has to lose to anything that paints its own ground. The exclusions
   sit inside `:where()`, which contributes no specificity, so the whole selector is three
   classes and one element -- below every rule that owns a link family. Written as a chain of
   `:not(.x)` it counted as eight classes and beat all of them: a selected tab was the accent
   ON the accent, 1.00:1, a green box with the tab's name invisible inside it, and the table
   heads below had gone the same way. Adding an exclusion to a `:not()` chain RAISES the very
   priority the exclusion is trying to give away, which is why this reads as it does.

   Anything with a selected or coloured ground is therefore owned elsewhere and not repeated
   here: `.nav-link` by the nav rules below, `.dropdown-item.active` by the `body:has()` rule
   further down, table heads by the rule immediately after this one. */
.tt-wrap.fc .tt-sheet a:not(:where(.btn, .tt-chip, .tt-time-pill, .nav-link, .dropdown-item)){
          color:var(--fc-accent) !important; }
/* Every outline button: Bootstrap's outline colours are chosen against white and fail on
   both turtle grounds. The accent reads on either, and the semantic ones use the value
   tokens, which are AA-tested per theme. */
.tt-wrap.fc .tt-sheet .btn-outline-primary,
.tt-wrap.fc .tt-sheet .btn-outline-success,
.tt-wrap.fc .tt-sheet .btn-outline-info,
.tt-wrap.fc .tt-sheet .btn-outline-secondary,
.tt-wrap.fc .tt-sheet .btn-outline-dark,
.tt-wrap.fc .tt-sheet .btn-outline-light{ color:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; background:transparent !important; }
.tt-wrap.fc .tt-sheet .btn-outline-danger{ color:var(--fc-val-r) !important;
          border-color:var(--fc-val-r) !important; background:transparent !important; }
.tt-wrap.fc .tt-sheet .btn-outline-warning{ color:var(--fc-val-a) !important;
          border-color:var(--fc-val-a) !important; background:transparent !important; }
.tt-wrap.fc .tt-sheet [class*="btn-outline-"]:hover{ background:var(--fc-inset) !important; }
/* Bootstrap gives .accordion-button an expanded state with its own colour pair */
.tt-wrap.fc .tt-sheet .accordion-button,
.tt-wrap.fc .tt-sheet .accordion-button:not(.collapsed),
.tt-wrap.fc .tt-sheet .accordion-item,
.tt-wrap.fc .tt-sheet .accordion-body{ background:var(--fc-inset) !important;
          color:var(--fc-ink) !important; box-shadow:none !important; }
.tt-wrap.fc .tt-sheet .accordion-button::after{ filter:invert(1) brightness(1.6); }

/* tabs and the solid Bootstrap buttons these pages use as category filters */
.tt-wrap.fc .tt-sheet .nav-link{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .nav-link.active{ color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .btn-warning,
.tt-wrap.fc .tt-sheet .btn-info,
.tt-wrap.fc .tt-sheet .btn-light,
.tt-wrap.fc .tt-sheet .btn-success,
.tt-wrap.fc .tt-sheet .btn-danger{ color:#ffffff !important; border-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet .btn-warning{ background:#7a5300 !important; }
.tt-wrap.fc .tt-sheet .btn-info{ background:#155e75 !important; }
.tt-wrap.fc .tt-sheet .btn-light{ background:var(--fc-inset) !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .btn-success{ background:#1f6b12 !important; }
.tt-wrap.fc .tt-sheet .btn-danger{ background:#b0202c !important; }

/* Form controls on a migrated sheet. The runners filter uses bare inputs rather than
   .form-control, so target the elements as well as the Bootstrap classes. */
.tt-wrap.fc .tt-sheet input[type="text"],
.tt-wrap.fc .tt-sheet input[type="number"],
.tt-wrap.fc .tt-sheet input[type="search"],
.tt-wrap.fc .tt-sheet input[type="date"],
.tt-wrap.fc .tt-sheet select,
.tt-wrap.fc .tt-sheet textarea{ background:var(--fc-inset) !important;
          border:2px solid var(--fc-hair) !important; border-radius:4px;
          color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet input::placeholder,
.tt-wrap.fc .tt-sheet textarea::placeholder{ color:var(--fc-ink-3) !important; }
.tt-wrap.fc .tt-sheet input:focus,
.tt-wrap.fc .tt-sheet select:focus{ outline:2px solid var(--fc-accent); outline-offset:1px; }
/* Bootstrap's indigo tick is off-palette; accent-color themes the native control */
.tt-wrap.fc .tt-sheet input[type="checkbox"],
.tt-wrap.fc .tt-sheet input[type="radio"]{ accent-color:var(--fc-accent); }
.tt-wrap.fc .tt-sheet .form-check-input:checked{ background-color:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet label,
.tt-wrap.fc .tt-sheet legend,
.tt-wrap.fc .tt-sheet .form-label{ color:var(--fc-ink-2); }

/* List groups are white by default and carry the icon-key panels, which are collapsed at
   rest -- so the contrast audit never sees them. Found only by force-expanding them. */
.tt-wrap.fc .tt-sheet .list-group,
.tt-wrap.fc .tt-sheet .list-group-item{ background:transparent !important;
          color:var(--fc-ink-2) !important; border-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet .border,
.tt-wrap.fc .tt-sheet .border-top,
.tt-wrap.fc .tt-sheet .border-bottom,
.tt-wrap.fc .tt-sheet .border-start,
.tt-wrap.fc .tt-sheet .border-end{ border-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet .table-responsive{ background:transparent !important; }

/* Nested cards each add their own translucent layer, so three deep the ground is light
   enough to pull accent-coloured links under AA. Flatten: only the outermost surface paints.

   A nested card that carries a SEMANTIC ground is exempt. My Shortlisted Runners states its
   big-priced winners as red, green, amber and blue cards with white text, nested inside the
   Tipping Summary card -- flattening took the colour away and left white text on the light
   sheet. Three of the four were invisible; the fourth read only because `bg-warning` is
   excluded from the rule that keeps white ink, so it had been repainted dark.

   The lesson is the flatten rule's own: only the outermost surface paints -- unless the inner
   one was asked to. A class that names a colour is asking. */
.tt-wrap.fc .tt-sheet .card .card:not([class*="bg-"]),
.tt-wrap.fc .tt-sheet .card-body .card-body:not([class*="bg-"]),
.tt-wrap.fc .tt-sheet .card .card-body .card:not([class*="bg-"]){ background:transparent !important; }

/* An active .nav-tabs tab gets a solid white background from Bootstrap -- the "selected"
   look -- so accent text on it is 1.57 whatever the page ground is. */
.tt-wrap.fc .tt-sheet .nav-tabs{ border-bottom-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet .nav-tabs .nav-link{ color:var(--fc-ink-2) !important;
          background:transparent !important; border-color:transparent !important; }
.tt-wrap.fc .tt-sheet .nav-tabs .nav-link:hover{ border-color:var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet .nav-tabs .nav-link.active{ background:var(--fc-inset) !important;
          color:var(--fc-accent) !important;
          border-color:var(--fc-hair) var(--fc-hair) transparent !important; }

/* ---- system builder ----
 * The builder ships its own #filterform stylesheet written for a white page. Those rules
 * carry an id, so only !important reaches them. Nothing here changes layout: the field set,
 * the accordion structure and the .filter-section-header sibling-walk are untouched.
 */
.tt-wrap.fc .tt-sheet .filter-section-header,
.tt-wrap.fc .tt-sheet .filter-section-header a{ color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .band-count{ color:var(--fc-ink-3) !important; }
.tt-wrap.fc .tt-sheet .band-count.has-active{ color:var(--fc-accent) !important; }
/* a .badge with no bg-* class keeps Bootstrap's grey ink and no ground */
.tt-wrap.fc .tt-sheet .badge:not([class*="bg-"]):not([class*="badge-outline"]){
          color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .btn-link{ color:var(--fc-accent) !important; }

/* Select2 renders its own widget, white by default */
.tt-wrap.fc .tt-sheet .select2-container--default .select2-selection,
.tt-wrap.fc .tt-sheet .select2-container--default .select2-selection--multiple,
.tt-wrap.fc .tt-sheet .select2-dropdown{ background:var(--fc-inset) !important;
          border-color:var(--fc-hair) !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .select2-selection__rendered,
.tt-wrap.fc .tt-sheet .select2-results__option{ color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .select2-selection__choice{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; border-color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .select2-results__option--highlighted{ background:var(--fc-hover) !important;
          color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .select2-search__field{ color:var(--fc-ink) !important; }

/* the credits page's promo panels */
.tt-wrap.fc .tt-sheet .bg-success.bg-opacity-10,
.tt-wrap.fc .tt-sheet .bg-primary.bg-opacity-10,
.tt-wrap.fc .tt-sheet [class*="bg-opacity-"]{ background:var(--fc-inset) !important; }
/* The builder's sticky action bar paints itself white (--ct-secondary-bg fallback), and it
   carries the live count, Rule by rule and Test the number. */
.tt-wrap.fc .tt-sheet #filteractions{ background:var(--fc-band-bg) !important;
          border-top:2px solid var(--fc-hair) !important; }
.tt-wrap.fc .tt-sheet #filteractions .btn-outline-primary,
.tt-wrap.fc .tt-sheet #filteractions .btn-outline-secondary{ color:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; }

/* a .bg-light panel's prose inherits Bootstrap's secondary grey from an ancestor, so the
   panel's own colour is not enough to reach it */
.tt-wrap.fc .tt-sheet .bg-light,
.tt-wrap.fc .tt-sheet .bg-light p,
.tt-wrap.fc .tt-sheet .bg-light li,
.tt-wrap.fc .tt-sheet .bg-light small{ color:var(--fc-ink-2) !important; }
/* the active breadcrumb crumb keeps Bootstrap's muted grey */
.tt-wrap.fc .tt-sheet .breadcrumb-item,
.tt-wrap.fc .tt-sheet .breadcrumb-item.active{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .breadcrumb-item + .breadcrumb-item::before{ color:var(--fc-ink-3) !important; }

/* The preset gallery paints its own cards from --ct-secondary-bg, which is white. */
.tt-wrap.fc .tt-sheet .preset-card{ background:var(--fc-surface-2) !important;
          border-color:var(--fc-hair) !important; color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .preset-card h2,
.tt-wrap.fc .tt-sheet .preset-card h3{ color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .preset-card p,
.tt-wrap.fc .tt-sheet .preset-card li,
.tt-wrap.fc .tt-sheet .preset-card span{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-sheet .preset-card .text-muted{ color:var(--fc-ink-3) !important; }
.tt-wrap.fc .tt-sheet .preset-needs{ color:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .preset-filter-list li.is-locked{ color:var(--fc-ink-3) !important; }

/* ionRangeSlider ships its own blue skin */
.tt-wrap.fc .tt-sheet .irs--flat .irs-bar,
.tt-wrap.fc .tt-sheet .irs .irs-bar{ background:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .irs--flat .irs-handle > i:first-child,
.tt-wrap.fc .tt-sheet .irs .irs-handle > i:first-child{ background:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .irs--flat .irs-from,
.tt-wrap.fc .tt-sheet .irs--flat .irs-to,
.tt-wrap.fc .tt-sheet .irs--flat .irs-single,
.tt-wrap.fc .tt-sheet .irs .irs-from,
.tt-wrap.fc .tt-sheet .irs .irs-to,
.tt-wrap.fc .tt-sheet .irs .irs-single{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }
.tt-wrap.fc .tt-sheet .irs--flat .irs-from:before,
.tt-wrap.fc .tt-sheet .irs--flat .irs-to:before,
.tt-wrap.fc .tt-sheet .irs--flat .irs-single:before{ border-top-color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .irs--flat .irs-line,
.tt-wrap.fc .tt-sheet .irs .irs-line{ background:var(--fc-inset) !important; }
.tt-wrap.fc .tt-sheet .irs-min,
.tt-wrap.fc .tt-sheet .irs-max{ background:var(--fc-inset) !important; color:var(--fc-ink-3) !important; }

/* The System Builder's band counter and its active-filter banner take the accent. Scoped to
   THEM: this used to claim every `.badge.bg-primary` in a sheet, and the finishing-position
   badge is one -- so a winner came out lime while the same badge is blue everywhere else
   (Kenny, 1 Sep). Two rules for one selector, the later winning silently. */
.tt-wrap.fc .tt-sheet .badge.bg-primary.filter-count-badge,
.tt-wrap.fc .tt-sheet #filterform .badge.bg-primary,
.tt-wrap.fc .tt-sheet #filteractions .badge.bg-primary{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }
.tt-wrap.fc .tt-sheet .border-primary{ border-color:var(--fc-accent) !important; }

/* The pricing page hard-codes Bootstrap's success green (#198754) and an emerald inline,
   both chosen against white. Map them to the value tokens, which are AA-tested per theme.
   Colour only -- no price, plan or claim on this page is touched. */
.tt-wrap.fc .tt-sheet .bt-noauto,
.tt-wrap.fc .tt-sheet .bt-renewal-price,
.tt-wrap.fc .tt-sheet [style*="#10b981"]{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .tt-sheet .bt-hero{ border-color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-sheet .bt-hero-head{ background:var(--fc-thead) !important; color:#fff !important; }

/* An active .nav-pills link paints itself Bootstrap indigo and keeps its own ink; and the
   *-subtle badge family is a pale tint with matching pale text, both chosen against white. */
.tt-wrap.fc .tt-sheet .nav-pills .nav-link.active,
.tt-wrap.fc .tt-sheet .nav-link.active[class*="text-"]{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }
.tt-wrap.fc .tt-sheet [class*="-subtle"]{ background:var(--fc-inset) !important; }
.tt-wrap.fc .tt-sheet .bg-success-subtle{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .tt-sheet .bg-warning-subtle{ color:var(--fc-val-a) !important; }
.tt-wrap.fc .tt-sheet .bg-danger-subtle{ color:var(--fc-val-r) !important; }
.tt-wrap.fc .tt-sheet .bg-primary-subtle,
.tt-wrap.fc .tt-sheet .bg-info-subtle{ color:var(--fc-accent) !important; }
/* The card-header ground is dark in both themes, so a button sitting on it must be white --
   the accent is the same green as that ground in light mode. */
.tt-wrap.fc .tt-sheet .card-header .btn,
.tt-wrap.fc .tt-sheet .card-header [class*="btn-outline-"]{ color:#ffffff !important;
          border-color:rgba(255,255,255,.6) !important; background:transparent !important; }
.tt-wrap.fc .tt-sheet .card-header .btn:hover{ background:rgba(255,255,255,.14) !important; }

/* ---- icon fonts the turtle theme does not need ----
 * app.min.css @imports three icon stylesheets from CDNs: Material Design Icons, Remix Icon
 * and Unicons -- 966k and six render-blocking third-party files per page. Across every
 * turtle page measured, Remix Icon is used ZERO times and Unicons only draws two elements that
 * carry .bt-icon-ghost, so they are zero-width alignment spacers in BOTH themes and were
 * never visible. Material Design Icons exists solely for the fourteen navbar dropdown carets,
 * redrawn below as a CSS triangle. That lets the turtle branch load a derived stylesheet with
 * those imports stripped -- see manage.py build_turtle_css.
 */
.tt-wrap.fc .arrow-down::before{ content:"" !important; font-family:inherit !important;
          display:inline-block; width:0; height:0; vertical-align:middle;
          border-left:.3em solid transparent; border-right:.3em solid transparent;
          border-top:.34em solid currentColor; }

/* The factor row a customer asked about. Set by showWhy() and cleared by every other
   highlight, so only one thing on a row is ever marked. */
.tt-wrap.fc .tt-why-row.is-focus{ background:var(--fc-hover); border-radius:4px;
          box-shadow:inset 3px 0 0 var(--fc-accent); }

/* Stands in for content the customer's plan does not include. */
.tt-wrap.fc .tt-locked{ color:var(--fc-ink-3); font-style:italic; }
.tt-wrap.fc .tt-locked i{ margin-right:6px; opacity:.75; }

/* Card-level banner: free-card count, filtered field. */
.tt-wrap.fc .tt-notice{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
          margin:0 0 10px; padding:8px 12px; border:1px solid var(--fc-line);
          border-radius:8px; background:var(--fc-surface-2);
          font-size:calc(13px * var(--fc-scale)); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-notice > i{ color:var(--fc-accent); }
.tt-wrap.fc .tt-notice p{ margin:0; flex:1 1 260px; }
.tt-wrap.fc .tt-notice b{ color:var(--fc-ink); }
.tt-wrap.fc .tt-notice-sub{ color:var(--fc-ink-3); }
.tt-wrap.fc .tt-notice.is-good{ border-color:var(--fc-cell-g); }
.tt-wrap.fc .tt-notice.is-warn{ border-color:var(--fc-warn-line); background:var(--fc-warn); }
/* Also used on a <button>, which otherwise takes the browser's default face -- that
   measured 1.15:1 on the dark ground. State everything rather than inherit it. */
.tt-wrap.fc .tt-notice-cta{ padding:5px 12px; border:1px solid var(--fc-line-2); border-radius:6px;
          background:var(--fc-inset); color:var(--fc-ink); text-decoration:none;
          white-space:nowrap; cursor:pointer; font:inherit;
          font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-notice-cta:hover{ background:var(--fc-hover); }
.tt-wrap.fc .tt-notice-cta.is-go{ background:var(--fc-accent); border-color:var(--fc-accent);
          color:var(--fc-accent-ink); }

/* The persona preset: what the card opened with, and both ways out. Two buttons, so the
   note wraps rather than crushing them at narrow widths. */
.tt-wrap.fc .tt-preset{ border-color:var(--fc-accent); }
/* One sentence above a statistics table saying what its numbers mean for this field. */
.tt-wrap.fc .bt-takeaway{ display:flex; align-items:flex-start; gap:9px;
          margin:0 0 12px; padding:9px 12px; border:1px solid var(--fc-line);
          border-left:3px solid var(--fc-accent); border-radius:6px;
          background:var(--fc-surface-2); color:var(--fc-ink-2);
          font-size:max(12px, calc(13px * var(--fc-scale))); line-height:1.5; }
.tt-wrap.fc .bt-takeaway > i{ color:var(--fc-accent); margin-top:2px; }

.tt-wrap.fc .tt-preset .tt-notice-cta + .tt-notice-cta{ margin-left:6px; }

/* A withdrawn runner stays on the card, dimmed, and says so in words. */
/* A withdrawn runner still has to be readable -- someone is checking WHICH horse came
   out. The strikethrough and the label carry the meaning; opacity only cost contrast. */
.tt-wrap.fc .tt-runner.is-nr{ background:var(--fc-well); }
/* Same reason: this had never applied, because .tt-name sets text-decoration !important. */
.tt-wrap.fc .tt-runner.is-nr .tt-name{ text-decoration:line-through !important; }
.tt-wrap.fc .tt-nr{ margin-left:6px; padding:1px 6px; border-radius:4px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink-2); font-size:calc(11px * var(--fc-scale));
          text-transform:uppercase; letter-spacing:.04em; }

/* The way back to the classic design, beside the display controls. */
.tt-wrap.fc .tt-classic{ padding:4px 10px; border-radius:6px;
          border:1px solid var(--fc-line); color:var(--fc-ink-3); text-decoration:none;
          font-size:calc(12px * var(--fc-scale)); white-space:nowrap;
          background:none; font-family:inherit; line-height:inherit; cursor:pointer; }
.tt-wrap.fc .tt-classicform{ display:inline; margin:0; }
.tt-wrap.fc .tt-classic:hover{ color:var(--fc-ink); background:var(--fc-hover); }

/* Race status: Off, Weighed In, Abandoned, Void. Ink on a tint, the pair the rating
   values already use — the tile tints are translucent and cannot carry light text. */
/* A race state, not a warning: "Weighed In" is the normal end of a race and read as an
   alarm in red. Neutral ground and the sheet's own ink -- the --fc-cell-* tints are 13-18%
   and composite over the card's gradient, which is why this measured 3.53:1. */
.tt-wrap.fc .tt-status{ display:inline-block; margin-left:8px; padding:2px 8px; border-radius:5px;
          background:var(--fc-well); color:var(--fc-ink); border:1px solid var(--fc-hair);
          vertical-align:middle; font-size:calc(12px * var(--fc-scale)); font-weight:600;
          text-transform:uppercase; letter-spacing:.04em; }
.tt-wrap.fc .tt-status.is-prov{ background:var(--fc-cell-a); color:var(--fc-val-a);
          border-color:var(--fc-cell-a); }

/* The classic form fragment, injected into the drawer. It is Bootstrap markup written for a
   white page, so it gets the .tt-sheet treatment the migrated pages use. */
.tt-wrap.fc .tt-formfull{ margin-top:10px; }
.tt-wrap.fc .tt-formfull .tt-formload{ width:100%; }
.tt-wrap.fc .tt-formfull .nav-tabs{ border-color:var(--fc-line); }
/* The sub-tab strip ran to the panel edge while everything under it -- the race-code select,
   the key, the table -- sits inset, so the first tab looked stuck to the side of the card.
   Padded to sit on the same left edge as the content it switches. */
.tt-wrap.fc .tt-formfull > .card > .nav-pills,
.tt-wrap.fc .tt-formfull .nav-pills{ padding:6px 6px 0; }
/* The tables ran flush to the container edge -- `.tt-formfull .card` zeroes its side padding
   so a wide table can use the full width, which left the first column touching the border.
   The inset goes on the panes rather than the card, so the table still scrolls edge to edge
   inside its own box. */
.tt-wrap.fc .tt-formfull .tab-content{ padding-left:10px; padding-right:10px; }
/* The reused tables follow the card's own text-size control rather than a fixed px, so the
   A/A/A buttons reach them. 13px rather than 12: at the default scale the stat tabs were
   11.5px in their cells against 13.8 elsewhere in the drawer, which read as a denser, older
   table than the panel around it. Set on the cells as well as the table -- Bootstrap's own
   `td` rules were winning, so raising the table alone moved the headers and left the numbers
   where they were. */
.tt-wrap.fc .tt-formfull.tt-sheet{ --tt-tsize:calc(13px * var(--fc-scale));
                                   --tt-thsize:calc(13px * var(--fc-scale)); }

/* Two more pieces of furniture the injected form fragment brings with it. `.bg-nav-pills`
   is a Hyper class that paints its own pale ground, so the inactive pills sat light-on-light;
   `text-info` is Bootstrap cyan, chosen against white. */
.tt-wrap.fc .tt-sheet .bg-nav-pills{ background:var(--fc-inset) !important; }
.tt-wrap.fc .tt-sheet .text-info{ color:var(--fc-accent) !important; }

/* The race statistics panel sits between the toolbar and the runners. */
.tt-wrap.fc .tt-statspanel{ margin:0 0 12px; }
.tt-wrap.fc .tt-statspanel[hidden]{ display:none !important; }

/* Hyper's `btn-soft-*` family: a pale tint carrying its colour as ink, chosen against white.
   Same shape as the `*-subtle` badges above, and it needs the same treatment. */
.tt-wrap.fc .tt-sheet [class*="btn-soft-"]{ background:var(--fc-inset) !important;
          border-color:var(--fc-line) !important; color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet [class*="btn-soft-"]:hover{ background:var(--fc-hover) !important; }

/* The classic badge family, reused on the turtle row. Bootstrap's pill badges are sized and
   coloured for a white page, so they are remapped to the row's own tag look; the three that
   carry meaning (tip, strong favourite, vulnerable favourite) keep a distinct ground. */
.tt-wrap.fc .tt-badges{ display:contents; }
.tt-wrap.fc .tt-tags .badge{ display:inline-block; padding:1px 6px; border-radius:4px;
          border:1px solid var(--fc-chip-line); background:var(--fc-chip-bg);
          color:var(--fc-chip-ink); font-size:calc(11px * var(--fc-scale));
          font-weight:600; letter-spacing:.02em; vertical-align:middle; }
.tt-wrap.fc .tt-tags .badge.bg-primary,
.tt-wrap.fc .tt-tags .badge.badge-outline-primary{ background:var(--fc-badge-bg-g) !important;
          border-color:var(--fc-badge-bg-g) !important; color:var(--fc-badge-g) !important; }
.tt-wrap.fc .tt-tags .badge.bg-success{ background:var(--fc-badge-bg-g) !important;
          border-color:var(--fc-badge-bg-g) !important; color:var(--fc-badge-g) !important; }
.tt-wrap.fc .tt-tags .badge.bg-warning,
.tt-wrap.fc .tt-tags .badge.badge-outline-warning{ background:var(--fc-badge-bg-a) !important;
          border-color:var(--fc-badge-bg-a) !important; color:var(--fc-badge-a) !important; }
.tt-wrap.fc .tt-tags .badge.bg-danger,
.tt-wrap.fc .tt-tags .badge.badge-outline-danger{ background:var(--fc-badge-bg-r) !important;
          border-color:var(--fc-badge-bg-r) !important; color:var(--fc-badge-r) !important; }
.tt-wrap.fc .tt-tags .btn-link{ color:var(--fc-accent); }

/* Row markers: future entries, noted runner, the system-qualifier gear. */
.tt-wrap.fc .tt-mark{ display:inline-flex; align-items:center; padding:0 3px; border:0;
          background:none; color:var(--fc-ink-3); font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-mark:hover{ color:var(--fc-ink); }
.tt-wrap.fc .tt-mark.is-sys{ color:var(--fc-val-a); }
.tt-wrap.fc .tt-mark.is-intel{ color:var(--fc-accent); }

/* The ordering control, beside the toolbar buttons. */
.tt-wrap.fc .tt-orderlbl{ color:var(--fc-ink-3); font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-order{ padding:4px 8px; border-radius:4px; border:1px solid var(--fc-hair);
          background:var(--fc-inset); color:var(--fc-ink);
          font-size:calc(12px * var(--fc-scale)); }

/* Racecourse guide, opened from a chip in the race header. */
.tt-wrap.fc .tt-chip-btn{ cursor:pointer; border-style:dashed; }
.tt-wrap.fc .tt-courseinfo{ margin:8px 0 0; }
.tt-wrap.fc .tt-courseinfo[hidden]{ display:none !important; }

/* The detailed race board on today's racing. */
.tt-wrap.fc .tt-board{ margin-top:14px; }

/* Which day's cards to show. Bootstrap gives `label` its own colour, so the token has to
   be set on the element rather than inherited from the bar. */
.tt-wrap.fc .tt-datebar{ display:flex; align-items:center; flex-wrap:wrap; gap:8px;
          margin:0 0 12px; font-size:calc(13px * var(--fc-scale)); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-datebar label{ margin:0; color:var(--fc-ink-2);
          font-size:calc(13px * var(--fc-scale)); font-weight:500; }
.tt-wrap.fc .tt-datebar input[type="date"]{ padding:5px 8px; border-radius:6px;
          border:1px solid var(--fc-line-2); background:var(--fc-surface);
          color:var(--fc-ink); font:inherit; }

/* The newsletter prompt is anonymous-only and unstyled apart from Bootstrap, so it inherits
   an h5 colour chosen against white. It appears in the footer of every page, which is why it
   only surfaced on a logged-out audit. */
.tt-wrap.fc .bt-newsletter-prompt{ padding:12px; border:1px solid var(--fc-line);
          border-radius:8px; background:var(--fc-surface-2); color:var(--fc-ink-2); }
.tt-wrap.fc .bt-newsletter-prompt h5{ color:var(--fc-ink); }
.tt-wrap.fc .bt-newsletter-prompt .text-muted{ color:var(--fc-ink-3) !important; }

/* Quick Settings, opened from the toolbar. */
.tt-wrap.fc .tt-quicksettings{ margin:0 0 12px; }
.tt-wrap.fc .tt-quicksettings[hidden]{ display:none !important; }

/* DataTables sort indicators. Hyper draws these from Remix Icon, whose @import
   build_turtle_css.py strips -- so in this theme the glyphs had no font at all and every
   sortable column showed nothing. Redrawn from self-hosted Font Awesome, which keeps the
   966k saving that dropping the import bought. */
/* Scoped to the THEME, not to .tt-sheet: the Race Profile fit table sits in a .tt-panel and
   had no sort indicator at all, so a sortable column looked like a fixed one. Every
   DataTable in this theme gets the same arrows wherever it is reused. */
.tt-wrap.fc table.dataTable thead th:after,
.tt-wrap.fc table.dataTable thead td:after{
          font-family:"Font Awesome 7 Pro" !important; font-weight:900;
          content:"\f0dc"; color:var(--fc-on-thead, #ffffff); opacity:.55;
          font-size:calc(11px * var(--fc-scale)); margin-left:6px; }
.tt-wrap.fc table.dataTable thead th[aria-sort="ascending"]:after{
          content:"\f0de"; opacity:1; }
.tt-wrap.fc table.dataTable thead th[aria-sort="descending"]:after{
          content:"\f0dd"; opacity:1; }
/* Hyper hides the indicator on the un-sortable columns; keep that. */
.tt-wrap.fc table.dataTable thead th.sorting_disabled:after{ content:none; }
/* The fit table's top row is a spanning group header — nothing there sorts. */
.tt-wrap.fc table.dataTable thead tr:first-child th[colspan]:after,
.tt-wrap.fc table.dataTable thead tr:first-child th:empty:after{ content:none; }

/* ---------------------------------------------------------------------------------------
   Popovers and tooltips.

   Bootstrap renders these into <body>, outside `.tt-wrap.fc`, so they inherit none of the
   theme's tokens and fell through to the classic cascade -- and because the turtle theme
   switches on `data-fc-theme` while the classic dark rules key off `data-bs-theme`, a dark
   turtle user got a LIGHT popover over a dark card.

   These selectors are deliberately unscoped: `.tt-pop` is added by btThemePopClass() only
   when the turtle shell is present, so nothing here can reach the classic UI. The tokens are
   redeclared rather than inherited, for the same reason.

   Dark keys off `:root[data-fc-theme]` rather than a second class, because a popover in
   <body> is still a descendant of :root -- so switching theme restyles open popovers, where
   a class fixed at construction time would go stale.
   --------------------------------------------------------------------------------------- */

/* 360px was narrower than the tables these popovers carry -- the last-six run table is 543px
   and simply drew OUTSIDE the box, across the page, because `.popover-body` was
   `overflow-x:visible`. Wide enough for the content, capped to the viewport, and anything
   still wider scrolls inside its own box rather than escaping. The height cap matters as
   much: a 1089px-tall popover in a 1100px viewport has nowhere to go and Popper pins it to
   the top of the screen, far from the cell that was clicked. */
.tt-pop.popover{ background:var(--fc-pop-bg); border:1px solid var(--fc-line);
          border-radius:8px; box-shadow:0 6px 24px rgba(0,0,0,.28);
          max-width:min(980px, calc(100vw - 24px)); }
.tt-pop .popover-body{ overflow-x:auto; overflow-y:auto;
          max-height:min(78vh, 720px); overscroll-behavior:contain; }
.tt-pop .popover-header{ background:var(--fc-thead); color:#ffffff;
          border-bottom:1px solid var(--fc-line); border-radius:7px 7px 0 0;
          font-size:calc(13px * var(--fc-scale, 1.15)); font-weight:600; }
.tt-pop .popover-body{ background:var(--fc-pop-bg); color:var(--fc-ink-2);
          font-size:calc(13px * var(--fc-scale, 1.15)); }
.tt-pop .popover-body a{ color:var(--fc-accent); }
.tt-pop .popover-arrow::after{ border-top-color:var(--fc-pop-bg);
          border-bottom-color:var(--fc-pop-bg);
          border-left-color:var(--fc-pop-bg); border-right-color:var(--fc-pop-bg); }
.tt-pop .popover-arrow::before{ border-top-color:var(--fc-line);
          border-bottom-color:var(--fc-line);
          border-left-color:var(--fc-line); border-right-color:var(--fc-line); }

/* Content inside a popover is the classic fragments' markup, so it needs the same
   remapping the .tt-sheet pages get. */
.tt-pop .popover-body table{ color:var(--fc-ink-2); }
.tt-pop .popover-body thead th{ background:var(--fc-thead) !important; color:#ffffff !important; }
/* ...and the icons in it. They keep the key's colours rather than going white, on a pale chip
   of their own -- a true red cannot reach even the 3:1 non-text floor on the light green head
   (the best is 2.35) and lightening it far enough turns it pink. On its own ground each glyph
   carries the SAME hex as the legend under the table, so the head and the key match exactly. */
.tt-pop .popover-body thead th i,
.tt-pop .popover-body thead th span[class*="fa-"],
.tt-wrap.fc .tt-sheet table > thead i,
.tt-wrap.fc .tt-sheet table > thead span[class*="fa-"],
.tt-wrap.fc .tt-sheet .card-header i,
.tt-wrap.fc .tt-sheet .card-header span[class*="fa-"]{
          background:#ffffff; border-radius:50%; padding:3px;
          width:1.55em; height:1.55em; line-height:1em;
          display:inline-flex; align-items:center; justify-content:center;
          color:var(--fc-perf-good) !important; }
/* Star good, thumb-up moderate, thumb-down poor -- yellow, green, red. The chip is white, so
   the green is measured against white (5.88:1), not against the head it sits in. */
.tt-pop .popover-body thead th :is(i,span)[class*="fa-thumbs-up"],
.tt-wrap.fc .tt-sheet table > thead :is(i,span)[class*="fa-thumbs-up"],
.tt-wrap.fc .tt-sheet .card-header :is(i,span)[class*="fa-thumbs-up"]{
          color:var(--fc-perf-mid) !important; }
.tt-pop .popover-body thead th :is(i,span)[class*="fa-thumbs-down"],
.tt-wrap.fc .tt-sheet table > thead :is(i,span)[class*="fa-thumbs-down"],
.tt-wrap.fc .tt-sheet .card-header :is(i,span)[class*="fa-thumbs-down"]{
          color:var(--fc-perf-poor) !important; }

/* The key under the table, so it says the same thing. Both thumbs carry the theme's own
   value inks wherever they appear in the turtle wrap -- the pair the Icon Help panel uses.
   Turtle only -- the classic markup is untouched. */
.tt-wrap.fc .tt-sheet .fa-star.text-warning,
.tt-pop .popover-body .fa-star.text-warning{ color:var(--fc-star) !important;
          text-shadow:var(--fc-star-edge); }
.tt-wrap.fc .fa-thumbs-up.text-success,
.tt-pop .popover-body .fa-thumbs-up.text-success{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .fa-thumbs-down.text-danger,
.tt-pop .popover-body .fa-thumbs-down.text-danger{ color:var(--fc-val-r) !important; }
.tt-pop .popover-body .table-striped > tbody > tr:nth-of-type(odd) > *{
          box-shadow:none !important; background:var(--fc-zebra) !important; color:var(--fc-ink-2); }
.tt-pop .popover-body .text-success{ color:var(--fc-val-g) !important; }
.tt-pop .popover-body .text-warning{ color:var(--fc-val-a) !important; }
.tt-pop .popover-body .text-danger{ color:var(--fc-val-r) !important; }
.tt-pop .popover-body .text-muted{ color:var(--fc-ink-3) !important; }
.tt-pop .popover-body .bg-light{ background:var(--fc-inset) !important; color:var(--fc-ink-2) !important; }
/* The classic fragments' remaining Bootstrap vocabulary. These are chosen against a white
   page: info cyan and the badge fills are the two that land on the popover's dark ground. */
.tt-pop .popover-body .text-info{ color:var(--fc-accent) !important; }
.tt-pop .popover-body .border-info{ border-color:var(--fc-accent) !important; }
.tt-pop .popover-body .text-primary{ color:var(--fc-accent) !important; }
.tt-pop .popover-body .badge{ color:var(--fc-accent-ink) !important; }
.tt-pop .popover-body .badge.bg-success{ background:var(--fc-good) !important; }
.tt-pop .popover-body .badge.bg-danger{ background:var(--fc-poor) !important; }
.tt-pop .popover-body .badge.bg-warning{ background:var(--fc-fair) !important; }
.tt-pop .popover-body .badge.bg-primary,
.tt-pop .popover-body .badge.bg-info{ background:var(--fc-accent) !important; }
.tt-pop .popover-body .badge.bg-secondary{ background:var(--fc-inset) !important;
          color:var(--fc-ink-2) !important; }
/* The popover root's own colour is Bootstrap's body grey. Content that sits outside
   .popover-body inherits it, on the popover's own ground. */
.tt-pop.popover{ color:var(--fc-ink-2); }

.tt-pop.tooltip .tooltip-inner{ background:var(--fc-pop-bg); color:var(--fc-ink);
          border:1px solid var(--fc-line);
          font-size:calc(12px * var(--fc-scale, 1.15)); }
.tt-pop.tooltip .tooltip-arrow::before{ border-top-color:var(--fc-pop-bg);
          border-bottom-color:var(--fc-pop-bg);
          border-left-color:var(--fc-pop-bg); border-right-color:var(--fc-pop-bg); }

/* Hyper paints `.topnav` with its indigo brand gradient. The turtle chrome restyled the
   navbar itself but not that container, so it only showed for anonymous visitors -- whose
   nav links then sat on indigo at 2.96:1. Same for the footer's muted grey on near-white. */
.tt-wrap.fc .topnav{ background-image:none !important; background:var(--fc-band-bg) !important; }
.tt-wrap.fc .topnav .nav-link,
.tt-wrap.fc .topnav .navbar-nav .nav-link{ color:var(--fc-ink) !important; }
.tt-wrap.fc .topnav .nav-link:hover,
.tt-wrap.fc .topnav .nav-link:focus,
.tt-wrap.fc .topnav .nav-link.active{ color:var(--fc-accent) !important; }
.tt-wrap.fc .footer,
.tt-wrap.fc .footer .container-fluid{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .footer a{ color:var(--fc-accent) !important; }

/* Bootstrap alerts. Twenty-one of them across the sixteen chrome fragments -- the goal
   prompt, the tier banners, the messages framework -- all painted in Bootstrap's own
   pastels, which read as foreign on either turtle ground and jarring on the dark one.
   They are chrome, so they sit outside `.tt-sheet` and nothing had mapped them. */
.tt-wrap.fc .alert{ background:var(--fc-surface-2) !important; color:var(--fc-ink-2) !important;
          border:1px solid var(--fc-line) !important; border-radius:8px; }
.tt-wrap.fc .alert .alert-heading,
.tt-wrap.fc .alert strong{ color:var(--fc-ink) !important; }
.tt-wrap.fc .alert a:not(.btn){ color:var(--fc-accent) !important; }
.tt-wrap.fc .alert .text-primary,
.tt-wrap.fc .alert .text-info{ color:var(--fc-accent) !important; }
.tt-wrap.fc .alert .text-success{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .alert .text-warning{ color:var(--fc-val-a) !important; }
.tt-wrap.fc .alert .text-danger{ color:var(--fc-val-r) !important; }
.tt-wrap.fc .alert .btn-primary,
.tt-wrap.fc .alert .btn-success{ background:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; color:var(--fc-accent-ink) !important; }
/* Each variant keeps its meaning through the left edge rather than a pastel fill. */
.tt-wrap.fc .alert-success{ border-left:4px solid var(--fc-good) !important; }
.tt-wrap.fc .alert-info,
.tt-wrap.fc .alert-primary{ border-left:4px solid var(--fc-accent) !important; }
.tt-wrap.fc .alert-warning{ border-left:4px solid var(--fc-fair) !important; }
.tt-wrap.fc .alert-danger{ border-left:4px solid var(--fc-poor) !important; }
.tt-wrap.fc .alert .btn-close{ filter:var(--fc-close-filter, none); }
:root[data-fc-theme="dark"] .tt-wrap.fc .alert .btn-close{ filter:invert(1) grayscale(1) brightness(2); }

/* Row markers restored alongside the form figures. */
.tt-wrap.fc .tt-days{ color:var(--fc-ink-3); white-space:nowrap; }
/* Course/distance winner reads as a phrase in the tag row, not a letter badge. */
.tt-wrap.fc .tt-tag-cd{ border-color:var(--fc-line-2); color:var(--fc-accent); }
.tt-wrap.fc .tt-rateswrap{ min-width:0; }

/* The statistics panel's own filtered/all switch. */
/* The two buttons sat on their own above the tab row and read as page furniture rather than
   as a control belonging to these statistics. Named, boxed and on the panel's own inset, so
   what they govern is the thing underneath them. */
.tt-wrap.fc .tt-statscope-bar{ display:flex; align-items:center; flex-wrap:wrap; gap:10px;
          margin:0 0 12px; padding:8px 10px; border:1px solid var(--fc-hair);
          border-radius:8px; background:var(--fc-inset); }
.tt-wrap.fc .tt-statscope-label{ font-weight:600; color:var(--fc-ink);
          font-size:calc(13px * var(--fc-scale)); }
.tt-wrap.fc .tt-statscope-note{ color:var(--fc-ink-2); font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-statscope{ display:flex; gap:4px; margin:0; }
.tt-wrap.fc .tt-statscope .tt-seg{ padding:4px 12px; }
.tt-wrap.fc .tt-statscope .tt-seg[disabled]{ opacity:.55; cursor:default; }

/* The interactive career chart replaces the inline SVG once it has rendered. */
.tt-wrap.fc .tt-chart-live{ width:100%; min-height:0; }
.tt-wrap.fc .tt-chart-live[hidden]{ display:none !important; }
.tt-wrap.fc .tt-chart svg[hidden]{ display:none !important; }
/* Quick Settings autosave. The state has to be readable without colour alone, so the
   words carry it and the colour only reinforces. */
.tt-wrap.fc .tt-savenote{ margin:10px 0 0; min-height:1.2em;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink-3); }
.tt-wrap.fc .tt-savenote.is-ok{ color:var(--fc-accent); }
.tt-wrap.fc .tt-savenote.is-bad{ color:var(--fc-poor); font-weight:600; }

/* Shortlist and hide, beside the comment. The controls already existed but only inside the
   actions menu, which is the last place somebody who has just read a comment will look. */
.tt-wrap.fc .tt-commentacts{ display:flex; align-items:center; gap:10px; margin-top:6px; }
.tt-wrap.fc .tt-commentact{ display:inline-flex; align-items:center; gap:5px;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink-3); }
.tt-wrap.fc .tt-commentact:hover{ color:var(--fc-ink); }
.tt-wrap.fc .tt-commentact .tt-actlbl{ font-size:inherit; }

/* The runner's record against today's race. Sits above the tabs, so it is the first thing
   read whichever tab is open. */
.tt-wrap.fc .tt-insightline{ display:flex; gap:8px; align-items:flex-start;
          margin:0 0 10px; padding:8px 11px; border-radius:6px;
          border-left:3px solid var(--fc-accent); background:var(--fc-surface-2);
          color:var(--fc-ink-2); font-size:max(12px, calc(13px * var(--fc-scale)));
          line-height:1.5; }
.tt-wrap.fc .tt-insightline > i{ color:var(--fc-accent); margin-top:3px; }

/* The price trend. Labelled at both ends so the line has a direction the reader can name. */
.tt-wrap.fc .tt-oddstrend{ margin:10px 0 4px; }
.tt-wrap.fc .tt-oddstrend figcaption{ display:flex; justify-content:space-between;
          color:var(--fc-ink-3); margin-top:2px;
          font-size:max(10px, calc(11px * var(--fc-scale))); }
/* The line matches the arrow: green shortening, red drifting. A price that has not
   moved far enough to say anything keeps the neutral ink. */
.tt-wrap.fc .tt-spark-odds.is-in polyline{ stroke:var(--fc-val-g); }
.tt-wrap.fc .tt-spark-odds.is-out polyline{ stroke:var(--fc-move-out); }
.tt-wrap.fc .tt-spark-odds.is-in circle{ fill:var(--fc-accent); }

/* The whole comment block goes from the FORM fragment: the suitability ticks, the summary
   line and the bullet list are what the Insights tab is for, and the drawer was showing all
   of it twice. What stays in the Horse & Trainer sub-tab is what Insights does NOT have --
   the pedigree table, the consistency stats and the run stats.

   Hidden here rather than removed from the fragment, because the classic card's row does not
   show the comment at all: that tab is where its customers read it. The customer's own saved
   note goes with it, and is still reachable in Insights. */
.tt-wrap.fc .tt-formfull .bt-comments{ display:none !important; }

/* And with it the whole Horse & Trainer sub-tab. Every part of it is elsewhere in the drawer:
   the comment block in Insights, Consistency and Lifetime as packs under Form, the trainer and
   jockey records under Why, and the pedigree in Form's key facts. Hidden only inside the turtle
   drawer: on the classic card this is the fragment's default tab and carries content its
   customers have nowhere else. */
.tt-wrap.fc .tt-formfull .nav-item:has(> [href*="horsemenu"]){ display:none !important; }

/* Form Grid plots the same career runs as Lifetime Runs, which sits two tabs to its left. */
.tt-wrap.fc .tt-formfull .nav-item:has(> [href*="formgridmenu"]){ display:none !important; }

/* Race Profile / 10 Year Trends are chips in the brief bar above, so the statistics panel's
   own copy of that tab is a second way into the same page. Hidden here only: on the classic
   card that tab is the only way to reach it. */
.tt-wrap.fc .tt-statspanel .nav-item:has(> [href*="trendsmenu"]){ display:none !important; }

/* The AI comment is on the row already, so its repeat at the head of Insights goes. With the
   form table, the suitability ticks and the comment card all switched off it is the whole of
   the FETCHED fragment, which then renders nothing -- the loader says so in that case rather
   than leaving an empty box under the profile pack. The customer's own comment and the
   "available by 6am" notice are neither a repeat nor hidden. */
.tt-wrap.fc [data-tt-insight] .bt-comments > .alert:has(strong):not(:has(p)){
          display:none !important; }
.tt-wrap.fc [data-tt-insight] .bt-comments > .alert:has(p) > strong{ display:none !important; }

/* Headgear. Boxed rather than capitalised: the codes are lower case everywhere in racing,
   and a box makes them findable without shouting. First-time headgear says the yard has
   changed something, so it carries the accent. */
.tt-wrap.fc .tt-gear{ display:inline-block; padding:0 4px; border-radius:3px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink-2); font-size:.92em; line-height:1.45; }
.tt-wrap.fc .tt-gear.is-first{ border-color:var(--fc-accent); color:var(--fc-ink);
          font-weight:600; }
.tt-wrap.fc .tt-gearfirst{ color:var(--fc-ink-2); font-weight:500; }

/* The last six finishing positions, oldest first. */
.tt-wrap.fc .tt-formrun{ display:flex; align-items:center; flex-wrap:wrap; gap:4px;
          margin-top:8px; font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-formrun b{ color:var(--fc-ink-2); margin-right:2px; }
.tt-wrap.fc .tt-formrun em{ color:var(--fc-ink-3); font-style:normal; margin-left:4px;
          font-size:.9em; }
.tt-wrap.fc .tt-pos{ display:inline-flex; align-items:center; justify-content:center;
          min-width:20px; height:20px; padding:0 4px; border-radius:3px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink-2); font-variant-numeric:tabular-nums; }
.tt-wrap.fc .tt-pos.is-win{ border-color:var(--fc-accent); color:var(--fc-ink);
          font-weight:700; }
.tt-wrap.fc .tt-pos.is-place{ border-color:var(--fc-line); color:var(--fc-ink); }
.tt-wrap.fc .tt-pos.is-none{ color:var(--fc-ink-3); border-style:dashed; }
.tt-wrap.fc .tt-runorder{ margin-bottom:4px; }

/* Filters on/off. `is-go` is the normal state -- the customer's filter is being applied --
   so the OFF state is the one that has to look deliberate rather than broken. */
.tt-wrap.fc .tt-tool.is-off{ background:var(--fc-inset); border-style:dashed;
          border-color:var(--fc-line-2); color:var(--fc-ink-3); }
.tt-wrap.fc .tt-tool.is-off:hover{ color:var(--fc-ink); border-color:var(--fc-accent); }

/* Charts on or off across the card. Both drawings the button names -- the stat-pack and
   price figures, and the sparkline beside each rating line -- and the live ApexCharts layer
   that renders over the figure. */
.tt-wrap.fc .tt-runners.is-nocharts .tt-chart,
.tt-wrap.fc .tt-runners.is-nocharts .tt-rowchart,
.tt-wrap.fc .tt-runners.is-nocharts .tt-rowspark,
.tt-wrap.fc .tt-runners.is-nocharts .tt-sixline .tt-spark{ display:none !important; }

/* The Apex layer sits where the SVG does and replaces it once it has rendered, so there is
   never a moment with two lines drawn. */
/* Fixed to the SVG's own box. Sparkline mode expands to whatever it is given, and given a
   button's content box it drew a line across the horseshoes. */
.tt-wrap.fc .tt-rowchart{ display:block; position:relative; line-height:0; overflow:hidden;
          width:50px; height:25px; margin:1px auto 0; }
/* The rating chip is a baseline flex row, so the chart landed BESIDE the figure and the three
   chips grew wide enough to squeeze each other. Given a full-width basis it wraps underneath,
   which is where it was asked for. */
.tt-wrap.fc .tt-rate{ flex-wrap:wrap; }
/* Price and its arrow stay on one line; the chart goes underneath them. */
.tt-wrap.fc .tt-oddsline{ display:inline-flex; align-items:center; gap:2px; white-space:nowrap; }
.tt-wrap.fc .tt-rate .tt-rowchart{ flex:0 0 100%; }
.tt-wrap.fc .tt-rowchart .tt-chart-live{ display:block; width:100%; height:25px; }
.tt-wrap.fc .tt-rowchart .apexcharts-canvas,
.tt-wrap.fc .tt-rowchart .apexcharts-canvas svg{ width:100% !important; height:25px !important; }
/* `is-live` is only set when an Apex chart actually renders, which it does not while
   `ttApexSeries` is off -- so the inline graph stays visible. Left in place for when it is
   switched back on. */
.tt-wrap.fc .tt-rowchart.is-live > .tt-rowspark{ display:none; }
.tt-wrap.fc .tt-rowchart .apexcharts-canvas{ margin:0 auto; }
@media print{ .tt-wrap.fc .tt-rowchart .tt-chart-live{ display:none; }
              .tt-wrap.fc .tt-rowchart.is-live > .tt-rowspark{ display:block; } }

/* The six-run line under a rating, and the price line under the price. Its own block so the
   chip lays out as figure-over-line rather than figure-beside-line. */
.tt-wrap.fc .tt-rowspark{ display:block; margin:1px auto 0; overflow:visible; }
.tt-wrap.fc .tt-rowspark polyline{ fill:none; stroke:var(--fc-ink-3); stroke-width:1.2;
          stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke; }
.tt-wrap.fc .tt-rowspark circle{ fill:var(--fc-ink-2); }
.tt-wrap.fc .tt-rowspark.is-up polyline{ stroke:var(--fc-val-g); }
.tt-wrap.fc .tt-rowspark-odds.is-in polyline{ stroke:var(--fc-val-g); }
.tt-wrap.fc .tt-rowspark-odds.is-out polyline{ stroke:var(--fc-move-out); }

/* A tablet in portrait draws with Apex, a phone with the inline SVG, and the Charts button is
   offered wherever there is a drawing to switch off (Kenny, 4 Sep). */
@media (max-width: 991px){
  .tt-wrap.fc .tt-rate{ flex-wrap:wrap; }
  .tt-wrap.fc .tt-rate .tt-rowchart{ flex:0 0 100%; }
}

/* Market direction, and the short series behind a rating.
   Green shortening, red drifting (Kenny, 31 Aug 2026). The value inks rather than the
   horseshoe pair: these sit on the row ground at 10px, where the glyph inks do not clear AA. */
.tt-wrap.fc .tt-move-in{ color:var(--fc-val-g); margin-left:3px;
          font-size:max(9px, calc(10px * var(--fc-scale))); }
.tt-wrap.fc .tt-move-out{ color:var(--fc-move-out); margin-left:3px;
          font-size:max(9px, calc(10px * var(--fc-scale))); }

.tt-wrap.fc .tt-spark{ display:inline-block; vertical-align:middle; margin:0 8px;
          overflow:visible; }
.tt-wrap.fc .tt-spark polyline{ fill:none; stroke:var(--fc-ink-3); stroke-width:1.4;
          stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke; }
.tt-wrap.fc .tt-spark circle{ fill:var(--fc-ink-2); }
.tt-wrap.fc .tt-spark.is-up polyline{ stroke:var(--fc-accent); }
.tt-wrap.fc .tt-spark.is-up circle{ fill:var(--fc-accent); }
.tt-wrap.fc .tt-spark-odds{ display:block; width:100%; margin:8px 0 4px; }
.tt-wrap.fc .tt-sixline{ display:flex; align-items:center; flex-wrap:wrap; gap:2px 4px; }

/* Once ApexCharts has taken over, the static fallback and its own caption and key go.
   The child combinator is load-bearing: the fallback drawing is a DIRECT child of the
   figure, while ApexCharts renders its own <svg> inside .tt-chart-live. A descendant
   selector here hid the chart it had just drawn -- it appeared, then blanked. */
.tt-wrap.fc .tt-chart.is-live > svg,
.tt-wrap.fc .tt-chart.is-live > figcaption,
.tt-wrap.fc .tt-chart.is-live > .tt-chart-key{ display:none !important; }
/* While Apex is fetching, the static drawing stays out of the way rather than appearing and
   being replaced a moment later. The height is held so the pane does not jump when the chart
   lands; it matches options.chart.height in betturtle-turtle.js. If Apex gives up, the class
   comes off and the drawing takes over. */
.tt-wrap.fc .tt-chart.is-pending{ min-height:260px; }
/* The price chart is shorter than the career ones, so it holds its own height while it
   loads rather than reserving space it will not use. */
.tt-wrap.fc .tt-oddstrend.is-pending{ min-height:210px; }
.tt-wrap.fc .tt-chart.is-pending > svg,
.tt-wrap.fc .tt-chart.is-pending > figcaption,
.tt-wrap.fc .tt-chart.is-pending > .tt-chart-key{ display:none !important; }

/* Comments mode. One copy of the comment, revealed either when its own drawer is open or
   when the whole card is in Comments mode. */
.tt-wrap.fc .tt-rowcomment{ display:none; grid-column:1 / -1; margin:6px 0 2px;
          padding:8px 10px; border-left:3px solid var(--fc-accent);
          background:var(--fc-surface-2); border-radius:0 6px 6px 0; }
.tt-wrap.fc .tt-runner.is-open .tt-rowcomment,
.tt-wrap.fc .tt-runners.is-comments .tt-rowcomment{ display:block; }
.tt-wrap.fc .tt-rowcomment .tt-comment{ margin:0; }
.tt-wrap.fc .tt-whybtn{ margin-top:6px; padding:3px 10px; border-radius:5px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink); cursor:pointer; font:inherit;
          font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-whybtn:hover{ background:var(--fc-hover); }
/* The drawer opens on Why, so the button that opens Why has nothing left to do. */
/* The button STAYS when the drawer opens (Kenny, 31 Aug, twice). It used to be hidden
   here, so the control that opened the panel vanished and there was no way back out
   with it. It is lit while open and closes what it opened. */
/* No dimming of the ratings in Comments mode. Fading them to .55 measured 2.2-3.6:1 on
   every value ink -- legible data pushed below AA to make a stylistic point. The comment's
   own accent border already gives it the lead. */

/* Winner-profile traits on the row (Enhanced). The chip names how many of the race's own
   winner traits a runner matches and opens the list; `is-best` marks a closest match, which
   is the same set the Race Profile panel's "closest matches" names. */
/* `font:inherit` gave the traits button the row's ~13px instead of the tag's 10px, so it
   sat a size and a weight above the tags beside it and read as the loudest thing on the row.
   Inherit the family only; the rest matches .tt-tag exactly. */
.tt-wrap.fc button.tt-tag-fit{ cursor:pointer; font-family:inherit; display:inline-flex;
          align-items:center; gap:4px; text-transform:uppercase; letter-spacing:.04em;
          font-weight:600; font-size:max(10px, calc(10px * var(--fc-scale)));
          line-height:1.35; padding:1px 6px; border-radius:3px; }
.tt-wrap.fc button.tt-tag-fit i{ font-size:.85em; }
.tt-wrap.fc .tt-tag-fit.is-best{ border-color:var(--fc-accent);
          background:color-mix(in srgb, var(--fc-accent) 16%, transparent);
          color:var(--fc-ink); font-weight:600; }
.tt-wrap.fc button.tt-tag-fit[aria-expanded="true"]{ border-color:var(--fc-accent); }
.tt-wrap.fc .tt-rowtraits{ margin:6px 0 2px; padding:8px 10px; border-radius:8px;
          background:var(--fc-inset); border:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-rowtraits-head{ margin:0 0 5px; color:var(--fc-ink); font-weight:600;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-rowtraits-line{ display:flex; gap:7px; margin:0 0 4px;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink-2);
          line-height:1.45; }
.tt-wrap.fc .tt-rowtraits-line b{ color:var(--fc-ink); font-weight:600; }
.tt-wrap.fc .tt-rowtraits-line.is-tick i{ color:var(--fc-val-g); }
.tt-wrap.fc .tt-rowtraits-line.is-cross i{ color:var(--fc-val-r); }
.tt-wrap.fc .tt-rowtraits-note.is-best{ color:var(--fc-ink-2); font-weight:600; }
.tt-wrap.fc .tt-rowtraits-note{ margin:2px 0 0; color:var(--fc-ink-3);
          font-size:max(11px, calc(11.5px * var(--fc-scale))); }

/* 10 Year Trends: the footer records, and today's runners that have been here before. The
   table above is past winners; this is the other question the same history answers. */
.tt-wrap.fc .tt-trendfoot{ margin:8px 0 0; }
/* The year links to that running's own card. The sheet's link rule paints links in the
   accent, which on this ground is 2.97:1 -- the same defect as the Odds column headings.
   A link inside a data table reads as one by its underline, not its hue. */
.tt-wrap.fc .tt-table .tt-year a{ color:var(--fc-ink) !important;
          text-decoration:underline; text-underline-offset:2px;
          text-decoration-color:var(--fc-line); }
.tt-wrap.fc .tt-table .tt-year a:hover{ text-decoration-color:var(--fc-ink-2); }
.tt-wrap.fc .tt-returners{ margin-top:14px; padding-top:12px;
          border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-returners-h{ margin:0 0 8px; color:var(--fc-ink); font-weight:600;
          font-size:max(12px, calc(13.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-returner{ margin-bottom:9px; }
.tt-wrap.fc .tt-returner-n{ margin:0; display:flex; flex-wrap:wrap; align-items:baseline;
          gap:8px; font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink); }
.tt-wrap.fc .tt-returner-run{ color:var(--fc-ink-2); }
.tt-wrap.fc .tt-returner-run.is-won{ color:var(--fc-val-g); font-weight:600; }
.tt-wrap.fc .tt-returner-d{ margin:2px 0 0; color:var(--fc-ink-3);
          font-size:max(11px, calc(12px * var(--fc-scale))); }

/* What the three rating lines show, stated. Computed arithmetic over the same numbers. */
.tt-wrap.fc .tt-ratingread{ margin:8px 0 2px; padding:8px 10px; border-radius:8px;
          background:var(--fc-inset); border:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-ratingread p{ margin:0 0 4px; color:var(--fc-ink-2); line-height:1.5;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-ratingread p:last-child{ margin-bottom:0; }

/* Today's racing: the reused board, with the three tabs this page already answers hidden.
   Scoped to .tt-board so the classic races page keeps all six. Hiding the tab is not enough
   -- its pane carries `active` from the fragment, so the board would open on a hidden pane
   and read as empty. The first visible tab is activated in JS for that reason. */
/* Two of the board's tabs, Races and Times, repeat the "Meetings today" section directly
   above them -- the same courses and the same time buttons. They are hidden; NEXT RACES stays,
   along with Non-Runners, Tomorrow and the days after, because none of those is anywhere else
   on the page.

   The turtle "Next off" strip went instead of this tab: the board's version is the fuller one
   and is what the classic page offered. Removing the tab and keeping the strip would have
   given the smaller answer. */
.tt-wrap.fc .tt-board .nav-item:has(> a[href="#times_detailedmenu"]),
.tt-wrap.fc .tt-board .nav-item:has(> a[href="#times_shortmenu"]),
.tt-wrap.fc .tt-board .nav-item:has(> a[href="#timeordermenu"]){ display:none; }
.tt-wrap.fc .tt-board #times_detailedmenu,
.tt-wrap.fc .tt-board #times_shortmenu,
.tt-wrap.fc .tt-board #timeordermenu{ display:none !important; }

/* Prose links inside a panel take the sheet's accent, which on the light ground is 3.55:1.
   A link in running text reads as one by its underline. */
.tt-wrap.fc .tt-panel p a,
.tt-wrap.fc .tt-body a{ color:var(--fc-ink) !important; text-decoration:underline;
          text-underline-offset:2px; text-decoration-color:var(--fc-line); }
.tt-wrap.fc .tt-panel p a:hover,
.tt-wrap.fc .tt-body a:hover{ text-decoration-color:var(--fc-ink-2); }

/* A finished race's time button is faded to `opacity: 0.3` by an inline style in
   races/v2/snippets/timebutton.html. It is not a disabled control -- it has no disabled
   attribute, keeps pointer events, is keyboard focusable and links to that race's card -- so
   WCAG's exemption for inactive components does not apply, and at .3 the label measures
   1.76:1. Measured across the range: .7 still fails at 4.00, .8 is the first value that
   clears AA on both button variants at 4.82.

   !important because the fade is an inline style. Scoped to .tt-board so the classic page
   keeps what it has today -- where the same 0.3 is just as unreadable. */
.tt-wrap.fc button.btn[style*="opacity"]{ opacity:.8 !important; }

/* A career-form row that is a previous running of today's race. */
.tt-wrap.fc .tt-formfull tr.is-prevrun{ background:color-mix(in srgb, var(--fc-accent) 12%, transparent); }
/* Under the date, not beside it: inline, the tag set the column's width for every row in
   the table, and the date column is the one the reader scans down. */
.tt-wrap.fc .tt-prevrun{ display:block; width:fit-content; margin:3px 0 0; padding:1px 5px;
          border-radius:4px; background:var(--fc-accent); color:var(--fc-accent-ink);
          font-size:max(10px, calc(10.5px * var(--fc-scale))); font-weight:700;
          letter-spacing:.02em; white-space:nowrap; }

/* DataTables 2 sort indicators. It renders `span.dt-column-order` and draws the arrows with
   ::before/::after; that CSS is not in the turtle build, so every sortable header lost its
   affordance -- the columns still sorted, nothing said they could. Plain triangles rather
   than an icon font: the indicator should not depend on a webfont that a stylesheet strip
   can remove, which is how the classic card lost the same arrows to Remix Icon.

   betturtle-base.css overlays the control at opacity 0 and reveals it on hover or on the
   sorted column only, in a 6px box -- so a reader who does not already know the header is
   sortable has nothing to tell them, and the glyph is clipped. Both are overridden here; the
   base rule carries !important on the width, so these do too.

   currentColor, not --fc-ink: the table head is a dark ground carrying white text, where the
   page ink is invisible. */
.tt-wrap.fc table.dataTable thead th span.dt-column-order{
          position:absolute; right:1px !important; top:50%; transform:translateY(-50%);
          width:7px !important; min-width:7px !important; height:16px;
          opacity:1 !important; pointer-events:none; }
/* The pair sits symmetrically about the middle of the box, so the two glyphs together read
   as centred against the header text rather than hanging off its baseline. */
.tt-wrap.fc table.dataTable thead th.dt-orderable-asc span.dt-column-order::before,
.tt-wrap.fc table.dataTable thead th.dt-orderable-desc span.dt-column-order::after{
          position:absolute; left:0; right:0; display:block; text-align:center;
          font-size:7px; line-height:7px; color:currentColor; opacity:.62; }
.tt-wrap.fc table.dataTable thead th.dt-orderable-asc span.dt-column-order::before{
          content:"\25B2"; top:0; }
.tt-wrap.fc table.dataTable thead th.dt-orderable-desc span.dt-column-order::after{
          content:"\25BC"; bottom:0; }
/* The column actually in use reads at full strength. */
.tt-wrap.fc table.dataTable thead th.dt-ordering-asc span.dt-column-order::before,
.tt-wrap.fc table.dataTable thead th.dt-ordering-desc span.dt-column-order::after{
          opacity:1; }
.tt-wrap.fc table.dataTable thead th.dt-orderable-asc:hover span.dt-column-order::before,
.tt-wrap.fc table.dataTable thead th.dt-orderable-desc:hover span.dt-column-order::after{
          opacity:.85; }
/* No reserved gap for the overlay. Measured: a 26-column table pays for one on every column,
   which costs ~130px and puts the table back outside its pane -- and the pane is what the
   reader actually notices. The glyph sits in the cell padding instead. */

/* The run-by-run tables carry 25 and 36 columns. They were overflowing their pane by about
   a dozen pixels at every width, so the whole table scrolled sideways to show one more
   column of a two-character value. Trimming the horizontal cell padding recovers roughly
   4px per column -- 140px across Run Quality -- which is far more than the overflow. */
.tt-wrap.fc .tt-formfull table.dataTable > tbody > tr > td,
.tt-wrap.fc .tt-formfull table.dataTable > thead > tr > th{
          padding-left:4px !important; padding-right:4px !important; }
/* Career form: the date and the chequered flag both open that race's report, and both were
   rendering in the table's own ink -- white on dark -- so nothing said they could be pressed
   (Derek, 1 Sep). A blue, deliberately not the accent: the accent is the brand's colour and is
   used for state all over the card, whereas nothing else in these tables is blue. 7.3:1 on the
   dark ground and 6.3:1 on the light one.

   `.tt-sheet table.table a` already paints these `--fc-ink !important` and carries one class
   more, so this has to out-specify it rather than merely follow it. Note `.tt-formfull.tt-sheet`
   and not `.tt-sheet .tt-formfull`: they are the SAME element, so the descendant form matched
   nothing at all. */
:root{ --fc-linkish:#7fb3ff; }
/* First place is blue across the new design, as the classic card has always badged it
   (`position.html` uses bg-primary for a winner). It was three different things: gold on
   the card, #1e5a8a in the sheet, #5a63e0 on Your day. One ground for the badges, one ink
   for the card's own place text -- white on the ground is 4.9:1, and the ink clears AA on
   both card grounds. */
/* The tooltip's red. `--fc-val-r` measures 3.95:1 on the dark popover ground -- under AA for
   text this size -- so the tooltip lightens it to 5.1:1. Light is unchanged at 5.7:1. */
:root{ --fc-tip-r:#ff8078; }
:root:not([data-fc-theme="dark"]){ --fc-tip-r:#d10011; }
:root{ --fc-first-bg:#5a63e0; --fc-first-ink:#7fb3ff; }
:root:not([data-fc-theme="dark"]){ --fc-first-ink:#1857b8; }
:root:not([data-fc-theme="dark"]){ --fc-linkish:#1857b8; }
.tt-wrap.fc .tt-formfull.tt-sheet table.table a,
.tt-wrap.fc .tt-formfull.tt-sheet table.table .btn-link,
.tt-wrap.fc .tt-formfull.tt-sheet table.table a .fa-flag-checkered,
.tt-wrap.fc .tt-formfull.tt-sheet table.dataTable a,
.tt-wrap.fc .tt-formfull.tt-sheet table.dataTable .btn-link{ color:var(--fc-linkish) !important; }
.tt-wrap.fc .tt-formfull.tt-sheet table a:hover,
.tt-wrap.fc .tt-formfull.tt-sheet table a:focus-visible{ text-decoration:underline; }

/* The date is the widest thing in the first column and it never wraps. */
.tt-wrap.fc .tt-formfull table[id^="formmenu"] tbody td:first-child,
.tt-wrap.fc .tt-formfull table[id^="formplusmenu"] tbody td:first-child{ white-space:nowrap; }

/* The tables sit in a Bootstrap `.card.p-1`, whose padding and border make its content box
   12px wider than the pane it sits in -- so both tables overflowed by exactly 12px whatever
   their column count, and the page scrolled sideways to show nothing. Keep the overflow
   inside the card, which is this project's rule for wide content anyway. */
.tt-wrap.fc .tt-formfull .card{ max-width:100%; overflow-x:auto; }
.tt-wrap.fc .tt-formfull .tab-content{ max-width:100%; }

/* Three elements were taking their colour from the classic stylesheet rather than the
   tokens their own rules name: `.tt-why-h` is declared unscoped, so a Hyper heading rule
   outranks it, and the two links lose to Bootstrap's `a` colour. All three then render a
   light-on-dark colour on the LIGHT theme -- 1.09:1, 1.56:1 and 1.62:1. Scoped and raised.
   Invisible to the audit until --expand learned to open the panels they sit in. */
.tt-wrap.fc .tt-why-h,
.tt-wrap.fc .tt-panel-h{ color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-classic{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc a.tt-notice-cta{ color:var(--fc-ink) !important; }
.tt-wrap.fc a.tt-notice-cta.is-go{ color:var(--fc-accent-ink) !important; }

/* The reused board's own markup carries light-on-dark colours (a Hyper card written for the
   dark shell), so on the light theme its headings and the non-runner list read at 1.02:1.
   Scoped to .tt-board, so the classic page keeps what it has. */
.tt-wrap.fc .tt-board :is(h1, h2, h3, h4, h5, .header-title){ color:var(--fc-ink); }
/* Not inside a button: the race-time buttons are colour-coded by race class and carry their
   own badges, and repainting them with the sheet ink threw that coding away. */
.tt-wrap.fc .tt-board .tab-content :is(div, span, p, strong, b):not(.btn):not(.btn *):not(.badge):not(.badge *){
          color:var(--fc-ink); }
.tt-wrap.fc .tt-board .tab-content a:not(:has(.btn)):not(.btn){ color:var(--fc-ink); }
/* NOT restyled: the going and TV strip is white on a dark green panel of its own, which
   reads fine. The audit scores it 2.44:1 because its ground-walk composites past that panel
   to the light page behind it. Left alone deliberately -- three attempts to "fix" it only
   added CSS that changed nothing. Worth confirming by eye before anyone tries again. */

/* The navbar is rendered outside .tt-wrap, so it is scoped by the body CONTAINING the turtle
   shell rather than by an ancestor -- and on :has() rather than the data-fc-theme attribute,
   which only exists once the theme script has run.

   Hyper marks the current page with its own dark grey, which does not follow the theme: on
   the light theme that is the sheet's dark ink on a dark grey block, 1.74:1. The current
   page should be marked in the accent, like everything else that means "this one". */
body:has(.tt-wrap.fc) .dropdown-item.active,
body:has(.tt-wrap.fc) .dropdown-item:active,
body:has(.tt-wrap.fc) .nav-link.active{
          background-color:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }

/* Instant tooltips.

   A native `title` waits about a second before the browser shows it, which on a small marker
   like the headgear code reads as the page being slow. A Bootstrap tooltip is instant but
   costs an instance and a Popper layout per element, and the card carries hundreds.

   `data-tt-tip` is CSS only: no JS, no instance, nothing to initialise, and it appears on
   hover and on keyboard focus. Use it for short fixed labels; anything that needs HTML, a
   fetch or a click stays a popover. */
.tt-wrap.fc [data-tt-tip]{ position:relative; }
.tt-wrap.fc [data-tt-tip]::after{
          content:attr(data-tt-tip); position:absolute; left:50%; bottom:calc(100% + 6px);
          transform:translateX(-50%); z-index:60; pointer-events:none;
          opacity:0; visibility:hidden; transition:opacity .08s linear;
          background:var(--fc-pop-bg); color:var(--fc-ink); border:1px solid var(--fc-line);
          border-radius:6px; padding:4px 8px;
          /* Was `nowrap`, which is right for "Vibes" and absurd for the 130-character
             explanations the card also carries -- a single line wider than the screen. Sized
             to the content up to a readable measure, then wrapped. */
          white-space:normal; width:max-content; max-width:min(260px, 70vw); text-align:center;
          font-size:max(11px, calc(12px * var(--fc-scale))); font-weight:500; line-height:1.35;
          box-shadow:0 4px 14px rgba(0,0,0,.28); }

@media (prefers-reduced-motion:reduce){
  .tt-wrap.fc [data-tt-tip]::after{ transition:none; }
}
/* The cloth sits in the row's top-left corner, which is exactly where the tip ribbon is
   absolutely positioned. A tooltip opening upward from the draw lands on the ribbon and the
   two read as one jumbled box (profiler, 1 Sep). It opens downward instead -- the same flip
   the view bar uses, for the same reason: there is something in the way above it. */
/* Downward, and anchored to the LEFT edge rather than centred on it. The cloth is the first
   thing in the row, so a tooltip centred on an 18px badge hangs half its width off the page --
   and it got wider the moment it carried the draw's record (Kenny, 1 Sep). */
.tt-wrap.fc .tt-cloth [data-tt-tip]::after{ bottom:auto; top:calc(100% + 6px);
          left:0; transform:none; text-align:left; }

/* And the record inside it takes its own band. `--fc-val-*` rather than `--fc-good/fair/poor`
   because these are the values tuned for the popover ground -- the horseshoe inks fail AA on
   it, which is why the two families exist. */
.tt-wrap.fc .tt-draw.is-g[data-tt-tip]::after{ color:var(--fc-val-g); }
.tt-wrap.fc .tt-draw.is-a[data-tt-tip]::after{ color:var(--fc-val-a); }
.tt-wrap.fc .tt-draw.is-r[data-tt-tip]::after{ color:var(--fc-tip-r); }

/* The view bar is the first thing on the page, so a tooltip above it is drawn off the top of
   the screen -- measured at -24px. Anything pinned to the top edge shows its tooltip below. */
.tt-wrap.fc .tt-viewbar [data-tt-tip]::after{ bottom:auto; top:calc(100% + 6px); }

/* The row's actions as a small grid rather than two buttons and a "..." menu. Every one of
   these is one tap on the classic card, and the ellipsis said nothing about what it hid. */
.tt-wrap.fc .tt-actcell{ display:grid; grid-template-columns:repeat(3, 1fr); gap:2px 4px;
          justify-items:center; align-items:center; }
.tt-wrap.fc .tt-actcell .tt-more{ grid-column:1 / -1; margin-top:2px; }
.tt-wrap.fc .tt-actcell .tt-actrow{ display:inline-flex; align-items:center;
          justify-content:center; min-width:24px; min-height:24px; }
@media (max-width:1100px){
  /* Stacked layouts give the cell its width back, so the actions can sit in one line. */
  .tt-wrap.fc .tt-actcell{ grid-template-columns:repeat(6, auto); justify-content:flex-start; }
  .tt-wrap.fc .tt-actcell .tt-more{ grid-column:auto; margin-top:0; }
}

/* The trainer and jockey names are buttons now, and must not look like a form control. */
.tt-wrap.fc .tt-connname{ border:0; background:none; padding:0; font:inherit; color:inherit;
          cursor:pointer; text-align:left; text-decoration:underline;
          text-underline-offset:2px; text-decoration-color:var(--fc-line); }
.tt-wrap.fc .tt-connname:hover{ text-decoration-color:var(--fc-ink-2); color:var(--fc-ink); }

/* The race-level readings above the trends table. */
.tt-wrap.fc .tt-trendhead{ margin:0 0 10px; padding-bottom:10px;
          border-bottom:1px solid var(--fc-hair); }

/* Reused classic markup inside a turtle sheet.

   These pages keep their Bootstrap markup by design, and a lot of it carries colours written
   for the dark classic shell -- white headings, white figures. On the light theme those land
   on a pale sheet at about 1:1. Headings and plain text take the sheet's ink; anything that
   paints its OWN ground keeps its colour, which is why buttons, badges and alerts are
   excluded rather than swept up. */
.tt-wrap.fc .tt-sheet :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6,
                          .card-title, .header-title, .text-center, .text-muted)
      :not(.btn):not(.badge):not(.alert){ color:inherit; }
.tt-wrap.fc .tt-sheet > :is(h1, h2, h3, h4, h5, h6),
.tt-wrap.fc .tt-sheet :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6,
                          .card-title, .header-title):not(.home-cta-gradient *):not(.hero-section *){
          color:var(--fc-ink); }
/* `.text-white` is markup written for the dark classic shell: it means "the thing behind
   this is dark". Inside a light sheet most of those things are no longer dark, so the ink is
   repainted -- except where the thing still paints a dark ground of its own.

   Those exceptions are a rule of their OWN below, not more `:not()`s. Every `:not(.x)` costs
   a class and this chain had reached (0,11,4), so nothing could override it and each new dark
   ground had to be added here, one report at a time: the homepage CTA, the hero, a card
   header, and then the landing pages' step markers -- near-black numerals on green circles at
   2.44:1. `:where()` costs no specificity, so this is a default anything can beat. */
.tt-wrap.fc .tt-sheet .text-white:not(:where(.btn, .badge)){ color:var(--fc-ink) !important; }

/* A ground that stays dark keeps its white ink: the ground and the ink on it decided in one
   place, so adding a ground is one edit rather than two.

   `.bg-warning` is deliberately absent -- Bootstrap's yellow is a LIGHT ground, so white on it
   fails and the dark ink above is the right answer. `.alert` is excluded because this sheet
   repaints every alert's ground to `--fc-inset`, which follows the theme: white ink there
   would be white on a pale panel. */
.tt-wrap.fc .tt-sheet :is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-info,
                          .bg-dark, .card-header):not(.alert).text-white,
.tt-wrap.fc .tt-sheet :is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-info,
                          .bg-dark, .card-header):not(.alert) .text-white{ color:#ffffff !important; }
/* Headings on those same grounds. The heading rule above repaints h1-h6 and `.card-title` to
   the sheet ink wherever they appear, which on a ground that stays dark is the same defect a
   line up: the summary panel's "1:25 GOODWOOD" was near-black on green at 2.44:1 -- read as
   "green on black" (Kenny, 30 Aug 2026). Third family after links and `.text-white`, and the
   last of the three that had its own idea about ink. */
.tt-wrap.fc .tt-sheet :is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-info,
                          .bg-dark, .card-header):not(.alert)
      :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, .card-title, .header-title){
          color:#ffffff !important; }

/* A Bootstrap card-header inside a sheet paints its own ground from the classic palette. */
.tt-wrap.fc .tt-sheet .card-header{ background:var(--fc-thead); color:#ffffff; }
.tt-wrap.fc .tt-sheet .card-header :is(h1,h2,h3,h4,h5,h6,.card-title){ color:#ffffff; }

/* Bootstrap's indigo `.display-*` figures land on the turtle sheet's own dark ground at
   about 2:1. The accent is what this theme uses for a number worth looking at. */
.tt-wrap.fc .tt-sheet :is(.display-1, .display-2, .display-3,
                          .display-4, .display-5, .display-6){ color:var(--fc-accent); }

/* The homepage's marketing sections, in the theme's own colours.

   They ship with a blue gradient (#1e3a5f -> #2563eb -> #6366f1) and indigo step circles
   from the classic design, which is the clash: a blue hero above a green card. Given a
   turtle ground, their white text is correct again and nothing needs repainting. */
.tt-wrap.fc .home-cta-gradient{
          background:linear-gradient(135deg, var(--fc-thead) 0%, #1c6b33 55%,
                                     color-mix(in srgb, var(--fc-accent) 55%, #0e3b21) 100%); }
/* !important because a section that paints its OWN dark ground owns the text on it, and the
   generic sheet rules are more specific than any sane exception selector -- `:not(.x *)`
   carries the specificity of `.x *`, so excluding a section makes the generic rule WIN. */
.tt-wrap.fc .home-cta-gradient :is(h1,h2,h3,h4,h5,h6,p,.lead,.text-white){ color:#ffffff !important; }
.tt-wrap.fc .home-cta-gradient .text-white-50{ color:rgba(255,255,255,.82) !important; }
/* The hero's ::after gradient is positioned `top:-400px` -- decoration ABOVE the section,
   not its background. The hero itself sits on the page's own light ground, so its text takes
   the sheet's INK. Painting it white, as the CTA needs, put "Study Horse Racing Form" white
   on white and is exactly the invisible text Kenny reported. */
.tt-wrap.fc .hero-section::after{
          background-image:linear-gradient(to bottom, var(--fc-thead), #1c6b33) !important; }
.tt-wrap.fc .hero-section :is(h1,h2,h3,h4,.display-4,.display-6,.lead,.text-white){
          color:var(--fc-ink) !important; }
.tt-wrap.fc .hero-section :is(.text-white-50,.text-muted){ color:var(--fc-ink-2) !important; }
/* The step circles and card accents, off the classic indigo/amber palette. */
.tt-wrap.fc .home-step-circle.step-1{ background:var(--fc-thead); }
.tt-wrap.fc .home-step-circle.step-2{ background:#1c6b33; }
.tt-wrap.fc .home-step-circle.step-3{ background:color-mix(in srgb, var(--fc-accent) 70%, #0e3b21); }
.tt-wrap.fc .home-learn-card.accent-blue{ border-top-color:var(--fc-thead); }
.tt-wrap.fc .home-learn-card.accent-green{ border-top-color:#1c6b33; }
.tt-wrap.fc .home-learn-card.accent-orange{ border-top-color:var(--fc-accent); }

/* Bootstrap's `.bg-primary` is Hyper's indigo (#727cf5) -- an indigo band across the top of a
   green sheet, which is the clash in Summary Statistics and anywhere else a reused fragment
   uses it. It takes the theme's table-head green, and its badges follow. */
.tt-wrap.fc .tt-sheet .bg-primary{ background-color:var(--fc-thead) !important; color:#ffffff; }
.tt-wrap.fc .tt-sheet .bg-primary :is(h1,h2,h3,h4,h5,h6,span,div,p){ color:#ffffff; }
.tt-wrap.fc .tt-sheet .bg-primary .badge{ background-color:rgba(255,255,255,.16) !important;
          color:#ffffff !important; border:1px solid rgba(255,255,255,.28); }

/* The notebook is the one row action whose icon says least -- an address book means nothing
   until you have been told. It carries its word; the label follows the tag's own icon state
   the way the heart and bin labels do. */
.tt-wrap.fc .tt-actcell .tt-a-note{ flex-direction:column; gap:0; }
.tt-wrap.fc .tt-actcell .tt-a-note .tt-actlbl{
          font-size:max(9px, calc(9.5px * var(--fc-scale))); line-height:1.1;
          color:var(--fc-ink-3); }
.tt-wrap.fc .tt-a-note:has(.fas.fa-address-book) .tt-off,
.tt-wrap.fc .tt-a-note:has(.far.fa-address-book) .tt-on{ display:none; }

/* Run Quality carries 36 columns and Lifetime Runs 25, and they overflowed their pane at
   every width. The two widest are the jockey and trainer names, which do not wrap -- they
   take 230px between them for text that reads perfectly well on two lines. Wrapping those
   and tightening the type is what makes the table fit; the alternative, truncating names,
   is not something this project does. */
.tt-wrap.fc .tt-formfull table.dataTable{
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-formfull table.dataTable > tbody > tr > td{ white-space:normal; }
.tt-wrap.fc .tt-formfull table.dataTable > thead > tr > th{ white-space:normal;
          vertical-align:bottom; }
/* The date stays on one line -- it is the column the reader scans down. */
.tt-wrap.fc .tt-formfull table.dataTable > tbody > tr > td:first-child{ white-space:nowrap; }

/* The last 6px. The tables sit in a Bootstrap `.card.p-1` whose 6px of horizontal padding is
   the whole of the remaining overflow -- the table is 1370 in a 1358 pane, and the card
   scrolls by exactly 6. Dropping the padding for these two tables reclaims 12 and the card
   stops scrolling. The border stays; only the inside gutter goes. */
.tt-wrap.fc .tt-formfull .card{ padding-left:0 !important; padding-right:0 !important; }

/* ---- Bootstrap ground classes inside the turtle shell -------------------------------------
   `bg-white`, `bg-light` and `bg-light-lighten` are written for a white page. On a themed
   ground they paint a slab of the wrong colour and everything on them keeps the ink chosen
   for white -- on the home page that measured 1.04:1, which is text nobody can read. The
   .tt-sheet rules above are more specific and still win where they apply. */
.tt-wrap.fc .bg-white,
.tt-wrap.fc .bg-light,
.tt-wrap.fc .bg-light-lighten{ background:var(--fc-surface) !important; color:var(--fc-ink); }
.tt-wrap.fc h1, .tt-wrap.fc h2, .tt-wrap.fc h3,
.tt-wrap.fc h4, .tt-wrap.fc h5, .tt-wrap.fc h6{ color:var(--fc-ink); }
.tt-wrap.fc .text-muted{ color:var(--fc-ink-2) !important; }

/* The home page's four headline figures carry inline hex chosen against white -- indigo, sky,
   emerald and amber, which read at 1.9:1 and 2.5:1 on this ground. Inline styles need the
   override to be !important. */
.tt-wrap.fc .bt-statband .display-6{ color:var(--fc-accent) !important; }
.tt-wrap.fc .bt-other-access .btn i,
.tt-wrap.fc .bt-statband i{ color:var(--fc-accent) !important; }

/* betturtle-base paints this section with a gradient and switches it on
   html[data-bs-theme="dark"]. The turtle theme switches on data-fc-theme, so the LIGHT
   gradient stayed under turtle's light ink in dark mode -- 1.04:1. A flat token instead: a
   gradient ground also defeats a contrast audit, which samples one colour. */
.tt-wrap.fc .bt-other-access{ background:var(--fc-band-bg) !important; }
.tt-wrap.fc .bt-other-access h3{ color:var(--fc-ink) !important; }
.tt-wrap.fc .bt-other-access p,
.tt-wrap.fc .bt-other-access .text-muted{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .bt-other-access .btn-outline-primary{ color:var(--fc-ink) !important;
          border-color:var(--fc-line) !important; background:var(--fc-surface) !important; }
.tt-wrap.fc .bt-other-access .btn-outline-primary:hover{ border-color:var(--fc-accent) !important;
          color:var(--fc-accent) !important; }

/* A secondary figure inside a table cell is still a figure. --fc-ink-2 is a comment colour
   and reads at 2.48:1 at 12px in the systems table. */
.tt-wrap.fc small.text-muted{ color:var(--fc-ink) !important; }
/* Except in a table head, which is a dark green ground with its own ink. A comment grey there
   reads at 2.48:1. */
.tt-wrap.fc thead .text-muted,
.tt-wrap.fc thead small.text-muted{ color:var(--fc-on-thead, #fff) !important; }

/* DataTables wraps the heading in span.dt-column-title, which outranks the generic muted rule. */
.tt-wrap.fc table.dataTable thead th span.dt-column-title small.text-muted,
.tt-wrap.fc table.dataTable thead th span.dt-column-title .text-muted{
          color:var(--fc-on-thead, #ffffff) !important; }

/* The race-analysis chip carries the pace line as a subtitle. It is a sentence, and on a race
   with a lot to say it pushed the bar wide; one line, clipped. */
.tt-wrap.fc .tt-brief-chip em{ display:inline-block; max-width:34ch; overflow:hidden;
          text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom; }
/* Which six runs the three rating lines are. */
.tt-wrap.fc .tt-sixnote{ margin:0 0 6px; color:var(--fc-ink-2);
          font-size:max(11px, calc(11.5px * var(--fc-scale))); }

/* The race-level figures under the analysis: betting rating, previous runnings, favourite
   strike rate and the winners' rating range. */
.tt-wrap.fc .tt-racefacts{ list-style:none; margin:10px 0 0; padding:0; display:flex;
          flex-wrap:wrap; gap:6px 18px; }
.tt-wrap.fc .tt-racefacts li{ display:flex; align-items:baseline; gap:6px; }
.tt-wrap.fc .tt-racefacts span{ color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-racefacts b{ color:var(--fc-ink); font-weight:600;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-racefacts b i{ margin-right:4px; }

/* The 14-day record opens the form line, so it has to look pressable. */
.tt-wrap.fc .tt-d14{ cursor:pointer; text-decoration:none;
          border-bottom:1px dotted currentColor; }

/* Run Quality carries the most columns of any table on the card and is the one that has to
   fit. The tighter cell padding is scoped to it alone -- Lifetime Runs keeps the density it
   has always had. */
.tt-wrap.fc .tt-formfull table.formpluslist > tbody > tr > td,
.tt-wrap.fc .tt-formfull table.formpluslist > thead > tr > th{
          padding-left:3px !important; padding-right:3px !important; }

/* ---- Meeting strip: race times carrying their standing ------------------------------------
   The classic time button colours on drtitleclass and badges the betting rating; the turtle
   pill carried neither, so every race looked alike and a finished one looked live. */
.tt-wrap.fc .tt-nav-next{ display:flex; flex-wrap:wrap; align-items:center; gap:6px;
          margin:6px 0; }
.tt-wrap.fc .tt-nav-next > span{ color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
/* Off next carries the time, the course and the marks, so it needs room the meeting strip's
   pills do not: the time and its icons on one line, the course underneath. Without the width
   the icons pushed the course out and the pill read as a bare time. */
.tt-wrap.fc .tt-nav-next .tt-time-pill{ display:inline-flex; flex-wrap:wrap;
          align-items:baseline; justify-content:center; gap:0 4px;
          min-width:6.6rem; line-height:1.2; padding:4px 9px; text-align:center; }
/* currentColor, not --fc-ink-2: the pill has its own ground, and the comment ink read at
   1.34:1 on it in dark. The course name is the smaller half of the pill, not a lesser one. */
.tt-wrap.fc .tt-pill-course{ flex:0 0 100%; font-style:normal; color:currentColor;
          opacity:.9; font-weight:600;
          font-size:max(10px, calc(10.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-time-pill i{ margin-left:5px; font-size:.85em; }
.tt-wrap.fc .tt-time-pill.is-done{ opacity:.45; }
/* The six bands the classic time button colours on, and the key names: GRP 1, GRP 2, GRP 3,
   LST, HCP, OTHER. Every one carries white ink and was measured against it — 5.67:1 at the
   weakest (GRP 3) — because a coloured pill is the only thing distinguishing a Group race
   from a seller at a glance, and it has to survive both themes. */
/* The six bands from the key: GRP 1, GRP 2, GRP 3, LST, HCP, OTHER.
   COLOUR SAYS ONE THING — which band the race is in — and the ink is decided by the band it
   sits on, not by what the icon means: five dark bands carry white, OTHER is white and carries
   black. Four icon colours that changed with the pill underneath them were the inconsistency,
   not the bands.

   Each band is the LIGHTEST version of its hue that still holds white text, so the hue stays
   recognisable: 4.91:1 at the weakest (GRP 2). */
.tt-wrap.fc .tt-time-pill.tt-tier-g1{ --tt-ink:#fff; --tt-band:#544AC0; background:#544AC0; border-color:#4F46B8; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-g2{ --tt-ink:#fff; --tt-band:#966800; background:#966800; border-color:#8A5500; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-g3{ --tt-ink:#fff; --tt-band:#24768F; background:#24768F; border-color:#1F6F8B; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-lst{ --tt-ink:#fff; --tt-band:#B41C40; background:#B41C40; border-color:#A81238; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-hcp{ --tt-ink:#fff; --tt-band:#1A7A4F; background:#1A7A4F; border-color:#166542; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-oth{ --tt-ink:#10261a; --tt-band:#c3ccd2; background:#ffffff; border-color:#c3ccd2; color:#10261a !important; }
/* The same six in both themes: a band carries its own ground, so a race's standing does not
   change colour with the theme. */

/* Mono-tone: every glyph takes the ink of the band it is on. `i` alone missed them — the
   classic markup is <span class="fa …"> — which is why seven inks survived the first attempt. */
.tt-wrap.fc .tt-time-pill i[class],
.tt-wrap.fc .tt-time-pill span[class],
.tt-wrap.fc .tt-time-pill .tt-pill-rate,
.tt-wrap.fc .tt-time-pill .tt-pill-marks i{ color:inherit !important; }

/* The race being read is marked by an OUTLINE, not by repainting it: the older is-now rule
   forced the accent ink, which landed light-on-light over a band colour at 2.05:1. The band
   keeps its own ground and ink; the outline says "you are here". */
.tt-wrap.fc .tt-time-pill.is-now{ outline:2px solid var(--fc-accent); outline-offset:1px; }
/* The rating keeps its colour -- shape alone is harder to tell apart at this size -- but
   Bootstrap's text-success is a green thumb on a green band. These are the same three
   meanings in inks measured against every band: 3.47:1 at the worst (poor on GRP 3), and the
   dark set for the light OTHER band. !important because the utilities carry it. */
/* The customer's own marks take the band's ink: they are one meaning each, told apart by
   glyph, and a fourth colour scale on a 20px pill would be noise. */
.tt-wrap.fc .tt-time-pill .tt-pill-marks i{ color:inherit !important; }
/* "You have been here", counted. One dot instead of four glyphs: which of shortlist, notes,
   comments or systems you used is not the question while scanning a day's racing. */
/* Outlined, not filled: the ring and the numeral both take the band's ink, which is the one
   ink already measured against that ground -- a filled dot would need the numeral in the
   band's own colour and six more rules to say so. */
.tt-wrap.fc .tt-pill-mine{ display:inline-flex; align-items:center; justify-content:center;
          min-width:16px; height:16px; margin-left:5px; padding:0 3px; border-radius:999px;
          border:1px solid currentColor; color:inherit;
          font-size:max(9px, calc(10px * var(--fc-scale))); font-weight:700; line-height:1; }

/* The key. Named because six colours nobody can look up are decoration. */
.tt-wrap.fc .tt-rf-group .tt-timekey{ margin-top:6px; flex-wrap:wrap; }
.tt-wrap.fc .tt-timekey{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px;
          margin:8px 0 2px; }
.tt-wrap.fc .tt-timekey b{ color:var(--fc-ink-2); font-weight:600;
          font-size:max(10px, calc(11px * var(--fc-scale))); }
.tt-wrap.fc .tt-timekey span{ padding:1px 10px; border-radius:999px; color:#fff;
          font-size:max(10px, calc(10.5px * var(--fc-scale))); font-weight:700; }
/* The key shows the bands as the times show them. */
.tt-wrap.fc .tt-timekey span{ color:#fff !important; }
.tt-wrap.fc .tt-timekey .k-g1{ background:#544AC0; }
.tt-wrap.fc .tt-timekey .k-g2{ background:#966800; }
.tt-wrap.fc .tt-timekey .k-g3{ background:#24768F; }
.tt-wrap.fc .tt-timekey .k-lst{ background:#B41C40; }
.tt-wrap.fc .tt-timekey .k-hcp{ background:#1A7A4F; }
.tt-wrap.fc .tt-timekey .k-oth{ background:#ffffff; color:#10261a !important;
          border:1px solid #c3ccd2; }
.tt-wrap.fc .tt-timekey em{ font-style:normal; color:var(--fc-ink-2); display:inline-flex;
          align-items:center; gap:4px; font-size:max(10px, calc(11px * var(--fc-scale))); }
/* The key shows the glyphs in the inks the pill uses, on a swatch of a band, so it describes
   what is actually on screen. */
.tt-wrap.fc .tt-timekey em i{ color:var(--fc-ink-2) !important; }

/* A block, not the flex row an earlier rule made it: as a flex container the <details>
   laid its summary and the meetings out as siblings in a row, which is why the label sat at
   the vertical middle of the list.
   And the collapse is stated rather than inherited: every child here sets its own display
   (the meeting rows are flex, the colour key is flex), and a child with an author display
   escapes the UA's hiding — so "Other meetings (6)" was showing all six meetings while
   closed, and the colour key with them. */
.tt-wrap.fc .tt-nav-other{ display:block; margin-top:6px; }
.tt-wrap.fc .tt-nav-other:not([open]) > *:not(summary){ display:none !important; }
.tt-wrap.fc .tt-nav-other > summary{ cursor:pointer; color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); padding:4px 0; }
.tt-wrap.fc .tt-nav-meet{ display:flex; flex-wrap:wrap; align-items:center; gap:5px;
          padding:4px 0; border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-nav-meetname{ min-width:9rem; color:var(--fc-ink);
          font-size:max(11px, calc(12px * var(--fc-scale))); font-weight:600; }

/* Previous winners of the named race. A dense record, so it scrolls inside its own box
   rather than widening the panel. */
.tt-wrap.fc .tt-rp-winners{ overflow-x:auto; margin:6px 0 10px; }
.tt-wrap.fc .tt-rp-wintable{ width:100%; border-collapse:collapse;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-rp-wintable th{ text-align:left; padding:4px 8px 4px 0; white-space:nowrap;
          color:var(--fc-ink-2); font-weight:600; border-bottom:1px solid var(--fc-line); }
.tt-wrap.fc .tt-rp-wintable td{ padding:4px 8px 4px 0; white-space:nowrap;
          color:var(--fc-ink); border-bottom:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-rp-wintable tbody tr:last-child td{ border-bottom:0; }
.tt-wrap.fc .tt-rp-wintable a{ color:var(--fc-accent); }

/* ---- Blog ---------------------------------------------------------------------------------
   The blog's own stylesheet is written for a white page: headings, tag pills, the category
   badge and the sidebar carry inks chosen against it, which read at 1.0:1 inside the turtle
   shell. Scoped through body.bt-blog so it reaches the sidebar as well as the article -- the
   sheet wrapper covers only the entry itself -- and so the classic blog is untouched. */
body.bt-blog .tt-wrap.fc :is(h1, h2, h3, h4, h5, h6){ color:var(--fc-ink) !important; }
body.bt-blog .tt-wrap.fc :is(p, li, dd, dt, blockquote, td, th, figcaption, div.small,
          span:not([class])){ color:var(--fc-ink); }
body.bt-blog .tt-wrap.fc :is(.text-muted, small, .bt-author-desc, .reading-time,
          .endless_separator, .breadcrumb-item, .breadcrumb-item a, .bt-related-meta,
          .bt-related-meta span){
          color:var(--fc-ink-2) !important; }
body.bt-blog .tt-wrap.fc a:not(.btn):not(.blog-cat-badge):not(.blog-tag-pill){
          color:var(--fc-accent) !important; }
body.bt-blog .tt-wrap.fc .bt-author-name{ color:var(--fc-ink) !important; }
/* The category badge carries a per-category Bootstrap ground (cyan for Learn, and so on)
   under whichever ink wins -- accent green on cyan measured 3.01:1. One treatment for both
   the link and the plain-span form: the accent on the sheet's own surface, which is the pair
   the palette is built around. The attribute selector is there for the specificity. */
body.bt-blog .tt-wrap.fc a[class*="blog-cat-"],
body.bt-blog .tt-wrap.fc span[class*="blog-cat-"]{
          background:var(--fc-surface) !important; color:var(--fc-accent) !important;
          border:1px solid var(--fc-line) !important; }
/* The category badge and tag pill are NOT restyled: the blog gives each category its own
   coloured ground with white text, and overriding the ground put white on white. Their own
   colours read on either theme because the badge carries its own ground. */
body.bt-blog .tt-wrap.fc :is(.card, .bt-author, .entry-card, aside, .sidebar){
          background:var(--fc-inset) !important; border-color:var(--fc-line) !important; }
body.bt-blog .tt-wrap.fc :is(code, pre){ background:var(--fc-well) !important;
          color:var(--fc-ink) !important; }
body.bt-blog .tt-wrap.fc hr{ border-color:var(--fc-line); }

/* The KEY column carries up to three performance icons. They were wrapping to a second line,
   which took every row from 48px to 69px and made the two run tables a third taller than the
   data needs. KEY is the second column in both templates. */
.tt-wrap.fc .tt-formfull table.formlist > tbody > tr > td:nth-child(2),
.tt-wrap.fc .tt-formfull table.formpluslist > tbody > tr > td:nth-child(2){
          white-space:nowrap !important; }
.tt-wrap.fc .tt-formfull table.formlist > tbody > tr > td:nth-child(2) > *,
.tt-wrap.fc .tt-formfull table.formpluslist > tbody > tr > td:nth-child(2) > *{
          display:inline-block; }

/* ---- Popover CONTENT ----------------------------------------------------------------------
   The race-date and chequered-flag popovers fetch their body from the report and form-summary
   APIs, and that fragment is plain Bootstrap: bg-primary section headers, bg-info / bg-success
   badges, bg-white panels, text-dark. The shell is themed by `tt-pop`, so the frame was right
   and everything inside it was still the classic card -- which is what "using the classic
   styling" looked like.

   Scoped to `.tt-pop`, added only when the turtle shell is present, so the classic popovers
   are untouched. */
.tt-pop .popover-body :is(.bg-primary, .bg-secondary, .bg-dark){
          background:var(--fc-thead) !important; color:var(--fc-on-thead, #ffffff) !important; }
/* No descendant ink rule here: a .bg-white panel nested inside the band would inherit the
   band's white and land at 1.12:1. Colour inherits from the band on its own, and the light
   grounds below re-assert their own ink. */
.tt-pop .popover-body :is(.bg-white, .bg-light, .bg-body, .bg-body-tertiary),
.tt-pop .popover-body :is(.bg-primary, .bg-secondary, .bg-dark) :is(.bg-white, .bg-light){
          background:var(--fc-inset) !important; color:var(--fc-ink) !important; }
.tt-pop .popover-body :is(.text-dark, .text-body, .fw-bold){ color:var(--fc-ink) !important; }
/* The runner the popover was opened FROM. `report.html` marks its name `fw-bold text-success`,
   and the rule above -- later, same specificity -- turned that into plain bold white, so the
   horse being asked about read like every other line (Kenny, 2 Sep). The name takes the value
   green again and the whole line takes a tint and a rule down its edge, because the line is
   what a reader is scanning for, not the name on its own. */
/* The runner the popover was opened FROM. `report.html` marks its name `fw-bold text-success`,
   and the `.fw-bold` rule above -- later, same specificity -- turned that into plain bold
   white, so the horse being asked about read like every other line (Kenny, 2 Sep).

   The name takes the value green back and the LINE takes a rule down its edge. Deliberately no
   tint behind it: a translucent ground under text is something `popover_content_check` cannot
   reason about -- it reads the first non-transparent background WITHOUT compositing the alpha,
   so `rgba(28,107,51,.12)` is measured as solid dark green and every dark word on the line
   fails. The edge rule marks the line without putting anything under the text. */
.tt-pop .popover-body .fw-bold.text-success{ color:var(--fc-val-g) !important; }
.tt-pop .popover-body div:has(> .fw-bold.text-success){
          box-shadow:inset 3px 0 0 var(--fc-accent);
          border-radius:4px; padding:2px 4px 2px 8px; margin-left:-4px; }
.tt-wrap.fc .tt-tags .btn-link{ color:var(--fc-accent); }

/* Row markers: future entries, noted runner, the system-qualifier gear. */
.tt-wrap.fc .tt-mark{ display:inline-flex; align-items:center; padding:0 3px; border:0;
          background:none; color:var(--fc-ink-3); font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-mark:hover{ color:var(--fc-ink); }
.tt-wrap.fc .tt-mark.is-sys{ color:var(--fc-val-a); }
.tt-wrap.fc .tt-mark.is-intel{ color:var(--fc-accent); }

/* The ordering control, beside the toolbar buttons. */
.tt-wrap.fc .tt-orderlbl{ color:var(--fc-ink-3); font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-order{ padding:4px 8px; border-radius:4px; border:1px solid var(--fc-hair);
          background:var(--fc-inset); color:var(--fc-ink);
          font-size:calc(12px * var(--fc-scale)); }

/* Racecourse guide, opened from a chip in the race header. */
.tt-wrap.fc .tt-chip-btn{ cursor:pointer; border-style:dashed; }
.tt-wrap.fc .tt-courseinfo{ margin:8px 0 0; }
.tt-wrap.fc .tt-courseinfo[hidden]{ display:none !important; }

/* The detailed race board on today's racing. */
.tt-wrap.fc .tt-board{ margin-top:14px; }

/* Which day's cards to show. Bootstrap gives `label` its own colour, so the token has to
   be set on the element rather than inherited from the bar. */
.tt-wrap.fc .tt-datebar{ display:flex; align-items:center; flex-wrap:wrap; gap:8px;
          margin:0 0 12px; font-size:calc(13px * var(--fc-scale)); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-datebar label{ margin:0; color:var(--fc-ink-2);
          font-size:calc(13px * var(--fc-scale)); font-weight:500; }
.tt-wrap.fc .tt-datebar input[type="date"]{ padding:5px 8px; border-radius:6px;
          border:1px solid var(--fc-line-2); background:var(--fc-surface);
          color:var(--fc-ink); font:inherit; }

/* The newsletter prompt is anonymous-only and unstyled apart from Bootstrap, so it inherits
   an h5 colour chosen against white. It appears in the footer of every page, which is why it
   only surfaced on a logged-out audit. */
.tt-wrap.fc .bt-newsletter-prompt{ padding:12px; border:1px solid var(--fc-line);
          border-radius:8px; background:var(--fc-surface-2); color:var(--fc-ink-2); }
.tt-wrap.fc .bt-newsletter-prompt h5{ color:var(--fc-ink); }
.tt-wrap.fc .bt-newsletter-prompt .text-muted{ color:var(--fc-ink-3) !important; }

/* Quick Settings, opened from the toolbar. */
.tt-wrap.fc .tt-quicksettings{ margin:0 0 12px; }
.tt-wrap.fc .tt-quicksettings[hidden]{ display:none !important; }

/* DataTables sort indicators. Hyper draws these from Remix Icon, whose @import
   build_turtle_css.py strips -- so in this theme the glyphs had no font at all and every
   sortable column showed nothing. Redrawn from self-hosted Font Awesome, which keeps the
   966k saving that dropping the import bought. */
/* Scoped to the THEME, not to .tt-sheet: the Race Profile fit table sits in a .tt-panel and
   had no sort indicator at all, so a sortable column looked like a fixed one. Every
   DataTable in this theme gets the same arrows wherever it is reused. */
.tt-wrap.fc table.dataTable thead th:after,
.tt-wrap.fc table.dataTable thead td:after{
          font-family:"Font Awesome 7 Pro" !important; font-weight:900;
          content:"\f0dc"; color:var(--fc-on-thead, #ffffff); opacity:.55;
          font-size:calc(11px * var(--fc-scale)); margin-left:6px; }
.tt-wrap.fc table.dataTable thead th[aria-sort="ascending"]:after{
          content:"\f0de"; opacity:1; }
.tt-wrap.fc table.dataTable thead th[aria-sort="descending"]:after{
          content:"\f0dd"; opacity:1; }
/* Hyper hides the indicator on the un-sortable columns; keep that. */
.tt-wrap.fc table.dataTable thead th.sorting_disabled:after{ content:none; }
/* The fit table's top row is a spanning group header — nothing there sorts. */
.tt-wrap.fc table.dataTable thead tr:first-child th[colspan]:after,
.tt-wrap.fc table.dataTable thead tr:first-child th:empty:after{ content:none; }

/* ---------------------------------------------------------------------------------------
   Popovers and tooltips.

   Bootstrap renders these into <body>, outside `.tt-wrap.fc`, so they inherit none of the
   theme's tokens and fell through to the classic cascade -- and because the turtle theme
   switches on `data-fc-theme` while the classic dark rules key off `data-bs-theme`, a dark
   turtle user got a LIGHT popover over a dark card.

   These selectors are deliberately unscoped: `.tt-pop` is added by btThemePopClass() only
   when the turtle shell is present, so nothing here can reach the classic UI. The tokens are
   redeclared rather than inherited, for the same reason.

   Dark keys off `:root[data-fc-theme]` rather than a second class, because a popover in
   <body> is still a descendant of :root -- so switching theme restyles open popovers, where
   a class fixed at construction time would go stale.
   --------------------------------------------------------------------------------------- */

/* 360px was narrower than the tables these popovers carry -- the last-six run table is 543px
   and simply drew OUTSIDE the box, across the page, because `.popover-body` was
   `overflow-x:visible`. Wide enough for the content, capped to the viewport, and anything
   still wider scrolls inside its own box rather than escaping. The height cap matters as
   much: a 1089px-tall popover in a 1100px viewport has nowhere to go and Popper pins it to
   the top of the screen, far from the cell that was clicked. */
.tt-pop.popover{ background:var(--fc-pop-bg); border:1px solid var(--fc-line);
          border-radius:8px; box-shadow:0 6px 24px rgba(0,0,0,.28);
          max-width:min(980px, calc(100vw - 24px)); }
.tt-pop .popover-body{ overflow-x:auto; overflow-y:auto;
          max-height:min(78vh, 720px); overscroll-behavior:contain; }
.tt-pop .popover-header{ background:var(--fc-thead); color:#ffffff;
          border-bottom:1px solid var(--fc-line); border-radius:7px 7px 0 0;
          font-size:calc(13px * var(--fc-scale, 1.15)); font-weight:600; }
.tt-pop .popover-body{ background:var(--fc-pop-bg); color:var(--fc-ink-2);
          font-size:calc(13px * var(--fc-scale, 1.15)); }
.tt-pop .popover-body a{ color:var(--fc-accent); }
.tt-pop .popover-arrow::after{ border-top-color:var(--fc-pop-bg);
          border-bottom-color:var(--fc-pop-bg);
          border-left-color:var(--fc-pop-bg); border-right-color:var(--fc-pop-bg); }
.tt-pop .popover-arrow::before{ border-top-color:var(--fc-line);
          border-bottom-color:var(--fc-line);
          border-left-color:var(--fc-line); border-right-color:var(--fc-line); }

/* Content inside a popover is the classic fragments' markup, so it needs the same
   remapping the .tt-sheet pages get. */
.tt-pop .popover-body table{ color:var(--fc-ink-2); }
.tt-pop .popover-body thead th{ background:var(--fc-thead) !important; color:#ffffff !important; }
/* ...and the icons in it. They keep the key's colours rather than going white, on a pale chip
   of their own -- a true red cannot reach even the 3:1 non-text floor on the light green head
   (the best is 2.35) and lightening it far enough turns it pink. On its own ground each glyph
   carries the SAME hex as the legend under the table, so the head and the key match exactly. */
.tt-pop .popover-body thead th i,
.tt-pop .popover-body thead th span[class*="fa-"],
.tt-wrap.fc .tt-sheet table > thead i,
.tt-wrap.fc .tt-sheet table > thead span[class*="fa-"],
.tt-wrap.fc .tt-sheet .card-header i,
.tt-wrap.fc .tt-sheet .card-header span[class*="fa-"]{
          background:#ffffff; border-radius:50%; padding:3px;
          width:1.55em; height:1.55em; line-height:1em;
          display:inline-flex; align-items:center; justify-content:center;
          color:var(--fc-perf-good) !important; }
/* Star good, thumb-up moderate, thumb-down poor -- yellow, green, red. The chip is white, so
   the green is measured against white (5.88:1), not against the head it sits in. */
.tt-pop .popover-body thead th :is(i,span)[class*="fa-thumbs-up"],
.tt-wrap.fc .tt-sheet table > thead :is(i,span)[class*="fa-thumbs-up"],
.tt-wrap.fc .tt-sheet .card-header :is(i,span)[class*="fa-thumbs-up"]{
          color:var(--fc-perf-mid) !important; }
.tt-pop .popover-body thead th :is(i,span)[class*="fa-thumbs-down"],
.tt-wrap.fc .tt-sheet table > thead :is(i,span)[class*="fa-thumbs-down"],
.tt-wrap.fc .tt-sheet .card-header :is(i,span)[class*="fa-thumbs-down"]{
          color:var(--fc-perf-poor) !important; }

/* The key under the table, so it says the same thing. Both thumbs carry the theme's own
   value inks wherever they appear in the turtle wrap -- the pair the Icon Help panel uses.
   Turtle only -- the classic markup is untouched. */
.tt-wrap.fc .tt-sheet .fa-star.text-warning,
.tt-pop .popover-body .fa-star.text-warning{ color:var(--fc-star) !important;
          text-shadow:var(--fc-star-edge); }
.tt-wrap.fc .fa-thumbs-up.text-success,
.tt-pop .popover-body .fa-thumbs-up.text-success{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .fa-thumbs-down.text-danger,
.tt-pop .popover-body .fa-thumbs-down.text-danger{ color:var(--fc-val-r) !important; }
.tt-pop .popover-body .table-striped > tbody > tr:nth-of-type(odd) > *{
          box-shadow:none !important; background:var(--fc-zebra) !important; color:var(--fc-ink-2); }
.tt-pop .popover-body .text-success{ color:var(--fc-val-g) !important; }
.tt-pop .popover-body .text-warning{ color:var(--fc-val-a) !important; }
.tt-pop .popover-body .text-danger{ color:var(--fc-val-r) !important; }
.tt-pop .popover-body .text-muted{ color:var(--fc-ink-3) !important; }
.tt-pop .popover-body .bg-light{ background:var(--fc-inset) !important; color:var(--fc-ink-2) !important; }
/* The classic fragments' remaining Bootstrap vocabulary. These are chosen against a white
   page: info cyan and the badge fills are the two that land on the popover's dark ground. */
.tt-pop .popover-body .text-info{ color:var(--fc-accent) !important; }
.tt-pop .popover-body .border-info{ border-color:var(--fc-accent) !important; }
.tt-pop .popover-body .text-primary{ color:var(--fc-accent) !important; }
.tt-pop .popover-body .badge{ color:var(--fc-accent-ink) !important; }
.tt-pop .popover-body .badge.bg-success{ background:var(--fc-good) !important; }
.tt-pop .popover-body .badge.bg-danger{ background:var(--fc-poor) !important; }
.tt-pop .popover-body .badge.bg-warning{ background:var(--fc-fair) !important; }
.tt-pop .popover-body .badge.bg-primary,
.tt-pop .popover-body .badge.bg-info{ background:var(--fc-accent) !important; }
.tt-pop .popover-body .badge.bg-secondary{ background:var(--fc-inset) !important;
          color:var(--fc-ink-2) !important; }
/* The popover root's own colour is Bootstrap's body grey. Content that sits outside
   .popover-body inherits it, on the popover's own ground. */
.tt-pop.popover{ color:var(--fc-ink-2); }

.tt-pop.tooltip .tooltip-inner{ background:var(--fc-pop-bg); color:var(--fc-ink);
          border:1px solid var(--fc-line);
          font-size:calc(12px * var(--fc-scale, 1.15)); }
.tt-pop.tooltip .tooltip-arrow::before{ border-top-color:var(--fc-pop-bg);
          border-bottom-color:var(--fc-pop-bg);
          border-left-color:var(--fc-pop-bg); border-right-color:var(--fc-pop-bg); }

/* Hyper paints `.topnav` with its indigo brand gradient. The turtle chrome restyled the
   navbar itself but not that container, so it only showed for anonymous visitors -- whose
   nav links then sat on indigo at 2.96:1. Same for the footer's muted grey on near-white. */
.tt-wrap.fc .topnav{ background-image:none !important; background:var(--fc-band-bg) !important; }
.tt-wrap.fc .topnav .nav-link,
.tt-wrap.fc .topnav .navbar-nav .nav-link{ color:var(--fc-ink) !important; }
.tt-wrap.fc .topnav .nav-link:hover,
.tt-wrap.fc .topnav .nav-link:focus,
.tt-wrap.fc .topnav .nav-link.active{ color:var(--fc-accent) !important; }
.tt-wrap.fc .footer,
.tt-wrap.fc .footer .container-fluid{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .footer a{ color:var(--fc-accent) !important; }

/* Bootstrap alerts. Twenty-one of them across the sixteen chrome fragments -- the goal
   prompt, the tier banners, the messages framework -- all painted in Bootstrap's own
   pastels, which read as foreign on either turtle ground and jarring on the dark one.
   They are chrome, so they sit outside `.tt-sheet` and nothing had mapped them. */
.tt-wrap.fc .alert{ background:var(--fc-surface-2) !important; color:var(--fc-ink-2) !important;
          border:1px solid var(--fc-line) !important; border-radius:8px; }
.tt-wrap.fc .alert .alert-heading,
.tt-wrap.fc .alert strong{ color:var(--fc-ink) !important; }
.tt-wrap.fc .alert a:not(.btn){ color:var(--fc-accent) !important; }
.tt-wrap.fc .alert .text-primary,
.tt-wrap.fc .alert .text-info{ color:var(--fc-accent) !important; }
.tt-wrap.fc .alert .text-success{ color:var(--fc-val-g) !important; }
.tt-wrap.fc .alert .text-warning{ color:var(--fc-val-a) !important; }
.tt-wrap.fc .alert .text-danger{ color:var(--fc-val-r) !important; }
.tt-wrap.fc .alert .btn-primary,
.tt-wrap.fc .alert .btn-success{ background:var(--fc-accent) !important;
          border-color:var(--fc-accent) !important; color:var(--fc-accent-ink) !important; }
/* Each variant keeps its meaning through the left edge rather than a pastel fill. */
.tt-wrap.fc .alert-success{ border-left:4px solid var(--fc-good) !important; }
.tt-wrap.fc .alert-info,
.tt-wrap.fc .alert-primary{ border-left:4px solid var(--fc-accent) !important; }
.tt-wrap.fc .alert-warning{ border-left:4px solid var(--fc-fair) !important; }
.tt-wrap.fc .alert-danger{ border-left:4px solid var(--fc-poor) !important; }
.tt-wrap.fc .alert .btn-close{ filter:var(--fc-close-filter, none); }
:root[data-fc-theme="dark"] .tt-wrap.fc .alert .btn-close{ filter:invert(1) grayscale(1) brightness(2); }

/* Row markers restored alongside the form figures. */
.tt-wrap.fc .tt-days{ color:var(--fc-ink-3); white-space:nowrap; }
/* Course/distance winner reads as a phrase in the tag row, not a letter badge. */
.tt-wrap.fc .tt-tag-cd{ border-color:var(--fc-line-2); color:var(--fc-accent); }
.tt-wrap.fc .tt-rateswrap{ min-width:0; }

/* The statistics panel's own filtered/all switch. */
/* The two buttons sat on their own above the tab row and read as page furniture rather than
   as a control belonging to these statistics. Named, boxed and on the panel's own inset, so
   what they govern is the thing underneath them. */
.tt-wrap.fc .tt-statscope-bar{ display:flex; align-items:center; flex-wrap:wrap; gap:10px;
          margin:0 0 12px; padding:8px 10px; border:1px solid var(--fc-hair);
          border-radius:8px; background:var(--fc-inset); }
.tt-wrap.fc .tt-statscope-label{ font-weight:600; color:var(--fc-ink);
          font-size:calc(13px * var(--fc-scale)); }
.tt-wrap.fc .tt-statscope-note{ color:var(--fc-ink-2); font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-statscope{ display:flex; gap:4px; margin:0; }
.tt-wrap.fc .tt-statscope .tt-seg{ padding:4px 12px; }
.tt-wrap.fc .tt-statscope .tt-seg[disabled]{ opacity:.55; cursor:default; }

/* The interactive career chart replaces the inline SVG once it has rendered. */
.tt-wrap.fc .tt-chart-live{ width:100%; min-height:0; }
.tt-wrap.fc .tt-chart-live[hidden]{ display:none !important; }
.tt-wrap.fc .tt-chart svg[hidden]{ display:none !important; }
/* Quick Settings autosave. The state has to be readable without colour alone, so the
   words carry it and the colour only reinforces. */
.tt-wrap.fc .tt-savenote{ margin:10px 0 0; min-height:1.2em;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink-3); }
.tt-wrap.fc .tt-savenote.is-ok{ color:var(--fc-accent); }
.tt-wrap.fc .tt-savenote.is-bad{ color:var(--fc-poor); font-weight:600; }

/* Shortlist and hide, beside the comment. The controls already existed but only inside the
   actions menu, which is the last place somebody who has just read a comment will look. */
.tt-wrap.fc .tt-commentacts{ display:flex; align-items:center; gap:10px; margin-top:6px; }
.tt-wrap.fc .tt-commentact{ display:inline-flex; align-items:center; gap:5px;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink-3); }
.tt-wrap.fc .tt-commentact:hover{ color:var(--fc-ink); }
.tt-wrap.fc .tt-commentact .tt-actlbl{ font-size:inherit; }

/* The runner's record against today's race. Sits above the tabs, so it is the first thing
   read whichever tab is open. */
.tt-wrap.fc .tt-insightline{ display:flex; gap:8px; align-items:flex-start;
          margin:0 0 10px; padding:8px 11px; border-radius:6px;
          border-left:3px solid var(--fc-accent); background:var(--fc-surface-2);
          color:var(--fc-ink-2); font-size:max(12px, calc(13px * var(--fc-scale)));
          line-height:1.5; }
.tt-wrap.fc .tt-insightline > i{ color:var(--fc-accent); margin-top:3px; }

/* The price trend. Labelled at both ends so the line has a direction the reader can name. */
.tt-wrap.fc .tt-oddstrend{ margin:10px 0 4px; }
.tt-wrap.fc .tt-oddstrend figcaption{ display:flex; justify-content:space-between;
          color:var(--fc-ink-3); margin-top:2px;
          font-size:max(10px, calc(11px * var(--fc-scale))); }
/* The line matches the arrow: green shortening, red drifting. A price that has not
   moved far enough to say anything keeps the neutral ink. */
.tt-wrap.fc .tt-spark-odds.is-in polyline{ stroke:var(--fc-val-g); }
.tt-wrap.fc .tt-spark-odds.is-out polyline{ stroke:var(--fc-move-out); }
.tt-wrap.fc .tt-spark-odds.is-in circle{ fill:var(--fc-accent); }

/* The whole comment block goes from the FORM fragment: the suitability ticks, the summary
   line and the bullet list are what the Insights tab is for, and the drawer was showing all
   of it twice. What stays in the Horse & Trainer sub-tab is what Insights does NOT have --
   the pedigree table, the consistency stats and the run stats.

   Hidden here rather than removed from the fragment, because the classic card's row does not
   show the comment at all: that tab is where its customers read it. The customer's own saved
   note goes with it, and is still reachable in Insights. */
.tt-wrap.fc .tt-formfull .bt-comments{ display:none !important; }

/* And with it the whole Horse & Trainer sub-tab. Every part of it is elsewhere in the drawer:
   the comment block in Insights, Consistency and Lifetime as packs under Form, the trainer and
   jockey records under Why, and the pedigree in Form's key facts. Hidden only inside the turtle
   drawer: on the classic card this is the fragment's default tab and carries content its
   customers have nowhere else. */
.tt-wrap.fc .tt-formfull .nav-item:has(> [href*="horsemenu"]){ display:none !important; }

/* Form Grid plots the same career runs as Lifetime Runs, which sits two tabs to its left. */
.tt-wrap.fc .tt-formfull .nav-item:has(> [href*="formgridmenu"]){ display:none !important; }

/* Race Profile / 10 Year Trends are chips in the brief bar above, so the statistics panel's
   own copy of that tab is a second way into the same page. Hidden here only: on the classic
   card that tab is the only way to reach it. */
.tt-wrap.fc .tt-statspanel .nav-item:has(> [href*="trendsmenu"]){ display:none !important; }

/* The AI comment is on the row already, so its repeat at the head of Insights goes. With the
   form table, the suitability ticks and the comment card all switched off it is the whole of
   the FETCHED fragment, which then renders nothing -- the loader says so in that case rather
   than leaving an empty box under the profile pack. The customer's own comment and the
   "available by 6am" notice are neither a repeat nor hidden. */
.tt-wrap.fc [data-tt-insight] .bt-comments > .alert:has(strong):not(:has(p)){
          display:none !important; }
.tt-wrap.fc [data-tt-insight] .bt-comments > .alert:has(p) > strong{ display:none !important; }

/* Headgear. Boxed rather than capitalised: the codes are lower case everywhere in racing,
   and a box makes them findable without shouting. First-time headgear says the yard has
   changed something, so it carries the accent. */
.tt-wrap.fc .tt-gear{ display:inline-block; padding:0 4px; border-radius:3px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink-2); font-size:.92em; line-height:1.45; }
.tt-wrap.fc .tt-gear.is-first{ border-color:var(--fc-accent); color:var(--fc-ink);
          font-weight:600; }
.tt-wrap.fc .tt-gearfirst{ color:var(--fc-ink-2); font-weight:500; }

/* Column headings for the horseshoe tiles. The heading mirrors `.tt-r1`'s own grid at every
   width, so each letter sits over the tile it names; the row template changes at 768, 992 and
   1400 and each band below restates it. The letters are buttons: pressing one opens the icon
   guide filtered to that factor, which is the route to the key on a touch device. */
.tt-wrap.fc .tt-runhead{ display:grid; gap:0 10px; padding:0 10px 3px;
          grid-template-columns:44px 40px 1fr 30px 30px auto; }
.tt-wrap.fc .tt-runhead-shoes{ grid-column:1 / 4; display:flex; gap:4px; }
.tt-wrap.fc .tt-runhead-pick{ grid-column:4; text-align:center; }
.tt-wrap.fc .tt-runhead-shoes > button, .tt-wrap.fc .tt-runhead-pick{
          font-size:max(11px, calc(10px * var(--fc-scale))); font-weight:700;
          letter-spacing:.12em; text-transform:uppercase; color:var(--fc-ink-3); }
.tt-wrap.fc .tt-runhead-shoes > button{ flex:1 1 0; min-width:0; text-align:center;
          background:none; border:0; padding:4px 0; cursor:pointer; }
.tt-wrap.fc .tt-runhead-shoes > button:hover,
.tt-wrap.fc .tt-runhead-shoes > button:focus-visible{ color:var(--fc-accent); }

@media (min-width:768px){
  .tt-wrap.fc .tt-runhead{ grid-template-columns:46px 42px minmax(0,1fr) 118px 126px; }
  .tt-wrap.fc .tt-runhead-shoes{ grid-column:1 / 5; }
  .tt-wrap.fc .tt-runhead-pick{ grid-column:5; }
}
@media (min-width:992px){
  .tt-wrap.fc .tt-runhead{ gap:0 8px;
          grid-template-columns:46px 42px minmax(150px,1.3fr) minmax(150px,1fr) 290px 46px 118px 62px 86px; }
  .tt-wrap.fc .tt-runhead-shoes{ grid-column:5; }
  .tt-wrap.fc .tt-runhead-pick{ grid-column:6; }
}
@media (min-width:1400px){
  .tt-wrap.fc .tt-runhead{
          grid-template-columns:46px 42px minmax(170px,1.4fr) minmax(160px,1fr) minmax(212px,232px) 270px 46px 118px 62px 86px; }
  .tt-wrap.fc .tt-runhead-shoes{ grid-column:6; }
  .tt-wrap.fc .tt-runhead-pick{ grid-column:7; }
}

/* The last six finishing positions, oldest first. */
.tt-wrap.fc .tt-formrun{ display:flex; align-items:center; flex-wrap:wrap; gap:4px;
          margin-top:8px; font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-formrun b{ color:var(--fc-ink-2); margin-right:2px; }
.tt-wrap.fc .tt-formrun em{ color:var(--fc-ink-3); font-style:normal; margin-left:4px;
          font-size:.9em; }
.tt-wrap.fc .tt-pos{ display:inline-flex; align-items:center; justify-content:center;
          min-width:20px; height:20px; padding:0 4px; border-radius:3px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink-2); font-variant-numeric:tabular-nums; }
.tt-wrap.fc .tt-pos.is-win{ border-color:var(--fc-accent); color:var(--fc-ink);
          font-weight:700; }
.tt-wrap.fc .tt-pos.is-place{ border-color:var(--fc-line); color:var(--fc-ink); }
.tt-wrap.fc .tt-pos.is-none{ color:var(--fc-ink-3); border-style:dashed; }
.tt-wrap.fc .tt-runorder{ margin-bottom:4px; }

/* Filters on/off. `is-go` is the normal state -- the customer's filter is being applied --
   so the OFF state is the one that has to look deliberate rather than broken. */
.tt-wrap.fc .tt-tool.is-off{ background:var(--fc-inset); border-style:dashed;
          border-color:var(--fc-line-2); color:var(--fc-ink-3); }
.tt-wrap.fc .tt-tool.is-off:hover{ color:var(--fc-ink); border-color:var(--fc-accent); }

/* Charts on or off across the card. Both drawings the button names -- the stat-pack and
   price figures, and the sparkline beside each rating line -- and the live ApexCharts layer
   that renders over the figure. */
.tt-wrap.fc .tt-runners.is-nocharts .tt-chart,
.tt-wrap.fc .tt-runners.is-nocharts .tt-rowchart,
.tt-wrap.fc .tt-runners.is-nocharts .tt-rowspark,
.tt-wrap.fc .tt-runners.is-nocharts .tt-sixline .tt-spark{ display:none !important; }

/* The Apex layer sits where the SVG does and replaces it once it has rendered, so there is
   never a moment with two lines drawn. */
/* Fixed to the SVG's own box. Sparkline mode expands to whatever it is given, and given a
   button's content box it drew a line across the horseshoes. */
.tt-wrap.fc .tt-rowchart{ display:block; position:relative; line-height:0; overflow:hidden;
          width:50px; height:25px; margin:1px auto 0; }
/* The rating chip is a baseline flex row, so the chart landed BESIDE the figure and the three
   chips grew wide enough to squeeze each other. Given a full-width basis it wraps underneath,
   which is where it was asked for. */
.tt-wrap.fc .tt-rate{ flex-wrap:wrap; }
/* Price and its arrow stay on one line; the chart goes underneath them. */
.tt-wrap.fc .tt-oddsline{ display:inline-flex; align-items:center; gap:2px; white-space:nowrap; }
.tt-wrap.fc .tt-rate .tt-rowchart{ flex:0 0 100%; }
.tt-wrap.fc .tt-rowchart .tt-chart-live{ display:block; width:100%; height:25px; }
.tt-wrap.fc .tt-rowchart .apexcharts-canvas,
.tt-wrap.fc .tt-rowchart .apexcharts-canvas svg{ width:100% !important; height:25px !important; }
/* `is-live` is only set when an Apex chart actually renders, which it does not while
   `ttApexSeries` is off -- so the inline graph stays visible. Left in place for when it is
   switched back on. */
.tt-wrap.fc .tt-rowchart.is-live > .tt-rowspark{ display:none; }
.tt-wrap.fc .tt-rowchart .apexcharts-canvas{ margin:0 auto; }
@media print{ .tt-wrap.fc .tt-rowchart .tt-chart-live{ display:none; }
              .tt-wrap.fc .tt-rowchart.is-live > .tt-rowspark{ display:block; } }

/* The six-run line under a rating, and the price line under the price. Its own block so the
   chip lays out as figure-over-line rather than figure-beside-line. */
.tt-wrap.fc .tt-rowspark{ display:block; margin:1px auto 0; overflow:visible; }
.tt-wrap.fc .tt-rowspark polyline{ fill:none; stroke:var(--fc-ink-3); stroke-width:1.2;
          stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke; }
.tt-wrap.fc .tt-rowspark circle{ fill:var(--fc-ink-2); }
.tt-wrap.fc .tt-rowspark.is-up polyline{ stroke:var(--fc-val-g); }
.tt-wrap.fc .tt-rowspark-odds.is-in polyline{ stroke:var(--fc-val-g); }
.tt-wrap.fc .tt-rowspark-odds.is-out polyline{ stroke:var(--fc-move-out); }

/* A tablet in portrait draws with Apex, a phone with the inline SVG, and the Charts button is
   offered wherever there is a drawing to switch off (Kenny, 4 Sep). */
@media (max-width: 991px){
  .tt-wrap.fc .tt-rate{ flex-wrap:wrap; }
  .tt-wrap.fc .tt-rate .tt-rowchart{ flex:0 0 100%; }
}

/* Market direction, and the short series behind a rating.
   Green shortening, red drifting (Kenny, 31 Aug 2026). The value inks rather than the
   horseshoe pair: these sit on the row ground at 10px, where the glyph inks do not clear AA. */
.tt-wrap.fc .tt-move-in{ color:var(--fc-val-g); margin-left:3px;
          font-size:max(9px, calc(10px * var(--fc-scale))); }
.tt-wrap.fc .tt-move-out{ color:var(--fc-move-out); margin-left:3px;
          font-size:max(9px, calc(10px * var(--fc-scale))); }

.tt-wrap.fc .tt-spark{ display:inline-block; vertical-align:middle; margin:0 8px;
          overflow:visible; }
.tt-wrap.fc .tt-spark polyline{ fill:none; stroke:var(--fc-ink-3); stroke-width:1.4;
          stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke; }
.tt-wrap.fc .tt-spark circle{ fill:var(--fc-ink-2); }
.tt-wrap.fc .tt-spark.is-up polyline{ stroke:var(--fc-accent); }
.tt-wrap.fc .tt-spark.is-up circle{ fill:var(--fc-accent); }
.tt-wrap.fc .tt-spark-odds{ display:block; width:100%; margin:8px 0 4px; }
.tt-wrap.fc .tt-sixline{ display:flex; align-items:center; flex-wrap:wrap; gap:2px 4px; }

/* Once ApexCharts has taken over, the static fallback and its own caption and key go.
   The child combinator is load-bearing: the fallback drawing is a DIRECT child of the
   figure, while ApexCharts renders its own <svg> inside .tt-chart-live. A descendant
   selector here hid the chart it had just drawn -- it appeared, then blanked. */
.tt-wrap.fc .tt-chart.is-live > svg,
.tt-wrap.fc .tt-chart.is-live > figcaption,
.tt-wrap.fc .tt-chart.is-live > .tt-chart-key{ display:none !important; }
/* While Apex is fetching, the static drawing stays out of the way rather than appearing and
   being replaced a moment later. The height is held so the pane does not jump when the chart
   lands; it matches options.chart.height in betturtle-turtle.js. If Apex gives up, the class
   comes off and the drawing takes over. */
.tt-wrap.fc .tt-chart.is-pending{ min-height:260px; }
/* The price chart is shorter than the career ones, so it holds its own height while it
   loads rather than reserving space it will not use. */
.tt-wrap.fc .tt-oddstrend.is-pending{ min-height:210px; }
.tt-wrap.fc .tt-chart.is-pending > svg,
.tt-wrap.fc .tt-chart.is-pending > figcaption,
.tt-wrap.fc .tt-chart.is-pending > .tt-chart-key{ display:none !important; }

/* Comments mode. One copy of the comment, revealed either when its own drawer is open or
   when the whole card is in Comments mode. */
.tt-wrap.fc .tt-rowcomment{ display:none; grid-column:1 / -1; margin:6px 0 2px;
          padding:8px 10px; border-left:3px solid var(--fc-accent);
          background:var(--fc-surface-2); border-radius:0 6px 6px 0; }
.tt-wrap.fc .tt-runner.is-open .tt-rowcomment,
.tt-wrap.fc .tt-runners.is-comments .tt-rowcomment{ display:block; }
.tt-wrap.fc .tt-rowcomment .tt-comment{ margin:0; }
.tt-wrap.fc .tt-whybtn{ margin-top:6px; padding:3px 10px; border-radius:5px;
          border:1px solid var(--fc-line-2); background:var(--fc-inset);
          color:var(--fc-ink); cursor:pointer; font:inherit;
          font-size:calc(12px * var(--fc-scale)); }
.tt-wrap.fc .tt-whybtn:hover{ background:var(--fc-hover); }
/* The drawer opens on Why, so the button that opens Why has nothing left to do. */
/* The button STAYS when the drawer opens (Kenny, 31 Aug, twice). It used to be hidden
   here, so the control that opened the panel vanished and there was no way back out
   with it. It is lit while open and closes what it opened. */
/* No dimming of the ratings in Comments mode. Fading them to .55 measured 2.2-3.6:1 on
   every value ink -- legible data pushed below AA to make a stylistic point. The comment's
   own accent border already gives it the lead. */

/* Winner-profile traits on the row (Enhanced). The chip names how many of the race's own
   winner traits a runner matches and opens the list; `is-best` marks a closest match, which
   is the same set the Race Profile panel's "closest matches" names. */
/* `font:inherit` gave the traits button the row's ~13px instead of the tag's 10px, so it
   sat a size and a weight above the tags beside it and read as the loudest thing on the row.
   Inherit the family only; the rest matches .tt-tag exactly. */
.tt-wrap.fc button.tt-tag-fit{ cursor:pointer; font-family:inherit; display:inline-flex;
          align-items:center; gap:4px; text-transform:uppercase; letter-spacing:.04em;
          font-weight:600; font-size:max(10px, calc(10px * var(--fc-scale)));
          line-height:1.35; padding:1px 6px; border-radius:3px; }
.tt-wrap.fc button.tt-tag-fit i{ font-size:.85em; }
.tt-wrap.fc .tt-tag-fit.is-best{ border-color:var(--fc-accent);
          background:color-mix(in srgb, var(--fc-accent) 16%, transparent);
          color:var(--fc-ink); font-weight:600; }
.tt-wrap.fc button.tt-tag-fit[aria-expanded="true"]{ border-color:var(--fc-accent); }
.tt-wrap.fc .tt-rowtraits{ margin:6px 0 2px; padding:8px 10px; border-radius:8px;
          background:var(--fc-inset); border:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-rowtraits-head{ margin:0 0 5px; color:var(--fc-ink); font-weight:600;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-rowtraits-line{ display:flex; gap:7px; margin:0 0 4px;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink-2);
          line-height:1.45; }
.tt-wrap.fc .tt-rowtraits-line b{ color:var(--fc-ink); font-weight:600; }
.tt-wrap.fc .tt-rowtraits-line.is-tick i{ color:var(--fc-val-g); }
.tt-wrap.fc .tt-rowtraits-line.is-cross i{ color:var(--fc-val-r); }
.tt-wrap.fc .tt-rowtraits-note.is-best{ color:var(--fc-ink-2); font-weight:600; }
.tt-wrap.fc .tt-rowtraits-note{ margin:2px 0 0; color:var(--fc-ink-3);
          font-size:max(11px, calc(11.5px * var(--fc-scale))); }

/* 10 Year Trends: the footer records, and today's runners that have been here before. The
   table above is past winners; this is the other question the same history answers. */
.tt-wrap.fc .tt-trendfoot{ margin:8px 0 0; }
/* The year links to that running's own card. The sheet's link rule paints links in the
   accent, which on this ground is 2.97:1 -- the same defect as the Odds column headings.
   A link inside a data table reads as one by its underline, not its hue. */
.tt-wrap.fc .tt-table .tt-year a{ color:var(--fc-ink) !important;
          text-decoration:underline; text-underline-offset:2px;
          text-decoration-color:var(--fc-line); }
.tt-wrap.fc .tt-table .tt-year a:hover{ text-decoration-color:var(--fc-ink-2); }
.tt-wrap.fc .tt-returners{ margin-top:14px; padding-top:12px;
          border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-returners-h{ margin:0 0 8px; color:var(--fc-ink); font-weight:600;
          font-size:max(12px, calc(13.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-returner{ margin-bottom:9px; }
.tt-wrap.fc .tt-returner-n{ margin:0; display:flex; flex-wrap:wrap; align-items:baseline;
          gap:8px; font-size:max(11px, calc(12.5px * var(--fc-scale))); color:var(--fc-ink); }
.tt-wrap.fc .tt-returner-run{ color:var(--fc-ink-2); }
.tt-wrap.fc .tt-returner-run.is-won{ color:var(--fc-val-g); font-weight:600; }
.tt-wrap.fc .tt-returner-d{ margin:2px 0 0; color:var(--fc-ink-3);
          font-size:max(11px, calc(12px * var(--fc-scale))); }

/* What the three rating lines show, stated. Computed arithmetic over the same numbers. */
.tt-wrap.fc .tt-ratingread{ margin:8px 0 2px; padding:8px 10px; border-radius:8px;
          background:var(--fc-inset); border:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-ratingread p{ margin:0 0 4px; color:var(--fc-ink-2); line-height:1.5;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-ratingread p:last-child{ margin-bottom:0; }

/* Today's racing: the reused board, with the three tabs this page already answers hidden.
   Scoped to .tt-board so the classic races page keeps all six. Hiding the tab is not enough
   -- its pane carries `active` from the fragment, so the board would open on a hidden pane
   and read as empty. The first visible tab is activated in JS for that reason. */
/* Two of the board's tabs, Races and Times, repeat the "Meetings today" section directly
   above them -- the same courses and the same time buttons. They are hidden; NEXT RACES stays,
   along with Non-Runners, Tomorrow and the days after, because none of those is anywhere else
   on the page.

   The turtle "Next off" strip went instead of this tab: the board's version is the fuller one
   and is what the classic page offered. Removing the tab and keeping the strip would have
   given the smaller answer. */
.tt-wrap.fc .tt-board .nav-item:has(> a[href="#times_detailedmenu"]),
.tt-wrap.fc .tt-board .nav-item:has(> a[href="#times_shortmenu"]),
.tt-wrap.fc .tt-board .nav-item:has(> a[href="#timeordermenu"]){ display:none; }
.tt-wrap.fc .tt-board #times_detailedmenu,
.tt-wrap.fc .tt-board #times_shortmenu,
.tt-wrap.fc .tt-board #timeordermenu{ display:none !important; }

/* Prose links inside a panel take the sheet's accent, which on the light ground is 3.55:1.
   A link in running text reads as one by its underline. */
.tt-wrap.fc .tt-panel p a,
.tt-wrap.fc .tt-body a{ color:var(--fc-ink) !important; text-decoration:underline;
          text-underline-offset:2px; text-decoration-color:var(--fc-line); }
.tt-wrap.fc .tt-panel p a:hover,
.tt-wrap.fc .tt-body a:hover{ text-decoration-color:var(--fc-ink-2); }

/* A finished race's time button is faded to `opacity: 0.3` by an inline style in
   races/v2/snippets/timebutton.html. It is not a disabled control -- it has no disabled
   attribute, keeps pointer events, is keyboard focusable and links to that race's card -- so
   WCAG's exemption for inactive components does not apply, and at .3 the label measures
   1.76:1. Measured across the range: .7 still fails at 4.00, .8 is the first value that
   clears AA on both button variants at 4.82.

   !important because the fade is an inline style. Scoped to .tt-board so the classic page
   keeps what it has today -- where the same 0.3 is just as unreadable. */
.tt-wrap.fc button.btn[style*="opacity"]{ opacity:.8 !important; }

/* A career-form row that is a previous running of today's race. */
.tt-wrap.fc .tt-formfull tr.is-prevrun{ background:color-mix(in srgb, var(--fc-accent) 12%, transparent); }
/* Under the date, not beside it: inline, the tag set the column's width for every row in
   the table, and the date column is the one the reader scans down. */
.tt-wrap.fc .tt-prevrun{ display:block; width:fit-content; margin:3px 0 0; padding:1px 5px;
          border-radius:4px; background:var(--fc-accent); color:var(--fc-accent-ink);
          font-size:max(10px, calc(10.5px * var(--fc-scale))); font-weight:700;
          letter-spacing:.02em; white-space:nowrap; }

/* DataTables 2 sort indicators. It renders `span.dt-column-order` and draws the arrows with
   ::before/::after; that CSS is not in the turtle build, so every sortable header lost its
   affordance -- the columns still sorted, nothing said they could. Plain triangles rather
   than an icon font: the indicator should not depend on a webfont that a stylesheet strip
   can remove, which is how the classic card lost the same arrows to Remix Icon.

   betturtle-base.css overlays the control at opacity 0 and reveals it on hover or on the
   sorted column only, in a 6px box -- so a reader who does not already know the header is
   sortable has nothing to tell them, and the glyph is clipped. Both are overridden here; the
   base rule carries !important on the width, so these do too.

   currentColor, not --fc-ink: the table head is a dark ground carrying white text, where the
   page ink is invisible. */
.tt-wrap.fc table.dataTable thead th span.dt-column-order{
          position:absolute; right:1px !important; top:50%; transform:translateY(-50%);
          width:7px !important; min-width:7px !important; height:16px;
          opacity:1 !important; pointer-events:none; }
/* The pair sits symmetrically about the middle of the box, so the two glyphs together read
   as centred against the header text rather than hanging off its baseline. */
.tt-wrap.fc table.dataTable thead th.dt-orderable-asc span.dt-column-order::before,
.tt-wrap.fc table.dataTable thead th.dt-orderable-desc span.dt-column-order::after{
          position:absolute; left:0; right:0; display:block; text-align:center;
          font-size:7px; line-height:7px; color:currentColor; opacity:.62; }
.tt-wrap.fc table.dataTable thead th.dt-orderable-asc span.dt-column-order::before{
          content:"\25B2"; top:0; }
.tt-wrap.fc table.dataTable thead th.dt-orderable-desc span.dt-column-order::after{
          content:"\25BC"; bottom:0; }
/* The column actually in use reads at full strength. */
.tt-wrap.fc table.dataTable thead th.dt-ordering-asc span.dt-column-order::before,
.tt-wrap.fc table.dataTable thead th.dt-ordering-desc span.dt-column-order::after{
          opacity:1; }
.tt-wrap.fc table.dataTable thead th.dt-orderable-asc:hover span.dt-column-order::before,
.tt-wrap.fc table.dataTable thead th.dt-orderable-desc:hover span.dt-column-order::after{
          opacity:.85; }
/* No reserved gap for the overlay. Measured: a 26-column table pays for one on every column,
   which costs ~130px and puts the table back outside its pane -- and the pane is what the
   reader actually notices. The glyph sits in the cell padding instead. */

/* The run-by-run tables carry 25 and 36 columns. They were overflowing their pane by about
   a dozen pixels at every width, so the whole table scrolled sideways to show one more
   column of a two-character value. Trimming the horizontal cell padding recovers roughly
   4px per column -- 140px across Run Quality -- which is far more than the overflow. */
.tt-wrap.fc .tt-formfull table.dataTable > tbody > tr > td,
.tt-wrap.fc .tt-formfull table.dataTable > thead > tr > th{
          padding-left:4px !important; padding-right:4px !important; }
/* Career form: the date and the chequered flag both open that race's report, and both were
   rendering in the table's own ink -- white on dark -- so nothing said they could be pressed
   (Derek, 1 Sep). A blue, deliberately not the accent: the accent is the brand's colour and is
   used for state all over the card, whereas nothing else in these tables is blue. 7.3:1 on the
   dark ground and 6.3:1 on the light one.

   `.tt-sheet table.table a` already paints these `--fc-ink !important` and carries one class
   more, so this has to out-specify it rather than merely follow it. Note `.tt-formfull.tt-sheet`
   and not `.tt-sheet .tt-formfull`: they are the SAME element, so the descendant form matched
   nothing at all. */
:root{ --fc-linkish:#7fb3ff; }
/* First place is blue across the new design, as the classic card has always badged it
   (`position.html` uses bg-primary for a winner). It was three different things: gold on
   the card, #1e5a8a in the sheet, #5a63e0 on Your day. One ground for the badges, one ink
   for the card's own place text -- white on the ground is 4.9:1, and the ink clears AA on
   both card grounds. */
/* The tooltip's red. `--fc-val-r` measures 3.95:1 on the dark popover ground -- under AA for
   text this size -- so the tooltip lightens it to 5.1:1. Light is unchanged at 5.7:1. */
:root{ --fc-tip-r:#ff8078; }
:root:not([data-fc-theme="dark"]){ --fc-tip-r:#d10011; }
:root{ --fc-first-bg:#5a63e0; --fc-first-ink:#7fb3ff; }
:root:not([data-fc-theme="dark"]){ --fc-first-ink:#1857b8; }
:root:not([data-fc-theme="dark"]){ --fc-linkish:#1857b8; }
.tt-wrap.fc .tt-formfull.tt-sheet table.table a,
.tt-wrap.fc .tt-formfull.tt-sheet table.table .btn-link,
.tt-wrap.fc .tt-formfull.tt-sheet table.table a .fa-flag-checkered,
.tt-wrap.fc .tt-formfull.tt-sheet table.dataTable a,
.tt-wrap.fc .tt-formfull.tt-sheet table.dataTable .btn-link{ color:var(--fc-linkish) !important; }
.tt-wrap.fc .tt-formfull.tt-sheet table a:hover,
.tt-wrap.fc .tt-formfull.tt-sheet table a:focus-visible{ text-decoration:underline; }

/* The date is the widest thing in the first column and it never wraps. */
.tt-wrap.fc .tt-formfull table[id^="formmenu"] tbody td:first-child,
.tt-wrap.fc .tt-formfull table[id^="formplusmenu"] tbody td:first-child{ white-space:nowrap; }

/* The tables sit in a Bootstrap `.card.p-1`, whose padding and border make its content box
   12px wider than the pane it sits in -- so both tables overflowed by exactly 12px whatever
   their column count, and the page scrolled sideways to show nothing. Keep the overflow
   inside the card, which is this project's rule for wide content anyway. */
.tt-wrap.fc .tt-formfull .card{ max-width:100%; overflow-x:auto; }
.tt-wrap.fc .tt-formfull .tab-content{ max-width:100%; }

/* Three elements were taking their colour from the classic stylesheet rather than the
   tokens their own rules name: `.tt-why-h` is declared unscoped, so a Hyper heading rule
   outranks it, and the two links lose to Bootstrap's `a` colour. All three then render a
   light-on-dark colour on the LIGHT theme -- 1.09:1, 1.56:1 and 1.62:1. Scoped and raised.
   Invisible to the audit until --expand learned to open the panels they sit in. */
.tt-wrap.fc .tt-why-h,
.tt-wrap.fc .tt-panel-h{ color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-classic{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc a.tt-notice-cta{ color:var(--fc-ink) !important; }
.tt-wrap.fc a.tt-notice-cta.is-go{ color:var(--fc-accent-ink) !important; }

/* The reused board's own markup carries light-on-dark colours (a Hyper card written for the
   dark shell), so on the light theme its headings and the non-runner list read at 1.02:1.
   Scoped to .tt-board, so the classic page keeps what it has. */
.tt-wrap.fc .tt-board :is(h1, h2, h3, h4, h5, .header-title){ color:var(--fc-ink); }
/* Not inside a button: the race-time buttons are colour-coded by race class and carry their
   own badges, and repainting them with the sheet ink threw that coding away. */
.tt-wrap.fc .tt-board .tab-content :is(div, span, p, strong, b):not(.btn):not(.btn *):not(.badge):not(.badge *){
          color:var(--fc-ink); }
.tt-wrap.fc .tt-board .tab-content a:not(:has(.btn)):not(.btn){ color:var(--fc-ink); }
/* NOT restyled: the going and TV strip is white on a dark green panel of its own, which
   reads fine. The audit scores it 2.44:1 because its ground-walk composites past that panel
   to the light page behind it. Left alone deliberately -- three attempts to "fix" it only
   added CSS that changed nothing. Worth confirming by eye before anyone tries again. */

/* The navbar is rendered outside .tt-wrap, so it is scoped by the body CONTAINING the turtle
   shell rather than by an ancestor -- and on :has() rather than the data-fc-theme attribute,
   which only exists once the theme script has run.

   Hyper marks the current page with its own dark grey, which does not follow the theme: on
   the light theme that is the sheet's dark ink on a dark grey block, 1.74:1. The current
   page should be marked in the accent, like everything else that means "this one". */
body:has(.tt-wrap.fc) .dropdown-item.active,
body:has(.tt-wrap.fc) .dropdown-item:active,
body:has(.tt-wrap.fc) .nav-link.active{
          background-color:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }

/* Instant tooltips.

   A native `title` waits about a second before the browser shows it, which on a small marker
   like the headgear code reads as the page being slow. A Bootstrap tooltip is instant but
   costs an instance and a Popper layout per element, and the card carries hundreds.

   `data-tt-tip` is CSS only: no JS, no instance, nothing to initialise, and it appears on
   hover and on keyboard focus. Use it for short fixed labels; anything that needs HTML, a
   fetch or a click stays a popover. */
.tt-wrap.fc [data-tt-tip]{ position:relative; }
.tt-wrap.fc [data-tt-tip]::after{
          content:attr(data-tt-tip); position:absolute; left:50%; bottom:calc(100% + 6px);
          transform:translateX(-50%); z-index:60; pointer-events:none;
          opacity:0; visibility:hidden; transition:opacity .08s linear;
          background:var(--fc-pop-bg); color:var(--fc-ink); border:1px solid var(--fc-line);
          border-radius:6px; padding:4px 8px;
          /* Was `nowrap`, which is right for "Vibes" and absurd for the 130-character
             explanations the card also carries -- a single line wider than the screen. Sized
             to the content up to a readable measure, then wrapped. */
          white-space:normal; width:max-content; max-width:min(260px, 70vw); text-align:center;
          font-size:max(11px, calc(12px * var(--fc-scale))); font-weight:500; line-height:1.35;
          box-shadow:0 4px 14px rgba(0,0,0,.28); }
.tt-wrap.fc [data-tt-tip]:hover::after,
.tt-wrap.fc [data-tt-tip]:focus-visible::after,
.tt-wrap.fc [data-tt-tip].is-tipped::after{ opacity:1; visibility:visible; }
@media (prefers-reduced-motion:reduce){
  .tt-wrap.fc [data-tt-tip]::after{ transition:none; }
}
/* The cloth sits in the row's top-left corner, which is exactly where the tip ribbon is
   absolutely positioned. A tooltip opening upward from the draw lands on the ribbon and the
   two read as one jumbled box (profiler, 1 Sep). It opens downward instead -- the same flip
   the view bar uses, for the same reason: there is something in the way above it. */
/* Downward, and anchored to the LEFT edge rather than centred on it. The cloth is the first
   thing in the row, so a tooltip centred on an 18px badge hangs half its width off the page --
   and it got wider the moment it carried the draw's record (Kenny, 1 Sep). */
.tt-wrap.fc .tt-cloth [data-tt-tip]::after{ bottom:auto; top:calc(100% + 6px);
          left:0; transform:none; text-align:left; }

/* And the record inside it takes its own band. `--fc-val-*` rather than `--fc-good/fair/poor`
   because these are the values tuned for the popover ground -- the horseshoe inks fail AA on
   it, which is why the two families exist. */
.tt-wrap.fc .tt-draw.is-g[data-tt-tip]::after{ color:var(--fc-val-g); }
.tt-wrap.fc .tt-draw.is-a[data-tt-tip]::after{ color:var(--fc-val-a); }
.tt-wrap.fc .tt-draw.is-r[data-tt-tip]::after{ color:var(--fc-tip-r); }

/* The view bar is the first thing on the page, so a tooltip above it is drawn off the top of
   the screen -- measured at -24px. Anything pinned to the top edge shows its tooltip below. */
.tt-wrap.fc .tt-viewbar [data-tt-tip]::after{ bottom:auto; top:calc(100% + 6px); }

/* The row's actions as a small grid rather than two buttons and a "..." menu. Every one of
   these is one tap on the classic card, and the ellipsis said nothing about what it hid. */
.tt-wrap.fc .tt-actcell{ display:grid; grid-template-columns:repeat(3, 1fr); gap:2px 4px;
          justify-items:center; align-items:center; }
.tt-wrap.fc .tt-actcell .tt-more{ grid-column:1 / -1; margin-top:2px; }
.tt-wrap.fc .tt-actcell .tt-actrow{ display:inline-flex; align-items:center;
          justify-content:center; min-width:24px; min-height:24px; }
@media (max-width:1100px){
  /* Stacked layouts give the cell its width back, so the actions can sit in one line. */
  .tt-wrap.fc .tt-actcell{ grid-template-columns:repeat(6, auto); justify-content:flex-start; }
  .tt-wrap.fc .tt-actcell .tt-more{ grid-column:auto; margin-top:0; }
}

/* The trainer and jockey names are buttons now, and must not look like a form control. */
.tt-wrap.fc .tt-connname{ border:0; background:none; padding:0; font:inherit; color:inherit;
          cursor:pointer; text-align:left; text-decoration:underline;
          text-underline-offset:2px; text-decoration-color:var(--fc-line); }
.tt-wrap.fc .tt-connname:hover{ text-decoration-color:var(--fc-ink-2); color:var(--fc-ink); }

/* The race-level readings above the trends table. */
.tt-wrap.fc .tt-trendhead{ margin:0 0 10px; padding-bottom:10px;
          border-bottom:1px solid var(--fc-hair); }

/* Reused classic markup inside a turtle sheet.

   These pages keep their Bootstrap markup by design, and a lot of it carries colours written
   for the dark classic shell -- white headings, white figures. On the light theme those land
   on a pale sheet at about 1:1. Headings and plain text take the sheet's ink; anything that
   paints its OWN ground keeps its colour, which is why buttons, badges and alerts are
   excluded rather than swept up. */
.tt-wrap.fc .tt-sheet :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6,
                          .card-title, .header-title, .text-center, .text-muted)
      :not(.btn):not(.badge):not(.alert){ color:inherit; }
.tt-wrap.fc .tt-sheet > :is(h1, h2, h3, h4, h5, h6),
.tt-wrap.fc .tt-sheet :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6,
                          .card-title, .header-title):not(.home-cta-gradient *):not(.hero-section *){
          color:var(--fc-ink); }
/* `.text-white` is markup written for the dark classic shell: it means "the thing behind
   this is dark". Inside a light sheet most of those things are no longer dark, so the ink is
   repainted -- except where the thing still paints a dark ground of its own.

   Those exceptions are a rule of their OWN below, not more `:not()`s. Every `:not(.x)` costs
   a class and this chain had reached (0,11,4), so nothing could override it and each new dark
   ground had to be added here, one report at a time: the homepage CTA, the hero, a card
   header, and then the landing pages' step markers -- near-black numerals on green circles at
   2.44:1. `:where()` costs no specificity, so this is a default anything can beat. */
.tt-wrap.fc .tt-sheet .text-white:not(:where(.btn, .badge)){ color:var(--fc-ink) !important; }

/* A ground that stays dark keeps its white ink: the ground and the ink on it decided in one
   place, so adding a ground is one edit rather than two.

   `.bg-warning` is deliberately absent -- Bootstrap's yellow is a LIGHT ground, so white on it
   fails and the dark ink above is the right answer. `.alert` is excluded because this sheet
   repaints every alert's ground to `--fc-inset`, which follows the theme: white ink there
   would be white on a pale panel. */
.tt-wrap.fc .tt-sheet :is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-info,
                          .bg-dark, .card-header):not(.alert).text-white,
.tt-wrap.fc .tt-sheet :is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-info,
                          .bg-dark, .card-header):not(.alert) .text-white{ color:#ffffff !important; }
/* Headings on those same grounds. The heading rule above repaints h1-h6 and `.card-title` to
   the sheet ink wherever they appear, which on a ground that stays dark is the same defect a
   line up: the summary panel's "1:25 GOODWOOD" was near-black on green at 2.44:1 -- read as
   "green on black" (Kenny, 30 Aug 2026). Third family after links and `.text-white`, and the
   last of the three that had its own idea about ink. */
.tt-wrap.fc .tt-sheet :is(.bg-primary, .bg-secondary, .bg-success, .bg-danger, .bg-info,
                          .bg-dark, .card-header):not(.alert)
      :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, .card-title, .header-title){
          color:#ffffff !important; }

/* A Bootstrap card-header inside a sheet paints its own ground from the classic palette. */
.tt-wrap.fc .tt-sheet .card-header{ background:var(--fc-thead); color:#ffffff; }
.tt-wrap.fc .tt-sheet .card-header :is(h1,h2,h3,h4,h5,h6,.card-title){ color:#ffffff; }

/* Bootstrap's indigo `.display-*` figures land on the turtle sheet's own dark ground at
   about 2:1. The accent is what this theme uses for a number worth looking at. */
.tt-wrap.fc .tt-sheet :is(.display-1, .display-2, .display-3,
                          .display-4, .display-5, .display-6){ color:var(--fc-accent); }

/* The homepage's marketing sections, in the theme's own colours.

   They ship with a blue gradient (#1e3a5f -> #2563eb -> #6366f1) and indigo step circles
   from the classic design, which is the clash: a blue hero above a green card. Given a
   turtle ground, their white text is correct again and nothing needs repainting. */
.tt-wrap.fc .home-cta-gradient{
          background:linear-gradient(135deg, var(--fc-thead) 0%, #1c6b33 55%,
                                     color-mix(in srgb, var(--fc-accent) 55%, #0e3b21) 100%); }
/* !important because a section that paints its OWN dark ground owns the text on it, and the
   generic sheet rules are more specific than any sane exception selector -- `:not(.x *)`
   carries the specificity of `.x *`, so excluding a section makes the generic rule WIN. */
.tt-wrap.fc .home-cta-gradient :is(h1,h2,h3,h4,h5,h6,p,.lead,.text-white){ color:#ffffff !important; }
.tt-wrap.fc .home-cta-gradient .text-white-50{ color:rgba(255,255,255,.82) !important; }
/* The hero's ::after gradient is positioned `top:-400px` -- decoration ABOVE the section,
   not its background. The hero itself sits on the page's own light ground, so its text takes
   the sheet's INK. Painting it white, as the CTA needs, put "Study Horse Racing Form" white
   on white and is exactly the invisible text Kenny reported. */
.tt-wrap.fc .hero-section::after{
          background-image:linear-gradient(to bottom, var(--fc-thead), #1c6b33) !important; }
.tt-wrap.fc .hero-section :is(h1,h2,h3,h4,.display-4,.display-6,.lead,.text-white){
          color:var(--fc-ink) !important; }
.tt-wrap.fc .hero-section :is(.text-white-50,.text-muted){ color:var(--fc-ink-2) !important; }
/* The step circles and card accents, off the classic indigo/amber palette. */
.tt-wrap.fc .home-step-circle.step-1{ background:var(--fc-thead); }
.tt-wrap.fc .home-step-circle.step-2{ background:#1c6b33; }
.tt-wrap.fc .home-step-circle.step-3{ background:color-mix(in srgb, var(--fc-accent) 70%, #0e3b21); }
.tt-wrap.fc .home-learn-card.accent-blue{ border-top-color:var(--fc-thead); }
.tt-wrap.fc .home-learn-card.accent-green{ border-top-color:#1c6b33; }
.tt-wrap.fc .home-learn-card.accent-orange{ border-top-color:var(--fc-accent); }

/* Bootstrap's `.bg-primary` is Hyper's indigo (#727cf5) -- an indigo band across the top of a
   green sheet, which is the clash in Summary Statistics and anywhere else a reused fragment
   uses it. It takes the theme's table-head green, and its badges follow. */
.tt-wrap.fc .tt-sheet .bg-primary{ background-color:var(--fc-thead) !important; color:#ffffff; }
.tt-wrap.fc .tt-sheet .bg-primary :is(h1,h2,h3,h4,h5,h6,span,div,p){ color:#ffffff; }
.tt-wrap.fc .tt-sheet .bg-primary .badge{ background-color:rgba(255,255,255,.16) !important;
          color:#ffffff !important; border:1px solid rgba(255,255,255,.28); }

/* The notebook is the one row action whose icon says least -- an address book means nothing
   until you have been told. It carries its word; the label follows the tag's own icon state
   the way the heart and bin labels do. */
.tt-wrap.fc .tt-actcell .tt-a-note{ flex-direction:column; gap:0; }
.tt-wrap.fc .tt-actcell .tt-a-note .tt-actlbl{
          font-size:max(9px, calc(9.5px * var(--fc-scale))); line-height:1.1;
          color:var(--fc-ink-3); }
.tt-wrap.fc .tt-a-note:has(.fas.fa-address-book) .tt-off,
.tt-wrap.fc .tt-a-note:has(.far.fa-address-book) .tt-on{ display:none; }

/* Run Quality carries 36 columns and Lifetime Runs 25, and they overflowed their pane at
   every width. The two widest are the jockey and trainer names, which do not wrap -- they
   take 230px between them for text that reads perfectly well on two lines. Wrapping those
   and tightening the type is what makes the table fit; the alternative, truncating names,
   is not something this project does. */
.tt-wrap.fc .tt-formfull table.dataTable{
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-formfull table.dataTable > tbody > tr > td{ white-space:normal; }
.tt-wrap.fc .tt-formfull table.dataTable > thead > tr > th{ white-space:normal;
          vertical-align:bottom; }
/* The date stays on one line -- it is the column the reader scans down. */
.tt-wrap.fc .tt-formfull table.dataTable > tbody > tr > td:first-child{ white-space:nowrap; }

/* The last 6px. The tables sit in a Bootstrap `.card.p-1` whose 6px of horizontal padding is
   the whole of the remaining overflow -- the table is 1370 in a 1358 pane, and the card
   scrolls by exactly 6. Dropping the padding for these two tables reclaims 12 and the card
   stops scrolling. The border stays; only the inside gutter goes. */
.tt-wrap.fc .tt-formfull .card{ padding-left:0 !important; padding-right:0 !important; }

/* ---- Bootstrap ground classes inside the turtle shell -------------------------------------
   `bg-white`, `bg-light` and `bg-light-lighten` are written for a white page. On a themed
   ground they paint a slab of the wrong colour and everything on them keeps the ink chosen
   for white -- on the home page that measured 1.04:1, which is text nobody can read. The
   .tt-sheet rules above are more specific and still win where they apply. */
.tt-wrap.fc .bg-white,
.tt-wrap.fc .bg-light,
.tt-wrap.fc .bg-light-lighten{ background:var(--fc-surface) !important; color:var(--fc-ink); }
.tt-wrap.fc h1, .tt-wrap.fc h2, .tt-wrap.fc h3,
.tt-wrap.fc h4, .tt-wrap.fc h5, .tt-wrap.fc h6{ color:var(--fc-ink); }
.tt-wrap.fc .text-muted{ color:var(--fc-ink-2) !important; }

/* The home page's four headline figures carry inline hex chosen against white -- indigo, sky,
   emerald and amber, which read at 1.9:1 and 2.5:1 on this ground. Inline styles need the
   override to be !important. */
.tt-wrap.fc .bt-statband .display-6{ color:var(--fc-accent) !important; }
.tt-wrap.fc .bt-other-access .btn i,
.tt-wrap.fc .bt-statband i{ color:var(--fc-accent) !important; }

/* betturtle-base paints this section with a gradient and switches it on
   html[data-bs-theme="dark"]. The turtle theme switches on data-fc-theme, so the LIGHT
   gradient stayed under turtle's light ink in dark mode -- 1.04:1. A flat token instead: a
   gradient ground also defeats a contrast audit, which samples one colour. */
.tt-wrap.fc .bt-other-access{ background:var(--fc-band-bg) !important; }
.tt-wrap.fc .bt-other-access h3{ color:var(--fc-ink) !important; }
.tt-wrap.fc .bt-other-access p,
.tt-wrap.fc .bt-other-access .text-muted{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .bt-other-access .btn-outline-primary{ color:var(--fc-ink) !important;
          border-color:var(--fc-line) !important; background:var(--fc-surface) !important; }
.tt-wrap.fc .bt-other-access .btn-outline-primary:hover{ border-color:var(--fc-accent) !important;
          color:var(--fc-accent) !important; }

/* A secondary figure inside a table cell is still a figure. --fc-ink-2 is a comment colour
   and reads at 2.48:1 at 12px in the systems table. */
.tt-wrap.fc small.text-muted{ color:var(--fc-ink) !important; }
/* Except in a table head, which is a dark green ground with its own ink. A comment grey there
   reads at 2.48:1. */
.tt-wrap.fc thead .text-muted,
.tt-wrap.fc thead small.text-muted{ color:var(--fc-on-thead, #fff) !important; }

/* DataTables wraps the heading in span.dt-column-title, which outranks the generic muted rule. */
.tt-wrap.fc table.dataTable thead th span.dt-column-title small.text-muted,
.tt-wrap.fc table.dataTable thead th span.dt-column-title .text-muted{
          color:var(--fc-on-thead, #ffffff) !important; }

/* The race-analysis chip carries the pace line as a subtitle. It is a sentence, and on a race
   with a lot to say it pushed the bar wide; one line, clipped. */
.tt-wrap.fc .tt-brief-chip em{ display:inline-block; max-width:34ch; overflow:hidden;
          text-overflow:ellipsis; white-space:nowrap; vertical-align:bottom; }
/* Which six runs the three rating lines are. */
.tt-wrap.fc .tt-sixnote{ margin:0 0 6px; color:var(--fc-ink-2);
          font-size:max(11px, calc(11.5px * var(--fc-scale))); }

/* The race-level figures under the analysis: betting rating, previous runnings, favourite
   strike rate and the winners' rating range. */
.tt-wrap.fc .tt-racefacts{ list-style:none; margin:10px 0 0; padding:0; display:flex;
          flex-wrap:wrap; gap:6px 18px; }
.tt-wrap.fc .tt-racefacts li{ display:flex; align-items:baseline; gap:6px; }
.tt-wrap.fc .tt-racefacts span{ color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-racefacts b{ color:var(--fc-ink); font-weight:600;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-racefacts b i{ margin-right:4px; }

/* The 14-day record opens the form line, so it has to look pressable. */
.tt-wrap.fc .tt-d14{ cursor:pointer; text-decoration:none;
          border-bottom:1px dotted currentColor; }

/* Run Quality carries the most columns of any table on the card and is the one that has to
   fit. The tighter cell padding is scoped to it alone -- Lifetime Runs keeps the density it
   has always had. */
.tt-wrap.fc .tt-formfull table.formpluslist > tbody > tr > td,
.tt-wrap.fc .tt-formfull table.formpluslist > thead > tr > th{
          padding-left:3px !important; padding-right:3px !important; }

/* ---- Meeting strip: race times carrying their standing ------------------------------------
   The classic time button colours on drtitleclass and badges the betting rating; the turtle
   pill carried neither, so every race looked alike and a finished one looked live. */
.tt-wrap.fc .tt-nav-next{ display:flex; flex-wrap:wrap; align-items:center; gap:6px;
          margin:6px 0; }
.tt-wrap.fc .tt-nav-next > span{ color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
/* Off next carries the time, the course and the marks, so it needs room the meeting strip's
   pills do not: the time and its icons on one line, the course underneath. Without the width
   the icons pushed the course out and the pill read as a bare time. */
.tt-wrap.fc .tt-nav-next .tt-time-pill{ display:inline-flex; flex-wrap:wrap;
          align-items:baseline; justify-content:center; gap:0 4px;
          min-width:6.6rem; line-height:1.2; padding:4px 9px; text-align:center; }
/* currentColor, not --fc-ink-2: the pill has its own ground, and the comment ink read at
   1.34:1 on it in dark. The course name is the smaller half of the pill, not a lesser one. */
.tt-wrap.fc .tt-pill-course{ flex:0 0 100%; font-style:normal; color:currentColor;
          opacity:.9; font-weight:600;
          font-size:max(10px, calc(10.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-time-pill i{ margin-left:5px; font-size:.85em; }
.tt-wrap.fc .tt-time-pill.is-done{ opacity:.45; }
/* The six bands the classic time button colours on, and the key names: GRP 1, GRP 2, GRP 3,
   LST, HCP, OTHER. Every one carries white ink and was measured against it — 5.67:1 at the
   weakest (GRP 3) — because a coloured pill is the only thing distinguishing a Group race
   from a seller at a glance, and it has to survive both themes. */
/* The six bands from the key: GRP 1, GRP 2, GRP 3, LST, HCP, OTHER.
   COLOUR SAYS ONE THING — which band the race is in — and the ink is decided by the band it
   sits on, not by what the icon means: five dark bands carry white, OTHER is white and carries
   black. Four icon colours that changed with the pill underneath them were the inconsistency,
   not the bands.

   Each band is the LIGHTEST version of its hue that still holds white text, so the hue stays
   recognisable: 4.91:1 at the weakest (GRP 2). */
.tt-wrap.fc .tt-time-pill.tt-tier-g1{ --tt-ink:#fff; --tt-band:#544AC0; background:#544AC0; border-color:#4F46B8; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-g2{ --tt-ink:#fff; --tt-band:#966800; background:#966800; border-color:#8A5500; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-g3{ --tt-ink:#fff; --tt-band:#24768F; background:#24768F; border-color:#1F6F8B; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-lst{ --tt-ink:#fff; --tt-band:#B41C40; background:#B41C40; border-color:#A81238; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-hcp{ --tt-ink:#fff; --tt-band:#1A7A4F; background:#1A7A4F; border-color:#166542; color:#fff !important; }
.tt-wrap.fc .tt-time-pill.tt-tier-oth{ --tt-ink:#10261a; --tt-band:#c3ccd2; background:#ffffff; border-color:#c3ccd2; color:#10261a !important; }
/* The same six in both themes: a band carries its own ground, so a race's standing does not
   change colour with the theme. */

/* Mono-tone: every glyph takes the ink of the band it is on. `i` alone missed them — the
   classic markup is <span class="fa …"> — which is why seven inks survived the first attempt. */
.tt-wrap.fc .tt-time-pill i[class],
.tt-wrap.fc .tt-time-pill span[class],
.tt-wrap.fc .tt-time-pill .tt-pill-rate,
.tt-wrap.fc .tt-time-pill .tt-pill-marks i{ color:inherit !important; }

/* The race being read is marked by an OUTLINE, not by repainting it: the older is-now rule
   forced the accent ink, which landed light-on-light over a band colour at 2.05:1. The band
   keeps its own ground and ink; the outline says "you are here". */
.tt-wrap.fc .tt-time-pill.is-now{ outline:2px solid var(--fc-accent); outline-offset:1px; }
/* The rating keeps its colour -- shape alone is harder to tell apart at this size -- but
   Bootstrap's text-success is a green thumb on a green band. These are the same three
   meanings in inks measured against every band: 3.47:1 at the worst (poor on GRP 3), and the
   dark set for the light OTHER band. !important because the utilities carry it. */
/* The customer's own marks take the band's ink: they are one meaning each, told apart by
   glyph, and a fourth colour scale on a 20px pill would be noise. */
.tt-wrap.fc .tt-time-pill .tt-pill-marks i{ color:inherit !important; }
/* "You have been here", counted. One dot instead of four glyphs: which of shortlist, notes,
   comments or systems you used is not the question while scanning a day's racing. */
/* Outlined, not filled: the ring and the numeral both take the band's ink, which is the one
   ink already measured against that ground -- a filled dot would need the numeral in the
   band's own colour and six more rules to say so. */
.tt-wrap.fc .tt-pill-mine{ display:inline-flex; align-items:center; justify-content:center;
          min-width:16px; height:16px; margin-left:5px; padding:0 3px; border-radius:999px;
          border:1px solid currentColor; color:inherit;
          font-size:max(9px, calc(10px * var(--fc-scale))); font-weight:700; line-height:1; }

/* The key. Named because six colours nobody can look up are decoration. */
.tt-wrap.fc .tt-rf-group .tt-timekey{ margin-top:6px; flex-wrap:wrap; }
.tt-wrap.fc .tt-timekey{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px;
          margin:8px 0 2px; }
.tt-wrap.fc .tt-timekey b{ color:var(--fc-ink-2); font-weight:600;
          font-size:max(10px, calc(11px * var(--fc-scale))); }
.tt-wrap.fc .tt-timekey span{ padding:1px 10px; border-radius:999px; color:#fff;
          font-size:max(10px, calc(10.5px * var(--fc-scale))); font-weight:700; }
/* The key shows the bands as the times show them. */
.tt-wrap.fc .tt-timekey span{ color:#fff !important; }
.tt-wrap.fc .tt-timekey .k-g1{ background:#544AC0; }
.tt-wrap.fc .tt-timekey .k-g2{ background:#966800; }
.tt-wrap.fc .tt-timekey .k-g3{ background:#24768F; }
.tt-wrap.fc .tt-timekey .k-lst{ background:#B41C40; }
.tt-wrap.fc .tt-timekey .k-hcp{ background:#1A7A4F; }
.tt-wrap.fc .tt-timekey .k-oth{ background:#ffffff; color:#10261a !important;
          border:1px solid #c3ccd2; }
.tt-wrap.fc .tt-timekey em{ font-style:normal; color:var(--fc-ink-2); display:inline-flex;
          align-items:center; gap:4px; font-size:max(10px, calc(11px * var(--fc-scale))); }
/* The key shows the glyphs in the inks the pill uses, on a swatch of a band, so it describes
   what is actually on screen. */
.tt-wrap.fc .tt-timekey em i{ color:var(--fc-ink-2) !important; }

/* A block, not the flex row an earlier rule made it: as a flex container the <details>
   laid its summary and the meetings out as siblings in a row, which is why the label sat at
   the vertical middle of the list.
   And the collapse is stated rather than inherited: every child here sets its own display
   (the meeting rows are flex, the colour key is flex), and a child with an author display
   escapes the UA's hiding — so "Other meetings (6)" was showing all six meetings while
   closed, and the colour key with them. */
.tt-wrap.fc .tt-nav-other{ display:block; margin-top:6px; }
.tt-wrap.fc .tt-nav-other:not([open]) > *:not(summary){ display:none !important; }
.tt-wrap.fc .tt-nav-other > summary{ cursor:pointer; color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); padding:4px 0; }
.tt-wrap.fc .tt-nav-meet{ display:flex; flex-wrap:wrap; align-items:center; gap:5px;
          padding:4px 0; border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-nav-meetname{ min-width:9rem; color:var(--fc-ink);
          font-size:max(11px, calc(12px * var(--fc-scale))); font-weight:600; }

/* Previous winners of the named race. A dense record, so it scrolls inside its own box
   rather than widening the panel. */
.tt-wrap.fc .tt-rp-winners{ overflow-x:auto; margin:6px 0 10px; }
.tt-wrap.fc .tt-rp-wintable{ width:100%; border-collapse:collapse;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-rp-wintable th{ text-align:left; padding:4px 8px 4px 0; white-space:nowrap;
          color:var(--fc-ink-2); font-weight:600; border-bottom:1px solid var(--fc-line); }
.tt-wrap.fc .tt-rp-wintable td{ padding:4px 8px 4px 0; white-space:nowrap;
          color:var(--fc-ink); border-bottom:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-rp-wintable tbody tr:last-child td{ border-bottom:0; }
.tt-wrap.fc .tt-rp-wintable a{ color:var(--fc-accent); }

/* ---- Blog ---------------------------------------------------------------------------------
   The blog's own stylesheet is written for a white page: headings, tag pills, the category
   badge and the sidebar carry inks chosen against it, which read at 1.0:1 inside the turtle
   shell. Scoped through body.bt-blog so it reaches the sidebar as well as the article -- the
   sheet wrapper covers only the entry itself -- and so the classic blog is untouched. */
body.bt-blog .tt-wrap.fc :is(h1, h2, h3, h4, h5, h6){ color:var(--fc-ink) !important; }
body.bt-blog .tt-wrap.fc :is(p, li, dd, dt, blockquote, td, th, figcaption, div.small,
          span:not([class])){ color:var(--fc-ink); }
body.bt-blog .tt-wrap.fc :is(.text-muted, small, .bt-author-desc, .reading-time,
          .endless_separator, .breadcrumb-item, .breadcrumb-item a, .bt-related-meta,
          .bt-related-meta span){
          color:var(--fc-ink-2) !important; }
body.bt-blog .tt-wrap.fc a:not(.btn):not(.blog-cat-badge):not(.blog-tag-pill){
          color:var(--fc-accent) !important; }
body.bt-blog .tt-wrap.fc .bt-author-name{ color:var(--fc-ink) !important; }
/* The category badge carries a per-category Bootstrap ground (cyan for Learn, and so on)
   under whichever ink wins -- accent green on cyan measured 3.01:1. One treatment for both
   the link and the plain-span form: the accent on the sheet's own surface, which is the pair
   the palette is built around. The attribute selector is there for the specificity. */
body.bt-blog .tt-wrap.fc a[class*="blog-cat-"],
body.bt-blog .tt-wrap.fc span[class*="blog-cat-"]{
          background:var(--fc-surface) !important; color:var(--fc-accent) !important;
          border:1px solid var(--fc-line) !important; }
/* The category badge and tag pill are NOT restyled: the blog gives each category its own
   coloured ground with white text, and overriding the ground put white on white. Their own
   colours read on either theme because the badge carries its own ground. */
body.bt-blog .tt-wrap.fc :is(.card, .bt-author, .entry-card, aside, .sidebar){
          background:var(--fc-inset) !important; border-color:var(--fc-line) !important; }
body.bt-blog .tt-wrap.fc :is(code, pre){ background:var(--fc-well) !important;
          color:var(--fc-ink) !important; }
body.bt-blog .tt-wrap.fc hr{ border-color:var(--fc-line); }

/* The KEY column carries up to three performance icons. They were wrapping to a second line,
   which took every row from 48px to 69px and made the two run tables a third taller than the
   data needs. KEY is the second column in both templates. */
.tt-wrap.fc .tt-formfull table.formlist > tbody > tr > td:nth-child(2),
.tt-wrap.fc .tt-formfull table.formpluslist > tbody > tr > td:nth-child(2){
          white-space:nowrap !important; }
.tt-wrap.fc .tt-formfull table.formlist > tbody > tr > td:nth-child(2) > *,
.tt-wrap.fc .tt-formfull table.formpluslist > tbody > tr > td:nth-child(2) > *{
          display:inline-block; }

/* ---- Popover CONTENT ----------------------------------------------------------------------
   The race-date and chequered-flag popovers fetch their body from the report and form-summary
   APIs, and that fragment is plain Bootstrap: bg-primary section headers, bg-info / bg-success
   badges, bg-white panels, text-dark. The shell is themed by `tt-pop`, so the frame was right
   and everything inside it was still the classic card -- which is what "using the classic
   styling" looked like.

   Scoped to `.tt-pop`, added only when the turtle shell is present, so the classic popovers
   are untouched. */
.tt-pop .popover-body :is(.bg-primary, .bg-secondary, .bg-dark){
          background:var(--fc-thead) !important; color:var(--fc-on-thead, #ffffff) !important; }
/* No descendant ink rule here: a .bg-white panel nested inside the band would inherit the
   band's white and land at 1.12:1. Colour inherits from the band on its own, and the light
   grounds below re-assert their own ink. */
.tt-pop .popover-body :is(.bg-white, .bg-light, .bg-body, .bg-body-tertiary),
.tt-pop .popover-body :is(.bg-primary, .bg-secondary, .bg-dark) :is(.bg-white, .bg-light){
          background:var(--fc-inset) !important; color:var(--fc-ink) !important; }
.tt-pop .popover-body :is(.text-dark, .text-body, .fw-bold){ color:var(--fc-ink) !important; }
/* The runner the popover was opened FROM. `report.html` marks its name `fw-bold text-success`,
   and the rule above -- later, same specificity -- turned that into plain bold white, so the
   horse being asked about read like every other line (Kenny, 2 Sep). The name takes the value
   green again and the whole line takes a tint and a rule down its edge, because the line is
   what a reader is scanning for, not the name on its own. */
/* `--fc-badge-g`, not `--fc-val-g`: the name sits on the tint below, where the value green
   measured 4.44:1 in light. The badge pair is the one tuned for ink ON a tint. */
.tt-pop .popover-body :is(.text-body-secondary, .text-secondary, .text-muted){
          color:var(--fc-ink-2) !important; }
.tt-pop .popover-body .border-primary{ border-color:var(--fc-accent) !important; }
.tt-pop .popover-body :is(.border, .border-start, .border-end, .border-top, .border-bottom){
          border-color:var(--fc-line) !important; }
/* One treatment for every badge in here, using the chip pair the palette defines. Mapping
   each Bootstrap colour to a token of the same NAME is what produced lime on lime (1.65:1)
   and dark ink on dark green (1.92:1): those pairs are built for other grounds. Semantic
   colour is not worth an unreadable badge in a popover this small. */
.tt-pop .popover-body .badge,
.tt-pop .popover-body .badge[class*="bg-"],
.tt-pop .popover-body span.badge[class*="bg-"]{ background:var(--fc-chip-bg) !important;
          color:var(--fc-chip-ink) !important;
          border:1px solid var(--fc-chip-line, var(--fc-line)) !important; }
.tt-pop .popover-body :is(td, th, tr){ border-color:var(--fc-hair) !important; }
/* The body ink is a comment grey, which is right for a sentence and wrong for a table of
   figures -- every plain cell measured 4.2:1. No !important, so a cell that carries its own
   semantic colour keeps it. */
.tt-pop .popover-body :is(table, td, th){ color:var(--fc-ink); }

/* ---- Filter panel: two screens made navigable -------------------------------------------
   43 fieldsets in a flat column ran to 1,872px — two full screens — with Apply, Reset and the
   only way out at the far end of it. */
.tt-wrap.fc .tt-filterbar{ position:sticky; top:0; z-index:5; display:flex; flex-wrap:wrap;
          align-items:center; gap:8px; margin:0 0 8px; padding:8px 10px;
          background:var(--fc-thead); color:var(--fc-on-thead, #fff);
          border-radius:8px 8px 0 0; }
.tt-wrap.fc .tt-filterbar > b{ font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-filterbar-hint{ margin-right:auto; opacity:.85;
          font-size:max(10px, calc(11px * var(--fc-scale))); }
.tt-wrap.fc .tt-filterbar .tt-tool{ background:var(--fc-surface); color:var(--fc-ink);
          border:1px solid var(--fc-line); }
.tt-wrap.fc .tt-filterbar .tt-tool.is-go{ background:var(--fc-accent);
          color:var(--fc-accent-ink); border-color:var(--fc-accent); }

/* The fieldsets flow into columns instead of one long list, so the whole set is roughly one
   screen. Each fieldset stacks its own label above its controls, because Bootstrap's col-md-2
   legend is sized from the VIEWPORT, not from the column it lands in, and would otherwise be
   squeezed to a sliver. */
@media (min-width: 1100px) {
  .tt-wrap.fc .tt-filterpanel form > div.mb-2{
            column-count:3; column-gap:22px; }
  .tt-wrap.fc .tt-filterpanel form > div.mb-2 > fieldset{
            break-inside:avoid; page-break-inside:avoid; display:block;
            margin:0 0 10px; padding:0 0 8px;
            border-bottom:1px solid var(--fc-hair); }
  .tt-wrap.fc .tt-filterpanel form > div.mb-2 > fieldset > .row{ display:block; margin:0; }
  .tt-wrap.fc .tt-filterpanel form > div.mb-2 > fieldset legend{
            width:100%; max-width:100%; flex:none; padding:0 0 2px;
            font-weight:600; color:var(--fc-ink);
            font-size:max(11px, calc(12px * var(--fc-scale))); }
  .tt-wrap.fc .tt-filterpanel form > div.mb-2 > fieldset > .row > div{
            width:100%; max-width:100%; flex:none; padding:0; }
}
@media (min-width: 1500px) {
  .tt-wrap.fc .tt-filterpanel form > div.mb-2{ column-count:4; }
}

/* ---- Filter panel: two ways to narrow the card, and only one applies -----------------------
   The panel ran the system chooser straight into the 43 racecard fieldsets with nothing
   between them but a red status line, so it read as one long form. They are alternatives:
   `card_filter` skips the racecard filters entirely while a system is set. */
.tt-wrap.fc .tt-filtersect{ border:1px solid var(--fc-line); border-radius:8px;
          padding:10px 12px; margin:0 0 14px; background:var(--fc-surface); }
.tt-wrap.fc .tt-filtersect + .tt-filtersect{ margin-top:16px; }
/* No glyph: a section heading is not a runner marker, and the icon legend explains only
   markers -- borrowing one for decoration puts an unexplained symbol inside .tt-card. */
.tt-wrap.fc .tt-filtersect-h{ display:flex; align-items:center; gap:8px; margin:0 0 2px;
          color:var(--fc-ink); font-weight:700;
          font-size:max(13px, calc(14.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-filtersect-note{ margin:0 0 10px; color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
/* The section actually deciding the runners is the one to look at. */
.tt-wrap.fc .tt-filtersect.is-live{ border-color:var(--fc-accent);
          box-shadow:inset 3px 0 0 var(--fc-accent); }
.tt-wrap.fc .tt-filtersect-tag{ margin-left:auto; padding:1px 8px; border-radius:999px;
          background:var(--fc-accent); color:var(--fc-accent-ink); font-weight:700;
          font-size:max(10px, calc(11px * var(--fc-scale))); text-transform:uppercase; }
/* NOT dimmed. Fading the inactive section to .62 put its strongest ink at 4.62:1 and anything
   secondary inside it well below AA -- and opacity is invisible to the contrast audit, so it
   would have shipped unmeasured. The heading says "Not in use" and the live section carries
   the accent rail; that is signal enough without spending legibility on it. */
.tt-wrap.fc .tt-filtersect.is-muted{ border-style:dashed; }
/* The classic red status line duplicates the note above it. */
.tt-wrap.fc .tt-filtersect #filterp{ display:none; }

/* The 14 day form line under a trainer or jockey. Collapsed by default: there are two per
   runner and the record above them is the summary. */
.tt-wrap.fc .tt-formline{ margin:6px 0 0; border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-formline > summary{ cursor:pointer; list-style:none; padding:6px 0;
          color:var(--fc-accent); font-weight:600;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-formline > summary::-webkit-details-marker{ display:none; }
.tt-wrap.fc .tt-formline > summary::after{ content:" \25BE"; }
.tt-wrap.fc .tt-formline[open] > summary::after{ content:" \25B4"; }
.tt-wrap.fc .tt-formline-body{ padding:0 0 8px; overflow-x:auto; }
/* The form line is wider than a phone. `overflow-x` only scrolls a box that is allowed
   to be narrower than its content: a grid or flex child defaults to `min-width:auto` and
   grows to fit instead, taking the page sideways with it. */
.tt-wrap.fc .tt-person{ min-width:0; }
.tt-wrap.fc .tt-formline, .tt-wrap.fc .tt-formline > summary{ min-width:0; }
/* The fetched strip is a Bootstrap card written for a white page. */
.tt-wrap.fc .tt-formline-body .card{ background:transparent !important; border:0 !important; }
.tt-wrap.fc .tt-formline-body .card-title{ display:none; }
.tt-wrap.fc .tt-formline-body .card-widgets{ display:none; }
.tt-wrap.fc .tt-formline-body .collapse{ display:block !important; }
.tt-wrap.fc .tt-formline-body :is(.text-muted, small){ color:var(--fc-ink-2) !important; }
/* Its TABLE is written for a white page too, and the card rule above does not reach it:
   Bootstrap paints the cells from its own `--bs-table-*` variables, so in dark mode the
   strip was a white sheet under dark headings. The variables are set rather than the cells
   painted, so striping and hover still work -- they just work in this theme's colours. */
.tt-wrap.fc .tt-formline-body .table{
          --bs-table-bg:transparent; --bs-table-color:var(--fc-ink);
          --bs-table-striped-bg:var(--fc-surface-2); --bs-table-striped-color:var(--fc-ink);
          --bs-table-hover-bg:var(--fc-inset); --bs-table-hover-color:var(--fc-ink);
          --bs-table-border-color:var(--fc-hair);
          background:transparent; color:var(--fc-ink); }
.tt-wrap.fc .tt-formline-body .table > :not(caption) > * > *{
          background-color:transparent; color:inherit;
          border-color:var(--fc-hair); box-shadow:none; }
.tt-wrap.fc .tt-formline-body .table > thead > tr > th{ color:var(--fc-ink-2); }

/* Today's racing: the filter that replaced the icons. */
.tt-wrap.fc .tt-racefilter{ margin:10px 0; border:1px solid var(--fc-line); border-radius:8px;
          background:var(--fc-surface); }
.tt-wrap.fc .tt-racefilter > summary{ cursor:pointer; padding:8px 12px; color:var(--fc-ink);
          font-weight:600; font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-racefilter > summary span{ color:var(--fc-ink-2); font-weight:400; }
.tt-wrap.fc .tt-rf-body{ display:flex; flex-wrap:wrap; gap:14px 26px;
          padding:4px 12px 12px; border-top:1px solid var(--fc-hair); }
.tt-wrap.fc .tt-rf-group{ display:flex; flex-direction:column; gap:3px; }
.tt-wrap.fc .tt-rf-group b{ color:var(--fc-ink-2); font-weight:600;
          font-size:max(10px, calc(11px * var(--fc-scale))); text-transform:uppercase;
          letter-spacing:.03em; }
.tt-wrap.fc .tt-rf-group label{ display:flex; align-items:center; gap:6px; color:var(--fc-ink);
          font-size:max(11px, calc(12.5px * var(--fc-scale))); cursor:pointer; }

/* Day tabs on Today's Racing, and the non-runner list. */
.tt-wrap.fc .tt-daytabs{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 12px; }
.tt-wrap.fc .tt-daytab{ appearance:none; cursor:pointer; border:1px solid var(--fc-line);
          background:var(--fc-surface); color:var(--fc-ink); border-radius:7px;
          padding:6px 12px; font-weight:600;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-daytab:hover{ border-color:var(--fc-accent); }
.tt-wrap.fc .tt-daytab.is-on{ background:var(--fc-accent); border-color:var(--fc-accent);
          color:var(--fc-accent-ink); }
/* Closed by default and laid out in columns: fifty names down one column is a page of
   scrolling under a list nobody came here to scroll. */
.tt-wrap.fc .tt-nonrunners{ margin-top:18px; border:1px solid var(--fc-line);
          border-radius:8px; background:var(--fc-surface); }
.tt-wrap.fc .tt-nonrunners > summary{ cursor:pointer; padding:8px 12px; color:var(--fc-ink);
          font-weight:600; font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-nonrunners > summary span{ color:var(--fc-ink-2); font-weight:400; }
/* A grid, not CSS columns: columns flowed one meeting into the bottom of one column and the
   top of the next, leaving a short block stranded beside a tall one. A meeting is a unit. */
.tt-wrap.fc .tt-nr-body{ padding:8px 12px 12px; border-top:1px solid var(--fc-hair);
          display:grid; grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));
          gap:12px 24px; align-items:start; }
/* No rule under each meeting: in a grid those read as stray lines of different lengths.
   The heading and the gap separate them. */
.tt-wrap.fc .tt-nr-meeting{ padding:0; }
.tt-wrap.fc .tt-nr-course{ display:block; color:var(--fc-ink); font-weight:700;
          padding-bottom:3px; margin-bottom:3px; border-bottom:1px solid var(--fc-hair);
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-nr-row{ display:flex; gap:10px; align-items:baseline; padding:2px 0; }
/* !important like every other turtle link rule: the classic sheet's
   html[data-bs-theme="dark"] a:not(.btn):not(.nav-link):not(.dropdown-item) is (0,4,2) and
   beat this on specificity, so the times rendered in the classic link blue. */
.tt-wrap.fc .tt-nr-time{ color:var(--fc-accent) !important; font-weight:600;
          text-decoration:none !important; font-variant-numeric:tabular-nums;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-nr-time:hover{ text-decoration:underline !important; }
.tt-wrap.fc .tt-nr-names{ color:var(--fc-ink);
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }

/* Race detail: the same time pill, with more of it showing. */
.tt-wrap.fc .tt-daybar{ display:flex; align-items:flex-start; justify-content:space-between;
          flex-wrap:wrap; gap:10px; margin:0 0 10px; }
.tt-wrap.fc .tt-daybar .tt-daytabs{ margin:0; border:0; padding:0; flex:1 1 auto; }
.tt-wrap.fc .tt-daybar .tt-seg{ display:flex; flex:0 0 auto; }
.tt-wrap.fc .tt-segbtn{ appearance:none; cursor:pointer; border:1px solid var(--fc-line);
          background:var(--fc-surface); color:var(--fc-ink); padding:5px 10px;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-segbtn:first-child{ border-radius:7px 0 0 7px; }
.tt-wrap.fc .tt-segbtn:last-child{ border-radius:0 7px 7px 0; margin-left:-1px; }
.tt-wrap.fc .tt-segbtn[aria-pressed="true"]{ background:var(--fc-accent);
          border-color:var(--fc-accent); color:var(--fc-accent-ink); font-weight:700; }
.tt-wrap.fc .tt-pill-detail{ display:none; }
.tt-wrap.fc .tt-meet.is-detail .tt-nav-times{ display:flex; flex-direction:column; gap:4px; }
.tt-wrap.fc .tt-meet.is-detail .tt-time-pill{ display:flex; align-items:baseline; gap:10px;
          width:100%; text-align:left; }
.tt-wrap.fc .tt-meet.is-detail .tt-pill-time{ flex:0 0 auto; font-weight:700;
          font-variant-numeric:tabular-nums; }
.tt-wrap.fc .tt-meet.is-detail .tt-pill-detail{ display:flex; flex-direction:column;
          min-width:0; gap:1px; }
/* Wraps rather than truncates: the title is the reason this density exists, and a phone is
   where it would have been cut. */
.tt-wrap.fc .tt-pill-title{ font-weight:600; white-space:normal;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
/* No opacity: the pill's ink is picked to pass against its own band colour, and dimming it
   took the meta line to 4.33:1 on every band in both themes. */
.tt-wrap.fc .tt-pill-meta{ font-weight:400;
          font-size:max(11px, calc(12px * var(--fc-scale))); }

/* Detailed rows: the band as an edge, not a flood. Six full-width colour fills down a page
   is more ink than the distinction is worth, and it made the unbanded races read as a
   different component rather than a quieter one. */
.tt-wrap.fc .tt-meet.is-detail .tt-time-pill{ background:var(--fc-surface) !important;
          color:var(--fc-ink) !important; border-color:var(--fc-line);
          border-left:4px solid var(--tt-band, var(--fc-line)); padding:7px 10px; }
.tt-wrap.fc .tt-meet.is-detail .tt-time-pill:hover{ border-color:var(--fc-accent);
          border-left-color:var(--tt-band, var(--fc-accent)); }
.tt-wrap.fc .tt-meet.is-detail .tt-time-pill.is-done{ opacity:1; }
.tt-wrap.fc .tt-meet.is-detail .tt-time-pill.is-done .tt-pill-time{ color:var(--fc-ink-2); }

/* "still to run" reads as live rather than as another fact about the day. */
.tt-wrap.fc .tt-chip.tt-chip-run{ border-color:var(--fc-accent); color:var(--fc-accent-ink);
          background:var(--fc-accent); font-weight:700; }

/* The live band sits above the controls, so it has to read as its own thing rather than as
   another row of chrome. */
.tt-wrap.fc .tt-todaynext{ display:flex; align-items:center; flex-wrap:wrap; gap:6px;
          margin:0 0 12px; padding:8px 10px; border:1px solid var(--fc-line);
          border-left:4px solid var(--fc-accent); border-radius:8px;
          background:var(--fc-surface-2, var(--fc-surface)); }
.tt-wrap.fc .tt-next-label{ color:var(--fc-ink); font-weight:700;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); margin-right:2px; }

/* Jockey changes: the same panel shape as the non-runners, since it answers the same kind
   of question about the same day. */
.tt-wrap.fc .tt-jchanges{ margin-top:10px; }
.tt-wrap.fc .tt-jc-row .tt-nr-names b{ color:var(--fc-ink); font-weight:700; }
.tt-wrap.fc .tt-jc-arrow{ color:var(--fc-ink-2); font-size:.8em; margin:0 2px; }
/* A name is not a place to wrap: the break belongs at the arrow. */
.tt-wrap.fc .tt-jc-name{ white-space:nowrap; }
.tt-wrap.fc .tt-jc-when{ color:var(--fc-ink-2); font-style:normal;
          font-size:max(10px, calc(11px * var(--fc-scale))); }

/* Jump to a course: a compact control in the day bar, sized like the day tabs. */
.tt-wrap.fc .tt-jump select{ appearance:auto; border:1px solid var(--fc-line); border-radius:7px;
          background:var(--fc-surface); color:var(--fc-ink); padding:5px 8px; max-width:200px;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-jump select:disabled{ opacity:.5; }

/* A link inside turtle content that carries no turtle class of its own -- a horse name in a
   reused classic fragment, a table cell link -- had no turtle ink, so it fell to the classic
   sheet's dark-mode blue. Legible on a dark ground and 1.8:1 on a light one, which is how a
   horse name on the card came to fail.
   Scoped to links WITHOUT a tt- class, so every rule that sets its own colour still wins,
   and specific enough (0,6,1) to beat the classic (0,4,2). */
.tt-wrap.fc a:not([class*="tt-"]):not(.btn):not(.nav-link):not(.dropdown-item){
          color:var(--fc-accent); }
.tt-wrap.fc a:not([class*="tt-"]):not(.btn):not(.nav-link):not(.dropdown-item):hover{
          color:var(--fc-ink); }

/* Top/bottom jump: out of the way until wanted, and never over the content it sits beside. */
.tt-wrap.fc .tt-updown{ position:fixed; right:18px; bottom:22px; z-index:1030;
          width:40px; height:40px; border-radius:50%; cursor:pointer;
          border:1px solid var(--fc-line); background:var(--fc-surface);
          color:var(--fc-ink) !important; opacity:.72;
          box-shadow:0 2px 8px rgba(0,0,0,.25); }
.tt-wrap.fc .tt-updown:hover,
.tt-wrap.fc .tt-updown:focus-visible{ opacity:1; border-color:var(--fc-accent);
          color:var(--fc-accent) !important; }
@media (max-width: 700px){ .tt-wrap.fc .tt-updown{ right:12px; bottom:14px;
          width:36px; height:36px; } }

/* Breadcrumbs: the way back to the day's racing, from a card or a meeting summary. */
.tt-wrap.fc .tt-crumbs{ margin:0 0 10px; }
.tt-wrap.fc .tt-crumbs ol{ display:flex; flex-wrap:wrap; align-items:center; gap:6px;
          list-style:none; margin:0; padding:0; }
.tt-wrap.fc .tt-crumbs li{ display:flex; align-items:center; gap:6px; color:var(--fc-ink-2);
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-crumbs li + li::before{ content:"/"; color:var(--fc-ink-2); opacity:.7; }
.tt-wrap.fc .tt-crumbs a{ color:var(--fc-accent) !important; text-decoration:none !important; }
.tt-wrap.fc .tt-crumbs a:hover{ text-decoration:underline !important; }
.tt-wrap.fc .tt-crumbs [aria-current="page"]{ color:var(--fc-ink); font-weight:600; }

/* Weather detail, on a press rather than a hover: a tooltip cannot be reached on a phone. */
.tt-wrap.fc .tt-chip-weather{ cursor:pointer; }
.tt-wrap.fc .tt-wx-panel{ margin:6px 0 8px; padding:8px 10px; border:1px solid var(--fc-line);
          border-left:4px solid var(--fc-accent); border-radius:8px;
          background:var(--fc-surface); }
.tt-wrap.fc .tt-wx-panel dl{ display:grid; grid-template-columns:repeat(auto-fill, minmax(170px, 1fr));
          gap:4px 20px; margin:0; }
.tt-wrap.fc .tt-wx-panel dt{ display:inline; color:var(--fc-ink-2); font-weight:600;
          font-size:max(10px, calc(11.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-wx-panel dd{ display:inline; margin:0 0 0 6px; color:var(--fc-ink);
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-wx-credit{ margin:6px 0 0; color:var(--fc-ink-2);
          font-size:max(10px, calc(11px * var(--fc-scale))); }

/* The meeting strip collapses. Stated, not inherited: its children set their own display
   (the time rows are flex), and a child with an author display escapes the UA's hiding --
   the same reason Other meetings never actually shut. */
.tt-wrap.fc details.tt-nav:not([open]) > *:not(summary){ display:none !important; }
.tt-wrap.fc details.tt-nav > summary.tt-nav-course{ cursor:pointer; }
.tt-wrap.fc details.tt-nav > summary.tt-nav-course::-webkit-details-marker{ display:none; }

/* A runner the customer binned: still on the card, sorted to the bottom, and set apart by
   its ground rather than by fading. Opacity read as "set aside" and took the whole row --
   the horse's own name included -- to 2.6:1. */
.tt-wrap.fc .tt-eighty-help{ margin:10px 0 4px; }
.tt-wrap.fc .tt-eighty-help > summary{ cursor:pointer; list-style:none; font-weight:600;
          color:var(--fc-ink-2); font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-eighty-help > summary::-webkit-details-marker{ display:none; }
.tt-wrap.fc .tt-eighty-help > summary i{ margin-right:5px; color:var(--fc-accent); }
.tt-wrap.fc .tt-eighty-help[open] > summary{ margin-bottom:6px; }
.tt-wrap.fc .tt-eighty-help p{ margin:0 0 6px; }

.tt-wrap.fc .tt-runner.is-binned{ background:var(--fc-inset);
          border-left:4px solid var(--fc-ink-3, var(--fc-line)); }
/* Colour is drained rather than the row faded, and the actions cell is left out of it so
   the bin stays findable. The horse's name and its comment keep their ink. */
.tt-wrap.fc .tt-runner.is-binned .tt-r1 > *:not(.tt-actcell){ filter:grayscale(1); }
.tt-wrap.fc .tt-runner.is-binned .tt-cell,
.tt-wrap.fc .tt-runner.is-binned .tt-rate,
.tt-wrap.fc .tt-runner.is-binned .tt-badges,
.tt-wrap.fc .tt-runner.is-binned .tt-rowchart,
.tt-wrap.fc .tt-runner.is-binned .tt-rowspark,
.tt-wrap.fc .tt-runner.is-binned .tt-odds,
.tt-wrap.fc .tt-runner.is-binned .tt-pick{ opacity:.55; }
/* The bin is the way back: red in both themes, at full strength. */
.tt-wrap.fc .tt-runner.is-binned .tt-actcell button.hide i,
.tt-wrap.fc .tt-runner.is-binned .tt-commentact.tt-a-hide i{ color:var(--fc-poor) !important; }
.tt-wrap.fc .tt-runner.is-binned .tt-actcell,
.tt-wrap.fc .tt-runner.is-binned .tt-binbtn{ opacity:1; }
/* No second label: the row already carries a "Binned" tag, revealed by the bin's own
   restore icon. Its ink only needed to pass -- it was 4.3:1 on the light ground. */
.tt-wrap.fc .tt-hidden-tag{ color:var(--fc-ink) !important; }

/* The badge family (1st Hcap, NAP, WIN TIP) keeps its colours -- they carry meaning -- but
   takes the tags' geometry and type, so a row reads as one family of markers rather than
   pills and boxes side by side. Scoped to the turtle shell: badges.html is shared with the
   classic card, which is untouched. */
.tt-wrap.fc .tt-badges .badge{ border-radius:3px !important; padding:1px 6px !important;
          font-weight:600 !important; letter-spacing:.04em;
          font-size:max(10px, calc(10px * var(--fc-scale))) !important;
          line-height:1.35 !important; text-transform:uppercase; }

/* Unicons is stripped from the turtle stylesheet (see build_turtle_css), so any uil- glyph
   left in shared markup has no font behind it and paints as a missing-character box. The
   only thing preventing that was .bt-icon-ghost in another stylesheet -- one stale cache and
   a green block appears beside HOME. Neutralised here as well, so it cannot come back. */
.tt-wrap.fc [class*="uil-"]::before{ content:"" !important; }

/* The band's ink, at a specificity that survives a page whose own link colour is !important:
   on the home page the site link green beat the tier rules and painted 1:53 green on blue.
   One selector, the ink named by the band itself. */
.tt-wrap.fc a.tt-time-pill[class*="tt-tier-"]{ color:var(--tt-ink, #fff) !important; }

/* A marker never breaks inside a word. "SOLE RUNNER" wrapped to "SOLE RUNNE / R", which is
   the sort of thing that reads as broken rather than as tight. The same for a horse's name
   and for the people: a name is one thing, so it wraps between words or not at all. */
.tt-wrap.fc .tt-tag,
.tt-wrap.fc .tt-badges .badge,
.tt-wrap.fc .tt-chip{ overflow-wrap:normal; word-break:keep-all; hyphens:none; }
.tt-wrap.fc .tt-badges .badge{ white-space:nowrap; }
.tt-wrap.fc .tt-name,
.tt-wrap.fc .tt-person a,
.tt-wrap.fc .tt-person{ overflow-wrap:normal; word-break:keep-all; hyphens:none; }

/* The rest of the day on the home page. The collapse is stated, not inherited: the meeting
   rows set their own display and a child with an author display escapes the UA's hiding. */
.tt-wrap.fc .tt-homeday{ margin-top:12px; }
.tt-wrap.fc .tt-homeday > summary{ cursor:pointer; color:var(--fc-ink); font-weight:600;
          padding:8px 0; font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-homeday > summary span{ color:var(--fc-ink-2); font-weight:400; }
.tt-wrap.fc .tt-homeday:not([open]) > *:not(summary){ display:none !important; }

/* The hero's next-races strip, in theme tokens. index.html is a classic template rendered
   inside the turtle shell, so anything it styles for a dark hero has to be restated here. */
.tt-wrap.fc .hero-next-label{ color:var(--fc-ink-2); opacity:1; }
.tt-wrap.fc .hero-next-time{ color:var(--fc-ink) !important; background:var(--fc-surface);
          border:1px solid var(--fc-line); }
.tt-wrap.fc .hero-next-time b{ color:var(--fc-ink); }
.tt-wrap.fc .hero-next-time span{ color:var(--fc-ink-2); opacity:1; }
.tt-wrap.fc .hero-next-time:hover{ border-color:var(--fc-accent); background:var(--fc-inset); }

/* The member home in theme tokens: it is a classic template inside the turtle shell, so its
   muted inks have to be restated or they stay at the light-theme values on a dark ground. */
.tt-wrap.fc .member-home-sub,
.tt-wrap.fc .member-next-label,
.tt-wrap.fc .member-next-time span,
.tt-wrap.fc .member-tile-l{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .member-home-title,
.tt-wrap.fc .member-tile-n,
.tt-wrap.fc .member-next-time b{ color:var(--fc-ink) !important; }
.tt-wrap.fc .member-tile,
.tt-wrap.fc .member-next-time{ border-color:var(--fc-line); background:var(--fc-surface); }
.tt-wrap.fc .member-tile:hover,
.tt-wrap.fc .member-next-time:hover{ border-color:var(--fc-accent); }

.tt-wrap.fc .member-panel{ border-color:var(--fc-line); background:var(--fc-surface); }
.tt-wrap.fc .member-panel-h{ color:var(--fc-ink) !important; }
.tt-wrap.fc .member-panel-lead,
.tt-wrap.fc .member-when{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .member-horse{ color:var(--fc-ink) !important; }
.tt-wrap.fc .member-pos{ border-color:var(--fc-line); color:var(--fc-ink); }
.tt-wrap.fc .member-pos.is-win{ background:var(--fc-accent); color:var(--fc-accent-ink) !important;
          border-color:var(--fc-accent); }
.tt-wrap.fc .member-benefits li{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .member-upgrade{ border-color:var(--fc-accent); }
.tt-wrap.fc .member-editlinks{ color:var(--fc-accent) !important; }
.tt-wrap.fc .member-linkpicker{ border-color:var(--fc-line); background:var(--fc-surface); }
.tt-wrap.fc .member-linkopts label{ color:var(--fc-ink); }
.tt-wrap.fc .member-linksaved{ color:var(--fc-accent) !important; }
.tt-wrap.fc .member-linkgroup-h{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .member-panel::before{ background:var(--fc-accent); }
.tt-wrap.fc .member-panel-h i{ color:var(--fc-accent); }
.tt-wrap.fc .member-panel-sub{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .member-upgrade::before{ background:var(--fc-warn, #9a6b00); }
.tt-wrap.fc .member-move.is-in{ color:var(--fc-accent); }
.tt-wrap.fc .member-move.is-out{ color:var(--fc-ink-3); }
.tt-wrap.fc .member-price{ border-color:var(--fc-chip-line); background:var(--fc-chip-bg);
          color:var(--fc-chip-ink); }
.tt-wrap.fc .member-figures span{ color:var(--fc-ink-2); }
.tt-wrap.fc .member-editlinks{ border-color:var(--fc-hair); background:var(--fc-inset);
          color:var(--fc-accent); }
.tt-wrap.fc .member-links-label{ color:var(--fc-ink-2); }
.tt-wrap.fc .member-slot.is-over .member-panel{ outline-color:var(--fc-accent); }
.tt-wrap.fc .bt-homecrumb a{ color:var(--fc-accent); }
.tt-wrap.fc .bt-homecrumb li[aria-current], .tt-wrap.fc .bt-homecrumb li + li::before{ color:var(--fc-ink-2); }
.tt-wrap.fc .help-form input{ border-color:var(--fc-hair); background:var(--fc-inset);
          color:var(--fc-ink); }
.tt-wrap.fc .help-note{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .help-answer-refused .help-said, .tt-wrap.fc .help-answer-escalate .help-said{
          color:var(--fc-ink-2) !important; }

/* Bootstrap's breadcrumb divider is a Material Design Icons codepoint, and build_turtle_css
   strips the CDN icon imports -- so every breadcrumb on every turtle page drew a tofu box.
   Same class as the DataTables sort arrows: a glyph with no font behind it. */
.tt-wrap.fc .breadcrumb-item + .breadcrumb-item::before{ content:"/" !important;
          font-family:inherit !important; }
.tt-wrap.fc .help-waiting{ color:var(--fc-ink-2) !important; }

/* Hyper's secondary grey reaches a reused fragment through `--ct-secondary-color`, which
   knows nothing about this theme: on a turtle sheet its table headings and superscripts
   measured 3.54:1 dark and 4.20:1 light. The sheet owns the variable, so every reused
   fragment inherits an ink chosen against the ground it is actually on. */
.tt-wrap.fc{ --ct-secondary-color:var(--fc-ink-2); }
/* Hyper paints a plain table heading and superscript with its own grey literal, which the
   variable above does not reach: 3.54:1 dark, 4.20:1 light on the turtle ground. No
   `!important`, so the green-head tables and any explicit theme ink still win. */
.tt-wrap.fc .table > thead > tr > th,
.tt-wrap.fc .table thead th,
.tt-wrap.fc .table sup{ color:var(--fc-ink-2); }

/* Chart text on a turtle sheet takes the sheet's ink. Hyper's rule is `--ct-secondary-color`
   and betturtle-base maps it to `--ct-body-color`; neither follows this theme, and the sheet
   ground is not the one either was chosen against -- the staff dashboard's labels measured
   3.00:1 here. A stylesheet rule beats the `fill` attribute ApexCharts writes, so the ink is
   owned here rather than in the chart options. */
.tt-wrap.fc .apexcharts-title-text,
.tt-wrap.fc .apexcharts-subtitle-text,
.tt-wrap.fc .apexcharts-xaxis text,
.tt-wrap.fc .apexcharts-yaxis text,
.tt-wrap.fc .apexcharts-yaxis-title text,
.tt-wrap.fc .apexcharts-xaxis-title text{ fill:var(--fc-ink-2) !important; }
.tt-wrap.fc .apexcharts-legend-text{ color:var(--fc-ink-2) !important; }

/* The chart's own export menu. ApexCharts ships it white-on-white until something paints it:
   the app stylesheet only styles the HOVER state, so at rest "Download SVG" sat at 1:1 in both
   themes -- present, clickable, and invisible. It is hidden behind the hamburger, which is why
   an audit only sees it with --expand. */
.tt-wrap.fc .apexcharts-menu{ background:var(--fc-surface-2) !important; border:1px solid var(--fc-hair) !important; }
.tt-wrap.fc .apexcharts-menu-item{ color:var(--fc-ink) !important; }

/* Each view mode: the button, and the list of what it switches on beside it.

   The blurb used to name four or five settings while the mode wrote a dozen -- two claims
   about the same thing, which is what made the page confusing. The blurb says what the mode
   is FOR; the list is read off the settings themselves, so the words and the switches cannot
   disagree. Closed at rest so four buttons stay four buttons. */
.tt-wrap.fc .tt-modecell{ display:flex; flex-direction:column; }
.tt-wrap.fc .tt-modecell .tt-mode{ flex:1 1 auto; }
.tt-wrap.fc .tt-modewhat > summary{ display:flex; align-items:center; gap:6px; cursor:pointer;
          padding:6px 2px; font-size:calc(12px * var(--fc-scale)); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-modewhat > summary::-webkit-details-marker{ display:none; }
.tt-wrap.fc .tt-modewhat[open] > summary .tt-fsec-caret{ transform:rotate(90deg); }
.tt-wrap.fc .tt-modewhat p{ margin:0 0 8px; }

/* The label beside an action control is part of the control, so it looks like it. */
.tt-wrap.fc .tt-commentact .tt-actlbl,
.tt-wrap.fc .tt-actrow .tt-actlbl{ cursor:pointer; }
.tt-wrap.fc .tt-commentact:hover .tt-actlbl,
.tt-wrap.fc .tt-actrow:hover .tt-actlbl{ color:var(--fc-accent); }

/* The form figures are a control, so they read as one: the row's own type and colour, with
   a dotted underline rather than a button's chrome -- they sit inside a line of prose. */
.tt-wrap.fc .tt-formfig{ background:none; border:0; padding:0; font:inherit; color:inherit;
          cursor:pointer; border-bottom:1px dotted var(--fc-line-2, var(--fc-line)); }
.tt-wrap.fc .tt-formfig:hover,
.tt-wrap.fc .tt-formfig:focus-visible{ color:var(--fc-accent); border-bottom-color:var(--fc-accent); }

/* The form figures, to the left of the sex at the head of the sub-line. Set bold and spaced
   rather than as another item in the run of text: a form string is the first thing a form
   reader looks for, and in the sub-line's own weight it read as part of the sentence. */
.tt-wrap.fc .tt-sub .tt-formfig{ font-weight:700; letter-spacing:.06em;
          font-size:calc(14px * var(--fc-scale)); color:var(--fc-ink); }

/* A popover's own way out. It sits in the header where a dismiss is looked for, and the
   header is padded so the title never runs under it. */
.tt-pop .popover-header{ position:relative; padding-right:34px; }
.tt-pop .popover-body{ position:relative; }
/* The button carries its own ground. Sitting transparent, its ink depended on whatever it
   happened to land over -- and a popover with no header of its own gets it appended to the
   body, where the CONTENT's green band is the first thing at the top: near-black on green.
   A chip of the popover's own background is readable wherever it ends up. */
.tt-pop-close{ position:absolute; top:4px; right:6px; z-index:3;
          background:var(--fc-pop-bg); border:1px solid var(--fc-line);
          line-height:1; cursor:pointer; padding:3px 6px; border-radius:6px;
          color:var(--fc-ink); opacity:.95; }
.tt-pop-close:hover, .tt-pop-close:focus-visible{ opacity:1; background:var(--fc-hover);
          border-color:var(--fc-accent); }

/* A card that states its meaning in colour ------------------------------------------------
   My Shortlisted Runners states its big-priced winners as four coloured cards. Bootstrap's
   semantic grounds are LIGHT -- `bg-success` is #0acf97 and `bg-warning` #ffc35a -- so the
   `text-white` they ship with measures 2.02 and 1.59 on their own ground, in either theme.
   They take the palette's tint-and-ink pairs, which are defined together and tuned per theme
   at this size. The TINT carries the meaning; the words take the sheet's own ink, because the
   value inks are tuned for the row ground and measure 3.75-4.37 on these. */
.tt-wrap.fc .tt-sheet .card.bg-danger{ background:var(--fc-cell-r) !important; }
.tt-wrap.fc .tt-sheet .card.bg-success{ background:var(--fc-cell-g) !important; }
.tt-wrap.fc .tt-sheet .card.bg-warning{ background:var(--fc-cell-a) !important; }
/* `.bg-primary` becomes a solid head-green band wherever it appears, which is right for a
   section header and wrong for one card in a row of four: it read as a different kind of
   thing. In a card it is a tint like its neighbours. */
.tt-wrap.fc .tt-sheet .card.bg-primary{
          background:color-mix(in srgb, #1e5a8a 20%, transparent) !important; }
.tt-wrap.fc .tt-sheet .card.bg-primary,
.tt-wrap.fc .tt-sheet .card.bg-primary :is(h1,h2,h3,h4,h5,h6,p,span,div,small,strong,
                                           .card-title,.card-text,.text-white){
          color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .card:is(.bg-primary, .bg-danger, .bg-success, .bg-warning,
                               .bg-info, .bg-secondary){ border-color:var(--fc-hair) !important; }

.tt-wrap.fc .tt-sheet .card.bg-danger,
.tt-wrap.fc .tt-sheet .card.bg-danger :is(h1,h2,h3,h4,h5,h6,p,span,div,small,strong,
                                          .card-title,.card-text,.text-white){
          color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .card.bg-success,
.tt-wrap.fc .tt-sheet .card.bg-success :is(h1,h2,h3,h4,h5,h6,p,span,div,small,strong,
                                           .card-title,.card-text,.text-white){
          color:var(--fc-ink) !important; }
.tt-wrap.fc .tt-sheet .card.bg-warning,
.tt-wrap.fc .tt-sheet .card.bg-warning :is(h1,h2,h3,h4,h5,h6,p,span,div,small,strong,
                                           .card-title,.card-text,.text-white){
          color:var(--fc-ink) !important; }

/* What kind of racing a course stages, on its card in the index. One chip style for all
   three: the word is the information, so a colour vocabulary would be decoration that has to
   be learned. */
.tt-wrap.fc .tt-coursetypes{ display:flex; flex-wrap:wrap; gap:4px; margin-top:4px; }
.tt-wrap.fc .tt-ctype{ background:var(--fc-chip-bg); color:var(--fc-chip-ink);
          border:1px solid var(--fc-chip-line); border-radius:999px; padding:1px 7px;
          font-size:max(11px, calc(10.5px * var(--fc-scale))); font-weight:600;
          letter-spacing:.02em; white-space:nowrap; }

/* The shared time button, drawn as the pill Today's Racing draws. The paywall state rides on
   the corner of it: it is the one thing the classic button carried that is not a decoration,
   because it says whether the card behind the time is open to this customer. */
.tt-wrap.fc .tt-pillwrap{ position:relative; display:inline-block; }
/* Tucked INSIDE the pill, not hung off its corner: at -5px each mark overlapped the pill
   beside it, and a row of them read as a rash of blobs rather than a status. Only the
   "already open" mark exists now -- see _timepill.html for why a locked one could never
   say anything, appearing as it did on every race at once. */
.tt-wrap.fc .tt-pillmark{ position:absolute; top:1px; right:1px; z-index:2;
          width:13px; height:13px; border-radius:50%; display:grid; place-items:center;
          font-size:8.5px; font-weight:700; border:0; }
/* Inverted. The mark sat accent-on-accent -- rgb(0,117,33) on a rgb(26,122,79) pill, about
   1.2:1 -- so it was invisible on the very pills it marks. The ring keeps it readable if it
   ever lands on a pale pill. */
.tt-wrap.fc .tt-pillmark.is-open{ background:var(--fc-accent-ink); color:var(--fc-accent);
          box-shadow:0 0 0 1px var(--fc-accent); }

/* Today's Tips and Today's Best Bets, reading like Today's Racing ---------------------------
   Both are classic pages inside a sheet, so their sections arrive as `.card.widget-flat` with
   a solid `.bg-primary` slab across the top -- a band of head-green every few hundred pixels,
   where Today's Racing gives a meeting a quiet accent label and a bordered box. Scoped to
   `.tt-tipspage` so `.card.widget-flat` elsewhere is untouched. */
.tt-wrap.fc .tt-tipspage .card.widget-flat{ background:var(--fc-surface-2) !important;
          border:1px solid var(--fc-hair) !important; border-radius:10px; margin-bottom:14px; }
/* The ground and its ink are decided here together. The course band and the three section
   bands are the same `.card-header.bg-primary.text-white` shape, so taking the dark ground
   away and leaving `text-white` alone put "Going: Soft" and the TV channel white on a pale
   sheet -- invisible, and the third time that pairing has been split in this theme. */
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header{
          background:transparent !important; border-bottom:1px solid var(--fc-hair) !important;
          padding:10px 12px 8px; color:var(--fc-ink-2) !important; }
/* `div` and `p` are named because the sheet paints every element inside a `.bg-primary` band
   white, and the going sits in a plain `.row`. The section title keeps the accent: `.card-title`
   carries a class and out-specifies the bare `h4` here. */
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header .text-white,
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header .text-white-50,
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header i,
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header span,
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header div,
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header p,
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header h4{
          color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header .row{
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header .card-title{
          margin:0; color:var(--fc-accent) !important; text-transform:uppercase;
          letter-spacing:.05em; font-weight:700;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-tipspage .card.widget-flat > .card-header p{
          margin:4px 0 0; color:var(--fc-ink-2) !important;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
/* The per-tip boxes are the meeting boxes' shape rather than a second one. */
.tt-wrap.fc .tt-tipspage .card-body .border.card{ background:var(--fc-surface) !important;
          border:1px solid var(--fc-hair) !important; border-radius:8px; }

/* The course/times switch is the same segmented control as Times / Detailed. */
.tt-wrap.fc .tt-tipspage .nav-tabs{ border-bottom:none; gap:0;
          display:inline-flex; padding:3px; border:1px solid var(--fc-hair);
          border-radius:8px; background:var(--fc-inset); }
.tt-wrap.fc .tt-tipspage .nav-tabs .nav-link{ border:none !important; border-radius:6px;
          padding:4px 12px; color:var(--fc-ink-2) !important; font-weight:600;
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }
.tt-wrap.fc .tt-tipspage .nav-tabs .nav-link.active{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }

/* The Filter Races control, given the shape of Today's Racing's filter. The markup is left
   alone: its JS binds `#filter-table`, `#applyfilterbutton` and `#resetfilterbutton` by id,
   and a filter that looks aligned but has stopped applying is worse than one that looks
   different. */
.tt-wrap.fc .tt-tipspage .btn-group[aria-label="Filter Races"]{
          border:1px solid var(--fc-line); border-radius:8px; background:var(--fc-surface); }
.tt-wrap.fc .tt-tipspage .btn-group[aria-label="Filter Races"] > a{
          padding:8px 12px; color:var(--fc-ink) !important; font-weight:600;
          text-decoration:none !important;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-tipspage .btn-group[aria-label="Filter Races"] > a i{
          color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-tipspage #filter-table{ border:1px solid var(--fc-line); border-radius:8px;
          background:var(--fc-surface); padding:10px 12px; }
.tt-wrap.fc .tt-tipspage #filter-table legend{ color:var(--fc-ink-2); font-weight:600;
          text-transform:uppercase; letter-spacing:.03em;
          font-size:max(10px, calc(11px * var(--fc-scale))); }
.tt-wrap.fc .tt-tipspage #filter-table .form-check-label{ color:var(--fc-ink);
          font-size:max(11px, calc(12.5px * var(--fc-scale))); }

/* Race Profiles index: the season as a calendar --------------------------------------------
   Each month was a full-width card holding a short vertical list, so a page of twelve months
   was mostly empty to the right of the race names. The months flow across as well as down;
   a month with a long list simply makes its own card taller. Classic is untouched -- the
   wrapper is an unstyled div there. */
.tt-wrap.fc .tt-rpmonths{ display:grid; gap:12px;
          grid-template-columns:repeat(auto-fill, minmax(300px, 1fr)); align-items:start; }
.tt-wrap.fc .tt-rpmonths .tt-rpmonth{ margin-bottom:0 !important;
          background:var(--fc-surface-2) !important; border:1px solid var(--fc-hair) !important;
          border-radius:10px; }
.tt-wrap.fc .tt-rpmonths .tt-rpmonth h2{ color:var(--fc-accent) !important;
          text-transform:uppercase; letter-spacing:.05em; font-weight:700;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-rpmonths .tt-rpmonth li{ line-height:1.45;
          font-size:max(12px, calc(13px * var(--fc-scale))); }

/* The Today / Tomorrow choice on Search Horse Races. The words state their own ink rather
   than inheriting it: they were loose text nodes in a table with no class, so nothing in this
   file reached them and whatever rule got there last decided how readable they were. */
.tt-wrap.fc .bt-daypick{ display:inline-flex; gap:4px; border:1px solid var(--fc-line);
          border-radius:8px; padding:3px; background:var(--fc-surface); }
.tt-wrap.fc .bt-daypick-opt{ display:inline-flex; align-items:center; gap:7px; margin:0;
          padding:5px 12px; border-radius:6px; cursor:pointer;
          color:var(--fc-ink) !important; font-weight:600;
          font-size:max(12px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .bt-daypick-opt span{ color:var(--fc-ink) !important; }
.tt-wrap.fc .bt-daypick-opt:hover{ background:var(--fc-hover); }
.tt-wrap.fc .bt-daypick-opt:has(input:checked){ background:var(--fc-accent); }
.tt-wrap.fc .bt-daypick-opt:has(input:checked) span{ color:var(--fc-accent-ink) !important; }

/* The sheet paints its own ground rather than letting the page gradient show through. Text on
   a gradient has a contrast that VARIES down the page -- the same red measured 5.34 against a
   panel and 3.76 against the gradient's lighter top, which is where the last failure was. */
.tt-wrap.fc .tt-card.tt-sheet{ background:var(--fc-surface-2); }

/* The comment's expand control exists only where the comment is clamped. */
.tt-wrap.fc .tt-cmore{ display:none; }

/* Phone density -------------------------------------------------------------------------
   Measured at 390px: a runner row was 616px, so 1.4 fitted on a screen. Where it went:
   the comment 259, the trainer and jockey 51 on two full-width lines of their own, the
   horseshoe block 59 including a label row repeating the same five words under every
   runner, the ratings 30. Customers want to see more runners; none of this removes a fact
   from the card. */
@media (max-width: 1024px){
  /* 1. The comment is the largest single thing in the row. Three lines, then a control that
        opens it in place -- the row is the only place this text appears, so it cannot just
        be truncated. */
  /* A height cap, not `-webkit-line-clamp`. The paragraph is a grid item, so its display is
     BLOCKIFIED -- setting `-webkit-box` on it, even inline, computes back to `flow-root` and
     the clamp never engages. A max-height in line units survives that. */
  /* No clamp and no More on a phone (Kenny, 31 Aug). The comment reads in full; the button
     was one more thing to press on the row it was meant to shorten. */
  .tt-wrap.fc .tt-cmore{ display:none !important; }
  /* No fade. It half-erased the third line and read as broken rendering rather than as an
     affordance; the More button below says there is more. */
  .tt-wrap.fc .tt-cmore{ display:inline-block; margin-top:4px; padding:2px 8px;
            border:1px solid var(--fc-line-2); border-radius:5px; background:var(--fc-inset);
            color:var(--fc-ink); font:inherit; cursor:pointer;
            font-size:max(11px, calc(12px * var(--fc-scale))); }
  .tt-wrap.fc .tt-cmore:hover{ background:var(--fc-hover); }

  /* 4b. The action row under the comment was the biggest block after the prose -- 98px, three
        wrapped lines at a 10px gap. The words stay: an icon alone is a thing to decode. */
  .tt-wrap.fc .tt-commentacts{ gap:2px 10px; margin-top:4px; line-height:1.25; }
  .tt-wrap.fc .tt-commentact{ font-size:max(11px, calc(11.5px * var(--fc-scale))); gap:4px; }
  .tt-wrap.fc .tt-commentacts .btn,
  .tt-wrap.fc .tt-commentacts button{ padding-top:1px; padding-bottom:1px; }
  .tt-wrap.fc .tt-whybtn{ margin-top:2px; padding:1px 8px; }

  /* 4. The gaps between blocks, which add up over eight runners. */
  .tt-wrap.fc .tt-r3{ margin-top:4px; }
  .tt-wrap.fc .tt-rowcomment{ margin:4px 0 2px; padding:6px 8px; }
  .tt-wrap.fc .tt-rateswrap{ margin-top:2px; }
}

/* Trainer and jockey share a line up to 1024px, where the row is a stack and each name was
   alone on a line with the rest of it empty. NOT above that: at desktop the people area is a
   narrow column of a single-row layout, and forcing one line there truncated the trainer to
   "Dr Richar..." on a 1400px screen. The height saving was real and the cost was a name
   nobody could read -- which a height measurement cannot see.

   `display` has to be stated: .tt-people is a GRID elsewhere in this file, so setting
   flex-direction alone left both names as full-width grid rows. */
@media (max-width: 1024px){
  .tt-wrap.fc .tt-people{ display:flex; flex-direction:row; flex-wrap:wrap; gap:0 12px; }
}
@media (max-width: 1024px){
  .tt-wrap.fc .tt-connline{ display:inline-flex; align-items:baseline; gap:4px; }
}

/* The five factor labels are the same five words under every runner in the race. `.tt-runhead`
   names the columns once, at every width, so the per-runner repeat goes at every width too.
   Each tile keeps its own aria-label, so a screen reader is unaffected. */
.tt-wrap.fc .tt-shoes .tt-cellwrap > small{ display:none; }

/* Row layout, 31 Aug 2026 -------------------------------------------------------------------
   Kenny: the days figure beside the horse name, the descriptive labels at the top of Why, the
   tip badges as a ribbon, and on a phone the saddle, silk, name, days and price on one line. */

/* 1 + 4. Days since the last run, beside the name. It was the last item of the sub-line, where
   it read as part of a run of text; as a superscript it belongs to the name and rides on the
   line the saddle, silk and price already share. The word "days" is a `d` -- the tooltip and
   the aria-label carry the meaning, and the figure is what is being compared. */
/* .68em not .62, and ink-2 not ink-3: at 9.9px the `d` measured 3.97 and 4.24 against the
   row. A suffix small enough to be decoration still has to be readable. No opacity -- that is
   what took it under, and it is invisible in a token audit because the token itself passes. */
.tt-wrap.fc .tt-dayssup{ margin-left:5px; font-size:.68em; font-weight:700;
          color:var(--fc-ink-2); vertical-align:super; white-space:nowrap;
          font-variant-numeric:tabular-nums; }
.tt-wrap.fc .tt-dayssup em{ font-style:normal; margin-left:1px; }

/* 2. The labels at the top of the Why tab. */
.tt-wrap.fc .tt-labels{ display:flex; flex-wrap:wrap; gap:5px; margin:0 0 10px; }
.tt-wrap.fc .tt-dpane[data-tt-dpane="why"] .tt-rowtraits{ margin:0 0 12px; }

.tt-wrap.fc .tt-runner{ position:relative; }

/* The customer's own state -- shortlisted, notebooked, binned -- read off the BUTTON's icon
   rather than from the context, so the label follows a click with no JS and cannot disagree
   with the control. `far`<->`fas` is what the like and note handlers toggle; hide swaps
   `fa-trash` for `fa-trash-restore`. */
/* Shortlist-only, read off the heart's own icon so the list follows a heart being pressed
   while the filter is on. The button beside Charts owns the class. */
.tt-wrap.fc .tt-runners.is-shortlistonly .tt-runner:not(:has(i[class*="like-"].fas)){
          display:none; }
.tt-wrap.fc .tt-shortlistbtn.is-on{ border-color:var(--fc-val-r); color:var(--fc-val-r); }
.tt-wrap.fc .tt-shortlistbtn em{ font-style:normal; font-weight:700; }
.tt-wrap.fc .tt-runner i[class*="like-"].fa-heart{ color:var(--fc-val-r) !important; }
.tt-wrap.fc .tt-runner i[class*="note-"].fa-address-book{ color:var(--fc-val-a) !important; }

/* 3. Badges, labels and markers as ONE run under the comment. Each of the three keeps its
   own internal layout; the run only lines them up and closes the gaps between them, so a
   group that renders nothing takes no space. */
.tt-wrap.fc .tt-whyrun{ display:flex; flex-wrap:wrap; align-items:center; gap:5px;
          margin:0 0 12px; }
.tt-wrap.fc .tt-whyrun > *{ margin-bottom:0; }
.tt-wrap.fc .tt-whyrun .tt-labels,
.tt-wrap.fc .tt-whyrun .tt-whymarks{ margin:0; }
.tt-wrap.fc .tt-whyrun .tt-badges{ display:flex; flex-wrap:wrap; align-items:center;
          gap:5px; }
.tt-wrap.fc .tt-whyrun .tt-badges:empty{ display:none; }
/* An outline badge paints only its text, and Hyper's indigo on the drawer's ground is 3.3:1.
   Off the ribbon it has no inset behind it, so it takes the tag's own ink and border and
   reads as one family with the labels beside it. The filled badges keep their own colours. */
.tt-wrap.fc .tt-whyrun .tt-badges .badge[class*="badge-outline"]{
          color:var(--fc-accent) !important; border-color:var(--fc-line-2) !important;
          background:transparent !important; }

/* 5. The trainer and jockey flags keep the icon and drop the word when the line is tight, so
   the pair stays on one line. The word is still the accessible name and the tooltip. */
@media (max-width: 1024px){
  .tt-wrap.fc .tt-flags .tt-flag em{ position:absolute; width:1px; height:1px;
            overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
  .tt-wrap.fc .tt-flags .tt-flag{ padding-left:4px; padding-right:4px; }
}

/* The name and its days figure: one line, the figure last. A long name wrapped the figure
   under itself at phone width, which is the opposite of what was asked for. */
.tt-wrap.fc .tt-nameline{ display:flex; align-items:baseline; gap:0; min-width:0; }
.tt-wrap.fc .tt-nameline .tt-name{ min-width:0; overflow:hidden; text-overflow:ellipsis;
          white-space:nowrap; }
.tt-wrap.fc .tt-nameline .tt-dayssup{ flex:0 0 auto; }

/* Making `.tt-people` a flex row put the label and the name in the same wrapping context, so
   a long trainer split as "T Dr Richard : Newland", and the flag words broke mid-word into
   "CO / LD". Both were visible on a desktop card and neither showed up in a height
   measurement -- the row got SHORTER as it got wronger. */
@media (max-width: 1024px){ .tt-wrap.fc .tt-connline > b{ flex:0 0 auto; } }
/* The label never leaves its name, at any width -- that is what produced "T Dr Richard :
   Newland". Truncation is only for the widths where the two share a line: at desktop the
   people area is a narrow column and a name that does not fit should WRAP, not disappear
   behind an ellipsis. A trainer's name is worth a second line. */
@media (max-width: 1024px){
  .tt-wrap.fc .tt-connline{ flex-wrap:nowrap; white-space:nowrap; max-width:100%; }
  .tt-wrap.fc .tt-connname{ min-width:0; overflow:hidden; text-overflow:ellipsis;
            white-space:nowrap; }
}
/* Only the word must not break -- "COLD" became "CO / LD". The flags' own layout is left
   alone, because changing it collapsed the people cell at desktop and the name then broke one
   character per line. */
.tt-wrap.fc .tt-flag{ white-space:nowrap; }
.tt-wrap.fc .tt-flag em{ white-space:nowrap; }

/* "Why this?" is lit while the panel it opened is open, so it reads as the way back out as
   well as the way in. Same treatment as the other pressed controls on the card. */
.tt-wrap.fc .tt-whybtn[aria-expanded="true"]{ background:var(--fc-accent);
          border-color:var(--fc-accent); color:var(--fc-accent-ink); font-weight:700; }

/* The connection heads above the records in Insights: one per line, so a trainer and their
   flags read as one thing rather than running into the next person. */
.tt-wrap.fc .tt-connheads{ display:flex; flex-direction:column; gap:4px; margin:0 0 10px; }

/* The per-horse markers, now at the top of Why beside the labels. */
.tt-wrap.fc .tt-whymarks{ display:flex; flex-wrap:wrap; align-items:center; gap:5px;
          margin:0 0 12px; }
/* Each marker is NAMED (Kenny, 31 Aug). An icon alone is a thing to decode, and these sit
   beside labels that carry their words -- so they take the tag's geometry and ink and the
   run reads as one family. */
.tt-wrap.fc .tt-whymarks .tt-mark{ display:inline-flex; align-items:center; gap:4px;
          border:1px solid var(--fc-line-2); border-radius:3px; padding:1px 6px;
          color:var(--fc-accent); background:transparent; }
.tt-wrap.fc .tt-whymarks .tt-mark em{ font-style:normal; text-transform:uppercase;
          letter-spacing:.04em; font-weight:600;
          font-size:max(10px, calc(10px * var(--fc-scale))); }
.tt-wrap.fc .tt-whymarks .tt-mark.is-intel{ color:var(--fc-accent); }
.tt-wrap.fc .tt-whymarks:empty{ display:none; }

/* The betting rating as a badge in the Race Analysis pane, in the `.tt-flag` family the
   trainer and jockey marks use. Its own colour, from the same three the card uses for good,
   fair and poor everywhere else -- not the accent, which would say "notable" rather than
   "good". */
.tt-wrap.fc .tt-racebadge{ margin:6px 0 8px; }
.tt-wrap.fc .tt-flag-rate1{ color:var(--fc-val-g); }
.tt-wrap.fc .tt-flag-rate2{ color:var(--fc-val-a); }
.tt-wrap.fc .tt-flag-rate3{ color:var(--fc-val-r); }

/* The price and its movement arrow on one line -- the odds track is widened in the grid
   definitions themselves, not by a second rule competing with them. Adding one here set four
   columns against a nine-column template and the pick and the price landed on top of the
   horseshoes. */
/* The price sits in the space between the pick number and MORE rather than hard against the
   pick, and its contents are left-aligned within that (Kenny, 31 Aug). `flex-end` pushed it
   onto the pick and left the gap on the other side. */
.tt-wrap.fc [style*="grid-area:odds"], .tt-wrap.fc .tt-oddscell{
          display:flex; align-items:center; justify-content:flex-start; gap:8px;
          flex-wrap:nowrap; white-space:nowrap; padding-left:28px; }

/* The betting-race badge sits on the same line as the runnings, strike rate and OR range
   rather than on a line of its own. */
.tt-wrap.fc .tt-briefline{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 18px;
          margin:6px 0 8px; }
.tt-wrap.fc .tt-briefline .tt-racebadge{ margin:0; }
.tt-wrap.fc .tt-briefline .tt-racefacts{ display:contents; }
.tt-wrap.fc .tt-briefline .tt-racefacts li{ display:flex; align-items:baseline; gap:6px;
          margin:0; }

/* The winner traits in two columns -- what winners did more often on the left, less often on
   the right. One column below 900px, where two would give each row about 40 characters. */
.tt-wrap.fc .tt-traitcols{ display:grid; gap:0 26px; grid-template-columns:1fr; }
@media (min-width:900px){ .tt-wrap.fc .tt-traitcols{ grid-template-columns:1fr 1fr; } }
.tt-wrap.fc .tt-traitcols .tt-traits{ margin:0; }
.tt-wrap.fc .tt-traitcols .tt-traits:empty{ display:none; }

/* Room at the foot of the brief panes. They ended flush against the runner list, which is
   what made a dense panel read as congested. */
.tt-wrap.fc .tt-panel{ padding-bottom:18px; }
.tt-wrap.fc .tt-panel > :last-child{ margin-bottom:0; }

/* A control that opened something stays lit while it is open (Kenny, 31 Aug). This is the
   general rule rather than another per-button one: several controls already tracked
   `aria-expanded`/`aria-pressed` correctly and simply looked identical either way -- "Show
   runners vs the winner profile" was the example, and the Why button needed its own rule
   last week for the same reason.

   `:where()` keeps this at attribute specificity, so the controls that already have a lit
   style of their own -- the segmented buttons, the brief chips, the day tabs -- keep theirs
   and this only reaches the ones with none. */
/* The navbar toggle is excluded: it is a button carrying `aria-expanded`, so this rule lit it
   the moment somebody opened the menu -- and Bootstrap's own `bg-transparent` beat the accent
   background, leaving white ink on the pale bar. This rule is for controls INSIDE the card,
   not for site chrome. `:not()` costs a class's specificity, which this rule can afford. */
.tt-wrap.fc :where(button, [role="button"])[aria-expanded="true"]:not(.navbar-toggler),
.tt-wrap.fc :where(button, [role="button"])[aria-pressed="true"]:not(.navbar-toggler){
          background:var(--fc-accent); border-color:var(--fc-accent);
          color:var(--fc-accent-ink); font-weight:700; }
/* Everything inside a lit control takes the accent's ink, not just the icon. A child span
   carrying its own colour -- the fit button's label is one -- stayed light on the lime accent
   in dark mode, which is the worst pairing the palette has. */
.tt-wrap.fc :where(button, [role="button"])[aria-expanded="true"]:not(.navbar-toggler) *,
.tt-wrap.fc :where(button, [role="button"])[aria-pressed="true"]:not(.navbar-toggler) *{
          color:var(--fc-accent-ink) !important; }

/* Icon Help, Print and Settings are icon-only on a phone (Kenny, 31 Aug). Each keeps an
   aria-label and a tooltip, so hiding the word costs neither a screen reader nor a hover. */
@media (max-width: 767px){
  .tt-wrap.fc .tt-tool .tt-toollbl{ position:absolute; width:1px; height:1px;
            overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
  .tt-wrap.fc .tt-tool:has(.tt-toollbl){ padding-left:9px; padding-right:9px; }
}

/* Smaller shoe tiles on a phone, which is what makes room for the pick and MORE beside them.
   The glyph keeps its own floor so it does not become a smudge. */
@media (max-width: 767px){
  .tt-wrap.fc .tt-cell{ height:34px; }
  .tt-wrap.fc .tt-cell i{ font-size:max(14px, calc(17px * var(--fc-scale))); }
  .tt-wrap.fc .tt-shoes{ gap:4px; }
  .tt-wrap.fc .tt-r1{ gap:6px 6px; }
}

/* Narrower phones need a little more taken out, or MORE drops below the shoes again. */
/* The tiles SHARE whatever is left rather than each claiming a width, so they compress to fit
   beside the pick and MORE at any phone width. Fixed sizes worked at 320 and 430 and dropped
   MORE below the row at 360 and 390 -- the two commonest -- which is column arithmetic being
   asked to do a job flex does properly. */
@media (max-width: 767px){
  /* Two things shared the last column: the price on line one and the four action icons on
     the last line. `auto` sized it to the icons -- 191px -- and the horse's name, a
     `minmax(0,1fr)` beside it, collapsed to 37px, so a name read as "Z...". Stating the
     column fixed the name and clipped the icons instead: 416px cannot hold both.
     So the actions take a line of their own. It is one row more, and it is the row that was
     overflowing; the name, the price, the horseshoes and the pick all read now. */
  .tt-wrap.fc .tt-r1{ grid-template-columns:44px 40px minmax(0,1fr) 26px 26px 80px;
        grid-template-areas:
          "cloth  silk   name   name  name  odds"
          "people people people people people people"
          "rates  rates  rates  rates rates rates"
          "shoes  shoes  shoes  pick  pos   act"; }
  /* MORE stays with the marks rather than moving up beside the pick. Moving it does not free
     the marks' row, and the arithmetic is why: at 390px the row has 356 to spend, the four
     marks want 140, the pick 26 and MORE 51, leaving 115 for five horseshoes -- 23px each.
     They are the product's headline rating and 23px is not a reading of anything. What DOES
     buy the space back is the note's word, which the legend already carries. */
  .tt-wrap.fc .tt-r1 > [style*="grid-area:act"], .tt-wrap.fc .tt-actcell{
        justify-content:flex-start; gap:4px; }
  /* The cell holds MORE and nothing else now, so it sits back on the horseshoes' line where
     it began -- the row it had to itself was one button tall. */
  .tt-wrap.fc .tt-r1 > [style*="grid-area:act"], .tt-wrap.fc .tt-actcell{
        display:flex; align-items:center; justify-content:flex-end; }
  .tt-wrap.fc .tt-actcell .tt-actlbl{ display:none; }
  /* The 28px inset that centres the price between the pick and MORE is a desktop measure;
     on a phone it is a quarter of the column. */
  .tt-wrap.fc [style*="grid-area:odds"], .tt-wrap.fc .tt-oddscell{ padding-left:0; }
  .tt-wrap.fc .tt-shoes{ display:flex; gap:3px; min-width:0; }
  .tt-wrap.fc .tt-shoes .tt-cellwrap{ flex:1 1 0; min-width:0; }
  .tt-wrap.fc .tt-cell{ height:30px; }
  .tt-wrap.fc .tt-cell i{ font-size:max(13px, calc(15px * var(--fc-scale))); }
}

/* A closest match is pressable, and the runner it takes you to is marked briefly on arrival
   -- a smooth scroll ending in the middle of a card of similar rows leaves the reader hunting
   for the one they asked for. */
.tt-wrap.fc button.tt-check{ cursor:pointer; }
.tt-wrap.fc button.tt-check:hover,
.tt-wrap.fc button.tt-check:focus-visible{ border-color:var(--fc-accent);
          box-shadow:0 0 0 2px var(--fc-hover); }
.tt-wrap.fc .tt-runner.is-found{ animation:tt-found 2.2s ease-out 1; }
@keyframes tt-found{
  0%, 60%{ box-shadow:0 0 0 3px var(--fc-accent); }
  100%{ box-shadow:0 0 0 3px transparent; }
}
@media (prefers-reduced-motion: reduce){
  .tt-wrap.fc .tt-runner.is-found{ animation:none; box-shadow:0 0 0 3px var(--fc-accent); }
}

/* The two labels in that run that OPEN something look identical to the ones that only
   describe the horse, so nothing says they can be pressed (Kenny, 1 Sep). Three signals, none
   of them a colour on its own: the cursor, a chevron that turns when the thing is open, and a
   border that answers on hover and focus. The descriptive labels get none of them, which is
   what makes these two read as different. */
.tt-wrap.fc button.tt-tag-fit,
.tt-wrap.fc .tt-whymarks button.tt-mark{ cursor:pointer; }
/* A real element, not a pseudo with a font name in it: the icon font is Pro v7 here and a
   family that does not match renders a tofu box. `tt-fsec-caret` already proves the pattern. */
.tt-wrap.fc .tt-tag-caret{ margin-left:5px; font-size:.72em; opacity:.75;
          transition:transform .12s ease; display:inline-block; }
.tt-wrap.fc [aria-expanded="true"] > .tt-tag-caret{ transform:rotate(90deg); }
.tt-wrap.fc button.tt-tag-fit:hover,
.tt-wrap.fc button.tt-tag-fit:focus-visible,
.tt-wrap.fc .tt-whymarks button.tt-mark:hover,
.tt-wrap.fc .tt-whymarks button.tt-mark:focus-visible{
          border-color:var(--fc-accent); box-shadow:0 0 0 2px var(--fc-hover); }

/* Today's racing on a phone: three next races and no "still to run" count (Kenny, 1 Sep).
   The strip is a way into the next few races, not a summary of the day -- the count is a
   number nobody acts on, and races four to six are a tap away on the card below. */
@media (max-width: 767px){
  .tt-wrap.fc .tt-todaynext .tt-chip-run{ display:none; }
  /* Three (Kenny, 1 Sep, from his own phone). My measurement said they wanted 440px of a 358px
     strip -- taken at the NORMAL text setting, which is a 1.15 scale. At compact they fit, and
     at the larger settings they wrap to a second line, which is what wrapping is for. */
  .tt-wrap.fc .tt-todaynext .tt-time-pill:nth-of-type(n+4){ display:none; }
  /* Three pills still wanted 400px of a 358px strip, and the course name is what makes them
     wide -- "Gowran Park" alone took a pill to 134. The course is set smaller rather than
     truncated: a course cut to "Gowran P..." is worse than a course read at 11px. */
  .tt-wrap.fc .tt-todaynext .tt-pill-course{
        font-size:max(10px, calc(10.5px * var(--fc-scale))); }
  .tt-wrap.fc .tt-todaynext .tt-time-pill{ padding-left:7px; padding-right:7px; }
}

/* The brief chips answer to a short name on a phone: five of them at their full length wrap
   to three lines, and "Race" leads three of the five without separating any of them. The count
   under each name goes too -- it is a detail for a screen with room. */
.tt-chip-short{ display:none; }
@media (max-width: 767px){
  .tt-wrap.fc .tt-chip-long{ display:none; }
  .tt-wrap.fc .tt-chip-short{ display:inline; }
  .tt-wrap.fc .tt-brief-chip em{ display:none; }
  /* The short names alone still wanted 482px of a 378px bar. The icon goes too: it is a
     second way of saying what the word already says, and it was the biggest single piece of
     each chip. */
  .tt-wrap.fc .tt-brief-chip i{ display:none; }
  .tt-wrap.fc .tt-brief-chip{ padding-left:7px; padding-right:7px;
        font-size:max(11px, calc(12.5px * var(--fc-scale))); }
  /* Four pixels over at 390 with a 6px gap, and 360 is a phone width people still carry. */
  .tt-wrap.fc .tt-briefbar{ gap:4px; }
}

/* Help, print and settings share the order control's line rather than taking one of their own
   (Kenny, 1 Sep). `display:contents` on the first group so its children become items of the
   bar itself -- otherwise the group is one wide item and always wraps whole -- then the order
   label, the select and the utilities are ordered to the end and sit together. The three
   icons are 44px each and the select about 110: they fit a 356px line with room. */
@media (max-width: 767px){
  .tt-wrap.fc .tt-bar > .tt-bargroup:first-child{ display:contents; }
  .tt-wrap.fc .tt-bar .tt-orderlbl{ order:8; }
  .tt-wrap.fc .tt-bar .tt-order{ order:9; }
  .tt-wrap.fc .tt-bar .tt-barutils{ order:10; margin-left:auto; }
  /* A break before them, or flex packs the select onto the end of an earlier line and the
     icons wrap alone anyway -- which is the row this was meant to remove. Zero height, so it
     costs nothing but the wrap it forces. */
  .tt-wrap.fc .tt-bar::after{ content:""; flex-basis:100%; height:0; order:7; }
}

/* The card toolbar on a phone: fewer words, same controls (Kenny, 31 Aug). Every label that
   goes is either repeated by the control's own state or is a count that belongs to the panel
   it opens, not to the button. Nothing is removed above 767px. */
@media (max-width: 767px){
  /* "Filters on - none excluded" -> "Filters on". The exclusion count is in the panel. */
  .tt-wrap.fc .tt-fstate-detail{ display:none; }
  /* The Order select says "Pick"; the word "Order" in front of it says nothing more. */
  .tt-wrap.fc .tt-orderwrap > label,
  .tt-wrap.fc .tt-orderlbl{ position:absolute; width:1px; height:1px; overflow:hidden;
            clip-path:inset(50%); white-space:nowrap; }
  /* The brief chips keep their names and drop the counts. */
  .tt-wrap.fc .tt-brief-chip em,
  .tt-wrap.fc .tt-brief-chip .tt-chip-count{ display:none; }
  /* Vertical only. The block above sets 7px sides to fit five chips on one line, and a
     shorthand here would restate the horizontal value and undo it. */
  .tt-wrap.fc .tt-brief-chip{ padding-top:5px; padding-bottom:5px; }
  .tt-wrap.fc .tt-bar{ gap:5px; }
}

/* The action row fits one line on a phone (Kenny, 31 Aug). The four markers keep their icons
   and drop their words; "Why this?" keeps its label, because it is the one control here whose
   icon would mean nothing. The words stay in the DOM, clipped rather than removed, so they
   are still the accessible name -- and each control's own tooltip already carries them. */
@media (max-width: 767px){
  .tt-wrap.fc .tt-commentacts .tt-actlbl{ position:absolute; width:1px; height:1px;
            overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
  .tt-wrap.fc .tt-commentacts{ flex-wrap:nowrap; gap:2px 14px; align-items:center; }
  .tt-wrap.fc .tt-commentact{ flex:0 0 auto; }
  .tt-wrap.fc .tt-whybtn{ flex:0 0 auto; }
}

/* ---------------------------------------------------------------------------------------
   Every star is the same yellow (Kenny, 31 Aug), wherever it is drawn: the shrewd-trainer
   flag, the closest-match marks, the performance key, a column heading, the shortlist control
   and anything a reused classic fragment brings with it. The ICON only -- a flag's word keeps
   its own colour, and a star inside a run of coloured text is still a star.

   Last in the file and carrying `.text-warning` in the selector on purpose: five `.text-warning`
   mappings are (0,3,0) with `!important`, so a shorter selector earlier in the file loses to
   every one of them. This ties on specificity and wins on order.
   --------------------------------------------------------------------------------------- */
.tt-wrap.fc .fa-star,
.tt-wrap.fc .fa-star.text-warning,
.tt-wrap.fc .fas.fa-star,
.tt-wrap.fc .far.fa-star,
.tt-wrap.fc .fa-solid.fa-star,
.tt-wrap.fc .fa-sharp.fa-star,
.tt-pop .popover-body .fa-star.text-warning{ color:var(--fc-star) !important;
          text-shadow:var(--fc-star-edge); }

/* The Quick Settings card filter takes the sheet's own ink and hairline rather than
   Bootstrap's, which is chosen against white. */
.tt-wrap.fc .qs-surf{ border-color:var(--fc-hair); background:var(--fc-inset);
          color:var(--fc-ink-2); }
.tt-wrap.fc .qs-surf-lbl{ color:var(--fc-ink); }

/* ==========================================================================================
   Appended 2 Sep 2026. These rules are LAST on purpose: several of the selectors below exist
   more than once earlier in this file (.tt-mark three times, .tt-more and .tt-dayssup twice),
   and in CSS the last copy wins. Editing one of the earlier copies changes nothing on screen.
   See memory/incident_turtle_css_duplicated_region.md.
   ========================================================================================== */

/* The move in official rating since the last run, beside OR on a handicap. Follows the
   `lastor` display toggle, as `cardsnips/jc.html` does on the classic card. */
.tt-wrap.fc .tt-lastor{ font-style:normal; margin-left:3px; color:var(--fc-ink-3);
          font-size:max(11px, calc(11px * var(--fc-scale))); font-variant-numeric:tabular-nums; }

/* Hit areas to the 24px WCAG 2.5.8 minimum, WITHOUT changing the visual size or the row's
   height: the padding grows the pressable box and the negative margin gives the space back to
   the layout. Vertical only, so two controls side by side in a row cannot steal each other's
   presses. The phone row's arithmetic is unchanged. */
.tt-wrap.fc .tt-mark{ padding-top:5px; padding-bottom:5px; margin-top:-5px; margin-bottom:-5px; }
.tt-wrap.fc .tt-more{ padding-top:9px; padding-bottom:3px; margin-bottom:-3px; }
.tt-wrap.fc .tt-rate{ padding-top:4px; padding-bottom:4px; margin-top:-2px; margin-bottom:-2px; }
.tt-wrap.fc .tt-dtab{ padding-top:5px; padding-bottom:5px; margin-top:-1px; margin-bottom:-1px; }
.tt-wrap.fc .tt-chip{ padding-top:3px; padding-bottom:3px; margin-top:-1px; margin-bottom:-1px; }

/* The days-since suffix carries real information and was set at .68em -- 9.9px against a
   13-15px body. The 11px floor is not optional, so it is floored here. Its measured contrast
   against the row (3.97 and 4.24) is still under 4.5:1 and the ink is a separate decision. */
.tt-wrap.fc .tt-dayssup{ font-size:max(11px, calc(11px * var(--fc-scale))); }

/* The muted mark that stands in for a tier-gated value. `.tt-sub` cannot be used for this:
   it sets a MONOSPACE family for form figures and stats, and it is declared after Font
   Awesome's own `.fa` at the same specificity, so an icon wearing it lost the icon font and
   rendered as a replacement box. Colour only. */
.tt-wrap.fc .tt-lockmark{ color:var(--fc-ink-3); }

/* The tooltip states its own typography instead of inheriting the element it sits on. It is
   drawn with ::after, so a tip on an <i> inherited "Font Awesome 7 Pro" and rendered its
   sentence in the icon font; one on an uppercase control shouted. Neither is about the tip. */
.tt-wrap.fc [data-tt-tip]::after{
          font-family:var(--ct-font-sans-serif, system-ui, sans-serif);
          text-transform:none; font-style:normal; letter-spacing:normal; }

/* What an anonymous reader gets where the shortlist, hide, notebook and comment controls sit
   for everyone else. One invitation, in the theme's own accent, rather than four words with
   nothing under them. */
.tt-wrap.fc .tt-actjoin{ display:inline-flex; align-items:center; gap:6px;
          color:var(--fc-accent); font-weight:600;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-actjoin:hover{ text-decoration:underline; }

/* What sits where the brief-bar chips are for everyone else. The bar is a row of chips, so a
   sentence in it needs its own width rather than a chip's. */
.tt-wrap.fc .tt-briefnone{ flex:1 1 100%; margin:0; padding:6px 2px 0;
          color:var(--fc-ink-2); font-size:max(11px, calc(13px * var(--fc-scale)));
          line-height:1.45; }

/* The free insight standing in for the written comment. Same size and measure as the comment
   it replaces so the row does not change shape between tiers; quieter ink because it is a
   counted fact rather than somebody's opinion. */
.tt-wrap.fc .tt-rowinsight{ color:var(--fc-ink-2); }

/* The comment row is hidden until its runner is opened or the card is put in Comments mode,
   and Comments mode is a control that needs Basic -- so a reader below Basic could not reach
   the one free line the card writes about each horse. It shows whenever it is the insight
   standing in for a comment, which is exactly the case where nothing else would reveal it. */
.tt-wrap.fc .tt-rowcomment:has(.tt-rowinsight){ display:block; }

/* A control that cannot deliver keeps its shape and loses its affordance: the figure or name
   is still the point and still reads, but nothing invites a press that would open an empty
   panel. `disabled` carries it to assistive technology; this is the visual half. */
.tt-wrap.fc .tt-rate.is-inert, .tt-wrap.fc .tt-formfig.is-inert,
.tt-wrap.fc .tt-connname.is-inert, .tt-wrap.fc .tt-odds.is-inert{ cursor:default; }
.tt-wrap.fc .tt-formfig.is-inert, .tt-wrap.fc .tt-connname.is-inert{ text-decoration:none; }

/* What the filter panel holds for a reader who cannot use it. The panel is normally two
   screens of controls, so this keeps its own padding rather than inheriting that layout. */
.tt-wrap.fc .tt-filterjoin{ padding:14px 16px 18px; max-width:62ch; }
.tt-wrap.fc .tt-filterjoin .tt-body{ margin:0 0 10px; }

/* The quick filter. A row hidden by it is hidden, not removed, so Clear is exact and nothing
   is re-fetched -- and `!important` because .tt-runner sets its own display. */
.tt-wrap.fc .tt-runner.is-qf-out{ display:none !important; }
.tt-wrap.fc .tt-qf-lead{ margin:0 0 10px; font-weight:600; color:var(--fc-ink); }
.tt-wrap.fc .tt-qf-row{ display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px;
          margin-bottom:10px; }
.tt-wrap.fc .tt-qf-ctl{ display:inline-flex; align-items:center; gap:6px;
          font-size:max(11px, calc(13px * var(--fc-scale))); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-qf-ctl select{ background:var(--fc-inset); color:var(--fc-ink);
          border:1px solid var(--fc-line-2); border-radius:4px; padding:3px 6px;
          font-size:max(11px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-qf-check input{ accent-color:var(--fc-accent); }
.tt-wrap.fc .tt-qf-count{ margin:0 0 12px; min-height:1.2em; font-weight:600;
          color:var(--fc-accent); font-size:max(11px, calc(13px * var(--fc-scale))); }

/* ==========================================================================================
   Signed-out home page: contrast, and one green (2 Sep 2026)
   Measured on /betturtle/ as an anonymous reader. Appended, because several of the selectors
   below exist twice earlier in this file and the last copy wins.
   ========================================================================================== */

/* `--fc-on-thead` is listed in this skill as one of the four tokens that need their own pair
   and was defined NOWHERE: six rules fell through to a hard-coded fallback, one of them
   `var(--fc-accent)`, which is green ink on the green table head. Defined here, once. */
:root{ --fc-on-thead:#ffffff; }

/* The call to action has its own role, so it has its own pair rather than borrowing the
   amber that means "fair" on a rating. Light #c2410c carries white at 5.18 and reads as
   warm against the pale green page; the mustard it replaces was 6.85 and dull. Dark keeps a
   near-black ink at 8.11. */
:root{ --fc-cta:#ff8c1a; --fc-cta-ink:#141005; }
:root:not([data-fc-theme="dark"]){ --fc-cta:#c2410c; --fc-cta-ink:#ffffff; }

/* Black on green, measured 2.48. The step numbers sit on the head green and take the ink
   that green is meant to carry. */
.tt-wrap.fc .home-step-circle{ color:var(--fc-on-thead) !important; }

/* Green on green, measured 1.11. `btn-outline-light` is a WHITE outline button — it exists
   for a dark ground, and the sheet had recoloured its ink to the accent, which is the one
   colour it cannot be when the ground is the head green. */
.tt-wrap.fc .tt-sheet .btn-outline-light{ color:var(--fc-on-thead) !important;
          border-color:var(--fc-on-thead) !important; background:transparent !important; }
.tt-wrap.fc .tt-sheet .btn-outline-light:hover{ background:rgba(255,255,255,.14) !important;
          color:var(--fc-on-thead) !important; }

/* One green for an action, and it is the card's. Three were in play on this page --
   #1f6b12, #007521 and a stray #146c43 -- so the same button read as three different
   products depending which section it was in. */
/* Both selectors on purpose. The earlier rules in this file are `.tt-sheet .btn-success`,
   which is MORE specific than a bare `.tt-wrap.fc .btn-success` -- and among !important
   declarations specificity still decides, so widening the selector alone lost to them. */
.tt-wrap.fc .btn-success, .tt-wrap.fc .btn-primary,
.tt-wrap.fc .tt-sheet .btn-success, .tt-wrap.fc .tt-sheet .btn-primary{
          background:var(--fc-accent) !important; border-color:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; }

/* The primary sign-up, in the CTA colour rather than the warning one. `btn-warning` was
   never a warning here: it is the strongest action on the page. */
.tt-wrap.fc .btn-warning, .tt-wrap.fc .tt-sheet .btn-warning{
          background:var(--fc-cta) !important; border-color:var(--fc-cta) !important;
          color:var(--fc-cta-ink) !important; }
.tt-wrap.fc .btn-outline-warning, .tt-wrap.fc .tt-sheet .btn-outline-warning{
          color:var(--fc-cta) !important; border-color:var(--fc-cta) !important; }

/* The hero's benefit list is written white for a dark hero. Under the sheet the ground is
   near-white, so it was white on #f4f8f4 -- rendered, and invisible. */
.tt-wrap.fc .tt-sheet .hero-benefits li{ color:var(--fc-ink-2) !important; }

/* Step 3 was `color-mix(...)`, which computes to `color(srgb ...)`. That is a valid colour
   the contrast audit cannot parse, so it read as a failure at 1.12 while the ink was already
   white. Tokens the checker can read, and the three circles now share one source. */
.tt-wrap.fc .home-step-circle.step-2{ background:var(--fc-thead); }
.tt-wrap.fc .home-step-circle.step-3{ background:var(--fc-accent); }

/* Step 3 sits on the ACCENT, not the head green, and the accent is a lime in dark — so it
   takes the ink the accent carries rather than the white the other two need. Higher
   specificity than the blanket rule above, and after it. */
.tt-wrap.fc .home-step-circle.step-3{ color:var(--fc-accent-ink) !important; }

/* The six "Everything You Need to Study Form" cards each carry a coloured disc -- indigo,
   amber, emerald, sky, rose -- and the sheet had flattened every glyph inside them to
   `--fc-ink-2`. Five distinct colours were drawn and five identical near-black icons were
   shown, which is why the section read flat.
   Each glyph now takes its own disc's hue. Measured on the 12% disc over the card: the
   full-strength hues fail in light (1.96 amber to 3.85 indigo), so light uses a darkened
   shade of the same hue (4.49 to 6.81) and dark uses a brighter one. A pair each, because a
   colour with one definition is a promise about one ground. */
:root{ --fc-cat-indigo:#818cf8; --fc-cat-amber:#fbbf24; --fc-cat-emerald:#34d399;
       --fc-cat-sky:#38bdf8; --fc-cat-rose:#fb7185; --fc-cat-violet:#a78bfa; }
:root:not([data-fc-theme="dark"]){
       --fc-cat-indigo:#4338ca; --fc-cat-amber:#a16207; --fc-cat-emerald:#047857;
       --fc-cat-sky:#0369a1; --fc-cat-rose:#be123c; --fc-cat-violet:#6d28d9; }

.tt-wrap.fc .home-icon-circle.bg-indigo i{ color:var(--fc-cat-indigo) !important; }
.tt-wrap.fc .home-icon-circle.bg-amber i{ color:var(--fc-cat-amber) !important; }
.tt-wrap.fc .home-icon-circle.bg-emerald i{ color:var(--fc-cat-emerald) !important; }
.tt-wrap.fc .home-icon-circle.bg-sky i{ color:var(--fc-cat-sky) !important; }
.tt-wrap.fc .home-icon-circle.bg-rose i{ color:var(--fc-cat-rose) !important; }
.tt-wrap.fc .home-icon-circle.bg-violet i{ color:var(--fc-cat-violet) !important; }

/* The hero's free offer and its one real runner. The offer was a 12px line among three ticks
   and is the most concrete thing on the page; the runner is the argument the rest of the page
   only describes. */
/* Ink tokens, not `--fc-on-thead`: the hero has no ground of its own, so in light it sits on
   the sheet's near-white and white text is invisible there. The ink tokens follow the ground;
   the head-green ink does not. Same fault as the benefit list above. */
.tt-wrap.fc .hero-free{ color:var(--fc-ink); font-weight:700;
          font-size:max(13px, calc(17px * var(--fc-scale))); }
.tt-wrap.fc .hero-secondary{ color:var(--fc-accent); text-decoration:underline; }
.tt-wrap.fc .hero-kicker{ color:var(--fc-ink-3); text-transform:uppercase;
          letter-spacing:.08em; font-weight:700;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .hero-kicker-sep{ opacity:.55; margin:0 4px; }
.tt-wrap.fc .hero-proof{ border-left:3px solid var(--fc-cta); padding:2px 0 2px 14px;
          max-width:52ch; }
.tt-wrap.fc .hero-proof-head{ color:var(--fc-ink-2); opacity:1; letter-spacing:.06em;
          text-transform:uppercase; font-size:max(11px, calc(11px * var(--fc-scale))); }
.tt-wrap.fc .hero-proof-name{ color:var(--fc-ink); font-weight:700;
          font-family:Oswald,system-ui,sans-serif;
          font-size:max(13px, calc(18px * var(--fc-scale))); }
.tt-wrap.fc .hero-proof-line{ color:var(--fc-ink-2); opacity:1; line-height:1.45;
          font-size:max(11px, calc(14px * var(--fc-scale))); }
.tt-wrap.fc .hero-proof-shoes{ color:var(--fc-ink); font-weight:600;
          font-size:max(11px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .hero-proof-shoes i{ color:var(--fc-good); margin-right:5px; }
.tt-wrap.fc .hero-proof-rate{ color:var(--fc-ink-3); margin-top:6px; line-height:1.45;
          font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .hero-proof-link{ display:inline-block; margin-top:8px; font-weight:600;
          color:var(--fc-accent); text-decoration:underline;
          font-size:max(11px, calc(13px * var(--fc-scale))); }

/* Proof before price. Its own quiet band so it reads as evidence rather than another sell. */
.tt-wrap.fc .home-record-band{ background:var(--fc-surface-2);
          border-top:1px solid var(--fc-hair); border-bottom:1px solid var(--fc-hair); }
.tt-wrap.fc .home-record-band h2{ color:var(--fc-ink); }
.tt-wrap.fc .home-record-band p{ color:var(--fc-ink-2); max-width:62ch; margin-inline:auto; }

/* Example ratings block, shown where the horseshoes are not. */
.tt-wrap.fc .tt-example{ border:1px solid var(--fc-line); border-radius:8px;
  background:var(--fc-surface); padding:10px 12px; margin:0 0 10px; }
.tt-wrap.fc .tt-example-head{ display:flex; align-items:center; gap:8px; margin-bottom:8px; }
.tt-wrap.fc .tt-example-head b{ color:var(--fc-ink); font-size:13px; }
.tt-wrap.fc .tt-example-tag{ font-size:11px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--fc-ink-3); border:1px solid var(--fc-line); border-radius:4px; padding:1px 6px; }
.tt-wrap.fc .tt-example-row{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.tt-wrap.fc .tt-example-name{ display:flex; flex-direction:column; color:var(--fc-ink-3);
  font-size:13px; min-width:120px; }
.tt-wrap.fc .tt-example-name small{ font-size:11px; color:var(--fc-ink-3); opacity:.8; }
.tt-wrap.fc .tt-example-shoes .tt-cellwrap{ background:none; border:0; padding:0; }
.tt-wrap.fc .tt-example-pick{ display:flex; flex-direction:column; align-items:center; gap:2px; }
.tt-wrap.fc .tt-example-pick small{ font-size:11px; color:var(--fc-ink-3); }
.tt-wrap.fc .tt-example-note{ margin:8px 0 0; color:var(--fc-ink-3); font-size:12px; }

/* The pick column without an account: a word, not a padlock. */
.tt-wrap.fc .tt-picklock{ display:inline-block; font-size:11px; letter-spacing:.03em;
  color:var(--fc-ink-3); border:1px dashed var(--fc-line); border-radius:4px;
  padding:1px 5px; white-space:nowrap; }
.tt-wrap.fc .tt-example-shoes .tt-cellwrap > small{ display:block; margin-top:3px;
  font-size:11px; color:var(--fc-ink-3); text-align:center; }

/* The free-cards offer on Today's racing. */
.tt-wrap.fc .tt-offer{ display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  border:1px solid var(--fc-line); border-left:3px solid var(--fc-cta);
  border-radius:8px; background:var(--fc-surface); padding:12px 14px; margin:0 0 12px; }
.tt-wrap.fc .tt-offer-main{ flex:1 1 320px; min-width:0; }
.tt-wrap.fc .tt-offer-lead{ display:block; color:var(--fc-ink); font-size:15px; line-height:1.3; }
.tt-wrap.fc .tt-offer-sub{ margin:3px 0 0; color:var(--fc-ink-3); font-size:13px; }
.tt-wrap.fc .tt-offer-cta{ flex:0 0 auto; white-space:nowrap; }
.tt-wrap.fc .tt-offer.is-count{ border-left-color:var(--fc-line); }
@media (max-width:520px){
  .tt-wrap.fc .tt-offer-cta{ width:100%; text-align:center; }
}

/* Settings sections mix checkbox cards with text, select and select2 fields. The card rules
   further up were written for the checkboxes -- tick, name, help text -- and matched every
   .mb-3, so a text field had its label, its box and its help text flexed into one 230px
   cell: the username box came out 82px wide against 259px on the classic page. Anything
   that is not a .form-check now gets a plain stacked row across the full width. */
/* Selected by what the column CONTAINS, not by what it is not: `:has()` may not be nested
   inside another `:has()`, and `:has(.mb-3:not(:has(.form-check)))` is invalid, so the
   browser dropped the whole rule and the column stayed one grid cell wide. A checkbox
   carries .form-check-input, never .form-control, so this cannot catch the cards. */
.tt-wrap.fc .tt-settings .accordion-body .row > [class*="col"]:has(.form-control),
.tt-wrap.fc .tt-settings .accordion-body .row > [class*="col"]:has(.form-select),
.tt-wrap.fc .tt-settings .accordion-body .row > [class*="col"]:has(.select2-container),
.tt-wrap.fc .tt-quicksettings .accordion-body .row > [class*="col"]:has(.form-control),
.tt-wrap.fc .tt-quicksettings .accordion-body .row > [class*="col"]:has(.form-select){
  display:block; grid-column:1 / -1; }
.tt-wrap.fc .tt-settings .accordion-body .row .mb-3:not(:has(.form-check)),
.tt-wrap.fc .tt-quicksettings .accordion-body .row .mb-3:not(:has(.form-check)){
  display:block; grid-column:1 / -1; margin-bottom:10px !important; }
.tt-wrap.fc .tt-settings .accordion-body .mb-3:not(:has(.form-check)) > label,
.tt-wrap.fc .tt-quicksettings .accordion-body .mb-3:not(:has(.form-check)) > label{
  display:block; margin:0 0 3px; font-weight:600; color:var(--fc-ink); }
.tt-wrap.fc .tt-settings .accordion-body .mb-3:not(:has(.form-check)) .form-control,
.tt-wrap.fc .tt-settings .accordion-body .mb-3:not(:has(.form-check)) .form-select,
.tt-wrap.fc .tt-quicksettings .accordion-body .mb-3:not(:has(.form-check)) .form-control,
.tt-wrap.fc .tt-quicksettings .accordion-body .mb-3:not(:has(.form-check)) .form-select{
  display:block; width:100%; max-width:460px; }
.tt-wrap.fc .tt-settings .accordion-body .mb-3:not(:has(.form-check)) .form-text,
.tt-wrap.fc .tt-settings .accordion-body .mb-3:not(:has(.form-check)) .helptext,
.tt-wrap.fc .tt-quicksettings .accordion-body .mb-3:not(:has(.form-check)) .form-text{
  display:block; width:auto; max-width:60ch; margin:3px 0 0; font-size:12px;
  color:var(--fc-ink-3); }

/* select2 sets its own inline width, so the favourite trainers and jockeys pickers came out
   too narrow to read a name being typed. They hold many chips, so they get more room. */
.tt-wrap.fc .tt-settings .select2-container,
.tt-wrap.fc .tt-quicksettings .select2-container{ width:100% !important; max-width:620px; }
.tt-wrap.fc .tt-settings .select2-container .select2-selection--multiple,
.tt-wrap.fc .tt-quicksettings .select2-container .select2-selection--multiple{
  display:flex; align-items:center; flex-wrap:wrap; gap:4px;
  width:100%; box-sizing:border-box; min-height:42px; padding:4px 6px; }
.tt-wrap.fc .tt-settings .select2-container .select2-search__field,
.tt-wrap.fc .tt-quicksettings .select2-container .select2-search__field{ min-width:24ch; }
/* Crispy does not always wrap a field in a Row: the favourite trainers and jockeys pickers
   are .mb-3 straight inside .accordion-body, so the rules above never reached them and they
   sat in one 293px grid cell -- too narrow to read a name being typed. */
.tt-wrap.fc .tt-settings .accordion-body > .mb-3:not(:has(.form-check)),
.tt-wrap.fc .tt-quicksettings .accordion-body > .mb-3:not(:has(.form-check)){
  display:block; grid-column:1 / -1; margin-bottom:10px !important; }
/* The brand header carries the logo, not a title, so it keeps the sheet surface rather than
   the table-head green every other .card-header gets inside a .tt-sheet: the light-ground
   logo's dark-green wordmark all but vanished on it. */
.tt-wrap.fc .tt-sheet .card-header.bt-brand-header{
  background:var(--fc-surface) !important; border-bottom:1px solid var(--fc-line); }
/* The select2 dropdown is appended to <body>, so `.tt-wrap` never reaches it: on the dark
   theme it stayed white with grey text beneath a dark control. Keyed on the root attribute
   for that reason, not on the wrapper. */
/* --fc-pop-bg, not --fc-surface: the dark surface is rgba(0,0,0,.24), an overlay meant to
   sit on the page's own dark ground. Used on a dropdown that floats over arbitrary content
   it let the page bleed through and the list of names was unreadable. --fc-pop-bg is the
   opaque ground the popovers already use for exactly this. */
:root[data-fc-theme="dark"] .select2-dropdown{
  background-color:var(--fc-pop-bg); border-color:var(--fc-hair); color:var(--fc-ink-2); }
:root[data-fc-theme="dark"] .select2-results__option{
  background-color:transparent; color:var(--fc-ink-2); }
:root[data-fc-theme="dark"] .select2-results__option--highlighted{
  background-color:var(--fc-hover); color:var(--fc-ink-2); }
:root[data-fc-theme="dark"] .select2-search--dropdown .select2-search__field{
  background-color:var(--fc-pop-bg); border-color:var(--fc-hair); color:var(--fc-ink-2); }
.tt-wrap.fc .tt-settings .select2-container .select2-search--inline{ display:flex; flex:1 1 auto; }
.tt-wrap.fc .tt-settings .select2-container .select2-search__field{
  border:0 !important; background:transparent !important; outline:none;
  flex:1 1 auto; margin:0; padding:4px 2px; color:var(--fc-ink); }

/* The A A A control scales the root font too, not only the .tt-* rules.
   Those rules size in px (`calc(12px * var(--fc-scale))`), so they cover the rebuilt turtle
   surfaces and nothing else. On a page that is reused Bootstrap markup -- help, sign out,
   the account pages -- pressing A changed 4 elements out of 255, which reads as a broken
   control. Bootstrap sizes in rem, so scaling the root reaches that text.

   Divided by 1.15 so "normal" stays exactly 16px and no turtle page shifts today; the
   buttons move it either side. `data-fc-size` is only ever set by the turtle shell's own
   script, so this cannot reach the classic site.

   px rules do not compound with a rem change, so the card is not scaled twice. */
:root[data-fc-size]{ font-size: calc(16px * var(--fc-scale) / 1.15); }

/* The "last free card" notice.
   `--fc-warn` is an INK token -- #7a4a00 on light, #ffd479 on dark, flipping the way a
   foreground does -- and .tt-notice.is-warn used it as a BACKGROUND. That put the sheet's
   dark-green ink on a dark brown ground: the bold line measured 2.14:1, the sub-line
   1.16:1 and the icon 1.27:1, so "3 of 3 used" was invisible. `--fc-badge-bg-a` is the
   amber TINT that pairs with it, and over the sheet it leaves the ordinary ink readable. */
.tt-wrap.fc .tt-notice.is-warn{
  background:var(--fc-badge-bg-a); border-color:var(--fc-badge-a); }
.tt-wrap.fc .tt-notice.is-warn > i{ color:var(--fc-badge-a); }

/* The free-card counter on Today's racing, given the same amber so the two surfaces say
   the same thing in the same colour. */
.tt-wrap.fc .tt-offer.is-count{
  background:var(--fc-badge-bg-a); border-color:var(--fc-badge-a);
  border-left:3px solid var(--fc-badge-a); }
/* The number is the thing being counted, so it is read first. */
.tt-wrap.fc .tt-offer-count{ display:inline-block; min-width:1.6em; padding:0 6px; margin-right:2px;
  border-radius:5px; background:var(--fc-badge-a);
  font-size:17px; font-weight:700; text-align:center; line-height:1.45; }
/* The amber ink is a dark brown on light and a bright yellow on dark, so the chip's own
   text has to flip with it: 7.09:1 and 12.25:1, both measured on the composited chip. */
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-offer-count{ color:#ffffff; }
:root[data-fc-theme="dark"] .tt-wrap.fc .tt-offer-count{ color:#1a1400; }
.tt-wrap.fc .bt-plans-link{ color:var(--fc-ink) !important; border-color:var(--fc-line-2) !important; }
.tt-wrap.fc .bt-plans-link:hover{ background:var(--fc-hover) !important; }

/* The plan ladder under a blocked prompt. Three steps, so the customer sees what the next
   one buys rather than only the cheapest. */
.tt-wrap.fc .bt-ladder{ margin:8px 0 12px; }
.tt-wrap.fc .bt-ladder-lead{ margin:0 0 6px; color:var(--fc-ink-3); font-size:13px; }
.tt-wrap.fc .bt-ladder-steps{ list-style:none; margin:0; padding:0;
  display:grid; gap:8px; grid-template-columns:repeat(auto-fit, minmax(210px, 1fr)); }
/* !important because `.content a:not(.btn):not(.btn-link):not(.nav-link):not(.badge)...`
   in the classic sheet buys a class per :not() and out-specifies anything reasonable here.
   The card is a block, not prose, so it should not carry a prose underline. */
.tt-wrap.fc .bt-ladder-step a{ display:block; height:100%; padding:9px 11px;
  border:1px solid var(--fc-line); border-radius:8px; background:var(--fc-surface);
  text-decoration:none !important; }
.tt-wrap.fc .bt-ladder-step a:hover{ border-color:var(--fc-accent); background:var(--fc-hover); }
.tt-wrap.fc .bt-ladder-name{ color:var(--fc-ink); font-size:14px; margin-right:6px; }
.tt-wrap.fc .bt-ladder-price{ color:var(--fc-accent); font-weight:700; font-size:14px; }
.tt-wrap.fc .bt-ladder-price em{ font-style:normal; font-weight:400; font-size:11px;
  color:var(--fc-ink-3); }
.tt-wrap.fc .bt-ladder-gain{ display:block; margin-top:3px; color:var(--fc-ink-3);
  font-size:12px; line-height:1.35; }
.tt-wrap.fc .bt-ladder-builds{ font-style:normal; font-weight:600; color:var(--fc-ink); }
.tt-wrap.fc .bt-ladder-was{ color:var(--fc-ink-3); font-weight:400; margin-right:3px; }
.tt-wrap.fc .bt-ladder-offer{ margin:0 0 8px; color:var(--fc-ink); font-size:13px; }
/* The step above the cheapest is the one that gets overlooked, so it is the one marked. */
.tt-wrap.fc .bt-ladder-step.is-recommended a{ border-color:var(--fc-accent); }
/* A section named but not given: the heading reads normally, the tier is stated beside it. */
.tt-wrap.fc .tt-fsec.is-locked > summary{ color:var(--fc-ink-3); }
.tt-wrap.fc .tt-fsec-tier{ margin-left:6px; padding:1px 6px; border-radius:4px;
  border:1px solid var(--fc-warn-line); background:var(--fc-badge-bg-a); color:var(--fc-badge-a);
  font-size:11px; font-weight:700; letter-spacing:.02em; }

/* A .btn-link inside a sheet is pinned to `color:var(--fc-accent) !important` (line ~1631),
   and the lit-while-open rule paints an expanded button's BACKGROUND with the same accent.
   The result is accent on accent: press "View" on the 14 Day Form Line and the "Hide" it
   becomes cannot be read. The descendant `*` rule does not save it, because the label is a
   bare text node and inherits the button's own colour. One class more than the pinning rule,
   so it wins on specificity rather than on order. */
.tt-wrap.fc .tt-sheet .btn-link[aria-expanded="true"],
.tt-wrap.fc .tt-sheet .btn-link[aria-pressed="true"]{ color:var(--fc-accent-ink) !important; }

/* How it fits today: one line per condition, the verdict carrying the colour. */
.tt-wrap.fc .tt-fits{ display:grid; grid-template-columns:auto 1fr; gap:4px 12px; margin:0; }
.tt-wrap.fc .tt-fit-k{ color:var(--fc-ink-3); font-size:13px; }
.tt-wrap.fc .tt-fit-v{ margin:0; font-size:13px; font-weight:600; }
.tt-wrap.fc .tt-fit-v.is-yes{ color:var(--fc-badge-g); }
.tt-wrap.fc .tt-fit-v.is-no{ color:var(--fc-badge-r); }
.tt-wrap.fc .tt-fit-v.is-unknown{ color:var(--fc-ink-3); font-weight:400; }

/* A brief chip that names a tier instead of opening a panel. */
.tt-wrap.fc .tt-brief-chip.is-inert{ cursor:default; color:var(--fc-ink-3);
    border-style:dashed; }
.tt-wrap.fc .tt-brief-chip.is-inert i{ color:var(--fc-ink-3); }
.tt-wrap.fc .tt-brief-chip.is-inert:hover{ border-color:var(--fc-hair); color:var(--fc-ink-3); }

/* Subscription-plan badges in the menus. One family, up a ladder: the plans are told apart
   by how much ground they carry, not by borrowing the good/fair/poor hues that mean a
   verdict on a runner. Enhanced matches `.tt-fsec-tier`, so a badge in a menu and the pill
   in the drawer are the same mark. Named `tt-plan` because `tt-tier-*` already means a race
   grade on a time pill. Two classes plus the wrapper, to out-specify Bootstrap's own badge
   colouring and the sheet's `.badge.bg-primary` rule. */
.tt-wrap.fc .tt-plan{ border-radius:4px; padding:1px 6px;
          font-size:max(11px, calc(11px * var(--fc-scale))); font-weight:700;
          letter-spacing:.02em; text-transform:none; }
.tt-wrap.fc .tt-plan.tt-plan-free{ background:transparent !important;
          border:1px solid var(--fc-hair) !important; color:var(--fc-ink-3) !important; }
.tt-wrap.fc .tt-plan.tt-plan-basic{ background:var(--fc-inset) !important;
          border:1px solid var(--fc-hair) !important; color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-plan.tt-plan-enhanced{ background:var(--fc-badge-bg-a) !important;
          border:1px solid var(--fc-warn-line) !important; color:var(--fc-badge-a) !important; }
.tt-wrap.fc .tt-plan.tt-plan-pro{ background:var(--fc-accent) !important;
          border:1px solid var(--fc-accent) !important; color:var(--fc-accent-ink) !important; }
.tt-wrap.fc .tt-plan.tt-plan-super{ background:var(--fc-cta) !important;
          border:1px solid var(--fc-cta) !important; color:var(--fc-cta-ink) !important; }

/* The statistics control has two shapes and the Stats Button setting chooses. Only one of
   them is rendered, so neither is hidden by width. */
.tt-wrap.fc .tt-staticons{ display:inline; }
.tt-wrap.fc .tt-statsbtn-narrow{ display:inline-flex; }

/* In form / out of form is back on the NAME, the way the classic card has always marked it
   (Derek, 3 Sep 2026). ONE encoding: the ribbon labels that said the same thing are gone.
   Last in the file deliberately -- `.tt-connname` is declared twice above and the later copy
   wins, so an earlier rule here would never apply. */
.tt-wrap.fc .tt-connname.is-hot,
.tt-wrap.fc .tt-connname.is-cold{ padding:0 4px; border-radius:3px;
          color:var(--fc-hc-ink) !important; text-decoration:none; }
.tt-wrap.fc .tt-connname.is-hot{ background:var(--fc-hc-hot-bg); }
.tt-wrap.fc .tt-connname.is-cold{ background:var(--fc-hc-cold-bg); }
.tt-wrap.fc .tt-connname.is-hot:hover,
.tt-wrap.fc .tt-connname.is-cold:hover{ color:var(--fc-hc-ink) !important; }

/* The classic horse markers, on the turtle ground. Bootstrap's `bg-danger` here is a light
   pink and carried white text at 3.05:1 -- the marker keeps its RED meaning and takes the
   deeper red this theme already uses for "in form", which white clears comfortably. The 11px
   floor applies to the badge and to the first-time-headgear asterisk, which rendered at
   7.8px. Measured 3 Sep 2026. */
.tt-wrap.fc .tt-horseicons{ display:inline-flex; align-items:baseline; gap:3px; margin-left:4px; }
.tt-wrap.fc .tt-horseicons .badge{
          font-size:max(11px, calc(11px * var(--fc-scale))) !important;
          font-weight:700; padding:1px 5px; }
.tt-wrap.fc .tt-horseicons .badge sup{
          font-size:max(11px, calc(9px * var(--fc-scale))); top:0; }
.tt-wrap.fc .tt-horseicons .badge.bg-danger{
          background:var(--fc-hc-hot-bg) !important; color:var(--fc-hc-ink) !important; }
.tt-wrap.fc .tt-horseicons .badge.bg-primary{
          background:var(--fc-hc-cold-bg) !important; color:var(--fc-hc-ink) !important; }
/* (BF) carries `text-dark` with no ground of its own -- near-black on this page, so it was
   there and unreadable. It takes the muted ink instead. */
.tt-wrap.fc .tt-horseicons .badge.text-dark,
.tt-wrap.fc .tt-horseicons .badge.text-secondary{
          background:none !important; color:var(--fc-ink-3) !important; }

/* The trainer and jockey markers take the amber the classic card gives them (`text-warning`
   in `icon_help.py`). `.tt-flag-mark` alone is (0,1,0) and was losing to a red rule earlier
   in this file, so this names its container and sits last. The edge carries the contrast in
   light, where a genuinely golden ink cannot clear 3:1 on its own -- the same treatment the
   stars use. Verified by reading the computed colour back, not by reading the rule. */
.tt-wrap.fc .tt-people .tt-flag-mark,
.tt-wrap.fc .tt-people .tt-flag-mark i{ color:var(--fc-star) !important; }
:root:not([data-fc-theme="dark"]) .tt-wrap.fc .tt-people .tt-flag-mark i{
          text-shadow:var(--fc-star-edge); }

/* Trainer and jockey markers sit under the name rather than trailing it. */
.tt-wrap.fc .tt-connline .tt-flags{ display:inline-flex; margin-top:0; }

/* In form / out of form on the connection's name, the way the row marks it. */
.tt-wrap.fc .tt-hcname.is-hot,
.tt-wrap.fc .tt-hcname.is-cold{ padding:0 4px; border-radius:3px; color:var(--fc-hc-ink) !important; }
.tt-wrap.fc .tt-hcname.is-hot{ background:var(--fc-hc-hot-bg); }
.tt-wrap.fc .tt-hcname.is-cold{ background:var(--fc-hc-cold-bg); }

/* The pick reads by its VALUE, not its position -- the same three states Summary Statistics
   uses (`picktrend`: 1 good, 2 fair, 3 poor). The old accent border marked rank <= 4, which
   said "top four" twice: the number already says it. */
.tt-wrap.fc .tt-pick.is-t1{ border-color:var(--fc-val-g); color:var(--fc-val-g); }
.tt-wrap.fc .tt-pick.is-t2{ border-color:var(--fc-val-a); color:var(--fc-val-a); }
.tt-wrap.fc .tt-pick.is-t3{ border-color:var(--fc-val-r); color:var(--fc-val-r); }

/* Shortlist and bin sit above Study form, each with its own count. The bin arrives with
   Bootstrap's `text-dark`, which is near-black on this ground and effectively invisible, so
   it takes the theme's own ink. Tight against the button: this block is two glyphs. */
.tt-wrap.fc .tt-actmarks{ display:flex; align-items:center; justify-content:center; gap:8px;
          margin:0 0 1px; line-height:1; }
.tt-wrap.fc .tt-actmarks .btn{ font-size:max(11px, calc(14px * var(--fc-scale)));
          line-height:1; padding:0 !important; }
.tt-wrap.fc .tt-actmarks .hide i{ color:var(--fc-ink-2) !important; }
.tt-wrap.fc .tt-actmarks .hide i.fa-trash-restore{ color:var(--fc-val-r) !important; }
/* The count sits BESIDE the glyph, not raised above it -- `sup` lifts it onto the line
   above, which reads as a stray number over the row. */
.tt-wrap.fc .tt-actmarks .btn{ white-space:nowrap; }
.tt-wrap.fc .tt-actmarks sup{ font-size:max(11px, calc(10px * var(--fc-scale)));
          margin-left:2px; vertical-align:baseline; top:0; position:static; }

/* ApexCharts bakes its tooltip theme at chart CREATION from `window.Apex.tooltip.theme`, so a
   chart drawn in one theme keeps that tooltip after the reader switches -- dark ink on a dark
   panel, or the reverse. The stylesheet follows the page live, so it owns these colours. */
.tt-wrap.fc .apexcharts-tooltip{ background:var(--fc-pop-bg) !important;
          color:var(--fc-ink) !important; border:1px solid var(--fc-hair) !important;
          box-shadow:0 2px 10px rgba(0,0,0,.35) !important; }
.tt-wrap.fc .apexcharts-tooltip-title{ background:var(--fc-inset) !important;
          color:var(--fc-ink) !important; border-bottom:1px solid var(--fc-hair) !important; }
.tt-wrap.fc .apexcharts-tooltip-text-y-label,
.tt-wrap.fc .apexcharts-tooltip-text-y-value,
.tt-wrap.fc .apexcharts-tooltip-text-goals-label,
.tt-wrap.fc .apexcharts-tooltip-text-goals-value,
.tt-wrap.fc .apexcharts-tooltip-series-group,
.tt-wrap.fc .apexcharts-tooltip .apexcharts-tooltip-text{ color:var(--fc-ink) !important; }
.tt-wrap.fc .apexcharts-xaxistooltip{ background:var(--fc-pop-bg) !important;
          color:var(--fc-ink) !important; border-color:var(--fc-hair) !important; }
.tt-wrap.fc .apexcharts-xaxistooltip-text{ color:var(--fc-ink) !important; }

/* The shortlist/bin block sat centred in the row, so the space above it grew with the row --
   8px on a short one, 25px on a tall one. Pinned to the top instead. A tipped runner keeps
   its room, because the ribbon is drawn over that corner. */
.tt-wrap.fc .tt-actcell{ align-self:start; align-content:start; }

/* The classic markers are bare glyphs, not chips. In a box they read as badges and every row
   grew a row of little tiles. Ground, border and padding off; the glyph and its colour stay. */
.tt-wrap.fc .tt-people .tt-flags{ display:inline-flex; margin-top:0; }
.tt-wrap.fc .tt-people .tt-flag{ background:none !important; border:0 !important;
          padding:0 !important; border-radius:0 !important; margin-right:5px; }
/* Connections is the drawer, where there is room: the flag keeps its outline AND its words,
   so a phone reader is not left decoding a glyph (Kenny, 3 Sep). */
.tt-wrap.fc .tt-person-head .tt-flag{ gap:4px; margin:0 4px 2px 0; }
.tt-wrap.fc .tt-person-head .tt-flag-hot{ color:var(--fc-hot); border-color:currentColor; }
.tt-wrap.fc .tt-person-head .tt-flag-cold{ color:var(--fc-cold-ink); border-color:currentColor; }

/* Tip badges sit inline before the horse's name. */
.tt-wrap.fc .tt-underform{ display:flex; flex-wrap:wrap; align-items:center; gap:4px;
          margin-top:2px; }
.tt-wrap.fc .tt-underform:empty{ display:none; margin:0; }

/* The draw pill takes its record's RAG (Kenny, 3 Sep) -- it kept the accent whatever the
   record said, so the band was only ever in the tooltip. Grounds, not inks: the pill is small
   and a coloured ground reads at a glance where coloured text does not. */
.tt-wrap.fc .tt-draw.is-g{ background:var(--fc-val-g) !important; color:var(--fc-pill-ink) !important; }
.tt-wrap.fc .tt-draw.is-a{ background:var(--fc-val-a) !important; color:var(--fc-pill-ink) !important; }
.tt-wrap.fc .tt-draw.is-r{ background:var(--fc-val-r) !important; color:var(--fc-pill-ink) !important; }

/* Out of form is a quieter fact than in form, and a solid saturated blue read as a text
   selection rather than a marking (Kenny, 3 Sep). Cold takes a tint with coloured ink; hot
   keeps its solid ground, so the two are told apart by weight as well as hue and the
   stronger signal stays the more prominent one. */
.tt-wrap.fc .tt-connname.is-cold,
.tt-wrap.fc .tt-hcname.is-cold{
          background:color-mix(in srgb, var(--fc-hc-cold-bg) 38%, transparent) !important;
          color:var(--fc-cold-ink) !important;
          box-shadow:inset 0 0 0 1px var(--fc-hc-cold-bg); }
.tt-wrap.fc .tt-connname.is-cold:hover{ color:var(--fc-cold-ink) !important; }
/* `--fc-cold` is the row's cold BLUE and reads 3.56:1 on its own 20% tint in light, so the
   ink needs a darker shade of the same hue there. Dark keeps the bright one. */
:root{ --fc-cold-ink:#17455c; }
:root[data-fc-theme="dark"]{ --fc-cold-ink:#9ac6e2; }
@media (prefers-color-scheme: dark){ :root:not([data-fc-theme="light"]){ --fc-cold-ink:#9ac6e2; } }

/* WIN TIP arrives as `badge-outline-primary` -- Bootstrap's indigo on no ground, 3.31:1 on the
   light row. It is the strongest mark on the card, so it takes a filled accent chip. */
/* Win tip is blue and first handicap is red, as they have always been (Kenny, 3 Sep). The
   Bootstrap outline versions read 3.31:1 on the light row, so they are filled with the theme's
   own blue and red, which carry white in both themes. Any other badge keeps the accent. */
.tt-wrap.fc .tt-underform > .badge{ background:var(--fc-accent) !important;
          color:var(--fc-accent-ink) !important; border-color:var(--fc-accent) !important; }
.tt-wrap.fc .tt-underform > .badge-outline-primary,
.tt-wrap.fc .badge.badge-outline-primary{ background:var(--fc-hc-cold-bg) !important;
          color:var(--fc-hc-ink) !important; border-color:var(--fc-hc-cold-bg) !important; }
.tt-wrap.fc .tt-underform > .tt-horsemark,
.tt-wrap.fc .badge.tt-horsemark{ background:var(--fc-hc-hot-bg) !important;
          color:var(--fc-hc-ink) !important; border-color:var(--fc-hc-hot-bg) !important; }
/* Bootstrap's yellow is a LIGHT ground -- the one badge in this family that keeps dark ink.
   White on it read 1.59:1. */
.tt-wrap.fc .tt-underform .badge.bg-warning,
.tt-wrap.fc .tt-horseicons .badge.bg-warning{ color:#12241a !important; }
/* The shortlist count carries `text-warning`, a pale amber that reads 1.82:1 on the light row. */
.tt-wrap.fc .tt-actmarks sup{ color:var(--fc-ink-2) !important; }

/* Short words on a phone, the full ones where there is room. */
.tt-wrap.fc .tt-narrow{ display:none; }
@media (max-width:767px){
  .tt-wrap.fc .tt-wide{ display:none; }
  .tt-wrap.fc .tt-narrow{ display:inline; }
}
/* Shortlist and bin ride with the name rather than under the pick, which they overlapped on
   a phone. Pushed to the end of the name line so they sit top right of the row. */
/* The name and its days figure share one line: the name ellipsises, the figure never wraps. */
.tt-wrap.fc .tt-nameline{ flex-wrap:nowrap; }
.tt-wrap.fc .tt-nameline .tt-name{ flex:0 1 auto; }
.tt-wrap.fc .tt-actcell .tt-actmarks{ display:flex; align-items:center;
          justify-content:center; gap:10px; margin-bottom:2px; grid-column:1 / -1; }

/* On a phone the name line is a narrow cell, so "rightmost" inside it still leaves 60-odd
   pixels unused. Lift the marks out of flow to the row's own top right instead -- clear of
   the pick, which is what they overlapped before. Desktop keeps them in the line, where the
   far right belongs to Study form. */
@media (max-width:767px){
  .tt-wrap.fc .tt-runner{ position:relative; }
  .tt-wrap.fc .tt-actcell .tt-actmarks{ position:absolute; top:0; right:6px;
            margin:0; z-index:4; flex-wrap:nowrap; white-space:nowrap; line-height:1;
            align-items:flex-start; }
  .tt-wrap.fc .tt-actcell .tt-actmarks .btn{ min-height:36px; }
}

/* Sex is the single letter on a phone, as every racecard writes it. */
@media (max-width:767px){ .tt-wrap.fc .tt-sexlong{ display:none; } }
@media (min-width:768px){ .tt-wrap.fc .tt-sexshort{ display:none; } }

@media (max-width:767px){
  /* The heart and bin take the top-right corner, so the price drops clear of them. */
  .tt-wrap.fc .tt-r1 > [style*="grid-area:odds"]{ margin-top:10px; }
  /* Shortlist is the heart on a phone -- the word is the widest thing in that action row. */
  .tt-wrap.fc .tt-a-like .tt-actlbl{ display:none; }
}

/* The inline line is the server's HTML, so it paints BEFORE any script runs -- adding a class
   in JS was always one frame too late and the row visibly drew its line twice on refresh
   (Kenny, 3 Sep). CSS applies before first paint, so above the width where Apex draws the row
   charts (992px, the breakpoint the Charts button uses) the fallback starts hidden and the
   Apex canvas is the only thing ever painted. Below that width, and wherever Apex is not
   available at all, `.tt-noapex` hands it straight back. */
@media (min-width:700px){
  .tt-wrap.fc .tt-runners:not(.tt-noapex) .tt-rowchart > .tt-rowspark{ visibility:hidden; }
  .tt-wrap.fc .tt-runners.tt-noapex .tt-rowchart > .tt-rowspark{ visibility:visible; }
}
.tt-wrap.fc .tt-rowchart.is-claimed > .tt-rowspark{ visibility:hidden; }

/* The people's marks wear the horse's tag styling; only in/out of form takes a colour, and it
   is the same pair the row and the drawer already use. */
.tt-wrap.fc .tt-labels .tt-tag i{ font-size:.9em; margin-right:1px; }
.tt-wrap.fc .tt-tag-hot{ color:var(--fc-hot); border-color:currentColor; }
.tt-wrap.fc .tt-tag-cold{ color:var(--fc-cold-ink); border-color:currentColor; }
.tt-wrap.fc .tt-runners.is-nomarks .tt-horseicons,
.tt-wrap.fc .tt-runners.is-nomarks .tt-people .tt-flag,
.tt-wrap.fc .tt-runners.is-nomarks .tt-labels .tt-tag,
.tt-wrap.fc .tt-runners.is-nomarks .tt-horsemark{ display:none !important; }
.tt-wrap.fc .tt-runners.is-nomarks .tt-connname.is-hot,
.tt-wrap.fc .tt-runners.is-nomarks .tt-connname.is-cold{ background:none !important;
          box-shadow:none !important; color:inherit !important; padding:0 !important; }

/* A lit tool takes the ink that belongs on the accent, not the page's. `.is-lit` was picking
   up the accent GROUND from the pressed-button rule and leaving near-black text on it. */
.tt-wrap.fc .tt-tool.is-lit,
.tt-wrap.fc .tt-tool.is-lit i{ color:var(--fc-accent-ink) !important; }

/* Tablet portrait. The nine-column row needs 1,024px of grid before the name and the
   connections reach their minimums, which is the whole viewport -- so the name column sat at
   130px and clipped eleven of twelve horses. The horseshoe strip takes a line of its own
   here, as it does below 992px, and the width it frees goes to the name and the people. */
@media (min-width:992px) and (max-width:1099.98px){
  .tt-wrap.fc .tt-r1{
          grid-template-columns:46px 42px minmax(140px,1.5fr) minmax(120px,1fr) 180px 34px 84px 46px 72px;
          grid-template-areas:
            "cloth silk  name  people shoes pick odds pos act"
            "rates rates rates rates  shoes pick odds pos act"; }
  .tt-wrap.fc .tt-runhead{ gap:0 10px;
          grid-template-columns:46px 42px minmax(140px,1.5fr) minmax(120px,1fr) 180px 34px 84px 46px 72px; }
  .tt-wrap.fc .tt-runhead-shoes{ grid-column:5; }
  .tt-wrap.fc .tt-runhead-pick{ grid-column:6; }
  /* Both keep their width instead of stretching across the line they now have to themselves;
     the headings sit above the shoes because the two strips share the row's left edge. */
  .tt-wrap.fc .tt-rates{ max-width:430px; }
}

/* A tooltip has to cover something, so it must read as a layer over the page rather than a
   panel in it: a hairline border and a soft shadow on a near-white ground left the controls
   it covered looking like they were inside it. */
.tt-wrap.fc [data-tt-tip]::after{ border-color:var(--fc-line-2);
          box-shadow:0 10px 28px rgba(0,0,0,.42), 0 2px 6px rgba(0,0,0,.28); }
/* Downward wherever the space above belongs to something the reader is identifying the row
   by: the drawer tabs sit under the action icons, and the form figure and days count sit
   under the horse's name. The same flip the cloth and the view bar already use. */
.tt-wrap.fc .tt-dtabs [data-tt-tip]::after,
.tt-wrap.fc .tt-formfig[data-tt-tip]::after,
.tt-wrap.fc .tt-nameline [data-tt-tip]::after{ bottom:auto; top:calc(100% + 6px); }

/* Tablet landscape. The desktop row fits here, but only just: on the desktop column widths
   the name and the connections both sit on their minimums and thirteen names clip. The
   fixed columns are tighter so the flexible pool has something to give them. */
@media (min-width:1100px) and (max-width:1199.98px){
  .tt-wrap.fc .tt-r1{
          grid-template-columns:46px 42px minmax(150px,1.4fr) minmax(150px,1fr) 236px 40px 100px 56px 80px;
          grid-template-areas:
            "cloth silk  name  people shoes pick odds pos act"
            "rates rates rates rates  shoes pick odds pos act"; }
  .tt-wrap.fc .tt-runhead{ gap:0 8px;
          grid-template-columns:46px 42px minmax(150px,1.4fr) minmax(150px,1fr) 236px 40px 100px 56px 80px; }
  .tt-wrap.fc .tt-runhead-shoes{ grid-column:5; }
  .tt-wrap.fc .tt-runhead-pick{ grid-column:6; }
}

/* The headings share the row's column gap, so each label sits over the column it names. */
@media (min-width:992px){ .tt-wrap.fc .tt-runhead{ column-gap:10px; } }

/* Trainer above jockey from 992 up. Side by side they had 66px each at desktop and 86px on a
   tablet, and every name wrapped -- several onto four lines. */
@media (min-width:992px){
  .tt-wrap.fc .tt-people{ grid-template-columns:1fr; }
}

/* The stats strip carries a comment button of its own, so the named one beside Shortlist is
   the same control twice. It goes wherever the strip is on screen -- which is 768px up, and
   only when Popup Stats is on, because the strip is not rendered at all when it is off. */
@media (min-width:768px){
  .tt-wrap.fc .tt-commentacts:has(.tt-staticons:not(.d-none)) .tt-a-comment{ display:none; }
}

/* The notebook mark on the badge line, and the label in the drawer. Both follow the note
   button's own icon -- solid once the horse is in the notebook -- so neither costs a query
   and both change the moment the button is pressed. */
.tt-wrap.fc .tt-notemark,
.tt-wrap.fc .tt-tag-note{ display:none; }
.tt-wrap.fc .tt-runner:has(i[class*="note-"].fas) .tt-notemark{ display:inline-flex;
          align-items:center; color:var(--fc-val-a); }
.tt-wrap.fc .tt-runner:has(i[class*="note-"].fas) .tt-tag-note{ display:inline-flex;
          align-items:center; gap:4px; color:var(--fc-val-a); border-color:var(--fc-val-a); }

/* A tooltip is centred on its control, which runs it off the page when the control sits at an
   edge -- the drawer's first tab lost 47px of its text off the left. These anchor to the edge
   they are nearest instead, so the text starts or ends with the control. */
.tt-wrap.fc .tt-dtabs [data-tt-tip]::after,
.tt-wrap.fc .tt-flag[data-tt-tip]::after{ left:0; transform:none; }

/* PICK sits on the same line as the horseshoe letters: they are buttons carrying 4px of
   vertical padding and it is not, which left its text riding 4px higher. */
.tt-wrap.fc .tt-runhead-pick{ padding:4px 0; }

/* A statistic that opens a popover is a control, so it reads as one: the cell's own type and
   colour with a dotted underline, the same way the form figures do, and the accent on hover or
   keyboard focus. Colour alone would not carry it -- these sit in a dense table and half the
   readers are on a touch screen with no hover at all. */
.tt-wrap.fc .tt-sheet a.btn-link[data-bs-toggle="popover"]{
          border-bottom:1px dotted var(--fc-ink-3); text-decoration:none; }
.tt-wrap.fc .tt-sheet a.btn-link[data-bs-toggle="popover"]:hover,
.tt-wrap.fc .tt-sheet a.btn-link[data-bs-toggle="popover"]:focus-visible{
          color:var(--fc-accent) !important; border-bottom-color:var(--fc-accent); }

/* The comment on a run reads at the size of the run it belongs to. Bootstrap's .small put it
   at 12px against 15px cells, with lh-sm tightening a paragraph that is meant to be read. */
.tt-wrap.fc .tt-formfull .bt-childrow-body,
.tt-wrap.fc .tt-sheet .bt-childrow-body{
          font-size:max(11px, calc(13px * var(--fc-scale))) !important; line-height:1.45; }

/* Marks that sit in the badge strip and beside the actions: the row's own type, no button
   chrome, and the accent when they can be pressed. */
.tt-wrap.fc .tt-stripmark,
.tt-wrap.fc .tt-markbtn{ background:none; border:0; padding:0; font:inherit; line-height:1;
          display:inline-flex; align-items:center; color:var(--fc-val-a); }
.tt-wrap.fc .tt-markbtn{ cursor:pointer; }
.tt-wrap.fc .tt-stripmark.is-sys{ color:var(--fc-val-a); }
.tt-wrap.fc .tt-markbtn:hover,
.tt-wrap.fc .tt-markbtn:focus-visible{ color:var(--fc-accent); }
.tt-wrap.fc .tt-intelwand{ margin-right:2px; color:var(--fc-linkish); }
.tt-wrap.fc .tt-intelwand:hover,
.tt-wrap.fc .tt-intelwand:focus-visible{ color:var(--fc-accent); }
.tt-wrap.fc .tt-intelwand[data-tt-tip]::after{ left:0; transform:none; }

/* 80:20 pane — the pool list. One block, at the end, so it is the copy that wins. */
/* The rating sits beside the name, not at the far edge of a full-width panel. */
.tt-wrap.fc .tt-eighty{ list-style:none; margin:4px 0 8px; padding:0; counter-reset:tt-eighty;
          max-width:min(100%, 26rem); }
.tt-wrap.fc .tt-eighty li{ display:flex; align-items:baseline; gap:8px; padding:4px 0; border-bottom:1px solid var(--fc-hair); counter-increment:tt-eighty; font-size:max(11px, calc(13px * var(--fc-scale))); }
.tt-wrap.fc .tt-eighty li::before{ content:counter(tt-eighty); min-width:1.4em; color:var(--fc-ink-3); font-variant-numeric:tabular-nums; }
.tt-wrap.fc .tt-eighty-name{ flex:1 1 auto; color:var(--fc-ink); font-weight:500; }
.tt-wrap.fc .tt-eighty-rating{ color:var(--fc-ink-2); font-variant-numeric:tabular-nums; }
.tt-wrap.fc .tt-eighty-act{ margin:2px 0 8px; }
.tt-wrap.fc .tt-eighty-act .tt-tool{ font-size:max(11px, calc(12px * var(--fc-scale))); }

/* The age and the weight are one fact, so they wrap together rather than splitting 11-4. */
.tt-wrap.fc .tt-agewt{ white-space:nowrap; }

/* The rating, its last-OR move and its rank are one thing and wrap as one. */
.tt-wrap.fc .tt-ratefig{ display:inline-flex; align-items:baseline; white-space:nowrap; }

/* The inline drawing fills its tile the way the Apex one does, rather than sitting at its
   natural 50px in the middle of a tile three times that wide. */
.tt-wrap.fc .tt-rate .tt-rowchart > .tt-rowspark{ width:100%; height:22px; }

/* The Stats button borrows the classic behaviour from cards.js, so it also picks up the
   classic sizing and a hard-coded blue active state. Restate both in tokens. The padding
   carries !important because the classic rule does. */
.tt-wrap.fc .tt-statsbtn-narrow.bt-stats-btn{ padding:3px 10px !important; border-radius:5px;
          font-size:calc(12px * var(--fc-scale)); line-height:normal; margin-top:6px; }
.tt-wrap.fc .tt-statsbtn-narrow.bt-stats-btn.active,
.tt-wrap.fc .tt-statsbtn-narrow.bt-stats-btn.active:hover,
.tt-wrap.fc .tt-statsbtn-narrow.bt-stats-btn.active:focus{
          background:var(--fc-accent) !important; color:var(--fc-accent-ink) !important;
          border-color:var(--fc-accent) !important; }
/* The lazily loaded strip sits beside the button, not under it. */
.tt-wrap.fc .tt-statsicons-lazy{ margin-left:6px; }
.tt-wrap.fc .tt-statsicons-lazy.d-none{ display:none !important; }

/* The saving on the pricing table. Its own rule hard-codes a light-green ground with dark
   green ink, which the dark shell leaves as ink alone: 1.05:1, on the figure that carries
   the discount. Tokens, per theme. */
.tt-wrap.fc .save-pill{ background:var(--fc-badge-bg-g) !important; color:var(--fc-badge-g) !important;
          border-color:var(--fc-badge-bg-g) !important; }

/* Native select options are painted by the platform from the control's own ink. */
.tt-wrap.fc select option,
.tt-wrap.fc .tt-sheet select option{ color:var(--fc-ink); background:var(--fc-surface); }

/* Courses as a scrolling strip. The tail always overflows on a phone -- a Saturday is seven
   to ten meetings and the longest name runs fifteen characters -- so All is first and never
   scrolls out of reach, and the chosen chip is scrolled into view when it is set. */
.tt-wrap.fc .tt-courses{ display:flex; gap:6px; overflow-x:auto; scrollbar-width:thin;
          -webkit-overflow-scrolling:touch; padding:2px 0; margin:0 0 2px;
          scroll-snap-type:x proximity; }
.tt-wrap.fc .tt-coursechip{ flex:0 0 auto; scroll-snap-align:start; white-space:nowrap;
          padding:4px 10px; border-radius:999px; cursor:pointer;
          border:1px solid var(--fc-line); background:var(--fc-inset); color:var(--fc-ink-2);
          font:inherit; font-size:max(11px, calc(12px * var(--fc-scale))); }
.tt-wrap.fc .tt-coursechip:hover{ background:var(--fc-hover); color:var(--fc-ink); }
.tt-wrap.fc .tt-coursechip.is-on{ background:var(--fc-accent); color:var(--fc-accent-ink);
          border-color:var(--fc-accent); font-weight:600; }
/* Its own class, not `hidden`: the race filter already owns that attribute on a meeting and
   the two must not fight over it. */
.tt-wrap.fc .tt-meeting.is-coursehidden{ display:none; }

/* The homepage day: courses as chips, wrapping rather than scrolling -- this one is a list
   to read, not a control to operate, so nothing may be hidden off the right-hand edge. */
.tt-wrap.fc .tt-homecourses{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 10px; }
/* The sheet's link rule carries three classes of :not(), so a bare selector loses to it. */
.tt-wrap.fc .tt-homecourses a.tt-coursechip{ text-decoration:none !important;
          color:var(--fc-ink-2); }
.tt-wrap.fc .tt-homecourses a.tt-coursechip:hover{ color:var(--fc-ink);
          background:var(--fc-hover); }
.tt-wrap.fc .tt-chipcount{ color:var(--fc-ink-3); font-variant-numeric:tabular-nums;
          margin-left:4px; }
.tt-wrap.fc .tt-coursechip.is-on .tt-chipcount{ color:var(--fc-accent-ink); }
