/* Gleisplan — spokojny, ciemny interfejs w motywie kolejowym: jedna kolorystyka (morski turkus jak ikona aplikacji), duże zaokrąglenia,
   mało obramowań, czytelne karty. Układ: pasek projektu u góry, 4 zakładki (telefon: na dole, komputer: po lewej) i podzakładki w AI i Wiedzy. */
:root {
  --bg: #090d12; --panel: #10161d; --panel2: #171f29; --line: #212c39; --line2: #2d3a4b;
  --txt: #e8eef5; --dim: #97a4b3; --faint: #667385;
  --accent: #2dd4bf; --accent-ink: #04211e; --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent);
  --green: #4ade80; --red: #f87171; --amber: #fbbf24; --blue: var(--accent);
  --plan-bg: #fff; --cien: 0 12px 36px #0009; --szyna: #7d8896; --podklad: #3a2f26;
  --sprez: cubic-bezier(.34, 1.35, .64, 1); --plynnie: cubic-bezier(.22, .61, .36, 1);
  --gap: .6rem; --r: 14px; --r-maly: 10px;
  --st-zr: #16a34a; --st-tok: #f2b705; --st-otw: #dc2626; --wybor: #2f6bff;  /* plan: zrobione / w toku; zaznaczenie wielu elementów (inny kolor niż stan) */
  --na-kolorze: #06140f;  /* napis na kolorowym tle (stan kroku, stan planu): kolory ciemnego motywu są jasne, więc napis ciemny; jasny motyw — biały */
  /* nazwy używane przez skrypty i starsze reguły */
  --text: var(--txt); --otw: var(--faint);
  color-scheme: dark;
}
:root[data-theme="light"] {
  --bg: #f2f5f9; --panel: #ffffff; --panel2: #f4f7fa; --line: #dde4ec; --line2: #c8d2de;
  --txt: #141b24; --dim: #536171; --faint: #8493a4;
  --accent: #0f766e; --accent-ink: #ffffff; --na-kolorze: #ffffff;
  --green: #15803d; --red: #c62828; --amber: #b45309;
  --cien: 0 12px 30px #1b1f2425; --szyna: #6e7781; --podklad: #b9a48c;
  color-scheme: light;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; height: 100%; }
/* iPhone, aplikacja z ekranu początkowego: okno bywa niższe od ekranu o pasek stanu; app.js (dopasujWysokoscEkranu) ustawia --brak-dolu i klasę, dokument sięga krawędzi ekranu */
html.brak-dolu { height: calc(100% + var(--brak-dolu, 0px)); }
html.brak-dolu body { position: relative; }
body {
  /* rozmiar pisma i ikon jest ten sam na każdym ekranie (telefon, Duo złożony i rozłożony, poziomo): większy ekran pokazuje więcej, nie większe */
  background: var(--bg); color: var(--txt); font: 14px/1.45 "Inter", "Segoe UI", -apple-system, system-ui, sans-serif;
  display: flex; flex-direction: column; gap: .5rem; overflow: hidden;
  padding: calc(.5rem + env(safe-area-inset-top)) calc(.55rem + env(safe-area-inset-right)) calc(.5rem + env(safe-area-inset-bottom)) calc(.55rem + env(safe-area-inset-left));
  -webkit-tap-highlight-color: transparent;
}
button, select, input, textarea { font: inherit; color: inherit; }
.mono, .ozn, code, pre { font-family: "JetBrains Mono", "Consolas", ui-monospace, Menlo, monospace; }
.meta { color: var(--dim); font-size: 13px; }
.info { color: var(--dim); margin: 0 0 var(--gap); }
/* linki w treści (PDF planu, zdjęcia, „delete” przy notatce i polu) w kolorach aplikacji — domyślny niebieski i fioletowy „odwiedzony” przeglądarki był słabo czytelny na ciemnym tle */
a { color: var(--accent); text-underline-offset: .15em; }
a[data-usun-notatke], a[data-usun-pole] { color: var(--red); }
/* ✕ przy polu szablonu: większe pole stuknięcia (wysokość wiersza bez zmian — dopełnienie elementu w linii nie rozpycha wiersza) */
a[data-usun-pole] { padding: 9px 7px; margin: 0 -7px 0 -3px; text-decoration: none; touch-action: manipulation; }
h2, h3 { letter-spacing: .005em; }
h3 { font-size: 1.02rem; }

/* ---------- przyciski i pola ---------- */
a.przycisk-link { text-decoration: none; }
button, a.przycisk-link {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  background: var(--panel2); color: var(--txt); border: 1px solid var(--line); border-radius: var(--r-maly);
  padding: 0 .9rem; min-height: 40px; cursor: pointer; font-weight: 550; white-space: nowrap;
  transition: transform .18s var(--sprez), background .14s ease, border-color .14s ease, box-shadow .18s ease, color .14s ease;
}
/* najechanie tylko tam, gdzie jest kursor: na ekranie dotykowym przeglądarka zostawia je na ostatnio stukniętym elemencie (przycisk z turkusową obwódką, przesunięty wiersz listy) */
@media (hover: hover) { button:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line2)); } }
button:active { transform: scale(.97); transition-duration: .05s; }
button:focus-visible, select:focus-visible, input:focus-visible, textarea:focus-visible, summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button:disabled { opacity: .45; cursor: default; transform: none; }
button.glowny {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 650;
  box-shadow: 0 4px 16px color-mix(in srgb, var(--accent) 28%, transparent);
}
@media (hover: hover) { button.glowny:hover { filter: brightness(1.08); box-shadow: 0 6px 22px color-mix(in srgb, var(--accent) 40%, transparent); } }
button.maly { min-height: 32px; padding: 0 .65rem; font-size: 13px; border-radius: 9px; }
button.ikona { width: 40px; min-height: 40px; padding: 0; border-radius: 12px; }
button.ikona.maly { width: 34px; min-height: 34px; }
button.cichy { background: transparent; border-color: transparent; color: var(--dim); }
@media (hover: hover) { button.cichy:hover { color: var(--txt); background: var(--panel2); } }
button.niebezpieczne { color: var(--red); }
.ik { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }

select, input, textarea {
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r-maly); padding: 0 .65rem; min-height: 40px; color: var(--txt);
  transition: border-color .14s ease, box-shadow .14s ease; max-width: 100%;
}
textarea { padding: .5rem .65rem; }
select:hover, input:hover, textarea:hover { border-color: var(--line2); }
select:focus, input:focus, textarea:focus { border-color: var(--accent); }
input[type="checkbox"], input[type="radio"] { min-height: 0; width: 1.05rem; height: 1.05rem; padding: 0; accent-color: var(--accent); flex: none; }
input[type="file"] { padding: .35rem .5rem; }
input[type="search"] { padding-left: .8rem; }

/* ---------- górny pasek: projekt, postęp, menu ---------- */
.gora { position: relative; flex: 0 0 auto; background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: .4rem .5rem .4rem .7rem; overflow: hidden; }  /* bez paska postępu: procent jest w przycisku obok szukania */
.gora:not(:has(.offline-baner:not([hidden]))) { display: none; }  /* projekt, postęp i szukanie są w kapsule kart — nagłówek tylko dla banera „Offline” */
.projekt-wybor { flex: 1; min-width: 0; display: flex; align-items: center; gap: .55rem; cursor: pointer; }
.projekt-wybor .logo { color: var(--accent); width: 22px; height: 22px; }
.projekt-wybor select {
  flex: 1; min-width: 0; min-height: 36px; padding: 0 .1rem; border: none; background: transparent; font-weight: 650; font-size: 1.08rem;
  text-overflow: ellipsis; cursor: pointer;
}
.projekt-wybor select option { background: var(--panel); font-weight: 500; }
.chip-postep { flex-direction: column; align-items: flex-end; gap: 0; padding: .1rem .7rem; min-height: 40px; border-radius: 12px; background: var(--panel2); line-height: 1.15; }
.chip-postep .duze { font-weight: 750; font-size: 1.1rem; }
.chip-postep small { font-size: 11px; color: var(--dim); font-weight: 450; max-width: 11rem; overflow: hidden; text-overflow: ellipsis; }
#motyw .slonce { display: none; } :root[data-theme="light"] #motyw .slonce { display: block; } :root[data-theme="light"] #motyw .ksiezyc { display: none; }

/* ---------- zakładki główne ---------- */
nav.zakladki { display: flex; align-items: stretch; gap: .25rem; position: relative; }
nav.zakladki button {
  position: relative; flex: 1; flex-direction: column; gap: 3px; min-height: 54px; padding: .25rem 0; border: none; background: transparent; color: var(--faint);
  font-size: 11px; font-weight: 600; border-radius: 12px; letter-spacing: .02em;
}
nav.zakladki button .ik { width: 23px; height: 23px; transition: transform .25s var(--sprez); }
@media (hover: hover) { nav.zakladki button:hover { color: var(--txt); background: var(--panel); } }
nav.zakladki button.aktywny { color: var(--accent); background: var(--accent-soft); }
nav.zakladki button.aktywny .ik { transform: translateY(-1px) scale(1.06); }
.odznaka { position: absolute; top: 4px; left: calc(50% + 6px); min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px; background: var(--amber); color: #1b1300;
  font: 700 10.5px/17px system-ui, sans-serif; text-align: center; font-style: normal; box-shadow: 0 0 0 2px var(--bg); }

/* podzakładki (AI: Analyses · Plans · Assistant, Wiedza: Symbols · Templates) */
.podnaw { display: flex; gap: .3rem; padding: .22rem; background: var(--panel); border: 1px solid var(--line); border-radius: 13px; flex: 0 0 auto; }
.podnaw button { flex: 1; min-height: 36px; border: none; background: transparent; color: var(--dim); font-size: 13.5px; border-radius: 10px; padding: 0 .6rem; }
.podnaw button:hover { color: var(--txt); }
.podnaw button.aktywny { background: var(--panel2); color: var(--txt); box-shadow: inset 0 0 0 1px var(--line2); }
/* podświetlenie płynie pod wybraną podkartę (app.js ustawWskaznikPodnaw): jeden pseudo-element przesuwany przekształceniem, przycisk przezroczysty;
   bez wskaźnika (schowany pasek, pierwsze rysowanie) tło rysuje sam przycisk */
.podnaw { position: relative; isolation: isolate; }
.podnaw::before { content: ""; position: absolute; z-index: -1; top: .22rem; bottom: .22rem; left: 0; width: var(--wsk-w, 0); transform: translateX(var(--wsk-x, 0));
  border-radius: 10px; background: var(--panel2); box-shadow: inset 0 0 0 1px var(--line2); opacity: 0;
  transition: transform .32s var(--sprez), width .3s var(--plynnie), opacity .15s ease; }  /* jak wskaźnik kapsuły */
.podnaw.ze-wskaznikiem::before { opacity: 1; }
.podnaw.ze-wskaznikiem button.aktywny { background: transparent; box-shadow: none; }
.podnaw button { transition: color .2s ease; }
.podnaw.bez-przejscia::before { transition: none; }
.podnaw .odznaka { position: static; margin-left: .35rem; box-shadow: none; }

/* ---------- widoki ---------- */
main { flex: 1; min-height: 0; position: relative; }
.widok {
  display: none; height: 100%; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 16px; overflow: hidden;
}
.widok.aktywny { display: flex; animation: widokWchodzi .28s var(--plynnie) both; }
#widok-szablony, #widok-import, #widok-wiedza, #widok-ai, #widok-logi { padding: .8rem; overflow: auto; }
#widok-szablony.aktywny, #widok-import.aktywny, #widok-wiedza.aktywny, #widok-ai.aktywny, #widok-logi.aktywny { display: block; }
@keyframes widokWchodzi { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes wchodzi { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes pulsLampy { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
@keyframes obrot { to { transform: rotate(360deg); } }

.pasek { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; padding: .55rem .7rem; border-bottom: 1px solid var(--line); background: var(--panel); }
.pasek label, .przelacznik { display: inline-flex; align-items: center; gap: .4rem; padding: .25rem .65rem; border: 1px solid var(--line); border-radius: 999px; cursor: pointer; font-size: 13px; color: var(--dim);
  transition: background .15s ease, border-color .15s ease, color .15s ease; user-select: none; }
.pasek label:hover { border-color: var(--line2); color: var(--txt); }
.pasek label:has(input:checked) { background: var(--accent-soft); border-color: var(--accent); color: var(--txt); }
#stronaNr { min-width: 3.6em; text-align: center; font-family: "JetBrains Mono", ui-monospace, monospace; color: var(--dim); }
#licznik { color: var(--dim); font-size: 13px; }
.sprawdz-pasek { background: var(--accent-soft); border-left: 3px solid var(--accent); }

/* wysuwane menu (details): warstwy planu, filtry listy */
.pasek { position: relative; }
details.warstwy, details.filtry { position: static; }  /* menu pozycjonowane względem paska, żeby nie wychodziło poza ekran */
details.warstwy > summary, details.filtry > summary {
  list-style: none; display: inline-flex; align-items: center; gap: .4rem; min-height: 36px; padding: 0 .75rem; cursor: pointer; user-select: none;
  background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r-maly); font-weight: 550; font-size: 13.5px;
}
details > summary::-webkit-details-marker { display: none; }
details.warstwy[open] > summary, details.filtry[open] > summary { border-color: var(--accent); color: var(--accent); }
.warstwy-lista, .filtry-lista {
  position: absolute; z-index: 15; top: calc(100% + 4px); right: .5rem; min-width: 240px; max-width: calc(100% - 1rem); display: grid; gap: .5rem; padding: .7rem; background: var(--panel);
  border: 1px solid var(--line2); border-radius: 14px; box-shadow: var(--cien);
}
/* wejście przy każdym otwarciu: treść zamkniętego <details> Chrome tylko ukrywa (nie usuwa), więc animacja na samej liście wybrzmiewała raz przy starcie,
   niewidocznie, i przy otwarciu już się nie powtarzała */
details[open] > .warstwy-lista, details[open] > .filtry-lista { animation: wchodzi .18s var(--plynnie) both; }
.filtry-lista { left: .5rem; right: auto; width: min(340px, calc(100% - 1rem)); }
.warstwy-lista label, .filtry-lista label { border-radius: 10px; }

/* ---------- plan ---------- */
#planOkno { flex: 1; overflow: hidden; position: relative; touch-action: none; background: var(--plan-bg); cursor: grab; }
/* ciemny plan (menu warstw, app.js): sam obraz planu i miniatura w odwróconych kolorach, odcienie zachowane obrotem barwy (jak „inteligentne odwracanie”
   w iOS); papier ciemnoszary i kreski jasnoszare zamiast czystej czerni i bieli — mniej oślepia. Nakładka (stany, zaznaczenia, ramki) bez odwracania, tylko
   kolory dobrane do ciemnego tła. Eksport (canvas) i AI (serwer) nie widzą filtra — biorą oryginał */
html.plan-ciemny { --plan-bg: #1a1a1a; }
html.plan-ciemny #planObraz, html.plan-ciemny .plan-mapa img { filter: invert(.9) hue-rotate(180deg); }
#planOkno:active { cursor: grabbing; }
#planWarstwa { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
#planObraz { display: block; width: 100%; height: 100%; user-select: none; -webkit-user-select: none; }
#planNakladka { position: absolute; inset: 0; width: 100%; height: 100%; }
#planNakladka .el { fill: transparent; stroke-width: 1.4px; cursor: pointer; vector-effect: non-scaling-stroke; transition: stroke-width .15s ease, fill .2s ease; }  /* obrys ma stałą grubość na ekranie, niezależnie od powiększenia */
#planNakladka .el:hover { stroke-width: 3px; }
#planNakladka .el.otwarte { stroke: transparent; }  /* otwarte: bez obwódki, klikalne (przezroczyste wypełnienie łapie stuknięcie) */
/* stan prac w wybranym etapie (plakietka na planie): zielony = zrobione, żółty = w toku, czerwony = nic nie ruszone. Klasę ze-stanem nadaje app.js: kolory
   włączone na plakietce i (gdy w menu warstw są zaznaczone typy) element jednego z tych typów — pozostałe zostają bez kolorów. :where nie podnosi
   szczegółowości: zaznaczenie, wybór i plan pracy (późniejsze reguły) dalej wygrywają */
#planNakladka .el:where(.ze-stanem).otwarte { stroke: var(--st-otw); fill: color-mix(in srgb, var(--st-otw) 24%, transparent); stroke-width: 2px; }
#planNakladka .el:where(.ze-stanem).w_toku { stroke: var(--st-tok); fill: color-mix(in srgb, var(--st-tok) 38%, transparent); stroke-width: 2px; }
#planNakladka .el:where(.ze-stanem).zrobione { stroke: var(--st-zr); fill: color-mix(in srgb, var(--st-zr) 32%, transparent); stroke-width: 2px; }
#planNakladka .el.brak { stroke: transparent; }
#planNakladka .el.kandydat { stroke: var(--blue); stroke-width: 2.4px; fill: #0a64d833; animation: migaj 1s ease-in-out infinite alternate; }
#planNakladka .el.kandydat.zajety { stroke: var(--amber); fill: #e38b0044; }
@keyframes migaj { from { fill-opacity: .15; } to { fill-opacity: .6; } }
#planNakladka .el.bez-opisu { stroke: #6b7684; stroke-width: 1.8px; stroke-dasharray: 3px 2px; fill: #6b768422; }  /* szare: czerwień oznacza „nic nie zrobione” */
#planNakladka.filtr-typow .el.bez-opisu { stroke: transparent; fill: transparent; }  /* filtr typów w warstwach: symbole bez opisu (bez typu) też bez obrysu, dalej klikalne */
#planNakladka .el.wybrany { stroke: var(--blue); stroke-width: 3px; stroke-dasharray: none; filter: drop-shadow(0 0 3px var(--blue)); }
#planNakladka .znacznik { font: 700 5px sans-serif; pointer-events: none; }
#planNakladka .napis { fill: #0a64d811; stroke: #0a64d8; stroke-width: .6; stroke-dasharray: 1.5 1; cursor: pointer; transition: fill .15s; }
#planNakladka .napis:hover { fill: #0a64d833; }
#planNakladka .napis.kandydat { stroke: #0a64d8; stroke-width: 2; stroke-dasharray: none; fill: #0a64d833; animation: migaj 1s ease-in-out infinite alternate; }
#planNakladka .napis.km { stroke: #8a8f98; fill: #8a8f9811; }
#planNakladka .napis.ukryty { opacity: .35; }
#planNakladka .prop { cursor: pointer; stroke-width: 1.2; }
#planNakladka .prop circle { fill: #e38b0033; stroke: #e38b00; }
#planNakladka .prop.tak circle { fill: #1f9d4c44; stroke: #1f9d4c; }
#planNakladka .prop.nie circle { fill: #c6282822; stroke: #c62828; }
#planNakladka .prop.uwagi circle { stroke-width: 2.4; stroke-dasharray: 2 1; }
#planNakladka .prop text { font: 700 6px ui-monospace, Menlo, monospace; paint-order: stroke; stroke: #fff; stroke-width: 2px; fill: #111; }
#planNakladka .prop.nie text { text-decoration: line-through; fill: #c62828; }
/* ciemny plan: ciemnoniebieskie i szare obrysy ginęły na ciemnym papierze — jaśniejsze; liczniki kroków z obwódką w kolorze papieru */
html.plan-ciemny #planNakladka .napis, html.plan-ciemny #planNakladka .napis.kandydat { stroke: #6aaeff; }
html.plan-ciemny #planNakladka .napis { fill: #6aaeff14; }
html.plan-ciemny #planNakladka .napis:hover, html.plan-ciemny #planNakladka .napis.kandydat, html.plan-ciemny #planNakladka .el.kandydat { fill: #6aaeff33; }
html.plan-ciemny #planNakladka .el.bez-opisu { stroke: #a3acb7; fill: #a3acb722; }
html.plan-ciemny #planNakladka .znacznik { paint-order: stroke; stroke: var(--plan-bg); stroke-width: 1.4px; }

/* ---------- szyny: pasek postępu (dwie szyny, podkłady, lokomotywa na końcu) ---------- */
.szyna { position: relative; display: inline-block; vertical-align: middle; width: 92px; height: 14px; border-radius: 3px; overflow: hidden; }
.szyna { background:
  linear-gradient(var(--szyna), var(--szyna)) 0 3px / 100% 1.5px no-repeat,
  linear-gradient(var(--szyna), var(--szyna)) 0 9.5px / 100% 1.5px no-repeat,
  repeating-linear-gradient(90deg, transparent 0 6px, color-mix(in srgb, var(--podklad) 90%, transparent) 6px 8px); }
.szyna b { position: absolute; left: 0; top: 0; bottom: 0; width: var(--p, 0%); animation: szynaWchodzi .5s var(--plynnie) both;
  background: linear-gradient(90deg, color-mix(in srgb, var(--green) 25%, transparent), color-mix(in srgb, var(--green) 55%, transparent));
  border-right: 3px solid var(--green); box-shadow: 4px 0 10px color-mix(in srgb, var(--green) 55%, transparent); border-radius: 0 3px 3px 0; }
.szyna b::after { content: ""; position: absolute; right: -5px; top: 2px; width: 8px; height: 10px; background: var(--green); border-radius: 2px 4px 4px 2px; box-shadow: 0 0 8px var(--green); }
.szyna.w-toku b { border-color: var(--amber); box-shadow: 4px 0 10px color-mix(in srgb, var(--amber) 55%, transparent); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--amber) 45%, transparent)); }
.szyna.w-toku b::after { background: var(--amber); box-shadow: 0 0 8px var(--amber); }
.szyna.duza { width: 100%; height: 18px; } .szyna.duza b::after { top: 3px; height: 12px; width: 10px; }
/* pasek wjeżdża przesunięciem (lokomotywa przyjeżdża z lewej): bez animowania szerokości, która w liście z setkami wierszy przeliczała układ w każdej klatce */
@keyframes szynaWchodzi { from { transform: translateX(-100%); } }  /* bez sprężystego przestrzelenia: pasek postępu nie może na chwilę pokazywać więcej, niż jest zrobione */

/* ---------- lista: wiersze jak karty pozycji w panelu bota ---------- */
.tabela-wrap { flex: 1; overflow: auto; padding: 0 var(--gap) var(--gap); }
table { border-collapse: separate; border-spacing: 0 5px; width: 100%; }
th, td { text-align: left; padding: .5rem .75rem; white-space: nowrap; }
th { position: sticky; top: 0; background: var(--panel); cursor: pointer; user-select: none; z-index: 2; font-size: .66rem; letter-spacing: .09em; text-transform: uppercase; color: var(--faint); font-weight: 600; transition: color .14s; }
th:hover { color: var(--txt); }
th.sort-asc, th.sort-desc { color: var(--blue); }
th.sort-asc::after { content: " ▲"; } th.sort-desc::after { content: " ▼"; }
tbody tr { cursor: pointer; transition: transform .2s var(--sprez); }
tbody tr td { background: var(--panel2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); transition: border-color .14s; }
tbody tr td:first-child { border-left: 3px solid var(--line2); border-radius: .55rem 0 0 .55rem; }
tbody tr td:last-child { border-right: 1px solid var(--line); border-radius: 0 .55rem .55rem 0; }
@media (hover: hover) {
  tbody tr:hover { transform: translateX(3px); }
  tbody tr:hover td { border-top-color: var(--blue); border-bottom-color: var(--blue); }
  tbody tr:hover td:first-child { border-left-color: var(--blue); box-shadow: -4px 0 12px -4px var(--blue); }
  tbody tr:hover td:last-child { border-right-color: var(--blue); }
}
tbody tr.zrobione td:first-child { border-left-color: var(--green); } tbody tr.w_toku td:first-child { border-left-color: var(--amber); }



.ozn { font-weight: 700; }

/* ---------- okno elementu (dialog) ---------- */
dialog {
  border: 1px solid var(--line2); border-radius: .9rem; padding: 0; width: min(580px, 96vw); max-height: 90vh; max-height: 90dvh; background: var(--panel); color: var(--txt); box-shadow: var(--cien);
}
dialog[open] { animation: okienko .34s var(--sprez) both; }
dialog:focus { outline: none; }  /* fokus na samym oknie po otwarciu stuknięciem (ruch.js fokusBezObwodki) — bez obwódki wokół całego okna */
dialog::backdrop { opacity: var(--tlo, 1); background: color-mix(in srgb, #000 55%, transparent); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); animation: tloWchodzi .25s ease both; }
@keyframes okienko { from { opacity: 0; transform: translateY(24px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes tloWchodzi { from { opacity: 0; } }
#oknoTresc { padding: 1rem; overflow: auto; max-height: 90vh; max-height: 90dvh; }
.okno-naglowek { display: flex; justify-content: space-between; gap: 8px; align-items: start; }
.okno-naglowek h2 { margin: 0; font-size: 1.4rem; }
/* ---------- konta (21.10.2026) ---------- */
/* osoba z internetu (main.strona_glowna: klasa „gosc”): bez AI, Wiedzy, Logów, ustawień projektu, importu, usuwania i narzędzi zmieniających plan — serwer
   i tak ich nie wpuszcza (app/dostep.py), tu tylko nie ma przycisków, które kończyłyby się błędem */
html.gosc nav.zakladki button[data-widok="ai"], html.gosc nav.zakladki button[data-widok="wiedza"], html.gosc nav.zakladki button[data-widok="logi"],
html.gosc #ustawieniaProjektu, html.gosc #nowyProjektBtn, html.gosc #usunProjekt, html.gosc #offlineZapis, html.gosc #kontaBtn,
html.gosc #oknoTresc details.narzedzia, html.gosc #oknoTresc [data-akcja="przesun"], html.gosc #oknoTresc [data-akcja="znacznik-usun"],
html.gosc #oknoTresc [data-akcja="przesun-cofnij"], html.gosc #oknoTresc [data-akcja="wskaz-opis"],
html.gosc #oknoTresc .krok-stopka [data-akcja="pole"], html.gosc #oknoTresc .krok-stopka [data-akcja="usun-krok"], html.gosc #oknoTresc form[data-form="krok"],
html.gosc .fs-raport { display: none !important; }
/* z internetu, projekt tylko do podglądu (21.10.2026): bez przycisków zmian (serwer i tak ich nie przyjmie); stan kroków, wartości pól i plan pracy widać dalej */
html.tylko-podglad #oknoTresc .krok .statusy, html.tylko-podglad #oknoTresc .krok .pola, html.tylko-podglad #oknoTresc .kabel-blok input,
html.tylko-podglad #pracaTytul, html.tylko-podglad #pracaLista textarea { pointer-events: none; }
html.tylko-podglad #oknoTresc .krok .pola input[type="file"], html.tylko-podglad #oknoTresc .do-pracy-wiersz, html.tylko-podglad #oknoTresc form[data-form="notatka"],
html.tylko-podglad #oknoTresc [data-usun-notatke], html.tylko-podglad [data-zaznacz-tryb], html.tylko-podglad #zaznaczPasek, html.tylko-podglad .praca-dodaj,
html.tylko-podglad #pracaDodajListe, html.tylko-podglad #pracaWyczysc, html.tylko-podglad .praca-akcje [data-praca="gora"], html.tylko-podglad .praca-akcje [data-praca="dol"],
html.tylko-podglad .praca-akcje [data-praca="usun"] { display: none !important; }
.menu-konto { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .3rem .2rem .5rem; border-bottom: 1px solid var(--line); }
#kontaBtn .odznaka { position: static; margin-left: auto; }
.konta-sekcja { display: grid; gap: .55rem; margin-top: 1rem; }
.konta-sekcja h3 { margin: 0; font-size: 1rem; }
.konta-sekcja .meta { margin: 0; }
.konta-admin { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: .5rem; }
.konta-admin .szeroko { grid-column: 1 / -1; }
.konta-admin label, .konta-logowanie label { display: grid; gap: .2rem; font-size: 13px; color: var(--dim); }
.konto-karta { display: grid; gap: .5rem; padding: .7rem; border: 1px solid var(--line); border-radius: 14px; background: var(--panel2); }
.konto-karta.czeka { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
.konto-glowa { display: grid; gap: .1rem; }
.konto-glowa .meta { font-size: 12.5px; overflow-wrap: anywhere; }
.konto-prawa { display: grid; gap: .3rem; }
.konto-prawa label { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: .5rem; font-size: 14px; }
.konto-prawa label span { overflow-wrap: anywhere; }
.konto-prawa select { min-width: 8.5rem; }
.konta-logowanie summary { cursor: pointer; font-weight: 600; }
/* ---------- skaner w aplikacji (app.js „skaner”): formularz zdjęć i okno rogów na cały ekran ---------- */
.skan-wybor { display: flex; }
.skan-wybor button { display: inline-flex; align-items: center; gap: .45rem; }
.skan-strony { display: grid; gap: .35rem; }
.skan-strony > .meta { margin: 0; }
.skan-miniatury { display: flex; gap: .5rem; overflow-x: auto; padding: 2px 2px 6px; }
.skan-miniatura { position: relative; flex: none; }
.skan-miniatura.nowy { animation: wchodzi .22s var(--plynnie) both; }
.skan-miniatura > button[data-skan-strona] { position: relative; display: block; width: 76px; height: 96px; box-sizing: content-box; min-height: 0; padding: 0; overflow: hidden; border: 1px solid var(--line2); border-radius: 10px; background: #000; }
.skan-miniatura img { display: block; width: 100%; height: 100%; object-fit: fill; }
/* zdjęcie, którego przeglądarka nie czyta (HEIC poza Safari): nazwa pliku zamiast podglądu — kartkę znajdzie serwer */
.skan-miniatura .skan-bez-podgladu { display: grid; place-items: center; width: 100%; height: 100%; padding: .35rem .3rem 1.4rem; box-sizing: border-box;
  color: var(--dim); font-size: 10.5px; line-height: 1.25; text-align: center; overflow-wrap: anywhere; overflow: hidden; }
.skan-miniatura svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.skan-miniatura polygon { fill: color-mix(in srgb, var(--accent) 14%, transparent); stroke: var(--accent); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.skan-miniatura b { position: absolute; left: 4px; bottom: 4px; min-width: 18px; padding: 0 4px; border-radius: 6px; background: #000b; color: #fff; font-size: 11px; line-height: 18px; text-align: center; }
.skan-miniatura [data-skan-usun] { position: absolute; top: -6px; right: -6px; width: 26px; min-width: 0; height: 26px; min-height: 0; padding: 0; border-radius: 50%; font-size: 12px; }
/* okno rogów: zdjęcie na ciemnym tle (jak edytor zdjęć), rogi do przeciągania z lupą; poza ramką przyciemnione */
:root dialog#skanOkno { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; border-radius: 0;
  background: #05080c; color: #f1f5f9; grid-template-rows: auto minmax(0, 1fr) auto; overflow: hidden; }
:root dialog#skanOkno[open] { display: grid; animation: skanWchodzi .26s var(--plynnie) both; }
:root dialog#skanOkno::before { content: none; }
:root dialog#skanOkno::backdrop { background: #05080c; animation: none; }
@keyframes skanWchodzi { from { opacity: 0; transform: scale(.98); } }
.skan-gora { display: flex; align-items: center; gap: .6rem; padding: calc(.45rem + env(safe-area-inset-top)) calc(.6rem + env(safe-area-inset-right)) .45rem calc(.9rem + env(safe-area-inset-left)); }
.skan-gora b { flex: none; font-size: 15px; }
.skan-gora #skanStan { flex: 1; min-width: 0; font-size: 13px; color: #b8c2cf; }
.skan-gora button { background: #ffffff14; border-color: #ffffff24; color: inherit; }
.skan-scena { position: relative; overflow: hidden; touch-action: none; }
.skan-obraz { position: absolute; }
.skan-obraz img { display: block; width: 100%; height: 100%; pointer-events: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.skan-obraz svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.skan-cien { fill: #000000a0; }
.skan-ramka { fill: none; stroke: var(--accent); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.skan-rog { position: absolute; width: 48px; height: 48px; min-width: 0; min-height: 0; margin: -24px 0 0 -24px; padding: 0; border: 0; border-radius: 50%; background: none; box-shadow: none;
  touch-action: none; cursor: grab; -webkit-tap-highlight-color: transparent; }
.skan-rog::after { content: ""; position: absolute; inset: 13px; border-radius: 50%; border: 3px solid #fff; background: color-mix(in srgb, var(--accent) 75%, transparent);
  box-shadow: 0 1px 6px #000c; transition: transform .16s var(--sprez); }
.skan-rog.ciagniety { cursor: grabbing; }
.skan-rog.ciagniety::after { transform: scale(1.3); }
/* lupa nad palcem: powiększony fragment pod rogiem, krzyżyk w środku */
.skan-lupa { position: absolute; z-index: 3; width: 120px; height: 120px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 6px 20px #000c; background-color: #000;
  background-repeat: no-repeat; pointer-events: none; animation: skanLupa .14s var(--plynnie) both; }
.skan-lupa::after { content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: linear-gradient(var(--accent), var(--accent)) center / 2px 26px no-repeat, linear-gradient(var(--accent), var(--accent)) center / 26px 2px no-repeat; }
@keyframes skanLupa { from { opacity: 0; transform: scale(.85); } }
.skan-dol { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .45rem .6rem;
  padding: .5rem calc(.6rem + env(safe-area-inset-right)) calc(.55rem + env(safe-area-inset-bottom)) calc(.6rem + env(safe-area-inset-left)); }
.skan-narzedzia, .skan-nawig { display: flex; flex-wrap: wrap; gap: .4rem; }
.skan-nawig { margin-left: auto; }
.skan-dol button:not(.glowny) { background: #ffffff14; border-color: #ffffff24; color: inherit; }
.skan-dol button.niebezpieczne { color: #fca5a5; }
.skan-dol button:disabled { opacity: .4; }
/* karta elementu: nazwa z danymi | przyciski | ✕. W wąskiej karcie (panel zwężony do granicy, telefon) przyciski schodzą pod nazwę, ✕ zostaje w rogu —
   wcześniej nazwa ściskała się w kolumnę, a ✕ spadał do drugiego rzędu (zrzut z iPhone'a w poziomie, 21.10.2026). Rozmiar z kontenera, nie z ekranu */
.naglowek-elementu { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: start; gap: 8px; container: naglowek / inline-size; }
.naglowek-elementu .naglowek-tytul { min-width: 0; }
.naglowek-elementu .naglowek-tytul h2 { overflow-wrap: anywhere; }
.naglowek-akcje { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
@container naglowek (max-width: 440px) {
  .naglowek-elementu > .naglowek-tytul { grid-column: 1 / 3; grid-row: 1; }
  .naglowek-elementu > [data-akcja="zamknij"] { grid-column: 3; grid-row: 1; }
  .naglowek-elementu > .naglowek-akcje { grid-column: 1 / -1; grid-row: 2; justify-content: flex-start; }
}
.krok {
  position: relative; border: 1px solid var(--line); border-radius: .6rem; padding: .6rem .75rem .6rem 1rem; margin: .65rem 0; background: var(--panel2); overflow: hidden;
  animation: wchodzi .3s var(--plynnie) both; transition: border-color .2s ease, box-shadow .3s ease;
}
.krok::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--line2); transition: background .25s ease, box-shadow .25s ease; }
.krok.w_toku::before { background: var(--amber); box-shadow: 0 0 12px var(--amber); }
.krok.zrobione::before { background: var(--green); box-shadow: 0 0 14px var(--green); }
.krok.zrobione { border-color: color-mix(in srgb, var(--green) 45%, var(--line)); animation: wchodzi .3s var(--plynnie) both, blysk .9s ease-out; }
@keyframes blysk { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 60%, transparent); } 100% { box-shadow: 0 0 0 14px transparent; } }
.krok-gora { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.krok-gora strong { flex: 1; min-width: 6em; }
.znaczek { font-size: 11px; color: var(--dim); border: 1px solid var(--line2); border-radius: 999px; padding: 0 .5rem; line-height: 1.6; white-space: nowrap; }
.znaczek.plan { color: var(--amber); border-color: var(--amber); }
/* statusy jak sygnały: kropka-lampa przy każdym stanie */
.statusy { display: inline-flex; background: var(--bg); border: 1px solid var(--line); border-radius: .55rem; padding: 2px; gap: 2px; }
.statusy button { border: none; background: transparent; min-height: 30px; padding: 0 .6rem; border-radius: .4rem; font-size: 13px; color: var(--dim); box-shadow: none; }
.statusy button::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--faint); transition: background .2s, box-shadow .2s; }
.statusy button:hover { transform: none; box-shadow: none; color: var(--txt); background: var(--panel2); }
.statusy button.on { color: #fff; }
.statusy button.on[data-s="otwarte"] { background: color-mix(in srgb, var(--faint) 70%, #000); }
.statusy button.on[data-s="w_toku"] { background: color-mix(in srgb, var(--amber) 80%, #000); color: var(--na-kolorze); }
.statusy button.on[data-s="w_toku"]::before { background: #fff; box-shadow: 0 0 8px var(--amber); animation: pulsLampy 1.4s ease-in-out infinite; }
.statusy button.on[data-s="zrobione"] { background: color-mix(in srgb, var(--green) 80%, #000); color: var(--na-kolorze); }
.statusy button.on[data-s="zrobione"]::before { background: #fff; box-shadow: 0 0 8px var(--green); }
.pola { display: grid; gap: 6px; margin-top: 8px; }
.pola label { display: grid; grid-template-columns: 40% 1fr; align-items: center; gap: 8px; font-size: 14px; }

/* przełączniki jak w iOS, w kolorystyce aplikacji (turkus = włączony) */
.przel, .pola label.przel { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 44px; padding: .15rem 0; cursor: pointer; font-size: 14px; }
.przel-nazwa { flex: 1; min-width: 0; }
.przel input[type="checkbox"] {
  -webkit-appearance: none; appearance: none; position: relative; flex: none; width: 52px; height: 32px; min-height: 0; margin: 0; padding: 0; border: none; border-radius: 999px;
  background: var(--line2); cursor: pointer; transition: background .22s ease, box-shadow .22s ease;
}
.przel input[type="checkbox"]::before {
  content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 999px; background: #fff; box-shadow: 0 2px 6px #0007;
  transition: transform .26s var(--sprez), width .18s ease;
}
.przel input[type="checkbox"]:checked { background: var(--accent); box-shadow: 0 0 16px -4px var(--accent); }
.przel input[type="checkbox"]:checked::before { transform: translateX(20px); }
.przel input[type="checkbox"]:active::before { width: 31px; }
.przel input[type="checkbox"]:checked:active::before { transform: translateX(15px); }
.przel input[type="checkbox"].zwarcie:not(:checked) { background: color-mix(in srgb, var(--red) 62%, var(--line2)); }
.przel input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* karta „Problem / Note”: stoi pod sekcjami etapów, zawsze rozwinięta; kapsuła jak przełącznik etapów (.tryby), a dwa widoki pod nią zamieniają się płynnie
   (wysokość, przezroczystość i lekki ruch w bok) */
.wpisy-karta { margin: .55rem 0 .6rem; padding: .6rem .65rem .35rem; border: 1px solid var(--line); border-radius: var(--r); background: color-mix(in srgb, var(--panel2) 55%, transparent); }
.tryby.wpisy-przel { display: flex; width: 100%; margin: 0 0 .5rem; }
.wpisy-przel button { flex: 1 1 0; }
.wpisy-przel .licznik { display: inline-block; min-width: 1.35em; padding: 0 .35em; margin-left: .2rem; border-radius: 999px; font-size: 12px; line-height: 1.5; background: color-mix(in srgb, currentColor 16%, transparent); }
.podwidoki { display: grid; }
.podwidok { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .42s var(--plynnie), opacity .32s ease .06s, transform .42s var(--plynnie), visibility 0s; }
.podwidok-wnetrze { min-height: 0; overflow: hidden; padding: 4px 6px 8px; margin: -4px -6px -8px; }
.podwidoki[data-podwidok="problem"] > .podwidok-notatka, .podwidoki[data-podwidok="notatka"] > .podwidok-problem {
  grid-template-rows: 0fr; opacity: 0; visibility: hidden; pointer-events: none;
  transition: grid-template-rows .42s var(--plynnie), opacity .22s ease, transform .42s var(--plynnie), visibility 0s linear .42s;
}
.podwidoki[data-podwidok="problem"] > .podwidok-notatka { transform: translateX(32px); }
.podwidoki[data-podwidok="notatka"] > .podwidok-problem { transform: translateX(-32px); }
.notatka.problem { border-left-color: var(--red); }
.notatka-pisz { flex-wrap: nowrap; align-items: stretch; }
.notatka-pisz textarea { flex: 1; min-width: 0; resize: none; }
.notatka-pisz button { flex: none; align-self: stretch; }
@media (prefers-reduced-motion: reduce) { .podwidok { transition: none !important; } }
.pola .wym::after { content: " *"; color: var(--red); }
.pola img { max-width: 120px; border-radius: 6px; display: block; }
.krok-stopka { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; align-items: center; }
.krok-stopka .kiedy { color: var(--faint); font-size: 12px; margin-left: auto; }
form.inline { display: grid; gap: 6px; margin-top: 8px; padding: .55rem; background: var(--bg); border: 1px solid var(--line); border-radius: .6rem; }
form.inline .rzad, .rzad { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.rzad-przyciski { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.notatka { border-left: 3px solid var(--blue); background: var(--panel2); border-radius: 0 .5rem .5rem 0; padding: .35rem .6rem; margin: 6px 0; animation: wchodzi .3s var(--plynnie) both; }
.notatka small { color: var(--dim); }
.notatka img { max-width: 100%; border-radius: 6px; margin-top: 4px; }
.uwaga { color: var(--amber); font-size: 13px; }

/* ---------- karty (szablony, wiedza, import, legenda) ---------- */
.typ, .karta, .wiedza-wpis {
  background: var(--panel2); border: 1px solid var(--line); border-radius: .65rem; padding: .7rem .85rem; margin-bottom: .6rem; animation: wchodzi .35s var(--plynnie) both;
  transition: border-color .18s ease;
}
.typ:hover, .karta:hover, .wiedza-wpis:hover { border-color: var(--line2); }
.typ h3, .karta h3, .wiedza-wpis h3 { margin: 0 0 .3rem; font-size: 1rem; }
.typ ul { margin: 4px 0; padding-left: 18px; } .typ li { margin: 4px 0; }
.import-kolumny { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--gap); }
#importForm, #zdjeciaForm { display: grid; gap: 8px; align-content: start; }
#importForm label, #zdjeciaForm label { display: grid; gap: 4px; }
.plan-wiersz { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; padding: .55rem .2rem; border-bottom: 1px solid var(--line); animation: wchodzi .3s var(--plynnie) both; }
.plan-wiersz .status { font-size: 11px; border-radius: 999px; padding: 0 .55rem; line-height: 1.6; color: #fff; background: var(--otw); }
.plan-wiersz .status.oczekuje_ai { background: color-mix(in srgb, var(--amber) 85%, #000); color: var(--na-kolorze); } .plan-wiersz .status.do_sprawdzenia { background: var(--blue); color: var(--accent-ink); }
.plan-wiersz .status.gotowy { background: color-mix(in srgb, var(--green) 85%, #000); color: var(--na-kolorze); }
.kropka { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--faint); margin-right: 6px; }
.kropka.on { background: var(--green); box-shadow: 0 0 8px var(--green); animation: pulsLampy 2s ease-in-out infinite; }
.roznice li.nowe { color: var(--green); } .roznice li.usuniete { color: var(--red); } .roznice li.zmienione { color: var(--amber); }

.wiedza-wpis.wylaczony { opacity: .5; }
.wiedza-wpis dl { display: grid; grid-template-columns: 8em minmax(0, 1fr); gap: 4px 10px; margin: 8px 0 0; font-size: 14px; }
/* kolumna opisu nie rośnie do najdłuższego słowa (1fr = minmax(auto, 1fr)): na telefonie tekst Wiedzy → Technika sięgał 517 px przy ekranie 393 px
   i był ucinany przez overflow wpisu; długie skróty i adresy łamią się w dowolnym miejscu */
.wiedza-wpis dd, .wiedza-wpis dt { min-width: 0; overflow-wrap: anywhere; }
.wiedza-wpis dt { color: var(--dim); } .wiedza-wpis dd { margin: 0; white-space: pre-wrap; }
.wiedza-wpis textarea, .wiedza-wpis input[type=text] { width: 100%; }
.wiedza-grupa { margin: 1rem 0 .4rem; font-size: .68rem; letter-spacing: .09em; text-transform: uppercase; color: var(--faint); }
.wiedza-tekst { background: var(--bg); border: 1px solid var(--line); border-radius: .6rem; padding: .6rem .8rem; white-space: pre-wrap; font: 12px/1.45 "JetBrains Mono", ui-monospace, monospace; max-height: 50vh; max-height: 50dvh; overflow: auto; }
.kandydaci { display: grid; gap: 6px; margin: 8px 0; }
.kandydat { border: 1px solid var(--line); border-radius: .5rem; padding: .4rem .7rem; display: grid; gap: 2px; background: var(--bg); }
.kandydat.wylaczony { opacity: .5; } .kandydat button { justify-self: start; }
.lista-prop td { cursor: pointer; } .lista-prop tr.nie td { color: var(--faint); text-decoration: line-through; }

/* ---------- asystent ---------- */
#widok-asystent { padding: 0; }
/* ---------- historia rozmów z asystentem (19.10.2026, widok jak Open WebUI) ----------
   wąski panel (telefon, połowa Duo): lista to szuflada z lewej nad rozmową (przesunięcie i przyciemnienie tła, bez blednięcia samej listy);
   szeroki (od 760 px panelu): kolumna obok rozmowy. Lista ma pełne tło — leży nad tekstem rozmowy, szkło byłoby nieczytelne */
#widok-asystent { position: relative; flex-direction: row; container: asystent / inline-size; }
.asystent-glowna { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.asystent-naglowek { flex: none; display: flex; align-items: center; gap: .25rem; padding: .25rem .4rem; border-bottom: 1px solid var(--line); }
.asystent-naglowek .ikona { flex: none; }
.asystent-tytul { flex: 1; min-width: 0; padding: 0 .25rem; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* wysiłek rozumowania w pasku (jak wybór modelu w Open WebUI): ikona AI i zwarta lista; na telefonie 16 px (bez powiększania strony w iOS) */
.asystent-wysilek { flex: none; display: inline-flex; align-items: center; gap: .3rem; color: var(--dim); }
.asystent-wysilek .ik { width: 17px; height: 17px; color: var(--accent); }
.asystent-wysilek select { min-height: 36px; padding: 0 1.4rem 0 .5rem; font-size: 13px; width: auto; max-width: 7rem; }
@container asystent (max-width: 480px) { .asystent-wysilek .ik { display: none; } }  /* wąski panel (telefon, połowa Duo): miejsce dla tytułu rozmowy */
.rozmowy { position: absolute; z-index: 30; top: 0; bottom: 0; left: 0; width: min(310px, 86%); display: flex; flex-direction: column; min-height: 0;
  background: var(--panel2); border-right: 1px solid var(--line); box-shadow: 10px 0 30px #0007; border-radius: 16px 0 0 16px;
  transform: translateX(-104%); visibility: hidden; transition: transform .3s var(--plynnie), visibility 0s .3s; }
#widok-asystent.rozmowy-otwarte .rozmowy { transform: none; visibility: visible; transition: transform .3s var(--plynnie), visibility 0s; }
.rozmowy-tlo { position: absolute; inset: 0; z-index: 29; background: color-mix(in srgb, #000 42%, transparent); opacity: 0; pointer-events: none;
  transition: opacity .3s var(--plynnie); }
#widok-asystent.rozmowy-otwarte .rozmowy-tlo { opacity: 1; pointer-events: auto; }
@container asystent (min-width: 760px) {
  .rozmowy { position: static; flex: none; width: 260px; transform: none; visibility: visible; box-shadow: none; border-radius: 0; transition: none; }
  #widok-asystent.rozmowy-ukryte .rozmowy { display: none; }
  .rozmowy-tlo { display: none; }
}
.rozmowy-gora { flex: none; display: grid; gap: .45rem; padding: .6rem; border-bottom: 1px solid var(--line); }
.rozmowy-nowa { justify-content: center; gap: .4rem; }
.rozmowy-lista { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: .2rem .4rem .6rem; }
.rozmowy-grupa { margin: .75rem .5rem .25rem; font-size: 11px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }
.rozmowy-pusto { padding: .8rem .5rem; }
.rozmowa-poz { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; border-radius: 10px; transition: background-color .15s ease; }
.rozmowa-poz.nowy { animation: wchodzi .26s var(--plynnie) both; }
.rozmowa-poz.aktywna { background: color-mix(in srgb, var(--accent) 17%, transparent); }
@media (hover: hover) { .rozmowa-poz:not(.aktywna):hover { background: color-mix(in srgb, var(--txt) 6%, transparent); } }
.rozmowa-otworz { min-width: 0; display: block; text-align: left; background: none; border: 0; box-shadow: none; padding: .55rem .6rem; color: var(--txt); font-weight: 500; }
.rozmowa-tytul { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rozmowa-poz.aktywna .rozmowa-tytul { font-weight: 650; }
.rozmowa-wiecej { background: none; border: 0; box-shadow: none; color: var(--dim); font-size: 18px; line-height: 1; }
.rozmowa-akcje { grid-column: 1 / -1; display: none; flex-wrap: wrap; gap: .35rem; padding: 0 .5rem .55rem; }
.rozmowa-poz.rozwinieta .rozmowa-akcje { display: flex; }
.rozmowa-usun { color: var(--red); gap: .3rem; }
.rozmowa-usun .ik { width: 15px; height: 15px; }
.rozmowy .asystent-przel { border-top: 1px solid var(--line); border-bottom: 0; padding-bottom: calc(.35rem + env(safe-area-inset-bottom)); }
.asystent-przel { flex: none; padding: .35rem .9rem; border-bottom: 1px solid var(--line); }
.asystent-przel small { display: block; font-weight: 400; }
.asystent-okno { flex: 1; overflow: auto; padding: var(--gap); display: flex; flex-direction: column; gap: .55rem; }
/* elementy rozmowy nie mogą się kurczyć: rysunek (overflow: hidden) i rozumowanie (overflow: auto) mają minimalną wysokość 0,
   więc w pełnym oknie flex ściskał je do zera i rysunku nie było widać */
.asystent-okno > *, .asystent-czesc > * { flex-shrink: 0; }
.asystent-pasek { border-top: 1px solid var(--line); background: var(--panel); padding: .55rem var(--gap); display: grid; gap: 6px; }
.asystent-pasek textarea { width: 100%; resize: vertical; }
.asystent-przyciski { display: flex; gap: 8px; }
.wiad { max-width: 92%; padding: .5rem .8rem; border-radius: .9rem; white-space: pre-wrap; word-break: break-word; animation: wchodzi .3s var(--sprez) both; }
.wiad.user { align-self: flex-end; background: linear-gradient(180deg, color-mix(in srgb, var(--blue) 90%, #fff), var(--blue)); color: var(--accent-ink); border-bottom-right-radius: .25rem; }
.wiad.assistant { align-self: flex-start; background: var(--panel2); border: 1px solid var(--line); border-bottom-left-radius: .25rem; }
.wiad.system { align-self: center; color: var(--dim); font-size: 13px; background: transparent; }
.wiad.system.praca::after { content: ""; display: block; height: 8px; margin: 6px auto 0; border-radius: 4px; width: 140px; background: repeating-linear-gradient(90deg, var(--podklad) 0 2px, transparent 2px 8px), var(--line); animation: pociag 1s linear infinite; }
@keyframes pociag { from { background-position: 0 0, 0 0; } to { background-position: 8px 0, 0 0; } }
.rysunek { align-self: flex-start; width: min(100%, 900px); margin: 0; border: 1px solid var(--line); border-radius: .65rem; background: #fff; overflow: hidden; animation: wchodzi .3s var(--sprez) both; }
.rysunek img { display: block; width: 100%; height: auto; background: #fff; }
.rysunek figcaption { display: flex; gap: 6px; flex-wrap: wrap; padding: .4rem .5rem; background: var(--panel2); border-top: 1px solid var(--line); }
.rozumowanie { align-self: flex-start; width: min(100%, 900px); font-size: 13px; color: var(--dim); }
.rozumowanie.nowy { animation: wchodzi .3s var(--plynnie) both; }
.pusto.nowy { animation: wchodzi .25s var(--plynnie) both; }  /* „pusto” (Wiedza, plan pracy, analizy) wchodzi, gdy lista się opróżni — odswiezHTML nie powtarza go przy tym samym HTML */  /* początek odpowiedzi (app.js htmlRozumowania) */
#asystentPrzerwij:not([hidden]) { animation: wchodzi .22s var(--plynnie) both; }  /* „Przerwij” pojawia się razem z odpowiedzią, nie wskakuje */
.rozumowanie summary { cursor: pointer; user-select: none; padding: 2px 0; list-style: none; }
.rozumowanie summary::before { content: "▸ "; } .rozumowanie[open] summary::before { content: "▾ "; }
.rozum-tresc { white-space: pre-wrap; word-break: break-word; max-height: 260px; overflow: auto; margin: 4px 0 2px; padding: .45rem .6rem;
  border-left: 2px solid var(--line); background: color-mix(in srgb, var(--panel2) 60%, transparent); border-radius: 0 .4rem .4rem 0; }
.wiad-tokeny { align-self: flex-start; font-size: 11.5px; color: var(--dim); margin-top: -4px; }
/* odświeżane w pętli (odswiezHTML): bez ponownej animacji wejścia — nowe wiadomości (.nowy) dalej wjeżdżają, a ciągłe wskaźniki stanu dalej
   działają: lampki (.kropka), lampka Qwena (.lampa) i kręcąca się kropka etapu analizy (.kropka-etapu) — wcześniej gasły przy pierwszej zmianie stanu */
.bez-wejscia *:not(.nowy):not(.kropka):not(.lampa):not(.kropka-etapu) { animation: none !important; }
.asystent-czesc { display: contents; }
.asystent-podglad { position: relative; align-self: flex-start; }
.asystent-podglad img { display: block; max-height: 110px; max-width: 100%; border-radius: .5rem; border: 1px solid var(--line); }
.asystent-podglad button { position: absolute; top: 3px; right: 3px; min-height: 26px; padding: 0 .45rem; background: color-mix(in srgb, var(--panel) 85%, transparent); }
.przycisk-label { display: inline-flex; align-items: center; gap: .3rem; min-height: 38px; padding: 0 .9rem; border: 1px solid var(--line);
  border-radius: .55rem; background: var(--panel2); cursor: pointer; font-weight: 500; white-space: nowrap; user-select: none; }
.zdjecie-pytania { display: block; margin: -2px -4px 6px; } .zdjecie-pytania img { display: block; max-width: min(100%, 260px); max-height: 200px; border-radius: .6rem; }
/* wysyłanie pytania (19.10.2026): przycisk z kręciołkiem od pierwszej klatki po stuknięciu („Sending…”, potem „Answering…”, dopóki Qwen pracuje)
   i dymek pytania z paskiem wysyłania (zdjęcie: procent); pasek rośnie przekształceniem, nie szerokością */
#asystentWyslij.czeka { display: inline-flex; align-items: center; justify-content: center; gap: .45rem; opacity: .85; cursor: progress; }
#asystentWyslij.czeka::before { content: ""; flex: none; width: 13px; height: 13px; border-radius: 50%; border: 2px solid currentColor; border-top-color: transparent;
  animation: obrot .8s linear infinite; }
.wiad.wysylana { opacity: .92; }
.wysylanie { display: grid; gap: 4px; margin-top: 6px; font-size: 12px; white-space: normal; }
.wysylanie-pasek { display: block; height: 3px; border-radius: 2px; overflow: hidden; background: color-mix(in srgb, currentColor 28%, transparent); }
.wysylanie-pasek i { display: block; height: 100%; background: currentColor; transform: scaleX(.04); transform-origin: left; transition: transform .25s linear; }
.propozycja-wiedzy { align-self: flex-start; width: min(100%, 720px); border: 1px solid var(--blue); border-radius: .65rem; background: var(--panel2); padding: .5rem .7rem; }
.propozycja-wiedzy.dodano { border-color: var(--green); } .propozycja-wiedzy.odrzucono { opacity: .55; border-color: var(--line); }
.propozycja-wiedzy h4 { margin: 0 0 4px; font-size: 14px; } .propozycja-wiedzy dl { margin: 4px 0; font-size: 13px; }
.propozycja-wiedzy dt { color: var(--dim); font-size: 12px; } .propozycja-wiedzy dd { margin: 0 0 4px; white-space: pre-wrap; word-break: break-word; }
/* asystent: elementy z odpowiedzi jako przyciski (otwierają element na planie) i karta zmiany danych elementów (19.10.2026) */
.pokaz-elementy { display: flex; flex-wrap: wrap; gap: 6px; align-self: flex-start; width: min(100%, 720px); flex-shrink: 0; }
.znaczek-elementu { font: 600 12px/1.4 ui-monospace, monospace; color: var(--txt); background: var(--panel2); border: 1px solid var(--line2);
  border-radius: 999px; padding: 3px 10px; cursor: pointer; transition: border-color .15s, background .15s; }
@media (hover: hover) { .znaczek-elementu:hover:not(:disabled) { border-color: var(--blue); } }  /* na telefonie :hover zostawał na stukniętym przycisku */
.znaczek-elementu:disabled { opacity: .45; cursor: default; }
@media (pointer: coarse) { .znaczek-elementu { min-height: 44px; padding: 6px 12px; } }  /* cel dotyku jak reszta przycisków (44 px) */
/* przyciski wchodzą razem z nową odpowiedzią (.nowy, jak dymek wiadomości); przy odświeżeniu rozmowy stoją (.bez-wejscia) */
.pokaz-elementy.nowy { animation: wchodzi .3s var(--plynnie) .08s both; }
/* zdjęcia z bazy wiedzy pod odpowiedzią (pole `zdjecia_wiedzy`, 20.10.2026): miniatury z nazwą wpisu, stuknięcie otwiera oryginał */
.zdjecia-wiedzy { display: flex; flex-wrap: wrap; gap: 8px; align-self: flex-start; width: min(100%, 720px); flex-shrink: 0; }
.zdjecia-wiedzy .link-zdjecia { display: flex; flex-direction: column; width: 132px; border-radius: .6rem; overflow: hidden; background: var(--panel2);
  border: 1px solid var(--line2); color: var(--txt); text-decoration: none; transition: border-color .15s; }
.zdjecia-wiedzy img { display: block; width: 100%; height: 100px; object-fit: cover; background: #fff; }
.zdjecie-wiedzy-podpis { font-size: 11.5px; line-height: 1.25; padding: 4px 7px 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (hover: hover) { .zdjecia-wiedzy .link-zdjecia:hover { border-color: var(--blue); } }
.zdjecia-wiedzy.nowy { animation: wchodzi .3s var(--plynnie) .12s both; }
.obrazy-wpisu .link-zdjecia { display: block; }
.propozycja-zmiany { flex-shrink: 0; }
.zmiany-tabela { width: 100%; border-collapse: collapse; margin: 4px 0 6px; font-size: 13px; }
.zmiany-tabela tbody tr td, .zmiany-tabela tbody tr td:first-child { padding: 5px 8px 5px 0; background: none; border: 0; border-top: 1px solid var(--line);
  border-radius: 0; box-shadow: none; vertical-align: baseline; }
.zmiany-tabela tbody tr:first-child td { border-top: 0; }
.zmiany-tabela td:first-child { white-space: nowrap; }
.zmiany-tabela td:nth-child(2) { color: var(--dim); white-space: nowrap; }
.zmiany-tabela .zm-obiekt { color: var(--dim); font-size: 12px; }
.zmiany-tabela tr.blad td { color: var(--dim); }
.zmiany-tabela tr.bez-zmian td { opacity: .6; }
.zmiany-tabela .uwaga { margin-top: 2px; font-size: 12px; color: var(--red); }
.zmiany-tabela button.link { display: inline-block; min-height: 0; min-width: 0; background: none; border: 0; padding: 8px 0; margin: -8px 0; color: var(--blue);
  font: 600 13px/1.4 ui-monospace, monospace; cursor: pointer; }
.zm-stara { color: var(--dim); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--dim) 60%, transparent); }
.zm-wartosci strong { font-family: ui-monospace, monospace; }
.zm-ok { color: var(--green); margin-right: 4px; } .zm-blad { color: var(--red); margin-right: 4px; }
.wiad code { background: color-mix(in srgb, var(--faint) 25%, transparent); border-radius: 4px; padding: 0 4px; font-size: 13px; }

/* ---------- powiadomienie ---------- */
#toast {
  position: fixed; inset: auto auto calc(1rem + env(safe-area-inset-bottom)) 50%; margin: 0; transform: translate(-50%, 30px) scale(.94); background: var(--panel2); color: var(--txt);
  border: 1px solid var(--line2); border-left: 4px solid var(--green); padding: .6rem 1rem; border-radius: .6rem; opacity: 0; pointer-events: none; max-width: 90vw; z-index: 30;
  box-shadow: var(--cien); transition: opacity .2s ease, transform .4s var(--sprez);
}
#toast.widoczny { opacity: 1; transform: translate(-50%, 0) scale(1); }
#toast.blad { border-left-color: var(--red); }


/* ---------- analiza planu: kroki, pytanie o typy, duplikaty ---------- */
.analiza { border-left: 3px solid var(--blue); }
.typy-pytanie { display: grid; gap: .5rem; margin: .5rem 0; }
.typ-pytanie { display: grid; grid-template-columns: 120px minmax(0, 1fr) auto; gap: .7rem; align-items: center; background: var(--bg); border: 1px solid var(--line); border-radius: .6rem; padding: .5rem .7rem;
  animation: wchodzi .3s var(--plynnie) both; transition: opacity .2s, border-color .2s; }
.typ-pytanie.wylaczony { opacity: .45; }
.typ-pytanie .obrazy { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; justify-content: center; background: #fff; border-radius: .4rem; padding: 4px; min-height: 44px; }
.typ-pytanie .obrazy img { max-width: 110px; max-height: 60px; object-fit: contain; }
.typ-pytanie .brak { color: #888; font-size: 11px; }
.typ-pytanie h4 { margin: 0 0 2px; font-size: .95rem; }
.przelacznik-typu { display: inline-flex; align-items: center; gap: .4rem; cursor: pointer; font-size: 13px; color: var(--dim); }
.przelacznik-typu input { appearance: none; width: 42px; height: 24px; border-radius: 999px; background: var(--line2); position: relative; cursor: pointer; transition: background .2s; min-height: 0; border: none; }
.przelacznik-typu input::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .25s var(--sprez); }
.przelacznik-typu input:checked { background: var(--green); }
.przelacznik-typu input:checked::after { transform: translateX(18px); }
.duplikat { background: var(--bg); border: 1px solid var(--line); border-radius: .5rem; padding: .4rem .7rem; margin: .4rem 0; }
.duplikat .rzad { margin-top: 4px; }
.obrazy-wpisu { display: flex; flex-wrap: wrap; gap: .5rem; margin: .5rem 0; }
.obrazy-wpisu figure { margin: 0; background: #fff; border-radius: .5rem; padding: 4px 6px; position: relative; text-align: center; border: 1px solid var(--line2); }
.obrazy-wpisu img { display: block; max-width: 170px; max-height: 70px; object-fit: contain; margin: 0 auto; }
.obrazy-wpisu figcaption { font-size: 10.5px; color: #444; max-width: 170px; line-height: 1.2; margin-top: 2px; }
.obrazy-wpisu button.ikona { position: absolute; top: -8px; right: -8px; width: 20px; min-height: 20px; height: 20px; padding: 0; border-radius: 50%; font-size: 11px; opacity: 0; }
.obrazy-wpisu figure:hover button, .obrazy-wpisu figure:focus-within button { opacity: 1; }
/* ekran dotykowy nie ma najechania: ✕ widoczny zawsze, trochę większy, a pole stuknięcia sięga poza kółko (usunięcie i tak pyta o potwierdzenie) */
@media (hover: none) {
  .obrazy-wpisu button.ikona { opacity: 1; top: -10px; right: -10px; width: 26px; min-height: 26px; height: 26px; font-size: 12px; }
  .obrazy-wpisu button.ikona::after { content: ""; position: absolute; inset: -8px; }
}
.kandydat .obraz { background: #fff; border-radius: .4rem; padding: 3px 6px; justify-self: start; }
.kandydat .obraz img { max-height: 50px; max-width: 200px; display: block; }
@media (max-width: 760px) { .typ-pytanie { grid-template-columns: 90px minmax(0, 1fr); } .typ-pytanie .przelacznik-typu { grid-column: 1 / 3; } }

/* ramka symbolu zaznaczona dla napisu (czeka na zatwierdzenie) */
#planNakladka .zaznaczenie { stroke: #1f9d4c; stroke-width: 2.4; fill: #1f9d4c33; stroke-dasharray: 3 2; }
.typy-wybor { display: grid; gap: 6px; max-height: 60vh; max-height: 60dvh; overflow: auto; margin-top: .5rem; }
.typ-opcja { display: grid; grid-template-columns: 90px minmax(0, 1fr); gap: 10px; align-items: center; text-align: left; padding: 6px 8px;
  border: 1px solid var(--line); border-radius: .5rem; background: var(--bg); color: inherit; cursor: pointer; }
.typ-opcja:hover, .typ-opcja.polecany { border-color: var(--blue); }
.typ-opcja .obrazki { background: #fff; border-radius: .35rem; min-height: 40px; display: flex; gap: 3px; align-items: center; justify-content: center; padding: 3px; }
.typ-opcja .obrazki img { max-height: 38px; max-width: 40px; }
.typ-opcja .brak { color: #888; font-size: 11px; }
.typ-opcja strong { display: block; } .typ-opcja .meta { font-size: 12px; }

/* ---------- Fortschritt ---------- */
.fs-kafle { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; margin: .6rem 0; }
.fs-kafle div { background: var(--bg); border: 1px solid var(--line); border-radius: .5rem; padding: .4rem .6rem; }
.fs-kafle b { display: block; font-size: 1.1rem; }
.fs-kafle .lbl { font-size: .74rem; color: var(--dim); }
.fs-tab { width: 100%; border-collapse: collapse; font-size: .8rem; }
.fs-tab th, .fs-tab td { padding: .3rem .4rem; border-bottom: 1px solid var(--line); text-align: left; position: static; }
.fs-tab td.num, .fs-tab th.num { text-align: right; white-space: nowrap; }
.fs-bar { display: inline-block; width: 70px; height: 6px; border-radius: 3px; background: var(--line); vertical-align: middle; overflow: hidden; margin-right: 6px; }
.fs-bar i { display: block; height: 100%; background: var(--green); }
.raport { background: var(--bg); border: 1px solid var(--line); border-radius: .5rem; padding: .6rem .8rem; margin-top: .6rem; }
.raport h4 { margin: .6rem 0 .2rem; }
.raport ul, .raport ol { margin: .2rem 0 .2rem 1.1rem; padding: 0; }
.okno-szerokie { width: min(760px, calc(100vw - 56px)); max-width: 100%; }
.fs-tab { table-layout: auto; }
.fs-tab td:first-child { white-space: normal; }  /* długie nazwy kroków zawijają się */
@media (max-width: 760px) {
  .fs-kafle { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .fs-tab th, .fs-tab td { padding: .25rem .2rem; }
  .fs-tab th:nth-child(4), .fs-tab td:nth-child(4) { display: none; }  /* „in Arbeit” — widać w kafelkach */
  .fs-bar { width: 34px; margin-right: 3px; }
}

/* wynik pomiaru izolacji: zwarcie na czerwono */
.krok select option[value="Short circuit"], .krok select.kurzschluss, .krok select:has(option[value="Short circuit"]:checked) { color: var(--red); font-weight: 700; }
.krok select.kurzschluss option:not([value="Short circuit"]), .krok select:has(option[value="Short circuit"]:checked) option:not([value="Short circuit"]) { color: var(--txt); font-weight: 400; }


.podswietl-lista { display: grid; gap: 4px; max-height: 55vh; max-height: 55dvh; overflow: auto; margin: .5rem 0; }
.podswietl-lista label { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: center; padding: 6px 8px; border: 1px solid var(--line); border-radius: .5rem; background: var(--bg); }


.przed-legenda { display: grid; gap: 6px; }
.przed-legenda label { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.przelacznik-skanu { display: flex !important; flex-direction: row !important; align-items: center; gap: 8px; }



/* ================= układ: telefon, rozłożony iPhone Duo / tablet, komputer ================= */
/* wąski ekran (telefon, złożony Duo): wszystko ciaśniej */
@media (max-width: 699px) {
  body { padding-bottom: calc(.5rem + env(safe-area-inset-bottom)); gap: .4rem; }
  #toast { bottom: calc(72px + env(safe-area-inset-bottom)); }
  html.brak-dolu #toast { bottom: calc(72px + env(safe-area-inset-bottom) - var(--brak-fixed, 0px)); }
  html.brak-dolu dialog { margin-bottom: calc(0px - var(--brak-fixed, 0px)); }  /* --brak-fixed: ile elementy fixed kończą się nad dołem ekranu (mierzy sonda w app.js) */
  #oknoTresc { padding-bottom: calc(1rem + env(safe-area-inset-bottom) + var(--klawiatura, 0px)); }  /* dół arkusza nad home indicator i nad klawiaturą ekranową */
  dialog { width: 100vw; max-width: 100vw; max-height: 92vh; max-height: 92dvh; margin: auto 0 0; border-radius: 18px 18px 0 0; }
  .chip-postep small { display: none; }
  .gora { padding: .3rem .45rem .3rem .6rem; }
  .karta, .typ, .wiedza-wpis { padding: .6rem .7rem; }
}
@media (max-width: 380px) { .chip-postep { padding: .1rem .5rem; } .projekt-wybor .logo { display: none; } }

/* ---------- kapsuła „karty + menu” (17.10.2026): na każdym układzie pływa ze szkła w prawym dolnym rogu, nad treścią ----------
   pionowa: od góry projekt, postęp i szukanie (dawny nagłówek), karty Plan, List, AI, Knowledge, na dole menu. Wcześniej: telefon — belka na całą szerokość (ok. 93 px u dołu iPhone'a), szeroki ekran —
   karty i menu w wierszu nagłówka, potem pozioma kapsuła rozwijana w lewo. Przewijanie w dół albo przesuwanie planu zwija ją do bieżącej karty i menu
   (app.js zwinKarty); przewinięcie w górę, początek listy, zmiana karty albo stuknięcie w kartę — rozwija. Dół i prawy brzeg stoją w miejscu, kapsuła rośnie
   w górę, a szerokość jest stała — na lewo od menu zostaje miejsce na miniaturę planu, pasek zaznaczania i pole Asystenta */
:root {
  --kw: 66px; --kh: 52px; --mh: 46px;  /* szerokość karty („Knowledge” 58 px), wysokość karty, wysokość menu */
  --kapsula-w: calc(var(--kw) + 10px);  /* z wnętrzem 2 × 4 px i ramką 2 × 1 px */
  --rezerwa-dol: calc(var(--kh) + var(--mh) + 26px);  /* zapas pod zwiniętą kapsułą w przewijanych widokach (ostatni wiersz wysuwa się ponad nią) */
  /* Liquid Glass — przejrzysty (użytkownik: „bardziej przezroczysty wszędzie”, 17.10.2026): tło za szkłem przyciemnione tylko do 58%, zabarwienie 28%, lekkie
     rozmycie 10 px — plan prześwituje kształtami i kolorami. Czytelność: pełna biel napisów z cieniem (nad białym planem ok. 3,8:1) i jaśniejszy akcent wybranej karty.
     Wcześniej 42% / 48% / 14 px wyglądało jak dymione szkło */
  --szklo-filtr: blur(10px) saturate(200%) brightness(.58);
  /* tło = blask (gradient) + zabarwienie (kolor) — osobno, bo kolor może być tylko w ostatniej warstwie background: tafle z drobnym tekstem (menu warstw,
     wyniki wyszukiwania) biorą gęstsze zabarwienie zamiast doklejać drugi kolor (taka deklaracja była nieważna i tafle nie miały tła) */
  --szklo-blask: linear-gradient(180deg, color-mix(in srgb, #fff 13%, transparent) 0%, color-mix(in srgb, #fff 4%, transparent) 30%, transparent 58%, color-mix(in srgb, #fff 5%, transparent) 100%);
  --szklo-kolor: color-mix(in srgb, var(--panel) 28%, transparent);
  --szklo-kolor-gesty: color-mix(in srgb, var(--panel) 52%, transparent);  /* nad białym planem napisy ok. 7:1 */
  --szklo-tlo: var(--szklo-blask), var(--szklo-kolor);
  --szklo-krawedz: color-mix(in srgb, #fff 24%, transparent);
  --szklo-cien: inset 0 1px 1px color-mix(in srgb, #fff 42%, transparent), inset 0 -1px 1px color-mix(in srgb, #fff 10%, transparent),
    inset 0 0 14px color-mix(in srgb, #fff 5%, transparent), 0 14px 34px #0008, 0 2px 6px #0005;
  --szklo-tekst: var(--txt);
  --szklo-akcent: color-mix(in srgb, var(--accent) 68%, #fff);  /* wybrana karta na przejrzystym szkle: jaśniejszy turkus */
  --szklo-cien-tekstu: 0 1px 3px #000b;
  --szklo-wybor: color-mix(in srgb, var(--accent) 30%, color-mix(in srgb, #fff 10%, transparent));  /* wybrana karta: jaśniejsza soczewka */
  --szklo-wybor-cien: inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--accent) 32%, transparent);
}
:root[data-theme="light"] {
  --szklo-filtr: blur(10px) saturate(190%) brightness(1.08);
  --szklo-blask: linear-gradient(180deg, color-mix(in srgb, #fff 45%, transparent) 0%, color-mix(in srgb, #fff 10%, transparent) 50%, color-mix(in srgb, #fff 22%, transparent) 100%);
  --szklo-kolor: color-mix(in srgb, #fff 22%, transparent);
  --szklo-kolor-gesty: color-mix(in srgb, #fff 58%, transparent);
  --szklo-tlo: var(--szklo-blask), var(--szklo-kolor);
  --szklo-krawedz: color-mix(in srgb, #fff 92%, transparent);
  --szklo-cien: inset 0 1px 1px #fff, inset 0 -1px 1px color-mix(in srgb, #000 6%, transparent), 0 14px 34px #1b1f2430, 0 2px 6px #1b1f241c;
  --szklo-tekst: var(--txt);
  --szklo-akcent: var(--accent);
  --szklo-cien-tekstu: 0 1px 2px #fff9;
  --szklo-wybor: color-mix(in srgb, var(--accent) 16%, color-mix(in srgb, #fff 62%, transparent));
  --szklo-wybor-cien: inset 0 1px 0 #fff, inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
}
@media (max-height: 520px) { :root { --kh: 40px; --mh: 40px; } }  /* niski ekran (iPhone w poziomie, złożony Duo w poziomie): rozwinięta kapsuła 344 zamiast 436 px */
/* bardzo niski (iPhone w poziomie, do 414 px): rozwinięta kapsuła sięga górnego brzegu planu — narzędzia planu (warstwy, zaznaczanie) stoją na lewo od niej */
@media (max-height: 414px) { .plan-narzedzia { right: calc(var(--kapsula-w) + 14px); } }
nav.zakladki {
  position: fixed; right: calc(.55rem + env(safe-area-inset-right)); bottom: calc(.5rem + env(safe-area-inset-bottom)); z-index: 20; flex-direction: column; gap: 2px; padding: 4px; border-radius: 999px;
  /* szkło (zmienne --szklo-*): kapsuła leży zwykle nad białym planem — czytelność daje przyciemnienie tła za szkłem, nie gęste zabarwienie */
  background: var(--szklo-tlo); backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr);
  border: 1px solid var(--szklo-krawedz); box-shadow: var(--szklo-cien); text-shadow: var(--szklo-cien-tekstu);
}
nav.zakladki button.aktywny { color: var(--szklo-akcent); }
/* zaznaczanie (18.10.2026, użytkownik): kapsuła kart i menu zjeżdża w dół poza ekran — stuknięcie przy prawym dolnym rogu nie przełączy karty w trakcie
   zaznaczania; wraca po „Gotowe” (zwinięta). Samo przesunięcie, bez przezroczystości: szkło z backdrop-filter gubi rozmycie, gdy blednie */
nav.zakladki { transition: translate .32s var(--plynnie), visibility 0s; }
body.zaznaczanie nav.zakladki { translate: 0 calc(100% + 1.5rem + env(safe-area-inset-bottom)); visibility: hidden; pointer-events: none;
  transition: translate .28s var(--plynnie), visibility 0s .28s; }
nav.zakladki .ik { filter: drop-shadow(0 1px 1px #0006); }  /* ikony odcinają się od jasnych miejsc pod szkłem */
:root[data-theme="light"] nav.zakladki .ik { filter: none; }
@media (min-width: 700px) { nav.zakladki { right: calc(var(--przerwa) + env(safe-area-inset-right)); } }  /* brzeg jak obszar kart */
nav.zakladki button, nav.zakladki .kapsula-gora { flex: 0 0 auto; width: var(--kw); height: var(--kh); min-height: 0; padding: 0; border-radius: 999px; overflow: hidden; color: var(--szklo-tekst);
  transition: height .32s var(--sprez), margin .32s var(--sprez), opacity .18s ease, color .14s ease, background .14s ease; }
/* dawny nagłówek na górze kapsuły: projekt (folder i skrócona nazwa; wybór to przezroczysta lista na całym przycisku), postęp (sam procent), szukanie */
nav.zakladki .kapsula-gora { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: 11px; font-weight: 600; cursor: pointer; }
nav.zakladki .projekt-wybor .logo { width: 23px; height: 23px; color: var(--szklo-tekst); }
nav.zakladki .projekt-wybor .et { max-width: calc(var(--kw) - 8px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 14px; }  /* jedna linia, skrót z wielokropkiem */
nav.zakladki .projekt-wybor select { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; padding: 0; border: 0; opacity: 0; font-size: 16px; cursor: pointer; }
nav.zakladki .chip-postep { background: none; padding: 0; align-items: center; line-height: 1.1; }
nav.zakladki .chip-postep .duze { font-size: 15px; color: var(--szklo-tekst); }
nav.zakladki .chip-postep small { display: none; }
nav.zakladki #szukajBtn .ik { width: 22px; height: 22px; }
nav.zakladki #szukajBtn::after { content: ""; position: absolute; bottom: 0; left: 16px; right: 16px; height: 1px; background: var(--szklo-krawedz); }  /* kreska: nagłówek | karty */
/* menu na dole kapsuły, pod cienką kreską; po zwinięciu chowa się razem z resztą (18.10.2026, użytkownik: zwinięta kapsuła to jeden przycisk) */
nav.zakladki .kapsula-menu { height: var(--mh); }
nav.zakladki .kapsula-menu .ik { width: 22px; height: 22px; }
nav.zakladki .kapsula-menu::before { content: ""; position: absolute; top: 0; left: 16px; right: 16px; height: 1px; background: var(--szklo-krawedz); }
:root[data-theme="light"] nav.zakladki { background: color-mix(in srgb, #fff 72%, transparent); border-color: color-mix(in srgb, #fff 85%, transparent);
  box-shadow: inset 0 1px 0 #fff, 0 10px 30px #1b1f2433; }
/* zwinięta: jeden przycisk — bieżąca karta (stuknięcie w nią rozwija całą kapsułę z menu); kropka, gdy schowana karta ma odznakę */
html.karty-zwiniete nav.zakladki :is(button[data-widok]:not(.aktywny), .kapsula-gora, .kapsula-menu) { height: 0; margin-bottom: -2px; opacity: 0; pointer-events: none; }  /* -2 px: bez odstępów po schowanych */
/* napis zostaje w układzie (przezroczysty, dalej nazwą przycisku dla czytnika), a ikona zjeżdża na środek transformem — wysokość przycisku się nie zmienia;
   „display: none” przestawiało ikonę o 9 px w jednej klatce (pomiar 17.10.2026). Przy rozwijaniu napis wraca, gdy karty już się rozsunęły */
nav.zakladki button .et { white-space: nowrap; line-height: 14px; transition: opacity .2s ease .1s; }
html.karty-zwiniete nav.zakladki button .et { opacity: 0; transition: opacity .1s ease; }
html.karty-zwiniete nav.zakladki button.aktywny .ik { transform: translateY(7.5px) scale(1.06); }  /* (3 px odstępu + 14 px napisu) / 2 − 1 px uniesienia aktywnej */
/* zwinięta i w trakcie rozwijania (app.js zwinKarty): tło bieżącej karty rysuje sam przycisk — maleje i rośnie razem z nim; wskaźnik schowany bez przejścia.
   Wskaźnik z układu sprzed zmiany gasł/wschodził obok karty, rozjazd do 142 px. Zamiana przycisk ↔ wskaźnik w jednej klatce, w tym samym miejscu (bez-przejscia) */
html:is(.karty-zwiniete, .karty-rozwijane) nav.zakladki::before { opacity: 0; transition: none; }
html:is(.karty-zwiniete, .karty-rozwijane) nav.zakladki button.aktywny { background: var(--szklo-wybor); box-shadow: var(--szklo-wybor-cien); transition: height .32s var(--sprez), opacity .18s ease, color .14s ease; }
nav.zakladki.ze-wskaznikiem.bez-przejscia::before, nav.zakladki.bez-przejscia button { transition: none; }  /* mocniej niż globalna reguła wskaźnika (niżej w pliku) */
html.karty-zwiniete nav.zakladki:has(button:not(.aktywny) .odznaka:not([hidden]))::after { content: ""; position: absolute; top: 9px; right: 13px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--amber); box-shadow: 0 0 0 2px var(--panel); animation: kropkaKarty .26s var(--sprez) .22s both; }  /* gdy kapsuła już prawie zwinięta */
@keyframes kropkaKarty { from { opacity: 0; scale: .3; } }
html.brak-dolu nav.zakladki { position: absolute; }  /* fixed trzymałby się krawędzi niższego okna */

/* szeroki ekran (rozłożony Duo, iPhone w poziomie, komputer): nagłówek nad obszarem kart (karty i menu — w kapsule w prawym dolnym rogu) */
@media (min-width: 700px) {
  body { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "gora" "main"; grid-template-rows: auto minmax(0, 1fr); row-gap: .45rem;
    padding-left: calc(var(--przerwa) + env(safe-area-inset-left)); padding-right: calc(var(--przerwa) + env(safe-area-inset-right)); }  /* brzeg = przerwa między kartami */
  .gora { grid-area: gora; } main { grid-area: main; }
  .chip-postep small { display: inline; }
  .chip-postep { flex-direction: row; align-items: baseline; gap: .5rem; }
}
@media (min-width: 700px) and (max-height: 520px) {  /* telefon / Duo w poziomie: mniej pionu */
  body { row-gap: .3rem; padding-top: calc(.3rem + env(safe-area-inset-top)); padding-bottom: calc(.3rem + env(safe-area-inset-bottom)); }
  .gora { padding: .15rem .4rem .15rem .6rem; }
  .projekt-wybor select { min-height: 30px; } .chip-postep, button.ikona { min-height: 34px; } button.ikona { width: 34px; }
}

/* ---------- narzędzia na planie (17.10.2026): szkło jak kapsuła kart (zmienne --szklo-*) — plakietka stanu etapu w lewym górnym rogu, warstwy i zaznaczanie
   w prawym, strony ◀ n / m ▶ pośrodku (tylko plan wielostronicowy). Pasek nad planem zniknął: wybór planu jest w oknie „Projekt i plan” (kapsuła → projekt),
   plan ma całą wysokość karty ---------- */
#widok-plan { container: plan / inline-size; }
.plan-szklo { position: absolute; z-index: 8; display: flex; align-items: center; gap: 2px; padding: 3px; border-radius: 999px; cursor: default; touch-action: manipulation;
  background: var(--szklo-tlo); backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr); border: 1px solid var(--szklo-krawedz); box-shadow: var(--szklo-cien);
  color: var(--szklo-tekst); text-shadow: var(--szklo-cien-tekstu); }
.plan-narzedzia { top: 10px; right: 10px; transition: right .32s var(--sprez); }
/* szkło grupy na ::before, nie na samej grupie: element z backdrop-filter jest „korzeniem tła” dla potomków — menu warstw (dziecko grupy) rozmywało wtedy
   tylko pustą grupę i plan prześwitywał przez nie ostro, a białe napisy ginęły na białym planie (zrzut z iPhone'a, 17.10.2026) */
.plan-narzedzia { background: none; backdrop-filter: none; -webkit-backdrop-filter: none; border-color: transparent; box-shadow: none; }
.plan-narzedzia::before { content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; pointer-events: none;
  background: var(--szklo-tlo); backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr); border: 1px solid var(--szklo-krawedz); box-shadow: var(--szklo-cien); }
.plan-narzedzia > button, .plan-narzedzia details.warstwy > summary { width: 44px; height: 44px; min-height: 0; min-width: 0; padding: 0; border: 0; border-radius: 999px; background: none;
  color: inherit; display: grid; place-items: center; font-size: 0; }
.plan-narzedzia .ik { width: 22px; height: 22px; filter: drop-shadow(0 1px 1px #0006); }
:root[data-theme="light"] .plan-narzedzia .ik { filter: none; }
.plan-narzedzia details.warstwy > summary span, .plan-narzedzia #zaznaczBtn span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }  /* nazwa dla czytnika */
.plan-narzedzia details.warstwy[open] > summary, .plan-narzedzia #zaznaczBtn[aria-pressed="true"] { background: var(--szklo-wybor); box-shadow: var(--szklo-wybor-cien); color: var(--szklo-akcent); }
.plan-narzedzia > button, .plan-narzedzia details.warstwy > summary { position: relative; transition: transform .14s var(--plynnie), background .16s ease, color .16s ease; }
.plan-narzedzia > button:active, .plan-narzedzia details.warstwy > summary:active { transform: scale(.88); }  /* ugięcie pod palcem */
/* kropka: podświetlanie typów włączone (warstwy), licznik zaznaczonych elementów (zaznaczanie) */
.plan-narzedzia details.warstwy.aktywne > summary::after { content: ""; position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--panel) 80%, transparent); }
.plan-narzedzia #zaznaczBtn[data-licznik]::after { content: attr(data-licznik); position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent); color: var(--accent-ink); font: 700 11px/18px system-ui, sans-serif; text-shadow: none; animation: licznikWchodzi .26s var(--sprez) both; }
@keyframes licznikWchodzi { from { opacity: 0; scale: .4; } }
.plan-narzedzia details.warstwy { position: static; }
/* menu warstw: tafla szkła pod przyciskami, w granicach planu */
.plan-narzedzia .warstwy-lista { top: calc(100% + 8px); right: 0; width: min(320px, calc(100cqw - 20px)); min-width: 0; max-width: none;  /* bazowe max-width 100% liczyło się od grupy przycisków (98 px) */
  max-height: calc(100cqh - 80px); overflow: auto;
  background: var(--szklo-blask), var(--szklo-kolor-gesty); backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr);
  border: 1px solid var(--szklo-krawedz); border-radius: 18px; box-shadow: var(--szklo-cien); color: var(--txt); text-shadow: var(--szklo-cien-tekstu); font-size: 14px; transform-origin: calc(100% - 66px) 0; }
.plan-narzedzia details.warstwy[open] > .warstwy-lista { animation: szkloMenu .3s var(--sprez) both; }
/* otwiera się od przycisku warstw (sprężyście), zamyka szybciej (app.js zamknijWarstwy: klasa zamyka, potem open = false) */
.plan-narzedzia details.warstwy.zamyka[open] > .warstwy-lista { animation: szkloMenuZnika .15s ease-in both; pointer-events: none; }
@keyframes szkloMenu { from { opacity: 0; transform: scale(.86) translateY(-6px); } }
@keyframes szkloMenuZnika { to { opacity: 0; transform: scale(.92) translateY(-4px); } }
/* treść menu: typy do podświetlenia — nagłówek z „Clear”, szklane wiersze (zaznaczony jak soczewka wybranej karty), przewijanie przy wielu typach */
.plan-narzedzia .warstwy-lista { gap: .3rem; padding: .5rem; width: min(380px, calc(100cqw - 20px)); }
.warstwy-naglowek { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .1rem .2rem .15rem .5rem; }
/* ciemny plan: przełącznik na górze menu warstw, oddzielony od listy typów */
.warstwy-ciemny { padding: .2rem .45rem .45rem .5rem; margin-bottom: .2rem; border-bottom: 1px solid var(--szklo-krawedz); border-radius: 0; color: var(--txt); }
.warstwy-ciemny .przel-nazwa { font-weight: 600; }
.warstwy-ciemny .przel-nazwa small { display: block; margin-top: 1px; font-size: 12px; font-weight: 400; line-height: 1.35; color: var(--szklo-tekst); }
.warstwy-opis { margin: 0 .2rem .35rem; font-size: 12px; line-height: 1.35; }
.warstwy-naglowek h2 { margin: 0; font-size: 12px; font-weight: 650; letter-spacing: .05em; text-transform: uppercase; color: var(--szklo-tekst); }
.warstwy-naglowek button { min-height: 32px; padding: 0 .85rem; border-radius: 999px; border: 1px solid var(--szklo-krawedz); background: color-mix(in srgb, var(--txt) 10%, transparent);
  color: var(--txt); font-size: 13px; font-weight: 600; }
.plan-narzedzia .podswietl-lista { gap: 2px; margin: 0; max-height: min(56svh, 440px); overscroll-behavior: contain; }
.plan-narzedzia .podswietl-lista label { min-height: 44px; padding: 6px 10px; border: 0; border-radius: 12px; background: none; color: var(--txt); cursor: pointer;
  transition: background .16s ease, box-shadow .16s ease; }
.plan-narzedzia .podswietl-lista label:has(input:checked) { background: var(--szklo-wybor); box-shadow: var(--szklo-wybor-cien); }
@media (hover: hover) { .plan-narzedzia .podswietl-lista label:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--txt) 8%, transparent); } }
.plan-narzedzia .podswietl-lista input { width: 20px; height: 20px; margin: 0; accent-color: var(--accent); }
.plan-narzedzia .podswietl-lista .meta { color: var(--szklo-tekst); opacity: .8; font-variant-numeric: tabular-nums; }
.plan-narzedzia .podswietl-lista > .meta { margin: .4rem .5rem; }
.plan-strony { top: 10px; left: 50%; translate: -50% 0; }
.strony-nawig { display: flex; align-items: center; }
.plan-strony .ikona.maly { width: 40px; min-height: 38px; border: none; background: transparent; color: inherit; }
.plan-strony #stronaNr { min-width: 2.7em; text-align: center; font-size: 13px; font-weight: 650; }
html.plan-jedna-strona .plan-strony { display: none; }  /* plan jednostronicowy: bez ◀ 1/1 ▶ */

/* lista: szukanie + filtry w jednym rzędzie, wiersz jako zwarta karta */
.pasek-listy { display: grid; grid-template-columns: minmax(0, 1fr); gap: .25rem; padding: .45rem .5rem; }
.szukaj-rzad { display: flex; gap: .35rem; align-items: center; }
.szukaj-rzad #filtr { flex: 1; min-width: 0; min-height: 38px; }
#widok-lista #licznik { padding-left: .15rem; font-size: 12.5px; }
#tabela thead { display: none; }
#tabela, #tabela tbody { display: block; }
#tabela tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 10px; padding: .4rem .65rem; margin-bottom: 4px; background: var(--panel2);
  border: 1px solid var(--line); border-left: 3px solid var(--line2); border-radius: var(--r-maly); cursor: pointer; transition: border-color .14s, transform .2s var(--sprez); }
@media (hover: hover) { #tabela tbody tr:hover { border-color: var(--line2); border-left-color: var(--accent); } }
#tabela tbody tr td, #tabela tbody tr td:first-child, #tabela tbody tr td:last-child { background: none; border: none; border-radius: 0; padding: 0; white-space: normal; box-shadow: none; }
#tabela tbody tr td:nth-child(1) { grid-column: 1 / -1; }
#tabela tbody tr td:nth-child(2) { grid-column: 1; color: var(--dim); font-size: 12.5px; }
#tabela tbody tr td:nth-child(3) { grid-column: 2; grid-row: 2; color: var(--dim); font-size: 12.5px; text-align: right; }
#tabela tbody tr td:nth-child(4) { display: none; }
#tabela tbody tr td:nth-child(5) { grid-column: 1 / -1; font-size: 12.5px; color: var(--dim); }
#tabela tbody tr.zrobione { border-left-color: var(--green); } #tabela tbody tr.w_toku { border-left-color: var(--amber); }
/* szeroka lista: postęp wszystkich etapów i liczby notatek / problemów (na wąskiej — bieżący etap i same ikony, jak dotąd) */
.etapy-mini, .licz-wpisy small { display: none; }
@container panel (min-width: 520px) {
  #tabela tbody tr .postep-biezacy { display: none; }
  .etapy-mini { display: inline-flex; gap: .6rem; align-items: center; vertical-align: middle; }
  .licz-wpisy small { display: inline; margin-left: 1px; font-size: 11px; color: var(--dim); }
}
.etap-mini { display: inline-flex; align-items: center; gap: 3px; }
.etap-mini i { font-style: normal; font-size: 11px; font-weight: 700; color: var(--dim); }
.etap-mini.biezacy i { color: var(--txt); }
.etap-mini b { position: relative; width: 38px; height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.etap-mini b::before { content: ""; position: absolute; inset: 0 auto 0 0; width: var(--p, 0%); border-radius: inherit; background: var(--st-tok); }
.etap-mini.zrobione b::before { background: var(--st-zr); }
@container panel (min-width: 600px) { #tabela tbody { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 5px; } #tabela tbody tr { margin-bottom: 0; } }
.tabela-wrap { padding: .45rem .5rem .6rem; }
/* start aplikacji: zanim przyjdą dane, lista pokazuje migoczące szkielety wierszy, a plan cienki pasek ładowania */
@keyframes szkielet { from { background-position: 150% 0; } to { background-position: -50% 0; } }
#tabela tbody tr.szkielet { height: 62px; padding: 0; pointer-events: none; border-left-color: var(--line); animation: szkielet 1.3s linear infinite;
  background: linear-gradient(100deg, var(--panel2) 30%, color-mix(in srgb, var(--panel2) 82%, var(--txt)) 50%, var(--panel2) 70%) 150% 0 / 220% 100% no-repeat, var(--panel2); }
#planOkno.laduje::after { content: ""; position: absolute; left: 0; top: 0; height: 3px; width: 40%; background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: pasekLadowania 1.1s ease-in-out infinite; z-index: 5; pointer-events: none; }
@keyframes pasekLadowania { from { transform: translateX(-100%); } to { transform: translateX(260%); } }

/* wspólne klocki: sekcje, karty, odznaki */
.sekcja { display: flex; align-items: center; gap: .5rem; margin: 1rem 0 .4rem; font-size: .74rem; letter-spacing: .09em; text-transform: uppercase; color: var(--faint); font-weight: 650; }
.sekcja:first-child { margin-top: .2rem; }
.sekcja .chip { letter-spacing: 0; text-transform: none; }
.chip { display: inline-flex; align-items: center; gap: .25rem; padding: 0 .55rem; line-height: 1.75; border-radius: 999px; font-size: 11.5px; border: 1px solid var(--line2); color: var(--dim); white-space: nowrap; }
.chip.ok { color: var(--green); border-color: color-mix(in srgb, var(--green) 45%, var(--line)); }
.chip.uwaga { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 50%, var(--line)); }
.chip.akcent { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 50%, var(--line)); }
.chip.zle { color: var(--red); border-color: color-mix(in srgb, var(--red) 50%, var(--line)); }
.pusto { text-align: center; color: var(--dim); padding: 1.1rem .5rem; border: 1px dashed var(--line2); border-radius: var(--r); font-size: 13.5px; }
.karta-ai { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r); padding: .7rem .8rem; margin-bottom: .55rem; animation: wchodzi .3s var(--plynnie) both; }
.karta-ai h3 { margin: 0 0 .2rem; display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.menu-tresc { padding: .8rem .9rem 1rem; display: grid; gap: .45rem; }
.menu-pozycja { justify-content: flex-start; width: 100%; min-height: 46px; padding: 0 .9rem; background: var(--panel2); border-radius: 12px; font-weight: 550; }
.menu-jezyk { display: flex; align-items: center; justify-content: space-between; cursor: default; border: 1px solid var(--line); }
.menu-jezyk select { min-width: 9rem; }
.menu-pozycja.niebezpieczne { margin-top: .4rem; }

/* ---------- ekran AI ---------- */
.ai-stan { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .7rem; padding: .6rem .75rem; background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r); margin-bottom: .6rem; }
.ai-stan .lampa { width: 11px; height: 11px; border-radius: 50%; background: var(--faint); flex: none; }
.ai-stan .lampa.on { background: var(--green); box-shadow: 0 0 9px var(--green); animation: pulsLampy 2.2s ease-in-out infinite; }
.ai-stan .lampa.pauza { background: var(--amber); box-shadow: 0 0 9px var(--amber); }
.ai-stan .tytul { font-weight: 650; flex: 1; min-width: 8rem; }
.ai-stan .teraz { flex: 1 1 100%; color: var(--dim); font-size: 13px; }
.ai-stan .teraz b { color: var(--txt); font-weight: 600; }
/* przyciski stanu AI (Pause, Schedule): na szerokim ekranie obok tytułu, na wąskim jeden równy wiersz pod nim */
.ai-akcje { display: contents; }
@media (max-width: 520px) { .ai-akcje { flex: 1 1 100%; display: flex; gap: .5rem; } .ai-akcje button { flex: 1; justify-content: center; } }
/* okno tygodniowego harmonogramu pracy AI (siatka dzień × godzina) */
.harm-przel small, .off-przel small { display: block; font-weight: 400; }
.harm-siatka { display: grid; grid-template-columns: 2.4rem repeat(7, minmax(0, 1fr)); gap: 3px; margin: .5rem 0; transition: opacity .2s; }
.harm-siatka.wyl { opacity: .45; }
.harm-siatka button { min-height: 26px; padding: 0; border-radius: 6px; font-size: 12px; }
.harm-kom { background: var(--panel2); border: 1px solid var(--line); }
.harm-kom.on { background: var(--accent); border-color: var(--accent); }
.harm-kom.teraz { outline: 2px solid var(--amber); outline-offset: 1px; }
.harm-gl { background: transparent; border-color: transparent; color: var(--dim); }
.harm-przyciski { display: flex; gap: .4rem; flex-wrap: wrap; }
/* stopka (liczba godzin + zapis) zostaje na dole okna przy przewijaniu 24 wierszy; margines ujemny rozciąga ją na całą szerokość okna (#oknoTresc ma padding 1rem) */
.harm-stopka { position: sticky; bottom: -1rem; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin: .7rem -1rem -1rem; padding: .7rem 1rem; background: var(--panel); border-top: 1px solid var(--line); }
.etapy { display: grid; gap: .1rem; margin: .45rem 0 .3rem; }
.etap { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: .12rem .55rem; align-items: center; padding: .28rem .05rem; }
.etap .kropka-etapu { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line2); display: grid; place-items: center; font-size: 11px; font-weight: 800; line-height: 1; }
.etap.gotowy .kropka-etapu { background: var(--green); border-color: var(--green); color: #052e13; }
.etap.w_toku .kropka-etapu { border-color: var(--accent); border-top-color: transparent; animation: obrot 1s linear infinite; }
.etap .nazwa { font-weight: 550; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.etap.oczekuje .nazwa { color: var(--dim); font-weight: 450; }
.etap .liczby { color: var(--dim); font-size: 12.5px; white-space: nowrap; }
.etap .postep-etapu { grid-column: 2 / 4; height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.etap .postep-etapu i { display: block; height: 100%; background: var(--accent); border-radius: 2px; transform: scaleX(var(--p, 0)); transform-origin: left; transition: transform .6s var(--plynnie); }
.etap.gotowy .postep-etapu i { background: var(--green); }
.rzad-akcji { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .55rem; align-items: center; }
.pytania { display: grid; gap: .55rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr)); }
.pytanie { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r); padding: .65rem .75rem; animation: wchodzi .3s var(--plynnie) both; }
.pytanie.wazne { border-color: color-mix(in srgb, var(--amber) 55%, var(--line)); }
.pytanie .wycinki { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; background: #fff; border-radius: 10px; padding: 6px; min-height: 52px; }
.pytanie .wycinki img { max-height: 56px; max-width: 110px; object-fit: contain; }
.pytanie h4 { margin: .5rem 0 .15rem; display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; font-size: .98rem; }
.pytanie .sugestia { color: var(--dim); font-size: 13px; }
.pytanie .sugestia b { color: var(--txt); }
.pytanie form.odpowiedz { display: grid; gap: .4rem; margin-top: .5rem; padding-top: .5rem; border-top: 1px dashed var(--line2); }
.pytanie form.odpowiedz label { display: grid; gap: 2px; font-size: 12.5px; color: var(--dim); }
.pytanie form.odpowiedz label.zwykla { display: flex; align-items: center; gap: .5rem; }
.hist { display: grid; gap: .4rem; }
.hist-wiersz { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .1rem .6rem; padding: .5rem .7rem; background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r-maly); cursor: pointer; transition: border-color .14s; }
.hist-wiersz:hover { border-color: var(--line2); }
.hist-wiersz strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-wiersz .meta { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .1rem .6rem; }
.tryby { display: grid; gap: .45rem; margin: .4rem 0; }
.tryb { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: .1rem .6rem; text-align: left; padding: .55rem .7rem; border-radius: var(--r); background: var(--panel2); border: 1px solid var(--line);
  cursor: pointer; align-items: start; white-space: normal; font-weight: 450; }
.tryb:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.tryb input { margin-top: .2rem; }
.tryb strong { font-weight: 650; } .tryb .meta { grid-column: 2; }
@container panel (min-width: 640px) {
  #widok-ai.aktywny { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); grid-template-areas: "stan stan" "analiza hist" "pyt hist" "nowa hist"; column-gap: 1rem; align-content: start; grid-template-rows: auto auto auto 1fr; }
  #aiStan { grid-area: stan; } #analizaKarta { grid-area: analiza; } #aiPytania { grid-area: pyt; } #aiNowa { grid-area: nowa; } #aiHistoria { grid-area: hist; }
}
.warstwy-lista { min-width: min(320px, calc(100% - 1rem)); }
.plan-etap-chip { left: 10px; top: 10px; display: inline-flex; gap: .45rem; min-height: 38px; padding: 0 .8rem 0 .65rem; font-size: 12.5px; font-weight: 650; cursor: pointer; }  /* szkło: .plan-szklo */
.plan-etap-chip .kropki { display: inline-flex; gap: 3px; }
.plan-etap-chip .kropki b { width: 8px; height: 8px; border-radius: 50%; }
.plan-etap-chip .kropki .o { background: var(--st-otw); } .plan-etap-chip .kropki .t { background: var(--st-tok); } .plan-etap-chip .kropki .z { background: var(--st-zr); }
.plan-etap-chip.wyl { color: var(--szklo-tekst); opacity: .85; } .plan-etap-chip.wyl .kropki b { background: var(--line2); }
/* ---------- więcej funkcji, gdy komponent ma miejsce (18.10.2026): progi według szerokości SAMEGO komponentu — w połowie otwartego Duo i na telefonie
   wszystko wygląda jak dotąd (ten sam rozmiar pisma i ikon), szerszy plan / panel / lista pokazują więcej ---------- */
#planOkno { container: plan / inline-size; }
.plan-etapy { display: none; left: 10px; top: 10px; }  /* szkło: .plan-szklo */
.plan-etapy button { min-height: 32px; padding: 0 .75rem; border: 0; border-radius: 999px; background: transparent; color: var(--szklo-tekst); font-size: 12.5px; font-weight: 650;
  box-shadow: none; transition: background-color .16s ease, color .16s ease; }
.plan-etapy button.on { background: var(--szklo-wybor); box-shadow: var(--szklo-wybor-cien); }
@container plan (min-width: 560px) { #planEtapChip { display: none; } .plan-etapy { display: flex; } }

/* ---------- wyszukiwanie jak Spotlight na iPhonie (app.js otworzSzukanie, 17.10.2026): treść pod spodem się rozmywa i przygasa, u góry pośrodku planu
   (bez planu na ekranie — u góry obszaru kart) wjeżdża szklana pigułka z polem, pod nią tafla wyników. Wyniki zmieniają się przy pisaniu i wjeżdżają po kolei;
   wiersz, który zostaje po kolejnym znaku, nie powtarza wejścia (.bylo). Zamknięcie: pole odpływa w górę, tło się wyostrza ---------- */
#szukajOkno { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; border-radius: 0;
  background: transparent; box-shadow: none; overflow: hidden; animation: none; color: var(--txt); }
#szukajOkno::before { content: none; }  /* bez uchwytu arkusza (telefon) — to nie arkusz */
#szukajOkno::backdrop { background: color-mix(in srgb, var(--bg) 20%, transparent); backdrop-filter: blur(8px) saturate(150%); -webkit-backdrop-filter: blur(8px) saturate(150%);
  animation: spTlo .3s var(--plynnie) both; }
#szukajOkno.zamyka::backdrop { animation: spTloZnika .19s ease-in both; }
@keyframes spTlo { from { background: transparent; backdrop-filter: blur(0px) saturate(100%); -webkit-backdrop-filter: blur(0px) saturate(100%); } }
@keyframes spTloZnika { to { background: transparent; backdrop-filter: blur(0px) saturate(100%); -webkit-backdrop-filter: blur(0px) saturate(100%); } }
.sp-pole, .sp-wyniki { position: fixed; left: var(--sp-x, 50%); width: var(--sp-w, min(560px, calc(100% - 24px))); translate: -50% 0;
  background: var(--szklo-tlo); backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr); border: 1px solid var(--szklo-krawedz); box-shadow: var(--szklo-cien); }
.sp-pole { top: var(--sp-y, 12px); z-index: 1; display: flex; align-items: center; gap: .55rem; height: 52px; padding: 0 .35rem 0 1rem; border-radius: 999px;
  animation: spPole .46s var(--sprez) both; }
.sp-pole .ik { flex: none; width: 21px; height: 21px; color: var(--szklo-tekst); }
.sp-pole input { flex: 1; min-width: 0; height: 100%; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; outline: none; font-size: 17px; color: var(--txt); }
.sp-pole input::placeholder { color: var(--szklo-tekst); opacity: .75; }
.sp-pole input::-webkit-search-cancel-button { display: none; }
.sp-zamknij { flex: none; width: 40px; height: 40px; min-height: 0; padding: 0; border: 0; border-radius: 999px; background: color-mix(in srgb, var(--txt) 12%, transparent); color: var(--txt); }
.sp-wyniki { top: calc(var(--sp-y, 12px) + 62px); max-height: calc(100dvh - var(--sp-y, 12px) - 82px - var(--klawiatura, 0px)); overflow: auto; overscroll-behavior: contain;
  display: grid; gap: 2px; align-content: start; padding: .45rem; border-radius: 24px; background: var(--szklo-blask), var(--szklo-kolor-gesty);
  text-shadow: var(--szklo-cien-tekstu);
  animation: spWyniki .32s var(--plynnie) .04s both; }
.sp-wyniki:empty { display: none; }
.sp-wyniki .szukaj-poz { border: 0; border-radius: 14px; background: none; color: var(--txt); }
.sp-wyniki .szukaj-poz:active { background: color-mix(in srgb, var(--accent) 18%, transparent); }
@media (hover: hover) { .sp-wyniki .szukaj-poz:hover { background: color-mix(in srgb, var(--txt) 8%, transparent); } }
.sp-wyniki .szukaj-grupa { margin: .45rem .7rem .1rem; }
.sp-wyniki > * { animation: spWiersz .3s var(--plynnie) both; animation-delay: calc(var(--i, 0) * 22ms); }
.sp-wyniki > .bylo { animation: none; }
.sp-wyniki > .meta { margin: .45rem .75rem; }
#szukajOkno.zamyka .sp-pole { animation: spPoleZnika .19s ease-in both; }
#szukajOkno.zamyka .sp-wyniki { animation: spWynikiZnika .16s ease-in both; }
@keyframes spPole { from { opacity: 0; transform: translateY(-22px) scale(.92); } }
@keyframes spWyniki { from { opacity: 0; transform: translateY(-10px) scale(.98); } }
@keyframes spWiersz { from { opacity: 0; transform: translateY(8px); } }
@keyframes spPoleZnika { to { opacity: 0; transform: translateY(-14px) scale(.95); } }
@keyframes spWynikiZnika { to { opacity: 0; transform: translateY(-8px) scale(.98); } }

/* ---------- okno „Projekt i plan” (app.js otworzProjektIPlan): projekty jako akordeon — bieżący rozwinięty, pod nim jego plany; inny projekt rozwija się
   stuknięciem (plany z serwera), stuknięcie planu przełącza projekt i plan ---------- */
.pp-tresc { padding: .8rem .9rem 1rem; display: grid; gap: .55rem; }
.pp-lista { display: grid; gap: .45rem; }
.pp-projekt { border-radius: 14px; background: var(--panel2); border: 1px solid var(--line); overflow: hidden; }
.pp-projekt.otwarty { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.pp-naglowek { width: 100%; min-height: 50px; justify-content: flex-start; gap: .65rem; padding: 0 .85rem; border: 0; border-radius: 0; background: none; font-weight: 650; text-align: left; }
.pp-naglowek .ik { color: var(--accent); flex: none; }
.pp-nazwa { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-biezacy { flex: none; padding: .1rem .5rem; border-radius: 999px; background: var(--accent-soft); color: var(--accent); font-size: 11px; font-weight: 650; }
.pp-strzalka { flex: none; width: 8px; height: 8px; border-right: 2px solid var(--dim); border-bottom: 2px solid var(--dim); rotate: -45deg; transition: rotate .22s var(--plynnie); }
.pp-projekt.otwarty .pp-strzalka { rotate: 45deg; }
.pp-plany { display: grid; gap: 2px; padding: 0 .45rem; }
.pp-projekt.otwarty .pp-plany { padding-bottom: .45rem; animation: wchodzi .2s var(--plynnie) both; }
.pp-plan, .pp-dodaj { width: 100%; min-height: 48px; justify-content: flex-start; gap: .65rem; padding: .35rem .6rem; border: 0; border-radius: 10px; background: none; text-align: left; }
.pp-plan .ik, .pp-dodaj .ik { flex: none; color: var(--dim); }
.pp-tekst { flex: 1; min-width: 0; display: grid; }
.pp-tekst b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-tekst small { color: var(--dim); font-size: 12px; }
.pp-plan.biezacy { background: var(--accent-soft); }
.pp-plan.biezacy .ik { color: var(--accent); }
.pp-ok { margin-left: auto; }
.pp-dodaj { color: var(--accent); font-weight: 600; }
.pp-plany .meta { margin: .3rem .6rem .5rem; }
@media (hover: hover) { .pp-plan:hover, .pp-dodaj:hover, .pp-naglowek:hover { background: color-mix(in srgb, var(--txt) 6%, transparent); } }

/* ---------- gesty i przejścia (ruch.js) ---------- */
/* karty wjeżdżają z kierunkiem ruchu: naprzód z prawej, wstecz z lewej */
@keyframes widokZPrawej { from { opacity: 0; transform: translateX(36px); } to { opacity: 1; transform: none; } }
@keyframes widokZLewej { from { opacity: 0; transform: translateX(-36px); } to { opacity: 1; transform: none; } }
/* kierunek ustala app.js przelacz w chwili pokazania karty (klasa) — późniejsza zmiana kierunku nie restartuje animacji widocznej już karty */
.widok.aktywny.wjazd-przod { animation-name: widokZPrawej; }
.widok.aktywny.wjazd-tyl { animation-name: widokZLewej; }
.tabela-wrap.anim-przod { animation: widokZPrawej .3s var(--plynnie) both; }
.tabela-wrap.anim-tyl { animation: widokZLewej .3s var(--plynnie) both; }
/* strzałka „wstecz” przy przeciąganiu od lewej krawędzi */
.gest-wstecz { position: fixed; left: 0; top: 50%; z-index: 1200; width: 42px; height: 42px; margin: -21px 0 0 -46px; border-radius: 50%; display: grid; place-items: center;
  background: var(--panel); color: var(--dim); border: 1px solid var(--line2); box-shadow: var(--cien); opacity: 0; pointer-events: none; will-change: transform, opacity;
  transition: background .15s, color .15s, border-color .15s; }
.gest-wstecz.gotowy { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
/* okno: zamykanie (kopia okna odjeżdża) */
.okno-duch { display: block !important; animation: okienkoWychodzi .2s ease-in both !important; pointer-events: none; }
.okno-duch.do-przycisku { animation: none !important; transform-origin: center; }  /* wraca do przycisku, który otworzył okno (ruch.js, animacja z JS) */
@keyframes okienkoWychodzi { to { opacity: 0; transform: translateY(22px) scale(.96); } }
.okno-tlo-duch { position: fixed; inset: 0; z-index: 999; background: color-mix(in srgb, #000 55%, transparent); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  animation: tloWychodzi .2s ease-in both; pointer-events: none; }
@keyframes tloWychodzi { to { opacity: 0; } }
/* arkusz od dołu (telefon, prawa połowa rozłożonego Duo — reguły w @media niżej) */
@keyframes arkuszWchodzi { from { transform: translateY(100%); } to { transform: none; } }
@keyframes arkuszWychodzi { to { transform: translateY(100%); } }
/* kopie znikających elementów (okno, treść okna przy ▶, pasek, ramka kadru) to sklonowane węzły: każda animacja wejścia w środku startowałaby od zera —
   18.10.2026 treść karty wjeżdżała z prawej w zjeżdżającym w dół arkuszu, gdy zamknięto go w ciągu 0,3 s po ▶. W kopii wszystko stoi w stanie końcowym */
.okno-duch *, .tresc-duch *, .el-duch, .el-duch * { animation: none !important; }
.el-duch { pointer-events: none; }
@media (max-width: 699px) {  /* na telefonie okno to arkusz od dołu z uchwytem: wjeżdża i odjeżdża pionowo, da się go zamknąć przeciągnięciem w dół */
  dialog[open] { animation-name: arkuszWchodzi; animation-duration: .36s; animation-timing-function: cubic-bezier(.2, .9, .25, 1); }
  .okno-duch:not(.do-przycisku) { animation-name: arkuszWychodzi !important; }
  dialog::before { content: ""; position: absolute; top: 6px; left: 50%; width: 40px; height: 4px; margin-left: -20px; border-radius: 2px; background: var(--line2); z-index: 5; pointer-events: none; }
  #oknoTresc { padding-top: 1.35rem; }
}
/* wskaźnik aktywnej zakładki płynie między zakładkami */
nav.zakladki.ze-wskaznikiem::before { content: ""; position: absolute; left: 0; top: 0; width: var(--ind-w, 0); height: var(--ind-h, 0); border-radius: 999px; background: var(--szklo-wybor); box-shadow: var(--szklo-wybor-cien);
  transform: translate(var(--ind-x, 0), var(--ind-y, 0)); transition: transform .38s var(--sprez), width .3s var(--plynnie), height .3s var(--plynnie), opacity .18s ease; pointer-events: none; }
nav.zakladki.ze-wskaznikiem button.aktywny { background: transparent; }
/* naciśnięty wiersz listy zapada się, wybrany etap „wskakuje” */
#tabela tbody tr:not(.szkielet):active { transform: scale(.985); transition: transform .08s; }
/* długie listy: wiersze elementów i wpisy wiedzy poza ekranem nie są układane ani malowane — szybsze pokazanie widoku i przewijanie przy setkach elementów;
   „auto” zapamiętuje ostatni rozmiar (pasek przewijania nie skacze). Na szerokim ekranie (wiersze tabeli) właściwość nie działa i niczego nie zmienia */
#tabela tbody tr:not(.szkielet) { content-visibility: auto; contain-intrinsic-size: auto 88px; }
.wiedza-wpis { content-visibility: auto; contain-intrinsic-size: auto 56px; }
.tryby button.on.nowy { animation: trybWlaczony .3s var(--sprez); }  /* tylko przy zmianie etapu (app.js ustawTryb), nie przy każdym rysowaniu */
@keyframes trybWlaczony { from { transform: scale(.9); } to { transform: none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

/* ---------- Wiedza: uporządkowana lista (wpisy rozwijane, szukanie, grupy) ---------- */
.wiedza-pasek { display: grid; grid-template-columns: minmax(0, 1fr); gap: .45rem; margin-bottom: .6rem; position: sticky; top: -.8rem; z-index: 5; background: var(--panel); padding: .1rem 0 .4rem; }
.wiedza-pasek .szukaj-rzad { display: flex; gap: .35rem; align-items: center; }
.wiedza-pasek #wiedzaSzukaj { flex: 1; min-width: 0; }
.wiedza-pasek #wiedzaBaza { max-width: 42%; text-overflow: ellipsis; }
.wiedza-licz { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.chipy { display: flex; gap: .35rem; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.chipy::-webkit-scrollbar { display: none; }
/* pasek pigułek przewijany w bok: krawędź, za którą jest jeszcze treść, zanika (na telefonie widać 3 z 6 grup i nic nie zdradzało reszty).
   Czysty CSS: oś czasu = przewinięcie samego paska; gdy treść się mieści, oś jest nieaktywna i maski nie ma. Bez wsparcia — bez maski */
@property --krawedz-l { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --krawedz-p { syntax: "<length>"; inherits: false; initial-value: 0px; }
@supports (animation-timeline: scroll()) {
  .chipy { mask-image: linear-gradient(90deg, transparent, #000 var(--krawedz-l), #000 calc(100% - var(--krawedz-p)), transparent);
    animation: chipyKrawedzie linear both; animation-timeline: scroll(self inline); }
}
@keyframes chipyKrawedzie { 0% { --krawedz-l: 0px; --krawedz-p: 26px; } 8% { --krawedz-l: 26px; } 92% { --krawedz-p: 26px; } 100% { --krawedz-l: 26px; --krawedz-p: 0px; } }
.chip-btn { min-height: 30px; padding: 0 .7rem; border-radius: 999px; font-size: 12.5px; background: var(--panel2); color: var(--dim); flex: 0 0 auto; }
.chip-btn b { color: var(--txt); font-weight: 650; margin-left: .15rem; }
.chip-btn.aktywny { background: var(--accent-soft); border-color: var(--accent); color: var(--txt); }
#wiedzaLista { display: grid; gap: .35rem; }
#wiedzaLista .wiedza-grupa { margin: .7rem 0 .15rem; animation: wchodzi .35s var(--plynnie) both; }  /* razem z wpisami pod nim (wcześniej wskakiwał) */
.wiedza-grupa-bazy { letter-spacing: .04em; text-transform: none; color: var(--accent); }  /* ten sam rodzaj w legendach kilku planów */
details.wiedza-wpis { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r); margin: 0; padding: 0; overflow: hidden; transition: border-color .14s; }
details.wiedza-wpis:hover { border-color: var(--line2); }
details.wiedza-wpis[open] { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
details.wiedza-wpis.wylaczony > summary { opacity: .55; }
details.wiedza-wpis > summary { list-style: none; display: grid; grid-template-columns: 46px minmax(0, 1fr) auto; gap: .6rem; align-items: center; padding: .4rem .6rem; cursor: pointer; min-height: 54px; }
details.wiedza-wpis > summary::-webkit-details-marker { display: none; }
.wpis-mini { width: 46px; height: 42px; display: grid; place-items: center; background: #fff; border-radius: 9px; overflow: hidden; color: #889; }
.wpis-mini img { max-width: 100%; max-height: 100%; object-fit: contain; }
.wpis-tytul { min-width: 0; display: grid; }
.wpis-tytul strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.wpis-tytul small { color: var(--dim); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wpis-znaczki { display: flex; gap: .25rem; flex-wrap: wrap; justify-content: flex-end; max-width: 9.5rem; }
.wpis-tresc { padding: .1rem .75rem .7rem; border-top: 1px dashed var(--line); animation: wchodzi .2s var(--plynnie) both; }
.wpis-tresc dl { margin: .5rem 0; grid-template-columns: 7.5em minmax(0, 1fr); font-size: 13.5px; }
@container panel (min-width: 760px) { #wiedzaLista { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } #wiedzaLista .wiedza-grupa, #wiedzaLista .pusto { grid-column: 1 / -1; } }
@media (max-width: 420px) { .wpis-znaczki { display: none; } }
details.zaawansowane { margin: .7rem 0 .2rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2); }
details.zaawansowane > summary { cursor: pointer; padding: .55rem .75rem; font-weight: 550; list-style: none; }
details.zaawansowane > summary::-webkit-details-marker { display: none; }
details.zaawansowane > summary::before { content: "▸ "; color: var(--dim); }
details.zaawansowane[open] > summary::before { content: "▾ "; }
details.zaawansowane > :not(summary) { margin-left: .75rem; margin-right: .75rem; }
details.zaawansowane { padding-bottom: .7rem; }
.menu-tresc .okno-naglowek { margin-bottom: .2rem; }
.rzad-akcji button .ik { width: 16px; height: 16px; }

details.zaawansowane > form.karta { border: none; background: none; padding: .2rem 0 0; margin-bottom: 0; animation: none; }
.import-kolumny { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; }
#listaPlanow .plan-wiersz { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--r-maly); padding: .5rem .7rem; margin-bottom: .35rem; }
/* plan = nazwa, pod nią jego rewizje; „Delete plan” usuwa wszystkie, „Delete revision” jedną */
.plan-grupa { margin-bottom: .6rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2); overflow: hidden; }
.plan-grupa-gora { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; padding: .5rem .7rem; border-bottom: 1px solid var(--line); }
.plan-grupa-gora strong { font-size: 1.02rem; }
.plan-grupa-gora button { margin-left: auto; }
#listaPlanow .plan-grupa .plan-wiersz { background: none; border: none; border-bottom: 1px solid var(--line); border-radius: 0; margin: 0; padding: .5rem .7rem; }
#listaPlanow .plan-grupa .plan-wiersz:last-child { border-bottom: none; }
button.niebezpieczne:hover { border-color: var(--red); }

.pole-wysilek { display: grid; gap: 3px; margin: .5rem 0; font-size: 13px; color: var(--dim); }
#sprawdzPytania { background: color-mix(in srgb, var(--amber) 18%, var(--panel2)); border-color: var(--amber); }

/* pasek sprawdzania propozycji: zwarty, przyciski małe, podpowiedź tylko na szerokim ekranie */
.sprawdz-pasek { padding: .4rem .5rem; gap: .3rem .35rem; }
.sprawdz-pasek button { min-height: 32px; font-size: 13px; padding: 0 .6rem; border-radius: 9px; }
.sprawdz-pasek strong { flex: 1 1 100%; font-size: .95rem; }
.sprawdz-pasek > .meta { display: none; }
#sprawdzLicznik { flex: 1 1 100%; font-size: 12.5px; color: var(--dim); }
@media (min-width: 700px) { .sprawdz-pasek > .meta { display: inline; } .sprawdz-pasek strong { flex: 0 1 auto; } #sprawdzLicznik { flex: 0 1 auto; } }


/* ===== panel boczny: lista, AI i wiedza otwierają się OBOK planu i odsuwają go w prawo (jak panele w bocie na Pi) =====
   telefon: panel zajmuje cały ekran; szeroki ekran (rozłożony Duo, tablet, komputer): plan zostaje widoczny, zmniejsza się i przesuwa w prawo */
/* --przerwa: odstęp między kartami (plan | panel) i — na szerokim ekranie — do brzegu ekranu, gdzie przy pełnym ekranie leżą boczne uchwyty (app.js PODZIAL_PRZERWA) */
:root { --panel-w: clamp(340px, 40vw, 560px); --przerwa: 12px; }
main { display: flex; gap: var(--przerwa); min-width: 0; }
#panel { display: none; flex-direction: column; gap: .4rem; min-width: 0; min-height: 0; position: relative; }
#panelTresc { flex: 1; min-height: 0; position: relative; container-type: inline-size; container-name: panel; }
#panelTresc > .widok { height: 100%; }
#widok-plan { flex: 1; min-width: 0; }
.rozdzielacz { display: none; --chwyt: 30px; }  /* pole chwytu krawędzi między kartami (palcem 44 px); pastylka w środku odstępu */
.rozdzielacz::after { content: ""; position: absolute; top: 50%; left: 50%; width: 6px; height: 64px; translate: -50% -50%; border-radius: 3px;
  background: color-mix(in srgb, var(--txt) 34%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--bg) 55%, transparent);
  transition: background .15s, width .22s var(--sprez), height .22s var(--sprez); }
.rozdzielacz:hover::after, .rozdzielacz.ciagniety::after, .rozdzielacz:focus-visible::after { background: var(--accent); height: 84px; }
.rozdzielacz.srodek::after { background: var(--accent); width: 8px; height: 104px; }  /* przyciągnięty do środka ekranu (zgięcie Duo) */
.rozdzielacz:focus-visible { outline: none; }
@media (max-width: 559px), (min-width: 560px) and (max-width: 699px) and (orientation: landscape) {  /* wąski: panel zajmuje cały ekran */
  body:not([data-widok="plan"]) #panel { display: flex; flex: 1; }
  body:not([data-widok="plan"]) #widok-plan { display: none; }
}
@media (min-width: 700px) {
  body:not([data-widok="plan"]) #panel { display: flex; flex: 0 0 var(--panel-w); width: var(--panel-w); min-width: 300px; max-width: 72%; animation: panelWchodzi .32s var(--plynnie) both; }
  #widok-plan { display: flex; }  /* plan jest zawsze widoczny; panel go odsuwa */
  .rozdzielacz { display: block; position: absolute; top: 0; bottom: 0; right: calc(var(--przerwa) / -2 - var(--chwyt) / 2); width: var(--chwyt); cursor: col-resize; z-index: 6; touch-action: none; }
  body.zmiana-rozmiaru { cursor: col-resize; user-select: none; } body.zmiana-rozmiaru #panel { animation: none; }
}
/* panel od razu ma docelową szerokość (plan przelicza się raz), wjeżdża tylko przesunięciem i przezroczystością — bez animowania szerokości, która przeliczała plan w każdej klatce */
@keyframes panelWchodzi { from { opacity: 0; transform: translateX(-28px); } to { opacity: 1; transform: none; } }

/* ===== iPhone Duo: układy zależne od kształtu okna (Safari nie zna położenia zgięcia, więc nic nie zakłada pozycji urządzenia) =====
   złożony (466×678, 678×466) = wąski; rozłożony w pionie (626×890) = „stos”: plan u góry, panel pod nim; rozłożony w poziomie (890×626) = szeroki: szyna, panel i plan obok siebie */
:root { --panel-h: 52%; }

/* STOS: rozłożony Duo w pionie i tablet w pionie (do 1099 px) — plan i panel (lista, AI, wiedza) leżą jeden nad drugim: szeroki plan torowy ma całą szerokość
   (wcześniej iPad w pionie dostawał układ „obok siebie” i plan 322 × 993 px). Na Duo dolna belka zakładek zostaje, na tablecie szyna po lewej */
@media (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  main { flex-direction: column; }
  #widok-plan { display: flex; order: 1; }
  body:not([data-widok="plan"]) #panel { display: flex; order: 2; flex: 0 0 var(--panel-h); height: var(--panel-h); min-height: 200px; max-height: 72%; animation: panelWchodziPion .32s var(--plynnie) both;
    width: auto; min-width: 0; max-width: none; }  /* tablet w pionie (700–1099 px): bez szerokości panelu z układu „obok siebie” */
  .rozdzielacz { display: block; position: absolute; top: calc(var(--przerwa) / -2 - var(--chwyt) / 2); left: 0; right: 0; bottom: auto; height: var(--chwyt); width: auto; cursor: row-resize; z-index: 6; touch-action: none; }
  .rozdzielacz::after { width: 64px; height: 6px; }
  .rozdzielacz:hover::after, .rozdzielacz.ciagniety::after, .rozdzielacz:focus-visible::after { width: 84px; height: 6px; }
  .rozdzielacz.srodek::after { width: 104px; height: 8px; }
  body { gap: var(--przerwa); }  /* odstęp nad obszarem kart = przerwa między kartami (górny uchwyt przy pełnym ekranie) */
  body.zmiana-rozmiaru { cursor: row-resize; user-select: none; } body.zmiana-rozmiaru #panel { animation: none; }
}
@keyframes panelWchodziPion { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }

/* NISKI POZIOM: złożony Duo (678×466) albo telefon obrócony — mniej pionu; karty w tej samej pływającej kapsule co na telefonie
   (wcześniej szyna na prawej krawędzi zabierała 66 px szerokości) */
@media (min-width: 560px) and (max-width: 699px) and (orientation: landscape) {
  body { padding: calc(.3rem + env(safe-area-inset-top)) calc(.55rem + env(safe-area-inset-right)) calc(.3rem + env(safe-area-inset-bottom)) calc(.55rem + env(safe-area-inset-left)); gap: .3rem; }
  .gora { padding: .15rem .4rem .15rem .6rem; }
  .projekt-wybor select { min-height: 32px; }
  .chip-postep, button.ikona { min-height: 36px; } button.ikona { width: 36px; }
}

/* SZEROKI 700–1099 px (rozłożony Duo w poziomie, tablet): zgięcie wypada na środku, więc nic ważnego nie leży na środkowym pasie ani nie przecina go.
   Okna dokują się do prawej połowy, powiadomienia do lewej, a listy rozwijane i grupy przycisków nie sięgają środka. */
@media (min-width: 700px) and (max-width: 1099px) and (orientation: landscape) {
  :root { --panel-w: clamp(320px, 37vw, 560px); }
  .projekt-wybor { flex: 0 1 min(380px, 42%); }
  .chip-postep { margin-left: auto; }
  #okno:not(:has(.okno-szerokie)) { margin: 0 0 0 auto; height: 100dvh; max-height: 100dvh; width: min(460px, calc(50vw - 24px)); border-radius: 16px 0 0 16px; border-right: none; }
  #okno:not(:has(.okno-szerokie))[open] { animation: okienkoPrawe .32s var(--plynnie) both; }
  #okno:not(:has(.okno-szerokie)) #oknoTresc { max-height: 100dvh; padding-top: calc(1rem + env(safe-area-inset-top)); padding-bottom: calc(1rem + env(safe-area-inset-bottom)); padding-right: calc(1rem + env(safe-area-inset-right)); }
  #toast { inset: auto auto calc(1rem + env(safe-area-inset-bottom)) calc(1rem + env(safe-area-inset-left)); transform: translate(0, 30px) scale(.94); }
  #toast.widoczny { transform: translate(0, 0) scale(1); }
}
@keyframes okienkoPrawe { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
.podnaw { flex: 0 0 auto; }

/* zaznaczenie elementu: wiersz listy, znacznik na planie, karta pytania AI */
#tabela tbody tr.wybrany { border-color: var(--accent); border-left-color: var(--accent); background: var(--accent-soft); }
#tabela tbody tr td:nth-child(1) { position: relative; padding-right: 2.1rem; }
#tabela tbody tr .szczegoly { position: absolute; right: -.3rem; top: -.2rem; width: 32px; min-height: 30px; padding: 0; font-size: 18px; line-height: 1; }
#tabela tbody tr { user-select: none; -webkit-user-select: none; touch-action: manipulation; }
.pytanie { touch-action: manipulation; cursor: pointer; }
.pytanie.zaznaczone { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
#planNakladka .el.wybrany.puls { animation: podswietlPuls 1s ease-in-out 3; }  /* klasa i opóźnienie z app.js: przerysowanie nie zaczyna pulsowania od nowa */
#planNakladka .prop.podsw circle { stroke: var(--accent); stroke-width: 3.2; fill: color-mix(in srgb, var(--accent) 30%, transparent); animation: podswietlPuls 1s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
/* puls obrysem (grubość i przezroczystość), nie filtrem: animowany drop-shadow w nakładce SVG rozmywał w każdej klatce całą nakładkę — przy propozycjach AI
   i przenoszeniu bez końca (na iPhonie najdroższa animacja aplikacji). --sw: grubość obrysu danego stanu */
@keyframes podswietlPuls { 0%, 100% { stroke-width: var(--sw, 2.4px); stroke-opacity: 1; } 50% { stroke-width: calc(var(--sw, 2.4px) * 2.2); stroke-opacity: .55; } }
#planNakladka .el.wybrany, #planNakladka .prop.przenoszony circle { --sw: 3px; }
#planNakladka .prop.podsw circle { --sw: 3.2px; }
#planNakladka .el.przenoszony { --sw: 2.4px; }

/* informacje z internetu (przy pytaniu AI i we wpisie wiedzy) */
.info-web { margin-top: .5rem; padding: .5rem .6rem; border: 1px dashed var(--line2); border-radius: 10px; background: color-mix(in srgb, var(--accent) 6%, var(--panel2)); font-size: 13px; display: grid; gap: .3rem; }
.info-web p { margin: 0; line-height: 1.4; }
.info-web .rzad { align-items: center; gap: .35rem; flex-wrap: wrap; }
.info-web .rzad .ikona { margin-left: auto; }
.info-web .zrodla { margin: 0; padding-left: 1.1rem; font-size: 12px; color: var(--dim); }
.info-web .zrodla a { color: var(--accent); overflow-wrap: anywhere; }
.info-web label.zwykla { display: flex; align-items: center; gap: .5rem; font-size: 12.5px; color: var(--dim); }

/* kolejność wielu wybranych plików planu */
.kolejnosc-plikow { margin: 0; padding: .35rem .6rem; list-style: none; border: 1px dashed var(--line2); border-radius: 8px; font-size: 12.5px; display: grid; gap: 1px; }
.kolejnosc-plikow li { overflow-wrap: anywhere; }
.kolejnosc-plikow[hidden] { display: none; }

/* ---------- tryby pracy: Montage / Prüfung ---------- */
.tryby { display: inline-flex; gap: 2px; padding: 3px; border-radius: 13px; background: var(--panel2); border: 1px solid var(--line); }
.tryby button { min-height: 34px; padding: 0 1rem; border-radius: 10px; border-color: transparent; background: transparent; color: var(--dim); font-weight: 650; box-shadow: none; font-size: 13.5px; }
.tryby button:hover { transform: none; color: var(--txt); }
.tryby button.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); box-shadow: 0 3px 12px color-mix(in srgb, var(--accent) 30%, transparent); }
#trybPrzelacznik { margin: 0 0 .5rem; }
.element-pasek { display: flex; gap: .5rem; align-items: center; justify-content: space-between; flex-wrap: wrap; margin: .2rem 0 .6rem; }
.nawig-el { display: inline-flex; gap: .3rem; align-items: center; }
.nawig-el button.ikona { width: 38px; min-height: 36px; }
.sekcja-trybu { border: 1px solid var(--line); border-radius: var(--r); margin: .55rem 0; background: color-mix(in srgb, var(--panel2) 55%, transparent); }
.sekcja-trybu > summary { cursor: pointer; padding: .55rem .75rem; display: flex; gap: .45rem; align-items: center; list-style: none; font-size: 1rem; }
.sekcja-trybu > summary::-webkit-details-marker { display: none; }
.sekcja-trybu > summary::after { content: "▾"; margin-left: auto; color: var(--faint); transition: transform .2s ease; }
.sekcja-trybu:not([open]) > summary::after { transform: rotate(-90deg); }
.sekcja-trybu[open] > summary { border-bottom: 1px solid var(--line); }
.sekcja-trybu > .krok, .sekcja-trybu > .pomiary, .sekcja-trybu > p { margin: .55rem .6rem; }
.chip.ok { color: var(--green); }
.chip.zle { color: var(--red); border-color: color-mix(in srgb, var(--red) 55%, var(--line)); }
.do-pracy-wiersz { margin: .5rem 0; }
/* numer (nazwa) kabla elementu: pole w karcie i znaczek na liście */
.kabel-pole { display: flex; align-items: center; gap: .6rem; margin: .5rem 0 .2rem; }
.kabel-pole > span { color: var(--dim); font-size: 13px; flex: none; }
.kabel-pole input { flex: 1; min-width: 0; }
.kabel-chip { display: inline-block; max-width: 12em; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; color: var(--txt); background: var(--panel2); }
.narzedzia { margin: .5rem 0 .7rem; }
.narzedzia > summary { cursor: pointer; color: var(--dim); font-size: 13px; padding: .3rem 0; }
.narzedzia[open] { background: var(--panel2); border: 1px solid var(--line); border-radius: .6rem; padding: .1rem .7rem .3rem; }
.blad-formularza { color: var(--red); font-size: 13px; margin: .35rem 0 0; }

/* ---------- pomiary rezystancji przewodów ---------- */
.pomiary { display: grid; gap: .5rem; padding: .1rem 0; }
.pom-znaczek { display: inline-block; font-size: 11.5px; font-weight: 650; padding: 0 .4rem; border-radius: 999px; border: 1px solid var(--line2); color: var(--dim); margin-left: .25rem; white-space: nowrap; }
.pom-znaczek.ok { color: var(--green); border-color: color-mix(in srgb, var(--green) 50%, var(--line)); }
.pom-znaczek.zle { color: var(--red); border-color: color-mix(in srgb, var(--red) 55%, var(--line)); }
.pom-znaczek.w-toku { color: var(--amber); border-color: color-mix(in srgb, var(--amber) 50%, var(--line)); }
.pom-limity { display: grid; gap: .5rem; margin: .3rem 0 .6rem; }
.pom-limity label { display: grid; gap: 2px; font-size: 13px; color: var(--dim); }
.pom-limity input, .pom-limity select { min-height: 38px; border: 1px solid var(--line2); border-radius: 9px; background: var(--bg); padding: 0 .5rem; }

/* ---------- plan pracy („koszyk”) ---------- */
#planNakladka .el.w-pracy { stroke: #e6007e; stroke-width: 2.6px; stroke-dasharray: none; }
#planNakladka .el.w-pracy.otwarte, #planNakladka .el.w-pracy.brak { fill: #e6007e24; }
#planNakladka .praca-znacznik circle { fill: #e6007e; stroke: #fff; stroke-width: 1.2; }
#planNakladka .praca-znacznik text { font: 700 7px sans-serif; fill: #fff; text-anchor: middle; dominant-baseline: central; }
/* problem przy elemencie: mały czerwony wykrzyknik na planie (biała obwódka, żeby był widoczny także na czerwonym tle „otwarte”) */
#planNakladka .problem-znacznik { cursor: pointer; }
#planNakladka .problem-znacznik circle { fill: #e11d1d; stroke: #fff; }
#planNakladka .problem-znacznik text { font-family: sans-serif; font-weight: 800; fill: #fff; text-anchor: middle; dominant-baseline: central; pointer-events: none; }
/* wykrzyknik pulsuje powoli (18.10.2026, użytkownik): znak lekko „oddycha”, a od niego rozchodzi się gasnąca fala — 3 s na cykl (PULS_PROBLEMU w app.js).
   Faza z zegara dokumentu (--faza-problemu), więc przerysowanie nakładki nie szarpie pulsu; same transformacje i przezroczystość */
#planNakladka .problem-znacznik :is(.rdzen, .fala) { transform-box: fill-box; transform-origin: center; animation-duration: 3s; animation-iteration-count: infinite;
  animation-delay: var(--faza-problemu, 0s); }
#planNakladka .problem-znacznik .rdzen { animation-name: problemOddech; animation-timing-function: ease-in-out; }
#planNakladka .problem-znacznik .fala { fill: none; stroke: #e11d1d; pointer-events: none; animation-name: problemFala; animation-timing-function: cubic-bezier(.2, .6, .35, 1); }
@keyframes problemOddech { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
@keyframes problemFala { 0% { transform: scale(1); opacity: .75; } 75%, 100% { transform: scale(2.3); opacity: 0; } }
#tabela button.do-pracy { margin-right: 2px; }
#tabela button.do-pracy.jest { color: #e6007e; }
#tabela button.do-pracy .ik { width: 17px; height: 17px; }
.praca-gora { display: grid; gap: .4rem; margin-bottom: .6rem; }
.praca-gora input { min-height: 40px; border: 1px solid var(--line2); border-radius: var(--r-maly); background: var(--panel2); padding: 0 .7rem; width: 100%; }
#pracaLista { display: grid; gap: .5rem; }
.praca-poz { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: .55rem; align-items: start; padding: .6rem .65rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2); cursor: pointer; }
.praca-poz.zaznaczone { border-color: #e6007e; box-shadow: 0 0 0 1px #e6007e inset; }
.praca-poz.brak { opacity: .7; border-style: dashed; }
.praca-nr { width: 30px; height: 30px; border-radius: 50%; background: #e6007e; color: #fff; display: grid; place-items: center; font-weight: 750; font-size: 14px; flex: none; }
.praca-tresc { display: grid; gap: .35rem; min-width: 0; }
.praca-el { display: flex; gap: .4rem; align-items: baseline; flex-wrap: wrap; }
.praca-tresc textarea { width: 100%; resize: vertical; min-height: 3.2rem; border: 1px solid var(--line2); border-radius: 9px; background: var(--bg); padding: .45rem .55rem; }
.praca-akcje { display: grid; grid-template-columns: repeat(2, auto); gap: 2px; }
.praca-akcje button { width: 34px; min-height: 34px; padding: 0; }
.praca-dol { display: grid; gap: .5rem; margin-top: .8rem; }
.praca-dodaj { display: flex; gap: .4rem; }
.praca-dodaj input { flex: 1; min-height: 40px; border: 1px solid var(--line2); border-radius: var(--r-maly); background: var(--panel2); padding: 0 .7rem; min-width: 0; }
.pole-opis { display: grid; gap: 4px; margin: .6rem 0; color: var(--dim); font-size: 13px; }
.pole-opis textarea { width: 100%; border: 1px solid var(--line2); border-radius: 9px; background: var(--bg); padding: .5rem .6rem; font-size: 15px; resize: vertical; }
.chipy-zadan { display: flex; gap: .35rem; flex-wrap: wrap; align-items: center; margin: .3rem 0 .6rem; }
.chip-btn { min-height: 30px; padding: 0 .65rem; border-radius: 999px; font-size: 13px; }
.eks-opcje { gap: .8rem; margin: .4rem 0 .8rem; }
.eks-obraz { margin: 0 0 1rem; padding: .5rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2); }
.eks-obraz img { width: 100%; height: auto; display: block; border-radius: 8px; background: #fff; }
.eks-obraz figcaption { font-size: 12.5px; color: var(--dim); margin: .35rem 0; }

/* ---------- zaznaczanie wielu elementów ---------- */
#planRamka { position: absolute; z-index: 6; border: 2px dashed var(--accent); background: color-mix(in srgb, var(--accent) 16%, transparent); pointer-events: none; border-radius: 4px; }
#planNakladka .el.zazn { stroke: var(--wybor); stroke-width: 3.2px; stroke-dasharray: none; filter: drop-shadow(0 0 2px var(--wybor)); }
#planNakladka .el.zazn.otwarte, #planNakladka .el.zazn.brak, #planNakladka .el.zazn.bez-opisu { fill: color-mix(in srgb, var(--wybor) 30%, transparent); }
body.zaznaczanie #planOkno { cursor: crosshair; }
body.zaznaczanie #tabela td:first-child { position: relative; }
body.zaznaczanie #tabela tbody tr { cursor: pointer; }
body.zaznaczanie #tabela tbody tr td:first-child::before { content: "☐"; margin-right: .3rem; color: var(--dim); font-size: 1.1rem; }
#tabela tbody tr.zazn { background: color-mix(in srgb, var(--wybor) 16%, transparent); }
body.zaznaczanie #tabela tbody tr.zazn td:first-child::before { content: "☑"; color: var(--wybor); }
[data-zaznacz-tryb].on { background: var(--wybor); border-color: var(--wybor); color: #fff; }
.zazn-pasek { position: absolute; left: .3rem; right: .3rem; bottom: .3rem; z-index: 20; display: grid; gap: .45rem; padding: .6rem .7rem; border-radius: var(--r); background: var(--panel); border: 1px solid var(--wybor); box-shadow: var(--cien); }
.zazn-gora { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; justify-content: space-between; }
.zazn-pasek .ikona-maly { min-width: 40px; padding: 0 .5rem; }
/* szybkie odhaczanie wszystkich etapów: przyciski etapów (jedno stuknięcie), lista pozycji ze wszystkich etapów i ikony ✓ / ↺ */
.zazn-gora-przyciski { display: inline-flex; gap: .35rem; flex-wrap: wrap; justify-content: flex-end; }
/* „Mark places”: nazwa, typ i km następnego elementu; poniżej licznik i cofnięcie */
.znacz-pola { display: grid; grid-template-columns: minmax(0, 1fr) 7rem; gap: .35rem; }
.znacz-pola input[data-znacz="nazwa"], .znacz-pola select { min-height: 40px; }
.znacz-pola input[data-znacz="nazwa"] { grid-column: 1 / -1; }
.znacz-pola select { min-width: 0; }
.znacz-pola input { min-width: 0; min-height: 40px; }
.znacz-stopka { display: flex; align-items: center; justify-content: space-between; gap: .5rem; flex-wrap: wrap; }
.znacz-stopka .meta { flex: 1 1 10rem; }

.zazn-pasek { padding: .5rem .55rem; gap: .35rem; container: zazn / inline-size; grid-template-columns: minmax(0, 1fr); }  /* kolumna siatki nie rośnie do zawartości: długi wiersz zwęża tytuł (wielokropek), nie wypycha ⌃ poza ekran */
.zazn-etap-szybki, .zazn-znacz-gora { display: none; }
@container zazn (min-width: 560px) { .zazn-szybki { display: none; } .zazn-etap-szybki { display: inline-flex; } }  /* ✓ każdego etapu bez rozwijania */
@container zazn (min-width: 760px) { .zazn-znacz-gora { display: inline-flex; } .zazn-przyciski [data-zazn="znacz-start"] { display: none; } }
.zazn-przyciski button { padding: 0 .4rem; font-size: 12.5px; }
.zazn-przyciski { display: flex; gap: .3rem; flex-wrap: wrap; }

/* ---------- sprawdzanie: wybrany / przenoszony znacznik, tryb dodawania ---------- */
#planNakladka .prop.wybrana circle { stroke: var(--accent); stroke-width: 2.6; stroke-dasharray: none; filter: drop-shadow(0 0 2px var(--accent)); cursor: grab; }
#planNakladka .prop.przenoszony circle { stroke: var(--wybor); stroke-width: 3; animation: podswietlPuls 1s ease-in-out infinite; }
#planOkno.celowanie { cursor: crosshair; }
#planNakladka .el.przenoszony { stroke: var(--wybor); stroke-width: 2.4px; fill: color-mix(in srgb, var(--wybor) 24%, transparent); animation: podswietlPuls 1s ease-in-out infinite; cursor: grab; }
.przesuniety-info { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin: .1rem 0 .5rem; }
#sprawdzDodaj.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.sprawdz-pasek.bez-podpowiedzi > .meta { display: none !important; }
#dodajPasek { flex-wrap: nowrap; align-items: center; }
#dodajPasek strong { flex: 1 1 0; min-width: 0; font-size: .9rem; line-height: 1.25; }
@media (max-width: 440px) { .tryby button { padding: 0 .55rem; } }  /* wąski ekran: mniej odstępu, ten sam rozmiar pisma */

/* ---------- cele dotykowe na ekranie dotykowym: Apple zaleca co najmniej 44 pt (mysz i klawiatura zostają przy zwartym wyglądzie) ---------- */
@media (pointer: coarse) {
  select, input, textarea { font-size: 16px; }  /* iOS Safari powiększa stronę przy polu z czcionką < 16 px — na każdym ekranie dotykowym, też szerokim (Duo w poziomie) */
  button, a.przycisk-link, select, summary, input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]) { min-height: 44px; }
  button.maly, .przycisk-label { min-height: 44px; }
  button.ikona, button.ikona.maly { width: 44px; min-height: 44px; }
  .podnaw button, .tryby button, .statusy button, .projekt-wybor select, .chip-postep,
  details.warstwy > summary, details.filtry > summary, .szukaj-rzad #filtr { min-height: 44px; }
  .chip-btn { min-height: 36px; } .plan-etap-chip { min-height: 40px; }  /* pastylki: filtry grup i znacznik etapu na planie (nie zasłaniają planu) */
  #tabela tbody tr button.maly.cichy, #tabela tbody tr .szczegoly { width: 40px; min-height: 40px; }  /* ikony w wierszu listy: 40 px, żeby wiersz nie rósł */
}
.menu-diag { margin: .4rem 0; }
.menu-diag > summary { cursor: pointer; color: var(--dim); font-size: 13px; padding: .3rem 0; }
.menu-diag pre { margin: .3rem 0 .5rem; user-select: text; -webkit-user-select: text; }
/* wyszukiwanie w projekcie (lupa w nagłówku) i przejście „wszystkie elementy tego kabla” */
.szukaj-grupa { margin: .7rem 0 .1rem; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; color: var(--dim); }
.szukaj-poz { justify-content: flex-start; text-align: left; flex-wrap: wrap; gap: .1rem .5rem; width: 100%; min-height: 44px; padding: .35rem .7rem; font-weight: 500; white-space: normal; }
.kabel-blok { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.kabel-blok .kabel-pole { flex: 1 1 15rem; }
.kabel-inne .licznik { margin-left: .35rem; }
/* pasek „Offline” w nagłówku (tryb bez sieci, sw.js): dane z pamięci urządzenia, zmiany się nie zapisują */
.offline-baner { display: block; width: 100%; min-height: 0; margin: .35rem 0 .35rem; padding: .3rem .65rem; text-align: left; justify-content: flex-start; white-space: normal;
  font-size: 12.5px; font-weight: 500; line-height: 1.35; color: var(--amber); background: color-mix(in srgb, var(--amber) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--amber) 55%, var(--line)); border-radius: 10px; box-shadow: none; }
.offline-baner[hidden] { display: none; }
@media (pointer: coarse) { .offline-baner { min-height: 36px; } }

/* zapis na urządzeniu (Menu → Save for offline use) */
.offline-stan { margin: .6rem 0; padding: .55rem .7rem; border-left: 3px solid var(--accent); background: var(--accent-soft); border-radius: 0 6px 6px 0; }
.off-postep { display: block; width: 100%; height: .7rem; margin: .6rem 0; accent-color: var(--accent); }
.off-przyciski { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .7rem; }
.off-przyciski button { flex: 1 1 9rem; justify-content: center; }

/* ---------- przejście między kartami: View Transitions (app.js przelaczPlynnie) ----------
   ruch robią zrzuty starej i nowej zawartości na karcie graficznej; w tym czasie elementy nie mają własnych animacji wejścia */
html.vt .widok.aktywny, html.vt #panel { animation: none !important; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }  /* nagłówek i belka zakładek zmieniają się od razu */
::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation-duration: .32s; animation-timing-function: var(--plynnie); }
/* nagłówek: osobna warstwa, która przenika — na niskim ekranie (telefon, złożony Duo w poziomie) karta Plan ma w nim pasek planu, a inne karty nie;
   wcześniej zawartość nagłówka podmieniała się w pierwszej klatce, a pod nim karty płynnie się przesuwały (17.10.2026) */
.gora { view-transition-name: naglowek; }
::view-transition-old(naglowek), ::view-transition-new(naglowek) { animation-duration: .22s; }
/* telefon: cała zawartość pod nagłówkiem przesuwa się jak strona — nowa wjeżdża z kierunkiem ruchu, stara ustępuje */
main { view-transition-name: karty; }
html[data-kier="przod"]::view-transition-new(karty) { animation-name: vtZPrawej; }
html[data-kier="przod"]::view-transition-old(karty) { animation-name: vtWLewo; }
html[data-kier="tyl"]::view-transition-new(karty) { animation-name: vtZLewej; }
html[data-kier="tyl"]::view-transition-old(karty) { animation-name: vtWPrawo; }
@keyframes vtZPrawej { from { opacity: 0; transform: translateX(22%); } }
@keyframes vtZLewej { from { opacity: 0; transform: translateX(-22%); } }
@keyframes vtWLewo { to { opacity: 0; transform: translateX(-10%); } }
@keyframes vtWPrawo { to { opacity: 0; transform: translateX(10%); } }
/* kapsuła kart (telefon): własna warstwa NAD przesuwaną treścią — main sięga pod kapsułę, więc warstwa „karty” zakrywała ją na całe przejście
   i kapsuła wskakiwała na końcu (zrzut w połowie przejścia, 17.10.2026). Warstwa idzie za żywym elementem (grupa bez animacji: zwijanie i rozwijanie
   widać na bieżąco); rozmycie szkła robi sama warstwa — wewnątrz zrzutu elementu „backdrop-filter” nie ma czego rozmywać */
nav.zakladki { view-transition-name: kapsula; }
::view-transition-group(kapsula), ::view-transition-new(kapsula) { animation: none; }
::view-transition-old(kapsula) { display: none; }
::view-transition-image-pair(kapsula) { border-radius: 999px; backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr); }
@keyframes vtZnika { to { opacity: 0; } }
@keyframes vtPojawia { from { opacity: 0; } }
/* szeroki ekran i „stos”: plan zostaje na miejscu — osobno panel (wjeżdża, znika albo zmienia zawartość) i plan (płynnie zmienia rozmiar, bez zniekształcenia) */
@media (min-width: 700px), (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  main { view-transition-name: none; }
  #panel { view-transition-name: panel; }
  #widok-plan { view-transition-name: plan; }
  ::view-transition-image-pair(plan) { overflow: hidden; border-radius: 16px; }
  /* zrzuty w naturalnej skali, wyśrodkowane (rozciąganie „cover” do zmieniającej się karty dawało dwa rysunki w różnej skali naraz) */
  ::view-transition-old(plan), ::view-transition-new(plan) { width: 100%; height: 100%; object-fit: none; object-position: center; }
  ::view-transition-old(plan) { animation-name: vtZnika; }
  ::view-transition-new(plan) { animation-name: vtPojawia; }
  /* przenikanie bez przygaszenia: własna animacja zastępuje też przeglądarkowe „plus-lighter” — przy zwykłym mieszaniu dwa obrazy po 50% kryły razem 75%
     i plan (ten sam przed i po) szarzał w połowie każdej zmiany karty, bo prześwitywało ciemne tło (zrzut w połowie przejścia, 17.10.2026) */
  ::view-transition-old(plan), ::view-transition-new(plan) { mix-blend-mode: plus-lighter; }
  html[data-kier]::view-transition-new(panel):only-child { animation-name: vtPanelWchodzi; }
  html[data-kier]::view-transition-old(panel):only-child { animation-name: vtPanelWychodzi; animation-duration: .24s; }
  /* zmiana zawartości panelu (stara i nowa): z kierunkiem; panel, który się pojawia albo znika (:only-child), ma reguły niżej o wyższej szczegółowości */
  html[data-kier="przod"]::view-transition-new(panel) { animation-name: vtZPrawej; }
  html[data-kier="przod"]::view-transition-old(panel) { animation-name: vtWLewo; }
  html[data-kier="tyl"]::view-transition-new(panel) { animation-name: vtZLewej; }
  html[data-kier="tyl"]::view-transition-old(panel) { animation-name: vtWPrawo; }
  ::view-transition-image-pair(panel) { overflow: hidden; border-radius: 16px; }
  /* plan na ekranie przed i po (app.js planWObuStanach, ruchPlanuVT): rysunek leży sam na sobie — stary zrzut maleje do nowego kadru i zostaje pod spodem,
   nowy startuje z kadru starego i pojawia się nad nim (bez „plus-lighter”: stary jest nieprzezroczysty); tło i ramkę karty rysuje para obrazów, bo zrzuty
   w innej skali nie pokrywają karty i ich ramka wypadałaby w środku. Szklane narzędzia planu jadą osobno, ze szkłem na parze (w zrzucie nie ma czego rozmywać) */
  html.vt-plan-obie #widok-plan { border-color: transparent; }
  html.vt-plan-obie::view-transition-image-pair(plan) { background: var(--plan-bg); outline: 1px solid var(--line); outline-offset: -1px; }  /* tło jak pod planem (papier) — brzegi odsłaniane w ruchu */
  html.vt-plan-obie::view-transition-old(plan) { animation-name: vtPlanStary; mix-blend-mode: normal; }
  html.vt-plan-obie::view-transition-new(plan) { animation-name: vtPlanNowy; mix-blend-mode: normal; }
  html.vt-plan-obie #planNarzedzia { view-transition-name: plan-narzedzia; }
  html.vt-plan-obie :is(#planEtapy, #planEtapChip) { view-transition-name: plan-etap; }  /* widoczny jeden z dwóch: szeroki plan — pasek, wąski — znacznik */
  html.vt-plan-obie .plan-strony { view-transition-name: plan-strony; }
  html.vt-plan-obie #planMapa { view-transition-name: plan-mapa; }
  html.vt-plan-obie::view-transition-image-pair(plan-narzedzia), html.vt-plan-obie::view-transition-image-pair(plan-etap), html.vt-plan-obie::view-transition-image-pair(plan-strony) {
    overflow: hidden; border-radius: 999px; backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr); }
  /* pasek etapów ↔ znacznik: szkło zmienia szerokość, zawartość bez rozciągania (zakotwiczona z lewej, jak oba elementy) */
  html.vt-plan-obie::view-transition-old(plan-etap), html.vt-plan-obie::view-transition-new(plan-etap) { width: 100%; height: 100%; object-fit: none; object-position: left center; }
  /* inna zawartość (pasek ↔ znacznik): stara znika w pierwszej części ruchu, nowa pojawia się w drugiej — bez nakładania napisów („Montaż” na „Montaż”) */
  html.vt-etap-zmiana.vt-plan-obie::view-transition-old(plan-etap) { animation-name: vtEtapZnika; mix-blend-mode: normal; }
  html.vt-etap-zmiana.vt-plan-obie::view-transition-new(plan-etap) { animation-name: vtEtapPojawia; mix-blend-mode: normal; }
  /* panel albo karta elementu wsuwa się razem z krawędzią planu — bez przezroczystości, nie wchodzi na plan (ta sama krzywa i czas co plan) */
  html.vt-plan-ruch.vt-plan-obie[data-kier]::view-transition-new(panel):only-child, html.vt-plan-ruch.vt-plan-obie[data-kier]::view-transition-new(karta):only-child {
    animation-name: vtWsuwa; animation-duration: .32s; }
  html.vt-plan-ruch.vt-plan-obie[data-kier]::view-transition-old(panel):only-child, html.vt-plan-ruch.vt-plan-obie[data-kier]::view-transition-old(karta):only-child {
    animation-name: vtWysuwa; animation-duration: .32s; }
}
@keyframes vtPlanStary { to { transform: var(--vt-plan-stary, none); } }
@keyframes vtPlanNowy { from { opacity: 0; transform: var(--vt-plan-nowy, none); } }
@keyframes vtEtapZnika { 40%, to { opacity: 0; } }
@keyframes vtEtapPojawia { 0%, 30% { opacity: 0; } }
@keyframes vtWsuwa { from { transform: translate(var(--vt-wsuw-x, 0px), var(--vt-wsuw-y, 0px)); } }
@keyframes vtWysuwa { to { transform: translate(calc(-1 * var(--vt-wsuw-x, 0px)), calc(-1 * var(--vt-wsuw-y, 0px))); } }
@keyframes vtPanelWchodzi { from { opacity: 0; transform: translateX(-16%); } }
@keyframes vtPanelWychodzi { to { opacity: 0; transform: translateX(-16%); } }
@media (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {  /* „stos”: panel leży pod planem, więc wjeżdża od dołu */
  html[data-kier]::view-transition-new(panel):only-child { animation-name: vtPanelZDolu; }
  html[data-kier]::view-transition-old(panel):only-child { animation-name: vtPanelWDol; }
}
@keyframes vtPanelZDolu { from { opacity: 0; transform: translateY(16%); } }
@keyframes vtPanelWDol { to { opacity: 0; transform: translateY(16%); } }

/* ---------- karta elementu w miejscu panelu (app.js pokazKarteElementu) ----------
   niemodalne okno dokładnie na prostokącie panelu (--karta-*), plan obok zostaje aktywny; gdy panel był zamknięty, jego miejsce i tak się pojawia (puste pod kartą) */
@media (min-width: 700px) {
  body.karta-w-panelu[data-widok="plan"] #panel { display: flex; flex: 0 0 var(--panel-w); width: var(--panel-w); min-width: 300px; max-width: 72%; }
}
@media (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  body.karta-w-panelu[data-widok="plan"] #panel { display: flex; order: 2; flex: 0 0 var(--panel-h); height: var(--panel-h); min-height: 200px; max-height: 72%; width: auto; min-width: 0; max-width: none; }
}
@media (min-width: 700px), (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  body.karta-w-panelu[data-widok="plan"] #panelTresc, body.karta-w-panelu[data-widok="plan"] #podnaw { visibility: hidden; }
  body.karta-w-panelu #panel { animation: none; }
  body.karta-w-panelu #okno { position: fixed; inset: auto; left: var(--karta-x); top: var(--karta-y); width: var(--karta-w); height: var(--karta-h); max-width: none; max-height: none;
    margin: 0; z-index: 40; border: 1px solid var(--line2); border-radius: 16px; box-shadow: var(--cien); }
  body.karta-w-panelu #okno[open] { animation: kartaWPanelu .26s var(--plynnie) both; }
  body.karta-w-panelu #okno::before { display: none; }  /* bez uchwytu arkusza */
  /* treść przewija się pod kapsułą jak w innych widokach (zapas na dole); kapsuła NAD kartą — karta w prawej połowie Duo i w „stosie” (na dole) ją przykrywała:
     nie dało się zmienić karty ani otworzyć menu bez zamknięcia okna (20.10.2026) */
  body.karta-w-panelu #okno #oknoTresc { height: 100%; max-height: none; padding: 1rem 1rem calc(var(--rezerwa-dol) + .5rem); }
  body.karta-w-panelu nav.zakladki { z-index: 45; }
}
@keyframes kartaWPanelu { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* plan stale widoczny obok panelu (szeroki ekran, „stos”) nie ma animacji wejścia — nic nie „wjeżdża”, bo plan cały czas jest na ekranie */
@media (min-width: 700px), (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  #widok-plan.aktywny { animation: none; }
}

/* ---------- przegląd animacji (16.10.2026): tylko transform i przezroczystość, 0,2–0,45 s, wspólne krzywe; ograniczony ruch wyłącza wszystko (reguła wyżej) ---------- */
/* plan: przy zmianie strony stary obraz znika od razu, nowy pojawia się płynnie (app.js aktualizujObraz); „pokaż na planie” na tej samej stronie dojeżdża płynnie */
#planObraz { transition: opacity .22s var(--plynnie); }
#planObraz.zmiana-strony { opacity: 0; transition: none; }
#planWarstwa.lot { transition: transform .42s var(--plynnie); }
/* karta elementu: inny element (◀ ▶, przesunięcie, stuknięcie na planie) wjeżdża od strony ruchu; po zapisie kroku tylko odhaczony krok błyska */
#oknoTresc.anim-przod { animation: trescZPrawej .28s var(--plynnie) both; }
#oknoTresc.anim-tyl { animation: trescZLewej .28s var(--plynnie) both; }
/* nowa treść przez pierwsze ok. 60 ms niewidoczna (stara gaśnie w 130 ms, app.js duchTresci) — przenikanie bez podwójnego obrazu; ruch od początku */
@keyframes trescZPrawej { 0% { opacity: 0; transform: translateX(28px); } 22% { opacity: 0; } 100% { opacity: 1; transform: none; } }
@keyframes trescZLewej { 0% { opacity: 0; transform: translateX(-28px); } 22% { opacity: 0; } 100% { opacity: 1; transform: none; } }
.krok.nowy.zrobione { animation: blysk .9s ease-out; }
/* pasek zaznaczania i pasek „Offline” wsuwają się, gdy się pojawiają */
/* pasek zaznaczania i kadrowania stoi przy dolnej krawędzi (kapsuła w tym czasie zjeżdża w dół): wjeżdża spod krawędzi samym przesunięciem — szkło
   z backdrop-filter, które blednie, gubi rozmycie (plan prześwitywał ostro, rozmycie wskakiwało na końcu); odjazd w dół robi kopia (app.js duchElementu) */
.zazn-pasek:not([hidden]) { animation: zaznWchodzi .3s var(--plynnie) both; }
@keyframes zaznWchodzi { from { transform: translateY(calc(100% + .75rem)); } to { transform: none; } }
.offline-baner:not([hidden]) { animation: wchodzi .25s var(--plynnie) both; }
/* zmiana motywu (app.js initMotyw): cała strona płynnie przenika do nowych kolorów; nazwane części (karty, panel, plan) na ten czas nie są osobne */
html.vt-motyw main, html.vt-motyw #panel, html.vt-motyw #widok-plan, html.vt-motyw .gora, html.vt-motyw nav.zakladki { view-transition-name: none !important; }
html.vt-motyw::view-transition-old(root) { animation: none; mix-blend-mode: normal; }
html.vt-motyw::view-transition-new(root) { animation: vtPojawia .34s var(--plynnie) both; mix-blend-mode: normal; }

/* komunikat (popover): pokazuje się z „display: none”, więc bez punktu startowego przejście w ogóle nie ruszało — wyskakiwał od razu */
@starting-style { #toast.widoczny { opacity: 0; transform: translate(-50%, 30px) scale(.94); } }
@media (min-width: 700px) and (max-width: 1099px) and (orientation: landscape) { @starting-style { #toast.widoczny { opacity: 0; transform: translate(0, 30px) scale(.94); } } }
/* karta elementu: kopia starej zawartości odjeżdża nad nową (app.js duchTresci) */
.tresc-duch { position: absolute; z-index: 3; overflow: hidden; pointer-events: none; background: var(--panel); }

/* nowy znacznik („Mark places”) ląduje w miejscu stuknięcia, potem pulsuje jak każdy zaznaczony element */
#planNakladka .el.nowy { transform-box: fill-box; transform-origin: center; animation: znacznikLaduje .38s var(--sprez) both; }
#planNakladka .el.wybrany.nowy { animation: znacznikLaduje .38s var(--sprez) both, podswietlPuls 1s ease-in-out .38s 2; }
@keyframes znacznikLaduje { from { opacity: 0; transform: scale(2.4); } to { opacity: 1; transform: none; } }

/* pulsy ciągłe na planie: ta sama faza po przerysowaniu nakładki (--faza z app.js rysujNakladke) */
#planNakladka .el.przenoszony, #planNakladka .prop.przenoszony circle, #planNakladka .prop.podsw circle, #planNakladka .el.kandydat, #planNakladka .napis.kandydat { animation-delay: var(--faza, 0s); }
/* karta elementu w miejscu panelu: otwarcie i zamknięcie przejściem (app.js przejscie) — karta wjeżdża jak panel, plan płynnie zmienia rozmiar */
html.vt #okno { animation: none !important; }
@media (min-width: 700px), (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  body.karta-w-panelu #okno { view-transition-name: karta; }
  ::view-transition-image-pair(karta) { overflow: hidden; border-radius: 16px; }
  html[data-kier]::view-transition-new(karta):only-child { animation-name: vtPanelWchodzi; }
  html[data-kier]::view-transition-old(karta):only-child { animation-name: vtPanelWychodzi; animation-duration: .24s; }
}
@media (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  html[data-kier]::view-transition-new(karta):only-child { animation-name: vtPanelZDolu; }
  html[data-kier]::view-transition-old(karta):only-child { animation-name: vtPanelWDol; }
}

/* gest „wstecz” od krawędzi (ruch.js): ekran docelowy widać pod przesuwaną kartą (Plan pod panelem albo poprzednia karta pod bieżącą) */
@property --tlo { syntax: "<number>"; inherits: true; initial-value: 1; }  /* przyciemnienie pod arkuszem ściąganym w dół (blednie za palcem) */
.widok.podklad-wstecz { display: flex !important; position: absolute; inset: 0; z-index: 0; pointer-events: none; will-change: transform, opacity; }
#widok-szablony.podklad-wstecz, #widok-import.podklad-wstecz, #widok-wiedza.podklad-wstecz, #widok-ai.podklad-wstecz, #widok-logi.podklad-wstecz { display: block !important; }
body.wstecz-w-toku #panel { z-index: 1; }
body.wstecz-w-toku #panelTresc > .widok.aktywny { position: relative; z-index: 1; }
/* ekran pod spodem przyciemniony nakładką (blednie za palcem) — półprzezroczystość dawała w jasnym motywie wyblakły obraz */
@property --cien-wstecz { syntax: "<number>"; inherits: false; initial-value: 0; }
/* zmienna nie dziedziczy się (przeliczanie całej karty w każdej klatce gestu), więc ::after bierze ją od karty jawnie */
.widok.podklad-wstecz::after { content: ""; position: absolute; inset: 0; z-index: 50; background: #000; --cien-wstecz: inherit; opacity: var(--cien-wstecz, 0); pointer-events: none; }
/* przeciągnięcie poziome w panelu (ruch.js): sąsiednia karta wjeżdża z boku razem z palcem; panel przycina to, co wyjeżdża poza niego */
body.strony-w-toku #panelTresc { overflow: hidden; }
#panelTresc > .widok.strona-obok { display: flex !important; position: absolute; inset: 0; z-index: 2; pointer-events: none; will-change: transform; }
#widok-szablony.strona-obok, #widok-import.strona-obok, #widok-wiedza.strona-obok, #widok-ai.strona-obok, #widok-logi.strona-obok { display: block !important; }

/* paski trybów planu (sprawdzanie propozycji AI, wybór opisu na planie) i podgląd zdjęcia w Asystencie pojawiają się płynnie */
.sprawdz-pasek:not([hidden]), #asystentPodglad:not([hidden]) { animation: wchodzi .22s var(--plynnie) both; }

/* start: ostatnią kartą nie był Plan — do przełączenia w start() obszar kart jest niewidoczny (skrypt w <head> index.html), żeby nie mignął Plan */
html[data-start="karta"] main { visibility: hidden; }

/* gesty przesuwają karty poza krawędź ekranu: obszar kart i okno przycinają to, co wystaje — inaczej przeglądarka mobilna uznaje stronę za szerszą,
   poszerza ją (iOS: „oddala”) i przesuwa elementy przyklejone do ekranu (pasek zakładek uciekał w dół w trakcie gestu „wstecz”). clip nie tworzy przewijania. */
main { overflow: hidden; overflow: clip; }
#okno { overflow: hidden; overflow: clip; }

/* ---------- podział ekranu (app.js „podział ekranu”): strona panelu, jedna karta na całym ekranie, matowe szkło przy przeciąganiu, uchwyty przy krawędziach ----------
   panel po lewej albo po prawej planu (w układzie „stos” u dołu albo u góry) — tam, skąd go wyciągnięto; kolejność zmienia się na planie, nie na panelu
   (reguły panelu mają różną szczegółowość: karta elementu, przeciąganie krawędzi) */
@media (min-width: 700px) and (orientation: landscape), (min-width: 1100px) {
  html.panel-prawo #widok-plan { order: -1; }
  html.panel-prawo .rozdzielacz { right: auto; left: calc(var(--przerwa) / -2 - var(--chwyt) / 2); }
  html.panel-prawo body:not([data-widok="plan"]):not(.zmiana-rozmiaru):not(.karta-w-panelu) #panel { animation-name: panelWchodziPrawo; }
  html.panel-prawo[data-kier]::view-transition-new(panel):only-child, html.panel-prawo[data-kier]::view-transition-new(karta):only-child { animation-name: vtPanelWchodziPrawo; }
  html.panel-prawo[data-kier]::view-transition-old(panel):only-child, html.panel-prawo[data-kier]::view-transition-old(karta):only-child { animation-name: vtPanelWychodziPrawo; }
}
@keyframes panelWchodziPrawo { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes vtPanelWchodziPrawo { from { opacity: 0; transform: translateX(16%); } }
@keyframes vtPanelWychodziPrawo { to { opacity: 0; transform: translateX(16%); } }
@media (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  html.panel-gora #widok-plan { order: 3; }
  html.panel-gora .rozdzielacz { top: auto; bottom: calc(var(--przerwa) / -2 - var(--chwyt) / 2); }
  html.panel-gora body:not([data-widok="plan"]):not(.zmiana-rozmiaru):not(.karta-w-panelu) #panel { animation-name: panelWchodziZGory; }
  html.panel-gora[data-kier]::view-transition-new(panel):only-child, html.panel-gora[data-kier]::view-transition-new(karta):only-child { animation-name: vtPanelZGory; }
  html.panel-gora[data-kier]::view-transition-old(panel):only-child, html.panel-gora[data-kier]::view-transition-old(karta):only-child { animation-name: vtPanelWGore; }
}
@keyframes panelWchodziZGory { from { opacity: 0; transform: translateY(-28px); } to { opacity: 1; transform: none; } }
@keyframes vtPanelZGory { from { opacity: 0; transform: translateY(-16%); } }
@keyframes vtPanelWGore { to { opacity: 0; transform: translateY(-16%); } }
/* karta panelu na całym ekranie: plan schowany, panel zajmuje cały obszar kart (krawędzi między kartami nie ma) */
@media (min-width: 700px), (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  html.panel-pelny body:not([data-widok="plan"]) #widok-plan { display: none; }
  html.panel-pelny body:not([data-widok="plan"]) #panel { flex: 1 1 auto; width: auto; height: auto; min-width: 0; min-height: 0; max-width: none; max-height: none; }
  html.panel-pelny body:not([data-widok="plan"]) .rozdzielacz { display: none; }
}
@media (pointer: coarse) {
  .rozdzielacz { --chwyt: 44px; }  /* minimalny cel dotyku wg Apple */
}

/* szkło: dwie części nad obszarem kart z ikoną i nazwą karty (jak podział ekranu na iPadzie, w stylu „Liquid Glass”): przejrzyste, matowe, z jasną krawędzią
   i odblaskiem; część, która po puszczeniu zajmie cały ekran, jest wyraźniejsza, druga przygasa */
#szkloPodzialu { position: fixed; z-index: 30; pointer-events: none; }
body.karta-w-panelu #szkloPodzialu { z-index: 42; }  /* nad kartą elementu w miejscu panelu (40) — wcześniej karta stała w pełnym rozmiarze nad szkłem; kapsuła (45) nad nim */
.szklo-czesc { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; display: grid; place-items: center;
  border-radius: 18px; background-color: color-mix(in srgb, var(--panel) 48%, transparent);
  -webkit-backdrop-filter: blur(26px) saturate(180%); backdrop-filter: blur(26px) saturate(180%); }
/* krawędzie i odblask szkła (osobna warstwa: przenika razem z ikoną, podczas gdy w części narasta rozmycie) */
.szklo-ramka { position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(135deg, color-mix(in srgb, #fff 17%, transparent) 0%, transparent 32%, transparent 68%, color-mix(in srgb, #fff 8%, transparent) 100%);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #fff 15%, transparent), inset 0 1px 0 color-mix(in srgb, #fff 32%, transparent), inset 0 -1px 0 color-mix(in srgb, #000 22%, transparent); }
.szklo-tresc { position: relative; display: flex; flex-direction: column; align-items: center; gap: .6rem; min-width: 0; max-width: 100%; }
.szklo-ikona { position: relative; flex: none; width: 70px; height: 70px; border-radius: 21px; display: grid; place-items: center; color: var(--accent);
  background: color-mix(in srgb, var(--panel2) 72%, transparent); box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 24%, transparent), inset 0 0 0 1px color-mix(in srgb, #fff 10%, transparent), 0 10px 26px #0007;
  transition: transform .26s var(--sprez), opacity .2s ease; }
.szklo-ikona .ik { width: 34px; height: 34px; stroke-width: 1.7; }
.szklo-czesc b { position: relative; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 650; color: var(--txt); transition: opacity .2s ease; }
.szklo-czesc.wygrywa .szklo-ikona { transform: scale(1.1); }
.szklo-czesc.znika .szklo-ikona { transform: scale(.8); opacity: .5; }
.szklo-czesc.znika b { opacity: .4; }
.szklo-szczelina { position: absolute; top: 0; bottom: 0; width: var(--przerwa); background: var(--bg); }
#szkloPodzialu.pion .szklo-szczelina { top: auto; bottom: auto; left: 0; right: 0; width: auto; height: var(--przerwa); }
.szklo-kreska { position: absolute; width: 6px; height: 64px; translate: -50% -50%; border-radius: 3px; background: color-mix(in srgb, #fff 75%, transparent); box-shadow: 0 0 0 1px #0004, 0 2px 10px #0006;
  transition: width .22s var(--sprez), height .22s var(--sprez), background .15s; }
.szklo-kreska.srodek { width: 8px; height: 104px; background: var(--accent); }
#szkloPodzialu.pion .szklo-kreska { width: 64px; height: 6px; }
#szkloPodzialu.pion .szklo-kreska.srodek { width: 104px; height: 8px; }
:root[data-theme="light"] .szklo-czesc { background-color: color-mix(in srgb, #fff 52%, transparent); }
:root[data-theme="light"] .szklo-ramka { box-shadow: inset 0 0 0 1px color-mix(in srgb, #fff 75%, transparent), inset 0 1px 0 #fff, inset 0 -1px 0 color-mix(in srgb, #000 8%, transparent); }
:root[data-theme="light"] .szklo-ikona { background: color-mix(in srgb, #fff 70%, transparent); box-shadow: inset 0 1px 0 #fff, inset 0 0 0 1px color-mix(in srgb, #000 6%, transparent), 0 10px 26px #1b1f2426; }
:root[data-theme="light"] .szklo-kreska { background: color-mix(in srgb, #000 38%, transparent); box-shadow: 0 0 0 1px #fff8; }

/* uchwyty przy krawędziach obszaru kart (tylko jedna karta na całym ekranie): pastylka w odstępie, pole chwytu szersze od niej */
.uchwyt-podzialu { position: fixed; z-index: 15; translate: -50% -50%; width: 40px; height: 128px; min-height: 0; padding: 0; border: none; border-radius: 0; background: none; box-shadow: none;
  cursor: col-resize; touch-action: none; animation: uchwytWchodzi .35s var(--plynnie) both; }
.uchwyt-podzialu::before { content: ""; position: absolute; top: 50%; left: 50%; width: 6px; height: 64px; translate: -50% -50%; border-radius: 3px;
  background: color-mix(in srgb, var(--txt) 30%, transparent); transition: background .15s, height .22s var(--sprez), width .22s var(--sprez); }
.uchwyt-podzialu.pion { width: 128px; height: 40px; cursor: row-resize; }
.uchwyt-podzialu:not([hidden]) { animation: uchwytWchodzi .3s ease both; }  /* pojawia się przy jednej karcie na ekranie — wcześniej wskakiwał */
@keyframes uchwytWchodzi { from { opacity: 0; } }
.uchwyt-podzialu.pion::before { width: 64px; height: 6px; }
@media (hover: hover) { .uchwyt-podzialu:hover::before { background: var(--accent); height: 80px; } .uchwyt-podzialu.pion:hover::before { width: 80px; height: 6px; } }
.uchwyt-podzialu:focus-visible { outline: none; }
.uchwyt-podzialu:focus-visible::before { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }
@keyframes uchwytWchodzi { from { opacity: 0; } }
@media (pointer: coarse) { .uchwyt-podzialu { min-height: 0; width: 44px; height: 140px; } .uchwyt-podzialu.pion { width: 140px; height: 44px; } }

/* ---------- miniatura strony (app.js rysujMape): cała strona z prostokątem widoku, gdy plan jest powiększony — długi plan torowy na telefonie
   bez ciągłego oddalania; przeciągnięcie albo stuknięcie przesuwa widok. Pojawia się i znika płynnie, nie zasłania paska zaznaczania ---------- */
/* na dolnej krawędzi planu, na lewo od menu kapsuły (app.js polozMape: --mapa-dx/dy); w prawym dolnym rogu planu, gdy kapsuła leży nad panelem.
   Przy otwartym menu znika; po 5 s bez ruchu planu gaśnie sama (app.js uspijMape) — spokojniej (0,55 s), niż się pojawia (0,22 s), lekko malejąc w stronę kapsuły */
.plan-mapa { position: absolute; right: 10px; bottom: 10px; z-index: 7; translate: var(--mapa-dx, 0px) var(--mapa-dy, 0px); overflow: hidden; border-radius: 9px; background: var(--plan-bg);
  border: 1px solid var(--line2); box-shadow: 0 4px 16px #0007; opacity: 0; pointer-events: none; transform-origin: 100% 100%;
  transition: opacity .55s cubic-bezier(.4, 0, .2, 1), translate .55s cubic-bezier(.4, 0, .2, 1), scale .55s cubic-bezier(.4, 0, .2, 1); touch-action: none; cursor: pointer; }  /* gaśnie łagodnie od początku do końca */
.plan-mapa.widac { opacity: 1; pointer-events: auto; transition: opacity .22s var(--plynnie), translate .32s var(--sprez), scale .32s var(--sprez); }
.plan-mapa:not(.widac) { translate: var(--mapa-dx, 0px) calc(var(--mapa-dy, 0px) + 6px); scale: .92; }
body:has(#menu[open]) .plan-mapa { opacity: 0; pointer-events: none; }
.plan-mapa img { display: block; width: 100%; height: 100%; object-fit: fill; pointer-events: none; user-select: none; -webkit-user-drag: none; opacity: .92; }
.plan-mapa-okno { position: absolute; border: 2px solid var(--accent); border-radius: 3px; background: color-mix(in srgb, var(--accent) 14%, transparent);
  box-shadow: 0 0 0 999px color-mix(in srgb, #000 28%, transparent); pointer-events: none; }

/* ---------- „stos” (rozłożony Duo i tablet w pionie): nagłówek listy w jednym wierszu — etapy, szukanie, filtry, zaznaczanie i dodawanie obok siebie;
   lista zyskuje ok. 50 px (wcześniej paski panelu zajmowały ok. 165 z 396 px) ---------- */
@media (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) {
  #widok-lista .pasek-listy { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: .5rem; }
  #widok-lista #trybPrzelacznik { margin: 0; display: flex; }
  #widok-lista #trybPrzelacznik .tryby { margin: 0; }
  #widok-lista #licznik { grid-column: 1 / -1; }
  #widok-lista .szukaj-rzad details.filtry > summary span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  #widok-lista .szukaj-rzad details.filtry > summary { padding: 0; min-width: 44px; justify-content: center; }
}

/* ---------- kapsuła kart: treść przewija się pod nią — ostatnie wiersze dają się wysunąć ponad zwiniętą kapsułę; pasek zaznaczania obok niej ---------- */
.tabela-wrap, #widok-szablony, #widok-import, #widok-wiedza, #widok-ai, #widok-praca, #widok-logi { padding-bottom: calc(var(--rezerwa-dol) + .5rem); }
/* ---------- karta „Log” (18.10.2026): rodzaje w kolorach — zmiany zielone, AI fioletowe, błędy czerwone, system niebieski ---------- */
:root { --log-zmiany: var(--green); --log-ai: #a78bfa; --log-bledy: var(--red); --log-system: #60a5fa; --log-wszystkie: var(--dim); }  /* system: niebieski, nie turkus akcentu — obok zielonych zmian był nie do odróżnienia */
:root[data-theme="light"] { --log-ai: #7c4ddb; --log-system: #2563eb; }
.logi-pasek { display: flex; align-items: flex-start; gap: .5rem; margin-bottom: .35rem; }
.logi-pasek .chipy { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; overflow: visible; mask-image: none; -webkit-mask-image: none; }  /* wszystkie rodzaje widoczne naraz, bez przewijania w bok */
.logi-pasek #logiOdswiez { flex: none; }
.chip-btn .log-kropka { display: inline-block; width: 8px; height: 8px; margin-right: .4rem; border-radius: 50%; background: var(--k); }
.logi-pasek .chip-btn.on { background: color-mix(in srgb, var(--k) 18%, var(--panel2)); border-color: var(--k); color: var(--txt); box-shadow: inset 0 0 0 1px var(--k); }
.log-wszystkie { --k: var(--log-wszystkie); } .log-zmiany { --k: var(--log-zmiany); } .log-ai { --k: var(--log-ai); } .log-bledy { --k: var(--log-bledy); } .log-system { --k: var(--log-system); }
.logi-lista { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px; }
.log-wpis { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: .6rem; row-gap: .1rem; padding: .45rem .6rem; border: 1px solid var(--line);
  border-left: 4px solid var(--k); border-radius: var(--r-maly); background: color-mix(in srgb, var(--k) 7%, var(--panel2)); font-size: 13px; }
.log-wpis .log-czas { color: var(--dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.log-wpis .log-tekst { overflow-wrap: anywhere; }
.log-wpis .log-meta { grid-column: 2; color: var(--dim); font-size: 12px; overflow-wrap: anywhere; }
.log-wpis.z-elementem { cursor: pointer; touch-action: manipulation; }
.log-wpis.z-elementem .log-meta::before { content: "⌖ "; color: var(--k); }
.log-wpis.wybrany { border-color: var(--accent); border-left-color: var(--k); box-shadow: 0 0 0 1px var(--accent) inset; }
.log-wpis { transition: border-color .15s ease, box-shadow .15s ease; }
/* pierwsze pokazanie: wpisy wchodzą jak karty AI i Wiedzy — tylko pierwsze 30 (to, co widać; 300 naraz to stracone klatki na telefonie). Przerysowanie
   (odświeżenie, powrót na kartę) bez powtórek (.bez-wejscia), wjeżdżają tylko nowe wpisy (.nowy); zmiana rodzaju — lista wjeżdża od strony przycisku */
.logi-lista > .log-wpis:nth-child(-n+30), .logi-lista > .log-wpis.nowy { animation: wchodzi .26s var(--plynnie) both; }
.logi-lista.anim-przod, #wiedzaLista.anim-przod { animation: widokZPrawej .3s var(--plynnie) both; }  /* także Wiedza po zmianie grupy (app.js initWiedza) */
.logi-lista.anim-tyl, #wiedzaLista.anim-tyl { animation: widokZLewej .3s var(--plynnie) both; }
/* kapsuła przewija się, gdy brakuje wysokości (telefon w poziomie: projekt, %, szukanie, pięć kart i menu nie mieszczą się w 393 px) */
nav.zakladki { max-height: calc(100dvh - 1rem - env(safe-area-inset-top) - env(safe-area-inset-bottom)); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; }
nav.zakladki::-webkit-scrollbar { display: none; }
/* panel zaznaczania: szkło na całą szerokość nad zwiniętą kapsułą — zwinięte menu niczego w nim nie zasłania (rozwija się tylko na stuknięcie) */
.zazn-pasek { right: .3rem; bottom: var(--rezerwa-dol); border-radius: 22px; color: var(--txt); text-shadow: var(--szklo-cien-tekstu);
  background: var(--szklo-blask), var(--szklo-kolor-gesty); backdrop-filter: var(--szklo-filtr); -webkit-backdrop-filter: var(--szklo-filtr);
  border: 1px solid var(--szklo-krawedz); box-shadow: var(--szklo-cien); }
.zazn-pasek button:not(.glowny):not(.on) { background: color-mix(in srgb, var(--txt) 9%, transparent); border-color: var(--szklo-krawedz); color: var(--txt); }
.zazn-pasek button.cichy:not(.glowny) { background: none; border-color: transparent; }
/* zwinięty do jednego wiersza (ok. 56 px nad kapsułą); stuknięcie w liczbę zaznaczonych wysuwa resztę — wysokość płynnie przez wiersz siatki 0fr → 1fr */
.zazn-pasek { gap: 0; }
/* pasek „Zaznacz elementy” na samym dole ekranu (18.10.2026, użytkownik; kapsuły w trybie zaznaczania nie ma): wiersz tytułu zawsze przy dolnej krawędzi,
   reszta (etapy, kroki, przyciski; w „Mark places” pola) wysuwa się NAD nim. W prawym dolnym rogu, w miejscu kapsuły i jej szerokości, stoi nieszkodliwy
   przycisk ⌃ (w „Mark places” — powrót do zaznaczania): stuknięcie tam z przyzwyczajenia nie trafia w „Done”, które kończy zaznaczanie i kasuje wybór */
body.zaznaczanie .zazn-pasek { bottom: 0; }
/* kadrowanie obrazu do wiedzy (18.10.2026): kapsuła schowana jak przy zaznaczaniu, pasek na dole, ramka na środku planu, poza nią przyciemnienie */
body.kadrowanie nav.zakladki { translate: 0 calc(100% + 1.5rem + env(safe-area-inset-bottom)); visibility: hidden; pointer-events: none;
  transition: translate .28s var(--plynnie), visibility 0s .28s; }
body.kadrowanie .kadr-pasek { bottom: 0; }
body.kadrowanie #zaznaczPasek { display: none; }
.kadr-pasek { grid-template-columns: minmax(0, 1fr); }
.kadr-pasek .kadr-tytul { display: grid; gap: .1rem; min-width: 0; }
.kadr-pasek .kadr-tytul b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kadr-pasek .kadr-rzad { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.kadr-pasek #kadrPlan { flex: 1 1 10rem; min-width: 0; max-width: 100%; }
.kadr-ramka { position: absolute; left: 50%; top: 42%; z-index: 9; width: var(--kadr, 160px); height: var(--kadr, 160px); translate: -50% -50%; pointer-events: none;
  border: 2px dashed var(--accent); border-radius: 6px; box-shadow: 0 0 0 9999px color-mix(in srgb, #000 38%, transparent); }
/* ramka wchodzi lekko z góry na plan razem z przyciemnieniem wokół (przezroczystość i skala, układ bez zmian); znika kopią (app.js duchElementu) */
.kadr-ramka:not([hidden]) { animation: kadrRamkaWchodzi .26s var(--plynnie) both; }
@keyframes kadrRamkaWchodzi { from { opacity: 0; transform: scale(1.08); } }
.zazn-pasek .zazn-gora { order: 2; }
.zazn-rog { flex: none; display: grid; place-items: center; width: var(--kw); min-height: 40px; margin-left: .1rem; padding: 0; border: 0; border-radius: 999px;
  background: color-mix(in srgb, var(--txt) 9%, transparent); color: var(--szklo-tekst); box-shadow: none; }
.zazn-rog-tekst { min-width: var(--kw); }
.zazn-pasek .zazn-gora { flex-wrap: nowrap; }
.zazn-pasek .zazn-gora-przyciski { flex-wrap: nowrap; min-width: 0; }
.zazn-rozwin { flex: 1 1 auto; min-width: 0; justify-content: flex-start; gap: .5rem; min-height: 40px; padding: 0 .4rem 0 .15rem; border: 0;
  background: none !important; color: var(--txt); }
.zazn-rozwin strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zazn-strzalka { flex: none; width: 8px; height: 8px; translate: 0 2px; border-right: 2px solid var(--szklo-tekst); border-bottom: 2px solid var(--szklo-tekst);
  rotate: -135deg; transition: rotate .28s var(--plynnie), translate .28s var(--plynnie); }  /* przesunięcie zamiast marginesu: bez przeliczania wiersza */
.zazn-pasek.rozwiniety .zazn-strzalka { rotate: 45deg; translate: 0 -2px; }
.zazn-szybki { min-width: 0; max-width: 11rem; overflow: hidden; }
/* napis w przycisku przycina się wielokropkiem z prawej (przycisk jest kontenerem flex — sam text-overflow na nim nie działał i tekst ucinało z obu stron) */
.zazn-et { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* wąski panel (telefon, Duo złożony, połowa otwartego): zamiast „zaznaczono: 57” pastylka z liczbą — jak licznik na przycisku zaznaczania; zostaje
   miejsce na „✓ etap”, „Gotowe” i ⌃ bez ucinania */
.zazn-liczba { font-variant-numeric: tabular-nums; }
@container zazn (max-width: 459px) {
  .zazn-slowo { display: none; }
  .zazn-liczba { display: inline-block; min-width: 2.4em; padding: .15rem .55rem; border-radius: 999px; background: var(--szklo-wybor); box-shadow: var(--szklo-wybor-cien);
    text-align: center; }
}
/* szeroki panel: wybór etapu jest na planie (przełącznik wszystkich etapów, plan ≥ 560 px) i prowadzi też panel — bez drugiego takiego samego w panelu */
@container zazn (min-width: 560px) { #zaznaczPasek .zazn-tryby { display: none; } }  /* id: mocniej niż późniejsza reguła wyglądu przełącznika */
/* przyciski pod krokami w jednym wierszu (ikona planu pracy spadała do osobnego wiersza na telefonie) */
.zazn-pasek .zazn-przyciski { flex-wrap: nowrap; gap: .25rem; }
.zazn-pasek .zazn-przyciski button { flex: 0 1 auto; min-width: 0; padding: 0 .45rem; white-space: nowrap; }
.zazn-pasek .zazn-przyciski .ikona-maly { flex: none; }
.zazn-wiecej { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .32s var(--plynnie); }
.zazn-pasek.rozwiniety .zazn-wiecej { grid-template-rows: 1fr; }
.zazn-wiecej-tresc { min-height: 0; overflow: hidden; opacity: 0; transition: opacity .18s ease; }
.zazn-pasek.rozwiniety .zazn-wiecej-tresc { opacity: 1; transition: opacity .26s ease .06s; }
.zazn-wiecej-wnetrze { display: grid; gap: .4rem; padding-bottom: .45rem; }  /* nad wierszem tytułu */
.zazn-pasek:not(.rozwiniety) .zazn-wiecej-tresc { visibility: hidden; transition: opacity .18s ease, visibility 0s .32s; }  /* schowane przyciski poza kolejnością Tab */
/* przełącznik etapów i kroki jak w karcie elementu — przejrzyste na szkle; wiele kroków przewija się w panelu */
.zazn-pasek .zazn-tryby { display: flex; width: 100%; margin: 0; background: color-mix(in srgb, var(--txt) 8%, transparent); border-color: var(--szklo-krawedz); }
.zazn-pasek .zazn-tryby button { flex: 1 1 0; min-width: 0; padding: 0 .35rem; overflow: hidden; text-overflow: ellipsis; }
.zazn-pasek .zazn-tryby button:not(.on) { background: none; border-color: transparent; color: var(--szklo-tekst); }
/* wiersze w pełnej wysokości, lista przewija się: krok ma overflow: hidden (minimalna wysokość 0), więc ograniczona wysokością siatka ściskała wiersze
   zamiast przewijać — w poziomie (32svh ≈ 126 px) zostawały puste paski, w pionie wiersze ucięte w połowie (zrzuty z telefonu 18.10.2026) */
.zazn-kroki { display: grid; grid-auto-rows: max-content; align-content: start; gap: 4px; max-height: 32svh; overflow: auto; overscroll-behavior: contain; }
.zazn-krok { margin: 0; padding: .4rem .5rem .4rem .7rem; border: 1px solid color-mix(in srgb, var(--txt) 10%, transparent); border-left-width: 1px; border-radius: 14px;
  background: color-mix(in srgb, var(--txt) 6%, transparent); }
.zazn-krok::before { display: none; }  /* bez paska stanu z lewej (w karcie pokazuje stan jednego elementu; tu stanów jest wiele) */
.zazn-krok .krok-gora { display: flex; align-items: center; gap: .5rem; flex-wrap: nowrap; }
.zazn-krok .krok-gora strong { flex: 1; min-width: 0; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.zazn-krok .znaczek { flex: none; }
/* przełączniki jak w karcie elementu (18.10.2026): z lewej znacznik „uwzględnij”, z prawej wartość (wł. = zrobione); pozycja nieuwzględniona przygasa,
   uwzględniona ma turkusową ramkę — nic nie zapisuje się, dopóki człowiek nie stuknie „Zatwierdź” */
.zazn-uwzgl { flex: none; display: grid; place-items: center; width: 32px; height: 36px; margin-left: -.3rem; cursor: pointer; }
.zazn-uwzgl input { -webkit-appearance: none; appearance: none; display: grid; place-items: center; width: 22px; height: 22px; min-height: 0; margin: 0; padding: 0;
  border-radius: 7px; border: 2px solid color-mix(in srgb, var(--txt) 45%, transparent); background: transparent; cursor: pointer; transition: background-color .16s ease, border-color .16s ease; }
.zazn-uwzgl input:checked { background: var(--accent); border-color: var(--accent); }
.zazn-uwzgl input:checked::after { content: ""; width: 6px; height: 11px; margin-top: -2px; border: solid var(--accent-ink); border-width: 0 2.5px 2.5px 0; rotate: 45deg; }
.zazn-wart { flex: none; min-height: 0; padding: 0; }
.zazn-krok:not(.uwzgl) :is(strong, .znaczek) { opacity: .66; transition: opacity .16s ease; }
.zazn-pasek .zazn-krok.uwzgl { border-color: color-mix(in srgb, var(--accent) 60%, transparent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
/* wiersz pod pozycjami: przy przygotowanych zmianach „Odrzuć zmiany”, po zapisie „↶” (cofnięcie całego zatwierdzenia) — wiersz przycisków niżej się nie rozpycha */
.zazn-odrzuc-rzad { display: none; align-items: center; justify-content: flex-end; gap: .5rem; }
.zazn-odrzuc-rzad .meta { flex: 1 1 auto; min-width: 0; font-size: 12px; }
.zazn-pasek.ma-zmiany .zazn-odrzuc-rzad, .zazn-odrzuc-rzad:has(.zazn-cofnij) { display: flex; }
.zazn-pasek:not(.ma-zmiany) .zazn-tylko-zmiany { display: none; }
.zazn-cofnij { flex: none; }
/* kolumny siatek panelu nie rosną do zawartości (wiersz przycisków z „↶” rozpychał wszystkie pozycje poza ekran) */
.zazn-wiecej, .zazn-wiecej-wnetrze { grid-template-columns: minmax(0, 1fr); }
/* przygotowane zmiany: w nagłówku „Zatwierdź” z liczbą zamiast szybkich „✓ etap”; kropka przy etapach, w których coś czeka */
.zazn-pasek:not(.ma-zmiany) .zazn-zatwierdz, .zazn-pasek.ma-zmiany :is(.zazn-szybki, .zazn-etap-szybki) { display: none; }
.zazn-zatwierdz { flex: none; gap: .4rem; }
.zazn-ile { min-width: 1.4em; padding: 0 .35rem; border-radius: 999px; background: color-mix(in srgb, var(--accent-ink) 22%, transparent); font-variant-numeric: tabular-nums; }
.zazn-tryby button.ma-zmiany::after { content: ""; display: inline-block; width: 6px; height: 6px; margin-left: .35rem; border-radius: 50%; background: var(--accent); vertical-align: middle; }
.zazn-krok .statusy button[data-s="zrobione"]:not(:disabled) { color: var(--szklo-akcent); }
/* pole pytania Asystenta na lewo od kapsuły — tam, gdzie kapsuła leży nad panelem (telefon, „stos”, panel na całym ekranie albo po prawej) */
@media (max-width: 699px), (min-width: 560px) and (max-width: 1099px) and (orientation: portrait) { .asystent-pasek { padding-right: calc(var(--kapsula-w) + .75rem); } }
@media (min-width: 700px) and (orientation: landscape) { html:is(.panel-pelny, .panel-prawo) .asystent-pasek { padding-right: calc(var(--kapsula-w) + .75rem); } }
/* plan pracy: długa lista przewija się (wcześniej koniec listy i „Export image…” mogły być nieosiągalne — widok miał overflow: hidden) */
#widok-praca { overflow: auto; }

/* ===== DUO OTWARTY POZIOMO (18.10.2026, użytkownik): po otwarciu prawa połowa pokazuje DOKŁADNIE to, co złożony telefon — bieżącą kartę w tych samych
   rozmiarach, kapsułę w prawym dolnym rogu i panel zaznaczania — a lewa połowa to więcej funkcji: przy Planie lista elementów, przy Liście / AI / Wiedzy plan.
   Podział dokładnie na zgięciu (brzegi body są równe, więc środek obszaru kart = środek ekranu), bez przeciągania krawędzi i bez jednej karty na całym
   ekranie (app.js MQ_DUO: ten sam warunek). Przy zmianie karty plan i lista zamieniają się połowami — View Transitions przesuwa je na nowe miejsca ===== */
@media (min-width: 700px) and (max-width: 1099px) and (orientation: landscape) and (min-height: 560px) {
  #panel, body:not([data-widok="plan"]) #panel, body.karta-w-panelu[data-widok="plan"] #panel {
    display: flex; flex: 0 0 calc((100% - var(--przerwa)) / 2); width: auto; min-width: 0; max-width: none; animation: none; }
  #widok-plan { display: flex; flex: 1 1 0; min-width: 0; }
  body:not([data-widok="plan"]) #widok-plan { order: -1; }  /* karta (prawa połowa) jak na złożonym telefonie, plan po lewej */
  body[data-widok="plan"] #panel { order: -1; }  /* Plan po prawej, lista elementów po lewej */
  .rozdzielacz { display: none; }
  #zaznaczPasek { left: calc(50% + var(--przerwa) / 2 + .3rem); }  /* panel zaznaczania w prawej połowie — na złożonym telefonie zajmuje szerokość ekranu */
  /* okna jak na złożonym telefonie: arkusz od dołu z uchwytem, ale w prawej połowie — wyśrodkowane menu i „Projekt i plan” leżały na zgięciu.
     Karta elementu przy Planie zostaje w lewej połowie obok planu (body.karta-w-panelu: miejsce panelu, reguły wyżej o większej szczegółowości) */
  dialog:not(#szukajOkno), #okno:not(:has(.okno-szerokie)) {
    width: calc(50vw - var(--przerwa) / 2); max-width: none; height: auto; max-height: 92vh; max-height: 92dvh; margin: auto 0 0 auto;
    border-radius: 18px 18px 0 0; border-right: 1px solid var(--line2); }
  dialog:not(#szukajOkno)[open], #okno:not(:has(.okno-szerokie))[open] { animation-name: arkuszWchodzi; animation-duration: .36s; animation-timing-function: cubic-bezier(.2, .9, .25, 1); }
  .okno-duch:not(.do-przycisku) { animation-name: arkuszWychodzi !important; }
  /* kadrowanie z Wiedzy: plan leży w lewej połowie — pasek „Image for…” pod nim, nie przez zgięcie (18.10.2026: rozciągał się na oba ekrany) */
  body:not([data-widok="plan"]) .kadr-pasek { right: calc(50% + var(--przerwa) / 2 + .3rem); }
  body[data-widok="plan"] .kadr-pasek { left: calc(50% + var(--przerwa) / 2 + .3rem); }
  dialog:not(#szukajOkno)::before { content: ""; position: absolute; top: 6px; left: 50%; width: 40px; height: 4px; margin-left: -20px; border-radius: 2px;
    background: var(--line2); z-index: 5; pointer-events: none; }
  #okno:not(:has(.okno-szerokie)) #oknoTresc { max-height: 92dvh; padding: 1.35rem 1rem calc(1rem + env(safe-area-inset-bottom)); }
}
