/* The chess.com look: a green board on a warm near-black shell, one loud
   green for anything you can press, and everything else deliberately quiet so
   the board is the only thing with colour in it. Dark is the primary theme,
   as it is there; light is a full second palette rather than an afterthought. */
:root {
  --bg: #302e2b;
  --panel: #262421;
  --panel-2: #21201d;
  --ink: #ffffff;
  --ink-soft: #b0aeab;
  --ink-dim: #8b8987;
  --line: rgba(255, 255, 255, .09);
  --accent: #81b64c;
  --accent-hi: #95bb4a;
  --accent-edge: #45753c;
  --accent-ink: #ffffff;
  --light-sq: #ebecd0;
  --dark-sq: #739552;
  --hl-light: #f5f682;      /* last move / selection, on a light square */
  --hl-dark: #b9ca43;       /* ... and on a dark one */
  --sel-ring: rgba(255, 255, 255, .55);
  --hint-dot: rgba(0, 0, 0, .16);
  --good: #81b64c;
  --bad: #ca3431;
  --bad-soft: rgba(202, 52, 49, .22);
  --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 10px 30px rgba(0, 0, 0, .3);
  --r: 8px;
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f8f8f6;
    --panel: #ffffff;
    --panel-2: #f1f1ef;
    --ink: #312e2b;
    --ink-soft: #5d5b58;
    --ink-dim: #7c7a77;
    --line: rgba(0, 0, 0, .1);
    --sel-ring: rgba(0, 0, 0, .45);
    --shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 8px 24px rgba(0, 0, 0, .08);
  }
}

* { box-sizing: border-box; }
/* Anything laid out with flex or grid otherwise ignores the hidden attribute,
   and an invisible element that still takes space — or still catches clicks —
   is a bug every single time. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100dvh; background: var(--bg); color: var(--ink);
  font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  -webkit-font-smoothing: antialiased;
}
button, select, input { font: inherit; color: inherit; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
h1, h2 { margin: 0; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  /* Wraps rather than overflows: on a narrow phone the sync state and the
     next-puzzle button drop to a second row instead of off the screen. */
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: .5rem 1rem;
  padding: .65rem clamp(.9rem, 3vw, 2rem);
  background: var(--panel); border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: .55rem; text-decoration: none; color: inherit; }
.brand-mark {
  width: 2rem; height: 2rem; border-radius: 7px; display: grid; place-items: center;
  background: var(--accent); padding: 2px;
}
.brand-mark svg { width: 100%; height: 100%; display: block; }
.brand-name { font-size: 1.25rem; font-weight: 800; letter-spacing: -.02em; }
.brand-name .dot { color: var(--accent); }
.top-right { display: flex; align-items: center; gap: .6rem; margin-left: auto; }
.cta {
  border: 0; border-bottom: 3px solid var(--accent-edge);
  background: var(--accent); color: var(--accent-ink);
  font-weight: 700; font-size: .95rem; padding: .55rem 1.2rem; border-radius: var(--r);
  cursor: pointer; transition: background .12s, transform .08s;
}
.cta:hover { background: var(--accent-hi); }
.cta:active { transform: translateY(2px); border-bottom-width: 1px; }

.sync-pill {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .78rem; font-weight: 600; color: var(--ink-soft);
  background: var(--panel-2); border: 1px solid var(--line);
  padding: .3rem .6rem; border-radius: 999px; white-space: nowrap;
}
.sync-dot { width: .5rem; height: .5rem; border-radius: 50%; background: var(--ink-dim); }
.sync-pill[data-state="synced"] .sync-dot { background: var(--good); }
.sync-pill[data-state="syncing"] .sync-dot { background: #e8a33d; }
.sync-pill[data-state="offline"] .sync-dot { background: var(--bad); }

/* ---------- layout ---------- */
.layout {
  display: grid; gap: clamp(.9rem, 2vw, 1.6rem);
  grid-template-columns: minmax(0, 1fr) 22rem;
  align-items: start;
  max-width: 66rem; margin: 0 auto; padding: clamp(.8rem, 2vw, 1.4rem);
}
@media (max-width: 900px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- board ---------- */
.board-wrap { position: relative; }
.board {
  display: grid; grid-template-columns: repeat(8, 1fr);
  aspect-ratio: 1; width: 100%;
  border-radius: 6px; overflow: hidden; box-shadow: var(--shadow);
}
.sq {
  position: relative; border: 0; padding: 0; margin: 0; cursor: pointer;
  display: block; background: var(--light-sq);
}
.sq.dark { background: var(--dark-sq); }
.sq.hl { background: var(--hl-light); }
.sq.dark.hl { background: var(--hl-dark); }
.sq piece, .sq .piece {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; pointer-events: none;
}
/* The selection ring sits above the piece so a selected piece still reads. */
.sq.sel::after {
  content: ""; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 4px var(--sel-ring); pointer-events: none;
}
/* chess.com's move hints: a dot on an empty square, a ring around a capture. */
.sq.move::before {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 30%; height: 30%; border-radius: 50%;
  background: var(--hint-dot); pointer-events: none;
}
.sq.move.take::before {
  width: 100%; height: 100%; border-radius: 50%; background: none;
  box-shadow: inset 0 0 0 .32em var(--hint-dot);
}
/* Check glows; mate burns. They looked identical before, which made every
   material puzzle that ended in check look like a mate the app had missed. */
.sq.check { background: radial-gradient(circle, #ff8a7a 0%, #e8564a 30%, rgba(224, 47, 34, 0) 70%); }
.sq.check.mate { background: radial-gradient(circle, #ff4b3e 0%, #b81d12 46%, rgba(150, 20, 12, .35) 100%); }
.sq.wrong { animation: shake .34s; }
.sq.wrong::after {
  content: ""; position: absolute; inset: 0; background: var(--bad-soft);
  box-shadow: inset 0 0 0 4px var(--bad); pointer-events: none;
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6%); }
  50% { transform: translateX(6%); }
  80% { transform: translateX(-3%); }
}
@media (prefers-reduced-motion: reduce) {
  .sq.wrong { animation: none; }
}
/* Coordinates, printed in the square's opposite colour like chess.com. */
.sq .coord {
  position: absolute; font-size: clamp(.5rem, 1.5vw, .68rem); font-weight: 700;
  line-height: 1; pointer-events: none; color: var(--dark-sq);
}
.sq.dark .coord { color: var(--light-sq); }
.sq .coord.file { right: .18em; bottom: .12em; }
.sq .coord.rank { left: .18em; top: .12em; }

.player {
  display: flex; align-items: center; gap: .5rem;
  padding: .4rem .2rem; font-weight: 600; color: var(--ink-soft); font-size: .92rem;
}
.player-dot {
  width: .95rem; height: .95rem; border-radius: 50%;
  background: #fff; border: 1px solid var(--line); box-shadow: 0 0 0 1px rgba(0,0,0,.25);
}
.player[data-side="b"] .player-dot { background: #403d39; }
.player.to-move { color: var(--ink); }
.player.to-move .player-name::after {
  content: "to play"; margin-left: .4rem; font-weight: 500; color: var(--accent);
}

/* ---------- promotion picker ---------- */
.promo {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(0, 0, 0, .55); z-index: 5;
}
.promo-card {
  display: flex; gap: .4rem; padding: .55rem;
  background: var(--panel); border-radius: var(--r); box-shadow: var(--shadow);
}
.promo-card button {
  width: 3.6rem; height: 3.6rem; border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel-2); cursor: pointer; padding: .25rem;
}
.promo-card button:hover { background: var(--accent); }
.promo-card svg { width: 100%; height: 100%; display: block; }

/* ---------- side column ---------- */
.col-side { display: grid; gap: clamp(.7rem, 1.6vw, 1rem); }
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: .9rem 1rem; box-shadow: var(--shadow);
}
.panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; margin-bottom: .6rem; }
.panel-title { font-size: .8rem; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-soft); }
.panel-note { font-size: .8rem; color: var(--ink-dim); }

.prompt-head { display: flex; align-items: center; gap: .5rem; margin-bottom: .45rem; }
.tier-chip {
  font-size: .7rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  background: var(--accent); color: var(--accent-ink); padding: .22rem .5rem; border-radius: 4px;
}
.rating-chip {
  font-size: .8rem; font-weight: 700; color: var(--ink-soft);
  background: var(--panel-2); border: 1px solid var(--line);
  padding: .2rem .55rem; border-radius: 999px; margin-left: auto;
}
.prompt { font-size: 1.35rem; font-weight: 800; letter-spacing: -.02em; }
.goal { margin: .15rem 0 .5rem; font-size: 1rem; font-weight: 600; color: var(--accent); }
.status { margin: 0; font-size: .88rem; color: var(--ink-soft); min-height: 1.35rem; }
.status.bad { color: var(--bad); }
.status.good { color: var(--good); }

.verdict {
  display: flex; align-items: center; gap: .5rem; margin-top: .6rem;
  padding: .5rem .65rem; border-radius: 6px; font-weight: 700;
  background: var(--panel-2);
}
.verdict[data-state="good"] { color: var(--good); }
.verdict[data-state="bad"] { color: var(--bad); }
.verdict-icon { width: 1.3rem; height: 1.3rem; display: grid; place-items: center; flex: none; }
.verdict-icon svg { width: 100%; height: 100%; fill: currentColor; display: block; }

/* ---------- tools ---------- */
.tools { display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem; }
.tool {
  display: grid; gap: .25rem; justify-items: center; min-height: 3.6rem;
  padding: .5rem .25rem; cursor: pointer;
  background: var(--panel); color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: var(--r);
}
.tool:hover:not(:disabled) { color: var(--ink); border-color: var(--accent); }
.tool[aria-pressed="true"] { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
.tool:disabled { opacity: .42; cursor: default; }
.tool-ico { width: 1.35rem; height: 1.35rem; }
.tool-ico svg { width: 100%; height: 100%; fill: currentColor; display: block; }
.tool-label { font-size: .72rem; font-weight: 700; }

/* ---------- picker ---------- */
.tier-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: .3rem; margin-bottom: .65rem; }
.tier-tab {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--ink-soft);
  border-radius: 6px; padding: .38rem .2rem; cursor: pointer;
  font-size: .7rem; font-weight: 800; letter-spacing: .03em; text-transform: uppercase;
}
.tier-tab[aria-selected="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.grid-picker { display: grid; grid-template-columns: repeat(5, 1fr); gap: .3rem; }
.pick {
  aspect-ratio: 1; border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel-2); color: var(--ink-soft);
  font-size: .8rem; font-weight: 700; cursor: pointer; position: relative;
}
.pick:hover { color: var(--ink); border-color: var(--accent); }
.pick.solved { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.pick.failed { border-color: var(--bad); color: var(--bad); }
.pick.current { box-shadow: inset 0 0 0 2px var(--ink); color: var(--ink); }

/* ---------- stats and history ---------- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin-bottom: .7rem; }
.stat { display: grid; gap: .1rem; text-align: center; }
.stat-label { font-size: .62rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-dim); }
.stat strong { font-size: 1.05rem; }

.history { list-style: none; margin: 0; padding: 0; display: grid; gap: .25rem; }
.history-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
  font-size: .84rem; padding: .3rem .45rem; border-radius: 5px; background: var(--panel-2);
}
.history-main { font-weight: 600; }
.history-side { color: var(--ink-dim); font-size: .78rem; }
.history-row.miss .history-main { color: var(--bad); }

.sync-code { margin-top: .7rem; font-size: .85rem; color: var(--ink-soft); }
.sync-code summary { cursor: pointer; font-weight: 700; }
.sync-help { margin: .5rem 0; font-size: .8rem; color: var(--ink-dim); }
.sync-row { display: flex; gap: .35rem; margin-bottom: .35rem; }
.sync-row input {
  flex: 1; min-width: 0; background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px; padding: .4rem .55rem; font-size: .82rem;
}
.btn {
  border: 1px solid var(--line); background: var(--panel-2); color: var(--ink);
  border-radius: 6px; padding: .4rem .8rem; font-size: .82rem; font-weight: 700; cursor: pointer;
}
.btn:hover { border-color: var(--accent); }

.tips { margin: 0; font-size: .76rem; color: var(--ink-dim); text-align: center; }
.tips kbd {
  background: var(--panel-2); border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 4px; padding: .05rem .35rem; font: inherit; font-size: .72rem;
}

.credits {
  max-width: 66rem; margin: 0 auto; padding: 0 1.4rem 2rem;
  font-size: .74rem; color: var(--ink-dim); text-align: center;
}
.credits a { color: inherit; }

/* On a phone the board comes first and the tap targets grow. */
@media (max-width: 900px) {
  .layout { max-width: 34rem; }
  .tool { min-height: 3.2rem; }
  .pick { font-size: .85rem; }
}
