/* Shell tokens (colour, type, spacing, radii) come from /brand/brand.css.
   This file owns only the Connect Four accent and board-specific colours. */
:root{--accent:#f4c16e;--accent-deep:#cf9433;--accent-ink:#271e0e;--disc-human:var(--human);--disc-jev:var(--jev);--board-face:#2c3756;--board-face-2:#222c47;--board-edge:#43506c;--hole:#0d1427}
*{box-sizing:border-box}body{margin:0;background:radial-gradient(ellipse at 0 4%,#211c394d,transparent 45%),var(--bg);color:var(--text);line-height:1.5;font-size:var(--fs-sm)}button,input,select{font:inherit}button,a,input,select,summary{touch-action:manipulation}button,a{ -webkit-tap-highlight-color:transparent}button{cursor:pointer}button:disabled{opacity:.45;cursor:not-allowed}a{color:inherit;text-decoration:none}[hidden]{display:none!important}button{color:inherit}h2{font-size:var(--fs-xl);line-height:1.25;margin-bottom:var(--s2);font-weight:640;letter-spacing:-.4px}h3{font-size:var(--fs-md);font-weight:620}pre{overflow:auto;max-height:320px;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.7 ui-monospace,monospace;color:var(--muted);background:var(--bg);padding:var(--s3);border-radius:var(--radius-sm)}.muted{color:var(--muted)}.small-text{font-size:var(--fs-xs)}.fineprint{font-size:var(--fs-xs);color:var(--muted);margin:var(--s3) 0 0}/* One set of nav tabs + account controls. They live in #jv-controls inside the
   sheet; brand.js moves that node into the header row at >=900px. */
.nav-link{border:0;background:none;color:var(--muted);font-size:var(--fs-sm);text-align:left}
.nav-link.active{background:var(--raised);color:var(--accent)}
.account{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap;font-size:var(--fs-xs);color:var(--muted);padding:var(--s2) var(--s3)}
#identity{color:var(--text);flex:none;max-width:16ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.online-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--disc-jev);flex-shrink:0}.button{border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--raised);font-weight:580;padding:var(--s3) var(--s4);min-height:44px;font-size:var(--fs-xs);transition:background .15s,transform .15s;display:inline-flex;align-items:center;justify-content:center;gap:var(--s2)}@media(hover:hover){.button:not(:disabled):hover{background:#303a54}}.button:not(:disabled):active{background:#303a54}.button.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}@media(hover:hover){.button.primary:not(:disabled):hover{background:#f7d094}}.button.primary:not(:disabled):active{background:#f7d094}.button.small{font-size:var(--fs-xs);padding:var(--s2) var(--s3);min-height:38px}.button.secondary{background:transparent}.button.danger{color:var(--danger);border-color:#814852}.eyebrow{font-size:var(--fs-2xs);letter-spacing:2px;color:var(--accent);font-weight:650;margin-bottom:var(--s3)}.hero{display:flex;justify-content:space-between;gap:var(--s4);align-items:flex-end;padding:var(--s3) 0 0}.intro{font-size:var(--fs-xs);color:var(--muted);margin:0}.hero-meta{display:flex;flex-direction:column;align-items:flex-end;gap:var(--s2);color:var(--muted);font-size:var(--fs-2xs);margin-bottom:2px}.pill{display:inline-flex;align-items:center;gap:var(--s2);border:1px solid var(--line);border-radius:var(--radius-pill);padding:var(--s1) var(--s2);font-size:var(--fs-2xs);font-weight:650;letter-spacing:1px;color:var(--accent);white-space:nowrap}.pill.subtle{color:var(--muted);font-size:var(--fs-2xs);padding:4px var(--s2)}.notice{padding:var(--s3) var(--s4);border-radius:var(--radius-sm);background:#362d24;border:1px solid #705138;color:#f8d499;margin:0 0 var(--s4);font-size:var(--fs-xs)}.notice.info{background:#1a243d;border-color:#364466;color:#c6d1e9}.play-layout{display:grid;grid-template-columns:minmax(0,1.63fr) minmax(300px,1fr);gap:var(--s5)}.game-card,.analysis-card,.activity-card,.dashboard-card{}.game-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--s4);gap:var(--s3)}.player-label{display:flex;align-items:center;gap:var(--s2)}.player-label strong{font-size:var(--fs-xs);font-weight:630;display:block}.player-label span:not(.disc-key){font-size:var(--fs-2xs);display:block;color:var(--muted)}.player-label.opponent{text-align:right}.disc-key{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;color:#141d29;font-size:var(--fs-xs);font-weight:750;flex-shrink:0}.human{background:var(--disc-human)}.jev{background:var(--disc-jev)}/* Fits width AND height: never taller than the viewport minus the chrome.
   7 columns x 6 rows, so the board is 7/6 wide, not square. */
.board-shell{--fit-max:32rem;--fit-reserve:23rem;--fit-ratio:1.1667;margin:0 auto}.column-controls{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:var(--s2);padding:0 var(--s3) var(--s2)}.column-button{min-height:var(--tap);background:transparent;border:1px solid transparent;color:var(--muted);border-radius:var(--radius-sm);font:12px ui-monospace,monospace}/* Hover is decorative here; .selected (set by app.js on pointer, focus and key)
   carries the same state, so touch never leaves a stuck hover. */
@media(hover:hover){.column-button:not(:disabled):hover{background:#30344b;color:var(--disc-human);border-color:#7a624355}}.column-button.selected:not(:disabled),.column-button:not(:disabled):active{background:#30344b;color:var(--disc-human);border-color:#7a624355}.column-button.selected:not(:disabled):after{content:'↓';display:inline-block;margin-left:var(--s1);color:var(--disc-human)}.board{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:var(--s2);padding:var(--s3);background:linear-gradient(150deg,#2c3756,#222c47);border:1px solid #43506c;border-radius:var(--radius-lg);box-shadow:0 12px 24px #05091045,inset 0 1px 0 #ffffff10;aspect-ratio:7/6}.cell{aspect-ratio:1;border-radius:50%;background:#0d1427;box-shadow:inset 0 3px 7px #01061399,0 1px 0 #ffffff0b;position:relative;display:flex;align-items:center;justify-content:center;min-width:0}.cell.disc-human{background:var(--disc-human);box-shadow:inset 0 -3px 0 color-mix(in srgb,var(--disc-human) 66%,#000),inset 0 2px 1px color-mix(in srgb,var(--disc-human) 55%,#fff),0 2px 8px #02050a45}.cell.disc-jev{background:var(--disc-jev);box-shadow:inset 0 -3px 0 color-mix(in srgb,var(--disc-jev) 66%,#000),inset 0 2px 1px color-mix(in srgb,var(--disc-jev) 55%,#fff),0 2px 8px #02050a45}.cell.disc-human:after,.cell.disc-jev:after{content:'H';color:#23304480;border:2px solid #1f293433;width:64%;height:64%;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:clamp(10px,1.2vw,18px);font-weight:750}.cell.disc-jev:after{content:'J'}.cell.preview:before{content:'';position:absolute;inset:12%;border:2px dashed var(--disc-human);border-radius:50%;opacity:.4}.cell.winning{outline:3px solid white;outline-offset:-1px;filter:brightness(1.16)}.cell.last{animation:drop .25s ease-out}.board-help{font-size:var(--fs-2xs);text-align:center;color:var(--muted);margin:var(--s4) 0 var(--s2)}.accessible-board{font-size:var(--fs-2xs);margin-top:var(--s2);color:var(--muted)}.accessible-board table{width:100%;margin-top:var(--s2);font-size:var(--fs-2xs)}.accessible-board td{padding:4px;text-align:center}.accessible-board summary{cursor:pointer}.match-strip{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);margin-top:var(--s4);padding:var(--s4) 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);font-size:var(--fs-2xs);color:var(--muted)}.metric-label{letter-spacing:1.5px;font-size:var(--fs-2xs);margin-right:var(--s1)}.match-strip b{color:var(--text);font:18px ui-monospace,monospace}.game-options{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:var(--s3);margin:var(--s4) 0 var(--s3)}label{display:block;font-size:var(--fs-2xs);font-weight:550;color:var(--muted)}select{display:block;width:100%;margin-top:var(--s1);min-height:var(--tap);border-radius:var(--radius-sm);border:1px solid var(--line);background:#11192b;color:var(--text);padding:var(--s2) var(--s2);font-size:var(--fs-xs);max-width:100%}.game-actions{display:flex;align-items:center;flex-wrap:wrap;gap:var(--s2)}.game-actions .button{font-size:var(--fs-xs)}.checkbox{display:flex;align-items:center;gap:var(--s2);font-size:var(--fs-2xs);font-weight:450}.checkbox input{accent-color:var(--accent);width:16px;height:16px}.game-actions .checkbox{margin-left:auto}.panel-heading{display:flex;align-items:center;justify-content:space-between;gap:var(--s2)}.panel-heading .eyebrow{font-size:var(--fs-2xs);letter-spacing:1.7px}.analysis-card h2{font-size:var(--fs-xl)}.toggle-label{font-size:var(--fs-2xs);display:flex;gap:var(--s1);align-items:center}.toggle-label input{accent-color:var(--accent)}.analysis-status{margin:var(--s5) 0 var(--s5);display:flex;align-items:center;gap:var(--s3)}.status-orbit{width:37px;height:37px;border:1px solid #6b668d;border-radius:50%;position:relative;box-shadow:0 0 25px #8672ff12}.status-orbit:before{content:'';position:absolute;inset:9px;background:var(--accent);border-radius:50%}.status-orbit:after{content:'';position:absolute;width:6px;height:6px;top:0;left:24px;background:var(--disc-jev);border-radius:50%}.analysis-status strong{font-size:var(--fs-xs)}.analysis-status p{font-size:var(--fs-2xs);color:var(--muted);margin:3px 0 0}.mini-metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s2);margin-bottom:var(--s5)}.mini-metrics>div{background:#0f1728;padding:var(--s3) var(--s3);border:1px solid #263047;border-radius:var(--radius-sm)}.mini-metrics span{font-size:var(--fs-2xs);display:block;color:var(--muted)}.mini-metrics strong{font:22px ui-monospace,monospace;margin-top:var(--s1);display:block}.section-label{font-size:var(--fs-2xs);letter-spacing:1.6px;color:var(--muted);font-weight:600;display:flex;justify-content:space-between;margin:0 0 var(--s3)}.section-label span{letter-spacing:0;color:#7785a5;font-weight:400}.candidate-chart{margin-bottom:var(--s6)}.candidate-row{display:grid;grid-template-columns:28px 1fr 47px;align-items:center;gap:var(--s2);margin-bottom:var(--s2);font-size:var(--fs-2xs)}.candidate-row .track{height:6px;background:#263047;border-radius:var(--radius-sm);overflow:hidden}.candidate-row .bar{height:100%;background:#7872aa;border-radius:var(--radius-sm)}.candidate-row.best .bar{background:var(--accent)}.candidate-row.best{color:var(--accent)}.candidate-row.excluded{color:#8490a6}.candidate-row .value{text-align:right;font:10px ui-monospace,monospace}.factor-row{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s2);border-bottom:1px solid var(--line);padding:var(--s2) 0;font-size:var(--fs-2xs)}.factor-row:last-child{border-bottom:none}.factor-row small{display:block;color:var(--muted);font-size:var(--fs-2xs);margin-top:2px}.factor-row b{color:var(--disc-jev);font-size:var(--fs-2xs);font-weight:500}.evidence-note{display:flex;gap:var(--s2);background:#23233b;border:1px solid #39334e;border-radius:var(--radius-sm);padding:var(--s3);margin-top:var(--s5)}.evidence-note p{font-size:var(--fs-2xs);color:#b1aacb;margin:0}.note-icon{font:10px serif;display:flex;align-items:center;justify-content:center;border:1px solid #8c82ad;border-radius:50%;width:14px;height:14px;flex-shrink:0;margin-top:2px;color:var(--accent)}.analysis-card details{margin-top:var(--s4);font-size:var(--fs-2xs);color:var(--muted)}summary{cursor:pointer}.empty-state{font-size:var(--fs-xs);color:var(--muted);padding:var(--s4) 0;margin:0}.activity-card{margin-top:var(--s5)}.activity-card .eyebrow{font-size:var(--fs-2xs)}.activity-card h2{font-size:var(--fs-lg)}.inline-actions{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap}.move-timeline{display:flex;gap:var(--s2);flex-wrap:wrap;margin-top:var(--s3)}.move-chip{font:11px ui-monospace,monospace;padding:var(--s2) var(--s2);border-radius:var(--radius-sm);background:#1d2940;border:1px solid var(--line);color:var(--disc-jev)}.move-chip.human-chip{color:var(--disc-human)}.section-header{display:flex;justify-content:space-between;align-items:center;gap:var(--s4);margin:var(--s2) 0 var(--s5)}.section-header h2{font-size:var(--fs-num)}.section-header p{margin-bottom:0}.kpi-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--s4);margin-bottom:var(--s4)}.kpi{border:1px solid var(--line);background:var(--surface);padding:var(--s4);border-radius:var(--radius)}.kpi>span{font-size:var(--fs-2xs);color:var(--muted);display:block}.kpi strong{font-size:var(--fs-num);font-weight:500;letter-spacing:-1px;margin-top:var(--s2);display:block}.kpi small{font-size:var(--fs-2xs);color:var(--muted);display:block;margin-top:var(--s1)}.dashboard-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--s4)}.dashboard-card h3{margin-bottom:var(--s1)}.wide{margin-top:var(--s4)}.chart-container{min-height:175px;display:flex;align-items:center;justify-content:center}.chart-container svg{width:100%;max-height:220px;overflow:visible}.chart-axis{stroke:var(--line);stroke-width:1}.chart-label{fill:var(--muted);font:10px sans-serif}.chart-line{fill:none;stroke:var(--accent);stroke-width:2}.chart-point{fill:var(--accent)}.chart-human{fill:var(--disc-human)}.chart-jev{fill:var(--disc-jev)}.legend{display:flex;gap:var(--s4);font-size:var(--fs-2xs);justify-content:center}.human-text{color:var(--disc-human)}.jev-text{color:var(--disc-jev)}.heatmap{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--s1);max-width:330px;margin:var(--s4) auto}.heat-cell{aspect-ratio:1.25;background:#393257;border:1px solid #75649b;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;font:11px ui-monospace,monospace}.heat-cell.heat-0{background:#1b2438;color:#94a0b8}.heat-cell.heat-1{background:#352e50}.heat-cell.heat-2{background:#55416e}.heat-cell.heat-3{background:#735394}.heat-cell.heat-4{background:#9876bd;color:#100c20}.table-scroll{overflow-x:auto}table{border-collapse:collapse;width:100%;text-align:left;font-size:var(--fs-xs)}th{font-size:var(--fs-2xs);font-weight:550;color:var(--muted);padding:var(--s3) var(--s3);border-bottom:1px solid var(--line);white-space:nowrap}td{padding:var(--s3);border-bottom:1px solid #263047;vertical-align:top}tbody tr:last-child td{border-bottom:0}td.numeric,th.numeric{text-align:right;font-variant-numeric:tabular-nums}.data-pairs{display:grid;grid-template-columns:1fr 1fr;gap:0 var(--s5)}.data-pair{display:flex;gap:var(--s2);justify-content:space-between;border-bottom:1px solid var(--line);padding:var(--s3) 0;font-size:var(--fs-2xs)}.data-pair span{color:var(--muted)}.data-pair strong{font-weight:500}.export-controls,.leader-controls{display:flex;align-items:flex-end;flex-wrap:wrap;gap:var(--s3);margin-top:var(--s4)}.export-controls select{width:auto;margin:0;min-height:44px}.leader-controls label{flex:1;min-width:120px}.telemetry{margin-top:var(--s5)}footer{max-width:var(--shell);margin:var(--s6) auto 0;padding:var(--s4) var(--s5) calc(var(--s5) + var(--sa-b));border-top:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:var(--s4);font-size:var(--fs-2xs);color:var(--muted)}footer>span:first-child{color:var(--text);letter-spacing:1px}dialog{max-width:600px;width:calc(100% - 32px);max-height:88vh;max-height:88dvh;padding:var(--s5);background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);color:var(--text);box-shadow:0 25px 100px #0009}dialog::backdrop{background:#050914d9;backdrop-filter:blur(5px)}dialog p{color:var(--muted);font-size:var(--fs-xs)}dialog h3{margin-top:var(--s5)}.dialog-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--s4)}.dialog-header h2{margin:0}.compact-board{max-width:390px;margin:var(--s4) auto}input[type=range]{width:100%;accent-color:var(--accent)}input[type=file]{max-width:100%;margin-top:var(--s2);color:var(--text);font-size:var(--fs-xs)}@keyframes drop{from{transform:translateY(-12px);opacity:.5}to{transform:translateY(0);opacity:1}}
@media(max-width:899px){.play-layout{grid-template-columns:1fr;gap:var(--s4)}.dashboard-grid{grid-template-columns:1fr}.hero{flex-direction:column;align-items:flex-start;gap:var(--s3);padding-bottom:0}.hero-meta{align-items:flex-start;flex-direction:row;flex-wrap:wrap;gap:var(--s3)}.section-header{flex-wrap:wrap}.section-header .inline-actions{width:100%}.board-shell{--fit-reserve:19rem}.game-card{padding:var(--s5) var(--s4)}.analysis-card{padding:var(--s5) var(--s4)}.data-pairs{grid-template-columns:1fr}}
@media(max-width:600px){.game-card{padding:var(--s4) var(--s3)}.analysis-card{padding:var(--s4) var(--s4)}.board{gap:var(--s1);padding:var(--s2)}.column-controls{gap:var(--s1);padding:0 var(--s2) var(--s1)}.column-button.selected:not(:disabled):after{display:none}.board-shell{--fit-reserve:16rem}.game-heading{gap:var(--s1)}.player-label{gap:var(--s1)}.player-label strong{font-size:var(--fs-2xs)}.disc-key{width:27px;height:27px}.kpi-grid{grid-template-columns:1fr 1fr;gap:var(--s3)}.kpi{padding:var(--s4)}.kpi strong{font-size:var(--fs-num-sm)}.game-options{grid-template-columns:1fr 1fr}.game-options label:first-child{grid-column:1/-1}.match-strip{flex-wrap:wrap;font-size:var(--fs-2xs)}.cell.disc-human:after,.cell.disc-jev:after{font-size:var(--fs-xs)}.activity-card,.dashboard-card{padding:var(--s4)}.activity-card .panel-heading{align-items:flex-start}.section-header h2{font-size:var(--fs-num-sm)}footer{flex-wrap:wrap;padding-left:var(--s3);padding-right:var(--s3)}footer>span:nth-child(2){display:none}}
/* >=900px: how the relocated controls look once brand.js has moved
   #jv-controls into the header. Positioning lives in brand.css. */
@media(min-width:900px){.nav-link{position:relative;padding:0 var(--s2);background:none;font-size:var(--fs-xs)}.nav-link.active{background:none;color:var(--text)}.nav-link.active:after{content:"";position:absolute;left:8px;right:8px;bottom:9px;height:2px;background:var(--accent)}.account{padding:0;flex-wrap:nowrap}}
@media(min-width:1280px){.board-shell{--fit-max:34rem}.play-layout{gap:var(--s5)}}
/* Short viewports (laptops, landscape phones): the board leads, so it is never
   below the fold, and the hero keeps all of its copy underneath. */
@media(max-height:950px){.hero{padding-top:0}}
@media(max-height:560px) and (orientation:landscape){.hero{padding:0}.game-card{padding:var(--s3)}.board-help{font-size:var(--fs-2xs)}.board-shell{--fit-reserve:11rem}.board-help{margin:var(--s2) 0 var(--s1)}.match-strip{margin-top:var(--s2);padding:var(--s2) 0}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
