/* ==============================================================
   StudyPass — the study area
   Loaded only by the student shell. Everything here assumes the
   tokens and the shared shell are already in.
   No rounded corners anywhere: --radius is 0 and stays 0.
   ============================================================== */

/* --------------------------------------------------------------
   Top bar
   Same skeleton as the admin bar, but bilingual and with the
   band badge sitting where an admin has its role chip.
   -------------------------------------------------------------- */
.study-bar {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--bg-page);
  border-bottom: var(--border-hair) solid var(--edge-hair);
}
.study-bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: var(--nav-height);
  padding: 0 var(--gutter);
}
.study-bar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.study-bar__band { white-space: nowrap; }

/* Below 1000px the sidebar collapses into the drawer, so the two
   text buttons in the bar would crowd the toggles. */
@media (max-width: 640px) {
  .study-bar__actions .btn { display: none; }
  .study-bar__band { display: none; }
}

/* --------------------------------------------------------------
   The band bar
   Persistent across every study screen while there is something
   to say. Sticks under the header so it survives a long scroll —
   a student two thousand pixels down a vocabulary list is exactly
   who needs to be reminded the trial has four hours left.
   -------------------------------------------------------------- */
.band-bar {
  position: sticky;
  top: var(--nav-height);
  z-index: calc(var(--z-header) - 1);
  border-bottom: var(--border-hair) solid var(--edge-hair);
  background: var(--bg-subtle);
}
.band-bar[data-tone='trial']  { background: var(--bg-subtle); border-bottom-color: var(--edge-brand); }
.band-bar[data-tone='urgent'] { background: var(--bg-brand-subtle, var(--bg-subtle)); }
.band-bar[data-tone='urgent'] .band-bar__text { color: var(--fg-strong); }

.band-bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--gutter);
  min-width: 0;
}
.band-bar__text {
  margin: 0;
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--fg-muted);
}
.band-bar__cta { flex: 0 0 auto; white-space: nowrap; }

/* Mongolian runs 20–40% longer than English, so the bar has to be
   allowed to wrap before the button is allowed to shrink. */
@media (max-width: 640px) {
  .band-bar__inner { flex-direction: column; align-items: stretch; }
  .band-bar__cta { white-space: normal; text-align: center; }
}

/* --------------------------------------------------------------
   Locked areas
   An unpaid student sees the whole shape of the product with the
   substance dimmed — not an empty page. The dimming is honest,
   not a tease: the rows underneath genuinely are not there,
   because the study_* views returned nothing.
   -------------------------------------------------------------- */
.is-locked {
  position: relative;
  opacity: 0.45;
  filter: grayscale(1);
  user-select: none;
  pointer-events: none;
}
.is-locked::after {
  content: '';
  position: absolute;
  inset: 0;
  background: transparent;
}

.locked-note {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border: var(--border-hair) solid var(--edge-hair);
  border-left: var(--border-medium) solid var(--edge-brand);
  background: var(--bg-subtle);
  font-size: var(--text-sm);
  color: var(--fg-muted);
}
.locked-note__key {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--fg-subtle);
  white-space: nowrap;
}

/* --------------------------------------------------------------
   Study page furniture
   -------------------------------------------------------------- */
.study-main { padding-top: var(--space-6); }

.study-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}
.study-head__title { margin: 0; }

.stat-row {
  display: grid;
  grid-template-columns: 1fr;
  border: var(--border-hair) solid var(--edge-hair);
}
@media (min-width: 560px)  { .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .stat-row { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.stat {
  padding: var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
  min-width: 0;
}
.stat:first-child { border-top: 0; }
@media (min-width: 560px) {
  .stat { border-top: 0; border-left: var(--border-hair) solid var(--edge-hair); }
  .stat:nth-child(2n + 1) { border-left: 0; }
}
@media (min-width: 1000px) {
  .stat:nth-child(2n + 1) { border-left: var(--border-hair) solid var(--edge-hair); }
  .stat:first-child { border-left: 0; }
}
.stat__key {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.stat__value {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  font-weight: var(--weight-semibold);
  line-height: 1;
  margin-top: var(--space-3);
}
.stat__note { font-size: var(--text-xs); color: var(--fg-muted); margin-top: var(--space-3); }

/* --------------------------------------------------------------
   No flash of unlocked content
   guard.js hides the body until the profile lands, but it and
   student.js resolve independently. Holding the main region back
   until data-access exists costs a frame and removes the chance
   of a locked screen rendering unlocked first.
   -------------------------------------------------------------- */
html:not([data-access]) .study-main,
html:not([data-access]) .band-bar { visibility: hidden; }

/* --------------------------------------------------------------
   A section that does not exist yet
   Rendered by build.py in place of a link, so a half-built demo
   never offers a button that goes nowhere.
   -------------------------------------------------------------- */
.btn.is-disabled {
  opacity: 0.5;
  pointer-events: none;
  cursor: default;
}
.btn.is-disabled .side-nav__soon { margin-left: var(--space-2); }

/* --------------------------------------------------------------
   A block inside the study frame
   The frame already supplies the gutter, so study sections do not
   take the marketing .section padding — they only need separating.
   -------------------------------------------------------------- */
.section--flush { padding: 0; }

/* --------------------------------------------------------------
   Today's tasks
   A queue, not a syllabus: one line per thing to do, the done ones
   struck through rather than removed, so progress stays visible.
   -------------------------------------------------------------- */
.task-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: var(--border-hair) solid var(--edge-hair);
}
.task {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
  min-width: 0;
}
.task:first-child { border-top: 0; }

.task__mark {
  flex: 0 0 auto;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.1rem;
  border: var(--border-hair) solid var(--edge-hair);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  line-height: 1;
  color: var(--fg-brand);
}
.task__body { min-width: 0; }
.task__label { margin: 0; font-weight: var(--weight-medium); }
.task__meta {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  color: var(--fg-subtle);
}

.task.is-done .task__label { color: var(--fg-subtle); text-decoration: line-through; }
.task.is-done .task__mark { border-color: var(--edge-brand); }

/* The per-task action. Pushed to the far edge so the label and the
   button do not fight for the middle of the row. */
.task__go { flex: 0 0 auto; margin-left: auto; align-self: center; }

/* The tick is a real button on the plan screen (it writes), and a plain
   span on the dashboard (it only reports). Same box either way. */
button.task__mark { cursor: pointer; background: none; }
button.task__mark:hover { border-color: var(--edge-brand); }
button.task__mark:disabled { opacity: 0.5; cursor: default; }

@media (max-width: 560px) {
  .task { flex-wrap: wrap; }
  .task__go { margin-left: 0; width: 100%; text-align: center; }
}

/* --------------------------------------------------------------
   The practice player
   One question, one screen. Nothing competes with the prompt.
   -------------------------------------------------------------- */
.quiz {
  border: var(--border-hair) solid var(--edge-hair);
  padding: var(--space-6);
  max-width: 68ch;
}
.quiz__prompt { margin-top: var(--space-4); }
.quiz__form { margin-top: var(--space-6); }

.choices { display: block; border: var(--border-hair) solid var(--edge-hair); }
.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
  cursor: pointer;
  min-width: 0;
}
.choice:first-child { border-top: 0; }
.choice:hover { background: var(--bg-subtle); }
.choice__input { flex: 0 0 auto; margin-top: 0.25rem; accent-color: var(--fg-brand); }
.choice__text { min-width: 0; }
.choice:has(.choice__input:checked) { background: var(--bg-subtle); }
.choice:has(.choice__input:disabled) { cursor: default; }

/* --------------------------------------------------------------
   The verdict
   A hairline on the left carries right-or-wrong. No green, no red
   fill: the explanation is the point, not the colour.
   -------------------------------------------------------------- */
.verdict {
  margin-top: var(--space-6);
  padding: var(--space-5);
  border: var(--border-hair) solid var(--edge-hair);
  border-left: var(--border-heavy) solid var(--edge-hair);
}
.verdict.is-right { border-left-color: var(--edge-brand); }
.verdict.is-wrong { border-left-color: var(--fg-strong); }
.verdict__head {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.verdict__key { margin-top: var(--space-3); font-weight: var(--weight-semibold); }
.verdict__body { margin-top: var(--space-3); color: var(--fg-muted); }

/* --------------------------------------------------------------
   The passage
   Collapsed by default: on a phone the question is what you came
   for, and a thousand words above it is a scroll, not context.
   -------------------------------------------------------------- */
.passage {
  border: var(--border-hair) solid var(--edge-hair);
  margin-top: var(--space-5);
}
.passage__summary {
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}
.passage__body {
  padding: 0 var(--space-5) var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
  padding-top: var(--space-5);
}
.passage__text { white-space: pre-wrap; margin-top: var(--space-4); color: var(--fg-muted); }
.passage audio { width: 100%; }

@media (max-width: 560px) {
  .quiz { padding: var(--space-5) var(--space-4); }
}

/* --------------------------------------------------------------
   Vocabulary, and the wall
   A locked row is a bar, not blurred text: the server sent no
   word to blur. Faking a smudge over invented letters would be a
   worse lie than an honest empty bar.
   -------------------------------------------------------------- */
.vocab-bar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  margin-top: var(--space-6);
  padding-bottom: var(--space-5);
  border-bottom: var(--border-hair) solid var(--edge-hair);
}
.field--inline { flex: 1 1 18rem; min-width: 0; }

.vocab-list { border: var(--border-hair) solid var(--edge-hair); }

.vocab-group {
  padding: var(--space-4) var(--space-5);
  background: var(--bg-subtle);
  border-top: var(--border-hair) solid var(--edge-hair);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.vocab-list > .vocab-group:first-child { border-top: 0; }

.vocab-unlock {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-4) var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
  border-left: var(--border-medium) solid var(--edge-brand);
}
.vocab-unlock__text { margin: 0; font-size: var(--text-sm); color: var(--fg-muted); }

.vocab {
  padding: var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
  min-width: 0;
}
.vocab__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.vocab__word {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  margin: 0;
}
.vocab__pos { font-size: var(--text-xs); color: var(--fg-subtle); font-style: italic; }
.vocab__gloss { margin-top: var(--space-3); font-weight: var(--weight-medium); }
.vocab__example { margin-top: var(--space-3); color: var(--fg-muted); }
.vocab__collocations {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--fg-subtle);
}

.vocab--locked { background: var(--bg-subtle); }
.vocab__bar {
  display: inline-block;
  height: 0.85rem;
  width: 8.5rem;
  max-width: 60%;
  background: var(--edge-hair);
}
.vocab__bar--short { margin-top: var(--space-4); width: 14rem; height: 0.6rem; }

/* Available to screen readers, absent from the page. Locked rows carry a
   spoken description because a bar reads as nothing at all. */
.u-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 560px) {
  .vocab-unlock { flex-direction: column; align-items: stretch; }
  .vocab-unlock .btn { text-align: center; }
}

/* --------------------------------------------------------------
   Buying a band
   The ladder again, but priced for this account: an upgrade shows
   the difference, not the list price.
   -------------------------------------------------------------- */
.ladder-buy { border: var(--border-hair) solid var(--edge-hair); }

.buy-rung {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: var(--space-3) var(--space-5);
  align-items: baseline;
  padding: var(--space-5);
  border-top: var(--border-hair) solid var(--edge-hair);
}
.buy-rung:first-child { border-top: 0; }
.buy-rung.is-held { background: var(--bg-subtle); }
.buy-rung.is-wanted { border-left: var(--border-heavy) solid var(--edge-brand); }

@media (min-width: 760px) {
  .buy-rung {
    grid-template-columns: 3.5rem minmax(0, 1fr) 12rem auto;
    align-items: center;
  }
}

.buy-rung__band {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  line-height: 1;
}
.buy-rung__body { min-width: 0; }
.buy-rung__promise { margin: 0; font-weight: var(--weight-medium); }
.buy-rung__buyer { margin: var(--space-2) 0 0; font-size: var(--text-xs); color: var(--fg-subtle); }
.buy-rung__price { min-width: 0; }
.buy-rung__amount {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
}
.buy-rung__action { min-width: 0; }
.buy-rung__action .btn { white-space: normal; }

/* --------------------------------------------------------------
   An order waiting on a transfer
   The reference is the only thing that matches money to an
   account, so it is set in the monospaced face and given room.
   -------------------------------------------------------------- */
.order {
  border: var(--border-hair) solid var(--edge-hair);
  border-left: var(--border-heavy) solid var(--edge-brand);
  padding: var(--space-5);
  max-width: 40rem;
}
.order + .order { margin-top: var(--space-4); }
.order__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.order__what { margin: 0; font-weight: var(--weight-semibold); }
.order__ref {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--text-lg);
  letter-spacing: 0.04em;
}
.order__how { margin-top: var(--space-4); font-size: var(--text-sm); color: var(--fg-muted); }
