/* ============================================================================
   22-projekty-tabela.css — ZAWARTOŚĆ kafla projektu + drzewo etapów
   ----------------------------------------------------------------------------
   Uzupełnia 10-projekty.css (tam: rama kafla, wiersz .prow-*, siatka listy).
   Tutaj: to, co jest W ŚRODKU kafla i co rozwija się po kliknięciu.

   Renderer: public/js/widoki/projekty-lista.js. Kafel to wiersz tabeli na komputerze (.project-tile.project-row)
   i ekran projektu (.project-tile.mprojekt-tile). Wnętrze mają wspólne: etapy -> designy/oferty -> konstrukcje,
   akcje schowane w menu ⋮. POPR2-x11b (28.09.2026): usunięte reguły starej wizytówki (.tile-head, .tile-totals,
   .tile-expander…) — od POPR-n11 tablet i telefon mają kartę .mkarta, a funkcje wizytówki usunął POPR2-x11.

   Trzy poziomy akordeonu, wszystkie na klasie .open (nadaje ją JS):
     .project-tile.open      -> .tile-stages-wrap        (etapy projektu)
     .tile-stage-item.open   -> .tile-constr-wrap        (wnętrze etapu)
     .tile-design-group.open -> .tile-design-constr-wrap (konstrukcje designu)
   ============================================================================ */
/* Strzałki rozwijania (pasek etapów, etap, Design/oferta) — ikona „chevron-down” z zestawu ikon programu, ta sama co w listach
   rozwijanych i na stronie projektu, w kwadracie 20 px wyśrodkowanym w wierszu. Dotąd znak tekstowy „⌄” z kroju zastępczego
   siedział nisko pod linią tekstu i był mniejszy niż strzałki w innych miejscach (przegląd E1, 27.09). */
.tile-stage-chevron, .tile-design-chevron { display: inline-grid; flex: none; place-items: center; width: 20px; height: 20px; color: var(--text-faint); transition: transform var(--wolno); }
/* Trzy poziomy rozwijania. Bez tego kafel pokazywałby całe drzewo naraz. */
/* Wyglad przeniesiony z 10-projekty 05.08.2026 — stal w innym pliku niz reguly
   pokazywania, wiec zeby zrozumiec ten element trzeba bylo czytac dwa arkusze. */
.tile-stages-wrap { display: none; border-top: 1px solid var(--line); background: var(--surface-2); padding: var(--s-3) var(--s-4); }
.project-tile.open .tile-stages-wrap { display: block; }
.tile-constr-wrap { display: none; }
.tile-stage-item.open .tile-constr-wrap { display: block; margin-top: var(--s-2); }
.tile-design-constr-wrap { display: none; }
.tile-design-group.open .tile-design-constr-wrap { display: block; }
/* ============================================================================
   ETAP W KAFLU — nagłówek (nazwa + koszt + ⋮) i podrząd (status + licznik)
   ============================================================================ */
.tile-stage-row { display: flex; align-items: center; gap: var(--s-2); }
.tile-stage-head { display: flex; flex: 1; align-items: center; gap: var(--s-2); min-width: 0; }
.tile-stage-name { flex: 1; font-size: var(--t-base); font-weight: var(--w-bold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile-stage-cost { flex: none; font-size: var(--t-base); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tile-stage-item.open .tile-stage-chevron { transform: rotate(180deg); }
/* STAŁA WYSOKOŚĆ RZĘDU — kafelki etapów muszą mieć jedną wysokość niezależnie
   od tego, czy etap ma pigułkę statusu. Zmierzone przed poprawką: „Konsultacje"
   (bez pigułki) 59.1 px, „Etap Design" (z pigułką „W toku") 68.5 px. Cała
   różnica siedziała TU: rząd bez pigułki mierzył 14.5 px, z pigułką 23.9 px.
   24 px to wysokość pigułki statusu — rezerwujemy ją zawsze, więc kafelek
   nie skacze w zależności od tego, czy etap ma nadany status. */
.tile-stage-sub { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); min-height: var(--s-5); }
.tile-stage-count { font-size: var(--t-xs); color: var(--text-muted); }
/* Etap z zawartością rozwija się kliknięciem w cały nagłówek, nie tylko w chevron */
.tile-stage-item.has-constr .tile-stage-row { cursor: pointer; }
.tile-stage-item.has-constr .tile-stage-sub { cursor: pointer; }
/* Otwarte menu ⋮ nie może zostać przycięte. Przycinających warstw są DWIE,
   nie jedna: ramka etapu `.tile-stage-item` ORAZ kafel projektu
   `.project-tile` — obie mają `overflow: hidden` (arkusz 10). Zwolnienie
   tylko tej pierwszej nic nie dawało: panel wychodził poza kafelek etapu
   i od razu ścinał go kafel projektu, więc z menu widać było jedną pozycję
   i połowę drugiej. Zwalniamy obie na czas otwarcia menu. */
.tile-stage-item:has(.tile-menu-panel:not([hidden])),
.project-tile:has(.tile-menu-panel:not([hidden])) { overflow: visible; }
/* Trzecia warstwa — szara wanna `.project-table` — przycina i zwolnić się
   NIE DA: potrzebuje `overflow-x: hidden` na nadmiar szerokości wiersza,
   a CSS nie pozwala trzymać tego razem z `overflow-y: visible`.
   Zamiast rozpychać wannę wyściółką (co przesuwało układ i psuło narożnik),
   menu po prostu otwiera się W GÓRĘ, gdy pod spodem brakuje miejsca.
   Kierunek ustala JS jedną klasą — patrz public/js/widoki/projekty-lista.js. */
.tile-menu-panel.otwiera-w-gore { top: auto; bottom: calc(100% + var(--s-1)); }
.tile-stage-empty { padding: var(--s-3); border-radius: var(--r); background: var(--surface-2); color: var(--text-muted); font-size: var(--t-base); text-align: center; }
/* ============================================================================
   MENU ⋮ — wszystkie akcje wiersza schowane pod trzema kropkami
   ============================================================================ */
.tile-menu { position: relative; flex: none; }
.tile-menu-btn { display: grid; place-items: center; width: var(--h-control-sm); height: var(--h-control-sm); padding: 0; border: 1px solid transparent; border-radius: var(--r-sm); background: transparent; color: var(--text-muted); line-height: 1; cursor: pointer; transition: border-color var(--szybko), background var(--szybko), color var(--szybko); }
.tile-menu-btn:hover { border-color: var(--line); background: var(--surface-2); color: var(--accent-strong); }
.tile-menu:has(.tile-menu-panel:not([hidden])) .tile-menu-btn { border-color: var(--line); background: var(--surface-2); color: var(--accent-strong); }
/* Ujednolicenie 11.08.2026 — jeden wzorzec panelu pływającego: --r +
   --line-strong + --cien-2 (jak .combo-panel 03:142). --cien-3 to głębia okna
   modalnego, menu podręczne nie ma prawa być cięższe od okna. */
.tile-menu-panel { position: absolute; right: 0; top: calc(100% + var(--s-1)); z-index: var(--z-menu-nad-trescia); display: flex; flex-direction: column; gap: 2px; min-width: 190px; padding: var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); box-shadow: var(--cien-2); }
/* [hidden] MUSI wygrać z display:flex powyżej — inaczej panel wisi otwarty */
.tile-menu-panel[hidden] { display: none; }
.tile-menu-panel button { display: block; width: 100%; min-height: 0; padding: var(--s-2) var(--s-3); border: 0; border-radius: var(--r-sm); background: transparent; box-shadow: none; color: var(--text); font-size: var(--t-control); font-weight: var(--w-bold); text-align: left; cursor: pointer; }
.tile-menu-panel button:hover { background: var(--surface-2); }
.tile-menu-panel .danger { color: var(--danger); }
/* renderStageActions oddaje przyciski w poziomych opakowaniach — w menu mają iść w pionie */
.tile-menu-panel .inline-actions, .tile-menu-panel .row-actions, .tile-menu-panel .row-action-left, .tile-menu-panel .row-action-right { display: contents; }
/* Przyciski „tylko ikona" z renderStageActions dostają w menu etykietę tekstową */
.tile-menu-panel .icon { display: none; }
.tile-menu-panel .delete-stage-button::after { content: "Usuń etap"; }
.tile-menu-panel .delete-design-button::after { content: "Usuń design"; }
.tile-menu-panel .delete-construction-button::after { content: "Usuń konstrukcję"; }
/* ============================================================================
   MENU „Dodaj etap" (details/summary) — zakotwiczone pod przyciskiem
   ============================================================================ */
.project-stage-menu { position: relative; }
.project-stage-trigger { list-style: none; cursor: pointer; }
.project-stage-trigger::-webkit-details-marker { display: none; }
.project-stage-trigger::marker { content: ""; }
/* NAPRAWA 11.08.2026 — MENU BYLO PRZYCINANE. Zmierzone na zywej stronie:
   panel `position: absolute` siedzial w lancuchu PIECIU przodkow z overflow —
   `.project-tile` (10:88, hidden), `.project-table` (10:86), `.main-grid`
   (28:17), `.content`, `.app-shell` — i przy 5 pozycjach byl ucinany.
   PRAWDZIWA PRZYCZYNA: `10-events.js:635-644` JUZ liczy wspolrzedne EKRANOWE
   przycisku i zapisuje je do trzech zmiennych (--project-stage-menu-top/left/
   width), lacznie z odwracaniem menu W GORE gdy nie miesci sie na dole. CSS
   tych zmiennych NIGDY NIE CZYTAL — caly mechanizm byl martwy.
   `fixed` wyprowadza panel poza kazdy overflow. `right: auto` JEST KONIECZNE:
   razem z `left` wymusiloby szerokosc i zignorowalo `width`.
   `min-width` 210 -> 205, bo tyle wynosi podloga w JS (10-events.js:636).
   To ten sam wzorzec, ktory projekt juz stosuje dla `.combo-panel` (03:129). */
/* Ujednolicenie 11.08.2026 — ramka --line-strong i cień --cien-2 jak w każdym
   innym panelu pływającym. Pozycjonowania (fixed + zmienne --project-stage-menu-*)
   NIE RUSZAMY — to naprawa przycinania z 11.08. */
.project-stage-menu-panel { position: fixed; top: var(--project-stage-menu-top, auto); left: var(--project-stage-menu-left, auto); right: auto; width: var(--project-stage-menu-width, auto); z-index: var(--z-menu-nad-trescia); display: flex; flex-direction: column; gap: 2px; min-width: 205px; max-height: 320px; overflow: auto; padding: var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); box-shadow: var(--cien-2); }
/* Wysokość z tokenu, nie z wyściółki — pozycja menu mierzyła 32.5 px zamiast
   równych 32, bo zależała od interlinii tekstu. */
.project-stage-menu-action { display: flex; align-items: center; gap: var(--s-2); width: 100%; min-height: var(--h-control); padding: 0 var(--s-3); border: 0; border-radius: var(--r-sm); background: transparent; color: var(--text); font-size: var(--t-control); font-weight: var(--w-bold); text-align: left; white-space: nowrap; cursor: pointer; }
.project-stage-menu-action:hover { background: var(--surface-2); }
/* M1 (18.10.2026) — „Nowy Design” u góry menu, od etapów oddziela cienka linia (wzór: .ui-mn hr w artefakcie, b39). */
.project-stage-menu-sep { display: block; flex: none; height: 0; margin: var(--s-1) 2px; border: 0; border-top: 1px solid var(--line); }
.project-stage-menu-action:disabled { color: var(--text-muted); cursor: not-allowed; }
.project-stage-menu-action:disabled:hover { background: transparent; }
/* ============================================================================
   GRUPA DESIGN / OFERTA (A, B…) — rozwijalny pasek nad listą konstrukcji
   ============================================================================ */
.tile-design-group { border: 1px solid var(--line); border-radius: var(--r); }
.tile-design-head { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2); border-radius: var(--r); background: var(--surface-2); cursor: pointer; }
.tile-design-group.open .tile-design-head { border-radius: var(--r) var(--r) 0 0; }
.tile-design-label { flex: 0 1 auto; min-width: 0; font-weight: var(--w-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Tura 5: licznik („2 KONSTRUKCJE", 11 px) oddaje miejsce PIERWSZY (duży współczynnik kurczenia, wielokropek),
   nazwa („Oferta A", „Design B") dopiero po nim — przy 1280–1366 px nazwa ścinała się do „O.". */
.tile-design-count { flex: 0 100 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: var(--t-3xs); color: var(--text-faint); white-space: nowrap; }
.tile-design-cost { flex: none; margin-left: auto; font-size: var(--t-base); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tile-design-chevron { margin-left: auto; }
.tile-design-group.open .tile-design-chevron { transform: rotate(180deg); }
.tile-design-head > .tile-menu { margin-left: var(--s-2); }
.tile-constr-sublist { display: flex; flex-direction: column; gap: var(--s-1); padding: var(--s-2); }
.tile-constr-empty { padding: var(--s-1) 2px; color: var(--text-muted); font-size: var(--t-sm); }
/* ============================================================================
   WIERSZ KONSTRUKCJI / POZYCJI — tło i ramka na CAŁYM wierszu, ⋮ w środku
   ============================================================================ */
.tile-constr-list { display: flex; flex-direction: column; gap: var(--s-2); }
.tile-constr-item { display: flex; align-items: center; gap: 2px; padding-right: var(--s-1); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); transition: border-color var(--szybko), background var(--szybko); }
.tile-constr-item:hover { border-color: var(--accent-strong); background: var(--surface-2); }
.tile-constr-open { display: flex; flex: 1; align-items: center; gap: var(--s-2); min-width: 0; padding: var(--s-2) var(--s-3); border: 0; border-radius: var(--r-sm); background: transparent; text-align: left; cursor: pointer; }
.tile-constr-body { display: flex; flex: 1; flex-direction: column; gap: 2px; min-width: 0; }
/* Bezklasowe spany w wierszu konstrukcji (metryki) — 600 jak monolit.
   Nazwa i koszt mają WŁASNE reguły niżej, więc ich to nie dotyczy. */
.tile-constr-open > span:not([class]) { font-weight: var(--w-bold); }
.tile-constr-name { font-size: var(--t-sm); font-weight: var(--w-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tile-constr-metrics { font-size: var(--t-xs); color: var(--text-muted); }
.tile-constr-cost { flex: none; font-size: var(--t-base); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tile-constr-statuswrap { display: inline-flex; flex: none; align-items: center; margin-left: auto; }
/* ============================================================================
   TABELA DRZEWA W KAFLU (.tree-table.tile-stage-table)
   ----------------------------------------------------------------------------
   Ostatni ŻYWY użytek `tree-table`: etapy bez własnego kompaktowego renderu
   (legacy konsultacje, etapy własne) idą przez renderStageChildren i wracają
   jako 9-kolumnowe <tr class="tree-row">. Tabela nie może rozepchać kafla —
   zwija się do jego szerokości i przewija poziomo.
   ============================================================================ */
.tile-stage-table { display: block; width: 100%; max-width: 100%; min-width: 0; overflow-x: auto; }
.tile-stage-table > tbody { display: table; width: max-content; min-width: 100%; }
.tree-table td { padding: var(--s-1) var(--s-2); border-bottom: 1px solid var(--line); font-size: var(--t-xs); line-height: var(--lh-tight); vertical-align: middle; }
/* Ujednolicenie 11.08.2026 — ostatni wiersz bez kreski, jak w pozostałych
   tabelach (kafel rysuje własną krawędź, druga robi podwójną). */
.tree-table tbody tr:last-child td { border-bottom: 0; }
.tree-table .price-cell { text-align: center; white-space: nowrap; }
.tree-row { transition: background var(--szybko); }
.tree-row:hover { background: var(--surface-2); }
/* Ujednolicenie 11.08.2026 — pasek akcentu ma JEDNĄ szerokość w całej apce: --s-1. */
.tree-row.consultation-row { background: color-mix(in srgb, var(--etap-konsultacje) 8%, var(--surface)); }   /* POPR-n45: kolor etapu w tle wiersza, bez paska */
.tree-row.stage-task-row { background: var(--surface-2); }
.tree-row.empty-tree-row { color: var(--text-muted); font-style: italic; }
.tree-cell-main { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.tree-node-title { font-size: var(--t-sm); font-weight: var(--w-bold); overflow: hidden; text-overflow: ellipsis; }
.tree-indent { display: inline-block; width: var(--s-4); }
/* ============================================================================
   OSOBY: podsumowanie w wierszu (kartoteka, czat) — awatar + nazwa
   ============================================================================ */
.project-people-summary { display: inline-grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--s-2); max-width: 100%; min-width: 0; }
/* NAPRAWA 11.08.2026 — `:not(.avatar-stack)` + własna reguła dla stosu awatarów.
   Ta reguła jest przeznaczona dla NAZWISKA (ucinanie wielokropkiem), ale
   celowała w „ostatnie dziecko". W wariancie zwartym ostatnim dzieckiem jest
   STOS AWATARÓW, więc dostawał `min-width: 0` i `overflow: hidden`.
   Zmierzone na liście projektów: pojemnik miał 9 px szerokości, a cztery
   awatary w środku zajmowały 0–72 px — widać było skrawek pierwszej osoby,
   trzy pozostałe znikały całkowicie. Awatary zachodzą na siebie ujemnym
   marginesem, więc `max-content` jest tu jedyną poprawną szerokością. */
.project-people-summary > span:last-child:not(.avatar-stack) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.project-people-summary > .avatar-stack { flex: none; min-width: max-content; overflow: visible; }
/* ============================================================================
   FORMULARZ PROJEKTU — wybór uczestników i opis
   ----------------------------------------------------------------------------
   Wybrani = chipy w jednej linii; lista do wyboru wysuwa się POD chipami jako
   nakładka (nie rozpycha modala), na focus albo po klasie .is-open.
   ============================================================================ */
/* NAPRAWA 11.08.2026 — WYŚCIÓŁKA 8 px USUNIĘTA.
   Zmierzone w oknie Gwarancji: wszystkie pozostałe `.project-field-card`
   w kolumnie mają `padding: 0`, a ta jedna miała 8 px z każdej strony. Efekt:
   ramka pola „Osoby przypisane" zaczynała się 8 px głębiej i kończyła 8 px
   płycej niż Status, Data, Konstrukcja i Załączniki nad i pod nią — jedyne
   pole w formularzu wsunięte do środka. `position: relative` ZOSTAJE, bo trzyma
   układ współrzędnych dla wysuwanej listy osób. */
.project-participants-card { position: relative; align-content: start; }
.project-people-picker { position: relative; display: grid; gap: var(--s-1); min-height: 0; }
.project-people-tools { display: grid; grid-template-columns: minmax(0, 1fr) 106px; gap: var(--s-1); }
.project-participant-selected { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--s-1); min-height: 28px; overflow-x: auto; padding: var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); }
/* NAPRAWA 11.08.2026 — GEOMETRIA PIGUŁKI OSOBY („jajko z nałożonym awatarem").
   Zmierzone: pigułka 27,6 px wysokości, w środku awatar 24 px przy wyściółce
   1 px. Awatar (koło o promieniu 12) dotykał obu krawędzi pigułki, a zaokrąglony
   koniec pigułki ma przy tej wysokości promień 13,8 px — dwa różne łuki jeden na
   drugim, stąd wrażenie „jajka z doklejoną ikoną".
   Zasada: awatar w pigułce musi mieć DOOKOŁA tyle samo miejsca, ile wynosi
   różnica promieni — inaczej łuki się tną. Wysokość 27 (--h-control-sm, ta sama
   co każda kontrolka w wierszu), awatar 18 (rozmiar `.avatar.tiny`, już używany
   w aplikacji), zapas 3,5 px w pionie i 5 px od lewej — koło leży w środku
   zaokrąglenia, nie na nim.
   POPR2-awatar-projekty (28.09.2026): awatar 22 px z inicjałami 12 px (11 px w kółku 18 px było za drobne);
   wyściółka z lewej = (wysokość pigułki − 2 px ramki − 22) / 2, więc koło dalej leży w środku zaokrąglenia
   (na komputerze 1,5 px, na dotyku przy pigułce 40 px — 8 px). */
.project-participant-chip { display: inline-flex; flex: 0 0 auto; align-items: center; gap: var(--s-2); max-width: 200px; height: var(--h-control-sm); padding: 0 var(--s-2) 0 calc((var(--h-control-sm) - 2px - 22px) / 2); border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface-2); font-size: var(--t-xs); font-weight: var(--w-medium); }
.project-participant-chip .avatar { --avatar-d: 22px; }
.project-participant-chip > span { min-width: 0; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.project-participant-chip button { display: inline-grid; place-items: center; width: var(--s-4); height: var(--s-4); border: 0; border-radius: var(--r-pill); background: var(--surface); color: var(--danger); font-size: var(--t-xs); line-height: 1; cursor: pointer; transition: background var(--szybko), color var(--szybko); }
.project-participant-chip button:hover { background: var(--danger-soft); }
/* Ujednolicenie 11.08.2026 — promień panelu pływającego = --r (był --r-sm). */
.project-people-grid { position: absolute; top: calc(100% + var(--s-1)); left: 0; right: 0; z-index: var(--z-menu-nad-trescia); display: none; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); align-content: start; gap: var(--s-1); max-height: 148px; overflow: auto; padding: var(--s-1); border: 1px solid var(--line-strong); border-radius: var(--r); background: var(--surface); box-shadow: var(--cien-3); }
.project-people-picker.is-open .project-people-grid { display: grid; }
/* NAPRAWA 11.08.2026 — USUNIĘTA reguła `:focus-within`.
   Widoczność listy osób miała DWA niezależne źródła: klasę `.is-open`, którą
   świadomie ustawia i zdejmuje JS (10-events.js:609 i :3342), oraz `:focus-within`,
   którego nie kontroluje nikt. Skutek zgłoszony przez użytkownika: chwyt za pasek
   przewijania formularza zabiera fokus z pickera → reguła CSS gaśnie i lista
   ZNIKA, mimo że JS nadal uważa ją za otwartą (klasa `.is-open` na niej zostaje).
   Otwieranie działa bez tej reguły: `focusin` w JS sam nadaje `.is-open`,
   więc kliknięcie w pole wyszukiwania nadal listę rozwija — ale teraz zamyka ją
   wyłącznie to, co ma zamykać. */
.project-participant-card { position: relative; display: grid; grid-template-columns: 22px minmax(0, 1fr); align-items: center; gap: var(--s-2); min-height: 28px; min-width: 0; padding: var(--s-1) var(--s-2); border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: var(--surface); cursor: pointer; }
.project-participant-card[hidden] { display: none; }
.project-participant-card:hover { background: var(--surface-2); }
/* Ujednolicenie 11.08.2026 — pasek akcentu --s-1, jeden na całą aplikację. */
.project-participant-card.is-selected { border-color: var(--accent-strong); background: var(--accent-soft); }
/* Checkbox tylko dla klawiatury i czytnika — widoczny stan niesie sama karta */
.project-participant-checkbox { position: absolute; opacity: 0; pointer-events: none; }
.project-people-empty { display: grid; place-items: center; grid-column: 1 / -1; min-height: 44px; border: 1px dashed var(--line-strong); border-radius: var(--r-sm); color: var(--text-muted); font-size: var(--t-xs); }
.project-people-empty[hidden] { display: none; }
.project-description-card { align-self: start; min-height: 0; }
.project-description-card textarea { width: 100%; min-height: 104px; height: auto; font-size: var(--t-base); }
/* Z dawnego 29-luka-pokrycia.css (K14, v14): stare drzewo projektu (04-projects.js) — ramka i wiersze. */
.tree-wrap { max-height: calc(100vh / var(--skala-ui) - 240px); overflow-x: auto; scrollbar-gutter: stable; }
.version-branch { color: var(--text-muted); font-weight: 650; }
.tree-indent-cell { color: var(--muted); white-space: nowrap; }
.consultation-offer-cell.continuation { color: var(--muted); }
/* Ujednolicenie 11.08.2026 — pasek akcentu z lewej: w aplikacji jest 12 takich
   pasków i wszystkie mają `inset var(--s-1) 0 0`; ten jeden miał 3px. */
.premium-tree-row { background: var(--surface-2); }
/* ============================================================================
   RESPONSYWNOŚĆ — progi z kanonu (980 / telefon)
   ============================================================================ */
@media (max-width: 980px) {
  .project-people-grid { grid-template-columns: 1fr; }
  .project-people-tools { grid-template-columns: 1fr; }
}
:where(:root[data-ui="mobile"]) .tile-menu-panel { min-width: 160px; }
:where(:root[data-ui="mobile"]) .project-stage-menu-panel { min-width: 180px; }
/* --- Kafel: etapy, statusy kroków, metryki wersji (z dawnego 28, K17) --- */
/* Rozwinięte etapy: menu ⋮ etapu musi móc wyjść poza kontener. */
.tile-stages { overflow: visible; }
/* Ujednolicenie 11.08.2026 — B6: plakietka statusu jest `<button>`
   (public/js/widoki/projekty-lista.js, 04-projects.js:649/718), ale `.status-pill`
   (05-komponenty:127) nie ma hovera, a żaden arkusz go tu nie dokładał —
   klikalny element bez ANI JEDNEJ reakcji na kursor.
   Pogłębiony własny ton (--ton czyta już `.status-pill`), zero nowych barw. */
.production-step-status-button { border-radius: var(--r-pill); cursor: pointer; transition: background var(--szybko), border-color var(--szybko); }
.production-step-status-button:hover { border-color: color-mix(in srgb, var(--ton, var(--text-muted)) 55%, transparent); background: color-mix(in srgb, var(--ton, var(--text-muted)) 28%, var(--surface)); }
.tile-stage-sub .production-step-status-button { min-height: 0; padding: 1px var(--s-2); font-size: var(--t-xs); }
/* Monolit: 11px, waga 600, kolor ciemniejszy od zwykłego wyszarzenia (--gray-700
   ze starych tokenów). Odtwarzam mieszanką, żeby działało też w trybie ciemnym. */
.version-metrics { display: grid; gap: 2px; color: color-mix(in srgb, var(--text-muted) 55%, var(--text)); font-size: var(--t-xs); font-weight: var(--w-bold); line-height: var(--lh-tight); }
.version-metrics span { display: block; }
.tile-constr-metrics .version-metrics { display: flex; flex-wrap: wrap; gap: var(--s-3); margin: 0; }
.status-badge-pair { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.status-badge-sep { color: var(--text-muted); font-weight: var(--w-bold); opacity: .55; }
