/* ============================================================================
   17-czat.css — komunikator: hub wiadomości, rozmowa, edytor, szkicownik
   ----------------------------------------------------------------------------
   Dwie powierzchnie, ten SAM panel rozmowy w środku: HUB (.message-hub =
   lista/drzewo | rozmowa) oraz okno projektu (.project-chat-panel, opcjo-
   nalnie z .chat-thread-rail). Panel rozmowy = siatka 4 wierszy: tytuł | osoby |
   historia | pole pisania; historia jest JEDYNYM elementem ze scrollem, więc pole
   pisania nigdy nie ucieka. Bąbelki: cudze po lewej na powierzchni, własne po
   prawej w tonie „gotowe" (color-mix z --ok) — kolor niesie autorstwo i działa
   sam w obu motywach. Szerokości kolumn nie mają tokenów (dotyczą jednego
   komponentu) — siedzą w zmiennych lokalnych --lista-w/--watki-w.
   Rama okna, awatary, ikony i pigułki są w 05/06/07 — tu ich NIE powtarzamy.
   ============================================================================ */
/* === 1. HUB: okno — lista rozmów | rozmowa (v15-b6 CZ1, wzór 03.10.2026) ===== */
/* Pełna wysokość: lista rozmów ma sens dopiero, gdy widać ich kilkanaście. */
/* v15 b19 (ZN5): okno ma wielkość obszaru strony „Czat” ze wzoru — karta 1350 × 830 przy ekranie 1646 × 930
   (szerokość ekranu − menu 232 px − 2 × 32 px; wysokość ekranu − 40 px razem z nagłówkiem okna). Do 1180 px szerokość jak dotąd. */
.message-hub-modal { height: calc(100dvh / var(--skala-ui) - 40px); max-height: none; }
@media (min-width: 1181px) { .message-hub-modal { --okno-w: calc(100vw / var(--skala-ui) - 296px); } }
/* Dwie kolumny jak we wzorze: lista 392 px | rozmowa. Szyny ikon (Aktywność/Projekty/Osoby/Szukaj) już nie ma — zakładki
   stoją nad listą, szukajka nad zakładkami. */
.message-hub { --lista-w: 392px; flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: var(--lista-w) minmax(0, 1fr); }
/* ZK7c: bez wybranej rozmowy fokus przy otwarciu dostaje karta czatu (data-initial-focus, czat/centrum-wiadomosci.js), nie zakładka „Wszystkie” — karta bez obrysu. */
.message-hub:focus-visible { outline: 0; }
/* ZK7c (wzór .aw): awatary czatu mają obwódkę 2 px w kolorze powierzchni; cienki obrys ciemnego motywu (--avatar-obrys) zostaje na krawędzi koła, pod obwódką. */
.message-hub .avatar { --avatar-ramka: 2px; border: var(--avatar-ramka) solid var(--surface); outline-offset: -3px; }
/* === 2. HUB: lista — szukajka, zakładki, podpowiedź ======================= */
.message-hub-sidebar { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--line); background: var(--surface); }
.mh-glowa { flex: none; display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-3) var(--s-3) var(--s-2); }
.mh-glowa .mh-search { margin: 0; }
.mh-zakladki { display: flex; width: 100%; }
.mh-zakladki.segmented { gap: 3px; border-radius: var(--r); background: var(--surface-3); }
/* ZK7c (wzór .cz-zak): zakładka = jej napis z licznikiem + równa część wolnego miejsca (1 1 auto); przy równych trzecich „Wszystkie” była o 11 px za wąska. Dotyk: boki 4 px. */
.mh-zakladki > button { display: inline-flex; flex: 1 1 auto; align-items: center; justify-content: center; gap: var(--s-1); min-width: 0; padding: 0 var(--s-2); white-space: nowrap; }
:root[data-ui="tablet"] .mh-zakladki > button { padding: 0 var(--s-1); }
/* Licznik nieprzeczytanych przy zakładce — czerwone kółko jak we wzorze (w wierszach listy licznik jest w akcencie). */
.mh-licznik { display: inline-grid; place-items: center; flex: none; min-width: 18px; height: 18px; padding: 0 var(--s-1); border-radius: var(--r-pill); background: var(--danger); color: var(--text-invert); font-size: var(--t-xs); font-weight: var(--w-strong); line-height: 1; }
/* Podczas szukania zakładki przygasają (wynik zastępuje listę); klik w zakładkę czyści szukanie. */
.mh-glowa.is-szuka .mh-zakladki { opacity: .45; }
.mh-wskazowka { margin: 0; color: var(--text-faint); font-size: var(--t-xs); }
/* „Do kogo piszesz?” w miejscu rozmowy (czat/nowa-rozmowa.js): nagłówek, szukajka, lista osób przewijana. */
.mh-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--s-2) var(--s-3); padding: var(--s-4) var(--s-4) var(--s-2); }
.mh-head-tekst { flex: 1 1 160px; min-width: 0; }
.mh-nowa-wybor { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.mh-head h3 { font-size: var(--t-lg); font-weight: var(--w-bold); }
.mh-sub { color: var(--text-muted); font-size: var(--t-sm); line-height: var(--lh-base); }
/* Lupa i pole w JEDNEJ ramce — input bez własnej, inaczej powstaje ramka w ramce. */
/* b56: na komputerze szukajka miała 18 px (pole 16 px — samo pole bez wysokości, min-height: 0 niżej); teraz pole ma
   wysokość kontrolki (--h-control), a flex: none nie pozwala ramce ściskać się w kolumnie okna z długą listą osób
   (jak na telefonie w b55). */
/* ZK7c (wzór .cz-szuk): lupa 12 px od krawędzi pola, tekst 33 px (były 13 i 37 px) — stąd odstępy o 1 px różne od tokenów. */
.mh-search { flex: none; display: flex; align-items: center; gap: calc(var(--s-1) + 1px); margin: 0 var(--s-4) var(--s-2); padding: 0 var(--s-3) 0 calc(var(--s-3) - 1px); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); }
.mh-search .icon { width: 16px; height: 16px; color: var(--text-faint); }
/* `:not(...)` = podbicie szczegółowości do (0,3,1); bez tego bazowa reguła pól
   zostawia szukajce własną ramkę w środku ramki `.mh-search` — dwa pierścienie. */
.mh-search input:not([type="checkbox"]):not([type="radio"]) { flex: 1; min-height: calc(var(--h-control) - 2px); padding: 0; border: 0; border-radius: 0; background: transparent; font-weight: var(--w-regular); }
/* b56: na tablecie pole szukajki ma 44 px do stuknięcia (--h-control tabletu) — ogólna reguła dotyku z 03-kontrolki
   (0,7,1) dawała 40 px (--h-control-sm); ta sama waga pola + .mh-search wygrywa. Telefon ma własną regułę w 9-telefon/2-okna.css. */
:root[data-ui="tablet"] .mh-search input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]) { min-height: var(--h-control); margin-block: -1px; }   /* ZK4: pole 44 px — zachodzi na kreski ramki */
.message-hub-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 0 var(--s-2) var(--s-3); }   /* v15-b6: zaznaczenie wiersza nie dotyka krawędzi */
/* === 3. HUB: drzewo wątków, osoby, aktywność ============================== */
/* Pozycje wszystkich list (drzewo, osoby, wątki, aktywność) reagują tak samo — jedna reguła zamiast powtarzania jej przy każdym komponencie z osobna. */
.message-hub-conversation:hover, .message-hub-contact:hover, .message-hub-thread-child:hover, .hub-act-row:hover, .chat-thread-item:hover { background: var(--surface-3); }
.message-hub-conversation.is-active, .message-hub-contact.is-active, .message-hub-thread-child.is-active, .thread-people-option.is-selected, .chat-recipient-option.is-selected { background: var(--accent-soft); }
/* v15-b6 CZ4 (wzór 03.10.2026): wiersze list bez kresek, zaokrąglone podświetlenie, licznik w akcencie.
   Strzałka rozwijania to ODDZIELNY przycisk obok pozycji: klik w nazwę otwiera rozmowę, klik w strzałkę tylko rozwija gałąź etapów. */
.message-hub-tree-node + .message-hub-tree-node { margin-top: var(--s-1); }
.message-hub-tree-row { display: grid; grid-template-columns: 28px minmax(0, 1fr); align-items: start; min-width: 0; }
.message-hub-twisty { display: grid; place-items: center; width: 28px; height: 28px; margin-top: var(--s-2); border-radius: var(--r-sm); color: var(--text-muted); cursor: pointer; }
.message-hub-twisty:not(.is-empty):hover { background: var(--surface-3); }
.message-hub-twisty.is-empty { cursor: default; }
.message-hub-twisty .icon { transition: transform var(--szybko) ease; }
.message-hub-twisty.is-open .icon { transform: rotate(90deg); }
.message-hub-conversation, .message-hub-contact { display: grid; gap: 3px; width: 100%; min-width: 0; padding: var(--s-2); border-radius: var(--r); text-align: left; cursor: pointer; }
.message-hub-contact { grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: var(--s-3); min-height: 56px; }
.message-hub-contact > .avatar { --avatar-d: 36px; font-size: var(--t-base); font-weight: var(--w-strong); }   /* ZK7c: inicjały jak na liście „Wszystkie” (wzór 14/700) */
.message-hub-conv-top, .message-hub-contact-top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); min-width: 0; }
.message-hub-conv-top strong, .message-hub-contact-top strong { min-width: 0; overflow: hidden; font-weight: var(--w-medium); text-overflow: ellipsis; white-space: nowrap; }
.message-hub-conv-top .mh-proj-nr { font-weight: var(--w-bold); }
/* POPR-n15: „Pokaż wszystkie projekty (N)” pod listą rozmów projektów (i „Pokaż starsze” we „Wszystkich”). */
.message-hub-pokaz-wszystkie { display: flex; align-items: center; justify-content: center; width: 100%; height: var(--h-control); margin: var(--s-2) 0 0; border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); color: var(--accent-strong); font-size: var(--t-sm); font-weight: var(--w-bold); cursor: pointer; }
.message-hub-pokaz-wszystkie:hover { background: var(--accent-soft); }
/* Tablet: pełna nazwa projektu zamiast wielokropka (na dotyku nie ma dymka). */
:root[data-ui="tablet"] .message-hub-conv-top strong { white-space: normal; overflow-wrap: anywhere; }
.message-hub-conversation.has-unread strong, .message-hub-contact.has-unread strong { font-weight: var(--w-bold); }
.message-hub-conv-prev, .message-hub-contact-prev { min-width: 0; overflow: hidden; color: var(--text-muted); font-size: var(--t-sm); text-overflow: ellipsis; white-space: nowrap; }
.message-hub-conv-prev em { color: var(--text); font-style: normal; font-weight: var(--w-bold); }
.message-hub-conv-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); min-width: 0; }
.message-hub-conv-meta time, .message-hub-contact-top time { flex: none; color: var(--text-muted); font-size: var(--t-xs); font-variant-numeric: tabular-nums; white-space: nowrap; }
.message-hub-contact.has-unread .message-hub-contact-top time { color: var(--accent-strong); font-weight: var(--w-bold); }
.message-hub-badge, .chat-thread-badge { display: grid; place-items: center; flex: none; min-width: var(--s-5); height: var(--s-5); padding: 0 var(--s-1); border-radius: var(--r-pill); background: var(--accent); color: var(--on-accent); font-size: var(--t-xs); font-weight: var(--w-strong); }
.hub-act-row .message-hub-badge { min-width: 20px; height: 20px; }
.hub-act-sect .message-hub-badge { min-width: 18px; height: 18px; font-weight: var(--w-heavy); }   /* wzór: licznik sekcji najgrubszym pismem */
.message-hub-thread-children { display: flex; flex-direction: column; margin: 0 0 var(--s-2) 42px; padding-left: var(--s-2); border-left: 1px solid var(--line); }
.message-hub-thread-child { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; align-items: center; gap: var(--s-2); width: 100%; min-height: 40px; padding: var(--s-1) var(--s-2); border-radius: var(--r-sm); text-align: left; cursor: pointer; }
.message-hub-thread-child-copy { display: grid; min-width: 0; }
.message-hub-thread-child-name, .message-hub-thread-child-prev { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.message-hub-thread-child-name { font-size: var(--t-sm); font-weight: var(--w-medium); }
.message-hub-thread-child.has-unread .message-hub-thread-child-name { font-weight: var(--w-bold); }
.message-hub-thread-child-prev { color: var(--text-muted); font-size: var(--t-xs); }
.message-hub-add-thread { display: inline-flex; align-self: flex-start; align-items: center; gap: var(--s-2); min-height: 36px; padding: 0 var(--s-2); border-radius: var(--r-sm); color: var(--accent-strong); font-size: var(--t-sm); font-weight: var(--w-bold); cursor: pointer; }
.message-hub-add-thread:hover { background: var(--accent-soft); }
/* v15-b6 CZ2: „Wszystkie” jak we wzorze — sekcje „Nieprzeczytane” (akcent, z licznikiem) i „Przeczytane”, wiersz 36 px awatar/kropka |
   nazwa + godzina, podgląd „Etap: treść” | licznik. Przeczytane nie są już półprzezroczyste — różni je grubość napisu. */
/* odstęp przed licznikiem = 4 px + szerokość spacji (.28em), jak we wzorze („Nieprzeczytane <b>3</b>”) */
.hub-act-sect { display: flex; align-items: center; gap: calc(var(--s-1) + .28em); padding: var(--s-3) var(--s-2) var(--s-1); color: var(--text-faint); font-size: var(--t-xs); font-weight: var(--w-strong); }
.hub-act-sect.is-nowe { color: var(--accent-strong); }
.hub-act-row { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: var(--s-3); width: 100%; min-height: 56px; padding: var(--s-2); border-radius: var(--r-sm); text-align: left; cursor: pointer; }
.hub-act-row.is-active { background: var(--accent-soft); }
.hub-act-row > .avatar { --avatar-d: 36px; font-size: var(--t-base); font-weight: var(--w-strong); }
.hub-act-kropka { display: grid; place-items: center; width: 36px; }
/* Kolor kropki podaje JS zmienną --dot (ton etapu), stąd wartość zastępcza. */
.hub-act-dot { flex: none; width: 9px; height: 9px; border-radius: var(--r-pill); background: var(--dot, var(--text-faint)); }
.hub-act-c { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hub-act-top { display: flex; align-items: baseline; gap: var(--s-2); min-width: 0; }
.hub-act-nazwa { flex: 1 1 auto; min-width: 0; overflow: hidden; font-weight: var(--w-medium); text-overflow: ellipsis; white-space: nowrap; }
.hub-act-row.is-nowe .hub-act-nazwa { font-weight: var(--w-strong); }
.hub-act-row.is-read .hub-act-nazwa { color: var(--text-muted); }
.hub-act-top time { flex: none; margin-left: auto; color: var(--text-faint); font-size: var(--t-xs); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hub-act-row.is-nowe .hub-act-top time { color: var(--accent-strong); font-weight: var(--w-strong); }
.hub-act-prev { min-width: 0; overflow: hidden; color: var(--text-faint); font-size: var(--t-sm); text-overflow: ellipsis; white-space: nowrap; }
.hub-act-row.is-nowe .hub-act-prev { color: var(--text-muted); }
.hub-act-prev i { color: var(--text-muted); font-style: normal; font-weight: var(--w-bold); }
.hub-act-ok { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-3) var(--s-3); color: var(--text-muted); font-size: var(--t-sm); }
.hub-act-ok .icon { color: var(--ok-strong); }
/* === 4. Panel rozmowy i belka wątków ===================================== */
.message-hub-thread { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.message-hub-placeholder, .message-hub-empty { display: grid; place-items: center; height: 100%; max-width: 340px; margin-inline: auto; padding: var(--s-5); color: var(--text-muted); text-align: center; }   /* wzór: napis w dwóch wyśrodkowanych liniach */
/* v15-b6 CZ5 (wzór 03.10.2026): JEDEN nagłówek rozmowy — z lewej tytuł i pod nim „Wiadomości: N”, z prawej awatary, „N os. ⚙” i kosz
   (dawniej osoby w osobnym rzędzie pod tytułem). Bez zmiany znaczników: tytuł i osoby stoją w pierwszym rzędzie siatki obok siebie. */
.project-chat-panel { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto minmax(0, 1fr) auto; min-height: 0; background: var(--surface); }
.message-hub-thread > .project-chat-panel { height: 100%; }
/* Rozmowa w oknie „Wiadomości” (wzór .cz-rg / .cz-m / .cz-pisz): tytuł tytułowym krojem, awatary 26 i 28 px, pole pisania z odstępem 16 px,
   pasek edytora jak w Notatkach (przyciski 32 px bez ramek, „Obraz” z napisem). */
.message-hub-thread .project-chat-title span:first-child { font-family: var(--font-tytul); }
.message-hub-thread .project-chat-title span:last-child { color: var(--text-faint); }
.message-hub-thread .project-chat-people .avatar.small-avatar { --avatar-d: 26px; font-weight: var(--w-strong); }
/* ZK7c (wzór .cz-rg, .cz-stos): nagłówek rozmowy — 12 px między tytułem, awatarami i „N os.”; awatary zachodzą na siebie o 6 px (oddziela je obwódka); trybik 15 px. */
.message-hub-thread .project-chat-title { padding-right: var(--s-3); }
.message-hub-thread .project-chat-people { gap: var(--s-3); }
.message-hub-thread .project-chat-people :is(.project-people-summary, .avatar-stack) { gap: 0; }   /* pusta druga kolumna siatki podsumowania odsuwała awatary o 8 px */
.message-hub-thread .project-chat-people .avatar-stack .avatar { box-shadow: none; }
.message-hub-thread .project-chat-people .avatar-stack .avatar + .avatar { margin-left: -6px; }
.message-hub-thread .chat-thread-manage .icon { width: 15px; height: 15px; }
/* ZK7c (wzór .cz-m): limit 78 % / 640 px ma cała wiadomość (awatar + dymek), nie sam dymek (był o 36 px szerszy niż we wzorze); awatar 2 px nad dołem dymka. */
.message-hub-thread .chat-message { justify-self: start; max-width: min(78%, 640px); }
.message-hub-thread .chat-message.own { justify-self: end; }
.message-hub-thread .chat-message > .avatar { --avatar-d: 28px; margin-bottom: 2px; font-weight: var(--w-strong); }
.message-hub-thread .chat-bubble { max-width: none; }
/* ZK7c (wzór .cz-pisz): pod edytorem 20 px (było 12 — obszar pisania 136 zamiast 144 px); podpowiedź „Widzą i dostają…”: wiersz 1,4, szara ikona 15 px. */
.message-hub-thread .project-chat-compose { padding: var(--s-2) var(--s-4) calc(var(--s-3) + var(--s-2)); }
.message-hub-thread .chat-public-note { line-height: 1.4; }
.message-hub-thread .chat-public-note .icon { width: 15px; height: 15px; margin-top: 2px; color: var(--text-faint); }
.message-hub-thread .chat-rich-editor.rich-editor { border-radius: var(--r); }
/* Wzór .cz-ed:focus-within — podczas pisania ramka edytora w akcencie z miękką poświatą. */
.message-hub-thread .chat-rich-editor.rich-editor:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.message-hub-thread .chat-rich-editor .rich-toolbar { gap: 2px; border-bottom-color: var(--line-soft); }
.message-hub-thread .chat-rich-editor .rich-toolbar :is(button, .rich-image-button, .rich-attach-button) { gap: var(--s-1); min-width: 32px; height: 32px; border: 0; color: var(--text-muted); font-size: var(--t-base); font-weight: var(--w-regular); }
/* Listy „Tekst” i „Skala” jak we wzorze (.cz-nar select): natywna strzałka, bez ramki, odstęp 0 4 px. */
.message-hub-thread .chat-rich-editor .rich-toolbar select { height: 32px; min-height: 32px; padding: 0 var(--s-1); border: 0; border-radius: var(--r-sm); background: transparent; box-shadow: none; appearance: auto; color: var(--text-muted); font-weight: var(--w-regular); }
.message-hub-thread .chat-rich-editor .rich-toolbar select:hover { background: var(--surface-3); }
.message-hub-thread .chat-rich-editor .rich-toolbar .icon { width: 16px; height: 16px; }   /* wzór: ikony paska 16 px */
.message-hub-thread .chat-rich-editor .rich-toolbar .rich-image-button:not(.rich-attach-button) { gap: var(--s-1); padding: 0 var(--s-1); }
.message-hub-thread .chat-rich-editor .rich-toolbar .rich-image-button:not(.rich-attach-button) > span:not(.icon) { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
.message-hub-thread .chat-rich-editor .rich-editable { min-height: 72px; }
/* Z belką wątków panel jest dwukolumnowy: belka + ta sama siatka 4 wierszy obok. */
.project-chat-panel.has-thread-rail { display: flex; min-width: 0; }
.project-chat-main { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto minmax(0, 1fr) auto; flex: 1 1 auto; min-width: 0; }
:is(.project-chat-panel, .project-chat-main) > :is(.project-chat-history, .project-chat-compose, .project-chat-empty) { grid-column: 1 / -1; }
.project-chat-title { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; min-height: 64px; padding: var(--s-2) var(--s-2) var(--s-2) var(--s-4); border-bottom: 1px solid var(--line); background: var(--surface); }
.project-chat-title span:first-child { overflow: hidden; font-size: var(--t-md); font-weight: var(--w-bold); text-overflow: ellipsis; white-space: nowrap; }
.project-chat-title span:last-child { color: var(--text-muted); font-size: var(--t-xs); }
.project-chat-people { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-2); padding: var(--s-2) var(--s-3) var(--s-2) 0; border-bottom: 1px solid var(--line); background: var(--surface); }
/* Osoby rozmowy stoją obok siebie (ergonomia E1, 26.09): nachodzące kółka zasłaniały drugą literę inicjałów („B”, „A”). */
.project-chat-people .avatar-stack { gap: 2px; }
.project-chat-people .avatar-stack .avatar + .avatar { margin-left: 0; }
/* min-height:0 odblokowuje scroll historii w siatce — bez tego rośnie cały panel. */
.project-chat-history { display: grid; align-content: start; gap: var(--s-3); min-height: 0; overflow: auto; padding: var(--s-4) var(--s-5); background: var(--surface-2); }
.project-chat-empty { align-self: center; justify-self: center; max-width: 40ch; color: var(--text-muted); text-align: center; }
/* z-index nad historią: rozwijane listy odbiorców i emoji mają ją zasłaniać. */
.project-chat-compose { position: relative; z-index: 2; display: grid; gap: var(--s-2); padding: var(--s-2); border-top: 1px solid var(--line); background: var(--surface); }
/* v15-b6 CZ6 (decyzja właściciela 5): „Wyślij” = okrągły przycisk ze strzałką w prawym dolnym rogu pola wiadomości (jak SMS) —
   pole (.chat-pole) trzyma edytor i przycisk; tekst ma z prawej miejsce na kółko. Tablet i telefon: 44 px. */
/* ZK7c (wzór .cz-edw, .cz-wy): kółko 8 px od WEWNĘTRZNEJ krawędzi ramki edytora (było 7), tekst kończy się 8 + 12 px przed nim. Średnica --wyslij: 38 px, dotyk 44 px. */
.chat-pole { --wyslij: 38px; position: relative; min-width: 0; }
:root:not([data-ui="desktop"]) .chat-pole { --wyslij: 44px; }
.chat-pole .chat-rich-editor .rich-editable { padding-right: calc(var(--wyslij) + var(--s-3) + var(--s-2) * 2); }
.chat-wyslij { position: absolute; right: calc(var(--s-2) + 1px); bottom: calc(var(--s-2) + 1px); z-index: 1; display: grid; place-items: center; width: var(--wyslij); height: var(--wyslij); border: 0; border-radius: var(--r-pill); background: var(--accent); color: var(--on-accent); cursor: pointer; transition: transform var(--szybko) ease-out, filter var(--szybko) ease-out; }
.chat-wyslij:hover { filter: brightness(1.08); }
.chat-wyslij:active { transform: scale(.94); }
.chat-wyslij:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
/* Rysunek .icon-send wypełnia 20 z 24 jednostek pola, we wzorze 16 z 24 przy ikonie 18 px — ikona 15 px daje ten sam rozmiar samolotu (przy 18 px był wyraźnie większy). */
.chat-wyslij .icon { width: 15px; height: 15px; }
/* Powiększone pole (przelaczPowiekszenieCzatu): historia znika, pisanie zajmuje całą rozmowę. */
.project-chat-panel.is-pelny :is(.project-chat-history) { display: none; }
.project-chat-panel.is-pelny .project-chat-compose { display: flex; flex-direction: column; min-height: 0; }
.project-chat-panel.is-pelny .chat-pole { display: flex; flex: 1 1 auto; min-height: 0; }
.project-chat-panel.is-pelny .chat-pole > .rich-editor { flex: 1 1 auto; }
.project-chat-panel.is-pelny .chat-rich-editor .rich-editable { max-height: none; }
.chat-public-note { display: flex; align-items: flex-start; gap: var(--s-2); color: var(--text-muted); font-size: var(--t-sm); }
.chat-public-note .icon { flex: none; color: var(--accent-strong); }
.chat-thread-rail { --watki-w: 172px; display: flex; flex-direction: column; flex: 0 0 var(--watki-w); min-height: 0; border-right: 1px solid var(--line); background: var(--surface-2); }
.chat-thread-rail-head { display: flex; align-items: center; justify-content: space-between; min-height: var(--h-control); padding: 0 var(--s-1) 0 var(--s-3); border-bottom: 1px solid var(--line); color: var(--text-muted); font-size: var(--t-xs); font-weight: var(--w-bold); }
.chat-thread-rail-list { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--s-2); }
.chat-thread-item { display: flex; align-items: center; gap: var(--s-2); width: 100%; padding: var(--s-1) var(--s-2); border-radius: var(--r-sm); font-weight: var(--w-medium); text-align: left; cursor: pointer; }
.chat-thread-item.is-active { background: var(--accent-soft); color: var(--accent-strong); }
.chat-thread-item.has-unread { font-weight: var(--w-bold); }
.chat-thread-dot { flex: none; width: var(--s-2); height: var(--s-2); border-radius: var(--r-pill); background: var(--dot, var(--text-faint)); }
.chat-thread-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* „N os. ⚙” — pigułka z obrysem w akcencie (wzór), kosz własnego wątku — okrągła ikona w kolorze ostrzeżenia. */
.chat-thread-manage { display: inline-flex; flex: none; align-items: center; gap: var(--s-1); height: 32px; padding: 0 var(--s-3); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); border-radius: var(--r-pill); background: var(--surface); color: var(--accent-strong); font-size: var(--t-sm); font-weight: var(--w-bold); white-space: nowrap; cursor: pointer; }
.chat-thread-manage:hover { background: var(--accent-soft); }
.chat-thread-delete { display: inline-grid; flex: none; place-items: center; width: 32px; height: 32px; border-radius: var(--r-pill); color: var(--danger); cursor: pointer; }
.chat-thread-delete:hover { background: var(--danger-soft); }
.thread-people-list { display: grid; gap: 2px; max-height: calc(50vh / var(--skala-ui)); overflow-y: auto; }
.thread-people-option { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-1) var(--s-2); border-radius: var(--r-sm); cursor: pointer; }
.thread-people-option:hover { background: var(--surface-2); }
.thread-people-name { display: flex; flex-direction: column; line-height: var(--lh-tight); }
.thread-people-name small, .thread-people-hint { color: var(--text-muted); font-size: var(--t-xs); }
/* === 5. Bąbelki wiadomości i cytowanie =================================== */
/* Własne = ten sam wiersz odwrócony (row-reverse): bąbelek sam ląduje przy właściwej krawędzi, bez drugiej siatki i bez przestawiania kolumn. */
.chat-message { display: flex; align-items: flex-end; gap: var(--s-2); max-width: 100%; scroll-margin: var(--s-6); }
.chat-message.own { flex-direction: row-reverse; }
/* W2 (27.09.2026): jeden dymek na komputerze i telefonie — zaokrąglony, „ogonek” (mały róg) na dole od strony nadawcy,
   bez cienia; własne w jasnym akcencie (na komputerze były zielone z ogonkiem u góry, na telefonie niebieskie z ogonkiem
   u dołu). Zieleń w programie znaczy „w porządku / zysk”, nie „moja wiadomość”. */
/* v15-b6 CZ5 (wzór): cudzy dymek biały z cienką ramką, własny w tle akcentu bez ramki, zaokrąglenie 12 px bez „ogonka”. */
.chat-bubble { position: relative; max-width: min(78%, 640px); min-width: calc(var(--s-7) + var(--s-2)); padding: var(--s-2) var(--s-3); border: 1px solid var(--line-soft); border-radius: var(--r); background: var(--surface); box-shadow: none; }
.chat-message.own .chat-bubble { border-color: transparent; background: var(--accent-soft); }
.chat-message.is-system .chat-bubble { border: 1px dashed color-mix(in srgb, var(--accent) 35%, transparent); }
.chat-message.is-pending { opacity: .65; }
/* wysyłka jeszcze trwa */
.chat-message.is-failed .chat-bubble { border: 1px solid var(--danger); }
.chat-message.is-highlighted .chat-bubble { box-shadow: 0 0 0 var(--s-1) var(--accent-soft); }
.chat-sender { margin-bottom: 2px; color: var(--accent-strong); font-size: var(--t-sm); font-weight: var(--w-bold); }
.chat-text { line-height: var(--lh-base); white-space: pre-wrap; word-break: break-word; }
.chat-text img { max-width: 100%; height: auto; border-radius: var(--r-sm); }
.chat-text a { color: var(--accent-strong); }
.chat-text code { padding: 0 var(--s-1); border-radius: var(--r-sm); background: var(--surface-3); font-family: var(--font-mono); white-space: pre-wrap; word-break: break-word; }
.chat-text blockquote { padding-left: var(--s-2); border-left: 3px solid var(--accent); color: var(--text-muted); }
/* WYCIĘTE 11.08.2026: `.chat-drawing`, `.chat-drawing-badge` — pasek
   „Edytowany przez…" doklejany nad rysunkiem w czacie. Był widoczny wyłącznie
   w wysłanej wiadomości, więc w oknie pisania i po pobraniu pliku podpisu nie
   było wcale. Podpis jest teraz wtopiony w sam obrazek przy eksporcie
   (public/js/okna/, `sketchStampLabel`), więc markup tych klas już nie
   powstaje. */
/* Wyciete 11.08.2026 — martwe reguly, zero wystapien w public/js. Szczegoly: AUDYT-CSS-2026-08-11.md B9. */
.chat-stamp { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-1); margin-top: 2px; color: var(--text-faint); font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
.chat-tick { letter-spacing: -1.5px; }
/* dwa ptaszki mają się zazębiać */
.chat-tick.is-read { color: var(--accent-strong); }
.chat-failed-note { color: var(--danger); font-size: var(--t-xs); font-weight: var(--w-bold); }
/* Akcje bąbelka (odpowiedz, zleć zadanie) — dopiero pod kursorem, żeby nie zaśmiecać historii; focus-within zostawia je dostępne z klawiatury. */
/* Wzór: akcje to okrągłe przyciski NAD dymkiem (nie zasłaniają treści). */
.chat-bubble-actions { position: absolute; top: calc(var(--s-4) * -1); right: var(--s-2); display: flex; gap: var(--s-1); opacity: 0; transition: opacity var(--szybko) ease; }
.chat-message:hover .chat-bubble-actions, .chat-bubble-actions:focus-within { opacity: 1; }
.chat-act-btn { display: grid; place-items: center; width: 30px; height: 30px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--surface); color: var(--text-muted); box-shadow: var(--cien-1); cursor: pointer; }
.chat-act-btn:hover { border-color: var(--accent-strong); color: var(--accent-strong); }
/* „Edytuj rysunek” — miękki przycisk pod rysunkiem (wzór), nie sam napis. */
.chat-edit-drawing { display: inline-flex; align-items: center; gap: var(--s-1); height: 32px; margin-top: var(--s-2); padding: 0 var(--s-3); border-radius: var(--r); background: var(--btn-2); color: var(--accent-strong); font-size: var(--t-sm); font-weight: var(--w-bold); cursor: pointer; }
.chat-edit-drawing:hover { background: var(--btn-2-hover); }
/* Cytat w bąbelku i zapowiedź odpowiedzi nad polem pisania — ten sam wzór: pasek akcentu z lewej, autor pogrubiony, treść ucięta do jednej linii. */
.chat-quote, .chat-reply-preview { display: grid; gap: 1px; width: 100%; margin-bottom: var(--s-1); padding: var(--s-1) var(--s-2); border-left: 3px solid var(--accent); border-radius: var(--r-sm); background: var(--accent-soft); font-size: var(--t-sm); text-align: left; cursor: pointer; }
.chat-reply-preview { grid-template-columns: minmax(0, 1fr) auto; align-items: center; cursor: auto; }
.chat-quote-author, .chat-reply-author { color: var(--accent-strong); font-weight: var(--w-bold); }
.chat-quote-text, .chat-reply-text { overflow: hidden; color: var(--text-muted); text-overflow: ellipsis; white-space: nowrap; }
.chat-reply-body { display: grid; min-width: 0; }
.chat-reply-bar { display: none; }
/* pasek rysuje już border-left */
.chat-reply-cancel { display: grid; place-items: center; width: var(--s-5); height: var(--s-5); border-radius: var(--r-pill); color: var(--danger); cursor: pointer; }
.chat-reply-cancel:hover { background: var(--danger-soft); }
/* === 6. Załączniki, odbiorcy, wzmianki =================================== */
/* v15-b6 CZ5 (wzór): załączniki jako „pigułki” obok siebie — miniatura 44×32 albo ikona pliku, „Załącznik N”. */
.chat-attachments { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-2); }
.chat-attachment-menu { position: relative; min-width: 0; }
/* kotwica dla menu poniżej */
.chat-attachment { display: inline-flex; align-items: center; gap: var(--s-2); min-height: 36px; padding: var(--s-1) var(--s-3) var(--s-1) var(--s-1); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); font-size: var(--t-sm); font-weight: var(--w-bold); list-style: none; cursor: pointer; }
.chat-attachment > .icon { width: 18px; height: 18px; margin-left: var(--s-1); color: var(--text-faint); }   /* wzór .cz-zl summary .ic */
.chat-attachment::-webkit-details-marker { display: none; }
/* własna strzałka, nie systemowa */
.chat-attachment:hover { border-color: var(--accent-strong); background: var(--surface); }
.chat-attachment.missing:hover { border-color: var(--danger); background: var(--danger-soft); color: var(--danger); }
.chat-attachment img { width: 44px; height: 32px; border-radius: 4px; object-fit: cover; }
/* ZK7c (wzór .cz-zl-m): menu załącznika — karta 140 px z odstępem 4 px, pozycje 36 px (dotyk 44 px) zwykłym pismem, bez kresek. */
.chat-attachment-panel { position: absolute; top: calc(100% + var(--s-1)); left: 0; z-index: 3; display: grid; min-width: 140px; padding: var(--s-1); overflow: hidden; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); box-shadow: var(--cien-2); }
.chat-attachment-action { display: flex; align-items: center; min-height: 36px; padding: 0 var(--s-3); border-radius: var(--r-sm); color: var(--text); font-size: var(--t-sm); white-space: nowrap; }
.chat-attachment-action:hover { background: var(--surface-3); text-decoration: none; }
/* Pliki wybrane przed wysłaniem — pusty kontener znika, żeby nie zjadał miejsca. */
.chat-pending-files { display: grid; gap: var(--s-1); padding: var(--s-2); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2); }
.chat-pending-files:empty { display: none; }
.chat-pending-head { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; color: var(--text-muted); font-size: var(--t-xs); font-weight: var(--w-bold); }
.chat-pending-list { display: grid; gap: var(--s-1); }
.chat-pending-file { display: grid; grid-template-columns: var(--s-4) minmax(0, 1fr) auto auto; align-items: center; gap: var(--s-2); padding: var(--s-1); border-radius: var(--r-sm); background: var(--surface); }
.chat-pending-name { min-width: 0; overflow: hidden; font-size: var(--t-sm); text-overflow: ellipsis; white-space: nowrap; }
.chat-pending-size { color: var(--text-muted); font-size: var(--t-xs); white-space: nowrap; }
.chat-recipient-field, .chat-recipient-picker { display: grid; gap: var(--s-1); min-width: 0; }
.chat-selected-recipients { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.chat-recipient-chip { display: inline-flex; align-items: center; gap: var(--s-1); padding-right: var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface); font-size: var(--t-sm); }
.chat-recipient-list { display: grid; max-height: calc(var(--h-row) * 4); overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); }
/* Pozycja listy odbiorców i podpowiedzi @ wygląda tak samo — wiersz z awatarem. */
.chat-recipient-option, .chat-mention-option { display: flex; align-items: center; gap: var(--s-2); width: 100%; padding: var(--s-1) var(--s-2); border-radius: var(--r-sm); text-align: left; cursor: pointer; }
.chat-recipient-option:hover, .chat-mention-option:hover, .chat-mention-option.is-active { background: var(--surface-2); }
.chat-recipient-copy, .chat-mention-copy { display: flex; flex-direction: column; min-width: 0; }
.chat-mention-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-mention-copy small, .chat-recipient-empty, .chat-recipient-empty-chip { color: var(--text-muted); font-size: var(--t-xs); }
/* Wzmianki @: JS liczy pozycję kursora i ustawia top/left — stąd position: fixed. */
.chat-mention-dropdown { position: fixed; z-index: var(--z-dymek); width: 280px; max-height: calc(var(--h-row) * 6); overflow-y: auto; padding: var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); box-shadow: var(--cien-3); }
/* === 7. Edytor: pasek formatowania i panel emoji ========================= */
/* W1: w oknie edytor wygląda jak pole okna (zmienne --okno-pole-*, 05-komponenty §3); poza oknem bez zmian. */
.rich-editor { position: relative; display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; min-height: 0; overflow: hidden; border: 1px solid var(--okno-pole-ramka, var(--pole-ramka)); border-radius: var(--okno-pole-r, var(--r)); background: var(--okno-pole-tlo, var(--pole-tlo)); box-shadow: var(--okno-pole-obrys, none); }
.rich-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1); padding: var(--s-1); border-bottom: 1px solid var(--line); background: var(--surface-2); }
/* Przyciski paska są NISKIE (h-control-sm) — pasek nie ma dominować nad treścią. */
/* `gap` jest tu KONIECZNY. „Obraz" to jedyny przycisk paska, który ma ikonę
   ORAZ napis — bez odstępu ikona przyklejała się do słowa i ten jeden guzik
   wyglądał inaczej niż cała reszta. Odstęp jest ten sam co między ikoną
   a tekstem w przyciskach całej aplikacji (`.button` w arkuszu 03). */
/* NAPRAWA 11.08.2026 — pasek narzędzi edytora łamał się na DWA rzędy.
   Zmierzone: w kolumnie opisu (554 px) miał 67 px wysokości, a ten sam pasek
   w czacie (961 px) — 36 px. Ta sama liczba przycisków, dwie wysokości.
   Pasek dostał wtedy przewijanie w poziomie zamiast zawijania.
   OSTATECZNIE (po przeklikaniu wszystkich okien): przewijanie USUNIĘTE,
   wraca zawijanie z reguły bazowej. Ten sam edytor stoi też w panelach
   BARDZO wąskich — panel boczny Bloków ma 318 px, panel Ekip 218 px — a pasek
   potrzebuje 504. Tam żadne zwężanie przycisków nie pomoże i przy `nowrap`
   połowa narzędzi chowała się za poziomym paskiem przewijania WEWNĄTRZ pola
   formularza. Zawinięty pasek jest brzydszy niż jednorzędowy, ale schowane
   narzędzie jest gorsze od obu. Pierwotny problem („ten sam pasek raz 36 px,
   raz 67") rozwiązują kwadratowe przyciski 27×27 wprowadzone niżej: pasek
   potrzebuje teraz 504 zamiast 533 px i w każdej kolumnie ≥ 510 px mieści się
   w jednym rzędzie samoistnie. */
/* NAPRAWA 11.08.2026 — `flex: none`.
   Kontrolki paska są elementami flex, a domyślne `flex-shrink: 1` pozwalało im
   kurczyć się PONIŻEJ własnej treści. Zmierzone w oknie Gwarancji: przycisk
   „Obraz" miał 30 px szerokości, a jego zawartość (ikona 13 + napis 34 +
   odstęp 8) potrzebuje 55 — napis był ucięty do „Obra". Ten sam przycisk
   w szerszym pasku czatu wyświetlał się w całości, więc dwa identyczne paski
   w JEDNYM oknie pokazywały co innego. */
/* Wyściółka --s-1, nie --s-2: przy 8 px z każdej strony przycisk z ikoną 13 px
   wychodził 31 px szeroki przy 27 px wysokości — NIE był kwadratem, a pasek
   przez to potrzebował 533 px zamiast dostępnych 514. Przy 4 px szerokość
   spada poniżej `min-width`, więc wszystkie przyciski ikonowe są dokładnie
   kwadratem 27×27, a pasek mieści się w jednym rzędzie bez przewijania. */
.rich-toolbar button, .rich-image-button { display: inline-flex; flex: none; align-items: center; justify-content: center; gap: var(--s-2); min-width: var(--h-control-sm); height: var(--h-control-sm); padding: 0 var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); color: var(--text); font-size: var(--t-sm); font-weight: var(--w-bold); cursor: pointer; }
/* NAPRAWA 11.08.2026 — napis „Obraz" schowany: w pasku samych ikon był
   JEDYNYM przyciskiem z tekstem, przez co wyglądał na wklejony z innego
   zestawu, a przy okazji zjadał 42 px, których pasek nie miał. Etykieta
   zostaje dla czytników ekranu i podpowiedzi (`title="Dodaj obraz"`). */
.rich-toolbar .rich-image-button > span:not(.icon) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.rich-toolbar select { flex: none; }
/* Ikony w pasku edytora mają rozmiar ikon `mini` (13 px) — przy 16 px
   dominowały nad napisem sąsiedniego przycisku i pasek wyglądał jak zlepek
   elementów z różnych zestawów. */
.rich-toolbar .icon { width: 13px; height: 13px; }
.rich-toolbar button:hover, .rich-image-button:hover { background: var(--surface-3); }
.rich-toolbar button.is-active { border-color: var(--accent-strong); background: var(--accent-soft); color: var(--accent-strong); }
/* W1d: pasek formatowania w OKNIE jak na telefonie (obie wersje ekranu) — bez tła, włosowa kreska pod spodem,
   narzędzia bez ramek i bez szarych pól (listy „Tekst”/„Skala” też), włączone narzędzie zostaje podświetlone.
   POPR3-pola: przezroczysta ramka list „Tekst”/„Skala” ustawiona TU — okno nie zdejmuje już ramki wszystkim polom. */
.modal .rich-toolbar { --okno-pole-tlo: transparent; --okno-pole-ramka: transparent; --okno-pole-obrys: none; border-bottom-color: var(--kreska-wlos); background: transparent; }
.modal .rich-toolbar :is(button, .rich-image-button, .rich-attach-button):not(.is-active) { border-color: transparent; border-radius: var(--r-sm); background: transparent; box-shadow: none; }
.modal .rich-toolbar :is(button, .rich-image-button, .rich-attach-button):not(.is-active):hover { background: var(--btn-2); }
.modal .rich-toolbar button.is-active { border-color: transparent; border-radius: var(--r-sm); }
.modal .rich-toolbar :is(select, input.combo-input) { border-radius: var(--r-sm); }
/* Select rozmiaru czcionki musi mierzyć tyle co przyciski obok, inaczej pasek faluje. */
/* `min-height` MUSI tu być razem z `height`. Bazowa reguła pól w arkuszu 03
   daje każdemu `select` `min-height: var(--h-control)` (32 px), a minimum
   BIJE zwykłą wysokość — listy „Tekst" i „Skala" sterczały o 5 px ponad
   przyciski (27 px) i pasek wyglądał jak zlepek dwóch zestawów kontrolek. */
/* `padding-right` MUSI być tu powtórzony. Reguła ogólna (03-kontrolki) rezerwuje
   miejsce na strzałkę, ale te pola kończyły z domyślnymi 10 px przeglądarki —
   strzałka rysowana od 12 px do 28 px od krawędzi wchodziła wtedy na tekst
   („Tekst", „Skala"). Wartość liczona z tych samych tokenów co pozycja strzałki,
   więc jedno i drugie zmienia się razem. */
.rich-toolbar select { height: var(--h-control-sm); min-height: var(--h-control-sm); padding-left: var(--s-2); padding-right: calc(var(--s-3) + var(--s-4) + var(--s-2)); font-size: var(--t-sm); }
.rich-image-button input { display: none; }
/* <input type=file> chowa się pod etykietą */
.rich-expand-wrap { display: inline-flex; margin-left: auto; }
/* Kreska między grupami narzędzi (wzór .cz-sep): tekst | obraz | listy i reszta. Widać ją tylko w pasku o wyglądzie wzoru (Notatki, Czat)
   na komputerze; na dotyku formatowanie stoi pod „Aa”, a w pozostałych edytorach (opis zadania, okna) pasek zostaje w jednym rzędzie bez kresek. */
.rich-sep { display: none; flex: none; width: 1px; height: 20px; margin: 0 var(--s-1); background: var(--line); }
:root[data-ui="desktop"] :is(.note-editor2, .message-hub-thread .chat-rich-editor) .rich-toolbar > .rich-sep { display: block; }
.rich-editable { min-height: calc(var(--h-row) * 2); overflow-y: auto; padding: var(--s-2) var(--s-3); line-height: var(--lh-base); }
.rich-editable:focus { outline: none; }
/* ramkę rysuje już .rich-editor */
/* NAPRAWA 11.08.2026 — WSTAWIONY RYSUNEK BEZ RAMKI I BEZ ZAOKRĄGLEŃ.
   Zgłoszenie: „wstawione rysunki mają zjebaną niebieską ramkę". Były DWIE
   rzeczy naraz: zaokrąglone rogi (`--r-sm`) obcinające narożniki szkicu oraz
   niebieski obrys 2 px, który zostawał na obrazku po jego kliknięciu.
   Rysunek ze szkicownika ma białe tło i własne krawędzie — ramka wokół niego
   to druga ramka w ramce, a zaokrąglenie ścina to, co narysowałeś w rogu.
   Zaznaczenie ZOSTAJE, bo bez niego nie wiadomo, który obrazek się przesuwa —
   ale rysuje je teraz cienka linia w barwie akcentu PRZYLEGAJĄCA do obrazka
   (`outline-offset: 0`), a nie gruby pierścień odsunięty na zewnątrz. */
.rich-editable img { max-width: 100%; height: auto; border-radius: 0; }
.rich-editable img.rich-image-selected { outline: 1px solid var(--accent-strong); outline-offset: 0; }
/* ----------------------------------------------------------------------------
   PODGLĄD „KTO PISAŁ" — ramka i podpis przy akapicie (11.08.2026).
   Włącza go klasa `.pokaz-autorow` na edytorze. BEZ NIEJ nie zmienia się nic —
   tekst wygląda dokładnie jak dotąd, o co prosił użytkownik („w jakiś intymny
   sposób"). Nazwisko z datą podaje JS w `data-podpis`, kolor działu autora
   w `--autor-kolor`; CSS wyłącznie to rysuje.
   PEŁNA cienka ramka, a NIE kolorowy pasek z boku — o pasek z boku użytkownik
   dopytywał tego samego dnia z pretensją przy etapie „Gwarancja".
   Podpis jest ZWYKŁYM WIERSZEM na dole ramki, nie elementem ustawionym
   bezwzględnie: przy krótkim akapicie i długim nazwisku nie ma jak wyjść poza
   ramkę ani nachodzić na tekst.
   `user-select: none` jest KONIECZNE — bez tego podpis wjeżdża do schowka razem
   z zaznaczonym tekstem i ląduje w skopiowanej treści. */
.rich-editor.pokaz-autorow [data-rich-editable] [data-podpis] {
  /* `display: block` jest KONIECZNE — jednostką podpisu bywa `<span>` owijający
     linię gołego tekstu (treść z tego edytora często nie ma akapitów, tylko
     teksty rozdzielone <br>). Element liniowy nie przyjmuje wyściółki w pionie
     ani nie da się go otoczyć ramką, która nie nachodzi na sąsiednie wiersze. */
  display: block;
  margin: var(--s-2) 0;
  padding: var(--s-2);
  border: 1px solid color-mix(in srgb, var(--autor-kolor, var(--line-strong)) 55%, transparent);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--autor-kolor, var(--surface-2)) 6%, var(--surface));
}
.rich-editor.pokaz-autorow [data-rich-editable] [data-podpis]::after {
  content: attr(data-podpis);
  display: block;
  margin-top: var(--s-1);
  padding-top: 3px;
  border-top: 1px dashed color-mix(in srgb, var(--autor-kolor, var(--line-strong)) 35%, transparent);
  color: color-mix(in srgb, var(--autor-kolor, var(--text-muted)) 65%, var(--text));
  font-size: var(--t-2xs);
  font-weight: var(--w-bold);
  line-height: 1.3;
  text-align: right;
  user-select: none;
  pointer-events: none;
}
.rich-editable ul, .rich-editable ol { padding-left: var(--s-5); }
.chat-rich-editor .rich-editable { max-height: calc(var(--h-row) * 5); }
.rich-editable[data-placeholder]:empty::before { content: attr(data-placeholder); color: var(--text-faint); pointer-events: none; }
.chat-rich-editor .rich-editable:not([data-placeholder]):empty::before { content: "Napisz wiadomość..."; color: var(--text-faint); pointer-events: none; }   /* zapas: pole czatu ma data-placeholder (tłumaczony) */
/* Panel emoji: ~175 pozycji, więc auto-fill — liczba kolumn dopasowuje się do szerokości panelu i NIGDY nie powstaje przewijanie w poziomie. */
.rich-emoji-wrap { position: relative; display: inline-flex; }
.rich-emoji-panel { --emoji-min: 28px; position: fixed; z-index: var(--z-dymek); gap: 2px; padding: var(--s-2); display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--emoji-min), 1fr)); max-height: calc(var(--h-row) * 7); overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); box-shadow: var(--cien-3); }
.rich-emoji { display: grid; place-items: center; aspect-ratio: 1; border: 0; border-radius: var(--r-sm); background: none; font-size: var(--t-xl); line-height: 1; cursor: pointer; }
.rich-emoji:hover { background: var(--surface-3); }
/* === 8. Szkicownik i edytor na pełnym ekranie ============================ */
.rich-sketch-overlay, .rich-expand-overlay { position: fixed; inset: 0; z-index: var(--z-dymek); display: grid; place-items: center; padding: var(--s-5); background: color-mix(in srgb, var(--zaslona-kolor) 55%, transparent); backdrop-filter: blur(var(--s-1)); }
.rich-sketch-panel, .rich-expand-panel { display: flex; flex-direction: column; width: min(1160px, 100%); max-height: calc(92vh / var(--skala-ui)); overflow: hidden; border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--cien-3); }
.rich-sketch-head, .rich-expand-head { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) var(--s-4); border-bottom: 1px solid var(--line); background: var(--surface-2); }
/* PEŁNY EKRAN EDYTORA — okno ma wypełnić ekran, a nie kurczyć się do treści.
   Sam `max-height` (wyżej) daje tylko górny limit, więc przy krótkim tekście
   panel zostawał niski i pisało się w pasku wysokości kilku linijek. v8 dawał
   tu wysokość WYMUSZONĄ i trzy reguły rozciągające wnętrze — bez nich edytor
   nie rósł razem z panelem. */
.rich-expand-panel { height: min(86vh / var(--skala-ui), 900px); }
.rich-expand-panel .rich-editor.rich-expand-editor { flex: 1 1 auto; min-height: 0; border: 0; border-radius: 0; }
/* Pole tekstowe zjada całą wolną wysokość panelu; `min-height: 0` jest konieczne,
   bo element flex domyślnie nie kurczy się poniżej swojej treści. */
.rich-expand-editor .rich-editable { flex: 1 1 auto; min-height: 0; max-height: none; overflow-y: auto; }
/* Podpowiedź stoi tuż za tytułem i zjada resztę nagłówka; `min-width: 0`
   pozwala jej się skrócić w wąskim oknie zamiast rozpychać pasek. */
.rich-sketch-hint { min-width: 0; overflow: hidden; color: var(--text-muted); font-size: var(--t-xs); text-overflow: ellipsis; white-space: nowrap; }
/* Klawisze jako klawisze — inaczej „Ctrl+V", „Shift" i „Del" giną w szarym
   ciągu tekstu i podpowiedź czyta się jak jedno długie zdanie do pominięcia.
   Reguła CELOWO zawężona do podpowiedzi szkicownika: w aplikacji nie ma
   systemowego stylu <kbd> i nie zakładamy go tutaj przy okazji. */
.rich-sketch-hint kbd { padding: 1px var(--s-1); border: 1px solid var(--line-strong); border-radius: 4px; background: var(--surface); color: var(--text); font-family: inherit; font-size: var(--t-2xs); font-weight: var(--w-bold); }
/* `.rich-sketch-head-actions` USUNIĘTE 11.08.2026 — „Anuluj" i „Wstaw do tekstu"
   przeniesione z nagłówka do stopki, więc ta reguła straciła markup. */
/* ============================================================================
   UKŁAD PANELU 11.08.2026 — NARZĘDZIA PIONOWO PO LEWEJ (jak w programach graficznych)
   ----------------------------------------------------------------------------
   ZGŁOSZENIE: „szkicownik ma nadal rozjebany panel (…) może narzędzia pionowo
   po lewej stronie, zobacz jak wygląda photoshop".
   ZMIERZONY STAN PRZED ZMIANĄ: JEDEN poziomy pasek z 15 kontrolkami — treść
   1532 px przy 1016 px dostępnego miejsca, więc pasek ZAWIJAŁ SIĘ na dwa rzędy
   (1160 × 79 px zamiast 43 px). Przy zawijaniu kolejność łamała się przypadkowo
   i „Wyczyść" — akcja NIEODWRACALNA — lądowało tuż obok narzędzi klikanych
   co chwilę.
   NOWY PODZIAŁ na trzy strefy, każda odpowiada na inne pytanie:
     • LEWA SZYNA `.rich-sketch-rail` — CZYM rysuję: wyłącznie narzędzia,
       kwadratowe przyciski w jednej kolumnie, sama ikona, nazwa w `title`.
     • GÓRNY PASEK `.rich-sketch-toolbar` — JAK i NA CZYM: kolor, grubość, tło
       (kratka/kropki/białe), przyciąganie do siatki, kolejność elementów.
       Czyli wszystko, co dotyczy BIEŻĄCEGO narzędzia i płótna.
     • STOPKA `.rich-sketch-foot` — HISTORIA I PLIKI: Cofnij, Ponów, Wczytaj
       obraz, a „Wyczyść" wypchnięte rozpychaczem na przeciwny koniec paska,
       czyli najdalej jak się da od wszystkiego innego.
   Po podziale w górnym pasku zostaje 941 px treści przy 1079 px miejsca — jeden
   rząd z zapasem.
   WYSOKOŚĆ: płótno bierze całą resztę. `flex: 1 1 auto` + `min-height: 0` musi
   iść przez CAŁY łańcuch panel → body → work → canvas-wrap; bez `min-height: 0`
   element flex nie kurczy się poniżej swojej treści i wraca pasek przewijania. */
.rich-sketch-body { display: flex; flex: 1 1 auto; min-height: 0; }
.rich-sketch-rail { display: flex; flex: none; flex-direction: column; gap: var(--s-1); padding: var(--s-2); border-right: 1px solid var(--line); background: var(--surface-2); }
/* Poziomy podział grup w szynie: kreślarskie | figury | wypełnianie i kasowanie. */
.rich-sketch-rail-sep { flex: none; height: 1px; margin: var(--s-1) 0; background: var(--line-strong); }
.rich-sketch-work { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; min-height: 0; }
.rich-sketch-foot { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-4); border-top: 1px solid var(--line); background: var(--surface-2); }
/* Stopka powiększonego edytora — ten sam pasek co w szkicowniku, żeby oba duże
   okna kończyły się tak samo. `flex: none` chroni ją przed ściśnięciem: panel
   ma sztywną wysokość, a pole tekstowe zjada całą resztę (`flex: 1 1 auto`)
   i bez tego wypchnęłoby stopkę poza widok. Jeden przycisk, więc dosunięty
   do prawej — jak we wszystkich oknach aplikacji. */
/* `.rich-expand-foot` WYCIĘTE 11.08.2026 — stopka z przyciskiem „Gotowe" zniknęła
   z dużego edytora. Wyjście siedzi teraz w prawym rogu paska narzędzi, dokładnie
   tam, gdzie w małym oknie stoi przycisk powiększenia (public/js/okna/,
   opcja `collapse`). Markupu tej klasy nic już nie tworzy. */
/* „Cofnij"/„Ponów" mają ikonę przy podpisie. Bazowy odstęp przycisku (--s-2,
   8 px) jest dobrany pod ikony 18–20 px; przy 16 px ikona odkleja się od słowa,
   więc w stopce zacieśniamy go do 4 px. `flex: none` chroni ikonę przed
   ściśnięciem, gdyby okno było bardzo wąskie. */
.rich-sketch-foot .button { gap: var(--s-1); }
.rich-sketch-foot .button svg { flex: none; }
.rich-sketch-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-4); border-bottom: 1px solid var(--line); }
.rich-sketch-colors, .rich-sketch-bg { display: inline-flex; align-items: center; gap: var(--s-1); }
/* Przycisk szyny = KWADRAT wysokości kontrolki, sama ikona, w spoczynku bez ramki
   i bez tła — kolumna dwunastu narzędzi musi być spokojna, inaczej sama w sobie
   robi hałas. Podświetla się dopiero pod kursorem i w stanie aktywnym. */
.rich-sketch-rail button { display: grid; flex: none; place-items: center; width: var(--h-control); height: var(--h-control); padding: 0; border: 1px solid transparent; border-radius: var(--r-sm); background: transparent; color: var(--text-muted); cursor: pointer; transition: background var(--szybko), border-color var(--szybko), color var(--szybko); }
.rich-sketch-rail button:hover { border-color: var(--line-strong); background: var(--surface); color: var(--text); }
/* AKTYWNE NARZĘDZIE — pełne wypełnienie akcentem. Poprzednio było tylko delikatne
   tło `--accent-soft`, które w rzędzie identycznych przycisków ginęło i nie dało
   się na pierwszy rzut oka powiedzieć, czym się właśnie rysuje. */
.rich-sketch-rail button.is-active { border-color: var(--accent-strong); background: var(--accent); color: var(--surface); box-shadow: var(--cien-1); }
/* „WYCZYŚĆ" — jedyny przycisk szyny, który NIE rysuje, tylko kasuje wszystko.
   Stoi za kreską, na końcu, i jako jedyny jest czerwony (--danger z systemu
   kolorów), żeby ręka zwolniła ZANIM kliknie. Nie jest to akcja nieodwracalna:
   `data-sketch-clear` woła pushUndo(), więc Ctrl+Z przywraca płótno — dlatego
   sam kolor wystarczy i nie ma tu okna potwierdzenia. */
.rich-sketch-rail button.is-clear { color: var(--danger); }
.rich-sketch-rail button.is-clear:hover { border-color: color-mix(in srgb, var(--danger) 45%, transparent); background: var(--danger-soft); color: var(--danger); }
/* ----------------------------------------------------------------------------
   PRZYCISK-IKONA GÓRNEGO PASKA — tło, przyciąganie, kolejność, wczytanie obrazu.
   PRZEPISANE 11.08.2026. Poprzednio te przyciski miały PODPISY („Kratka",
   „Kropki", „Białe", „Siatka") i mikro-kwadracik z podglądem wzoru, przez co
   cztery sąsiadujące kontrolki zajmowały 318 px paska i i tak nie dało się ich
   odróżnić rzutem oka — kwadracik 16 px nie pokazuje wzoru.
   Teraz: sam kwadrat z ikoną, nazwa w dymku. Ten sam język co szyna narzędzi po
   lewej, tylko o rozmiar mniejszy (--h-control-sm zamiast --h-control) — bo to
   USTAWIENIA bieżącego narzędzia, a nie WYBÓR narzędzia. Ta różnica wielkości
   jest celowa i niesie hierarchię.
   Domyślnie stonowany (--text-muted): dziewięć równie mocnych ikon w jednym
   rzędzie robi hałas i zabiera uwagę płótnu. Rozjaśnia się pod kursorem, akcent
   zostaje wyłącznie dla stanu włączonego. */
.rich-sketch-ikona { display: grid; flex: none; place-items: center; width: var(--h-control-sm); height: var(--h-control-sm); padding: 0; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); color: var(--text-muted); cursor: pointer; transition: background var(--szybko), border-color var(--szybko), color var(--szybko); }
.rich-sketch-ikona:hover { border-color: var(--line-strong); background: var(--surface-2); color: var(--text); }
.rich-sketch-ikona.is-active { border-color: var(--accent-strong); background: var(--accent-soft); color: var(--accent-strong); }
/* SEGMENT = wybór JEDNEGO z trzech. Tło płótna jest rozłączne (kratka ALBO
   kropki ALBO białe), więc trzy przyciski są zrośnięte wspólnymi krawędziami
   i czyta się je jako jedną kontrolkę. Przyciąganie do siatki stoi tuż obok
   jako osobny kwadrat, bo jest NIEZALEŻNYM przełącznikiem — sam kształt mówi,
   że działa inaczej, i nie trzeba tego nigdzie pisać. */
.rich-sketch-seg { display: inline-flex; flex: none; }
.rich-sketch-seg > .rich-sketch-ikona { border-radius: 0; }
.rich-sketch-seg > .rich-sketch-ikona + .rich-sketch-ikona { margin-left: -1px; }
.rich-sketch-seg > .rich-sketch-ikona:first-child { border-top-left-radius: var(--r-sm); border-bottom-left-radius: var(--r-sm); }
.rich-sketch-seg > .rich-sketch-ikona:last-child { border-top-right-radius: var(--r-sm); border-bottom-right-radius: var(--r-sm); }
/* Sąsiedzi zachodzą na siebie o 1 px (wspólna krawędź), więc podświetlony
   segment musi wyjść NA WIERZCH — inaczej jego akcentowa ramka chowa się pod
   krawędzią następnego przycisku i wygląda na uciętą z prawej. */
.rich-sketch-seg > .rich-sketch-ikona:hover, .rich-sketch-seg > .rich-sketch-ikona.is-active { position: relative; z-index: 1; }
.rich-sketch-bg-label { color: var(--text-muted); font-size: var(--t-xs); font-weight: var(--w-bold); }
/* WCZYTAJ OBRAZ — <label> udający przycisk. Pole pliku było wcześniej ukryte
   atrybutem [hidden], a element ukryty w ten sposób NIE PRZYJMUJE FOKUSU: do
   przycisku nie dało się dojść Tabem, mimo że to jedyna droga wstawienia pliku
   z dysku.
   Rozwiązanie NIE JEST tu wymyślone — to ten sam wzorzec, którego aplikacja
   używa dla `.upload-button` (03-kontrolki.css, warianty przycisków): przezroczyste
   pole rozciągnięte na CAŁY przycisk. Klikalna jest cała powierzchnia, natywny
   „Wybierz plik" nigdy się nie pokazuje, a element zostaje w drzewie fokusu
   i reaguje na Enter/Spację. `min-height: 0` jest konieczne, bo bazowa reguła
   pól (03-kontrolki) daje każdemu `input` minimum 32 px, a minimum bije
   wysokość — bez tego pole rozpychałoby 27-pikselowy przycisk. */
.rich-sketch-load { position: relative; overflow: hidden; }
.rich-sketch-load input[type="file"] { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0; border: 0; opacity: 0; cursor: inherit; }
.rich-sketch-load:focus-within { border-color: var(--accent-strong); background: var(--surface-2); color: var(--text); }
/* Pionowa kreska dzieląca grupy GÓRNEGO paska: kolor i grubość | tło i siatka |
   kolejność elementów. `align-self: stretch` zamiast sztywnej wysokości — kreska
   rośnie razem z rzędem i zostaje wyrównana, gdyby pasek jednak się zawinął
   (bardzo wąskie okno). */
.rich-sketch-sep { flex: none; align-self: stretch; width: 1px; margin: 0 var(--s-1); background: var(--line-strong); }
.rich-sketch-spacer { flex: 1; }
/* odpychają to, co ma iść na koniec paska — w stopce szkicownika „Wyczyść" */
/* Kolor pisaka podaje JS zmienną --c (paleta rysunku, nie paleta motywu). */
.rich-sketch-color { width: var(--s-5); height: var(--s-5); padding: 0; border: 2px solid var(--line); border-radius: var(--r-pill); background: var(--c); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 45%, transparent); cursor: pointer; transition: border-color var(--szybko); }   /* cienki jasny/ciemny obrys: tusz nie ginie na tle okna w żadnym motywie */
/* Ujednolicenie 11.08.2026 — próbki koloru pisaka siedzą w `.rich-sketch-toolbar`,
   a nie w `.rich-toolbar`, więc wspólna reakcja przycisków paska (wyżej w tym
   pliku) ich nie obejmowała. Były jedynymi klikalnymi elementami szkicownika
   bez żadnej odpowiedzi na kursor. */
.rich-sketch-color:hover { border-color: var(--line-strong); }
.rich-sketch-color.is-active { border-color: var(--accent-strong); }
.rich-sketch-width { display: inline-flex; flex: none; align-items: center; gap: var(--s-2); color: var(--text-muted); font-size: var(--t-xs); }
/* Szerokość liczby jest STAŁA, inaczej przy przejściu z „9 px" na „10 px" suwak
   przeskakuje w lewo — pasek tańczył przy każdym przeciągnięciu gałki. */
.rich-sketch-width-val { flex: none; min-width: 34px; font-variant-numeric: tabular-nums; }
/* ----------------------------------------------------------------------------
   SUWAK GRUBOŚCI — WŁASNY TOR I GAŁKA, przepisany 11.08.2026.
   Zastany stan: JS liczył zmienną `--pct` (public/js/okna/, komentarz
   „CSS przelicza na pozycję ŚRODKA kółka"), ale ŻADEN arkusz w projekcie tej
   zmiennej nie czytał — sprawdzone przeszukaniem całego public/css. Suwak był
   zwykłym natywnym `range` pomalowanym `accent-color`, czyli miał tę samą wadę,
   co suwak zasięgu w oknie projektu: ŚRODEK gałki nigdy nie dochodzi do końca
   toru, bo przeglądarka trzyma ją w całości wewnątrz. Przy wartościach 1 i 16
   wyglądało to, jakby minimum i maksimum były nieosiągalne.
   Rozwiązanie to samo, co zadziałało w 19-modale-tresc.css (suwak zasięgu):
   rysujemy tor i gałkę sami i cofamy gałkę o połowę różnicy wysokości, żeby jej
   środek trafiał dokładnie w koniec toru. Przy okazji `--pct` przestaje być
   martwy — maluje wypełnioną część toru w Chrome, który nie ma odpowiednika
   `::-moz-range-progress`.
   SZCZEGÓŁOWOŚĆ: bazowa reguła pól w 03-kontrolki to (0,2,1), a ta jest też
   (0,2,1) i leży w arkuszu ładowanym PÓŹNIEJ, więc wygrywa kolejnością. Zgodnie
   z zasadą projektu nie podbijamy szczegółowości — poprzednia wersja robiła to
   przez `:not(...)`, co było niepotrzebne.
   Chrome i Firefox mają OSOBNE nazwy pseudoelementów i nie wolno ich łączyć
   przecinkiem — jeden nieznany selektor unieważnia całą regułę. */
.rich-sketch-width input[type="range"] { width: 96px; height: var(--s-4); min-height: 0; margin: 0; padding: 0; border: 0; background: transparent; appearance: none; -webkit-appearance: none; cursor: pointer; }
.rich-sketch-width input[type="range"]::-webkit-slider-runnable-track { height: var(--s-1); border-radius: var(--r-pill); background: linear-gradient(to right, var(--accent-strong) calc(var(--pct, 0) * 1%), var(--line-strong) calc(var(--pct, 0) * 1%)); }
.rich-sketch-width input[type="range"]::-moz-range-track { height: var(--s-1); border-radius: var(--r-pill); background: var(--line-strong); }
.rich-sketch-width input[type="range"]::-moz-range-progress { height: var(--s-1); border-radius: var(--r-pill); background: var(--accent-strong); }
.rich-sketch-width input[type="range"]::-webkit-slider-thumb { appearance: none; -webkit-appearance: none; width: var(--s-4); height: var(--s-4); margin-top: calc((var(--s-4) - var(--s-1)) / -2); border: 0; border-radius: var(--r-pill); background: var(--accent-strong); }
.rich-sketch-width input[type="range"]::-moz-range-thumb { width: var(--s-4); height: var(--s-4); border: 0; border-radius: var(--r-pill); background: var(--accent-strong); }
/* PŁÓTNO NIESKOŃCZONE (18.10.2026): brak kartki — canvas wypełnia całe wolne miejsce okna (position: absolute; inset: 0),
   a jego rozmiar bitmapy liczy JS (client × devicePixelRatio, szkicownik-widok.js). Siatka/kropki i papier są rysowane na
   canvasie (kratka zawsze kwadratowa, od brzegu do brzegu), więc CSS nie ma już tła w procentach ani wymiarów A3.
   Pole dotyku: touch-action: none — palec rysuje i przesuwa/zbliża widok, przeglądarka nie przewija strony. */
.rich-sketch-canvas-wrap { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; background: var(--szkic-papier, var(--surface-2)); }
.rich-sketch-canvas-wrap canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* TŁO PŁÓTNA (kratka / kropki / białe) — od 18.10.2026 rysuje je sam canvas (szkicownik-widok.js, `rysujTlo`): oczko 24 jednostki
   świata, przy małym zoomie ×2, zawsze kwadratowe. Papier jest biały albo ciemny (tokeny --szkic-* w 1-podstawa/05-tokeny-szkicownik.css;
   rodzaj wybiera szkicownik-papier.js) — tło wrappera ma ten sam kolor, więc przed pierwszym rysowaniem nic nie błyska. Dawne reguły tła CSS w procentach (48 × 34 oczek
   kartki 1152 × 816) usunięte razem z kartką. */
/* WYCIĘTE 11.08.2026: `.rich-sketch-bg-swatch` (+ `.is-grid` / `.is-dots` /
   `.is-white`), `.rich-sketch-snap-dot` i `.rich-sketch-gap`. Podglądy wzoru
   w kwadraciku 16 px nie pokazywały wzoru — trzy przyciski i tak wyglądały
   identycznie, a to był powód, dla którego w ogóle istniały. Zastąpione
   ikonami (`SKETCH_TOOL_ICONS.grid/dots/blank` w public/js/okna/szkicownik.js), więc
   markup tych klas już nie tworzy. `.rich-sketch-gap` nie miał wystąpień
   w public/js już wcześniej. */
/* === 8a. TREŚĆ BOGATA (opis zadania, treść notatki) ======================= (z dawnego 26, K15)
   To, co użytkownik wkleił lub narysował w edytorze, wyświetlane w trybie
   odczytu — w szczegółach zadania (`renderTodoDetail`) i w panelu tematu
   notatek (`renderNoteTopicPanel`). Wklejone obrazy bywają ogromne, więc
   twardo skalują się do szerokości kolumny; długi link nie rozpycha panelu. */
.rich-content { word-break: break-word; }
.rich-content img { max-width: 100%; height: auto; border-radius: var(--r-sm); }
/* === 8b. NARZĘDZIA EDYTORA — cztery przełączniki ========================== (z dawnego 26, K15)
   17-czat.css opisuje pasek, panel emoji i cały szkicownik. Brakowało w nim
   czterech samych przełączników. */
/* Emotikona jest znakiem, nie ikoną-maską — stopień ustawia się jej wprost. */
.rich-emoji-toggle { font-size: var(--t-md); line-height: 1; }
/* „Powiększ edytor" siedzi w gęstym pasku narzędzi, więc ikona jest mniejsza
   niż domyślne 16 px — inaczej rozpycha rząd.
   13 px, nie 14: WSZYSTKIE ikony paska edytora mają ten rozmiar (arkusz 17).
   Ta jedna wyłamywała się o piksel i była jedyną większą w rzędzie. */
.rich-expand-toggle .icon { width: 13px; height: 13px; }
/* Wczytanie obrazu to <label> na ukrytym <input type="file">: wygląda jak
   przycisk, więc musi też ZACHOWYWAĆ się jak przycisk pod kursorem. */
.rich-sketch-load { cursor: pointer; }
/* Grubość pióra obok suwaka. Stała szerokość i cyfry o równej szerokości —
   przy przeciąganiu suwaka liczba zmienia się w miejscu, nie skacze. */
.rich-sketch-width-val { min-width: 34px; color: var(--text); font-weight: var(--w-bold); font-variant-numeric: tabular-nums; }
/* === 9. Powiadomienia wyskakujące ======================================= */
/* Prawy DOLNY róg: górę ekranu zajmują toasty zapisu (.toast-root), więc powiadomienie o wiadomości nie zasłania potwierdzenia operacji. */
.chat-notification-root { position: fixed; right: var(--s-4); bottom: var(--s-4); z-index: var(--z-toast); display: grid; gap: var(--s-2); width: min(420px, calc(100vw / var(--skala-ui) - var(--s-6))); }
.chat-notification { display: grid; gap: var(--s-2); padding: var(--s-3); border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--line)); border-radius: var(--r); background: var(--surface); box-shadow: var(--cien-2); }
.chat-notification-head { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--s-2); }
.chat-notification-head strong, .chat-notification-head span { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-notification-head span { color: var(--text-muted); font-size: var(--t-xs); }
.chat-notification p { color: var(--text-muted); }
.chat-notification-reply { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--s-2); }
/* === 10. Chowanie paneli ================================================ */
/* KONIECZNE: `[hidden]` z 01-reset i `.hidden` z 06-elementy ważą tyle samo co selektor klasy, a ten arkusz ładuje się PÓŹNIEJ — bez tych reguł panel emoji, szkicownik i menu byłyby widoczne mimo ukrycia przez JS. Selektor złożony (0,2,0) wygrywa niezależnie od kolejności arkuszy. */
.rich-emoji-panel[hidden], .rich-emoji-panel.hidden, .rich-sketch-overlay[hidden], .rich-sketch-overlay.hidden, .rich-expand-overlay[hidden], .rich-expand-overlay.hidden, .chat-attachment-panel[hidden], .chat-attachment-panel.hidden, .chat-mention-dropdown[hidden], .chat-mention-dropdown.hidden, .chat-notification-root[hidden], .chat-notification-root.hidden, .chat-recipient-list[hidden], .chat-recipient-list.hidden, .chat-recipient-list.is-collapsed, .chat-pending-files[hidden], .chat-pending-files.hidden, .chat-thread-rail[hidden], .chat-thread-rail.hidden, .message-hub-list[hidden], .message-hub-list.hidden { display: none; }
/* === 11. Węższe ekrany ================================================== */
/* 1180: węższa lista i belka wątków — rozmowa jest ważniejsza niż spis. */
@media (max-width: 1180px) {
  .message-hub { --lista-w: 360px; }
  .chat-thread-rail { --watki-w: 140px; }
}
/* 980: hub pionowo — lista u góry (38%), rozmowa pod nią. */
@media (max-width: 980px) {
  .message-hub { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(160px, 38%) minmax(0, 1fr); }
  .message-hub-sidebar { border-right: 0; border-bottom: 1px solid var(--line); }
}
/* Telefon: hub = JEDEN panel w kolumnie (lista albo rozmowa — 9-telefon/2-okna.css §6). Belka wątków w oknie projektu tak samo. */
:where(:root[data-ui="mobile"]) .message-hub-modal { height: 100%; }
:where(:root[data-ui="mobile"]) .message-hub { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(96px, 30%) minmax(0, 1fr); }
:where(:root[data-ui="mobile"]) .chat-bubble { max-width: 88%; }
:where(:root[data-ui="mobile"]) .project-chat-panel.has-thread-rail { flex-direction: column; }
/* W kolumnie rozmowa (tytuł, osoby, historia, pole pisania) musi dać się ścisnąć do wysokości okna —
   bez tego długa rozmowa rozpychała ją, a pole pisania i „Wyślij” lądowały poza ekranem (FRO-29). */
:where(:root[data-ui="mobile"]) .project-chat-main { min-height: 0; }
:where(:root[data-ui="mobile"]) .chat-thread-rail { flex: 0 0 auto; border-right: 0; border-bottom: 1px solid var(--line); }
:where(:root[data-ui="mobile"]) .chat-thread-rail-list { flex-direction: row; overflow-x: auto; }
/* --- Czat: emoji, odbiorcy, drzewo (z dawnego 28, K17) --- */
/* Ujednolicenie 11.08.2026 — dodane `transition`: tło wskakiwało skokiem. */
.chat-emoji { padding: var(--s-1); border: 0; border-radius: var(--r-sm); background: transparent; font-size: var(--t-lg); line-height: 1; cursor: pointer; transition: background var(--szybko); }
.chat-emoji:hover { background: var(--surface-2); }
.chat-recipient-check { color: var(--accent-strong); font-size: var(--t-base); font-weight: var(--w-bold); }
.chat-recipient-chip-name { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.message-hub-tree-node { min-width: 0; max-width: 100%; }
.message-hub-contact-copy { display: grid; gap: 2px; min-width: 0; }
/* Próbki tła szkicownika w czacie. */
.rich-sketch-bg-swatch.is-grid { background-image: linear-gradient(to right, color-mix(in srgb, var(--text) 50%, transparent) 1px, transparent 1px), linear-gradient(to bottom, color-mix(in srgb, var(--text) 50%, transparent) 1px, transparent 1px); background-size: 5px 5px; }
.rich-sketch-bg-swatch.is-dots { background-image: radial-gradient(color-mix(in srgb, var(--text) 62%, transparent) 1px, transparent 1.5px); background-size: 5px 5px; }
.rich-sketch-bg-swatch.is-white { background-image: none; }
:root[data-ui="tablet"] .rich-sketch-width input[type="range"] { height: 44px; }   /* POPR-n29: dotyk — suwak grubości 44 px (był 16 px) */
/* POPR-n29: „Wątek: … ▾” i „Aa” istnieją tylko w czacie na telefonie (9-telefon/4-projekty-zadania-czat.css). */
.chat-thread-wybor, .rich-toolbar .rich-aa-toggle { display: none; }   /* 0,2,0 — mocniej niż „.rich-toolbar button” (inline-flex) */
/* v15-b6 CZ7 (wzór 03.10.2026): tablet jak telefon — w czacie formatowanie schowane pod „Aa” (widać Aa, szkic, Zleć jako zadanie,
   załącz i powiększ; pasek w jednym rzędzie zamiast dwóch), cele dotyku 44 px: strzałka drzewa, „N os.”, akcje dymka, cytat. */
:root[data-ui="tablet"] .message-hub-thread .chat-rich-editor .rich-toolbar { gap: var(--s-1); }   /* wzór: na dotyku odstęp 4 px */
:root[data-ui="tablet"] .chat-rich-editor .rich-aa-toggle { display: inline-grid; place-items: center; font-size: var(--t-base); font-weight: var(--w-strong); }
:root[data-ui="tablet"] .chat-rich-editor.is-format-open .rich-aa-toggle { background: var(--accent-soft); color: var(--accent-strong); }
:root[data-ui="tablet"] .chat-rich-editor:not(.is-format-open) .rich-toolbar > :is([data-rich-command], [data-rich-font-size], [data-rich-image-size], .rich-image-button:not(.rich-attach-button), [data-action="rich-checklist"], .rich-emoji-wrap, .rich-authors-toggle, .combo:has([data-rich-font-size], [data-rich-image-size])) { display: none; }
/* `width`, nie `min-width`: ogólna reguła dotyku (03-kontrolki, 40 px) ma wyższą szczegółowość. */
:root[data-ui="tablet"] .chat-rich-editor .rich-toolbar :is(button, .rich-image-button, .rich-attach-button) { width: 44px; height: 44px; }
:root[data-ui="tablet"] .chat-rich-editor .rich-toolbar select { min-width: 64px; height: 44px; }
:root[data-ui="tablet"] .message-hub-tree-row { grid-template-columns: 44px minmax(0, 1fr); }
:root[data-ui="tablet"] .message-hub-twisty { width: 44px; height: 44px; margin-top: 0; }
:root[data-ui="tablet"] .message-hub-thread-children { margin-left: 44px; }
:root[data-ui="tablet"] :is(.message-hub-thread-child, .message-hub-add-thread) { min-height: 44px; }
:root[data-ui="tablet"] :is(.chat-thread-manage, .chat-thread-delete) { height: 44px; }
:root[data-ui="tablet"] .chat-thread-delete { width: 44px; }
:root[data-ui="tablet"] .chat-bubble-actions { top: calc(var(--s-6) * -1); }
:root[data-ui="tablet"] .chat-act-btn { width: 44px; height: 44px; }
:root[data-ui="tablet"] :is(.chat-attachment, .chat-edit-drawing) { height: 44px; }
/* ZK7c (wzór, do 1180 px): pozycja menu załącznika 44 px, nagłówek rozmowy 68 px, wiersz rozmowy 60 px (`height`: ogólna reguła dotyku z 03-kontrolki ma wyższą wagę niż min-height). */
:root[data-ui="tablet"] .chat-attachment-action { min-height: 44px; }
:root[data-ui="tablet"] .message-hub-thread .project-chat-title { min-height: 68px; }
:root[data-ui="tablet"] .hub-act-row { height: 60px; }
:root[data-ui="tablet"] .chat-quote { padding-block: 6px; }
