/* The Digital Chessboard — parent & coach portal
   ------------------------------------------------------------------
   Same brand as thedigitalchessboard.com: navy, gold, ivory, with
   Playfair Display for identity and Inter for everything operational.

   The marketing site is read; this is used. So gold appears only where
   it carries meaning — a status, a focus — never as decoration, and the
   surfaces stay quiet so the numbers can be the loud thing.
   ------------------------------------------------------------------ */

:root {
  /* Brand, carried over from the site */
  --navy-900:#0B1E3D; --navy-800:#102649; --navy-700:#16315C;
  --gold-500:#D4AF37; --gold-600:#C9A24B; --gold-text:#7E5F10;

  /* Surfaces */
  --ground:#F5F3ED;
  --surface:#FFFFFF;
  --sunk:#EDE9DF;
  --line:#E2DCCD;
  --line-soft:#EEE9DD;

  /* Text */
  --ink:#0B1E3D;
  --body:#4A5468;
  --muted:#6B7488;

  --accent:#7E5F10;
  --accent-line:#D4AF37;

  /* Status. Semantic, and deliberately not the accent hue. */
  --good:#1C6E3C;   --good-bg:#E6F0E8;
  --watch:#8A5A08;  --watch-bg:#F8EDD8;
  --ended:#8C3A2A;  --ended-bg:#F8E7E2;

  --shadow-sm:0 1px 2px rgba(11,30,61,.05);
  --shadow:0 1px 2px rgba(11,30,61,.05), 0 12px 28px -18px rgba(11,30,61,.28);
  --radius:10px;
  --radius-sm:6px;

  --serif:"Playfair Display","Cormorant Garamond",Georgia,serif;
  --sans:"Inter","Manrope",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground:#091423; --surface:#0F2138; --sunk:#152B47;
    --line:#213A57; --line-soft:#182E49;
    --ink:#EAEFF7; --body:#AEBBD0; --muted:#8496AF;
    --accent:#D4AF37; --accent-line:#8A6F22;
    --good:#6FC98C;  --good-bg:#10301F;
    --watch:#E5B65A; --watch-bg:#33260A;
    --ended:#F0907A; --ended-bg:#3A1B14;
    --shadow-sm:0 1px 2px rgba(0,0,0,.4);
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 30px -20px rgba(0,0,0,.85);
  }
}
:root[data-theme="dark"] {
  --ground:#091423; --surface:#0F2138; --sunk:#152B47;
  --line:#213A57; --line-soft:#182E49;
  --ink:#EAEFF7; --body:#AEBBD0; --muted:#8496AF;
  --accent:#D4AF37; --accent-line:#8A6F22;
  --good:#6FC98C;  --good-bg:#10301F;
  --watch:#E5B65A; --watch-bg:#33260A;
  --ended:#F0907A; --ended-bg:#3A1B14;
  --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 30px -20px rgba(0,0,0,.85);
}

*,*::before,*::after { box-sizing:border-box; }

/* A [hidden] element must win regardless of what else styles it. The browser's
   own [hidden] rule and an author rule like .btn's `display:inline-flex` sit
   at the SAME specificity (one attribute selector, one class selector), and
   the author rule comes later in the cascade — so without this, a "hidden"
   button stays visible the moment it also carries a class that sets display.
   Found via the Set Up screen's Remove-photo button silently failing to hide. */
[hidden] { display:none !important; }
html { -webkit-text-size-adjust:100%; }
body {
  margin:0;
  background:var(--ground);
  color:var(--body);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3 { font-family:var(--serif); color:var(--ink); font-weight:600;
           line-height:1.14; letter-spacing:-.01em; margin:0; text-wrap:balance; }
p { margin:0; }
a { color:var(--accent); }
button { font:inherit; cursor:pointer; }

:focus-visible {
  outline:2px solid var(--accent-line);
  outline-offset:2px;
  border-radius:3px;
}

.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ---------------------------------------------------- layout ---- */
.shell { min-height:100dvh; display:flex; }
.wrap { width:100%; max-width:960px; margin:0 auto; padding:0 20px; }

/* The six sections live here, always visible, so a parent can see what is
   in the portal without first knowing to look for it. */
.side {
  width:222px; flex:none; background:var(--navy-900);
  padding:22px 12px; position:sticky; top:0; height:100dvh; overflow-y:auto;
  display:flex; flex-direction:column;
}
.side .brand { padding:4px 8px 22px; align-items:flex-start; }

.brand { display:flex; flex-direction:column; line-height:1; }
.brand__sub {
  font-size:.54rem; letter-spacing:.24em; text-transform:uppercase;
  color:var(--gold-500); margin-top:.5rem; font-weight:500;
}
.brand--light .brand__sub { color:var(--accent); }

/* The academy's wordmark is supplied as black artwork on transparency. On the
   navy rail it is inverted to white rather than shipping a second file, so
   there is only ever one logo to keep up to date. */
.brand__logo {
  width:100%; max-width:150px; height:auto; display:block;
  filter:brightness(0) invert(1);
}
.brand--light .brand__logo { filter:none; max-width:132px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand--light .brand__logo { filter:brightness(0) invert(1); }
}
:root[data-theme="dark"] .brand--light .brand__logo { filter:brightness(0) invert(1); }

.nav { display:flex; flex-direction:column; gap:2px; }
.nav__item {
  display:flex; align-items:center; gap:11px; width:100%;
  padding:10px 12px; border-radius:8px; font-size:.86rem; font-weight:500;
  color:#B7C2D6; background:none; border:0; text-align:left;
}
.nav__item:hover { background:rgba(255,255,255,.07); color:#fff; }
.nav__item[aria-current="page"] { background:var(--gold-500); color:var(--navy-900); font-weight:600; }
.nav__item svg { width:18px; height:18px; flex:none; stroke-width:1.9; }

.content { flex:1; min-width:0; display:flex; flex-direction:column; }

.topbar {
  background:var(--ground);
  border-bottom:1px solid var(--line);
  position:sticky; top:0; z-index:20;
}
.topbar__inner { display:flex; align-items:center; justify-content:flex-end; gap:16px; height:56px; }
.topbar__actions { display:flex; align-items:center; gap:14px; }
.topbar__link {
  color:var(--body); background:none; border:0; padding:8px 4px;
  font-size:.86rem; text-decoration:none;
}
.topbar__link:hover { color:var(--ink); }

main { flex:1; padding:28px 0 96px; }

/* ------------------------------------------------- page head ---- */
.pagehead { margin-bottom:24px; }
.pagehead__eyebrow {
  font-size:.68rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted); font-weight:600; margin-bottom:8px;
}
.pagehead h1 { font-size:clamp(1.6rem,4.4vw,2.1rem); }
.pagehead__meta { margin-top:6px; color:var(--muted); font-size:.92rem; }

/* ----------------------------------------------------- cards ---- */
.card {
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--radius);
  box-shadow:var(--shadow-sm);
}
.card__head {
  display:flex; align-items:baseline; gap:12px;
  padding:16px 20px 0;
}
.card__title {
  font-family:var(--sans); font-size:.72rem; font-weight:600;
  letter-spacing:.13em; text-transform:uppercase; color:var(--muted);
}
.card__body { padding:16px 20px 20px; }

.grid { display:grid; gap:16px; }
/* Grid items default to min-width:auto, so a long unbreakable string — the UPI
   ID, as it turned out — pushes its track wider than the viewport and the whole
   page scrolls sideways. min-width:0 lets the track shrink and the content wrap. */
.grid > * { min-width:0; }
@media (min-width:720px) { .grid--2 { grid-template-columns:1fr 1fr; } }

/* --------------------------------------------- status banner ---- */
.status {
  display:flex; flex-wrap:wrap; align-items:center; gap:10px 16px;
  padding:14px 20px; border-radius:var(--radius);
  border:1px solid var(--line); background:var(--surface);
  box-shadow:var(--shadow-sm);
}
.status--good  { border-left:3px solid var(--good); }
.status--watch { border-left:3px solid var(--watch); }
.status--ended { border-left:3px solid var(--ended); }
.status__label { font-weight:600; color:var(--ink); }
.status__detail { color:var(--muted); font-size:.93rem; }
.status__action { margin-left:auto; }

.pill {
  display:inline-block; font-size:.7rem; font-weight:600;
  letter-spacing:.07em; text-transform:uppercase;
  padding:4px 9px; border-radius:100px;
}
.pill--good  { background:var(--good-bg);  color:var(--good); }
.pill--watch { background:var(--watch-bg); color:var(--watch); }
.pill--ended { background:var(--ended-bg); color:var(--ended); }

/* ------------------------------------------------ fact lists ---- */
.facts { display:grid; gap:0; }
.fact {
  display:flex; align-items:baseline; gap:16px;
  padding:11px 0; border-bottom:1px solid var(--line-soft);
}
.fact:last-child { border-bottom:0; }
.fact__key {
  flex:none; width:110px; color:var(--muted);
  font-size:.82rem; letter-spacing:.02em;
}
.fact__val { color:var(--ink); font-weight:500; }
.fact__val small { display:block; color:var(--muted); font-weight:400; font-size:.85rem; }

/* --------------------------------------------------- numbers ---- */
.figure { display:flex; flex-direction:column; gap:2px; }
.figure__num {
  font-family:var(--serif); font-size:2.4rem; line-height:1;
  color:var(--ink); font-weight:600; font-variant-numeric:tabular-nums;
}
.figure__num sup { font-size:.9rem; font-family:var(--sans); font-weight:500;
                   color:var(--muted); margin-left:3px; vertical-align:super; }
.figure__cap { font-size:.82rem; color:var(--muted); }

/* --------------------------------------------------- buttons ---- */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:11px 20px; border-radius:var(--radius-sm);
  border:1px solid transparent; font-size:.94rem; font-weight:600;
  text-decoration:none; white-space:nowrap;
}
.btn--primary { background:var(--navy-900); color:#fff; }
.btn--primary:hover { background:var(--navy-700); }
.btn--gold { background:var(--gold-500); color:var(--navy-900); }
.btn--gold:hover { background:var(--gold-600); }
.btn--quiet {
  background:transparent; color:var(--ink); border-color:var(--line);
}
.btn--quiet:hover { background:var(--sunk); }
.btn--block { width:100%; }
.btn[disabled] { opacity:.55; cursor:not-allowed; }

/* ----------------------------------------------------- forms ---- */
.field { display:flex; flex-direction:column; gap:6px; margin-bottom:16px; }
.field label { font-size:.86rem; font-weight:500; color:var(--ink); }
.field input {
  font:inherit; padding:11px 13px; border-radius:var(--radius-sm);
  border:1px solid var(--line); background:var(--surface); color:var(--ink);
}
.field input:focus-visible { border-color:var(--accent-line); }
.field__hint { font-size:.82rem; color:var(--muted); }

.notice {
  padding:12px 15px; border-radius:var(--radius-sm); font-size:.92rem;
  border:1px solid var(--line); background:var(--sunk); color:var(--ink);
}
.notice--error { background:var(--ended-bg); border-color:transparent; color:var(--ended); }
.notice--good  { background:var(--good-bg);  border-color:transparent; color:var(--good); }

/* ------------------------------------------------ auth screen ---- */
/* Sign-in, forgot-password and set-password are always rendered in the
   light theme, regardless of the device's own dark-mode setting — this is
   the brand's first impression, and the background art is a light,
   cream-toned collage that only works against light surfaces. Everything a
   parent sees AFTER signing in still respects their system theme as before;
   this override is scoped to .auth alone. Re-declaring the tokens here is
   enough: they are custom properties, so anything inside .auth that reads
   var(--ink) etc. picks up these values regardless of what :root set. */
.auth {
  --ground:#F5F3ED; --surface:#FFFFFF; --sunk:#EDE9DF;
  --line:#E2DCCD; --line-soft:#EEE9DD;
  --ink:#0B1E3D; --body:#4A5468; --muted:#6B7488;
  --accent:#7E5F10; --accent-line:#D4AF37;
  --shadow-sm:0 1px 2px rgba(11,30,61,.05);
  --shadow:0 1px 2px rgba(11,30,61,.05), 0 12px 28px -18px rgba(11,30,61,.28);

  min-height:100dvh; display:grid; place-items:center; padding:24px;
  background:var(--ground) url('/assets/login.png') center/cover no-repeat;
}
/* A phone screen is portrait, not a cropped slice of the desktop landscape
   composition — the supplied art has its own portrait layout for this.
   contain, not cover: the art is proportionally wider than a typical phone
   screen, so cover crops both edges and clips the hand-lettered captions
   sitting there. The image's own background is the same cream tone as
   --ground, so the letterboxed strip this leaves top and bottom reads as a
   continuation of the art rather than a visible seam. */
@media (max-width:640px) {
  .auth { background:var(--ground) url('/assets/login-ph.png') center/contain no-repeat; }
}
.auth__card { width:100%; max-width:400px; }
.auth__brand { text-align:center; margin-bottom:26px; }
.auth__brand .brand__sub { color:var(--accent); display:block; margin-top:8px; }
/* Black artwork — no invert needed, this screen is never dark now. */
.auth__logo { width:100%; max-width:230px; height:auto; margin:0 auto; display:block; }

/* ------------------------------------------------ empty state ---- */
.empty { padding:26px 20px; text-align:center; }
.empty__title { color:var(--ink); font-weight:600; margin-bottom:5px; }
.empty__body { color:var(--muted); font-size:.91rem; max-width:44ch; margin:0 auto; }

/* --------------------------------------------------- loading ---- */
.skeleton {
  background:var(--sunk); border-radius:var(--radius-sm);
  height:1em; animation:pulse 1.4s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity:1 } 50% { opacity:.55 } }
@media (prefers-reduced-motion:reduce) {
  .skeleton { animation:none; }
  * { transition:none !important; }
}

/* -------------------------------------------------- renewal ---- */
.renewal__amount {
  font-family:var(--serif); font-size:3rem; line-height:1;
  color:var(--ink); font-weight:700; font-variant-numeric:tabular-nums;
}
.qr {
  display:block; width:100%; max-width:260px; height:auto; margin:0 auto;
  border:1px solid var(--line); border-radius:var(--radius); background:#fff;
}
.upi {
  font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size:.95rem; background:var(--sunk); color:var(--ink);
  padding:9px 13px; border-radius:var(--radius-sm);
  display:flex; align-items:center; gap:10px; justify-content:space-between;
}
/* An address with no spaces in it still has to fit a 360px phone. */
.upi > span { overflow-wrap:anywhere; min-width:0; }
.upi > button { flex:none; }
.steps { counter-reset:step; list-style:none; padding:0; margin:0; }
.steps li {
  counter-increment:step; position:relative; padding:0 0 0 34px;
  margin-bottom:11px; font-size:.94rem;
}
.steps li::before {
  content:counter(step);
  position:absolute; left:0; top:1px;
  width:22px; height:22px; border-radius:50%;
  background:var(--sunk); color:var(--ink);
  font-size:.74rem; font-weight:600;
  display:grid; place-items:center;
}

/* ----------------------------------------------- child switch ---- */
.children { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:20px; }
.children__btn {
  padding:7px 14px; border-radius:100px; font-size:.88rem; font-weight:500;
  border:1px solid var(--line); background:var(--surface); color:var(--body);
}
.children__btn[aria-current="true"] {
  background:var(--navy-900); border-color:var(--navy-900); color:#fff;
}

@media (max-width:720px) {
  .shell { flex-direction:column; }
  /* .side becomes just the logo strip — .nav is pulled out of its normal
     flow by position:fixed below, so it no longer takes up room here. */
  .side {
    width:auto; height:auto; position:static;
    padding:10px 16px; flex-direction:row; align-items:center;
  }
  .side .brand { padding:0; flex:none; }

  /* The six sections move to a fixed bottom tab bar — reachable with a
     thumb, and it frees the top into one slim strip for the logo instead of
     cramming icons in beside it. main's existing bottom padding (96px) was
     already generous enough to clear a bar this size without changing it. */
  .nav {
    position:fixed; left:0; right:0; bottom:0; z-index:30;
    flex-direction:row; justify-content:space-around;
    background:var(--navy-900); gap:0;
    padding:6px 4px calc(6px + env(safe-area-inset-bottom));
    border-top:1px solid rgba(255,255,255,.08);
  }
  .nav__item {
    flex-direction:column; gap:3px; flex:1; min-width:0;
    padding:6px 2px; border-radius:6px; font-size:.62rem;
  }
  .nav__item span { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
}

@media (max-width:520px) {
  .wrap { padding:0 16px; }
  .fact { flex-direction:column; gap:2px; }
  .fact__key { width:auto; }
  .status__action { margin-left:0; width:100%; }
  .status__action .btn { width:100%; }
}

/* ================================================================
   Components carried over from the approved design (the TDC Parent
   Portal preview). Token names are the design's own, mapped onto this
   stylesheet's palette where they mean the same thing, so both
   vocabularies work while the screens are migrated one at a time.
   ================================================================ */
:root {
  --card:var(--surface);
  --page:var(--ground);
  --r:var(--radius);
  --r-sm:var(--radius-sm);
  --blue:#1D6FE8; --blue-bg:#EAF2FE; --blue-dark:#1559C0;
  --green:var(--good); --green-bg:var(--good-bg);
  --amber:var(--watch); --amber-bg:var(--watch-bg);
  --violet:#6D4AC4; --violet-bg:#F0EBFB;
  --wa:#1EA85C;

  /* One step deeper than the -bg tints, for a chip that has to read as a chip
     while sitting on a tile already painted in its own colour. */
  --blue-tint:#D7E6FD; --green-tint:#D4E4D9;
  --amber-tint:#F1E1C0; --violet-tint:#E2D8F6;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --blue:#5A9AF5; --blue-bg:#152540; --blue-dark:#4285DD;
    --violet:#A98FE8; --violet-bg:#231C3B;
    --blue-tint:#1E3459; --green-tint:#17452B;
    --amber-tint:#453317; --violet-tint:#312751;
  }
}
:root[data-theme="dark"] {
  --blue:#5A9AF5; --blue-bg:#152540; --blue-dark:#4285DD;
  --violet:#A98FE8; --violet-bg:#231C3B;
  --blue-tint:#1E3459; --green-tint:#17452B;
  --amber-tint:#453317; --violet-tint:#312751;
}

.card__hd { display:flex; align-items:center; gap:10px; padding:18px 22px 0; }
.card__hd h3 { font-size:.97rem; margin:0; color:var(--ink); font-weight:600; }
.card__pad { padding:20px 22px; }

.g2, .g3 { display:grid; gap:16px; grid-template-columns:1fr; }
@media (min-width:760px) { .g2 { grid-template-columns:1fr 1fr; } }
@media (min-width:1040px) { .g3 { grid-template-columns:repeat(3,1fr); } }

.pill--green  { background:var(--green-bg);  color:var(--green); }
.pill--blue   { background:var(--blue-bg);   color:var(--blue); }
.pill--amber  { background:var(--amber-bg);  color:var(--amber); }
.pill--violet { background:var(--violet-bg); color:var(--violet); }

.btn--pri { background:var(--blue); color:#fff; border-color:var(--blue); }
.btn--pri:hover { background:var(--blue-dark); border-color:var(--blue-dark); }
.btn--out { border:1px solid var(--line); color:var(--blue); background:var(--card); }
.btn--out:hover { background:var(--blue-bg); }
.btn--wa { background:var(--wa); color:#fff; width:100%; padding:13px; }
.btn--wa:hover { filter:brightness(.94); }
.btn--sm { padding:6px 12px; font-size:.75rem; }

.banner {
  display:flex; gap:12px; align-items:flex-start; background:var(--blue-bg);
  border:1px solid transparent; border-radius:var(--r); padding:13px 16px;
  font-size:.82rem; color:var(--ink);
}
.banner__ico { color:var(--blue); flex:none; margin-top:1px; font-size:1rem; }

/* Segmented control — Bundles / Individual, Daily puzzle / Analyse. */
.tabs { display:inline-flex; gap:3px; background:var(--line-soft); padding:3px; border-radius:9px; }
.tab {
  padding:6px 14px; border-radius:7px; font-size:.79rem; font-weight:500;
  color:var(--muted); background:none; border:0;
}
.tab[aria-selected="true"] { background:var(--card); color:var(--ink); font-weight:600; box-shadow:var(--shadow-sm); }

/* -------------------------------------------------- dashboard ------ */
/* The design's greeting sub-classes, added beside the originals so a
   rewritten screen and an un-migrated one can both render. */
.hello__pc { font-size:1.7rem; line-height:1; opacity:.9; flex:none; }
.hello__t { font-size:1.06rem; font-weight:600; letter-spacing:-.01em; }
.hello__s { font-size:.78rem; color:#B9C8DC; margin-top:3px; }

.setup-nudge__b { flex:1; min-width:0; }
.setup-nudge__t { display:block; font-size:.84rem; font-weight:600; color:var(--ink); }
.setup-nudge__s { display:block; font-size:.75rem; color:var(--body); margin-top:1px; }

/* The renewal warning is its own amber (or red, when overdue) call to action,
   shown only inside the last week — a banner that never turns off is wallpaper. */
.renew-warn {
  display:flex; align-items:center; gap:13px; width:100%; text-align:left;
  border-radius:var(--r); padding:14px 18px; font:inherit; cursor:pointer;
  background:var(--amber-bg); border:1px solid rgba(178,106,0,.30);
}
.renew-warn:hover { border-color:var(--amber); }
.renew-warn--over { background:var(--ended-bg); border-color:rgba(140,58,42,.32); }
.renew-warn__ico { font-size:1.15rem; flex:none; }
.renew-warn__b { flex:1; min-width:0; }
.renew-warn__t { display:block; font-size:.84rem; font-weight:600; color:var(--ink); }
.renew-warn__s { display:block; font-size:.75rem; color:var(--body); margin-top:1px; }
.renew-warn__go { font-size:.78rem; font-weight:600; color:var(--amber); flex:none; }
.renew-warn--over .renew-warn__go { color:var(--ended); }

/* The student card: avatar, name, id, then a facts strip that pushes right. */
.stu { display:flex; flex-wrap:wrap; align-items:center; gap:18px; }
.stu__nm { font-size:1.3rem; font-weight:700; color:var(--ink); line-height:1.15; }
.stu__id { font-size:.78rem; color:var(--muted); margin-top:2px; }
.facts { display:flex; flex-wrap:wrap; gap:22px; margin-left:auto; align-items:center; }
.fact__k { font-size:.69rem; color:var(--muted); font-weight:500; display:flex; align-items:center; gap:5px; }
.fact__v { font-size:.87rem; font-weight:600; color:var(--ink); margin-top:2px; }
.fact__s { font-size:.69rem; color:var(--muted); }
.days { background:var(--amber-bg); border-radius:var(--r-sm); padding:11px 18px; text-align:center; min-width:110px; }
.days__k { font-size:.69rem; color:var(--amber); font-weight:600; display:flex; align-items:center; gap:5px; justify-content:center; }
.days__v { font-size:1.6rem; font-weight:700; color:var(--amber); line-height:1.1; margin-top:2px; }
.days__u { font-size:.69rem; color:var(--amber); }
.days--ok { background:var(--good-bg); } .days--ok .days__k, .days--ok .days__v, .days--ok .days__u { color:var(--good); }
.days--over { background:var(--ended-bg); } .days--over .days__k, .days--over .days__v, .days--over .days__u { color:var(--ended); }

/* Enrollment status, split into columns that stack on a phone. */
.split { display:grid; gap:14px; grid-template-columns:1fr; }
@media (min-width:640px) { .split { grid-template-columns:repeat(3,1fr); } }

/* At-a-glance tiles. */
/* The tile keeps its own padding so nothing sits on the edge of the box, and
   an illustration sits in the corner behind the figure. The art is decoration
   for a number that is already spelled out beside it, so it is hidden from
   screen readers and never carries meaning of its own. */
.tile { display:flex; flex-direction:column; min-width:0; }
/* Everything the illustration needs is scoped away from `.card.tile`, which is
   the coach portal's batch button — a different thing wearing the same name.
   It gets no containment, no minimum height and no padding it never asked for. */
.tile:not(.card) {
  position:relative; overflow:hidden; container-type:inline-size;
  padding:15px 16px 16px; border-radius:var(--r); border:1px solid var(--line-soft);
  min-height:158px;
}
/* Lifts the figures above the artwork. The artwork is excluded by name rather
   than left to the cascade: this selector outranks `.tile__art`, so catching
   it here would put its `position:absolute` back to `relative` and drop it
   into the flow. */
.tile:not(.card) > :not(.tile__art) { position:relative; z-index:1; }
/* Sized as a share of the tile, and fitted into that box rather than stretched
   to it: the illustrations run from a squat stack of books to a rook half
   again as tall as it is wide, and sizing them by width alone let the tall
   ones grow until they swallowed the tile.

   Hidden by default and switched on by tile width, not viewport width — the
   sidebar takes 222px, so four columns can be 107px each on an 800px screen,
   nowhere near enough to carry a picture as well as a figure. A browser too
   old for container queries keeps the numbers and loses the decoration, which
   is the right way round. */
.tile__art {
  display:none; position:absolute; z-index:0;
  object-fit:contain; object-position:100% 100%;
  pointer-events:none; user-select:none;
}

/* The widths below are the tile's CONTENT box, which is 32px narrower than the
   tile itself — 110px here means a tile of about 142px.

   Two across on a phone is 148px, and at that width there is no room for a
   picture beside the figures: it lands on the chip. So it goes in the gap next
   to the icon instead, where every tile has space going spare. */
@container (min-width:110px) {
  .tile__art { display:block; right:10px; top:9px; width:38%; height:46px; }
}

/* Anything roomier takes the design as drawn — the illustration beside the
   figures, with the wording held clear of it. The rating tile is exempt: its
   curve is a backdrop the figures are meant to sit on. */
@container (min-width:150px) {
  .tile__art { right:10px; top:auto; bottom:10px; width:42%; height:58%; }
  .tile:not(.tile--band) .tile__k { padding-right:44%; }
  .tile:not(.tile--band) .tile__s { max-width:58%; }
}

/* The rating curve is a band rather than an object, so it spans the tile at
   every width. Last, so it outranks the two blocks above. */
.tile__art--wide {
  right:0; left:0; top:auto; bottom:0; width:100%; height:47%;
  object-position:50% 100%; opacity:.85;
}
.tile__ico { width:34px; height:34px; border-radius:9px; background:var(--card); display:grid; place-items:center; margin-bottom:12px; flex:none; }
.tile__v { font-size:1.5rem; font-weight:700; color:var(--ink); line-height:1.15; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }
.tile__k { font-size:.79rem; color:var(--body); font-weight:600; margin-top:4px; line-height:1.3; }
.tile__s {
  align-self:flex-start; margin-top:7px; padding:3px 9px; border-radius:100px;
  font-size:.68rem; font-weight:600; line-height:1.35; max-width:100%;
  background:var(--line-soft); color:var(--muted);
}
.tile--blue   .tile__ico { color:var(--blue); }
.tile--green  .tile__ico { color:var(--green); }
.tile--amber  .tile__ico { color:var(--amber); }
.tile--violet .tile__ico { color:var(--violet); }
.tile--blue   .tile__s { background:var(--blue-tint);   color:var(--blue-dark); }
.tile--green  .tile__s { background:var(--green-tint);  color:var(--green); }
.tile--amber  .tile__s { background:var(--amber-tint);  color:var(--amber); }
.tile--violet .tile__s { background:var(--violet-tint); color:var(--violet); }
.g4 { display:grid; gap:16px; grid-template-columns:repeat(2,1fr); }
@media (min-width:760px) { .g4 { grid-template-columns:repeat(4,1fr); } }

/* Important updates — derived rows, each linking somewhere real. */
.upd {
  display:flex; gap:12px; align-items:flex-start; padding:14px; border:1px solid var(--line);
  border-radius:var(--r); background:var(--card); width:100%; text-align:left;
}
.upd:hover { border-color:var(--accent-line); }

/* A dashboard row, which carries an illustration and needs the height to show
   it. The Progress page reuses `.upd` as a plain bordered-off list row, so all
   of that hangs off the modifier instead of the base class. */
.upd--art { position:relative; overflow:hidden; min-height:104px; container-type:inline-size; }
.upd--art > :not(.upd__art) { position:relative; z-index:1; }
.upd__art {
  display:none; position:absolute; z-index:0; right:8px; bottom:7px;
  width:80px; height:60%; object-fit:contain; object-position:100% 100%;
  pointer-events:none; user-select:none;
}
@container (min-width:240px) { .upd__art { display:block; } }
.upd__ico { width:32px; height:32px; border-radius:8px; display:grid; place-items:center; flex:none; font-size:.95rem; }
.upd__ico.tile--blue   { color:var(--blue); }
.upd__ico.tile--green  { color:var(--green); }
.upd__ico.tile--amber  { color:var(--amber); }
.upd__ico.tile--violet { color:var(--violet); }
.upd__t { display:block; font-size:.82rem; font-weight:600; color:var(--ink); }
.upd__s { display:block; font-size:.75rem; color:var(--muted); margin-top:1px; }
.upd__a { margin-left:auto; color:var(--muted); flex:none; }
/* Keep the wording clear of the illustration. */
@container (min-width:240px) { .upd--art .upd__s { padding-right:74px; } }

.more { margin-left:auto; font-size:.78rem; color:var(--blue); font-weight:500; background:none; border:0; cursor:pointer; }

.stack { display:flex; flex-direction:column; gap:16px; }
.sec-title { font-size:1rem; font-weight:600; color:var(--ink); }
.sec-sub { font-size:.82rem; color:var(--muted); margin-top:2px; }
.tnum { font-variant-numeric:tabular-nums; }

/* Key/value rows, used on the plan card. */
.rows { display:grid; gap:0; }
.row { display:flex; flex-wrap:wrap; gap:6px 20px; padding:13px 0; border-bottom:1px solid var(--line-soft); }
.row:last-child { border-bottom:0; }
.row__k { flex:none; width:132px; font-size:.78rem; color:var(--muted); }
.row__v { font-size:.85rem; color:var(--ink); font-weight:500; }

/* ------------------------------------------------- chess accounts --- */
.plat__hd { display:flex; align-items:center; gap:9px; margin-bottom:14px; }
.plat__ico { width:26px; height:26px; border-radius:6px; display:grid; place-items:center; font-size:.95rem; line-height:1; flex:none; }
.plat__ico--cc { background:#81B64C; color:#fff; }
.plat__ico--li { background:#2B2B2B; color:#fff; }
/* The platforms' own supplied logos, on white so each keeps its real colours. */
.plat__ico--img { background:#fff; border:1px solid var(--line); padding:2px; overflow:hidden; }
.plat__ico--img img { width:100%; height:100%; object-fit:contain; display:block; }
.chart { margin:14px 0 10px; }
.chart svg { width:100%; height:auto; display:block; overflow:visible; }
.plat__nm { font-size:.91rem; font-weight:600; color:var(--ink); }
.rating { display:flex; align-items:baseline; gap:9px; }
.rating__v { font-size:1.85rem; font-weight:700; color:var(--ink); line-height:1; }
.rating__k { font-size:.72rem; color:var(--muted); margin-top:3px; }
/* The record under each account. Four columns that divide evenly, with the
   figure large enough to read at a glance and its label beneath it. */
.statrow {
  display:grid; grid-template-columns:repeat(2,1fr); gap:14px 8px;
  padding-top:14px; margin-top:14px; border-top:1px solid var(--line-soft);
}
@media (min-width:520px) { .statrow { grid-template-columns:repeat(4,1fr); } }
.statrow--2 { grid-template-columns:repeat(2,1fr); }
.statrow--3 { grid-template-columns:repeat(3,1fr); }
.stat { min-width:0; }
.stat__v { font-size:1.22rem; font-weight:700; color:var(--ink); line-height:1.15; font-variant-numeric:tabular-nums; }
.stat__v--up { color:var(--good); }
.stat__v--down { color:var(--ended); }
.stat__k { font-size:.7rem; color:var(--muted); margin-top:3px; line-height:1.3; }
.updated { font-size:.69rem; color:var(--muted); display:flex; align-items:center; gap:5px; margin-top:12px; }

/* --------------------------------------------------- progress ------- */
.ring { display:grid; place-items:center; text-align:center; gap:2px; }
.ring svg { width:132px; height:132px; }
.ring__v { font-size:1.6rem; font-weight:700; color:var(--ink); }
.ring__k { font-size:.72rem; color:var(--muted); }
.skill { display:grid; grid-template-columns:1fr 54px; gap:10px; align-items:center; padding:8px 0; }
.skill__n { font-size:.82rem; color:var(--ink); display:flex; align-items:center; gap:8px; }
.skill__p { font-size:.78rem; font-weight:600; color:var(--ink); text-align:right; }
.bar { height:6px; border-radius:100px; background:var(--line-soft); overflow:hidden; }
.bar__f { height:100%; border-radius:100px; background:var(--green); }
.bar__f--green { background:var(--green); }
.bar__f--amber { background:var(--amber); }
.bar__f--blue { background:var(--blue); }
.tgt { padding:11px 0; border-bottom:1px solid var(--line-soft); }
.tgt:last-child { border-bottom:0; }
.tgt__hd { display:flex; align-items:center; gap:9px; }
.tgt__n { font-size:.82rem; font-weight:600; color:var(--ink); }
.tgt__v { font-size:1.05rem; font-weight:700; color:var(--ink); margin:5px 0 6px; }
.tgt__goal { font-size:.75rem; font-weight:500; color:var(--muted); }
.tgt__s { font-size:.69rem; color:var(--muted); margin-top:5px; }
/* The tick a child presses for work done off-platform. */
.tick {
  width:26px; height:26px; border-radius:7px; border:1.5px solid var(--line);
  display:grid; place-items:center; background:var(--card); color:transparent;
  flex:none; cursor:pointer;
}
.tick:hover { border-color:var(--green); color:var(--line); }
.tick--on { background:var(--green); border-color:var(--green); color:#fff; }
.tick[disabled] { opacity:.5; cursor:default; }

/* --------------------------------------------------- practice ------- */
.week { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.week__n { font-size:1.85rem; font-weight:700; color:var(--ink); line-height:1; }
.cycle__note { font-size:.72rem; color:var(--muted); margin-top:7px; max-width:34ch; line-height:1.5; }
.cycle__note b { color:var(--ink); font-weight:600; }
.streak { display:flex; align-items:center; gap:12px; }
.streak__v { font-size:1.85rem; font-weight:700; color:var(--ink); line-height:1; }
.dots { display:flex; gap:4px; flex-wrap:wrap; }
.dot { width:13px; height:13px; border-radius:4px; background:var(--line-soft); }
.dot--on { background:var(--green); }

.pcards { display:grid; gap:14px; grid-template-columns:1fr; }
@media (min-width:620px) { .pcards { grid-template-columns:1fr 1fr; } }
@media (min-width:1080px) { .pcards { grid-template-columns:repeat(3,1fr); } }
.pcard {
  display:block; border:1px solid var(--line); border-radius:var(--r);
  overflow:hidden; background:var(--card); box-shadow:var(--shadow-sm);
  color:inherit; text-align:left; width:100%; font:inherit; cursor:pointer;
  /* Three of these cards are real links to Lichess; without this their
     captions arrive underlined and the row stops matching. */
  text-decoration:none;
}
.pcard:hover { border-color:var(--blue); }
/* A fixed strip rather than an aspect ratio: the cards stretch to match the
   tallest in the row, and an aspect-ratio would let the artwork grow to fill
   whatever slack a shorter caption left behind. */
.pcard__art { position:relative; height:132px; display:grid; place-items:center; background:linear-gradient(150deg,#16305A,#0A1628); font-size:2.2rem; color:#fff; }
/* The academy's supplied banners are 2:1 with the title already set into the
   picture, so they fill the strip and the caption below says what to DO. */
.pcard__art img { width:100%; height:100%; object-fit:cover; display:block; }
.pcard__badge { position:absolute; top:9px; left:9px; font-size:.62rem; font-weight:700; padding:3px 8px; border-radius:100px; letter-spacing:.02em; }
.pcard__badge--auto { background:rgba(29,111,232,.94); color:#fff; }
.pcard__badge--man { background:rgba(255,255,255,.94); color:#0A1628; }
.pcard__done { position:absolute; top:9px; right:9px; width:22px; height:22px; border-radius:50%; background:var(--green); color:#fff; display:grid; place-items:center; font-size:.7rem; }
.pcard__b { padding:12px 14px; display:block; }
/* Both are spans so the whole card can stay a single button; without an
   explicit block they run together on one line. */
.pcard__t { display:block; font-size:.85rem; font-weight:600; color:var(--ink); }
.pcard__s { display:block; font-size:.72rem; color:var(--muted); margin-top:2px; }
.pcard__goal { display:block; margin-top:11px; }
.pcard__goalt { display:block; font-size:.72rem; color:var(--muted); margin-top:6px; }
.pcard__goalt b { color:var(--ink); font-weight:600; }

/* A row in a list of things to act on — the academy's payments queue. */
.task { display:flex; gap:13px; align-items:center; padding:14px 0; border-bottom:1px solid var(--line-soft); flex-wrap:wrap; }
.task:last-child { border-bottom:0; }
.task__ico { width:34px; height:34px; border-radius:9px; display:grid; place-items:center; flex:none; font-weight:700; }
.task__t { font-size:.85rem; font-weight:600; color:var(--ink); }
.task__s { font-size:.72rem; color:var(--muted); margin-top:1px; }

.hist { display:grid; grid-template-columns:1fr auto; gap:8px 14px; align-items:center;
  padding:11px 0; border-bottom:1px solid var(--line-soft); font-size:.82rem; }
.hist:last-child { border-bottom:0; }
.hist__c { font-size:.72rem; color:var(--muted); font-variant-numeric:tabular-nums; }

/* --------------------------------------------------- payments ------- */
.qr--img { max-width:236px; padding:0; overflow:hidden; }
.qr--img img { width:100%; height:auto; display:block; }
.paydata { background:var(--card); border:1px solid var(--line); border-radius:var(--r); margin-top:16px; overflow:hidden; }
.paydata__row { display:flex; align-items:center; gap:12px; padding:13px 16px; border-bottom:1px solid var(--line-soft); }
.paydata__row:last-child { border-bottom:0; }
.paydata__k { font-size:.78rem; color:var(--muted); width:96px; flex:none; }
.paydata__v { font-size:.85rem; font-weight:600; color:var(--ink); overflow-wrap:anywhere; min-width:0; }
.copy { margin-left:auto; display:flex; align-items:center; gap:5px; font-size:.78rem;
  color:var(--blue); font-weight:500; flex:none; background:none; border:0; cursor:pointer; }
.plan__amt { font-size:1.6rem; font-weight:700; color:var(--ink); }

.fee-wrap { overflow-x:auto; margin:0 -2px; }
.fee { border-collapse:collapse; width:100%; min-width:430px; font-size:.82rem; }
.fee th, .fee td { padding:11px 12px; text-align:center; border-bottom:1px solid var(--line-soft); }
.fee thead th { background:var(--navy-900); color:#fff; font-size:.72rem; font-weight:600; line-height:1.35; border-bottom:0; padding:12px 10px; }
.fee thead th:first-child { text-align:left; border-top-left-radius:var(--r-sm); }
.fee thead th:last-child { border-top-right-radius:var(--r-sm); }
.fee thead th small { display:block; font-weight:400; opacity:.72; font-size:.66rem; margin-top:2px; }
.fee tbody th { text-align:left; font-weight:600; color:var(--ink); font-size:.78rem; white-space:nowrap; }
.fee td { font-variant-numeric:tabular-nums; font-weight:600; color:var(--ink); }
.fee tr:last-child th, .fee tr:last-child td { border-bottom:0; }
.fee tr[data-popular] td, .fee tr[data-popular] th { background:var(--blue-bg); }
.fee tr[data-popular] th::after {
  content:"Most popular"; display:block; font-size:.6rem; font-weight:700; color:var(--blue);
  letter-spacing:.04em; text-transform:uppercase; margin-top:2px;
}
.fee__note { font-size:.75rem; color:var(--muted); margin-top:12px; line-height:1.55; }
.fee__inc { display:flex; gap:9px; align-items:center; }
.fee__inc-ico { width:30px; height:30px; border-radius:8px; display:grid; place-items:center; flex:none; font-size:.88rem; }
.fee__inc-t { font-size:.78rem; font-weight:600; color:var(--ink); line-height:1.3; }
.whys { display:grid; gap:8px 18px; grid-template-columns:1fr; }
@media (min-width:640px) { .whys { grid-template-columns:1fr 1fr; } }
.why { display:flex; gap:9px; align-items:flex-start; font-size:.78rem; color:var(--body); }
.step { display:flex; gap:13px; align-items:flex-start; }
.step__n { width:30px; height:30px; border-radius:50%; background:var(--blue-bg); color:var(--blue);
  display:grid; place-items:center; font-size:.82rem; font-weight:700; flex:none; }
.step__t { font-size:.85rem; font-weight:600; color:var(--ink); }
.step__s { font-size:.78rem; color:var(--muted); margin-top:2px; line-height:1.45; }

/* ------------------------------------------------------- library ---- */
.book { display:flex; gap:14px; align-items:flex-start; }
.cover {
  width:78px; height:106px; flex:none; border-radius:6px; overflow:hidden; position:relative;
  display:grid; place-items:center; text-align:center; padding:8px;
  box-shadow:0 2px 8px rgba(11,30,61,.18); border:1px solid rgba(0,0,0,.08);
}
.cover span { font-size:.53rem; font-weight:700; color:#fff; line-height:1.25; }
.cover--plain { background:linear-gradient(160deg,#1D3557,#0B1E3D); }
.cover--img { background:var(--line-soft); padding:0; }
.cover img { width:100%; height:100%; object-fit:cover; display:block; }
.cover__tag {
  position:absolute; top:0; right:0; background:var(--green); color:#fff; z-index:1;
  font-size:.47rem; font-weight:700; padding:2px 5px;
  border-bottom-left-radius:5px; letter-spacing:.04em;
}
.book__t { font-size:.91rem; font-weight:600; color:var(--ink); line-height:1.3; }
.book__a { font-size:.75rem; color:var(--muted); margin-top:1px; }
.book__d { font-size:.78rem; color:var(--body); margin-top:7px; line-height:1.45; }

.mini-covers { display:flex; gap:5px; margin:12px 0; flex-wrap:wrap; }
.mini-cover {
  width:34px; height:46px; border-radius:3px; flex:none; overflow:hidden;
  background:var(--line-soft); box-shadow:0 1px 3px rgba(11,30,61,.2);
}
.mini-cover img { width:100%; height:100%; object-fit:cover; display:block; }

.bundle__hd { display:flex; align-items:flex-start; gap:11px; }
.bundle__ico { width:34px; height:34px; border-radius:9px; display:grid; place-items:center; flex:none; font-size:1.15rem; }
.tile--blue { background:var(--blue-bg); }
.tile--green { background:var(--green-bg); }
.tile--amber { background:var(--amber-bg); }
.tile--violet { background:var(--violet-bg); }

.bundle__list { list-style:none; margin:0; padding:10px 0 0; border-top:1px solid var(--line-soft); }
.bundle__list li { padding:5px 0 5px 15px; position:relative; font-size:.78rem; line-height:1.4; }
.bundle__list li::before {
  content:""; position:absolute; left:2px; top:11px;
  width:5px; height:5px; border-radius:1px; background:var(--blue);
}
.bundle__list b { display:block; color:var(--ink); font-weight:600; }
.bundle__list span { color:var(--muted); font-size:.72rem; }

.price { display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.price__now { font-size:1.19rem; font-weight:700; color:var(--ink); }
.price__was { font-size:.78rem; color:var(--muted); text-decoration:line-through; }

.cat + .cat { margin-top:22px; }
.cat__h {
  font-size:.82rem; font-weight:600; color:var(--ink); margin:0 0 11px;
  display:flex; align-items:center; gap:8px;
}
.cat__h span {
  font-size:.69rem; font-weight:600; color:var(--muted);
  background:var(--line-soft); border-radius:100px; padding:2px 8px;
}
.ind { display:grid; gap:12px; grid-template-columns:repeat(2,1fr); }
@media (min-width:700px) { .ind { grid-template-columns:repeat(3,1fr); } }
@media (min-width:1080px) { .ind { grid-template-columns:repeat(5,1fr); } }
.ind .cover { width:100%; height:118px; margin-bottom:9px; }

/* The payment block a book or bundle opens into. */
.buy { margin-top:12px; padding-top:12px; border-top:1px solid var(--line-soft); }
.buy__qr { width:100%; max-width:190px; height:auto; display:block; margin:10px 0;
  border:1px solid var(--line); border-radius:var(--r-sm); background:#fff; }

/* ------------------------------------------------ coach portal ---- */
/* A batch is a button, so it reads as somewhere to go rather than a panel
   that happens to be clickable.

   Scoped to `.card.tile`, which is what coach.js actually writes. Left as a
   bare `.tile` it also caught the parent dashboard's at-a-glance tiles, and
   being the later rule it won: their tint reverted to white and their padding
   to zero, so the figures sat hard against the edge of the box. */
.card.tile {
  text-align:left; font:inherit; color:inherit; cursor:pointer;
  border:1px solid var(--line); background:var(--surface); padding:0;
}
.card.tile:hover { border-color:var(--accent-line); }
.tile__name {
  font-family:var(--serif); font-size:1.15rem; color:var(--ink);
  font-weight:600; line-height:1.2; margin-bottom:3px;
}
.tile__count {
  margin-top:12px; padding-top:10px; border-top:1px solid var(--line-soft);
  font-size:.82rem; color:var(--muted); font-variant-numeric:tabular-nums;
}

/* The register. Nothing but names, by design. */
.roster { list-style:none; padding:0; margin:0; }
.roster li { border-bottom:1px solid var(--line-soft); }
.roster li:last-child { border-bottom:0; }
.roster__btn {
  display:block; width:100%; text-align:left;
  padding:13px 4px; border:0; background:none;
  font-size:1rem; color:var(--ink); font-weight:500;
}
.roster__btn:hover { color:var(--accent); }
.roster__btn::after { content:"\203A"; float:right; color:var(--muted); }

/* ------------------------------------------------------- board ---- */
/* Board colours are the academy's own. Chess.com's terms reserve their
   palette, piece designs and move glyphs, so nothing here borrows them. */
:root {
  --sq-light:#EFE7D6;
  --sq-dark:#7C93B0;
  --sq-from:rgba(212,175,55,.42);
  --sq-to:rgba(212,175,55,.55);
  --sq-sel:rgba(212,175,55,.72);
  --piece-white:#FBFAF7;
  --piece-black:#1B2942;
  --piece-edge:rgba(11,30,61,.55);
}
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) {
    --sq-light:#C6CFDC; --sq-dark:#4A6082;
    --piece-white:#F4F6FA; --piece-black:#0B1524;
    --piece-edge:rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"] {
  --sq-light:#C6CFDC; --sq-dark:#4A6082;
  --piece-white:#F4F6FA; --piece-black:#0B1524;
  --piece-edge:rgba(0,0,0,.6);
}

.board {
  display:grid;
  grid-template-columns:repeat(8, 1fr);
  aspect-ratio:1;
  width:100%;
  max-width:min(560px, 92vw);
  margin:0 auto;
  border:1px solid var(--line);
  border-radius:4px;
  overflow:hidden;
  box-shadow:var(--shadow);
  touch-action:manipulation;
}
.sq {
  position:relative; border:0; padding:0; margin:0;
  display:grid; place-items:center; cursor:default;
  background:var(--sq-light);
}
button.sq { cursor:pointer; }
.sq--dark { background:var(--sq-dark); }
.sq--from { box-shadow:inset 0 0 0 100px var(--sq-from); }
.sq--to { box-shadow:inset 0 0 0 100px var(--sq-to); }
.sq--selected { box-shadow:inset 0 0 0 100px var(--sq-sel); }
.sq--good { box-shadow:inset 0 0 0 100px rgba(28,110,60,.5); }
.sq--bad { box-shadow:inset 0 0 0 100px rgba(140,58,42,.5); }

/* A dot for an empty target, a ring for a capture — the standard grammar,
   drawn ourselves rather than copied. */
.sq--target::after {
  content:""; position:absolute; width:26%; aspect-ratio:1;
  border-radius:50%; background:rgba(11,30,61,.28); pointer-events:none;
}
.sq--occupied-target::after {
  width:86%; background:none; border:3px solid rgba(11,30,61,.3);
}

/* Coordinates, on the edge squares only, as a printed board has them. */
.sq[data-rank]::before, .sq[data-file]:not([data-rank])::before {
  position:absolute; font-size:.56rem; font-weight:600;
  color:rgba(11,30,61,.5); pointer-events:none;
}
.sq[data-rank]::before { content:attr(data-rank); top:2px; left:3px; }
.sq[data-file]:not([data-rank])::before { content:attr(data-file); bottom:1px; right:3px; }
.sq--dark[data-rank]::before, .sq--dark[data-file]::before { color:rgba(255,255,255,.66); }

.piece {
  width:88%; height:88%; pointer-events:none;
  filter:drop-shadow(0 1px 1px rgba(11,30,61,.28));
}
.piece--w path { fill:var(--piece-white); stroke:var(--piece-edge); stroke-width:1.4; }
.piece--b path { fill:var(--piece-black); stroke:rgba(255,255,255,.32); stroke-width:1.1; }

.board-controls {
  display:flex; gap:6px; justify-content:center; margin-top:14px; flex-wrap:wrap;
}
.board-controls .btn { padding:8px 14px; font-size:.86rem; }

/* ------------------------------------------------------ puzzle ---- */
.puzzle__board { margin-bottom:16px; }
.puzzle__feedback {
  text-align:center; font-size:.95rem; color:var(--muted);
  min-height:1.5em; margin-top:12px;
}
.puzzle__feedback--good { color:var(--good); font-weight:600; }
.puzzle__feedback--soft { color:var(--watch); }
.puzzle__solution {
  font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  font-size:.9rem; color:var(--ink); line-height:1.8;
}

/* ---------------------------------------------------- analysis ---- */
.analysis { display:grid; gap:16px; }
@media (min-width:900px) { .analysis { grid-template-columns:minmax(0,1fr) 320px; align-items:start; } }

.eval {
  display:flex; align-items:center; gap:10px; margin-bottom:12px;
  font-variant-numeric:tabular-nums;
}
.eval__bar {
  flex:1; height:8px; border-radius:100px; overflow:hidden;
  background:var(--piece-black); position:relative;
}
.eval__fill {
  position:absolute; inset:0 auto 0 0; background:var(--piece-white);
  transition:width .25s ease;
}
@media (prefers-reduced-motion:reduce) { .eval__fill { transition:none; } }
.eval__score { font-weight:600; color:var(--ink); min-width:4.5ch; text-align:right; }
.eval__depth { font-size:.76rem; color:var(--muted); }

.moves {
  max-height:340px; overflow-y:auto; font-size:.9rem;
  display:grid; grid-template-columns:2.6rem 1fr 1fr; gap:2px 6px;
  align-content:start;
}
.moves__no { color:var(--muted); font-variant-numeric:tabular-nums; padding:3px 0; }
.moves__move {
  text-align:left; border:0; background:none; padding:3px 6px;
  border-radius:3px; color:var(--ink); font:inherit; cursor:pointer;
}
.moves__move:hover { background:var(--sunk); }
.moves__move[aria-current="true"] { background:var(--sunk); font-weight:600; }
.moves__move--blunder { color:var(--ended); }
.moves__move--mistake { color:var(--watch); }
.moves__move--best { color:var(--good); }

.pgn-box {
  width:100%; min-height:110px; font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.82rem; padding:10px; border-radius:var(--radius-sm);
  border:1px solid var(--line); background:var(--surface); color:var(--ink);
  resize:vertical;
}

/* ---------------------------------------------------------------- */
/* Greeting, Set Up nudge, and the profile form on the Set Up screen */
/* ---------------------------------------------------------------- */

.notice--attention { background:var(--watch-bg); border-color:transparent; color:var(--watch); }

.hello {
  display:flex; align-items:center; gap:14px;
  background:linear-gradient(120deg, var(--navy-900), var(--navy-700));
  color:#fff; border-radius:var(--radius); padding:16px 20px;
  box-shadow:var(--shadow); margin-bottom:16px;
}
.hello__ico { font-size:1.6rem; line-height:1; opacity:.92; flex:none; }
.hello__title { font-size:1.05rem; font-weight:600; letter-spacing:-.01em; }
.hello__sub { font-size:.85rem; color:#C6D0E4; margin-top:3px; }

.setup-nudge {
  display:flex; align-items:center; gap:13px; width:100%; text-align:left;
  background:var(--watch-bg); border:1px solid var(--accent-line);
  border-radius:var(--radius); padding:13px 18px; margin-bottom:16px;
  font:inherit; cursor:pointer;
}
.setup-nudge:hover { border-color:var(--watch); }
.setup-nudge__ico { font-size:1.15rem; flex:none; }
.setup-nudge__body { flex:1; min-width:0; display:flex; flex-direction:column; }
.setup-nudge__title { font-size:.92rem; font-weight:600; color:var(--ink); }
.setup-nudge__detail { font-size:.82rem; color:var(--body); margin-top:1px; }
.setup-nudge__go { font-size:.85rem; font-weight:600; color:var(--watch); flex:none; }

/* A round photo, used on the Set Up screen. Same shape whether it holds an
   uploaded photo or the child's initial. */
.stu__ph {
  width:74px; height:74px; border-radius:50%; flex:none; overflow:hidden;
  background:linear-gradient(150deg,#F2C88B,#D89A5A); display:grid; place-items:center;
  font-size:1.6rem; font-weight:700; color:#7A4A16; border:3px solid var(--surface);
  box-shadow:0 0 0 1px var(--line);
}
.stu__ph img { width:100%; height:100%; object-fit:cover; display:block; }
