/* ============================================================
   Panel webweb — design system v8 (MATOWE PŁASZCZYZNY · ciepła czerń)
   Zamiast szkła i połysku: płaskie, nieprzezroczyste płyty na ciepłej czerni,
   obrysy-włoski, miękkie promienie i dużo powietrza. Hierarchia robi się
   JASNOŚCIĄ warstwy (strona → karta → element w karcie), nie rozmyciem tła.
   Kolorystyka bez zmian poza tłem: akcent #ff005c, przyciski --accent-btn /
   --danger-btn, statusy i motyw jasny zostają na swoich wartościach.
   Anty-miganie: brak backdrop-filter na hero logowania (animowany canvas),
   okno powiadomień nieprzezroczyste.
   Manrope (nagłówki) · Inter (tekst) · JetBrains Mono (mikro-etykiety)
   ============================================================ */
@import url('/css/jetbrains-mono.css');
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Manrope:wght@600;700;800&display=swap');

:root{
  /* TŁO — ciepła czerń zamiast czystej #020202. Czysta czerń pod matową płytą
     daje twardą, „dziurawą" krawędź; lekko ciepły, rozjaśniony grafit sprawia,
     że karta wygląda jak położona NA powierzchni, a nie wycięta w niej. */
  --bg:#0c0b0c; --bg-2:#100f11;
  --bg-glow:radial-gradient(120% 78% at 50% -12%, rgba(255,0,92,.065), rgba(255,0,92,0) 62%);
  /* Tafle mają JEDNOLITY, nieprzezroczysty kolor. Wcześniej były półprzezroczystą
     bielą (rgba) — a przezroczystości SUMUJĄ SIĘ przy zagnieżdżeniu: karta w karcie
     w karcie wychodziła za każdym razem jaśniejsza. Stąd „różne odcienie".
     TERAZ dwie warstwy mają RÓŻNE wartości i to jest cała hierarchia:
     --surface-2 = KARTA (na tle strony), --surface = ELEMENT W KARCIE
     (wiersz tabeli, pole, kafelek, chip). Zawsze o jeden krok jaśniej. */
  --surface:#1a181b; --surface-2:#151416;
  --border:rgba(255,255,255,.075); --border-2:rgba(255,255,255,.14); --border-3:rgba(255,255,255,.24);
  /* --faint podbity z #6b6773 (3.42:1 — fail AA) do 4.62:1 na --surface: używany w
     placeholderach, pustych stanach i etykietach 9-11px, więc MUSI zdać 4.5:1.
     Po rozjaśnieniu płyt przeliczone: --faint 4.62:1, --accent jako tekst 4.54:1. */
  /* --faint musi zdać 4.5:1 na NAJJAŚNIEJSZEJ płaszczyźnie ciemnego motywu, czyli na
     nagłówku okna (--modal-head #1d1b1f) — nie na tle strony. #858189 dawało tam 4.47:1,
     #8a868e daje 4.79:1 i wciąż siedzi wyraźnie niżej niż --muted. */
  --txt:#f1f0f4; --muted:#a19da8; --faint:#8a868e;
  --accent:#ff005c; --accent-2:#ff3d78; --accent-soft:rgba(255,0,92,.13);
  --ok:#2bd18a; --st-ok:#2bd18a; --st-warn:#e0a33a; --st-bad:#ff5a72; --ok-bg:rgba(43,209,138,.14);
  --danger:#ff5a72; --danger-bg:rgba(255,90,114,.13);
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  /* TYPOGRAFIA. Inter zamiast Lato w tekście: wyższy x-height i otwarte litery
     czytają się lepiej w 13-14 px, czyli w rozmiarze, w którym panel realnie żyje
     (tabele, etykiety, opisy). Ma też cyfry o stałej szerokości — kwoty i daty
     w kolumnach przestają „tańczyć". Manrope w nagłówkach zamiast Exo: bardziej
     zwarty, geometryczny rysunek, który przy ujemnym trackingu daje mocny,
     spokojny tytuł zamiast technicznego. */
  --sans:'Inter','Segoe UI',system-ui,-apple-system,Roboto,Arial,sans-serif;
  --head:'Manrope','Inter','Segoe UI',system-ui,sans-serif;
  /* SKALA TYPOGRAFII — jedno źródło rozmiarów zamiast 26 wartości „na oko" (m.in.
     ułamkowych 13.5/12.5/9.5). PODŁOGA 11px: nic mniejszego, bo poniżej robi się
     nieczytelne. Mono-etykiety (uppercase) bywają najmniejsze i to im wystarcza. */
  --fs-2xs:11px; --fs-xs:12px; --fs-sm:13px; --fs-base:14px; --fs-md:16px;
  /* Górne stopnie podbite (26→28, 30→34): tytuł strony i liczba na kafelku to
     jedyne miejsca, w których typografia ma mówić głośno. Dolne stopnie BEZ ZMIAN —
     to one decydują o gęstości tabel i o tym, czy treść mieści się w kartach. */
  --fs-lg:19px; --fs-xl:23px; --fs-2xl:28px; --fs-3xl:34px;
  /* SKALA ODSTĘPÓW — siatka 4px. Wartości dokładnie pasujące do siatki mają teraz
     token (bez zmiany wyglądu); wartości „pomiędzy" zostają celowo — ich hurtowe
     zaokrąglanie byłoby przeprojektowaniem, nie porządkowaniem. */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px; --sp-8:32px; --sp-10:40px;
  /* PROMIENIE. KRAWĘDZIE OSTRE (--r-*:0) — decyzja produktowa wspólna ze stroną firmową
     (PRODUCT.md), nie niedopatrzenie. Rozdzielenie płaszczyzn robi tu RÓŻNICA JASNOŚCI
     i kreska obrysu, nie łuk narożnika. Cały arkusz odwołuje się wyłącznie do tych
     tokenów (zero twardych pikseli), więc przejście na miękkie narożniki to zmiana
     tej jednej linii: 14/10/8/6 px = karta > kontrolka > drobiazg.
     --r-pill zostaje dla rzeczy z natury okrągłych: avatar, odznaki, przyciski-ikony,
     paski postępu — te były okrągłe także przed restylizacją. */
  --r-card:0; --r-ctrl:0; --r-sm:0; --r-xs:0; --r-pill:999px;
  --blur:16px;
  /* SZKŁO WYŁĄCZONE. backdrop-filter mieszał treść spod spodu w tło karty — przy
     przewijaniu każda tafla zmieniała odcień, a hierarchia warstw znikała. Teraz
     płaszczyzny są matowe i nieprzezroczyste; token zostaje, żeby nie tykać
     kilkunastu deklaracji `backdrop-filter:var(--glass)`. */
  --glass:none;
  --edge:rgba(255,0,92,.28);            /* akcent krawędzi — paski boczne, obrysy */
  /* POŁYSK WYŁĄCZONY (tafle i przyciski). Gradient na górze elementu dawał mu dwa
     odcienie i „plastikowy" refleks. Kolory przycisków zostają bez zmian — znika
     wyłącznie nakładka. Wartość `none` jest poprawna dla `background`. */
  --gloss:none;
  --gloss-panel:none;
  --gloss-strong:none;
  /* Biała linia górnej krawędzi zredukowana niemal do zera. UWAGA: `none` W ŚRODKU
     listy box-shadow jest niepoprawne i unieważnia CAŁĄ deklarację — stąd
     ledwo widoczna, ale prawidłowa wartość zamiast wyłączenia. */
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.035);
  /* Cień płaski i bliski (kontaktowy) + delikatna poświata — tafla ma leżeć na tle,
     a nie unosić się nad nim. Duże, rozmyte cienie zostają dla okien i menu. */
  --shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px -26px rgba(0,0,0,.9);
  --shadow-lg:0 24px 60px -22px rgba(0,0,0,.72),0 6px 18px -10px rgba(0,0,0,.55);
  --glow:0 4px 20px rgba(255,0,92,.26);
  --sidebar-w:256px; --topbar-h:68px;
  /* KOLORY TŁA PRZYCISKÓW — osobno od kolorów TEKSTU. Ten sam róż nie może pełnić obu ról:
     --accent (#ff005c) jako TEKST na ciemnej karcie ma 4.85:1 (zdaje AA), ale jako TŁO pod
     BIAŁYM napisem tylko 3.88:1 — poniżej progu 4.5:1 dla zwykłego tekstu (WCAG 1.4.3), a
     napis na przycisku ma 14px/700, więc nie liczy się jako „duży tekst". Dlatego tła mają
     własne, minimalnie ciemniejsze tokeny; kolory tekstu zostają nietknięte.
     --accent-btn 4.50:1 z bielą (było 3.88), --danger-btn 4.76:1 (było 3.02). */
  --accent-btn:#eb0055;
  --danger-btn:#e01e37;
  /* MOTION — skala czasów zamiast 10 wartości „na oko" (.12/.14/.15/.16/.18/.2/.25/.28/.4/.5s),
     z których połowa była nieodróżnialna gołym okiem. Trzy kroki wystarczają: mikro-reakcja
     kontrolki, standardowe przejście, wejście/wyjście większej płaszczyzny (modal, panel).
     Krzywa standardowa jak w Material Design (szybki start, łagodne dojście). */
  --dur-fast:.12s; --dur-base:.16s; --dur-slow:.25s;
  --ease-std:cubic-bezier(.4,0,.2,1);
}
*{box-sizing:border-box}
html,body{margin:0}
body{
  font-family:var(--sans); color:var(--txt); line-height:1.62;
  /* Tło = jednolity kolor + jedna bardzo delikatna poświata u GÓRY dokumentu.
     Nie jest ozdobą: daje górze ekranu (nagłówek sekcji, pierwsze karty) minimalnie
     inną wartość niż dołowi, przez co strona przestaje być płaskim prostokątem.
     Bez `fixed` — poświata przewija się razem z treścią, więc nie ma przemalowania
     całego tła w każdej klatce przewijania. */
  background:var(--bg-glow) no-repeat top center/100% 760px, var(--bg);
  min-height:100vh;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  font-variant-numeric:tabular-nums;
}
a{color:var(--accent-2);text-decoration:none;transition:color var(--dur-base)}
a:hover{color:var(--txt)}
::selection{background:var(--accent);color:#fff}
/* NAGŁÓWKI: ciasny tracking i ciasna interlinia. Tytuł ma być zwartym blokiem,
   który wzrok bierze jednym spojrzeniem — to on nadaje stronie rytm, nie ramki. */
h1,h2,h3{font-family:var(--head);letter-spacing:-.022em;line-height:1.18}

/* Ikony — miękkie i czyste (zaokrąglone końce, spójna grubość) */
.app svg *, .auth-split svg *, .ww-wrap svg *{stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}

/* ============================================================
   DASHBOARD SHELL  (.app = sidebar + main)
   ============================================================ */
.app{display:flex;min-height:100vh}

/* ---- sidebar (matowa kolumna) ---- */
.sidebar{
  position:sticky;top:0;align-self:flex-start;height:100vh;
  width:var(--sidebar-w);flex:0 0 var(--sidebar-w);
  /* Ten sam kolor co tło strony, rozdzielone WŁOSEM. Nawigacja nie jest treścią,
     więc nie dostaje własnej płyty — ma zniknąć w tle i wracać dopiero pod kursorem. */
  background:var(--bg);
  border-right:1px solid var(--border);
  display:flex;flex-direction:column;padding:22px var(--sp-4);gap:2px;z-index:40;
}
.side-logo{font-family:var(--head);font-weight:800;font-size:var(--fs-xl);letter-spacing:-.5px;
  display:flex;align-items:center;gap:9px;padding:6px var(--sp-3) var(--sp-5);color:var(--txt);text-decoration:none;cursor:pointer}
.side-logo:hover{opacity:.8}
.side-logo span{color:var(--accent)}
.side-sec{font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:1.8px;text-transform:uppercase;
  color:var(--faint);padding:18px 14px var(--sp-2);font-weight:500}
.nav{display:flex;flex-direction:column;gap:2px}
.nav-item{
  display:flex;align-items:center;gap:13px;padding:11px 14px;border-radius:var(--r-sm);
  color:var(--muted);font-size:var(--fs-base);font-weight:600;cursor:pointer;border:none;background:none;
  width:100%;text-align:left;font-family:var(--sans);text-decoration:none;
  transition:background var(--dur-base),color var(--dur-base);position:relative;
}
.nav-item svg{width:19px;height:19px;flex:0 0 19px}
.nav-item:hover{color:var(--txt);background:rgba(255,255,255,.045)}
.nav-item.active{color:var(--txt);background:rgba(255,0,92,.12)}
.nav-item.active::before{content:"";position:absolute;left:0;top:9px;bottom:9px;width:2.5px;background:var(--accent);box-shadow:0 0 10px var(--accent)}
.nav-item.active svg{color:var(--accent-2)}
.side-foot{margin-top:auto;display:flex;flex-direction:column;gap:var(--sp-2);padding-top:var(--sp-4);border-top:1px solid var(--border)}
/* przycisk „Zamknij menu" — widoczny tylko w trybie wysuwanym (tablet/mobile) */
.side-close{display:none;align-items:center;justify-content:center;gap:var(--sp-2);width:100%;
  margin:0 0 10px;padding:var(--sp-3);background:var(--surface);border:1px solid var(--border-2);
  border-radius:var(--r-ctrl);
  color:var(--txt);font-family:var(--sans);font-weight:700;font-size:var(--fs-sm);cursor:pointer}
.side-close svg{width:18px;height:18px}
.side-close:hover{border-color:var(--accent-2)}
.side-close:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
/* przewijana nawigacja (gdy dużo pozycji) — środek scrolluje, logo i stopka przypięte */
.side-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:2px;
  scrollbar-width:thin;scrollbar-color:var(--border-2) transparent}
.side-scroll::-webkit-scrollbar{width:8px}
.side-scroll::-webkit-scrollbar-thumb{background:var(--border-2)}
.side-more{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;margin:var(--sp-2) 0 var(--sp-1);padding:9px;
  background:none;border:1px dashed var(--border-2);border-radius:var(--r-sm);color:var(--muted);font-family:var(--sans);font-size:var(--fs-sm);font-weight:600;cursor:pointer}
.side-more:hover{color:var(--txt);border-color:var(--muted)}
.side-more:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}

/* ---- main column ---- */
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  position:sticky;top:0;z-index:30;min-height:var(--topbar-h);
  display:flex;align-items:center;gap:var(--sp-4);justify-content:space-between;padding:0 26px;
  background:var(--bg);
  border-bottom:1px solid var(--border);
}
.menu-btn{display:none;width:42px;height:42px;border-radius:var(--r-ctrl);border:1px solid var(--border-2);
  background:var(--surface);color:var(--txt);align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto}
.menu-btn svg{width:20px;height:20px}
.search{flex:1;max-width:440px;position:relative}
.search input{padding-left:42px;border-radius:var(--r-ctrl);background:var(--surface);height:42px}
.search svg{position:absolute;left:15px;top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--faint);pointer-events:none}
.top-right{display:flex;align-items:center;gap:var(--sp-3);flex:0 0 auto}
.icon-btn{position:relative;width:42px;height:42px;border-radius:var(--r-pill);border:1px solid var(--border);
  background:var(--surface);color:var(--muted);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:var(--dur-base)}
.icon-btn:hover{border-color:var(--accent-2);color:var(--txt)}
.icon-btn svg{width:18px;height:18px}
.icon-btn .dot{position:absolute;top:9px;right:10px;width:7px;height:7px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 2px var(--surface),0 0 8px var(--accent)}
.user-chip{display:flex;align-items:center;gap:10px;padding:5px 14px 5px 5px;border-radius:var(--r-pill);
  border:1px solid var(--border);background:var(--surface)}
.avatar{width:34px;height:34px;border-radius:50%;flex:0 0 34px;
  background:var(--accent);color:#fff;box-shadow:var(--glow);
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:var(--fs-sm);font-family:var(--head)}
.uc-meta{display:flex;flex-direction:column;line-height:1.15}
.uc-name{font-size:var(--fs-sm);font-weight:700}
.uc-role{font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:1.2px;text-transform:uppercase;color:var(--muted)}
/* zegar auto-wylogowania (bezczynność) */
.idle-timer{display:flex;align-items:center;gap:7px;height:42px;padding:0 13px;border:1px solid var(--border);background:var(--surface);color:var(--muted);font-family:var(--mono);font-size:var(--fs-sm);white-space:nowrap}
.idle-timer svg{width:15px;height:15px;flex:0 0 15px}
.idle-timer b{color:var(--txt);font-weight:700;letter-spacing:.5px}
.idle-timer .il-lab{font-family:var(--sans);font-size:var(--fs-xs)}
.idle-timer.warn{background:var(--danger);border-color:var(--danger);color:#fff}
.idle-timer.warn b{color:#fff}
@media (max-width:900px){ .idle-timer .il-lab{display:none} }
@media (max-width:560px){ .idle-timer{padding:0 10px;font-size:var(--fs-xs)} }

/* ---- content ---- */
.content{padding:38px 34px 56px;max-width:1180px;width:100%;margin:0 auto}
/* Nagłówek strony dostaje więcej powietrza pod spodem niż nad kartami — to on
   otwiera widok, a odstęp jest tu jedynym separatorem (nie ma już kreski). */
.page-head{margin:0 0 32px}
.page-head h1{font-size:var(--fs-2xl);font-weight:800;letter-spacing:-.028em;line-height:1.12;margin:0}
.page-head p{margin:9px 0 0;color:var(--muted);font-size:var(--fs-base);max-width:74ch}

/* mobile sidebar overlay */
.side-ov{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:35;backdrop-filter:blur(2px)}
.side-ov.show{display:block}

/* ============================================================
   STAT CARDS  (matowe płyty)
   ============================================================ */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:18px;margin-bottom:var(--sp-6)}
.stat{position:relative;overflow:hidden;container-type:inline-size;padding:22px 22px;border-radius:var(--r-card);
  background:var(--surface-2);border:1px solid var(--border);
  box-shadow:var(--inset-hi),var(--shadow);transition:border-color var(--dur-base),transform var(--dur-base),box-shadow var(--dur-base)}
.stat::before{content:"";position:absolute;inset:0 0 auto 0;height:44%;background:var(--gloss-panel);pointer-events:none}
/* Hover rozjaśnia CAŁY obrys, nie samą górną krawędź: przy zaokrąglonym narożniku
   pasek innego koloru tylko u góry urywa się w połowie łuku i wygląda na usterkę. */
.stat:hover{border-color:var(--border-2);transform:translateY(-2px);box-shadow:var(--inset-hi),var(--shadow),0 10px 30px -18px rgba(255,0,92,.35)}
.stat .s-ico{position:relative;z-index:1;width:38px;height:38px;border-radius:var(--r-ctrl);
  background:var(--accent-soft);color:var(--accent-2);display:flex;align-items:center;justify-content:center;margin-bottom:var(--sp-4)}
.stat .s-ico svg{width:18px;height:18px}
.stat .s-num{position:relative;z-index:1;font-family:var(--head);font-size:var(--fs-3xl);font-weight:800;line-height:1;letter-spacing:-.035em}
/* Kafelki z KWOTĄ (klasa .is-fit nadawana w JS, gdy wartość zawiera „zł"): długi
   ciąg typu „128 000,00 zł" trzymamy w JEDNEJ linii, a font skaluje się do szerokości
   kafelka (container query) — bez zawijania „zł" i bez przycięcia przez overflow:hidden.
   Krótkie liczniki (np. „42") zostają duże, bo tej klasy nie dostają. */
.stat.is-fit .s-num{font-size:clamp(1.15rem,10cqi,var(--fs-3xl));line-height:1.05;letter-spacing:-.02em;
  white-space:nowrap;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.stat .s-lab{position:relative;z-index:1;font-family:var(--sans);font-size:var(--fs-sm);letter-spacing:0;
  text-transform:none;color:var(--muted);margin-top:10px;font-weight:500}

/* two-column content grid */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-5);align-items:start}

/* ---- kalendarz rezerwacji ---- */
.cal-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-4)}
.cal-title{font-family:var(--head);font-weight:700;font-size:var(--fs-lg);letter-spacing:-.3px;text-transform:capitalize}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.cal-dow{font-family:var(--mono);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.8px;color:var(--faint);text-align:center;padding:2px 0}
.cal-cell{min-height:80px;border:1px solid var(--border);border-radius:var(--r-sm);padding:7px;background:var(--surface);overflow:hidden}
.cal-cell.other{opacity:.4}
.cal-cell.today{border-color:var(--accent-2);box-shadow:0 0 0 1px var(--accent-2) inset,0 0 14px -4px var(--accent)}
.cal-daynum{font-size:var(--fs-xs);font-weight:700;color:var(--muted);margin-bottom:3px}
.cal-ev{font-size:var(--fs-2xs);padding:2px 6px;border-radius:var(--r-xs);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background:rgba(255,255,255,.055);color:var(--muted)}
.cal-ev.ok{background:var(--ok-bg);color:var(--ok)}
.cal-ev.warn{background:rgba(255,176,32,.15);color:#ffb020}
.cal-ev.odw{background:rgba(255,255,255,.045);color:var(--faint);text-decoration:line-through}
.cal-more{font-size:var(--fs-2xs);color:var(--faint);margin-top:3px}
@media (max-width:640px){ .cal-cell{min-height:58px;padding:var(--sp-1)} .cal-ev{font-size:var(--fs-2xs)} }

/* ============================================================
   CARD  (matowa płyta z obrysem-włosem)
   ============================================================ */
.ww-card{
  position:relative;overflow:hidden;
  background:var(--surface-2);
  border:1px solid var(--border); border-radius:var(--r-card);
  box-shadow:var(--inset-hi),var(--shadow);
  padding:26px 28px; margin-bottom:var(--sp-5);
}
.ww-card>*{position:relative;z-index:1}
.ww-card::before{content:"";position:absolute;inset:0 0 auto 0;height:38%;background:var(--gloss-panel);pointer-events:none;z-index:0}
.ww-card h2{margin:0 0 var(--sp-1);font-size:var(--fs-lg);font-weight:700;letter-spacing:-.022em;line-height:1.25}
.ww-card .sub{margin:0 0 20px;color:var(--muted);font-size:var(--fs-sm);line-height:1.6;max-width:78ch}
.ww-muted{color:var(--muted);font-size:var(--fs-sm)}
/* Nadtytuł: krótki, WERSALIKAMI, z szerokim światłem między literami — sygnalizuje
   „tu zaczyna się nowa sekcja" bez dokładania kolejnego dużego nagłówka. */
.eyebrow{font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.18em;text-transform:uppercase;color:var(--accent-2);font-weight:500}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap;margin-bottom:20px}
.card-head h2{margin:0}
.card-head .row{flex:0 0 auto;gap:var(--sp-2)}

/* ---------- forms ---------- */
label{display:block;font-family:var(--sans);font-size:var(--fs-sm);letter-spacing:0;text-transform:none;color:var(--muted);margin:var(--sp-4) 0 7px;font-weight:600}
/* POLA: matowa płaszczyzna o krok jaśniejsza od karty, bez „wklęsłego" cienia.
   Wgłębienie imitowało fizyczne pole formularza z 2010 r. i przy ciemnym motywie
   robiło z każdego pola czarną dziurę. Pole rozpoznaje się po jaśniejszym tle
   i obrysie, a przy pracy — po pierścieniu fokusu. */
input,select,textarea{
  width:100%;padding:11px 14px;font-size:var(--fs-base);font-family:var(--sans);
  background:var(--surface);border:1px solid var(--border-2);border-radius:var(--r-ctrl);color:var(--txt);
  transition:border-color var(--dur-base), box-shadow var(--dur-base), background var(--dur-base);
}
textarea{resize:vertical;line-height:1.55;min-height:76px}
input::placeholder,textarea::placeholder{color:var(--faint)}
input:hover:not(:focus),select:hover:not(:focus),textarea:hover:not(:focus){border-color:var(--border-3)}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--accent-2);box-shadow:0 0 0 3px var(--accent-soft)}
/* Checkboxy i radia to NIE pola tekstowe — reguła bazowa input{} nadaje width:100%+padding+tło,
   przez co w wierszach flex (np. checklista startu sklepu) rozdymają się na całą szerokość i
   miażdżą etykietę. Zerujemy to raz w jednym miejscu zamiast łatać inline style="width:auto". */
input[type=checkbox],input[type=radio]{width:auto;padding:0;background:none;border:none;box-shadow:none;accent-color:var(--accent)}

/* wiadomości (czat) */
.chat{display:flex;flex-direction:column;gap:10px;max-height:440px;overflow-y:auto;padding:var(--sp-1) 2px;margin-bottom:var(--sp-4)}
/* Dymki rozmowy: zaokrąglone, z jednym „przyciętym" narożnikiem od strony nadawcy —
   kierunek widać wtedy nawet bez czytania podpisu. */
.chat-msg{max-width:80%;padding:10px 14px;border:1px solid var(--border-2);border-radius:var(--r-card);font-size:var(--fs-base);line-height:1.5;white-space:pre-wrap;word-break:break-word}
.chat-msg.me{align-self:flex-end;background:var(--accent-soft);border-color:rgba(255,0,92,.32);border-bottom-right-radius:var(--r-xs)}
.chat-msg.them{align-self:flex-start;background:var(--surface);border-bottom-left-radius:var(--r-xs)}
.chat-msg .cm-meta{display:block;font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.4px;text-transform:uppercase;color:var(--faint);margin-top:6px}
.cm-del{color:var(--danger);text-decoration:none}
.cm-del:hover{color:var(--danger);text-decoration:underline}
/* zgłoszenia poprawek */
.cr-item{border:1px solid var(--border);border-radius:var(--r-ctrl);padding:13px 15px;margin-bottom:10px;background:var(--surface)}
.cr-item .cr-h{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;align-items:center}
.cr-item .cr-b{color:var(--muted);font-size:var(--fs-sm);margin-top:7px;white-space:pre-wrap;word-break:break-word}
/* akceptacja etapu projektu */
.appr-box{margin-top:14px;padding:13px 15px;border:1px solid rgba(255,0,92,.32);border-radius:var(--r-ctrl);background:var(--accent-soft)}
/* opieka nad stroną */
.site-card{border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface);padding:14px var(--sp-4);margin-bottom:var(--sp-3)}
.site-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:space-between}
.site-meta{display:flex;flex-direction:column;gap:5px;margin-top:var(--sp-2);font-size:var(--fs-sm)}
/* treść umowy do akceptacji */
.agr-body{max-height:220px;overflow-y:auto;border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface);padding:12px 14px;margin-top:var(--sp-2);white-space:pre-wrap;word-break:break-word;font-size:var(--fs-sm);color:var(--muted)}
/* jasne, widoczne ikony natywnych pól daty/godziny na ciemnym tle */
input[type=date],input[type=time],input[type=datetime-local],input[type=month],input[type=week]{color-scheme:dark}
html.html-light-mode input[type=date],html.html-light-mode input[type=time],html.html-light-mode input[type=datetime-local],html.html-light-mode input[type=month],html.html-light-mode input[type=week]{color-scheme:light}

/* modal potwierdzenia */
.modal-ov{position:fixed;inset:0;background:rgba(0,0,0,.62);backdrop-filter:blur(6px);z-index:100;display:none;align-items:center;justify-content:center;padding:var(--sp-5)}
.modal-ov.show{display:flex}
.modal{position:relative;overflow:hidden;background:var(--modal-bg);border:1px solid var(--border-2);border-radius:var(--r-card);max-width:440px;width:100%;padding:28px;
  box-shadow:var(--inset-hi),var(--shadow-lg)}
.modal::before{content:"";position:absolute;inset:0 0 auto 0;height:40%;background:var(--gloss-panel);pointer-events:none}
.modal>*{position:relative;z-index:1}
.modal h3{margin:0 0 var(--sp-2);font-family:var(--head);font-size:var(--fs-lg);font-weight:700}
.modal p{color:var(--muted);font-size:var(--fs-base);margin:0 0 22px;line-height:1.62}
.modal .modal-actions{display:flex;justify-content:flex-end;gap:10px;flex-wrap:wrap}

/* stepper projektu */
.proj{position:relative;overflow:hidden;border:1px solid var(--border);border-radius:var(--r-card);padding:var(--sp-5);margin-bottom:var(--sp-6);background:var(--surface-2);box-shadow:var(--inset-hi),var(--shadow);transition:box-shadow var(--dur-base) ease,transform var(--dur-base) ease,border-color var(--dur-base) ease}
.proj:hover{border-color:var(--border-2);box-shadow:var(--inset-hi),var(--shadow),0 12px 34px -20px rgba(255,0,92,.30);transform:translateY(-2px)}
.proj>*{position:relative;z-index:1}
.proj::before{content:"";position:absolute;inset:0 0 auto 0;height:36%;background:var(--gloss-panel);pointer-events:none}
.proj-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin:calc(var(--sp-5) * -1) calc(var(--sp-5) * -1) var(--sp-5);padding:var(--sp-4) var(--sp-5);background:var(--surface);border-bottom:1px solid var(--border)}
.proj-head b{font-family:var(--head);font-size:var(--fs-lg);letter-spacing:-.022em}
.stepper{display:flex;margin-bottom:14px}
.step{flex:1;text-align:center;position:relative;font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.4px;text-transform:uppercase;color:var(--faint);padding-top:22px}
.step::before{content:"";position:absolute;top:4px;left:50%;transform:translateX(-50%);width:12px;height:12px;border-radius:50%;border:2px solid var(--border-2);background:var(--surface);z-index:1}
.step::after{content:"";position:absolute;top:10px;left:50%;width:100%;height:2px;background:var(--border)}
.step:last-child::after{display:none}
.step.done{color:var(--muted)}
.step.done::before,.step.done::after{background:var(--accent);border-color:var(--accent)}
.step.active{color:var(--accent-2);font-weight:700}
.step.active::before{border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft),0 0 12px var(--accent)}
.progress{height:6px;border-radius:var(--r-pill);background:rgba(255,255,255,.09);overflow:hidden}
.progress .bar{height:100%;border-radius:var(--r-pill);background:var(--accent);box-shadow:0 0 12px var(--accent);transition:width .4s}
/* wybór wolnego terminu (sloty) */
.slots{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:10px 0}
.slot{padding:9px 13px;border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--surface);color:var(--txt);font-family:var(--mono);font-size:var(--fs-sm);cursor:pointer;transition:var(--dur-base)}
.slot:hover{border-color:var(--accent-2);color:var(--txt)}
.slot.sel{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:var(--glow)}
/* centrum powiadomień (dzwonek) — NIEPRZEZROCZYSTE (na życzenie) */
.notif-wrap{position:relative}
.notif-panel{position:absolute;right:0;top:52px;width:340px;max-width:86vw;max-height:460px;overflow-y:auto;background:var(--modal-bg);border:1px solid var(--border-2);border-radius:var(--r-card);z-index:50;display:none;
  box-shadow:var(--inset-hi),var(--shadow-lg)}
.notif-panel.show{display:block}
/* Mobile: panel powiadomień przyklejony do krawędzi ekranu (nie „ucieka" w lewo poza widok) */
@media (max-width:640px){
  .notif-panel{position:fixed;top:calc(var(--topbar-h) + 6px);left:10px;right:10px;width:auto;max-width:none;
    max-height:calc(100vh - var(--topbar-h) - 20px)}
}
.notif-panel .nh{padding:13px var(--sp-4);border-bottom:1px solid var(--border);font-family:var(--mono);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.12em;color:var(--muted);position:sticky;top:0;background:var(--modal-head)}
.notif-item{padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.notif-item.clk{cursor:pointer;transition:background var(--dur-fast)}
.notif-item.clk:hover{background:var(--accent-soft)}
.notif-item.clk:active{background:var(--accent-soft);opacity:.85}
.notif-item:last-child{border-bottom:none}
.notif-item.unread{background:var(--accent-soft)}
.notif-item .nt{font-size:var(--fs-sm);font-weight:700}
.notif-item .nb{font-size:var(--fs-xs);color:var(--muted);margin-top:2px}
.notif-item .nd{font-size:var(--fs-2xs);color:var(--faint);font-family:var(--mono);margin-top:var(--sp-1)}
/* pola daty w ustawieniach */
.chips{display:flex;flex-wrap:wrap;gap:6px;margin:var(--sp-2) 0}
.chip{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:var(--fs-2xs);padding:6px 11px;border:1px solid var(--border-2);border-radius:var(--r-sm);background:var(--surface)}
.chip button{background:none;border:none;color:var(--danger);cursor:pointer;font-size:var(--fs-base);line-height:1;padding:0}
.dow-days{display:flex;flex-wrap:wrap;gap:10px;margin:var(--sp-2) 0}
.dow-days label{display:inline-flex;align-items:center;gap:6px;text-transform:none;font-family:var(--sans);margin:0;color:var(--txt)}
.dow-days input{width:auto}

/* ocena gwiazdkami */
.stars{display:flex;gap:var(--sp-2);font-size:var(--fs-3xl);line-height:1;margin:6px 0 14px}
.stars span{cursor:pointer;color:var(--faint);transition:color .1s}
.stars span.on{color:#ffb020}

/* paginacja */
.pager{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:var(--sp-4)}
.pager .pg-info{font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.4px;color:var(--muted)}
.pager button[disabled]{opacity:.4;cursor:not-allowed}
select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2010%206'%3E%3Cpath%20d%3D'M0%200l5%205%205-5z'%20fill%3D'%23a19da8'%2F%3E%3C%2Fsvg%3E");background-position:calc(100% - 14px) center;background-size:10px 6px;background-repeat:no-repeat;padding-right:38px}

/* ---------- PRZYCISKI (płaskie, kolory bez zmian + miękka poświata) ----------
   Zniknęła wyłącznie nakładka połysku (gradient na górnej połowie). Tła, obrysy,
   kolor napisu i poświata zostają dokładnie te same — przycisk ma być jednolitą
   plamą koloru, bo to ona niesie „tu się klika", a nie refleks szkła. */
.btn{
  /* `overflow:hidden` jest TU NIEZBĘDNE, nie kosmetyczne (naprawione 2026-08-05).
     Przebłysk `.btn::after` (koniec pliku) startuje POZA przyciskiem — left:-45%,
     translateX(-160%) — i przelatuje do +480%, czyli daleko za jego prawą krawędź.
     Bez przycięcia ten świecący pasek wychodził z przycisku i przelatywał po
     sąsiednich elementach: zmierzone na przycisku 40→108 px pseudo-element był
     w połowie przelotu na 128→154 px, w pełni widoczny, na sąsiednim przycisku.
     Przycinanie respektuje border-radius, więc `.btn.sm` z własnym promieniem
     obsługuje się samo. To ten sam wzorzec, co `.stat`, `.ww-card`, `.modal`
     i `.proj` — każdy element z dekoracyjnym pseudo-elementem ma tę parę. */
  position:relative;overflow:hidden;
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  background:var(--accent-btn);color:#fff;border:1px solid rgba(255,0,92,.62);border-radius:var(--r-ctrl);
  padding:11px var(--sp-5);font-size:var(--fs-base);font-weight:700;letter-spacing:-.005em;cursor:pointer;text-decoration:none;font-family:var(--sans);
  box-shadow:var(--glow);
  transition:transform var(--dur-fast) cubic-bezier(.4,0,.2,1), box-shadow var(--dur-base), background var(--dur-base), border-color var(--dur-base), filter var(--dur-base);
}
.btn:hover{transform:translateY(-1px);filter:brightness(1.08);box-shadow:0 8px 26px rgba(255,0,92,.42)}
.btn:active{transform:translateY(1px) scale(.985);filter:none;box-shadow:inset 0 3px 8px rgba(0,0,0,.28)}
.btn:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
.btn.ghost{background:var(--surface);color:var(--txt);border-color:var(--border-2);box-shadow:none;filter:none}
.btn.ghost:hover{background:var(--surface);border-color:var(--accent-2);filter:none;box-shadow:0 6px 18px -8px rgba(255,0,92,.4)}
.btn.danger{background:var(--danger-btn);border-color:rgba(255,90,114,.62);box-shadow:0 4px 20px rgba(255,90,114,.3);color:#fff}
.btn.danger:hover{filter:brightness(1.07);box-shadow:0 8px 24px rgba(255,90,114,.42)}
.btn.sm{padding:7px 13px;font-size:var(--fs-sm);border-radius:var(--r-sm)}
.btn.block{width:100%}

/* separator „lub" + przycisk Google */
.or-sep{display:flex;align-items:center;gap:var(--sp-3);margin:var(--sp-5) 0;color:var(--faint);font-size:var(--fs-2xs);font-family:var(--mono);text-transform:uppercase;letter-spacing:.14em}
.or-sep::before,.or-sep::after{content:"";flex:1;height:1px;background:var(--border)}
.btn-google{position:relative;display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:var(--sp-3);background:#fff;color:#1f1f1f;border:1px solid var(--border-2);border-radius:var(--r-ctrl);font-weight:700;font-size:var(--fs-base);cursor:pointer;font-family:var(--sans);box-shadow:0 2px 10px rgba(0,0,0,.18);transition:transform var(--dur-fast),box-shadow var(--dur-base)}
.btn-google:hover{transform:translateY(-1px);box-shadow:0 6px 16px rgba(0,0,0,.22)}
.btn-google svg{width:18px;height:18px;flex:0 0 18px;position:relative;z-index:1}
.btn-google span,.btn-google *{position:relative;z-index:1}

.row{display:flex;gap:var(--sp-3);flex-wrap:wrap}.row>*{flex:1 1 180px}

/* ---------- tabs ---------- */
.tabs{display:flex;gap:4px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-ctrl);padding:4px;margin-bottom:var(--sp-5)}
.tab{position:relative;flex:1;padding:9px 10px;text-align:center;border-radius:var(--r-xs);background:transparent;cursor:pointer;font-weight:600;font-size:var(--fs-sm);color:var(--muted);border:none;transition:var(--dur-base);font-family:var(--sans)}
.tab:hover{color:var(--txt)}
.tab.active{background:var(--accent);color:#fff;font-weight:700;box-shadow:var(--glow)}
.tab:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}

/* pasek przełączania funkcji (widoków) w treści panelu */
.viewtabs{display:flex;gap:var(--sp-2);overflow-x:auto;padding:2px 0 18px;scrollbar-width:thin;scrollbar-color:var(--border-2) transparent}
.viewtabs::-webkit-scrollbar{height:7px}
.viewtabs::-webkit-scrollbar-thumb{background:var(--border-2)}
/* Afordancja przewijania paska zakładek: gradienty krawędzi + strzałki + podpowiedź.
   Klasy can-left / can-right dokłada JS, gdy naprawdę jest co przewijać. */
.vt-wrap{position:relative}
.vt-wrap::before,.vt-wrap::after{content:"";position:absolute;top:0;bottom:18px;width:40px;pointer-events:none;z-index:2;opacity:0;transition:opacity .2s}
.vt-wrap::before{left:0;background:linear-gradient(to right,var(--bg),transparent)}
.vt-wrap::after{right:0;background:linear-gradient(to left,var(--bg),transparent)}
.vt-wrap.can-left::before,.vt-wrap.can-right::after{opacity:1}
.vt-nav{position:absolute;top:3px;z-index:3;width:30px;height:30px;border-radius:var(--r-pill);border:1px solid var(--border-2);
  background:var(--surface);color:var(--txt);cursor:pointer;display:none;align-items:center;justify-content:center;
  font-size:var(--fs-lg);line-height:1;box-shadow:var(--shadow);padding:0}
.vt-prev{left:-4px}.vt-next{right:-4px}
.vt-wrap.can-left .vt-prev{display:flex}
.vt-wrap.can-right .vt-next{display:flex}
.vt-hint{position:absolute;right:4px;bottom:0;font-size:var(--fs-2xs);color:var(--faint);font-family:var(--mono);
  opacity:0;transition:opacity .25s;pointer-events:none;white-space:nowrap}
.vt-hint.show{opacity:1}
.vtab{flex:0 0 auto;padding:9px 15px;background:var(--surface);border:1px solid var(--border);color:var(--muted);
  font-family:var(--sans);font-weight:600;font-size:var(--fs-sm);cursor:pointer;white-space:nowrap;transition:background var(--dur-base),color var(--dur-base),border-color var(--dur-base)}
.vtab:hover{color:var(--txt);border-color:var(--border-2)}
.vtab.active{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:var(--glow)}
.vtab:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
/* „Więcej (N)" na końcu paska — rozwija sekcje, w których nic jeszcze nie ma.
   Kreska zamiast ramki, bo to NIE jest sekcja: obietnica, że coś jest dalej, a nie wejście. */
.vtab-more{background:none;border-style:dashed}
.viewnav{display:flex;justify-content:space-between;gap:10px;margin-top:22px;padding-top:var(--sp-4);border-top:1px solid var(--border)}

/* pokaż/ukryj hasło */
.pw-wrap{position:relative}
.pw-wrap input{padding-right:46px}
.pw-toggle{position:absolute;right:1px;top:1px;bottom:1px;width:42px;display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--muted);cursor:pointer;border-radius:0 var(--r-ctrl) var(--r-ctrl) 0;z-index:2}
.pw-toggle:hover{color:var(--txt)}
.pw-toggle svg{width:19px;height:19px}
.pw-toggle:focus-visible{outline:3px solid var(--accent-soft);outline-offset:-2px}

/* ---------- table: WIERSZ = KARTA Z RAMKĄ ----------
   Wcześniej wiersze rozdzielała jedna cienka kreska i sąsiedzi zlewali się w jeden blok
   (klient od klienta, projekt od projektu). Teraz `border-collapse:separate` +
   `border-spacing` daje ODSTĘP między wierszami, a ramka na komórkach zamyka każdy wiersz
   w osobnej karcie z własnym tłem. Zero zmian w HTML — działa we WSZYSTKICH sekcjach naraz. */
/* `-var(--sp-1)` to NIE jest ujemna wartość zmiennej — przeglądarka odrzuca całą deklarację
   marginesu. Ujemny margines zapisuje się przez calc(). */
.tbl-wrap{overflow-x:auto;margin:0 calc(-1 * var(--sp-1))}
table{width:100%;border-collapse:separate;border-spacing:0 var(--sp-2);font-size:var(--fs-sm);min-width:380px;
  font-variant-numeric:tabular-nums}
/* Odstęp POZIOMY jest o stopień mniejszy niż pionowy: Inter ma szersze znaki od poprzedniego
   kroju, więc przy 12 px na bok najszersza tabela (abonamenty opieki) wychodziła o 29 px poza
   kartę na laptopie 1280 px. 8 px na bok oddaje tę różnicę kolumnom, a wiersz i tak oddycha
   w pionie (13 px) — bramka tools/test-layout.js mierzy to na pięciu szerokościach. */
th,td{text-align:left;padding:13px var(--sp-2);vertical-align:middle}
/* DŁUGIE „SŁOWO" W KOMÓRCE (e-mail, nazwa pliku, adres URL). Dla przeglądarki to jeden
   niepodzielny wyraz, więc wymusza szerokość kolumny i rozpycha całą tabelę — na laptopie
   1280 px „Pliki" wychodziły przez to 126 px poza kartę, „Użytkownicy" 13 px. `anywhere`
   łamie taki wyraz w środku i (w odróżnieniu od `break-word`) obniża też minimalną szerokość
   kolumny, czyli naprawdę zwęża tabelę. ŚWIADOMIE tylko tam, gdzie takie wyrazy występują:
   ustawione globalnie na `td` psuło zwykłe kolumny — „klient" w wąskiej kolumnie „Od"
   łamało się na „kli / en / t". */
.wrap-any{overflow-wrap:anywhere}
/* Drugi wariant tego samego problemu: adres w DRUGIEJ linijce komórki (pod nazwą klienta).
   Łamanie go rozciągało wiersz abonamentu do 196 px wysokości — pięć linijek adresu obok
   jednej linijki treści. Tu lepsze jest wielokropek + pełna wartość w dymku. Na telefonie
   (wiersz jest kartą, miejsca w pionie nie brakuje) pokazujemy adres w całości. */
.ell{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:26ch}
/* Wiersz jest KARTĄ W KARCIE, więc bierze --surface (o krok jaśniej od tafli tabeli).
   Wcześniej wiersz i karta miały ten sam kolor i całość zlewała się w jedną płytę. */
td{background:var(--surface);border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  transition:background var(--dur-base),border-color var(--dur-base)}
td:first-child{border-left:1px solid var(--border);border-top-left-radius:var(--r-ctrl);border-bottom-left-radius:var(--r-ctrl)}
td:last-child{border-right:1px solid var(--border);border-top-right-radius:var(--r-ctrl);border-bottom-right-radius:var(--r-ctrl)}
/* nagłówek to etykiety kolumn, nie karta — bez tła i ramek, ciaśniej nad pierwszą kartą */
th{font-family:var(--mono);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.1em;color:var(--faint);font-weight:500;
  background:none;border:none;padding-top:0;padding-bottom:var(--sp-2)}
tr:hover td{background:rgba(255,0,92,.05)}

/* ---------- AKCJE W WIERSZU: JEDNA GŁÓWNA DECYZJA, RESZTA POD „⋯" ----------
   PROBLEM (zmierzony 2026-08-01 na Rozliczeniach admina, okno 1920 px): wiersz faktury miał
   do pięciu przycisków w jednej linii z `white-space:nowrap`. Kolumna akcji brała przez to
   512 z 1058 px szerokości tabeli — więcej niż wszystkie kolumny z treścią razem. „Za co"
   zostawało 113 px, więc tytuł łamał się na pięć linijek, wiersz rósł do 133 px wysokości,
   a ostatni przycisk („Usuń") i tak wypadał poza kartę: trzeba było przewijać w bok.
   ROZWIĄZANIE (klasa .acts + helper `actsTd` w obu panelach): na wierzchu zostaje główna
   decyzja, reszta chowa się pod „⋯". Przyciski MOGĄ się zawinąć, więc żaden wiersz nie jest
   już w stanie rozepchnąć tabeli szerzej niż karta — działa w każdej tabeli panelu naraz. */
td.acts{text-align:right}
.acts .btn{margin:3px 0 3px 6px;white-space:nowrap;vertical-align:middle}
/* Kolumna z menu ma stałe minimum: dzięki temu rozwinięcie „⋯" nie przestawia szerokości
   kolumn (bez tego tabela skakała przy każdym otwarciu menu). */
.acts.has-more{min-width:224px}
.acts-more{display:inline-block;position:relative;margin-left:6px;vertical-align:middle}
.acts-more>summary{list-style:none;cursor:pointer;margin:3px 0}
.acts-more>summary::-webkit-details-marker{display:none}
.acts-more>summary::marker{content:""}
.acts-more[open]>summary{border-color:var(--accent-2);background:var(--accent-soft)}
/* Rozwijamy W DÓŁ, w środku komórki (a nie na `position:absolute`): kontener tabeli ma
   `overflow-x:auto`, który przyciąłby wypływające menu. */
.acts-pop{margin-top:8px;display:flex;flex-direction:column;gap:6px;padding:8px;text-align:left;
  border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--modal-bg);box-shadow:var(--shadow-lg)}
.acts-pop .btn{width:100%;margin:0;justify-content:flex-start}

/* ---------- badges ---------- */
.badge{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:var(--fs-2xs);font-weight:600;letter-spacing:.06em;padding:var(--sp-1) 10px;border-radius:var(--r-pill);background:rgba(255,255,255,.08);color:var(--muted);text-transform:uppercase}
.badge.admin{background:var(--accent-soft);color:var(--accent-2)}
.badge.ok{background:var(--ok-bg);color:var(--ok)}
.badge.warn{background:rgba(255,176,32,.14);color:#ffb020}

/* ---------- messages / banners ---------- */
.msg{padding:var(--sp-3) 15px;border-radius:var(--r-ctrl);font-size:var(--fs-sm);margin:14px 0 0;display:none;border:1px solid transparent}
.msg.err{display:block;background:var(--danger-bg);color:#ff9097;border-color:rgba(255,90,114,.3)}
.msg.ok{display:block;background:var(--ok-bg);color:#7ff0bf;border-color:rgba(43,209,138,.3)}
.ww-banner{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;background:rgba(255,176,32,.10);border:1px solid rgba(255,176,32,.3);color:#ffce7a;border-radius:var(--r-ctrl);padding:13px var(--sp-4);margin-bottom:var(--sp-5);font-size:var(--fs-sm)}
.ww-banner b{color:#ffd99a}
.ww-banner .btn{margin-left:auto}

.empty{color:var(--faint);font-style:italic;padding:var(--sp-4) 0;font-size:var(--fs-sm)}
.hide{display:none!important}

/* PUSTY STAN Z AKCJĄ (js: pustyStan()). Kropkowana ramka mówi „to miejsce czeka na treść",
   a nie „coś się zepsuło" — inaczej nowe konto wygląda jak panel po awarii. Bez kursywy
   i szarości .empty: tu jest przycisk, więc blok ma być czytelny, nie wyszeptany. */
.pusto{text-align:center;padding:var(--sp-6) var(--sp-4);border:1px dashed var(--border-2);border-radius:var(--r-card);background:rgba(128,128,128,.04)}
.pusto-ic{font-size:30px;line-height:1;margin-bottom:var(--sp-3);opacity:.85}
.pusto-t{margin:0;font-weight:600;color:var(--txt);font-size:var(--fs-base)}
.pusto-o{margin:var(--sp-2) auto 0;max-width:52ch;color:var(--muted);font-size:var(--fs-sm);line-height:1.65}
.pusto-a{margin-top:var(--sp-4);display:flex;gap:var(--sp-2);flex-wrap:wrap;justify-content:center}

/* danger zone card */
.ww-card.danger-zone{border-color:rgba(255,90,114,.3)}
.ww-card.danger-zone h2{color:#ff8089}

/* ============================================================
   AUTH (login/rejestracja) — split hero + panel
   ============================================================ */
/* ============================================================
   EKRAN LOGOWANIA
   Lewa kolumna miała 10 punktów listy i długi akapit — rozpychały ją tak, że na
   laptopie trzeba było przewijać, a film ściskał się do 420 px. Teraz: krótki tekst,
   film na PEŁNĄ szerokość kolumny, całość mieści się w wysokości ekranu.
   ============================================================ */
/* min-height, NIE height: formularz rejestracji jest wyższy od ekranu (zwłaszcza na
   telefonie). Przy `height:100vh` + `overflow:hidden` nadmiar był po prostu obcinany
   i nie dało się do niego doscrollować — pola na dole były nieosiągalne. */
.auth-split{min-height:100vh;display:grid;grid-template-columns:1.15fr 1fr}
/* WAŻNE: hero ma animowany canvas — BEZ backdrop-filter (inaczej miga) */
/* Poświata w lewym górnym rogu, nie na środku: prowadzi wzrok od logo w dół do
   nagłówka i dalej do formularza po prawej. Ten sam gest co na tle strony, tylko
   przesunięty — hero nie jest osobnym światem, jest wycinkiem tego samego. */
.auth-hero{position:relative;overflow:hidden;padding:44px;display:flex;flex-direction:column;
  justify-content:center;gap:26px;border-right:1px solid var(--border);
  background:radial-gradient(90% 62% at 18% 8%, rgba(255,0,92,.10), rgba(255,0,92,0) 64%), var(--bg-2)}
.auth-hero>*{position:relative;z-index:1}
.auth-hero canvas#heroFx{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;display:block}
.auth-hero .ah-logo{font-family:var(--head);font-weight:800;font-size:var(--fs-2xl);letter-spacing:-.028em}
.auth-hero .ah-logo span{color:var(--accent)}
/* Jedyne miejsce w całym panelu, gdzie typografia ma prawo krzyczeć. Ciasny tracking
   i interlinia poniżej 1.1 robią z dwóch linii jeden zwarty blok — to on, a nie ramka,
   dzieli ekran na „obietnicę" i „formularz". */
.auth-hero h1{font-size:clamp(30px,3.4vw,46px);line-height:1.04;font-weight:800;letter-spacing:-.038em;margin:0 0 14px}
.auth-hero .ah-lead{color:var(--muted);font-size:var(--fs-md);line-height:1.6;max-width:46ch;margin:0}
/* Cztery krótkie hasła w dwóch kolumnach, bez ikon — zwięzły „skan" możliwości panelu */
.auth-feats{list-style:none;padding:0;margin:var(--sp-5) 0 0;display:grid;grid-template-columns:1fr 1fr;gap:12px 18px}
.auth-feats li{font-size:var(--fs-sm);font-weight:500;color:var(--muted);padding-left:16px;position:relative}
/* Znacznik pozycji to KWADRAT, nie kropka — w języku ostrych krawędzi okrągły punkt
   byłby jedynym łukiem na całym ekranie logowania i czytałby się jak obcy element. */
.auth-feats li::before{content:"";position:absolute;left:0;top:.62em;width:5px;height:5px;background:var(--accent)}
.auth-foot{font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.12em;color:var(--faint);text-transform:uppercase}
/* MOBILE: opis aplikacji jako zwijany <details>. Na desktopie ukryty (hero to pokrywa),
   pokazywany dopiero w breakpoincie, gdzie hero znika. */
.auth-about-m{display:none}
/* Prawa kolumna rośnie razem z formularzem, a przewija się CAŁA STRONA.
   Wcześniej kolumna miała `overflow-y:auto` w kontenerze o sztywnej wysokości —
   przy wyśrodkowaniu (align-items:center) treść wyższa od kontenera jest wtedy
   obcinana z GÓRY i nie da się jej doscrollować. Klasyczna pułapka flexboxa. */
.auth-pane{display:flex;align-items:center;justify-content:center;padding:var(--sp-8) var(--sp-6)}
.auth-pane .pane-inner{width:100%;max-width:500px;position:relative;overflow:hidden;
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-card);
  box-shadow:var(--inset-hi),var(--shadow-lg);padding:38px var(--sp-8)}
.auth-pane .pane-inner::before{content:"";position:absolute;inset:0 0 auto 0;height:34%;background:var(--gloss);pointer-events:none}
.auth-pane .pane-inner>*{position:relative;z-index:1}
.auth-pane .pane-logo{display:none;font-family:var(--head);font-weight:800;font-size:var(--fs-xl);letter-spacing:-.028em;text-align:center;margin-bottom:var(--sp-2)}
.auth-pane .pane-logo span{color:var(--accent)}
.auth-pane .eyebrow{display:block;text-align:center;margin-bottom:18px}
/* karta formularza wewnątrz szklanej tafli — przezroczysta, bez podwójnej obudowy */
.auth-pane .ww-card{background:transparent;border:none;box-shadow:none;padding:0;margin:0;backdrop-filter:none;-webkit-backdrop-filter:none}
.auth-pane .ww-card::before{display:none}

@media (max-width:900px){
  .auth-split{grid-template-columns:1fr}
  .auth-hero{display:none}
  /* Formularz zaczyna się u GÓRY, nie na środku — wyśrodkowany długi formularz
     na telefonie chowa pierwsze pole nad krawędzią ekranu.
     dvh zamiast vh: na telefonie pasek adresu zjada część 100vh. */
  .auth-pane{padding:var(--sp-6) var(--sp-4) var(--sp-10);min-height:100vh;min-height:100dvh;align-items:flex-start}
  .auth-pane .pane-inner{padding:28px var(--sp-5)}
  .auth-pane .pane-logo{display:block}
  /* Opis aplikacji dla telefonu (hero jest tu ukryte) */
  .auth-about-m{display:block;margin:0 0 16px;border:1px solid var(--border);border-radius:var(--r-ctrl);
    background:var(--accent-soft);overflow:hidden}
  .auth-about-m summary{list-style:none;cursor:pointer;padding:11px 13px;font-size:var(--fs-sm);
    font-weight:700;color:var(--txt);display:flex;align-items:center;justify-content:space-between;gap:8px}
  .auth-about-m summary::-webkit-details-marker{display:none}
  .auth-about-m .aam-chev{transition:transform .2s;color:var(--accent);font-size:var(--fs-base)}
  .auth-about-m[open] .aam-chev{transform:rotate(180deg)}
  .auth-about-m .aam-body{padding:0 13px 12px}
  .auth-about-m .aam-body ul{list-style:none;padding:0;margin:0;display:grid;gap:7px}
  .auth-about-m .aam-body li{position:relative;padding-left:18px;font-size:var(--fs-sm);line-height:1.4;color:var(--muted)}
  .auth-about-m .aam-body li::before{content:"";position:absolute;left:2px;top:7px;width:6px;height:6px;border-radius:50%;background:var(--accent)}
  .auth-about-m .aam-body b{color:var(--txt);font-weight:600}
  .auth-about-m .aam-trust{margin:11px 0 0;font-size:var(--fs-2xs);color:var(--faint);font-weight:600;line-height:1.5}
}

/* ---- proste strony tokenowe (reset.html / verify.html) ---- */
.ww-wrap{max-width:960px;margin:0 auto;padding:30px 18px 72px}
.ww-wrap.auth{max-width:440px;min-height:100vh;display:flex;flex-direction:column;justify-content:center;padding-top:var(--sp-10)}
.ww-top{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:26px;flex-wrap:wrap}
.ww-logo{font-family:var(--head);font-size:var(--fs-xl);font-weight:800;letter-spacing:-.028em;display:inline-flex;align-items:center;gap:10px}
.ww-logo span{color:var(--accent)}

/* ============================================================
   RESPONSYWNOŚĆ shell — tablet + mobile
   ============================================================ */

/* ≤1024px (tablety): sidebar jako wysuwany panel, treść na pełną szerokość */
@media (max-width:1024px){
  .sidebar{position:fixed;left:0;top:0;transform:translateX(-100%);transition:transform .25s ease;
    box-shadow:var(--shadow-lg);width:min(86vw,320px);flex-basis:min(86vw,320px);overflow-y:auto;background:var(--bg-2)}
  .sidebar.open{transform:none}
  .side-close{display:flex}
  .menu-btn{display:flex}
  .content{padding:var(--sp-6)}
  .grid2{grid-template-columns:1fr}
  /* gdy menu otwarte: blokada przewijania tła — nawigacja tylko po menu */
  body.nav-open{overflow:hidden}
}

/* ≤900px: statystyki 2-kol, a TABELE zmieniają układ na karty (każdy wiersz = karta) */
@media (max-width:900px){
  .user-chip .uc-meta{display:none}
  .stats{grid-template-columns:repeat(2,1fr)}

  /* Tabela -> lista kart: nagłówek ukryty, komórki w pionie z etykietą pola */
  .tbl-wrap{overflow-x:visible;margin:0}
  .tbl-wrap table{display:block;min-width:0;font-size:var(--fs-base)}
  .tbl-wrap thead,.tbl-wrap tbody,.tbl-wrap tr,.tbl-wrap td{display:block}
  .tbl-wrap tr:has(th){display:none}                 /* ukryj wiersz nagłówka */
  .tbl-wrap tr{border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--surface);margin-bottom:var(--sp-3);padding:2px 14px}
  /* każda komórka: etykieta pola nad wartością (łamie długie e-maile/ciągi).
     Kartą jest tu CAŁY wiersz (tr), więc komórki gubią własne tło/ramkę/zaokrąglenia
     z układu desktopowego — inaczej karta w karcie. */
  .tbl-wrap td{border:none;border-bottom:1px solid var(--border);padding:9px 0;background:none;border-radius:0;
    display:block;text-align:left;white-space:normal!important;overflow-wrap:anywhere;word-break:break-word}
  .tbl-wrap td:last-child{border-bottom:none}
  .tbl-wrap tr:hover td{background:none}
  .tbl-wrap td::before{content:attr(data-label);display:block;margin-bottom:3px;
    font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.5px;text-transform:uppercase;color:var(--faint)}
  .tbl-wrap td select{max-width:100%!important;width:100%}
  /* Wiersz jest tu kartą — miejsca w pionie nie brakuje, więc skrócony adres pokazujemy
     w całości (na dotyku nie ma dymka z `title`, ucięty adres byłby nie do odczytania). */
  .tbl-wrap .ell{white-space:normal;overflow:visible;max-width:none;overflow-wrap:anywhere}
  /* komórka akcji (bez etykiety): przyciski w rzędzie na całą szerokość */
  .tbl-wrap td[data-label=""]{padding-top:var(--sp-3);display:flex;flex-wrap:wrap;gap:var(--sp-2)}
  .tbl-wrap td[data-label=""]::before{display:none}
  /* cel dotykowy min. ~44px (WCAG 2.5.5): w liście użytkowników w jednym rzędzie
     bywa 5 przycisków — na dotyku muszą być trafialne, nie 33px wysokości. */
  .tbl-wrap td[data-label=""] .btn{flex:1 1 auto;min-height:42px;display:inline-flex;align-items:center;justify-content:center}
  /* Odstępy daje tu `gap` komórki, więc marginesy z układu desktopowego muszą zniknąć —
     inaczej sumują się z gapem i przyciski rozjeżdżają się nierówno. */
  .tbl-wrap td.acts .btn{margin:0}
  .tbl-wrap td.acts.has-more{min-width:0}
  /* Menu „⋯" na dotyku zajmuje własny wiersz — inaczej rozwinięta lista wciskała się
     obok przycisku i miała szerokość dwóch centymetrów. */
  .tbl-wrap td.acts .acts-more{flex:1 1 100%;margin-left:0}
  .tbl-wrap td.acts .acts-more>summary{margin:0;min-height:42px;justify-content:center}
}

/* ≤560px (telefony): jedna kolumna, luźniejszy topbar, mniejsze paddingi */
@media (max-width:560px){
  .topbar{padding:0 14px;gap:10px}
  .search{display:none}
  .content{padding:var(--sp-4)}
  .ww-card{padding:var(--sp-4)}
  .stats{grid-template-columns:1fr}
  .page-head h1{font-size:var(--fs-xl)}
  .page-head p{font-size:var(--fs-sm)}
  .top-right .btn.ghost.sm{display:none}   /* „Strona www" jest też w menu bocznym */
  .card-head{gap:10px}
  .card-head .row{width:100%}
  .card-head .row .btn{flex:1 1 auto}
  /* Pozycja (.fn) na telefonie: opis u góry, przyciski pod nim na całą szerokość — tak samo,
     jak wiersz tabeli zwinięty w kartę. Obok siebie mieściły się najwyżej dwa krótkie. */
  .fn{flex-wrap:wrap}
  .fn-main{flex:1 1 100%}
  .fn-acts{flex:1 1 100%;justify-content:flex-start;margin-top:2px}
  .fn-acts .btn{flex:1 1 auto;min-height:40px;justify-content:center}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}

/* ============================================================
   LIGHT MODE  (jak strona główna: ciepła biel #f0ede8, mleczne szkło)
   ============================================================ */
html.html-light-mode{
  --bg:#f0ede8; --bg-2:#e6e2db;
  --bg-glow:radial-gradient(120% 78% at 50% -12%, rgba(232,0,79,.05), rgba(232,0,79,0) 62%);
  /* TA SAMA hierarchia co w ciemnym, tylko w drugą stronę jasności:
     strona (kremowa) → karta (--surface-2) → element w karcie (--surface, biel).
     PODŁOGA JASNOŚCI JEST TWARDA: --faint (#77717c) zdaje 4.5:1 dopiero od ~#fbf9f6
     w górę, a to kolor dat, metadanych i etykiet kolumn. Przyciemnienie którejkolwiek
     z tych dwóch płaszczyzn zbija je poniżej AA. */
  --surface:#ffffff; --surface-2:#fdfcfa;
  --border:rgba(20,10,30,.10); --border-2:rgba(20,10,30,.17); --border-3:rgba(20,10,30,.30);
  /* --faint to kolor DAT i metadanych pod wpisami, czyli tekstu, który realnie się czyta.
     Poprzednie #77717c liczono WYŁĄCZNIE względem karty (4.50:1 na #fbf9f6) — na samym
     kremowym tle strony schodziło do 4.05:1, a więc pod AA. #6f6974 zdaje na WSZYSTKICH
     płaszczyznach jasnego motywu: 4.55:1 na stronie, 5.06:1 na oknie, 5.32:1 na bieli,
     i nadal jest wyraźnie jaśniejsze od --muted (nie zlewa się z drugim stopniem).
     --accent jako TEKST daje 4.08:1 na stronie, ale występuje tam tylko w logo i wielkich
     liczbach KPI — czyli w rozmiarach, dla których AA wymaga 3:1. Na kartach ma 4.65:1. */
  --txt:#1b1720; --muted:#5a5560; --faint:#6f6974;
  --accent:#e4004e; --accent-2:#c2003f; --accent-soft:rgba(232,0,79,.10);
  --ok:#1a7a44; --st-ok:#1a7a44; --st-warn:#8a5d0a; --st-bad:#b8253c; --ok-bg:rgba(26,122,68,.12);
  --danger:#cc2b45; --danger-bg:rgba(204,43,69,.10);
  /* W jasnym motywie tła przycisków już zdają AA z bielą (#e8004f = 4.62:1, #cc2b45 = 5.25:1),
     więc nie przyciemniamy ich tak jak w ciemnym — wystarczy wskazać właściwe wartości. */
  --accent-btn:#e8004f; --danger-btn:#cc2b45;
  /* Etykieta „pracownik" na jasnym tle: #6e78ff dawało 2.96:1 po zmieszaniu z --member-soft. */
  --member:#424fff;
  --edge:rgba(232,0,79,.32);
  --glass:none;
  --gloss:none; --gloss-panel:none; --gloss-strong:none;
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.6);
  /* Matowe płaszczyzny w jasnym motywie rozdziela CIEŃ, nie połysk — karta biała na
     kremowym tle bez cienia zlewa się z tłem przy niskiej jasności ekranu. */
  --shadow:0 1px 2px rgba(40,20,50,.06),0 12px 30px -22px rgba(40,20,50,.34);
  --shadow-lg:0 24px 60px -26px rgba(40,20,50,.30),0 6px 18px -12px rgba(40,20,50,.20);
  --glow:0 4px 20px rgba(232,0,79,.26);
}
/* pola formularzy: tło i kolor biorą z tokenów (--surface / --txt) — bez nadpisań */
html.html-light-mode .eyebrow{color:#c2003f}
/* chrom aplikacji o pół stopnia jaśniejszy od treści — oddziela nawigację od obszaru
   roboczego i daje etykietom w menu bocznym zapas kontrastu ponad próg AA. */
html.html-light-mode .topbar{background:var(--surface-2)}
html.html-light-mode .sidebar{background:var(--surface-2)}
html.html-light-mode .tabs{background:rgba(20,10,30,.05)}
html.html-light-mode tr:hover td{background:rgba(232,0,79,.05)}
html.html-light-mode .nav-item:hover{background:rgba(20,10,30,.05)}
html.html-light-mode .nav-item.active{color:#1b1720;background:rgba(232,0,79,.10)}
html.html-light-mode .badge{background:rgba(20,10,30,.06);color:#5a5560}
html.html-light-mode .badge.admin{background:var(--accent-soft);color:#c2003f}
html.html-light-mode .badge.ok{background:rgba(26,122,68,.12);color:#1a7a44}
html.html-light-mode .badge.warn{background:rgba(180,120,0,.14);color:#8a5a00}
/* Zostaje jako osobna reguła (nie sam token) — patrz komentarz przy .btn.ghost.is-open
   na końcu pliku: ta swoistość jest częścią układanki i jej usunięcie zmienia stan „otwarte". */
html.html-light-mode .btn.ghost{background:var(--surface);color:#1b1720}
html.html-light-mode .btn.ghost:hover{background:#f4f1ee}
html.html-light-mode .msg.err{color:#b00020}
html.html-light-mode .msg.ok{color:#1a7a44}
html.html-light-mode .ww-banner{background:rgba(180,120,0,.10);border-color:rgba(180,120,0,.32);color:#7a5200}
html.html-light-mode .ww-banner b{color:#5e3f00}
html.html-light-mode .auth-hero{
  background:radial-gradient(90% 62% at 18% 8%, rgba(232,0,79,.07), rgba(232,0,79,0) 64%), var(--bg-2)}
/* --bg-2 to jedyna płaszczyzna jasnego motywu CIEMNIEJSZA od strony (hero logowania
   i szuflada na telefonie) — trzeci stopień szarości daje tam 4.12:1. Zamiast rozjaśniać
   --bg-2 (hero straciłby odcięcie od formularza) te dwa mikro-podpisy schodzą stopień
   wyżej, na --muted. W ciemnym motywie problemu nie ma, więc reguła jest tylko tutaj. */
html.html-light-mode .auth-foot,
html.html-light-mode .side-sec{color:var(--muted)}
html.html-light-mode .cal-ev{background:rgba(20,10,30,.05)}
html.html-light-mode .progress{background:rgba(20,10,30,.08)}
/* .cal-cell, .modal i .notif-panel biorą tło z tokenów (--surface / --modal-bg / --modal-head) */

/* przelacznik motywu */
.ww-theme-tgl{position:fixed;right:18px;bottom:18px;z-index:60;width:44px;height:44px;border-radius:var(--r-pill);
  border:1px solid var(--border-2);background:var(--surface);color:var(--txt);cursor:pointer;font-size:var(--fs-md);line-height:1;
  display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow);transition:var(--dur-base)}
.ww-theme-tgl:hover{border-color:var(--accent-2);transform:translateY(-2px)}
.ww-theme-tgl:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}

/* ============================================================
   WYDAJNOŚĆ na mobile/tablecie
   Design v8 nie używa już rozmycia tła na elementach interfejsu — powierzchnie
   są nieprzezroczyste, więc przewijanie nie przelicza blura w każdej klatce.
   Rozmycie zostało WYŁĄCZNIE na przyciemnieniach pod oknami (.modal-ov, .side-ov,
   .cmdk-ov, .ed-ov, .cf-ov), które istnieją tylko przy otwartym oknie — i tam też
   je gasimy na dotyku, bo w trakcie otwierania panelu bocznego kosztuje najwięcej.
   Blok na końcu pliku, aby wygrać kolejnością nad regułami light-mode.
   ============================================================ */
@media (max-width:1024px){
  .modal-ov,.side-ov,.cmdk-ov,.ed-ov,.cf-ov{
    backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
  /* płynny scroll dotykowy */
  html,body{-webkit-overflow-scrolling:touch}
}

/* Aktywny przycisk otwierający panel (toggle) — podświetlenie „otwarte", jak w aplikacjach.
   Klasę .is-open dokłada/zdejmuje JS (panelToggle/panelClose). */
.btn.is-open,.btn.ghost.is-open{background:var(--accent);border-color:var(--accent);color:#fff;
  box-shadow:var(--inset-hi),var(--glow,0 4px 20px rgba(232,0,79,.28))}
.btn.is-open:hover,.btn.ghost.is-open:hover{background:var(--accent-2,#c2003f);border-color:var(--accent-2,#c2003f);color:#fff}

/* ============================================================
   INTERAKCJE + DOSTĘPNOŚĆ (spójne ze stroną główną)
   Ten sam język ruchu co css/ww-interactions.css:
   --ww-ease / --ww-dur. Wszystko gaśnie przy prefers-reduced-motion.
   ============================================================ */
:root{
  --ww-ease:cubic-bezier(.16,1,.3,1);
  --ww-dur:.28s;
}

/* ---- 1. Focus widoczny dla klawiatury (WCAG 2.4.7) ----
   .btn/.tab/.vtab/.side-close/.side-more/.pw-toggle mają już swój pierścień
   wyżej w pliku — tu uzupełniamy elementy, które go nie miały. */
.nav-item:focus-visible,
.icon-btn:focus-visible,
.notif-item:focus-visible,
.ww-card a:focus-visible,
.chip:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible{
  outline:3px solid var(--accent-soft);
  outline-offset:2px;
}
[tabindex="-1"]:focus{outline:none}

/* ---- 2. Skip link (WCAG 2.4.1) ---- */
.ww-skip{
  position:absolute;left:12px;top:-5rem;z-index:10000;
  display:inline-flex;align-items:center;min-height:44px;
  padding:.7rem 1.1rem;border-radius:var(--r-sm);
  background:var(--accent);color:#fff;text-decoration:none;
  font-family:var(--sans);font-size:var(--fs-sm);font-weight:700;
  transition:top .25s var(--ww-ease);
}
.ww-skip:focus{top:12px}

/* ---- 3. Mikro-interakcje ---- */
.btn{transition:background var(--ww-dur) var(--ww-ease),border-color var(--ww-dur) var(--ww-ease),
     color var(--ww-dur) var(--ww-ease),transform .12s var(--ww-ease),box-shadow var(--ww-dur) var(--ww-ease)}
.btn:active{transform:translateY(1px)}

.icon-btn{transition:border-color var(--ww-dur) var(--ww-ease),color var(--ww-dur) var(--ww-ease),transform var(--dur-base) var(--ww-ease)}
.icon-btn:hover{transform:scale(1.06)}
.icon-btn:active{transform:scale(.95)}

/* nawigacja boczna — delikatne przesunięcie + pasek akcentu na hover.
   Używamy ::after, bo ::before należy już do wskaźnika pozycji aktywnej. */
.nav-item{transition:background var(--ww-dur) var(--ww-ease),color var(--ww-dur) var(--ww-ease),transform .18s var(--ww-ease)}
.nav-item:hover{transform:translateX(3px)}
.nav-item::after{
  content:"";position:absolute;left:0;top:50%;width:2.5px;height:0;
  background:var(--accent);border-radius:0 var(--r-xs) var(--r-xs) 0;pointer-events:none;
  transform:translateY(-50%);transition:height .22s var(--ww-ease);
}
.nav-item:hover::after{height:60%}
.nav-item.active::after{height:0}   /* pozycja aktywna ma własny pasek (::before) */

.vtab{transition:background var(--ww-dur) var(--ww-ease),border-color var(--ww-dur) var(--ww-ease),transform var(--dur-base) var(--ww-ease)}
.vtab:hover{transform:translateY(-1px)}
.vtab:active{transform:translateY(0)}

/* ---- 4. Wejście widoku i kart ---- */
@keyframes wwViewIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes wwPop{from{opacity:0;transform:translateY(8px) scale(.985)}to{opacity:1;transform:none}}
@keyframes wwDrop{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}

.content > [data-view]{animation:wwViewIn .34s var(--ww-ease) both}
.content > [data-view] > .ww-card{animation:wwViewIn .42s var(--ww-ease) both}
.content > [data-view] > .ww-card:nth-child(2){animation-delay:60ms}
.content > [data-view] > .ww-card:nth-child(3){animation-delay:120ms}
.content > [data-view] > .ww-card:nth-child(4){animation-delay:180ms}
.content > [data-view] > .ww-card:nth-child(n+5){animation-delay:220ms}

.modal-ov.show .modal{animation:wwPop .26s var(--ww-ease) both}
.notif-panel.show{animation:wwDrop .2s var(--ww-ease) both}

/* ---- 5. Mniej ruchu = zero ruchu (WCAG 2.3.3) ---- */
@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
  .nav-item:hover,.vtab:hover,.icon-btn:hover,.icon-btn:active,.btn:active{transform:none!important}
  .content > [data-view],.content > [data-view] > .ww-card,
  .modal-ov.show .modal,.notif-panel.show{opacity:1!important;transform:none!important}
}

/* ---- Modal podglądu (szeroki) — briefy, umowy ---- */
.modal.wide{max-width:900px}
.ww-modal-body{max-height:68vh;overflow:auto;margin-top:6px;padding-right:var(--sp-1)}
.ww-modal-body h3{font-size:var(--fs-base);margin:var(--sp-4) 0 6px;color:var(--accent);
  border-bottom:1px solid var(--border);padding-bottom:var(--sp-1)}
.ww-modal-body h3:first-child{margin-top:0}
.ww-modal-body .kv{font-size:var(--fs-sm);line-height:1.6;margin:0 0 7px}
.ww-modal-body .kv b{color:var(--txt)}
.ww-modal-body pre{white-space:pre-wrap;word-break:break-word;font-family:var(--sans);
  font-size:var(--fs-sm);line-height:1.65;margin:0;color:var(--txt)}

/* Etykieta widoczna tylko dla czytników ekranu (pole ma widoczny nagłówek obok) */
.ww-sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---- Strefa „wklej zrzut ekranu / upuść plik" (Podglądy) ---- */
.pv-drop{
  display:flex;align-items:center;gap:14px;
  padding:18px var(--sp-4);cursor:pointer;
  border:2px dashed var(--border-2);border-radius:var(--r-card);
  background:var(--surface);
  transition:border-color var(--ww-dur,.28s) var(--ww-ease,ease),background var(--ww-dur,.28s) var(--ww-ease,ease);
}
.pv-drop:hover,.pv-drop:focus-visible{border-color:var(--accent);background:rgba(255,0,92,.05)}
.pv-drop.is-over{border-color:var(--accent);background:rgba(255,0,92,.10);border-style:solid}
.pv-drop.is-disabled{opacity:.45;pointer-events:none;cursor:not-allowed}
.pv-drop-ic{flex:0 0 auto;color:var(--accent)}
.pv-drop-ic svg{width:30px;height:30px}
.pv-drop-txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.pv-drop-txt b{font-size:var(--fs-sm);color:var(--txt);display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.pv-drop-txt span{font-size:var(--fs-xs)}

kbd{
  font-family:var(--mono);font-size:var(--fs-2xs);line-height:1;
  padding:3px 6px;border:1px solid var(--border-2);border-bottom-width:2px;
  border-radius:var(--r-xs);background:rgba(127,127,127,.12);color:var(--txt);
}

/* miniatura wybranego zdjęcia przed wysyłką */
.pv-pick{
  display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  margin-top:var(--sp-3);padding:10px;border:1px solid var(--border);border-radius:var(--r-ctrl);
  background:var(--surface);
}
.pv-pick img{width:88px;height:64px;object-fit:contain;border-radius:var(--r-sm);background:rgba(127,127,127,.18);flex:0 0 auto}
.pv-pick-meta{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.pv-pick-meta b{font-size:var(--fs-sm);word-break:break-all}
.pv-pick-meta span{font-size:var(--fs-xs)}

@media (max-width:560px){
  .pv-drop{flex-direction:column;text-align:center;gap:10px}
  .pv-drop-txt{align-items:center}
  .pv-drop-txt b{justify-content:center}
}

/* ============================================================
   UWAGI I POMYSŁY (ideas) — klient + admin
   ============================================================ */
.idea-kinds{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:var(--sp-2);margin-top:6px}
.idea-kind{
  display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  padding:11px var(--sp-3);cursor:pointer;text-align:left;
  border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--surface);
  color:var(--muted);font-family:var(--sans);
  transition:border-color var(--ww-dur,.28s) var(--ww-ease,ease),background var(--ww-dur,.28s) var(--ww-ease,ease),transform var(--dur-base) var(--ww-ease,ease);
}
.idea-kind:hover{border-color:var(--accent-2);transform:translateY(-2px)}
.idea-kind:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
.idea-kind.is-on{border-color:var(--accent);background:rgba(255,0,92,.10);color:var(--txt)}
.idea-kind-ic{font-size:var(--fs-lg);line-height:1}
.idea-kind b{font-size:var(--fs-sm);color:var(--txt)}
.idea-kind small{font-size:var(--fs-2xs);line-height:1.35;color:var(--muted)}

.idea-stats{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 14px}
.idea-stats div{
  flex:1;min-width:96px;text-align:center;padding:11px 6px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-ctrl);
}
.idea-stats b{display:block;font-size:var(--fs-xl);font-weight:800;line-height:1.1}
.idea-stats span{font-size:var(--fs-xs);color:var(--muted)}

.idea-item{border:1px solid var(--border);border-radius:var(--r-ctrl);padding:13px;margin-bottom:11px;background:var(--surface)}
.idea-h{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.idea-h b{font-size:var(--fs-base);flex:1;min-width:140px}
.idea-ic{font-size:var(--fs-md);line-height:1}
.idea-reply{
  margin-top:10px;padding:9px 11px;font-size:var(--fs-sm);
  border-left:3px solid var(--accent);border-radius:0 var(--r-sm) var(--r-sm) 0;
  background:var(--accent-soft);
}

/* admin: wykresy */
.idea-charts{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin:14px 0}
.idea-chart{border:1px solid var(--border);border-radius:var(--r-ctrl);padding:13px;background:var(--surface)}
.idea-chart h3{font-size:var(--fs-sm);margin:0 0 10px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;font-weight:600}
.idea-bar{display:flex;align-items:center;gap:9px;margin-bottom:7px;font-size:var(--fs-sm)}
.idea-bar-lab{flex:0 0 42%;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.idea-bar-track{flex:1;height:9px;background:var(--border);overflow:hidden}
/* display:block jest OBOWIĄZKOWE: wypełnienie to <span> wewnątrz toru, a na
   elemencie liniowym przeglądarka ignoruje width i height — słupki (lejek wycen,
   wykresy w „Uwagach i pomysłach") miały przez to zerową szerokość i nie było ich
   widać wcale. Tak samo robi .ank-bar-fill niżej. */
.idea-bar-fill{display:block;height:100%;background:var(--accent);transition:width .5s var(--ww-ease,ease)}
.idea-bar-num{flex:0 0 auto;font-family:var(--mono);font-size:var(--fs-xs);color:var(--txt)}

/* admin: ankiety ze strony głównej.
   Karta odpowiedzi reużywa .cr-item (jak zgłoszenia i briefy) — dokładamy tylko
   wyróżnienie nieprzeczytanej i układ „pytanie → zaznaczone opcje". Pytanie jest
   drobne i przygaszone, bo skanuje się ODPOWIEDZI; pytania służą tylko za nagłówki. */
.ank-item.nowa{border-left:3px solid var(--accent)}
.ank-odp{margin-top:9px}
.ank-odp-p{font-size:var(--fs-2xs);color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px}
.ank-odp-v{display:flex;flex-wrap:wrap;gap:5px}

/* Słupek odpowiedzi w ankiecie. Świadomie NIE reużywa .idea-bar: tam etykieta
   dostaje 42% szerokości i jest przycinana wielokropkiem, a odpowiedzi w ankiecie
   to całe zdania („Nie wiem, ile finalnie zapłacę") — przycięta odpowiedź jest
   bezużyteczna. Etykieta idzie więc NAD ścieżkę, całą szerokością i z zawijaniem. */
.ank-charts{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:14px;margin:0 0 14px}
.ank-chart{border:1px solid var(--border);border-radius:var(--r-ctrl);padding:14px;background:var(--surface)}
.ank-chart h3{font-size:var(--fs-sm);margin:0 0 12px;color:var(--txt);font-weight:700;line-height:1.4}
.ank-bar{display:grid;grid-template-columns:1fr auto;gap:0 10px;align-items:baseline;margin:0 0 11px;font-size:var(--fs-sm)}
.ank-bar-lab{color:var(--muted);overflow-wrap:anywhere;line-height:1.4}
.ank-bar-num{font-family:var(--mono);font-size:var(--fs-xs);color:var(--muted);white-space:nowrap}
.ank-bar-track{grid-column:1/-1;height:8px;margin-top:4px;border-radius:var(--r-pill);background:var(--border);overflow:hidden}
.ank-bar-fill{display:block;height:100%;border-radius:var(--r-pill);background:var(--accent-2);transition:width .5s var(--ww-ease,ease)}
.ank-bar.top .ank-bar-lab{color:var(--txt);font-weight:700}
.ank-bar.top .ank-bar-fill{background:var(--accent)}

/* Gwiazdki oceny. Były wpisane w style="color:#ffb020" w trzech miejscach i przez
   to niewidoczne dla czytnika ekranu — teraz jedna klasa + role="img" z aria-label. */
.ocena{color:#ffb020;white-space:nowrap;letter-spacing:1px}
html.html-light-mode .ocena{color:#b8770a}
.ocena-rozklad{display:grid;gap:5px;margin:0 0 var(--sp-4);max-width:420px}
.ocena-rzad{display:grid;grid-template-columns:auto 1fr auto;gap:9px;align-items:center;font-size:var(--fs-xs)}
.ocena-rzad .ank-bar-track{grid-column:auto;margin:0}

/* Błąd ładowania sekcji — zamiast wiecznego „Ładowanie…" albo mylącego „Brak danych" */
.load-fail{
  display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  padding:14px var(--sp-4);border:1px solid var(--danger);border-left-width:3px;
  border-radius:var(--r-ctrl);
  background:var(--danger-bg);color:var(--txt);font-size:var(--fs-sm);
}
.load-fail-txt{flex:1;min-width:180px;line-height:1.55}
.load-fail-txt b{display:block;margin-bottom:2px}
.load-fail-txt span{color:var(--muted);font-size:var(--fs-sm)}

/* ============================================================
   Natywne listy rozwijane <select>
   Popup <option> rysuje przeglądarka — nie da się go ostylować
   dowolnie. Kluczem jest `color-scheme`: bez niego Chrome maluje
   listę na jasno, także w ciemnym motywie (biały tekst na białym tle).
   ============================================================ */
html{color-scheme:dark}
html.html-light-mode{color-scheme:light}

select option,
select optgroup{
  background-color:#1a181b;   /* = --surface, żeby popup nie był ciemniejszy od pola */
  color:#f1f0f4;
}
select option:checked,
select option:hover{
  background-color:#33101f;
  color:#fff;
}
html.html-light-mode select option,
html.html-light-mode select optgroup{
  background-color:#ffffff;
  color:#1b1720;
}
html.html-light-mode select option:checked,
html.html-light-mode select option:hover{
  background-color:#f7d9e3;
  color:#1b1720;
}

/* ============================================================
   ASYSTENT AI — edytor bloga
   ============================================================ */
.ai-assist{
  border:1px solid var(--accent);border-radius:var(--r-ctrl);
  background:var(--accent-soft);
  padding:13px 14px;margin:0 0 18px;
}
.ai-assist-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ai-assist-title{font-weight:800;font-size:var(--fs-base);color:var(--accent-2)}
.ai-actions{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin-top:11px}
.ai-out{
  margin-top:11px;padding:var(--sp-3);
  border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface);
  max-height:340px;overflow:auto;
}
.ai-out-head{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:7px}
.ai-out-body{font-size:var(--fs-sm);line-height:1.6;white-space:pre-wrap;word-break:break-word}
.ai-title-opt{
  display:block;width:100%;text-align:left;cursor:pointer;
  margin:0 0 6px;padding:9px 11px;font-size:var(--fs-sm);
  border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--surface);color:var(--txt);
  font-family:var(--sans);transition:border-color var(--dur-base),background var(--dur-base);
}
.ai-title-opt:hover{border-color:var(--accent);background:var(--accent-soft)}

/* ============================================================
   STATYSTYKI BLOGA + ocena SEO w edytorze
   ============================================================ */
.bstats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px;margin:0 0 14px}
.bstat{text-align:center;padding:var(--sp-3) var(--sp-2);border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.bstat-n{font-size:var(--fs-xl);font-weight:800;line-height:1.1}
.bstat-l{font-size:var(--fs-xs);color:var(--muted);margin-top:var(--sp-1)}
.bstat-h{font-size:var(--fs-2xs);color:var(--faint);margin-top:2px}
.bstats-2col{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media (max-width:900px){ .bstats-2col{grid-template-columns:1fr} }
.bbars{display:flex;align-items:flex-end;gap:var(--sp-1);height:64px}
.bbar{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:3px;min-width:0}
.bbar-fill{width:100%;max-width:22px;background:var(--accent);border-radius:var(--r-xs) var(--r-xs) 0 0;transition:height .4s var(--ww-ease,ease)}
.bbar-lab{font-size:var(--fs-2xs);color:var(--faint);font-family:var(--mono);white-space:nowrap;transform:rotate(-45deg);transform-origin:center}
.brow{display:flex;align-items:center;gap:10px;padding:6px 0;border-top:1px solid var(--border);font-size:var(--fs-sm)}
.brow:first-of-type{border-top:0}
.brow a{color:var(--txt)}
.brow a:hover{color:var(--accent-2)}

/* Ocena SEO w edytorze — pierścień postępu */
.pe-seo{margin-top:14px;padding:14px;border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.pe-seo-head{display:flex;align-items:center;gap:14px}
.pe-seo-ring{
  --p:0;--c:var(--accent);
  width:52px;height:52px;flex:0 0 52px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;position:relative;
  background:conic-gradient(var(--c) calc(var(--p)*1%), var(--border) 0);
}
.pe-seo-ring::before{content:"";position:absolute;inset:5px;border-radius:50%;background:var(--surface)}
.pe-seo-ring span{position:relative;font-weight:800;font-size:var(--fs-md);color:var(--c)}
.pe-seo-issues{margin:10px 0 0;padding-left:18px;font-size:var(--fs-sm);line-height:1.7;color:var(--muted)}
.pe-seo-issues li{margin:2px 0}

/* ============================================================
   GLOBALNA WYSZUKIWARKA (Ctrl+K)
   ============================================================ */
.cmdk-trigger{display:inline-flex;align-items:center;gap:7px}
.cmdk-trigger kbd{font-size:var(--fs-2xs);padding:2px 5px}
@media (max-width:900px){ .cmdk-trigger{display:none} }

.cmdk-ov{
  position:fixed;inset:0;z-index:200;display:none;
  background:rgba(0,0,0,.5);backdrop-filter:blur(4px);
  align-items:flex-start;justify-content:center;padding:12vh var(--sp-4) var(--sp-4);
}
.cmdk-ov.show{display:flex}
.cmdk-box{
  width:100%;max-width:640px;background:var(--modal-bg);
  border:1px solid var(--border-2);border-radius:var(--r-card);overflow:hidden;
  box-shadow:var(--shadow-lg);
  animation:wwPop .2s var(--ww-ease,ease) both;
}
.cmdk-box input{
  width:100%;border:0;border-bottom:1px solid var(--border);
  background:transparent;padding:var(--sp-4) 18px;font-size:var(--fs-md);color:var(--txt);
  font-family:var(--sans);outline:none;
}
.cmdk-results{max-height:56vh;overflow:auto;padding:6px}
.cmdk-hint{padding:var(--sp-4) 14px;color:var(--muted);font-size:var(--fs-sm);text-align:center}
.cmdk-item{
  display:flex;align-items:center;gap:var(--sp-3);padding:10px var(--sp-3);cursor:pointer;
  border-radius:var(--r-sm);
}
.cmdk-item.sel{background:var(--accent-soft)}
.cmdk-ic{font-size:var(--fs-md);flex:0 0 auto}
.cmdk-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.cmdk-main b{font-size:var(--fs-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-sub{font-size:var(--fs-xs);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cmdk-type{font-size:var(--fs-2xs);font-family:var(--mono);color:var(--faint);text-transform:uppercase;letter-spacing:.05em;flex:0 0 auto}

/* ============================================================
   ASYSTENT AI DLA KLIENTA — licznik + narzędzia przy treściach
   ============================================================ */
.ai-quota{margin:0 0 14px}
.ai-quota-in{display:flex;align-items:center;gap:var(--sp-3);padding:11px 13px;border:1px solid var(--accent);
  border-radius:var(--r-ctrl);background:var(--accent-soft)}
.ai-quota-ic{font-size:var(--fs-lg);flex:0 0 auto}
.ai-quota-track{height:5px;background:var(--border);margin-top:5px;overflow:hidden}
.ai-quota-fill{display:block;height:100%;transition:width .4s var(--ww-ease,ease)}

/* Narzędzia AI przy pozycji treści — widoczne tylko gdy asystent dostępny (html.ai-on) */
.ai-tools{display:none;margin-top:9px;gap:7px;flex-wrap:wrap;align-items:center;
  padding-top:9px;border-top:1px dashed var(--border)}
html.ai-on .ai-tools{display:flex}
.ai-tools-lbl{font-size:var(--fs-xs);color:var(--accent-2,#ff3d78);font-weight:700}
.ai-tools .btn{font-size:var(--fs-xs)}

/* ASYSTENT KONTA („Zapytaj o swoje konto") — karta na pulpicie klienta.
   Domyślnie UKRYTA: bez działającego AI (brak bindingu, wyłączony limit) nie ma sensu
   pokazywać pola, które zawsze odpowie błędem. Odsłania ją dopiero html.ai-on. */
.ai-ask{display:none}
html.ai-on .ai-ask{display:block}
.ai-ask-row{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center}
.ai-ask-row input{flex:1 1 260px;min-width:0;margin:0}
.ai-ask-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.ai-ask-chips .btn{font-size:var(--fs-xs)}
.ai-ask-out{margin-top:12px;padding:11px 13px;border:1px solid var(--accent);border-radius:var(--r-ctrl);
  background:var(--accent-soft);
  font-size:var(--fs-base);line-height:1.65;overflow-wrap:anywhere}
.ai-ask-out.warn{border-color:var(--st-warn);background:transparent}
.ai-ask-q{font-weight:700;margin-bottom:6px}

/* ASYSTENT ZGŁOSZEŃ — wynik sprawdzenia „czy niczego nie brakuje".
   Bez `display:none`: sprawdzenie działa też regułami (bez AI), więc pudełko nie może
   znikać razem z html.ai-on — patrz checkTicket() w js/panel-konto.js. */
/* --bd i --txt-2 nie istnieją w tym pliku (ślad po innym zestawie nazw) — border-color
   spadał wtedy na currentColor, czyli ramka miała kolor tekstu. Tokeny właściwe. */
.tri{margin-top:12px;padding:11px 13px;border:1px solid var(--border-2);border-radius:var(--r-ctrl);
  background:var(--surface);
  font-size:var(--fs-sm);line-height:1.6;overflow-wrap:anywhere}
.tri.warn{border-color:var(--st-warn)}
.tri-sum{margin-top:6px;font-style:italic;color:var(--muted)}
.tri-q{margin:9px 0 0;padding-left:20px}
.tri-q li{margin-bottom:5px}
.tri-acts{margin-top:9px}
.tri-meta{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:11px}
.tri-cov{margin-top:9px;padding:8px 10px;border-left:3px solid var(--border-2)}
.tri-cov.ok{border-left-color:var(--st-ok)}
.tri-cov.warn{border-left-color:var(--st-warn)}
.tri-foot{margin-top:9px;font-size:var(--fs-xs)}

/* SEO-COPILOT — propozycja tytułu/opisu pod frazę z Search Console.
   Bez `display:none` na html.ai-on: cały blok pojawia się dopiero po kliknięciu przycisku,
   a sam przycisk rysuje się tylko przy dostępnym asystencie (patrz loadGSC w panel-konto.js). */
.seo-plan{margin:10px 0 0;padding:11px 13px;border:1px solid var(--border-2);border-radius:var(--r-ctrl);
  background:var(--surface);
  font-size:var(--fs-sm);line-height:1.6;overflow-wrap:anywhere}
.seo-plan.warn{border-color:var(--st-warn)}
.seo-plan-h{font-weight:700}
.seo-plan-meta{margin-top:2px;font-size:var(--fs-xs)}
.seo-pole{margin-top:11px;padding-top:9px;border-top:1px solid var(--border)}
.seo-pole-h{display:flex;flex-wrap:wrap;gap:7px;align-items:center;margin-bottom:4px}
.seo-pole-v{font-size:var(--fs-sm)}
.seo-pole-teraz{margin-top:3px;font-size:var(--fs-xs)}
.seo-lista{margin:4px 0 0;padding-left:20px}
.seo-lista li{margin-bottom:5px}
.seo-uwagi{margin:11px 0 0;padding-left:20px;font-size:var(--fs-xs)}
.seo-uwagi li{margin-bottom:4px}
.seo-plan-foot{margin-top:11px;font-size:var(--fs-xs)}

/* ============================================================
   SPÓJNOŚĆ WIZUALNA — wspólne komponenty dla obu paneli
   Kolory statusów przez tokeny (--st-ok / --st-warn / --st-bad),
   dzięki czemu automatycznie dopasowują się do jasnego motywu.
   ============================================================ */

/* Linia wykresu dostępności (SVG nie przyjmuje var() w atrybucie stroke) */
.svg-ok{color:var(--st-ok)}

/* Kafelek metryki — jeden rozmiar w całej aplikacji (były 3 różne) */
.ww-tile,
.bstat{
  flex:1;min-width:100px;text-align:center;
  padding:var(--sp-3) var(--sp-2);
  border:1px solid var(--border);border-radius:var(--r-ctrl);
  background:var(--surface);
}
.ww-tile.hot{border-color:var(--accent)}
.ww-tile-n,
.bstat-n{font-size:var(--fs-xl);font-weight:800;line-height:1.15}
.ww-tile.hot .ww-tile-n{color:var(--accent)}
/* overflow-wrap: etykiety typu „kontakt/audyt/konsultacja" to jeden nierozdzielny
   token — bez tego wylewały się poza kafelek. */
.ww-tile-l,
.bstat-l{font-size:var(--fs-xs);color:var(--muted);margin-top:5px;overflow-wrap:anywhere}
.bstat-h{font-size:var(--fs-2xs);color:var(--faint);margin-top:2px;overflow-wrap:anywhere}

/* Pudełko z ramką — zastępuje powtarzane style inline */
.ww-box{border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface);padding:var(--sp-3)}

/* Statusy — jednolite kropki i teksty */
.st-ok{color:var(--st-ok)}
.st-warn{color:var(--st-warn)}
.st-bad{color:var(--st-bad)}
.st-dot{display:inline-block;width:8px;height:8px;border-radius:50%;vertical-align:middle}
.st-dot.ok{background:var(--st-ok)}
.st-dot.warn{background:var(--st-warn)}
.st-dot.bad{background:var(--st-bad)}

/* Odznaki: dociągamy do tokenów statusów (spójnie w obu motywach) */
.badge.ok{background:var(--ok-bg);color:var(--st-ok);border-color:color-mix(in srgb, var(--st-ok) 30%, transparent)}
.badge.warn{background:rgba(224,163,58,.14);color:var(--st-warn);border-color:color-mix(in srgb, var(--st-warn) 30%, transparent)}

/* ============================================================
   TOASTY — nieblokujące powiadomienia (zastępują natywny alert())
   alert() zatrzymywał całą przeglądarkę i wyglądał obco.
   Dostępność: role="status" + aria-live, można zamknąć klawiaturą.
   ============================================================ */
.toast-wrap{
  position:fixed;right:16px;bottom:16px;z-index:300;
  display:flex;flex-direction:column;gap:var(--sp-2);
  max-width:min(380px, calc(100vw - 32px));
  pointer-events:none;
}
.toast{
  display:flex;align-items:flex-start;gap:10px;
  padding:var(--sp-3) 14px;
  border:1px solid var(--border-2);border-left-width:3px;border-radius:var(--r-ctrl);
  background:var(--modal-bg);color:var(--txt);
  box-shadow:var(--shadow-lg);
  font-size:var(--fs-sm);line-height:1.5;
  pointer-events:auto;
  animation:toastIn .22s var(--ww-ease,ease) both;
}
.toast.out{animation:toastOut .18s var(--ww-ease,ease) both}
.toast.ok{border-left-color:var(--st-ok)}
.toast.err{border-left-color:var(--st-bad)}
.toast.info{border-left-color:var(--accent)}
.toast-ic{flex:0 0 auto;font-size:var(--fs-md);line-height:1.3}
.toast-msg{flex:1;min-width:0;word-break:break-word}
.toast-x{
  flex:0 0 auto;background:none;border:0;cursor:pointer;
  color:var(--muted);font-size:var(--fs-md);line-height:1;padding:0 2px;
}
.toast-x:hover{color:var(--txt)}
.toast-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Pasek „Cofnij” po usunięciu. To jedyne wyjście z pomyłki, więc musi wyglądać jak
   przycisk (obwódka, kursor), a nie jak dopisek — i pokazywać, ile zostało czasu. */
.toast-undo{
  flex:0 0 auto;align-self:center;white-space:nowrap;
  background:none;border:1px solid var(--border-2);border-radius:var(--r-sm,6px);
  color:var(--accent);font:inherit;font-weight:600;cursor:pointer;padding:4px 10px;
}
.toast-undo:hover{border-color:var(--accent)}
.toast-undo:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.toast-licz{color:var(--muted);font-weight:400;font-variant-numeric:tabular-nums}

@keyframes toastIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(6px)}}
@media (prefers-reduced-motion:reduce){
  .toast,.toast.out{animation:none}
}
@media (max-width:560px){
  .toast-wrap{left:12px;right:12px;bottom:12px;max-width:none}
}

/* ============================================================
   SKRÓTY NA TELEFONIE — dolny pasek w zasięgu kciuka
   TYLKO na telefonie: na szerszym ekranie menu boczne stoi na wierzchu, więc pasek
   byłby powtórzeniem tego samego. Zawartość (i kolejność) wypełnia skrotyRysuj()
   w js/panel-konto.js — tutaj jest wyłącznie kształt.
   Blok stoi PO regułach responsywnych i po `.toast-wrap`, bo musi nadpisać ich dół —
   przeniesiony wyżej przestanie działać, mimo że wygląda identycznie.
   ============================================================ */
.ww-skroty{display:none}
@media (max-width:700px){
  :root{--sk-h:60px}
  .ww-skroty{
    display:grid;grid-auto-flow:column;grid-auto-columns:1fr;
    position:fixed;left:0;right:0;bottom:0;
    /* PONIŻEJ zasłony menu (.side-ov, z-index 35): otwarta szuflada ma przykryć pasek,
       inaczej skróty wisiałyby na wierzchu menu, które same otworzyły. */
    z-index:32;
    height:var(--sk-h);padding-bottom:env(safe-area-inset-bottom,0px);
    background:var(--bg-2);border-top:1px solid var(--border-2);
    box-shadow:0 -6px 18px rgba(0,0,0,.18);
  }
  .sk-item{
    position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    min-width:0;padding:0 2px;border:0;background:none;cursor:pointer;
    color:var(--muted);font:inherit;font-size:var(--fs-2xs);line-height:1.2;
    -webkit-tap-highlight-color:transparent;
  }
  .sk-item .sk-ic{display:flex}
  .sk-item svg{width:22px;height:22px;stroke-width:1.8}
  /* Podpis MUSI zostać. Na pasku, który układa się pod nawyk klienta, sama ikona byłaby
     zgadywanką — po tygodniu to samo miejsce prowadzi gdzie indziej. */
  .sk-lab{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .sk-item.active{color:var(--accent)}
  .sk-item.active::before{content:"";position:absolute;top:0;left:22%;right:22%;height:2px;border-radius:0 0 2px 2px;background:var(--accent)}
  .sk-item:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}
  .sk-dot{
    position:absolute;top:6px;left:calc(50% + 6px);min-width:16px;height:16px;padding:0 4px;
    border-radius:var(--r-pill);background:var(--st-bad);color:#fff;
    font-size:9px;line-height:16px;font-weight:700;text-align:center;
  }
  /* Pasek leży NA treści, więc treść musi mieć pod czym się skończyć — bez tego ostatni
     przycisk sekcji zostaje trwale poza zasięgiem, bo nie da się go wyprzewijać. */
  .content{padding-bottom:calc(var(--sk-h) + var(--sp-4) + env(safe-area-inset-bottom,0px))}
  /* Pasek „Cofnij” to jedyne wyjście z pomyłki — schowany za skrótami byłby bezużyteczny. */
  .toast-wrap{bottom:calc(var(--sk-h) + 12px + env(safe-area-inset-bottom,0px))}
  .ww-theme-tgl{bottom:calc(var(--sk-h) + 14px + env(safe-area-inset-bottom,0px))}
}

/* Wskaźnik zapisywania — cienki pasek u góry podczas żądań zmieniających dane */
.saving-bar{
  position:fixed;top:0;left:0;right:0;height:2px;z-index:400;
  background:var(--accent);
  transform:scaleX(0);transform-origin:left;
  transition:transform .25s ease, opacity .3s ease;
  opacity:0;pointer-events:none;
}
.saving-bar.on{transform:scaleX(.75);opacity:1}
.saving-bar.done{transform:scaleX(1);opacity:0}

/* ============================================================
   MODAL POTWIERDZENIA — zastępuje natywne confirm()
   confirm() blokował całą przeglądarkę i wyglądał obco.
   Dostępność: focus na przycisku, Esc = anuluj, Enter = potwierdź.
   ============================================================ */
.cf-ov{
  position:fixed;inset:0;z-index:350;display:none;
  align-items:center;justify-content:center;padding:var(--sp-5);
  background:rgba(0,0,0,.6);backdrop-filter:blur(4px);
}
.cf-ov.show{display:flex}
.cf-box{
  width:100%;max-width:420px;
  background:var(--surface-2);border:1px solid var(--border-2);
  box-shadow:var(--shadow-lg);padding:var(--sp-5);
  animation:wwPop .2s var(--ww-ease,ease) both;
}
.cf-title{font-family:var(--head);font-size:var(--fs-md);font-weight:800;margin:0 0 var(--sp-2);display:flex;align-items:center;gap:9px}
.cf-msg{font-size:var(--fs-sm);line-height:1.6;color:var(--muted);margin:0 0 18px;white-space:pre-wrap}
.cf-actions{display:flex;gap:var(--sp-2);justify-content:flex-end;flex-wrap:wrap}
@media (prefers-reduced-motion:reduce){ .cf-box{animation:none} }

/* ============================================================
   OŚ CZASU PROJEKTU (panel klienta)
   ============================================================ */
.tl{margin-top:var(--sp-4)}
.tl-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:var(--sp-3)}
.tl-item{
  position:relative;display:flex;gap:var(--sp-3);
  padding:9px 0 9px var(--sp-1);
}
/* pionowa linia łącząca kroki */
.tl-item::before{
  content:"";position:absolute;left:12px;top:26px;bottom:-9px;width:1px;
  background:var(--border);
}
.tl-item:last-child::before{display:none}
.tl-dot{
  flex:0 0 20px;width:20px;height:20px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:var(--fs-2xs);line-height:1;
  border:1.5px solid var(--border);background:var(--surface);color:transparent;
  position:relative;z-index:1;
}
.tl-item.is-done .tl-dot{background:var(--st-ok);border-color:var(--st-ok);color:#fff}
.tl-item.is-next .tl-dot{border-color:var(--accent);color:var(--accent);background:var(--surface)}
.tl-item.is-mine .tl-dot{border-color:var(--st-warn);color:var(--st-warn)}
.tl-body{flex:1;min-width:0}
.tl-title{font-size:var(--fs-sm);line-height:1.45;display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.tl-item.is-done .tl-title{opacity:.55}
.tl-now{
  font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.08em;text-transform:uppercase;
  padding:2px 6px;background:var(--accent);color:#fff;
}
.tl-meta{display:flex;gap:10px;flex-wrap:wrap;margin-top:3px;font-size:var(--fs-xs)}
.tl-owner{color:var(--st-warn);font-weight:700}
.tl-owner.team{color:var(--muted);font-weight:400}
.tl-due{color:var(--muted);font-family:var(--mono)}
.tl-due.soon{color:var(--st-warn)}
.tl-due.late{color:var(--st-bad);font-weight:700}
.tl-due.done{color:var(--muted);opacity:.7}
/* zadanie czekające na klienta — wyraźnie wyróżnione */
.tl-item.is-mine{
  background:rgba(224,163,58,.07);
  border-left:2px solid var(--st-warn);
  padding-left:10px;margin-left:-6px;
}
.tl-item.is-mine::before{left:18px}

/* ============================================================
   OKNO EDYCJI (wwEdit) + PODGLĄD DANYCH W KARCIE
   Listy pokazują dane (dl.ed-view), edycja dzieje się w oknie.
   ============================================================ */
.ed-view{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:10px 18px;margin:var(--sp-3) 0 6px;padding:var(--sp-3) 0;
  border-top:1px solid var(--border);border-bottom:1px solid var(--border);
}
.ed-view > div{min-width:0}
.ed-view > div.wide{grid-column:1/-1}
.ed-view dt{
  font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);margin-bottom:3px;
}
.ed-view dt .lc{text-transform:none;letter-spacing:0;font-family:var(--sans)}
.ed-view dd{margin:0;font-size:var(--fs-sm);line-height:1.5;white-space:pre-wrap;word-break:break-word}
/* odpowiedź już wysłana do klienta — widoczna od razu na karcie */
.ed-reply{
  margin-top:10px;padding:9px var(--sp-3);border-left:2px solid var(--st-ok);
  background:rgba(43,209,138,.06);font-size:var(--fs-sm);line-height:1.5;white-space:pre-wrap;
}
.ed-reply-l{
  display:block;font-family:var(--mono);font-size:var(--fs-2xs);letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);margin-bottom:var(--sp-1);
}
/* przycisk testu GA — zostaje na karcie, instrukcje przeniesione do okna */
.care-ga{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:2px 0 6px}

/* --- samo okno --- */
.ed-ov{
  position:fixed;inset:0;z-index:9000;display:none;
  background:rgba(0,0,0,.72);backdrop-filter:blur(3px);
  padding:var(--sp-6);overflow-y:auto;
}
.ed-ov.show{display:flex;align-items:flex-start;justify-content:center}
.ed-box{
  width:100%;max-width:680px;margin:auto;
  background:var(--surface);border:1px solid var(--border);
  display:flex;flex-direction:column;max-height:calc(100vh - 48px);
}
.ed-head{
  display:flex;align-items:flex-start;gap:var(--sp-3);
  padding:var(--sp-4) 18px;border-bottom:1px solid var(--border);
}
.ed-head h2{margin:0;font-size:var(--fs-md);line-height:1.3}
.ed-sub{
  margin:3px 0 0;font-size:var(--fs-xs);color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.ed-x{
  margin-left:auto;flex:0 0 auto;background:none;border:1px solid var(--border);
  color:var(--muted);width:30px;height:30px;cursor:pointer;font-size:var(--fs-base);line-height:1;
  border-radius:var(--r-ctrl);transition:color var(--dur-base),border-color var(--dur-base);
}
.ed-x:hover{color:var(--txt);border-color:var(--txt)}
.ed-body{padding:var(--sp-4) 18px;overflow-y:auto;flex:1}
.ed-note{
  margin:0 0 14px;padding:10px var(--sp-3);border:1px solid var(--border);
  border-radius:var(--r-ctrl);font-size:var(--fs-xs);line-height:1.6;color:var(--muted);
}
.ed-note b{color:var(--txt)}
.ed-note details{margin-top:var(--sp-2)}
.ed-note summary{cursor:pointer}
.ed-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3) 14px}
.ed-f{min-width:0;display:flex;flex-direction:column}
.ed-f.wide{grid-column:1/-1}
.ed-f label{margin-bottom:5px}
.ed-f .lc{text-transform:none;letter-spacing:0;font-family:var(--sans);color:var(--muted);font-weight:400}
.ed-f input,.ed-f select,.ed-f textarea{margin:0;width:100%}
.ed-f textarea{resize:vertical}
.ed-hint{margin-top:6px;font-size:var(--fs-xs);color:var(--muted);line-height:1.55}
.ed-foot{
  display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;
  padding:13px 18px;border-top:1px solid var(--border);
}
.ed-msg{font-size:var(--fs-sm);flex:1;min-width:120px;line-height:1.45}
.ed-extra{display:flex;gap:var(--sp-2);flex-wrap:wrap}
/* okno potwierdzenia musi być NAD oknem edycji (pyta o niezapisane zmiany) */
.cf-ov{z-index:9500}
@media(max-width:640px){
  .ed-ov{padding:0}
  .ed-box{max-width:none;min-height:100vh;max-height:none;border:none;border-radius:0}
  .ed-grid{grid-template-columns:1fr}
  .ed-foot{position:sticky;bottom:0}
  .ed-foot .btn{flex:1}
}

/* ============================================================
   TŁO OKIEN MODALNYCH — pełne, nieprzezroczyste
   Okno unosi się NAD treścią, więc musi ją zasłaniać w stu procentach:
   przy tle półprzezroczystym tekst z listy pod spodem prześwituje przez
   formularz i wszystko robi się nieczytelne.
   Skala jasności o stopień wyżej niż karty (karta #151416 → okno #171618),
   bo okno leży wyżej w hierarchii — to samo prawo co „element w karcie".
   ============================================================ */
:root{ --modal-bg:#171618; --modal-head:#1d1b1f; --modal-foot:#141315; }
/* Jasny motyw idzie w drugą stronę: okno #fdfcfa, a pola w nim (--surface) są BIAŁE,
   czyli znowu o stopień jaśniejsze od podłoża. Gdyby okno było białe, pola zniknęłyby. */
   Nagłówek i stopka są w jasnym motywie tylko o WŁOS ciemniejsze od okna: to pasy
   pod mikro-etykiety (--faint) i podpisy akcentem, a każdy dalszy stopień w dół
   zbija je pod 4.5:1. Rozdzielenie robi tu kreska obrysu, nie różnica jasności. */
html.html-light-mode{ --modal-bg:#fdfcfa; --modal-head:#fbf9f6; --modal-foot:#fbf9f6; }

.ed-box, .cf-box{
  background:var(--modal-bg);
  border:1px solid var(--border-2);
  border-radius:var(--r-card);
  box-shadow:var(--shadow-lg);
}
/* nagłówek i stopka mają własne tło i dochodzą do krawędzi — bez przycięcia
   wystawałyby prostym rogiem poza zaokrąglenie okna */
.ed-box{ overflow:hidden; }
.ed-head{ background:var(--modal-head); }
.ed-foot{ background:var(--modal-foot); }
/* przyciemniamy też tło pod oknem — mocniejszy kontrast, mniej rozpraszania */
.ed-ov{ background:rgba(0,0,0,.82); backdrop-filter:blur(5px); }
.cf-ov{ background:rgba(0,0,0,.82); backdrop-filter:blur(5px); }
html.html-light-mode .ed-ov,
html.html-light-mode .cf-ov{ background:rgba(28,22,38,.55); }
/* pola w oknie: o stopień jaśniejsze niż okno, tak samo jak pola w karcie są
   jaśniejsze od karty. Przezroczysta czerń nie działa — okno ma własne tło,
   więc półprzezroczyste warstwy dawały inny odcień w nagłówku, treści i stopce. */
.ed-f input, .ed-f select, .ed-f textarea{ background:var(--surface); }
.ed-note{ background:var(--surface); }

/* ============================================================
   wwPrompt — okno na wpisanie tekstu (zastępuje natywne prompt())
   ============================================================ */
.pr-box{max-width:560px;text-align:left}
.pr-box textarea{
  width:100%;margin:10px 0 0;resize:vertical;
  text-transform:none;letter-spacing:0;font-family:var(--sans);
  background:var(--surface);
}
.pr-err{
  display:none;margin:var(--sp-2) 0 0;font-size:var(--fs-sm);color:var(--st-bad);font-weight:600;
}
.pr-box .cf-actions{margin-top:14px}

/* ============================================================
   PULPIT: sygnały już przejrzane
   ============================================================ */
.dash-stat{cursor:pointer}
.att-done{margin-top:var(--sp-2);border-top:1px solid var(--border);padding-top:6px}
.att-done summary{
  cursor:pointer;font-size:var(--fs-xs);color:var(--muted);
  font-family:var(--mono);letter-spacing:.04em;text-transform:uppercase;
  padding:var(--sp-1) 0;list-style:none;
}
.att-done summary:hover{color:var(--txt)}
.att-done summary::-webkit-details-marker{display:none}
.att-done summary::before{content:"▸ ";display:inline-block;transition:transform var(--dur-base)}
.att-done[open] summary::before{content:"▾ "}
.todo-item.att-seen{opacity:.5}
.todo-item.att-seen:hover{opacity:.85}

/* ============================================================
   EKRAN LOGOWANIA — dopracowanie
   ============================================================ */
/* wejście karty: subtelne, jednorazowe (bez animacji przy prefers-reduced-motion) */
.auth-pane .ww-card{animation:authIn .38s cubic-bezier(.22,.8,.3,1) both}
@keyframes authIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.auth-pane .ww-card{animation:none}}

/* zakładki: wyraźny wskaźnik aktywnej, zamiast samego pogrubienia */
.tabs{position:relative}
.tab{position:relative;transition:color var(--dur-base)}

/* ostrzeżenie o Caps Locku */
.caps-warn{
  margin:7px 0 0;padding:6px 9px;font-size:var(--fs-xs);line-height:1.4;
  color:var(--st-warn);border-left:2px solid var(--st-warn);
  border-radius:0 var(--r-sm) var(--r-sm) 0;
  background:rgba(224,163,58,.08);
}

/* miernik siły hasła */
.pw-meter{
  height:3px;margin-top:9px;background:var(--border);overflow:hidden;
}
.pw-meter span{
  display:block;height:100%;width:0;transition:width .2s,background .2s;background:var(--st-bad);
}
.pw-meter span.s2{background:var(--st-warn)}
.pw-meter span.s3{background:var(--st-ok)}
.pw-meter span.s4{background:var(--st-ok)}
.pw-reqs{
  list-style:none;margin:var(--sp-2) 0 0;padding:0;
  display:grid;grid-template-columns:1fr 1fr;gap:3px var(--sp-3);
  font-size:var(--fs-xs);color:var(--muted);
}
.pw-reqs li{display:flex;align-items:center;gap:6px;line-height:1.45}
.pw-reqs li.rq-opt{grid-column:1/-1}
.pw-reqs .rq-i{
  flex:0 0 12px;font-size:var(--fs-2xs);color:var(--muted);font-weight:700;text-align:center;
}
.pw-reqs li.rq-ok{color:var(--st-ok)}
.pw-reqs li.rq-ok .rq-i{color:var(--st-ok)}

/* przycisk w trakcie wysyłania */
.btn.is-busy{opacity:.75;cursor:progress}

/* Rejestr błędów (admin → Błędy) */
.err-stack{font-size:var(--fs-xs);line-height:1.5;white-space:pre-wrap;word-break:break-word;background:var(--surface);border-radius:var(--r-ctrl);padding:10px;margin-top:var(--sp-2);max-height:260px;overflow:auto}

/* Okno wyniku AI (wspólne dla funkcji AI w panelu) */
.ai-box{margin:10px 0;padding:11px 13px;border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:0 var(--r-ctrl) var(--r-ctrl) 0;background:var(--surface)}
.ai-box-head{display:flex;align-items:center;gap:10px;font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:6px}
.ai-box-head>span:first-child{flex:1}
.ai-x{flex:0 0 auto;background:none;border:none;color:var(--muted);cursor:pointer;font-size:var(--fs-md);line-height:1;padding:2px var(--sp-1)}
.ai-x:hover{color:var(--txt)}
.ai-box-txt{font-size:var(--fs-sm);line-height:1.6;white-space:pre-wrap}
.ai-box-btns{display:flex;flex-wrap:wrap;gap:7px;margin-top:10px}

/* Skąd pochodzi plik (kolumna „Gdzie dodany") */
.fk{display:inline-block;font-size:var(--fs-2xs);font-weight:600;letter-spacing:.02em;padding:3px var(--sp-2);border:1px solid var(--border);border-radius:var(--r-xs);white-space:nowrap;cursor:help}
.fk-proj{color:var(--muted)}
.fk-preview{color:#c084fc;border-color:rgba(192,132,252,.45);background:rgba(192,132,252,.10)}
.fk-brand{color:#38bdf8;border-color:rgba(56,189,248,.45);background:rgba(56,189,248,.10)}
.fk-intake{color:#fbbf24;border-color:rgba(251,191,36,.45);background:rgba(251,191,36,.10)}

/* ============================================================
   PASEK DZIAŁAŃ PROJEKTU
   Osiem przycisków w jednym ciągu zlewało się w ścianę tekstu, a „Usuń projekt"
   sąsiadował z często klikanymi. Dzielimy na grupy: zawartość projektu | działania |
   usuwanie (odsunięte na koniec, z separatorem).
   ============================================================ */
.proj-bar{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin-top:var(--sp-3)}
.pb-group{display:flex;flex-wrap:wrap;gap:7px}
.pb-group + .pb-group{padding-left:14px;border-left:1px solid var(--border)}
.pb-danger{margin-left:auto}
.proj-bar .btn{min-height:38px}                     /* wygodny cel kliknięcia/dotyku */
/* Otwarty panel — strzałka w dół mówi „to jest teraz rozwinięte pod spodem" */
.proj-bar .btn.is-open::after{content:'▾';margin-left:7px;font-size:var(--fs-2xs);opacity:.9}
@media (max-width:640px){
  .pb-group + .pb-group{padding-left:0;border-left:none}
  .pb-danger{margin-left:0}
  .proj-bar{gap:10px}
  .proj-bar .btn{flex:1 1 auto}                     /* na telefonie przyciski wypełniają szerokość */
}

/* Dowód akceptacji umowy (panel klienta) */
.agr-proof{margin-top:10px;border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.agr-proof summary{cursor:pointer;padding:9px var(--sp-3);font-size:var(--fs-sm);font-weight:600}
.agr-proof-b{padding:0 var(--sp-3) var(--sp-3)}
.agr-proof-b>div{display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-3);padding:6px 0;border-top:1px solid var(--border)}
.agr-proof-b>div>span{flex:0 0 190px;color:var(--muted);font-size:var(--fs-xs)}
.agr-proof-b code{font-size:var(--fs-2xs);word-break:break-all}

/* Rozliczenia */
.inv-totals{display:flex;flex-wrap:wrap;gap:10px;margin:var(--sp-3) 0 var(--sp-4)}
/* Kafel bywa <div> (sama liczba) albo <button> (klik = filtr listy klientów) —
   dlatego resetujemy font/kolor/obramowanie, żeby oba wyglądały identycznie. */
.inv-t{flex:1 1 160px;border:1px solid var(--border);border-radius:var(--r-ctrl);padding:11px 13px;background:var(--surface);
  font-family:var(--sans);color:var(--txt);text-align:left;margin:0}
button.inv-t{cursor:pointer;transition:border-color var(--dur-base),background var(--dur-base),transform var(--dur-fast)}
button.inv-t:hover{border-color:var(--accent-2);background:var(--accent-soft)}
button.inv-t:active{transform:scale(.985)}
button.inv-t:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
button.inv-t[aria-pressed=true]{border-color:var(--accent);background:var(--accent-soft);box-shadow:var(--inset-hi)}
.inv-t>span{display:block;font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:var(--sp-1)}
.inv-t>b{font-size:var(--fs-lg)}
.inv-t.is-late{border-color:var(--danger);color:var(--danger)}
.inv-t.is-late>span{color:var(--danger)}
.inv-row{display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-3);padding:6px 0;border-top:1px solid var(--border);font-size:var(--fs-sm)}
.inv-row>span{flex:0 0 150px;color:var(--muted);font-size:var(--fs-xs)}
a.fk{text-decoration:none}

/* --- Rozliczenia u KLIENTA: sekcje zamiast ciągu identycznych kart ---
   Wcześniej abonamenty i faktury leciały jedną listą, a pod każdym abonamentem
   powtarzało się to samo zdanie — nie dało się jednym spojrzeniem odpowiedzieć
   „ile mam zapłacić i do kiedy". Teraz: nagłówek sekcji, wyjaśnienie RAZ na
   sekcję, kwota jako największy element karty, historia opłaconych zwinięta. */
.bill-sec{margin:0 0 var(--sp-5)}
.bill-sec-h{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin:0 0 var(--sp-2);
  padding-bottom:var(--sp-2);border-bottom:1px solid var(--border)}
.bill-sec-h h3{margin:0;font-size:var(--fs-base)}
.bill-note{margin:0 0 var(--sp-3);color:var(--muted);font-size:var(--fs-sm);line-height:1.55}
.bill-ok{margin:0;padding:var(--sp-3) var(--sp-4);border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--ok-bg);
  color:var(--ok);font-size:var(--fs-sm);font-weight:600}
.bill-subs{display:grid;gap:var(--sp-2)}
.bill-sub{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:var(--r-ctrl);background:var(--surface);box-shadow:var(--inset-hi)}
.bill-sub.off{border-left-color:var(--muted)}
.bill-ic{flex:0 0 auto;font-size:18px;line-height:1}
.bill-main{flex:1 1 auto;min-width:0}
.bill-main>b{display:block;font-size:var(--fs-sm);overflow-wrap:anywhere}
.bill-meta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-1) var(--sp-2);margin-top:5px;
  color:var(--muted);font-size:var(--fs-xs)}
.bill-amt{display:flex;flex-direction:column;align-items:flex-end;flex:0 0 auto;line-height:1.25;white-space:nowrap}
.bill-amt>b{font-size:var(--fs-lg);font-family:var(--mono)}
.bill-amt>span{color:var(--muted);font-size:var(--fs-2xs)}
.bill-invs{display:grid;gap:var(--sp-3);grid-template-columns:1fr}
@media (min-width:820px){ .bill-invs{grid-template-columns:1fr 1fr} }
/* Akcent siedzi na GÓRNEJ krawędzi — przy ostrych narożnikach kreska biegnie przez całą
   szerokość i czyta się jak zakładka teczki. (Gdyby --r-card kiedyś wrócił na niezerowy,
   trzeba ją przenieść na lewą krawędź: pozioma urywa się w połowie łuku i wygląda
   jak błąd rysowania.) */
.bill-inv{display:flex;flex-direction:column;gap:6px;padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--border);border-top:2px solid var(--edge);border-radius:var(--r-card);
  background:var(--surface);box-shadow:var(--inset-hi)}
.bill-inv.is-late{border-color:var(--danger);border-top-color:var(--danger)}
.bill-inv.is-paid{background:var(--surface-2);border-top-color:var(--border-2)}
.bill-inv-h{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);flex-wrap:wrap}
.bill-inv-h>b{font-family:var(--mono);font-size:var(--fs-xs);color:var(--muted)}
.bill-inv-t{font-size:var(--fs-base);font-weight:600;line-height:1.35;overflow-wrap:anywhere}
.bill-inv-x{color:var(--muted);font-size:var(--fs-xs)}
.bill-inv-note{color:var(--muted);font-size:var(--fs-xs);line-height:1.5;
  border-left:2px solid var(--border);padding-left:var(--sp-2)}
.bill-inv-f{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-2);flex-wrap:wrap;
  margin-top:auto;padding-top:var(--sp-2);border-top:1px solid var(--border)}
.bill-inv-f .bill-amt{align-items:flex-start}
.bill-inv.is-late .bill-amt>b{color:var(--danger)}

/* --- JAK ZAPŁACIĆ (dane do przelewu przy fakturze) ---
   Panel liczył „ile i do kiedy", ale nie mówił DOKĄD — a PDF faktury bywa nieprzypięty.
   Blok siedzi w karcie konkretnej faktury, bo tam klient podejmuje decyzję o przelewie.
   Numer konta i tytuł idą fontem MONO z tabular-nums: to numery, które człowiek porównuje
   znak po znaku z tym, co wkleił do banku — proporcjonalny font utrudnia właśnie to. */
.bill-pay{margin-top:var(--sp-2);padding:var(--sp-3);display:flex;flex-direction:column;gap:4px;
  border:1px dashed var(--border);border-left:2px solid var(--edge);border-radius:var(--r-ctrl);background:var(--surface-2)}
.bill-pay-h{font-size:var(--fs-xs);font-weight:700;letter-spacing:.02em;margin-bottom:2px}
.bill-pay-r{display:flex;align-items:baseline;gap:var(--sp-2);flex-wrap:wrap}
.bill-pay-r>span{flex:0 0 100px;color:var(--muted);font-size:var(--fs-2xs)}
.bill-pay-r>b{flex:1 1 auto;font-size:var(--fs-xs);overflow-wrap:anywhere}
.bill-pay-r>b.big{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:var(--fs-sm)}
.bill-pay-n{margin:2px 0 0;color:var(--muted);font-size:var(--fs-2xs);line-height:1.5}
/* Przycisk kopiowania celowo drobny i bez tła: ma być pod ręką, ale nie konkurować
   z „Pobierz PDF". Stan „Skopiowano ✓" jest SŁOWEM, nie samym kolorem (dostępność). */
.bill-pay-c{flex:0 0 auto;padding:2px 8px;font:inherit;font-size:var(--fs-2xs);cursor:pointer;
  color:var(--muted);background:transparent;border:1px solid var(--border);border-radius:var(--r-xs)}
.bill-pay-c:hover{color:var(--txt);border-color:var(--edge)}
.bill-pay-c:focus-visible{outline:2px solid var(--edge);outline-offset:2px}
.bill-pay-c.done{color:var(--st-ok);border-color:var(--st-ok)}
@media (max-width:520px){ .bill-pay-r>span{flex:1 0 100%} }
/* Ostrzeżenie przy kodzie QR bez kwoty — TREŚĆ mówi, co zrobić, kolor tylko ją wzmacnia
   (samym kolorem nie da się przekazać „wpisz kwotę ręcznie"). */
.bill-pay-n.is-warn{color:var(--danger);font-size:var(--fs-xs)}
/* Typ dokumentu: rachunek, rachunek do umowy o dzieło, faktura. Drobny wiersz pod numerem —
   klient ma wiedzieć, CO dostał, ale nazwa dokumentu nie konkuruje z kwotą i terminem. */
.bill-inv-doc{color:var(--muted);font-size:var(--fs-2xs);letter-spacing:.02em;margin-top:-2px}
/* --- KOD QR + ZGŁOSZENIE PRZELEWU ---
   Oba zwinięte w <details>: to czynności jednorazowe przy JEDNYM dokumencie, a rozwinięte
   na stałe rozpychałyby listę, po której klient najczęściej tylko przebiega wzrokiem. */
.bill-qr,.bill-claim{margin-top:var(--sp-2)}
.bill-qr>summary,.bill-claim>summary{cursor:pointer;font-size:var(--fs-xs);color:var(--muted);
  padding:4px 0;list-style:none}
.bill-qr>summary::-webkit-details-marker,.bill-claim>summary::-webkit-details-marker{display:none}
.bill-qr>summary::before,.bill-claim>summary::before{content:"▸ ";display:inline-block;width:1em}
.bill-qr[open]>summary::before,.bill-claim[open]>summary::before{content:"▾ "}
.bill-qr>summary:hover,.bill-claim>summary:hover{color:var(--txt)}
.bill-qr>summary:focus-visible,.bill-claim>summary:focus-visible{outline:2px solid var(--edge);outline-offset:2px}
/* Białe tło pod kodem NIEZALEŻNIE od motywu: czytnik banku wymaga ciemnych modułów na
   jasnym tle, a w trybie ciemnym kod na ciemnym tle po prostu się nie skanuje. */
.bill-qr-b{margin:var(--sp-2) 0;padding:var(--sp-2);background:#fff;border-radius:var(--r-sm);width:max-content;max-width:100%;
  color:#111;font-size:var(--fs-2xs)}
.bill-qr-b svg{display:block;width:180px;height:180px;max-width:100%}
.bill-claim-b{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);padding:var(--sp-2) 0}
.bill-claim-b>label{color:var(--muted);font-size:var(--fs-2xs)}
.bill-claim-b>input{width:auto;flex:0 0 auto}
.bill-claim-b>.bill-pay-n{flex:1 0 100%}
/* Stan „zgłoszono" musi być widoczny bez rozwijania czegokolwiek — to jedyna informacja
   zwrotna, jaką klient dostaje po kliknięciu, dopóki wpłata nie zostanie zaksięgowana. */
.bill-claimed{margin:var(--sp-2) 0 0;padding:6px var(--sp-2);font-size:var(--fs-2xs);line-height:1.5;
  color:var(--muted);border-left:2px solid var(--edge);border-radius:0 var(--r-sm) var(--r-sm) 0;background:var(--surface-2)}

/* --- USTAWIENIA ADMINA: dane do przelewu (sekcja #sec-payto w panel/admin.html) ---
   Własna karta na SAMEJ GÓRZE Ustawień, bo to JEDYNE pole, którego błąd kosztuje pieniądze
   (przelew na obce konto) — i jedyne, bez którego klient nie wie, gdzie zapłacić. Podgląd
   pokazuje dokładnie to, co zobaczy klient: admin sprawdza numer oczami PRZED zapisem,
   a nie po pierwszej zagubionej wpłacie. */
.pay-on{display:flex;align-items:center;gap:8px;font-size:var(--fs-sm);cursor:pointer}
.pay-on input{width:auto;margin:0}
.pay-prev{padding:var(--sp-3);border:1px dashed var(--border);border-left:2px solid var(--edge);
  border-radius:var(--r-ctrl);background:var(--surface);font-size:var(--fs-xs);line-height:1.7}
.pay-prev b{font-family:var(--mono);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.pay-prev .bad{color:var(--danger)}
.pay-prev .off{color:var(--muted)}

/* --- TERMINY PŁATNOŚCI (oba panele) ---
   Wcześniej termin był surową datą w szarym tekście — żeby zrozumieć, czy to problem,
   trzeba było znać dzisiejszą datę i policzyć w głowie. Teraz obok daty stoi SŁOWO
   („za 3 dni", „dziś — ostatni dzień", „po terminie o 2 dni"), więc stan niesie sam
   tekst, a kolor tylko go wzmacnia (dostępność: nigdy sam kolor, nigdy sam title=). */
.term{display:inline-flex;align-items:center;flex-wrap:wrap;gap:4px;font-size:var(--fs-xs);color:var(--muted)}
.term time{font-variant-numeric:tabular-nums;white-space:nowrap}
.term.soon{color:var(--st-warn);font-weight:600}
.term.late{color:var(--danger);font-weight:700}
.term.paid{color:var(--ok)}
/* .bill-amt>span narzuca własny rozmiar — dorównujemy, żeby stan nie zmieniał wielkości pisma */
.bill-amt>.term{font-size:var(--fs-xs);text-align:left}
/* Ważność wyceny na karcie oferty. W tabeli faktur pigułka jest celowo drobna (gęsta lista,
   dziesiątki wierszy), ale na karcie stoi samotnie i to ona decyduje, czy klient ma jeszcze
   czas na decyzję — stopień większa i z oddechem pod spodem. */
.q-waz{font-size:var(--fs-sm);margin-bottom:8px}
/* dopisek „za ile" przy dacie w kaflach faktu (Opłacony do …) — bez mono, lekko cofnięty */
.term-rel{font-family:var(--sans);font-size:var(--fs-2xs);font-weight:600;opacity:.85;white-space:nowrap}
/* podtytuł kafla podsumowania (numer faktury, kwota, „za ile") —
   .inv-t>span jest WERSALIKAMI z odstępem liter, tu tego nie chcemy */
.inv-t .inv-t-sub{display:block;margin:4px 0 0;text-transform:none;letter-spacing:0;
  font-size:var(--fs-2xs);color:var(--muted);white-space:normal;line-height:1.45}

/* Wyceny — edytor pozycji (admin) */
.q-item{display:grid;grid-template-columns:1fr 90px 130px 40px;gap:var(--sp-2);margin-bottom:var(--sp-2)}
.q-item input{margin:0}
.q-sum{font-size:var(--fs-base);color:var(--muted)}
.q-sum b{font-size:var(--fs-lg);color:var(--txt)}
@media (max-width:640px){ .q-item{grid-template-columns:1fr 70px 110px 36px} }

/* ============================================================
   NAWIGACJA POGRUPOWANA
   Menu urosło do 22 pozycji w jednej płaskiej liście — nie dało się nic znaleźć.
   Teraz są grupy, uszeregowane od tego, co pilne i co zarabia. Nagłówki mają
   PORZĄDKOWAĆ, a nie krzyczeć: cienka linia + drobny podpis, zero ozdobników.
   ============================================================ */
.side-sec{padding-top:var(--sp-4);position:relative}
.side-sec + .nav{margin-bottom:2px}
.side-scroll > .side-sec:not(:first-child)::before{
  content:'';position:absolute;left:14px;right:14px;top:6px;height:1px;background:var(--border);opacity:.6
}
/* Odznaka „coś czeka" — ma być widoczna z drugiego końca pokoju */
.nav-item .badge{margin-left:auto;font-size:var(--fs-2xs);padding:2px 7px;font-weight:700}
.nav-item .badge.warn{background:var(--danger);color:#fff;border-color:var(--danger)}

/* ============================================================
   PORADNIKI WIDEO
   ============================================================ */
.vid-ov{position:fixed;inset:0;z-index:1200;display:none;align-items:center;justify-content:center;
  background:rgba(0,0,0,.86);padding:var(--sp-5)}
.vid-ov.show{display:flex}
.vid-box{background:var(--modal-bg);border:1px solid var(--border);border-radius:var(--r-card);max-width:900px;width:100%;padding:var(--sp-4)}
.vid-head{display:flex;align-items:center;gap:var(--sp-3);margin-bottom:10px}
.vid-head b{flex:1;font-size:var(--fs-md)}
.vid-frame{position:relative;padding-top:56.25%;background:#000}
.vid-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.vid-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px}
.vid-card{position:relative;display:block;padding:0;border:1px solid var(--border);background:none;
  cursor:pointer;text-align:left;border-radius:var(--r-ctrl);overflow:hidden}
.vid-card:hover{border-color:var(--accent)}
.vid-card img{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}
.vid-play{position:absolute;top:38%;left:50%;transform:translate(-50%,-50%);font-size:var(--fs-2xl);color:#fff;
  text-shadow:0 2px 12px rgba(0,0,0,.7);pointer-events:none}
.vid-t{display:block;padding:10px var(--sp-3);font-size:var(--fs-sm);font-weight:600;color:var(--txt)}
/* Przycisk „Jak to działa" w górnym pasku */
.vid-btn{white-space:nowrap}

/* Film powitalny na ekranie logowania — dostaje PEŁNĄ szerokość kolumny.
   To on ma sprzedać panel; tekst jest tylko podpisem. */
/* Ramka filmu nie musi zjadać całej szerokości kolumny — przy 930 px dominowała
   nad nagłówkiem i wymuszała miniaturkę, której YouTube i tak nie ma w takiej jakości. */
.ah-vid{margin:var(--sp-1) 0 0;width:100%;max-width:480px}
.ah-vid.hide{display:none}
.ah-vid-btn{position:relative;display:block;width:100%;padding:0;border:1px solid var(--border-2);
  background:none;cursor:pointer;border-radius:var(--r-card);overflow:hidden}
.ah-vid-btn:hover{border-color:var(--accent)}
/* height:auto MUSI tu być: atrybuty width/height na <img> (dla CLS) działają jak
   sztywne `height:720px` i biją aspect-ratio. Bez tego miniaturka rosła na 720 px. */
.ah-vid-btn img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
.ah-vid-play{position:absolute;inset:0;display:grid;place-items:center;font-size:var(--fs-3xl);color:#fff;
  text-shadow:0 2px 14px rgba(0,0,0,.8)}
.ah-vid-frame{position:relative;padding-top:56.25%;background:#000}
.ah-vid-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.ah-vid-t{margin-top:var(--sp-2);font-size:var(--fs-sm);font-weight:600;opacity:.85}

/* Pasek poradnika wewnątrz sekcji */
.vid-inline{border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:0 var(--r-ctrl) var(--r-ctrl) 0;
  background:var(--surface);padding:11px 13px;margin-bottom:14px}
.vid-inline-h{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.vid-inline-t{flex:1;font-size:var(--fs-sm);font-weight:600}
.vid-inline-b{margin-top:var(--sp-3)}

/* Archiwum na spodzie sekcji — rozwijane, zwinięte domyślnie */
.arch-box{margin-top:18px;border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.arch-box summary{cursor:pointer;padding:11px 13px;font-size:var(--fs-sm);font-weight:600;color:var(--muted)}
.arch-box summary:hover{color:var(--txt)}
.arch-box[open] summary{border-bottom:1px solid var(--border)}
.arch-b{padding:var(--sp-3) 13px}
.arch-b .cr-item:last-child{margin-bottom:0}

/* Zestawienie roczne + eksport CSV. Jeden rok = jeden wiersz: rok, trzy kwoty i przycisk
   pobrania. Wiersz zawija się na wąskim ekranie (auto-fit), więc na telefonie kwoty stają
   jedna pod drugą zamiast ściskać się do nieczytelnych kolumn. */
.yr-box{margin:0 0 var(--sp-5);border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface);padding:0}
.yr-box>summary{cursor:pointer;padding:11px 13px;font-size:var(--fs-sm)}
.yr-box[open]>summary{border-bottom:1px solid var(--border)}
.yr-list{display:grid;gap:var(--sp-2);padding:var(--sp-3) 13px 0}
.yr-row{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  padding:var(--sp-3);border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface)}
.yr-y{flex:0 0 auto;min-width:96px}
.yr-y>b{display:block;font-size:var(--fs-lg);font-family:var(--mono)}
.yr-y>span{display:block;color:var(--muted);font-size:var(--fs-2xs)}
.yr-n{flex:1 1 120px;min-width:0}
.yr-n>span{display:block;color:var(--muted);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.4px}
.yr-n>b{display:block;font-family:var(--mono);font-size:var(--fs-base);margin-top:3px;overflow-wrap:anywhere}
.yr-n .yr-s{text-transform:none;letter-spacing:0;margin-top:2px}
.yr-n.is-late>b,.yr-n.is-late .yr-s{color:var(--danger)}
.yr-dl{flex:0 0 auto;text-decoration:none}
.yr-box .yr-list+p{padding:0 13px var(--sp-3)}

/* Opieka nad sklepem — status koszyka i karty produktu */
.shop-row{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:var(--sp-2);padding-top:var(--sp-2);
  border-top:1px dashed var(--border)}
.shop-row .cm-l{font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.shop-row>div{flex-basis:100%}

/* Numer projektu na karcie — przydaje się m.in. przy szablonach */
.proj-id{font-family:var(--mono);font-size:var(--fs-2xs);color:var(--muted);background:rgba(127,127,127,.10);
  border:1px solid var(--border);border-radius:var(--r-xs);padding:2px 6px;cursor:help}

/* ── ANALITYKA / KPI ─────────────────────────────────────────
   Kafelki dzielą styl z .ww-tile; kontener układa je w responsywną siatkę.
   Wykres przychodu to pionowe słupki (flex), lejek wycen reużywa .idea-bar. */
/* Kafelki KPI to <ul>/<li> — czytnik ekranu zapowiada „lista, 3 elementy",
   więc wiadomo, ile liczb jest w grupie i gdzie się kończy. */
.ww-tiles{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-top:var(--sp-2);list-style:none;padding:0}
/* kafelek KPI jest kontenerem — jego liczba/kwota skaluje się do jego szerokości */
.ww-tile{container-type:inline-size}
.ww-tile-n{white-space:nowrap;font-size:clamp(1rem,16cqi,var(--fs-xl));max-width:100%;overflow:hidden;text-overflow:ellipsis}
.kpi-block{margin-top:var(--sp-2)}
.kpi-tile-sub{font-size:var(--fs-2xs);margin-top:3px}
.kpi-up{color:var(--st-ok)} .kpi-down{color:var(--accent)}
.kpi-chart{display:flex;align-items:flex-end;gap:var(--sp-1);
  height:150px;padding:var(--sp-2) 0 0;margin-top:var(--sp-2);
  border-bottom:1px solid var(--border)}
.kpi-bar{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;
  justify-content:flex-end;height:100%;gap:6px}
.kpi-bar-track{width:100%;max-width:34px;flex:1;display:flex;align-items:flex-end}
.kpi-bar-fill{width:100%;background:var(--accent);min-height:2px;border-radius:var(--r-xs) var(--r-xs) 0 0;
  transition:height var(--ww-dur,.4s) var(--ww-ease,ease)}
.kpi-bar-fill.is-zero{background:rgba(127,127,127,.25)}
.kpi-bar-lab{font-size:var(--fs-2xs);color:var(--muted);font-family:var(--mono);white-space:nowrap}
.kpi-cur{font-size:var(--fs-2xs);color:var(--faint);margin:6px 0 0}
/* Nagłówek grupy kafelków — osiem liczb w jednym rzędzie czytało się jak wysypka. */
.kpi-grp-h{margin:var(--sp-4) 0 0;font-size:var(--fs-2xs);font-weight:700;color:var(--muted);
  text-transform:uppercase;letter-spacing:.07em}
.kpi-grp-h:first-child{margin-top:0}
/* Tekstowa alternatywa wykresu (tabela) — zwinięta, ale zawsze pod ręką. */
.kpi-dane{margin-top:var(--sp-2)}
.kpi-dane>summary{cursor:pointer;display:inline-block;font-size:var(--fs-xs);font-weight:600;
  color:var(--accent-2);padding:4px 2px}
.kpi-dane>summary:hover{text-decoration:underline}
.kpi-dane table{margin-top:var(--sp-1)}
/* Lejek wycen: kolor niesie znaczenie tak samo jak długość słupka. */
.idea-bar-fill.ok{background:var(--st-ok)}
/* Szarość musi być mocniejsza niż tor (var(--border)), inaczej słupek zlewa się z tłem. */
.idea-bar-fill.off{background:rgba(127,127,127,.55)}
/* Etykiety lejka są krótkie — bazowe 42% robiło na szerokim ekranie pustą rynnę
   między napisem a słupkiem. Na wąskim ekranie wraca do 42%, żeby się mieściły. */
#kpiFunnel .idea-bar-lab{flex:0 0 min(42%,190px)}

/* ===== TRYB PRACOWNIKA (konto zespołowe dodane przez klienta) =====
   Wyraźnie odróżniamy panel pracownika: fioletowo-niebieski akcent (ten sam,
   którym w panelu admina oznaczone są konta zespołowe), pasek u góry, etykieta
   pod logo i ZABLOKOWANE (nie ukryte) sekcje właściciela. */
/* Etykieta „pracownik" to TEKST na półprzezroczystym tle (--member-soft na karcie), więc
   liczy się kontrast PO zmieszaniu warstw: #6e78ff dawał 4.43:1 w ciemnym i tylko 2.96:1 w
   jasnym — w obu poniżej progu 4.5:1. Ciemny motyw wymaga odcienia jaśniejszego, jasny
   wyraźnie ciemniejszego (patrz nadpisanie w sekcji trybu jasnego niżej). */
:root{--member:#767ffe;--member-soft:rgba(110,120,255,.14)}
body[data-mode="member"] .main{border-top:3px solid var(--member)}
.side-member-tag{margin:8px 0 4px;padding:5px 10px;border-radius:var(--r-sm);
  background:var(--member-soft);color:var(--member);border:1px solid rgba(110,120,255,.35);
  font-size:var(--fs-2xs);font-weight:800;letter-spacing:.03em;text-align:center}
.badge.member{background:var(--member-soft);color:var(--member);border-color:rgba(110,120,255,.4)}
.member-banner{margin:0 0 var(--sp-4,16px);padding:12px 16px;border:1px solid rgba(110,120,255,.4);
  border-left:4px solid var(--member);background:var(--member-soft);border-radius:var(--r-ctrl);
  font-size:var(--fs-xs);line-height:1.55;color:var(--txt)}
.member-banner b{color:var(--member)}
.nav-item.locked{opacity:.5;cursor:not-allowed}
.nav-item.locked:hover{transform:none;background:transparent;color:inherit}
.nav-item.locked .lock{margin-left:auto;font-size:var(--fs-2xs);opacity:.9;filter:grayscale(.2)}
/* Owner-only ustawienia w karcie „Profil" — dla pracownika widoczne, ale zablokowane (nie ciche 403). */
.member-lock-note{margin:8px 0 4px;padding:9px 12px;border-radius:var(--r-sm);font-size:var(--fs-xs,12.5px);line-height:1.5;
  background:var(--member-soft);color:var(--member);border:1px solid rgba(110,120,255,.35)}
.member-lock-note b{color:var(--member)}
body[data-mode="member"] #sec-top input:disabled,
body[data-mode="member"] #sec-top button:disabled,
body[data-mode="member"] #sec-top label:has(input:disabled){opacity:.55;cursor:not-allowed}
html.html-light-mode .side-member-tag,
html.html-light-mode .member-banner b,
html.html-light-mode .member-lock-note,
html.html-light-mode .member-lock-note b,
html.html-light-mode .badge.member{color:#4048d6}

/* ── TRYB POKAZOWY (konto demo) ──────────────────────────────
   Osobny kolor od pracownika (fiolet) i od akcentu (róż): zwiedzający ma jednym rzutem oka
   widzieć, że to inny stan panelu, a nie kolejny komunikat. Kontrast liczony PO zmieszaniu
   z --demo-soft: #ffc247 na ciemnym 8.6:1, #8a5300 na jasnym 5.8:1 (oba > 4.5:1). */
:root{--demo:#ffc247;--demo-soft:rgba(255,176,32,.14)}
body[data-mode="demo"] .main{border-top:3px solid var(--demo)}
.demo-banner{display:flex;flex-wrap:wrap;align-items:center;gap:10px;justify-content:space-between;
  margin:0 0 var(--sp-4,16px);padding:12px 16px;border:1px solid rgba(255,176,32,.4);
  border-left:4px solid var(--demo);background:var(--demo-soft);border-radius:var(--r-ctrl);
  font-size:var(--fs-xs);line-height:1.55;color:var(--txt)}
.demo-banner span{flex:1 1 260px;min-width:0}
.demo-banner b{color:var(--demo)}
.side-demo-tag{margin:8px 0 4px;padding:5px 10px;border-radius:var(--r-sm);
  background:var(--demo-soft);color:var(--demo);border:1px solid rgba(255,176,32,.35);
  font-size:var(--fs-2xs);font-weight:800;letter-spacing:.03em;text-align:center}
.badge.demo{background:var(--demo-soft);color:var(--demo);border-color:rgba(255,176,32,.4)}
/* Zaproszenie do trybu pokazowego na ekranie logowania. */
.demo-entry{display:block;padding:10px 13px;border-radius:var(--r-ctrl);text-decoration:none;
  background:var(--demo-soft);border:1px solid rgba(255,176,32,.35);
  color:var(--txt);font-size:var(--fs-sm);line-height:1.45;transition:transform .18s var(--ww-ease,ease),filter .18s ease}
.demo-entry b{color:var(--demo)}
.demo-entry:hover{transform:translateY(-1px);filter:brightness(1.06)}
/* Lista „co zobaczysz w środku" na stronie wejścia (panel/demo.html). */
.demo-list{margin:0 0 18px;padding:0;list-style:none;display:grid;gap:8px}
.demo-list li{position:relative;padding:9px 12px 9px 34px;border-radius:var(--r-sm);
  background:var(--demo-soft);border:1px solid rgba(255,176,32,.28);
  font-size:var(--fs-sm);line-height:1.5;color:var(--txt)}
.demo-list li::before{content:"✓";position:absolute;left:12px;top:9px;font-weight:900;color:var(--demo)}
html.html-light-mode .side-demo-tag,
html.html-light-mode .demo-banner b,
html.html-light-mode .demo-entry b,
html.html-light-mode .demo-list li::before,
html.html-light-mode .badge.demo{color:#8a5300}

/* ============================================================
   WZMOCNIONA WARSTWA INTERAKCJI (2026-07-18)
   Zasada: hover = uniesienie + poświata akcentu + przebłysk (sheen);
   active = dociśnięcie. Wszystko na tokenach (--ww-ease/--accent),
   spójne z ruchem strony głównej i GASNĄCE przy prefers-reduced-motion.
   Dopisane NA KOŃCU pliku — nadpisuje bazowe hover z góry (ta sama
   specyficzność, późniejsza reguła wygrywa); overridy trybu jasnego
   (html.html-light-mode …) mają wyższą specyficzność, więc nadal działają.
   ============================================================ */

/* — Przyciski: mocniejsze uniesienie + przebłysk szkła — */
.btn:hover{transform:translateY(-2px);filter:brightness(1.1);
  box-shadow:var(--inset-hi),0 10px 30px rgba(255,0,92,.5),0 2px 8px rgba(255,0,92,.35)}
.btn::after{content:"";position:absolute;top:-20%;bottom:-20%;left:-45%;width:38%;z-index:2;
  background:linear-gradient(105deg,transparent,rgba(255,255,255,.35),transparent);
  transform:skewX(-18deg) translateX(-160%);opacity:0;pointer-events:none}
.btn:hover::after{opacity:1;transform:skewX(-18deg) translateX(480%);
  transition:transform .55s var(--ww-ease),opacity var(--dur-fast) ease}
.btn.ghost:hover{filter:none}                        /* ghost: bez rozjaśniania — tylko lift+ramka */
.btn.ghost::after{background:linear-gradient(105deg,transparent,rgba(255,255,255,.18),transparent)}

/* — KLIKNIĘCIE = WIDOCZNY KOLOR —
   Bazowy `.btn:active` dawał wyłącznie dociśnięcie (cień + zjazd o 1px). Na przyciskach
   `ghost` (a tych jest w panelu najwięcej: „Zmień", „Odśwież", „Otwórz") wyglądało to jak
   „kliknąłem i nic się nie stało" — brak zmiany koloru. Każdy wariant dostaje własny,
   ciemniejszy kolor przytrzymania; `!important` nie jest potrzebne, bo te reguły są
   późniejsze i mają wyższą specyficzność niż `.btn.ghost`. */
.btn:active{background:var(--accent-2);border-color:var(--accent-2)}
.btn.ghost:active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-2)}
.btn.danger:active{background:#a8102a;border-color:#a8102a;color:#fff}
.btn.danger:focus-visible{outline-color:rgba(255,90,114,.45)}
.btn:disabled,.btn[disabled]{opacity:.55;cursor:not-allowed;filter:grayscale(.3)}
.btn:disabled:hover,.btn[disabled]:hover{transform:none;filter:grayscale(.3);box-shadow:var(--inset-hi)}
/* Linki-przyciski i pigułki też muszą reagować na sam klik, nie tylko na najechanie */
.chip:active,.canned-chip:active,.tab:active,.slot:active,.idea-kind:active{transform:scale(.97)}
a:active{color:var(--accent-2)}
html.html-light-mode .btn.ghost:active{background:rgba(232,0,79,.12);border-color:#c2003f;color:#c2003f}

/* — Ikony akcji: żywsze powiększenie + poświata; dociśnięcie przy kliknięciu — */
.icon-btn{transition:transform var(--dur-base) var(--ww-ease),border-color var(--dur-base),color var(--dur-base),box-shadow var(--dur-base)}
.icon-btn:hover{transform:scale(1.1);box-shadow:0 0 0 3px var(--accent-soft),0 4px 14px -6px rgba(255,0,92,.45)}
.icon-btn:active{transform:scale(.92)}

/* — Elementy klikalne, które NIE są `.btn` (panel klienta) —
   Kafle bazy wiedzy, nagłówki pytań, typy briefu i kafle pulpitu to `<button>`/`<div>`
   z własnymi stylami w `konto.html`. Część z nich nie miała ANI hoveru, ANI reakcji na
   klik — wyglądały jak martwy tekst. Reguły trzymamy tu (arkusz wspólny), bo pisane są
   selektorem klasowym z pseudoklasą, więc biją style bazowe niezależnie od kolejności. */
.kb-cat,.kb-q,.bf-type,.dash-stat{transition:border-color var(--dur-base),background var(--dur-base),color var(--dur-base),transform .1s var(--ww-ease)}
.kb-cat:hover,.bf-type:hover{border-color:var(--accent-2);background:var(--accent-soft);color:var(--txt)}
.kb-cat:active,.bf-type:active{transform:scale(.97);border-color:var(--accent);color:var(--accent-2)}
.kb-q:hover{background:var(--accent-soft);color:var(--accent-2)}
.kb-q:active{background:var(--accent-soft);transform:translateY(1px)}
.dash-stat:active{transform:translateY(0) scale(.985);border-color:var(--accent)}
.kb-cat:focus-visible,.kb-q:focus-visible,.bf-type:focus-visible,.dash-stat:focus-visible{
  outline:3px solid var(--accent-soft);outline-offset:2px}

/* — Zakładki widoków (mobile): tint akcentu zamiast samej ramki — */
.vtab{transition:transform var(--dur-base) var(--ww-ease),border-color var(--dur-base),background var(--dur-base),color var(--dur-base)}
.vtab:hover{color:var(--txt);border-color:var(--accent-2);background:var(--accent-soft)}
.vtab:active{transform:translateY(0) scale(.97)}

/* — Wiersze tabel: czytelne "jesteś tutaj" — tint + rozświetlona ramka karty + pasek z lewej — */
tr:hover td{background:rgba(255,0,92,.08);border-top-color:var(--border-2);border-bottom-color:var(--border-2)}
tr:hover td:first-child{box-shadow:inset 2.5px 0 0 var(--accent);border-left-color:var(--border-2)}
tr:hover td:last-child{border-right-color:var(--border-2)}
html.html-light-mode tr:hover td{background:rgba(232,0,79,.07)}
html.html-light-mode tr:hover td:first-child{box-shadow:inset 2.5px 0 0 #c2003f}

/* — Nawigacja: ikona ożywa razem z etykietą — */
.nav-item svg{transition:transform .18s var(--ww-ease),color .18s}
.nav-item:hover svg{transform:scale(1.14);color:var(--accent-2)}
.nav-item:active{transform:translateX(3px) scale(.98)}

/* — Redukcja ruchu: wszystkie nowe efekty gasną (spójnie z regułą bazową wyżej) — */
@media (prefers-reduced-motion:reduce){
  .btn::after,.btn:hover::after{opacity:0!important;transition:none!important;transform:none!important}
  .icon-btn:hover,.icon-btn:active,.vtab:active,.nav-item:active,.nav-item:hover svg{transform:none!important}
  /* kolor przytrzymania ZOSTAJE — to jedyna informacja zwrotna, gdy ruch jest wyłączony */
  .chip:active,.canned-chip:active,.tab:active,.slot:active,.idea-kind:active,
  .crm-tag:active,.chk-inline:active,
  .kb-cat:active,.bf-type:active,.kb-q:active,.dash-stat:active,.dash-stat:hover{transform:none!important}
}

/* — Wyjaśnienie sekcji („Jak czytać tę sekcję?") — reużywalne w kolejnych sekcjach — */
.sec-help{margin:0 0 var(--sp-4);border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--accent-soft)}
.sec-help summary{list-style:none;cursor:pointer;padding:9px 13px;font-size:var(--fs-sm);font-weight:600;color:var(--txt);
  display:flex;align-items:center;gap:8px;transition:color var(--dur-base)}
.sec-help summary::-webkit-details-marker{display:none}
.sec-help summary::after{content:"▾";margin-left:auto;color:var(--accent);transition:transform .2s var(--ww-ease)}
.sec-help[open] summary::after{transform:rotate(180deg)}
.sec-help summary:hover{color:var(--accent-2)}
.sec-help ul{list-style:none;margin:0;padding:0 13px 12px;display:grid;gap:8px}
.sec-help li{position:relative;padding-left:18px;font-size:var(--fs-sm);line-height:1.55;color:var(--muted)}
.sec-help li::before{content:"";position:absolute;left:2px;top:8px;width:6px;height:6px;border-radius:50%;background:var(--accent)}
.sec-help b{color:var(--txt)}

/* — Rząd szybkich akcji na karcie projektu — */
.proj-actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 0}

/* — Szybkie odpowiedzi (admin, sekcja Wiadomości) — */
.canned-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.canned-chip{font-size:var(--fs-xs);font-weight:600;color:var(--txt);background:var(--accent-soft);
  border:1px solid var(--border-2);border-radius:var(--r-pill);padding:5px 12px;cursor:pointer;font-family:var(--sans);
  transition:transform var(--dur-base) var(--ww-ease),border-color var(--dur-base),background var(--dur-base),color var(--dur-base);max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.canned-chip:hover{transform:translateY(-1px);border-color:var(--accent-2);color:var(--accent-2);background:rgba(255,0,92,.18)}
.canned-chip:active{transform:translateY(0) scale(.97)}
.canned-mgr{margin-top:14px;border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--surface);padding:14px;animation:wwPop .2s var(--ww-ease) both}
.canned-mgr .cn-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.canned-x{background:none;border:none;color:var(--muted);font-size:var(--fs-md);cursor:pointer;line-height:1;padding:2px 6px;border-radius:var(--r-sm);transition:color var(--dur-base),background var(--dur-base)}
.canned-x:hover{color:var(--txt);background:var(--accent-soft)}
.cn-list{display:grid;gap:8px}
.cn-item{display:flex;align-items:center;gap:10px;justify-content:space-between;padding:8px 10px;border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.cn-txt{min-width:0}
.cn-txt b{display:block;font-size:var(--fs-sm);color:var(--txt)}
.cn-txt span{display:block;font-size:var(--fs-xs);color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:46ch}
.canned-mgr code{background:rgba(127,127,127,.16);padding:1px 5px;border-radius:var(--r-xs);font-size:.92em}
html.html-light-mode .canned-chip:hover{background:rgba(232,0,79,.12)}

/* — Suwak „przed/po" dla podglądów (K5) — */
.pv-compare{margin:0 0 12px;border:1px solid var(--border-2);border-radius:var(--r-ctrl);background:var(--accent-soft);padding:12px}
.pv-ba{position:relative;width:100%;max-width:100%;overflow:hidden;border:1px solid var(--border);line-height:0;user-select:none;border-radius:var(--r-ctrl)}
.pv-ba img{display:block;width:100%;height:auto;pointer-events:none}
.pv-ba-after{position:relative;z-index:1}
.pv-ba-before{position:absolute;inset:0;width:50%;overflow:hidden;z-index:2;border-right:2px solid #fff}
.pv-ba-before img{width:auto;max-width:none;height:100%}          /* „przed" nie może się skalować szerokością klipa */
.pv-ba-divider{position:absolute;top:0;bottom:0;left:50%;width:2px;background:#fff;z-index:3;transform:translateX(-50%);pointer-events:none;box-shadow:0 0 0 1px rgba(0,0,0,.25)}
.pv-ba-divider span{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--accent);color:#fff;border-radius:var(--r-pill);font-size:var(--fs-2xs);font-weight:700;padding:3px 8px;white-space:nowrap;box-shadow:0 2px 8px rgba(0,0,0,.35)}
.pv-ba-tag{position:absolute;top:8px;z-index:3;font-size:var(--fs-2xs);font-weight:700;letter-spacing:.05em;color:#fff;background:rgba(0,0,0,.55);padding:2px 8px;border-radius:var(--r-xs);line-height:1.4}
.pv-ba-tag--l{left:8px}
.pv-ba-tag--r{right:8px}
#pvBARange{accent-color:var(--accent)}
html.html-light-mode .pv-compare{background:rgba(232,0,79,.08)}

/* — CRM: tagi klienta + wskaźnik notatki (sekcja Użytkownicy) — */
.crm-tag{display:inline-block;font-size:var(--fs-2xs);font-weight:600;color:var(--accent-2);background:var(--accent-soft);
  border:1px solid rgba(255,0,92,.28);border-radius:var(--r-pill);padding:1px 8px;margin:2px 3px 0 0;white-space:nowrap}
.crm-dot{color:var(--st-warn,#e0a800);font-size:.8em;vertical-align:middle}
/* Tylko SPAN — ta reguła ma wyższą specyficzność niż .crm-tag.on i .crm-tag.alarm,
   więc bez zawężenia malowała w jasnym motywie wszystkie pigułki filtrów identycznie
   (aktywny filtr był nie do odróżnienia od nieaktywnego). Filtry to <button>. */
html.html-light-mode span.crm-tag{background:rgba(232,0,79,.10);color:#b3003a;border-color:rgba(232,0,79,.3)}

/* — Oś aktywności projektu (K1) — */
.ph-tl{border-left:2px solid var(--border-2);padding-left:14px;margin-left:4px;display:flex;flex-direction:column;gap:12px}
.ph-item{position:relative;display:flex;gap:10px;align-items:flex-start}
.ph-item .ph-ic{position:absolute;left:-25px;top:-1px;width:20px;height:20px;display:grid;place-items:center;font-size:var(--fs-xs);background:var(--surface);border:1px solid var(--border-2);border-radius:50%}
.ph-body{min-width:0}
.ph-txt{font-size:var(--fs-sm);color:var(--txt);line-height:1.4}
.ph-meta{font-size:var(--fs-2xs);color:var(--muted);margin-top:2px}

/* — Warianty wyceny obok siebie (K6) — */
.q-variants-wrap{margin:0 0 16px;border:1px solid var(--border-2);border-radius:var(--r-card);background:var(--accent-soft);padding:14px}
.q-variants-head{font-weight:700;color:var(--txt);font-size:var(--fs-base);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.q-variants{display:grid;grid-template-columns:1fr;gap:12px}
@media(min-width:760px){ .q-variants{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))} }
.q-variant{margin:0;background:var(--surface)}
.q-variant--dim{opacity:.55}
.q-vbadge{display:inline-block;font-size:var(--fs-2xs);font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:#fff;background:var(--accent);border-radius:var(--r-xs);padding:2px 7px;margin-right:8px;vertical-align:middle}
html.html-light-mode .q-variants-wrap{background:rgba(232,0,79,.07)}

/* — Automatyzacje (katalog + moje; klient i admin) — */
.auto-card{border:1px solid var(--border);border-radius:var(--r-card,0);padding:14px;margin-bottom:12px;background:var(--surface)}
.auto-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.auto-head b{font-size:var(--fs-md)}
.auto-ic{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;flex-shrink:0;border:1px solid var(--border);border-radius:var(--r-ctrl);color:var(--txt);background:var(--surface);transition:border-color .18s ease,color .18s ease}
.auto-ic svg{width:20px;height:20px;display:block}
.auto-card:hover .auto-ic{border-color:var(--accent,#e8004f);color:var(--accent,#e8004f)}
.ac-row-ic{width:16px;height:16px;flex-shrink:0;color:var(--accent,#e8004f);vertical-align:middle}
.ac-cat{display:inline-flex;align-items:center;gap:6px}
.ac-cat-ic{width:14px;height:14px;flex-shrink:0;opacity:.7}
.auto-benefit{margin:8px 0 0;color:var(--accent,#e8004f);font-weight:600;font-size:var(--fs-sm)}
.auto-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px;flex-wrap:wrap}
.auto-plat{font-size:var(--fs-2xs);color:var(--muted);background:rgba(127,127,127,.12);border:1px solid var(--border);padding:2px 8px;border-radius:var(--r-pill)}
.auto-catgrp{margin:0 0 18px}
.auto-catlbl{display:flex;align-items:center;gap:8px;font-weight:700;font-size:var(--fs-base);margin:0 0 10px;color:var(--txt)}
.auto-catlbl svg{width:18px;height:18px;flex-shrink:0;color:var(--accent,#e8004f)}
.auto-grid{display:grid;grid-template-columns:1fr;gap:12px}
@media(min-width:760px){ .auto-grid{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))} }
.auto-grid .auto-card{margin-bottom:0;display:flex;flex-direction:column}
.auto-grid .auto-card .auto-foot{margin-top:auto}

/* ============================================================
   KLIENCI (CRM) — jeden ekran: kto ile płaci, co ma włączone, co wisi.
   Klienci pogrupowani po TAGU, każdy jako rozwijana karta z ramką.
   ============================================================ */
.crm-bar{display:flex;flex-wrap:wrap;gap:var(--sp-2);align-items:center;margin:0 0 var(--sp-4)}
.crm-bar input[type=search]{flex:1 1 220px;min-width:180px;margin:0;width:auto}
/* Filtr tagów — „pigułki". aria-pressed niesie stan dla czytnika, klasa .on dla oka. */
.crm-tag{flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;padding:7px 13px;border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--border);color:var(--muted);cursor:pointer;
  font-family:var(--sans);font-size:var(--fs-sm);font-weight:600;
  transition:background var(--dur-base),border-color var(--dur-base),color var(--dur-base),transform var(--dur-fast)}
.crm-tag:hover{color:var(--txt);border-color:var(--accent-2);background:var(--accent-soft)}
.crm-tag:active{transform:scale(.97)}
.crm-tag:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
.crm-tag.on{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:var(--inset-hi),var(--glow)}
.crm-tag .n{font-family:var(--mono);font-size:var(--fs-2xs);opacity:.75}
/* Nagłówek grupy (tag) — wyraźna kreska, żeby grupy nie zlewały się ze sobą */
.crm-group{margin:0 0 var(--sp-6)}
.crm-group-head{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin:0 0 var(--sp-3);
  padding-bottom:var(--sp-2);border-bottom:1px solid var(--border-2)}
.crm-group-head h3{margin:0;font-size:var(--fs-md);font-weight:700;letter-spacing:-.2px}
.crm-group-head .crm-gmeta{margin-left:auto;font-family:var(--mono);font-size:var(--fs-2xs);color:var(--faint);letter-spacing:.4px}
/* Karta klienta */
.crm-client{border:1px solid var(--border);border-radius:var(--r-card);background:var(--surface);
  margin:0 0 var(--sp-3);overflow:hidden;transition:border-color var(--dur-base),box-shadow var(--dur-base)}
.crm-client:hover{border-color:var(--border-2);box-shadow:var(--shadow)}
.crm-client.open{border-color:var(--edge);box-shadow:var(--inset-hi),var(--shadow)}
.crm-client.blocked{border-left:3px solid var(--danger)}
/* Nagłówek = przycisk rozwijania (cały pasek klikalny, dostępny z klawiatury) */
.crm-head{display:flex;align-items:center;gap:var(--sp-3);width:100%;padding:var(--sp-3) var(--sp-4);
  background:none;border:none;cursor:pointer;text-align:left;color:var(--txt);font-family:var(--sans);
  transition:background var(--dur-base)}
.crm-head:hover{background:var(--accent-soft)}
.crm-head:focus-visible{outline:3px solid var(--accent-soft);outline-offset:-3px}
.crm-chev{flex:0 0 auto;width:16px;height:16px;color:var(--muted);transition:transform var(--dur-base)}
.crm-client.open .crm-chev{transform:rotate(90deg);color:var(--accent)}
/* kolumna, bo to <span>-y w przycisku — bez tego nazwa i e-mail lecą w jednej linii */
.crm-who{min-width:0;flex:1 1 220px;display:flex;flex-direction:column;align-items:flex-start;gap:2px}
.crm-name{font-weight:700;font-size:var(--fs-base);overflow-wrap:anywhere}
.crm-mail{font-size:var(--fs-2xs);color:var(--muted);font-family:var(--mono);overflow-wrap:anywhere}
/* Liczniki w nagłówku: MRR + co ma włączone + co wisi */
.crm-nums{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-left:auto}
.crm-num{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:var(--r-pill);
  background:rgba(127,127,127,.12);border:1px solid var(--border);font-size:var(--fs-2xs);
  font-family:var(--mono);color:var(--muted);white-space:nowrap}
.crm-num b{font-weight:700;color:var(--txt)}
.crm-num.mrr{background:var(--ok-bg);border-color:transparent;color:var(--ok)}
.crm-num.mrr b{color:var(--ok)}
.crm-num.due{background:var(--danger-bg);border-color:transparent;color:var(--danger)}
.crm-num.due b{color:var(--danger)}
/* Rozwinięcie */
.crm-body{padding:0 var(--sp-4) var(--sp-4);border-top:1px solid var(--border)}
.crm-cols{display:grid;grid-template-columns:1fr;gap:var(--sp-4);margin-top:var(--sp-4)}
@media(min-width:860px){ .crm-cols{grid-template-columns:1fr 1fr} }
.crm-col h4{margin:0 0 var(--sp-2);font-size:var(--fs-2xs);font-family:var(--mono);text-transform:uppercase;
  letter-spacing:.6px;color:var(--faint);font-weight:500;
  display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
/* Skrót do sekcji, która daną rzecz załatwia — dosunięty do prawej krawędzi nagłówka bloku. */
.crm-col-acts{margin-left:auto}
/* ------------------------------------------------------------
   ZAKŁADKI W ROZWINIĘTEJ KARCIE KLIENTA  (2026-08-09)
   Karta pokazywała sześć kolumn naraz; teraz jeden z trzech widoków: co klient przysłał /
   pieniądze / co ma włączone. To zwykłe przełączniki (aria-pressed), a nie role="tab" —
   w sekcji potrafi być kilkanaście rozwiniętych kart, a kilkanaście tablist z własną
   nawigacją strzałkami byłoby dla czytnika ekranu gorsze niż uczciwa grupa przycisków.
   ------------------------------------------------------------ */
.crm-tabs{display:flex;flex-wrap:wrap;gap:var(--sp-1);margin:var(--sp-4) 0 0;padding:4px;
  border-radius:var(--r-ctrl);background:rgba(127,127,127,.08)}
.crm-tab{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;
  border:1px solid transparent;border-radius:var(--r-ctrl);background:none;cursor:pointer;
  color:var(--muted);font-family:var(--sans);font-size:var(--fs-sm);font-weight:600;
  transition:background var(--dur-base),color var(--dur-base),border-color var(--dur-base)}
.crm-tab:hover{color:var(--txt);background:var(--accent-soft)}
.crm-tab:focus-visible{outline:3px solid var(--accent-soft);outline-offset:-2px}
.crm-tab.on{color:var(--txt);background:var(--surface);border-color:var(--border);box-shadow:var(--shadow)}
.crm-tab .n{font-family:var(--mono);font-size:var(--fs-2xs);padding:1px 7px;border-radius:var(--r-pill);
  background:rgba(127,127,127,.16);color:var(--muted)}
.crm-tab.on .n{background:var(--accent);color:#fff}
/* Lista „od klienta" — kilka najnowszych pozycji plus przejście dalej, a nie kopia sekcji. */
.crm-feed{display:flex;flex-direction:column;gap:var(--sp-2)}
.cf{padding:var(--sp-2) var(--sp-3);border:1px solid var(--border);border-radius:var(--r-ctrl);
  background:rgba(127,127,127,.05)}
/* `.od` = pozycja OD KLIENTA, czyli ta, która jest robotą. Kolor nie niesie sensu sam:
   obok stoi podpis „klient" / „wgrał klient" i status pozycji. */
.cf.od{border-left:3px solid var(--accent)}
.cf-b{font-size:var(--fs-sm);color:var(--txt);overflow-wrap:anywhere}
.cf-m{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap;margin-top:5px;
  font-size:var(--fs-2xs);color:var(--faint);font-family:var(--mono)}
.crm-acts{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin-top:var(--sp-4);padding-top:var(--sp-3);border-top:1px solid var(--border)}
.crm-note{margin:var(--sp-3) 0 0;padding:var(--sp-3);border-radius:var(--r-ctrl);background:var(--surface);
  border:1px solid var(--border);font-size:var(--fs-sm);color:var(--muted);white-space:pre-wrap;overflow-wrap:anywhere}
.crm-tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:5px}
.crm-tags .t{font-family:var(--mono);font-size:var(--fs-2xs);padding:1px 8px;border-radius:var(--r-pill);
  background:var(--accent-soft);color:var(--accent-2);letter-spacing:.3px}

/* ============================================================
   KLIENCI I SPRZEDAŻ — jedna sekcja, trzy zakładki (hub)
   Zakładki to prawdziwy role="tablist" (strzałki, aria-selected), a nie linki —
   zmiana zakładki NIE przeładowuje danych, wszystko siedzi już w pamięci.
   ============================================================ */
.hub-tabs{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0 0 var(--sp-4);
  padding-bottom:var(--sp-2);border-bottom:1px solid var(--border-2)}
.hub-tab{display:inline-flex;align-items:center;gap:7px;padding:9px 16px;
  background:none;border:1px solid transparent;border-bottom:2px solid transparent;
  color:var(--muted);cursor:pointer;font-family:var(--sans);font-size:var(--fs-base);font-weight:600;
  transition:color var(--dur-base),background var(--dur-base),border-color var(--dur-base)}
.hub-tab:hover{color:var(--txt);background:var(--accent-soft)}
.hub-tab:focus-visible{outline:3px solid var(--accent-soft);outline-offset:-2px}
.hub-tab.on{color:var(--txt);border-bottom-color:var(--accent)}
.hub-tab .badge{background:rgba(127,127,127,.16);color:var(--muted);font-family:var(--mono);
  font-size:var(--fs-2xs);padding:1px 7px;border-radius:var(--r-pill);min-width:0}
.hub-tab.on .badge{background:var(--accent);color:#fff}
.hub-panel:focus-visible{outline:3px solid var(--accent-soft);outline-offset:4px}
/* Podsumowanie listy (aria-live) — to ono mówi czytnikowi, ile pozycji zostało po filtrze */
.hub-sum{margin:0 0 var(--sp-3);font-size:var(--fs-sm);color:var(--muted)}
.hub-sum b{color:var(--txt);font-weight:700}
/* Etykieta przed rzędem „pigułek", żeby filtr nie był bezimienny */
.crm-bar-lbl{font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.05em;color:var(--faint);
  font-weight:600;margin-right:2px}
/* Czerwona pigułka = coś wymaga reakcji (zaległości). Sam kolor nie niesie sensu — obok jest liczba. */
.crm-tag.alarm{border-color:var(--danger);color:var(--danger)}
.crm-tag.alarm.on{background:var(--danger);border-color:var(--danger);color:#fff}
/* Pusty filtr: widać, że kryterium istnieje i ma zero trafień, ale nie da się w niego wejść. */
.crm-tag:disabled{opacity:.45;cursor:default;pointer-events:none}
/* Nazwa metryki w pigułce nagłówka karty — wcześniej sens siedział tylko w title= */
.crm-num .k{color:inherit;opacity:.8;font-size:var(--fs-2xs)}

/* ============================================================
   „CZEKA NA CIEBIE" — PODŚWIETLENIE MIEJSCA KLIENTA  (2026-08-09)
   Admin czyta tę listę kilkanaście razy dziennie, żeby sprawdzić, czy ktoś czegoś nie
   dorzucił. Podświetlenie ma odpowiadać na to pytanie z odległości ramienia, zanim
   ktokolwiek zacznie czytać nazwiska.

   KOLOR NIE JEST JEDYNYM NOŚNIKIEM SENSU (WCAG 1.4.1): przy każdym podświetleniu jest
   plakietka z liczbą i nazwą sygnału, a „czeka 5 dni" mówi wprost, o co chodzi. Osoba,
   która nie rozróżnia czerwieni od różu, traci wyłącznie stopniowanie pilności.

   STOPNIOWANIE PO CZASIE, NIE PO ILOŚCI: akcent = jest robota, czerwień = najstarsza
   sprawa czeka ≥ 3 dni. Trzy rzeczy dorzucone przed chwilą są głośniejsze, ale mniej
   pilne niż jedna sprzed tygodnia.

   BEZ ANIMACJI. Migająca lista, na którą patrzy się kilkanaście razy dziennie, uczy
   ignorowania — a to dokładne przeciwieństwo celu.
   ============================================================ */
.crm-client.uwaga{border-left:3px solid var(--accent);background:linear-gradient(90deg,var(--accent-soft),transparent 38%)}
.crm-client.uwaga.pilne{border-left-color:var(--danger)}
/* Zablokowane konto zostaje czerwoną krawędzią — blokada jest ważniejsza niż kolejka roboty. */
.crm-client.blocked.uwaga{border-left-color:var(--danger)}
.crm-num.uwaga{background:var(--accent-soft);border-color:transparent;color:var(--accent-2);font-weight:700}
.crm-num.uwaga b{color:var(--accent-2)}
/* „Czeka u klienta" celowo szare: to informacja, nie zadanie — nie ma tu nic do kliknięcia. */
.crm-num.czeka{background:rgba(127,127,127,.12);border-color:var(--border);color:var(--muted)}
/* Pasek sygnałów pod nagłówkiem karty (rodzeństwo <button>, nie jego dziecko) */
.crm-uwaga{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);
  padding:0 var(--sp-4) var(--sp-3);margin-top:calc(-1 * var(--sp-1))}
.uw-od{font-family:var(--mono);font-size:var(--fs-2xs);color:var(--muted);white-space:nowrap}
.uw-od.pilne{color:var(--danger);font-weight:700}
.uw-chip{display:inline-flex;align-items:stretch;border:1px solid var(--edge);border-radius:var(--r-pill);
  background:var(--accent-soft);overflow:hidden;max-width:100%}
.uw-chip.u-klienta{border-color:var(--border);background:transparent}
.uw-go{border:none;background:none;cursor:pointer;font-family:var(--sans);font-size:var(--fs-2xs);
  color:var(--accent-2);padding:4px 11px;min-width:0;overflow-wrap:anywhere;text-align:left;
  transition:background var(--dur-base)}
.uw-chip.u-klienta .uw-go{color:var(--muted)}
.uw-go b{font-family:var(--mono);font-weight:700;margin-left:4px}
.uw-go:hover{background:var(--accent-soft)}
.uw-go:focus-visible,.uw-seen:focus-visible{outline:3px solid var(--accent-soft);outline-offset:-2px}
/* „Widziane" tylko dla plików i komentarzy — jedynych sygnałów bez stanu obsłużenia w bazie */
.uw-seen{border:none;border-left:1px solid var(--edge);background:none;cursor:pointer;
  color:var(--muted);font-size:var(--fs-2xs);padding:4px 9px;transition:background var(--dur-base),color var(--dur-base)}
.uw-seen:hover{background:var(--ok-bg);color:var(--ok)}
/* ============================================================
   SKRZYNKA SPRAW (pulpit) — jeden wiersz = jeden CZŁOWIEK, który czeka.
   Te same plakietki co na karcie klienta (.uw-chip), więc wygląd sygnału jest
   wszędzie identyczny — uczy się go raz. Wiersz nie ma własnego tła: czerwona
   krawędź zapala się dopiero po 3 dniach, żeby lista ośmiu spraw nie była
   ścianą alarmu. Kolejność ustala CZAS, nie liczba spraw.
   ============================================================ */
.skrz-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-3);
  padding:var(--sp-3);border-left:3px solid var(--edge);border-bottom:1px solid var(--border)}
.skrz-row:last-child{border-bottom:none}
.skrz-row.pilne{border-left-color:var(--danger);background:var(--danger-bg)}
/* Nazwisko nad adresem: przy kilkunastu klientach po samym e-mailu się nie nawiguje. */
.skrz-who{display:flex;flex-direction:column;gap:2px;border:none;background:none;cursor:pointer;
  padding:2px 0;text-align:left;min-width:0;flex:1 1 180px}
.skrz-who .n{font-family:var(--sans);font-size:var(--fs-base);font-weight:700;color:var(--txt);
  overflow-wrap:anywhere;transition:color var(--dur-base)}
.skrz-who .m{font-family:var(--mono);font-size:var(--fs-2xs);color:var(--faint);overflow-wrap:anywhere}
.skrz-who:hover .n{color:var(--accent-2)}
.skrz-who:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
/* Plakietki na prawo — czytamy „kto → od kiedy → co", a nie odwrotnie. */
.skrz-chips{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);margin-left:auto}
@media (max-width:640px){
  .skrz-chips{margin-left:0;width:100%}
  .skrz-who{flex:1 1 100%}
}
/* Pastylka w menu: ilu klientów czeka na reakcję. Wypełniona, bo ma wygrywać z liczbami obok. */
.badge.uwaga{background:var(--accent-btn);color:#fff;text-transform:none;letter-spacing:0}
/* Formularz chowany pod <details> — dopisywanie faktury/abonamentu bez zmiany ekranu */
.hub-form{margin:var(--sp-4) 0 0;border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.hub-form>summary{list-style:none;cursor:pointer;padding:11px 14px;font-weight:700;font-size:var(--fs-base);
  display:flex;align-items:center;gap:8px;color:var(--txt)}
.hub-form>summary::-webkit-details-marker{display:none}
.hub-form>summary::after{content:"▾";margin-left:auto;color:var(--accent);transition:transform .2s var(--ww-ease)}
.hub-form[open]>summary::after{transform:rotate(180deg)}
.hub-form>summary:hover{background:var(--accent-soft)}
.hub-form>summary:focus-visible{outline:3px solid var(--accent-soft);outline-offset:-3px}
.hub-form-b{padding:0 14px 14px;border-top:1px solid var(--border)}
.hub-form-b>*:first-child{margin-top:var(--sp-3)}
/* Blok podrzędny w zakładce (np. Abonamenty pod fakturami) */
.hub-sub{margin:var(--sp-6) 0 0;padding-top:var(--sp-5);border-top:1px solid var(--border-2)}
.hub-sub-h{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin:0 0 var(--sp-2)}
.hub-sub-h h3{margin:0;font-size:var(--fs-md);font-weight:700;letter-spacing:-.2px}
.hub-sub-h .btn{margin-left:auto}
/* Odnośnik-przycisk w tabeli („skocz do klienta") — wygląda jak link, jest przyciskiem */
.lnk{background:none;border:none;padding:0;margin:0;font-family:inherit;font-size:inherit;
  color:var(--accent-2);font-weight:600;cursor:pointer;text-align:left;overflow-wrap:anywhere;
  border-bottom:1px dotted currentColor}
.lnk:hover{color:var(--accent)}
.lnk:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}

/* Nagłówek grupy w katalogu „Co mogę domówić" (panel klienta). Katalog jest JEDNĄ listą,
   ale wewnątrz dzieli się na automatyzacje i usługi — bez nagłówka z licznikiem po
   przefiltrowaniu nie wiadomo, czy pusto jest wszędzie, czy tylko w jednej grupie. */
.wsp-kind-h{display:flex;align-items:center;gap:var(--sp-2);margin:var(--sp-5) 0 var(--sp-2);
  font-size:var(--fs-base);font-weight:700;letter-spacing:-.2px;color:var(--txt)}
.wsp-kind-h:first-child{margin-top:0}
.wsp-kind-h .n{font-family:var(--mono);font-size:var(--fs-2xs);font-weight:700;color:var(--muted);
  border:1px solid var(--border);padding:1px 6px;border-radius:var(--r-pill)}

/* ============================================================
   FUNKCJE U KLIENTA (automatyzacje / usługi) — pozycja jako karta z ramką
   Używane w CRM i w sekcjach Automatyzacje / Portfel usług.
   ============================================================ */
.fn-list{display:grid;gap:var(--sp-2)}
.fn{display:flex;align-items:flex-start;gap:var(--sp-3);padding:var(--sp-3);border:1px solid var(--border);
  border-radius:var(--r-sm);background:var(--surface);transition:border-color var(--dur-base),background var(--dur-base)}
.fn:hover{border-color:var(--border-2);background:var(--accent-soft)}
.fn svg.fn-ic{width:16px;height:16px;flex:0 0 16px;margin-top:2px;color:var(--accent)}
.fn-main{min-width:0;flex:1}
.fn-name{font-weight:600;font-size:var(--fs-sm);overflow-wrap:anywhere}
.fn-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:5px}
.fn-sub{font-family:var(--mono);font-size:var(--fs-2xs);color:var(--ok);white-space:nowrap}
.fn-sub.off{color:var(--faint)}
/* Przyciski pozycji. `flex:0 0 auto` (do 2026-08-01) znaczyło „nie kurcz się" — grupa trzymała
   szerokość max-content, więc na telefonie wiersz „Kto zalega" z trzema akcjami wychodził
   63 px poza kartę i „↩︎ Cofnij zgłoszenie" było nie do kliknięcia. `0 1 auto` + min-width:0
   pozwala grupie się zwęzić, a wtedy `flex-wrap` faktycznie łamie przyciski na kolejne linie. */
.fn-acts{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px;flex:0 1 auto;min-width:0}
/* Wyłączona funkcja: przygaszona i w przerywanej ramce — widać, że to archiwum, nie usterka */
.fn.off{opacity:.62;border-style:dashed;background:var(--surface-2)}
.fn.off .fn-name{text-decoration:line-through;text-decoration-thickness:1px}
.fn.off svg.fn-ic{color:var(--faint)}
/* Wiersz tabeli z wyłączoną pozycją — przygaszony i w przerywanej ramce (jak .fn.off) */
tr.row-off td{opacity:.66;border-style:dashed;background:none}
tr.row-off:hover td{opacity:1}
/* Przełącznik „Pokaż wyłączone" — cała etykieta klikalna, więc musi wyglądać na klikalną */
.chk-inline{display:inline-flex;align-items:center;gap:7px;padding:6px 11px;border:1px solid var(--border);
  border-radius:var(--r-ctrl);background:var(--surface);color:var(--muted);font-size:var(--fs-xs);
  white-space:nowrap;cursor:pointer;transition:color var(--dur-base),border-color var(--dur-base),background var(--dur-base)}
.chk-inline:hover{color:var(--txt);border-color:var(--accent-2);background:var(--accent-soft)}
.chk-inline:active{transform:scale(.98)}
.chk-inline:focus-within{outline:3px solid var(--accent-soft);outline-offset:2px}
.chk-inline input{margin:0;flex:0 0 auto}

/* ============================================================
   PAKIETY OPIEKI (brak / hosting / podstawowy / zaawansowany)
   Pakiet klient widzi w KILKU miejscach: pigułka w pasku górnym (każda zakładka),
   karta na Pulpicie, panel w Rozliczeniach oraz pasek nad katalogami usług
   i automatyzacji. Kolor bierze się ze STANU (opłacony / kończy się / wygasł),
   nie z nazwy pakietu — status jest tym, co klient musi zobaczyć pierwsze.
   ============================================================ */
.plan-chip{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border:1px solid var(--border);
  border-radius:var(--r-pill);background:var(--surface);color:var(--txt);font-size:var(--fs-xs);
  font-weight:600;white-space:nowrap;cursor:pointer;line-height:1.2;
  transition:border-color var(--dur-base),background var(--dur-base),color var(--dur-base)}
.plan-chip:hover{border-color:var(--accent-2);background:var(--accent-soft)}
.plan-chip:active{transform:scale(.97)}
.plan-chip:focus-visible{outline:3px solid var(--accent-soft);outline-offset:2px}
.plan-chip .pc-ico{font-size:14px;line-height:1}
.plan-chip .pc-dot{width:8px;height:8px;border-radius:50%;background:var(--muted);flex:0 0 8px}
.plan-chip.s-aktywny .pc-dot,.plan-chip.s-bezterminu .pc-dot{background:var(--st-ok)}
.plan-chip.s-wygasa .pc-dot{background:var(--st-warn)}
.plan-chip.s-wygasl .pc-dot{background:var(--danger)}
@media (max-width:900px){ .plan-chip{display:none} }

/* Karta pakietu — Pulpit i Rozliczenia używają tej samej, żeby klient widział to samo dwa razy. */
.plan-card{border:1px solid var(--border);border-left:4px solid var(--muted);border-radius:var(--r-card);
  background:var(--surface);padding:var(--sp-4) var(--sp-5);margin:0 0 var(--sp-4)}
.plan-card.s-aktywny,.plan-card.s-bezterminu{border-left-color:var(--st-ok)}
.plan-card.s-wygasa{border-left-color:var(--st-warn)}
.plan-card.s-wygasl{border-left-color:var(--danger)}
.plan-card-h{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.plan-card-ic{font-size:26px;line-height:1;flex:0 0 auto}
.plan-card-n{flex:1 1 220px;min-width:0}
.plan-card-n>b{display:block;font-size:var(--fs-lg);line-height:1.25;overflow-wrap:anywhere}
.plan-card-n>span{display:block;color:var(--muted);font-size:var(--fs-xs);margin-top:3px;line-height:1.5}
.plan-card-acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;flex:0 0 auto}
/* Siatka terminów: „opłacony do", „kolejna opłata", „cykl", „kwota" — cztery liczby, jeden rząd. */
.plan-facts{display:grid;gap:var(--sp-2);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));margin-top:var(--sp-4)}
.plan-fact{padding:var(--sp-3);border:1px solid var(--border);border-radius:var(--r-ctrl);background:var(--surface)}
.plan-fact>span{display:block;color:var(--muted);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.4px}
.plan-fact>b{display:block;font-size:var(--fs-base);margin-top:5px;font-family:var(--mono);overflow-wrap:anywhere}
.plan-fact.is-late>b{color:var(--danger)}
.plan-fact.is-soon>b{color:var(--st-warn)}
.plan-note{margin:var(--sp-3) 0 0;color:var(--muted);font-size:var(--fs-sm);line-height:1.55}

/* Licznik godzin z pakietu („3 z 10 h w tym miesiącu"). Pakiet obiecuje godziny pracy,
   więc klient musi widzieć, ile z nich zostało — inaczej dowiaduje się o tym dopiero
   z odmowy albo z dopłaty. Kolor zmienia się dopiero od 80%: wcześniej to zwykły stan. */
.plan-hours{margin-top:var(--sp-4);padding:var(--sp-3);border:1px solid var(--border);
  border-radius:var(--r-ctrl);background:var(--surface)}
.ph-top{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-2);flex-wrap:wrap}
.ph-top>span{color:var(--muted);font-size:var(--fs-2xs);text-transform:uppercase;letter-spacing:.4px}
.ph-top>b{font-family:var(--mono);font-size:var(--fs-base);white-space:nowrap}
.ph-track{height:8px;margin-top:8px;border-radius:var(--r-pill);background:var(--border);overflow:hidden}
.ph-fill{display:block;height:100%;border-radius:var(--r-pill);background:var(--st-ok);
  transition:width var(--ww-dur,.4s) var(--ww-ease,ease)}
.plan-hours.is-high .ph-fill{background:var(--st-warn)}
.plan-hours.is-over .ph-fill{background:var(--danger)}
.plan-hours.is-over{border-color:var(--danger)}
.ph-note{margin:var(--sp-2) 0 0;color:var(--muted);font-size:var(--fs-xs);line-height:1.55}

/* Lista wszystkich 4 pakietów (rozwijana) — klient ma wiedzieć, co jeszcze może mieć. */
.plan-list{display:grid;gap:var(--sp-2);margin-top:var(--sp-3)}
.plan-opt{display:flex;gap:var(--sp-3);padding:var(--sp-3);border:1px solid var(--border);
  border-radius:var(--r-ctrl);background:var(--surface)}
.plan-opt.is-mine{border-color:var(--st-ok);background:var(--ok-bg)}
.plan-opt-ic{font-size:18px;line-height:1;flex:0 0 auto}
.plan-opt-b{min-width:0}
.plan-opt-b>b{display:block;font-size:var(--fs-sm)}
.plan-opt-b>span{display:block;color:var(--muted);font-size:var(--fs-xs);margin-top:3px;line-height:1.5}

/* Pasek nad katalogiem automatyzacji/usług: „co masz bez dopłat w swoim pakiecie". */
.plan-strip{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--border);border-left:4px solid var(--muted);border-radius:var(--r-sm);
  background:var(--surface);margin:0 0 var(--sp-4);font-size:var(--fs-sm);line-height:1.55}
.plan-strip.has-free{border-left-color:var(--st-ok)}
.plan-strip b{white-space:nowrap}
.plan-strip .ps-txt{flex:1 1 260px;min-width:0;color:var(--muted)}

/* Znacznik na karcie katalogu: bez dopłat vs płatne dodatkowo. */
.plan-tag{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:var(--r-pill);
  font-size:var(--fs-2xs);font-weight:700;letter-spacing:.3px;white-space:nowrap;border:1px solid transparent}
.plan-tag.free{background:var(--ok-bg);color:var(--st-ok);border-color:color-mix(in srgb,var(--st-ok) 30%,transparent)}
.plan-tag.paid{background:rgba(127,127,127,.10);color:var(--muted);border-color:var(--border)}
/* Te same pigułki w panelu ADMINA niosą stan pakietu (nie cenę), stąd trzy dodatkowe warianty. */
.plan-tag.ok{background:var(--ok-bg);color:var(--st-ok);border-color:color-mix(in srgb,var(--st-ok) 30%,transparent)}
.plan-tag.soon{background:color-mix(in srgb,var(--st-warn) 14%,transparent);color:var(--st-warn);border-color:color-mix(in srgb,var(--st-warn) 34%,transparent)}
.plan-tag.late{background:var(--danger-bg);color:var(--danger);border-color:color-mix(in srgb,var(--danger) 34%,transparent)}
.plan-tag+.plan-tag{margin-left:4px}
.auto-card.in-plan{border-color:color-mix(in srgb,var(--st-ok) 45%,var(--border))}

/* ============================================================
   TYP DOKUMENTU I WIDOK „KTO ZALEGA" (admin)
   Pigułka typu stoi przy numerze i celowo jest STONOWANA: informuje, że to nie faktura,
   ale nie może przekrzykiwać statusu ani terminu, które decydują o działaniu.
   ============================================================ */
.doc-pill{display:inline-block;padding:1px 7px;border-radius:var(--r-pill);border:1px solid var(--border);
  background:rgba(127,127,127,.08);color:var(--muted);font-size:var(--fs-2xs);font-weight:700;
  letter-spacing:.2px;white-space:nowrap;vertical-align:middle}
/* Blok zaległości. Czerwona krawędź od lewej, bo to jedyna lista w sekcji, która woła o ruch;
   pojawia się TYLKO gdy ktoś zalega (renderInvLate chowa go razem z treścią). */
.late-box{margin:0 0 var(--sp-4);padding:var(--sp-3);border:1px solid color-mix(in srgb,var(--danger) 30%,var(--border));
  border-left:3px solid var(--danger);border-radius:var(--r-sm);background:var(--danger-bg)}
.late-h{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin-bottom:var(--sp-3);font-size:var(--fs-sm)}
.late-h>span{color:var(--muted);font-size:var(--fs-xs)}
/* Wiersze w środku leżą na tle alertu — dajemy im własne, nieprzezroczyste tło,
   inaczej czerwień prześwitywałaby przez .fn i zlewała kwoty z tłem. */
.late-box .fn{background:var(--surface)}

/* ============================================================
   STANY KLIKANIA — HOVER / WCIŚNIĘTY / WYBRANY (cały panel)
   Trzy stany, trzy różne pytania użytkownika: „czy to klikalne?" (hover),
   „czy kliknięcie zadziałało?" (:active) i „co jest teraz wybrane?" (.is-open).
   Brakowało ich w kilkunastu miejscach — klik wyglądał jak brak reakcji.
   ============================================================ */

/* 1. Podświetlenie wybranego przycisku w JASNYM motywie.
   `html.html-light-mode .btn.ghost` ma WYŻSZĄ swoistość niż `.btn.ghost.is-open`,
   więc bez tej reguły aktywny przycisk w jasnym motywie tracił wypełnienie i został sam kontur. */
html.html-light-mode .btn.ghost.is-open{background:var(--accent);border-color:var(--accent);color:#fff}
html.html-light-mode .btn.ghost.is-open:hover{background:var(--accent-2,#c2003f);border-color:var(--accent-2,#c2003f);color:#fff}

/* 2. Hover tam, gdzie go nie było */
.menu-btn,.vt-nav{transition:border-color var(--ww-dur) var(--ww-ease),color var(--ww-dur) var(--ww-ease),transform var(--dur-base) var(--ww-ease)}
.menu-btn:hover,.vt-nav:hover{border-color:var(--accent-2);color:var(--accent-2)}
.cmdk-item{transition:background var(--dur-base) var(--ww-ease)}
.cmdk-item:hover{background:rgba(255,0,92,.08)}
.chip button:hover{filter:brightness(1.3)}
.stars span:hover{color:#ffb020}          /* podgląd oceny pod kursorem, zanim klikniesz */
.pay-on:hover{color:var(--accent-2)}

/* 3. Wciśnięcie. Trzy języki, bo trzy rodzaje elementów:
   klawisze się „ugniatają", ikonki kurczą, a wiersze i linki tylko przygasają (bez skoku układu). */
.side-logo:active,.side-close:active,.side-more:active,.menu-btn:active,.btn-google:active,
.vt-nav:active,.pw-toggle:active,.ww-theme-tgl:active,.pv-drop:active,.ai-title-opt:active,
.hub-tab:active,.ah-vid-btn:active,.vid-card:active,.crm-head:active,.bill-pay-c:active{transform:translateY(1px)}
.chip button:active,.toast-x:active,.ed-x:active,.ai-x:active,.canned-x:active,.stars span:active{transform:scale(.88)}
.cmdk-item:active,.pay-on:active,.lnk:active,
.auth-about-m summary:active,.ed-note summary:active,.att-done summary:active,.agr-proof summary:active,
.arch-box summary:active,.sec-help summary:active,.hub-form>summary:active,
.bill-qr>summary:active,.bill-claim>summary:active{opacity:.72}

@media (prefers-reduced-motion:reduce){
  .side-logo:active,.side-close:active,.side-more:active,.menu-btn:active,.btn-google:active,
  .vt-nav:active,.pw-toggle:active,.ww-theme-tgl:active,.pv-drop:active,.ai-title-opt:active,
  .hub-tab:active,.ah-vid-btn:active,.vid-card:active,.crm-head:active,.bill-pay-c:active,
  .chip button:active,.toast-x:active,.ed-x:active,.ai-x:active,.canned-x:active,.stars span:active{transform:none!important}
}

/* ============================================================
   DOWIEZIENIE DO ODSŁONIĘTEJ TREŚCI  (2026-08-05)
   Klik w przycisk często dokleja treść pod spodem albo w innym miejscu
   widoku. Na dłuższych ekranach lądowała poza polem widzenia i wyglądało
   to jak „nic się nie stało" — użytkownik nie wiedział, gdzie patrzeć.
   Logika siedzi w `ujawnij()` w js/panel-konto.js i js/panel-admin.js.
   ============================================================ */

/* Cel przewijania nie może wjechać pod PRZYKLEJONY pasek górny (.topbar).
   Klasa nic nie maluje — zostaje na elemencie na stałe. */
.ww-cel{scroll-margin-top:calc(var(--topbar-h) + 14px);scroll-margin-bottom:24px}

/* Ramka „patrz tutaj". Trzy decyzje, każda z powodu:
   1. `outline`, nie `border` — nie zmienia układu; dołożona ramka przesunęłaby
      treść o 2 px i to by mrugnęło przy każdym otwarciu.
   2. `outline-offset` UJEMNY — ramka rysuje się WEWNĄTRZ elementu. Na zewnątrz
      potrafi ją przyciąć rodzic z overflow:hidden, a przy elementach na pełną
      szerokość dokłada się do obszaru przewijania i robi poziomy pasek.
   3. Bez cienia i poświaty — sama ramka wystarcza, a kolorowa łuna na ciemnym
      tle to wyłącznie ozdoba, nie informacja. */
@keyframes ww-blysk{
  0%       {outline-color:transparent}
  10%,62%  {outline-color:var(--accent)}
  100%     {outline-color:transparent}
}
.ww-blysk{outline:2px solid transparent;outline-offset:-2px;animation:ww-blysk 1.5s var(--ww-ease) both}

/* Bez animacji ramka ZOSTAJE — to ona niesie informację „tu patrz", nie ruch.
   Gasi ją i tak zdejmowanie klasy w JS po tym samym czasie. */
@media (prefers-reduced-motion:reduce){
  .ww-blysk{animation:none;outline-color:var(--accent)}
}

/* ============================================================
   PASEK KOPII ROBOCZEJ  (2026-08)
   „Masz niedokończone zgłoszenie sprzed 5 min" nad pustym formularzem.
   Logika: SZKICE w js/panel-konto.js.

   To OFERTA, nie ostrzeżenie — dlatego neutralne tło i szara ramka, a nie
   czerwień. Klient niczego nie zepsuł; panel po prostu zapamiętał jego pracę.
   Kolor rezerwujemy dla rzeczy, które wymagają reakcji.
   ============================================================ */
.ww-szkic{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 14px;padding:10px 12px;
  border:1px solid var(--border);border-radius:var(--r-ctrl);
  background:color-mix(in srgb, var(--accent) 5%, transparent);
}
.ww-szkic-ic{font-size:16px;line-height:1;flex:0 0 auto}
/* Fragment treści bywa długi — to on musi się kurczyć, nie przyciski. */
.ww-szkic-t{flex:1 1 220px;min-width:0;display:flex;flex-direction:column;gap:2px}
.ww-szkic-t b{font-size:var(--fs-sm);font-weight:600}
.ww-szkic-t span{
  font-size:var(--fs-xs);color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Na telefonie przyciski schodzą pod tekst i biorą pół szerokości każdy —
   inaczej „Przywróć" i „Odrzuć" ściskają się do dwóch nieklikalnych pastylek. */
@media (max-width:520px){
  .ww-szkic-t{flex:1 1 100%}
  .ww-szkic [data-szkic]{flex:1 1 0}
}

/* ============================================================
   „OD TWOJEJ OSTATNIEJ WIZYTY"  (2026-08)
   Karta pulpitu z tym, co przybyło od poprzedniego wejścia.
   Logika: wizytaOtworz()/renderDashChanges() w js/panel-konto.js.

   To relacja z tego, co się wydarzyło — nie lista zadań. Dlatego bez czerwieni
   i bez odznak alarmowych: pilność mówi sekcja „Do zrobienia" niżej, a ta karta
   ma być przeczytana i zamknięta. Nagłówek i przycisk „Wiem, dziękuję" w jednej
   linii, żeby wyjście było widoczne od razu, a nie po przewinięciu listy.
   ============================================================ */
.ww-zmiany .zm-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 4px}
.ww-zmiany .zm-head h2{font-size:15px;margin:0;flex:1 1 auto}
.zm-row{
  display:flex;align-items:center;gap:10px;
  padding:8px 0;border-top:1px solid var(--border);
}
.zm-ic{font-size:16px;line-height:1;flex:0 0 auto}
/* Tytuł zdarzenia bywa długi — kurczy się on, nie przycisk „Zobacz". */
.zm-t{flex:1 1 auto;min-width:0;font-size:var(--fs-sm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* „×3" to liczba powtórzeń tego samego zdarzenia — ma być czytelna, ale nie krzyczeć. */
.zm-n{font-size:var(--fs-xs);color:var(--muted);font-weight:700}
@media (max-width:520px){
  .ww-zmiany .zm-head h2{flex:1 1 100%}
  .zm-t{white-space:normal}
}
