/* The page is a printed statistical plate; the product is a dark terminal block
   set into it. Two rules hold the whole system together:

   1. Chroma appears only where a MEASUREMENT appears. Never a button fill,
      never a nav hover, never a gradient. If it is not a number or the bound
      of one, it is ink, rule or ground.
   2. An interval is drawn as an object, never printed as a string. The site's
      thesis is that the edge is a range; a page that only says so in words is
      not making the argument it claims to make.

   Light is the bare :root default. Dark is the media override plus the
   [data-theme] stamp, so all three viewer states resolve as a set. */
:root{
  /* --- ground --- */
  --plate:#ece9e2;        /* page ground: warm coated chart stock */
  --card:#f7f5f1;         /* lifted plot / table / figure surface */
  --sink:#e3dfd6;         /* inset: table head, app bar, footer */

  /* --- ink --- */
  --ink:#16161a;          /* body type AND the terminal-block ground */
  --ink-2:#57544d;        /* labels, secondary prose      6.23:1 on plate */
  --ink-3:#7d786e;        /* decorative only              3.62:1 — never text
                             that carries meaning on its own */
  --rule:#b8b3a8;         /* axes, ticks, hairlines, table rules
                             NON-TEXT ONLY, by design */

  /* --- measurement chroma (the only chroma on the site) --- */
  --indigo:#2d3561;       /* interval bounds, computed values   9.66:1 */
  --oxblood:#9e2f27;      /* negative side of zero, named costs 5.99:1 */
  --band:rgba(45,53,97,.16);      /* interval fill */
  --band-neg:rgba(158,47,39,.15); /* interval fill left of zero */
  --hatch:rgba(158,47,39,.32);    /* 45 degree hatch = "not claimable" */

  /* --- the terminal block --- */
  --term:#16161a;
  --term-line:#2c2c33;

  /* --- type --- */
  --serif:ui-serif,"Iowan Old Style",Charter,"Bitstream Charter",Georgia,Cambria,serif;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;

  --t-1:.72rem;   --t-2:.82rem;   --t-3:.9rem;    --t-4:1rem;
  --t-5:1.0625rem;--t-6:1.25rem;  --t-7:1.75rem;
  --t-8:clamp(2.25rem,5.2vw,3.4rem);

  --s-1:.25rem; --s-2:.5rem;  --s-3:.75rem; --s-4:1rem;
  --s-5:1.5rem; --s-6:2.25rem;--s-7:3.5rem; --s-8:5.5rem;

  /* the asymmetry is what makes it a report rather than an essay */
  --measure-prose:34rem;
  --measure-plate:58rem;
  --measure-page:46rem;

  --r:2px;                /* the only radius on the site */
}

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --plate:#15161a;
    --card:#1c1e24;
    --sink:#111216;
    --ink:#e8e6e0;
    --ink-2:#9a968b;
    --ink-3:#75716a;
    --rule:#3a3d46;
    --indigo:#8f9bd8;
    --oxblood:#e0685c;
    --band:rgba(143,155,216,.22);
    --band-neg:rgba(224,104,92,.20);
    --hatch:rgba(224,104,92,.34);
    --term:#0f1014;       /* a step BELOW --plate, so the block stays an object */
    --term-line:#3a3d46;
  }
}
:root[data-theme="dark"]{
  --plate:#15161a; --card:#1c1e24; --sink:#111216;
  --ink:#e8e6e0;   --ink-2:#9a968b; --ink-3:#75716a; --rule:#3a3d46;
  --indigo:#8f9bd8;--oxblood:#e0685c;
  --band:rgba(143,155,216,.22); --band-neg:rgba(224,104,92,.20);
  --hatch:rgba(224,104,92,.34);
  --term:#0f1014; --term-line:#3a3d46;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--plate);color:var(--ink);
  font:var(--t-5)/1.62 var(--sans);
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}

/* numbers in sentences should read as sentences; numbers in columns should
   line up. On the system stacks this is a graceful no-op. */
p,li{font-variant-numeric:oldstyle-nums}
.rf,.app,table,.figure,.screen,.plate{font-variant-numeric:tabular-nums lining}

/* ---------- chrome ---------- */
header{position:sticky;top:0;z-index:20;background:var(--plate);
  border-bottom:1px solid var(--rule)}
nav{max-width:70rem;margin:0 auto;padding:.8rem 1.5rem;display:flex;
  align-items:center;gap:1.6rem;flex-wrap:wrap}
.brand{display:inline-flex;align-items:center;gap:.5rem;color:var(--ink);
  font-family:var(--serif);font-weight:600;font-size:1.12rem;
  letter-spacing:-.015em;text-decoration:none}
.brand:hover{color:var(--ink)}
.mark{width:1.35rem;height:1.35rem;color:var(--ink);flex:none}
.links{display:flex;gap:1.35rem;flex-wrap:wrap}
nav .links a{color:var(--ink-2);text-decoration:none;font-size:.92rem;
  font-weight:500;padding:.15rem 0;border-bottom:1px solid transparent}
nav .links a:hover{color:var(--ink);border-bottom-color:var(--ink)}

main{max-width:var(--measure-page);margin:0 auto;padding:0 var(--s-5) var(--s-8)}
body.home main{max-width:var(--measure-plate)}
body.home main>h1,body.home main>h2,body.home main>p,
body.home main>ul,body.home main>table{
  max-width:var(--measure-prose);margin-inline:0}
body.home main>.plate,body.home main>.app,body.home main>.scroll,
body.home main>.figure,body.home main>.screen{max-width:var(--measure-plate)}

/* ---------- type ---------- */
h1{font-family:var(--serif);font-size:var(--t-8);line-height:1.04;
  letter-spacing:-.018em;font-weight:600;margin:var(--s-7) 0 var(--s-4);
  text-wrap:balance}
h2{font-family:var(--serif);font-size:var(--t-7);font-weight:600;
  letter-spacing:-.01em;margin:var(--s-7) 0 var(--s-3);
  padding-top:var(--s-5);border-top:1px solid var(--rule);
  text-wrap:balance}
p{margin:var(--s-3) 0;color:var(--ink-2)}
.lede{font-size:var(--t-6);line-height:1.5;color:var(--ink-2);
  max-width:var(--measure-prose)}
strong{color:var(--ink);font-weight:600}
a{color:var(--ink);text-decoration-color:var(--rule);text-underline-offset:3px;
  text-decoration-thickness:1px}
a:hover{text-decoration-color:var(--oxblood)}
ul{padding-left:1.15rem}
li{margin:var(--s-1) 0;color:var(--ink-2)}
.caveat{color:var(--ink-2);font-size:var(--t-3);
  border-left:2px solid var(--rule);padding-left:var(--s-4)}

/* ---------- hero ---------- */
.hero{padding:var(--s-8) 0 var(--s-5);text-align:left}
.eyebrow{margin:0 0 var(--s-4);font-size:var(--t-1);font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2)}
.hero h1{margin:0 0 var(--s-4)}
.hero .lede{margin:0;text-align:left}
.cta{display:flex;gap:var(--s-3);justify-content:flex-start;flex-wrap:wrap;
  margin:var(--s-6) 0 var(--s-2)}
.btn{display:inline-block;padding:.6rem 1.1rem;border-radius:var(--r);
  background:transparent;color:var(--ink);border:1px solid var(--ink);
  text-decoration:none;font-weight:600;font-size:var(--t-3);
  transition:background-color .12s ease,color .12s ease}
.btn:hover{background:var(--ink);color:var(--plate)}
/* --rule is 1.72:1 and is reserved for axes and hairlines. A button's border
   is the boundary of an active control, so it needs 3:1 under WCAG 1.4.11 —
   --ink-2 is 6.23:1 and still reads a clear step below the primary. */
.btn.ghost{border-color:var(--ink-2);color:var(--ink-2)}
.btn.ghost:hover{border-color:var(--ink);background:transparent;color:var(--ink)}

/* ---------- the range-frame: one primitive, four scales ----------
   anatomy, fixed and never varied:
     axis    1px --rule hairline, full width
     band    --band fill from lo to hi, full height  (the interval IS the mark)
     serifs  --indigo at both bounds, full height + overshoot
     point   --ink tick, 56% height, FULL contrast

   The point estimate is subordinate by EXTENT, not by contrast. Ghosting it
   would encode "numbers are unknowable", and that is not the claim. The claim
   is: here is an honest number, its range, and a stake you can place. */
.rf{--lo:0%;--hi:100%;--pt:50%;
  position:relative;display:inline-block;flex:none;
  width:var(--rf-w,4rem);height:var(--rf-h,.8em);
  vertical-align:-.14em}
.rf::before{content:"";position:absolute;left:0;right:0;top:50%;
  height:1px;margin-top:-.5px;background:var(--rule)}

.rf-band{position:absolute;top:0;bottom:0;
  left:var(--lo);right:calc(100% - var(--hi));
  background-color:var(--band)}
.rf-band::before,.rf-band::after{content:"";position:absolute;
  top:-2px;bottom:-2px;width:1.5px;background:var(--indigo)}
.rf-band::before{left:0}
.rf-band::after{right:0}

.rf-pt{position:absolute;left:var(--pt);top:22%;height:56%;
  width:1.5px;margin-left:-.75px;background:var(--ink)}

/* the value Bookbreaker actually stands behind: solid, below the axis */
.rf-real{position:absolute;left:var(--rl);bottom:-5px;
  width:0;height:0;margin-left:-3px;
  border-left:3px solid transparent;border-right:3px solid transparent;
  border-bottom:4px solid var(--indigo)}

/* an interval containing zero is not claimable, and says so with TEXTURE
   rather than hue — survives greyscale and every colour deficiency */
.rf-zero{position:absolute;left:var(--z);top:-4px;bottom:-4px;
  width:1px;margin-left:-.5px;background:var(--ink)}
.rf-neg{position:absolute;top:0;bottom:0;
  left:var(--lo);right:calc(100% - var(--z));background:var(--band-neg)}
.rf-band.is-zero{background-image:repeating-linear-gradient(45deg,
  transparent 0 3px,var(--hatch) 3px 5px)}

/* a competitor's figure: no band, no bounds. the absence is the argument. */
.rf--bare .rf-band{background:none}
.rf--bare .rf-band::before,.rf--bare .rf-band::after{display:none}

.rf--inline{--rf-w:4rem;--rf-h:.8em}
.rf--row{--rf-w:100%;--rf-h:.95rem;display:block;vertical-align:baseline}
.rf--plate{--rf-w:100%;--rf-h:2.4rem;display:block;margin:var(--s-3) 0}
.rf--hero{--rf-w:100%;--rf-h:3.4rem;display:block;margin:var(--s-4) 0}
.rf--plate .rf-pt,.rf--hero .rf-pt{top:26%;height:48%;width:2px;margin-left:-1px}
.rf--plate .rf-band::before,.rf--plate .rf-band::after,
.rf--hero  .rf-band::before,.rf--hero  .rf-band::after{width:2px;top:-5px;bottom:-5px}

/* ---------- the plate wrapper ---------- */
.plate{margin:var(--s-5) 0;padding:var(--s-4) var(--s-5) var(--s-3);
  background:var(--card);border:1px solid var(--rule);border-radius:var(--r);
  max-width:var(--measure-plate)}
.plate-cap{font-family:var(--sans);font-size:var(--t-1);font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);
  margin:0 0 var(--s-2)}
/* Each label sits under the mark it names, at the same measured percentage the
   frame used. Spreading them edge-to-edge would put "0" in the middle of a
   panel whose zero rule is at 31% — a key that points at the wrong thing is
   worse than no key. */
.plate-key{position:relative;height:1.15rem;margin-top:var(--s-2);
  font-family:var(--mono);font-size:var(--t-2);color:var(--ink-2)}
.plate-key span{position:absolute;left:var(--at);transform:translateX(-50%);
  white-space:nowrap}
.plate-key .neg{color:var(--oxblood)}
.plate--split{display:grid;gap:var(--s-5)}
@media(min-width:44rem){.plate--split{grid-template-columns:1fr 1fr}}

/* Marks a competitor's over-precision. The dotted rule is the whole device:
   dimming just the decimals would mean wrapping them in a tag, and check.py's
   visible() replaces tags with spaces — "5.<em>91</em>" tokenises as 5 and 91,
   neither of which is a measured number, and the build fails. The number stays
   one text node. */
.over{border-bottom:1px dotted var(--rule)}

/* ---------- the terminal block: the one dark object, in BOTH themes ----------
   Re-scoping the tokens inside .app is what lets one range-frame component
   serve two grounds: every .rf inside recolours itself automatically. */
.app{
  --card:#1c1e24; --sink:#1a1b21;
  --ink:#e8e6e0; --ink-2:#9a968b; --ink-3:#75716a; --rule:#3a3d46;
  --indigo:#8f9bd8; --oxblood:#e0685c;
  --band:rgba(143,155,216,.26); --band-neg:rgba(224,104,92,.22);
  --hatch:rgba(224,104,92,.36);

  margin:var(--s-6) 0 var(--s-7);max-width:var(--measure-plate);
  background:var(--term);color:var(--ink);
  border:1px solid var(--term-line);border-radius:var(--r);
  overflow:hidden;font-family:var(--mono);font-size:var(--t-2)}
.app-bar{display:flex;align-items:center;gap:var(--s-2);
  padding:var(--s-2) var(--s-4);background:var(--sink);
  border-bottom:1px solid var(--rule)}
.dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--rule);flex:none}
.app-title{margin-left:var(--s-2);color:var(--ink-2);font-weight:500}
.app-meta{margin-left:auto;color:var(--ink-2);font-size:var(--t-1)}
.app-head,.app-row{display:grid;
  grid-template-columns:1.3fr .86fr .58fr .7fr 2.3fr .48fr .82fr .78fr;
  gap:var(--s-3);padding:var(--s-2) var(--s-4);align-items:center}
.app-head{font-family:var(--sans);font-size:var(--t-1);text-transform:uppercase;
  letter-spacing:.09em;color:var(--ink-2);background:var(--sink);
  border-bottom:1px solid var(--rule)}
.app-row{border-bottom:1px solid var(--rule)}
.app-row:last-of-type{border-bottom:0}
.app-row:hover{background:var(--card)}

/* tabular figures make + and - exactly one digit wide, so right-aligned
   numeric columns align their signs down the whole strip */
.app-head span:nth-child(3),.app-row span:nth-child(3),
.app-head span:nth-child(4),.app-row span:nth-child(4),
.app-head span:nth-child(6),.app-row span:nth-child(6),
.app-head span:nth-child(8),.app-row span:nth-child(8){text-align:right}

.ev-name{color:var(--ink);font-weight:500}
.dim{color:var(--ink-2)}
.price{color:var(--ink-2)}
.band{min-width:0}
.pos{color:var(--ink-2);font-weight:400}
.pos.strong{color:var(--indigo);font-weight:500}

/* fill stays deliberately subordinate: a bar with NO terminators, so it can
   never be mistaken for an interval */
.fill{display:flex;align-items:center;gap:var(--s-2);min-width:0}
.fill i{display:block;height:2px;border-radius:0;background:var(--rule);
  opacity:1;min-width:2px}
.fill b{font-weight:400;color:var(--ink-2);font-size:var(--t-1)}

.app-foot{padding:var(--s-3) var(--s-4);background:var(--sink);
  color:var(--ink-2);font-family:var(--sans);font-size:var(--t-3);
  line-height:1.5;border-top:1px solid var(--rule)}
.app-foot strong{color:var(--ink);font-weight:600}

/* ---------- figures ---------- */
.figure{background:var(--card);border:1px solid var(--rule);
  border-left:2px solid var(--indigo);border-radius:var(--r);
  padding:var(--s-4) var(--s-5);margin:var(--s-5) 0;font-family:var(--mono);
  font-size:var(--t-3);line-height:1.6;overflow-x:auto}
.screen{background:var(--card);border:1px solid var(--rule);
  border-radius:var(--r);padding:var(--s-4) var(--s-5);margin:var(--s-5) 0;
  font-family:var(--mono);font-size:var(--t-2);line-height:1.95;
  overflow-x:auto;white-space:nowrap}
.screen .num{color:var(--indigo)}
.scroll{margin:var(--s-5) 0;overflow-x:auto;border:1px solid var(--rule);
  border-radius:var(--r);background:var(--card)}
table{border-collapse:separate;border-spacing:0;width:100%;
  min-width:max-content;font-size:var(--t-3);font-family:var(--mono);
  white-space:nowrap;background:var(--card)}
th{text-align:left;padding:var(--s-2) var(--s-3);font-family:var(--sans);
  font-size:var(--t-1);text-transform:uppercase;letter-spacing:.09em;
  color:var(--ink-2);font-weight:600;background:var(--sink);
  border-bottom:1px solid var(--rule)}
td{padding:var(--s-2) var(--s-3);border-bottom:1px solid var(--rule);
  color:var(--ink-2)}
tr:last-child td{border-bottom:0}
td:first-child{font-family:var(--sans);color:var(--ink-2)}
tr:hover td{background:var(--sink)}

/* ---------- cards ---------- */
main>ul:has(a){list-style:none;padding:0;margin:var(--s-6) 0;display:grid;
  gap:var(--s-3);grid-template-columns:repeat(auto-fill,minmax(16.5rem,1fr))}
main>ul:has(a) li{margin:0;background:var(--card);border:1px solid var(--rule);
  border-radius:var(--r);padding:var(--s-4) var(--s-4);font-size:var(--t-3);
  color:var(--ink-2);display:flex;flex-direction:column;gap:var(--s-1);
  transition:border-color .15s ease}
main>ul:has(a) li:hover{border-color:var(--ink)}
main>ul:has(a) a{font-weight:600;text-decoration:none;color:var(--ink);
  font-family:var(--serif);letter-spacing:-.005em}
main>ul:has(a) li:hover a{color:var(--ink)}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--rule);background:var(--sink);
  margin-top:var(--s-7)}
.foot-grid{max-width:var(--measure-page);margin:0 auto;
  padding:var(--s-6) var(--s-5) var(--s-4);
  display:grid;gap:var(--s-5);grid-template-columns:1.6fr 1fr 1fr}
.foot-grid p{margin:.3rem 0;font-size:var(--t-3);color:var(--ink-2)}
.foot-brand{font-family:var(--serif);font-weight:600;color:var(--ink);
  font-size:var(--t-4);letter-spacing:-.01em}
.foot-head{font-size:var(--t-1)!important;text-transform:uppercase;
  letter-spacing:.1em;color:var(--ink)!important;font-weight:600;
  margin-bottom:var(--s-2)!important}
.foot-grid a{color:var(--ink-2);text-decoration:none}
.foot-grid a:hover{color:var(--ink);text-decoration:underline;
  text-decoration-color:var(--rule)}
.foot-fine{max-width:var(--measure-page);margin:0 auto;
  padding:0 var(--s-5);color:var(--ink-2);
  font-size:var(--t-2);line-height:1.55}
.foot-fine:last-child{padding-bottom:var(--s-6)}

@media(prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
  html{scroll-behavior:auto}
}
:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}

@media(max-width:52rem){
  .app{font-size:.76rem}
  /* the band is now the most valuable column on the strip, so it survives to
     the smallest breakpoint. Book and Age go first. */
  .app-head,.app-row{grid-template-columns:1.4fr .62fr .78fr 1.6fr .9fr .85fr}
  .app-head span:nth-child(2),.app-row span:nth-child(2),
  .app-head span:nth-child(6),.app-row span:nth-child(6){display:none}
  .app-head span:nth-child(3),.app-row span:nth-child(3),
  .app-head span:nth-child(4),.app-row span:nth-child(4),
  .app-head span:nth-child(8),.app-row span:nth-child(8){text-align:right}
}
@media(max-width:40rem){
  main{padding:0 1.15rem 3.5rem}
  .hero{padding:var(--s-6) 0 var(--s-2)}
  .hero .lede{font-size:var(--t-4)}
  h2{margin-top:var(--s-6)}
  .foot-grid{grid-template-columns:1fr;padding:var(--s-6) 1.15rem .6rem}
  .app-meta{display:none}
  .app-head,.app-row{grid-template-columns:1.3fr .8fr 1.5fr .9fr}
  .app-head span:nth-child(3),.app-row span:nth-child(3),
  .app-head span:nth-child(7),.app-row span:nth-child(7){display:none}

  /* The nav wrapped onto three lines and ate half a phone screen of sticky
     header. One row that scrolls sideways instead — the brand stays put and
     the links slide. */
  nav{padding:.6rem 0 .6rem 1.15rem;gap:.85rem;flex-wrap:nowrap;
    align-items:center}
  .brand{flex:none;font-size:1.05rem}
  .links{flex:1 1 auto;flex-wrap:nowrap;gap:1.05rem;overflow-x:auto;
    padding-right:1.15rem;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .links::-webkit-scrollbar{display:none}
  nav .links a{white-space:nowrap;font-size:.88rem}
}
