/* base.css — Dobry Wstęp
   Reset + remap komponentów na KANON DESIGN SYSTEMU (S3b).
   Tokeny (kolory/typografia/geometria/ruch) żyją w `tokens.css` (importowany niżej) —
   base.css tylko JE KONSUMUJE. ZAKAZ hardkodowania kolorów/rozmiarów tutaj i w widokach:
   stylujemy WYŁĄCZNIE tokenami i komponentami (patrz sekcja „DESIGN SYSTEM — KOMPONENTY").
   ZAKAZ CIEMNYCH TEŁ (motyw jasny „papierowy briefing"). */

/* ---- Kanon tokenów (jedno źródło prawdy) ---- */
@import url("tokens.css");

/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.6;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* Nagłówki = szeryf display; elegancja przez ROZMIAR, nie grubość (waga 400–500). */
h1, h2, h3, h4 { font-family: var(--font-head); line-height: 1.15; font-weight: var(--fw-display); letter-spacing: var(--tracking-head); color: var(--color-text); }
h1 { font-size: clamp(2.25rem, 5vw, var(--fs-3xl)); }
h2 { font-size: clamp(1.75rem, 4vw, var(--fs-2xl)); }
h3 { font-size: var(--fs-lg); font-weight: var(--fw-display-med); letter-spacing: -.01em; }
h4 { font-size: var(--fs-base); font-weight: var(--fw-display-med); letter-spacing: -.01em; }
a { color: var(--color-accent); text-decoration: none; transition: color var(--dur-micro) var(--ease-micro); }
a:hover { text-decoration: underline; }
img { max-width: 100%; height: auto; display: block; }
ul { list-style: none; }

/* ---- Layout helpers ---- */
.container { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--sp-4); }
.section { padding: var(--sp-8) 0; }
.stack > * + * { margin-top: var(--sp-4); }
.center { text-align: center; }
.muted { color: var(--color-text-muted); }
.hidden { display: none !important; }

/* ---- Button ---- @dsButton
   Miękki prostokąt (radius-btn, NIE pill). Hover reaguje „całym ciałem"
   (transform + cień + jasność w JEDNEJ tranzycji — wzorzec landing-research). */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font-family: var(--font-body); font-size: 1rem; font-weight: var(--fw-ui-bold); line-height: 1.2;
  padding: var(--sp-3) var(--sp-5);
  border: var(--border-w) solid var(--color-border); border-radius: var(--radius-btn);
  cursor: pointer; text-decoration: none;
  transition: background var(--dur-micro) var(--ease-micro), border-color var(--dur-micro) var(--ease-micro),
              box-shadow var(--dur-micro) var(--ease-micro), transform var(--dur-micro) var(--ease-micro),
              filter var(--dur-micro) var(--ease-micro), opacity var(--dur-micro) var(--ease-micro);
  background: var(--color-surface); color: var(--color-text);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(0); }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Primary = terakota (akcja główna) */
.btn-primary { background: var(--color-accent); color: var(--color-accent-text); border-color: var(--color-accent); box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--color-accent-hover); border-color: var(--color-accent-hover); box-shadow: var(--shadow-md); transform: translateY(-1px); filter: saturate(1.02); }
/* Secondary = jasny „papier" z obrysem (np. „Zbyt mocne", „Podgląd planu") */
.btn-secondary { background: var(--color-surface); color: var(--color-text); border-color: var(--color-border-strong); }
.btn-secondary:hover { background: var(--color-bg-alt); border-color: var(--color-text-subtle); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
/* Ghost = bez wypełnienia */
.btn-ghost { background: transparent; border-color: var(--color-border); }
.btn-ghost:hover { background: var(--color-surface); border-color: var(--color-border-strong); }
.btn:disabled { opacity: .55; cursor: not-allowed; box-shadow: none; transform: none; }
.btn-block { width: 100%; }
/* Rząd zakładek-przycisków (auth: Logowanie/Rejestracja/Reset) — równe, zwężony padding,
   min-width:0 by mieściły się na 390px bez overflow (znalezisko krytyka R1). */
.auth-tabs { display: flex; gap: var(--sp-2); }
.auth-tabs .btn { flex: 1; min-width: 0; padding-left: var(--sp-3); padding-right: var(--sp-3); }

/* ---- Card ---- @dsCard
   Papierowa karta: biała powierzchnia na kremowym tle, ciepły warstwowy cień, radius 22px. */
.card {
  background: var(--color-surface);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-card);
  padding: var(--sp-5);
  box-shadow: var(--shadow-card);
}
.card-alt { background: var(--color-surface-alt); }
/* Karta interaktywna (klikalna) — hover unosi się „całym ciałem". */
.card-hover { transition: box-shadow var(--dur-micro) var(--ease-micro), transform var(--dur-micro) var(--ease-micro), border-color var(--dur-micro) var(--ease-micro); }
.card-hover:hover { box-shadow: var(--shadow-card-hover); transform: translateY(-2px); border-color: var(--color-border-strong); }

/* ---- Input / form ---- @dsField */
.field { display: block; margin-bottom: var(--sp-4); }
.field label { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); margin-bottom: var(--sp-2); color: var(--color-text); }
.field label .field-ico { color: var(--color-text-subtle); flex: none; }
.field-hint { display: block; font-size: var(--fs-xs); color: var(--color-text-subtle); margin-top: var(--sp-2); }
.input, select.input, textarea.input {
  width: 100%; font-family: var(--font-body); font-size: 1rem; line-height: 1.5;
  padding: var(--sp-3) var(--sp-4); color: var(--color-text); background: var(--color-bg-alt);
  border: var(--border-w) solid var(--color-border); border-radius: var(--radius-input);
  transition: border-color var(--dur-micro) var(--ease-micro), box-shadow var(--dur-micro) var(--ease-micro);
}
.input::placeholder { color: var(--color-text-subtle); }
.input:hover { border-color: var(--color-border-strong); }
.input:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-soft); }
/* Select z natywną strzałką zastąpioną chevronem (spójny z line-ikonami) */
select.input {
  appearance: none; -webkit-appearance: none; padding-right: var(--sp-7);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238A837A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--sp-4) center;
}

/* ---- Pole daty/godziny — @dsDateTime (UX-5: natywny datetime-local → dwa spójne pola DS)
   Ładny wrapper z ikoną wiodącą; natywny picker zostaje (klik w całe pole), ale rama/typografia = DS. */
.dt-field { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.dt-part { position: relative; display: flex; align-items: center; flex: 1 1 160px; min-width: 0;
  background: var(--color-bg-alt); border: var(--border-w) solid var(--color-border); border-radius: var(--radius-input);
  padding-left: var(--sp-4); transition: border-color var(--dur-micro) var(--ease-micro), box-shadow var(--dur-micro) var(--ease-micro); }
.dt-part > svg { flex: none; color: var(--color-text-subtle); }
.dt-part:hover { border-color: var(--color-border-strong); }
.dt-part:focus-within { border-color: var(--color-accent); box-shadow: 0 0 0 3px var(--color-accent-soft); }
.dt-input { width: 100%; font-family: var(--font-body); font-size: 1rem; line-height: 1.5; color: var(--color-text);
  background: transparent; border: 0; outline: none; padding: var(--sp-3) var(--sp-4) var(--sp-3) var(--sp-2); }
/* Natywny glif pickera rozciągnięty na CAŁE pole i niewidoczny — znika podwójna ikona kalendarza,
   a klik gdziekolwiek w polu otwiera natywny picker (zero JS, wygląd w pełni DS — ikona wiodąca zostaje). */
.dt-input::-webkit-calendar-picker-indicator { position: absolute; inset: 0; width: auto; height: auto; margin: 0; padding: 0; opacity: 0; cursor: pointer; }

/* ---- Feedback message (auth/errors) ---- @dsMsg */
.msg { padding: var(--sp-3) var(--sp-4); border-radius: var(--radius); font-size: var(--fs-sm); border: var(--border-w) solid transparent; }
.msg-error   { background: var(--color-error-soft);   color: var(--color-error);   border-color: rgba(192, 57, 43, .22); }
.msg-success { background: var(--color-success-soft); color: #4E501F; border-color: rgba(110, 112, 56, .28); }
.msg-warning { background: #F7EFDC; color: var(--color-warning-text); border-color: rgba(181, 138, 46, .30); }

/* ---- Badge (lifecycle status) ---- */
.badge {
  display: inline-block; font-size: .75rem; font-weight: 600;
  padding: 2px var(--sp-2); border-radius: 999px; border: var(--border-w) solid var(--color-border);
}
/* Warianty statusu (np. dostarczalność maili w Wiadomościach): OK / oczekujący / błąd. */
.badge-ok     { border-color: var(--color-success); color: var(--color-success); }
.badge-warn   { border-color: var(--color-warning-text); color: var(--color-warning-text); }
.badge-danger { border-color: var(--color-error);   color: var(--color-error); }

/* ---- Top nav (app/admin) ---- */
.topnav {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: var(--border-w) solid var(--color-border);
  background: var(--color-bg);
}
.topnav .brand { font-weight: 700; font-family: var(--font-head); }
.topnav nav { display: flex; gap: var(--sp-4); align-items: center; }
/* Wąskie telefony (≤560px): nagłówek nie może rozpychać strony (poziomy scroll całej appki).
   Zawijamy pasek i skracamy e-mail usera z wielokropkiem zamiast wypychać „Wyloguj" poza ekran. */
@media (max-width: 560px) {
  .topnav { flex-wrap: wrap; row-gap: var(--sp-2); }
  .topnav nav { flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); min-width: 0; justify-content: flex-end; }
  .topnav nav #user-name { max-width: 42vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ---- Empty state ---- */
.empty {
  text-align: center; padding: var(--sp-8) var(--sp-4);
  border: var(--border-w) dashed var(--color-border); border-radius: var(--radius);
  color: var(--color-text-muted);
}

/* ---- Table (admin) ---- */
/* Afordancja przewijania poziomego (mobile): subtelny cień na krawędzi, gdy tabela ma więcej
   kolumn w poziomie niż widać (np. Historia wiadomości — kolumna Status po prawej). Cień znika po
   dosunięciu do końca dzięki background-attachment: local. Baza = --color-surface (białe karty,
   motyw light-only — bez wariantu dark). Wszystkie .table-wrap to białe .card (7 tabel panelu). */
.table-wrap {
  overflow-x: auto;
  background:
    linear-gradient(to right, var(--color-surface) 30%, transparent) 0 0 / 28px 100% no-repeat local,
    linear-gradient(to left, var(--color-surface) 30%, transparent) 100% 0 / 28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(31, 25, 15, 0.10), transparent) 0 0 / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(31, 25, 15, 0.10), transparent) 100% 0 / 12px 100% no-repeat scroll,
    var(--color-surface);
}
table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th, td { text-align: left; padding: var(--sp-3); border-bottom: var(--border-w) solid var(--color-border); }
th { font-weight: 600; color: var(--color-text-muted); }

/* ---- Grid ---- */
.grid { display: grid; gap: var(--sp-4); }
@media (min-width: 720px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

/* ---- Separator „albo" (OAuth ↔ formularz e-mail) ---- */
.or-sep { display: flex; align-items: center; gap: var(--sp-3); margin: 0 0 var(--sp-4); color: var(--color-text-muted); font-size: .8rem; }
.or-sep::before, .or-sep::after { content: ""; flex: 1; height: 1px; background: var(--color-border); }

/* ---- Baner trybu podglądu operatora (impersonation) — TRWAŁY, u góry, czerwony ---- */
.impersonation-banner {
  position: sticky; top: 0; z-index: var(--z-banner);
  background: var(--color-error); color: #fff;
  padding: var(--sp-2) var(--sp-4); text-align: center;
  font-size: .85rem; font-weight: 600;
}

/* ---- TRYB PRZERWY TECHNICZNEJ (maintenance mode, B10) — plansza + baner (maintenance.js) ----
   Plansza (mode 'app'): pełny ekran NAD wszystkim, user nie działa. Baner (mode 'admin'): sticky,
   panel operatora działa dalej. Landing (index.html) świadomie bez bramki. Wszystko na tokenach DS. */
.maintenance-locked { overflow: hidden; }
.maintenance-plane {
  position: fixed; inset: 0; z-index: var(--z-maintenance);
  display: flex; align-items: center; justify-content: center; padding: var(--sp-5);
  background: var(--color-bg);
}
.maintenance-box {
  max-width: 420px; width: 100%; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-4);
}
.maintenance-box .maintenance-brand { transform: scale(1.1); margin-bottom: var(--sp-2); }
.maintenance-ico { width: 44px; height: 44px; color: var(--color-accent); }
.maintenance-title { font-size: 1.5rem; }
.maintenance-sub { font-size: 1rem; margin: 0; }

.maintenance-banner {
  position: sticky; top: 0; z-index: var(--z-banner);
  display: flex; align-items: center; justify-content: center; gap: var(--sp-3); flex-wrap: wrap;
  background: var(--color-warning, #C08A16); color: #fff;
  padding: var(--sp-2) var(--sp-4); text-align: center;
  font-size: .85rem; font-weight: 600;
}
.maintenance-banner-link { color: #fff; text-decoration: underline; white-space: nowrap; }

/* ---- Zgoda (checkbox z linkami przy rejestracji) ---- */
.check-line { display: flex; gap: var(--sp-2); align-items: flex-start; font-size: .9rem; margin-bottom: var(--sp-4); }
.check-line input { margin-top: 3px; }

/* ---- Onboarding: wiersz kroku „Pierwsze kroki" (stack na wąskich telefonach) ----
   Forward-compatible (S27): gdy apka zbuduje POZIOMY wiersz kroku (.onb-step z przyciskiem .btn),
   poniżej 460px przycisk schodzi pod treść na całą szerokość zamiast się ściskać.
   Starter renderuje kroki jako listę .check-line (już pionowo) — reguła aktywuje się dopiero
   gdy apka doda .onb-step (jak Fachmat). Zero efektu dla obecnego #onboarding-card. */
@media (max-width: 460px) {
  .onb-step { flex-wrap: wrap; }
  .onb-step .btn { flex-basis: 100%; width: 100%; margin-top: var(--sp-2); }
}

/* ---- Przycisk destrukcyjny + strefa czerwona (usunięcie konta) ---- */
.btn-danger { background: var(--color-error); color: #fff; }
.btn-danger:hover { background: #a01f1f; }
.danger-zone { border-color: var(--color-error); }

/* ---- Overlay pełnoekranowy (subscription gating: past_due / canceled) ----
   UWAGA: to warstwa UX. Twardy gate = RLS/edge (patrz app.js requireActiveSub). */
.overlay {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  display: flex; align-items: center; justify-content: center; padding: var(--sp-4);
  background: var(--scrim-strong); backdrop-filter: blur(2px);
}
.overlay-box { max-width: 440px; text-align: center; background: var(--color-bg); }
/* Blokada scrolla tła pod nakładką onboardingu (S5). */
body.modal-open { overflow: hidden; }

/* ---- Pływający przycisk „Zgłoś uwagę" (feedback widget) ----
   Desktop (≥1024px): kompaktowa pigułka-ikona (52×52) bez etykiety — nie zasłania treści.
   Mobile: pełna pigułka z ikoną + etykietą (czytelny cel dotyku). */
.fab {
  position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: var(--z-fab);
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5); border-radius: 999px; border: none;
  background: var(--color-accent); color: var(--color-accent-text);
  font-weight: 600; cursor: pointer; box-shadow: var(--shadow-md);
  transition: transform var(--dur-base, .25s) var(--ease-out, ease), opacity var(--dur-base, .25s) ease;
}
.fab:hover { background: var(--color-accent-hover); }
/* KLASA BŁĘDU „FAB zakrywa wartości/treść" (S4b/S4d/S4e — 3× kolizja) → jedna GLOBALNA reguła:
   pływający FAB CHOWA SIĘ przy przewijaniu w dół (czytanie) i wraca przy przewijaniu w górę / u góry
   (js: toggle .fab-tucked wg kierunku scrolla — app.js initFabAutoHide). Dzięki temu NIGDY nie
   „siedzi" nad treścią, którą user właśnie czyta — działa na KAŻDYM ekranie (raport/fakty/symulacja). */
.fab.fab-tucked { transform: translateY(160%); opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .fab { transition: opacity .01ms; } }
.fab .fab-ico { flex: none; }
@media (min-width: 1024px) {
  .fab { width: 52px; height: 52px; padding: 0; justify-content: center; }
  .fab .fab-label { display: none; }
}
/* Wąskie telefony: FAB jako kompaktowe kółko (nie rozlewa się na treść — np. czat symulacji). .app-shell daje zapas na dole. */
@media (max-width: 560px) {
  .fab { width: 52px; height: 52px; padding: 0; justify-content: center; }
  .fab .fab-label { display: none; }
}

/* ---- Modal (feedback) ---- */
.modal-backdrop {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: flex; align-items: center; justify-content: center; padding: var(--sp-4);
  background: var(--scrim);
}
/* Paywall = modal wyboru planu OTWIERANY Z overlaya gatingu → MUSI być nad overlayem
   (canceled/past_due), inaczej plany są zasłonięte i user nie wznowi subskrypcji. */
.modal-backdrop.paywall { z-index: var(--z-paywall); }
.modal { width: 100%; max-width: 480px; background: var(--color-bg); }
.modal textarea.input { resize: vertical; }

/* ============================================================
   SHELL nawigacji w tabach — panel operatora (admin) + wejście operatora (app).
   Standard fabryki: kanoniczny topnav z zakładkami + hash-routing + menu mobilne.
   Reużywany przez admin.html (6 zakładek) i app.html (link „Panel operatora").
   Wszystko na tokenach; #fff = biel na grafitowym tle (jak reszta pliku, brak tokenu bieli).
   ============================================================ */

/* ---- Warianty przycisków używane w topnav ---- */
.btn-sm { padding: var(--sp-2) var(--sp-4); font-size: .85rem; }
.btn-neutral { background: var(--color-text); color: #fff; border-color: var(--color-text); }
.btn-neutral:hover { background: var(--color-text); opacity: .88; }

/* ---- Nagłówek widoku (tytuł zakładki) ---- */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-bottom: var(--sp-4); flex-wrap: wrap; }

/* ---- Plakietka „PANEL OPERATORA" (odróżnienie panelu od aplikacji) ---- */
.plaq {
  display: inline-flex; align-items: center; gap: var(--sp-2); flex: none;
  background: var(--color-text); color: #fff; border-radius: var(--radius);
  padding: var(--sp-1) var(--sp-3);
  font-weight: 700; font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
}
.plaq-op::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--color-accent); flex: none; }

/* ---- Zakładki topnav (hash-routing; aktywna = podkreślenie akcentu) ---- */
.navtabs { display: flex; gap: var(--sp-4); align-items: center; flex: 1; justify-content: center; }
.navtab {
  font-weight: 600; font-size: .9rem; color: var(--color-text-muted);
  padding: var(--sp-2) 0; border-bottom: 2px solid transparent; text-decoration: none;
  transition: color .2s, border-color .2s;
}
.navtab:hover { color: var(--color-text); text-decoration: none; }
.navtab-active { color: var(--color-text); border-bottom-color: var(--color-accent); }
/* Link „Panel operatora" w app (widoczny tylko dla operatora) — wyróżniony obrys-pigułka */
.navtab-op {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1.5px solid var(--color-text); border-radius: 999px;
  padding: 5px var(--sp-3); color: var(--color-text);
  transition: background .15s, color .15s;
}
.navtab-op:hover { background: var(--color-text); color: #fff; text-decoration: none; }
.navtab-op svg { flex: none; }

/* ---- CTA topnav (← Aplikacja) + przycisk MENU (mobile) ---- */
.nav-cta { flex: none; }
.nav-menu-mobile { display: none; flex: none; }

/* ---- Rozwijane menu (mobile ≤860px) — lista zakładek pod topnavem (vanilla) ---- */
.nav-menu-panel {
  display: flex; flex-direction: column; gap: 2px;
  background: var(--color-surface); border-bottom: var(--border-w) solid var(--color-border);
  box-shadow: var(--shadow-sm); padding: var(--sp-2);
}
.nav-menu-panel a {
  display: block; text-align: left; font-weight: 600; font-size: .95rem; color: var(--color-text);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius); text-decoration: none;
}
.nav-menu-panel a:hover { background: var(--color-bg); text-decoration: none; }
.nav-menu-panel a.navtab-active { color: var(--color-accent); }
.nav-menu-panel .nav-menu-op, .nav-menu-panel .nav-cta-m { color: var(--color-accent); }
.nav-menu-head { display: block; font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--color-text-muted); padding: var(--sp-2) var(--sp-4) var(--sp-1); }

/* ---- Pasek konta operatora (Pulpit): kto zalogowany + Wyloguj ---- */
.admin-userbar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-5); }

/* ---- Widok routera (pokazywanie/ukrywanie przez .hidden) ---- */
.view { animation: fade-in .18s ease-out; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ---- Fix overflow poziomy tabel na mobile ----
   Karty gridu (grid-3/grid-4) mają domyślnie min-width:auto → nie schodzą poniżej
   min-content i rozpychają viewport. Zerujemy min-width, a szerokie tabele scrollują
   REALNIE wewnątrz .table-wrap (overflow-x:auto) zamiast rozciągać stronę. */
.grid > * { min-width: 0; }
[data-view] .table-wrap { max-width: 100%; }

/* ---- Mobile ≤860px: topnav = brand + MENU; zakładki/CTA/plakietkę chowamy ----
   Breakpoint 860 (nie 720): desktopowy topnav (zakładki + CTA + plakietka) nie mieści się
   poniżej ~860px → w strefie 721–860px rozpychał viewport i dawał poziomy scroll (S27). */
@media (max-width: 860px) {
  .topnav .navtabs, .topnav .nav-cta, .topnav .plaq-op { display: none; }
  .nav-menu-mobile { display: inline-flex; }
}

/* ============================================================
   MODUŁ WIADOMOŚCI (panel operatora — tab „Wiadomości"): pod-zakładki, edytor szablonów,
   podgląd renderu w iframe. Wszystko na tokenach. */
.subtabs { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-5);
  border-bottom: var(--border-w) solid var(--color-border); }
.subtab {
  background: transparent; border: none; border-bottom: 2px solid transparent;
  padding: var(--sp-3) var(--sp-3); font-family: var(--font-body); font-size: .9rem; font-weight: 600;
  color: var(--color-text-muted); cursor: pointer; transition: color .15s, border-color .15s;
}
.subtab:hover { color: var(--color-text); }
.subtab-active { color: var(--color-text); border-bottom-color: var(--color-accent); }

/* Szablony: lista + edytor obok siebie (na wąskich = jedna kolumna). */
.msg-tpl-grid { display: grid; gap: var(--sp-4); grid-template-columns: 1fr; }
@media (min-width: 900px) { .msg-tpl-grid { grid-template-columns: 260px 1fr; align-items: start; } }
.msg-tpl-editor { display: block; }
#tpl-list li { list-style: none; }
.tpl-item {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  width: 100%; text-align: left; background: transparent; border: var(--border-w) solid transparent;
  border-radius: var(--radius); padding: var(--sp-2) var(--sp-3); cursor: pointer;
  font-family: var(--font-body); font-size: .9rem; color: var(--color-text);
}
.tpl-item:hover { background: var(--color-bg); }
.tpl-item-active { background: var(--color-bg); border-color: var(--color-border); font-weight: 600; }
.tpl-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--color-text-muted); }
.tpl-dot.on { background: var(--color-success); }
.tpl-dot.off { background: var(--color-warning); }

/* Podgląd renderu w izolowanym iframe (sandbox="" — brak skryptów, XSS-safe). */
.msg-preview-wrap { margin-top: var(--sp-4); }
.msg-preview {
  width: 100%; height: 420px; border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius); background: var(--color-bg-alt);
}

/* ============================================================
   MODUŁ POLECENIA — prompt aha (pasek), licznik, panel operatora. Wszystko na tokenach. */
.aha-ref {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  background: var(--color-surface); border: var(--border-w) solid var(--color-border);
  border-left: 3px solid var(--color-accent); border-radius: var(--radius);
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-5); box-shadow: var(--shadow-sm);
}
.aha-ref #aha-referral-text { flex: 1 1 220px; font-size: .95rem; color: var(--color-text); }
.aha-ref-close {
  background: transparent; border: none; color: var(--color-text-muted); cursor: pointer;
  font-size: 1.3rem; line-height: 1; padding: 0 var(--sp-1);
}
.aha-ref-close:hover { color: var(--color-text); }
.ref-stats { color: var(--color-text-muted); }
.ref-stats b { color: var(--color-text); }
.ref-stat-grid { display: grid; gap: var(--sp-3); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 720px) { .ref-stat-grid { grid-template-columns: repeat(5, 1fr); } }
.ref-stat { background: var(--color-surface); border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius); padding: var(--sp-3) var(--sp-4); }
.ref-stat .n { font-family: var(--font-head); font-size: 1.5rem; color: var(--color-text); }
.ref-stat .l { font-size: .8rem; color: var(--color-text-muted); }
.ref-chip { display: inline-block; padding: 2px var(--sp-2); border-radius: 999px;
  font-size: .78rem; font-weight: 600; border: var(--border-w) solid var(--color-border); }
.ref-chip.invited  { color: var(--color-text-muted); }
.ref-chip.paid     { color: var(--color-warning-text); border-color: var(--color-warning-text); }
.ref-chip.rewarded { color: var(--color-success); border-color: var(--color-success); }
.ref-chip.refunded, .ref-chip.rejected { color: var(--color-error); border-color: var(--color-error); }

/* ---- Druk (S31): przy Ctrl+P chowamy chrome aplikacji (nawigacja, akcje, warstwy nakładkowe),
   żeby na wydruku/PDF została wyłącznie treść. Uniwersalny podzbiór — TYLKO selektory, które
   starter faktycznie ma. Rozszerzaj per apka o własne elementy sticky/floating (paski sum,
   szybkie skoki, toasty), gdy je dodasz. */
@media print {
  .topnav,
  .nav-menu-panel,
  .nav-menu-mobile,
  .impersonation-banner,
  .fab,
  .aha-ref,
  .overlay,
  .modal-backdrop {
    display: none !important;
  }
}

/* ============================================================================
   DESIGN SYSTEM — KOMPONENTY NISZY „Dobry Wstęp" (S3b)
   Biblioteka wzorców z makiet sparingu. Podgląd: /dev/komponenty.html.
   Każdy blok oznaczony @ds<Nazwa>. Widoki (app/admin/landing) składają się
   WYŁĄCZNIE z tych klas + tokenów — ZERO stylowania ad hoc.
   ============================================================================ */

/* ---- Eyebrow (nadtytuł CAPS) — @dsEyebrow ---- */
.eyebrow {
  display: inline-block; font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-ui-bold);
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-success);
}
.eyebrow-pill {
  border: var(--border-w) solid var(--color-success); border-radius: var(--radius-pill);
  padding: var(--sp-2) var(--sp-4); background: transparent;
}

/* ---- Label CAPS (etykieta pola/sekcji) — @dsLabel ---- */
.label-caps { font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-ui-bold);
  letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-text-subtle); }

/* ---- Pill statusu — @dsPill (wzór makiet: oliwkowy „Gotowy do spotkania" z checkiem) ---- */
.pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); line-height: 1;
  padding: var(--sp-2) var(--sp-3); border-radius: var(--radius-pill);
  border: var(--border-w) solid transparent;
}
.pill .pill-ico { flex: none; }
.pill-ready   { background: var(--color-success-soft); color: #4E501F; border-color: rgba(110, 112, 56, .30); }
.pill-neutral { background: var(--color-chip-bg);      color: var(--color-text-muted); border-color: var(--color-border); }
.pill-accent  { background: var(--color-accent-soft);  color: #8F3A1E; border-color: rgba(183, 79, 38, .25); }
.pill-warn    { background: #F7EFDC;                    color: var(--color-warning-text); border-color: rgba(181, 138, 46, .30); }

/* ---- Numerowane kółko-krok — @dsStepNum (filary planu) ---- */
.step-num {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; border-radius: 50%;
  font-family: var(--font-ui); font-weight: var(--fw-ui-bold); font-size: var(--fs-sm);
  color: #fff; background: var(--color-accent);
}
.step-num-olive { background: var(--color-success); }
.step-num-sm { width: 26px; height: 26px; font-size: var(--fs-xs); }
.step-num-lg { width: 40px; height: 40px; font-size: var(--fs-base); }

/* ---- Okrągły żeton ikony (line-icon) — @dsIconChip ---- */
.icon-chip {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--color-chip-bg); color: var(--color-text-muted);
}
.icon-chip svg { width: 22px; height: 22px; }
.icon-chip-accent { background: var(--color-accent-soft); color: var(--color-accent); }
.icon-chip-olive  { background: var(--color-success-soft); color: var(--color-success); }

/* ---- Listy „rób / unikaj" — @dsList (oliwkowe kropki = amunicja, czerwone ✗ = miny) ---- */
.list-do, .list-avoid { list-style: none; display: flex; flex-direction: column; gap: var(--sp-3); }
.list-do li, .list-avoid li { position: relative; padding-left: var(--sp-6); color: var(--color-text); font-size: var(--fs-base); line-height: 1.5; }
.list-do li::before {
  content: ""; position: absolute; left: 6px; top: .55em; width: 8px; height: 8px;
  border-radius: 50%; background: var(--color-success);
}
.list-avoid li::before {
  content: "✗"; position: absolute; left: 2px; top: 0; color: var(--color-error);
  font-weight: 700; font-size: .95em; line-height: 1.5;
}

/* ---- Etykieta wiarygodności faktu — @dsFactLabel ---- */
.fact-label {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-ui); font-size: 11px; font-weight: var(--fw-ui-bold);
  letter-spacing: .06em; text-transform: uppercase;
  padding: 3px var(--sp-2); border-radius: var(--radius-pill); border: var(--border-w) solid transparent;
}
.fact-label::before { content: ""; width: 6px; height: 6px; border-radius: 50%; flex: none; background: currentColor; }
.fact-confirmed { color: #4E501F; background: var(--color-success-soft); border-color: rgba(110, 112, 56, .30); }
.fact-ai        { color: var(--color-text-muted); background: var(--color-chip-bg); border-color: var(--color-border); }
.fact-check     { color: var(--color-warning-text); background: #F7EFDC; border-color: rgba(181, 138, 46, .30); }

/* ---- Karta faktu researchu — @dsFactCard (żeton-ikona + treść + etykieta + źródło + akcje keep/discard;
   stany zatwierdzony/„zapytaj klienta"). UX-6: charakter filaru jak Plan/Raport — żeton w kółku + pillar. ---- */
.fact-card { display: block; border-left: 3px solid var(--color-border); }
.fact-card.is-approved { border-left-color: var(--color-success); background: var(--color-success-soft); }
.fact-card.is-ask { border-left-color: var(--color-warning-text); background: #F7EFDC; }
.fact-card > .pillar { align-items: flex-start; gap: var(--sp-4); }
.fact-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.fact-chip { width: 40px; height: 40px; }
.fact-chip svg { width: 20px; height: 20px; }
.icon-chip-warn { background: #F7EFDC; color: var(--color-warning-text); }
.fact-card .fact-content { color: var(--color-text); font-size: var(--fs-base); line-height: 1.5; margin: 0; }
.fact-meta { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.fact-source { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--color-text-subtle); word-break: break-word; }
.fact-badge { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-ui); font-size: 11px; font-weight: var(--fw-ui-bold); letter-spacing: .05em; text-transform: uppercase; }
.fact-badge.is-approved { color: var(--color-success); }
.fact-badge.is-ask { color: var(--color-warning-text); }
.fact-badge svg { flex: none; }
.fact-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }
.fact-edit-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }

/* Przyciski keep/discard faktu — @dsFactAct (wzór makieta dodatkowa.png: „Dodaj do planu / Zbyt mocne”).
   Domyślnie obrys; stan is-on = wypełnienie (oliwka = potwierdzone, piaskowy = zapytam klienta). */
.fact-act { display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 6px var(--sp-3);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med);
  color: var(--color-text-muted); background: var(--color-surface);
  border: var(--border-w) solid var(--color-border); border-radius: var(--radius-pill); cursor: pointer;
  transition: color var(--dur-micro) var(--ease-micro), background var(--dur-micro) var(--ease-micro), border-color var(--dur-micro) var(--ease-micro); }
.fact-act svg { flex: none; }
.fact-act:hover { color: var(--color-text); border-color: var(--color-border-strong); background: var(--color-chip-bg); }
.fact-act-keep:hover { color: #4E501F; border-color: rgba(110,112,56,.4); background: var(--color-success-soft); }
.fact-act-keep.is-on { color: #fff; background: var(--color-success); border-color: var(--color-success); }
.fact-act-discard:hover { color: var(--color-warning-text); border-color: rgba(181,138,46,.4); background: #F7EFDC; }
.fact-act-discard.is-on { color: #fff; background: var(--color-warning-text); border-color: var(--color-warning-text); }
.fact-act-del { margin-left: auto; color: var(--color-text-subtle); border-color: transparent; background: transparent; padding: 6px; }
.fact-act-del:hover { color: var(--color-error); background: var(--color-accent-soft); border-color: transparent; }
@media (max-width: 460px) { .fact-act-del { margin-left: 0; } }

/* ---- Pasek kryteriów obowiązkowych — @dsCriteria (co dopiąć, żeby ruszyć z planem) ---- */
.criteria-bar { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.criteria-chip { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); padding: 4px var(--sp-3); border-radius: var(--radius-pill); border: var(--border-w) solid var(--color-border); background: var(--color-chip-bg); color: var(--color-text-muted); }
.criteria-chip.is-met { color: #4E501F; background: var(--color-success-soft); border-color: rgba(110, 112, 56, .30); }
.criteria-chip .crit-ico { flex: none; }

/* ---- Spinner + wiersz postępu — @dsSpinner (research „to potrwa 1–2 min") ---- */
.spinner { display: inline-block; width: 18px; height: 18px; flex: none; border-radius: 50%; border: 2px solid var(--color-border); border-top-color: var(--color-accent); animation: ds-spin .7s linear infinite; }
@keyframes ds-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 1.6s; } }
.facts-progress { display: flex; align-items: center; gap: var(--sp-3); color: var(--color-text-muted); font-size: var(--fs-sm); }

/* Zapas na dole panelu, żeby pływający FAB „Zgłoś uwagę" (fixed) nie zasłaniał akcji na dole. */
.app-shell { padding-bottom: 84px; }

/* ---- Pierścień gotowości % — @dsReadinessRing (ustaw --pct: 0..100) ---- */
.ring {
  --pct: 0; --ring-size: 108px; --ring-w: 10px;
  width: var(--ring-size); height: var(--ring-size); border-radius: 50%; flex: none;
  display: inline-grid; place-items: center;
  background:
    radial-gradient(farthest-side, var(--color-surface) calc(100% - var(--ring-w)), transparent calc(100% - var(--ring-w) + 1px)),
    conic-gradient(var(--color-accent) calc(var(--pct) * 1%), var(--color-border) 0);
  /* Fallback prostszy (jeden radial nakłada „dziurę") */
}
.ring::before {
  content: ""; position: absolute; width: calc(var(--ring-size) - var(--ring-w) * 2);
  height: calc(var(--ring-size) - var(--ring-w) * 2); border-radius: 50%; background: var(--color-surface);
}
.ring { position: relative; }
.ring-val { position: relative; z-index: 1; text-align: center; line-height: 1.05; }
.ring-val b { display: block; font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-xl); color: var(--color-text); }
.ring-val span { font-family: var(--font-ui); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-text-subtle); }
/* Gotowy (≥ próg) — pierścień oliwkowy */
.ring-ready { background:
    radial-gradient(farthest-side, var(--color-surface) calc(100% - var(--ring-w)), transparent calc(100% - var(--ring-w) + 1px)),
    conic-gradient(var(--color-success) calc(var(--pct) * 1%), var(--color-border) 0); }

/* ---- Wiersz czatu symulacji — @dsSimChat ---- */
.sim-chat { display: flex; flex-direction: column; gap: var(--sp-3); }
.sim-msg { max-width: 80%; padding: var(--sp-3) var(--sp-4); border-radius: 16px; font-size: var(--fs-base); line-height: 1.5; }
.sim-msg-them { align-self: flex-start; background: var(--color-surface); border: var(--border-w) solid var(--color-border); border-bottom-left-radius: 5px; color: var(--color-text); }
.sim-msg-you  { align-self: flex-end;   background: var(--color-accent-soft); border: var(--border-w) solid rgba(183, 79, 38, .18); border-bottom-right-radius: 5px; color: var(--color-text); }
.sim-msg-role { display: block; font-family: var(--font-ui); font-size: 11px; font-weight: var(--fw-ui-bold); letter-spacing: .07em; text-transform: uppercase; color: var(--color-text-subtle); margin-bottom: 4px; }

/* Podpowiedź trenera (inline, tryb treningu) — @dsSimTrainer: pełna szerokość, oliwka, wyraźnie inne niż rozmówca */
.sim-msg-trainer {
  align-self: stretch; max-width: 100%;
  background: var(--color-success-soft); border: var(--border-w) solid rgba(110, 112, 56, .28);
  border-radius: 12px; padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm); line-height: 1.5; color: var(--color-text);
  display: flex; gap: var(--sp-3);
}
.sim-msg-trainer svg { flex: none; color: var(--color-success); margin-top: 2px; }
.sim-msg-trainer .sim-msg-role { color: var(--color-success); }

/* Wskaźnik pisania rozmówcy — @dsSimTyping */
.sim-typing { align-self: flex-start; display: inline-flex; gap: 5px; padding: var(--sp-3) var(--sp-4); background: var(--color-surface); border: var(--border-w) solid var(--color-border); border-radius: 16px; border-bottom-left-radius: 5px; }
.sim-typing span { width: 7px; height: 7px; border-radius: 50%; background: var(--color-text-subtle); opacity: .45; animation: sim-blink 1.2s infinite ease-in-out; }
.sim-typing span:nth-child(2) { animation-delay: .2s; }
.sim-typing span:nth-child(3) { animation-delay: .4s; }
@keyframes sim-blink { 0%, 60%, 100% { opacity: .3; transform: translateY(0); } 30% { opacity: .9; transform: translateY(-3px); } }
@media (prefers-reduced-motion: reduce) { .sim-typing span { animation: none; } }

/* Ekran startu symulacji — @dsSimSetup: wybór trybu + poziomu + persona */
.sim-mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 620px) { .sim-mode-grid { grid-template-columns: 1fr; } }
.sim-mode-card {
  text-align: left; cursor: pointer; background: var(--color-surface); color: var(--color-text);
  border: 1.5px solid var(--color-border); border-radius: var(--radius-card);
  padding: var(--sp-4) var(--sp-5); transition: border-color var(--dur-micro) var(--ease-micro), box-shadow var(--dur-micro) var(--ease-micro), background var(--dur-micro) var(--ease-micro);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.sim-mode-card:hover { border-color: var(--color-border-strong); }
.sim-mode-card.is-active { border-color: var(--color-accent); background: var(--color-accent-soft); box-shadow: var(--shadow-sm); }
.sim-mode-card .smc-title { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: var(--fw-display-med); display: flex; align-items: center; gap: var(--sp-2); }
.sim-mode-card .smc-desc { font-size: var(--fs-sm); color: var(--color-text-muted); line-height: 1.5; }
.sim-mode-card .smc-tag { font-family: var(--font-ui); font-size: 11px; font-weight: var(--fw-ui-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-subtle); }

.sim-diff { display: inline-flex; gap: var(--sp-2); flex-wrap: wrap; }
.sim-diff-btn { cursor: pointer; font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); color: var(--color-text-muted); background: var(--color-surface); border: 1.5px solid var(--color-border); border-radius: var(--radius-pill); padding: 6px 16px; transition: all var(--dur-micro) var(--ease-micro); }
.sim-diff-btn:hover { border-color: var(--color-border-strong); }
.sim-diff-btn.is-active { color: var(--color-accent-text); background: var(--color-accent); border-color: var(--color-accent); }

.sim-persona {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  border-radius: 14px; padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); line-height: 1.5;
}
.sim-persona.is-konkretny { background: var(--color-accent-soft); border: var(--border-w) solid rgba(183, 79, 38, .18); }
.sim-persona.is-neutralny { background: var(--color-bg-alt); border: var(--border-w) solid var(--color-border); }
.sim-persona svg { flex: none; margin-top: 2px; color: var(--color-accent); }
.sim-persona.is-neutralny svg { color: var(--color-text-subtle); }
.sim-persona b { font-weight: var(--fw-ui-bold); }

/* Ekran rozmowy — @dsSimLayout: czat + boczny plan (trening) */
.sim-layout { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); }
.sim-layout.has-side { grid-template-columns: minmax(0, 1fr) 300px; }
@media (max-width: 900px) { .sim-layout.has-side { grid-template-columns: 1fr; } }
.sim-header { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.sim-header .pill { font-size: var(--fs-xs); }
.sim-scroll { max-height: min(60vh, 560px); overflow-y: auto; padding: var(--sp-2) var(--sp-1) var(--sp-4); }
.sim-composer { display: flex; gap: var(--sp-3); align-items: flex-end; margin-top: var(--sp-4); }
.sim-composer textarea { flex: 1; resize: none; min-height: 48px; max-height: 140px; line-height: 1.45; }
.sim-composer .btn { flex: none; }
.sim-side .card { position: sticky; top: var(--sp-4); }
.sim-plan > summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); }
.sim-plan > summary::-webkit-details-marker { display: none; }
.sim-plan > summary .chev { color: var(--color-text-subtle); transition: transform var(--dur-micro) var(--ease-micro); }
.sim-plan[open] > summary .chev { transform: rotate(180deg); }
.sim-plan-title-d { display: none; }                                        /* tytuł panelu — desktop-only (na mobile jest w <summary>) */
@media (min-width: 901px) { .sim-plan > summary { display: none; } .sim-plan-title-d { display: block; } }  /* desktop: plan zawsze otwarty (JS open), bez zwijania */
@media (max-width: 900px) { .sim-side { order: -1; } .sim-plan > summary { cursor: pointer; } }  /* mobile: plan NAD czatem, zwijany */
.sim-side .plan-mini { max-height: 46vh; overflow-y: auto; font-size: var(--fs-sm); }
.sim-side .plan-mini h4 { font-family: var(--font-ui); font-size: 11px; font-weight: var(--fw-ui-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--color-text-subtle); margin: var(--sp-3) 0 var(--sp-1); }
.sim-side .plan-mini p, .sim-side .plan-mini li { color: var(--color-text-muted); line-height: 1.45; margin: 0 0 var(--sp-1); }
.sim-side .plan-mini ul { margin: 0; padding-left: var(--sp-4); }

/* Ekran „rozmowa zakończona" / ocena — @dsSimEnd */
.sim-end { text-align: center; padding: var(--sp-7) var(--sp-5); }
.sim-end .sim-end-ico { display: inline-flex; align-items: center; justify-content: center; width: 64px; height: 64px; border-radius: 50%; background: var(--color-success-soft); color: var(--color-success); margin-bottom: var(--sp-4); }
.sim-end h2 { font-family: var(--font-display); font-size: var(--fs-xl); margin-bottom: var(--sp-2); }
.sim-end-ico-spin svg { animation: rap-spin 1s linear infinite; }
@keyframes rap-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sim-end-ico-spin svg { animation: none; } }

/* ---- Opt-in retencji transkryptu — @dsKeepTranscript ---- */
.keep-transcript { display: flex; gap: var(--sp-3); align-items: flex-start; padding: var(--sp-4); border: var(--border-w) solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); cursor: pointer; }
.keep-transcript input { margin-top: 3px; flex: none; width: 18px; height: 18px; accent-color: var(--color-accent); }
.keep-transcript-title { display: block; font-family: var(--font-ui); font-weight: var(--fw-ui-med); font-size: var(--fs-sm); color: var(--color-text); }
.keep-transcript-sub { display: block; font-size: var(--fs-xs); color: var(--color-text-subtle); line-height: 1.5; margin-top: 3px; }

/* ================= RAPORT Z ROZMOWY (F4b) ================= */
/* ---- Wynik 1–10 + wynik domknięcia — @dsReportScore ---- */
.report-score { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.report-score-num { display: flex; align-items: baseline; gap: var(--sp-2); flex: none; }
.report-score-num .rs-big { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: 4.5rem; line-height: .9; color: var(--color-accent); }
.report-score-num .rs-max { font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-text-subtle); text-transform: uppercase; letter-spacing: var(--tracking-caps); }
.report-score-side { flex: 1 1 220px; min-width: 0; }
@media (max-width: 560px) { .report-score { gap: var(--sp-4); } .report-score-num .rs-big { font-size: 3.6rem; } }

/* ---- Paski subscore — @dsScoreBar ---- */
.score-bars { display: flex; flex-direction: column; gap: var(--sp-4); }
.score-bar-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); margin-bottom: 6px; }
.score-bar-label { font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); color: var(--color-text); }
.score-bar-val { font-family: var(--font-ui); font-size: var(--fs-xs); color: var(--color-text-subtle); flex: none; }
.score-bar-track { height: 10px; border-radius: var(--radius-pill); background: var(--color-chip-bg); overflow: hidden; }
.score-bar-fill { display: block; height: 100%; border-radius: var(--radius-pill); background: var(--color-accent); transition: width var(--dur-slow, .5s) var(--ease-out, ease); }

/* ---- Wnioski trenera — @dsReportInsights ---- */
.report-insights-head { display: flex; align-items: center; gap: var(--sp-3); }
.report-insights { font-size: var(--fs-base); line-height: 1.65; color: var(--color-text); white-space: pre-line; }

/* ---- Powtórka końcówki — @dsReportRetry ---- */
.report-retry { border-color: rgba(183, 79, 38, .30); background: var(--color-accent-soft); }
.report-retry-head { display: flex; gap: var(--sp-3); align-items: flex-start; }
.report-retry-title { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); }
.report-retry .icon-chip { flex: none; }

/* ---- Porównanie prób — @dsReportCompare ---- */
.compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 640px) { .compare-grid { grid-template-columns: 1fr; } }
.compare-col { border: var(--border-w) solid var(--color-border); border-radius: var(--radius); padding: var(--sp-4); background: var(--color-surface); }
.compare-head { font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-ui-bold); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-text-subtle); margin-bottom: var(--sp-3); }
.compare-col .quote-say { font-size: var(--fs-base); }

/* ---- Cytat „do wypowiedzenia" — @dsQuote (kursywa szeryfowa, odróżnia skrypt od UI) ---- */
.quote-say {
  font-family: var(--font-display); font-style: italic; font-weight: var(--fw-display);
  font-size: var(--fs-lg); line-height: 1.45; color: var(--color-text);
  border-left: 3px solid var(--color-accent); padding: var(--sp-2) 0 var(--sp-2) var(--sp-4);
  margin: 0;
}
.quote-say cite { display: block; margin-top: var(--sp-2); font-style: normal; font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-text-subtle); }

/* ---- Stepper kroków przygotowania — @dsStepper ---- */
.stepper { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.stepper-item { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--color-text-subtle); font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); }
.stepper-item .step-num { background: var(--color-chip-bg); color: var(--color-text-subtle); }
.stepper-item.is-done .step-num { background: var(--color-success); color: #fff; }
.stepper-item.is-active { color: var(--color-text); }
.stepper-item.is-active .step-num { background: var(--color-accent); color: #fff; }
.stepper-sep { width: 22px; height: 2px; background: var(--color-border); border-radius: 2px; flex: none; }

/* ---- KPI pulpitu — @dsKpi ---- */
/* minmax(0,1fr): tracki MUSZĄ móc zejść poniżej szerokości treści — inaczej długie etykiety KPI
   (min-content) rozpychają rząd i pulpit z danymi wystaje na wąskich telefonach (fix S5 must-fix). */
.kpi-grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* KOLEJNOŚĆ: reguły bazowe .kpi PRZED @media — inaczej późniejsza baza (ta sama specyficzność)
   ubija mobilny override i etykieta wraca do 13px+.12em → „NADCHODZĄCE” za szerokie i cięte
   na krawędzi karty (pułapka „@media przed bazowymi = martwe override”, złapana w mini-krytyku POPR-B). */
.kpi { text-align: center; padding: var(--sp-5) var(--sp-4); }
.kpi .kpi-ico { color: var(--color-text-subtle); margin-bottom: var(--sp-3); display: inline-flex; }
.kpi .kpi-ico.is-accent { color: var(--color-accent); }
.kpi .kpi-ico.is-olive  { color: var(--color-success); }
.kpi .kpi-num { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: 3rem; line-height: 1; color: var(--color-text); }
.kpi .kpi-label { font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-ui-med); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-text-subtle); margin-top: var(--sp-2); line-height: 1.2; overflow-wrap: normal; word-break: keep-all; hyphens: manual; }
/* Mobile (fix S5/d): NIE zwijamy do 1 kolumny (pulpit robił się bardzo długi) — kompaktowy rząd 3-up.
   UX-4: mniejsza etykieta (10px, minimalny tracking) + łamanie WYŁĄCZNIE po spacjach („NADCHODZĄCE / ROZMOWY”). */
@media (max-width: 640px) {
  .kpi-grid { gap: var(--sp-2); }
  .kpi { padding: var(--sp-4) var(--sp-2); min-width: 0; }
  .kpi .kpi-ico { margin-bottom: var(--sp-1); }
  .kpi .kpi-ico svg { width: 18px; height: 18px; }
  .kpi .kpi-num { font-size: 1.9rem; }
  .kpi .kpi-label { font-size: 10px; letter-spacing: .01em; }
}
/* UX-4: na bardzo wąskich (≤390) skracamy padding boczny i tracking do zera, by 3-up się mieścił. */
@media (max-width: 390px) {
  .kpi { padding: var(--sp-4) 6px; }
  .kpi .kpi-num { font-size: 1.75rem; }
  .kpi .kpi-label { letter-spacing: 0; }
}

/* ---- Karta wydarzenia pulpitu — @dsEventCard (ikona + tytuł + meta + CTA) ---- */
.event-card { display: flex; align-items: center; gap: var(--sp-4); }
.event-card .event-body { flex: 1 1 auto; min-width: 0; }
.event-card .event-title { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); }
.event-card .event-cta { flex: none; }
@media (max-width: 560px) { .event-card { flex-wrap: wrap; } .event-card .event-cta { flex-basis: 100%; } .event-card .event-cta .btn { width: 100%; } }

/* ---- Wiersz meta (czas · miejsce · osoba) — @dsMetaRow ---- */
.meta-row { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-top: 6px; font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-text-muted); }
.meta-row .meta-item { display: inline-flex; align-items: center; gap: 6px; }
.meta-row .meta-item svg { flex: none; color: var(--color-text-subtle); }
.meta-row .meta-item.is-accent svg { color: var(--color-accent); }
.meta-row .meta-sep { color: var(--color-border-strong); }

/* ---- Micro-copy prywatności — @dsPrivacy (kluczowe w niszy: „Twoje dane są tylko dla Ciebie") ---- */
.privacy-note { display: inline-flex; align-items: center; gap: var(--sp-2); font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-success); }
.privacy-note svg { flex: none; }

/* ---- Filar planu — @dsPillar (numer + tytuł + treść; wzór landing/glowna) ---- */
.pillar { display: flex; gap: var(--sp-4); }
.pillar .pillar-head { display: flex; align-items: center; gap: var(--sp-3); }
.pillar .pillar-title { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); }
.pillar .pillar-sub { font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-text-subtle); }

/* ---- Ekran „Plan rozmowy" (F3) — @dsPlanLayout / @dsPlanItem ----
   Dwie kolumny: filary planu + boczny panel gotowości (sticky na desktopie).
   Poniżej 900px kolumny stają jedna pod drugą; panel gotowości traci sticky. */
.plan-layout { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); align-items: start; }
@media (min-width: 900px) { .plan-layout { grid-template-columns: minmax(0, 1fr) 320px; gap: var(--sp-6); } }
.plan-side { display: grid; gap: var(--sp-4); }
/* Mobile: panel gotowości (pierścień + braki + CTA) NAD filarami — 5 min przed spotkaniem
   od razu widzisz „ile brakuje" i „przećwicz", bez przewijania całego planu. */
@media (max-width: 899px) { .plan-side { order: -1; } }
@media (min-width: 900px) { .plan-side { position: sticky; top: var(--sp-4); } }
.plan-side .ring { justify-self: center; }

/* Sekcja-filar planu: numer + tytuł + lista pozycji. Reużywa .pillar (numer + tytuł/sub). */
.plan-sec { display: block; }
.plan-sec + .plan-sec { margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--color-border); }
.plan-sec .pillar { align-items: flex-start; }
.plan-sec-body { flex: 1; min-width: 0; }
.plan-items { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-3); }

/* Pojedyncza pozycja planu (cytat / pytanie / problem / obiekcja) z paskiem interakcji. */
.plan-item { border: var(--border-w) solid var(--color-border); border-radius: var(--radius-card-sm, 14px); background: var(--color-surface); padding: var(--sp-3) var(--sp-4); }
.plan-item.is-important { border-color: var(--color-accent); box-shadow: inset 3px 0 0 var(--color-accent); }
.plan-item.is-read { opacity: .72; }
.plan-item-text { color: var(--color-text); font-size: var(--fs-base); line-height: 1.55; margin: 0; }
.plan-item .quote-say { border-left-width: 3px; }
.plan-obj-q { font-family: var(--font-ui); font-weight: var(--fw-ui-bold); color: var(--color-text); margin: 0 0 var(--sp-2); }
.plan-obj-q::before { content: "„"; }
.plan-obj-q::after { content: "”"; }
.plan-obj-r { color: var(--color-text-muted); font-size: var(--fs-base); line-height: 1.55; margin: 0; padding-left: var(--sp-4); border-left: 2px solid var(--color-success); }

/* Pasek interakcji pozycji: przeczytane / najważniejsze / ulubione / kopiuj. */
.plan-item-tools { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-top: var(--sp-3); }
.mark-btn { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); color: var(--color-text-subtle); background: transparent; border: var(--border-w) solid transparent; border-radius: var(--radius-pill); padding: 3px var(--sp-2); cursor: pointer; transition: color var(--dur-micro) var(--ease-micro), background var(--dur-micro) var(--ease-micro); }
.mark-btn:hover { color: var(--color-text); background: var(--color-chip-bg); }
.mark-btn svg { flex: none; }
.mark-btn.is-on { color: #fff; background: var(--color-accent); border-color: var(--color-accent); }
.mark-btn.mark-read.is-on { color: #fff; background: var(--color-success); border-color: var(--color-success); }
.mark-btn.mark-favorite.is-on { color: #fff; background: var(--color-accent); border-color: var(--color-accent); }

/* Lista braków gotowości. */
.readiness-gaps { list-style: none; display: flex; flex-direction: column; gap: var(--sp-2); }
.readiness-gaps li { display: flex; gap: var(--sp-2); align-items: baseline; font-size: var(--fs-sm); color: var(--color-text-muted); line-height: 1.4; }
.readiness-gaps .gap-pct { flex: none; font-family: var(--font-ui); font-weight: var(--fw-ui-bold); color: var(--color-accent); font-variant-numeric: tabular-nums; }
.readiness-done { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--color-success); }

/* =====================================================================
 * PULPIT + HISTORIA (F5a, S4f) — hero najbliższego spotkania, KPI, trend.
 * ===================================================================== */

/* Zakładki topnav panelu usera (Pulpit / Historia) — aktywna = akcent. */
.apptab.is-active { color: var(--color-accent); background: var(--color-accent-soft); }

/* Warianty pierścienia gotowości: sm (hero pulpitu) i mini (karta listy). */
.ring-sm  { --ring-size: 92px;  --ring-w: 8px; }
.ring-mini { --ring-size: 48px; --ring-w: 5px; }
.ring-sm .ring-val b { font-size: var(--fs-lg); }
.ring-sm .ring-val span { font-size: 10px; }
.ring-mini .ring-mini-val { position: relative; z-index: 1; font-family: var(--font-ui); font-weight: var(--fw-ui-bold); font-size: 12px; color: var(--color-text); font-variant-numeric: tabular-nums; }
/* Mocniejszy obrys pustej części mini-pierścienia (czytelny na białym także przy 0%). */
.ring-mini:not(.ring-ready) {
  background:
    radial-gradient(farthest-side, var(--color-surface) calc(100% - var(--ring-w)), transparent calc(100% - var(--ring-w) + 1px)),
    conic-gradient(var(--color-accent) calc(var(--pct) * 1%), var(--color-border-strong) 0);
}

/* Hero pulpitu — najbliższa nadchodząca rozmowa (na jeden rzut oka „co teraz?"). */
.pulpit-hero { display: flex; align-items: center; gap: var(--sp-5); }
.pulpit-hero .hero-lead { flex: 1 1 auto; min-width: 0; }
.pulpit-hero .hero-eyebrow { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-ui); font-size: var(--fs-xs); font-weight: var(--fw-ui-med); letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-accent); }
.pulpit-hero .hero-eyebrow svg { flex: none; }
.pulpit-hero .hero-title { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-xl); line-height: 1.15; color: var(--color-text); margin: var(--sp-2) 0 var(--sp-3); }
.pulpit-hero .hero-when { font-family: var(--font-ui); font-weight: var(--fw-ui-bold); color: var(--color-accent); }
.pulpit-hero .hero-cta { margin-top: var(--sp-4); }
.pulpit-hero .hero-ring { flex: none; text-align: center; }
@media (max-width: 560px) {
  .pulpit-hero { flex-direction: column-reverse; align-items: stretch; text-align: left; gap: var(--sp-4); }
  .pulpit-hero .hero-ring { align-self: flex-start; }
  .pulpit-hero .hero-cta .btn { width: 100%; }
}

/* Mini pierścień na karcie przygotowania (obok CTA). Na mobile: pierścień NAD CTA (naturalna
   hierarchia „ile mam zrobione" przed akcją) — DOM ma ring przed cta, więc bez order wygrywa. */
.event-card .event-ring { flex: none; display: inline-flex; }

/* Nagłówek strony z akcją po prawej (pulpit/historia). */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap; }

/* Sekcja historii: wiersz podsumowania przeszłej rozmowy. */
.hist-row { display: flex; align-items: center; gap: var(--sp-4); }
.hist-row .hist-body { flex: 1 1 auto; min-width: 0; }
.hist-row .hist-title { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); }
.hist-row .hist-date { font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-text-subtle); }
.hist-row .hist-score { flex: none; text-align: center; min-width: 64px; }
.hist-row .hist-score b { display: block; font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); line-height: 1; }
.hist-row .hist-score b.is-strong { color: var(--color-success); }
.hist-row .hist-score span { font-family: var(--font-ui); font-size: 10px; letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--color-text-subtle); }
/* Mobile: wynik egzaminu NAD przyciskiem (najważniejsza informacja wiersza przed akcją). */
@media (max-width: 560px) { .hist-row { flex-wrap: wrap; } .hist-row .event-cta { flex-basis: 100%; } .hist-row .event-cta .btn { width: 100%; } }

/* Trend ocen egzaminów — mini-wykres liniowy SVG (własny, bez bibliotek; tokeny). */
.trend-card { display: grid; gap: var(--sp-3); }
.trend-svg { width: 100%; height: auto; display: block; overflow: visible; }
.trend-line { fill: none; stroke: var(--color-accent); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.trend-area { fill: var(--color-accent-soft); opacity: .5; }
.trend-dot { fill: var(--color-surface); stroke: var(--color-accent); stroke-width: 2; }
.trend-dot-last { fill: var(--color-accent); stroke: var(--color-accent); }
.trend-grid { stroke: var(--color-border); stroke-width: 1; }
.trend-axis { font-family: var(--font-ui); font-size: 10px; fill: var(--color-text-subtle); }
.trend-legend { display: flex; justify-content: space-between; align-items: baseline; font-family: var(--font-ui); font-size: var(--fs-sm); color: var(--color-text-subtle); }
.trend-legend b { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); }

/* Toast (feedback kopiowania) — pojawia się nad FAB, znika sam. */
.plan-toast { position: fixed; left: 50%; bottom: calc(var(--sp-6) + 56px); transform: translateX(-50%) translateY(8px); background: var(--color-text); color: var(--color-surface); font-family: var(--font-ui); font-size: var(--fs-sm); padding: var(--sp-2) var(--sp-4); border-radius: var(--radius-pill); box-shadow: var(--shadow-card); opacity: 0; pointer-events: none; transition: opacity var(--dur-micro) var(--ease-micro), transform var(--dur-micro) var(--ease-micro); z-index: var(--z-toast, 60); }
.plan-toast.is-show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---- Empty-state (rozszerzenie .empty o ikonę/tytuł/CTA) — @dsEmpty ---- */
.empty-ico { display: inline-flex; margin-bottom: var(--sp-3); color: var(--color-text-subtle); }
.empty-title { font-family: var(--font-display); font-weight: var(--fw-display-med); font-size: var(--fs-lg); color: var(--color-text); margin-bottom: var(--sp-2); }
.empty-text { color: var(--color-text-muted); max-width: 380px; margin: 0 auto var(--sp-4); }

/* ---- Utility: reveal wejścia (fade + rise) — @dsReveal ---- */
.reveal { opacity: 0; animation: ds-reveal-in var(--dur-reveal) var(--ease-reveal) both; }
.reveal-2 { animation-delay: 90ms; }
.reveal-3 { animation-delay: 180ms; }
.reveal-4 { animation-delay: 270ms; }

/* ---- Divider (subtelna linia sekcji) — @dsDivider ---- */
.ds-divider { height: 1px; background: var(--color-border); border: 0; margin: var(--sp-5) 0; }

/* ---- Gwiazdka pola wymaganego — @dsRequired (przy etykiecie pola z walidacją minimum) ---- */
.req { color: var(--color-accent); font-weight: var(--fw-ui-bold); margin-left: 2px; }

/* ---- Sekcja zwijana — @dsDisclosure (np. „Plan B" w formularzu przygotowania) ----
   details/summary bez natywnego markera; własny znacznik +/− na tokenach. */
.disclosure {
  border: var(--border-w) solid var(--color-border); border-radius: var(--radius-input);
  padding: var(--sp-3) var(--sp-4); background: var(--color-bg-alt);
}
.disclosure > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; gap: var(--sp-2);
  font-family: var(--font-ui); font-size: var(--fs-sm); font-weight: var(--fw-ui-med); color: var(--color-text);
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before {
  content: "+"; display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--color-chip-bg); color: var(--color-text-muted); font-weight: 700; line-height: 1;
}
.disclosure[open] > summary::before { content: "\2212"; } /* minus */

/* ---- Link „wróć" (nawigacja wstecz w widokach app) — @dsBackLink ---- */
.back-link { display: inline-flex; align-items: center; gap: var(--sp-2); font-family: var(--font-ui);
  font-size: var(--fs-sm); font-weight: var(--fw-ui-med); color: var(--color-text-muted); }
.back-link:hover { color: var(--color-text); text-decoration: none; }
.back-link svg { flex: none; }
