/* ============================================================================
   lux.css - AlphaDrill "institutional quiet-luxury" art direction.

   Loaded LAST (after theme.css). theme.css remains the structural design system;
   this layer gives it a point of view so it stops looking like a generic SaaS
   template: a high-contrast serif display face, a warm ink-on-bone palette with
   ONE champagne-gold decorative accent, faint paper grain, hairline rules, and a
   signature concentric-ring motif. Think private bank / FT Weekend, not Tailwind.

   It works by REMAPPING the shared design tokens theme.css already uses (so the
   whole app recolours cohesively) and then layering the bespoke bits on top.
============================================================================ */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght,SOFT@0,9..144,400,0..100;0,9..144,500,0..100;0,9..144,580,0..100;1,9..144,460,0..100&family=Tinos:wght@400;700&family=Hanken+Grotesk:wght@400;500;600;700&display=swap');

/* ---------------------------------------------------------------------------
   TOKEN REMAP - recolour the existing system to ink + bone + champagne
--------------------------------------------------------------------------- */
:root {
  --f: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --f-display: 'Fraunces', Georgia, 'Times New Roman', serif;

  /* warm ink neutrals */
  --ink-0: #0b1020;   /* near-black navy - display */
  --ink-1: #1c2233;   /* body */
  --ink-2: #3b4459;   /* secondary */
  --ink-3: #6c7589;   /* muted */
  --ink-4: #9aa1b1;   /* placeholder */

  /* paper */
  --bg:        #f6f2ea;
  --surface:   #fffdf9;
  --surface-2: #f1ebe0;
  --surface-3: #eae2d4;
  --line:      #e4dccd;   /* warm hairline */
  --line-2:    #d4c9b5;

  /* neutral grey for calendar off-days / holidays (distinct from the warm beige
     surface-3, which otherwise looks like a study day) */
  --cal-grey:      #e6e7ea;
  --cal-grey-line: #d3d5db;
  --cal-hatch: repeating-linear-gradient(45deg, transparent 0, transparent 4px, rgba(60,66,82,.07) 4px, rgba(60,66,82,.07) 5px);

  /* primary interactive = ink (timeless, reads expensive); white text on it */
  --accent:    #0b1020;
  --accent-d:  #20283d;
  --accent-t:  rgba(11,16,32,.05);
  --accent-t2: rgba(11,16,32,.12);

  /* the ONE decorative accent - champagne gold */
  --gold:    #9b7a3c;   /* gold text / icons (AA on bone) */
  --gold-2:  #c8a96a;   /* gold lines / glints */
  --gold-t:  rgba(155,122,60,.10);

  --ok:  #2f6b4f;  --ok-bg: rgba(47,107,79,.10);
  --bad: #9d3b1f;  --bad-bg: rgba(157,59,31,.10);
  --warn: #8a5a12;  --warn-bg: rgba(184,134,11,.12);  --warn-line: rgba(184,134,11,.45);

  /* secondary action accent - the SAME dark navy as the dashboard hero strip
     (Custom session / Sudden death / View question bank) so the buttons read as
     part of the same family. The primary CTA keeps its gold ring for hierarchy. */
  --blue:   #11182c;
  --blue-d: #1c2540;
  --blue-t: rgba(17,24,44,.08);

  /* softer, warmer shadows */
  --sh-xs: 0 1px 2px rgba(20,15,5,.04);
  --sh-sm: 0 2px 8px rgba(20,15,5,.06);
  --sh-md: 0 20px 50px -24px rgba(20,15,5,.20);
}

/* ---------------------------------------------------------------------------
   PAPER GRAIN - a faint texture over the whole page (a real "not-AI" tell)
--------------------------------------------------------------------------- */
body:not(.exam-body) { position: relative; }
body:not(.exam-body)::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}
.home-wrap, .bank-tabs { position: relative; z-index: 1; }

/* Reserve the scrollbar gutter on EVERY page (even ones that don't scroll, like the
   viewport-locked dashboard). Without this, scrolling pages (Privacy, Q Bank) lose
   ~15px to the scrollbar while the dashboard keeps the full width, so their sticky
   nav and fixed footer sit indented on the right relative to the dashboard. A stable
   gutter everywhere gives all pages an identical content width, so the header brand
   and footer links line up across pages and there is no jump when navigating. */
html { scrollbar-gutter: stable; }

/* ---------------------------------------------------------------------------
   TYPE - serif display headlines, refined sans body
--------------------------------------------------------------------------- */
body { font-family: var(--f); letter-spacing: 0; }
h1, h2, h3, h4 { font-family: var(--f-display); font-optical-sizing: auto; }
h1 { font-weight: 500; letter-spacing: -0.02em; }
h2 { font-weight: 560; letter-spacing: -0.015em; }
h3 { font-weight: 560; }
.page-head h1 { font-size: clamp(30px, 5vw, 42px); line-height: 1.04; }

/* an editorial eyebrow/kicker used above headlines */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--f);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 18px;
}
.eyebrow::before { content: ""; width: 28px; height: 1px; background: var(--gold-2); display: inline-block; }

/* ---------------------------------------------------------------------------
   NAVIGATION - bone glass, serif wordmark, gold active underline
--------------------------------------------------------------------------- */
.bank-tabs {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(246,242,234,.86);
  border-bottom: 1px solid var(--line);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
}
/* The text wordmark was injected via ::before; we now ship a real <a.brand>
   lockup (gold α + black "Drill"), so suppress the generated content. */
.bank-tabs::before { content: none !important; }

/* ---- Brand lockup: gold α + near-black "Drill" (reads as "AlphaDrill") ---- */
/* The brand α is set in Tinos (a Times New Roman twin) rather than the display font:
   its upright serif alpha has the big oval bowl and sharp flat-cut terminals at BOTH
   the top and the bottom tail that the wordmark wants. Tinos only ships a 400 weight,
   Tinos ships real 400 and 700 weights, so 700 is a true designed bold (not a faux
   one); the brand uses 700 for a heavier α, restated on the size overrides below. */
.brand-a { font-family: 'Tinos', Georgia, 'Times New Roman', serif; font-weight: 700; }
.bank-tabs .brand {
  display: inline-flex;
  align-items: baseline;
  align-self: center;            /* centre the lockup in the nav row... */
  transform: translateY(-1px);   /* ...then nudge up so the gold a optically
                                    centres on the nav links' x-height */
  gap: 0;
  height: auto;
  margin-right: 22px;
  padding: 0 2px 0 0;
  font-family: var(--f-display);
  text-decoration: none;
  white-space: nowrap;
  background: transparent !important;
  border-bottom: none !important;
}
.bank-tabs .brand:hover { background: transparent !important; }
.bank-tabs .brand .brand-a {
  font-size: 30px;
  font-weight: 700;
  line-height: 1;
  color: var(--gold);
  margin-right: 1px;
}
.bank-tabs .brand .brand-word {
  font-size: 20px;
  font-weight: 560;
  letter-spacing: -0.02em;
  color: var(--ink-0);
}
.bank-tabs .brand:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; border-radius: 4px; }

.bank-tabs a { font-family: var(--f); letter-spacing: .01em; border-radius: var(--r-sm); position: relative; }
/* Active tab: a quiet champagne pill + a gold underline, so the current section
   reads clearly without shouting. */
.bank-tabs a.active { background: var(--gold-t); color: var(--ink-0); font-weight: 600; }
.bank-tabs a.active::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: 4px;
  height: 2px; border-radius: 2px; background: var(--gold-2);
}
.bank-tabs a:hover { background: var(--surface-3); color: var(--ink-0); }
.bank-tabs a.active:hover { background: var(--gold-t); }

/* ---------------------------------------------------------------------------
   BUTTONS - ink, squared-ish, gold focus
--------------------------------------------------------------------------- */
.btn-primary, .hero-cta {
  background: var(--ink-0);
  border: 1px solid var(--ink-0);
  color: var(--surface) !important;
  border-radius: 6px;
  font-family: var(--f);
  font-weight: 600;
  letter-spacing: .01em;
  box-shadow: none;
}
.btn-primary:hover, .hero-cta:hover { background: var(--accent-d); border-color: var(--accent-d); }
.btn-primary:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.btn-ghost { border-radius: 6px; border-color: var(--line-2); background: transparent; }

/* Secondary action button - solid blue. Same geometry as .btn-primary so it sits
   cleanly beside the ink CTA and gold accents. */
.btn-blue {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--blue); color: #fff !important; border: 1px solid var(--blue);
  border-radius: 6px; padding: 10px 20px;
  font-family: var(--f); font-size: 14px; font-weight: 600; line-height: 1.2;
  letter-spacing: .01em; cursor: pointer; text-decoration: none; white-space: nowrap;
  box-shadow: 0 8px 18px -12px rgba(8,12,24,.6);
  transition: background .13s, border-color .13s, transform .08s, box-shadow .13s;
}
.btn-blue:hover { background: var(--blue-d); border-color: var(--blue-d); color: #fff; box-shadow: 0 10px 22px -12px rgba(8,12,24,.7); }
.btn-blue:active { transform: translateY(1px); box-shadow: none; }
.btn-blue:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.btn-blue:disabled { opacity: .45; cursor: not-allowed; transform: none; }

a { color: var(--ink-0); }
a:hover { color: var(--gold); }

/* ---------------------------------------------------------------------------
   CARDS - bone surface, hairline border, gold top-rule, restrained shadow
--------------------------------------------------------------------------- */
.card, .runner, .bank-item, .mode-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--sh-xs);
}
.card h2, .mode-card h2 { font-family: var(--f-display); font-size: 20px; font-weight: 560; }

/* ---------------------------------------------------------------------------
   HOME HERO - the showcase
--------------------------------------------------------------------------- */
.home-hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, var(--surface) 0%, var(--bg) 100%);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 56px 48px 52px;
  margin-bottom: 28px;
}
.home-hero h1 {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(40px, 7vw, 68px);
  line-height: 1.0;
  letter-spacing: -0.03em;
  color: var(--ink-0);
  margin: 0 0 18px;
  max-width: 16ch;
}
.home-hero h1 em { font-style: italic; color: var(--gold); font-weight: 460; }
.home-hero .hero-tagline {
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 52ch;
  margin: 0 0 28px;
}
.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 13px 26px;
  font-size: 15px;
  text-decoration: none;
}
.hero-cta::after { content: "\2192"; }

.privacy-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  width: 100%;
  font-size: 13px;
  color: var(--ink-3);
}
.privacy-badge svg { width: 15px; height: 15px; color: var(--gold); }

/* signature concentric-ring motif (echoes the readiness gauge) */
.lux-rings {
  position: absolute;
  top: 50%;
  right: -120px;
  transform: translateY(-50%);
  width: 460px;
  height: 460px;
  pointer-events: none;
  opacity: .9;
}
.lux-rings circle { fill: none; stroke: var(--gold-2); }
@media (max-width: 860px) { .lux-rings { display: none; } }

/* ---------------------------------------------------------------------------
   START SCREEN - pitch (left) + "tailor your prep" / resume panel (right)
--------------------------------------------------------------------------- */
.start-split { display: grid; grid-template-columns: 1.25fr 0.85fr; gap: 24px; align-items: stretch; margin-bottom: 28px; }
.start-split .home-hero { margin-bottom: 0; padding: 44px 42px; display: flex; flex-direction: column; }
.start-split .home-hero h1 { font-size: clamp(34px, 4.4vw, 50px); margin-bottom: 16px; }
.start-split .home-hero .hero-tagline { margin-bottom: 0; }
.start-split .privacy-badge { margin-top: auto; }

.hero-points { list-style: none; margin: 24px 0 0; padding: 0; display: flex; flex-direction: column; gap: 13px; }
.hero-points li { position: relative; padding-left: 26px; font-size: 14.5px; line-height: 1.5; color: var(--ink-2); max-width: 54ch; }
.hero-points li::before {
  content: ""; position: absolute; left: 0; top: 6px; width: 11px; height: 11px;
  border-radius: 999px; border: 2px solid var(--gold-2);
}

.start-setup {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 32px 30px; align-self: start; box-shadow: var(--sh-sm);
}
.start-setup-title { font-family: var(--f-display); font-size: 24px; font-weight: 540; color: var(--ink-0); margin: 0 0 4px; }
.start-setup-sub { font-size: 13.5px; color: var(--ink-3); margin: 0 0 22px; }
.start-setup .setup-go { width: 100%; justify-content: center; margin-top: 20px; }
.start-setup .home-status {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 12px 14px; font-size: 13px; margin-bottom: 8px;
}
@media (max-width: 860px) { .start-split { grid-template-columns: 1fr; } }

/* Resume card (returning candidate): full-height to balance the hero, with the
   CTA pinned to the bottom edge so the two cards read as a matched pair. */
.resume-card { align-self: stretch; display: flex; flex-direction: column; padding: 44px 40px; }
.resume-card .hero-brand { margin-bottom: 22px; }
.resume-card .start-setup-sub { margin-bottom: 26px; }
.resume-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.rs-tile { display: flex; flex-direction: column; gap: 5px; }
.rs-tile strong {
  font-family: var(--f-display); font-size: 30px; font-weight: 560; line-height: 1;
  color: var(--ink-0); font-variant-numeric: tabular-nums;
}
.rs-tile span { font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); line-height: 1.3; }
.resume-card .setup-go { margin-top: auto; }
.resume-links { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; }
.resume-change { font-size: 13px; color: var(--ink-3); text-decoration: none; }
.resume-change:hover { color: var(--gold); }

/* ---------------------------------------------------------------------------
   MODE CARDS - editorial, hairline, gold accents
--------------------------------------------------------------------------- */
.mode-card { padding: 20px 22px; transition: border-color .2s, box-shadow .2s, transform .2s; }
.mode-card:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--sh-md); }
/* Tighter rhythm inside the practice cards so all three stay short and even.
   ~10% more compact than the default card: smaller padding, headings and gaps. */
.practice-grid .mode-card { padding: 16px 18px; }
.practice-grid .mode-card h2 { font-size: 18px; margin-bottom: 3px; }
.practice-grid .mode-card p { font-size: 12.5px; }
.practice-grid .mode-info { gap: 4px; flex: 1; }
.practice-grid .mode-stats { margin: 6px 0 2px; }
.practice-grid .mode-stats strong { font-size: 26px; }
/* Solo KPI (Daily Review bank count, Sudden Death best streak): fill the space
   between the copy and the bottom button so the number sits centred in the card. */
.practice-grid .mode-stats-solo { flex: 1; display: flex; align-items: center; justify-content: center; margin: 0; }
.practice-grid .mode-fields { margin: 6px 0 2px; gap: 7px; }
/* Cards with little content (Daily Review, Sudden Death) keep their button just
   below the copy rather than stranded at the very bottom, so the trio reads as a
   tidy row instead of two near-empty cards beside a tall one. */
.practice-grid .mode-card .sudden-best { margin-bottom: 10px; }
/* Buttons sit flush to the bottom so all three line up across the row. */
.practice-grid .mode-card .btn-primary { margin-top: auto; }
/* Recommended card: a faint champagne wash that follows the theme. Overrides
   theme.css's hardcoded mint gradient (#f5fdf9) which never inverted and showed
   as a pale "shine" in dark mode. */
.mode-card.mode-recommended { border-color: var(--gold-2); box-shadow: 0 0 0 1px var(--gold-t);
  background: linear-gradient(160deg, var(--gold-t) 0%, var(--surface) 58%); }
/* PRO MODE pill: a long pill-shaped feature tag pinned to the card's top-right
   corner (not inline with the heading), so the title reads cleanly on its own.
   Reads as the premium upsell, not a tiny decorative icon. */
.mode-badge {
  position: absolute; top: 14px; right: 14px;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  min-height: 20px;
  font-family: var(--f); font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gold);
  background: var(--gold-t); border: 1px solid var(--gold-2); border-radius: 999px;
  padding: 0 10px 0 8px; line-height: 1;
}
/* Crown sits inside the pill on the left, vertically centred with the text. The
   gold stroke matches the nav crown toggle so every Pro marker reads as one set. */
.pro-crown { width: 12px; height: 12px; flex: none; }
.mode-badge .pro-crown { width: 11px; height: 11px; }
.mode-card .btn-primary { margin-top: auto; }

/* hero brand lockup - gold α + near-black "Drill", quietly above the kicker */
.hero-brand {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--f-display);
  text-decoration: none;
  margin-bottom: 20px;
}
.hero-brand:hover { color: inherit; }
/* The α is sized so its glyph height matches the cap-height of the "D": baseline
   alignment lands their bottoms together, and ~1.3x the word size brings the α's
   top up to the top of the D, so its tips touch both ends of the letter. */
.hero-brand .brand-a { font-size: 39px; font-weight: 700; line-height: 1; color: var(--gold); margin-right: 1px; }
.hero-brand .brand-word { font-size: 26px; font-weight: 560; letter-spacing: -0.02em; color: var(--ink-0); }
.hero-brand:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; border-radius: 4px; }

/* footer wordmark - match the nav lockup so the brand is consistent end-to-end:
   the "Drill" word uses the display face (not the body font) exactly like the
   nav .brand-word, while the gold serif alpha comes from .brand-a above. */
.site-foot .foot-brand { font-family: var(--f-display); font-weight: 560; letter-spacing: -0.02em; }
/* Same proven recipe as .hero-brand: α at ~1.5x the word size, baseline-aligned
   (no vertical-align nudge), line-height 1 — its bottom sits on the baseline with
   "Drill" and its top reaches the cap-height of the "D". */
.site-foot .brand-a { color: var(--gold); margin-right: 1px; font-weight: 700; font-size: 1.5em; line-height: 1; vertical-align: baseline; }

/* status strip */
.home-status { border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.home-status strong { color: var(--ink-0); }

/* empty state */
#empty .es-icon { color: var(--gold); }
#empty h3 { font-family: var(--f-display); font-size: 22px; }

/* ---------------------------------------------------------------------------
   REVIEW hub - type-filter chips + "missed" marker
--------------------------------------------------------------------------- */
.review-filters { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.rev-filter {
  font-family: var(--f);
  font-size: 13px;
  font-weight: 500;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.rev-filter:hover { border-color: var(--ink-3); }
.rev-filter.active { background: var(--ink-0); border-color: var(--ink-0); color: var(--surface); }
.rev-filter:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.pill-miss { background: var(--bad-bg) !important; color: var(--bad) !important; border-color: rgba(157,59,31,.25) !important; }
.rev-q { margin-bottom: 6px; }

/* ---------------------------------------------------------------------------
   SETUP screen - carry the look through (selected = gold)
--------------------------------------------------------------------------- */
.setup-title { font-family: var(--f-display); font-weight: 500; }
.setup-brand {
  display: inline-flex;
  align-items: baseline;
  color: var(--ink-0);
  background: transparent;
  border: none;
  padding: 0;
  margin-bottom: 22px;
  font-family: var(--f-display);
  font-weight: 560;
  font-size: 26px;
  letter-spacing: -0.02em;
  text-transform: none;
}
.setup-brand .brand-a { color: var(--gold); margin-right: 1px; font-size: 39px; font-weight: 700; line-height: 1; }
/* Selected level reads as a premium, filled tile - warm champagne gradient,
   solid gold edge and a soft gold glow - not just a recoloured outline. */
.level-card.selected {
  border-color: var(--gold);
  background: linear-gradient(165deg, var(--gold-t) 0%, var(--surface) 72%);
  box-shadow: 0 0 0 3px var(--gold-t), var(--sh-md);
}
.level-card.selected .level-num { background: var(--gold); border-color: var(--gold); color: #fff; box-shadow: 0 2px 8px rgba(155,122,60,.35); }
.level-card.selected .level-name { color: var(--ink-0); }
.level-card.selected::after { background: var(--gold); border: none; }
.level-name, .setup-q { font-family: var(--f); }

/* dashboard accents that were emerald → keep ink/gold cohesive */
.bar-fill { background: var(--ink-0); }
.readiness-card { background: linear-gradient(160deg, #fffdf9 0%, var(--surface) 60%); }

/* ---------------------------------------------------------------------------
   DASHBOARD - status verdict + recommended next action + today's target
--------------------------------------------------------------------------- */
.status-card { background: linear-gradient(160deg, #fffdf9 0%, var(--surface) 70%); }
.status-line { display: flex; align-items: flex-start; gap: 14px; }
.status-line h2 { margin: 0 0 2px; font-size: 22px; }
.status-line .muted { font-size: 14px; }
.status-dot {
  flex: none; width: 12px; height: 12px; border-radius: 50%; margin-top: 7px;
  background: var(--ink-4); box-shadow: 0 0 0 4px rgba(0,0,0,.04);
}
.status-dot.ok     { background: var(--ok);  box-shadow: 0 0 0 4px var(--ok-bg); }
.status-dot.behind { background: var(--bad); box-shadow: 0 0 0 4px var(--bad-bg); }
.status-dot.info   { background: var(--gold-2); box-shadow: 0 0 0 4px var(--gold-t); }
.status-dot.empty  { background: var(--ink-4); }

.next-action {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 16px; padding: 14px 16px;
  background: var(--gold-t); border: 1px solid rgba(155,122,60,.22); border-radius: 10px;
}
.next-action > div { flex: 1; min-width: 200px; }
.next-action .na-label {
  font-family: var(--f); font-size: 10.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold);
}
.next-action #naText { margin: 3px 0 0; font-size: 15px; color: var(--ink-1); line-height: 1.45; }
.next-action .btn-primary { flex: none; }
.passmarks { margin-top: 12px; }
.passmarks strong { color: var(--ink-1); }

/* The status ("behind pace") bubble holds the key-stat boxes and the
   accuracy-by-topic list, all in one rounded, raised card. */
.dash-stats > .card { border-radius: 12px; box-shadow: var(--sh-md); }
/* Stat boxes live inside the bubble: 3 across and flat (no nested shadow). */
.status-card .score-grid { grid-template-columns: repeat(4, 1fr); margin: 18px 0 0; }
.status-card .score-grid .score-card { box-shadow: none; background: var(--surface-2); }
@media (max-width: 560px) { .status-card .score-grid { grid-template-columns: repeat(2, 1fr); } }

/* Accuracy-by-topic block, folded into the status bubble */
.status-topics { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); }
.status-topics-head { margin: 0 0 4px; font-size: 14px; font-weight: 650; color: var(--ink-0); }
/* Four aligned columns so every row lines up: name | acc | bar | attempted.
   The % sits immediately before (at the start of) the progress bar. */
.status-topics .topic-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 46px 64px 54px;
  gap: 10px; align-items: center; width: 100%;
  padding: 8px 10px; margin: 0; border: 0; border-radius: 8px;
  background: none; cursor: pointer; text-align: left; font: inherit; color: inherit;
}
.status-topics .topic-row:nth-child(odd) { background: var(--accent-t2); }
.status-topics .topic-row:hover { background: var(--accent-t); }
.status-topics .topic-name {
  font-size: 12.5px; font-weight: 500; color: var(--ink-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.status-topics .topic-weight { font-size: 10.5px; font-weight: 600; color: var(--ink-3); }
.status-topics .topic-track { height: 8px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.status-topics .topic-fill { display: block; height: 100%; border-radius: 999px; }
.status-topics .topic-att {
  font-size: 11px; color: var(--ink-3); text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.status-topics .topic-att-lbl { display: none; }   /* keep the column tight */
.status-topics .topic-val { font-size: 12.5px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }

.today-target {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line);
}
.tt-stats { display: flex; gap: 24px; flex: 1; }
.tt-stats > div { font-size: 12.5px; color: var(--ink-3); }
.tt-big { display: block; font-family: var(--f-display); font-size: 26px; font-weight: 560; color: var(--ink-0); }
.today-target .btn-primary { flex: none; }

/* ---------------------------------------------------------------------------
   PRACTICE - three clean cards: what to do right now
--------------------------------------------------------------------------- */
.practice-section { margin-bottom: 22px; }
.practice-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch;
}
.practice-grid .mode-card { height: 100%; position: relative; }
.practice-grid .mode-info { display: flex; flex-direction: column; gap: 6px; }
/* small KPI pair shown in Daily Review / Sudden Death */
.mode-stats { display: flex; gap: 26px; margin: 8px 0 4px; }
.mode-stats > div { display: flex; flex-direction: column; gap: 3px; }
.mode-stats strong {
  font-family: var(--f-display); font-size: 26px; font-weight: 600; line-height: 1;
  color: var(--ink-0); font-variant-numeric: tabular-nums;
}
.mode-stats span { font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
/* A single, centred KPI (Daily Review's bank count, Sudden Death's best streak). */
.mode-stats-solo { justify-content: center; }
.mode-stats-solo > div { align-items: center; text-align: center; }
/* stacked controls inside the Exam Session card only */
.mode-fields { display: flex; flex-direction: column; gap: 11px; margin: 10px 0 4px; }
.mode-fields label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--ink-2);
}
.mode-fields select, .mode-fields input { width: 100%; }
@media (max-width: 860px) { .practice-grid { grid-template-columns: 1fr; } }

/* Exam Session multi-selects: a compact field that opens a tick-box popover, so
   the card stays as short as Sudden Death no matter how many topics exist. */
.ms { position: relative; }
.ms > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 11px; border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); font-size: 12.5px; font-weight: 600; color: var(--ink-1);
  transition: border-color .15s, background .15s;
}
.ms > summary::-webkit-details-marker { display: none; }
.ms > summary::after {
  content: ""; width: 7px; height: 7px; margin-left: 2px; flex: none;
  border-right: 1.5px solid var(--ink-3); border-bottom: 1.5px solid var(--ink-3);
  transform: rotate(45deg) translateY(-2px); transition: transform .15s;
}
.ms[open] > summary { border-color: var(--gold-2); background: var(--surface-2); }
.ms[open] > summary::after { transform: rotate(225deg) translateY(-2px); }
.ms > summary:hover { border-color: var(--gold-2); }
.ms-count {
  font-size: 10.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  color: var(--gold); margin-left: auto;
}
.ms-panel {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 6px);
  box-sizing: border-box; max-height: 196px; padding: 6px;
  /* Scroll vertically only. Setting overflow-y alone makes overflow-x compute to
     auto, which spawned a stray sideways scrollbar — pin overflow-x to hidden. */
  overflow-y: auto; overflow-x: hidden;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: var(--sh-md);
}
/* Force a single horizontal row: name (+ count) on the left, tick box on the
   right. The generic `.mode-fields label` rule sets flex-direction:column, which
   would otherwise stack the tick box UNDER the label - this higher-specificity
   selector wins and keeps everything on one short row. */
.mode-fields label.ms-opt,
.ms-opt {
  display: flex; flex-direction: row; align-items: center; gap: 9px;
  padding: 7px 8px; border-radius: 7px;
  font-size: 12.5px; font-weight: 500; color: var(--ink-1); cursor: pointer;
}
.ms-opt:hover { background: var(--accent-t); }
/* Native input is hidden; .ms-box is the visible tick box on the right. */
.ms-opt input { position: absolute; opacity: 0; pointer-events: none; }
.ms-opt .ms-lab { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ms-opt em { font-style: normal; font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.ms-box {
  flex: none; width: 18px; height: 18px; border: 1.5px solid var(--line-2); border-radius: 5px;
  display: grid; place-items: center; font-size: 12px; line-height: 1; color: var(--gold);
  transition: border-color .12s, background .12s;
}
.ms-opt input:checked ~ .ms-box { border-color: var(--gold); background: var(--accent-t); }
.ms-opt input:checked ~ .ms-box::after { content: "\2713"; }   /* ✓ when ticked */
.ms-opt input:focus-visible ~ .ms-box { outline: 2px solid var(--gold-2); outline-offset: 1px; }
.ms-empty { margin: 6px 8px; font-size: 12px; color: var(--ink-3); }
/* Count field: a [−] [ 20 ] [+] stepper, then the word "question(s)" beside it.
   No free typing — the arrows step the value, so users can't fat-finger a bad count. */
.mode-fields .ms-num { display: flex; flex-direction: row; align-items: center; gap: 9px;
  font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--ink-2); }
/* Minus/plus are a matched pair around the readout, sharing the dropdown surface so
   the whole control reads as one native dark-mode unit. */
.mode-fields .ms-step {
  flex: none; width: 36px; height: 36px; padding: 0; box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); color: var(--ink-1);
  font: inherit; font-size: 18px; font-weight: 600; line-height: 1;
  cursor: pointer; user-select: none; -webkit-user-select: none;
  -webkit-appearance: none; appearance: none; outline: none;
  transition: border-color .15s, background .15s, color .15s;
}
.mode-fields .ms-step:hover { border-color: var(--gold-2); color: var(--ink-0); }
.mode-fields .ms-step:active { background: var(--surface-2); }
.mode-fields .ms-step:focus-visible { border-color: var(--gold-2); outline: 2px solid var(--gold-2); outline-offset: 1px; }
.mode-fields .ms-step:disabled { color: var(--ink-4); border-color: var(--line); cursor: default; background: var(--surface-2); }
.mode-fields .ms-stepper { gap: 6px; }
/* The number readout borrows the exact surface/border/text of the .ms dropdown
   summary so it reads as a native dark-mode control (theme-aware vars adapt for
   light + dark). Width/alignment are set elsewhere and left untouched here. */
.mode-fields .ms-num input {
  width: 56px; flex: none; height: 36px; padding: 0 6px; box-sizing: border-box;
  text-align: center;
  border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); color: var(--ink-0);
  font: inherit; font-size: 12.5px; font-weight: 600;
  -webkit-appearance: none; appearance: none; outline: none;
  cursor: text;
  transition: border-color .15s, background .15s;
}
.mode-fields .ms-num input::-webkit-outer-spin-button,
.mode-fields .ms-num input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.mode-fields .ms-num input[type=number] { -moz-appearance: textfield; }
.mode-fields .ms-num input::placeholder { color: var(--ink-3); opacity: 1; }
.mode-fields .ms-num input:hover { border-color: var(--gold-2); }
.mode-fields .ms-num input:focus-visible { border-color: var(--gold-2); outline: 2px solid var(--gold-2); outline-offset: 1px; }
.mode-fields .ms-num input:disabled { background: var(--surface-2); color: var(--ink-4); border-color: var(--line); cursor: default; }
.ms-num-unit { font-size: 12.5px; font-weight: 600; color: var(--ink-2); text-transform: none; letter-spacing: 0; }

/* "Practice questions" bubble: a single bordered panel wrapping the three mode
   cards, with a label up top so it's clear this is where you start drilling. */
.practice-bubble {
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--sh-xs); padding: 18px 18px 20px;
}
.practice-bubble-head { margin: 2px 4px 14px; }
.practice-bubble-head h2 {
  font-family: var(--f-display); font-size: 18px; font-weight: 560;
  margin: 0 0 2px; color: var(--ink-0);
}
.practice-bubble-head p { margin: 0; font-size: 12.5px; }

/* Sudden Death shows its record inline as "Best streak: 3" - a single quiet line
   rather than a big KPI tile, so the card stays short. */
.sudden-best {
  margin: 8px 0 4px; font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  letter-spacing: .01em;
}
.sudden-best strong {
  font-family: var(--f-display); font-size: 15px; font-weight: 600;
  color: var(--gold); font-variant-numeric: tabular-nums;
}

/* Daily Review count: small "Pro" tag shown when the input is locked at 10. */
.daily-pro-tag { font-size: 10px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; margin-left: auto; }
.daily-count input:disabled { opacity: .55; cursor: not-allowed; }

/* ---------------------------------------------------------------------------
   TOPIC COVERAGE - dashboard rows: loaded / attempted / due (no accuracy)
   Owned by the dashboard. The Question Bank has its own .bcov-* table below.
--------------------------------------------------------------------------- */
/* Card header: title on the left, the dark "View question bank" CTA on the
   right - a primary action, not a text link. */
.coverage-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 16px;
}
.coverage-head h2 { margin: 0; }
/* Reuse the dark .btn-primary CTA, sized down to read as a header action. */
.coverage-cta { padding: 9px 16px; font-size: 13px; }

.cov-head, .cov-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 64px 88px 76px 132px;
  gap: 14px; align-items: center;
}
.cov-head {
  padding: 0 12px 10px; border-bottom: 1px solid var(--line);
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
  white-space: nowrap;
}
.cov-head span:not(:first-child):not(.cov-bar-h) { text-align: right; }
/* Clean hairline-separated rows (no zebra) keep the table calm and uncluttered. */
.cov-row {
  width: 100%; padding: 11px 12px; margin: 0; border: 0; border-bottom: 1px solid var(--line);
  border-radius: 0; background: none; cursor: pointer; text-align: left; font: inherit; color: inherit;
  transition: background .12s;
}
.cov-row:last-child { border-bottom: 0; }
.cov-row:hover { background: var(--accent-t); }
.cov-name {
  font-size: 13.5px; font-weight: 600; color: var(--ink-0);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cov-weight { font-size: 10.5px; font-weight: 500; color: var(--ink-3); margin-left: 2px; }
.cov-num { font-size: 13px; text-align: right; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.cov-due { color: var(--ink-3); }
.cov-due.has-due { color: var(--gold); font-weight: 700; }
/* % Correct column - tiered so weak/strong topics read at a glance. */
.cov-acc { color: var(--ink-3); font-weight: 600; }
.cov-acc.acc-low { color: #c0392b; font-weight: 700; }
.cov-acc.acc-mid { color: var(--gold); font-weight: 700; }
.cov-acc.acc-ok  { color: var(--ok); font-weight: 700; }
/* Coverage bar: subtle but visible empty track, dark ink fill animating to width. */
.cov-track {
  height: 7px; border-radius: 999px; background: var(--surface-2);
  box-shadow: inset 0 0 0 1px var(--line); overflow: hidden;
}
.cov-fill {
  display: block; height: 100%; border-radius: 999px; background: var(--ink-0);
  transition: width .5s cubic-bezier(.22,.61,.36,1);
}
@media (max-width: 620px) {
  .coverage-head { gap: 12px; }
  .coverage-cta { padding: 8px 13px; }
  .cov-head, .cov-row { grid-template-columns: minmax(0, 1fr) 48px 64px 56px; gap: 10px; }
  .cov-track, .cov-bar-h { display: none; }
}

/* ---------------------------------------------------------------------------
   BANK COVERAGE BY TOPIC - compact premium table (Question Bank page only).
   Namespaced .bcov-* so it never collides with the dashboard's .cov-* rows.
   One row per topic; every metric stays on a single horizontal line on desktop.
--------------------------------------------------------------------------- */
.bcov-rows { display: block; }
.bcov-head, .bcov-row {
  display: grid;
  grid-template-columns: minmax(220px, 1.8fr) 84px 78px 92px 88px 108px minmax(120px, 1fr);
  gap: 14px; align-items: center; white-space: nowrap;
}
.bcov-head {
  padding: 0 16px 9px; border-bottom: 1px solid var(--line);
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}
.bcov-head span:not(:first-child) { text-align: right; }
.bcov-row {
  padding: 14px 16px; border-bottom: 1px solid var(--line);
  font: inherit; color: inherit; transition: background .12s;
}
.bcov-row:last-child { border-bottom: 0; }
.bcov-row:hover { background: var(--accent-t); }
.bcov-name {
  font-size: 13.5px; font-weight: 600; color: var(--ink-0);
  overflow: hidden; text-overflow: ellipsis;
}
.bcov-weight-cell { text-align: right; }
.bcov-weight {
  display: inline-block; font-size: 10.5px; font-weight: 600; color: var(--accent);
  background: var(--accent-t); padding: 2px 8px; border-radius: 999px;
}
.bcov-num { font-size: 13px; text-align: right; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.bcov-due { color: var(--ink-3); }
.bcov-due.has-due { color: var(--gold); font-weight: 700; }
.bcov-score-cell { text-align: right; }
.bcov-score {
  display: inline-block; font-size: 11.5px; font-weight: 600; color: var(--ink-1);
  background: var(--surface-2); padding: 2px 9px; border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.bcov-score-none { font-size: 11px; color: var(--ink-4); font-style: italic; }
.bcov-track { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.bcov-fill { display: block; height: 100%; border-radius: 999px; background: var(--gold); transition: width .5s cubic-bezier(.22,.61,.36,1); }
/* Tablet/mobile: drop the rawest count columns, keep topic + loaded + score.
   Remaining children (1 Topic, 3 Loaded, 6 Score) fill the 3 grid tracks. */
@media (max-width: 720px) {
  .bcov-head, .bcov-row { grid-template-columns: minmax(0, 1fr) 64px 96px; gap: 10px; padding-left: 12px; padding-right: 12px; }
  .bcov-head > span:nth-child(2), .bcov-row > span:nth-child(2),
  .bcov-head > span:nth-child(4), .bcov-row > span:nth-child(4),
  .bcov-head > span:nth-child(5), .bcov-row > span:nth-child(5),
  .bcov-head > span:nth-child(7), .bcov-row > span:nth-child(7) { display: none; }
}

/* ---------------------------------------------------------------------------
   IMPORT - keep the upload path the focus; secondary methods collapse quietly
--------------------------------------------------------------------------- */
/* Page header: same identity treatment as the rest of the in-app pages, with a
   compact summary row directly under the subtitle so the bank count is the first
   thing the user sees - never buried at the foot of the page. */
.import-head { margin-bottom: 12px; }
.import-head h1 { font-size: clamp(24px, 3.4vw, 30px); margin-bottom: 4px; }
.import-head .muted { font-size: 15px; max-width: 60ch; }

.import-stat-row {
  display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px;
}
.import-stat {
  flex: 1 1 0; min-width: 140px;
  display: flex; flex-direction: column; gap: 4px;
  padding: 14px 18px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--sh-xs);
}
.import-stat strong {
  font-family: var(--f-display); font-size: 26px; font-weight: 600; line-height: 1;
  color: var(--ink-0); font-variant-numeric: tabular-nums;
}
.import-stat span {
  font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}

/* Main upload card: a premium surface in the spirit of the landing privacy card -
   clean border, soft shadow, generous, consistent padding. */
.import-upload-card { padding: 18px 26px 16px; box-shadow: var(--sh-sm); }
.import-upload-card .iu-head { margin-bottom: 10px; }
.import-upload-card .iu-head h2 { margin: 0 0 5px; }
.import-upload-card .iu-head .muted { font-size: 14.5px; line-height: 1.5; max-width: 62ch; margin: 0; }
.import-rights-note { margin: 7px 2px 11px; }
/* Consent gate: slimmer and vertically centred so the checkbox sits on one clean
   line with its label, not top-aligned against a tall padded box. */
.import-upload-card .rights-gate { flex-direction: row; align-items: center; padding: 9px 14px; margin-bottom: 12px; }
.import-upload-card .rights-gate input[type="checkbox"] { margin-top: 0; }
/* A cleaner square icon box (matching the landing icon boxes) rather than the
   generic circle, so the drop zone reads as deliberate, not empty. Drop-zone
   height kept tight (~25% shorter than the default) so the card never feels empty. */
.import-upload-card .upload-zone { padding: 11px 24px 10px; }
.import-upload-card .upload-zone-icon {
  width: 42px; height: 42px; border-radius: 12px;
  border: 1px solid var(--line-2); background: var(--surface-2); color: var(--ink-0);
  margin-bottom: 10px;
}
.import-upload-card .upload-zone h3 { margin: 0 0 4px; }
.import-upload-card .uz-formats { margin-top: 10px; }
.import-upload-card .uz-choose { margin-top: 12px; }
.import-upload-card .upload-zone:hover .upload-zone-icon,
.import-upload-card .upload-zone.drag-over .upload-zone-icon {
  border-color: var(--gold-2); color: var(--gold);
}
/* Reserve fixed space for the helper text (two lines) so swapping between the
   "Confirm the box above..." and "PDF, Word, CSV..." strings never changes the
   drop-zone height when the consent box is ticked. */
.import-upload-card .upload-zone p {
  font-size: 13.5px; line-height: 1.45; color: var(--ink-3); max-width: 46ch; margin: 0 auto;
  min-height: 2.9em; display: flex; align-items: center; justify-content: center;
}

/* App shell: full-bleed with the same 56px side gutter as the dashboard, so the
   nav brand lines up with the page content exactly (the body left edge matches
   the nav left edge at every width, never a narrow centred column floating mid-
   page). Matches the dashboard's content grid. */
body.import-page .home-wrap,
body.bank-page .home-wrap,
body.privacy-page .home-wrap,
body.terms-page .home-wrap { max-width: none; width: 100%; margin: 0; padding: 20px 56px 0; }
@media (max-width: 640px) {
  body.import-page .home-wrap,
  body.bank-page .home-wrap,
  body.privacy-page .home-wrap,
  body.terms-page .home-wrap { padding: 16px 16px 0; }
}

/* Use the dashboard's compact footer here instead of the centred base footer:
   disclaimer (with brand mark) left, Privacy/Terms far right, aligned to the
   page content width. The base site-foot is hidden so only this one renders.
   Sticky-footer layout: the home-wrap is a full-height flex column and the
   footer's margin-top:auto pushes it to the bottom when content is short, so it
   never floats halfway up the page. */
body.import-page .site-foot,
body.bank-page .site-foot,
body.privacy-page .site-foot,
body.terms-page .site-foot { display: none; }
/* The footer follows the page content in natural flow (not fixed/sticky): it sits
   just below the last card with a small, quiet gap, so it never floats halfway up
   the page nor leaves a large void above it on this content-heavy page. */
/* Sticky-footer column: the wrapper fills the viewport below the 56px sticky nav,
   so the footer's margin-top:auto pins it to the bottom of the screen when the page
   content is short, and it simply follows the content when the page is tall. No
   bottom padding/min-height void is left under the bar. */
body.import-page .home-wrap,
body.bank-page .home-wrap,
body.privacy-page .home-wrap {
  display: flex; flex-direction: column;
  min-height: calc(100dvh - 56px);
}

/* Full-bleed footer bar that mirrors the header: the outer <footer> breaks out of
   the home-wrap's 56px side padding (negative margins) so its border-top and
   background span the whole viewport width, exactly like the sticky nav. The
   inner grid then re-applies the same 56px gutter, so the brand mark lands
   directly under the header logo and the links under the right-side nav controls.
   margin-top:auto pins the bar to the bottom of the viewport when content is short. */
.import-foot {
  margin-top: auto;
  margin-left: -56px; margin-right: -56px;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
.import-foot-inner {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 24px;
  padding: 8px 56px;
}
/* Brand mark on the left, mirroring the nav lockup (gold a + "Drill"), followed by
   a short muted-gold separator so it reads as one quiet lockup tied to the
   disclaimer rather than a detached label. */
.import-foot-mark {
  display: inline-flex; align-items: center; gap: 14px;
  white-space: nowrap; font-family: var(--f-display);
  font-weight: 560; font-size: 13px; color: var(--ink-2); letter-spacing: -0.01em;
}
/* The α + "Drill" are one tight lockup (gap:0, like the header brand), so they read
   as a single wordmark; the muted-gold separator (::after) follows the full logo. */
.import-foot-logo {
  display: inline-flex; align-items: baseline; gap: 0;
  font-family: var(--f-display);
}
.import-foot-mark::after {
  content: ""; width: 1px; height: 13px;
  background: var(--gold-2); opacity: .6;
}
.import-foot-mark .brand-a {
  color: var(--gold); font-weight: 700; font-style: normal;
  font-size: 1.4em; line-height: 1; vertical-align: baseline; margin-right: 1px;
}
.import-foot-mark .brand-word {
  font-weight: 560; font-size: 13px; color: var(--ink-1); letter-spacing: -0.02em;
}
/* Disclaimer fills the middle column; two sentences split by a <br>, left-aligned
   and quiet, never centred or cramped. */
.import-foot .import-foot-note {
  margin: 0; min-width: 0; font-size: 11px; line-height: 1.6;
  color: var(--ink-3); text-align: left; white-space: normal;
}
/* Match the home-wrap's tighter mobile gutter so the bar stays full-bleed. */
@media (max-width: 640px) {
  .import-foot { margin-left: -16px; margin-right: -16px; }
  .import-foot-inner { padding-left: 16px; padding-right: 16px; }
}

/* ===== Privacy page ======================================================
   Reuses the Import/Bank app shell (full-bleed 56px gutter + compact footer)
   so it reads as part of the same product. The body is a scannable three-up
   summary, a full-width lead, a balanced 2x2 grid of compact sections, then a
   prominent data-control card - far shorter than the old single stacked column
   of full-width cards. Cream surfaces, navy ink, muted-gold accents only. */
/* Header reuses the Dashboard's navy hero (.exam-countdown / .ec-id): same gold
   display title, cream subtitle, padding and shadow, so Privacy reads as part of
   the same product. The base .exam-countdown + .ec-h rules already supply the navy
   gradient and gold title; these mirror the .dash-page row layout and subtitle. */
.privacy-page .exam-countdown {
  display: flex; flex-direction: row; align-items: center; flex-wrap: wrap;
  gap: 14px 28px; margin: 0 0 18px; padding: 14px 24px;
  box-shadow: 0 14px 30px -18px rgba(8, 12, 24, 0.6);
}
.privacy-page .ec-title {
  font-family: var(--f); font-size: 13px; font-weight: 500; letter-spacing: .015em;
  color: rgba(244, 239, 230, 0.82); margin: 0;
}

/* Top summary: three at-a-glance assurances, gold top-rule on each. */
.privacy-summary {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 18px;
}
@media (max-width: 760px) { .privacy-summary { grid-template-columns: 1fr; } }
.privacy-sum-cell {
  display: flex; flex-direction: column; gap: 6px; padding: 15px 18px;
  background: var(--surface); border: 1px solid var(--line);
  border-top: 2px solid var(--gold-2); border-radius: 12px; box-shadow: var(--sh-xs);
}
.privacy-sum-cell strong {
  font-family: var(--f-display); font-size: 14.5px; font-weight: 600; color: var(--ink-0);
}
.privacy-sum-cell span { font-size: 13px; line-height: 1.5; color: var(--ink-2); }

/* Balanced 2x2 grid of compact section cards (consistent width, border, radius). */
.privacy-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px; align-items: stretch; margin-bottom: 16px;
}
@media (max-width: 760px) { .privacy-grid { grid-template-columns: 1fr; } }
.privacy-card { padding: 18px 22px; }
.privacy-card h2 { font-size: 17px; margin: 0 0 10px; }
.privacy-card p { font-size: 14px; line-height: 1.55; margin: 0; }
.privacy-card p + p, .privacy-card .fine { margin-top: 10px; }
.privacy-lead { margin-bottom: 16px; }
.privacy-lead p { max-width: 92ch; }

.privacy-list { margin: 0; padding-left: 18px; }
.privacy-list li { font-size: 14px; line-height: 1.5; margin-bottom: 5px; color: var(--ink-1); }
.privacy-list li:last-child { margin-bottom: 0; }

/* Third-party providers: term + short description in two tidy columns. */
.privacy-rows { list-style: none; margin: 0; padding: 0; }
.privacy-rows li {
  display: grid; grid-template-columns: 170px 1fr; gap: 14px;
  padding: 10px 0; border-top: 1px solid var(--line);
  font-size: 13.5px; line-height: 1.5;
}
.privacy-rows li:first-child { border-top: 0; padding-top: 2px; }
.privacy-rows li strong { color: var(--ink-0); font-weight: 600; }
.privacy-rows li span { color: var(--ink-2); }
@media (max-width: 520px) { .privacy-rows li { grid-template-columns: 1fr; gap: 2px; } }

/* Processing table: Data / Purpose / Lawful basis / Retention. Cream surface,
   navy ink, a quiet gold header rule - reads as a premium SaaS data table, not a
   raw spreadsheet. Scrolls horizontally on narrow screens rather than crushing. */
.privacy-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.privacy-table {
  width: 100%; border-collapse: collapse; font-size: 13px; line-height: 1.5;
  min-width: 560px;
}
.privacy-table thead th {
  text-align: left; font-family: var(--f-display); font-size: 11px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2);
  padding: 0 14px 9px; border-bottom: 2px solid var(--gold-2); white-space: nowrap;
}
.privacy-table tbody td {
  padding: 11px 14px; border-bottom: 1px solid var(--line);
  color: var(--ink-1); vertical-align: top;
}
.privacy-table tbody tr:last-child td { border-bottom: 0; }
.privacy-table tbody td:first-child { color: var(--ink-0); font-weight: 600; white-space: nowrap; }
.privacy-table-note { margin-top: 12px; }

/* Prominent, full-width data-control card. */
.privacy-data-card { padding: 20px 24px; margin-bottom: 16px; }
.privacy-data-card .pd-head h2 { margin: 0 0 4px; }
.privacy-data-card .pd-head .muted { margin: 0; font-size: 14px; }
.privacy-data-card .pd-actions { display: flex; gap: 12px; flex-wrap: wrap; margin: 14px 0 0; }
.privacy-data-card .msg { font-size: 13.5px; margin: 10px 0 0; }
.privacy-data-card .fine { margin-top: 10px; }

.privacy-contact { padding: 16px 22px; margin-bottom: 8px; }
.privacy-contact h2 { font-size: 17px; margin: 0 0 6px; }
.privacy-contact p { font-size: 14px; margin: 0; }

/* Footer: sticky to the bottom of the viewport and visually identical to the
   Dashboard/Import bar. The page scrolls, so - like the Q Bank - we fix the
   compact bar to the bottom with an opaque background + border, reserve bottom
   space on the wrap, and re-apply the dashboard's exact 56px inner inset + 24px
   gap + 8px vertical padding, so the Privacy/Terms links land in exactly the same
   place as on the Dashboard and Import bars. */
body.privacy-page .home-wrap,
body.terms-page .home-wrap {
  min-height: auto;          /* fixed footer is out of flow - no flex-fill needed */
  padding-bottom: 68px;      /* clear the fixed bar so the last card stays visible */
}
body.privacy-page .import-foot,
body.terms-page .import-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  margin: 0;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
body.privacy-page .import-foot-inner,
body.terms-page .import-foot-inner { padding: 8px 56px; gap: 24px; }

/* ===== Terms page ========================================================
   Same full-bleed width + 56px gutter as the Privacy/Import pages (see the
   shared .home-wrap rule above), reusing the Privacy card system - summary
   cells, a compact two-column clause grid, and a full-width closing card.
   Unnumbered headings + tight, even spacing keep it reading as a product
   terms page, not a stacked legal contract. */
/* Title block matches the Privacy / Q Bank pages exactly: same 20px wrap top
   padding (inherited from the shared rule above) and the same compact gap below
   the heading, so the H1 lands in the identical position when toggling between
   Q Bank, Privacy and Terms - nothing shifts. */
.terms-page .page-head { margin-bottom: 16px; }
.terms-updated { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-3); }

.terms-summary { margin-bottom: 16px; }

/* Compact two-column clause grid (one column on mobile, via .privacy-grid).
   Stretch keeps paired cards level; slightly tighter padding than Privacy. */
.terms-grid { margin-bottom: 16px; gap: 14px; align-items: stretch; }
.terms-card { padding: 15px 18px; }
.terms-card h2 { font-size: 15.5px; line-height: 1.3; margin: 0 0 7px; }
.terms-card p { font-size: 13.5px; line-height: 1.55; margin: 0; color: var(--ink-1); }

/* Full-width closing card: IP, liability and contact in one calm block. */
.terms-contact { padding: 18px 22px; margin-bottom: 8px; }
.terms-contact h2 { font-size: 16px; margin: 0 0 10px; }
.terms-contact p { font-size: 13.5px; line-height: 1.6; margin: 0; color: var(--ink-1); }
.terms-contact p + p { margin-top: 9px; }
.terms-contact .tc-meta { margin: 12px 0 0; display: flex; flex-wrap: wrap; gap: 4px 28px; }
.terms-contact .tc-meta span { display: block; }
.terms-contact .tc-meta strong { color: var(--ink-0); font-weight: 600; }

/* Main section: upload card (wide, left) beside the right column (narrow). */
.import-main {
  display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: 20px; align-items: start; margin-bottom: 4px;
}
@media (max-width: 860px) { .import-main { grid-template-columns: 1fr; } }

/* Right column: bank card stacked over the secondary-actions card. Its top edge
   aligns with the upload card (both are grid cells with align-items:start), and
   both cards share the column width. */
.import-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.import-side > .card { width: 100%; }

/* Bank management card: sits in the narrow right column, so it stacks - count,
   then a full-width primary "View question bank", then the quiet danger link. */
.import-bank-card { display: flex; flex-direction: column; gap: 14px; }
/* Header row: title left, quiet "delete all" pinned to the top-right corner. */
.import-bank-card .ib-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
}
.import-bank-card .ib-head h2 { margin: 0; }
.import-bank-card .ib-count { margin: 0; font-size: 14px; color: var(--ink-2); }
.import-bank-card .ib-count strong { color: var(--ink-0); font-variant-numeric: tabular-nums; }
/* "Delete all" - small, muted red outline; sits in the header corner, never below the CTA. */
.import-bank-card .ib-delete {
  flex: none; padding: 4px 10px; font-size: 12px; line-height: 1.2;
  border-radius: 999px; opacity: .8;
}
.import-bank-card .ib-delete:hover { opacity: 1; }
/* Primary action: full-width navy CTA in the body of the card. */
.import-bank-card .ib-cta { width: 100%; justify-content: center; text-align: center; }

.import-collapse { padding: 0; margin-bottom: 12px; overflow: hidden; }
.import-collapse > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 20px;
  font-family: var(--f-display);
  font-size: 17px;
  font-weight: 560;
  color: var(--ink-0);
}
.import-collapse > summary::-webkit-details-marker { display: none; }
.import-collapse > summary::after {
  content: "+";
  margin-left: auto;
  font-family: var(--f);
  font-size: 22px;
  font-weight: 300;
  line-height: 1;
  color: var(--ink-3);
}
.import-collapse[open] > summary::after { content: "\2013"; }
.import-collapse[open] > summary { border-bottom: 1px solid var(--line); }
.import-collapse > summary:hover { color: var(--gold); }
.import-collapse > summary:focus-visible { outline: 2px solid var(--gold-2); outline-offset: -2px; }
.import-collapse-body { padding: 18px 20px 20px; }

/* "Choose files" affordance inside the upload zone (visual only - the invisible
   file input overlay above it captures the click). */
.uz-choose {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: 16px; padding: 9px 20px;
  border-radius: 6px; border: 1px solid var(--ink-0);
  background: var(--ink-0); color: var(--surface);
  font-family: var(--f); font-size: 13.5px; font-weight: 600; letter-spacing: .01em;
}
.upload-zone.disabled .uz-choose {
  background: var(--surface-2); border-color: var(--line-2); color: var(--ink-4);
}

/* Compact processing status + progress bar */
.import-status { margin-top: 16px; }
.import-status-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 14px; margin-bottom: 8px;
}
.import-status-file {
  font-size: 13.5px; font-weight: 600; color: var(--ink-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.import-status-count {
  font-size: 12.5px; color: var(--ink-3); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.import-progress { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.import-progress > span {
  display: block; height: 100%; width: 0; border-radius: 999px;
  background: var(--gold); transition: width .25s ease;
}

/* one-line privacy note beneath the upload card */
.import-foot-note { margin: 12px 2px 0; }

/* "Other ways to add questions": a card in the right column holding the two
   secondary input methods as compact stacked rows (each a quiet accordion that
   expands on click, with a + / - affordance on the right). */
.import-more-card { padding: 22px 24px; }
.import-more-title { margin: 0; font-family: var(--f-display); font-size: 17px; font-weight: 560; color: var(--ink-0); }
.import-collapse--row {
  margin: 0; padding: 0; border: 0; border-radius: 0; box-shadow: none;
  background: transparent; border-top: 1px solid var(--line); overflow: visible;
}
.import-collapse--row:first-of-type { margin-top: 8px; }
.import-collapse--row > summary { padding: 14px 0; }
.import-collapse--row[open] > summary { border-bottom: 0; }
.import-collapse--row .import-collapse-body { padding: 2px 0 16px; }
.import-collapse > summary .ic-text { display: flex; flex-direction: column; gap: 2px; }
.import-collapse > summary .ic-title {
  font-family: var(--f-display); font-size: 16px; font-weight: 560; color: var(--ink-0); line-height: 1.2;
}
.import-collapse > summary .ic-sub {
  font-family: var(--f); font-size: 12.5px; font-weight: 400; color: var(--ink-3);
}

/* ===========================================================================
   GUIDED IMPORT FLOW - step indicator, uploaded-file list, success panel,
   compact review rows and the sticky add bar. Restrained, premium, themed.
=========================================================================== */

/* --- 3-step progress indicator --- */
.import-steps {
  display: flex; align-items: center; gap: 8px;
  list-style: none; margin: 0 0 16px; padding: 0;
  font-family: var(--f);
}
.import-steps .is-step {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  color: var(--ink-4); font-size: 13px; font-weight: 500; white-space: nowrap;
}
.import-steps .is-step:not(:last-child)::after {
  content: ""; flex: 1 1 14px; min-width: 14px; height: 1px;
  background: var(--line-2); margin-left: 2px;
}
.import-steps .is-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 999px; flex: none;
  border: 1px solid var(--line-2); background: var(--surface);
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--ink-3);
}
.import-steps .is-current { color: var(--ink-0); }
.import-steps .is-current .is-num {
  border-color: var(--ink-0); background: var(--ink-0); color: var(--surface);
}
.import-steps .is-done { color: var(--ink-2); }
.import-steps .is-done .is-num {
  border-color: var(--gold-2); background: var(--gold-2); color: var(--surface);
}
@media (max-width: 560px) {
  .import-steps .is-step .is-label { display: none; }
  .import-steps .is-current .is-label { display: inline; }
}

/* --- uploaded file list --- */
.file-list { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.file-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); box-shadow: var(--sh-xs);
}
.file-row .fl-icon {
  display: inline-flex; flex: none; width: 30px; height: 30px;
  align-items: center; justify-content: center; border-radius: 8px;
  background: var(--surface-2); color: var(--ink-2);
}
.file-row .fl-icon svg { width: 16px; height: 16px; }
.file-row .fl-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.file-row .fl-name {
  font-size: 13.5px; font-weight: 600; color: var(--ink-0);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.file-row .fl-meta { font-size: 11.5px; color: var(--ink-3); letter-spacing: .02em; }
.fl-status {
  flex: none; font-size: 11.5px; font-weight: 600; padding: 3px 10px;
  border-radius: 999px; white-space: nowrap;
  background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line);
}
.fl-status.fl-parsed { background: var(--ok-bg); color: var(--ok); border-color: transparent; }
.fl-status.fl-error { background: var(--bad-bg); color: var(--bad); border-color: transparent; }
.fl-status.fl-processing { color: var(--gold); border-color: var(--gold-2); }
.file-row .fl-remove {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 8px; border: 0; cursor: pointer;
  background: transparent; color: var(--ink-3); transition: background .12s, color .12s;
}
.file-row .fl-remove svg { width: 15px; height: 15px; }
.file-row .fl-remove:hover { background: var(--bad-bg); color: var(--bad); }

/* --- success panel (above the review list) --- */
.success-panel {
  border: 1px solid var(--gold-2); border-radius: 12px;
  background: linear-gradient(180deg, var(--surface), var(--surface-2));
  padding: 16px 18px; margin-bottom: 18px; box-shadow: var(--sh-xs);
}
.success-panel .sp-head { display: flex; align-items: center; gap: 12px; }
.success-panel .sp-check {
  display: inline-flex; flex: none; width: 30px; height: 30px;
  align-items: center; justify-content: center; border-radius: 999px;
  background: var(--ok); color: #fff;
}
.success-panel .sp-check svg { width: 17px; height: 17px; }
.success-panel .sp-stats {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px;
  font-size: 14px; color: var(--ink-2);
}
.success-panel .sp-stat strong {
  font-family: var(--f-display); font-size: 20px; font-weight: 600;
  color: var(--ink-0); font-variant-numeric: tabular-nums; margin-right: 4px;
}
.success-panel .sp-review strong { color: var(--warn); }
.success-panel .sp-ready strong { color: var(--ok); }
/* Clickable counts (Ready / Needs review) - look like the surrounding text but
   underline on hover so it's clear they jump to a filtered view. */
.success-panel .sp-link {
  border: 0; background: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: inherit; text-decoration: none;
  border-bottom: 1px dashed transparent; transition: border-color .12s;
}
.success-panel .sp-link:hover { border-bottom-color: currentColor; }
.success-panel .sp-link:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; border-radius: 3px; }
.success-panel .sp-link.sp-link-off { cursor: default; pointer-events: none; }
.success-panel .sp-note { font-size: 13px; line-height: 1.5; margin: 12px 0 14px; max-width: 64ch; }
.success-panel .sp-actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* --- review filter chips (all / ready / needs review) --- */
.review-filters { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.review-filters .rf-chip {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 6px 13px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink-2);
  font-family: var(--f); font-size: 13px; font-weight: 500; transition: all .12s;
}
.review-filters .rf-chip:hover { border-color: var(--ink-3); color: var(--ink-0); }
.review-filters .rf-chip .rf-count {
  font-size: 11.5px; font-weight: 600; font-variant-numeric: tabular-nums;
  padding: 1px 7px; border-radius: 999px; background: var(--surface-2); color: var(--ink-2);
}
.review-filters .rf-chip.is-active {
  border-color: var(--ink-0); background: var(--ink-0); color: var(--surface);
}
.review-filters .rf-chip.is-active .rf-count { background: rgba(255,255,255,.18); color: var(--surface); }
.review-filters .rf-chip-review .rf-count { background: var(--warn-bg); color: var(--warn); }
.review-filters .rf-chip-review.is-active { border-color: var(--warn); background: var(--warn); color: #fff; }
.review-filters .rf-chip-review.is-active .rf-count { background: rgba(255,255,255,.22); color: #fff; }
/* Pulse when a filter is applied via a success-panel/CTA click, so the user
   sees the list react to what they pressed. */
.review-filters.rf-flash { animation: rfFlash 1.1s ease-out 1; }
@keyframes rfFlash {
  0% { box-shadow: 0 0 0 3px var(--warn-line); }
  100% { box-shadow: 0 0 0 3px transparent; }
}
.review-empty { font-size: 14px; color: var(--ink-3); padding: 16px 2px; }

/* CSS-only filtering: hide the rows that don't match the active chip. */
#reviewList[data-filter="ready"] .rev-card.is-flagged { display: none; }
#reviewList[data-filter="review"] .rev-card:not(.is-flagged) { display: none; }

/* --- review toolbar (above the list) --- */
.review-toolbar {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 16px;
}
.review-toolbar .btn-link { font-size: 13px; }
.review-toolbar #commitBtn { margin-left: auto; }

/* --- compact parsed-question rows --- */
.rev-card > summary {
  align-items: flex-start; gap: 12px; padding: 11px 14px;
}
/* Custom tick box (the global input rule strips the native checked indicator, so
   without this a ticked row reads as an empty circle). Fills ink with a crisp
   white check when selected, so "ticked" is unmistakable. */
.rev-card .rev-keep {
  appearance: none; -webkit-appearance: none;
  flex: none; margin-top: 2px; width: 18px; height: 18px; cursor: pointer;
  border: 1.5px solid var(--line-2) !important; border-radius: 6px !important;
  background: var(--surface); display: inline-grid; place-content: center;
  padding: 0 !important; transition: background .14s, border-color .14s;
}
.rev-card .rev-keep::after {
  content: ""; width: 11px; height: 11px; transform: scale(0);
  transition: transform .14s cubic-bezier(.22,.61,.36,1); background-color: #fff;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / contain no-repeat;
}
.rev-card .rev-keep:hover { border-color: var(--ink-3) !important; }
.rev-card .rev-keep:checked { background: var(--ink-0); border-color: var(--ink-0) !important; }
.rev-card .rev-keep:checked::after { transform: scale(1); }
.rev-card .rev-keep:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
/* On a flagged row, a manual tick fills amber so it stays legible on the wash. */
.rev-card.is-flagged .rev-keep:checked { background: var(--warn); border-color: var(--warn) !important; }
.rev-card .rev-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 1 1 auto; }
.rev-card .rev-stem {
  font-size: 13.5px; font-weight: 500; color: var(--ink-1); line-height: 1.45;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.rev-card .rev-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.rev-card .rev-flag { font-size: 11.5px; font-weight: 500; color: var(--warn); }
.rev-card .conf-pill { color: var(--ink-3); }
.rev-card .chip-complete { background: var(--ok-bg); color: var(--ok); border-color: transparent; }
.rev-card .chip-review { background: var(--warn-bg); color: var(--warn); border-color: transparent; }
/* Subtle amber wash + left accent so flagged rows read as "review me" without
   shouting. They sort to the top of the list (see import.js order). */
.rev-card.is-flagged { border-color: var(--warn-line); background: var(--warn-bg); }
.rev-card.is-flagged > summary { border-left: 3px solid var(--warn); padding-left: 11px; }
.rev-card.is-selected { border-color: var(--gold-2); box-shadow: 0 0 0 1px var(--gold-2) inset; }
.rev-card.is-selected > summary { background: var(--surface-2); }
.rev-card.is-flagged.is-selected > summary { background: transparent; }

/* --- add bar (lives in the fixed bottom dock, above the disclaimer) --- */
.sticky-bar {
  display: flex; align-items: center; justify-content: flex-end; gap: 16px;
  padding: 12px 18px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); box-shadow: 0 -4px 16px rgba(20,15,5,.08);
}
.sticky-bar .sb-count { font-size: 13.5px; color: var(--ink-2); margin-right: auto; }
.sticky-bar .sb-count strong { color: var(--ink-0); font-variant-numeric: tabular-nums; }

/* --- fixed bottom dock: pins the disclaimer footer (always visible, compliance)
   with the add bar stacked directly above it. Opaque so page content scrolls
   cleanly behind it; .import-flow gets matching bottom padding from import.js. --- */
.import-dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--bg);
}
.import-dock .sticky-bar { margin: 10px 56px 12px; }
.import-dock .import-foot { margin: 0; }   /* override the full-bleed negative margins */
@media (max-width: 640px) {
  .import-dock .sticky-bar { margin: 8px 16px 10px; }
}

/* ===========================================================================
   DARK MODE - same ink/bone/gold point of view, inverted. Driven by a
   data-theme="dark" attribute on <html> (set before paint by an inline script
   in base.html, toggled from the nav). We override the SAME design tokens lux
   already remaps, so the whole app recolours from one place. Charts read these
   tokens at runtime (see dashboard.js), so they follow the theme automatically.
=========================================================================== */
:root[data-theme="dark"] {
  --ink-0: #f5f0e4;   /* bone - display text */
  --ink-1: #e7e2d4;   /* body */
  --ink-2: #b7bfd0;   /* secondary */
  --ink-3: #8a93a8;   /* muted */
  --ink-4: #5e6884;   /* placeholder */

  --bg:        #0a0e1b;
  --surface:   #121829;
  --surface-2: #1a2133;
  --surface-3: #232c42;
  --line:      #29324b;
  --line-2:    #3a4768;
  --cal-grey:      #2b3242;
  --cal-grey-line: #3c455c;
  --cal-hatch: repeating-linear-gradient(45deg, transparent 0, transparent 4px, rgba(255,255,255,.05) 4px, rgba(255,255,255,.05) 5px);

  /* primary interactive = bone (a light button on dark reads premium) */
  --accent:    #f0ead9;
  --accent-d:  #d9d2bf;
  --accent-t:  rgba(240,234,217,.06);
  --accent-t2: rgba(240,234,217,.14);

  /* gold brightened so it stays AA on the dark surface */
  --gold:    #cda85f;
  --gold-2:  #e0c489;
  --gold-t:  rgba(205,168,95,.14);

  --ok:  #5fb288;  --ok-bg: rgba(95,178,136,.14);
  --bad: #db7a55;  --bad-bg: rgba(219,122,85,.14);
  --warn: #e0b25f;  --warn-bg: rgba(224,178,95,.15);  --warn-line: rgba(224,178,95,.40);

  --sh-xs: 0 1px 2px rgba(0,0,0,.35);
  --sh-sm: 0 4px 14px rgba(0,0,0,.40);
  --sh-md: 0 24px 60px -28px rgba(0,0,0,.70);
}
/* in dark, a light button needs dark ink text (not the dark surface) */
:root[data-theme="dark"] .btn-primary,
:root[data-theme="dark"] .hero-cta { color: var(--bg) !important; }
/* tone the paper grain right down so it isn't visible speckle on dark */
:root[data-theme="dark"] body:not(.exam-body)::before { opacity: .12; }
/* these cards hardcoded a bone gradient; repoint them at the token */
:root[data-theme="dark"] .status-card,
:root[data-theme="dark"] .readiness-card,
:root[data-theme="dark"] .home-hero {
  background: linear-gradient(160deg, var(--surface-2) 0%, var(--surface) 70%);
}
:root[data-theme="dark"] .bank-tabs { background: rgba(10,14,27,.86); }

/* ---- theme toggle button (injected into the nav by profile.js) ---- */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; margin-left: 8px; padding: 0;
  border: 1px solid var(--line-2); border-radius: 999px;
  background: var(--surface); color: var(--ink-2);
  cursor: pointer; transition: color .15s, border-color .15s, transform .15s;
}
.theme-toggle:hover { color: var(--gold); border-color: var(--gold-2); transform: translateY(-1px); }
.theme-toggle:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.theme-toggle svg { width: 17px; height: 17px; }

/* ---- premium-mode (crown) toggle ----
   Shares the exact .theme-toggle shape (34px, fully rounded, same padding) so it
   reads as one control group with the moon. The crown is always gold — gold icon
   inside a gold-outlined button — so the Pro symbol never looks like a stray grey
   glyph. Active premium state is shown with a subtle champagne fill on top. */
.premium-toggle { color: var(--gold); border-color: var(--gold-2); }
.premium-toggle:hover { color: var(--gold); border-color: var(--gold); transform: translateY(-1px); }
.premium-toggle.on { background: var(--gold-t); border-color: var(--gold); }
.premium-toggle.on:hover { color: var(--gold); }
/* Premium pill: the crown toggle now also names itself "Pro mode". It widens from
   the 34px circle into a pill that wraps the crown + label, keeping the same
   height, gold ring, and champagne-on fill so it stays one of the cluster. */
.premium-pill {
  width: auto; gap: 6px; padding: 0 13px 0 11px;
  font-family: var(--f); font-size: 10.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; line-height: 1;
}
.premium-pill .pro-crown { width: 13px; height: 13px; flex: none; }
.premium-pill .premium-label { white-space: nowrap; }
/* Tighten the moon + crown into one visual cluster with even spacing. */
.bank-tabs .theme-toggle { margin-left: 7px; }
/* The right-hand cluster (moon · crown · countdown · level) is anchored to the
   far right as one group: the auto margin starts at the FIRST toggle, not the
   profile slot, so the toggles no longer strand themselves mid-bar. */
.bank-tabs .theme-toggle:first-of-type { margin-left: auto; }
.bank-tabs .nav-profile-slot { margin-left: 8px; }

/* All four right-cluster controls (moon · crown · countdown · level) must read as
   the same complete, even, solid outline. The pills have long straight top/bottom
   edges (unlike the moon's all-curve circle); on the translucent, backdrop-blurred
   nav a 1px hairline *border* along a straight edge anti-aliases unevenly and the
   lower edge reads as faded. So we drop the border and draw the ring with a crisp
   1px inset box-shadow instead, which rasterises evenly all the way around. Applied
   identically to the moon so the whole cluster matches. flex:none keeps the pills
   from being squashed out of shape in the crowded row. */
.bank-tabs .theme-toggle,
.bank-tabs .premium-toggle,
.bank-tabs .nav-countdown,
.bank-tabs .profile-chip {
  box-sizing: border-box; flex: none;
  border: 0 !important;
  box-shadow: inset 0 0 0 1px var(--line-2) !important;
}
.bank-tabs .premium-toggle { box-shadow: inset 0 0 0 1px var(--gold-2) !important; }
.bank-tabs .theme-toggle:hover,
.bank-tabs .nav-countdown:hover,
.bank-tabs .profile-chip:hover { box-shadow: inset 0 0 0 1px var(--gold-2) !important; }
.bank-tabs .premium-toggle:hover { box-shadow: inset 0 0 0 1px var(--gold) !important; }
.bank-tabs .premium-toggle.on { box-shadow: inset 0 0 0 1px var(--gold) !important; }
/* Free version: a refined gold "Upgrade to Pro mode" CTA. A soft top-down gold
   gradient (light glint at the top easing into the deeper gold) gives it a subtle
   shine rather than a flat, harsh slab; a faint inner highlight + soft drop shadow
   lift it off the glass nav. White text/crown. */
.bank-tabs .premium-toggle.premium-upgrade,
.premium-toggle.premium-upgrade {
  background: linear-gradient(180deg, var(--gold-2) 0%, var(--gold) 130%) !important;
  color: #fff !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14),
              inset 0 0 0 1px rgba(155,122,60,.4) !important;
}
.bank-tabs .premium-toggle.premium-upgrade:hover,
.premium-toggle.premium-upgrade:hover {
  filter: brightness(1.04);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18),
              inset 0 0 0 1px rgba(155,122,60,.5) !important;
}
.premium-toggle.premium-upgrade .pro-crown,
.premium-toggle.premium-upgrade .premium-label { color: #fff !important; }

/* ---------------------------------------------------------------------------
   MOBILE NAV (phones <= 760px). theme.css's abandoned bottom-bar experiment
   stretched every .bank-tabs <a> to flex:1 / column and left the right-hand
   control cluster (level pill, Pro, countdown, moon) unmanaged, so it spilled
   past the viewport to ~614px and the whole site could be dragged sideways.

   This block (the last-loaded, winning layer) rebuilds the nav as a clean
   two-row app header:
     row 1  | brand (top-left) ......... level + countdown + Pro + moon (top-right)
     row 2  | Dashboard  Import  Q Bank  (the tabs, left-aligned)
   flex `order` lets the controls sit on row 1 (ahead of the tabs in DOM order)
   while the brand's auto right-margin pushes them to the right edge, with the
   moon pinned last so it lands in the top-right corner. */
@media (max-width: 760px) {
  .bank-tabs {
    flex-wrap: wrap;
    height: auto;
    min-height: 52px;
    row-gap: 8px;
    column-gap: 6px;
    padding: 10px 16px;
    align-items: center;
  }
  /* Undo the bottom-bar stretching: nav tabs read as inline pills again. The
     more-specific .bank-tabs .brand / .profile-chip rules above are unaffected. */
  .bank-tabs a {
    flex: 0 0 auto;
    flex-direction: row;
    min-height: 0;
    height: 32px;
    padding: 0 12px;
    font-size: 13.5px;
    text-align: left;
  }
  /* Row 1, far left. The auto right-margin claims all free space on its line,
     shoving every control to the right edge; the tabs (order 5) fall to row 2. */
  .bank-tabs .brand { order: 0; margin-right: auto; margin-left: 0; }
  /* Row 1 right cluster, in reading order: level chip, countdown, Pro, then moon
     pinned to the far corner. */
  .bank-tabs .nav-profile-slot {
    order: 1; flex: 0 0 auto; margin-left: 0;
    display: flex; align-items: center; gap: 6px;
  }
  .bank-tabs .premium-toggle { order: 2; }
  .bank-tabs .theme-toggle:not(.premium-toggle) { order: 3; margin-left: 0; }
  /* Row 2: the three section tabs, left-aligned beneath the brand. */
  .bank-tabs > a:not(.brand) { order: 5; }
  /* Drop the long labels so pills shrink to crown/number and never overflow. */
  .bank-tabs .premium-label,
  .bank-tabs .nav-countdown .ncd-label { display: none; }
  .bank-tabs .premium-pill { padding: 0 9px; }

  /* ----- Compact footer. The legal disclaimer (.import-foot-note) was squeezed
     into a narrow middle grid column and wrapped into ~half a screen. Stack the
     footer into one full-width column with small quiet type so the notice stays
     visible (compliance) without dominating the page. */
  .import-foot-inner {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    text-align: left;
  }
  .import-foot .import-foot-note { font-size: 10.5px; line-height: 1.5; }
  .import-foot-mark::after { display: none; }
}

/* Brand-to-content alignment. The nav is a full-width glass bar, so we line the
   wordmark up with the page content using side padding (keeping the bar full
   bleed). Dashboard: home-wrap pads 32px and the navy hero pads a further 24px
   inside, so the brand meets the "WELCOME BACK / Dashboard" text (32 + 24 = 56px),
   not the card edge. Tabs/controls shift right to follow. Import shares the exact
   same 56px nav gutter (and matching content gutter, below) so its header is
   pixel-identical to the dashboard - same component, same gutters, same controls. */
.dash-page .bank-tabs,
.import-page .bank-tabs,
.bank-page .bank-tabs,
.privacy-page .bank-tabs,
.terms-page .bank-tabs { padding-left: 56px; padding-right: 56px; }
/* On phones the 56px desktop gutter leaves too little room and forces a tab onto
   a third row; match the mobile nav gutter so all three tabs sit on one row. */
@media (max-width: 760px) {
  .dash-page .bank-tabs,
  .import-page .bank-tabs,
  .bank-page .bank-tabs,
  .privacy-page .bank-tabs,
  .terms-page .bank-tabs { padding-left: 16px; padding-right: 16px; }
}

/* Landing nav: slim sticky header - wordmark left, theme toggle alone on the
   right. It stays pinned while scrolling on a soft cream glass; a hairline
   bottom border fades in only once the page has scrolled (.is-scrolled, toggled
   by the landing script) so it reads as the top of the hero at rest and as a
   clean premium bar in motion. No heavy shadow. */
.bank-tabs--bare {
  position: sticky;
  top: 0;
  z-index: 60;
  height: 56px;
  background: rgba(246,242,234,.78);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease, background .25s ease;
  /* Landing nav brand sits in the EXACT same spot as the dashboard nav brand
     (56px = home-wrap 32px + hero inner 24px) so the wordmark never jumps when
     moving between the landing and the app. overflow:visible so the gold serif
     alpha is never clipped by the slim bar. */
  padding-left: 56px;
  padding-right: 56px;
  overflow: visible;
}
.bank-tabs--bare.is-scrolled { border-bottom-color: var(--line); background: rgba(246,242,234,.9); }
/* Match the dashboard nav brand exactly (no extra padding/line-height that would
   nudge it down); just sit above the blurred backdrop. overflow:visible on the
   bar already prevents the gold serif alpha from being clipped. */
.bank-tabs--bare .brand { margin-right: 0; position: relative; z-index: 1; }
.bank-tabs--bare .theme-toggle { margin-left: auto; }
:root[data-theme="dark"] .bank-tabs--bare { background: rgba(10,14,27,.72); }
:root[data-theme="dark"] .bank-tabs--bare.is-scrolled { background: rgba(10,14,27,.88); border-bottom-color: rgba(255,255,255,.08); }

/* The landing page breaks out of the global 1040px .home-wrap so its own .ld-wrap
   container (1140px) governs every section's width and gutters. The footer keeps
   its own max-width, so it stays centred and readable. */
.home-wrap:has(> .ld) { max-width: none; padding: 0; }

/* Landing footer: reuse the Import page's compact footer bar (.import-foot) verbatim,
   but pin it to the bottom of the viewport with position:fixed so it is visible from
   first paint without scrolling. The base centred site-foot is hidden. The bar spans
   the full viewport (left/right:0), so the inner keeps the Import page's own 56px
   gutter and grid, giving a pixel-for-pixel match side by side. */
body.home-page .site-foot { display: none; }
body.home-page .import-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  margin: 0;
}
/* Reserve space equal to the fixed footer's height so the FAQ/CTA never hide behind
   it (the bar is ~52px: two 11px/1.6 disclaimer lines + 8px padding top/bottom + 1px
   border). */
body.home-page .home-wrap { padding-bottom: 60px; }
@media (max-width: 640px) {
  body.home-page .home-wrap { padding-bottom: 72px; }
}

/* ---- header top-right pills: match the moon (theme) / crown toggles ----
   The countdown pill and the level pill adopt the exact same shape as the
   .theme-toggle button — 34px tall, fully rounded, thin neutral outline, no
   shadow — so the whole header top-right reads as one set of premium controls.
   Both are clickable links (countdown -> schedule, level -> setup). */
.bank-tabs .nav-countdown,
.bank-tabs .profile-chip {
  display: inline-flex; align-items: center;
  height: 34px; padding: 0 13px; gap: 5px;
  border: 1px solid var(--line-2); border-radius: 999px;
  background: var(--surface); color: var(--ink-2);
  box-shadow: none; white-space: nowrap; text-decoration: none;
  cursor: pointer; transition: color .15s, border-color .15s, transform .15s, background .15s;
}
/* Tight, consistent spacing between the two pills (and from the toggles). */
.bank-tabs .nav-countdown { margin-right: 8px; }
.bank-tabs .nav-countdown:hover,
.bank-tabs .profile-chip:hover { color: var(--gold); border-color: var(--gold-2); transform: translateY(-1px); background: var(--surface); }
.bank-tabs .nav-countdown:focus-visible,
.bank-tabs .profile-chip:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.bank-tabs .nav-countdown strong { color: var(--gold); font-weight: 700; }
.bank-tabs .profile-chip .profile-text { color: var(--ink-2); font-weight: 600; }
/* Keep the level label visible at every width (theme.css hides .profile-text on
   narrow screens for the old name+level chip); truncate long exam names neatly
   with an ellipsis — the full value stays available via the link's title. */
.bank-tabs .profile-chip--level .profile-text {
  display: inline-block !important;
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- paywall: unlock panel + blurred Pro sections (recoloured for dark) ---- */
.unlock-panel { border: 1px solid var(--gold-2);
  background: linear-gradient(160deg, var(--gold-t) 0%, var(--surface) 62%);
  box-shadow: var(--sh-md);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 18px; }
.unlock-panel h2 { color: var(--ink-0); }
.unlock-panel .btn-primary { text-decoration: none; }

/* Gold Pro lockup - the centrepiece of the free/locked view: the AlphaDrill
   wordmark with a gold "Pro mode" pill directly beneath it, the whole stack a
   single link to the store. The .pro-hero size is for the central unlock panel;
   .pro-lockup is the compact version laid over each individual locked card. */
.pro-hero, .pro-lockup {
  display: inline-flex; flex-direction: column; align-items: center;
  text-decoration: none; cursor: pointer;
}
.pro-hero { gap: 13px; }
.pro-lockup { gap: 9px; }
.pro-hero-brand, .pro-lockup-brand {
  display: inline-flex; align-items: baseline; font-family: var(--f-display);
}
.pro-hero-brand .brand-a   { font-size: 52px; font-weight: 700; line-height: 1; color: var(--gold); margin-right: 2px; }
.pro-hero-brand .brand-word{ font-size: 34px; font-weight: 560; letter-spacing: -.02em; color: var(--ink-0); }
.pro-lockup-brand .brand-a   { font-size: 30px; font-weight: 700; line-height: 1; color: var(--gold); margin-right: 1px; }
.pro-lockup-brand .brand-word{ font-size: 20px; font-weight: 560; letter-spacing: -.02em; color: var(--ink-0); }
.pro-hero-mode, .pro-lockup-mode {
  display: inline-flex; align-items: center;
  background: var(--gold-t); border: 1px solid var(--gold-2); border-radius: 999px;
  color: var(--gold); font-weight: 700; text-transform: uppercase; line-height: 1;
  transition: border-color .15s, transform .15s;
}
.pro-hero-mode   { gap: 7px; padding: 6px 16px 6px 13px; font-size: 12px;   letter-spacing: .16em; }
.pro-lockup-mode { gap: 6px; padding: 5px 13px 5px 10px; font-size: 10px;   letter-spacing: .14em; }
.pro-hero-mode .pro-crown   { width: 14px; height: 14px; }
.pro-lockup-mode .pro-crown { width: 12px; height: 12px; }
.pro-hero:hover .pro-hero-mode,
.pro-lockup:hover .pro-lockup-mode { border-color: var(--gold); transform: translateY(-1px); }
.pro-hero-sub { color: var(--ink-2); font-size: 14px; line-height: 1.55; max-width: 46ch; margin: 0; }
.pro-hero-cta { text-decoration: none; }
.pro-hero-key { width: 100%; max-width: 440px; text-align: left; }

/* ---- clean locked states (no blur) ----
   Subtle "Upgrade to use / unlock" action: keeps the button's size/shape but
   swaps the heavy fill for a quiet gold-tinted outline, so a locked card reads as
   a calm upsell rather than a disabled dead end. Works on .btn-primary and
   .btn-blue alike (those set the geometry; this only recolours). */
.btn-upgrade, a.btn-upgrade {
  background: var(--gold-t) !important;
  color: var(--gold) !important;
  border-color: var(--gold-2) !important;
  box-shadow: inset 0 0 0 1px var(--gold-2) !important;
  text-decoration: none;
}
.btn-upgrade:hover, a.btn-upgrade:hover {
  background: var(--gold-t) !important;
  box-shadow: inset 0 0 0 1px var(--gold) !important;
  transform: translateY(-1px);
}
/* Dark mode: the quiet gold outline reads as washed-out next to the solid bone
   "Start review" CTA. So in dark, locked upgrade buttons ("Upgrade to use",
   "Upgrade to unlock") take the SAME filled treatment as the primary CTA — bone
   fill, navy ink, equal weight — so the locked actions feel first-class. */
:root[data-theme="dark"] .btn-upgrade,
:root[data-theme="dark"] a.btn-upgrade {
  background: var(--ink-0) !important;
  color: var(--surface) !important;
  border-color: var(--ink-0) !important;
  box-shadow: 0 8px 18px -12px rgba(0, 0, 0, 0.6) !important;
}
:root[data-theme="dark"] .btn-upgrade:hover,
:root[data-theme="dark"] a.btn-upgrade:hover {
  background: var(--ink-0) !important;
  box-shadow: 0 12px 22px -12px rgba(0, 0, 0, 0.65) !important;
  transform: translateY(-1px);
}
/* "View question bank" (the Pro-mode Topic-review CTA) is a solid-blue secondary
   button. In dark mode it should read as the same filled bone CTA as "Start review"
   (and the locked "Upgrade to …" buttons), so all dashboard CTAs match. Scoped to
   the coverage head so other blue buttons app-wide are untouched. */
:root[data-theme="dark"] .dash-page .coverage-head .btn-blue {
  background: var(--ink-0); color: var(--surface) !important;
  border-color: var(--ink-0);
}
:root[data-theme="dark"] .dash-page .coverage-head .btn-blue:hover {
  background: var(--ink-0); border-color: var(--ink-0); color: var(--surface) !important;
}

/* Inline Pro pill beside a card heading (e.g. Topic review). Same gold pill as
   the mode-card badge, but laid out inline next to the title. */
.pro-inline-badge {
  display: inline-flex; align-items: center; gap: 5px; flex: none;
  padding: 0 10px 0 8px; height: 20px; white-space: nowrap;
  font-family: var(--f); font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gold);
  background: var(--gold-t); border: 1px solid var(--gold-2); border-radius: 999px;
}
.pro-inline-badge .pro-crown { width: 11px; height: 11px; flex: none; }
/* Let the Topic-review heading + pill sit on one baseline-aligned row. */
.coverage-card.is-locked-preview .coverage-head > div {
  display: flex; align-items: center; gap: 10px; min-width: 0;
}
/* Topic review locked: a clean locked preview — NOT an overlay. The header (title +
   Pro pill + CTA) stays sharp, and so do the topic names (the readable teaser).
   Only the GATED metrics are softened: the coverage bar, the score fraction inside
   it and the accuracy caption + pill. Each row carries a small gold lock bubble on
   the right (.cov-status) so it reads as deliberately locked, not broken. */
.dash-page .coverage-card.is-locked-preview { position: relative; }
.coverage-card.is-locked-preview #coverage { user-select: none; }
.coverage-card.is-locked-preview .cov-row { position: relative; padding-right: 42px; cursor: default; }
.coverage-card.is-locked-preview .cov-row:hover { background: none; }
.coverage-card.is-locked-preview .cov-track,
.coverage-card.is-locked-preview .cov-acc,
.coverage-card.is-locked-preview .cov-acc-cap {
  filter: blur(3.5px) saturate(.92); opacity: .6; pointer-events: none;
}

/* Small gold status bubble pinned to the right of each locked row — the same
   gold-tint pill treatment used across the app, here as a round lock chip. Sits
   above the softened metrics and stays perfectly sharp. */
.cov-status {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%); z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 999px;
  background: var(--gold-t); border: 1px solid var(--gold-2); color: var(--gold);
}
.cov-status svg { width: 11px; height: 11px; }
.locked-blur { filter: blur(7px) saturate(.85); pointer-events: none; user-select: none;
  opacity: .7; }
/* Heavier blur for a teased KPI value (e.g. the best streak) - obscured enough
   that the number can't be read, while its label stays sharp beside it. */
.locked-blur-strong { filter: blur(11px) saturate(.8); pointer-events: none; user-select: none;
  opacity: .55; }

/* "Pro" tag on premium mode cards + the lock overlay used on the home Exam card */
.pro-tag { color: var(--gold); }
/* Mode cards are positioned in BOTH states so an open dropdown can be raised above
   the card beneath it (see .ms[open] layering below). */
.today-alt, .mode-card.is-locked { position: relative; }
/* Locked mode card: keep the EXACT Pro-mode layout, height and spacing - nothing
   moves or resizes. The content area (pickers / streak) gets a SUBTLE locked blur
   and is made fully inert + unclickable; the title, description, Pro pill and the
   "Upgrade to use" button stay sharp. So free mode reads as the same premium
   dashboard, just with its Pro controls softly locked. */
.mode-card.is-locked .mode-fields,
.mode-card.is-locked .mode-stats {
  filter: blur(1.6px) saturate(.92); opacity: .9;
  pointer-events: none; user-select: none;
}
/* Dropdowns are visibly disabled in free mode: a not-allowed cursor on the summary
   and a muted surface, so it's clear they can't be opened (the pointer-events:none
   above already blocks the click). */
.mode-card.is-locked .ms > summary { cursor: not-allowed; color: var(--ink-3); }
.mode-card.is-locked .ms-count { color: var(--ink-3); }

/* Dropdown layering (PRO mode, where dropdowns open): when a topic/module dropdown
   is open inside Custom session, lift its whole card above the Sudden death card
   below so the absolutely-positioned .ms-panel is never painted over / clipped. */
.today-alt:has(.ms[open]) { z-index: 20; }
.today-alt .ms[open] { z-index: 20; }
.today-alt .ms-panel { z-index: 40; }
.mode-lock { position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 7px; text-align: center;
  padding: 22px; border-radius: inherit;
  background: linear-gradient(160deg, color-mix(in srgb, var(--gold-t) 80%, transparent), color-mix(in srgb, var(--surface) 93%, transparent));
  backdrop-filter: blur(2px);
  border: 1px solid var(--gold-2); }
.mode-lock p { color: var(--ink-2); font-size: 14px; line-height: 1.5; margin: 0; max-width: 30ch; }
.mode-lock-badge { font-size: 10.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--gold); }
/* "[Feature] is part of" sits quietly above the brand line. */
.mode-lock-feat { font-size: 13px; color: var(--ink-3); }
/* The brand gets its own line, larger and gold - the headline of the unlock. */
.mode-lock-title { font-family: var(--f-display); font-size: 26px; font-weight: 700;
  line-height: 1.05; color: var(--gold); letter-spacing: -.01em; margin-bottom: 4px; }
.mode-lock .btn-primary { text-decoration: none; }

/* ---- vignette highlighting (persisted reader highlights) ---- */
.vignette mark, .q-stem mark {
  background: var(--gold-t);
  color: inherit;
  border-bottom: 2px solid var(--gold-2);
  border-radius: 2px;
  padding: 0 1px;
}
.case-body { position: relative; }
.highlight-hint {
  font-size: 11px; color: var(--ink-4); margin: 0 0 6px;
  letter-spacing: .02em;
}

/* ---- confidence chips (after answering) ---- */
.confidence {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
}
.confidence .conf-label {
  font-size: 11px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-3); margin-right: 2px;
}
.conf-btn {
  font-family: var(--f); font-size: 13px; font-weight: 500;
  padding: 6px 13px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface);
  color: var(--ink-2); cursor: pointer;
  transition: border-color .15s, background .15s, color .15s, transform .12s;
}
.conf-btn:hover { border-color: var(--ink-3); transform: translateY(-1px); }
.conf-btn.sel { background: var(--ink-0); border-color: var(--ink-0); color: var(--surface); }
.conf-btn:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }

/* ---- entrance + count motion (the "alive" feel) ---- */
@media (prefers-reduced-motion: no-preference) {
  .card, .mode-card, .score-card, .home-hero, .status-card {
    animation: lux-rise .5s cubic-bezier(.22,.61,.36,1) both;
  }
  .score-grid .score-card:nth-child(2) { animation-delay: .04s; }
  .score-grid .score-card:nth-child(3) { animation-delay: .08s; }
  .score-grid .score-card:nth-child(4) { animation-delay: .12s; }
  .score-grid .score-card:nth-child(5) { animation-delay: .16s; }
  .score-grid .score-card:nth-child(6) { animation-delay: .20s; }
  @keyframes lux-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
  .gauge svg path { transition: stroke-dashoffset .9s cubic-bezier(.22,.61,.36,1); }
}

/* ── Top status bar ───────────────────────────────────────────────────────
   An always-dark, two-line "hero" strip (its text colours are fixed, not theme
   vars that would flip and vanish in dark mode). Top line: identity + a
   change-level chip. Bottom line: the day-count chip + three key metrics. */
.exam-countdown {
  display: flex; flex-direction: column; gap: 14px; position: relative; overflow: hidden;
  background: linear-gradient(150deg, #090d18 0%, #10172a 58%, #161d33 100%);
  border: 1px solid #1c2540; border-radius: 14px;
  padding: 16px 22px 18px; margin-bottom: 22px;
  box-shadow: 0 1px 0 rgba(255,255,255,.04) inset, 0 14px 34px rgba(8,12,24,.32);
}

/* Top line: which exam track you're on. */
.ec-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.ec-title {
  font-family: var(--f-display); font-size: 21px; font-weight: 600; line-height: 1.1;
  color: #f4efe6; margin: 0;
}

/* Bottom line: four balanced metric tiles — days, bank progress, target, streak.
   A clean grid (progress gets the widest column) so no single metric dominates;
   every number shares one scale and the gold is reserved for the day count + bar. */
.ec-metrics {
  display: grid;
  grid-template-columns: 1fr 1.7fr 1fr 1fr;
  gap: 12px;
  align-items: stretch;
}
/* Each metric sits in its own lightly bordered glass panel, so the row reads as a
   deliberate control-panel grid rather than four loose numbers on a flat box. */
.exam-countdown .ec-metrics > * {
  display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center;
  gap: 7px; min-width: 0;
  padding: 11px 13px; border-radius: 10px;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.09);
}
/* Respect the [hidden] attr JS toggles on the progress tile (the flex rule above
   would otherwise re-show it before a bank is imported). */
.exam-countdown .ec-metrics > [hidden] { display: none !important; }
/* Pre-upload state: the question-driven tiles (questions covered + average score)
   carry a quiet gold "Upload to start review" CTA instead of a number, so the hero
   stays full and premium for a brand-new visitor and invites them into Import. */
/* The prompt tiles ARE daily-review bubbles: the same pale-gold cream fill
   (var(--surface-2)) and warm hairline border (var(--line)), with the title stacked
   above a centred CTA. */
.exam-countdown .ec-tile-prompt {
  flex-direction: column !important; align-items: center; justify-content: center !important;
  gap: 9px !important; text-align: center; padding: 14px 12px;
  background: var(--surface-2) !important;
  border-color: var(--line) !important;
}
/* Pre-upload the day chip needs little room, so give the two prompt tiles more
   width for their title + button. */
.exam-countdown .ec-metrics:has(.ec-tile-prompt),
.dash-page .exam-countdown .ec-metrics:has(.ec-tile-prompt) {
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.55fr) minmax(0, 1.55fr);
}
/* Title in the SAME format as the "Daily review" / "Custom session" titles. */
.exam-countdown .ec-tile-prompt .ec-prompt-title {
  margin: 0; font-family: var(--f-display);
  font-size: 15px !important; font-weight: 560; line-height: 1.2;
  letter-spacing: 0 !important; text-transform: none !important; color: var(--ink-0) !important;
}
/* The CTA IS the daily-review button (.btn-primary.today-go) — identical colours,
   radius and gold ring in both modes — sized to its own text and centred. */
.exam-countdown .ec-upload-cta.btn-primary {
  flex: none; display: inline-flex; align-items: center; justify-content: center; text-align: center;
  max-width: 100%; white-space: normal; line-height: 1.2;
  font-size: 11.5px; padding: 9px 14px; border-radius: 9px;
}
/* Shared metric type: one display-serif number + one uppercase micro-label. */
.ec-days-chip strong,
.ec-prog-count,
.exam-countdown .ec-stat strong {
  font-family: var(--f-display); font-size: 26px; font-weight: 600; line-height: 1;
  color: #f4efe6; font-variant-numeric: tabular-nums;
}
.ec-days-chip span,
.ec-prog-label,
.ec-prog-pct,
.exam-countdown .ec-stat span {
  font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: rgba(255,255,255,.8);
}
.exam-countdown .ec-stat { position: relative; }
/* Pass benchmark beneath the average score, styled as the SAME quiet gold pill as
   the "Aim N/day" pace read-out under the day count (.ec-pace-aim), and pushed to
   the tile floor (margin-top:auto) so the two pills sit on one shared bottom line. */
.exam-countdown .ec-stat .ec-pass-note {
  margin-top: auto; align-self: center; max-width: 92%;
  padding: 3px 11px; border-radius: 10px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em; line-height: 1.35; text-align: center;
  text-transform: none;
  color: #ecd7a0; background: rgba(200,169,106,.17); border: 1px solid rgba(200,169,106,.5);
}

/* Days metric: a quiet link to the plan. Gold number anchors the row, but it
   sits on the same baseline + scale as the other tiles — no oversized box. */
/* The days panel doubles as a link to the plan: it lifts to a faint gold wash +
   gold hairline on hover, while keeping the shared panel geometry. */
.ec-days-chip {
  text-decoration: none; cursor: default;
  align-items: center; justify-content: center; text-align: center; gap: 6px;
  transition: background .15s, border-color .15s;
}
/* Only interactive in the "Set exam date" prompt state, where JS adds an href —
   the plain day-count read-out is not a link, so it doesn't invite a click. */
.ec-days-chip:hover { text-decoration: none; }
.ec-days-chip[href] { cursor: pointer; }
.ec-days-chip[href]:hover { background: rgba(200,169,106,.12); border-color: rgba(200,169,106,.45); }
.ec-days-chip strong { color: #d8bd86; font-size: 46px; }
.ec-days-prompt { justify-content: center; }
.ec-setdate { color: #c8a96a; font-size: 14px; font-weight: 600; }
/* Pace pill under the day count: the pace verdict is carried by the TEXT ("On pace"
   / "Aim N per day"); the pill itself always wears the SAME quiet gold as the pass
   pill under the average score, so the two read as one matched pair. Scoped under
   .ec-days-chip so it beats the generic uppercase span styling. */
.ec-days-chip .ec-pace,
.ec-days-chip .ec-pace-ok,
.ec-days-chip .ec-pace-behind,
.ec-days-chip .ec-pace-aim {
  margin-top: auto; padding: 3px 11px; border-radius: 10px; max-width: 90%;
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  text-transform: none; white-space: normal; text-align: center; line-height: 1.35;
  color: #ecd7a0; background: rgba(200,169,106,.17); border: 1px solid rgba(200,169,106,.5);
}

/* Question-bank progress: label, count, slim bar, then "n% complete". Four stacked
   rows, so this panel flows from the top with a tight rhythm (not space-between). */
.exam-countdown .ec-prog { justify-content: center; gap: 6px; }
.ec-prog-pct { text-transform: none; letter-spacing: .02em; }
.exam-countdown .ec-prog .bar { width: 100%; background: rgba(255,255,255,.16); height: 7px; border-radius: 999px; overflow: hidden; margin-top: 1px; box-shadow: 0 0 0 1px rgba(255,255,255,.05); }
.exam-countdown .ec-prog .bar-fill { background: linear-gradient(90deg, #c8a96a, #e2c789); border-radius: 999px; min-width: 3px; }

.exam-countdown-set { display: block; text-align: center; padding: 12px; margin-bottom: 22px;
  border: 1px dashed var(--line-2); border-radius: 10px; background: var(--surface);
  color: var(--ink-2) !important; font-size: 13.5px; text-decoration: none; }
.exam-countdown-set:hover { border-color: var(--gold-2); color: var(--ink-0) !important; }

/* Tablet: two columns. Mobile: a single stacked column. */
@media (max-width: 720px) {
  .ec-metrics { grid-template-columns: 1fr 1fr; gap: 20px 30px; }
}
@media (max-width: 440px) {
  .ec-metrics { grid-template-columns: 1fr; }
}

/* Setup: exam-window dropdown */
.setup-select { width: 100%; padding: 11px 12px; border: 1px solid var(--line-2);
  border-radius: 8px; background: var(--surface); color: var(--ink-1); font: inherit; }
.setup-select:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 1px; }
.setup-hint { display: block; margin-top: 6px; font-size: 12.5px; color: var(--ink-3); }

/* Item-set sub-label cues (1.1 / 2.3) - parser groups vignette questions */
.qset-tag { font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--gold); font-weight: 600; margin-bottom: 6px; }
.pill-set { background: var(--gold-t); border: 1px solid var(--gold-2);
  color: var(--gold); font-weight: 600; }
.bank-vignette { margin: 0 0 12px; padding: 12px 14px; background: var(--surface-2);
  border: 1px solid var(--line); border-left: 3px solid var(--gold-2); border-radius: 8px;
  font-size: 13px; color: var(--ink-2); max-height: 320px; overflow: auto; }
.bank-vignette table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 12.5px; }
.bank-vignette th, .bank-vignette td { border: 1px solid var(--line-2); padding: 4px 8px; text-align: left; }

/* Exhibit images (charts/figures rendered from the user's PDF) */
.vignette .exhibit-img, .bank-vignette .exhibit-img {
  display: block; max-width: 100%; height: auto; margin: 12px 0;
  border: 1px solid var(--line); border-radius: 8px; background: #fff;
}
.exhibit-missing { font-size: 12.5px; font-style: italic; color: var(--ink-3); margin: 8px 0; }
.exhibit-slot { display: none; }   /* unfilled slot is invisible until hydrated/replaced */

/* ---------------------------------------------------------------------------
   EXAM PLAN - interactive study calendar
--------------------------------------------------------------------------- */
.schedule-card { position: relative; scroll-margin-top: 88px; }
/* Tier 1 - heading + subtitle on the left, the inputs that drive the plan tucked
   to the right on the same row. The output metrics sit in their own band below. */
.sched-head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 14px 32px; margin-bottom: 14px;
}
.sched-head-text { min-width: 240px; flex: 1 1 260px; }
.sched-title { font-family: var(--f-display); font-size: 21px; font-weight: 560; color: var(--ink-0); margin: 0 0 4px; }
.sched-sub { margin: 0; max-width: 38ch; }
.sched-controls {
  display: flex; flex-wrap: wrap; gap: 12px 14px; align-items: flex-end; justify-content: flex-end;
  padding: 13px 15px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2);
}
.sched-controls label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3);
}
.sched-controls input {
  height: 40px; width: 158px; padding: 0 12px; box-sizing: border-box; font-size: 14px;
  border: 1px solid var(--line-2); border-radius: 9px; background: var(--surface); color: var(--ink-0); font-family: inherit;
}
.sched-controls input:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 1px; border-color: var(--gold-2); }
.sched-controls input[type=number] { width: 124px; }
.sched-controls .msg { align-self: center; }

/* Tier 2 - output cards. A full-width band that reads as results (not inputs):
   larger numbers, a hairline gold top accent, sitting on the deeper surface. */
.sched-summary {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
  margin: 0 0 20px; padding-bottom: 20px; border-bottom: 2px solid var(--line);
}
/* Clean white analytics tiles - thin neutral border, a single 2px gold accent on
   the left edge (no gold fill, no beige panel, no heavy top bar). */
.ss-tile {
  position: relative; display: flex; flex-direction: row; align-items: center; gap: 11px;
  padding: 13px 16px 13px 18px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--sh-xs); overflow: hidden;
}
.ss-tile::before { content: ""; position: absolute; inset: 12px auto 12px 0; width: 2px; border-radius: 0 2px 2px 0; background: var(--gold); opacity: .85; }
.ss-big { flex: none; font-family: var(--f-display); font-size: 26px; font-weight: 600; color: var(--ink-0); line-height: 1; font-variant-numeric: tabular-nums; }
.ss-label { font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); line-height: 1.25; }
@media (max-width: 760px) { .sched-summary { grid-template-columns: 1fr 1fr; } .sched-summary .ss-tile:last-child { grid-column: 1 / -1; } }
@media (max-width: 640px) { .sched-controls { justify-content: flex-start; } .sched-controls label { flex: 1 1 140px; } }

/* Month blocks: a fixed three-month window on desktop, paged with the arrows
   beside the range caption; collapsing to one column on small screens. */
.cal-nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
.cal-nav-btns { display: flex; gap: 8px; }
.cal-nav-btn {
  display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  border: 1px solid var(--line-2); border-radius: 9px; background: var(--surface); color: var(--ink-2);
  cursor: pointer; transition: border-color .12s, color .12s, background .12s;
}
.cal-nav-btn:hover { border-color: var(--gold-2); color: var(--gold); background: var(--surface-2); }
.cal-nav-btn:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.cal-nav-btn:disabled { opacity: .32; cursor: default; border-color: var(--line); color: var(--ink-4); background: var(--surface); }
/* Quiet helper caption where the big "May - July 2026" range title used to sit.
   The per-month headings ("June 2026", etc.) now carry the dates on their own. */
.cal-nav-caption { font-size: 12px; color: var(--ink-3); }
@media (max-width: 560px) { .cal-nav-caption { display: none; } }
.cal-months { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px 24px; }
.cal-locked { cursor: default; pointer-events: none; }
.cal-month-block { min-width: 0; }
.cal-month-title { font-family: var(--f-display); font-size: 15px; font-weight: 560; color: var(--ink-0); margin-bottom: 8px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { margin-bottom: 4px; }
.cal-dow-cell { text-align: center; font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-4); padding: 2px 0; }

.cal-cell {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; min-height: 42px; padding: 4px 6px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); cursor: pointer; font: inherit;
  transition: border-color .12s, box-shadow .12s, transform .08s;
}
.cal-cell:hover { border-color: var(--gold-2); box-shadow: var(--sh-sm); transform: translateY(-1px); }
.cal-empty { border: 0; background: none; cursor: default; pointer-events: none; min-height: 0; }
/* Day number + hours stacked dead-centre (matching the exam tile): a larger leading
   number with a quiet hours micro-label beneath it, so every cell reads the same. */
.cal-num { font-size: 16px; font-weight: 600; color: var(--ink-1); line-height: 1; }
.cal-hrs { font-size: 11px; font-weight: 600; color: var(--ink-3); align-self: center; line-height: 1; }

/* Active study day: a clean off-white card with a thin gold border + dark text. */
.cal-study { background: var(--surface); border-color: var(--gold-2); }
.cal-study .cal-num { color: var(--ink-1); }
.cal-study .cal-hrs { color: var(--gold); }
/* Custom-hours day: the same off-white study card; only the hours turn green to
   flag they've been overridden. */
.cal-custom { background: var(--surface); border-color: var(--gold-2); }
.cal-custom .cal-num { color: var(--ink-1); }
.cal-custom .cal-hrs { color: var(--ok); }
/* Holiday / no-study: a clear light grey fill, muted border + muted text. */
.cal-holiday { background: var(--cal-grey); border-color: var(--cal-grey-line); }
.cal-holiday .cal-num, .cal-holiday .cal-hrs { color: var(--ink-3); font-weight: 500; }
/* Past / inactive (before the plan starts or after the exam): a lighter grey than
   the holiday days, low-contrast text — clearly out of the active window. */
.cal-past { background: var(--surface-2); border-color: var(--line); }
.cal-past .cal-num { color: var(--ink-4); font-weight: 500; }
.cal-past .cal-hrs { color: var(--ink-4); font-weight: 500; }
/* Today / live day: one step up from the off-white study day — a light gold-tinted
   fill with a stronger deep-gold border — clearly "you are here", clearly lighter
   than the solid-gold exam day. */
.cal-today { background: rgba(200, 169, 106, 0.30) !important; border-color: var(--gold) !important; box-shadow: inset 0 0 0 1px var(--gold); }
.cal-today .cal-num { color: var(--ink-0); font-weight: 700; }
.cal-today .cal-hrs { color: var(--gold); }
/* Exam day: the single strongest gold state — a rich gold fill with the day number
   and a small "Exam" caplabel stacked dead-centre. The number leads (largest, white,
   softly shadowed); the label sits beneath it as a quiet uppercase micro-line, so the
   tile reads as one balanced, deliberate marker rather than two competing corners. */
.cal-exam {
  background: linear-gradient(155deg, var(--gold-2) 0%, var(--gold) 60%, #8a6c34 100%) !important;
  border-color: var(--gold-2) !important; border-style: solid !important;
  align-items: center !important; justify-content: center !important; gap: 2px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 2px 9px rgba(120,90,34,.4), 0 0 0 1px var(--gold-2);
}
.cal-exam .cal-num {
  position: static; margin: 0; color: #fff !important; font-weight: 700;
  font-size: 16px !important; line-height: 1; letter-spacing: -.01em;
  text-shadow: 0 1px 1px rgba(110,82,28,.45);
}
.cal-exam .cal-hrs {
  position: static; inset: auto; align-self: center; margin: 0; padding: 0;
  display: block; color: rgba(255,255,255,.96) !important; font-weight: 700;
  font-size: 7.5px !important; line-height: 1; letter-spacing: .16em; text-transform: uppercase;
  text-shadow: 0 1px 1px rgba(110,82,28,.4);
}
/* Mock-exam day: the SAME centred number + caplabel layout as the exam tile, but on
   a clean surface with a dark-gold ring instead of the solid gold fill — so it reads
   as a lighter sibling of exam day. Day number + "Mock" both in dark gold. */
.cal-mock { border-color: var(--gold) !important; box-shadow: inset 0 0 0 1px var(--gold); }
.cal-mock .cal-num { color: var(--ink-1); font-weight: 600; }
.cal-mock .cal-hrs {
  align-self: center; margin: 0; padding: 0; background: none;
  color: var(--gold) !important; font-weight: 700;
  font-size: 7.5px !important; line-height: 1; letter-spacing: .16em; text-transform: uppercase;
}

/* Compact horizontal legend, sat directly under the month-range heading and above
   the grid so it is always fully visible (it used to sit below and get clipped). */
.cal-legend {
  display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0 0 14px;
  font-size: 11.5px; color: var(--ink-3);
}
.cal-legend span { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.cal-key { width: 13px; height: 13px; border-radius: 4px; border: 1px solid var(--line-2); display: inline-block; }
.cal-key-study { background: var(--surface); border-color: var(--gold-2); }
.cal-key-holiday { background: var(--cal-grey); border-color: var(--cal-grey-line); }
.cal-key-custom { background: rgba(47,107,79,.12); border-color: rgba(47,107,79,.34); }
.cal-key-today { background: rgba(200, 169, 106, 0.20); border-color: var(--gold); }
.cal-key-mock { background: var(--surface); border: 2px solid var(--gold); }
.cal-key-exam { background: var(--gold); border-color: var(--gold); }

.cal-pop {
  position: absolute; z-index: 30; width: 196px; padding: 13px 15px;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: 11px;
  box-shadow: var(--sh-md, 0 12px 32px rgba(11,16,32,.18));
}
/* Title row: date heading on the left, a quiet close "x" pinned to the right. */
.cal-pop-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin: 0 0 12px; padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.cal-pop-title {
  font-family: var(--f-display); font-weight: 560; font-size: 14px; color: var(--ink-0);
}
.cal-pop-close {
  flex: none; width: 24px; height: 24px; margin: -4px -4px -4px 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 7px; background: none; color: var(--ink-3);
  font-size: 19px; line-height: 1; cursor: pointer; transition: background .12s, color .12s;
}
.cal-pop-close:hover { background: var(--surface-2); color: var(--ink-0); }
.cal-pop-close:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 1px; }
.cal-pop-row { display: block; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 5px; }
/* `input.cal-pop-input` (not just `.cal-pop-input`) so this beats the global
   light-theme `input[type=number]{background:#fff}` rule in alphadrill.css — that
   hardcoded white was overriding the theme-aware surface here in dark mode. */
input.cal-pop-input {
  width: 100%; height: 36px; padding: 0 10px; box-sizing: border-box;
  border: 1px solid var(--line-2); border-radius: 8px;
  background: var(--surface); color: var(--ink-0); font: inherit; margin-bottom: 12px;
  -webkit-appearance: none; appearance: none; outline: none;
  transition: border-color .15s, background .15s;
}
/* Strip the native spinner buttons (they render as a bright white strip in dark
   mode) so the field stays one clean dark box. */
.cal-pop-input::-webkit-outer-spin-button,
.cal-pop-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cal-pop-input[type=number] { -moz-appearance: textfield; }
.cal-pop-input::placeholder { color: var(--ink-3); opacity: 1; }
.cal-pop-input:hover { border-color: var(--gold-2); }
.cal-pop-input:focus-visible { border-color: var(--gold-2); outline: 2px solid var(--gold-2); outline-offset: 1px; }
.cal-pop-input:disabled { background: var(--surface-2); color: var(--ink-4); border-color: var(--line); cursor: default; }
/* Holiday / mock controls: a proper toggle switch (hidden native checkbox + gold
   track). The label text sits on the left; the switch is pinned to the right.
   The two rows share one bordered group so they read as a tidy pair, not loose
   lines. */
.cal-pop-switch {
  display: flex !important; flex-direction: row !important; flex-wrap: nowrap;
  align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12.5px; color: var(--ink-1);
  padding: 9px 0; cursor: pointer; user-select: none;
}
/* Label text fills the row so the switch is pinned to the far right; both stay
   vertically centred. */
.cal-pop-switch > span:first-child { flex: 1 1 auto; min-width: 0; text-align: left; }
.cal-pop-switch + .cal-pop-switch { border-top: 1px solid var(--line); }
.cal-pop-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.cal-switch {
  flex: 0 0 auto; margin-left: auto; order: 2;          /* always hard-right */
  position: relative; width: 34px; height: 20px; border-radius: 999px;
  background: var(--surface-3); border: 1px solid var(--line-2); transition: background .15s, border-color .15s;
}
.cal-switch::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px;
  border-radius: 50%; background: var(--surface); box-shadow: var(--sh-xs);
  transition: transform .15s;
}
/* Dark mode: the off-state knob can't be var(--surface) (that's the navy page bg,
   so it reads as a hole on the navy track). Use a bright bone knob instead; the
   checked rule below still wins for the on-state white knob (it's later + same
   specificity). */
:root[data-theme="dark"] .cal-switch::after { background: var(--ink-1); }
.cal-pop-switch input:checked ~ .cal-switch { background: var(--gold); border-color: var(--gold); }
.cal-pop-switch input:checked ~ .cal-switch::after { transform: translateX(14px); background: #fff; }
.cal-pop-switch input:focus-visible ~ .cal-switch { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.cal-pop-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--line); }
.cal-pop-actions .btn-link { font-size: 12px; font-weight: 600; color: var(--ink-3); padding: 0; }
.cal-pop-actions .btn-link:hover { color: var(--gold); }
.cal-pop-actions .btn-primary { padding: 8px 20px; font-size: 13px; border-radius: 8px; }

/* Tablet: let the three-month window wrap gracefully to two columns. */
@media (max-width: 900px) { .cal-months { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) {
  .cal-months { grid-template-columns: 1fr; gap: 16px; }
  .cal-cell { min-height: 42px; padding: 4px 6px; }
  .cal-num { font-size: 12px; }
  .cal-hrs { font-size: 10px; }
  .cal-grid { gap: 4px; }
}

/* First section divider in the bank sits flush at the top */
.bank-list > .bank-section-divider:first-child { margin-top: 2px; }

/* ===========================================================================
   DASHBOARD - single-viewport cockpit (premium art direction)
   A fixed-height grid that fits one desktop screen with no page scroll: navy
   hero / two-column main row / footer. The main row's left column stacks
   Today's session over "Where you stand"; the right column is the Exam plan +
   the full calendar. Every zone clips its own overflow so nothing overlaps the
   row beneath it. Falls back to normal scrolling flow below ~1100px.
   =========================================================================== */
body.dash-page { overflow: hidden; }
.dash-page .home-wrap {
  width: 100%; max-width: none; margin: 0;
  /* Subtract the real 56px nav height (was 52px, which overflowed the viewport by
     4px) and drop the bottom padding to 0, so the full-bleed footer lands flush
     against the viewport bottom — pixel-matching the Import page footer. */
  height: calc(100dvh - 56px); overflow: hidden;
  padding: 12px 32px 0; box-sizing: border-box;
  display: flex; flex-direction: column;
}
.dash-page .site-foot { display: none; }

.dash {
  flex: 1 1 auto; min-height: 0; width: 100%; max-width: none; display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr); gap: 14px;
  box-sizing: border-box; overflow: hidden;
}
.dash > * { min-height: 0; min-width: 0; max-width: 100%; overflow: hidden; box-sizing: border-box; }

/* Hairline borders (~12% ink) + a soft lift on every card container. */
.dash-page .today,
.dash-page .schedule-card,
.dash-page .coverage-card {
  border: 1px solid rgba(11, 16, 32, 0.12);
  box-shadow: 0 10px 30px -20px rgba(20, 15, 5, 0.3);
}
.dash .eyebrow { margin-bottom: 6px; }

/* === HERO: navy strip, identity left, three headline metrics right ======== */
.dash-page .exam-countdown {
  display: flex; flex-direction: row; align-items: center; flex-wrap: wrap;
  gap: 14px 28px; margin: 0; padding: 14px 24px;
  box-shadow: 0 14px 30px -18px rgba(8, 12, 24, 0.6);
}
.ec-id { flex: 0 0 auto; min-width: 150px; align-self: center; }
/* Personal greeting eyebrow above the title: small, uppercase, quiet bone — a
   formal welcome, not a gimmick. Hidden via .hidden when no name is stored. */
.ec-greet { font-family: var(--f); font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: rgba(244, 239, 230, 0.82); margin: 0 0 5px; }
.ec-h { font-family: var(--f-display); font-size: 24px; font-weight: 600; line-height: 1; letter-spacing: -0.01em; color: var(--gold-2); margin: 0 0 5px; }
.dash-page .ec-title { font-family: var(--f); font-size: 13px; font-weight: 500; letter-spacing: .015em; color: rgba(244, 239, 230, 0.82); margin: 0; }
/* Three equal-width, equal-height KPI cards (the grid + align-items:stretch keep
   them identical); the numbers are large and dominant, the labels small + quiet. */
.dash-page .ec-metrics { flex: 1 1 460px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: stretch; }
/* Top-anchor each tile's content so the three primary numbers sit on one shared
   line (the tiles differ in row count, so centring used to float them at three
   different heights). One consistent top padding + gap gives the row an even,
   intentional rhythm. */
.dash-page .exam-countdown .ec-metrics > * { padding: 13px 16px 12px; gap: 5px; min-width: 0; justify-content: flex-start; }
/* Gold day count stays the anchor, but a gentler step over the 26px stat numbers
   (was 40px) keeps the row from looking lopsided. */
.dash-page .ec-days-chip strong { font-size: 34px; }
.dash-page .ec-prog-count,
.dash-page .exam-countdown .ec-stat strong { font-size: 26px; }
/* The day count is larger than the other numbers, so seat every primary number in
   one shared-height box, glyph baseline-aligned to its floor. That lands the labels
   beneath them ("days until exam", "average score", "questions covered") on one
   common line across the row. */
.dash-page .ec-metrics > * > strong { display: flex; align-items: flex-end; justify-content: center; min-height: 38px; }
.dash-page .exam-countdown .ec-stat span,
.dash-page .ec-days-chip span,
.dash-page .ec-prog-label,
.dash-page .ec-prog-pct { font-size: 9.5px; }
/* Pace pill (days tile) + pass pill (score tile) MUST read as one identical pair.
   This single high-specificity rule (4 classes) overrides every base/variant rule,
   so size, weight, colour and gold shade are pixel-for-pixel the same on both. */
.dash-page .exam-countdown .ec-days-chip .ec-pace,
.dash-page .exam-countdown .ec-days-chip .ec-pace-ok,
.dash-page .exam-countdown .ec-days-chip .ec-pace-behind,
.dash-page .exam-countdown .ec-days-chip .ec-pace-aim,
.dash-page .exam-countdown .ec-stat .ec-pass-note {
  font-size: 10.5px; font-weight: 500; padding: 4px 12px; max-width: 94%;
  border-radius: 10px; letter-spacing: .03em; line-height: 1.35; text-align: center; text-transform: none;
  color: rgba(208,180,120,.95); background: rgba(200,169,106,.12); border: 1px solid rgba(200,169,106,.34);
}

/* === MAIN ROW: three columns ============================================== */
/* Practice (left) · Exam plan + calendar (centre, the hero visual) · Topic review
   (right). Giving the diagnostic its own column - rather than a full-width band
   beneath - hands the whole row height to all three, so nothing is squished. */
.dash-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.2fr) minmax(0, 1.3fr);
  gap: 14px; min-height: 0; overflow: hidden;
}
.dash-main > * { min-width: 0; min-height: 0; overflow: hidden; box-sizing: border-box; }

/* === TODAY'S SESSION (fills the left cell) ================================ */
.today { height: 100%; background: var(--surface); border-radius: 14px; padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; }
.today-head { display: flex; flex-direction: column; }
/* Shared dashboard card-header type: Practice / Exam plan / Topic review all use
   this exact size + weight + zero margin so their titles align on one baseline. */
.today-head h2 { font-family: var(--f-display); font-size: 18px; font-weight: 580; line-height: 1.2; margin: 0; color: var(--ink-0); }
.today-context { font-size: 12.5px; line-height: 1.4; color: var(--ink-2); margin: 0; }
.today-cta { margin: 0; }
/* Daily review: a compact card (matching the alt cards' radius/padding) — title +
   subline on the left, the gold CTA on the right — not a bare full-width button. */
.today-daily {
  margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--line);
  transition: border-color .2s, box-shadow .2s;
}
.today-daily:hover { border-color: var(--line-2); box-shadow: var(--sh-sm); }
.daily-info { min-width: 0; }
.daily-info h3 { font-family: var(--f-display); font-size: 15px; font-weight: 560; margin: 0 0 2px; color: var(--ink-0); }
.daily-info p { font-size: 11.5px; line-height: 1.3; color: var(--ink-2); margin: 0; }
.today-go { flex: none; font-size: 13px; font-weight: 600; padding: 10px 18px; border-radius: 9px; white-space: nowrap; box-shadow: 0 0 0 1px var(--gold-2), 0 8px 18px -12px rgba(11, 16, 32, 0.5); }
.today-go:hover { box-shadow: 0 0 0 1px var(--gold-2), 0 12px 22px -12px rgba(11, 16, 32, 0.55); }
/* Custom session sizes to its own content (so both dropdowns, the count field and
   the button are always fully visible); Sudden death fills the remaining height. */
.today-alts { flex: 1; min-height: 0; display: grid; grid-template-rows: auto minmax(0, 1fr); gap: 12px; }
.today-alt { display: flex; flex-direction: column; overflow: visible; padding: 14px 16px; background: var(--surface-2); border: 1px solid var(--line); box-shadow: none; }
.today-alt:hover { border-color: var(--line-2); box-shadow: var(--sh-sm); transform: none; }
.today-alt h3 { font-family: var(--f-display); font-size: 15px; font-weight: 560; margin: 0 0 2px; color: var(--ink-0); }
.today-alt p { font-size: 11.5px; line-height: 1.3; color: var(--ink-2); margin: 0; }
.today-alt .mode-info { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.today-alt .mode-fields { margin-top: 4px; gap: 6px; }
/* Compact the picker controls so Custom session stays short. */
.today-alt .ms > summary { padding: 6px 10px; font-size: 12px; }
/* Cap the open panel at ~5 option rows (each ≈33px + 12px padding) then scroll, so a
   long topic/module list never runs down into the Sudden-death card below. */
.today-alt .ms-panel { max-height: 177px; }
/* Count control reads as one unit: the "20" box flush-left under the dropdowns
   above it, "Questions" tight beside it, both vertically centred. */
.today-alt .mode-fields .ms-num { padding: 0; gap: 6px; }
.today-alt .ms-num input { height: 32px; width: 48px; text-align: center; }
.today-alt .ms-step { height: 32px; width: 32px; font-size: 17px; }
.today-alt .mode-stats { margin: 4px 0 0; }
/* Sudden death's streak reads as one compact inline line ("0 BEST STREAK") rather
   than a tall stacked number, so the card's content fits its row and the action
   button sits cleanly at the foot. Number, label and button are all centred. */
.today-alt .mode-stats-solo { justify-content: center; }
.today-alt .mode-stats-solo > div { flex-direction: row; align-items: baseline; justify-content: center; gap: 8px; text-align: center; }
.today-alt .mode-stats strong { font-family: var(--f-display); font-size: 22px; font-weight: 600; line-height: 1; color: var(--ink-0); }
.today-alt .mode-stats-solo span { align-self: center; }
.today-alt .mode-stats span { font-size: 10px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
/* The alt-card actions ("Build session", "Start sudden death") wear the same
   ink-fill + gold-outline treatment as the "Start review" CTA, but stretch full
   width at the foot of their card. One consistent primary-button language. */
.today-alt .btn-primary { margin-top: auto; align-self: stretch; width: 100%; font-size: 12.5px; padding: 9px 14px; border-radius: 9px; box-shadow: 0 0 0 1px var(--gold-2), 0 8px 18px -12px rgba(11, 16, 32, 0.5); }
.today-alt .btn-primary:hover { box-shadow: 0 0 0 1px var(--gold-2), 0 12px 22px -12px rgba(11, 16, 32, 0.55); }

/* === WHERE YOU STAND (fills its cell, rows scroll internally) ============= */
.dash-page .coverage-card { margin: 0; padding: 16px 18px; display: flex; flex-direction: column; overflow: hidden; }
.dash-page .coverage-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 12px; flex: none; }
.dash-page .coverage-head h2 { font-family: var(--f-display); font-size: 18px; font-weight: 580; line-height: 1.2; margin: 0; color: var(--ink-0); white-space: nowrap; }
/* Match the "Start review" CTA geometry (radius + height) so dashboard CTAs read as
   one family; the dark-mode fill override above matches its colour too. */
.dash-page .coverage-head .btn-blue,
.dash-page .coverage-head .btn-upgrade { flex: none; padding: 10px 18px; font-size: 13px; border-radius: 9px; }
/* Gold hairline outline to match the "Start review" CTA (.today-go), so the
   Topic-review action reads as the same primary-button family. */
.dash-page .coverage-head .btn-blue { box-shadow: 0 0 0 1px var(--gold-2), 0 8px 18px -12px rgba(11, 16, 32, 0.5); }
.dash-page .coverage-head .btn-blue:hover { box-shadow: 0 0 0 1px var(--gold-2), 0 12px 22px -12px rgba(11, 16, 32, 0.55); }
.dash-page #coverage { flex: 1; min-height: 0; overflow-y: auto; }
/* Compact two-line row for the narrow column: topic + exam weight on top, the
   coverage bar + accuracy pill below. The column header and per-row "Drill this"
   link are dropped (no room, and the whole row is clickable to drill). */
.dash-page .cov-head { display: none; }
.dash-page .cov-row {
  display: grid; align-items: center;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name wt" "track acc"; gap: 7px 10px;
}
.dash-page .cov-name { grid-area: name; }
.dash-page .cov-acc-cap { grid-area: wt; align-self: end; }
.dash-page .cov-track { grid-area: track; }
.dash-page .cov-acc { grid-area: acc; align-self: start; }
.dash-page .cov-drill { display: none; }
.dash-page .cov-row { padding: 9px 10px; border-bottom: 1px solid var(--line); border-radius: 8px; cursor: pointer; transition: background .12s; }
.dash-page .cov-row:hover { background: var(--accent-t); }
.cov-name { display: flex; flex-direction: column; gap: 2px; font-size: 13px; font-weight: 600; color: var(--ink-1); min-width: 0; overflow: hidden; }
.cov-focus { background: var(--gold-t); box-shadow: inset 3px 0 0 var(--gold); }
.cov-focus:hover { background: rgba(155, 122, 60, 0.15); }
.cov-focus-tag { align-self: flex-start; font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--gold); }
/* Exam weight now reads inline in brackets beside the topic name (e.g. "Ethics
   (10–15%)"), in a quieter weight so the topic still leads. */
.cov-wt { font-size: 11.5px; font-weight: 500; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* "Accuracy" caption above the accuracy value (top-right), so the % below it is
   clearly labelled and never confused with the bracketed exam weight. */
.cov-acc-cap { font-size: 8px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); line-height: 1.2; text-align: right; }
.cov-track { position: relative; height: 20px; border-radius: 999px; overflow: hidden; background: var(--surface-2); border: 1px solid var(--line); display: flex; align-items: center; }
/* The gold fill begins around the middle/right of the fraction pill (left offset) and
   runs proportional to coverage, feeding out from behind the pill (which floats on top)
   so there's no gap — the bar appears to emerge from the pill. */
.cov-fill { position: absolute; left: 22px; top: 0; bottom: 0; min-width: 2px; background: linear-gradient(90deg, var(--gold), var(--gold-2)); border-radius: 999px; }
/* The score fraction reads as a small high-contrast chip flush-left in the track, so
   it's legible against the empty track and the gold fill picks up where it ends. The
   chip surface + ink invert with the theme, so it stays readable in light and dark. */
.cov-track-lab {
  position: relative; z-index: 1; flex: none; margin-left: 0;
  padding: 1px 7px; border-radius: 999px;
  background: var(--surface); color: var(--ink-0);
  box-shadow: 0 0 0 1px var(--line);
  font-size: 10px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.cov-acc { justify-self: center; display: inline-flex; align-items: center; justify-content: center; min-width: 42px; padding: 2px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap; background: var(--surface-2); color: var(--ink-3); }
/* Below 50% reads "Needs work" in a soft amber/clay — attention, not alarm — so a
   couple of unlucky attempts never paints a topic in harsh red. */
.cov-acc.acc-low { background: rgba(176, 106, 60, 0.13); color: #a4632f; }
.cov-acc.acc-mid { background: var(--gold-t); color: var(--gold); }
.cov-acc.acc-ok  { background: rgba(47, 107, 79, 0.12); color: var(--ok); }
.cov-drill { justify-self: end; font-size: 11.5px; font-weight: 600; color: var(--gold); text-decoration: none; padding: 4px 9px; border-radius: 7px; white-space: nowrap; transition: background .13s, color .13s; }
.cov-drill:hover { background: var(--gold-t); color: var(--ink-0); }

/* === EXAM PLAN (right column, calendar fills the rest) ==================== */
.dash-page .schedule-card { margin: 0; padding: 16px 18px; display: flex; flex-direction: column; min-height: 0; overflow: hidden; scroll-margin-top: 60px; }
.dash-page .sched-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 12px; flex: none; }
/* Title + derived metrics share one baseline-aligned row: "Exam plan" then the
   "202 hours remaining · …" line beside it (wrapping only if the column is tight). */
.dash-page .sched-head-text { min-width: 0; flex: 1 1 auto; display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 12px; }
.dash-page .sched-title { font-family: var(--f-display); font-size: 18px; font-weight: 580; line-height: 1.2; margin: 0; color: var(--ink-0); flex: none; }
.sched-derived { font-family: var(--f-display); font-size: 14.5px; font-weight: 460; line-height: 1.45; color: var(--ink-2); margin: 0; }
.dash-page .sched-derived { font-size: 12.5px; }
.sched-derived strong { color: var(--ink-0); font-weight: 600; font-variant-numeric: tabular-nums; }
.sched-dot { color: var(--gold-2); margin: 0 3px; }
/* "Adjust plan" reads as a clear pill button (gold-tint fill + hairline gold
   border) so candidates can see at a glance where to change the exam date, rather
   than a bare text link that blends into the heading. */
.adjust-link {
  flex: none; cursor: pointer; text-decoration: none;
  font-family: var(--f); font-size: 12.5px; font-weight: 600; color: var(--gold);
  padding: 7px 14px; border-radius: 999px; white-space: nowrap;
  background: var(--gold-t); border: 1px solid var(--gold-2);
  transition: background .13s, color .13s, border-color .13s;
}
.adjust-link:hover, .adjust-link.is-open {
  background: var(--gold-2); color: #fff; border-color: var(--gold-2);
}

.dash-page .sched-strip { display: flex; flex-wrap: wrap; gap: 10px 12px; align-items: flex-end; margin: 0 0 12px; padding: 12px 14px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; flex: none; }
.dash-page .sched-strip[hidden] { display: none; }
.sched-field { display: flex; flex-direction: column; gap: 4px; font-size: 9.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); }
.sched-field input { height: 34px; width: 150px; max-width: 100%; padding: 0 10px; box-sizing: border-box; font: inherit; font-size: 13px; border: 1px solid var(--line-2); border-radius: 8px; background: var(--surface); color: var(--ink-0); }
.sched-field input:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 1px; border-color: var(--gold-2); }
.dash-page .sched-strip .msg { align-self: center; margin: 0; }

.dash-page .cal { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.dash-page .cal-nav { margin-bottom: 12px; gap: 12px; flex: none; }
.dash-page .cal-nav-btn { width: 30px; height: 30px; }
.dash-page .cal-legend { margin: 0; gap: 6px 8px; font-size: 10.5px; min-width: 0; }
/* Each legend entry reads as a small, consistent pill (swatch + label) rather than
   loose inline text, so the key scans as one tidy row. */
.dash-page .cal-legend span {
  gap: 5px; padding: 3px 9px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--ink-2);
}
.dash-page .cal-legend .cal-key { width: 10px; height: 10px; border-radius: 3px; }
/* Two readable months that FILL the column height. Each month is a flex column
   whose day grid flexes to the available space with equal-height rows
   (grid-auto-rows: 1fr), so a 5- or 6-week month always shows every week instead
   of clipping the last row. Blocks stretch (align-items) to use the full height. */
.dash-page .cal-months {
  flex: 1; min-height: 0; overflow: hidden;
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 22px;
  align-content: stretch; align-items: stretch;
}
.dash-page .cal-month-block { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* Let the 7 day-columns shrink below their content width so each month stays
   inside its own third of the row instead of overflowing into the next month. */
.dash-page .cal-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.dash-page .cal-cell { overflow: hidden; }
.dash-page .cal-month-title { font-size: 15px; margin-bottom: 9px; flex: none; }
.dash-page .cal-dow { margin-bottom: 5px; flex: none; }
.dash-page .cal-dow-cell { font-size: 10px; padding: 1px 0; }
.dash-page .cal-days { gap: 5px; flex: 1; min-height: 0; grid-auto-rows: 1fr; }
.dash-page .cal-cell { min-height: 0; padding: 6px 8px; }
.dash-page .cal-num { font-size: 14px; }
.dash-page .cal-hrs { font-size: 9.5px; font-weight: 500; color: var(--ink-4); }

/* === FOOTER: reuses the Import page's .import-foot, and now lives OUTSIDE the
   cockpit grid (a flex child of .home-wrap) so it runs FULL-BLEED exactly like the
   Import page. The home-wrap has a 32px gutter, so -32px side margins take the bar
   edge-to-edge; the inner keeps the Import page's 56px content inset, 24px gap and
   8px vertical padding, so the bar is visually identical across pages. ========== */
/* Breathing room between the cockpit cards and the footer (the bar is a flex child
   after .dash, which has no gap), then break full-bleed with -32px side margins (the
   home-wrap's gutter) so the bar runs edge-to-edge. The inner then re-applies the
   Import page's EXACT 56px content inset, 24px gap and 8px vertical padding, so the
   footer is pixel-identical to the Import footer - switching tabs shows no shift. */
.dash-page .import-foot { margin: 18px -32px 0; }
.dash-page .import-foot-inner { padding: 8px 56px; gap: 24px; }

.dash-foot { display: flex; align-items: center; justify-content: space-between; gap: 18px; border-top: 1px solid var(--line); padding-top: 8px; }
/* Roomier line-height so the enlarged α isn't clipped by overflow:hidden. */
.dash-foot-note { margin: 0; font-size: 11px; line-height: 1.6; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.dash-foot-note .brand-a { color: var(--gold-2); font-weight: 700; font-style: normal; font-size: 1.45em; line-height: 1; vertical-align: baseline; margin-right: 1px; }
.dash-foot-links { margin: 0; display: flex; gap: 4px; flex: none; }
.dash-foot-links a { font-size: 12px; color: var(--ink-4); text-decoration: none; padding: 2px 8px; border-radius: var(--r-sm); transition: color .13s, background .13s; }
.dash-foot-links a:hover { color: var(--ink-1); background: var(--surface-3); }

/* Taller screens: a touch more breathing room (cells flex to fill, so no fixed
   height here - that would clip 6-week months). */
@media (min-height: 980px) {
  .dash-page .ec-days-chip strong { font-size: 37px; }
}

/* Below ~1100px: release the fixed frame and let the page scroll + stack. */
@media (max-width: 1100px) {
  body.dash-page { overflow: auto; }
  .dash-page .home-wrap { height: auto; overflow: visible; max-width: 1040px; padding: 24px 22px 64px; }
  /* Below the fixed-frame breakpoint the cockpit centres in a 1040px column with
     22px padding + the hero's 24px inner pad, so re-track the brand to the hero
     text (22 + 24 = 46px) instead of the desktop 56px. */
  .dash-page .bank-tabs { padding-left: max(46px, calc((100% - 1040px) / 2 + 46px)); padding-right: max(46px, calc((100% - 1040px) / 2 + 46px)); }
  .dash { height: auto; display: flex; flex-direction: column; gap: 24px; overflow: visible; }
  .dash > *, .dash-main > *, .dash-left > * { overflow: visible; }
  .dash-main { display: flex; flex-direction: column; gap: 24px; }
  .dash-left { display: flex; flex-direction: column; gap: 24px; }
  .dash-page #coverage { overflow: visible; }
  .dash-page .cal-cell { min-height: 42px; }
  .dash-foot-note { white-space: normal; }
}
@media (max-width: 760px) {
  /* Drop the 46px desktop-column nav padding (set by the <=1100px rule above) back
     to the phone default so all three tabs fit on line 1 instead of one wrapping. */
  .dash-page .bank-tabs { padding-left: 14px; padding-right: 14px; }
  /* The dash footer kept its desktop 56px side padding, which squeezed the legal
     note into a narrow column and wrapped it into a tall block. Match the mobile
     gutter so it reads as a short, full-width compact bar. */
  .dash-page .import-foot-inner { padding: 12px 22px; gap: 6px; }
  .dash-page .exam-countdown { flex-direction: column; align-items: stretch; gap: 16px; padding: 18px; }
  /* Stack the three metric tiles into one column. The pre-upload prompt state
     carries its own higher-specificity 3-column grid (.ec-metrics:has(...)),
     which otherwise out-ranked the line below and left the "tracker" tiles
     squished side-by-side; match that specificity so the override actually wins. */
  .dash-page .ec-metrics,
  .dash-page .exam-countdown .ec-metrics:has(.ec-tile-prompt) { grid-template-columns: 1fr; gap: 10px; }
  .dash-page .exam-countdown .ec-metrics > * { flex-direction: row; justify-content: space-between; text-align: left; }
  .today-alts { grid-template-columns: 1fr; }
  .today-go { width: 100%; }
  .dash-page .cal-months { grid-template-columns: 1fr; }
  .dash-page .cov-head { display: none; }
  .dash-page .cov-row { grid-template-columns: 1fr auto; gap: 8px 12px; }
  .cov-name { grid-column: 1 / -1; }
  .cov-wt { display: none; }
  .cov-track { grid-column: 1 / 2; }
  .cov-acc { grid-column: 2; justify-self: end; }
  .cov-drill { grid-column: 1 / -1; justify-self: start; padding-left: 0; }
  /* The footer full-bleeds with -32px margins sized for the desktop column;
     on mobile the dash page only has 22px side padding, so -32px spilled 10px
     past the right edge and re-introduced a sideways scroll. Match the mobile
     padding so it bleeds cleanly to both edges instead. */
  .dash-page .import-foot { margin-left: -22px; margin-right: -22px; }
}

/* ===========================================================================
   QUESTION BANK - dense working layout (loads last so it wins).
   A tighter KPI row + coverage table, slim sticky filter toolbar, collapsed
   topic rows by default, and a compact footer FIXED to the bottom of the
   viewport. Content reserves bottom space so the last rows are never hidden
   behind the bar. Scoped to body.bank-page so nothing else is affected.
   =========================================================================== */

/* Fixed compact footer: always visible, sits above the scrolling content with
   an opaque background + border so rows scroll cleanly beneath it. */
body.bank-page .home-wrap {
  min-height: auto;          /* fixed footer is out of flow - no flex-fill needed */
  padding-bottom: 68px;      /* clear the fixed bar so the last row stays visible */
}
body.bank-page .import-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  margin: 0;
  border-top: 1px solid var(--line);
  background: var(--bg);
}
/* On phones a fixed disclaimer bar would eat the bottom third of the list, so let
   it scroll with the content at the end of the page instead. */
@media (max-width: 760px) {
  body.bank-page .import-foot { position: static; margin-left: -16px; margin-right: -16px; }
  body.bank-page .home-wrap { padding-bottom: 24px; }
}

/* Title + one compact summary line; no KPI cards or coverage table, so the
   sticky toolbar sits directly beneath the summary with no large gap. */
body.bank-page .import-head { margin-bottom: 6px; }
body.bank-page .bank-summary { margin: 2px 0 0; font-size: 13px; font-variant-numeric: tabular-nums; }

/* "Reset progress" - a red button the same shape/size as the format dropdown,
   sitting at the far right of the toolbar where the dropdown used to be. */
body.bank-page .bank-reset {
  appearance: none; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--bad, #c0392b);
  background: var(--surface-2); border: 1px solid var(--bad, #c0392b); border-radius: 8px;
  padding: 7px 10px; cursor: pointer; max-width: 200px;
  transition: background .15s ease, color .15s ease;
}
body.bank-page .bank-reset:hover { background: var(--bad, #c0392b); color: #fff; }

/* Slim sticky filter toolbar, pinned just under the 56px nav. */
body.bank-page .bank-toolbar { padding: 7px 0; margin-bottom: 4px; }
body.bank-page .bank-list { margin-top: 6px; gap: 5px; }

/* Topic rows ~48px high; figures and the chevron stay aligned right. */
body.bank-page .bank-item.bank-topic > summary,
body.bank-page .bank-item.bank-other > summary {
  min-height: 48px; padding-top: 6px; padding-bottom: 6px;
}

/* Deep-linked topics scroll to the top of the view: leave room for the sticky
   56px nav + the sticky filter toolbar so the row isn't tucked underneath them. */
body.bank-page .bank-item.bank-topic { scroll-margin-top: 124px; }

/* Brief gold flash when a topic is opened via a deep-link from Review, so the
   eye lands on the right row after the scroll. */
body.bank-page .bank-item.bank-topic-flash {
  animation: bank-topic-flash 1.5s ease-out;
}
@keyframes bank-topic-flash {
  0%   { box-shadow: 0 0 0 2px var(--gold-2); }
  100% { box-shadow: 0 0 0 2px transparent; }
}

/* Compact expanded body - trim the blank gaps around the module list. */
body.bank-page .bank-body { padding: 4px 14px 10px; }
body.bank-page .lm-list { padding: 2px 2px; gap: 1px; }

/* Learning-module rows ~40px high, Drill aligned right. */
body.bank-page .lm-row { padding: 6px 10px; min-height: 40px; }
body.bank-page .lm-item > summary.lm-row { min-height: 40px; }

/* Expanded learning module: no heavy outline - a thin muted-gold left border
   and a barely-there tint mark the open module, so the section reads as one
   calm block rather than a boxed cluster. */
body.bank-page .lm-item[open] {
  background: var(--accent-t);
  border-left: 2px solid var(--gold-2);
  border-radius: var(--r-xs);
}
body.bank-page .lm-item[open] > summary.lm-row { background: transparent; }

/* Nested End-of-chapter / Examples rows: lighter, slightly indented and flat
   (no per-row box or border) so they sit quietly beneath their module. */
body.bank-page .lm-cats { padding: 1px 8px 6px 42px; gap: 0; }
body.bank-page .lm-cat-row {
  background: transparent; border-left: 0;
  padding: 5px 10px; min-height: 34px;
}
body.bank-page .lm-cat-row:hover { background: var(--surface-2); }

/* Tighter group divider so the pathway/core split doesn't push rows off-screen. */
body.bank-page .bank-section-divider { margin: 10px 2px 6px; padding-bottom: 6px; }
body.bank-page .bank-list > .bank-section-divider:first-child { margin-top: 2px; }
