/* Shapes board. Inherits the existing theme tokens (--text, --muted, --line, --accent,
   --ink, --action-text, --canvas); it introduces no colour of its own. Pieces are told apart
   by a letter and by their own outline, never by colour. */
.shapes { display: grid; justify-items: center; gap: 1.25rem; width: 100%; color: inherit; }
/* Squares never shrink below a full-size target: a wider frame scrolls inside this shell
   instead, so the page itself never scrolls sideways. */
.shapes-frame { width: 100%; max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain; }
/* One square track per column and per row of the frame's own bounding rectangle. The renderer
   sets --columns and --rows for the board in hand; the squares carry the 44px floor on both
   axes, and a square outside the frame is simply an empty track. */
.shapes-layout { display: grid; grid-template-columns: repeat(var(--columns, 6), minmax(44px, 1fr)); grid-template-rows: repeat(var(--rows, 5), minmax(44px, auto)); width: min(100%, calc(var(--columns, 6) * 3.4rem)); margin-inline: auto; }
.shapes-gap { display: block; min-width: 44px; min-height: 44px; }
.shapes-cell { position: relative; box-sizing: border-box; width: 100%; min-width: 0; aspect-ratio: 1; min-height: 44px; display: grid; place-items: center; margin: 0; padding: 0; font: inherit; font-size: clamp(1rem, 4vw, 1.4rem); font-weight: 650; line-height: 1; color: inherit; background: color-mix(in srgb, currentColor 4%, transparent); border: 1px solid color-mix(in srgb, currentColor 35%, transparent); cursor: pointer; transition: background .15s ease; }
/* The frame's own outline, set once when the board is built: a firm edge wherever the frame
   stops, so the tile reads as a shape rather than a rectangle. */
.shapes-cell.is-rim-top { border-top: 2px solid currentColor; }
.shapes-cell.is-rim-right { border-right: 2px solid currentColor; }
.shapes-cell.is-rim-bottom { border-bottom: 2px solid currentColor; }
.shapes-cell.is-rim-left { border-left: 2px solid currentColor; }
/* A placed piece reads as one tile: a shared tint, its letter on every square, and a firm
   outline wherever it meets something that is not itself. */
.shapes-cell.is-filled { background: color-mix(in srgb, currentColor 15%, transparent); }
.shapes-cell.is-edge-top { border-top: 2px solid currentColor; }
.shapes-cell.is-edge-right { border-right: 2px solid currentColor; }
.shapes-cell.is-edge-bottom { border-bottom: 2px solid currentColor; }
.shapes-cell.is-edge-left { border-left: 2px solid currentColor; }
.shapes-glyph { display: block; }
/* Where the piece in hand would land. The dashed inner line says it without colour. */
.shapes-cell.is-ghost { background: color-mix(in srgb, var(--accent, currentColor) 18%, transparent); }
.shapes-cell.is-ghost::after { content: ''; position: absolute; inset: 14%; border: 2px dashed currentColor; border-radius: 3px; }
/* Where it would not. A hatch, so the refusal does not depend on colour either. */
.shapes-cell.is-refused { background: repeating-linear-gradient(45deg, transparent, transparent 4px, color-mix(in srgb, currentColor 20%, transparent) 4px, color-mix(in srgb, currentColor 20%, transparent) 8px); }
.shapes-cell:hover:not(.is-filled) { background: color-mix(in srgb, currentColor 10%, transparent); }
.shapes-cell.is-filled:hover { background: color-mix(in srgb, currentColor 22%, transparent); }
.shapes-cell[aria-current="true"] { box-shadow: inset 0 0 0 3px var(--accent, currentColor); }
.shapes-cell:focus-visible { outline: 3px solid currentColor; outline-offset: -5px; }
/* The tray. Each piece is drawn at its current turn, with its letter in every square. */
.shapes-tray { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; width: min(100%, 30rem); }
.shapes-piece { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 48px; min-height: 48px; padding: .4rem; margin: 0; font: inherit; color: inherit; background: transparent; border: 1px solid var(--line, currentColor); border-radius: 4px; cursor: pointer; }
.shapes-piece-grid { display: grid; grid-template-columns: repeat(var(--columns, 1), 12px); grid-template-rows: repeat(var(--rows, 1), 12px); gap: 1px; }
.shapes-bit { display: block; width: 12px; height: 12px; font-size: 8px; font-weight: 700; line-height: 12px; text-align: center; color: transparent; }
.shapes-bit.is-on { color: inherit; background: color-mix(in srgb, currentColor 30%, transparent); box-shadow: inset 0 0 0 1px currentColor; }
/* In hand, and already in the frame: a doubled border and a dashed one, not two colours. */
.shapes-piece.is-held { border-width: 3px; border-style: double; border-color: var(--accent, currentColor); }
.shapes-piece.is-placed { border-style: dashed; opacity: .6; }
.shapes-piece:hover:not(:disabled) { background: color-mix(in srgb, currentColor 8%, transparent); }
.shapes-piece:disabled { cursor: default; opacity: .5; }
.shapes-piece:focus-visible { outline: 3px solid currentColor; outline-offset: 3px; }
.shapes-tally { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem 1.75rem; margin: 0; font-size: .875rem; }
.shapes-metric { display: inline-flex; align-items: baseline; gap: .5rem; }
.shapes-label { color: var(--muted, currentColor); }
.shapes-value { font-size: 1.2rem; font-variant-numeric: tabular-nums; }
.shapes-pad { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem; width: min(100%, 24rem); }
.shapes-pad [hidden] { display: none; }
.shapes-key { flex: 1 1 6rem; min-height: 48px; min-width: 0; padding: .5rem .35rem; font: inherit; color: inherit; background: transparent; border: 1px solid currentColor; border-radius: 3px; cursor: pointer; }
.shapes-key:hover:not(:disabled) { background: color-mix(in srgb, currentColor 8%, transparent); }
.shapes-key:disabled { opacity: .55; cursor: default; }
.shapes-key:focus-visible { outline: 3px solid currentColor; outline-offset: 4px; }
.shapes-hint { max-width: 34rem; margin: 0; font-size: .875rem; line-height: 1.5; color: var(--muted, currentColor); }
.shapes[data-state="solved"] .shapes-cell { border-color: var(--accent, currentColor); }
.shapes[data-state="blocked"] .shapes-cell, .shapes[data-state="waiting"] .shapes-cell { cursor: default; }
/* The gallery tile: the shared painter marks the frame's squares as given, so the squares
   outside it step back and the miniature reads as the same shape as the board. */
.catalogue-grid[data-family="shapes"] span:not([data-given]) { border-color: transparent; background: transparent; }
.catalogue-grid[data-family="shapes"] span[data-given] { background: color-mix(in srgb, var(--ink) 8%, transparent); }
@media (max-width: 380px) {
  .shapes { gap: 1rem; }
  .shapes-pad, .shapes-tray { width: 100%; max-width: 100%; }
  .shapes-key { padding: .5rem .1rem; font-size: .8125rem; }
  .shapes-tally { gap: .3rem 1.1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .shapes-cell { transition: none; }
}
@media (forced-colors: active) {
  .shapes-cell { border-color: CanvasText; background: Canvas; }
  .shapes-cell.is-filled { background: Canvas; border-color: CanvasText; }
  .shapes-cell.is-ghost { background: Highlight; color: HighlightText; }
  .shapes-cell.is-ghost::after { border-color: HighlightText; }
  .shapes-cell.is-refused { background: Canvas; }
  .shapes-cell[aria-current="true"] { outline: 3px solid Highlight; outline-offset: -3px; }
  .shapes-bit.is-on { background: CanvasText; color: Canvas; }
  .shapes-piece.is-held { border-color: Highlight; }
}
