/* ── TrueTail: Ink & Copper ───────────────────────────────────────────────
   Deep teal-ink base, molten copper accent, bone-white text. No green, no red -
   results read as copper (won) / gunmetal (lost) / bone (push), never traffic-
   light colors. THE FOX (brand mark, F:\Wynfall\TrueTail-Brain\Brand) is the
   logo/nav/loader identity as of brand-fox1; the comet-tail motif (bright head,
   fading tail) remains the language for sparklines, seal stamps, and empty
   states - it was never the brand mark, just the house "verify" visual idiom. */
:root {
  --bg: #0A1214;
  --bg-panel: #10191C;
  --bg-panel-2: #142124;
  --line: rgba(200, 230, 235, 0.08);
  --line-strong: rgba(200, 230, 235, 0.16);

  --accent: #D97B4A;            /* molten copper base */
  --accent-highlight: #E89A5E;  /* copper highlight */
  --accent-dim: rgba(217, 123, 74, 0.14);
  --accent-gradient: linear-gradient(180deg, var(--accent-highlight) 0%, var(--accent) 100%);

  --text: #F1EDE6;              /* bone-white */
  --text-dim: #B9C7CA;
  --text-faint: #7E959B;        /* steel-cyan, secondary text */

  /* LOST / negative / metadata. Raised from #5A6468 on 2026-07-28: that value measured 2.94:1 on
     panels, failing WCAG AA body text (4.5:1) and missing even the large-text floor, while wins in
     copper measured 7.82:1 - a 2.6x legibility gap on a product that promises misses stand beside
     wins, and it also carried .flash-error. #9CA8AD is 7.32:1, deliberately level with copper
     rather than merely legal. See DESIGN.md "Losses read as loudly as wins". */
  --gunmetal: #9CA8AD;
  /* The old dark value, kept ONLY where gunmetal is a FILL behind lighter content rather than a
     text or border colour: .legal-rg-panel sets bone text on it, and the win-prob bar uses it as
     a track. Lightening those would break contrast or make a background shout. */
  --gunmetal-fill: #5A6468;
  --bone: #F1EDE6;              /* PUSH */
  --copper: var(--accent);      /* WON */

  --red: var(--gunmetal);       /* legacy var name kept - no red anywhere in this theme */
  --green: var(--accent);       /* legacy var name kept - no green anywhere in this theme */
  --amber: #E89A5E;

  /* Tote Board type system (DESIGN.md, chosen 2026-07-28) - the numeral IS the design, so it
     gets a mechanically-drawn tabular monospace with real character (Martian Mono); interface
     text gets a grotesk with engineering restraint (Archivo). Both self-hosted variable fonts,
     SIL Open Font License. Instrument Serif/Sans and IBM Plex Mono retired with the broadsheet.
     --display is now an ALIAS for --sans - headings are Archivo, not a second face to load -
     kept as its own token only so the ~35 existing var(--display) call sites (h1-h3, taglines,
     seals, ticket stubs) don't all need touching to get the new type. */
  --mono: 'Martian Mono', 'SFMono-Regular', Consolas, monospace;
  --sans: 'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --display: var(--sans);

  /* The comet-tail mark, inlined as an SVG data URI so it can be reused as a CSS background
     (nav wordmark glyph, empty-state accent) without a network request. Three tapered, fading
     tail segments streaking up into a checkmark head - copper on transparent. */
  --comet-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M8 56 L26 38' stroke='%23D97B4A' stroke-width='3.5' stroke-linecap='round' opacity='0.25'/%3E%3Cpath d='M16 52 L32 36' stroke='%23D97B4A' stroke-width='4.5' stroke-linecap='round' opacity='0.45'/%3E%3Cpath d='M24 48 L38 34' stroke='%23E89A5E' stroke-width='5.5' stroke-linecap='round' opacity='0.7'/%3E%3Ccircle cx='45' cy='27' r='9' fill='%23E89A5E'/%3E%3Ccircle cx='48' cy='24' r='3.5' fill='%23F1EDE6' opacity='0.85'/%3E%3C/svg%3E");

  /* BROADSHEET WAVE 1: the exact token names DESIGN.md specifies, aliased onto the values
     above (never re-defining the color - one source of truth). New Broadsheet component
     classes at the bottom of this file read these names; existing rules keep reading the
     names above untouched. */
  --ink: var(--bg);
  --panel: var(--bg-panel);
  --copper: var(--accent);
  --copper-2: var(--accent-highlight);
  --rule: var(--line-strong);
}

/* Self-hosted, SIL Open Font License. Martian Mono (Evil Martians) - a tabular, mechanically
   drawn monospace carrying every numeral/odd/unit/table figure on the board, without exception.
   It is a WIDE face by design (the family spans Condensed through Semi Wide on a font-stretch
   axis) - dense contexts (record tables, the countable bar's rate line, anything at 390px) use
   a tighter font-stretch/letter-spacing rather than the default width; see the classes that set
   font-stretch below. Archivo (Omnibus-Type) is the interface grotesk for headings and body
   text. Both are VARIABLE fonts, so font-weight is declared as a RANGE, not a fixed value. */
@font-face {
  font-family: 'Martian Mono';
  src: url('/fonts/martian-mono-var.woff2') format('woff2-variations'), url('/fonts/martian-mono-var.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('/fonts/archivo-var.woff2') format('woff2-variations'), url('/fonts/archivo-var.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  background-image: radial-gradient(ellipse 900px 500px at 15% -10%, rgba(217,123,74,0.05), transparent 60%);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
}

a { color: var(--accent-highlight); text-decoration: none; }
a:hover { text-decoration: underline; color: var(--accent-highlight); }

/* Redesign wave: fixed grain overlay breaks the flat-vector digital sterility of a pure
   dark-teal field. Small tiled SVG noise, copper-tinted at near-zero opacity so it reads as
   texture rather than pattern; pointer-events:none keeps it fully inert. Off entirely for
   prefers-reduced-motion out of caution (some users pair reduced-motion with reduced-effects),
   but this is static (no animation) so it stays on by default. */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: 2000; pointer-events: none;
  opacity: 0.5; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}

/* Redesign wave: a single global focus-visible ring (copper, matches the identity) for every
   interactive element that doesn't already define its own focus treatment - keyboard nav gets
   a visible, on-brand indicator everywhere instead of relying on browser defaults. */
a:focus-visible, button:focus-visible, .btn:focus-visible,
input:focus-visible, textarea:focus-visible, select:focus-visible,
summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent-highlight);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Redesign wave: skip-to-content link, keyboard-only. Visually hidden until focused, then
   pinned top-left over the topbar. */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 3000;
  background: var(--bg-panel-2); color: var(--text); border: 1px solid var(--accent);
  padding: 10px 16px; border-radius: 0 0 8px 0; font-family: var(--mono); font-size: 12px;
}
.skip-link:focus { left: 0; }

.label {
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 11px;
  color: var(--text-faint);
}

/* THE BOARD VOICE. Retiring the serif was right, but leaving headings at grotesk 400 with
   POSITIVE tracking left them reading as default-dashboard: the exact "stock component inside a
   committed form" lapse the 2026-07-28 critique named. A board sets its headings heavy and tight,
   not light and airy. */
h1, h2, h3 { font-family: var(--display); font-weight: 600; letter-spacing: -0.015em; text-wrap: balance; }
p { text-wrap: pretty; }

/* Editorial header signature: left-weighted heading with a hairline ledger rule extending
   the rest of the row width - "the racing form, reborn". Used on every page header. */
.page-head {
  display: flex;
  align-items: baseline;
  gap: 18px;
  margin-bottom: 4px;
}
.page-head h1 { margin-bottom: 0; white-space: nowrap; }
.page-head .ledger-rule { flex: 1; height: 1px; background: var(--line-strong); transform: translateY(-2px); }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 28px;
  padding-top: max(16px, env(safe-area-inset-top, 0px));
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--bg-panel) 0%, var(--bg) 140%);
  flex-wrap: wrap;
  gap: 10px;
}

/* Nav brand: THE FOX horizontal lockup (mark + wordmark), inlined as SVG in header.ejs so the
   l-flick tail can animate. Swap target if the owner ever wants the no-flick wordmark variant:
   the <path class="brand-flick"> inside the inlined SVG in views/partials/header.ejs. */
.brand-link {
  display: inline-flex;
  align-items: center;
  transition: transform 150ms ease;
}
.brand-link:hover { transform: translateY(-1px); }
.brand-group { display: flex; align-items: center; min-height: 48px; }
.brand-lockup { height: 46px; width: auto; display: block; }
/* At topbar scale the wordmark's tail-flick reads as a smudge - hide it here only
   (the full lockup with the flick still renders at hero/OG sizes). */
.topbar .brand-flick { display: none; }
.topbar .tagline {
  color: var(--text-faint);
  font-size: 15px;
  font-family: var(--display);
  font-style: italic;
  margin-left: 16px;
  padding-left: 16px;
  border-left: 1px solid var(--line);
  line-height: 1;
  white-space: nowrap;
}
@media (max-width: 560px) { .topbar .tagline { display: none; } }

/* Scoped to DIRECT nav>a children only (the logged-out Pricing/Sign in pair) - the logged-in
   .nav-grouped nav wraps its links in .nav-cluster divs, so this must not leak into it (it
   used to, via higher specificity than .nav-cluster a, silently defeating the nav retypeset). */
.topbar > nav > a {
  color: var(--text-dim);
  margin-left: 18px;
  font-size: 13px;
  font-family: var(--mono);
}
.topbar > nav > a:hover { color: var(--accent-highlight); text-decoration: none; }

.wrap { max-width: 1080px; margin: 0 auto; padding: 32px 24px 80px; }
.wrap-narrow { max-width: 460px; margin: 0 auto; padding: 60px 24px; }

h1 { font-size: 34px; margin: 0 0 6px; color: var(--text); }
h2 { font-size: 21px; margin: 0 0 14px; color: var(--text); }
.sub { color: var(--text-faint); margin: 0 0 26px; font-size: 14px; font-family: var(--display); font-style: italic; }

/* Thin ledger rule between rows, used in place of heavy card borders where a list reads
   better as a form/ledger than as boxed panels. */
.ledger-list > * { border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 10px; }
.ledger-list > *:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }

.panel {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 22px;
  margin-bottom: 18px;
  position: relative;
}
.panel-tight { padding: 14px 18px; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
@media (max-width: 720px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

label { display: block; font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); margin: 14px 0 6px; }
label:first-child { margin-top: 0; }

input[type=text], input[type=email], input[type=password], input[type=number], input[type=date], input[type=url], textarea, select {
  width: 100%;
  background: var(--bg-panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  padding: 9px 11px;
  font-size: 14px;
  font-family: var(--sans);
}
textarea { resize: vertical; min-height: 70px; }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim); }

/* numbers/odds/units always mono, even inside otherwise-sans inputs */
input[name="units"], input[name="odds_american"], input[name="unit_value"], input[name="bankroll"],
input[name="line"], input[name$="_units"], input[name$="_cap_units"] { font-family: var(--mono); }

.btn {
  display: inline-block;
  font-family: var(--mono);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 9px 18px;
  border-radius: 6px;
  border: 1px solid var(--accent);
  background: linear-gradient(180deg, rgba(232,154,94,0.18), rgba(217,123,74,0.10));
  color: var(--accent-highlight);
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { background: linear-gradient(180deg, rgba(232,154,94,0.30), rgba(217,123,74,0.18)); text-decoration: none; }
.btn-ghost { border-color: var(--line-strong); background: transparent; color: var(--text-dim); }
.btn-ghost:hover { border-color: var(--text-faint); background: transparent; }
.btn-danger { border-color: var(--gunmetal); color: var(--gunmetal); background: rgba(90,100,104,0.12); }
.btn-sm { padding: 5px 11px; font-size: 11px; }

form { margin: 0; }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 9px 11px; border-bottom: 1px solid var(--line); }
th { font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-faint); font-weight: 400; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: rgba(200,230,235,0.02); }

/* numbers/odds/units in tables always mono */
td.mono, .mono { font-family: var(--mono); }

.badge { font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; padding: 3px 8px; border-radius: 4px; border: 1px solid var(--line-strong); color: var(--text-faint); }
.badge-pending { color: var(--amber); border-color: var(--amber); }
.badge-won { color: var(--copper); border-color: var(--copper); }
.badge-lost { color: var(--gunmetal); border-color: var(--gunmetal); }
.badge-push, .badge-void { color: var(--bone); border-color: rgba(241,237,230,0.4); }

/* ── Seal stamps: graded results get a circular pressed-seal badge instead of
   a flat pill. Engraved ring + faint radial texture + slight rotation, with a
   300ms press-in on first paint (respects reduced-motion). */
.seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border-width: 2px;
  transform: rotate(-4deg);
  padding: 7px 10px;
  background-image: radial-gradient(circle at 35% 30%, rgba(255,255,255,0.10), transparent 60%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.05), 0 1px 2px rgba(0,0,0,0.4);
  animation: seal-press 300ms ease-out;
}
.seal-sm { padding: 3px 7px; font-size: 9px; }
.seal.badge-won { box-shadow: inset 0 0 0 1px rgba(232,154,94,0.25), 0 1px 4px rgba(217,123,74,0.25); }
.seal.badge-lost { box-shadow: inset 0 0 0 1px rgba(90,100,104,0.3), 0 1px 4px rgba(0,0,0,0.3); }
.seal.badge-push, .seal.badge-void { box-shadow: inset 0 0 0 1px rgba(241,237,230,0.15), 0 1px 4px rgba(0,0,0,0.3); }

@keyframes seal-press {
  0% { transform: rotate(-4deg) scale(1.6); opacity: 0; }
  60% { transform: rotate(-4deg) scale(0.94); opacity: 1; }
  100% { transform: rotate(-4deg) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .seal { animation: none; }
}

.flash { font-family: var(--mono); font-size: 13px; padding: 10px 14px; border-radius: 6px; margin-bottom: 20px; }
.flash-error { color: var(--gunmetal); border: 1px solid var(--gunmetal); background: rgba(90,100,104,0.10); }
.flash-ok { color: var(--accent-highlight); border: 1px solid var(--accent); background: rgba(217,123,74,0.08); }
.flash-warn { color: var(--amber); border: 1px solid var(--amber); background: rgba(232,154,94,0.08); }

.leg-row { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 90px 1fr auto; gap: 8px; align-items: end; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px dashed var(--line); }
.leg-row label { margin: 0 0 4px; }
@media (max-width: 900px) { .leg-row { grid-template-columns: 1fr 1fr; } }

.muted { color: var(--text-faint); font-size: 12px; }
.row-actions { display: flex; gap: 8px; }
.empty { color: var(--text-faint); font-size: 13px; padding: 20px 0; text-align: center; }
.empty.comet-empty::before {
  content: '';
  display: block;
  width: 40px; height: 40px;
  margin: 0 auto 8px;
  background-image: var(--comet-mark);
  background-size: contain;
  background-repeat: no-repeat;
  opacity: 0.5;
}

.footer-line { color: var(--text-faint); font-size: 11.5px; text-align: center; padding: 24px 16px 8px; font-family: var(--mono); }
.sample-badge { color: var(--amber); border-color: var(--amber); }
.checkbox-row { display: flex; align-items: center; gap: 8px; margin: 10px 0; }
.checkbox-row input { width: auto; }
.checkbox-row label { margin: 0; }

/* Comet sparkline head: leading point brighter than the fading gradient tail. */
.comet-head { fill: var(--accent-highlight); filter: drop-shadow(0 0 3px rgba(232,154,94,0.8)); }

/* ── Onboarding (4-step tailored setup) ─────────────────────────────────── */
.onboarding-steps { display: flex; gap: 6px; margin-bottom: 22px; }
.onboarding-steps .step-dot {
  flex: 1; height: 4px; border-radius: 2px; background: var(--line-strong);
}
.onboarding-steps .step-dot.done, .onboarding-steps .step-dot.active { background: var(--accent-gradient); }
.choice-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; margin: 10px 0 6px; }
.choice-card {
  border: 1px solid var(--line-strong); border-radius: 8px; padding: 10px 12px;
  background: var(--bg-panel-2); cursor: pointer; font-size: 12.5px; display: flex; align-items: flex-start; gap: 8px;
  word-break: break-word; line-height: 1.35;
}
.choice-card input { margin-top: 2px; flex-shrink: 0; }
.choice-card:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent-highlight); }
.choice-card input { width: auto; margin: 0; }
.choice-group-label { font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint); margin: 18px 0 4px; }
.choice-group-label:first-child { margin-top: 0; }

/* engraved texture strip used behind panel headings on graded/report surfaces */
.engraved-rule { height: 1px; margin: 14px 0; background: linear-gradient(90deg, transparent, var(--line-strong) 20%, var(--line-strong) 80%, transparent); }

/* ── THE ENGINES wave: orchestrated page-load motion, one signature per screen ────────────
   Header ledger-rule draws left-to-right on first paint; stat numerals "count-settle" (a
   brief scale/opacity settle, not a numeric tween - simple, once); Best Bets cards enter with
   a short staggered rise. All once-only (animation runs on load, not on every interaction),
   and all respect prefers-reduced-motion. */
.page-head .ledger-rule {
  animation: ledger-draw 520ms cubic-bezier(0.22, 1, 0.36, 1) both;
  transform-origin: left center;
}
@keyframes ledger-draw {
  0% { transform: scaleX(0) translateY(-2px); opacity: 0; }
  100% { transform: scaleX(1) translateY(-2px); opacity: 1; }
}
.ev-stagger .ev-card {
  animation: card-rise 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: calc(var(--i, 0) * 40ms);
}
@keyframes card-rise {
  0% { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .page-head .ledger-rule, .ev-stagger .ev-card { animation: none; }
}

/* Best Bets +EV card layout */
.ev-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.ev-num-wrap { text-align: right; flex-shrink: 0; }
.ev-num { font-size: 32px; color: var(--accent-highlight); }
.ev-card-line { margin-top: 8px; font-size: 13px; color: var(--text-dim); }
.show-math { margin-top: 10px; font-family: var(--mono); font-size: 12px; }
.show-math summary { cursor: pointer; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em; font-size: 11px; }
.show-math summary:hover { color: var(--accent-highlight); }
.show-math table { margin-top: 4px; }

/* THE FOX loader (brand-fox1): fox-mark-small draws in as a stroke outline (tail-first read,
   using the SVG pathLength=1000 trick so stroke-dasharray math doesn't need the real path
   length), then cross-fades to the flat fill - the "verified/settled" beat - and loops for an
   indefinite loading state, per Motion-Identity.md section 1/4. */
.fox-loader { display: inline-flex; align-items: center; justify-content: center; padding: 30px; }
.fox-loader svg { width: 64px; height: 64px; }
.fox-loader .fox-loader-stroke {
  fill: none; stroke: var(--accent-highlight); stroke-width: 26; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1000; stroke-dashoffset: 1000;
  filter: drop-shadow(0 0 3px rgba(232,154,94,0.6));
  animation: fox-draw 1600ms ease-in-out infinite;
}
.fox-loader .fox-loader-fill {
  fill: var(--accent); opacity: 0;
  animation: fox-fill 1600ms ease-in-out infinite;
}
@keyframes fox-draw {
  0% { stroke-dashoffset: 1000; opacity: 1; }
  55% { stroke-dashoffset: 0; opacity: 1; }
  68% { opacity: 0; }
  100% { opacity: 0; stroke-dashoffset: -1000; }
}
@keyframes fox-fill {
  0%, 58% { opacity: 0; }
  70%, 88% { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .fox-loader .fox-loader-stroke { display: none; }
  .fox-loader .fox-loader-fill { opacity: 1; animation: none; }
}

/* THE FOX assembly moment (brand-fox1, Motion-Identity.md section 2): a simplified but
   spec-faithful version - the shipped lockup SVG isn't split per-glyph, so the wordmark fades+
   rises as one group rather than per-character, the fox mark then cross-fades in from 60% scale,
   and the l-flick tail settles last with a small overshoot-and-settle. ~800ms total, one-shot.
   Shared by the login stacked lockup and the landing page's horizontal hero lockup - both
   contain a .lockup-word-wrap / .lockup-fox-wrap / .lockup-flick, scoped under .assembly-lockup. */
.assembly-lockup svg { width: 100%; height: auto; display: block; }
.assembly-lockup .lockup-word-wrap {
  opacity: 0; transform: translateY(8px);
  animation: assembly-word 300ms cubic-bezier(0.22, 1, 0.36, 1) 0ms both;
}
.assembly-lockup .lockup-fox-wrap {
  opacity: 0; transform: scale(0.6);
  transform-box: fill-box; transform-origin: center;
  animation: assembly-fox 350ms cubic-bezier(0.34, 1.56, 0.64, 1) 280ms both;
}
.assembly-lockup .lockup-flick {
  opacity: 0; transform: scale(0.7);
  transform-box: fill-box; transform-origin: center;
  animation: assembly-flick 200ms cubic-bezier(0.34, 1.56, 0.64, 1) 650ms both;
}
@keyframes assembly-word {
  0% { opacity: 0; transform: translateY(8px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes assembly-fox {
  0% { opacity: 0; transform: scale(0.6); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes assembly-flick {
  0% { opacity: 0; transform: scale(0.7); }
  70% { opacity: 1; transform: scale(1.05); }
  100% { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .assembly-lockup .lockup-word-wrap, .assembly-lockup .lockup-fox-wrap, .assembly-lockup .lockup-flick {
    animation: none !important; opacity: 1; transform: none;
  }
}
.login-lockup { max-width: 260px; margin: 0 auto 22px; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ── Public landing page v2 (landing-fox2) ─────────────────────────────────────────────────
   Signature: THE TAIL-THREAD - one continuous copper SVG path running from the hero fox's
   tail down through every section, drawn progressively via scroll (public/js/landing-thread.js,
   vanilla, no deps). Editorial asymmetry throughout: no centered-everything, no floating blobs,
   no purple. Everything below is scoped to .landing-thread-scope so it never leaks into the
   authenticated app screens. */
.landing-thread-scope { position: relative; max-width: 1080px; margin: 0 auto; padding: 0 24px; overflow: hidden; }

.thread-layer { position: absolute; top: 0; left: 50%; transform: translateX(-50%); width: 100%; max-width: 1080px; height: 100%; z-index: 0; pointer-events: none; }
.thread-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/* 0.5 read as a drawn LINE crossing the page rather than a watermark behind it, so anywhere the
   fixed-geometry path passed near content it looked like a defect. This is decoration stretched
   over variable-height content, so it will always pass near something on some viewport: keeping
   it subordinate is what makes that harmless. DESIGN.md: copper is foil, used sparingly. */
.thread-path { opacity: 0.3; }
.thread-mobile { display: none; }
@media (max-width: 760px) {
  .thread-desktop { display: none; }
  .thread-mobile { display: block; }
}
@media (prefers-reduced-motion: reduce) {
  .thread-path { stroke-dashoffset: 0 !important; }
}

/* ── Hero: the fox owns the moment - big mark left-of-center, headline column right, on
   desktop; centered stack on mobile. Ambient constellation + bloom stay inside the fox's own
   box (the hard-cutoff bloom bug is a known class - never repeat it: bloom falloff completes
   well inside its container). */
.landing-hero2 {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: minmax(280px, 46vh) 1fr; align-items: center; gap: 48px;
  min-height: 86vh; padding: 90px 0 40px;
}
.hero-fox-col { position: relative; display: flex; flex-direction: column; align-items: center; justify-self: start; }
.hero-fox-lockup { width: 100%; max-width: 420px; position: relative; z-index: 2; }
.hero-fox-lockup svg { width: 100%; height: auto; display: block; }
.hero-bloom {
  position: absolute; inset: -10% -10% -10% -10%; z-index: 1; pointer-events: none;
  background: radial-gradient(ellipse 60% 55% at 50% 45%, rgba(217,123,74,0.16), rgba(217,123,74,0.05) 55%, transparent 78%);
}
.hero-constellation { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.hero-constellation span {
  position: absolute; width: 2.5px; height: 2.5px; border-radius: 50%;
  background: var(--accent-highlight); opacity: 0.35;
  animation: constellation-drift 14s ease-in-out infinite;
}
.hero-constellation span:nth-child(1) { top: 12%; left: 18%; animation-delay: 0s; }
.hero-constellation span:nth-child(2) { top: 68%; left: 8%; animation-delay: 3.2s; }
.hero-constellation span:nth-child(3) { top: 22%; left: 82%; animation-delay: 6.4s; }
.hero-constellation span:nth-child(4) { top: 78%; left: 74%; animation-delay: 9.6s; }
@keyframes constellation-drift {
  0%, 100% { transform: translate(0, 0); opacity: 0.25; }
  50% { transform: translate(3px, -4px); opacity: 0.5; }
}
@media (prefers-reduced-motion: reduce) { .hero-constellation span { animation: none; } }

.hero-wordmark-small { margin-top: 14px; display: flex; align-items: center; justify-content: center; opacity: 0; animation: hero-reveal 420ms cubic-bezier(0.22,1,0.36,1) 900ms both; }
.hero-wordmark-small svg { display: none; }
.hero-wordmark-text { font-family: var(--display); font-size: 18px; letter-spacing: 0.03em; color: var(--text-dim); }

.hero-copy-col { position: relative; z-index: 1; justify-self: start; max-width: 560px; }
.hero-h1 { display: flex; flex-direction: column; margin: 0 0 14px; }
.hero-h1 .hero-line {
  font-family: var(--display); font-size: clamp(34px, 5vw, 58px); line-height: 1.08; color: var(--text);
  opacity: 0; transform: translateY(14px);
  animation: hero-reveal 420ms cubic-bezier(0.22,1,0.36,1) both;
}
.hero-line-1 { animation-delay: 950ms; }
.hero-line-2 { animation-delay: 1030ms; }
.hero-tagline {
  font-family: var(--display); font-style: italic; color: var(--accent-highlight);
  font-size: clamp(18px, 2vw, 22px); margin: 0 0 16px;
}
.hero-sub { color: var(--text-dim); font-size: 15.5px; max-width: 480px; margin: 0 0 26px; }
.hero-reveal { opacity: 0; transform: translateY(10px); animation: hero-reveal 380ms cubic-bezier(0.22,1,0.36,1) 1140ms both; }
.hero-sub.hero-reveal { animation-delay: 1200ms; }
.hero-cta-row.hero-reveal { animation-delay: 1260ms; }
@keyframes hero-reveal {
  0% { opacity: 0; transform: translateY(10px); }
  100% { opacity: 1; transform: translateY(0); }
}
.hero-cta-row { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
/* THE PRIMARY ACTION (visual polish pass, 2026-07-27): was the same translucent-outline .btn
   used everywhere else on the site, which made the single most important action on the page
   its weakest-looking element. Copper is the foil per DESIGN.md ("use like foil - sparingly,
   where it means something") - this is exactly that moment, so it gets the one filled-copper
   treatment on the site rather than a global .btn change (which would repaint every button in
   the app). Ink-dark text on the copper gradient for real contrast, not another tint of copper
   on copper. */
.btn-hero-cta {
  font-size: 13px; padding: 14px 28px;
  background: var(--accent-gradient);
  border-color: var(--copper);
  color: var(--ink);
  font-weight: 600;
}
.btn-hero-cta:hover { background: var(--copper); }
.hero-cta-quiet { color: var(--text-faint); font-family: var(--mono); font-size: 13px; }
.hero-cta-quiet:hover { color: var(--accent-highlight); }

/* Tail-first load: fox body cross-fades in, tail settles last with a slight overshoot -
   approximation of the assembly-lockup pattern (filled paths, no reliable stroke-trace). */
.hero-fox-lockup .hero-fox-body { opacity: 0; transform-box: fill-box; transform-origin: center; animation: fox-body-in 380ms cubic-bezier(0.22,1,0.36,1) 80ms both; }
.hero-fox-lockup .hero-fox-tail { opacity: 0; transform-box: fill-box; transform-origin: 70% 10%; transform: translate(6px, -10px) scale(0.94); animation: fox-tail-settle 420ms cubic-bezier(0.34,1.56,0.64,1) 360ms both; }
.hero-fox-lockup .hero-fox-tail-hi { opacity: 0; transform-box: fill-box; transform-origin: 70% 10%; transform: translate(6px, -10px) scale(0.94); animation: fox-tail-settle 420ms cubic-bezier(0.34,1.56,0.64,1) 420ms both; }
@keyframes fox-body-in { 0% { opacity: 0; } 100% { opacity: 1; } }
@keyframes fox-tail-settle {
  0% { opacity: 0; transform: translate(6px, -10px) scale(0.94); }
  70% { opacity: 1; transform: translate(-1px, 2px) scale(1.02); }
  100% { opacity: 1; transform: translate(0, 0) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-h1 .hero-line, .hero-reveal, .hero-wordmark-small, .hero-fox-lockup .hero-fox-body, .hero-fox-lockup .hero-fox-tail, .hero-fox-lockup .hero-fox-tail-hi {
    animation: none !important; opacity: 1; transform: none;
  }
}

@media (max-width: 900px) {
  .landing-hero2 { grid-template-columns: 1fr; text-align: center; min-height: 0; padding: 56px 0 30px; }
  .hero-fox-col { justify-self: center; margin-bottom: 8px; }
  .hero-fox-lockup { max-width: 220px; }
  .hero-copy-col { justify-self: center; max-width: 480px; }
  .hero-h1 { align-items: center; }
  .hero-cta-row { justify-content: center; }
}

/* ── Proof sections: alternating editorial rows along the thread, ledger hairline top. ── */
.proof-row {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 220px 1fr; gap: 40px; align-items: center;
  max-width: 920px; margin: 0 auto; padding: 64px 0;
}
.proof-row-reverse { grid-template-columns: 1fr 220px; }
.proof-row-reverse .proof-visual { order: 2; }
.proof-row-reverse .proof-copy { order: 1; }
.proof-visual { text-align: center; }
.proof-copy .engraved-rule { margin: 0 0 12px; }
.proof-copy h3 { font-size: 19px; margin: 0 0 8px; }
.proof-copy p { color: var(--text-dim); font-size: 14.5px; line-height: 1.55; margin: 0; max-width: 460px; }
.proof-row-reverse .proof-copy p { margin-left: auto; }
@media (max-width: 720px) {
  .proof-row, .proof-row-reverse { grid-template-columns: 1fr; text-align: center; padding: 40px 0; gap: 18px; }
  .proof-row-reverse .proof-visual, .proof-row-reverse .proof-copy { order: initial; }
  .proof-copy p, .proof-row-reverse .proof-copy p { margin: 0 auto; }
}

.proof-num-big { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 56px; color: var(--accent-highlight); line-height: 1; }
.proof-math {
  font-family: var(--mono); font-size: 12px; color: var(--text-faint); margin-top: 10px;
  opacity: 0; transform: translateY(4px);
}
[data-proof].in-view .proof-math { opacity: 1; transform: translateY(0); transition: opacity 400ms cubic-bezier(0.22,1,0.36,1) 650ms, transform 400ms cubic-bezier(0.22,1,0.36,1) 650ms; }

.comet-sparkline { width: 200px; height: 72px; }
.comet-tail { stroke-dasharray: 260; stroke-dashoffset: 260; }
[data-proof].in-view .comet-tail { transition: stroke-dashoffset 600ms cubic-bezier(0.22,1,0.36,1); stroke-dashoffset: 0; }
.comet-head { fill: var(--accent-highlight); opacity: 0; filter: drop-shadow(0 0 4px rgba(232,154,94,0.8)); }
[data-proof].in-view .comet-head { transition: opacity 200ms ease 560ms; opacity: 1; }
.proof-num-label { display: block; margin-top: 4px; font-family: var(--mono); font-size: 22px; color: var(--accent-highlight); }

.seal.seal-big { font-family: var(--display); font-size: 22px; padding: 20px 26px; animation: none; opacity: 0; transform: rotate(-4deg) scale(1.5); }
[data-proof].in-view .seal.seal-big { animation: seal-press 380ms cubic-bezier(0.22,1,0.36,1) both; }
@media (prefers-reduced-motion: reduce) {
  .seal-big { opacity: 1 !important; transform: rotate(-4deg) scale(1) !important; }
}

/* ── How it works: racing-form numbered strip. ── */
.how-strip {
  position: relative; z-index: 1; max-width: 920px; margin: 20px auto 10px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px;
  border-top: 1px solid var(--line-strong); padding-top: 32px;
}
.how-step { text-align: left; }
.how-num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 44px; color: var(--accent-highlight); line-height: 1; margin-bottom: 6px; }
.how-step p { color: var(--text-dim); font-size: 15px; margin: 0; }
@media (max-width: 720px) { .how-strip { grid-template-columns: 1fr; text-align: center; } .how-step { text-align: center; } }

/* ── Waitlist: the thread's destination, a small fox settled beside the form. ── */
.landing-status {
  position: relative; z-index: 1;
  max-width: 460px; margin: 60px auto 60px; padding: 30px 24px 26px; text-align: center;
  border: 1px solid var(--line-strong); border-radius: 10px; background: var(--bg-panel);
}
.thread-resolve { display: flex; justify-content: center; margin-bottom: 10px; }
.waitlist-fox { width: 34px; height: 34px; opacity: 0.9; }
.landing-status .status-line { font-family: var(--mono); font-size: 12px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 16px; }
.landing-status form { display: flex; gap: 8px; flex-wrap: wrap; }
.landing-status input[type="email"] { flex: 1; min-width: 160px; margin: 0; }
@media (max-width: 480px) {
  .landing-status form { flex-direction: column; }
  .landing-status input[type="email"] { min-width: 0; }
}
.landing-status .hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.landing-status .waitlist-ok { color: var(--accent-highlight); font-family: var(--mono); font-size: 13px; }
.landing-status .waitlist-invite { margin-top: 14px; font-size: 12.5px; color: var(--text-faint); }
.waitlist-fox.fox-nod { animation: fox-nod 500ms cubic-bezier(0.22,1,0.36,1); }
@keyframes fox-nod {
  0% { transform: translateY(0) rotate(0deg); }
  35% { transform: translateY(2px) rotate(-3deg); }
  70% { transform: translateY(0) rotate(1deg); }
  100% { transform: translateY(0) rotate(0deg); }
}
@media (prefers-reduced-motion: reduce) { .waitlist-fox.fox-nod { animation: none; } }

.landing-footer {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  color: var(--text-faint); font-size: 11.5px; font-family: var(--mono);
  padding: 8px 16px 0;
}
.landing-footer svg { height: 14px; width: auto; color: var(--text-faint); }

/* ── Ease wave: tooltips, tail confirm sheet, thread onboarding, guide page ──────────── */

/* Plain-English jargon tooltip: a dotted-underline "?" badge, CSS-only popover on
   hover/focus (attr(data-tip) content) so it works without JS and is keyboard-reachable. */
.tt-tip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%;
  border: 1px dotted var(--accent-highlight); color: var(--accent-highlight);
  font-size: 10px; font-family: var(--mono); cursor: help; position: relative;
  margin-left: 3px; vertical-align: middle;
}
.tt-tip:hover::after, .tt-tip:focus::after {
  content: attr(data-tip);
  position: absolute; left: 50%; bottom: 130%; transform: translateX(-50%);
  width: 220px; max-width: 60vw; padding: 8px 10px; border-radius: 6px;
  background: var(--bg-panel-2); border: 1px solid var(--line-strong);
  color: var(--text-dim); font-size: 11.5px; font-family: var(--sans);
  line-height: 1.4; white-space: normal; z-index: 40;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
}

/* Tail confirm sheet: a small centered modal, same panel language as everywhere else. Rebuilt
   2026-07-28 (DESIGN.md "What retires" owner ruling) - was "a generic add-item form" (heading,
   muted caption, three stacked full-width labeled inputs, two stacked buttons). The three
   editable fields are now one ruled register row - small mono uppercase labels over narrow
   tabular-mono inputs, the same k/v grammar as every other figure on the board - instead of a
   generic vertical form. */
.tail-sheet-overlay {
  position: fixed; inset: 0; background: rgba(6,10,11,0.72); backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center; z-index: 100; padding: 16px;
}
.tail-sheet { max-width: 360px; width: 100%; }
.tail-sheet-pick { margin: 2px 0 0; font-size: 19px; }
.tail-sheet-sub { margin: 4px 0 0; }
.tail-sheet-fields {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
.tail-sheet-field label {
  margin: 0 0 6px; font-size: 10px;
}
.tail-sheet-field input { padding: 8px 6px; text-align: center; }
/* Units and odds are numerals - tabular mono, per the board's numeral rule. Book is a name,
   not a number, so it keeps the ordinary interface face. */
.tail-sheet-field input.tail-units, .tail-sheet-field input.tail-odds { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.tail-sheet-actions { display: flex; gap: 10px; margin-top: 16px; }
/* 44px minimum touch target at every breakpoint (DESIGN.md rule of restraint), scoped to this
   dialog's own buttons rather than a sitewide .btn change. */
.tail-sheet-actions .btn { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.tail-btn { display: inline-block; }
.tailing-count { font-size: 11px; color: var(--text-faint); font-family: var(--mono); margin-left: 6px; }

/* Preflight fix 1: the leg-status table cell was stacking a badge + a note (tt-tip/auto-graded/
   self-graded) inline in the same flow, which wrapped and overlapped at narrow widths. A tiny
   flex column with a small gap keeps them stacked cleanly at every width instead. */
.leg-status-cell { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.leg-status-cell .tailing-count { margin-left: 0; }

/* GRADE PROVENANCE: gunmetal (never copper/won-colored - this is metadata, not a result) chip
   marking a manually-graded slip/leg. Deliberately quiet - auto-graded is the norm and gets no
   badge at all. */
.self-graded-chip {
  display: inline-flex; align-items: center; gap: 4px; color: var(--gunmetal);
  border: 1px solid var(--line-strong); border-radius: 4px; padding: 1px 6px;
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.05em;
}

/* ── Onboarding redesign: the thread draws one segment per completed step, resolving
   into the fox mark at finish. Reuses the landing's thread language, scoped to onboarding. */
.thread-progress { display: flex; align-items: center; gap: 4px; margin-bottom: 26px; }
.thread-progress .thread-seg {
  flex: 1; height: 3px; border-radius: 2px; background: var(--line-strong);
  position: relative; overflow: hidden;
}
.thread-progress .thread-seg::after {
  content: ''; position: absolute; inset: 0; background: var(--accent-gradient);
  transform: scaleX(0); transform-origin: left; transition: transform 500ms cubic-bezier(0.22,1,0.36,1);
}
.thread-progress .thread-seg.done::after, .thread-progress .thread-seg.active::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .thread-progress .thread-seg::after { transition: none; } }

.onboarding-question { font-family: var(--display); font-size: 26px; margin: 0 0 6px; }
.onboarding-micro { color: var(--text-dim); font-size: 13.5px; margin: 0 0 18px; }
.choice-card-lg {
  border: 1px solid var(--line-strong); border-radius: 10px; padding: 16px 14px;
  background: var(--bg-panel-2); cursor: pointer; font-size: 14px;
  display: flex; align-items: center; gap: 10px; min-height: 52px; transition: border-color 150ms, background 150ms;
}
.choice-card-lg:has(input:checked) { border-color: var(--accent); background: var(--accent-dim); color: var(--accent-highlight); }
.choice-card-lg input { width: auto; margin: 0; accent-color: var(--accent); }
.onboarding-finish-fox { width: 64px; height: 64px; margin: 0 auto 14px; display: block; opacity: 0; }
.onboarding-finish-fox.show { opacity: 1; animation: fox-nod 600ms cubic-bezier(0.22,1,0.36,1); }
@media (prefers-reduced-motion: reduce) { .onboarding-finish-fox.show { animation: none; } }

/* ── Interior elevation wave (interior-wave5): editorial compositions replacing card grids on
   the dashboard, Best Bets, slip detail, capper cards, and leaderboard. Shared primitives below;
   per-screen rules follow in their own blocks. ───────────────────────────────────────────── */

/* Folio numbers: small mono section numerals, ledger-catalog read, never decorative. */
.folio { font-family: var(--mono); font-size: 11px; color: var(--text-faint); letter-spacing: 0.04em; }

/* Numeric micro-rules: right-aligned, decimal-tabular number columns. */
.num-col { font-family: var(--mono); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.num-pos { color: var(--accent-highlight); }
.num-neg { color: var(--gunmetal); }
.num-ctx { color: var(--text-faint); font-size: 0.85em; }

/* The evidence thread: a thin copper rule that runs through a claim's supporting evidence,
   drawn once (400ms) on data resolve, then sits as a quiet structural rule. Reduced-motion:
   static (no draw animation, just present). */
.evidence-thread { position: relative; }
.evidence-thread::before {
  content: '';
  position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--accent-gradient); border-radius: 1px;
  transform: scaleY(0); transform-origin: top;
  animation: thread-draw 400ms cubic-bezier(0.22,1,0.36,1) both;
}
@keyframes thread-draw { 0% { transform: scaleY(0); opacity: 0.3; } 100% { transform: scaleY(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .evidence-thread::before { animation: none; transform: scaleY(1); } }
.evidence-thread-h { position: relative; padding-top: 10px; }
.evidence-thread-h::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--accent-gradient); border-radius: 1px;
  transform: scaleX(0); transform-origin: left;
  animation: thread-draw-h 400ms cubic-bezier(0.22,1,0.36,1) both;
}
@keyframes thread-draw-h { 0% { transform: scaleX(0); opacity: 0.3; } 100% { transform: scaleX(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .evidence-thread-h::before { animation: none; transform: scaleX(1); } }

/* VERIFIED seal: small copper stamp, appears only when n>=30 AND CLV>0 (capper cards). */
.verified-seal {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--accent-highlight); border: 1px solid var(--accent); border-radius: 20px;
  padding: 3px 9px 3px 7px; transform: rotate(-2deg);
}
.verified-seal .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent-highlight); box-shadow: 0 0 4px rgba(232,154,94,0.8); }

/* Freshness dot: a small pulsing indicator next to a rank/timestamp. */
.freshness-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-highlight); box-shadow: 0 0 4px rgba(232,154,94,0.7); margin-right: 5px; }

/* ── Dashboard: command ledger ──────────────────────────────────────────── */
.truth-panel { padding-top: 26px; }
.truth-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 32px; align-items: start; }
@media (max-width: 860px) { .truth-grid { grid-template-columns: 1fr; } }
.truth-figure { font-family: var(--mono); font-size: 58px; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; }
.truth-rows { margin-top: 18px; }
.truth-row { display: flex; justify-content: space-between; align-items: baseline; padding: 7px 0; border-bottom: 1px solid var(--line); }
.truth-row:last-child { border-bottom: none; }
.truth-row .label { margin: 0; }
.truth-row .val { font-family: var(--mono); font-size: 15px; font-variant-numeric: tabular-nums; }
.since-visit { margin-top: 18px; padding-top: 12px; border-top: 1px dashed var(--line-strong); }
.since-visit ul { list-style: none; margin: 8px 0 0; padding: 0; }
.since-visit li { font-size: 12.5px; color: var(--text-dim); padding: 3px 0; }
.since-visit li .mono { color: var(--text-faint); }

/* Rebuilt 2026-07-28 (DESIGN.md "What retires" owner ruling) - was a vertical timeline with a
   colored dot per row, "the same DOM shape as a support-ticket log." Now a ruled register row:
   the number that moved (the realized result once graded, the stake while still pending) leads
   each row as the loudest element, tabular mono - the seal is the status mark, not a dot. */
.activity-ledger { display: flex; flex-direction: column; }
.activity-row {
  /* minmax, not a flat px: Martian Mono is a WIDE face (measured: "-2.00u" alone needs 63px at
     1rem/600) - a fixed track clips a real result, minmax(auto) lets rare wide values (a big
     bankroll's "+100.00u") grow the column instead of ever overflowing it. */
  display: grid; grid-template-columns: minmax(60px, auto) 1fr; gap: 12px;
  padding: 10px 8px; border-bottom: 1px dotted var(--line-strong); margin: 0 -8px;
  border-radius: 4px; transition: background 120ms ease;
}
.activity-row:last-child { border-bottom: none; }
.activity-row:hover { background: rgba(200,230,235,0.03); }
.today-strip-row, .week-ahead-edges, .exceptions-list li { transition: background 120ms ease; }
.today-strip-row:hover { background: rgba(200,230,235,0.03); border-radius: 6px; }
.activity-row-figure {
  font-family: var(--mono); font-size: 0.95rem; font-weight: 600; line-height: 1.4;
  letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: var(--text-faint); text-align: right;
}
.activity-row.is-won .activity-row-figure { color: var(--copper-2); }
.activity-row.is-lost .activity-row-figure { color: var(--gunmetal); }
.activity-row-top { display: flex; justify-content: space-between; gap: 10px; font-size: 13.5px; flex-wrap: wrap; }
.activity-row-meta { color: var(--text-faint); font-size: 12px; margin-top: 2px; }

.exceptions-list li { font-size: 12.5px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.exceptions-list li:last-child { border-bottom: none; }

/* ── Best Bets: analyst sheets ───────────────────────────────────────────── */
.analyst-card { display: grid; grid-template-columns: 46px 1fr; gap: 14px; }
.rank-gutter { font-family: var(--mono); text-align: center; padding-top: 2px; }
.rank-gutter .rank-num { font-size: 20px; color: var(--text-faint); line-height: 1; }
.rank-gutter .rank-meta { font-size: 9.5px; color: var(--text-faint); margin-top: 6px; line-height: 1.4; }
.evidence-strip { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 12px 0 6px; font-family: var(--mono); font-size: 14px; }
.evidence-strip .book-price { color: var(--text-dim); }
.evidence-strip .arrow { color: var(--text-faint); }
.evidence-strip .fair-price { color: var(--text-dim); }
.evidence-strip .ev-proof { color: var(--accent-highlight); font-weight: 600; }
.calib-scale { position: relative; height: 6px; border-radius: 3px; background: var(--line-strong); margin: 10px 0 4px; }
.calib-scale .calib-fair { position: absolute; top: -3px; width: 2px; height: 12px; background: var(--text-faint); }
.calib-scale .calib-book { position: absolute; top: -4px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent-highlight); box-shadow: 0 0 5px rgba(232,154,94,0.7); transform: translateX(-50%); }
.decision-footer { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.decision-footer .stake-line { font-family: var(--mono); font-size: 12.5px; color: var(--text-dim); }
.audit-worksheet { margin-top: 10px; }
.audit-worksheet .audit-eq { font-family: var(--mono); font-size: 12px; color: var(--text-dim); padding: 8px 0; }

/* ── LIVE EV RE-CHECK ("Check price now") ────────────────────────────────── */
.recheck-btn { white-space: nowrap; }
.recheck-status { font-family: var(--mono); font-size: 12px; margin-top: 6px; }
.recheck-status.is-fresh { color: var(--accent-highlight); }
.recheck-status.is-dead { color: var(--gunmetal); }
.recheck-status.is-error { color: var(--gunmetal); }
.recheck-props-note { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.tail-card.is-edge-dead, .ev-card.is-edge-dead { opacity: 0.55; }

/* ── Matchup Lab: The Danger Board (copper-bordered vulnerability list) ──── */
.matchup-danger-board { border-left: 2px solid var(--accent); padding-left: 12px; }
.matchup-danger-board .matchup-simple-takeaways { padding-left: 0; list-style: none; }

/* ── THE RISK COACH: quiet copper-bordered notice panel ──────────────────── */
.coach-panel { border-color: var(--accent); background: var(--accent-dim); margin-bottom: 20px; }
.coach-notice { margin: 6px 0 0; font-size: 14px; color: var(--text); }
.coach-notice:first-of-type { margin-top: 10px; }
.coach-notice-warn { color: var(--accent-highlight); }
.coach-notice-notice { color: var(--text-dim); }

/* ── Slip detail: stake -> legs -> seal ─────────────────────────────────── */
.slip-stake-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
/* FIX ("lu" glyph): this was the one stake figure still set in the serif display font - at
   1 unit it renders "1u", and Instrument Serif's "1" has no distinguishing serif, so it reads
   as a lowercase L next to the u ("lu"). Every other unit figure in the app already uses mono
   (house rule: numbers are always mono) - this one just got missed. */
.slip-stake-figure { font-family: var(--mono); font-size: 34px; color: var(--text); }
.parlay-eq { font-family: var(--mono); font-size: 12.5px; color: var(--text-dim); background: var(--bg-panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 8px 12px; margin: 10px 0; }
.leg-thread-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; }
.leg-thread-row .leg-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--text-faint); }
.leg-thread-row.is-won .leg-dot { background: var(--accent-highlight); }
.leg-thread-row.is-lost .leg-dot { background: var(--gunmetal); }

/* ── Capper dossier / leaderboard ledger ─────────────────────────────────── */
.dossier-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
.dossier-stat-row { display: flex; gap: 28px; flex-wrap: wrap; margin-top: 14px; }
.dossier-stat-row .dstat .val { font-family: var(--mono); font-size: 20px; }
.dossier-stat-row .dstat .lbl { font-family: var(--mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-faint); margin-top: 3px; }
.rank-folio { font-family: var(--mono); color: var(--text-faint); width: 30px; }

/* ── Off the record: branded 404 / error page ────────────────────────────────────────── */
.error-scope { padding-top: 40px; text-align: center; }
.error-fox { width: 74px; height: 74px; margin: 0 auto 18px; opacity: 0.92; }
.error-fox svg { width: 100%; height: 100%; display: block; }
.error-panel { text-align: left; }
.error-panel .label { text-align: center; }
.error-panel h1 { text-align: center; margin-bottom: 6px; }
.error-panel .sub { text-align: center; margin: 0 auto 22px; max-width: 40ch; }
.error-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
@media (prefers-reduced-motion: no-preference) {
  .error-fox svg { animation: fox-nod 700ms cubic-bezier(0.22,1,0.36,1) 120ms both; }
}

/* ── Guide page: racing-form editorial layout, thread motif as a left rule. ─────────── */
.guide-section { border-left: 2px solid var(--line-strong); padding-left: 18px; margin-bottom: 28px; position: relative; }
.guide-section::before {
  content: ''; position: absolute; left: -5px; top: 2px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--accent-highlight); box-shadow: 0 0 6px rgba(232,154,94,0.7);
}
.guide-section h2 { margin-top: 0; }
.guide-toc { display: flex; flex-wrap: wrap; gap: 10px 18px; margin: 14px 0 30px; font-family: var(--mono); font-size: 12.5px; }

/* ── board-wave6: confidence + grade chip + Kelly + EV filter bar ────────── */
.ev-filter-bar { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin: 10px 0 20px; padding: 12px 14px; background: var(--bg-panel-2); border: 1px solid var(--line); border-radius: 8px; }
.ev-filter-bar label { margin: 0; }
.ev-filter-item { font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); display: flex; flex-direction: column; gap: 4px; }
.ev-filter-item select, .ev-filter-item input { margin: 0; min-width: 120px; }
.confidence-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 10px 0; flex-wrap: wrap; }
.confidence-fig { display: flex; align-items: center; gap: 6px; }
.confidence-num { font-family: var(--mono); font-size: 15px; color: var(--text); }
.grade-chip { font-family: var(--mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; padding: 4px 10px; border-radius: 20px; border: 1px solid; white-space: nowrap; }
.grade-chip.grade-a { color: var(--accent-highlight); border-color: var(--accent); background: var(--accent-dim); }
.grade-chip.grade-b { color: var(--bone); border-color: rgba(241,237,230,0.4); background: rgba(241,237,230,0.06); }
.grade-chip.grade-c { color: var(--gunmetal); border-color: var(--gunmetal); background: rgba(90,100,104,0.10); }

/* ── TODAY'S TAILS (presentation wave) ─────────────────────────────────── */
.tails-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
.tail-card { display: flex; flex-direction: column; gap: 8px; padding-top: 20px; }
/* Racing-form header row: sport chip top-left, the emphasis chip (edge label) top-right. */
.tail-card-sport { font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-faint); margin-bottom: 2px; }
.tail-card-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.tail-pick { margin: 0; font-family: var(--display); font-size: 25px; line-height: 1.15; color: var(--bone); }
.tail-meta { font-size: 12px; }
/* Probability-first wave: the hit-rate leads the card, right next to the pick phrase. */
.tail-hitrate-pill { font-family: var(--mono); font-size: 12px; letter-spacing: 0.02em; color: var(--accent-highlight); white-space: nowrap; }
.tail-hitrate-pill strong { font-size: 15px; }
.tail-chip { font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; padding: 3px 9px; border-radius: 20px; border: 1px solid var(--accent); color: var(--accent-highlight); background: var(--accent-dim); white-space: nowrap; }
.tail-chip.tail-chip-strong_edge { color: var(--accent-highlight); border-color: var(--accent-highlight); background: rgba(232,154,94,0.16); }
.tail-chip.tail-chip-solid { color: var(--bone); border-color: rgba(241,237,230,0.4); background: rgba(241,237,230,0.06); }
.tail-fields { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; font-family: var(--mono); }
.tail-arrow { color: var(--text-faint); }
.tail-stake-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
/* Actions right-aligned - the decision row reads left(context)->right(commit). */
.decision-footer { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.decision-footer .recheck-props-note { margin-right: auto; }
/* Earned emphasis: when the full 5-tail shortlist clears the bar, a subtle copper left-rule
   marks the set as complete - never shown on a partial (padded) list. */
.tails-grid.is-full-five .tail-card { border-left: 2px solid var(--accent); padding-left: 18px; }

/* ── PARLAY BUILDER ───────────────────────────────────────────────────────
   Left: board plays + manual leg form. Right: the slip under construction and
   the honest verdict panel. No green/red, no gamified progress bars - the
   verdict is plain text plus mono numbers, same as everywhere else. */
.parlay-layout { display: grid; grid-template-columns: 1fr 420px; gap: 24px; align-items: start; }
/* FIX (parlay page overflows at 1440): a grid item's default min-width is `auto`, i.e. its own
   content's min-content size - not 0. The left (1fr) column's cards/table rows have an
   intrinsic min-content width wider than the space actually available once the fixed 420px
   sidebar and gap are subtracted, so the 1fr track was refusing to shrink and dragging the
   WHOLE grid (sidebar included) ~300px past the page width instead of wrapping its own content.
   min-width: 0 on both columns lets each track actually shrink to its assigned size; long
   content inside wraps or scrolls locally instead of blowing out the page. */
.parlay-layout > * { min-width: 0; }
@media (max-width: 960px) { .parlay-layout { grid-template-columns: 1fr; } }
.parlay-play-list { display: flex; flex-direction: column; gap: 14px; max-height: 900px; overflow-y: auto; padding-right: 4px; }
.parlay-play-card .tail-fields { font-size: 12.5px; }
.parlay-slip-leg { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 0; border-bottom: 1px dashed var(--line); }
.parlay-slip-leg:last-child { border-bottom: none; }
.parlay-slip-leg-info { display: flex; flex-direction: column; gap: 2px; }
.parlay-slip-leg-label { color: var(--bone); font-size: 14px; }
.parlay-slip-leg-meta { font-size: 12px; color: var(--text-faint); }
.parlay-slip-leg-odds { font-family: var(--mono); color: var(--text-dim); white-space: nowrap; }
.parlay-verdict { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-strong); }
.parlay-verdict-row { display: flex; justify-content: space-between; align-items: center; padding: 5px 0; font-size: 13.5px; }
.parlay-verdict-text { margin: 10px 0 0; font-size: 14px; color: var(--bone); }
.parlay-warning-chip { display: inline-block; font-family: var(--mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; padding: 4px 10px; border-radius: 20px; border: 1px solid var(--amber); color: var(--amber); background: rgba(232,154,94,0.08); margin: 6px 6px 0 0; }

/* PARLAY CORRELATION WARNINGS: one amber-tinted row per warning (lib/parlay.js
   detectCorrelations) - a small mono severity chip (SAME GAME / OVERLAP / EXPOSURE) plus the
   plain-language message. Same amber idiom as .parlay-warning-chip above - never green/red,
   this is an honest note, not a pass/fail signal. */
.parlay-corr-warning { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px dashed rgba(232,154,94,0.25); }
.parlay-corr-warning:last-child { border-bottom: none; }
.parlay-corr-warning-chip { flex: none; font-family: var(--mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em; padding: 3px 8px; border-radius: 4px; border: 1px solid var(--amber); color: var(--amber); background: rgba(232,154,94,0.08); white-space: nowrap; }
.parlay-corr-warning-msg { font-size: 12.5px; color: var(--text-dim); line-height: 1.4; }

/* ── board-wave6: Today's board (per-sport tabs, expandable game rows) ──── */
.board-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.board-tab { font-family: var(--mono); font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; padding: 6px 14px; border-radius: 20px; border: 1px solid var(--line); color: var(--text-faint); background: transparent; cursor: pointer; }
.board-tab.active { color: var(--accent-highlight); border-color: var(--accent); background: var(--accent-dim); }

/* SPORT CHIP ROW (ALL-SPORTS VISIBILITY fix): one chip per supported sport on Find Bets
   surfaces where sports mix in one list (Best Bets, Parlay) - same copper-outline idiom as
   .board-tab above, laid out as a horizontally-scrollable row (mobile: scrolls, never wraps
   into a wall of chips). "All" and "My sports (N)" are presets, visually set apart with a
   thin divider. */
/* Wrap, never overflow-scroll: a filter chip hidden past an invisible scroll edge is a filter
   the member does not know exists (live-audit finding: WNBA's chip was offscreen in the parlay
   board column). Two rows of visible chips beats one row hiding sports. */
.sport-chip-row { display: flex; flex-wrap: wrap; gap: 8px; padding-bottom: 4px; margin-bottom: 12px; }
.sport-chip-row::-webkit-scrollbar { height: 6px; }
.sport-chip { flex: 0 0 auto; }
.sport-chip-divider { flex: 0 0 auto; width: 1px; background: var(--line); margin: 4px 2px; }
.sport-chip-hidden-note { font-size: 12.5px; margin: 0 0 12px; }

/* SPORT RAIL (nav restructure wave): the Dimers-style "what has games today" strip under the
   app nav - see partials/sport-rail.ejs + lib/sport-rail.js. Same .board-tab pill idiom as the
   Find Bets sport chips above, but ALWAYS a single non-wrapping scroll row (unlike the filter
   chips, which wrap on purpose so nothing hides offscreen) - this is a short, honest, real-count
   list (at most a handful of sports are ever in season on the same day), so a horizontal scroll
   here never hides a chip the member doesn't know exists. Scoped inside .wrap so its own
   internal scroll never causes the page body to scroll sideways. */
/* Selector is .wrap.sport-rail-wrap (TWO classes) on purpose. Written as a bare
   .sport-rail-wrap it lost to the four plain .wrap padding rules that appear LATER in this file
   (the responsive ones near lines 1766 / 1813 / 2122 / 2237): equal specificity, so source order
   decided it and the rail inherited .wrap's tab-bar clearance. That rendered a ~116px band of
   dead space between the rail and the folio line on every page, worst on mobile where it pushed
   Today's Tails entirely below the fold. Two classes beats one at any source position, so this
   holds without having to patch each breakpoint. */
.wrap.sport-rail-wrap { padding-top: 10px; padding-bottom: 0; }
.sport-rail {
  display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto; padding-bottom: 10px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.sport-rail::-webkit-scrollbar { display: none; }
.sport-rail-chip { flex: 0 0 auto; white-space: nowrap; text-decoration: none; }
.board-day-toggle { display: flex; gap: 6px; margin: 0 0 16px; }
.board-game-row { border: 1px solid var(--line); border-radius: 8px; margin-bottom: 10px; overflow: hidden; }
.board-game-summary { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 12px 16px; cursor: pointer; flex-wrap: wrap; }
.board-game-summary:hover { background: var(--bg-panel-2); }
.board-game-matchup { font-family: var(--display); font-size: 16px; }
.board-game-meta { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.board-game-favorite { font-family: var(--mono); font-size: 13px; color: var(--text); }
.board-game-lines { display: flex; gap: 16px; flex-wrap: wrap; font-family: var(--mono); font-size: 12.5px; color: var(--text-dim); }
.board-game-detail { padding: 0 16px 16px; border-top: 1px solid var(--line); display: none; }
.board-game-row.open .board-game-detail { display: block; }
.board-game-row.open .board-game-summary { background: var(--bg-panel-2); }
.board-books-table { width: 100%; margin-top: 12px; font-size: 12.5px; }
.board-books-table td.best-price { color: var(--accent-highlight); font-weight: 600; background: var(--accent-dim); border-radius: 4px; }
.props-note { font-family: var(--mono); font-size: 11px; color: var(--text-faint); margin-top: 8px; }
.props-loading { font-style: italic; color: var(--text-faint); }

/* ── board-wave6: dashboard TODAY strip ──────────────────────────────────── */
.today-strip-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 8px; margin: 0 -8px; border-bottom: 1px dotted var(--line-strong); flex-wrap: wrap; border-radius: 6px; }
.today-strip-row:last-child { border-bottom: none; }
.today-strip-game { font-family: var(--display); font-size: 14.5px; }
.today-strip-meta { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.today-strip-fair { font-family: var(--mono); font-size: 12.5px; }

/* ── board-wave6: empty-state first-day guide ────────────────────────────── */
.first-day-guide { text-align: center; padding: 10px 0; }
.first-day-steps { display: flex; flex-direction: column; gap: 10px; max-width: 340px; margin: 14px auto 0; text-align: left; }
.first-day-step { display: flex; align-items: center; gap: 10px; font-size: 13.5px; }
.first-day-step .fd-num { font-family: var(--mono); font-size: 11px; color: var(--accent-highlight); border: 1px solid var(--accent); border-radius: 50%; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }

/* ── board-wave6: landing product showcase ───────────────────────────────── */
.showcase-section { padding: 60px 0; }
.showcase-frame { border: 1px solid var(--line-strong); border-radius: 10px; background: var(--bg-panel); box-shadow: 0 24px 60px rgba(0,0,0,0.35); overflow: hidden; max-width: 900px; margin: 0 auto; }
.showcase-frame .frame-chrome { display: flex; gap: 6px; padding: 10px 12px; background: var(--bg-panel-2); border-bottom: 1px solid var(--line); }
.showcase-frame .frame-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line-strong); }
.showcase-frame img { display: block; width: 100%; height: auto; }
.showcase-caption { text-align: center; font-family: var(--display); font-style: italic; color: var(--text-faint); margin-top: 14px; font-size: 15px; }
.showcase-row { margin-bottom: 56px; }
.showcase-row:nth-child(even) .showcase-frame { transform: rotate(-0.6deg); }
.showcase-row:nth-child(odd) .showcase-frame { transform: rotate(0.6deg); }

/* landing v2 ─────────────────────────────────────────────────────────────
   Additive-only block for the rebuilt landing page copy/sections. Nothing
   above this line is touched; every selector here is new. */

.hero-sub-2 { color: var(--text-dim); }

.tails-open-section {
  display: grid;
  grid-template-columns: 1fr 420px;
  gap: 48px;
  align-items: center;
  max-width: 1080px;
  margin: 0 auto;
  padding: 60px 24px;
}
.tails-open-copy p.label { margin: 0 0 6px; }
.tails-open-h2 { font-size: 34px; margin: 0 0 14px; }
.tails-open-copy p:not(.label) { color: var(--text-dim); max-width: 42ch; }
.tails-open-mock { min-width: 0; }
.tails-open-mock .tail-card { max-width: 420px; margin: 0 auto; }
@media (max-width: 860px) {
  .tails-open-section { grid-template-columns: 1fr; text-align: center; padding: 44px 20px; gap: 28px; }
  .tails-open-copy p:not(.label) { margin: 0 auto; }
  .tails-open-mock .tail-card { max-width: 100%; }
}

.feature-grid-section { max-width: 1080px; margin: 0 auto; padding: 40px 24px 60px; text-align: center; }
.feature-grid-section .engraved-rule { max-width: 220px; margin: 0 auto 14px; }
.feature-grid-h2 { font-size: 30px; margin: 6px 0 32px; }
/* Redesign wave: bento, not a 3x2 grid of equal cards. Six 12-col spans laid out so
   two features (the +EV finder and the discipline engine, the load-bearing pair) get a wide
   row to themselves while the rest settle into an uneven three/two split - the eye lands
   somewhere specific instead of scanning six identical boxes. */
.feature-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 18px;
  text-align: left;
}
.feature-card {
  background: var(--bg-panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 22px 24px;
  grid-column: span 4;
  transition: border-color 180ms ease, transform 180ms ease, box-shadow 180ms ease;
}
.feature-card:hover {
  border-color: var(--line-strong);
  transform: translateY(-2px);
  box-shadow: 0 14px 34px -18px rgba(217,123,74,0.35);
}
.feature-card:nth-child(1) { grid-column: span 7; }
.feature-card:nth-child(2) { grid-column: span 5; }
.feature-card:nth-child(3) { grid-column: span 5; }
.feature-card:nth-child(4) { grid-column: span 7; }
.feature-card:nth-child(5) { grid-column: span 6; }
.feature-card:nth-child(6) { grid-column: span 6; }
/* Staggered reveal, keyed off the section's own [data-proof].in-view (landing-thread.js
   already flips this class once, at 35% visibility - no new JS needed). */
.feature-card {
  opacity: 0; transform: translateY(14px);
  transition: opacity 420ms cubic-bezier(0.22,1,0.36,1), transform 420ms cubic-bezier(0.22,1,0.36,1), border-color 180ms ease, transform 180ms ease, box-shadow 180ms ease;
}
.feature-card:nth-child(1) { transition-delay: 0ms; }
.feature-card:nth-child(2) { transition-delay: 60ms; }
.feature-card:nth-child(3) { transition-delay: 120ms; }
.feature-card:nth-child(4) { transition-delay: 180ms; }
.feature-card:nth-child(5) { transition-delay: 240ms; }
.feature-card:nth-child(6) { transition-delay: 300ms; }
[data-proof].in-view .feature-card { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .feature-card { opacity: 1; transform: none; transition: none; }
}
.feature-card h3 { margin: 0 0 8px; font-size: 18px; }
.feature-card p { margin: 0; color: var(--text-dim); font-size: 13.5px; line-height: 1.55; }
.feature-card .feature-building {
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 10.5px;
  color: var(--accent-highlight);
  margin: 0 0 6px;
}
@media (max-width: 860px) {
  .feature-grid { grid-template-columns: 1fr; }
  .feature-card, .feature-card:nth-child(1), .feature-card:nth-child(2), .feature-card:nth-child(3),
  .feature-card:nth-child(4), .feature-card:nth-child(5), .feature-card:nth-child(6) { grid-column: span 1; }
  .feature-grid-section { text-align: center; padding: 32px 20px 48px; }
  .feature-card { text-align: left; }
}

.honesty-ledger-section {
  max-width: 780px;
  margin: 0 auto;
  padding: 50px 24px 70px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 30px;
  align-items: start;
}
.honesty-seal { display: flex; justify-content: center; padding-top: 6px; }
.honesty-h2 { font-size: 30px; margin: 6px 0 10px; }
.honesty-line { font-family: var(--display); font-style: italic; font-size: 19px; color: var(--text); margin: 0 0 10px; }
.honesty-copy p:not(.honesty-line) { color: var(--text-dim); }
@media (max-width: 620px) {
  .honesty-ledger-section { grid-template-columns: 1fr; text-align: center; padding: 40px 20px 56px; }
  .honesty-seal { padding-top: 0; }
}

/* legal pages */
.legal-footer {
  text-align: center;
  padding: 18px 16px 0;
  color: var(--text-faint);
  font-family: var(--mono);
  font-size: 11px;
}
.legal-footer-links a { color: var(--text-faint); text-decoration: underline; text-underline-offset: 2px; }
.legal-footer-links a:hover { color: var(--accent-highlight); }
.legal-footer-line { margin-top: 4px; }

.legal-rg-panel {
  background: var(--gunmetal-fill);
  color: var(--bone);
  border-radius: 8px;
  padding: 20px 22px;
  margin: 8px 0 28px;
}
.legal-rg-panel h2 { color: var(--bone); margin-top: 0; }
.legal-rg-panel p { color: var(--bone); }
.legal-rg-panel a { color: var(--bone); text-decoration: underline; }

/* tail rating */
.tail-rating { display: inline-flex; align-items: center; gap: 2px; cursor: help; }
.tail-glyph { width: 13px; height: 9px; display: block; }
.tail-glyph-filled path { fill: var(--accent); stroke: none; }
.tail-glyph-empty path { fill: none; stroke: var(--gunmetal); stroke-width: 1.3; }

/* props browser */
.props-filter-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.props-game-group { border: 1px solid var(--line); border-radius: 8px; margin-bottom: 18px; overflow: hidden; }
.props-game-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  padding: 12px 16px; background: var(--bg-panel-2); border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.props-market-group { padding: 10px 16px; border-bottom: 1px solid var(--line); }
.props-market-group:last-child { border-bottom: none; }
.props-market-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
.props-row-list { display: flex; flex-direction: column; gap: 6px; }
.props-row {
  display: grid;
  grid-template-columns: 1.6fr 1.1fr 0.7fr 0.9fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
}
.props-row-thin { border-style: dashed; opacity: 0.85; }
.props-row-pick { font-size: 13px; }
.props-row-fair { font-size: 12.5px; display: flex; flex-direction: column; gap: 2px; }
.props-row-ev { text-align: right; }
/* Deliberately gunmetal for EV in every case (positive AND negative) - no green/red
   traffic-light coloring anywhere in this theme, an honest negative number is not an "error". */
.props-ev-neutral { color: var(--gunmetal); font-size: 14px; }
.props-row-rating { text-align: right; }
.props-row-actions { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }

@media (max-width: 760px) {
  .props-row { grid-template-columns: 1fr; text-align: left; }
  .props-row-ev, .props-row-rating, .props-row-actions { text-align: left; justify-content: flex-start; }
  .props-game-head { flex-direction: column; }
}
.tail-rating-compact { display: inline-block; font-size: 11px; color: var(--accent-highlight); border: 1px solid var(--line-strong); border-radius: 20px; padding: 2px 8px; letter-spacing: 0.03em; }

/* filters wave */
.filters-books-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 2px 14px; margin: 10px 0 14px; }
.filters-wave-bar {
  display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap;
  margin: 10px 0 6px; padding: 12px 14px;
  background: var(--bg-panel-2); border: 1px solid var(--line); border-radius: 8px;
}
.filters-wave-item { display: flex; flex-direction: column; gap: 5px; margin: 0; min-width: 0; }
.filters-wave-label {
  font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-faint); white-space: nowrap;
}
.filters-wave-item select, .filters-wave-item input[type="search"] { margin: 0; min-width: 130px; }
.filters-wave-search { flex: 1 1 180px; }
.filters-wave-search input { width: 100%; min-width: 0; }
.tail-rating-picker { display: inline-flex; align-items: center; gap: 3px; }
.tail-rating-pick-btn {
  background: none; border: none; padding: 3px; margin: 0; cursor: pointer; line-height: 0;
}
.tail-rating-pick-btn .tail-glyph { width: 15px; height: 11px; }
.tail-rating-pick-btn .tail-glyph path { fill: none; stroke: var(--gunmetal); stroke-width: 1.3; }
.tail-rating-pick-btn.tail-rating-pick-filled .tail-glyph path { fill: var(--accent); stroke: none; }
.tail-rating-pick-btn:hover .tail-glyph path { stroke: var(--accent-highlight); }
.filters-hidden-note { margin: 0 0 18px; }
@media (max-width: 620px) {
  .filters-wave-bar { flex-direction: column; align-items: stretch; gap: 12px; }
  .filters-wave-item, .filters-wave-search { width: 100%; }
  .filters-wave-item select, .filters-wave-item input[type="search"], .filters-wave-item input { width: 100%; min-width: 0; box-sizing: border-box; }
  .filters-books-grid { grid-template-columns: 1fr 1fr; }
}

/* sweat screen */
.sweat-teaser {
  font-family: var(--mono); font-size: 12.5px; letter-spacing: 0.02em;
  margin-bottom: 14px; padding: 9px 12px;
  background: var(--accent-dim); border: 1px solid rgba(217,123,74,0.3); border-radius: 6px;
}
.sweat-teaser a { color: var(--accent-highlight); text-decoration: none; }
.sweat-teaser a:hover { text-decoration: underline; }
.sweat-strip { display: flex; gap: 14px; flex-wrap: wrap; margin: 10px 0 20px; }
.sweat-stat {
  flex: 1 1 220px; padding: 12px 14px;
  background: var(--bg-panel-2); border: 1px solid var(--line); border-radius: 8px;
}
.sweat-stat-figure { font-size: 22px; margin-top: 4px; }
.sweat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
.sweat-card { padding: 14px 16px; }
.sweat-card-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 13px; margin-bottom: 10px; padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.sweat-card-view { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--text-faint); text-decoration: none; }
.sweat-card-view:hover { color: var(--accent-highlight); }
.sweat-leg { padding: 10px 0; border-bottom: 1px solid var(--line); }
.sweat-leg:last-child { border-bottom: none; }
.sweat-leg-top { display: flex; justify-content: space-between; gap: 8px; font-size: 14px; }
.sweat-leg-event { font-size: 12px; margin-top: 2px; }
.sweat-leg-status { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 6px; font-size: 12.5px; }
.sweat-score { color: var(--text-faint); white-space: nowrap; }
.sweat-need { flex: 1; }
/* Copper accent = currently hitting, gunmetal = currently behind - never green/red. */
.sweat-leg-ahead .sweat-need, .sweat-leg-push .sweat-need { color: var(--accent-highlight); }
.sweat-leg-behind .sweat-need { color: var(--gunmetal); }
.sweat-leg-ahead { border-left: 2px solid var(--accent); padding-left: 10px; }
.sweat-leg-behind { border-left: 2px solid var(--gunmetal); padding-left: 10px; }
.sweat-leg-push { border-left: 2px solid rgba(241,237,230,0.35); padding-left: 10px; }
@media (max-width: 620px) {
  .sweat-grid { grid-template-columns: 1fr; }
  .sweat-strip { flex-direction: column; }
}

/* dashboard wave */
.tails-record-stat { text-decoration: none; }
.tails-record-stat:hover { color: var(--accent-highlight); }

/* Week Ahead planner: compact horizontal day-strip on desktop, stacked vertically on mobile
   at the same 620px breakpoint every other dashboard module already uses. */
.week-ahead-strip { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 2px; }
.week-ahead-day {
  flex: 1 1 0; min-width: 118px; padding: 10px 12px;
  background: var(--bg-panel-2); border: 1px solid var(--line); border-radius: 8px;
}
.week-ahead-day.is-today { border-color: rgba(217,123,74,0.4); background: var(--accent-dim); }
.week-ahead-day.is-today .week-ahead-weekday, .week-ahead-day.is-tomorrow .week-ahead-weekday { color: var(--accent-highlight); }
.week-ahead-day-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; }
.week-ahead-weekday { font-family: var(--display); font-size: 14px; }
.week-ahead-count { font-size: 18px; margin-top: 6px; }
/* Per-sport breakdown on mixed days ("6 MLB - 3 WNBA") instead of a single opaque total. */
.week-ahead-sport-chips { font-size: 10.5px; color: var(--text-faint); margin-top: 3px; letter-spacing: 0.01em; }
.week-ahead-notable { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.week-ahead-edges { font-family: var(--mono); font-size: 11px; margin-top: 8px; color: var(--text-faint); }
.week-ahead-edges.has-edges { color: var(--accent-highlight); }
@media (max-width: 620px) {
  .week-ahead-strip { flex-direction: column; overflow-x: visible; }
  .week-ahead-day { min-width: 0; }
}

/* Your Edge Report: ROI tables + habit lines, numbers always in Martian Mono, copper for
   positive / gunmetal for negative - never red/green. */
.edge-report-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.edge-report-table td { padding: 6px 4px; border-bottom: 1px solid var(--line); }
.edge-report-table td:last-child, .edge-report-table td:nth-child(2) { text-align: right; white-space: nowrap; }
.edge-report-habits { list-style: none; margin: 6px 0 0; padding: 0; font-size: 13px; }
.edge-report-habits li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.edge-report-habits li:last-child { border-bottom: none; }
@media (max-width: 620px) {
  .edge-report-table { font-size: 12px; }
}

/* matchup lab */
/* Tote Board editorial: dense stat tables ARE the aesthetic - Martian Mono numbers, copper
   only for genuinely notable OPS (>=.900 hot / <=.550 cold, min 20 PA - see lib/matchup-lab.js
   notableOps), gunmetal for honesty caveats, never green/red/checkmarks. Mobile: the table
   scrolls inside its own container (the page body never scrolls horizontally), first column
   pinned so the player/window name stays visible while stats scroll under it. */
.matchup-index-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-top: 10px; }
.matchup-index-card {
  display: flex; flex-direction: column; gap: 4px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--bg-panel);
  text-decoration: none; color: var(--text);
}
.matchup-index-card:hover { border-color: var(--line-strong); background: var(--bg-panel-2); }
.matchup-index-teams { font-family: var(--display); font-size: 17px; }
/* Games Hub card avatar audit (WNBA multi-sport wave): a long "Away Team @ Home Team" line
   wraps to two lines on narrower cards - align-items:flex-start (instead of the shared
   avatar-row default of center) keeps both team logos pinned to the top of the first line
   instead of drifting to a false vertical center between the wrapped lines. Scoped to this
   class only so every other avatar-row usage in the app (matchup-lab header, live strip,
   prop rows) keeps its existing center alignment. */
.matchup-index-teams.avatar-row { align-items: flex-start; }
.matchup-index-teams.avatar-row .avatar { flex-shrink: 0; margin-top: 2px; }
.matchup-index-card .badge { align-self: flex-start; margin-top: 4px; }
/* SIM LAB DISCOVERABILITY (Quick Wins wave): tiny mono tag, only when a sim exists for the game. */
.games-hub-sim-tag { align-self: flex-start; font-size: 11px; letter-spacing: 0.02em; }

.matchup-side-panel + .matchup-side-panel { margin-top: 16px; }
.matchup-pitcher-panel { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.matchup-pitcher-name { display: flex; align-items: baseline; gap: 8px; font-size: 15px; }
.matchup-pitcher-name a { color: var(--text); }
.matchup-pitcher-stats { display: flex; gap: 16px; flex-wrap: wrap; font-size: 13px; color: var(--text-dim); }

.matchup-table-container { overflow-x: auto; margin-top: 6px; }
/* matchup layout pass: overlay scrollbars (Windows/Chrome default) leave the clipped Streak
   column with zero visible affordance that more content exists offscreen - force a thin,
   always-reserved scrollbar so users at narrow widths see there's more to scroll to. */
.matchup-table-container { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.matchup-table-container::-webkit-scrollbar { height: 6px; }
.matchup-table-container::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.matchup-table-container::-webkit-scrollbar-track { background: transparent; }
.matchup-lineup-table { width: 100%; border-collapse: collapse; font-size: 12.5px; white-space: nowrap; }
.matchup-lineup-table th, .matchup-lineup-table td { padding: 6px 10px; border-bottom: 1px solid var(--line); text-align: right; }
.matchup-lineup-table th:first-child, .matchup-lineup-table td:first-child { text-align: left; }
.matchup-lineup-table thead th { color: var(--text-faint); font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: 0.02em; }
.matchup-lineup-table a { color: var(--text); }
.mtl-sticky { position: sticky; left: 0; background: var(--bg-panel); z-index: 1; }
.mtl-notable-hot { color: var(--accent-highlight); font-weight: 600; }
.mtl-notable-cold { color: var(--gunmetal); font-weight: 600; }
.mtl-caveat-row td { border-bottom: 1px solid var(--line); padding-top: 0; padding-bottom: 8px; }
.mtl-caveat, p.mtl-caveat { color: var(--gunmetal); font-size: 11.5px; text-align: left; white-space: normal; }

.matchup-connects-list { display: flex; flex-direction: column; gap: 2px; }
.matchup-connects-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.matchup-connects-row:last-child { border-bottom: none; }

.player-hub-stat-row { display: flex; gap: 18px; flex-wrap: wrap; font-size: 13px; color: var(--text-dim); }

/* Games hub: search box + live tiles */
.games-search-form { display: flex; gap: 8px; margin: 10px 0 18px; max-width: 420px; }
.games-search-input { flex: 1; }
.matchup-index-card.is-live { border-color: var(--accent); }
.games-live-score { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; }
.games-live-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim);
}

/* ── THE FACES WAVE: player/team avatars (partials/avatar.ejs) ───────────────
   Fixed-size circle: initials sit behind, img covers on load, avatar-fallback.js
   hides a broken img so initials show through. No layout shift either way. */
.avatar { position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center; border-radius: 50%; overflow: hidden; background: var(--bg-panel-2); border: 1px solid var(--line); vertical-align: middle; }
.avatar-team { border-radius: 50%; background: #ffffff0d; }
.avatar-initials { font-family: var(--mono); font-weight: 600; color: var(--text-faint); letter-spacing: 0.02em; font-size: 40%; line-height: 1; user-select: none; }
.avatar-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.avatar-team .avatar-img { object-fit: contain; padding: 12%; box-sizing: border-box; }
.avatar-ring-copper { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.avatar-ring-gunmetal { border-color: var(--gunmetal); box-shadow: 0 0 0 1px var(--gunmetal); }
.avatar-row { display: inline-flex; align-items: center; gap: 8px; }

/* Live Game Center */
.gamecenter-panel { margin-bottom: 20px; }
.gamecenter-score { display: flex; align-items: baseline; gap: 10px; font-family: var(--display); font-size: 22px; margin: 6px 0; flex-wrap: wrap; }
.gamecenter-runs { color: var(--accent-highlight); font-family: var(--mono); }
.gamecenter-sep { color: var(--text-faint); }
.gamecenter-winprob-bar { height: 8px; border-radius: 4px; background: var(--gunmetal-fill); overflow: hidden; margin-top: 8px; }
.gamecenter-winprob-bar span { display: block; height: 100%; background: var(--accent-gradient); }
.gamecenter-winprob-labels { display: flex; justify-content: space-between; font-size: 12px; margin-top: 4px; color: var(--text-dim); }
.sweat-leg-ahead, .sweat-leg-behind, .sweat-leg-push, .sweat-leg-final, .sweat-leg-untrackable, .sweat-leg-pregame { padding-left: 8px; }
.matchup-connects-row.sweat-leg-ahead { border-left: 2px solid var(--accent); }
.matchup-connects-row.sweat-leg-behind { border-left: 2px solid var(--gunmetal); }

/* Dashboard live strip */
.live-strip-panel { margin-bottom: 16px; }
.live-strip-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.live-strip-game {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--bg-panel); text-decoration: none; color: var(--text); font-size: 13px;
}
.live-strip-game:hover { border-color: var(--accent); text-decoration: none; }
.live-strip-bet-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

@media (max-width: 620px) {
  .matchup-index-grid { grid-template-columns: 1fr; }
  .matchup-lineup-table { font-size: 11.5px; }
  .games-search-form { max-width: none; }
}

/* view modes */
.view-mode-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: 12px;
  padding-left: 12px;
  border-left: 1px solid var(--line);
}
.view-mode-option {
  background: none;
  border: none;
  padding: 2px 2px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-faint);
  cursor: pointer;
}
.view-mode-option:hover { color: var(--text-dim); }
.view-mode-option.is-active { color: var(--accent-highlight); }
.view-mode-sep { color: var(--line-strong); font-size: 12px; }
@media (max-width: 560px) { .view-mode-toggle { margin-left: 0; padding-left: 0; border-left: none; } }
.tail-simple-sentence { margin: 8px 0 10px; font-size: 14px; line-height: 1.4; }
.board-game-row-simple {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.props-row-simple { margin-bottom: 10px; }
.props-row-simple .props-row-pick { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.matchup-simple-takeaways { margin: 6px 0 0; padding-left: 18px; }
.matchup-simple-takeaways li { margin-bottom: 6px; font-size: 14px; line-height: 1.4; }

/* ── REDESIGN WAVE: "Refined Racing Form" (evolution, not revolution) ───────────────────
   Nav regroup, comet sparklines everywhere numbers trend, sparse purposeful motion, a
   375px-first mobile pass, and the advanced-mode fair-line overlay. Still Ink & Copper,
   still no green/red, still no checkmarks. */

/* NAV REGROUP: the flat 12-link row becomes 4 clusters with a divider rhythm + small mono
   group labels; the account cluster (Settings/Help/Feedback/Log out) collapses behind a
   <details> so the row never crowds. Active link gets a copper underline accent. */
.nav-grouped { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.nav-cluster { display: flex; align-items: center; padding: 0 20px; border-left: 1px solid rgba(90,100,104,0.35); }
.nav-cluster:first-child { border-left: none; padding-left: 0; }
/* TOUCH TARGET FIX (P0, 2026-07-28 critique): these links measured ~24.75px tall (14.5px text
   at this app's 1.5 line-height, plus the 3px underline gap) - well under 44px, and that held at
   every breakpoint this row is shown at. inline-flex + min-height gives a real 44px target
   without changing the visible font/color; the active-link underline moves from "3px below the
   box edge" to a fixed offset tuned for the now-centered text (see .nav-cluster a.is-active::after
   below) so it still hugs the text instead of floating near the box's new, taller edge. */
.nav-grouped nav, .nav-cluster a {
  color: rgba(241,237,230,0.75); margin-left: 0; margin-right: 18px; font-size: 14.5px;
  font-family: var(--sans); letter-spacing: normal; position: relative;
  display: inline-flex; align-items: center; min-height: 44px;
}
.nav-cluster a:last-child { margin-right: 0; }
.nav-cluster a:hover { color: var(--text); text-decoration: none; }
.nav-cluster a.is-active { color: var(--text); }
.nav-cluster a.is-active::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 8px; height: 2px;
  background: var(--accent-gradient); border-radius: 2px;
}
.nav-more { margin-left: 18px; padding-left: 18px; border-left: 1px solid rgba(90,100,104,0.35); position: relative; }
.nav-more-summary {
  list-style: none; cursor: pointer; color: rgba(241,237,230,0.75); font-size: 14.5px; font-family: var(--sans);
  user-select: none; display: flex; align-items: center; gap: 4px; min-height: 44px;
}
.nav-more-summary:hover { color: var(--text); }
.nav-more-summary::-webkit-details-marker { display: none; }
.nav-more-summary::after { content: '\25BE'; color: var(--text-faint); font-size: 10px; }
.nav-more[open] .nav-more-summary { color: var(--accent-highlight); }
.nav-more-menu {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 160px; z-index: 30;
  background: var(--bg-panel-2); border: 1px solid var(--line-strong); border-radius: 8px;
  padding: 6px; display: flex; flex-direction: column; box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.nav-more-menu a { color: var(--text-dim); font-size: 13px; font-family: var(--mono); padding: 7px 10px; border-radius: 5px; }
.nav-more-menu a:hover { color: var(--accent-highlight); background: rgba(217,123,74,0.08); text-decoration: none; }

/* MORE MENU GROUP LABELS (IA wave): ruled groups instead of one flat scan - shared by the
   desktop dropdown (.nav-more-menu) and the mobile full-screen sheet (.more-sheet). */
.nav-more-group-label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint);
  padding: 8px 10px 2px;
}
.more-sheet-featured { color: var(--accent-highlight) !important; font-weight: 600; }

/* NAV SEARCH (Intent Wave): a compact box in the desktop topbar (right of the nav clusters) and
   a full-width one in the mobile More sheet - see partials/header.ejs. */
.nav-search-form { margin-left: 18px; }
.nav-search-form input[type="search"] {
  background: rgba(10,18,20,0.5); border: 1px solid var(--line-strong); border-radius: 6px;
  color: var(--text); font-family: var(--sans); font-size: 13.5px; padding: 6px 10px; width: 170px;
  /* TOUCH TARGET FIX (P0, 2026-07-28 critique): measured 34.25px at every breakpoint - box-sizing
     keeps the existing padding/width intact while min-height grows the box to a real 44px; a
     text input centers its own value vertically, so no extra alignment rule is needed. */
  box-sizing: border-box; min-height: 44px;
}
.nav-search-form input[type="search"]::placeholder { color: var(--text-faint); }
.nav-search-form input[type="search"]:focus { outline: none; border-color: var(--accent-highlight); }
.more-sheet .nav-search-form input[type="search"] { width: 100%; box-sizing: border-box; }

/* SEARCH-AS-YOU-TYPE (Quick Wins wave): the dropdown positions relative to this wrap, which is
   just the form's own margin plus a relative anchor - no layout shift when it opens. */
.nav-search-wrap { position: relative; display: inline-block; }
.more-sheet .nav-search-wrap { display: block; }
.search-typeahead-dropdown {
  position: absolute; top: calc(100% + 6px); left: 18px; right: 0; z-index: 40;
  background: var(--bg-panel-2); border: 1px solid var(--line-strong); border-radius: 8px;
  padding: 4px; box-shadow: 0 8px 24px rgba(0,0,0,0.4); max-height: 320px; overflow-y: auto;
}
.more-sheet .search-typeahead-dropdown { left: 0; }
.search-typeahead-row {
  display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 5px;
  color: var(--text-dim); font-size: 13.5px;
}
.search-typeahead-row:hover, .search-typeahead-row.is-active { color: var(--accent-highlight); background: rgba(217,123,74,0.08); text-decoration: none; }
.search-typeahead-avatar { border-radius: 50%; object-fit: cover; flex: none; }
.search-typeahead-avatar-blank { width: 22px; height: 22px; border-radius: 50%; background: rgba(90,100,104,0.25); display: inline-block; }
.search-typeahead-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-typeahead-sport { font-size: 10px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em; }

/* MOBILE (<760px): the desktop grouped nav + account dropdown disappear in favor of a fixed
   bottom tab bar; the topbar itself slims to brand + view-mode toggle only. */
/* TABLET PORTRAIT decision (owner directive): 12 nav links plus the account cluster do not
   fit cleanly at 768px even tightened - rather than risk an awkward 2-line wrap, tablet
   portrait (<=900px) gets the same bottom tab bar as phone. Tablet LANDSCAPE and small
   laptops (901px+) get the full desktop grouped nav. Clean single breakpoint, no in-between
   half-state. */
@media (max-width: 900px) {
  .nav-grouped { display: none; }
  .topbar { padding: 12px 16px; }
  .brand-lockup { height: 36px; }
}
@media (min-width: 901px) {
  .bottom-tab-bar, .more-sheet, .more-sheet-toggle { display: none !important; }
}
/* TABLET LANDSCAPE (901-1024): still tighten the nav slightly so it never feels cramped
   against the account cluster right before the full desktop spacing kicks in at 1025px+. */
@media (min-width: 901px) and (max-width: 1024px) {
  .topbar .tagline { display: none; }
  .nav-cluster { padding: 0 7px; }
  .nav-grouped nav, .nav-cluster a { margin-right: 7px; font-size: 12px; }
  .nav-more, .view-mode-toggle { margin-left: 6px; padding-left: 6px; }
  .nav-more-summary { font-size: 12px; }
}

/* BOTTOM TAB BAR: app-like fixed nav, 5 items, safe-area aware for the PWA. The active tab
   gets a small one-frame icon "pop" on load (page reloads on nav in this server-rendered
   app, so "on load" reads as "on switch"). */
.more-sheet-toggle { position: absolute; opacity: 0; pointer-events: none; }
.bottom-tab-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; justify-content: space-around; align-items: stretch;
  background: linear-gradient(0deg, var(--bg) 0%, var(--bg-panel) 100%);
  border-top: 1px solid var(--line-strong);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tab-item {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 8px 4px 7px; color: var(--text-faint); font-size: 10.5px; font-family: var(--sans);
  text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer; min-height: 44px;
}
.tab-item:hover { text-decoration: none; color: var(--text-dim); }
.tab-icon { width: 21px; height: 21px; }
.tab-item.is-active { color: var(--accent-highlight); }
.tab-item.is-active .tab-icon { animation: tab-pop 260ms cubic-bezier(0.22,1,0.36,1) both; }
@keyframes tab-pop {
  0% { transform: scale(1); }
  55% { transform: scale(1.22); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .tab-item.is-active .tab-icon { animation: none; }
}

/* EMPTY-STATE FOX ART: sits above the existing honest empty-state copy, no layout weight. */
.empty-state-panel { text-align: center; padding: 10px 0; }
.fox-empty-art { display: block; margin: 0 auto 10px; opacity: 0.9; }

/* DASHBOARD GREETING HEADER: serif display line + honest one-line sub-summary, replaces the
   plain "Dashboard" h1. Numbers in the sub-line are server-computed (greetingSubline). */
.dash-greeting {
  margin-bottom: 18px; display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.dash-greeting h1, .dash-greeting-heading {
  /* A number-bearing line, so it uses the mono face the board is built around. */
  font-family: var(--mono); font-weight: 500; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; text-wrap: balance;
  font-size: 32px; margin: 0 0 6px; color: var(--text);
}
.dash-greeting .dash-greeting-sub { color: var(--text-faint); font-size: 14.5px; margin: 0; }
/* Right-hand mono chip summary (the morning ledger): a quiet status readout beside the date,
   desktop-only company for the ambient comet - collapses under the greeting on narrow widths. */
.dash-greeting-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.dash-greeting-chip {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.02em; color: var(--text-faint);
  border: 1px solid var(--line-strong); border-radius: 20px; padding: 4px 11px; white-space: nowrap;
}
.dash-greeting-chip strong { color: var(--accent-highlight); font-weight: 600; }
@media (max-width: 640px) { .dash-greeting { flex-direction: column; align-items: flex-start; } }

/* STAT STRIP: 4 compact tiles reusing already-computed dashboard figures. Ledger motif: a 1px
   copper top-rule per tile, sparkline tucked into the bottom-right corner, equal tile heights. */
.stat-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; align-items: stretch; }
.stat-tile {
  background: var(--bg-panel); border: 1px solid var(--line); border-top: 1px solid var(--accent);
  border-radius: 8px; padding: 16px 18px; position: relative; min-height: 96px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.stat-tile .label { margin-bottom: 8px; }
.stat-tile .stat-tile-num { font-family: var(--mono); font-size: 24px; font-weight: 500; color: var(--text); line-height: 1.1; }
.stat-tile .stat-tile-num.num-neg { color: var(--gunmetal); }
.stat-tile .stat-tile-num.num-pos { color: var(--accent-highlight); }
.stat-tile .stat-tile-sub { color: var(--text-faint); font-size: 11px; margin-top: 4px; font-family: var(--mono); }
.stat-tile .comet-chart { position: absolute; right: 14px; bottom: 12px; width: 72px; opacity: 0.85; }
/* 4-across on tablet-landscape and up, 2x2 through phone/tablet-portrait, tighter 2x2 <480 */
@media (max-width: 1023px) { .stat-strip { grid-template-columns: 1fr 1fr; } }
@media (max-width: 479px) { .stat-strip { gap: 8px; } .stat-tile { padding: 11px 12px; min-height: 84px; } .stat-tile .stat-tile-num { font-size: 19px; } }

/* DISCIPLINE STREAKS strip: neutral copper/gunmetal/bone seals only, no green/red, no fire
   emojis. A quiet compact row above the stat strip; the detail is a native <details> (zero JS). */
.streak-strip { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin-bottom: 14px; padding: 10px 14px; background: var(--bg-panel); border: 1px solid var(--line); border-radius: 8px; }
.streak-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-faint); }
.streak-chip strong { color: var(--text); font-weight: 600; }
.streak-seal {
  display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  border-radius: 50%; border: 1px solid var(--line-strong); font-family: var(--mono); font-size: 9px;
  color: var(--text-faint); flex-shrink: 0;
}
.streak-strip-empty { margin: 0; }
.streak-strip-detail { margin-left: auto; font-size: 12px; }
.streak-strip-detail summary { cursor: pointer; }
.streak-strip-detail p { margin: 6px 0 0; font-size: 12px; }
@media (max-width: 640px) { .streak-strip-detail { margin-left: 0; width: 100%; } }

/* DASHBOARD 2-COLUMN LEDGER LAYOUT (beauty wave): main = the action column (tails hero, week
   ahead, tonight, truth panel, edge report); rail = the status column (sweat/live, pending
   exposure, CLV trend, coach notices, condensed activity). Below 1024 it collapses to one
   column and DOM order alone carries priority (main content first, rail after). */
.dashboard-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; align-items: start; }
.dash-rail { display: flex; flex-direction: column; }
.dash-rail > * { margin-bottom: 12px; }
.dash-rail > *:last-child { margin-bottom: 0; }
@media (max-width: 1023px) { .dashboard-grid { grid-template-columns: 1fr; } }

/* Sections below the tails hero get a ~30% tighter vertical rhythm so the dashboard reads as
   dense-but-calm rather than a long scroll of panels. */
.panel-dash-tight { padding: 15px 22px; margin-bottom: 12px; }

/* AMBIENT COMET: a very faint fixed comet-thread motif behind dashboard content only, reusing
   the existing --comet-mark data-uri (no new asset). Off on mobile and reduced-motion. */
.dashboard-comet-bg {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 0.06;
  background-image: var(--comet-mark); background-repeat: no-repeat;
  background-position: 78% 12%; background-size: 760px;
  animation: comet-drift 64s ease-in-out infinite;
}
@keyframes comet-drift {
  0% { transform: translate(0, 0); }
  50% { transform: translate(-26px, 22px); }
  100% { transform: translate(0, 0); }
}
@media (prefers-reduced-motion: reduce), (max-width: 760px) {
  .dashboard-comet-bg { display: none; }
}
.wrap { position: relative; z-index: 1; }

/* MORE SHEET: full-screen overlay listing the rest of the nav, opened via a CSS-only
   checkbox toggle (CSP-safe - no inline handlers, no JS at all needed for this). */
.more-sheet {
  position: fixed; inset: 0; z-index: 50; background: var(--bg);
  display: flex; flex-direction: column; padding: 18px 20px calc(24px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  transform: translateY(100%); transition: transform 220ms ease;
}
.more-sheet-toggle:checked ~ .more-sheet { transform: translateY(0); }
.more-sheet-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
/* TOUCH TARGET FIX (P0, 2026-07-28 critique): measured ~34px tall/42px wide - a single glyph
   with no room to grow into 44px on its own, so this centers it in an explicit 44x44 box. */
.more-sheet-close {
  font-size: 26px; line-height: 1; color: var(--text-faint); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px;
}
.more-sheet a {
  padding: 14px 4px; font-family: var(--mono); font-size: 15px; color: var(--text);
  border-bottom: 1px solid var(--line); min-height: 44px; display: flex; align-items: center;
}
.more-sheet a:hover { color: var(--accent-highlight); text-decoration: none; }
@media (prefers-reduced-motion: reduce) { .more-sheet { transition: none; } }

/* Bottom tab bar clears content - give .wrap breathing room at the foot on mobile so the
   last panel never sits under the fixed bar. */
@media (max-width: 760px) { .wrap { padding-bottom: 96px; } }

/* MINI COMET SPARKLINES (partials/sparkline.ejs): per-play line-movement + reused for the
   dashboard's full-width bankroll/CLV trend charts (responsive:true skips this fixed box). */
.comet-chart-mini { display: block; flex-shrink: 0; }
.line-move-spark { display: flex; align-items: center; gap: 6px; }
.fair-line-overlay { margin-top: 4px; font-size: 12.5px; color: var(--text-dim); }

/* TAIL CARD / EV CARD staggered reveal on load - same rise as .ev-stagger .ev-card (best
   bets advanced), reused via nth-child so plain grids don't need a per-item --i style attr. */
.tails-grid.reveal-stagger > * { animation: card-rise 360ms cubic-bezier(0.22,1,0.36,1) both; }
.tails-grid.reveal-stagger > *:nth-child(1) { animation-delay: 0ms; }
.tails-grid.reveal-stagger > *:nth-child(2) { animation-delay: 40ms; }
.tails-grid.reveal-stagger > *:nth-child(3) { animation-delay: 80ms; }
.tails-grid.reveal-stagger > *:nth-child(4) { animation-delay: 120ms; }
.tails-grid.reveal-stagger > *:nth-child(5) { animation-delay: 160ms; }
.tails-grid.reveal-stagger > *:nth-child(6) { animation-delay: 200ms; }
.tails-grid.reveal-stagger > *:nth-child(7) { animation-delay: 240ms; }
.tails-grid.reveal-stagger > *:nth-child(8) { animation-delay: 280ms; }
.tails-grid.reveal-stagger > *:nth-child(9) { animation-delay: 320ms; }
.tails-grid.reveal-stagger > *:nth-child(n+10) { animation-delay: 360ms; }
@media (prefers-reduced-motion: reduce) { .tails-grid.reveal-stagger > * { animation: none; } }

/* SEAL STAMP: the slip-detail page's big status seal gets a heavier one-time "stamp down" -
   scale 1.15 -> 1 with a slight rotate settle + a soft opacity thump - distinct from the
   smaller inline .seal press used everywhere else (badges/leg rows keep the lighter one). */
.seal-stamp { animation: seal-stamp-down 420ms cubic-bezier(0.22,1,0.36,1) both; }
@keyframes seal-stamp-down {
  0% { opacity: 0; transform: rotate(-4deg) scale(1.15); }
  55% { opacity: 1; transform: rotate(-4deg) scale(0.97); }
  100% { opacity: 1; transform: rotate(-4deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .seal-stamp { animation: none; opacity: 1; } }

/* RECHECK BUTTON: a brief copper pulse when "verified just now" appears (public/js/ev-
   recheck.js sets .is-fresh on the status element - the class add is itself the one-time
   trigger, so no extra JS is needed to fire this once). */
.recheck-status.is-fresh { animation: recheck-pulse 900ms ease-out; }
@keyframes recheck-pulse {
  0% { text-shadow: 0 0 0 rgba(232,154,94,0); }
  30% { text-shadow: 0 0 10px rgba(232,154,94,0.85); }
  100% { text-shadow: 0 0 0 rgba(232,154,94,0); }
}
@media (prefers-reduced-motion: reduce) { .recheck-status.is-fresh { animation: none; } }

/* ── 375px MOBILE-FIRST PASS ─────────────────────────────────────────────────────────── */
@media (max-width: 480px) {
  .wrap { padding: 20px 16px 96px; }
  .panel { padding: 16px; border-radius: 6px; }
  .grid-3 { grid-template-columns: 1fr; }

  /* responsive audit: .page-head h1 is nowrap by default (fine for short static titles like
     "Best Bets") but several pages fill it with dynamic content that runs long on a real phone -
     matchup-lab's "Away Team at Home Team", player-hub/capper-detail's real names, slip-detail's
     "<name>'s parlay - 2u", share-slip's "<name>'s <leg>". Unwrapped, that pushed past 375px and
     widened the whole layout viewport (every fixed element, including the bottom tab bar,
     rendered relative to the wider width instead of the real 375px screen). Let it wrap here;
     the ledger-rule drops to its own row rather than fighting the title for space. */
  .page-head { flex-wrap: wrap; }
  .page-head h1 { white-space: normal; word-break: break-word; }
  .page-head .ledger-rule { flex-basis: 100%; order: 1; }

  /* Filter bars become horizontally-scrollable chip rows instead of wrapping into a wall. */
  /* filters-bar.ejs already force-stacks into a column below 620px (an earlier mobile pass -
     see the @media(max-width:620px) block above). The redesign wave wants a horizontally-
     scrollable chip ROW instead at this tighter breakpoint, so every property that older
     block sets has to be explicitly re-overridden here (flex-direction included) rather than
     just adding nowrap/overflow, or the column layout wins and nothing visibly changes. */
  .ev-filter-bar, .filters-wave-bar {
    flex-direction: row; flex-wrap: nowrap; align-items: flex-start;
    overflow-x: auto; -webkit-overflow-scrolling: touch; padding: 10px 12px;
  }
  .ev-filter-bar::-webkit-scrollbar, .filters-wave-bar::-webkit-scrollbar { display: none; }
  .ev-filter-item, .filters-wave-item, .filters-wave-search { flex: 0 0 auto; width: auto; }
  .ev-filter-item select, .ev-filter-item input,
  .filters-wave-item select, .filters-wave-item input[type="search"], .filters-wave-item input {
    width: auto; min-width: 132px; box-sizing: border-box;
  }
  .filters-wave-search input[type=search] { min-width: 170px; }
  .tail-rating-picker { flex-wrap: nowrap; }

  .board-tabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* Tap targets >=44px on the small interactive bits that ship at a tighter size by default. */
  .btn-sm { min-height: 44px; display: inline-flex; align-items: center; }
  .tail-rating-pick-btn { min-width: 44px; min-height: 44px; }

  /* Parlay: two-pane stacks builder-under-board with a sticky collapsed summary bar. */
  .parlay-layout { grid-template-columns: 1fr; }
  #parlay-slip-panel {
    position: sticky; bottom: 0; z-index: 20; max-height: 60vh; overflow-y: auto;
    border-radius: 10px 10px 0 0; box-shadow: 0 -8px 24px rgba(0,0,0,0.4);
  }
}

/* ── pricing (pricing-fox1) ─────────────────────────────────────────────── */
.pricing-scope { max-width: 1080px; margin: 0 auto; padding: 20px 0 40px; }
.pricing-toggle-input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }

.pricing-kicker { margin: 0 0 22px; }
.pricing-kicker-line {
  font-family: var(--display); font-style: italic; font-size: 19px; line-height: 1.4;
  color: var(--text); max-width: 62ch; margin: 0;
}

.pricing-status-banner { max-width: 720px; }

.pricing-toggle-row {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  margin: 30px 0 28px;
}
.pricing-toggle-label { font-size: 12px; letter-spacing: 0.05em; color: var(--text-faint); cursor: pointer; margin: 0; }
.pricing-toggle-save { color: var(--accent-highlight); }
.pricing-toggle-switch {
  position: relative; display: inline-block; width: 46px; height: 24px; cursor: pointer;
}
.pricing-toggle-track {
  position: absolute; inset: 0; border-radius: 999px; background: var(--bg-panel-2);
  border: 1px solid var(--line-strong); transition: background 150ms ease, border-color 150ms ease;
}
.pricing-toggle-track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--text-faint); transition: transform 150ms ease, background 150ms ease;
}
.pricing-toggle-input:checked ~ .pricing-toggle-row .pricing-toggle-track { border-color: var(--accent); background: var(--accent-dim); }
.pricing-toggle-input:checked ~ .pricing-toggle-row .pricing-toggle-track::after { transform: translateX(22px); background: var(--accent-highlight); }
.pricing-toggle-input:checked ~ .pricing-toggle-row [data-toggle-annual] { color: var(--accent-highlight); }
.pricing-toggle-input:not(:checked) ~ .pricing-toggle-row [data-toggle-monthly] { color: var(--accent-highlight); }

.pricing-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 780px) { .pricing-grid { grid-template-columns: 1fr; } }
/* Founding-open state (owner ruling 2026-07-25): one real card, not a two-tier comparison. */
.pricing-grid-single { grid-template-columns: 1fr; max-width: 460px; margin: 0 auto; }
.pricing-founding-count { margin: 14px 0 0; font-size: 13px; color: var(--text-faint); }

.pricing-tier { padding: 26px 26px 24px; }
.pricing-tier-pro { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(217,123,74,0.18), 0 18px 40px rgba(217,123,74,0.08); }
.pricing-tier-badge { position: absolute; top: 20px; right: 22px; }
.pricing-tier-head h2 { margin: 0 0 4px; font-size: 22px; }
.pricing-tier-sub { margin: 0 0 18px; }
.pricing-price { font-family: var(--mono); font-size: 34px; color: var(--accent-highlight); }
.pricing-price-period { font-size: 14px; color: var(--text-faint); margin-left: 2px; }
.pricing-price-annual { display: none; }
.pricing-toggle-input:checked ~ .pricing-grid [data-price-monthly] { display: none; }
.pricing-toggle-input:checked ~ .pricing-grid [data-price-annual] { display: block; }

.pricing-feature-list { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.pricing-feature-list li { font-size: 13.5px; color: var(--text-dim); display: flex; align-items: baseline; gap: 9px; }
.pricing-mark { font-family: var(--mono); font-size: 13px; width: 14px; flex: 0 0 auto; text-align: center; }
.pricing-mark-in { color: var(--accent-highlight); }
.pricing-mark-out { color: var(--gunmetal); }
.pricing-feature-list-excluded li { color: var(--text-faint); }

.pricing-not-included { border-top: 1px solid var(--line); padding-top: 14px; margin-bottom: 18px; }
.pricing-not-included-label { font-size: 10px; color: var(--text-faint); margin: 0 0 10px; }

.pricing-cta { width: 100%; text-align: center; }

.pricing-founding-strip { max-width: 640px; margin: 34px auto 10px; text-align: center; }
.pricing-founding-strip p { font-size: 14px; color: var(--text-dim); margin: 0; }
.pricing-founding-price { color: var(--accent-highlight); font-size: 15px; }

.pricing-truth-line { text-align: center; color: var(--text-faint); font-size: 12.5px; margin: 18px 0 40px; }

.pricing-teaser-section { max-width: 1080px; margin: 0 auto; padding: 40px 24px; text-align: center; }
.pricing-teaser-section p { color: var(--text-dim); max-width: 56ch; margin: 10px auto 14px; }

.upgrade-panel { text-align: center; }
.upgrade-panel .seal { margin-bottom: 14px; }
.upgrade-actions { display: flex; gap: 10px; justify-content: center; margin-top: 18px; }

/* ── responsive audit ────────────────────────────────────────────────────────────────────
   Generic wrapper for a plain <table> that has no room to breathe on a real phone (leaderboard,
   slip-detail's legs table, slips-list, capper-detail's tailed-slips table) - same "the page
   body never scrolls, only the table does" contract as .matchup-table-container/.mtl-sticky
   above, just not MLB-specific so any bare table can opt in with one wrapper div. First column
   stays pinned (name/who/rank) while the rest of the row scrolls under it. */
.table-scroll-container { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* matchup layout pass: same invisible-overlay-scrollbar problem as .matchup-table-container -
   give these bare scroll-tables a visible scroll affordance too. */
.table-scroll-container { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
.table-scroll-container::-webkit-scrollbar { height: 6px; }
.table-scroll-container::-webkit-scrollbar-thumb { background: var(--line); border-radius: 3px; }
.table-scroll-container::-webkit-scrollbar-track { background: transparent; }
.table-scroll-container table { white-space: nowrap; }
.table-scroll-container th:first-child, .table-scroll-container td:first-child {
  position: sticky; left: 0; background: var(--bg-panel); z-index: 1;
}

/* slip-detail legs table: 9 columns need to fit 1280px without a scrollbar - tighter padding
   and a truncated Event cell (full name in title attr) instead of forcing nowrap overflow. */
.legs-table th, .legs-table td { padding: 7px 8px; }
.legs-table-event { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leg-grade-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.leg-grade-row:last-of-type { border-bottom: none; }
.leg-grade-label { flex: 1; font-size: 13px; color: var(--text-dim); }
.leg-grade-row select { width: auto; padding: 4px 6px; }

/* THE UNIFICATION WAVE, rebuilt 2026-07-28 (DESIGN.md "What retires" - a plain checkbox list
   is "structurally identical to Notion's or Linear's"). The guided overlay tour that used to
   sit alongside this is gone too (owner ruling 2026-07-28). Same ink/copper tokens as
   everything else - no new palette. Steps are now numbered ledger rows: a small tabular-mono
   index badge instead of a checkbox, ringed and neutral while pending, filled copper once
   done - completion reads as the number that moved, not a tick mark (no checkmarks, ever). */
.dash-checklist-card { border: 1px solid var(--line-strong); margin-bottom: 20px; }
.dash-checklist-items { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.dash-checklist-item { display: flex; align-items: center; }
/* TOUCH TARGET FIX (P0, 2026-07-28 critique): the index glyph used to be a decorative <span>
   sibling of the <a>, outside the clickable target entirely, and the link itself measured
   ~22.5px tall. The glyph is the <a>'s first child (see dashboard.ejs) and this rule gives
   the whole row a real 44px target at every breakpoint, not just below some cutoff. */
.dash-checklist-item a { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.dash-checklist-num {
  width: 22px; height: 22px; flex: 0 0 auto; border-radius: 50%;
  border: 1px solid var(--line-strong); display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums; color: var(--text-faint);
}
.dash-checklist-item.is-done .dash-checklist-num { background: var(--accent); border-color: var(--accent); color: var(--ink); }
.dash-checklist-item.is-done a { color: var(--text-faint); text-decoration: line-through; }
/* The dismiss control is a real 44px target too, at every breakpoint - scoped here rather
   than a global .btn-sm change. */
.dash-checklist-dismiss { margin-left: auto; min-height: 44px; display: inline-flex; align-items: center; }

/* ── SOCIAL WAVE: profiles, follow, groups, chat ───────────────────────── */

.profile-head { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.profile-head-meta { flex: 1; min-width: 160px; }
.profile-follow-counts { display: flex; gap: 18px; margin-top: 6px; }
.profile-follow-counts .fcount { font-family: var(--mono); }
.profile-follow-counts .fcount .val { color: var(--text); font-weight: 600; }
.profile-follow-counts .fcount .lbl { color: var(--text-faint); margin-left: 4px; }

.follow-btn-form { display: inline-block; }
.btn-following { color: var(--text-faint); border-color: var(--line-strong); }

.groups-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.group-card-code {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.08em; color: var(--accent-highlight);
  border: 1px dashed var(--line-strong); border-radius: 6px; padding: 6px 10px; display: inline-block; margin: 6px 0;
}
.group-share-toggle-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-dim); }
.group-member-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.group-member-row:last-child { border-bottom: none; }
.group-member-row .grow { flex: 1; }

/* Chat: a bounded scrollable message list + a post box, same panel language as everywhere else. */
.group-chat-panel { display: flex; flex-direction: column; height: 360px; }
.group-chat-messages { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding-right: 4px; }
.group-chat-msg { font-size: 13.5px; line-height: 1.4; }
.group-chat-msg .who { color: var(--accent-highlight); font-weight: 600; margin-right: 6px; }
.group-chat-msg .when { color: var(--text-faint); font-size: 10.5px; font-family: var(--mono); margin-left: 6px; }
.group-chat-form { display: flex; gap: 8px; margin-top: 10px; }
.group-chat-form input[type="text"] { flex: 1; }
.group-chat-empty { color: var(--text-faint); font-size: 13px; text-align: center; margin: auto; }

.following-empty-cta { text-align: center; padding: 24px 0; }

/* ── SIM VIZ WAVE: duel bar / score curve / conviction bar / NRFI dial / calibration ladder ──
   No chart library - inline SVG server-rendered by lib/sim-viz.js + views/partials/*.ejs. Same
   comet-tail language as the rest of the app: copper favored, gunmetal/bone the other side. */
.duel-bar { display: inline-flex; flex-direction: column; gap: 4px; }
.duel-bar-svg { display: block; }
.duel-bar-track { fill: var(--gunmetal); opacity: 0.35; }
.duel-bar-track.duel-bar-home { fill: var(--bone); opacity: 0.18; }
.duel-bar-track.is-favored { fill: var(--accent); opacity: 0.85; }
.duel-bar-labels { display: flex; justify-content: space-between; gap: 8px; font-size: 11px; color: var(--text-faint); }
/* Hard overflow guard (live-audit finding): even a long label must clip inside the bar's
   fixed width, never bleed into a neighboring table column. */
.duel-bar { max-width: 100%; overflow: hidden; }
.duel-bar-labels span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.duel-bar-labels .duel-bar-favored { color: var(--accent-highlight); font-weight: 600; }

.score-curve { width: 100%; max-width: 280px; height: auto; display: block; }
.score-curve-market-line { stroke: var(--gunmetal); stroke-width: 1.5; stroke-dasharray: 3 3; }
.score-curve-caption { font-size: 11.5px; margin-top: 4px; }

.conviction-bar-wrap { display: flex; flex-direction: column; gap: 4px; min-width: 140px; }
.conviction-bar-label { font-size: 11.5px; color: var(--bone); white-space: nowrap; }
.conviction-bar-svg { display: block; }
.conviction-bar-track { fill: var(--gunmetal); opacity: 0.25; }
.conviction-bar-fill { fill: var(--bone); opacity: 0.55; }
.conviction-bar-fill.is-strong { fill: var(--accent); opacity: 0.9; }
.conviction-bar-mid { stroke: var(--text-faint); stroke-width: 1; opacity: 0.5; }

.nrfi-dial-wrap { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
.nrfi-dial-svg { display: block; }
.nrfi-dial-track { stroke: var(--gunmetal); opacity: 0.3; }
.nrfi-dial-needle { stroke: var(--bone); }
.nrfi-dial-needle.is-yrfi { stroke: var(--accent-highlight); }
.nrfi-dial-zones { display: flex; justify-content: space-between; width: 100%; font-size: 9.5px; color: var(--text-faint); letter-spacing: 0.04em; text-transform: uppercase; }
.nrfi-dial-caption { font-size: 11px; margin-top: 2px; text-align: center; max-width: 130px; }

.calib-ladder { width: 100%; max-width: 260px; height: auto; display: block; }
.calib-ladder-ideal { stroke: var(--text-faint); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.6; }
.calib-ladder-rule { stroke: var(--gunmetal); stroke-width: 1; opacity: 0.5; }
.calib-ladder-predicted { fill: var(--bone); opacity: 0.8; }
.calib-ladder-caption { font-size: 11.5px; margin-top: 6px; max-width: 280px; }

/* ── THE COUNTABLE BAR (Tote Board device wave): one bar per recent graded result, hand-rolled
   SVG, no chart library - see lib/countable-bar.js + views/partials/countable-bar.ejs. Same
   copper/gunmetal/bone vocabulary as the rest of the app; neutral (push/void) is a hollow
   outline, never a fill, so it never reads as a win or a loss. Static, no entrance animation -
   the bars are a count, not a reveal. */
.countable-bar-wrap { margin: 10px 0; }
.countable-bar-rate { margin: 0 0 8px; }
.countable-bar-svg { display: block; max-width: 100%; }
.countable-bar-cleared { fill: var(--copper); }
.countable-bar-missed { fill: var(--gunmetal); }
.countable-bar-neutral { fill: none; stroke: var(--bone); stroke-width: 1.5; opacity: 0.55; }

/* ── THE DISTRIBUTION STRIP (Tote Board device wave): a simulation's spread of outcomes as
   countable ticks - see lib/distribution-strip.js + views/partials/distribution-strip.ejs. A
   SIBLING to the countable bar above, never that file's own markup: same copper/gunmetal
   grammar (copper = the single most likely outcome, gunmetal = the rest), but bars carry a
   variable HEIGHT (the shape of the distribution) where the countable bar's are always the same
   height (a plain count of discrete results). Static, no entrance animation - same reasoning as
   the countable bar (a shape to read, not a reveal). */
.distribution-strip-wrap { margin: 10px 0; }
.distribution-strip-caption { margin: 0 0 8px; }
.distribution-strip-svg { display: block; max-width: 100%; }
.distribution-strip-mark { fill: var(--gunmetal); opacity: 0.55; }
.distribution-strip-peak { fill: var(--copper); opacity: 1; }

/* ── PER-GAME PREDICTOR PAGES (SEO wave, 2026-07-28): views/game-page.ejs - see lib/game-page.js.
   The lede reuses .truth-figure (the dashboard's own big-number scale) for the huge win-probability
   numeral: bone/text colored, never copper, because this number did not "move" - copper stays
   reserved for the number that changed (DESIGN.md), and a pre-game win probability is a single
   static read, not a delta. */
.game-page-lede { text-align: left; }
.game-lede-sentence { font-size: 17px; color: var(--text); margin: 4px 0 10px; max-width: 60ch; }
.game-page-lede .truth-figure { margin: 4px 0 14px; }

/* WEEKLY MARKET REPORT (views/reports-index.ejs, views/report-detail.ejs) */
.reports-index-list { display: flex; flex-direction: column; }
.reports-index-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 12px 0; border-bottom: 1px solid var(--line); color: var(--text); text-decoration: none;
}
.reports-index-row:last-child { border-bottom: none; }
.reports-index-row:hover span:first-child { color: var(--accent-highlight); }
.report-mover-row, .report-divergence-row {
  display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.report-mover-row:last-child, .report-divergence-row:last-child { border-bottom: none; }
.report-nav-links { display: flex; justify-content: space-between; margin: 8px 0 24px; font-size: 13px; }

/* ══════════════════════════════════════════════════════════════════════════════════════════
   MOBILE-NATIVE PASS (<=760px, design target 390x844) - additive-only, on top of every mobile
   rule already shipped above (the 375px pass, the 620px passes, the redesign-wave breakpoints).
   Goal: the app should read as DESIGNED for a phone, not a shrunk desktop layout - a distinct
   type scale, tighter/consistent spacing rhythm, real >=44px tap targets everywhere, honest
   fold priority on the key screens, and sticky context where it earns its keep. Still Ink &
   Copper, still no green/red, still no new palette. ══════════════════════════════════════════ */

@media (max-width: 760px) {

  /* 1. MOBILE TYPE SCALE - one coherent scale, applied through the existing classes rather
     than one-off per-page tweaks. Desktop keeps its own sizes; this block only fires <=760px. */
  :root {
    --m-title: 26px;      /* h1 / page-head - was 34px, ate too much of a phone screen */
    --m-h2: 19px;         /* h2 / panel section headings */
    --m-card-pick: 21px;  /* tail-pick / analyst-card serif figures - was 25px */
    --m-body: 15px;       /* baseline body copy, unchanged from desktop - already comfortable */
    --m-label: 11.5px;    /* .label / mono uppercase tags - was 11px, right at the illegible edge */
  }
  h1, .page-head h1 { font-size: var(--m-title); }
  h2 { font-size: var(--m-h2); }
  .tail-pick { font-size: var(--m-card-pick); }
  .label, label, .badge, .grade-chip, .tail-chip, th, .folio { font-size: var(--m-label); }
  .truth-figure { font-size: 42px; }
  .slip-stake-figure { font-size: 27px; }
  .dash-greeting h1, .dash-greeting-heading { font-size: 27px; }
  .ev-num { font-size: 26px; }
  .proof-num-big { font-size: 42px; }

  /* 2. SPACING RHYTHM - a single outer gutter, tighter panel padding, consistent section
     gaps. (.wrap already goes to 20/16 at <=480; unify the whole <=760 range on the same
     12px outer gutter so tablet-portrait/phone-landscape don't feel like an in-between size.) */
  .wrap { padding-left: 12px; padding-right: 12px; }
  .wrap-narrow { padding-left: 12px; padding-right: 12px; }
  .panel { padding: 14px; border-radius: 8px; margin-bottom: 12px; }
  .panel-tight { padding: 12px 14px; }
  .panel-dash-tight { padding: 12px 14px; margin-bottom: 12px; }
  h2 { margin-bottom: 10px; }
  .sub { margin-bottom: 18px; }
  /* Cards go full-bleed minus the outer gutter - grids stop reserving their own extra gap. */
  .grid-2, .grid-3, .grid-4 { gap: 12px; }
  .tails-grid { gap: 12px; }

  /* 3. TAP ERGONOMICS - every actionable control clears the 44px minimum, with a visible
     pressed state so touch feels responsive rather than dead. */
  .btn, .tab-item, .board-tab, .view-mode-option, .recheck-btn, .tail-btn > .btn,
  .follow-btn-form .btn, .props-row-actions .btn, .decision-footer .btn {
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
  }
  .btn:active, .board-tab:active, .choice-card:active, .choice-card-lg:active,
  .board-game-summary:active, .props-row:active, .tab-item:active,
  .more-sheet a:active, .nav-more-menu a:active {
    background-color: rgba(217,123,74,0.10);
  }
  .btn-ghost:active { background-color: rgba(200,230,235,0.06); }
  /* Expander summaries (board game rows, <details> disclosures) - the whole row is the tap
     target, not just the caret/label text. */
  .board-game-summary { min-height: 44px; cursor: pointer; }
  summary { min-height: 44px; display: flex; align-items: center; cursor: pointer; }
  .show-math summary { min-height: 32px; }

  /* Chip / tab rows: momentum scroll + a visible edge-fade so it's obvious there's more to
     scroll to (an overlay scrollbar alone reads as "that's everything" on a phone). Scoped to
     the horizontally-scrolling rows across the app - sport chips, hub tabs, board tabs, the
     board day-toggle, and any future chip row that opts in via .chip-scroll-row. */
  .sport-chip-row, .board-tabs, .hub-tabs, .board-day-toggle, .filters-books-grid,
  .chip-scroll-row {
    -webkit-overflow-scrolling: touch;
  }
  .hub-tabs-wrap {
    position: relative;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  }
  .hub-tabs {
    display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto; padding: 2px 16px 6px;
    margin: 0 -16px 14px; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .hub-tabs::-webkit-scrollbar { display: none; }
  .hub-tabs .btn { flex: 0 0 auto; white-space: nowrap; }
  /* Chips wrap now (see base rule) - the old edge-fade mask over a horizontal scroll would
     just dim the last visible chip for no reason, so it is gone on mobile too. */
  .board-tabs {
    flex-wrap: nowrap; overflow-x: auto; -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%);
  }
  .board-tab { flex: 0 0 auto; white-space: nowrap; }

  /* 4. THE FOLD - tighten the hero elements on the dashboard/find-bets/game screens so the
     first meaningful content clears a 390x844 viewport before the fixed bottom tab bar. */
  .dash-greeting { margin-bottom: 14px; }
  .dash-greeting-chips { gap: 6px; }
  .dash-greeting-chip { padding: 3px 9px; font-size: 10px; }
  .stat-strip { margin-bottom: 14px; }
  .dashboard-grid { gap: 14px; }
  .page-head { margin-bottom: 2px; gap: 12px; }
  .board-day-toggle { margin-bottom: 12px; }

  /* 5. STICKY ERGONOMICS - Find Bets hub tabs stick just under the topbar once scrolled past,
     and game-page headers (team names + score) stick likewise, so context never scrolls fully
     out of view on a long page. Pure CSS position:sticky, no JS, no layout shift. */
  .topbar { position: sticky; top: 0; z-index: 30; }
  .hub-tabs-wrap {
    position: sticky; top: 0; z-index: 20; background: var(--bg);
    padding-top: 8px; margin-top: -8px;
  }
  .page-head-sticky {
    position: sticky; top: 0; z-index: 20; background: var(--bg);
    padding: 8px 0 6px; margin: -8px 0 0; flex-wrap: wrap;
  }
  .page-head-sticky h1 { font-size: 17px; white-space: normal; }
  .page-head-sticky .ledger-rule { display: none; }

  /* 6. SIM VISUALS - the duel bar / score curve / conviction bar / NRFI dial / calibration
     ladder are all inline SVG server-rendered at fixed widths for desktop tables; on a phone
     they need to shrink to their container rather than force a horizontal scroll. */
  .duel-bar, .duel-bar-svg, .conviction-bar-wrap, .conviction-bar-svg,
  .nrfi-dial-wrap, .nrfi-dial-svg { max-width: 100%; }
  .duel-bar-svg, .conviction-bar-svg, .nrfi-dial-svg { width: 100%; height: auto; }
  .score-curve, .calib-ladder { max-width: 100%; }
  .conviction-bar-wrap { min-width: 0; }
  /* Conviction bars sit inside plain tables on matchup/sim pages - keep the numeric columns
     aligned instead of the bar pushing the row wider than its cell. */
  td .conviction-bar-wrap, td .duel-bar { width: 100%; }

  /* 7. FORMS - 16px minimum on every text-entry field (below 16px, iOS Safari auto-zooms on
     focus, which is jarring and never intentional here); full-width fields already the default
     via the base input rule, reaffirmed here for anything with an inline width override. */
  input[type=text], input[type=email], input[type=password], input[type=number],
  input[type=date], input[type=url], input[type=search], textarea, select {
    font-size: 16px; width: 100%; box-sizing: border-box;
  }
  #units-input, input[name="units"] { width: 100%; max-width: none; }

  /* 8. PWA safe areas - reaffirm both bars clear the notch/home-indicator after this pass's
     spacing changes (topbar already carries env(safe-area-inset-top), bottom-tab-bar already
     carries env(safe-area-inset-bottom) - just confirming the sticky topbar above didn't need
     an extra inset since it's the same element, same padding). */
  .topbar { padding-top: max(12px, env(safe-area-inset-top, 0px)); }
}

/* Landscape phones (short viewport, wide-ish): the fixed bottom tab bar eats a larger share of
   a ~390px-tall landscape screen - trim its padding and drop the fixed dashboard comet/greeting
   chips so content has room to breathe. */
@media (max-width: 900px) and (max-height: 430px) and (orientation: landscape) {
  .tab-item { padding: 4px 4px 5px; font-size: 9.5px; }
  .tab-icon { width: 18px; height: 18px; }
  .wrap { padding-bottom: 64px; }
  .dash-greeting-chips { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   TICKET REDESIGN (presentation wave) - additive only. Slips become printed tickets, records
   become showcases. Same Ink & Copper palette, same seal/comet idiom - just a register-receipt
   / betting-slip physical metaphor for the ticket, and a trophy-case metaphor for records.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

/* The ticket card: perforated top edge, stub header, ticket lines, punch divider, totals, the
   big seal, and a receipt footer. Standalone card (not .panel) so the seal's rotation/shadow
   doesn't fight a plain border. */
.ticket-card {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--line-strong);
  border-radius: 4px 4px 14px 14px;
  box-shadow: 0 18px 40px rgba(0,0,0,0.30);
  padding: 26px 26px 22px;
  margin-bottom: 20px;
  overflow: visible;
}
.ticket-perforation {
  position: absolute; top: -1px; left: 14px; right: 14px; height: 14px;
  background-image: radial-gradient(circle at 7px 0, var(--bg) 5px, transparent 5.5px);
  background-size: 18px 14px;
  background-repeat: repeat-x;
  background-position: top center;
}
.ticket-card::before, .ticket-card::after {
  content: ""; position: absolute; top: -1px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--bg); border: 1px solid var(--line-strong);
}
.ticket-card::before { left: -9px; }
.ticket-card::after { right: -9px; }

.ticket-stub-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; padding-top: 10px; margin-bottom: 14px;
}
.ticket-stub-id { font-family: var(--mono); font-size: 11px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.06em; }
.ticket-stub-title { font-family: var(--display); font-size: 24px; color: var(--bone); margin: 4px 0 0; }
.ticket-stub-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.ticket-stub-stake { text-align: right; }
.ticket-stub-stake .label { margin-bottom: 2px; }
.ticket-stub-stake .ticket-stake-fig { font-family: var(--mono); font-size: 28px; color: var(--text); }

.ticket-lines { border-top: 1px dashed var(--line-strong); margin-top: 4px; }
.ticket-line {
  display: flex; align-items: center; gap: 12px; padding: 12px 0;
  border-bottom: 1px dashed var(--line);
}
.ticket-line:last-child { border-bottom: none; }
.ticket-line-idx { font-family: var(--mono); font-size: 11px; color: var(--text-faint); width: 16px; flex-shrink: 0; }
.ticket-line-body { flex: 1; min-width: 0; }
.ticket-line-pick { font-family: var(--display); font-size: 17px; color: var(--bone); line-height: 1.3; }
.ticket-line-event { font-family: var(--sans); font-size: 12px; color: var(--text-faint); margin-top: 1px; }
.ticket-line-odds { font-family: var(--mono); font-size: 15px; color: var(--text); text-align: right; white-space: nowrap; }
.ticket-line-seal {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; border: 1.5px solid var(--gunmetal); transform: rotate(-6deg);
}
.ticket-line-seal.seal-won { border-color: var(--accent); background: var(--accent-dim); }
.ticket-line-seal.seal-lost { border-color: var(--gunmetal); background: rgba(90,100,104,0.10); }
.ticket-line-seal.seal-push, .ticket-line-seal.seal-void { border-color: rgba(241,237,230,0.35); }
.ticket-line-seal .mark { font-family: var(--mono); font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.02em; }
.ticket-line-seal.seal-won .mark { color: var(--accent-highlight); }
.ticket-line-seal.seal-lost .mark { color: var(--gunmetal); }
.ticket-line-seal.seal-push .mark, .ticket-line-seal.seal-void .mark { color: var(--bone); }
.ticket-line-seal.seal-pending { border-style: dashed; border-color: var(--text-faint); }
.ticket-line-seal.seal-pending .mark { color: var(--text-faint); }

.ticket-punch-divider {
  display: flex; align-items: center; gap: 8px; margin: 12px 0;
  color: var(--text-faint);
}
.ticket-punch-divider::before, .ticket-punch-divider::after {
  content: ""; flex: 1; border-top: 1px dashed var(--line-strong);
}
.ticket-punch-divider .hole { width: 6px; height: 6px; border-radius: 50%; background: var(--bg); border: 1px solid var(--line-strong); flex-shrink: 0; }

.ticket-totals-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ticket-totals-eq { font-family: var(--mono); font-size: 12.5px; color: var(--text-dim); }
.ticket-totals-result { font-family: var(--mono); font-size: 22px; }

.ticket-big-seal-wrap { display: flex; justify-content: center; padding: 8px 0 4px; }
/* Ticket's own big seal - deliberately NOT .seal-big (that class is scroll-triggered via
   [data-proof].in-view for the landing page's proof section and stays invisible without that
   observer). This one uses the same always-visible .seal-stamp press-down as everywhere else
   on the ticket, just sized up. */
.ticket-big-seal { font-family: var(--display); font-size: 26px; padding: 18px 30px; letter-spacing: 4px; }

.ticket-receipt-footer {
  margin-top: 16px; padding-top: 12px; border-top: 1px dashed var(--line-strong);
  font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); line-height: 1.9;
}
.ticket-receipt-footer .receipt-line { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ticket-receipt-footer .receipt-line .rv { color: var(--text-dim); }
.ticket-receipt-footer .receipt-note { margin-top: 4px; font-style: italic; color: var(--text-faint); }

.ticket-stub-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }

/* Slips list -> compact ticket stub rows. */
.ticket-stub-list { display: flex; flex-direction: column; gap: 10px; }
.ticket-stub-row {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  background: var(--bg-panel-2);
  border: 1px solid var(--line);
  border-radius: 3px 3px 9px 9px;
  padding: 12px 16px 12px 20px;
  text-decoration: none; color: inherit;
}
.ticket-stub-row::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px; width: 2px;
  background-image: radial-gradient(circle at 1px 0, var(--bg-panel-2) 3px, transparent 3.5px);
  background-size: 8px 10px; background-repeat: repeat-y;
}
.ticket-stub-row-main { flex: 1; min-width: 0; }
.ticket-stub-row-who { font-size: 14.5px; color: var(--bone); }
.ticket-stub-row-who a { color: inherit; }
.ticket-stub-row-meta { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.ticket-stub-row-stake { font-family: var(--mono); font-size: 13px; color: var(--text-dim); white-space: nowrap; }
.ticket-stub-row-result { font-family: var(--mono); font-size: 15px; white-space: nowrap; text-align: right; min-width: 68px; }
.ticket-stub-row-seal {
  flex-shrink: 0; width: 34px; height: 34px; border-radius: 50%; border: 1.5px solid var(--gunmetal);
  display: flex; align-items: center; justify-content: center; transform: rotate(-5deg);
}
.ticket-stub-row-seal .mark { font-family: var(--mono); font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.02em; }
.ticket-stub-row-seal.seal-won { border-color: var(--accent); background: var(--accent-dim); }
.ticket-stub-row-seal.seal-won .mark { color: var(--accent-highlight); }
.ticket-stub-row-seal.seal-lost { border-color: var(--gunmetal); }
.ticket-stub-row-seal.seal-lost .mark { color: var(--gunmetal); }
.ticket-stub-row-seal.seal-push .mark, .ticket-stub-row-seal.seal-void .mark { color: var(--bone); }
.ticket-stub-row-seal.seal-pending { border-style: dashed; border-color: var(--text-faint); }
.ticket-stub-row-seal.seal-pending .mark { color: var(--text-faint); }
a.ticket-stub-row:hover { border-color: var(--line-strong); background: var(--bg-panel); }

/* Slip timeline: day dividers with a running P/L figure. */
.slip-day-divider {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 22px 0 10px; padding-bottom: 6px; border-bottom: 1px solid var(--line-strong);
}
.slip-day-divider:first-child { margin-top: 4px; }
.slip-day-label { font-family: var(--display); font-style: italic; font-size: 17px; color: var(--text-dim); }
.slip-day-running { font-family: var(--mono); font-size: 12.5px; color: var(--text-faint); }

/* Record showcases (profile + capper dossier). */
.showcase-record-figure { font-family: var(--mono); font-size: 34px; color: var(--bone); letter-spacing: -0.01em; }
.showcase-ribbon { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 10px; }
.showcase-ribbon-seal {
  width: 20px; height: 20px; border-radius: 50%; border: 1.5px solid var(--gunmetal);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.showcase-ribbon-seal.seal-won { border-color: var(--accent); background: var(--accent-dim); }
.showcase-ribbon-seal.seal-lost { border-color: var(--gunmetal); }
.showcase-ribbon-seal.seal-push, .showcase-ribbon-seal.seal-void { border-color: rgba(241,237,230,0.3); }
.showcase-ribbon-seal .dot { width: 5px; height: 5px; border-radius: 50%; }
.showcase-ribbon-seal.seal-won .dot { background: var(--accent-highlight); }
.showcase-ribbon-seal.seal-lost .dot { background: var(--gunmetal); }
.showcase-ribbon-seal.seal-push .dot, .showcase-ribbon-seal.seal-void .dot { background: var(--bone); }
.showcase-clv-block { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.showcase-clv-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

@media (max-width: 760px) {
  .ticket-card { padding: 20px 16px 18px; }
  .ticket-stub-title { font-size: 20px; }
  .ticket-stub-stake .ticket-stake-fig { font-size: 24px; }
  .ticket-line-pick { font-size: 15.5px; }
  .ticket-stub-row { padding: 12px 12px 12px 18px; flex-wrap: wrap; }
  .ticket-stub-row-result { min-width: 0; }
  .ticket-stub-row { min-height: 44px; }
  .showcase-record-figure { font-size: 28px; }
}

/* ── SIM LAB UX REBUILD (2026-07-22) ───────────────────────────────────────
   Cards instead of dense tables, a compact record strip, and a live player-
   props search. Ink & Copper throughout - no green/red, no bare percentages
   (every number lives inside a sentence or a labeled visual per the house
   honesty rule). */

.sim-record-strip { margin-bottom: 20px; }
.record-chip-row { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: flex-start; }
.record-chip { font-family: var(--mono); font-size: 12px; color: var(--text-faint); padding: 4px 0; }
.record-chip-expand { font-size: 12px; }
.record-chip-expand summary {
  font-family: var(--mono); font-size: 12px; color: var(--text-dim); cursor: pointer;
  padding: 4px 10px; border: 1px solid var(--line-strong); border-radius: 20px; list-style: none;
}
.record-chip-expand summary::-webkit-details-marker { display: none; }
.record-chip-expand summary:hover { border-color: var(--text-faint); }
.record-chip-expand[open] summary { border-color: var(--accent); color: var(--accent-highlight); }
.record-chip-expand.is-earned summary { border-color: var(--accent); color: var(--accent-highlight); box-shadow: 0 0 0 1px var(--accent-dim); }
.record-chip-expand p { margin: 8px 2px 0; font-size: 12.5px; line-height: 1.5; }

/* SIM LAB THIN INDEX (Job 4, 2026-07-28): today's games as a flat linked list, one tap through
   to the full predictor page each (.sim-card-* below is that page's own card style, game-page.ejs -
   untouched). 44px min height at every breakpoint, not just under 760px (DESIGN.md touch-target
   rule) - this row is a real link, not decoration. */
.sim-index-list { display: flex; flex-direction: column; }
.sim-index-row {
  display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap;
  min-height: 44px; padding: 10px 8px; margin: 0 -8px;
  border-bottom: 1px dotted var(--line-strong); border-radius: 6px;
  text-decoration: none; color: inherit; transition: background 120ms ease;
}
.sim-index-row:last-child { border-bottom: none; }
.sim-index-row:hover { background: rgba(200,230,235,0.03); }
.sim-index-day { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); flex-shrink: 0; min-width: 60px; }
.sim-index-matchup { font-family: var(--display); font-size: 14.5px; flex-shrink: 0; }
.sim-index-sentence { font-size: 12.5px; flex: 1 1 220px; }
.sim-index-arrow { font-size: 12px; flex-shrink: 0; margin-left: auto; }

/* Game / first-inning cards: responsive grid, 2-up desktop, 1-up mobile. */
.sim-card-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 4px; }
@media (max-width: 760px) { .sim-card-grid { grid-template-columns: 1fr; } }
.sim-game-card { display: flex; flex-direction: column; }
.sim-card-headline { font-family: var(--display); font-size: 22px; margin: 0 0 12px; }
.sim-card-headline a { color: var(--text); }
.sim-card-headline a:hover { color: var(--accent-highlight); }
.sim-card-sentence { font-size: 13.5px; color: var(--text-dim); margin: 10px 0 0; line-height: 1.45; }
.sim-card-meta { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.sim-lean-badge { color: var(--accent-highlight); border-color: var(--accent); }
.sim-card-details { margin-top: 12px; font-size: 12px; }
.sim-card-details summary {
  font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-faint); cursor: pointer; list-style: none;
}
.sim-card-details summary::-webkit-details-marker { display: none; }
.sim-card-details summary:hover { color: var(--accent-highlight); }
.sim-card-details p { margin: 8px 0; }
.sim-card-details .badge { margin: 4px 6px 0 0; }

/* Player Props tab: search box + list */
#prop-search { max-width: 420px; }
.prop-list { display: flex; flex-direction: column; gap: 12px; }
.prop-row { padding: 16px 18px; }
.prop-row-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 8px; }
.prop-row-name { font-family: var(--display); font-size: 19px; margin: 0 0 4px; }
.prop-row-name a { color: var(--text); }
.prop-row-name a:hover { color: var(--accent-highlight); }
.prop-row-line { color: var(--text-faint); font-size: 13px; flex-shrink: 0; }
.prop-row .mtl-caveat { margin-top: 8px; }

@media (max-width: 760px) {
  #prop-search { max-width: 100%; }
  .prop-row-top { flex-wrap: wrap; }
}

/* Player Props search-result rows built by public/js/sim-lab.js from the full-day JSON corpus
   (live QA fix, 2026-07-22) use a plain div bar instead of the server-rendered conviction-bar
   partial's inline SVG (no templating engine available client-side) - same copper fill language,
   lighter weight. */
.prop-bar-lite-wrap { margin: 8px 0 2px; }
.prop-bar-lite-label { font-size: 11.5px; color: var(--text-dim); margin-bottom: 4px; }
.prop-bar-lite-track { width: 220px; max-width: 100%; height: 10px; border-radius: 5px; background: var(--bg-panel-2); border: 1px solid var(--line); overflow: hidden; }

/* ── NEW SECTION: /receipts + /tools/clv-calculator (2026-07-23) ─────────────────────────────
   Additive only - do not touch any rule above this comment (another agent is concurrently
   reworking landing + global CSS elsewhere in this file). */
.receipts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 10px; }
.receipts-col { padding: 16px 18px; border-radius: 10px; border: 1px solid var(--line); }
.receipts-col h3 {
  font-family: var(--mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-faint); margin: 0 0 12px;
}
.receipts-col-industry { background: var(--bg-panel-2); }
.receipts-col-truetail { background: var(--bg-panel-2); border-color: var(--accent); }
.receipts-row { padding: 10px 0; border-top: 1px solid var(--line); }
.receipts-row:first-of-type { border-top: none; padding-top: 0; }
.receipts-claim { font-family: var(--display); font-size: 16px; margin: 0 0 4px; }
.receipts-why { font-size: 13px; color: var(--text-dim); margin: 0 0 6px; line-height: 1.45; }
.receipts-audit-steps { margin: 10px 0 0; padding-left: 20px; }
.receipts-audit-steps li { margin: 0 0 10px; line-height: 1.5; }

.clv-headline { font-size: 34px; margin: 0 0 10px; }

@media (max-width: 760px) {
  .receipts-grid { grid-template-columns: 1fr; }
}
.prop-bar-lite-fill { height: 100%; background: var(--accent-gradient); }

/* ── TOTE BOARD: component vocabulary ────────────────────────────────────────────────────
   DESIGN.md "What retires" (owner ruling 2026-07-28): the folio strip, the VOL/NO dateline,
   the double rule, the drop cap and the masthead conceit are all retired as page furniture -
   costume, not soul. Scoped classes only - nothing here redefines .panel/.label/.page-head,
   which app surfaces still use untouched. */

.broadsheet-scope { max-width: 900px; margin: 0 auto; }

/* The compact brand lockup (formerly "compressed masthead") - small fox + wordmark, used in
   the topbar for interior/app pages and on the two public share pages. The folio line that
   used to sit under it is gone (.masthead-compressed .masthead-folio, removed below) - the
   fox stays as the operator's mark, compact at top-left; it is no longer a masthead crest,
   because there is no masthead (DESIGN.md anchors). */
.masthead-compressed { display: flex; align-items: center; gap: 10px; }
.masthead-compressed .masthead-fox { width: 22px; height: 22px; margin: 0; }
.masthead-compressed .masthead-word { font-family: var(--display); font-size: 19px; color: var(--text); }

/* The double rule retires everywhere it was page furniture. Neutralized rather than deleted:
   views/pricing.ejs still carries a <hr class="double-rule"> and is explicitly frozen this
   wave (do not edit) - display:none makes it vanish there too instead of falling back to an
   unstyled browser default <hr>. Every other template that rendered one has had the tag
   removed outright. */
.double-rule { display: none; }

/* The lede drop cap retires - deleted outright (not neutralized): a plain paragraph is the
   correct end state, so views that still carry the now-inert .lede-dropcap class (unedited
   this wave) degrade to ordinary text with no dead-CSS artifact. */

/* By-the-numbers sidebar (landing's marketing proof column) - boxed stat list, ruled register
   rows stacked vertically. */
.by-numbers { border: 1px solid var(--rule); background: var(--panel); }
.by-numbers-head {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text); background: var(--accent-dim); padding: 10px 16px; border-bottom: 1px solid var(--rule);
}
.by-numbers-item { padding: 15px 16px; border-bottom: 1px solid var(--line); }
.by-numbers-item:last-child { border-bottom: none; }
/* Landing hero sidebar only: tighter item padding so its 4-item height sits closer to the
   copy column's, cutting the dead gap under the hero CTA (visual polish pass, 2026-07-27).
   Scoped to .landing-lede so the dashboard/records by-numbers rows are untouched. */
.landing-lede .by-numbers-item { padding: 11px 16px; }
.by-numbers-item .k { font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); margin-bottom: 5px; }
.by-numbers-item .v { font-family: var(--mono); font-size: 1.1rem; color: var(--text); font-variant-numeric: tabular-nums; }
.by-numbers-item .v b, .by-numbers-item .v strong { color: var(--copper-2); font-weight: 600; }
.by-numbers-item .f { margin-top: 3px; font-size: 12px; color: var(--text-faint); }

/* THE DASHBOARD FIGURE ROW (rebuilt 2026-07-28, DESIGN.md "What retires" owner ruling): this
   used to be a four boxed tiles in a grid - the same shape any B2B panel uses for
   MRR/Churn/Pipeline/NPS. Rebuilt as one ruled register: a thin vertical rule between figures
   instead of four separate tiles, and the numeral is the loudest thing in each cell (board
   anchor - "illuminated tabular numerals are the loudest thing on every surface"), not the
   small-caps label above it. Copper only lands on the number that actually moved
   (.v-pos/.v-neg, applied by the caller per figure) - Bankroll and At risk stay neutral text
   color, they are standing balances, not a result. Dashboard-only: landing's .by-numbers
   sidebar never applies this modifier, so its vertical ruled-list shape is untouched. */
.by-numbers-grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); }
.by-numbers-grid-4 .by-numbers-item { border-bottom: none; border-left: 1px solid var(--line); }
.by-numbers-grid-4 .by-numbers-item:first-child { border-left: none; }
.by-numbers-grid-4 .by-numbers-item .v { display: block; font-size: 1.7rem; font-weight: 600; margin-top: 2px; }
.by-numbers-grid-4 .by-numbers-item .v.v-pos { color: var(--copper-2); }
.by-numbers-grid-4 .by-numbers-item .v.v-neg { color: var(--gunmetal); }
@media (max-width: 560px) {
  .by-numbers-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .by-numbers-grid-4 .by-numbers-item:nth-child(2n+1) { border-left: none; }
  .by-numbers-grid-4 .by-numbers-item:nth-child(n+3) { border-top: 1px solid var(--line); padding-top: 15px; }
  .by-numbers-grid-4 .by-numbers-item .v { font-size: 1.5rem; }
}

/* BROADSHEET WAVE 2: More menu tidy - a thin rule between groups instead of one flat list,
   in both the desktop dropdown and the mobile sheet. */
.nav-more-rule, .more-sheet hr.nav-more-rule { border: none; border-top: 1px solid var(--line); margin: 6px 4px; }

/* Numbered entries - the day's plays, large copper italic serif numerals */
.entry-numbered {
  display: grid; grid-template-columns: 48px 1fr auto; gap: 16px;
  padding: 20px 0; border-top: 1px solid var(--line); align-items: start;
}
.entry-numbered:last-child { border-bottom: 1px solid var(--line); }
.entry-numbered .entry-num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 1.5rem; font-weight: 600; color: var(--copper-2); line-height: 1; }
.entry-numbered .entry-title { font-size: 1.05rem; font-weight: 600; letter-spacing: -0.005em; margin-bottom: 4px; }
.entry-numbered .entry-desc { color: var(--text-faint); font-size: 14px; line-height: 1.6; }
.entry-numbered .entry-meta { display: flex; gap: 18px; margin-top: 10px; font-family: var(--mono); font-size: 11.5px; flex-wrap: wrap; }
.entry-numbered .entry-meta .k { display: block; color: var(--text-faint); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; margin-bottom: 2px; }
.entry-numbered .entry-meta .v { color: var(--text); }
.entry-numbered .entry-meta .v.copper { color: var(--copper-2); }

/* Stub actions - Tail this / More, filled-copper + ruled-ghost pair. TOUCH TARGET FIX (P0,
   2026-07-28 critique): Tail/Log measured ~22.5px above 760px (a mobile-only media query was
   the sole source of their 44px rescue) - min-height here applies at every breakpoint instead,
   scoped to this row (and its overflow menu below) rather than every .btn sitewide. */
.stub-actions { display: flex; flex-direction: column; gap: 8px; }
.stub-actions .btn {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; padding: 8px 14px;
  min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
}
.stub-skip-btn {
  background: none; border: none; padding: 4px 6px; font-size: 11px; letter-spacing: 0.03em;
  color: var(--text-faint); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
  margin-left: auto; display: inline-flex; align-items: center; min-height: 44px;
}
.stub-skip-btn:hover, .stub-skip-btn:focus-visible { color: var(--text); }

/* DECISION-POINT OVERFLOW (P0 fix, 2026-07-28 critique): Tail is the only primary action left
   at this decision point - Log, Check price, Set alarm and skip collapse into this one native
   <details>, in the same uppercase-mono disclosure voice as "Show the math" on the same card.
   Kept as its own rule rather than reusing .show-math so this new control gets a real 44px
   target at every breakpoint (an existing, unrelated media-query override holds .show-math's
   own summary at 32px on purpose, and that expander is explicitly staying as-is). */
.stub-overflow-summary {
  cursor: pointer; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.05em;
  font-size: 11px; font-family: var(--mono); list-style: none;
  display: inline-flex; align-items: center; min-height: 44px; padding: 4px 2px;
}
.stub-overflow-summary::-webkit-details-marker { display: none; }

/* BOARD SINGLE-ACTION LOG (Job 3, 2026-07-28): same touch-target fix as .stub-actions .btn above
   - .btn-sm's own 44px rescue is mobile-only (max-width:480px), so a bare .btn-ghost.btn-sm here
   would repeat the exact P0 the critique already fixed elsewhere. Scoped to this row instead of
   every .btn-sm sitewide. */
.board-log-actions { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.board-log-actions .btn { min-height: 44px; display: inline-flex; align-items: center; }
.board-log-actions a { display: inline-flex; align-items: center; min-height: 44px; }
.stub-overflow-summary:hover { color: var(--accent-highlight); }
.stub-overflow[open] .stub-overflow-summary { color: var(--accent-highlight); }
.stub-overflow-menu { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; margin-top: 8px; }

/* Column rules - 1px vertical rules between true columns at desktop, collapse on mobile */
.column-rules { display: grid; gap: 0; }
.column-rules > * + * { border-left: 1px solid var(--line); padding-left: 24px; }
@media (max-width: 760px) {
  .column-rules { grid-template-columns: 1fr !important; }
  .column-rules > * + * { border-left: none; padding-left: 0; border-top: 1px solid var(--line); padding-top: 20px; margin-top: 20px; }
}

/* Broadsheet-scoped entrance stagger (extends landing-thread.js [data-proof] pattern to any
   [data-bs-stagger] container: children fade/translate in with an incremented delay). */
[data-bs-stagger] > * { opacity: 0; transform: translateY(10px); transition: opacity .3s ease, transform .3s ease; }
[data-bs-stagger].in-view > * { opacity: 1; transform: translateY(0); }
[data-bs-stagger] > *:nth-child(1) { transition-delay: 0ms; }
[data-bs-stagger] > *:nth-child(2) { transition-delay: 60ms; }
[data-bs-stagger] > *:nth-child(3) { transition-delay: 120ms; }
[data-bs-stagger] > *:nth-child(4) { transition-delay: 180ms; }
[data-bs-stagger] > *:nth-child(5) { transition-delay: 240ms; }
@media (prefers-reduced-motion: reduce) {
  [data-bs-stagger] > * { opacity: 1; transform: none; transition: none; }
}

/* Meters (Instrument steal) - thin copper linear meters, data-dense app surfaces only */
.bs-meter { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; margin-top: 6px; }
.bs-meter-fill { height: 100%; background: var(--accent-gradient); width: 0; transition: width .8s cubic-bezier(.22,.61,.36,1); }
[data-bs-stagger].in-view .bs-meter-fill, .bs-meter.in-view .bs-meter-fill { width: var(--bs-meter-pct, 0%); }

/* Onboarding compressed to one ruled broadsheet form */
.bs-onboard-form { display: flex; flex-direction: column; gap: 0; }
.bs-onboard-step { padding: 20px 0; border-top: 1px solid var(--line); }
.bs-onboard-step:first-child { border-top: none; padding-top: 4px; }
.bs-onboard-step-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.bs-onboard-step-num { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 1.3rem; font-weight: 600; color: var(--copper-2); }
.bs-onboard-step-title { font-weight: 600; }

/* Login/register/error broadsheet framing */
.bs-auth-scope { max-width: 460px; margin: 0 auto; }

/* ── INFORMATION ARCHITECTURE WAVE ─────────────────────────────────────── */

/* CROSS-LINK CLUSTERS: the quiet mono link row a game-shaped card gets (views/partials/
   game-links.ejs) - never a button pile, just small underlined links separated by a middot. */
.game-links-row { font-size: 11.5px; color: var(--text-faint); margin-top: 8px; }
.game-links-row a { color: var(--text-faint); text-decoration: underline; text-underline-offset: 2px; }
.game-links-row a:hover { color: var(--accent-highlight); }

/* NEVER DEAD-END: a quiet folio-line "back" link at the top of any deep page that lacked one. */
.back-folio-line {
  display: inline-block; font-family: var(--mono); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-faint); margin-bottom: 14px; text-decoration: none;
}
.back-folio-line:hover { color: var(--accent-highlight); }

/* FOOTER SITEMAP (logged-in members): the same grouped links as the More menu, compact ruled
   columns per DESIGN.md column-rules; collapses to a single stacked column on mobile. */
.footer-sitemap { max-width: 1040px; margin: 0 auto 18px; padding: 0 16px; }
.footer-sitemap .column-rules { grid-template-columns: repeat(4, 1fr); gap: 0; }
.footer-sitemap-group-label {
  font-family: var(--mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-faint); margin: 0 0 8px;
}
.footer-sitemap-group { display: flex; flex-direction: column; gap: 6px; }
.footer-sitemap-group a { color: var(--text-dim); font-size: 12.5px; font-family: var(--mono); }
.footer-sitemap-group a:hover { color: var(--accent-highlight); }
@media (max-width: 760px) {
  .footer-sitemap .column-rules { grid-template-columns: 1fr; }
}

/* ── EMPTY-STATE ICON FIX (owner-reported: blob fox + broken quill) ─────────
   The real fox crest, small and dimmed, replaces the hand-drawn pose art. */
.fox-empty-wrap { display: block; width: 52px; margin: 0 auto 10px; opacity: 0.4; }
.fox-empty-wrap svg { width: 100%; height: auto; display: block; }
.fox-empty-wrap svg path { fill: var(--gunmetal); }

/* ── LANDING TOP PLAY (honesty wave) ─────────────────────────────────────
   Cold-start fallback for the Today's Tails teaser: when server.js's
   buildLandingTopPlay() finds neither a qualifying play nor a graded record, no
   card renders at all (never a placeholder) - this just re-centers the copy
   into the single column so it never sits lopsided against an empty grid cell. */
.tails-open-no-card { grid-template-columns: 1fr; text-align: center; }
.tails-open-no-card .tails-open-copy p:not(.label) { margin: 0 auto; }
