/* ============================================================
   Impara l'Italiano — the visual system.

   Built on the "Impara Italiano" design system that lives in
   assets/Design system Impara Italiano/: verde as the primary, rosso as
   the single accent, warm paper neutrals in light and a cool ink base in
   dark. The palette itself, with the hex each step came from, is in the
   PALETTE block below; this file holds the components that spend it.
   ============================================================ */

/* Atrybut `hidden` ma naprawdę chować.
   Reguła przeglądarki to zwykłe `[hidden]{display:none}`, więc każdy
   selektor klasowy z własnym `display` bije ją specyficznością i atrybut
   przestaje cokolwiek robić — po cichu, bo w HTML-u wygląda poprawnie.
   Trafiło się już dwa razy: zasłona szuflady zostawała na ekranie i
   łapała kliknięcia, a przycisk „dalej" w treningu pokazywał się przed
   odpowiedzią. Jedna reguła zamiast poprawki przy każdym kolejnym. */
[hidden]{display:none !important;}

/* ============================================================
   Typefaces — hosted here, not fetched from Google.

   The course must open from file:// and must work with no network, so the
   service worker precaches these files and index.html asks no foreign
   domain for anything. `font-src 'self'` in the CSP makes that a rule the
   browser enforces, not a habit: a @import of fonts.googleapis.com added
   later would simply be blocked, and the page would fall back in silence.

   Three families, the three registers of the design system:
   Spectral (serif) for headings, Manrope (sans) for body and interface,
   JetBrains Mono for CEFR levels — the "official classification" voice.

   Two subsets per family, because `latin` carries no Polish diacritics:
   ą, ę, ł, ż live in `latin-ext`. The other subsets (Cyrillic, Greek,
   Vietnamese) are not taken: the course speaks five languages and all of
   them are Latin-script. The mono face is the exception and ships `latin`
   only — it renders CEFR codes and verb-group labels, which are ASCII;
   anything outside that range falls through to the next font in the stack,
   per glyph, which is the behaviour we want there.

   Manrope and JetBrains Mono are variable, so one file covers the whole
   weight axis. Spectral is not, and it needs two weights: 600 for headings
   and 700 for the large display numbers. Faux-bold on a serif is visible,
   so the second file is cheaper than the artefact.

   Licence: SIL Open Font License 1.1 for all three (OFL-*.txt alongside).
   ============================================================ */
@font-face{
  font-family:'Spectral';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url(../fonts/spectral-600-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:'Spectral';
  font-style:normal;
  font-weight:600;
  font-display:swap;
  src:url(../fonts/spectral-600-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:'Spectral';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url(../fonts/spectral-700-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:'Spectral';
  font-style:normal;
  font-weight:700;
  font-display:swap;
  src:url(../fonts/spectral-700-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:'Manrope';
  font-style:normal;
  font-weight:400 800;
  font-display:swap;
  src:url(../fonts/manrope-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:'Manrope';
  font-style:normal;
  font-weight:400 800;
  font-display:swap;
  src:url(../fonts/manrope-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:'JetBrains Mono';
  font-style:normal;
  font-weight:500 700;
  font-display:swap;
  src:url(../fonts/jetbrainsmono-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;
}

/* ============================================================
   PALETTE — the "Impara Italiano" design system, in OKLCH.

   The system is authored in sRGB hex (assets/Design system Impara
   Italiano/tokens/colors.css); the steps below are the same colours
   converted, because the rest of this file measures and mixes in OKLCH
   and a file in two colour spaces lies about lightness in half its rules.
   The hex each step came from is written next to it, so a drift against
   the source is a diff and not an opinion.

   Two brand hues with a division of labour, and it is the division that
   matters more than the hues: VERDE is the primary — progress, lessons
   done, every ordinary action. ROSSO is the single energetic accent —
   streaks, milestones, the citizenship track. Red is NOT the error colour:
   errors are terracotta, so that a wrong answer never borrows the mark.

   Neutrals are warm paper, not cold grey (an exercise book, not a
   dashboard). Dark mode drops onto a cool ink base rather than a dark
   green, so both brand hues stay recognisable on top of it.
   ============================================================ */
:root{
  /* --- superfici: carta --- */
  --paper:        oklch(0.980 0.007 81);   /* paper-50  #FBF8F3 */
  --paper-2:      oklch(0.987 0.004 56);   /* paper-0   #FDFAF8 */
  --paper-3:      oklch(0.945 0.013 82);   /* paper-100 #F1ECE3 */
  --paper-sunk:   oklch(0.903 0.015 81);   /* paper-200 #E4DED4 */

  /* --- inchiostro --- */
  /* Three steps, three thresholds, all measured against paper and card:
     --ink 16.7:1, --ink-soft 7.6:1, --ink-faint 5.0:1. The faint step is
     also the border of a control that carries no fill (.tab), so it has to
     clear 3:1 as a shape and 4.5:1 as text — one step doing both jobs is
     why it is not simply the lightest neutral that still reads. */
  --ink:          oklch(0.211 0.007 67);   /* paper-950 #1B1815 */
  --ink-soft:     oklch(0.433 0.014 59);   /* paper-700 #574F49 */
  --ink-faint:    oklch(0.529 0.016 67);   /* paper-600 #726A62 */

  /* --- verde: il primario --- */
  --salvia:       oklch(0.951 0.023 169);  /* green-100 #E1F4EC */
  --salvia-mid:   oklch(0.656 0.119 168);  /* green-500 #2FA883 */
  --salvia-deep:  oklch(0.515 0.102 170);  /* green-700 #007A5E — mark */

  /* --- rosso: l'unico accento --- */
  --rosa:         oklch(0.945 0.022 7);    /* red-100 #FBE7EA */
  --rosa-deep:    oklch(0.520 0.172 18);   /* red-700 #B72E42 — mark */

  /* --- accenti di servizio --- */
  /* Gold does not flip with the theme, and that is deliberate: it is a
     fill that always carries dark ink (badge, highlight, test marker), so
     a pale step plus a fixed --on-oro passes in both themes and removes
     the hardcoded dark literal this file used to repeat at every use. */
  --oro:          oklch(0.946 0.037 86);   /* gold-100 #F8ECD2 */
  /* One step past the end of the system's gold ramp, and it is here because
     the ramp's own pairing does not hold: gold-700 on gold-100 — the design
     system's warning badge — measures 4.30:1, under the 4.5 that WCAG asks
     of small text, and the contrast gate reads it on the "new word" chip in
     the five-minute session. The gate is right and the ramp is short, so the
     step is extended rather than the threshold lowered. 5.6:1 on gold-100. */
  --oro-deep:     oklch(0.490 0.100 74);   /* gold-800, derived — 5.6:1 */
  /* Teal is the system's "info" hue; it replaces the lavender the earlier
     palette used, which belonged to no part of the mark. */
  --lavanda:      oklch(0.932 0.018 214);  /* teal-100 #DCECF0 */
  --lavanda-deep: oklch(0.446 0.061 221);  /* teal-700 #285C6C */

  /* --- semantica: distinta dal marchio --- */
  /* Success reuses the green; error is TERRACOTTA, not the mark red. A
     wrong answer and the brand must not be the same colour, or the student
     learns to read the identity as a warning. */
  --ok:           oklch(0.422 0.086 165);  /* green-800 #075C42 */
  --ok-bg:        oklch(0.951 0.023 169);  /* green-100 #E1F4EC */
  --ko:           oklch(0.456 0.114 39);   /* terracotta-700 #8A3C21 */
  --ko-bg:        oklch(0.922 0.026 52);   /* terracotta-100 #F4E1D6 */

  /* --- linee --- */
  --line:         oklch(0.903 0.015 81);   /* paper-200 #E4DED4 */
  --line-strong:  oklch(0.821 0.018 76);   /* paper-300 #CBC3B8 */
  --line-mint:    oklch(0.903 0.045 169);  /* green-200 #C3E9DA */
  /* The outline of a control, not a decorative rule: a ghost button has the
     paper as its fill, so this edge is the only sign that it is a button at
     all, and WCAG 1.4.11 asks 3:1 of such a sign. --line-strong gives 1.6:1
     and is tuned for separators that should barely show. */
  --line-control: oklch(0.622 0.017 67);   /* paper-500 #8E857C — 3.4:1 */

  /* --- testo sopra un fondo pieno --- */
  /* One pair per fill, flipped in dark mode where the fills themselves get
     lighter. Before these existed, every filled control repeated a literal
     and every dark-theme override had to repeat it back. */
  --on-primary:   oklch(0.987 0.004 56);   /* paper-0 on green-700 — 5.1:1 */
  --on-accent:    oklch(0.987 0.004 56);   /* paper-0 on red-700   — 5.8:1 */
  --on-oro:       oklch(0.211 0.007 67);   /* paper-950 on gold-100 */
  /* The halo around a focused field, the current lesson and the microphone.
     It has to be its own token rather than a literal of the fill: in the dark
     theme --salvia-deep and --rosa-deep move several steps lighter, and a glow
     frozen at the light value stops belonging to the thing it surrounds. */
  --glow-primary: 0.515 0.102 170;
  --glow-accent:  0.520 0.172 18;

  /* --- fondi tenui e stati --- */
  /* The rail is a dark brand panel in BOTH themes, so the ink on it does
     not flip: --on-rail is a constant, unlike --on-primary. */
  --on-rail:      oklch(0.987 0.004 56);
  --on-tonal:     oklch(0.422 0.086 165);  /* green-800 on a green-100 fill */
  --oro-soft:     oklch(0.946 0.037 86);   /* gold-100 — callout, chip */
  --btn-primary-hover: oklch(0.422 0.086 165);  /* green-800 — 7.7:1 */
  --btn-tonal-hover:   oklch(0.903 0.045 169);  /* green-200 */

  /* --- il motivo di marchio: una riga tricolore, usata una volta sola --- */
  --tri-green:    oklch(0.515 0.102 170);
  --tri-white:    oklch(0.987 0.004 56);
  --tri-red:      oklch(0.520 0.172 18);

  /* --- ombre: a tono caldo, mai nero puro --- */
  --shadow-s: 0 1px 2px oklch(0.211 0.007 67 / 0.08);
  --shadow-m: 0 8px 20px oklch(0.211 0.007 67 / 0.10), 0 2px 6px oklch(0.211 0.007 67 / 0.06);
  --shadow-l: 0 16px 36px oklch(0.211 0.007 67 / 0.14), 0 4px 10px oklch(0.211 0.007 67 / 0.08);

  /* --- tipografia --- */
  --display: 'Spectral', 'Iowan Old Style', Georgia, serif;
  --sans: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  /* --- metriche --- */
  /* Measured radii, 8/12/18/24 on a 4px grid. The pill (999px) is reserved
     for badges, tags and the tricolor rail — not put on every card. */
  --rail-w: 272px;
  --r-s: 8px;
  --r-m: 12px;
  --r-l: 18px;
  --r-xl: 24px;
  --r-pill: 999px;
}

/* ============================================================
   DARK — a cool ink base, not a dark green. Only the aliases remap; the
   ramp each one points at is the same ramp as above, one or two steps
   lighter where the surface got darker.
   ============================================================ */
:root[data-theme="dark"]{
  --paper:        oklch(0.175 0.009 241);  /* ink-950 #0D1114 */
  --paper-2:      oklch(0.201 0.011 242);  /* ink-900 #12171B */
  --paper-3:      oklch(0.244 0.013 243);  /* ink-800 #1B2126 */
  --paper-sunk:   oklch(0.296 0.016 241);  /* ink-700 #262E34 */

  --ink:          oklch(0.980 0.007 81);   /* paper-50  #FBF8F3 — 17.9:1 */
  --ink-soft:     oklch(0.821 0.018 76);   /* paper-300 #CBC3B8 — 10.3:1 */
  --ink-faint:    oklch(0.720 0.019 73);   /* paper-400 #ACA398 —  7.3:1 */

  --salvia:       oklch(0.320 0.055 168);  /* wash, not a ramp step */
  --salvia-mid:   oklch(0.588 0.115 168);  /* green-600 #14926F */
  --salvia-deep:  oklch(0.739 0.105 168);  /* green-400 #5FC09E — 8.2:1 */

  --rosa:         oklch(0.320 0.060 17);   /* wash, not a ramp step */
  --rosa-deep:    oklch(0.736 0.103 11);   /* red-400 #E28E9A — 7.4:1 */

  /* --oro and --on-oro do not flip: see the note in the light block. */
  --oro-deep:     oklch(0.678 0.127 73);   /* gold-500 #C68A2E — 6.1:1 */
  --lavanda:      oklch(0.296 0.030 221);
  --lavanda-deep: oklch(0.760 0.060 221);

  --ok:           oklch(0.739 0.105 168);  /* green-400 */
  --ok-bg:        oklch(0.300 0.055 168);
  --ko:           oklch(0.740 0.085 40);   /* terracotta, lifted for dark */
  --ko-bg:        oklch(0.310 0.060 40);

  --line:         oklch(0.296 0.016 241);  /* ink-700 */
  --line-strong:  oklch(0.373 0.019 242);  /* ink-600 */
  --line-mint:    oklch(0.422 0.086 165);  /* green-800 */
  /* Same job as in the light theme, opposite direction: the outline goes
     lighter than the paper instead of darker. 3.4:1 against the card. */
  --line-control: oklch(0.529 0.016 67);   /* paper-600 #726A62 */

  /* The fills get lighter in the dark theme, so the ink on top goes dark. */
  --on-primary:   oklch(0.175 0.009 241);  /* ink-950 on green-400 — 8.6:1 */
  --on-accent:    oklch(0.175 0.009 241);  /* ink-950 on red-400   — 7.7:1 */
  --on-tonal:     oklch(0.980 0.007 81);   /* paper-50 on a green wash */
  --glow-primary: 0.739 0.105 168;
  --glow-accent:  0.736 0.103 11;
  --oro-soft:     oklch(0.300 0.055 74);
  --btn-primary-hover: oklch(0.824 0.077 168);  /* green-300 */
  --btn-tonal-hover:   oklch(0.380 0.065 168);

  --shadow-s: 0 1px 2px oklch(0 0 0 / 0.40);
  --shadow-m: 0 10px 24px oklch(0 0 0 / 0.50);
  --shadow-l: 0 20px 44px oklch(0 0 0 / 0.55);
}

*,*::before,*::after{box-sizing:border-box;}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;}
}

body{
  margin:0;
  font-family:var(--sans);
  font-size:16px;
  line-height:1.62;
  color:var(--ink);
  background:var(--paper);
  /* Two soft washes rather than a flat sheet of paper: green-200 at the top
     right, gold-100 at the bottom left. No red down here — the accent is
     spent on streaks and the citizenship track, not on wallpaper. */
  background-image:
    radial-gradient(circle at 92% -4%, oklch(0.903 0.045 169 / .55), transparent 46%),
    radial-gradient(circle at -6% 102%, oklch(0.946 0.037 86 / .70), transparent 44%);
  background-attachment:fixed;
  -webkit-font-smoothing:antialiased;
}

/* The washes are tuned for paper. On ink they would be two lamps, so the
   dark theme keeps the shape and drops both the lightness and the alpha. */
:root[data-theme="dark"] body{
  background-image:
    radial-gradient(circle at 92% -4%, oklch(0.422 0.086 165 / .38), transparent 46%),
    radial-gradient(circle at -6% 102%, oklch(0.363 0.116 17 / .26), transparent 44%);
}

h1,h2,h3,h4{font-family:var(--display);font-weight:600;line-height:1.22;margin:0;letter-spacing:-0.01em;}
p{margin:0 0 .8em;}
a{color:var(--salvia-deep);text-underline-offset:3px;}
button{font:inherit;color:inherit;}
:focus-visible{outline:3px solid var(--salvia-deep);outline-offset:3px;border-radius:6px;}

/* Schowany W PIONIE, nie w bok. Odsunięcie poziome jest niewidoczne tylko
   w jedną stronę: `left:-9999px` znika w LTR, a przy `dir="rtl"` wypada za
   krawędź i robi 9999px poziomego przewijania całej strony. Własność logiczna
   nic tu nie ratuje, bo bezpieczna strona zmienia się razem z kierunkiem;
   góra jest poza ekranem w obu. */
.skip-link{
  position:absolute;left:0;inset-inline-start:0;top:-9999px;z-index:999;
  background:var(--salvia-deep);color:var(--on-primary);padding:12px 20px;border-radius:0 0 var(--r-m) 0;font-weight:600;
}
.skip-link:focus{top:0;}

.visually-hidden{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* ══════════════════ SHELL ══════════════════ */
.shell{display:flex;min-height:100vh;}

/* ══════════════════ RAIL ══════════════════ */
.rail{
  width:var(--rail-w);flex:0 0 var(--rail-w);
  position:sticky;top:0;height:100vh;
  display:flex;flex-direction:column;
  /* fallback for browsers with no oklab interpolation */
  background: oklch(0.308 0.059 168);
  /* The brand panel: the deep end of the primary ramp, green-800 down to
     green-950. Every stop is dark enough for paper-white to hold 4.5:1 over
     the whole height — the lightest of them, green-800, measures 7.7:1, and
     the contrast gate reads the stops straight out of this declaration. */
  background:
    linear-gradient(172deg in oklab,
      oklch(0.422 0.086 165) 0%,
      oklch(0.308 0.059 168) 45%,
      oklch(0.231 0.040 172) 100%);
  color:var(--on-rail);
  z-index:40;
}
:root[data-theme="dark"] .rail{
  background: oklch(0.231 0.040 172);
  background:linear-gradient(172deg in oklab,
    oklch(0.308 0.059 168) 0%,
    oklch(0.231 0.040 172) 55%,
    oklch(0.201 0.011 242) 100%);
}

.rail__head{padding:26px 22px 16px;}
.rail__brand{
  font-family:var(--display);font-weight:600;font-size:1.34rem;
  margin:0 0 2px;display:flex;align-items:center;gap:9px;line-height:1.2;
}
/* The one brand flourish, and it appears exactly once: a thin tricolor
   rule under the course name. It also retires the flag emoji that stood
   before the title — the design system asks for no emoji in the interface,
   and the span is aria-hidden, so nothing is lost to a screen reader. */
.rail__flag{display:none;}
.rail__tag{margin:0;font-size:.78rem;opacity:.96;font-weight:500;letter-spacing:.01em;}
.rail__tag::after{
  content:"";display:block;width:56px;height:4px;margin-top:12px;
  border-radius:var(--r-pill);
  background:linear-gradient(90deg,
    var(--tri-green) 0 33.33%, var(--tri-white) 33.33% 66.66%, var(--tri-red) 66.66%);
}

/* wybór języka wyjaśnień: na przycisku flaga i endonim bieżącego języka,
   reszta w liście. 44 px celu dotykowego na przycisku i na każdej pozycji listy. */
.rail__lang{position:relative;margin-top:12px;}
.rail__lang-btn{
  min-height:44px;padding:0 10px;gap:7px;
  display:flex;align-items:center;justify-content:flex-start;
  background:oklch(0 0 0 / .16);border:1px solid oklch(1 0 0 / .30);
  border-radius:var(--r-m);font-size:1.15rem;line-height:1;cursor:pointer;color:inherit;
  transition:background .16s ease, border-color .16s ease;
}
.rail__lang-btn:hover{background:oklch(0 0 0 / .28);}
.rail__lang-name{font-size:.88rem;font-weight:600;line-height:1;}
.rail__lang-caret{font-size:.7rem;opacity:.8;}
/* Tło z palety, nie na sztywno: w ciemnym motywie jasne tło zostawało jasne,
   a dziedziczony `--ink` robił się prawie biały — nazwa języka znikałaby na
   nim tak, jak dotąd znikała strzałka. Tu przycisk otwarty jest z tego samego
   papieru co lista pod nim, więc oba motywy trzymają się same. */
.rail__lang-btn[aria-expanded="true"]{
  background:var(--paper);border-color:transparent;box-shadow:var(--shadow-s);
}
.rail__lang-btn[aria-expanded="true"] .rail__lang-name,
.rail__lang-btn[aria-expanded="true"] .rail__lang-caret{color:var(--ink);}

.rail__lang-list{
  position:absolute;top:calc(100% + 6px);left:0;z-index:100;
  min-width:190px;margin:0;padding:6px;list-style:none;
  background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-m);box-shadow:var(--shadow-m);
}
.rail__lang-opt{
  min-height:44px;padding:0 10px;display:flex;align-items:center;gap:10px;
  border-radius:var(--r-s);cursor:pointer;color:var(--ink);
  font-size:.9rem;line-height:1.2;
}
.rail__lang-opt:hover{background:var(--paper-2);}
.rail__lang-opt[aria-selected="true"]{background:var(--paper-2);font-weight:600;}
/* offset ujemny: globalny +3px wychodziłby poza ramkę listy i zostałby ucięty */
.rail__lang-opt:focus-visible{outline:3px solid var(--salvia-deep);outline-offset:-3px;}

.rail__stats{
  margin:0 16px 14px;padding:12px 14px;
  /* nakładka ciemna, nie jasna: rozjaśnienie tła obniżyłoby kontrast białego tekstu */
  background:oklch(0 0 0 / .16);
  border:1px solid oklch(1 0 0 / .22);
  border-radius:var(--r-m);
  display:grid;grid-template-columns:repeat(3,1fr);gap:6px;text-align:center;
}
.rail__stat b{display:block;font-family:var(--display);font-size:1.12rem;font-weight:600;line-height:1.1;}
.rail__stat span{font-size:.68rem;opacity:.95;letter-spacing:.03em;text-transform:uppercase;}

.rail__menu{list-style:none;margin:0;padding:4px 12px;flex:1;overflow-y:auto;}
.rail__menu::-webkit-scrollbar{width:6px;}
.rail__menu::-webkit-scrollbar-thumb{background:oklch(1 0 0 / .25);border-radius:8px;}
.rail__item{
  display:flex;align-items:center;gap:11px;width:100%;min-height:44px;
  background:transparent;border:none;border-radius:var(--r-m);
  padding:10px 13px;margin-bottom:3px;cursor:pointer;
  font-size:.90rem;font-weight:600;text-align:left;color:inherit;
  transition:background .16s ease, transform .16s ease;
}
.rail__item:hover{background:oklch(0 0 0 / .18);}
/* Paper and green-800, both fixed: the current entry sits on the brand
   panel, which is dark in either theme, so a pair that followed the theme
   would invert under one of them. 7.7:1. */
.rail__item[aria-current="page"]{background:oklch(0.987 0.004 56);color:oklch(0.422 0.086 165);box-shadow:var(--shadow-s);}
.rail__ico{font-size:1.02rem;width:22px;text-align:center;flex:0 0 22px;}
.rail__badge{
  margin-left:auto;background:var(--oro);color:var(--on-oro);
  font-size:.70rem;font-weight:700;padding:2px 8px;border-radius:var(--r-pill);min-width:22px;text-align:center;
}
/* Wejście do wyszukiwarki w główce panelu, nie jako dziesiąta pozycja menu:
   szuka się z dowolnego miejsca, a menu jest listą miejsc, nie czynności. */
.rail__search{
  display:flex;align-items:center;gap:8px;width:100%;min-height:44px;
  margin-top:10px;padding:8px 12px;border-radius:var(--r-m);
  background:oklch(0 0 0 / .16);border:1px solid oklch(1 0 0 / .30);
  color:var(--on-rail);font-family:inherit;font-size:.86rem;font-weight:600;
  cursor:pointer;text-align:left;
}
.rail__search:hover{background:oklch(0 0 0 / .26);}
.rail__search:focus-visible{outline:3px solid var(--on-rail);outline-offset:2px;}

.rail__foot{padding:12px 16px 18px;border-top:1px solid oklch(1 0 0 / .2);}
.rail__theme{
  width:100%;min-height:40px;background:oklch(0 0 0 / .16);border:1px solid oklch(1 0 0 / .30);
  border-radius:var(--r-m);color:inherit;font-size:.82rem;font-weight:600;cursor:pointer;
}
.rail__theme:hover{background:oklch(0 0 0 / .26);}

.rail-toggle{display:none;}
.rail__scrim{display:none;}

/* ══════════════════ MAIN ══════════════════ */
/* The content column: <main> and the footer one under the other. `.main`
   carries flex:1, so inside a column it grows vertically and pushes the
   footer to the bottom of the window — on a short screen (settings, an empty
   lexicon) the footer then does not hang halfway up the page. */
.col{flex:1;min-width:0;display:flex;flex-direction:column;}

.main{
  flex:1;min-width:0;
  padding:44px 52px 120px;
  max-width:1080px;
}

/* The horizontal inset is the one `.main` uses (and changes with it in the
   media queries below), so the rule above the footer ends where the text
   above it ends. */
.site-foot{
  max-width:1080px;padding:16px 52px 26px;
  border-top:1px solid var(--line);
  font-size:.85rem;color:var(--ink-soft);text-align:center;
}
.site-foot p{margin:0;}
/* The name is the only thing to click down here: the padding lifts the touch
   target off the 16px of the line itself, without breaking the flow of the
   sentence the way a block would. */
.site-foot a{display:inline-block;padding:6px 4px;}

.view-head{margin-bottom:30px;}
.view-head__kicker{
  font-size:.74rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--salvia-deep);margin:0 0 8px;
}
.view-head h1{font-size:clamp(1.85rem,4vw,2.5rem);margin:0 0 8px;}
.view-head p{color:var(--ink-soft);max-width:64ch;margin:0;font-size:1.02rem;}

/* ══════════════════ ELEMENTI BASE ══════════════════ */
.card{
  background:var(--paper-2);
  border:1.5px solid var(--line);
  border-radius:var(--r-l);
  padding:24px 26px;
  box-shadow:var(--shadow-s);
}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:44px;padding:11px 22px;
  border-radius:var(--r-m);border:2px solid transparent;
  font-size:.92rem;font-weight:600;cursor:pointer;
  transition:transform .14s ease, background .16s ease, border-color .16s ease;
}
.btn:active{transform:translateY(1px);}
.btn:disabled{opacity:.45;cursor:not-allowed;}
/* The primary action is VERDE. The design system gives the mark green
   every ordinary action — progress, confirm, continue — and keeps the red
   for streaks, milestones and the citizenship track, one accent per view.
   Under the cursor the fill moves in whichever direction pulls AWAY from
   the label: darker in the light theme, where the label is paper; lighter
   in the dark theme, where the label is ink. That is one pair of tokens
   instead of the four theme-specific rules this block used to carry. */
.btn--primary{background:var(--salvia-deep);color:var(--on-primary);border-color:var(--salvia-deep);}
.btn--primary:hover:not(:disabled){background:var(--btn-primary-hover);border-color:var(--btn-primary-hover);}
/* Tonal, not a second solid. The sixteen places carrying btn--green are
   subordinate confirmations (play, add, export, ok); two solid greens a few
   steps apart read as a rendering fault, not as a hierarchy. The border is
   green-700 — 5.0:1 against the page — so the shape still clears WCAG
   1.4.11 without a fill that competes with the primary. */
.btn--green{background:var(--salvia);color:var(--on-tonal);border-color:var(--salvia-deep);}
.btn--green:hover:not(:disabled){background:var(--btn-tonal-hover);}
.btn--ghost{background:var(--paper-2);border-color:var(--line-control);color:var(--ink);}
.btn--ghost:hover:not(:disabled){border-color:var(--salvia-deep);color:var(--salvia-deep);}
.btn--quiet{background:transparent;border-color:transparent;color:var(--ink-soft);text-decoration:underline;min-height:36px;padding:6px 10px;}
.btn--sm{min-height:36px;padding:7px 14px;font-size:.82rem;border-radius:var(--r-s);}

.chip{
  display:inline-flex;align-items:center;gap:6px;
  font-size:.72rem;font-weight:700;letter-spacing:.02em;
  padding:5px 12px;border-radius:var(--r-pill);
  background:var(--paper-3);border:1px solid var(--line-strong);color:var(--ink);
}
/* The CEFR level is set in the mono face, and that is the point of it: the
   design system reserves JetBrains Mono for classifiers — levels, verb
   groups, the citizenship mark — so a code reads as a code and not as a
   word. Green, not red: the level is progress, not an alarm. */
.chip--cefr{
  background:var(--salvia-deep);border-color:var(--salvia-deep);color:var(--on-primary);
  font-family:var(--mono);font-weight:600;letter-spacing:.05em;
}
.chip--green{background:var(--salvia);border-color:var(--line-mint);color:var(--on-tonal);}
.chip--gold{background:var(--oro-soft);border-color:var(--oro-deep);color:var(--oro-deep);}

.meta-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:14px;}

.divider{
  border:none;border-top:2px dashed var(--line-strong);
  margin:36px 0;
}

/* ══════════════════ ŚCIEŻKA (percorso) ══════════════════ */
.level-strip{
  display:flex;gap:10px;overflow-x:auto;padding:4px 4px 14px;margin-bottom:26px;
  scrollbar-width:thin;
}
.level-pill{
  flex:0 0 auto;min-width:132px;
  border:2px solid var(--line-strong);border-radius:var(--r-l);
  background:var(--paper-2);padding:12px 16px;cursor:pointer;text-align:left;
  transition:border-color .16s, transform .16s;
}
.level-pill:hover{transform:translateY(-2px);border-color:var(--salvia-mid);}
.level-pill[aria-pressed="true"]{border-color:var(--salvia-deep);background:var(--salvia);}
/* Mono, like every other CEFR code. A monospaced face runs wider than the
   serif it replaces, so the size comes down a step to keep the pill from
   growing around it. */
.level-pill__code{font-family:var(--mono);font-size:1.14rem;font-weight:600;letter-spacing:.03em;display:block;line-height:1.24;}
.level-pill__name{font-size:.74rem;color:var(--ink-soft);display:block;font-weight:600;}
.level-pill__bar{height:6px;background:var(--paper-sunk);border-radius:var(--r-pill);margin-top:8px;overflow:hidden;}
.level-pill__bar i{display:block;height:100%;background:var(--salvia-deep);border-radius:var(--r-pill);}

.unit{
  position:relative;
  margin-bottom:34px;padding:0 0 4px;
}
.unit__head{
  display:flex;align-items:flex-start;gap:14px;margin-bottom:18px;
  padding:16px 20px;border-radius:var(--r-l);
  background:linear-gradient(100deg, var(--paper-3), var(--paper-2) 70%);
  border:1.5px solid var(--line);
}
.unit__badge{
  flex:0 0 52px;height:52px;border-radius:var(--r-l);
  display:grid;place-items:center;font-size:1.5rem;
  background:var(--paper-2);border:2px solid var(--line-strong);
}
.unit__titles h3{font-size:1.16rem;margin:0 0 2px;}
.unit__titles p{margin:0;font-size:.86rem;color:var(--ink-soft);}
.unit__count{margin-left:auto;text-align:right;flex:0 0 auto;}
.unit__count b{font-family:var(--display);font-size:1.05rem;}
.unit__count span{display:block;font-size:.7rem;color:var(--ink-faint);text-transform:uppercase;letter-spacing:.06em;}

/* serpentina */
.path{position:relative;padding:6px 0 6px;}
.path::before{
  content:"";position:absolute;left:50%;top:0;bottom:0;width:0;
  border-left:3px dashed var(--line-strong);transform:translateX(-50%);
}
.node{position:relative;display:flex;margin-bottom:14px;}
.node:nth-child(4n+1){padding-left:6%;}
.node:nth-child(4n+2){padding-left:26%;}
.node:nth-child(4n+3){padding-left:46%;}
.node:nth-child(4n+4){padding-left:26%;}

.node__btn{
  position:relative;display:flex;align-items:center;gap:12px;
  background:var(--paper-2);border:2.5px solid var(--line-strong);
  border-radius:var(--r-l);padding:12px 18px 12px 12px;cursor:pointer;
  min-height:64px;min-width:230px;max-width:300px;text-align:left;
  box-shadow:var(--shadow-s);
  transition:transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.node__btn:hover:not(:disabled){transform:translateY(-3px);box-shadow:var(--shadow-m);border-color:var(--salvia-mid);}
.node__btn:disabled{opacity:.55;cursor:not-allowed;filter:saturate(.4);}
.node__dot{
  flex:0 0 42px;height:42px;border-radius:50%;display:grid;place-items:center;
  background:var(--paper-3);border:2px solid var(--line-strong);font-size:1.1rem;
}
.node__txt b{display:block;font-size:.94rem;font-weight:600;line-height:1.28;}
.node__txt span{display:block;font-size:.76rem;color:var(--ink-soft);}
.node--done .node__btn{border-color:var(--salvia-deep);background:var(--salvia);}
.node--done .node__dot{background:var(--salvia-deep);border-color:var(--salvia-deep);color:var(--on-primary);}
.node--current .node__btn{border-color:var(--salvia-deep);box-shadow:0 0 0 5px oklch(var(--glow-primary) / .18);}
.node--test .node__dot{background:var(--oro);border-color:var(--oro-deep);}

/* ══════════════════ LEKCJA ══════════════════ */
.lesson-top{
  display:flex;align-items:center;gap:14px;margin-bottom:22px;
  position:sticky;top:0;z-index:12;
  padding:14px 0 12px;background:var(--paper);
  background-image:inherit;
}
.lesson-top__bar{flex:1;height:12px;border-radius:var(--r-pill);background:var(--paper-sunk);overflow:hidden;border:1px solid var(--line);}
.lesson-top__bar i{display:block;height:100%;background:linear-gradient(90deg,var(--salvia-mid),var(--salvia-deep));border-radius:var(--r-pill);transition:width .35s ease;}
.lesson-top__hearts{font-size:1rem;letter-spacing:2px;flex:0 0 auto;}

.step{margin-bottom:34px;}
.step__label{
  display:flex;align-items:center;gap:10px;margin:0 0 14px;
  font-family:var(--display);font-size:1.18rem;font-weight:600;
}
.step__label::before{
  content:"";width:11px;height:11px;border-radius:50%;flex:0 0 11px;
  background:var(--salvia-deep);
}
.step--gram .step__label::before{background:var(--lavanda-deep);}
.step--vocab .step__label::before{background:var(--oro-deep);}
/* Not the accent red: this dot stands on the exercises section of EVERY
   lesson, and a colour the system reserves for streaks, milestones and the
   citizenship badge stops meaning anything once it marks a page furniture
   item. Green-500, one step off the section dot above it. */
.step--ex .step__label::before{background:var(--salvia-mid);}

.prose{max-width:68ch;}
.prose p{font-size:1.02rem;}
.prose strong{color:var(--salvia-deep);font-weight:700;}
.prose em{font-style:normal;font-weight:600;color:var(--lavanda-deep);}
.prose h4{font-size:1rem;margin:20px 0 6px;color:var(--ink);}
.prose ul{padding-left:20px;margin:0 0 14px;}
.prose li{margin-bottom:5px;}

.callout{
  border-left:5px solid var(--oro-deep);
  background:var(--oro-soft);
  border-radius:0 var(--r-m) var(--r-m) 0;
  padding:14px 20px;margin:18px 0;font-size:.94rem;
}
.callout b{color:var(--oro-deep);}
/* The three soft fills flip with the theme now, so a callout needs one rule
   instead of a light one plus a dark correction underneath it. */
.callout--trap{border-left-color:var(--rosa-deep);background:var(--rosa);}
.callout--trap b{color:var(--rosa-deep);}
.callout--pl{border-left-color:var(--lavanda-deep);background:var(--lavanda);}
.callout--pl b{color:var(--lavanda-deep);}

.gram-box{
  border:2px solid var(--line-strong);
  border-radius:var(--r-l);
  background:linear-gradient(180deg, var(--paper-3), var(--paper-2) 62%);
  padding:22px 24px;
}
.gram-box__rule{font-family:var(--display);font-weight:600;font-size:1.06rem;margin:0 0 6px;color:var(--salvia-deep);}
.gram-box__note{font-size:.9rem;color:var(--ink-soft);margin:0 0 16px;}

.table-wrap{overflow-x:auto;border-radius:var(--r-m);border:1px solid var(--line);}
table.gt{border-collapse:collapse;width:100%;min-width:380px;background:var(--paper-2);font-size:.92rem;}
table.gt th,table.gt td{padding:9px 14px;text-align:left;border-bottom:1px solid var(--line);}
table.gt thead th{background:var(--paper-3);font-weight:700;font-size:.78rem;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft);}
table.gt tbody tr:last-child td{border-bottom:none;}
table.gt td:first-child{font-weight:600;color:var(--ink-soft);white-space:nowrap;}
table.gt .it{font-weight:700;color:var(--salvia-deep);}

.ex-list{list-style:none;margin:16px 0 0;padding:0;}
.ex-list li{
  padding:10px 0;border-bottom:1px dashed var(--line-strong);
  display:flex;flex-wrap:wrap;gap:4px 12px;align-items:baseline;
}
.ex-list li:last-child{border-bottom:none;}
.ex-list .it{font-weight:600;font-size:1rem;}
.ex-list .pl{color:var(--ink-soft);font-size:.88rem;}
.ex-list .nb{width:100%;font-size:.8rem;color:var(--ink-faint);font-style:italic;}

.say-btn{
  flex:0 0 32px;width:32px;height:32px;border-radius:50%;
  border:1.5px solid var(--line-strong);background:var(--paper-2);
  display:inline-grid;place-items:center;cursor:pointer;font-size:.82rem;padding:0;
  vertical-align:middle;
}
.say-btn:hover{border-color:var(--salvia-deep);background:var(--salvia);}
.say-btn.is-playing{border-color:var(--salvia-deep);background:var(--ok-bg);}

/* vocabolario */
.vocab-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:10px;}
.vocab-card{
  display:flex;align-items:center;gap:10px;
  background:var(--paper-2);border:1.5px solid var(--line);
  border-radius:var(--r-m);padding:11px 14px;
}
.vocab-card__txt{min-width:0;flex:1;}
.vocab-card__it{font-weight:700;color:var(--salvia-deep);display:block;font-size:.98rem;}
.vocab-card__pl{color:var(--ink-soft);font-size:.85rem;display:block;}
.vocab-card__ex{font-size:.78rem;color:var(--ink-faint);display:block;margin-top:3px;font-style:italic;}
.vocab-card__star{
  flex:0 0 30px;width:30px;height:30px;border-radius:50%;border:1.5px solid var(--line-strong);
  background:transparent;cursor:pointer;display:grid;place-items:center;font-size:.8rem;padding:0;
}
.vocab-card__star[aria-pressed="true"]{background:var(--oro);border-color:var(--oro-deep);}

/* dialogo */
.dlg{display:flex;flex-direction:column;gap:10px;}
.dlg__line{display:flex;gap:10px;align-items:flex-start;max-width:88%;}
.dlg__line--b{align-self:flex-end;flex-direction:row-reverse;text-align:right;}
.dlg__who{
  flex:0 0 34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:var(--rosa);font-size:.9rem;border:1.5px solid var(--line-strong);
}
.dlg__line--b .dlg__who{background:var(--salvia);}
.dlg__bubble{
  background:var(--paper-2);border:1.5px solid var(--line);
  border-radius:var(--r-m);padding:10px 15px;
}
.dlg__line--b .dlg__bubble{background:var(--paper-3);}
.dlg__it{font-weight:600;display:block;}
.dlg__pl{font-size:.84rem;color:var(--ink-soft);display:block;margin-top:2px;}

/* Wybór repliki w dialogu rozgałęzionym. Kolumna, nie rząd: obie możliwości
   są całymi zdaniami i przy dwóch kolumnach na telefonie łamią się na czwarte
   wiersze, przez co dłuższa wygląda na ważniejszą. */
.dlg-opts{display:flex;flex-direction:column;gap:8px;margin-bottom:14px;}
.dlg-opt{
  display:block;width:100%;text-align:left;cursor:pointer;
  border:2px solid var(--line-strong);background:var(--paper-2);color:var(--ink);
  border-radius:var(--r-m);padding:10px 14px;min-height:44px;font:inherit;
  transition:border-color .16s ease, background .16s ease;
}
.dlg-opt:hover{border-color:var(--salvia-deep);background:var(--paper-3);}
.dlg-opt i{display:block;font-style:italic;font-weight:600;}
.dlg-opt span{display:block;font-size:.84rem;color:var(--ink-soft);margin-top:2px;}

/* ══════════════════ ĆWICZENIA ══════════════════ */
.exq{
  border:2px solid var(--line);background:var(--paper-2);
  border-radius:var(--r-l);padding:22px 24px;margin-bottom:16px;
}
.exq--ok{border-color:var(--ok);}
.exq--ko{border-color:var(--ko);}
.exq__num{
  font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--lavanda-deep);margin:0 0 8px;display:flex;align-items:center;gap:10px;
}
.exq__prompt{font-size:1.04rem;font-weight:600;margin:0 0 6px;}
.exq__sub{font-size:.86rem;color:var(--ink-soft);margin:0 0 16px;}

.opts{display:flex;flex-direction:column;gap:9px;}
.opt{
  display:flex;align-items:center;gap:11px;
  border:2px solid var(--line-strong);background:var(--paper-2);
  border-radius:var(--r-m);padding:12px 16px;cursor:pointer;
  font-size:.96rem;font-weight:600;min-height:48px;
  transition:border-color .14s, background .14s;
}
.opt:hover{border-color:var(--salvia-mid);}
.opt input{accent-color:var(--salvia-deep);width:18px;height:18px;flex:0 0 18px;}
.opt.is-sel{border-color:var(--salvia-deep);background:var(--salvia);}
.opt.is-ok{border-color:var(--ok);background:var(--ok-bg);}
.opt.is-ko{border-color:var(--ko);background:var(--ko-bg);}

.field{
  font-family:var(--sans);font-weight:600;font-size:1rem;
  padding:12px 16px;border:2px solid var(--line-strong);border-radius:var(--r-m);
  background:var(--paper-2);color:var(--ink);min-height:48px;width:100%;max-width:420px;
}
.field:focus{outline:none;border-color:var(--salvia-deep);box-shadow:0 0 0 4px oklch(var(--glow-primary) / .16);}
.field-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;}
/* Wypracowanie potrzebuje szerokości i wysokości, których pole jednoliniowe
   nie daje: 420 px na tekst o osiemdziesięciu słowach to pisanie w rurce. */
textarea.field{max-width:min(720px, 100%);line-height:1.7;font-weight:500;resize:vertical;}

/* tokens (ordinamento) */
.tok-target{
  min-height:60px;border:2px dashed var(--line-strong);border-radius:var(--r-m);
  background:var(--paper-3);padding:10px;display:flex;flex-wrap:wrap;gap:8px;align-items:flex-start;margin-bottom:12px;
}
.tok-bank{display:flex;flex-wrap:wrap;gap:8px;}
.tok{
  border:2px solid var(--line-strong);background:var(--paper-2);
  border-radius:var(--r-m);padding:8px 14px;font-weight:600;cursor:pointer;min-height:40px;font-size:.94rem;
}
.tok:hover{border-color:var(--salvia-deep);}
.tok--placed{background:var(--salvia);border-color:var(--salvia-mid);}

/* match */
.match-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px 18px;}
.match-col{display:flex;flex-direction:column;gap:8px;}
.match-btn{
  border:2px solid var(--line-strong);background:var(--paper-2);border-radius:var(--r-m);
  padding:11px 14px;cursor:pointer;font-weight:600;text-align:left;min-height:46px;font-size:.93rem;
}
.match-btn.is-sel{border-color:var(--salvia-deep);background:var(--salvia);}
.match-btn.is-ok{border-color:var(--ok);background:var(--ok-bg);opacity:.75;cursor:default;}
.match-btn.is-ko{border-color:var(--ko);background:var(--ko-bg);}

/* conjugation grid */
.conj-grid{display:grid;grid-template-columns:auto 1fr;gap:8px 14px;align-items:center;max-width:460px;}
.conj-grid label{font-weight:600;color:var(--ink-soft);}
.conj-grid .field{max-width:100%;min-height:44px;}

/* voice */
.voice-box{
  border:2px dashed var(--line-strong);border-radius:var(--r-l);
  background:var(--paper-3);padding:20px;text-align:center;
}
.voice-target{font-family:var(--display);font-size:1.3rem;font-weight:600;margin:0 0 4px;color:var(--salvia-deep);}
.voice-pl{font-size:.88rem;color:var(--ink-soft);margin:0 0 16px;}
.mic{
  width:76px;height:76px;border-radius:50%;border:none;cursor:pointer;
  /* At rest the microphone is the primary action, so it is green like every
     other one. RECORDING is the state that earns the accent: something is
     leaving the student's machine, and that is the one moment on this screen
     worth spending the red on. */
  background:var(--salvia-deep);color:var(--on-primary);font-size:1.7rem;
  box-shadow:0 6px 20px oklch(var(--glow-primary) / .32);
}
.mic:hover{background:var(--btn-primary-hover);}
.mic.is-rec{background:var(--rosa-deep);color:var(--on-accent);animation:pulse 1.3s ease-in-out infinite;}
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 oklch(var(--glow-accent) / .50);}50%{box-shadow:0 0 0 18px oklch(var(--glow-accent) / 0);}}
.voice-heard{margin-top:14px;font-size:.95rem;min-height:1.4em;}
.voice-heard b{color:var(--ink);}
.voice-score{font-family:var(--display);font-size:1.5rem;font-weight:700;}

/* feedback */
.fb{
  margin-top:16px;padding:13px 17px;border-radius:var(--r-m);
  font-size:.93rem;font-weight:600;display:none;border:2px solid transparent;
}
.fb.is-on{display:block;}
.fb--ok{background:var(--ok-bg);border-color:var(--ok);color:var(--ok);}
.fb--ko{background:var(--ko-bg);border-color:var(--ko);color:var(--ko);}
.fb__why{display:block;margin-top:6px;color:var(--ink);font-weight:500;font-size:.88rem;line-height:1.55;}

/* riepilogo */
.summary{
  text-align:center;padding:44px 28px;
  border:2px solid var(--line-strong);border-radius:var(--r-xl);
  background:linear-gradient(180deg, var(--paper-3), var(--paper-2) 65%);
}
.summary__score{font-family:var(--display);font-size:3.4rem;font-weight:700;color:var(--salvia-deep);line-height:1;}
.summary__msg{font-size:1.06rem;color:var(--ink-soft);margin:8px 0 24px;}
.summary__acts{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;}

/* ══════════════════ PIĘĆ MINUT ══════════════════ */
.flash__bar{display:flex;align-items:baseline;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:6px;}
.flash__clock{font-family:var(--display);font-size:2rem;font-weight:700;color:var(--salvia-deep);font-variant-numeric:tabular-nums;line-height:1;}
.flash__count{font-size:.86rem;color:var(--ink-soft);}
/* The note keeps its height when empty, so the card does not jump down when the minute warning appears. */
.flash__note{min-height:1.5em;font-size:.92rem;color:var(--ink-soft);margin:0 0 10px;}
.flash__grades{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}
.flash__unit{display:block;margin-bottom:16px;}
/* A typed card keeps its field focused from the moment it appears, and
   keys.js opens the accent bar ABOVE a focused field (60px, 108px once it
   wraps under 360px). Without this room the bar sits on the question the
   student is being asked. */
.flash__typed .field-row{margin-top:4.5rem;}
@media (max-width:359px){.flash__typed .field-row{margin-top:7.5rem;}}
.flash__unit span{display:block;font-weight:600;margin-bottom:5px;}

/* ══════════════════ SIATKI POMOCNICZE ══════════════════ */
.stack{display:flex;flex-direction:column;gap:14px;}
.grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;}

.stat-card{
  border:1.5px solid var(--line);border-radius:var(--r-l);background:var(--paper-2);
  padding:18px 20px;
}
.stat-card b{display:block;font-family:var(--display);font-size:2rem;font-weight:700;line-height:1.1;color:var(--salvia-deep);}
.stat-card span{font-size:.82rem;color:var(--ink-soft);font-weight:600;}

.list-row{
  display:flex;align-items:center;gap:12px;padding:12px 16px;
  border:1.5px solid var(--line);border-radius:var(--r-m);background:var(--paper-2);
}
.list-row__main{flex:1;min-width:0;}
.list-row__main b{display:block;font-size:.96rem;}
.list-row__main span{font-size:.83rem;color:var(--ink-soft);}
/* Wiersz, który na wąskim ekranie kładzie przycisk POD tekstem.
   Zwykły `.list-row` ściska wtedy zdanie do trzech linijek obok
   przycisku — na liście tematów to drobiazg, na ekranie powitalnym
   to pierwsze, co uczeń widzi, i jedyne trzy zdania, które ma
   przeczytać. Modyfikator, nie zmiana `.list-row`: ten wiersz stoi
   w kursie w pięćdziesięciu kilku miejscach. */
@media (max-width: 560px){
  .list-row--stack{flex-direction:column;align-items:stretch;}
  .list-row--stack .btn{width:100%;justify-content:center;}
}

/* Przewodnik. Spis treści leży w poprzek, nie w słupku: dziewięć
   pozycji jedna pod drugą zajmowało cały ekran, więc pierwsza sekcja
   zaczynała się poniżej krawędzi i strona wyglądała na sam spis.
   Nagłówek sekcji dostaje odstęp od tekstu, bo `.card` go nie daje. */
.guide-toc{display:flex;flex-wrap:wrap;gap:6px 10px;margin-bottom:26px;}
.guide-toc .btn{min-height:32px;padding:4px 10px;font-size:.86rem;}
.guide-sec h3{margin-bottom:10px;}
.guide-sec p + p{margin-top:10px;}

.empty{
  border:2px dashed var(--line-strong);border-radius:var(--r-l);
  padding:40px 28px;text-align:center;color:var(--ink-soft);background:var(--paper-3);
}
.empty h3{margin-bottom:6px;color:var(--ink);}

/* Etykieta tylko dla czytnika ekranu: widoczna dla technologii
   wspomagających, niewidoczna na ekranie. `display:none` nie zadziała —
   czytnik też by jej nie zobaczył. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0;
}
mark{background:var(--oro);color:var(--on-oro);border-radius:3px;padding:0 2px;}

/* ══════════════════ PASEK ZNAKÓW ══════════════════ */
/* Unosi się nad treścią pod polem tekstowym: pozycję liczy keys.js,
   bo pole bywa w różnych widokach i nie ma jednego rodzica do zaczepienia. */
.keybar{
  position:absolute;z-index:100;display:flex;gap:4px;
  /* Zawija się i mieści w ekranie. Dziesięć klawiszy po 44px to ~500px,
     więc na telefonie pasek wystawał poza stronę i spychał ją w bok —
     akurat tam, gdzie jest najbardziej potrzebny, bo akcentów nie ma na
     klawiaturze ekranowej. Zmierzone: +436px przy szerokości 280px. */
  flex-wrap:wrap;max-width:calc(100vw - 24px);
  padding:6px;border-radius:var(--r-m);
  background:var(--paper-2);border:2px solid var(--ink-faint);box-shadow:var(--shadow-m);
}
.keybar__k{
  min-width:44px;min-height:44px;
  border:1px solid var(--line-strong);border-radius:var(--r-s);
  /* Było `var(--paper-1)`, a takiego tokenu nie ma w palecie: deklaracja
     jest nieprawidłowa, więc klawisze nie miały własnego tła i zlewały
     się z paskiem. Nic tego nie zgłaszało, bo CSS po prostu pomija
     regułę, której nie rozumie. */
  background:var(--paper);color:var(--ink);
  font-family:inherit;font-size:1.05rem;font-weight:600;cursor:pointer;
}
.keybar__k:hover{background:var(--paper-3);border-color:var(--salvia-deep);}

/* Uwaga „w twoim języku jest inaczej" — najcenniejsza treść kursu wobec
   aplikacji, które uczą wszystkich tak samo. Wyróżniona lewą krawędzią,
   nie tłem: tło zmieniłoby kontrast tekstu, krawędź nie. */
.card--contrast{border-left:5px solid var(--salvia-deep);}

/* ══════════════════ ZAKŁADKI ══════════════════ */
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:22px;}
/* Obramowanie z --ink-faint, nie z --line-strong: to drugie daje 1.58:1
   w jasnym i 1.80:1 w ciemnym, czyli granica kontrolki znika w tle.
   Wypełnienie zakładki jest prawie w kolorze strony, więc to obramowanie
   niesie kształt przycisku i musi przejść próg 3:1 (WCAG 1.4.11). */
.tab{
  display:inline-flex;align-items:center;gap:8px;
  min-height:44px;padding:9px 18px;border-radius:var(--r-m);
  background:var(--paper-2);border:2px solid var(--ink-faint);
  font-family:inherit;font-size:.94rem;font-weight:600;color:var(--ink);cursor:pointer;
}
.tab:hover{border-color:var(--salvia-mid);}
.tab:focus-visible{outline:3px solid var(--salvia-deep);outline-offset:2px;}
.tab[aria-current="true"]{border-color:var(--salvia-deep);background:var(--paper-3);}
/* The same pair as the badge in the side panel (.rail__badge): a pale gold
   fill and a fixed dark ink, neither of which follows the theme. An earlier
   version used the brand colour over --paper-1 and measured 2.58:1 in light
   and 1.59:1 in dark — this is a number to be read, not an ornament. */
.tab__n{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:22px;height:22px;padding:0 6px;border-radius:var(--r-pill);
  background:var(--oro);color:var(--on-oro);font-size:.72rem;font-weight:700;
}

/* ══════════════════ TOAST ══════════════════ */
.toast-stack{position:fixed;right:20px;bottom:20px;z-index:80;display:flex;flex-direction:column;gap:8px;}
.toast{
  background:var(--paper-2);border:2px solid var(--salvia-deep);border-radius:var(--r-m);
  padding:11px 18px;box-shadow:var(--shadow-m);font-weight:600;font-size:.9rem;
  animation:toastIn .25s ease;max-width:320px;
}
.toast--ok{border-color:var(--ok);}
/* Komunikat, który zostaje: utrata danych nie ma znikać po trzech sekundach.
   Szerokość liczona od okna, nie stała: przy 320 px stała 360 px kładła
   ramkę na samej krawędzi ekranu, bez marginesu. */
.toast--stuck{
  border-color:var(--ko);position:relative;font-weight:500;
  max-width:min(360px, calc(100vw - 40px));padding-right:54px;
}
/* 44 px, nie mniej: to jest cel dotykowy na telefonie, a nie ikonka do trafiania paznokciem. */
.toast__x{
  position:absolute;top:50%;right:4px;transform:translateY(-50%);
  width:44px;height:44px;line-height:1;
  border:0;background:none;color:var(--ink-soft);font-size:1.25rem;cursor:pointer;border-radius:var(--r-s);
}
.toast__x:hover{background:var(--paper-3);color:var(--ink);}
.toast__x:focus-visible{outline:3px solid var(--salvia-deep);outline-offset:2px;}
/* Akcja w trwałym komunikacie, trzy decyzje i wszystkie z pomiaru:
   `flex`, nie odziedziczone `inline-flex` z .btn, bo przycisk zostawał w
   linii tekstu i margin-top wsuwał go NA ostatni wiersz zamiast wypchnąć
   pod akapit; `fit-content`, żeby nie rozciągał się na całą szerokość;
   klasa btn--primary, nie ghost, bo obramowanie ghosta na tle komunikatu
   dawało 1,58:1 przy progu 3:1 (btn--sm odpada osobno: 36 px to za mały
   cel dotykowy na telefonie). */
.toast__act{display:flex;width:fit-content;margin-top:10px;}
@keyframes toastIn{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}

/* ══════════════════ RESPONSIVE ══════════════════ */
@media (max-width: 1000px){
  .main{padding:36px 30px 110px;}
  .site-foot{padding-left:30px;padding-right:30px;}
  .node:nth-child(4n+1),.node:nth-child(4n+2),.node:nth-child(4n+3),.node:nth-child(4n+4){padding-left:0;justify-content:flex-start;}
  .path::before{left:34px;}
  .node__btn{margin-left:0;}
}

@media (max-width: 880px){
  .rail{
    position:fixed;left:0;top:0;transform:translateX(-100%);
    transition:transform .24s ease;box-shadow:var(--shadow-l);
  }
  .rail.is-open{transform:none;}
  /* Chowanie zasłony obsługuje teraz globalna reguła [hidden] na górze pliku. */
  .rail__scrim{display:block;position:fixed;inset:0;background:oklch(0.211 0.007 67 / .50);z-index:35;}
  .rail-toggle{
    display:grid;place-items:center;position:fixed;top:14px;left:14px;z-index:45;
    width:48px;height:48px;border-radius:50%;border:none;cursor:pointer;
    background:var(--salvia-deep);color:var(--on-primary);box-shadow:var(--shadow-m);
  }
  .rail-toggle__bars,.rail-toggle__bars::before,.rail-toggle__bars::after{
    display:block;width:20px;height:2.5px;background:currentColor;border-radius:2px;position:relative;
  }
  .rail-toggle__bars::before,.rail-toggle__bars::after{content:"";position:absolute;left:0;}
  .rail-toggle__bars::before{top:-6px;}
  .rail-toggle__bars::after{top:6px;}
  .main{padding:76px 18px 100px;}
  .site-foot{padding-left:18px;padding-right:18px;}
  .path::before{left:30px;}
  .node__btn{min-width:0;width:100%;max-width:none;}
  .match-grid{grid-template-columns:1fr;}
  .unit__count{display:none;}
  .lesson-top{position:static;}
}

@media (max-width: 420px){
  .view-head h1{font-size:1.6rem;}
  .exq{padding:18px 16px;}
  .card{padding:18px 18px;}
}

@media print{
  .rail,.rail-toggle,.toast-stack{display:none;}
  .main{padding:0;max-width:100%;}
  .site-foot{padding-left:0;padding-right:0;max-width:100%;}
}

/* ============================================================
   Dotknięcie słowa w czytance (views-lookup.js)
   ============================================================ */

/* Słowo w tekście. Wygląda jak tekst, zachowuje się jak przycisk:
   podkreślenie kropkowane mówi „da się dotknąć" bez rozbijania rytmu
   akapitu, którego kolorowanie każdego wyrazu by nie przetrwało. */
.lk-word{
  font:inherit;color:inherit;background:none;border:0;padding:0 1px;margin:0;
  cursor:pointer;border-radius:3px;
  text-decoration:underline dotted color-mix(in oklch, var(--ink-faint) 60%, transparent);
  text-underline-offset:4px;
}
.lk-word:hover{background:var(--paper-3);text-decoration-color:var(--salvia-deep);}
.lk-word:focus-visible{outline:2px solid var(--salvia-deep);outline-offset:2px;}

/* Wiersz tekstu ma line-height 2.1 właśnie po to: cel dotknięcia rośnie
   w pionie do ~44px bez rozstrzeliwania liter w poziomie. Sam padding na
   wyrazie by tego nie dał, bo wyrazy stoją obok siebie w zdaniu. */
@media (pointer:coarse){
  .lk-text{line-height:2.4;}
}

.lk-card{
  display:block;margin:10px 0;padding:14px 16px;
  background:var(--paper-2);border:1px solid var(--salvia-deep);border-radius:var(--r-m);
  box-shadow:var(--shadow-m);
  max-width:min(460px,100%);
}
.lk-card__head{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
.lk-card__lemma{font-family:var(--display);font-size:1.14rem;font-weight:600;}
.lk-card__x{
  margin-left:auto;min-width:44px;min-height:44px;
  background:none;border:0;cursor:pointer;color:var(--ink-soft);font-size:1rem;border-radius:10px;
}
.lk-card__x:hover{background:var(--paper-sunk);color:var(--ink);}
.lk-card__x:focus-visible{outline:2px solid var(--salvia-deep);outline-offset:2px;}
.lk-card__lab{display:block;font-size:.86rem;font-weight:600;color:var(--ink-soft);}
.lk-card__lab .field{margin-top:5px;width:100%;}
.lk-card__row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:12px;}
.lk-card__from,.lk-card__guess{color:var(--ink-soft);font-size:.86rem;margin:0;}
.lk-card__miss{margin:0 0 8px;font-size:.94rem;}
.lk-card__ctx{color:var(--ink-soft);font-size:.84rem;margin:6px 0 0;}

/* ============================================================
   Pokrycie listy częstości (views-frequency.js)
   ============================================================ */
.cov{margin:0 0 22px;}
.cov:last-child{margin-bottom:0;}
.cov__top{display:flex;align-items:baseline;gap:10px;margin-bottom:6px;}
.cov__top b{font-family:var(--display);font-size:1.06rem;}
.cov__n{margin-left:auto;font-variant-numeric:tabular-nums;color:var(--ink-soft);font-size:.92rem;}
.cov__bar{height:12px;border-radius:var(--r-pill);background:var(--paper-sunk);overflow:hidden;}
.cov__fill{display:block;height:100%;border-radius:var(--r-pill);background:var(--salvia-mid);}
.cov__fill--strong{background:var(--salvia-deep);}
.cov__why{margin:7px 0 0;color:var(--ink-soft);font-size:.9rem;}
.cov__tok{margin:3px 0 0;font-size:.9rem;font-weight:600;}
.cov__h{font-size:1.15rem;margin:26px 0 4px;}
.cov__done{margin-top:22px;font-weight:600;}
.cov__src{margin-top:26px;color:var(--ink-faint);font-size:.84rem;}
#covList .js-f{color:var(--ink-faint);font-size:.86rem;}

/* ============================================================
   Fałszywi przyjaciele (views-falsi.js)
   ============================================================ */
.fa-card{margin:0;}
.fa-head{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
.fa-it{font-family:var(--display);font-size:1.15rem;font-weight:600;}
.fa-line{display:flex;gap:10px;align-items:baseline;margin:0 0 5px;flex-wrap:wrap;}
.fa-tag{
  flex:0 0 auto;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:2px 8px;border-radius:var(--r-pill);
}
.fa-tag--no{background:var(--ko-bg);color:var(--ko);}
.fa-tag--yes{background:var(--ok-bg);color:var(--ok);}
.fa-why{margin:10px 0 0;color:var(--ink-soft);font-size:.92rem;}
.fa-ex{margin:10px 0 0;font-style:italic;}

/* ============================================================
   Shadowing (views-shadow.js)
   ============================================================ */
.sh-it{font-family:var(--display);font-size:1.35rem;line-height:1.5;margin:0 0 18px;}
.sh-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.sh-row + .sh-row{margin-top:10px;}
.sh-state{margin:12px 0 0;min-height:1.5em;color:var(--ink-soft);font-size:.92rem;}
.sh-note{margin-top:18px;color:var(--ink-faint);font-size:.86rem;}
/* Nagrywanie widać, a nie tylko słychać w opisie: puls przy czerwonym
   przycisku plus aria-pressed, bo sam kolor nie jest informacją. */
.js-rec.is-rec{background:var(--ko);border-color:var(--ko);color:var(--on-accent);}
@media (prefers-reduced-motion: no-preference){
  .js-rec.is-rec{animation:sh-puls 1.4s ease-in-out infinite;}
}
@keyframes sh-puls{50%{opacity:.72;}}

/* Zgoda na rozpoznawanie mowy (views-shadow.js) */
.stt-consent{
  position:fixed;inset:0;z-index:400;
  display:flex;align-items:center;justify-content:center;padding:20px;
  background:oklch(0.211 0.007 67 / .60);
}
.stt-consent__box{
  background:var(--paper-2);border:2px solid var(--salvia-deep);border-radius:var(--r-l);
  padding:26px;max-width:520px;box-shadow:var(--shadow-l);
}
.stt-consent__box h2{font-size:1.2rem;margin-bottom:10px;}
.stt-consent__box p{margin:0 0 12px;}
.stt-consent__row{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px;}

/* ============================================================
   Tempo mowy (views-speed.js)
   ============================================================ */
.sp-num{font-size:.74rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-faint);margin:0 0 12px;}
.sp-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.sp-state{margin:12px 0 0;min-height:1.5em;color:var(--ink-soft);font-size:.92rem;}
.sp-reveal{margin-top:16px;}
.sp-it{font-family:var(--display);font-size:1.28rem;line-height:1.5;margin:12px 0 0;}

/* ══════════════════ SYMULACJA EGZAMINU ══════════════════ */
/* The exam simulation is the citizenship track, and the design system puts
   the accent red exactly there. One edge on the running bar carries it —
   not a red panel, not a red heading: the register is set once and the rest
   of the screen stays the same course. The step label goes mono with it,
   like every other classifier in the system. */
.cils-bar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-bottom:14px;padding:10px 14px;border:2px solid var(--line-strong);
  border-left:4px solid var(--rosa-deep);
  border-radius:var(--r-m);background:var(--paper-2);
}
.cils-step{font-family:var(--mono);font-size:.74rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);}
/* Zegar: cyfry o stałej szerokości, żeby pasek nie drgał co sekundę. */
.cils-clock{font-variant-numeric:tabular-nums;font-size:1.3rem;font-weight:700;color:var(--ink);}
.cils-prova{margin-bottom:18px;}
.cils-h{font-size:1.05rem;margin:0 0 8px;}
.cils-titolo{font-family:var(--display);font-size:1.15rem;margin:14px 0 6px;}
.cils-consegna{font-style:italic;color:var(--ink-soft);margin:0 0 12px;}
.cils-testo{margin:0 0 10px;line-height:1.62;}
.cils-gap{color:var(--rosa-deep);}
.cils-audio{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:12px;}
.cils-hint{font-size:.86rem;color:var(--ink-soft);margin:6px 0 0;}
/* The free conversation. The correction sits INSIDE the partner's bubble and
   under their words, set apart by size and by a rule rather than by colour:
   it is a second voice in the same breath, not a state. The counter of turns
   left is plain text and always present — it costs the student money, so it
   is not something to discover when it runs out. */
.chat-fix{display:block;margin-top:8px;padding-top:8px;border-top:1px solid var(--line);font-size:.86rem;color:var(--ink-soft);}
.chat-left{margin:12px 0 0;font-size:.86rem;color:var(--ink-soft);text-align:right;}
/* The model's reading of a production. Set apart from the course's own text
   by an indent rather than by a colour: it is somebody else's sentence, not
   a state, and colouring it would read as a verdict. Empty by default, so a
   report without it has no gap where it would have been. */
.cils-lettura:empty{display:none;}
.cils-lettura{margin-top:14px;padding-left:12px;border-left:3px solid var(--line);font-size:.92rem;line-height:1.6;}
.cils-lettura.is-waiting{color:var(--ink-soft);font-style:italic;}
.cils-items{margin:14px 0 0;padding-left:22px;}
.cils-items li{margin-bottom:12px;line-height:1.5;}
.cils-q{display:block;margin-bottom:4px;}
.cils-opts{display:flex;gap:16px;flex-wrap:wrap;}
.cils-opts--col{flex-direction:column;gap:4px;}
.cils-opts label{display:inline-flex;gap:6px;align-items:baseline;cursor:pointer;min-height:32px;}
.cils-tracce{display:flex;flex-direction:column;gap:10px;margin-bottom:14px;}
.cils-traccia{display:flex;gap:8px;align-items:flex-start;line-height:1.5;cursor:pointer;}
.cils-ta{width:100%;min-height:220px;font-family:inherit;line-height:1.6;resize:vertical;}
.cils-count{font-size:.88rem;color:var(--ink-soft);margin:8px 0 0;}
.cils-list{margin:0 0 14px;padding-left:22px;}
.cils-list li{margin-bottom:4px;}
.cils-check{list-style:none;margin:0;padding:0;}
.cils-check li{margin-bottom:6px;line-height:1.5;}
.cils-check label{display:flex;gap:8px;align-items:flex-start;cursor:pointer;min-height:32px;}
.cils-acts{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px;}
.cils-state{margin:10px 0 0;min-height:1.4em;color:var(--ink-soft);}
.cils-tab{width:100%;border-collapse:collapse;margin-bottom:12px;}
.cils-tab th,.cils-tab td{text-align:left;padding:8px 0;border-bottom:1px solid var(--line);}
.cils-tab td{font-variant-numeric:tabular-nums;}
.cils-verdict{margin:12px 0 0;line-height:1.6;}
/* Pochodzenie progu jest częścią wyniku, nie przypisem: ma być czytelne, */
/* nie szare do granicy niewidzialności. */
.cils-src{font-size:.88rem;color:var(--ink-soft);line-height:1.55;margin:10px 0 0;}
.cils-struct{margin:0;line-height:1.6;}
