/* ============================================================
   Reversi board.

   The page chrome, the two themes and every token used here come
   from games.css. This file adds the board, the score line and
   the online panel, and nothing else.

   The controls, the win banner and the rules block are the same
   shapes solitaire uses. They are repeated here rather than
   shared because games.css is a file this lane does not own. If
   a third game wants them too, they should be lifted into
   games.css once and dropped from both game sheets.

   Sizing is pure CSS. Unlike a cascade of nineteen cards, an
   eight by eight grid always knows its own shape, so the board
   is one square that divides itself and needs no measuring pass
   in JS.
   ============================================================ */

.gamewrap{max-width:1080px; margin:0 auto; padding:0 clamp(8px,2vw,20px)}

/* ---------- controls ---------- */
.controls{display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding:10px 0 12px}
.controls .spacer{flex:1 1 auto}
.seg{display:inline-flex; border:1px solid var(--line); border-radius:999px; overflow:hidden;
  background:var(--panel)}
.seg button{
  font-family:var(--mono); font-size:.72rem; letter-spacing:.05em;
  background:transparent; border:0; color:var(--ink); cursor:pointer;
  min-height:var(--tap); padding:0 13px; line-height:1.1}
.seg button[aria-pressed="true"]{background:var(--accent); color:#15102a; font-weight:700}
:root[data-theme="light"] .seg button[aria-pressed="true"]{color:#f6f2ff}
.seg button:focus-visible{outline:3px solid var(--accent-ink); outline-offset:-3px}
.stat{font-family:var(--mono); font-size:.72rem; letter-spacing:.08em; color:var(--muted);
  white-space:nowrap}
.stat b{color:var(--ink); font-weight:700; font-variant-numeric:tabular-nums}

/* A single line of plain talk under the controls, used when something the
   player asked for cannot happen. It has to read as a sentence, not an error. */
.note{margin:0 0 10px; color:var(--ink); font-size:.9rem; max-width:62ch;
  border-left:3px solid var(--accent); padding-left:12px}

/* ---------- score line ---------- */
.tally{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:0 2px 10px; justify-content:space-between;
}
.side{
  display:inline-flex; align-items:center; gap:8px;
  border:1px solid var(--line); border-radius:999px; padding:6px 14px;
  background:var(--panel); font-family:var(--mono); font-size:.74rem; letter-spacing:.06em;
  color:var(--muted); white-space:nowrap;
}
/* Whose turn it is is carried by a ring and by the word in the middle, never
   by color alone. */
.side.on{border-color:var(--accent-ink); color:var(--ink)}
.side .scount{color:var(--ink); font-weight:700; font-variant-numeric:tabular-nums; font-size:.9rem}
.side.win{border-color:var(--accent-ink)}
.turnline{
  flex:1 1 auto; text-align:center; font-family:var(--mono); font-size:.74rem;
  letter-spacing:.08em; color:var(--ink); min-width:12ch;
}

/* the small disc swatch in the score line, same paint as a disc on the board */
.pip{width:16px; height:16px; border-radius:50%; display:inline-block; flex:none;
  border:2px solid transparent}
.pip.dark{background:var(--disc-dark); border-color:var(--disc-dark-rim)}
.pip.light{background:var(--disc-light); border-color:var(--disc-light-rim)}

/* ---------- the board ---------- */
:root{
  /* Discs are painted from their own tokens rather than from --ink and --bg,
     because the dark side stays dark in both themes. A player's color is part
     of the game state and must not move when the room lights change.
     Measured against the felt in both themes, every pair clears 3:1. */
  --disc-dark:#17122b;
  --disc-dark-rim:#b9a6f5;
  --disc-light:#f2ecff;
  --disc-light-rim:#5b41a8;
  --cell:rgba(185,166,245,.07);
  --cell-line:rgba(185,166,245,.20);
}
:root[data-theme="light"]{
  --disc-dark:#1d1734;
  --disc-dark-rim:#6d28d9;
  --disc-light:#ffffff;
  --disc-light-rim:#4a348c;
  --cell:rgba(255,255,255,.42);
  --cell-line:rgba(74,52,140,.22);
}

.board{max-width:min(100%, 560px); margin:0 auto}
.grid{
  display:grid; grid-template-rows:repeat(8, 1fr); gap:2px;
  aspect-ratio:1 / 1; width:100%;
  background:var(--felt); border:1px solid var(--line); border-radius:12px;
  padding:3px; touch-action:manipulation;
}
.grid .brow{display:grid; grid-template-columns:repeat(8, 1fr); gap:2px}

.cell{
  position:relative; padding:0; margin:0; cursor:default;
  background:var(--cell); border:1px solid var(--cell-line); border-radius:3px;
  display:flex; align-items:center; justify-content:center;
  -webkit-tap-highlight-color:transparent;
}
.cell:focus-visible{outline:3px solid var(--accent-ink); outline-offset:-3px; z-index:2}

/* A disc is one element that changes color, so a flip is a real animation
   rather than a swap of two nodes. */
.disc{
  width:78%; height:78%; border-radius:50%;
  border:2px solid transparent; background:transparent;
  transform:scale(.2); opacity:0;
  transition:transform .16s ease, opacity .16s ease, background-color .16s linear,
             border-color .16s linear;
}
.cell.dark .disc{background:var(--disc-dark); border-color:var(--disc-dark-rim);
  transform:scale(1); opacity:1}
.cell.light .disc{background:var(--disc-light); border-color:var(--disc-light-rim);
  transform:scale(1); opacity:1}

/* the squares the side to move can actually take */
.cell.legal{cursor:pointer}
.cell.legal::after{
  content:""; position:absolute; left:50%; top:50%;
  width:26%; height:26%; margin:-13% 0 0 -13%; border-radius:50%;
  background:var(--accent-ink); opacity:.75;
}
.cell.legal:hover{background:color-mix(in srgb, var(--accent-ink) 16%, var(--cell))}
/* the square just played, so a returning eye can find the last move */
.cell.last::before{
  content:""; position:absolute; inset:2px; border-radius:3px;
  border:2px solid var(--accent-ink); opacity:.85; pointer-events:none;
}
/* the board is not yours to touch right now, for instance while the other
   browser is thinking */
.grid.locked .cell{cursor:default}
.grid.locked .cell.legal::after{opacity:.35}

/* ---------- end of game ---------- */
.winbar{
  margin:14px 0 0; border:1px solid var(--accent-ink); border-radius:14px;
  padding:16px 18px; background:var(--panel);
  display:flex; flex-wrap:wrap; gap:12px; align-items:center; justify-content:space-between;
}
.winbar[hidden]{display:none}
.winbar h2{margin:0; font-size:1.15rem}
.winbar p{margin:4px 0 0; color:var(--muted); font-size:.92rem}

/* ---------- rules ---------- */
.rules{margin-top:26px; margin-bottom:10px}
.rules summary{
  font-family:var(--mono); font-size:.74rem; letter-spacing:.08em; text-transform:uppercase;
  color:var(--accent); cursor:pointer; min-height:var(--tap); display:flex; align-items:center;
  gap:9px; list-style:none}
.rules summary::-webkit-details-marker{display:none}
.rules summary::before{content:"▸"; font-size:.9rem; transition:transform .18s ease}
.rules[open] summary::before{transform:rotate(90deg)}
.rules summary:focus-visible{outline:3px solid var(--accent-ink); outline-offset:2px}
.rules ul{margin:10px 0 0; padding-left:20px; color:var(--muted); max-width:62ch}
.rules li{margin:6px 0}

/* live region for screen readers, never visible */
.live{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0)}

/* On a narrow phone the board wants every pixel of the width, so the score
   line stops competing for it. */
@media (max-width:430px){
  .tally{gap:6px}
  .side{padding:6px 10px}
  .turnline{order:3; flex-basis:100%; text-align:center}
}
