/* Meter Gomoku web calculator — mobile-first UI */
*{box-sizing:border-box}
:root{
  --ink:#171b21; --sub:#5c6774; --mute:#8792a0; --body-text:#2b333c;
  --line:#e3e8ef; --line-2:#eef2f7;
  --accent:#2f6fb0; --accent-d:#1e4e80; --accent-l:#eaf3fc; --accent-ink:#fff;
  --paper:#fff; --bg:#edf1f6; --card-bg:#fcfdfe;
  --chip-border:#d6e6f7; --chip-gray-bg:#f3f5f8;
  --btn-bg:#fff; --btn-border-hover:#c9d7e6;
  --nav-hover:#f2f6fb;
  --shadow:0 20px 45px -38px rgba(16,40,72,.55),0 2px 6px rgba(16,40,72,.05);
  --sans:"Source Han Sans SC","Noto Sans SC","PingFang SC","Microsoft YaHei",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:"JetBrains Mono","Cascadia Code",Consolas,"SF Mono",Menlo,monospace;
  --board:#e9d6b0; --board-line:#4a4438;
  --r:13px;
  --vh:100dvh;
}
html[data-theme="dark"]{
  --ink:#e8eef7; --sub:#b6c2d1; --mute:#94a3b5; --body-text:#d7dfe9;
  --line:#2b3745; --line-2:#232e3a;
  --accent:#79b8ef; --accent-d:#a8d2f6; --accent-l:#17283a;
  --paper:#111820; --bg:#0a0f15; --card-bg:#151d27;
  --chip-border:#2d4b68; --chip-gray-bg:#1a232e;
  --btn-bg:#17212d; --btn-border-hover:#3d5167;
  --nav-hover:#1c2a3a;
  --shadow:0 24px 50px -40px #000,0 2px 7px rgba(0,0,0,.35);
  --board:#bda87f; --board-line:#332e26;
}
html,body{margin:0;padding:0;background:var(--bg);color:var(--body-text);font-family:var(--sans);
  -webkit-text-size-adjust:100%;overflow-x:hidden}
body{min-height:100vh;min-height:100dvh}
button,input{font-family:inherit}
button{cursor:pointer}
h1,h2,p{margin:0}
/* one column width for header, board, keys, stats and panels: 780 px on a
   desktop, full width on a phone. Everything below the header now shares the
   same left/right edge instead of shrinking to 640 px above 900 px. */
.app{width:100%;max-width:780px;margin:0 auto;padding:calc(2px + env(safe-area-inset-top)) 8px calc(14px + env(safe-area-inset-bottom))}
.top{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 2px 4px}
.brand{display:flex;align-items:center;gap:8px;min-width:0}
.logo{width:30px;height:30px;border-radius:9px;object-fit:cover;display:block;flex:0 0 auto}
.brand-txt{min-width:0}
.brand-txt h1{font-size:15px;line-height:1.2;font-weight:700;color:var(--ink);letter-spacing:.01em;white-space:nowrap}
.brand-txt p{font-size:9.5px;line-height:1.35;color:var(--mute);letter-spacing:.06em;white-space:nowrap}
.top-right{display:flex;align-items:center;gap:4px;flex:0 0 auto}
.lang-btn{height:28px;padding:0 10px;border-radius:999px;border:1px solid var(--line);background:var(--chip-gray-bg);
  color:var(--sub);font-size:11px;font-weight:700;letter-spacing:.05em;transition:.15s}
.lang-btn:hover{color:var(--accent-d);border-color:var(--border-hover,var(--btn-border-hover))}
.lang-btn:active{transform:translateY(1px)}
.chip{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 9px;border-radius:999px;
  font-size:10.5px;font-weight:600;color:var(--sub);background:var(--chip-gray-bg);border:1px solid var(--line);
  white-space:nowrap;transition:.16s}
.chip::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--mute);flex:0 0 auto}
.chip.on{background:var(--accent-l);border-color:var(--chip-border);color:var(--accent-d)}
.chip.on::before{background:#28a46a}
.chip.warn{background:#fff7e8;border-color:#f0d9a8;color:#8a5a12}
.chip.warn::before{background:#d29b32}
html[data-theme="dark"] .chip.warn{background:#2a2216;border-color:#584827;color:#e0b768}
.chip.err{background:#fdecec;border-color:#f3c4c4;color:#9c3131}
.chip.err::before{background:#cc4646}
.icon-btn{width:34px;height:34px;flex:0 0 auto;display:grid;place-items:center;padding:0;border:1px solid transparent;
  border-radius:999px;background:transparent;color:var(--sub);transition:.16s}
.icon-btn:hover{background:var(--nav-hover);color:var(--accent-d)}
.icon-btn svg{width:18px;height:18px;display:block}
.icon-btn .icon-sun{display:none}
html[data-theme="dark"] .icon-btn .icon-moon{display:none}
html[data-theme="dark"] .icon-btn .icon-sun{display:block}
.board-shell{position:relative;width:100%;margin:0 auto;display:flex;justify-content:center}
#board{display:block;width:100%;height:auto;aspect-ratio:1/1;border-radius:2px;touch-action:manipulation;
  outline:1px solid rgba(20,30,20,.10);outline-offset:-1px;background:var(--board);margin:0 auto}
html[data-theme="dark"] #board{outline-color:rgba(0,0,0,.45)}

.stepbar{display:grid;gap:4px;margin:8px auto 0}
/* row 1: 5 board controls; row 2: a 6-cell grid whose AI and balance halves
   are each one segmented block spanning two cells. Never wraps. */
.steps5row{grid-template-columns:repeat(5,minmax(0,1fr))}
.steps6row{grid-template-columns:repeat(6,minmax(0,1fr));margin-top:4px}
.step-btn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;min-width:0;min-height:42px;
  padding:2px 2px;border:1px solid var(--line);border-radius:9px;background:var(--btn-bg);color:var(--sub);
  font-size:10.5px;font-weight:600;line-height:1.15;white-space:nowrap;transition:.15s}
.step-btn svg{width:13px;height:13px;display:block;flex:0 0 auto}
.step-btn .step-txt{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.step-btn:hover:not(:disabled){border-color:var(--btn-border-hover);color:var(--ink);background:var(--nav-hover)}
.step-btn:disabled{opacity:.42;cursor:default}
.step-btn.key-play{color:var(--accent-d);border-color:var(--chip-border);background:var(--accent-l)}
.step-btn.key-play:hover:not(:disabled){border-color:var(--accent);color:var(--accent-d)}
.step-btn[aria-pressed="true"],.step-btn.key-scan[aria-pressed="true"]{
  border-color:var(--accent);background:var(--accent-l);color:var(--accent-d)}
.step-btn.key-danger{color:#9c3131;border-color:#f0cccc;background:#fdf4f4}
html[data-theme="dark"] .step-btn.key-danger{color:#f0a4a4;border-color:#5b2c2c;background:#251618}
.step-btn.key-danger.confirm{background:#c9463c;border-color:#c9463c;color:#fff}
html[data-theme="dark"] .step-btn.key-danger.confirm{background:#b53d34;border-color:#b53d34;color:#fff}

/* segmented block: two half-width keys sharing one frame, divided by the same
   hairline the settings rows use. The active half keeps its own accent fill. */
.seg-block{grid-column:span 2;display:grid;grid-template-columns:1fr 1fr;min-width:0;
  border:1px solid var(--line);border-radius:9px;background:var(--btn-bg);overflow:hidden}
.seg-btn{border:0;border-radius:0;background:transparent;min-height:40px;padding:2px 1px}
.seg-btn + .seg-btn{border-left:1px solid var(--line)}
.seg-block .seg-btn[aria-pressed="true"]{background:var(--accent-l);color:var(--accent-d)}
.seg-block .seg-btn:hover:not(:disabled){background:var(--nav-hover);color:var(--ink)}
.seg-block .seg-btn[aria-pressed="true"]:hover:not(:disabled){background:var(--accent-l);color:var(--accent-d)}
.seg-bal .bal-count{color:var(--mute)}
.seg-bal .bal-count b{font-family:var(--mono);font-size:14px;font-weight:700;color:var(--ink);line-height:1}
.seg-bal .bal-count .step-txt{font-size:9px;line-height:1}
.seg-bal .bal-count:hover b{color:var(--ink)}
/* active AI halves are filled, not pale tints: violet for black (7.4:1 light,
   6.1:1 dark) and sky blue for white (5.9:1 light, 4.9:1 dark), both white text */
#btnAIB[aria-pressed="true"]{background:#5136c9;color:#fff}
html[data-theme="dark"] #btnAIB[aria-pressed="true"]{background:#5b43d2;color:#fff}
#btnAIW[aria-pressed="true"]{background:#2a66a4;color:#fff}
html[data-theme="dark"] #btnAIW[aria-pressed="true"]{background:#3573b4;color:#fff}

/* nine-way position transform, floating over the board in frosted glass */
.xf-panel{position:fixed;z-index:70;left:50%;bottom:calc(16px + env(safe-area-inset-bottom));
  transform:translate(-50%,8px);width:min(430px,calc(100vw - 24px));padding:11px 12px 12px;
  border-radius:16px;border:1px solid var(--line);
  background:color-mix(in srgb,var(--paper) 72%,transparent);
  backdrop-filter:blur(18px) saturate(1.25);-webkit-backdrop-filter:blur(18px) saturate(1.25);
  box-shadow:0 24px 60px -26px rgba(10,24,40,.42),inset 0 1px 0 rgba(255,255,255,.5);
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s ease,transform .18s ease,visibility .18s}
html[data-theme="dark"] .xf-panel{background:color-mix(in srgb,var(--card-bg) 76%,transparent);
  box-shadow:0 24px 60px -24px #000,inset 0 1px 0 rgba(255,255,255,.10)}
.xf-panel.open{opacity:1;visibility:visible;pointer-events:auto;transform:translate(-50%,0)}
.xf-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
.xf-title{font-size:11.5px;font-weight:700;letter-spacing:.08em;color:var(--mute);text-transform:uppercase}
.xf-close{width:32px;height:32px;display:grid;place-items:center;border:0;border-radius:9px;background:transparent;
  color:var(--sub);font-size:18px;line-height:1}
.xf-close:hover{background:var(--nav-hover);color:var(--ink)}
.xf-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}
.xf-key{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-height:54px;
  padding:4px 3px;border:1px solid var(--line);border-radius:10px;background:var(--btn-bg);color:var(--sub);
  font-size:11px;font-weight:600;line-height:1.2;white-space:nowrap;transition:.15s}
.xf-key:hover{border-color:var(--btn-border-hover);color:var(--ink);background:var(--nav-hover)}
.xf-key:active{transform:translateY(1px)}
.xf-key:disabled{opacity:.4;cursor:not-allowed;transform:none}
.xf-key:disabled .g{color:var(--mute)}
.xf-key .g{font-family:var(--mono);font-size:17px;line-height:1;color:var(--accent-d)}
.xf-hint{grid-column:1/-1;font-size:10px;color:var(--mute);text-align:center;margin-top:1px}
body.xf-open .xf-panel{pointer-events:auto}

/* settings rows that leave the app (official site, about page) */
.set-link{display:flex;align-items:center;gap:10px;min-height:46px;padding:8px 10px;margin-top:6px;
  border:1px solid var(--line);border-radius:10px;background:var(--btn-bg);color:var(--ink);
  text-decoration:none;transition:.15s;box-shadow:0 1px 2px rgba(20,40,70,.03)}
.set-link:hover{border-color:var(--btn-border-hover);background:var(--nav-hover)}
.set-link:active{transform:translateY(1px)}
.set-link-ico{width:30px;height:30px;flex:0 0 auto;display:grid;place-items:center;border-radius:8px;
  background:var(--accent-l);color:var(--accent-d)}
.set-link-ico svg{width:17px;height:17px;display:block}
.set-link-txt{min-width:0;display:flex;flex-direction:column;gap:1px;flex:1 1 auto}
.set-link-txt b{font-size:12.5px;font-weight:700;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.set-link-txt span{font-size:10.5px;color:var(--mute);line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.set-link-go{width:16px;height:16px;flex:0 0 auto;color:var(--mute)}
.set-link-go svg{width:16px;height:16px;display:block}
@media (max-width:360px){
  .set-link{padding:7px 8px;gap:8px}
  .set-link-txt b{font-size:12px}
  .set-link-txt span{font-size:10px}
}

.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin:15px auto 0}
.stat{background:var(--paper);padding:7px 6px 8px;min-width:0;display:flex;flex-direction:column;align-items:center;gap:2px}
.stat .k{font-size:10px;color:var(--mute);font-weight:600;letter-spacing:.08em}
.stat .v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:13.5px;font-weight:700;color:var(--ink);
  line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;min-height:17px}
.stat:first-child .v{color:var(--accent-d)}

.panel{max-width:100%;margin:7px auto 0;background:var(--paper);border:1px solid var(--line);border-radius:var(--r);
  padding:8px 10px;box-shadow:0 1px 2px rgba(20,40,70,.02)}
.panel-head{display:flex;align-items:center;justify-content:space-between;gap:8px;min-height:18px;margin-bottom:5px}
.panel-title{font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--mute);text-transform:uppercase}
.panel-hint{font-size:10.5px;color:var(--mute);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.panel-hint.live{color:var(--accent-d);font-weight:600}
.code-row{display:flex;align-items:stretch;gap:6px}
.code-input{flex:1 1 auto;min-width:0;height:60px;padding:7px 10px;border:1px solid var(--line);border-radius:8px;
  background:var(--bg);color:var(--ink);font-family:var(--mono);font-size:13px;line-height:1.5;letter-spacing:.02em;
  outline:none;resize:none;overflow-y:auto;overflow-x:hidden;white-space:pre-wrap;word-break:break-all;display:block}
html[data-theme="dark"] .code-input{background:#0e151e}
.code-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(47,111,176,.13)}
html[data-theme="dark"] .code-input:focus{box-shadow:0 0 0 3px rgba(121,184,239,.16)}
.code-input.bad{border-color:#d35b5b;animation:shake .22s}
@keyframes shake{25%{transform:translateX(-3px)}75%{transform:translateX(3px)}}
.icon-btn.copy{width:40px;height:auto;align-self:stretch;border-color:var(--line);background:var(--btn-bg);border-radius:8px}
.icon-btn.copy:hover{border-color:var(--btn-border-hover);background:var(--nav-hover)}
/* the same position in 1-based x,y pairs, always in sync with the textarea */
.code-alt{margin-top:5px;font-family:var(--mono);font-size:10.5px;line-height:1.4;color:var(--mute);
  white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}
.code-alt::-webkit-scrollbar{display:none}
.code-alt span{margin-right:6px;font-family:var(--sans);font-size:9.5px;letter-spacing:.06em;opacity:.8}

/* analysis route: depth and eval ride in the panel head, the PV itself is a
   wrapping list that shows three rows and scrolls beyond that */
.route-row{display:flex;flex-direction:column;align-items:stretch;gap:0;min-height:30px;max-height:186px;
  overflow-y:auto;font-family:var(--mono);font-variant-numeric:tabular-nums;scrollbar-width:thin;
  scrollbar-color:var(--line) transparent;overscroll-behavior:contain}
.route-row::-webkit-scrollbar{width:5px}
.route-row::-webkit-scrollbar-thumb{background:var(--line);border-radius:99px}
.route-line{display:flex;align-items:flex-start;gap:7px;padding:3px 0;border-bottom:1px dashed var(--line-2)}
.route-line:last-child{border-bottom:0}
.rt-rank{flex:0 0 auto;font-size:10px;line-height:18px;color:var(--mute);font-weight:700;
  font-variant-numeric:tabular-nums;white-space:nowrap}
.rt-moves{flex:1 1 auto;min-width:0;display:flex;flex-wrap:wrap;gap:4px 2px}
.rt-ev{flex:0 0 auto;min-width:3.4ch;text-align:left;font-size:11px;line-height:18px;font-weight:700;
  color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.rt-ev.pos{color:#1d7a4b}
.rt-ev.neg{color:#a63d3d}
html[data-theme="dark"] .rt-ev.pos{color:#57c98a}
html[data-theme="dark"] .rt-ev.neg{color:#e58a8a}
.route-meta{display:inline-flex;align-items:center;gap:8px;margin-right:auto;margin-left:6px;
  font-family:var(--mono);font-variant-numeric:tabular-nums}
.route-meta .depth{font-size:11.5px;color:var(--sub);font-weight:600}
.route-meta .eval{font-size:12px;font-weight:700;color:var(--ink)}
.route-meta .eval.pos{color:#1d7a4b}
.route-meta .eval.neg{color:#a63d3d}
html[data-theme="dark"] .route-meta .eval.pos{color:#57c98a}
html[data-theme="dark"] .route-meta .eval.neg{color:#e58a8a}
.route-row .route{flex:1 1 auto;min-width:0;font-size:12.5px;color:var(--ink);letter-spacing:.04em;display:block}
.route-row .route:not(.route-list){white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.route-row .route-list{display:flex;flex-wrap:wrap;gap:5px 2px;max-height:78px;overflow-y:auto;overflow-x:hidden;
  white-space:normal;scrollbar-width:thin;scrollbar-color:var(--line) transparent;overscroll-behavior:contain}
.route-list::-webkit-scrollbar{width:5px}
.route-list::-webkit-scrollbar-thumb{background:var(--line);border-radius:99px}
.route-row .mv{flex:0 0 auto;padding:1px 3px;border-radius:5px;font-weight:600;color:var(--sub);
  cursor:pointer;transition:background .12s,color .12s}
.route-row .mv:hover,.route-row .mv.on{background:var(--accent);color:var(--accent-ink)}
.route-row .mv.pin{box-shadow:inset 0 0 0 1px var(--accent)}
html[data-theme="dark"] .route-row .mv:hover,html[data-theme="dark"] .route-row .mv.on{color:#0d1a26}
.route-row.empty{color:var(--mute)}
.route-row.empty .route{color:var(--mute);font-family:var(--sans);font-size:12px;letter-spacing:0;display:block}
.balance-row{display:flex;flex-wrap:wrap;gap:5px;margin-top:5px;padding-top:6px;border-top:1px dashed var(--line)}
.balance-row .bal{display:inline-flex;align-items:center;gap:5px;padding:2px 7px 2px 6px;border-radius:999px;
  border:1px dashed var(--accent);background:var(--accent-l);color:var(--accent-d);font-size:10.5px;font-weight:600}
.balance-row .bal i{width:7px;height:7px;border-radius:50%;background:var(--accent);flex:0 0 auto}
.balance-row .bal em{font-family:var(--mono);font-style:normal;font-variant-numeric:tabular-nums}
.balance-row .bal.note{border-style:dotted;border-color:var(--line);background:transparent;color:var(--mute);font-weight:500}

/* win rate: one row — 胜率 / score chip / 黑 xx% 白 xx%. The head is a
   1fr-auto-1fr grid, so the score chip is centred over the bar itself instead
   of floating in whatever space the side labels leave behind. */
.wr-panel{padding-bottom:10px}
.wr-head{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:8px;
  margin-bottom:6px;min-height:24px}
.wr-head .panel-title{justify-self:start;margin:0}
.wr-right{justify-self:end;display:inline-flex;align-items:center;gap:9px}
.wr-side{display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;font-size:10.5px;color:var(--mute);font-weight:600}
.wr-side i{width:7px;height:7px;border-radius:50%;display:block}
.wr-side .dot-b{background:#7a5af8}
.wr-side .dot-w{background:#4f8fd6}
.wr-side b{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:11.5px;font-weight:700;color:var(--ink)}
.wrbar{display:flex;width:100%;height:7px;border-radius:999px;
  background:rgba(122,140,165,.18);border:1px solid var(--line);box-shadow:inset 0 1px 2px rgba(15,30,50,.08)}
.wr-b,.wr-w{display:block;min-width:0;
  transition:flex-basis .32s cubic-bezier(.22,.61,.36,1)}
/* forced win: one half owns the bar, rounded at both ends and lit from the
   middle, since it no longer has a seam to glow against */
.wr-b.solo,.wr-w.solo{border-radius:999px}
.wr-b.solo{background:linear-gradient(90deg,#6338ff,#a78bff 50%,#6338ff)}
.wr-w.solo{background:linear-gradient(90deg,#2f7fd6,#79c8ff 50%,#2f7fd6)}
.wr-b.gone,.wr-w.gone{display:none}
.wr-b{flex:0 0 50%;border-radius:999px 0 0 999px;
  background:linear-gradient(90deg,#6338ff,#a78bff);
  box-shadow:0 0 9px rgba(122,90,248,.85),0 0 22px rgba(122,90,248,.4)}
.wr-w{flex:1 1 auto;border-radius:0 999px 999px 0;
  /* mirrored, so the bright end of both halves meets at the middle seam */
  background:linear-gradient(90deg,#79c8ff,#2f7fd6);
  box-shadow:0 0 9px rgba(79,143,214,.8),0 0 22px rgba(79,143,214,.36)}
html[data-theme="dark"] .wrbar{background:rgba(120,145,180,.14)}
/* score chips: one per side, kept on screen all the time — a missing number
   shows a dash instead of the row collapsing. Each chip wears a two-tone frame:
   white inside, the side colour outside (purple = black, blue = white). */
.wr-eval{display:flex;align-items:center;justify-content:center;gap:5px;min-width:0;max-width:100%;
  margin:0;font-family:var(--mono);font-size:12px;line-height:1;color:var(--sub);white-space:nowrap;
  overflow:hidden;font-variant-numeric:tabular-nums;letter-spacing:.01em}
/* a fresh number must never move the chip: no scale, no shake, no flash —
   only the text is replaced, so the border and label stay pixel-stable */
.wr-eval .side{display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:0 9px;
  height:28px;border-radius:8px;border:.5px solid var(--line);background:var(--chip-gray-bg);font-size:12.5px}
.wr-eval .side i{width:6px;height:6px;border-radius:50%;display:inline-block;flex:0 0 auto}
.wr-eval .side.b{border-color:rgba(122,90,248,.62);background:rgba(122,90,248,.10);
  box-shadow:inset 0 0 0 .5px rgba(255,255,255,.72)}
.wr-eval .side.w{border-color:rgba(79,143,214,.66);background:rgba(79,143,214,.12);
  box-shadow:inset 0 0 0 .5px rgba(255,255,255,.72)}
.wr-eval .side.b i{background:#14171a;border:.5px solid rgba(255,255,255,.35)}
.wr-eval .side.w i{background:#faf9f5;border:.5px solid rgba(0,0,0,.25)}
.wr-eval b{display:inline-block;min-width:27px;text-align:center;font-weight:700;color:var(--ink);
  font-size:13.5px;font-variant-numeric:tabular-nums;transition:none}
html[data-theme="dark"] .wr-eval .side.b i{background:#0c1014;border-color:rgba(255,255,255,.28)}
html[data-theme="dark"] .wr-eval .side.b{background:rgba(122,90,248,.16);
  box-shadow:inset 0 0 0 .5px rgba(255,255,255,.16)}
html[data-theme="dark"] .wr-eval .side.w{background:rgba(79,143,214,.18);
  box-shadow:inset 0 0 0 .5px rgba(255,255,255,.16)}
@media (max-width:360px){
  .wr-head{gap:6px}
  .wr-right{gap:6px}
  .wr-eval{gap:4px;font-size:11px}
  .wr-eval .side{gap:3px;padding:0 6px;height:26px;font-size:11.5px}
  .wr-eval b{font-size:12.5px;min-width:0}
  .wr-side{font-size:9.5px;gap:3px}
  .wr-side b{font-size:10.5px}
}
/* on phones the chip drops its word — the coloured dot plus the 黑/白 values on
   the right already say whose score it is, and the row stays uncrowded */
@media (max-width:380px){
  .wr-eval .side > span{display:none}
  .wr-eval .side{padding:0 7px}
  .wr-eval b{min-width:4.2ch}
}


.foot{max-width:100%;margin:9px auto 0;display:flex;align-items:center;justify-content:center;gap:8px;
  flex-wrap:wrap;text-align:center;font-size:10.5px;color:var(--mute);letter-spacing:.02em}
.foot .chip{height:23px;font-size:9.5px;padding:0 8px}
.foot-note{white-space:nowrap}

/* settings dialog */
.dialog{width:min(430px,calc(100vw - 24px));max-height:min(84vh,620px);padding:0;border:1px solid var(--line);
  border-radius:16px;background:var(--paper);color:var(--body-text);box-shadow:var(--shadow);margin:auto;overflow:hidden}
.dialog::backdrop{background:rgba(10,20,30,.44);backdrop-filter:blur(2px)}
.dialog-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:13px 12px 10px 17px;
  border-bottom:1px solid var(--line-2)}
.dialog-head h2{font-size:15px;font-weight:700;color:var(--ink);letter-spacing:.02em}
.dialog-body{padding:4px 17px calc(14px + env(safe-area-inset-bottom));overflow-y:auto;max-height:calc(min(84vh,620px) - 55px)}
.set-row{padding:10px 0 11px;border-bottom:1px solid var(--line-2)}
.set-row:last-of-type{border-bottom:0}
.set-group{display:flex;align-items:center;gap:7px;margin:13px 0 1px;font-size:10px;font-weight:700;
  letter-spacing:.14em;color:var(--mute);text-transform:uppercase}
.set-group:first-child{margin-top:8px}
.set-group::after{content:"";flex:1 1 auto;height:1px;background:var(--line-2)}
.set-label{display:flex;flex-direction:column;gap:1px;margin-bottom:7px}
.set-label b{font-size:12.5px;color:var(--ink);font-weight:700}
.set-label span{font-size:10.5px;color:var(--mute)}
.seg{display:flex;gap:3px;background:var(--bg);border:1px solid var(--line-2);border-radius:9px;padding:3px}
html[data-theme="dark"] .seg{background:#0e151e}
.seg.five button{font-size:10.5px;padding:0 2px}
/* hash segments carry the unit: never wrap or squeeze at 320 px */
.seg.hash-seg button{white-space:nowrap;letter-spacing:-.15px;font-variant-numeric:tabular-nums}
@media (max-width:360px){
  .seg.five button{font-size:10px;padding:0 1px}
  .seg.hash-seg button{font-size:9.5px;letter-spacing:-.35px}
}
.seg.four{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:3px}
.seg button{flex:1 1 0;min-width:0;min-height:38px;border:0;border-radius:7px;background:transparent;color:var(--sub);
  font-size:11.5px;font-weight:600;transition:.14s;padding:0 4px;white-space:nowrap}
.seg button:hover{color:var(--ink);background:var(--nav-hover)}
.seg button.on{background:var(--accent);color:var(--accent-ink);box-shadow:0 4px 10px -7px rgba(47,111,176,.9)}
html[data-theme="dark"] .seg button.on{color:#0d1a26}
.range-wrap{display:flex;align-items:center;gap:11px}
.range-wrap input[type=range]{flex:1 1 auto;min-width:0;height:44px;accent-color:var(--accent);background:transparent;margin:0}
.range-wrap output{flex:0 0 auto;min-width:44px;height:30px;padding:0 8px;display:grid;place-items:center;
  border:1px solid var(--line);border-radius:7px;font-family:var(--mono);font-size:12.5px;font-weight:700;color:var(--ink);background:var(--bg)}
.range-wrap input:disabled{opacity:.45}
.seg.grid4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:3px}
/* board colour presets: 15 chips, 5 per row */
.swatches{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px}
.swatch{position:relative;height:34px;min-width:0;padding:0;border:1px solid rgba(20,30,20,.18);border-radius:8px;
  background:var(--sw,#e9d6b0);transition:.14s;overflow:hidden}
.swatch::after{content:"";position:absolute;inset:0;
  background:
    linear-gradient(to right,transparent calc(50% - .5px),var(--swl,#4a4438) 50%,transparent calc(50% + .5px)),
    linear-gradient(to bottom,transparent calc(50% - .5px),var(--swl,#4a4438) 50%,transparent calc(50% + .5px));
  opacity:.62}
.swatch:hover{border-color:var(--btn-border-hover);transform:translateY(-1px)}
.swatch[aria-pressed="true"]{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-l),0 0 0 3px var(--accent)}
.custom-row{display:flex;align-items:center;gap:8px;margin-top:7px}
.custom-k{font-size:11px;color:var(--mute);font-weight:600}
.custom-u{font-size:11px;color:var(--mute)}
.num-input{width:66px;height:34px;padding:0 8px;border:1px solid var(--line);border-radius:8px;background:var(--bg);
  color:var(--ink);font-family:var(--mono);font-size:12.5px;font-weight:700;text-align:center;outline:none;
  -moz-appearance:textfield}
.num-input::-webkit-outer-spin-button,.num-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.num-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(47,111,176,.12)}
.mini-btn{height:34px;padding:0 14px;margin-left:auto;border:1px solid var(--accent);border-radius:8px;
  background:var(--accent);color:var(--accent-ink);font-size:11.5px;font-weight:700;transition:.15s}
.mini-btn:hover{filter:brightness(1.05)}
html[data-theme="dark"] .mini-btn{color:#0d1a26}
.switch-row{display:flex;align-items:center;gap:12px}
.switch-row .set-label{flex:1 1 auto;margin-bottom:0}
.switch{flex:0 0 auto;position:relative;width:52px;height:30px;padding:0;border:1px solid var(--line);
  border-radius:999px;background:var(--chip-gray-bg);transition:.2s}
.switch .knob{position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:#fff;
  box-shadow:0 1px 3px rgba(15,30,50,.28);transition:transform .2s cubic-bezier(.22,.61,.36,1)}
.switch[aria-checked="true"]{background:var(--accent);border-color:var(--accent)}
.switch[aria-checked="true"] .knob{transform:translateX(22px)}
html[data-theme="dark"] .switch .knob{background:#e8eef7}
/* a compact switch that sits inline with a settings title */
.switch.sw-sm{width:38px;height:22px}
.switch.sw-sm .knob{top:2px;left:2px;width:16px;height:16px}
.switch.sw-sm[aria-checked="true"] .knob{transform:translateX(16px)}
.set-label .set-title-line{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.seg[hidden]{display:none!important}
.debug{margin-top:11px;padding:8px 10px;border:1px dashed var(--line);border-radius:9px;background:var(--bg);
  font-family:var(--mono);font-size:10.5px;line-height:1.75;color:var(--sub);overflow-wrap:anywhere}
.debug b{color:var(--ink);font-weight:600}
.dialog-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:13px}
.btn{min-height:40px;padding:0 15px;border-radius:9px;border:1px solid var(--line);background:var(--btn-bg);
  color:var(--ink);font-size:12.5px;font-weight:600;transition:.15s}
.btn:hover{border-color:var(--btn-border-hover);background:var(--nav-hover)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn.primary:hover{filter:brightness(1.04)}
.btn.text{border-color:transparent;background:transparent;color:var(--mute);padding:0 4px}
.btn.text:hover{color:var(--accent-d);background:transparent}

/* notices used to float over the board's top-right corner, where they covered
   both the stones and the coordinate label; they now sit on one line in the
   footer, so the board stays clean */
.toast-line{font-size:10.5px;color:var(--accent-d);font-weight:600;opacity:0;
  transition:opacity .18s ease;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.toast-line.on{opacity:1}
html[data-theme="dark"] .toast-line{color:#8fb6ff}

/* engine boot: the card is the only loading UI. The page behind it is never
   blurred or dimmed — the board stays readable while the weights stream in. */
.loader{position:fixed;inset:0;z-index:90;display:grid;place-items:center;padding:20px;
  background:transparent;
  transition:opacity .3s ease,visibility .3s ease}
.loader.hidden{opacity:0;visibility:hidden;pointer-events:none}
.loader-card{width:min(320px,100%);padding:17px 17px 13px;border-radius:18px;border:1px solid var(--line);
  background:var(--paper);
  box-shadow:0 26px 64px -32px rgba(8,20,36,.6),inset 0 1px 0 rgba(255,255,255,.6)}
html[data-theme="dark"] .loader{background:transparent}
html[data-theme="dark"] .loader-card{background:var(--card-bg);border-color:var(--line);
  box-shadow:0 26px 64px -30px #000,inset 0 1px 0 rgba(255,255,255,.08)}
.loader-top{display:flex;align-items:center;gap:11px}
.loader-top img{width:40px;height:40px;border-radius:11px;object-fit:cover;flex:0 0 auto}
.loader-titles{min-width:0}
.loader-titles h2{font-size:13.5px;font-weight:700;color:var(--ink);line-height:1.3}
.loader-titles p{font-size:10.5px;color:var(--sub);line-height:1.45;margin-top:1px}
.loader-bar{position:relative;height:3px;margin:14px 0 8px;border-radius:999px;overflow:hidden;background:rgba(120,140,165,.22)}
.loader-bar i{display:block;height:100%;width:0%;border-radius:999px;
  background:linear-gradient(90deg,#4f8fd6,#7a5af8);transition:width .22s linear}
.loader-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-family:var(--mono);font-size:9.5px;color:var(--mute);letter-spacing:.02em}
.loader-foot b{font-size:11px;color:var(--ink);font-variant-numeric:tabular-nums}
.loader-actions{display:flex;gap:8px;margin-top:12px}
.loader-actions[hidden]{display:none}
.loader-actions .mini-btn{flex:1 1 0;margin-left:0;display:inline-flex;align-items:center;justify-content:center;
  text-decoration:none}
.loader-actions .ghost{background:transparent;border-color:var(--line);color:var(--sub)}
.loader-actions .ghost:hover{border-color:var(--btn-border-hover);color:var(--ink);filter:none}
.loader.error .loader-titles h2{color:#c9463c}
.loader.error .loader-bar i{width:100% !important;background:linear-gradient(90deg,#d35b5b,#e79a9a);opacity:.5}

/* lazy load: the engine is fetched only when a search is asked for, so the
   first paint is never blocked. The same card shrinks into a small, non-modal
   status pill in the corner while the 41 MB package streams in. */
.loader.lazy{display:block;background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;
  pointer-events:none;padding:0}
/* solid pill, no frosted glass: the blur over a live board looked like a smudge
   and cost a compositing layer the whole time the engine was loading */
.loader.lazy .loader-card{position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));
  transform:translateX(-50%);width:min(330px,calc(100vw - 22px));pointer-events:auto;
  padding:10px 12px 9px;border-radius:14px;background:var(--paper);border:1px solid var(--line);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  box-shadow:0 12px 30px -18px rgba(10,24,40,.55),0 2px 6px rgba(10,24,40,.10)}
html[data-theme="dark"] .loader.lazy .loader-card{background:var(--card-bg);border-color:var(--line)}
.loader.lazy .loader-top{gap:9px}
.loader.lazy .loader-top img{width:26px;height:26px;border-radius:7px}
.loader.lazy .loader-titles h2{font-size:12px}
.loader.lazy .loader-titles p{font-size:10px}
.loader.lazy .loader-bar{margin:9px 0 5px;height:2px}
.loader.lazy .loader-actions{margin-top:9px}
.loader.lazy .loader-actions .mini-btn{height:30px;font-size:11px}

@media (max-width:560px){
  /* both key rows are fixed 5/6-column grids: no wrapping, no third row */
  .steps5row{grid-template-columns:repeat(5,minmax(0,1fr))}
  .steps6row{grid-template-columns:repeat(6,minmax(0,1fr))}
}
@media (max-width:360px){
  .app{padding-left:6px;padding-right:6px}
  .brand-txt h1{font-size:15px}
  .brand-txt p{font-size:9.5px}
  .logo{width:31px;height:31px;font-size:15px}
  .chip{font-size:9.5px;padding:0 7px;height:26px}
  .icon-btn{width:42px;height:42px}
  .stat .v{font-size:12.5px}
  .route-row .route{font-size:12px}
  .step-btn{font-size:10px;padding:2px 1px;gap:1px}
  .step-btn svg{width:12px;height:12px}
  .seg-btn{padding:2px 0}
  .route-row .mv{padding:1px 2px}
}
@media (min-width:900px){
  .app{padding-top:calc(16px + env(safe-area-inset-top))}
  .top{padding-top:2px;padding-bottom:10px}
  .dialog{margin:auto}
}
/* A short window used to shrink the whole column so the board stayed square
   without scrolling. That is what made the board look smaller than the header
   after the keyboard had been opened. The column keeps one width now; a short
   landscape window simply scrolls. */
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
}
