/*
Theme Name: NTB24
Theme URI: https://ntb24.pl
Description: Motyw potomny do Hello Elementor dla sklepu jezdzieckiego NTB24.pl. Szablony sklepowe natywnie w PHP na hookach WooCommerce, Elementor tylko do tresci na stronach statycznych.
Author: NTB24
Template: hello-elementor
Version: 0.3.5
Text Domain: ntb24
Tags: e-commerce, minimal, monochrome
*/

/* ============================================================
   1. SYSTEM PROJEKTOWY
   Jedyne zrodlo prawdy dla kolorow, typografii, odstepow i linii.
   ============================================================ */

:root {
  /* --- Kolor: paleta zamknieta, dokladnie dziewiec wartosci (regula 5, D07) ---
     Poza ta lista nie wolno wpisac zadnego koloru. Nie ma kolorow funkcyjnych:
     ostrzezenie to ramka 1 px --c-ink + ikona, stan aktywny to czarne
     wypelnienie i bialy tekst. Kontrole: skrypty/qa_paleta.rb. */
  --c-bg: #FFFFFF;      /* tlo */
  --c-paper: #F6F4F0;   /* panele */
  --c-hatch: #F2EFEA;   /* szraf i kadry bez zdjecia */
  --c-line: #E4E1DB;    /* linie hairline, tlo siatek 2 px */
  --c-line-2: #C9C4BC;  /* ramki kontrolek */
  /* Po poprawce P20 zostaly tu WYLACZNIE cztery role, w ktorych #9C9C9C
     niczego nie mowi: tekst zastepczy w polu (::placeholder), punktor listy
     (::marker) i dwie strzalki rozwijania, obok ktorych stoi ten sam
     komunikat slowami. Kazde inne uzycie to blad - 2,75:1 na bieli przy
     progu 4,5:1. Tresc idzie na --c-ink-3 (5,10:1). */
  --c-ink-4: #9C9C9C;   /* wylacznie dekoracja i placeholder, nigdy tresc */
  --c-ink-3: #6E6E6E;   /* etykiety, minimalny tier na bieli */
  --c-ink-2: #3C3C3C;   /* tekst drugorzedny */
  --c-ink: #0A0A0A;     /* tekst i akcent */
  --c-on-ink: #FFFFFF;  /* tekst na czerni */

  /* Rola, nie nowa barwa: granica kontrolki, w ktorej obrys jest JEDYNYM
     sygnalem, ze cos jest do wypelnienia (puste pole, niezaznaczony
     checkbox). WCAG 1.4.11 zada tam 3:1, a --c-line-2 daje na bieli 1,73:1
     i --c-line 1,31:1. Z palety przechodzi dopiero #6E6E6E - 5,10:1.
     Linie dzialowe i ramki, obok ktorych stoi ikona albo etykieta,
     zostaja na --c-line-2: tam obrys nie niesie informacji sam. */
  --c-control: var(--c-ink-3);

  /* Ikona ostrzezenia jako maska SVG. W masce liczy sie wylacznie kanal alfa,
     wiec zapis stroke w data URI nie jest kolorem interfejsu - barwe nadaje
     background-color: var(--c-ink). Obrys 1.5 px, viewBox 24, jak w sprite. */
  --i-alert: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230A0A0A' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5'/%3E%3Cpath d='M12 16.2h.01'/%3E%3C/svg%3E");

  /* Znacznik wyboru, ta sama zasada co --i-alert: maska, nie kolor.
     Potrzebny w dwoch miejscach, gdzie ptaszek stoi na czarnym wypelnieniu
     i nie ma go w markupie: slupek wybranego rozmiaru na skali (uklad B)
     i pole wyboru w formularzach kasy. Nowy token, bo w :root nie bylo
     zadnej maski poza ostrzezeniem. */
  --i-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230A0A0A' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12.5l5 5 10-11'/%3E%3C/svg%3E");

  /* --- Typografia --- */
  --f-display: "Bodoni Moda", Georgia, "Times New Roman", serif;
  --f-ui: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;

  /* --- Skala pisma: drabina zamknieta, dwanascie szczebli ------------------
     Do poprawki na ekranie stalo 27 stopni przy 9 tokenach, bo wymiar pisano
     liczba w miejscu uzycia i nie bylo widac, ktory szczebel wybrac - kazda
     nowa sekcja dokladala wlasny. Ponizej jest komplet: NIE WOLNO wpisac
     font-size liczba, tylko var(--fs-*). Brakuje szczebla? Dopisz go TUTAJ,
     razem z rola, zeby nastepny ekran mial z czego wybierac.

     Drabina ma dwie rodziny i to one, a nie poziom znacznika, decyduja
     o stopniu (S28):
       ETYKIETA  --fs-50 .. --fs-200  wersaliki, jedno-dwa slowa, Archivo.
                 Tylko tu wolno zejsc ponizej 14 px.
       TRESC     --fs-300 i wyzej. Zdanie nigdy nizej niz --fs-300,
                 a na telefonie --fs-300 podnosi sie do 14 px (blok nizej). */
  --fs-50:  .625rem;   /* 10 px, mikro wersaliki: szyna, logo, kicker */
  --fs-100: .6875rem;  /* 11 px, mikro etykiety */
  --fs-200: .75rem;    /* 12 px, etykieta pola i chipa */
  --fs-300: .8125rem;  /* 13 px, tekst pomocniczy, tabele, przypisy */
  --fs-400: .875rem;   /* 14 px, baza interfejsu i dolna granica zdania */
  --fs-500: 1rem;      /* 16 px, tekst ciagly, pola wpisywane, leady */
  --fs-600: 1.125rem;  /* 18 px, cena i wyrozniony wiersz */
  --fs-700: 1.375rem;  /* 22 px, tytul kafla i naglowek trzeciego rzedu */
  --fs-800: 1.75rem;   /* 28 px, naglowek sekcji */
  --fs-850: 2.125rem;  /* 34 px, naglowek bloku zakupu i pasa sekcji */
  --fs-900: clamp(2rem, 3vw, 2.75rem);        /* 32-44 px, H1 podstrony */
  --fs-1000: clamp(2.125rem, 3.6vw, 3.25rem); /* 34-52 px, H1 hero i liczba wyswietlana */

  /* --- Interlinia: cztery role, nic poza nimi ------------------------------
     Wczesniej 27 wartosci przy trzech tokenach, w tym osiem na samym tekscie
     ciaglym - ten sam akapit wypadal raz 1.68, raz 1.78. Ulamkowe pudelka
     wykluczaly przy okazji siatke 4 px. */
  --lh-tight: 1.05;   /* H1-H2 i liczby wyswietlane */
  --lh-snug: 1.2;     /* H3-H4, nazwy w kartach */
  --lh-label: 1.4;    /* etykiety i wiersze, ktore maja sie nie lamac */
  --lh-body: 1.55;    /* tekst zdaniowy */
  --tr-tight: -.02em;

  /* --- Odstepy, skala 4 px --- */
  --s-1: .25rem;
  --s-2: .5rem;
  --s-3: .75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 2.5rem;
  --s-8: 3rem;
  --s-9: 4rem;
  --s-10: 5rem;
  --s-11: 6rem;

  /* --- Linie i promienie: promien zawsze 0, wyjatkiem tylko swatch koloru --- */
  --bw-hair: 1px;
  --bw-strong: 1.5px;
  --bw-heavy: 2px;
  --r-0: 0;
  --r-round: 50%;

  /* --- Cien wystepuje wylacznie pod paskami przyklejonymi (README par. 3).
     Zadna inna warstwa cienia nie ma: panel dzialu, modal i panel koszyka
     odcinaja sie ramka 1 px. --- */
  --sh-bar: 0 -6px 18px rgba(10, 10, 10, .08);
  --sh-sheet: 0 -8px 24px rgba(10, 10, 10, .10);

  /* --- Uklad. Kontener domyslny 1560/40 px (D06); strona glowna ma
     wlasny, wezszy wariant ustawiony nizej modyfikatorem. --- */
  --w-page: 1560px;
  --pad-page: 40px;
  /* Miara akapitu. Do poprawki token mial 68ch i ZERO uzyc, a w arkuszu
     stalo obok niego osiem miar ad hoc (16, 44, 56, 60, 62, 64, 70, 76ch).
     Zmieniamy jednostke na rem, bo `ch` klamie: pomiar z audytu daje
     1ch = 8,59 px przy realnych 7,42-7,60 px na znak, wiec deklaracja
     w znakach wychodzila o ~16% szersza, niz mowila. 33rem = 528 px daje
     przy stopniach 13-16 px od 64 do 84 znakow w wierszu - pod progiem 85,
     ktory audyt przekraczal w siedmiu z 33 zmierzonych akapitow. */
  --w-text: 33rem;
  /* Miara naglowka wyswietlanego. Osobny token, bo naglowek lamie sie po
     innej liczbie znakow niz akapit i liczy sie w znakach kroju display. */
  --w-head: 16ch;
  /* Szerokosc KOLUMNY tekstu ciaglego. To co innego niz --w-text, ktory jest
     miara akapitu: kolumna moze byc szersza od akapitu, akapit nigdy szerszy
     od kolumny. 760 px daje przy stopniu tresci strony statycznej ok. 75
     znakow w wierszu. Do poprawki ta liczba siedziala inline w dziewieciu
     miejscach siedmiu szablonow i nie dalo sie jej nadpisac arkuszem -
     stad obejscia z !important przy koszyku i kasie (sekcja 27). */
  --w-prose: 760px;
  --rail-w: 64px;
  --col-filters: 20%;
  --header-h: 96px;
  --header-sticky-h: 58px;
  --mobilebar-h: 60px;
  --safe-b: env(safe-area-inset-bottom, 0px);

  /* Zapas pod paskiem przyklejonym. Wartosc tutaj jest tylko zapasem na
     wypadek braku JavaScriptu i opisuje nizszy z dwoch paskow (nawigacyjny,
     60 px). Realna wysokosc mierzy ntb.js i wpisuje ta sama zmienna na
     <html>: pasek zakupu ma 73 px, a jedna stala zaslaniala 13 px tresci
     na dole karty produktu (AUDYT-UX blad D2). */
  --ntb-bar-h: calc(var(--mobilebar-h) + var(--safe-b));

  /* Wysokosc naglowka po przyklejeniu. Tak samo jak wyzej: wartosc tutaj jest
     zapasem, realna mierzy ntb.js. Uzywa jej skorowidz literowy na /marki/,
     ktory stoi pod naglowkiem. */
  --ntb-head-h: var(--header-sticky-h);

  /* Zapas nad kotwica. Celowo NIE --ntb-head-h: te zmienna ntb.js wpisuje
     dopiero, gdy naglowek sie przyklei, a przegladarka czyta scroll-padding
     w chwili skoku, czyli jeszcze przed tym - kotwica ladowala wtedy 4 px
     pod krawedzia naglowka. Wartosc jest statyczna i nie mniejsza niz
     najwyzszy przyklejony naglowek w serwisie: 78 px na 390 px (59 na 1440). */
  --h-anchor: 94px;

  /* --- Wymiary kontrolek wg README par. 3 i D08.
     Wszystko, co ponizej 44 px, jest na 390 px podnoszone polem dotyku. --- */
  --touch: 44px;      /* minimalny cel dotykowy, regula 3 */
  --h-btn: 52px;      /* przycisk glowny 52-56 */
  --h-field: 48px;    /* pole formularza 48-50 */
  --h-chip: 40px;     /* chip filtra 38-44 */
  --h-chip-x: 34px;   /* chip aktywny z krzyzykiem */
  --h-step: 44px;     /* stepper ilosci, takze na mobile (regula 3) */
  --box-filter: 15px; /* checkbox w filtrach */
  --box-form: 20px;   /* checkbox i radio w formularzach */

  /* Cztery warianty kafelka rozmiaru, README par. 3.
     A: karta produktu, F: faseta filtra, S: chip na liscie, R: kask z zakresem. */
  --tile-a-w: 74px;
  --tile-a-h: 48px;
  --tile-f-w: 56px;
  --tile-f-h: 38px;
  --tile-s-w: 44px;
  --tile-s-h: 28px;
  --tile-r-w: 108px;
  --tile-r-h: 58px;

  /* --- Proporcje kadrow --- */
  --ar-product: 4 / 5;
  --ar-hero-d: 4 / 1;
  --ar-hero-t: 3 / 1;
  --ar-hero-m: 16 / 9;
  --ar-editorial: 3 / 2;

  /* --- Ruch: wylacznie transform i opacity, maks 200 ms --- */
  --dur: 200ms;
  --ease: cubic-bezier(.2, 0, .2, 1);

  /* --- Warstwy --- */
  --z-rail: 40;
  --z-mobilebar: 45;
  --z-header: 50;
  --z-overlay: 80;
  --z-panel: 90;
  --z-modal: 100;
}

/* Atrybut hidden ma zawsze wygrywac z display: z klasy (np. .ntb-notice { display:flex }),
   inaczej pusty kontener bledu w panelu koszyka rysuje sie jako pusty boks z ikona. */
[hidden] { display: none !important; }

/* Dolne szczeble skali na telefonie (S26). Do poprawki cala drabinka ponizej
   16 px stala w miejscu - na 390 px malaly WYLACZNIE naglowki, wiec 88 miejsc
   z tekstem zdaniowym schodzilo do 11,5-13,5 px na najmniejszym ekranie,
   czyli dokladnie tam, gdzie czyta sie najtrudniej.
   Podnosimy dwa dolne szczeble TRESCI, a nie kazdy komponent z osobna:
   --fs-300 (tekst pomocniczy, tabele, przypisy) siada na 14 px, --fs-200
   (etykieta pola i chipa) na 13 px. Rodzina ETYKIETY (--fs-50, --fs-100)
   zostaje bez zmian: to wersaliki po jednym-dwa slowa, ktorych S26 nie liczy
   i ktore przy 13 px rozjechalyby chipy i szyne.
   Stoi tuz pod :root, zeby nikt nie szukal tej decyzji w sekcji breakpointow. */
@media (max-width: 767px) {
  :root {
    --fs-200: .8125rem;  /* 13 px */
    --fs-300: .875rem;   /* 14 px */
  }
}

/* Breakpointy nie moga byc zmiennymi w @media, wiec sa udokumentowane tutaj:
   480, 768, 1024, 1200, 1440 px.
   Kolumny listingu: 2 do 767, 3 do 1199, dalej 3 albo 4 z przelacznika gestosci. */

/* ============================================================
   2. KROJE, lokalnie jako woff2, maks 4 odmiany
   ============================================================ */

/* Kroje lokalne, bez odpytywania Google (prywatność i LCP).
   Google nie udostępnia już statycznych instancji Bodoni Moda ani Archivo - oba API
   zwracają ten sam plik zmienny dla każdej wagi, więc zamiast pięciu plików statycznych
   mamy dwa zmienne w dwóch podzbiorach. Patrz DECISIONS.md D17.
   Polskie znaki: ó jest w latin, ą ć ę ł ń ś ź ż w latin-ext - potrzebne są oba podzbiory,
   i oba dla Bodoni idą w preload, bo H1 hero jest elementem LCP. */

/* Bodoni Moda, nagłówki, podzbiór latin */
@font-face {
  font-family: "Bodoni Moda";
  src: url("assets/fonts/bodoni-moda-latin.woff2") format("woff2");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Bodoni Moda, podzbiór latin-ext (polskie znaki) */
@font-face {
  font-family: "Bodoni Moda";
  src: url("assets/fonts/bodoni-moda-latin-ext.woff2") format("woff2");
  font-weight: 400 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Archivo, tekst i interfejs, podzbiór latin */
@font-face {
  font-family: "Archivo";
  src: url("assets/fonts/archivo-latin.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Archivo, podzbiór latin-ext (polskie znaki) */
@font-face {
  font-family: "Archivo";
  src: url("assets/fonts/archivo-latin-ext.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================
   3. BAZA
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--f-ui);
  font-size: var(--fs-500);
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: var(--fw-regular);
  letter-spacing: var(--tr-tight);
  line-height: var(--lh-snug);
  margin: 0;
}

h1 { font-size: var(--fs-900); line-height: var(--lh-tight); }
h2 { font-size: var(--fs-800); }
h3 { font-size: var(--fs-700); }

/* --- Dwie role naglowka, zeby stopien przestal zalezec od znacznika (S28) ---
   Do poprawki na jednym adresie stalo H2 w czterech stopniach i dwoch krojach,
   H3 w trzech, a najwieksze H3 bylo o 3,5 px WIEKSZE od najmniejszego H2 -
   bo `h2` w panelu sterowania i `h2` w tresci to dwie rozne rzeczy opisane
   tym samym znacznikiem. Rozdzielamy je na dwie klasy i od tej pory stopien
   wybiera ROLA, nie poziom w drzewie.

   1) ETYKIETA PANELU - .ntb-panelhead. Archivo, jeden stopien, wersaliki.
      Tytul kolumny filtrow, nazwa grupy faset, kicker w mega menu, nadtytul
      nad naglowkiem. Panel nie ma wlasnej hierarchii wielkosci: porzadek
      niesie w nim polozenie i linia, nie stopien pisma.
      .ntb-eyebrow jest historyczna nazwa tej samej roli. To ona lamala
      regule 5: klasa nie ustawiala kroju, wiec ta sama etykieta wychodzila
      raz Bodoni (jako <h2>, z reguly wyzej), raz Archiva (jako <span>,
      z body). Przy okazji Bodoni ma @font-face 400-500, wiec zadana waga 600
      i tak byla przycinana do 500 - etykieta w Bodoni nie moglaby byc
      polgruba, nawet gdybysmy tego chcieli. */
.ntb-panelhead,
.ntb-eyebrow,
.ntb-catlinks h2,
.ntb-filters__head h2,
.ntb-fgroup__head h3,
.ntb-mega__kicker,
.ntb-tile__label {
  font-family: var(--f-ui);
  font-size: var(--fs-100);
  font-weight: var(--fw-semibold);
  letter-spacing: .18em;
  line-height: var(--lh-label);
  text-transform: uppercase;
  color: var(--c-ink-3);
}

/* 2) PODNAGLOWEK TRESCI - .ntb-subhead. Archivo, zdaniowo, bez rozstrzelenia.
      Stopien nad tekstem ciaglym, ponizej naglowka sekcji. Do poprawki ta
      sama rola byla opisana czterema zestawami (14,5/500, 15/600, 15/600,
      15/600) w czterech miejscach. */
.ntb-subhead,
.ntb-prose h3,
.ntb-prose__rest h3,
.ntb-faq__item h3,
.ntb-sizing__grid h3,
.ntb-step__t {
  font-family: var(--f-ui);
  font-size: var(--fs-500);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  line-height: var(--lh-snug);
}

p { margin: 0; }

a { color: var(--c-ink); text-decoration: none; }
a:hover { color: var(--c-ink-2); }

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

ul, ol { margin: 0; padding: 0; list-style: none; }

/* Reset motywu nadrzednego (hello-elementor/assets/css/reset.css) maluje
   KAZDY przycisk na rozowo: kolor pisma i ramke 1 px w barwie spoza palety,
   do tego promien 3 px, choc promien u nas jest zawsze zerowy. Selektorem
   jest tam [type="button"], mocniejszym niz samo `button`, wiec dotychczasowa
   regula `button { font: inherit }` do tych wlasnosci nie siegala - ikony
   serca i porownania na kartach, zamkniecie filtrow i zamkniecie koszyka
   wychodzily rozowe. Powtarzamy sile selektora i wracamy do systemu.
   qa_paleta.rb tego nie zlapie, bo barwa nie pada w naszych zrodlach;
   widac ja dopiero na zrzucie z przegladarki.
   Paddingu i grubosci ramki celowo nie zerujemy, zeby nie zmniejszyc
   zadnego pola dotyku - komponenty i tak podaja swoje wartosci nizej. */
button,
[type="button"],
[type="submit"],
[type="reset"] {
  color: inherit;
  background-color: transparent;
  border-color: var(--c-line-2);
  border-radius: var(--r-0);
  font: inherit;
  cursor: pointer;
}

/* Reset nadrzedny ma tez `button:hover { background-color: rozowy; color: #fff }`.
   Bez tej pary kazdy przycisk bez wlasnego stanu rozjezdzal sie pod palcem
   i myszka. Reguly komponentow stoja nizej w tym pliku, wiec wygrywaja. */
button:hover, button:focus,
[type="button"]:hover, [type="button"]:focus,
[type="submit"]:hover, [type="submit"]:focus,
[type="reset"]:hover, [type="reset"]:focus {
  background-color: transparent;
  color: inherit;
}

select, input, textarea { color: inherit; }

/* Obrys skupienia: 2 px czerni z odstepem, na KAZDYM elemencie interaktywnym.
   Regula ogolna wystarczy, bo nigdzie nie gasimy outline bez podstawienia
   wlasnego pierscienia na opakowaniu pola (patrz .ntb-field, .ntb-search).
   z-index podnosi obrys nad sasiadow w siatkach bez odstepow. */
:focus-visible { outline: var(--bw-heavy) solid var(--c-ink); outline-offset: 2px; z-index: 1; }

/* Pola wpisywane gasza wlasny outline, wiec pierscien dostaje ich opakowanie. */
.ntb-field:focus-within,
.ntb-search:focus-within,
.ntb-select:focus-within,
.ntb-qty:focus-within,
.ntb-calc__field:focus-within,
.ntb-fgroup__search:focus-within { outline: var(--bw-heavy) solid var(--c-ink); outline-offset: 2px; }

.ntb-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* Kotwica ma ladowac POD przyklejonym naglowkiem, nie za nim.
   scroll-padding na kontenerze przewijania, a nie scroll-margin na kazdym
   celu: dziala tak samo dla kotwicy z adresu, dla skoku wewnatrz strony
   i dla scrollIntoView ze skryptu, a takich celow jest w serwisie sporo
   (#rozmiarowka na 4 623 kartach, #dostawa-zwroty, #ntb-wizyta, #par-N).
   Wysokosc bierzemy z --h-anchor, nie z mierzonego --ntb-head-h - dlaczego,
   opisuje komentarz przy tokenie. */
html { scroll-padding-top: var(--h-anchor); }

/* Ceny, rozmiary i liczby zawsze tabelarycznie, zeby kolumny sie zgadzaly. */
.ntb-num, .price, .woocommerce-Price-amount { font-variant-numeric: tabular-nums; }

/* ============================================================
   4. UKLAD STRONY
   ============================================================ */

/* Kontener wg D06: domyslnie 1560 px z marginesem bocznym 40 px.
   Strona glowna jest jedynym widokiem w siatce 1440/32 px - to WYJATEK
   wlaczany modyfikatorem, nie wartosc domyslna systemu. Modyfikator dziala
   dwojako: przez klase body.home, ktora WordPress daje sam, albo przez
   jawna klase .ntb-shell--home dopisana w szablonie. */
.ntb-shell { display: flex; align-items: stretch; max-width: var(--w-page); margin-inline: auto; }
body.home,
.ntb-shell--home { --w-page: 1440px; --pad-page: 32px; }
.ntb-main { flex: 1; min-width: 0; }
.ntb-wrap { padding-inline: var(--pad-page); }
.ntb-section { padding-top: var(--s-11); }
.ntb-section--tight { padding-top: var(--s-9); }

/* --- Naglowek sekcji: tytul H2, lead i link po prawej --- */
.ntb-sechead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-7);
  padding-bottom: var(--s-5);
  border-bottom: var(--bw-hair) solid var(--c-line);
}
.ntb-sechead__title { font-size: var(--fs-850); }
.ntb-sechead__lead { margin-top: 10px; font-size: var(--fs-400); color: var(--c-ink-3); max-width: var(--w-text); }
.ntb-sechead__link { flex: none; }

/* ============================================================
   5. PRZYCISKI, LINKI, POLA, KAFLE ROZMIARU
   Wymiary wg README par. 3 i D08. Hover zawsze przez inwersje czerni
   i bieli, nigdy przez kolor. Kazdy stan aktywny to czarne wypelnienie
   i bialy tekst.
   ============================================================ */

.ntb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: var(--h-btn);
  padding-inline: 22px;
  border: var(--bw-hair) solid var(--c-ink);
  border-radius: var(--r-0);
  background: var(--c-ink);
  color: var(--c-on-ink);
  font-size: var(--fs-300);
  font-weight: var(--fw-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
/* Inwersja z wewnetrzna ramka, zeby przycisk nie tracil konturu na bieli. */
.ntb-btn:hover { background: var(--c-bg); color: var(--c-ink); box-shadow: inset 0 0 0 1px var(--c-ink); }

.ntb-btn--ghost { background: var(--c-bg); color: var(--c-ink); }
.ntb-btn--ghost:hover { background: var(--c-ink); color: var(--c-on-ink); box-shadow: none; }

.ntb-btn--block { width: 100%; }

.ntb-btn[disabled], .ntb-btn[aria-disabled="true"] {
  border-color: var(--c-line);
  background: var(--c-paper);
  color: var(--c-ink-3);
  pointer-events: none;
}
.ntb-btn.is-busy { opacity: .6; pointer-events: none; }

.ntb-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-300);
  font-weight: var(--fw-medium);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.ntb-link--caps {
  font-size: var(--fs-200);
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none;
}

/* Pole formularza 48 px, ramka --c-control, ramka czerni w stanie aktywnym.
   Ramka jest tu JEDYNYM sygnalem, ze cos jest do wypelnienia, wiec nie moze
   stac na --c-line-2 (1,73:1 przy wymaganych 3:1 z WCAG 1.4.11). */
.ntb-field {
  display: flex;
  align-items: center;
  height: var(--h-field);
  border: var(--bw-hair) solid var(--c-control);
  background: var(--c-bg);
}
.ntb-field:focus-within { border-color: var(--c-ink); }
.ntb-field input {
  flex: 1;
  min-width: 0;
  height: 100%;
  padding-inline: 14px;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-400);
  color: var(--c-ink);
}
.ntb-field input::placeholder { color: var(--c-ink-4); }
.ntb-field input:focus { outline: none; }
/* Jednostka w polu oddzielona hairline (par. 3). */
.ntb-field__unit { display: flex; align-items: center; height: 100%; padding-inline: 14px; border-left: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); color: var(--c-ink-3); }

/* Checkbox i radio: 15 px w filtrach, 20 px w formularzach, kropka radia 10 px. */
.ntb-check, .ntb-radio {
  flex: none;
  width: var(--box-form);
  height: var(--box-form);
  display: grid;
  place-items: center;
  border: var(--bw-hair) solid var(--c-control);
  background: var(--c-bg);
}
.ntb-radio { border-radius: var(--r-round); }
.ntb-check[aria-checked="true"], .ntb-check.is-on { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-radio[aria-checked="true"]::before, .ntb-radio.is-on::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: var(--r-round);
  background: var(--c-ink);
}

/* --- Etykiety i znaczniki --- */
.ntb-tag {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding-inline: 9px;
  background: var(--c-ink);
  color: var(--c-on-ink);
  font-size: var(--fs-50);
  font-weight: var(--fw-semibold);
  letter-spacing: .12em;
  text-transform: uppercase;
}
.ntb-tag--outline { background: var(--c-bg); color: var(--c-ink); box-shadow: inset 0 0 0 1px var(--c-ink); }

/* --- Wiersz dostepnosci: cztery stany D04, rozroznienie ikona i waga, nie kolorem ---
   Ikone wstawia szablon ze sprite (znacznik / zegar / dzwonek / info).
   Nigdzie nie pojawia sie liczba sztuk (regula 1). */
.ntb-avail {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 20px;
  font-size: var(--fs-300);
  color: var(--c-ink-2);
}
.ntb-avail svg { flex: none; color: currentColor; }
.ntb-avail--available { color: var(--c-ink); font-weight: var(--fw-medium); }
.ntb-avail--backorder { color: var(--c-ink-2); }
.ntb-avail--soon { color: var(--c-ink-3); }
.ntb-avail--discontinued { color: var(--c-ink-3); text-decoration: line-through; text-decoration-color: var(--c-line-2); }
/* Wiersz dostepnosci wstawiany przez WooCommerce jest akapitem, nie spanem. */
p.ntb-avail { display: flex; margin: 0; }

/* --- Komunikaty systemowe (regula 5, D07) ---
   Bez kolorow funkcyjnych: ramka 1 px czerni, tlo panelu i ikona po lewej.
   Ikona jest maska SVG w kolorze --c-ink, wiec komunikat wstawiony z JS
   (zwykly akapit bez markupu ikony) tez ja dostaje. */
.ntb-notice, .ntb-msg {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--touch);
  padding: 12px 14px;
  border: var(--bw-hair) solid var(--c-ink);
  background: var(--c-paper);
  font-size: var(--fs-400);
  color: var(--c-ink);
}
.ntb-notice::before, .ntb-msg::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  background: var(--c-ink);
  -webkit-mask: var(--i-alert) center / 18px 18px no-repeat;
  mask: var(--i-alert) center / 18px 18px no-repeat;
}
/* Komunikat ma juz wlasna ikone w markupie - maska bylaby jej duplikatem. */
.ntb-notice:has(> svg)::before, .ntb-msg:has(> svg)::before { display: none; }

/* --- Kafelek rozmiaru: cztery warianty (README par. 3) ---
   Baza to wariant fasety 56x38. Modyfikatory: --lg karta produktu 74x48,
   --sm lista 44x28, --range kask z zakresem 108x58. */
.ntb-sizes { display: flex; flex-wrap: wrap; gap: 6px; }
.ntb-size {
  min-width: var(--tile-f-w);
  min-height: var(--tile-f-h);
  padding-inline: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: var(--bw-hair) solid var(--c-line-2);
  background: var(--c-bg);
  font-size: var(--fs-300);
  font-variant-numeric: tabular-nums;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ntb-size:hover { border-color: var(--c-ink); }
.ntb-size[aria-pressed="true"] { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); font-weight: var(--fw-medium); }

/* Kafelek na liscie produktow: 44x28, tylko nosnik stanu, nigdy kontrolka. */
.ntb-size--sm {
  min-width: var(--tile-s-w);
  min-height: var(--tile-s-h);
  padding-inline: 6px;
  font-size: var(--fs-200);
}
/* Kask i kalkulatory: kafelek z zakresem pomiaru pod nazwa rozmiaru. */
.ntb-size--range {
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-width: var(--tile-r-w);
  min-height: var(--tile-r-h);
  line-height: var(--lh-tight);
}
.ntb-size--range span { font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-size--range[aria-pressed="true"] span { color: var(--c-on-ink); }

/* Cztery stany dostepnosci na kafelku (D04). Rozroznienie wylacznie
   rysunkiem ramki: ciagla, kropkowana, przekreslenie, szraf. */
.ntb-size[data-state="available"] { border-style: solid; }
.ntb-size[data-state="backorder"] { border-style: dashed; }
.ntb-size[data-state="soon"] {
  border-color: var(--c-line);
  color: var(--c-ink-3);
  text-decoration: line-through;
  text-decoration-color: var(--c-line-2);
}
/* Wartosc osi bez pokrycia w wariantach po wyborze drugiej osi (np. rozmiar S,
   ktorego nie ma w wybranym kolorze). Zostaje klikalna, zeby dalo sie zmienic
   zdanie, ale wyglada jak niedostepna - skrypt ustawia to po kazdym wyborze. */
.ntb-size.is-brak-polaczenia,
.ntb-color.is-brak-polaczenia { opacity: .55; }
.ntb-size.is-brak-polaczenia { text-decoration: line-through; }
.ntb-color.is-brak-polaczenia { position: relative; }
.ntb-color.is-brak-polaczenia::after {
	content: "";
	position: absolute;
	inset: 50% 2px auto;
	height: var(--bw-hair);
	background: var(--c-ink-2);
	transform: rotate(-45deg);
}

.ntb-size[data-state="discontinued"] {
  border-color: var(--c-line);
  color: var(--c-ink-3);
  background-image: repeating-linear-gradient(45deg, var(--c-hatch) 0 1px, transparent 1px 10px);
}
.ntb-size[disabled] { pointer-events: none; }
.ntb-size[disabled]:not([data-state]) { border-color: var(--c-line); color: var(--c-ink-3); text-decoration: line-through; }

/* Grupa rozmiarow po probie dodania bez wyboru: ramka czerni, nigdy czerwien. */
.ntb-sizes.is-required .ntb-size:not([disabled]) { border-color: var(--c-ink); }

/* --- Chip filtra: 40 px w bazie, 34 px gdy niesie krzyzyk odznaczenia --- */
.ntb-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--h-chip);
  padding-inline: 14px;
  border: var(--bw-hair) solid var(--c-ink);
  background: var(--c-bg);
  font-size: var(--fs-300);
}
.ntb-chip button { border: 0; background: none; padding: 0; line-height: 0; color: currentColor; }
.ntb-chip--x, .ntb-chips .ntb-chip { min-height: var(--h-chip-x); padding-inline: 12px; }
a.ntb-chip:hover { background: var(--c-ink); color: var(--c-on-ink); }

/* --- Swatche koloru, czarno-biale z obwodka --- */
.ntb-swatches { display: flex; gap: 6px; }
.ntb-swatch { width: 12px; height: 12px; border-radius: var(--r-round); border: var(--bw-hair) solid var(--c-line-2); }
.ntb-swatch[aria-pressed="true"] { outline: 1px solid var(--c-ink); outline-offset: 2px; }

/* ============================================================
   6. PLACEHOLDER OBRAZU
   Pelnoprawny element systemu, nie stan awaryjny.
   ============================================================ */

.ntb-ph {
  position: relative;
  display: grid;
  place-items: center;
  background: var(--c-bg);
  border: var(--bw-hair) solid var(--c-line);
  overflow: hidden;
}
.ntb-ph::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(45deg, var(--c-hatch) 0 1px, transparent 1px 10px);
}
.ntb-ph__body { position: relative; display: grid; gap: 7px; justify-items: center; padding-inline: var(--s-5); text-align: center; }
.ntb-ph__name { font-size: var(--fs-100); letter-spacing: .18em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-ph__spec { font-size: var(--fs-100); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-ph--product { aspect-ratio: var(--ar-product); }
.ntb-ph--editorial { aspect-ratio: var(--ar-editorial); }
.ntb-ph--hero { aspect-ratio: var(--ar-hero-d); }

/* ============================================================
   7. FOTOGRAFIA
   Lifestyle monochromatycznie, produkt w kolorze na bieli.
   Na produkcji pliki lifestyle eksportujemy w skali szarosci,
   klasa nizej jest zabezpieczeniem dla zdjec wgranych w kolorze.
   ============================================================ */

.ntb-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Kadry redakcyjne w kolorze - decyzja wlasciciela (8 wrzesnia 2026).
   Filtr grayscale(1) byl zabezpieczeniem na wypadek kolorowych plikow;
   od dzis kolor jest zamierzony: stonowany, ziemisty, bez soczystych zieleni,
   zeby nie klocil sie z monochromatyczna paleta interfejsu. Klasa zostaje
   jako punkt zaczepienia (jeden filtr i jedna decyzja, nie rozsiane style). */
.ntb-img--mono { filter: contrast(1.02) saturate(.85); }
.ntb-frame { position: relative; overflow: hidden; background: var(--c-hatch); }
.ntb-frame--editorial { aspect-ratio: var(--ar-editorial); }
.ntb-frame--product { aspect-ratio: var(--ar-product); }
/* Przyciemnienie pod podpisem na zdjeciu. Przezroczystosc daje opacity
   warstwy, nie kolor z kanalem alfa - paleta zostaje zamknieta. */
.ntb-scrim {
  position: absolute;
  inset: auto 0 0 0;
  height: 120px;
  background: linear-gradient(to top, var(--c-ink), transparent);
  opacity: .55;
  pointer-events: none;
}

/* ============================================================
   8. PIONOWY PASEK DZIALOW
   Szesc ikon, panel wysuwany, aktywna pozycja z czarnym znacznikiem.
   ============================================================ */

.ntb-rail {
  position: sticky;
  top: 0;
  align-self: flex-start;
  z-index: var(--z-rail);
  width: var(--rail-w);
  flex: none;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: var(--s-5);
  gap: 2px;
  background: var(--c-bg);
  border-right: var(--bw-hair) solid var(--c-line);
}
/* Slot dzialu: panel jest RODZENSTWEM kotwicy, nie jej dzieckiem (inc/nav.php),
   wiec to slot jest kontenerem pozycjonujacym i nosnikiem hover oraz focus.
   Bez tej klasy panel nie ma sie na czym oprzec i wypada w lewy gorny rog. */
.ntb-rail__slot { position: relative; width: var(--rail-w); }

.ntb-rail__item {
  position: relative;
  width: var(--rail-w);
  height: 60px;
  display: grid;
  place-items: center;
  color: var(--c-ink-2);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ntb-rail__item:hover, .ntb-rail__item:focus-visible { background: var(--c-ink); color: var(--c-on-ink); }
.ntb-rail__slot:hover .ntb-rail__item, .ntb-rail__slot:focus-within .ntb-rail__item { background: var(--c-ink); color: var(--c-on-ink); }
.ntb-rail__item[aria-current="true"] { background: var(--c-paper); color: var(--c-ink); }
.ntb-rail__item[aria-current="true"]::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: var(--bw-heavy);
  background: var(--c-ink);
}
.ntb-rail__label { writing-mode: vertical-rl; font-size: var(--fs-50); letter-spacing: .22em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-rail__rule { width: 24px; height: 1px; background: var(--c-line); margin-block: 14px; }

/* Panel dzialu wysuwany ze slotu. Linki kategorii sa w HTML zawsze, wiec robot
   je widzi. Panel otwiera hover i focus wewnatrz slotu, wiec z klawiatury nic
   nie ginie. Selektor [data-open="true"] jest ZAREZERWOWANY dla JS i dzis nikt
   go nie ustawia (assets/js/ntb.js nie zna railu), czyli na ekranie dotykowym
   szerszym niz 1200 px panel pozostaje niedostepny - do domkniecia razem
   z obsluga railu w JS. Ponizej 1200 px rail znika, a te same linki niesie
   pelne drzewo kategorii. */
.ntb-rail__panel {
  position: absolute;
  left: var(--rail-w);
  top: 0;
  width: 420px;
  padding: var(--s-6);
  background: var(--c-bg);
  border: var(--bw-hair) solid var(--c-ink);
  opacity: 0;
  transform: translateX(-8px);
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.ntb-rail__slot:hover .ntb-rail__panel,
.ntb-rail__slot:focus-within .ntb-rail__panel,
.ntb-rail__panel[data-open="true"] { opacity: 1; transform: none; pointer-events: auto; }
.ntb-rail__panel h2 { font-size: var(--fs-700); }
.ntb-rail__panel ul { columns: 2; column-gap: var(--s-6); margin-top: var(--s-4); }
.ntb-rail__panel li { break-inside: avoid; }
.ntb-rail__panel a { display: block; padding-block: 6px; font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-rail__panel a:hover { color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }

/* ============================================================
   9. NAGLOWEK
   Pasek gorny z wyszukiwarka jako najwiekszym elementem,
   pasek drugi z drzewem kategorii, menu tresciowym i ikonami.
   ============================================================ */

.ntb-header { background: var(--c-bg); }
.ntb-header__top { height: var(--header-h); display: flex; align-items: center; gap: var(--s-7); }

.ntb-logo { flex: none; display: grid; gap: 5px; }
.ntb-logo img { width: 112px; height: 45px; }
.ntb-logo__sub { font-size: var(--fs-50); letter-spacing: .24em; text-transform: uppercase; color: var(--c-ink-3); }

/* Wyszukiwarka ma 54 px zamiast normy pola 48-50 px. To SWIADOMY WYJATEK
   strony glownej wg D08: szukajka jest tam najwiekszym elementem nad zgieciem.
   Audyt go nie zglasza, ale nie wolno go kopiowac do innych pol. */
.ntb-search { flex: 1; max-width: 672px; display: flex; height: 54px; border: var(--bw-hair) solid var(--c-ink); }
.ntb-search__icon { width: 54px; display: grid; place-items: center; color: var(--c-ink-3); }
.ntb-search input { flex: 1; min-width: 0; border: 0; background: none; font: inherit; font-size: var(--fs-500); }
.ntb-search input:focus { outline: none; }
.ntb-search button {
  width: 132px;
  flex: none;
  border: 0;
  background: var(--c-ink);
  color: var(--c-on-ink);
  font-size: var(--fs-300);
  font-weight: var(--fw-medium);
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: opacity var(--dur) var(--ease);
}
.ntb-search button:hover { opacity: .82; }

.ntb-service { flex: none; display: flex; align-items: center; gap: var(--s-6); }
.ntb-service__item { display: flex; align-items: center; gap: 10px; }
.ntb-service__item svg { color: var(--c-ink-2); }
.ntb-service__t { display: block; font-size: var(--fs-400); font-weight: var(--fw-medium); }
.ntb-service__s { display: block; font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-rule-v { width: 1px; height: 32px; background: var(--c-line); }

.ntb-header__nav {
  height: var(--header-sticky-h);
  display: flex;
  align-items: center;
  gap: var(--s-6);
  border-top: var(--bw-hair) solid var(--c-line);
  border-bottom: var(--bw-hair) solid var(--c-line);
}
/* Przycisk pelnego drzewa ma 38 px zamiast normy przycisku 52-56 px.
   SWIADOMY WYJATEK strony glownej wg D08 - na 390 px i tak go nie ma,
   bo Kategorie siedza w dolnym pasku mobilnym. */
.ntb-treebtn {
  flex: none;
  height: 38px;
  padding-inline: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 0;
  background: var(--c-ink);
  color: var(--c-on-ink);
  font-size: var(--fs-400);
  font-weight: var(--fw-medium);
}
.ntb-menu { flex: 1; display: flex; align-items: center; gap: 26px; font-size: var(--fs-400); }
.ntb-menu a:hover { text-decoration: underline; text-underline-offset: 4px; }
.ntb-tools { flex: none; display: flex; align-items: center; gap: 22px; }
/* Ikona narzedzia ma wlasne pole dotyku 44 px takze na desktopie: sama ikona
   ma 21 px, wiec bez tego cel bylby o polowe za maly (regula 3). */
.ntb-tools__item { position: relative; display: grid; place-items: center; min-width: var(--touch); min-height: var(--touch); }
.ntb-count {
  position: absolute;
  top: -6px;
  right: -9px;
  min-width: 16px;
  height: 16px;
  padding-inline: 4px;
  display: grid;
  place-items: center;
  background: var(--c-ink);
  color: var(--c-on-ink);
  font-size: var(--fs-50);
  font-weight: var(--fw-semibold);
}
/* KOLIZJA NAZW: `.ntb-cart` w naglowku to odnosnik do koszyka (ikona i suma),
   a `.ntb-cart` w woocommerce/cart/cart.php to opakowanie CALEGO widoku
   koszyka. Bez zawezenia do elementu <a> strona koszyka dostawala
   display: flex i szerokosc 44 px, przez co uklad wyjezdzal poza ekran
   o 172 px na 390 px (zmierzone). Naglowkowy jest kotwica, stronowy divem. */
a.ntb-cart { display: flex; align-items: center; gap: 10px; }
.ntb-cart__total { font-size: var(--fs-400); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }

/* Stan przyklejony: gorny pasek chowa sie, drugi zostaje w skroconej formie. */
.ntb-header.is-stuck { position: sticky; top: 0; z-index: var(--z-header); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-header.is-stuck .ntb-header__top { height: 0; overflow: hidden; }
.ntb-header.is-stuck .ntb-header__nav { height: var(--header-sticky-h); border-top: 0; }

/* --- Panel pelnego drzewa kategorii ---
   Przyciemnienie tla to czern z opacity warstwy, nie kolor z alfa. */
.ntb-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--c-ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}
.ntb-overlay[data-open="true"] { opacity: .55; pointer-events: auto; }

.ntb-tree {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: var(--z-panel);
  width: min(860px, 92vw);
  display: grid;
  grid-template-columns: 320px 1fr;
  background: var(--c-bg);
  transform: translateX(-100%);
  transition: transform var(--dur) var(--ease);
}
.ntb-tree[data-open="true"] { transform: none; }

/* Naglowek panelu kategorii: tytul po lewej, ✕ po prawej, linia 1 px pod
   spodem (projekt NTB24 Mobile.dc.html sekcja 02). Na desktopie panel
   otwiera sie pod naglowkiem strony i ma wlasny rzad zakladek dzialow,
   wiec ten naglowek nie powstaje wcale. */
.ntb-tree__head { display: none; }
.ntb-tree__title { font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); line-height: var(--lh-tight); }

/* Zamkniecie szuflady kategorii. Na telefonie to jedyna droga powrotna,
   bo overlay pojawia sie tylko przy otwarciu z JS, a wejscie kotwica
   (#ntb-tree, wersja bez JS) go nie tworzy. Cel dotykowy 44 px. */
.ntb-tree__close {
  flex: none;
  display: none;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  padding: 0;
  border: var(--bw-hair) solid var(--c-line);
  background: var(--c-bg);
  color: var(--c-ink);
  cursor: pointer;
}
.ntb-tree__close:hover,
.ntb-tree__close:focus-visible { background: var(--c-ink); color: var(--c-bg); }
.ntb-tree__cols { border-right: var(--bw-hair) solid var(--c-line); overflow-y: auto; }
.ntb-tree__dept {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px var(--s-5);
  border-bottom: var(--bw-hair) solid var(--c-line);
  font-size: var(--fs-400);
}
.ntb-tree__dept[aria-expanded="true"] { background: var(--c-paper); font-weight: var(--fw-medium); }
.ntb-tree__dept svg:last-child { margin-left: auto; }
.ntb-tree__sub { padding: var(--s-6); overflow-y: auto; }
.ntb-tree__sub ul { columns: 2; column-gap: var(--s-6); }
.ntb-tree__sub a { display: flex; align-items: center; min-height: var(--touch); padding-block: 7px; font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-tree__dept { min-height: var(--touch); }

/* ============================================================
   10. HERO STRONY GLOWNEJ
   ============================================================ */

.ntb-hero { display: grid; grid-template-columns: minmax(0, 592px) minmax(0, 1fr); min-height: 552px; }
.ntb-hero__panel { background: var(--c-paper); padding: 52px 56px 44px; display: flex; flex-direction: column; }
.ntb-hero__h1 { margin-top: 18px; font-size: var(--fs-1000); line-height: var(--lh-tight); max-width: var(--w-head); }
.ntb-hero__lead { margin-top: 20px; font-size: var(--fs-500); line-height: var(--lh-body); color: var(--c-ink-2); max-width: var(--w-text); }
.ntb-hero__tools { margin-top: auto; padding-top: 36px; }

.ntb-tool {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 17px 4px;
  border-top: var(--bw-hair) solid var(--c-line-2);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), padding var(--dur) var(--ease);
}
.ntb-tool:last-of-type { border-bottom: var(--bw-hair) solid var(--c-line-2); }
.ntb-tool:hover { background: var(--c-ink); color: var(--c-on-ink); padding-inline: 14px; }
.ntb-tool__icon { flex: none; }
/* Ikony-obrazy (option ntb24_ikony) zastepuja piktogramy ze sprite'a: ten sam
   flex: none, inaczej na 390 px tekst sciskal <img> do 12-17 px (odbior 17.09.2026).
   Na czarnym tle kafla po najechaniu realistyczna ikona dostaje jasna plakietke. */
.ntb-ikona { flex: none; }
.ntb-tool:hover .ntb-ikona { background: var(--c-on-ink); border-radius: 4px; box-shadow: 0 0 0 3px var(--c-on-ink); }
.ntb-tool__body { flex: 1; display: grid; gap: 3px; }
.ntb-tool__t { font-size: var(--fs-500); font-weight: var(--fw-medium); }
.ntb-tool__s { font-size: var(--fs-300); opacity: .7; }
.ntb-hero__caption { position: absolute; left: 28px; bottom: 22px; font-size: var(--fs-100); letter-spacing: .16em; text-transform: uppercase; color: var(--c-on-ink); }

/* ============================================================
   11. KAFLE DZIALOW
   ============================================================ */

.ntb-depts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px 32px; margin-top: 40px; }
.ntb-dept__media { position: relative; display: block; }
.ntb-dept__badge {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  background: var(--c-bg);
  color: var(--c-ink);
}
.ntb-dept__title { margin-top: 18px; font-size: var(--fs-700); }
.ntb-dept__list { margin-top: 12px; display: grid; gap: 7px; }
.ntb-dept__list a { font-size: var(--fs-400); color: var(--c-ink-2); }
.ntb-dept__list a:hover { color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }
.ntb-dept__more { margin-top: 14px; }

/* ============================================================
   12. KARTA PRODUKTU W PETLI
   Projekt v2 wg D11: kadr, marka, nazwa, chipy rozmiarow, wiersz
   dostepnosci, cena. Bez gwiazdek, bez panelu na hover, bez koszyka.
   ============================================================ */

.ntb-grid { display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr)); gap: 32px; margin-top: 36px; }

.ntb-card { display: flex; flex-direction: column; }
.ntb-card__media { position: relative; }
.ntb-card__media .ntb-frame, .ntb-card__media .ntb-ph { border: var(--bw-hair) solid var(--c-line); }
.ntb-card:hover .ntb-card__media .ntb-ph,
.ntb-card:hover .ntb-card__media .ntb-frame { border-color: var(--c-ink); }
.ntb-card__tag { position: absolute; left: 12px; top: 12px; }
.ntb-card__tag--magazyn { top: auto; bottom: 12px; background: var(--c-paper); pointer-events: none; }

/* Ulubione i porownanie sa widoczne ZAWSZE. Wczesniej odslanial je hover,
   czyli na telefonie nie istnialy (regula 3). Hover i focus zmieniaja
   wylacznie wypelnienie przycisku. */
.ntb-card__acts { position: absolute; right: 8px; top: 8px; display: grid; gap: 6px; }
.ntb-card__act {
  width: var(--touch);
  height: var(--touch);
  display: grid;
  place-items: center;
  background: var(--c-bg);
  border: var(--bw-hair) solid var(--c-line);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ntb-card__act:hover, .ntb-card__act:focus-visible, .ntb-card__act[aria-pressed="true"] { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }

.ntb-card__brand { margin-top: 14px; font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-card__name { display: block; margin-top: 6px; font-size: var(--fs-400); line-height: var(--lh-label); }
.ntb-card__sizes { margin-top: 11px; }
.ntb-card .ntb-avail { margin-top: 10px; }
.ntb-card__price { margin-top: 12px; display: flex; align-items: baseline; gap: 10px; font-size: var(--fs-600); font-weight: var(--fw-medium); }
/* Akcja kafla (od 5.10.2026): "Do koszyka" przy produkcie prostym, "Wybierz
   rozmiar" przy wariantowym. Cala szerokosc kafla, bo na 390 px kafel ma 170 px
   i przycisk w pol szerokosci nie mialby celu dotykowego 44 px. Margines
   gorny 12 px trzyma rytm z cena. */
.ntb-card__buy { margin-top: 12px; }
.ntb-card__btn { margin-top: 12px; width: 100%; justify-content: center; }
.ntb-card__buy .ntb-card__btn { margin-top: 0; }
.ntb-card__price del { font-size: var(--fs-300); color: var(--c-ink-3); font-weight: var(--fw-regular); }
/* Omnibus: najnizsza cena z 30 dni przed obnizka - wiersz pod cena wszedzie,
   gdzie stoi cena promocyjna (ntb24-core/inc/omnibus.php). W pasku zakupu
   na telefonie nie ma na niego miejsca - jest na karcie nad paskiem. */
.ntb-omnibus { display: block; flex: 1 1 100%; margin-top: 2px; font-size: var(--fs-200); font-weight: var(--fw-regular); line-height: var(--lh-body); color: var(--c-ink-3); letter-spacing: 0; }
.ntb-omnibus .woocommerce-Price-amount { font-weight: var(--fw-medium); color: var(--c-ink-2); }
.ntb-buybar .ntb-omnibus, .ntb-cartpanel .ntb-omnibus, .ntb-cartrow .ntb-omnibus, .ntb-oreview .ntb-omnibus { display: none; }
.ntb-buy__price .ntb-omnibus { font-size: var(--fs-300); }

/* Gwiazdki zyja juz tylko w opiniach na karcie produktu, nie w petli. */
.ntb-card__stars { display: flex; gap: 2px; }
.ntb-card__stars svg { width: 12px; height: 12px; }
.ntb-card__stars svg[data-off] { color: var(--c-line-2); }
.ntb-card__swatches { margin-top: 11px; }

/* ============================================================
   13. PASY TRESCIOWE STRONY GLOWNEJ
   ============================================================ */

.ntb-band { background: var(--c-paper); padding: 56px 56px 52px; }
.ntb-cols3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px; margin-top: 40px; }
.ntb-usp { border-top: var(--bw-hair) solid var(--c-line-2); padding-top: 22px; }
.ntb-usp__t { margin-top: 18px; font-family: var(--f-ui); font-size: var(--fs-600); font-weight: var(--fw-medium); letter-spacing: 0; }
.ntb-usp__p { margin-top: 9px; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-usp .ntb-link { margin-top: 14px; }

/* Marki: stala liczba kolumn wg D12, nigdy auto-fit. Dwanascie kafli
   dzieli sie bez reszty na 4, 3 i 2, wiec zaden rzad nie zostaje pusty. */
.ntb-brands { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-left: var(--bw-hair) solid var(--c-line); }
.ntb-brands a {
  padding: 26px 20px;
  border-right: var(--bw-hair) solid var(--c-line);
  border-bottom: var(--bw-hair) solid var(--c-line);
  font-family: var(--f-display);
  font-size: var(--fs-600);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ntb-brands a:hover { background: var(--c-ink); color: var(--c-on-ink); }

.ntb-showroom { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 560px); }
.ntb-showroom__media { position: relative; overflow: hidden; background: var(--c-hatch); min-height: 420px; }
.ntb-showroom__panel { background: var(--c-paper); padding: 52px 48px; display: flex; flex-direction: column; }
.ntb-hours { margin-top: 28px; display: grid; grid-template-columns: auto 1fr; gap: 12px 20px; font-size: var(--fs-400); }
.ntb-hours dt { display: flex; align-items: center; gap: 9px; color: var(--c-ink-3); }
.ntb-hours dd { margin: 0; font-variant-numeric: tabular-nums; }
/* CTA showroomu ma 46 px zamiast normy 52-56 px. SWIADOMY WYJATEK strony
   glownej wg D08 - nie podnosimy go, ale i nie kopiujemy dalej. */
.ntb-showroom__panel .ntb-btn { margin-top: auto; align-self: flex-start; min-height: 46px; }

/* --- Galeria showroomu (template-parts/showroom-galeria.php) ---------------
   Kafle 4:5 w siatce 4 kolumn (2 na telefonie); podglad przez :target na caly
   ekran, bez skryptu: przeslona i X wracaja do #galeria, strzalki to kotwice
   sasiednich zdjec. Pasek na stronie glownej (.ntb-showroom__strip) to ta
   sama lista bez podgladu - kafle prowadza do /showroom/#galeria. */
.ntb-galeria { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-3); margin: var(--s-6) 0 0; padding: 0; list-style: none; }
.ntb-galeria__item { margin: 0; }
.ntb-galeria__link { position: relative; display: block; aspect-ratio: 4 / 5; overflow: hidden; background: var(--c-hatch); }
.ntb-galeria__img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur) var(--ease); }
.ntb-galeria__link:hover .ntb-galeria__img, .ntb-galeria__link:focus-visible .ntb-galeria__img { transform: scale(1.03); }
.ntb-showroom__strip .ntb-galeria { margin-top: var(--s-3); }
.ntb-lbox { position: fixed; inset: 0; z-index: var(--z-modal); display: none; align-items: center; justify-content: center; padding: var(--s-4); background: var(--c-ink); }
.ntb-lbox:target { display: flex; }
html:has(.ntb-lbox:target) { overflow: hidden; }
.ntb-lbox__backdrop { position: absolute; inset: 0; }
.ntb-lbox__fig { position: relative; z-index: 1; margin: 0; max-width: min(1200px, 100%); max-height: 100%; display: flex; flex-direction: column; align-items: center; pointer-events: none; }
.ntb-lbox__img { display: block; width: auto; height: auto; max-width: 100%; max-height: calc(100vh - 2 * var(--s-4) - 44px); object-fit: contain; pointer-events: auto; }
.ntb-lbox__cap { display: flex; gap: var(--s-3); align-items: baseline; min-height: 44px; padding-top: 10px; font-size: var(--fs-300); color: var(--c-line); }
.ntb-lbox__cap .ntb-num { flex: none; white-space: nowrap; color: var(--c-on-ink); }
.ntb-lbox__nav, .ntb-lbox__close { position: absolute; z-index: 2; display: grid; place-items: center; width: var(--touch); height: var(--touch); background: var(--c-bg); color: var(--c-ink); }
.ntb-lbox__nav:hover, .ntb-lbox__close:hover { background: var(--c-paper); }
.ntb-lbox__nav { top: 50%; transform: translateY(-50%); }
.ntb-lbox__nav--prev { left: var(--s-4); }
.ntb-lbox__nav--prev svg { transform: rotate(180deg); }
.ntb-lbox__nav--next { right: var(--s-4); }
.ntb-lbox__close { top: var(--s-4); right: var(--s-4); }
/* Kadr showroomu na /showroom/: pas na cala szerokosc kontenera (12:5 na
   desktopie, 3:2 na telefonie), zdjecie kadrowane object-fit. */
@media (min-width: 768px) { .ntb-showroom-kadr .ntb-frame { aspect-ratio: 12 / 5; } }
@media (max-width: 767px) {
	.ntb-galeria { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
	.ntb-lbox { padding: 0; }
	.ntb-lbox__img { max-height: calc(100vh - 88px); }
	.ntb-lbox__cap { padding-inline: var(--s-4); }
	.ntb-lbox__nav { top: auto; bottom: 0; transform: none; }
	.ntb-lbox__nav--prev { left: 0; }
	.ntb-lbox__nav--next { right: 0; }
	.ntb-lbox__close { top: 0; right: 0; }
}

.ntb-posts { margin-top: 8px; }
.ntb-post {
  display: flex;
  align-items: center;
  gap: 32px;
  padding: 26px 8px;
  border-bottom: var(--bw-hair) solid var(--c-line);
  transition: background var(--dur) var(--ease), padding var(--dur) var(--ease);
}
.ntb-post:hover { background: var(--c-paper); padding-inline: 20px; }
/* Wpis bez kategorii zostawial w kazdym wierszu pusta kolumne 150 px, przez
   ktora tytul zaczynal sie 190 px od marginesu strony. Pusty slot nie niesie
   niczego, wiec go nie ma. */
.ntb-post__cat:empty { display: none; }
.ntb-post__cat { flex: none; width: 150px; font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-post__t { flex: 1; font-family: var(--f-display); font-size: var(--fs-700); line-height: var(--lh-snug); }
.ntb-post__meta { flex: none; font-size: var(--fs-200); color: var(--c-ink-3); }

.ntb-trust { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: var(--bw-hair) solid var(--c-line); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-trust__item { display: flex; align-items: center; gap: 14px; padding: 26px 24px; border-right: var(--bw-hair) solid var(--c-line); }
.ntb-trust__item:first-child { padding-left: 0; }
.ntb-trust__item:last-child { padding-right: 0; border-right: 0; }
.ntb-trust__item svg, .ntb-trust__item .ntb-ikona { flex: none; color: var(--c-ink-2); }
.ntb-trust__t { display: block; font-size: var(--fs-400); font-weight: var(--fw-medium); }
.ntb-trust__s { display: block; font-size: var(--fs-200); color: var(--c-ink-3); }

/* ============================================================
   14. STOPKA
   ============================================================ */

.ntb-footer { margin-top: 80px; background: var(--c-paper); padding: 64px var(--pad-page) 28px; }
.ntb-footer__kontakt a { display: inline-flex; align-items: center; min-height: var(--touch); }
/* Kontakt: dojazd jako lista adres + przycisk do map (bez mapy osadzonej). */
.ntb-dojazd { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: var(--s-3); }
.ntb-dojazd li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-4); padding: var(--s-3) 0; border-top: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-dojazd .ntb-btn { min-height: var(--touch); padding-inline: 16px; font-size: var(--fs-200); }
.ntb-footer__kontakt { display: grid; }
/* Stopka: piec kolumn wg D12, ostatnia szersza pod newsletter. */
.ntb-footer__cols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)) minmax(0, 348px); gap: 48px; }
.ntb-footer h3 { font-family: var(--f-ui); font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .18em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-footer ul { margin-top: 18px; display: grid; gap: 10px; font-size: var(--fs-400); }
.ntb-footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  margin-top: 52px;
  padding-top: var(--s-5);
  border-top: var(--bw-hair) solid var(--c-line-2);
  /* Dolny wiersz stopki niesie pelne zdanie (nota o prawach i o sklepie),
     wiec obowiazuje go dolna granica tresci, nie stopien etykiety. */
  font-size: var(--fs-300);
  color: var(--c-ink-3);
}

/* ============================================================
   15. DOLNY PASEK MOBILNY
   ============================================================ */

/* Cztery pozycje po 60 px (D10). Liczbe kolumn niesie modyfikator z PHP,
   bo bez WooCommerce pozycja koszyka nie powstaje. Cien wylacznie tutaj
   i na pasku zakupu - to jedyne paski przyklejone w systemie. */
.ntb-mbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: var(--z-mobilebar);
  display: none;
  grid-template-columns: repeat(var(--mbar-cols, 4), minmax(0, 1fr));
  height: calc(var(--mobilebar-h) + var(--safe-b));
  padding-bottom: var(--safe-b);
  background: var(--c-bg);
  border-top: var(--bw-hair) solid var(--c-line);
  box-shadow: var(--sh-bar);
  transform: translateY(0);
  transition: transform var(--dur) var(--ease);
}
.ntb-mbar--cols-3 { --mbar-cols: 3; }
.ntb-mbar--cols-4 { --mbar-cols: 4; }
.ntb-mbar--cols-5 { --mbar-cols: 5; }
.ntb-mbar.is-hidden { transform: translateY(100%); }
.ntb-mbar__item { display: grid; place-items: center; align-items: center; align-content: center; gap: 3px; min-height: var(--mobilebar-h); font-size: var(--fs-100); letter-spacing: .04em; } /* 11 px: etykieta jest jedynym podpisem ikony */
.ntb-mbar__item svg { width: 22px; height: 22px; }
.ntb-mbar__item[aria-current="page"] { background: var(--c-ink); color: var(--c-on-ink); }

/* ============================================================
   16. BREAKPOINTY
   480, 768, 1024, 1200, 1440 px. Siatki maja jawna liczbe kolumn
   na kazdym progu (D12), nigdzie nie ma auto-fit.
   ============================================================ */

@media (max-width: 1199px) {
  .ntb-rail { display: none; }
  .ntb-depts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ntb-grid { --cols: 3; }
  .ntb-brands { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ntb-hero { grid-template-columns: minmax(0, 1fr); }
  .ntb-hero__panel { padding: 40px 32px 32px; }
  .ntb-showroom { grid-template-columns: minmax(0, 1fr); }
  .ntb-footer__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Tablet 768–1199 px: naglowek desktopowy (burger i dolny pasek wchodza
   dopiero ponizej 768 px), ale wiersz nawigacji sie nie miescil - koszyk,
   ulubione i porownywarka wychodzily za prawa krawedz, a strona przewijala
   sie w bok (przeglad 16.09.2026: scrollWidth 1165 px przy 768–1100).
   Mniejsze odstepy, menu przewijane w poziomie, bez sumy koszyka. */
@media (min-width: 768px) and (max-width: 1199px) {
  .ntb-header__nav { gap: var(--s-4); }
  .ntb-menu { min-width: 0; gap: 16px; padding-right: 24px; overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); } /* qa-ok: maska (krycie), nie kolor */
  .ntb-menu::-webkit-scrollbar { display: none; }
  .ntb-menu li { flex: none; }
  .ntb-menu a { white-space: nowrap; }
  .ntb-treebtn { padding-inline: 14px; }
  .ntb-tools { gap: 4px; }
  .ntb-tools .ntb-rule-v,
  .ntb-cart__total { display: none; }
}

@media (max-width: 1023px) {
  .ntb-service { display: none; }
  .ntb-search { max-width: none; }
  /* Porownywarka wraca na karcie produktu; w naglowku 768–1023 px nie ma na nia miejsca. */
  .ntb-tools__item[href*="/porownaj/"] { display: none; }
  .ntb-trust { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ntb-trust__item { padding-inline: 16px; }
  .ntb-post__cat { display: none; }
}

@media (max-width: 767px) {
  /* Margines boczny na telefonie to 16 px w kazdym wariancie kontenera (D06). */
  body, body.home, .ntb-shell--home { --pad-page: 16px; }
  .ntb-section { padding-top: var(--s-9); }
  .ntb-mbar { display: grid; }
  /* Karta produktu nosi pasek zakupu, ktory jest wyzszy od nawigacyjnego:
     10 px + przycisk 52 px + 10 px + wloskowa ramka = 73 px. Bez tej reguly
     zapas zostawal na 60 px i przy wylaczonym JavaScripcie 13 px tresci
     chowalo sie pod paskiem - czyli dokladnie blad D2, tyle ze na sciezce
     bez skryptu. Wartosc liczymy ze skladnikow paska, nie z liczby 73.
     Gdy ntb.js dziala, jego pomiar siedzi w stylu inline na <html> i wygrywa
     z ta regula, wiec zmiana wysokosci paska dalej jest widziana. */
  :root:has(.ntb-buybar) {
    --ntb-bar-h: calc(10px + var(--h-btn) + 10px + var(--bw-hair) + var(--safe-b));
  }
  /* Pasek koszyka ma szerszy wewnetrzny odstep (--s-3 zamiast 10 px), wiec
     jego zapas liczymy z jego wlasnych skladnikow. */
  :root:has(.ntb-buybar--cart) {
    --ntb-bar-h: calc(var(--s-3) + var(--h-btn) + var(--s-3) + var(--bw-hair) + var(--safe-b));
  }
  body { padding-bottom: var(--ntb-bar-h); }
  /* Kotwica ma ladowac nad paskiem, a nie pod nim. */
  html { scroll-padding-bottom: var(--ntb-bar-h); }
  /* Sekcja dzialow rosla z 1 284 do 3 937 px (x3,07) i spychala pierwsza karte
     produktu na 5 595 px, czyli 6,6 ekranu. Winna byla nie siatka, tylko kafel:
     szesc kafli po siedem odnosnikow w jednej kolumnie. Dwie kolumny i kafel
     bez listy podkategorii daja ok. 900 px. Nic nie ginie - te same 52 grupy
     stoja w #ntb-tree i w menu mobilnym. */
  .ntb-depts { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-7) var(--s-5); }
  .ntb-dept__list { display: none; }
  .ntb-grid { --cols: 2; gap: var(--s-5) var(--s-4); }
  .ntb-brands { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ntb-cols3 { grid-template-columns: minmax(0, 1fr); gap: var(--s-6); }
  .ntb-band { padding: 32px 20px; }
  /* Naglowek sekcji lamie sie na dwa wiersze: tytul 36 px i link obok siebie
     nie miescily sie w 390 px i wypychaly strone w bok. */
  .ntb-sechead { flex-wrap: wrap; align-items: flex-start; gap: var(--s-3); }
  .ntb-sechead__title { font-size: var(--fs-800); }
  .ntb-sechead__link { flex: 1 0 100%; }
  .ntb-post__t { font-size: var(--fs-600); }
  .ntb-footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); }
  /* Piaty blok (Newsletter) stal sam w trzecim rzedzie i zajmowal 163 z 358 px,
     zostawiajac pusty prostokat 179x161 px na kazdej stronie serwisu. */
  .ntb-footer__cols > :last-child { grid-column: 1 / -1; }
  .ntb-footer__bottom { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
  /* Szuflada kategorii i jej zamkniecie: reguly stoja w sekcji 28 razem
     z przelacznikiem mega menu i akordeonu - panel jest jednokolumnowy
     ponizej 1024 px, a nie dopiero ponizej 768 px. */

  /* --- Naglowek mobilny wg projektu NTB24 Mobile par. 01 ---
     Rzad pierwszy: logo, konto, koszyk. Rzad drugi: szukajka 48 px na cala
     szerokosc. Drugi pasek desktopowy (drzewo, menu tresciowe, porownywarka,
     ulubione, suma koszyka) nie zwijal sie i wypychal strone o 79 px w bok.
     display: contents rozpuszcza oba paski, wiec ich dzieci trafiaja do jednej
     siatki .ntb-wrap i mozna im nadac kolejnosc bez zmiany markupu.
     Kategorie, Szukaj i Ulubione zyja w dolnym pasku, a Konto w naglowku (D10). */
  .ntb-header .ntb-wrap {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    row-gap: 12px;
    padding-block: 10px 14px;
  }
  .ntb-header__top, .ntb-header__nav { display: contents; }
  .ntb-logo { order: 1; }
  .ntb-logo img { width: 86px; height: 34px; }
  .ntb-tools { order: 2; justify-self: end; gap: 6px; }
  .ntb-search { order: 3; grid-column: 1 / -1; height: var(--h-field); }
  .ntb-search__icon { width: 46px; }
  .ntb-search button { width: auto; padding-inline: 16px; }
  .ntb-service, .ntb-menu, .ntb-treebtn { display: none; }

  /* Porownywarka i ulubione znikaja z naglowka: ulubione sa w dolnym pasku,
     porownywarka wraca na karcie produktu. Suma koszyka schodzi do licznika
     przy ikonie - sam napis mial 74 px i to on wypychal wiersz. */
  .ntb-tools__item[href*="/porownaj/"],
  .ntb-tools__item[href*="/ulubione/"],
  .ntb-tools .ntb-rule-v,
  .ntb-cart__total { display: none; }
  a.ntb-cart { min-height: var(--touch); }

  /* Naglowek przyklejony na telefonie zostawia tylko wiersz z logo i ikonami.
     WYJATEK: pozycja "Szukaj" z dolnego paska to zwykla kotwica #ntb-search
     (inc/nav.php:206) i nie ma za soba zadnego JS. Gdyby szukajka zostawala
     display: none, skok do kotwicy nie mialby na czym wyladowac i przycisk
     bylby martwy przez cale przewijanie - czyli od 160 px w dol strony.
     :target przywraca ja w przyklejonym naglowku (regula 3). */
  .ntb-header.is-stuck .ntb-search { display: none; }
  .ntb-header.is-stuck .ntb-search:target { display: flex; }

  /* Pelne drzewo kategorii otwiera na desktopie [data-ntb-tree-toggle]
     (.ntb-treebtn), a ten jest wyzej ukryty. Na telefonie jedynym wejsciem
     jest pozycja "Kategorie" z dolnego paska, tez zwykla kotwica #ntb-tree -
     bez tej reguly panel zostawalby na translateX(-100%) i cala nawigacja
     kategoriami ginelaby na 390 px. Escape i klikniecie tla nadal dzialaja:
     JS ustawia wtedy data-open="false", ktore wygrywa z :target. */
  .ntb-tree { overflow-y: auto; }
  .ntb-tree:target:not([data-open="false"]) { transform: none; }
}

/* Ruch ograniczony: zostaje sama zmiana stanu, bez przejsc i przewijania. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   17. OKRUSZKI, PANEL KOSZYKA, ILOSC
   ============================================================ */

.ntb-icon { flex: none; }

.ntb-crumbs { padding-block: var(--s-4); font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ntb-crumbs li { display: flex; align-items: center; gap: 8px; }
.ntb-crumbs li:not(:last-child)::after { content: "/"; color: var(--c-line-2); }
.ntb-crumbs a { color: var(--c-ink-3); }
.ntb-crumbs a:hover { color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }
.ntb-crumbs [aria-current="page"] { color: var(--c-ink); }

/* --- Panel koszyka, wysuwany z prawej na cala wysokosc okna --- */
.ntb-cartpanel {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: var(--z-panel);
  width: min(440px, 94vw);
  display: flex;
  flex-direction: column;
  background: var(--c-bg);
  border-left: var(--bw-hair) solid var(--c-ink);
  transform: translateX(100%);
  transition: transform var(--dur) var(--ease);
}
.ntb-cartpanel[data-open="true"] { transform: none; }
.ntb-cartpanel__head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s-5) var(--s-5) var(--s-4);
  border-bottom: var(--bw-hair) solid var(--c-line);
}
.ntb-cartpanel__head h2 { font-size: var(--fs-700); }
.ntb-cartpanel__close { display: grid; place-items: center; width: var(--touch); height: var(--touch); margin-right: -10px; border: 0; background: none; padding: 0; line-height: 0; }

.ntb-cartpanel__ship { flex: none; padding: var(--s-4) var(--s-5); border-bottom: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); }
.ntb-bar { display: block; height: 2px; margin-top: 10px; background: var(--c-line); }
.ntb-bar__fill { display: block; height: 100%; background: var(--c-ink); transition: width var(--dur) var(--ease); }

.ntb-cartpanel__items { flex: 1; overflow-y: auto; padding: var(--s-2) var(--s-5); }
.ntb-cartitem { display: grid; grid-template-columns: 72px 1fr 20px; gap: var(--s-4); padding-block: var(--s-4); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-cartitem__media { aspect-ratio: var(--ar-product); overflow: hidden; background: var(--c-paper); }
.ntb-cartitem__body { display: grid; gap: 5px; align-content: start; min-width: 0; }
.ntb-cartitem__brand { font-size: var(--fs-50); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-cartitem__name { font-size: var(--fs-300); line-height: var(--lh-label); }
.ntb-cartitem__variant { font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-cartitem__row { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; font-size: var(--fs-300); }
.ntb-cartitem__remove { display: grid; place-items: center; width: 20px; min-height: 20px; color: var(--c-ink-3); line-height: 0; }
.ntb-cartitem__remove:hover { color: var(--c-ink); }

/* Stepper ilosci: 44 px wg par. 3, na telefonie 40 px z polem dotyku
   siegajacym krawedzi wiersza (nizej, w bloku mobilnym panelu koszyka). */
.ntb-qty { display: inline-flex; align-items: center; height: var(--h-step); border: var(--bw-hair) solid var(--c-control); }
.ntb-qty button { width: var(--h-step); height: 100%; border: 0; background: none; color: var(--c-ink-2); }
.ntb-qty button:hover { background: var(--c-ink); color: var(--c-on-ink); }
.ntb-qty span { min-width: 36px; text-align: center; font-size: var(--fs-300); font-variant-numeric: tabular-nums; }

.ntb-cartpanel__empty { flex: 1; padding: var(--s-6) var(--s-5); }
.ntb-cartpanel__hint { margin-top: 6px; font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-cartpanel__empty ul { margin-top: var(--s-5); }
.ntb-cartpanel__empty a { display: flex; align-items: center; gap: 12px; padding-block: 12px; border-top: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); }
.ntb-cartpanel__empty li:last-child a { border-bottom: var(--bw-hair) solid var(--c-line); }

/* Stopka panelu przyklejona na dole: suma i dwa przyciski. */
.ntb-cartpanel__foot { flex: none; padding: var(--s-4) var(--s-5) var(--s-5); border-top: var(--bw-hair) solid var(--c-line); background: var(--c-bg); }
.ntb-cartpanel__sum { display: flex; align-items: baseline; justify-content: space-between; font-size: var(--fs-400); }
.ntb-cartpanel__sum strong { font-size: var(--fs-600); font-weight: var(--fw-medium); }
.ntb-cartpanel__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: var(--s-4); }
.ntb-cartpanel__loading { padding: var(--s-4) var(--s-5); font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-cartpanel__error { margin: var(--s-4) var(--s-5); }

/* ============================================================
   18. ARCHIWUM KATEGORII
   Filtry jedna piata, listing cztery piate.
   ============================================================ */

.ntb-archive { padding-top: var(--s-7); }
.ntb-archive__grid { display: grid; grid-template-columns: minmax(220px, var(--col-filters)) minmax(0, 1fr); gap: var(--s-7); align-items: start; }

/* --- Naglowek kategorii --- */
.ntb-cathead { position: relative; overflow: hidden; }
.ntb-cathead--type { background: var(--c-paper); }
.ntb-cathead--type .ntb-cathead__body { padding: 34px 44px 38px; }
.ntb-cathead--media { min-height: 320px; }
.ntb-cathead--media .ntb-cathead__body { position: relative; padding: 44px; color: var(--c-on-ink); }
.ntb-cathead--media .ntb-cathead__body a { color: var(--c-on-ink); }
.ntb-cathead__img { position: absolute; inset: 0; }
.ntb-cathead__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--c-ink), transparent);
  opacity: .7;
}
.ntb-cathead__h1 { margin-top: var(--s-4); font-size: var(--fs-900); line-height: var(--lh-tight); }
.ntb-cathead__intro { margin-top: 14px; font-size: var(--fs-500); line-height: var(--lh-body); color: var(--c-ink-2); max-width: var(--w-text); }
.ntb-cathead--media .ntb-cathead__intro { color: var(--c-on-ink); }
.ntb-cathead__children { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.ntb-cathead__children a {
  display: inline-flex;
  align-items: center;
  min-height: var(--h-chip);
  padding-inline: 14px;
  border: var(--bw-hair) solid var(--c-line-2);
  background: var(--c-bg);
  color: var(--c-ink);
  font-size: var(--fs-300);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ntb-cathead__children a:hover { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
/* Hero ze zdjeciem ustawia linki w tresci na biel (.ntb-cathead--media .ntb-cathead__body a),
   a chip podkategorii ma biale tlo - bez tej reguly tekst znikal (bialy na bialym)
   na wszystkich szesciu dzialach. Hover zostaje odwrocony. */
.ntb-cathead--media .ntb-cathead__body .ntb-cathead__children a { color: var(--c-ink); }
.ntb-cathead--media .ntb-cathead__body .ntb-cathead__children a:hover,
.ntb-cathead--media .ntb-cathead__body .ntb-cathead__children a:focus-visible { color: var(--c-on-ink); }

/* Proporcje naglowka ze zdjeciem. Jeden plik 2:1 obsluguje wszystkie ekrany. */
@media (min-width: 1200px) { .ntb-cathead--media { aspect-ratio: var(--ar-hero-d); min-height: 320px; max-height: 360px; } }
@media (min-width: 768px) and (max-width: 1199px) { .ntb-cathead--media { aspect-ratio: var(--ar-hero-t); } }
@media (max-width: 767px) { .ntb-cathead--media { aspect-ratio: var(--ar-hero-m); max-height: 40vh; } }

/* --- Kolumna filtrow --- */
.ntb-filters { position: sticky; top: calc(var(--header-sticky-h) + var(--s-4)); display: flex; flex-direction: column; max-height: calc(100vh - var(--header-sticky-h) - var(--s-6)); }
.ntb-filters__head {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  padding-bottom: 14px;
  border-bottom: var(--bw-hair) solid var(--c-ink);
}
.ntb-filters__head h2 { flex: 1; }
.ntb-filters__head a { font-size: var(--fs-200); color: var(--c-ink-3); text-decoration: underline; text-underline-offset: 3px; }
.ntb-filters__close { display: none; place-items: center; width: var(--touch); height: var(--touch); border: 0; background: none; padding: 0; line-height: 0; }
.ntb-filters__scroll { flex: 1; overflow-y: auto; overscroll-behavior: contain; }
.ntb-filters__apply { display: none; }

.ntb-fgroup { padding-block: var(--s-5); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-fgroup__head { display: flex; align-items: baseline; gap: var(--s-2); margin-bottom: var(--s-3); }
.ntb-fgroup__head h3 { flex: 1; }
.ntb-fgroup__link { font-size: var(--fs-200); color: var(--c-ink-3); text-decoration: underline; text-underline-offset: 3px; }
.ntb-fgroup__toggle { display: grid; place-items: center; width: 28px; height: 28px; border: 0; background: none; padding: 0; line-height: 0; color: var(--c-ink-3); }
.ntb-fgroup__note { margin-bottom: var(--s-3); font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-fgroup.is-collapsed .ntb-fgroup__list,
.ntb-fgroup.is-collapsed .ntb-fgroup__search,
.ntb-fgroup.is-collapsed .ntb-fgroup__note,
.ntb-fgroup.is-collapsed .ntb-fgroup__more { display: none; }

.ntb-fgroup__search { display: flex; align-items: center; height: var(--h-field); margin-bottom: var(--s-3); border: var(--bw-hair) solid var(--c-control); }
.ntb-fgroup__search svg { margin-inline: 9px; color: var(--c-ink-4); }
/* align-self: stretch, bo samo pole ma wysokosc linii pisma (35 px) i na
   390 px bylo jedynym celem dotykowym ponizej 44 px w kolumnie filtrow.
   Rozciagniete wypelnia ramke grupy i cel rosnie do jej wysokosci. */
.ntb-fgroup__search input { flex: 1; min-width: 0; align-self: stretch; border: 0; background: none; font: inherit; font-size: var(--fs-300); }
.ntb-fgroup__search input:focus { outline: none; }
/* README Faza 4 dla marki: szukajka 38 px. Wysokosc obowiazuje w kolumnie
   filtrow na duzym ekranie. Ponizej 768 px kolumna jest arkuszem na telefonie,
   gdzie pole jest celem dotykowym i musi miec 44 px, wiec zostaje --h-field. */
@media (min-width: 768px) { .ntb-fgroup__search { height: 38px; } }

.ntb-fgroup__list { display: grid; gap: 10px; }
/* Wiersz fasety jest calym celem dotykowym, checkbox ma projektowe 15 px. */
.ntb-fitem { display: flex; align-items: center; gap: 10px; min-height: 34px; font-size: var(--fs-300); color: var(--c-ink); }
.ntb-fitem__box { width: var(--box-filter); height: var(--box-filter); flex: none; border: var(--bw-hair) solid var(--c-control); display: grid; place-items: center; }
.ntb-fitem__box svg { width: 11px; height: 11px; }
.ntb-fitem.is-on { font-weight: var(--fw-medium); }
.ntb-fitem.is-on .ntb-fitem__box { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-fitem__label { flex: 1; }
.ntb-fitem__count { color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-fitem.is-empty { color: var(--c-line-2); pointer-events: none; }
.ntb-fitem.is-empty .ntb-fitem__box { border-color: var(--c-line); }
.ntb-fitem:hover:not(.is-empty) .ntb-fitem__box { border-color: var(--c-ink); }

/* Kafle rozmiaru zamiast checkboxow. */
.ntb-fgroup[data-style="tiles"] .ntb-fgroup__list { display: flex; flex-wrap: wrap; gap: 6px; }
.ntb-fgroup[data-style="tiles"] .ntb-fitem {
  min-width: var(--tile-f-w);
  min-height: var(--tile-f-h);
  justify-content: center;
  padding-inline: 8px;
  border: var(--bw-hair) solid var(--c-line-2);
  font-size: var(--fs-300);
  font-variant-numeric: tabular-nums;
}
.ntb-fgroup[data-style="tiles"] .ntb-fitem__box,
.ntb-fgroup[data-style="tiles"] .ntb-fitem__count { display: none; }
.ntb-fgroup[data-style="tiles"] .ntb-fitem.is-on { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-fgroup[data-style="tiles"] .ntb-fitem.is-empty { border-color: var(--c-line); text-decoration: line-through; text-decoration-color: var(--c-line-2); }

/* Swatche koloru: czarno biale z obwodka i podpisem. */
.ntb-fgroup[data-style="swatch"] .ntb-fitem__box { border-radius: var(--r-round); }

.ntb-fgroup__more { margin-top: 14px; padding: 0; border: 0; background: none; font-family: var(--f-ui); font-size: var(--fs-300); font-weight: var(--fw-medium); text-decoration: underline; text-underline-offset: 3px; }

.ntb-ftree { display: grid; gap: 8px; font-size: var(--fs-300); }
.ntb-ftree a { display: inline-flex; align-items: center; min-height: 24px; color: var(--c-ink-2); }
.ntb-ftree .is-current { padding-left: 12px; border-left: var(--bw-heavy) solid var(--c-ink); font-weight: var(--fw-medium); }
.ntb-ftree .is-child { padding-left: 14px; }

/* Suwak ceny: galka jest wysrodkowana na koncu toru (margin-left -6px przy
   szerokosci 12px), wiec bez tego marginesu polowa prawej galki wychodzila
   6 px poza kolumne filtrow i na arkuszu 390 px byla przycieta krawedzia
   panelu. Zmierzone: scrollWidth 348 przy clientWidth 342. Tor skracamy
   o galke z obu stron, zeby skala pozostala symetryczna. */
.ntb-fprice__track { position: relative; height: 2px; background: var(--c-line); margin-block-end: var(--s-4); margin-inline: 6px; }
.ntb-fprice__fill { position: absolute; inset: 0; background: var(--c-ink); }
.ntb-fprice__knob { position: absolute; top: -5px; width: 12px; height: 12px; margin-left: -6px; border-radius: var(--r-round); background: var(--c-bg); border: var(--bw-strong) solid var(--c-ink); }
.ntb-fprice__knob[data-knob="min"] { left: 0; }
.ntb-fprice__knob[data-knob="max"] { left: 100%; }
.ntb-fprice__fields { display: flex; align-items: center; gap: var(--s-2); }
.ntb-fprice__fields input {
  flex: 1;
  min-width: 0;
  height: var(--h-field);
  padding-inline: 10px;
  border: var(--bw-hair) solid var(--c-line-2);
  background: var(--c-bg);
  font: inherit;
  font-size: var(--fs-300);
  font-variant-numeric: tabular-nums;
}
.ntb-fprice__fields span { flex: none; font-size: var(--fs-200); color: var(--c-ink-3); } /* flex: none - na 390 px "zł" bylo sciskane do 10 px i obciete */
.ntb-fprice__fields .ntb-sr { position: absolute; }

/* --- Chipy wybranych filtrow: wariant 34 px z krzyzykiem (par. 3) --- */
.ntb-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding-bottom: 18px; }
.ntb-chips__label { font-size: var(--fs-200); color: var(--c-ink-3); margin-right: 4px; }
.ntb-chips__clear { margin-left: 6px; font-size: var(--fs-300); color: var(--c-ink-3); text-decoration: underline; text-underline-offset: 3px; }

/* --- Pasek narzedzi --- */
.ntb-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px var(--s-5);
  padding-block: 14px;
  border-top: var(--bw-hair) solid var(--c-line);
  border-bottom: var(--bw-hair) solid var(--c-line);
}
.ntb-toolbar__count { font-size: var(--fs-300); color: var(--c-ink-2); font-variant-numeric: tabular-nums; }
.ntb-toolbar__tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px var(--s-5); }

.ntb-select { position: relative; display: inline-flex; align-items: center; min-height: var(--h-chip); border: var(--bw-hair) solid var(--c-control); }
.ntb-select select {
  /* height: 100% nie dzialalo: opakowanie ma tylko min-height, wiec jego
     wysokosc jest nieokreslona i procent nie mial sie do czego odniesc.
     Select spadal do 13 px (sama linia pisma) i chowal sie pod ramka
     opakowania - klikalny byl pasek 13 px zamiast calej kontrolki.
     align-self: stretch rozciaga go na pelna wysokosc opakowania. */
  align-self: stretch;
  padding: 0 32px 0 12px;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--fs-300);
  appearance: none;
}
.ntb-select select:focus { outline: none; }
.ntb-select svg { position: absolute; right: 10px; pointer-events: none; color: var(--c-ink-3); }

/* Petla Woo w naszej siatce. Liczba kolumn jest JAWNA na kazdym progu (D12):
   auto-fit przy zmiennej liczbie wynikow zostawial puste komorki i odslanial
   tlo, a przy trzech wynikach rozciagal karty na cala szerokosc.
   Wartosc data-density przychodzi z ntb24_loop_columns(). */
.ntb-listing ul.products {
  display: grid;
  grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
  gap: 32px 24px;
  margin-top: 28px;
}
/* Woo czysci floaty przez ::before i ::after z content " ". W siatce grid
   te pseudoelementy nie sa czyszczeniem, tylko dwoma pelnoprawnymi komorkami:
   pierwsza karta ladowala w drugiej kolumnie, a na koncu listy zostawala
   dziura. Floatow juz nie ma, wiec czyszczenie jest zbedne. */
.ntb-listing ul.products::before,
.ntb-listing ul.products::after { content: none; display: none; }
.ntb-listing[data-density="3"] ul.products { --cols: 3; }
.ntb-listing[data-density="4"] ul.products { --cols: 4; }

/* Woo trzyma petle na floatach i procentach: woocommerce-layout.css daje
   li.product width 22.05%, a woocommerce-smallscreen.css ponizej 768 px
   width 48%. W siatce grid ten procent liczy sie od SZEROKOSCI KOMORKI,
   nie od listy, wiec karta kurczyla sie do ulamka wlasnej kolumny
   (na 390 px do 37 px) i cala tresc karty z niej wystawala. Zerujemy
   szerokosc, float i marginesy Woo; rozmiar ma dawac wylacznie grid.
   Selektor musi byc mocniejszy niz `.woocommerce ul.products[class*=columns-] li.product`. */
.ntb-listing ul.products li.product,
.woocommerce .ntb-listing ul.products[class*="columns-"] li.product {
  display: flex;
  flex-direction: column;
  float: none;
  clear: none;
  width: auto;
  margin: 0;
}

/* --- Stan pusty ---
   Miara czytania nalezy do AKAPITU, nie do bloku: na kontenerze scinala do 568
   z 1296 px takze naglowek i rzad przyciskow, ktore stoja pod nagowkiem
   rozciagnietym na cala kolumne - dwie rozne osie na jednym ekranie. */
.ntb-empty { padding: var(--s-9) 0; }
.ntb-empty h2 { font-size: var(--fs-800); }
.ntb-empty p { margin-top: var(--s-3); max-width: var(--w-text); font-size: var(--fs-400); color: var(--c-ink-2); }
.ntb-empty__chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--s-5); }
.ntb-empty__actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--s-6); }

/* --- Paginacja: prawdziwe linki --- */
.woocommerce-pagination { margin-top: 44px; padding-top: var(--s-5); border-top: var(--bw-hair) solid var(--c-line); }
/* Lista stron u Woo to wciaz uklad na floatach: ramka 1 px wokol calego
   bloku i kreska miedzy pozycjami, obie w barwie spoza palety. Nasz
   `.woocommerce-pagination ul` przegrywal z jej lancuchem, wiec numery
   siedzialy w liliowej obwodce zamiast w oddzielonych kwadratach. */
.woocommerce-pagination ul,
.woocommerce nav.woocommerce-pagination ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: 0;
  border: 0;
}
.woocommerce nav.woocommerce-pagination ul li {
  display: block;
  float: none;
  margin: 0;
  border: 0;
  overflow: visible;
}
/* Woo opisuje strony pelnym lancuchem `.woocommerce nav.woocommerce-pagination
   ul li a`, ktory jest mocniejszy niz `.woocommerce-pagination a` i narzucal
   display: block, padding .5em i min-width 1em. Nasz uklad nigdy nie wchodzil
   w zycie, wiec numery byly wezsze niz projekt. Powtarzamy sile selektora. */
.woocommerce-pagination a, .woocommerce-pagination span,
.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
  min-width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-inline: 8px;
  border: var(--bw-hair) solid var(--c-line-2);
  font-size: var(--fs-300);
  /* Woo daje tym linkom interlinie 1 - piata wartosc obok naszych czterech.
     Wizualnie nic sie nie zmienia (kafel ma stala wysokosc i wysrodkowanie),
     zmienia sie liczba wartosci w systemie. */
  line-height: var(--lh-label);
  font-variant-numeric: tabular-nums;
}
/* Stan biezacy i najechanie: Woo maluje je na liliowo (tlo i pismo spoza
   palety). U nas stan aktywny to zawsze czarne wypelnienie i biale pismo. */
.woocommerce-pagination span.current,
.woocommerce nav.woocommerce-pagination ul li span.current { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); font-weight: var(--fw-medium); }
.woocommerce-pagination a:hover,
.woocommerce nav.woocommerce-pagination ul li a:focus,
.woocommerce nav.woocommerce-pagination ul li a:hover { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }

/* --- Tresc pod listingiem --- */
.ntb-catcontent { padding-top: var(--s-10); }
/* Opis i FAQ: dwie kolumny od 1024 px, jedna nizej. Bez auto-fit (D12). */
.ntb-catcontent__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); padding-top: var(--s-6); border-top: var(--bw-hair) solid var(--c-line); }
/* Tylko naglowek W SIATCE opisu (FAQ). Szerszy selektor `.ntb-catcontent h2`
   siegal takze do bloku linkow, ktorego naglowki sa etykietami panelu. */
.ntb-catcontent__grid h2 { font-size: var(--fs-800); }
/* Tylko akapity BEZPOSREDNIO w tresci redakcyjnej. Koszyk, kasa
   i potwierdzenie wchodza do tej samej kolumny przez shortcode (page.php),
   wiec selektor potomka narzucal ich akapitom stopien pisma i marginesy
   tresci ciaglej - pasek dostawy, notatki i ostrzezenia gubily swoj wyglad. */
.ntb-prose > p { margin-top: 14px; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-prose h3 { margin-top: var(--s-6); }
.ntb-faq { margin-top: 18px; }
.ntb-faq__item { padding-block: var(--s-4); border-top: var(--bw-hair) solid var(--c-line); }
.ntb-faq__item:last-child { border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-faq__item p { margin-top: 8px; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }

/* Linkowanie dzialow wg D12: 3 kolumny od 1200 px, 2 od 768, 1 nizej. */
/* --- /marki/: kafle marek z wlasna strona i skorowidz literowy (Faza 8) --- */

/* Osiem kafli w siatce 4 x 2. Liczba kolumn jest jawna na kazdym progu -
   auto-fit na pasku o zmiennej liczbie dzieci odslania tlo siatki (D12). */
.ntb-brandtiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--bw-hair);
  margin-top: var(--s-6);
  background: var(--c-line);
  border: var(--bw-hair) solid var(--c-line);
}
.ntb-brandtile {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 160px;
  padding: 22px 24px;
  background: var(--c-paper);
}
.ntb-brandtile:hover, .ntb-brandtile:focus-visible { background: var(--c-bg); }
.ntb-brandtile__name { font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); line-height: var(--lh-tight); }
.ntb-brandtile__go { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--fs-300); font-weight: var(--fw-medium); text-decoration: underline; text-underline-offset: 4px; }

/* Skorowidz: litery 44 px (regula 3 podnosi projektowe 40 px do celu
   dotykowego). Litera bez marek zostaje w rzedzie, kreskowana i wylaczona. */
.ntb-alpha { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-6); }
.ntb-alpha__letter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--touch);
  min-height: var(--touch);
  padding-inline: 6px;
  border: var(--bw-hair) solid var(--c-line-2);
  font-size: var(--fs-300);
  font-variant-numeric: tabular-nums;
}
a.ntb-alpha__letter:hover,
a.ntb-alpha__letter:focus-visible { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-alpha__letter[data-state="discontinued"] { border-style: dashed; color: var(--c-ink-3); }
.ntb-catlinks--alpha li { display: flex; }
.ntb-catlinks--alpha li a { display: inline-flex; align-items: center; min-height: var(--touch); min-width: var(--touch); }

.ntb-catlinks { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-7); margin-top: var(--s-9); }
.ntb-catlinks ul { display: grid; gap: 10px; margin-top: var(--s-4); font-size: var(--fs-400); }
.ntb-catlinks a { text-decoration: underline; text-underline-offset: 3px; }

/* --- Arkusz filtrow na telefonie ---
   ARKUSZ OD DOLU, NIE SZUFLADA Z LEWEJ. Panel zajmowal caly ekran i wjezdzal
   w poziomie, wiec po otwarciu mial 4 696 px przewijania w oknie 662 px:
   "Dostepnosc" lezala na 4 391 px, czyli 6,6 ekranu od gory. Ruch w pionie
   jest kierunkiem, w ktorym telefon otwiera panele, a 85vh zostawia widoczny
   pasek listingu, wiec widac, ze filtry naklada sie NA wyniki (regula 3).

   visibility: hidden w stanie zamknietym wyprowadza arkusz z drzewa
   ogniskowania razem ze 110 kontrolkami w srodku - 69 ze 108 przystankow
   tabulacji lezacych poza ekranem na 390 px bralo sie stad. Przejscie
   na visibility jest opoznione o czas ruchu, zeby wyjazd bylo widac.

   Stan otwarty ustawia skrypt (is-open, data-open), a bez niego regula
   :target - dokladnie tym samym wzorcem, co .ntb-tree w naglowku. */
.ntb-filters-open { display: none; }
.ntb-filters-shut { display: none; }

@media (max-width: 1023px) {
  .ntb-archive__grid { grid-template-columns: minmax(0, 1fr); }

  .ntb-filters {
    position: fixed;
    inset: auto 0 0 0;
    z-index: var(--z-panel);
    max-height: 85vh;
    background: var(--c-bg);
    padding: var(--s-4) var(--s-4) calc(var(--s-4) + var(--safe-b));
    border-top: var(--bw-hair) solid var(--c-line);
    box-shadow: var(--sh-bar);
    transform: translateY(100%);
    visibility: hidden;
    transition: transform var(--dur) var(--ease), visibility 0s linear var(--dur);
  }

  /* Uchwyt arkusza. Nie jest kontrolka - mowi tylko, ze panel przyszedl
     z dolu i tam wraca. */
  .ntb-filters::before {
    content: "";
    display: block;
    flex: none;
    width: 44px;
    height: 4px;
    margin: 0 auto var(--s-4);
    background: var(--c-line);
  }

  .ntb-filters.is-open,
  .ntb-filters[data-open="true"],
  .ntb-filters:target:not([data-open="false"]) {
    transform: none;
    visibility: visible;
    transition: transform var(--dur) var(--ease), visibility 0s;
  }

  /* Jeden otwieracz na widok: odnosnik ze stopki (inc/filters.php). Kazdy inny
     egzemplarz chowamy, zeby w tym samym punkcie nie stalo dwoch celow
     dotykowych, z ktorych jeden bez JavaScriptu nie dziala. */
  .ntb-filters-open:not(#ntb-filters-open) { display: none; }

  /* Tlo zamykajace: przy otwartym arkuszu jedyna droga powrotna bez skryptu.
     Stoi pod arkuszem (z-index nizszy o jeden), wiec nie zaslania tresci. */
  .ntb-filters-shut {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-panel) - 1);
    display: none;
    align-items: flex-start;
    justify-content: center;
    gap: var(--s-2);
    padding-top: var(--s-5);
    background: rgba(10, 10, 10, .38);
    color: var(--c-on-ink);
    font-family: var(--f-ui);
    font-size: var(--fs-300);
    font-weight: var(--fw-medium);
    letter-spacing: .08em;
    text-transform: uppercase;
    text-decoration: none;
  }

  html:has(#ntb-filters:target:not([data-open="false"])) .ntb-filters-shut,
  html.ntb-filters-on .ntb-filters-shut { display: flex; }

  html:has(#ntb-filters:target:not([data-open="false"])) .ntb-filters-open,
  html.ntb-filters-on .ntb-filters-open { display: none; }

  .ntb-filters__close { display: grid; }
  .ntb-filters__apply { display: block; flex: none; padding-top: var(--s-4); border-top: var(--bw-hair) solid var(--c-line); }

  .ntb-filters-open {
    position: fixed;
    left: 50%;
    bottom: calc(var(--ntb-bar-h) + var(--s-4));
    z-index: var(--z-mobilebar);
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    min-height: var(--touch);
    padding-inline: 20px;
    border: 0;
    background: var(--c-ink);
    color: var(--c-on-ink);
    font-family: var(--f-ui);
    font-size: var(--fs-300);
    font-weight: var(--fw-medium);
    letter-spacing: .08em;
    text-transform: uppercase;
    box-shadow: var(--sh-bar);
  }
}

@media (max-width: 1199px) {
  .ntb-catlinks { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1023px) {
  .ntb-catcontent__grid { grid-template-columns: minmax(0, 1fr); }
  /* Z atrybutem data-density, bo `.ntb-listing[data-density="4"] ul.products`
     jest mocniejsze niz `.ntb-listing ul.products` - media query nie dodaje
     specyficznosci, wiec bez tego telefon zostawal na czterech kolumnach. */
  .ntb-listing ul.products,
  .ntb-listing[data-density] ul.products { --cols: 3; }
}

@media (max-width: 767px) {
  .ntb-cathead--type .ntb-cathead__body { padding: var(--s-5) var(--s-4) var(--s-6); }
  .ntb-listing ul.products,
  .ntb-listing[data-density] ul.products { --cols: 2; gap: var(--s-5) var(--s-4); }
  .ntb-catlinks { grid-template-columns: minmax(0, 1fr); }

  /* Sto jedenascie marek to na 390 px blisko dziesieciu tysiecy pikseli.
     Skorowidz zostaje pod naglowkiem przez cala droge i przewija sie w bok
     jednym rzedem, zeby nie zjadal czwartej czesci ekranu (blad D5). */
  .ntb-brandtiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ntb-brandtile { min-height: 120px; padding: 18px 16px; }
  .ntb-brandtile__name { font-size: var(--fs-600); }

  .ntb-alpha {
    position: sticky;
    top: var(--ntb-head-h);
    z-index: var(--z-rail);
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    margin-inline: calc(var(--pad-page) * -1);
    padding: var(--s-2) var(--pad-page);
    background: var(--c-bg);
    border-bottom: var(--bw-hair) solid var(--c-line);
  }
  .ntb-alpha__letter { flex: none; scroll-snap-align: center; }

  /* Kotwica ma ladowac pod naglowkiem i pod skorowidzem, nie za nimi. */
  /* Sam skorowidz, bez naglowka: ten niesie juz scroll-padding-top na html.
     Skorowidz mierzy 61 px, z ktorych 16 pokrywa juz zapas w --h-anchor. */
  .ntb-alpha__group { scroll-margin-top: 48px; }
  .ntb-catcontent__grid h2 { font-size: var(--fs-700); }
}

/* ============================================================
   19. KARTA PRODUKTU
   ============================================================ */

/* Galeria i blok zakupu: dwie kolumny od 1024 px, jedna nizej (D12). */
.ntb-product { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); align-items: start; }

/* --- Galeria --- */
.ntb-gallery__main { position: relative; aspect-ratio: var(--ar-product); border: var(--bw-hair) solid var(--c-line); overflow: hidden; background: var(--c-bg); }
.ntb-gallery__main img { width: 100%; height: 100%; object-fit: cover; }
.ntb-gallery__tag { position: absolute; left: 16px; top: 16px; }
.ntb-gallery__thumbs { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s-3); margin-top: var(--s-3); }
.ntb-gallery__thumb {
  position: relative;
  aspect-ratio: var(--ar-product);
  padding: 0;
  border: var(--bw-hair) solid var(--c-line);
  background: var(--c-bg);
  overflow: hidden;
}
.ntb-gallery__thumb.is-on { border-color: var(--c-ink); }
.ntb-gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
/* Licznik pozostalych zdjec na ostatniej miniaturze. Tlo pelne z palety,
   bo biel z kanalem alfa dawalaby na zdjeciu kolor spoza listy. */
.ntb-gallery__rest {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--c-paper);
  font-size: var(--fs-200);
  color: var(--c-ink-3);
}

/* --- Blok zakupu --- */
.ntb-buy__top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
.ntb-buy__brand { font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .18em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-buy__sku { font-size: var(--fs-200); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
/* H1 karty ma 34 px, nie 38: tyle daja projekty wszystkich szesciu ukladow
   (NTB24 Karta produktu, blok naglowka). Uklad E schodzi do 30 px - sekcja 23. */
.ntb-buy__h1 { margin-top: var(--s-3); font-size: var(--fs-850); line-height: var(--lh-tight); letter-spacing: -.01em; }
.ntb-buy__rating { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); margin-top: 14px; font-size: var(--fs-300); }
.ntb-buy__rating a { color: var(--c-ink-2); text-decoration: underline; text-underline-offset: 3px; }
.ntb-buy__price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 14px;
  margin-top: var(--s-5);
  padding-bottom: 22px;
  border-bottom: var(--bw-hair) solid var(--c-line);
  font-size: var(--fs-800);
  font-weight: var(--fw-medium);
}
.ntb-buy__price del { font-size: var(--fs-600); color: var(--c-ink-3); font-weight: var(--fw-regular); }
.ntb-buy__pricenote { font-size: var(--fs-300); font-weight: var(--fw-regular); color: var(--c-ink-3); }

.ntb-buy__block { margin-top: var(--s-5); }
.ntb-buy__blockhead { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 10px; }
.ntb-buy__label { font-size: var(--fs-300); font-weight: var(--fw-semibold); letter-spacing: .06em; }
.ntb-buy__label strong { font-weight: var(--fw-regular); color: var(--c-ink-2); }
.ntb-buy__guiderow { margin-top: var(--s-4); }
.ntb-buy__guide {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--f-ui);
  font-size: var(--fs-300);
  color: var(--c-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Zwijanie do drugiego wiersza jest tu obowiazkowe. Przy nowcase i osmiu
   probkach 8 x 44 px + 7 x 10 px = 422 px nie miesci sie w 358 px kolumny,
   wiec flex sciskal kazda probke do 36 px szerokosci i lamal regule dotyku
   na karcie produktu. Rosnie liczba wierszy, nie maleje pole dotyku. */
.ntb-colors { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--s-3); }
.ntb-color { flex: 0 0 auto; width: var(--touch); height: var(--touch); padding: 0; border: var(--bw-hair) solid var(--c-line-2); border-radius: var(--r-round); }
.ntb-color[aria-pressed="true"] { outline: 1px solid var(--c-ink); outline-offset: 3px; }

/* Kafelek rozmiaru w bloku zakupu: wariant A, 74x48 (par. 3). */
.ntb-sizes--lg { margin-top: var(--s-3); gap: var(--s-2); }
.ntb-sizes--lg .ntb-size { min-width: var(--tile-a-w); min-height: var(--tile-a-h); padding-inline: 12px; font-size: var(--fs-400); }

/* Pasek powiadomienia o braku rozmiaru: ramka czerni i ikona, bez koloru. */
.ntb-notify { display: flex; align-items: center; gap: 9px; min-height: var(--touch); margin-top: var(--s-3); padding: 11px 13px; border: var(--bw-hair) solid var(--c-ink); background: var(--c-paper); font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-notify svg { flex: none; color: var(--c-ink-2); }
.ntb-notify span { flex: 1; }
.ntb-notify button { padding: 0; border: 0; background: none; font-family: var(--f-ui); font-size: var(--fs-300); font-weight: var(--fw-medium); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }

.ntb-buy__form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: var(--s-5); }
/* Stepper, "Dodaj do koszyka" i "Kup teraz" w jednej linii: oba przyciski
   dziela miejsce po stepperze po rowno, z podstawa, ktora jeszcze miesci
   napis w kapitalikach bez lamania (620 px kolumny: 132 + 2 x 234). */
.ntb-buy__add, .ntb-buy__now { flex: 1 1 180px; min-height: var(--h-btn); padding-inline: 16px; white-space: nowrap; }
.ntb-qty--lg { height: var(--h-btn); }
.ntb-qty--lg button { width: var(--touch); height: 100%; }
.ntb-qty input { width: var(--touch); height: 100%; border: 0; background: none; text-align: center; font: inherit; font-size: var(--fs-400); font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.ntb-qty input::-webkit-outer-spin-button, .ntb-qty input::-webkit-inner-spin-button { appearance: none; margin: 0; }

/* --- Lista zyczen i porownywarka (C3) ---------------------------------- */

/* Kazdy przycisk listy siedzi we wlasnym formularzu POST, zeby dzialac bez
   JavaScriptu. display: contents rozpuszcza ten formularz w ukladzie rodzica,
   wiec siatka .ntb-card__acts i rzad .ntb-buy__acts wygladaja tak samo jak
   przed zmiana. */
.ntb-lista-form { display: contents; }
.ntb-lista-clear { margin-top: var(--s-7); }

/* Przycisk w roli odnosnika: bez ramki i tla przegladarki, zeby "Usun"
   w porownaniu wygladalo jak "Zobacz karte" obok niego. */
button.ntb-link { padding: 0; border: 0; background: none; font: inherit; cursor: pointer; }

/* Odznaka listy stoi w tym samym miejscu co licznik koszyka. */
.ntb-list-count { font-variant-numeric: tabular-nums; }

/* Tabela porownania bywa szersza niz kolumna tresci przy czterech modelach.
   Przewija sie w swoim pudelku, a nie cala strona (regula: zero przewijania
   poziomego na 390 px - tam tabela i tak zamienia sie w liste definicji). */
.ntb-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.ntb-compare th[scope="row"] { white-space: nowrap; color: var(--c-ink-3); font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; }
.ntb-compare td { vertical-align: top; }
.ntb-compare__acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-5); }

.ntb-buy__acts { display: flex; flex-wrap: wrap; gap: 22px; margin-top: var(--s-4); }
.ntb-buy__acts button { display: inline-flex; align-items: center; gap: 8px; padding: 0; border: 0; background: none; font-family: var(--f-ui); font-size: var(--fs-300); }
.ntb-buy__acts button[aria-pressed="true"] { font-weight: var(--fw-medium); text-decoration: underline; text-underline-offset: 3px; }
.ntb-buy__acts button:hover { text-decoration: underline; text-underline-offset: 3px; }

.ntb-buy__facts { display: grid; grid-template-columns: auto 1fr; gap: 14px 16px; margin-top: var(--s-6); padding-top: var(--s-5); border-top: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); }
.ntb-buy__facts dt { display: flex; align-items: center; gap: 10px; color: var(--c-ink-3); }
.ntb-buy__facts dd { margin: 0; }

/* --- Opis, specyfikacja, rozmiarowka --- */
/* Opis i specyfikacja: dwie kolumny od 1024 px, jedna nizej (D12). */
.ntb-pcols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); padding-top: var(--s-6); border-top: var(--bw-hair) solid var(--c-line); }
.ntb-pcols h2 { font-size: var(--fs-800); }

.ntb-specs { display: grid; grid-template-columns: auto 1fr; margin-top: 18px; font-size: var(--fs-400); }
.ntb-specs dt { padding-block: 12px; border-top: var(--bw-hair) solid var(--c-line); color: var(--c-ink-3); }
/* Miara czytania takze tutaj: na /dostawa-i-zwroty/ ta sama definicja
   szla przez 722 px, czyli 95 znakow w wierszu przy progu 85 (P28).
   Kolumna zostaje szeroka, lamie sie sam tekst. */
.ntb-specs dd { margin: 0; padding: 12px 0 12px 20px; border-top: var(--bw-hair) solid var(--c-line); max-width: calc(var(--w-text) + 20px); }
.ntb-specs dt:last-of-type, .ntb-specs dd:last-of-type { border-bottom: var(--bw-hair) solid var(--c-line); }

.ntb-sizing__head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 20px var(--s-7); }
.ntb-sizing__head h2 { margin-top: 14px; font-size: var(--fs-800); }
.ntb-sizing__head p { margin-top: var(--s-3); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); max-width: var(--w-text); }
/* Tabele rozmiarowki: dwie kolumny od 1024 px, jedna nizej (D12).
   Na telefonie kazda tabela i tak zamienia sie w liste definicji. */
.ntb-sizing__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-7); margin-top: var(--s-6); }
.ntb-sizing__note { margin-top: var(--s-3); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-sizing__note a { text-decoration: underline; text-underline-offset: 3px; }

/* Tabela: na desktopie zwykla siatka, na 390 px lista definicji (nizej). */
.ntb-table { width: 100%; border-collapse: collapse; font-size: var(--fs-400); }
.ntb-table caption { text-align: left; padding-bottom: var(--s-3); font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-table th { text-align: left; padding-block: 10px; border-bottom: var(--bw-hair) solid var(--c-line-2); font-weight: var(--fw-semibold); }
.ntb-table td { padding-block: 10px; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-table tbody tr:last-child td { border-bottom: 0; }
.ntb-table tbody tr.is-match { background: var(--c-paper); }
.ntb-table tbody tr.is-match td { font-weight: var(--fw-medium); }

/* --- Opinie --- */
.ntb-reviews { display: flex; flex-wrap: wrap; gap: var(--s-7); margin-top: var(--s-6); }
.ntb-reviews__summary { flex: 0 0 240px; }
.ntb-reviews__list { flex: 1 1 380px; min-width: 0; }
.ntb-reviews__score { display: flex; align-items: baseline; gap: var(--s-3); }
.ntb-reviews__score span:first-child { font-family: var(--f-display); font-size: var(--fs-1000); line-height: var(--lh-tight); }
.ntb-reviews__score span:last-child { font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-reviews__summary .ntb-card__stars { margin-top: var(--s-3); }
.ntb-reviews__summary .ntb-card__stars svg { width: 16px; height: 16px; }
.ntb-reviews__count { margin-top: var(--s-3); font-size: var(--fs-300); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-bars { display: grid; gap: var(--s-2); margin-top: var(--s-5); font-size: var(--fs-300); }
.ntb-bars__row { display: flex; align-items: center; gap: 10px; }
.ntb-bars__row span:first-child { width: 16px; }
.ntb-bars__row span:last-child { width: 30px; text-align: right; color: var(--c-ink-3); }
.ntb-bars .ntb-bar { flex: 1; margin: 0; }

.ntb-review { padding-block: 22px; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-review:first-child { padding-top: 0; }
.ntb-review__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.ntb-review__author { font-size: var(--fs-400); font-weight: var(--fw-medium); }
.ntb-review__meta { font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-review__date { margin-left: auto; font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-review p { margin-top: var(--s-3); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }

.ntb-faq__by { display: inline-block; margin-top: 10px; font-size: var(--fs-200); color: var(--c-ink-3); }

/* --- Modal: arkusz „Jak zmierzyc i dobrac rozmiar” (size-modal.php) ---
   Stan otwarcia to data-open (skrypt) albo :target (bez skryptu), nie atrybut
   hidden - [hidden] ma !important i :target by go nie przebil. Przeslona
   stoi w DOM tuz za oknem, wiec .ntb-modal:target + .ntb-overlay tez
   dziala bez skryptu. Na desktopie okno posrodku, na telefonie arkusz od
   dolu ekranu (blok @media nizej). */
.ntb-modal {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: var(--z-modal);
  display: none;
  width: min(640px, calc(100vw - var(--s-8)));
  max-height: min(88vh, 88dvh);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translate(-50%, -50%);
  background: var(--c-bg);
  border: var(--bw-hair) solid var(--c-ink);
}
.ntb-modal[data-open="true"], .ntb-modal:target { display: block; }
.ntb-modal:target + .ntb-overlay { opacity: .55; pointer-events: auto; }
.ntb-modal:focus { outline: none; }
/* Przeslona-odnosnik przy zamknietym oknie nie moze siedziec w kolejnosci
   tabulacji (niewidoczny „Zamknij” na koncu strony): visibility zdejmuje ja
   z drzewa ogniska i z czytnika, z opoznieniem rownym przejsciu opacity. */
.ntb-modal__overlay { visibility: hidden; transition: opacity var(--dur) var(--ease), visibility 0s var(--dur); }
.ntb-modal:target + .ntb-modal__overlay, .ntb-modal__overlay[data-open="true"] { visibility: visible; transition-delay: 0s; }
/* Bez skryptu blokada przewijania strony pod otwartym arkuszem. */
html:has(.ntb-modal:target) { overflow: hidden; }
/* Po wyslaniu kalkulatora bez skryptu (GET wraca na kotwice) wynik ma byc
   pierwszy w arkuszu, nie 1000 px nizej pod schematem: kolejnosc blokow
   zmienia klasa nadana po stronie serwera, gdy w adresie sa parametry. */
.ntb-modal__body { display: flex; flex-direction: column; }
.ntb-modal--wynik .ntb-pomiar__calc { order: -1; margin-top: 0; padding-top: 0; border-top: 0; }
.ntb-modal--wynik .ntb-pomiar__schemat { margin-top: var(--s-5); }
/* Naglowek przyklejony: przy przewijaniu dlugiego arkusza X jest zawsze pod reka. */
.ntb-modal__head { position: sticky; top: 0; z-index: 1; display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-5); padding: 24px 28px 18px; background: var(--c-bg); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-modal__title { min-width: 0; }
.ntb-modal__head h2 { margin-top: 8px; font-size: var(--fs-700); line-height: var(--lh-tight); }
.ntb-modal__close { width: var(--touch); height: var(--touch); flex: none; display: grid; place-items: center; border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); color: var(--c-ink); }
.ntb-modal__close:hover { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-pomiar__grip { display: none; }
.ntb-modal__body { padding: 24px 28px 28px; }
.ntb-modal__body > p { font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-modal__body .ntb-table { margin-top: 28px; }
.ntb-modal__body > .ntb-modal__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; margin-top: var(--s-5); padding-top: var(--s-3); border-top: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-modal__foot a { display: inline-flex; align-items: center; min-height: var(--touch); color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }
/* Schemat pomiaru na papierze, na cala szerokosc arkusza; instrukcja pod nim. */
.ntb-pomiar__schemat { margin: 0; padding: 14px 16px 16px; background: var(--c-paper); }
.ntb-pomiar__schemat .ntb-infografika { margin: 0 auto; max-width: 420px; }
.ntb-pomiar__how { margin-top: var(--s-4); }
/* Kalkulator wtyczki w arkuszu: bez wlasnego panelu i drugiej ramki, jedna
   kolumna (pole nad wynikiem), tytul jako srodtytul arkusza. */
.ntb-pomiar__calc { margin-top: var(--s-5); padding-top: var(--s-5); border-top: var(--bw-hair) solid var(--c-line); }
.ntb-pomiar__calc .ntbs-kalkulator__panel { padding: 0; border: 0; background: none; }
.ntb-pomiar__calc .ntbs-kalkulator__tytul { font-size: var(--fs-600); }
.ntb-pomiar__calc .ntbs-kalkulator__cols { grid-template-columns: minmax(0, 1fr); }
.ntb-pomiar__calc .ntbs-kalkulator__out .ntbs-wynik { margin-top: var(--s-3); }
.ntb-pomiar__calc .ntbs-form { grid-template-columns: minmax(0, 1fr); }
.ntb-pomiar__calc .ntbs-form__wyslij { width: 100%; justify-content: center; }
/* Po wyniku jeden przycisk glowny („Wybierz ten rozmiar”, doklejany skryptem);
   „Produkty w tym rozmiarze” i „Zapisz wymiary” to na karcie drogi poboczne -
   odnosniki tekstowe w jednym wierszu, nie trzy czarne belki. */
.ntb-pomiar__calc .ntbs-wynik__akcje { align-items: center; gap: 4px var(--s-5); }
.ntb-pomiar__calc .ntbs-wynik__akcje .ntbs-wynik__wybierz { flex: 1 1 100%; justify-content: center; margin-bottom: var(--s-2); }
.ntb-pomiar__calc .ntbs-wynik__akcje a.ntb-btn { min-height: var(--touch); padding: 0; border: 0; background: none; color: var(--c-ink); font-size: var(--fs-300); letter-spacing: .02em; text-transform: none; text-decoration: underline; text-underline-offset: 3px; box-shadow: none; }
.ntb-pomiar__calc .ntbs-wynik__akcje a.ntb-btn:hover { color: var(--c-ink-2); }
/* Ognisko na wyniku jest programowe (po przeliczeniu), ramka nie ma tu czego sygnalizowac. */
.ntb-pomiar__calc .ntbs-wynik:focus { outline: none; }

.ntb-calc { margin-top: var(--s-5); }
.ntb-calc label { display: grid; gap: var(--s-2); max-width: 240px; }
.ntb-calc label > span:first-child { font-size: var(--fs-300); font-weight: var(--fw-semibold); letter-spacing: .06em; }
.ntb-calc__field { display: flex; align-items: center; height: var(--h-field); border: var(--bw-hair) solid var(--c-ink); }
.ntb-calc__field input { flex: 1; min-width: 0; height: 100%; padding-inline: 14px; border: 0; background: none; font: inherit; font-size: var(--fs-500); font-variant-numeric: tabular-nums; }
.ntb-calc__field input:focus { outline: none; }
.ntb-calc__field > span { display: flex; align-items: center; height: 100%; padding-inline: 14px; border-left: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-calc__result { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); margin-top: var(--s-5); padding: 22px 24px; background: var(--c-paper); }
.ntb-calc__result > div { flex: 1; min-width: 180px; }
.ntb-calc__result strong { display: block; margin-top: var(--s-2); font-family: var(--f-display); font-size: var(--fs-900); font-weight: var(--fw-regular); line-height: var(--lh-tight); }
.ntb-calc__hint { margin-top: var(--s-4); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }

/* --- Pasek zakupu na telefonie --- */
.ntb-buybar { display: none; }

@media (max-width: 767px) {
  /* NTB24 Mobile sekcja 06: naglowek karty na 390 px ma 25 px. */
  .ntb-buy__h1 { font-size: var(--fs-800); line-height: var(--lh-tight); }
  .ntb-gallery__thumbs { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* Arkusz od dolu ekranu: gorna krawedz z uchwytem, naglowek przyklejony,
     tresc przewija sie w srodku, dol z marginesem bezpiecznym. */
  .ntb-modal { inset: auto 0 0 0; left: 0; top: auto; width: auto; max-width: none; height: auto; max-height: min(92vh, 92dvh); transform: none; border: 0; border-top: var(--bw-heavy) solid var(--c-ink); padding-bottom: var(--safe-b); }
  .ntb-modal__head { padding: 22px var(--s-4) 14px; }
  .ntb-pomiar__grip { display: block; position: absolute; top: 8px; left: 50%; width: 40px; height: 3px; margin-left: -20px; background: var(--c-line-2); }
  .ntb-modal__head h2 { font-size: var(--fs-600); }
  .ntb-modal__body { padding: var(--s-4) var(--s-4) var(--s-6); }
  .ntb-pomiar__schemat { margin-inline: calc(-1 * var(--s-4)); padding: 12px var(--s-3) 14px; }
  .ntb-pomiar__calc .ntbs-kalkulator__tytul { font-size: var(--fs-500); }
  .ntb-reviews__summary { flex: 1 1 100%; }

  .ntb-buybar {
    position: fixed;
    inset: auto 0 0 0;
    z-index: var(--z-mobilebar);
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: 10px var(--s-4) calc(10px + var(--safe-b));
    background: var(--c-bg);
    border-top: var(--bw-hair) solid var(--c-line);
    box-shadow: var(--sh-bar);
    transition: transform var(--dur) var(--ease);
  }
  .ntb-buybar.is-hidden { transform: translateY(100%); }
  .ntb-buybar__info { flex: 1; display: grid; gap: 2px; min-width: 0; }
  .ntb-buybar__price { font-size: var(--fs-600); font-weight: var(--fw-medium); }
  .ntb-buybar__size { font-size: var(--fs-200); color: var(--c-ink-3); }
  /* Przycisk paska zakupu ma 52 px, jak kazdy przycisk glowny (par. 3),
     a nie minimum dotykowe 44 px - to on jest celem calego ekranu. */
  .ntb-buybar .ntb-btn { flex: none; min-height: var(--h-btn); }

  /* Galeria i blok zakupu jedna pod druga; miniatury sa celem dotykowym. */
  .ntb-product, .ntb-pcols { grid-template-columns: minmax(0, 1fr); }
  .ntb-sizing__grid { grid-template-columns: minmax(0, 1fr); }
  .ntb-gallery__thumb { min-height: var(--touch); }

  /* Stepper w koszyku: 40 px, a pole dotyku plusa i minusa siega
     krawedzi wiersza, zeby trafic kciukiem bez celowania (par. 3). */
  .ntb-cartitem .ntb-qty { height: var(--touch); }
  .ntb-cartitem .ntb-qty button { width: var(--touch); }
  .ntb-cartitem__row { gap: var(--s-3); }
  .ntb-cartpanel .ntb-qty { height: var(--touch); }
  .ntb-cartpanel .ntb-qty button { width: var(--touch); }
  .ntb-cartrow__change { display: inline-flex; align-items: center; min-height: var(--touch); padding-inline: 4px; }
}

/* ============================================================
   20. TABELE JAKO LISTY DEFINICJI NA 390 px (regula 3)
   Kazdy wiersz staje sie blokiem, a kazda komorka para etykieta-wartosc.
   Etykieta pochodzi z atrybutu data-label na komorce; gdy go nie ma,
   wiersz nadal czyta sie poprawnie, tylko bez podpisu kolumny.
   ============================================================ */

@media (max-width: 767px) {
  /* caption jest tu razem z reszta: bez display: block zostawal komorka tabeli
     w tabeli, ktora tabela juz nie jest - zwezal sie do 85 z 358 px i puchl
     z 72 do 462 px wysokosci na tych samych 286 znakach. */
  .ntb-table, .ntb-table caption, .ntb-table tbody, .ntb-table tr, .ntb-table td { display: block; width: 100%; }
  .ntb-table caption { text-align: left; }

  /* Naglowek kolumn nie znika z drzewa dostepnosci, tylko z widoku -
     czytnik ekranu nadal wiaze komorki z naglowkami. */
  .ntb-table thead {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
  }

  .ntb-table tbody tr {
    padding-block: var(--s-3);
    border-bottom: var(--bw-hair) solid var(--c-line);
  }
  .ntb-table tbody tr:last-child { border-bottom: 0; }

  .ntb-table td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    padding-block: 5px;
    border-bottom: 0;
    text-align: right;
  }
  .ntb-table td::before {
    content: attr(data-label);
    flex: none;
    font-size: var(--fs-100);
    font-weight: var(--fw-semibold);
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--c-ink-3);
    text-align: left;
  }
  /* Pierwsza komorka wiersza jest jego naglowkiem, wiec czyta sie mocniej. */
  .ntb-table tbody td:first-child { font-weight: var(--fw-medium); }
  .ntb-table tbody tr.is-match { padding-inline: var(--s-3); }

  /* Tabela porownania jest wyjatkiem od ukladu "etykieta z lewej, wartosc
     z prawej": etykieta to pelna nazwa produktu, wiec przy flex: none
     spychala wartosc poza ekran i obcinala ja krawedzia (widoczne na
     qa/porownaj-390.png). Tu nazwa stoi nad wartoscia. */
  .ntb-compare tbody th[scope="row"] { display: block; width: 100%; padding-bottom: var(--s-2); }
  .ntb-compare td { display: block; padding-block: 6px 10px; text-align: left; }
  .ntb-compare td::before { display: block; margin-bottom: 3px; }
  .ntb-compare tbody td:first-of-type { font-weight: var(--fw-regular); }

  /* Nazwa produktu w naglowku kolumny to jedyne wyjscie z tabeli na karte,
     a jako zwykly odnosnik w wierszu tekstu miala 15 px wysokosci - ponizej
     minimum dotykowego 44 px z reguly 3. Pole dotyku podnosimy samym
     odnosnikiem, bez ruszania siatki tabeli. */
  .ntb-compare thead a {
    display: flex;
    align-items: center;
    min-height: var(--touch);
  }
}

/* ============================================================
   21. CELE DOTYKOWE NA 390 px (regula 3)
   Kazdy link nawigacyjny, kazdy przycisk i kazda kontrolka filtra ma
   co najmniej 44 px wysokosci. Powiekszamy POLE DOTYKU (padding albo
   min-height), nigdy stopien pisma. Linki w blokach tekstowych
   (.ntb-prose, .ntb-faq, tresc redakcyjna) sa z tego wylaczone.

   TA SEKCJA MUSI ZOSTAC OSTATNIA. Wczesniej stala jako 16b, przed
   sekcjami 17-19, wiec kazda pozniejsza wartosc bazowa komponentu ja
   nadpisywala: .ntb-fitem wracalo do 34 px, .ntb-select do 40 px,
   a .ntb-ftree a do 24 px. Media query nie dodaje specyficznosci,
   liczy sie kolejnosc - nowe reguly dotykowe dopisujemy tutaj.

   PROG 1023, NIE 767. Szuflada filtrow wlacza sie od 1023 px w dol, wiec
   miedzy 768 a 1023 px panel byl juz dotykowy, a kontrolki w nim zostawaly
   desktopowe: 74 sztuki ponizej 44 px ("Wyczysc" 18,6, odnosniki drzewa 24,
   "Zwin grupe" 28, kazdy .ntb-fitem 34, selecty 38). Luka 256 px miedzy
   dwoma progami tego samego zachowania. Ten sam prog maja sekcje 22 i 30.
   ============================================================ */

@media (max-width: 1023px) {
  .ntb-link,
  .ntb-card__name,
  .ntb-crumbs a,
  .ntb-dept__list a,
  .ntb-dept__more,
  .ntb-footer ul a,
  .ntb-catlinks a,
  .ntb-tree__sub a,
  .ntb-ftree a,
  .ntb-chips__clear,
  .ntb-fgroup__link,
  .ntb-fgroup__more,
  .ntb-filters__head a,
  .ntb-sechead__link,
  .ntb-buy__brand,
  .ntb-buy__guide,
  .ntb-buy__acts button,
  .ntb-notify button,
  .ntb-cartpanel__empty a,
  .ntb-cartitem__remove {
    display: inline-flex;
    align-items: center;
    min-height: var(--touch);
  }
  /* Usuwanie pozycji koszyka to ikona bez tekstu z twarda szerokoscia 20 px,
     wiec samo min-height dawaloby cel 20x44. min-width wygrywa z width. */
  .ntb-cartitem__remove { justify-content: center; min-width: var(--touch); }

  /* Marka nad tytulem stoi w wierszu wyrownanym do linii pisma; pole dotyku
     rosnie w gore i w dol wokol tej samej linii, wiec tytul nie odjezdza. */
  .ntb-buy__top { align-items: center; }

  /* Kontrolki, ktore w projekcie desktopowym sa nizsze niz 44 px. */
  .ntb-select,
  .ntb-chip,
  .ntb-chips .ntb-chip,
  .ntb-modal__close,
  .ntb-cartpanel__close,
  .ntb-filters__close,
  .ntb-fgroup__toggle { min-height: var(--touch); }
  .ntb-modal__close, .ntb-cartpanel__close, .ntb-filters__close, .ntb-fgroup__toggle { min-width: var(--touch); }

  /* Celem dotykowym jest sam <select>, nie jego opakowanie - to select
     lapie palec. Opakowanie ma tylko min-height, wiec urosnie za nim. */
  .ntb-select select { min-height: var(--touch); }

  /* Numery stron: Woo opisuje je pelnym lancuchem selektorow, wiec krotkie
     `.woocommerce-pagination a` przegrywalo i cel zostawal 27 px szeroki. */
  .woocommerce-pagination a,
  .woocommerce-pagination span,
  .woocommerce nav.woocommerce-pagination ul li a,
  .woocommerce nav.woocommerce-pagination ul li span {
    min-width: var(--touch);
    min-height: var(--touch);
    height: auto;
  }

  /* Chip rozmiaru na liscie zostaje maly wzrokowo (44x28 wg par. 3), bo
     w karcie w petli nie jest kontrolka - to <span> niosacy stan. Kontrolki
     fasety sa linkami, wiec ida do pelnego celu dotykowego. */
  .ntb-fitem { min-height: var(--touch); }
  .ntb-fgroup[data-style="tiles"] .ntb-fitem { min-height: var(--touch); min-width: var(--touch); }

  /* Pozycja listy dzialow zajmuje caly wiersz swojej kolumny, wiec
     display: flex zamiast inline-flex. Przy inline-flex cel mial szerokosc
     samego napisu i krotkie nazwy ("Derki", "Kopyta", "Siodla") schodzily
     ponizej 44 px, choc wysokosc byla juz dobra. */
  .ntb-tree__sub a,
  .ntb-dept__list a,
  .ntb-ftree a { display: flex; }

  /* Krotkie napisy dawaly cel wezszy niz 44 px mimo poprawnej wysokosci:
     okruch "Kopyta" mierzyl 41x44, a odnosnik dzialu 44x44 tylko z zaokraglenia
     (43,7 px). Wysokosc zalatwia min-height wyzej, szerokosc dopiero to.
     Widac to jedynie na kategoriach o krotkiej nazwie, dlatego audyt trafial
     na to losowo - zaleznie od tego, ktory produkt wybral do zrzutu. */
  .ntb-crumbs a,
  .ntb-catlinks a,
  .ntb-buy__brand { min-width: var(--touch); }

  /* Kafle dzialow na stronie dzialu nadrzednej (/kategoria/dla-konia/) mialy
     40 px wysokosci - nie sa objete zadnym z selektorow wyzej, bo to gole <a>
     w .ntb-cathead__children. Widac to tylko na stronach dzialow bez produktow,
     ktorych audyt nie odwiedza. */
  .ntb-cathead__children a {
    display: inline-flex;
    align-items: center;
    min-height: var(--touch);
    min-width: var(--touch);
  }

  /* Ikony narzedzi i pozycje paska dzialow. */
  .ntb-tools__item, .ntb-mbar__item, .ntb-filters-open { min-height: var(--touch); }

  /* Chip osi wariantu. Na ukladach D i E to on JEST selektorem rozmiaru
     (inc/product.php), a prawdziwy input jest niewidoczny - wiec celem dotyku
     jest etykieta. Dotad spadala na wymiar faseta 56x38 px i lamala regule 3
     na 3 107 kartach wariantowych (audyt 1.10.2026). */
  .ntb-size--pick { min-height: var(--touch); }
}

/* ==========================================================================
   22. Cele dotykowe w markupie, ktorego nie piszemy sami         [ntb-dotyk-woo]
   ==========================================================================
   Koszyk i formularze konta renderuje WooCommerce wlasnymi szablonami,
   wiec ich kontrolki omijaja nasz system rozmiarow. Zmierzone na 390 px:
   a.button w koszyku 127x32, checkbox "nie wylogowuj mnie" 20x20.
   Regula 3 wymaga 44 px, wiec podnosimy POLE DOTYKU, nie stopien pisma
   ani nie sam kwadrat pola wyboru - ten zostaje 20 px zgodnie z paragrafem 3.
   Prog 1023 jak w sekcji 21. */

@media (max-width: 1023px) {

	.woocommerce a.button,
	.woocommerce button.button,
	.woocommerce input.button,
	.woocommerce-page a.button,
	.woocommerce-page button.button {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		min-height: var(--touch);
		padding-block: 0;
	}

	/* Pole wyboru zostaje 20 px, ale klikalny obszar dookola ma 44 px.
	   Etykieta jest celem razem z polem, wiec podnosimy oba. */
	/* .ntb-check__label to ZDANIE obok pola wyboru, nie kontrolka: przy
	   inline-flex jego dzieci ("Akceptuję", odnosnik "regulamin", "i",
	   odnosnik "politykę prywatności") stawaly sie osobnymi elementami
	   w rzedzie z przerwami, a koncowka zdania wpadala w slupek 91 px.
	   Cel dotykowy daje etykieta-rodzic (label.ntb-check, min-height 44 px). */
	.woocommerce form .form-row label.checkbox,
	.woocommerce-form__label-for-checkbox {
		display: inline-flex;
		align-items: center;
		gap: var(--s-2);
		min-height: var(--touch);
	}

	.woocommerce form .form-row input[type="checkbox"],
	.woocommerce-form__input-checkbox,
	.ntb-check__input,
	.ntb-check input[type="checkbox"] {
		position: relative;
		width: var(--box-form);
		height: var(--box-form);
		margin: 0;
		flex: none;
	}

	.woocommerce form .form-row input[type="checkbox"]::before,
	.woocommerce-form__input-checkbox::before,
	.ntb-check__input::before,
	.ntb-check input[type="checkbox"]::before {
		content: "";
		position: absolute;
		inset: calc( ( var(--box-form) - var(--touch) ) / 2 );
		min-width: var(--touch);
		min-height: var(--touch);
	}
}

/* ==========================================================================
   23. KARTA PRODUKTU - SZESC UKLADOW                              [ntb-uklady]
   ==========================================================================
   single-product.php rozgalezia sie przez ntb24_layout() na layout-{a..f}.php
   i owija wynik w .ntb-pcard z modyfikatorem literowym. Czesc wspolna szesciu
   ukladow (naglowek, cena, zakup, kafle, wiersze, ostrzezenie) siedzi
   w template-parts/product/shared.php, wiec i CSS jest tu jeden dla wszystkich,
   a modyfikatory literowe zostaja puste - sa punktem zaczepienia dla wyjatkow.
   Bloki decydujace (matryca, skala, konfigurator, opakowania, norma) maja
   wlasna sekcje 24. */

/* Sam wrapper nie ma wygladu: to hak dla wyjatkow ukladowych. */
.ntb-pcard { display: block; }

/* Kadr 1:1 dla siodel (C), suplementow i kosmetykow (D) oraz ukladu
   minimalnego (E) - par. 3 wymienia je wprost. Selektor schodzi przez
   .ntb-gallery, zeby nie zlapac kadrow kart w sekcji "Z tej samej grupy",
   ktora w ukladzie E lezy w tym samym .ntb-pcard i ma zostac 4:5. */
.ntb-pcard--square .ntb-gallery__main,
.ntb-pcard--square .ntb-gallery .ntb-ph { aspect-ratio: 1 / 1; }
.ntb-pcard--square .ntb-gallery__thumb { aspect-ratio: 1 / 1; }

/* Uklad E jest wezszy od pozostalych: przy dwoch kolumnach po 780 px
   prawa zostawalaby w polowie pusta i czytalaby sie jak blad skladu. */
/* Uklad E jest wezszy swiadomie (single-product.php:65), ale bez wysrodkowania
   1 040 px stalo dosuniete do lewej: prawa krawedz skakala z 1144 na 1400 px
   miedzy blokiem zakupu a sekcja pod nim, na 3 535 kartach. */
.ntb-pcard--narrow .ntb-product--narrow { max-width: 1040px; margin-inline: auto; }
.ntb-product--narrow { gap: 40px; }

/* Uklad D: zdjecie opakowania jest male, a tresc szeroka, wiec zamiast
   1fr 1fr idzie flex z bazami (par. 3, dwukolumnowe uklady przez flex-wrap). */
.ntb-product--aside { display: flex; flex-wrap: wrap; gap: 44px; align-items: flex-start; }
.ntb-product--aside > .ntb-gallery-col { flex: 0 1 300px; min-width: 0; }
.ntb-product--aside > .ntb-buy { flex: 2 1 420px; min-width: 0; }

/* Kolumna galerii trzyma razem kadr i to, co pod nim: pasek normy (F),
   schemat pomiaru (B), kafle (C). */
.ntb-gallery-col { display: grid; gap: 10px; align-content: start; min-width: 0; }

/* --- Blok naglowka -------------------------------------------------------- */

.ntb-buy__meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.ntb-buy__group {
	font-size: var(--fs-100);
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--c-ink-3);
}
.ntb-buy__group:hover { color: var(--c-ink-3); text-decoration: underline; text-underline-offset: 3px; }
/* Kropka miedzy marka a grupa jest wylacznie separatorem, nie trescia. */
.ntb-buy__dot { color: var(--c-line-2); }

/* Uklad E ma naglowek o stopien mniejszy - kolumna zakupu jest tam wezsza. */
.ntb-pcard--e .ntb-buy__h1 { font-size: var(--fs-800); line-height: var(--lh-tight); }

/* Chipy cech pod H1: etykiety, nie kontrolki - bez ramki i bez hovera. */
.ntb-feats { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-4); }
.ntb-feat {
	padding: 6px 11px;
	border-radius: var(--r-0);
	background: var(--c-paper);
	font-size: var(--fs-200);
	line-height: var(--lh-label);
	color: var(--c-ink-2);
}

/* --- Blok ceny ------------------------------------------------------------ */

/* Dwa odstepstwa od 30 px: siodla (C) czytaja cene jako pierwsza informacje,
   uklad minimalny (E) nie ma jej czym przewazyc. */
.ntb-buy__price--duza { font-size: var(--fs-850); }
.ntb-buy__price--mala { font-size: var(--fs-800); }

/* Druga wartosc obok ceny: cena za litr w D, odnosnik do rat w C.
   Waga i stopien pisma wracaja do wartosci tekstowych, bo kontener ceny
   ma 30 px i wage 500. */
.ntb-buy__aside {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding-left: var(--s-5);
	border-left: var(--bw-hair) solid var(--c-line);
}
.ntb-buy__asideval { font-size: var(--fs-600); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.ntb-buy__asidenote { font-size: var(--fs-300); font-weight: var(--fw-regular); line-height: var(--lh-label); color: var(--c-ink-3); }
.ntb-buy__asidelink {
	font-size: var(--fs-200);
	font-weight: var(--fw-regular);
	line-height: var(--lh-label);
	color: var(--c-ink-3);
	text-decoration: underline;
	text-underline-offset: 3px;
}
.ntb-buy__asidelink:hover { color: var(--c-ink); }

/* --- Blok zakupu ---------------------------------------------------------- */

.ntb-buy__hint { font-size: var(--fs-200); font-weight: var(--fw-regular); color: var(--c-ink-3); }
.ntb-buy__lead { margin-top: var(--s-4); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); max-width: var(--w-text); }

/* W ukladzie D nie ma drugiego przycisku (W4: blok subskrypcji ukryty),
   wiec CTA bierze caly wiersz obok steppera zamiast konczyc sie w polowie.
   Podstawa 200 px wprost z projektu ukladu D. Nie 100 %: przy pelnej
   szerokosci CTA schodzi POD stepper i pierwszy wiersz zostaje z sama
   ramka ilosci - widac to bylo na zrzucie D-top.png. */
.ntb-buy__form--wide .ntb-buy__add, .ntb-buy__form--wide .ntb-buy__now { flex: 1 1 180px; }

/* Drugi przycisk obok czarnego: "Popros o dobor" (C), "Przymierz
   w showroomie" (F). Wyglad daje .ntb-btn--ghost, tutaj tylko baza flex
   i odstep przy ikonie. */
.ntb-buy__second { flex: 1 1 180px; gap: 9px; }
/* Siodla maja przyciski o 2 px wyzsze - projekt ukladu C. Podnosimy oba,
   inaczej wiersz konczy sie schodkiem. */
.ntb-pcard--c .ntb-buy__form .ntb-btn { min-height: 54px; }

/* --- Kafle i wiersze ------------------------------------------------------ */

/* Linie robi tlo z odstepem 2 px, nie ramki (par. 3). Flex, nie grid
   auto-fit: liczba kafli jest zmienna, a pusta komorka odslonilaby tlo (D12). */
.ntb-tiles { display: flex; flex-wrap: wrap; gap: 2px; margin-top: var(--s-5); background: var(--c-line); }
.ntb-tile { flex: 1 1 180px; display: flex; flex-direction: column; gap: 5px; padding: 14px 16px; background: var(--c-bg); }
.ntb-tile__value { font-size: var(--fs-400); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.ntb-tile__note { font-size: var(--fs-200); color: var(--c-ink-3); }

.ntb-rows { display: grid; gap: 2px; margin-top: var(--s-5); background: var(--c-line); }
.ntb-rows__item {
	display: flex;
	align-items: flex-start;
	gap: var(--s-3);
	padding: 15px 16px;
	background: var(--c-bg);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
}
.ntb-rows__item svg { flex: none; margin-top: 1px; color: var(--c-ink-2); }

/* --- Ostrzezenie i panel --------------------------------------------------
   Ostrzezenie to ramka 1 px czerni i ikona, nigdy kolor funkcyjny (D07).
   .ntb-hint to ten sam klocek lagodniej: bez ramki, na tle panelu. */
.ntb-warn {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin-top: var(--s-3);
	padding: 12px 14px;
	border: var(--bw-hair) solid var(--c-ink);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink);
}
.ntb-warn svg { flex: none; margin-top: 1px; color: var(--c-ink); }
.ntb-warn p { margin: 0; }

.ntb-hint {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin-top: var(--s-3);
	padding: 12px 14px;
	background: var(--c-paper);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink-2);
}
.ntb-hint svg { flex: none; margin-top: 1px; color: var(--c-ink-2); }

/* --- Dane techniczne ------------------------------------------------------ */

/* Wariant listy definicji w kolumnie zakupu (uklad E): bez naglowka sekcji,
   wiec odstep gorny jest wiekszy, a wiersze o stopien nizsze. */
.ntb-specs--buy { margin-top: 26px; font-size: var(--fs-300); }
.ntb-specs--buy dt { padding-block: 11px; }
.ntb-specs--buy dd { padding: 11px 0 11px 20px; }

/* Sekcja "Dane techniczne" (template-parts/product/tech.php). Dzis nikt nie
   wola akcji ntb24_product_tech, wiec sie nie renderuje; regula czeka gotowa.
   Odstep sekcji zastepuje hairline plus 32 px, dokladnie jak w .ntb-pcols. */
.ntb-tech { padding-top: var(--s-6); border-top: var(--bw-hair) solid var(--c-line); }
.ntb-tech__title { font-size: var(--fs-800); line-height: var(--lh-tight); letter-spacing: -.015em; margin-bottom: 18px; }
/* Lista nie rozciaga sie na cala szerokosc kontenera - w projekcie stoi
   w kolumnie zakupu szerokiej okolo 640 px. */
.ntb-tech__list { margin-top: 0; max-width: 640px; }

/* ==========================================================================
   24. BLOKI DECYDUJACE UKLADOW A-F                                 [ntb-bloki]
   ==========================================================================
   Kazdy uklad ma jeden blok, ktory rozstrzyga zakup: matryca kolor x rozmiar
   (A), skala pomiaru (B), konfigurator rodzenstwa (C), wybor opakowania (D),
   dane techniczne (E, sekcja 23), norma i obwod glowy (F).
   Stany dostepnosci rysujemy ramka i wysokoscia, nigdy kolorem i nigdy
   liczba sztuk (regula 1, D04). */

/* --- A. Matryca kolor x rozmiar ------------------------------------------ */

/* Sekcja niesie .ntb-wrap, wiec margines boczny strony zostaje na miejscu,
   a tlo panelu idzie na pelna szerokosc kolumny - dlatego padding boczny
   to var(--pad-page), nie 34 px z projektu: tresc ma stac w tej samej
   pionowej linii co reszta karty. */
.ntb-matrix { margin-top: 44px; padding: 32px var(--pad-page); background: var(--c-paper); }
.ntb-matrix__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--s-4) var(--s-7);
}
.ntb-matrix__title { margin-top: 10px; font-size: var(--fs-800); }
.ntb-matrix__lead { margin-top: 10px; font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); max-width: var(--w-text); }
/* Na desktopie matryca nie jest arkuszem, wiec nie ma czego zamykac. */
.ntb-matrix__close { display: none; }

/* Wejscie do matrycy z kolumny zakupu. Na 390 px jedyne, na 1440 px skrot
   do sekcji nizej. */
.ntb-matrix__trigger {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: var(--h-btn);
	margin-top: var(--s-3);
	padding: 0 14px;
	border: var(--bw-hair) solid var(--c-line);
	font-size: var(--fs-300);
	color: var(--c-ink);
}
.ntb-matrix__trigger svg:first-of-type { flex: none; color: var(--c-ink-2); }
.ntb-matrix__trigger svg:last-of-type { flex: none; margin-left: auto; color: var(--c-ink-4); }
.ntb-matrix__trigger:hover { border-color: var(--c-ink); }

/* KLASA BLOKUJACA: bez niej karta ukladu A przewija sie w bok o 96 px
   na 390 px (zmierzone w qa/raport.json). Tabela ma wlasne przewijanie,
   strona nie rusza sie ani o piksel. */
.ntb-matrix__scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: var(--s-5); }

.ntb-matrix__table { width: 100%; border-collapse: collapse; background: var(--c-bg); font-size: var(--fs-300); }
.ntb-matrix__table th {
	padding: 12px 8px;
	border-bottom: var(--bw-hair) solid var(--c-ink);
	font-weight: var(--fw-semibold);
	text-align: center;
}
.ntb-matrix__table thead th:first-child,
.ntb-matrix__table tbody th { text-align: left; padding-inline: 14px; min-width: 210px; }
.ntb-matrix__table td { padding: 11px 8px; border-bottom: var(--bw-hair) solid var(--c-line); text-align: center; }
.ntb-matrix__table tbody th { font-weight: var(--fw-regular); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-matrix__table td:last-child { padding-inline: 14px; }

/* Znacznik stanu w komorce i w legendzie. Rozmiar nie zmienia sie ze stanem -
   kwadrat mowi o stanie, nie o ilosci (regula 1). */
.ntb-matrix__cell { display: inline-block; width: 13px; height: 13px; }
.ntb-matrix__cell[data-state="available"] { background: var(--c-ink); }
.ntb-matrix__cell[data-state="backorder"] { border: var(--bw-hair) dotted var(--c-ink); }
.ntb-matrix__cell[data-state="soon"] { border: var(--bw-hair) dashed var(--c-line-2); }
.ntb-matrix__cell[data-state="discontinued"] {
	border: var(--bw-hair) solid var(--c-line);
	background-image: repeating-linear-gradient(45deg, var(--c-line-2) 0 1px, transparent 1px 4px);
}

.ntb-matrix__color { display: flex; align-items: center; gap: 10px; }
.ntb-matrix__color .ntb-swatch { flex: none; width: 16px; height: 16px; }
.ntb-matrix__reach { text-align: right; color: var(--c-ink-3); padding-inline: 14px; }

.ntb-matrix__legend { display: flex; flex-wrap: wrap; gap: 14px 20px; margin-top: var(--s-4); font-size: var(--fs-200); color: var(--c-ink-2); }
.ntb-matrix__key { display: flex; align-items: center; gap: 7px; }
.ntb-matrix__note { margin-top: 14px; font-size: var(--fs-200); line-height: var(--lh-body); color: var(--c-ink-3); }

/* Kolumna wybranego rozmiaru. Klase ustawia JS po wyborze rozmiaru;
   tutaj jest cala mechanika podswietlenia z projektu. */
[data-ntb-matrix-col].is-on { background: var(--c-paper); }

/* --- B. Skala pomiaru ----------------------------------------------------- */

/* Wariant liniowy: wysokosc slupka niesie stan, nie kolor. */
.ntb-scale { margin-top: 18px; padding: 20px 20px 16px; border: var(--bw-hair) solid var(--c-line); }
.ntb-scale__track { display: flex; align-items: flex-end; gap: 0; }
.ntb-scale__step {
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--s-2);
	padding: 0;
	border: 0;
	background: none;
}
.ntb-scale__label { font-size: var(--fs-200); font-variant-numeric: tabular-nums; color: var(--c-ink); }
.ntb-scale__bar { width: 100%; height: 42px; border: var(--bw-hair) solid var(--c-ink); }

.ntb-scale__step[data-state="backorder"] .ntb-scale__label,
.ntb-scale__step[data-state="soon"] .ntb-scale__label { color: var(--c-ink-3); } /* 5,0:1 - klient ma z tej cyfry odczytac, na ktory rozmiar zapisac powiadomienie; stan sygnalizuje kropkowany slupek */
.ntb-scale__step[data-state="backorder"] .ntb-scale__bar,
.ntb-scale__step[data-state="soon"] .ntb-scale__bar { height: 30px; border: var(--bw-hair) dotted var(--c-line-2); }
.ntb-scale__step[data-state="discontinued"] { pointer-events: none; }
.ntb-scale__step[data-state="discontinued"] .ntb-scale__label { color: var(--c-ink-3); }
.ntb-scale__step[data-state="discontinued"] .ntb-scale__bar {
	height: 30px;
	border: var(--bw-hair) dotted var(--c-line-2);
	background-image: repeating-linear-gradient(45deg, var(--c-hatch) 0 1px, transparent 1px 6px);
}

/* Wybrany rozmiar: slupek pelny, wyzszy, z ptaszkiem, i o cwierc szerszy
   od sasiadow, zeby dalo sie go wskazac palcem bez celowania. */
.ntb-scale__step[aria-pressed="true"] { flex: 1.25; }
.ntb-scale__step[aria-pressed="true"] .ntb-scale__label { font-weight: var(--fw-semibold); color: var(--c-ink); }
.ntb-scale__step[aria-pressed="true"] .ntb-scale__bar {
	height: 54px;
	display: grid;
	place-items: center;
	border-color: var(--c-ink);
	background: var(--c-ink);
}
.ntb-scale__step[aria-pressed="true"] .ntb-scale__bar::before {
	content: "";
	width: 14px;
	height: 14px;
	background: var(--c-on-ink);
	-webkit-mask: var(--i-check) center / 14px 14px no-repeat;
	mask: var(--i-check) center / 14px 14px no-repeat;
}

.ntb-scale__legend {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 10px 20px;
	margin-top: 14px;
	padding-top: var(--s-3);
	border-top: var(--bw-hair) solid var(--c-line);
	font-size: var(--fs-200);
	color: var(--c-ink-2);
}
.ntb-scale__legend > span { display: inline-flex; align-items: center; gap: 7px; }
.ntb-scale__key { flex: none; width: 14px; height: 10px; }
.ntb-scale__key--on { background: var(--c-ink); }
.ntb-scale__key--available { border: var(--bw-hair) solid var(--c-ink); }
.ntb-scale__key--backorder { border: var(--bw-hair) dotted var(--c-line-2); }
.ntb-scale__note { color: var(--c-ink-3); }

/* Wariant opisowy: PONY / COB / FULL albo S / M / L z nota z opisu terminu. */
.ntb-horse { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: 18px; }
.ntb-horse__item {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-height: var(--touch);
	padding: 10px 14px;
	border: var(--bw-hair) solid var(--c-line-2);
	background: none;
	text-align: left;
}
.ntb-horse__item:hover { border-color: var(--c-ink); }
.ntb-horse__name { font-size: var(--fs-300); }
.ntb-horse__note { font-size: var(--fs-100); line-height: var(--lh-label); color: var(--c-ink-3); }
.ntb-horse__item[aria-pressed="true"] { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-horse__item[aria-pressed="true"] .ntb-horse__note { color: var(--c-line-2); }
.ntb-horse__item[data-state="backorder"],
.ntb-horse__item[data-state="soon"] { border-style: dotted; color: var(--c-ink-3); }
.ntb-horse__item[data-state="discontinued"] {
	pointer-events: none;
	border-color: var(--c-line);
	color: var(--c-ink-3);
	background-image: repeating-linear-gradient(45deg, var(--c-hatch) 0 1px, transparent 1px 6px);
}

/* --- C. Konfigurator rodzenstwa ------------------------------------------ */

.ntb-config__opts { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.ntb-config__opt {
	min-width: 64px;
	min-height: 46px;
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	padding-inline: 12px;
	border: var(--bw-hair) solid var(--c-line-2);
	font-size: var(--fs-400);
	font-variant-numeric: tabular-nums;
	color: var(--c-ink);
}
a.ntb-config__opt:hover { border-color: var(--c-ink); color: var(--c-ink); }
.ntb-config__opt.is-on { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); font-weight: var(--fw-medium); }
.ntb-config__opt[data-state="backorder"],
.ntb-config__opt[data-state="soon"] { border-style: dotted; color: var(--c-ink-3); }
.ntb-config__opt[data-state="discontinued"] {
	pointer-events: none;
	border-color: var(--c-line);
	color: var(--c-ink-3);
	background-image: repeating-linear-gradient(45deg, var(--c-hatch) 0 1px, transparent 1px 6px);
}
.ntb-config__state { font-size: var(--fs-50); letter-spacing: .08em; text-transform: uppercase; }
.ntb-config__note { margin-top: 9px; font-size: var(--fs-200); line-height: var(--lh-body); color: var(--c-ink-3); }

/* --- D. Cena jednostkowa i opakowania ------------------------------------ */

.ntb-unit { display: flex; flex-direction: column; gap: var(--s-1); }
.ntb-unit__price { font-size: var(--fs-600); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.ntb-unit__note { font-size: var(--fs-300); color: var(--c-ink-3); }

.ntb-packs { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-3); }
.ntb-pack {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-height: var(--h-btn);
	padding: 12px 16px;
	border: var(--bw-hair) solid var(--c-line-2);
	background: none;
	text-align: left;
}
.ntb-pack:hover { border-color: var(--c-ink); }
.ntb-pack__size { font-size: var(--fs-300); font-variant-numeric: tabular-nums; }
.ntb-pack__unit { font-size: var(--fs-100); font-variant-numeric: tabular-nums; color: var(--c-ink-3); }
.ntb-pack[aria-pressed="true"] { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-pack[aria-pressed="true"] .ntb-pack__unit { color: var(--c-line-2); }
.ntb-pack[data-state="backorder"],
.ntb-pack[data-state="soon"] { border-style: dotted; color: var(--c-ink-3); }
.ntb-pack[data-state="discontinued"] {
	pointer-events: none;
	border-color: var(--c-line);
	color: var(--c-ink-3);
	background-image: repeating-linear-gradient(45deg, var(--c-hatch) 0 1px, transparent 1px 6px);
}

/* --- D. Uczciwy stan wiedzy ---------------------------------------------- */

.ntb-honest { padding: 28px 30px; background: var(--c-paper); }
.ntb-honest__title { margin-top: var(--s-3); font-size: var(--fs-700); }
.ntb-honest__lead { margin-top: var(--s-3); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); max-width: var(--w-text); }
.ntb-honest__list { margin: 18px 0 0; padding: 0; display: grid; gap: 11px; font-size: var(--fs-300); }
.ntb-honest__list li { display: flex; align-items: flex-start; gap: 10px; line-height: var(--lh-body); }
.ntb-honest__list svg { flex: none; margin-top: 2px; color: var(--c-ink-2); }
/* Czego NIE wiemy, oznaczamy slabszym tierem - to nie jest fakt o produkcie. */
.ntb-honest__list li.is-missing { color: var(--c-ink-3); }
.ntb-honest__list li.is-missing svg { color: var(--c-line-2); }
.ntb-honest__acts { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: var(--s-5); }

/* --- F. Norma i obwod glowy ---------------------------------------------- */

/* Jedyne miejsce na karcie z odwroconym tlem: norma ma byc widoczna
   natychmiast, zanim klient zejdzie do rozmiarow. */
.ntb-cert { display: flex; align-items: center; gap: var(--s-3); margin-top: 10px; padding: 14px 16px; background: var(--c-ink); color: var(--c-on-ink); }
.ntb-cert svg { flex: none; width: 22px; height: 22px; color: currentColor; }
.ntb-cert__body { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ntb-cert__norm { font-size: var(--fs-300); font-weight: var(--fw-medium); }
.ntb-cert__note { font-size: var(--fs-200); line-height: var(--lh-label); color: var(--c-line-2); }

/* Kafelek rozmiaru kasku 108x58 z zakresem obwodu (par. 3, wariant R). */
.ntb-sizes--cert { gap: var(--s-2); margin-top: var(--s-3); }
.ntb-size--cert {
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 2px;
	min-width: var(--tile-r-w);
	min-height: var(--tile-r-h);
	padding-inline: 12px;
	line-height: var(--lh-tight);
}
.ntb-size__letter { font-size: var(--fs-400); }
.ntb-size__range { font-size: var(--fs-100); font-variant-numeric: tabular-nums; color: var(--c-ink-3); }
.ntb-size--cert[aria-pressed="true"] .ntb-size__range { color: var(--c-line-2); }
/* Zaszrafowane pole z projektu: rozmiar, ktorego producent nie robi. */
.ntb-size--cert[data-state="discontinued"] {
	border-color: var(--c-line);
	color: var(--c-ink-3);
	background-image: repeating-linear-gradient(45deg, var(--c-paper) 0 1px, transparent 1px 5px);
}
.ntb-size--cert[data-state="discontinued"] .ntb-size__range { color: var(--c-ink-3); }

/* ==========================================================================
   25. KOSZYK                                                     [ntb-koszyk]
   ==========================================================================
   Projekt "NTB24 Koszyk i zamowienie" sekcja 01. Dwie kolumny przez flex-wrap
   z bazami (par. 3): pozycje flex:3 1 440px, podsumowanie flex:1 1 300px
   z maksimum 400 px. Dostepnosc niesie wylacznie przynaleznosc do grupy
   i termin - nigdzie liczby sztuk (regula 1). */

.ntb-cart__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--s-4) var(--s-6);
	padding-bottom: var(--s-5);
	border-bottom: var(--bw-hair) solid var(--c-line);
}
.ntb-cart__h1 { font-size: var(--fs-900); line-height: var(--lh-tight); letter-spacing: -.015em; }
.ntb-cart__back {
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
	min-height: var(--touch);
	font-size: var(--fs-300);
	text-decoration: underline;
	text-underline-offset: 3px;
}
.ntb-cart__cols { display: flex; flex-wrap: wrap; gap: 44px; align-items: flex-start; margin-top: var(--s-2); }
.ntb-cart__items { flex: 3 1 440px; min-width: 0; }
.ntb-cart__aside { flex: 1 1 300px; max-width: 400px; min-width: 0; margin-top: var(--s-5); }
.ntb-cart__update { margin-top: var(--s-4); text-align: right; }

/* Czarny pasek nad pozycjami: prog darmowej dostawy i godzina nadania. */
.ntb-shipbar {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: var(--s-5) 0 0;
	padding: 14px 16px;
	background: var(--c-ink);
	color: var(--c-on-ink);
	font-size: var(--fs-300);
}
.ntb-shipbar svg { flex: none; width: 17px; height: 17px; }

/* Naglowek grupy: "Dostepne od razu" albo "Na zamowienie". */
.ntb-cartgroup {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--s-2) var(--s-4);
	margin-top: 28px;
	padding-bottom: var(--s-3);
	border-bottom: var(--bw-hair) solid var(--c-ink);
}
.ntb-cartgroup:not(:first-child) { margin-top: 36px; }
.ntb-cartgroup__t {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	font-size: var(--fs-200);
	font-weight: var(--fw-semibold);
	letter-spacing: .14em;
	text-transform: uppercase;
}
.ntb-cartgroup__t svg { flex: none; width: 15px; height: 15px; }
.ntb-cartgroup__s { font-size: var(--fs-300); color: var(--c-ink-3); }

/* --- Wiersz pozycji ------------------------------------------------------- */

.ntb-cartrow { display: flex; gap: 22px; padding: 22px 0; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-cartrow__media {
	position: relative;
	flex: none;
	width: 112px;
	height: 140px;
	border: var(--bw-hair) solid var(--c-line);
	overflow: hidden;
}
.ntb-cartrow__media img,
.ntb-cartrow__media .ntb-ph { width: 100%; height: 100%; object-fit: cover; }
/* Kadr ma stala wysokosc, wiec placeholder nie moze narzucac proporcji. */
.ntb-cartrow__media .ntb-ph--product { aspect-ratio: auto; border: 0; }

/* Podpis placeholdera w malych kadrach (112x140 w koszyku, 64x80
   w odlozonych, 52x64 w podsumowaniu zamowienia) nie ma sie gdzie zmiescic:
   ntb24_placeholder() wypisuje pelna nazwe produktu, ktora przy 11 px
   z odstepem .18em i marginesem 24 px lamie sie na osiem wierszy i wypelnia
   caly kadr (zmierzone: nazwa podkladki Piuma zajmowala 138 z 140 px).
   Projekt (par. 3) przewiduje w kadrze szraf, ikone i JEDNOLINIJKOWY podpis,
   wiec w kadrach ponizej 160 px zostaje sam szraf. Ramka i tlo bez zmian. */
.ntb-cartrow__media .ntb-ph__body,
.ntb-cartsaved__media .ntb-ph__body,
.ntb-oreview__media .ntb-ph__body { display: none; }

.ntb-cartrow__body { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6); }
.ntb-cartrow__main { flex: 1 1 260px; min-width: 0; }

.ntb-cartrow__brand { font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-cartrow__name { display: block; margin-top: 5px; font-size: var(--fs-500); line-height: var(--lh-label); }
.ntb-cartrow__dl { display: grid; grid-template-columns: auto 1fr; gap: 5px 14px; margin: 10px 0 0; font-size: var(--fs-300); }
.ntb-cartrow__dl dt { color: var(--c-ink-3); }
.ntb-cartrow__dl dd { margin: 0; font-variant-numeric: tabular-nums; }
.ntb-cartrow__change { margin-left: var(--s-2); color: var(--c-ink-2); text-decoration: underline; text-underline-offset: 3px; }
.ntb-cartrow__change:hover { color: var(--c-ink); }

/* Notatka kalkulatora rozmiaru. Wypelni ja ntb24-sizing przez filtr
   ntb24_cart_item_sizing_note; bez wtyczki blok sie nie renderuje. */
.ntb-cartrow__note {
	display: flex;
	align-items: center;
	gap: 9px;
	margin-top: var(--s-3);
	padding: 9px 12px;
	background: var(--c-paper);
	font-size: var(--fs-200);
	color: var(--c-ink-2);
}
.ntb-cartrow__note svg { flex: none; width: 15px; height: 15px; }

.ntb-cartrow__side { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 14px; min-width: 150px; }
.ntb-cartrow__price { font-size: var(--fs-600); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.ntb-cartrow__acts { display: flex; gap: 18px; font-size: var(--fs-300); }

/* Przycisk formularza wygladajacy jak odnosnik: "Zapisz", "Usun",
   "Podziel na dwie paczki". Caly koszyk to jeden formularz, wiec kontrolek
   bez ramki jest tu duzo. */
.ntb-linkbtn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 0;
	border: 0;
	background: none;
	font-family: var(--f-ui);
	font-size: var(--fs-300);
	line-height: var(--lh-label);
	color: var(--c-ink-2);
	cursor: pointer;
	text-decoration: underline;
	text-underline-offset: 3px;
}
.ntb-linkbtn:hover { color: var(--c-ink); }
.ntb-linkbtn svg { flex: none; width: 14px; height: 14px; }

/* Stepper koszyka: 44 px wg par. 3, pole liczbowe w srodku ramki. */
.ntb-qty--cart { height: var(--h-step); }
.ntb-qty__field { display: flex; align-items: center; height: 100%; }
.ntb-qty__field input { min-width: 34px; }

/* --- Arkusz zmiany rozmiaru ---------------------------------------------- */

/* Na desktopie panel w wierszu pozycji, na 390 px arkusz od dolu (sekcja 29). */
.ntb-sheet { margin-top: 14px; padding: 16px 18px; border: var(--bw-hair) solid var(--c-ink); background: var(--c-bg); }
.ntb-sheet__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.ntb-sheet__t { font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .14em; text-transform: uppercase; }
.ntb-sheet__close { display: grid; place-items: center; width: var(--touch); height: var(--touch); margin-right: -10px; color: var(--c-ink-2); }
.ntb-sheet__close:hover { color: var(--c-ink); }
.ntb-sheet__lead { margin: var(--s-2) 0 14px; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-sheet__opts { display: grid; gap: var(--s-2); }
.ntb-sheet__opt {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: var(--touch);
	padding: 0 14px;
	border: var(--bw-hair) solid var(--c-line-2);
	cursor: pointer;
}
.ntb-sheet__opt:hover { border-color: var(--c-ink); }
.ntb-sheet__opt[data-state="backorder"],
.ntb-sheet__opt[data-state="soon"] { border-style: dotted; }
/* Stan niesie cala etykieta, wiec samo pole wyboru schodzi z oczu.
   Markup variant-sheet.php nie daje mu klasy .ntb-sr, a bez tej reguly
   przegladarka rysuje natywny przycisk radiowy w barwie systemowej -
   na zrzucie wychodzil niebieski krazek posrod czerni i bieli, czyli
   kolor spoza palety (regula 5, D07), ktorego qa_paleta.rb nie zlapie,
   bo nie pada w naszych zrodlach. Chowamy przez wyciecie, nie przez
   display: none, zeby pole zostalo w kolejnosci tabulacji. */
.ntb-sheet__opt input[type="radio"] {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
}
/* Pierscien skupienia przechodzi na etykiete, bo ognisko siedzi
   na wycietym polu i nie mialoby czego obrysowac. */
.ntb-sheet__opt:has(input:focus-visible) { outline: var(--bw-heavy) solid var(--c-ink); outline-offset: 2px; }
.ntb-sheet__opt:has(input:checked) { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-sheet__label { font-size: var(--fs-400); }
.ntb-sheet__s { margin-left: auto; font-size: var(--fs-100); color: var(--c-ink-3); }
.ntb-sheet__opt:has(input:checked) .ntb-sheet__s { color: var(--c-line-2); }
.ntb-sheet .ntb-btn { margin-top: var(--s-3); }

/* --- Zapisane na pozniej -------------------------------------------------- */

.ntb-cartsaved { margin-top: 40px; }
.ntb-cartsaved__head {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--s-3);
	padding-bottom: var(--s-3);
	border-bottom: var(--bw-hair) solid var(--c-line);
}
.ntb-cartsaved__t { font-size: var(--fs-700); margin: 0; }
.ntb-cartsaved__s { font-size: var(--fs-200); color: var(--c-ink-3); }
/* Stala liczba kolumn na kazdym progu (D12), nigdy auto-fit. */
.ntb-cartsaved__list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-5); margin: var(--s-5) 0 0; padding: 0; }
.ntb-cartsaved__item { display: flex; align-items: flex-start; gap: 14px; }
.ntb-cartsaved__media { flex: none; width: 64px; height: 80px; border: var(--bw-hair) solid var(--c-line); overflow: hidden; }
.ntb-cartsaved__media img, .ntb-cartsaved__media .ntb-ph { width: 100%; height: 100%; object-fit: cover; }
.ntb-cartsaved__media .ntb-ph--product { aspect-ratio: auto; border: 0; }
.ntb-cartsaved__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--s-1); font-size: var(--fs-200); }
.ntb-cartsaved__name { font-size: var(--fs-300); line-height: var(--lh-label); }
.ntb-cartsaved__acts { display: flex; flex-wrap: wrap; gap: 14px; margin-top: var(--s-1); }

/* --- Podsumowanie --------------------------------------------------------- */

.ntb-sum { border: var(--bw-hair) solid var(--c-ink); padding: var(--s-5) 26px; }
.ntb-sum__t { margin: 0; font-family: var(--f-ui); font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .14em; text-transform: uppercase; }
.ntb-sum__dl { display: grid; grid-template-columns: 1fr auto; gap: var(--s-3) var(--s-4); margin: 18px 0 0; font-size: var(--fs-400); }
.ntb-sum__dl dt { color: var(--c-ink-2); }
.ntb-sum__dl dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.ntb-sum__total { padding-top: 14px; border-top: var(--bw-hair) solid var(--c-ink); }
dt.ntb-sum__total { font-size: var(--fs-500); font-weight: var(--fw-semibold); color: var(--c-ink); }
dd.ntb-sum__total { font-size: var(--fs-700); font-weight: var(--fw-semibold); }
.ntb-sum__muted { color: var(--c-ink-3); }
/* Woo dokleja do sumy dopisek "(zawiera X VAT)" w <small class="includes_tax">.
   Ta sama informacja stoi wierszem nizej w .ntb-sum__vat, a dopisek rozpychal
   kolumne kwot tak, ze etykieta "Produkty, 3 pozycje" lamala sie na trzy
   wiersze. Zostaje jedna, nasza forma. */
.ntb-sum__dl .includes_tax,
.ntb-sum__dl .woocommerce-Price-taxLabel,
.ntb-oreview__dl .includes_tax,
.ntb-oreview__dl .woocommerce-Price-taxLabel { display: none; }

.ntb-sum__vat { margin: 10px 0 0; font-size: var(--fs-200); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-sum__note {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 18px;
	padding: 11px 12px;
	background: var(--c-paper);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink-2);
}
.ntb-sum__note svg { flex: none; width: 16px; height: 16px; }
.ntb-sum__cta { min-height: 54px; margin-top: 18px; gap: 10px; }
.ntb-sum__coupon { display: flex; align-items: center; gap: 10px; margin-top: var(--s-4); }
.ntb-sum__coupon .ntb-field { flex: 1; min-width: 0; height: var(--touch); }
.ntb-sum__coupon .ntb-field input { font-size: var(--fs-300); padding-inline: 12px; }
.ntb-sum__coupon .ntb-btn { flex: none; min-height: var(--touch); padding-inline: 16px; font-size: var(--fs-300); letter-spacing: .06em; }

/* Trzy wiersze zaufania pod podsumowaniem. */
.ntb-trustrows { display: grid; gap: var(--s-3); margin: 18px 0 0; padding: 0; font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-trustrows li { display: flex; align-items: center; gap: 10px; }
.ntb-trustrows svg { flex: none; width: 16px; height: 16px; color: var(--c-ink-3); }

/* Pierwszy akapit pustego koszyka; reszta stanu z .ntb-empty (sekcja 18). */
.ntb-empty__lead { font-size: var(--fs-500); line-height: var(--lh-body); margin: 0 0 var(--s-2); }

/* ==========================================================================
   26. ZAMOWIENIE I POTWIERDZENIE                                    [ntb-kasa]
   ==========================================================================
   Jeden ekran, trzy numerowane sekcje, podsumowanie w kolumnie bocznej.
   Dwie paczki to dwie daty - nigdy stan magazynu (regula 1). */

.ntb-checkout__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--s-4) var(--s-6);
	padding-bottom: var(--s-5);
	border-bottom: var(--bw-hair) solid var(--c-line);
}
.ntb-checkout__h1 { font-size: var(--fs-900); line-height: var(--lh-tight); letter-spacing: -.015em; }
.ntb-checkout__note { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-checkout__note svg { flex: none; width: 15px; height: 15px; }
.ntb-checkout__cols { display: flex; flex-wrap: wrap; gap: 44px; align-items: flex-start; margin-top: 28px; }
.ntb-checkout__main { flex: 3 1 440px; min-width: 0; display: grid; gap: 40px; }
.ntb-checkout__aside { flex: 1 1 300px; max-width: 400px; min-width: 0; }

/* --- Trzy kroki ----------------------------------------------------------- */

.ntb-step__head { display: flex; align-items: baseline; gap: 14px; padding-bottom: 14px; border-bottom: var(--bw-hair) solid var(--c-ink); }
.ntb-step__nr {
	flex: none;
	width: 28px;
	height: 28px;
	display: grid;
	place-items: center;
	background: var(--c-ink);
	color: var(--c-on-ink);
	font-size: var(--fs-200);
	font-weight: var(--fw-semibold);
	font-variant-numeric: tabular-nums;
}
.ntb-step__t { margin: 0; }
.ntb-step__aside { margin-left: auto; font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-step__aside a { text-decoration: underline; text-underline-offset: 3px; }
.ntb-step--zgody { display: grid; gap: 6px; }

/* --- Pola formularza Woo --------------------------------------------------
   Markup pol rysuje woocommerce_form_field(), wiec ubieramy jego klasy.
   Stala liczba kolumn na kazdym progu (D12). */
.ntb-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; margin-top: var(--s-5); }
.ntb-fields .form-row { display: grid; gap: 6px; margin: 0; padding: 0; }
.ntb-fields .form-row-wide,
.ntb-fields--uwagi .form-row { grid-column: 1 / -1; }
.ntb-fields label { font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .06em; color: var(--c-ink); }
.ntb-fields .woocommerce-input-wrapper { display: block; }
.ntb-fields input,
.ntb-fields select,
.ntb-fields textarea {
	width: 100%;
	min-height: var(--h-field);
	padding: 0 12px;
	border: var(--bw-hair) solid var(--c-control);
	border-radius: var(--r-0);
	background: var(--c-bg);
	font: inherit;
	font-size: var(--fs-400);
	color: var(--c-ink);
}
.ntb-fields textarea { padding: 12px; min-height: 96px; line-height: var(--lh-body); }
.ntb-fields input:focus-visible,
.ntb-fields select:focus-visible,
.ntb-fields textarea:focus-visible { border-color: var(--c-ink); }
/* Gwiazdka pola wymaganego bez koloru funkcyjnego (D07). */
.ntb-fields .required { color: var(--c-ink); text-decoration: none; border: 0; }

/* Kraj i wojewodztwo sa ustalone (PL), wiec pola nie ma na ekranie -
   zostaje w formularzu, zeby Woo dostalo wartosc. Selektor musi byc
   mocniejszy niz `.ntb-fields .form-row`, ktore ustawia display: grid. */
.ntb-fields .form-row.ntb-hidden-field,
.ntb-hidden-field { display: none; }

/* Faktura na firme: pola odslania samo zaznaczenie, bez JavaScriptu. */
.ntb-fields--firma { display: none; }
.ntb-step:has(.ntb-check--faktura input:checked) .ntb-fields--firma { display: grid; }

/* --- Wybor dostawy -------------------------------------------------------- */

.ntb-ship { display: grid; gap: var(--s-2); margin-top: var(--s-5); }
.ntb-ship__opt {
	display: flex;
	align-items: center;
	gap: 14px;
	min-height: 64px;
	padding: 12px 16px;
	border: var(--bw-hair) solid var(--c-line-2);
	cursor: pointer;
}
.ntb-ship__opt:hover { border-color: var(--c-ink); }
.ntb-ship__opt:has(input:checked) { border-color: var(--c-ink); }
/* Radio 20 px z kropka 10 px (par. 3). */
.ntb-ship__opt input[type="radio"] {
	flex: none;
	width: var(--box-form);
	height: var(--box-form);
	margin: 0;
	display: grid;
	place-items: center;
	appearance: none;
	-webkit-appearance: none;
	border: var(--bw-hair) solid var(--c-line-2);
	border-radius: var(--r-round);
	background: var(--c-bg);
}
.ntb-ship__opt input[type="radio"]:checked { border-color: var(--c-ink); }
.ntb-ship__opt input[type="radio"]:checked::before {
	content: "";
	width: 10px;
	height: 10px;
	border-radius: var(--r-round);
	background: var(--c-ink);
}
.ntb-ship__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ntb-ship__name { font-size: var(--fs-400); font-weight: var(--fw-medium); }
.ntb-ship__when { font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-ship__price { flex: none; font-size: var(--fs-400); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
/* Logo przewoznika z wtyczki InPost: w wierszu, nie pod nim. Bez tej reguly
   obrazek szedl w naturalnej wielkosci (100 px zoltego prostokata) i rozpychal
   kafel 64 px. 24 px to wysokosc tekstu nazwy, wiec logo siada w linii. */
.ntb-ship__logo { flex: none; display: inline-flex; align-items: center; }
.ntb-ship__logo img { display: block; width: auto; height: 24px; }
.ntb-ship__dodatek { margin: -4px 0 4px; padding-left: calc( var(--box-form) + 14px + 16px ); }
.ntb-ship__dodatek img { max-width: 100%; height: auto; }
.ntb-ship__punkt { margin-top: 14px; padding: 14px 16px; border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); }
.ntb-ship__punkt.is-hidden { display: none; }
.ntb-ship__punkt label { display: grid; gap: 8px; max-width: 320px; }
.ntb-ship__punkt input { text-transform: uppercase; }
.ntb-paczkomat { margin: 12px 0 0; font-size: var(--fs-300); }
.ntb-ship__note {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 10px;
	padding: 14px 16px;
	background: var(--c-paper);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink-2);
}
.ntb-ship__note svg { flex: none; width: 17px; height: 17px; color: var(--c-ink-2); }

/* --- Platnosc ------------------------------------------------------------- */

/* Cztery kafle w rzedzie, stala liczba kolumn (D12). Pozycja listy ma
   display: contents, zeby kafel i pole rozwijane byly osobnymi polami siatki. */
.ntb-pay__list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-2); margin: var(--s-5) 0 0; padding: 0; }
.ntb-pay__item { display: contents; }
.ntb-pay__item > input[type="radio"] {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
}
.ntb-pay__tile {
	min-height: 56px;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--s-2);
	padding: 8px 12px;
	border: var(--bw-hair) solid var(--c-line-2);
	font-size: var(--fs-400);
	text-align: center;
	cursor: pointer;
}
.ntb-pay__tile:hover { border-color: var(--c-ink); }
.ntb-pay__item > input[type="radio"]:checked + .ntb-pay__tile { background: var(--c-ink); border-color: var(--c-ink); color: var(--c-on-ink); }
.ntb-pay__icon { display: flex; align-items: center; }
/* Pole rozwijane wybranej bramki stoi POD rzedem kafli, nie miedzy nimi.
   Pozycja listy ma display: contents, wiec kafel i pole sa osobnymi polami
   siatki i bez `order` pole na pelna szerokosc rozbijalo rzad na dwa. */
.ntb-pay__tile { order: 0; }
.ntb-pay__box { order: 1; grid-column: 1 / -1; padding: 14px 16px; background: var(--c-paper); font-size: var(--fs-300); line-height: var(--lh-body); }
.ntb-pay__box p { margin: 0; }
.ntb-pay__free,
.ntb-pay__noscript { margin-top: var(--s-3); font-size: var(--fs-300); color: var(--c-ink-3); }

/* --- Zgody ---------------------------------------------------------------- */

.ntb-consents { display: grid; gap: 6px; }
/* Zdanie o przetwarzaniu danych wypisuje WooCommerce jako zwykly akapit,
   wiec bez tego czyta sie stopniem tresci ciaglej (16 px) i przykrywa zgody. */
.ntb-consents .woocommerce-privacy-policy-text p { margin: 0 0 var(--s-2); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-consents .woocommerce-privacy-policy-text a { text-decoration: underline; text-underline-offset: 3px; }
/* Formularzowy wariant pola wyboru: etykieta jest cala kontrolka, kwadrat
   ma 20 px (par. 3). Selektor z elementem, bo .ntb-check bez etykiety jest
   w sekcji 5 samym kwadratem. */
label.ntb-check {
	display: flex;
	align-items: flex-start;
	gap: var(--s-3);
	width: auto;
	height: auto;
	min-height: var(--touch);
	border: 0;
	background: none;
	cursor: pointer;
}
.ntb-check__input {
	flex: none;
	width: var(--box-form);
	height: var(--box-form);
	margin-top: 1px;
	display: grid;
	place-items: center;
	appearance: none;
	-webkit-appearance: none;
	/* --c-control, nie --c-line-2: pole niezaznaczone nie ma innego oznaczenia
	   niz ramka, a ta na bieli dawala 1,73:1 przy progu 3:1 dla elementow
	   interfejsu (audyt dostepnosci 23.09). Dotyczy tez zgody na regulamin. */
	border: var(--bw-hair) solid var(--c-control);
	border-radius: var(--r-0);
	background: var(--c-bg);
}
.ntb-check__input:checked { background: var(--c-ink); border-color: var(--c-ink); }
.ntb-check__input:checked::after {
	content: "";
	width: 13px;
	height: 13px;
	background: var(--c-on-ink);
	-webkit-mask: var(--i-check) center / 13px 13px no-repeat;
	mask: var(--i-check) center / 13px 13px no-repeat;
}
/* iOS przybliza strone po tapnieciu w pole mniejsze niz 16 px, a viewport
   celowo nie blokuje powiekszania. Na telefonie pola wpisywane dostaja wiec
   pelne 16 px (audyt mobile 23.09). */
@media (max-width: 767px) {
	.ntb-field input,
	.ntb-field textarea,
	.ntb-field select,
	.ntb-search input,
	.ntb-qty input,
	/* Audyt 1.10.2026: ponizsze pola wypadly z tej listy, a to CALY formularz
	   kasy (imie, e-mail, telefon, ulica, kod, NIP, haslo), pole kuponu, pola
	   ceny w filtrach i szukajka w grupie filtrow. Przy .ntb-sum__coupon
	   konieczny pelny selektor: krotszy przegrywa moca z regula sekcji kasy. */
	.ntb-fields input,
	.ntb-fields select,
	.ntb-fields textarea,
	.ntb-sum__coupon .ntb-field input,
	.ntb-fprice__fields input,
	.ntb-fgroup__search input { font-size: 16px; }
}

.ntb-check__label { font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-check__label a { text-decoration: underline; text-underline-offset: 3px; }
.ntb-check--faktura { margin-top: var(--s-4); min-height: 48px; }
.ntb-check--faktura .ntb-check__label { font-size: var(--fs-300); color: var(--c-ink); }

/* --- Podsumowanie zamowienia w kolumnie bocznej --------------------------- */

.ntb-oreview { border: var(--bw-hair) solid var(--c-ink); background: var(--c-bg); }
.ntb-oreview__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: 18px 22px; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-oreview__t { margin: 0; font-family: var(--f-ui); font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .14em; text-transform: uppercase; }
.ntb-oreview__edit { font-size: var(--fs-300); text-decoration: underline; text-underline-offset: 3px; }

.ntb-oreview__items { margin: 0; padding: 6px 22px; }
.ntb-oreview__item { display: flex; gap: 14px; padding: 14px 0; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-oreview__item:last-child { border-bottom: 0; }
.ntb-oreview__media { position: relative; flex: none; width: 52px; height: 64px; border: var(--bw-hair) solid var(--c-line); overflow: hidden; }
.ntb-oreview__media img, .ntb-oreview__media .ntb-ph { width: 100%; height: 100%; object-fit: cover; }
.ntb-oreview__media .ntb-ph--product { aspect-ratio: auto; border: 0; }
.ntb-oreview__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ntb-oreview__name { font-size: var(--fs-300); line-height: var(--lh-label); }
.ntb-oreview__meta { font-size: var(--fs-200); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-oreview__when { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-200); color: var(--c-ink-2); }
.ntb-oreview__when svg { flex: none; width: 13px; height: 13px; }
.ntb-oreview__price { flex: none; font-size: var(--fs-400); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }

.ntb-oreview__dl { display: grid; grid-template-columns: 1fr auto; gap: 10px var(--s-4); margin: 0; padding: 18px 22px; border-top: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); }
.ntb-oreview__dl dt { color: var(--c-ink-2); }
.ntb-oreview__dl dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.ntb-oreview__total { padding-top: var(--s-3); border-top: var(--bw-hair) solid var(--c-ink); }
dt.ntb-oreview__total { font-size: var(--fs-500); font-weight: var(--fw-semibold); color: var(--c-ink); }
dd.ntb-oreview__total { font-size: var(--fs-700); font-weight: var(--fw-semibold); }
.ntb-oreview__vat { margin: 0; padding: 0 22px; font-size: var(--fs-200); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-oreview__submit { padding: 0 22px 22px; }
.ntb-oreview__submit .ntb-btn { margin-top: 18px; min-height: 56px; font-size: var(--fs-300); letter-spacing: .09em; }
.ntb-oreview__hint { margin: var(--s-3) 0 0; font-size: var(--fs-200); line-height: var(--lh-body); color: var(--c-ink-3); text-align: center; }

/* --- Potwierdzenie -------------------------------------------------------- */

.ntb-thanks { max-width: 960px; margin: 36px auto 0; }
.ntb-thanks__head { display: flex; align-items: flex-start; gap: var(--s-5); padding-bottom: 28px; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-thanks__mark { flex: none; width: 52px; height: 52px; display: grid; place-items: center; background: var(--c-ink); color: var(--c-on-ink); }
.ntb-thanks__h1 { margin: 0; font-size: var(--fs-900); line-height: var(--lh-tight); letter-spacing: -.015em; }
.ntb-thanks__lead { margin: var(--s-3) 0 0; font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-thanks__lead b { font-variant-numeric: tabular-nums; }
.ntb-thanks__mail { word-break: break-word; }
.ntb-thanks__failed { margin-bottom: var(--s-5); }

/* DWIE PACZKI JAKO DWIE DATY. Stala liczba kolumn, nigdy auto-fit (D12):
   przy jednej paczce pusta komorka odslonilaby tlo siatki. */
.ntb-parcels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px; margin-top: 28px; background: var(--c-line); }
/* Zamowienie bez pozycji na zamowienie ma JEDNA paczke, a dwie stale kolumny
   zostawialy wtedy pusta komorke - czyli polowe pasa w barwie linii
   (zmierzone: kafel 567 z 1136 px, reszta gola #E4E1DB). To dokladnie ta
   pulapka, ktora opisuje D12; auto-fit jej nie rozwiazuje, bo ma ten sam
   skutek przy zmiennej liczbie dzieci. Jawna liczba kolumn dla jednego
   dziecka zostawia zakaz auto-fit nienaruszony. */
.ntb-parcels:has(> .ntb-parcel:only-child) { grid-template-columns: minmax(0, 1fr); }
.ntb-parcel { padding: var(--s-5) 26px; background: var(--c-bg); }
.ntb-parcel[data-state="available"] { background: var(--c-paper); }
.ntb-parcel__label { display: flex; align-items: center; gap: 10px; font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-parcel__label svg { flex: none; width: 16px; height: 16px; color: var(--c-ink-2); }
.ntb-parcel__date { display: block; margin-top: var(--s-3); font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-800); line-height: var(--lh-tight); }
.ntb-parcel__text { margin: var(--s-2) 0 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-parcel__list { display: grid; gap: var(--s-2); margin: var(--s-4) 0 0; padding: 0; font-size: var(--fs-300); }
.ntb-parcel__list li { display: flex; justify-content: space-between; gap: var(--s-3); }
.ntb-parcel__variant { color: var(--c-ink-3); font-variant-numeric: tabular-nums; }

.ntb-savehorse {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--s-4) var(--s-6);
	margin-top: 28px;
	padding: 22px 26px;
	border: var(--bw-hair) solid var(--c-ink);
}
.ntb-savehorse__body { display: flex; align-items: flex-start; gap: 14px; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); }
.ntb-savehorse__body svg { flex: none; width: 20px; height: 20px; margin-top: 2px; }
.ntb-savehorse__body p { margin: 0; }
.ntb-savehorse .ntb-btn { flex: none; min-height: 48px; padding-inline: 20px; font-size: var(--fs-300); }

/* Cztery fakty w rzedzie, stala liczba kolumn (D12). */
.ntb-thanks__facts {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--s-5) var(--s-6);
	margin-top: 36px;
	padding-top: 28px;
	border-top: var(--bw-hair) solid var(--c-line);
	font-size: var(--fs-300);
}
.ntb-thanks__facts p { margin: var(--s-2) 0 0; line-height: var(--lh-body); }
.ntb-thanks__acts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); margin-top: var(--s-6); }
.ntb-thanks__acts .ntb-btn { min-height: 48px; padding-inline: 20px; font-size: var(--fs-300); }

@media (min-width: 1024px) {
	/* Podsumowanie jedzie z klientem przez caly formularz. */
	.ntb-checkout__aside { position: sticky; top: var(--s-5); }
}

/* ==========================================================================
   27. MARKUP WOOCOMMERCE, KTOREGO NIE PISZEMY SAMI            [ntb-woo-obce]
   ==========================================================================
   Komunikaty, cross-sells i pole select2 renderuje WooCommerce swoim kodem
   i nie da sie ich nadpisac szablonem. Ubieramy je w palete: bez kolorow
   funkcyjnych (D07) - blad to ramka 1 px czerni z ikona, informacja
   i potwierdzenie to panel z hairline. Selektory sa podwojone lancuchem
   `.woocommerce`, bo arkusz Woo opisuje je z ta sama moca co my. */

/* --- Widoki sklepowe w szablonie strony -----------------------------------
   Koszyk, kasa i potwierdzenie wchodza do WordPressa jako strony z kodem
   skroconym, wiec page.php owija je w kolumne tekstowa .ntb-page__body.ntb-prose
   i poprzedza je tytulowym paskiem .ntb-cathead. Kazdy z tych trzech widokow
   ma wlasny uklad dwukolumnowy, wiec kolumna tekstowa go dusila.

   Szesc regul z `max-width: none !important` stalo tu wczesniej po to, zeby
   przebic inline `max-width: 760px` z szablonu. Inline'u juz nie ma, a miara
   prozy siedzi na DZIECIACH kontenera (sekcja 31), wiec koszyk, kasa
   i potwierdzenie dostaja pelna kolumne bez zadnego wyjatku. */

/* Margines strony niesie juz sekcja nadrzedna, wiec .ntb-wrap na widoku
   sklepowym dodawalby go drugi raz. */
.ntb-page__body .ntb-cart,
.ntb-page__body .ntb-checkout,
.ntb-page__body .ntb-thanks { padding-inline: 0; }

/* Tytulowy pasek kategorii nie nalezy do projektu tych trzech widokow -
   tytul niesie ich wlasny naglowek razem z powrotem do zakupow. */
#ntb-content:has(.ntb-cart) > .ntb-wrap > .ntb-cathead,
#ntb-content:has(.ntb-checkout) > .ntb-wrap > .ntb-cathead,
#ntb-content:has(.ntb-thanks) > .ntb-wrap > .ntb-cathead { display: none; }

/* --- Sekcja platnosci ----------------------------------------------------
   Woo maluje #payment na fiolet (tlo bloku, kreska pod lista metod, tlo pola
   rozwijanego i trojkat nad nim) - cztery wartosci spoza palety, opisane
   lancuchem z identyfikatorem, wiec nasze klasy same nie wystarcza. */
.woocommerce-cart #payment.ntb-pay,
.woocommerce-checkout #payment.ntb-pay { background: transparent; border-radius: var(--r-0); }
.woocommerce-cart #payment ul.payment_methods.ntb-pay__list,
.woocommerce-checkout #payment ul.payment_methods.ntb-pay__list { padding: 0; border-bottom: 0; margin: var(--s-5) 0 0; }
/* Woo czysci floaty pseudoelementami; w siatce sa to dwa pelnoprawne pola. */
.woocommerce-cart #payment ul.payment_methods.ntb-pay__list::before,
.woocommerce-cart #payment ul.payment_methods.ntb-pay__list::after,
.woocommerce-checkout #payment ul.payment_methods.ntb-pay__list::before,
.woocommerce-checkout #payment ul.payment_methods.ntb-pay__list::after { content: none; display: none; }
.woocommerce-cart #payment ul.payment_methods li input,
.woocommerce-checkout #payment ul.payment_methods li input { margin: 0; }
/* Woo czysci floaty takze na KAZDEJ pozycji listy. Pozycja ma u nas
   display: contents, wiec jej pseudoelementy wskakuja do siatki jako
   pelnoprawne pola i przesuwaja kazdy kafel o kolumne w prawo - zmierzone:
   pierwszy kafel siadal w kolumnie drugiej. */
.woocommerce-cart #payment ul.payment_methods li.ntb-pay__item::before,
.woocommerce-cart #payment ul.payment_methods li.ntb-pay__item::after,
.woocommerce-checkout #payment ul.payment_methods li.ntb-pay__item::before,
.woocommerce-checkout #payment ul.payment_methods li.ntb-pay__item::after { content: none; display: none; }
.woocommerce-cart #payment div.payment_box.ntb-pay__box,
.woocommerce-checkout #payment div.payment_box.ntb-pay__box {
	margin: 0;
	padding: 14px 16px;
	border-radius: var(--r-0);
	background: var(--c-paper);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink);
}
.woocommerce-cart #payment div.payment_box.ntb-pay__box::before,
.woocommerce-checkout #payment div.payment_box.ntb-pay__box::before { content: none; display: none; }

/* --- Reset motywu nadrzednego maluje KAZDA tabele ------------------------
   hello-elementor/assets/css/reset.css daje `table td, table th` ramke 1 px
   w polprzezroczystej szarosci, pasy na `tbody > tr:nth-child(odd)` i jeszcze
   jedno podswietlenie wiersza pod myszka. Trzy wartosci spoza palety
   (regula 5), zapisane u nadrzednego w ukladzie hsl - widoczne na rozmiarowce
   i na matrycy jako siatka szarych kratek zamiast wloskowatych linii.
   qa_paleta.rb ich nie zlapie, bo nie padaja w naszych zrodlach - widac je
   dopiero na zrzucie z przegladarki.
   Powtarzamy moc selektorow resetu i wracamy do systemu. */
table td,
table th { border-color: var(--c-line); }
table tbody > tr:nth-child(odd) > td,
table tbody > tr:nth-child(odd) > th,
table tbody tr:hover > td,
table tbody tr:hover > th { background-color: transparent; }
/* Nasze tabele rysuja linie tylko tam, gdzie ma je projekt: pod wierszem.
   Zerujemy gore i boki, dolu nie ruszamy - niesie go komponent. */
.ntb-table th, .ntb-table td,
.ntb-matrix__table th, .ntb-matrix__table td { border-top: 0; border-inline: 0; }
/* Reset daje komorkom 15 px z kazdej strony; pierwsza kolumna ma stac
   w linii tresci, jak dt w liscie definicji. */
.ntb-table th, .ntb-table td { padding-inline: 0 var(--s-4); }

/* Pierscien skupienia z resetu jest w czystej czerni, ktorej w palecie nie ma
   (nasza czern jest o kilka procent jasniejsza), a jego selektory sa
   mocniejsze niz nasze :focus-visible z sekcji 3. Podmieniamy sama barwe. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible { outline-color: var(--c-ink); }

.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews,
.woocommerce .woocommerce-message,
.woocommerce .woocommerce-info,
.woocommerce .woocommerce-error {
	display: block;
	margin: 0 0 var(--s-4);
	padding: 14px 16px;
	border: var(--bw-hair) solid var(--c-line);
	border-radius: var(--r-0);
	background: var(--c-paper);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink);
	list-style: none;
}
.woocommerce-error,
.woocommerce .woocommerce-error { border-color: var(--c-ink); background: var(--c-bg); }
/* Woo wstawia przed komunikatem znak ze swojego kroju ikon. Gasimy go
   i dajemy wlasna ikone maska, dokladnie jak w .ntb-notice (sekcja 5). */
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before,
.woocommerce .woocommerce-message::before,
.woocommerce .woocommerce-info::before,
.woocommerce .woocommerce-error::before { content: none; }
/* Ikona ostrzezenia stoi w lewym gornym rogu ramki, a tekst dostaje na nia
   miejsce paddingiem. Wczesniej byla plywajaca (float: left), ale Woo wypisuje
   komunikat jako <ul><li>, a li jest wlasnym blokiem listy - jego wiersze nie
   omijaly plywaka i pierwsza litera lezala pod ikona. Widac to bylo dopiero
   od chwili, gdy karta produktu w ogole zaczela pokazywac komunikaty. */
.woocommerce-error,
.woocommerce .woocommerce-error { position: relative; padding-left: 42px; }
.woocommerce-error::before,
.woocommerce .woocommerce-error::before {
	content: "";
	position: absolute;
	top: 17px;
	left: 16px;
	width: 16px;
	height: 16px;
	background: var(--c-ink);
	-webkit-mask: var(--i-alert) center / 16px 16px no-repeat;
	mask: var(--i-alert) center / 16px 16px no-repeat;
}
.woocommerce-error li { list-style: none; }
.woocommerce-NoticeGroup { display: block; }
/* Przycisk w komunikacie ("Zobacz koszyk") wraca do systemu. */
.woocommerce-message .button,
.woocommerce .woocommerce-message .button { float: right; margin-left: var(--s-4); }

/* Gwiazdka pola wymaganego: bez koloru funkcyjnego (D07). Woo opisuje ja
   lancuchem `.woocommerce form .form-row .required`, wiec sama klasa
   przegrywa i gwiazdka zostawala czerwona na kazdym formularzu Woo. */
.required,
.woocommerce .required,
.woocommerce form .form-row .required,
.woocommerce form .form-row abbr.required { color: var(--c-ink); text-decoration: none; border: 0; }

/* Przyciski, ktore rysuje sam WooCommerce (komunikaty, weryfikacja adresu,
   formularze konta) niosa klase .button i barwy spoza palety. Ubieramy je
   w przycisk drugorzedny: biale tlo, ramka 1 px czerni, inwersja pod myszka. */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce-page a.button,
.woocommerce-page button.button,
.woocommerce-page input.button,
.woocommerce #respond input#submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--touch);
	padding: 0 18px;
	border: var(--bw-hair) solid var(--c-ink);
	border-radius: var(--r-0);
	background: var(--c-bg);
	color: var(--c-ink);
	font-family: var(--f-ui);
	font-size: var(--fs-300);
	font-weight: var(--fw-medium);
	line-height: var(--lh-snug);
	letter-spacing: .08em;
	text-transform: uppercase;
	text-shadow: none;
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce-page a.button:hover,
.woocommerce-page button.button:hover,
.woocommerce-page input.button:hover,
.woocommerce #respond input#submit:hover { background: var(--c-ink); color: var(--c-on-ink); }

/* Reset nadrzednego daje kazdemu polu tekstowemu ramke w szarosci spoza
   palety i promien 3 px, choc promien u nas jest zawsze zerowy. Selektor ma
   te sama moc co u nadrzednego, wiec wygrywa kolejnoscia w pliku. */
input[type="date"],
input[type="email"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="text"],
input[type="time"],
input[type="url"],
select,
textarea { border-color: var(--c-line-2); border-radius: var(--r-0); }
input[type="date"]:focus,
input[type="email"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="text"]:focus,
input[type="time"]:focus,
input[type="url"]:focus,
select:focus,
textarea:focus { border-color: var(--c-ink); }

/* "Do derki ..." - akcesoria dobrane do koszyka. Stale kolumny (D12). */
.cross-sells { margin-top: 40px; }
.cross-sells > h2 { font-size: var(--fs-700); padding-bottom: var(--s-3); border-bottom: var(--bw-hair) solid var(--c-line); }
.cross-sells ul.products,
.woocommerce .cross-sells ul.products {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--s-5);
	margin-top: var(--s-5);
}
.cross-sells ul.products::before,
.cross-sells ul.products::after { content: none; display: none; }
.cross-sells ul.products li.product,
.woocommerce .cross-sells ul.products[class*="columns-"] li.product {
	display: flex;
	flex-direction: column;
	float: none;
	width: auto;
	margin: 0;
}

/* Select2 podstawia wlasny widget pod <select>. Kraj jest ustalony i pole
   idzie do ukrycia razem z .ntb-hidden-field, ale gdyby wtyczka wystawila
   inne pole, ma wygladac jak nasze: 48 px, ramka kontrolki, promien 0. */
.select2-container .select2-selection--single {
	height: var(--h-field);
	border: var(--bw-hair) solid var(--c-line-2);
	border-radius: var(--r-0);
	background: var(--c-bg);
}
.select2-container .select2-selection--single .select2-selection__rendered { line-height: var(--h-field); padding-left: 12px; color: var(--c-ink); }
.select2-container .select2-selection--single .select2-selection__arrow { height: var(--h-field); }
.ntb-hidden-field .select2-container { display: none; }

/* ==========================================================================
   28. MEGA MENU I MENU MOBILNE                                      [ntb-menu]
   ==========================================================================
   Panel #ntb-tree niesie DWIE prezentacje tej samej struktury: mega menu
   od 1024 px i akordeon ponizej. Bez przelacznika obie renderuja sie naraz -
   dokladnie to widac na qa/menu-1440.png i qa/menu-390.png.
   ntb.js ustawia na panelu data-open="true"/"false", nie klase. */

/* Panel przestaje byc szuflada z lewej i staje sie rozwijanym panelem
   naglowka. position: absolute bez `top` siada na pozycji statycznej, czyli
   dokladnie pod naglowkiem - ntb24_tree_panel() wypisuje panel zaraz za
   <header> w .ntb-main. Krawedzie boczne wyrownane do marginesu strony,
   zeby panel stal w tej samej linii co tresc (D06). */
@media (min-width: 1024px) {
	.ntb-main { position: relative; }

	.ntb-tree {
		position: absolute;
		inset: auto var(--pad-page) auto var(--pad-page);
		width: auto;
		max-height: min(78vh, 720px);
		display: block;
		overflow: auto;
		overscroll-behavior: contain;
		border: var(--bw-hair) solid var(--c-ink);
		background: var(--c-bg);
		transform: none;
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transition: opacity var(--dur) var(--ease);
	}
	.ntb-tree[data-open="true"],
	.ntb-tree:target:not([data-open="false"]) { opacity: 1; visibility: visible; pointer-events: auto; }
}

/* Przelacznik prezentacji. Wartosci bazowe MUSZA stac przed media query -
   media query nie dodaje specyficznosci, liczy sie kolejnosc w pliku;
   odwrotnie mega menu renderowalo sie takze na 390 px, razem z akordeonem. */
.ntb-mega { display: block; }
.ntb-mmenu { display: none; }

@media (max-width: 1023px) {
	/* Ponizej 1024 px zostaje szuflada z lewej, ale jednokolumnowa:
	   w srodku jest akordeon, nie siatka dzialow. */
	.ntb-tree {
		display: block;
		width: min(480px, 100vw);
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
		padding-bottom: 80px;
		overscroll-behavior: contain;
	}
	.ntb-mega { display: none; }
	.ntb-mmenu { display: block; }

	/* Naglowek zostaje w zasiegu kciuka takze po przewinieciu listy dzialow:
	   panel jest tu jedynym elementem przewijanym, wiec sticky dziala. */
	.ntb-tree__head {
		position: sticky;
		top: 0;
		z-index: 2;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--s-3);
		padding: 6px 8px 12px var(--s-4);
		background: var(--c-bg);
		border-bottom: var(--bw-hair) solid var(--c-ink);
	}
	.ntb-tree__close { display: flex; border: 0; }
}

/* Menu tresciowe naglowka wchodzi z wp_nav_menu() jako gole <li> bez <ul>
   (items_wrap '%3$s'), wiec regula `ul, ol { list-style: none }` z sekcji 3
   ich nie obejmuje i przegladarka rysuje przy kazdej pozycji kropke.
   Widac ja na kazdym zrzucie desktopowym nad paskiem menu. */
.ntb-menu li { list-style: none; }

/* --- Rzad zakladek dzialow (D09: pierwszy rzad OTWARTEGO mega menu) ------- */

.ntb-mega__tabs { display: flex; flex-wrap: wrap; gap: 0; padding: 0 var(--s-5); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-mega__tab {
	min-height: 52px;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: var(--s-2) var(--s-5);
	font-size: var(--fs-400);
	color: var(--c-ink-2);
}
.ntb-mega__tab:first-child { padding-left: 0; }
.ntb-mega__tab svg { flex: none; color: var(--c-ink-3); }
.ntb-mega__tab:hover,
.ntb-mega__tab:focus-visible { color: var(--c-ink); }
.ntb-mega__tab:hover svg { color: currentColor; }
.ntb-mega__tab[aria-selected="true"] { color: var(--c-ink); font-weight: var(--fw-semibold); box-shadow: inset 0 -2px 0 var(--c-ink); }
.ntb-mega__tab[aria-selected="true"] svg { color: currentColor; }
/* Pierscien fokusu w menu tylko dla klawiatury. Otwarcie mysza tez konczy sie
   fokusem ze skryptu na zakladce i w Safari rysowalo pudelko wokol "Dla konia"
   obok podkreslenia wyboru - dwa wskazniki naraz, ramka nachodzaca na linie
   menu. Atrybut ustawia ntb-menu.js przy pointerdown/keydown. */
html[data-ntb-input="pointer"] .ntb-mega__tab:focus-visible,
html[data-ntb-input="pointer"] .ntb-mega__group:focus-visible,
html[data-ntb-input="pointer"] .ntb-treebtn:focus-visible { outline: none; }
/* Zakladka marek nie ma ikony, wiec wysokosc musi wziac z wlasnej reguly. */
.ntb-mega__tab--brands { min-height: 52px; margin-left: auto; padding-left: var(--s-5); border-left: var(--bw-hair) solid var(--c-line); }

/* --- Panele -------------------------------------------------------------- */

/* Bez !important regula autora z display: grid wygrywa z [hidden] z arkusza
   przegladarki i wszystkie siedem paneli widac naraz. Ten sam mechanizm
   opisuje komentarz przy setHidden() w ntb.js. */
.ntb-mega__pane[hidden] { display: none !important; }

.ntb-mega__pane { display: grid; grid-template-columns: minmax(220px, 1fr) minmax(0, 2.1fr) minmax(230px, 1fr); gap: 0; }
/* Nosnik podmieniany przez ntb-menu.js jednym innerHTML. Bez display: contents
   obie kolumny wpadaja do jednego pola siatki i uklad trzykolumnowy nie
   powstaje wcale. */
.ntb-mega__detail { display: contents; }

.ntb-mega__groups {
	border-right: var(--bw-hair) solid var(--c-line);
	padding: 14px 0;
	max-height: min(64vh, 560px);
	overflow-y: auto;
}
.ntb-mega__group {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	min-height: 42px;
	padding: 6px var(--s-5);
	font-size: var(--fs-400);
	color: var(--c-ink);
}
.ntb-mega__group svg { flex: none; color: var(--c-line-2); }
.ntb-mega__group:hover,
.ntb-mega__group:focus-visible { background: var(--c-paper); color: var(--c-ink); }
.ntb-mega__group[aria-current="true"] { background: var(--c-ink); color: var(--c-on-ink); font-weight: var(--fw-medium); }
.ntb-mega__group[aria-current="true"] svg { color: currentColor; }

.ntb-mega__axes { padding: 22px 28px; border-right: var(--bw-hair) solid var(--c-line); }
.ntb-mega__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 10px 20px; }
.ntb-mega__title { font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); line-height: var(--lh-tight); color: var(--c-ink); }
.ntb-mega__all { display: inline-flex; align-items: center; gap: var(--s-2); font-size: var(--fs-300); font-weight: var(--fw-medium); text-decoration: underline; text-underline-offset: 4px; }

/* Liczba osi zmienia sie od jednej do czterech, wiec stale kolumny (D12). */
.ntb-mega__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5) 28px; margin-top: var(--s-5); }
.ntb-mega__axis ul { list-style: none; margin: var(--s-3) 0 0; padding: 0; display: grid; gap: 9px; font-size: var(--fs-300); }
.ntb-mega__axis a { color: var(--c-ink); }
.ntb-mega__axis a:hover { color: var(--c-ink-2); text-decoration: underline; text-underline-offset: 3px; }
.ntb-mega__kicker { margin: 0; }
/* Wyjscie do kalkulatora, nie wartosc filtra - stad podkreslenie. */
.ntb-mega__axislink--guide { text-decoration: underline; text-underline-offset: 3px; }

.ntb-mega__chips { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-5); padding-top: var(--s-5); border-top: var(--bw-hair) solid var(--c-line); }
.ntb-mega__chip {
	min-height: 38px;
	display: inline-flex;
	align-items: center;
	padding: 0 14px;
	border: var(--bw-hair) solid var(--c-line-2);
	font-size: var(--fs-300);
	color: var(--c-ink);
}
.ntb-mega__chip:hover,
.ntb-mega__chip:focus-visible { border-color: var(--c-ink); color: var(--c-ink); }

/* --- Prawa kolumna: rozmiary dzialu -------------------------------------- */

.ntb-mega__aside { padding: 22px 24px; background: var(--c-paper); }
.ntb-mega__calc { display: flex; flex-direction: column; gap: var(--s-2); margin-top: 14px; padding: var(--s-4); background: var(--c-bg); }
.ntb-mega__calc svg { flex: none; color: var(--c-ink-2); }
.ntb-mega__calc:hover,
.ntb-mega__calc:focus-visible { outline: var(--bw-hair) solid var(--c-ink); }
.ntb-mega__calct { font-size: var(--fs-400); font-weight: var(--fw-medium); }
/* Zdanie idzie z zajawki podstrony i bywa dlugie - trzy wiersze wystarcza. */
.ntb-mega__calcd {
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink-2);
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.ntb-mega__calco { display: inline-flex; align-items: center; gap: var(--s-2); margin-top: var(--s-1); font-size: var(--fs-300); font-weight: var(--fw-medium); text-decoration: underline; text-underline-offset: 3px; }

/* Odstep 2 px na tle linii daje wloskowate kreski bez rysowania ramek. */
.ntb-mega__systems { display: grid; gap: 2px; margin-top: 14px; background: var(--c-line); }
.ntb-mega__system { display: flex; align-items: center; gap: var(--s-3); min-height: 52px; padding: var(--s-2) 14px; background: var(--c-bg); font-size: var(--fs-300); }
.ntb-mega__system svg:first-of-type { flex: none; color: var(--c-ink-2); }
.ntb-mega__system span { flex: 1; min-width: 0; }
.ntb-mega__system svg:last-of-type { flex: none; color: var(--c-ink-4); }
.ntb-mega__system:hover { background: var(--c-paper); }

.ntb-mega__guides { display: grid; gap: 9px; margin-top: var(--s-4); font-size: var(--fs-300); }
.ntb-mega__guides a { text-decoration: underline; text-underline-offset: 3px; }
.ntb-mega__note {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin: 18px 0 0;
	padding-top: var(--s-4);
	border-top: var(--bw-hair) solid var(--c-line-2);
	font-size: var(--fs-300);
	line-height: var(--lh-body);
	color: var(--c-ink-2);
}
.ntb-mega__note svg { flex: none; margin-top: 1px; }

/* --- Panel marek ---------------------------------------------------------- */

.ntb-mega__pane--brands { display: block; padding: var(--s-5) 28px; }
.ntb-mega__brandhead { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-4) var(--s-6); padding-bottom: var(--s-5); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-mega__brandhead p { margin: var(--s-2) 0 0; font-size: var(--fs-300); color: var(--c-ink-2); max-width: var(--w-text); }
.ntb-mega__brandfind { flex: none; display: flex; align-items: center; height: 42px; min-width: 260px; border: var(--bw-hair) solid var(--c-line-2); }
.ntb-mega__brandfind:focus-within { border-color: var(--c-ink); }
.ntb-mega__brandfind svg { flex: none; width: 40px; color: var(--c-ink-3); }
.ntb-mega__brandfind input { flex: 1; min-width: 0; height: 100%; padding: 0 12px 0 0; border: 0; background: none; font: inherit; font-size: var(--fs-300); }
.ntb-mega__brandfind input:focus { outline: none; }
/* Pole i komunikat wchodza z atrybutem hidden, ktory zdejmuje skrypt. */
.ntb-mega__brandfind[hidden],
.ntb-mega__brandempty[hidden] { display: none !important; }

/* Piec stalych kolumn, bez auto-fit (D12). */
.ntb-mega__brandcols { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 22px 28px; margin-top: 22px; }
.ntb-mega__brandcols li[hidden] { display: none !important; }
.ntb-mega__brand--lead { font-weight: var(--fw-medium); }
.ntb-mega__brandempty { margin: var(--s-4) 0 0; font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-mega__brandfoot { display: flex; flex-wrap: wrap; gap: 14px; margin-top: var(--s-5); padding-top: var(--s-5); border-top: var(--bw-hair) solid var(--c-line); }
.ntb-mega__brandfoot .ntb-btn { min-height: var(--touch); padding-inline: 18px; font-size: var(--fs-300); }

/* --- Akordeon mobilny ----------------------------------------------------- */

.ntb-mmenu__acc { border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-mmenu__dept {
	min-height: 56px;
	display: flex;
	align-items: center;
	gap: var(--s-3);
	padding: var(--s-2) var(--s-4);
	font-size: var(--fs-500);
	color: var(--c-ink);
	cursor: pointer;
	list-style: none;
}
/* Natywny trojkat <summary> jest widoczny na zrzucie i nie nalezy do systemu. */
.ntb-mmenu__dept::-webkit-details-marker { display: none; }
.ntb-mmenu__dept::marker { content: ""; }
.ntb-mmenu__dept svg:first-of-type { flex: none; }
.ntb-mmenu__dept svg:last-child { flex: none; margin-left: auto; color: var(--c-ink-3); transition: transform var(--dur) var(--ease); }
.ntb-mmenu__acc[open] .ntb-mmenu__dept svg:last-child { transform: rotate(180deg); }

.ntb-mmenu__body { padding-bottom: var(--s-2); background: var(--c-bg); }
.ntb-mmenu__group {
	min-height: 48px;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: var(--s-2) var(--s-4) var(--s-2) 28px;
	border-top: var(--bw-hair) solid var(--c-hatch);
	font-size: var(--fs-400);
}
.ntb-mmenu__group svg { flex: none; color: var(--c-line-2); }
.ntb-mmenu__group--all { padding-left: var(--s-4); border-top: 0; font-weight: var(--fw-medium); }
.ntb-mmenu__group--all svg { color: var(--c-ink-2); }

.ntb-mmenu__sizes { margin-top: var(--s-2); padding: var(--s-3) var(--s-4) var(--s-3) 28px; background: var(--c-paper); }
.ntb-mmenu__size { min-height: 48px; display: flex; align-items: center; gap: 10px; font-size: var(--fs-300); }
.ntb-mmenu__size svg:first-of-type { flex: none; color: var(--c-ink-2); }
.ntb-mmenu__size svg:last-of-type { flex: none; margin-left: auto; color: var(--c-line-2); }

.ntb-mmenu__short { padding: var(--s-4); border-top: var(--bw-heavy) solid var(--c-ink); }
.ntb-mmenu__link { min-height: 48px; display: flex; align-items: center; justify-content: space-between; font-size: var(--fs-400); border-bottom: var(--bw-hair) solid var(--c-hatch); }
.ntb-mmenu__link:last-child { border-bottom: 0; }
.ntb-mmenu__link svg { flex: none; color: var(--c-line-2); }

/* Pierscien skupienia bierze regula ogolna :focus-visible z sekcji 3 -
   2 px czerni z odstepem na kazdym elemencie interaktywnym, wiec pulapka
   ogniskowania z ntb-menu.js ma po czym chodzic i nic sie tu nie powtarza. */

/* ==========================================================================
   29. BREAKPOINTY SEKCJI 23-28                                 [ntb-progi-new]
   ==========================================================================
   Progi te same co w sekcji 16: 480, 768, 1024, 1200, 1440 px. Kazda siatka
   ma jawna liczbe kolumn na kazdym progu (D12). Reguly dla nowych klas stoja
   razem tutaj, a nie przy komponentach, zeby na pewno pasly sie za wszystkimi
   wartosciami bazowymi z sekcji 23-28 - media query nie dodaje specyficznosci,
   liczy sie kolejnosc. */

@media (max-width: 1279px) {
	/* Prawa kolumna mega menu schodzi pod dwie pozostale. */
	.ntb-mega__pane { grid-template-columns: minmax(200px, 1fr) minmax(0, 2fr); }
	.ntb-mega__aside { grid-column: 1 / -1; }
	.ntb-mega__brandcols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 1199px) {
	.ntb-mega__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ntb-cartsaved__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.cross-sells ul.products,
	.woocommerce .cross-sells ul.products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1023px) {
	/* Uklad E: przy jednej kolumnie ograniczenie szerokosci przestaje miec sens. */
	.ntb-product--narrow { grid-template-columns: minmax(0, 1fr); }
	.ntb-pcard--narrow .ntb-product--narrow { max-width: none; }
	.ntb-mega__brandcols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ntb-thanks__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 767px) {
	/* --- Karta produktu --- */
	.ntb-buy__price--duza { font-size: var(--fs-800); }
	.ntb-tile { flex: 1 1 140px; }
	/* Ostrzezenie jest w calosci celem czytania, wiec na telefonie nie moze
	   byc nizsze niz norma dotyku - inaczej ginie miedzy blokami. */
	.ntb-warn, .ntb-hint { min-height: var(--touch); }

	/* --- Matryca jako arkusz od dolu (regula 3) --- */
	.ntb-matrix {
		position: fixed;
		inset: auto 0 0 0;
		z-index: var(--z-panel);
		max-height: 86vh;
		overflow: auto;
		overscroll-behavior: contain;
		margin: 0;
		padding: var(--s-5) var(--pad-page) calc(var(--s-5) + var(--safe-b));
		background: var(--c-bg);
		box-shadow: var(--sh-sheet);
		transform: translateY(100%);
		transition: transform var(--dur) var(--ease);
	}
	/* Wejscie kotwica z .ntb-matrix__trigger; JS domknie przycisk zamkniecia. */
	.ntb-matrix:target { transform: none; }
	.ntb-matrix__head { padding-right: 52px; }
	.ntb-matrix__close {
		position: absolute;
		top: var(--s-2);
		right: var(--s-2);
		display: grid;
		place-items: center;
		width: var(--touch);
		height: var(--touch);
		border: var(--bw-hair) solid var(--c-line);
		background: var(--c-bg);
	}
	.ntb-matrix__title { font-size: var(--fs-700); }
	/* Kolumna zasiegu jest poza ekranem (tabela przewija sie w bok), wiec
	   jej lamanie rozciagalo wiersze i rozjezdzala sie siatka kwadratow. */
	.ntb-matrix__reach { white-space: nowrap; }

	/* --- Skala pomiaru: przewijana poziomo ze snapem --- */
	.ntb-scale { padding: var(--s-4) var(--s-3) var(--s-3); }
	/* position: relative - bez tego .ntb-sr (absolutne etykiety stanu) liczyly
	   sie do najblizszego pozycjonowanego przodka i rozciagaly dokument do
	   531 px przy 7+ stopniach (przeglad 16.09.2026). */
	.ntb-scale__track { position: relative; overflow-x: auto; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; scrollbar-width: none; }
	.ntb-scale__track::-webkit-scrollbar { display: none; }
	/* Sygnal, ze dalej sa kolejne stopnie: wygaszenie prawej krawedzi, dopoki nie dojedzie do konca (klasy z ntb-product.js). */
	.ntb-scale__track.is-scrollable:not(.is-at-end) { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent); } /* qa-ok: maska (krycie), nie kolor */
	.ntb-scale__step { flex: 0 0 auto; min-width: var(--touch); min-height: var(--touch); scroll-snap-align: center; }
	.ntb-scale__step[aria-pressed="true"] { flex: 0 0 auto; min-width: 56px; }
	.ntb-scale__legend { justify-content: flex-start; }

	/* --- Konfigurator i opakowania: pelna norma dotyku --- */
	.ntb-config__opt { min-height: var(--h-btn); }

	/* --- Koszyk --- */
	.ntb-cart__cols { gap: var(--s-6); }
	.ntb-cart__aside { max-width: none; }
	.ntb-shipbar { padding: var(--s-3) var(--s-4); font-size: var(--fs-200); }
	.ntb-cartrow { gap: var(--s-3); padding: var(--s-4) 0; }
	.ntb-cartrow__media { width: 80px; height: 100px; }
	.ntb-cartrow__body { flex-direction: column; gap: var(--s-3); }
	/* Podstawa `flex: 1 1 260px` z ukladu desktopowego opisuje SZEROKOSC, ale
	   po obroceniu opakowania na kolumne flex-basis przechodzi na wysokosc
	   i kazdy wiersz koszyka dostawal 260 px zamiast wysokosci tresci -
	   zmierzone: 188 px pustki pod nazwa, przy trzech pozycjach ponad polowa
	   ekranu (qa/tor2-koszyk-390.png). W kolumnie liczy sie tylko tresc. */
	.ntb-cartrow__main { flex: 0 1 auto; width: 100%; }
	.ntb-cartrow__name { font-size: var(--fs-300); line-height: var(--lh-label); }
	/* Prawa kolumna staje sie wierszem pod nazwa: cena i stepper obok siebie,
	   akcje w drugim wierszu - w 358 px wszystkie trzy nie mieszcza sie
	   naraz i "Zapisz / Usun" wychodzilo poza ekran o 67 px (zmierzone). */
	.ntb-cartrow__side { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; width: 100%; min-width: 0; gap: var(--s-3); }
	.ntb-cartrow__acts { flex: 1 1 100%; gap: var(--s-5); }
	/* Stepper 40 px, ale pole dotyku plusa i minusa siega krawedzi (par. 3). */
	.ntb-qty--cart { height: var(--touch); }
	.ntb-qty--cart button { position: relative; width: var(--touch); }
	.ntb-qty--cart button::before { content: ""; position: absolute; inset: -2px 0; min-height: var(--touch); }
	.ntb-cartsaved__list { grid-template-columns: minmax(0, 1fr); }
	.cross-sells ul.products,
	.woocommerce .cross-sells ul.products { grid-template-columns: minmax(0, 1fr); }

	/* Arkusz zmiany rozmiaru od dolu, nad paskiem koszyka. */
	.ntb-sheet {
		position: fixed;
		inset: auto 0 0 0;
		z-index: var(--z-modal);
		max-height: 70vh;
		overflow: auto;
		overscroll-behavior: contain;
		margin: 0;
		border: 0;
		border-top: var(--bw-hair) solid var(--c-ink);
		box-shadow: var(--sh-sheet);
		padding-bottom: calc(18px + var(--safe-b));
	}

	/* Przyklejony pasek "Razem" z CTA - na koszyku pokazuje sie tak samo
	   jak pasek zakupu na karcie produktu. */
	.ntb-buybar--cart { padding: var(--s-3) var(--s-4) calc(var(--s-3) + var(--safe-b)); border-top: var(--bw-hair) solid var(--c-ink); }
	.ntb-buybar--cart .ntb-buybar__size { font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .14em; text-transform: uppercase; }
	.ntb-buybar--cart .ntb-buybar__price { font-size: var(--fs-600); font-weight: var(--fw-semibold); }
	.ntb-buybar--cart .ntb-btn { flex: 1; }

	/* --- Kasa i potwierdzenie --- */
	.ntb-checkout__cols { gap: var(--s-6); }
	.ntb-checkout__main { gap: var(--s-6); }
	.ntb-checkout__aside { max-width: none; }
	.ntb-pay__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ntb-ship__opt { min-height: 60px; padding: 10px 14px; }
	.ntb-parcels { grid-template-columns: minmax(0, 1fr); }
	.ntb-parcel { padding: var(--s-4) var(--s-4); }
	.ntb-savehorse { padding: 18px var(--s-4); }
	.ntb-savehorse .ntb-btn { width: 100%; }
	.ntb-thanks { margin-top: var(--s-5); }
	.ntb-thanks__head { gap: var(--s-3); }
	.ntb-thanks__mark { width: 44px; height: 44px; }
	.ntb-thanks__acts .ntb-btn { width: 100%; }
}

@media (max-width: 599px) {
	/* Pola formularza kasy schodza do jednej kolumny. */
	.ntb-fields { grid-template-columns: minmax(0, 1fr); }
	.ntb-thanks__facts { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 479px) {
	/* Druga wartosc obok ceny schodzi pod nia: kreska pionowa zamienia sie
	   w pozioma, inaczej cena i cena za litr walcza o te sama szerokosc. */
	.ntb-buy__aside { padding-left: 0; padding-top: var(--s-3); border-left: 0; border-top: var(--bw-hair) solid var(--c-line); width: 100%; }

	/* Lista definicji na waskim ekranie: etykieta NAD wartoscia, hairline
	   tylko nad para (regula 3). Przy dlugich etykietach ("Kraj pochodzenia")
	   i dlugich wartosciach kolumna auto zjadala szerokosc wartosci. */
	.ntb-specs { grid-template-columns: minmax(0, 1fr); }
	.ntb-specs dt { padding: var(--s-3) 0 0; border-top: var(--bw-hair) solid var(--c-line); }
	.ntb-specs dd { padding: 2px 0 var(--s-3); border-top: 0; padding-left: 0; }
	.ntb-specs dd:last-of-type { border-bottom: var(--bw-hair) solid var(--c-line); }
	.ntb-specs--buy dt { padding: var(--s-3) 0 0; }
	.ntb-specs--buy dd { padding: 2px 0 var(--s-3); }

	.ntb-cartrow__dl { grid-template-columns: minmax(0, 1fr); gap: 2px; }
	.ntb-cartrow__dl dt { margin-top: var(--s-2); }
}

/* ==========================================================================
   30. CELE DOTYKOWE NA 390 px DLA SEKCJI 23-28              [ntb-dotyk-nowe]
   ==========================================================================
   Dalszy ciag sekcji 21 i 22: kazdy nowy link i kazda nowa kontrolka ma na
   390 px co najmniej 44 px. Powiekszamy POLE DOTYKU, nigdy stopien pisma.
   Prog 1023 jak w sekcji 21. */

@media (max-width: 1023px) {
	.ntb-linkbtn,
	.ntb-buy__group,
	.ntb-sizing__note a,
	.ntb-cartrow__change,
	.ntb-cartrow__name,
	.ntb-cartsaved__name,
	.ntb-oreview__edit,
	.ntb-buy__asidelink,
	.ntb-mega__all,
	.ntb-mega__axis a,
	.ntb-mega__guides a,
	.ntb-honest__acts .ntb-link,
	.ntb-thanks__acts .ntb-link {
		display: inline-flex;
		align-items: center;
		min-height: var(--touch);
	}

	/* Nazwa pozycji jest jedynym z tej listy, ktory NIE jest wtracony w zdanie:
	   marka stoi przed nia jako <span>, wiec przy inline-flex obie wchodzily
	   w jeden wiersz ("DADA SPORT DADA Sport bryczesy Sagaro" na zrzucie).
	   Flex blokowy trzyma norme dotyku i wlasny wiersz. Wielowierszowa nazwa
	   dalej lamie sie normalnie - tekst jest jednym polem flex. */
	.ntb-cartrow__name,
	.ntb-cartsaved__name { display: flex; }

	/* Chip i przycisk w mega menu ida z 38 px do normy dotyku (D08). */
	.ntb-mega__chip,
	.ntb-sheet__opt,
	.ntb-horse__item,
	.ntb-pack { min-height: var(--touch); }

	/* Ikona zamkniecia arkusza to kwadrat, wiec liczy sie takze szerokosc. */
	.ntb-sheet__close,
	.ntb-matrix__close { min-width: var(--touch); min-height: var(--touch); }
}

/* --- Cele dotykowe wykryte audytem odbiorczym na 390 px (rozdzial 9 pkt 1) --- */
@media (max-width: 1023px) {
	/* Telefon i adres e-mail wtracone w zdanie.
	   Na stronach prawnych i na /wsparcie-dietetyczne/ to jedyne wezwanie do
	   dzialania w calej tresci ("W sprawach pilnych prosimy o kontakt: ..."),
	   a mierzyly 80x16 i 151x16 px. Padding pionowy na elemencie liniowym
	   powieksza obszar klikalny do 44 px i NIE zmienia wysokosci wiersza,
	   wiec akapit lamie sie dokladnie tak samo jak dotad. */
	#ntb-content a[href^="tel:"],
	#ntb-content a[href^="mailto:"] { padding-block: 15px; }

	/* Formularz logowania WooCommerce na /konto/. Motyw ma wlasna strone
	   /logowanie/ i tam pola maja --h-field, ale /konto/ oddaje surowy
	   formularz Woo: pole 310x36 px i przelacznik podgladu hasla 22x22 px.
	   Rownamy oba do normy dotyku bez tykania szablonu Woo. */
	.woocommerce-form input.woocommerce-Input,
	.woocommerce-form input[type="text"],
	.woocommerce-form input[type="email"],
	.woocommerce-form input[type="password"] { min-height: var(--h-field); }

	.woocommerce-form .show-password-input {
		min-width: var(--touch);
		min-height: var(--touch);
		background-position: center;
	}

	/* "Nie pamietasz hasla?" stoi pod formularzem jako osobny wiersz,
	   wiec moze dostac pelna wysokosc bez psucia ukladu zdania. */
	.woocommerce-LostPassword a { display: inline-flex; align-items: center; min-height: var(--touch); }
}

/* ==========================================================================
   23. Poradnik i przewodniki doboru rozmiaru
   ==========================================================================
   Kafle 3:2 wg paragrafu 3. Siatka ma stala liczbe kolumn z jawnymi progami,
   a nie auto-fit - przy zmiennej liczbie kafli puste komorki odslanialyby
   tlo siatki (D12). */

.ntb-guides {
  margin-block: var(--s-10);
}

.ntb-guides + .ntb-guides {
  margin-top: var(--s-11);
  padding-top: var(--s-10);
  border-top: var(--bw-hair) solid var(--c-line);
}

.ntb-guides__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px;
  margin-top: var(--s-6);
  background: var(--c-line);
}

.ntb-guide {
  background: var(--c-bg);
}

.ntb-guide__link {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-height: 132px;
  padding: var(--s-6);
  height: 100%;
}

.ntb-guide__link:hover,
.ntb-guide__link:focus-visible {
  background: var(--c-paper);
}

.ntb-guide__title {
  margin: 0;
  font-family: var(--f-display);
  font-size: var(--fs-700);
  line-height: var(--lh-tight);
  font-weight: var(--fw-regular);
}

.ntb-guide__lead {
  margin: 0;
  font-size: var(--fs-400);
  line-height: var(--lh-body);
  color: var(--c-ink-3);
}

@media (max-width: 1023px) {
  .ntb-guides__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 767px) {
  .ntb-guides__grid { grid-template-columns: minmax(0, 1fr); }

  /* Cel dotykowy: caly kafel jest linkiem, wiec wystarczy jego wysokosc. */
  .ntb-guide__link { min-height: var(--touch); padding: var(--s-5); }
  .ntb-guide__title { font-size: var(--fs-600); }
}

/* ==========================================================================
   24. Opis kategorii: pierwszy akapit widoczny, reszta pod "Czytaj wiecej"
   ==========================================================================
   Rozwijanie na <details>, bez JavaScriptu. Strzalke rysujemy sami, bo domyslny
   trojkat przegladarki nie nalezy do naszego jezyka wizualnego, a jego ukrycie
   wymaga zdjecia display: list-item takze w Safari (::-webkit-details-marker). */

.ntb-prose__more {
  margin-top: var(--s-4);
}

.ntb-prose__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--touch);
  padding-inline: 0;
  font-size: var(--fs-300);
  font-weight: var(--fw-medium);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--c-ink);
  cursor: pointer;
  list-style: none;
}

.ntb-prose__toggle::-webkit-details-marker { display: none; }

.ntb-prose__toggle:hover { color: var(--c-ink-2); }

.ntb-prose__toggle:focus-visible {
  outline: 2px solid var(--c-ink);
  outline-offset: 2px;
}

/* Etykieta zmienia sie ze stanem, zeby przycisk zawsze mowil, co zrobi. */
.ntb-prose__more[open] .ntb-prose__toggle-more,
.ntb-prose__more:not([open]) .ntb-prose__toggle-less { display: none; }

.ntb-prose__toggle svg { transition: transform var(--dur) var(--ease); }
.ntb-prose__more[open] .ntb-prose__toggle svg { transform: rotate(180deg); }

.ntb-prose__rest { margin-top: var(--s-4); }

/* Pierwszy naglowek rozwiniecia nie potrzebuje podwojnego odstepu. */
.ntb-prose__rest > :first-child { margin-top: 0; }

@media (prefers-reduced-motion: reduce) {
  .ntb-prose__toggle svg { transition: none; }
}

/* ==========================================================================
   25. Typografia tresci rozwijanej pod listingiem
   ==========================================================================
   Opis kategorii to jedyne miejsce w sklepie, gdzie mamy tresc redakcyjna
   z naglowkami, listami i odnosnikami w zdaniu. Kontener .ntb-prose byl
   opisany tylko dla pojedynczego akapitu (.ntb-prose > p), wiec ta tresc
   dziedziczyla ustawienia strony: akapity bez marginesu zlewaly sie w jeden
   blok, listy traciły wciecie, a odnosniki - przez globalne
   a { color: var(--c-ink); text-decoration: none } - byly nieodroznialne
   od tekstu. Na jednej stronie dzialu bylo tak 29 niewidocznych odnosnikow.

   Stylujemy .ntb-prose__rest, a nie .ntb-prose, i to celowo: do tej samej
   kolumny wchodza przez shortcode koszyk, kasa i potwierdzenie (page.php),
   dlatego selektor potomka na .ntb-prose zabralby ich akapitom wlasny wyglad.
   Rozwiniecie opisu zawiera wylacznie nasza tresc redakcyjna. */

.ntb-prose__rest p {
  margin-top: 14px;
  max-width: var(--w-text);
  font-size: var(--fs-400);
  line-height: var(--lh-body);
  color: var(--c-ink-2);
}

.ntb-prose__rest h2 {
  margin-top: var(--s-6);
  font-size: var(--fs-600);
  font-weight: var(--fw-medium);
  line-height: var(--lh-label);
  color: var(--c-ink);
}

/* Ten sam podnaglowek tresci co .ntb-subhead - krój, stopien i wage niesie
   rola z sekcji 3, tutaj zostaje tylko odstep i barwa. */
.ntb-prose__rest h3 {
  margin-top: var(--s-5);
  color: var(--c-ink);
}

.ntb-prose__rest ul,
.ntb-prose__rest ol {
  margin-top: 12px;
  padding-left: var(--s-5);
}

.ntb-prose__rest li {
  margin-top: 6px;
  font-size: var(--fs-400);
  line-height: var(--lh-body);
  color: var(--c-ink-2);
}

.ntb-prose__rest li::marker { color: var(--c-ink-4); }

/* Odnosnik w zdaniu musi byc widoczny bez najechania - na dotyku najechania
   nie ma w ogole (regula 3). Podkreslenie niesie ten sam sygnal, co kolor,
   wiec dziala takze przy monochromatycznej palecie. */
.ntb-prose__rest a {
  color: var(--c-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--c-line-2);
}

.ntb-prose__rest a:hover { text-decoration-color: var(--c-ink); }

.ntb-prose__rest a:focus-visible {
  outline: 2px solid var(--c-ink);
  outline-offset: 2px;
}

/* Cel dotykowy odnosnika w zdaniu ogranicza wysokosc wiersza otaczajacego
   tekstu, wiec nie da sie go rozciagnac do 44 px bez rozjechania akapitu
   (WCAG 2.5.8 wylacza z tego wymogu odnosniki wplecione w zdanie).
   Robimy tyle, ile mozna zrobic uczciwie: luzniejszy interlinia na telefonie
   powieksza pole trafienia i odsuwa sasiednie odnosniki od siebie. */
@media (max-width: 600px) {
  .ntb-prose__rest p,
  .ntb-prose__rest li { line-height: var(--lh-body); }

  .ntb-prose__rest a { padding-block: 2px; }
}

/* ============================================================
   26. Poprawki z audytu: karta produktu
   ============================================================ */

/* Osie wariantu sa polami radio (K5), wiec wybor niesie :checked, a nie
   aria-pressed. Pole jest wizualnie ukryte klasa .ntb-sr, cala robote
   widzialna robi sasiadujaca etykieta - stad kazda regula stanu ma tu
   swoj odpowiednik w postaci input + label. */
label.ntb-size,
label.ntb-color,
label.ntb-scale__step,
label.ntb-horse__item { cursor: pointer; }

/* Cel dotykowy chipa rozmiaru: przed poprawka 38 px (mierzone 37), przy
   normie 44 px (regula 3, K13). Podnosimy go tam, gdzie chip JEST kontrolka,
   czyli w bloku zakupu - wariant --sm na listingu zostaje nosnikiem stanu
   i normy dotyku nie dotyczy. */
.ntb-buy__block .ntb-size,
.ntb-buy__block .ntb-color { min-height: var(--touch); }

/* Stan wybrany. */
input[type="radio"]:checked + .ntb-size {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: var(--c-on-ink);
  font-weight: var(--fw-medium);
}
input[type="radio"]:checked + .ntb-size--range span,
input[type="radio"]:checked + .ntb-size--cert .ntb-size__range { color: var(--c-line-2); }
input[type="radio"]:checked + .ntb-color { outline: 1px solid var(--c-ink); outline-offset: 3px; }

input[type="radio"]:checked + .ntb-horse__item {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: var(--c-on-ink);
}
input[type="radio"]:checked + .ntb-horse__item .ntb-horse__note { color: var(--c-line-2); }

input[type="radio"]:checked + .ntb-scale__step { flex: 1.25; }
input[type="radio"]:checked + .ntb-scale__step .ntb-scale__label { font-weight: var(--fw-semibold); color: var(--c-ink); }
input[type="radio"]:checked + .ntb-scale__step .ntb-scale__bar {
  height: 54px;
  display: grid;
  place-items: center;
  border-color: var(--c-ink);
  background: var(--c-ink);
}
input[type="radio"]:checked + .ntb-scale__step .ntb-scale__bar::before {
  content: "";
  width: 14px;
  height: 14px;
  background: var(--c-on-ink);
  -webkit-mask: var(--i-check) center / 14px 14px no-repeat;
  mask: var(--i-check) center / 14px 14px no-repeat;
}

/* Rozmiar, ktorego nie da sie kupic. Etykiety nie da sie wylaczyc
   atrybutem, wiec stan bierze sie z pola. */
input[type="radio"]:disabled + .ntb-size,
input[type="radio"]:disabled + .ntb-color,
input[type="radio"]:disabled + .ntb-scale__step,
input[type="radio"]:disabled + .ntb-horse__item { pointer-events: none; cursor: default; }
input[type="radio"]:disabled + .ntb-size:not([data-state]) {
  border-color: var(--c-line);
  color: var(--c-ink-3);
  text-decoration: line-through;
}

/* Fokus. Pole jest przyciete do zera, wiec obrys musi narysowac etykieta -
   inaczej klawiatura chodzi po grupie bez zadnego sladu (P19, S22).
   Bierzemy :focus, nie tylko :focus-visible: skrypt ustawia fokus programowo
   po probie zakupu bez wyboru, a wtedy :focus-visible bywa nieaktywne. */
input[type="radio"]:focus + .ntb-size,
input[type="radio"]:focus + .ntb-color,
input[type="radio"]:focus + .ntb-scale__step,
input[type="radio"]:focus + .ntb-horse__item {
  outline: var(--bw-heavy) solid var(--c-ink);
  outline-offset: 2px;
}

/* Grupa po probie zakupu bez wyboru: ramka czerni, nigdy czerwien. */
.ntb-scale__track.is-required .ntb-scale__bar,
.ntb-horse.is-required .ntb-horse__item,
.ntb-colors.is-required .ntb-color { border-color: var(--c-ink); }

/* Zapis na powiadomienie stoi teraz na karcie naprawde (K14), wiec
   potrzebuje wlasnego odstepu od skali rozmiarow. */
.ntb-notify-group { display: flex; flex-direction: column; gap: var(--s-3); margin-top: var(--s-4); }
.ntb-notify-group__lead { display: flex; align-items: flex-start; gap: 8px; font-size: var(--fs-300); color: var(--c-ink-2); }

/* Karta bez ani jednego kupowalnego rozmiaru: zamiast formularza zakupu
   stan, zapis na powiadomienie i wyjscie do grupy (K16). */
.ntb-buy__off { display: flex; flex-direction: column; gap: var(--s-3); margin-top: var(--s-4); }
.ntb-buy__off-link { align-self: flex-start; }

/* Probka koloru niesie stan tak samo jak chip rozmiaru (K12). Probka jest
   z definicji barwna, wiec stanu NIE moze nieść barwa: kropkowana obwodka
   dla "na zamowienie", ukosna kreska w czerni dla "chwilowo brak" i "poza
   oferta" - ten sam jezyk, ktorego uzywa szraf na kafelku. */
.ntb-color { position: relative; }
.ntb-color[data-state="backorder"] { border-style: dotted; border-color: var(--c-ink); }
.ntb-color[data-state="soon"]::after,
.ntb-color[data-state="discontinued"]::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: var(--r-round);
  background: linear-gradient(
    to top right,
    transparent calc(50% - 1px),
    var(--c-ink) calc(50% - 1px),
    var(--c-ink) calc(50% + 1px),
    transparent calc(50% + 1px)
  );
}
.ntb-color[data-state="discontinued"] { border-color: var(--c-line); }

/* Zapis na powiadomienie wchodzi na 1 580 kart bez zapasu i pod rozmiary,
   ktorych chwilowo brak (K14). Kontener .ntb-notify powstal dla jednego
   zdania z przyciskiem obok, a niesie teraz zdanie ORAZ formularz z polem
   i zgoda - przy dwoch dzieciach flex sciskal etykiete do kilku znakow
   w wierszu. Zdanie zostaje w wierszu z ikona, formularz schodzi pod nie. */
.ntb-buy__off .ntb-notify,
.ntb-notify-group .ntb-notify { flex-wrap: wrap; align-items: flex-start; }
.ntb-buy__off .ntb-notify > span,
.ntb-notify-group .ntb-notify > span { flex: 1 1 12rem; }
.ntb-buy__off .ntb-notify .ntb-notify__form,
.ntb-notify-group .ntb-notify .ntb-notify__form { flex: 1 1 100%; }

/* Podkreslenie z .ntb-notify button (regula 1803) przechodzilo na czarny
   przycisk wysylki formularza z wtyczki - wygladal jak odnosnik w przycisku. */
.ntb-notify .ntb-notify__form button[type="submit"] { text-decoration: none; }

/* ==========================================================================
   31. ROZKLAD TRESCI: KOLUMNA PROZY I SIATKI, KTORE ZNAJA LICZBE DZIECI
   ==========================================================================
   Odpowiedz na pytanie wlasciciela "dlaczego opisy kategorii wypelniaja tylko
   czesc widoku". Przyczyny byly dwie, a nie dwadziescia usterek.

   PIERWSZA: siatka deklarowala wiecej kolumn, niz szablon ma dzieci.
   Ten sam nawyk w pieciu selektorach zostawial pusta prawa polowe na 58 z 58
   kategorii (opis 624 z 1296 px), na 2 870 kartach produktu (.ntb-pcols),
   na 6 664 blokach linkow i na stronach prawnych bez spisu tresci (259
   z 1296 px). Lekarstwem nie jest usuniecie drugiej kolumny - FAQ i spis
   tresci maja prawo kiedys powstac - tylko regula, ktora reaguje na LICZBE
   DZIECI. `:has(> :last-child:nth-child(1))` czyta sie doslownie: jedyne
   dziecko jest zarazem pierwsze i ostatnie. Kiedy dojdzie drugie, siatka
   sama wraca do dwoch kolumn i nie trzeba pamietac o zdjeciu wyjatku.

   Reguly stoja w @media (min-width), zeby nie przebily progow z sekcji 16
   i 29: ponizej nich siatki i tak sa jednokolumnowe, a wieksza moc selektora
   z :has() wygralaby z regula telefonu.

   DRUGA: szerokosc kolumny tekstu byla liczba w miejscu uzycia - inline
   `max-width: 760px` w dziewieciu miejscach siedmiu szablonow. Inline'u nie
   nadpisze arkusz, wiec koszyk i kasa mialy obejscie z !important (sekcja 27),
   a tabela dostawy i kalkulator rozmiarow zostawaly scisniete do miary prozy.
   Dzis miare dostaja DZIECI kontenera: proza swoje 760 px, a wszystko, co
   proza nie jest - tabela, formularz, siatka kafli, koszyk - cala kolumne. */

/* --- Kolumna tekstu ciaglego -------------------------------------------- */
.ntb-page__body > * { max-width: var(--w-prose); }

/* Miara AKAPITU wewnatrz tej kolumny. Kolumna zostaje na --w-prose: niesie ja
   naglowek, tabela, formularz i linia dzialowa, wiec strona ma dalej jedna os.
   Zwezamy sam tekst ciagly, bo 760 px to miara policzona dla stopnia 16 px,
   a proza stron statycznych stoi na --fs-400: pomiar Range.getClientRects
   na /dostawa-i-zwroty/ dawal przy 760 px 97 znakow w wierszu wobec progu 85.
   Listy bez klasy tez sa tekstem; lista Z klasa to komponent (.ntb-guides,
   .ntb-sizes) i miary akapitu jej nie narzucamy. */
.ntb-page__body > p,
.ntb-page__body > ul:not([class]),
.ntb-page__body > ol:not([class]) { max-width: var(--w-text); }

/* Elementy szersze od zdania. Tabela lamana do 760 px zamiast 997 px, siatka
   kafli w jednej trzeciej kolumny i formularz kasy w kolumnie prozy to nie
   jest ta sama usterka co za dlugi wiersz tekstu - i nie leczy sie jej ta
   sama miara. */
.ntb-page__body > table,
.ntb-page__body > figure,
.ntb-page__body > form,
.ntb-page__body > .ntb-table,
.ntb-page__body > .ntb-sizing__table,
.ntb-page__body > .ntb-grid,
.ntb-page__body > .ntb-sizes,
.ntb-page__body > .ntb-guides,
.ntb-page__body > .woocommerce,
.ntb-page__body > .ntb-cart,
.ntb-page__body > .ntb-checkout,
.ntb-page__body > .ntb-thanks,
.ntb-page__body > .ntbs-tabela,
.ntb-page__body > .ntbs-kalkulator,
.ntb-page__body > .ntbs-systemy,
.ntb-page__body > .ntbs-kafle,
.ntb-page__body > .ntbs-wynik,
.ntb-page__body > .ntbs-po-zakupie { max-width: none; }

/* Tabela i jej przypis wychodza z template-parts/page-size-table.php jako
   jeden element ukladu, wiec moga stanac wprost w siatce albo samodzielnie
   w sekcji. Odstep gorny tylko poza siatka - w siatce niesie go gap. */
.ntb-sizing__table { min-width: 0; margin-top: var(--s-6); overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Tabela o osmiu kolumnach (czapraki) jest szersza niz kolumna siatki (727 > 572 px)
   i bez overflow-x nachodzila na panel obok. Przewijanie zostaje wewnatrz kontenera;
   na 390 px tabela i tak zamienia sie w liste definicji. */
.ntb-sizing__grid > .ntb-sizing__table,
.ntb-page__body > .ntb-sizing__table:first-child { margin-top: 0; }

/* --- Siatki, ktore zwijaja sie do liczby dzieci -------------------------- */

@media (min-width: 768px) {
  /* Blok linkow: 3 kolumny w projekcie, ale 52 grupy maja jedno dziecko,
     a karty produktu dwa. Jedno dziecko schodzi do miary prozy, bo to lista
     odnosnikow do czytania, nie pas kafli. */
  .ntb-catlinks:has(> :last-child:nth-child(1)) { grid-template-columns: minmax(0, var(--w-prose)); }

  /* Rozmiarowka bez przeliczenia na inne marki to sama tabela - a tabela
     czyta sie lepiej na calej szerokosci niz na polowie. */
  .ntb-sizing__grid:has(> :last-child:nth-child(1)) { grid-template-columns: minmax(0, 1fr); }
}

@media (min-width: 1024px) {
  /* Opis kategorii bez FAQ i opis produktu bez atrybutow. Miara prozy,
     nie pelna kolumna: 1 296 px dalyby wiersz po 150 znakow. */
  .ntb-catcontent__grid:has(> :last-child:nth-child(1)),
  .ntb-pcols:has(> :last-child:nth-child(1)) { grid-template-columns: minmax(0, var(--w-prose)); }

  /* Archiwum bez kolumny bocznej: strona prawna bez naglowkow H2 nie ma spisu
     tresci, wiec tresc wpadala w kolumne filtrow szeroka na 259 px i lamala
     sie po 31 znakach. Tu pelna kolumna, bo miare trzyma juz .ntb-page__body. */
  .ntb-archive__grid:has(> :last-child:nth-child(1)) { grid-template-columns: minmax(0, 1fr); }
}

@media (min-width: 1200px) {
  /* Dwa dzieci z trzech kolumn: karta produktu ma poradniki i kategorie
     siostrzane, nie ma marek. Trzecia kolumna stala pusta na 6 664 kartach. */
  .ntb-catlinks:has(> :last-child:nth-child(2)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   32. ZAPORA NA KOLORY SPOZA PALETY                            [ntb-zapora]
   ==========================================================================
   Regula 5 mowi o dziewieciu kolorach, a qa_paleta.rb pilnuje jej w NASZYCH
   zrodlach. Tymczasem kolor wchodzi na strone takze z dwoch arkuszy, ktorych
   nie piszemy: motywu nadrzednego Hello Elementor i WooCommerce. Skrypt nie
   ma czego zlapac, bo barwa nie pada w naszym kodzie - widac ja dopiero na
   zrzucie z przegladarki. Dlatego zapora, nie kolejna punktowa podmianka.

   Kolejnosc wczytywania (sprawdzone na wyjsciu HTML):
     woocommerce.css -> hello-elementor/reset.css -> ntb24/style.css
   Nasz arkusz jest ostatni, wiec przy ROWNEJ mocy selektora wygrywamy.
   Warunek jest jeden: powtorzyc moc, a nie zgadywac. Reset opisuje linie
   nad naglowkiem tabeli lancuchem o mocy (0,2,4); nasze `.ntb-table th`
   ma (0,1,1) i przez to przegrywalo (K19).

   Zapora ma dwa pietra i wolno dokladac tylko do wlasciwego:
     A. WooCommerce trzyma barwy w zmiennych na :root - przepinamy ZMIENNE,
        raz, zamiast scigac selektory. To zamyka czerwien kasy (P23), fiolet
        przyciskow, zielen komunikatow i pomarancz ostrzezen naraz.
     B. Hello Elementor pisze barwy literalami, wiec tu trzeba lustra
        selektorow. Dopisujac nowe, SKOPIUJ lancuch z reset.css, nie skracaj.

   Sprawdzenie: node skrypty/zrzuty.mjs plus odczyt piksela przy krawedzi
   elementu. getComputedStyle nie wystarcza - pokazuje wartosc wyliczona
   dla elementu, a nie to, co narysowala sasiednia ramka. */

/* --- A. WooCommerce: przepiecie zmiennych barw na palete ------------------
   Wtyczka trzyma szesnascie barw w zmiennych na :root: czerwien bledu,
   ziel potwierdzenia, pomarancz ostrzezenia, blekit informacji, fiolet marki
   i cztery szarosci pomocnicze. Wartosci celowo NIE przepisujemy tutaj -
   literal spoza palety w naszym pliku to smiec, ktory qa_paleta.rb ma
   zglaszac, takze w komentarzu. Zrodlo: woocommerce/assets/css/woocommerce.css,
   pierwsza regula pliku. Zadnej z tych barw nie ma w naszej palecie.
   Stan bledu nie moze byc niesiony sama barwa (D07), wiec czerwien staje sie
   czernia, a odroznia ja GRUBOSC ramki - reguly ponizej, w pietrze B. */
:root {
	--woocommerce: var(--c-ink);
	--wc-green: var(--c-ink);
	--wc-red: var(--c-ink);
	--wc-orange: var(--c-ink);
	--wc-blue: var(--c-ink);
	--wc-primary: var(--c-ink);
	--wc-primary-text: var(--c-on-ink);
	--wc-secondary: var(--c-paper);
	--wc-secondary-text: var(--c-ink-2);
	--wc-highlight: var(--c-ink);
	--wc-highligh-text: var(--c-on-ink);
	--wc-content-bg: var(--c-bg);
	--wc-subtext: var(--c-ink-3);
	--wc-destructive: var(--c-ink);
	--wc-form-border-color: var(--c-control);
	--wc-form-border-radius: var(--r-0);
	--wc-card-border-radius: var(--r-0);
}

/* Pole odrzucone przez walidacje: po przepieciu zmiennej ramka jest juz
   czarna, ale czern to u nas takze stan skupienia i stan wypelniony, wiec
   sam kolor niczego nie mowi (P23: 7 pol oznaczonych WYLACZNIE barwa).
   Rozroznienie niesie grubosc - 2 px zamiast 1 px. Lancuch skopiowany
   z woocommerce.css, zeby moc byla rowna, plus nasza klasa .ntb-fields
   dla formularzy, ktore skladamy sami. */
.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select,
.woocommerce form .form-row.woocommerce-invalid textarea,
.ntb-fields .woocommerce-invalid input,
.ntb-fields .woocommerce-invalid select,
.ntb-fields .woocommerce-invalid textarea,
.ntb-fields [aria-invalid="true"] {
	border-color: var(--c-ink);
	border-width: var(--bw-heavy);
}

/* --- B. Hello Elementor: lustra selektorow z reset.css --------------------

   B1. Linia nad naglowkiem KAZDEJ tabeli (K19).
   Reset: `table thead:first-child tr:first-child th` z ramka gorna 1 px
   w polprzezroczystej szarosci (zapis hsl) - moc (0,2,4). Pomiar przed poprawka:
   odczyt piksela przy gornej krawedzi th dawal jasna szarosc spoza palety
   (polprzezroczysta szarosc resetu na bieli), przy dolnej --c-line z palety.
   Zasieg: 24 komorki th na 7 z 11 stron
   /rozmiary/, 3 na /dostawa-i-zwroty/ i 3 na kazdej karcie z rozmiarowka.
   Najpierw sprowadzamy barwe do palety wszedzie, potem zerujemy szerokosc
   tam, gdzie projekt linii nad naglowkiem nie ma. Drugi krok ma moc (0,3,4),
   wiec przebija reset o jedna klase. */
table caption + thead tr:first-child td,
table caption + thead tr:first-child th,
table colgroup + thead tr:first-child td,
table colgroup + thead tr:first-child th,
table thead:first-child tr:first-child td,
table thead:first-child tr:first-child th { border-block-start-color: var(--c-line); }

.ntb-table caption + thead tr:first-child th,
.ntb-table colgroup + thead tr:first-child th,
.ntb-table thead:first-child tr:first-child th,
.ntb-matrix__table caption + thead tr:first-child th,
.ntb-matrix__table colgroup + thead tr:first-child th,
.ntb-matrix__table thead:first-child tr:first-child th,
.ntbs-tabela__grid caption + thead tr:first-child th,
.ntbs-tabela__grid colgroup + thead tr:first-child th,
.ntbs-tabela__grid thead:first-child tr:first-child th { border-block-start-width: 0; }

/* B2. Reszta tabeli. `table tbody + tbody` to jedyna linia z resetu,
   ktorej nie obejmowala zapora z sekcji 27 (tam stoi `table td, table th`). */
table tbody + tbody { border-block-start-color: var(--c-line); }

/* B3. Podpis pod ilustracja. Reset daje `figcaption` ciemna szarosc spoza
   palety, 16 px i kursywe - moc (0,0,1). Kursywa nie jest kolorem, ale przez nia
   `figcaption.ntb-eyebrow` (schemat pomiaru na karcie produktu, uklad B)
   wychodzil pochyly mimo poprawnej klasy: nasza klasa ustawiala krój i stopien,
   a font-style zostawal z resetu. */
figcaption { color: inherit; font-style: normal; line-height: var(--lh-label); }

/* B3a. Interlinia z resetu. Poza barwa reset wnosi trzy wartosci interlinii,
   ktorych nie ma w naszych czterech tokenach: 1 na etykiecie, 1.5 na
   kontrolkach i na komorkach tabeli. Zmierzone na 15 adresach: 48 wezlow
   z 1 i 85 z 1.5 - czyli wiecej niz jakakolwiek nasza wartosc poza --lh-body.
   Etykieta dostaje --lh-label, bo przy 1 dwuwierszowa etykieta w kasie
   sklejala sie w jeden pas. */
label { line-height: var(--lh-label); }
button, input, optgroup, select, textarea { line-height: var(--lh-body); }
table td, table th { line-height: var(--lh-body); }

/* B4. Pola wpisywane. Reset daje kazdemu polu ramke 1 px w szarosci spoza
   palety i promien 3 px (moc 0,1,1), a przy skupieniu druga szarosc (0,2,1).
   Nasze komponenty opisuja swoje pola same, ale kazde pole POZA komponentem
   (formularz wtyczki, blok WordPressa, pole w tresci strony) dostawalo obie
   barwy spoza palety i promien, ktory w tym systemie zawsze wynosi zero. */
input[type="date"],
input[type="email"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="text"],
input[type="time"],
input[type="url"],
select,
textarea { border-color: var(--c-control); border-radius: var(--r-0); }

input[type="date"]:focus,
input[type="email"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="text"]:focus,
input[type="time"]:focus,
input[type="url"]:focus,
select:focus,
textarea:focus { border-color: var(--c-ink); }

/* --- Slad skupienia tam, gdzie pole jest przyciete do zera (S22) ----------
   Radio metody platnosci ma 1x1 px i clip-path: inset(50%), wiec outline
   z sekcji 3 rysuje sie wokol punktu przycietego do zera - zrzuty kafla
   z fokusem i bez mialy identyczny md5. Pierscien musi narysowac ETYKIETA.
   Wzorzec istnieje juz przy chipach rozmiaru (sekcja 26), tu tylko wraca
   do kasy. Stan ZAZNACZENIA niesie osobno czarne wypelnienie kafla,
   wiec te dwie rzeczy sie nie mieszaja. */
.ntb-pay__item:has(input:focus-visible),
.ntb-ship__opt:has(input:focus-visible),
.ntb-pay__item:has(input:focus),
.ntb-ship__opt:has(input:focus) {
	outline: var(--bw-heavy) solid var(--c-ink);
	outline-offset: 2px;
}

/* ==========================================================================
   27. Filtrowanie bez przeladowania: stan oczekiwania
   ==========================================================================
   Skrypt podmienia zawartosc #ntb-filters i .ntb-listing po pobraniu tej
   samej strony. Miedzy klikniecem a podmiana klient musi widziec, ze cos
   sie dzieje - inaczej klika drugi raz, a drugie zadanie przerywa pierwsze.
   Stan sygnalizujemy przezroczystoscia, nie kolorem: paleta zostaje zamknieta,
   a element pod spodem pozostaje czytelny. Kursor "progress" zamiast "wait":
   strona nadal reaguje, tylko listing jest w drodze.

   Odpowiedz przychodzi zwykle w 200-600 ms, wiec przejscie jest krotkie
   i bez opoznienia startu: przy tak szybkim cyklu opoznienie dawaloby
   migniecie zamiast plynnego wygaszenia. */

.is-filtering .ntb-listing,
.is-filtering #ntb-filters .ntb-filters__scroll {
  opacity: .55;
  transition: opacity 120ms ease-out;
  pointer-events: none;
}

.is-filtering .ntb-listing { cursor: progress; }

.ntb-listing,
#ntb-filters .ntb-filters__scroll { transition: opacity 160ms ease-in; }

@media (prefers-reduced-motion: reduce) {
  .is-filtering .ntb-listing,
  .is-filtering #ntb-filters .ntb-filters__scroll,
  .ntb-listing,
  #ntb-filters .ntb-filters__scroll { transition: none; }
}

/* ==========================================================================
   40) KONTO - powloka Moje konto (woocommerce/myaccount/*, inc/account.php)
   Boczna nawigacja 240 px od 1024 px, na telefonie przewijany pasek chipow.
   Karty z ramka hairline, kafle z liczba w Bodoni, wiersze zamowien.
   Zadnych kolorow funkcyjnych: status to ikona i ramka (D07).
   ========================================================================== */

.ntb-account-wrap { padding-bottom: var(--s-10); }
.ntb-account { display: grid; gap: var(--s-7); }
.ntb-account__main { min-width: 0; }

/* --- Nawigacja --- */
.ntb-anav__user { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ntb-anav__initials {
	display: inline-flex; align-items: center; justify-content: center; flex: none;
	width: 44px; height: 44px; border: var(--bw-hair) solid var(--c-ink); border-radius: var(--r-round);
	font-family: var(--f-display); font-size: var(--fs-600); line-height: 1; color: var(--c-ink);
}
.ntb-anav__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ntb-anav__who strong { font-size: var(--fs-400); font-weight: var(--fw-medium); color: var(--c-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ntb-anav__who span { font-size: var(--fs-200); color: var(--c-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ntb-anav__label { display: block; margin-bottom: var(--s-2); color: var(--c-ink-3); }
.ntb-anav ul { list-style: none; margin: 0; padding: 0; }
.ntb-anav__link {
	display: flex; align-items: center; gap: 12px; min-height: var(--touch);
	padding: 0 12px; margin-left: -12px; border-left: var(--bw-heavy) solid transparent;
	color: var(--c-ink-2); font-size: var(--fs-400); text-decoration: none;
	transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ntb-anav__link svg { flex: none; color: var(--c-ink-3); }
.ntb-anav__link:hover, .ntb-anav__link:focus-visible { color: var(--c-ink); background: var(--c-paper); }
.ntb-anav__link:hover svg, .ntb-anav__link[aria-current="page"] svg { color: var(--c-ink); }
.ntb-anav__link[aria-current="page"] { color: var(--c-ink); font-weight: var(--fw-medium); border-left-color: var(--c-ink); background: var(--c-paper); }
.ntb-anav__text { flex: 1 1 auto; min-width: 0; }
.ntb-anav__count { flex: none; font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-anav__link[aria-current="page"] .ntb-anav__count { color: var(--c-ink); }

@media (min-width: 1024px) {
	.ntb-account { grid-template-columns: 240px minmax(0, 1fr); gap: var(--s-9); align-items: start; }
	.ntb-account__nav { position: sticky; top: calc(var(--ntb-head-h) + var(--s-5)); }
	.ntb-anav__user { padding-bottom: var(--s-5); margin-bottom: var(--s-5); border-bottom: var(--bw-hair) solid var(--c-line); }
	.ntb-anav__group + .ntb-anav__group { margin-top: var(--s-5); }
}

/* Telefon i tablet: znak klienta w wierszu, grupy jako jeden przewijany
   pasek chipow. Etykiety grup zostaja dla czytnika (klip). */
@media (max-width: 1023px) {
	.ntb-account__nav { position: relative; margin-inline: calc(-1 * var(--pad-page)); padding-inline: var(--pad-page); border-bottom: var(--bw-hair) solid var(--c-line); }
	/* Znak klienta wraca na telefonie nad paskiem, jako osobny wiersz. */
	.ntb-account__nav::before { content: none; }
	.ntb-anav { display: flex; flex-wrap: nowrap; gap: 0; padding-bottom: var(--s-4); overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
	.ntb-anav::-webkit-scrollbar { display: none; }
	.ntb-anav__user { padding: var(--s-2) 0 var(--s-4); }
	.ntb-anav__group { display: contents; }
	.ntb-anav__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
	.ntb-anav ul { display: contents; }
	.ntb-anav__group ul li { display: inline-flex; margin: 0 var(--s-2) 0 0; }
	.ntb-anav__link { margin: 0; padding: 0 14px; border: var(--bw-hair) solid var(--c-line-2); border-radius: var(--r-0); white-space: nowrap; font-size: var(--fs-300); }
	.ntb-anav__link[aria-current="page"] { background: var(--c-ink); color: var(--c-on-ink); border-color: var(--c-ink); }
	.ntb-anav__link[aria-current="page"] svg, .ntb-anav__link[aria-current="page"] .ntb-anav__count { color: var(--c-on-ink); }
	.ntb-anav__link svg { width: 16px; height: 16px; }
}

/* --- Sekcje w kolumnie tresci --- */
.ntb-asec + .ntb-asec, .ntb-atiles + .ntb-asec, .ntb-asec + .ntb-atiles { margin-top: var(--s-8); }
.ntb-asec__head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-3) var(--s-5); padding-bottom: var(--s-4); margin-bottom: var(--s-5); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-asec__head > div:first-child { min-width: 0; flex: 1 1 320px; }
.ntb-asec__head .ntb-eyebrow { display: block; margin-bottom: var(--s-2); color: var(--c-ink-3); }
.ntb-asec__h { margin: 0; font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-800); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); color: var(--c-ink); }
.ntb-asec__h3 { margin: 0 0 var(--s-4); font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); line-height: var(--lh-snug); }
.ntb-asec__lead { margin: var(--s-2) 0 0; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-asec__act { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.ntb-asec__back { margin: var(--s-6) 0 0; }
.ntb-asec--hello .ntb-eyebrow { display: block; margin-bottom: var(--s-2); color: var(--c-ink-3); }
.ntb-asec__hello { margin: 0; font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-900); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); }
.ntb-aempty { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-6); padding: var(--s-5); background: var(--c-paper); }
.ntb-aempty p { flex: 1 1 320px; margin: 0; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }

/* --- Kafle liczbowe --- */
.ntb-atiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px; margin-top: var(--s-6); background: var(--c-line); }
.ntb-atile { display: flex; flex-direction: column; gap: 4px; min-height: 150px; padding: var(--s-4) var(--s-5); background: var(--c-bg); }
.ntb-atile__label { display: inline-flex; align-items: center; gap: 8px; margin-bottom: var(--s-2); font-family: var(--f-ui); font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .18em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-atile__label svg { color: var(--c-ink); }
.ntb-atile__value { font-family: var(--f-ui); font-size: var(--fs-850); font-weight: var(--fw-regular); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); color: var(--c-ink); font-variant-numeric: tabular-nums; }
.ntb-atile__note { font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-atile .ntb-link { margin-top: auto; padding-top: var(--s-3); }
@media (min-width: 768px) { .ntb-atiles { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1024px) and (max-width: 1279px) { .ntb-atiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* --- Status zamowienia: ikona i ramka, bez koloru --- */
.ntb-status { display: inline-flex; align-items: center; gap: 8px; min-height: 28px; padding: 0 10px; border: var(--bw-hair) solid var(--c-line-2); font-size: var(--fs-200); font-weight: var(--fw-medium); letter-spacing: .06em; text-transform: uppercase; color: var(--c-ink-2); white-space: nowrap; }
.ntb-status svg { flex: none; color: var(--c-ink); }
.ntb-status--done { border-color: var(--c-ink); color: var(--c-ink); }
.ntb-status--live { border-color: var(--c-ink); background: var(--c-ink); color: var(--c-on-ink); }
.ntb-status--live svg { color: var(--c-on-ink); }
.ntb-status--off { color: var(--c-ink-3); border-style: dashed; }
.ntb-status--lg { min-height: 36px; padding: 0 14px; font-size: var(--fs-300); }

/* --- Wiersze zamowien --- */
.ntb-orders { list-style: none; margin: 0; padding: 0; border-top: var(--bw-hair) solid var(--c-line); }
.ntb-order { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-2) var(--s-4); align-items: center; padding: 14px 0; border-bottom: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); }
.ntb-order__no { display: flex; flex-direction: column; gap: 2px; min-height: var(--touch); justify-content: center; color: var(--c-ink); text-decoration: none; }
.ntb-order__no .ntb-num { font-weight: var(--fw-medium); }
.ntb-order__no time { font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-order__no:hover .ntb-num { text-decoration: underline; text-underline-offset: 3px; }
.ntb-order__items { grid-column: 1 / -1; line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-order__total { justify-self: end; font-weight: var(--fw-medium); white-space: nowrap; }
.ntb-order__acts { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--s-2); }
.ntb-order .ntb-status { justify-self: start; }
.ntb-btn--sm { min-height: 40px; padding-inline: 14px; font-size: var(--fs-200); }
.ntb-apag { display: flex; gap: var(--s-3); margin-top: var(--s-5); }
@media (min-width: 900px) {
	.ntb-order { grid-template-columns: 150px minmax(0, 1fr) auto 130px; }
	.ntb-order__items { grid-column: auto; }
	.ntb-order__acts { grid-column: 2 / -1; justify-content: flex-end; }
	.ntb-orders--full .ntb-order { grid-template-columns: 150px minmax(0, 1fr) auto 130px; }
}

/* --- Terminy stajni --- */
.ntb-terms { list-style: none; margin: 0; padding: 0; border-top: var(--bw-hair) solid var(--c-line); }
.ntb-term { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--s-4); align-items: center; padding: 12px 0; border-bottom: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); }
.ntb-term__when { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-term__when svg { color: var(--c-ink); }
.ntb-term__what { font-weight: var(--fw-medium); color: var(--c-ink); }
.ntb-term__who { font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-term__date { justify-self: end; font-size: var(--fs-300); color: var(--c-ink-2); white-space: nowrap; }
.ntb-term--late .ntb-term__when { color: var(--c-ink); font-weight: var(--fw-medium); }
@media (min-width: 768px) { .ntb-term { grid-template-columns: 140px minmax(0, 1fr) minmax(0, 1fr) auto; } }

/* --- Karty (koń, jeździec, adres) --- */
.ntb-acards { display: grid; gap: var(--s-5); }
@media (min-width: 900px) { .ntb-acards { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.ntb-acard { border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); padding: var(--s-5); }
.ntb-acard--ink { border-color: var(--c-ink); }
.ntb-acard__head { display: flex; align-items: flex-start; gap: 12px; padding-bottom: var(--s-4); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-acard__head > svg { flex: none; margin-top: 4px; color: var(--c-ink); }
.ntb-acard__titles { flex: 1 1 auto; min-width: 0; }
.ntb-acard__title { margin: 0; font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-800); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); color: var(--c-ink); overflow-wrap: anywhere; }
.ntb-acard__meta { margin: 4px 0 0; font-size: var(--fs-300); line-height: var(--lh-label); color: var(--c-ink-3); }
.ntb-acard__tool { flex: none; display: inline-flex; align-items: center; justify-content: center; width: var(--touch); height: var(--touch); margin: -10px -10px 0 0; color: var(--c-ink-2); background: none; border: 0; cursor: pointer; }
.ntb-acard__tool:hover, .ntb-acard__tool:focus-visible { color: var(--c-ink); background: var(--c-paper); }
.ntb-acard__sec { margin-top: var(--s-4); }
.ntb-acard__sec > .ntb-eyebrow { display: block; margin-bottom: var(--s-2); color: var(--c-ink-3); }
.ntb-acard__note { margin: var(--s-3) 0 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-acard__acts { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-3); margin-top: var(--s-4); }

/* Wiersze definicji: etykieta po lewej, wartosc po prawej, hairline. */
.ntb-drows { margin: 0; }
.ntb-drows > div { display: flex; justify-content: space-between; gap: var(--s-4); padding: 11px 0; border-bottom: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); line-height: var(--lh-label); }
.ntb-drows dt { color: var(--c-ink-2); }
.ntb-drows dd { margin: 0; text-align: right; color: var(--c-ink); font-variant-numeric: tabular-nums; }
.ntb-drows__none { color: var(--c-ink-3); }
.ntb-drows--2 { display: grid; column-gap: var(--s-6); }
@media (min-width: 640px) { .ntb-drows--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Wyliczone rozmiary: chip system + wartosc. */
.ntb-asizes { margin-top: var(--s-4); padding: var(--s-4); background: var(--c-paper); }
.ntb-asizes > .ntb-eyebrow { display: block; margin-bottom: var(--s-3); color: var(--c-ink-3); }
.ntb-asizes__list { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; margin: 0; padding: 0; }
.ntb-sizechip { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-height: var(--touch); padding: 6px 12px; border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); }
.ntb-sizechip--edge { border-color: var(--c-ink); }
.ntb-sizechip__sys { font-size: var(--fs-100); letter-spacing: .1em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-sizechip__val { font-size: var(--fs-400); font-weight: var(--fw-medium); color: var(--c-ink); font-variant-numeric: tabular-nums; }
.ntb-asizes__note { margin: var(--s-3) 0 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }

/* --- Kafle objasnien (trzy, hairline miedzy) --- */
.ntb-ahints { display: grid; gap: 2px; margin-top: var(--s-7); background: var(--c-line); }
.ntb-ahint { display: flex; flex-direction: column; gap: 6px; padding: var(--s-4) var(--s-5); background: var(--c-bg); }
.ntb-ahint__h { display: flex; align-items: center; gap: 8px; margin: 0; font-size: var(--fs-400); font-weight: var(--fw-medium); color: var(--c-ink); }
.ntb-ahint__h svg { color: var(--c-ink); }
.ntb-ahint p { margin: 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
@media (min-width: 768px) { .ntb-ahints { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* --- Formularze konta: ta sama siatka co kasa --- */
.ntb-aform .ntb-fields { margin-top: var(--s-3); }
.ntb-aform__set { border: 0; margin: 0 0 var(--s-6); padding: 0; min-width: 0; }
.ntb-aform__set legend { padding: 0; color: var(--c-ink-3); }
.ntb-aform__acts { display: flex; flex-wrap: wrap; gap: var(--s-3); margin: var(--s-2) 0 0; }
.ntb-fields__help { font-size: var(--fs-200); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-account .ntb-fields .form-row-first, .ntb-account .ntb-fields .form-row-last { float: none; width: auto; }
.ntb-account .ntb-fields .optional { display: none; }
.ntb-account .ntb-fields .select2-container { width: 100% !important; }

/* --- Adresy --- */
.ntb-addr { display: grid; gap: var(--s-4); }
@media (min-width: 768px) { .ntb-addr { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ntb-addr__card { display: flex; flex-direction: column; gap: var(--s-4); padding: var(--s-5); border: var(--bw-hair) solid var(--c-line); }
.ntb-addr__head { display: flex; align-items: center; gap: 10px; }
.ntb-addr__head svg { color: var(--c-ink); }
.ntb-addr__h { margin: 0; font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); line-height: var(--lh-snug); }
.ntb-addr__body { flex: 1 1 auto; font-style: normal; font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-addr__none { color: var(--c-ink-3); }
.ntb-addr__card .ntb-btn { align-self: flex-start; }

/* --- Podglad zamowienia: tabele WooCommerce w rytmie sklepu --- */
.ntb-odetails .woocommerce-order-details__title, .ntb-odetails .woocommerce-column__title { margin: var(--s-6) 0 var(--s-4); font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); line-height: var(--lh-snug); }
.ntb-odetails .shop_table { width: 100%; border-collapse: collapse; font-size: var(--fs-400); }
.ntb-odetails .shop_table th, .ntb-odetails .shop_table td { padding: 12px 0; border-bottom: var(--bw-hair) solid var(--c-line); text-align: left; vertical-align: top; line-height: var(--lh-body); }
.ntb-odetails .shop_table thead th { font-size: var(--fs-100); font-weight: var(--fw-semibold); letter-spacing: .14em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-odetails .shop_table th:last-child, .ntb-odetails .shop_table td:last-child { text-align: right; white-space: nowrap; }
.ntb-odetails .shop_table tfoot th { font-weight: var(--fw-regular); color: var(--c-ink-2); }
.ntb-odetails .shop_table tfoot tr:last-child th, .ntb-odetails .shop_table tfoot tr:last-child td { font-weight: var(--fw-medium); color: var(--c-ink); font-size: var(--fs-500); }
.ntb-odetails .wc-item-meta { list-style: none; margin: 4px 0 0; padding: 0; font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-odetails .wc-item-meta li { display: inline; }
.ntb-odetails .wc-item-meta p { display: inline; margin: 0; }
.ntb-odetails .product-quantity { color: var(--c-ink-3); }
.ntb-odetails .woocommerce-columns { display: grid; gap: var(--s-5); }
@media (min-width: 768px) { .ntb-odetails .woocommerce-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ntb-odetails address { font-style: normal; font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-odetails .woocommerce-customer-details--phone, .ntb-odetails .woocommerce-customer-details--email { margin: 4px 0 0; }
.ntb-odetails .order-again, .ntb-odetails .ntb-stajnia__akcje { margin-top: var(--s-5); }
.ntb-onotes { list-style: none; margin: 0; padding: 0; }
.ntb-onote { padding: var(--s-3) 0; border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-onote__date { display: block; font-size: var(--fs-200); color: var(--c-ink-3); }
.ntb-onote__text { margin-top: 4px; font-size: var(--fs-400); line-height: var(--lh-body); }
.ntb-onote__text p { margin: 0; }

/* --- Panel administratora --- */
.ntb-admin { padding: var(--s-5); border: var(--bw-hair) solid var(--c-ink); }
.ntb-admin .ntb-atiles { margin-top: var(--s-4); }
.ntb-admin__h3 { margin: var(--s-6) 0 var(--s-3); font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-700); }
.ntb-admin__list { list-style: none; margin: 0; padding: 0; border-top: var(--bw-hair) solid var(--c-line); }
.ntb-admin__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px var(--s-4); align-items: center; padding: 10px 0; border-bottom: var(--bw-hair) solid var(--c-line); font-size: var(--fs-400); }
.ntb-admin__who { display: flex; flex-direction: column; min-width: 0; }
.ntb-admin__who span { font-size: var(--fs-200); color: var(--c-ink-3); overflow: hidden; text-overflow: ellipsis; }
.ntb-admin__horses { grid-column: 1 / -1; font-size: var(--fs-300); color: var(--c-ink-2); }
@media (min-width: 768px) { .ntb-admin__row { grid-template-columns: 260px minmax(0, 1fr) auto; } .ntb-admin__horses { grid-column: auto; } }
.ntb-admin-banner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-5); margin-bottom: var(--s-5); padding: 12px 14px; border: var(--bw-hair) solid var(--c-ink); font-size: var(--fs-300); }
.ntb-admin-banner svg { flex: none; }
.ntb-admin-banner p { flex: 1 1 260px; margin: 0; }

/* Komunikaty WooCommerce w koncie: pelna szerokosc kolumny tresci. */
.ntb-account__main > .woocommerce-message, .ntb-account__main > .woocommerce-info, .ntb-account__main > .woocommerce-error, .ntb-account__main > .woocommerce-notices-wrapper { margin-bottom: var(--s-5); }
/* Komunikat WooCommerce z przyciskiem (np. powiazanie wczesniejszych
   zamowien): tekst i przycisk w jednym wierszu, na telefonie pod soba. */
.ntb-account__main .woocommerce-info, .ntb-account__main .woocommerce-message { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3) var(--s-5); }
.ntb-account__main .woocommerce-info .button, .ntb-account__main .woocommerce-message .button { order: 2; margin-left: auto; }
@media (max-width: 767px) { .ntb-account__main .woocommerce-info .button, .ntb-account__main .woocommerce-message .button { flex: 1 1 100%; margin-left: 0; } }

/* ==========================================================================
   41) DAWKOWANIE - blok na karcie paszy/suplementu (ntb24-core/inc/dosing.php)
   Panel na papierze, dwie kolumny od 900 px: formularz masy | wynik w ramce.
   ========================================================================== */
.ntb-dosing__panel { padding: var(--s-5); border: var(--bw-hair) solid var(--c-line); background: var(--c-paper); }
.ntb-dosing__head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--s-3) var(--s-5); padding-bottom: var(--s-4); border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-dosing__head > div { flex: 1 1 320px; min-width: 0; }
.ntb-dosing__head .ntb-eyebrow { display: block; margin-bottom: var(--s-2); color: var(--c-ink-3); }
.ntb-dosing__h { margin: 0; font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-800); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); }
.ntb-dosing__note { margin: var(--s-2) 0 0; max-width: var(--w-text); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-dosing__pack { display: inline-flex; align-items: center; min-height: 28px; padding: 0 10px; border: var(--bw-hair) solid var(--c-line-2); font-size: var(--fs-200); letter-spacing: .06em; text-transform: uppercase; color: var(--c-ink-2); white-space: nowrap; }
.ntb-dosing__cols { display: grid; gap: var(--s-5); margin-top: var(--s-5); }
.ntb-dosing__form { display: grid; gap: var(--s-4); align-content: start; }
.ntb-dosing__field { display: grid; gap: 6px; }
.ntb-dosing__field label { font-size: var(--fs-200); letter-spacing: .08em; text-transform: uppercase; color: var(--c-ink-3); }
.ntb-dosing__input { display: flex; align-items: stretch; border: var(--bw-hair) solid var(--c-line-2); background: var(--c-bg); }
.ntb-dosing__input input { flex: 1 1 auto; min-width: 0; min-height: 48px; padding: 0 12px; border: 0; background: var(--c-bg); font: inherit; font-size: var(--fs-500); color: var(--c-ink); }
.ntb-dosing__input input:focus-visible { outline: 2px solid var(--c-ink); outline-offset: -2px; }
.ntb-dosing__input span { display: flex; align-items: center; padding: 0 12px; border-left: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-dosing__field .ntb-select { min-height: 48px; padding: 0 12px; border: var(--bw-hair) solid var(--c-line-2); background: var(--c-bg); font: inherit; font-size: var(--fs-400); color: var(--c-ink); }
.ntb-dosing__help, .ntb-dosing__fixed { margin: 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-dosing__form .ntb-btn { justify-self: start; min-height: 52px; }
.ntb-dosing__out { padding: var(--s-5); border: var(--bw-hair) solid var(--c-ink); background: var(--c-bg); }
.ntb-dosing__out .ntb-eyebrow { display: block; margin-bottom: var(--s-2); color: var(--c-ink-3); }
.ntb-dosing__value { display: block; font-family: var(--f-display); font-weight: var(--fw-regular); font-size: var(--fs-1000); line-height: var(--lh-tight); letter-spacing: var(--tr-tight); }
.ntb-dosing__value small { font-family: var(--f-ui); font-size: var(--fs-300); letter-spacing: .08em; text-transform: uppercase; color: var(--c-ink-3); margin-left: var(--s-2); }
.ntb-dosing__days { margin: var(--s-3) 0 0; font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink); }
.ntb-dosing__source { margin: var(--s-4) 0 0; padding-top: var(--s-3); border-top: var(--bw-hair) solid var(--c-line); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
@media (min-width: 900px) { .ntb-dosing__cols { grid-template-columns: minmax(0, 5fr) minmax(0, 4fr); align-items: start; } }

/* --- Filtr koloru: grupy z probka prawdziwej barwy (ntb24-core/inc/colors.php).
   Barwa probki to dane produktu (--ntb-sw z PHP), ramka i tekst zostaja w palecie. */
.ntb-fitem__swatch { background: var(--ntb-sw, var(--c-hatch)); border-color: var(--c-line-2); }
.ntb-fitem--kolor .ntb-fitem__box { width: 22px; height: 22px; }
.ntb-fitem--kolor.is-on .ntb-fitem__box { background: var(--ntb-sw, var(--c-ink)); border-color: var(--c-ink); box-shadow: inset 0 0 0 2px var(--c-bg); color: var(--c-on-ink); }
.ntb-fitem--kolor.is-on .ntb-fitem__box svg { filter: drop-shadow(0 0 1px var(--c-ink)); }
.ntb-fitem--kolor.is-empty .ntb-fitem__box { opacity: .35; }
.ntb-fitem--kolor:hover:not(.is-empty) .ntb-fitem__box { border-color: var(--c-ink); }
.ntb-fgroup__list--kolor { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-5); row-gap: 0; }
.ntb-fgroup__list--kolor li, .ntb-fgroup__list--kolor .ntb-fitem { min-width: 0; }
/* Etykieta koloru czyta sie w calosci: "Granat..." i "Pomaranc..." nie mowia,
   ktory to kolor, a to jedyna nazwa, jaka klient ma w tym filtrze. */
.ntb-fgroup__list--kolor .ntb-fitem__label { min-width: 0; overflow: visible; text-overflow: clip; white-space: normal; }
.ntb-fgroup__list--kolor .ntb-fitem__count { flex: none; margin-left: auto; padding-inline-end: var(--s-2); }
/* Ponizej 1440 px kolumna filtrow ma ok. 300 px - dwie kolumny kolorow
   sklejalyby licznik jednej z probka drugiej (zmierzone: 2 px odstepu). */
@media (max-width: 1439px) { .ntb-fgroup__list--kolor { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   42) SELECT - jeden wyglad kazdego pola wyboru w sklepie
   Natywny <select> Safari ignoruje ramke i wysokosc (zaokraglona ramka,
   strzalki w gore i w dol). Tu: to samo pudelko co pole tekstowe, chevron
   ze sprite'u jako maska w kolorze tekstu. Opakowanie .ntb-select (pasek
   narzedzi listy) zachowuje wlasny chevron SVG i wysokosc chipa.
   ========================================================================== */
.ntb-shell select:not([multiple]) {
	appearance: none;
	-webkit-appearance: none;
	min-height: var(--h-field);
	max-width: 100%;
	padding: 0 40px 0 12px;
	border: var(--bw-hair) solid var(--c-control);
	border-radius: var(--r-0);
	background-color: var(--c-bg);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230A0A0A' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); /* qa-ok: chevron w kolorze --c-ink z palety, zapis w data URI */
	background-position: right 12px center;
	background-repeat: no-repeat;
	background-size: 16px 16px;
	font: inherit;
	font-size: var(--fs-400);
	line-height: var(--lh-label);
	color: var(--c-ink);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	cursor: pointer;
}
.ntb-shell select:not([multiple]):focus-visible { border-color: var(--c-ink); outline: 2px solid var(--c-ink); outline-offset: -2px; }
.ntb-shell select:not([multiple]):disabled { color: var(--c-ink-3); background-color: var(--c-paper); cursor: default; }
.ntb-shell .ntb-select select { min-height: 0; padding-right: 32px; border: 0; background-image: none; font-size: var(--fs-300); }
.ntb-shell .ntb-select select:focus-visible { outline: none; }

/* Hamburger w naglowku mobilnym: widoczny tylko tam, gdzie znika przycisk
   "Wszystkie kategorie" (do 767 px). Otwiera to samo drzewo #ntb-tree. */
.ntb-tools__burger { display: none; }
@media (max-width: 767px) {
	.ntb-tools__burger { display: grid; }
	.ntb-tools { gap: 2px; }
}

/* ==========================================================================
   43) FILTRY - dopracowanie wizualne wg makiety "Archiwum kategorii v2"
   Tytuly grup zdaniowo, pogrubione (nie wersaliki); wiersze 14 px z licznikiem
   szarym tabularnym; szukajka i pola ceny w jednym pudelku co reszta pol;
   "Zastosuj cene" jako przycisk drugorzedny, nie czarny pas; ogon listy jako
   cichy odnosnik z chevronem. Nadpisuje sekcje "Kolumna filtrow".
   ========================================================================== */
.ntb-filters__head { align-items: center; padding-bottom: 12px; }
.ntb-filters__head h2 { font-family: var(--f-ui); font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .18em; text-transform: uppercase; color: var(--c-ink); }
.ntb-filters__head a { font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-filters__head a:hover { color: var(--c-ink); }

.ntb-fgroup { padding-block: 22px; }
.ntb-fgroup__head { align-items: center; gap: var(--s-2); margin-bottom: 12px; }
.ntb-fgroup__head h3 { font-family: var(--f-ui); font-size: var(--fs-400); font-weight: var(--fw-semibold); letter-spacing: 0; text-transform: none; line-height: var(--lh-label); color: var(--c-ink); }
.ntb-fgroup__toggle { width: 32px; height: 32px; margin-right: -6px; color: var(--c-ink-2); }
.ntb-fgroup__toggle:hover { color: var(--c-ink); }
.ntb-fgroup__link { font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-fgroup__note { margin-bottom: 12px; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }

.ntb-fgroup__search { height: 40px; margin-bottom: 12px; border-color: var(--c-line-2); background: var(--c-bg); }
.ntb-fgroup__search:hover { border-color: var(--c-control); }
.ntb-fgroup__search svg { color: var(--c-ink-3); }
.ntb-fgroup__search input { font-size: var(--fs-400); }
.ntb-fgroup__search input::placeholder { color: var(--c-ink-4); }
.ntb-fgroup__searchbtn { display: grid; place-items: center; border: 0; background: none; padding: 0; line-height: 0; color: var(--c-ink-3); }

.ntb-fgroup__list { gap: 2px; }
.ntb-fitem { gap: 12px; min-height: 32px; font-size: var(--fs-400); line-height: var(--lh-label); color: var(--c-ink-2); }
/* Probka koloru ma wlasne tlo z danych produktu (--ntb-sw), wiec nie moze
   dostac tla pola wyboru - inaczej cala paleta filtra jest biala. */
.ntb-fitem__box:not(.ntb-fitem__swatch) { background: var(--c-bg); }
.ntb-fitem__box { width: 16px; height: 16px; border-color: var(--c-control); transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
.ntb-fitem__box svg { width: 12px; height: 12px; }
.ntb-fitem__label { overflow-wrap: anywhere; }
.ntb-fitem__count { font-size: var(--fs-300); color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
.ntb-fitem:hover:not(.is-empty) { color: var(--c-ink); }
.ntb-fitem.is-on { color: var(--c-ink); }
.ntb-fitem.is-on .ntb-fitem__count { color: var(--c-ink); }
.ntb-fitem.is-empty { color: var(--c-ink-4); }
.ntb-fitem.is-empty .ntb-fitem__count { color: var(--c-ink-4); }

.ntb-fgroup__more {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 32px;
	margin-top: 8px;
	font-size: var(--fs-300);
	font-weight: var(--fw-medium);
	color: var(--c-ink-2);
	text-decoration: none;
	border-bottom: var(--bw-hair) solid var(--c-line-2);
}
.ntb-fgroup__more::after {
	content: "";
	width: 12px;
	height: 12px;
	background: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / 12px 12px no-repeat; /* qa-ok: maska, barwe daje currentColor */
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / 12px 12px no-repeat; /* qa-ok: maska, barwe daje currentColor */
}
.ntb-fgroup__more:hover { color: var(--c-ink); border-bottom-color: var(--c-ink); }
.ntb-fgroup__more[aria-busy="true"] { opacity: .5; }

/* Drzewo kategorii: wiersze 14 px, biezaca z kreska, dzieci wciete. */
.ntb-ftree { gap: 4px; font-size: var(--fs-400); }
.ntb-ftree a { min-height: 30px; color: var(--c-ink-2); }
.ntb-ftree a:hover { color: var(--c-ink); }
.ntb-ftree .is-current { color: var(--c-ink); }
.ntb-ftree .is-child { padding-left: 18px; }

/* Kafle rozmiaru: 44 x 36, czytelna liczba, stan wybrany czarny. */
.ntb-fgroup[data-style="tiles"] .ntb-fgroup__list { gap: 6px; }
.ntb-fgroup[data-style="tiles"] .ntb-fitem { min-width: 44px; min-height: 36px; padding-inline: 10px; font-size: var(--fs-300); color: var(--c-ink); }
.ntb-fgroup[data-style="tiles"] .ntb-fitem:hover:not(.is-empty) { border-color: var(--c-ink); }
.ntb-fgroup[data-style="tiles"] .ntb-fitem.is-empty { color: var(--c-ink-4); }

/* Cena: pola 44 px z jednostka, podpowiedz zakresu drobna i szara,
   przycisk drugorzedny (nie czarny pas), pelna szerokosc kolumny. */
.ntb-fprice__fields { gap: 8px; }
.ntb-fprice__fields input { height: 44px; padding-inline: 12px; border-color: var(--c-control); font-size: var(--fs-400); }
.ntb-fprice__fields input:focus-visible { border-color: var(--c-ink); }
.ntb-fprice__fields span { font-size: var(--fs-300); color: var(--c-ink-3); }
.ntb-fprice__hint { margin: 8px 0 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-fprice__submit,
.ntb-fprice .ntb-btn { margin-top: 12px; min-height: 44px; background: var(--c-bg); color: var(--c-ink); border-color: var(--c-ink); font-size: var(--fs-200); }
.ntb-fprice__submit:hover,
.ntb-fprice .ntb-btn:hover { background: var(--c-ink); color: var(--c-on-ink); box-shadow: none; }

/* Grupa koloru: tytul jak inne grupy, probki 20 px. */
.ntb-fitem--kolor .ntb-fitem__box { width: 20px; height: 20px; }

/* Arkusz (do 1023 px): wiersze 44 px (regula 3), tytul grupy wiekszy.
   Zakres 1023, nie 767, bo arkusz filtrow jest arkuszem takze na tablecie. */
@media (max-width: 1023px) {
	.ntb-fgroup { padding-block: 20px; }
	.ntb-fgroup[data-style="tiles"] .ntb-fitem { min-height: var(--touch); min-width: var(--touch); }
	.ntb-ftree a { min-height: var(--touch); }
	.ntb-fgroup__toggle { width: var(--touch); height: var(--touch); }
	.ntb-fgroup__head h3 { font-size: var(--fs-500); }
	.ntb-fitem { min-height: var(--touch); font-size: var(--fs-500); }
	.ntb-fitem__box { width: 18px; height: 18px; }
	.ntb-fgroup__search { height: var(--h-field); }
	.ntb-fgroup__more { min-height: var(--touch); }
	.ntb-fprice__fields input { height: var(--h-field); }
	.ntb-fprice__submit { min-height: var(--h-field); }
}

/* Pas tytulowy ze zdjeciem na telefonie: aspect-ratio z max-height
   przenosil ograniczenie na szerokosc (569 px przy 390 px ekranu) i strona
   przewijala sie w bok o 195 px. Proporcja zostaje, limit wysokosci znika. */
@media (max-width: 767px) { .ntb-cathead--media { min-height: 0; max-height: none; } }
/* Regula 3 na 390 px: select paska narzedzi i maly przycisk drugorzedny
   mialy 42 i 40 px - cel dotykowy ma 44 px. */
@media (max-width: 767px) {
	.ntb-select, .ntb-select select { min-height: var(--touch); }
	.ntb-btn--sm { min-height: var(--touch); }
}
@media (max-width: 767px) {
	.ntb-toolbar .ntb-select, .ntb-toolbar .ntb-select select, .ntb-select { height: auto; min-height: var(--touch); }
}
/* Obrys fokusa w kolumnie filtrow do wewnatrz: na zewnatrz ginal w overflow
   przewijanej kolumny i zostawaly dwie poziome kreski. */
.ntb-filters .ntb-fitem:focus-visible, .ntb-filters .ntb-fgroup__more:focus-visible, .ntb-filters .ntb-ftree a:focus-visible { outline-offset: -2px; }

/* Kolumna filtrow dluzsza niz ekran (po rozwinieciu grup) nie moze byc
   przyklejonym panelem z wlasnym przewijaniem: kolko myszy nad kolumna
   przewijalo tylko ja, a strona stala. Na duzym ekranie przewijanie zawsze
   przechodzi na strone (overscroll auto), a panel dluzszy niz okno traci
   przyklejenie i plynie razem z trescia (klasa nadaje ntb-filters.js;
   bez skryptu zostaje przyklejony panel z przewijaniem do konca i dalej
   strona). Arkusz na telefonie zachowuje contain - tam blokada jest celowa. */
@media (min-width: 1024px) {
	.ntb-filters__scroll { overscroll-behavior: auto; }
	.ntb-filters.is-long { position: static; max-height: none; }
	.ntb-filters.is-long .ntb-filters__scroll { flex: none; overflow: visible; }
}

/* Pas tytulowy ze zdjeciem: proporcja jest MINIMUM, nie sufitem. Wczesniej
   max-height 360 px i overflow hidden ucinaly drugi rzad chipow podkategorii
   (tresc 377 px w pasie 324 px na 1440 px). Zdjecie i przyciemnienie sa
   absolutne w calym pudelku, wiec bez overflow hidden nic nie wystaje. */
.ntb-cathead--media { overflow: visible; max-height: none; }
.ntb-cathead--media .ntb-cathead__img, .ntb-cathead--media .ntb-cathead__scrim { overflow: hidden; }
@media (min-width: 1200px) { .ntb-cathead--media { max-height: none; } }

/* Opis kategorii na calej szerokosci kolumny (decyzja wlasciciela 2026-09-09):
   jedna kolumna zamiast siatki opis | FAQ, akapity bez miary 33rem. */
.ntb-catcontent__grid { grid-template-columns: minmax(0, 1fr); }
.ntb-catcontent .ntb-prose > p, .ntb-catcontent .ntb-prose__rest p, .ntb-catcontent .ntb-prose__rest li, .ntb-catcontent .ntb-prose__rest h3, .ntb-catcontent .ntb-faq { max-width: none; }
.ntb-catcontent .ntb-prose > p, .ntb-catcontent .ntb-prose__rest p, .ntb-catcontent .ntb-prose__rest li { font-size: var(--fs-500); line-height: var(--lh-body); }
.ntb-catcontent .ntb-prose, .ntb-catcontent .ntb-prose__rest, .ntb-catcontent .ntb-prose__more { max-width: none; }
.ntb-catcontent__grid:has(> :last-child:nth-child(1)) { grid-template-columns: minmax(0, 1fr); }

/* ==========================================================================
   44) UKLAD - poprawki z audytu ulozenia tresci podstron (2026-09-09)
   ==========================================================================
   Audyt 66 podstron na 1920/1440/390 px (qa/audyt-uklad). Reguly stoja na
   koncu arkusza, bo poprawiaja wartosci z sekcji 4-31 i musza po nich
   wygrywac kolejnoscia, nie moca selektora. */

/* --- 44.1 Pas tytulowy na osi tresci ------------------------------------
   Pas mial wciecie 44 px, a tresc pod nim zaczynala sie na krawedzi
   kontenera: H1 i akapit wstepu staly na dwoch osiach (1920: x=330 i 284),
   a tlo pasa konczylo sie 40 px przed tlem stopki. Pas wychodzi na krawedz
   powloki jak stopka (ujemny margines o szerokosc marginesu strony),
   a tekst wraca na os kolumny. Wypelnienie pionowe rowne z obu stron. */
.ntb-cathead--type { margin-inline: calc(-1 * var(--pad-page)); }
.ntb-cathead--type .ntb-cathead__body { padding: var(--s-8) var(--pad-page); }
/* Przyciski akcji w pasie (showroom: "Umow wizyte" i telefon) - wczesniej
   staly osierocone pod pasem jako .ntb-empty__actions bez tresci. */
.ntb-cathead__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-6); }
.ntb-cathead__actions .ntb-btn { gap: 9px; }

/* --- 44.2 Pasek narzedzi listy ------------------------------------------
   W jednym rzedzie staly selecty 42 px i przycisk 52 px. Jedna wysokosc pola
   (48 px) dla wszystkich kontrolek; na telefonie dwa rowne pola w wierszu,
   przycisk "Zastosuj" na cala szerokosc pod nimi zamiast osieroconego
   w drugim wierszu przy lewej krawedzi. */
.ntb-toolbar { padding-block: 12px; }
.ntb-toolbar .ntb-select { min-height: var(--h-field); }
.ntb-toolbar .ntb-select select { min-height: calc(var(--h-field) - 2 * var(--bw-hair)); }
.ntb-toolbar__apply { min-height: var(--h-field); padding-block: 0; }
@media (max-width: 767px) {
	.ntb-toolbar { gap: var(--s-3); }
	.ntb-toolbar__count:empty { display: none; }
	.ntb-toolbar__tools { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); width: 100%; }
	.ntb-toolbar .ntb-select { width: 100%; min-width: 0; }
	.ntb-toolbar .ntb-select select { width: 100%; min-width: 0; }
	.ntb-toolbar__apply { grid-column: 1 / -1; width: 100%; }
}
/* Naglowek kolumny filtrow na wysokosci paska narzedzi: jego dolna linia
   pokrywa sie z dolna linia paska (obie 74 px od gory siatki). */
@media (min-width: 1024px) {
	.ntb-filters__head { box-sizing: border-box; min-height: calc(var(--h-field) + 24px + 2 * var(--bw-hair)); align-items: center; padding-bottom: 0; }
}

/* --- 44.3 Paginacja: cel 44 px na kazdej szerokosci, na osi listy -------- */
.woocommerce-pagination ul, .woocommerce nav.woocommerce-pagination ul { padding: 0; list-style: none; }
.woocommerce-pagination a, .woocommerce-pagination span,
.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span { min-width: var(--touch); min-height: var(--touch); height: auto; padding-inline: 12px; border-color: var(--c-line); }
.woocommerce-pagination span.current, .woocommerce nav.woocommerce-pagination ul li span.current { border-color: var(--c-ink); }

/* --- 44.4 Karta w petli: stan i cena na wspolnej dolnej linii rzedu ------
   Karta z dwoma rzedami chipow rozmiaru spychala cene o 60-150 px nizej niz
   w sasiednich kartach. Karta wypelnia komorke siatki, a blok stanu i ceny
   jest dosuniety do dolu. Cena "od-do" na 390 px zawija sie zamiast
   wychodzic poza kolumne. */
.ntb-listing ul.products li.product > .ntb-card, .ntb-grid > .ntb-card { flex: 1 1 auto; height: 100%; }
.ntb-card .ntb-avail { margin-top: auto; padding-top: 10px; }
.ntb-card__price { flex-wrap: wrap; row-gap: 0; }
@media (max-width: 479px) { .ntb-card__price { font-size: var(--fs-500); gap: 6px; } }

/* --- 44.5 Stan pusty jako skomponowany blok ------------------------------
   Goly tekst z dziura 148 px nad pierwsza linia i przyciskami "auto"
   o dwoch szerokosciach na telefonie. Blok ma rame i wypelnienie, akcje
   na cala szerokosc ponizej 600 px. Wariant --cta: pas na papierze z jednym
   zdaniem i para przyciskow (strony rozmiarow), zamiast dwoch przyciskow
   zawieszonych miedzy kafelkami a stopka. Koszyk ma wlasny sklad (sekcja 25). */
.ntb-empty:not(.ntb-cart *) { max-width: 640px; padding: var(--s-7) var(--s-7) var(--s-8); border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); }
.ntb-empty__actions { gap: var(--s-3); }
.ntb-empty.ntb-empty--cta { max-width: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-5) var(--s-8); padding: var(--s-6) var(--s-7); background: var(--c-paper); border-color: var(--c-line); }
.ntb-empty--cta .ntb-empty__lead { flex: 1 1 320px; margin: 0; max-width: var(--w-text); font-size: var(--fs-500); color: var(--c-ink-2); }
.ntb-empty--cta .ntb-empty__actions { margin-top: 0; }
@media (max-width: 599px) {
	.ntb-empty:not(.ntb-cart *) { padding: var(--s-5) var(--s-4) var(--s-6); }
	.ntb-empty.ntb-empty--cta { padding: var(--s-5) var(--s-4); }
	.ntb-empty__actions { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; }
	.ntb-empty__actions .ntb-btn { width: 100%; }
}

/* --- 44.6 Strony tekstowe z paragrafami (.ntb-legal) ---------------------
   Spis tresci byl golym <details> z trojkatem systemowym, a lista sekcji
   w tresci miala 16 px bez odstepow. Kolumna spisu 200-260 px, przyklejona;
   na telefonie wiersz 44 px z wlasna strzalka. Sam tekst zostaje na mierze
   .ntb-page__body / .ntb-prose. */
.ntb-legal .ntb-archive__grid { gap: var(--s-8) var(--s-9); }
.ntb-legal__toc { border-top: var(--bw-strong) solid var(--c-ink); padding-top: var(--s-3); }
.ntb-legal__toc summary { display: flex; align-items: center; justify-content: space-between; min-height: var(--touch); list-style: none; cursor: pointer; font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink); }
.ntb-legal__toc summary::-webkit-details-marker { display: none; }
.ntb-legal__toc summary::after { content: ""; width: 8px; height: 8px; margin: -4px 6px 0 0; border-right: var(--bw-hair) solid var(--c-ink); border-bottom: var(--bw-hair) solid var(--c-ink); transform: rotate(45deg); transition: transform var(--dur) var(--ease); }
.ntb-legal__toc details[open] summary::after { transform: rotate(-135deg); margin-top: 4px; }
.ntb-legal__toc ul { list-style: none; margin: 0; padding: 0; }
.ntb-legal__toc li { border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-legal__toc a { display: flex; align-items: center; gap: var(--s-3); min-height: var(--touch); padding: 10px 0; font-size: var(--fs-300); line-height: var(--lh-label); color: var(--c-ink-2); }
.ntb-legal__toc a:hover { color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }
.ntb-legal__num { flex: none; min-width: 2.25rem; color: var(--c-ink-3); font-variant-numeric: tabular-nums; }
@media (min-width: 1024px) {
	.ntb-legal .ntb-archive__grid { grid-template-columns: minmax(200px, 260px) minmax(0, var(--w-prose)); }
	.ntb-legal__toc { position: sticky; top: calc(var(--header-sticky-h) + var(--s-5)); }
	.ntb-legal__toc summary { pointer-events: none; }
	.ntb-legal__toc summary::after { display: none; }
}
.ntb-legal__body > h2 { margin: var(--s-9) 0 var(--s-4); font-size: var(--fs-800); line-height: var(--lh-tight); max-width: var(--w-prose); }
.ntb-legal__body > h2:first-child { margin-top: 0; }
.ntb-legal__body > h3 { margin: var(--s-6) 0 var(--s-2); font-size: var(--fs-600); }
.ntb-legal__body > h2 + p, .ntb-legal__body > h3 + p { margin-top: 0; }
.ntb-legal__body > ul, .ntb-legal__body > ol { margin-top: 14px; padding-left: 1.5rem; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-legal__body > ol { padding-left: 2rem; }
.ntb-legal__body li + li { margin-top: 8px; }
.ntb-legal__body li::marker { color: var(--c-ink-3); }

/* --- 44.9 Strony tekstowe: koniec z pustka po prawej ---------------------
   Zgloszenie wlasciciela z 5.10.2026: "wszystkie strony w stopce nie maja
   tresci na cala szerokosc sekcji". Pomiar przy oknie 1512 px, gdzie kanon
   .ntb-wrap ma 1 432 px (qa/proba/regulamin.html liczy to na zywo):

     /regulamin/, /polityka-prywatnosci/, /cookies/, /reklamacje/
         260 spis + 64 odstep + 760 tekst = 1 084 px, czyli 348 px pustki
     /dostawa-i-zwroty/
         760 px tresci w kolumnie 1 105,6 px, czyli 346 px pustki
     /wsparcie-dietetyczne/ i inne strony bez wlasnego szablonu
         528 px, czyli 904 px pustki - 63 procent kanonu

   Byly jedynym rodzajem widoku w sklepie, ktory nie dochodzil do prawej
   krawedzi. Lista kategorii (286 + 40 + 1 106), karta produktu (692 + 48 +
   692), koszyk i kasa (988 + 44 + 400) wypelniaja 1 432 px co do piksela.

   NIE zalatwia tego rozciagniecie zdania i to jest tu najwazniejsze.
   Kalibracja z linii 4897 (760 px = 97 znakow przy --fs-400) daje 7,8 px na
   znak, wiec cala kolumna 1 108 px to 138 znakow w wierszu wobec progu 85,
   ktory arkusz sam sobie postawil w linii 136. Zmierzone, nie oszacowane.

   Dlatego dwa rozne lekarstwa na dwie rozne strony:

   --prawna: dokument do czytania (regulamin ma dwadziescia paragrafow).
   Dostaje TRZECI TOR z panelem pomocy, a zdanie zostaje na mierze 41rem =
   656 px, czyli 84 znaki. 260 + 64 + 656 + 64 + 388 = 1 432 px, zero pustki
   przy mierze pod progiem. Lekarstwem na za waska kolumne jest dodanie
   kolumny, nie rozciagniecie zdania - ten sam wzorzec, co wstep strony
   rozmiarow ze zdjeciem obok (sekcja 53).

   --szeroka: krotka strona informacyjna i strona dostawy, gdzie tresci jest
   kilka akapitow, tabela i infografika. Tu nie ma czego wstawic w trzeci tor,
   wiec schodzi sufit i tresc bierze cala kolumne. To ta sama decyzja, co przy
   opisach kategorii z 9.09.2026 (sekcja wyzej) i przy ukladzie E karty
   produktu (linia 5784, "ta sama siatka co A-F").

   Na telefonie nic sie nie zmienia: przy 390 px kanon ma 358 px, czyli mniej
   niz kazda ze zdjetych i nalozonych miar, a panel pomocy jest trzecim
   dzieckiem siatki, wiec lada na koncu dokumentu. */

/* Krotka strona informacyjna: wszystko bierze kolumne. */
.ntb-page__body--szeroka > *,
.ntb-page__body--szeroka > p,
.ntb-page__body--szeroka > ul:not([class]),
.ntb-page__body--szeroka > ol:not([class]) { max-width: none; }
.ntb-page__body--szeroka.ntb-prose > p { max-width: none; }

/* Dokument prawny: struktura bierze kolumne, zdanie zostaje na 84 znakach. */
.ntb-page__body--prawna > * { max-width: none; }
.ntb-page__body--prawna > p,
.ntb-page__body--prawna > ul:not([class]),
.ntb-page__body--prawna > ol:not([class]),
.ntb-page__body--prawna.ntb-prose > p { max-width: 41rem; }
.ntb-legal__body > h2 { max-width: none; }

/* Panel pomocy w trzecim torze. Od 1280 px, nie od 1024: przy kanonie 944 px
   trzy tory zostawilyby tekstowi 260 px, czyli wrocilibysmy do usterki
   opisanej w page-legal.php - tresc w kolumnie spisu i wiersz lamany po
   trzydziestu znakach. Miedzy 1024 a 1279 px panel stoi POD tekstem w drugim
   torze, bo tor spisu ma tylko 260 px. */
.ntb-legal__card { padding: var(--s-5); border: var(--bw-hair) solid var(--c-line); background: var(--c-paper); }
.ntb-legal__card + .ntb-legal__card { margin-top: var(--s-4); }
.ntb-legal__card h2 { margin: 0 0 var(--s-2); font-family: var(--f-ui); font-size: var(--fs-200); font-weight: var(--fw-semibold); letter-spacing: .16em; text-transform: uppercase; color: var(--c-ink); }
.ntb-legal__card p { margin: 0; font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-legal__card ul { list-style: none; margin: 0; padding: 0; }
.ntb-legal__card li + li { margin-top: 6px; }
.ntb-legal__card a { display: inline-flex; align-items: center; min-height: var(--touch); font-size: var(--fs-300); color: var(--c-ink-2); }
.ntb-legal__card a:hover { color: var(--c-ink); text-decoration: underline; text-underline-offset: 3px; }

@media (min-width: 1024px) {
	.ntb-legal .ntb-archive__grid > .ntb-legal__aside { grid-column: 2; }
}

@media (min-width: 1280px) {
	.ntb-legal .ntb-archive__grid:has(> .ntb-legal__toc) { grid-template-columns: minmax(200px, 260px) minmax(0, 41rem) minmax(280px, 1fr); }
	.ntb-legal .ntb-archive__grid:has(> .ntb-legal__toc) > .ntb-legal__aside { grid-column: 3; grid-row: 1; position: sticky; top: calc( var(--header-sticky-h) + var(--s-5) ); }
	/* Bez naglowkow H2 nie ma spisu tresci, wiec tresc jest pierwszym
	   dzieckiem. Bez tej reguly wpadlaby w tor spisu szeroki na 260 px. */
	.ntb-legal .ntb-archive__grid:not(:has(> .ntb-legal__toc)) { grid-template-columns: minmax(0, 41rem) minmax(280px, 1fr); }
	.ntb-legal .ntb-archive__grid:not(:has(> .ntb-legal__toc)) > .ntb-legal__aside { grid-column: 2; grid-row: 1; }
}

/* --- 44.7 Karta produktu -------------------------------------------------- */
/* Rytm sekcji 80 px zamiast 96 (norma 72-80); sekcja "Zobacz tez" ma juz
   wlasne 32 px nad linia, wiec jej sekcja dostaje 48. */
body.single-product .ntb-section { padding-top: var(--s-10); }
body.single-product .ntb-section--tight { padding-top: var(--s-8); }
/* Opis z importu: listy 16 px, ciagi kropek rozpychajace kolumne (605 px na
   ekranie 390), naglowki w <strong> sklejone z trescia. Jedna miara i jeden
   stopien dla wszystkiego, co jest tekstem opisu. */
.ntb-pcols .ntb-prose { min-width: 0; overflow-wrap: anywhere; }
.ntb-pcols .ntb-prose :is(p, li) { max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-pcols .ntb-prose :is(ul, ol) { margin-top: 10px; padding-left: 1.25rem; max-width: var(--w-text); }
.ntb-pcols .ntb-prose li + li { margin-top: 4px; }
.ntb-pcols .ntb-prose :is(h2, h3, h4, h5) { margin: var(--s-6) 0 var(--s-2); font-family: var(--f-ui); font-size: var(--fs-300); font-weight: var(--fw-semibold); letter-spacing: .08em; text-transform: uppercase; color: var(--c-ink); }
.ntb-pcols .ntb-prose p > strong:first-child { color: var(--c-ink); }
.ntb-pcols .ntb-prose p:empty { display: none; }
.ntb-pcols .ntb-prose > :last-child { margin-bottom: 0; }
.ntb-pcols .ntb-prose table { width: auto; max-width: 100%; margin-top: 10px; border-collapse: collapse; font-size: var(--fs-400); }
.ntb-pcols .ntb-prose td, .ntb-pcols .ntb-prose th { padding: 6px 16px 6px 0; border-bottom: var(--bw-hair) solid var(--c-line); text-align: left; vertical-align: top; }
/* Lista "Specyfikacja" konczyla sie 28 px przed prawa krawedzia kolumny. */
.ntb-pcols .ntb-specs dd, .ntb-buy .ntb-specs dd { max-width: none; }
/* Uklad D (pasze, kosmetyki): galeria 300 px i kolumna informacji 1072 px
   z przyciskiem koszyka na 928 px. Galeria rosnie do 480 px, kolumna
   informacji konczy sie na 760 px - zdjecie opakowania jest w kadrze
   w calosci (contain), nie docinane do kwadratu. */
.ntb-product--aside > .ntb-gallery-col { flex: 1 1 320px; max-width: 480px; }
.ntb-product--aside > .ntb-buy { flex: 1 1 420px; max-width: 760px; }
.ntb-pcard--square .ntb-gallery__main img, .ntb-pcard--square .ntb-gallery__thumb img { object-fit: contain; }
/* Uklad E: hero wysrodkowane w 1040 px stalo na innej osi niz sekcje pod nim
   (po 189 px pustki z obu stron na 1920). Ta sama siatka co A-F. */
.ntb-pcard--narrow .ntb-product--narrow { max-width: none; margin-inline: 0; }
/* Kafle faktow (Waga brutto, Postac) mialy wciecie 16 px bez ramy, ktora by
   je tlumaczyla - teraz sa w ramie, jak inne panele. */
.ntb-tiles { border: var(--bw-hair) solid var(--c-line); }
/* "Przymierz w showroomie" lamalo sie na dwie linie w przycisku 52 px. */
.ntb-buy__second { flex: 0 1 auto; white-space: nowrap; }
/* Macierz kolor x rozmiar: tabela na 1416 px z kolumna koloru 680 px. */
.ntb-matrix__table { width: auto; min-width: min(100%, 640px); max-width: 100%; }
.ntb-matrix__table td { min-width: 96px; }
/* Tabela rozmiarowki bez bloku porownania: cala szerokosc, ale nie 1416 px. */
.ntb-sizing__grid:has(> :last-child:nth-child(1)) .ntb-table { max-width: 860px; }
/* Chipy rozmiaru: 8 px odstepu (siatka 4 px), a na waskim ekranie siatka
   po trzy w wierszu zamiast stalych 106 px i pustki po prawej. */
.ntb-sizes:not(.ntb-card__sizes) { gap: var(--s-2); }
@media (max-width: 479px) {
	.ntb-sizes--lg { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); }
	.ntb-sizes--lg .ntb-size { min-width: 0; width: 100%; }
}
/* Trzy mini-fakty pod galeria na 390 px: trzy w rzedzie, nie 2 + 1. */
@media (max-width: 767px) { .ntb-tile { flex: 1 1 100px; } }
/* Arkusz macierzy zamkniety jest poza ekranem, ale wciaz w przeplywie
   i drzewie dostepnosci; zamkniety ma byc niewidoczny takze dla czytnika. */
@media (max-width: 767px) {
	.ntb-matrix { visibility: hidden; transition: transform var(--dur) var(--ease), visibility 0s linear var(--dur); }
	.ntb-matrix:target { visibility: visible; transition-delay: 0s; }
}
/* Dawkowanie bez pola masy: dwie kolumny zostawialy 750 x 200 px pustki
   obok jednego zdania. Jedna kolumna, karta wyniku 560 px, zdanie pod nia. */
.ntb-dosing__cols--staly, .ntb-dosing__cols--staly.ntb-dosing__cols { grid-template-columns: minmax(0, 1fr); }
.ntb-dosing__cols--staly .ntb-dosing__form { order: 2; }
.ntb-dosing__cols--staly .ntb-dosing__out { max-width: 560px; }
@media (min-width: 900px) { .ntb-dosing__cols--staly.ntb-dosing__cols { grid-template-columns: minmax(0, 1fr); } }

/* --- 44.8 Naglowek: blok telefonu i dostawy na prawej osi kontenera ------ */
.ntb-header__top .ntb-service { margin-left: auto; }
.ntb-search input { text-overflow: ellipsis; }

/* --- 44.9 Strona glowna, stopka, telefon --------------------------------- */
@media (max-width: 767px) {
	/* Linki stopki: krok 44 px zamiast 54 (cel dotykowy zachowany). */
	.ntb-footer ul { gap: 0; }
	.ntb-footer ul a { display: flex; align-items: center; min-height: var(--touch); }
	/* Odstep pas tytulowy -> tresc 40 px zamiast 64 na telefonie. */
	.ntb-section--tight { padding-top: var(--s-7); }
	.ntb-search input { font-size: var(--fs-400); }
	/* Siatka kafli tekstowych (dzialy w stanie pustym, showroom) na 390 px:
	   inline --cols:4 wygrywal z regula progu; kafle tekstowe w jednej
	   kolumnie, produkty w dwoch. */
	.ntb-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.ntb-grid:has(> .ntb-usp) { grid-template-columns: minmax(0, 1fr); gap: var(--s-5); }
	.ntb-grid > .ntb-usp { display: flex; flex-direction: column; }
	.ntb-grid > .ntb-usp .ntb-link { margin-top: auto; padding-top: 14px; }
}

/* --- 44.10 Marki: skorowidz w przeplywie kolumnowym ----------------------
   Siatka 3 kolumn grup literowych wyrownywala rzedy do najdluzszej grupy
   (dziury po 300-430 px, lista 3 583 px). Przeplyw kolumnowy wypelnia
   kolumny po kolei; na telefonie dwie kolumny pozycji z linia w wierszu. */
.ntb-catlinks--alpha { display: block; columns: 4 220px; column-gap: var(--s-8); }
.ntb-catlinks--alpha .ntb-alpha__group { break-inside: avoid; margin-bottom: var(--s-7); }
.ntb-catlinks--alpha ul { margin-top: var(--s-3); }
@media (max-width: 1023px) { .ntb-catlinks ul { gap: 0; } }
@media (max-width: 767px) {
	.ntb-catlinks--alpha { columns: 1; }
	.ntb-catlinks--alpha ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s-4); }
	.ntb-catlinks--alpha li a { width: 100%; min-height: var(--touch); border-bottom: var(--bw-hair) solid var(--c-line); text-decoration: none; }
}

/* --- 44.11 Poradnik: linie z ramek, nie z tla siatki ---------------------
   Jedenascie kafli w trzech kolumnach zostawialo pusta komorke, ktora
   odslaniala tlo siatki jako wypelniony prostokat 470 x 134 px. */
.ntb-guides__grid { gap: 0; background: none; border-top: var(--bw-hair) solid var(--c-line); border-left: var(--bw-hair) solid var(--c-line); }
.ntb-guide { border-right: var(--bw-hair) solid var(--c-line); border-bottom: var(--bw-hair) solid var(--c-line); }

/* --- 44.12 Showroom, kontakt, logowanie ----------------------------------- */
/* Kroki przymiarki siodla w kolumnie obok formularza wizyty. */
.ntb-steps { display: grid; gap: var(--s-5); margin-top: var(--s-6); }
.ntb-steps .ntb-usp { padding-top: 18px; }
.ntb-steps .ntb-usp__p { margin-top: 8px; }
.ntb-pcols .ntb-eyebrow + h2 { margin-top: 10px; }
.ntb-pcols .ntb-sizing__note { max-width: var(--w-text); }
/* Logowanie: dwa panele w jednej ramie z linia miedzy nimi, rejestracja
   na papierze; wczesniej kolumny 420 i 568 px z rynsztokiem 312 px. */
.ntb-panels { display: flex; flex-wrap: wrap; gap: var(--bw-hair); padding: 0; border: var(--bw-hair) solid var(--c-line); background: var(--c-line); }
.ntb-panels > div { flex: 1 1 400px; min-width: 0; padding: var(--s-8); background: var(--c-bg); }
.ntb-panels > div:last-child { background: var(--c-paper); }
.ntb-panels .ntb-usp__p, .ntb-panels .ntb-specs, .ntb-panels .ntb-sizing__note, .ntb-panels .ntb-notice { max-width: 480px; }
.ntb-panels .ntb-specs { margin-top: var(--s-5); }
@media (max-width: 599px) { .ntb-panels > div { padding: var(--s-5) var(--s-4); } }
/* Blok z <pre> tlumacza (opis produktu z importu): zwykly tekst, lamanie wierszy jak w akapicie. */
.ntb-pcols .ntb-prose .ntb-prose__blok { margin-top: 14px; max-width: var(--w-text); font: inherit; font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); white-space: normal; }
.ntb-pcols .ntb-prose .ntb-prose__blok br + br { display: block; content: ""; margin-top: 10px; }

/* Pasek "Rozumiemy to jako" (ntb24-search) wchodzi do siatki wynikow jako
   trzecie dziecko przed listingiem, wiec listing spadal do drugiego rzedu
   w kolumnie filtrow (283 px, karty po 53 px). Pasek zajmuje caly pierwszy
   rzad, filtry i listing wracaja do swoich kolumn. */
.ntb-archive__grid > .ntb-understand { grid-column: 1 / -1; order: -1; }
/* Blok "Nic nie pasuje" wtyczki (.ntb-noresults) i listing zawsze w kolumnie
   listy; przy zerze wynikow pasek sortowania pod blokiem nie ma czego sortowac.
   TYLKO od 1024 px: nizej siatka ma JEDNA kolumne (filtry sa arkuszem od dolu),
   wiec "grid-column: 2" tworzylo pusta kolumne 0 px i odstep 40 px, a cala lista
   jechala o 40 px w prawo (karty 151 zamiast 171 px na kazdej stronie kategorii,
   sklepu i wynikow - zmierzone na 390 px). */
@media (min-width: 1024px) {
	.ntb-archive__grid > .ntb-noresults, .ntb-archive__grid > .ntb-listing { grid-column: 2; }
}
.ntb-archive__grid > .ntb-noresults + .ntb-listing > .ntb-toolbar { display: none; }

/* ==========================================================================
   45) OBRAZY - kadry z audytu PLIKI-GRAFICZNE.md (Etap 4)
   ========================================================================== */
/* Kadr hero strony glownej: wysokosc 552 px od 1200 px, nizej proporcja
   z tokenow (ta sama co pas ze zdjeciem), wiec placeholder i zdjecie maja
   jedna wysokosc i nie ma przeskoku po zaladowaniu. */
.ntb-frame--hero { min-height: 552px; }
@media (max-width: 1199px) { .ntb-frame--hero, .ntb-ph--hero { min-height: 0; aspect-ratio: var(--ar-hero-t); } }
@media (max-width: 767px) { .ntb-frame--hero, .ntb-ph--hero { aspect-ratio: var(--ar-hero-m); } }
/* Oryginal wezszy niz 600 px stoi w kadrze w calosci zamiast byc rozciagany. */
.ntb-img--small { object-fit: contain; background: var(--c-bg); }

/* --- Infografiki (docs/INFOGRAFIKI.md): SVG inline, szerokosc kolumny, wysokosc z viewBox --- */
.ntb-infografika { margin: var(--s-6) 0 0; max-width: 560px; }
.ntb-infografika svg { display: block; width: 100%; height: auto; }
.ntb-infografika__caption { margin-top: var(--s-3); font-size: var(--fs-300); line-height: var(--lh-body); color: var(--c-ink-3); }
.ntb-page__body > .ntb-infografika { max-width: 560px; }
.ntb-infografika--kroki { margin-top: var(--s-5); max-width: 480px; }
.ntb-infografika--konto { margin: var(--s-5) 0 0; max-width: 480px; }

/* Skala szerokosci pyska (uklad B) na telefonie: wybrany segment rosl do 239 px
   (flex 1.25 z sekcji 26 wygrywal z flex 0 0 auto z sekcji 29), a pozostale
   mialy 46 px - szerokosc samej etykiety. Segmenty dziela tor po rowno,
   wybrany o cwierc szerszy; przy wielu rozmiarach tor dalej przewija sie w bok. */
@media (max-width: 767px) {
	.ntb-scale__step { flex: 1 1 0; min-width: 52px; }
	input[type="radio"]:checked + .ntb-scale__step,
	.ntb-scale__step[aria-pressed="true"] { flex: 1.25 1 0; min-width: 60px; }
}

/* ==========================================================================
   46) PO PRZEGLADZIE REGRESJI (2026-09-10)
   ========================================================================== */

/* --- 46.1 Infografiki: rysunek w skali tekstu strony ----------------------
   Pliki SVG maja viewBox 343 px (projekt mobile-first, tekst 12-13 px), a max-width
   560 px skalowal je 1,63x - podpisy renderowaly sie po 19-21 px przy tekscie strony
   13-14 px i rysunek czytal sie jak powiekszona grafika telefonu (zmierzone na
   /dostawa-i-zwroty/ i /rozmiary/*). 400 px to skala 1,17x, czyli tekst 14 px:
   tyle samo, co Archivo w kolumnie obok. */
.ntb-infografika { max-width: 400px; }
.ntb-infografika--modal, .ntb-infografika--kroki, .ntb-infografika--konto { max-width: 400px; }
.ntb-page__body > .ntb-infografika { max-width: 400px; }

/* Rysunek OBOK tekstu, nie pod nim: schemat stal sam w kolumnie 1416 px
   i zostawial 870-950 px pustki, a rzad chipow rozmiaru odrywal sie od swojego
   naglowka o 476 px. Od 1024 px sekcja osi rozmiaru jest dwukolumnowa:
   naglowek, opis i chipy po lewej, schemat po prawej. */
@media (min-width: 1024px) {
	.ntb-section--tight:has(> .ntb-infografika--os), .ntb-sysaxis:has(> .ntb-infografika--os) {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(300px, 400px);
		column-gap: var(--s-8);
		align-items: start;
	}
	.ntb-section--tight > .ntb-infografika--os, .ntb-sysaxis > .ntb-infografika--os { grid-column: 2; grid-row: 1 / span 3; margin-top: 0; }
	.ntb-section--tight:has(> .ntb-infografika--os) > :not(.ntb-infografika--os), .ntb-sysaxis:has(> .ntb-infografika--os) > :not(.ntb-infografika--os) { grid-column: 1; }
}

/* --- 46.2 Strony prawne: lista z paragrafami ma znaczniki ------------------
   Wciecie 24/32 px bez znacznika (globalne list-style:none) czytalo sie jak
   niedokonczona lista. */
.ntb-legal__body ul { list-style: disc outside; }
.ntb-legal__body ol { list-style: decimal outside; }
.ntb-legal__body :is(ul, ol) ul { list-style: circle outside; }

/* --- 46.3 Logowanie: panele bez pustej bieli -------------------------------
   Rama obejmowala obie kolumny, wiec krotszy panel logowania miał ok. 200 px
   bialej pustki pod ostatnim linkiem. Kolumny konczą sie na tresci, a papier
   drugiej kolumny wypelnia rame. */
.ntb-panels { align-items: stretch; background: var(--c-paper); }
.ntb-panels > div { align-self: stretch; }
@media (max-width: 799px) { .ntb-panels > div { border-bottom: var(--bw-hair) solid var(--c-line); } }

/* --- 46.4 Pusty koszyk: odstep do stopki 80 px zamiast 143 px -------------- */
.ntb-cart--empty .ntb-empty > :last-child { margin-bottom: 0; }
.ntb-cart--empty { padding-bottom: 0; }

/* --- 46.5 Miara zdania w panelach i notach ---------------------------------
   Zdania, ktore po zmianie ukladu dostaly cala szerokosc kolumny: nota
   dawkowania (1 366 px na 1920), nota macierzy kolor x rozmiar i przypis
   o jednostce pomiaru. Zdanie czyta sie do ok. 85 znakow. */
.ntb-dosing__fixed, .ntb-dosing__help, .ntb-matrix__note, .ntb-sizing__note, .ntbs-uwaga { max-width: var(--w-text); }
/* Odnosniki w bloku "Zobacz tez" byly polami szerokimi na cala kolumne,
   choc tekst zajmowal jedna trzecia. */
.ntb-catlinks a { display: inline-block; width: max-content; max-width: 100%; }

/* --- 46.6 Kontrolki WooCommerce, ktore zostaly ponizej celu dotykowego -----
   Zmierzone na 390 px: przycisk "Pokaż hasło" w danych konta 22x22 px, pole
   kodu rabatowego 42 px. Oba rysuje WooCommerce, wiec ida tutaj razem z reszta
   obcego markupu. */
.woocommerce form .show-password-input,
.woocommerce-page form .show-password-input {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: var(--touch);
	min-height: var(--touch);
	top: 50%;
	transform: translateY(-50%);
	right: 2px;
}
.woocommerce .coupon input#coupon_code,
.woocommerce-page .coupon input#coupon_code { min-height: var(--h-field); }

/* --- 46.7 Ostatnie cele dotykowe ponizej 44 px na 390 px -------------------
   Pole ilosci w koszyku mialo 38 px (przyciski plus i minus juz maja 44 px
   przez ::before). Odnosniki w opisie kategorii maja 22 px wysokosci: pole
   dotyku rosnie paddingiem i wraca ujemnym marginesem, wiec wiersz tekstu
   nie zmienia wysokosci, a palec ma pelne 44 px. */
@media (max-width: 1023px) {
	.ntb-qty--cart input { min-height: var(--touch); }
	.ntb-catcontent p a, .ntb-prose__rest p a, .ntb-prose__rest li a { padding-block: 13px; margin-block: -13px; }
}

/* --- 46.8 Zdania, ktore dostawaly cala szerokosc kolumny ------------------
   Zmierzone na 1920 px: komunikat koszyka 1 356 px, ostrzezenie o braku
   rozmiaru 760 px, wyjasnienie rozmiaru w koncie 881 px. Zdanie czyta sie
   do ok. 85 znakow niezaleznie od tego, kto je wypisuje. */
.woocommerce-error li, .woocommerce-message li, .woocommerce-info li { max-width: var(--w-text); }
.ntb-warn > span, .ntb-warn p, .ntb-asizes__note { max-width: var(--w-text); }

/* --- 46.9 Miara zdania w pozostalych blokach ------------------------------
   Zmierzone na 1920 px: stan pusty powiadomien 911 px, stan pusty zakupow
   cyklicznych 892 px, nota o punkcie odbioru w kasie 644 px, zajawka kafla
   systemu rozmiarow 847 px, podpis schematu pomiaru 594 px. */
.ntb-ship__note, .ntb-stajnia__pusto p,
.ntb-account__main > p, .woocommerce-MyAccount-content > p { max-width: var(--w-text); }

/* --- 46.10 Filtr koloru: probka pokazuje kolor, nie biale pole -------------
   Regula tla pol wyboru z sekcji 43 stala PO regule probki i zamalowywala ja
   na bialo, wiec filtr koloru czytal sie jak lista tekstowa. Kolor probki
   jest dana produktu i przychodzi z PHP w --ntb-sw. */
.ntb-fitem__swatch { background: var(--ntb-sw, var(--c-hatch)); border-color: var(--c-line-2); }
.ntb-fitem--kolor.is-on .ntb-fitem__box { background: var(--ntb-sw, var(--c-ink)); }

/* ==========================================================================
   47) PO PRZEGLADZIE 36 PODSTRON (2026-09-10)
   ========================================================================== */

/* --- 47.1 Odnosniki pod opisem kategorii: pola dotyku nie nachodza na siebie
   Regula "gap: 0" byla pisana dla skorowidzu marek (dwie kolumny z linia
   w wierszu), ale lapala takze bloki "Marki w kategorii" i "Powiazane
   kategorie". Z polem dotyku 48 px i podzialka 22 px sasiednie odnosniki
   nachodzily na siebie o 26 px - palec trafial w sasiada. */
@media (max-width: 1023px) {
	.ntb-catlinks:not(.ntb-catlinks--alpha) ul { gap: var(--s-2); }
	.ntb-catlinks:not(.ntb-catlinks--alpha) a {
		display: flex;
		align-items: center;
		min-height: var(--touch);
		width: max-content;
		max-width: 100%;
	}
}

/* --- 47.2 Macierz kolor x rozmiar wypelnia swoj kafel ---------------------
   Ograniczenie szerokosci tabeli (min-width: min(100%, 640px)) mialo zwezic
   kolumne koloru, a zwezilo cala tabele do 640 px w kaflu 1 376 px: obok
   zostawal pusty prostokat papieru 800 x 491 px. Kolumne koloru trzyma teraz
   jej wlasna szerokosc, a tabela zajmuje kafel. */
.ntb-matrix__table { width: 100%; min-width: 0; max-width: none; }
.ntb-matrix__table th, .ntb-matrix__table td { max-width: none; }
.ntb-matrix__table thead th:first-child, .ntb-matrix__table tbody th { width: 260px; }

/* --- 47.3 Opis produktu: jedna skala pisma w calym bloku ------------------
   Normalizacja lapala tylko <p> i <li>, a tekst wklejony bez znacznika (czesc
   opisow z importu) zostawal na 16 px obok akapitow 14 px. Srodtytul zapisany
   jako <strong> na poczatku akapitu przyklejal sie do poprzedniego wiersza. */
.ntb-pcols .ntb-prose { font-size: var(--fs-400); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-pcols .ntb-prose p > strong:first-child { display: block; margin-top: var(--s-6); }
.ntb-pcols .ntb-prose > :first-child > strong:first-child { margin-top: 0; }

/* --- 47.4 Drugi przycisk zakupu na telefonie ------------------------------
   "Popros o dobor" mial 216 px obok pelnoszerokiego przycisku glownego. */
@media (max-width: 640px) {
	.ntb-buy__form .ntb-btn, .ntb-buy__second { width: 100%; justify-content: center; }
}

/* --- 47.5 Kasa: imie i nazwisko na cala szerokosc swojej kolumny ----------
   Dwie kolumny daje juz siatka .ntb-fields; procenty WooCommerce (47%)
   zostawialy obok kazdego pola ok. 254 px pustki, a e-mail nizej szedl
   na pelna szerokosc. Ten sam wyjatek mialo juz konto. */
.ntb-checkout .ntb-fields .form-row-first,
.ntb-checkout .ntb-fields .form-row-last,
.ntb-checkout .ntb-fields .form-row-wide { float: none; width: auto; }

/* --- 47.6 Cena promocyjna nie jest odnosnikiem ----------------------------
   WooCommerce wstawia cene po obnizce w <ins>, a przegladarka podkresla ten
   znacznik domyslnie: kafel pokazywal dwie "skreslone" liczby obok siebie. */
.ntb-card__price ins, .ntb-buy__price ins, .woocommerce ins { text-decoration: none; background: none; color: inherit; }

/* --- 47.7 Filtr koloru: dwie kolumny z prawdziwym odstepem ----------------
   Regula .ntb-fgroup__list { gap: 2px } z sekcji 43 stala w arkuszu po regule
   listy kolorow i sklejala kolumny: licznik jednej konczyl sie 2 px przed
   probka drugiej. Ta regula stoi na koncu, wiec zadna pozniejsza jej nie
   przykryje. */
/* Jedna kolumna w bocznej kolumnie filtrow: ma ona ok. 283 px, wiec dwie
   kolumny lamaly polskie nazwy w polowie slowa ("Niebie / ski",
   "Pomara / nczowy"). Dwie kolumny zostaja w arkuszu filtrow na telefonie,
   gdzie panel jest na cala szerokosc. */
.ntb-fgroup__list--kolor { grid-template-columns: minmax(0, 1fr); column-gap: var(--s-5); row-gap: 0; }
@media (max-width: 1023px) {
	/* W arkuszu na telefonie panel jest na cala szerokosc, wiec mieszcza sie
	   dwie kolumny; przy odstepie 24 px dwie najdluzsze nazwy lamaly sie
	   w polowie ("Pomaranczo / wy"), wiec odstep schodzi do 12 px. */
	.ntb-fgroup__list--kolor { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-3); }
}

/* --- 47.8 Menu konta na telefonie: widac wszystkie pozycje ----------------
   Pasek chipow przewijany w bok pokazywal 3 z 9 pozycji, ucinal sie na
   krawedzi ekranu i nie przewijal sie do pozycji biezacej: na /konto/edit-
   address/ i /konto/powiadomienia/ klient nie widzial, gdzie jest. Chipy
   zawijaja sie teraz do kolejnych wierszy - caly spis konta jest na oczach,
   bez przewijania i bez JavaScriptu. */
@media (max-width: 1023px) {
	.ntb-anav { flex-wrap: wrap; gap: var(--s-2); overflow-x: visible; }
	.ntb-anav__group ul li { margin: 0; }
	.ntb-anav__link { min-height: var(--touch); }
}

/* --- 47.9 Odnosniki w zdaniach kasy ---------------------------------------
   "regulamin", "polityke prywatnosci" i "Zaloguj sie" mialy 16 px wysokosci.
   Pole dotyku rosnie paddingiem i wraca ujemnym marginesem, wiec wiersz
   tekstu nie zmienia wysokosci. Szerokosc zostaje szerokoscia slowa -
   odnosnika w zdaniu nie da sie rozciagnac bez rozerwania wiersza. */
@media (max-width: 1023px) {
	.ntb-check__label a,
	.ntb-step__aside a,
	.woocommerce-privacy-policy-text a,
	.woocommerce-form-login-toggle a,
	.woocommerce-info a { padding-block: 14px; margin-block: -14px; }
}

/* --- 48. Poziome przewijanie tabel: kontener musi byc blokiem pozycjonujacym --
   Tabela dostepnosci i tabele rozmiarow chowaja szerokosc w kontenerze
   z overflow-x: auto. Kontener byl jednak position: static, wiec elementy
   .ntb-sr wewnatrz komorek - a takze <caption class="ntb-sr"> - liczyly swoje
   polozenie wzgledem strony, nie wzgledem kontenera, i NIE podlegaly jego
   przycinaniu. Przy popregu Sheepskin Girth (4 kolory na 14 dlugosci) dawalo to
   1616 px zawartosci na 1440 px okna: strona przewijala sie w bok o 176 px,
   choc sama tabela byla przycieta poprawnie.

   position: relative nie zmienia wygladu - .ntb-sr nie ma przesuniec - a robi
   z kontenera blok pozycjonujacy, wiec ukryty tekst zostaje w srodku. */
.ntb-matrix__scroll,
.ntb-table-wrap,
.ntb-sizing__table { position: relative; }

/* --- 49. Wariant, ktorego nie ma na stanie: wyszarzenie ---------------------
   Decyzja wlasciciela z 10 wrzesnia 2026. Produkt bez stanu znika z list
   (ntb24-core/inc/offer-visibility.php), ale WARIANT zostaje widoczny -
   klient ma wiedziec, ze rozmiar w ogole istnieje, i moze zapisac sie na
   powiadomienie. Zamiast chowac go, wyszarzamy.

   Rozroznienie nie moze isc samym kolorem (regula dostepnosci), wiec zostaje
   to, co bylo - przekreslenie na kafelku i ukosna kreska na probce barwy -
   a doklada sie do tego przygaszenie. Barwy probki NIE zmieniamy recznie:
   grayscale() zdejmuje ja bez wprowadzania koloru spoza palety. */
.ntb-size[data-state="soon"],
.ntb-size[data-state="discontinued"] {
	background: var(--c-paper);
	opacity: .55;
}

.ntb-color[data-state="soon"],
.ntb-color[data-state="discontinued"] {
	filter: grayscale(1);
	opacity: .5;
}

/* Kreska na probce ma zostac czytelna mimo przygaszenia calosci. */
.ntb-color[data-state="soon"]::after,
.ntb-color[data-state="discontinued"]::after { opacity: 1; }

/* Probka w tabeli dostepnosci i na karcie listy: ten sam jezyk. */
.ntb-matrix__color[data-state="soon"] .ntb-swatch,
.ntb-matrix__color[data-state="discontinued"] .ntb-swatch,
.ntb-swatches [data-state="soon"],
.ntb-swatches [data-state="discontinued"] { filter: grayscale(1); opacity: .5; }

/* Kafelek rozmiaru na karcie listy jest mniejszy, ale niesie ten sam stan. */
.ntb-card__sizes .ntb-size[data-state="soon"],
.ntb-card__sizes .ntb-size[data-state="discontinued"] { opacity: .5; }

@media (prefers-reduced-transparency: reduce) {
	/* Bez przezroczystosci zostaje sam rysunek: ramka, przekreslenie, szraf. */
	.ntb-size[data-state="soon"],
	.ntb-size[data-state="discontinued"],
	.ntb-color[data-state="soon"],
	.ntb-color[data-state="discontinued"],
	.ntb-card__sizes .ntb-size[data-state="soon"],
	.ntb-card__sizes .ntb-size[data-state="discontinued"] { opacity: 1; }
}

/* --- 50. Zapis na powrót rozmiaru: jeden wiersz na rozmiar --------------------
   Przy kilku brakujących rozmiarach karta zamieniała się w ścianę formularzy:
   przy sztybletach Franceschini brakowało siedmiu rozmiarów, więc klient
   dostawał siedem pól na adres i siedem zgód jedno pod drugim, zanim doszedł
   do opisu. Każdy rozmiar ma teraz własne <details> - zwinięte zajmuje wiersz,
   działa bez JavaScriptu, a formularz w środku zostaje ten sam. */
.ntb-notify__item { border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); }
.ntb-notify__item + .ntb-notify__item { border-top: 0; }
/* Grupa kilku rozmiarow: jeden zwiniety wiersz, w srodku wiersze rozmiarow (wciete, bez podwojnej ramki). */
.ntb-notify__all { border: var(--bw-hair) solid var(--c-line); background: var(--c-bg); }
.ntb-notify__all > .ntb-notify__sum { color: var(--c-ink); font-weight: var(--fw-medium); }
.ntb-notify__all[open] > .ntb-notify__sum { border-bottom: var(--bw-hair) solid var(--c-line); }
.ntb-notify__all .ntb-notify__item { border-inline: 0; border-bottom: 0; }
.ntb-notify__all .ntb-notify__item:first-of-type { border-top: 0; }
.ntb-notify__all .ntb-notify__item .ntb-notify__sum { padding-left: calc(var(--s-4) + 26px); }

.ntb-notify__sum {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: var(--touch);
	padding: 0 var(--s-4);
	font-size: var(--fs-300);
	color: var(--c-ink-2);
	cursor: pointer;
	list-style: none;
}

.ntb-notify__sum::-webkit-details-marker { display: none; }
.ntb-notify__sum svg { flex: none; color: var(--c-ink-3); }
.ntb-notify__sum:hover { color: var(--c-ink); }

/* Znak rozwinięcia rysujemy sami, bo strzałka przeglądarki jest niewidoczna
   po zdjęciu list-style. */
.ntb-notify__sum::after {
	content: "";
	flex: none;
	margin-left: auto;
	width: 8px;
	height: 8px;
	border-right: var(--bw-hair) solid var(--c-ink-3);
	border-bottom: var(--bw-hair) solid var(--c-ink-3);
	transform: rotate(45deg);
	transition: transform var(--dur) var(--ease);
}

.ntb-notify__item[open] > .ntb-notify__sum::after { transform: rotate(-135deg); }
.ntb-notify__item[open] > .ntb-notify__sum { color: var(--c-ink); }
.ntb-notify__item > form,
.ntb-notify__item > .ntb-notify { border: 0; padding-top: 0; }

@media (prefers-reduced-motion: reduce) {
	.ntb-notify__sum::after { transition: none; }
}

/* --- 51. Galeria: reszta zdjęć za <details>, kadr wariantu -------------------
   Znacznik "+N" nie prowadził nigdzie; teraz szósta i dalsze miniatury stoją
   w rozwijanej siatce, która działa bez skryptu. Miniatury rozwinięte
   podmieniają kadr główny tak samo jak pierwsza piątka. */
.ntb-gallery__more { margin-top: var(--s-3); }
.ntb-gallery__more-sum {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	min-height: var(--touch);
	font-size: var(--fs-200);
	color: var(--c-ink-2);
	cursor: pointer;
	list-style: none;
}
.ntb-gallery__more-sum::-webkit-details-marker { display: none; }
.ntb-gallery__more-sum::after {
	content: "";
	flex: none;
	width: 8px;
	height: 8px;
	border-right: var(--bw-hair) solid var(--c-ink-3);
	border-bottom: var(--bw-hair) solid var(--c-ink-3);
	transform: rotate(45deg);
	transition: transform var(--dur) var(--ease);
}
.ntb-gallery__more[open] > .ntb-gallery__more-sum::after { transform: rotate(-135deg); }
.ntb-gallery__more-sum:hover { color: var(--c-ink); }
.ntb-gallery__thumbs--more { margin-top: 0; }

@media (prefers-reduced-motion: reduce) {
	.ntb-gallery__more-sum::after { transition: none; }
}

/* --- 52. Strony prawne: listy zagnieżdżone, tabela odbiorców, formularz ------ */
.ntb-legal__body .ntb-legal__lead { max-width: var(--w-prose); font-size: var(--fs-500); line-height: var(--lh-body); color: var(--c-ink-2); }
.ntb-legal__body ol ol, .ntb-legal__body ol ul, .ntb-legal__body ul ul { margin-top: 8px; padding-left: 1.5rem; font-size: inherit; }
.ntb-legal__body ol[type="a"] { list-style: lower-alpha; }
.ntb-legal__body .ntb-legal__dl { display: grid; grid-template-columns: minmax(140px, 200px) minmax(0, 1fr); margin-top: 12px; max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); }
.ntb-legal__body .ntb-legal__dl dt { padding: 10px 0; border-top: var(--bw-hair) solid var(--c-line); color: var(--c-ink-3); }
.ntb-legal__body .ntb-legal__dl dd { margin: 0; padding: 10px 0 10px 16px; border-top: var(--bw-hair) solid var(--c-line); color: var(--c-ink-2); }
.ntb-legal__body .ntb-table-wrap { margin-top: 14px; max-width: var(--w-prose); }
.ntb-legal__body .ntb-legal__form { margin-top: 14px; padding: var(--s-5); border: var(--bw-hair) solid var(--c-line); background: var(--c-paper); max-width: var(--w-text); font-size: var(--fs-400); line-height: var(--lh-body); overflow-wrap: anywhere; /* wiersze z kropkami we wzorze odstapienia nie maja spacji - na 390 px rozciagaly strone do 727 px */ }
.ntb-legal__body .ntb-legal__form p + p { margin-top: 10px; }
@media (max-width: 767px) {
	.ntb-legal__body .ntb-legal__dl { grid-template-columns: 1fr; }
	.ntb-legal__body .ntb-legal__dl dd { padding-left: 0; border-top: 0; padding-top: 0; }
}

/* --- 53. Strona systemu rozmiarowego: wstęp w dwóch kolumnach, sekcje ------
   Przegląd 13 września 2026: tekst wstępu stał sam w lewej trzeciej ekranu,
   a kalkulator i tabele siedziały w kolumnie prozy. Teraz: tekst + zdjęcie
   (albo placeholder z wymiarem kadru), kalkulator i tabele na pełnej
   szerokości, jeden rytm odstępów między sekcjami. */
.ntb-sysintro { padding-top: var(--s-7); }
.ntb-sysintro__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-6); align-items: start; }
.ntb-sysintro__text { max-width: var(--w-prose); }
.ntb-sysintro__media .ntb-ph, .ntb-sysintro__media .ntb-frame { aspect-ratio: 4 / 3; }
.ntb-sysintro__media .ntb-frame img { width: 100%; height: 100%; object-fit: cover; }
.ntb-syscalc .ntbs-kalkulator { margin-top: 0; }
.ntb-systab .ntbs-tabela { margin-top: var(--s-5); display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-6) var(--s-8); align-items: start; }
.ntb-systab .ntbs-tabela .ntb-table { margin: 0; }
.ntb-sysaxis .ntb-sechead { margin-bottom: var(--s-5); }
.ntb-sysaxis .ntb-infografika--os { margin-top: 0; }
.ntb-sysaxis__sizes { margin-top: var(--s-6); }
.ntb-sysaxis__sizes .ntb-size { min-height: var(--touch); }

@media (min-width: 900px) {
	.ntb-sysintro__grid { grid-template-columns: minmax(0, 7fr) minmax(280px, 5fr); gap: var(--s-8) var(--s-10); }
	.ntb-systab .ntbs-tabela { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
