/* ============================================================
   tokens.css - JEDYNE źródło tokenów SOLVE (Etap 4 audytu, UI-01/UI-02).
   Ładowany przez app.css: @import ... layer(tokens) - pierwsza warstwa,
   więc każda reguła w components/utilities może nadpisać wartość, ale
   tokeny są zdefiniowane w jednym miejscu, na górze kaskady.

   Zasady:
   - hexy tylko w sekcji „Marka" (+ kolory obcych marek, np. WhatsApp);
     reszta pliku i cały app.css używa var(--…) albo oklch();
   - light w :root, nadpisania dark w html.dark (ten sam zestaw nazw);
   - po zmianie: bump ?v= tokens.css w app.css (@import) i w sw.js
     (PRECACHE_URLS) razem z CACHE_VERSION.
   ============================================================ */

:root {
  /* Natywne kontrolki (scrollbary, <select>, date picker) w kolorze motywu;
     html.dark niżej przełącza na dark. */
  color-scheme:               light;

  /* Marka (UI-02, KV-APP 08.10): JEDYNE miejsce z hexami. Od 08.10 cały panel
     ma paletę strony korepetycjesolve.com (wcześniej tylko skorupa /probna*):
     kto przechodzi ze strony do aplikacji, ma widzieć ten sam produkt.
     Niebieski = akcja i nawigacja, atrament = tekst, chłodna szarość = tło.
     Cyjan = wyróżnienie („polecany", 0-1 element na ekran), nigdy zwykły
     przycisk; jako tekst tylko --brand-cyan-text (biały na #00B9D6 ma 2,36:1, UI-03). */
  --brand-blue:               #014EE6;   /* PANEL-V2 29.10: niebieski strony (--zs-blue), biały tekst 6,5:1 */
  --brand-blue-hover:         #0041C2;
  --brand-blue-press:         #0035A8;
  --brand-blue-soft:          #EAF1FF;   /* tło aktywnej pozycji menu, zaznaczenia */
  --brand-blue-100:           #B2DFFF;   /* pierścień fokusu, obwódka zaznaczenia */
  --brand-blue-text:          #0041C2;   /* tekst na --brand-blue-soft: 7,3:1 */
  --brand-ink:                #141B4E;   /* PANEL-V2: granat strony (15,8:1 na tle) */
  --brand-ink-muted:          #4A5180;   /* 7,4:1 */
  --brand-ink-soft:           #5A6190;   /* 5,76:1 na tle strony */
  --brand-line:               #DCE6F7;
  --brand-line-strong:        #BFD0EE;
  --brand-field:              #7C86B8;   /* PANEL-V2: obrys pól w odcieniu granatu, 3,5:1 do bieli */
  /* PANEL-V2-CIEMNY (29.10, właściciel: „przenosimy na motyw"): ciemny motyw jak granatowe sekcje strony
     (stopka, „Jak zaczynamy") - granat w cyjanową kratkę. Kontrasty: tekst 14:1, text-2 9,3:1, text-3 6,2:1,
     niebieski akcji 7,2:1 na karcie; obrys pól 3,7:1. */
  --brand-navy-bg:            #0E1442;
  --brand-navy-card:          #18205A;
  --brand-navy-1:             #1B2460;
  --brand-navy-2:             #1F2866;
  --brand-navy-3:             #273072;
  --brand-navy-4:             #2D377C;
  --brand-navy-5:             #343F86;
  --brand-navy-line:          #2C3577;
  --brand-navy-line-strong:   #3E4A98;
  --brand-navy-field:         #6E79BE;
  --brand-navy-text:          #F4F6FF;
  --brand-navy-text-2:        #C3C9F2;
  --brand-navy-text-3:        #9AA3DC;
  --brand-navy-blue:          #8DB3FF;
  --brand-navy-blue-hover:    #A9C6FF;
  --brand-navy-blue-press:    #7AA4F5;
  --brand-navy-blue-soft:     #24307A;
  --brand-navy-blue-text:     #DCE6FF;
  --brand-bg:                 #FAFCFF;   /* PANEL-V2: papier zeszytu */
  --brand-cyan:               #00B9D6;
  --brand-cyan-soft:          #E0F7FB;
  --brand-cyan-100:           #A5E8F2;
  --brand-cyan-text:          #00707F;   /* na --brand-cyan-soft: 5,21:1 */
  /* PROBNA-HERO (28.10): kolory strony głównej dla ramki rezerwacji w hero (/probna?embed=hero) - tylko tam
     (html.pb-heroframe nadpisuje nimi --primary, --border, --text). Biały tekst na --pbh-blue: 6,3:1. */
  --pbh-blue:                 var(--zs-blue);
  --pbh-blue-hover:           var(--zs-blue-hover);
  --pbh-cyan:                 var(--zs-cyan);
  --pbh-navy:                 var(--zs-ink);
  --pbh-line:                 var(--zs-line);
  --pbh-radius:               var(--zs-r-btn);   /* zaokrąglenia przycisków i kafli w ramce hero (12-14 px wg strony) */
  /* STRONA-V2 (28.10): system wizualny nowej korepetycjesolve.com („zeszyt w kratkę") dla publicznych
     widoków panelu (sklep, cennik korepetycji, pakiet, /probna, asystent, okno zgód). Paleta sklepu niżej
     i nadpisania w html.pb-kv (app.css, blok STRONA-V2) biorą barwy stąd. Biały na --zs-blue: 6,3:1;
     --zs-ink na --zs-paper: 15:1; --zs-mute na bieli: 7,6:1. Cyjan, żółty i czerwony tylko jako akcenty. */
  --zs-ink:                   #141B4E;
  --zs-blue:                  #014EE6;
  --zs-blue-hover:            #0041C2;
  --zs-blue-press:            #0035A8;   /* cień „klawisza" pod przyciskiem */
  --zs-blue-soft:             #EAF1FF;
  --zs-cyan:                  #00B9D6;
  --zs-paper:                 #FAFCFF;
  --zs-line:                  #DCE6F7;
  --zs-line-strong:           #BFD0EE;
  --zs-mute:                  #4A5180;
  --zs-mark:                  #FFE36E;   /* zakreślacz */
  --zs-pen:                   #E5484D;   /* czerwony długopis */
  --zs-teal:                  #0E7C86;
  --zs-violet:                #5B3CC4;
  --zs-tape:                  rgba(255, 227, 110, 0.75);
  --zs-grid:                  rgba(1, 78, 230, 0.07);
  --zs-key:                   0 4px 0 #0035A8;
  --zs-key-down:              0 2px 0 #0035A8;
  /* KV-STRONA-1 (05.11, właściciel: „KV aplikacji jak strony"): główna akcja na granatowej scenie jest żółta
     (`.btn.cta` i żółte przyciski sklepu), na jasnym tle niebieska (`.btn.accent` z `--zs-key`). Żółty TYLKO na
     scenie: na bieli 1,24-1,28:1 (WCAG 1.4.11 wymaga 3:1), na granacie 12,7:1; granatowy tekst na żółtym 12,7:1.
     Hover i cień liczone z zakreślacza jak dotąd w sklepie (#FFE784, #958960 - wygląd sklepu bez zmian).
     Bez nadpisań w html.dark: żółty na granacie w obu motywach (tests/test_tokens_css.py). */
  --zs-cta:                   #FFE36E;
  --zs-cta-ink:               #141B4E;
  --zs-cta-hover:             color-mix(in srgb, var(--zs-cta) 85%, #FFFFFF);
  --zs-cta-press:             color-mix(in srgb, var(--zs-cta) 55%, var(--zs-cta-ink));   /* „klawisz" pod żółtym */
  --zs-cta-key:               0 4px 0 var(--zs-cta-press);
  --zs-cta-key-down:          0 2px 0 var(--zs-cta-press);
  /* Scena granatowa strony (hero, pas końcowy): granat + cyjanowa kratka co 28 px + niebieska poświata w rogu.
     KV-STRONA-2 (05.11): z tych tokenów jest `--g-panel` (hero panelu, baner płatności, panel logowania, nagłówek
     kursu) i sceny sklepu (hero katalogu, pas końcowy, „Materiał miesiąca", karta produktu). Tekst na scenie:
     biały 16,2:1 (w najjaśniejszym miejscu poświaty 11,1:1, na linii kratki 9,1:1), drugorzędny
     `--zs-scene-mute` 9,2 / 6,3 / 5,1:1, odręczny dopisek cyjanem `--zs-cyan` 6,9 / 4,7:1 (tests/test_tokens_css.py). */
  --zs-scene-bg:              #141B4E;
  --zs-scene-grid:            rgba(0, 185, 214, 0.13);
  --zs-scene-glow:            radial-gradient(60% 75% at 88% 8%, rgba(1, 78, 230, 0.45), transparent 70%);
  --zs-scene-text:            #FFFFFF;
  --zs-scene-mute:            #B9C0F0;   /* podpisy na scenie (jak --zs-foot-text stopki strony) */
  --zs-ghost-line:            rgba(255, 255, 255, 0.35);   /* obwódka przezroczystego przycisku na scenie */
  --zs-ghost-hover:           rgba(255, 255, 255, 0.10);   /* tło przezroczystego przycisku na scenie pod kursorem */
  --zs-scene-pill:            rgba(255, 255, 255, 0.16);   /* tło pigułek na scenie */
  --focus-on-scene:           #FFFFFF;   /* fokus na scenie: 16,2:1 (niebieski #0A62C7 strony ma tam 2,76:1) */
  --zs-shadow:                0 1px 0 rgba(20, 27, 78, 0.04), 0 18px 40px -24px rgba(20, 27, 78, 0.22);
  --zs-shadow-lift:           0 0 0 1.5px #DCE6F7, 0 30px 60px rgba(20, 27, 78, 0.14);
  --zs-r-btn:                 14px;
  --zs-r-card:                20px;
  --zs-r-big:                 22px;
  --zs-hl:                    linear-gradient(transparent 60%, #FFE36E 60%, #FFE36E 92%, transparent 92%);
  /* STRONA-V2-NAGLOWEK (28.10): nagłówek i stopka jak na korepetycjesolve.com (#sp-hdr, stopka w kratkę).
     --zs-foot-text na --zs-ink: 9,6:1, --zs-foot-mute: 5,9:1, link w pasku (cyjan) na granacie: 11:1. */
  --zs-nav:                   #2A3060;   /* linki nawigacji w nagłówku */
  --zs-topbar-link:           #7FE7F7;
  --zs-foot-text:             #B9C0F0;
  --zs-foot-mute:             #8F98D6;
  --zs-foot-grid:             rgba(127, 231, 247, 0.05);
  --zs-foot-line:             rgba(127, 231, 247, 0.22);
  --zs-key-light:             #A8C4FF;   /* cień „klawisza" białego przycisku na niebieskim/granatowym tle */
  --zs-final-sub:             #D6E4FF;
  /* SKLEP-NAGLOWEK-WWW (04.11): nagłówek sklepu = #sp-hdr strony WWW (kolory odczytane w przeglądarce). */
  --zs-hdr-ico:               #BFE9F5;   /* ikonki w menu na telefonie (dekoracja przy podpisie) */
  --zs-hdr-ico-cur:           #0A62C7;   /* ikonka bieżącej strony w menu na telefonie */
  --zs-wa:                    #25D366;   /* okrągły przycisk WhatsApp (sama ikona) */
  --zs-check:                 #1FAF55;   /* CENNIK-1-DO-1: zielony ptaszek w tabeli „Co dostajesz w cenie” (jak na WWW) */
  /* MOTYWY PROMOCJI (BW-PASEK-BANER, 10.11): pasek nad nagłówkiem, baner w sklepie i plakietka „-X%”
     w czasie promocji z panelu (Sklep -> Promocje). Trzy motywy: zwykła promocja (granat strony),
     Black Week (czerń z żółtym zakreślaczem, jak grafiki akcji), Mikołaj (czerwień).
     Kontrast tekstu na tle: biały na #0B0B0F 19:1, biały na #B3202A 6,5:1, #FFE784 na #0B0B0F 15:1. */
  --promo-bg:                 var(--zs-ink);
  --promo-ink:                #FFFFFF;
  --promo-accent:             var(--zs-mark);
  --promo-blackweek-bg:       #0B0B14;
  --promo-blackweek-accent:   #FFE36E;
  --promo-mikolaj-bg:         #B3202A;
  --promo-mikolaj-accent:     #FFFFFF;
  --promo-snow:               #BFD8FF;   /* płatki śniegu motywu Mikołaj: widoczne na granacie i (blado) na bieli */
  /* PALETA SKLEPU (SKLEP-KV-3, 12.10): publiczny /sklep w wyglądzie strony szkoły
     (/cennik). Jedyne miejsce zmiany barw sklepu; app.css (html.sk-kv) tylko z nich
     korzysta. Sklep ma zawsze jasny motyw, więc bez nadpisań w html.dark. */
  --sk-primary:               #014EE6;   /* przyciski główne, linki, aktywne (biały tekst 5,86:1) */
  --sk-on-primary:            #FFFFFF;   /* tekst na --sk-primary; NIE --on-primary - to w html.dark
                                            jest granatowe, a koszyk panelu (/konto/sklep) widzi
                                            ciemny motyw (SKLEP-KOSZYK-DARK, 15.10) */
  --sk-primary-hover:         #0041C2;
  --sk-primary-deep:          #0035A8;   /* środek gradientu hero */
  --sk-primary-soft:          #EAF1FF;   /* tło przycisku drugorzędnego */
  --sk-primary-soft-hover:    #DCE8FF;
  --sk-primary-line:          #BFD0EE;   /* obwódka karty pod kursorem */
  --sk-accent:                #00B9D6;   /* wyróżnienia, ikony, gradient z głównym */
  --sk-accent-deep:           #0E7C86;   /* STRONA-V2: morski z zeszytu (oszczędność, akcenty tekstowe) */
  --sk-accent-light:          #9FE9F5;   /* akcent na granatowym hero */
  --sk-accent-soft:           #E3F8FB;
  --sk-accent-ink:            #00707F;   /* ikona/tekst na --sk-accent-soft: 5,2:1 */
  --sk-highlight:             #F5A623;   /* Promocja, Nowość - tło plakietki */
  --sk-highlight-ink:         #4A2E00;   /* tekst na --sk-highlight: 8,4:1 */
  --sk-highlight-soft:        #FEF4E2;
  --sk-success:               #007E46;   /* Opłacone, dostęp aktywny (5,2:1 na bieli) */
  --sk-success-soft:          #E5F4EC;
  --sk-bg:                    #FAFCFF;
  --sk-card:                  #FFFFFF;
  --sk-line:                  #DCE6F7;
  /* SKLEP-KV-STRONA (20.10, „KV sklepu a naszej strony to dwie różne rzeczy"): wartości 1:1
     z motywu korepetycjesolve.com (style.css 3.95: --c-*, nagłówek .sp-hdr, karty .sp-pkg,
     pas .sp-final, stopka .sp-ftr--v2), żeby sklep wyglądał jak /cennik. */
  --sk-ink:                   #141B4E;
  --sk-ink-muted:             #4A5180;
  --sk-ink-soft:              #4A5180;   /* 5,9:1 na bieli */
  --sk-site-line:             #DCE6F7;
  --sk-primary-press:         #0035A8;
  --sk-primary-pale:          #EAF1FF;   /* --c-primary-soft strony: tło ikon, „+" w pytaniach */
  --sk-primary-100:           #B2DFFF;
  --sk-len-line:              #BFD0EE;   /* obwódka przełącznika 45 / 60 min */
  --sk-success-pale:          #CCF8DA;
  --sk-success-line:          #9EE9B9;
  --sk-success-ink:           #006B3C;   /* tekst na --sk-success-pale: 5,7:1 (#007E46 ma tylko 4,4:1) */
  --sk-final-accent:          #8FE3F7;   /* kreski napisu na niebieskim pasie */
  --sk-grad-text:   linear-gradient(120deg, #014EE6 0%, #014EE6 100%);
  --sk-grad-light:  linear-gradient(120deg, #8FE3F7 0%, #00C8E6 100%);
  /* panel (KV-KADRA, po review): imię na niebieskim pasku `--g-panel` - od bieli do jasnego
     cyjanu (>= 4,9:1 na #0A62C7; --sk-grad-light ma na końcu tylko 2,9:1) */
  --sk-grad-on-blue: linear-gradient(120deg, #FFFFFF 0%, #C8F3FC 100%);
  /* kod błędu na jasnym tle: ciemniejsza wersja gradientu tytułów (>= 4,1:1 na #F6F8FA) */
  --sk-grad-deep:   linear-gradient(120deg, #0954AA 0%, #1E74EE 100%);
  --sk-grad-price:  linear-gradient(120deg, #014EE6 0%, #0035A8 100%);   /* STRONA-V2: cena bez cyjanu (cyjan nie jest kolorem tekstu) */
  --sk-grad-tab:    linear-gradient(90deg, #0A62C7 0%, #1E74EE 100%);
  --sk-grad-kick:   linear-gradient(90deg, #0A62C7, #00B9D6);
  --sk-grad-kick-r: linear-gradient(90deg, #00B9D6, #0A62C7);
  --sk-grad-badge:  linear-gradient(90deg, #0A62C7 0%, #00B9D6 100%);
  --sk-grad-perk-1: linear-gradient(135deg, #19B36B 0%, #007E46 100%);
  --sk-grad-perk-2: linear-gradient(135deg, #8B6BF0 0%, #5330C4 100%);
  --sk-grad-perk-3: linear-gradient(135deg, #F5A623 0%, #E8940A 100%);
  --sk-grad-featured: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 100%);
  --sk-hdr-bg: #FFFFFF;   /* STRONA-V2: płaskie tło jak na stronie */
  --sk-final-bg: #141B4E;   /* STRONA-V2: płaskie tło jak na stronie */
  --sk-ftr-bg: #FFFFFF;   /* STRONA-V2: płaskie tło jak na stronie */
  --sk-shadow-card:     0 1px 0 rgba(20, 27, 78, 0.04), 0 18px 40px -24px rgba(20, 27, 78, 0.22);
  --sk-shadow-featured: 0 0 0 1.5px #DCE6F7, 0 30px 60px rgba(20, 27, 78, 0.14);
  --sk-shadow-primary:  0 4px 0 #0035A8;
  --sk-shadow-len:      0 8px 20px -12px rgba(10, 98, 199, 0.45);
  /* CENNIK-W-PANELU (21.10): tabela cennika 1:1 z /cennik strony (CENNIK-TABELA, .sp-tab) */
  --sk-line-strong:     #BFD0EE;   /* obwódka przycisku „Wybieram" przy lekcji pojedynczej */
  --sk-wa:              #15803D;
  --sk-on-blue-muted:   rgba(255, 255, 255, 0.88);   /* tekst pomocniczy na --sk-help-bg */   /* WhatsApp: ciemniejszy niż #1FAF38 strony - biały tekst 5,0:1 */
  --sk-grad-slate:      linear-gradient(135deg, #141B4E 0%, #2E3A86 100%);   /* STRONA-V2: granat zamiast szarości */
  --sk-grad-rec:        linear-gradient(100deg, #FFFFFF 0%, #FFFFFF 100%);
  --sk-help-bg: #141B4E;   /* STRONA-V2: płaskie tło jak na stronie */
  --sk-shadow-row-hover: 0 30px 56px -28px rgba(13, 18, 26, 0.38);
  --sk-shadow-chip:     0 8px 16px -12px rgba(13, 18, 26, 0.35);
  --sk-shadow-step:     0 16px 32px -22px rgba(13, 18, 26, 0.28);
  --sk-shadow-help:     0 30px 60px -28px rgba(10, 98, 199, 0.6);
  --sk-shadow-help-btn: 0 18px 36px -12px rgba(2, 20, 60, 0.55);
  --sk-shadow-tile-blue:   0 12px 24px -10px rgba(10, 98, 199, 0.6);
  --sk-shadow-tile-slate:  0 12px 24px -10px rgba(13, 18, 26, 0.45);
  --sk-shadow-tile-violet: 0 12px 24px -10px rgba(83, 48, 196, 0.55);
  --sk-shadow-tile-green:  0 12px 24px -10px rgba(0, 126, 70, 0.55);
  --sk-shadow-tile-orange: 0 12px 24px -10px rgba(245, 166, 35, 0.6);
  /* Gradienty kafelków z ikoną. W zestawie stała kolejność: blue, violet,
     orange, green, cyan, pink. Niosą białą ikonę albo cyfrę, nie tekst. */
  --g-blue:   linear-gradient(135deg, #014EE6 0%, #014EE6 100%);   /* PANEL-V2: płaskie kafle jak na stronie */
  --g-green:  linear-gradient(135deg, #0E7C86 0%, #0E7C86 100%);
  --g-violet: linear-gradient(135deg, #5B3CC4 0%, #5B3CC4 100%);
  --g-orange: linear-gradient(135deg, #D97F06 0%, #D97F06 100%);
  --g-cyan:   linear-gradient(135deg, #00869C 0%, #00869C 100%);
  --g-pink:   linear-gradient(135deg, #C2255C 0%, #C2255C 100%);
  /* Panel marki (hero, baner płatności, panel logowania, nagłówek kursu). KV-STRONA-2 (05.11, właściciel: „KV
     aplikacji jak strony"): granatowa scena strony z tokenów `--zs-scene-*` - kratka cyjanowa co 28 px nad
     poświatą w prawym górnym rogu, pod spodem granat (wcześniej PANEL-V2: płaski niebieski #014EE6 w białą
     kratkę). Kolejność warstw jak w scenach sklepu. Bez wersji html.dark - scena jest granatowa w obu motywach,
     w ciemnym dostaje obwódkę (app.css, KV-STRONA-2). */
  --g-panel:
    linear-gradient(var(--zs-scene-grid) 1px, transparent 1px) 0 0 / 28px 28px,
    linear-gradient(90deg, var(--zs-scene-grid) 1px, transparent 1px) 0 0 / 28px 28px,
    var(--zs-scene-glow),
    var(--zs-scene-bg);
  /* Ta sama poświata dla jasnych nagłówków (logowanie) - bez tekstu na niej. */
  --g-glow-light:
    radial-gradient(ellipse 700px 460px at 12% 10%, rgba(10, 98, 199, 0.12), transparent 70%),
    radial-gradient(ellipse 640px 440px at 88% 70%, rgba(0, 185, 214, 0.10), transparent 70%);
  --grid-line:                rgba(1, 78, 230, 0.07);   /* kratka „zeszytu" (PANEL-V2: jak --zs-grid) */
  /* Boczny margines strony - patrz .page. Paski pełnej szerokości (.stats,
     .filters) liczą z tego swój ujemny margines, więc gutter MUSI być jedną
     wartością, a nie liczbą przepisaną w kilku miejscach. Nadpisywany
     w breakpointach razem z paddingiem .page. */
  --page-gutter:              32px;
  /* Tła */
  --bg:                       var(--brand-bg);
  --surface:                  oklch(1 0 0);
  --surface-1:                oklch(0.983 0.005 260);
  --surface-2:                oklch(0.972 0.007 260);
  --surface-3:                oklch(0.962 0.009 260);
  --surface-4:                oklch(0.952 0.011 260);
  --surface-5:                oklch(0.942 0.013 260);

  /* Bordery */
  --border:                   var(--brand-line);
  --border-strong:            var(--brand-line-strong);
  --outline:                  oklch(0.73 0.009 260);
  --outline-variant:          oklch(0.90 0.006 260);
  --field-border:             var(--brand-field);   /* obrys pól: >= 3:1 do białego */

  /* Tekst */
  --text:                     var(--brand-ink);
  --text-2:                   var(--brand-ink-muted);
  --text-3:                   var(--brand-ink-soft);

  /* Primary (marka) */
  --primary:                  var(--brand-blue);
  --primary-hover:            var(--brand-blue-hover);
  --primary-pressed:          var(--brand-blue-press);
  --on-primary:               oklch(1 0 0);
  --primary-container:        var(--brand-blue-soft);
  --on-primary-container:     var(--brand-blue-text);
  --primary-ring:             var(--brand-blue-100);   /* fokus pól i przycisków */

  /* Accent alias */
  --accent:                   var(--primary);
  --accent-hover:             var(--primary-hover);
  --accent-fg:                var(--on-primary);
  --accent-cyan:              var(--brand-cyan);   /* dekoracja / gradient */
  /* Wyróżnienie (polecany pakiet, plakietka "Najczęstszy wybór"): 0-1 na ekran. */
  --highlight:                var(--brand-cyan);
  --highlight-soft:           var(--brand-cyan-soft);
  --highlight-line:           var(--brand-cyan-100);
  --highlight-text:           var(--brand-cyan-text);

  /* Surface tint */
  --surface-tint:             oklch(0.52 0.17 255 / 0.05);

  /* State layers */
  --state-hover:              oklch(0.18 0.018 260 / 0.055);
  --state-focus:              oklch(0.18 0.018 260 / 0.09);
  --state-pressed:            oklch(0.18 0.018 260 / 0.12);
  --state-hover-primary:      oklch(0.52 0.17 255 / 0.08);
  --state-focus-primary:      oklch(0.52 0.17 255 / 0.13);

  /* Semantic colors — status ledów */
  --c-new:                    oklch(0.50 0.20 260);
  --c-new-bg:                 oklch(0.93 0.05 260);
  --c-prog:                   oklch(0.52 0.14 60);
  --c-prog-bg:                oklch(0.95 0.06 70);
  --c-ok:                     oklch(0.50 0.13 155);
  --c-ok-bg:                  oklch(0.94 0.06 155);
  --c-rej:                    oklch(0.52 0.18 25);
  --c-rej-bg:                 oklch(0.95 0.04 25);
  /* warn (pomarańcz, hue 55) — panel rodzica: „oczekuje/do zapłaty”, streak,
     egzamin „wkrótce”. Wcześniej literały oklch(0.72 0.18 55) — 2.6:1 na bieli. */
  --c-warn:                   oklch(0.52 0.15 55);
  --c-warn-bg:                oklch(0.95 0.06 55);

  /* Kalendarz (14.09, zgłoszenie „kolory bardziej rozróżnialne"): każdy status
     ma własny odcień - wcześniej zaplanowana i przełożona były tym samym
     niebieskim, a nieobecność szara. Tokeny, więc dark mode dostaje swoje. */
  --cal-pending:              oklch(0.50 0.23 262);
  --cal-done:                 oklch(0.55 0.15 150);
  --cal-rescheduled:          oklch(0.52 0.20 305);
  --cal-skipped:              oklch(0.55 0.21 25);
  --cal-trial:                oklch(0.50 0.11 195);   /* biały tekst 12px: 5,5:1 */
  --c-star:                   oklch(0.66 0.16 65);    /* gwiazdki ocen: 3,2:1 na białym */
  --cal-booking:              oklch(0.64 0.17 60);
  --cal-av:                   oklch(0.74 0.15 150 / 0.34);
  --cal-off:                  oklch(0.62 0.21 25 / 0.26);
  --cal-busy:                 oklch(0.50 0.03 260 / 0.30);
  --cal-ev-text:              oklch(1 0 0);

  /* Shape - zaokrąglenia. KV-APP 08.10: przyciski i pola 10, karty 16, modale
     i hero 20, chipy i plakietki pigułka. Strona ma 20-24 na kartach i pigułki na
     przyciskach - to skala landingu; w narzędziu z gęstymi listami (właściciel:
     „ma wyglądać premium, high-tech") ciaśniejsze rogi czytają się precyzyjniej.
     Nic na kartach i przyciskach poniżej 8 px; --shape-xs dla drobnicy (kbd). */
  --shape-xs:                 6px;
  --shape-sm:                 8px;
  --shape-md:                 10px;
  --shape-lg:                 18px;   /* KV-APP-KARTY 12.10: jak karty sklepu (było 16) */
  --shape-xl:                 20px;
  --shape-full:               999px;
  --radius:                   var(--shape-md);
  --radius-sm:                var(--shape-sm);

  /* Cienie */
  --elev-1:   0 1px 2px oklch(0 0 0 / 0.04), 0 1px 4px oklch(0.52 0.17 255 / 0.05);
  --elev-2:   0 2px 6px oklch(0 0 0 / 0.05), 0 4px 16px oklch(0.52 0.17 255 / 0.07);
  --elev-3:   0 4px 12px oklch(0 0 0 / 0.06), 0 12px 32px oklch(0.52 0.17 255 / 0.10);
  --elev-4:   0 8px 24px oklch(0 0 0 / 0.08), 0 24px 48px oklch(0.52 0.17 255 / 0.12);
  --shadow-1: var(--elev-1);
  --shadow-2: var(--elev-2);
  --shadow-3: var(--elev-3);
  --shadow-drawer: -16px 0 40px -8px oklch(0.52 0.17 255 / 0.12);
  /* Cienie (KV-APP 08.10): warstwowe i ciche - ostra krawędź 1px + krótki cień
     kontaktowy + rozmyty cień głębi. Strona ma długie cienie 40-60 px; w panelu
     z dziesiątkami kart dawały „mgłę" pod każdą. Niebieski cień tylko pod
     głównym przyciskiem i niebieskim panelem. */
  --shadow-xs:         0 1px 2px rgba(13, 18, 26, 0.06);
  /* KV-APP-KARTY 12.10: miękki cień z niebieskim odcieniem marki, jak karty sklepu. */
  --shadow-card:       0 1px 2px rgba(15, 27, 45, 0.04), 0 8px 24px -6px rgba(10, 98, 199, 0.10);
  --shadow-card-hover: 0 2px 6px rgba(15, 27, 45, 0.06), 0 18px 40px -12px rgba(10, 98, 199, 0.20);
  --shadow-card-lg:    0 2px 6px rgba(13, 18, 26, 0.05), 0 24px 56px -24px rgba(13, 18, 26, 0.30);
  /* Główny przycisk: wewnętrzne światło u góry + cień kontaktowy + niebieska poświata. */
  --shadow-primary:    inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 1px 2px rgba(13, 18, 26, 0.12), 0 6px 16px -6px rgba(10, 98, 199, 0.55);
  --shadow-primary-lg: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 2px 4px rgba(13, 18, 26, 0.12), 0 10px 24px -8px rgba(10, 98, 199, 0.60);
  --shadow-panel:      inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 18px 40px -20px rgba(10, 98, 199, 0.55);
  --shadow-highlight:  0 6px 18px rgba(0, 185, 214, 0.25);
  --shadow-tile:       0 10px 20px -8px rgba(10, 98, 199, 0.50);

  /* Motion — spring-like */
  --motion-fast:  140ms;
  --motion-std:   220ms;
  --motion-slow:  360ms;
  --ease-std:     cubic-bezier(0.23, 1, 0.32, 1);   /* emil: mocny ease-out, bez bounce */
  --ease-emph:    cubic-bezier(0.2, 0, 0, 1.05);
  --ease-decel:   cubic-bezier(0.05, 0.7, 0.1, 1);
  --ease-spring:  cubic-bezier(0.3, 1.6, 0.5, 1);    /* „pop" odznak i wyników */

  /* (scalone z bazy przy refaktorze tokenów) */
  --elev-0:                   none;
  --elev-5:                   0 24px 48px -12px oklch(0 0 0 / 0.18), 0 12px 24px -8px oklch(0 0 0 / 0.10);
  --danger:                   var(--c-rej);
  --success:                  var(--c-ok);
  --warning:                  var(--c-prog);
  --text-muted:               var(--text-3);
  --sidebar-w:                260px;
  --topbar-h:                 60px;
  --drawer-w:                 560px;
  --bottom-nav-h:             64px;

  /* Gradient marki + easing (scalone z dawnych osobnych :root) */
  /* Paski postępu i podkreślenia: niebieski w cyjan (bez tekstu na nim). */
  --grad: linear-gradient(90deg, var(--primary) 0%, var(--accent-cyan) 100%);
  --grad-soft: linear-gradient(120deg, oklch(0.50 0.17 262 / 0.14), oklch(0.72 0.13 214 / 0.12));
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1); --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* Kolory zewnętrznych marek (jedyne poza --brand-*) */
  --c-whatsapp:               #25D366;
  --c-whatsapp-hover:         #1EBE5B;

  /* Typografia (UI-01): skala zamiast 33 rozmiarów px. Adopcja w app.css
     idzie stopniowo (zadanie 4.3); nowe reguły używają tokenów.
     KV-APP 08.10: krój strony (Montserrat, self-host, latin-ext). Skala
     rozmiarów zostaje panelowa (gęste listy i tabele kadry) - ze strony
     bierzemy krój, grube nagłówki i ciasne światło liter, nie 60 px. */
  --font-sans:                "Montserrat", "Montserrat Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;   /* PLYNNOSC-FONTY: zastępczy z size-adjust (vendor/montserrat.css) */
  --fs-2xs: 10px; --fs-xs: 11px; --fs-sm: 12px; --fs-base: 13px; --fs-md: 14px;
  --fs-lg: 16px; --fs-xl: 18px; --fs-2xl: 22px; --fs-3xl: 28px; --fs-display: 40px;
  --lh-tight: 1.2; --lh-base: 1.5;
  --fw-regular: 400; --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700; --fw-black: 800;
  --fw-heavy: 900;                        /* tytuły stron, liczby KPI, hero */
  --ls-tight: -0.015em; --ls-display: -0.03em; --ls-caps: 0.1em;

  /* Odstępy: siatka 4 px */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px;
  --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;

  /* z-index: nazwane szczeble zamiast gołych liczb (wartości = dotychczasowe,
     żeby kolejność warstw się nie zmieniła; lokalne 1/2/5/-1 wewnątrz
     komponentów zostają literałami) */
  --z-sticky: 20; --z-popover: 25; --z-dropdown: 30; --z-topbar: 30;
  --z-bottom-nav: 35; --z-nav-overlay: 40; --z-drawer: 45; --z-sidebar: 50;
  --z-toast: 100; --z-palette: 200; --z-skip: 9999;

  /* Breakpointy (dokumentacja - CSS nie czyta var() w @media): 360 / 600 / 900 / 1100 */

  /* LAB-4: wydruk kartkówki (A4) - stałe kolory papieru, NIEZALEŻNE od motywu
     (bez odpowiednika w html.dark): atrament i akcent marki jak w druku SOLVE Lab. */
  --print-ink: #101735; --print-accent: #00a9be; --print-paper: #ffffff; --print-desk: #eef1f5;
  --print-mute: #4b5563; --print-soft: #6b7280; --print-line: #d1d5db; --print-grid: #dcdcdc;
  --print-key-bg: #f3f4f6; --print-grading: #374151; --print-shadow: rgba(16, 23, 53, .12);
}

/* ---------- DARK MODE ---------- */
html.dark {
  color-scheme:               dark;
  /* PANEL-V2-CIEMNY (29.10): barwy z sekcji „Marka" (--brand-navy-*), granat strony zamiast grafitu.
     Historia - KV-APP 08.10 (zgłoszenie właściciela: „motyw ciemny jest zbyt ciemny"):
     grafit z granatowym odcieniem zamiast prawie-czerni (tło było L 0,095 ≈ #030508,
     teraz L 0,25 ≈ #1C222B, karty #252C36). Pary tekst/tło policzone: text-3 na
     karcie 7:1, obwódka pola 4,2:1, statusy >= 6,7:1. */
  --bg:                       var(--brand-navy-bg);
  --surface:                  var(--brand-navy-card);
  --surface-1:                var(--brand-navy-1);
  --surface-2:                var(--brand-navy-2);
  --surface-3:                var(--brand-navy-3);
  --surface-4:                var(--brand-navy-4);
  --surface-5:                var(--brand-navy-5);

  --border:                   var(--brand-navy-line);
  --border-strong:            var(--brand-navy-line-strong);
  --outline:                  var(--brand-navy-line-strong);
  --outline-variant:          var(--brand-navy-line);
  --field-border:             var(--brand-navy-field);

  --text:                     var(--brand-navy-text);
  --text-2:                   var(--brand-navy-text-2);
  --text-3:                   var(--brand-navy-text-3);

  --primary:                  var(--brand-navy-blue);
  --primary-hover:            var(--brand-navy-blue-hover);
  --primary-pressed:          var(--brand-navy-blue-press);
  --on-primary:               var(--brand-navy-bg);
  --primary-container:        var(--brand-navy-blue-soft);
  --on-primary-container:     var(--brand-navy-blue-text);
  --primary-ring:             oklch(0.800 0.140 255 / 0.45);

  --highlight-soft:           oklch(0.35 0.06 210);
  --highlight-line:           oklch(0.52 0.09 210);
  --highlight-text:           oklch(0.88 0.10 210);

  --accent:                   var(--primary);
  --accent-fg:                var(--on-primary);

  --surface-tint:             oklch(0.800 0.140 255 / 0.07);

  --state-hover:              oklch(1 0 0 / 0.07);
  --state-focus:              oklch(1 0 0 / 0.11);
  --state-pressed:            oklch(1 0 0 / 0.15);
  --state-hover-primary:      oklch(0.800 0.140 255 / 0.10);
  --state-focus-primary:      oklch(0.800 0.140 255 / 0.16);

  --c-new:    oklch(0.85 0.12 260);  --c-new-bg:  oklch(0.35 0.08 260);
  --c-prog:   oklch(0.85 0.12 70);   --c-prog-bg: oklch(0.35 0.06 75);
  --c-ok:     oklch(0.85 0.12 155);  --c-ok-bg:   oklch(0.35 0.06 155);
  --c-rej:    oklch(0.85 0.11 25);   --c-rej-bg:  oklch(0.35 0.08 25);
  --c-warn:   oklch(0.86 0.13 55);   --c-warn-bg: oklch(0.35 0.06 55);

  --cal-pending: oklch(0.68 0.16 262);  --cal-done: oklch(0.72 0.14 150);
  --cal-rescheduled: oklch(0.70 0.16 305);  --cal-skipped: oklch(0.70 0.17 25);
  --c-star: oklch(0.82 0.18 75);
  --cal-trial: oklch(0.72 0.10 195);  --cal-booking: oklch(0.80 0.15 60);
  --cal-av: oklch(0.70 0.15 150 / 0.24);  --cal-off: oklch(0.66 0.18 25 / 0.24);
  --cal-busy: oklch(0.78 0.02 260 / 0.20);  --cal-ev-text: oklch(0.16 0.02 260);

  --elev-1: 0 1px 2px oklch(0 0 0 / 0.20), 0 1px 4px oklch(0 0 0 / 0.15);
  --elev-2: 0 2px 6px oklch(0 0 0 / 0.25), 0 4px 16px oklch(0 0 0 / 0.20);
  --elev-3: 0 4px 12px oklch(0 0 0 / 0.30), 0 12px 32px oklch(0 0 0 / 0.25);

  /* Cienie strony w ciemnym motywie: czarne, bez niebieskiego zabarwienia. */
  /* Krawędź światła u góry karty zamiast ciemnego cienia - na grafitowym tle
     cień ginie, a 1px jaśniejszej linii daje głębię. */
  --shadow-card:       inset 0 1px 0 oklch(1 0 0 / 0.04), 0 1px 2px oklch(0 0 0 / 0.25), 0 12px 28px -16px oklch(0 0 0 / 0.45);
  --shadow-card-hover: inset 0 1px 0 oklch(1 0 0 / 0.06), 0 2px 4px oklch(0 0 0 / 0.30), 0 20px 40px -18px oklch(0 0 0 / 0.55);
  --shadow-card-lg:    inset 0 1px 0 oklch(1 0 0 / 0.05), 0 24px 56px -24px oklch(0 0 0 / 0.60);
  --shadow-xs:         0 1px 2px oklch(0 0 0 / 0.30);
  --shadow-primary:    inset 0 1px 0 oklch(1 0 0 / 0.25), 0 1px 2px oklch(0 0 0 / 0.30), 0 6px 16px -6px oklch(0 0 0 / 0.45);
  --shadow-primary-lg: inset 0 1px 0 oklch(1 0 0 / 0.30), 0 2px 4px oklch(0 0 0 / 0.30), 0 10px 24px -8px oklch(0 0 0 / 0.50);
  --shadow-panel:      inset 0 1px 0 oklch(1 0 0 / 0.12), 0 18px 40px -20px oklch(0 0 0 / 0.60);
  --shadow-tile:       0 10px 20px -10px oklch(0 0 0 / 0.60);
  --grid-line:         rgba(127, 231, 247, 0.05);
  --g-glow-light:
    radial-gradient(ellipse 700px 460px at 12% 10%, oklch(0.75 0.18 260 / 0.10), transparent 70%),
    radial-gradient(ellipse 640px 440px at 88% 70%, oklch(0.80 0.12 210 / 0.07), transparent 70%);
  /* PANEL-V2-CIEMNY: cień „klawisza" z ciemniejszego niebieskiego akcji, cienie kart czarne. */
  --zs-key:            0 4px 0 color-mix(in srgb, var(--primary) 50%, black);
  --zs-key-down:       0 2px 0 color-mix(in srgb, var(--primary) 50%, black);
  --zs-shadow:         0 1px 0 rgba(0, 0, 0, 0.25), 0 18px 40px -24px rgba(0, 0, 0, 0.7);
  --zs-shadow-lift:    0 0 0 1.5px var(--border-strong), 0 30px 60px rgba(0, 0, 0, 0.45);
}

