/* ==========================================================================
   reversi.css — reversi's arena (src/assets/js/games/reversi/view.mjs), inside
   the table games.css draws: the board in hairlines, the discs (games.css
   .g-disc: solid for one side, a ring for the other), a line of caption over
   it and, under it, which disc is whose with the count of each. Every class
   here is .rv-*.
   ========================================================================== */

/* The column the board is given is its measure (cqw, below): the widest board, ten squares a
   side, still fits a phone. */
.rv {
  container-type: inline-size;
  position: relative; /* the caption hangs over its top edge */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(12 * var(--s, 1px));
}

/* The caption: what a first turn is to do, and that a player was passed over. It lies over the
   board in the arena's own top margin (games.css gives the arena 32 design pixels there, 20 on a
   phone), so it takes no height: on a phone the page opens with the site's nav above the game, and
   a line under the board would start below the screen's edge. One line always, cut with an
   ellipsis before it would wrap (view.mjs keeps what it says short enough not to be). */
.rv-note {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 100%;
  block-size: calc(20 * var(--s, 1px));
  padding-block-end: calc(4 * var(--s, 1px));
  line-height: calc(16 * var(--s, 1px));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The turn has come back to you: green, as the top line's "your turn" is. */
.rv-note--you {
  color: var(--green);
  font-weight: 500;
}
/* A first turn's "place a ○ on a dotted square": the reader's own disc, at the size of the type. */
.rv-note > .g-disc {
  --disc: 0.85em;
  display: inline-block;
  vertical-align: -0.1em;
  margin-inline: 0.15ch;
}
.rv-note > .g-disc--ring { border-width: calc(2 * var(--s, 1px)); }

/* The board: --n squares a side — six, eight or ten, as the match is set — with one hairline
   between each two and one all round. The lines are the board's own ground showing through the
   1px gaps, so every line is one pixel and none is drawn twice. A square is 56 design pixels
   where there is room and what the column allows where there is not — in the 335px column of a
   375px phone, 54px at six a side, 40px at eight and 32px at ten — in whole pixels, so the lines
   fall on the pixel grid. (A variable cannot fall back the way a property does, so the measure is
   built up: by the window, for a browser without container units, taking the page's 20px gutters
   as given; then by the column itself; then in whole pixels. Either way it is the width less the
   n + 1 lines, shared among the n squares.) */
.rv-board {
  --n: 8; /* squares a side; view.mjs sets it */
  --cell: min(calc(56 * var(--s, 1px)), calc((100vw - 41px - var(--n) * 1px) / var(--n)));
  display: grid;
  grid-template-columns: repeat(var(--n), var(--cell));
  grid-auto-rows: var(--cell);
  gap: 1px;
  padding: 1px;
  background: var(--hairline);
  -webkit-user-select: none;
  user-select: none;
}
@supports (width: 1cqw) {
  .rv-board { --cell: min(calc(56 * var(--s, 1px)), calc((100cqw - 1px - var(--n) * 1px) / var(--n))); }
}
@supports (width: 1cqw) and (width: round(down, 1px, 1px)) {
  .rv-board { --cell: round(down, min(calc(56 * var(--s, 1px)), calc((100cqw - 1px - var(--n) * 1px) / var(--n))), 1px); }
}
/* A row is a row to a screen reader only: its squares lie straight on the board's grid. */
.rv-row { display: contents; }
/* A square: the button that is there while it can be placed on, and the two faces of a disc, all
   three in the one place. */
.rv-cell {
  position: relative;
  display: grid;
  place-items: center;
  background: var(--bg);
}
.rv-cell > * { grid-area: 1 / 1; }
/* A taken square shows the face its mark says: X the solid one, O the ring. */
.rv-cell > .g-disc { visibility: hidden; }
.rv-cell[data-mark="X"] > .g-disc--solid,
.rv-cell[data-mark="O"] > .g-disc--ring { visibility: visible; }

/* The disc just placed is green until the next one, and the squares of the discs it turned over
   are filled a touch, as a picked tile is in 24: the move stays readable after it is made. */
.rv-cell--last > .g-disc { color: var(--green); }
.rv-cell--last,
.rv-cell--turned { background: color-mix(in srgb, var(--green) 13%, var(--bg)); }
/* A press that could not be a move: the square says no for a moment (view.mjs takes it off). */
.rv-cell--no { background: color-mix(in srgb, var(--red) 12%, var(--bg)); }

/* A square you may place on, on your turn: the whole square is the button, and a small dot in its
   middle says so. Nothing else on the board is a control. */
.rv-sq {
  position: absolute;
  inset: 0;
  z-index: 1;
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.rv-sq::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  inline-size: calc(6 * var(--s, 1px));
  block-size: calc(6 * var(--s, 1px));
  border-radius: 50%;
  background: var(--ink-muted);
  opacity: 0.5;
}
/* Under the pointer the dot gives way to a ghost of your own disc, in pink — the face the square
   would show (the button comes first in the square, so the faces are its later siblings) — and
   the discs it would turn over go pink with it (view.mjs marks them), so a move can be seen
   before it is made. */
@media (hover: hover) {
  .rv-sq:hover::after { visibility: hidden; }
  .rv-board[data-you="X"] .rv-sq:hover ~ .g-disc--solid,
  .rv-board[data-you="O"] .rv-sq:hover ~ .g-disc--ring {
    visibility: visible;
    color: var(--pink);
    opacity: 0.6;
  }
  .rv-board:not(.rv-board--keys) .rv-cell--would > .g-disc { color: var(--pink); }
}

/* The keyboard's place. The board is the one stop for Tab; what shows where the keys will act is
   the ring on the cursor's square (base.css's ring, drawn inside the square so it covers no line
   of its neighbours), not a ring round the whole board. On a square a disc can go on, the discs it
   would turn over go pale: the pointer's preview, in the keyboard's register (pink is the
   pointer's alone). */
.rv-board:focus-visible { outline: none; }
.rv-board:focus-visible .rv-cell--cursor {
  outline: calc(2 * var(--s, 1px)) solid var(--green);
  outline-offset: calc(-2 * var(--s, 1px));
  z-index: 2;
}
.rv-board--keys:focus-visible .rv-cell--would > .g-disc {
  color: var(--ink-muted);
  opacity: 0.45;
}

/* Which disc is whose, and how many each has: the disc itself, the name, the count. Yours first
   and in ink; the other player's in the muted register of everything not yours. */
.rv-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: calc(4 * var(--s, 1px)) calc(28 * var(--s, 1px));
}
.rv-side {
  display: inline-flex;
  align-items: center;
  gap: 0.8ch;
  white-space: nowrap;
}
.rv-mark { display: inline-flex; }
/* The board's disc at the size of the type; its ring a little finer, to keep the hole open. */
.rv-mark > .g-disc { --disc: calc(13 * var(--s, 1px)); }
.rv-mark > .g-disc--ring { border-width: calc(2 * var(--s, 1px)); }
.rv-side--you .rv-who {
  color: var(--ink);
  font-weight: 500;
}
/* Whose move it is: the name underlined in green, as the table's top line underlines it. */
.rv-side--turn .rv-who {
  text-decoration: underline;
  text-decoration-color: var(--green);
  text-decoration-thickness: calc(2 * var(--s, 1px));
  text-underline-offset: calc(4 * var(--s, 1px));
}
/* Over: the winner's name and count in green, as the results above the board have them. */
.rv-side--won .rv-who,
.rv-side--won .rv-n {
  color: var(--green);
  font-weight: 500;
}
/* Two digits wide always, so a count passing ten moves nothing. */
.rv-n {
  flex: none;
  inline-size: 2ch;
  text-align: start;
  color: var(--ink);
}
/* The one count that is longer — a hundred, every square of the largest board — can only be a
   winner's, once the game is over: there the box grows for it rather than let a figure spill. */
.rv-side--won .rv-n {
  inline-size: auto;
  min-inline-size: 2ch;
}

/* The keys, where a keyboard is likely (as 24 shows its own during the count-in). */
.rv-keys {
  display: none;
  font-size: calc(12 * var(--s, 1px));
}
@media (hover: hover) and (pointer: fine) {
  .rv-keys { display: block; }
}

/* ---- Phones ---------------------------------------------------------------- */
/* The arena's top margin is 20px here: the caption fills it, in type a size down so that the
   longest thing it says ("the caterpillar had no move — your turn again") fits a 375px phone. */
@media (max-width: 600px) {
  .rv-note {
    padding-block-end: calc(2 * var(--s, 1px));
    line-height: calc(18 * var(--s, 1px));
    font-size: calc(12 * var(--s, 1px));
  }
}
