/* Paleta, rewizja 19.09. Trzy rzeczy zmienily sie wzgledem pierwszej wersji.

   1. Tla byly sine i lezaly blisko siebie (#EBF2F7 obok #DCE8F1), wiec
      sasiadujace sekcje zlewaly sie w jedna szara plame. Teraz papier jest
      jasniejszy i chlodno-neutralny, a rytm strony robi CIEMNA sekcja
      (--noc), nie kolejny odcien bladego blekitu.
   2. Tekst pomocniczy miał kontrast 4,3:1 na tle papieru, czyli tyle, ile
      WCAG wymaga w minimum dla duzego tekstu, a stal w nim tekst 13 px.
      --cichy jest ciemniejszy: 6,4:1.
   3. Lazur linkow byl wyprany. Ciemniejszy wariant daje 7:1 na papierze i
      dopiero teraz wyglada na kolor, a nie na zblakniete granatowe.

   Semantyka pozostalych kolorow jest zajeta i nie wolno jej uzywac
   dekoracyjnie: zielen znaczy "najlepsza wartosc w kolumnie", bursztyn
   "ostrzezenie", czerwien "blokada" (D22). Dlatego kolorem marki zostaje
   lazur, jedyny wolny.

   4. Scalenie palety (rewizja 20.09). Glowna.css mial 39 zywych wartosci
      szesnastkowych poza :root, wpisywanych recznie zamiast przez zmienna.
      Bialy (#FFF/#FFFFFF) to zawsze --karta zapisana inaczej. Cztery bardzo
      bliskie szarosci (#93AABA, #9FB6C4, #8FAEC4, #7A93A4), wszystkie tekst
      pomocniczy na ciemnym tle, scalily sie w --noc-cichy: kontrast najnizszej
      z nich na wlasciwym tle to bylo 5,23:1, po scaleniu do wartosci
      #93AABA wszystkie miejsca stoja miedzy 6,96:1 a 7,97:1, wiec zaden
      próg WCAG nie ucierpial. Reszta kolorow ciemnej sekcji strony glownej
      (--noc i --atrament) dostala nazwy zamiast zostac anonimowymi hexami:
      --noc-tekst i --noc-tekst-2 to dwa stopnie jasnosci tekstu opisowego,
      --noc-lazur i --noc-lazur-2 to jasny lazur w dwoch sekcjach o lekko
      innym tle (0C1B26 i 0E1F2B) - wartosci ROZNE, bo ujednolicenie
      zmienioby wyglad, ktorego to porzadkowanie nie ma prawa ruszac.
      --noc-uwaga i --noc-stop to jasniejsze odpowiedniki --uwaga i --stop,
      czytelne na ciemnym tle. --noc-kreska to ramka karty w ciemnej sekcji
      (#2F4757): za daleko od --noc i --noc-2 (roznica do 19 procent na
      kanale), zeby uzyc istniejacego tokenu. Tlo tej samej karty (#16232C)
      odwrotnie, bylo o mniej niz 4 procent od --noc, wiec dostalo istniejacy
      token zamiast piatego odcienia czerni.

   5. Trzecia paleta (rewizja 20.09, druga czesc). naglowek.js i stopka.js
      wstrzykuja wlasny <style> jako string i mialy 39 hexow wobec 32 uzyc
      var(), rownolegle do :root i do palety glowna.css. --akcent to kolor
      obramowania fokusu w polu wyszukiwania naglowka: rozni sie od --lazur
      o 31 procent na kanale niebieskim, wiec to NIE jest zapomniany --lazur,
      tylko osobny, celowo inny odcien - dostaje wlasny token zamiast
      podmiany na --lazur, ktora zmieniloby wyglad. --tlo (#F7F9FB) w tych
      samych plikach byl o mniej niz 3 procent od --papier, wiec zniknal:
      wszystkie jego uzycia wskazuja teraz na --papier. --noc-kreska-2
      i --noc-kreska-3 to trzeci i czwarty odcien ramki na ciemnym tle
      stopki (osobne od --noc-kreska z hp-para-karta): rozstrzelenie miedzy
      wszystkimi trzema siega kilkunastu procent na kanale, wiec zadna para
      nie mogla dzielic tokenu bez zmiany wygladu. */
:root{
  --papier:#F1F5F8; --papier-2:#E3ECF3; --karta:#FFFFFF;
  --noc:#0C1B26; --noc-2:#14303F;
  --kreska:#D3DFE8; --kreska-mocna:#0E1F2B;
  --atrament:#0E1F2B; --atrament-2:#2C4254; --cichy:#456079;
  --lazur:#0B5486; --lazur-tlo:#DDEBF6;
  --zielen:#0C7358; --zielen-tlo:#D7EDE5;
  --uwaga:#8A5C07; --uwaga-tlo:#F3E7CE;
  --stop:#A63A2E; --stop-tlo:#F7E1DD;
  --noc-kreska:#2F4757; --noc-kreska-2:#22384A; --noc-kreska-3:#3C566A;
  --noc-tekst:#EAF1F6; --noc-tekst-2:#C6D8E4; --noc-cichy:#93AABA;
  --noc-lazur:#7FC5EA; --noc-lazur-2:#5FC0E6;
  --noc-uwaga:#F2C25B; --noc-stop:#E8776B;
  --akcent:#1C7ED6;
  --font:"Archivo",system-ui,-apple-system,sans-serif;
  --dane:"IBM Plex Mono",ui-monospace,Menlo,monospace;
  --r:4px;
  /* Kolory chipow celu (D35, karta "Jeden preparat na kilka celow naraz",
     serwer/cele.py::_kompleksowe): jedna para tlo/tekst na kazdy z dziesieciu
     kodow celu z /api/cele. Trzy pierwsze (koncentracja-i-pamiec,
     energia-i-zmeczenie, stres-i-napiecie) to dokladnie te same hexy co w
     zaakceptowanej makiecie makieta/cele-kompleksowe.html -- nie przeliczone
     na nowo. Pozostale siedem dobrane tym samym wzorem HSL (tlo: nasycenie
     42,9%, jasnosc 93,1%; tekst: nasycenie 60%, jasnosc 45,1%, poza
     odchudzanie: 43% -- przy 45,1% kontrast wzgledem wlasnego tla spadal
     ponizej 4,5:1), z odstepem hue min. 10 stopni od siebie i od pasm juz
     zajetych znaczeniowo: ~0-15 (--stop, blokada), ~30-50 (--uwaga,
     ostrzezenie), ~150-170 (--zielen, najlepsza wartosc), ~205-215 (--lazur,
     marka). Kontrast tekstu (WCAG): wszystkie dziesiec par miedzy 4,67:1 a
     9,30:1 na bialej karcie, miedzy 4,51:1 a 7,55:1 na wlasnym tle chipu --
     nad progiem 4,5:1 z zapasem. Tabela w raporcie wdrozenia D35. */
  --cel-koncentracja-i-pamiec-tlo:#E7E6F5; --cel-koncentracja-i-pamiec-tekst:#392EB8;
  --cel-odpornosc-tlo:#E6EBF5; --cel-odpornosc-tekst:#2E5CB8;
  --cel-budowa-masy-tlo:#E6E8F5; --cel-budowa-masy-tekst:#2E40B8;
  --cel-sen-i-zasypianie-tlo:#EBE6F5; --cel-sen-i-zasypianie-tekst:#612EB8;
  --cel-jelita-i-trawienie-tlo:#EFE6F5; --cel-jelita-i-trawienie-tekst:#7F2EB8;
  --cel-energia-i-zmeczenie-tlo:#F1E6F5; --cel-energia-i-zmeczenie-tekst:#952EB8;
  --cel-odchudzanie-tlo:#F5E6F4; --cel-odchudzanie-tekst:#AF2CA4;
  --cel-stres-i-napiecie-tlo:#F5E6EE; --cel-stres-i-napiecie-tekst:#B82E7E;
  --cel-wlosy-i-paznokcie-tlo:#F5E6EC; --cel-wlosy-i-paznokcie-tekst:#B82E63;
  --cel-libido-tlo:#F5E6E9; --cel-libido-tekst:#B82E47;
}
*{box-sizing:border-box}
/* Kazda klasa z wlasnym display (grid, flex, block) bije wbudowane [hidden]
   z arkusza przegladarki, bo ma wyzsza specyficznosc. Bez tej reguly element
   z atrybutem hidden zostaje widoczny: tak przestal dzialac przycisk "Pokaz
   jeszcze" na ekranie /substancje, bo .wst-siatka ma display:grid, wiec ukryte
   kafle staly na ekranie od poczatku, a klikniecie usuwalo tylko przycisk.
   Jedna regula zamiast dopisywania .klasa[hidden] przy kazdej nowej klasie. */
[hidden]{display:none !important}
body{margin:0;background:var(--papier);color:var(--atrament);font-family:var(--font);
  font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums}
h1,h2,h3{margin:0;font-stretch:100%;font-weight:700;letter-spacing:-.017em;line-height:1.14;text-wrap:balance}
/* h1 osobno stron podrzednych mial cztery rozne wartosci wpisane recznie
   (metoda, osoba, substancje, i reszta domyslna 24px z .head-* h1), zadna nie
   skalowala sie z reszta. Jedna regula clamp zamiast tego, odtwarzajaca
   dzialajaca pare 1.4rem/1.7rem, ktora miala juz karta substancji. Wyjatek:
   hero strony glownej (.hp-hero-in h1 w glowna.css), z zalozenia wiekszy. */
h1{font-size:clamp(1.4rem,1.289rem + 0.457vw,1.7rem)}

/* Zaden font w fonty.css nie ma odmiany pochylej (kazdy @font-face ma
   font-style:normal), wiec kazde <i> z tekstem dostawaloby kursywe
   syntetyczna: przegladarka pochyla litery prostego kroju mechanicznie,
   co psuje ksztalty znakow, najmocniej przy polskich ogonkach. Puste <i>
   uzywane jako ozdobniki (kropka, kwadracik legendy) to nie dotyczy, bo bez
   tekstu font-style nie ma znaczenia wizualnego. */
i{font-style:normal}

/* Drugi czlon naglowka ("Porownaj suplementy po tym, ILE SUBSTANCJI NAPRAWDE
   DOSTAJESZ") byl w <i> i mial ten sam problem. Zamiast dogrywac plik
   kursywy robimy kontrast tym, co font ma naprawde: mniejsza waga i kolor.
   Czyta sie spokojniej, a akcent pada na to samo slowo co wczesniej. */
h1 i,h2 i,h3 i{font-weight:400;color:var(--lazur)}

/* Elementy formularzowe nie dziedzicza kroju po body z arkusza przegladarki,
   dopoki sie im tego nie kaze wprost: bez tej reguly kazdy nowy formularz
   dostaje domyslny font przegladarki (Arial) zamiast Archivo. */
button,input,select,textarea{font-family:inherit}

.num{font-family:var(--dane);letter-spacing:-.03em}
.eyebrow{font-size:.64rem;text-transform:uppercase;letter-spacing:.16em;font-weight:600;color:var(--cichy)}
.eyebrow a{color:inherit;text-decoration:underline;text-decoration-color:var(--kreska)}
.eyebrow a:hover,.eyebrow a:focus-visible{color:var(--lazur);text-decoration-color:currentColor}

/* Skip link do wynikow na /produkty (kontroler 26.09): panel filtrow ma
   kilkadziesiat pol wyboru PRZED lista wynikow w DOM, wiec bez tego linku
   klawiatura musi przejsc caly panel, zeby dotrzec do pierwszego chipa albo
   pierwszego produktu. Standardowy wzorzec: niewidoczny, dopoki nie dostanie
   fokusu (Tab jako pierwszy element strony), wtedy wyskakuje nad naglowek
   (z-index wyzszy niz sticky header). */
.pomin-do-wynikow{position:absolute;top:-9999px;left:8px;z-index:30;
  padding:10px 16px;background:var(--atrament);color:var(--karta);
  border-radius:var(--r);font-weight:600;font-size:.86rem;text-decoration:none}
.pomin-do-wynikow:focus{top:8px}

header{background:var(--karta);border-bottom:1px solid var(--kreska);position:sticky;top:0;z-index:20}
.hdr{max-width:1240px;margin:0 auto;padding:0 20px;height:62px;display:flex;align-items:center;gap:22px}
/* Znak jest obrazem z wlasnym tlem i wlasnym promieniem, wiec kafelek pod nim
   musi byc przezroczysty: dwa tla dawaly widoczna obwodke przy 30 px. */
.znak{width:30px;height:30px;flex:0 0 auto;display:block}
.znak img{display:block;width:100%;height:100%}
.znak{text-decoration:none}
/* Pasek zapasowy, widoczny zanim naglowek.js podmieni naglowek: znak stoi
   tu z tego samego powodu co w pasku wlasciwym, zeby pierwsza klatka nie
   pokazywala serwisu bez marki. */
.marka a{color:inherit;text-decoration:none;display:inline-flex;align-items:center;gap:8px}
.marka a img{display:block;border-radius:var(--r)}
.marka b{display:block;font-size:.92rem;font-stretch:112%;letter-spacing:-.02em;line-height:1.1}
.marka small{display:block;font-family:var(--dane);font-size:.57rem;color:var(--cichy)}
.hdr-stan{margin-left:auto;font-family:var(--dane);font-size:.68rem;color:var(--cichy);text-align:right}

main{max-width:1240px;margin:0 auto;padding:26px 20px 70px}

.szukajka{margin-bottom:18px}
.szukajka input[type=search]{width:100%;padding:11px 14px;border:1px solid var(--kreska);
  border-radius:var(--r);background:var(--karta);font:inherit;color:var(--atrament)}
.szukajka input:focus-visible{outline:2px solid var(--lazur);outline-offset:1px}
.przelacznik{display:inline-flex;align-items:center;gap:8px;padding:10px 13px;border:1px solid var(--kreska);
  border-radius:var(--r);background:var(--karta);font-size:.86rem;cursor:pointer;user-select:none}
.przelacznik input{accent-color:var(--lazur);width:16px;height:16px}

.pasek{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;
  padding-bottom:10px;border-bottom:1px solid var(--kreska-mocna);margin-bottom:16px}
.pasek .ile{font-family:var(--dane);font-size:.84rem;color:var(--cichy)}
.pasek .ile b{color:var(--atrament);font-weight:600}
.tbar-sort{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.seg{display:inline-flex;border:1px solid var(--kreska);border-radius:var(--r);overflow:hidden;background:var(--karta)}
.seg button{padding:7px 14px;font:inherit;font-size:.81rem;color:var(--cichy);border:0;border-right:1px solid var(--kreska);
  background:none;cursor:pointer}
.seg button:last-child{border-right:0}
.seg button[aria-pressed="true"]{background:var(--atrament);color:var(--karta);font-weight:600}
/* U21: odwrocenie kierunku aktywnej kolumny sortowania. Osobny przycisk
   zamiast trzeciego stanu w .seg, bo kierunek dotyczy KAZDEJ z trzech
   kolumn naraz, nie jest czwarta opcja rownorzedna z nimi. */
.sort-kierunek{width:30px;height:30px;flex:0 0 auto;border:1px solid var(--kreska);border-radius:var(--r);
  background:var(--karta);color:var(--atrament-2);font-size:.9rem;cursor:pointer;line-height:1}
.sort-kierunek:hover{border-color:var(--atrament);color:var(--atrament)}
.sort-kierunek:focus-visible{outline:2px solid var(--lazur);outline-offset:1px}

/* Panel filtrow reczniejszych, ekran listy. Skladniki dodane to jedyna grupa
   z danymi dzis (forma_id i wariant.postac sa puste w katalogu), wiec panel
   ma jedna sekcje zamiast trzech jak w makiecie: pusty slot nie wchodzi. */
.filtr-panel{margin-bottom:16px;border:1px solid var(--kreska);border-radius:var(--r);background:var(--karta)}
/* Wewnatrz panelu z lewej (.pfl-panel) filtr skladnikow ma juz wlasna karte
   z ramka i naglowkiem rozwijanym, wiec nie dostaje drugiej ramki od
   .pfl-sekcja, tylko odstep od gap kolumny zamiast wlasnego margin. */
.pfl-panel .filtr-panel{margin-bottom:0}
.filtr-panel[hidden]{display:none}
.filtr-glowa{display:flex;justify-content:space-between;align-items:center;gap:16px;width:100%;
  padding:13px 16px;text-align:left;font:inherit;background:none;border:0;cursor:pointer;color:inherit}
.filtr-glowa h2{font-size:.94rem}
.filtr-lead{display:block;font-size:.76rem;color:var(--cichy);margin-top:3px;font-weight:400}
.filtr-stan{display:flex;align-items:center;gap:7px;flex-shrink:0}
.filtr-stan .num{font-size:1.05rem;font-weight:600}
.filtr-stan .u{font-family:var(--dane);font-size:.66rem;color:var(--cichy)}
.filtr-strzalka{transition:transform .2s;display:inline-block}
.filtr-glowa[aria-expanded="true"] .filtr-strzalka{transform:rotate(180deg)}
.filtr-cialo{padding:2px 16px 16px;border-top:1px solid var(--kreska)}
.filtr-cialo[hidden]{display:none}
.filtr-grupa-dodatki{padding-top:13px}
.filtr-chipy{display:flex;flex-wrap:wrap;gap:6px}
.filtr-chip{display:inline-flex;flex-direction:column;align-items:flex-start;gap:2px;padding:6px 10px;
  border-radius:var(--r);font:inherit;font-size:.79rem;border:1px solid var(--kreska);background:var(--papier);
  color:var(--atrament-2);cursor:pointer}
.filtr-chip:hover{border-color:var(--atrament)}
.filtr-chip .num{font-family:var(--dane);font-size:.72rem;color:var(--cichy)}
.filtr-chip[aria-pressed="true"]{background:var(--stop-tlo);border-color:var(--stop);color:var(--stop)}
.filtr-chip[aria-pressed="true"] .num{color:var(--stop)}
.filtr-chip .ukryte{font-size:.68rem;color:var(--uwaga);font-weight:600}
.filtr-chip[aria-pressed="true"] .ukryte{color:var(--stop)}
.filtr-uwaga{margin:8px 0 0;font-size:.73rem;color:var(--cichy);line-height:1.4}
.filtr-licznik{padding:10px 16px;border-top:1px solid var(--kreska);font-size:.82rem;color:var(--atrament-2)}
.filtr-licznik b{color:var(--stop);font-weight:600}

.siatka{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:12px}
.kafel{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  display:flex;flex-direction:column;text-align:left;padding:0;font:inherit;color:inherit;
  cursor:pointer;transition:border-color .16s,transform .16s}
.kafel:hover{border-color:var(--atrament);transform:translateY(-2px)}
.kafel:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
/* zdjecia ze sklepow sa kwadratowe, wiec kafel tez: przy proporcji 4/3
   opakowanie przycinalo sie u dolu razem z gramatura na etykiecie */
.kafel-obraz{aspect-ratio:1/1;background:var(--karta);display:grid;place-items:center;
  border-bottom:1px solid var(--kreska);overflow:hidden;padding:10px}
.kafel-obraz img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;
  mix-blend-mode:multiply}
.kafel-obraz .brak{font-family:var(--dane);font-size:.6rem;color:var(--cichy);letter-spacing:.06em;
  text-transform:uppercase;padding:8px;text-align:center}
.kafel-tresc{padding:12px 13px 13px;display:flex;flex-direction:column;flex:1;gap:5px;min-width:0}
.kafel .marka-p{font-family:var(--dane);font-size:.62rem;text-transform:uppercase;letter-spacing:.06em;color:var(--cichy)}
.kafel .nazwa{font-size:.9rem;font-weight:600;font-stretch:104%;letter-spacing:-.01em;line-height:1.3}
.kafel .opak{font-family:var(--dane);font-size:.68rem;color:var(--atrament-2)}
/* Liczba skladnikow: informacja, po ktorej ludzie wybieraja preparat zlozony
   albo jednoskladnikowy, wiec stoi na kaflu, nie dopiero na karcie produktu. */
.kafel .skladnikow{font-family:var(--dane);font-size:.68rem;color:var(--cichy)}
.kafel .stopka{margin-top:auto;padding-top:9px;display:flex;justify-content:space-between;align-items:flex-end;gap:8px}
.kafel .cena{font-family:var(--dane);font-size:1.02rem;font-weight:600;letter-spacing:-.04em}
.kafel .cena small{font-size:.62rem;color:var(--cichy);font-weight:400;display:block;letter-spacing:0}
.kafel .cena.brak{color:var(--cichy);font-size:.78rem;font-weight:400}

/* Zdjecia kafli byly za duze na liscie produktow pod tabela porownawcza
   (polecenie wlasciciela 18.09): kwadrat 1:1 nie mieszcil kilku produktow w
   jednym rzucie oka. Scoped do sekcji produktow (karta substancji i krok 4
   wywiadu), zeby /produkty zachowaly dotychczasowy kwadrat. */
.cel-produkty .kafel-obraz{aspect-ratio:16/9}
.cel-produkty .siatka{margin-top:18px}

.tag{display:inline-block;padding:2px 7px;border-radius:var(--r);font-size:.7rem;font-weight:600;
  white-space:nowrap;font-stretch:100%}
.tag.warnt{background:var(--uwaga-tlo);color:var(--uwaga)}
.tag.fakt{background:var(--papier-2);color:var(--atrament-2);font-weight:500}

/* Tabela porownawcza (D22 w notes/DECYZJE.md): rdzen porownywarki, wspolna
   dla karty substancji i konca wywiadu (statyczne/tabela-porownania.js).
   Zielone podswietlenie dostaje DOKLADNIE dwie kolumny (zawartosc na porcje,
   zl za 1000 mg) i nigdy sama cena opakowania - patrz D22 punkt 3. */
.legenda-koloru{display:flex;gap:9px;align-items:flex-start;margin:0 0 12px;font-size:.79rem;
  color:var(--cichy);max-width:78ch;line-height:1.5}
.legenda-koloru i{flex:0 0 auto;width:12px;height:12px;border-radius:var(--r);margin-top:3px;
  background:var(--zielen-tlo);box-shadow:inset 3px 0 0 var(--zielen)}
.tabela-subst td.naj{background:var(--zielen-tlo);box-shadow:inset 3px 0 0 var(--zielen)}
.tabela-subst td.naj .num{color:var(--zielen)}
.etykieta-naj{display:block;font-family:var(--dane);font-size:.62rem;text-transform:uppercase;
  letter-spacing:.05em;color:var(--zielen);font-weight:600;margin-top:2px}
.tabela-subst .tr-dzial td{background:var(--papier-2);font-family:var(--dane);font-size:.62rem;
  text-transform:uppercase;letter-spacing:.1em;color:var(--cichy);font-weight:600}
/* Blad karty (dawka o rzad wielkosci za wysoka) dostaje bursztyn, nie
   czerwien: to sygnal jakosci danych, nie zagrozenie bezpieczenstwa, ktore
   D22 rezerwuje wylacznie dla wykluczen. */
.tabela-subst .tr-dzial-blad td{background:var(--uwaga-tlo);color:var(--uwaga)}
.tabela-subst .pnazwa{font-weight:600;line-height:1.3}
.tabela-subst .pmarka{font-family:var(--dane);font-size:.66rem;color:var(--cichy);
  text-transform:uppercase;letter-spacing:.05em}
.tabela-subst .otworz-wiersz{all:unset;cursor:pointer;display:block}
.tabela-subst .otworz-wiersz:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}

/* Kolumny wezsze (zlecenie Krzysztofa 18.09): table-layout:fixed trzyma sie
   proporcji z <colgroup> zamiast rozciagac kazda kolumne do najdluzszej
   tresci, wiec osiem kolumn miesci sie na 1280px bez przewijania w poziomie.
   width:100% z gornym pulapem zamiast sztywnego px: na szerokim ekranie
   (priorytet desktop, ustalenie 18.09) tabela wypelnia dostepne miejsce, ale
   nie rozjezdza sie w nieskonczonosc na bardzo szerokich monitorach.
   min-width rowny sumie kolumn z colgroup: ponizej tej szerokosci przegladarka
   i tak by je scisnela do nieczytelnosci, wiec od tego progu .tscroll
   przejmuje przewijanie w poziomie (dotyczy telefonow, patrz notatka nizej). */
.tabela-subst{table-layout:fixed;width:100%;min-width:904px;max-width:1120px}
.tabela-subst .col-produkt{width:228px}
.tabela-subst .col-forma{width:96px}
.tabela-subst .col-zawartosc{width:130px}
.tabela-subst .col-porcja{width:96px}
.tabela-subst .col-dni{width:88px}
.tabela-subst .col-cena{width:88px}
.tabela-subst .col-koszt{width:82px}
.tabela-subst .col-cena1000{width:96px}
/* Padding scisniejszy niz w generycznej regule table/td (styl.css wyzej):
   przy osmiu kolumnach w wezszej tabeli oszczedza tyle miejsca, ile jedna
   dodatkowa kolumna. Liczby zostaja tej samej wielkosci co reszta serwisu -
   scisniety jest odstep, nie czcionka (zakaz z briefu 18.09). */
.tabela-subst th,.tabela-subst td{padding:6px 8px}
.tabela-subst th{white-space:normal;font-size:.58rem;line-height:1.25}
/* Nazwa i forma tez licza sie jako "liczby w jednej linii"? Nie - to tekst,
   wiec smie zawijac sie na dwie linie zamiast rozpychac kolumne (pelna tresc
   zawsze zostaje w title, patrz tabela-porownania.js). Kolumny liczbowe
   (klasa .n) zostaja na jednej linii - to one licza sie jako dane do
   porownania i nie wolno im sie zawijac (brief 18.09). Zawartosc/porcja ma
   klase .n (podswietlenie "naj"), ale przy mieszanym zestawie skladnikow
   (cele.html, rozne cele naraz) niesie tez nazwe substancji przed liczba,
   wiec dostaje wlasny wyjatek od nowrap. Kolumna rankingowa (zl/1000mg)
   stoi od 23.09 na trzecim miejscu, zaraz po formie (zlecenie: czytelnik
   nie powinien przewijac szesciu kolumn, zeby wrocic do domyslnego
   porzadku sortowania) - wyjatki nizej licza wiec pozycje CZWARTA
   (zawartosc) i PIATA (porcja), nie trzecia i czwarta jak przed przesunieciem. */
.tabela-subst td{white-space:normal}
.tabela-subst td.n{white-space:nowrap}
.tabela-subst td:nth-child(4).n{white-space:normal}
/* Kolumna porcji: od 19.09 stoi w niej tez zapis wagowy ("5 g dziennie" przy
   proszkach, patrz baza/porcja_wagowa.py), o kilka znakow dluzszy niz "1
   dziennie" przy kapsulkach. Przy table-layout:fixed i nowrap tekst nie
   zawijal sie, tylko wychodzil poza komorke i naklada sie na sasiednia
   kolumne (widoczne na telefonie). Ta jedna kolumna smie wiec zawinac. */
.tabela-subst td:nth-child(5).n{white-space:normal}
.tabela-subst td:nth-child(4) .num{white-space:nowrap}
/* Miniatura stoi OBOK tekstu, nie nad nim: kolumna niesie juz marke, nazwe i
   checkbox porownania (okolo 52 px), wiec obrazek 34 px nie podnosi wiersza.
   Kolumna nazwy dostala za to 38 px szerokosci wiecej (col-produkt wyzej),
   czyli dokladnie tyle, ile zabiera obrazek z odstepem - tekst zostaje rowno
   tak szeroki jak przed zmiana. */
.tab-produkt{display:flex;flex-direction:row;align-items:center;gap:8px;min-width:0}
.tab-produkt-tekst{display:flex;flex-direction:column;gap:5px;min-width:0;flex:1 1 auto}
/* 51 px zamiast 34 (poltora raza, polecenie Bartosza 23.09): wiersz tabeli ma
   okolo 52 px tresci, wiec obrazek tej wysokosci wypelnia go bez rozpychania. */
.tab-foto{width:51px;height:51px;flex:0 0 auto;object-fit:contain;border-radius:var(--r);
  background:var(--papier-2);mix-blend-mode:multiply}
.tab-foto-pusto{width:51px;height:51px;flex:0 0 auto;border-radius:var(--r);
  background:var(--papier-2);border:1px solid var(--kreska)}
.tab-produkt .otworz-wiersz{overflow:hidden}
.tab-produkt .pnazwa{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tab-porownaj{display:flex;align-items:center;gap:5px;font-size:.66rem;color:var(--cichy);
  cursor:pointer;user-select:none}
.tab-porownaj input{accent-color:var(--lazur);width:13px;height:13px;flex:0 0 auto;margin:0}
/* U39: serduszko obok checkboxa "porownaj", plaskie jak w .kafel-akcje (kolumna
   produktu w tej tabeli jest za wazka na wlasna ramke przycisku). */
.tab-produkt-akcje{display:flex;align-items:center;justify-content:space-between;gap:6px}
.tab-produkt-akcje .btn-ulub-mini{width:26px;height:26px;font-size:1.06rem;
  border:0;background:none;color:var(--cichy);padding:0;flex:0 0 auto;position:relative}
/* R6: ikona zostaje 26 px, ale obszar dotyku rosnie do 44 x 44 przez
   pseudo-element (klik w jego obszar trafia w ten sam przycisk, bo to jego
   potomek renderowany, nie osobny element). Tabela ma stala szerokosc
   kolumn i przewija sie w poziomie (.tscroll), wiec odstep miedzy checkboxem
   "porownaj" a serduszkiem zostaje ten sam na 390 i 1440 px: zmierzone
   Playwright, 66 px, wielokrotnosc rozszerzenia z zapasem. */
.tab-produkt-akcje .btn-ulub-mini::after{content:"";position:absolute;
  top:-9px;right:-9px;bottom:-9px;left:-9px}
.tab-produkt-akcje .btn-ulub-mini:hover{color:var(--atrament)}
.tab-produkt-akcje .btn-ulub-mini[aria-pressed="true"]{color:var(--lazur)}
/* Forma bywa dluzsza niz kolumna (np. "diglicynian magnezu (Albion Chelate)").
   Wczesniej przycinala sie wykropkowaniem w polowie slowa, a forma chemiczna
   to informacja merytoryczna: od niej zalezy przyswajalnosc. Zamiast ucinac
   tekst pozwalamy mu zawinac sie na kolejna linie, pelny zapis zostaje tez
   w title (formaTabeli w tabela-porownania.js). */
.tabela-subst td:nth-child(2) .tag{display:inline-block;max-width:100%;
  white-space:normal;overflow-wrap:break-word;vertical-align:bottom}

.plakietka{display:inline-flex;align-items:center;gap:5px;padding:2px 7px;border-radius:var(--r);
  font-size:.64rem;font-weight:600;font-stretch:100%;white-space:nowrap;letter-spacing:.01em}
.plakietka i{width:6px;height:6px;border-radius:50%;background:currentColor;flex:0 0 auto}
.p-potwierdzone{background:var(--zielen-tlo);color:var(--zielen)}
.p-jednozrodlowe{background:var(--uwaga-tlo);color:var(--uwaga)}
.p-brak{background:var(--papier-2);color:var(--cichy)}
/* Status prawny (rozporzadzenie 609/2013), nie ocena jakosci: neutralny
   lazur, nie bursztyn ani zielen zarezerwowane gdzie indziej (D22). Plakietka
   stoi wprost w tresci kafla (nie w .stopka jak reszta), wiec dostaje
   align-self, zeby nie rozciagnela sie na cala szerokosc flex-column. */
.p-fsmp{background:var(--lazur-tlo);color:var(--lazur)}
.kafel-tresc > .plakietka{align-self:flex-start}

.strony{display:flex;gap:8px;align-items:center;justify-content:center;margin-top:26px;flex-wrap:wrap}
.strony button{padding:9px 15px;border:1px solid var(--kreska);border-radius:var(--r);background:var(--karta);
  font:inherit;font-size:.86rem;cursor:pointer;color:var(--atrament)}
.strony button:hover:not(:disabled){border-color:var(--atrament)}
.strony button:disabled{opacity:.4;cursor:not-allowed}
.strony .gdzie{font-family:var(--dane);font-size:.8rem;color:var(--cichy);padding:0 6px}

.pusto{padding:48px 20px;text-align:center;color:var(--cichy);background:var(--karta);
  border:1px solid var(--kreska);border-radius:var(--r)}

dialog{border:1px solid var(--kreska-mocna);border-radius:var(--r);padding:0;max-width:min(760px,94vw);
  width:100%;background:var(--karta);color:var(--atrament)}
dialog::backdrop{background:rgba(14,31,43,.55)}
.karta-glowa{padding:20px 22px 16px;border-bottom:1px solid var(--kreska);display:flex;
  justify-content:space-between;gap:16px;align-items:flex-start}
.karta-glowa h2{font-size:1.24rem;max-width:44ch}
/* Rzad chipow pod nazwa produktu (zlecenie wlasciciela, zrzut z suplaner.pl,
   23.09, dolozony chip grupy 24.09): jedna definicja tresci w serwer/
   statyczne/chipy-produktu.js, ten plik dostaje wylacznie wyglad. :empty
   chowa caly rzad, gdy karta nie ma ani jednego chipu do pokazania (brak
   danych = brak rzedu, nie pusta ramka do zapelnienia). Kolory: fsmp i cel
   dziela lazur z .p-fsmp i .plakietka-tag.info nizej (ten sam typ faktu ma
   zawsze ten sam kolor w calym serwisie), fakt (sklad, postac) dostaje
   neutralny szary jak .tag.fakt. Grupa (etykieta katalogowa sklepu, NIE
   oswiadczenie zdrowotne) dostaje bursztyn zamiast zieleni: zielen w calym
   serwisie znaczy "najlepsza wartosc" albo "dobrane pod Twoje cele" (.naj,
   .tag.ok, .cel-dowod-tag.n5), a klasyfikacja katalogowa nie jest ocena ani
   rekomendacja (CLAUDE.md, zasada 5) -- bursztyn jest neutralny wobec tego
   znaczenia, a mimo to wyraznie inny niz lazur chipu celu. */
.karta-chipy{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.karta-chipy:empty{display:none}
.karta-chip{display:inline-block;padding:2px 8px;border-radius:var(--r);
  font-size:.72rem;font-weight:600;line-height:1.4;background:var(--papier-2);color:var(--atrament-2)}
.karta-chip-cel,.karta-chip-fsmp{background:var(--lazur-tlo);color:var(--lazur)}
.karta-chip-grupa{background:var(--uwaga-tlo);color:var(--uwaga)}
.karta-zamknij{border:1px solid var(--kreska);background:var(--papier);border-radius:var(--r);
  width:32px;height:32px;font-size:1rem;cursor:pointer;color:var(--atrament);flex:0 0 auto}
/* Grupuje zdjecie z nazwa/marka w jeden flex-item, zeby dodanie zdjecia nie
   rozjechalo justify-content:space-between na .karta-glowa (ktore liczy
   odstepy miedzy WSZYSTKIMI bezposrednimi dziecmi, wiec zdjecie jako osobne
   dziecko wepchaloby sie miedzy tekst i przyciski zamiast obok tekstu). */
.karta-info{display:flex;gap:12px;align-items:flex-start;min-width:0}
/* Ten sam wzorzec zastepczy co .kafel-obraz na liscie, tylko mniejszy: to
   okno modalne, nie strona, wiec zdjecie nie moze zepchnac skladu i ceny
   poza widoczny obszar. */
.karta-obraz{width:56px;height:56px;flex:0 0 auto;border-radius:var(--r);background:var(--papier);
  display:grid;place-items:center;overflow:hidden}
.karta-obraz img{max-width:100%;max-height:100%;object-fit:contain}
.karta-obraz .brak{font-family:var(--dane);font-size:.5rem;color:var(--cichy);letter-spacing:.03em;
  text-transform:uppercase;text-align:center;line-height:1.25}
/* Werdykt stoi NAD nazwa produktu, przed .karta-glowa: uniewaznia to, co
   jest pod nim (sklad, cena, oferty), wiec musi byc pierwsza rzecza, jaka
   widac po otwarciu karty, nie ostatnim akapitem po przewinieciu. */
.karta-werdykt{margin:16px 22px 0;padding:11px 14px;border-radius:var(--r);font-size:.86rem;
  display:flex;flex-direction:column;gap:4px}
.karta-werdykt h3{font-size:.86rem;margin:0}
.karta-werdykt p{margin:0;font-size:.82rem;line-height:1.4}
.karta-werdykt.blokada{background:var(--stop-tlo);color:var(--stop);border-left:2px solid var(--stop)}
.karta-werdykt.ostrzezenie{background:var(--uwaga-tlo);color:var(--uwaga);border-left:2px solid var(--uwaga)}
.karta-cialo{padding:18px 22px 24px;max-height:70vh;overflow-y:auto;display:flex;flex-direction:column;gap:22px}
.karta-cialo section{display:flex;flex-direction:column;gap:9px}
.karta-cialo h3{font-size:.76rem;text-transform:uppercase;letter-spacing:.13em;color:var(--cichy);font-stretch:100%}
table{border-collapse:collapse;width:100%;font-size:.85rem}
th{text-align:left;font-family:var(--dane);font-size:.6rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--cichy);font-weight:500;padding:7px 10px;border-bottom:1.5px solid var(--kreska-mocna)}
td{padding:8px 10px;border-bottom:1px solid var(--kreska)}
td.n{text-align:right;font-family:var(--dane);white-space:nowrap}
/* Bez tego naglowek kolumny liczbowej stal po lewej, a wartosci po prawej,
   wiec zadna liczba nie stala pod swoim tytulem. */
th.n{text-align:right}
/* Przeplot: oko trzyma wiersz przy przejsciu przez szeroka tabele. */
tbody tr:nth-child(even) td{background:var(--papier)}
td .brak{color:var(--cichy);font-style:normal}
/* Pasek tylko na pierwszej komorce (zgloszenie 27.09): inset na kazdym td
   rysowal zielona kreske przy kazdej kolumnie, wiec wyrozniony wiersz
   wygladal na podzielony na kolumny, a pozostale nie. */
tr.naj td,tbody tr.naj:nth-child(even) td{background:var(--zielen-tlo)}
tr.naj td:first-child{box-shadow:inset 3px 0 0 var(--zielen)}
.nota{font-size:.79rem;color:var(--cichy);line-height:1.5}
.nota.ostrzezenie{color:var(--uwaga);background:var(--uwaga-tlo);padding:9px 11px;border-radius:var(--r);
  border-left:2px solid var(--uwaga)}
.nota.spor{color:var(--stop);background:var(--stop-tlo);padding:9px 11px;border-radius:var(--r);
  border-left:2px solid var(--stop)}
/* Ostrzezenie o kumulacji dawek na karcie preparatu zlozonego: sama sprawa
   (mozna przekroczyc norme biorac osobny preparat z tym samym skladnikiem)
   jest bezpieczenstwem, nie ciekawostka, wiec ten sam ton co .ostrzezenie. */
.nota.kumulacja{color:var(--uwaga);background:var(--uwaga-tlo);padding:9px 11px;border-radius:var(--r);
  border-left:2px solid var(--uwaga)}
/* Status prawny (rozporzadzenie 609/2013), nie ryzyko: lazur, nie bursztyn -
   ta sama roznica jak przy plakietce .p-fsmp na kaflu i w tabeli. */
.nota.fsmp{color:var(--lazur);background:var(--lazur-tlo);padding:9px 11px;border-radius:var(--r);
  border-left:2px solid var(--lazur)}
.zrodla-lista{display:flex;flex-wrap:wrap;gap:6px}
.zrodlo-plakietka{font-family:var(--dane);font-size:.66rem;padding:3px 8px;border-radius:var(--r);
  border:1px solid var(--kreska);background:var(--papier);color:var(--atrament-2)}
.zrodlo-plakietka.pierwotne{border-color:var(--zielen);color:var(--zielen);background:var(--zielen-tlo)}

.wywiad{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  margin-bottom:18px}
.wywiad-glowa{display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:13px 16px;cursor:pointer;user-select:none}
.wywiad-glowa h2{font-size:.86rem}
.wywiad-glowa .ile-zaznaczonych{font-family:var(--dane);font-size:.72rem;color:var(--cichy)}
.wywiad-cialo{padding:0 16px 16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px}
.wywiad[data-otwarty="false"] .wywiad-cialo{display:none}
.wywiad-grupa h3{font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;color:var(--cichy);
  font-stretch:100%;margin:0 0 8px}
/* Wielokrotny wybor wyglada tak samo jak jednokrotny (.wywiad-jednokrotny
   nizej): te same tabletki, ten sam stan zaznaczenia. Kratka checkboxa jest
   ukryta wizualnie, ale ZOSTAJE w drzewie dostepnosci, bo przy wielokrotnym
   wyborze to wlasciwa semantyka. Do 17.09 plec i wiek byly tabletkami, a
   dieta, leki i schorzenia lista kratek: ten sam rodzaj decyzji w dwoch
   roznych strojach na jednym ekranie. */
.wywiad-chip{display:inline-flex;align-items:center;gap:0;padding:7px 13px;font-size:.85rem;
  cursor:pointer;border:1px solid var(--kreska);border-radius:var(--r);background:var(--karta);
  color:var(--atrament);line-height:1.25}
.wywiad-chip:hover{border-color:var(--atrament)}
.wywiad-chip input{position:absolute;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}
.wywiad-chip:has(input:checked){background:var(--atrament);color:var(--karta);border-color:var(--atrament)}
.wywiad-chip:has(input:focus-visible){outline:2px solid var(--lazur);outline-offset:2px}

.wykl-pasek{display:flex;align-items:center;gap:10px;padding:10px 13px;border-radius:var(--r);
  margin-bottom:14px;font-size:.83rem;background:var(--uwaga-tlo);color:var(--uwaga);
  border-left:2px solid var(--uwaga)}
.wykl-pasek.pusty{background:var(--papier-2);color:var(--cichy);border-left-color:var(--kreska)}
.wykl-pasek b{font-weight:600}
.wykl-pasek button{margin-left:auto;flex:0 0 auto;border:1px solid currentColor;background:none;
  border-radius:var(--r);padding:5px 10px;font:inherit;font-size:.76rem;cursor:pointer;color:inherit}

.kafel .powod-blokady{font-size:.68rem;color:var(--stop);background:var(--stop-tlo);
  padding:5px 8px;border-radius:var(--r);margin-top:6px}

@media (max-width:560px){
  .hdr{gap:12px} .hdr-stan{display:none}
  /* Kafel produktu z pionu na poziom (notes/MOBILE-PRZEBUDOWA.md): jedna
     kolumna, miniatura po lewej, tresc obok. Dwie kolumny pionowych kafli
     mieszczaly jeden i pol produktu na ekranie, ten uklad mieisci cztery.
     .kafel-otworz i .kafel-marka nadpisywane dalej w pliku (patrz sekcja
     "kafel przestal byc jednym przyciskiem"), wiec ich mobilny uklad stoi
     w osobnym @media tuz za ta sekcja, zeby wygrac kaskade. */
  .siatka{grid-template-columns:1fr;gap:8px}
  .kafel-obraz{width:88px;height:88px;aspect-ratio:auto;flex:0 0 88px;
    border-bottom:0;border-right:1px solid var(--kreska);padding:6px}
  .cel-produkty .kafel-obraz{aspect-ratio:auto}
  .kafel-tresc{padding:6px 11px 6px 10px;gap:2px}
  /* Opakowanie leci pierwsze, potem liczba skladnikow: na 88px wysokosci
     to najmniej wazne linie, zawartosc na porcje i cena (stopka) zostaja
     zawsze widoczne, to po nie tu ktos przyszedl. */
  .kafel .opak,.kafel .skladnikow{display:none}
  .kafel .stopka{padding-top:2px}
}

/* Przebudowa mobilna listy /produkty (notes/MOBILE-PRZEBUDOWA.md, zlecenie
   22.09): przy 390px pierwszy kafel zaczynal sie na 668px, bo nad lista
   stalo szesc blokow tresci jeden pod drugim. Nic z tego nie znika:
   nota o metodzie liczenia rankingu, etykieta szukajki i licznik strony
   zostaja w DOM dla czytnikow ekranu, tylko przestaja zajmowac ekran, zanim
   uzytkownik zobaczy pierwszy produkt. */
@media (max-width:560px){
  /* Nota jest teza serwisu (CLAUDE.md, zasada nie do usuniecia), wiec nie
     znika: chowa sie za przyciskiem "o metodzie" i wraca po kliknieciu. */
  /* W markupie przycisk stoi WEWNATRZ h1, na koncu jego tekstu (patrz
     index.html): dzieki temu dopisuje sie do istniejacego zawijania linii
     tytulu zamiast rozpychac nagłowek o cala wlasna linie. vertical-align
     dosuwa go do linii bazowej tekstu, nie do gornej krawedzi liter. */
  .nota-przelacznik{display:inline-flex;align-items:center;vertical-align:middle;
    margin-left:4px;padding:3px 9px;
    border:1px solid var(--kreska);border-radius:var(--r);background:var(--karta);
    font-size:.68rem;font-weight:600;color:var(--cichy);cursor:pointer;
    min-height:24px}
  .nota-przelacznik:hover{border-color:var(--atrament);color:var(--atrament)}
  .head-produkty .nota{display:none}
  .head-produkty .nota.nota-widoczna{display:block}

  /* Pasek "Twoja sytuacja" zostaje zawsze widoczny (wejscie do wykluczen),
     ale tytul i licznik zaznaczonych ida pod soba zamiast obok, zeby zadna
     z dwoch linii nie zawijala sie wewnetrznie na dwie kolejne. */
  .wywiad-glowa{flex-direction:column;align-items:flex-start;gap:2px;padding:10px 13px}
  .wywiad-glowa h2{font-size:.8rem}

  /* Etykieta "Zawez wyniki" i licznik strony ("strona 1 z 178") nie sa
     tresci, dla ktorej warto poswiecic ekran telefonu (zlecenie 22.09):
     placeholder w polu i przyciski "Poprzednia/Nastepna" pod lista mowia to
     samo. Znikaja wizualnie, zostaja w drzewie dostepnosci. */
  .tylko-czytnik-waski{position:absolute;width:1px;height:1px;margin:-1px;
    overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .szukajka{margin-bottom:10px}
  .ile-strona{display:none}

  /* Trzy przyciski sortowania pelnym tekstem ("zl za 1000 mg", "cena
     opakowania", "mg na porcje") nie miesza sie obok liczby wynikow w
     jednej linii przy 390px: scisniejszy padding i mniejsza czcionka. */
  .pasek{padding-bottom:6px;margin-bottom:12px}
  .seg button{padding:6px 10px;font-size:.74rem}
}

/* Nawigacja miedzy trzema wejsciami. Kolejnosc nieprzypadkowa: cel zdrowotny
   pierwszy, bo to wejscie dla kogos, kto nie zna substancji (D2 w DECYZJE.md). */
.nawigacja{display:flex;gap:2px;margin-left:24px}
.nawigacja a{padding:8px 13px;border-radius:var(--r);font-size:.86rem;font-weight:600;
  color:var(--atrament-2);text-decoration:none;border:1px solid transparent}
.nawigacja a:hover{background:var(--papier-2);color:var(--atrament)}
.nawigacja a[aria-current="page"]{background:var(--atrament);color:var(--karta)}
.nawigacja a:focus-visible{outline:2px solid var(--lazur);outline-offset:1px}
@media (max-width:760px){
  .nawigacja{margin-left:auto;gap:0}
  .nawigacja a{padding:8px 9px;font-size:.78rem}
  .marka small{display:none}
}

/* ============================================================
   Blok: ekran porownania tabelarycznego i wybor produktow do niego
   (serwer/porownanie.py, serwer/statyczne/porownanie.html).
   Dopisany na koncu, zeby nie ruszac kaskady istniejacych regul.
   ============================================================ */

/* kafel przestal byc jednym przyciskiem: otwieranie karty i wybor do
   porownania to dwa oddzielne elementy klikalne w jednym kontenerze */
.kafel{cursor:default}
.kafel-otworz{all:unset;box-sizing:border-box;display:flex;flex-direction:column;
  flex:1;width:100%;cursor:pointer;color:inherit;font:inherit;text-align:left}
.kafel-otworz:focus-visible{outline:2px solid var(--lazur);outline-offset:-2px}
/* U19: przycisk niewygodny i za maly u konkurencji. Tlo przy zaznaczeniu i
   przy hover dostaje ciezar przycisku niezaleznie od szerokosci ekranu;
   wieksza czcionka i checkbox to desktop-only powiekszenie nizej w pliku
   (ten sam powod co U18: kafel 160px na telefonie nie wolno cofnac). */
.kafel-porownaj{display:flex;align-items:center;gap:7px;padding:9px 13px;
  border-top:1px solid var(--kreska);font-size:.74rem;color:var(--atrament-2);
  cursor:pointer;user-select:none}
.kafel-porownaj:hover{background:var(--papier)}
.kafel-porownaj:has(input:checked){background:var(--lazur-tlo);color:var(--lazur);font-weight:600}
.kafel-porownaj:has(input:focus-visible){outline:2px solid var(--lazur);outline-offset:-2px}
.kafel-porownaj input{accent-color:var(--lazur);width:15px;height:15px;flex:0 0 auto}
/* Limit szesciu produktow do porownania (G3, 26.09): przy szesciu wybranych
   pozostale checkboxy dostaja aria-disabled (statyczne/porownanie-wybor.js),
   nie disabled, zeby zostaly fokusowalne z klawiatury: stad przygaszenie
   samym stylem, bez pointer-events:none. Dotyczy obu wariantow checkboxa
   porownania: kafle listy (.kafel-porownaj) i wiersze tabeli (.tab-porownaj,
   styl.css wyzej). */
.kafel-porownaj:has(input[aria-disabled="true"]),
.tab-porownaj:has(input[aria-disabled="true"]){opacity:.45}

/* Marka wyprowadzona POZA .kafel-otworz (przejscie do strony producenta,
   serwer/producenci_web.py): .kafel .marka-p wyzej daje jej ten sam wyglad,
   tu tylko wlasny odstep i zniesienie podkreslenia linku. */
.kafel-marka{display:block;padding:11px 13px 0;text-decoration:none;width:fit-content}
.kafel-marka:hover,.kafel-marka:focus-visible{color:var(--lazur);text-decoration:underline}

@media (max-width:560px){
  .kafel-marka{padding:4px 11px 0}
  .kafel-otworz{flex-direction:row;align-items:stretch}
}

.pasek-porownaj{position:fixed;left:50%;bottom:18px;transform:translateX(-50%);
  display:flex;align-items:center;gap:14px;padding:12px 18px;background:var(--atrament);
  color:var(--karta);border-radius:var(--r);box-shadow:0 8px 24px rgba(14,31,43,.32);z-index:30;
  max-width:calc(100vw - 24px)}
.pasek-porownaj[hidden]{display:none}
.pasek-porownaj span{font-size:.86rem}
/* U33a: skad sie bierze wybor i ze nigdzie nie jest wysylany -- ta sama
   informacja, ktora .nota-wywiad daje przy wywiadzie zdrowotnym. Mniejsza i
   przygaszona, zeby nie konkurowala z przyciskiem "Porownaj". */
.pasek-porownaj-nota{font-size:.72rem;color:var(--noc-cichy);max-width:34ch;line-height:1.4}
.pasek-porownaj button{font:inherit;font-weight:600;padding:8px 15px;border-radius:var(--r);
  border:1px solid var(--karta);background:var(--karta);color:var(--atrament);cursor:pointer;white-space:nowrap}
.pasek-porownaj button.wyczysc{background:none;border-color:transparent;color:var(--karta);
  font-weight:400;text-decoration:underline;padding:8px 4px}

.head-porownanie{margin-bottom:20px;display:flex;flex-direction:column;gap:7px;max-width:74ch}

/* strona porownania: tabela scrolluje we wlasnym kontenerze, strona nie.
   max-height jest tu warunkiem koniecznym, nie kosmetyka: overflow-x:auto z
   overflow-y niepodanym przelicza sie w przegladarce na overflow-y:auto (kwirk
   CSS, spec overflow-3 3.3 - "visible" na jednej osi zmienia sie na "auto",
   gdy druga os nie jest "visible"). Bez wlasnej wysokosci kontener i tak
   staje sie kontekstem przewijania dla position:sticky, tylko bez widocznego
   scrollbara - a wtedy sticky nie ma wzgledem czego "przykleic sie" i po
   prostu jedzie razem z dokumentem (zmierzone Playwrightem 22.09: thead
   wychodzil poza ekran przy przewinieciu strony). max-height czyni z .tscroll
   FAKTYCZNY kontener przewijania w obu osiach, wiec sticky dziala tak, jak
   wyglada: nagrywa sie wzgledem tabeli, nie wzgledem strony. */
.tscroll{overflow:auto;border:1px solid var(--kreska);border-radius:var(--r);
  background:var(--karta);max-height:min(640px,70vh)}
.tabela-porownania{min-width:100%}
/* Kontroler 26.09: goly <small> (cena za sztuke, zrodlo apteczne, "jedna
   oferta") dziedziczy domyslne ~83% przegladarki, co przy bazowych 13,6px w
   tabeli dawalo 11,3px. Jeden przelacznik na cala tabele, zamiast klasy przy
   kazdym z czterech miejsc w kodzie, ktore dzis buduja <small> bez klasy. */
.tabela-porownania small{font-size:.75rem}
/* U34, 22.09: nowrap na kazdej komorce byl glownym powodem przewijania w
   bok, bo nazwa produktu albo zdanie w komorce ciagnely kolumne do pelnej
   dlugosci tekstu. normal + wlasny max-width pozwala kolumnie zwezic sie do
   sensownej szerokosci i zawinac tekst zamiast rozpychac tabele. */
.tabela-porownania th,.tabela-porownania td{white-space:normal;padding:8px 7px;
  max-width:148px}
.tabela-porownania th:first-child,.tabela-porownania td:first-child{
  position:sticky;left:0;background:var(--karta);white-space:normal;max-width:none;
  box-shadow:1px 0 0 var(--kreska);z-index:1}
/* Naglowek przyklejony w pionie (brief 22.09, punkt 2): najwieksza wada
   mobilna konkurencji to thead ktory NIE jest przyklejony, wiec po paru
   przewinieciach nie wiadomo, o ktorym produkcie mowa. top:0 jest tu wzgledem
   .tscroll (patrz wyzej), nie wzgledem strony. */
.tabela-porownania thead th{position:sticky;top:0;z-index:2;background:var(--karta);
  box-shadow:0 1px 0 var(--kreska)}
.tabela-porownania thead th:first-child{position:sticky;top:0;left:0;z-index:3}
.tabela-porownania td.n,.tabela-porownania th.n{text-align:left}
.porown-glowa{display:flex;flex-direction:column;gap:6px;min-width:0}
.porown-obraz{width:64px;height:64px;border:1px solid var(--kreska);border-radius:var(--r);
  display:grid;place-items:center;background:var(--papier);overflow:hidden}
.porown-obraz img{max-width:100%;max-height:100%;object-fit:contain;mix-blend-mode:multiply}
.porown-obraz .brak{font-family:var(--dane);font-size:.75rem;color:var(--cichy);text-align:center}
.porown-teksty{display:flex;flex-direction:column;gap:6px;min-width:0}
.porown-marka{font-family:var(--dane);font-size:.75rem;text-transform:uppercase;
  letter-spacing:.06em;color:var(--cichy)}
.porown-nazwa{font-size:.88rem;font-weight:600;line-height:1.28}
/* Jednostka porcji stoi w naglowku, bo kazda liczba w kolumnie odnosi sie
   wlasnie do niej. Jedyny element wziety wprost od suplaner.pl, patrz
   notes/MOBILE-PRZEBUDOWA.md */
.porown-porcja{font-family:var(--dane);font-size:.75rem;color:var(--atrament-2)}
.tabela-porownania td.naj{background:var(--zielen-tlo);box-shadow:inset 3px 0 0 var(--zielen)}
.wiersz-sekcja td{background:var(--papier-2);font-family:var(--dane);font-size:.75rem;
  text-transform:uppercase;letter-spacing:.1em;color:var(--cichy);font-weight:600}
.wiersz-nota td{background:var(--karta);white-space:normal;padding:8px 10px 12px}
.etykieta-naj{font-family:var(--dane);font-size:.75rem;text-transform:uppercase;
  letter-spacing:.05em;color:var(--zielen);font-weight:600}
.nie-zawiera{color:var(--cichy)}
.nie-zawiera[title]:not([title=""]){cursor:help;border-bottom:1px dotted var(--cichy)}
.jedno-zrodlo-adnotacja{display:block;color:var(--cichy);font-family:var(--dane);font-size:.75rem}
/* dwa wpisy w jednej komorce (wiersz scalony ze slownika, dwie formy
   chemiczne tej samej substancji) dostaja odstep i kreske miedzy soba,
   zeby nie czytaly sie jak jedna liczba */
.wpis-skladnika+.wpis-skladnika{margin-top:7px;padding-top:7px;border-top:1px dashed var(--kreska)}
.etykieta-surowa{display:block;color:var(--cichy);font-size:.75rem;margin-top:1px}
/* procent RWS: informacyjny, nie ocenny, wiec sam szary tekst bez plakietki */
.procent-rws{color:var(--cichy);font-family:var(--dane);font-size:.75rem}
/* Pasek normy z dwoma znacznikami (brief 22.09, punkt 1): 100% RWS i gorna
   granica bezpieczenstwa. Wypelnienie zmienia kolor WYLACZNIE przy
   wpis.przekracza_granice z API (mg do mg), nigdy od samego procentu RWS -
   200-300% RWS bywa normalne i nie ma prawa wygladac jak alarm. Bursztyn,
   nie czerwien: ta sama zasada co .ponad-granica nizej (D22, czerwien tylko
   dla wykluczen bezpieczenstwa). Sam kolor nigdy nie wystarcza, wiec liczba
   i teksty obok paska (procent-rws, ponad-granica) zostaja bez zmian. */
.pasek-normy{position:relative;width:100%;max-width:120px;height:6px;margin-top:5px;
  border-radius:3px;background:var(--papier-2)}
.pasek-normy-wypelnienie{position:absolute;top:0;left:0;height:100%;border-radius:3px;
  background:var(--zielen)}
.pasek-normy--przekroczona .pasek-normy-wypelnienie{background:var(--uwaga)}
/* Znaczniki to piony wystajace lekko ponad i pod pasek, zeby byly widoczne
   nawet gdy stoja blisko konca wypelnienia. */
.pasek-normy-znacznik{position:absolute;top:-2px;bottom:-2px;width:2px;
  background:var(--atrament-2)}
.pasek-normy-znacznik--ul{background:var(--stop)}
/* Brak gornej granicy (np. B12, biotyna) to "nie wiadomo", nie "mieszczy sie
   w normie" - brak drugiego znacznika sam w sobie latwo przeoczyc, wiec
   dostaje wlasny, czytelny dopisek (brief, warunek "musi to byc widoczne"). */
.pasek-brak-ul{display:block;margin-top:3px;color:var(--cichy);font-size:.75rem}
/* przekroczenie gornej granicy to regularna informacja przy tej skali danych
   (32 procent wariantow magnezowych), nie alarm: bursztyn, nie czerwien,
   ktora w tym projekcie jest zarezerwowana dla wykluczen bezpieczenstwa (D22) */
.ponad-granica{display:inline-block;margin-top:4px;padding:2px 7px;border-radius:var(--r);
  background:var(--uwaga-tlo);color:var(--uwaga);font-size:.75rem;font-weight:600}
/* znacznik przypisu przy nazwie substancji, tresc idzie pod tabele (nie w
   kolumnie etykiety: zdanie o gornej granicy nizszej niz RWS lamalo sie tam
   na dziesiec linii i rozpychalo caly wiersz, przeglad 17.09) */
.przypis-znacznik{color:var(--cichy);cursor:help;font-weight:600;font-size:.75rem}
.przypisy{padding:10px 2px 0;display:flex;flex-direction:column;gap:4px}
.przypisy .nota{margin:0}
.sporne-wartosci{display:flex;flex-direction:column;gap:2px;font-size:.78rem}
.sporne-wartosci b{font-weight:600}
.sporne-wartosci small{color:var(--cichy);font-family:var(--dane);font-size:.75rem}
.sporne-naglowek{display:block;color:var(--cichy);margin-bottom:2px}
.werdykt-plakietka{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;
  border-radius:var(--r);font-size:.75rem;font-weight:600;white-space:nowrap}
.werdykt-plakietka.w-ok{background:var(--zielen-tlo);color:var(--zielen)}
.werdykt-plakietka.w-ostrzezenie{background:var(--uwaga-tlo);color:var(--uwaga)}
.werdykt-plakietka.w-blokada{background:var(--stop-tlo);color:var(--stop)}
.werdykt-plakietka.w-nieznany{background:var(--papier-2);color:var(--cichy)}
.werdykt-powody{margin-top:5px;display:flex;flex-direction:column;gap:3px;font-size:.75rem;
  color:var(--atrament-2);white-space:normal;max-width:220px}
.blokada-pasek{display:flex;align-items:center;gap:10px;padding:11px 14px;border-radius:var(--r);
  margin-bottom:16px;font-size:.86rem;background:var(--stop-tlo);color:var(--stop);
  border-left:2px solid var(--stop)}
.blokada-pasek b{font-weight:600}
.porownanie-pusto{padding:60px 20px;text-align:center;color:var(--cichy);background:var(--karta);
  border:1px solid var(--kreska);border-radius:var(--r);display:flex;flex-direction:column;
  gap:14px;align-items:center}
.porownanie-pusto a{color:var(--lazur);font-weight:600;text-decoration:none}
.porownanie-pusto a:hover{text-decoration:underline}

/* Przelacznik "Tylko roznice" (brief 22.09, punkt 3): stoi nad tabela, cel
   dotykowy min. 24px liczony z padding+min-height na calej etykiecie, nie
   tylko z samego checkboxa. */
.porown-kontrolki{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-bottom:8px}
/* U36: zapis calego zestawienia to dodanie kazdego produktu do ulubionych po
   kolei (ten sam plaski mechanizm co pojedyncze serduszko, patrz raport) -
   stad zwykly przycisk drugorzedny, nie gwiazdka. */
.porown-zapisz-ulubione{border:1px solid var(--kreska);background:var(--karta);color:var(--atrament-2);
  border-radius:var(--r);padding:7px 13px;font:inherit;font-size:.8rem;cursor:pointer}
.porown-zapisz-ulubione:hover{border-color:var(--atrament);color:var(--atrament)}
.porown-zapisz-ulubione:focus-visible{outline:2px solid var(--lazur);outline-offset:1px}
.porown-zapisz-ulubione:disabled{cursor:default;color:var(--cichy)}
.tylko-rozne-etykieta{display:flex;align-items:center;gap:7px;min-height:24px;
  padding:4px 2px;font-size:.82rem;color:var(--atrament-2);cursor:pointer;user-select:none}
.tylko-rozne-etykieta input{accent-color:var(--lazur);width:16px;height:16px;flex:0 0 auto}
.tabela-porownania.tylko-rozne tr[data-identyczne="1"]{display:none}

@media (max-width:560px){
  .pasek-porownaj{flex-wrap:wrap;justify-content:center;text-align:center}
  /* Miniatura w naglowku kolumny porownania (brief 22.09, punkt 2): przy
     przyklejonym thead 64px zjadaloby zbyt duzo ekranu przy kazdym
     przewinieciu. Uklad z pionu na poziom, tak jak kafel produktu w
     notes/MOBILE-PRZEBUDOWA.md - obrazek obok tekstu, nie nad nim. Cala
     kolumna (obrazek + marka + nazwa + porcja) miesci sie w 96px wysokosci. */
  .porown-glowa{flex-direction:row;align-items:flex-start;gap:8px;
    min-width:0;position:relative;padding-right:30px}
  .porown-obraz{width:32px;height:32px}
  .porown-teksty{gap:2px}
  /* Pasek akcji (serce i krzyzyk) stoi w prawym gornym rogu kolumny, ale w
     pionie: w poziomie dwa pola po 28 px zjadalyby 60 px szerokosci
     naglowka, ktory na telefonie ma jej najmniej. */
  .porown-akcje{position:absolute;top:0;right:0;flex-direction:column;gap:2px}
}

/* Naglowek z trzema pozycjami nawigacji (D15 w DECYZJE.md) nie miescil sie
   w 400px nawet po istniejacej regule <=760px: suma znaku, marki i trzech
   linkow przekraczala szerokosc ekranu o 15px, wiec strona scrollowala sie
   w bok. Marka jest zbedna, gdy uzytkownik i tak widzi, gdzie jest, bo
   wlasnie klika w nawigacji. */
@media (max-width:420px){
  .marka{display:none}
  .hdr{gap:8px}
}

/* Ostrzezenie na kaflu. Blokada usuwa produkt z listy, ostrzezenie zostawia,
   wiec bez tego kafel z ostrzezeniem wygladal identycznie jak produkt bez uwag. */
.kafel .powod-ostrzezenia{font-size:.68rem;color:var(--uwaga);background:var(--uwaga-tlo);
  padding:5px 8px;border-radius:var(--r);margin-top:4px;line-height:1.35}
/* Nota o danych zdrowotnych stoi pod wywiadem, wiec chowa sie razem z nim. */
.wywiad[data-otwarty="false"] .nota-wywiad{display:none}
.nota-wywiad{padding:0 16px 14px;margin:0}

/* ============================================================
   Blok: wejscie przez cel zdrowotny, ekran wyboru i ekran wyniku
   (serwer/cele.py, serwer/statyczne/cele.html).
   Dopisany na koncu, zeby nie ruszac kaskady istniejacych regul.
   ============================================================ */

.head-cele{margin-bottom:20px;display:flex;flex-direction:column;gap:7px;max-width:74ch}

/* Tytul listy produktow. Do 21.09 ta strona nie miala naglowka h1 wcale i
   zaczynala sie od h2 panelu wywiadu: struktura dokumentu bez korzenia, a
   czytelnik bez informacji, co wlasciwie oglada. Krotko byl tu h1 ukryty
   wizualnie, ale to polsrodek; decyzja Bartosza z 21.09: tytul ma byc
   widoczny. Ten sam uklad co .head-cele i .head-porownanie. */
.head-produkty{margin-bottom:20px;display:flex;flex-direction:column;gap:7px;max-width:74ch}
/* Przycisk rozwijajacy note o metodzie liczenia rankingu istnieje tylko na
   waskim ekranie (patrz @media(max-width:560px) na poczatku pliku): na
   desktopie nota stoi zawsze widoczna pod h1, tak jak dotad. min-width, nie
   samo "display:none" bez zakresu: reguly dla waskiego ekranu stoja WYZEJ w
   tym pliku (przed tym blokiem), wiec przy rownej specyficznosci zwykle
   "display:none" bez wlasnego zakresu wygralby kaskade i chowal przycisk
   tez na telefonie. */
@media (min-width:561px){
  .nota-przelacznik{display:none}
}

.wroc-do-celow{display:inline-block;margin-bottom:14px;font-size:.86rem;font-weight:600;
  color:var(--lazur);text-decoration:none}
.wroc-do-celow:hover{text-decoration:underline}

.siatka-cele{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px}
/* U1 do U3 (notes/UWAGI-UX-2026-09-22.md): dziesiec kafli maja zmiescic sie w
   dwoch rzedach na desktopie, dzis widac osiem w czterech kolumnach. Klasa
   dodatkowa zamiast zmiany .siatka-cele wprost: .siatka-cele zyje tez w
   roslinne.html, ktorego to zlecenie nie dotyczy, wiec ta specyficznosc
   (dwie klasy) nadpisuje tylko kontener celow, nie rusza tamtego ekranu. Piec
   kolumn od 900px w gore (main ma max-width 1240px, wiec przy 1440px na
   ekranie kolumna wychodzi ok. 220px), auto-fill ponizej tego progu, zeby
   szerokosci posrednie (tablet) nie scisnely kafli do nieczytelnej waskosci.
   Mobile (<=560px) ma wlasny grid ustawiony w media query nizej i ten tu
   progu nie dotyczy w ogole (max-width:560px < min-width:900px). */
.siatka-cele.cele-siatka-kafli{grid-template-columns:repeat(auto-fill,minmax(190px,1fr))}
@media (min-width:900px){
  .siatka-cele.cele-siatka-kafli{grid-template-columns:repeat(5,1fr)}
}
.kafel-cel{position:relative;background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  display:flex;flex-direction:column;gap:8px;text-align:left;padding:0 0 16px;font:inherit;
  color:inherit;cursor:pointer;transition:border-color .16s,transform .16s;overflow:hidden}
.kafel-cel>*{padding-left:17px;padding-right:17px}
.kafel-cel:hover{border-color:var(--atrament);transform:translateY(-2px)}
.kafel-cel:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
.kafel-cel-nazwa{font-size:1.02rem;font-weight:700;font-stretch:110%;letter-spacing:-.015em}
.kafel-cel-opis{font-size:.84rem;color:var(--atrament-2);line-height:1.45}
.kafel-cel-liczba{margin-top:auto;padding-top:6px;font-family:var(--dane);font-size:.68rem;
  color:var(--cichy);letter-spacing:.02em}
/* Bez kursywy: Archivo jest wgrana wylacznie w odmianie prostej, wiec
   font-style:italic dawalby tu skos syntetyczny, psujacy ksztalty znakow,
   najmocniej na polskich ogonkach. Wyroznienie robi kolor, tak jak przy
   nazwach lacinskich i w naglowkach. */
.kafel-cel-brak{margin-top:auto;padding-top:6px;font-size:.76rem;color:var(--cichy);
  line-height:1.4}

/* Kafel celu na /cele (.cele-siatka-kafli): dowod liczbowy zamiast duzej
   fotografii nad nazwa (23.09), a od wieczora tego samego dnia mala miniatura
   w rzedzie z nazwa, wylacznie na desktopie. Ten sam kafel co na stronie
   glownej (serwer/statyczne/glowna.html::renderCele). Pierwszemu dziecku
   trzeba dolozyc gorny odstep, ktorego dotad dostarczal obraz nad nim.
   Scoped, zeby .kafel-cel na /rosliny (kafel-roslina, bez zdjecia od
   poczatku, wlasny rytm juz to zaklada) zostal dokladnie taki jak dzis. */
/* Gestsze wnetrze niz do 23.09 (margin-top 16, gap kafla 8, dolny padding 16):
   miniatura podnosi rzad nazwy o 17 px, a te ciecia oddaja polowe z powrotem.
   Zmierzone przy 1440 px: kafel 151 px bez obrazu, 169 z obrazem i tymi
   odstepami zamiast 177 na starych. */
.cele-siatka-kafli .kafel-cel{gap:6px;padding-bottom:13px}
.cele-siatka-kafli .kafel-cel-glowa{margin-top:13px;display:flex;align-items:center;gap:11px;min-width:0}
/* Miniatura celu: TYLKO od 900 px w gore, czyli tam, gdzie siatka ma piec
   stalych kolumn. Ponizej kafel zostaje dokladnie taki, jaki byl: na telefonie
   dwie kolumny po ~170 px nie maja z czego oddac 40 px na obraz, a przy
   szerokosciach posrednich kolumna schodzi do 190 px. Obraz jest tlem, nie
   <img>: element ukryty display:none nie pobiera swojego tla, a <img
   loading="lazy"> ukryty tak samo pobiera sie mimo to (zmierzone). */
.cele-siatka-kafli .kafel-cel-obraz{display:none;width:56px;height:56px;flex:0 0 56px;
  border-radius:var(--r);background-color:var(--tlo);background-size:cover;background-position:center}
@media (min-width:900px){
  .cele-siatka-kafli .kafel-cel-obraz{display:block}
}
/* Zdanie o rejestrze UE stalo dotad w kazdym kaflu ("N skladnikow z
   oswiadczeniem"), czyli dziesiec razy to samo. Mowi je teraz raz nota pod
   siatka, tak jak na stronie glownej (.hp-goals-nota). */
.cele-nota-rejestr{margin-top:14px;font-size:.79rem;color:var(--cichy);max-width:74ch;line-height:1.5}
.cele-siatka-kafli .kafel-cel-brak{color:var(--uwaga)}

/* Cel bez pokrycia w rejestrze nie znika: dostaje jawny komunikat zamiast
   pustej listy, zeby nie wygladalo na brak danych do uzupelnienia (D6,
   CLAUDE.md zasada 4: nie zmyslamy oswiadczen, ktorych nie ma). */
.cel-brak-pokrycia{background:var(--papier-2);border:1px solid var(--kreska);border-radius:var(--r);
  padding:16px 18px;display:flex;flex-direction:column;gap:8px;font-size:.88rem;
  color:var(--atrament-2);line-height:1.55;margin-bottom:26px}
.cel-brak-pokrycia p{margin:0}

.cel-skladniki{margin-bottom:28px}
.cel-skladniki h2,.cel-produkty h2{font-size:.98rem;margin-bottom:12px}

/* Zastrzezenie prawne z rejestru (np. "Stres i napiecie" nie jest oswiadczeniem
   o stresie) stoi tuz przed lista skladnikow i wyglada jak ostrzezenie, nie
   jak zwykla notka: to sufit tego, co wolno obiecac, wiec nie moze byc cichy. */
.cel-zastrzezenie{margin:0 0 16px;padding:11px 14px;border-radius:var(--r);
  background:var(--uwaga-tlo);color:var(--uwaga);border-left:2px solid var(--uwaga);
  font-size:.84rem;line-height:1.5;max-width:none}

.lista-skladnikow{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}
.skladnik-karta{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  padding:14px 16px;display:flex;flex-direction:column;gap:8px}
.skladnik-glowa{display:flex;justify-content:space-between;align-items:baseline;gap:10px;flex-wrap:wrap}
.skladnik-nazwa{font-size:.92rem;font-weight:700;text-transform:capitalize}
.skladnik-liczba{font-family:var(--dane);font-size:.64rem;color:var(--cichy);white-space:nowrap}
.skladnik-oswiadczenie{margin:0;padding:0 0 0 11px;border-left:2px solid var(--lazur);
  font-size:.86rem;line-height:1.5;color:var(--atrament)}
.skladnik-warunek{margin:0;font-size:.74rem;color:var(--cichy);line-height:1.45}
.skladnik-zrodlo{margin:0;font-size:.72rem;color:var(--cichy)}
.skladnik-zrodlo a{color:var(--lazur)}

.cel-produkty{margin-bottom:16px}
.cel-produkty-ile{font-family:var(--dane);font-size:.68rem;font-weight:500;color:var(--cichy);
  text-transform:none;letter-spacing:0}

/* Grid- i flex-item maja domyslnie min-width:auto, wiec obrazek produktu i
   marka pisana jednym slowem bez spacji ("ALLNUTRITION") blokowaly skurczenie
   kolumny na waskim ekranie mimo 1fr i mimo max-width:100% na img. Scoped
   tylko do tej sekcji, zeby nie zmieniac zachowania .kafel na innych stronach. */
.cel-produkty .siatka > .kafel{min-width:0}
.cel-produkty .kafel-tresc,.cel-produkty .kafel-tresc > *{min-width:0}
.cel-produkty .marka-p,.cel-produkty .nazwa{overflow-wrap:anywhere}

/* U41: pasek "Wybrano N produktow do porownania" (styl.css, poza mandatem
   tego zlecenia, wspolny z index.html) jest position:fixed nad dolem ekranu
   i zaslaniał ostatni rzad kafli celu, gdy w sesji byl juz jakis wybor z
   /produkty. cele.html dodaje klase na <body>, kiedy pasek jest widoczny
   (odswiezPasekPorownania). Wysokosc rezerwy liczona z paska: padding
   12px*2 + tekst ~20px + bottom:18px ~= 74px, plus margines na oddech. */
body.cele-ma-pasek-porownaj .cele-siatka-kafli{padding-bottom:90px}

/* U5: skladniki z oswiadczeniem dla wybranych celow, pod siatka kafli.
   Karta w tym samym jezyku wizualnym co .wynik-lista/.wynik-pozycja z kroku
   3 (border, tlo karty), zeby caly wywiad wygladal spojnie, ale wlasny
   prefiks .cele-edukacja*, bo to inny ksztalt danych (lista skladnikow per
   cel, nie per wywiad) i zyje na innym kroku. */
.cele-edukacja:empty{display:none}
.cele-edukacja{margin-top:24px}
.cele-edukacja h2{font-size:1rem;margin-bottom:12px}
.cele-edukacja-cel{background:var(--karta);border:1px solid var(--kreska);
  border-radius:var(--r);padding:16px 18px;margin-bottom:12px}
.cele-edukacja-cel:last-child{margin-bottom:0}
.cele-edukacja-cel h3{font-size:.92rem;margin:0 0 12px}
.cele-edukacja-lista{display:flex;flex-direction:column;gap:14px}
/* Dwie kolumny od 900 px, ale dopiero od trzeciego skladnika: przy jednym albo
   dwoch siatka zostawialaby pusta polowe wiersza, czyli dokladnie te biala
   przestrzen, ktora ten uklad ma usuwac (zgloszenie Bartosza 23.09: przy celu
   z kilkunastoma skladnikami lista ciagnela sie przez pol ekranu, a zdanie
   warunku stosowania bieglo przez 1106 px od lewej do prawej). :has liczy
   dzieci bez pomocy JS, a przegladarka bez :has dostaje dotychczasowa kolumne,
   wiec degradacja jest bezpieczna. */
@media (min-width:900px){
  .cele-edukacja-lista:has(> .cele-edukacja-skladnik:nth-child(3)){
    display:grid;grid-template-columns:repeat(2,1fr);gap:20px 28px;align-items:start}
}
.cele-edukacja-skladnik{display:flex;gap:14px;align-items:flex-start}
/* 66 px zamiast 44 (poltora raza, polecenie Bartosza): w dwoch kolumnach kafel
   jest wezszy, wiec tekst ma wiecej linii i mniejsza miniatura wisiala przy
   samej gorze bloku tekstu. */
.cele-edukacja-obraz{display:block;width:66px;height:66px;flex:0 0 66px;
  border-radius:var(--r);object-fit:cover;background:var(--tlo)}
.cele-edukacja-tresc{display:flex;flex-direction:column;gap:4px;min-width:0}
.cele-edukacja-nazwa{font-weight:700;font-size:.9rem}
/* Cytat doslowny z rejestru UE (CLAUDE.md zasada 4: wolno cytowac oswiadczenie,
   nie wolno dopisac wlasnego zdania o dzialaniu): ta sama forma wizualna co
   .wynik-oswiadczenie z kroku 3 (border po lewej, kolor stonowany), zeby
   uzytkownik rozpoznal cytat po ksztalcie, nie tylko po cudzyslowie w tekscie. */
.cele-edukacja-oswiadczenie{margin:0;padding:0 0 0 11px;border-left:2px solid var(--lazur);
  font-size:.86rem;line-height:1.5;color:var(--atrament)}
/* Wspolne skladniki wielu celow: jedna grupa "chip celu + jego cytat(y)" na
   kazdy cel (zlecenie wlasciciela 23.09 druga runda: chip ma stac PRZY
   cytacie, ktory opisuje, nie zbiorczo nad wszystkimi). Chip dostaje mala
   przerwe pod soba, cytat wlasny odstep gora zamiast odziedziczonego
   marginesu .cele-edukacja-oswiadczenie, zeby grupy nie zlewaly sie wizualnie. */
.cele-edukacja-grupa-celu{display:flex;flex-direction:column;gap:4px}
.cele-edukacja-grupa-celu:not(:first-child){margin-top:10px}
.cele-edukacja-grupa-celu .plakietka-tag{align-self:flex-start}
.cele-edukacja-naglowek-drugi{margin-top:24px}

/* Druga warstwa dowodu POD sekcja oswiadczen rejestrowych, ten sam wpis
   #celeEdukacja (brief "Karuzela wiedzy i dowody przy celu", 23.09; poprawki
   tego samego dnia wieczorem: skrocenie tresci i grupowanie po substancji,
   patrz cele.html). Karta listy w jezyku wizualnym .oswiadczenie z
   substancja.css, plakietka poziomu to kopia .tag-dowod z roslinne.css (ta
   sama skala poziom_dowodu w calym serwisie): wlasny prefiks .cel-dowod-*,
   bo cele.html nie laduje zadnego z tamtych dwoch plikow. */
.cel-dowod-lista{list-style:none;padding-left:0;display:flex;flex-direction:column;gap:10px;margin:12px 0 0}
.cel-dowod-poz{padding:11px 13px;border:1px solid var(--kreska);border-radius:var(--r);background:var(--karta)}
.cel-dowod-poz .cele-edukacja-nazwa{display:block;margin-bottom:4px}
.cel-dowod-poz p{margin:0 0 4px;font-size:.88rem}
/* Substancja z wiecej niz jednym wierszem dowodowym (dwa wybrane cele naraz
   dajace osobny wiersz tej samej substancji): kazdy wpis dostaje kreske u
   gory oprocz pierwszego, zeby bylo widac, ze to OSOBNE zrodlo, nie dalszy
   ciag tego samego zdania. */
.cel-dowod-wpis{margin-top:8px;padding-top:8px;border-top:1px solid var(--kreska)}
.cel-dowod-wpis:first-of-type{margin-top:0;padding-top:0;border-top:0}
.cel-dowod-tag{display:inline-block;max-width:100%;box-sizing:border-box;padding:2px 8px;
  border-radius:var(--r);font-size:.68rem;font-weight:600;line-height:1.35;margin-bottom:6px}
.cel-dowod-tag.n5,.cel-dowod-tag.n4{background:var(--zielen-tlo);color:var(--zielen)}
.cel-dowod-tag.n3{background:var(--lazur-tlo);color:var(--lazur)}
.cel-dowod-tag.n2{background:var(--uwaga-tlo);color:var(--uwaga)}
.cel-dowod-tag.n1,.cel-dowod-tag.n0{background:var(--papier-2);color:var(--cichy)}
/* Rozwiniecie reszty zdania i lista "pozostale substancje": natywny
   <details>, zero JS do otwierania/zamykania (zlecenie: sekcja byla za
   dluga, wiec dodatkowa tresc ma zostac schowana do interakcji, nie
   doliczona do wysokosci od razu). */
.cel-dowod-rozwin{margin:0 0 6px}
.cel-dowod-rozwin summary{cursor:pointer;font-size:.78rem;color:var(--lazur);font-weight:600}
.cel-dowod-rozwin summary:hover{text-decoration:underline}
.cel-dowod-rozwin p{margin:6px 0 0;font-size:.88rem}
.cel-dowod-rozwin-lista{margin-top:2px}
.cel-dowod-rozwin-lista summary{cursor:pointer;font-size:.83rem;color:var(--lazur);font-weight:600}
.cel-dowod-rozwin-lista summary:hover{text-decoration:underline}
/* .cel-dowod-lista ma wlasny display:flex (wyzej), a jawna deklaracja display
   w arkuszu autora bije domyslna regule przegladarki, ktora chowa tresc
   zamknietego <details> (origin autora > origin User-Agent, niezaleznie od
   specyficznosci) -- bez tej pary regul lista "pozostale" bylaby widoczna od
   razu, mimo zamknietego <details>. Zauwazone Playwrightem: offsetParent
   ukrytej pozycji nie byl null, choc <details> nie mial atrybutu open. */
.cel-dowod-rozwin-lista .cel-dowod-lista{display:none;margin-top:10px}
.cel-dowod-rozwin-lista[open] .cel-dowod-lista{display:flex}
.cel-dowod-zrodlo{display:block;font-size:.72rem;color:var(--cichy);text-decoration:none}
a.cel-dowod-zrodlo{color:var(--lazur)}
a.cel-dowod-zrodlo:hover{text-decoration:underline}

/* Karuzela wiedzy pod skladnikami, POD #celeEdukacja (element osobny, nie
   wewnatrz): pula rotujacych blokow /api/bloki, ten sam jezyk wizualny co
   .cele-edukacja-cel (tlo, obwodka, promien), wlasny prefiks .cele-karuzela-*
   zeby nie mieszac sie z .hp-* z hero strony glownej, ktore liczy ta sama
   pula danych, ale osobnym mechanizmem front-endowym. */
.cele-karuzela{background:var(--karta);border:1px solid var(--kreska);
  border-radius:var(--r);padding:16px 18px;margin-top:24px}
.cele-karuzela:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
.cele-karuzela>.eyebrow{display:block;margin-bottom:10px}
.cele-karuzela-blok{display:flex;flex-direction:column;gap:10px;transition:opacity .6s ease}
.cele-karuzela-znika{opacity:0}
.cele-karuzela-naglowek{display:block;font-size:.92rem;font-weight:700}
.cele-karuzela-tresc{display:flex;flex-direction:column;gap:8px}
.cele-karuzela-tresc p{margin:0;padding-top:8px;border-top:1px solid var(--kreska);font-size:.86rem;line-height:1.5}
.cele-karuzela-tresc p:first-child{border-top:none;padding-top:0}
.cele-karuzela-liczba{font-family:var(--dane)}
.cele-karuzela-liczba.dziesietna{font-family:inherit;font-weight:600;font-variant-numeric:tabular-nums}
.cele-karuzela-stopka{margin:0;font-size:.71rem;color:var(--cichy);line-height:1.4}

@media (max-width:560px){
  .siatka-cele{grid-template-columns:1fr;gap:8px}
  .lista-skladnikow{grid-template-columns:1fr}
  /* Kafel z pionu (zdjecie 16:9 + tekst pod nim) na wiersz: ikona 40px po
     lewej, tekst obok. Dotyczy /rosliny, ktorego ten kafel dziala tak od
     dawna (kafel-roslina nie ma obrazu wcale, wiec kolumna "img" zostaje
     pusta - istniejace zachowanie, poza mandatem tego zlecenia). Grid zamiast
     flex, bo pozwala ulozyc dzieci .kafel-cel w kolumny bez zmiany kolejnosci
     w znaczniku. */
  .kafel-cel{display:grid;grid-template-columns:40px 1fr;
    grid-template-areas:"img nazwa" "img opis" "img liczba";
    column-gap:10px;row-gap:2px;padding:9px 12px}
  .kafel-cel>*{padding-left:0;padding-right:0}
  .kafel-cel-nazwa{grid-area:nazwa}
  .kafel-cel-opis{grid-area:opis;font-size:.76rem;line-height:1.35;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .kafel-cel-liczba,.kafel-cel-brak{grid-area:liczba;margin-top:0;padding-top:0;
    display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}

  /* Kafel celu na /cele: dwie kolumny, nie jedna pelnej szerokosci (bez
     zdjecia miesci sie wiecej w rzedzie, zlecenie 23.09), i bez ikony 40px z
     reguly ogolnej wyzej - nie ma juz obrazu, ktory ta ikona zastepowala.
     Obie reguly maja wyzsza specyficznosc (0,2,0) niz .siatka-cele/.kafel-cel
     same (0,1,0), wiec wygrywaja mimo ze stoja pozniej w tym samym pliku. */
  .siatka-cele.cele-siatka-kafli{grid-template-columns:repeat(2,1fr)}
  /* Wnetrze wezsze o dwa piksele z kazdej strony niz na starcie (bylo 12):
     przy kaflu 164 px kazdy piksel wraca do tekstu, a nazwa celu jest tu
     jedyna trescia, wiec nie ma o co konkurowac. */
  .cele-siatka-kafli .kafel-cel{display:flex;flex-direction:column;gap:4px;padding:10px 10px 11px}
  .cele-siatka-kafli .kafel-cel-glowa{margin-top:0}
  .cele-siatka-kafli .kafel-cel-nazwa{font-size:.86rem}
  .cele-siatka-kafli .kafel-cel-brak{font-size:.72rem}
}

/* Przekroczenie gornej granicy EFSA. Osobny komunikat, nie sam kolor: to inna
   informacja niz wysoki procent RWS, ktory w suplementach jest normalny. */
.ponad-norme{display:inline-block;margin-top:3px;font-size:.66rem;color:var(--uwaga);
  background:var(--uwaga-tlo);padding:2px 6px;border-radius:var(--r);font-weight:600}
/* Wysoki procent RWS bez ustalonej gornej granicy: inny sygnal niz .ponad-norme
   powyzej, wiec inny, neutralny kolor. Wysoki procent sam w sobie nie jest
   zarzutem (notes/MODEL-DANYCH.md: witamina B12 przy 38 000 procent to norma),
   wiec ten znacznik nie ma prawa wygladac jak alarm. */
.wysoki-rws{display:inline-block;margin-top:3px;font-size:.66rem;color:var(--atrament-2);
  background:var(--papier-2);padding:2px 6px;border-radius:var(--r)}

.za-zawartosc{font-family:var(--dane);font-size:.72rem;color:var(--atrament);margin-top:4px}
.za-zawartosc b{font-size:.86rem;font-weight:600}
.za-zawartosc.brak{color:var(--cichy);font-size:.66rem}
/* U32: pokrycie zalecanej dziennej dawki na kaflu. Rysowana WYLACZNIE gdy
   API poda oba skladniki liczby (26 ze 191 substancji ma ustalona norme),
   wiec sam kolor neutralny -- nieobecnosc elementu, nie zero, jest tu
   odpowiedzia dla reszty katalogu. */
.rws-pokrycie{font-family:var(--dane);font-size:.68rem;color:var(--cichy);margin-top:2px}

/* ============================================================
   Blok: sciezka "nie wiem od czego zaczac" jako cztery kroki
   (serwer/cele.py, endpoint /api/cele/wynik; serwer/statyczne/cele.html).
   Dopisany na koncu, zeby nie ruszac kaskady istniejacych regul. Klasy
   wzorowane na makieta/porownywarka-v1.html (.steps, .field, .opt, .item,
   .two, .tag), przemianowane z prefiksem cele-/wywiad-/wynik-, zeby nie
   kolidowaly z niczym istniejacym w tym pliku.
   ============================================================ */

/* Pasek kroków ma dzis postac kolek z linia (styl w cele.html), a nie
   zakladek z podkresleniem, jak w pierwszej wersji. Reguly zakladek zostaly
   tu po tamtej wersji i nadal trafialy w te same elementy: dokladaly kazdemu
   spanowi w pasku padding 7px 13px i dolna krawedz 2px. Skutek byl widoczny
   na telefonie i trudny do zrozumienia: kolka wychodzily elipsami (28 na 26
   pikseli zamiast 26 na 26), a cyfry siedzialy ponizej srodka. Martwy kod w
   kaskadzie nie jest neutralny: tutaj przez kilka dni psul element, ktorego
   nikt nie podejrzewal, bo jego wlasny styl wygladal poprawnie. */

/* stan wybrania na kaflu celu z siatki-cele: ten sam kafel co na dawnym
   ekranie nawigacji, tylko z dodatkowym stanem aria-pressed */
.kafel-cel[aria-pressed="true"]{border-color:var(--atrament);background:var(--papier-2)}
/* Znacznik zaznaczenia stal dawniej w tekscie nazwy (spacja nierozdzielajaca
   plus "✓" doklejone do napisu), wiec zaznaczenie zmienialo dostepna
   szerokosc tekstu: przy dluzszych nazwach ("Koncentracja i pamięć", "Energia
   i zmęczenie") napis lamal sie na dodatkowy wiersz i caly rzad kafli rosl w
   momencie klikniecia (zgloszenie mobilne 26.09, telefon, punkt 2, zmierzone
   plywright: wysokosc nazwy 21,3px -> 42,7px po zaznaczeniu). Znacznik jest
   teraz kropka w rogu kafla, pozycjonowana absolutnie wzgledem .kafel-cel
   (position:relative wyzej): nie nalezy do przeplywu tekstu, wiec nie moze
   zmienic jego zawijania. Padding w .cele-siatka-kafli .kafel-cel-nazwa jest
   zarezerwowany ZAWSZE, takze bez zaznaczenia, zeby sama obecnosc znacznika w
   rogu (gdy stan sie zmienia) nie zaslaniala ostatnich liter najdluzszych
   nazw. Ksztalt (kolko), nie sam kolor tla kafla, niesie informacje o stanie:
   wymog dostepnosci z tego samego zlecenia. */
.cele-siatka-kafli .kafel-cel-nazwa{padding-right:18px}
.kafel-cel[aria-pressed="true"]::after{content:"✓";position:absolute;top:10px;right:10px;
  width:16px;height:16px;line-height:16px;text-align:center;border-radius:50%;
  background:var(--zielen);color:#fff;font-size:.62rem;font-weight:700}

/* Pasek "Wyczysc wybor / Dalej" nad siatka kafli (krok 1, /cele): dwa
   wewnetrzne wiersze o stalej wysokosci (info, potem akcje), ZAWSZE oba
   obecne w ukladzie, niezaleznie od liczby zaznaczonych celow. Przed 26.09
   oba przyciski w drugim wierszu byly [hidden] (display:none) przy zerze
   zaznaczonych i wskakiwaly w uklad po pierwszym wyborze, co na telefonie
   dokladalo caly wiersz i spychalo siatke kafli o wysokosc tego wiersza w
   dol pod palcem uzytkownika (zgloszenie mobilne 26.09, punkt 1). */
.cele-pasek{display:flex;flex-direction:column;gap:8px;margin-bottom:12px;font-size:.83rem}
.cele-pasek b{font-family:var(--dane);font-weight:600}
.cele-pasek-info{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cele-pasek .cele-podpowiedz{color:var(--cichy)}
/* Wyrownanie do prawej (zgloszenie 27.09): przycisk "Dalej" stal przesuniety,
   bo niewidoczny "Wyczysc wybor" zajmuje miejsce po jego lewej. */
.cele-pasek-akcje{display:flex;align-items:center;gap:12px;justify-content:flex-end}
/* "Wyczysc wybor" niewidoczny przy zerze zaznaczonych przez visibility, nie
   przez display:none: zajmuje swoje miejsce w wierszu, wiec jego pojawienie
   sie nie zmienia wysokosci paska. Domyslnie (bez klasy .widoczny) jest
   niewidoczny, bo krok 1 zaczyna sie od zera zaznaczonych celow.
   line-height jako liczba (nie dziedziczone "normal" z UA-stylesheet
   przegladarki dla <button>) z tego samego powodu co przy .cele-btn-dalej w
   cele.html: strzalka "→" w tekscie sasiedniego przycisku nie zyje w foncie
   strony (fonty.css) i przegladarka dobiera dla niej font zastepczy o innych
   metrykach, co bez wlasnej wartosci podnosilo wysokosc przycisku o 1 px w
   momencie zmiany tekstu z "Wybierz cel..." na "Dalej z N celem →"
   (zmierzone: 32px -> 33px) i przez flex przenosilo sie na caly pasek,
   spychajac siatke kafli. */
#celeWyczysc{visibility:hidden;font-size:.79rem;color:var(--lazur);font-weight:600;
  background:none;border:0;cursor:pointer;padding:4px;line-height:1.3}
#celeWyczysc.widoczny{visibility:visible}
/* "Dalej" w gornym pasku stoi zawsze, tez przy zerze zaznaczonych (jako
   przygaszony, aria-disabled): tekst dla stanu pustego jest celowo krotki
   ("Wybierz cel, żeby przejść dalej" miesci sie w jednym wierszu obok
   "Wyczysc wybor" przy 390 px, zmierzone), zeby zmiana tresci miedzy 0 a N
   zaznaczonymi nie przenosila przycisku do nowego wiersza. line-height stalej
   przycisku samej (nie tylko rezerwowanie w tym pliku): styl.css koncentruje
   sie na kolorze i wymiarach, wlasciwa wartosc line-height stoi przy
   .cele-pasek .cele-btn-dalej w cele.html, obok reszty jego wygladu. */
.cele-pasek-akcje .cele-btn-dalej[aria-disabled="true"]{opacity:.45;cursor:not-allowed}

.krok-akcje{display:flex;gap:10px;flex-wrap:wrap;margin-top:24px;align-items:center}
.cele-btn{display:inline-flex;align-items:center;gap:7px;padding:11px 18px;border-radius:var(--r);
  border:1px solid var(--atrament);background:var(--atrament);color:var(--karta);font:inherit;
  font-weight:600;font-size:.88rem;cursor:pointer}
.cele-btn:hover{background:var(--lazur);border-color:var(--lazur)}
/* R8: krok1Dalej przeszedl z disabled natywnego na aria-disabled (ten sam
   mechanizm co krok1DalejGora, patrz cele.html), wiec wyglad przygaszony
   musi reagowac na oba. */
.cele-btn:disabled,.cele-btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.cele-btn.ghost{background:transparent;color:var(--atrament);border:1px solid var(--kreska)}
.cele-btn.ghost:hover{background:var(--karta);border-color:var(--atrament)}

.wywiad-karta{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r)}
.wywiad-pole{padding:17px 19px;border-bottom:1px solid var(--kreska);display:flex;
  flex-direction:column;gap:10px}
.wywiad-pole:last-child{border-bottom:0}
.wywiad-pole .lab{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.wywiad-pole label{font-weight:600;font-size:.92rem}
.wywiad-jednokrotny{display:flex;flex-wrap:wrap;gap:6px}
.wywiad-jednokrotny button{padding:7px 13px;border-radius:var(--r);border:1px solid var(--kreska);
  font-size:.84rem;background:var(--papier);cursor:pointer;font:inherit;color:inherit}
.wywiad-jednokrotny button:hover{border-color:var(--atrament)}
.wywiad-jednokrotny button[aria-pressed="true"]{background:var(--atrament);color:var(--karta);
  border-color:var(--atrament);font-weight:600}
.wywiad-chipy{display:flex;flex-wrap:wrap;gap:6px}
.cele-skip{font-size:.75rem;color:var(--lazur);text-decoration:underline;text-underline-offset:2px;
  background:none;border:0;cursor:pointer;font:inherit}
.cele-nota-pomin{font-size:.78rem;color:var(--uwaga);background:var(--uwaga-tlo);
  border-left:2px solid var(--uwaga);padding:8px 10px;border-radius:var(--r)}
.cele-nota-pomin.hidden{display:none}

/* Od 23.09 kolumny stoja JEDNA NAD DRUGA, nie obok siebie (polecenie Bartosza).
   Powod jest rzeczowy, nie estetyczny: lista odpadow ma zwykle dwie albo trzy
   pozycje, a lista dobranych kilkanascie, wiec przy dwoch kolumnach obok siebie
   prawa konczyla sie po trzech wierszach i dalej ciagnela sie pusta ramka przez
   pol ekranu. Wykluczenia sa wazniejsze (zasada twarda nr 1), wiec ida na gore
   na pelna szerokosc, a dobrane pod nimi rozkladaja sie na dwie kolumny pozycji
   (.wynik-lista-dobrane nizej). */
.wynik-kolumny{display:grid;grid-template-columns:1fr;gap:16px;
  align-items:start;margin-bottom:8px}
.wynik-lista{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r)}
.wynik-lista h3{padding:13px 15px;display:flex;align-items:center;gap:8px;
  border-bottom:1px solid var(--kreska);font-size:.86rem}
@media (min-width:900px){
  .wynik-lista-dobrane .wynik-lista-tresc{display:grid;grid-template-columns:repeat(2,1fr)}
  /* Kreska dolna zostaje tylko pod PARAMI: w dwoch kolumnach ostatnie dwie
     pozycje sa przedostatnia i ostatnia, wiec :last-child samo nie wystarcza. */
  .wynik-lista-dobrane .wynik-lista-tresc > .wynik-pozycja:nth-child(odd){border-right:1px solid var(--kreska)}
  .wynik-lista-dobrane .wynik-lista-tresc > .wynik-pozycja:nth-last-child(2):nth-child(odd){border-bottom:0}
}
/* height:100%: w kroku 3 kolumna "dobrane" jest siatka dwoch kolumn od 900 px
   (.wynik-lista-dobrane nizej), a grid domyslnie rownuje wysokosc obu kart w
   parze. Stopka skladnika (margin-top:auto, patrz .wynik-skladnik-stopka)
   korzysta z tej rozciagnietej wysokosci, zeby przycisk "Zobacz produkty"
   stanal w prawym dolnym rogu KAZDEJ karty, nie tylko tej krotszej tresciowo.
   Bez wplywu na kolumne "odpada" (jedna kolumna, brak siatki nadrzednej). */
.wynik-pozycja{padding:15px 17px;border-bottom:1px solid var(--kreska);display:flex;
  flex-direction:column;gap:4px;height:100%}
.wynik-pozycja:last-child{border-bottom:0}
.wynik-pozycja .t{font-weight:600;font-size:.92rem;display:flex;justify-content:space-between;
  gap:10px;align-items:baseline;flex-wrap:wrap}
.wynik-pozycja .r{font-size:.83rem;color:var(--cichy);line-height:1.45}
.wynik-pozycja-odpada .t{text-decoration:line-through;text-decoration-color:var(--stop);
  text-decoration-thickness:1.5px}
.wynik-pozycja-odpada .r{color:var(--stop)}
.wynik-dawka{font-family:var(--dane);font-size:.76rem;color:var(--cichy);white-space:nowrap;
  font-weight:400}
.wynik-oswiadczenie{margin:0;font-size:.78rem;color:var(--atrament-2);line-height:1.45}

/* U13 do U16: zdjecie, link do karty skladnika, link do produktow i przycisk
   ulubionych na kazdej pozycji skladnika w kroku 3. Wrapper osobny od .t
   (ktory zostaje justify-content:space-between miedzy nazwa a dawka), zeby
   obraz i przycisk stanely PRZY tym wierszu, nie WEWNATRZ niego. */
.wynik-skladnik-glowa{display:flex;align-items:center;gap:10px}
.wynik-skladnik-glowa .t{flex:1;min-width:0}
/* 52 px zamiast 32 (polecenie Bartosza: poltora raza albo wiecej). Wiersze
   pod glowa dostaja wciecie rownie szerokosci obrazu plus odstep, zeby tekst
   zaczynal sie w jednej linii z nazwa skladnika, a nie pod miniatura. */
.wynik-pozycja .r,.wynik-oswiadczenie{padding-left:64px}
.wynik-pozycja-odpada .r{padding-left:0}
.wynik-skladnik-obraz{display:block;width:52px;height:52px;flex:0 0 52px;
  border-radius:var(--r);object-fit:cover;background:var(--tlo)}
.wynik-skladnik-link{color:inherit;text-decoration:none}
.wynik-skladnik-link:hover{text-decoration:underline}
/* Chipy celow zamiast dawnego zdania "Pod: X, Y." (zlecenie wlasciciela,
   23.09 druga runda): sama forma co .cele-edukacja-plakietki z kroku 1. */
.wynik-skladnik-cele{padding-left:64px;display:flex;flex-wrap:wrap;gap:6px}
/* Stopka na dole kafla (margin-top:auto, patrz height:100% przy .wynik-pozycja
   wyzej): liczba produktow po lewej w tym samym wcieciu co reszta tresci,
   przycisk "Zobacz produkty" przy prawej krawedzi karty, nie w srodku zdania. */
.wynik-skladnik-stopka{margin-top:auto;padding-top:4px;display:flex;
  align-items:center;justify-content:space-between;gap:10px}
/* Przycisk, nie odnosnik ze strzalka (polecenie Bartosza 23.09): to jedyne
   wyjscie z tej pozycji do produktow, wiec ma wygladac na klikalne z odleglosci.
   Zielen, nie lazur, bo w tej kolumnie zielen juz znaczy "dobrane pod twoje
   cele" (plakietka nad lista) i przycisk trzyma sie tego samego znaczenia.
   Kontrast bieli na --zielen: 5,2:1, czyli ponad wymagane 4,5. flex:0 0 auto:
   przy dlugiej liczbie produktow tekst obok (.r) ma prawo zawinac sie na
   dwie linie, przycisk nie moze sie przy tym scisnac. */
.wynik-skladnik-produkty{display:inline-block;flex:0 0 auto;padding:5px 12px;
  background:var(--zielen);color:var(--karta);border-radius:var(--r);font-weight:600;
  font-size:.78rem;text-decoration:none;white-space:nowrap}
.wynik-skladnik-produkty:hover{background:var(--atrament);text-decoration:none}
.plakietka-tag{display:inline-block;padding:2px 7px;border-radius:var(--r);font-size:.7rem;
  font-weight:600}
.plakietka-tag.ok{background:var(--zielen-tlo);color:var(--zielen)}
.plakietka-tag.critt{background:var(--stop-tlo);color:var(--stop)}
.plakietka-tag.info{background:var(--lazur-tlo);color:var(--lazur)}

@media (max-width:560px){
  .wynik-kolumny{grid-template-columns:1fr}
}

/* Watek C briefu "dwie sekcje wyniku" (notes/BRIEF-DWIE-SEKCJE.md, D29):
   podzial warstwy rejestrowej kroku 4 na "Jeden preparat na kilka celow
   naraz" i "Osobno na kazdy cel". Prefiks pokrycie-, zeby nie kolidowac
   z wynik-* z kroku 3: inny ekran, inny ksztalt danych mimo podobnego
   wygladu karty. */
.warstwa-rejestr h3{font-size:.94rem;margin:20px 0 6px}
.pokrycie-nota{margin-bottom:14px}
.pokrycie-wszystko-albo-nic{margin-bottom:16px}

/* Karta wariantu A (D35, decyzja wlasciciela na podstawie
   makieta/cele-kompleksowe.html, sekcja #wariantA): kazda karta jest wlasnym
   kaflem z ramka i radiusem (jezyk wizualny .kafel), nie wierszem we wspolnej
   liscie jak poprzednia wersja -- std siatka gap zamiast obwodki miedzy
   sasiadami upraszcza kod i skraca karte na mobile (przed: ~700px, cel: tyle
   co w makiecie, 323px na pierwszej karcie). Dwie kolumny od 1000px, ten sam
   prog co reszta warstwy rejestrowej wyzej w tym pliku. */
.kompl-lista{display:grid;grid-template-columns:1fr;gap:12px;margin-bottom:14px}
@media (min-width:1000px){
  .kompl-lista{grid-template-columns:repeat(2,1fr)}
}
.kompl-karta{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  padding:13px 15px;display:flex;flex-direction:column;gap:9px}

/* Glowa: miniatura, producent+nazwa (rosnie), koszt dnia i przycisk "Sprawdz
   ceny" w JEDNYM wierszu (brief D35, punkt 1 -- "obok koszt dnia i przycisk"),
   nie w osobnej stopce jak poprzednia wersja karty. */
.kompl-glowa{display:flex;align-items:flex-start;gap:10px}
/* all:unset+flex column: przycisk otwiera karte produktu (.otworz-wiersz,
   ten sam delegowany listener co reszta strony), ale ma wygladac jak zwykly
   blok tekstu, nie jak przycisk. min-height 24px: cel dotykowy. */
.kompl-id{all:unset;cursor:pointer;display:flex;flex-direction:column;gap:1px;
  flex:1;min-width:0;text-align:left;min-height:24px}
.kompl-id:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
/* Zwykla pisownia producenta: .marka-p-zwykla (juz w tym pliku), bez
   text-transform -- dane bywaja wersalikami w bazie (dlug E2), nie poprawiane
   tutaj ani w skrypcie. */
.kompl-id .marka-p-zwykla{font-family:var(--dane);font-size:.62rem;color:var(--cichy)}
.kompl-nazwa{font-weight:600;font-size:.92rem;line-height:1.3}
.kompl-cena{flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:6px}
.kompl-koszt{font-size:.83rem;color:var(--atrament-2);white-space:nowrap}
.kompl-sprawdz{all:unset;cursor:pointer;padding:6px 14px;background:var(--zielen);
  color:var(--karta);border-radius:var(--r);font-weight:600;font-size:.78rem;white-space:nowrap}
.kompl-sprawdz:hover{background:var(--atrament)}
.kompl-sprawdz:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}

.kompl-naglowek{margin:0;font-weight:700;font-size:.88rem}

/* Jeden wiersz na cel (D35): chip celu w jego kolorze, sklad, dawka, procent
   normy. Cel niepokryty albo bez skladnika dobijajacego do pelnej normy
   dostaje szary chip (.kompl-chip-brak) -- kolor sam nie wystarcza jako
   jedyny nosnik informacji (osoby z zaburzeniami widzenia barw). */
.kompl-cele-lista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.kompl-cel-wiersz{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
/* Chip PLASKI: bez obrysu, bez cursor:pointer, klasa inna niz klikalny
   .pfl-chip paska filtrow -- nie da sie pomylic jednego z drugim. Kolor per
   cel idzie inline (var(--cel-<kod>-tlo/-tekst) ustawiane przez skrypt),
   zeby dodanie jedenastego celu nie wymagalo nowej klasy CSS. */
.kompl-chip{display:inline-block;flex:0 0 auto;padding:2px 8px;border-radius:var(--r);
  font-size:.72rem;font-weight:600;line-height:1.5;white-space:nowrap}
.kompl-chip-brak{background:var(--papier-2);color:var(--cichy)}
.kompl-skladnik{font-size:.84rem;color:var(--atrament-2)}
.kompl-skladnik b{font-weight:600;color:var(--atrament)}
/* Skladnik ponizej normy (D35, poprawka wlasciciela): dopisek wyszarzony,
   NIGDY jako jedyne pokrycie przy kolorowym chipie -- tylko obok skladnika,
   ktory faktycznie dobija do 100% normy, albo samodzielnie przy szarym chipie
   gdy zaden skladnik celu nie dobija. */
.kompl-skladnik-brak,.kompl-tekst-brak,.kompl-tekst-duplikat{font-size:.84rem;color:var(--cichy);
  font-style:italic}

.kompl-kategoria{margin:2px 0 0;font-size:.78rem;color:var(--cichy);border-top:1px solid var(--kreska);
  padding-top:8px}
.kompl-kategoria i{font-style:normal;color:var(--atrament-2)}
.kompl-kategoria-etykieta{color:var(--cichy)}
.kompl-kategoria-brak i{color:var(--cichy);font-style:italic}

/* ============================================================
   Krok 4 sciezki celow w zakladkach (D37): naglowek z odrzuconymi,
   zakladki "Jeden preparat" / "Zestaw" / "Osobno", karta zestawu (D36).
   Dawna osobna sekcja "Poza rejestrem UE" (D25, warstwa druga) zniknela w
   D38: te produkty sa dzis kartami z flaga wewnatrz "Osobno". Wzorzec
   wizualny 1:1 z makieta/cele-krok4-zakladki.html (27.09, do akceptacji),
   z prefiksem k4- na elementach zakladek zamiast .tab- z makiety, zeby nie
   mieszac ich z .tab-produkt/.tab-porownaj juz uzywanymi na tej samej
   stronie przez tabela-porownania.js.
   ============================================================ */

.odrzucone-info{margin:8px 0 0;font-size:.88rem;color:var(--atrament-2)}
.odrzucone-info b{color:var(--atrament)}
.link-guzik{all:unset;cursor:pointer;color:var(--lazur);text-decoration:underline;font-size:inherit}
.link-guzik:hover{color:var(--atrament)}
.link-guzik:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
.odrzucone-lista{margin-top:10px;display:flex;flex-direction:column;gap:8px}
.odrzucone-pozycja{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  padding:9px 12px;font-size:.82rem}
.odrzucone-pozycja b{display:block;font-weight:600;margin-bottom:2px}
.odrzucone-pozycja .powod{color:var(--stop)}

/* Zakladki w ukladzie teczki (role=tablist), rewizja D38: etykieta niesie
   koszt pokrycia WSZYSTKICH wybranych celow ta forma, zeby trzy sposoby
   porownac bez przelaczania (D37). Zakladka bez wyniku dostaje aria-disabled
   i .k4-tab-wyszarzona.

   Aktywna zakladka i panel dziela to samo tlo (var(--karta)) i te sama
   ramke (var(--kreska)): aktywna zakladka ma ramke z trzech stron, bez dolnej
   (border-bottom-color = tlo karty), i zachodzi na gorna ramke panelu o 1px
   (margin-bottom:-1px, z-index), wiec obie plaszczyzny sklejaja sie w jedna
   figure zamiast dawnego grubego dolnego paska. Nieaktywne sa plaskie (bez
   tla), a ich dolna krawedz to ta sama linia co gorna ramka panelu
   (border-bottom:1px solid var(--kreska) na bazowej klasie, wspolna dla obu
   stanow zeby wysokosc przycisku nie skakala przy przelaczeniu). */
.k4-tab-lista{display:flex;gap:8px}
.k4-tab-przycisk{all:unset;box-sizing:border-box;cursor:pointer;flex:1 1 0;min-width:0;text-align:center;
  padding:9px 8px;border:1px solid transparent;border-bottom:0;
  border-radius:var(--r) var(--r) 0 0;font-size:.86rem;font-weight:600;color:var(--cichy);
  min-height:44px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}
.k4-tab-przycisk small{font-weight:400;font-size:.74rem;color:var(--cichy)}
.k4-tab-przycisk[aria-selected="true"]{color:var(--atrament);background:var(--karta);
  border-color:var(--kreska);border-bottom-color:var(--karta);position:relative;z-index:1;margin-bottom:-1px}
.k4-tab-przycisk[aria-selected="true"] small{color:var(--atrament-2)}
/* Hover tylko na urzadzeniach z kursorem i tylko na nieaktywnej: iOS po
   dotknieciu zostawia :hover przyklejony, przez co wybrana zakladka szarzala
   i odcinala sie od panelu (zgloszenie 27.09). Linie pod nieaktywnymi daje
   gorna ramka panelu, nie wlasny border-bottom (byla podwojna i przerywana). */
@media (hover:hover){.k4-tab-przycisk:not([aria-disabled="true"]):not([aria-selected="true"]):hover{background:var(--papier-2)}}
.k4-tab-przycisk:focus-visible{outline:2px solid var(--lazur);outline-offset:-2px}
.k4-tab-wyszarzona{color:var(--cichy);opacity:.55;cursor:not-allowed}
.k4-tab-wyszarzona small{color:var(--cichy)}
.k4-tab-panel-tresc[hidden]{display:none}
.k4-tab-panel-tresc:not([hidden]){background:var(--karta);border:1px solid var(--kreska);
  border-radius:var(--r);padding:16px}
/* Zakladka pierwsza (skrajnie lewa) aktywna: panel dostaje kwadratowy lewy
   gorny rog, zeby jego ramka laczyla sie plasko z ramka zakladki tuz nad nim
   zamiast tworzyc luke przy zaokragleniu (klasa ustawiana w JS,
   ustawZakladkeKrok4). */
.k4-tab-panel-tresc.k4-panel-pierwsza:not([hidden]){border-top-left-radius:0}
.k4-tab-pusto{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  padding:22px 18px;text-align:center;color:var(--cichy);font-size:.88rem}

/* "pokaz pozostale" w zakladce Jeden preparat: 3 karty widoczne od razu,
   reszta za przyciskiem (R4, notes/REWIZJA-UX-CELE-2026-09-26.md:
   "sekcja kompleksowa spycha tabele o kilka ekranow"). */
.pokaz-pozostale{all:unset;cursor:pointer;display:inline-block;margin:4px 0 6px;padding:8px 14px;
  border:1px solid var(--kreska);border-radius:var(--r);font-size:.84rem;font-weight:600;color:var(--atrament)}
.pokaz-pozostale:hover{border-color:var(--atrament)}
.pokaz-pozostale:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
.kompl-ukryta{display:none}

/* Karty "Osobno na kazdy cel" (D37): jeden blok na cel, do piec kart w
   pionie, dwie/trzy kolumny od 900/1300px. */
.p2-cel-blok{margin-bottom:26px}
.p2-cel-naglowek{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;margin-bottom:4px}
.p2-cel-chip{display:inline-block;padding:3px 10px;border-radius:var(--r);font-size:.8rem;font-weight:700}
.p2-cel-info{font-size:.83rem;color:var(--cichy)}
.p2-karty{display:flex;flex-direction:column;gap:10px}
@media (min-width:900px){
  .p2-karty{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
}
@media (min-width:1300px){
  .p2-karty{grid-template-columns:repeat(3,1fr)}
}
/* Struktura karty jak D35 (.kompl-karta: kolumna, kompl-glowa na gorze),
   poprawka spojnosci 27.09 -- przed nia karta byla trzema kolumnami obok
   siebie (foto | tresc | cena), inna niz kazda inna karta kroku 4. */
.p2-karta{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  padding:12px 14px;display:flex;flex-direction:column;gap:9px}
.p2-foto{width:48px;height:48px;flex:0 0 auto;border-radius:var(--r);background:var(--papier-2);
  border:1px solid var(--kreska);object-fit:contain;mix-blend-mode:multiply}
.p2-foto-pusto{width:48px;height:48px;flex:0 0 auto;border-radius:var(--r);background:var(--papier-2);
  border:1px solid var(--kreska)}
.p2-dawka{font-size:.82rem;color:var(--atrament-2)}
.p2-dawka b{font-weight:600;color:var(--atrament)}
/* Dopisek "ponizej normy/warunku" na karcie "Osobno" (uzupelnienie D37,
   27.09): sam kolor cichy nie wystarcza jako jedyny sygnal (D22), ale tu
   dopisek zawsze niesie tez slowo "ponizej" w tresci, wiec kolor jest
   wzmocnieniem, nie jedynym nosnikiem informacji. */
.p2-dawka-niepelna{color:var(--cichy)}
.p2-cel-brak-pelnych{font-size:.8rem;color:var(--cichy);margin:0 0 8px}
.p2-ostrzezenie{font-size:.76rem;color:var(--uwaga);background:var(--uwaga-tlo);border-radius:var(--r);
  padding:4px 8px;line-height:1.35;margin-top:2px}
.p2-akcje-dolne{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:4px}
.p2-porownaj{display:flex;align-items:center;gap:5px;font-size:.72rem;color:var(--cichy);cursor:pointer;
  user-select:none}
.p2-porownaj input{accent-color:var(--lazur);width:13px;height:13px}
.p2-serce{all:unset;cursor:pointer;width:26px;height:26px;display:grid;place-items:center;
  color:var(--cichy);font-size:1.05rem}
.p2-serce:hover{color:var(--stop)}
.p2-serce[aria-pressed="true"]{color:var(--stop)}
.p2-wiecej{all:unset;cursor:pointer;display:inline-block;margin-top:10px;font-size:.82rem;
  color:var(--lazur);text-decoration:underline}
.p2-wiecej:hover{color:var(--atrament)}

/* Karta zestawu dwoch preparatow (D36) w zakladce "Zestaw": od spojnosci
   27.09 (zgloszenie wlasciciela "karta zestawu wyglada inaczej niz reszta")
   dziedziczy szkielet .kompl-karta (ta sama karta co "Jeden preparat" i
   "Osobno" -- padding, kolumna, gap), tylko dokleja margines miedzy kartami
   (te nie stoja w gridzie .kompl-lista) i wlasny naglowek/separator/notatki
   ponizej. Wiersze celow to ta sama .kompl-cele-lista/.kompl-cel-wiersz co
   w karcie "Jeden preparat" (wierszZestawuCelu w cele.html), przekroczenia
   jako ostrzezenie bursztynowe (nigdy czerwien -- to nie jest blokada,
   produkt zostaje na liscie), "jak brac" jesli niepuste (wejscie do planera
   D33, tylko ze zrodlem, patrz serwer/cele.py::_jak_brac). */
.zestaw-karta{margin-bottom:12px}
/* Naglowek "Zestaw N: A + B" + koszt laczny po prawej, w miejscu i stylu
   .kompl-glowa/.kompl-cena karty "Jeden preparat" -- lewa strona to zwykly
   tekst (nie przycisk .kompl-id), wiec potrzebuje wlasnego space-between
   zamiast polegac na flex:1 z .kompl-id. */
.zestaw-naglowek{justify-content:space-between}
.zestaw-naglowek .kompl-nazwa{flex:1;min-width:0}
.zestaw-plus{align-self:center;font-weight:700;color:var(--cichy);font-size:1.1rem;flex:0 0 auto}
/* Dopisek zrodla przy skladniku pokrywajacym cel ("(nazwa krotka produktu)"):
   odpowiada, ktory z dwoch produktow to daje -- pytanie, ktorego karta
   jednego preparatu nie zadaje. */
.zestaw-cel-zrodlo{font-size:.8rem;color:var(--cichy)}
.zestaw-wspolne{margin:0;font-size:.82rem;color:var(--atrament-2)}
.zestaw-wspolne b{font-weight:600;color:var(--atrament)}
.zestaw-przekroczenie{font-size:.8rem;color:var(--uwaga);background:var(--uwaga-tlo);border-radius:var(--r);
  padding:6px 10px;line-height:1.4}
.zestaw-jak-brac{font-size:.8rem;color:var(--atrament-2);background:var(--papier-2);border-radius:var(--r);
  padding:6px 10px;line-height:1.4}

/* Flaga "bez oswiadczenia UE" (D38): plakietka szara neutralna na karcie
   "Osobno" (.p2-karta) zamiast dawki/procentu normy -- produkt z kategorii
   sklepowej DOZ, ktoremu rejestr (rozporzadzenie 1924/2006) nie przyznaje
   oswiadczenia zdrowotnego na wybrany cel. Zastepuje dawna osobna sekcje
   "Poza rejestrem UE" (.pietro3/.p3-*, usuniete). */
.flaga-bez-oswiadczenia{display:inline-block;padding:2px 8px;border-radius:var(--r);
  font-size:.76rem;font-weight:700;background:var(--papier-2);color:var(--cichy);cursor:help}
.flaga-opis{font-size:.78rem;color:var(--cichy);margin:3px 0 0;line-height:1.4}
.flaga-kategoria{font-size:.78rem;color:var(--cichy);margin:2px 0 0}
.flaga-kategoria i{font-style:normal;color:var(--atrament-2)}

/* ============================================================
   Blok: ulubione skladniki i produkty (serwer/statyczne/ulubione.html,
   serwer/statyczne/ulubione.js, przyciski gwiazdki na kaflu produktu, na
   karcie produktu i na stronie substancji). Dopisany na koncu, zeby nie
   ruszac kaskady istniejacych regul.
   ============================================================ */

.btn-ulub{display:inline-flex;align-items:center;gap:6px;padding:8px 13px;border-radius:var(--r);
  border:1px solid var(--kreska);background:var(--karta);font:inherit;font-size:.82rem;
  font-weight:600;color:var(--atrament-2);cursor:pointer;flex:0 0 auto;white-space:nowrap}
.btn-ulub:hover{border-color:var(--atrament)}
.btn-ulub:focus-visible{outline:2px solid var(--lazur);outline-offset:1px}
.btn-ulub[aria-pressed="true"]{background:var(--lazur-tlo);border-color:var(--lazur);color:var(--lazur)}

/* Sama gwiazdka, bez tekstu: na kaflu listy i w naglowku karty produktu
   miejsca jest tyle, co na jedna ikone, opis niesie aria-label. */
/* Serce bez kwadratu (polecenie Bartosza 23.09): ramka wokol znaku robila z
   niego przycisk-pudelko obok kazdej nazwy, a to jest akcja drugoplanowa.
   Zostaje sam znak, wiekszy (0,92 -> 1,34 rem) i w polu 34 px, wiec cel
   dotykowy nadal ma wymagane 24 px z zapasem, a sasiedzi maja od niego
   bezpieczny odstep. */
.btn-ulub-mini{width:34px;height:34px;padding:0;justify-content:center;font-size:1.34rem;
  line-height:1;border:0;background:none;color:var(--cichy)}
.btn-ulub-mini:hover{background:none;border:0;color:var(--stop)}
.btn-ulub-mini[aria-pressed="true"]{background:none;border:0;color:var(--stop)}
/* R6: krok 3 wywiadu (.wynik-skladnik-glowa) uzywa tej samej gwiazdki 34 px.
   Bez sasiada interaktywnego obok (tylko tekst skladnika w gap:10px), wiec
   pelne symetryczne rozszerzenie o 5 px z kazdej strony daje 44 x 44 bez
   ryzyka dwoch celow dotykowych na sobie. Scoped, nie w bazowej .btn-ulub-mini,
   zeby nie ruszac kafli listy i naglowka karty produktu, ktore uzywaja tej
   samej klasy w innym ukladzie. */
.wynik-skladnik-glowa .btn-ulub-mini{position:relative}
.wynik-skladnik-glowa .btn-ulub-mini::after{content:"";position:absolute;
  top:-5px;right:-5px;bottom:-5px;left:-5px}

.subst-tytul-wiersz{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap}

/* Kafel produktu zyskuje drugi wiersz akcji obok "do porownania": gwiazdka
   ulubionych siedzi w tym samym rzedzie, zeby nie wydluzac kafla o kolejny
   pasek. */
.kafel-akcje{display:flex;align-items:center;justify-content:space-between;gap:4px;
  border-top:1px solid var(--kreska)}
.kafel-akcje .kafel-porownaj{border-top:0;flex:1;min-width:0}
.kafel-akcje .btn-ulub-mini{margin-right:6px;border:0;background:none;color:var(--cichy)}
.kafel-akcje .btn-ulub-mini[aria-pressed="true"]{background:none;color:var(--lazur)}
.kafel-akcje .btn-ulub-mini:hover{color:var(--atrament)}
/* Strona substancji nie ma "do porownania" na kaflu, wiec gwiazdka jest
   jedynym dzieckiem: bez tej reguly space-between przyklejalby ja do lewej. */
.kafel-akcje:has(> .btn-ulub-mini:only-child){justify-content:flex-end}

@media (max-width:560px){
  /* Pasek akcji cienszy przy poziomym kaflu, ale nie ponizej 24px celu
     dotykowego: 7px+7px padding wokol linii tekstu/checkboxa daje ~29px. */
  .kafel-akcje .kafel-porownaj{padding:7px 11px}
}

.ulub-sekcja{margin-bottom:30px}
.ulub-sekcja h2{font-size:1.05rem;margin-bottom:12px}
.ulub-pusta{padding:28px 20px;text-align:center;color:var(--cichy);background:var(--karta);
  border:1px solid var(--kreska);border-radius:var(--r);display:flex;flex-direction:column;
  gap:10px;align-items:center}
.ulub-pusta a{color:var(--lazur);font-weight:600;text-decoration:none}
.ulub-pusta a:hover{text-decoration:underline}

.siatka-ulub-skladniki{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}
.karta-ulub-skladnik{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);
  padding:14px 16px;display:flex;flex-direction:column;gap:8px}
.karta-ulub-skladnik a{color:inherit;text-decoration:none;font-weight:700;font-size:.96rem}
.karta-ulub-skladnik a:hover{color:var(--lazur)}
.karta-ulub-skladnik .l{font-family:var(--dane);font-size:.68rem;color:var(--cichy)}
.karta-ulub-skladnik-akcje{display:flex;justify-content:flex-end;align-items:center;gap:8px;margin-top:auto}
.usun-ulub{border:0;background:none;color:var(--cichy);font-size:.76rem;text-decoration:underline;
  text-underline-offset:2px;cursor:pointer;padding:0;font:inherit}
.usun-ulub:hover{color:var(--stop)}

/* Kafel produktu na /ulubione: tego samego wzoru co siatka na liscie, wiec
   .kafel dziedziczy wyglad, tylko akcje pod nim sa inne (usun, porownaj). */
.ulub-produkt-akcje{display:flex;justify-content:space-between;align-items:center;gap:8px;
  padding:9px 13px;border-top:1px solid var(--kreska)}
.ulub-produkt-akcje button.porownaj{font:inherit;font-size:.76rem;font-weight:600;color:var(--lazur);
  background:none;border:0;cursor:pointer;padding:0}
.ulub-produkt-akcje button.porownaj:hover{text-decoration:underline}

/* ============================================================
   Blok: panel filtrow z lewej na liscie produktow (/produkty).
   notes/ANALIZA-LISTY-PRODUKTOW.md, krok 1: przeniesienie filtrow, ktore juz
   istnialy w jednym pasie nad lista, do panelu z lewej. Zadnych nowych
   filtrow. Prefiks pfl- (panel filtrow), zeby nie kolidowac z .filtr-panel
   (skladniki do wykluczenia), ktory zyje wewnatrz tego panelu bez zmian.
   ============================================================ */

/* 300px, nie 260 jak dawniej z jednym <select> na sekcje: priorytet desktop
   (Krzysztof 18.09) oznacza, ze panel ma pokazywac duzo naraz, wiec kolumna
   list wielokrotnego wyboru dostaje wiecej miejsca na etykiete i liczbe. */
.pfl-uklad{display:flex;gap:22px;align-items:flex-start}
.pfl-panel{flex:0 0 300px;width:300px;display:flex;flex-direction:column;gap:14px}
.pfl-lista{flex:1;min-width:0}

.pfl-sekcja{background:var(--karta);border:1px solid var(--kreska);border-radius:var(--r);padding:13px 15px}
.pfl-sekcja h3{font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;color:var(--cichy);
  font-stretch:100%;margin:0 0 9px}

/* Filtry wielokrotnego wyboru (substancja, producent, postac, grupa): checkbox
   na kazda pozycje, tak jak w porownywarkach elektroniki, zamiast dawnego
   pojedynczego <select> (Krzysztof 18.09: "filtry jak w elektronice"). */
.pfl-multi{display:flex;flex-direction:column;gap:1px}
.pfl-opcja{display:flex;align-items:center;gap:8px;padding:6px 5px;border-radius:var(--r);cursor:pointer}
.pfl-opcja:hover{background:var(--papier)}
.pfl-opcja input{accent-color:var(--lazur);width:15px;height:15px;flex:0 0 auto}
.pfl-opcja:has(input:focus-visible){outline:2px solid var(--lazur);outline-offset:1px}
.pfl-opcja-etykieta{flex:1;min-width:0;font-size:.86rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pfl-opcja .num{font-size:.72rem;color:var(--cichy);flex:0 0 auto}
/* Substancja i producent licza dziesiatki do kilkuset pozycji: bez limitu
   wysokosci panel z lewej bylby dluzszy niz cala reszta strony. Postac (siedem
   wartosci) i grupa (szesc) miesza sie w calosci, bez wlasnego przewijania. */
.pfl-multi-przewijana{max-height:320px;overflow-y:auto;padding-right:2px}
/* U17: opcja bez pasujacych produktow w biezacym zbiorze (U31) zostaje na
   liscie, przygaszona zamiast usunieta -- zero tez jest informacja. */
.pfl-opcja-zero{opacity:.45}
/* U17: pole szukania nad dluga lista wielokrotnego wyboru (substancja, forma,
   producent), zeby nie trzeba bylo przewijac 191 pozycji reczne. Mniejsze niz
   glowne pole "Zawez wyniki" (.szukajka input), bo stoi wewnatrz waskiej
   kolumny panelu (300px), nie na pelnej szerokosci listy. */
.pfl-szukaj-multi{width:100%;padding:7px 10px;margin-bottom:7px;border:1px solid var(--kreska);
  border-radius:var(--r);background:var(--papier);font:inherit;font-size:.8rem;color:var(--atrament)}
.pfl-szukaj-multi:focus-visible{outline:2px solid var(--lazur);outline-offset:1px}

/* Przejscie do strony marki (serwer/producenci_web.py), tylko przy pozycjach
   producenta: link jest RODZENSTWEM .pfl-opcja, nie jej dzieckiem, zeby
   klikniecie w checkbox i klikniecie w przejscie do marki byly dwiema
   osobnymi, nie zagniezdzonymi akcjami. */
.pfl-wiersz{display:flex;align-items:center;gap:2px}
.pfl-wiersz .pfl-opcja{flex:1;min-width:0}
.pfl-opcja-link{flex:0 0 auto;padding:6px 8px;border-radius:var(--r);color:var(--cichy);
  text-decoration:none;font-size:.86rem;line-height:1}
.pfl-opcja-link:hover,.pfl-opcja-link:focus-visible{color:var(--lazur);background:var(--papier)}

.pfl-etykieta-szukaj{display:block;font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;
  color:var(--cichy);margin-bottom:5px}

/* S1: pasek aktywnych filtrow nad lista wynikow. Wyraznie inny wyglad niz
   plakietki informacyjne na kaflu (.karta-chip: plaska pigula bez ramki, nie
   do klikniecia): tu kazdy chip JEST przyciskiem, wiec dostaje ramke,
   wysokosc min. 32px (cel dotykowy) i widoczny stan hover/fokus. */
.pfl-chipy{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:14px 0}
.pfl-chipy[hidden]{display:none}
.pfl-chip{display:inline-flex;align-items:center;gap:7px;min-height:32px;padding:0 9px 0 13px;
  border:1px solid var(--lazur);border-radius:var(--r);background:var(--lazur-tlo);color:var(--lazur);
  font:inherit;font-size:.78rem;font-weight:600;cursor:pointer}
.pfl-chip:hover{background:var(--lazur);color:var(--karta)}
.pfl-chip:focus-visible{outline:2px solid var(--lazur);outline-offset:2px}
.pfl-chip-x{font-size:.68rem;line-height:1}
.pfl-chip-wyczysc{display:inline-flex;align-items:center;min-height:32px;padding:0 4px;
  border:0;background:none;color:var(--cichy);font:inherit;font-size:.78rem;
  text-decoration:underline;cursor:pointer}
.pfl-chip-wyczysc:hover,.pfl-chip-wyczysc:focus-visible{color:var(--atrament)}

/* Przycisk otwierajacy panel na waskim ekranie: schowany na desktopie, gdzie
   panel stoi z lewej caly czas widoczny jako kolumna. */
.pfl-przelacznik{display:none}

@media (max-width:900px){
  .pfl-uklad{flex-direction:column}
  /* width:100%, nie auto: .pfl-uklad ma align-items:flex-start (zamierzone -
     panel nie ma sie rozciagac w pionie do wysokosci listy), a przy flex-start
     "width:auto" liczy sie z WLASNEJ tresci panelu (max-content), nie z
     miejsca, jakie realnie ma .pfl-uklad. Zmierzone Playwrightem 26.09: panel
     465px na ekranie 390px (dostepne miejsce w .pfl-uklad to 350px), mimo ze
     panel formalnie "auto" mial sie dopasowac. Prawdziwym zrodlem tych 465px
     byl #zlozonoscSeg nizej (patrz tam): width:100% tutaj i min-width:0 razem
     pilnuja, zeby panel NIGDY nie byl szerszy niz miejsce, ktore dostal,
     niezaleznie od tego, co kiedys wyladuje w jego tresci. */
  .pfl-panel{display:none;width:100%;min-width:0}
  .pfl-panel.pfl-panel-otwarty{display:flex}
  .pfl-przelacznik{display:inline-flex;align-items:center;gap:8px;margin-bottom:14px;
    padding:10px 15px;border:1px solid var(--kreska);border-radius:var(--r);
    background:var(--karta);font:inherit;font-size:.86rem;font-weight:600;cursor:pointer;
    color:var(--atrament)}
  .pfl-przelacznik:hover{border-color:var(--atrament)}
  .pfl-przelacznik .num{background:var(--atrament);color:var(--karta);padding:1px 7px;border-radius:var(--r);font-size:.72rem}
  /* Rzeczywista przyczyna przewiniecia (zmierzone 26.09: kazdy potomek panelu
     mial dokladnie ta sama szerokosc 433-465px, wiec to nie tekst etykiety
     filtra byl winny, tylko JEDEN element: segment zlozonosci. .seg jest
     inline-flex (rozmiar dopasowany do tresci, jak inline-block), wiec trzy
     nierozdzielone przyciski ("Wszystkie produkty" / "Preparaty złożone" /
     "Tylko jeden składnik") wymuszaly na calym .pfl-sekcja i .pfl-panel
     szerokosc, ktorej ekran telefonu nie ma. Zamiana na blokowy flex ze
     zlamaniem w kolumne oddaje kontrole szerokosci rodzicowi (100%), a
     min-height 44px daje cel dotykowy, ktorego 6px/10px padding z ponizszego
     @media(max-width:560px) nie gwarantowal. Selektor po id, nie po .seg, zeby
     nie ruszyc segmentu sortowania (#sortSeg), ktory tego problemu nie ma. */
  #zlozonoscSeg{display:flex;flex-direction:column;width:100%}
  #zlozonoscSeg button{border-right:0;border-bottom:1px solid var(--kreska);
    min-height:44px;white-space:normal;text-align:left;padding:10px 14px}
  #zlozonoscSeg button:last-child{border-bottom:0}
}

/* Druga runda scisniecia listy /produkty na 390px (notes/MOBILE-PRZEBUDOWA.md):
   dopisane na koncu pliku CELOWO, zeby wygrac w kaskadzie z regulami dla tych
   samych klas zdefiniowanymi wyzej w bloku @media(max-width:900px)
   (.pfl-przelacznik) - ten sam mechanizm, co komentarz przy .cel-produkty
   .kafel-obraz wyzej w pliku. Cel dotykowy 24px pilnowany wszedzie. */
@media (max-width:560px){
  /* main{padding-top:26px} jest wspolne dla calego serwisu (porownanie.html,
     cele.html), wiec go nie ruszamy globalnie: :has(> .head-produkty)
     trafia wylacznie w /produkty, gdzie ten div stoi jako pierwsze dziecko. */
  main:has(> .head-produkty){padding-top:10px}
  .head-produkty{margin-bottom:6px}
  /* h1 na dwoch liniach przy pelnym rozmiarze (clamp 1.4-1.7rem) zabieral
     51px. Skalowanie w dol tylko na tym jednym naglowku (nie global h1),
     zeby nie ruszyc rozmiaru tytulow na innych stronach. */
  .head-produkty h1{font-size:1.02rem}
  .wywiad{margin-bottom:6px}
  .wywiad-glowa{padding:6px 13px}
  .pfl-przelacznik{padding:6px 13px;margin-bottom:6px}
  .szukajka{margin-bottom:6px}
  .szukajka input[type=search]{padding:7px 12px}
  .pasek{gap:6px;margin-bottom:8px}
}

/* Miniatury na liscie /produkty -- DESKTOP WYLACZNIE (telefon ma wlasny uklad
   w @media max-width:560px wyzej: obraz 88x88 obok tresci, kafel 160px).
   Historia tej reguly: 18.09 miniatury powiekszono (U18) do minmax 330,
   nastepnie cofnieto do 280, a 23.09 Bartosz zglosil, ze na listingu z
   filtrami zdjecia sa za duze. Zmierzone przy 1440 px: siatka ma 878 px, bo
   panel filtrow zabiera lewa kolumne, wiec 280 dawalo trzy kolumny, obraz
   283x283 i kafel 530 px wysokosci, czyli jeden produkt na polowe ekranu.
   208 px daje cztery kolumny, a kadr 4:3 zamiast kwadratu skraca kafel o
   jedna trzecia: opakowanie nie maleje, bo przy object-fit:contain to ono
   wyznacza wysokosc, znika pusty pas nad nim i pod nim. */
@media (min-width:561px){
  .siatka-produkty{grid-template-columns:repeat(auto-fill,minmax(208px,1fr))}
  /* grid-template-rows:minmax(0,1fr) nie jest kosmetyka. Regula ogolna wyzej
     daje obrazowi max-height:100%, a procent liczy sie od wysokosci WIERSZA
     gridu. Domyslny wiersz auto ma wysokosc tresci, czyli samego obrazu, wiec
     ograniczenie nie mialo od czego liczyc i pionowe opakowanie wychodzilo poza
     kadr, przyciete dopiero przez overflow (zmierzone: kadr 209x156, obrazek
     196x241). W kontenerze kwadratowym problem nie bylo widac, bo obraz i kadr
     mialy te sama proporcje. Wiersz 1fr dziedziczy wysokosc z aspect-ratio
     kontenera i max-height znow cos znaczy. */
  .siatka-produkty .kafel-obraz{aspect-ratio:4/3;padding:6px;grid-template-rows:minmax(0,1fr)}
}

/* U19: przycisk "do porownania" wiekszy i wyrazniejszy -- desktop wylacznie,
   ta sama granica i ten sam powod co blok U18 wyzej (kafel 160px na
   telefonie nie wolno cofnac; padding tam i tak nadpisuje mobilny
   @media(max-width:560px) przy .kafel-akcje .kafel-porownaj powyzej w
   pliku, ale font-size i checkbox nie mialy tam wlasnego override). */
@media (min-width:561px){
  .kafel-porownaj{padding:11px 13px;font-size:.82rem;font-weight:600}
  .kafel-porownaj input{width:18px;height:18px}
}

/* Nota przy zestawie polaczonym samym celem: patrz porownanie.html,
   pasekWspolnegoCelu. Ton informacyjny, nie ostrzegawczy: to nie blad
   uzytkownika, tylko wlasciwosc zestawu. */
.pasek-wspolny-cel{background:var(--papier-2);border:1px solid var(--kreska);border-radius:var(--r);padding:10px 12px;margin-bottom:10px}
