/* ==========================================================================
   puzzles.css — the Puzzle Trainer's own styles.

   Loaded AFTER the site's styles.css, which provides the brand tokens
   (--teal, --black, --radius …), the buttons, the cards, the top bar and the
   wrap. Everything here is either an addition or a deliberate override, and
   nothing in here can affect the landing page: every rule is inside .puzzles
   or a class only the trainer uses.

   Mobile-first, designed at 375px.
   ========================================================================== */

/* ---------- Board colours, kept close to the printed book ---------- */
:root {
  --board-light: #ECDAB9;     /* cm-chessboard's "default" theme, warm cream  */
  --board-dark: #C5A076;      /*                              … warm brown   */
  --marker-last: #E9C46A;     /* the opponent's last move                     */
  --marker-correct: #3FAE6B;
  --marker-wrong: #E05B4B;
}

/* --------------------------------------------------------------------------
   Page frame
   -------------------------------------------------------------------------- */

/* The landing page leaves room at the bottom for its sticky mobile CTA.
   There is no sticky CTA in the trainer, so take that space back. */
@media (max-width: 767px) {
  body.puzzles { padding-bottom: 0; }
}

.puzzles__main {
  padding-top: 28px;
  padding-bottom: 56px;
  min-height: calc(100vh - 64px);   /* never a short page with a dark gap */
}

/* ---------- Top bar additions ---------- */
.topbar__section {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--teal);
  margin-right: auto;
}
.topbar__section a { color: inherit; }
.topbar__section a:hover { text-decoration: underline; }

.topbar__user {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;                      /* lets the email truncate */
}
.user__email {
  display: none;                     /* no room for it on a phone */
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.85rem;
  color: var(--gray);
}
.user__logout {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--gray);
  padding: 8px 4px;
  min-height: 44px;                  /* a comfortable tap target */
  display: inline-flex;
  align-items: center;
}
.user__logout:hover { color: var(--teal); text-decoration: underline; }

@media (min-width: 560px) {
  .user__email { display: inline; }
}

/* --------------------------------------------------------------------------
   The shared "one card in the middle" states: loading, errors, no access,
   the login form.
   -------------------------------------------------------------------------- */
.state-card {
  background: var(--black-soft);
  border: 1px solid var(--line-dark);
  border-radius: var(--radius);
  padding: 28px 22px;
  text-align: center;
  max-width: 480px;
  margin: 24px auto;
}
.state-card__title {
  font-size: clamp(1.3rem, 5vw, 1.8rem);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.state-card__text {
  margin-top: 12px;
  color: var(--gray);
  font-size: 0.97rem;
}
.state-card__actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 22px;
}
.state-card__error {
  margin-top: 14px;
  font-size: 0.9rem;
  font-weight: 600;
  color: #FFB4A8;
}
.state-card__foot {
  margin-top: 18px;
  font-size: 0.85rem;
  color: var(--gray);
}
.state-card__foot a { color: var(--teal); text-decoration: underline; }

.state-card--form { text-align: left; }
.state-card--form .state-card__title,
.state-card--form .state-card__text { text-align: center; }

@media (min-width: 520px) {
  .state-card { padding: 34px 30px; }
  .state-card__actions { flex-direction: row; justify-content: center; }
}

/* Text field, matching the newsletter field on the landing page */
.field {
  width: 100%;
  min-height: 52px;
  margin: 18px 0 12px;
  padding: 14px 18px;
  font: inherit;
  color: var(--white);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line-dark);
  border-radius: 999px;
}
.field::placeholder { color: #9AA6A4; }
.field:focus-visible { border-color: var(--teal); }

/* Spinner */
.spinner {
  display: block;
  width: 28px;
  height: 28px;
  margin: 0 auto 16px;
  border: 3px solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--teal);
  border-radius: 999px;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-top-color: var(--teal); }
}

/* --------------------------------------------------------------------------
   Dashboard
   -------------------------------------------------------------------------- */
.dash__title {
  font-size: clamp(1.5rem, 6vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-wrap: balance;
}
.dash__sub {
  margin-top: 8px;
  color: var(--gray);
  font-size: 0.97rem;
}

.dash__grid {
  display: grid;
  gap: 16px;
  margin: 24px 0 40px;
}

.dash-card { display: flex; flex-direction: column; gap: 12px; }
.dash-card__kicker {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal);
}
.dash-card__title { font-size: 1.15rem; font-weight: 800; line-height: 1.25; }
.dash-card__text { color: var(--gray); font-size: 0.93rem; }
.dash-card__foot { color: var(--gray); font-size: 0.85rem; }

.dash-card--today { border-color: var(--teal); }
.dash-card--review { border-color: var(--marker-last); }

/* Progress bar */
.bar {
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}
.bar__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--teal);
  transition: width 0.4s ease;
}

/* The 30 day chips */
.dash-card__plan-label {
  margin-top: 6px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gray);
}
.daychips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(36px, 1fr));
  gap: 6px;
}
.daychip {
  display: grid;
  place-items: center;
  min-height: 36px;
  border-radius: 10px;
  border: 1px solid var(--line-dark);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--gray);
}
.daychip:hover { border-color: var(--teal); color: var(--white); }
.daychip--started { border-color: rgba(78, 205, 196, 0.5); color: var(--white); }
.daychip--done { background: rgba(78, 205, 196, 0.18); border-color: var(--teal); color: var(--white); }
.daychip--next {
  background: var(--teal);
  border-color: var(--teal);
  color: var(--black);
  font-weight: 800;
}

/* Stats */
.stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  text-align: center;
}
.stat { display: flex; flex-direction: column; gap: 2px; }
.stat__value { font-size: 1.3rem; font-weight: 800; line-height: 1.1; }
.stat__label { font-size: 0.75rem; color: var(--gray); }

/* Chapters */
.dash-chapters__title { font-size: clamp(1.3rem, 5vw, 1.9rem); margin-bottom: 18px; }
.cards--chapters { gap: 14px; }
.chapter { display: flex; flex-direction: column; gap: 10px; }
.chapter__number {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--teal);
}
.chapter__name { font-size: 1.05rem; font-weight: 800; line-height: 1.25; }
.chapter__meta { font-size: 0.85rem; color: var(--gray); }
.chapter__cta { margin-top: auto; align-self: flex-start; }

@media (min-width: 700px) {
  .dash__grid { grid-template-columns: repeat(2, 1fr); align-items: start; }
  .dash-card--today { grid-column: 1 / -1; }
  .cards--chapters { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) {
  .dash__grid { grid-template-columns: 1.4fr 1fr 1fr; }
  .dash-card--today { grid-column: 1; grid-row: 1 / span 2; }
  .cards--chapters { grid-template-columns: repeat(5, 1fr); }
}

/* --------------------------------------------------------------------------
   Solving screen
   -------------------------------------------------------------------------- */
.play { max-width: 620px; }

.play__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.play__back { font-size: 0.88rem; font-weight: 600; color: var(--gray); }
.play__back:hover { color: var(--teal); }
.play__count { font-size: 0.85rem; font-weight: 600; color: var(--gray); }

.play__crumb {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--teal);
}
.play__title {
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.3;
  margin: 4px 0 14px;
}

/* The board itself. cm-chessboard fills the width of this element. */
.play__board {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  border-radius: var(--radius-sm);
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  /* Keeps the page from jumping while the board is being built. */
  aspect-ratio: 1;
}
/* Once the board's SVG is in, let it decide the height itself. */
.play__board:has(svg) { aspect-ratio: auto; }

/* styles.css resets every svg to `height: auto` so the site's icons scale.
   The board is the one exception: cm-chessboard gives its svg width and
   height of 100% and sizes the box around it, and `auto` collapses it to the
   browser's default 150px. Without this rule the board is a thin strip. */
.play__board svg.cm-chessboard { width: 100%; height: 100%; }

.play__status {
  min-height: 3em;                    /* the layout must not jump on feedback */
  margin: 14px auto 0;
  max-width: 480px;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--gray);
  text-align: center;
}
.play__status--correct { color: #8FE3B4; }
.play__status--wrong { color: #FFB4A8; }
.play__status--hint { color: var(--teal); }

.play__actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 4px;
}
.play__actions .btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* Result panel */
.play__result {
  margin-top: 24px;
  background: var(--black-soft);
  border: 1px solid var(--line-dark);
  border-radius: var(--radius);
  padding: 20px;
}
.play__result-title { font-size: 1.1rem; font-weight: 800; }
.play__line {
  margin-top: 10px;
  font-weight: 700;
  font-size: 1rem;
  color: var(--teal);
  /* A chess line reads better with even spacing. */
  font-variant-numeric: tabular-nums;
}
.play__explanation { margin-top: 10px; color: var(--gray); font-size: 0.95rem; }
.play__result-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 18px;
}
.play__keyhint {
  margin-top: 14px;
  font-size: 0.8rem;
  color: #9AA6A4;
  text-align: center;
}

@media (min-width: 560px) {
  .play__title { font-size: 1.15rem; }
  .play__result-actions { flex-direction: row; flex-wrap: wrap; }
  .play__result-actions .btn { flex: 1 1 auto; }
}

/* --------------------------------------------------------------------------
   cm-chessboard overrides

   The library's own stylesheets are loaded from the CDN in play/index.html;
   these rules restyle the markers and arrows in the site's colours. The
   square colours come from the library's "default" theme, which is already
   the warm cream/brown of the book.
   -------------------------------------------------------------------------- */

/* The opponent's last move: a soft warm highlight on both squares. */
.cm-chessboard .markers .marker.hc-marker-last {
  fill: var(--marker-last);
  opacity: 0.42;
}

/* A correct move. */
.cm-chessboard .markers .marker.hc-marker-correct {
  stroke: var(--marker-correct);
  stroke-width: 2.4px;
  opacity: 0.95;
}

/* A wrong move. */
.cm-chessboard .markers .marker.hc-marker-wrong {
  stroke: var(--marker-wrong);
  stroke-width: 2.6px;
  opacity: 0.95;
}

/* Hint level 3: the piece that moves. */
.cm-chessboard .markers .marker.hc-marker-hint {
  stroke: var(--teal);
  stroke-width: 3px;
  opacity: 0.9;
}

/* The arrows drawn by "Show solution". */
.cm-chessboard .hc-arrow-solution .arrow-head { fill: var(--teal); fill-rule: nonzero; }
.cm-chessboard .hc-arrow-solution .arrow-line { stroke: var(--teal); stroke-linecap: round; opacity: 0.75; }

/* The board's frame border, tuned to sit on the dark page. */
.cm-chessboard.default.border-type-frame .board .border { fill: #B08A63; }
.cm-chessboard.default .coordinates .coordinate { font-weight: 600; }

/* The promotion dialog. The library draws it as a translucent white panel
   inside the board's SVG; this gives it the site's dark card look so it reads
   as part of the trainer. */
svg.cm-chessboard .promotion-dialog-group .promotion-dialog {
  fill: #12100E;
  fill-opacity: 0.94;
  stroke: var(--teal);
  stroke-width: 1.5px;
}
svg.cm-chessboard .promotion-dialog-group .promotion-dialog-button:hover {
  fill: rgba(78, 205, 196, 0.28);
}
svg.cm-chessboard .promotion-dialog-group .promotion-dialog-button-group:focus .promotion-dialog-button {
  fill: rgba(78, 205, 196, 0.2);
  stroke: var(--teal);
  stroke-width: 1.5px;
}
