/* Layout rule: every button has a fixed height and never wraps, and anything whose text changes from move to move
   lives in a box of fixed size — so nothing on screen moves when the text does. */
:root {
  /* read on a phone in a bright hall: grey text and borders dark enough to see (mute 7.6:1 on white) */
  --bg: #eef0f3; --card: #fff; --ink: #0f172a; --mute: #475569; --line: #cfd6e0; --soft: #f8fafc; --hover: #e9edf2;
  --ours: #2563eb; --ours-soft: #eff6ff; --good: #059669; --good-soft: #ecfdf5; --bad: #dc2626; --bad-soft: #fef2f2;
  --warn: #d97706; --warn-soft: #fffbeb;
  --wood: #e9c37e; --woodln: #6d4f1c;
  --r: 14px; --rs: 10px; --tap: 44px; --btn: 40px; --hdr: 56px; --tabbar: 0px;
  --shadow: 0 1px 2px rgba(15,23,42,.04), 0 1px 3px rgba(15,23,42,.06);
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); letter-spacing: -0.01em;
  font: 15px/1.5 "Pretendard Variable", Pretendard, -apple-system, "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased; font-feature-settings: "tnum"; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }

/* ---- shell ---- */
.top { position: sticky; top: 0; z-index: 20; display: flex; gap: 16px; align-items: center; height: var(--hdr);
  padding: 0 24px; padding-top: env(safe-area-inset-top); box-sizing: content-box;
  background: rgba(255,255,255,.88); backdrop-filter: saturate(180%) blur(12px); -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line); color: var(--ink); }
.brand { display: flex; align-items: center; gap: 8px; text-decoration: none; font-weight: 700; font-size: 17px; white-space: nowrap; letter-spacing: -0.02em; }
.brand img { border-radius: 7px; }
.tabbar { display: flex; gap: 4px; }
.tabbar a { display: flex; align-items: center; gap: 6px; height: 38px; text-decoration: none; padding: 0 12px; border-radius: var(--rs);
  color: var(--mute); font-weight: 500; white-space: nowrap; }
.tabbar a:hover { background: var(--hover); color: var(--ink); }
.tabbar a.on { background: var(--hover); color: var(--ink); font-weight: 700; }
.tabbar svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }
main { max-width: 1240px; margin: 0 auto; padding: 20px 24px 48px; }
.foot { text-align: center; color: var(--mute); font-size: 12px; padding: 0 16px 24px; }

@media (max-width: 720px) {
  :root { --hdr: 52px; }
  /* a backdrop-filter would make the header the containing block of the fixed tab bar inside it */
  .top { padding: 0 16px; padding-top: env(safe-area-inset-top); gap: 10px; background: #fff; backdrop-filter: none; -webkit-backdrop-filter: none; }
  body.tvpage .top { background: #0b1120; }
  .tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; justify-content: space-around; gap: 0;
    background: rgba(255,255,255,.94); backdrop-filter: saturate(180%) blur(12px); -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-top: 1px solid var(--line); padding: 4px 4px max(4px, env(safe-area-inset-bottom)); }
  .tabbar a { flex: 1; flex-direction: column; justify-content: center; gap: 2px; height: 54px; padding: 0; font-size: 11px; border-radius: var(--rs); }
  .tabbar a.on, .tabbar a:hover { background: none; color: var(--ours); }
  .tabbar svg { width: 23px; height: 23px; }
  /* the fixed tab bar's real height: 54px buttons + 4px top + the home-indicator inset */
  :root { --tabbar: calc(58px + max(4px, env(safe-area-inset-bottom))); }
  main { padding: 14px 16px calc(var(--tabbar) + 30px); }
  .foot { padding-bottom: calc(var(--tabbar) + 22px); }
  .toast { bottom: calc(var(--tabbar) + 26px); }
  body.gamepage .foot { display: none; }
}

/* ---- basics ---- */
/* the smallest text anywhere: 12px (small inside a 14px heading came out at 11.7) */
small { font-size: max(12px, .85em); }
h2 { margin: 4px 0 14px; font-size: 22px; line-height: 1.3; font-weight: 700; letter-spacing: -0.025em; }
h3 { margin: 24px 0 10px; font-size: 14px; color: var(--mute); font-weight: 600; }
.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.spread { display: flex; gap: 10px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.muted { color: var(--mute); }
.small { font-size: 13px; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--btn); flex: none;
  border: 1px solid var(--line); background: var(--card); border-radius: var(--rs); padding: 0 14px; cursor: pointer; text-decoration: none;
  font-size: 14px; font-weight: 600; white-space: nowrap; color: var(--ink); transition: background .12s, border-color .12s; }
.btn:hover { background: var(--hover); }
.btn.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn.primary { background: var(--ours); color: #fff; border-color: var(--ours); }
.btn.primary:hover { background: #1d4ed8; }
.btn:disabled { opacity: .5; cursor: default; }
.btn.danger { color: var(--bad); border-color: #fecaca; }
.btn.more { display: flex; width: 100%; margin-top: 8px; color: var(--mute); }
.pill { display: inline-flex; align-items: center; height: 24px; padding: 0 10px; border-radius: 999px; font-size: 13px; font-weight: 600;
  background: var(--hover); color: #334155; white-space: nowrap; }
.pill.live { background: var(--bad); color: #fff; }
.pill.w { background: var(--good-soft); color: var(--good); }
.pill.l { background: var(--bad-soft); color: var(--bad); }
.empty { padding: 32px 20px; text-align: center; color: var(--mute); background: var(--card); border-radius: var(--r); border: 1px solid var(--line); }
.empty b { color: var(--ink); }
.panel { background: var(--card); border-radius: var(--r); padding: 16px; border: 1px solid var(--line); box-shadow: var(--shadow); }
.seg { display: inline-flex; background: var(--hover); border-radius: var(--rs); padding: 3px; gap: 2px; flex: none; }
.seg button { border: 0; background: none; border-radius: 8px; padding: 0 14px; height: 32px; cursor: pointer; color: #334155;
  font-size: 14px; font-weight: 600; white-space: nowrap; }
.seg button.on { background: var(--card); color: var(--ink); box-shadow: 0 1px 3px rgba(15,23,42,.18); }
.skeleton { height: 76px; border-radius: var(--r); background: linear-gradient(90deg, #eceff3 25%, #f5f7f9 50%, #eceff3 75%);
  background-size: 200% 100%; animation: sk 1.2s infinite; margin-bottom: 8px; }
@keyframes sk { to { background-position: -200% 0; } }
.toast { position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%); background: var(--ink); color: #fff; max-width: calc(100% - 32px);
  padding: 10px 16px; border-radius: 12px; z-index: 50; font-size: 14px; box-shadow: 0 8px 24px rgba(15,23,42,.2); }
/* a newer version is out: floats over the page (nothing under it moves) until it is tapped */
.newver { position: fixed; left: 50%; top: max(8px, env(safe-area-inset-top)); transform: translateX(-50%); z-index: 70; height: 36px; padding: 0 14px;
  border: 0; border-radius: 999px; background: #1d4ed8; color: #fff; font: inherit; font-size: 13px; font-weight: 600; white-space: nowrap;
  box-shadow: 0 8px 24px rgba(15,23,42,.3); cursor: pointer; }

/* search */
.search { display: flex; align-items: center; gap: 8px; background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 0 14px; height: 48px; box-shadow: var(--shadow); }
.search:focus-within { border-color: var(--ours); box-shadow: 0 0 0 3px rgba(37,99,235,.12); }
.search svg { width: 19px; height: 19px; fill: none; stroke: var(--mute); stroke-width: 2; flex: none; }
.search input, .search input[type=search], .search input[type=text] { flex: 1; border: 0; outline: 0; background: none; font-size: 16px; min-width: 0;
  padding: 0; height: 100%; box-shadow: none; }

/* summary */
.summary { display: flex; gap: 6px 20px; padding: 14px 16px; background: var(--card); border-radius: var(--r); margin-bottom: 12px; flex-wrap: wrap;
  align-items: baseline; border: 1px solid var(--line); }
.summary b { font-size: 22px; font-weight: 700; }
.summary .good b { color: var(--good); } .summary .bad b { color: var(--bad); }

/* stones */
.stone { display: inline-block; width: 12px; height: 12px; border-radius: 50%; vertical-align: -1px; margin-right: 6px; border: 1px solid #334155; flex: none; }
.stone.b { background: #0f172a; } .stone.w { background: #fff; }
.me { font-weight: 700; color: var(--ours); }
a.me, .me a { color: var(--ours); }

/* ---- game list (one component for every list; cards on phones, two columns on wide screens) ---- */
.glist { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 440px), 1fr)); gap: 10px; }
.gitem { display: block; background: var(--card); border-radius: var(--r); padding: 12px 16px; text-decoration: none;
  border: 1px solid var(--line); transition: border-color .12s, box-shadow .12s; }
a.gitem:hover { border-color: #bfdbfe; box-shadow: 0 2px 8px rgba(37,99,235,.08); }
.gitem .where { font-size: 13px; color: var(--mute); display: flex; gap: 8px; justify-content: space-between; height: 20px; }
.gitem .where span { white-space: nowrap; }
.gitem .where span:first-child { overflow: hidden; text-overflow: ellipsis; }
.gitem .vs { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; align-items: center; margin-top: 6px; }
.gitem .seat { display: flex; align-items: center; min-width: 0; font-size: 17px; height: 28px; white-space: nowrap; }
.gitem .seat .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gitem .seat small { margin-left: 6px; color: var(--mute); font-size: 12px; }
/* who won, on the names themselves (lists and cards) */
.seat.win .nm { font-weight: 700; color: var(--ink); }
.seat.lose .nm { color: var(--mute); }
.seat .wl { margin-left: 6px; flex: none; font-size: 12px; font-weight: 700; line-height: 1; padding: 3px 7px; border-radius: 999px; }
.seat.win .wl { background: var(--good); color: #fff; }
.seat.lose .wl { background: var(--bad-soft); color: var(--bad); }
/* ★ by a name on a tournament page: this player in this tournament */
.tstar { flex: none; margin-left: 4px; width: 28px; height: 28px; border: 0; background: none; padding: 0; cursor: pointer;
  font-size: 15px; line-height: 1; color: #d5dbe3; border-radius: 999px; }
.tstar:hover { color: #f59e0b; background: var(--hover); }
.tstar.on { color: #f59e0b; }
.gitem .res { grid-row: span 2; text-align: right; }
.gitem .foot2 { display: flex; gap: 6px; flex-wrap: nowrap; overflow: hidden; font-size: 13px; color: var(--mute); margin-top: 8px; align-items: center; height: 22px; }
.gitem .foot2 > * { flex: none; white-space: nowrap; }
.gitem.nokey { opacity: .7; }
.tag { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 6px; font-size: 12px; font-weight: 600;
  background: var(--hover); color: var(--mute); white-space: nowrap; }
.tag.bad { background: var(--bad-soft); color: var(--bad); }
.tag.ok { background: var(--good-soft); color: var(--good); }

/* live cards with a board */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 12px; }
.gcard { background: var(--card); border-radius: var(--r); padding: 12px; text-decoration: none; display: block; border: 1px solid var(--line); }
.gcard:hover { border-color: var(--ours); }
.gcard.fav { border-color: #fcd34d; box-shadow: 0 0 0 1px #fcd34d; }
.favtag { font-size: 12px; font-weight: 700; color: #b45309; margin-bottom: 4px; height: 18px; }
.gcard .names { display: flex; justify-content: space-between; gap: 6px; font-size: 15px; margin-bottom: 8px; height: 24px; white-space: nowrap; overflow: hidden; }
.gcard .names .seat { display: flex; align-items: center; min-width: 0; }
.gcard .names .nm { overflow: hidden; text-overflow: ellipsis; }
.gcard .meta { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 13px; color: var(--mute); margin-top: 8px; height: 22px; white-space: nowrap; }
.gcard .meta b { font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gcard .meta span { flex: none; }
/* the tournament on its own line at the top of the card, the round and board at its right; the line is there even when empty */
.gcard { min-width: 0; }      /* a long tournament name is cut short, it does not widen the card past its column */
.gcard .ctop { display: flex; justify-content: space-between; gap: 8px; height: 18px; margin-bottom: 6px; font-size: 12px; color: var(--mute); white-space: nowrap; }
.gcard .ctop span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gcard .ctop span:last-child { flex: none; font-weight: 600; }
.gcard .meta2 { display: flex; justify-content: space-between; align-items: center; gap: 6px; font-size: 13px; color: var(--mute); margin-top: 6px; white-space: nowrap; }
/* a phone looking at a whole round: two small boards a row, names stacked */
@media (max-width: 720px) {
  .grid.compact { grid-template-columns: 1fr 1fr; gap: 8px; }
  .grid.compact .gcard { padding: 8px; }
  .grid.compact .gcard .names { flex-direction: column; height: auto; gap: 4px; font-size: 15px; margin-bottom: 6px; }
  .grid.compact .gcard .names .wl { margin-left: auto; }
  .grid.compact .gcard .names small { margin-left: 4px; }
  .grid.compact .gcard .meta2 { flex-direction: column; align-items: flex-start; height: auto; gap: 2px; font-size: 12px; margin-top: 6px; }
  .grid.compact .gcard .meta2 span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
  /* two narrow cards a row: the tournament gets the whole first line (its division is at the end of the name), the round
     and board the second */
  .grid.compact .gcard .ctop { flex-direction: column; gap: 0; height: 34px; line-height: 17px; }
  .grid.compact .gcard .meta { font-size: 12px; margin-top: 6px; }
  .grid.compact .gcard .meta b { font-size: 13px; }
  .grid.compact .favtag { font-size: 12px; }
}
.wbar { height: 6px; border-radius: 3px; background: #e2e8f0; overflow: hidden; margin-top: 8px; }
.wbar i { display: block; height: 100%; background: var(--ours); transition: width .4s; }
.wbar.na i { background: transparent; }

/* chips of favourite players */
.favs { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; scrollbar-width: none; }
.favs a { flex: none; display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 8px 14px; text-decoration: none; width: 128px; }
.favs a b { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.favs a span { font-size: 12px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* tables (admin + standings) */
table.list { width: 100%; border-collapse: collapse; background: var(--card); border-radius: 12px; overflow: hidden; }
.tablewrap { overflow-x: auto; border-radius: 12px; border: 1px solid var(--line); -webkit-overflow-scrolling: touch; }
table.list td, table.list th { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; font-size: 14px; }
table.list tr:last-child td { border-bottom: 0; }
table.list th { color: var(--mute); font-weight: 600; font-size: 12px; background: var(--soft); white-space: nowrap; }
table.list tr.click { cursor: pointer; } table.list tr.click:hover td { background: var(--soft); }
table.list.mini td, table.list.mini th { padding: 7px 9px; font-size: 13px; }
table.list tr.hl td { background: var(--ours-soft); font-weight: 700; }
table.list tr.warnrow td { background: var(--bad-soft); }
.panel.bad { background: var(--bad-soft); border-color: #fecaca; color: var(--bad); }

/* tabs: one scrolling line on phones */
.tabs { display: flex; gap: 6px; margin: 8px 0; align-items: center; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.tabs::-webkit-scrollbar, .favs::-webkit-scrollbar { display: none; }
.tabs .btn { flex: none; }
/* a tournament's pickers: one labelled row each (조 / 라운드 / 보기), chips scroll sideways inside their row */
.tpick { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 12px; padding: 10px 12px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r); }
.prow { display: flex; align-items: center; gap: 10px; min-width: 0; }
.prow .plab { width: 44px; flex: none; font-size: 13px; font-weight: 700; color: var(--mute); }
.prow .tabs { margin: 0; flex: 1; min-width: 0; }
.prow > .row { flex-wrap: nowrap; }
.tabs .btn.later:not(.on) { border-style: dashed; color: var(--mute); font-weight: 500; }
.tsplit { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; align-items: start; }
@media (max-width: 1000px) { .tsplit { grid-template-columns: 1fr; } }

/* ---- board ---- */
svg.board { width: 100%; height: auto; display: block; user-select: none; -webkit-user-select: none; touch-action: pan-y; border-radius: 8px; }
.wood { fill: var(--wood); }
.ln { stroke: var(--woodln); stroke-width: .7; }
.star { fill: var(--woodln); }
.co { font-size: 8px; fill: var(--woodln); text-anchor: middle; }
.sb { fill: #151515; }
.sw { fill: #fafafa; stroke: #555; stroke-width: .6; }
.ghost { opacity: .6; }
.pvn { font-size: 9px; text-anchor: middle; font-weight: 700; }
.pvn.onb { fill: #fff; } .pvn.onw { fill: #000; }
/* move numbers on stones (coloured when the move was a mistake) and KaTrain-style mistake dots */
.mvn { font-size: 8px; text-anchor: middle; font-weight: 700; pointer-events: none; letter-spacing: -.3px; }
.mvn.onb { fill: #fff; } .mvn.onw { fill: #111; }
.mdot { stroke: rgba(255,255,255,.85); stroke-width: .8; pointer-events: none; }
.best { fill: rgba(37,99,235,.18); stroke: #2563eb; stroke-width: 2.4; }
.played { fill: none; stroke: #dc2626; stroke-width: 2.4; }
.pick { fill: none; stroke: #d97706; stroke-width: 2.4; stroke-dasharray: 3 2; }
.lastb { fill: none; stroke: #fff; stroke-width: 1.6; } .lastw { fill: none; stroke: #000; stroke-width: 1.6; }
.lastring { fill: none; stroke: #ef4444; stroke-width: 1.6; pointer-events: none; }
svg.board.clickable { cursor: pointer; touch-action: manipulation; }

/* ---- game page ---- */
/* the board column (title, players, board, evaluation, buttons) is all fixed heights, and the board is sized from the
   screen height so the buttons stay on screen on a laptop */
.gpage { display: grid; grid-template-columns: minmax(0, min(640px, max(360px, calc(100vh - 300px)))) minmax(320px, 1fr); gap: 16px; align-items: start; }
.gpage .side { display: flex; flex-direction: column; gap: 12px; }
.gwhere { height: 28px; font-size: 13px; color: var(--mute); margin-bottom: 4px; white-space: nowrap; display: flex; align-items: center; gap: 8px; }
.gwhere .gw-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gwhere .btn { height: 26px; padding: 0 8px; font-size: 12px; flex: none; }
/* black's or white's point of view for win rate and lead */
.gwhere .seg { padding: 2px; }
.gwhere .seg button { height: 24px; padding: 0 9px; font-size: 12px; }
/* a finger needs ~32px: the game page's top line grows a little on phones */
@media (max-width: 720px) {
  .gwhere { height: 36px; }
  .gwhere .btn { height: 32px; padding: 0 10px; }
  .gwhere .seg { padding: 2px; }
  .gwhere .seg button { height: 30px; padding: 0 10px; }
  .tstar { width: 32px; height: 32px; }
}
.ghead { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 8px; align-items: center; font-size: 15px; height: 30px; }
.ghead .seat { display: flex; align-items: center; min-width: 0; white-space: nowrap; }
.ghead .seat:last-child { justify-content: flex-end; text-align: right; }
.ghead .seat .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
/* the seat being looked from (흑/백 기준) is underlined like a tab; the other one is the switch */
.ghead .seat { height: 100%; cursor: pointer; }
.ghead .seat.on { box-shadow: inset 0 -2px 0 var(--ours); }
.ghead .seat:not(.on) .nm { opacity: .75; }
.morebtn { font-size: 18px; letter-spacing: 1px; min-width: 40px; }
.menulist { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.menulist .btn { justify-content: flex-start; width: 100%; }
.legendbox { margin-top: 8px; }
.legendbox summary { font-size: 12px; color: var(--mute); cursor: pointer; list-style: none; text-align: right; }
.legendbox summary::-webkit-details-marker { display: none; }
.legendbox .legend { margin-top: 6px; }
.boardwrap { position: relative; margin-top: 8px; aspect-ratio: 1; }
.evalstrip { display: flex; align-items: center; gap: 12px; margin-top: 10px; height: 32px; white-space: nowrap; overflow: hidden; }
.evalstrip .turn { flex: none; width: 9em; font-size: 13px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; }
.evalbig { flex: 1; min-width: 0; font-size: 18px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; }
.controls { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 8px; }
.controls.six { grid-template-columns: 1fr 1.3fr 1.3fr 1fr 1.2fr 1.2fr; }
.controls .btn { height: var(--tap); padding: 0; font-size: 15px; width: 100%; user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none; touch-action: manipulation; }
.controls .btn.mis { color: var(--bad); }
.slider { width: 100%; margin: 10px 0 0; accent-color: var(--ours); height: 24px; display: block; }
/* below the controls: the hint line and three bars, each of fixed height */
.hint { font-size: 13px; color: var(--mute); height: 40px; margin-top: 6px; line-height: 20px; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.slot { margin-top: 8px; }
.slot:empty { display: none; }
.pvbar, .aibar, .deepbar { display: flex; align-items: center; gap: 8px; height: 52px; padding: 0 8px 0 14px; border-radius: 12px;
  font-size: 14px; white-space: nowrap; overflow: hidden; border: 1px solid var(--line); background: var(--soft); }
.pvbar > span:first-child, .aibar > span:first-child, .deepbar > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pvbar .btn, .aibar .btn, .deepbar .btn { height: 36px; padding: 0 12px; font-size: 13px; }
.pvbar { background: var(--ours-soft); border-color: #dbeafe; }
.pvbar b { color: var(--ours); }
.pvbar.idle { background: var(--soft); border-color: var(--line); border-style: dashed; color: var(--mute); font-size: 13px; }
.pvbar [data-cmp] { width: 104px; }
.pvbar [data-pv="-1"], .pvbar [data-pv="1"] { width: 40px; padding: 0; }
.pvbar.cmp { padding: 0 8px 0 12px; }
.pvbar.cmp > span:first-child { flex: none; color: var(--mute); }
.pvbar.cmp .btn { flex: 1 1 0; min-width: 0; width: auto; justify-content: space-between; overflow: hidden; }
.pvbar.cmp .btn b { overflow: hidden; text-overflow: ellipsis; }
.pvbar.cmp .btn small { color: var(--mute); font-weight: 500; }
.aibar { background: var(--warn-soft); border-color: #fde68a; }
.deepbar { background: var(--ink); color: #e2e8f0; border-color: var(--ink); }
.deepbar .btn { background: #1e293b; color: #f1f5f9; border-color: #334155; }
.deepbar .btn:hover { background: #334155; }
.deepbar .btn.on { background: #f1f5f9; color: var(--ink); border-color: #f1f5f9; }
.deepbar b { color: #60a5fa; }
/* 보관함 */
.keepbtn.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.foldertabs { flex-wrap: wrap; margin-top: 10px; }
.foldertabs small { opacity: .7; margin-left: 2px; }
.boxlist { display: flex; flex-direction: column; gap: 10px; }
.boxrow { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.boxrow .gitem { border: 0; border-radius: 0; box-shadow: none; }
.boxact { display: flex; gap: 6px; align-items: center; padding: 8px 10px; border-top: 1px solid var(--line); background: var(--soft); }
.boxact .note { flex: 1; min-width: 0; height: 36px; font-size: 14px; }
.sheet { position: fixed; inset: 0; z-index: 60; background: rgba(15,23,42,.45); display: flex; align-items: flex-end; justify-content: center; }
.sheetbox { background: var(--card); width: min(480px, 100%); border-radius: 16px 16px 0 0; padding: 16px 16px max(16px, env(safe-area-inset-bottom)); }
@media (min-width: 721px) { .sheet { align-items: center; } .sheetbox { border-radius: 16px; } }
/* 다른 판: the same tournament's games of the day, one row each */
.siblist { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; max-height: min(60vh, 460px); overflow-y: auto; }
.sibrow { display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 6px 10px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--ink); font: inherit; font-size: 15px; text-align: left; cursor: pointer; }
.sibrow.on { background: var(--bg); cursor: default; }
.sibvs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; white-space: nowrap; overflow: hidden; }
.sibvs .nm { overflow: hidden; text-overflow: ellipsis; }
.sibvs .nm.me { font-weight: 700; color: var(--pri, #2563eb); }
.sibvs i { font-style: normal; color: var(--mute); margin: 0 2px; }
.sibres { flex: none; }
.sibwin { flex: none; font-size: 11px; font-weight: 700; color: #fff; background: var(--good); border-radius: 4px; padding: 1px 4px; }
.tvsib { flex: none; height: 28px; padding: 0 10px; font-size: 12px; background: #1e293b; color: #e2e8f0; border-color: #334155; }
.mtabs button.sib { flex: 0 0 auto; padding: 0 12px; color: var(--ink); border-style: dashed; }
/* ★ on a game (this account's own): in a list row beside the time, on the heads of the game and broadcast screens */
.gitem .where span:last-child { display: inline-flex; align-items: center; flex: none; }
.gitem .where .gstar { width: 26px; height: 20px; margin: 0 -6px 0 2px; font-size: 14px; }
.tvstar { color: #475569; }
.tvstar.on { color: #f59e0b; }
.tvhead .tstar:hover { background: #1e293b; }
@media (max-width: 720px) and (orientation: portrait) { .gpage .gwhere .gstar.hd { display: none; } .tvhead .tvsib { padding: 0 8px; } }
@media (max-width: 720px) and (orientation: portrait) { .gpage .gwhere .sibbtn { display: none; } }
.folderpick { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; max-height: 50vh; overflow-y: auto; }
.folderpick label { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 4px; font-size: 15px; border-bottom: 1px solid var(--line); }
.folderpick input { width: 20px; height: 20px; }
/* what the board shows besides the game: 후보수 / 실수 / 수 번호 (Lizzie's switches) */
.viewbar { display: flex; gap: 6px; height: 40px; align-items: center; margin-top: 8px; }
.vbtn { height: 32px; padding: 0 12px; font-size: 13px; }
.vbtn.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.legend { display: flex; gap: 6px 12px; flex-wrap: wrap; font-size: 12px; color: var(--mute); margin-top: 10px; }
.legend label { display: inline-flex; align-items: center; gap: 4px; }
.legend i { display: inline-block; width: 12px; height: 12px; border-radius: 50%; vertical-align: -2px; margin-right: 4px; }
.legend .lb { border: 2.5px solid #2563eb; background: rgba(37,99,235,.18); } .legend .lp { border: 2.5px solid #dc2626; }
.legend .lk { border: 2.5px dashed #d97706; }
.legend .lm { width: 8px; height: 8px; background: #FF9100; box-shadow: 0 0 0 3px #151515; margin: 0 6px 0 3px; }
.graph { width: 100%; height: 130px; display: block; cursor: pointer; border-radius: 10px; touch-action: none; }
#gtip { margin-top: 6px; }
.mistakes { display: flex; flex-direction: column; gap: 4px; max-height: 420px; overflow: auto; }
.mistakes button { display: flex; justify-content: space-between; align-items: center; gap: 8px; text-align: left; border: 1px solid transparent;
  background: var(--soft); border-radius: var(--rs); padding: 0 12px; height: var(--tap); flex: none; cursor: pointer; white-space: nowrap; }
.mistakes button:hover { background: var(--hover); }
.mistakes button.cur { border-color: var(--ours); background: var(--ours-soft); }
.mistakes button > span:first-child { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.mistakes button .t { font-size: 13px; color: var(--mute); }
.drop { color: var(--bad); font-weight: 700; white-space: nowrap; }
.mcount { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0; }
.mcount button { border: 1px solid var(--line); background: var(--card); border-radius: 999px; padding: 0 14px; height: 34px; cursor: pointer;
  font-size: 14px; font-weight: 600; white-space: nowrap; }
.mcount button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
/* 부정확 포함: a switch, not a filter like 전체/흑 — on the right, outlined, blue when on */
.mcount .mtoggle { margin-left: auto; font-weight: 500; color: var(--mute); border-style: dashed; padding: 0 12px; }
.mcount .mtoggle.on { background: var(--ours-soft); color: var(--ours); border: 1px solid var(--ours); font-weight: 600; }
@media (max-width: 900px) {
  .gpage { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .gpage > .panel:first-child { margin: 0 -16px; border-radius: 0; border-width: 1px 0; box-shadow: none; padding: 10px 8px 12px; }
  .gpage .ghead, .gpage .gwhere, .gpage .evalstrip, .gpage .hint { padding: 0 6px; }
  .controls { position: sticky; bottom: var(--tabbar, 70px); z-index: 10; background: var(--card); padding: 6px 0; }
}

/* ---- training ---- */
/* the board leaves room for the ◀ ▶ buttons under it on a laptop screen */
.quiz { display: grid; grid-template-columns: minmax(0, min(600px, max(360px, calc(100vh - 300px)))) minmax(280px, 1fr); gap: 16px; align-items: start; }
.qbtns { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; margin-top: 10px; }
.qbtns .btn { height: var(--tap); width: 100%; }
@media (max-width: 900px) {
  .quiz { grid-template-columns: minmax(0, 1fr); }
  .quiz > .panel:first-child { margin: 0 -16px; border-radius: 0; border-width: 1px 0; box-shadow: none; padding: 10px 8px; }
  .qbtns { position: sticky; bottom: var(--tabbar, 70px); z-index: 10; background: var(--card); padding: 6px 0; }
  .trainhead h2 { font-size: 19px; }
}
.qprompt { font-size: 17px; font-weight: 700; margin: 4px 6px 8px; min-height: 26px; }
.qres { padding: 12px 14px; border-radius: 12px; min-height: 120px; }
.qres.wait { background: var(--card); border: 1px dashed #cbd5e1; }
.quiz #pvbar:not(:empty) { margin-top: 10px; }
.qres.ok { background: var(--good-soft); } .qres.no { background: var(--warn-soft); }
.score { display: flex; gap: 14px; font-size: 14px; color: var(--mute); white-space: nowrap; }
.score b { color: var(--ink); font-size: 18px; }

/* ---- forms (admin) ---- */
textarea { width: 100%; min-height: 120px; padding: 10px 12px; border-radius: var(--rs); border: 1px solid #cbd5e1; background: var(--card); }
input[type=text], input[type=password], input[type=search], input[type=date], select {
  padding: 0 12px; height: var(--btn); border-radius: var(--rs); border: 1px solid #cbd5e1; background: var(--card); color: var(--ink); font-size: 15px; }
select { appearance: none; -webkit-appearance: none; padding-right: 30px;
  background: var(--card) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2364748b' stroke-width='1.6'/%3E%3C/svg%3E") no-repeat right 11px center; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 0; border-color: var(--ours); box-shadow: 0 0 0 3px rgba(37,99,235,.15); }
.btn:focus-visible { outline: 2px solid var(--ours); outline-offset: 1px; }
input[type=checkbox] { accent-color: var(--ours); width: 16px; height: 16px; vertical-align: -3px; }
.chip { display: inline-flex; gap: 6px; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: 999px;
  height: 32px; padding: 0 4px 0 12px; margin: 3px; white-space: nowrap; }
.chip button { border: 0; background: var(--hover); border-radius: 50%; width: 28px; height: 28px; cursor: pointer; }
.star-btn { cursor: pointer; border: 0; background: none; font-size: 22px; color: #94a3b8; width: 40px; height: 40px; flex: none; }
.star-btn.on { color: #f59e0b; }
.kv { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px 16px; margin-top: 8px; font-size: 14px; }
.form1 { display: flex; flex-direction: column; gap: 12px; }
.form1 label, .form2 label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--mute); font-weight: 500; }
.form2 { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px 16px; }
.err { color: var(--bad); font-size: 13px; }
.badge:not(:empty) { background: var(--bad); color: #fff; border-radius: 999px; padding: 0 6px; font-size: 11px; margin-left: 4px; }
hr { border: 0; border-top: 1px solid var(--line); margin: 16px 0; }
.pcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 10px; }
.pcard { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; font-size: 13px; display: flex; flex-direction: column; gap: 2px; background: var(--soft); }
.pcard a { text-decoration: none; }
.pcard .big { font-size: 22px; font-weight: 700; color: var(--ink); }
.cands { display: flex; flex-wrap: wrap; gap: 6px; }
.btn.cand { text-align: left; line-height: 1.35; display: block; height: auto; min-height: var(--btn); padding: 6px 12px; white-space: normal; }
.btn.cand.here { border-color: var(--good); }
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; }
.dot.ok { background: var(--good); } .dot.bad { background: var(--bad); }

/* ---- Lizzie-style candidates, territory, deep analysis ---- */
.cand { cursor: pointer; }
.cand circle { stroke: rgba(0,0,0,.35); stroke-width: .6; }
.cand.sel circle { stroke: #fff; stroke-width: 1.6; }
/* KataGo reading: the strip on the board's top edge, and a candidate that just changed (rank, win rate or lead) */
.rtrack { fill: rgba(15,23,42,.18); }
.rfill { fill: #2563eb; }
.cand.chg circle { animation: candchg .7s ease-out; }
@keyframes candchg { 0% { stroke: #fff; stroke-width: 3.2; } 100% { stroke: rgba(0,0,0,.35); stroke-width: .6; } }
.tvnext.chg { animation: rowchg .7s ease-out; }
@keyframes rowchg { 0% { background: rgba(96,165,250,.35); } 100% { background: transparent; } }
@media (prefers-reduced-motion: reduce) { .cand.chg circle, .tvnext.chg { animation: none; } }
.cw { font-size: 6.6px; font-weight: 800; text-anchor: middle; fill: #10141a; }
.cs { font-size: 4.6px; text-anchor: middle; fill: #10141a; }
.ob { fill: #111; } .ow { fill: #fff; stroke: #555; stroke-width: .3; }
.candlist { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
/* eight rows, filled or not: the panels under it stay put when candidates come and go (deep reading, a move without them) */
@media (min-width: 721px) { #cands { height: 348px; overflow-y: auto; } }
.candlist button { display: grid; grid-template-columns: 58px 1fr 104px 44px; gap: 10px; align-items: center; text-align: left; border: 1px solid transparent;
  background: var(--soft); border-radius: var(--rs); padding: 0 12px; height: 40px; flex: none; cursor: pointer; font-size: 14px; white-space: nowrap; }
.candlist button:hover { background: var(--hover); }
.candlist button.sel { border-color: var(--ours); background: var(--ours-soft); }
.candlist button > :nth-child(4) { text-align: right; }
.candlist button > :nth-child(3) { font-weight: 700; }
/* a phone held upright: under the pinned board there is room for about 190px of list. Rows closer together, and on
   the 연구판 no heading over them (whose turn and how much was read are on the bar above), so seven show where four
   did (2026-11-14, the user: 1순위 있는 곳 공간이 너무 작아서 쓰기 불편) */
@media (max-width: 720px) and (orientation: portrait) {
  .candlist { gap: 2px; margin-top: 6px; }
  .candlist button { height: 34px; grid-template-columns: 50px 1fr 112px 38px; gap: 8px; padding: 0 10px; }
  .gpage.free .side .panel { padding: 4px 6px; margin-top: 6px; }
  .gpage.free .side .panel > .spread { display: none; }
  .gpage.free .candlist { margin-top: 0; }
}
.candlist .bar { height: 6px; border-radius: 3px; background: #dbeafe; overflow: hidden; } .candlist .bar i { display: block; height: 100%; background: var(--ours); }

/* ---- move grades, report card, compare ---- */
.gb { display: inline-flex; align-items: center; height: 20px; color: #fff; font-size: 12px; font-weight: 700; padding: 0 7px; border-radius: 6px;
  white-space: nowrap; vertical-align: 1px; }
.rep { padding: 12px 0 4px; border-top: 1px solid var(--line); margin-top: 10px; }
.rep.me .spread b { color: var(--ours); }
.rep .acc { font-size: 14px; }
.letter { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 8px; color: #fff; font-size: 14px; font-weight: 800; margin-right: 6px; }
.lS { background: #7c3aed; } .lA { background: #2563eb; } .lB { background: #16a34a; } .lC { background: #ca8a04; } .lD { background: #ea580c; } .lF { background: #dc2626; } .l- { background: #94a3b8; }
.hist { display: flex; height: 8px; border-radius: 4px; overflow: hidden; margin: 8px 0 6px; background: var(--hover); }
.hist i { display: block; height: 100%; }
.dotc { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin: 0 3px 0 8px; }
@media (max-width: 720px) { .replegend { display: none; } }
.rep.me .spread b.letter { color: #fff; }

/* ---- team-only ---- */
.memberlink { display: inline-flex; align-items: center; height: 32px; text-decoration: none; font-size: 13px; font-weight: 600;
  padding: 0 12px; border-radius: 999px; border: 1px solid var(--line); white-space: nowrap; color: var(--mute); }
.memberlink.on { background: var(--good-soft); border-color: #a7f3d0; color: var(--good); }
.lock { display: flex; flex-direction: column; gap: 8px; background: var(--warn-soft); border: 1px dashed #fcd34d; border-radius: 12px; padding: 14px; font-size: 14px; }
.memberlink.warn { background: var(--warn-soft); border-color: #fcd34d; color: #92400e; }
.lock .btn { align-self: flex-start; }
/* logged out: only the login box (no tabs, no account link, no footer counts) */
body.nologin .tabbar, body.nologin .acct, body.nologin .foot { display: none; }
/* top right: who is in · settings (gear) · log out */
.acct { margin-left: auto; display: flex; align-items: center; gap: 6px; min-width: 0; }
.acct [hidden] { display: none; }
/* first login on the issued password: only the settings page (no tabs, no gear) until it is changed */
body.pwfirst .tabbar, body.pwfirst #gearLink { display: none; }
/* one-column pages (설정): centred, not a strip down the left of a wide screen */
.narrow { max-width: 560px; margin: 0 auto; }
.acct .memberlink { max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--mute); background: none; flex: none; }
.iconbtn:hover, .iconbtn.on { color: var(--ink); background: var(--hover); }
.iconbtn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.logoutbtn { height: 32px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--line); background: none; color: var(--mute);
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; flex: none; }
.logoutbtn:hover { color: var(--bad); border-color: #fecaca; }
@media (max-width: 720px) { .acct .memberlink { max-width: 96px; padding: 0 10px; } .logoutbtn { padding: 0 10px; } }
.tabbar a[hidden] { display: none; }
.loginbox { max-width: 380px; margin: 40px auto; }
.loginbox h2 { display: flex; align-items: center; gap: 8px; margin-top: 0; }
.loginbox input { height: 48px; font-size: 16px; }
.loginbox .btn { height: 48px; }

/* ---- broadcast (중계) ---- */
body.tvpage { background: #0b1120; }
body.tvpage .top { background: rgba(11,17,32,.85); border-bottom-color: #1e293b; color: #e2e8f0; }
body.tvpage .tabbar { background: rgba(11,17,32,.94); border-top-color: #1e293b; }
body.tvpage .tabbar a { color: #94a3b8; }
body.tvpage .tabbar a.on, body.tvpage .tabbar a:hover { background: #1e293b; color: #f1f5f9; }
body.tvpage .memberlink, body.tvpage .iconbtn, body.tvpage .logoutbtn { background-color: #1e293b; border-color: #334155; color: #e2e8f0; }
body.tvpage .foot { display: none; }
body.tvpage main { max-width: none; padding-top: 12px; }
.tv { color: #e2e8f0; }
.tvhead { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 14px; color: #94a3b8; margin-bottom: 10px; height: 28px; white-space: nowrap; }
.tvwhere { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.wrrow { display: grid; grid-template-columns: minmax(0, 1fr) minmax(160px, 3fr) minmax(0, 1fr); gap: 12px; align-items: center; margin-bottom: 12px; }
.wrname { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 16px; white-space: nowrap; overflow: hidden; height: 36px; }
.wrname.r { justify-content: flex-end; }
.wrname small { color: #94a3b8; }
.wrname b.me { color: #60a5fa; }
/* the number that is our player's stands out, the other steps back: same size, so nothing moves */
.wrpct.me { color: #60a5fa; }
.wrpct.opp { opacity: .5; }
.wrpct { font-size: 22px; font-weight: 800; margin: 0 4px; width: 2.6em; flex: none; text-align: center; }
.wrbar2 { position: relative; height: 32px; border-radius: 16px; background: #f8fafc; overflow: hidden; outline: 2px solid #64748b; outline-offset: 1px; }
.wrbar2 i { position: absolute; left: 0; top: 0; bottom: 0; background: #000; transition: width .6s ease; }
.wrbar2 span { position: absolute; inset: 0; display: grid; place-items: center; font-weight: 800; font-size: 15px; color: #fff; mix-blend-mode: difference; }
.tvmain { display: grid; grid-template-columns: minmax(0, min(calc(100vh - 180px), 62vw)) minmax(320px, 1fr); gap: 16px; align-items: start; }
.tvboard svg.board { border-radius: 10px; }
.tvside { display: flex; flex-direction: column; gap: 10px; }
.tvcard { background: #111a2e; border: 1px solid #1e293b; border-radius: 14px; padding: 14px 16px; }
#lastMove { height: 118px; overflow: hidden; }
#nextMoves { height: 182px; overflow: hidden; }
.tvcard .graph { height: 120px; }
.tvlabel { font-size: 13px; color: #94a3b8; margin-bottom: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tvlabel small { color: #64748b; }
.tvbig { font-size: 26px; font-weight: 800; display: flex; align-items: center; gap: 4px; height: 38px; }
.tvbig .stone { width: 18px; height: 18px; }
.tvgrade { margin-top: 6px; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tvgrade b { color: #60a5fa; }
.tvnext { display: grid; grid-template-columns: 30px 56px 1fr auto; gap: 8px; align-items: center; height: 46px; font-size: 18px; border-top: 1px solid #1e293b; white-space: nowrap; }
.tvnext:first-of-type { border-top: 0; }
.tvnext[data-ck] { cursor: pointer; }
.tvnext.sel { background: #1e293b; box-shadow: inset 3px 0 0 #60a5fa; }
.tvhint { height: 20px; line-height: 20px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tvhd { display: flex; align-items: center; gap: 6px; height: 34px; }
.tvhd .tvlabel { flex: 1; min-width: 0; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tvmini { flex: none; height: 32px; padding: 0 12px; background: #1e293b; color: #e2e8f0; border-color: #334155; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tvmini.wide { min-width: 124px; }
.tvmini.on { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
.rk { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; font-size: 14px; color: #0b1120; }
.rk.r0 { background: #22d3ee; } .rk.r1 { background: #a3e635; } .rk.r2 { background: #fbbf24; }
.tvctl { display: grid; grid-template-columns: 44px 44px 1fr auto auto auto; gap: 6px; }
.tvctl .btn { background: #1e293b; color: #e2e8f0; border-color: #334155; height: var(--tap); padding: 0 12px; }
.tvctl .btn:hover { background: #334155; }
.tvctl [data-tv="-1"], .tvctl [data-tv="1"] { padding: 0; }
.tvctl .btn.on { background: #dc2626; border-color: #dc2626; color: #fff; }
.tvdeep { width: 100%; margin-top: 10px; background: #1e293b; color: #e2e8f0; border-color: #334155; }
.tvdeep.on { background: #1d4ed8; border-color: #1d4ed8; color: #fff; }
.tv .muted { color: #94a3b8; }
.tv .pill { background: #1e293b; color: #cbd5e1; }
.tv .pill.live { background: #dc2626; color: #fff; }
@media (max-width: 900px) {
  .tvmain { grid-template-columns: minmax(0, 1fr); }
  .tvboard { margin: 0 -12px; }
  .wrrow { grid-template-columns: 1fr 1fr; }
  .wrbar2 { grid-column: 1 / -1; grid-row: 2; }
  .wrpct { font-size: 18px; }
  .tvctl { grid-template-columns: 44px 44px 1fr 1fr; }
  .tvctl > :last-child { grid-column: 1 / -1; }
  .tvctl:has(#tvAi) > :last-child, .tvctl:has(#tvAi) [data-tv="full"] { grid-column: span 2; }
}
.tv .stone.b { background: #000; border: 1.5px solid #e2e8f0; box-sizing: border-box; }

/* starred tournaments: the star sits in the card's bottom-right corner */
.tcard { position: relative; }
.tcard .star-btn { position: absolute; right: 6px; bottom: 4px; }

/* player page, "포석·흐름": opening heat map per colour, first-move kinds, win rate lost by phase */
.scoutgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; margin: 12px 0; }
.heatwrap { max-width: 420px; margin: 8px auto 0; }
.heatwrap svg { width: 100%; height: auto; display: block; }
.heat { fill: var(--ours); }
.heatn { fill: #fff; font-size: 10px; font-weight: 700; text-anchor: middle; pointer-events: none; }
.fm { border-top: 1px solid var(--line); }
.fm summary { display: grid; grid-template-columns: 44px 1fr 88px; align-items: center; gap: 8px; height: 36px; cursor: pointer; list-style: none; font-size: 14px; }
.fm summary::-webkit-details-marker { display: none; }
.fm .k { font-weight: 700; }
.fm .n { text-align: right; color: var(--mute); font-size: 13px; white-space: nowrap; }
.fm .bar { height: 8px; background: var(--hover); border-radius: 4px; overflow: hidden; }
.fm .bar i { display: block; height: 100%; background: var(--ours); }
.fm .row { padding: 0 0 10px 52px; gap: 6px; }
.fm .row a { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; height: 28px; border: 1px solid var(--line); border-radius: 6px; text-decoration: none; }
.phase { margin-top: 10px; }
.phase .pbar { position: relative; height: 10px; background: var(--hover); border-radius: 5px; margin-top: 4px; }
.phase .pbar i { display: block; height: 100%; background: var(--ours); border-radius: 5px; }
.phase .pbar s { position: absolute; top: -3px; width: 2px; height: 16px; background: var(--mute); }
.phase.worst .pbar i { background: var(--bad); }
.phase.worst b { color: var(--bad); }

/* ---- phones ---- */
/* help text that names the mouse or the keyboard is swapped for the touch one */
.touch-only { display: none; }
@media (hover: none) { .touch-only { display: inline; } .mouse-only { display: none; } }
@media (max-width: 720px) {
  /* iOS zooms the page into any field under 16px */
  input[type=text], input[type=password], input[type=search], input[type=date], select, textarea { font-size: 16px; }
  /* the bars keep their height but their label may take two lines instead of being cut */
  .pvbar > span:first-child, .aibar > span:first-child, .deepbar > span:first-child { white-space: normal; line-height: 18px; font-size: 13px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .pvbar.cmp > span:first-child { display: block; }
  .legend label { height: 32px; padding-right: 6px; }
  .legend input[type=checkbox] { width: 20px; height: 20px; }
}
/* a phone on its side: the board is sized from the height, and its column stays put while the side scrolls */
@media (orientation: landscape) and (max-height: 560px) {
  :root { --hdr: 44px; }
  .top, main { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
  main { padding-top: 8px; }
  .gpage, .quiz { grid-template-columns: minmax(0, min(calc(100vh - var(--hdr) - 84px), 56vw)) minmax(0, 1fr); gap: 12px; }
  .gpage > .panel:first-child, .quiz > .panel:first-child { margin: 0; border-radius: var(--r); border-width: 1px; padding: 8px;
    position: sticky; top: calc(var(--hdr) + 8px); max-height: calc(100vh - var(--hdr) - 16px); overflow-y: auto; overscroll-behavior: contain; }
  .gpage .ghead, .gpage .gwhere, .gpage .evalstrip, .gpage .hint { padding: 0; }
  .controls, .qbtns { position: static; padding: 0; }
  .controls .btn { font-size: 13px; }
  .pvbar > span:first-child, .aibar > span:first-child, .deepbar > span:first-child { white-space: normal; line-height: 18px; font-size: 13px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .pvbar.cmp > span:first-child { display: block; }
  .tvmain { grid-template-columns: minmax(0, min(calc(100vh - var(--hdr) - 110px), 56vw)) minmax(0, 1fr); }
  .tvboard { margin: 0; }
  .wrrow { grid-template-columns: minmax(0, 1fr) minmax(120px, 3fr) minmax(0, 1fr); margin-bottom: 8px; }
  .wrbar2 { grid-column: auto; grid-row: auto; }
  .tvhead { margin-bottom: 4px; }
}
@supports (height: 100dvh) {
  @media (orientation: landscape) and (max-height: 560px) {
    .gpage, .quiz { grid-template-columns: minmax(0, min(calc(100dvh - var(--hdr) - 84px), 56vw)) minmax(0, 1fr); }
    .gpage > .panel:first-child, .quiz > .panel:first-child { max-height: calc(100dvh - var(--hdr) - 16px); }
    .tvmain { grid-template-columns: minmax(0, min(calc(100dvh - var(--hdr) - 110px), 56vw)) minmax(0, 1fr); }
  }
}
/* the game page on a phone turned sideways, like a video: no header, the board fills the height and stays put on the
   left, everything else scrolls beside it (2026-11-05) */
@media (orientation: landscape) and (max-height: 560px) {
  body.gamepage, body.tvpage { --bside: calc(100vh - 8px); }
  body.gamepage .top, body.tvpage .top { display: none; }
  body.gamepage main, body.tvpage main { max-width: none; padding: 8px max(12px, env(safe-area-inset-right)) 24px
    calc(var(--bside) + max(4px, env(safe-area-inset-left)) + 12px); }
  body.tvpage .tvmain { grid-template-columns: minmax(0, 1fr); }
  body.tvpage .tvboard { position: fixed; z-index: 7; top: 4px; left: max(4px, env(safe-area-inset-left)); margin: 0;
    width: var(--bside); height: var(--bside); }
  body.gamepage .gpage { grid-template-columns: minmax(0, 1fr); }
  body.gamepage .gpage > .panel:first-child { position: static; max-height: none; overflow: visible; }
  body.gamepage .gpage .boardwrap { position: fixed; z-index: 7; top: 4px; left: max(4px, env(safe-area-inset-left)); margin: 0;
    width: var(--bside); height: var(--bside); }
}
@supports (height: 100dvh) {
  @media (orientation: landscape) and (max-height: 560px) { body.gamepage, body.tvpage { --bside: calc(100dvh - 8px); } }
}

/* ---- game page on a phone held upright: the board is pinned, the side panels are tabs, the move buttons sit at
   the bottom where the app's tab bar was (a back button replaces the header) ---- */
.backbtn, .mtabs, .graph.mini, #mbar, .ngtp { display: none; }
/* labels on the board at a mistake: the AI's move (blue) and the move played (red) */
.btag { pointer-events: none; }
.btag rect { fill: #2563eb; } .btag.tme rect { fill: #dc2626; }
.btag text { fill: #fff; font-size: 10px; font-weight: 700; text-anchor: middle; }
svg.board { -webkit-touch-callout: none; }
/* 후보수 for a quick-look game: this position only (deep, seconds) or the whole game (full analysis, a minute) */
.pick2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
/* (inside .candlist, whose buttons are candidate rows laid out as a grid) */
.pick2 .btn { display: flex; height: auto; min-height: 54px; flex-direction: column; gap: 1px; white-space: normal; text-align: center; }
.pick2 .btn small { font-weight: 500; font-size: 12px; opacity: .85; }
/* the broadcast screen on a phone held upright (2026-11-14, the user: 바둑판은 위에 고정 + 승률): one fixed screen —
   the names with the win-rate bar and the board stay put, only the cards under the board scroll, the next moves
   (win rate of each) first. The app's header gives its room to the board (← is on the screen's own line) */
@media (max-width: 720px) and (orientation: portrait) {
  body.tvpage .top { display: none; }
  body.tvpage main { padding: 0; }
  .tv { position: fixed; top: 0; left: 0; right: 0; bottom: var(--tabbar); z-index: 1; display: flex; flex-direction: column; background: #0b1120; }
  .tv .tvhead { flex: none; margin: 0; padding: 6px 10px 0; height: 36px; }
  .tv .wrrow { flex: none; margin: 2px 10px 6px; gap: 2px 12px; }
  .tv .wrname { height: 28px; font-size: 14px; }
  .tv .wrbar2 { height: 22px; margin: 0 2px; }
  .tv .wrbar2 span { font-size: 13px; }
  .tv .tvmain { display: contents; }
  .tv .tvboard { flex: none; margin: 0; }
  .tv .tvboard svg.board { border-radius: 0; display: block; }
  .tv .tvside { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 10px 14px; }
  .tv .tvside > * { flex: none; }
  .tv #nextMoves { order: -1; }
}
@media (max-width: 720px) and (orientation: portrait) {
  body.gamepage .top, body.gamepage .tabbar { display: none; }
  body.gamepage { --tabbar: calc(56px + max(6px, env(safe-area-inset-bottom))); }
  body.gamepage main { padding-top: 0; }
  /* one fixed screen, like an app: it scrolls inside itself, so the browser's address bar never comes and goes and the
     page under the finger does not shift; the board pins at the top, the tabs under it (pinBoard) */
  .gpage { position: fixed; top: 0; left: 0; right: 0; bottom: var(--tabbar); z-index: 1; overflow-y: auto; overscroll-behavior: contain;
    padding: 0 16px 16px; background: var(--bg); }
  .gpage .bcol { display: contents; }
  .gpage .bpanel { position: sticky; z-index: 6; margin: 0 -16px; padding: 6px 8px 6px; background: var(--card);
    border-bottom: 1px solid var(--line); box-shadow: 0 6px 12px -10px rgba(15,23,42,.35); }
  .gpage .bpanel .gwhere { margin: 0; padding: 0; height: 40px; }
  .backbtn { display: inline-flex; width: 36px; height: 32px !important; padding: 0 !important; font-size: 18px !important; }
  .gpage .ghead { padding: 0 4px; }
  /* the board panel never moves (pinBoard), so above the board one line only: ← 흑 · 결과 · 백 ⋯ — the tournament
     line moves into ⋯ and the list under the board gets the room. A live game keeps its line for 중계 화면 */
  .gpage .bpanel.oneline .gwhere { height: 0; }
  .gpage .bpanel.oneline .gwhere .gw-t { display: none; }
  .gpage .bpanel.oneline .gwhere .btn { position: absolute; top: 9px; z-index: 2; }
  .gpage .bpanel.oneline .gwhere .backbtn { left: 8px; }
  .gpage .bpanel.oneline .gwhere .morebtn { right: 8px; height: 32px; }
  .gpage .bpanel.oneline .gwhere .fsbtn { right: 52px; height: 32px; }
  .gpage .bpanel.oneline .ghead { height: 38px; padding: 0 92px 0 48px; }
  .gpage .evalstrip { margin-top: 6px; height: 28px; padding: 0 4px; }
  .graph.mini { display: block; height: 34px; margin-top: 4px; border-radius: 6px; }
  .gpage .controls { position: fixed; left: 0; right: 0; bottom: 0; z-index: 25; margin: 0; gap: 4px;
    padding: 6px 8px max(6px, env(safe-area-inset-bottom)); background: rgba(255,255,255,.96); border-top: 1px solid var(--line);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
  .gpage .controls .btn { height: 44px; }
  .gpage .tools { padding: 0; }
  /* no legend on a phone: it pushed the tabs under the move buttons, and its text is for a mouse (2026-11-15) */
  .gpage.rv .legendbox { display: none; }
  /* the board edge to edge; under it one line for what can be done here (#mbar) instead of the slider, the hint and
     the compare / deep bars — the compare is on the board itself (labelled moves, tap for the line) */
  .gpage .bpanel .boardwrap { margin: 6px -8px 0; }
  .gpage .bpanel svg.board { border-radius: 0; }
  .gpage .slider, .gpage .bpanel .hint, .gpage .bpanel #pvbar, .gpage .bpanel #deepbar, .gpage .viewbar { display: none; }
  #mbar { display: block; margin-top: 4px; }
  .mb { display: flex; align-items: center; gap: 6px; height: 44px; padding: 0 4px 0 10px; border-radius: 10px; background: var(--soft);
    border: 1px solid var(--line); font-size: 14px; white-space: nowrap; overflow: hidden; }
  .mb > span:first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .mb small { color: var(--mute); font-size: 12px; }
  .mb .btn { height: 34px; padding: 0 11px; font-size: 13px; }
  .mb.views { padding-left: 5px; }
  .mb.views > span { flex: 1; }
  .mb.dark { background: var(--ink); color: #e2e8f0; border-color: var(--ink); }
  .mb.dark b { color: #60a5fa; }
  .mb.dark .btn { background: #1e293b; color: #f1f5f9; border-color: #334155; }
  .mb.dark .btn.on { background: #f1f5f9; color: var(--ink); border-color: #f1f5f9; }
  /* coordinates mean nothing to the players: the board shows where */
  .gtp { display: none; }
  .ngtp { display: inline; }
  .mtabs { display: flex; position: sticky; z-index: 5; gap: 4px; margin: 4px -16px 10px; padding: 8px 16px; background: var(--bg); }
  .mtabs button { flex: 1; height: 38px; border: 1px solid var(--line); background: var(--card); border-radius: 999px; font-size: 14px;
    font-weight: 600; color: var(--mute); cursor: pointer; white-space: nowrap; }
  .mtabs button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
  .gpage [data-pane] { display: none; }
  .gpage[data-tab="mist"] [data-pane="mist"], .gpage[data-tab="rep"] [data-pane="rep"], .gpage[data-tab="cand"] [data-pane="cand"] { display: block; }
  .gpage .mistakes { max-height: none; }
  /* the tab already says 실수; the grading note stays on wide screens */
  .gpage [data-pane="mist"] > .spread > b, .gpage [data-pane="mist"] > .muted.small { display: none; }
  .gpage [data-pane="mist"] .mcount { margin-top: 0; }
}

/* a short phone (360×640 class): no graph strip, tabs scroll with the page, lower buttons — so the list keeps a few rows */
@media (max-width: 720px) and (orientation: portrait) and (max-height: 700px) {
  .graph.mini { display: none; }
  .mtabs { position: static; margin-bottom: 6px; }
  .gpage .evalstrip { height: 24px; margin-top: 4px; }
  .gpage .controls .btn { height: 38px; }
  body.gamepage { --tabbar: calc(50px + max(6px, env(safe-area-inset-bottom))); }
}

/* professional games (#/pro) */
.prosearch .profields { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.prosearch .profields input { flex: 1 1 140px; min-width: 0; height: 40px; padding: 0 12px; font-size: 15px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--card); color: var(--ink); }
.prosearch .profields input[type=number] { flex: 0 1 110px; }
.prosearch .profields .btn { flex: none; height: 40px; }
a.chip { text-decoration: none; color: var(--ink); padding: 0 12px; }
a.chip small { color: var(--mute); }
.pronav { justify-content: center; margin-top: 12px; }
a.chip.on { background: var(--ours); border-color: var(--ours); color: #fff; }
a.chip.on small { color: rgba(255,255,255,.8); }
.prosearch .profields.dates { align-items: flex-end; }
.prosearch .pf { display: flex; flex-direction: column; gap: 3px; flex: 1 1 140px; min-width: 0; font-size: 12px; color: var(--mute); }
.prosearch .pf input, .prosearch .pf select { width: 100%; height: 40px; padding: 0 10px; font-size: 15px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--card); color: var(--ink); }
.prosearch .pf select:disabled { opacity: .55; }
.prosearch .pf.check { flex-direction: row; align-items: center; gap: 8px; font-size: 14px; color: var(--ink); align-self: flex-end; height: 40px; }
.prosearch .pf.check input { width: 18px; height: 18px; }
.profilter { margin-top: 10px; border: 1px solid var(--line); border-radius: 12px; padding: 8px 12px; background: var(--card); }
.profilter summary { cursor: pointer; font-weight: 700; }
.profilter summary b { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 999px; background: var(--ours); color: #fff; font-size: 12px; text-align: center; }
.profilter .btn { margin-top: 8px; }
.prosort { margin-top: 10px; }
.prosearch .pf input, .prosearch .pf select { flex: none; }
.prosearch .pf.check input { flex: none; width: 18px; height: 18px; }
.prosearch .profields .pf input[type=number] { flex: none; }

/* back button above every page but home (route()); the game page keeps its own ← in its header */
.pageback { max-width: 1240px; margin: 14px auto -10px; padding: 0 24px; }
@media (max-width: 720px) { .pageback { padding: 0 16px; margin: 8px auto -12px; } }
.pageback[hidden] { display: none; }
.pageback .btn { height: 32px; }
body.gamepage .gwhere .backbtn { display: inline-flex; width: 36px; height: 32px; padding: 0; font-size: 18px; align-items: center; justify-content: center; }

/* tournaments: filters, live / mine badges */
/* one row of tabs (what), one row of count + toggles + 필터 (the rest sits in a sheet) */
.tfilters { margin-top: 10px; }
.tfilters .seg { display: flex; }
.tfilters .seg button { flex: 1; padding: 0 6px; height: 36px; }
@media (min-width: 721px) { .tfilters .seg { display: inline-flex; } .tfilters .seg button { flex: none; padding: 0 16px; } }
.tbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; height: 40px; margin: 8px 0 10px; }
.tbar .row { flex-wrap: nowrap; gap: 6px; }
.btn.set { border-color: var(--ours); color: var(--ours); }
.fsheet { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.fsheet label { display: flex; align-items: center; gap: 12px; }
.fsheet label span { width: 56px; flex: none; font-weight: 600; font-size: 14px; }
.fsheet select { flex: 1; height: var(--tap); padding: 0 10px; font-size: 16px; border: 1px solid var(--line); border-radius: var(--rs); background: var(--card); color: var(--ink); }
.btn.toggle.on { background: var(--ours); border-color: var(--ours); color: #fff; }
.tag.live { background: var(--bad-soft); color: var(--bad); }
.tag.mine { background: var(--ours-soft); color: var(--ours); }

/* 나 / 선수단 / 팀 성적표 */
.mygrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin: 14px 0; }
.mygrid .panel { margin: 0; }
.oppcard { margin-top: 8px; }
.oppcard .foot2 { flex-wrap: wrap; gap: 6px; align-items: center; height: auto; overflow: visible; }
.phbars { display: grid; gap: 6px; margin-top: 8px; }
.phbar { display: grid; grid-template-columns: 112px 1fr 52px; align-items: center; gap: 8px; font-size: 13px; }
.phbar i { display: block; height: 10px; border-radius: 5px; background: #94a3b8; min-width: 4px; }
.phbar.worst i { background: var(--bad); }
.phbar b { text-align: right; }
.spark { display: block; max-width: 100%; }
.tablewrap { overflow-x: auto; margin-top: 10px; }
.teamtable { width: 100%; border-collapse: collapse; font-size: 14px; }
.teamtable th, .teamtable td { padding: 7px 8px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; white-space: nowrap; }
.teamtable th { font-size: 12px; color: var(--mute); font-weight: 600; }
.teamtable tr.best td { background: var(--good-soft); }
.teamtable tr.worst td { background: var(--bad-soft); }
.repsum { font-size: 18px; margin: 10px 0; }
.repsumtable { max-width: 560px; margin-bottom: 14px; }
.repcard { margin-top: 12px; }
.repcard .teamtable { margin-top: 8px; }
@media print {
  header, .tabbar, .foot, .pageback, .noprint { display: none !important; }
  body { background: #fff; }
  main { padding: 0; max-width: none; }
  .repcard { break-inside: avoid; border: 1px solid #ccc; box-shadow: none; }
}

/* 포석·흐름: the latest games' openings as small boards */
.openboards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.openboards .ob { display: grid; gap: 2px; text-decoration: none; color: var(--ink); }
.openboards .ob svg { width: 100%; height: auto; display: block; }
/* 포석 사전: board on the left, what was played next on the right; rows keep their height so nothing moves */
.bookhead { flex-wrap: nowrap; }
/* the line under the title: the professionals' note or the player search, one height either way */
.bookwho { display: flex; align-items: center; gap: 10px; height: 46px; margin: 4px 2px 10px; flex-wrap: nowrap; }
.bookwho > p { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.bpick { position: relative; flex: 1; min-width: 0; max-width: 280px; }
.bpick .search { height: 40px; padding-top: 0; padding-bottom: 0; }
.bhits { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0; min-width: 220px; max-height: 320px; overflow: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--rs); box-shadow: 0 6px 20px rgba(15,23,42,.14); }
.bhits button { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 9px 12px; font: inherit; color: var(--ink); cursor: pointer; }
.bhits button:hover { background: var(--hover); }
.bookwho .seg { flex: none; }
.bookwho > a { flex: none; white-space: nowrap; }
.booklay { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }
.bookgames .where span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 900px) { .booklay { grid-template-columns: minmax(0, 560px) minmax(0, 1fr); align-items: start; } }
.bookctl { margin-top: 8px; flex-wrap: nowrap; }
.bookside { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; align-content: start; }
.bookside .panel { margin: 0; }
/* the AI line, then a count with its bar or a title with one line under it */
#bStat { min-height: 106px; box-sizing: border-box; }
.pbar.book { height: 8px; margin-top: 8px; border-radius: 4px; background: #f1f5f9; border: 1px solid var(--line); overflow: hidden; }
.pbar.book i { display: block; height: 100%; background: #1f2937; }
.booknext { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; height: calc(8 * 39px + 20px); overflow: hidden; }
.brow { display: flex; flex: none; align-items: center; gap: 8px; height: 36px; min-width: 0;
  padding: 0 8px; border: 1px solid var(--line); border-radius: var(--rs); background: var(--card); color: var(--ink); font: inherit; font-size: 13px; text-align: left; cursor: pointer; }
.brow:hover, .brow.sel { border-color: var(--ours); background: var(--hover); }
.brow .bk { flex: none; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; font-weight: 800;
  background: hsla(210, 85%, 58%, .55); color: #0b1220; }
.brow.top .bk { background: hsla(190, 90%, 50%, .8); }
.brow .gtp { flex: none; width: 34px; }
.brow .bar { flex: 1; min-width: 24px; height: 6px; border-radius: 3px; background: #eef2f7; overflow: hidden; }
.brow .bar i { display: block; height: 100%; background: var(--ours); }
.brow .n { flex: none; white-space: nowrap; font-variant-numeric: tabular-nums; }
.brow .w { flex: none; width: 46px; text-align: right; font-size: 12px; white-space: nowrap; }
.brow .ai { flex: none; width: 52px; text-align: right; font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.brow .ai.best { color: var(--good); font-weight: 700; }
#bStat .bai { margin-bottom: 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#bStat .aigo { border: 0; padding: 0; background: none; font: inherit; font-weight: 700; color: var(--ours); cursor: pointer; }
#bStat .aigo:hover { text-decoration: underline; }
/* 승률 흐름: black's win rate along the line walked, under the board */
.bookgraph { margin-top: 10px; padding: 10px 12px 6px; }
.bookgraph .aigo { border: 0; padding: 0; background: none; font: inherit; font-weight: 700; color: var(--ours); cursor: pointer; white-space: nowrap; }
.bookgraph .aigo:hover { text-decoration: underline; }
svg.bline { display: block; width: 100%; height: auto; margin-top: 4px; }
.bline .mid { stroke: var(--line); stroke-dasharray: 3 3; }
.bline .lbl { font-size: 10px; fill: var(--mute); text-anchor: end; }
.bline .lbl.mid-x { text-anchor: middle; }
.bline .lbl.tag { text-anchor: start; opacity: .7; }
.bline .now { stroke: hsla(190, 90%, 45%, .5); stroke-width: 1.5; }
.bline .seg { stroke: var(--ours); stroke-width: 2; }
.bline .seg.gap { stroke-width: 1.2; stroke-dasharray: 3 3; opacity: .6; }
.bline .pt { fill: var(--ours); }
.bline .pt.now { fill: hsl(190, 90%, 45%); stroke: #fff; stroke-width: 1.5; }
.bline .hit { fill: transparent; cursor: pointer; }
.bookgames { margin-top: 8px; }
/* AI 대응: three rows at most, the box keeps that height so the lists under it never move */
.bookanswers { margin-top: 10px; padding: 10px 12px; }
.bookans .brow .bk { background: hsla(150, 70%, 45%, .6); }
.bookans .brow.top .bk { background: hsla(150, 75%, 40%, .9); color: #fff; }
.bookans { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; height: calc(3 * 39px); overflow: hidden; }
/* the last scene's lists while the next one is on its way: in place (nothing moves), greyed, not pressable */
.stale { opacity: .4; pointer-events: none; transition: opacity .15s; }
/* AI 포석: themes in a row that scrolls sideways; under the board one line of the way here, two rows of ways on and the
   buttons, each a fixed height whatever is in it (the board and the buttons never move) */
.aibthemes { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin: 4px 0 10px; }
.aibthemes::-webkit-scrollbar { display: none; }
.aibthemes .chip { padding: 6px 14px; cursor: pointer; flex: none; font: inherit; color: var(--ink); }
.aibthemes .chip.on { background: var(--ours); border-color: var(--ours); color: #fff; font-weight: 700; }
.aibpanel { margin-top: 10px; padding: 10px 12px; }
.aibpath { display: flex; align-items: center; gap: 8px; height: 30px; }
.aibpath .crumbs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 2px; overflow-x: auto; white-space: nowrap; scrollbar-width: none; }
.aibpath .crumbs::-webkit-scrollbar { display: none; }
.aibpath .crumbs button { border: 0; background: none; padding: 2px 4px; font: inherit; font-size: 13px; color: var(--ours); cursor: pointer; }
.aibpath .crumbs i { font-style: normal; color: var(--mute); font-size: 12px; }
.aibpath .lvl { flex: none; border: 0; background: var(--hover); border-radius: 8px; padding: 3px 8px; font: inherit; font-size: 13px; font-weight: 700; cursor: pointer; color: var(--ink); }
/* up to six ways on, three a row: the box is two rows high whatever it holds */
.aibkids { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 40px; gap: 6px; height: 86px; overflow: hidden; margin: 6px 0 8px; }
.aibkids p { grid-column: 1 / -1; margin: 6px 2px; }
.chip.aib { cursor: pointer; font: inherit; font-size: 14px; padding: 0 8px; gap: 4px; min-width: 0; color: var(--ink); border-radius: 10px; justify-content: flex-start; }
.chip.aib b { flex: none; display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--mute); color: #fff; font-size: 12px; }
.chip.aib strong { font-weight: 700; font-size: 15px; }
.chip.aib span { font-size: 11.5px; color: var(--mute); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chip.aib em { font-style: normal; font-size: 11.5px; color: var(--bad); margin-left: auto; }
.chip.aib.ai b { background: hsl(190, 80%, 42%); }
.chip.aib.near b { background: hsl(40, 85%, 48%); }
.chip.aib.human b { background: hsl(270, 45%, 55%); }
.aibkids .aibask { grid-column: 1 / -1; height: 40px; }
/* 연구: the tab's first page, a row for each way in */
.lab { padding: 4px 14px; }
.labrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 13px 2px; border-bottom: 1px solid var(--line);
  text-decoration: none; color: var(--ink); }
.labrow:last-child { border-bottom: 0; }
.labrow.col { flex-direction: column; align-items: stretch; }
.labrow > span { display: grid; gap: 2px; min-width: 0; }
.labrow > i { font-style: normal; color: var(--ours); font-weight: 700; font-size: 18px; }
.labthemes { display: flex; flex-wrap: wrap; gap: 6px; }
.labthemes .chip { padding: 7px 15px; text-decoration: none; color: var(--ink); font-weight: 700; }
.openboards.labrec { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; }
.labhead { display: flex; align-items: center; gap: 8px; min-width: 0; }
.labback { flex: none; height: 32px; padding: 0 10px; }
.aibthemes .labback { height: auto; border-radius: 999px; }
.aibctl { display: grid; grid-template-columns: 1.35fr 1fr 1fr .7fr; gap: 6px; }
.aibctl .btn { padding: 0 4px; white-space: nowrap; }
.aibpath .crumbs button[data-list] { font-weight: 700; }
/* 줄기 목록: small boards, two a row on a phone, scrolling inside the sheet */
.aiblines { max-height: 86dvh; display: flex; flex-direction: column; }
.aibcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; overflow-y: auto; overscroll-behavior: contain; }
.aibcard { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; text-align: left; padding: 6px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--card); color: var(--ink); font: inherit; cursor: pointer; }
.aibcard svg.board { width: 100%; height: auto; display: block; margin-bottom: 4px; }
/* a phone held upright: two a row, three rows (three a row cut the words short) */
@media (max-width: 520px) and (orientation: portrait) {
  .aibkids { grid-template-columns: repeat(2, minmax(0, 1fr)); height: 132px; }
}
.aibpage { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "head" "themes" "board" "panel"; }
.aibpage .bookhead { grid-area: head; }
.aibpage .aibthemes { grid-area: themes; }
.aibpage .aibboard { grid-area: board; }
.aibpage .aibpanel { grid-area: panel; }
/* wide screens and a phone on its side: the board beside everything else, as high as the screen lets it be */
@media (min-width: 900px) {
  .aibpage { grid-template-columns: minmax(0, 560px) minmax(0, 1fr); column-gap: 16px; align-items: start;
    grid-template-areas: "head head" "board themes" "board panel"; grid-template-rows: auto auto 1fr; }
  .aibpage .aibpanel { margin-top: 0; }
}
@media (orientation: landscape) and (max-height: 520px) {
  .aibpage { grid-template-columns: calc(100dvh - var(--hdr) - 20px) minmax(0, 1fr); column-gap: 12px; align-items: start;
    grid-template-areas: "board head" "board themes" "board panel"; grid-template-rows: auto auto 1fr; }
  .aibpage .aibpanel { margin-top: 0; }
  .aibpage .bookhead h2 { display: none; }
}
.aibctl .btn { user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }
/* a button whose request is on its way (app.js send): pressed-looking, the same size */
.busy { opacity: .55; cursor: progress; }
.bookans .brow .n { flex: 1; min-width: 0; }
.bookans .brow .ai { width: 60px; }
/* 포석 도감: the filters, then the shapes as small boards */
.atlasf { display: grid; gap: 6px; padding: 10px 12px; }
.atlasf .row { flex-wrap: nowrap; gap: 10px; overflow-x: auto; }
.atlasf .row > span { flex: none; width: 64px; }
.atlasf .seg button { height: 28px; padding: 0 10px; font-size: 13px; white-space: nowrap; }
.openboards.atlas .ob .loss { color: var(--bad); font-weight: 700; margin-left: 4px; }
@media (min-width: 720px) { .openboards.atlas { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.spot { cursor: pointer; }
.spot circle { fill: hsl(210, 85%, 58%); fill-opacity: .55; stroke: rgba(0,0,0,.3); stroke-width: .6; }
.spot.top circle { fill: hsl(190, 90%, 50%); fill-opacity: .8; }
.spot.sel circle { fill-opacity: .95; stroke: #fff; stroke-width: 1.8; }
.spot text { font-size: 8px; font-weight: 800; text-anchor: middle; fill: #0b1220; pointer-events: none; }
/* AI 포석: a way on is marked on the board in its chip's colour */
.spot.aib circle { fill-opacity: .9; stroke: #fff; stroke-width: .8; }
.spot.aib text { fill: #fff; }
.spot text.cw { font-size: 6.6px; }
.spot text.cs { font-size: 4.6px; font-weight: 600; }
.spot.aib.ai circle { fill: hsl(190, 80%, 42%); }
.spot.aib.near circle { fill: hsl(40, 85%, 48%); }
.spot.aib.human circle { fill: hsl(270, 45%, 55%); }
.spot.aib.far circle { fill: #64748b; }
/* 오늘의 상황판: a row per squad player, a cell per round */
.boardban { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 16px; margin-bottom: 12px;
  background: var(--ours-soft); border: 1px solid #bfdbfe; border-radius: var(--r); color: var(--ink); text-decoration: none; }
.boardban > span:last-child { color: var(--ours); font-weight: 700; white-space: nowrap; }
.insthint { flex-wrap: nowrap; }
.insthint > span:first-child { min-width: 0; }
.insthint > span:last-child { display: inline-flex; gap: 6px; flex: none; }
.insthint .btn { height: 30px; padding: 0 10px; }
table.sboard { overflow: visible; }      /* hidden would make the table the sticky name column's scroller */
table.sboard th, table.sboard td { white-space: nowrap; vertical-align: top; }
table.sboard th small { display: block; font-weight: 400; }
table.sboard th.cur { color: var(--ours); background: var(--ours-soft); }
table.sboard .nm { position: sticky; left: 0; z-index: 1; background: var(--card); font-weight: 700; box-shadow: 1px 0 0 var(--line); }
table.sboard th.nm { background: var(--soft); }
table.sboard .nm a { color: var(--ink); text-decoration: none; }
table.sboard .rec { display: block; color: var(--mute); font-size: 12px; font-weight: 400; }
table.sboard td.bc { padding: 0; min-width: 118px; }
table.sboard td.bc > a { display: block; padding: 8px 10px; color: var(--ink); text-decoration: none; font-size: 13px; line-height: 1.35; }
table.sboard td.bc .opp { display: block; color: var(--mute); font-size: 12px; }
table.sboard td.bc .opp small { font-size: 11px; }
table.sboard td.none { color: var(--line); text-align: center; padding: 8px; }
table.sboard td.w { background: var(--good-soft); } table.sboard td.w b { color: var(--good); }
table.sboard td.l { background: var(--bad-soft); } table.sboard td.l b { color: var(--bad); }
table.sboard td.live { background: #fff7ed; } table.sboard td.live > a { font-weight: 600; }
table.sboard td.live .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--bad); margin-right: 5px;
  vertical-align: 1px; animation: sbpulse 1.4s ease-in-out infinite; }
table.sboard td.next > a { color: var(--ours); }
table.sboard td.fresh { box-shadow: inset 0 0 0 2px var(--warn); }
@keyframes sbpulse { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { table.sboard td.live .dot { animation: none; } }
/* 상황판 › 판으로 보기: this round's games of ours as big boards; 전체 화면 on a waiting-room TV */
.grid.wall { grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); }
.wcell { display: flex; flex-direction: column; gap: 6px; }
.wwho { display: flex; align-items: baseline; gap: 8px; padding: 0 4px; font-size: 16px; }
.wwho span { color: var(--mute); font-size: 13px; }
.wwho .wres { margin-left: auto; padding: 2px 12px; border-radius: 999px; font-size: 15px; font-weight: 800; color: #fff; }
.wcell.w .wres { background: var(--good); } .wcell.l .wres { background: var(--bad); }
.wcell.w .gcard { border-color: var(--good); box-shadow: 0 0 0 1px var(--good); }
.wcell.l .gcard { border-color: #fca5a5; }
.wcell.w .gcard svg, .wcell.l .gcard svg { opacity: .7; }
.wcell.live .gcard { border-color: #fdba74; }
body.wallfull .top, body.wallfull .tabbar, body.wallfull .pageback, body.wallfull .foot { display: none; }
body.wallfull main { max-width: none; padding-top: 12px; }
/* a TV: the few games of a round spread over the screen, each board no taller than the screen leaves room for */
body.wallfull .grid.wall { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); justify-items: center; }
body.wallfull .wcell { width: 100%; max-width: max(340px, calc(100vh - 330px)); }
@media (max-width: 720px) {
  .wwho { font-size: 14px; gap: 4px; flex-wrap: wrap; }
  .wwho span { font-size: 12px; }
  .wwho .wres { padding: 1px 8px; font-size: 13px; }
  .grid.wall.compact { grid-template-columns: 1fr 1fr; }      /* a round's games side by side, not one per screen */
}

/* 상황판 › 이번 라운드: every row the same height, the same columns, whatever state the game is in */
.nowlist { display: flex; flex-direction: column; gap: 6px; }
.nowrow { display: grid; grid-template-columns: minmax(0, 38%) minmax(0, 1fr); column-gap: 10px; align-items: center; height: 62px;
  padding: 8px 12px 0; background: var(--card); border: 1px solid var(--line); border-radius: var(--rs); color: var(--ink); text-decoration: none; overflow: hidden; }
.nowrow .who, .nowrow .st { display: flex; flex-direction: column; min-width: 0; white-space: nowrap; line-height: 1.3; }
.nowrow .who b, .nowrow .st .t, .nowrow .opp { overflow: hidden; text-overflow: ellipsis; }
.nowrow .who b { font-size: 16px; }
.nowrow .who small, .nowrow .opp { font-size: 12px; color: var(--mute); }
.nowrow .st { font-size: 14px; }
.nowrow .wb { grid-column: 1 / -1; align-self: end; height: 4px; margin: 0 -12px; background: var(--hover); }
.nowrow .wb i { display: block; height: 100%; background: var(--ours); }
.nowrow.live { border-color: #fdba74; background: #fff7ed; }
.nowrow.live .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--bad); margin-right: 5px; }
.nowrow.w { background: var(--good-soft); } .nowrow.w b { color: var(--good); } .nowrow.w .who b { color: var(--ink); }
.nowrow.l { background: var(--bad-soft); } .nowrow.l b { color: var(--bad); } .nowrow.l .who b { color: var(--ink); }
.nowrow.next .st { color: var(--ours); }
.nowrow.fresh { box-shadow: inset 0 0 0 2px var(--warn); }

/* 크게 보기 (body.focus, bindFocus): the board, its move buttons and the AI line only, over the whole screen */
.focusbar { display: none; }
body.focus .top, body.focus .tabbar, body.focus .pageback, body.focus .foot, body.focus .gpage .gwhere, body.focus .gpage .ghead,
body.focus .gpage .tools, body.focus .gpage .side, body.focus .gpage .mtabs { display: none !important; }
body.focus .gpage { position: fixed; inset: 0; z-index: 30; margin: 0; padding: 0 0 var(--tabbar, 0px); overflow: hidden; background: var(--card);
  display: flex; flex-direction: column; justify-content: center; align-items: stretch; }
body.focus .gpage > .bcol { display: block; margin: 0; padding: 0; border: 0; border-radius: 0; box-shadow: none; background: none; }
body.focus .gpage .bpanel { position: static; margin: 0; border: 0; box-shadow: none; }
body.focus .focusbar { display: flex; gap: 8px; position: fixed; top: max(8px, env(safe-area-inset-top)); right: 8px; z-index: 40; }
body.focus .focusbar .btn { height: 40px; min-width: 40px; padding: 0 12px; font-size: 15px; }
body.focus .focusbar #focusX { width: 40px; padding: 0; font-size: 18px; }
/* zoomed (boardZoom): a finger drag moves the board instead of scrolling or stepping; the see-through stone waiting
   for its second tap, its row and column lined up */
.boardwrap.zoomed svg.board { touch-action: none; }
.boardwrap.zoomed { overflow: hidden; border-radius: 8px; }
svg.board .aim { stroke: #2563eb; stroke-width: .9; opacity: .55; }
svg.board .pend { opacity: .55; stroke: #2563eb; stroke-width: 1.2; }
/* turned sideways (and wide screens): the board as tall as the screen on the left, everything else in a column beside it */
@media (orientation: landscape) {
  body.focus .gpage { padding: 6px; justify-content: flex-start; }
  body.focus .gpage > .bcol { padding: 0; }
  body.focus .gpage .bpanel { display: grid; grid-template-columns: calc(100dvh - 12px) minmax(0, 1fr); column-gap: 12px; align-content: start;
    height: calc(100dvh - 12px); padding: 0; }
  body.focus .gpage .bpanel > * { grid-column: 2; }
  body.focus .gpage .bpanel > .boardwrap { grid-column: 1; grid-row: 1 / span 30; margin: 0; width: calc(100dvh - 12px); }
  body.focus .focusbar { position: static; justify-self: end; }
  body.focus .gpage .controls { position: static; padding: 0; background: none; border: 0; }
}

/* 설정 › 화면: a switch per line, the explanation under its name */
.setrow { display: flex; gap: 10px; align-items: flex-start; margin-top: 10px; cursor: pointer; }
.setrow input { width: 20px; height: 20px; margin-top: 2px; flex: none; }
.setrow span { display: flex; flex-direction: column; gap: 2px; }

/* 크게 보기 › 판만 (body.boardonly): nothing but the board, as large as the screen allows either way up; the two
   buttons stay in the corner, faint */
body.focus.boardonly .gpage .bpanel > :not(.boardwrap):not(.focusbar) { display: none !important; }
body.focus.boardonly .gpage { padding: 0; justify-content: center; align-items: center; background: #1f2937; }
body.focus.boardonly .gpage > .bcol, body.focus.boardonly .gpage .bpanel { width: 100%; padding: 0; background: none; }
body.focus.boardonly .gpage .bpanel { display: flex; justify-content: center; align-items: center; height: 100dvh; }
body.focus.boardonly .gpage .bpanel > .boardwrap { position: static; margin: 0; width: min(100vw, 100dvh); height: auto; flex: none; }
body.focus.boardonly .focusbar { position: fixed; top: max(6px, env(safe-area-inset-top)); right: 6px; opacity: .75; }
.aibcard .pick { stroke-width: 4; stroke-dasharray: none; }

/* ---- app frame (phones, upright): the page is one fixed frame and only the middle scrolls (2026-11-14, the user:
   모바일에서 화면이 날라다닌다 · 웹이되 앱에 최적화). With the document itself not scrolling, the browser's address
   bar stays where it is (it folded away and came back with every scroll, and everything fixed to the screen's edge
   jumped with it), the page does not rubber-band past its ends and a pull down does not reload. The header sits
   above, the tab bar floats over the bottom as before; the game and broadcast screens were already built this way.
   The status line under the page is not shown here (it jumped at every change of screen). app.js: appFrame. */
@media (max-width: 720px) and (orientation: portrait) {
  html { height: 100%; overflow: hidden; overscroll-behavior: none; touch-action: manipulation; }
  body { position: fixed; inset: 0; overflow: hidden; display: flex; flex-direction: column; overscroll-behavior: none; }
  .top { position: static; flex: none; }
  .pageback { flex: none; width: 100%; box-sizing: border-box; margin: 8px 0 0; }
  main { flex: 1 1 auto; min-height: 0; width: 100%; max-width: none; box-sizing: border-box; margin: 0;
    overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  .foot { display: none; }
  /* a field smaller than 16px makes iOS zoom the whole page in when it is tapped */
  input, select, textarea { font-size: max(16px, 1em); }
}

/* ---- game page on tablets and computers: one screen, nothing to scroll to (2026-11-15 user) ----
   the board column keeps only what steps through the game; the side column is 형세 흐름, then 실수 / 후보수 / 리포트 as tabs
   that scroll inside themselves, then the AI lines (dockAI in app.js) pinned at its foot. The board is sized from the
   screen height, so the page itself has no scroll and the board and the buttons never move */
@media (min-width: 721px) and (min-height: 561px) {
  body.gamepage main { padding: 12px 16px; max-width: 1400px; }
  body.gamepage .foot { display: none; }
  .gpage.rv { --gh: max(540px, calc(100dvh - var(--hdr) - 26px)); height: var(--gh); gap: 12px; align-items: stretch;
    grid-template-columns: minmax(0, min(calc(var(--gh) - 196px), 58vw, 800px)) minmax(0, 1fr); }
  .gpage.rv .bcol { align-self: start; }
  .gpage.rv .side { min-height: 0; gap: 8px; }
  .gpage.rv .side > [data-pane="flow"] { order: 1; flex: none; padding: 10px 14px; }
  .gpage.rv .side .graph { height: 96px; }
  .gpage.rv .mtabs { order: 2; flex: none; display: flex; gap: 4px; }
  .gpage.rv .mtabs button { flex: 1; height: 38px; border: 1px solid var(--line); background: var(--card); border-radius: 999px; font-size: 14px;
    font-weight: 600; color: var(--mute); cursor: pointer; white-space: nowrap; }
  .gpage.rv .mtabs button.on { background: var(--ink); color: #fff; border-color: var(--ink); }
  .gpage.rv .mtabs .sib { display: none; }
  .gpage.rv .side > [data-pane="mist"], .gpage.rv .side > [data-pane="cand"], .gpage.rv .side > [data-pane="rep"] { order: 3; display: none;
    flex: 1 1 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 12px 14px; }
  .gpage.rv[data-tab="mist"] .side > [data-pane="mist"], .gpage.rv[data-tab="cand"] .side > [data-pane="cand"],
  .gpage.rv[data-tab="rep"] .side > [data-pane="rep"] { display: block; }
  .gpage.rv #cands { height: auto; overflow: visible; }
  .gpage.rv .mistakes { max-height: none; }
  /* the dock: the hint, then what the board shows and 깊게 보기 on one line, then the line being read, then AI 분석 */
  .gpage.rv .aidock { order: 4; flex: none; display: flex; flex-wrap: wrap; gap: 6px; }
  .gpage.rv .aidock > * { flex: 1 1 100%; min-width: 0; }
  .gpage.rv .aidock > *, .gpage.rv .aidock .slot { margin-top: 0; }
  .gpage.rv .aidock .hint { height: 20px; -webkit-line-clamp: 1; }
  .gpage.rv .aidock > .viewbar { order: 1; flex: 0 0 auto; height: 52px; }
  .gpage.rv .aidock > #deepbar { order: 1; flex: 1 1 0; }
  .gpage.rv .aidock > #pvbar { order: 2; }
  .gpage.rv .aidock > .tools { order: 3; }
  .gpage.rv .side .graph { height: 84px; }
  .gpage.rv .aidock .tools { display: flex; flex-direction: column; gap: 6px; }
  .gpage.rv .aidock .legendbox { margin-top: 0; }
  body.focus .gpage.rv { height: auto; }
}
/* a tablet held upright: the board on top, under it the AI lines on the left and the tabs on the right; the wide graph
   gives way to the strip under the board */
@media (min-width: 721px) and (min-height: 561px) and (orientation: portrait) {
  .gpage.rv { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr); }
  .gpage.rv .bcol { grid-column: 1 / -1; justify-self: center; width: min(100%, calc(var(--gh) - 450px)); margin: 0; padding: 16px;
    border-radius: var(--r); border-width: 1px; box-shadow: var(--shadow); }
  /* the strip under the board steps through the game, so the slider goes; so does the legend (a mouse's help) */
  .gpage.rv .slider, .gpage.rv .legendbox { display: none; }
  .gpage.rv .controls { position: static; padding: 0; }
  .gpage.rv .graph.mini { display: block; height: 34px; margin-top: 4px; border-radius: 6px; }
  .gpage.rv .side { display: contents; }
  .gpage.rv .side > [data-pane="flow"] { display: none; }
  .gpage.rv .aidock { grid-column: 1; grid-row: 2 / span 2; align-self: start; flex-direction: column; flex-wrap: nowrap; }
  .gpage.rv .aidock > *, .gpage.rv .aidock > #deepbar { flex: none; }
  .gpage.rv .aidock > .viewbar { height: 40px; }
  .gpage.rv .mtabs { grid-column: 2; grid-row: 2; }
  .gpage.rv .side > [data-pane="mist"], .gpage.rv .side > [data-pane="cand"], .gpage.rv .side > [data-pane="rep"] { grid-column: 2; grid-row: 3; }
  body.focus .gpage.rv .bcol { width: auto; }
}

/* ---- game page on a phone: nothing scrolls (2026-11-15 user) ----
   head, board, evaluation, the one line of actions, AI 분석, the tabs, the move buttons: all on screen at once. A tab
   opens its list as a sheet over the foot of the board (setTab); the board gives way only when the height is short
   (--bw, pinBoard) */
@media (max-width: 720px) and (orientation: portrait) {
  .gpage.rv { overflow: hidden; padding-bottom: 0; gap: 0; align-content: start; }
  body:not(.focus) .gpage.rv .bpanel .boardwrap { width: var(--bw, 100vw); margin: 6px 0 0 calc((100% - var(--bw, 100vw)) / 2); }
  .gpage.rv .tools .slot { margin-top: 6px; }
  .gpage.rv .tools .aibar { height: 40px; font-size: 13px; }
  .gpage.rv .tools .aibar .btn { height: 30px; }
  .gpage.rv .mtabs { position: fixed; left: 0; right: 0; top: auto; bottom: var(--tabbar); z-index: 26; margin: 0; padding: 6px 8px; background: var(--bg); }
  .gpage.rv:not([data-sheet]) .mtabs button.on { background: var(--card); color: var(--mute); border-color: var(--line); }
  .gpage.rv:not([data-sheet]) .side > [data-pane] { display: none; }
  .gpage.rv[data-sheet] .side > [data-pane] { position: fixed; left: 0; right: 0; bottom: calc(var(--tabbar) + 50px); max-height: 50dvh; overflow-y: auto;
    overscroll-behavior: contain; z-index: 24; margin: 0; border-radius: 16px 16px 0 0; box-shadow: 0 -10px 30px rgba(15,23,42,.28); }
}

/* ---- 연구판 on tablets and computers: one screen (as the game page above) ---- */
@media (min-width: 721px) and (min-height: 561px) {
  .gpage.free { --gh: max(540px, calc(100dvh - var(--hdr) - 26px)); height: var(--gh); gap: 12px; align-items: stretch;
    grid-template-columns: minmax(0, min(calc(var(--gh) - 132px), 58vw, 800px)) minmax(0, 1fr); }
  .gpage.free .bcol { align-self: start; }
  .gpage.free .side { min-height: 0; gap: 8px; }
  .gpage.free .side > .panel { flex: 1 1 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 12px 14px; }
  .gpage.free #cands { height: auto; overflow: visible; }
  .gpage.free .aidock { flex: none; display: flex; flex-direction: column; gap: 6px; }
  .gpage.free .aidock > *, .gpage.free .aidock .slot { margin-top: 0; }
  .gpage.free .aidock .hint { height: 20px; -webkit-line-clamp: 1; }
  body.focus .gpage.free { height: auto; }
}
@media (min-width: 721px) and (min-height: 561px) and (orientation: portrait) {
  .gpage.free { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .gpage.free .bcol { grid-column: 1 / -1; justify-self: center; width: min(100%, calc(var(--gh) - 132px - 262px)); margin: 0; padding: 16px;
    border-radius: var(--r); border-width: 1px; box-shadow: var(--shadow); }
  .gpage.free .controls { position: static; padding: 0; }
  .gpage.free .side { display: contents; }
  .gpage.free .aidock { grid-column: 1; grid-row: 2; align-self: start; }
  .gpage.free .side > .panel { grid-column: 2; grid-row: 2; }
  body.focus .gpage.free .bcol { width: auto; }
}
/* ---- AI 포석: one screen. A phone gives the header and the tab bar to the board (the ← in the theme row goes back);
   the board is as wide as the screen unless the height is short ---- */
@media (max-width: 720px) and (orientation: portrait) {
  body.aibp .top, body.aibp .tabbar { display: none; }
  body.aibp main { padding: 6px 12px; }
  body.aibp .aibthemes { margin: 0 0 8px; }
  body.aibp .aibboard { width: min(100%, calc(100dvh - 306px)); justify-self: center; }
}
@media (min-width: 721px) and (max-width: 899px) and (min-height: 561px) {
  body.aibp main { padding-bottom: 12px; }
  body.aibp .foot { display: none; }
  body.aibp .aibboard { width: min(100%, calc(100dvh - var(--hdr) - 300px)); justify-self: center; }
}
.candlist button[hidden] { display: none; }
.candlist .morec { display: flex; justify-content: center; color: var(--ours); font-weight: 600; background: none; border: 1px dashed var(--line); }
/* 연구판 on a phone: nothing scrolls; the whole candidate list opens as a sheet (fitCands) */
@media (max-width: 720px) and (orientation: portrait) {
  .gpage.free { overflow: hidden; align-content: start; }
  body:not(.focus) .gpage.free .bpanel .boardwrap { width: var(--bw, 100vw); margin: 6px 0 0 calc((100% - var(--bw, 100vw)) / 2); }
  .gpage.free[data-all] .side > .panel { position: fixed; left: 0; right: 0; bottom: var(--tabbar); max-height: 60dvh; overflow-y: auto;
    overscroll-behavior: contain; z-index: 24; margin: 0; padding: 8px; border-radius: 16px 16px 0 0; box-shadow: 0 -10px 30px rgba(15,23,42,.28); }
}
/* 연구판, a tablet held upright: eight candidates in the room under the board */
@media (min-width: 721px) and (min-height: 561px) and (orientation: portrait) {
  .gpage.free .side > .panel { padding: 6px 8px; }
  .gpage.free .side > .panel > .spread { display: none; }
  .gpage.free .candlist { gap: 2px; margin-top: 0; }
  .gpage.free .candlist button { height: 28px; }
}

/* ---- 요약 (#/recap): the group's games of one day, a card each ---- */
.rtop { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.rtop h2 { margin: 0; font-size: 20px; }
.rtop select { height: 40px; padding: 0 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card); color: var(--ink); font: inherit; font-size: 16px; }
.rbar { display: flex; align-items: center; justify-content: space-between; gap: 8px 12px; flex-wrap: wrap; margin-bottom: 10px; min-height: 40px; }
.rlead { display: inline-flex; align-items: center; gap: 8px; }
.rgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 12px; }
.rcard { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; }
.rhead { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 8px; color: var(--ink); text-decoration: none; font-size: 15px; height: 30px; }
.rhead > span { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.rhead > span:last-child { justify-content: flex-end; }
.rhead .me { font-weight: 800; color: var(--ours); }
.rspark { width: 100%; height: 44px; display: block; background: var(--soft); border-radius: 8px; }
.rspark line { stroke: var(--line); stroke-width: .4; stroke-dasharray: 1.5 1.5; }
.rspark polyline { fill: none; stroke: var(--ours); stroke-width: 2; }
.rspark circle { fill: var(--mute); }
.rspark circle.mine { fill: var(--bad); }
.rturn { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--mute); min-height: 34px; flex-wrap: wrap; }
.rturn.warn { color: var(--bad); font-weight: 600; }
.rside { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 34px; }
.rside .who { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 700; width: 100%; }
.rside.opp .who { font-weight: 500; color: var(--mute); }
.rchip { display: inline-flex; align-items: center; gap: 5px; height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--card);
  color: var(--ink); text-decoration: none; font-size: 13px; white-space: nowrap; }
.rchip:hover { background: var(--hover); }
.rchip i { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.rchip.key { border-color: var(--ours); background: var(--ours-soft); }
.rside.opp .rchip { color: var(--mute); }
.rfoot { display: flex; gap: 6px; justify-content: space-between; margin-top: 2px; }
/* the game page stepping up to a move by itself (from 요약): what it is doing, and that a touch stops it */
.replaybar { position: fixed; left: 50%; transform: translateX(-50%); top: calc(var(--hdr) + 10px); z-index: 45; height: 36px; padding: 0 16px; border: 0;
  border-radius: 999px; background: var(--ink); color: #fff; font: inherit; font-size: 13px; font-weight: 600; white-space: nowrap; box-shadow: 0 6px 18px rgba(15,23,42,.3); }
@media (max-width: 720px) and (orientation: portrait) { .replaybar { top: 56px; } }
