/* ==========================================================================
   StudyPass — site.css
   Design system v1.0. Tokens are copied verbatim from studypass-styleguide.html,
   which stays the source of truth: change the styleguide first, then this file.

   House style: zero radius everywhere · full solid fills, no tints or opacity
   variants · no gaps between grouped controls · macro type scale · no shadows,
   gradients or glass · high contrast.

   Mobile-first. Every rule below is written for 390px and widened upward.
   ========================================================================== */

/* ---- FONTS ---------------------------------------------------------------
   DIN Pro is licensed to Vanda; the woff2 subsets carry Latin + Cyrillic
   including Ө ө Ү ү and the tugrik sign ₮. Inter comes from the same folder
   for display, so the app has no third-party font requests at all.
   -------------------------------------------------------------------------- */
/* Inter, self-hosted, Latin + Cyrillic. Four weights only: 400 body-in-display
   contexts, 600 UI, 700 buttons and labels, 900 the macro display scale.
   Split by subset so a Mongolian page never downloads Latin glyphs it will
   not draw, and vice versa — unicode-range does the picking. */
@font-face{font-family:'Inter';src:url('../fonts/Inter-400-latin.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-400-cyrillic.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116,U+048A-04FF;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-600-latin.woff2') format('woff2');
  font-weight:600;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-600-cyrillic.woff2') format('woff2');
  font-weight:600;font-style:normal;font-display:swap;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116,U+048A-04FF;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-700-latin.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-700-cyrillic.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116,U+048A-04FF;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-900-latin.woff2') format('woff2');
  font-weight:900;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215;}
@font-face{font-family:'Inter';src:url('../fonts/Inter-900-cyrillic.woff2') format('woff2');
  font-weight:900;font-style:normal;font-display:swap;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116,U+048A-04FF;}

@font-face{font-family:'DIN Pro';src:url('../fonts/DINPro-Regular.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:'DIN Pro';src:url('../fonts/DINPro-Medium.woff2') format('woff2');
  font-weight:500;font-style:normal;font-display:swap;}
@font-face{font-family:'DIN Pro';src:url('../fonts/DINPro-Bold.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap;}

:root{
  /* ---- 1. BRAND PRIMITIVES (from the brand book, do not invent new ones) ---- */
  --sp-blue:#1464FF;      /* signature blue   */
  --sp-white:#FFFFFF;
  --sp-navy:#0A1E46;      /* dark navy        */
  --sp-ink:#1C1C1C;       /* black, text only */
  --sp-sky:#DAEBFF;       /* light blue, bg   */
  --sp-yellow:#FFE478;
  --sp-orange:#F78239;
  --sp-green:#4ECC97;

  /* ---- 2. DERIVED NEUTRALS (navy mixed into white — not in the book) ---- */
  --n-04:#F5F6F8;  --n-08:#EBEDF0;  --n-12:#E2E4E9;  --n-20:#CED2DA;
  --n-32:#B1B7C4;  --n-48:#8993A6;  --n-62:#67748C;  --n-78:#40506F;
  --n-90:#223458;

  /* ---- 3. SEMANTIC ROLES ---- */
  --bg-canvas:var(--sp-white);
  --bg-subtle:var(--sp-sky);
  --bg-inverse:var(--sp-navy);
  --bg-brand:var(--sp-blue);
  --bg-muted:var(--n-04);

  --fg-default:var(--sp-ink);      /* 17.04 on white */
  --fg-strong:var(--sp-navy);      /* 16.32 on white */
  --fg-muted:var(--n-78);          /* 8.09 on white · 6.67 on sky */
  --fg-brand:var(--sp-blue);       /* 4.89 on white — AA normal */
  --fg-on-dark:var(--sp-white);    /* 16.32 on navy  */
  --fg-on-dark-muted:var(--sp-sky);/* 13.45 on navy  */
  --fg-on-brand:var(--sp-white);   /* 4.89 on blue   */

  --status-pass:var(--sp-green);
  --status-warn:var(--sp-yellow);
  --status-alert:var(--sp-orange);
  --status-info:var(--sp-blue);
  /* every status surface carries INK text — white fails on all three */
  --fg-on-status:var(--sp-ink);

  --edge-hair:var(--n-20);
  --edge-strong:var(--sp-navy);
  --edge-brand:var(--sp-blue);
  --edge-inverse:rgba(255,255,255,.28);

  /* ---- 4. TYPOGRAPHY ---- */
  --font-display:'Inter','Helvetica Neue',Arial,sans-serif;
  --font-body:'DIN Pro','Inter','Helvetica Neue',Arial,sans-serif;
  --font-mono:'SFMono-Regular',ui-monospace,Menlo,Consolas,monospace;

  --fs-d1:clamp(56px,9vw,112px);
  --fs-d2:clamp(44px,6.4vw,80px);
  --fs-d3:clamp(36px,4.6vw,60px);
  --fs-h1:44px; --fs-h2:34px; --fs-h3:26px; --fs-h4:20px;
  --fs-lg:18px; --fs-md:16px; --fs-sm:14px; --fs-xs:12px; --fs-2xs:11px;

  --lh-tight:0.92; --lh-snug:1.1; --lh-heading:1.16; --lh-body:1.55; --lh-loose:1.7;
  --tr-mega:-0.045em; --tr-tight:-0.02em; --tr-normal:0; --tr-wide:0.06em; --tr-mega-wide:0.16em;

  /* ---- 5. SPACE (4px base) ---- */
  --s-0:0; --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px; --s-11:192px;

  /* ---- 6. EDGES — RADIUS IS ALWAYS ZERO ---- */
  --radius:0px;
  --bw-hair:1px; --bw-1:2px; --bw-2:3px; --bw-3:4px; --bw-slab:8px;

  /* ---- 7. MOTION ---- */
  --dur-fast:90ms; --dur-base:150ms; --dur-slow:240ms;
  --ease:cubic-bezier(.2,0,0,1);

  --z-nav:100; --z-sticky:200; --z-overlay:900; --z-modal:1000;

  /* ---- 8. LAYOUT ---- */
  --content-max:1160px;
  --measure-body:68ch;
  --touch:48px;
  --tabbar-h:60px;
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;}
}

/* ==========================================================================
   RESET
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;
  background:var(--bg-canvas);
  color:var(--fg-default);
  font-family:var(--font-body);
  font-size:var(--fs-md);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
  /* no horizontal scrolling, ever (sitemap §2) */
  overflow-x:hidden;
}
img,svg,video{max-width:100%;height:auto;display:block;}
button,input,select,textarea{font:inherit;color:inherit;border-radius:var(--radius);}
a{color:var(--fg-brand);text-decoration:none;font-weight:600;}
a:hover{text-decoration:underline;text-underline-offset:3px;}
hr{border:0;border-top:var(--bw-hair) solid var(--edge-hair);margin:var(--s-6) 0;}

/* One focus treatment everywhere: a hard offset ring, never a glow. */
:focus-visible{outline:var(--bw-2) solid var(--sp-blue);outline-offset:2px;}

.visually-hidden{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.skip-link{
  position:absolute;left:0;top:-60px;background:var(--sp-navy);color:var(--fg-on-dark);
  padding:var(--s-3) var(--s-4);z-index:var(--z-modal);font-weight:700;
}
.skip-link:focus{top:0;}

/* ==========================================================================
   TYPE
   ========================================================================== */
h1,h2,h3,h4,.display1,.display2,.display3{
  font-family:var(--font-display);
  color:var(--fg-strong);
  margin:0 0 var(--s-4);
  font-weight:900;
}
.display1{font-size:var(--fs-d1);line-height:var(--lh-tight);letter-spacing:var(--tr-mega);text-transform:uppercase;}
.display2{font-size:var(--fs-d2);line-height:var(--lh-tight);letter-spacing:var(--tr-mega);}
.display3{font-size:var(--fs-d3);line-height:var(--lh-snug);letter-spacing:var(--tr-tight);}
h1{font-size:var(--fs-h1);line-height:var(--lh-snug);letter-spacing:var(--tr-tight);}
h2{font-size:var(--fs-h2);line-height:var(--lh-heading);letter-spacing:var(--tr-tight);}
h3{font-size:var(--fs-h3);line-height:var(--lh-heading);}
h4{font-size:var(--fs-h4);line-height:var(--lh-heading);font-weight:700;}
p{margin:0 0 var(--s-4);max-width:var(--measure-body);}
.lead{font-size:var(--fs-lg);color:var(--fg-muted);}
.muted{color:var(--fg-muted);}
.small{font-size:var(--fs-sm);}
.label{
  font-family:var(--font-display);font-size:var(--fs-xs);font-weight:700;
  letter-spacing:var(--tr-mega-wide);text-transform:uppercase;color:var(--fg-muted);
}

/* The band number is the loudest thing on any screen. */
.band-number{
  font-family:var(--font-display);font-weight:900;font-size:56px;
  line-height:var(--lh-tight);letter-spacing:var(--tr-mega);
  color:var(--fg-strong);font-variant-numeric:tabular-nums;
}

/* ==========================================================================
   LAYOUT
   ========================================================================== */
.wrap{width:100%;max-width:var(--content-max);margin:0 auto;padding:0 var(--s-4);}
.section{padding:var(--s-7) 0;}
.section--inverse{background:var(--bg-inverse);color:var(--fg-on-dark);}
.section--inverse h1,.section--inverse h2,.section--inverse h3,
.section--inverse .display1,.section--inverse .display2,.section--inverse .display3{color:var(--fg-on-dark);}
.section--inverse .muted,.section--inverse .lead{color:var(--fg-on-dark-muted);}
.section--subtle{background:var(--bg-subtle);}
.stack>*+*{margin-top:var(--s-4);}
.grid{display:grid;gap:var(--s-4);grid-template-columns:1fr;}
@media (min-width:768px){
  .wrap{padding:0 var(--s-5);}
  .section{padding:var(--s-9) 0;}
  .grid--2{grid-template-columns:repeat(2,1fr);}
  .grid--3{grid-template-columns:repeat(3,1fr);}
}

/* ==========================================================================
   BUTTONS
   Grouped controls share a single seam — a gutter would make each button a
   separate decision. That is why .btn-group uses a negative margin instead
   of a gap.
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);
  min-height:var(--touch);padding:0 var(--s-5);
  font-family:var(--font-display);font-weight:700;font-size:var(--fs-md);
  letter-spacing:var(--tr-wide);text-transform:uppercase;
  border:var(--bw-1) solid var(--sp-blue);
  background:var(--sp-blue);color:var(--fg-on-brand);
  cursor:pointer;text-decoration:none;
  transition:background var(--dur-fast) var(--ease),color var(--dur-fast) var(--ease);
}
.btn:hover{background:var(--sp-navy);border-color:var(--sp-navy);color:var(--fg-on-dark);text-decoration:none;}
.btn--secondary{background:transparent;color:var(--fg-brand);}
.btn--secondary:hover{background:var(--sp-blue);color:var(--fg-on-brand);}
.btn--inverse{background:var(--sp-white);border-color:var(--sp-white);color:var(--sp-navy);}
.btn--inverse:hover{background:var(--sp-sky);border-color:var(--sp-sky);color:var(--sp-navy);}
.btn--ghost{background:transparent;border-color:var(--edge-strong);color:var(--fg-strong);}
.btn--ghost:hover{background:var(--sp-navy);color:var(--fg-on-dark);}
.btn--lg{min-height:56px;font-size:var(--fs-lg);padding:0 var(--s-6);}
.btn--block{display:flex;width:100%;}
.btn[disabled],.btn[aria-disabled="true"]{
  background:var(--n-20);border-color:var(--n-20);color:var(--n-62);cursor:not-allowed;
}
/* Below 520px a row of buttons would wrap and break the seam, so the group
   becomes a vertical stack that shares a horizontal seam instead. The rule is
   "one shared edge", not "one shared row". */
.btn-group{display:flex;flex-wrap:nowrap;}
.btn-group>.btn+.btn{margin-left:calc(var(--bw-1) * -1);}
@media (max-width:520px){
  .btn-group{flex-direction:column;align-items:stretch;}
  .btn-group>.btn{width:100%;}
  .btn-group>.btn+.btn{margin-left:0;margin-top:calc(var(--bw-1) * -1);}
}

/* ==========================================================================
   FORM CONTROLS
   ========================================================================== */
.field{display:block;margin-bottom:var(--s-4);}
.field>.label{display:block;margin-bottom:var(--s-2);}
.input,.select,.textarea{
  width:100%;min-height:var(--touch);padding:var(--s-3) var(--s-4);
  background:var(--bg-canvas);color:var(--fg-default);
  border:var(--bw-1) solid var(--edge-strong);
}
.textarea{min-height:180px;resize:vertical;line-height:var(--lh-body);}
.input::placeholder,.textarea::placeholder{color:var(--n-48);}
.input:disabled,.textarea:disabled{background:var(--n-08);color:var(--n-62);}
.field--error .input,.field--error .textarea{border-color:var(--sp-orange);border-width:var(--bw-2);}
.field-note{font-size:var(--fs-sm);color:var(--fg-muted);margin-top:var(--s-2);}
.field-note--error{color:var(--fg-default);background:var(--sp-orange);padding:var(--s-2) var(--s-3);}

/* ==========================================================================
   SURFACES
   ========================================================================== */
.card{background:var(--bg-canvas);border:var(--bw-1) solid var(--edge-strong);padding:var(--s-5);}
.card--subtle{background:var(--bg-subtle);border-color:var(--bg-subtle);}
.card--muted{background:var(--bg-muted);border-color:var(--edge-hair);}
.card--inverse{background:var(--bg-inverse);border-color:var(--bg-inverse);color:var(--fg-on-dark);}

.badge{
  display:inline-block;padding:var(--s-1) var(--s-3);
  font-family:var(--font-display);font-size:var(--fs-xs);font-weight:700;
  letter-spacing:var(--tr-wide);text-transform:uppercase;
  background:var(--sp-navy);color:var(--fg-on-dark);
}
/* green means ACHIEVED, never "go". orange is destructive or locked. */
.badge--pass{background:var(--status-pass);color:var(--fg-on-status);}
.badge--warn{background:var(--status-warn);color:var(--fg-on-status);}
.badge--locked{background:var(--status-alert);color:var(--fg-on-status);}
.badge--free{background:var(--status-pass);color:var(--fg-on-status);}

.alert{border-left:var(--bw-slab) solid var(--sp-navy);background:var(--bg-muted);padding:var(--s-4);}
.alert--pass{border-color:var(--status-pass);}
.alert--warn{border-color:var(--status-warn);}
.alert--alert{border-color:var(--status-alert);}

/* The locked wall. The blur here is decoration on top of data that was never
   sent — locked_vocab_summary() returns counts, not words. Never rely on it. */
.locked{position:relative;background:var(--bg-muted);border:var(--bw-1) solid var(--edge-hair);padding:var(--s-5);text-align:center;}
.locked__blur{filter:blur(7px);user-select:none;pointer-events:none;color:var(--n-48);font-size:var(--fs-lg);}
.locked__label{margin-top:var(--s-3);}

/* ==========================================================================
   NAV — injected by site.js
   ========================================================================== */
.nav{
  position:sticky;top:0;z-index:var(--z-nav);
  background:var(--bg-canvas);border-bottom:var(--bw-1) solid var(--edge-strong);
}
.nav__inner{display:flex;align-items:center;justify-content:space-between;min-height:64px;gap:var(--s-4);}
.nav__brand{display:flex;align-items:center;gap:var(--s-2);font-family:var(--font-display);
  font-weight:900;font-size:var(--fs-h4);letter-spacing:var(--tr-tight);color:var(--fg-strong);text-decoration:none;}
.nav__brand:hover{text-decoration:none;}
.nav__links{display:none;gap:var(--s-5);align-items:center;}
.nav__links a{color:var(--fg-strong);font-size:var(--fs-sm);font-weight:600;}
.nav__actions{display:flex;align-items:center;}
@media (min-width:900px){.nav__links{display:flex;}}

/* Language toggle: two halves of one control, sharing a seam. */
.lang{display:flex;border:var(--bw-1) solid var(--edge-strong);}
.lang button{
  min-height:36px;padding:0 var(--s-3);background:transparent;border:0;cursor:pointer;
  font-family:var(--font-display);font-size:var(--fs-xs);font-weight:700;
  letter-spacing:var(--tr-wide);text-transform:uppercase;color:var(--fg-strong);
}
.lang button[aria-pressed="true"]{background:var(--sp-navy);color:var(--fg-on-dark);}

/* ==========================================================================
   BOTTOM TAB BAR — the whole app (sitemap §2). Five items, thumb-reachable.
   ========================================================================== */
.tabbar{
  position:fixed;left:0;right:0;bottom:0;z-index:var(--z-nav);
  display:flex;background:var(--bg-canvas);
  border-top:var(--bw-1) solid var(--edge-strong);
  padding-bottom:env(safe-area-inset-bottom);
}
.tabbar a{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  min-height:var(--tabbar-h);text-decoration:none;color:var(--fg-muted);
  font-family:var(--font-display);font-size:var(--fs-2xs);font-weight:700;
  letter-spacing:var(--tr-wide);text-transform:uppercase;
}
.tabbar a[aria-current="page"]{background:var(--sp-navy);color:var(--fg-on-dark);}
.has-tabbar{padding-bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom));}

/* ==========================================================================
   FOOTER — the trademark disclaimer is required on every page.
   ========================================================================== */
.footer{background:var(--bg-inverse);color:var(--fg-on-dark-muted);padding:var(--s-7) 0 var(--s-6);}
.footer a{color:var(--fg-on-dark);}
.footer__cols{display:grid;gap:var(--s-5);grid-template-columns:1fr;}
@media (min-width:768px){.footer__cols{grid-template-columns:repeat(4,1fr);}}
.footer__legal{
  margin-top:var(--s-6);padding-top:var(--s-4);
  border-top:var(--bw-hair) solid var(--edge-inverse);
  font-size:var(--fs-xs);line-height:var(--lh-body);
}

/* ==========================================================================
   BILINGUAL
   site.js sets <html lang> and toggles which of the two spans is shown.
   Mongolian is the default language, not the translation.
   ========================================================================== */
html[lang="mn"] [data-lang="en"]{display:none;}
html[lang="en"] [data-lang="mn"]{display:none;}

/* ==========================================================================
   UTILITIES
   ========================================================================== */
.center{text-align:center;}
.row{display:flex;align-items:center;gap:var(--s-3);flex-wrap:wrap;}
.between{display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);}
.mt-0{margin-top:0;} .mb-0{margin-bottom:0;}
.hide{display:none!important;}
[hidden]{display:none!important;}

/* ==========================================================================
   APP-ONLY COMPONENTS  (loaded on every page; used only under /app)
   ========================================================================== */

/* ---- question blocks ----------------------------------------------------- */
.qblock{border:var(--bw-1) solid var(--edge-strong);padding:var(--s-4);margin-bottom:calc(var(--bw-1) * -1);}
.qblock:last-of-type{margin-bottom:0;}
.qprompt{font-size:var(--fs-lg);margin-bottom:var(--s-3);}
.qblock--right{border-color:var(--status-pass);border-width:var(--bw-2);}
.qblock--wrong{border-color:var(--status-alert);border-width:var(--bw-2);}
.qblock--blank{border-color:var(--n-48);}
.qblock--blank .qmark{color:var(--fg-muted);}
.qmark{font-family:var(--font-display);font-size:var(--fs-sm);font-weight:700;
  letter-spacing:var(--tr-wide);text-transform:uppercase;margin:var(--s-3) 0 0;}
.qblock--right .qmark{color:var(--fg-strong);}
.qblock--wrong .qmark{background:var(--status-alert);color:var(--fg-on-status);padding:var(--s-2) var(--s-3);}

/* Options are one stacked control group — no gaps, one shared seam. */
.opts{display:flex;flex-direction:column;}
.opt{display:flex;align-items:center;gap:var(--s-3);min-height:var(--touch);
  padding:0 var(--s-4);border:var(--bw-hair) solid var(--edge-hair);
  margin-bottom:calc(var(--bw-hair) * -1);cursor:pointer;}
.opt:has(input:checked){background:var(--bg-subtle);border-color:var(--edge-brand);
  border-width:var(--bw-1);position:relative;z-index:1;}
.opt input{width:20px;height:20px;accent-color:var(--sp-blue);flex:none;}

/* ---- criterion table ----------------------------------------------------- */
.crit{width:100%;border-collapse:collapse;margin-top:var(--s-3);}
.crit th,.crit td{border:var(--bw-hair) solid var(--edge-hair);padding:var(--s-2) var(--s-3);
  font-size:var(--fs-sm);text-align:left;}
.crit th{font-family:var(--font-display);font-weight:700;letter-spacing:var(--tr-wide);
  width:70px;background:var(--bg-muted);}
.crit td{font-family:var(--font-display);font-weight:900;font-variant-numeric:tabular-nums;}

/* ---- plan list ----------------------------------------------------------- */
.plan{display:flex;flex-direction:column;}
.plan__item{display:flex;gap:var(--s-4);align-items:flex-start;
  border:var(--bw-1) solid var(--edge-strong);padding:var(--s-4);
  margin-bottom:calc(var(--bw-1) * -1);text-decoration:none;color:inherit;}
.plan__item:hover{background:var(--bg-muted);text-decoration:none;}
.plan__item--done{background:var(--status-pass);border-color:var(--status-pass);color:var(--fg-on-status);}
.plan__num{font-family:var(--font-display);font-weight:900;font-size:var(--fs-h3);
  line-height:1;flex:none;width:34px;font-variant-numeric:tabular-nums;}
.plan__body{flex:1;min-width:0;}
/* the row is an <a>, so its children must opt out of link styling or the
   metadata renders as bold blue and runs into the title */
.plan__item,.plan__item:hover{font-weight:400;}
.plan__title{display:block;font-family:var(--font-display);font-weight:700;
  font-size:var(--fs-md);color:var(--fg-strong);margin:0 0 var(--s-1);}
.plan__meta{display:block;font-size:var(--fs-sm);font-weight:400;color:var(--fg-muted);margin:0;}
.plan__item--done .plan__title{color:var(--fg-on-status);}
.plan__item--done .plan__meta{color:var(--fg-on-status);}

/* ---- vocabulary ---------------------------------------------------------- */
.word{border:var(--bw-1) solid var(--edge-strong);padding:var(--s-4);margin-bottom:calc(var(--bw-1) * -1);}
.word__head{display:flex;justify-content:space-between;align-items:baseline;gap:var(--s-3);}
.word__w{font-family:var(--font-display);font-weight:900;font-size:var(--fs-h4);margin:0;}
.word__gloss{margin:var(--s-2) 0 0;}
.word__err{margin:var(--s-3) 0 0;padding:var(--s-2) var(--s-3);
  background:var(--status-warn);color:var(--fg-on-status);font-size:var(--fs-sm);}

/* The locked wall. Real words are never in the DOM — the blurred text below
   is generated filler. Removing the blur in dev tools reveals nothing. */
.wall{border:var(--bw-1) solid var(--edge-strong);margin-bottom:calc(var(--bw-1) * -1);}
.wall__head{display:flex;justify-content:space-between;align-items:center;gap:var(--s-3);
  background:var(--sp-navy);color:var(--fg-on-dark);padding:var(--s-3) var(--s-4);}
.wall__count{font-family:var(--font-display);font-weight:900;font-size:var(--fs-h3);
  font-variant-numeric:tabular-nums;}
.wall__body{padding:var(--s-4);display:flex;flex-wrap:wrap;gap:var(--s-2);}
.wall__ghost{filter:blur(6px);user-select:none;pointer-events:none;
  background:var(--n-20);color:transparent;height:22px;}

/* ---- progress meters ----------------------------------------------------- */
.meter{height:16px;background:var(--n-12);border:var(--bw-1) solid var(--edge-strong);}
.meter__fill{height:100%;background:var(--sp-blue);}
.meter__fill--pass{background:var(--status-pass);}
.meter__fill--warn{background:var(--status-warn);}

/* ---- counters ------------------------------------------------------------ */
.counter{font-family:var(--font-display);font-size:var(--fs-sm);font-weight:700;
  letter-spacing:var(--tr-wide);text-transform:uppercase;color:var(--fg-muted);}

/* ---- auth ---------------------------------------------------------------- */
.auth{max-width:420px;margin:0 auto;padding:var(--s-7) var(--s-4) var(--s-9);}
.auth h1{font-size:var(--fs-h2);}

/* ==========================================================================
   DESKTOP SHELL — sidebar navigation at 900px and up.

   Design target is 1440. Below 900px nothing here applies and the bottom tab
   bar takes over unchanged: the sidebar collapses into it rather than being a
   second, separate navigation concept. One nav definition in site.js, two
   presentations decided here.
   ========================================================================== */
.sidebar{display:none;}

@media (min-width:900px){
  .sidebar{
    display:flex;flex-direction:column;
    position:fixed;left:0;top:0;bottom:0;width:240px;z-index:var(--z-nav);
    background:var(--bg-inverse);color:var(--fg-on-dark);
    border-right:var(--bw-1) solid var(--sp-navy);
    overflow-y:auto;
  }
  .sidebar__brand{
    display:block;padding:var(--s-5) var(--s-5) var(--s-4);
    font-family:var(--font-display);font-weight:900;font-size:var(--fs-h4);
    letter-spacing:var(--tr-tight);color:var(--fg-on-dark);text-decoration:none;
  }
  .sidebar__brand:hover{text-decoration:none;}

  /* The band the student owns is the most important fact on any screen, so
     it sits above the navigation rather than inside a settings page. */
  .sidebar__tier{
    padding:var(--s-4) var(--s-5);
    border-top:var(--bw-hair) solid var(--edge-inverse);
    border-bottom:var(--bw-hair) solid var(--edge-inverse);
  }
  .sidebar__tier .label{color:var(--sp-sky);margin:0 0 var(--s-1);}
  .sidebar__tier b{
    font-family:var(--font-display);font-weight:900;font-size:var(--fs-h2);
    line-height:1;letter-spacing:var(--tr-mega);color:var(--fg-on-dark);
    font-variant-numeric:tabular-nums;
  }

  /* Nav items share one seam, like every other grouped control. */
  .sidebar__nav{display:flex;flex-direction:column;padding:var(--s-4) 0;}
  .sidebar__nav a{
    display:block;padding:var(--s-3) var(--s-5);min-height:var(--touch);
    line-height:var(--touch);
    font-family:var(--font-display);font-weight:700;font-size:var(--fs-sm);
    letter-spacing:var(--tr-wide);text-transform:uppercase;
    color:var(--fg-on-dark-muted);text-decoration:none;
    border-left:var(--bw-3) solid transparent;
  }
  .sidebar__nav a:hover{background:rgba(255,255,255,.06);color:var(--fg-on-dark);text-decoration:none;}
  .sidebar__nav a[aria-current="page"]{
    background:var(--sp-blue);color:var(--fg-on-brand);border-left-color:var(--sp-white);
  }
  .sidebar__foot{margin-top:auto;padding:var(--s-4) var(--s-5) var(--s-5);
    border-top:var(--bw-hair) solid var(--edge-inverse);}
  .sidebar__foot .lang{border-color:var(--edge-inverse);margin-bottom:var(--s-3);}
  .sidebar__foot .lang button{color:var(--fg-on-dark-muted);}
  .sidebar__foot .lang button[aria-pressed="true"]{background:var(--sp-white);color:var(--sp-navy);}
  .sidebar__foot .btn{width:100%;min-height:40px;font-size:var(--fs-xs);
    background:transparent;border-color:var(--edge-inverse);color:var(--fg-on-dark);}
  .sidebar__foot .btn:hover{background:var(--sp-white);border-color:var(--sp-white);color:var(--sp-navy);}

  /* The sidebar is fixed, so the document gets out of its way. */
  body.has-sidebar{padding-left:240px;padding-bottom:0;}
  body.has-sidebar .tabbar{display:none;}

  /* 1440 canvas: a 1200px content column, left-aligned against the sidebar
     rather than centred in the viewport — centring it drifts the reading
     column away from the nav as the window widens. */
  body.has-sidebar .wrap{max-width:1200px;margin:0;padding:0 var(--s-7);}

  /* Anything the sidebar already says must not be repeated in the page —
     the band tier is the obvious one. It stays in the markup because below
     900px the sidebar is gone and the page is the only place it appears. */
  body.has-sidebar .only-mobile{display:none;}
}

@media (min-width:1680px){
  /* Past the design target, centre the whole shell instead of letting the
     content column strand itself on the left of a very wide display. */
  body.has-sidebar .wrap{margin:0 auto;}
}
