@font-face{font-family:"Plex Mono";src:url("./fonts/IBMPlexMono-500.woff2") format("woff2");font-weight:500;font-display:swap}
@font-face{font-family:"Plex Sans";src:url("./fonts/IBMPlexSans-400.woff2") format("woff2");font-weight:400;font-display:swap}
:root{color-scheme:light;--bg:#fff;--ink:#000;--text:#111;--sub:#5e5e5e;--line:#d4d4d4;--guide:#8f8f8f;--frame:#1c1c1c;--band:rgba(0,0,0,.05);--scrim:rgba(255,255,255,.84);--mono:"Plex Mono",monospace;--sans:"Plex Sans",sans-serif}
@media(prefers-color-scheme:dark){:root:not([data-theme=light]){color-scheme:dark;--bg:#000;--ink:#fff;--text:#ededed;--sub:#a6a6a6;--line:#2f2f2f;--frame:#ededed;--band:rgba(255,255,255,.06);--scrim:rgba(0,0,0,.8)}}
:root[data-theme=dark]{color-scheme:dark;--bg:#000;--ink:#fff;--text:#ededed;--sub:#a6a6a6;--line:#2f2f2f;--frame:#ededed;--band:rgba(255,255,255,.06);--scrim:rgba(0,0,0,.8)}
*{box-sizing:border-box;border-radius:0}
html,body{touch-action:manipulation}
body{margin:0;height:100dvh;overflow:hidden;background:var(--bg);color:var(--text);font:16px/1.45 var(--sans);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}
button,select,input{font:inherit;color:inherit}button{cursor:pointer}button:disabled{opacity:.35;cursor:default}
button:focus-visible,select:focus-visible,summary:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.readout{position:fixed;top:calc(max(0px,env(safe-area-inset-top)) + 18px);left:50%;transform:translateX(-50%);font:500 13px/1 var(--mono);letter-spacing:.02em;color:var(--sub);font-variant-numeric:tabular-nums;white-space:nowrap}
#restart-btn{position:fixed;top:max(0px,env(safe-area-inset-top));left:8px;z-index:2}

/* The board: a ring of ports around the grid. Lines and beams are drawn in two
   overlays, one under the cells and one over them. */
#board-shell{position:absolute;inset:48px 6px 116px;display:flex;overflow:hidden}
.board-stage{flex:none;margin:auto;display:flex;flex-direction:column;align-items:center;gap:8px}
.board{position:relative;display:grid;flex:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.board svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.board .lines{z-index:0}.board .beams{z-index:2}
.lines path{fill:none;stroke:var(--line);stroke-width:1}.lines rect{fill:none;stroke:var(--guide);stroke-width:1}
.cell,.port{position:relative;z-index:1;display:grid;place-items:center;cursor:pointer;outline:none}
.cell:focus-visible,.port:focus-visible{outline:2px solid var(--ink);outline-offset:-3px;z-index:3}
.stone{width:56%;height:56%;border-radius:50%;background:var(--ink)}
.dot{width:5px;height:5px;border-radius:50%;background:var(--sub)}
.cell.ghost-stone::after{content:"";position:absolute;inset:22%;border:1.5px dashed var(--ink);border-radius:50%;animation:pulse 650ms 2}
.cell.ghost-empty::after{content:"";position:absolute;left:50%;top:50%;width:11px;height:11px;margin:-5.5px;border:1.5px solid var(--ink);border-radius:50%;animation:pulse 650ms 2}

/* Port readings are told apart by shape: a solid square, a ring, a numeral. */
.port{color:var(--ink);font:500 var(--num)/1 var(--mono);font-variant-numeric:tabular-nums}
.port::before{content:"";position:absolute;inset:0}
.port.top::before{top:-8px}.port.bottom::before{bottom:-8px}.port.left::before{left:-6px}.port.right::before{right:-6px}
.glyph.sq{width:var(--sq);height:var(--sq);background:var(--ink)}
.glyph.ring{width:var(--rg);height:var(--rg);border:1.5px solid var(--ink);border-radius:50%}
.port.traced{box-shadow:inset 0 0 0 1px var(--ink)}
.port.hinted{box-shadow:inset 0 0 0 2px var(--ink);animation:pulse 650ms 2}
/* A reading the stones on the board do not give: a short bar under it. */
.port.off::after{content:"";position:absolute;left:50%;top:calc(50% + var(--num)*.5 + 3px);width:12px;height:2px;margin-left:-6px;background:var(--ink)}

.beam{fill:none;stroke:var(--ink);stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.beam.trace{stroke-dasharray:1;animation:beam-draw .28s ease-out both}
.beam.soft{stroke:var(--guide);stroke-width:1.25;stroke-dasharray:1;animation:beam-draw .7s cubic-bezier(.3,.7,.2,1) both}
@keyframes beam-draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
@keyframes pulse{50%{opacity:.3}}
.dot{transition:opacity .5s}.board.solved .dot{opacity:0}
.board.solved .cell,.board.solved .port{cursor:default}

/* Stones still to place: one ring each, filled as they go down. */
.tray{display:flex;gap:6px;height:8px}
.tray i{width:8px;height:8px;border:1.5px solid var(--sub);border-radius:50%}
.tray i.down{background:var(--ink);border-color:var(--ink)}
.tray i.extra{background:var(--ink);border-color:var(--ink);outline:1px solid var(--ink);outline-offset:2px;margin-left:4px}

/* One thing on a solved board: the boxed arrow, after the beams have drawn. */
.completion{display:flex;justify-content:center;animation:next-reveal .45s .75s both}
.completion[hidden]{display:none}
#next-btn{outline:1px solid var(--ink);outline-offset:-1px}
#next-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
@keyframes next-reveal{from{opacity:0;translate:0 4px}to{opacity:1;translate:0 0}}

#feedback{position:fixed;bottom:60px;left:16px;right:16px;margin:0;text-align:center;color:var(--sub);font:13px/1.3 var(--sans);pointer-events:none}
.toolbar{position:fixed;bottom:max(6px,env(safe-area-inset-bottom));left:8px;right:8px;display:flex;justify-content:space-between}.toolbar>div{display:flex}
.ib{display:inline-grid;place-items:center;width:48px;height:48px;min-width:48px;min-height:48px;border:0;background:none;padding:12px;color:var(--ink);transition:opacity .15s,transform .1s}
.ib svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.ib:active{transform:scale(.94)}

.sheet{width:min(32rem,calc(100vw - 16px));max-height:calc(100dvh - 16px);border:1px solid var(--frame);padding:0;background:var(--bg);color:var(--text)}
.sheet[open]{display:flex;flex-direction:column}.sheet::backdrop{background:var(--scrim)}
.sheet-head{display:flex;justify-content:space-between;align-items:center;padding:8px 16px;gap:12px;flex:none;border-bottom:1px solid var(--line)}
h2{font:500 16px/1.3 var(--mono);margin:0}.sheet-head form{margin:0}
.sheet-x{width:44px;height:44px;min-width:44px;min-height:44px;padding:10px}
.sheet-body{padding:20px 24px;overflow:auto;min-height:0;overscroll-behavior:contain}
.sheet-body p{margin:0 0 16px;max-width:60ch}
.row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:52px;border-bottom:1px solid var(--line)}
.row select{max-width:65%;min-height:44px;background:var(--bg);border:0;padding:4px 8px}
.row button{min-height:44px;background:none;border:0;padding:8px}.row button:not(:disabled){text-decoration:underline;text-underline-offset:4px}
.sheet-foot{padding:12px 24px;border-top:1px solid var(--line);flex:none;color:var(--sub);font-size:14px}.sheet-foot a{color:inherit}
.text-action{min-height:44px;padding:8px 12px;border:1px solid var(--line);background:none;font:500 14px/1.3 var(--mono);color:var(--text)}
.legend p{display:flex;align-items:center;gap:12px;margin:0 0 8px}.legend{margin-bottom:16px}
.key{flex:none;display:inline-grid;place-items:center;width:20px;height:20px;font:500 14px/1 var(--mono);color:var(--ink)}
.key.sq::before{content:"";width:11px;height:11px;background:var(--ink)}
.key.ring::before{content:"";width:13px;height:13px;border:1.5px solid var(--ink);border-radius:50%}
.controls{border-top:1px solid var(--line);padding-top:16px}.controls p{margin:0 0 6px}
.help-more{border-top:1px solid var(--line);margin-top:16px;padding-top:4px}.help-more summary{cursor:pointer;min-height:44px;padding:12px 0;color:var(--sub)}.help-more p{font-size:14px}.sheet-body .help-more p:last-child{margin-bottom:0}
@media(max-width:480px){.sheet-head{padding:8px 12px}.sheet-body{padding:16px}}

@media(orientation:landscape) and (max-height:500px){#board-shell{inset:30px 72px 62px 12px}.toolbar{left:auto;right:8px;top:12px;bottom:12px;flex-direction:column;width:48px}.toolbar>div{flex-direction:column}#feedback{left:12px;right:72px;bottom:4px;font-size:12px}.readout{left:calc(50% - 32px);top:10px}.board-stage{gap:5px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}
:root[data-motion=reduce] *,:root[data-motion=reduce] *::before,:root[data-motion=reduce] *::after{animation:none!important;transition:none!important}
@media(forced-colors:active){.stone,.glyph.sq,.tray i.down{background:CanvasText;forced-color-adjust:none}.beam{stroke:CanvasText}.port.off::after{background:CanvasText}}
header,.toolbar,.toolbar *,button,button *{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
