/* Wspólny arkusz aplikacji — redesign „papierowy" wg projektu Claude Design („Notatnik Redesign").
   Klasy odpowiadają komponentom z Notatnik.Client.UI. Ten sam plik obsługuje wszystkie hosty:
   przeglądarkę (Blazor WASM) oraz BlazorWebView w MAUI i WPF, więc nie ma tu nic platformowego.

   Zasada projektu: papier zamiast panelu. Tło w kolorze kartki, białe powierzchnie treści, jeden ciepły
   akcent (terakota), nagłówki szeryfowe. Kolory i wymiary siedzą w zmiennych — zmiana palety to zmiana
   bloku :root, nie przeszukiwanie arkusza. */

:root {
    /* Powierzchnie */
    --paper: #efeadf;          /* tło aplikacji — kolor kartki */
    --surface: #fffefb;        /* karty, panele, nawigacja */
    --surface-sunken: #fdfbf6; /* pola formularzy i źródło edytora */

    /* Atrament — od najciemniejszego do najjaśniejszego */
    --ink: #23201b;
    --ink-2: #3c3830;
    --ink-3: #4a463e;
    --ink-4: #5c574e;
    --muted: #8a857c;
    --muted-2: #a49e93;   /* metadane: daty, liczniki */

    /* Akcent */
    --accent: #b8543a;
    --accent-dark: #93412c;
    --accent-soft: #f4e7e2;   /* tło aktywnej pozycji nawigacji, odznaki akcentowej */
    --accent-line: #ecd9d2;
    --accent-wash: #fdf8f6;   /* tło wyróżnionego wiersza (nieprzeczytane, zgłoszenie w edycji) */

    /* Linie */
    --line: #e6e0d5;          /* obrysy kart i separatory */
    --line-strong: #ddd6c8;   /* obrysy pól i przycisków */
    --line-input: #ccc4b6;    /* pusty checkbox */

    /* Odznaka neutralna */
    --chip: #f1ede4;

    /* Role, nie wyglądy — te same nazwy działają w obu motywach, a wartości nie są takie same.
       „scrim" to przyciemnienie pod arkuszem, nie „półprzezroczysta czerń". */
    --on-accent: #fff;        /* tekst na wypełnieniu akcentem */
    --ink-hover: #100e0b;     /* najciemniejszy przycisk po najechaniu */
    --warn-strong: #93701a;   /* wyróżnienie w treści ostrzegawczej (odpowiedź administratora) */
    --shadow-strong: 0 20px 50px -34px rgba(35, 32, 27, .5);
    --shadow-soft: 0 -12px 32px rgba(35, 32, 27, .16);
    --scrim: rgba(35, 32, 27, .35);

    /* Statusy */
    --ok: #3f7d4e;   --ok-bg: #e6f0e8;   --ok-line: #cfe2d4;
    --warn: #b07a1e; --warn-bg: #f6efe0; --warn-line: #e2c489;
    --info: #3b6fb0; --info-bg: #e7eef6; --info-line: #d3e0ee;
    --danger: var(--accent);

    /* Kroje: Google Fonts wpięte w index.html hostów; stos zapasowy trzyma układ, gdy fontów nie ma
       (np. desktop/mobile bez sieci). */
    --serif: "Newsreader", Georgia, "Times New Roman", serif;
    --sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
    --mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

    /* Mówi przeglądarce, w którym motywie ma malować rzeczy, których ten arkusz nie dotyka: CHECKBOX LISTY
       ZADAŃ, paski przewijania, tła autouzupełnienia, natywne kontrolki pól. W tym projekcie ta jedna linia
       waży więcej niż gdzie indziej, bo checkbox jest częścią treści notatki (renderujemy prawdziwy `input`,
       nie `::before` — patrz reguła niżej) i jasny kwadrat na ciemnej notatce wygląda jak błąd renderowania,
       a nie jak niedokończony motyw.

       Konkretna wartość, nie `light dark`: o motywie decyduje wybór użytkownika (patrz blok niżej), więc
       przeglądarka nie ma tu nic do rozstrzygania. `light dark` kazałoby jej pytać system i natywne kontrolki
       chodziłyby własną drogą względem reszty arkusza. */
    color-scheme: light;
}

/* Motyw ciemny — wchodzi WYŁĄCZNIE przy atrybucie `data-theme="dark"` na `<html>`, który stawia
   `js/theme.js` przed pierwszym malowaniem. Ani jednego `@media (prefers-color-scheme…)` w tym arkuszu
   i to jest celowe: „za ustawieniem systemu" jest jedną z trzech możliwych PREFERENCJI użytkownika
   (ekran „Konto"), a skrypt rozstrzyga ją do konkretnego motywu. Gdyby na `<html>` trafiała surowa
   preferencja, ta paleta musiałaby stać tu dwa razy — raz pod atrybutem, raz pod zapytaniem mediów —
   i jej rozjazd byłoby widać dopiero na rzadkim ekranie w jednym z dwóch trybów.

   Domyślnie, bez wyboru i bez JS, aplikacja jest JASNA — także na systemie ustawionym na ciemno.

   Blok przedefiniowuje WYŁĄCZNIE zmienne (`color-scheme` jest jedną z nich w tym sensie: mówi o palecie,
   nie o układzie) i nie ma tu ani jednej reguły. Gdyby okazała się potrzebna, znaczy to, że gdzieś
   w arkuszu został kolor wpisany na sztywno — i to jego trzeba naprawić, a nie dopisać wyjątek.

   Odwrócone są ROLE, nie kolory: „papier" staje się najciemniejszą powierzchnią, a karty są od niego
   JAŚNIEJSZE (wychodzą do przodu, tak jak w motywie jasnym były jaśniejsze od tła). Atrament idzie od
   najbardziej wyrazistego do najmniej — tak samo jak w jasnym, tylko w drugą stronę osi jasności. */
:root[data-theme="dark"] {
    /* Powierzchnie — ciepłe, nie neutralnie szare; papier zostaje papierem, tylko nocnym */
    --paper: #191714;
    --surface: #221f1b;
    --surface-sunken: #1e1c18;

    /* Atrament — od najbardziej wyrazistego do najmniej (12.8:1 → 3.6:1 na tle karty) */
    --ink: #ece7dd;
    --ink-2: #ddd7cb;
    --ink-3: #cbc4b7;
    --ink-4: #b3ab9d;
    --muted: #8f887c;
    --muted-2: #7b746a;

    /* Akcent MUSI zjaśnieć: terakota #b8543a na ciemnym tle daje 3.25:1, czyli za mało na tekst.
       Rozjaśniona ma 5.5:1 — ale wtedy biel przestaje się na niej mieścić i dlatego `--on-accent`
       robi się ciemny. To jest cały powód, dla którego ten kolor jest zmienną, a nie literałem. */
    --accent: #e0805f;
    --accent-dark: #eb9b7d;   /* hover = JAŚNIEJ, bo na ciemnym tle wyrazistość rośnie z jasnością */
    --accent-soft: #3a241d;
    --accent-line: #4a2e24;
    --accent-wash: #241b17;

    --line: #322e28;
    --line-strong: #403b33;
    --line-input: #554e44;

    --chip: #2b2723;

    --on-accent: #1a1512;     /* ciemny tekst na jasnym akcencie — odwrotnie niż w motywie jasnym */
    --ink-hover: #fbf8f2;     /* `.btn-ink` jest tu jasnym przyciskiem, więc hover rozjaśnia */
    --warn-strong: #e0bd6a;

    /* Cień na ciemnym tle musi być czystą czernią i głębszy — cień w kolorze tła jest niewidoczny,
       a rozjaśniony wygląda jak poświata. */
    --shadow-strong: 0 20px 50px -34px rgba(0, 0, 0, .8);
    --shadow-soft: 0 -12px 32px rgba(0, 0, 0, .5);
    --scrim: rgba(0, 0, 0, .55);

    --ok: #7fc08c;   --ok-bg: #1c2b20;   --ok-line: #2f4736;
    --warn: #d9a94e; --warn-bg: #2c2416; --warn-line: #4a3c1e;
    --info: #7aa8dd; --info-bg: #1a2432; --info-line: #2c3d52;

    /* Ta sama rola co w `:root` — natywne kontrolki (CHECKBOX LISTY ZADAŃ, paski przewijania) mają iść
       za wybranym motywem, a nie za systemem. */
    color-scheme: dark;
}

/* Krój i wielkość TREŚCI notatki — druga i trzecia preferencja urządzenia obok motywu. `js/theme.js` stawia
   na `<html>` atrybut `data-font` (sans / serif / mono), a wielkość i odstępy wpisuje przed pierwszym
   malowaniem wprost w `style` tego elementu (`--note-base`, `--note-lead`) — bo to DOWOLNE liczby i nie da
   się napisać reguły na każdą. Wartości w `:root` niżej są więc awaryjne: widać je tylko wtedy, gdy skrypt
   nie wystartował. Zmiennych używa wyłącznie `.markdown-view`
   (powierzchnia edytora i podgląd). Reszta interfejsu — nawigacja, listy, formularze — CELOWO nie idzie za
   tym wyborem: to jest ustawienie czytania notatki, nie skalowanie aplikacji (od tego jest zoom przeglądarki).

   Krój niesie własny współczynnik wielkości, bo trzy rodziny mają różną wysokość x: Newsreader przy tych
   samych 15 px czyta się drobniej niż Hanken Grotesk, a JetBrains Mono — szerzej i większe. Bez tej korekty
   „Zwykły" znaczyłoby co innego przy każdym kroju. Domyślne wartości (sans, normal) dają dokładnie to,
   co arkusz miał przed dołożeniem tych preferencji, więc bez JS nic się nie zmienia. */
:root {
    --note-font: var(--sans);
    --note-base: 15px;
    --note-scale: 1;
    --note-size: calc(var(--note-base) * var(--note-scale));
    --note-lead: 1.2;
    /* Przerwa MIĘDZY akapitami nie jest osobnym wyborem — liczy się z wysokości wiersza, żeby jedna liczba
       sterowała obiema odległościami i żeby wzór stał w jednym miejscu (decyzja właściciela 2026-09-03).
       `em` zamiast pikseli: przerwa ma rosnąć razem z wielkością tekstu, inaczej większy tekst byłby
       ciaśniejszy niż mniejszy. Dolne ograniczenie `clamp` nie jest ozdobą — przy wysokości wiersza poniżej 1
       wzór dałby margines UJEMNY, czyli akapity zachodzące na siebie. Górne trzyma luźny wybór przy ziemi.
       ⚠️ Cena przyjęta świadomie: przy 1.2 przerwa wynosi 3 px, więc AKAPIT wygląda prawie jak złamanie
       wiersza — pusta linia w Markdownie niemal przestaje być widoczna. Pozycji listy nie dotyczy ani ta
       liczba, ani wysokość wiersza: pozycje stoją wiersz przy wierszu i to jest punkt odniesienia. */
    --note-gap: clamp(0em, calc((var(--note-lead) - 1) * 1em), 1em);
}
:root[data-font="serif"] { --note-font: var(--serif); --note-scale: 1.08; }
:root[data-font="mono"] { --note-font: var(--mono); --note-scale: .94; }

* { box-sizing: border-box; }

/* Przewija się DOKUMENT, a nie kontener wewnątrz aplikacji — góra strony stoi w miejscu przez `position: sticky`
   (blok `.page-top` niżej). Wariant „aplikacja na całą wysokość ekranu, treść we własnym przewijaku"
   (`height: 100dvh` + `overflow: auto`) daje ten sam obraz, ale na telefonie kosztuje dwie rzeczy naraz:
   klawiatura ekranowa zmniejsza widoczny obszar i karetka w powierzchni edycji potrafi zostać POD nią
   (przeglądarka przewija wtedy dokument, a nie nasz kontener), a pasek adresu przestaje się chować przy
   przewijaniu w dół. Obie awarie widać dopiero na urządzeniu, nie w oknie przeglądarki na biurku.

   `scroll-padding-top` to druga połowa tej decyzji: przewijanie „pokaż mi to" robi przeglądarka sama
   (karetka w powierzchni edycji, fokus po Tabie) i bez tego celowałaby w górną krawędź OKNA, czyli pod
   przypięty pasek. Liczba to najwyższy przypięty blok w aplikacji — nagłówek edytora razem z paskiem
   formatowania. */
html { scroll-padding-top: 96px; }

body {
    margin: 0;
    font-family: var(--sans);
    font-size: 14.5px;
    color: var(--ink);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-dark); }

h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; color: var(--ink); }

.loading { padding: 4rem; text-align: center; color: var(--muted); }

/* --- Szkielet: lewa nawigacja + treść (na wąskim ekranie nawigacja schodzi na dół jako pasek zakładek) --- */

.app { min-height: 100vh; display: flex; }

.app-plain { align-items: center; justify-content: center; }
.app-plain .content { padding: 6vh 20px; width: 100%; display: flex; justify-content: center; }

.sidebar {
    width: 250px;
    flex: none;
    background: var(--surface);
    border-right: 1px solid var(--line);
    padding: 22px 16px;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

.brand {
    display: flex; align-items: center; gap: 9px;
    padding: 4px 10px 22px;
    font-family: var(--serif); font-size: 23px; font-weight: 600;
    color: var(--ink);
}
.brand:hover { color: var(--ink); }
.brand-dot { width: 11px; height: 11px; border-radius: 50%; background: var(--accent); flex: none; }

/* Nawigacja przewija się sama, bo sekcje przestrzeni potrafią być długie: `.sidebar` ma `height: 100vh`,
   a stopka z wylogowaniem stoi na `margin-top: auto` — bez tego rozwinięta przestrzeń z kilkunastoma
   notatkami wypchnęłaby ją poza ekran i wyglądałoby to na zniknięcie przycisku, nie na za długie menu.
   `min-height: 0` jest konieczne: element flex nie zjeżdża domyślnie poniżej rozmiaru swojej treści. */
.sidebar nav { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; min-height: 0; }
.sidebar nav a {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 12px; border-radius: 9px;
    color: var(--ink-3); position: relative;
}
.sidebar nav a:hover { background: var(--chip); color: var(--ink-2); }
.sidebar nav a.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

.nav-badge {
    margin-left: auto;
    background: var(--accent); color: var(--on-accent);
    font-size: 11px; font-weight: 700;
    border-radius: 999px; padding: 1px 7px;
}
.nav-tag {
    margin-left: auto;
    font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
    color: var(--accent); border: 1px solid var(--accent-line); border-radius: 5px; padding: 1px 5px;
}
.nav-divider { height: 1px; background: var(--line); margin: 12px 10px; }

/* Notatki przestrzeni w menu: mniejsze i węższe niż pozycje nawigacji, żeby lista nie konkurowała
   z nią o uwagę. Tytuł idzie w jedną linię — notatka nazwana zdaniem nie ma rozpychać menu. */
.nav-section {
    padding: 2px 12px 6px; font-size: 11px; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted);
}
.sidebar nav a.nav-note {
    padding: 6px 12px; font-size: 13.5px;
    display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar nav a.nav-more { padding: 4px 12px; font-size: 12.5px; color: var(--muted); }

/* Nagłówek przestrzeni. Przycisk, nie link — rozwijanie sekcji nie jest nawigacją. Przestrzeń bez notatek
   przychodzi wyłączona (nie ma czego rozwinąć), ale zostaje w menu z licznikiem `0`: ukryta wyglądałaby
   na przestrzeń, która zniknęła. */
.nav-space {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 7px 12px; border: none; border-radius: 9px;
    background: none; font: inherit; font-size: 13.5px; color: var(--ink-3);
    text-align: left; cursor: pointer;
}
.nav-space:hover:not(:disabled) { background: var(--chip); color: var(--ink-2); }
.nav-space:disabled { cursor: default; color: var(--muted); }
.nav-space-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-space-count { margin-left: auto; font-size: 11.5px; color: var(--muted); }
/* Trójkącik z czystego CSS zamiast ikony: obraca się przy rozwinięciu i nie dokłada nic do drzewa. */
.nav-space::before {
    content: ""; flex: none;
    border: 4px solid transparent; border-left-color: currentColor;
    transition: transform .12s ease; transform-origin: 2px 4px;
}
.nav-space[aria-expanded="true"]::before { transform: rotate(90deg); }
.nav-space-loading { padding: 6px 12px 6px 24px; font-size: 12.5px; color: var(--muted); }

.sidebar-foot {
    margin-top: auto; padding-top: 18px; border-top: 1px solid var(--line);
    display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
}
.sidebar-foot .email {
    font-size: 13px; color: var(--ink-4); padding: 0 10px;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Elementy nawigacji, które istnieją WYŁĄCZNIE na wąskim ekranie: ikony zakładek, piąta zakładka „Więcej"
   i jej arkusz. Są w drzewie zawsze (jeden layout dla wszystkich hostów), więc chowa je arkusz stylów.
   Domyślnie ukryte, a nie domyślnie widoczne — dzięki temu zmiana szerokości okna z otwartym arkuszem
   nie zostawia panelu wiszącego nad desktopowym menu. */
.nav-icon { display: none; }
.nav-sheet-toggle { display: none; }
.sheet, .sheet-backdrop { display: none; }

/* Kolumna treści przestaje rosnąć do szerokości monitora. Bez `max-width` wiersz notatki miał na ekranie
   1920 px około 190 znaków — przy takiej długości oko gubi początek następnego wiersza. Wyśrodkowana,
   a nie dosunięta do nawigacji: dosunięta zostawia na 2560 px metr pustki po jednej stronie i wygląda
   na niedokończony układ, a nie na decyzję. */
.content { flex: 1; min-width: 0; max-width: 1100px; margin: 0 auto; padding: 40px 48px; }

/* --- Nagłówki stron --- */

/* Przypięta góra strony — JEDEN mechanizm na całą aplikację. W środku stoi to, czego nie wolno stracić
   przy przewijaniu: powrót, tytuł ekranu i działania nagłówka („opróżnij kosz", „oznacz wszystkie",
   menu „⋯" w notatce). Powód jest praktyczny: przestrzeń z setką notatek i długa notatka kończyły się
   tym samym — żeby cofnąć albo sięgnąć po działanie, trzeba było przewinąć całą stronę do góry.

   Tło jest NIEPRZEZROCZYSTE i to nie ozdoba: pod paskiem przejeżdża treść. `--paper`, a nie `--surface`,
   bo to tło strony, nie karta.

   Blok nie sięga poza kolumnę treści i nie musi — boczne marginesy `.content` są puste, więc nie ma tam
   czego zasłaniać. Marginesu dolnego dzieci też nie zerujemy: zostaje POZA blokiem, więc treść wsuwa się
   pod pasek z tym samym odstępem, jaki ma w spoczynku, a wygląd nieprzewiniętej strony się nie zmienia.

   z-index nad dolnym paskiem zakładek (20), pod arkuszem „Więcej" (30) — przypięcie tworzy kontekst
   układania, więc to ONA rozstrzyga, czy menu „⋯" wynurzy się nad zakładki; sam `z-index: 25` na `.menu`
   już by tego nie zrobił. */
.page-top {
    position: sticky; top: 0; z-index: 25;
    background: var(--paper);
}

h1 { font-size: 38px; font-weight: 500; margin: 0 0 28px; letter-spacing: -.01em; }

.page-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    margin-bottom: 28px;
}
.page-head h1 { margin: 0; }
/* Licznik pozycji i odnośniki do miejsc powiązanych stoją po prawej, w jednym rzędzie z tytułem —
   ten sam kształt nagłówka na każdej stronie listowej. */
.page-head .head-meta { display: flex; align-items: baseline; gap: 14px; margin-left: auto; }

.back-link { display: inline-block; font-size: 13.5px; color: var(--muted); margin-bottom: 14px; }
.back-link:hover { color: var(--ink-3); }

/* --- Przyciski --- */

.btn {
    /* Element liniowy z pionowym paddingiem NIE rozpycha wiersza, więc <a class="btn"> nachodziłby na tekst
       nad sobą i pod sobą, a width nic by na nim nie robiło. <button> jest inline-block sam z siebie i tego
       nie potrzebuje — potrzebuje odnośnik udający przycisk. */
    display: inline-flex; align-items: center; justify-content: center;
    padding: 11px 18px;
    border: 1px solid var(--line-strong); border-radius: 10px;
    background: var(--surface); color: var(--ink);
    font: inherit; text-align: center; text-decoration: none; cursor: pointer;
}
.btn:hover { border-color: var(--muted-2); }
.btn:disabled { opacity: .55; cursor: default; }

/* Zapis formularza — ciemny „atramentowy" przycisk (dodaj przestrzeń, udostępnij, zapisz odpowiedź). */
.btn-ink { background: var(--ink); border-color: var(--ink); color: var(--surface); font-weight: 600; }
.btn-ink:hover { background: var(--ink-hover); border-color: var(--ink-hover); }

/* Akcja nieodwracalna, która jest JEDYNA w swojej sekcji („Usuń konto") — waga przycisku, kolor ostrzeżenia.
   Obrys, a nie wypełnienie: wypełniony na czerwono przycisk czyta się jak akcja główna ekranu, a ta ma być
   łatwa do znalezienia i trudna do kliknięcia odruchem. */
.btn-danger { border-color: var(--accent); color: var(--accent); }
.btn-danger:hover { border-color: var(--accent-dark); color: var(--accent-dark); background: var(--accent-wash); }

/* Akcja główna ekranu — akcent (zaloguj, zapisz notatkę, wyślij zgłoszenie). */
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.btn-primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); }

/* Akcja drugorzędna w wierszu listy — wygląda jak odnośnik.

   `min-height` zamiast większego `padding`: cel wskaźnika ma mieć co najmniej 24 px w każdym wymiarze,
   ale „usuń trwale" ma dalej wyglądać jak odnośnik, a nie jak przycisk. Rośnie POLE TRAFIENIA, nie rysunek —
   stąd `inline-flex` z wyśrodkowaniem, a nie ramka. */
.btn-link {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 24px;
    border: none; background: none; color: var(--muted);
    font: inherit; font-size: 13.5px; padding: 4px 6px; cursor: pointer;
}
.btn-link:hover { color: var(--ink-3); }
.btn-link.danger, .danger { color: var(--accent); }
.btn-link.danger:hover { color: var(--accent-dark); }

.btn-icon {
    width: 34px; height: 34px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
}

/* Ikona-odnośnik w wierszu listy (przywróć, usuń trwale, odbierz, oznacz przeczytane, do kosza w pasku
   edytora): ta sama waga co `.btn-link`, którym te akcje były jako słowa — bez ramki i bez tła w spoczynku,
   z podświetleniem pod kursorem, bo sama ikona bez żadnej reakcji nie mówi, że jest przyciskiem.
   Kolor ostrzegawczy niesie `.danger`, jak przy odnośnikach.

   Ujemny margines pionowy z tego samego powodu, co w regule mobilnej `.btn-link`: pole trafienia ma 34 px,
   ale w UKŁADZIE ikona zajmuje 24 px jak odnośnik tekstowy — inaczej wiersz karty rósł o 10 px, a przy
   uzbrojeniu `ConfirmButton` (ikona → zdanie „tak / nie") cała lista podskakiwała. */
.btn-link.btn-icon { border-radius: 9px; margin-top: -5px; margin-bottom: -5px; }
.btn-link.btn-icon:hover { background: var(--chip); }

.btn-sm { padding: 8px 14px; font-size: 13px; border-radius: 9px; }


/* Ikona w pasku edytora i w akcjach wierszy. WŁASNE klasy, nie `.nav-icon`: tamta ma na desktopie
   `display: none`, bo ikony nawigacji widać wyłącznie w dolnym pasku zakładek. Dwie nazwy, jedna reguła —
   `editor-icon` została w pasku, `action-icon` mówi, że ikona jest akcją wiersza, a nie narzędziem. */
.editor-icon, .action-icon { display: block; width: 19px; height: 19px; }
/* Krzyżyk w pigułce etykiety (filtr i panel etykiet): mały i w linii z tekstem, grubszą kreską, bo przy 12 px
   standardowe 1.7 robiło się nitką. `vertical-align` zamiast flexa — pigułka zostaje zwykłym przyciskiem. */
.chip-icon { display: inline-block; width: 12px; height: 12px; vertical-align: -1px; margin-left: 3px; stroke-width: 2.4; }

/* „Aa" w pasku edytora: krojem nagłówków, bo to przycisk o kroju — i dwie litery, jak `B`/`I`/`H` obok. */
.editor-aa { font-family: var(--serif); font-size: 15px; font-weight: 600; letter-spacing: -.02em; line-height: 1; }

/* Przycisk paska, którego panel jest otwarty, wygląda jak zaznaczony (ten sam wygląd, co aktywna pozycja
   nawigacji) — bez tego nic nie łączy panelu pod paskiem z przyciskiem, który go otworzył. */
.editor-toolbar .btn[aria-expanded="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* --- Fokus z klawiatury --- */

/* JEDNA reguła na cały arkusz. Dotąd obrys istniał wyłącznie tam, gdzie ktoś napisał go ręcznie przy polu
   (trzy miejsca), więc ani jeden przycisk w aplikacji nie pokazywał, że jest wybrany z klawiatury.

   `:focus-visible`, a nie `:focus`: obrys ma się pokazywać przy przejściu Tabem, a nie po kliknięciu myszą —
   inaczej każdy klik zostawia ramkę i człowiek uczy się jej nie widzieć. Pola tekstowe przeglądarka i tak
   zalicza do `:focus-visible` także po kliknięciu, więc nic nie tracą na zniknięciu tamtych trzech reguł.

   Kolor z akcentu, nie z `--accent-line`: obrys ma być widoczny również na ciemnym tle, a `--accent`
   zmienia się razem z motywem — to jest cały powód, dla którego jest zmienną. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Element z `tabindex="-1"` dostaje fokus WYŁĄCZNIE programowo: `FocusOnNavigate` kładzie go na `<h1>`
   po każdej nawigacji (żeby czytnik ekranu przeczytał nazwę ekranu), a arkusz „Więcej" bierze go pod Escape.
   Obrys wokół takiego elementu jest informacją o niczym — Tabem nie da się tam wrócić — a pojawiał się
   po zwykłym kliknięciu w pozycję menu. */
[tabindex="-1"]:focus-visible { outline: none; }

/* --- Komunikaty i odznaki --- */

.error {
    color: var(--accent-dark); background: var(--accent-wash);
    border: 1px solid var(--accent-line); border-radius: 10px;
    padding: 10px 14px; margin: 0 0 16px; font-size: 14px;
}

/* Komunikat sukcesu — ten sam kształt co `.error`, paleta `--ok` zamiast akcentu: „udało się" nie ma
   wyglądać jak „coś jest nie tak". `role="status"` na wołającym, nie `alert` — to nie przerywa czytnika. */
.notice {
    color: var(--ok); background: var(--ok-bg);
    border: 1px solid var(--ok-line); border-radius: 10px;
    padding: 10px 14px; margin: 0 0 16px; font-size: 14px;
}

.muted { color: var(--muted); }
.meta { color: var(--muted-2); font-size: 13px; }
/* Termin trwałego usunięcia w koszu — ta sama wielkość co reszta metadanych, ale kolorem akcentu, bo mówi
   o czymś nieodwracalnym. */
.meta.warn { color: var(--accent); }

/* Uzbrojony ConfirmButton. Trzy elementy zamiast jednego, więc `inline-flex` z własnym odstępem — inaczej
   pytanie i odpowiedzi rozjeżdżałyby się odstępem kontenera, w którym przycisk akurat stoi. */
.confirm { display: inline-flex; align-items: center; gap: 8px; }
.confirm-question { font-size: 13px; color: var(--muted); }

.badge {
    font-size: 12px; font-weight: 600;
    border-radius: 999px; padding: 3px 11px;
    background: var(--chip); color: var(--muted);
    white-space: nowrap;
}
.badge-accent { background: var(--accent-soft); color: var(--accent); }
.badge-ok { background: var(--ok-bg); color: var(--ok); }
.badge-warn { background: var(--warn-bg); color: var(--warn); }
.badge-info { background: var(--info-bg); color: var(--info); }
.badge-count { background: var(--accent); color: var(--on-accent); margin-left: .35rem; }

/* Etykieta kategorii — obrys zamiast wypełnienia, żeby odróżnić ją od odznaki statusu. */
.tag {
    font-size: 11px; font-weight: 600;
    border: 1px solid var(--line-strong); border-radius: 6px; padding: 2px 8px;
    color: var(--muted); white-space: nowrap;
}
.tag-accent { color: var(--accent); border-color: var(--accent-line); }
.tag-ok { color: var(--ok); border-color: var(--ok-line); }
.tag-warn { color: var(--warn); border-color: var(--warn-line); }
.tag-info { color: var(--info); border-color: var(--info-line); }

.badges { display: flex; gap: .4rem; flex-wrap: wrap; }

/* --- Listy kart --- */

.card-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }

.card {
    background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
    padding: 18px 22px;
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}

.card-title {
    font-family: var(--serif); font-size: 20px; font-weight: 600;
    color: var(--ink); text-decoration: none; text-align: left;
    margin-right: auto; border: none; background: none; padding: 0; cursor: pointer;
    /* Bez tego duszy dwójka rozpychała całą stronę na telefonie: domyślne `min-width: auto` elementu flex
       nie pozwala mu zejść poniżej szerokości najdłuższego NIEROZDZIELONEGO fragmentu tekstu, więc tytuł
       bez spacji (wklejony link, ciąg znaków) wypychał kartę, listę i całą stronę w poziomy scroll zamiast
       się zawinąć. `overflow-wrap: anywhere` daje przeglądarce zgodę na złamanie takiego fragmentu w środku. */
    min-width: 0; overflow-wrap: anywhere;
}
.card-title:hover { color: var(--accent); }

/* Karta-odnośnik: CAŁA karta jest celem, nie sam tytuł. Tytuł jako jedyne klikalne miejsce czytał się jak
   zwykły napis, a kciuk trafiał obok niego — w datę albo w puste pole karty — i nic się nie działo.
   Odnośnik ZOSTAJE na tytule (semantyka, fokus z klawiatury, czytnik ekranu), a pseudoelement rozciąga jego
   pole trafienia na całą kartę. Pozostałe przyciski w karcie (etykiety na liście wszystkich notatek) wychodzą
   nad to pole własnym z-index — inaczej stałyby pod nim i nie dało się ich kliknąć. */
.card-clickable { position: relative; cursor: pointer; }
/* To samo dla karty, której główna akcja jest PRZYCISKIEM, nie odnośnikiem: tytuł rozwijający grupę albo uwagę,
   treść powiadomienia. Pseudoelement na przycisku pozycjonuje się względem karty (jedyny pozycjonowany przodek),
   więc mechanizm jest jeden. Karta rozwijana ma tę klasę także ROZWINIĘTA — zwija się kliknięciem w dowolne
   miejsce, tak samo jak się rozwinęła; formularze i listy z jej środka wychodzą nad cel regułą niżej. */
.card-clickable .card-title::after,
.card-clickable .notification-body::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
/* Podświetlenie „da się kliknąć" gaśnie, gdy kursor stoi nad treścią wyjętą spod celu (reguła niżej) — tam klik
   nic z kartą nie robi, więc karta nie ma tego obiecywać. `:where` zeruje specyficzność `:not(:has())`: reguła
   ma dalej przegrywać z `.feedback-item.open` (obrys rozwiniętej uwagi), tak jak przegrywała bez wyjątku. */
.card-clickable:hover:where(:not(:has(.card-lift:hover))) { border-color: var(--line-strong); }
.card-clickable:hover:where(:not(:has(.card-lift:hover))) .card-title,
.card-clickable:hover:where(:not(:has(.card-lift:hover))) .notification-body { color: var(--accent); }
/* Wszystko, co w karcie jest przyciskiem, wychodzi NAD rozciągnięty cel: pigułki etykiet, „udostępnij", kosz
   i jego pytanie „tak / nie", ptaszek „przeczytane". Miejsce przycisku aktywuje przycisk, reszta karty — tytuł. */
.card-clickable .tag-btn, .card-clickable .btn, .card-clickable .btn-link, .card-clickable .confirm { position: relative; z-index: 1; }
/* Treść rozwiniętej karty wychodzi nad cel W CAŁOŚCI, nie tylko jej przyciski. Konsument oznacza ją u siebie
   klasą `card-lift` (lista członków i formularz grupy, formularz odpowiedzi i treść uwagi, odpowiedź admina),
   zamiast wpisywać nazwę tutaj: lista nazw powtórzona w czterech regułach rozjechała się przy pierwszym
   dokładaniu (`.admin-reply` został pod celem). Klik w pole ma dać fokus polu, a przeciągnięcie po treści —
   zaznaczenie, nie zwinięcie; `cursor: auto` zdejmuje z niej łapkę odziedziczoną po karcie. Data z dymkiem
   i fragment w wyszukiwarce ZOSTAJĄ pod celem świadomie: cała karta ma otwierać, wyjątkiem są przyciski. */
.card-clickable .card-lift { position: relative; z-index: 1; cursor: auto; }
/* Zaczep menu „⋯" w karcie: lista pozycjonuje się absolutnie względem NIEGO, nie względem karty. Osobna klasa
   zamiast `.note-menu`, bo tamta należy do rzędu nagłówka edytora — sama lista (`.menu`, `.menu-backdrop`)
   jest wspólna. Nic tu nie unosi się nad rozciągnięty cel karty: robi to reguła `.card-clickable .btn` wyżej,
   bo unoszony ma być PRZYCISK, a nie zaczep (rozciągnięty zaczep zabierałby karcie pas na kliknięcie). */
.card-menu { position: relative; }
/* Przycisk „⋯" wychodzi nad `.menu-backdrop` (z-index 24) SAM, niezależnie od `.card-clickable .btn` niżej:
   backdrop otwartego menu jednej karty jest `position: fixed; inset: 0`, więc leży też nad przyciskami
   WSZYSTKICH pozostałych kart, a `.card-clickable` po tym przycisku zabiera karta z otwartym panelem
   udostępniania (traci tę klasę) — bez własnego z-index jej „⋯" nie miałby żadnego, przegrywając z backdropem
   podwójnie. Efekt bez tej reguły: pierwsze kliknięcie w „⋯" sąsiedniej karty tylko zamykało menu otwarte
   gdzie indziej (trafiało w jego backdrop), dopiero drugie otwierało właściwe. */
.card-menu > .btn { position: relative; z-index: 26; }
/* W karcie z menu tytuł ZWĘŻA SIĘ, zamiast rozpychać wiersz. Bazowa szerokość elementu flex to jego `max-content`,
   więc długa nazwa zajmowała całą pierwszą linię, a „⋯" spadał pod nią do lewej krawędzi — czyli dokładnie ten
   drugi wiersz, przez który to menu powstało. `flex: 1` daje bazę 0 i tytuł zawija się w sobie; `min-width: 0`
   jest konieczne, bo domyślne `min-width: auto` nie pozwoliłoby mu zejść poniżej najdłuższego wyrazu. */
.card:has(> .card-menu) .card-title { flex: 1; min-width: 0; }

/* Obrys fokusu wokół całej karty, nie samego tytułu — skoro całą kartę da się kliknąć, cała ma to pokazywać. */
.card-clickable:has(.card-title:focus-visible, .notification-body:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.card-clickable .card-title:focus-visible, .card-clickable .notification-body:focus-visible { outline: none; }

/* Wariant zwarty — wiersze wyszukiwarki, kosza i zgłoszeń. */
.card-compact { padding: 14px 17px; }
.card-compact .card-title { font-size: 17px; }

/* Pusty stan ma trzy części i żadna nie jest ozdobą: co tu będzie (normalnym kolorem tekstu, bo to jest
   treść ekranu, a nie przypis), dlaczego jest pusto — tylko gdy to nieoczywiste — i jedna akcja. Szare
   zdanie na pierwszym ekranie po rejestracji czyta się jak awaria, a nie jak zaproszenie. */
.empty { color: var(--muted); margin: 22px 0; }
.empty-title { display: block; color: var(--ink); font-size: 17px; margin-bottom: 6px; }
/* Akcja dostaje własny wiersz: w jednej linii ze zdaniem ginie, a to ona jest tu następnym krokiem. */
.empty-action { display: inline-block; margin-top: 12px; }

/* Zdanie wprowadzające nad listą — nie jest pustym stanem, więc nie jest szare ani wcięte. */
.intro { color: var(--ink); margin: 0 0 18px; }

/* --- Formularze --- */

input, select, textarea { font: inherit; color: var(--ink); }

/* `flex-end`, bo pola dostały podpisy: bez tego przycisk obok pola rósłby o wysokość etykiety. */
.inline-form { display: flex; align-items: flex-end; gap: 12px; margin-top: 22px; flex-wrap: wrap; }
/* Formularz nad listą (wyszukiwarka) zamiast pod nią — bez górnego odstępu. */
.inline-form.flush { margin-top: 0; margin-bottom: 22px; }
.inline-form input, .inline-form select {
    flex: 1; min-width: 180px;
    padding: 12px 16px; border: 1px solid var(--line-strong); border-radius: 10px;
    background: var(--surface);
}

.field {
    padding: 12px 15px; border: 1px solid var(--line-strong); border-radius: 10px;
    background: var(--surface-sunken); width: 100%;
}
textarea.field { resize: vertical; line-height: 1.6; min-height: 96px; }

.form-stack { display: flex; flex-direction: column; gap: 12px; }
.form-row { display: flex; gap: 10px; flex-wrap: wrap; }
.form-row > .field, .form-row > .field-group { flex: 1; }
.form-row > .field.wide, .form-row > .field-group.wide { flex: 2; }
.self-start { align-self: flex-start; }

/* Nazwa pola żyła dotąd WYŁĄCZNIE w placeholderze, czyli znikała w chwili, gdy ktoś zaczynał pisać.
   Przy trzech identycznych ramkach rejestracji to problem każdego, kto wrócił do formularza po przerwie —
   nie tylko czytnika ekranu. Etykieta jest widoczna zawsze; placeholder zostaje przykładem, nie nazwą. */
.field-label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 5px; }

/* Wymaganie POD polem, nie w placeholderze: warunek ma być widoczny dokładnie wtedy, gdy się go spełnia. */
.field-hint { font-size: 12.5px; color: var(--muted); margin: 5px 0 0; }

/* Pole z podpisem w formularzu poziomym: grupa przejmuje rozciąganie, które miało samo pole. */
.inline-form .field-group { flex: 1; min-width: 180px; }
.inline-form .field-group input, .inline-form .field-group select { width: 100%; min-width: 0; }

/* Treść wyłącznie dla czytnika ekranu — nagłówek edytora, który widoczny dublowałby pole tytułu tuż pod nim.
   `display: none` by go stąd usunęło, bo czytnik pomija to, czego nie ma w drzewie renderowanym. */
.visually-hidden {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- Logowanie i rejestracja --- */

.auth-card {
    width: 100%; max-width: 360px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 18px;
    padding: 40px 34px;
    box-shadow: var(--shadow-strong);
}
.auth-brand {
    display: flex; align-items: center; gap: 10px; justify-content: center;
    font-family: var(--serif); font-size: 30px; font-weight: 600;
    margin-bottom: 6px;
}
/* Podtytuł karty logowania JEST nagłówkiem strony (h1), tylko wygląda jak podpis pod logo: cztery ekrany
   autoryzacji nie miały żadnego h1, więc FocusOnNavigate nie miał czego złapać po nawigacji. */
.auth-card h1 {
    text-align: center; font-family: var(--sans); font-size: 14.5px; font-weight: 400;
    color: var(--muted); margin: 0 0 26px; letter-spacing: 0;
}
.auth-card form { display: flex; flex-direction: column; gap: 12px; }
.auth-card .btn-primary { margin-top: 6px; padding: 13px; width: 100%; }
/* Bloki kontrolek stojące POZA <form> (potwierdzenie adresu, „sprawdź skrzynkę", ponowna wysyłka linku).
   Sam `.form-stack` daje im rytm w środku; ten margines odsuwa je od akapitu nad i formularza pod nimi. */
.auth-card .form-stack { margin: 16px 0; }
.auth-card .switch { text-align: center; color: var(--muted); font-size: 13.5px; margin: 22px 0 0; }

/* --- Edytor notatki --- */

/* Rząd nagłówka notatki: powrót po lewej, stan zapisu i menu „⋯" po prawej. Stan zapisu stał w pasku
   formatowania i to on (razem z trzema słowami działań) łamał pasek na telefonie na dwa wiersze —
   tu jest w rzędzie, który i tak istnieje. */
/* `min-height` nie jest kosmetyką: pasek formatowania przypina się DOKŁADNIE pod tym rzędem (`.editor-bar`
   niżej, `top: 34px`). Notatka bez menu „⋯" (sam odczyt) dałaby rząd niższy o kilkanaście pikseli
   i między nagłówkiem a paskiem prześwitywałaby przejeżdżająca treść. */
.note-head { display: flex; align-items: center; gap: 10px; min-height: 34px; margin-bottom: 14px; }
.note-head .back-link { margin-bottom: 0; }
.note-head .spacer { flex: 1; }
.note-head .save-state { font-size: 12.5px; color: var(--muted); text-align: right; white-space: nowrap; }
/* Znak martwego kanału realtime: ostrzeżenie, nie błąd — stąd rodzina `--warn`, dobrana do obu trybów. */
.note-head .live-off { font-size: 12.5px; color: var(--warn); white-space: nowrap; }
.note-head .btn-icon { width: 34px; height: 34px; }
.note-head .btn[aria-expanded="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* Menu „⋯": własna lista pod przyciskiem, nie arkusz z layoutu — trzy pozycje pod palcem nie potrzebują
   półekranowego panelu. Przezroczyste tło pod nim łapie kliknięcie poza menu; z-index nad dolnym paskiem
   nawigacji (20), pod arkuszem „Więcej" (30) — otwarte jednocześnie nie mają jak się spotkać.
   Sama lista (`.menu`, `.menu-backdrop`) obsługuje DWA miejsca: nagłówek edytora i kartę przestrzeni
   (zaczep `.card-menu` wyżej); zmiana tutaj dotyczy obu. */
.note-menu { position: relative; }
.menu-backdrop { position: fixed; inset: 0; z-index: 24; }
.menu {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 25;
    min-width: 200px; padding: 6px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
    box-shadow: var(--shadow-soft);
}
.menu:focus { outline: none; }
.menu button {
    display: flex; align-items: center; gap: 10px;
    width: 100%; min-height: 40px; padding: 8px 12px;
    border: none; border-radius: 8px; background: none;
    color: var(--ink-2); font: inherit; font-size: 14px; text-align: left; cursor: pointer;
}
.menu button:hover { background: var(--chip); }
.menu button.danger { color: var(--accent); }
.menu .action-icon { width: 16px; height: 16px; }
/* Dwustopniowe potwierdzenie JAKO pozycja menu (usunięcie przestrzeni). Reguła wyżej robi z każdego przycisku
   pełny wiersz — dobre dla pozycji, złe dla pary „tak / nie", która ma stać obok pytania w jednym wierszu.
   Stąd dokładnie dwa wyjątki: przyciski wewnątrz `.confirm` wracają do własnej szerokości, a `.confirm` dostaje
   wcięcie pozostałych pozycji. Ostatnia linia prostuje to, co `.btn-link` wnosi ze sobą do wiersza menu:
   wyśrodkowanie (pozycja menu jest wyrównana do lewej jak sąsiadki) i ujemne marginesy, którymi poniżej 860 px
   rozpycha pole dotyku bez rozpychania wiersza karty — w menu wiersz MA być wysoki i marginesy zjadałyby go. */
/* Zawijanie, bo szerokości menu nie da się tu rozciągnąć treścią: jest pozycjonowane absolutnie względem
   samego przycisku „⋯", więc szerokość bierze z `min-width`, a nie z najdłuższej pozycji. Bez tego pytanie
   łamało się na trzy linie po dwa słowa. Z nim: pytanie w wierszu, „tak / nie" pod nim i obok siebie. */
.menu .confirm { flex-wrap: wrap; padding: 8px 12px; }
.menu .confirm button { width: auto; }
.menu .btn-link { justify-content: flex-start; margin: 0; }

/* Tytuł: pole ma być polem. Bez ramki z każdej strony (pełna ramka wokół 34-pikselowego szeryfa wygląda jak
   formularz, nie jak nagłówek), ale z linią pod spodem, która mówi „tu się pisze", i akcentem przy fokusie. */
.note-title {
    width: 100%; border: none; border-bottom: 2px solid var(--line); background: none; outline: none;
    font-family: var(--serif); font-size: 34px; font-weight: 600; color: var(--ink);
    padding: 0 0 8px; margin-bottom: 4px;
}
.note-title::placeholder { color: var(--ink-4); }
.note-title:focus { border-bottom-color: var(--accent); }

/* Pasek formatowania RAZEM z panelami, które spod niego wychodzą — przypięty tuż pod nagłówkiem notatki.
   Panele („Aa", odnośnik, przenoszenie) muszą siedzieć w tym samym bloku, i to jest jedyny powód, dla
   którego ten blok w ogóle istnieje: gdyby przypięty był sam pasek, kliknięcie „Aa" w połowie długiej
   notatki otwierałoby panel tam, gdzie pasek stoi W UKŁADZIE — kilka ekranów wyżej. Przycisk bez
   widocznego skutku, awaria bez objawu.

   `top` to wysokość rysunku nagłówka (34 px; 44 px na telefonie, w regule poniżej 860 px). Etykiety
   i sama treść notatki zostają POZA blokiem — przewijają się, bo należą do notatki, a nie do narzędzi.
   Tytuł też: wsuwa się pod pasek i znika, co jest ceną za dwa rzędy przypięte zamiast trzech. */
.editor-bar {
    position: sticky; top: 34px; z-index: 24;
    background: var(--paper);
}

/* Pasek formatowania: same narzędzia do tekstu, bez linii pod spodem — granicę treści rysuje teraz karta
   powierzchni niżej. Działania na notatce (udostępnij, przenieś, kosz) są w menu „⋯" w nagłówku. */
.editor-toolbar {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    padding: 10px 0 4px; margin-bottom: 10px;
}
.editor-toolbar .btn { padding: 0 12px; height: 34px; font-size: 13px; }
.editor-toolbar .btn-icon { padding: 0; }

/* Rząd etykiet: pigułki bez ramki wokół całości — w spoczynku to informacja o notatce, nie formularz.
   Pole dodawania pojawia się w tym samym rzędzie po „+" (NoteEditorPage), więc rząd się zawija. */
.tag-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.tag-row .tag-row-label { font-size: 13px; color: var(--muted); margin-right: 2px; }
.tag-row .filter-chip { padding: 5px 12px; }
/* „+" wygląda jak pigułka, której jeszcze nie ma: przerywany obrys zamiast tła. */
.tag-row .tag-add { background: none; border: 1px dashed var(--line-strong); color: var(--muted); }
.tag-row .tag-add:hover { border-color: var(--accent); color: var(--accent); }
.tag-row .btn-sm { min-height: 32px; padding: 0 12px; border-radius: 999px; }

/* Lista przestrzeni docelowych pod paskiem. Zawija się, bo nazw przestrzeni bywa kilka i są dowolnej długości. */
.move-panel {
    display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
    margin-bottom: 14px; padding: 12px 14px;
    background: var(--surface-sunken); border: 1px solid var(--line); border-radius: 12px;
}
.move-panel .move-label { font-size: 13px; color: var(--muted); }
.move-panel .btn { padding: 0 12px; height: 34px; font-size: 13px; }
/* Pole adresu odnośnika. `flex: 1` z sensownym minimum: adres bywa długi, a panel ma się zawijać,
   nie rozpychać strony. */
.move-panel .link-url {
    flex: 1; min-width: 180px; height: 34px; padding: 0 12px; font: inherit; font-size: 13px;
    border: 1px solid var(--line-strong); border-radius: 9px;
    background: var(--surface); color: var(--ink);
}

/* Powierzchnia edycji. Dzieli klasę .markdown-view z podglądem CELOWO: gdyby tekst miał tu inne kroje albo
   odstępy, po zapisie „skakałby" — a cała rzecz polega na tym, że pisze się w postaci docelowej.
   Karta jak na listach (tło, ramka, promień): tekst wprost na tle strony nie mówił, gdzie kończy się interfejs,
   a zaczyna miejsce do pisania. Akcent ramki przy fokusie — jak pod tytułem. */
.editor-surface {
    min-height: 420px;
    padding: 18px 22px 40px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
    outline: none;
}
.editor-surface:focus { border-color: var(--accent); }

/* Podpowiedź na PUSTEJ powierzchni: bez niej pierwsza notatka wita taflą tła bez śladu, gdzie się pisze.
   Pseudoelement zamiast treści — wnętrza edytora nie renderuje nic poza note-editor.js (pułapka
   w docs/pulapki.md), a ::before pod :empty nie dotyka drzewa DOM i znika przy pierwszym znaku.
   Świadome ograniczenie: po wyczyszczeniu całej treści przeglądarka zostawia w środku <br>/<p>
   i :empty już nie łapie — podpowiedź jest na pierwsze otwarcie, nie na powroty. */
.editor-surface:empty::before {
    content: "Zacznij pisać…";
    color: var(--ink-4);
    pointer-events: none;
}
/* Odstęp wokół checkboxa jest CELOWO wyrażony w `em`, nie w pikselach, i CELOWO nie jest spacją w treści:
   znak spacji wpadłby do Markdowna przy zapisie, a po round-tripie (zapis → Markdig → edytor) albo by się
   podwoił, albo zniknął — odstęp należy do wyglądu, nie do treści notatki. `.28em` to szerokość spacji
   w tym kroju (zmierzone: 4,11px przy 15px), więc pozycja czyta się jak „☐ mleko" napisane z ręki
   i zostaje taka po zmianie rozmiaru tekstu. Z lewej ZERO (nie domyślne 4 px przeglądarki): pozycja zadania
   zdejmuje całe wcięcie listy (reguła niżej), więc kwadrat ma stać równo z lewą krawędzią akapitu —
   każdy piksel marginesu odsuwałby go od niej bez powodu, bo kropki listy, od której można by się odsuwać, tu nie ma. */
.editor-surface input[type="checkbox"] {
    /* 22 px i ani piksela więcej: checkbox jest częścią TREŚCI notatki, nie interfejsu, a wielkości
       przycisku zmieniałby wygląd zapisanej notatki. Brakujące do 44 px dokłada obszar dotyku pozycji
       listy, nie sam kwadrat. */
    width: 22px; height: 22px; margin-left: 0; margin-right: .28em; accent-color: var(--accent);
    /* `-4px` zamiast `-2px`: kwadrat urósł o 5 px w górę, więc bez tego środek checkboxa wyszedłby
       ponad środek wiersza tekstu. Liczba trzyma go tam, gdzie był przy 17 px. */
    cursor: pointer; vertical-align: -4px;
}

/* Miara czytania, nie miara ekranu: próbka wyglądu (panel „Aa", ekran „Konto") trzyma się 70 znaków
   w wierszu. Powierzchnia edycji tego NIE dziedziczy: tytuł notatki, pasek narzędzi i rząd etykiet nad nią
   rozciągają się na całą kolumnę `.content`, a węższa karta pod nimi wyglądała na złamany layout, nie na
   celowo węższy akapit — decyzja właściciela 2026-09-04. */
.markdown-view { max-width: 70ch; }
.editor-surface { max-width: none; }

/* Rendering Markdown. Krój i wielkość treści biorą się ze zmiennych `--note-font` / `--note-size` (blok
   przy `:root`), które ustawia wybór użytkownika — domyślnie to te same 15 px krojem bezszeryfowym, co
   wcześniej. Nagłówki notatki są mnożnikiem wielkości treści, a nie stałymi: przy „Większym" tekście
   nagłówek `h3` o stałych 18 px byłby niemal równy akapitowi i hierarchia notatki by znikła. Krój nagłówków
   zostaje szeryfowy jak w całej aplikacji — zmienia się tekst, który się czyta, nie tytuły. */
/* Krój i wielkość stoją na KONTENERZE, nie tylko na `p`/`li`: w świeżej powierzchni edycji pierwszy tekst
   jest gołym węzłem tekstowym bez akapitu (akapity dorabia dopiero round-trip przez Markdig), więc reguła
   na `p` nie objęłaby właśnie tego, co użytkownik pisze, oglądając panel „Aa" — sprawdzone w przeglądarce. */
.markdown-view { font-family: var(--note-font); font-size: var(--note-size); line-height: var(--note-lead); color: var(--ink-2); }
.markdown-view :first-child { margin-top: 0; }
.markdown-view h1 { font-size: calc(var(--note-size) * 1.87); margin: 0 0 12px; }
.markdown-view h2 { font-size: calc(var(--note-size) * 1.6); margin: 0 0 12px; }
.markdown-view h3 { font-size: calc(var(--note-size) * 1.2); margin: 0 0 12px; }
.markdown-view p, .markdown-view li { font-size: var(--note-size); line-height: var(--note-lead); color: var(--ink-2); }
/* Odstęp między blokami treści wyrażony JAWNIE, zamiast domyślnego `margin: 1em 0` przeglądarki: użytkownik
   ma nim sterować (panel „Aa"), a przy domyślnym nie było czym. Tylko od dołu — marginesy sąsiadów i tak
   zwijają się do większego z dwóch, więc jedna strona wystarcza i nie ma czego odejmować pierwszemu blokowi. */
.markdown-view p, .markdown-view ul, .markdown-view ol { margin: 0 0 var(--note-gap); }
/* Zagnieżdżona lista tego odstępu NIE dostaje. Domyślna reguła przeglądarki (`:is(ul,ol) :is(ul,ol)`) daje
   podliście zero, a reguła wyżej ma nad nią specyficzność i ją przykrywała — podpunkt odsuwał się od następnej
   pozycji tak, jak akapit od akapitu (zmierzone: 15 px wobec 0 px). Gęstość listy jest tu punktem odniesienia
   i ma zostać nietknięta przez wybór odstępów. */
.markdown-view :is(ul, ol) :is(ul, ol) { margin-bottom: 0; }
.markdown-view code { font-family: var(--mono); font-size: .9em; background: var(--chip); border-radius: 4px; padding: 1px 4px; }
.markdown-view pre { background: var(--surface-sunken); border: 1px solid var(--line); border-radius: 10px; padding: 14px; overflow: auto; }
.markdown-view pre code { background: none; padding: 0; }
.markdown-view blockquote {
    margin: 0 0 var(--note-gap); padding: 8px 14px;
    border-left: 3px solid var(--line-strong); color: var(--ink-4);
}
.markdown-view mark { background: var(--accent-soft); color: var(--accent-dark); padding: 0 2px; }
/* Listy w treści: WŁASNE wcięcie zamiast domyślnych 40 px przeglądarki. Na telefonie karta treści ma
   324–339 px i 40 px zabierało wierszowi zadania jedną piątą szerokości, zanim padł pierwszy znak.
   1.5rem (24 px) mieści kropkę i numer dwucyfrowy; ta sama liczba wraca ze znakiem minus przy zadaniu niżej. */
.markdown-view ul, .markdown-view ol { padding-left: 1.5rem; }
/* Zadania renderowane przez Markdiga niosą klasę; te dopiero co wstawione w edytorze jeszcze nie — bez
   drugiego selektora pozycja miałaby kropkę listy OBOK checkboxa, aż do pierwszego zapisu i odczytu.
   Ujemny margines zdejmuje CAŁE wcięcie listy: checkbox stoi równo z lewą krawędzią akapitu, tak jak w każdym
   edytorze z listą zadań — wcześniej −1.2rem przy 40 px wcięcia zostawiało kwadrat 25 px w głąb wiersza. */
.markdown-view li.task-list-item,
.markdown-view li:has(> input[type="checkbox"]) { list-style: none; margin-left: -1.5rem; }

.conflict {
    background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 10px;
    padding: 12px 16px; margin-bottom: 16px; color: var(--ink-2);
}

/* Notatka bez prawa zapisu: spokojniejszy niż konflikt, bo to stan trwały, a nie zdarzenie do rozwiązania. */
.read-only { margin: 0 0 12px; font-size: 13px; color: var(--muted); }

/* Start bez serwera: ten sam język co pasek konfliktu, bo mówi o tym samym — coś jest nie tak i to minie. */
.offline-bar {
    background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 10px;
    padding: 12px 16px; margin: 0 0 16px; color: var(--ink-2);
}

/* Ekran logowania układa treść w rzędzie centrowanym, a pasek ma stać NAD kartą, nie obok niej (w rzędzie
   rozciągnąłby się jeszcze na jej wysokość). Kolumna daje jedno i drugie: karta ma własne max-width, więc
   jej wygląd się nie zmienia. */
.app-plain .content { flex-direction: column; align-items: center; }
.app-plain .offline-bar { width: 100%; max-width: 360px; }

/* --- Ekran konta --- */

/* Trzy sekcje jedna pod drugą, każda jako osobna kartka: eksport i usunięcie konta to operacje różnej wagi
   i nie mają wyglądać jak dwa przyciski w jednym bloku. */
.account-section {
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
    padding: 20px 24px; margin: 0 0 20px; max-width: 640px;
}

.account-section h2 { margin: 0 0 8px; font-size: 18px; }
.account-section p { margin: 0 0 12px; }
.account-section ul { margin: 0 0 12px; padding-left: 20px; }
.account-section li { margin-bottom: 4px; }
.account-section .form-stack { max-width: 320px; }
.account-docs { margin-top: 12px; font-size: 13px; }
/* Wybór motywu: trzy przyciski w rzędzie. Zawijanie, bo najdłuższa etykieta („Za ustawieniem systemu")
   nie mieści się w rzędzie na wąskim ekranie.

   Zaznaczony wygląda jak AKTYWNA POZYCJA NAWIGACJI, a nie jak `.btn-primary`: wypełnienie akcentem znaczy
   w tym arkuszu „główna akcja ekranu" i na ekranie konta jest już zajęte przez „Pobierz moje dane".
   Dwa różne znaczenia tego samego wyglądu na jednym ekranie kasują oba. */
.theme-choice { display: flex; flex-wrap: wrap; gap: 8px; }
.theme-choice .is-selected { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600; }

/* Wiersz wyboru wyglądu: podpis + kontrolka (motyw dalej przyciskami, tekst listami). Podpis ma stałą
   szerokość, żeby wiersze zaczynały się w jednej linii; na wąskim ekranie zawija się nad kontrolkę. */
.appearance-row { display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; }
.appearance-row + .appearance-row { margin-top: 10px; }
.appearance-label { font-size: 13px; color: var(--muted); min-width: 7.5em; }
/* Lista wyboru wyglądu tekstu — wzorem `.sort-select` nad listą notatek, żeby dwie listy w tej samej
   aplikacji nie wyglądały jak z dwóch różnych. `flex: 1` z sufitem: rząd ma wypełnić panel „Aa" na telefonie,
   ale na ekranie konta lista szeroka na pół strony wyglądałaby jak pole formularza, którym nie jest. */
.appearance-select {
    flex: 1; min-width: 150px; max-width: 260px;
    height: 34px; padding: 0 8px; font: inherit; font-size: 13.5px;
    border: 1px solid var(--line-strong); border-radius: 9px;
    background: var(--surface); color: var(--ink);
}
/* Pole „własnej" liczby jest WĄSKIE celowo: wpisuje się w nie dwa–cztery znaki, a szerokie wyglądałoby na
   miejsce na zdanie. Stoi w tym samym wierszu co lista i razem z nią zawija się na telefonie. */
.appearance-number {
    width: 5em; height: 34px; padding: 0 8px; font: inherit; font-size: 13.5px; text-align: right;
    border: 1px solid var(--line-strong); border-radius: 9px;
    background: var(--surface); color: var(--ink);
}
.appearance-unit { font-size: 12.5px; color: var(--muted); }
/* Każda pozycja kroju jest napisana swoim krojem — wybór widać przed kliknięciem. */
.font-sans { font-family: var(--sans); }
.font-serif { font-family: var(--serif); }
.font-mono { font-family: var(--mono); }
/* Podgląd wyboru na ekranie „Konto". Krój, wielkość i odstępy przychodzą z klasy `markdown-view` — tu
   zostaje tylko odsunięcie od przycisków i zdjęcie marginesu ostatniego akapitu, żeby karta się nie rozjeżdżała. */
.appearance-preview { margin: 14px 0 0; }
/* Odstęp akapitowy JESZCZE RAZ, z wyższą specyficznością. Bez tego próbka na ekranie „Konto" kłamie:
   `.account-section p` (0,1,1) stoi w tym pliku PO regule `.markdown-view p` o tej samej specyficzności
   i wygrywa remis, więc oba akapity dzieliło sztywne 12 px niezależnie od wyboru — czyli dokładnie ta
   odległość, którą ta próbka ma pokazywać. Zmierzone 2026-09-03: 12 px przy 1,45, gdzie należy się 7,8 px. */
.markdown-view.appearance-preview p { margin-bottom: var(--note-gap); }
.appearance-preview p:last-child { margin-bottom: 0; }

/* Panel „Aa" pod paskiem edytora — kolumna wierszy wyboru w tej samej ramce, co pozostałe panele. */
.appearance-panel { flex-direction: column; align-items: stretch; gap: 0; }

/* Sekcja nieodwracalna dostaje obrys w rodzinie ostrzegawczej, a nie akcentowej: akcent w tym arkuszu znaczy
   „główna akcja", a tutaj chodzi o coś przeciwnego — o zatrzymanie na chwilę przed kliknięciem. */
.account-danger { border-color: var(--warn-line); background: var(--warn-bg); }
.account-danger h2 { color: var(--warn-strong); }

/* --- Wyszukiwarka --- */

.search-hit { flex-direction: column; align-items: flex-start; gap: 6px; }
.search-hit .card-title { margin-right: 0; }
.snippet { font-size: 13.5px; line-height: 1.5; color: var(--muted); }

/* --- Powiadomienia --- */

.notification.unread { border-left: 3px solid var(--accent); background: var(--accent-wash); }
.notification-body {
    border: none; background: none; text-align: left; cursor: pointer;
    font-family: var(--sans); font-size: 14px; font-weight: 400; line-height: 1.5;
    color: var(--ink-2); margin-right: auto; padding: 0;
}
.notification-body:hover { color: var(--accent); }

/* --- Udostępnianie i grupy --- */

.share-panel {
    width: 100%; margin-top: 16px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
    padding: 22px 24px;
}
.share-panel h3 { margin: 0 0 14px; font-size: 20px; }
.share-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 9px; }
.share-list li { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.share-list .subject { margin-right: auto; }

.share-form { display: flex; align-items: flex-end; gap: 8px; margin-top: 16px; padding-top: 16px; border-top: 1px dashed var(--line-strong); flex-wrap: wrap; }
.share-form .field-group { flex: 1; min-width: 150px; }
.share-form .field-group input, .share-form .field-group select { width: 100%; }
.share-form input, .share-form select {
    padding: 9px 12px; border: 1px solid var(--line-strong); border-radius: 9px;
    background: var(--surface-sunken); font-size: 13.5px;
}

.group-details { width: 100%; border-top: 1px dashed var(--line-strong); margin-top: 14px; padding-top: 14px; }
.member-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 9px; }
.member-list li { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.member-list li > span:first-child { margin-right: auto; }

/* --- Panel uwag (Etap 6) --- */

.section-label {
    font-size: 13px; font-weight: 600; color: var(--muted);
    letter-spacing: .02em; margin: 28px 0 12px;
    font-family: var(--sans); text-transform: uppercase;
}

.filter-row { display: flex; gap: 8px; margin-bottom: 18px; flex-wrap: wrap; }
.filter-chip {
    font-size: 12.5px; font-weight: 600;
    border: none; border-radius: 999px; padding: 6px 14px;
    background: var(--chip); color: var(--ink-4);
    font-family: var(--sans); cursor: pointer;
}
.filter-chip:hover { background: var(--line); }
.filter-chip.active { background: var(--ink); color: var(--surface); }

/* --- Etykiety, kolejność i strony (widok „Wszystkie notatki" oraz panel etykiet w edytorze) --- */

/* Pasek zawężania reużywa `.filter-row` i `.filter-chip` z panelu uwag CELOWO: to ten sam element interfejsu —
   zawijający się rząd „pigułek" z zaznaczonymi wyborami. Druga kopia tych reguł rozjechałaby się z pierwszą
   przy pierwszej zmianie wyglądu. Poniżej tylko to, czego tamten pasek nie potrzebował. */
.filter-row .spacer { flex: 1; }
.filter-row .sort-label { font-size: 13px; color: var(--muted); align-self: center; }

/* Pole na etykietę: ta sama wysokość i ten sam promień co „pigułki" obok, żeby rząd się nie schodkował. */
.tag-input {
    height: 32px; min-width: 150px; padding: 0 14px; font: inherit; font-size: 13px;
    border: 1px solid var(--line-strong); border-radius: 999px;
    background: var(--surface); color: var(--ink);
}

.sort-select {
    height: 32px; padding: 0 10px; font: inherit; font-size: 13px;
    border: 1px solid var(--line-strong); border-radius: 9px;
    background: var(--surface); color: var(--ink);
}

/* Etykieta przy pozycji listy jest PRZYCISKIEM (kliknięcie zawęża listę), więc zdejmujemy z niej wygląd
   przycisku i zostawiamy wygląd `.tag` — inaczej lista notatek zamieniłaby się w rząd guzików. */
.tag-btn { background: none; font-family: var(--sans); cursor: pointer; }
.tag-btn:hover { color: var(--accent); border-color: var(--accent-line); }

.pager { display: flex; align-items: center; gap: 10px; margin-top: 18px; flex-wrap: wrap; }
.pager .btn { padding: 6px 12px; }

.feedback-item { flex-direction: column; align-items: stretch; gap: 0; }
.feedback-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.feedback-body { margin: 10px 0 0; max-width: 70ch; font-size: 14px; line-height: 1.6; color: var(--ink-2); white-space: pre-wrap; }
.feedback-item.open { border-color: var(--accent); background: var(--accent-wash); }

/* Odpowiedź admina widziana przez zgłaszającego — wyróżniona „karteczka" wewnątrz wiersza. */
.admin-reply {
    margin: 12px 0 0; padding: 10px 12px;
    background: var(--warn-bg); border-left: 3px solid var(--warn-line); border-radius: 9px;
    font-size: 13.5px; line-height: 1.55; color: var(--ink-4);
}
.admin-reply strong { color: var(--warn-strong); }

/* `flex-end` od czasu, gdy pola dostały podpisy — inaczej przycisk rośnie o wysokość etykiety. */
.respond-form { display: flex; gap: 8px; align-items: flex-end; margin-top: 12px; flex-wrap: wrap; }
.respond-form .field-group { flex: 1; min-width: 200px; }
.respond-form .field-group input { width: 100%; min-width: 0; }
.respond-form select, .respond-form input {
    padding: 8px 12px; border: 1px solid var(--line-strong); border-radius: 9px;
    background: var(--surface); font-size: 13px;
}
.respond-form input { flex: 1; min-width: 200px; }

.done { color: var(--muted); text-decoration: line-through; }

/* --- Wąski ekran: nawigacja jako dolny pasek zakładek (jak w makiecie MAUI) --- */

@media (max-width: 860px) {
    .app { flex-direction: column; }
    /* Przypięty blok jest tu wyższy niż na desktopie (44 + 58 px zamiast 34 + 48), więc zapas na przewijanie
       „pokaż mi to" rośnie razem z nim — inaczej karetka ląduje kilka pikseli POD paskiem formatowania. */
    html { scroll-padding-top: 112px; }

    .sidebar {
        position: fixed; inset: auto 0 0 0;
        width: auto; height: auto;
        flex-direction: row; align-items: center;
        border-right: none; border-top: 1px solid var(--line);
        padding: 8px 6px calc(8px + env(safe-area-inset-bottom));
        z-index: 20;
    }
    /* Nawigacja jest tu dolnym paskiem zakładek — lista notatek się w nim nie mieści, więc jej rolę
       przejmuje strona przestrzeni. `.sidebar-foot` znika razem z nią, ale to, co w niej siedziało
       (zmiana hasła, wylogowanie), przenosi się pod „Więcej" — nie przepada, jak przepadało wcześniej. */
    .sidebar .brand, .sidebar-foot, .nav-divider, .nav-tag,
    .nav-section, .sidebar nav a.nav-note, .sidebar nav a.nav-more,
    .nav-space, .nav-space-loading { display: none; }

    /* Pasek ma PIĘĆ zakładek niezależnie od roli — pozycje drugoplanowe (i obie administracyjne, przez które
       pasek rósł do ośmiu) schodzą pod „Więcej". Sześć podpisów po 11 px w rzędzie nie jest nawigacją. */
    .sidebar nav a.nav-secondary { display: none; }

    /* „Udostępnione mi" łamie się w zakładce na dwie linie i podnosi CAŁY pasek o kilkanaście pikseli —
       na telefonie zostaje samo „Udostępnione", bo obok ikony i tak nie ma z czym tego pomylić.
       Sufiks siedzi w spanie WEWNĄTRZ spanu etykiety, a nie wprost w linku: pozycja menu jest kontenerem
       flex, a bezpośrednie dziecko dostałoby własny `gap` i na desktopie rozjechałoby „Udostępnione | mi". */
    .nav-long { display: none; }

    .sidebar nav { flex-direction: row; flex: 1; justify-content: space-around; gap: 0; }
    .sidebar nav a, .nav-sheet-toggle {
        display: flex; flex: 1; min-height: 44px; /* mniejszy cel dotyku to trafianie kciukiem na loterię */
        flex-direction: column; align-items: center; justify-content: center; text-align: center;
        gap: 2px; padding: 6px 4px; font-size: 11px; border-radius: 8px;
        color: var(--ink-3); position: relative;
    }
    .nav-sheet-toggle { background: none; border: none; font-family: inherit; cursor: pointer; }
    .nav-icon { display: block; width: 22px; height: 22px; }
    .nav-badge { position: absolute; top: 0; left: 50%; margin-left: 10px; }

    /* Nagłówek strony listowej: na 375 px tytuł, licznik i akcje NIE mieszczą się w jednym rzędzie —
       licznik łamał się w środku („0 / notatek"), a „Dodaj notatkę" stawał dwuliniowy. Meta schodzi
       całym rzędem POD tytuł; przycisk trzyma prawą krawędź, żeby układ czytał się jak w rzędzie wyżej. */
    .page-head { flex-wrap: wrap; row-gap: 10px; }
    .page-head .head-meta { flex-basis: 100%; }
    .page-head .head-meta .meta, .page-head .head-meta .btn, .page-head .head-meta .btn-link { white-space: nowrap; }
    .page-head .head-meta .btn { margin-left: auto; }

    /* Arkusz „Więcej": wysokość z treści, nie pełny ekran — pełnoekranowy panel na sześć pozycji wygląda
       jak osobna strona i myli, zamiast być rozwinięciem paska, nad którym stoi. */
    .sheet-backdrop {
        display: block; position: fixed; inset: 0; z-index: 30;
        background: var(--scrim);
    }
    .sheet {
        display: flex; flex-direction: column;
        position: fixed; inset: auto 0 0 0; z-index: 31;
        background: var(--surface); border-top: 1px solid var(--line);
        border-radius: 14px 14px 0 0;
        padding: 8px 8px calc(10px + env(safe-area-inset-bottom));
        box-shadow: var(--shadow-soft);
    }
    .sheet:focus { outline: none; } /* panel dostaje fokus dla Escape, obrys wokół całego arkusza tylko myli */
    .sheet-handle { width: 38px; height: 4px; border-radius: 999px; background: var(--line-strong); margin: 2px auto 10px; }
    .sheet .email { font-size: 12.5px; color: var(--muted); padding: 0 14px 8px; }
    .sheet-sep { height: 1px; background: var(--line); margin: 6px 10px; }
    .sheet a, .sheet button {
        display: flex; align-items: center; gap: 10px;
        min-height: 46px; width: 100%; padding: 10px 14px;
        border: none; border-radius: 10px; background: none;
        color: var(--ink-2); font: inherit; font-size: 15px; text-align: left; cursor: pointer;
    }
    .sheet a.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
    .sheet .nav-tag { display: inline-block; margin-left: auto; }

    .content { padding: 24px 18px 96px; }
    /* 38 px szeryfa na 375 px łamie dwuwyrazowe tytuły stron („Moje notatki") — na telefonie skala schodzi
       o stopień, zostając nagłówkiem, nie plakatem. JEDNA reguła: poprzednia wersja miała wyżej drugą
       (`32px`), którą ta nadpisywała — zmiana wyglądała na zrobioną, a nic nie robiła. */
    h1 { font-size: 30px; margin-bottom: 20px; }
    .note-title { font-size: 26px; }
    .card { padding: 16px 18px; }
    .card-title { font-size: 18px; }

    /* --- Cele dotykowe: 44 px poniżej 860 px ---

       Dwa progi, nie jeden. Na desktopie wystarczy 24 px (poniżej tego nie trafia się nawet myszą),
       a wiersz listy z trzema akcjami po 44 px byłby wysoki na 60 px i lista przestałaby być listą.
       Tutaj obsługuje się kciukiem, więc obowiązuje 44 px — ta sama liczba, którą pasek zakładek wyżej
       ma od początku.

       `.btn-link` rośnie paddingiem, a ujemny margines zdejmuje z układu dokładnie tyle, ile padding
       dołożył: pole trafienia ma 44 px, a wiersz zostaje tej samej wysokości co był. Bez tego trzy akcje
       w karcie rozepchnęłyby ją o kilkadziesiąt pikseli. */
    .btn { min-height: 44px; } /* zwykły `.btn` ma z paddingu 43 px — brakuje dokładnie jednego */
    .btn-link { min-height: 44px; padding: 10px 6px; margin-top: -10px; margin-bottom: -10px; }
    .btn-icon { width: 44px; height: 44px; }
    /* Ikona-odnośnik: 44 px pola trafienia, 24 px w układzie — jak `.btn-link` wyżej. Powtórzone, bo selektor
       dwuklasowy z reguły bazowej (−5 px) wygrałby z jednoklasowym `.btn-link` mimo media query. */
    .btn-link.btn-icon { margin-top: -10px; margin-bottom: -10px; }
    .editor-toolbar .btn, .move-panel .btn { height: 44px; }
    /* Osiem narzędzi paska (siedem formatowania plus „Aa") w JEDNYM rzędzie na 360 i 375 px: przycisk
       ikonowy ma tu 36 px RYSUNKU, a 44 px POLA DOTYKU dokłada pseudoelement (R10: cel rośnie obszarem
       dotyku, nie ramką). Rachunek: 8 × 36 + 7 × 4 = 316 px, a kolumna treści ma 324 px na 360 px
       i 339 px na 375 px. Przy 44 px rysunku siedem narzędzi mieściło się tylko od 390 px wzwyż,
       a ósme łamało pasek na trzy linie. Pasek ma TYLKO te osiem: decyzje („udostępnij", „przenieś", kosz)
       poszły do menu „⋯" w nagłówku, a stan zapisu do tego samego rzędu — drugi wiersz paska zniknął. */
    .editor-toolbar { gap: 4px; }
    .editor-toolbar .btn-icon { width: 36px; height: 36px; position: relative; }
    .editor-toolbar .btn-icon::after { content: ""; position: absolute; inset: -4px; }
    /* Przycisk „⋯" i pozycje menu — 44 px pola dotyku jak reszta celów poniżej 860 px. */
    .note-head .btn-icon { width: 44px; height: 44px; }
    /* Przypięcie paska formatowania liczy się od rysunku nagłówka, a ten ma tu 44 px zamiast 34 (cel dotyku
       wiersz wyżej). Obie liczby muszą iść parami — rozjazd daje albo prześwit z przejeżdżającą treścią,
       albo pasek nachodzący na przycisk „⋯". */
    .note-head { min-height: 44px; }
    .editor-bar { top: 44px; }
    .menu button { min-height: 46px; font-size: 15px; }
    /* Karta treści na telefonie ciaśniejsza: kolumna ma 324–339 px, a 22 px z każdej strony zabierałoby
       wierszowi tekstu jedno słowo. */
    .editor-surface { padding: 14px 14px 40px; }
    .filter-chip { min-height: 44px; }
    .tag-row .tag-add { min-height: 36px; }
    .tag-input, .sort-select { height: 44px; }
    /* Kciuk, nie kursor: te same 44 px, co pozostałe kontrolki na telefonie. */
    .appearance-select, .appearance-number { height: 44px; }
    .pager .btn { min-height: 44px; }
    .share-form input, .share-form select { min-height: 44px; }
}

#blazor-error-ui {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 50;
    background: var(--accent-soft); color: var(--accent-dark);
    padding: .8rem 1.2rem; border-top: 1px solid var(--accent);
}

/* Świeżo wystawione zaproszenie. Wyróżnione akcentem nie dla ozdoby: token widać tu jeden jedyny raz,
   a karta wyglądająca jak każda inna zachęcałaby do przewinięcia jej wzrokiem. */
.issued-invite {
    border-color: var(--accent-line);
    background: var(--accent-wash);
    display: flex;
    flex-direction: column;
    gap: .6rem;
}

.issued-invite input[readonly] {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: .85rem;
}
