:root {
  --portal-bg: #f5f7f8;
  --portal-surface: #ffffff;
  --portal-text: #17211d;
  --portal-muted: #69756f;
  --portal-line: #dfe5e2;
  --portal-green: #167454;
  --portal-green-dark: #10563f;
  --portal-green-soft: #e7f3ee;
  --portal-blue: #286a8a;
  --portal-blue-soft: #e8f2f7;

  /* gender — content only, never UI chrome (see .headword-serif below) */
  --gender-der: #2B5CA8;
  --gender-die: #B3335A;
  --gender-das: #8A5A18;
  --gender-der-soft: #E8EEF7;
  --gender-die-soft: #F9E9ED;
  --gender-das-soft: #F6EEDF;

  /* FSRS rating buttons (W5) — UI chrome, deliberately not the gender palette
     above. All 4 pass >=4.5:1 contrast with white button text (checked). */
  --rating-again: #a13b48;
  --rating-hard: #ad5a00;
  --rating-easy: var(--portal-blue);
}

/* Newsreader, self-hosted (OFL 1.1, app/static/fonts/newsreader/OFL.txt).
   Was loaded from fonts.googleapis.com; moved local 2026-08-21 to avoid
   shipping visitor IPs to Google without consent (LG München I, 20.01.2022,
   Az. 3 O 17493/20) and because OFL redistribution into a future mobile
   build requires the licence to travel with the font anyway. One variable
   file covers weight 400 and 600; italic is 400 only (all this app uses). */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/static/fonts/newsreader/newsreader-variable-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/static/fonts/newsreader/newsreader-variable-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/newsreader/newsreader-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/newsreader/newsreader-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

.headword-serif {
  font-family: "Newsreader", Georgia, "Times New Roman", serif;
}

.progress-primary strong,
.progress-metrics strong,
.summary-results strong,
.placement-result strong,
.rail-heading > strong,
.level-meter-list strong,
.study-progress strong,
.tabular-nums {
  font-variant-numeric: tabular-nums;
}

[hidden],
.hidden {
  display: none !important;
}

.portal-shell {
  background: var(--portal-bg);
  color: var(--portal-text);
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  min-height: 100vh;
}

.portal-sidebar {
  background: var(--portal-surface);
  border-right: 1px solid var(--portal-line);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding: 24px 16px 18px;
  position: sticky;
  top: 0;
}

.portal-brand {
  align-items: center;
  color: var(--portal-text);
  display: flex;
  gap: 10px;
  text-decoration: none;
}

.portal-brand > span {
  align-items: center;
  background: var(--portal-green);
  border-radius: 6px;
  color: #fff;
  display: flex;
  font-size: 0.72rem;
  font-weight: 850;
  height: 34px;
  justify-content: center;
  width: 38px;
}

.portal-brand strong {
  font-size: 1rem;
}

.portal-nav {
  align-items: stretch;
  display: grid;
  gap: 5px;
  margin-top: 42px;
}

.portal-nav a {
  align-items: center;
  border-radius: 6px;
  color: var(--portal-muted);
  display: flex;
  font-size: 0.92rem;
  font-weight: 650;
  gap: 11px;
  padding: 11px 12px;
  text-decoration: none;
}

.portal-nav a svg { flex-shrink: 0; }

.portal-nav a:hover {
  background: #f3f6f4;
  color: var(--portal-text);
}

.portal-nav a.active {
  background: var(--portal-green-soft);
  color: var(--portal-green-dark);
}

.profile-avatar {
  align-items: center;
  background: var(--portal-blue-soft);
  border-radius: 50%;
  color: var(--portal-blue);
  display: flex;
  font-size: 0.82rem;
  font-weight: 850;
  height: 36px;
  justify-content: center;
  width: 36px;
}

.nav-label { color: #8a9590; font-size: .64rem; font-weight: 800; margin: 20px 12px 2px; text-transform: uppercase; }
.profile-note { color: var(--portal-muted); font-size: .8rem; line-height: 1.5; margin: 12px 0 0; }

.portal-workspace {
  min-width: 0;
}

.portal-content {
  margin: 0 auto;
  max-width: 1180px;
  padding: 38px 36px 64px;
}

.portal-header {
  align-items: center;
  background: var(--portal-surface);
  border-bottom: 1px solid var(--portal-line);
  display: flex;
  justify-content: flex-end;
  min-height: 68px;
  padding: 10px 36px;
  position: relative;
  z-index: 20;
}
.portal-header-brand { display: none; }
.account-menu { position: relative; }
.account-menu summary { align-items: center; cursor: pointer; display: flex; gap: 10px; list-style: none; }
.account-menu summary::-webkit-details-marker { display: none; }
.account-menu-name { display: grid; min-width: 110px; }
.account-menu-name strong { font-size: .82rem; overflow: hidden; text-overflow: ellipsis; }
.account-menu-name small { color: var(--portal-muted); font-size: .68rem; }
.account-menu > div { background: #fff; border: 1px solid var(--portal-line); border-radius: 7px; box-shadow: 0 12px 30px rgba(23,33,29,.12); display: none; min-width: 210px; padding: 7px; position: absolute; right: 0; top: calc(100% + 10px); }
.account-menu[open] > div { display: grid; }
.account-menu > div a, .account-menu > div button { background: transparent; border: 0; border-radius: 5px; color: var(--portal-text); display: block; font: inherit; font-size: .82rem; padding: 10px; text-align: left; text-decoration: none; width: 100%; }
.account-menu > div a:hover, .account-menu > div button:hover { background: var(--portal-green-soft); }

.mobile-nav {
  display: none;
}

.portal-section-heading span {
  color: var(--portal-green);
  font-size: 0.7rem;
  font-style: normal;
  font-weight: 800;
  letter-spacing: 0;
}

.study-progress { margin: 0 auto 16px; width: min(900px, 100%); }
.study-progress > div:first-child { align-items: baseline; display: flex; flex-wrap: wrap; gap: 2px 10px; justify-content: space-between; }
.study-progress span { color: var(--portal-green); font-size: .7rem; font-weight: 800; }
.study-progress strong { color: var(--portal-text); font-size: 1rem; font-weight: 850; }
.study-progress .goal-track { margin-top: 9px; }
.session-summary { margin: 70px auto; max-width: 700px; text-align: center; }
.summary-kicker { color: var(--portal-green); font-size: .72rem; font-weight: 850; }
.session-summary h1 { font-size: clamp(2.2rem,5vw,4rem); margin: 10px 0; }
.session-summary > p { color: var(--portal-muted); }
.summary-results { border-bottom: 1px solid var(--portal-line); border-top: 1px solid var(--portal-line); display: grid; grid-template-columns: repeat(3,1fr); margin: 38px 0; }
.summary-results div { display: grid; gap: 4px; padding: 25px 12px; }
.summary-results div + div { border-left: 1px solid var(--portal-line); }
.summary-results strong { font-size: 1.7rem; }
.summary-results span { color: var(--portal-muted); font-size: .74rem; }
.summary-actions { align-items: center; display: flex; gap: 12px; justify-content: center; }
.summary-actions button, .summary-actions a { background: var(--portal-green); border: 0; border-radius: 5px; color: #fff; display: inline-block; font-size: .84rem; font-weight: 800; padding: 12px 16px; text-decoration: none; }
.summary-actions a { background: #fff; border: 1px solid var(--portal-line); color: var(--portal-text); }
.placement-result { border: 1px solid var(--portal-line); margin: -14px 0 30px; padding: 24px; }
.placement-result > span { color: var(--portal-muted); display: block; font-size: .68rem; font-weight: 850; }
.placement-result > strong { color: var(--portal-green); display: block; font-size: 2.6rem; margin: 6px 0; }
.placement-result p { color: var(--portal-muted); margin: 0 auto 18px; max-width: 480px; }
.placement-result form { margin: 0; }
.placement-result button { background: var(--portal-green); border: 0; border-radius: 5px; color: #fff; font-weight: 800; min-height: 44px; padding: 0 18px; }
/* width (not max-width) so flex layout below sizes the card by this value
   instead of shrink-wrapping its content -- auto margins then centre the
   remaining free space exactly as they did in plain block layout. */
.study-card { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin: 0 auto; min-height: clamp(520px, 62vh, 680px); overflow: hidden; perspective: 1400px; position: relative; width: min(900px, 100%); }

/* Feedback flag (docs/units-spec.md section 3): a small corner button, always
   present but position:absolute so it sits outside the front/back grid flow
   and never competes with the 4 rating buttons for space, even at 320px.
   Top-right (not the mockup's bottom-right) so it also clears the sticky
   .review-actions bar on mobile (max-width: 720px below). */
.card-flag {
  align-items: center;
  background: #fff;
  border: 1px solid var(--portal-line);
  border-radius: 50%;
  color: var(--portal-muted);
  cursor: pointer;
  display: flex;
  font-size: 1rem;
  height: 34px;
  justify-content: center;
  line-height: 1;
  position: absolute;
  right: 14px;
  top: 14px;
  width: 34px;
  z-index: 2;
}
.card-flag--static { position: static; flex-shrink: 0; }
.card-flag:hover, .card-flag:focus-visible { border-color: var(--portal-green); color: var(--portal-green-dark); }
.card-flag:focus-visible { outline: 2px solid var(--portal-green); outline-offset: 2px; }

.card-feedback-dialog { border: 1px solid var(--portal-line); border-radius: 8px; box-shadow: 0 12px 32px rgba(0,0,0,.18); max-width: 420px; padding: 22px; width: calc(100vw - 40px); }
.card-feedback-dialog::backdrop { background: rgba(15,20,18,.45); }
.card-feedback-dialog h2 { font-size: 1.05rem; margin: 0 0 12px; }
.card-feedback-dialog textarea { border: 1px solid var(--portal-line); border-radius: 5px; box-sizing: border-box; font-family: inherit; min-height: 96px; padding: 10px; resize: vertical; width: 100%; }
.card-feedback-dialog textarea:focus { border-color: var(--portal-green); box-shadow: 0 0 0 3px var(--portal-green-soft); outline: 0; }
.card-feedback-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }
.card-feedback-actions button { border-radius: 5px; font-weight: 750; min-height: 40px; padding: 0 16px; }
.card-feedback-actions button[type="submit"] { background: var(--portal-green); border: 0; color: #fff; }
.card-feedback-actions button[type="submit"]:focus-visible, .card-flag:focus-visible, [data-flag-cancel]:focus-visible { outline: 2px solid var(--portal-green); outline-offset: 2px; }
[data-flag-cancel] { background: #fff; border: 1px solid var(--portal-line); color: var(--portal-text); }
.study-card-front, .study-card-back { min-height: clamp(520px, 62vh, 680px); padding: clamp(30px,6vw,64px); }

/* Deckful-style flip reveal (B4): the back rotates in (rotateY + opacity)
   over ~0.4s as it becomes visible. Instant (no transition) when the user
   has asked for reduced motion -- the hidden/visible swap itself is always
   synchronous, only this entrance animation is skipped. */
@media (prefers-reduced-motion: no-preference) {
  .study-card-back { transition: transform .4s cubic-bezier(.22,.61,.36,1), opacity .4s ease; }
  /* -80deg, not -90: at exactly 90deg the perspective-projected bounding box
     is zero-width for one frame, which reads as "not visible" to assistive
     tooling (and to Playwright's is_visible()) even though it's mid-animation. */
  .study-card-back.flip-in { opacity: 0; transform: rotateY(-80deg); }
}

/* Desktop composition (W4): centre the card in the space below the header
   instead of pinning it to the top with a dead area underneath. Mobile keeps
   its own fill-the-viewport rule below (max-width: 720px), unaffected. */
@media (min-width: 721px) {
  .portal-content:has(.study-card) {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: calc(100vh - 68px);
  }
}
.study-card-front { align-content: center; display: grid; justify-items: center; text-align: center; }
.card-meta { color: var(--portal-green); font-size: .7rem; font-weight: 850; }
.study-card-front h1, .study-card-back h1 { font-size: clamp(2.2rem,6vw,4.2rem); margin: 18px 0 12px; overflow-wrap: anywhere; }
.study-card-front > p, .study-translation { color: var(--portal-muted); font-size: 1rem; }

/* Verb conjugation cloze front: lemma / tense / "wir ___" on three lines
   instead of one long "haben — Präsens, wir: ___" headline. */
.study-card-front > .cloze-tense {
  color: var(--portal-muted);
  font-size: 0.78rem;
  font-weight: 850;
  letter-spacing: 0.1em;
  margin: 0 0 20px;
  text-transform: uppercase;
}

.study-card-front > .cloze-line {
  align-items: center;
  color: var(--portal-text);
  display: flex;
  flex-wrap: wrap;
  font-family: "Newsreader", Georgia, "Times New Roman", serif;
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  gap: 16px;
  justify-content: center;
  margin: 0 0 26px;
}

.cloze-blank {
  background: #eef1f0;
  border-bottom: 3px solid var(--portal-line);
  border-radius: 6px;
  display: inline-block;
  height: 1.15em;
  min-width: 4.5em;
}

.exercise-form { align-items: center; display: grid; gap: 16px; justify-items: center; max-width: 680px; width: 100%; }
.exercise-prompt { overflow-wrap: anywhere; }
.exercise-input { border: 1px solid var(--portal-line); border-radius: 5px; font-size: 1.1rem; max-width: 500px; min-height: 48px; padding: 0 14px; text-align: center; width: 100%; }
.exercise-input:focus { border-color: var(--portal-green); box-shadow: 0 0 0 3px var(--portal-green-soft); outline: 0; }
.check-answer, .listen-button, .record-button, .clear-answer { border: 0; border-radius: 5px; font-weight: 800; min-height: 44px; padding: 0 18px; }
.check-answer { background: var(--portal-green); color: #fff; margin-top: 4px; }
.listen-button, .record-button { background: var(--portal-green-soft); color: var(--portal-green-dark); }
.clear-answer { background: transparent; border: 1px solid var(--portal-line); color: var(--portal-muted); min-height: 36px; }
.reveal-link { background: transparent; border: 0; color: var(--portal-muted); font-size: .75rem; margin-top: 16px; text-decoration: underline; }
.sentence-answer { border-bottom: 2px solid var(--portal-green); box-sizing: border-box; color: var(--portal-text); font-size: 1.05rem; min-height: 52px; padding: 14px; width: 100%; }
.sentence-answer span { color: var(--portal-muted); }
.token-bank { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
/* This block predates being wired to anything (sentence building was
   scaffolded-and-unreachable) -- color was never set, so on this white
   background the global `button { color: #fff }` rule (app.css) made every
   token's label invisible. */
.token-bank button { background: #fff; border: 1px solid var(--portal-line); border-radius: 5px; color: var(--portal-text); font-size: .94rem; min-height: 40px; padding: 0 13px; }
.token-bank button:disabled { opacity: .35; }
.speech-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.speech-status { color: var(--portal-muted); font-size: .78rem; margin: 0; }
.exercise-feedback { background: #fff; border: 1px solid var(--portal-line); border-top: 5px solid var(--portal-green); display: grid; gap: 24px; margin: 30px auto; max-width: 820px; padding: clamp(28px,5vw,54px); }
.exercise-feedback.incorrect { border-top-color: #b54a3f; }
.feedback-mark { align-items: center; background: var(--portal-green-soft); border-radius: 50%; color: var(--portal-green-dark); display: flex; font-size: 1.5rem; font-weight: 900; height: 48px; justify-content: center; width: 48px; }
.exercise-feedback.incorrect .feedback-mark { background: #fbecea; color: #9f382f; }
.exercise-feedback h1 { font-size: clamp(1.8rem,5vw,3.2rem); margin: 8px 0; overflow-wrap: anywhere; }
.exercise-feedback dl { display: grid; gap: 3px; margin: 18px 0; }
.exercise-feedback dt { color: var(--portal-muted); font-size: .68rem; font-weight: 800; text-transform: uppercase; }
.exercise-feedback dd { margin: 0; }
.feedback-next { background: var(--portal-green); border-radius: 5px; color: #fff; font-weight: 800; justify-self: start; padding: 12px 18px; text-decoration: none; }
.sr-only { height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; clip: rect(0,0,0,0); }
.reveal-button { background: var(--portal-green); border: 0; border-radius: 5px; color: #fff; font-weight: 800; margin-top: 30px; min-height: 46px; padding: 0 22px; }
.reveal-button kbd, .review-actions kbd {
  background: rgba(255,255,255,.25);
  border-radius: 3px;
  font-size: .68rem;
  font-weight: 700;
  margin-left: 7px;
  opacity: .9;
  padding: 2px 6px;
}

/* FSRS 4-way rating (W5). Grid, not flex, so all 4 fit one row down to 320px
   without wrapping or horizontal scroll. Colour: Again/Hard/Easy get their own
   tokens above; Good reuses the brand green already used for every other
   primary action on this page (reveal-button, check-answer, feedback-next) --
   rating buttons are UI chrome, so gender colour never appears here. */
.review-actions {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: 28px;
}
.review-actions button {
  align-items: baseline;
  border: 0;
  border-radius: 10px;
  color: #fff;
  display: flex;
  flex-wrap: wrap;
  font-size: .86rem;
  font-weight: 800;
  gap: 4px;
  justify-content: center;
  padding: 14px 4px;
}
.review-actions button small { font-size: .68rem; font-weight: 600; opacity: .85; }
.review-actions .rating-again { background: var(--rating-again); }
.review-actions .rating-hard { background: var(--rating-hard); }
.review-actions .rating-good { background: var(--portal-green); }
.review-actions .rating-easy { background: var(--rating-easy); }
.study-card-back { display: grid; gap: 18px; }
.answer-heading { text-align: center; }
.answer-heading h1 { margin-bottom: 6px; }
.study-info-grid { gap: 0; }
.study-info-grid div { border-bottom: 1px solid var(--portal-line); padding: 10px 8px; }
.study-conjugation { border: 1px solid var(--portal-line); display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); }
.study-conjugation article { min-width: 0; padding: 18px; }
.study-conjugation article + article { border-left: 1px solid var(--portal-line); }
.study-conjugation h3 { font-size: .95rem; margin: 0 0 16px; text-align: center; }
.study-conjugation p { margin: 9px 0; }
.study-conjugation p span { display: inline-block; min-width: 72px; }
.study-conjugation p strong, .principal-form { color: var(--portal-green-dark); }
.principal-form { display: block; font-size: 1.08rem; text-align: center; }

/* Conjugation table: the part that changes per person (conjugated
   aux/verb) stays plain ink; the invariant trailing part every person
   shares (a Partizip II or infinitive, e.g. Perfekt's "gehabt") gets the
   accent colour -- the "second colour for the stem/participle" Kemal asked
   for. A simple one-word tense (Praesens) has no invariant span at all, so
   .conj-changing carries the full weight there instead. */
.study-conjugation p strong.conj-changing { color: inherit; font-weight: 650; }
.study-conjugation p .conj-invariant { color: var(--portal-green-dark); font-weight: 700; margin-left: 4px; }
.study-conjugation .konjunktiv-block strong { color: var(--portal-green-dark); }
.tense-derived {
  color: var(--portal-muted); cursor: help; font-size: .56rem; font-weight: 800;
  letter-spacing: .03em; margin-left: 4px; text-transform: uppercase; vertical-align: super;
}
.section-eyebrow { color: var(--portal-muted); font-size: .64rem; font-weight: 800; letter-spacing: .04em; margin: -8px 0 14px; text-transform: uppercase; }
.tense-example { border-top: 1px solid var(--portal-line); font-size: .83rem; line-height: 1.45; margin-top: 18px !important; padding-top: 14px; }
.tense-example small, .participle-example span { color: var(--portal-muted); display: block; margin-top: 5px; }
.participle-example { display: grid; gap: 5px; }
.participle-example p { margin: 8px 0 0; }
.expression-focus { background: var(--portal-green-soft); display: grid; gap: 5px; padding: 16px; }
.expression-focus span, .sentence-focus span { color: var(--portal-muted); font-size: .82rem; }
.sentence-focus { border-left: 4px solid var(--portal-green); display: grid; gap: 8px; margin: 0; padding: 14px 18px; }
.preposition-case { background: var(--portal-green-soft); display: grid; gap: 5px; padding: 20px; text-align: center; }
.preposition-case span { color: var(--portal-muted); font-size: .68rem; font-weight: 800; }
.preposition-case strong { color: var(--portal-green-dark); font-size: 1.35rem; }
.preposition-case p { color: var(--portal-muted); margin: 0; }
.dialogue-example { display: grid; gap: 7px; grid-template-columns: 38px 1fr; }
.dialogue-example > span { align-items: center; background: var(--portal-green-soft); color: var(--portal-green-dark); display: flex; font-size: .68rem; font-weight: 850; grid-row: 1 / 3; justify-content: center; }
.dialogue-example p { color: var(--portal-muted); margin: 0; }
.phrase-heading h1 { font-size: clamp(1.8rem,5vw,3.4rem); }
.study-configurator { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin: 20px auto; max-width: 900px; padding: clamp(22px,4vw,40px); }
.study-configurator fieldset { border: 0; margin: 0 0 28px; padding: 0; }
.study-configurator legend { font-size: .78rem; font-weight: 850; margin-bottom: 12px; text-transform: uppercase; }
.segmented-options { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); }
.segmented-options label { position: relative; }
.segmented-options input { opacity: 0; position: absolute; }
.segmented-options span { border: 1px solid var(--portal-line); display: block; font-size: .78rem; font-weight: 750; min-height: 44px; padding: 13px 8px; text-align: center; }
.segmented-options label + label span { border-left: 0; }
.segmented-options input:checked + span { background: var(--portal-green); border-color: var(--portal-green); color: #fff; }
.segmented-options input:focus-visible + span { outline: 3px solid var(--portal-green-soft); outline-offset: 2px; }
.config-grid { display: grid; gap: 18px; grid-template-columns: repeat(3,minmax(0,1fr)); }
.config-grid label { display: grid; font-size: .72rem; font-weight: 750; gap: 7px; }
.config-grid select { background: #fff; border: 1px solid var(--portal-line); border-radius: 5px; min-height: 46px; padding: 0 10px; width: 100%; }
.study-configurator footer { align-items: center; border-top: 1px solid var(--portal-line); display: flex; justify-content: space-between; margin-top: 30px; padding-top: 22px; }
.study-configurator footer p { color: var(--portal-muted); font-size: .75rem; margin: 0; }
.study-configurator footer button { background: var(--portal-green); border: 0; border-radius: 5px; color: #fff; font-weight: 800; min-height: 46px; padding: 0 20px; }
.study-translation { margin: -8px 0 5px; }
.study-fact { background: var(--portal-green-soft); border-left: 4px solid var(--portal-green); display: grid; gap: 5px; margin: 0; padding: 14px 16px; }
.study-fact dt { color: var(--portal-muted); font-size: .68rem; font-weight: 750; text-transform: uppercase; }
.study-fact dd { font-size: 1rem; font-weight: 800; margin: 0; }
.study-details { border-top: 1px solid var(--portal-line); padding-top: 18px; }
.study-details h2 { font-size: .78rem; margin: 0 0 12px; text-transform: uppercase; }
.study-details dl { display: grid; grid-template-columns: repeat(3,1fr); margin: 0; }
.study-details dl div { display: grid; gap: 4px; }
.study-details dt { color: var(--portal-muted); font-size: .68rem; }
.study-details dd { font-size: .9rem; font-weight: 750; margin: 0; }
.study-examples { display: grid; gap: 8px; }
.study-examples article { border-left: 2px solid var(--portal-line); display: grid; gap: 5px; padding: 5px 12px; }
.study-examples article strong { font-size: .88rem; }
.study-examples article span { color: var(--portal-muted); font-size: .8rem; }
.study-example-tense { font-size: .68rem; font-weight: 750; text-transform: uppercase; }
.admin-heading span { color: var(--portal-green); font-size: .7rem; font-weight: 850; }
.admin-heading h1 { font-size: 2rem; margin: 6px 0; }
.admin-heading p { color: var(--portal-muted); margin: 0; }
.admin-heading { position: relative; }
.admin-heading > .button { position: absolute; right: 0; top: 8px; }
.editor-layout { align-items: start; display: grid; gap: 22px; grid-template-columns: minmax(0,1fr) 280px; }
.lexeme-editor { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; overflow: hidden; }
.lexeme-editor fieldset { border: 0; border-bottom: 1px solid var(--portal-line); display: grid; gap: 14px; margin: 0; padding: 24px; }
.lexeme-editor legend { font-size: .82rem; font-weight: 850; padding-top: 24px; }
.editor-grid { display: grid; gap: 14px; }
.editor-grid.two { grid-template-columns: repeat(2,minmax(0,1fr)); }
.editor-grid.three { grid-template-columns: repeat(3,minmax(0,1fr)); }
.lexeme-editor label { display: grid; font-size: .72rem; font-weight: 750; gap: 6px; }
.lexeme-editor input, .lexeme-editor select, .lexeme-editor textarea { box-sizing: border-box; width: 100%; }
.lexeme-editor textarea { font-family: inherit; line-height: 1.55; resize: vertical; }
.lexeme-editor label small, .field-help { color: var(--portal-muted); font-size: .65rem; font-weight: 450; margin: 0; }
.check-field { align-content: center; grid-template-columns: auto 1fr; }
.check-field input { width: auto; }
.present-editor { border-top: 1px solid var(--portal-line); padding-top: 16px; }
.editor-actions { align-items: center; display: flex; gap: 14px; padding: 20px 24px; }
.editor-actions a { color: var(--portal-muted); font-size: .76rem; }
.editor-sidebar { display: grid; gap: 14px; }
.editor-sidebar > section { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; padding: 18px; }
.editor-sidebar > section > span { color: var(--portal-muted); font-size: .63rem; font-weight: 850; }
.editor-sidebar h2 { font-size: 1.2rem; margin: 5px 0 14px; }
.workflow-actions form { display: grid; gap: 8px; margin: 0; }
.revision-list { display: grid; gap: 0; list-style: none; margin: 12px 0 0; padding: 0; }
.revision-list li { border-top: 1px solid var(--portal-line); display: grid; gap: 4px; padding: 12px 0; }
.revision-list small { color: var(--portal-muted); font-size: .65rem; }
.revision-list form { margin: 3px 0 0; }
.revision-list button { background: transparent; border: 0; color: var(--portal-green-dark); font-size: .68rem; padding: 0; text-align: left; }
.editor-danger { border-color: #e8c5c1 !important; }
.editor-danger p { color: var(--portal-muted); font-size: .72rem; }
.editor-danger button { background: #a63e35; }
.admin-filters { align-items: end; background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; display: grid; gap: 10px; grid-template-columns: minmax(180px,1fr) repeat(3,minmax(110px,.45fr)) auto; margin: 26px 0 16px; padding: 16px; }
.candidate-filters { grid-template-columns: minmax(180px,1fr) repeat(2,minmax(110px,.45fr)) auto; }
.feedback-filters { grid-template-columns: minmax(140px,220px) auto; }
.admin-filters label { display: grid; font-size: .7rem; font-weight: 750; gap: 5px; }
.admin-filters input, .admin-filters select, .admin-filters button { min-height: 42px; }
.admin-filters button { background: var(--portal-green); border: 0; border-radius: 5px; color: #fff; font-weight: 800; padding: 0 16px; }
.admin-table { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; overflow: hidden; }
.admin-table-head { display: flex; justify-content: space-between; padding: 16px 18px; }
.admin-table-head span { color: var(--portal-muted); font-size: .75rem; }
.admin-table table { border-collapse: collapse; width: 100%; }
.admin-table th, .admin-table td { border-top: 1px solid var(--portal-line); padding: 13px 18px; text-align: left; }
.admin-table th { color: var(--portal-muted); font-size: .68rem; text-transform: uppercase; }
.admin-table td { font-size: .82rem; }
.admin-table td:first-child { display: grid; gap: 2px; }
.admin-table td small { color: var(--portal-muted); }
.status-chip { border-radius: 4px; font-size: .68rem; font-weight: 750; padding: 5px 7px; }
.status-draft, .status-pending { background: #eef0ef; }
.status-reviewed { background: #fff2c8; color: #70570d; }
.status-published, .status-selected { background: var(--portal-green-soft); color: var(--portal-green-dark); }
.status-archived, .status-rejected { background: #f5e9eb; color: #8b3440; }
.status-promoted { background: var(--portal-blue-soft); color: var(--portal-blue); }
.status-open { background: #fff2c8; color: #70570d; }
.status-resolved { background: var(--portal-green-soft); color: var(--portal-green-dark); }
.pagination { align-items: center; border-top: 1px solid var(--portal-line); display: flex; justify-content: center; min-height: 54px; }
.pagination a, .pagination span { font-size: .76rem; padding: 8px 12px; }

/* Candidate review queue (M1.2) -- card system with inline section titles,
   no separate left-label column (see WEB_REDESIGN_2026-08-20.md). */
.candidate-progress { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin: 26px 0 0; padding: 16px 18px; }
.candidate-progress-head { display: flex; justify-content: space-between; align-items: baseline; font-size: .82rem; margin-bottom: 8px; }
.candidate-progress-head strong { font-variant-numeric: tabular-nums; }
.candidate-progress-head span { color: var(--portal-muted); font-size: .72rem; }
.candidate-progress-bar { accent-color: var(--portal-green); height: 8px; width: 100%; }
.candidate-queue { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin-top: 16px; overflow: hidden; }
.candidate-queue-head { display: flex; justify-content: space-between; padding: 16px 18px; }
.candidate-queue-head span { color: var(--portal-muted); font-size: .75rem; }
.candidate-row { border-top: 1px solid var(--portal-line); display: grid; gap: 4px 16px; grid-template-columns: 40px minmax(0,1fr) auto; padding: 16px 18px; }
.candidate-row:focus { outline: 2px solid var(--portal-green); outline-offset: -2px; }
.candidate-rank { color: var(--portal-muted); font-size: .78rem; font-variant-numeric: tabular-nums; font-weight: 750; padding-top: 3px; }
.candidate-main { min-width: 0; }
.candidate-headline { align-items: baseline; display: flex; flex-wrap: wrap; gap: 8px; }
.candidate-headline .headword-serif { font-size: 1.2rem; }
.candidate-pos { color: var(--portal-muted); font-size: .68rem; font-weight: 800; text-transform: uppercase; }
.candidate-freq { color: var(--portal-muted); font-size: .78rem; font-variant-numeric: tabular-nums; }
.candidate-key-small { color: var(--portal-muted); font-size: .7rem; margin: 2px 0; }
.candidate-gloss { align-items: baseline; color: var(--portal-text); display: flex; flex-wrap: wrap; font-size: .82rem; gap: 6px; margin: 4px 0; }
.gloss-badge { background: #eef0ef; border-radius: 4px; color: var(--portal-muted); font-size: .6rem; font-weight: 750; padding: 2px 6px; text-transform: uppercase; white-space: nowrap; }
/* M1.3 grammar-coverage indicator on the candidate queue -- so Kemal sees
   which words have a resolvable Wikidata gender/conjugation while reviewing. */
.grammar-chip { border-radius: 4px; font-size: .68rem; font-weight: 750; padding: 3px 7px; white-space: nowrap; }
.grammar-complete { background: var(--portal-green-soft); color: var(--portal-green-dark); }
.grammar-needs-review { background: #f5e9eb; color: #8b3440; border: 1px solid #d9a7ae; }
.grammar-partial { background: #fff2c8; color: #70570d; }
.grammar-none { background: #f5e9eb; color: #8b3440; }
.gloss-ambiguous { color: #8b3440; font-size: .72rem; font-weight: 700; }
.candidate-rationale { color: var(--portal-text); font-size: .86rem; line-height: 1.5; margin: 6px 0 0; }
.candidate-actions { align-items: flex-end; display: flex; flex-direction: column; gap: 6px; }
.candidate-approve, .candidate-reject { border-radius: 5px; font-size: .78rem; font-weight: 800; min-height: 34px; padding: 0 14px; white-space: nowrap; }
.candidate-approve { background: var(--portal-green); border: 0; color: #fff; }
.candidate-reject { background: #fff; border: 1px solid var(--portal-line); color: #8b3440; }
.candidate-review-link { color: var(--portal-green-dark); font-size: .74rem; }
.skip-link { background: #fff; color: var(--portal-text); left: 12px; padding: 10px 14px; position: fixed; top: -60px; z-index: 100; }
.skip-link:focus { top: 12px; }
.portal-page-heading { align-items: end; display: flex; justify-content: space-between; margin-bottom: 22px; }
.portal-page-heading > div > span, .portal-page-heading .section-header > div > span { color: var(--portal-green); font-size: .7rem; font-weight: 850; }
.portal-page-heading h1 { font-size: 2rem; margin: 5px 0; }
.portal-page-heading p { color: var(--portal-muted); margin: 0; }
.library-filters { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px 8px 0 0; padding: 14px 16px; }
.library-filters .controls { display: grid; grid-template-columns: minmax(180px,1fr) 110px auto; }
/* flex-wrap, not a fixed column grid: at 768px the sidebar leaves too little
   room for four fixed-width columns (measured 858px content in a 768px
   viewport). Wrapping is the native fix -- fields drop to a second row
   instead of forcing the row wider than the viewport. */
.library-filters .lexeme-filter-grid { align-items: end; display: flex; flex-wrap: wrap; gap: 12px; }
.lexeme-filter-grid label { display: grid; flex: 1 1 150px; gap: 5px; min-width: 0; }
.lexeme-filter-grid label > span { color: var(--portal-muted); font-size: .66rem; font-weight: 800; text-transform: uppercase; }
.lexeme-filter-grid input, .lexeme-filter-grid select { box-sizing: border-box; min-height: 42px; width: 100%; }
.lexeme-filter-grid button { flex: 0 0 auto; min-height: 42px; }
.library-summary { align-items: baseline; display: flex; gap: 7px; margin: 18px 0 9px; }
.library-summary strong { font-size: 1.15rem; }
.library-summary span { color: var(--portal-muted); font-size: .75rem; }
.lexeme-grid { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; overflow: hidden; }
.lexeme-row { align-items: center; color: var(--portal-text); display: grid; gap: 14px; grid-template-columns: 38px minmax(0,1fr) minmax(130px,.45fr) 20px; padding: 15px 17px; text-decoration: none; }
.lexeme-row + .lexeme-row { border-top: 1px solid var(--portal-line); }
.lexeme-row:hover { background: #fafcfb; }
.pos-mark { align-items: center; background: var(--portal-line); border-radius: 5px; color: var(--portal-muted); display: flex; font-size: .72rem; font-weight: 900; height: 36px; justify-content: center; width: 36px; }
/* Words list (W4): every part-of-speech pill is the same neutral grey --
   "no colour beyond the three gender hues" applies to rows, so the old
   per-type colour set (blue/amber/purple/red/teal) is gone, not just the
   verb default. */
.level-chip { background: var(--portal-line); border-radius: 4px; color: var(--portal-muted); font-size: .62rem; font-weight: 800; padding: 2px 6px; }
/* Gender colour signature (W4): article word in noun rows. Text is always
   printed ("der"/"die"/"das") -- colour reinforces, never carries alone. */
.gender-article { font-weight: 850; }
.lexeme-row-main { display: grid; gap: 2px; min-width: 0; }
.lexeme-row-main small { align-items: center; color: var(--portal-muted); display: flex; font-size: .62rem; font-weight: 750; gap: 6px; }
.lexeme-row-main strong { font-size: .96rem; overflow-wrap: anywhere; }
.lexeme-row-main em, .lexeme-meta { color: var(--portal-muted); font-size: .75rem; font-style: normal; overflow-wrap: anywhere; }
.row-arrow { color: var(--portal-muted); font-size: 1.35rem; }
.generic-detail { margin: 0 auto; max-width: 820px; }
/* Word detail (W4): every card shares this shell -- inline title, no
   separate label column (that pattern wasted a whole column on P3). */
.detail-crumb { color: var(--portal-muted); font-size: .76rem; margin: 0 0 20px; }
.detail-hero-row { align-items: flex-start; display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; }
.detail-hero-row > * { min-width: 0; }
.detail-meaning { color: var(--portal-muted); font-size: 1.05rem; margin: 10px 0 0; overflow-wrap: anywhere; }
.detail-card { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin-top: 16px; padding: clamp(20px,4vw,30px); }
.detail-card h2 { color: var(--portal-green-dark); font-size: .78rem; font-weight: 850; letter-spacing: .02em; margin: 0 0 16px; text-transform: uppercase; }
.detail-card .form-note { color: var(--portal-muted); font-size: .82rem; margin: 4px 0 0; }
.detail-cta { display: flex; justify-content: flex-end; margin-top: 20px; }

/* Units (docs/units-spec.md): grouped by category (expressions vs vocabulary,
   0027_unit_category.py). One compact row per unit -- 20 units as full cards
   with a full-width button each made mobile /units a 4,678px scroll; a row
   list with an inline "Start" button keeps one-tap start but scans in one
   screenful of glances instead of one card-height of scrolling per unit. */
.unit-list { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin: 10px 0 26px; overflow: hidden; }
.unit-row { align-items: center; border-bottom: 1px solid var(--portal-line); display: grid; gap: 4px 12px; grid-template-columns: auto minmax(0,1fr) auto; padding: 9px 14px; }
.unit-list .unit-row:last-child { border-bottom: 0; }
.unit-row-main { display: grid; gap: 1px; min-width: 0; }
.unit-row-title { font-size: .92rem; font-weight: 700; }
.unit-row-meta { color: var(--portal-muted); font-size: .7rem; }
.unit-row form { grid-column: 3; }
.unit-row button { background: var(--portal-green); border: 0; border-radius: 6px; color: #fff; font-size: .78rem; font-weight: 800; min-height: 40px; padding: 0 14px; white-space: nowrap; }
/* Verbs page (/verbs): each row needs a second action (drill just this
   deck's conjugations) alongside the units-page "Start" button -- a flex
   wrapper around both forms takes the single grid-column: 3 slot instead of
   widening the row. */
.unit-row-actions { display: flex; gap: 8px; grid-column: 3; }
.unit-row-actions form { flex: 1; }
.unit-row-actions button { width: 100%; }
.unit-row-actions .secondary-btn { background: #fff; border: 1px solid var(--portal-line); color: var(--portal-green-dark); }
/* Was max-width: 359px -- too narrow to catch 390px (iPhone 12/13/14), where
   the two verbs-page buttons ("Start" + "Conjugate") still squeezed the
   auto/1fr/auto row enough to overflow deck titles behind the button
   background (no scrollbar, so scrollWidth<=clientWidth checks missed it).
   480px matches the file's other mobile-row breakpoint (.stat-chips-4). */
@media (max-width: 480px) {
  .unit-row { grid-template-columns: auto 1fr; }
  .unit-row form { grid-column: 1 / -1; }
  .unit-row button { width: 100%; }
  .unit-row-actions { flex-direction: column; grid-column: 1 / -1; }
}
.context-list, .expression-list { display: grid; }
.context-list article, .expression-list article { border-bottom: 1px solid var(--portal-line); display: grid; gap: 6px; padding: 15px 0; }
.context-list article:first-child, .expression-list article:first-child { padding-top: 0; }
.context-list article:last-child, .expression-list article:last-child { border-bottom: 0; padding-bottom: 0; }
.context-list article > div { align-items: baseline; display: flex; gap: 10px; }
.context-list article > div span { color: var(--portal-green-dark); font-size: .65rem; font-weight: 850; }
.context-list p, .context-list small, .expression-list span { color: var(--portal-muted); margin: 0; }
.expression-list article { grid-template-columns: minmax(0,1fr) minmax(0,1fr); }
.library-table, .progress-history { background: #fff; border: 1px solid var(--portal-line); border-radius: 0 0 8px 8px; overflow: hidden; }
.library-table table, .progress-history table { border-collapse: collapse; width: 100%; }
.library-table th, .library-table td, .progress-history th, .progress-history td { border-bottom: 1px solid var(--portal-line); padding: 13px 16px; text-align: left; }
.library-table th, .progress-history th { color: var(--portal-muted); font-size: .68rem; text-transform: uppercase; }
.library-table td, .progress-history td { font-size: .82rem; }
.empty-state { padding: 50px 22px; text-align: center; }
.empty-state h3 { margin: 0 0 7px; }
.empty-state p { color: var(--portal-muted); font-size: .84rem; }
.lexeme-detail { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; padding: clamp(24px,5vw,38px); }
.lexeme-detail h1 { font-size: clamp(2.2rem,5vw,3.4rem); margin: 0; overflow-wrap: anywhere; }
.detail-back { color: var(--portal-green); font-size: .72rem; font-weight: 750; }
.detail-facts { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 18px; }
.detail-facts span { background: #f2f5f3; border-radius: 4px; font-size: .72rem; padding: 7px 9px; }
.progress-overview { display: grid; gap: 14px; grid-template-columns: 260px 1fr; }
.progress-primary { background: var(--portal-green-dark); border-radius: 8px; color: #fff; padding: 25px; }
.progress-primary > span { color: #8dd9bd; font-size: .68rem; font-weight: 800; }
.progress-primary strong { display: block; font-size: 3rem; margin: 15px 0 4px; }
.progress-primary p { color: #cbd8d3; font-size: .78rem; margin: 0; }
.progress-metrics { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; display: grid; grid-template-columns: repeat(4,1fr); }
.progress-metrics article { display: grid; gap: 7px; padding: 22px; }
.progress-metrics article + article { border-left: 1px solid var(--portal-line); }
.progress-metrics span, .progress-metrics small { color: var(--portal-muted); font-size: .7rem; }
.progress-metrics strong { font-size: 1.6rem; }
.level-progress { margin: 28px 0; }
.level-meter-list { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; margin-top: 12px; padding: 10px 18px; }
.level-meter-list div { align-items: center; display: grid; gap: 12px; grid-template-columns: 28px 1fr 25px; padding: 9px 0; }
.level-meter-list span { background: #e7ebe9; border-radius: 3px; height: 7px; overflow: hidden; }
.level-meter-list i { background: var(--portal-green); display: block; height: 100%; }
.level-meter-list small { color: var(--portal-muted); text-align: right; }
.progress-history { border-radius: 8px; }
.progress-history .portal-section-heading { padding: 18px; }
.learning-status { border-radius: 4px; font-size: .66rem; padding: 5px 7px; }
.status-new { background: #eef0ef; }
.status-learning { background: #fff2c8; color: #70570d; }
.status-known { background: var(--portal-green-soft); color: var(--portal-green); }

.portal-section-heading {
  align-items: center;
  display: flex;
  justify-content: space-between;
}

.portal-section-heading h2 {
  font-size: 1.25rem;
  margin: 3px 0 0;
}

.portal-section-heading > small {
  color: var(--portal-muted);
}

/* Today dashboard (2026-08-21 layout): hero -> progress band -> tiered study
   options, with the week chart and word list in a side column on desktop.
   Green stays chrome-only; gender colours stay content-only. */
.today-grid {
  display: grid;
  gap: 18px;
  grid-template-columns: minmax(0, 1fr);
}

.today-main, .today-side { display: grid; gap: 14px; align-content: start; }

@media (min-width: 1000px) {
  .today-grid { align-items: start; gap: 20px; grid-template-columns: minmax(0, 1.5fr) minmax(300px, 0.8fr); }
}

.today-hero {
  background: var(--portal-green-dark);
  border-radius: 14px;
  color: #fff;
  padding: 24px 24px 22px;
}

.today-hero-top { display: flex; gap: 16px; justify-content: space-between; }

.today-hero-label { color: #a7d9c5; font-size: 0.86rem; font-weight: 700; }

.today-hero-count {
  display: block;
  font-size: clamp(3.4rem, 9vw, 4.6rem);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.04em;
  line-height: 1;
  margin: 6px 0 2px;
}

.today-hero-top p { color: #cfe0d9; font-size: 1rem; font-weight: 650; margin: 0; }

.streak-pill {
  background: rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 750;
  height: max-content;
  padding: 8px 12px;
  white-space: nowrap;
}

.today-hero-action {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 22px;
}

.today-hero-action form { margin: 0; }

.hero-cta {
  background: #fff;
  border: 0;
  border-radius: 12px;
  color: var(--portal-green-dark);
  font-size: 0.94rem;
  font-weight: 800;
  min-height: 50px;
  padding: 0 22px;
}

.hero-next { color: #bcd3cb; font-size: 0.78rem; margin: 0; }
.hero-next strong { color: #fff; display: block; font-size: 1.2rem; margin-top: 2px; }
/* Gender colours are unreadable on the dark hero; these are the same three
   hues lightened for contrast, not new meanings. */
.hero-article-der { color: #a9c7ff; }
.hero-article-die { color: #ffc0d0; }
.hero-article-das { color: #ffdca7; }

.hero-goal { margin-top: 22px; }
.hero-goal-line { display: flex; font-size: 0.8rem; font-weight: 700; justify-content: space-between; margin-bottom: 8px; }
.hero-goal-track { background: rgba(255, 255, 255, 0.22); border-radius: 999px; height: 9px; overflow: hidden; }
.hero-goal-track span { background: #fff; display: block; height: 100%; }

.progress-band { display: grid; gap: 12px; grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.7fr); }
@media (max-width: 520px) { .progress-band { grid-template-columns: minmax(0, 1fr); } }

.progress-known, .mini-stat {
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  border-radius: 12px;
  padding: 18px;
}

.progress-known-head { display: flex; gap: 16px; justify-content: space-between; }
.progress-known h2 { font-size: 0.98rem; margin: 0 0 5px; }
.progress-known-count { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.03em; margin: 0; }
.progress-known-count span { color: var(--portal-muted); font-size: 1rem; font-weight: 650; }
.progress-known-sub { color: var(--portal-muted); font-size: 0.8rem; margin: 4px 0 0; }
.progress-known-aside { text-align: right; }
.progress-known-aside span { color: var(--portal-muted); display: block; font-size: 0.72rem; font-weight: 750; }
.progress-known-aside strong { font-size: 1.2rem; }

.known-track { background: var(--portal-line); border-radius: 999px; height: 7px; margin-top: 15px; overflow: hidden; }
.known-track span { background: var(--portal-green); display: block; height: 100%; }

.mini-stat { background: var(--portal-green-soft); border-color: #cfe4da; display: grid; align-content: start; }
.mini-stat strong { font-size: 1.5rem; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }
.mini-stat > span { font-size: 0.78rem; margin-top: 2px; }
.mini-stat small { color: var(--portal-muted); font-size: 0.72rem; margin-top: 10px; }

.section-head { align-items: baseline; display: flex; justify-content: space-between; margin-bottom: 10px; }
.section-head h2 { font-size: 1.05rem; margin: 0; }
.section-head a { color: var(--portal-green); font-size: 0.8rem; font-weight: 750; }

.study-grid { display: grid; gap: 10px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 700px) { .study-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.study-item {
  align-items: center;
  color: inherit;
  text-decoration: none;
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  border-radius: 12px;
  display: grid;
  gap: 12px;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  margin: 0;
  padding: 14px;
}

.study-icon {
  align-items: center;
  border-radius: 11px;
  display: flex;
  font-size: 0.95rem;
  font-weight: 800;
  height: 40px;
  justify-content: center;
  width: 40px;
}

/* Chrome, not content: these tint the action, never a German word. */
.study-icon-verb { background: var(--portal-green-soft); color: var(--portal-green-dark); }
.study-icon-article { background: var(--portal-blue-soft); color: var(--portal-blue); }
.study-icon-leech { background: #fae8ed; color: var(--rating-again); }
.study-icon-units { background: #f4efe3; color: var(--rating-hard); }

.study-item-text { display: grid; min-width: 0; }
.study-item-text strong { font-size: 0.94rem; }
.study-item-text small { color: var(--portal-muted); font-size: 0.76rem; margin-top: 3px; }
.study-item-text small a { color: var(--portal-green); text-decoration: underline; }

.study-item:hover { border-color: var(--portal-green); }
.study-item:hover .study-go { color: var(--portal-green-dark); }

.study-go {
  background: none;
  border: 0;
  color: var(--portal-muted);
  font-size: 1.4rem;
  line-height: 1;
  padding: 6px 10px;
}

.study-badge {
  background: #fae8ed;
  border: 0;
  border-radius: 999px;
  color: var(--rating-again);
  font-size: 0.78rem;
  font-weight: 800;
  padding: 6px 12px;
}

/* D1: stat chips -- bordered 3-up grid, brand-green number, muted label.
   Chrome, not content, so brand green (never gender colour) is correct here. */
.stat-chips {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(3, 1fr);
  margin: 0;
}

.stat-chips div {
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  border-radius: 8px;
  padding: 14px 6px;
  text-align: center;
}

.stat-chips strong {
  color: var(--portal-green);
  display: block;
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.stat-chips span {
  color: var(--portal-muted);
  display: block;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  margin-top: 6px;
  text-transform: uppercase;
}

/* Progress page (W4 wave 2B): same stat-chip component, 4-up. Wraps to 2x2
   under 480px so "62.5%" never gets squeezed into a ~65px column. */
.stat-chips-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 480px) {
  .stat-chips-4 { grid-template-columns: repeat(2, 1fr); }
}

/* Recent-reviews rating pill -- reuses the FSRS rating colours (chrome, not
   gender) as text colour on a soft neutral fill, matching .learning-status. */
.rating-pill { border-radius: 4px; font-size: .66rem; font-weight: 750; padding: 5px 7px; background: #eef0ef; }
.rating-pill.rating-again { color: var(--rating-again); }
.rating-pill.rating-hard { color: var(--rating-hard); }
.rating-pill.rating-good { color: var(--portal-green); }
.rating-pill.rating-easy { color: var(--rating-easy); }

/* D2: activity strip -- filled squares come only from real review_events
   dates (see PostgresProgressRepository.statistics); never invented. */
.activity-strip {
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  border-radius: 8px;
  padding: 12px 16px 14px;
}

.activity-strip-label {
  color: var(--portal-muted);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}

.activity-days {
  display: grid;
  gap: 6px;
  grid-template-columns: repeat(7, 1fr);
  margin-top: 8px;
}

.activity-days span {
  aspect-ratio: 1;
  background: var(--portal-bg);
  border-radius: 5px;
  color: var(--portal-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.62rem;
  font-weight: 800;
}

.activity-days span.filled {
  background: var(--portal-green);
  color: #fff;
}

/* Week chart: bar height is relative to the busiest day, so the shape means
   volume. Counts come from real review_events only -- never invented. */
.week-card, .words-card {
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  border-radius: 12px;
  padding: 18px;
}

.week-head strong { display: block; font-size: 0.9rem; }
.week-head small { color: var(--portal-muted); font-size: 0.74rem; }

.week-bars {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(7, 1fr);
  height: 108px;
  margin-top: 16px;
}

/* The wrapper is a full-height flex column so the bars' percentage heights
   resolve against a real box instead of collapsing to their min-height. */
.week-bar-wrap { display: flex; flex-direction: column; justify-content: flex-end; height: 100%; text-align: center; }
.week-bar {
  background: var(--portal-line);
  border-radius: 6px 6px 3px 3px;
  margin: 0 auto;
  min-height: 6px;
  width: min(100%, 26px);
}
.week-bar.filled { background: var(--portal-green); }
.week-bar-wrap small { color: var(--portal-muted); font-size: 0.68rem; font-weight: 700; margin-top: 8px; }

.words-label { color: var(--portal-muted); display: block; font-size: 0.72rem; font-weight: 750; }

.words-continue { border-bottom: 1px solid var(--portal-line); margin-bottom: 14px; padding-bottom: 14px; }
.words-continue p { font-size: 1.4rem; font-weight: 700; margin: 5px 0 0; }
.words-continue small { color: var(--portal-muted); font-size: 0.8rem; }

.word-chips { display: grid; gap: 9px; grid-template-columns: repeat(2, minmax(0, 1fr)); list-style: none; margin: 9px 0 0; padding: 0; }
.word-chips li { background: var(--portal-bg); border: 1px solid var(--portal-line); border-radius: 10px; min-width: 0; padding: 10px; }
.word-chips .headword-serif { display: block; font-size: 1rem; overflow-wrap: anywhere; }
.word-chips small { color: var(--portal-muted); display: block; font-size: 0.72rem; margin-top: 2px; }
.word-chips .gender-article { font-size: 0.8rem; }

.level-link {
  color: var(--portal-muted);
  font-size: 0.78rem;
  text-decoration: none;
}

.level-link:hover {
  color: var(--portal-text);
}

.goal-track {
  background: var(--portal-line);
  border-radius: 4px;
  height: 10px;
  margin-top: 16px;
  overflow: hidden;
}

.goal-track span {
  background: var(--portal-green);
  display: block;
  height: 100%;
}

.public-header {
  background: var(--portal-surface);
  border-bottom: 1px solid var(--portal-line);
  padding: 14px clamp(18px, 4vw, 48px);
}

.public-content {
  margin: 0;
  max-width: none;
  padding: 0;
}

.public-header-inner { align-items: center; display: flex; justify-content: space-between; margin: 0 auto; max-width: 1240px; }
.public-nav { display: flex; gap: 8px; }
.public-nav a { color: var(--portal-text); font-size: .88rem; font-weight: 700; padding: 10px 14px; text-decoration: none; }
.public-nav .public-cta { background: var(--portal-green); border-radius: 6px; color: #fff; }

.marketing-hero {
  align-items: center;
  background: #f4f2ed url("/static/images/learning-hero-v2.webp") center/cover no-repeat;
  color: var(--portal-text);
  display: flex;
  min-height: min(720px, calc(100vh - 64px));
  padding: clamp(70px, 10vh, 120px) max(24px, calc((100vw - 1240px)/2));
  position: relative;
}

.hero-copy { max-width: 590px; position: relative; z-index: 1; }
.hero-kicker, .section-intro > span, .course-band > div > span, .profile-heading > span { color: var(--portal-green); font-size: .72rem; font-weight: 850; }
.hero-copy h1 { font-size: clamp(2.8rem, 6vw, 5.25rem); line-height: .98; margin: 18px 0 24px; max-width: 570px; }
.hero-copy p { color: #43514a; font-size: clamp(1rem, 2vw, 1.25rem); line-height: 1.6; max-width: 530px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin: 32px 0 20px; }
.primary-action, .secondary-action { border-radius: 6px; display: inline-flex; font-size: .92rem; font-weight: 800; justify-content: center; padding: 14px 20px; text-decoration: none; }
.primary-action { background: #f1ca56; color: #18211d; }
.secondary-action { background: rgba(255,255,255,.82); border: 1px solid #aeb9b3; color: var(--portal-text); }
.hero-copy small { color: #59675f; }

.proof-strip { background: #fff; border-bottom: 1px solid var(--portal-line); display: grid; grid-template-columns: repeat(3,1fr); margin: 0 auto; padding: 26px max(24px, calc((100vw - 1240px)/2)); }
.proof-strip div { display: grid; gap: 5px; padding: 0 28px; }
.proof-strip div + div { border-left: 1px solid var(--portal-line); }
.proof-strip strong { font-size: .91rem; }
.proof-strip span { color: var(--portal-muted); font-size: .78rem; }

.marketing-section { margin: 0 auto; max-width: 1240px; padding: 90px 24px; }
.section-intro { max-width: 650px; }
.section-intro > span, .course-band > div > span, .profile-heading > span { color: var(--portal-green); }
.section-intro h2, .course-band h2, .final-cta h2 { font-size: clamp(2rem,4vw,3.3rem); line-height: 1.08; margin: 10px 0 16px; }
.section-intro p { color: var(--portal-muted); font-size: 1.05rem; line-height: 1.65; }
.method-grid { border-bottom: 1px solid var(--portal-line); border-top: 1px solid var(--portal-line); display: grid; grid-template-columns: repeat(3,1fr); margin-top: 48px; }
.method-grid article { padding: 34px 28px; }
.method-grid article + article { border-left: 1px solid var(--portal-line); }
.method-grid b { color: var(--portal-green); font-size: .75rem; }
.method-grid h3 { font-size: 1.15rem; margin: 34px 0 10px; }
.method-grid p { color: var(--portal-muted); font-size: .9rem; line-height: 1.6; margin: 0; }

.course-band { background: #17352b; color: #fff; display: grid; gap: 70px; grid-template-columns: minmax(260px,.8fr) minmax(400px,1.2fr); padding: 80px max(24px, calc((100vw - 1160px)/2)); }
.course-band ol { list-style: none; margin: 0; padding: 0; }
.course-band li { align-items: start; border-top: 1px solid rgba(255,255,255,.18); display: grid; gap: 20px; grid-template-columns: 90px 1fr; padding: 22px 0; }
.course-band li strong { color: #f1ca56; }
.course-band li span { color: #cbd9d4; line-height: 1.5; }
.final-cta { background: #fff; padding: 85px 24px; text-align: center; }
.final-cta p { color: var(--portal-muted); margin: 0 0 28px; }
.public-footer { padding: 24px; text-align: center; }
.public-footer a { color: var(--portal-muted); font-size: .82rem; text-decoration: none; }
.public-footer a:hover { color: var(--portal-green); }
.error-page { margin: 0 auto; max-width: 680px; min-height: calc(100vh - 180px); padding: 110px 24px; text-align: center; }
.error-page > span { color: var(--portal-green); font-size: .78rem; font-weight: 850; }
.error-page h1 { font-size: clamp(2.2rem,5vw,4rem); margin: 12px 0 18px; }
.error-page p { color: var(--portal-muted); line-height: 1.65; margin: 0 auto 30px; max-width: 520px; }
form[aria-busy="true"] { cursor: progress; }
button.is-loading { opacity: .7; }

.account-page { align-items: start; display: grid; gap: clamp(40px,8vw,100px); grid-template-columns: minmax(0,1fr) minmax(350px,520px); margin: 0 auto; max-width: 1120px; min-height: calc(100vh - 64px); padding: 70px 24px; }
.account-page > *, .profile-layout > *, .form-row > * { min-width: 0; }
.account-intro { padding-top: 48px; }
.account-intro h1 { font-size: clamp(2.5rem,5vw,4rem); line-height: 1.04; margin: 10px 0 20px; overflow-wrap: anywhere; }
.account-intro p { color: var(--portal-muted); font-size: 1.05rem; line-height: 1.65; max-width: 500px; }
.account-panel, .settings-panel, .account-summary, .danger-zone { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; padding: clamp(24px,4vw,38px); }
.account-panel h2, .settings-panel h2 { margin-top: 0; }
.account-form { display: grid; gap: 17px; }
.account-form label { display: grid; font-size: .78rem; font-weight: 750; gap: 7px; }
.account-form input, .account-form select { background: #fff; border: 1px solid #cbd3cf; border-radius: 5px; font: inherit; min-height: 46px; padding: 10px 12px; width: 100%; }
.account-form label small { color: var(--portal-muted); font-weight: 500; }
.account-form button { background: var(--portal-green); border: 0; border-radius: 5px; color: #fff; font-weight: 800; min-height: 48px; }
.form-row { display: grid; gap: 12px; grid-template-columns: 1fr 1fr; }
.account-form fieldset { border: 0; border-top: 1px solid var(--portal-line); display: grid; gap: 14px; margin: 8px 0 0; padding: 22px 0 0; }
.account-form legend { font-size: .84rem; font-weight: 800; padding-right: 8px; }
.account-form legend small { color: var(--portal-muted); font-weight: 500; }

.profile-heading { margin-bottom: 28px; }
.profile-heading h1 { font-size: 2rem; margin: 6px 0; }
.profile-heading p { color: var(--portal-muted); margin: 0; }
.settings-tabs { border-bottom: 1px solid var(--portal-line); display: flex; gap: 28px; margin-bottom: 28px; overflow-x: auto; }
.settings-tabs a { border-bottom: 2px solid transparent; color: var(--portal-muted); font-size: .84rem; font-weight: 750; padding: 0 2px 13px; text-decoration: none; white-space: nowrap; }
.settings-tabs a.active { border-bottom-color: var(--portal-green); color: var(--portal-green-dark); }
.settings-tab-panel { margin: 0; max-width: 780px; }
.settings-title > div p { color: var(--portal-muted); font-size: .84rem; margin: -10px 0 24px; }
.profile-overview { display: grid; gap: 24px; }
.profile-identity { align-items: center; background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; display: flex; gap: 20px; padding: 26px; }
.profile-identity > div { min-width: 0; }
.profile-identity > div > span { color: var(--portal-green); font-size: .68rem; font-weight: 850; text-transform: uppercase; }
.profile-identity h2 { margin: 4px 0; overflow-wrap: anywhere; }
.profile-identity p { color: var(--portal-muted); margin: 0; overflow-wrap: anywhere; }
.profile-facts { display: grid; gap: 14px; grid-template-columns: repeat(3,minmax(0,1fr)); }
.profile-facts article { background: #fff; border: 1px solid var(--portal-line); border-radius: 8px; display: grid; min-height: 150px; padding: 22px; }
.profile-facts article > span { color: var(--portal-muted); font-size: .65rem; font-weight: 850; }
.profile-facts strong { font-size: 1.15rem; margin-top: 8px; }
.profile-facts a { align-self: end; color: var(--portal-green); font-size: .76rem; font-weight: 750; text-decoration: none; }
.verification-action { align-items: center; border-top: 1px solid var(--portal-line); display: flex; justify-content: space-between; margin-top: 26px; padding-top: 22px; }
.verification-action p { color: var(--portal-muted); font-size: .8rem; }
.verification-action button { background: transparent; border: 1px solid var(--portal-line); border-radius: 5px; min-height: 40px; padding: 8px 12px; }
.account-danger { border-color: #e6c8cc; display: grid; gap: 28px; }
.account-danger > div > span { color: #a13b48; font-size: .68rem; font-weight: 850; }
.account-danger > div p { color: var(--portal-muted); line-height: 1.55; max-width: 600px; }
.account-danger .account-form { max-width: 460px; }
.account-danger .account-form button.bad { background: #a13b48; }
.profile-layout { align-items: start; display: grid; gap: 24px; grid-template-columns: minmax(0,1fr) 280px; }
.settings-title { align-items: center; display: flex; justify-content: space-between; }
.settings-title span { background: var(--portal-green-soft); border-radius: 4px; color: var(--portal-green); font-size: .7rem; font-weight: 800; padding: 6px 8px; }
.account-summary { text-align: center; }
.large-avatar { align-items: center; background: var(--portal-blue-soft); border-radius: 50%; color: var(--portal-blue); display: inline-flex; font-size: 1.5rem; font-weight: 850; height: 72px; justify-content: center; width: 72px; }
.account-summary h2 { margin: 14px 0 22px; }
.account-summary dl { margin: 0; text-align: left; }
.account-summary dl div { border-top: 1px solid var(--portal-line); display: flex; justify-content: space-between; padding: 12px 0; }
.account-summary dt { color: var(--portal-muted); font-size: .76rem; }
.account-summary dd { font-size: .78rem; font-weight: 750; margin: 0; }
.danger-zone { align-items: center; border-color: #e6c8cc; display: flex; justify-content: space-between; margin-top: 24px; }
.danger-zone h2 { font-size: 1rem; margin: 0 0 5px; }
.danger-zone p { color: var(--portal-muted); font-size: .8rem; margin: 0; }
.danger-zone form { align-items: end; display: flex; gap: 10px; }
.danger-zone label { display: grid; font-size: .7rem; gap: 4px; }
.danger-zone input { min-height: 38px; }
.danger-zone button { min-height: 38px; white-space: nowrap; }
.form-success { background: #e7f3ee; border-left: 4px solid var(--portal-green); color: var(--portal-green-dark); padding: 10px 12px; }
.admin-heading-actions { align-items: center; display: flex; gap: 14px; position: absolute; right: 0; top: 8px; }
.admin-heading-actions .button { position: static; }
.package-import { align-items: start; border-bottom: 1px solid var(--portal-line); border-top: 1px solid var(--portal-line); display: grid; gap: 36px; grid-template-columns: minmax(220px,.65fr) minmax(0,1.35fr); margin: 28px 0 36px; padding: 30px 0; }
.package-import > div > span, .package-preview > span, .package-summary > div > span { color: var(--portal-green); font-size: .7rem; font-weight: 850; }
.package-import h2, .package-preview h2, .package-summary h2 { margin: 7px 0 10px; }
.package-import p, .package-summary p { color: var(--portal-muted); font-size: .86rem; line-height: 1.55; }
.package-import form { display: grid; gap: 14px; }
.package-import label:not(.check-control) { display: grid; font-size: .75rem; font-weight: 750; gap: 7px; }
.package-import textarea { border: 1px solid var(--portal-line); border-radius: 5px; font: .78rem/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; padding: 12px; resize: vertical; width: 100%; }
.check-control { align-items: center; display: flex; font-size: .78rem; gap: 8px; }
.package-actions, .inline-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.package-actions button, .inline-actions button, .package-summary form button { min-height: 38px; }
.package-preview { background: var(--portal-blue-soft); border-left: 4px solid var(--portal-blue); margin: 0 0 32px; padding: 22px; }
.package-preview h2 small { color: var(--portal-muted); font-size: .8rem; }
.package-preview dl, .package-summary dl { display: grid; gap: 14px; grid-template-columns: repeat(4,minmax(0,1fr)); margin: 18px 0 0; }
.package-preview dl div, .package-summary dl div { display: grid; gap: 4px; }
.package-preview dt, .package-summary dt { font-size: .68rem; font-weight: 800; text-transform: uppercase; }
.package-preview dd, .package-summary dd { font-size: .84rem; min-width: 0; overflow-wrap: anywhere; }
.package-summary { align-items: start; border-bottom: 1px solid var(--portal-line); border-top: 1px solid var(--portal-line); display: grid; gap: 28px; grid-template-columns: minmax(180px,.6fr) minmax(0,1.4fr); margin: 28px 0 36px; padding: 28px 0; }
.package-summary > form { display: flex; flex-wrap: wrap; gap: 8px; grid-column: 1 / -1; }

@media (max-width: 900px) {
  .marketing-hero { background-position: 62% center; }
  .marketing-hero::after { background: rgba(244,242,237,.84); bottom: 0; content: ""; left: 0; position: absolute; right: 0; top: 0; }
  .account-page, .profile-layout { grid-template-columns: 1fr; }
  .account-intro { padding-top: 0; }
  .account-summary { display: none; }
  .admin-filters { grid-template-columns: repeat(2,1fr); }
  .progress-overview { grid-template-columns: 1fr; }
  .editor-layout { grid-template-columns: 1fr; }
  .package-import, .package-summary { grid-template-columns: 1fr; }
  .package-preview dl, .package-summary dl { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .editor-sidebar { grid-template-columns: repeat(2,minmax(0,1fr)); }
  /* Lexeme detail: the 232px sidebar stays visible down to 720px, so this
     needs to collapse at the same 900px tier as the other sidebar-aware
     layouts above, not wait for the sidebar itself to hide. */
  .expression-list article { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  body {
    overflow-x: hidden;
    padding-bottom: calc(58px + env(safe-area-inset-bottom, 0px));
  }

  .portal-shell {
    display: block;
    min-height: 0;
  }

  .portal-sidebar {
    display: none;
  }

  .portal-header {
    align-items: center;
    background: var(--portal-surface);
    border-bottom: 1px solid var(--portal-line);
    display: flex;
    justify-content: space-between;
    padding: 11px 16px;
  }
  .portal-header-brand { display: flex; }
  .account-menu-name, .account-menu summary > span:last-child { display: none; }

  .portal-content {
    padding: 22px 16px 40px;
  }

  .mobile-nav {
    background: var(--portal-surface);
    border-top: 1px solid var(--portal-line);
    bottom: 0;
    display: grid;
    /* Column count follows however many items primary_nav_items renders
       (base.html), instead of a hardcoded repeat(N,1fr) that wraps to a
       second row the next time a nav item is added. */
    grid-auto-columns: 1fr;
    grid-auto-flow: column;
    left: 0;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    position: fixed;
    right: 0;
    z-index: 10;
  }

  .mobile-nav a {
    align-items: center;
    color: var(--portal-muted);
    display: flex;
    flex-direction: column;
    font-size: 0.56rem;
    font-weight: 650;
    gap: 3px;
    padding: 8px 1px 8px;
    text-align: center;
    text-decoration: none;
  }

  .mobile-nav a svg { flex-shrink: 0; }

  .mobile-nav a.active {
    color: var(--portal-green);
  }

  .marketing-hero { min-height: 660px; padding: 82px 22px; }
  .marketing-hero { background-position: 62% center; }
  .marketing-hero::after { background: rgba(244,242,237,.9); bottom: 0; content: ""; left: 0; position: absolute; right: 0; top: 0; }
  .hero-copy { max-width: calc(100vw - 44px); }
  .hero-copy h1 { font-size: 2.65rem; }
  .proof-strip, .method-grid, .course-band { grid-template-columns: 1fr; }
  .proof-strip { padding: 12px 22px; }
  .proof-strip div { padding: 15px 0; }
  .proof-strip div + div { border-left: 0; border-top: 1px solid var(--portal-line); }
  .marketing-section { padding: 65px 22px; }
  .method-grid article { padding: 26px 4px; }
  .method-grid article + article { border-left: 0; border-top: 1px solid var(--portal-line); }
  .method-grid h3 { margin-top: 18px; }
  .course-band { gap: 28px; padding: 60px 22px; }
  .account-page { padding: 42px 18px; }
  .account-page { grid-template-columns: minmax(0,1fr); overflow: hidden; }
  .account-intro, .account-panel { max-width: calc(100vw - 36px); width: calc(100vw - 36px); }
  .public-nav { display: none; }
  .form-row { grid-template-columns: 1fr; }
  .profile-facts { grid-template-columns: 1fr; }
  .settings-tabs { gap: 20px; margin-left: -16px; margin-right: -16px; padding: 0 16px; }
  .verification-action { align-items: stretch; display: grid; gap: 10px; }
  .danger-zone { align-items: stretch; display: grid; gap: 20px; }
  .danger-zone form { align-items: stretch; display: grid; }
  .study-card-front, .study-card-back { min-height: 460px; padding: 28px 22px; }

  /* Study card fills the space between header and the fixed bottom nav so
     reveal/rating actions are reachable without scrolling. Scoped with :has()
     so it only applies to the study/exercise pages, not Today/Words/Progress. */
  .portal-workspace:has(.study-card) {
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 58px - env(safe-area-inset-bottom, 0px));
  }
  .portal-content:has(.study-card) {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
    padding-bottom: 16px;
  }
  .study-progress { flex: 0 0 auto; }
  .study-card { display: flex; flex: 1; flex-direction: column; min-height: 0; }
  .study-card-front, .study-card-back { flex: 1; min-height: 0; overflow-y: auto; }
  .review-actions { background: #fff; bottom: 0; position: sticky; }
  .reveal-button kbd, .review-actions kbd { display: none; }
  .study-details dl { gap: 12px; grid-template-columns: 1fr; }
  .study-conjugation { grid-template-columns: 1fr; }
  .study-conjugation article + article { border-left: 0; border-top: 1px solid var(--portal-line); }
  .config-grid { grid-template-columns: 1fr; }
  .segmented-options { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .segmented-options label + label span { border-left: 1px solid var(--portal-line); }
  .study-configurator footer { align-items: stretch; display: grid; gap: 16px; }
  .summary-results { grid-template-columns: 1fr; }
  .summary-results div + div { border-left: 0; border-top: 1px solid var(--portal-line); }
  .admin-filters { grid-template-columns: 1fr; }
  .admin-heading > .button { display: inline-block; margin-top: 12px; position: static; }
  .admin-heading-actions { align-items: start; display: flex; flex-direction: column; margin-top: 14px; position: static; }
  .package-preview dl, .package-summary dl { grid-template-columns: 1fr; }
  .editor-grid.two, .editor-grid.three, .editor-sidebar { grid-template-columns: 1fr; }
  .responsive-table { overflow-x: auto; }
  .candidate-row { grid-template-columns: 1fr; }
  .candidate-rank { padding-top: 0; }
  .candidate-actions { align-items: stretch; flex-direction: row; margin-top: 10px; }
  .candidate-actions form { flex: 1; }
  .candidate-approve, .candidate-reject { width: 100%; }
  .portal-page-heading, .portal-page-heading .section-header { align-items: start; display: grid; gap: 14px; }
  .library-filters .controls { grid-template-columns: 1fr; }
  .library-filters .lexeme-filter-grid label, .library-filters .lexeme-filter-grid button { flex-basis: 100%; }
  .lexeme-row { grid-template-columns: 36px minmax(0,1fr) 16px; }
  .lexeme-meta { display: none; }
  .detail-cta { justify-content: stretch; }
  .detail-cta .reveal-button { width: 100%; }
  .progress-metrics { grid-template-columns: repeat(2,1fr); }
  .progress-metrics article:nth-child(3) { border-left: 0; border-top: 1px solid var(--portal-line); }
  .progress-metrics article:nth-child(4) { border-top: 1px solid var(--portal-line); }
}

@media (max-width: 430px) {
  .portal-brand strong {
    font-size: 0.92rem;
  }

  .public-header { padding: 11px 14px; }
  .public-nav a { padding: 9px 8px; }
  .hero-copy h1 { font-size: 2.4rem; }
  .hero-actions { display: grid; }
}

/* /articles hero: the one place all three gender colours appear together,
   as a legend for the drill (content colour, never chrome). */
.article-hero {
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  border-radius: 10px;
  display: grid;
  gap: 10px;
  justify-items: center;
  margin-bottom: 18px;
  padding: 24px 20px;
  text-align: center;
}

.article-legend {
  display: flex;
  font-family: "Newsreader", Georgia, "Times New Roman", serif;
  font-size: clamp(1.6rem, 4vw, 2.2rem);
  gap: 22px;
}

.article-hero > p { color: var(--portal-muted); margin: 0; }

.article-hero button {
  background: var(--portal-green);
  border: 0;
  border-radius: 8px;
  color: #fff;
  font-weight: 700;
  padding: 12px 28px;
}

.article-hero button[disabled] { background: var(--portal-line); color: var(--portal-muted); }

/* A deck whose words haven't been met yet can't produce a session -- say so
   rather than starting an empty one. */
.unit-row-actions button[disabled],
.article-hero button[disabled] {
  background: var(--portal-line);
  border-color: var(--portal-line);
  color: var(--portal-muted);
  cursor: not-allowed;
}

.article-hero small { color: var(--portal-muted); max-width: 38ch; }

/* Typed production answers (R5). The umlaut row is the one thing worth taking
   from Memrise's typing card wholesale -- without it a learner on a Turkish
   keyboard cannot type the answer at all. */
.typing-form { display: grid; gap: 14px; justify-items: center; margin-top: 8px; width: min(100%, 420px); }

.typing-input {
  border: 2px solid var(--portal-line);
  border-radius: 10px;
  font-family: "Newsreader", Georgia, "Times New Roman", serif;
  font-size: 1.5rem;
  padding: 14px 16px;
  text-align: center;
  width: 100%;
}

.typing-input:focus { border-color: var(--portal-green); outline: none; }

/* gap/min-width trimmed from 8px/44px so all 7 keys (Ä ä Ö ö Ü ü ß) fit one
   row at 390px (umlaut-row's real inner width there is 310px, once the
   card's own padding and .portal-content's 16px side padding are both
   counted). 38px still reads as a deliberate touch target, just not the
   44px ideal. Row stays centred, so it looks intentional at wider widths too. */
.umlaut-row { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }

.umlaut-row button {
  background: var(--portal-surface);
  border: 1px solid var(--portal-line);
  color: var(--portal-text);
  border-radius: 8px;
  font-family: "Newsreader", Georgia, "Times New Roman", serif;
  font-size: 1.05rem;
  min-width: 38px;
  padding: 9px 0;
}

.umlaut-row button:hover { border-color: var(--portal-green); }

.verdict { border-radius: 10px; margin-bottom: 18px; padding: 14px 16px; text-align: center; }
.verdict strong { display: block; font-size: 0.98rem; }
.verdict small { color: var(--portal-muted); display: block; font-size: 0.78rem; margin-top: 8px; }
.verdict-answers { align-items: center; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 8px 0 0; }
.verdict-typed { font-size: 1.15rem; }
.verdict-expected { font-size: 1.35rem; font-weight: 700; }
.verdict-arrow { color: var(--portal-muted); }

.verdict-exact, .verdict-capitals { background: var(--portal-green-soft); }
.verdict-exact strong, .verdict-capitals strong { color: var(--portal-green-dark); }
.verdict-almost { background: #fdf1e3; }
.verdict-almost strong { color: var(--rating-hard); }
.verdict-wrong { background: #fae8ed; }
.verdict-wrong strong { color: var(--rating-again); }
.verdict-almost .verdict-typed, .verdict-wrong .verdict-typed { text-decoration: line-through; }
