/* ============================================================================
   CYBERCAB FLEET OPERATOR — styles
   Phone first. 17px floor on desktop, 18px on phones. 44px tap targets.
   Every text/background pair below was checked to 4.5:1 or better.
   ========================================================================== */

:root{
  --bg:#0d1117;          /* page */
  --panel:#161c24;       /* cards */
  --panel2:#1e262f;      /* raised */
  --line:#2c3743;
  --ink:#eef3f8;         /* 15.9:1 on --bg */
  --ink2:#b9c7d4;        /* 8.4:1 on --panel */
  --dim:#8fa1b1;         /* 5.2:1 on --panel */
  --gold:#f2c14e;        /* 10.4:1 on --panel — the car is gold */
  --good:#5fd68d;        /* 9.6:1 on --panel */
  --bad:#ff7b7b;         /* 7.0:1 on --panel */
  --warn:#ffb454;        /* 9.7:1 on --panel */
  --blue:#7cc4ff;        /* 8.9:1 on --panel */
  --purple:#c9a6ff;
  --r:14px;
  --tap:46px;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; font-size:17px}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font:1rem/1.55 "Inter",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  padding-bottom:env(safe-area-inset-bottom);
}
/* Phones get BIGGER type, not smaller. Scaling the ROOT scales every rem-sized
   caption with it — sizing only <body> left them stuck at the browser's 16px
   default and small text landed at 12.5px on a phone. */
@media (max-width:520px){ html{ font-size:18px } body{ line-height:1.6 } }

.wrap{max-width:820px;margin:0 auto;padding:14px 14px 90px}

/* ------------------------------------------------------------------ type */
h1,h2,h3{margin:0 0 .5rem;line-height:1.25;font-weight:750;letter-spacing:-.015em}
h1{font-size:1.75rem;line-height:1.2;letter-spacing:-.01em}
h2{font-size:1.18rem}
h3{font-size:1.09rem}
p{margin:0 0 .7rem}
.mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;font-variant-numeric:tabular-nums}
.dim{color:var(--dim)}
.ink2{color:var(--ink2)}
.small{font-size:1rem;line-height:1.5}
.tiny{font-size:1rem;line-height:1.5;color:var(--dim)}
.gold{color:var(--gold)} .good{color:var(--good)} .bad{color:var(--bad)} .warn{color:var(--warn)} .blue{color:var(--blue)}
.center{text-align:center}
.nowrap{white-space:nowrap}

/* ---------------------------------------------------------------- layout */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:14px;margin:0 0 12px}
.card.tight{padding:11px}
.row{display:flex;gap:10px;align-items:center}
.row.wrap{flex-wrap:wrap}
.spread{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
@media (max-width:430px){ .grid3{grid-template-columns:1fr 1fr} }

/* ----------------------------------------------------------------- topbar */
.topbar{position:sticky;top:0;z-index:40;background:rgba(13,17,23,.97);
  border-bottom:1px solid var(--line);backdrop-filter:blur(8px)}
.topbar .inner{max-width:820px;margin:0 auto;padding:9px 14px;display:flex;
  justify-content:space-between;align-items:center;gap:10px}
.brand{font-weight:800;font-size:1rem;letter-spacing:-.01em;display:flex;gap:7px;align-items:center}
.brand .dot{width:9px;height:9px;border-radius:50%;background:var(--gold);flex:0 0 auto}
.stat{text-align:right;line-height:1.15}
.stat b{display:block;font-size:1.12rem;font-variant-numeric:tabular-nums}
.stat span{font-size:1rem;color:var(--dim);text-transform:uppercase;letter-spacing:.07em}

/* ---------------------------------------------------------------- buttons */
button{font:inherit;font-weight:650;color:var(--ink);background:var(--panel2);
  border:1px solid var(--line);border-radius:11px;padding:12px 14px;
  min-height:var(--tap);cursor:pointer;text-align:left;-webkit-tap-highlight-color:transparent}
button:hover:not(:disabled){border-color:#4a5a6b;background:#242e39}
button:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
button:disabled{opacity:.42;cursor:not-allowed}
.btn-primary{background:var(--gold);color:#12161c;border-color:var(--gold);
  font-weight:800;text-align:center;width:100%;font-size:1.08rem;min-height:56px}
.btn-primary:hover:not(:disabled){background:#ffd066;border-color:#ffd066}
.btn-ghost{background:transparent}
/* A SECOND TIER, between the gold primary and the ghost. Two things in this
   game are not decoration -- the number register, which is the whole claim it
   makes, and the board -- and a btn-ghost is how Review Day went unnoticed for
   weeks. Panel-2 fill with a lifted border reads as a real control at a glance;
   the ghosts underneath it stay ghosts, which is the point of having two tiers.
   --ink on #1e262f is 12.4:1; the hover fill keeps it above 10:1. */
.btn-major{background:#232d38;border:2px solid #5d7288;color:var(--ink);
  width:100%;text-align:center;font-weight:800;font-size:1.05rem;
  min-height:54px;margin-top:9px}
.btn-major:hover:not(:disabled){background:#2d3a47;border-color:#7d94aa}
.btn-row{display:flex;gap:8px;flex-wrap:wrap}
.btn-row button{flex:1 1 auto}

/* segmented option pickers ------------------------------------------------ */
.seg{display:flex;gap:6px;flex-wrap:wrap;margin:4px 0 2px}
.seg button{flex:1 1 0;min-width:88px;text-align:center;padding:11px 8px;font-size:1rem;font-weight:650}
.seg button[aria-pressed="true"]{background:var(--gold);color:#12161c;border-color:var(--gold)}
.lbl{font-size:1rem;text-transform:uppercase;letter-spacing:.09em;color:var(--dim);
  font-weight:700;margin:12px 0 2px}
.lbl:first-child{margin-top:0}

/* ------------------------------------------------------------------ meters */
.util{display:flex;height:26px;border-radius:7px;overflow:hidden;background:#0a0e13;
  border:1px solid var(--line)}
.util i{display:block;height:100%}
.u-earning{background:var(--good)}
.u-deadhead{background:#5b7fa8}
.u-charging{background:var(--blue)}
.u-cleaning{background:var(--purple)}
.u-stuck{background:var(--bad)}
.u-idle{background:#39434f}
.u-offline{background:#20272f}
.key{display:flex;flex-wrap:wrap;gap:5px 12px;margin-top:8px;font-size:1rem}
.key span{display:flex;align-items:center;gap:6px;color:var(--ink2)}
.key i{width:12px;height:12px;border-radius:3px;display:block;flex:0 0 auto}

.bignum{font-size:2.5rem;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;
  letter-spacing:-.03em}
@media (max-width:430px){ .bignum{font-size:2.2rem} }

/* ------------------------------------------------------------------- cars */
.car{border:1px solid var(--line);border-radius:12px;padding:12px;margin-bottom:10px;background:var(--panel2)}
.car h3{display:flex;align-items:center;gap:8px;margin-bottom:2px}
.chip{display:inline-block;font-size:1rem;font-weight:700;padding:3px 8px;border-radius:20px;
  background:#0a0e13;border:1px solid var(--line);color:var(--ink2);white-space:nowrap}
.chip.ok{color:var(--good);border-color:#2c5340}
.chip.warn{color:var(--warn);border-color:#5b4526}
.chip.bad{color:var(--bad);border-color:#5e2e2e}

.bar{height:9px;border-radius:5px;background:#0a0e13;overflow:hidden;border:1px solid var(--line)}
.bar i{display:block;height:100%;background:var(--good)}

/* ------------------------------------------------------------------ modal */
.scrim{position:fixed;inset:0;background:rgba(5,8,12,.88);z-index:100;display:flex;
  align-items:flex-end;justify-content:center;padding:0}
@media (min-width:560px){ .scrim{align-items:center;padding:20px} }
.modal{background:var(--panel);border:1px solid var(--line);border-radius:18px 18px 0 0;
  width:100%;max-width:560px;max-height:92vh;overflow:auto;padding:18px 16px 22px}
@media (min-width:560px){ .modal{border-radius:18px} }
.modal h2{display:flex;gap:10px;align-items:flex-start;font-size:1.16rem}
.modal .ico{font-size:1.5rem;line-height:1;flex:0 0 auto}
.opt{display:block;width:100%;margin:9px 0 0;padding:13px 14px;border-radius:12px}
.opt b{display:block;font-size:1.06rem;margin-bottom:2px;font-weight:700}
.opt span{display:block;font-size:1rem;color:var(--ink2);font-variant-numeric:tabular-nums}

/* ------------------------------------------------------------------ ticker */
.ticker{background:#0a0e13;border:1px solid var(--line);border-radius:12px;padding:12px;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:1rem;
  min-height:200px;max-height:44vh;overflow:auto;position:relative}
.ticker .clock{font-size:2.1rem;font-weight:800;color:var(--gold);letter-spacing:.02em}
.tline{color:var(--ink2);padding:2px 0;border-bottom:1px solid #151b22}

/* ------------------------------------------------------------------ tables */
.pl{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
.pl td{padding:8px 0;border-bottom:1px solid var(--line);font-size:1rem}
.pl td:last-child{text-align:right;font-weight:650;white-space:nowrap}
/* Money belongs on one line, right-aligned. A SENTENCE in the last column does
   not: nowrap pushed the rating ladder 231px past the edge of a 390px phone and
   gave the whole page a sideways scroll. `pl wrap` is for the tables whose
   right-hand column is prose. */
.pl.wrap td:last-child{white-space:normal;text-align:left;font-weight:650}
@media (max-width:520px){ .pl.wrap td{display:block;padding:6px 0;border-bottom:none}
  .pl.wrap tr{display:block;border-bottom:1px solid var(--line);padding:4px 0}
  .pl.wrap td:first-child{padding-bottom:2px} }
.pl tr.tot td{border-bottom:none;border-top:2px solid var(--line);font-weight:800;
  font-size:1.05rem;padding-top:10px}

/* ------------------------------------------------------------------ alerts */
.alert{border-radius:11px;padding:12px 13px;margin:0 0 10px;font-size:1rem;
  border:1px solid;line-height:1.5}
.alert.warn{background:#2a2013;border-color:#6b5124;color:#ffd79a}
.alert.bad{background:#2c1717;border-color:#6e3030;color:#ffbdbd}
.alert.info{background:#12222e;border-color:#2c4f66;color:#bfe2ff}
.alert.good{background:#132a1e;border-color:#2c5340;color:#b6f0cd}
.alert b{font-weight:800}

/* ------------------------------------------------------------------- misc */
.src{font-size:1rem;color:var(--dim);border-left:3px solid var(--gold);
  padding:2px 0 2px 10px;margin:8px 0;line-height:1.5}
.src b{color:var(--gold);font-weight:700}
.tag{font-size:1rem;font-weight:800;letter-spacing:.08em;padding:2px 6px;border-radius:5px;
  text-transform:uppercase;white-space:nowrap}
.tag.sourced{background:#14301f;color:#7fe0a5;border:1px solid #2c5340}
.tag.balance{background:#2d2416;color:#ffcd7d;border:1px solid #5b4526}
/* Links in prose. --blue is 8.9:1 on --panel and 8.2:1 on the alert fills. */
.card a,.alert a{color:var(--blue)}
.card a:hover,.alert a:hover{color:#a8d8ff}
hr{border:none;border-top:1px solid var(--line);margin:14px 0}
.tabs{display:flex;gap:6px;margin-bottom:12px}
.tabs button{flex:1;text-align:center;padding:11px 6px;font-size:1rem}
.tabs button[aria-pressed="true"]{background:var(--panel2);border-color:#4a5a6b;color:var(--gold)}
.sticky-cta{position:fixed;left:0;right:0;bottom:0;z-index:50;padding:10px 14px
  calc(10px + env(safe-area-inset-bottom));background:linear-gradient(180deg,rgba(13,17,23,0),rgba(13,17,23,.97) 26%)}
.sticky-cta .inner{max-width:820px;margin:0 auto}
.hidden{display:none !important}
.spark{display:flex;align-items:flex-end;gap:2px;height:52px}
.spark i{flex:1 1 0;min-width:2px;border-radius:2px 2px 0 0;background:var(--good);display:block}
.spark i.neg{background:var(--bad)}

/* --- Cybercab hero image -------------------------------------------------
   Dave supplies this from Grok Imagine. Until the file exists the onerror
   handler swaps in .hero-fallback, so the page never shows a broken image. */
.hero{display:block;width:100%;height:auto;aspect-ratio:3/2;
  object-fit:cover;object-position:50% 64%;border-radius:12px;margin:0 0 8px;
  border:1px solid #4a3c1a}
/* The source image is SQUARE with the car low in the frame. A centred 16:9 crop
   cut the wheels off, so the ratio is 3:2 and the crop is biased downward. */
.hero-cap{margin:0 0 14px;color:var(--dim);font-size:1rem;line-height:1.45}
.hero-fallback{font-size:2.6rem;line-height:1;margin-bottom:6px}

/* ------------------------------------------------------------------ radar */
/* The city radar (radar.js). Map on the left, live rail on the right from
   700px; stacked on a phone. Everything in here is 1rem or larger. */
.radar{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;margin-top:12px}
@media (min-width:700px){ .radar{grid-template-columns:minmax(0,1fr) 300px;align-items:start} }
.radar-map{position:relative;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#0a0e13}
.radar-map canvas{display:block;width:100%}
.radar-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 6px}
.radar-chip{display:inline-block;font-size:1rem;font-weight:700;color:var(--ink2);background:#0a0e13;
  border:1px solid var(--line);border-radius:20px;padding:3px 10px;white-space:nowrap}
.radar-chip.radar-conv{color:var(--gold);border-color:#5b4526}
.radar-banner{position:absolute;left:10px;right:10px;top:50%;transform:translateY(-50%);text-align:center;
  font-size:1.05rem;font-weight:800;color:#bfe2ff;background:rgba(18,34,46,.95);border:1px solid #2c4f66;
  border-radius:12px;padding:12px;pointer-events:none}
.radar-rail{display:flex;flex-direction:column;gap:8px;min-width:0}
.radar-alerts{display:flex;flex-direction:column;gap:8px}
.radar-alerts:empty{display:none}
.radar-cars{display:flex;flex-direction:column;gap:6px}
.rc{display:flex;gap:10px;align-items:flex-start;padding:8px 10px;border:1px solid var(--line);
  border-radius:11px;background:var(--panel2)}
.rc.rc-loud{border-color:#8a3a3a;background:#2c1717}
.rc-g{flex:0 0 auto;width:30px;height:30px;margin-top:3px}
.rc-g svg{display:block;width:30px;height:30px}
.rc-main{min-width:0;flex:1;line-height:1.4}
.rc-name{font-weight:800}
.rc-state{font-size:1rem;color:var(--ink2)}
.rc-loud .rc-state{color:#ffbdbd;font-weight:700}
.rc-sub{font-size:1rem;color:var(--dim);font-variant-numeric:tabular-nums;display:flex;gap:4px 10px;
  flex-wrap:wrap;align-items:center;margin-top:2px}
.rc-sub .warn{color:var(--warn)} .rc-sub .bad{color:var(--bad);font-weight:700}
.rc-soc{display:inline-block;width:46px;height:10px;border-radius:5px;background:#0a0e13;
  border:1px solid var(--line);overflow:hidden;vertical-align:middle}
.rc-soc i{display:block;height:100%;background:var(--good)}
.rc-soc.warn i{background:var(--warn)} .rc-soc.bad i{background:var(--bad)}
.rfeed{border:1px solid var(--line);border-radius:11px;background:#0a0e13;padding:4px 10px;font-size:1rem}
.rf{display:flex;gap:9px;padding:6px 0;border-bottom:1px solid #151b22;color:var(--ink2);line-height:1.4}
.rf:last-child{border-bottom:none}
.rf .t{color:var(--dim);flex:0 0 auto;font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-variant-numeric:tabular-nums}
.rf b{color:var(--ink)}
.rf.good{color:#b6f0cd} .rf.bad{color:#ffbdbd;font-weight:700} .rf.warn{color:#ffd79a}
.rf.info{color:#bfe2ff} .rf.dim{color:var(--dim)}
.radar-legend{grid-column:1 / -1;display:flex;flex-wrap:wrap;gap:6px 16px;font-size:1rem;color:var(--ink2);
  padding-top:2px}
.radar-legend span{display:inline-flex;align-items:center;gap:6px}
.radar-legend svg{width:26px;height:26px;flex:0 0 auto}
.radar-note{grid-column:1 / -1;font-size:1rem;color:var(--dim);margin:0;line-height:1.45}
.ticker.compact{min-height:0}

/* --------------------------------------------------------------- site nav */
/* /nav.js is the shared momatio menu. It ships its own light-first palette
   (dark only under prefers-color-scheme) and 15px type. This page is dark-only
   and holds a 17px floor, so both are overridden here. nav.mo-nav outranks the
   .mo-nav rule the script injects, whatever order the two stylesheets land in.
   Colours measured on --bg #0d1117: #b4aca0 9.5:1, #ece7df 14.6:1, #6ec79a 9.3:1. */
nav.mo-nav{--mo-ink:#ece7df;--mo-soft:#b4aca0;--mo-accent:#6ec79a;--mo-line:#2c3743;
  --mo-card:#161c24;--mo-hover:#1e2f26;background:var(--bg);font-size:1rem;line-height:1.4;
  padding:10px 14px;gap:6px 18px}
/* Its width is the site default (1080px), NOT this page's 820px column: nine
   items at 17px need about 880px, and capped at 820 the menu wrapped "More"
   onto a row of its own. Wider than the column, it reads as site chrome. */
nav.mo-nav .mo-nav__brand{font-size:1.15rem}
nav.mo-nav .mo-nav__menu i{font-size:1rem}

/* ---------------------------------------------------------------- settings */
.gear{min-height:44px;min-width:44px;padding:6px 10px;font-size:1.25rem;line-height:1;
  text-align:center;flex:0 0 auto}
.seg.seg-col{flex-direction:column}
.seg.seg-col button{text-align:left;min-width:0;flex:1 1 auto;padding:11px 13px}
.inp{font:inherit;font-size:1.1rem;color:var(--ink);background:#0a0e13;border:1px solid var(--line);
  border-radius:11px;padding:11px 13px;width:100%;min-height:var(--tap)}
.inp:focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.inp::placeholder{color:var(--dim);opacity:1}
#ini{text-transform:uppercase;letter-spacing:.2em;font-weight:800;max-width:9em}

/* -------------------------------------------------------------- review day */
/* One line per thing a car did. Colour says what kind of thing; the badge
   says who decided. Everything is 1rem or larger. */
.je{display:flex;gap:10px;padding:7px 0;border-bottom:1px solid #1b2229;line-height:1.45;color:var(--ink2)}
.je:last-child{border-bottom:none}
.jt{flex:0 0 auto;color:var(--dim);min-width:3.3em}
.jx{min-width:0}
.je-cancel .jx{color:#ffbdbd}
.je-charge .jx,.je-update .jx{color:#bfe2ff}
.je-emergency .jx,.je-low .jx{color:#ffd79a}
.je-wipe .jx,.je-clean .jx{color:var(--purple)}
.je-deadhead .jx{color:var(--dim)}
.je-decision{background:#12222e;border:1px solid #2c4f66;border-radius:10px;padding:9px 10px;margin:6px 0}
.je-decision .jx{color:var(--ink)}
.badge{display:inline-block;font-size:1rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  padding:1px 7px;border-radius:6px;background:var(--gold);color:#12161c;white-space:nowrap;margin-right:4px}
.badge-m{background:var(--purple)}
.badge-y{background:#2c3743;color:var(--ink)}

/* ----------------------------------------------------------------- realism */
.rr{display:grid;grid-template-columns:1fr;gap:6px;padding:10px 0;border-bottom:1px solid var(--line)}
@media (min-width:600px){ .rr{grid-template-columns:1.1fr 1fr 1.6fr;gap:12px} }
.rr-w{font-weight:800}
.rr-o b{display:block;font-variant-numeric:tabular-nums}
.rr-o .tiny,.rr-r .tiny{display:block}
.rr-r a,.rr-o a{color:var(--blue)}

/* ------------------------------------------------------------------- board */
.board th{text-align:left;font-size:1rem;color:var(--dim);font-weight:700;padding:6px 8px 6px 0;
  border-bottom:1px solid var(--line);text-transform:uppercase;letter-spacing:.06em}
.board td{white-space:nowrap;padding-right:8px}
.board td:last-child,.board th:last-child{padding-right:0}

/* ============================================ THE ASSUMPTION AFFORDANCE ====
   Every number the model runs on can say where it came from. The affordance
   has to be visible without shouting, and it has to be tappable by someone
   who is not twenty: the "?" is a full 1rem (17px floor, like everything
   else on this page) and the button carries padding beyond the text, so the
   hit area is about 30px tall inside a line of prose. The same records are
   also reachable from the Numbers screen, where each row is a full 46px
   button — nobody has to hit a small target to get at anything. */
.anum{display:inline;font:inherit;color:inherit;background:none;border:0;
  border-bottom:2px dotted var(--gold);border-radius:0;
  padding:4px 1px;margin:-4px 0;min-height:0;cursor:pointer;text-align:inherit;
  -webkit-tap-highlight-color:transparent}
.anum:hover:not(:disabled){color:var(--gold);background:none;border-color:#ffd066}
.anum:focus-visible{outline:3px solid var(--blue);outline-offset:2px;border-radius:4px}
.anum .q{display:inline-block;font-size:1rem;font-weight:800;line-height:1.15;
  color:var(--gold);background:#2d2416;border:1px solid #5b4526;border-radius:50%;
  width:1.3em;height:1.3em;text-align:center;margin-left:4px;vertical-align:baseline}
/* a number the player has replaced with their own */
.anum-mine{border-bottom-color:var(--blue)}
.anum-mine .q{color:var(--blue);background:#12222e;border-color:#2c4f66}

/* the card itself, in the same modal frame as a decision */
.acard .gear{font-size:1.1rem}
.acard-val{font-size:2rem;font-weight:800;color:var(--gold);line-height:1.15;
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;margin:6px 0 2px;
  overflow-wrap:anywhere}
.acard-unit{font-size:1rem;font-weight:650;color:var(--ink2);margin-left:8px;
  letter-spacing:0;white-space:nowrap}
.acard-math{color:var(--ink2)}
.acard-edit{display:flex;gap:8px;align-items:center;margin-top:4px}
.acard-edit .inp{flex:1 1 auto;min-width:0}
.acard-in-unit{flex:0 0 auto;font-size:1rem;font-weight:700;color:var(--ink2);
  max-width:9em;line-height:1.3}
.tag.derived{background:#12222e;color:#9fd6ff;border:1px solid #2c4f66}

/* ------------------------------------------------------- numbers screen */
.numtabs{flex-wrap:wrap}
.numtabs button{flex:1 1 auto;min-width:calc(50% - 3px)}
@media (min-width:560px){ .numtabs button{min-width:0} }
.numlist{display:flex;flex-direction:column;gap:6px;margin-top:4px}
.numrow{display:flex;justify-content:space-between;align-items:center;gap:10px;
  width:100%;padding:10px 12px;font-weight:650;flex-wrap:wrap}
.numrow-l{flex:1 1 12em;min-width:0}
/* The right-hand side used to be one nowrap run of tag + value + unit, which
   on a 360px phone forced the whole PAGE to scroll sideways as soon as a
   record had a long unit ("of long fares") next to a long derived value. It
   wraps now; only the number itself is kept on one line. */
.numrow-r{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px;
  flex-wrap:wrap;justify-content:flex-end;
  font-variant-numeric:tabular-nums;white-space:normal}
.numrow-r b{color:var(--gold);white-space:nowrap}
.numrow-u{font-weight:600;color:var(--ink2);white-space:normal;max-width:8em;line-height:1.3;
  text-align:right}

/* ------------------------------------------------------- the city picker
   Two geographies, chosen before the season starts. Every size here is in
   rem against the 17px root (18px under 520px), so nothing on this block can
   fall under the floor at any width. The cards stack on a phone and sit side
   by side from 560px, and the text wraps rather than shrinking. */
.citypick{display:grid;grid-template-columns:1fr;gap:10px;margin-top:6px}
/* A grid, not a row of flex children, because there are no longer two cards:
   there are two built in and however many cities somebody has researched. A
   six-across row squeezed each one to a 90px column and cut "San Buenaventura"
   in half. auto-fit with a 240px floor wraps instead of shrinking, which is
   what keeps the type at its size and the names whole. */
@media (min-width:560px){ .citypick{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))} }
.citycard{min-width:0;display:flex;flex-direction:column;gap:5px;
  align-items:flex-start;text-align:left;padding:14px 15px;min-height:56px;
  border:1px solid var(--line);border-radius:12px;background:var(--panel2);
  font-weight:650;white-space:normal;overflow-wrap:anywhere}
.citycard[aria-pressed="true"]{border-color:var(--gold);background:#1d1a10;
  box-shadow:inset 0 0 0 1px var(--gold)}
.cityname{display:block;font-size:1.12rem;font-weight:800;line-height:1.3;color:var(--ink)}
.citygeo{display:block;font-size:1rem;font-weight:700;color:var(--gold);line-height:1.4}
.cityblurb{display:block;font-size:1rem;font-weight:500;color:var(--ink2);line-height:1.45}

.warn-ink{color:var(--warn,#f2c14e)}

/* ------------------------------------------------------ suggest a town
   Reuses .inp, so the note box and the state list inherit the same
   1.1rem (18.7px desktop / 19.8px phone) as every other field on the page.
   Nothing here declares a px font size, which is what keeps the whole block
   above the 17px floor at every width. */
.sg-note{min-height:5.2em;line-height:1.5;resize:vertical;padding-top:12px;
  font-family:inherit}
/* The state list. A native select renders its own arrow; the only job here is
   to stop iOS shrinking the text and to leave room for that arrow. */
select.inp{-webkit-appearance:none;appearance:none;padding-right:2.6em;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink2) 50%),
                   linear-gradient(135deg,var(--ink2) 50%,transparent 50%);
  background-position:calc(100% - 1.15em) 1.35em,calc(100% - .8em) 1.35em;
  background-size:.36em .36em,.36em .36em;background-repeat:no-repeat}
select.inp option{background:var(--panel);color:var(--ink)}
/* The honeypot. Taken out of the flow entirely so it can never widen the page
   or be tabbed into, but still a real, fillable field to anything reading the
   markup. clip-path rather than display:none on purpose — some form-fillers
   skip what is display:none, which is the opposite of what we want. */
.sg-hp{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap;left:-9999px;top:auto}
/* Even the decoy inherits the page type. A person never sees it, but the 17px
   floor is audited by walking every element in the DOM, and a browser-default
   13.33px input is a failure whether or not anyone can read it. */
.sg-hp,.sg-hp label,.sg-hp input{font:inherit;font-size:1rem}

/* ------------------------------------------------------ section strip */
/* The three Cybercab pages, named on each of the two reading pages (the
   ladder and the methodology) inside their sticky .topbar, so the other two
   are one tap away wherever the reader has scrolled to. The game has its own
   sticky bar with the season in it, so it links to the ladder from the
   intro and from the end of a season instead. Same 17px floor and 44px
   targets as everything else here. */
.fsec{display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;max-width:820px;margin:0 auto;
  padding:8px 14px}
.fsec-k{font-weight:800;font-size:1rem;color:var(--ink);display:inline-flex;gap:7px;
  align-items:center;margin-right:6px}
.fsec-k .dot{width:9px;height:9px;border-radius:50%;background:var(--gold);flex:0 0 auto}
.fsec a{color:var(--ink2);text-decoration:none;font-weight:700;font-size:1rem;padding:8px 12px;
  border:1px solid var(--line);border-radius:10px;min-height:44px;display:inline-flex;
  align-items:center;white-space:nowrap}
.fsec a:hover{color:var(--ink);border-color:#4a5a6b;background:#242e39}
.fsec a[aria-current="page"]{color:#12161c;background:var(--gold);border-color:var(--gold)}

/* Links dressed as the button tiers, for the places a destination is a page
   rather than a screen: the ladder from the end of a season, the game from
   the ladder. Declared after .card a so the button colour wins inside a card. */
a.btn-major,a.btn-ghost{display:flex;align-items:center;justify-content:center;
  text-decoration:none;padding:12px 14px;min-height:var(--tap);border-radius:11px;
  font-weight:650;color:var(--ink);border:1px solid var(--line);background:transparent;
  text-align:center;line-height:1.35}
a.btn-major{background:#232d38;border:2px solid #5d7288;font-weight:800;font-size:1.05rem;
  min-height:54px}
.card a.btn-major,.card a.btn-ghost{color:var(--ink)}
a.btn-major:hover{background:#2d3a47;border-color:#7d94aa;color:var(--ink)}
a.btn-ghost:hover{border-color:#4a5a6b;background:#242e39;color:var(--ink)}
a.btn-primary{display:flex;align-items:center;justify-content:center;text-decoration:none;
  background:var(--gold);color:#12161c;border:1px solid var(--gold);border-radius:11px;
  padding:12px 14px;font-weight:800;font-size:1.08rem;min-height:56px;line-height:1.3}
a.btn-primary:hover{background:#ffd066;border-color:#ffd066;color:#12161c}
