/* --- design tokens (task 15.8) -----------------------------------------------------
   One accent, and it is deliberately NOT green.
   Green and red mean one thing on this site: a return above or below zero. An accent
   that shared the colour would make every heading and every link read as a verdict, and
   the one rule this project cannot bend is that colour on a number means something. So
   the accent is blue, "good" and "bad" are reserved for signed money, and anything
   computed from too few bets gets no colour at all. */

:root {
  /* ink and ground */
  --fg: #16181d;
  --muted: #62666f;
  --line: #e3e5e9;
  --bg: #ffffff;
  --panel: #f6f7f9;
  --panel-2: #eef0f4;

  /* the single accent */
  --accent: #2c5fd0;
  --accent-soft: #e8eefc;

  /* meaning, and only meaning */
  --good: #0f7a46;
  --bad: #b3261e;
  --warn: #9a5b06;

  /* type scale: five steps, nothing between them */
  --t-xs: 12px;
  --t-sm: 13.5px;
  --t-base: 15px;
  --t-md: 17px;
  --t-lg: 20px;
  --t-xl: 27px;

  /* spacing scale: multiples of four, nothing between them */
  --s1: .25rem;
  --s2: .5rem;
  --s3: .75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2.25rem;

  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(16, 18, 24, .05), 0 6px 18px rgba(16, 18, 24, .05);
  --focus: 0 0 0 3px var(--accent-soft);
}

@media (prefers-color-scheme: dark) {
  :root {
    --fg: #e7e9ee;
    --muted: #9aa0ab;
    --line: #2b2f37;
    --bg: #101216;
    --panel: #171a20;
    --panel-2: #1d212a;

    --accent: #7aa2f7;
    --accent-soft: #1b2540;

    --good: #4ec08a;
    --bad: #f07c74;
    --warn: #dba33a;

    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 20px rgba(0, 0, 0, .35);
    --focus: 0 0 0 3px var(--accent-soft);
  }
}

* { box-sizing: border-box; }

body {
  font: var(--t-base)/1.6 system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--fg);
  background: var(--bg);
  margin: 0;
  -webkit-font-smoothing: antialiased;
}

header, main, footer { max-width: 1080px; margin: 0 auto; padding: var(--s4) var(--s5); }
header { border-bottom: 1px solid var(--line); }

/* One typographic scale, five steps. A heading that is not on it is a heading whose
   size means nothing. */
h1 { margin: var(--s1) 0; font-size: var(--t-xl); letter-spacing: -.02em; line-height: 1.15; }
h2 {
  margin: 0 0 var(--s2); font-size: var(--t-lg);
  letter-spacing: -.01em; line-height: 1.25;
}
h3 { margin: var(--s5) 0 var(--s1); font-size: var(--t-md); line-height: 1.3; }
h4 { font-size: var(--t-sm); }
p { margin: var(--s2) 0; }

.sub { color: var(--muted); margin: var(--s1) 0; font-size: var(--t-md); }
.build-info { font: var(--t-xs)/1.5 ui-monospace, monospace; color: var(--muted); }
.status { color: var(--muted); padding: var(--s3) 0; }
.note { color: var(--muted); font-size: var(--t-sm); margin: var(--s1) 0 var(--s3);
  max-width: 72ch; }
.small { font-size: var(--t-xs); }

/* Every focusable thing gets the same visible ring: keyboard users are not a niche. */
a:focus-visible, button:focus-visible, select:focus-visible, input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
.muted { color: var(--muted); }
.strong { font-weight: 600; }
.good { color: var(--good); }
.bad { color: var(--bad); }
.warn { color: var(--warn); }

/* Content sits in cards rather than running edge to edge. A full-width table on a
   1080px page is a wall; a card gives it a beginning and an end. */
section {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s4) var(--s5) var(--s5);
  margin: var(--s4) 0;
}
section:first-child { border-top: 1px solid var(--line); }

/* Wide tables scroll inside their own box; the page itself never scrolls sideways. */
.scroll-x { overflow-x: auto; }

table {
  border-collapse: collapse; width: 100%; font-size: var(--t-sm);
  background: var(--bg); border-radius: var(--radius-sm); overflow: hidden;
}
th, td { text-align: left; padding: var(--s2) var(--s3); border-bottom: 1px solid var(--line); }
tbody tr:last-child td, tbody tr:last-child th { border-bottom: none; }
th {
  font-size: var(--t-xs); color: var(--muted); text-transform: uppercase;
  letter-spacing: .04em; white-space: nowrap; font-weight: 600;
}
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

.player-row { cursor: pointer; }
.player-row:hover { background: var(--panel); }
tr.detail > td { background: var(--panel); }

.controls { display: flex; gap: 1rem; flex-wrap: wrap; align-items: end; margin: .5rem 0; }
.controls label { font-size: 12px; color: var(--muted); display: grid; gap: .2rem; }
.controls select, .controls input {
  font: inherit; padding: .35rem .5rem; color: var(--fg);
  background: var(--bg); border: 1px solid var(--line); border-radius: 4px;
}

.gaps { color: var(--muted); font-size: 13.5px; margin: .4rem 0 1rem; padding-left: 1.2rem; }
.gaps li { margin: .2rem 0; }

.pools { display: grid; gap: .3rem; padding: .3rem 0; }
.pool { display: grid; grid-template-columns: 8rem 1fr 6rem; gap: .6rem; align-items: center; }
.pool-name { font-size: 12px; color: var(--muted); }
.pool-value { font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; }
.bar { display: block; height: 8px; background: var(--line); border-radius: 4px; }
.bar-fill { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.missing { font-size: 12.5px; color: var(--warn); margin: .5rem 0 .2rem; }

.badge {
  display: inline-block; padding: .1rem .45rem; border-radius: 999px;
  font-size: 12px; white-space: nowrap; border: 1px solid var(--line);
}
.badge-pick { color: var(--good); border-color: var(--good); }
.badge-pass { color: var(--muted); }

.verdict, .warn-box, .good-box {
  padding: .7rem .9rem; border-radius: 6px; font-size: 13.5px;
  border: 1px solid var(--line); background: var(--panel); margin: .8rem 0;
}
.warn-box { border-left: 4px solid var(--warn); }
.good-box { border-left: 4px solid var(--good); }

.explorer-row { cursor: pointer; }
.explorer-row:hover { background: var(--panel); }

.breakdowns { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); }
.breakdown h3 { font-size: 15px; margin: .2rem 0 .1rem; display: flex; justify-content: space-between; gap: 1rem; }
.pool-block { margin: .55rem 0; }
.pool-block h4 {
  font-size: 12.5px; font-weight: 600; color: var(--muted); margin: .35rem 0 .15rem;
  display: flex; justify-content: space-between; gap: .6rem; align-items: baseline;
  border-bottom: 1px solid var(--line); padding-bottom: .15rem;
}
.pool-total { font-variant-numeric: tabular-nums; color: var(--fg); }
.component {
  display: grid; grid-template-columns: 1fr auto 5.5rem; gap: .5rem;
  font-size: 12.5px; padding: .12rem 0;
}
.component-name { color: var(--fg); }
.component-raw { color: var(--muted); font-variant-numeric: tabular-nums; }
.component-points { text-align: right; font-variant-numeric: tabular-nums; }
/* Two different gaps, two different marks: missing data versus a refusal to price. */
.component-absent .component-gap { color: var(--warn); grid-column: 2; }
.component-declined .component-gap { color: var(--muted); font-style: italic; grid-column: 2; }
.component-absent .component-name { color: var(--warn); }

.coverage-row {
  display: grid; grid-template-columns: 20rem 1fr 9rem; gap: .6rem;
  align-items: center; font-size: 12.5px; padding: .16rem 0;
}
.coverage-name { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.coverage-value { text-align: right; font-variant-numeric: tabular-nums; }
.coverage-note { grid-column: 1 / -1; margin: 0 0 .3rem; }
.coverage h4 { font-size: 13px; margin: 1rem 0 .3rem; }
/* Each kind of gap gets its own mark: the panel has to answer "why", not only "how much". */
.kind-no-data { color: var(--warn); border-color: var(--warn); }
.kind-never-priced { color: var(--bad); border-color: var(--bad); }
.kind-declared { color: var(--bad); border-color: var(--bad); border-style: dashed; }
.kind-outside { color: var(--muted); border-style: dotted; }
.coverage-row.kind-never-priced .bar-fill,
.coverage-row.kind-declared .bar-fill { background: var(--bad); }
.coverage-row.kind-no-data .bar-fill { background: var(--warn); }
.coverage-row.kind-outside .bar-fill { background: var(--muted); }

.more {
  margin: .6rem 0; padding: .45rem .9rem; font: inherit; font-size: 13px;
  color: var(--fg); background: var(--panel); border: 1px solid var(--line);
  border-radius: 6px; cursor: pointer;
}
.more:hover { border-color: var(--accent); }

.axis { font-size: 11px; fill: var(--muted); }
.legends { display: flex; gap: 1rem; font-size: 12px; color: var(--muted); }
.legend { display: inline-flex; align-items: center; gap: .35rem; }
.swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }

footer {
  color: var(--muted); font-size: 13px;
  border-top: 1px solid var(--line); margin-top: 2rem;
}

img, svg { max-width: 100%; }

/* --- navigation ------------------------------------------------------------------ */

nav {
  display: flex; flex-wrap: wrap; gap: .25rem .5rem;
  margin: .75rem 0 .25rem;
}
nav a {
  color: var(--fg); text-decoration: none; font-size: 13px;
  padding: .3rem .6rem; border: 1px solid var(--line); border-radius: 999px;
}
nav a:hover, nav a:focus { border-color: var(--accent); color: var(--accent); }

/* Hidden above the breakpoint: with the links laid out in a row there is nothing to
   toggle, and a control that does nothing is worse than no control. */
.nav-toggle { display: none; }

/* --- phones ----------------------------------------------------------------------
   Below this width a ten-column table cannot be read by scrolling it sideways, so the
   rows stop being rows and become cards. The column heading travels down to each cell
   through data-label, because the header row is gone and a bare "1,45" says nothing.
   Tables without data-label keep their horizontal scroll rather than collapsing into
   an unlabelled column of numbers. */
@media (max-width: 640px) {
  header, main, footer { padding: .75rem .9rem; }

  .nav-toggle {
    display: inline-flex; align-items: center; gap: .4rem;
    margin-top: .6rem; padding: .45rem .8rem;
    font: inherit; font-size: 14px;
    color: var(--fg); background: var(--panel);
    border: 1px solid var(--line); border-radius: 8px; cursor: pointer;
  }
  nav { display: none; flex-direction: column; align-items: stretch; }
  nav.open { display: flex; }
  nav a { border-radius: 8px; padding: .5rem .7rem; }

  .controls { flex-direction: column; align-items: stretch; }
  .controls label, .controls select, .controls input { width: 100%; }

  table tr:has(> td[data-label]) {
    display: block;
    border: 1px solid var(--line); border-radius: 8px;
    padding: .5rem .65rem; margin-bottom: .6rem;
  }
  table td[data-label] {
    display: flex; justify-content: space-between; gap: 1rem;
    border: none; padding: .2rem 0; text-align: right;
  }
  table td[data-label]::before {
    content: attr(data-label);
    color: var(--muted); font-size: 12px; text-transform: uppercase;
    letter-spacing: .03em; text-align: left; flex: 0 0 auto;
  }
  /* The first cell of a card is its title, so it keeps the full width. */
  table td[data-label]:first-child {
    display: block; text-align: left;
    font-weight: 600; border-bottom: 1px solid var(--line);
    margin-bottom: .35rem; padding-bottom: .35rem;
  }
  table td[data-label]:first-child::before { display: block; font-weight: 400; }

  /* The header row belongs to a layout that no longer exists here. */
  table thead:has(~ tbody td[data-label]) { display: none; }

  /* An expanded breakdown is an accordion panel, not a table cell. Made a block
     explicitly: left as a table-row among block siblings the browser wraps it in an
     anonymous table box, which lays out but is not something to rely on. */
  tr.detail { display: block; }
  tr.detail td { display: block; padding: .5rem 0; }
  tr.detail[hidden] { display: none; }
}

/* --- glossary in place (task 15.2) -----------------------------------------------
   The reader who does not know what "log-loss" means is reading the sentence that uses
   it, not a page of definitions somewhere else. So the definition comes to the sentence:
   every first use is a button carrying its own bubble. */

button.term {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  border-bottom: 1px dashed var(--accent);
  padding: 0;
  cursor: help;
  position: relative;
}
button.term:hover, button.term:focus-visible { color: var(--accent); }
button.term:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* A data-term with no entry behind it is a bug; it should look like one. */
button.term-unknown { border-bottom-color: var(--bad); color: var(--bad); }

.term-pop {
  position: absolute;
  left: 0;
  top: calc(100% + .4rem);
  z-index: 20;
  width: max-content;
  max-width: min(22rem, 80vw);
  padding: .55rem .7rem;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  white-space: normal;
  color: var(--fg);
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-3px);
  transition: opacity .15s ease, transform .15s ease, visibility .15s;
}
button.term:hover .term-pop,
button.term:focus-visible .term-pop,
button.term.open .term-pop {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.term-pop a { color: var(--accent); }

.glossary { margin: .6rem 0 1rem; }
.glossary dt {
  font-weight: 600; margin-top: .9rem;
  scroll-margin-top: 1rem;
}
.glossary dd { margin: .15rem 0 0; color: var(--muted); font-size: 13.5px; max-width: 62ch; }

/* Whoever asked for less motion gets none of it, everywhere on this page. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* --- "start here" (task 15.1) ----------------------------------------------------
   Five numbered steps rather than a wall of prose. The number in the margin is the
   whole point of the layout: it tells the reader there are exactly five things to
   read before anything else, and that they are in an order. */

#start { border-top: none; }

ol.start {
  list-style: none;
  counter-reset: start;
  display: grid;
  gap: .9rem;
  margin: .8rem 0 1rem;
  padding: 0;
}
ol.start li {
  counter-increment: start;
  position: relative;
  padding: .85rem 1rem .85rem 3.1rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
}
ol.start li::before {
  content: counter(start);
  position: absolute;
  left: 1rem;
  top: .85rem;
  width: 1.5rem; height: 1.5rem;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
  color: var(--bg); background: var(--accent);
  border-radius: 50%;
}
ol.start h3 { margin: 0 0 .2rem; font-size: 14px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em; }
ol.start p { margin: 0; max-width: 68ch; }

@media (max-width: 640px) {
  ol.start li { padding: .75rem .8rem .75rem 2.7rem; }
  ol.start li::before { left: .7rem; top: .8rem; }
}

/* --- "your assumptions against the data" (task 15.3) -----------------------------
   Three columns, and the third one is the reason the section exists: a verdict a
   non-technical reader can act on, in the same row as the count it came from. The
   verdict badge is NOT the ROI colour scale - "Potwierdzone" means the owner's claim
   survived measurement, never that something was profitable. */

table.assumptions { table-layout: fixed; }
table.assumptions th:first-child, table.assumptions td:first-child { width: 22%; }
table.assumptions th:nth-child(2), table.assumptions td:nth-child(2) { width: 34%; }
table.assumptions td { vertical-align: top; padding: .7rem .6rem; }
table.assumptions tr.assumption + tr.assumption td { border-top: 1px solid var(--line); }
.verdict-text { margin-top: .35rem; font-size: 13.5px; }
.assumptions td:last-child { color: var(--muted); font-size: 13.5px; }

.badge-ok { color: var(--good); border-color: var(--good); }
.badge-partial { color: var(--warn); border-color: var(--warn); }
.badge-miss { color: var(--bad); border-color: var(--bad); }
.badge-none { color: var(--muted); border-style: dashed; }

/* On a phone the three columns become one card per rule, in reading order:
   what you wrote, what was measured, what it means. */
@media (max-width: 640px) {
  table.assumptions { table-layout: auto; }
  table.assumptions td[data-label] { display: block; text-align: left; }
  table.assumptions td[data-label]::before { display: block; margin-bottom: .15rem; }
  table.assumptions td[data-label]:first-child::before { display: none; }
}

/* --- the rating threshold, drawn (task 15.4) -------------------------------------
   Two bars per bucket, one window each, never averaged into one. The third swatch is
   the important one: a bar computed from fewer bets than the scan's own minimum gets
   no colour at all, because a green +20% over seventy bets is noise in a costume. */

.chart { margin: .8rem 0 1rem; }
.chart svg { width: 100%; height: auto; max-width: 680px; display: block; }
.bar-tuning { fill: var(--accent); }
.bar-validation { fill: var(--warn); }
.bar-thin { fill: var(--line); stroke: var(--muted); stroke-dasharray: 2 2; }
.thin-mark, .spec-mark { font-size: 10px; fill: var(--muted); }
.spec-mark { fill: var(--warn); }
.swatch-tuning { background: var(--accent); }
.swatch-validation { background: var(--warn); }
.swatch-thin { background: var(--line); border: 1px dashed var(--muted); }
.chart figcaption.legends { flex-wrap: wrap; margin-top: .4rem; }

/* --- tabs (task 15.6) -------------------------------------------------------------
   The same nav element as before, so the phone menu button keeps working; what changed
   is that the links now select a panel instead of scrolling to a heading. */

nav.tabs a.tab.current {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}
nav.tabs a.tab-link { color: var(--muted); }
nav.tabs a.tab-link:hover { color: var(--accent); }

.panel[hidden] { display: none; }
/* A panel that has just been opened fades in over a tenth of a second - enough to say
   "this is new content", not enough to be a wait. */
.panel { animation: panel-in .16s ease-out; }
@keyframes panel-in {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: 1; transform: none; }
}
.panel > section:first-child { border-top: none; }

/* --- 15.8 the visual layer ---------------------------------------------------------
   Restraint is the whole design here. One accent, one type scale, one spacing scale,
   and colour reserved for the two things that carry meaning: a return above or below
   zero, and a warning. Everything else is ink on paper. */

.panel > section:first-child { border-top: 1px solid var(--line); }

/* Cards inside cards would be a hall of mirrors, so nested surfaces step DOWN in
   contrast rather than adding another border. */
section table { border: 1px solid var(--line); }
tr.detail > td { background: var(--panel-2); }
.player-row:hover, .explorer-row:hover { background: var(--accent-soft); }

.verdict, .warn-box, .good-box {
  box-shadow: none;
  background: var(--bg);
  padding: var(--s3) var(--s4);
  font-size: var(--t-sm);
}
.warn-box { border-left: 3px solid var(--warn); }
.good-box { border-left: 3px solid var(--good); }

.badge {
  font-size: var(--t-xs); font-weight: 600;
  letter-spacing: .02em; padding: .12rem .5rem;
}

/* --- the tab strip ---------------------------------------------------------------- */

nav.tabs { gap: var(--s1); margin: var(--s3) 0 0; }
nav a {
  font-size: var(--t-sm); padding: .4rem .8rem;
  border-radius: 999px; transition: background .15s ease, color .15s ease,
    border-color .15s ease;
}
nav.tabs a.tab.current {
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent);
}

/* --- icons, drawn rather than downloaded ------------------------------------------
   Inline SVG, sized in em so an icon always matches the text it sits beside. No icon
   font: a font is a network dependency, and this site has none. */

.icon {
  width: 1em; height: 1em; flex: 0 0 auto;
  vertical-align: -.125em; fill: none;
  stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.nav-toggle .icon { width: 1.1em; height: 1.1em; }

/* --- movement, and only where it carries information -------------------------------
   Three effects, none over 200 ms: a figure counts up as it lands, a value that just
   changed flashes once, and a panel fades in. Nothing loops, nothing bounces, nothing
   moves more than a few pixels. */

.figure { font-variant-numeric: tabular-nums; }

@keyframes flash-change {
  from { background: var(--accent-soft); }
  to { background: transparent; }
}
.flash { animation: flash-change .2s ease-out; border-radius: 3px; }

tr.detail td > * { animation: detail-in .16s ease-out; }
@keyframes detail-in {
  from { opacity: 0; transform: translateY(-2px); }
  to { opacity: 1; transform: none; }
}

/* --- phones ------------------------------------------------------------------------ */

@media (max-width: 640px) {
  header, main, footer { padding: var(--s3) var(--s3); }
  section { padding: var(--s3) var(--s3) var(--s4); margin: var(--s3) 0; }
  h1 { font-size: var(--t-lg); }
  h2 { font-size: var(--t-md); }
  h3 { font-size: var(--t-base); }
  /* A card inside a card inside a phone is all border and no content. */
  section table { border: none; }
}
