:root{
  --bg:#EEF3F0;
  --surface:#FFFFFF;
  --ink:#1F2A24;
  --ink-soft:#4B5A50;
  --line:#D8DFD9;
  --accent-calm:#5B8A72;
  --accent-calm-dim:#E4EEE8;
  --accent-warm:#E8A24C;
  --accent-alert:#B5636B;
  --accent-alert-dim:#F5E7E8;
  --radius-lg:20px;
  --radius-sm:10px;
  --font-display:"Iowan Old Style","Palatino Linotype","Georgia",serif;
  --font-body:-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:"SF Mono","Menlo","Consolas",monospace;
}
*{box-sizing:border-box;}
html,body{margin:0;padding:0;}
body{
  background:var(--bg); color:var(--ink); font-family:var(--font-body);
  min-height:100vh; display:flex; align-items:center; justify-content:center; padding:32px 16px;
}
.app{ width:100%; max-width:720px; }
.steps{ display:flex; gap:8px; justify-content:center; margin-bottom:22px; }
.steps .dot{ width:8px; height:8px; border-radius:50%; background:var(--line); transition:background .3s ease, transform .3s ease; }
.steps .dot.active{ background:var(--accent-calm); transform:scale(1.35); }
.steps .dot.done{ background:var(--accent-calm); opacity:.55; }

.card{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-lg);
  padding:40px 36px; box-shadow:0 1px 2px rgba(31,42,36,.04), 0 8px 24px rgba(31,42,36,.05);
}
h1{ font-family:var(--font-display); font-weight:600; font-size:28px; margin:0 0 6px; letter-spacing:.2px; }
h2{ font-family:var(--font-display); font-weight:600; font-size:20px; margin:0 0 14px; }
p{ line-height:1.55; color:var(--ink-soft); margin:0 0 14px; }
.eyebrow{
  font-family:var(--font-mono); font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent-calm); margin-bottom:10px; display:block;
}
.disclaimer{
  background:var(--accent-calm-dim); border:1px solid var(--accent-calm); border-radius:var(--radius-sm);
  padding:14px 16px; font-size:13.5px; color:var(--ink); margin:18px 0;
}
.disclaimer strong{ color:var(--accent-calm); }
.disclaimer ul{ margin:8px 0 0; padding-left:20px; }
.disclaimer li{ margin-bottom:4px; line-height:1.45; }
.disclaimer li:last-child{ margin-bottom:0; }
.section-mini{ font-size:15px; margin:22px 0 10px; }
.step-list{ margin:0 0 14px; padding-left:0; list-style:none; counter-reset:step; }
.step-list li{ position:relative; padding-left:34px; margin-bottom:10px; line-height:1.5; color:var(--ink-soft); font-size:14px; }
.step-list li::before{
  counter-increment:step; content:counter(step);
  position:absolute; left:0; top:0; width:22px; height:22px; border-radius:50%;
  background:var(--accent-calm-dim); color:var(--accent-calm); font-family:var(--font-mono); font-size:12px; font-weight:700;
  display:flex; align-items:center; justify-content:center;
}
label.check{ display:flex; gap:10px; align-items:flex-start; font-size:14px; color:var(--ink-soft); margin:14px 0; cursor:pointer; }
label.check input{ margin-top:3px; }
/* "Zaznacz wszystkie" (2026-08-23) — wizualnie oddzielona od pojedynczych
   zgód, żeby nie wyglądała jak kolejny (czwarty) punkt regulaminu. */
label.check-all{ font-weight:600; color:var(--ink); padding-bottom:10px; border-bottom:1px solid var(--line); margin-bottom:16px; }
.field-row{ display:flex; gap:16px; margin:18px 0; flex-wrap:wrap; }
.field-row label{ display:flex; flex-direction:column; gap:6px; font-size:13px; color:var(--ink-soft); flex:1; min-width:140px; }
.field-row select, .field-row input{
  font-family:var(--font-body); font-size:14.5px; color:var(--ink); padding:10px 12px;
  border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--surface);
}
.actions{ display:flex; justify-content:flex-end; gap:10px; margin-top:24px; }

/* Ekran wyboru toru (landing) — dwie karty jedna pod drugą, ten sam wąski
   .app co reszta aplikacji, żeby nie łamać spójności layoutu resztą ekranów. */
.track-grid{ display:flex; flex-direction:column; gap:18px; margin:24px 0; }
.track-card{ border:1px solid var(--line); border-radius:var(--radius-lg); padding:22px 24px; }
.track-card h2{ margin-bottom:6px; }
.track-badge{
  display:inline-block; font-size:11px; letter-spacing:.4px; text-transform:uppercase;
  padding:3px 10px; border-radius:999px; font-weight:700; margin-bottom:10px;
  background:var(--accent-calm-dim); color:var(--accent-calm);
}
.track-card .actions{ margin-top:18px; }
/* Priorytet rozwoju (2026-08-23): tor neurodegeneracyjny wyróżniony jako
   główny na stronie startowej, tor autyzmu — skrócona zajawka z linkiem do
   osobnej podstrony (RENDERERS.autismInfo), stąd mniejszy/przygaszony wariant. */
.track-card--featured{ border-color:var(--accent-calm); background:var(--accent-calm-dim); }
.track-badge--featured{ background:var(--accent-calm); color:#fff; }
.track-card--secondary{ padding:18px 22px; }
.track-card--secondary h2{ font-size:17px; }
.track-card--secondary p{ font-size:14px; margin-bottom:0; }

button{
  font-family:var(--font-body); font-size:14.5px; font-weight:600; border-radius:999px; padding:12px 22px;
  border:1px solid transparent; cursor:pointer; transition:transform .15s ease, opacity .15s ease;
}
button:disabled{ opacity:.4; cursor:not-allowed; }
button.primary{ background:var(--ink); color:#fff; }
button.primary:not(:disabled):hover{ transform:translateY(-1px); }
button.ghost{ background:transparent; color:var(--ink-soft); border-color:var(--line); }
button.small{ padding:8px 14px; font-size:13px; }

.stage{
  position:relative; width:100%; aspect-ratio:16/10;
  background:linear-gradient(180deg,#0F1613,#1B2620); border-radius:var(--radius-lg);
  overflow:hidden; margin-bottom:18px;
}

/* Kalibracja/walidacja/zadania: .stage wypełnia praktycznie całe okno
   zamiast wąskiej, wyśrodkowanej karty — większy rozrzut kątów wobec
   kamery przy kalibracji i mniej rozpraszaczy przy obserwacji. Włączane
   przez goTo() wchodząc w te kroki, wyłączane przy raporcie. */
body.fs-active{ padding:0; }
body.fs-active .steps{ display:none; }
body.fs-active .app{ max-width:none; width:100%; height:100vh; display:flex; }
body.fs-active .card{
  width:100%; height:100vh; border-radius:0; box-shadow:none; border:none;
  padding:20px 28px; display:flex; flex-direction:column; justify-content:center;
}
body.fs-active .stage{ flex:1; width:100%; aspect-ratio:auto; min-height:0; margin-bottom:14px; }

/* Kalibracja/walidacja: prawdziwie CAŁY ekran (krawędź do krawędzi), nie
   tylko wypełnienie .card — zbyt mała wysokość .stage utrudniała rozróżnienie
   pionowego ruchu oczu (punkty kalibracji na y={0.1,0.5,0.9} miały wtedy
   mały rozrzut w pikselach). position:fixed liczy się względem viewportu,
   nie względem wyściełanego .card. */
.stage.stage-fullbleed{
  position:fixed; inset:0; width:100%; height:100%; margin:0; border-radius:0; z-index:0;
}
/* 2026-08-29 (na wniosek użytkownika): dawny stały pasek boczny (280px,
   prawie biały — rgba(250,250,248,.97)) USUNIĘTY z dwóch powodów zgłoszonych
   po realnych testach: (1) jasny, stale widoczny panel z jednej strony ekranu
   przez CAŁY czas badania mógł asymetrycznie doświetlać twarz/odbijać się w
   oczach — możliwy współautor niezerowego lightingAsymmetry w realnych
   sesjach; (2) .stage-safe-area była na stałe przesunięta względem
   FIZYCZNEGO ekranu (i kamery), nie tylko względem .stage. Obszar badania
   zajmuje teraz cały ekran (.stage-safe-area = inset:0, patrz niżej), a
   wszystkie komunikaty/przyciski to lekkie nakładki nad ciemnym tłem
   (.hud, .stage-actions-overlay) albo modal na środku pokazywany WYŁĄCZNIE
   w chwili faktycznego przekroczenia progu i zatrzymania sekwencji
   (.env-pause-modal-backdrop niżej) — nigdy stały element UI. */
.stage-safe-area{ position:absolute; inset:0; }
/* Przyciski "pomiń" — lekka nakładka w rogu, nie stały panel. */
.stage-actions-overlay{
  position:absolute; bottom:16px; right:16px; z-index:1;
  display:flex; gap:8px;
}
.stage-actions-overlay button{ font-size:12.5px; padding:8px 14px; }
/* Druga linia w .hud (patrz .hud w sekcji zadań) — WYŁĄCZNIE realny błąd
   silnika (np. brak kamery), nigdy rutynowe liczniki klatek — te ostatnie
   nie są wskazówką do działania dla testera, tylko szum. */
.stage-error-line{
  position:absolute; top:70px; left:12px; right:12px; z-index:1;
  font-family:var(--font-mono); font-size:11px; color:var(--accent-alert);
  white-space:pre-wrap;
}
@media (max-width:700px){
  .stage-actions-overlay{ flex-direction:column; }
}
.stage .zone{ position:absolute; display:flex; align-items:center; justify-content:center; }
.cal-countdown{
  position:absolute; inset:0; z-index:2; display:flex; align-items:center; justify-content:center;
  background:rgba(15,22,19,.35);
}
.cal-countdown-number{
  font-family:var(--font-display); font-size:min(30vw,180px); font-weight:700; color:#fff;
  text-shadow:0 2px 24px rgba(0,0,0,.55);
  animation:cal-countdown-fade 1s ease-out forwards;
}
@keyframes cal-countdown-fade{
  0%{ opacity:0; transform:scale(.6); }
  20%{ opacity:1; transform:scale(1); }
  75%{ opacity:1; transform:scale(1); }
  100%{ opacity:0; transform:scale(1.25); }
}
.fixation-dot{
  position:absolute; width:14px; height:14px; border-radius:50%; background:#fff; opacity:.85;
  box-shadow:0 0 0 6px rgba(255,255,255,.15); transform:translate(-50%,-50%);
}
/* Krzyżyk fiksacji zadania sakadowego — CELOWO inna klasa niż .fixation-dot
   (to jest cel "gdzie patrzeć", nie wskaźnik wykrytego spojrzenia; obie
   kropki są jednocześnie na ekranie w RENDERERS.task_saccade, więc muszą
   wyglądać inaczej, żeby się nie mylić). */
.saccade-fixation-cross{
  position:absolute; left:50%; top:50%; width:20px; height:20px; margin:-10px;
  transition:opacity .15s ease;
}
.saccade-fixation-cross::before, .saccade-fixation-cross::after{
  content:""; position:absolute; background:rgba(255,255,255,.7);
}
.saccade-fixation-cross::before{ left:9px; top:0; width:2px; height:20px; }
.saccade-fixation-cross::after{ left:0; top:9px; width:20px; height:2px; }
.blob{
  width:120px; height:120px; border-radius:44% 56% 60% 40%/48% 44% 56% 52%;
  background:radial-gradient(circle at 35% 30%, var(--accent-warm), #C7742B);
  animation:breathe 2.6s ease-in-out infinite;
}
@keyframes breathe{ 0%,100%{ transform:scale(1) rotate(0deg);} 50%{ transform:scale(1.08) rotate(6deg);} }
.geo{
  width:110px; height:110px; background:conic-gradient(from 0deg, #5B8A72, #8FB79E, #5B8A72);
  animation:spin 6s linear infinite; clip-path:polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
}
@keyframes spin{ to{ transform:rotate(360deg);} }
.face{
  width:96px; height:96px; border-radius:50%; background:#F0D8BC; position:relative;
  transition:transform 1.1s cubic-bezier(.4,0,.2,1);
}
.face::before, .face::after{ content:""; position:absolute; width:12px; height:12px; border-radius:50%; background:#1F2A24; top:38px; }
.face::before{ left:22px; } .face::after{ right:22px; }
.face .mouth{ position:absolute; bottom:22px; left:32px; width:32px; height:8px; border-radius:0 0 16px 16px; background:#B5636B; }
.face.look-left{ transform:rotate(-18deg) translateX(-14px); }
.face.look-right{ transform:rotate(18deg) translateX(14px); }
.target-obj{
  width:64px; height:64px; border-radius:16px;
  background:linear-gradient(135deg,var(--accent-warm),#D98A2E); opacity:.18; transition:opacity .3s ease;
}
.target-obj.armed{ opacity:1; }
.plw-zone-label{
  position:absolute; bottom:8px; left:0; right:0; text-align:center;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:rgba(255,255,255,.4);
}
.face-guide{
  width:120px; height:150px; margin:0 0 6px auto; position:relative;
  background:#0F1613; border-radius:8px; border:1px solid var(--line);
}
/* Miniaturowa wersja pokazywana w środku modala pauzy środowiskowej
   (.env-pause-modal, 2026-08-29 — dawniej w stałym pasku bocznym
   .stage-sidebar, usuniętym wraz z pełnoekranowym obszarem badania), nie
   pływająca nad .stage — siatka 3x3 punktów kalibracji zajmuje WSZYSTKIE
   rogi (x,y ∈ {0.1,0.5,0.9}), więc pływający widget w rogu ekranu zawsze
   zasłaniałby jeden z punktów. */
.face-guide-mini{
  /* Zgłoszenie: 52x64 było za małe, żeby kontrolować pozycję kątem oka
     równolegle z resztą wskazówek. Bazowa szerokość 100% — .env-pause-modal
     .face-guide-mini (wyżej) nadpisuje na stałe 200px, dopasowane do
     szerokości modala. Rozmiar kropki/celu liczony w JS względem
     RZECZYWISTEJ szerokości kontenera (clientWidth), nie sztywnych px — patrz
     diagTimer w app.js — więc skaluje się z tą zmianą automatycznie. */
  width:100%; aspect-ratio:4/5; margin:0; flex-shrink:0;
}
.face-guide-oval{
  position:absolute; top:12%; left:18%; width:64%; height:76%;
  border:2px dashed var(--accent-calm); border-radius:50%; opacity:.6;
}
.face-guide-dot{
  position:absolute; left:50%; top:50%; width:20px; height:20px;
  border-radius:50%; background:var(--accent-warm); opacity:.25; transform:translate(-50%,-50%);
  transition:left .15s linear, top .15s linear, opacity .2s ease;
}
/* Zgłoszenie 2026-08-20: dwa dodatkowe nieruchome okręgi (minimum/maksimum
   rozmiaru) nałożone na TEN SAM widget co owal pozycji dawały w sumie 3
   przerywane okręgi naraz — nieczytelne, użytkownik nie wiedział który
   oznacza co. Zastąpione osobnym, jednoznacznym paskiem odległości
   (.face-distance-*) pod widgetem — patrz updateFaceDistanceMeter() w
   app.js. Owal pozycji (wyżej) i kropka odtąd mówią WYŁĄCZNIE o pozycji
   (czy głowa jest wyśrodkowana), nie o odległości.
*/
.face-distance-meter{ font-size:12px; }
.face-distance-track{
  position:relative; height:14px; border-radius:7px; margin:4px 0 6px;
  background:linear-gradient(to right,
    var(--line) 0%, var(--line) var(--fd-good-start,40%),
    var(--accent-calm-dim) var(--fd-good-start,40%), var(--accent-calm-dim) var(--fd-good-end,60%),
    var(--accent-alert-dim) var(--fd-good-end,60%), var(--accent-alert-dim) 100%);
  border:1px solid var(--line);
}
.face-distance-marker{
  position:absolute; top:-3px; width:4px; height:20px; border-radius:2px;
  background:var(--accent-warm); transform:translateX(-50%);
  transition:left .15s linear, background .2s ease; left:0%;
}
.face-distance-marker.good{ background:var(--accent-calm); }
.face-distance-marker.too-close{ background:var(--accent-alert); }
.face-distance-label{ text-align:center; font-weight:600; color:var(--accent-warm); margin:0; }
.face-distance-label.good{ color:var(--accent-calm); }
.face-distance-label.too-close{ color:var(--accent-alert); }
.face-guide-hint{ font-size:12px; opacity:.75; margin:-4px 0 0; }
#faceGuideStatus{ text-align:right; margin:0 0 10px; }
.plw-figure{ position:relative; width:160px; height:220px; }
.plw-dot{
  position:absolute; width:7px; height:7px; margin:-3.5px; border-radius:50%;
  background:#fff; box-shadow:0 0 4px rgba(255,255,255,.5);
}
.hud{
  position:absolute; top:12px; left:12px; right:12px; display:flex; justify-content:space-between;
  font-family:var(--font-mono); font-size:11px; color:rgba(255,255,255,.55);
}
/* 2026-08-29: na .stage-fullbleed (kalibracja/walidacja) .hud siedzi u
   samej góry viewportu — dokładnie tam, gdzie .lang-switcher (position:
   fixed, top:10px, right:12px). Odsunięcie w dół, tylko dla tego wariantu,
   żeby licznik punktów przestał się nakładać na przełącznik języka. */
.stage.stage-fullbleed > .hud{ top:44px; }
.cal-track{
  position:absolute; width:10px; height:10px; margin:-5px; border-radius:50%; background:rgba(255,255,255,.25);
}
.cal-track.done{ background:var(--accent-calm); }
.cal-track.skipped{ background:rgba(255,255,255,.4); }
.cal-target{
  position:absolute; width:64px; height:64px; margin:-32px;
  border-radius:44% 56% 60% 40%/48% 44% 56% 52%;
  background:radial-gradient(circle at 35% 30%, var(--accent-warm), #C7742B);
  box-shadow:0 0 0 10px rgba(232,162,76,.18);
  animation:cal-grab 2.1s ease-in-out infinite;
  transition:left .5s cubic-bezier(.4,0,.2,1), top .5s cubic-bezier(.4,0,.2,1);
}
@keyframes cal-grab{
  0%{ transform:scale(1) rotate(0deg); }
  50%{ transform:scale(1.22) rotate(180deg); }
  100%{ transform:scale(1) rotate(360deg); }
}

.env-banner{
  position:fixed; top:0; left:0; right:0; z-index:2000; text-align:center;
  padding:10px 16px; background:var(--accent-alert-dim); color:var(--accent-alert);
  font-size:13.5px; font-weight:600; border-bottom:1px solid var(--accent-alert);
}
/* Przełącznik języka — górny prawy róg, nad #envBanner (z-index wyższy),
   żeby nawet gdy baner jest widoczny, przełącznik zostaje dostępny. Mały i
   stały rozmiar celowo — to drugorzędna kontrolka, nie ma konkurować z
   treścią karty. disabled (patrz initLangSwitcher w app.js) na ekranach z
   żywym stanem kamery/timerów (kalibracja/walidacja/zadania) — zmiana tam
   zastosuje się dopiero od następnego ekranu, nie przerywając pomiaru. */
.lang-switcher{
  position:fixed; top:10px; right:12px; z-index:2100;
}
.lang-switcher select{
  font:inherit; font-size:12.5px; font-weight:600; color:var(--ink-soft);
  background:var(--surface); border:1px solid var(--line); border-radius:8px;
  padding:4px 8px; cursor:pointer;
}
.lang-switcher select:disabled{
  opacity:.45; cursor:not-allowed;
}
.app-footer{
  position:fixed; left:0; right:0; bottom:0; z-index:1500;
  text-align:center; padding:10px 16px; font-size:12px; color:var(--ink-soft);
}
.app-footer a{ color:inherit; }
.privacy-note{ font-size:12.5px; color:var(--ink-soft); margin:4px 0 18px; }
.session-id-note{ font-size:12px; color:var(--ink-soft); margin-top:18px; }

/* Ekran wprowadzający przed kalibracją/walidacją — patrz showIntroModal w
   app.js. z-index wyżej niż wszystko inne (fullscreen stage, envBanner,
   langSwitcher), żeby zawsze był na wierzchu niezależnie od tego, co się
   dzieje w tle (kamera/model już się wtedy rozgrzewają). Nieusuwalny poza
   przyciskiem OK — celowo brak zamykania kliknięciem w tło/Escape. */
.intro-modal-backdrop{
  position:fixed; inset:0; z-index:3000; background:rgba(31,42,36,.6);
  display:flex; align-items:center; justify-content:center; padding:24px;
}
.intro-modal{
  background:var(--surface); border-radius:var(--radius-lg); padding:32px 30px;
  max-width:480px; box-shadow:0 12px 40px rgba(0,0,0,.3);
}
.intro-modal h2{ margin-top:0; }
.intro-modal p{ line-height:1.5; }
.intro-modal .actions{ margin-top:22px; text-align:right; }
/* Współdzielone przez treść modala (.intro-modal-body) i sekcję "Na czym to
   polega" na ekranie zgód (.theory-body, patrz RENDERERS.welcome) — oba
   miejsca dostają teraz treść, która może być zwykłym tekstem ALBO własnym
   <p>/<ul><li> (2026-08-23, na żądanie testerów: długie bloki tekstu były
   mało czytelne). Kolor/line-height ustawione wprost na kontenerze, nie
   przez globalną regułę `p`, żeby zwykły tekst (bez własnego <p>) wyglądał
   identycznie jak wcześniej. */
.intro-modal-body, .theory-body{ line-height:1.55; color:var(--ink-soft); }
.intro-modal-body p, .theory-body p{ margin:0 0 12px; }
.intro-modal-body p:last-child, .theory-body p:last-child{ margin-bottom:0; }
.intro-modal-body ul, .theory-body ul{ margin:0 0 12px; padding-left:20px; }
.intro-modal-body li, .theory-body li{ margin-bottom:6px; line-height:1.5; }
.intro-modal-body li:last-child, .theory-body li:last-child{ margin-bottom:0; }
/* Chowana w trybie fullscreen (kalibracja/walidacja/zadania), żeby nie
   nachodzić na scenę pomiaru — patrz komentarz w index.html. */
body.fs-active .app-footer{ display:none; }
.env-warning{
  color:var(--accent-alert);
}
/* Modal pauzy środowiskowej (2026-08-29, patrz komentarz przy .stage-
   safe-area powyżej) — pojawia się WYŁĄCZNIE gdy kalibracja/walidacja
   faktycznie się zatrzyma (po debounce, nie na pojedynczy zły odczyt),
   znika automatycznie po powrocie do dobrych warunków. Reużywa .intro-modal
   (ta sama spokojna biel/ciemny tekst co ekrany "Zanim zaczniemy") —
   ŚWIADOMIE bez czerwieni/koloru alertu na treści komunikatu, na wyraźną
   prośbę użytkownika: nieagresywne pod względem jasności i kolorystyki,
   mimo że informuje o przekroczonym progu. Niższy z-index niż
   .intro-modal-backdrop (3000) — te dwa nie pojawiają się jednak razem,
   pauza jest zablokowana dopóki sequenceStarted nie jest true (patrz JS). */
.env-pause-modal-backdrop{
  position:fixed; inset:0; z-index:2200; background:rgba(31,42,36,.45);
  display:flex; align-items:center; justify-content:center; padding:24px;
}
.env-pause-modal{ text-align:center; }
.env-pause-modal .face-guide-mini{ width:200px; margin:16px auto 0; }
.env-pause-modal .face-distance-meter{ max-width:280px; margin:10px auto 0; text-align:left; }
.env-pause-modal .envPause-resumeHint{ font-size:12.5px; color:var(--ink-soft); margin:14px 0 0; }
.env-video-wrap{
  position:relative; width:220px; height:165px; margin:0 auto 14px;
  border-radius:12px; overflow:hidden; background:#000;
}
#envVideoPreview{ width:100%; height:100%; object-fit:cover; transform:scaleX(-1); }
.env-video-oval{
  position:absolute; top:8%; left:20%; width:60%; height:84%;
  border:2px dashed var(--accent-calm); border-radius:50%; opacity:.7; pointer-events:none;
}
.env-checklist{ list-style:none; margin:0 0 14px; padding:0; display:flex; flex-direction:column; gap:6px; }
.env-checklist li{ display:flex; align-items:center; gap:8px; font-size:13.5px; color:var(--ink-soft); }
.env-check-dot{ width:10px; height:10px; border-radius:50%; background:var(--line); flex:none; }
.env-checklist li.ok{ color:var(--ink); }
.env-checklist li.ok .env-check-dot{ background:var(--accent-calm); }
.env-checklist li.fail{ color:var(--accent-alert); }
.env-checklist li.fail .env-check-dot{ background:var(--accent-alert); }

.report-toggle{ display:flex; gap:8px; margin-bottom:18px; }
.report-toggle button{ flex:1; }
.report-toggle button.active{ background:var(--ink); color:#fff; }
.report-toggle button:not(.active){ background:var(--accent-calm-dim); color:var(--ink); border-color:transparent; }

.task-result{ border:1px solid var(--line); border-radius:var(--radius-sm); padding:18px 20px; margin-bottom:14px; }
.task-result.flag{ border-color:var(--accent-alert); background:var(--accent-alert-dim); }
.task-result.inconclusive{ border-color:var(--line); background:#FAFAF8; }
.task-result .label-row{ display:flex; justify-content:space-between; align-items:center; margin-bottom:6px; }
.task-result h3{ font-family:var(--font-display); font-size:16px; margin:0; }
.tag{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px; background:var(--accent-calm); color:#fff;
}
.tag.alert{ background:var(--accent-alert); }
.tag.muted{ background:var(--line); color:var(--ink-soft); }
pre.metrics{
  font-family:var(--font-mono); font-size:11.5px; background:#F4F6F4; padding:12px 14px; border-radius:8px;
  overflow-x:auto; color:var(--ink-soft); margin:8px 0 0;
}
.final-note{ font-size:13.5px; color:var(--ink-soft); border-top:1px dashed var(--line); padding-top:16px; margin-top:8px; }
.hidden{ display:none !important; }
.qa-line{ font-family:var(--font-mono); font-size:11px; color:var(--ink-soft); }
.qa-line button{ margin-left:8px; vertical-align:middle; }
.load-error{ font-size:13px; color:var(--accent-alert); }
.print-only{ display:none; }

@media print{
  body{ background:#fff; padding:0; align-items:flex-start; min-height:0; }
  .steps, .report-toggle, .actions{ display:none !important; }
  .card{ box-shadow:none; border:none; padding:0; max-width:none; }
  .print-only{ display:block; font-size:12px; color:var(--ink-soft); margin:-4px 0 14px; }
  .task-result{ break-inside:avoid; }
  pre.metrics{ white-space:pre-wrap; word-break:break-word; }
}
