/* This small PWA is served without a frontend build step. The file is
   colocated and named like a CSS Module, following Jellybot Platform's feature
   convention, while its selectors intentionally remain global.

   Design system: one loud brand green, heavy rounded type, 2px visible borders,
   and solid-offset "lips" that physically depress on press. Depth comes from
   flat colour offsets, never blur. Full light and dark support. */

@font-face {
  font-family: Quicksand;
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("fonts/quicksand.woff2") format("woff2");
}

:root {
  color-scheme: light dark;

  /* ground */
  --paper: #fff;
  --panel: #f9fafb;
  --panel-2: #f3f4f6;

  /* ink */
  --ink: #111927;
  --ink-2: #6c737f;
  --ink-3: #9da4ae;

  /* structural lines: --line is the stroke, --lip is the solid drop under it */
  --line: #e5e7eb;
  --lip: #d2d6db;

  /* brand */
  --brand: #36bffa;
  --brand-lip: #0ba5ec;
  --brand-soft: #e0f2fe;
  --brand-line: #7cd4fd;
  --brand-ink: #026aa2;
  --brand-contrast: #071827;

  /* semantic */
  --wrong: #ef4444;
  --wrong-lip: #dc2626;
  --wrong-soft: #fee2e2;
  --wrong-line: #fecaca;
  --wrong-ink: #b91c1c;
  --amber: #fbbf24;
  --amber-lip: #d97706;
  --amber-soft: #fef3c7;
  --amber-line: #fde68a;
  --amber-ink: #92400e;
  --info: #0ba5ec;
  --info-lip: #026aa2;
  --info-soft: #e0f2fe;

  /* mode accents — learn is green now that the chrome itself is blue */
  --m-f: #ff5c8a;
  --m-f-lip: #d63c69;
  --m-l: #22c55e;
  --m-l-lip: #16a34a;
  --m-v: #9b5cff;
  --m-v-lip: #7a3cd6;

  /* shape */
  --r: 16px;
  --r-lg: 20px;
  --r-xl: 28px;

  /* the signature depth: solid offset, no blur */
  --drop: 0 4px 0;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --sans:
    "Quicksand", ui-rounded, "SF Pro Rounded", "Hiragino Maru Gothic ProN", system-ui, -apple-system,
    "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0d1520;
    --panel: #131e2b;
    --panel-2: #1b2837;
    --ink: #f0f5fa;
    --ink-2: #a3b0bf;
    --ink-3: #71808f;
    --line: #233242;
    --lip: #060b11;
    --brand: #36bffa;
    --brand-lip: #0086c9;
    --brand-soft: #0b4a6f;
    --brand-line: #065986;
    --brand-ink: #7cd4fd;
    --brand-contrast: #071827;
    --wrong: #f87171;
    --wrong-lip: #dc2626;
    --wrong-soft: #3a1a1c;
    --wrong-line: #7a3131;
    --wrong-ink: #fca5a5;
    --amber: #fbbf24;
    --amber-lip: #b45309;
    --amber-soft: #33270f;
    --amber-line: #6d5322;
    --amber-ink: #fcd34d;
    --info: #36bffa;
    --info-lip: #026aa2;
    --info-soft: #0b3049;
    --m-f: #ff6d96;
    --m-f-lip: #c9445f;
    --m-l: #4ade80;
    --m-l-lip: #16a34a;
    --m-v: #a875ff;
    --m-v-lip: #7d4ad2;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: var(--paper);
  color: var(--ink);
  overflow: hidden;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
  padding: 0;
  user-select: none;
}

:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--info);
  outline-offset: 3px;
}

button,
.big,
.ghost,
.chip,
.pill,
input:not([type="checkbox"]),
select {
  min-height: 44px;
}

.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Uppercase micro-label. Buttons opt out below — they carry weight instead. */
.caps {
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.big.caps,
.ghost.caps,
.fab.caps,
.rate button.caps,
.why.caps {
  font-size: 0.92rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}

/* ---------- feed scroller ---------- */
#reel {
  position: fixed;
  inset: 0;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  overscroll-behavior: contain;
  scrollbar-width: none;

  touch-action: pan-y pinch-zoom;
}

#reel::-webkit-scrollbar {
  display: none;
}

.card {
  height: 100dvh;
  min-height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  padding: calc(84px + env(safe-area-inset-top)) 18px calc(96px + env(safe-area-inset-bottom));
  background: var(--paper);
}

.card .inner {
  width: 100%;
  max-width: 540px;
  min-height: 0;
  margin: 0 auto;
  overflow-y: auto;
  scrollbar-width: none;

  /* overflow clips painting at the box edge, and the last child's 4px lip
     (plus its 4px pressed travel) paints below its border box — without this
     inset the bottom shadow is sliced off against the background. */
  padding-bottom: 8px;
}

.card .inner::-webkit-scrollbar {
  display: none;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--panel);
  color: var(--ink-2);
  padding: 7px 14px;
  border-radius: 999px;
  margin-bottom: 20px;
}

.tag.fix {
  background: var(--wrong-soft);
  color: var(--wrong);
}

.draftnote {
  max-width: 34rem;
  margin: 0 0 18px;
  padding: 10px 12px;
  border: 2px solid var(--amber-line);
  border-radius: 12px;
  background: var(--amber-soft);
  color: var(--amber-ink);
  font-size: 0.86rem;
  font-weight: 700;
  line-height: 1.4;
}

.tag .rev {
  color: var(--brand-ink);
}

.q {
  font-size: clamp(1.5rem, 6vw, 1.95rem);
  font-weight: 800;
  line-height: 1.22;
  letter-spacing: -0.02em;
  margin: 0 0 10px;
  white-space: pre-line;
  text-wrap: balance;
}

.sub {
  color: var(--ink-3);
  font-weight: 700;
  margin: 0 0 22px;
}

.opts {
  display: grid;
  gap: 12px;
}

/* The signature control: 2px stroke, solid lip beneath, presses into the lip. */
.opt {
  display: flex;
  gap: 14px;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 16px 16px;
  border: 2px solid var(--line);
  border-radius: var(--r);
  background: var(--paper);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.35;
  box-shadow: var(--drop) var(--lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease),
    border-color 0.12s var(--ease),
    background 0.12s var(--ease);
}

.opt:not(:disabled):active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--lip);
}

@media (hover: hover) {
  .opt:not(:disabled):hover {
    background: var(--panel);
  }
}

.opt .l {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border: 2px solid var(--line);
  border-radius: 9px;
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--ink-3);
  transition:
    background 0.12s var(--ease),
    color 0.12s var(--ease),
    border-color 0.12s var(--ease);
}

.opt.sel {
  border-color: var(--info);
  background: var(--info-soft);
  box-shadow: var(--drop) var(--info-lip);
}

.opt.sel .l {
  border-color: var(--info);
  background: var(--info);
  color: var(--brand-contrast);
}

.opt.right {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--brand-ink);
  box-shadow: var(--drop) var(--brand-lip);
  animation: correct-pop 0.4s var(--ease);
}

.opt.right .l {
  border-color: var(--brand);
  background: var(--brand);
  color: var(--brand-contrast);
}

.opt.wrong {
  border-color: var(--wrong);
  background: var(--wrong-soft);
  color: var(--wrong-ink);
  box-shadow: var(--drop) var(--wrong-lip);
  animation: shake 0.4s var(--ease);
}

.opt.wrong .l {
  border-color: var(--wrong);
  background: var(--wrong);
  color: #fff;
}

.opt.dim {
  opacity: 0.4;
  box-shadow: none;
  transform: translateY(4px);
}

.opt:disabled {
  cursor: default;
}

@keyframes correct-pop {
  35% {
    transform: scale(1.02);
  }

  70% {
    transform: scale(0.995);
  }
}

@keyframes shake {
  20% {
    transform: translateX(-7px);
  }

  40% {
    transform: translateX(6px);
  }

  60% {
    transform: translateX(-4px);
  }

  80% {
    transform: translateX(3px);
  }
}

/* ---------- celebration ---------- */
.cf {
  position: absolute;
  width: 9px;
  height: 9px;
  z-index: 6;
  pointer-events: none;
  border: 0 !important;
  border-radius: 2px;
  animation: cfly 0.9s var(--ease) forwards;
}

@keyframes cfly {
  to {
    transform: translate(var(--dx), var(--dy)) rotate(320deg);
    opacity: 0;
  }
}

/* ---------- answer sheet ---------- */

/* #reel is position:fixed and forms its own stacking context, and the FAB must
   outrank the reel to float over opaque cards — so no z-index here can lift the
   sheet above it, and a bottom inset fails too because sheet content scrolls
   under the FAB. The FAB is tucked away instead (see below). */
.sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  background: var(--panel);
  border-top: 2px solid var(--line);
  max-height: 46dvh;
  overflow-y: auto;
  /* The nav is fixed at z-index 30 and this sheet is at 3, so without the
     clearance the last thing in here — the explanation, and the prompt to
     swipe on — sits underneath it. That is the one line a wrong answer exists
     to deliver, so it gets the same 78px the caption uses. */
  padding: 20px 18px calc(96px + env(safe-area-inset-bottom));
  transform: translateY(108%);
  transition: transform 0.36s cubic-bezier(0.3, 1.18, 0.4, 1);
}

.sheet.show {
  transform: none;
}

.sheet .in {
  max-width: 540px;
  margin: 0 auto;
}

.vrow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.why {
  border: 2px solid var(--line);
  border-radius: 12px;
  padding: 9px 16px;
  background: var(--paper);
  color: var(--ink-2);
  box-shadow: 0 3px 0 var(--lip);
  flex: none;
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.why:active {
  transform: translateY(3px);
  box-shadow: 0 0 0 var(--lip);
}

.more {
  margin-top: 14px;
}

/* Verdict reads as a headline, not a chip — the sheet itself is the surface. */
.sticker {
  display: inline-block;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.sticker.good {
  color: var(--brand-ink);
}

.sticker.bad {
  color: var(--wrong-ink);
}

.sheet .ans {
  font-weight: 800;
  font-size: 1.05rem;
  color: var(--ink);
  margin: 12px 0 0;
}

.sheet .exp {
  color: var(--ink-2);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.55;
}

.sheet .note,
.miss .note {
  margin-top: 12px;
  padding: 12px 14px;
  border: 2px solid var(--amber-line);
  border-radius: 12px;
  color: var(--amber-ink);
  background: var(--amber-soft);
  font-weight: 700;
  font-size: 0.88rem;
  line-height: 1.5;
}

/* ---------- swipe hint ---------- */
.hint {
  position: absolute;
  bottom: calc(14px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: none;
  pointer-events: none;
  background: var(--panel-2);
  color: var(--ink-3);
  padding: 8px 16px;
  border-radius: 999px;
}

.hint.show {
  display: block;
  animation: bob 1.5s var(--ease) infinite;
}

@keyframes bob {
  0%,
  100% {
    transform: translate(-50%, 0);
  }

  50% {
    transform: translate(-50%, -6px);
  }
}

.chip.streak.lit {
  background: var(--amber-soft);
  border-color: var(--amber-line);
}

/* ---------- session progress bar (quiz + mock) ---------- */
.feedbar {
  position: fixed;
  top: calc(4px + env(safe-area-inset-top));
  left: 16px;
  right: 16px;
  max-width: 540px;
  margin-inline: auto;
  height: 5px;
  z-index: 10;
  background: var(--panel-2);
  border-radius: 999px;
  overflow: hidden;
}

.feedbar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--brand);
  border-radius: 999px;
  transition: width 0.4s var(--ease);
}

.feedbar.done i {
  background: var(--amber);
}

/* ---------- overlay chrome ---------- */
.bar {
  position: fixed;
  left: 0;
  right: 0;

  /* On wide viewports the reel content column is 540px centered; the floating
     chrome must track that column, not the window edges, or it ends up marooned
     on the empty background. 572px = 540px column + 16px padding each side. */
  max-width: 572px;
  margin-inline: auto;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  pointer-events: none;
}

.bar.top {
  top: calc(14px + env(safe-area-inset-top));
}

.bar > * {
  pointer-events: auto;
}

.bargroup {
  display: flex;
  gap: 9px;
  pointer-events: auto;
}

.chip {
  display: inline-flex;
  gap: 7px;
  align-items: center;
  padding: 9px 15px;
  border-radius: 999px;
  background: var(--paper);
  border: 2px solid var(--line);
  color: var(--ink-2);
  font-weight: 800;
  box-shadow: 0 3px 0 var(--lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.chip:active {
  transform: translateY(3px);
  box-shadow: 0 0 0 var(--lip);
}

.chip.streak {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--amber-lip);
}

.chip.streak svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

.chip.timer {
  position: fixed;
  top: calc(14px + env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  font-variant-numeric: tabular-nums;
  z-index: 10;
  color: var(--ink);
}

.chip.timer:active {
  transform: translateX(-50%) translateY(3px);
}

.chip.timer.low {
  background: var(--wrong);
  border-color: var(--wrong);
  color: #fff;
  box-shadow: 0 3px 0 var(--wrong-lip);
  animation: tock 1s var(--ease) infinite;
}

@keyframes tock {
  50% {
    transform: translateX(-50%) scale(1.06);
  }
}

.pop {
  animation: pop 0.4s var(--ease);
}

@keyframes pop {
  40% {
    transform: scale(1.28) rotate(-4deg);
  }
}

.fab {
  position: fixed;
  right: max(16px, calc(50vw - 254px));
  bottom: calc(22px + env(safe-area-inset-bottom));
  z-index: 10;
  padding: 15px 22px;
  background: var(--brand);
  color: var(--brand-contrast);
  border-radius: var(--r);
  box-shadow: var(--drop) var(--brand-lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.fab:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--brand-lip);
}

/* Answering tucks the mock-test button away so it can never sit on top of the
   answer sheet. Answered cards stay mounted in the reel, so it stays hidden for
   the rest of the feed session — the mock test remains reachable from Home. */
body:has(.sheet.show) .fab {
  display: none;
}

/* ---------- modal sheets ---------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgb(22 35 60 / 55%);
  display: none;
  align-items: flex-end;
  justify-content: center;
}

.modal.show {
  display: flex;
}

.panel {
  position: relative;
  width: 100%;
  max-width: 540px;
  background: var(--paper);
  border-top: 2px solid var(--line);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: 26px 18px calc(26px + env(safe-area-inset-bottom));
  max-height: 82dvh;
  overflow-y: auto;
  animation: sheetup 0.28s var(--ease);
}

.panel::before {
  content: "";
  position: absolute;
  top: 10px;
  left: 50%;
  width: 40px;
  height: 5px;
  border-radius: 999px;
  background: var(--panel-2);
  transform: translateX(-50%);
}

@keyframes sheetup {
  from {
    transform: translateY(18%);
  }
}

.panel h2 {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 4px;
}

.panel .phead {
  color: var(--ink-3);
  font-weight: 700;
  margin: 0 0 20px;
  font-size: 0.95rem;
}

.rowwrap {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.pill {
  padding: 11px 18px;
  border: 2px solid var(--line);
  border-radius: 999px;
  font-weight: 800;
  background: var(--paper);
  color: var(--ink-2);
  box-shadow: 0 3px 0 var(--lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.pill:active {
  transform: translateY(3px);
  box-shadow: 0 0 0 var(--lip);
}

.pill.on {
  background: var(--info);
  border-color: var(--info);
  color: var(--brand-contrast);
  box-shadow: 0 3px 0 var(--info-lip);
}

select {
  width: 100%;
  margin: 4px 0 18px;
  padding: 15px 16px;
  border-radius: var(--r);
  font-size: 1rem;
  font-weight: 700;
  font-family: var(--sans);
  background: var(--panel);
  color: var(--ink);
  border: 2px solid var(--line);
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, currentcolor 50%),
    linear-gradient(135deg, currentcolor 50%, transparent 50%);
  background-position:
    calc(100% - 21px) calc(50% + 1px),
    calc(100% - 15px) calc(50% + 1px);
  background-size:
    6px 6px,
    6px 6px;
  background-repeat: no-repeat;
}

.big {
  display: block;
  width: 100%;
  text-decoration: none;
  padding: 17px;
  border-radius: var(--r);
  background: var(--brand);
  color: var(--brand-contrast);
  text-align: center;
  text-decoration: none;
  box-shadow: var(--drop) var(--brand-lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.big:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--brand-lip);
}

.big.danger {
  background: var(--amber);
  color: #4a3000;
  box-shadow: var(--drop) var(--amber-lip);
}

.big.danger:active {
  box-shadow: 0 0 0 var(--amber-lip);
}

.big.disabled {
  background: var(--panel-2);
  color: var(--ink-3);
  box-shadow: none;
  cursor: default;
  transform: none;
}

.ghost {
  display: block;
  width: 100%;
  padding: 15px;
  margin-top: 12px;
  border: 2px solid var(--line);
  border-radius: var(--r);
  background: var(--paper);
  color: var(--ink-2);
  text-align: center;
  box-shadow: var(--drop) var(--lip);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.ghost:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--lip);
}

.hist {
  margin: 22px 0 0;
  font-size: 0.95rem;
  font-weight: 700;
}

.hist b.caps {
  display: block;
  color: var(--ink-3);
  margin-bottom: 8px;
}

.hist div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 2px solid var(--line);
  color: var(--ink-2);
}

.hist div:last-child {
  border-bottom: 0;
}

.hist div b {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- score / review ---------- */
.scorewrap {
  text-align: center;
}

@keyframes score-pop {
  0% {
    opacity: 0;
    transform: scale(0.3);
  }

  65% {
    transform: scale(1.06);
  }
}

.scorenum {
  animation: score-pop 0.5s var(--ease) both;
  font-size: 5rem;
  font-weight: 800;
  line-height: 1;
  margin: 18px 0 10px;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--brand-ink);
}

.scorenum small {
  font-size: 1.6rem;
  color: var(--ink-3);
}

.stamp {
  display: inline-block;
  padding: 11px 26px;
  border-radius: 999px;
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  margin: 6px 0;
  background: var(--panel-2);
  color: var(--ink-2);
}

.stamp.pass {
  background: var(--brand);
  color: var(--brand-contrast);
  box-shadow: var(--drop) var(--brand-lip);
}

.stamp.fail {
  background: var(--wrong);
  color: #fff;
  box-shadow: var(--drop) var(--wrong-lip);
}

.stamp.pass,
.stamp.fail {
  animation: score-pop 0.45s var(--ease) 0.12s backwards;
}

.resultStatus {
  margin-top: 16px;
  color: var(--ink-3);
}

.fullMarks {
  font-size: 1.35rem;
  margin: 0;
}

.actions {
  max-width: 330px;
  margin: 28px auto 0;
}

#review {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: var(--panel);
  overflow-y: auto;
  display: none;
  padding: calc(78px + env(safe-area-inset-top)) 18px 48px;
}

#review.show {
  display: block;
}

#review .inner {
  max-width: 540px;
  margin: 0 auto;
}

#review h2 {
  font-size: 1.7rem;
  font-weight: 800;
  letter-spacing: -0.025em;
  margin: 0 0 20px;
}

.miss {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--drop) var(--lip);
  padding: 18px;
  margin-bottom: 16px;
}

.miss .mq {
  font-weight: 800;
  letter-spacing: -0.015em;
  margin: 0 0 12px;
  white-space: pre-line;
}

.miss .you,
.miss .cor {
  font-size: 0.95rem;
  font-weight: 700;
  padding: 8px 12px;
  border-radius: 10px;
}

.miss .you {
  color: var(--wrong-ink);
  background: var(--wrong-soft);
}

.miss .cor {
  color: var(--brand-ink);
  background: var(--brand-soft);
  margin-top: 6px;
}

.miss .exp {
  color: var(--ink-2);
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.55;
  margin-top: 12px;
}

.closex {
  position: fixed;
  top: calc(14px + env(safe-area-inset-top));
  right: max(16px, calc(50vw - 254px));
  z-index: 31;
}

/* ---------- shared scroll panes ---------- */
#home,
#practice,
#learn,
#cards {
  position: fixed;
  inset: 0;
  background: var(--paper);
  overflow-y: auto;
  display: none;
  padding: calc(20px + env(safe-area-inset-top)) 18px calc(34px + env(safe-area-inset-bottom));
}

#home {
  z-index: 25;
}

#practice {
  z-index: 26;
}

#learn {
  z-index: 27;
}

#cards {
  z-index: 28;
}

#home.show,
#practice.show,
#learn.show,
#cards.show {
  display: block;
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}

#home.show .hinner > *,
#practice.show .pinner > *,
#learn.show .linner > *,
#cards.show .cinner > * {
  animation: rise-in 0.34s var(--ease) backwards;
}

#home.show .hinner > :nth-child(2),
#practice.show .pinner > :nth-child(2),
#learn.show .linner > :nth-child(2),
#cards.show .cinner > :nth-child(2) {
  animation-delay: 0.05s;
}

#home.show .hinner > :nth-child(3),
#practice.show .pinner > :nth-child(3),
#learn.show .linner > :nth-child(3),
#cards.show .cinner > :nth-child(3) {
  animation-delay: 0.1s;
}

#home.show .hinner > :nth-child(4),
#practice.show .pinner > :nth-child(4),
#learn.show .linner > :nth-child(4),
#cards.show .cinner > :nth-child(4) {
  animation-delay: 0.15s;
}

#home.show .hinner > :nth-child(n + 5),
#practice.show .pinner > :nth-child(n + 5),
#learn.show .linner > :nth-child(n + 5),
#cards.show .cinner > :nth-child(n + 5) {
  animation-delay: 0.2s;
}

#home .hinner,
#practice .pinner,
#learn .linner,
#cards .cinner {
  max-width: 540px;
  margin: 0 auto;
}

#home h1 {
  font-size: clamp(1.9rem, 7vw, 2.4rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.032em;
  margin: 16px 0 14px;
  text-wrap: balance;
}

#practice h1,
#learn h1,
#cards h1 {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.12;
  margin: 16px 0 6px;
}

#home .sub,
#practice .sub,
#learn .sub,
#cards .sub {
  margin: 0 0 24px;
  max-width: 44ch;
  line-height: 1.55;
}

/* ---------- home header row + settings ---------- */
.hrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

/* chips size to their label; the row wraps rather than the words */
.hrow .chip,
.hrow .tag {
  white-space: nowrap;
}

.hrow .tag {
  margin-bottom: 0;
}

/* account + settings travel together, so a narrow header wraps the date
   chip onto its own line rather than orphaning the gear */
.hactions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.chip.acct {
  text-decoration: none;
}

.chip.gear {
  padding: 8px 12px;
  font-size: 1rem;
  flex: none;
}

.setlabel {
  display: block;
  color: var(--ink-3);
  margin: 14px 0 6px;
}

input[type="date"] {
  width: 100%;
  padding: 13px 14px;
  border: 2px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
}

.setrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0;
  min-height: 44px;
  font-weight: 700;
}

.setrow input {
  width: 22px;
  height: 22px;
  accent-color: var(--brand);
}

/* ---------- home stats ---------- */
.goal {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--drop) var(--lip);
  padding: 12px 16px;
  margin-bottom: 14px;
}

.goal .ring {
  width: 56px;
  height: 56px;
  flex: none;
}

.goal .track {
  fill: none;
  stroke: var(--panel-2);
  stroke-width: 9;
}

.goal .fill {
  fill: none;
  stroke: var(--brand);
  stroke-width: 9;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.7s var(--ease);
}

.goal.done .fill {
  stroke: var(--amber);
}

.goal .gtxt b {
  display: block;
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.goal .gtxt .caps {
  color: var(--ink-3);
  font-size: 0.64rem;
}

.goal .xp {
  margin-left: auto;
  background: var(--amber-soft);
  color: var(--amber-ink);
  border: 2px solid var(--amber-line);
  border-radius: 999px;
  padding: 7px 13px;
  font-size: 0.7rem;
  white-space: nowrap;
}

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 16px;
}

.tile {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--drop) var(--lip);
  padding: 14px 8px;
  text-align: center;
}

.tile b {
  display: block;
  font-size: 1.65rem;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.tile:nth-child(1) b {
  color: var(--info);
}

.tile:nth-child(2) b {
  color: var(--brand);
}

.tile:nth-child(3) b {
  color: var(--amber-lip);
}

.tile span {
  display: block;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: 5px;
}

/* ---------- mode cards ---------- */
.modes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 0 0 22px;
}

.mode {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--drop) var(--lip);
  padding: 16px;
  text-align: left;
  color: var(--ink);
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.mode:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--lip);
}

.mode .i {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  font-size: 1.4rem;
  line-height: 1;
  margin-bottom: 12px;
  overflow: hidden;
}

.mode .i svg {
  width: 24px;
  height: 24px;
  fill: #fff;
}

.mode.q .i svg {
  fill: var(--brand-contrast);
}

.mode .n {
  font-weight: 800;
  font-size: 1.1rem;
  letter-spacing: -0.018em;
  display: block;
}

.mode .c {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: 4px;
  display: block;
}

.mode.q .i {
  background: var(--brand);
  box-shadow: 0 3px 0 var(--brand-lip);
}

.mode.f .i {
  background: var(--m-f);
  box-shadow: 0 3px 0 var(--m-f-lip);
}

.mode.l .i {
  background: var(--m-l);
  box-shadow: 0 3px 0 var(--m-l-lip);
}

.mode.v .i {
  background: var(--m-v);
  box-shadow: 0 3px 0 var(--m-v-lip);
}

.mode.q {
  border-color: var(--brand-line);
}

/* ---------- practise chooser ---------- */
.practice-modes {
  display: grid;
  gap: 16px;
  margin: 8px 0 22px;
}

.practice-mode {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 18px;
  border: 2px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--paper);
  color: var(--ink);
  text-align: left;
  box-shadow: 0 5px 0 var(--lip);
  overflow: hidden;
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.practice-mode:active {
  transform: translateY(5px);
  box-shadow: none;
}

.practice-mode.mock {
  border-color: var(--brand-line);
}

/* One deliberate departure from the paper UI: Doomscroll looks like the
   dark, infinite feed it opens, while Mock tests keeps the exam-sheet ground. */
.practice-mode.doom {
  border-color: #071827;
  background: #071827;
  color: #fff;
  box-shadow: 0 5px 0 #000;
}

.practice-mark {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 20px;
  background: var(--brand);
  color: var(--brand-contrast);
  box-shadow: 0 4px 0 var(--brand-lip);
  font-size: 1.55rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}

.practice-mode.doom .practice-mark {
  background: var(--m-f);
  color: #fff;
  box-shadow: 0 4px 0 var(--m-f-lip);
  font-size: 2rem;
}

.practice-copy {
  min-width: 0;
}

.practice-copy b,
.practice-copy span,
.practice-copy small {
  display: block;
}

.practice-copy b {
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.025em;
}

.practice-copy span {
  margin-top: 3px;
  color: var(--ink-2);
  font-size: 0.9rem;
  font-weight: 650;
  line-height: 1.35;
}

.practice-copy small {
  margin-top: 8px;
  color: var(--ink-3);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.practice-mode.doom .practice-copy span {
  color: rgb(255 255 255 / 72%);
}

.practice-mode.doom .practice-copy small {
  color: rgb(255 255 255 / 52%);
}

.practice-arrow {
  font-size: 1.55rem;
  font-weight: 800;
  color: var(--brand-ink);
}

.practice-mode.doom .practice-arrow {
  color: var(--m-f);
}

.practice-note {
  margin: 0 0 18px;
  padding: 13px 15px;
  border: 2px solid var(--amber-line);
  border-radius: var(--r);
  background: var(--amber-soft);
  color: var(--amber-ink);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.5;
}

@media (max-width: 390px) {
  .practice-mode {
    grid-template-columns: 54px minmax(0, 1fr) auto;
    gap: 12px;
    padding: 15px;
  }

  .practice-mark {
    width: 54px;
    height: 54px;
    border-radius: 17px;
  }
}

#home .big {
  margin-top: 0;
}

/* ---------- chapter progress ---------- */
.chrows {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--drop) var(--lip);
  padding: 6px 16px;
  margin: 24px 0;
}

.chrow {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 2px solid var(--line);
}

.chrow:last-child {
  border-bottom: 0;
}

.chrow .nm {
  width: 94px;
  font-weight: 800;
  font-size: 0.9rem;
  white-space: nowrap;
}

.chbar {
  flex: 1;
  height: 12px;
  border-radius: 999px;
  background: var(--panel-2);
  overflow: hidden;
}

.chbar i {
  position: relative;
  display: block;
  height: 100%;
  background: var(--brand);
  border-radius: 999px;
  transition: width 0.6s var(--ease);
}

.chbar i::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 4px;
  right: 4px;
  height: 3px;
  border-radius: 999px;
  background: rgb(255 255 255 / 25%);
}

.chrow .pc {
  width: 82px;
  text-align: right;
  font-size: 0.78rem;
  font-weight: 800;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

#home .hist {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--drop) var(--lip);
  padding: 16px 18px;
  margin-top: 24px;
}

.smallprint {
  margin: 26px 0 0;
  color: var(--ink-3);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.5;
}

/* ---------- learn ---------- */
.catgrid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.cat {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--drop) var(--lip);
  padding: 16px;
  text-align: left;
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.cat:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--lip);
}

.cat .i {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 13px;
  background: var(--panel);
  font-size: 1.25rem;
  line-height: 1;
  margin-bottom: 10px;
}

.cat .n {
  display: block;
  font-weight: 800;
  font-size: 1rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
}

.cat .c {
  display: block;
  color: var(--ink-3);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 5px;
}

.fact {
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--drop) var(--lip);
  padding: 16px 18px;
  margin-bottom: 12px;
}

.fact b {
  display: block;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  margin-bottom: 4px;
}

.fact span {
  color: var(--ink-2);
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1.55;
}

.learnHome {
  margin-top: 14px;
}

#learn .big {
  margin-top: 22px;
}

/* ---------- flashcards ---------- */
.deck {
  display: block;
  width: 100%;
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--drop) var(--lip);
  padding: 16px 18px;
  margin-bottom: 12px;
  text-align: left;
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.deck:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--lip);
}

.deck b {
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.015em;
}

.deck span {
  display: block;
  color: var(--ink-3);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 5px;
}

.fcbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 12px;
}

.flipwrap {
  perspective: 1400px;
  margin-bottom: 14px;
}

.flip {
  position: relative;
  width: 100%;
  min-height: 340px;
  transform-style: preserve-3d;
  transition: transform 0.5s var(--ease);
  cursor: pointer;
  user-select: none;
}

.flip.on {
  transform: rotateY(180deg);
}

.face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: 0 6px 0 var(--lip);
  padding: 30px 24px 42px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow-y: auto;
}

.face.back {
  transform: rotateY(180deg);
  background: var(--panel);
}

.face .k {
  font-size: 1.4rem;
  font-weight: 800;
  line-height: 1.28;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

.face .v {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-2);
  margin-top: 12px;
  line-height: 1.55;
}

.face .tapme {
  position: absolute;
  bottom: 16px;
  left: 0;
  right: 0;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.rate {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.rate button {
  padding: 17px;
  border-radius: var(--r);
  border: 2px solid transparent;
  transition:
    transform 0.08s var(--ease),
    box-shadow 0.08s var(--ease);
}

.rate .again {
  background: var(--amber);
  color: #4a3000;
  box-shadow: var(--drop) var(--amber-lip);
}

.rate .again:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--amber-lip);
}

.rate .got {
  background: var(--brand);
  color: var(--brand-contrast);
  box-shadow: var(--drop) var(--brand-lip);
}

.rate .got:active {
  transform: translateY(4px);
  box-shadow: 0 0 0 var(--brand-lip);
}

/* ---------- bottom navigation ---------- */
.desktop-brand {
  display: none;
}

#tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: var(--paper);
  border-top: 2px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}

#tabs button {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 10px 4px 12px;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
  transition: color 0.15s var(--ease);
}

#tabs button svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

#tabs button.on {
  color: var(--brand-ink);
}

/* every scrollable surface clears the nav bar */
#home,
#practice,
#learn,
#cards {
  padding-bottom: calc(96px + env(safe-area-inset-bottom));
}

.card {
  padding-bottom: calc(150px + env(safe-area-inset-bottom));
}

.fab {
  bottom: calc(90px + env(safe-area-inset-bottom));
}

/* ---------- locked video card ---------- */

.vstate .sub {
  max-width: 34rem;
  margin-inline: auto;
}

.vstate .actions {
  margin-top: 24px;
}

.state-link {
  text-decoration: none;
}

.sampler-note {
  max-width: 34rem;
  margin-inline: auto;
}

/* The card sits on the black video ground, so its text is light in both
   themes rather than following the paper palette. */
.locked {
  padding: 0 24px;
}

.locked .lockicon {
  font-size: 2.4rem;
  margin-bottom: 14px;
}

.locked .q {
  margin-bottom: 8px;
  color: #fff;
}

.locked .sub {
  color: rgb(255 255 255 / 72%);
}

/* ---------- video reel ---------- */
.vcard {
  padding: 0 !important;
  background: #000;
}

.vcard video {
  position: absolute;
  inset: 0;
  width: 100%;
  /* The fixed navigation owns the bottom of the viewport. Keep the picture
     above it so the lessons' burned-in captions are never hidden underneath
     the nav on short screens. */
  height: calc(100% - 64px - env(safe-area-inset-bottom));
  object-fit: contain;
  object-position: center;
  background: #000;
}

.vplay {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 4;
  min-width: 148px;
  min-height: 48px;
  padding: 12px 20px;
  border: 2px solid rgb(255 255 255 / 78%);
  border-radius: 999px;
  background: rgb(7 24 39 / 88%);
  color: #fff;
  box-shadow: 0 4px 0 rgb(0 0 0 / 55%);
  transform: translate(-50%, -50%);
}

.vplay:active {
  transform: translate(-50%, calc(-50% + 4px));
  box-shadow: none;
}

.mediaerror {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-content: center;
  justify-items: center;
  padding: 24px;
  background: rgb(7 24 39 / 90%);
  color: #fff;
  text-align: center;
}

.mediaerror p {
  margin: 0 0 14px;
  font-size: 1.35rem;
  font-weight: 800;
}

.mediaerror .ghost {
  min-width: 148px;
  margin: 0;
  color: var(--ink);
}

.media-failed video {
  opacity: 0.2;
}

/* Bottom scrim, the way every short-video app does it: the caption needs a
   floor to sit on, and the burned-in subtitles at 79-81% of frame height get
   the same benefit. */
.vscrim {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 44%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgb(0 0 0 / 62%) 0%,
    rgb(0 0 0 / 34%) 40%,
    rgb(0 0 0 / 0%) 100%
  );
}

/* Caption sits bottom-left above the nav. It clears the burned-in subtitle
   band (measured at 79-81% of the video) rather than landing on top of it. */
.vcap {
  position: absolute;
  left: 16px;
  right: 104px;
  bottom: calc(78px + env(safe-area-inset-bottom));
  z-index: 2;
  color: #fff;
  text-shadow: 0 1px 3px rgb(0 0 0 / 55%);
}

.vcap .t {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.vcap .f {
  margin-top: 2px;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
  opacity: 0.92;
}





/* Identity over the feed. Sits opposite the mute button, on the scrim, and
   disappears the moment any panel takes the screen — it is the front door's
   job, not a permanent chrome bar. */
#feedMark {
  position: fixed;
  left: 16px;
  top: calc(18px + env(safe-area-inset-top));
  z-index: 3;
  pointer-events: none;
  color: #fff;
  text-shadow: 0 1px 4px rgb(0 0 0 / 60%);
}

#feedMark b {
  display: block;
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

#feedMark span {
  display: block;
  margin-top: 1px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  opacity: 0.9;
}

/* Shown only while the video feed is the thing on screen. The quiz and the
   mock render into the same reel, so this has to be opt-in rather than a list
   of things to hide behind. */
#feedMark {
  display: none;
}

body.onvideo #feedMark {
  display: block;
}

.vmute {
  position: absolute;
  right: 18px;
  top: calc(14px + env(safe-area-inset-top));
  z-index: 2;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 16%);
  border-color: rgb(255 255 255 / 26%);
  color: #fff;
  box-shadow: none;
  backdrop-filter: blur(10px);
  transition:
    background 0.15s var(--ease),
    transform 0.1s var(--ease);
}

.vmute svg {
  width: 21px;
  height: 21px;
  fill: currentColor;
}

.vmute:active {
  transform: scale(0.92);
}

.vpause {
  position: absolute;
  right: 18px;
  top: calc(70px + env(safe-area-inset-top));
  z-index: 2;
  min-width: 76px;
  min-height: 44px;
  justify-content: center;
  padding: 9px 13px;
  border-color: rgb(255 255 255 / 26%);
  background: rgb(7 24 39 / 82%);
  color: #fff;
  box-shadow: none;
  backdrop-filter: blur(10px);
}

.vpause:active {
  transform: scale(0.96);
}

/* Muted is the state worth noticing: the lesson is narrated, so a silent feed
   is a thing to fix, not a neutral default. */
.vmute.off {
  background: rgb(255 255 255 / 92%);
  border-color: rgb(255 255 255 / 92%);
  color: var(--ink);
}

@media (min-width: 720px) {
  body {
    background: #071827;
  }

  #reel {
    left: 50%;
    right: auto;
    width: 540px;
    transform: translateX(-50%);
    background: var(--paper);
    border-inline: 1px solid rgb(255 255 255 / 12%);
  }

  #tabs {
    left: 50%;
    right: auto;
    width: 540px;
    transform: translateX(-50%);
  }

  #feedMark {
    left: calc(50% - 254px);
  }

  /* Wide viewports crop portrait lessons vertically, which moves their
     burned-in subtitle band towards the bottom navigation. Put the app's own
     title/fact block below the wordmark instead of competing with captions. */
  .vcap {
    top: calc(84px + env(safe-area-inset-top));
    bottom: auto;
  }

  .vpause {
    top: calc(138px + env(safe-area-inset-top));
  }
}

/* ---------- desktop workspace ----------
   The lesson itself stays portrait and focused. Everything around it becomes
   a desktop product: a permanent passport-blue rail and a wider study desk. */
@media (min-width: 960px) {
  :root {
    --desktop-rail: 232px;
    --desktop-centre-shift: 116px;
  }

  body {
    background: var(--panel-2);
  }

  #tabs {
    top: 0;
    bottom: 0;
    left: 0;
    right: auto;
    width: var(--desktop-rail);
    padding: 24px 18px;
    border-top: 0;
    border-right: 2px solid rgb(255 255 255 / 12%);
    background: #071827;
    box-shadow: 8px 0 0 rgb(0 0 0 / 12%);
    transform: none;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }

  .desktop-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 22px;
    padding: 4px 6px 22px;
    border-bottom: 1px solid rgb(255 255 255 / 16%);
    color: #fff;
    text-decoration: none;
  }

  .desktop-brand-mark {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: 14px;
    background: var(--brand);
    color: var(--brand-contrast);
    box-shadow: 0 4px 0 var(--brand-lip);
    font-weight: 800;
  }

  .desktop-brand b,
  .desktop-brand small {
    display: block;
  }

  .desktop-brand b {
    font-size: 1rem;
    line-height: 1.15;
  }

  .desktop-brand small {
    margin-top: 3px;
    color: rgb(255 255 255 / 58%);
    font-size: 0.68rem;
    font-weight: 700;
  }

  #tabs button {
    min-height: 52px;
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    padding: 13px 15px;
    border-radius: 15px;
    color: rgb(255 255 255 / 62%);
    font-size: 0.84rem;
    letter-spacing: 0.03em;
  }

  #tabs button svg {
    width: 23px;
    height: 23px;
  }

  #tabs button.on {
    background: var(--brand);
    color: var(--brand-contrast);
    box-shadow: 0 4px 0 var(--brand-lip);
  }

  #reel {
    left: calc(50% + var(--desktop-centre-shift));
  }

  /* YouTube Shorts-style desktop stage: the whole Watch sequence—including
     its check questions—lives in one centred 9:16 player instead of a tall
     black column. The page, not the video, owns the surrounding whitespace. */
  body.watch-mode #reel {
    top: 50%;
    bottom: auto;
    width: min(640px, 54dvh, calc(100vw - var(--desktop-rail) - 160px));
    height: auto;
    aspect-ratio: 9 / 16;
    border: 1px solid rgb(7 24 39 / 24%);
    border-radius: 22px;
    box-shadow: 0 22px 70px rgb(7 24 39 / 22%);
    transform: translate(-50%, -50%);
  }

  body.watch-mode #reel .card {
    height: 100%;
    min-height: 100%;
  }

  body.watch-mode #feedMark {
    display: none;
  }

  body.watch-mode .vcap {
    top: 20px;
  }

  /* Desktop navigation lives beside the reel, not below it. Use the full
     height and preserve every pixel of the authored 9:16 lesson frame. */
  .vcard video {
    height: 100%;
  }

  #home,
  #practice,
  #learn,
  #cards {
    left: var(--desktop-rail);
    padding: 48px clamp(36px, 5vw, 76px) 56px;
    background: var(--panel);
  }

  #home .hinner,
  #practice .pinner,
  #learn .linner,
  #cards .cinner {
    max-width: 1040px;
  }

  #home h1 {
    max-width: 18ch;
    font-size: clamp(2.35rem, 4vw, 3.2rem);
  }

  #practice h1,
  #learn h1,
  #cards h1 {
    font-size: 2.35rem;
  }

  .goal {
    padding: 16px 20px;
  }

  .tiles {
    gap: 16px;
  }

  .tile {
    padding: 20px 14px;
  }

  .modes {
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
  }

  .practice-modes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
  }

  .practice-mode {
    min-height: 178px;
    grid-template-columns: 64px minmax(0, 1fr) auto;
    align-content: center;
    padding: 22px;
  }

  .practice-note {
    max-width: 70ch;
  }

  .catgrid {
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
  }

  .bar {
    left: calc(50% + var(--desktop-centre-shift));
    right: auto;
    width: 572px;
    transform: translateX(-50%);
  }

  .feedbar {
    left: calc(50% + var(--desktop-centre-shift));
    right: auto;
    width: 508px;
    transform: translateX(-50%);
  }

  .chip.timer {
    left: calc(50% + var(--desktop-centre-shift));
  }

  .fab {
    right: max(16px, calc(50vw - 370px));
  }

  #feedMark {
    left: calc(50% - 138px);
  }

  .closex {
    right: 34px;
  }
}

@media (hover: hover) {
  .big:not(.disabled):hover,
  .fab:hover {
    filter: brightness(1.05);
  }

  .ghost:hover,
  .chip:hover,
  .why:hover,
  .deck:hover,
  .mode:hover,
  .practice-mode:hover,
  .cat:hover,
  .pill:not(.on):hover {
    background: var(--panel);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .cf {
    display: none !important;
  }

  .hint.show,
  .pop,
  .opt.right,
  .opt.wrong,
  .scorenum,
  .stamp,
  .panel {
    animation: none !important;
  }

  .sheet,
  #soundToast {
    transition: none !important;
  }
}

body.reduced-motion .cf {
  display: none !important;
}

body.reduced-motion .hint.show,
body.reduced-motion .pop,
body.reduced-motion .opt.right,
body.reduced-motion .opt.wrong,
body.reduced-motion .scorenum,
body.reduced-motion .stamp,
body.reduced-motion .panel {
  animation: none !important;
}

body.reduced-motion .sheet,
body.reduced-motion #soundToast {
  transition: none !important;
}

/* Routes out of the feed to the pages that answer "what is this, who made it,
   what does it cost". The feed is the front door now, so these need a home. */
.setlinks {
  margin: 16px 0 4px;
  text-align: center;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink-3);
}

.setlinks a {
  color: var(--brand-ink);
  text-underline-offset: 3px;
}

/* Same links, but on the Progress screen rather than three taps deep in
   Settings. A sceptical buyer looks for a footer before they look for a
   feature, and finding none reads as "nobody is behind this". */
.setlinks.foot {
  margin: 20px 0 8px;
  padding-top: 16px;
  border-top: 1px solid var(--line, rgb(0 0 0 / 8%));
}

/* Tap-to-toggle sound confirmation. Sits dead centre over the video for a
   beat, the way every short-video app acknowledges the gesture. Visibility is
   driven by a JS timeout rather than an animation, so it still shows for its
   full duration when prefers-reduced-motion flattens the transition. */
#soundToast {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 40;
  display: grid;
  place-items: center;
  gap: 10px;
  padding: 22px 26px;
  border-radius: 24px;
  background: rgb(0 0 0 / 62%);
  color: #fff;
  backdrop-filter: blur(12px);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.86);
  transition:
    opacity 0.18s var(--ease),
    transform 0.18s var(--ease);
}

#soundToast.show {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

#soundToast svg {
  width: 40px;
  height: 40px;
  fill: currentColor;
}

#soundToast span {
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
