/* Gameweek United — restrained editorial intelligence-room styling. */
/* -------------------------------------------------------------- breakpoints
   Two, and only two.

     900px  the sidebar has nowhere to go, so the layout stacks and every
            two-column grid becomes one. Also where controls grow to a size
            a thumb can hit, because everything this narrow is touched.
     640px  a phone. Dense tables stop being tables, and the navigation
            stops spending a third of the screen on itself.

   There were four: 900, 860, 700 and 640. The extra two were not decisions,
   they were the width somebody's window happened to be when a particular
   grid looked wrong -- 860 moved one grid to one column forty pixels before
   its neighbours did, which is a difference no reader has ever seen and a
   third place to remember to edit. Both were folded into the two above with
   no visible change: a layout that stacks earlier still fits. */
:root{
  --bg:#0b0d10; --panel:#12151a; --panel2:#161a20; --line:#222831;
  --line2:#2c3440; --text:#e8ebf0; --dim:#8d97a6; --dim2:#606b7b;
  --pos:#4ade80; --posdim:#1d3d2b; --neg:#f87171; --negdim:#3d1f22;
  --warn:#fbbf24; --warndim:#3a2f12; --accent:#7dd3fc; --accentdim:#12303d;
  --posline:#255c3c; --negline:#63292e; --warnline:#5a4a17;
  --accentline:#1d4a5e; --line3:#3b4553; --prose:#cdd4de; --onfill:#0b0d10;
  --shadow:#000;
  /* Display preferences, overwritten from the Boot Room. */
  --fs:1; --maxw:1500px;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Inter","Segoe UI",Roboto,sans-serif;
  --r:6px;

  /* ------------------------------------------------------------ type scale
     Eleven steps. There were twenty-six sizes across 360 declarations, and
     twelve of them lived between 9.5px and 15px -- 9.5, 10, 10.5, 11, 11.5,
     12, 12.5, 12.8, 13, 13.5, 14, 14.5, 15. Steps that close are not
     decisions anyone made or any reader can see; they are what happens when
     each new component picks a number that looked about right, and the cost
     is that nothing can be changed as a set.

     Sizes only ever moved DOWN where a value was between two steps. Text
     that shrinks by half a pixel cannot overflow anything; text that grows
     can, and finding out which cell it broke is not worth the pixel.

     The ratio is about 1.13 through the middle, opening up at the top where
     the jumps are between headings rather than between labels. Every size in
     this stylesheet comes from this list -- a new number here is a decision
     to have a twelfth step, which is a thing worth arguing about rather than
     doing by accident.

     Still px, and deliberately: the reader's text-size setting scales the
     whole interface with `zoom` (see the note on body), so a rem cascade
     would move some text and leave the rest. */
  --t-micro:9px;
  --t-xxs:10px;
  --t-xs:11px;
  --t-s:12.5px;
  --t-m:14px;
  --t-l:16px;
  --t-xl:19px;
  --t-2xl:22px;
  --t-3xl:26px;
  --t-4xl:30px;
  --t-5xl:38px;

  /* ---------------------------------------------------------------- scales
     Five things in this app are RAMPS, not single colours: how hard a
     fixture is, how good a bonus finish was, how hot a cell is. They were
     written as component rules with hex in them, once for each theme -- so
     the base palette could be changed and the ramps would stay exactly where
     they were, and the two themes could drift apart with nothing to notice.

     Naming them makes them part of the palette. The scale is defined once
     per theme, here, and every component reads it. */
  --d1:#255c3c; --d2:#2f4a30; --d3:#2c3440; --d4:#5c3a22; --d5:#63292e;
  --tk-easy-bg:#1e5b34;  --tk-easy-fg:#d8f5e3;
  --tk-ok-bg:#2c4a34;    --tk-ok-fg:#cfe6d8;
  --tk-even-bg:#333a44;  --tk-even-fg:var(--text);
  --tk-hard-bg:#5a2f33;  --tk-hard-fg:#f6d9dc;
  --tk-brutal-bg:#7a2027;--tk-brutal-fg:#ffe2e5;
  --medal-1-bg:#a8703c; --medal-1-fg:#1a0f05;
  --medal-2-bg:#9aa4b2; --medal-2-fg:#12151a;
  --medal-3-bg:#c9a227; --medal-3-fg:#1a1500;
  --heat-fg:#9fe8bd;    --heat-bg:rgba(74,222,128,.07);
  /* Points bands: a return, a good one, a haul. A ramp, so it
     lives in the palette like the other four. */
  --pts-mid-bg:rgba(74,222,128,.16);
  --pts-hi-bg:#9fe8bd;  --pts-hi-fg:#0b2415;
  --wk-best:#07240f;
  --alert-r:#f0b4b4; --alert-a:#e8d19a; --planbad-fg:#f3c4c8;
  --repl-hover:#123b4d; --trophy-line:#4a4020;

}
/* ---------------------------------------------------------------- light
   A second palette, not an inversion. Inverting a dark scheme gives you grey
   text on white and colours that shout; these are chosen for paper -- darker,
   less saturated accents that hold their meaning at small sizes, and fills
   pale enough that a pill still reads as a pill rather than a highlighter.
   The rules below the tokens are the handful of places that hard-code a
   colour because it has to sit on a solid fill. */
:root[data-theme="light"]{

  --d1:#8fc7a4; --d2:#b7d6bd; --d3:#d3d8e0; --d4:#e0c0a4; --d5:#e8a9ab;
  --tk-easy-bg:#cdeddb;  --tk-easy-fg:#0d4a2b;
  --tk-ok-bg:#e0eee4;    --tk-ok-fg:#2b4a34;
  --tk-even-bg:#e8ebf0;  --tk-even-fg:#3c434d;
  --tk-hard-bg:#f7dcdd;  --tk-hard-fg:#75282c;
  --tk-brutal-bg:#f3c3c5;--tk-brutal-fg:#7a2027;
  --medal-1-bg:#c08a55; --medal-1-fg:#33200c;
  --medal-2-bg:#c3cad4; --medal-2-fg:#2b323c;
  --medal-3-bg:#d8b53a; --medal-3-fg:#3a2f00;
  --heat-fg:#0d5c34;    --heat-bg:rgba(19,122,69,.09);
  --pts-mid-bg:rgba(19,122,69,.14);
  --pts-hi-bg:#0d5c34;  --pts-hi-fg:#f2fbf5;
  --wk-best:#08351a;
  --alert-r:#a32e27; --alert-a:#7d5405; --planbad-fg:#7a2620;
  --repl-hover:#d5e8f4; --trophy-line:#d9c98a;

  --bg:#f6f7f9; --panel:#ffffff; --panel2:#f1f3f6; --line:#e3e7ed;
  --line2:#d2d8e1; --line3:#b6bfcc; --text:#12161c; --dim:#59636f;
  --dim2:#828c99; --prose:#2b323c;
  --pos:#137a45; --posdim:#e4f4ea; --posline:#a6d8bb;
  --neg:#c0362e; --negdim:#fceceb; --negline:#efb2ad;
  --warn:#8a5d05; --warndim:#fdf2da; --warnline:#e3ca8d;
  --accent:#0a6ba3; --accentdim:#e3f0f8; --accentline:#a5cfe8;
  --onfill:#ffffff; --shadow:#8d97a6;
}
/* ---------------------------------------------- light, without being asked
   The palette above is reached by the toggle. This one is reached by the
   reader's operating system, which is what most people actually set and
   never think about again. Guarded by :not([data-theme="dark"]) so an
   explicit choice still wins over the system in BOTH directions -- picking
   dark on a machine set to light has to stick, and without the guard the
   media query would quietly undo it.

   The declarations are a copy of the block above, and a copy is a thing
   that drifts. tests_acceptance.py compares the two token-for-token, so a
   colour added to one and not the other fails a check rather than showing
   up as one wrong pill months later. */
@media(prefers-color-scheme:light){
  :root:not([data-theme="dark"]):not([data-theme="light"]){

  --d1:#8fc7a4; --d2:#b7d6bd; --d3:#d3d8e0; --d4:#e0c0a4; --d5:#e8a9ab;
  --tk-easy-bg:#cdeddb;  --tk-easy-fg:#0d4a2b;
  --tk-ok-bg:#e0eee4;    --tk-ok-fg:#2b4a34;
  --tk-even-bg:#e8ebf0;  --tk-even-fg:#3c434d;
  --tk-hard-bg:#f7dcdd;  --tk-hard-fg:#75282c;
  --tk-brutal-bg:#f3c3c5;--tk-brutal-fg:#7a2027;
  --medal-1-bg:#c08a55; --medal-1-fg:#33200c;
  --medal-2-bg:#c3cad4; --medal-2-fg:#2b323c;
  --medal-3-bg:#d8b53a; --medal-3-fg:#3a2f00;
  --heat-fg:#0d5c34;    --heat-bg:rgba(19,122,69,.09);
  --pts-mid-bg:rgba(19,122,69,.14);
  --pts-hi-bg:#0d5c34;  --pts-hi-fg:#f2fbf5;
  --wk-best:#08351a;
  --alert-r:#a32e27; --alert-a:#7d5405; --planbad-fg:#7a2620;
  --repl-hover:#d5e8f4; --trophy-line:#d9c98a;

  --bg:#f6f7f9; --panel:#ffffff; --panel2:#f1f3f6; --line:#e3e7ed;
  --line2:#d2d8e1; --line3:#b6bfcc; --text:#12161c; --dim:#59636f;
  --dim2:#828c99; --prose:#2b323c;
  --pos:#137a45; --posdim:#e4f4ea; --posline:#a6d8bb;
  --neg:#c0362e; --negdim:#fceceb; --negline:#efb2ad;
  --warn:#8a5d05; --warndim:#fdf2da; --warnline:#e3ca8d;
  --accent:#0a6ba3; --accentdim:#e3f0f8; --accentline:#a5cfe8;
  --onfill:#ffffff; --shadow:#8d97a6;
  }
}














:root[data-theme="light"] .planbad{border-color:var(--negline);
  background:#fceceb;color:#8c2b25}




:root[data-theme="light"] .pending{border-color:var(--warnline)}
:root[data-theme="light"] .dl.soon{border-color:var(--warnline)}

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{background:var(--bg);color:var(--text);font-family:var(--sans);
  font-size:var(--t-m);line-height:1.5;-webkit-font-smoothing:antialiased}
/* Text scale. `zoom` is used deliberately over a font-size cascade: this
   stylesheet sizes in px throughout, so scaling the root font would move some
   text and leave the rest -- which reads as a bug, not a setting. Zoom scales
   the layout with the type and keeps every alignment intact. */
:root[data-fs] .app{zoom:var(--fs)}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
input,select{font:inherit;color:inherit}

/* ---------------------------------------------------------------- layout */
.app{display:flex;min-height:100vh}
.side{width:212px;flex:none;border-right:1px solid var(--line);
  background:var(--panel);display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh}
.brand{padding:18px 18px 14px;border-bottom:1px solid var(--line)}
/* The phone nav's control. It only ever had a display rule INSIDE the 640px
   block, and a <button> defaults to inline-block -- so the hamburger and the
   section label it carries were visible at every width, sitting above the
   brand on a desktop sidebar that already shows the whole menu. Hidden by
   default; the 640px block turns it on. */
.navtoggle{display:none}
.brand h1{font-size:var(--t-s);letter-spacing:.16em;font-weight:600;text-transform:uppercase}
.brand .sub{font-size:var(--t-xs);color:var(--dim2);letter-spacing:.06em;margin-top:3px}
.nav{padding:10px 8px;flex:1;overflow:auto}
.nav button{display:flex;justify-content:space-between;align-items:center;
  width:100%;text-align:left;padding:8px 10px;border-radius:var(--r);
  color:var(--dim);font-size:var(--t-s);margin-bottom:1px}
.nav button:hover{background:var(--panel2);color:var(--text)}
.nav button.on{background:var(--accentdim);color:var(--accent)}
.nav .tag{font-family:var(--mono);font-size:var(--t-xxs);color:var(--dim2)}
.sidefoot{padding:12px 14px;border-top:1px solid var(--line);font-size:var(--t-xs);
  color:var(--dim2)}
.main{flex:1;min-width:0;display:flex;flex-direction:column}

.topbar{display:flex;align-items:center;gap:16px;padding:12px 22px;
  border-bottom:1px solid var(--line);background:var(--panel);
  position:sticky;top:0;z-index:20;flex-wrap:wrap}
.gw{font-family:var(--mono);font-size:var(--t-s);letter-spacing:.1em;color:var(--dim)}
.gw b{color:var(--text)}
.dl{font-family:var(--mono);font-size:var(--t-s);padding:3px 8px;border-radius:4px;
  background:var(--panel2);border:1px solid var(--line2);color:var(--dim)}
.dl.soon{background:var(--warndim);border-color:var(--warnline);color:var(--warn)}
.spacer{flex:1}
.btn{padding:6px 12px;border:1px solid var(--line2);border-radius:var(--r);
  font-size:var(--t-s);color:var(--dim);background:var(--panel2)}
.btn:hover{color:var(--text);border-color:var(--line3)}
.btn.pri{background:var(--accentdim);border-color:var(--accentline);color:var(--accent)}
/* Width and text size are preferences, not constants. A 1500px column is
   right on a laptop and a waste of a 34-inch monitor, and 14px is right for
   most people and small for some. */
.content{padding:22px;max-width:var(--maxw);width:100%}
.app{font-size:calc(1rem * var(--fs))}

/* --------------------------------------------------------------- generic */
h2.sec{font-size:var(--t-xs);letter-spacing:.16em;text-transform:uppercase;
  color:var(--dim2);font-weight:600;margin:38px 0 12px;
  display:flex;align-items:center;gap:10px}
h2.sec:first-child{margin-top:0}
/* A section that ends on its own footnote used to run straight into the next
   block, so the note read as a caption for the wrong thing. */
#view > p.dim2 + h2.sec,
#view > .tablewrap + h2.sec{margin-top:44px}
#view > p.dim2{margin-bottom:4px}
#view > .mwrap{margin-top:4px}

/* Section headings pin under the topbar, so scrolling a long list always shows
   which section you are in and hands over to the next one at the same place.
   Only top-level headings in the main view: the drawer scrolls itself and its
   own headings must not fight with these.

   The offset is a variable because the topbar WRAPS on a narrow window -- a
   hardcoded height leaves the heading floating over it or hidden behind it, so
   the real height is measured and written here. */
#view > h2.sec{position:sticky;top:var(--topbar-h,52px);z-index:12;
  background:var(--bg);margin:22px 0 0;padding:9px 0 9px;
  box-shadow:0 6px 10px -10px var(--bg)}
#view > h2.sec:first-child{margin-top:-9px}
/* Too little room to be worth pinning anything. */
:root.nostick #view > h2.sec{position:static}
h2.sec .line{flex:1;height:1px;background:var(--line)}
h2.sec .act{font-size:var(--t-xs);letter-spacing:.04em;text-transform:none;
  color:var(--accent);cursor:pointer}
.panel{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:16px}
.grid{display:grid;gap:14px}
.muted{color:var(--dim)}
.dim2{color:var(--dim2)}
.mono{font-family:var(--mono)}
.pos{color:var(--pos)} .neg{color:var(--neg)} .warn{color:var(--warn)}
.nowrap{white-space:nowrap}
.center{text-align:center}
.empty{padding:36px;text-align:center;color:var(--dim2);font-size:var(--t-s)}

.pill{display:inline-block;font-family:var(--mono);font-size:var(--t-xxs);
  letter-spacing:.06em;padding:2px 6px;border-radius:3px;
  background:var(--panel2);border:1px solid var(--line2);color:var(--dim)}
.pill.g{background:var(--posdim);border-color:var(--posline);color:var(--pos)}
.pill.r{background:var(--negdim);border-color:var(--negline);color:var(--neg)}
.pill.a{background:var(--warndim);border-color:var(--warnline);color:var(--warn)}
.pill.b{background:var(--accentdim);border-color:var(--accentline);color:var(--accent)}

/* ------------------------------------------------------------ top action */
.hero{border:1px solid var(--line2);border-radius:var(--r);overflow:hidden;
  background:linear-gradient(180deg,var(--panel2),var(--panel))}
.hero .bar{padding:7px 16px;font-family:var(--mono);font-size:var(--t-xs);
  letter-spacing:.16em;text-transform:uppercase;border-bottom:1px solid var(--line)}
.hero.claim .bar{background:var(--posdim);color:var(--pos)}
.hero.hold .bar{background:var(--panel2);color:var(--dim)}
.hero.setup .bar{background:var(--accentdim);color:var(--accent)}
.hero .body{padding:18px}
.movetitle{font-size:var(--t-3xl);font-weight:600;letter-spacing:-.01em;
  display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;line-height:1.25}
.movetitle .arrow{color:var(--dim2);font-size:var(--t-l)}
.movetitle .pl{cursor:pointer;border-bottom:1px dashed var(--line2)}
.movetitle .pl:hover{color:var(--accent);border-color:var(--accent)}
.deltas{display:flex;gap:26px;flex-wrap:wrap;margin:16px 0 4px;
  padding:12px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.delta .v{font-family:var(--mono);font-size:var(--t-xl);font-weight:600}
.delta .k{font-size:var(--t-xxs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim2);margin-top:2px}
.why{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:16px}
.why ul{list-style:none}
.why li{font-size:var(--t-s);padding:4px 0 4px 16px;position:relative;color:var(--dim)}
.why li:before{position:absolute;left:0;font-family:var(--mono)}
.why .p li:before{content:"+";color:var(--pos)}
.why .n li:before{content:"\2212";color:var(--neg)}
.why h4{font-size:var(--t-xxs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:6px}

/* ------------------------------------------------------------------- xi */
.pitch{display:grid;gap:10px}
.row{display:flex;justify-content:center;gap:8px;flex-wrap:wrap}
.card{background:var(--panel2);border:1px solid var(--line);border-radius:var(--r);
  padding:8px 10px;min-width:112px;cursor:pointer;transition:border-color .12s}
.card:hover{border-color:var(--accent)}
.card .n{font-size:var(--t-s);font-weight:500;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;max-width:130px}
.card .m{font-family:var(--mono);font-size:var(--t-xs);color:var(--dim2);
  display:flex;justify-content:space-between;gap:8px;margin-top:3px}
.card .m b{color:var(--text);font-weight:600}
.card.flag{border-color:var(--negline)}
.bench{display:flex;gap:8px;flex-wrap:wrap}
.bench .card{min-width:104px;opacity:.86}
.bench .ord{font-family:var(--mono);font-size:var(--t-xxs);color:var(--dim2)}

/* ---------------------------------------------------------------- table */
.tablewrap{border:1px solid var(--line);border-radius:var(--r);overflow:auto;
  background:var(--panel);max-height:calc(100vh - 260px)}
table{width:100%;border-collapse:collapse;font-size:var(--t-s)}
th{position:sticky;top:0;background:var(--panel2);text-align:left;
  padding:8px 10px;font-size:var(--t-xxs);letter-spacing:.09em;text-transform:uppercase;
  color:var(--dim2);font-weight:600;border-bottom:1px solid var(--line);
  cursor:pointer;white-space:nowrap;z-index:2}
th:hover{color:var(--text)}
th.on{color:var(--accent)}
td{padding:7px 10px;border-bottom:1px solid var(--line);white-space:nowrap}
tbody tr{cursor:pointer}
tbody tr:hover{background:var(--panel2)}

/* The first column names the row. Scrolling it out of view leaves a wall of
   numbers belonging to nobody, so it stays pinned to the left edge. */
.tablewrap th:first-child,.tablewrap td:first-child{position:sticky;left:0;
  z-index:3;background:var(--panel)}
.tablewrap th:first-child{z-index:4}
.tablewrap tbody tr:hover td:first-child{background:var(--panel2)}
.tablewrap th:first-child::after,.tablewrap td:first-child::after{
  content:"";position:absolute;top:0;right:0;bottom:0;width:1px;
  background:var(--line)}
/* Totals rows carry their own background and must keep it under the pin. */
.tablewrap tr.totals td:first-child,
.tablewrap tr.per90 td:first-child{background:var(--panel2)}
td.num{font-family:var(--mono);text-align:right}
/* Only td.num was right-aligned, so a numeric HEADER sat left while its
   numbers sat right — the column read as two ragged edges. */
th.num{text-align:right}
.filters{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:12px}
.filters input,.filters select{background:var(--panel2);border:1px solid var(--line2);
  border-radius:var(--r);padding:6px 10px;font-size:var(--t-s);outline:none}
.filters input:focus,.filters select:focus{border-color:var(--accent)}
.filters input[type=search]{min-width:210px}
.seg{display:flex;border:1px solid var(--line2);border-radius:var(--r);overflow:hidden}
.seg button{padding:6px 11px;font-size:var(--t-s);color:var(--dim);
  border-right:1px solid var(--line2)}
.seg button:last-child{border-right:none}
.seg button.on{background:var(--accentdim);color:var(--accent)}
.count{font-family:var(--mono);font-size:var(--t-xs);color:var(--dim2)}

/* --------------------------------------------------------------- drawer */
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:40;
  opacity:0;pointer-events:none;transition:opacity .16s}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(1180px,96vw);
  background:var(--bg);border-left:1px solid var(--line2);z-index:50;
  transform:translateX(100%);transition:transform .2s cubic-bezier(.4,0,.2,1);
  display:flex;flex-direction:column}
.drawer.on{transform:none}
.dhead{padding:16px 20px;border-bottom:1px solid var(--line);
  background:var(--panel);position:sticky;top:0}
.dhead .x{position:absolute;top:14px;right:16px;color:var(--dim2);font-size:var(--t-xl);
  line-height:1}
.dhead .x:hover{color:var(--text)}
.dhead h3{font-size:var(--t-2xl);font-weight:600;letter-spacing:-.01em}
.dhead .meta{color:var(--dim);font-size:var(--t-s);margin-top:4px;
  display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.dbody{padding:18px 20px 60px;overflow:auto;flex:1}
.dbody .tablewrap{max-height:none}   /* the drawer already scrolls */
.tabs{display:flex;flex-wrap:wrap;gap:2px 0;
  border-bottom:1px solid var(--line);margin:0 -20px 16px;padding:0 20px}
.tabs button{padding:8px 12px;font-size:var(--t-s);color:var(--dim2);
  border-bottom:2px solid transparent;white-space:nowrap}
.tabs button.on{color:var(--accent);border-color:var(--accent)}

.kv{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:10px}
.kv .b{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:9px 11px}
.kv .b .k{font-size:var(--t-xxs);letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim2)}
.kv .b .v{font-family:var(--mono);font-size:var(--t-l);margin-top:3px}
.kv .b .s{font-size:var(--t-xs);color:var(--dim2);margin-top:1px}

.bars{display:grid;gap:5px;margin-top:4px}
.bars .b{display:grid;grid-template-columns:130px 1fr 54px;gap:9px;
  align-items:center;font-size:var(--t-s)}
.bars .t{height:7px;background:var(--panel2);border-radius:3px;overflow:hidden;
  position:relative}
.bars .f{height:100%;background:var(--accent);border-radius:3px}
.bars .f.neg{background:var(--neg)}
.bars .val{font-family:var(--mono);text-align:right;font-size:var(--t-s)}
.bars .lbl{color:var(--dim)}

.fixrow{display:flex;gap:5px;flex-wrap:wrap}
.fix{border:1px solid var(--line);border-radius:4px;padding:5px 7px;
  background:var(--panel);min-width:56px;text-align:center}
.fix .o{font-family:var(--mono);font-size:var(--t-xs)}
.fix .e{font-size:var(--t-micro);color:var(--dim2);letter-spacing:.05em}
.fix .p{font-family:var(--mono);font-size:var(--t-xs);margin-top:2px}
.fix.d1{border-color:var(--posline)} .fix.d2{border-color:var(--d2)}
.fix.d3{border-color:var(--line2)} .fix.d4{border-color:var(--d4)}
.fix.d5{border-color:var(--negline)}

.story p{font-size:var(--t-s);line-height:1.62;color:var(--prose);margin-bottom:9px}
.plist{list-style:none}
.plist li{font-size:var(--t-s);padding:7px 0 7px 20px;position:relative;
  border-bottom:1px solid var(--line);color:var(--dim)}
.plist li:before{position:absolute;left:0;top:7px;font-family:var(--mono);font-size:var(--t-xs)}
.plist li.positive:before{content:"\25B2";color:var(--pos)}
.plist li.negative:before{content:"\25BC";color:var(--neg)}
.plist li.neutral:before{content:"\25CF";color:var(--dim2)}
.plist li .sm{color:var(--dim2);font-size:var(--t-xs);margin-left:6px;font-family:var(--mono)}

.matchup{display:grid;grid-template-columns:1fr auto 1fr;gap:16px;align-items:start}
.score{font-family:var(--mono);font-size:var(--t-4xl);font-weight:600;text-align:center}
.vs{text-align:center;color:var(--dim2);font-size:var(--t-xs);letter-spacing:.14em;
  padding-top:8px}
.edges{display:grid;gap:6px;margin-top:12px}
.edge{display:grid;grid-template-columns:44px 1fr 150px;gap:9px;align-items:center;
  font-size:var(--t-s)}
.edge .t{height:6px;background:var(--panel2);border-radius:3px;position:relative}
.edge .f{position:absolute;top:0;bottom:0;background:var(--pos);border-radius:3px}
.edge .f.neg{background:var(--neg)}
.edge .lead{font-size:var(--t-xs);text-align:right;font-variant-numeric:tabular-nums;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Which end of the bar means what, said once above the rows. */
.edgehead{display:grid;grid-template-columns:44px 1fr 150px;gap:9px;
  margin-top:12px;font-size:var(--t-xxs);letter-spacing:.09em;text-transform:uppercase;
  color:var(--dim2)}
.edgehead>span:nth-child(2){display:flex;justify-content:space-between}
.edgehead i{font-style:normal}
.edgehead>span:last-child{text-align:right}
/* The centre line the bars diverge from. */
.edge .t::after{content:"";position:absolute;left:50%;top:-2px;bottom:-2px;
  width:1px;background:var(--line2)}

.chg{border-bottom:1px solid var(--line);padding:10px 0;cursor:pointer}
.chg:hover{background:var(--panel2)}
.chg .h{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.chg .n{font-weight:500}
.chg ul{list-style:none;margin-top:4px}
.chg li{font-size:var(--t-s);color:var(--dim);padding-left:12px;position:relative}
.chg li:before{content:"\2192";position:absolute;left:0;color:var(--dim2)}

.matrix{overflow:auto;border:1px solid var(--line);border-radius:var(--r)}
.matrix table{font-size:var(--t-s)}
.matrix td.c{font-family:var(--mono);text-align:center;padding:5px 8px}

.cell0{color:var(--dim2)}
.cell1{color:var(--heat-fg);background:var(--heat-bg)}
.cell2{color:var(--pos);background:rgba(74,222,128,.15)}
.cell3{color:var(--onfill);background:var(--pos);font-weight:600}
.celln{color:var(--neg);background:rgba(248,113,113,.09)}

.setup{max-width:520px;margin:60px auto}
.setup input{width:100%;background:var(--panel2);border:1px solid var(--line2);
  border-radius:var(--r);padding:10px 12px;margin:6px 0 12px;outline:none}
.setup input:focus{border-color:var(--accent)}
.setup .opt{padding:10px 12px;border:1px solid var(--line);border-radius:var(--r);
  margin-bottom:6px;cursor:pointer;background:var(--panel)}
.setup .opt:hover{border-color:var(--accent)}
.load{padding:60px;text-align:center;color:var(--dim)}
.load .s{font-family:var(--mono);font-size:var(--t-s);color:var(--dim2);margin-top:8px}
.spin{width:18px;height:18px;border:2px solid var(--line2);
  border-top-color:var(--accent);border-radius:50%;margin:0 auto;
  animation:sp .7s linear infinite}
@keyframes sp{to{transform:rotate(360deg)}}

.srcs{display:flex;gap:8px;flex-wrap:wrap;font-size:var(--t-xs);color:var(--dim2)}
.srcs span{padding:3px 7px;border:1px solid var(--line);border-radius:3px}

@media(max-width:900px){
  .app{flex-direction:column}
  .side{width:100%;height:auto;position:static;flex-direction:row;
    align-items:center;overflow:auto}
  .brand{border-bottom:none;border-right:1px solid var(--line);flex:none;padding:12px 14px}
  .brand .sub{display:none}
  .nav{display:flex;padding:6px;gap:2px}
  .nav button{width:auto;white-space:nowrap}
  .nav .tag{display:none}
  .sidefoot{display:none}
  .content{padding:14px}
  .why{grid-template-columns:1fr}
  .matchup{grid-template-columns:1fr}
  .vs{padding:8px 0}
  .drawer{width:100%}
  .movetitle{font-size:var(--t-xl)}
  .tablewrap{max-height:none}
}

/* ---------------------------------------------- squad news & availability */
.newsitem{padding:9px 0;border-bottom:1px solid var(--line)}
.newsitem:last-of-type{border-bottom:none}
.newsitem .nh{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;cursor:pointer}
.newsitem .nn{font-weight:500}
.newsitem .nb{font-size:var(--t-s);color:var(--prose);margin-top:3px}
.newsitem .nm{font-size:var(--t-xs);color:var(--dim2);margin-top:3px}
.newsitem.r{border-left:2px solid var(--neg);padding-left:10px}
.newsitem.a{border-left:2px solid var(--warn);padding-left:10px}
.newsitem.g{border-left:2px solid var(--pos);padding-left:10px}
.availrow{padding:7px 0;border-bottom:1px solid var(--line);cursor:pointer}
.availrow:last-child{border-bottom:none}
.availrow:hover{background:var(--panel2)}
.availrow .nn{font-weight:500;font-size:var(--t-s)}
.teamrow{display:flex;justify-content:space-between;align-items:center;gap:10px;
  padding:5px 0;border-bottom:1px solid var(--line);cursor:pointer}
.teamrow:hover{background:var(--panel2)}
.seg button[disabled]{cursor:not-allowed}
.panel.busy{opacity:.5}

/* ------------------------------------------------------------ gw report */
.report h4{font-size:var(--t-xxs);letter-spacing:.15em;text-transform:uppercase;
  color:var(--accent);margin:18px 0 7px;font-weight:600}
.report h4:first-child{margin-top:0}
.report p{font-size:var(--t-s);line-height:1.68;color:var(--prose);margin-bottom:7px;
  max-width:74ch}
textarea:focus{border-color:var(--accent)}
tr.mineRow{background:rgba(125,211,252,.06)}

/* --------------------------------------------------------- league switcher */
.leaguebar{display:flex;gap:2px;align-items:center;border:1px solid var(--line2);
  border-radius:var(--r);overflow:hidden;flex-wrap:wrap}
.leaguebar .lg{padding:5px 11px;font-size:var(--t-s);color:var(--dim);
  border-right:1px solid var(--line2);white-space:nowrap}
.leaguebar .lg:last-child{border-right:none}
.leaguebar .lg:hover{color:var(--text);background:var(--panel2)}
.leaguebar .lg.on{background:var(--accentdim);color:var(--accent)}
.leaguebar .lg.add{color:var(--dim2)}
.leaguebar .lg.add:hover{color:var(--accent)}

/* ---------------------------------------------------------------- watchlist */
.watchcard{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:12px;cursor:pointer}
.watchcard:hover{border-color:var(--line2)}
.watchcard .wh{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;flex-wrap:wrap}
.watchcard .nn{font-weight:500;font-size:var(--t-m)}
.watchcard .wr{font-size:var(--t-s);color:var(--dim);margin-top:6px;line-height:1.5}
.watchcard .wmeta{display:flex;gap:12px;flex-wrap:wrap;margin-top:7px;
  font-family:var(--mono);font-size:var(--t-xs);color:var(--dim2)}
.watchcard .wmove{margin-top:9px;padding-top:8px;border-top:1px solid var(--line);
  font-size:var(--t-s);display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.watchcard .fix{display:inline-flex;flex-direction:column;align-items:center}

/* ------------------------------------------------- report voice controls */
.vin{width:100%;background:var(--panel2);border:1px solid var(--line2);
  border-radius:var(--r);padding:8px 10px;margin:5px 0 10px;color:var(--text);
  font:inherit;outline:none}
.vin:focus{border-color:var(--accent)}
.vin.sm{padding:5px 8px;margin:0;font-size:var(--t-s)}
.report .byline{font-size:var(--t-xs);color:var(--dim2);letter-spacing:.05em;
  border-bottom:1px solid var(--line);padding-bottom:9px;margin-bottom:13px}
.report p.opener{font-size:var(--t-m);color:var(--text)}
.report p.persona{font-style:italic;color:var(--dim)}
.report p.signoff{color:var(--dim2);font-style:italic;margin-top:12px}
.report p.highscore{color:var(--warn)}
/* Group-chat voice: the scoreline block is one line per match, so it has to
   keep its newlines, and the premises read as separated messages. */
.report p.scores{white-space:pre-line;font-variant-numeric:tabular-nums;
  color:var(--dim);border-left:2px solid var(--line2);padding-left:10px;
  margin:10px 0 14px}
.report p.premise{margin-bottom:13px}
/* The brief: the one field that replaced six panels. */
/* Probability cell: the figure, with a bar behind it for scanning. */
.pbar{position:relative;display:inline-block;min-width:52px;text-align:right;
  padding:1px 5px;border-radius:3px;overflow:hidden}
.pbar i{position:absolute;left:0;top:0;bottom:0;background:var(--accent);
  opacity:.16;border-radius:3px}
.pbar b{position:relative;font-weight:500;font-variant-numeric:tabular-nums}

.brief{margin-bottom:14px}
.brief textarea{width:100%;min-height:96px;background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);padding:10px 12px;
  color:var(--text);font:inherit;line-height:1.6;outline:none;resize:vertical}
.brief textarea:focus{border-color:var(--accent)}
.briefread{margin-top:10px;padding-top:9px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:6px;font-size:var(--t-xs)}
.briefread .pill{margin-right:7px}
/* The correspondent's own material, in his own words. Set apart from the
   generated copy so it is obvious which half the app wrote. */
.report p.coldopen,.report p.lastword{white-space:pre-line;color:var(--text)}
.report p.turn{font-weight:600;margin:14px 0 10px}
.report p.standfirst{color:var(--dim);font-style:italic;margin-bottom:14px}
.report p.interview{white-space:pre-line}
/* When a player is named in the body of a story rather than its headline,
   the sentence that names him is shown -- otherwise the card reads as a
   headline about somebody else entirely. */
.exq{margin-top:3px;padding-left:8px;border-left:2px solid var(--line2);
  color:var(--dim);font-style:italic}
/* The Keep decision, offered on the card that raises the question. */
.keepline{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-top:9px;padding-top:9px;border-top:1px solid var(--line)}
.keepline .dim2{font-size:var(--t-xs);line-height:1.5;flex:1;min-width:160px}
/* A joke that rests on outside news carries its source, so the reader can
   check the transfer rather than take the punchline's word for it. */
.report .prov{display:block;margin-top:4px;font-size:var(--t-xs);color:var(--dim2)}
.report .prov a{color:var(--dim2);text-decoration:underline}
.report .prov a:hover{color:var(--accent)}
.report p.note{border-left:2px solid var(--accent);padding-left:10px;color:var(--dim)}
.report .mixedzone{border:1px solid var(--line2);border-radius:var(--r);
  padding:12px 14px;margin:14px 0;background:var(--panel2)}
.report .mixedzone h4{margin-top:0}
.report .mixedzone p{margin-bottom:5px;font-size:var(--t-s)}

/* ---------------------------------------------------------- exit radar */
.exitcard{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:12px}
.exitcard.strong{border-color:var(--negline)}
.exitcard .wh{display:flex;justify-content:space-between;gap:10px;
  align-items:baseline;flex-wrap:wrap}
.exitcard .nn{font-weight:500;cursor:pointer}
.exitcard .nn:hover{color:var(--accent)}
.exitcard .wr{font-size:var(--t-s);color:var(--prose);margin-top:6px}
.exitcard .nm{font-size:var(--t-xs);color:var(--dim2);margin-top:4px}
.exitcard .wmove{margin-top:10px;padding-top:9px;border-top:1px solid var(--line);
  display:flex;gap:8px;flex-wrap:wrap}
details summary::-webkit-details-marker{color:var(--dim2)}

/* ------------------------------------------------------------ live view */
.lbar{text-align:center;margin-bottom:14px}
.lbig{font-family:var(--mono);font-size:var(--t-5xl);font-weight:600;letter-spacing:-.02em}
.lgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.lside{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:12px}
.lhead{text-align:center;padding-bottom:10px;border-bottom:1px solid var(--line);
  margin-bottom:10px}
.lhead .lt{font-size:var(--t-m);font-weight:500}
.lhead .lscore{font-family:var(--mono);font-size:var(--t-3xl);margin:4px 0 2px}
.lgrp{margin-bottom:10px}
.lgl{font-size:var(--t-xxs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:4px}
.lrow{display:flex;gap:9px;align-items:flex-start;padding:5px 6px;
  border-radius:4px;cursor:pointer}
.lrow:hover{background:var(--panel2)}
.lrow .lp{font-family:var(--mono);font-size:var(--t-m);min-width:26px;text-align:right;
  color:var(--dim2)}
.lrow.playing .lp,.lrow.played .lp{color:var(--text)}
.lrow .l1{font-size:var(--t-s)}
.lrow .l2{font-family:var(--mono);font-size:var(--t-xxs);color:var(--dim2);margin-top:1px}
.lrow .l3{font-size:var(--t-xs);color:var(--dim);margin-top:2px}
.lrow.did_not_play{opacity:.55}
.lrow.upcoming{opacity:.75}
.lrow.playing{background:rgba(74,222,128,.05)}
.livedot{display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--pos);margin-left:5px;animation:pulse 1.6s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
.lsubs{border-top:1px solid var(--line);padding-top:9px;margin-bottom:10px}
.nav button .tag{color:var(--pos)}
@media(max-width:900px){.lgrid{grid-template-columns:1fr}}

/* ---------------------------------------------------------- match centre */
/* Two columns, fixed. Ten fixtures divide into five even rows, and a card
   never changes width because of how many siblings it happens to have. */
.mgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
.mcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:13px}
/* Filling the row height is a GRID concern. The same card also renders inside
   the drawer, where height:100% made it swallow the note printed after it. */
.mgrid .mcard{display:flex;flex-direction:column;height:100%}
/* An open card carries line-ups and panels. Left in one column it would drag
   its neighbour's row to match, so it takes the full width instead. */
.mgrid .mcard.open{grid-column:1/-1}
.mwhen{font-size:var(--t-xxs);letter-spacing:.09em;text-transform:uppercase;
  margin-bottom:8px}
/* The expand control sits on the floor of every card in the grid, so the
   buttons line up across a row however much sits above them. */
.mgrid .mcard .mmore{margin-top:auto}
.mcard.live{border-color:var(--posline)}
.mhead{display:grid;grid-template-columns:1fr auto 1fr;gap:12px;align-items:center;
  padding-bottom:10px;border-bottom:1px solid var(--line)}
.mhead .mt{font-size:var(--t-s)}
.mhead .mt.right{text-align:right}
.mmid{text-align:center;min-width:74px}
.mmid .ms{font-family:var(--mono);font-size:var(--t-xl);font-weight:600}
.mmid .mv{font-family:var(--mono);font-size:var(--t-m);color:var(--dim2)}
.mmid .mst{margin-top:3px}

/* The personal read, stated in words at the top of each card. */
.mown{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;padding:9px 0;
  border-bottom:1px solid var(--line);font-size:var(--t-s)}
.ownlab{font-size:var(--t-xxs);letter-spacing:.11em;text-transform:uppercase;
  padding:2px 6px;border-radius:3px}
.ownlab.you{background:var(--accentdim);color:var(--accent)}
.ownlab.opp{background:var(--negdim);color:var(--neg)}
.ownnames{font-size:var(--t-s)}

.mpanel{padding:9px 0;border-bottom:1px solid var(--line)}
.mpanel:last-child{border-bottom:none}
.mpl{font-size:var(--t-xxs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:6px}
.mchips{display:flex;flex-wrap:wrap;gap:5px}

/* Chips are deliberately uniform. Reading a stat panel should feel like
   reading a stat panel; ownership is layered on top only where it changes
   what you would do. */
.chip{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;
  border:1px solid var(--line);border-radius:20px;font-size:var(--t-s);
  background:var(--panel2);cursor:pointer}
.chip:hover{border-color:var(--accent)}
.chip .cv{font-family:var(--mono);font-size:var(--t-xs);color:var(--dim2)}
.chip .cn{white-space:nowrap}
.chip .thr{font-family:var(--mono);font-size:var(--t-xxs);color:var(--dim2)}
.chip .thr.hit{color:var(--pos)}
.chip .tag{font-family:var(--mono);font-size:var(--t-micro);letter-spacing:.08em;
  padding:1px 4px;border-radius:2px;margin-left:1px}
.chip .tag.you{background:var(--accent);color:var(--onfill)}
.chip .tag.opp{background:var(--neg);color:var(--onfill)}
.chip.own-mine{border-color:var(--accent);background:var(--accentdim)}
.chip.own-opp{border-color:var(--negline)}

.bbadge{font-family:var(--mono);font-size:var(--t-xxs);width:16px;height:16px;
  border-radius:3px;display:inline-flex;align-items:center;justify-content:center;
  background:var(--line2);color:var(--text)}
.bbadge.b3{background:var(--medal-3-bg);color:var(--medal-3-fg)}
.bbadge.b2{background:var(--medal-2-bg);color:var(--medal-2-fg)}
.bbadge.b1{background:var(--medal-1-bg);color:var(--medal-1-fg)}

/* The filter is the lens. Nothing is hidden -- context stays -- but anything
   outside the current question recedes, and what remains is lifted. */
.chip.dim{opacity:.16}
.chip.lift{border-color:var(--accent);background:var(--accentdim)}
.chip.own-free.lift{border-color:var(--posline);background:rgba(74,222,128,.10)}
.chip.own-free.lift .cv{color:var(--pos)}
.chip.own-opp.lift{border-color:var(--negline);background:var(--negdim)}
.mcard.faded{opacity:.45}

.mcard details summary{font-size:var(--t-xs);cursor:pointer;padding:7px 0}
@media(max-width:900px){.mgrid{grid-template-columns:1fr}
  .mgrid .mcard.open{grid-column:auto}}

/* ------------------------------------------------------- match log legend */
.legend{margin-top:12px;padding:12px 14px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--panel)}
.lgnd-t{font-size:var(--t-xxs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:8px}
.lgnd-g{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:5px 18px;font-size:var(--t-s);color:var(--dim)}
.lgnd-g b{color:var(--text);font-family:var(--mono);font-size:var(--t-xs);
  margin-right:5px;font-weight:600}
.lgnd-p{font-size:var(--t-s);color:var(--dim);margin-top:9px;line-height:1.55;
  max-width:72ch}
.lgnd-p b{color:var(--text)}
th[title]{cursor:help}
.probeout{margin-top:10px;padding:10px;background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);font-family:var(--mono);
  font-size:var(--t-xs);color:var(--dim);max-height:260px;overflow:auto;white-space:pre-wrap}

/* --------------------------------------------------- outbound profile links */
.profiles{margin-top:7px;font-size:var(--t-xs);display:flex;gap:7px;
  align-items:center;flex-wrap:wrap}
.plink{color:var(--accent);text-decoration:none;border-bottom:1px solid transparent}
.plink:hover{border-bottom-color:var(--accent)}
.plink.guess{color:var(--warn)}
.plink.guess:hover{border-bottom-color:var(--warn)}
tfoot tr.totals td{border-top:1px solid var(--line2);font-weight:500;
  background:var(--panel2)}
tfoot tr.totals.per90 td{font-weight:400;border-top:none;font-size:var(--t-xs)}
tbody tr.thin{opacity:.5}

/* ------------------------------------------------ two-gameweek lookahead */
.alertcard{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:12px;cursor:pointer}
.alertcard.mine{border-left:2px solid var(--accent)}
.alertcard:hover{border-color:var(--line2)}
.alertcard .wh{display:flex;justify-content:space-between;gap:10px;
  align-items:baseline;flex-wrap:wrap;margin-bottom:7px}
.alertcard .nn{font-weight:500}
.alertcard .al{font-size:var(--t-s);color:var(--dim);padding:4px 0;
  display:flex;gap:7px;align-items:baseline}
.alertcard .al.r{color:var(--alert-r)}
.alertcard .al.a{color:var(--alert-a)}

/* ------------------------------------------------- league team scope card */
/* Shown above the player table whenever the table is scoped to one manager's
   squad rather than the free-agent pool. */
.teamcard{margin:0 0 12px;padding:13px 15px;border:1px solid var(--line2);
  border-radius:var(--r);background:var(--panel)}
.tc-head{display:flex;justify-content:space-between;align-items:flex-start;
  gap:18px;flex-wrap:wrap;padding-bottom:11px;border-bottom:1px solid var(--line)}
.tc-name{font-size:var(--t-l);letter-spacing:-.01em}
.tc-opp{text-align:right;min-width:180px}
.tc-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));
  gap:12px 20px;padding-top:11px}
.tc-l{font-size:var(--t-xxs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:3px}
.tc-v{font-family:var(--mono);font-size:var(--t-l);color:var(--text);line-height:1.2}
.tc-sub{font-size:var(--t-xs);color:var(--dim);margin-top:2px}
@media(max-width:640px){.tc-opp{text-align:left}}

/* Secondary figure inside a table cell — the rate beside a raw record. */
td .sub{color:var(--dim);font-size:var(--t-xs);margin-left:5px}

/* ---------------------------------------------------------------- ask box */
.askbox{border:1px solid var(--line2);border-radius:var(--r);
  background:var(--panel);padding:14px 15px;margin-bottom:20px}
#askform{display:flex;gap:8px}
#askq{flex:1;padding:10px 12px;font-size:var(--t-m);background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);color:var(--text)}
#askq:focus{outline:none;border-color:var(--accent)}
#askform button{padding:10px 18px;font-size:var(--t-s);border-radius:var(--r);
  border:1px solid var(--line2);background:var(--panel2);color:var(--text);
  cursor:pointer}
#askform button:hover{border-color:var(--accent);color:var(--accent)}
.askex{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.askex button,.askalt button{font-size:var(--t-xs);padding:4px 9px;border-radius:99px;
  border:1px solid var(--line);background:transparent;color:var(--dim);
  cursor:pointer}
.askex button:hover,.askalt button:hover{border-color:var(--accent);
  color:var(--accent)}
.askwait{margin-top:14px;font-size:var(--t-s);color:var(--dim2)}
.askhead{margin-top:16px;font-size:var(--t-m);letter-spacing:-.01em}
.askchips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin:8px 0 12px}
.askchips-t{font-size:var(--t-xxs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim2);margin-right:3px}
.askchip{font-size:var(--t-xs);padding:3px 9px;border-radius:99px;
  border:1px solid var(--line2);background:var(--panel2);color:var(--text)}
.askchip i{font-style:normal;color:var(--dim2);margin-right:6px;font-size:var(--t-xxs);
  letter-spacing:.06em;text-transform:uppercase}
.askwarn{margin-bottom:11px;padding:9px 11px;border-radius:var(--r);
  border:1px solid var(--warnline);background:var(--warndim);
  color:var(--warn);font-size:var(--t-s);
  line-height:1.5}
.asktable td{vertical-align:top}
.askwhy{font-size:var(--t-xs);color:var(--dim);line-height:1.5;max-width:44ch}
.asknote{font-size:var(--t-xs);color:var(--dim2);margin-top:9px;line-height:1.55;
  max-width:80ch}
.askalt{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:11px}
.askmiss{margin-top:14px;padding:12px 14px;border-radius:var(--r);
  border:1px solid var(--line2);background:var(--panel2)}
.askmiss-h{font-size:var(--t-s);margin-bottom:6px}
.askmiss p{font-size:var(--t-s);color:var(--dim);line-height:1.6;margin-top:5px;
  max-width:74ch}

/* --------------------------------------------------------- insights tab */
.inslist{display:flex;flex-direction:column;gap:10px}
.ins{padding:12px 14px;border:1px solid var(--line2);border-radius:var(--r);
  background:var(--panel2);border-left:3px solid var(--line2)}
.ins-pos{border-left-color:var(--pos)}
.ins-neg{border-left-color:var(--neg)}
.ins-h{font-size:var(--t-s);display:flex;justify-content:space-between;
  align-items:baseline;gap:12px;flex-wrap:wrap}
.ins-tag{font-size:var(--t-xxs);letter-spacing:.1em;text-transform:uppercase;
  white-space:nowrap;font-family:var(--mono)}
.ins-tag.pos{color:var(--pos)}
.ins-tag.neg{color:var(--neg)}
.ins-e{font-size:var(--t-s);color:var(--dim);line-height:1.6;margin-top:6px;
  max-width:78ch}
.ins-f{font-size:var(--t-s);color:var(--text);line-height:1.55;margin-top:6px;
  max-width:78ch}
.ins-c{font-size:var(--t-xs);color:var(--warn);line-height:1.55;margin-top:6px;
  max-width:78ch}
.ins-b{font-size:var(--t-xxs);letter-spacing:.08em;text-transform:uppercase;
  color:var(--dim2);margin-top:8px;font-family:var(--mono)}

/* Label-and-values grids: without a fixed layout the auto-width label column
   absorbs every spare pixel and shoves the numbers to the far edge. */
.vtable{table-layout:fixed}
.vtable th:first-child,.vtable td:first-child{width:34%;min-width:150px;
  white-space:normal}
.vtable th:not(:first-child),.vtable td:not(:first-child){width:22%}

/* ------------------------------------------------------------ XI planner */
.planbar{display:flex;justify-content:space-between;align-items:center;gap:14px;
  flex-wrap:wrap;margin-bottom:10px}
.planstate{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.planscore{display:flex;align-items:baseline;gap:7px}
.shapebits{display:flex;gap:5px}
.shapebit{font-family:var(--mono);font-size:var(--t-s);color:var(--dim);
  border:1px solid var(--line2);border-radius:99px;padding:2px 8px}
.shapebit i{font-style:normal;font-size:var(--t-xxs);letter-spacing:.08em;
  color:var(--dim2);margin-left:3px}
.shapebit.bad{color:var(--neg);border-color:var(--negline)}
.planbad{margin-bottom:10px;padding:9px 12px;border-radius:var(--r);
  border:1px solid var(--negline);background:var(--negdim);
  color:var(--neg);font-size:var(--t-s);
  line-height:1.55;max-width:80ch}
.planbad b{color:var(--planbad-fg)}
.planhold{margin-bottom:10px;padding:8px 12px;border-radius:var(--r);
  border:1px solid var(--accent);background:var(--accentdim);
  color:var(--text);font-size:var(--t-s)}
.planhold b{color:var(--accent)}
.lnk{color:var(--accent);text-decoration:underline;font-size:var(--t-s)}
.pcard{cursor:pointer;transition:border-color .12s,transform .12s}
.pcard:hover{border-color:var(--accent)}
.pcard.held{border-color:var(--accent);background:var(--accentdim);
  transform:translateY(-2px)}
.planacts{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:14px}
.planacts .btn[disabled]{opacity:.4;cursor:not-allowed}
.card .ord.neg{color:var(--neg)}

/* ------------------------------------------------------ predicted line-ups */
.pxwrap{margin-top:10px;border-top:1px solid var(--line);padding-top:8px}
.pxwrap summary{font-size:var(--t-xs);cursor:pointer;padding:2px 0}
.pxgrid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:10px}
@media(max-width:640px){.pxgrid{grid-template-columns:1fr}}
.pxh{font-size:var(--t-s);margin-bottom:6px;display:flex;justify-content:space-between;
  gap:8px;align-items:baseline}
.pxh .mono{font-size:var(--t-xxs)}
.pxr{display:flex;gap:7px;align-items:baseline;padding:2px 4px;border-radius:3px;
  font-size:var(--t-s);cursor:pointer}
.pxr:hover{background:var(--panel2)}
.pxr.you{background:var(--posdim)}
.pxr.opp{background:var(--negdim)}
.pxp{font-family:var(--mono);font-size:var(--t-xxs);color:var(--dim2);width:26px;
  flex:none}
.pxn{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pxv{font-size:var(--t-xs);color:var(--dim);flex:none}
/* Points sit at the end of the row, fixed width so the column reads down the
   side rather than wandering with each name. Minutes are the context; the
   points are the thing the screen is for. */
.pxpts{font-size:var(--t-s);flex:none;width:30px;text-align:right;font-weight:600}
.pxq{color:var(--warn);font-size:var(--t-xxs);cursor:help}
.pxnote{font-size:var(--t-xs);color:var(--dim);margin-top:7px;line-height:1.5}
.pxnote b{color:var(--text)}
.pxnote.neg b{color:var(--neg)}
.pxsrc{font-size:var(--t-xs);color:var(--dim2);line-height:1.55;margin-top:10px;
  max-width:90ch}
.pxsrc b{color:var(--dim)}

/* The planner card's own dossier button. The card body is for swapping, so
   opening a player needs its own target rather than competing for the click. */
.pcard{position:relative;padding-right:26px}
.pinfo{position:absolute;top:5px;right:5px;width:19px;height:19px;
  border-radius:50%;border:1px solid var(--line2);background:var(--panel);
  color:var(--dim2);line-height:0;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  padding:0;transition:color .12s,border-color .12s}
.pinfo:hover{color:var(--accent);border-color:var(--accent)}
.pcard.held .pinfo{border-color:var(--accent)}
.pinfo-inline{display:inline-flex;align-items:center;justify-content:center;
  width:17px;height:17px;border-radius:50%;border:1px solid var(--line2);
  vertical-align:middle;line-height:0;color:var(--dim2)}

/* ------------------------------------------------------------ gw archive */
.approved{margin-bottom:12px;padding:10px 13px;border-radius:var(--r);
  border:1px solid var(--posline);background:var(--posdim);font-size:var(--t-s);
  line-height:1.6;color:var(--dim);max-width:90ch}
.approved .pill{margin-right:7px}
.arclist{display:flex;flex-direction:column;gap:8px}
.arc{border:1px solid var(--line);border-radius:var(--r);background:var(--panel);
  padding:11px 13px}
.arc.on{border-color:var(--accent)}
.arch{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;
  align-items:baseline;margin-bottom:6px}
.arc summary{font-size:var(--t-xs);cursor:pointer}
.arcbody{margin-top:9px;padding:11px;background:var(--panel2);
  border:1px solid var(--line);border-radius:var(--r);font-family:var(--mono);
  font-size:var(--t-s);line-height:1.7;white-space:pre-wrap;color:var(--dim);
  max-height:420px;overflow:auto}

/* ------------------------------------------------------------------ radar */
/* One card at a time. A scrolling stack always shows half of the next card,
   which is exactly the thing you are not reading. */
.radar{display:flex;gap:10px;align-items:flex-start;margin-bottom:20px}
.rstage{flex:1;min-width:0}
.rstage .hero{margin-bottom:0}
.rstage.in{animation:cardin .18s ease-out}
@keyframes cardin{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.rstage.in{animation:none}}
/* Centring the controls against the card meant they moved every time a card
   of a different height swapped in -- 246px of travel between the shortest
   and tallest. They are pinned to the top of the row instead, so their
   position depends on the block and not on its contents, and made sticky so
   they stay reachable while a long card is being read. */
.rnav{display:flex;flex-direction:column;align-items:center;gap:8px;
  justify-content:flex-start;flex:none;padding:4px 0;align-self:flex-start;
  position:sticky;top:84px;z-index:5}
.rbtn{width:26px;height:26px;border-radius:50%;border:1px solid var(--line2);
  background:var(--panel);color:var(--dim2);font-size:var(--t-s);cursor:pointer;
  display:flex;align-items:center;justify-content:center;padding:0}
.rbtn:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}
.rbtn:disabled{opacity:.3;cursor:default}
.rdots{display:flex;flex-direction:column;gap:6px}
.rdot{width:7px;height:7px;border-radius:50%;padding:0;border:none;
  background:var(--line2);cursor:pointer;transition:background .15s,transform .15s}
.rdot:hover{background:var(--dim2)}
.rdot.on{background:var(--accent);transform:scale(1.35)}
@media(max-width:900px){
  .radar{flex-direction:column}
  .rnav{flex-direction:row;justify-content:center;align-self:stretch;
    position:static}
  .rdots{flex-direction:row}
}


/* --------------------------------------------------------- match briefing */
.bfside{min-width:0}
.bfh{font-size:var(--t-s);margin-bottom:8px}
.bfsec{margin-bottom:11px}
.bfl{font-size:var(--t-xxs);letter-spacing:.12em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:5px}
.bfl .dim2{letter-spacing:0;text-transform:none;font-size:var(--t-xxs);margin-left:5px}
.bfl2{list-style:none;display:flex;flex-direction:column;gap:5px;
  font-size:var(--t-s);line-height:1.5}
.bfl2 li{color:var(--dim)}
.bfl2 li b{color:var(--text)}
.bfl2 li[data-pid]{cursor:pointer;padding:3px 5px;border-radius:3px;
  margin:0 -5px}
.bfl2 li[data-pid]:hover{background:var(--panel2)}
.bfl2 li.you{background:var(--posdim)}
.bfl2 li.opp{background:var(--negdim)}
.bfl2 a{color:var(--text)}
.bfl2 a:hover{color:var(--accent)}
.bfn{font-size:var(--t-xs);color:var(--dim2);margin-top:2px}
.bfout{font-size:var(--t-xs);color:var(--dim);line-height:1.6}
.bfout b{color:var(--dim2);font-size:var(--t-xxs);letter-spacing:.1em;
  text-transform:uppercase;margin-right:4px}
.bfout span[data-pid]{cursor:pointer;border-radius:3px;padding:0 3px}
.bfout span.you{background:var(--posdim)}
.bfout span.opp{background:var(--negdim)}

/* ---------------------------------------------------------- report direction */
.dirout{margin-top:12px;padding:11px 13px;border-radius:var(--r);
  border:1px solid var(--line2);background:var(--panel2)}
.dirsum{font-size:var(--t-s);line-height:1.6;color:var(--text);max-width:86ch}
.dirchips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:9px}
.dirig{font-size:var(--t-xs);color:var(--dim);margin-top:9px;line-height:1.6;
  max-width:86ch}
.dirig code{font-family:var(--mono);font-size:var(--t-xs);color:var(--warn);
  background:var(--warndim);padding:1px 5px;border-radius:3px;margin-right:2px}
.teamrow.misfiled{border-left:2px solid var(--warn);padding-left:9px}
.misnote{font-size:var(--t-xs);color:var(--warn);line-height:1.55;margin-top:4px;
  max-width:80ch}
.misnote .lnk{margin-left:4px}

/* The fixture story: this week's decision, then the three after it. Kept apart
   because a player can be a clear hold now and a clear sell in three. */
.wstory{margin-top:8px;padding:8px 10px;border-radius:var(--r);
  background:var(--panel2);border:1px solid var(--line);font-size:var(--t-s);
  line-height:1.6;color:var(--dim)}

/* ------------------------------------------------------ positional scarcity */
.scard{display:flex;flex-direction:column}
.sclist{margin-top:8px;display:flex;flex-direction:column;gap:1px}
.scrow{display:flex;align-items:baseline;gap:8px;padding:4px 6px;margin:0 -6px;
  border-radius:3px;font-size:var(--t-s);cursor:pointer}
.scrow[data-pid]:hover{background:var(--panel2)}
.scrow .scl{font-size:var(--t-xxs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim2);flex:none;width:88px}
.scrow .scn{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.scrow .scr{font-size:var(--t-xxs);letter-spacing:.08em;flex:none}
.scrow .scv{font-size:var(--t-s);flex:none}
.scrow.pos .scv{color:var(--pos)}
.scrow.neg .scv{color:var(--neg)}
.scmore{margin-top:9px}
.scmore summary{font-size:var(--t-xs);cursor:pointer}

/* ------------------------------------------------------- stale app notice */
#stalebar{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);
  z-index:60;display:flex;align-items:center;gap:14px;max-width:min(680px,92vw);
  padding:11px 14px;border-radius:var(--r);background:var(--panel);
  border:1px solid var(--accent);box-shadow:0 10px 30px -12px var(--shadow);
  font-size:var(--t-s);color:var(--text);line-height:1.5}
#stalebar .btn{flex:none}

/* A live row leads to the match; the small i leads to the player. */
.lrow.hasmatch{cursor:pointer}
.lrow .lpi{position:static;margin-left:6px;width:17px;height:17px;
  display:inline-flex;vertical-align:middle}

@media(prefers-reduced-motion:reduce){.livedot{animation:none}}

/* ---------------------------------------------------------- info popover */
.infowrap{position:relative;display:inline-flex;align-items:center;
  letter-spacing:0;text-transform:none}
.infodot{width:15px;height:15px;border-radius:50%;border:1px solid var(--line2);
  background:var(--panel2);color:var(--dim2);font-size:var(--t-xxs);line-height:1;
  font-family:var(--mono);cursor:pointer;display:flex;align-items:center;
  justify-content:center;padding:0;flex:none}
.infodot:hover{color:var(--accent);border-color:var(--accent)}
.infopop{position:absolute;top:22px;left:-4px;z-index:40;width:min(340px,80vw);
  padding:11px 13px;border-radius:var(--r);background:var(--panel);
  border:1px solid var(--line2);box-shadow:0 12px 30px -14px var(--shadow);
  font-size:var(--t-xs);line-height:1.6;color:var(--dim);
  text-transform:none;letter-spacing:0;font-weight:400;text-align:left}
.infopop.flip{left:auto;right:-4px}
.infopop[hidden]{display:none}
.infopop b{display:block;color:var(--text);font-size:var(--t-s);margin-bottom:6px}
.infopop p{margin:0 0 6px}
.infopop p:last-child{margin-bottom:0}

/* Matchday carries a live dot rather than a bullet glyph, so it reads as
   "matches are on right now" instead of as a decoration. */
.nav .tag.livetag{background:none;border:none;padding:0;display:flex;
  align-items:center}
.nav .tag.livetag .livedot{margin:0}

.bpsgap{margin-left:8px;font-size:var(--t-xxs);letter-spacing:.04em;
  text-transform:none;color:var(--dim2)}
.bpsgap.tight{color:var(--warn)}

/* ------------------------------------------------------------ substitutions */
.subchip{display:inline-flex;align-items:baseline;gap:5px;padding:3px 9px;
  border:1px solid var(--line2);border-radius:99px;font-size:var(--t-s);
  background:var(--panel2);cursor:pointer}
.subchip:hover{border-color:var(--accent)}
.subchip.you{border-color:var(--accent);background:var(--accentdim)}
.subchip.opp{border-color:var(--negline);background:var(--negdim)}
.subchip i{font-style:normal;font-size:var(--t-xs)}
.subchip i.on{color:var(--pos)}
.subchip i.off{color:var(--dim2)}
.subchip b{font-family:var(--mono);font-size:var(--t-xxs);color:var(--dim2);
  font-weight:400}

/* Hollow green: he has played his minutes and the match has reached 90, but
   the final whistle has not been recorded. Solid and pulsing means one thing
   only — on the pitch right now. */
.donedot{display:inline-block;width:6px;height:6px;border-radius:50%;
  background:none;border:1px solid var(--pos);margin-left:5px}

/* Home / away pair. The two halves get equal fixed columns so the slash lands
   at the same offset on every row — right-aligning the cell as a whole left
   "7/8" and "7/12" with their slashes in different places, which is exactly
   the column you want to read down. */
.hapair{display:inline-grid;grid-template-columns:1.7em auto 1.7em;
  align-items:baseline}
.hah{text-align:right}
.haa{text-align:left}
.haslash{color:var(--line2);padding:0 1px}

/* ------------------------------------------------------------- match pins */
.mhead{position:relative}
.mpin{position:absolute;top:0;right:0;width:24px;height:24px;border:none;
  background:none;color:var(--line2);font-size:var(--t-m);cursor:pointer;padding:0;
  line-height:1}
.mpin:hover{color:var(--dim)}
.mpin.on{color:var(--accent)}
.mcard.pinned{border-color:var(--accent)}
.mmore{margin-top:10px;width:100%;padding:6px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--panel2);color:var(--dim2);
  font-size:var(--t-xs);cursor:pointer}
.mmore:hover{color:var(--accent);border-color:var(--line2)}

.subnote{font-size:var(--t-xs);color:var(--dim);line-height:1.55;margin-top:8px;
  max-width:82ch}
.subnote b{color:var(--text)}

/* Highlights search links. */
.hlink{display:inline-flex;align-items:center;gap:4px;padding:3px 11px;
  border:1px solid var(--line2);border-radius:99px;font-size:var(--t-s);
  background:var(--panel2);color:var(--dim)}
.hlink:hover{color:var(--accent);border-color:var(--accent)}

/* --------------------------------------------------- substitution pairings */
.subpairs{display:flex;flex-direction:column;gap:2px;margin-top:2px}
.subpair{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  padding:4px 6px;margin:0 -6px;border-radius:3px;font-size:var(--t-s)}
.subpair:hover{background:var(--panel2)}
.subpair.loose{border-left:2px solid var(--line2);padding-left:8px}
.submin{font-size:var(--t-xs);color:var(--dim2);width:30px;flex:none;text-align:right}
.subclub{font-size:var(--t-xxs);letter-spacing:.08em;width:30px;flex:none}
.subon{color:var(--pos)}
.suboff{color:var(--dim)}
.subfor{font-size:var(--t-xs)}
.subname{cursor:pointer;color:var(--text);border-radius:3px;padding:0 3px}
.subname:hover{color:var(--accent)}
.subname.you{background:var(--posdim)}
.subname.opp{background:var(--negdim)}
.subq{font-size:var(--t-xxs);letter-spacing:.06em;text-transform:uppercase;
  color:var(--warn);cursor:help}
.subloose{font-size:var(--t-s);margin-top:6px;display:flex;gap:6px;flex-wrap:wrap;
  align-items:baseline}
/* Highlights sit with the result, not at the bottom of the card. */
.mhl{position:absolute;top:0;left:0;display:flex;gap:6px}
.hlink.sm{padding:2px 8px;font-size:var(--t-xs)}

/* A manager's live side on his own card. */
.tlrow{display:flex;align-items:baseline;gap:9px;padding:3px 5px;margin:0 -5px;
  border-radius:3px;font-size:var(--t-s);cursor:pointer}
.tlrow:hover{background:var(--panel2)}
.tlp{width:22px;text-align:right;flex:none;font-size:var(--t-s)}
.tln{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tls{font-size:var(--t-xs);flex:none}

/* Find-replacements button, on the card of the player who needs one. */
.repl{margin-top:7px;width:100%;padding:5px 8px;border-radius:var(--r);
  border:1px solid var(--line2);background:var(--panel);color:var(--dim);
  font-size:var(--t-xs);cursor:pointer}
.repl:hover{color:var(--accent);border-color:var(--accent)}
.repl.big{padding:7px 8px;font-size:var(--t-s);background:var(--accentdim);
  border-color:var(--accentline);color:var(--accent)}
.repl.big:hover{background:var(--repl-hover)}
.card .ord.warn{color:var(--warn)}

.watchcard2 .wh{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;flex-wrap:wrap}
.watchcard2 .nn{cursor:pointer}
.watchcard2 .nn:hover{color:var(--accent)}
.watchcard2 .wr{font-size:var(--t-s);color:var(--dim);line-height:1.55;margin-top:6px}
.watchcard2 .wmeta{display:flex;gap:12px;flex-wrap:wrap;font-family:var(--mono);
  font-size:var(--t-xs);color:var(--dim2);margin-top:8px}

/* Banner while the pool is scoped to replacing one specific player. */
.replbar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin-bottom:12px;padding:9px 13px;border-radius:var(--r);
  border:1px solid var(--accent);background:var(--accentdim);
  font-size:var(--t-s);line-height:1.55}
.replbar b{color:var(--text)}
.replbar .btn{flex:none}

/* Paste-the-team-sheet box. */
.sheetin{width:100%;min-height:120px;margin-top:8px;background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);padding:9px 11px;
  color:var(--text);font-family:var(--mono);font-size:var(--t-s);line-height:1.6;
  outline:none;resize:vertical}
.sheetin:focus{border-color:var(--accent)}
.sheetlist{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}

/* ------------------------------------------------------ team news layout */
.hlnews .wh{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;flex-wrap:wrap}
.hlnews .nn{cursor:pointer}
.hlnews .nn:hover{color:var(--accent)}
.hlnews .wr{font-size:var(--t-s);line-height:1.55;margin-top:7px}
.hlnews .wr a{color:var(--text)}
.hlnews .wr a:hover{color:var(--accent)}
.hlnews .wmeta{display:flex;gap:12px;flex-wrap:wrap;font-family:var(--mono);
  font-size:var(--t-xs);color:var(--dim2);margin-top:9px}
.hlnews.flagged{border-color:var(--negline)}
.pnews{border-bottom:1px solid var(--line)}
.pnews:last-of-type{border-bottom:none}
.pnews > summary{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  padding:8px 4px;cursor:pointer;font-size:var(--t-s);list-style:none}
.pnews > summary::-webkit-details-marker{display:none}
.pnews > summary::before{content:'▸';color:var(--dim2);font-size:var(--t-xxs);
  margin-right:2px}
.pnews[open] > summary::before{content:'▾'}
.pnews > summary:hover{background:var(--panel2)}
.pnews.flagged > summary{border-left:2px solid var(--neg);padding-left:8px}
.pn-name{font-weight:500}
.pn-name:hover{color:var(--accent)}
.pnews-body{padding:2px 6px 12px 20px}
.pnews-body .wr{font-size:var(--t-s);color:var(--dim);line-height:1.55;
  margin-bottom:8px}

/* ------------------------------------------------------ league scoreboard */
.sbgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:8px;margin-bottom:14px}
.sbtie{display:flex;flex-direction:column;gap:2px;padding:9px 11px;
  border:1px solid var(--line);border-radius:var(--r);background:var(--panel);
  cursor:pointer;text-align:left;font:inherit}
.sbtie:hover{border-color:var(--line2)}
.sbtie.on{border-color:var(--accent);background:var(--accentdim)}
.sbtie.mine .sbn{color:var(--text)}
.sbrow{display:flex;justify-content:space-between;gap:8px;align-items:baseline;
  font-size:var(--t-s)}
.sbn{color:var(--dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sbrow b{font-family:var(--mono);font-size:var(--t-m);color:var(--dim);flex:none}
.sbrow b.pos{color:var(--pos)}
.sbmeta{font-size:var(--t-xxs);color:var(--dim2);margin-top:3px}

/* Basis toggle on the planner: three sources for one eleven. */
/* A second, unrelated component that also happens to be a row of buttons.
   It was written as a bare `.seg` nine hundred lines below the first one and
   silently overrode its display, border colour and margin for EVERY strip in
   the app -- two rules for one name, merged by the cascade rather than by
   anyone's decision, and neither author aware of the other.

   Scoped rather than renamed. Its buttons already carry their own class, so
   :has() says exactly what the selector always meant: this rule is for the
   strips built out of .segbtn. Renaming the container instead would have
   meant finding every one of them, and half are assembled through a variable
   where a search cannot see the pairing. */
.seg:has(.segbtn){display:inline-flex;gap:0;border:1px solid var(--line);
  border-radius:7px;overflow:hidden;margin-left:10px;vertical-align:middle}
.segbtn{background:transparent;border:0;color:var(--dim);font:inherit;
  font-size:var(--t-xs);letter-spacing:.04em;padding:4px 10px;cursor:pointer}
.segbtn+.segbtn{border-left:1px solid var(--line)}
.segbtn:hover{color:var(--fg);background:var(--rise)}
.segbtn.on{background:var(--rise);color:var(--fg)}
/* A reference eleven is read-only, so it must not look clickable. */
.pcard.ref{cursor:default}
.pcard.ref:hover{border-color:var(--line)}
.tbl.mini tr.hi td{background:var(--rise)}

/* ------------------------------------------------- league ties */
.tiegw{margin-bottom:14px}
.tiegwh{font-size:var(--t-xxs);letter-spacing:.11em;margin-bottom:5px}
.tie{display:grid;grid-template-columns:52px 1fr 74px 1fr 76px;align-items:center;
  gap:8px;padding:7px 10px;border:1px solid var(--line);border-radius:var(--r);
  margin-bottom:5px;cursor:pointer;background:var(--panel)}
.tie:hover{border-color:var(--line2);background:var(--panel2)}
.tie.mine{border-left:2px solid var(--accent)}
.tie .tt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tie .ta{text-align:right}
.tie .tsc{text-align:center;font-size:var(--t-m)}
.tie .tw{color:var(--pos)}
.tie .tme{font-weight:600}
.tie .tmore{text-align:right;font-size:var(--t-xs);opacity:0;transition:opacity .12s}
.tie:hover .tmore{opacity:1}
/* Each side's remaining players sit beside that side's own name, so there is
   never a question which team the number belongs to. */
.tie .tleft{font-size:var(--t-xxs);white-space:nowrap;margin-left:7px}
.tie .ta .tleft{margin:0 7px 0 0}
@media(max-width:640px){
  .tie{grid-template-columns:44px 1fr 62px 1fr;gap:6px}
  .tie .tmore{display:none}
}
/* One tie, opened out. */
.tsh{margin-bottom:9px;padding-bottom:7px;border-bottom:1px solid var(--line2)}
.tsr{display:grid;grid-template-columns:34px 1fr auto 42px;gap:7px;
  align-items:center;padding:3px 0;border-bottom:1px solid var(--line)}
.tsr.dim .tsn,.tsr.dim .num{color:var(--dim)}
.tsr[data-pid]{cursor:pointer}
.tsr[data-pid]:hover .tsn{color:var(--accent)}
.tsn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tsb{margin-top:9px;padding-top:7px;border-top:1px solid var(--line2)}
.tst{display:flex;justify-content:space-between;margin-top:9px;padding-top:7px;
  border-top:1px solid var(--line2);font-size:var(--t-m)}
.momrow{padding:9px 12px;border:1px solid var(--line2);border-radius:var(--r);
  margin-bottom:12px;background:var(--panel)}
.momn{font-size:var(--t-m);margin-top:2px}

/* --------------------------------------------- week by week (the side race) */
/* Newest on the left, older ones a swipe away. Snap is `proximity`, never
   `mandatory` -- mandatory silently kills programmatic smooth scrolling. */
.wkstrip{display:flex;gap:8px;overflow-x:auto;padding:2px 2px 8px;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch}
.wkstrip::-webkit-scrollbar{height:6px}
.wkstrip::-webkit-scrollbar-thumb{background:var(--line2);border-radius:3px}
.wk{flex:0 0 auto;width:112px;padding:9px 10px;border-radius:var(--r);
  border:1px solid var(--line);background:var(--panel);scroll-snap-align:start;
  cursor:pointer;transition:border-color .12s,background .12s}
.wk:hover{border-color:var(--line2);background:var(--panel2)}
.wke{font-size:var(--t-xxs);letter-spacing:.09em;color:var(--dim2)}
.wkp{font-size:var(--t-2xl);font-weight:600;line-height:1.15;margin:1px 0 2px}
.wkt{font-size:var(--t-xs);color:var(--dim);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.wkb{font-size:var(--t-micro);letter-spacing:.1em;margin-top:5px;color:var(--dim2)}
/* The season's best is a filled box, not an outlined one. */
.wk.best{background:var(--pos);border-color:var(--pos)}
.wk.best .wke,.wk.best .wkp,.wk.best .wkt,.wk.best .wkb{color:var(--wk-best)}
.wk.best .wkt,.wk.best .wke,.wk.best .wkb{opacity:.72}
.wk.best:hover{background:var(--pos);filter:brightness(1.06)}
.wk.mine:not(.best){border-color:var(--accent)}

/* Best GW opens the eleven that scored it, so it has to look like a target. */
.bestgw{background:none;border:0;padding:0;font:inherit;color:inherit;
  cursor:pointer;display:inline-flex;align-items:baseline;gap:5px}
.bestgw b{font-size:var(--t-m);border-bottom:1px dotted var(--line2)}
.bestgw:hover b{color:var(--accent);border-bottom-color:var(--accent)}
.bestgw .mono{font-size:var(--t-xxs)}

/* Sortable headers in the team Form table. */
th.sortable{cursor:pointer;user-select:none}
th.sortable:hover{color:var(--text)}
th.sortable.on{color:var(--accent)}

/* Sub-destinations under an open nav item. */
.nav button.sub{padding-left:26px;font-size:var(--t-s);color:var(--dim2)}
.nav button.sub::before{content:'';position:absolute;margin-left:-12px;
  width:1px;height:14px;background:var(--line2)}
.nav button.sub{position:relative}
.nav button.sub:hover{color:var(--text)}
.nav button.sub.on{background:var(--accentdim);color:var(--accent)}

/* ------------------------------------------ press-conference team news */
.pressgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
  gap:12px}
.presscard{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:12px 14px}
.presscard.mine{border-left:2px solid var(--accent)}
.pressh{display:flex;justify-content:space-between;align-items:center;gap:10px;
  margin-bottom:7px;font-size:var(--t-s)}
.pressn{font-size:var(--t-s);line-height:1.6;color:var(--dim);margin-bottom:7px}
/* The quoted words are the part that carries weight. */
.pressq{font-size:var(--t-s);line-height:1.6;padding:7px 10px;margin-top:6px;
  border-left:2px solid var(--line2);background:var(--panel2);
  border-radius:0 var(--r) var(--r) 0}
.pq{color:var(--text);font-weight:600}
h3.sub{font-size:var(--t-xs);letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim2);margin:14px 0 8px}
/* The quote is context, not the column you scan -- so it is clamped to two
   lines and the whole sentence sits in the tooltip. Left unclamped it pushed
   the Watch button off the edge of the table. */
.pressay{font-size:var(--t-xs);color:var(--dim);line-height:1.45;
  max-width:460px;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden}
.btn.sm{padding:3px 9px;font-size:var(--t-xs)}
.btn.sm.on{background:var(--accentdim);color:var(--accent);
  border-color:var(--accentdim)}

/* An openable row in the claim list. */
tr.mrow{cursor:pointer}
tr.mrow:hover{background:var(--panel2)}
tr.mrow .chev{display:inline-block;width:12px;color:var(--dim2);font-size:var(--t-xxs)}
tr.mdetail>td{background:var(--panel2);padding:14px 16px}
.mdgrid{display:grid;grid-template-columns:1.35fr 1fr;gap:18px}
@media(max-width:900px){.mdgrid{grid-template-columns:1fr}}
.insrow{padding:6px 0;border-bottom:1px solid var(--line);font-size:var(--t-s);
  line-height:1.5}
.insrow:last-child{border-bottom:none}
.insh{color:var(--text)}
.insfx{color:var(--accent);font-size:var(--t-xs);margin-top:2px}
.mdfx{display:flex;gap:5px;flex-wrap:wrap}
.load.sm{padding:14px}
.pill.prio{font-size:var(--t-xxs);letter-spacing:.06em;white-space:nowrap}
.forwho{font-size:var(--t-xxs);margin-top:1px}
.keptnote{font-size:var(--t-s);color:var(--dim);background:var(--panel);
  border:1px solid var(--line2);border-left:2px solid var(--pos);
  border-radius:var(--r);padding:9px 12px;margin-bottom:10px;line-height:1.55}

/* ------------------------------------------------------- keeping a player */
.keepcard{border-left:2px solid var(--pos)}
.keepcard.changed{border-color:var(--warn);border-left-color:var(--warn)}
.keepchg{font-size:var(--t-s);margin-top:8px;padding:8px 10px;border-radius:var(--r);
  background:var(--panel2);line-height:1.55}
.keepchg.fresh{background:var(--warndim);color:var(--text)}
.keeptl{margin-top:5px}
.keeptl .tlrow{display:flex;gap:8px;align-items:baseline;font-size:var(--t-xs);
  padding:4px 0;border-bottom:1px solid var(--line);line-height:1.45}
.keeptl .tlrow:last-child{border-bottom:none}
.keepsrch{display:flex;gap:6px;flex-wrap:wrap;margin-top:5px}

/* -------------------------------------------------- fixture win probability */
.odds{margin:9px 0 4px}
.obar{display:flex;height:6px;border-radius:3px;overflow:hidden;
  background:var(--line)}
.obar .oh{background:var(--pos)}
.obar .od{background:var(--line2)}
.obar .oa{background:var(--accent)}
.orow{display:flex;justify-content:space-between;font-size:var(--t-xs);
  margin-top:5px}
.onote{font-size:var(--t-xxs);margin-top:3px;line-height:1.45}

/* ------------------------------------------------------------- ask anything */
.asksearch{position:relative;padding:0 14px 12px}
.asksearch input{width:100%;padding:7px 10px;font:inherit;font-size:var(--t-s);
  color:var(--text);background:var(--panel2);border:1px solid var(--line2);
  border-radius:var(--r)}
.asksearch input:focus{outline:none;border-color:var(--accent)}
.qres{position:absolute;left:14px;right:14px;top:100%;z-index:60;
  background:var(--panel);border:1px solid var(--line2);border-radius:var(--r);
  box-shadow:0 18px 40px rgba(0,0,0,.55);max-height:70vh;overflow:auto;
  min-width:320px}
.qcard{padding:12px 14px}
.qhead{display:flex;justify-content:space-between;align-items:center;gap:10px}
.qhl{font-size:var(--t-s);margin:7px 0 8px;line-height:1.5}
.qnums{display:flex;gap:12px;flex-wrap:wrap;font-size:var(--t-xs);
  padding-bottom:8px;border-bottom:1px solid var(--line);margin-bottom:8px}
.qr{font-size:var(--t-xs);color:var(--dim);line-height:1.55;padding:3px 0}
.qr.warnr{color:var(--warn)}
.qacts{margin-top:9px}
.qalso{font-size:var(--t-xs);margin-top:8px;padding-top:7px;
  border-top:1px solid var(--line)}
@media(max-width:900px){.qres{position:fixed;left:10px;right:10px;top:auto}}
.h2hbox{margin:10px 0;padding:9px 11px;border:1px solid var(--line);
  border-radius:var(--r);background:var(--panel2);font-size:var(--t-s)}
.h2hrow{display:flex;gap:14px;flex-wrap:wrap;align-items:baseline;margin-top:4px}
.h2hlist{display:flex;gap:6px;flex-wrap:wrap;margin-top:7px}
.h2hm{font-size:var(--t-xs);color:var(--dim);border:1px solid var(--line2);
  border-radius:3px;padding:2px 6px}

/* ------------------------------------------------ trophies, pot, archive */
.cabgrid,.potgrid{display:grid;gap:10px;margin-bottom:14px;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.cabcard,.potcard{background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:11px 13px}
.potcard.mine{border-left:2px solid var(--accent)}
.cabt{font-size:var(--t-m)}
.cabn{font-size:var(--t-s);margin-top:5px}
.potamt{font-family:var(--mono);font-size:var(--t-xl)}
.potlab{font-size:var(--t-s);margin-top:2px}
.potwho{font-size:var(--t-s);color:var(--dim);margin-top:4px}
.trophyrow{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.trophy{display:flex;gap:9px;align-items:flex-start;background:var(--panel);
  border:1px solid var(--line);border-radius:var(--r);padding:9px 12px;
  min-width:210px}
.trophy.champion{border-color:var(--trophy-line)}
.tico{font-size:var(--t-l);line-height:1.2}
.tlab{font-size:var(--t-xxs);letter-spacing:.09em;text-transform:uppercase}
.tname{font-size:var(--t-s)}
.checks{margin:8px 0}
.chk{font-size:var(--t-xs);padding:2px 0}
.chk.ok{color:var(--pos)}
.chk.bad{color:var(--neg)}
textarea.vin{width:100%;font-family:var(--mono);font-size:var(--t-xs);margin-top:8px;
  resize:vertical}

tr.dimrow td{color:var(--dim2)}
tr.oppRow td{background:var(--negdim)}

/* The wire. Terminal density: fixed columns, monospace clock, tag chips. */
.wire{border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.wrow{display:grid;grid-template-columns:62px 118px 1fr 150px;gap:11px;
  padding:7px 11px;border-bottom:1px solid var(--line);font-size:var(--t-s);
  align-items:baseline}
.wrow:last-child{border-bottom:none}
.wrow:hover{background:var(--panel2)}
.wrow.mine{background:var(--accentdim)}
.wtime{color:var(--dim2);font-size:var(--t-xs);white-space:nowrap}
.wtags{display:flex;gap:3px;flex-wrap:wrap}
.wtag{font-size:var(--t-xxs);letter-spacing:.06em;text-transform:uppercase;
  padding:1px 5px;border-radius:3px;border:1px solid var(--line2);
  color:var(--dim);white-space:nowrap}
.wtag.t-transfer{border-color:var(--posline);color:var(--pos)}
.wtag.t-rumour{border-color:var(--warnline);color:var(--warn)}
.wtag.t-injury{border-color:var(--negline);color:var(--neg)}
.wtag.t-press{border-color:var(--accentline);color:var(--accent)}
.wbody{line-height:1.5;min-width:0}
.wbody a{text-decoration:none}
.wbody a:hover{text-decoration:underline}
.wsum{display:block;color:var(--dim2);font-size:var(--t-xs);margin-top:2px;
  line-height:1.45}
.wents{display:flex;gap:6px;flex-wrap:wrap;margin-top:4px}
.went{font-size:var(--t-xs);border:1px solid var(--line2);border-radius:3px;
  padding:1px 6px;cursor:pointer;white-space:nowrap}
.went i{font-style:normal;color:var(--dim2);margin-left:5px;font-size:var(--t-xxs)}
.went.mine{border-color:var(--accentline);color:var(--accent)}
.went.free{border-color:var(--posline);color:var(--pos)}
.wsrc{font-size:var(--t-xs);text-align:right;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
@media(max-width:900px){
  .wrow{grid-template-columns:1fr;gap:4px}
  .wsrc{text-align:left}
}

/* The unread bar. Above everything, because meeting it is the point. */
.inbox{border:1px solid var(--accentline);background:var(--accentdim);
  border-radius:var(--r);padding:11px 13px;margin-bottom:18px}
.inboxhead{display:flex;align-items:center;gap:9px;font-size:var(--t-s);
  margin-bottom:8px}
.inboxn{background:var(--accent);color:var(--onfill);border-radius:10px;
  padding:1px 8px;font-size:var(--t-xs);font-weight:700;font-variant-numeric:tabular-nums}
.inboxrow{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  padding:7px 0;border-top:1px solid var(--line2);font-size:var(--t-s)}
.inboxrow .nn{font-weight:600;cursor:pointer}
.inboxtext{flex:1;min-width:220px;color:var(--prose);line-height:1.5}
/* Returns tab: one block per way of scoring, each with its own run of matches. */
.rblock{margin-bottom:22px}
.rblock h4{font-size:var(--t-xs);letter-spacing:.13em;text-transform:uppercase;
  color:var(--dim2);margin-bottom:9px;display:flex;align-items:center;gap:7px}
/* Matrix headers were rotated 90 degrees with a projection tucked under each
   name -- two things fighting for the same 40 pixels, and neither readable.
   Upright, one line, no second number: every cell below is already the
   difference that player makes, so repeating his score explained nothing. */
table th.mxh{padding:6px 3px;vertical-align:bottom;font-weight:500;
  font-size:var(--t-xxs);letter-spacing:0;text-transform:none;color:var(--dim);
  white-space:nowrap;text-align:center;min-width:52px;max-width:66px}
table th.mxh span{display:block;overflow:hidden;text-overflow:ellipsis}
td.mxadd{white-space:nowrap;position:sticky;left:0;background:var(--bg);z-index:1}

/* A banner above the column headers, grouping a statistic's total and its
   home/away split under one season. */
tr.grprow th.grp{font-size:var(--t-xxs);letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim2);text-align:center;padding:5px 6px 3px;
  border-bottom:1px solid var(--line2);font-weight:600;white-space:nowrap}
tr.grprow th.grp.blank{border-bottom:none}
tr.grprow th.grp:not(.blank){background:var(--panel2)}

/* Yellow cards: the number carries the warning, so the cell stays one
   character wide. "4 to a ban" under every row was three words of chrome in
   a column that needed none. */
.yc{position:relative;display:inline-flex;align-items:center;
  justify-content:center;min-width:24px;padding:1px 6px;border-radius:4px;
  font-variant-numeric:tabular-nums}
.yc.ycnil{background:none;color:var(--dim2)}
.yc.ycwarn{background:var(--warndim);color:var(--warn)}
.yc.ycrisk{background:var(--negdim);color:var(--neg);font-weight:600}
/* The one-away mark must not shift the digit: every number in the column
   sits in the same box whether or not it carries a warning. */
.yc i{position:absolute;right:1px;top:-3px;font-style:normal;font-weight:700;
  font-size:var(--t-micro);line-height:1}

.rlay{display:flex;gap:22px;align-items:center;flex-wrap:wrap}
.rdial{display:flex;flex-direction:column;align-items:center;gap:2px;
  font-size:var(--t-xxs);letter-spacing:.09em;text-transform:uppercase}
.dial{width:78px;height:78px}
.dial .dtrack{fill:none;stroke:var(--line2);stroke-width:6}
.dial .dfill{fill:none;stroke:var(--pos);stroke-width:6;stroke-linecap:round}
.dial .dnum{fill:var(--text);font-size:var(--t-l);font-weight:600;text-anchor:middle}
.dial .dpc{font-size:var(--t-xxs);fill:var(--dim2)}
.dial .dsub{fill:var(--dim2);font-size:var(--t-micro);text-anchor:middle}
.rbars{flex:1;min-width:240px;display:flex;flex-direction:column;gap:6px}
.sbar{display:grid;grid-template-columns:78px 1fr 46px;gap:9px;
  align-items:center;font-size:var(--t-xs)}
.sbl{color:var(--dim2)}
.sbt{height:7px;background:var(--panel2);border-radius:4px;overflow:hidden}
.sbt i{display:block;height:100%;background:var(--pos);border-radius:4px}
.sbv{text-align:right;font-variant-numeric:tabular-nums}
.sbar.empty2{grid-template-columns:78px 1fr}

.rgrid{margin-top:12px;display:flex;flex-wrap:wrap;gap:2px}
.rcell{width:15px;height:15px;border-radius:2px;background:var(--panel2);
  border:1px solid var(--line2);display:inline-block}
.rcell.on{background:var(--pos);border-color:var(--pos)}

tr.seasonstart td{border-top:1px solid var(--line2)}
tr.ctot td{border-top:2px solid var(--line2);font-weight:600;
  color:var(--dim)}
tr.liveseason td{background:var(--accentdim)}
tr.liveseason td:first-child{font-weight:600}

/* The man the matrix wants to drop just got better. Nothing is blocked --
   the number still stands -- but the app will not stay quiet about it. */
.guard{margin-top:11px;padding:9px 11px;border-radius:var(--r);
  background:var(--warndim);border:1px solid var(--warnline);font-size:var(--t-s)}
.guard b{display:block;margin:2px 0 5px;color:var(--warn)}
.guard ul{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:4px}
.guard li{line-height:1.5;color:var(--prose);padding-left:13px;position:relative}
.guard li::before{content:"\2191";position:absolute;left:0;color:var(--warn)}
.guard .dim2{display:block;margin-top:6px;font-size:var(--t-xs)}

/* Why a swap is better, decomposed. A number with no reason is a ranking,
   and a ranking is what every other tool already gives you. */
.because{list-style:none;margin:7px 0 0;padding:0;display:flex;
  flex-direction:column;gap:4px}
.because li{font-size:var(--t-xs);line-height:1.5;color:var(--dim);
  padding-left:15px;position:relative}
.because li::before{content:"+";position:absolute;left:0;color:var(--pos);
  font-weight:600}
.because li.against::before{content:"\2212";color:var(--neg)}
.because li.b-horizon::before{content:"\21C4";color:var(--warn)}
.track{margin-top:9px;padding:8px 10px;border-radius:var(--r);
  background:var(--warndim);border:1px solid var(--warnline);
  font-size:var(--t-xs);line-height:1.5;color:var(--warn)}
.track .pill{margin-right:7px}

.rivnews{display:flex;flex-direction:column}
.rivrow{padding:10px 0;border-bottom:1px solid var(--line)}
.rivrow:last-child{border-bottom:none}
.rivhead{display:flex;gap:8px;align-items:baseline;flex-wrap:wrap;
  font-size:var(--t-s)}
.rivhead .nn{font-weight:600;cursor:pointer}
.rivtext{font-size:var(--t-s);line-height:1.55;color:var(--prose);margin-top:4px}

/* A loss reads differently from a notification. */
.inboxrow.gone{background:var(--negdim);margin:0 -13px;padding-left:13px;
  padding-right:13px}
.inboxrow.gone .nn{color:var(--neg)}
.inboxsplit{margin-top:9px;padding-top:8px;border-top:1px solid var(--line2);
  font-size:var(--t-xxs);letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim2)}
#undobar{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);
  z-index:60;display:flex;gap:12px;align-items:center;font-size:var(--t-s);
  background:var(--panel);border:1px solid var(--line2);border-radius:var(--r);
  padding:10px 14px;box-shadow:0 12px 30px -14px var(--shadow)}

/* Column heading for one manager's eleven. */
.sidehead{margin-bottom:12px;padding-bottom:9px;border-bottom:1px solid var(--line)}
.sideteam{font-size:var(--t-xl);font-weight:650;letter-spacing:-.01em;line-height:1.2}
.sideteam.mine{color:var(--accent)}
.sideteam.theirs{color:var(--text)}
.sidemeta{font-size:var(--t-xs);color:var(--dim2);margin-top:3px}

/* Two things a projection cannot see: who else is queueing for this player,
   and how much of your squad already depends on one club's afternoon. */
.conc{margin-top:12px;padding:9px 11px;border-radius:var(--r);
  background:var(--warndim);border:1px solid var(--warnline);
  font-size:var(--t-s);line-height:1.55;color:var(--warn)}
.conc .pill{margin-right:8px}
.claimline{margin-top:10px;display:flex;gap:9px;align-items:baseline;
  flex-wrap:wrap;font-size:var(--t-s)}
.claimline .dim2{flex:1;min-width:200px;line-height:1.5}

/* Between-gameweek preview: the tie ahead and the wire behind it. */
.prevhead{display:flex;align-items:center;gap:26px;flex-wrap:wrap;
  margin-bottom:12px}
.prevhead>div{display:flex;flex-direction:column;gap:2px}
.prevhead .dim2{font-size:var(--t-xxs);letter-spacing:.11em;text-transform:uppercase}
.prevhead b{font-size:var(--t-m)}
.mvlist{display:flex;flex-direction:column}
.mvrow{display:grid;grid-template-columns:minmax(130px,1.1fr) minmax(120px,1fr) 1fr auto;
  gap:12px;align-items:center;padding:7px 0;border-bottom:1px solid var(--line);
  font-size:var(--t-s)}
.mvrow:last-child{border-bottom:none}
.mvrow.mine{background:var(--accentdim);margin:0 -11px;padding-left:11px;
  padding-right:11px}
.mvrow.opp{background:var(--negdim);margin:0 -11px;padding-left:11px;
  padding-right:11px}
.mvkind{font-size:var(--t-xs)}

/* Win probability: one bar, three outcomes, in the order they matter. */
.wbar{display:flex;height:9px;border-radius:5px;overflow:hidden;
  background:var(--panel2);margin-bottom:7px}
.wbar i{display:block}
.wbar i.w{background:var(--pos)} .wbar i.d{background:var(--line3)}
.wbar i.l{background:var(--neg)}
.wbarlab{display:flex;justify-content:space-between;font-size:var(--t-s);
  font-variant-numeric:tabular-nums}
.wcmp{display:flex;gap:26px;flex-wrap:wrap;margin-top:12px;padding-top:10px;
  border-top:1px solid var(--line);font-size:var(--t-s)}
.wcmp .dim2{display:block;font-size:var(--t-xxs);letter-spacing:.11em;
  text-transform:uppercase;margin-bottom:2px}
.wswap{margin-top:11px;padding-top:10px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:6px;font-size:var(--t-s)}
.wswap .pill{margin-right:7px}

/* Display settings rows. */
.setrow{display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:12px 0;border-bottom:1px solid var(--line);flex-wrap:wrap}
.setrow:last-child{border-bottom:none;padding-bottom:0}
.setrow:first-child{padding-top:0}
.setrow b{font-size:var(--t-s);font-weight:600}
.setrow .dim2{font-size:var(--t-xs);line-height:1.55;margin-top:3px;max-width:52ch;
  color:var(--dim2)}
.btn.icon{padding:5px 9px;font-size:var(--t-s);line-height:1}

/* Paging the Premier League player table. */
.plfilters{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-bottom:10px}
.pager{display:flex;align-items:center;gap:12px;margin-top:10px;
  font-size:var(--t-xs)}
.pager .btn[disabled]{opacity:.35;cursor:default}

/* ---------------------------------------------------------- fixture ticker */
table.tkt td.tk{text-align:center;font-size:var(--t-xs);padding:6px 4px;
  border-radius:3px;white-space:nowrap}
table.tkt th.tkgw{text-align:center}
.tk.easy{background:var(--tk-easy-bg);color:var(--tk-easy-fg)}
.tk.ok{background:var(--tk-ok-bg);color:var(--tk-ok-fg)}
.tk.even{background:var(--tk-even-bg);color:var(--tk-even-fg)}
.tk.hard{background:var(--tk-hard-bg);color:var(--tk-hard-fg)}
.tk.brutal{background:var(--tk-brutal-bg);color:var(--tk-brutal-fg)}
.tk.blank{background:transparent;color:var(--dim2)}
.tkha{opacity:.6;font-size:var(--t-xxs)}
.tkname{white-space:nowrap}
.tklegend{display:flex;gap:12px;flex-wrap:wrap;margin-top:8px;font-size:var(--t-xs);
  color:var(--dim)}
.tkkey{display:flex;align-items:center;gap:5px}
.tkkey i{width:13px;height:11px;border-radius:2px;display:inline-block}
table.tkt tr.mineRow td.tkname{font-weight:600}
.pending{margin:10px 0;padding:10px 12px;border-radius:var(--r);
  background:var(--warndim);border:1px solid var(--warnline);font-size:var(--t-s);
  line-height:1.6}
.pending .pill{margin:0 3px}

/* ------------------------------------------------------ press room folds */
/* The page is for reading this week's report. Everything that produces it --
   the correspondent, the notes, the editor, the archive -- is available but
   folded, so the report is what you land on. */
.rsec{border:1px solid var(--line);border-radius:var(--r);margin-top:10px;
  background:var(--panel)}
.rsec>summary{cursor:pointer;padding:10px 14px;font-size:var(--t-s);
  color:var(--dim);list-style:none}
.rsec>summary::-webkit-details-marker{display:none}
.rsec>summary::before{content:'▸ ';color:var(--dim2)}
.rsec[open]>summary::before{content:'▾ '}
.rsec>summary:hover{color:var(--text)}
.rsec[open]>summary{border-bottom:1px solid var(--line);color:var(--text)}
.rsec>*:not(summary){margin:12px 14px}
.rsechead{margin:0}
.ractions{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
/* Those blocks carry their own heading for when they stand alone. Inside a
   fold the summary already names them, so the inner heading is noise. */
.rsec h2.sec{display:none}

/* Spoken-about vs written-about. The border weight is the whole point: a
   coach's own words get the accent, a writer's paraphrase gets nothing. */
.spk{font-size:var(--t-xs);line-height:1.5;padding:7px 9px;margin-bottom:8px;
  border-radius:4px;border:1px solid var(--line)}
.spk b{letter-spacing:.04em;text-transform:uppercase;font-size:var(--t-xxs)}
.spk-coach{border-left:3px solid var(--pos);background:var(--panel2)}
.spk-named{border-left:3px solid var(--accent);background:var(--panel2)}
.spk-quoted{border-left:3px solid var(--line);background:var(--panel2)}
.spk-none{color:var(--dim2);border-style:dashed}
.spkq{margin-top:5px;font-style:italic;color:var(--text);font-size:var(--t-s)}

/* Warm start: the last known dashboard, labelled as such. Deliberately loud
   -- the failure this guards against is a manager acting on an hour-old
   picture believing it is live. */
.warmbar{display:flex;align-items:center;gap:8px;font-size:var(--t-s);
  padding:8px 14px;background:var(--warndim);color:var(--text);
  border-bottom:1px solid var(--warnline)}
/* An author `display` beats the hidden attribute's UA rule, so hidden has to
   be restated here or the element renders as an empty bordered box. */
.warmbar[hidden]{display:none!important}
.warmbar b{letter-spacing:.03em;text-transform:uppercase;font-size:var(--t-xxs)}
.spin.sm{width:11px;height:11px;border-width:2px;flex:0 0 auto}

/* The quiet state. Deliberately calm rather than invisible: it is a verdict,
   and a verdict that looks like an error message is not reassuring. */
.inbox.quiet{border-left:3px solid var(--pos)}
.inbox.quiet.stands{border-left-color:var(--warnline)}
.quietmark{display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;border-radius:50%;font-size:var(--t-xs);font-weight:700;
  background:var(--posdim);color:var(--pos);flex:0 0 auto}
.inbox.quiet.stands .quietmark{background:var(--warndim);color:var(--warn)}
.quietbody{font-size:var(--t-s);line-height:1.55;padding:6px 12px 10px}

/* The verdict on the eleven he saved. A clean bill of health is stated as
   plainly as a problem: silence would read as "not checked". */
.xiverdict{font-size:var(--t-s);line-height:1.55;padding:9px 11px;margin-bottom:12px;
  border:1px solid var(--line);border-radius:4px;background:var(--panel)}
.xiverdict.ok{border-left:3px solid var(--pos);color:var(--dim)}
.xiverdict.bad{border-left:3px solid var(--neg)}
.xiprob{margin-top:6px;display:flex;gap:7px;align-items:baseline}

/* Which market you are in. The border does the work: a queue is calm, a race
   is not, and an urgent queue is somewhere between. */
.wclock{border:1px solid var(--line);border-radius:4px;margin-bottom:14px;
  background:var(--panel)}
.wclock.queue{border-left:3px solid var(--accent)}
.wclock.race{border-left:3px solid var(--warn)}
.wclock.urgent{border-left-color:var(--neg)}
.wchead{display:flex;align-items:center;gap:8px;padding:8px 11px;
  border-bottom:1px solid var(--line);font-size:var(--t-s)}
.wcbody{font-size:var(--t-s);line-height:1.55;padding:8px 11px;color:var(--dim)}

/* Answers about named players. A refusal is rendered as prominently as an
   answer: "we do not model that" is the product working. */
.asknamed{margin-top:10px}
.askp{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:8px 10px;
  border:1px solid var(--line);border-radius:4px;margin-bottom:7px;
  background:var(--panel);font-size:var(--t-s)}
.askp-n{font-weight:600}
.askp-o{font-size:var(--t-xs);color:var(--dim2)}
.askp-o.mine{color:var(--accent)}
.askp-o.free{color:var(--pos)}
.askp-v{font-family:var(--mono);font-size:var(--t-s)}
.askgain{width:100%;margin:8px 0}
.askverdict{font-size:var(--t-s);font-weight:600;padding:9px 11px;border-radius:4px;
  margin:8px 0;border:1px solid var(--line)}
.askverdict.yes{border-left:3px solid var(--pos);background:var(--posdim)}
.askverdict.no{border-left:3px solid var(--neg);background:var(--negdim)}

/* The count beside the rate. Quiet enough not to compete with the percentage,
   present enough that nobody reads a rate without its sample. */
.sbv .sbn{display:inline-block;margin-left:6px;font-size:var(--t-xxs);
  color:var(--dim2);font-variant-numeric:tabular-nums}

/* A labelled select that sits on the filter row like the chips it replaced. */
.fsel{display:inline-flex;align-items:center;gap:7px}
.fsell{font-size:var(--t-xs);text-transform:uppercase;letter-spacing:.05em;
  color:var(--dim2)}
.fsel select{background:var(--panel);color:var(--text);
  border:1px solid var(--line);border-radius:var(--r);
  padding:5px 26px 5px 9px;font:inherit;font-size:var(--t-s);cursor:pointer;
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--dim) 50%),
    linear-gradient(135deg,var(--dim) 50%,transparent 50%);
  background-position:calc(100% - 14px) 52%,calc(100% - 9px) 52%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat}
.fsel select:focus{outline:none;border-color:var(--accent)}
.chipx{background:none;border:1px solid var(--line);color:var(--dim);
  border-radius:var(--r);padding:5px 9px;font-size:var(--t-xs);cursor:pointer}
.chipx:hover{color:var(--text);border-color:var(--dim)}

/* The Scout reads as a column of prose, not as a panel of data. */
.scout{max-width:64ch;margin-top:6px}
.scbyline{font-size:var(--t-xs);color:var(--dim2);margin-bottom:14px;
  padding-bottom:10px;border-bottom:1px solid var(--line)}
.scp{font-size:var(--t-m);line-height:1.75;margin:0 0 15px;color:var(--text)}
.scp[data-kind="close"]{color:var(--dim);font-size:var(--t-s);
  border-top:1px solid var(--line);padding-top:13px}

/* The team sheet carries a line of a player's own history against this
   fixture. Quiet by default -- it is context, not a projection -- and it must
   never compete with the number it sits under. */
.muprow{padding:4px 0;border-bottom:1px solid var(--line);cursor:pointer}
.muptop{display:flex;justify-content:space-between;align-items:baseline}
.muphist{display:flex;flex-direction:column;gap:2px;margin:3px 0 2px}
.hline{font-size:var(--t-xs);line-height:1.45;color:var(--dim2);
  padding-left:8px;border-left:2px solid var(--line2)}
.hline.h-opp{color:var(--dim);border-left-color:var(--accentline)}
.hline.h-split{color:var(--dim);border-left-color:var(--posline)}

/* The next opponent, found without hunting. The table sorts by points per 90,
   so this row can be anywhere in nineteen. */
tr.nextopp{background:var(--accentdim)}
tr.nextopp td{border-top:1px solid var(--accentline);
  border-bottom:1px solid var(--accentline)}
tr.nextopp td:first-child{color:var(--accent);font-weight:600}
.nextmark{display:inline-block;margin-left:7px;padding:1px 6px;border-radius:3px;
  background:var(--accent);color:var(--onfill);font-size:var(--t-xxs);font-weight:700;
  letter-spacing:.07em;text-transform:uppercase;vertical-align:1px}

/* The fixture calendar, present only when the calendar has something on it. */
.dgw{margin-bottom:14px}
.dgwrow{padding:8px 0;border-bottom:1px solid var(--line)}
.dgwrow:last-of-type{border-bottom:none}
.dgwhead{display:flex;align-items:center;gap:8px;font-size:var(--t-s);
  margin-bottom:4px}
.dgwl{display:flex;gap:9px;font-size:var(--t-xs);line-height:1.55;
  padding:1px 0;color:var(--dim)}
.dgwk{flex:0 0 62px;color:var(--dim2);text-transform:uppercase;
  letter-spacing:.05em;font-size:var(--t-xxs);padding-top:2px}
.hline.h-cs{color:var(--dim);border-left-color:var(--posline)}
.hline.h-dc{color:var(--dim);border-left-color:var(--warnline)}
/* The window every count above it was drawn from. A count with no window
   reads as a career total. */
.hwin{font-size:var(--t-xxs);color:var(--dim2);opacity:.75;padding-left:8px;
  letter-spacing:.03em}

/* Names picked out of the prose: yours in the accent, everyone else bold. */
.pn{font-weight:600;color:var(--text);cursor:pointer}
.pn:hover{text-decoration:underline}
.pn.mine{color:var(--accent)}
/* A club whose text is not what we read last time. */
.presscard.changed{border-left:2px solid var(--pos)}
.pressbar{display:flex;gap:14px;align-items:flex-start;justify-content:space-between;
  font-size:var(--t-xs);line-height:1.6;margin-bottom:10px}
.pressbar .btn{flex:0 0 auto;white-space:nowrap}

/* The source is older than the gameweek it is being read for. Loud, because
   the failure it prevents is acting on a fortnight-old injury list. */
.stalesrc{background:var(--negdim);border:1px solid var(--negline);
  border-radius:var(--r);padding:11px 14px;margin-bottom:12px;
  font-size:var(--t-s);line-height:1.6;color:var(--text)}
.stalesrc b{display:block;margin-bottom:2px}

/* Dated team news: the half of this page that carries a timestamp. */
.dated{border:1px solid var(--line);border-radius:var(--r);
  background:var(--panel);padding:13px 15px;margin-bottom:14px}
.dated.empty2{background:none;border-style:dashed}
.dtrow{display:grid;grid-template-columns:70px 1fr auto;gap:12px;
  align-items:baseline;padding:7px 0;border-bottom:1px solid var(--line2);
  text-decoration:none;color:inherit}
.dtrow:last-of-type{border-bottom:none}
.dtrow:hover .dthead{text-decoration:underline}
.dtrow.mine{border-left:2px solid var(--accent);padding-left:9px;
  margin-left:-11px}
.dtwhen{font-size:var(--t-xs);color:var(--dim2);white-space:nowrap}
.dthead{font-size:var(--t-s);line-height:1.45;color:var(--text)}
.dtpl{display:block;font-size:var(--t-xs);color:var(--dim2);margin-top:2px}
.dtpl .mine{color:var(--accent);font-weight:600}
.dtsrc{font-size:var(--t-xs);white-space:nowrap}

/* The pool's pager. Same shape as the stats table's, so the two read as one
   pattern rather than two decisions. */
.pager{display:flex;gap:10px;align-items:center;justify-content:center;
  padding:14px 0 2px;font-size:var(--t-s);flex-wrap:wrap}


/* Sub-items are inserted into the same list as the top-level ones, so opening
   a section pushes everything below it down by two or three rows -- the item
   a hand was reaching for moves out from under it. The insertion is animated
   so the movement is legible as movement rather than reading as a different
   menu appearing. */
@media (prefers-reduced-motion: no-preference){
  .nav button.sub{animation:subin .16s ease-out both}
}
@keyframes subin{
  from{opacity:0;transform:translateY(-4px)}
  to{opacity:1;transform:none}
}

/* ------------------------------------------------------------ phone layout
   Measured at 375x812 before any of this existed:

     the sidebar became a 375px row and the three things in it took
     112px (brand) + 187px (the Ask box) + 75px (every one of eleven nav
     buttons, scrolling 1265px of content through that slot)

   Nothing was broken in a way that threw an error. The nav simply scrolled,
   so a swipe reached everything -- but ZERO buttons were visible at rest,
   including Team HQ, so the app opened with no navigation on screen at all
   and no indication there was any.

   The Ask box was the thing starving it: it kept its desktop width because
   nothing told it otherwise. On a phone it drops to its own row, which is
   also where it belongs -- typing a question is a deliberate act, and it was
   competing for space with the way out of the page.

   Tap targets and type were the other half. 25 of 46 controls were under
   32px tall and the commonest rendered size in the content was 11px, which
   is a desktop density on a device held at arm's length. */
@media(max-width:900px){
  .side{flex-wrap:wrap;row-gap:0}
  .brand{flex:0 0 auto}
  /* Its own line, full width, after the brand and the nav. */
  .asksearch{order:3;flex:1 0 100%;padding:0 12px 10px}
  .asksearch input{font-size:var(--t-l)}   /* 16px stops iOS zooming the page on focus */
  .qres{left:12px;right:12px}
  /* Everything the brand does not use. */
  .nav{order:2;flex:1 1 auto;min-width:0;padding:6px 8px;gap:4px;
    scrollbar-width:none}
  .nav::-webkit-scrollbar{display:none}
  .nav button{padding:9px 12px;font-size:var(--t-s);min-height:38px}
  .nav button.sub{min-height:34px;font-size:var(--t-s)}
  /* A control you tap with a thumb, not point at with a cursor. */
  .content .btn, .content button, .content select{min-height:36px}
  .pager .btn{min-height:38px;padding:0 14px}
}

/* The sub-items of the open section, in their own element directly under the
   button they belong to. On a desktop that is exactly the nesting the sidebar
   always had. */
.navsub{display:flex;flex-direction:column}

@media(max-width:900px){
  /* Wrap rather than scroll.
     Eleven destinations at ~76px each need 840px and the strip is 358px, so a
     single row hides seven of them behind a swipe nobody is told about. Three
     wrapped lines cost about 120px of an 812px screen and hide nothing --
     which is the better trade for a nav you use once and then ignore. */
  .nav{flex-direction:row;flex-wrap:wrap;overflow:visible;
       padding:5px 8px 7px;gap:4px;align-content:flex-start}
  /* Tighter than the desktop list. A wrapped nav costs vertical space on the
     device with least of it, so the buttons carry only their label -- the
     count badges belong to a sidebar you are looking at, not to a row you
     are scrolling past. */
  .nav > button{order:1;flex:0 0 auto;width:auto;white-space:nowrap;
    padding:8px 10px;font-size:var(--t-s);min-height:36px}
  .nav > button .tag{display:none}
  /* Its own line, after every top-level button, whatever the wrap does. */
  .navsub{order:2;flex:1 0 100%;flex-direction:row;flex-wrap:wrap;gap:4px;
          margin-top:2px;padding-top:5px;border-top:1px solid var(--line2)}
  .navsub button{flex:0 0 auto;width:auto;font-size:var(--t-s);white-space:nowrap}
}

/* A figure that has more behind it. The dotted underline is the only signal
   that hovering is worth doing -- without it nobody discovers the split. */
.vsp{border-bottom:1px dotted var(--line3);cursor:help}
.vsp:hover{border-bottom-color:var(--accent);color:var(--accent)}

/* His name in the article's own words, always visible.
   A fixed height is the point: the quotes arrive one request at a time, and
   a list that grows under the reader as each lands is worse than one that
   holds its shape and fills. Two sentences, clamped, then the link. */
.artfold{margin:8px 0 2px;padding:10px 12px;border-radius:var(--r);
  background:var(--panel2);border:1px solid var(--line2);
  display:flex;flex-direction:column;gap:6px;
  min-height:96px;justify-content:flex-start}
.artq{margin:0;font-size:var(--t-s);line-height:1.55;color:var(--text);
  padding-left:9px;border-left:2px solid var(--accentline);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}
.artq.quiet{color:var(--dim2);border-left-color:var(--line2)}
.artwait{font-size:var(--t-xs);font-style:italic;opacity:.6}
.artmore{font-size:var(--t-xxs)}
.artlink{font-size:var(--t-xs);color:var(--accent);text-decoration:none;
  margin-top:auto}
.artlink:hover{text-decoration:underline}

/* The home/away pair under a per-opponent number. Small and quiet: the total
   is the figure, the split is the detail that explains it. Both are on
   screen because a record against a club is really two records, and which
   one applies is decided by where this week's fixture is played. */
.hasub{display:block;font-size:var(--t-xxs);line-height:1.25;margin-top:1px;
  opacity:.55;font-variant-numeric:tabular-nums;letter-spacing:.02em}

/* A club he has never faced. Present, so its absence cannot be misread as an
   oversight; quiet, so it never competes with a real record. */
tr.nevermet td{opacity:.62}
tr.nevermet.nextopp td{opacity:.85}

/* ---- Compare: two players, one axis ---------------------------------- */
.cmpchart{width:100%;height:auto;display:block;margin:4px 0 2px}
.cmpchart .cgrid{stroke:var(--line);stroke-width:1;opacity:.5}
.cmpchart .cnow{stroke:var(--line);stroke-width:1;stroke-dasharray:3 3;opacity:.9}
.cmpchart .cax{fill:var(--dim2);font-size:var(--t-xxs);font-family:var(--mono)}
.cmphead{display:flex;gap:20px;flex-wrap:wrap;font-size:var(--t-s);margin-bottom:2px}
.cdot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px}
.cmpcols{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media (max-width:640px){.cmpcols{grid-template-columns:1fr}}
.cmpfix{display:flex;flex-direction:column;gap:4px;margin-top:6px}
.cfx{display:grid;grid-template-columns:44px 1fr auto auto;gap:8px;align-items:baseline;
  padding:5px 8px;border:1px solid var(--line);border-radius:6px;font-size:var(--t-s)}
.cfx.blank{opacity:.55}
.cfe{font-family:var(--mono);font-size:var(--t-xs);color:var(--dim2)}
.cfp{font-variant-numeric:tabular-nums;font-weight:600}
.cfw{font-size:var(--t-xxs)}

/* ---- Points, coloured by what they were worth ------------------------
   A points column read as an index once -- GW sat where PTS belonged and
   "3, 2, 1" looked like a scoreline. Colour makes the column unmistakable
   at a glance and never carries meaning on its own: the number is still
   the number, and every band is legible in both themes. */
.pts{font-variant-numeric:tabular-nums;font-weight:600;
  padding:1px 6px;border-radius:5px;display:inline-block;min-width:20px}
.pts.p0{color:var(--dim2);font-weight:500}                 /* blank */
.pts.p1{color:var(--text)}                                  /* 1-2: showed up */
.pts.p2{color:var(--heat-fg);background:var(--heat-bg)}     /* 3-5: a return */
.pts.p3{color:var(--heat-fg);background:var(--pts-mid-bg)}  /* 6-9: a good one */
.pts.p4{color:var(--pts-hi-fg);background:var(--pts-hi-bg);font-weight:700}
/* A season total has no match-sized band to sit in, so it gets weight only. */
.pts.pseason{font-weight:700;color:var(--text);background:none;padding-left:0;padding-right:0}

/* Connect-your-team: a numbered two-step, because the id lives in another
   app and the browser will not let us fetch it for you. One click out, one
   paste back. */
.connectrow{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin:6px 0 0}
.setup textarea, .panel textarea{width:100%;background:var(--panel2);
  border:1px solid var(--line2);border-radius:var(--r);padding:10px 12px;
  margin:6px 0 10px;outline:none;color:var(--text);font-family:var(--mono);
  font-size:var(--t-xs);resize:vertical}
.connectsteps{margin:8px 0 10px;padding-left:20px;font-size:var(--t-s);color:var(--dim)}
.connectsteps li{margin:4px 0;line-height:1.5}
.connectsteps b{color:var(--text)}

/* ---- Player overview: the season on one screen ----------------------- */
.ovtop{display:flex;gap:16px;align-items:flex-start;margin-bottom:14px;flex-wrap:wrap}
.ovphoto{width:76px;height:96px;object-fit:cover;object-position:top;
  border-radius:var(--r);background:var(--panel2);flex:0 0 auto}
.ovfacts{display:grid;grid-template-columns:repeat(auto-fit,minmax(94px,1fr));
  gap:8px;flex:1 1 380px}
.ovgrid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:10px;margin-bottom:8px}
.ovcard{border:1px solid var(--line);border-radius:var(--r);padding:9px 10px 4px;
  background:var(--panel)}
.ovhead{display:flex;justify-content:space-between;align-items:baseline;
  font-size:var(--t-xs);color:var(--dim);margin-bottom:4px;gap:8px}
.ovleg{font-size:var(--t-xxs);color:var(--dim2);white-space:nowrap}
.ovk{display:inline-block;width:7px;height:7px;border-radius:2px;
  background:var(--c);margin:0 3px 0 6px}
.ovdash{display:inline-block;width:12px;border-top:1.5px dashed var(--dim2);
  margin:0 3px 0 6px;vertical-align:middle}
.ovchart{width:100%;height:104px;display:block}
.ovchart .ovgrid{stroke:var(--line);stroke-width:1;opacity:.55}
.ovchart .ovthr{stroke:var(--dim2);stroke-width:1;stroke-dasharray:3 3}
.ovchart .ovax{fill:var(--dim2);font-size:var(--t-micro);font-family:var(--mono)}

/* ---- Game switch: two games, one engine ------------------------------- */
.modesw{display:inline-flex;border:1px solid var(--line2);border-radius:999px;
  overflow:hidden;margin-right:10px;flex:0 0 auto}
.modebtn{background:none;border:0;color:var(--dim);font:inherit;font-size:var(--t-s);
  padding:5px 14px;cursor:pointer;letter-spacing:.02em}
.modebtn.on{background:var(--acc);color:var(--bg);font-weight:600}
.modebtn:not(.on):hover{color:var(--text)}

/* The watch toggle on a watch card. Top-right of the card, out of the way of
   the name, and legible in both themes without a second colour token. */
.watchcard{position:relative}
/* The card header has to leave room for it, or the toggle lands on top of
   the ownership pill. */
.watchcard .wh{padding-right:92px}
.wwatch{position:absolute;top:8px;right:8px;z-index:2;
  font-size:var(--t-xxs);letter-spacing:.04em;padding:3px 8px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel);color:var(--dim);
  cursor:pointer}
.wwatch:hover{color:var(--text);border-color:var(--line2)}
.wwatch.on{color:var(--pos);border-color:var(--posline)}

/* Rumour tag on the wire. Deliberately the dimmest tag in the set: it is the
   only content in the app that no engine reads. */
.wtag.t-rumour{color:var(--dim);border-color:var(--line2)}

/* Add-to-watchlist, inline beside a player's name. Small enough to sit in a
   dense table without pushing the name around, big enough to hit. */
.addw{width:18px;height:18px;line-height:1;margin-right:6px;padding:0;
  border-radius:5px;border:1px solid var(--line);background:transparent;
  color:var(--dim2);font-size:var(--t-s);cursor:pointer;vertical-align:middle}
.addw:hover{color:var(--text);border-color:var(--line2)}
.addw.on{color:var(--pos);border-color:var(--posline)}

/* Names read straight off a rumour, including players outside the league.
   Italic and unstyled as data on purpose: the app has not identified them. */
.wment{display:block;margin-top:3px;font-size:var(--t-xs);color:var(--dim2)}
.wment i{font-style:italic;color:var(--dim)}

/* ============================================================ 640px: a phone
   Everything above this point treats a narrow window as a desktop with less
   room. Below it, the machine is a different one: a thumb, one column, and a
   screen where vertical space is the scarcest thing there is.

   THE PROBLEM THIS SOLVES
   Measured at 375x812, the chrome above the first line of content came to
   328px -- forty per cent of the screen, on every page, before a single
   number. Eleven wrapped navigation buttons were 123px of that.

   WHY A SHEET AND NOT A SCROLLING STRIP
   The rule this replaces argued against a single scrolling row, and it was
   right: eleven destinations need 840px, the strip is 358px, and seven of
   them end up behind a sideways swipe nobody is told about. That argument is
   against HIDING things silently. It is not an argument for spending a third
   of a phone screen on a menu you use once and then ignore.

   A labelled button is the third option. Nothing is hidden behind a gesture:
   the button says where you are and opens the full list, all eleven at once,
   at a size a thumb can hit. What stays on screen is the row that changes as
   you work -- the current section's own sub-pages. */
@media(max-width:640px){
  .navtoggle{display:flex;align-items:center;gap:9px;width:100%;
    background:none;border:0;color:var(--text);font:inherit;font-size:var(--t-s);
    padding:0;cursor:pointer;min-height:34px;text-align:left}
  .brand{padding:8px 12px;border-right:none;flex:1 1 auto;min-width:0}
  .brand h1,.brand .sub{display:none}
  .navtoggle .bars{position:relative;flex:none;width:16px;height:2px;
    background:var(--dim);border-radius:2px;transition:background .12s}
  .navtoggle .bars::before,.navtoggle .bars::after{content:'';position:absolute;
    left:0;width:16px;height:2px;background:var(--dim);border-radius:2px;
    transition:transform .16s}
  .navtoggle .bars::before{top:-5px}
  .navtoggle .bars::after{top:5px}
  .navtoggle .navwhere{font-weight:600;letter-spacing:-.01em;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .navtoggle:hover .bars,.navtoggle:hover .bars::before,
  .navtoggle:hover .bars::after{background:var(--accent)}

  /* Closed: the eleven are gone and only the sub-row remains. It scrolls
     sideways, and that is allowed here where the wrapped nav was not --
     these are the pages OF the section named right above them, so a reader
     already knows what kind of thing is off the edge. */
  .side{flex-wrap:wrap;row-gap:0;align-items:stretch;
    border-bottom:1px solid var(--line)}
  .nav{order:2;flex:1 0 100%;padding:0;overflow:visible}
  .nav > button{display:none}
  .asksearch{display:none}
  .navsub{flex-direction:row;gap:2px;overflow-x:auto;overflow-y:hidden;
    padding:0 8px 7px;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .navsub::-webkit-scrollbar{display:none}
  .nav button.sub{width:auto;flex:0 0 auto;white-space:nowrap;padding:7px 11px;
    padding-left:11px;font-size:var(--t-s);min-height:32px}
  .nav button.sub::before{display:none}

  /* Open: the full list, over the page, reachable with one thumb. */
  :root[data-navopen] .navtoggle .bars{background:transparent}
  :root[data-navopen] .navtoggle .bars::before{transform:translateY(5px) rotate(45deg)}
  :root[data-navopen] .navtoggle .bars::after{transform:translateY(-5px) rotate(-45deg)}
  :root[data-navopen] .nav{position:fixed;left:0;right:0;
    top:var(--navtop,52px);bottom:0;z-index:60;background:var(--bg);
    border-top:1px solid var(--line);overflow:auto;
    padding:8px 10px calc(18px + env(safe-area-inset-bottom));
    display:flex;flex-direction:column;gap:2px}
  :root[data-navopen] .nav > button{display:flex;width:100%;
    padding:11px 12px;font-size:var(--t-m);min-height:44px;border-radius:var(--r)}
  :root[data-navopen] .nav > button .tag{display:inline-flex}
  /* The sub-row belongs to the bar, not to the list of places to go. */
  :root[data-navopen] .navsub{display:none}
  /* The search is the one thing worth carrying into the sheet: it is how you
     reach a player without knowing which page he is on. It is pinned rather
     than ordered into place because it is a sibling of .nav, and .nav has
     left the flow -- so the sheet is two fixed layers, the box and the list
     under it, rather than one box trying to sit inside the other. */
  :root[data-navopen] .asksearch{display:block;position:fixed;z-index:61;
    left:0;right:0;top:var(--navtop,50px);background:var(--bg);
    padding:9px 10px 8px}
  /* 16px exactly: anything smaller and iOS zooms the whole page on focus. */
  :root[data-navopen] .asksearch input{font-size:var(--t-l);min-height:40px}
  :root[data-navopen] .nav{top:calc(var(--navtop,50px) + var(--navsearch-h,57px))}
  :root[data-navopen] .qres{left:10px;right:10px}
  :root[data-navopen] body{overflow:hidden}
}

/* The topbar, on a phone.
   It wraps to two rows at 375px and costs another 115px on top of the nav.
   Half of what it carries is already on the page underneath: the team name
   is the first thing the content says, in larger type, and "FPL 7m ago" is a
   freshness reading that has its own page. What is genuinely only here is
   which game you are in, when the deadline is, and Refresh -- so that is
   what stays, on one row. */
@media(max-width:640px){
  .topbar{gap:8px;padding:7px 12px;flex-wrap:nowrap;overflow:hidden}
  .topbar .gw{font-size:var(--t-xs);letter-spacing:.06em}
  .topbar > .count{display:none}
  .topbar .spacer{min-width:0}
  /* The team name is the content's own headline one line further down.
     Hidden by its own class: an earlier attempt used .gw:last-of-type, and
     :last-of-type counts ELEMENTS, not classes -- every item here is a span,
     so it matched none of them and the name stayed. */
  .topbar .teamname{display:none}
  .modesw{flex:none}
  .dl{padding:3px 7px;font-size:var(--t-xs);white-space:nowrap}
  .btn{padding:6px 10px}
}

/* A wide table, read as cards. See labelTableCells() in lib/render.js for
   where data-label comes from and why the transform lives in one place.
   Only tables that opted in are touched: data-cards="no" is a table narrow
   enough to still line up, or a heat grid whose columns ARE its meaning. */
@media(max-width:640px){
  table[data-cards="yes"],
  table[data-cards="yes"] tbody{display:block;width:100%}
  table[data-cards="yes"] thead{display:none}
  /* Two pairs to a line, not one. The player pool carries twenty-five
     columns, and one pair per line makes a single player taller than the
     screen he is being compared on -- which is the horizontal scroll problem
     again, turned on its side. Nothing is dropped to achieve it: a column
     hidden on a phone is a number the reader cannot know is missing, and
     this app does not do that. */
  table[data-cards="yes"] tbody tr{display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));column-gap:14px;
    background:var(--panel);
    border:1px solid var(--line);border-radius:var(--r);
    padding:9px 11px 7px;margin-bottom:7px}
  table[data-cards="yes"] tbody tr:hover{background:var(--panel2)}
  table[data-cards="yes"] tbody td{display:flex;gap:12px;align-items:baseline;
    justify-content:space-between;text-align:right;
    padding:3px 0;border:0;white-space:normal}
  table[data-cards="yes"] tbody td::before{content:attr(data-label);
    flex:0 1 auto;text-align:left;color:var(--dim2);font-size:var(--t-xxs);
    letter-spacing:.05em;text-transform:uppercase;white-space:nowrap}
  /* The first column names the thing the card is about, so it is the card's
     heading rather than another pair. */
  table[data-cards="yes"] tbody td:first-child{grid-column:1/-1;
    display:block;text-align:left;
    font-size:var(--t-m);padding:0 0 6px;margin-bottom:5px;
    border-bottom:1px solid var(--line)}
  table[data-cards="yes"] tbody td:first-child::before{display:none}
  /* A cell spanning the row is a note or an empty state: full width, no
     label, because it belongs to no single column. */
  table[data-cards="yes"] tbody td[colspan]{grid-column:1/-1;
    display:block;text-align:left}
  table[data-cards="yes"] tbody td[colspan]::before{display:none}
  /* The scroll container has nothing left to scroll. */
  .tablewrap:has(table[data-cards="yes"]){overflow-x:visible;max-height:none}
}

/* Button strips, on a phone.
   `.seg` clips what does not fit -- overflow:hidden with no scroll -- so the
   lens strip read "Projection | Form | DefCon | Goals | Assists | C" and the
   sixth option was gone with nothing to say it existed. Same mistake as the
   navigation, in a smaller box: wrap instead, and every option is on screen. */
@media(max-width:640px){
  .seg{flex-wrap:wrap;overflow:visible;border-radius:var(--r)}
  .seg button,.seg .segbtn{border-bottom:1px solid var(--line2)}
  .seg button:last-child,.seg .segbtn:last-child{border-right:none}
  .filters{gap:8px}
  .filters select{max-width:100%}
}

/* ------------------------------------------------------------- signing in
   A whole screen rather than a panel inside the app, because there is
   nothing behind it to look at yet. Sized and centred for a phone first:
   this is the one screen a new tester sees before anything else, and it
   arrives from a link in a mail client. */
.signin{position:fixed;inset:0;z-index:100;display:flex;
  align-items:center;justify-content:center;padding:24px;
  background:var(--bg);overflow:auto}
.signinbox{width:100%;max-width:380px}
.signinbox h1{font-size:var(--t-2xl);font-weight:650;letter-spacing:-.02em;
  margin-bottom:8px}
.signinbox p{font-size:var(--t-s);line-height:1.55;margin-bottom:18px}
.signinbox form{display:flex;flex-direction:column;gap:9px}
.signinbox input{width:100%;padding:11px 12px;font:inherit;
  /* 16px exactly: below it iOS zooms the page the moment this is focused,
     and this is the first thing anybody ever taps here. */
  font-size:var(--t-l);
  background:var(--panel2);color:var(--text);
  border:1px solid var(--line2);border-radius:var(--r);outline:none}
.signinbox input:focus{border-color:var(--accent)}
.signinbox button{min-height:42px;font-size:var(--t-m)}
.signinsaid{margin-top:14px;padding:10px 12px;border-radius:var(--r);
  font-size:var(--t-s);line-height:1.5;border:1px solid var(--line2);
  background:var(--panel);word-break:break-word}
.signinsaid.good{border-color:var(--posline);background:var(--posdim);
  color:var(--pos)}
.signinsaid.bad{border-color:var(--negline);background:var(--negdim);
  color:var(--neg)}
.signinsaid.warn{border-color:var(--warnline);background:var(--warndim);
  color:var(--warn)}
.signinsaid a{color:inherit;word-break:break-all}
.signinnote{margin-top:16px;font-size:var(--t-xs);line-height:1.5}

/* --------------------------------------------------- chip timing (classic)
   One row per chip: the verdict, why, and the week-by-week gain it came
   from. The weeks are shown rather than only the winner because the whole
   point of the answer is often that the winner is barely ahead. */
.chiprow{padding:12px 0;border-bottom:1px solid var(--line)}
.chiprow:last-of-type{border-bottom:none}
.chiphead{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.chiphead b{font-size:var(--t-m)}
.chipwhy{font-size:var(--t-s);color:var(--prose);line-height:1.5;
  margin-top:5px;max-width:62ch}
.chipweeks{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}
.chipwk{flex:0 0 auto;min-width:74px;padding:6px 9px;border-radius:var(--r);
  border:1px solid var(--line);background:var(--panel2);text-align:center}
/* The best week in view. Bordered rather than filled: it is frequently
   ahead by a rounding error, and a solid highlight would shout that. */
.chipwk.best{border-color:var(--accentline);background:var(--accentdim)}
.chipwk .k{font-size:var(--t-xxs);color:var(--dim2);letter-spacing:.04em;
  text-transform:uppercase;white-space:nowrap}
.chipwk .v{font-family:var(--mono);font-size:var(--t-m);margin-top:2px}
.chipwk .s{font-size:var(--t-xxs);color:var(--dim2);margin-top:1px}
.chipwk .s.pos{color:var(--pos)}
.chipwk .s.neg{color:var(--neg)}
.chipcav{font-size:var(--t-xs);color:var(--dim2);line-height:1.5;
  margin-top:7px;max-width:62ch}
/* The weakest week for the squad you have — which is where a Free Hit is
   worth most, and where a Wildcard's fixture run is worst. Marked, not
   scored: it is a fact about your own eleven, not a value for the chip. */
.chipwk.weak{border-color:var(--warnline);background:var(--warndim)}
/* The classic gameweek report. Prose, so it gets a measure and a rhythm
   rather than the density every other page here is tuned for. */
.reportp{font-size:var(--t-m);line-height:1.62;color:var(--prose);
  max-width:64ch;margin:0 0 12px}

/* ============================================================= The Brief
   An editorial front page, in this app's own palette and type scale. The
   reference was a magazine's HIERARCHY -- one lead that runs long, shorter
   satellites around it, a rule, then a row of equal stories. No new colours,
   no new faces, no new components.

   The hierarchy does the work that a second font would otherwise do: the
   lead headline is four steps up the existing scale from the evidence
   underneath it, which is what makes the page read as a briefing rather
   than a panel of equal boxes. */
.bmast{border-bottom:2px solid var(--text);padding-bottom:12px;
  margin-bottom:22px}
.bmastt{font-size:var(--t-4xl);font-weight:650;letter-spacing:-.03em;
  line-height:1}
.bmastl{display:flex;flex-wrap:wrap;gap:14px;margin-top:8px;
  font-size:var(--t-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim2)}
.bmastl .bdl{color:var(--warn)}

/* Lead beside its satellites. Two thirds and one third, the proportion a
   front page uses to say which story is the story. */
.bgrid{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr);
  gap:28px;align-items:start}

.blabel{font-size:var(--t-xxs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);margin-bottom:6px}
.blead .bleadh{font-size:var(--t-4xl);font-weight:600;letter-spacing:-.025em;
  line-height:1.08;max-width:18ch}
.bleads{font-size:var(--t-xl);line-height:1.35;color:var(--prose);
  margin:10px 0 0;max-width:34ch;font-weight:500}
.bstand{font-size:var(--t-m);line-height:1.6;color:var(--prose);
  max-width:56ch;margin:16px 0 0}

/* The call sits INSIDE the lead, under a rule -- a second section of the
   same story rather than a box of its own, because the transfer only means
   anything in the context of the week above it. */
.bcall{margin-top:22px;padding-top:18px;border-top:1px solid var(--line2)}
.bcall.hold .blabel{color:var(--dim)}
.bcallh{font-size:var(--t-2xl);font-weight:600;letter-spacing:-.02em;
  line-height:1.15;max-width:22ch}
.bcalls{font-size:var(--t-m);line-height:1.55;color:var(--prose);
  margin:8px 0 0;max-width:56ch}
.bcallm{margin-top:10px;font-size:var(--t-xxs);letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim2)}
.bacts{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.bacts .btn{min-height:34px}

/* Satellites. Deliberately smaller than the lead at every level -- label,
   headline, body -- so the page has one focus rather than four. */
.bside{display:flex;flex-direction:column;gap:0}
.bcard{padding:14px 0;border-bottom:1px solid var(--line)}
.bcard:first-child{padding-top:0}
.bcard:last-child{border-bottom:none}
.bcard.open{cursor:pointer}
.bcard.open:hover .bch{color:var(--accent)}
.bch{font-size:var(--t-m);font-weight:600;line-height:1.3;max-width:34ch}
.bcb{font-size:var(--t-s);line-height:1.5;color:var(--text);
  margin:5px 0 0;max-width:44ch}
/* Was --dim2, which on this ground reads as switched off rather than quiet.
   The evidence should be subordinate to the editorial copy, not invisible
   beside it. */
.bcm{font-size:var(--t-xs);color:var(--dim);margin-top:5px;font-style:italic}

.brule{border-top:2px solid var(--text);margin:26px 0 0}

/* BELOW THE FOLD: hierarchy, not a grid.
   Four equal columns is a dashboard however the cards are labelled --
   nothing is more important than anything else, so the eye has nowhere to
   start. One story runs wide; the rest are notes beside it. */
.bbelow{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  gap:30px;padding-top:20px;align-items:start}
.bbelow.solo{grid-template-columns:minmax(0,1fr)}
.bbelow.solo .bcard.big{max-width:none}
.bminor{display:flex;flex-direction:column;gap:0;
  border-left:1px solid var(--line);padding-left:22px}
.bminor .bcard{padding:12px 0;border-bottom:1px solid var(--line)}
.bminor .bcard:first-child{padding-top:0}
.bminor .bcard:last-child{border-bottom:none}

/* A card given the room to be a story rather than a note. */
.bcard.big .bch{font-size:var(--t-xl);max-width:24ch;letter-spacing:-.01em}
.bcard.big .bcb{font-size:var(--t-m);max-width:52ch;margin-top:7px}

.brisers{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:30px;
  padding-top:18px}
.brisers .bcard{border-bottom:none}
/* A single riser laid across the page rather than stacked down the left of
   it: the headline holds one column, its evidence the other, so one story
   reads as a deliberate wide item instead of a column with the rest of the
   page missing beside it. */
.brisers.solo{grid-template-columns:minmax(0,1fr)}
.brisers.solo .bcard{display:grid;gap:8px 30px;align-items:start;
  grid-template-columns:minmax(0,1fr) minmax(0,1.25fr)}
.brisers.solo .blabel{grid-column:1;grid-row:1}
.brisers.solo .bch{grid-column:1;grid-row:2;max-width:22ch}
.brisers.solo .bcb{grid-column:2;grid-row:1/3;margin:0;max-width:56ch}
.brisers.solo .bcm{grid-column:2;grid-row:3;margin-top:6px;max-width:56ch}

/* One riser, running the width of the page instead of sitting in a
   four-column grid with three empty columns beside it. A short week is a
   real answer and should look composed; three blank columns look like
   something failed to load. Two columns rather than one so the headline and
   its evidence stay in the same relationship they have on every other card,
   which is what stops this reading as a different component. */
/* THE WHAT-IF BAR.
   Amber, because it is the one state on the page where what you are looking
   at is not true yet. It says so in words as well: a colour alone is a
   convention somebody has to have learned. */
.wibar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  background:var(--warndim);border:1px solid var(--warnline);
  border-radius:var(--r);padding:11px 14px;margin-bottom:14px;
  font-size:var(--t-s)}
.wibar b{color:var(--warn)}
.wibar .lnk,.wibar .btn{margin-left:auto}
.wibar.plan{margin-bottom:16px;align-items:flex-start}
/* Not affordable, or not legal. Red rather than amber: amber is "this is
   not true yet", red is "this cannot happen". */
.wibar.bad{background:var(--negdim);border-color:var(--negline)}
.wibar.bad b{color:var(--neg)}
.wifigs{display:flex;gap:20px;flex:none}
.wifig b{display:block;font-family:var(--mono);font-size:var(--t-l);
  font-weight:600;font-variant-numeric:tabular-nums;color:var(--text)}
.wifig.bad b{color:var(--neg)}
.wifig span{display:block;font-size:var(--t-xxs);color:var(--dim);
  margin-top:2px;max-width:16ch}
.wift{display:flex;flex-direction:column;gap:4px;flex:none;max-width:26ch}
.wift label{font-size:var(--t-xxs);letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim2)}
.wift .seg button{min-width:30px}
.wift span{font-size:var(--t-micro);line-height:1.4}
@media(max-width:900px){
  .wibar.plan{flex-direction:column}
  .wibar .lnk,.wibar .btn{margin-left:0}
}
/* A queued cell on the waiver board. */
.matrix td.c.planned{outline:2px solid var(--warn);outline-offset:-2px;
  font-weight:600}
.matrix td.c{cursor:pointer}
.matrix td.c:hover{outline:1px solid var(--line3);outline-offset:-1px}

/* Paging a table, not opening a drawer over it. */
.tpage{display:flex;align-items:center;gap:12px;margin-top:10px;
  font-size:var(--t-xs)}
.tpage .btn{min-height:30px;padding:5px 11px}
.tpage .btn[disabled]{opacity:.4;cursor:default}

/* League movement. Level is a fact and gets a mark of its own; the colour
   agrees with the arrow so neither has to be read alone. */
.mv{color:var(--dim2)}
.mv.pos{color:var(--pos)}
.mv.neg{color:var(--neg)}

/* THE COLUMN'S FURNITURE.
   A headline, a standfirst and a byline with a face on it. The report is
   the shareable object, so it is given the space and the hierarchy of one
   -- and the hierarchy is what was missing, not the words. */
.rhead{font-size:var(--t-3xl);font-weight:600;letter-spacing:-.02em;
  line-height:1.12;margin:0 0 8px;max-width:22ch;text-wrap:balance}
.rstand{font-size:var(--t-l);line-height:1.5;color:var(--prose);
  margin:0 0 14px;max-width:56ch}
.byline{display:flex;align-items:center;gap:12px;padding-bottom:14px;
  border-bottom:1px solid var(--line);margin-bottom:16px;
  font-size:var(--t-xs);color:var(--dim)}
.byline b{color:var(--text);font-size:var(--t-s);font-weight:600}
/* The whole byline is the link, so the target is the size of the thing it
   looks like rather than a 44px circle somebody has to aim at. */
.regby{display:flex;align-items:center;gap:12px;text-decoration:none;
  color:inherit;border-radius:var(--r);padding:2px;margin:-2px}
.regby:hover b{color:var(--accent)}
.regby:hover .regmug{border-color:var(--accentline)}
.regby:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.regmug{width:44px;height:44px;border-radius:50%;object-fit:cover;flex:none;
  border:1px solid var(--line2);background:var(--panel2)}
/* Initials until the photograph is in place: a byline with a hole in it is
   worse than one without a picture. */
.regmug.ini{display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:var(--t-s);color:var(--dim2);
  letter-spacing:.06em}
@media(max-width:640px){ .rhead{font-size:var(--t-2xl);max-width:none} }

/* The Scout's figures. The same idea as the pull quote on The Brief and
   deliberately smaller: this is a strip of supporting arithmetic under a
   standfirst, not the object of the page. */
.scfigs{display:flex;flex-wrap:wrap;gap:26px;margin:0 0 18px;
  padding-bottom:16px;border-bottom:1px solid var(--line)}
.scfigs b{display:block;font-family:var(--mono);font-size:var(--t-2xl);
  font-weight:600;letter-spacing:-.03em;color:var(--accent);
  font-variant-numeric:tabular-nums;line-height:1}
.scfigs span{display:block;font-size:var(--t-xs);color:var(--dim);
  margin-top:4px;max-width:22ch}

/* THE WIRE, beside the call.

   Warning furniture, so it is the one place on this page allowed a fill --
   a sentence that might stop you acting has to be separable from the ones
   explaining why you should. Amber where the doubt is about the man coming
   IN, because that is the case against the move; quiet where it is about
   the man going out, because that only agrees with what the call already
   said, and colouring agreement as alarm is how a page teaches you to
   ignore its colours. */
.bwire{margin-top:14px;display:flex;flex-direction:column;gap:8px}
.bwirei{border-left:2px solid var(--line3);padding:8px 0 8px 12px}
.bwirei.against{border-left-color:var(--warn);background:var(--warndim);
  padding:10px 12px;border-radius:0 var(--r) var(--r) 0}
.bwirei.against .blabel{color:var(--warn)}
.bwireh{font-size:var(--t-s);line-height:1.45;color:var(--text);margin:4px 0 0;
  max-width:60ch}
.bwirem{font-size:var(--t-xs);color:var(--dim);margin-top:4px}
.bwiren{font-size:var(--t-xxs);color:var(--dim2);letter-spacing:.06em;
  max-width:64ch}

/* THE COST, and the four figures a classic transfer turns on.

   Inside the call, under a rule of its own: it is not a separate story, it
   is the price of the one the call just made. Draft never draws this --
   there is no money in Draft, and the constraint is other managers. */
.bcost{margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
.bcostl{font-size:var(--t-s);line-height:1.55;color:var(--prose);
  margin:6px 0 0;max-width:60ch}
/* Compact on purpose. These are the arithmetic of ONE decision, so they sit
   together in a strip rather than pretending to be four subjects on four
   cards. */
.bmoney{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px;
  margin-top:14px}
.bmoney > div{border-left:1px solid var(--line);padding-left:10px}
.bmoney b{display:block;font-family:var(--mono);font-size:var(--t-l);
  font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.bmoney span{display:block;font-size:var(--t-xxs);color:var(--dim);
  line-height:1.35;margin-top:3px}

/* YOUR ALTERNATIVES. Three ways through one week, side by side, so the
   trade between them is a glance rather than a paragraph. */
.broutes{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:26px;padding-top:14px}
.broute{border-left:1px solid var(--line);padding-left:18px}
.broute:first-child{border-left:none;padding-left:0}
.broute.open{cursor:pointer}
.broute.open:hover .bch{color:var(--accent)}
.broutem{margin-top:8px;font-family:var(--mono);font-size:var(--t-xxs);
  color:var(--dim);font-variant-numeric:tabular-nums}

/* THE NUMBER TO KNOW.

   A pull quote, set the way a magazine sets one: it does NOT get a band of
   its own across the page. It takes the column beside the story below the
   rule -- the column the minor notes would have filled -- separated by the
   same hairline the notes use. That is the whole reason it exists: a short
   week leaves that column empty, and an empty column is what made the lower
   half look unfinished.

   Two weights and no third. The numeral is the page's own text colour and
   the unit beside it is the accent, which is the only accent spent below
   the rule. No box, no fill, no second ground -- the rule and the space do
   the separating, as they do everywhere else in this stylesheet.

   No serif, and this is a decision rather than an omission: the app ships
   no webfonts and fetches none, because a face from somebody else's CDN is
   a dependency, a tracker and a render-blocking request. The editorial
   register comes from the italic and the measure instead. */
.bfigure{border-left:1px solid var(--line);padding-left:30px;
  align-self:stretch;display:flex;flex-direction:column;justify-content:center}
/* The label sits ABOVE the figure, as a kicker does. It was dropped in the
   first rebuild and the block lost the one line that says what kind of
   thing it is -- a number with no name over it is a number somebody left
   on the page. */
.bfigure .blabel{margin-bottom:6px}
/* Big, and tightly set. A pull quote that is merely larger than the body
   reads as an emphasis; one that is three or four times it reads as a
   different KIND of element, which is the whole effect being borrowed. */
.bfignum{font-size:clamp(64px,7.5vw,104px);font-weight:600;
  letter-spacing:-.055em;line-height:.85;color:var(--text);
  font-variant-numeric:tabular-nums}
/* The unit and the sign, in the accent. Two weights and no third. */
.bfignum i{font-style:normal;color:var(--accent);letter-spacing:-.02em}
.bfigsay{font-size:var(--t-l);font-style:italic;line-height:1.45;
  color:var(--prose);max-width:30ch;margin:16px 0 0;
  letter-spacing:.005em}
.bfigsrc{font-size:var(--t-xxs);letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim2);margin-top:12px}

@media(max-width:900px){
  .bgrid{grid-template-columns:1fr;gap:22px}
  /* Satellites become a row of stories under the lead rather than a column
     beside it; the lead keeps its size, because it is still the story. */
  .bside{border-top:1px solid var(--line2);padding-top:16px}
  /* The wide story and its notes stack. The hierarchy survives the stack
     because it is carried by type size, not only by column width. */
  .bbelow{grid-template-columns:minmax(0,1fr);gap:0}
  .bminor{border-left:none;padding-left:0;border-top:1px solid var(--line);
    margin-top:14px;padding-top:14px}
  .brisers{grid-template-columns:minmax(0,1fr);gap:0}
  .brisers .bcard{border-bottom:1px solid var(--line);padding:14px 0}
  .brisers .bcard:last-child{border-bottom:none}
  /* The side-by-side riser stacks; every child goes back to one column
     rather than keeping the explicit rows it was given above. */
  .brisers.solo .bcard{display:block}
  .brisers.solo .bcard > *{max-width:none}
}
@media(max-width:640px){
  .bmastt{font-size:var(--t-3xl)}
  .blead .bleadh{font-size:var(--t-2xl);max-width:none}
  .bleads{font-size:var(--t-m);max-width:none}
  /* Stacked under the story rather than squeezed beside it: a pull quote
     that has to compete for width stops being one. */
  .bfigure{border-left:none;padding-left:0;border-top:1px solid var(--line);
    margin-top:16px;padding-top:16px}
  .bfignum{font-size:var(--t-4xl,52px)}
  .bfigsay{max-width:none}
  /* Four money figures across a phone is four columns of two characters.
     Two by two keeps each one readable. */
  .bmoney{grid-template-columns:repeat(2,minmax(0,1fr))}
  .broutes{grid-template-columns:minmax(0,1fr);gap:0}
  .broute{border-left:none;padding:14px 0 0;
    border-top:1px solid var(--line)}
  .broute:first-child{border-top:none;padding-top:0}
  .bcard.big .bch{font-size:var(--t-l);max-width:none}
  .bcard.big .bcb{max-width:none}
}

/* The model's own wording, kept but demoted. The primary copy is written
   from the numbers; this is where the mechanism lives for anyone who wants
   it, which is the difference between a briefing and a model explanation. */
.bev{margin-top:12px}
.bev summary{font-size:var(--t-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim2);cursor:pointer;list-style:none}
.bev summary::-webkit-details-marker{display:none}
.bev summary::before{content:'▸ ';color:var(--dim2)}
.bev[open] summary::before{content:'▾ '}
.bev summary:hover{color:var(--text)}
.bev ul{margin:8px 0 0;padding-left:18px;max-width:62ch}
.bev li{font-size:var(--t-s);line-height:1.5;color:var(--dim);margin-bottom:3px}

/* A fixture marker. Typographic, because this app ships no images and a
   crest fetched from somebody else's CDN is a dependency and a tracker. The
   club codes are already on the row; set as a monospace slug they give the
   lead the visual anchor a badge would, and they still read as football. */
.bfix{display:inline-block;font-family:var(--mono);font-size:var(--t-xxs);
  letter-spacing:.14em;color:var(--dim);border:1px solid var(--line2);
  border-radius:3px;padding:3px 7px;margin-bottom:10px}
/* A second rule, lighter than the lead's, for the section under the row. */
.brule2{border-top:1px solid var(--line2);margin:26px 0 0}
.bsechead{font-size:var(--t-xs);letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);padding-top:16px}
.bsechead + .brisers{padding-top:12px}
