/* ChessJammer Tutor styling.
   Desktop layout is three columns: move list, board, coach. The board sizes itself from the viewport
   height so a study session never scrolls, and the move list scrolls inside its own column. */
/* THEMES. A theme is a block of SURFACE tokens under [data-theme=...]: backgrounds, panels, lines,
   text, accents, the page image. It never touches the board or the evidence colours. Red means
   under attack, amber means hanging, green means defended, teal means the engine's choice, and a
   theme that recoloured those would not restyle the app, it would break the teaching. The board's
   own colours live in board.js and are deliberately out of reach here too, because the heatmap
   and the king-cover fills are tuned against them.

   The active theme is set on <html> before the stylesheet loads, by a one-line script in
   index.html, so a themed page never flashes the default first. */
:root{
 --bg:#0a1119;--bg-2:#0e1723;--panel:#152233;--panel-2:#1b2b3f;--line:#2b3f56;--line-2:#3a5771;
 --ink:#eef4fa;--muted:#9db0c4;--accent:#54dcc9;--accent-2:#ffc46b;--accent-ink:#04201d;
 --radius:14px;--shadow:0 12px 32px rgba(0,0,0,.35);
 --page-bg:radial-gradient(1200px 700px at 12% -10%,#1b3347 0%,transparent 60%),
  radial-gradient(900px 600px at 100% 0%,#1d3b3a 0%,transparent 55%),var(--bg);
 --top-bg:rgba(13,22,33,.88);
 --card-glow:none;
 /* The primary button and the current move, which were the accent baked in as a gradient; a
    neutral track colour for meters and pips; and the accent as a wash for an "on" state. */
 --primary-top:#1c6a60;--primary-bot:#155049;--primary-line:#2fa392;--primary-ink:#eafffb;
 --track:#26384a;--accent-wash:rgba(84,220,201,.1);
 /* EVIDENCE. Red means under attack, amber hanging, green defended, blue defending, teal the
    engine. These are information the learner reads, not decoration. A theme may change them ONLY
    to keep them legible on its own panels, which the Light theme has to, because pale mint on
    white is not a colour. The board's own overlay colours are in board.js and are not these. */
 --good:#8ef0b8;--good-fill:#57c98c;--good-line:#3f8e68;
 --warn:#ff9f8f;--bad:#ff6a52;--bad-fill:#d4584a;--bad-line:#8e4f45;--attack:#ff8f5e;
 --defend:#5fb0ff;--defend-2:#8ecbff;--engine:#2fa392;--engine-ink:#bff3ea;
 --mistake:#ffa06a;--inaccuracy:#ffd166;--side-white:#f0e6d4;--side-black:#a9bccd;
 --web-bg:rgba(10,17,25,.4);
 color-scheme:dark;
}

/* RAVE. Neon violet and cyan over a club. The page image is a layer of its own, behind a dark
   wash so the panels stay readable over the crowd; with no image file present the layer is simply
   transparent and the neon gradients underneath carry it. Drop the image at themes/rave-bg.webp. */
:root[data-theme="rave"]{
 --bg:#0a0318;--bg-2:#120726;--panel:#170a33;--panel-2:#211048;--line:#5a2bb8;--line-2:#8a4dff;
 --ink:#f4edff;--muted:#c2aef0;--accent:#2ee6ff;--accent-2:#ff3fd8;--accent-ink:#031018;
 --shadow:0 0 18px rgba(46,230,255,.16),0 12px 32px rgba(0,0,0,.55);
 --page-bg:linear-gradient(rgba(6,2,18,.65),rgba(6,2,18,.85)),
  url("themes/rave-bg.webp") center/cover no-repeat,
  radial-gradient(1000px 650px at 12% -5%,#5a1fc4 0%,transparent 55%),
  radial-gradient(900px 600px at 92% 5%,#c0157e 0%,transparent 52%),
  radial-gradient(700px 500px at 50% 110%,#1a1a8a 0%,transparent 55%),
  var(--bg);
 --top-bg:rgba(10,3,24,.82);
 --card-glow:0 0 0 1px rgba(46,230,255,.18),0 0 22px rgba(138,77,255,.22);
 --primary-top:#2a8fb8;--primary-bot:#175b86;--primary-line:#2ee6ff;--primary-ink:#eafcff;
 --track:#2a1650;--accent-wash:rgba(46,230,255,.12);
}
/* DESK. Walnut, brass and cream, over a chess desk. Warm and low-glow: the panels are dark wood
   and the accent is brass, so the teal engine arrow and the evidence colours still stand out
   against it rather than blending into an amber wash. Image at themes/desk-bg.webp. */
:root[data-theme="desk"]{
 --bg:#1a1008;--bg-2:#241609;--panel:#2e1c0e;--panel-2:#3a2412;--line:#5a3a1c;--line-2:#8a5a2a;
 --ink:#f5e9d3;--muted:#cdb692;--accent:#e6b04f;--accent-2:#f2c46b;--accent-ink:#1a1008;
 --shadow:0 10px 28px rgba(0,0,0,.55);
 --page-bg:linear-gradient(rgba(22,13,5,.46),rgba(22,13,5,.74)),
  url("themes/desk-bg.webp") center/cover no-repeat,
  radial-gradient(900px 600px at 20% 0%,#5a3a1c 0%,transparent 55%),
  var(--bg);
 --top-bg:rgba(26,16,8,.84);
 --card-glow:0 0 0 1px rgba(230,176,79,.14),inset 0 1px 0 rgba(255,235,200,.05);
 --primary-top:#8a6426;--primary-bot:#5e4318;--primary-line:#e6b04f;--primary-ink:#fff4dc;
 --track:#4a3018;--accent-wash:rgba(230,176,79,.12);
}
:root[data-theme="desk"] .brand .mark{color:var(--accent);filter:drop-shadow(0 0 8px rgba(230,176,79,.45))}
:root[data-theme="desk"] :is(.card,.board-panel,.legend-col,.chart-panel,.rail,.coach,.bot-box,.guess-box,.quiz){
 box-shadow:var(--card-glow),var(--shadow)}

/* CHARCOAL. High contrast: black, charcoal, white text, a gold accent. No image, no glow, nothing
   soft. The gold ring on the panels is the one decoration, because a border you can see is part
   of what high contrast means. */
:root[data-theme="charcoal"]{
 --bg:#000;--bg-2:#0a0a0a;--panel:#151515;--panel-2:#202020;--line:#3c3c3c;--line-2:#606060;
 --ink:#fff;--muted:#cfcfcf;--accent:#ffd166;--accent-2:#ffd166;--accent-ink:#000;
 --shadow:0 8px 24px rgba(0,0,0,.6);
 --page-bg:#000;
 --top-bg:rgba(0,0,0,.94);
 --card-glow:0 0 0 1px rgba(255,209,102,.38);
 --primary-top:#7a6720;--primary-bot:#574915;--primary-line:#ffd166;--primary-ink:#fff8dc;
 --track:#2c2c2c;--accent-wash:rgba(255,209,102,.16);
}
:root[data-theme="charcoal"] .brand .mark{color:var(--accent);filter:none}
:root[data-theme="charcoal"] :is(.card,.board-panel,.legend-col,.chart-panel,.rail,.coach,.bot-box,.guess-box,.quiz){
 box-shadow:var(--card-glow)}

/* LIGHT MINIMAL. White panels on a pale page, dark text, a teal accent dark enough to read on
   white. The one theme that is not dark, which is why the contrast floor exists: light themes are
   where washed-out text happens. color-scheme:light so the browser's own form controls follow. */
:root[data-theme="light"]{
 --bg:#f2f5f8;--bg-2:#e9eef3;--panel:#fff;--panel-2:#f1f4f7;--line:#d5dce3;--line-2:#b4bfca;
 --ink:#14212c;--muted:#556676;--accent:#1a8f80;--accent-2:#a8660f;--accent-ink:#fff;
 --shadow:0 8px 24px rgba(20,30,40,.10);
 --page-bg:linear-gradient(180deg,#f7f9fb,#eef2f6);
 --top-bg:rgba(255,255,255,.9);
 --card-glow:0 0 0 1px rgba(20,33,44,.04);
 --primary-top:#2aae9c;--primary-bot:#1a8f80;--primary-line:#1a8f80;--primary-ink:#fff;
 --track:#dde4ea;--accent-wash:rgba(26,143,128,.12);
 /* The same meanings, dark enough to read on white. Green is still green, red still red. */
 --good:#157347;--good-fill:#2d9a5f;--good-line:#2d9a5f;
 --warn:#b4362a;--bad:#c0392b;--bad-fill:#c0392b;--bad-line:#d98a80;--attack:#c4501c;
 --defend:#1f6fbf;--defend-2:#1f6fbf;--engine:#1a8f80;--engine-ink:#0f5f55;
 --mistake:#b85c1e;--inaccuracy:#8a6300;--side-white:#5c4a22;--side-black:#2f4256;
 --web-bg:rgba(20,33,44,.05);
 color-scheme:light;
}
:root[data-theme="light"] .brand .mark{filter:drop-shadow(0 0 6px rgba(26,143,128,.25))}
:root[data-theme="light"] nav a:hover{background:var(--panel-2)}

/* GLASS. Translucent panels blurred over a bright image. The panel colour carries enough dark of
   its own that text clears the floor even where the image behind it is white, which the test
   checks by compositing the panel over white: the worst case, not the average one. */
:root[data-theme="glass"]{
 --bg:#0c1030;--bg-2:#121740;--panel:rgba(14,20,58,.74);--panel-2:rgba(28,36,88,.78);
 --line:rgba(150,170,255,.30);--line-2:rgba(180,196,255,.55);
 --ink:#eef2ff;--muted:#bcc6f0;--accent:#5ec8ff;--accent-2:#ffb3f0;--accent-ink:#06122a;
 --shadow:0 10px 30px rgba(0,0,0,.35);
 --page-bg:linear-gradient(rgba(8,10,40,.30),rgba(8,10,40,.55)),
  url("themes/glass-bg.webp") center/cover no-repeat,
  var(--bg);
 --top-bg:rgba(10,14,48,.55);
 --card-glow:0 0 0 1px rgba(255,255,255,.10),inset 0 1px 0 rgba(255,255,255,.14);
 --primary-top:#3a7de0;--primary-bot:#2757ad;--primary-line:#5ec8ff;--primary-ink:#eef8ff;
 --track:rgba(255,255,255,.14);--accent-wash:rgba(94,200,255,.16);
}
:root[data-theme="glass"] :is(.card,.board-panel,.legend-col,.chart-panel,.rail,.coach,.bot-box,.guess-box,.quiz,.top,.theme-menu){
 backdrop-filter:blur(16px) saturate(1.25);-webkit-backdrop-filter:blur(16px) saturate(1.25);
 box-shadow:var(--card-glow),var(--shadow)}
:root[data-theme="glass"] .brand .mark{filter:drop-shadow(0 0 10px rgba(94,200,255,.55))}

:root[data-theme="rave"] .brand .mark{filter:drop-shadow(0 0 10px rgba(46,230,255,.6))}
:root[data-theme="rave"] :is(.card,.board-panel,.legend-col,.chart-panel,.rail,.coach,.bot-box,.guess-box,.quiz){
 box-shadow:var(--card-glow),var(--shadow)}
:root[data-theme="rave"] nav a.active,:root[data-theme="rave"] .lib-tab.on{
 box-shadow:0 0 12px rgba(46,230,255,.35)}
:root[data-theme="rave"] h1{text-shadow:0 0 14px rgba(255,63,216,.35)}

*{box-sizing:border-box}
html{min-height:100%;background:var(--page-bg);background-attachment:fixed}
body{margin:0;min-height:100vh;color:var(--ink);font:16px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:transparent}
.skip{position:absolute;left:-999px}.skip:focus{left:8px;top:8px;background:var(--accent);color:var(--accent-ink);padding:8px;border-radius:8px;z-index:9}

.top{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;
 padding:9px 22px;border-bottom:1px solid var(--line);background:var(--top-bg);backdrop-filter:blur(8px);position:sticky;top:0;z-index:5}
.brand{display:flex;align-items:center;gap:10px;font-size:17px}
.brand .mark{font-size:24px;color:var(--accent);filter:drop-shadow(0 0 10px rgba(84,220,201,.35))}
.brand strong{color:var(--accent)}
nav{display:flex;gap:4px;flex-wrap:wrap}
nav a{color:var(--muted);text-decoration:none;padding:7px 14px;border-radius:999px;border:1px solid transparent;font-size:15px}
nav a:hover{color:var(--ink);background:var(--panel)}
nav a.active{background:var(--panel-2);color:var(--ink);border-color:var(--line-2)}
main{max-width:1640px;margin:0 auto;padding:12px 16px 16px}
.page-note{color:var(--muted);font-size:12px;margin:14px 0 0;max-width:80ch}
h1{font-size:25px;margin:0 0 3px;letter-spacing:-.01em}
h2{font-size:18px;margin:0 0 8px}
h3{font-size:12.5px;margin:0 0 8px;text-transform:uppercase;letter-spacing:.09em;color:var(--muted)}
/* The title and the way back share one line. The crumb used to sit on its own line above the
   title, which on a puzzle page pushed the bottom of the board off a laptop screen. It goes to the
   right of the title now; the description, when there is one, wraps underneath at full width. */
/* Grid, not flex. With flex the description's max-width of 70ch clamped it to about 600px, so a
   1400px header saw "title plus crumb plus 600 fits on one line" and never wrapped it. Grid puts
   it on the second row whatever its width. Anything else in the header takes a full row too. */
.page-head{margin-bottom:16px;display:grid;grid-template-columns:1fr auto;column-gap:16px;row-gap:2px;align-items:baseline}
.page-head h1{grid-column:1;grid-row:1;margin:0}
.page-head .crumb{grid-column:2;grid-row:1;justify-self:end;margin:0}
.page-head>*:not(h1):not(.crumb){grid-column:1/-1}
.page-head p{color:var(--muted);margin:0 0 10px;max-width:70ch}

.card{background:linear-gradient(180deg,var(--panel) 0%,var(--bg-2) 100%);border:1px solid var(--line);border-radius:var(--radius);padding:18px;margin-bottom:16px;box-shadow:var(--shadow)}
.row{display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin-top:10px}
.spacer{flex:1}
button,.button{font:inherit;background:var(--panel-2);color:var(--ink);border:1px solid var(--line-2);border-radius:10px;padding:8px 14px;cursor:pointer;text-decoration:none;display:inline-block;transition:border-color .15s,background .15s,transform .05s}
button:hover,.button:hover{border-color:var(--accent);background:#213448}
button:active{transform:translateY(1px)}
button.primary,.button.primary{background:linear-gradient(180deg,var(--primary-top),var(--primary-bot));border-color:var(--primary-line);color:var(--primary-ink);font-weight:600}
.button.subtle{background:transparent;color:var(--muted);border-color:transparent;padding:6px 10px;font-size:14px}
.button.subtle:hover{color:var(--ink);background:var(--panel)}
textarea{width:100%;background:#0b1520;color:var(--ink);border:1px solid var(--line);border-radius:10px;padding:12px;font:14px/1.5 ui-monospace,Consolas,monospace}
textarea:focus{outline:2px solid var(--accent);outline-offset:1px}
.file{border:1px dashed var(--line-2);border-radius:10px;padding:8px 14px;cursor:pointer;color:var(--muted)}
.file:hover{color:var(--ink);border-color:var(--accent)}
.file input{display:none}
.status{color:var(--accent);min-height:1.4em;margin:10px 0 0}

.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:12px}
.tile{display:flex;flex-direction:column;gap:6px;align-items:flex-start;text-align:left;padding:15px;
 background:linear-gradient(180deg,var(--panel-2),var(--panel));border:1px solid var(--line);border-radius:12px;color:var(--ink);text-decoration:none}
.tile:hover{border-color:var(--accent)}
.tile strong{font-size:16.5px}.tile span{color:var(--muted);font-size:14px}
.tile .eco{color:var(--accent);font-size:12.5px;letter-spacing:.05em;text-transform:uppercase}

/* ---------- study: moves | board | coach ---------- */
.study-top{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;justify-content:space-between;margin-bottom:8px}
.study-top p{color:var(--muted);margin:0;font-size:14px}
.study.no-eval{grid-template-columns:238px var(--board) 178px minmax(330px,1fr)}
.study{display:grid;--board:calc(100vh - 400px);grid-template-columns:238px calc(var(--board) + 45px) 178px minmax(330px,1fr);gap:10px;align-items:start;--column:calc(100vh - 148px)}
.board-panel{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);border-radius:var(--radius);padding:10px;box-shadow:var(--shadow);min-width:0}
.board-row{display:flex;gap:9px;align-items:stretch;justify-content:center}
.board-wrap{width:min(var(--board),100%);margin:0;position:relative}
/* The board SVG carries a margin for its coordinates (28 of 568 units, 4.93%), so the bar's track
   is inset by the same fraction and its ends line up with the squares. */
/* Wide enough for the number it has to print. At 16px the bar cut "+0.35" off after the point,
   and half an evaluation is not an evaluation. */
.eval-bar{position:relative;width:26px;flex:none}
.eval-track{position:absolute;left:0;right:0;top:4.93%;bottom:4.93%;border-radius:8px;overflow:hidden;
 background:linear-gradient(180deg,#1b2530,#243040);border:1px solid var(--line)}
.eval-track i{position:absolute;left:0;right:0;bottom:0;display:block;background:linear-gradient(180deg,#f4ecdc,#d9cdb4);transition:height .25s}
.eval-tick{position:absolute;left:-3px;right:-3px;height:3px;background:#ffc46b;border-radius:2px;box-shadow:0 0 0 1px #0a1119;transition:bottom .25s;z-index:3}
.eval-bar.compensation .eval-tick{background:var(--attack);box-shadow:0 0 0 1px #0a1119,0 0 7px rgba(255,143,94,.85)}
.eval-track.mate i{background:linear-gradient(180deg,#ffd9a0,#ffbf63)}
.eval-track span{position:absolute;left:0;right:0;text-align:center;font-size:10.5px;font-weight:700;
 font-variant-numeric:tabular-nums;letter-spacing:-.2px;white-space:nowrap;z-index:2}
.eval-top{top:3px;color:#cfe0ef}
.eval-bottom{bottom:3px;color:#2b2317}
.opening-line{margin:4px 0 0;font-size:13px;color:var(--muted)}
.opening-line a{color:var(--accent);text-decoration:none}
.opening-line a:hover{text-decoration:underline}
.engine-why{margin:8px 0 0;font-size:13px;color:var(--muted);line-height:1.45}
.sec-engine h5{margin:10px 0 4px;font-size:11.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}
.pv-list{margin:0;padding-left:18px;font-size:13px}
.pv-list li{margin:2px 0;font-variant-numeric:tabular-nums}
.pv-list b{color:var(--accent);margin-right:5px}
.accuracy{margin-top:10px;padding-top:9px;border-top:1px solid var(--line)}
.acc-row{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap;font-size:12.5px;color:var(--muted)}
.acc-row b{font-size:13.5px}
.acc-row .white-side{color:var(--side-white)}.acc-row .black-side{color:var(--side-black)}
.acc-phases{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px;font-size:11.5px;color:var(--muted)}
.cell{cursor:pointer}
.cell:focus{outline:2px solid var(--accent);outline-offset:-3px}
.sq-pop{position:absolute;z-index:4;width:232px;max-width:74%;background:linear-gradient(180deg,#16283a,#101c29);
 border:1px solid var(--line-2);border-radius:12px;box-shadow:0 16px 36px rgba(0,0,0,.5);padding:11px 12px;font-size:13px;color:var(--ink)}
.sq-pop header{display:flex;align-items:center;justify-content:space-between;margin-bottom:7px}
.sq-pop header strong{font-size:17px;letter-spacing:.04em;color:var(--accent)}
.pop-close{background:transparent;border:0;color:var(--muted);font-size:18px;line-height:1;padding:0 4px;cursor:pointer}
.pop-close:hover{color:var(--ink);background:transparent}
.sq-pop hr{border:0;border-top:1px solid var(--line);margin:8px 0}
.pop-row{display:flex;gap:8px;justify-content:space-between;align-items:baseline;margin:2px 0}
.pop-label{color:var(--muted);font-size:11.5px;text-transform:uppercase;letter-spacing:.06em}
.pop-value{text-align:right;font-weight:600}
.pop-row.good .pop-value{color:var(--good)}
.pop-row.bad .pop-value{color:var(--warn)}
.pop-row.muted .pop-value{color:var(--muted);font-weight:500}
.pop-row.white-side .pop-value{color:#f6eddc}
.pop-row.black-side .pop-value{color:#a9c0d4}
.pop-list{margin:1px 0 6px;font-size:15px;letter-spacing:.06em;color:var(--ink);
 font-family:system-ui,"Segoe UI Symbol","Noto Sans Symbols 2",sans-serif;font-variant-emoji:text}
.pop-note{margin:6px 0 0;font-size:12px;color:var(--muted);line-height:1.4}
.pop-note.warn{color:var(--accent-2)}
@media (max-width:560px){.sq-pop{width:190px;font-size:12.5px}}
#board{width:100%;height:auto;aspect-ratio:1/1;display:block;border-radius:8px}
.piece{cursor:pointer}.piece:focus{outline:2px solid var(--accent);outline-offset:-4px}
/* Move names keep their own case: QXD6 is not how anyone writes a move. */
.pop-row.san-row .pop-label{text-transform:none;font-size:13px;font-weight:700;letter-spacing:0;color:var(--ink)}
.info-dot{cursor:help}.info-dot:hover circle{fill:#13202b}.info-dot:focus{outline:2px solid var(--accent);outline-offset:-2px}

/* ---- lessons ---- */
.learn-top{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
.learn-top h2{margin:0}
.learn-rating{display:flex;flex-direction:column;gap:1px;padding:0 16px;border-left:1px solid var(--line);
 border-right:1px solid var(--line);margin-left:auto}
.learn-rating .dash-big{font-size:26px;color:var(--accent)}
.learn-rating .dash-note{max-width:210px}
.coverage{display:flex;flex-wrap:wrap;gap:5px;margin-top:4px}
/* One square per lesson, tinted by domain. Empty is an outline, done is filled: the shelf you can
   see at a glance is the point, so the two states have to differ in fill, not only in shade. */
.coverage .cell{width:22px;height:22px;border-radius:5px;border:1.5px solid var(--tint);
 background:color-mix(in srgb, var(--tint) 12%, transparent);display:block;transition:transform .12s}
.coverage .cell.done{background:var(--tint)}
.coverage .cell:hover{transform:translateY(-2px)}
/* ---- the pack dashboard ---- */
.dash{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px;margin-bottom:6px;
 background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);
 border-radius:var(--radius);box-shadow:var(--shadow);padding:14px 16px}
.dash-cell{display:flex;flex-direction:column;gap:2px;min-width:0}
.dash-cell.wide{gap:6px}
.dash-label{font-size:11.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:700}
.dash-big{font-size:34px;font-weight:800;line-height:1.05;font-variant-numeric:tabular-nums}
.dash-cell.level .dash-big{color:var(--accent)}
.dash-note{font-size:12px;color:var(--muted);line-height:1.35}
.dash-line{font-size:14px;font-weight:700}
.dash-cell .button{align-self:flex-start;padding:4px 10px;font-size:12.5px}
.pack-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:10px;margin-bottom:6px}
/* ---- an opening line, on the same four columns as every other board ---- */
.op-card{margin-bottom:0;padding:12px 13px}
.op-card h3{margin-bottom:7px}
.op-moves{display:flex;flex-direction:column;gap:3px}
.op-move{display:flex;flex-direction:column;align-items:flex-start;gap:1px;text-align:left;width:100%;
 background:transparent;border:1px solid transparent;border-left:2px solid var(--line);
 border-radius:7px;padding:5px 9px;cursor:pointer;color:var(--muted)}
.op-move b{color:var(--ink);font-size:13.5px;font-variant-numeric:tabular-nums}
.op-move span{font-size:11.6px;line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;
 -webkit-box-orient:vertical;overflow:hidden}
.op-move:hover{background:var(--panel-2);border-left-color:var(--accent)}
.op-move.played{border-left-color:var(--primary-line)}
.op-move.current{background:var(--panel-2);border-color:var(--line-2);border-left-color:var(--accent)}
.op-move.current b{color:var(--accent)}
.op-remember{margin:0;padding-left:17px;font-size:12.8px;color:var(--muted);line-height:1.45}
.op-remember li{margin:3px 0}
.op-reading .idea{border-left:3px solid var(--accent);padding-left:11px;margin:2px 0 10px;color:var(--ink)}
.op-reading .button.primary{margin-top:10px}
.transport-row{margin-top:9px}
.chip.good-chip{color:var(--good);border-color:var(--good-line)}
/* ---- a small static board for a card ---- */
.mini-board{display:block;border-radius:7px;flex:none;box-shadow:0 2px 10px rgba(0,0,0,.35)}
.opening-card{gap:9px}
.opening-top{display:flex;gap:12px;align-items:flex-start}
.opening-meta{display:flex;flex-direction:column;gap:4px;min-width:0}
.opening-meta strong{font-size:15.5px;line-height:1.25}
.opening-line-moves{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;
 background:rgba(255,255,255,.04);border-radius:7px;padding:5px 8px;letter-spacing:.02em}
.openings-grid{grid-template-columns:repeat(auto-fill,minmax(322px,1fr))}
.opening-thumbs{display:flex;flex-wrap:wrap;gap:10px;margin-top:9px}
.opening-thumbs a{display:flex;flex-direction:column;gap:4px;align-items:center;width:78px;
 text-decoration:none;color:var(--muted);font-size:10.5px;text-align:center;line-height:1.25}
.opening-thumbs a:hover{color:var(--ink)}
/* ---- progress: the same furniture as everywhere else, not a column of bullet lists ---- */
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(288px,1fr));gap:11px;align-items:stretch;
 grid-auto-rows:min-content}
.stat-card{margin-bottom:0;padding:14px 15px}
.stat-card h3{margin-bottom:8px}
.stat-card.wide-card{grid-column:1/-1}
.stat-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:4px}
.stat-top .dash-big{color:var(--accent)}
.trail{width:210px;height:44px;flex:none}
.stat-rows{margin-top:10px;border-top:1px solid var(--line);padding-top:8px}
.stat-row{display:flex;justify-content:space-between;gap:12px;font-size:12.8px;color:var(--muted);padding:3px 0}
.stat-row b{color:var(--ink);font-variant-numeric:tabular-nums}
.course-rings{display:flex;flex-wrap:wrap;gap:12px;margin-top:4px}
.course-rings .course-ring{display:flex;flex-direction:column;align-items:center;gap:5px;width:88px;
 text-decoration:none;color:var(--muted);font-size:11px;text-align:center;line-height:1.25}
.course-rings .course-ring:hover{color:var(--ink)}
.course-rings .ring{width:46px;height:46px}
.reset-card{display:flex;gap:16px;align-items:center;justify-content:space-between;flex-wrap:wrap;margin-top:12px}
.reset-card h3{margin-bottom:3px}
.reset-card .dash-note{max-width:72ch}
.opp-line{margin-top:7px;padding-top:7px;border-top:1px solid var(--line)}
.opp-line b{color:var(--ink)}
.opp-line.held b{color:var(--good)}
/* ---- declare before you move ---- */
.declare{border:1px solid var(--line-2);border-left:3px solid var(--accent-2);border-radius:10px;
 padding:10px 12px;margin:0 0 10px;background:rgba(255,196,107,.06)}
.declare.right{border-left-color:var(--good-line);background:rgba(111,230,162,.07)}
.declare.wrong{border-left-color:#b85c4a;background:rgba(255,106,82,.07)}
.declare-ask{margin:0 0 7px;font-weight:600;font-size:14px}
.declare-options{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:6px}
.declare-options button{padding:6px 12px;font-size:13.5px}
.declare-said{margin:0 0 5px;font-size:13.5px}
.declare .fineprint,.declare .hint{margin:4px 0 0}
.range.unrated{background:repeating-linear-gradient(90deg,var(--track) 0 6px,transparent 6px 12px)}
/* ---- the game cut into sentences ---- */
.arc-band{display:flex;gap:2px;height:16px;margin:8px 0 5px}
.arc-seg{flex:1;min-width:3px;padding:0;border:0;border-radius:3px;cursor:pointer;
 background:var(--tint);opacity:.34;transition:opacity .12s,transform .12s}
.arc-seg.past{opacity:.6}
.arc-seg:hover{opacity:.95;transform:translateY(-2px)}
.arc-seg.here{opacity:1;box-shadow:0 0 0 1.5px #fbf6ec}
.arc-note{margin:0 0 4px;font-size:12px;color:var(--muted);line-height:1.35}
.arc-note b{color:var(--ink)}
/* ---- the piece web ---- */
.web-panel svg{width:100%;height:auto;display:block;background:var(--web-bg);border-radius:9px}
.web-note{display:flex;flex-direction:column;gap:3px;margin:7px 0 0;font-size:11.5px;color:var(--muted)}
.web-legend{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.wl{width:13px;height:2px;border-radius:2px;display:inline-block;margin-right:2px}
.wl.atk{background:var(--attack)}
.wl.def{background:#6fe6a2;margin-left:8px}
.web-alone{color:var(--accent-2)}
.web-alone.none{color:var(--muted)}
/* ---- performance by theme ---- */
.theme-rows{display:flex;flex-direction:column;gap:3px;margin:9px 0 4px}
.theme-row{display:grid;grid-template-columns:132px 1fr 46px 42px;gap:9px;align-items:center;font-size:12.4px}
.theme-name{color:var(--muted);text-transform:capitalize;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.theme-bar{position:relative;height:10px;background:#1b2b3f;border-radius:5px}
.theme-bar i{position:absolute;top:3px;height:4px;border-radius:2px;background:var(--line-2)}
.theme-row .theme-bar i{background:var(--line-2)}
.theme-row.behind .theme-bar i{background:var(--bad-fill)}
.theme-row.ahead .theme-bar i{background:var(--good-fill)}
.theme-bar u{position:absolute;top:-2px;width:2px;height:14px;background:#fbf6ec;opacity:.75}
.theme-bar b{position:absolute;top:1px;width:8px;height:8px;margin-left:-4px;border-radius:50%;
 background:var(--ink);box-shadow:0 0 0 1px #0a1119}
.theme-row.behind .theme-bar b{background:var(--bad-fill)}
.theme-row.ahead .theme-bar b{background:var(--good-fill)}
.theme-num{font-variant-numeric:tabular-nums;text-align:right;font-weight:700}
.theme-row.behind .theme-num{color:var(--warn)}
.theme-row.ahead .theme-num{color:var(--good)}
.theme-n{font-variant-numeric:tabular-nums;color:var(--muted);font-size:11.5px;text-align:right}
/* ---- the journal ---- */
.journal-box textarea{margin-top:4px;min-height:52px}
.journal-box .row{margin-top:8px}
.journal-cell .journal-said{font-style:italic;color:var(--ink);line-height:1.4;font-weight:400;font-size:13.5px}
.lens.unavailable{opacity:.45;cursor:not-allowed}
.lens.unavailable input{cursor:not-allowed}
/* ---- a meter that folds, carrying its numbers on the fold ---- */
.fold-head{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:transparent;
 border:0;border-radius:0;padding:0 0 2px;cursor:pointer;color:var(--ink)}
.fold-head h3{margin:0;flex:none}
.fold-head:hover h3{color:var(--ink)}
.fold-chev{font-size:16px;line-height:.9;color:var(--muted);width:11px;flex:none;
 transform:rotate(90deg);transition:transform .12s}
.fold-head.folded .fold-chev{transform:rotate(0deg)}
.fold-sum{margin-left:auto;display:flex;align-items:center;gap:2px;font-size:13px;
 font-variant-numeric:tabular-nums}
.fold-sum .fold-king{font-size:14px;color:var(--muted);margin-right:2px}
.fold-sum .fold-dot{color:var(--line-2);margin:0 5px}
.fold-body[hidden]{display:none}
/* The graph is a picture, not a document: dragging across it should not select its labels. */
#web,#board{user-select:none;-webkit-user-select:none}
/* And it fits the panel rather than scrolling inside it. */
.web-panel{display:flex;flex-direction:column;gap:6px;overflow:hidden}
.web-panel svg{flex:1 1 auto;min-height:0;width:100%;height:100%}
.web-panel .web-note{flex:none}
/* One tab at a time, each with the whole column. */
.rail>.coach,.rail>.meter-stack{flex:1 1 auto;min-height:0;overflow:auto;scrollbar-width:thin}
.meter-stack{display:flex;flex-direction:column;gap:10px}
/* An author display rule beats the browser's own [hidden] rule, so a panel given display:flex
   stays on screen when it is hidden. The piece web showed under all three tabs because of it. */
.meter-stack[hidden],.rail>.coach[hidden],.web-panel[hidden]{display:none}
.meter-stack>.cover{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);
 border-radius:var(--radius);box-shadow:var(--shadow);padding:11px 12px;flex:0 0 auto}
/* ---- the piece web, in the rail behind a tab ---- */
.web-modes{display:flex;gap:5px;flex:none;flex-wrap:wrap}
.web-mode{padding:3px 9px;font-size:11.5px;border-radius:7px;background:transparent;
 border:1px solid var(--line);color:var(--muted)}
.web-mode:hover{color:var(--ink);border-color:var(--line-2)}
.web-mode.on{background:var(--panel-2);border-color:var(--accent);color:var(--ink);font-weight:600}
.web-panel svg{cursor:grab;touch-action:none}
.web-mode.fit{margin-left:auto;color:var(--accent)}
.web-hit{cursor:pointer}
.web-hit:focus{outline:2px solid var(--accent);outline-offset:1px}
.web-ask{color:var(--ink);font-size:12px;font-weight:600}
.web-sizes{color:var(--line-2)}

.rail-tabs{display:flex;gap:6px;flex:0 0 auto}
.rail-tab{padding:5px 12px;font-size:13px;border-radius:9px;background:transparent;
 border:1px solid transparent;color:var(--muted)}
.rail-tab:hover{color:var(--ink);background:var(--panel)}
.rail-tab.on{background:var(--panel-2);border-color:var(--line-2);color:var(--ink);font-weight:600}
.web-panel{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);
 border-radius:var(--radius);box-shadow:var(--shadow);padding:11px 12px;flex:1 1 auto;min-height:0}
.web-panel svg{display:block;background:var(--web-bg);border-radius:10px}
.web-moved{color:var(--accent-2)}
.web-moved.none{color:var(--muted)}
/* ---- a track opens and shuts ---- */
.track{margin-bottom:9px}
.track-head{display:flex;align-items:baseline;gap:11px;width:100%;text-align:left;flex-wrap:wrap;
 background:transparent;border:0;border-bottom:1px solid var(--line);border-radius:0;
 padding:9px 2px 7px;cursor:pointer;color:var(--ink)}
.track-head:hover{background:rgba(255,255,255,.03);border-color:var(--line-2)}
.track-chev{font-size:19px;line-height:.9;color:var(--muted);width:13px;flex:none;
 transform:rotate(90deg);transition:transform .12s}
.track-head.shut .track-chev{transform:rotate(0deg)}
.track-name{font-family:inherit;font-size:19px;font-weight:600;flex:none}
.track-count{font:600 11px ui-monospace,Consolas,monospace;letter-spacing:.06em;text-transform:uppercase;
 color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:2px 8px;flex:none}
.track-tally{font-size:12.5px;color:var(--accent-2);flex:none}
.track-blurb{font-size:12.5px;color:var(--line-2);flex:1 1 220px;min-width:0}
.track-body{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px;
 padding:11px 0 4px}
.track-body.openings-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}
.track-body[hidden]{display:none}
/* ---- gates ---- */
.course-top.passed{box-shadow:0 0 0 1px var(--good-line),var(--shadow)}
.gate-cell .dash-big{font-size:20px;color:var(--accent-2)}
.course-top.passed .gate-cell .dash-big{color:var(--good)}
.gate-steps{display:flex;gap:4px;margin-top:6px}
.gate-pip{width:17px;height:5px;border-radius:3px;background:var(--track);flex:none}
.gate-pip.lit{background:var(--accent-2)}
.course-top.passed .gate-pip.lit{background:#6fe6a2}
.exam-card{margin-bottom:0}
.exam-pips{display:flex;flex-wrap:wrap;gap:4px;margin:8px 0 9px}
.exam-pip{width:15px;height:15px;border-radius:4px;background:var(--track);flex:none}
.exam-pip.right{background:var(--good-fill)}
.exam-pip.wrong{background:var(--bad-fill)}
.exam-pip.now{background:transparent;box-shadow:inset 0 0 0 2px var(--accent-2)}
/* ---- the ember pile ---- */
.ember-cell .dash-big{color:#ffb454}
.ember-cell .button{align-self:flex-start;margin-top:2px}
.ember-card{margin-bottom:0}
.ember-steps{display:flex;gap:5px;margin:9px 0 7px}
.ember-pip{width:26px;height:6px;border-radius:3px;background:var(--track);flex:none}
.ember-pip.lit{background:#ffb454}
.ember-card .fineprint{margin-top:8px}
/* ---- courses: the taught lessons for one idea, then the drills for the same idea ---- */
.course-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:10px;margin-bottom:6px}
.course-card{display:flex;flex-direction:column;gap:6px;padding:12px 14px;text-decoration:none;color:inherit;
 background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);
 border-top:3px solid var(--tint);border-radius:var(--radius);box-shadow:var(--shadow);
 transition:transform .12s,border-color .12s}
.course-card:hover{transform:translateY(-2px);border-color:var(--tint)}
.course-card.done{box-shadow:0 0 0 1px var(--tint),var(--shadow)}
.course-card strong{font-size:17px}
.course-idea{font-size:12.8px;color:var(--muted);line-height:1.4;height:52px;overflow:hidden;
 display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical}
.big-idea{font-size:16px;color:var(--ink);border-left:3px solid var(--accent);padding-left:11px;margin:6px 0 9px}
.course-bars{display:flex;flex-direction:column;gap:5px}
.course-bar{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--muted)}
.course-bar u{text-decoration:none;text-transform:uppercase;letter-spacing:.07em;font-weight:700;width:48px;flex:none}
.course-bar b{font-variant-numeric:tabular-nums;font-size:11.5px;color:var(--ink);flex:none}
.step-bar{flex:1;height:5px;border-radius:3px;background:var(--track);overflow:hidden;display:block}
.step-bar i{display:block;height:100%;border-radius:3px;transition:width .2s}
.course-top{margin-bottom:6px}
.step-no{display:inline-flex;align-items:center;justify-content:center;width:21px;height:21px;border-radius:50%;
 background:var(--panel-2);border:1px solid var(--line-2);font-size:12px;font-weight:700;color:var(--muted)}
.tile.lesson.done .step-no{background:rgba(111,230,162,.16);border-color:var(--good-line);color:var(--good)}
.tile.lesson.missing{opacity:.6;border-style:dashed}
/* One shelf per tier, pushed sideways. Stacking 47 packs vertically is four screens of scrolling. */
.pack-shelf{display:flex;gap:10px;margin-bottom:6px;overflow-x:auto;padding-bottom:7px;
 scroll-snap-type:x proximity;scrollbar-width:thin}
.pack-shelf .pack-card{flex:0 0 244px;scroll-snap-align:start}
.course-shelf .course-card{flex:0 0 268px;scroll-snap-align:start}
/* The one-course tracks share a row, each keeping its own heading. */
.track-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;align-items:start}
/* In a shared row the heading stacks, because a title and its note side by side in a third of the
   width wrapped "King safety" onto two lines and pushed that column's card below its neighbours.
   The fixed height keeps the three cards on one line whatever the notes say. */
.track-col .pack-heading{margin-top:10px;flex-direction:column;align-items:flex-start;gap:2px;
 min-height:58px}
.track-col .pack-heading>span:first-of-type,.track-col .pack-heading{white-space:normal}
.track-col .pack-heading .tier-note{font-size:12px;line-height:1.35;display:-webkit-box;
 -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.track-col .course-grid{grid-template-columns:1fr}
.openings-shelf .opening-card{flex:0 0 300px;scroll-snap-align:start}
.opening-card.compact .course-idea{-webkit-line-clamp:2;height:34px}
.opening-card.compact .pack-meta{margin-top:-2px}
.pack-card{display:flex;flex-direction:column;gap:5px;padding:11px 13px;text-decoration:none;color:inherit;
 background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);
 border-left:3px solid var(--tint);border-radius:var(--radius);box-shadow:var(--shadow);transition:transform .12s,border-color .12s}
.pack-card:hover{transform:translateY(-2px);border-color:var(--tint)}
.pack-card.fits{box-shadow:0 0 0 1px var(--tint),var(--shadow)}
.pack-top{display:flex;align-items:center;justify-content:space-between}
.pack-glyph{font-size:26px;line-height:1;color:var(--tint)}
.pack-card strong{font-size:15.5px}
.pack-blurb{font-size:12.2px;color:var(--muted);line-height:1.35;height:33px;overflow:hidden;
 display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.pack-fit{font-size:11.5px;font-weight:700;color:var(--tint);text-transform:uppercase;letter-spacing:.06em}
/* Eight squares to a rank, so a pack card says how far up the board you are without a second look. */
.pack-ranks{display:flex;gap:3px}
.pack-ranks .pr{flex:1;height:5px;border-radius:2px;background:var(--track);position:relative;overflow:hidden}
.pack-ranks .pr.part::after,.pack-ranks .pr.full::after{content:'';position:absolute;inset:0;
 width:var(--fill);background:var(--tint)}
.ring{width:52px;height:52px;flex:none}
.range{position:relative;height:6px;border-radius:4px;background:var(--track);margin:2px 0}
.range i{position:absolute;top:0;bottom:0;border-radius:4px;opacity:.85}
.range u{position:absolute;top:-3px;width:2px;height:12px;background:#fbf6ec;box-shadow:0 0 0 1px #0a1119}
.pack-progress .row{align-items:center;gap:12px;margin-bottom:8px}
.pack-progress h2{margin:0}
/* ---- a pack IS a board ----
   64 puzzles, eight ranks of eight, sorted by rating with rank 1 at the bottom. An untouched square
   is a board square and nothing more. Colour is the OUTCOME and only the outcome: green solved
   clean, amber solved with help, red tried and not solved. Red is for a mistake, never for a
   finished piece of work. */
.pack-board{display:grid;grid-template-columns:13px repeat(8,1fr);grid-auto-rows:1fr;gap:2px;
 margin-top:6px;align-items:stretch}
.pack-board>*{aspect-ratio:1}
.pb-cell{display:block;border-radius:3px;text-decoration:none;transition:transform .1s,box-shadow .1s;
 box-shadow:inset 0 0 0 1px rgba(10,17,25,.55)}
.pb-cell.light{background:#4a5d70}
.pb-cell.dark{background:#33455a}
.pb-cell.clean{background:var(--good-fill)}
.pb-cell.hinted{background:#e0ae3d}
.pb-cell.missed{background:var(--bad-fill)}
.pb-cell:hover{transform:scale(1.14);box-shadow:0 0 0 1px #fbf6ec;z-index:2;position:relative}
.pb-rank,.pb-file{font-size:9.5px;color:var(--muted);display:flex;align-items:center;justify-content:center;
 font-variant-numeric:tabular-nums;aspect-ratio:auto;min-height:11px}
.pack-progress .fineprint{margin:6px 0 0}
.grid-key{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:9px;font-size:12px;color:var(--muted)}
.grid-key .key{display:flex;align-items:center;gap:6px}
.key-cell{width:14px;height:14px;border-radius:4px;border:1.5px solid var(--tint);
 background:color-mix(in srgb, var(--tint) 12%, transparent);display:inline-block;flex:none}
.key-cell.done{background:var(--tint)}
.pb-cell.key-cell{width:13px;height:13px;border:0;border-radius:3px;flex:none;aspect-ratio:auto}
.pb-cell.key-cell.open{background:#3f5265}
.pb-cell.key-cell:hover{transform:none;box-shadow:inset 0 0 0 1px rgba(10,17,25,.55)}
/* Your own rating, on every page where you are solving something. */
.level-chip{font-variant-numeric:tabular-nums;font-weight:700}
.level-chip .level-word{font-size:10px;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);
 font-weight:700;margin-right:5px}
.level-chip.empty{color:var(--muted)}
.daily-rating{display:flex;flex-direction:column;gap:1px;margin:9px 0 2px;padding-top:9px;border-top:1px solid var(--line)}
.daily-rating .dash-big{font-size:26px;color:var(--accent)}
/* Whose move it is, beside the task and not only over on the board. */
.task-side{display:flex;align-items:center;gap:7px;margin:0 0 5px;font-size:12.5px;font-weight:700;
 text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
.task-side .dot{width:11px;height:11px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(10,17,25,.7)}
.task-side.white .dot{background:#f4efe6}
.task-side.black .dot{background:#141a22;box-shadow:inset 0 0 0 1px #6d8196}
.domain h2{display:flex;align-items:center;gap:9px;margin-bottom:4px}
.domain .dot{width:12px;height:12px;border-radius:4px;display:inline-block}
.domain .count{margin-left:auto;font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
h3.tier{margin:14px 0 7px;font-size:12.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);
 display:flex;align-items:baseline;gap:10px}
.tier-note{text-transform:none;letter-spacing:0;font-weight:400;font-size:12.5px;color:var(--line-2)}
.tile.lesson strong{font-size:15px}
.pack-heading{margin:18px 0 8px;display:flex;align-items:baseline;gap:12px}
.tile.pack{min-height:132px}
.tile.pack.locked{opacity:.62;cursor:default;border-style:dashed}
.pack-meta{color:var(--muted);font-size:12.5px}
.home-links{display:flex;flex-direction:column;gap:8px}
.home-links .tile{min-height:0;padding:9px 11px;gap:2px}
.home-links h2{margin:0 0 2px}
a.brand{text-decoration:none;color:inherit}
.pack-lock{color:var(--accent-2);font-size:12.5px;font-weight:700}
.tile.lesson.done{border-color:#2f6f57}
.study .board-wrap{width:100%;margin:0;position:relative}
.to-move{display:inline-flex;align-items:center;gap:7px;margin:0 0 8px;padding:4px 10px;border-radius:999px;
 font-size:13px;font-weight:700;letter-spacing:.02em;border:1px solid var(--line-2);background:rgba(255,255,255,.04)}
.to-move .dot{width:11px;height:11px;border-radius:50%;border:1px solid #0a1119}
.task-head{align-items:center;gap:8px;margin-bottom:8px}
.task-head .to-move{margin:0}
.chip.rating{font-size:12px;color:var(--muted)}
.to-move.white .dot{background:#f4ecdc}.to-move.black .dot{background:#1d242c;border-color:#8fa0b0}
.daily-streak .big{margin:2px 0 4px}
/* While the forced answer is on its way. */
.task .waiting{animation:breathe 1.1s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:1}50%{opacity:.45}}
.rail>.task{overflow:auto;flex:1 1 auto;min-height:0}
.moves-col>.cover{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:9px 12px 8px;cursor:pointer;flex:0 0 auto}
.board-head .to-move{margin:0;padding:3px 9px;font-size:12.5px}
.task h2{margin:0 0 6px;font-size:18px}
.task .why{border-left:3px solid var(--accent);padding-left:10px;margin:10px 0 0;color:var(--ink)}
.task .why.hinted{border-left-color:var(--accent-2)}
.task .line-shown{font-weight:700;font-variant-numeric:tabular-nums;margin:8px 0 0}
.summary{margin:10px 0 0;padding:9px 11px;border-radius:10px;background:rgba(111,230,162,.07);border:1px solid rgba(111,230,162,.25)}
.summary .praise{margin:0 0 4px;font-weight:700;color:var(--good)}
.summary p{margin:0;font-size:13.5px}
.weak-row{border-top:1px solid var(--line);padding-top:10px;margin-top:10px}
.weak-row:first-of-type{border-top:0;padding-top:0}
.weak-name{margin:0 0 3px;font-weight:700}.weak-name::first-letter{text-transform:uppercase}
.weak-row .button{margin-top:6px}
.task .pattern-shown{margin:6px 0 0;color:var(--defend-2);font-weight:700;text-transform:capitalize}
.task .row{margin-top:12px}
.crumb{margin:0;font-size:13px;color:var(--muted);white-space:nowrap}
.crumb a::before{content:'‹ ';opacity:.7}
.board-strip{margin:0 2px 8px}
.board-head{display:flex;align-items:center;gap:6px;height:30px;flex-wrap:nowrap;overflow:hidden}
.board-taken{display:flex;gap:9px;height:28px;align-items:center;overflow:hidden;white-space:nowrap}
/* Anything that can lose characters rather than push the engine reading off the row. */
.chip.result,.advantage{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.transport{display:flex;gap:4px;margin-right:3px}
.transport button{padding:3px 9px;font-size:13.5px;line-height:1.25;border-radius:8px}
.legend-col{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:11px 12px;overflow:auto;height:var(--column)}
.acc{border-bottom:1px solid var(--line);padding-bottom:10px;margin-bottom:10px}
.acc:last-child{border-bottom:0;padding-bottom:0;margin-bottom:0}
.acc>summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:7px;
 font-size:12.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);font-weight:700;margin-bottom:9px}
.acc>summary::-webkit-details-marker{display:none}
.acc>summary::before{content:'';width:0;height:0;border-left:5px solid var(--line-2);border-top:4px solid transparent;border-bottom:4px solid transparent;transition:transform .15s}
.acc[open]>summary::before{transform:rotate(90deg)}
.acc>summary:hover::before{border-left-color:var(--accent)}
.acc>summary:hover{color:var(--ink)}

.legend-col .lenses{flex-direction:column;align-items:stretch;gap:4px;margin-top:0}
.legend-col .lens{justify-content:flex-start}
.swatch{width:26px;height:16px;flex:none;margin-top:1px}
.chip{background:var(--panel-2);border:1px solid var(--line);border-radius:999px;padding:3px 11px;font-size:12.5px;color:var(--muted);white-space:nowrap}
.chip.strong{color:var(--ink);border-color:var(--line-2)}
.chip.alert{color:var(--accent-ink);background:var(--accent-2);border-color:var(--accent-2);font-weight:650}
.chip.result{color:var(--accent-ink);background:var(--accent);border-color:var(--accent);font-weight:700}
.sec-result{border-left-color:var(--accent)}
.sec-result h4{color:var(--accent)}
.advantage{display:flex;align-items:center;gap:5px;flex:0 0 auto}
.adv-sep{color:var(--muted);font-size:11px}
.adv-bar{position:relative;flex:1;height:10px;border-radius:999px;background:linear-gradient(180deg,var(--track),var(--bg-2));border:1px solid var(--line);overflow:hidden}
.adv-bar i{position:absolute;inset:0 auto 0 0;background:linear-gradient(180deg,#fbf4e6,#d8cbb2);display:block;transition:width .2s}
.adv-bar u{position:absolute;left:50%;top:-2px;bottom:-2px;width:1px;background:rgba(255,255,255,.45)}
.adv-label{font-size:11px;text-transform:uppercase;letter-spacing:.07em;color:var(--muted)}
/* Under this width the strip's own row runs out of room before the engine reading, so the words
   go and the numbers stay. */
@media (max-width:1400px){.wide-only{display:none}}
.adv-diff{font-weight:600}
.adv-num{font-size:12.5px;font-variant-numeric:tabular-nums;color:var(--muted)}
.adv-num.white{color:var(--side-white)}.adv-num.black{color:var(--side-black)}
.adv-diff{font-size:12.5px;font-variant-numeric:tabular-nums;color:var(--muted);white-space:nowrap}
.adv-diff.up{color:#f4ead6}.adv-diff.down{color:#bcd6ea}
.board-taken .taken{font-size:15px;line-height:1;letter-spacing:-.5px}
.board-taken .white-took{color:#f0e6d4}.board-taken .black-took{color:#9fb3c6}
.controls{margin-top:9px;gap:7px}
.controls button{padding:7px 12px}

/* Every column stretches to the board panel, so their bottoms line up. Inside, the fixed panels
   keep their size and one panel takes the slack and scrolls. */
.moves-col{display:flex;flex-direction:column;gap:10px;min-width:0;height:var(--column);overflow:auto;scrollbar-width:thin}
.moves-col>.acc,.moves-col>.chart-panel{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);border-radius:var(--radius);padding:10px 12px;box-shadow:var(--shadow);margin:0}
/* <details> does not pass flex sizing to its content in Chromium, so the move list keeps an
   explicit height and the glance panel takes whatever is left. */
.moves-col>.acc{border-bottom:1px solid var(--line);flex:0 0 auto}
.moves-col>.chart-panel{flex:1 1 auto;min-height:0;overflow:auto}
.chart-panel h3{margin:0 0 8px}
.glance{margin-top:9px;display:flex;flex-direction:column;gap:3px}
.glance-row{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--muted);align-items:baseline}
.glance-row b{color:var(--ink);font-weight:600;text-align:right;font-variant-numeric:tabular-nums}
.moves{list-style:none;margin:0;padding:0;max-height:28vh;overflow:auto;scrollbar-width:thin}
.moves li{display:flex;gap:4px;align-items:center;padding:1px 0}
.moves .no{color:var(--muted);width:22px;font-variant-numeric:tabular-nums;font-size:12px;flex:none}
.san{background:transparent;border:1px solid transparent;padding:3px 6px;border-radius:7px;min-width:58px;text-align:left;font-variant-numeric:tabular-nums;font-size:14px;white-space:nowrap}
.san:hover{background:var(--panel-2);border-color:transparent}
.san.current{background:linear-gradient(180deg,var(--primary-top),var(--primary-bot));border-color:var(--primary-line);color:var(--primary-ink)}

.rail{display:flex;flex-direction:column;gap:10px;min-width:0;height:var(--column)}
.rail>section{background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:12px 14px;min-width:0}
.rail>.coach{overflow:auto;flex:1 1 auto;min-height:0}
/* King cover meter. Fixed height so the column keeps the height the board panel measured. */
.rail>.cover{flex:0 0 auto;background:linear-gradient(180deg,var(--panel),var(--bg-2));border:1px solid var(--line);
 border-radius:var(--radius);box-shadow:var(--shadow);padding:9px 12px 8px;cursor:pointer}
.rail>.cover h3{margin:0 0 6px}
.cover-key{margin:0 0 6px;font-size:11px;color:var(--muted);line-height:1.3}
.cover-key .hold{color:var(--defend-2)}.cover-key .press{color:var(--attack)}
.cover-row{padding:3px 0}
.cover-row+.cover-row{border-top:1px solid var(--line);margin-top:3px}
.cover-line{display:flex;align-items:center;gap:8px}
.cover-king{font-size:19px;line-height:1;width:16px;text-align:center}
.cover-bar{flex:1 1 auto;min-width:0;height:8px;border-radius:5px;background:var(--track);display:flex;overflow:hidden;box-shadow:inset 0 0 0 1px rgba(255,255,255,.04)}
.cover-bar i{background:linear-gradient(90deg,var(--defend),var(--defend-2))}
.cover-bar.wide{gap:0}
.cover-bar .own-white{background:linear-gradient(90deg,#e8dcc4,#f7c98b)}
.cover-bar .own-level{background:#4a5b6b}
.cover-bar .own-black{background:linear-gradient(90deg,#7fa2e6,#5b79bd)}
.cover-held{color:var(--attack)}
.coverage-meter{margin-top:8px;padding-top:8px;border-top:1px solid var(--line)}
.eval-cap{position:absolute;left:50%;transform:translateX(-50%);width:19px;height:19px;border-radius:50%;
 display:flex;align-items:center;justify-content:center;font-size:13px;line-height:1;
 font-family:"Segoe UI Symbol","Noto Sans Symbols 2",serif}
.eval-cap.black{top:0;background:#141a22;color:#f4ecdc;border:1.5px solid #55677c}
.eval-cap.white{bottom:0;background:#f4ecdc;color:#141a22;border:1.5px solid #b9ab8e}
.cover-bar u{background:linear-gradient(90deg,var(--attack),var(--bad));margin-left:auto}
.cover-nums{font-size:12.5px;font-variant-numeric:tabular-nums;color:var(--muted);white-space:nowrap}
.cover-nums .hold{color:var(--defend-2)}.cover-nums .press{color:var(--attack)}
.cover-out.none{color:var(--bad);font-weight:700}
.cover-note{margin:2px 0 0 24px;font-size:11.5px;color:var(--muted);line-height:1.3;height:15px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.cover-row.pressed .cover-king{text-shadow:0 0 9px rgba(255,106,82,.75)}
.chart-panel{flex:none}
#chart{width:100%;height:auto;display:block;cursor:pointer}
.chart-key{display:flex;flex-wrap:wrap;gap:4px 12px;margin:8px 0 0;font-size:11.5px;color:var(--muted)}
.chart-key .key{display:inline-flex;align-items:center;gap:6px}
.chart-key i{width:10px;height:10px;border-radius:2px;display:inline-block}
.chart-panel .fineprint{font-size:10.5px;margin:7px 0 0;line-height:1.35}
.chip.engine{border-color:var(--engine);color:var(--engine-ink);flex:0 0 auto}
.chip.engine.strong{background:rgba(84,220,201,.14)}
.badge{margin-left:5px;font-size:11.5px;font-weight:800;vertical-align:top}
.badge.blunder{color:var(--bad)}.badge.mistake{color:var(--mistake)}.badge.inaccuracy{color:var(--inaccuracy)}.badge.best{color:var(--good)}
.sec-engine{border-left-color:var(--engine)}
.sec-engine h4{color:#7fe4d6}
.coach h2{font-size:17px;color:var(--accent);margin-bottom:6px}
.coach .lines p{margin:0 0 11px}
.sec{margin:0 0 12px;padding-left:10px;border-left:3px solid var(--line-2)}
.sec h4{margin:0 0 4px;font-size:11.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);font-weight:700}
.sec ul{margin:0;padding-left:16px}
.sec li{margin:0 0 5px;line-height:1.45;
 /* name a symbol font before any emoji font, or the browser draws the White queen as a solid emoji */
 font-family:system-ui,-apple-system,"Segoe UI","Segoe UI Symbol","Noto Sans Symbols 2",sans-serif;font-variant-emoji:text}
.sec li::marker{color:var(--line-2)}
.sec-move{border-left-color:var(--accent)}
.sec-move h4{color:var(--accent)}
.sec-gained{border-left-color:#4fbf87}
.sec-gained h4{color:var(--good)}
.sec-lost{border-left-color:#b7745f}
.sec-lost h4{color:#ffb4a2}
.sec-watch{border-left-color:var(--accent-2)}
.sec-watch h4{color:var(--accent-2)}
.sec-position{border-left-color:#4a6a86}
.coach .idea{font-size:16.5px;color:var(--accent-2);margin:0 0 12px}
.tags{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 10px}
.tag{font-size:11.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--accent);background:rgba(84,220,201,.08);border:1px solid rgba(84,220,201,.3);border-radius:999px;padding:2px 9px}
.quiz{margin-top:14px;padding-top:14px;border-top:1px solid var(--line)}
/* Fixed height, scrolling inside: a box that grows with its question changed the board panel's
   height on every move, which shifted every column and the page with it. */
/* Exploring a what if: the board is framed so it never looks like the game itself. */
.board-panel.exploring{border-color:#ffc46b;box-shadow:0 0 0 1px rgba(255,196,107,.35),var(--shadow)}
.chip.exploring{background:var(--accent-wash);border-color:var(--accent-2);color:var(--accent-2);font-weight:700}
.quiz.under-board.explore,.board-panel.exploring .quiz.under-board{border-left-color:#ffc46b;background:rgba(255,196,107,.06)}
.explore-head{align-items:center;gap:9px;flex-wrap:nowrap}
.explore-buttons{display:flex;gap:6px;margin-left:auto;flex:0 0 auto}
.explore-buttons button{padding:4px 10px;font-size:12.5px}
/* The slot is a fixed height, so the reading has to fit a narrow column without scrolling. */
.board-panel.exploring .quiz.under-board .hint{font-size:13px;line-height:1.35}
.board-panel.exploring .quiz.under-board h3{font-size:12px}
.explore-line{font-weight:700;font-size:14px;color:#ffd79a;font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.quiz.under-board .fineprint{margin:4px 0 0;font-size:10.5px;line-height:1.3}
.quiz.under-board b.worse{color:var(--attack)}.quiz.under-board b.better{color:var(--good)}
.branch-line{background:rgba(255,196,107,.07)}
.branch-line .no{color:#ffc46b}
.san.branch{color:#ffd79a;font-style:italic;text-align:left;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.quiz.under-board{margin:10px 2px 0;padding:9px 12px;border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:10px;background:rgba(84,220,201,.05);height:142px;overflow:auto;scrollbar-width:thin}
.quiz.under-board h3{margin:0 0 4px}
.quiz.under-board .prompt{margin:0 0 6px;font-size:15px}
.quiz.under-board .row{margin-top:6px;gap:8px}
.quiz.under-board .row .hint{order:2;margin:0}
.quiz.under-board .hint{margin:0}
.hint{color:var(--muted);font-size:14px}
.hint.shown{color:var(--accent-2);margin-top:8px}
.good{color:var(--good)}.bad{color:var(--warn)}

.lenses{display:flex;flex-wrap:wrap;gap:5px;margin-top:10px}
.lens{display:inline-flex;align-items:center;gap:6px;background:var(--panel-2);border:1px solid var(--line);border-radius:999px;padding:4px 10px;font-size:12.5px;color:var(--muted);cursor:pointer}
.lens:hover{color:var(--ink);border-color:var(--accent)}
.lens:has(input:checked){color:var(--ink);border-color:var(--accent);background:var(--accent-wash)}
.legend{display:flex;flex-direction:column;gap:7px;font-size:12px;color:var(--muted);line-height:1.35}
.legend .key{display:flex;align-items:flex-start;gap:7px}
.legend .key.hint{color:#8296a9;font-style:italic}
.legend i{width:10px;height:10px;border-radius:3px;display:inline-block;flex:none}
.big{font-size:34px;margin:0}
.fineprint{color:var(--muted);font-size:13px;max-width:80ch}
ul{margin:0;padding-left:20px}li{margin:4px 0}
.moves-inline{margin-top:12px;gap:6px}
.moves-inline .san{min-width:0}

@media (max-width:1400px){.study{grid-template-columns:224px calc(var(--board) + 45px) 172px minmax(280px,1fr);gap:9px}}
/* Below this the four columns stop fitting: the chart and coach move under the board, and the
   board gives back height so the page still does not scroll. */
@media (max-width:1180px){
 .study{grid-template-columns:224px calc(var(--board) + 45px) 172px;gap:9px}
 .board-wrap{width:min(48vh,100%)}
 .moves{max-height:calc(48vh + 8px)}.legend-col{max-height:calc(48vh + 44px)}
 .rail{grid-column:1 / -1;flex-direction:row;max-height:none}.rail>section{flex:1;max-height:none}
}
@media (max-width:1000px){
 .study{grid-template-columns:1fr;align-items:start;--board:min(68vh,100%)}
 .moves-col,.rail,.legend-col{height:auto}
 .board-head{height:auto;flex-wrap:wrap}
 .board-wrap{width:min(68vh,100%)}
 .quiz.under-board{height:auto;overflow:visible}
 .moves{max-height:190px}
 .board-panel{order:1}.rail{order:2;flex-direction:column}.legend-col{order:3}.moves-col{order:4}
 .moves-col>.chart-panel,.rail>.coach,.legend-col{overflow:visible}
}
@media (max-width:560px){main{padding:14px}h1{font-size:22px}.top{padding:10px 14px}.board-wrap{width:100%}.board-head{height:auto;flex-wrap:wrap}}

/* ---- the games library ----
   Three collections behind tabs, and every game is a row that opens. A row shut is one line you can
   scan down: when it happened, what it is called, who played, how it went. A row open carries the
   note, the marked moves and the buttons. The date leads, because the game you are looking for is
   nearly always the one you just played. */
.collections{padding:0;overflow:hidden}
.lib-tabs{display:flex;gap:2px;padding:8px 8px 0;border-bottom:1px solid var(--line);background:var(--bg-2);flex-wrap:wrap}
.lib-tab{background:transparent;border:1px solid transparent;border-bottom:none;color:var(--muted);
 padding:9px 16px;border-radius:10px 10px 0 0;font-size:14.5px;cursor:pointer;display:flex;align-items:center;gap:7px}
.lib-tab:hover{color:var(--ink);background:var(--panel)}
.lib-tab.on{background:var(--panel-2);color:var(--ink);border-color:var(--line-2);border-bottom:1px solid var(--panel-2);margin-bottom:-1px}
.tab-count{font-size:11.5px;color:var(--muted);background:var(--bg);border:1px solid var(--line);border-radius:999px;padding:1px 7px}
.lib-tab.on .tab-count{color:var(--ink);border-color:var(--line-2)}

.game-list{padding:10px 12px 14px;display:flex;flex-direction:column;gap:7px}
.game-list[hidden]{display:none}
.game-row{border:1px solid var(--line);border-radius:11px;background:var(--panel);overflow:hidden}
.game-row.starred{border-color:var(--accent-2)}
.game-head{width:100%;display:grid;grid-template-columns:minmax(120px,150px) minmax(0,1.4fr) minmax(0,1fr) auto;
 gap:14px;align-items:center;text-align:left;background:transparent;border:0;color:var(--ink);
 padding:11px 14px;cursor:pointer;font-size:15px}
.game-head:hover{background:var(--panel-2)}
.game-head.on{background:var(--panel-2);border-bottom:1px solid var(--line)}
/* The date and how long ago it was are two lines. The column has one child, the wrapper, so the
   stacking has to be on the wrapper or they run together as "15 Sep 20266 days ago". */
.game-when{display:flex;flex-direction:column;line-height:1.3}
.game-when>span{display:flex;flex-direction:column}
.game-when b{font-size:14px;color:var(--ink);font-weight:600}
.game-when .ago{font-size:11.5px;color:var(--muted)}
.game-title{font-weight:600;display:flex;align-items:center;gap:7px;min-width:0}
.game-title i{font-style:normal;font-size:12px;color:var(--accent-2);flex:none}
.game-line{color:var(--muted);font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.game-chips{display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}
.game-body{padding:12px 14px 14px;display:flex;flex-direction:column;gap:11px;background:var(--bg-2)}
.game-body[hidden]{display:none}
.game-watch{margin:0;color:var(--ink);font-size:14px;max-width:80ch;line-height:1.5}

/* Result at a glance. Red is for a loss and nothing else on this page, which is the same rule the
   pack boards follow. */
.chip.won{color:var(--good);border-color:var(--good-line)}
.chip.lost{color:var(--warn);border-color:var(--bad-line)}
.chip.drawn,.chip.unfinished{color:var(--muted)}
.chip.quiet{font-size:11.5px;opacity:.85}
.chip.side{display:inline-flex;align-items:center;gap:4px}
.chip.side.white{color:var(--side-white)}
.chip.side.black{color:#b9c7d4}

.field{display:flex;flex-direction:column;gap:5px;font-size:13px;color:var(--muted)}
.game-note{width:100%;background:var(--bg);color:var(--ink);border:1px solid var(--line);border-radius:9px;
 padding:9px 11px;font:14px/1.5 inherit;resize:vertical}
.game-note:focus{outline:2px solid var(--accent);outline-offset:1px}

.marks h4{margin:0 0 5px;font-size:13px;color:var(--muted);font-weight:600}
.mark-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.mark-list li{display:flex;align-items:center;gap:9px;font-size:13.5px}
.mark-go{background:var(--panel-2);border:1px solid var(--line-2);color:var(--accent);border-radius:7px;
 padding:2px 9px;cursor:pointer;font:600 13px/1.4 inherit;flex:none;min-width:58px}
.mark-go:hover{background:var(--accent);color:var(--accent-ink)}
.mark-label{color:var(--muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tiny{background:transparent;border:1px solid var(--line);color:var(--muted);border-radius:6px;
 width:22px;height:22px;line-height:1;cursor:pointer;flex:none}
.tiny:hover{color:var(--warn);border-color:var(--bad-line)}
button.danger:hover{color:var(--warn);border-color:var(--bad-line)}

/* ---- adding a game ---- */
.add-game{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:18px}
.add-col{display:flex;flex-direction:column;gap:8px;min-width:0}
.add-col h3{margin:0;font-size:15px}
.add-col textarea{width:100%;background:var(--bg);color:var(--ink);border:1px solid var(--line);
 border-radius:10px;padding:10px 12px;font:13px/1.5 ui-monospace,"Cascadia Code",Consolas,monospace;resize:vertical}
.title-input,.user-input{background:var(--bg);color:var(--ink);border:1px solid var(--line);
 border-radius:9px;padding:9px 12px;font:15px/1.4 inherit;min-width:0;flex:1}
.title-input:focus,.user-input:focus{outline:2px solid var(--accent);outline-offset:1px}
.muted{color:var(--muted)}
.small{font-size:12.5px;line-height:1.5}

/* ---- where the losses sit ---- */
.weakness{margin:0 0 4px;padding:12px 14px}
.weakness h3{margin:0 0 4px;font-size:15px}
.weak-list{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.weak-list li{display:flex;align-items:center;gap:9px;font-size:14px;flex-wrap:wrap}
.weak-record{color:var(--warn);font-size:13px}

@media (max-width:820px){
 .game-head{grid-template-columns:1fr;gap:5px}
 .game-chips{justify-content:flex-start}
 .game-line{white-space:normal}
}

/* ---- guess the move, and marking a position ----
   Both sit in a strip under the board. The guess strip is quiet when the feature is off: one
   checkbox, no colour, nothing claiming attention on a board you are just reading through. */
.guess-box{display:flex;flex-direction:column;gap:7px;margin-top:8px;padding:8px 11px;
 border:1px solid var(--line-2);border-radius:11px;background:var(--panel-2)}
/* Off means gone. The study screen is sized to the board, so a panel that sits there whether or not
   you are using it spends height you never asked to spend. */
.guess-box[hidden]{display:none}
.guess-name{font-size:14px;font-weight:600;color:var(--accent)}
.guess-btn{font-size:13px;padding:3px 11px}
.guess-btn.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.guess-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.guess-side{display:flex;align-items:center;gap:6px}
.guess-side .chip{cursor:pointer;background:var(--bg);border-color:var(--line)}
.guess-side .chip.on{border-color:var(--accent);color:var(--ink);background:var(--panel)}
.guess-score{margin-left:auto;font-size:12.5px;color:var(--muted)}
.guess-ask{margin:0;font-size:14.5px;color:var(--accent)}
.guess-yes{margin:0;font-size:14.5px;color:var(--good)}
.guess-shown{margin:0;font-size:13.5px;color:var(--muted)}
.guess-no{display:flex;flex-direction:column;gap:6px}
.guess-no p{margin:0;font-size:14px}
.guess-no b{color:var(--accent-2)}
.guess-no .row{gap:7px}
.guess-box button[disabled]{opacity:.45;cursor:not-allowed}

/* The flag button in the transport, and the label strip it opens. */
.mark-btn{color:var(--accent-2)}
.marker{display:flex;align-items:center;gap:8px;margin-top:8px;padding:8px 11px;flex-wrap:wrap;
 border:1px solid var(--accent-2);border-radius:11px;background:var(--panel-2)}
.marker[hidden]{display:none}
.mark-at{font-size:13px;color:var(--accent-2);font-weight:600;flex:none}
.mark-input{flex:1;min-width:180px;background:var(--bg);color:var(--ink);border:1px solid var(--line);
 border-radius:9px;padding:8px 11px;font:14.5px/1.4 inherit}
.mark-input:focus{outline:2px solid var(--accent);outline-offset:1px}

/* ---- a player you follow ----
   Their games sit under their handle with their record beside it, so the tab reads as "here is
   this person's recent form" rather than as a heap of games with no owner. */
.player-block{border:1px solid var(--line);border-radius:12px;background:var(--bg-2);padding:10px 11px;
 display:flex;flex-direction:column;gap:6px}
.player-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.player-head h3{margin:0;font-size:16px}
.player-head h3 a{color:var(--accent);text-decoration:none}
.player-head h3 a:hover{text-decoration:underline}
.player-record{color:var(--muted);font-size:13px;flex:1;min-width:0}
.follow-input{margin-top:2px}

/* A move you have not been shown keeps its place in the list without naming itself. */
.san.blind{color:var(--line-2);letter-spacing:2px;cursor:default;background:transparent;border-color:transparent}

/* The glance panel, covered while you are guessing. A class rather than a rebuild: the sentence
   ribbon and its caption are children of this panel, and replacing its contents tore them out of
   the document so they never came back when guessing was switched off. */
.blind-note{display:none;margin:0;color:var(--muted);font-size:12.5px;line-height:1.5}
.chart-panel.blind>*:not(h3):not(.blind-note){display:none}
.chart-panel.blind .blind-note{display:block}
.blind-hint{color:var(--muted);font-weight:400}

/* Export all sits in the tab row but is an action, not a collection, so it is pushed to the end
   and does not take the selected state the tabs use. */
.lib-tab.export-all{margin-left:auto;color:var(--accent)}
.lib-tab.export-all:hover{background:var(--panel-2)}

/* ---- narrowing a long list ----
   A bar above a collection: search, then result and colour as chips. It sits inside the list so it
   scrolls with what it is filtering rather than floating above an unrelated tab. */
.filter-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:2px 2px 8px;
 border-bottom:1px solid var(--line);margin-bottom:4px}
.filter-text{flex:1 1 220px;min-width:170px;background:var(--bg);color:var(--ink);
 border:1px solid var(--line);border-radius:9px;padding:7px 11px;font:14px/1.4 inherit}
.filter-text:focus{outline:2px solid var(--accent);outline-offset:1px}
.filter-chips{display:flex;gap:4px;flex-wrap:wrap}
.filter-chip{cursor:pointer;background:var(--bg);border-color:var(--line);font-size:12px}
.filter-chip:hover{color:var(--ink)}
.filter-chip.on{border-color:var(--accent);color:var(--ink);background:var(--panel-2)}
.filter-count{font-size:12.5px;color:var(--muted);margin-left:auto;white-space:nowrap}
.filter-count.none{color:var(--warn)}
.clear-filter{font-size:12.5px;padding:3px 10px}

/* A followed player folds up, so following three people is three lines rather than three scrolls. */
.player-fold{background:transparent;border:1px solid var(--line);color:var(--muted);
 width:24px;height:24px;line-height:1;border-radius:7px;cursor:pointer;flex:none;font-size:14px}
.player-fold:hover{color:var(--ink);border-color:var(--line-2)}
.player-fold.on{color:var(--accent);border-color:var(--line-2)}
.player-games{display:flex;flex-direction:column;gap:6px;margin-top:4px}
.player-games[hidden]{display:none}

/* ---- playing the engine ----
   Same shape as the guess strip: gone when off, because the study screen is sized to the board. */
.bot-box{display:flex;flex-direction:column;gap:7px;margin-top:8px;padding:8px 11px;
 border:1px solid var(--accent);border-radius:11px;background:var(--panel-2)}
.bot-box[hidden]{display:none}
.bot-head{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.bot-name{font-size:14px;font-weight:600;color:var(--accent)}
.bot-sides{display:flex;align-items:center;gap:6px}
.bot-sides .chip{cursor:pointer;background:var(--bg);border-color:var(--line)}
.bot-sides .chip.on{border-color:var(--accent);color:var(--ink);background:var(--panel)}
.bot-stop{margin-left:auto;font-size:12.5px}
.bot-levels{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.bot-level{cursor:pointer;background:var(--bg);border-color:var(--line);font-size:12px}
.bot-level:hover{color:var(--ink)}
.bot-level.on{border-color:var(--accent);color:var(--ink);background:var(--panel)}
.bot-ask{margin:0;font-size:14.5px;color:var(--accent)}
.bot-thinking{margin:0;font-size:14px;color:var(--muted);animation:breathe 1.1s ease-in-out infinite}
.bot-over{margin:0;font-size:15px;font-weight:600;color:var(--accent-2)}
.bot-saved{font-size:13.5px;color:var(--good)}
.bot-error{margin:0;font-size:13.5px;color:var(--warn)}
.bot-caption{margin:0}
.bot-btn{font-size:13px;padding:3px 11px}
.bot-btn.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.play-bot h2{margin:0 0 4px}
.play-bot p{margin:0 0 8px;max-width:80ch}

.chip.playing{color:var(--accent);border-color:var(--accent)}
.quiz[hidden]{display:none}

/* The end of a game should look like the end of a game, not like one more line of body text. */
.bot-result{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding:6px 10px;border-radius:9px;
 border:1px solid var(--line-2);background:var(--bg-2)}
.bot-result strong{font-size:19px;letter-spacing:.01em}
.bot-result-why{font-size:13px;color:var(--muted)}
.bot-result.won{border-color:var(--good-line)}
.bot-result.won strong{color:var(--good)}
.bot-result.lost{border-color:var(--bad-line)}
.bot-result.lost strong{color:var(--warn)}
.bot-result.drawn strong,.bot-result.stopped strong{color:var(--muted)}
.bot-backs{margin:0}
.bot-rated{margin:0;font-size:13.5px;color:var(--accent)}
p.bot-rated.muted{color:var(--muted)}
.bot-yours{font-size:12px;color:var(--muted);margin-left:auto;white-space:nowrap}
.chip.finished{color:var(--accent-2);border-color:var(--accent-2)}

.transport .nav[disabled]{opacity:.35;cursor:not-allowed}


/* ---- the theme picker ----
   A palette button at the end of the nav, opening a short list. Backdrop click and Escape close it,
   the same rule every menu here follows. */
.theme-wrap{position:relative;display:flex;align-items:center}
.theme-btn{background:transparent;border:1px solid transparent;color:var(--muted);border-radius:999px;
 width:36px;height:36px;font-size:17px;cursor:pointer;line-height:1}
.theme-btn:hover,.theme-btn[aria-expanded="true"]{color:var(--ink);background:var(--panel);border-color:var(--line-2)}
.theme-menu{position:absolute;right:0;top:calc(100% + 8px);min-width:200px;background:var(--panel);
 border:1px solid var(--line-2);border-radius:12px;box-shadow:var(--shadow);padding:6px;z-index:20}
.theme-menu[hidden]{display:none}
.theme-menu h4{margin:4px 8px 6px;font-size:11.5px;text-transform:uppercase;letter-spacing:.09em;color:var(--muted)}
.theme-opt{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:transparent;
 border:1px solid transparent;color:var(--ink);padding:8px 10px;border-radius:9px;cursor:pointer;font:14px/1.3 inherit}
.theme-opt:hover{background:var(--panel-2)}
.theme-opt.on{border-color:var(--accent)}
.theme-swatch{width:26px;height:16px;border-radius:5px;border:1px solid rgba(255,255,255,.18);flex:none}
.theme-opt small{display:block;color:var(--muted);font-size:11.5px}


/* The piece web's labels and group rings, by class rather than inline fill, so a theme can reach
   them. Inline they were light grey on a dark box, and on the Light theme the box went pale and the
   labels stayed light: unreadable. */
.web-label{fill:var(--muted)}
.web-count{fill:var(--ink)}
.web-ring{stroke:var(--line-2)}
