/* ══════════════════════════════════════════════════════════════════════════
   BOARD — structure only.

   There is deliberately not a single color, size or duration written in this
   file. Every one is a var() pointing at theme.css. If you find yourself
   wanting to edit here to change an appearance, the variable is missing and
   should be added to theme.css instead.
   ══════════════════════════════════════════════════════════════════════════ */

.cb-root {
  display: block;
  width: 100%;
}

.cb-board {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  /* Makes cqw units inside resolve against the board's own width, which is what
     lets the coordinates scale with the board instead of with the page font. */
  container-type: inline-size;
  border-radius: var(--board-radius);
  box-shadow: var(--board-shadow);
  border: var(--board-border);
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  /* none, not manipulation: a drag across the board must not scroll the page
     on a touch screen. */
  touch-action: none;
}

/* ── squares ───────────────────────────────────────────────────────────── */

.cb-squares {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  z-index: 1;
}

.cb-square {
  position: relative;
}

.cb-light { background: var(--sq-light); }
.cb-dark  { background: var(--sq-dark); }

/* ── coordinates ───────────────────────────────────────────────────────── */

.cb-coord {
  position: absolute;
  font-size: var(--coord-size);
  font-weight: var(--coord-weight);
  line-height: 1;
  pointer-events: none;
}

.cb-coord-file { right: 4%; bottom: 3%; }
.cb-coord-rank { left: 4%;  top: 3%; }

.cb-light > .cb-coord { color: var(--coord-on-light); }
.cb-dark  > .cb-coord { color: var(--coord-on-dark); }

/* ── highlights ────────────────────────────────────────────────────────── */

/* Painted as a layer over the square rather than by swapping the square's own
   background, so the underlying board color still shows through the alpha. */
.cb-square::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.cb-square.cb-last::before  { background: var(--hl-last); }
.cb-square.cb-sel::before   { background: var(--hl-selected); }
.cb-square.cb-check::before { background: var(--hl-check); }

/* A premove: what you are about to play, before it is your turn. Its own colour
   rather than the selection colour, because it is a promise rather than a
   state — and it sits on the board while the reply arrives. */
.cb-square.cb-premove::before { background: var(--hl-premove); }

/* The square a dragged piece is hovering over. Inset so it reads as a frame
   around the square rather than a fill, which would hide the piece beneath. */
.cb-square.cb-hover::before {
  background: none;
  box-shadow: inset 0 0 0 var(--hl-hover-width) var(--hl-hover);
}

/* The move-target dot is a separate pseudo-element so it can coexist with a
   last-move or check highlight on the same square. */
.cb-square.cb-target::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--hl-target-size);
  height: var(--hl-target-size);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--hl-target);
  pointer-events: none;
}

/* A target square that is occupied reads better as a ring than a dot — it says
   "capture here" rather than "move here". */
.cb-square.cb-target.cb-occupied::after {
  width: 88%;
  height: 88%;
  background: none;
  border: calc(var(--hl-target-size) / 4) solid var(--hl-target);
}

/* ── pieces ────────────────────────────────────────────────────────────── */

.cb-pieces {
  position: absolute;
  inset: 0;
  z-index: 2;
  /* Clicks fall through to the square underneath, which always knows its own
     name. That is why the click handler never needs to hit-test a piece. */
  pointer-events: none;
}

.cb-piece {
  position: absolute;
  top: 0;
  left: 0;
  width: 12.5%;
  height: 12.5%;
  will-change: transform;
}

.cb-piece.cb-animating {
  transition: transform var(--anim-move) var(--anim-ease);
}

/* A piece under the cursor. Raised above its neighbors, slightly enlarged so
   it reads as lifted, and never animated — a transition here would make it lag
   behind the pointer. */
.cb-piece.cb-dragging {
  z-index: 20;
  transition: none;
  cursor: grabbing;
  filter: drop-shadow(0 var(--drag-shadow-y) var(--drag-shadow-blur) rgba(0, 0, 0, 0.45));
}

.cb-piece.cb-dragging > svg,
.cb-piece.cb-dragging > img,
.cb-piece.cb-dragging > span {
  transform: scale(calc(var(--piece-scale) * var(--drag-scale)));
}

.cb-piece.cb-appearing { opacity: 0; }

.cb-piece.cb-leaving {
  opacity: 0;
  transition: opacity var(--anim-fade) linear;
}

.cb-piece > svg,
.cb-piece > img,
.cb-piece > span {
  display: block;
  width: 100%;
  height: 100%;
  transform: scale(var(--piece-scale));
}

/* An image from a piece folder, drawn as itself. Whatever proportions the file
   has are kept — a square-ish piece in a rectangular file should not be
   stretched to fill the square. */
.piece-img { object-fit: contain; }

/* The built-in sets are silhouettes; the color is applied here so one set of
   path data serves both sides. Downloaded sets are <img> and skip all of this. */
.piece-svg {
  stroke: var(--piece-outline);
  stroke-width: var(--piece-outline-width);
  stroke-linejoin: round;
  stroke-linecap: round;
}

.piece-svg.piece-w * { fill: var(--piece-light); }
.piece-svg.piece-b * { fill: var(--piece-dark); }

/* `.piece-svg .cut { fill: none }` was here — detail that is a LINE rather
   than a shape, the old Staunton bishop's slit and knight's eye. That set was
   deleted on 2026-08-29 and `flat` has no line detail, so the rule had nothing
   left to style. A set written in path data that wants one again brings the
   rule back with it. */

/* A file from a piece folder that did not name a side, so it has to serve
   both. The image is used as a MASK and the color comes from the theme —
   otherwise White and Black would be the same picture and the board unusable.
   A file called white-pawn.png keeps its own colors and never comes through
   here; see board/piece-folders.js. */
.piece-mask {
  background-color: var(--piece-light);
  -webkit-mask-image: var(--piece-src);
  mask-image: var(--piece-src);
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  /* The silhouettes get their edge from a stroke; a mask has no stroke to
     give, so the edge is a shadow in the same color. Without it a dark piece
     on a dark square has no outline at all. */
  filter: drop-shadow(0 0 var(--piece-mask-edge) var(--piece-outline));
}

.piece-mask.piece-b { background-color: var(--piece-dark); }

/* ── arrows and circles ────────────────────────────────────────────────── */

.cb-overlay {
  position: absolute;
  inset: 0;
  /* Above the pieces: an arrow that disappears behind a knight is useless. */
  z-index: 3;
  pointer-events: none;
  overflow: visible;
}

/* Only when pieces can actually be picked up — an unconditional grab cursor on
   a read-only board promises something that will not happen. */
.cb-board.cb-grabbable { cursor: grab; }
.cb-board.cb-grabbable:active { cursor: grabbing; }
