:root {
  /* you and them: blue and red; north is the opponent unless you sit north
     (see .me-north) */
  --you: #1f4fb4;
  --them: #c4302b;
  --north: var(--them);
  --south: var(--you);
  --ink: #141414;
  --muted: #5c5c5c;
  --faint: #9a9a9a;
  --line: #d4d4d4;
  --frame: #6b6b6b;
  --wash: #e9effb;
  --wash-them: #fbeaea;

  /* the slightly rounded corner of a tile, shared by every button shell */
  --shell-radius: 0.4vmin;

  /* tile glyphs come from Apple Symbols; naming it first, rather than leaving it a
     fallback, keeps the tile in the same place in its box whatever the text font,
     so the shells and faces measured against it (--face-*) line up */
  --tile-font: "Apple Symbols", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --text-font: "Tenor Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* a tile that can be clicked is drawn bolder; a picked one is also underlined */
  --bold: 0.022em;
}

body {
  background-color: white;
  color: var(--ink);
  margin: 0;
  font-family: var(--text-font);
}
body.at-game {
  justify-content: center;
  align-items: center;
  overflow: hidden;
  position: fixed;
}

/* only the current screen shows */
body:not(.at-lobby) .lobby,
body:not(.at-room) .room,
body:not(.at-game) .container {
  display: none;
}

/*
------------------------------------------------------------- the lobby and table room

One quiet column. The lobby: the title, your name, and the open tables. The room: a
card laid out like the game, with your opponent above in red, you below in blue, and
the tiles between.
*/
.screen {
  box-sizing: border-box;
  min-height: 100vh;
  padding: 12vh 16px 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.title {
  margin: 0 0 6px;
  font-size: clamp(28px, 6vw, 44px);
  font-weight: normal;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: center;
}
.link {
  font-size: 14px;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
}
.link:hover {
  color: var(--ink);
  border-color: var(--ink);
}
.how-to {
  margin-bottom: 64px;
}

/* plain buttons: a thin outline and letter-spaced capitals */
.btn {
  height: 44px;
  padding: 0 22px;
  font: inherit;
  font-size: 14px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: inherit;
  background: white;
  border: 1px solid currentColor;
  cursor: pointer;
}
.btn:hover {
  background-color: #f4f4f4;
}
.btn.primary {
  color: white;
  background-color: var(--you);
  border-color: var(--you);
}
.btn.primary:hover {
  background-color: #1a4399;
}
.btn:disabled {
  color: var(--faint);
  border-color: var(--line);
  background: white;
  cursor: default;
}
.btn.primary:disabled {
  color: white;
  background-color: var(--line);
}
.btn.small {
  height: 36px;
  padding: 0 16px;
  font-size: 12px;
}

/* the name: a single underline */
.name-input {
  box-sizing: border-box;
  width: min(300px, 100%);
  padding: 6px 0;
  font: inherit;
  font-size: 26px;
  text-align: center;
  color: var(--ink);
  background: none;
  border: none;
  border-bottom: 1.5px solid var(--ink);
  border-radius: 0;
  outline: none;
}
.name-input::placeholder {
  color: var(--faint);
}
.lobby-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin: 18px 0 56px;
}
/* until there's a name, the rest is only a preview */
.lobby.locked .table-list {
  opacity: 0.35;
}

.table-list {
  width: min(560px, 100%);
  border-top: 1px solid var(--line);
}
.table-list[hidden] {
  display: none;
}
.list-head {
  padding: 14px 0 6px;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.table-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 24px;
  height: 64px;
  border-bottom: 1px solid var(--line);
}
.row-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 16px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--them);
}

/* a table's tiles, with a dashed slot for each still to be picked */
.tile-set {
  font-family: var(--tile-font);
  line-height: 1;
  white-space: nowrap;
}
.tile-set .slot {
  display: inline-block;
  width: 0.72em;
  height: 0.94em;
  margin: 0 0.04em;
  vertical-align: top;
  border: 1.5px dashed var(--line);
  border-radius: 0.06em;
}
.row-tiles {
  font-size: 34px;
  letter-spacing: 2px;
  color: var(--muted);
}
/* the room's set: each tile named under it; an empty one is a dashed slot */
.room-set {
  display: flex;
  gap: 6px;
}
.set-tile {
  width: 84px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0;
  font: inherit;
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
}
.set-glyph {
  font-family: var(--tile-font);
  font-size: 64px;
  line-height: 1;
}
.set-tile:hover .set-glyph {
  color: var(--you);
}
.set-name {
  font-size: 10px;
  letter-spacing: 0.12em;
}
.set-tile.empty {
  box-sizing: border-box;
  width: 46px;
  height: 60px;
  margin: 2px 19px 0;
  border: 1.5px dashed var(--line);
  border-radius: 4px;
  cursor: default;
}

/* the room */
.room {
  padding-top: 8vh;
}
.room-card {
  width: min(640px, 100%);
  border: 1.5px solid var(--frame);
}
.seat {
  min-height: 96px;
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 28px;
}
.seat.them {
  border-bottom: 1px solid var(--line);
  color: var(--them);
}
.seat.you {
  border-top: 1px solid var(--line);
  background-color: var(--wash);
  color: var(--you);
}
.seat-name {
  font-size: 20px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.seat-name.empty {
  font-size: 17px;
  letter-spacing: 0.04em;
  text-transform: none;
  color: var(--faint);
}
/* someone who has dropped out; the game will wait for them */
.seat-name.gone {
  opacity: 0.35;
}
.seat-buttons {
  display: flex;
  gap: 10px;
}

.tiles-area {
  padding: 26px 20px 30px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}
/* starter, random, or custom */
.segmented {
  display: inline-flex;
  border: 1px solid var(--ink);
}
.segmented button {
  height: 40px;
  padding: 0 20px;
  font: inherit;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  background: white;
  border: none;
  border-left: 1px solid var(--ink);
  cursor: pointer;
}
.segmented button:first-child {
  border-left: none;
}
.segmented button.on {
  color: white;
  background-color: var(--ink);
}
.segmented button:disabled {
  cursor: default;
}
.segmented button:disabled:not(.on) {
  color: var(--faint);
}

/* every tile, pale until picked */
.picker {
  display: grid;
  grid-template-columns: repeat(6, 92px);
  justify-content: center;
  row-gap: 10px;
}
.pick {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  color: var(--faint);
}
.pick.on {
  color: var(--ink);
}
.pick-tile {
  padding: 0;
  font-family: var(--tile-font);
  font-size: 52px;
  line-height: 1;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}
.pick-tile:hover {
  color: var(--muted);
}
.pick.on .pick-tile:hover {
  color: var(--ink);
}
.pick-tile:disabled {
  opacity: 0.4;
  cursor: default;
}
.pick-name {
  font-size: 10px;
  letter-spacing: 0.12em;
}
.about-tiles {
  font: inherit;
  font-size: 14px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--line);
  padding: 0 0 2px;
  cursor: pointer;
}
@media (max-width: 600px) {
  .room-set {
    gap: 2px;
  }
  .set-tile {
    width: 62px;
  }
  .set-tile.empty {
    margin: 2px 8px 0;
  }
  .set-glyph {
    font-size: 56px;
  }
  .set-name {
    font-size: 8px;
    letter-spacing: 0.04em;
  }
  .picker {
    grid-template-columns: repeat(4, 80px);
  }
}

.room-foot {
  display: flex;
  gap: 12px;
  margin-top: 26px;
}

/* connection trouble and server errors */
.netbar,
.toast {
  position: fixed;
  left: 0;
  right: 0;
  text-align: center;
  background-color: black;
  color: white;
  padding: 6px;
  z-index: 10;
}
.netbar {
  top: 0;
}
.toast {
  bottom: 0;
}
.netbar[hidden],
.toast[hidden] {
  display: none;
}

/*
------------------------------------------------------------------------- the game

Partitioned, never floating: the reference and tile accounting on the left, the board
in the middle between the two players' strips (theirs above, yours below), the log on
the right. Inspired by the tiles: white, fine lines, a tile's rounded corners. Only
the board is set off a little more heavily.

The board's size is derived from the window: as big as the height allows after the
strips, unless the side columns need the width. As the window narrows, the left
column stacks its contents before the board gives up any size. Everything on the
board is sized relative to it (cqmin), so the layout holds at any laptop size.
*/
.container.me-north {
  --north: var(--you);
  --south: var(--them);
}
.container {
  --radius: 8px;

  --side-min: 124px;
  /* the log gives up width before the board does */
  --log-min: clamp(150px, 20vw, 300px);
  --strip: clamp(70px, 12vh, 118px);
  --board: min(calc(100vh - 2 * var(--strip)), calc(100vw - var(--side-min) - var(--log-min)));

  width: 100vw;
  height: 100vh;
  display: grid;
  grid-template-columns: minmax(var(--side-min), 0.9fr) var(--board) minmax(var(--log-min), 1.2fr);
  /* the outer rows take any spare height, so the columns always run the full height */
  grid-template-rows: minmax(var(--strip), 1fr) var(--board) minmax(var(--strip), 1fr);

  font-family: var(--text-font);
  color: var(--ink);
  background-color: white;
  cursor: default;
}

/* ------------------------------------------------------------------- left */
.sidebar {
  grid-column: 1;
  grid-row: 1 / 4;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--line);
  container-type: inline-size;
}
/* the tiles in play and the smite cost, filling the height above the board so the
   graveyard's rule meets the board's top edge (unless they wrap in a narrow column) */
.sidebar-top {
  flex-shrink: 0;
  box-sizing: border-box;
  min-height: calc((100vh - var(--board)) / 2 - 1px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(var(--strip) * 0.06);
  padding: calc(var(--strip) * 0.06) 0;
}
/* the tiles in play, at a glance; clicking opens what each does */
.in-play {
  padding: 0 18px;
  font-size: calc(var(--strip) * 0.36);
  line-height: 1;
  letter-spacing: 2px;
  cursor: pointer;
}
.in-play:hover {
  color: var(--you);
}
.smite-cost {
  padding: 0 18px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: calc(var(--strip) * 0.19);
}
.smite-cost .option {
  font-size: calc(var(--strip) * 0.28);
  cursor: default;
  -webkit-text-stroke: 0;
}
.smite-cost .option.shell::before {
  border-width: var(--frame-width, 0.02em);
}
/* each kind of tile has its own fixed share of the column, so one filling up never
   moves the others */
.acc {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.acc-row {
  flex: 1;
  min-height: 0;
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.acc-label {
  font-size: 14px;
  color: var(--muted);
}
.acc-tiles {
  font-size: 28px;
  line-height: 1;
  color: #555555;
}
/* a dying tile, on its way from the board to the graveyard */
.ghost {
  position: fixed;
  z-index: 10;
  line-height: 1;
  pointer-events: none;
}
/* a narrow column stacks each label over its tiles */
@container (max-width: 200px) {
  .in-play, .smite-cost, .acc-row, .quit {
    padding-left: 12px;
    padding-right: 12px;
  }
}
.quit {
  margin-top: auto;
  flex-shrink: 0;
  height: var(--strip);
  padding: 0 18px;
  display: flex;
  align-items: center;
  cursor: pointer;
}
.quit .option {
  font-size: 36px;
  -webkit-text-stroke: 0;
}
.quit .option.shell::before {
  border-width: var(--frame-width, 0.02em);
}

/* ----------------------------------------------------------------- strips */
.strip {
  grid-column: 2;
  min-width: 0;
  padding: 8px calc(var(--board) * 0.025);
  display: grid;
  height: var(--strip);
  box-sizing: border-box;
  grid-template-columns: minmax(0, auto) 1fr auto;
  column-gap: 16px;
  align-items: center;
}
.strip.top {
  grid-row: 1;
  align-self: end;
}
.strip.bottom {
  grid-row: 3;
  align-self: start;
}
/* the strip of whoever the game is waiting on, washed in their colour */
.strip.acting {
  background-color: var(--wash);
}
.strip.top.acting {
  background-color: var(--wash-them);
}
.strip .who {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.strip .name {
  font-size: 13px;
  font-weight: normal;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.turn-note {
  font-size: 14px;
  color: var(--ink);
}
.strip .coins {
  grid-column: 2;
  display: flex;
  align-items: baseline;
  gap: 2px;
}
.amount {
  font-size: calc(var(--strip) * 0.32);
}
.hand-tiles {
  grid-column: 3;
  display: flex;
  gap: 6px;
}
.hand-tile {
  font-size: calc(var(--strip) * 0.62);
  line-height: 1;
}
.strip.north .name, .strip.north .amount, .strip.north .hand-tile { color: var(--north); }
.strip.south .name, .strip.south .amount, .strip.south .hand-tile { color: var(--south); }

/* ------------------------------------------------------------------ board */
/* the board's frame sits centred on the column dividers above and below it: its box
   reaches half a frame plus half a divider past its column on each side */
.board {
  --frame-width: 1.5px;
  --reach: calc(var(--frame-width) / 2 + 0.5px);
  grid-column: 2;
  grid-row: 2;
  box-sizing: border-box;
  width: calc(var(--board) + 2 * var(--reach));
  height: calc(var(--board) + 2 * var(--reach));
  margin: calc(-1 * var(--reach));
  position: relative;
  z-index: 1;
  container-type: size;

  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(5, 1fr);

  border: var(--frame-width) solid var(--frame);
  background-color: white;
}
.cell {
  position: relative;
  min-width: 0;
  min-height: 0;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);

  /* the piece sits in the middle, a little smaller than the square so what's drawn in
     the corners (options, exchange tiles, bonus) mostly clears it */
  display: flex;
  align-items: center;
  justify-content: center;
}
.cell:nth-child(5n) {
  border-right: none;
}
.cell:nth-child(n + 21) {
  border-bottom: none;
}
.piece {
  display: inline-block;
  position: relative;
  font-size: 14.6cqmin;
  line-height: 1;
}
.piece,
.vacancy,
.option,
.claim-note .claimed,
.rule-tile,
.ghost {
  font-family: var(--tile-font);
}
.board-tile {
  font-weight: normal;
}
/* an empty tile, dashed, where a tile died and its replacement will go */
.vacancy {
  display: inline-block;
  position: relative;
  width: 0.78em;
  height: 1em;
  font-size: 14.6cqmin;
  animation: vacancy 1.4s ease-in-out infinite alternate;
}
.vacancy::before {
  content: "";
  position: absolute;
  left: 0.0475em;
  top: 0.046em;
  width: 0.685em;
  height: 0.908em;
  box-sizing: border-box;
  border: 0.02em dashed currentColor;
  border-radius: 0.055em;
}
@keyframes vacancy {
  from { opacity: 1; }
  to { opacity: 0.35; }
}
/*
what makes a square special sits in its bottom-left corner: the bonus, or an
exchange's two tiles side by side
*/
.cell-marks {
  position: absolute;
  left: 0.5cqmin;
  bottom: 0.5cqmin;
  display: flex;
  align-items: flex-end;
  gap: 0.5cqmin;
  line-height: 1;
  pointer-events: none;
  color: #555555;
}
.cell-marks .board-tile {
  font-size: 4.4cqmin;
  pointer-events: auto;
}
.cell-marks .bonus {
  font-size: 3.7cqmin;
}
/* webs: a wash of the colour of whoever laid them */
.web {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.web.north { background-color: color-mix(in srgb, var(--north) 18%, transparent); }
.web.south { background-color: color-mix(in srgb, var(--south) 18%, transparent); }

/*
selection; colour only ever says whose piece it is
  - a tile that can be clicked (a piece, in hand, on an exchange) is drawn bolder,
    and a picked one also gets a bar under it
  - abilities, smites and responses are drawn on the board as options (see .option)
*/
.hand-tile.highlight,
.board-tile.highlight,
.cell.highlight.own-piece .piece,
.cell.chosen-start .piece,
.cell.chosen-target .piece {
  -webkit-text-stroke: var(--bold) currentColor;
}
.cell-marks .board-tile.highlight {
  color: var(--ink);
}
.cell.chosen-start .piece::after,
.cell.chosen-target .piece::after {
  content: "";
  position: absolute;
  left: 18%;
  right: 18%;
  bottom: -0.06em;
  height: 0.035em;
  border-radius: 0.02em;
  background-color: currentColor;
}
.highlight {
  cursor: pointer;
}

/* a finished claim: a line from the piece to its target */
.claim-line {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.claim-line line {
  stroke: currentColor;
  stroke-width: 0.9cqmin;
  stroke-linecap: round;
}
.claim-line polygon {
  fill: currentColor;
}
.claim-line .claim-cross {
  stroke-width: 1.1cqmin;
}
/* white under the cross, so it reads over the tile it lands on */
.claim-line .claim-halo {
  stroke: white;
  stroke-width: 2cqmin;
}
/* the claimed ability (and any reflect, and the answers) written beside the line */
.claim-note {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 1.2cqmin;
  white-space: nowrap;
}
.claim-note.above { transform: translate(-50%, -100%); }
.claim-note.right { transform: translate(0, -50%); }
.claim-note.left { transform: translate(-100%, -50%); }
.claim-note.below { transform: translate(-50%, 0); }
.claim-note.above-right { transform: translate(0, -100%); }
.claim-note.above-left { transform: translate(-100%, -100%); }
.claim-note.below-left { transform: translate(-100%, 0); }
.claim-note.below-right { transform: translate(0, 0); }
.claim-note .claimed,
.claim-note .option {
  font-size: 7.3cqmin;
}
.claim-note .note-separator {
  font-size: 4.9cqmin;
  color: var(--muted);
}

/* options, in every square: a row in the top-right corner, ↕ rightmost */
.cell-options {
  --option-gap: 0.5cqmin;
  position: absolute;
  inset: 0;
  padding: var(--option-gap);
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-content: flex-start;
  gap: var(--option-gap);
  pointer-events: none;
}
.cell-options .option {
  font-size: 5.2cqmin;
}
.option {
  pointer-events: auto;
  cursor: pointer;
  color: var(--ink);
  -webkit-text-stroke: var(--bold) currentColor;
}
/*
the face of a tile glyph, where this font draws it in the glyph's box (measured):
an option or claimed tile is filled white only there, so it covers just the tile and
not a box around it, and the ones that aren't tiles (↕ ⚡ ✓ 🚩 ✕) get a frame drawn in
the same place
*/
.option,
.claim-note .claimed {
  --face-left: 0.0475em;
  --face-top: 0.046em;
  --face-width: 0.685em;
  --face-height: 0.908em;
  --face-radius: 0.055em;
  --frame-width: 0.02em;

  position: relative;
  z-index: 0;
  display: inline-block;
  width: 0.78em;
  height: 1em;
  line-height: 1em;
}
.option::before,
.claim-note .claimed::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: var(--face-left);
  top: var(--face-top);
  width: var(--face-width);
  height: var(--face-height);
  border-radius: var(--face-radius);
  background-color: white;
}
/* the frame matches a bolded tile's: the font's frame plus the stroke on both edges */
.option.shell::before {
  box-sizing: border-box;
  left: calc(var(--face-left) - var(--bold) / 2);
  top: calc(var(--face-top) - var(--bold) / 2);
  width: calc(var(--face-width) + var(--bold));
  height: calc(var(--face-height) + var(--bold));
  border: calc(var(--frame-width) + var(--bold)) solid currentColor;
  border-radius: calc(var(--face-radius) + var(--bold) / 2);
}
.option.shell .symbol {
  position: absolute;
  left: var(--face-left);
  top: var(--face-top);
  width: var(--face-width);
  height: var(--face-height);
  display: flex;
  align-items: center;
  justify-content: center;
}
.option.shell .symbol span {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 0.5em;
  line-height: 1;
}

/* ------------------------------------------------------------------- log */
.side {
  grid-column: 3;
  grid-row: 1 / 4;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--line);
}
.log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 6px 0;
  /* the log is sized to its own width (cqi), so a row keeps to one line at any size */
  container-type: inline-size;
  cursor: text;
}
/* a grid of who, what, and coins, shared by every turn so the columns line up */
.log-list {
  display: grid;
  grid-template-columns: fit-content(8ch) 1fr auto;
  column-gap: 4cqi;
  padding: 0 5cqi;
  text-align: left;
  font-size: 4.6cqi;
  line-height: 5.6cqi;
}
/* each turn is a block of rows, ruled off from the one before */
.log-turn {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  align-items: center;
  row-gap: 1.4cqi;
  padding: 2.6cqi 0;
  border-top: 1px solid var(--line);
}
.log-turn:first-child {
  border-top: none;
}
.log-turn.old {
  opacity: 0.75;
}
.log-who {
  /* long names are cut short, but the column never collapses */
  min-width: 3ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.85em;
  font-weight: normal;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.log-what {
  display: flex;
  align-items: center;
  gap: 2.1cqi;
}
.log-item {
  display: inline-flex;
  align-items: center;
  gap: 1.3cqi;
  font-style: normal;
}
.log-glyph {
  font-size: 8.6cqi;
  line-height: 8.6cqi;
}
.log-name {
  font-size: 3.6cqi;
  font-weight: normal;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
/* a claim that didn't happen: a bluff caught, or an attack reflected */
.log-what.cancelled {
  color: var(--muted);
  text-decoration: line-through;
}
.log-coins {
  display: flex;
  gap: 2.1cqi;
  justify-content: flex-end;
}
/* a narrow log keeps to the glyphs: who is a bar in their colour, and the tiles go
   unnamed */
@container (max-width: 240px) {
  .log-list {
    grid-template-columns: 3px 1fr auto;
    column-gap: 6cqi;
    font-size: 8cqi;
    line-height: 10cqi;
  }
  .log-who {
    align-self: stretch;
    min-width: 0;
    font-size: 0;
  }
  .log-who:not(:empty) {
    background-color: currentColor;
  }
  .log-glyph {
    font-size: 14cqi;
    line-height: 14cqi;
  }
  .log-name {
    display: none;
  }
}

/* ----------------------------------------------------- the tiles reference */
.rules {
  position: fixed;
  inset: 0;
  z-index: 20;
  background-color: rgba(255, 255, 255, 0.82);
  display: flex;
  align-items: center;
  justify-content: center;
}
.rules[hidden] {
  display: none;
}
.rules-panel {
  position: relative;
  width: 88vw;
  height: 88vh;
  overflow-y: auto;
  /* everything scales from the mini boards' squares, so the whole reference fits */
  --sq: clamp(16px, 3.2vh, 30px);
  padding: max(5vh, 48px) 4vw 3vh;
  box-sizing: border-box;
  background-color: white;
  border: 1.5px solid #6b6b6b;
  border-radius: 8px;
  font-family: var(--text-font);
  color: #141414;
}
.rules-close {
  position: absolute;
  top: 12px;
  right: 16px;
  font-size: 36px;
  -webkit-text-stroke: 0;
}
/* a single tile's reference: a panel just big enough for it */
.rules-panel:has(.rules-list.single) {
  width: auto;
  height: auto;
  max-width: 88vw;
  padding-right: max(4vw, 64px);
}
.rules-list.single {
  grid-template-columns: auto;
}
/* two columns, filled top to bottom (renderRules sets the rows) */
.rules-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-flow: column;
  gap: calc(var(--sq) * 0.9) 4vw;
}
.rule {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto 1fr;
  column-gap: 18px;
  align-items: start;
}
.rule-glyph {
  grid-row: 1 / 3;
  font-size: calc(var(--sq) * 2.6);
  line-height: 1;
}
.rule-name {
  margin-top: 6px;
  font-size: calc(var(--sq) * 0.6);
  font-weight: normal;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.rule-text {
  font-size: calc(var(--sq) * 0.56);
  line-height: 1.35;
}
.rule-text > div + div {
  margin-top: 2px;
}
/* a mini board per use, in the board's own hairlines, jade for you, cinnabar for them */
.rule-boards {
  grid-column: 3;
  grid-row: 1 / 3;
  display: flex;
  gap: 10px;
  --you: #1f4fb4;
  --them: #c4302b;
  --line: #d4d4d4;
  --frame: #6b6b6b;
}
.rule-board {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, var(--sq));
  grid-template-rows: repeat(5, var(--sq));
  border: 1px solid var(--frame);
  border-radius: 5px;
  overflow: hidden;
}
.rule-square {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.rule-square:nth-child(5n) {
  border-right: none;
}
.rule-square:nth-child(n + 21) {
  border-bottom: none;
}
.rule-square.blast {
  background-color: color-mix(in srgb, var(--them) 16%, transparent);
}
.rule-square.webbed {
  background-color: color-mix(in srgb, var(--you) 18%, transparent);
}
.rule-arrows {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--them);
  stroke: currentColor;
  stroke-width: 0.07;
  stroke-linecap: round;
  pointer-events: none;
}
.rule-tile {
  font-size: calc(var(--sq) * 0.93);
  line-height: 1;
  position: relative;
}
.rule-tile.you, .rule-dot.you { color: var(--you); }
.rule-tile.them, .rule-dot.them, .rule-sign { color: var(--them); }
.rule-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: currentColor;
}
.rule-dot.trail {
  width: 4px;
  height: 4px;
  color: var(--them);
  opacity: 0.6;
}
.rule-sign {
  font-size: calc(var(--sq) * 0.55);
  line-height: 1;
}
/* where the tile set off from: an empty tile, dashed */
.rule-start {
  width: calc(var(--sq) * 0.55);
  height: calc(var(--sq) * 0.7);
  border: 1.5px dashed var(--you);
  border-radius: 3px;
  box-sizing: border-box;
}

/* whose piece it is: jade for you, cinnabar for the opponent, whichever side you sit */
.north {
  color: var(--north);
}
.south {
  color: var(--south);
}
