/* Reflex Chess -- the basic-checkmate trainer at /checkmates.
 *
 * Loaded AFTER seo.css, board.css and pieces.css, and it needs all three:
 *
 *   seo.css     the page chrome, the palette and the type. Everything here
 *               reads its custom properties and defines no colour of its own,
 *               so a change to the house palette moves this page with it.
 *   board.css   the board's geometry -- absolute squares, piece transforms,
 *               the coordinate rails.
 *   pieces.css  the artwork.
 *
 * WHAT IS DUPLICATED HERE AND WHY. board.css deliberately owns no appearance:
 * the square colours, the 1:1 box and the highlight colours live in styles.css,
 * which is the app shell's stylesheet -- 100dvh, a pinned tab bar, overscroll
 * locked. A document Google sends a stranger to must not load that, and
 * styles.css is not mine to split, so the board APPEARANCE block below is
 * restated against the same tokens. It is the same block ratingtest.css
 * carries, for the same reason; if the app's board changes colour, both have to
 * change with it.
 *
 * NO EXTERNAL ANYTHING. One font, already fetched by seo.css. No CDN, no icon
 * font, no image. The page has to render under the strict CSP in vercel.json.
 */

:root {
  /* styles.css defines this; seo.css does not, and the destination dots, the
     selected square and the box shading are all drawn from it. */
  --mark: 91 108 255;
}

/* ---------- the board ---------- */

.cg-wrap { width: 100%; aspect-ratio: 1 / 1; height: auto; }

.cg-wrap cg-board {
  border-radius: .7rem;
  background-color: var(--sq-light);
  background-image: conic-gradient(
    var(--sq-dark) 0 25%, var(--sq-light) 0 50%,
    var(--sq-dark) 0 75%, var(--sq-light) 0);
  background-size: 25% 25%;
  background-position: 0 0;
  background-repeat: repeat;
}

.cg-wrap coords {
  font-family: var(--mono);
  font-size: clamp(.5rem, 1.9vw, .68rem);
  letter-spacing: .04em;
  font-weight: 600;
  opacity: .9;
  text-shadow: 0 1px 2px rgb(0 0 0 / .45);
  color: #fff;
}

/* board.css offsets the file letters 24px right of the board, which pushes the
   "h" clean off the edge on a page where the board sits flush inside a card.
   Corrected for this page only. */
.cg-wrap coords.files { left: 0; bottom: 1px; }

.cg-wrap cg-board square.move-dest {
  background: radial-gradient(rgb(var(--mark) / .70) 22%, rgb(var(--mark) / .90) 0,
                              rgba(0,0,0,.3) 0, rgba(0,0,0,0) 0);
}
.cg-wrap cg-board square.oc.move-dest {
  background: radial-gradient(transparent 0%, transparent 80%, rgb(var(--mark) / .45) 80%);
}
.cg-wrap cg-board square.last-move { background-color: rgba(155,199,0,.41); }
.cg-wrap cg-board square.selected   { background: rgb(var(--mark) / .50); }
.cg-wrap cg-board square.check {
  background: radial-gradient(ellipse at center, rgba(255,0,0,1) 0%, rgba(231,0,0,1) 25%,
    rgba(169,0,0,0) 89%, rgba(158,0,0,0) 100%);
}

/* ---------- the card ---------- */

.bm {
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.1rem 1rem 1.25rem;
  margin: 0 0 2.25rem;
}

.bm-fallback {
  margin: 0;
  color: var(--dim);
  font-size: .95rem;
}
.bm.live .bm-fallback { display: none; }

/* Everything the script drives is hidden until the script is there to drive
   it, so a reader with JavaScript off gets the guide and not a dead board. */
.bm .bm-live { display: none; }
.bm.live .bm-live { display: block; }

/* ---------- the ending picker ---------- */

/* Auto-fit rather than flex-wrap: five buttons wrapping 4 + 1 reads as a
   mistake, three and two reads as a row. */
.bm-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6.4rem, 1fr));
  gap: .35rem;
  margin: 0 0 .85rem;
}

.bm-picker button {
  min-height: 2.4rem;
  padding: .4rem .6rem;
  font: inherit;
  font-size: .84rem;
  font-weight: 600;
  color: var(--dim);
  background: var(--card-2);
  border: 1px solid var(--rule);
  border-radius: .7rem;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.bm-picker button:hover { color: var(--ink); }
.bm-picker button[aria-pressed="true"] {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}

/* ---------- the head-up display ---------- */

.bm-hud {
  display: flex;
  align-items: baseline;
  gap: .9rem;
  flex-wrap: wrap;
  margin: 0 0 .6rem;
}

.bm-hud .who {
  flex: 1 1 auto;
  font-weight: 600;
  font-size: 1.02rem;
}

.bm-hud .stat {
  display: flex;
  align-items: baseline;
  gap: .3rem;
  font-size: .82rem;
  color: var(--dim);
}
.bm-hud .stat b {
  font-family: var(--mono);
  font-size: 1rem;
  color: var(--ink);
  font-weight: 600;
}
.bm.tight .bm-hud .moveline b { color: var(--sec-tactics-2); }

/* ---------- the board and the box overlay ---------- */

.bm-stage { position: relative; }

/* Sixty-four cells laid over the board, pointer-events off so nothing here can
   ever swallow a move. The grid is fixed to White at the bottom, which is what
   the trainer draws, so a1 is the bottom-left cell. */
.bm-overlay {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-template-rows: repeat(8, 1fr);
  pointer-events: none;
  border-radius: .7rem;
  overflow: hidden;
}

.bm-overlay i {
  display: block;
  transition: box-shadow .18s ease, background-color .18s ease;
}

/* The box is drawn as an inset tint rather than a border, because the region is
   rarely a clean rectangle and outlining every cell would produce a hatching
   pattern nobody can read at a glance. */
/* Teal, not the brand indigo. The squares themselves are indigo, so an indigo
   tint on a dark square is very nearly invisible -- and this is the same colour
   the box is drawn in on the guide pages, so the two teach the same thing. */
.bm-overlay i.in {
  background: rgb(22 184 201 / .27);
  box-shadow: inset 0 0 0 1px rgb(22 184 201 / .45);
}

@media (prefers-reduced-motion: reduce) {
  .bm-overlay i { transition: none; }
}

/* ---------- the talking parts ---------- */

.bm-warn {
  margin: .75rem 0 0;
  padding: .6rem .75rem;
  font-size: .9rem;
  line-height: 1.45;
  border-radius: .7rem;
  background: rgb(255 143 63 / .13);
  border: 1px solid rgb(255 143 63 / .45);
  color: var(--ink);
}
.bm-warn b { color: var(--sec-tactics-2); }

.bm-status {
  margin: .75rem 0 0;
  min-height: 4.4rem;
  padding: .6rem .75rem;
  font-size: .93rem;
  line-height: 1.5;
  border-radius: .7rem;
  background: var(--card-2);
  border: 1px solid var(--rule);
}
.bm-status.good { border-color: var(--good); }
.bm-status.good b { color: var(--good); }
.bm-status.bad { border-color: var(--bad); }
.bm-status.bad b { color: var(--bad); }
.bm-status.warn b { color: var(--sec-tactics-2); }

/* ---------- the buttons ---------- */

.bm-btns {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin: .75rem 0 0;
}

.bm-btns button {
  flex: 1 1 7rem;
  min-height: 2.6rem;
  padding: .45rem .7rem;
  font: inherit;
  font-size: .88rem;
  font-weight: 600;
  color: var(--ink);
  background: var(--card-2);
  border: 1px solid var(--rule);
  border-radius: .8rem;
  cursor: pointer;
}
.bm-btns button:hover { border-color: var(--brand-lt); }
.bm-btns button.primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.bm-btns button[hidden] { display: none; }

.bm-opts {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin: .7rem 0 0;
  font-size: .85rem;
  color: var(--dim);
}
.bm-opts input { width: 1rem; height: 1rem; accent-color: var(--brand); }

.bm-cue {
  margin: .7rem 0 0;
  font-size: .88rem;
  line-height: 1.5;
  color: var(--dim);
}

/* ---------- the guide pages ---------- */

/* Two diagrams side by side where there is room for them, stacked where there
   is not. seo.css has .pos for a puzzle and nothing for a before-and-after
   pair, which is the shape almost every explanation on these pages takes. */
.pair {
  display: grid;
  gap: .9rem;
  grid-template-columns: 1fr;
  margin: 1.4rem 0;
}
@media (min-width: 34rem) {
  .pair { grid-template-columns: 1fr 1fr; }
}
.pair figure { margin: 0; }
.pair figcaption {
  margin: .45rem 0 0;
  font-size: .88rem;
  line-height: 1.5;
  color: var(--dim);
}
.pair figcaption b { color: var(--ink); }

.board text { font: 10px var(--mono); }

.steps { counter-reset: step; list-style: none; padding: 0; }
.steps li {
  position: relative;
  padding: 0 0 0 2.1rem;
  margin: 0 0 .8rem;
}
.steps li::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: 0;
  top: .05rem;
  width: 1.5rem;
  height: 1.5rem;
  display: grid;
  place-items: center;
  font-family: var(--mono);
  font-size: .8rem;
  font-weight: 600;
  color: #fff;
  background: var(--sec, var(--brand));
  border-radius: 50%;
}

/* The honesty strip: one row per ending with the measured worst case. */
.tb {
  width: 100%;
  border-collapse: collapse;
  margin: 1.2rem 0;
  font-size: .9rem;
}
.tb th, .tb td {
  text-align: left;
  padding: .5rem .55rem;
  border-bottom: 1px solid var(--rule);
}
.tb th { color: var(--dim); font-weight: 600; font-size: .78rem;
         text-transform: uppercase; letter-spacing: .06em; }
.tb td b { font-family: var(--mono); }
.tb tr:last-child td { border-bottom: 0; }

/* ---------- one borrowed defect, corrected locally ---------- */

/* seo.css declares `.cta span { color: var(--dim) }` and then `.btn { color:
   #fff }`. The first is more specific, so it wins, and the pill on the primary
   call to action renders dim blue-grey on a saturated fill -- about 1.6:1,
   which is not readable. It is fixed there for the two sections whose colour is
   brightest (`[data-sec="basics"] .btn`), and endgame teal is just as bright.
   seo.css is not mine to edit, so it is restated here at a specificity that
   reaches it. The same fix belongs in seo.css, where it would also reach /mates
   and /rating-test, which have the identical problem today. */
.cta span.btn { color: #14161f; }
