/* =====================================================================
   ArtOn 2026 – ui.css · FUNDAMENT (właściciel: T1)
   Wspólny język wizualny panelu, portalu i stron publicznych. Ładowany po motion.css
   (w wydarzenia-zapis.html po inline <style>) na 9 stronach. SPEC 1, 2.1–2.7, 2.11, 2.12,
   2.16, 2.18, 2.20, 9, 10, 11.

   Zasady (KONTRAKT-ZBIORCZY):
   - kolory WYŁĄCZNIE z istniejących tokenów style.css – tu tylko aliasy i przezroczystości,
   - nadpisania starych arkuszy mają prefiks :root (+ to samo ID co oryginał),
   - display zmieniamy tylko w stanach „pokazany”, [hidden] i .hidden zawsze chowają,
   - wejścia z animation-fill-mode: backwards (po animacji działa transform z hovera i gestu),
   - wyjście okna 240 ms na samym .modal-backdrop (limit JS 320 ms), toastu 200 ms na #toast (limit 260 ms),
   - z-index: okna 50–59, alert 58, #cal-pop 60, HUD 99, toast 100,
   - próg telefonu (max-width: 700px) / (min-width: 701px) jak isMobileCal().

   Dla właścicieli E2 (T2a, T2b, T3, T4):
   - PRZYCISKI. Zestaw standardowy (STD) = <button> bez klasy albo z klasą .small / .primary / .danger / .ghost,
     poza .btn i poza kontenerami nawigacji, segmentów, kalendarza i Obecny/Nieobecny:
       button:where(:not([class]), .small, .primary, .danger, .ghost)
             :where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *))
     Zwykły = tinted, .primary = filled, .danger = destructive, .ghost = plain, drugi przycisk w stopce okna = szary.
     Kolory idą przez zmienne --btn-bg / --btn-fg / --btn-bg-h (hover) / --btn-bg-a (wciśnięcie) / --btn-sh / --btn-r.
     W swoim arkuszu wystarczy ustawić zmienne, np. :root #pay-today { --btn-bg: var(--c-fill); --btn-fg: var(--c-text); }.
     :where() nie podnosi specyficzności – reguły kontekstowe z panel.css / rodzic.css / public.css
     (np. main .pay-row .small, #att-actions .small) dalej wygrywają, dopóki właściciel ekranu ich nie przejmie.
   - OKNO. .modal ma padding var(--m-pad) (24 px komputer, 16 px telefon) i odstęp var(--m-gap).
     .c-sheet-head i .c-sheet-foot wychodzą na krawędzie ujemnym marginesem – element pełnej szerokości
     robi to samo: margin-inline: calc(-1 * var(--m-pad)).
   - KCIUKI. ui.js ustawia na kontenerze segmentu --thumb-x / --thumb-w (soczewka paska kart: --lens-x / --lens-w),
     a na czas pozycjonowania bez animacji klasę .ui-no-anim. Wygląd kciuka (::before) – w arkuszu ekranu.
   ===================================================================== */

:root {
  /* --- 1. Role kolorów (aliasy istniejących tokenów, zero nowych wartości) --- */
  --c-canvas: var(--bg);                 /* #f3effa – tło aplikacji */
  --c-surface: var(--panel);             /* #fff – karty, listy, arkusze */
  --c-fill: var(--n-100);                /* #f3f1f7 – pola, tory segmentów */
  --c-fill-ink: rgba(var(--ink), .06);   /* tor segmentu na tle strony */
  --c-tint-bg: var(--lav-100);           /* #efeaf8 – tinted, soczewka paska kart */
  --c-press: var(--lav-50);              /* #f7f4fc – wciśnięty wiersz */
  --c-sep: var(--hairline);              /* rgba(43,38,55,.08) – linie w listach */
  --c-sep-strong: var(--n-200);
  --c-text: var(--n-800);                /* 13,6:1 */
  --c-text-2: var(--n-600);              /* 5,6:1 */
  --c-text-3: var(--n-500);              /* tylko placeholdery i dekoracje */
  --c-accent: var(--lav-600);            /* #7d68a8 – przyciski filled (biel 4,75:1) */
  --c-accent-text: var(--lav-700);       /* #62509a – linki, tinted, plain (6,7:1) */
  --c-title: var(--lav-800);             /* #4a3a73 – duże tytuły (9,8:1) */
  --c-shell: var(--header-bg);           /* #a794c0 – kolor logo, decyzja właściciela (D1) */
  --c-on-shell: #fff;
  --c-on-shell-2: rgba(255, 255, 255, .85);
  --c-shell-fill: rgba(36, 28, 61, .2);  /* = pigułka „Wyloguj” (style.css .logout-link) */
  --c-shell-fill-2: rgba(36, 28, 61, .3);
  --c-shell-line: rgba(255, 255, 255, .45);
  --c-scrim: rgba(28, 24, 36, .42);      /* = tło okna w style.css */
  /* karta-hero: biały tekst ≥ 4,5:1 (T7, audyt kontrastu – lav-600 → lav-700 daje 4,75–6,7:1), rozjaśnienie w kolorze logo
     o stałym rozmiarze tylko w prawym górnym rogu – przy 390 px nie sięga końca etykiety (SPEC 1.1 miało lav-500 → lav-600
     z rozjaśnieniem do 58 % szerokości – etykieta 3,5–3,8:1) */
  --c-hero: radial-gradient(140px 110px at 100% 0%, #a794c0 0%, rgba(167, 148, 192, 0) 100%),
            linear-gradient(160deg, var(--lav-600) 0%, var(--lav-700) 70%);
  /* kafelki kategorii – kolory z icons/*.svg (kropki legend, kafelki rysowane w CSS) */
  --tile-blue: #3B7DF7; --tile-teal: #2AA79B; --tile-green: #34B65C; --tile-orange: #F5921E;
  --tile-red: #E8484E; --tile-indigo: #5D5FEF; --tile-rose: #E0559A; --tile-slate: #6B7280;

  /* --- 2. Typografia (skala iOS) --- */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", system-ui, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Inter", "Segoe UI", system-ui, sans-serif;
  --font-logo: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-logo-sub: "Inter", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;   /* „studio” skalibrowane pod Inter */
  --t-large:    700 34px/41px var(--font-display);  --tr-large: -0.022em;
  --t-title1:   700 28px/34px var(--font-display);  --tr-title1: -0.02em;
  --t-title2:   700 22px/28px var(--font-display);  --tr-title2: -0.016em;
  --t-title3:   600 20px/25px var(--font-display);  --tr-title3: -0.014em;
  --t-headline: 600 17px/22px var(--font-sans);     --tr-headline: -0.012em;
  --t-body:     400 17px/22px var(--font-sans);     --tr-body: -0.012em;
  --t-callout:  400 16px/21px var(--font-sans);
  --t-subhead:  400 15px/20px var(--font-sans);     --tr-subhead: -0.006em;
  --t-footnote: 400 13px/18px var(--font-sans);
  --t-caption:  500 12px/16px var(--font-sans);
  --t-caption2: 600 11px/13px var(--font-sans);     --tr-caps: 0.06em;

  /* --- 3. Odstępy (te same wartości co --s-* w style.css) --- */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px; --s-12: 48px;

  /* --- 4. Promienie (--r-xs / -sm / -md / -pill = wartości ze style.css) --- */
  --r-xs: 6px; --r-sm: 8px; --r-md: 10px; --r-ctl: 12px; --r-btn-lg: 14px;
  --r-card: 20px; --r-sheet: 28px; --r-pill: 999px; --r-tile: 23.5%;

  /* --- 5. Elewacje --- */
  --el-1: 0 0 0 .5px rgba(var(--ink), .05), 0 1px 2px rgba(var(--lav-rgb), .07), 0 8px 24px -18px rgba(var(--lav-rgb), .35);
  --el-2: var(--sh-2);
  --el-3: var(--sh-3);
  --el-float: 0 0 0 .5px rgba(var(--ink), .07), 0 12px 32px -12px rgba(var(--ink), .32), 0 2px 8px rgba(var(--ink), .06);
  --el-tile: 0 1px 1px rgba(var(--ink), .08), 0 6px 14px -8px rgba(var(--ink), .45);

  /* --- 6. Materiały --- */
  --glass-bar: rgba(255, 255, 255, .78);
  --glass-tint: rgba(247, 244, 252, .9);
  --glass-canvas: rgba(243, 239, 250, .86);
  --glass-dark: rgba(51, 42, 78, .94);    /* = lav-900, tło toastu */
  --glass-blur: blur(22px) saturate(180%);

  /* --- 7. Ruch – sprężyny Apple (wzorzec/narzedzia/sprezyny.mjs) --- */
  --spring: linear(0, 0.079 6%, 0.237 13%, 0.405 19%, 0.553 25%, 0.673 31%, 0.766 38%, 0.834 44%, 0.884 50%, 0.92 56%, 0.945 63%, 0.963 69%, 0.975 75%, 0.983 81%, 0.989 88%, 0.992 94%, 1);
  --spring-bounce: linear(0, 0.038 4%, 0.13 8%, 0.249 13%, 0.375 17%, 0.498 21%, 0.609 25%, 0.706 29%, 0.787 33%, 0.852 38%, 0.902 42%, 0.941 46%, 0.969 50%, 0.988 54%, 1.001 58%, 1.009 63%, 1.013 67%, 1.015 71%, 1.015 75%, 1.014 79%, 1.012 83%, 1.01 88%, 1.008 92%, 1.007 96%, 1);
  --spring-pop: linear(0, 0.037 4%, 0.127 8%, 0.247 13%, 0.379 17%, 0.509 21%, 0.63 25%, 0.735 29%, 0.824 33%, 0.895 38%, 0.95 42%, 0.989 46%, 1.017 50%, 1.034 54%, 1.043 58%, 1.046 63%, 1.045 67%, 1.041 71%, 1.036 75%, 1.03 79%, 1.024 83%, 1.018 88%, 1.013 92%, 1.009 96%, 1);
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-standard: cubic-bezier(.25, .1, .25, 1);
  --ease-exit-ios: cubic-bezier(.32, 0, .67, 0);   /* nowa nazwa – stare --ease-exit zostaje dla motion.css */
  --d-press: 90ms;       /* wciśnięcie */
  --d-snappy: 350ms;     /* damping 1, response .30 – kciuki, wskaźniki, chevron, przełącznik */
  --d-sheet: 410ms;      /* damping 1, response .35 – arkusz, soczewka, kalendarz, toast */
  --d-soft: 470ms;       /* damping 1, response .40 – panele, paski */
  --d-bounce: 460ms;     /* damping .8 – tylko po geście, toast */
  --d-pop: 330ms;        /* damping .7 – elementy < 40 px */
  --d-exit: 240ms;       /* wyjście okna ≤ 320 ms (afterExit) */
  --d-exit-toast: 200ms; /* ≤ 260 ms */

  /* --- 8. Wymiary --- */
  --ctl-s: 32px; --ctl-m: 40px; --ctl-l: 50px; --field-h: 44px; --hit: 44px;
  --sa-t: env(safe-area-inset-top, 0px);
  --sa-b: env(safe-area-inset-bottom, 0px);
  --m-pad: 24px;        /* wewnętrzny margines okna (telefon 16 px) */
  --m-gap: 12px;        /* odstęp między blokami okna */
}
@supports not (transition-timing-function: linear(0, 1)) {
  :root { --spring: var(--ease-out); --spring-bounce: cubic-bezier(.34, 1.4, .64, 1); --spring-pop: cubic-bezier(.34, 1.4, .64, 1); }
}
@media (max-width: 700px) {
  :root { --m-pad: 16px; }
}
@media (prefers-contrast: more) {
  :root { --c-shell: var(--lav-700); --c-text-2: var(--n-700); --c-sep: var(--n-300); --c-on-shell-2: #fff; }
}

/* =====================================================================
   BAZA
   ===================================================================== */
[hidden] { display: none !important; }                      /* kontrakt 0.4 */
:root { -webkit-tap-highlight-color: transparent; }
:root body { letter-spacing: var(--tr-subhead); }
/* logo bez zmian: Playfair „ArtOn” + „studio” w Inter (rozstrzelenie .313em skalibrowane pod Inter) */
:root .brand span, :root .portal-head .brand span, :root .arton-logo .al-sub { font-family: var(--font-logo-sub); }
.tnum { font-variant-numeric: tabular-nums; }
.c-sr { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* =====================================================================
   PRZYCISKI (SPEC 2.1) – zestaw standardowy STD (definicja w nagłówku pliku)
   ===================================================================== */
/* kształt i ruch – niska specyficzność (przegrywa z każdą regułą kontekstu, np. .msg-form button, .cal-nav button) */
button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)) {
  border-radius: var(--btn-r, var(--r-ctl));
  font-weight: 600; letter-spacing: -0.012em;
  -webkit-user-select: none; user-select: none; touch-action: manipulation;
  transition: transform var(--d-press) var(--ease-out), background-color 140ms var(--ease-standard), color 140ms var(--ease-standard),
              box-shadow 160ms var(--ease-standard), opacity 140ms var(--ease-standard);
}
button.small:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)) { --btn-r: var(--r-md); }

/* kolory – wariant ustawia zmienne, jedna reguła je rysuje */
:root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)) {
  --btn-bg: var(--c-tint-bg); --btn-fg: var(--c-accent-text); --btn-bg-h: var(--lav-200); --btn-bg-a: var(--lav-200); --btn-sh: none;
  background-color: var(--btn-bg); color: var(--btn-fg); border-color: transparent; box-shadow: var(--btn-sh);
}
/* filled */
:root button.primary:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)) {
  --btn-bg: var(--c-accent); --btn-fg: #fff; --btn-bg-h: var(--lav-700); --btn-bg-a: var(--lav-700); --btn-sh: var(--sh-accent);
}
/* destructive */
:root button.danger:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)) {
  --btn-bg: var(--red-50); --btn-fg: var(--red-600); --btn-bg-h: var(--red-200); --btn-bg-a: var(--red-200); --btn-sh: none;
}
/* plain */
:root button.ghost:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)) {
  --btn-bg: transparent; --btn-fg: var(--c-accent-text); --btn-bg-h: var(--lav-50); --btn-bg-a: transparent; --btn-sh: none;
}
/* szary – „Anuluj” / „Zamknij” obok akcji w stopce okna */
:root .modal .form-actions > button:not(.primary):not(.danger):where(:not([class]), .small, .ghost):where(:not(.btn)) {
  --btn-bg: var(--c-fill); --btn-fg: var(--c-text); --btn-bg-h: var(--n-200); --btn-bg-a: var(--n-200); --btn-sh: none;
}
/* hover – na dotyku tło bez zmian (stara reguła button:hover zostawiała obwódkę po stuknięciu) */
:root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):hover,
:root button.ghost:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):hover {
  background-color: var(--btn-bg); color: var(--btn-fg); border-color: transparent; box-shadow: var(--btn-sh);
}
@media (hover: hover) {
  :root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):hover,
  :root button.ghost:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):hover { background-color: var(--btn-bg-h); }
}
/* wciśnięcie: :active i .is-pressed (ui.js, min. 90 ms) – scale(.97) + ciemniejsze tło; plain = przezroczystość */
:root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):active:not(:disabled),
:root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)).is-pressed:not(:disabled) {
  background-color: var(--btn-bg-a); transform: scale(.97); transition-duration: var(--d-press);
}
:root button.ghost:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):active:not(:disabled),
:root button.ghost:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)).is-pressed:not(:disabled) { transform: none; opacity: .5; }
:root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):focus-visible { outline: none; box-shadow: var(--ring); }
:root button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):disabled {
  background-color: var(--n-200); color: var(--n-500); box-shadow: none; opacity: 1; transform: none;
}
:root button.ghost:where(:not(.btn, .c-seg *, .bottom-nav *, .cal-navgroup *, .cal-seg *, header nav *, .subnav *, .att-main *)):disabled { background-color: transparent; }

/* w trakcie wysyłki (.is-busy) – tekst gaśnie, spinner 18 px (biały na filled, lawendowy na pozostałych).
   #parents-refresh ma własny obrót ikony (motion.css). */
/* Bez przejścia koloru (T7, runda 2): Safari po wysłaniu formularza (nawigacja POST) przestaje odświeżać stronę, więc
   napis gasnący przez color .14s zostawał biały pod spinnerem („Zalo◌uj się”). Przezroczysty napis wchodzi od razu,
   przejścia skali, tła, cienia i krycia zostają (powrót z wciśnięcia .97 dalej płynny). */
:root button.is-busy:not(#parents-refresh) {
  position: relative; color: transparent !important; -webkit-text-fill-color: transparent; pointer-events: none;
  transition: transform var(--d-press) var(--ease-out), background-color 140ms var(--ease-standard), box-shadow 160ms var(--ease-standard), opacity 140ms;
}
:root button.is-busy:not(#parents-refresh) > :is(img, svg) { opacity: 0; }
:root button.is-busy:not(#parents-refresh)::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .45); border-top-color: #fff; animation: c-spin .7s linear infinite;
}
:root button.is-busy:not(.primary):not(.btn-filled):not(#parents-refresh)::after { border-color: var(--lav-200); border-top-color: var(--lav-700); }
/* withBusy (J12) ustawia też disabled – tło wariantu zostaje (inaczej reguły :disabled dają jasnoszare tło i biały spinner
   na .primary znika). !important – reguły :disabled w panel.css i widokach mają wyższą specyficzność */
:root button.is-busy:disabled:is(.primary, .btn-filled):not(#parents-refresh) { background-color: var(--btn-bg, var(--c-accent)) !important; box-shadow: none !important; opacity: 1 !important; }
:root button.is-busy:disabled:not(.primary):not(.btn-filled):not(#parents-refresh) { background-color: var(--btn-bg, var(--c-tint-bg)) !important; opacity: 1 !important; }

/* .btn – nowy komponent (markup E2): warianty filled / tinted / plain / gray / destructive / white / glass, rozmiary S / M / L */
:root .btn {
  --h: var(--ctl-m);
  --btn-bg: var(--c-tint-bg); --btn-fg: var(--c-accent-text); --btn-bg-h: var(--lav-200); --btn-bg-a: var(--lav-200); --btn-sh: none;
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: var(--h); min-height: 0; min-width: var(--h); padding: 0 16px; border: 0; border-radius: var(--r-ctl);
  background: var(--btn-bg); color: var(--btn-fg); box-shadow: var(--btn-sh); opacity: 1;
  font: 600 15px/1 var(--font-sans); letter-spacing: -0.012em; white-space: nowrap; text-decoration: none; cursor: pointer;
  -webkit-user-select: none; user-select: none; touch-action: manipulation;
  transition: transform var(--d-press) var(--ease-out), background-color 140ms var(--ease-standard), box-shadow 160ms var(--ease-standard), color 140ms, opacity 140ms;
}
:root .btn svg.ui { font-size: 17px; stroke-width: 2.1; }
:root .btn-s { --h: var(--ctl-s); padding: 0 12px; border-radius: var(--r-md); font-size: 13.5px; gap: 5px; }
:root .btn-s svg.ui { font-size: 15px; }
:root .btn-l { --h: var(--ctl-l); padding: 0 22px; border-radius: var(--r-btn-lg); font-size: 17px; }
:root .btn-block { display: flex; width: 100%; }
:root .btn-filled { --btn-bg: var(--c-accent); --btn-fg: #fff; --btn-bg-h: var(--lav-700); --btn-bg-a: var(--lav-700); --btn-sh: var(--sh-accent); }
:root .btn-tinted { --btn-bg: var(--c-tint-bg); --btn-fg: var(--c-accent-text); --btn-bg-h: var(--lav-200); --btn-bg-a: var(--lav-200); }
:root .btn-plain { --btn-bg: transparent; --btn-fg: var(--c-accent-text); --btn-bg-h: var(--lav-50); --btn-bg-a: transparent; padding: 0 10px; }
:root .btn-gray { --btn-bg: var(--c-fill); --btn-fg: var(--c-text); --btn-bg-h: var(--n-200); --btn-bg-a: var(--n-200); }
:root .btn-destructive { --btn-bg: var(--red-50); --btn-fg: var(--red-600); --btn-bg-h: var(--red-200); --btn-bg-a: var(--red-200); }
:root .btn-white { --btn-bg: #fff; --btn-fg: var(--lav-700); --btn-bg-h: var(--lav-50); --btn-bg-a: var(--lav-50); --btn-sh: 0 6px 16px -8px rgba(36, 28, 61, .5); }
:root .btn-glass { --btn-bg: rgba(255, 255, 255, .2); --btn-fg: #fff; --btn-bg-h: rgba(255, 255, 255, .28); --btn-bg-a: rgba(255, 255, 255, .32); --btn-sh: inset 0 0 0 1px rgba(255, 255, 255, .35); }
:root .btn-icon { width: var(--h); padding: 0; border-radius: 50%; }
:root .btn:hover { background: var(--btn-bg); color: var(--btn-fg); border-color: transparent; box-shadow: var(--btn-sh); text-decoration: none; }
@media (hover: hover) { :root .btn:hover { background: var(--btn-bg-h); } }
:root .btn:active, :root .btn.is-pressed { background: var(--btn-bg-a); transform: scale(.97); transition-duration: var(--d-press); }
:root .btn-plain:active, :root .btn-plain.is-pressed { transform: none; opacity: .5; }
:root .btn:focus-visible { outline: none; box-shadow: var(--ring); }
:root .btn:disabled, :root .btn[aria-disabled="true"] { background: var(--n-200); color: var(--n-500); box-shadow: none; transform: none; cursor: default; pointer-events: none; }
:root .btn-icon::after, .c-hit::after { content: ""; position: absolute; inset: min(0px, calc((var(--h, 44px) - var(--hit)) / 2)); } /* cel ≥ 44 px */
.c-hit { position: relative; }

/* link-przycisk (reset hasła, powrót z płatności, sukces zapisów) – filled bez „unoszenia” */
:root a.btn-link { border-radius: var(--r-ctl); background-color: var(--c-accent); box-shadow: var(--sh-accent); -webkit-user-select: none; user-select: none; transition: transform var(--d-press) var(--ease-out), background-color 140ms var(--ease-standard), box-shadow 160ms var(--ease-standard); }
@media (hover: hover) { :root a.btn-link:hover { background-color: var(--lav-700); transform: none; box-shadow: var(--sh-accent); text-decoration: none; } }
:root a.btn-link:active, :root a.btn-link.is-pressed { background-color: var(--lav-700); transform: scale(.97); transition-duration: var(--d-press); }
:root a.btn-link:focus-visible { outline: none; box-shadow: var(--ring); }

/* szybkie akcje – kafelek kategorii (biały glif na kolorze) + podpis (SPEC 2.2) */
.c-quick { display: grid; grid-template-columns: repeat(var(--qa-cols, 4), minmax(0, 1fr)); gap: 14px 6px; }
:root .c-qa {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 7px; min-width: 0;
  height: auto; padding: 2px 0; border: 0; border-radius: 0; background: none; box-shadow: none; cursor: pointer; white-space: normal;
  -webkit-user-select: none; user-select: none; touch-action: manipulation;
  font: 500 12px/14px var(--font-sans); letter-spacing: -0.005em; color: var(--c-text); text-align: center;
}
:root .c-qa:hover { background: none; }
:root .c-qa:active { transform: none; }
.c-qa img.ico, .c-qa .c-qa-tile { display: block; width: 50px; height: 50px; border-radius: 26%; box-shadow: var(--el-tile); transition: transform var(--d-press) var(--ease-out), filter 140ms, box-shadow 200ms var(--ease-out); }
.c-qa:active img.ico, .c-qa.is-pressed img.ico, .c-qa:active .c-qa-tile, .c-qa.is-pressed .c-qa-tile { transform: scale(.9); filter: brightness(.94); }
:root .c-qa:focus-visible { outline: none; box-shadow: none; }
.c-qa:focus-visible img.ico, .c-qa:focus-visible .c-qa-tile { box-shadow: var(--ring); }
/* najechanie myszą (T7, runda 2): kafelek unosi się o 1 px z mocniejszym cieniem – jak karta-hero i kafelek zajęć obok.
   :not(:active):not(.is-pressed) – wciśnięcie (scale .9, także 90 ms .is-pressed po puszczeniu) wygrywa z uniesieniem.
   Przy fokusie z klawiatury pierścień zostaje (cień składany: pierścień + uniesienie). Tylko urządzenia z myszą. */
@media (hover: hover) {
  :root .c-qa:hover:not(:active):not(.is-pressed) :is(img.ico, .c-qa-tile) { transform: translateY(-1px); box-shadow: var(--el-2); }
  :root .c-qa:hover:focus-visible:not(:active):not(.is-pressed) :is(img.ico, .c-qa-tile) { box-shadow: var(--ring), var(--el-2); }
}
.c-qa.is-danger { color: var(--red-600); }

/* =====================================================================
   POLA (SPEC 2.3) – globalna reguła style.css input:not(…)×4 ma (0,4,1), dlatego prefiks :root.
   Kolor, obwódka i promień nadpisane; wysokości, paddingi z ikonami i rozmiary kompaktowe zostają ze starych reguł.
   ===================================================================== */
:root input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]),
:root select:not([multiple]),
:root textarea {
  border-color: transparent; background-color: var(--c-fill); color: var(--c-text); box-shadow: none;
  transition: background-color 140ms var(--ease-standard), box-shadow 200ms var(--ease-out), color 140ms var(--ease-standard);
}
:root input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]),
:root select:not([multiple]) { border-radius: var(--r-ctl); }
textarea { border-radius: var(--r-ctl); }                 /* niska specyficzność – .msg-form textarea (pigułka) zostaje */
:root input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]):focus,
:root select:not([multiple]):focus,
:root textarea:focus { outline: none; background-color: #fff; border-color: transparent; box-shadow: var(--ring-inset); }
/* błąd: czerwona tinta + pierścień 1,5 px (osobne reguły – nieobsługiwany :user-invalid nie może unieważnić .is-invalid) */
:root input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]):user-invalid,
:root select:not([multiple]):user-invalid,
:root textarea:user-invalid { background-color: var(--red-50); box-shadow: inset 0 0 0 1.5px var(--red-500); }
:root input.is-invalid:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]),
:root select.is-invalid:not([multiple]),
:root textarea.is-invalid { background-color: var(--red-50); box-shadow: inset 0 0 0 1.5px var(--red-500); animation: c-shake 320ms var(--ease-out); }
/* wyłączone / tylko do odczytu – bez wypełnienia, sama linia (inne niż pole edytowalne) */
:root body input:disabled:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]),
:root body select:disabled:not([multiple]),
:root body textarea:disabled { background-color: transparent; border-color: transparent; box-shadow: inset 0 0 0 1px var(--n-200); color: var(--n-600); -webkit-text-fill-color: var(--n-600); opacity: 1; }

/* lista wyboru (select z size > 1, np. #indiv-child) bez strzałki rozwijania */
:root select[size]:not([size="0"]):not([size="1"]) { background-image: none; padding-right: 12px; }
/* wybór sezonu: panel.css daje mu białe tło (ID), a obwódkę zabrała reguła pól – „chip select” w tincie (SPEC 2.3) */
:root #season-select { background-color: var(--c-tint-bg); }
:root #season-select:focus { background-color: #fff; }

/* pola daty, godziny i liczby – ten sam wygląd w Safari i Chrome (T7, naprawy Safari)
   Liczba: strzałki tylko pod kursorem i przy fokusie – tak robi Chrome (jego arkusz przeglądarki), Safari pokazywało je stale.
   W Chrome bez zmian, w Safari to samo zachowanie. Pola z własnym appearance: none (kwota, stawki) zostają bez strzałek. */
:root input[type=number]::-webkit-inner-spin-button { opacity: 0; pointer-events: none; }
:root input[type=number]:enabled:read-write:is(:hover, :focus)::-webkit-inner-spin-button { opacity: 1; pointer-events: auto; }
/* Data i godzina: Safari (WebKit, macOS i iOS) nie ma ikony kalendarza ani zegara (::-webkit-calendar-picker-indicator), więc
   pole daty wyglądało jak zwykły tekst. Ikona jako tło w prawym końcu pola treści – tam, gdzie Chrome rysuje swoją. Warunek
   @supports wyklucza Chrome (ma własną ikonę) i Firefoksa (nie zna ::-webkit-datetime-edit, ma własną ikonę). !important, bo
   wiersze grup (.c-bare) i edycja w listach mają skrót background, który zdejmowałby ikonę. Klik w pole otwiera kalendarz Safari. */
@supports selector(::-webkit-datetime-edit) and (not selector(::-webkit-calendar-picker-indicator)) {
  :root input:is([type=date], [type=time]) {
    background-repeat: no-repeat !important; background-origin: content-box !important; background-position: right center !important; background-size: 16px 16px !important;
  }
  :root input[type=date] { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%232f2a3a' stroke-width='1.6' stroke-linecap='round'%3E%3Crect x='2' y='3' width='12' height='11' rx='2.2'/%3E%3Cpath d='M2 6.6h12M5.2 1.6v2.6M10.8 1.6v2.6'/%3E%3C/svg%3E") !important; }
  :root input[type=time] { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%232f2a3a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='6.2'/%3E%3Cpath d='M8 4.6V8l2.3 1.5'/%3E%3C/svg%3E") !important; }
  :root input:is([type=date], [type=time]):disabled { background-image: none !important; }
  /* segmenty daty bez 1 px dopełnienia z arkusza Safari: „20.10.2026” jak zwykły tekst, początek w linii z innymi polami
     (osobne reguły – nieznany pseudoelement unieważniłby całą listę selektorów) */
  input::-webkit-datetime-edit-day-field { padding: 0; }
  input::-webkit-datetime-edit-month-field { padding: 0; }
  input::-webkit-datetime-edit-year-field { padding: 0; }
  input::-webkit-datetime-edit-hour-field { padding: 0; }
  input::-webkit-datetime-edit-minute-field { padding: 0; }
}
/* tylko iOS (-webkit-touch-callout zna wyłącznie WebKit na iPhonie i iPadzie): Safari wyśrodkowuje wartość daty i zwija puste pole –
   wartość do lewej jak w pozostałych polach */
@supports (-webkit-touch-callout: none) {
  input:is([type=date], [type=time])::-webkit-date-and-time-value { min-height: 1.3em; margin: 0; text-align: start; }
}

/* nowe pole (markup E2) */
.c-input, .c-select,
:root input.c-input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]) {
  width: 100%; height: var(--field-h); min-height: 0; padding: 0 14px; border-radius: var(--r-ctl); border: 0;
  background-color: var(--c-fill); color: var(--c-text); font: var(--t-callout); outline: none; box-shadow: none;
}
.c-input::placeholder { color: var(--n-500); }
.c-select { appearance: none; -webkit-appearance: none; padding-right: 36px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 1.5l3 3M3 7.5l3 3 3-3' fill='none' stroke='%238d86a0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 12px; }
.c-search { position: relative; }
.c-search > svg.ui { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); font-size: 16px; color: var(--n-500); pointer-events: none; }
:root .c-search input.c-input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]) { height: 38px; padding-left: 35px; border-radius: var(--r-md); font-size: 16px; }
/* grupa pól iOS (inset grouped) */
.c-form-group { background: var(--c-surface); border-radius: var(--r-card); overflow: hidden; box-shadow: var(--el-1); }
.c-form-row { position: relative; display: block; padding: 9px 16px; min-height: 60px; }
/* linia tylko nad wierszem, nad którym stoi widoczny wiersz – ukryty pierwszy wiersz nie zostawia linii na górze karty (KOLEJKA T4 → T1), specyficzność jak dawniej */
.c-form-row:where(:not(.hidden, [hidden])) ~ .c-form-row::before { content: ""; position: absolute; top: 0; left: 16px; right: 0; height: 1px; background: var(--c-sep); }
.c-form-row > .c-label { display: block; font: 500 12.5px/16px var(--font-sans); color: var(--c-text-2); letter-spacing: 0; transition: color 140ms; }
/* pole „gołe” w wierszu grupy – specyficzność ponad globalną regułę pól (:root input:not(…)×5) */
:root .c-form-row .c-bare:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]) { display: block; width: 100%; height: 28px; min-height: 0; border: 0; border-radius: 0; padding: 2px 0 0; background: none; box-shadow: none; outline: none; font: var(--t-body); letter-spacing: var(--tr-body); color: var(--c-text); }
:root .c-form-row .c-bare:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]):focus { background: none; box-shadow: none; }
:root .c-form-row select.c-bare:not([multiple]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=color]):not([type=range]) { -webkit-appearance: none; appearance: none; padding-right: 22px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 1.5l3 3M3 7.5l3 3 3-3' fill='none' stroke='%238d86a0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right 0 center / 12px no-repeat; }
/* placeholder --c-text-3 (= --n-500, 3,47:1 – poziom iOS, SPEC 1.1); --n-400 miało 2,17:1 (T7, audyt kontrastu) */
.c-form-row .c-bare::placeholder { color: var(--c-text-3); }
.c-form-row:focus-within > .c-label { color: var(--c-accent-text); }
.c-form-row.is-ok { padding-right: 46px; }
.c-form-row.is-ok::after { content: ""; position: absolute; right: 14px; top: 50%; width: 22px; height: 22px; margin-top: -11px; border-radius: 50%; background: var(--green-500) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/13px no-repeat; animation: c-pop-in var(--d-pop) var(--spring-pop) backwards; }
.c-section-h { display: flex; align-items: center; gap: 6px; margin: 24px 16px 7px; font: var(--t-caption2); letter-spacing: var(--tr-caps); text-transform: uppercase; color: var(--c-text-2); }
.c-section-foot { margin: 7px 16px 0; font: var(--t-footnote); color: var(--c-text-2); }

/* przełącznik iOS 51×31 (SPEC 2.4) – markup: <label class="c-switch"><input type="checkbox" id="…"><i></i></label> */
.c-switch { position: relative; display: inline-block; width: 51px; height: 31px; flex: 0 0 auto; vertical-align: middle; }
:root .c-switch input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.c-switch i { position: absolute; inset: 0; border-radius: 99px; background: var(--n-300); transition: background-color 200ms var(--ease-standard), box-shadow 200ms; }
.c-switch i::after { content: ""; position: absolute; left: 2px; top: 2px; width: 27px; height: 27px; border-radius: 99px; background: #fff; box-shadow: 0 3px 8px rgba(0, 0, 0, .15), 0 1px 1px rgba(0, 0, 0, .16); transition: transform var(--d-snappy) var(--spring), width var(--d-snappy) var(--spring); }
.c-switch input:checked + i { background: var(--green-500); }
.c-switch input:checked + i::after { transform: translateX(20px); }
.c-switch input:active + i::after { width: 31px; }
.c-switch input:checked:active + i::after { transform: translateX(16px); }
.c-switch input:focus-visible + i { box-shadow: var(--ring); }
/* stan wyłączony: obwódka toru --n-500 (T7, runda 2, WCAG 1.4.11) – tor --n-300 miał 1,50:1 do białej karty i 1,43:1 do --n-50
   w oknach, obwódka ma 3,47:1 (jak pole wyboru .c-check). Włączony (zielony, 3,08:1) bez obwódki – gaśnie razem ze zmianą
   koloru (przejście box-shadow 200 ms). Fokus: obwódka + pierścień. Rolę „przełącznik” dla czytnika daje ui.js (role="switch"). */
.c-switch input:not(:checked) + i { box-shadow: inset 0 0 0 1.5px var(--n-500); }
.c-switch input:not(:checked):focus-visible + i { box-shadow: inset 0 0 0 1.5px var(--n-500), var(--ring); }
.c-switch input:disabled + i { opacity: .45; }
/* pole wyboru – kwadrat 24 px (zgody), kółko 22 px (zaznaczanie w listach)
   Obwódka pustego pola --n-500 (naprawa po bramce 1, runda 3): granica kontrolki potrzebuje 3:1 (WCAG 1.4.11) – --n-300 miało
   1,43:1 na karcie zgody (#faf9fc), --n-500 ma 3,31:1 (na bieli 3,47:1, na --n-100 3,10:1, na --lav-50 3,19:1). */
:root input.c-check { appearance: none; -webkit-appearance: none; flex: 0 0 auto; width: 24px; height: 24px; min-height: 0; margin: 0; padding: 0; border-radius: 7px; border: 1.5px solid var(--n-500); background: #fff; display: inline-grid; place-content: center; cursor: pointer; transition: background-color 140ms, border-color 140ms, transform var(--d-press) var(--ease-out); }
:root input.c-check::after { content: ""; width: 11px; height: 6px; border: 2.4px solid #fff; border-top: 0; border-right: 0; transform: rotate(-45deg) translate(1px, -1px) scale(0); transition: transform var(--d-pop) var(--spring-pop); }
:root input.c-check:checked { background: var(--c-accent); border-color: var(--c-accent); }
:root input.c-check:checked::after { transform: rotate(-45deg) translate(1px, -1px) scale(1); }
:root input.c-check.is-round { border-radius: 50%; width: 22px; height: 22px; }
:root input.c-check:focus-visible { outline: none; box-shadow: var(--ring); }
:root input.c-check:active { transform: scale(.9); }

/* =====================================================================
   SEGMENTED CONTROL (SPEC 2.5) – kciuk = ::before kontenera, --thumb-x / --thumb-w z ui.js
   (bez JS: rezerwa :has() dla segmentów 2-pozycyjnych o równej szerokości)
   ===================================================================== */
.c-seg { --thumb-x: 3px; --thumb-w: 0px; position: relative; display: inline-flex; align-items: stretch; padding: 3px; border-radius: 11px; background: var(--c-fill-ink); isolation: isolate; }
.c-seg::before {
  content: ""; position: absolute; z-index: -1; top: 3px; bottom: 3px; left: 0; width: var(--thumb-w); transform: translateX(var(--thumb-x));
  border-radius: 8px; background: #fff; box-shadow: 0 3px 8px rgba(var(--ink), .12), 0 0 0 .5px rgba(var(--ink), .04);
  transition: transform var(--d-snappy) var(--spring), width var(--d-snappy) var(--spring), opacity 200ms;
}
.c-seg.ui-no-anim::before { transition: none; }
:root .c-seg > button, :root .c-seg > a { position: relative; flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 30px; min-height: 0; padding: 0 14px; border: 0; border-radius: 8px; background: transparent; box-shadow: none; cursor: pointer; font: 600 13.5px/1 var(--font-sans); letter-spacing: -0.008em; color: var(--c-text-2); white-space: nowrap; text-decoration: none; transition: color 200ms, transform var(--d-press) var(--ease-out); }
:root .c-seg > button:hover { background: transparent; color: var(--c-text); }
:root .c-seg > .active, :root .c-seg > [aria-pressed="true"] { color: var(--c-text); }
:root .c-seg > button:active, :root .c-seg > button.is-pressed { transform: scale(.95); }
:root .c-seg > button:focus-visible { box-shadow: var(--ring); }
:root .c-seg.is-lg > button { height: 34px; font-size: 15px; }
.c-seg.is-fill { display: flex; }
:root .c-seg.is-fill > button { flex: 1 1 0; }
html:not(.ui-js) .c-seg:not(:has(> :nth-child(3)))::before { width: calc(50% - 3px); transform: translateX(3px); }
html:not(.ui-js) .c-seg:not(:has(> :nth-child(3))):has(> :nth-child(2).active)::before { transform: translateX(calc(100% + 3px)); }
/* nieaktywny tekst segmentu na torze --c-fill-ink na tle strony: --n-600 miało 4,46:1, --n-700 ma ponad 7:1 (T7, audyt kontrastu).
   Token na kontenerze – reguły przycisków w arkuszach ekranów (color: var(--c-text-2)) zostają bez zmian. */
:root :is(.c-seg, #participants-subnav, #child-tabs, .rate-tabs) { --c-text-2: var(--n-700); }
/* telefon: cel dotyku ≥ 44 px w pionie bez zmiany wyglądu (SPEC 10) – przyciski 30–34 px; w poziomie nie wchodzi na sąsiada.
   #participants-subnav i #child-tabs mają overflow: hidden (wielokropek), który obcina ::after – cel w ich arkuszach (KOLEJKA). */
@media (max-width: 700px) {
  :root .rate-tabs > button { position: relative; }
  :root .c-seg > button::after, :root .rate-tabs > button::after { content: ""; position: absolute; inset: -7px 0; }
}

/* =====================================================================
   LISTY, KARTY, KARTA-HERO (SPEC 2.6–2.8)
   ===================================================================== */
.c-card { background: var(--c-surface); border-radius: var(--r-card); box-shadow: var(--el-1); }
.c-list { margin: 0; padding: 0; list-style: none; background: var(--c-surface); border-radius: var(--r-card); box-shadow: var(--el-1); overflow: hidden; }
:root .c-row { position: relative; display: flex; align-items: center; justify-content: flex-start; gap: 12px; width: 100%; height: auto; min-height: 48px; padding: 11px 16px; border: 0; border-radius: 0; background: transparent; box-shadow: none; color: inherit; font: inherit; font-weight: 400; letter-spacing: inherit; text-align: left; white-space: normal; transition: background-color 140ms; }
:root .c-row.two { min-height: 64px; }
.c-row + .c-row::before { content: ""; position: absolute; top: 0; right: 0; left: var(--sep-left, 16px); height: 1px; background: var(--c-sep); }
.c-list.has-ico > .c-row { --sep-left: 60px; }
button.c-row, a.c-row, .c-row.is-tap { cursor: pointer; text-decoration: none; }
:root button.c-row:active, :root a.c-row:active, :root .c-row.is-tap:active, :root .c-row.is-pressed { background: var(--c-press); transform: none; transition-duration: 0ms; }
@media (hover: hover) { :root button.c-row:hover, :root a.c-row:hover, :root .c-row.is-tap:hover { background: var(--n-50); text-decoration: none; } }
:root button.c-row:focus-visible, :root a.c-row:focus-visible { box-shadow: var(--ring-inset); border-radius: 0; }
.c-row > img.ico { width: 32px; height: 32px; }
.c-row-main { flex: 1 1 auto; min-width: 0; }
.c-row-title { display: block; font: var(--t-headline); letter-spacing: var(--tr-headline); color: var(--c-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.c-row-sub { display: block; margin-top: 1px; font: var(--t-footnote); color: var(--c-text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.c-row-val { flex: 0 0 auto; text-align: right; font: 400 16px/21px var(--font-sans); color: var(--c-text-2); font-variant-numeric: tabular-nums; }
.c-row-val strong { display: block; font-weight: 600; color: var(--c-text); }
.c-chev { flex: 0 0 auto; width: 8px; height: 14px; }
.c-chev::before { content: ""; display: block; width: 8px; height: 8px; margin-top: 3px; border-right: 2px solid var(--n-400); border-bottom: 2px solid var(--n-400); border-radius: 1px; transform: translateX(-2px) rotate(-45deg); }
.c-h2 { display: flex; align-items: baseline; justify-content: space-between; margin: 28px 4px 10px; font: var(--t-title3); letter-spacing: var(--tr-title3); color: var(--c-text); }
:root .c-h2 a, :root .c-h2 button { height: auto; min-height: 0; border: 0; background: none; box-shadow: none; padding: 0; font: 600 15px/1 var(--font-sans); letter-spacing: -0.01em; color: var(--c-accent-text); cursor: pointer; }
.c-large-title { margin: 6px 4px 14px; font: var(--t-large); letter-spacing: var(--tr-large); color: var(--c-title); }

/* karta-hero (tylko 2 miejsca: „Do zapłaty” w portalu, „Wpłacono” w płatnościach) */
.c-hero {
  position: relative; overflow: hidden; isolation: isolate; color: #fff; border-radius: 24px; padding: 18px 20px 20px;
  background: var(--c-hero); box-shadow: 0 1px 2px rgba(var(--lav-rgb), .25), 0 18px 36px -18px rgba(var(--lav-rgb), .9), inset 0 1px 0 rgba(255, 255, 255, .28);
}
/* poświata w samym rogu – przy 390 px nie wchodzi pod koniec etykiety (T7, audyt kontrastu) */
.c-hero::after { content: ""; position: absolute; z-index: -1; width: 200px; height: 200px; right: -96px; top: -112px; border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 255, 255, .24), rgba(255, 255, 255, 0)); }
/* etykieta i opis w pełnej bieli (z alfą .92–.95 na gradiencie nie było 4,5:1) */
.c-hero-label { font: 600 15px/20px var(--font-sans); letter-spacing: -0.006em; color: #fff; }
.c-hero-num { margin: 2px 0 0; font: 700 46px/52px var(--font-display); letter-spacing: -0.032em; font-variant-numeric: tabular-nums; }
.c-hero-num small { font-size: 24px; font-weight: 600; letter-spacing: -0.015em; margin-left: 5px; opacity: .92; }
.c-hero-meta { margin-top: 4px; font: 500 14px/19px var(--font-sans); color: #fff; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.c-hero-bar { height: 8px; margin-top: 14px; border-radius: 4px; background: rgba(255, 255, 255, .25); overflow: hidden; }
.c-hero-bar > i { display: block; height: 100%; width: var(--p, 0%); border-radius: 4px; background: #fff; transform-origin: left; animation: c-bar-in 800ms var(--spring) 120ms backwards; }

/* pasek postępu i paski kategorii */
.c-progress { height: 6px; border-radius: 3px; background: var(--n-100); overflow: hidden; }
.c-progress > i { display: block; height: 100%; width: var(--p, 0%); border-radius: 3px; background: var(--green-500); transform-origin: left; animation: c-bar-in 800ms var(--spring) backwards; }
/* odstęp 3 px tylko przed segmentem niezerowym (margines zamiast gap): pasek zaczyna się i kończy równo z liczbą i legendą,
   także gdy pierwsze albo ostatnie segmenty mają 0 (np. wszyscy „do oznaczenia” na początku zajęć) */
.c-stack { display: flex; gap: 0; height: 8px; margin-left: -3px; }
.c-stack > i {
  height: 100%; border-radius: 4px; flex: var(--n, 0) 1 0; min-width: 0; margin-left: calc(min(var(--n, 0), 1) * 3px); background: var(--n-200);
  transform-origin: left; transition: flex-grow var(--d-soft) var(--spring), margin-left var(--d-soft) var(--spring);
}
.c-stack > i[data-k="p"] { background: var(--green-500); }
.c-stack > i[data-k="r"] { background: var(--amber-500); }
.c-stack > i[data-k="a"] { background: var(--red-500); }
.c-stack > i[data-k="u"] { background: var(--n-200); }

/* =====================================================================
   PIGUŁKI, LICZNIKI, STATUSY (SPEC 2.16)
   Licznik .nav-badge = czerwony 20 px (wymaga akcji); białe liczniki na lawendowym pasku zostają (style.css header nav …).
   ===================================================================== */
.c-badge, :root .nav-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--red-600); color: #fff; font: 700 12px/1 var(--font-sans); letter-spacing: 0; font-variant-numeric: tabular-nums; }
:root .nav-badge:not(.hidden), .c-badge { animation: c-pop-in var(--d-pop) var(--spring-pop) backwards; }
/* liczniki w listach odświeżanych w tle nie „skaczą” przy każdym renderze (jak motion.css) */
:root .thread-row .nav-badge, :root .thread-top .nav-badge { animation: none; }
.c-badge.is-info { background: var(--n-200); color: var(--n-700); }
.c-tag { display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: var(--r-xs); background: var(--c-tint-bg); color: var(--c-accent-text); font: 600 12px/1 var(--font-sans); letter-spacing: 0; white-space: nowrap; }
.c-tag.is-amber { background: var(--amber-50); color: var(--amber-700); }
.c-tag.is-blue { background: var(--blue-50); color: var(--blue-700); }
.c-tag.is-green { background: var(--green-50); color: var(--green-700); }
.c-status { display: inline-flex; align-items: center; gap: 6px; font: 600 13px/18px var(--font-sans); color: var(--st-fg, var(--c-text-2)); letter-spacing: 0; white-space: nowrap; }
.c-status::before { content: ""; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--st-dot, var(--gray-500)); }
.c-status.ok { --st-dot: var(--green-500); --st-fg: var(--green-700); }
.c-status.bad { --st-dot: var(--red-500); --st-fg: var(--red-700); }
.c-status.wait { --st-dot: var(--amber-500); --st-fg: var(--amber-700); }
.c-status.info { --st-dot: var(--lav-400); --st-fg: var(--lav-700); }
.c-status.is-critical { padding: 3px 9px 3px 8px; border-radius: 99px; background: var(--red-50); }

/* =====================================================================
   PUSTE STANY, SZKIELETY (SPEC 2.18)
   ===================================================================== */
.c-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 28px 24px 26px; text-align: center; font: var(--t-subhead); color: var(--c-text-2); }
.c-empty img.ico { width: 56px; height: 56px; margin: 0 0 10px; }
.c-empty strong { font: var(--t-headline); letter-spacing: var(--tr-headline); color: var(--c-text); }
.c-empty p { margin: 0; max-width: 30ch; }
/* istniejące puste stany: kafelek 56 px NAD tekstem (portal: JS daje samo .ico-xl bez .ico – audyt 5.1-1), bez ramki */
:root .empty > .ico-xl, :root .empty > img.ico { display: block; width: 56px; height: 56px; margin: 0 auto 10px; flex: 0 0 auto; }
:root main .empty, :root #att-list .empty, :root #cp-body .empty { border: 0; background: transparent; }
:root .empty { font-size: 15px; line-height: 20px; letter-spacing: var(--tr-subhead); color: var(--c-text-2); text-align: center; }
/* mniejsze puste stany w oknach – kafelek 36 px */
:root #att-list .empty > .ico-xl, :root #cp-body .empty > .ico-xl, :root #att-list .empty > img.ico, :root #cp-body .empty > img.ico { width: 36px; height: 36px; margin-bottom: 6px; }
.c-skel { border-radius: 8px; background: linear-gradient(90deg, var(--n-100) 0%, var(--lav-50) 50%, var(--n-100) 100%); background-size: 200% 100%; animation: c-skel 1.4s ease-in-out infinite; }
:root .skeleton { background-image: linear-gradient(90deg, var(--n-100) 0%, var(--lav-50) 50%, var(--n-100) 100%); background-size: 200% 100%; }
/* szkielet → treść: przenikanie 200 ms tylko przy zdjęciu .skeleton (klasę daje ui.js) */
.ui-unskel { animation: c-fade-in 200ms var(--ease-out) backwards; }

/* =====================================================================
   OKNA → ARKUSZE (.modal-backdrop > .modal) – wspólne dla panelu i portalu (SPEC 2.11)
   Struktura E2: .c-sheet-head (eyebrow, tytuł, podtytuł, button.sheet-x) + środek + .form-actions.c-sheet-foot.
   Do czasu markupu E2 te same reguły rysują dzisiejsze okna (h2, p, pola, .form-actions).
   ===================================================================== */
/* Przyciemnienie = ::before tła (kolor + rozmycie), gaśnie samą przezroczystością (kompozytor). Kontener nie zmienia opacity,
   więc arkusz przy wejściu i wyjściu jest w pełni kryjący – jak w iOS (T7: przez gasnący kontener prześwitywał grafik albo
   poprzedni arkusz). Animacja na samym .modal-backdrop zostaje (c-hold, bez efektu) – koniec wyjścia (afterExit, animationend
   z e.target === el) liczy się jak dotąd. Przy przeciąganiu ::before ma opacity --scrim-k (ui.js). */
:root .modal-backdrop {
  position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; padding: 24px;
  background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none;
  animation: c-hold 260ms linear backwards;
}
:root .modal-backdrop::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--c-scrim); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: var(--scrim-k, 1); transition: opacity 300ms var(--ease-out);
  animation: c-scrim-in 260ms var(--ease-out) backwards;
}
:root .modal-backdrop.is-dragging::before { transition: none; }
:root .modal-backdrop .modal {
  position: relative; width: 100%; max-width: 560px; max-height: 88vh; max-height: min(88dvh, 880px);
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: var(--m-gap); padding: var(--m-pad);
  border: 0; border-radius: var(--r-card); background: var(--c-surface); box-shadow: var(--el-3);
  transform-origin: var(--origin-x, 50%) var(--origin-y, 40%);
  animation: c-dialog-in var(--d-snappy) var(--spring) backwards;
}
:root .modal-backdrop .modal:has(> .c-sheet-head) { padding-top: 0; }
:root .modal-backdrop .modal:has(> .c-sheet-foot) { padding-bottom: 0; }
/* Fokus z klawiatury nie chowa się pod przyklejonym nagłówkiem i stopką arkusza (T7, runda 2, WCAG 2.4.11): okno przewija
   element poza pasek. Wysokości pasków mierzy ui.js (--ui-sheet-head / --ui-sheet-foot na .modal, przy otwarciu i przy zmianie
   rozmiaru – na telefonie tytuł łamie się na 2 wiersze), wartości zapasowe = typowy nagłówek i stopka. Zapas 8 px. */
:root .modal-backdrop .modal:has(> .c-sheet-head) { scroll-padding-top: calc(var(--ui-sheet-head, 104px) + 8px); }
:root .modal-backdrop .modal:has(> .c-sheet-foot, > form > .c-sheet-foot) { scroll-padding-bottom: calc(var(--ui-sheet-foot, 76px) + 8px); }
/* wyjście: osobna nazwa klatek (c-hold-out) – przy tej samej nazwie (c-hold) przeglądarka nie zaczyna animacji od nowa, tylko
   skraca wejściową (260 → 240 ms), więc okno zamknięte w trakcie wejścia znikało (animationend → .hidden) po 0–120 ms
   wyjścia zamiast po pełnym (T7, runda 2) */
:root .modal-backdrop.is-closing { animation: c-hold-out var(--d-exit) linear forwards; pointer-events: none; }
/* przy zamykaniu bez przejścia krycia przyciemnienia – ui.js może wtedy ustawić --scrim-k (zamknięcie w trakcie wejścia),
   a przejście w tle przykryłoby animację wyjścia */
:root .modal-backdrop.is-closing::before { animation: c-scrim-out var(--d-exit) var(--ease-exit-ios) forwards; transition: none; }
/* --exit-d / --exit-o / --exit-s (ui.js): zamknięcie w trakcie wejścia rusza z bieżącego krycia i skali, krócej */
:root .modal-backdrop.is-closing .modal { animation: c-dialog-out var(--exit-d, 180ms) var(--ease-exit-ios) forwards; }
/* fokus startowy okna (ui.js): nagłówek z tabindex="-1" – bez pierścienia, to nie jest kontrolka */
:root .modal-backdrop .modal :is(h2, h3)[tabindex="-1"]:focus-visible, :root .modal-backdrop .modal[tabindex="-1"]:focus-visible { outline: none; box-shadow: none; }
/* tytuł i podtytuł dzisiejszych okien = tytuł arkusza */
:root .modal h2 { margin: 0; font: var(--t-title2); letter-spacing: var(--tr-title2); color: var(--c-text); }
:root .modal > h2 + .sms-meta, :root .modal > h2 + p { margin-top: -6px; font-size: 13px; line-height: 18px; letter-spacing: 0; color: var(--c-text-2); }
:root .modal .form-actions { gap: 10px; }

/* nagłówek arkusza (markup E2) */
:root .c-sheet-head {
  position: sticky; top: 0; z-index: 3; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; flex-shrink: 0;
  margin: 0 calc(-1 * var(--m-pad)); padding: 18px 16px 12px var(--m-pad);
  background: var(--glass-bar); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  -webkit-user-select: none; user-select: none;
}
:root .c-sheet-head > :not(.sheet-x) { grid-column: 1; margin: 0; }
.c-sheet-eyebrow { display: flex; align-items: center; gap: 6px; font: 700 12px/16px var(--font-sans); letter-spacing: .06em; text-transform: uppercase; color: var(--c-accent-text); }
/* kropka w kolorze grupy (J13) – delikatny pierścień, bo część kolorów jest prawie biała (#ffe5fe, #cdf2fe) – KOLEJKA T5a → T1 */
.c-sheet-eyebrow::before { content: ""; flex: 0 0 auto; width: 9px; height: 9px; border-radius: 3px; background: var(--gc, var(--lav-400)); box-shadow: inset 0 0 0 1px rgba(var(--ink), .12); }
:root .c-sheet-head h2, :root .c-sheet-head h3 { font: var(--t-title2); letter-spacing: var(--tr-title2); color: var(--c-text); }
:root .c-sheet-head p { margin-top: 2px; font: var(--t-footnote); color: var(--c-text-2); letter-spacing: 0; }
:root .sheet-x {
  grid-column: 2; grid-row: 1 / span 3; align-self: start; position: relative; display: grid; place-items: center; flex: 0 0 auto;
  width: 30px; height: 30px; min-height: 0; padding: 0; border: 0; border-radius: 50%; background: rgba(var(--ink), .07); color: var(--n-600); box-shadow: none; cursor: pointer;
  transition: transform var(--d-press) var(--ease-out), background-color 140ms;
}
:root .sheet-x::after { content: ""; position: absolute; inset: -7px; }
:root .sheet-x svg.ui { font-size: 14px; stroke-width: 2.8; }
@media (hover: hover) { :root .sheet-x:hover { background: rgba(var(--ink), .12); } }
:root .sheet-x:active, :root .sheet-x.is-pressed { transform: scale(.88); }
:root .sheet-x:focus-visible { outline: none; box-shadow: var(--ring); }
.c-sheet-body { padding: 4px 0 8px; }
/* stopka arkusza (markup E2): przyklejona, na szkle, przyciski równej szerokości */
:root .c-sheet-foot, :root .modal .c-sheet-foot.form-actions {
  position: sticky; bottom: 0; z-index: 3; display: flex; flex-direction: row-reverse; flex-wrap: nowrap; gap: 10px; flex-shrink: 0;
  margin: auto calc(-1 * var(--m-pad)) 0; padding: 12px var(--m-pad) calc(14px + var(--sa-b)); border-top: 0;
  background: var(--glass-bar); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: 0 -.5px 0 var(--c-sep);
}
:root .c-sheet-foot > button, :root .c-sheet-foot > .btn { flex: 1 1 0; min-width: 0; }
/* destrukcyjny (np. #att-delete „Usuń te zajęcia”) – komputer: szerokość treści po lewej, główny przycisk rośnie
   (style.css .modal .form-actions button.danger ma flex-basis: 100% – bez zawijania wychodził 2× szerszy od „Gotowe”, T7) */
:root .modal .c-sheet-foot > button.danger { flex: 0 1 auto; }

@media (max-width: 700px) {
  :root .modal-backdrop { align-items: flex-end; padding: calc(var(--sa-t) + 10px) 0 0; }
  :root .modal-backdrop .modal {
    width: 100%; max-width: none; max-height: 100%; padding: 0 var(--m-pad) calc(var(--m-pad) + var(--sa-b));
    border-radius: var(--r-sheet) var(--r-sheet) 0 0; box-shadow: 0 -10px 40px -12px rgba(var(--ink), .35);
    transform: translateY(var(--drag-y, 0px));
    animation: c-sheet-in var(--d-sheet) var(--spring) backwards;
  }
  :root .modal-backdrop .modal:has(> .c-sheet-foot) { padding-bottom: 0; }
  /* uchwyt arkusza (przy nagłówku E2 – przyklejony nad nim) */
  :root .modal-backdrop .modal::before { content: ""; position: relative; z-index: 4; display: block; flex: 0 0 auto; align-self: center; width: 36px; height: 5px; margin: 8px auto 2px; border-radius: 3px; background: rgba(var(--ink), .18); }
  :root .modal-backdrop .modal:has(> .c-sheet-head)::before { position: sticky; top: 0; margin: 0 auto calc(-5px - var(--m-gap)); transform: translateY(7px); }
  :root .modal-backdrop.is-closing .modal { animation: c-sheet-out var(--exit-d, var(--d-exit)) var(--ease-exit-ios) forwards; }
  /* zamknięcie rzutem (ui.js: .is-flung, --fling-d 160–240 ms, --fling-ease z prędkością palca) – arkusz jedzie dalej
     z prędkością puszczenia zamiast ruszać od zera (ease-in). Czas ≤ 240 ms – kończy się przed wygaszeniem tła. */
  :root .modal-backdrop.is-closing.is-flung .modal { animation-duration: var(--fling-d, 220ms); animation-timing-function: var(--fling-ease, cubic-bezier(.2, .6, .35, 1)); }
  :root .c-sheet-head { padding: 22px 14px 12px var(--m-pad); touch-action: none; }
  /* przyciski stopki – L (50 px), dwa obok siebie (główny po prawej), destrukcyjny w osobnym wierszu */
  :root body .modal .form-actions > button:where(:not([class]), .small, .primary, .danger, .ghost):where(:not(.btn)) { min-height: var(--ctl-l); --btn-r: var(--r-btn-lg); font-size: 17px; }
  :root body .modal .form-actions > button:not(.danger):where(:not([class]), .small, .primary, .ghost):where(:not(.btn)) { flex: 1 1 calc(50% - 5px); }
  /* stopka arkusza z widocznym destrukcyjnym: zawijanie tylko wtedy (3 przyciski #temp-pass-modal zostają w jednym rzędzie).
     row-reverse + DOM [główny, Anuluj, danger] → główny u góry, destrukcyjny pod nim jako wiersz tekstowy 44 px na całą
     szerokość (mniejsza waga niż akcja główna). Kolejność w DOM i fokusu bez zmian. */
  :root .modal .c-sheet-foot:has(> button.danger:not(.hidden)) { flex-wrap: wrap; row-gap: 4px; }
  :root body .modal .c-sheet-foot > button.danger { flex: 1 1 100%; min-height: var(--hit); --btn-bg: transparent; --btn-bg-h: var(--red-50); --btn-bg-a: var(--red-50); }
}

/* zgodność: panel.css przykleja stopki #child-modal i #att-modal ujemnymi marginesami (1,2,0) liczonymi od dawnego paddingu.
   Tu ten sam efekt od var(--m-pad), a okno nie ma dolnego paddingu – treść nie prześwituje pod przyklejonym „Zamknij” (audyt 5.1-7). */
:root :is(#child-modal, #att-modal) .modal:has(> .form-actions:last-child) { padding-bottom: 0; }
:root :is(#child-modal, #att-modal) .modal > .form-actions:last-child { margin: 8px calc(-1 * var(--m-pad)) 0; padding: 12px var(--m-pad) calc(var(--m-pad) + var(--sa-b)); }
:root :is(#child-modal, #att-modal) .modal > .form-actions.c-sheet-foot { margin-top: auto; padding-bottom: calc(14px + var(--sa-b)); background: var(--glass-bar); }

/* =====================================================================
   ACTION SHEET / ALERT zamiast confirm() – tworzony przez askConfirm() (etap 3, SPEC 2.12, 13)
   ===================================================================== */
/* gaśnie samo przyciemnienie (kolor tła), karta zostaje w pełni kryjąca (T7) */
.c-alert { position: fixed; inset: 0; z-index: 58; display: flex; align-items: flex-end; justify-content: center; padding: 0 10px calc(10px + var(--sa-b)); background: var(--c-scrim); animation: c-tint-in 260ms var(--ease-out) backwards; }
.c-alert.is-closing { animation: c-tint-out var(--d-exit) var(--ease-exit-ios) forwards; pointer-events: none; }
.c-alert-box { width: 100%; max-width: 430px; animation: c-sheet-in var(--d-sheet) var(--spring) backwards; }
.c-alert.is-closing .c-alert-box { animation: c-sheet-out var(--exit-d, var(--d-exit)) var(--ease-exit-ios) forwards; }
.c-alert-group { overflow: hidden; border-radius: 16px; background: rgba(255, 255, 255, .86); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); }
.c-alert-group + .c-alert-group { margin-top: 8px; }
.c-alert-msg { padding: 15px 20px 14px; text-align: center; border-bottom: .5px solid rgba(var(--ink), .12); }
.c-alert-msg b { display: block; font: 600 13px/18px var(--font-sans); color: var(--n-600); letter-spacing: 0; }
.c-alert-msg span { display: block; margin-top: 2px; font: 400 13px/18px var(--font-sans); color: var(--n-600); letter-spacing: 0; white-space: pre-line; }
.c-alert-msg span:empty { display: none; }
.c-alert-field { padding: 12px 14px 2px; }
:root .c-alert-btn { display: block; width: 100%; height: 57px; min-height: 0; margin: 0; padding: 0 12px; border: 0; border-radius: 0; background: transparent; box-shadow: none; cursor: pointer; font: 400 20px/1 var(--font-display); letter-spacing: -0.012em; color: var(--c-accent-text); white-space: normal; transition: background-color 120ms; }
:root .c-alert-btn + .c-alert-btn { border-top: .5px solid rgba(var(--ink), .12); }
:root .c-alert-btn:hover { background: transparent; }
:root .c-alert-btn:active, :root .c-alert-btn.is-pressed { background: rgba(var(--ink), .07); transform: none; }
:root .c-alert-btn:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--lav-500); }
:root .c-alert-btn.is-destructive { color: var(--red-600); }
:root .c-alert-btn.is-cancel { font-weight: 600; background: #fff; }
:root .c-alert-btn.is-cancel:active { background: var(--n-100); }
@media (min-width: 701px) {
  .c-alert { align-items: center; padding: 24px; }
  .c-alert-box { display: flex; flex-direction: column; max-width: 290px; border-radius: 14px; box-shadow: var(--el-float); animation: c-alert-in var(--d-snappy) var(--spring) backwards; }
  .c-alert.is-closing .c-alert-box { animation: c-dialog-out var(--exit-d, 180ms) var(--ease-exit-ios) forwards; }
  .c-alert-group { border-radius: 14px; background: rgba(255, 255, 255, .92); }
  /* na komputerze jedna karta: „Anuluj” pod akcją, oddzielone linią */
  .c-alert-group:has(+ .c-alert-group) { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
  .c-alert-group + .c-alert-group { margin-top: 0; border-top: .5px solid rgba(var(--ink), .12); border-top-left-radius: 0; border-top-right-radius: 0; }
  :root .c-alert-btn.is-cancel { background: transparent; }
  :root .c-alert-btn { height: 46px; font-size: 17px; }
  .c-alert-msg { padding: 18px 18px 16px; }
  .c-alert-msg b { font-size: 17px; line-height: 22px; color: var(--c-text); }
}

/* =====================================================================
   TOAST – pigułka u góry (Dynamic Island) + HUD na środku (SPEC 2.20)
   centrowanie translateX(-50%) statycznie i w obu klatkach (kontrakt 0.11); nie przechwytuje kliknięć
   ===================================================================== */
:root #toast, :root body.portal #toast {
  position: fixed; z-index: 100; left: 50%; right: auto; top: calc(var(--sa-t) + 10px); bottom: auto;
  display: flex; align-items: center; gap: 10px; width: max-content; max-width: min(92vw, 420px); min-height: 46px;
  padding: 8px 18px 8px 9px; border-radius: 23px; background: var(--glass-dark); color: #fff;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  font: 600 15px/20px var(--font-sans); letter-spacing: -0.01em; box-shadow: 0 18px 40px -16px rgba(var(--ink), .6);
  transform: translateX(-50%); pointer-events: none;
  animation: c-toast-in var(--d-sheet) var(--spring-bounce) backwards;
}
:root #toast::before { content: ""; flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; box-shadow: none; background: var(--green-500) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center/15px no-repeat; }
:root #toast.error { background: var(--glass-dark); }
:root #toast.error::before { background-color: var(--red-600); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round'%3E%3Cpath d='M12 7v6M12 17h.01'/%3E%3C/svg%3E"); }
:root #toast.toast-out { animation: c-toast-out var(--d-exit-toast) var(--ease-exit-ios) forwards; }
.c-hud { position: fixed; z-index: 99; left: 50%; top: 50%; width: 156px; height: 156px; margin: -78px 0 0 -78px; border-radius: 22px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 0 12px; text-align: center; background: rgba(255, 255, 255, .82); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur); box-shadow: var(--el-float); color: var(--c-text); font: 600 15px/19px var(--font-sans); letter-spacing: -0.01em; pointer-events: none; animation: c-hud 1400ms var(--ease-out) forwards; }
.c-hud svg { width: 52px; height: 52px; fill: none; stroke: var(--green-600); stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; }
.c-hud svg path { stroke-dasharray: 30; stroke-dashoffset: 30; animation: c-draw 360ms var(--ease-out) 120ms forwards; }

/* =====================================================================
   FOKUS – pierścień na powłoce i odstęp od przyklejonych pasków (T7, audyt dostępności: WCAG 2.4.7, 1.4.11, 2.4.11)
   ===================================================================== */
/* Na lawendzie (#a794c0) pierścień 2 px bieli + 2 px --lav-500 prawie znikał (--lav-500/#a794c0 1,29:1), a na białej pigułce
   aktywnej pozycji biel zlewała się z pigułką. Na powłoce: ciemny środek (--lav-900 – 4,83:1 na lawendzie, 13,3:1 na bieli)
   i biały brzeg. Kolor powłoki i biały tekst bez zmian. Reguły z własnym pierścieniem w arkuszach ekranów (samo 2 px bieli,
   np. #top-nav, .c-jump) muszą przejść na var(--ring) – KOLEJKA. */
:root :is(header.c-shell, .portal-head) { --ring: 0 0 0 2px var(--lav-900), 0 0 0 4px #fff; }

/* Fokus z klawiatury nie może się chować pod przyklejonymi paskami: przeglądarka przewija tylko wtedy, gdy element wychodzi
   poza okno pomniejszone o scroll-padding. Panel (telefon): pływający pasek kart 64 px u dołu (u góry wystarcza istniejące
   scroll-margin-top paneli – górne dopełnienie sumowałoby się z nim). Portal: pasek u góry (52 px na telefonie, 64 px
   na komputerze, 108 px w dwóch rzędach przy 701–1279 px) + pasek wyboru dziecka (58 / 62 px, tylko przy 2+ dzieciach
   i poza Kontem i Wiadomościami), na telefonie pasek kart u dołu. Zapisy i wydarzenia: przyklejony przycisk wysyłki
   (74–100 px) i pasek kroków u góry. Zapas 8 px nad paskiem. */
@media (max-width: 700px) {
  html:has(> body.c-panel) { scroll-padding-bottom: calc(var(--sa-b) + 96px); }
  html:has(> body.c-portal) { scroll-padding-top: calc(var(--sa-t) + 60px); scroll-padding-bottom: calc(var(--sa-b) + 96px); }
  html:has(> body.c-portal #child-tabs:not(.hidden)):not(:has(#v-acc.active, #v-msg.active)) { scroll-padding-top: calc(var(--sa-t) + 118px); }
}
@media (min-width: 701px) {
  html:has(> body.c-portal) { scroll-padding-top: calc(var(--sa-t) + 72px); }
  html:has(> body.c-portal #child-tabs:not(.hidden)):not(:has(#v-acc.active, #v-msg.active)) { scroll-padding-top: calc(var(--sa-t) + 134px); }
}
@media (min-width: 701px) and (max-width: 1279px) {
  html:has(> body.c-portal) { scroll-padding-top: calc(var(--sa-t) + 116px); }
  html:has(> body.c-portal #child-tabs:not(.hidden)):not(:has(#v-acc.active, #v-msg.active)) { scroll-padding-top: calc(var(--sa-t) + 178px); }
}
html:has(.c-sticky-cta) { scroll-padding-bottom: calc(var(--sa-b) + 120px); }
html:has(.c-onb-bar) { scroll-padding-top: calc(var(--onb-h, 52px) + var(--sa-t) + 8px); }
@media print { html { scroll-padding: 0; } }

/* =====================================================================
   NISKIE OKNO (T7, runda 2): powiększenie 200 % na komputerze (720×450), telefon w poziomie (667×375, 844×390)
   Przyklejone paski zajmowały 38–62 % wysokości (arkusz zajęć: na listę zostawało 138 px). Przy wysokości ≤ 520 px nagłówek
   i stopka arkusza, uchwyt arkusza, pasek portalu, pasek wyboru dziecka i przycisk wysyłki zapisów jadą z treścią – jak
   duży tytuł iOS, który zwija się przy małej wysokości. Okno dalej zamyka Escape, tło i przeciągnięcie; pasek kart
   na telefonie (fixed) i pasek kroków zapisów zostają. Selektory z wyższą specyficznością niż reguły przyklejenia
   (panel.css #att-modal / #child-modal, ui-portal.css, ui-public.css – ładowane później). Bez przyklejenia nie ma czego
   omijać – dopełnienia przewijania tylko z zapasem 8 px (pasek kart: bez zmian).
   ===================================================================== */
@media (max-height: 520px) {
  :root body .modal-backdrop .modal > .c-sheet-head,
  :root body .modal-backdrop .modal > .c-sheet-foot,
  :root body .modal-backdrop .modal > form > .c-sheet-foot,
  :root body :is(#child-modal, #att-modal) .modal > .form-actions.c-sheet-foot { position: relative; }
  :root .modal-backdrop .modal:has(> .c-sheet-head)::before { position: relative; }
  :root .modal-backdrop .modal:has(> .c-sheet-head) { scroll-padding-top: 8px; }
  :root .modal-backdrop .modal:has(> .c-sheet-foot, > form > .c-sheet-foot) { scroll-padding-bottom: 8px; }
  :root:root body.c-portal .portal-head { position: relative; }
  :root:root body.c-portal .c-child-bar { position: relative; top: auto; }
  :root body .c-sticky-cta { position: relative; }
  html:has(> body.c-portal),
  html:has(> body.c-portal #child-tabs:not(.hidden)):not(:has(#v-acc.active, #v-msg.active)) { scroll-padding-top: calc(var(--sa-t) + 8px); }
  html:has(.c-sticky-cta) { scroll-padding-bottom: calc(var(--sa-b) + 8px); }
}

/* =====================================================================
   WYMUSZONE KOLORY (Windows – Kontrast, forced-colors: active) – T7, runda 2, WCAG 2.4.7 i 1.4.11
   Tryb usuwa box-shadow i tła pseudoelementów: pierścień fokusu (var(--ring)), kciuk segmentów, soczewka paska kart i tor
   przełącznika znikały. Tu: fokus = obwódka w kolorze systemowym Highlight (bez fokusu programowego tabindex="-1" –
   nagłówki okien, kontenery powrotu fokusu), wybrana pozycja segmentów i pasków = obwódka SelectedItem do środka,
   przełącznik rysowany kolorami systemowymi (tor z obwódką, gałka, stan włączony = Highlight). Poza tym trybem bez zmian.
   ===================================================================== */
@media (forced-colors: active) {
  :root :focus-visible:not([tabindex="-1"]) { outline: 2px solid Highlight !important; outline-offset: 2px !important; }
  /* pole przełącznika jest przezroczyste (opacity 0) – obwódka na widocznym torze */
  :root .c-switch input:focus-visible + i { outline: 2px solid Highlight; outline-offset: 2px; }
  :root .c-switch i { forced-color-adjust: none; background: Canvas; border: 1px solid CanvasText; }
  :root .c-switch i::after { top: 1px; left: 1px; background: CanvasText; box-shadow: none; }
  :root .c-switch input:checked + i { background: Highlight; border-color: Highlight; }
  :root .c-switch input:checked + i::after { background: HighlightText; }
  :root .c-switch input:disabled + i { opacity: 1; border-color: GrayText; }
  :root .c-switch input:disabled + i::after { background: GrayText; }
  :root :is(.c-seg, #cal-view, .c-city-seg, #participants-subnav, .rate-tabs, #child-tabs, #top-nav, #bottom-nav, .c-shell-tabs) > :is(.active, .is-active, [aria-pressed="true"], [aria-current="page"]) { outline: 2px solid SelectedItem; outline-offset: -2px; }
}

/* =====================================================================
   KLATKI KLUCZOWE
   ===================================================================== */
@keyframes c-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes c-fade-out { from { opacity: var(--exit-o, 1); } to { opacity: 0; } }
/* przyciemnienie: druga klatka niejawna = bieżąca wartość (po przeciągnięciu wyjście startuje od --scrim-k) */
@keyframes c-scrim-in { from { opacity: 0; } }
@keyframes c-scrim-out { to { opacity: 0; } }
@keyframes c-tint-in { from { background-color: transparent; } }
@keyframes c-tint-out { to { background-color: transparent; } }
/* animacja bez efektu – nośnik animationend / animacji wyjścia na samym .modal-backdrop (kontrakt 10) */
@keyframes c-hold { from, to { visibility: visible; } }
@keyframes c-hold-out { from, to { visibility: visible; } }
@keyframes c-view-in { from { opacity: .001; transform: translate3d(var(--dir-x, 0px), 8px, 0); } to { opacity: 1; transform: none; } }
@keyframes c-dialog-in { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
/* wyjście okna i arkusza rusza z punktu, w którym jest (ui.js: --exit-o, --exit-s, --drag-y – przeciągnięcie albo zamknięcie
   w trakcie wejścia); bez zmiennych jak dawniej (krycie 1, skala 1, przesunięcie 0) */
@keyframes c-dialog-out { from { opacity: var(--exit-o, 1); transform: scale(var(--exit-s, 1)); } to { opacity: 0; transform: scale(.97); } }
@keyframes c-alert-in { from { opacity: 0; transform: scale(1.12); } to { opacity: 1; transform: none; } }
@keyframes c-sheet-in { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes c-sheet-out { from { transform: translateY(var(--drag-y, 0px)); } to { transform: translateY(105%); } }
@keyframes c-toast-in { from { opacity: 0; transform: translate(-50%, -150%) scale(.9); } to { opacity: 1; transform: translate(-50%, 0) scale(1); } }
@keyframes c-toast-out { from { opacity: 1; transform: translate(-50%, 0); } to { opacity: 0; transform: translate(-50%, -130%) scale(.94); } }
@keyframes c-reveal { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes c-pop-in { from { opacity: 0; transform: scale(.4); } to { opacity: 1; transform: none; } }
@keyframes c-bar-in { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes c-tick { from { opacity: 0; transform: translateY(55%); } to { opacity: 1; transform: none; } }
@keyframes c-shake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-5px); } 40% { transform: translateX(5px); } 60% { transform: translateX(-3px); } 80% { transform: translateX(3px); } }
@keyframes c-spin { to { transform: rotate(360deg); } }
@keyframes c-skel { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes c-pulse { 0% { box-shadow: 0 0 0 0 rgba(232, 161, 60, .55); } 100% { box-shadow: 0 0 0 9px rgba(232, 161, 60, 0); } }
@keyframes c-flash-paid { 0% { background-color: var(--green-50); } 100% { background-color: transparent; } }
@keyframes c-hud { 0% { opacity: 0; transform: scale(.86); } 14% { opacity: 1; transform: scale(1); } 80% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(.96); } }
@keyframes c-draw { to { stroke-dashoffset: 0; } }
@keyframes c-today { 0%, 100% { transform: scale(1); } 40% { transform: scale(1.1); } }

/* =====================================================================
   REDUKCJA RUCHU / PRZEZROCZYSTOŚCI, DRUK (SPEC 10, 11)
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  :root .modal-backdrop .modal, .c-alert-box { animation: c-fade-in 150ms linear backwards !important; }
  :root .modal-backdrop.is-closing .modal, .c-alert.is-closing .c-alert-box { animation: c-fade-out 150ms linear forwards !important; }
  .c-hud { animation: c-fade-in 150ms linear both !important; }
  .c-hud svg path { stroke-dashoffset: 0; }
  :root #toast { animation: c-fade-in 150ms linear backwards !important; }
  :root #toast.toast-out { animation: c-fade-out 150ms linear forwards !important; }
  .c-form-row.is-ok::after, :root .nav-badge:not(.hidden), .c-badge { animation: none !important; }
}
@media (prefers-reduced-transparency: reduce) {
  :root .c-sheet-head, :root .c-sheet-foot, :root .modal .c-sheet-foot.form-actions, .c-alert-group, .c-hud { background: #fff !important; -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
  :root .modal-backdrop::before, :root #toast { -webkit-backdrop-filter: none; backdrop-filter: none; }
  :root #toast { background: var(--lav-900); }
}
@media print {
  header.c-shell, .c-shell-tabs, .c-nav-ind, .c-jump, .c-me, .c-notes, .c-legend-pop, .c-att-summary, .c-pay-hero, .c-quick-home, .c-child-bar,
  .c-hud, .c-alert, .sheet-x, :root #toast { display: none !important; }
  /* Bez rozmytych cieni: Chrome zapisuje każdą warstwę z rozmyciem jako obraz z maską miękką (/SMask /Luminosity), a podgląd i druk
     na macOS (Quartz) rysują w tym miejscu pełny prostokąt w kolorze cienia – także bez „Grafiki tła”. Ostre warstwy zostają
     (obwódki, linie podziału, paski kolorów zajęć), dlatego tokeny i wybrane reguły, a nie box-shadow: none dla wszystkich. */
  :root {
    --sh-1: 0 0 0 1px rgba(var(--lav-rgb), .05); --sh-2: 0 0 0 1px rgba(var(--ink), .05); --sh-3: 0 0 0 1px rgba(var(--ink), .06);
    --sh-accent: 0 0 transparent; --sh-accent-hover: 0 0 transparent; --sh-brand: 0 0 transparent; --sh-seg: 0 0 0 1px rgba(var(--ink), .04);
    --el-1: 0 0 0 .5px rgba(var(--ink), .05); --el-float: 0 0 0 .5px rgba(var(--ink), .07); --el-tile: 0 0 transparent;
  }
  html:root { --vw-group-sh: 0 0 0 .5px var(--n-200); }   /* html: – definicja w ui-panel-widoki.css ładuje się później */
  :root :is(button, a).small.primary, :root .btn-white { --btn-sh: 0 0 transparent !important; }
  :root :is(.c-seg, #participants-subnav, #sub-pay .subnav.rate-tabs)::before, :root #indiv-form .indiv-mode > label.inline-check:has(> input:checked) {
    box-shadow: 0 0 0 .5px rgba(var(--ink), .04) !important; }
  :root #pe-root .pe-card { box-shadow: var(--vw-group-sh) !important; }
  :root :is(#pe-root .pe-poster img, #ann-list .ann-photo, #ann-photo-preview img) { box-shadow: 0 0 0 .5px rgba(var(--ink), .08) !important; }
  :root body.c-portal #home-events .pw-poster { box-shadow: 0 0 0 .5px rgba(var(--ink), .06) !important; }
  :root body.c-portal #msg-text { box-shadow: 0 0 0 .5px rgba(var(--ink), .1) !important; }
  :root #inbox-messages .chat-msg:not(.me) { box-shadow: 0 0 0 .5px rgba(var(--ink), .06) !important; }
  :root #allpay-months .month-tile.active { box-shadow: 0 0 0 2px var(--lav-400) !important; }
  :root #step-form > p.c-place a.c-place-change { box-shadow: 0 0 0 .5px rgba(var(--ink), .05) !important; }
  .c-switch i::after, :root .cal-now span, :root :is(#indiv-list, #indiv-week-list, #tr-list, #tr-admin-list) > .req-card::before,
  :root #instr-list > .pay-row > .pay-name::before, :root #tab-events #ev-tabs > .auth-tab.active, :root body.c-portal #chat .chat-msg.me .chat-text,
  .c-done-ico, :root #step-done .done-ico, :root #pay-status .c-pay-wait { box-shadow: none !important; }
}
