/* Part of Survival Language — see index.html for load order.
   All colors live in tokens.css; this and the other files below only use
   var(--...) references, never raw hex, so a purchased theme (js/store.js
   applyThemeSkin) or dark mode recolors everything without touching CSS. */

  /* ---- Lesson overlay (unchanged mechanics) ---- */
  .lesson{ position:fixed; inset:0; background:var(--bg); z-index:100; display:flex; flex-direction:column; }
  .lesson-top{ display:flex; align-items:center; gap:var(--space-3); padding:var(--space-4) var(--space-6); flex:none; }
  .icon-btn{ background:none; border:none; color:var(--ink-faint); padding:var(--space-2); border-radius:var(--radius-sm); flex:none; }
  .icon-btn:hover{ color:var(--ink); background:var(--surface-2); }
  .icon-btn svg{ width:20px; height:20px; display:block; }
  .settings-icon-img{ width:20px; height:20px; border-radius:50%; object-fit:cover; display:block; }
  /* Sofia (17) asked for "chunky segments" rather than thin lines — these were
     already gapped, rounded, bordered blocks rather than hairlines, just a
     touch thinner; bumped up a couple px for more presence. */
  .segments{ flex:1; display:flex; gap:5px; }
  .segment{ flex:1; height:11px; border-radius:6px; background:var(--surface-2); border:1.5px solid var(--border); overflow:hidden; }
  .segment > i{ display:block; height:100%; width:0%; background:var(--success); transition:width .25s ease; }
  .segment.wrong > i{ background:var(--error); width:100%; }
  .segment.right > i{ width:100%; }
  .hearts{ display:flex; gap:4px; flex:none; }
  .hearts svg{ width:19px; height:19px; }

  /* ---- Energy (battery) pill — topbar stat + lesson header ----
     One rounded, tinted "block" (icon + charge count + refill countdown together),
     the way the reference game groups its lives count with the refill timer, rather
     than three loose bits of text. font-size is intentionally NOT set here: it must
     inherit from .stat-energy/.stat (shell.css) so the charge count always matches
     the crystal and streak counts next to it, at every breakpoint — hardcoding it
     here was exactly what let it drift out of sync with them before. */
  .energy-pill{
    display:flex; align-items:center; gap:5px; color:var(--energy); font-weight:700; flex:none;
    background:var(--energy-soft); border-radius:999px; padding:3px 10px 3px 6px;
  }
  .energy-pill.low{ color:var(--energy-empty); background:color-mix(in srgb, var(--energy-empty) 16%, var(--surface)); }
  .energy-battery{ width:18px; height:18px; display:flex; flex:none; } /* square: matches the 24x24 Boxicons viewBox, no letterboxing */
  .energy-battery svg{ width:100%; height:100%; display:block; }
  /* Inside the lesson header there's no .stat sibling to match sizes with (no crystal/streak
     counters up there) — .lesson-top isn't a text context at all, so without this the pill
     would just inherit the browser's 16px body default. Pin it to what it always looked like. */
  .lesson-top .energy-pill{ font-size:14px; }
  /* Topbar-only: matches the streak/xp de-emphasis in shell.css (.stat-num) — same
     game-meta info, so it should recede the same amount. The lesson-header pill is
     untouched: there it's the one live stat on screen, not competing with two others. */
  .stat-energy .energy-pill{ font-weight:600; }
  /* The countdown reads as a caption under the main count, not a fourth stat of its
     own — smaller and quieter is deliberate, same relationship as the reference. */
  .energy-timer{ font-size:.72em; font-weight:600; color:var(--ink-faint); }

  /* min-height:0 lets this flex child actually shrink instead of overflowing its fixed-height
     parent; overflow-y:auto means if content is ever taller than the screen (long end-screen
     text, larger system font size, a short viewport) it scrolls instead of pushing buttons like
     "Продолжить" off-screen and unreachable. */
  .lesson-body{ flex:1; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; display:flex; flex-direction:column; justify-content:center; max-width:560px; margin:0 auto; width:100%; padding:var(--space-3) var(--space-6) var(--space-4); }
  /* Motion system, pattern 1/4 ("card appears"): every teach card, quiz card, and
     end/fail screen is a fresh innerHTML swap into #lesson-body, so a plain CSS
     animation on its direct children replays automatically on every render — no
     JS hook needed. Same rule covers "task completion" too (.end-screen is just
     another direct child). Respects reduced-motion below. */
  @keyframes cardIn{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:translateY(0); } }
  .lesson-body > *{ animation:cardIn var(--dur-base) var(--ease-standard) both; }
  .q-kicker{ font-size:13px; font-weight:700; color:var(--ink-faint); text-transform:uppercase; letter-spacing:.06em; margin-bottom:var(--space-4); }
  /* ---- Typographic hierarchy: ქართული > transliteration > translation > explanation ----
     The Georgian word is the hero of every card — biggest, boldest, most weight in
     the room — with each tier under it stepping down in both size and color/weight
     so the eye lands on .ka first without having to think about it. See DEPLOY.md's
     design-polish-pass note for the full reasoning. */
  .q-prompt.ka{ font-size:44px; font-weight:700; line-height:1.15; letter-spacing:-.01em; }
  .q-prompt.ru{ font-size:25px; font-weight:800; font-family:'Unbounded',sans-serif; line-height:1.3; text-wrap:balance; }
  /* Before the alphabet is finished, dualHtml() leads with the transcription instead of the
     Georgian line — same slot, so it needs its own size (a touch smaller than .ka, still a
     clear "this is the answer" prompt, in the Latin/Cyrillic-friendly Unbounded face). */
  .q-prompt.dual{ font-size:28px; font-weight:800; font-family:'Unbounded',sans-serif; line-height:1.3; text-wrap:balance; }
  /* Tier 2 (transliteration) — deliberately smaller and lighter than before: it's a
     reading aid, not a second headline next to .ka. */
  .q-translit{ margin-top:var(--space-4); font-size:14px; font-style:italic; font-weight:500; color:var(--ink-soft); line-height:1.4; }
  /* Facts quiz ("which region is this about?"): a full sentence, not a short word/letter —
     normal weight, readable paragraph sizing instead of the big word-prompt treatment. */
  .q-prompt.fact-prompt{ font-size:19px; font-weight:600; line-height:1.4; text-wrap:balance; }
  /* Alphabet unit: the letter being introduced gets shown much bigger than a regular word,
     plus a lighter outlined "twin" of the same glyph underneath to trace with a finger —
     a generic memorization aid, not a claim about the "correct" stroke order (there isn't
     one well-documented and verifiable source for Mkhedruli stroke order to draw from). */
  .q-prompt.ka.letter-big{ font-size:104px; line-height:1; }
  /* Multiplication trainer: a plain numeric equation, no script involved — same
     bold Unbounded treatment as .dual (the transcription-leads case) since both
     are "read this as one short phrase" prompts, just with digits instead of
     letters. Shared by the teach cards (renderTeach's multiplication branch)
     and the quiz prompt ("7 × 8 = ?"). */
  .q-prompt.equation{ font-size:32px; font-weight:800; font-family:'Unbounded',sans-serif; line-height:1.3; }
  .letter-trace-wrap{ margin-top:var(--space-4); }
  .letter-trace-label{ font-size:13px; color:var(--ink-faint); margin-bottom:var(--space-2); }
  .letter-trace{
    font-family:'Noto Sans Georgian','Manrope',sans-serif; font-size:104px; font-weight:600; line-height:1;
    color:transparent; -webkit-text-stroke:1.5px var(--border); text-stroke:1.5px var(--border);
    user-select:none;
  }
  /* Tier 3 (translation) — used to be a loud filled-and-bordered box that visually
     out-weighed the Georgian word above it; a colored rule plus quiet text reads as
     "here's the answer" without competing with .ka for attention. The rule keeps a
     one-glance "this is the meaning slot" cue even with no box around it. */
  .teach-meaning{
    margin-top:var(--space-6); padding-left:var(--space-3); border-left:3px solid var(--success);
    font-size:16px; font-weight:600; color:var(--ink); line-height:1.4;
  }
  /* Tier 4 (explanation) — the ejective-sound aside appended to .teach-meaning
     (renderTeach, lesson.js) is a footnote to the translation, not part of it, so
     it gets its own lighter/smaller treatment rather than inheriting the meaning's
     weight and color. */
  .teach-note{ display:block; margin-top:3px; font-size:12.5px; font-weight:500; font-style:italic; color:var(--ink-faint); }
  /* Multiplication trainer: the "trick" note for a table, shown once on its first
     teach card (see renderTeach's multiplication branch). Gold rather than the
     green .teach-meaning rule — a different kind of callout (a memorization tip,
     not "this is what the word means") — so the two read as visually distinct.
     Kept as a real box (unlike .teach-meaning) since it's genuinely a one-off
     highlighted aside, not something shown on every single card. */
  .trick-note{
    display:flex; align-items:flex-start; gap:var(--space-3); margin-bottom:var(--space-6); padding:var(--space-3) var(--space-4);
    background:var(--gold-soft); border:1.5px solid var(--gold); border-radius:var(--radius-md);
    font-size:15px; line-height:1.45; color:var(--ink); text-align:left;
  }
  .trick-note-icon{ flex:none; width:22px; height:22px; color:var(--gold); margin-top:1px; }
  .trick-note-icon svg{ width:100%; height:100%; display:block; }
  .trick-note b{ color:var(--gold-text); }
  /* Grammar rule on a course teach card (renderTeach, lesson.js — words with a
     `rule` in course.json). Same box as the multiplication trick, but purple
     (--category-a = "learning") instead of gold, so a rule doesn't read as a
     reward/tip. */
  .grammar-note{ background:var(--purple-100); border-color:var(--category-a); }
  .grammar-note .trick-note-icon{ color:var(--category-a); }
  .grammar-note b{ color:var(--ink); }
  .teach-actions{ margin-top:var(--space-8); }
  .teach-actions .btn{ width:100%; }

  .options{ display:flex; flex-direction:column; gap:var(--space-3); margin-top:var(--space-8); }
  .option{
    text-align:left; background:var(--surface); border:2px solid var(--border); border-radius:var(--radius-md); padding:var(--space-4);
    font-size:16.5px; font-weight:600; color:var(--ink); box-shadow:0 3px 0 0 var(--border);
    transition:border-color .12s ease, background .12s ease, transform .06s ease;
    /* A question's options are plain Latin letters (sound2ka answers, ka2sound quizzes)
       on one screen and Georgian glyphs (.ka, below) on another — two different fonts,
       each with its own "normal" line-height, so the same padding produced visibly
       different button heights depending only on which quiz direction you'd landed on.
       Centering a fixed min-height (rather than trusting each font's own line box)
       makes every option row the same height regardless of script. */
    display:flex; align-items:center; min-height:60px;
  }
  .option .ka{ font-size:18px; }
  /* Sofia (18): resting/hover/selected/correct/wrong should each look distinct —
     hover used to change only the border, now a faint tint too, so a resting
     card, a hovered one and a resolved (correct/wrong) one are each visibly
     their own state rather than "border color changed slightly". Uses --accent
     (brand pink), not --accent-2 (coral) as the old hover border did — coral
     sits close enough to --error's red that a tinted background in that hue
     read a little too much like the wrong-answer state at a glance. This app
     answers on tap (no separate "select, then confirm" step — pick-correct/
     pick-wrong fire immediately), so there's no separate "selected" state to
     style beyond hover/resolved. */
  .option:hover:not(:disabled){ border-color:var(--accent); background:color-mix(in srgb, var(--accent) 6%, var(--surface)); }
  .option:active:not(:disabled){ transform:translateY(2px); box-shadow:0 1px 0 0 var(--border); }
  /* Motion system, patterns 2 & 3/4 ("correct"/"incorrect answer"): a small confident
     pop for right, the pre-existing shake for wrong — both under 350ms so they read
     as a reaction to the tap, not a delay before the feedback bar. */
  .option.pick-correct{ background:var(--success-soft); border-color:var(--success); color:var(--success); box-shadow:0 3px 0 0 var(--success); animation:pickPop .28s var(--ease-pop); }
  .option.pick-wrong{ background:var(--error-soft); border-color:var(--error); color:var(--error); box-shadow:0 3px 0 0 var(--error); animation:shake .32s ease; }
  .option:disabled{ opacity:.65; }
  .option:disabled.pick-correct, .option:disabled.pick-wrong{ opacity:1; }
  @keyframes shake{ 20%{transform:translateX(-6px);} 40%{transform:translateX(5px);} 60%{transform:translateX(-4px);} 80%{transform:translateX(3px);} 100%{transform:translateX(0);} }
  @keyframes pickPop{ 0%{ transform:scale(1); } 45%{ transform:scale(1.025); } 100%{ transform:scale(1); } }
  .q-skip-row{ display:flex; justify-content:center; margin-top:var(--space-4); }
  .q-skip-btn{ display:flex; align-items:center; gap:var(--space-1); font-size:13px; }
  .q-skip-btn:disabled{ opacity:.45; }
  .q-skip-cost{ display:inline-flex; align-items:center; gap:2px; color:var(--gold-text); font-weight:800; }
  .q-skip-cost svg{ width:12px; height:12px; }

  .feedback{
    flex:none; width:100%; padding:var(--space-4) 0 calc(var(--space-6) + env(safe-area-inset-bottom));
    transform:translateY(110%); transition:transform .22s ease;
  }
  .feedback.show{ transform:translateY(0); }
  /* Solid, saturated fill instead of a pale wash (Sofia, п.21) — reads as a clear
     game-style banner rather than a tinted strip. --success/--error paired with
     --success-ink/--error-ink is already the app's contrast-checked "text on top
     of this solid color" pairing (same pairing .btn-ok/.btn-bad use below), so the
     banner text needs no separate tuning. */
  .feedback.ok{ background:var(--success); color:var(--success-ink); }
  .feedback.bad{ background:var(--error); color:var(--error-ink); }
  .feedback-inner{
    max-width:560px; margin:0 auto; width:100%; box-sizing:border-box; padding:0 var(--space-6);
    display:flex; align-items:center; gap:var(--space-3);
  }
  /* Small filled circle for ✓/✗ (Sofia asked for the icon explicitly, п.21) —
     background is a tint of currentColor so it auto-adapts between .ok/.bad
     without a second pair of color rules. */
  .feedback-icon{
    flex:none; width:34px; height:34px; border-radius:50%; display:flex; align-items:center; justify-content:center;
    background:color-mix(in srgb, currentColor 18%, transparent);
  }
  .feedback-icon svg{ width:19px; height:19px; }
  .feedback-body{ flex:1; min-width:0; }
  .feedback-text{ font-weight:800; font-size:16px; }
  .feedback-text small{ display:block; font-weight:600; opacity:.85; margin-top:2px; font-size:13px; }
  .btn{ border:none; border-radius:var(--radius-md); padding:var(--space-3) var(--space-6); font-weight:700; font-size:15px; box-shadow:0 4px 0 0 var(--accent-hover); flex:none; }
  .btn:active{ transform:translateY(3px); box-shadow:none; }
  .btn:disabled{ opacity:.45; box-shadow:none; cursor:not-allowed; }
  .btn:disabled:active{ transform:none; }
  .btn-primary{ background:var(--accent); color:var(--accent-ink); }
  /* Now that the bar itself is a solid --success/--error fill, the button needs to
     invert (light pill on the green bar, not another green-on-green shape) to stay
     visible — --success-ink/--error-ink already read as near-white on light theme
     surfaces and near-black in dark mode, exactly the inversion this needs. */
  .btn-ok{ background:var(--success-ink); color:var(--success); box-shadow:0 4px 0 0 color-mix(in srgb, var(--success-ink) 75%, black); }
  .btn-bad{ background:var(--error-ink); color:var(--error); box-shadow:0 4px 0 0 color-mix(in srgb, var(--error-ink) 75%, black); }
  /* Secondary actions ("Повторить", "Пропустить"...) stay visibly lighter than
     .btn-primary — smaller, less bold, no fill — so there's never a question of
     which button is the intended next step on a screen that shows both. */
  .btn-ghost{ background:none; box-shadow:none; color:var(--ink-soft); font-weight:600; font-size:14px; padding:var(--space-2) var(--space-4); }

  .end-screen{ flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:var(--space-6); gap:var(--space-2); }
  /* .medal / .medal.muted stay as-is — still used by the "energy ran out" fail
     screen (renderFail), where the icon genuinely is the main message. On the
     *success* end screen the medal is no longer the hero (Sofia, п.22, see
     .end-hero below) — the earned reward is. */
  .medal{ width:120px; height:120px; border-radius:50%; display:flex; align-items:center; justify-content:center; margin-bottom:var(--space-6); background:var(--gold-soft); border:3px solid var(--gold); }
  .medal svg{ width:56px; height:56px; color:var(--gold); }
  .medal.muted{ background:var(--surface-2); border-color:var(--border); }
  .medal.muted svg{ color:var(--ink-faint); }
  /* ---- Success end screen: the earned reward is the hero, the medal is a small
     decorative badge riding on it — not the other way around, as it was before. ---- */
  .end-hero{ position:relative; display:flex; flex-direction:column; align-items:center; margin-bottom:var(--space-4); }
  .end-hero-medal{
    /* z-index:1 pins the badge above .end-hero-num explicitly — .end-hero-num's
       xpPop animation leaves a lingering transform (fill-mode:both), and any
       non-none transform creates its own stacking context, which was letting
       the number's own layer paint over this badge despite it coming later in
       painting order (Sofia: "ачивка находится под цифрой"). Border lightened
       to her requested light-yellow — var(--gold) alone renders as dark
       amber/brown in light mode and was reading as murky, not "outlined". */
    position:absolute; top:-10px; right:-6px; width:40px; height:40px; border-radius:50%;
    display:flex; align-items:center; justify-content:center; transform:rotate(14deg);
    background:var(--gold-soft); border:2.5px solid #F5D76E; box-shadow:var(--shadow-soft);
    z-index:1;
  }
  .end-hero-medal svg{ width:20px; height:20px; color:var(--gold); }
  .end-hero-num{
    position:relative; z-index:0;
    font-family:'Unbounded',sans-serif; font-variant-numeric:tabular-nums; font-weight:800;
    font-size:64px; line-height:1; color:var(--accent); animation:xpPop .3s var(--ease-pop) 120ms both;
  }
  .end-hero-label{ font-size:13px; font-weight:800; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-faint); margin-top:var(--space-1); }
  .end-screen h2{ font-size:22px; margin-bottom:var(--space-2); }
  .end-screen p{ color:var(--ink-soft); font-size:15.5px; max-width:26em; line-height:1.5; }
  .end-stats{ display:flex; gap:var(--space-6); margin:var(--space-4) 0 var(--space-8); }
  /* Motion system, pattern 4/4 ("XP gained"): the reward number pops in a beat
     after the rest of the end screen (cardIn on .end-screen already covers the
     card as a whole) — the little overshoot is what makes the reward feel like
     it landed, not just appeared. Reused on .end-hero-num above. */
  .end-stat b{ display:block; font-family:'Unbounded',sans-serif; font-size:22px; }
  @keyframes xpPop{ 0%{ transform:scale(.7); } 100%{ transform:scale(1); } }
  .end-stat span{ font-size:12.5px; color:var(--ink-faint); text-transform:uppercase; letter-spacing:.05em; }
  .boost-tag{ display:inline-block; background:var(--gold-soft); color:var(--gold-text); font-size:14px; font-weight:800; border-radius:var(--radius-sm); padding:1px 6px; vertical-align:middle; }
  .end-actions{ display:flex; flex-direction:column; gap:var(--space-3); width:100%; max-width:280px; }
  .end-actions .btn{ width:100%; }

  @media (max-width:420px){
    .hero h1{ font-size:26px; }
    .q-prompt.ka{ font-size:34px; }
    .q-prompt.ka.letter-big{ font-size:78px; }
    .letter-trace{ font-size:78px; }
    .q-prompt.ru{ font-size:21px; }
    .q-prompt.equation{ font-size:26px; }
    .day-grid{ grid-template-columns:repeat(6,1fr); }
    .topbar-inner{ padding:var(--space-3); gap:6px; }
    .who-name{ max-width:108px; }
    .who-chip{ gap:6px; }
    .stats{ gap:var(--space-2); }
    .stat{ font-size:12.5px; }
    .stat svg{ width:15px; height:15px; }
    .course-flag{ width:20px; height:14px; }
  }
