/* SL8IQ mockup design tokens.
 *
 * The contract every mockup screen builds against. Do not edit this file from a screen:
 * add your own <style> block that consumes these variables instead, so six screens stay
 * one product.
 *
 * ---- the visual world: concept E, "the blue edge" ----
 * docs/design/concepts/e-blue-edge/ is the product's committed look, and these values are
 * its palette carried over verbatim: a near-black navy page under one deep-blue light
 * source, a single electric-blue signal ink, and figures that say where they came from.
 * The concept's README owns the reasoning; edge.css is the same values re-declared for the
 * landing page. Nothing here invents a colour that concept does not have.
 *
 * Three rules come with the palette and are not optional on any screen:
 *   1. ONE SIGNAL INK. --accent is for the action you can take, the nav entry you are on,
 *      and the data line. It is not for decoration, not for a second brand mark, and not
 *      for a state that already has a semantic colour (use --positive / --warn / --negative).
 *   2. EVERY FIGURE SAYS WHERE IT CAME FROM. Blocks of figures carry a .prov tag —
 *      Fixture / Derived / Measured / Rule — at 10px, quiet enough to repeat. A figure
 *      nobody can source is not rounded, it is refused.
 *   3. A MISSING NUMBER KEEPS ITS SLOT. Where the product cannot source a value, print the
 *      refusal and the reason in the slot the value would occupy (.withheld), never a
 *      plausible-looking estimate. The standing example is return on money: the prize
 *      structure is an assumption, not a captured table (ADR-0027).
 *
 * ---- calendar anchor ----
 * The mockups share one calendar, recorded once here and in fixture.js (the code copy
 * every dated screen loads): Week 1 = Sunday, September 13, 2026 (the slate that was
 * actually captured), so Week 3 = Sunday, September 27, 2026, and entries close at the
 * first kickoff, 1:00 PM ET. Screens must never type a date: they derive every visible
 * date from the anchor in fixture.js, so the six screens cannot drift apart again.
 */

:root {
  /* Surfaces — the navy ground, coldest at the page and lifting to the hover step.
     The values are concept E's; the names are the ones the six screens already use. */
  --bg: #0b0f1a;              /* the page — near-black navy, the reference's ground */
  --glow-peak: #101c33;       /* what the deep-blue glow lifts the page to at its peak */
  --surface: #111a2b;
  --surface-2: #16203a;
  --surface-3: #1b2747;
  --surface-4: #1f2c4f;       /* hover, one step past surface-3 */
  --border: #23305a;
  --border-strong: #33427a;
  --overlay: rgba(4, 7, 14, 0.74);

  /* Text */
  --text: #eaf0fb;
  --text-2: #a3b0c9;
  /* --text-3 carries teaching text (every .label, .dim, thead th, chart tick, footnote) and
     the .prov-mute tag, so it must hold WCAG AA (4.5:1) on every surface and every tint it
     can sit on. Measured, worst case 5.27:1 (--surface-4); 5.65:1 on --surface-3, 6.20:1 on
     --surface-2, 6.69:1 on --surface, 7.35:1 on --bg, 6.53:1 on the glow, and 4.98:1 on its
     own 14% neutral tint over --surface-4. Do not lower it. */
  --text-3: #94a1ba;
  --text-inverse: #0b0f1a;

  /* Signal */
  --accent: #4c8dff;          /* the one signal ink: links, edges, focus ring, the data line */
  --accent-soft: rgba(76, 141, 255, 0.16);
  /* Accent as *text* has to clear AA on every surface it can land on, and the full-strength
     signal reads only 4.28:1 on --surface-4. So link ink and the .prov tag use
     --accent-on-soft, one step up the same hue: measured worst case 5.48:1 (on the 16% accent
     tint over --surface-4), 6.94:1 on plain --surface-4, 7.45:1 on --surface-3, 9.69:1 on
     --bg. The full-strength --accent stays for fills, 1px edges and the data line, where the
     4.5:1 text bar does not apply (5.98:1 against the page, so the edge is a real edge). */
  --accent-on-soft: #8fbaff;
  /* Accent as a *fill* needs a deeper step of the same hue: white on --accent is 3.20:1,
     white on --accent-fill is 5.41:1 at rest and 5.17:1 on the --accent-fill-hover step —
     both AA for the 13px button text. Hover moves the fill, it does not brighten it. */
  --accent-fill: #2c66cc;
  --accent-fill-hover: #2563eb;
  --accent-glow: rgba(76, 141, 255, 0.28);
  --positive: #3ddc97;        /* value, leverage, beating the field */
  --positive-soft: rgba(61, 220, 151, 0.16);
  --negative: #ff5c6c;        /* fade, over-owned, bust */
  --negative-soft: rgba(255, 92, 108, 0.16);
  /* Same pair rule as the accent: ink on the negative tint. --negative itself is tuned for
     plain surfaces (5.80:1 on --surface) and is fine on --bg (6.38:1) and --surface-3
     (4.90:1), but reads 4.57:1 on --surface-4 — so badges and any negative text on a tinted
     or hovered surface use --negative-on-soft: measured worst case 5.02:1 (on the 16%
     negative tint over --surface-4), 6.09:1 on plain --surface-4, 7.73:1 on --surface. */
  --negative-on-soft: #ff8a96;
  --warn: #ffb020;
  --warn-soft: rgba(255, 176, 32, 0.16);
  --neutral-soft: rgba(148, 161, 186, 0.14);
  /* The withheld slot's hatch. Warm, at 5% — a texture you notice only when you look at the
     tile, never a second signal ink competing with --accent. */
  --withheld-stripe: rgba(255, 176, 32, 0.05);

  /* Positions — fixed across every screen. */
  --pos-qb: #ff6b8a;
  --pos-rb: #3ddc97;
  --pos-wr: #4c8dff;
  --pos-te: #ffb020;
  --pos-dst: #9b8cff;
  --pos-k: #5ad2e6;

  /* Type */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  --fs-11: 11px;
  --fs-12: 12px;
  --fs-13: 13px;
  --fs-14: 14px;
  --fs-16: 16px;
  --fs-20: 20px;
  --fs-26: 26px;
  --fs-34: 34px;
  --fw-normal: 450;
  --fw-medium: 550;
  --fw-bold: 680;
  --lh-tight: 1.15;
  --lh-body: 1.5;

  /* Space — 4px scale. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s8: 32px;
  --s10: 40px;
  --s12: 48px;

  --r-sm: 6px;
  --r: 10px;
  --r-lg: 14px;
  --r-pill: 999px;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 6px 20px rgba(0, 0, 0, 0.45);
}

/* NOT PART OF CONCEPT E. Concept E is a single dark world — one light source, one ground —
   and defines no light palette, so these values are the previous world's, carried here
   unchanged. No screen in this set sets data-theme, so nothing currently renders them.
   They stay in place rather than being deleted because choosing a light world is the
   owner's design decision, not a side effect of adopting E. The palette the mockups
   actually use is the :root block above. */
[data-theme="light"] {
  --bg: #f6f8fb;
  --surface: #ffffff;
  --surface-2: #eef2f7;
  --surface-3: #e3e9f1;
  --border: #dce3ec;
  --border-strong: #c2ccda;
  --overlay: rgba(20, 26, 36, 0.44);
  --text: #131a24;
  --text-2: #4e5b6e;
  /* Same AA rule as the dark value: 4.63:1 on #e3e9f1 (surface-3), 5.03:1 on #eef2f7,
     5.66:1 on white. Unmeasured against concept E, which has no light ground. */
  --text-3: #5c6879;
  --text-inverse: #ffffff;
  --shadow-1: 0 1px 2px rgba(19, 26, 36, 0.08);
  --shadow-2: 0 6px 20px rgba(19, 26, 36, 0.12);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-14);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* Numerals line up in every table and KPI. Never opt out of this. */
.num, td.num, .kpi-value, table { font-variant-numeric: tabular-nums; }

h1, h2, h3, h4 { margin: 0; line-height: var(--lh-tight); font-weight: var(--fw-bold); }
h1 { font-size: var(--fs-34); letter-spacing: -0.02em; }
h2 { font-size: var(--fs-26); letter-spacing: -0.01em; }
h3 { font-size: var(--fs-20); }
h4 { font-size: var(--fs-16); }
p { margin: 0 0 var(--s3); color: var(--text-2); }
a { color: var(--accent-on-soft); text-decoration: none; }
a:hover { color: var(--text); text-decoration: underline; }

.label {
  font-size: var(--fs-11);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
  font-weight: var(--fw-medium);
}

/* ---- layout ---- */
.app { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; }
.app-main { min-width: 0; }           /* min-width:0 stops tables blowing out the grid */
.page { padding: var(--s6); max-width: 1440px; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s4); margin-bottom: var(--s5); }
.page-head .sub { color: var(--text-2); font-size: var(--fs-13); }
.grid { display: grid; gap: var(--s4); }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.stack { display: flex; flex-direction: column; gap: var(--s3); }
.row { display: flex; align-items: center; gap: var(--s3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.spacer { flex: 1; }

/* ---- surfaces ---- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: var(--s4);
}
.card.flush { padding: 0; overflow: hidden; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); padding: var(--s4); border-bottom: 1px solid var(--border); }
.card-body { padding: var(--s4); }
.panel { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-sm); padding: var(--s3); }

.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: var(--s4); }
.kpi .label { display: block; margin-bottom: var(--s2); }
.kpi-value { font-size: var(--fs-26); font-weight: var(--fw-bold); letter-spacing: -0.01em; }
.kpi-delta { font-size: var(--fs-12); margin-top: var(--s1); }
.kpi-delta.up { color: var(--positive); }
.kpi-delta.down { color: var(--negative); }

/* ---- controls ---- */
.btn {
  display: inline-flex; align-items: center; gap: var(--s2);
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  padding: 7px var(--s3); font: inherit; font-size: var(--fs-13); font-weight: var(--fw-medium);
  cursor: pointer;
}
.btn:hover { background: var(--surface-3); }
.btn.primary { background: var(--accent-fill); border-color: var(--accent-fill); color: #fff; }
.btn.primary:hover { background: var(--accent-fill-hover); border-color: var(--accent-fill-hover); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn.danger { color: var(--negative); border-color: var(--negative-soft); }
.btn.sm { padding: 4px var(--s2); font-size: var(--fs-12); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

.input, select.input {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  padding: 7px var(--s3); font: inherit; font-size: var(--fs-13); width: 100%;
}
/* Focus must be visible on a dark surface. --accent-soft is a fill colour and is too dim
 * to read as a ring; use the solid accent, offset. Every interactive element gets this. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

.tabs { display: flex; gap: var(--s1); border-bottom: 1px solid var(--border); }
.tab { padding: var(--s2) var(--s3); font-size: var(--fs-13); color: var(--text-2); border-bottom: 2px solid transparent; cursor: pointer; }
.tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); font-weight: var(--fw-medium); }

.seg { display: inline-flex; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 2px; }
.seg > * { padding: 4px var(--s3); font-size: var(--fs-12); border-radius: 4px; color: var(--text-2); cursor: pointer; }
.seg > [aria-selected="true"] { background: var(--surface-3); color: var(--text); }

/* ---- data ---- */
table { width: 100%; border-collapse: collapse; font-size: var(--fs-13); }
thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface-2); color: var(--text-3);
  font-size: var(--fs-11); text-transform: uppercase; letter-spacing: 0.06em; font-weight: var(--fw-medium);
  text-align: left; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
tbody td { padding: var(--s2) var(--s3); border-bottom: 1px solid var(--border); }
tbody tr:hover { background: var(--surface-2); }
td.num, th.num { text-align: right; }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px var(--s2); border-radius: var(--r-pill);
  font-size: var(--fs-11); font-weight: var(--fw-medium);
  background: var(--neutral-soft); color: var(--text-2);
}
.badge.pos { background: var(--positive-soft); color: var(--positive); }
.badge.neg { background: var(--negative-soft); color: var(--negative-on-soft); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.acc { background: var(--accent-soft); color: var(--accent-on-soft); }

.tag-pos { font-size: var(--fs-11); font-weight: var(--fw-bold); padding: 1px 5px; border-radius: 4px; color: var(--text-inverse); }
.tag-pos.QB { background: var(--pos-qb); }
.tag-pos.RB { background: var(--pos-rb); }
.tag-pos.WR { background: var(--pos-wr); }
.tag-pos.TE { background: var(--pos-te); }
.tag-pos.DST { background: var(--pos-dst); }
.tag-pos.K { background: var(--pos-k); }

/* ==========================================================================
   THE PROVENANCE TAG — concept E's one new device, and a product rule

   An unsourced figure is a refusal, not a rounding. Every block of figures says
   where it came from in one word, and the tag is a designed object: legible at
   10px, quiet enough to repeat thirty times on a screen, and never mistakable
   for a badge that means "good". It is a receipt, not a reward — which is why it
   is a pill in the ink family and not a --positive chip.

   The vocabulary is fixed at four words, and a screen may not invent a fifth:
     Fixture   the mockups' own fixture universe — no real slate produced it
     Derived   arithmetic on figures that are themselves tagged
     Measured  read from a real artifact (a results file, a capture, a run log)
     Rule      the product refuses this number on purpose; pair it with the reason

   Use .prov (signal ink) for Measured and for the screen-level Fixture tag,
   .prov-mute for Derived and for Fixture on a block that already carries a louder
   tag, and .prov-warn for Rule and for any Measured figure that must name which
   week it came from ("Measured · Week 1").

   Contrast, measured on its own 16%/14% tint over the darkest and lightest surfaces
   it can land on, worst case across all six:
     .prov       accent-on-soft on the accent tint   5.48:1
     .prov-mute  text-2 on the neutral tint          4.98:1
     .prov-warn  warn on the warn tint               5.51:1
   All four words therefore clear AA at their 10px size. Do not lower any of them.
   ========================================================================== */

.prov {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: var(--fw-medium);
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent-on-soft);
  background: var(--accent-soft);
  border-radius: var(--r-pill); padding: 1px 7px 1px 6px;
  white-space: nowrap; vertical-align: 1px;
}
.prov::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; flex: none;
}
.prov-mute { color: var(--text-2); background: var(--neutral-soft); }
.prov-warn { color: var(--warn); background: var(--warn-soft); }

/* ==========================================================================
   THE WITHHELD SLOT — a missing number keeps its place

   The reference page fills this slot with a simulated return. This product cannot:
   the prize structure is an assumption, not a captured table, so return on money is
   withheld by rule (ADR-0027). What goes in the slot is the refusal, the reason in
   one sentence, and — where they exist — the figures that do NOT depend on the thing
   being withheld. Never an estimate dressed as a measurement.

   .withheld      the tile or panel itself: dashed edge, warm 5% hatch, nothing loud
   .withheld-v    the value slot, where the number would have been
   .withheld-why  the reason, one or two sentences, plain language
   .withheld-under the figures that survive the refusal, as a definition list

   --warn on the hatched tile measures 8.74:1, and 7.50:1 at its worst on --surface-4,
   so "Withheld" is as readable as any number it replaces. The hatch is 5% — a texture
   you notice when you look at the tile, never a second signal ink.
   ========================================================================== */

.withheld {
  border-style: dashed; border-color: var(--border-strong);
  background:
    repeating-linear-gradient(135deg, transparent 0 7px, var(--withheld-stripe) 7px 14px),
    var(--surface);
}
.withheld-v {
  font-size: var(--fs-20); font-weight: var(--fw-bold); letter-spacing: -0.01em;
  color: var(--warn);
}
.withheld-why { font-size: var(--fs-12); color: var(--text-2); line-height: 1.45; }
.withheld-under { display: grid; gap: 3px; margin: var(--s3) 0 0; padding-top: var(--s3); border-top: 1px solid var(--border); }
.withheld-under > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); min-width: 0; }
.withheld-under dt { font-size: var(--fs-11); color: var(--text-3); text-transform: uppercase; letter-spacing: 0.06em; white-space: nowrap; }
.withheld-under dd { margin: 0; font-size: var(--fs-16); font-weight: var(--fw-medium); color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Exposure / ownership bar — the same widget everywhere a share is shown. */
.bar { position: relative; height: 6px; border-radius: var(--r-pill); background: var(--surface-3); overflow: hidden; min-width: 56px; }
.bar > i { position: absolute; inset: 0 auto 0 0; display: block; background: var(--accent); }
.bar.pos > i { background: var(--positive); }
.bar.neg > i { background: var(--negative); }
.bar.warn > i { background: var(--warn); }

.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.dot.pos { background: var(--positive); }
.dot.neg { background: var(--negative); }
.dot.warn { background: var(--warn); }
.dot.mute { background: var(--text-3); }

.empty { padding: var(--s10) var(--s4); text-align: center; color: var(--text-3); }
.empty h4 { color: var(--text-2); margin-bottom: var(--s2); }

.muted { color: var(--text-2); }
.dim { color: var(--text-3); }
.mono { font-family: var(--font-mono); font-size: var(--fs-12); }
.hairline { height: 1px; background: var(--border); border: 0; margin: var(--s4) 0; }
.scroll-x { overflow-x: auto; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* ---- the rail and the topbar — concept E's chrome, shared by every screen ----
   The rail is one light-source surface against the navy page: --surface against --bg, one
   1px seam, the wordmark with "IQ" in the signal ink, then the entries. Each entry's mark
   sits in --text-3 until you are on it, and then the mark alone takes the signal while the
   word takes full-strength --text. That pair — colour on the mark, weight on the word — is
   the whole of how the rail answers "where am I"; nothing else in the chrome is blue. */
.app { display: grid; grid-template-columns: 214px 1fr; min-height: 100vh; background: var(--bg); }
.side {
  background: var(--surface); border-right: 1px solid var(--border);
  padding: var(--s4) var(--s3) var(--s5); display: flex; flex-direction: column; gap: var(--s5);
  position: sticky; top: 0; align-self: start; max-height: 100vh; overflow-y: auto;
}
/* The wordmark is one text run, not a mark plus a word: a flex row here would boxify the
   "IQ" span into its own flex item and push an 8px gap through the middle of the name. */
.brand { padding: 0 var(--s2); white-space: nowrap; font-weight: var(--fw-bold); font-size: 17px; letter-spacing: -0.02em; color: var(--text); }
/* The wordmark carries the signal on two letters and nowhere else. A second brand mark
   beside it — a gradient tile, a glyph — is a second signal ink, and there is one. */
.brand .iq { color: var(--accent); }
.nav { display: flex; flex-direction: column; gap: 1px; }
.nav a { display: flex; align-items: center; gap: var(--s3); padding: 8px var(--s2); border-radius: var(--r-sm); color: var(--text-2); font-size: var(--fs-13); }
.nav a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav a[aria-current="page"] { background: var(--accent-soft); color: var(--text); font-weight: var(--fw-medium); }
.nav .glyph { width: 17px; flex: none; text-align: center; color: var(--text-3); font-size: var(--fs-14); line-height: 1; }
.nav a:hover .glyph { color: var(--text-2); }
.nav a[aria-current="page"] .glyph { color: var(--accent); }
.nav .label { padding: var(--s3) var(--s2) var(--s1); }

/* ---- mobile: the product is mobile-first (M11), so the rail does not disappear ----
   Below 880px the same eight entries become a bottom tab bar: the rail's own surface,
   stuck to the bottom edge, icons over words, the active entry's mark in the signal ink.
   The brand and the week panel go — the topbar already carries the wordmark, and the
   countdown they repeat lives in the page. */
.topbar { display: none; }
@media (max-width: 880px) {
  .app { grid-template-columns: 1fr; }
  .topbar {
    display: flex; align-items: center; gap: var(--s3);
    padding: var(--s3) var(--s4); background: var(--bg);
    border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 20;
  }
  /* Fixed, not sticky: the rail's own grid cell is only as tall as the rail, so a sticky
     bottom edge would scroll away with it. The bar is a constant 54px and .app-main is
     padded by exactly that, so nothing is ever hidden under it. */
  .side {
    position: fixed; inset: auto 0 0 0; height: 54px; z-index: 30;
    max-height: none; overflow-x: auto; overflow-y: hidden;
    flex-direction: row; align-items: stretch; gap: 0; padding: 0;
    border-right: 0; border-top: 1px solid var(--border);
    scroll-snap-type: x proximity; scrollbar-width: none;
  }
  .app-main { padding-bottom: 54px; }
  .side .brand, .side .panel, .side .spacer { display: none; }
  .nav { flex-direction: row; gap: 0; width: 100%; }
  .nav .label { display: none; }
  .nav a {
    flex: 1 0 auto; min-width: 68px; scroll-snap-align: start;
    flex-direction: column; gap: 3px; justify-content: center; text-align: center;
    padding: var(--s2); font-size: 10px; letter-spacing: 0.02em; line-height: 1.15;
  }
  .nav .glyph { width: auto; font-size: 17px; }
  .nav a[aria-current="page"] { background: none; }
  .nav a[aria-current="page"] .glyph { color: var(--accent); }
  .page { padding: var(--s4); }
  .g2, .g3, .g4 { grid-template-columns: 1fr; }
  h1 { font-size: var(--fs-26); }
}
