/* ============================================================================
   14-timeline.css — oś czasu: zakładki, gantt, konsultacje, odhaczanie
   ----------------------------------------------------------------------------
   Siedem zakładek (Konsultacje, Design, Plany, Produkcja, Gwarancja, Transport,
   Montaż); pięć rysuje ten sam silnik: siatkę dni z przyklejoną kolumną nazw.

   SZEROKOŚCI SIATKI TU NIE MA — liczbę dni zna dopiero JS i wstawia inline
   `grid-template-columns` + `min-width` (`timelineGridStyle()`). Dawne
   `min-width: 950px` blokowało telefon: siatka nie mieściła się i nic nie dało
   się przewinąć. Teraz przewija się KONTENER (`.timeline{overflow:auto}`), a
   kolumna nazw jest przyklejona. Liczba 7 niżej = układ awaryjny bez JS.
   ============================================================================ */
/* Wymiary właściwe wyłącznie tej osi — nie mają tokenu, bo nie występują nigdzie
   indziej. Siedzą w jednym miejscu, żeby nie krążyły po całym pliku. */
.timeline-head, .timeline-row { --tl-nazwa: 244px; /* kolumna nazw (JS zwęża ją na telefonie) */ --tl-dzien: 116px; /* minimalna szerokość jednego dnia */ --tl-kafel: 34px; /* wysokość kafelka; JS układa pasy co 38px → 4px przerwy */; }
/* === 1. ZAKŁADKI I PASEK NARZĘDZI ========================================== */
/* Pasek narzędzi Timeline'u jest WYŻSZY niż reszta aplikacji: monolit trzyma
   wszystkie kontrolki w nim na 40 px (7094, 7103, 7576), a zakładki na 36 px.
   U nas szły na standardowe 32 px i cały pasek był niższy niż w v8.
   Jedna zmienna, żeby nie rozjechały się względem siebie. */
/* KONTROLKI TIMELINE ZRÓWNANE Z RESZTĄ APLIKACJI — `--h-control` (32 px).
   v8 miał tu 40 px (monolit 7094, 7103, 7576) i tyle było odtworzone, ale
   przez to szukajka, przełącznik zakresu i „Dodaj" były o 8 px wyższe niż
   te same kontrolki w każdym innym oknie. Użytkownik zgłaszał różne rozmiary
   przycisków w różnych miejscach — to jedyne miejsce, gdzie zostały.
   To ŚWIADOME odejście od v8 na rzecz spójności; powrót = zmiana tej
   jednej wartości z powrotem na `var(--h-row)`. */
.timeline-workspace { --tl-kontrolka: var(--h-control); display: grid; gap: var(--s-3); }
/* Tablet: przyciski w przełącznikach (Tydzień / Miesiąc, Mój / Wszystko) mają 44 px (--h-tab) wewnątrz ramki 1 px, więc cały
   pasek sterowania — szukajka, „Dzisiaj”, „Nowe zadanie” — ma 44 + 2 px, żeby stał w jednej linii (tura 3 E1, 27.09). */
:root[data-ui="tablet"] .timeline-workspace { --tl-kontrolka: calc(var(--h-tab) + 2px); }
/* `min-width: 0` na dzieciach jest KONIECZNE. Domyślne `min-width: auto`
   w siatce sprawia, że najszerszy element (gantt, tu 4768 px) rozpycha CAŁE
   rodzeństwo: pasek narzędzi, stopka i nagłówek panelu też dostawały 4768 px
   zamiast 1614 i ich zawartość uciekała daleko poza ekran. Zmierzone wobec
   monolitu, który trzyma je na szerokości kontenera. */
.timeline-workspace > * { min-width: 0; }
/* Zakładki na wspólnym tle — widać, że to jeden przełącznik, a nie luźne guziki. */
.timeline-tabs { display: flex; flex-wrap: wrap; gap: var(--s-1); width: fit-content; max-width: 100%; margin-bottom: 14px; padding: var(--s-1); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface-2); }
.timeline-tab { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-1); min-height: var(--h-tab); padding: 0 var(--s-4); border: 1px solid transparent; border-radius: var(--r); color: var(--text-muted); font-size: var(--t-base); font-weight: var(--w-strong); white-space: nowrap; cursor: pointer; transition: background var(--szybko), color var(--szybko); }
.timeline-tab:hover { background: var(--surface); color: var(--text); }
.timeline-tab.active { background: var(--accent); color: var(--text-invert); }
/* Licznik zaległych przy nazwie zakładki. */
.timeline-tab-badge { min-width: var(--s-4); padding: 0 var(--s-1); border-radius: var(--r-pill); background: var(--accent); color: var(--text-invert); font-size: var(--t-xs); font-weight: var(--w-bold); text-align: center; }
.timeline-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-3); }
/* Szukajka rośnie, sterowanie datami trzyma się prawej krawędzi. */
/* Ujednolicenie 11.08.2026 — gap 9px → --s-2 (8 px). Wyściółka `0 14px` zostaje:
   14 px leży 2 px od --s-3 i 2 px od --s-4, więc nie ma tokenu, do którego
   „pasuje", a ta sama liczba trzyma poziomą oś pasków w całej aplikacji. */
.timeline-search { display: flex; align-items: center; gap: var(--s-2); flex: 1 1 260px; min-width: 220px; max-width: 460px; height: var(--tl-kontrolka); padding: 0 14px; border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); }
/* Ramkę i poświatę rysuje KONTENER — pole własnej mieć nie może, bo widać dwie.
   `:not(...)` NIE jest ozdobą: podbija szczegółowość do (0,3,1), żeby ta reguła
   pobiła bazową `input:not([type=checkbox]):not([type=radio])` (0,2,1) z arkusza
   03. Bez tego zerowanie ramki PRZEGRYWA i pierścienie są dwa. Tak samo v8 (27422). */
.timeline-search input:not([type="checkbox"]):not([type="radio"]) { flex: 1; height: 100%; min-height: 0; padding: 0; border: 0; border-radius: 0; background: transparent; }
.timeline-search-clear { width: var(--h-control-sm); height: var(--h-control-sm); border-radius: var(--r-pill); color: var(--text-muted); cursor: pointer; }
.timeline-search-clear:hover { background: var(--surface-2); color: var(--text); }
.timeline-controls { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2); margin-left: auto; }
/* Przełącznik zakresu i przycisk dodania też na 40 px — inaczej pasek ma trzy różne wysokości. */
/* Ujednolicenie 11.08.2026 — 10 px było JEDYNĄ surową wartością promienia
   w całej aplikacji (zmierzone: wszystkie inne widoki dają 6/9/12/999).
   Timeline wyróżniał się o 1 px bez powodu. */
.timeline-toolbar .segmented { height: var(--tl-kontrolka); border-radius: var(--r); }
.timeline-toolbar .segmented button { min-height: 0; height: 100%; padding: 0 var(--s-4); font-size: var(--t-base); font-weight: var(--w-strong); }
.timeline-controls .timeline-add { height: var(--tl-kontrolka); padding: 0 var(--s-4); font-weight: var(--w-strong); }
.timeline-nav button { height: var(--tl-kontrolka); }
.timeline-nav button { min-width: calc(var(--h-control) + var(--s-3)); }
/* „Dziś: …” — sama informacja z zieloną kropką, BEZ ramki i tła (ergonomia 26.09, E1: zielona plakietka obok
   „Dzisiaj” wyglądała jak przycisk, a nie jest). Tak samo jak na telefonie (31-telefon-wzorzec). */
.timeline-today-chip { display: inline-flex; align-items: center; gap: var(--s-2); height: var(--tl-kontrolka); padding: 0 var(--s-2); border: 0; background: transparent; color: var(--text-muted); font-size: var(--t-sm); font-weight: var(--w-medium); white-space: nowrap; cursor: default; }
.timeline-today-pip { width: var(--s-2); height: var(--s-2); border-radius: var(--r-pill); background: var(--ok); }
/* === 2. SIATKA DNI ========================================================= */
/* Jedyny element ze scrollem — telefon przewija oś palcem, nie rozpycha strony. */
/* Ujednolicenie 11.08.2026 — cień kontenera --cien-1 dla CAŁEJ osi, nie tylko
   dla Gantta (osobna reguła `.timeline.timeline-gantt` przez to zbędna). */
.timeline { overflow: auto; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--cien-1); }
.timeline-head, .timeline-row { display: grid; grid-template-columns: var(--tl-nazwa) repeat(7, minmax(var(--tl-dzien), 1fr)); }
/* Nagłówek dni zostaje na górze przy przewijaniu w pionie. */
.timeline-head { position: sticky; top: 0; z-index: 4; }
.timeline-head > div, .timeline-label, .timeline-canvas { min-height: calc(var(--h-row) + var(--s-3)); border-bottom: 1px solid var(--line); }
.timeline-head > div { display: flex; flex-direction: column; justify-content: center; padding: 0 var(--s-2); background: var(--surface-2); color: var(--text-muted); font-size: var(--t-sm); font-weight: var(--w-bold); }
.timeline-head small { font-size: var(--t-xs); font-weight: var(--w-medium); }
/* Podpis dnia (skrót dnia tygodnia) w nagłówku: 10px/700 i kolor DZIEDZICZONY
   po kolumnie — dzięki temu w weekend jest wyszarzony razem z całym dniem.
   Bazowe  z 02-typografia wymusza wyszarzenie, więc trzeba je zdjąć. */
.timeline-head .timeline-day small { color: inherit; font-size: var(--t-2xs); font-weight: var(--w-strong); }
/* Nagłówki dni: treść do LEWEJ, nie na środku. Monolit ma tu
   `align-items: flex-start` (linia 7019) i NIGDZIE nie centruje dnia —
   bez tego span rozciąga się na całą kolumnę i numer skacze na środek. */
.timeline-head .timeline-day { align-items: flex-start; }
/* W widoku miesiąca kolumna ma ~38 px — miesiąc i dzień muszą zejść o stopień. Na telefonie tak samo w „Tydzień”
   (cały tydzień na ekranie, ~30 px na dzień), a w „Miesiąc” (~22 px) wyściółka prawie zerowa. */
.timeline.month .timeline-day, :root[data-ui="mobile"] .timeline.week .timeline-day { padding: 0 var(--s-1); font-size: var(--t-xs); }
:root[data-ui="mobile"] .timeline.month .timeline-day { padding: 0 1px; }
/* Numer dnia siedzi w <span> i NIE dziedziczy rozmiaru z kolumny (ma własny
   kontekst z .timeline-head > div = 12px). Monolit celuje w span wprost
   (linia 7884). Bez tego 119 numerów dni renderowało się w 13 px i tłoczyło
   się w kolumnie szerokiej na 38 px. */
.timeline-head .timeline-day span { font-size: var(--t-xs); }
/* Weekend i święto = dzień nierobocze; niedziela/święto mocniej niż sobota.
   SZARE, nie czerwone (ergonomia 26.09, E1): czerwień w programie znaczy błąd / spóźnienie, a weekend
   na czerwono wyglądał jak alarm. Napis --text-muted na lekko przyciemnionym tle (kontrast ≥ 4,5 : 1). */
/* (11.08.2026 napis czerwonego weekendu był przyciemniany domieszką --text, bo PEŁNY `--danger` na
   czerwonym tle dawał 3,99 : 1 przy najdrobniejszych napisach osi — szarość ten problem usuwa.) */
.timeline-day.nonwork { background: color-mix(in srgb, var(--text) 4%, var(--surface-2)); color: var(--text-muted); }
.timeline-day.sunday, .timeline-day.holiday { background: color-mix(in srgb, var(--text) 7%, var(--surface-2)); }
/* Dziś: zielony ton + kreska pod spodem. Pionowa linia „teraz" celowo wyłączona
   (była toporna) — orientację daje tint kolumny w warstwie dni. */
.timeline-day.today { background: color-mix(in srgb, var(--ok) 12%, var(--surface-2)); color: var(--ok-strong); box-shadow: inset 0 calc(var(--s-1) / -2) 0 color-mix(in srgb, var(--ok) 65%, transparent); }
.timeline-today-marker { display: none; }
/* === 3. KOLUMNA NAZW (przyklejona) ========================================= */
/* Nazwa projektu/osoby zostaje widoczna, gdy dni przewijają się w bok. Scope na
   `.timeline`, żeby nie ruszyć podglądów Design/Plany w oknach modalnych. */
.timeline .timeline-first-head, .timeline .timeline-label { position: sticky; left: 0; box-shadow: 1px 0 0 var(--line); }
.timeline .timeline-label { z-index: 3; background: var(--surface); }
/* Nagłówek kolumny nazw: 10px/700 jak w monolicie (linia 27757), a nie
   dziedziczone 12px/600 z .timeline-head > div. align-items zwęża napis do
   treści — bez tego rozciąga się na całe 224px kolumny. */
.timeline-head > .timeline-first-head { z-index: 1; align-items: flex-start; font-size: var(--t-2xs); font-weight: var(--w-strong); }
.timeline-label { display: flex; flex-direction: column; justify-content: center; gap: var(--s-1); padding: var(--s-2) var(--s-3); }
.timeline-label-main { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
/* Rozwijanie kroków produkcji („+"/„−") — mały kwadrat, nie pełny przycisk. */
.tree-toggle { display: inline-grid; place-items: center; flex: 0 0 auto; width: var(--h-control-sm); height: var(--h-control-sm); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); color: var(--text-muted); font-weight: var(--w-bold); line-height: 1; cursor: pointer; transition: background var(--szybko), border-color var(--szybko); }
/* Ujednolicenie 11.08.2026 — wygląda jak przycisk (ramka, tło, kursor), więc
   ma się jak przycisk zachowywać. Był bez reakcji na kursor. */
.tree-toggle:hover { border-color: var(--line-strong); background: var(--surface-2); }
.timeline-label-text { min-width: 0; }
/* Długa nazwa nie może wylewać się na siatkę — ucinamy, pełna jest w tooltipie. */
.timeline-label-text strong, .timeline-label-text small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.timeline-label-text strong { line-height: var(--lh-tight); }
.timeline-label-text small { color: var(--text-muted); font-size: var(--t-xs); }
.timeline-row.child .timeline-label { padding-left: var(--s-6); background: var(--surface-2); }
/* Wyciete 11.08.2026 (Ujednolicenie) — `.timeline.timeline-gantt` powtarzalo
   ten sam cien, ktory ma juz `.timeline` (l. 64). Gantt niczym sie tu nie rozni. */
.timeline-row:hover > .timeline-label { background: var(--surface-2); }
.timeline-row.drop-target > .timeline-label { box-shadow: inset var(--s-1) 0 0 var(--accent); }
/* Postęp i stan pracy — pasek zamiast liczby, bo czyta się jednym rzutem oka. */
.timeline-row-meta { display: flex; align-items: center; gap: var(--s-2); }
.timeline-progress-track { flex: 1 1 auto; min-width: var(--s-6); height: var(--s-2); overflow: hidden; border-radius: var(--r-pill); background: var(--surface-3); }
.timeline-progress-track > span { display: block; height: 100%; background: var(--accent); }
.timeline-row-meta em { color: var(--text-muted); font-size: var(--t-xs); font-style: normal; font-weight: var(--w-bold); }
.timeline-status { display: inline-flex; align-items: center; gap: var(--s-1); color: var(--text-muted); font-size: var(--t-xs); font-weight: var(--w-bold); white-space: nowrap; }
.timeline-status i { width: var(--s-2); height: var(--s-2); border-radius: var(--r-pill); background: currentColor; }
.timeline-status.active { color: var(--status-wtoku); }
.timeline-status.late { color: var(--danger); }
.timeline-status.planned { color: var(--status-oczekuje); }
/* Pusty znacznik ze starego układu — bez ukrycia robi dziurę w etykiecie. */
.timeline-row-dots { display: none; }
/* === 4. KANWA I KAFELKI ZADAŃ ============================================== */
/* Pionowe kreski dni rysuje gradient tła — jeden element zamiast N wierszy DOM. */
.timeline-canvas { position: relative; grid-column: span 7; background-image: linear-gradient(to right, var(--line) 1px, transparent 1px); background-size: calc(100% / 7) 100%; }
.timeline-row.drop-target > .timeline-canvas { outline: 2px solid color-mix(in srgb, var(--accent) 30%, transparent); outline-offset: -2px; }
/* Warstwa dni siedzi POD kafelkami — inaczej nalot weekendu je przykrywa. */
.timeline-day-layer { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.timeline-day-layer span { position: absolute; top: 0; bottom: 0; }
.timeline-day-layer .nonwork { background: color-mix(in srgb, var(--text) 4%, transparent); }
.timeline-day-layer .sunday, .timeline-day-layer .holiday { background: color-mix(in srgb, var(--text) 7%, transparent); }
.timeline-day-layer .today { background: color-mix(in srgb, var(--ok) 8%, transparent); }
/* Kafelek = JEDNA reguła; wariant podmienia tylko ton (jak pigułki statusu). */
.timeline-task { --ton: var(--etap-produkcja); position: absolute; z-index: 1; display: flex; flex-direction: column; justify-content: center; min-width: var(--s-6); height: var(--tl-kafel); padding: 0 var(--s-3); overflow: hidden; border: 1px solid color-mix(in srgb, var(--ton) 45%, transparent); border-radius: var(--r-sm); background: color-mix(in srgb, var(--ton) 18%, var(--surface)); color: var(--text); text-align: left; white-space: nowrap; user-select: none; -webkit-touch-callout: none; touch-action: none; cursor: grab; box-shadow: var(--cien-1); transition: left var(--szybko), width var(--szybko), box-shadow var(--szybko), transform var(--szybko); }
.timeline-task:hover { z-index: 2; transform: translateY(-1px); box-shadow: var(--cien-2); }
.timeline-task .task-title { overflow: hidden; font-size: var(--t-sm); font-weight: var(--w-bold); line-height: var(--lh-tight); text-overflow: ellipsis; }
.timeline-task small { overflow: hidden; color: var(--text-muted); font-size: var(--t-xs); line-height: var(--lh-tight); text-overflow: ellipsis; }
.timeline-task.consulting { --ton: var(--etap-konsultacje); }
.timeline-task.projects, .timeline-task.design { --ton: var(--etap-design); }
.timeline-task.plans { --ton: var(--etap-plany); }
.timeline-task.production, .timeline-task.orders { --ton: var(--etap-produkcja); }
.timeline-task.assembly { --ton: var(--etap-montaz); }
.timeline-task.transport { --ton: var(--warn); }
.timeline-task.certification { --ton: var(--etap-certyfikacja); }
.timeline-task.warranty { --ton: var(--etap-gwarancja); }
.timeline-task.late { --ton: var(--danger); }
.timeline-task.planned { --ton: var(--status-oczekuje); }/* Pozycja konsultacji otwiera okno przypomnienia; nie da się jej przeciągać. */
.timeline-task.is-consult { cursor: pointer; }
.timeline-task.dragging { z-index: 2; opacity: .8; cursor: grabbing; }
.timeline-task.drag-ready, .timeline-task.resizing { z-index: 2; outline: 2px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.timeline-task.resize-left { box-shadow: inset var(--s-1) 0 0 var(--accent), var(--cien-2); }
.timeline-task.resize-right { box-shadow: inset calc(var(--s-1) * -1) 0 0 var(--accent), var(--cien-2); }
/* Uchwyt zmiany terminu — szerszy niż widać, żeby dało się w niego trafić. */
.resize-handle { position: absolute; top: 0; bottom: 0; z-index: 1; width: var(--s-3); cursor: ew-resize; }
.resize-handle.left { left: 0; }
.resize-handle.right { right: 0; }
.resize-handle:hover { background: color-mix(in srgb, var(--accent) 35%, transparent); }
/* POPR2-x05: pasek zaczyna się przed widocznym okresem — przycięty do pierwszego widocznego dnia (timeline-paski-przed-oknem.js):
   „←” przed tytułem, prosty przerywany lewy bok, bez uchwytu początku. Schowany w całości pod kolumną nazw — niewidoczny.
   Przy przycinaniu położenie zmienia się co klatkę przewijania, więc bez animacji left/width (zostaje przy przeciąganiu). */
.timeline[data-przycinanie] .timeline-task:not(.dragging):not(.resizing) { transition: box-shadow var(--szybko), transform var(--szybko); }
.timeline-task.is-przed-oknem { border-left-style: dashed; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.timeline-task.is-przed-oknem .task-title::before { content: "← "; }
.timeline-task.is-przed-oknem .resize-handle.left { display: none; }
.timeline-task.is-pod-nazwami { visibility: hidden; }
/* === 5. PANEL, LEGENDA, STAN PUSTY ========================================= */
.timeline-panel { padding: var(--s-4); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--cien-1); }
.timeline-panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); margin-bottom: var(--s-3); padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.timeline-panel-head h3 { font-size: var(--t-md); }
/* Komunikat „brak pozycji" jest szeroki na WIDOCZNY kawałek osi, a nie na całą oś,
   więc przy przewinięciu do „dziś" (a tak okno startuje) wyjeżdżał poza ekran i pusty
   Timeline wyglądał na zepsuty. Przypinamy go do lewej krawędzi tą samą metodą co
   kolumna nazw wyżej. Widać to od 13.08.2026, odkąd widok „Mój" normalnie kończy się
   pustą listą. */
.timeline-empty { position: sticky; left: 0; padding: var(--s-4); border-top: 1px solid var(--line); color: var(--text-faint); font-style: italic; }
/* Legenda przyklejona do lewej jak „Brak zadań…” wyżej — po przewinięciu osi do „dziś” uciekała za lewą krawędź
   (na telefonie widać było samo „…anowany”). */
.timeline-footer { position: sticky; left: 0; display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-2) var(--s-4); padding: var(--s-2) var(--s-3); color: var(--text-muted); font-size: var(--t-xs); }
.status-dot { display: inline-block; width: var(--s-2); height: var(--s-2); margin-right: var(--s-1); border-radius: var(--r-pill); background: var(--text-faint); vertical-align: middle; }
.status-dot.active { background: var(--status-wtoku); }
.status-dot.late { background: var(--danger); }
.status-dot.planned { background: var(--status-oczekuje); }
/* === 6. KONSULTACJE — karty projektów z przypomnieniami ==================== */
.consult-gantt-wrap { margin-bottom: var(--s-3); }
.consult-gantt-label { display: inline-flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-2); }
/* Karty same dobierają liczbę kolumn — jedna reguła zamiast progów @media. */
.consult-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: var(--s-3); }
/* Pusta lista kart: napis na całą szerokość panelu i bez własnej kreski (kreskę ma już nagłówek panelu). Stał w pierwszej
   kolumnie siatki (340 px) z kreską nad sobą — pod nagłówkiem wisiał krótki, urwany odcinek linii (przegląd E1, 27.09). */
.consult-grid > .timeline-empty { grid-column: 1 / -1; position: static; border-top: 0; }
.consult-card { display: flex; flex-direction: column; gap: var(--s-3); padding: var(--s-3); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--cien-1); transition: box-shadow var(--wolno), border-color var(--wolno); }
.consult-card:hover { border-color: var(--line-strong); box-shadow: var(--cien-2); }
/* Zaległe przypomnienia = czerwona ramka i jasnoczerwone tło karty (POPR-n45: bez paska z lewej). */
.consult-card.has-overdue { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); background: color-mix(in srgb, var(--danger) 5%, var(--surface)); }
/* Nagłówek karty zawija się CAŁYMI blokami: gdy obok nazwy nie mieszczą się plakietki „Konsultacje / Oczekuje”, schodzą
   one pod nazwę. Dotąd w karcie 340 px nazwa łamała się na 2–3 linie, klient też, a „Oczekuje” spadało pod „Konsultacje”
   z samotnym „/” na końcu wiersza (przegląd E1, 27.09). */
.consult-card-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--s-2); }
.consult-card-title { display: flex; flex: 1 1 180px; flex-direction: column; gap: var(--s-1); min-width: 0; }
.consult-card-title strong { color: var(--accent-strong); }
.consult-card-name { font-weight: var(--w-medium); }
.consult-card-client { display: inline-flex; align-items: center; gap: var(--s-1); color: var(--text-muted); font-size: var(--t-sm); }
.consult-card-meta { display: flex; flex-direction: column; align-items: flex-end; gap: var(--s-1); }
.consult-card-meta .status-badge-pair { flex-wrap: nowrap; }
.consult-badge { padding: 0 var(--s-2); border-radius: var(--r-pill); background: var(--danger-soft); color: var(--danger); font-size: var(--t-xs); font-weight: var(--w-bold); white-space: nowrap; }
.consult-add-btn { align-self: flex-start; }
/* 14.09.2026: styl wyjęty z atrybutu style (miał !important). Przycisk jak każdy pomocniczy (szary), dzwonek w kolorze przypomnień. */
.consult-add-btn .icon { background: var(--reminder); }
.reminder-list { display: flex; flex-direction: column; gap: var(--s-1); }
.reminder-item { display: flex; align-items: flex-start; gap: var(--s-2); padding: var(--s-2); border: 1px solid var(--line); border-radius: var(--r); transition: border-color var(--szybko), background var(--szybko); }
/* Ujednolicenie 11.08.2026 — reguła wyżej deklarowała PRZEJŚCIE tła i ramki,
   a nie istniała żadna reguła `:hover`, do której to przejście miałoby prowadzić.
   Przypomnienie jest klikalne (`.reminder-body` ma `cursor: pointer`), więc
   dostaje ten sam odzew co każdy inny wiersz listy w aplikacji. */
.reminder-item:hover { border-color: var(--line-strong); background: var(--surface-2); }
.reminder-item.is-overdue { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); background: var(--danger-soft); }
.reminder-body { display: flex; flex-direction: column; gap: var(--s-1); flex: 1; min-width: 0; text-align: left; cursor: pointer; }
.reminder-type { display: inline-flex; align-items: center; gap: var(--s-2); font-weight: var(--w-medium); }
.reminder-due { display: inline-flex; align-items: center; gap: var(--s-1); color: var(--text-muted); font-size: var(--t-xs); }
.reminder-due.overdue { color: var(--danger); font-weight: var(--w-bold); }
.reminder-due.soon { color: var(--warn-strong); font-weight: var(--w-bold); }
/* Okno „Dodaj przypomnienie": typ (siatka 2 kolumn) + termin + cykl. */
.consult-rem-section { display: flex; flex-direction: column; gap: var(--s-2); }
.consult-type-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
.consult-type-btn { display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--h-control); padding: 0 var(--s-3); border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); text-align: left; cursor: pointer; }
.consult-recur-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.consult-recur-btn { min-height: var(--h-control-sm); padding: 0 var(--s-3); border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface); color: var(--text-muted); font-size: var(--t-sm); cursor: pointer; }
.consult-type-btn:hover, .consult-recur-btn:hover { background: var(--surface-2); }
.consult-type-btn.is-sel, .consult-recur-btn.is-sel { border-color: var(--accent-strong); background: var(--accent-soft); color: var(--accent-strong); font-weight: var(--w-medium); }
/* === 7. ODHACZANIE — zakładka Gwarancja i wiersze w kartach konsultacji ==== */
.checklist { display: grid; gap: var(--s-2); max-width: 760px; }
/* Pole „dodaj" w przerywanej ramce — zaproszenie, nie gotowy wiersz listy. POPR3-pola: tło i kolor ramki jak każde pole
   do wpisania (--pole-tlo, --pole-ramka) — szare wypełnienie wyglądało jak pole zablokowane; przerywana linia zostaje. */
.checklist-add { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-3); border: 1px dashed var(--pole-ramka); border-radius: var(--r); background: var(--pole-tlo); }
/* `:not(...)` = podbicie szczegółowości do (0,3,1) — patrz uwaga przy `.timeline-search input`. */
.checklist-add input:not([type="checkbox"]):not([type="radio"]) { flex: 1; min-height: 0; padding: 0; border: 0; border-radius: 0; background: transparent; }
.checklist-list { display: flex; flex-direction: column; gap: var(--s-2); }
.checklist-item { display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-2) var(--s-3); border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.checklist-item:hover { border-color: var(--line-strong); box-shadow: var(--cien-1); }
/* Ptaszek jest przezroczysty aż do odhaczenia — puste pole zostaje puste. */
.checklist-check { display: grid; place-items: center; flex: 0 0 auto; width: var(--h-control-sm); height: var(--h-control-sm); border: 2px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); color: transparent; cursor: pointer; }
.checklist-check:hover { border-color: var(--ok-strong); }
.checklist-item.is-done .checklist-check, .checklist-check.checked { border-color: var(--ok-strong); background: var(--ok); color: var(--text-invert); }
.checklist-body { flex: 1; min-width: 0; }
.checklist-text { font-weight: var(--w-medium); word-break: break-word; }
.checklist-item.is-done .checklist-text { color: var(--text-muted); font-weight: var(--w-regular); text-decoration: line-through; }
.checklist-meta { color: var(--text-muted); font-size: var(--t-xs); }
/* Akcje wiersza wychodzą spod kursora — lista zostaje spokojna. */
.checklist-row-actions { display: flex; align-items: center; gap: var(--s-1); flex: 0 0 auto; opacity: 0; transition: opacity var(--szybko); }
.checklist-item:hover .checklist-row-actions { opacity: 1; }
.checklist-empty { padding: var(--s-3); border: 1px dashed var(--line); border-radius: var(--r); color: var(--text-faint); text-align: center; }
.checklist-done-group { margin-top: var(--s-3); padding-top: var(--s-2); border-top: 1px solid var(--line); }
.checklist-done-head { display: flex; align-items: center; gap: var(--s-2); color: var(--text-muted); font-weight: var(--w-bold); cursor: pointer; }
.checklist-done-count { padding: 0 var(--s-2); border-radius: var(--r-pill); background: var(--surface-2); font-size: var(--t-xs); }
/* === 7a. CHECKLISTA — plakietka, zrobione, edycja, przypomnienie ========== (z dawnego 26, K15)
   Widok „Gwarancja" (jedyna żywa checklista) miesza dwa rodzaje wierszy:
   REALNE zadania gwarancyjne z bazy i prywatne notatki z localStorage.
   14-timeline.css opisuje sam wiersz; tutaj trzy rzeczy, których tam nie było. */
/* Znacznik „projekt" odróżnia zadanie z bazy od notatki własnej — sama ramka
   w tonie etapu, bez wypełnienia, żeby nie konkurował z treścią wiersza. */
/* Ujednolicenie 11.08.2026 — rozstrzelenie wersalików .5px (= .055em przy 9 px)
   sprowadzone do kanonu .04em; w aplikacji było .02/.03/.04/.05 i te same
   podpisy miały różną gęstość. Stopień i waga zostają: to plakietka w tonie
   etapu, a nie podpis nagłówkowy sekcji. */
/* Ujednolicenie 11.08.2026 — pozioma wyściółka pigułki 7px → --s-2 (8px):
   `.status-pill` (05-komponenty) i `.project-type-badge` (29) mają --s-2,
   ta jedna wyłamywała się o piksel. Pion 2px zostaje — poniżej skali. */
.checklist-task-badge { padding: 2px var(--s-2); border: 1px solid color-mix(in srgb, var(--etap-design) 45%, transparent); border-radius: var(--r-pill); color: var(--etap-design); font-size: var(--t-3xs); font-weight: var(--w-bold); }
/* Zrobione zostają na liście, tylko przygaszone — świeżo odhaczone chce się
   jeszcze zobaczyć, zanim zwinie się sekcję. */
.checklist-list-done { margin-top: var(--s-2); opacity: .85; }
/* Edycja wpisu w miejscu: JS podmienia akapit na pole. Ramka w kolorze akcentu
   mówi „to jest teraz edytowane"; `font: inherit` trzyma tekst dokładnie tam,
   gdzie był, więc wiersz nie drga w momencie kliknięcia. */
.checklist-edit-input { width: 100%; padding: 2px 6px; border: 1px solid var(--accent); border-radius: var(--r); font: inherit; font-weight: var(--w-bold); }
/* Data przypomnienia przy wpisie (dzwonek + dzień). Zaległe na czerwono —
   to jedyny sygnał, że termin już minął. */
/* Ujednolicenie 11.08.2026 — gap 3px → --s-1 (4px). */
.note-reminder { display: inline-flex; align-items: center; gap: var(--s-1); color: var(--text-muted); font-size: var(--t-xs); }
.note-reminder .icon { width: 11px; height: 11px; }
.note-reminder.is-due { color: var(--danger); font-weight: var(--w-bold); }
/* === 8. TELEFON ============================================================ */
/* Na telefonie sterowanie nie mieści się obok szukajki i wypychało chip „Dziś"
   poza ekran — schodzi więc do własnego rzędu. Sama oś nadal się przewija. */
:where(:root[data-ui="mobile"]) .timeline-search { max-width: none; }
:where(:root[data-ui="mobile"]) .timeline-controls { width: 100%; margin-left: 0; }
:where(:root[data-ui="mobile"]) .consult-grid, :where(:root[data-ui="mobile"]) .consult-type-grid { grid-template-columns: 1fr; }
:where(:root[data-ui="mobile"]) .consult-card-head { flex-direction: column; }
:where(:root[data-ui="mobile"]) .consult-card-meta { align-items: flex-start; }
/* --- Przypomnienie konsultacji: notatka (z dawnego 28, K17) --- */
.consult-note-wrap { margin-top: var(--s-2); }
.consult-note-wrap input { width: 100%; }
:where(:root[data-ui="mobile"]) .timeline-add { flex: 1 1 100%; justify-content: center; }
:where(:root[data-ui="mobile"]) .timeline-range-switch { flex: 1 1 calc(50% - var(--s-1)); min-width: 0; }
