/* =============================================================================
   PA 2.0 — WARSTWA KLAS katalogu (pa-klasy.css).
   Transpozycja SCSS z repo website-2 do czystego CSS. NAZWY KLAS BEZ ZMIAN.
   Pliki źródłowe (odczyt 11.08.2026, kopia repo w uploads/website-2):
     base/typography.scss, helpers/spacing|display|flexbox|grid.scss,
     elements/container|buttons|badge|input|accordion|animations.scss, main.scss.
   Zasada: TU NIE MA WARTOŚCI poza tymi, które stoją literałem w kodzie.
   Wszystko inne idzie przez var() do pa-tokens.css. Nic nie poprawiam po cichu —
   znalezione rozjazdy idą do "Rozbieznosci - kod vs katalog.md".
   ============================================================================= */

/* --- main.scss ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* --- base/reset.scss (transkrypcja CZĘŚCIOWA, 18.08.2026) -------------------
   Ten plik NIE BYŁ dotąd przepisany w ogóle, a jego reguła obrazków rządzi
   każdym rysunkiem produktu. Znalezione ze zgłoszenia zamawiającego o awatarze sekcji
   FAQ: rysunek 160 px stał w slocie 80 px i wyglądał jak anomalia produktu,
   a jest brakiem katalogu. Wiersz wyżej to ta sama rodzina resetu przepisana
   12.08 z main.scss — czyli rodzina obecna CZĘŚCIOWO, dokładnie ta pułapka,
   o której mówi pozycja 36 listy pułapek wzorca migracji.

   CZEGO NIE PRZEPISUJEMY I DLACZEGO — granica nośnika, nie przeoczenie:
   list-style na ol/ul, reset odnośnika, reset formularzy, tabel oraz html/body.
   Ten arkusz wczytują TAKŻE strony katalogu, więc te reguły przemalowałyby prozę
   katalogu (wypunktowania, odnośniki w opisach, tabele pomiarów), czyli rzeczy,
   które do produktu nie należą. Komponenty, które tych reguł potrzebują, niosą je
   u siebie — reset odnośnika stoi dziś w helmecie karty. */
img, picture { max-width: 100%; display: block; }
body { font-family: var(--static-typography-font-family); }
p { font-weight: 300; }

/* --- base/typography.scss ------------------------------------------------ */
.text-h1 { font-size: var(--pui-text-h1-font-size); line-height: var(--pui-text-h1-line-height); letter-spacing: var(--pui-text-h1-letter-spacing); }
.text-h2 { font-size: var(--pui-text-h2-font-size); line-height: var(--pui-text-h2-line-height); letter-spacing: var(--pui-text-h2-letter-spacing); }
.text-h3 { font-size: var(--pui-text-h3-font-size); line-height: var(--pui-text-h3-line-height); letter-spacing: var(--pui-text-h3-letter-spacing); }
.text-h4 { font-size: var(--pui-text-h4-font-size); line-height: var(--pui-text-h4-line-height); letter-spacing: var(--pui-text-h4-letter-spacing); }
.text-h5 { font-size: var(--pui-text-h5-font-size); line-height: var(--pui-text-h5-line-height); letter-spacing: var(--pui-text-h5-letter-spacing); }
.text-h6 { font-size: var(--pui-text-h6-font-size); line-height: var(--pui-text-h6-line-height); letter-spacing: var(--pui-text-h6-letter-spacing); }
.text-h7 { font-size: var(--pui-text-h7-font-size); line-height: var(--pui-text-h7-line-height); letter-spacing: var(--pui-text-h7-letter-spacing); }
.text-h8 { font-size: var(--pui-text-h8-font-size); line-height: var(--pui-text-h8-line-height); letter-spacing: var(--pui-text-h8-letter-spacing); }
.text-p-xxlg { font-size: var(--pui-text-p-xxlg-font-size); line-height: var(--pui-text-p-xxlg-line-height); letter-spacing: var(--pui-text-p-xxlg-letter-spacing); }
.text-p-xlg { font-size: var(--pui-text-p-xlg-font-size); line-height: var(--pui-text-p-xlg-line-height); letter-spacing: var(--pui-text-p-xlg-letter-spacing); }
.text-p-lg { font-size: var(--pui-text-p-lg-font-size); line-height: var(--pui-text-p-lg-line-height); letter-spacing: var(--pui-text-p-lg-letter-spacing); }
.text-p-base { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); letter-spacing: var(--pui-text-p-base-letter-spacing); }
.text-p-sm { font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); letter-spacing: var(--pui-text-p-sm-letter-spacing); }
.text-p-xs { font-size: var(--pui-text-p-xs-font-size); line-height: var(--pui-text-p-xs-line-height); letter-spacing: var(--pui-text-p-xs-letter-spacing); }
.text-p-xxs { font-size: var(--pui-text-p-xxs-font-size); line-height: var(--pui-text-p-xxs-line-height); letter-spacing: var(--pui-text-p-xxs-letter-spacing); }
.font-light { font-weight: var(--pui-font-weight-light); }
.font-regular { font-weight: var(--pui-font-weight-regular); }
.font-medium { font-weight: var(--pui-font-weight-medium); }
.font-semi-bold { font-weight: var(--pui-font-weight-semi-bold); }
.font-bold { font-weight: var(--pui-font-weight-bold); }
.text-variant-strong { color: var(--pui-text-strong); }
.text-variant-default { color: var(--pui-text-default); }
.text-variant-lighter { color: var(--pui-text-lighter); }
.text-variant-faded { color: var(--pui-text-faded); }
.text-variant-primary { color: var(--pui-text-primary); }
.text-variant-heading { color: var(--pui-text-heading); }
.text-variant-success { color: var(--pui-text-success); }
.text-variant-warning { color: var(--pui-text-warning); }
.text-variant-danger { color: var(--pui-text-danger); }
.text-variant-info { color: var(--pui-text-info); }
.text-variant-purple { color: var(--pui-text-purple); }
.text-variant-red { color: var(--pui-text-red); }
.text-variant-orange { color: var(--pui-text-orange); }

/* --- base/typography.scss, sekcja markdown ------------------------------- */
.markdown-h1 { font-size: var(--pui-markdown-h1-font-size); line-height: var(--pui-markdown-h1-line-height); font-weight: var(--pui-markdown-h1-font-weight); letter-spacing: var(--pui-markdown-h1-letter-spacing); margin-bottom: var(--pui-markdown-h1-margin-bottom); }
/* MARGINES GÓRNY NAGŁÓWKÓW DOŁOŻONY 06.09.2026, polecenie zamawiającego („może większy
   margines od góry?"). ROLE ISTNIAŁY I NIE MIAŁY CZYTELNIKA: --pui-markdown-h2..h6-margin-top
   stoją w arkuszu tokenów od początku (--static-space-4x, czyli 32 px), a te reguły ich nie
   wołały — render pokazywał margines 0. To nie jest nowa wartość, tylko wołanie roli, która
   czekała. h1 roli marginesu nie ma i dlatego jej nie dostaje: brak zgłaszam, nie zastępuję
   go wartością z sąsiedniego stopnia. */
.markdown-h2 { margin-top: var(--pui-markdown-h2-margin-top); font-size: var(--pui-markdown-h2-font-size); line-height: var(--pui-markdown-h2-line-height); font-weight: var(--pui-markdown-h2-font-weight); letter-spacing: var(--pui-markdown-h2-letter-spacing); margin-top: var(--pui-markdown-h2-margin-top); margin-bottom: var(--pui-markdown-h2-margin-bottom); }
.markdown-h3 { margin-top: var(--pui-markdown-h3-margin-top); font-size: var(--pui-markdown-h3-font-size); line-height: var(--pui-markdown-h3-line-height); font-weight: var(--pui-markdown-h3-font-weight); letter-spacing: var(--pui-markdown-h3-letter-spacing); margin-top: var(--pui-markdown-h3-margin-top); margin-bottom: var(--pui-markdown-h3-margin-bottom); }
.markdown-h4 { margin-top: var(--pui-markdown-h4-margin-top); font-size: var(--pui-markdown-h4-font-size); line-height: var(--pui-markdown-h4-line-height); font-weight: var(--pui-markdown-h4-font-weight); letter-spacing: var(--pui-markdown-h4-letter-spacing); margin-top: var(--pui-markdown-h4-margin-top); margin-bottom: var(--pui-markdown-h4-margin-bottom); }
.markdown-h5 { margin-top: var(--pui-markdown-h5-margin-top); font-size: var(--pui-markdown-h5-font-size); line-height: var(--pui-markdown-h5-line-height); font-weight: var(--pui-markdown-h5-font-weight); letter-spacing: var(--pui-markdown-h5-letter-spacing); margin-top: var(--pui-markdown-h5-margin-top); margin-bottom: var(--pui-markdown-h5-margin-bottom); }
.markdown-h6 { margin-top: var(--pui-markdown-h6-margin-top); font-size: var(--pui-markdown-h6-font-size); line-height: var(--pui-markdown-h6-line-height); font-weight: var(--pui-markdown-h6-font-weight); letter-spacing: var(--pui-markdown-h6-letter-spacing); margin-top: var(--pui-markdown-h6-margin-top); margin-bottom: var(--pui-markdown-h6-margin-bottom); }
.markdown-paragraph { font-size: var(--pui-markdown-paragraph-font-size); line-height: var(--pui-markdown-paragraph-line-height); font-weight: var(--pui-markdown-paragraph-font-weight); letter-spacing: var(--pui-markdown-paragraph-letter-spacing); margin-bottom: var(--pui-markdown-paragraph-margin-bottom); }
/* LISTA CZYTA TYPOGRAFIĘ AKAPITU, 06.09.2026, polecenie zamawiającego: „czcionka listy
   nie może być mniejsza niż czcionka paragrafu ani inna".
   BRAK ZMIERZONY NA RENDERZE, nie odczytany z arkusza: lista miała 16 px i wagę 400 przy
   akapicie 18 px i wadze 300, a interlinię „normal". Przyczyna: ta reguła ustawiała WYŁĄCZNIE
   margines i wcięcie, więc pozycja listy brała stopień i wagę z OTOCZENIA, nie z rodziny.
   Rodzina markdownu nie ma własnych ról stopnia listy (`--pui-markdown-list-font-size` nie
   istnieje) — dlatego lista wskazuje na role AKAPITU, a nie na nowe, wymyślone przez nas:
   pozycja listy i akapit to ten sam stopień treści, więc jedna rola na oba jest poprawna,
   a druga rozjechałaby się przy pierwszej zmianie.
   ZGŁOSZENIE DO DEWELOPERÓW: jeśli produkt też nie ustawia typografii listy, jego listy
   dziedziczą stopień z miejsca osadzenia i wyglądają inaczej na każdej stronie. */
.markdown-list {
  margin-bottom: var(--pui-markdown-list-margin-bottom);
  padding-left: var(--pui-layout-gap-base);
  font-size: var(--pui-markdown-paragraph-font-size);
  line-height: var(--pui-markdown-paragraph-line-height);
  font-weight: var(--pui-markdown-paragraph-font-weight);
  letter-spacing: var(--pui-markdown-paragraph-letter-spacing);
  /* PUNKTOR DOŁOŻONY 06.09.2026, zgłoszenie zamawiającego „lista nie ma kropek".
     Klasa niosła `list-style-type: disc` z ustawień przeglądarki, ale NIE MIAŁA CZEGO
     MALOWAĆ: punktor rysuje wyłącznie element o `display: list-item`, a klasa bywa nadawana
     zwykłemu blokowi, nie `<li>` w `<ul>`. Objaw jest cichy w najgorszy sposób: reguła
     wygląda na kompletną, wcięcie jest, więc lista czyta się jak lista bez punktorów, czyli
     jak decyzja projektowa.
     `list-style-position: inside` — bo wcięcie niesie już `padding-left` klasy; przy
     pozycji `outside` punktor wyszedłby PRZED to wcięcie i wypadł poza tekst akapitu. */
  display: list-item;
  list-style-position: inside;
}
/* KOD, TABELA I POGRUBIENIE W MARKDOWNIE — klasy dołożone 06.09.2026, polecenie
   zamawiającego. ZMIERZONE PRZED: .markdown-code ustawiała JEDNĄ własność (rodzinę pisma),
   więc blok kodu był akapitem innym pismem, bez tła i wyściółki; tabela nie miała klasy wcale.
   Wszystkie wartości z ról rodziny (dołożonych w tej samej turze do arkusza tokenów), więc
   rodzina zmienia się razem z systemem. */
.markdown-code {
  font-family: var(--pui-font-family-mono);
  display: block;
  margin-bottom: var(--pui-markdown-list-margin-bottom);
  padding: var(--pui-markdown-code-padding);
  border: var(--pui-ui-border-outline-border-width) solid var(--pui-markdown-code-border);
  border-radius: var(--pui-markdown-code-radius);
  background: var(--pui-markdown-code-bg);
  color: var(--pui-markdown-code-fg);
  font-size: var(--pui-markdown-code-font-size);
  line-height: var(--pui-markdown-code-line-height);
  /* Kod nie zawija się na siłę: łamanie linii w kodzie zmienia jego znaczenie. */
  white-space: pre;
  overflow-x: auto;
}
/* KOD W LINII — inna rzecz niż blok i dlatego osobna klasa: stoi WEWNĄTRZ zdania, więc nie
   może mieć własnej wyściółki pionowej ani tła na pełną szerokość. */
.markdown-code-inline {
  font-family: var(--pui-font-family-mono);
  padding: var(--pui-markdown-code-inline-padding);
  border-radius: var(--pui-markdown-code-inline-radius);
  background: var(--pui-markdown-code-inline-bg);
  color: var(--pui-markdown-code-fg);
  font-size: 0.94em;
}
/* LINIA ROZDZIELAJĄCA — klasa dołożona 06.09.2026, zgłoszenie zamawiającego: „divider wygląda
   jakby miał mniejszy odstęp od góry niż od dołu". Tak było: linia nie miała własnych marginesów,
   więc odstęp dawały marginesy SĄSIADÓW — akapit nad nią kończy się 16 px, a nagłówek pod nią
   zaczyna 32 px. Nierówność nie była w linii, była w tym, że linia nie miała nic swojego.
   Odstęp symetryczny i większy od obu: linia rozdziela rozdziały, więc musi być widoczna jako
   przerwa, nie jako kreska dociśnięta do nagłówka. */
.markdown-divider {
  display: block;
  height: var(--pui-ui-border-outline-border-width);
  margin: var(--static-space-5x) 0;
  background: var(--pui-panel-border);
  border: none;
}
/* ODSTĘP MUSI BYĆ RÓWNY PO OBU STRONACH, A MARGINESY SIĘ SUMUJĄ. Pierwsza wersja dała linii
   własny margines 40 px i nadal wychodziło nierówno: 56 px nad (40 plus margines dolny akapitu)
   i 72 px pod (40 plus margines górny nagłówka). W układzie kolumnowym marginesy sąsiadów NIE
   ZNOSZĄ SIĘ, tylko dokładają.
   Dlatego linia ZDEJMUJE margines temu, co stoi bezpośrednio po niej — wtedy odstęp z obu stron
   niesie wyłącznie ona i jest równy z definicji. Selektor łapie każdy stopień nagłówka i akapit,
   bo po linii może stać jedno albo drugie. */
.markdown-divider + [class*="markdown-h"],
.markdown-divider + .markdown-paragraph,
.markdown-divider + .markdown-list,
.markdown-divider + .markdown-table { margin-top: 0; }
/* I TO SAMO Z DRUGIEJ STRONY — poprawka po drugim pomiarze: zerowanie po linii dało 56 px nad
   i 40 px pod, bo margines DOLNY elementu stojącego PRZED linią dokładał swoje 16 px.
   Symetria wymaga zdjęcia marginesu z obu stron, nie z jednej; `:has` pozwala to zrobić bez
   dotykania szablonu. */
.markdown-paragraph:has(+ .markdown-divider),
.markdown-list:has(+ .markdown-divider),
.markdown-table:has(+ .markdown-divider),
[class*="markdown-h"]:has(+ .markdown-divider) { margin-bottom: 0; }
/* POGRUBIENIE — rodzina nie miała go wcale, a markdown używa go najczęściej z całej składni. */
.markdown-strong { font-weight: var(--pui-markdown-strong-weight); color: var(--pui-markdown-strong-fg); }
/* TABELA. Trzy klasy, bo trzy różne rzeczy: rama, wiersz nagłówkowy i komórka.
   Rama jest SIATKĄ, nie znacznikiem <table>: klasa bywa nadawana zwykłym blokom, dokładnie
   jak przy liście, więc oparcie stylu na znaczniku zawiodłoby w tym samym miejscu. */
.markdown-table {
  margin-bottom: var(--pui-markdown-list-margin-bottom);
  border: var(--pui-ui-border-outline-border-width) solid var(--pui-markdown-table-border);
  border-radius: var(--pui-ui-radius-lg);
  overflow: hidden;
}
.markdown-table-row {
  display: grid;
  gap: var(--pui-markdown-table-gap);
  padding: var(--pui-markdown-table-cell-padding);
  border-bottom: var(--pui-ui-border-outline-border-width) solid var(--pui-markdown-table-border);
}
.markdown-table-row:last-child { border-bottom: none; }
.markdown-table-row--header {
  background: var(--pui-markdown-table-header-bg);
  color: var(--pui-markdown-table-header-fg);
  font-weight: var(--pui-markdown-table-header-weight);
}
.markdown-table-cell {
  font-size: var(--pui-markdown-paragraph-font-size);
  line-height: var(--pui-markdown-paragraph-line-height);
  overflow-wrap: anywhere;
  text-wrap: pretty;
}
.markdown-image { margin-bottom: var(--pui-markdown-image-margin-bottom); border-radius: var(--pui-markdown-image-radius); }

/* --- helpers/spacing.scss ------------------------------------------------ */
.padding-5xl { padding: var(--pui-layout-padding-5xl); }
.padding-4xl { padding: var(--pui-layout-padding-4xl); }
.padding-3xl { padding: var(--pui-layout-padding-3xl); }
.padding-2xl { padding: var(--pui-layout-padding-2xl); }
.padding-xl { padding: var(--pui-layout-padding-xl); }
.padding-lg { padding: var(--pui-layout-padding-lg); }
.padding-base { padding: var(--pui-layout-padding-base); }
.padding-sm { padding: var(--pui-layout-padding-sm); }
.padding-xs { padding: var(--pui-layout-padding-xs); }
.padding-2xs { padding: var(--pui-layout-padding-2xs); }
.padding-3xs { padding: var(--pui-layout-padding-3xs); }
.padding-4xs { padding: var(--pui-layout-padding-4xs); }
.padding-5xs { padding: var(--pui-layout-padding-5xs); }
.padding-6xs { padding: var(--pui-layout-padding-6xs); }
.gap-5xl { gap: var(--pui-layout-gap-5xl); }
.gap-4xl { gap: var(--pui-layout-gap-4xl); }
.gap-3xl { gap: var(--pui-layout-gap-3xl); }
.gap-2xl { gap: var(--pui-layout-gap-2xl); }
.gap-xl { gap: var(--pui-layout-gap-xl); }
.gap-lg { gap: var(--pui-layout-gap-lg); }
.gap-base { gap: var(--pui-layout-gap-base); }
.gap-sm { gap: var(--pui-layout-gap-sm); }
.gap-xs { gap: var(--pui-layout-gap-xs); }
.gap-2xs { gap: var(--pui-layout-gap-2xs); }
.gap-3xs { gap: var(--pui-layout-gap-3xs); }
.gap-4xs { gap: var(--pui-layout-gap-4xs); }
.gap-5xs { gap: var(--pui-layout-gap-5xs); }
.gap-6xs { gap: var(--pui-layout-gap-6xs); }

/* --- helpers/display.scss, flexbox.scss, grid.scss ------------------------
   Odpowiedniki BAZOWE. Warianty responsywne rodzi w kodzie mixin make-responsive
   (d-flex-tablet itd.) — katalog ich nie mnoży, bo próbki stoją na desktopie. */
.d-none { display: none !important; }
.d-inline { display: inline !important; }
.d-inline-block { display: inline-block !important; }
.d-block { display: block !important; }
.d-flex { display: flex !important; }
.d-inline-flex { display: inline-flex !important; }
.d-grid { display: grid !important; }
.d-contents { display: contents !important; }
.d-table { display: table !important; }
.flex-row { flex-direction: row !important; }
.flex-row-reverse { flex-direction: row-reverse !important; }
.flex-col { flex-direction: column !important; }
.flex-col-reverse { flex-direction: column-reverse !important; }
.flex-wrap { flex-wrap: wrap !important; }
.flex-nowrap { flex-wrap: nowrap !important; }
.flex-wrap-reverse { flex-wrap: wrap-reverse !important; }
.justify-start { justify-content: flex-start !important; }
.justify-center { justify-content: center !important; }
.justify-end { justify-content: flex-end !important; }
.justify-between { justify-content: space-between !important; }
.justify-around { justify-content: space-around !important; }
.justify-evenly { justify-content: space-evenly !important; }
.items-start { align-items: flex-start !important; }
.items-center { align-items: center !important; }
.items-end { align-items: flex-end !important; }
.items-baseline { align-items: baseline !important; }
.items-stretch { align-items: stretch !important; }
.content-start { align-content: flex-start !important; }
.content-center { align-content: center !important; }
.content-end { align-content: flex-end !important; }
.content-between { align-content: space-between !important; }
.content-around { align-content: space-around !important; }
.content-stretch { align-content: stretch !important; }
.self-auto { align-self: auto !important; }
.self-start { align-self: flex-start !important; }
.self-center { align-self: center !important; }
.self-end { align-self: flex-end !important; }
.self-stretch { align-self: stretch !important; }
.flex-grow-0 { flex-grow: 0 !important; }
.flex-shrink-0 { flex-shrink: 0 !important; }
.flex-grow-1 { flex-grow: 1 !important; }
.flex-shrink-1 { flex-shrink: 1 !important; }
.flex-1 { flex: 1 1 0% !important; }
.flex-auto { flex: 1 1 auto !important; }
.flex-initial { flex: 0 1 auto !important; }
.flex-none { flex: none !important; }
.grid-cols-1 { display: grid !important; grid-template-columns: repeat(1, minmax(0, 1fr)) !important; }
.grid-cols-2 { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.grid-cols-3 { display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
.grid-cols-4 { display: grid !important; grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
.grid-cols-5 { display: grid !important; grid-template-columns: repeat(5, minmax(0, 1fr)) !important; }
.grid-cols-6 { display: grid !important; grid-template-columns: repeat(6, minmax(0, 1fr)) !important; }
.grid-cols-7 { display: grid !important; grid-template-columns: repeat(7, minmax(0, 1fr)) !important; }
.grid-cols-8 { display: grid !important; grid-template-columns: repeat(8, minmax(0, 1fr)) !important; }
.grid-cols-9 { display: grid !important; grid-template-columns: repeat(9, minmax(0, 1fr)) !important; }
.grid-cols-10 { display: grid !important; grid-template-columns: repeat(10, minmax(0, 1fr)) !important; }
.grid-cols-11 { display: grid !important; grid-template-columns: repeat(11, minmax(0, 1fr)) !important; }
.grid-cols-12 { display: grid !important; grid-template-columns: repeat(12, minmax(0, 1fr)) !important; }
.grid-cols-none { grid-template-columns: none !important; }
.col-span-1 { grid-column: span 1 / span 1 !important; }
.col-span-2 { grid-column: span 2 / span 2 !important; }
.col-span-3 { grid-column: span 3 / span 3 !important; }
.col-span-4 { grid-column: span 4 / span 4 !important; }
.col-span-5 { grid-column: span 5 / span 5 !important; }
.col-span-6 { grid-column: span 6 / span 6 !important; }
.col-span-7 { grid-column: span 7 / span 7 !important; }
.col-span-8 { grid-column: span 8 / span 8 !important; }
.col-span-9 { grid-column: span 9 / span 9 !important; }
.col-span-10 { grid-column: span 10 / span 10 !important; }
.col-span-11 { grid-column: span 11 / span 11 !important; }
.col-span-12 { grid-column: span 12 / span 12 !important; }
.col-span-full { grid-column: 1 / -1 !important; }
.row-span-1 { grid-row: span 1 / span 1 !important; }
.row-span-2 { grid-row: span 2 / span 2 !important; }
.row-span-3 { grid-row: span 3 / span 3 !important; }
.row-span-4 { grid-row: span 4 / span 4 !important; }
.row-span-5 { grid-row: span 5 / span 5 !important; }
.row-span-6 { grid-row: span 6 / span 6 !important; }
.row-span-full { grid-row: 1 / -1 !important; }
.grid-rows-1 { display: grid !important; grid-template-rows: repeat(1, minmax(0, 1fr)) !important; }
.grid-rows-2 { display: grid !important; grid-template-rows: repeat(2, minmax(0, 1fr)) !important; }
.grid-rows-3 { display: grid !important; grid-template-rows: repeat(3, minmax(0, 1fr)) !important; }
.grid-rows-4 { display: grid !important; grid-template-rows: repeat(4, minmax(0, 1fr)) !important; }
.grid-rows-5 { display: grid !important; grid-template-rows: repeat(5, minmax(0, 1fr)) !important; }
.grid-rows-6 { display: grid !important; grid-template-rows: repeat(6, minmax(0, 1fr)) !important; }

/* --- elements/container.scss --------------------------------------------- */
.container { margin: 0 auto; width: 100%; max-width: var(--pui-container-width-max); padding: 0 var(--pui-container-padding-h); gap: var(--pui-container-gap); }

/* --- elements/buttons.scss ------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; position: relative;
  border: 1px solid transparent; cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  text-decoration: none; white-space: nowrap; vertical-align: middle;
  user-select: none; outline: none; box-sizing: border-box;
  height: var(--pui-button-base-height);
  border-radius: var(--pui-button-base-radius);
  padding: 0 var(--pui-button-base-padding-h);
  gap: var(--pui-button-base-gap);
  /* DRUGI WŁAŚCICIEL KLASY. Typografia .btn nie stoi w elements/buttons.scss,
     tylko w scoped style komponentu app/components/ui/controls/Button.vue.
     Bez tych czterech deklaracji klasa dziedziczy stopień z otoczenia i przycisk
     wygląda inaczej w katalogu niż w produkcie. Rozjazd RZ-72. */
  font-size: var(--pui-text-p-lg-font-size);
  font-weight: 600;
  line-height: var(--pui-text-p-lg-line-height);
  letter-spacing: var(--pui-text-p-lg-letter-spacing);
}
.btn__content { display: none; }
.btn__text { font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; letter-spacing: inherit; }
.btn__icon { width: var(--pui-button-base-icon-size); height: var(--pui-button-base-icon-size); }
.btn__slot { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; min-width: 0; }
.btn--xxlg:not(.btn--hero):not(.btn--hero-outline) { height: var(--pui-button-xxlg-height); border-radius: var(--pui-button-xxlg-radius); padding: 0 var(--pui-button-xxlg-padding-h); gap: var(--pui-button-xxlg-gap); font-size: var(--pui-text-p-xxlg-font-size); line-height: var(--pui-text-p-xxlg-line-height); letter-spacing: var(--pui-text-p-xxlg-letter-spacing); }
.btn--xxlg:not(.btn--hero):not(.btn--hero-outline) .btn__icon { width: var(--pui-button-xxlg-icon-size); height: var(--pui-button-xxlg-icon-size); }
.btn--xlg:not(.btn--hero):not(.btn--hero-outline) { height: var(--pui-button-xlg-height); border-radius: var(--pui-button-xlg-radius); padding: 0 var(--pui-button-xlg-padding-h); gap: var(--pui-button-xlg-gap); font-size: var(--pui-text-p-xlg-font-size); line-height: var(--pui-text-p-xlg-line-height); letter-spacing: var(--pui-text-p-xlg-letter-spacing); }
.btn--xlg:not(.btn--hero):not(.btn--hero-outline) .btn__icon { width: var(--pui-button-xlg-icon-size); height: var(--pui-button-xlg-icon-size); }
.btn--lg:not(.btn--hero):not(.btn--hero-outline) { height: var(--pui-button-lg-height); border-radius: var(--pui-button-lg-radius); padding: 0 var(--pui-button-lg-padding-h); gap: var(--pui-button-lg-gap); }
.btn--lg:not(.btn--hero):not(.btn--hero-outline) .btn__icon { width: var(--pui-button-lg-icon-size); height: var(--pui-button-lg-icon-size); }
.btn--sm:not(.btn--hero):not(.btn--hero-outline) { height: var(--pui-button-sm-height); border-radius: var(--pui-button-sm-radius); padding: 0 var(--pui-button-sm-padding-h); gap: var(--pui-button-sm-gap); font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); letter-spacing: var(--pui-text-p-base-letter-spacing); }
.btn--sm:not(.btn--hero):not(.btn--hero-outline) .btn__icon { width: var(--pui-button-sm-icon-size); height: var(--pui-button-sm-icon-size); }
.btn--xs:not(.btn--hero):not(.btn--hero-outline) { height: var(--pui-button-xs-height); border-radius: var(--pui-button-xs-radius); padding: 0 var(--pui-button-xs-padding-h); gap: var(--pui-button-xs-gap); font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); letter-spacing: var(--pui-text-p-sm-letter-spacing); }
.btn--xs:not(.btn--hero):not(.btn--hero-outline) .btn__icon { width: var(--pui-button-xs-icon-size); height: var(--pui-button-xs-icon-size); }
.btn--primary { background-color: var(--pui-button-primary-solid-bg); color: var(--pui-button-primary-solid-fg); border-color: var(--pui-button-primary-solid-bg); }
.btn--primary:hover { background-color: var(--pui-button-primary-solid-bg-hover); }
.btn--primary:active { background-color: var(--pui-button-primary-solid-bg-active); border-color: var(--pui-button-primary-solid-border-active); }
.btn--primary:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--primary-faded { background-color: var(--pui-button-primary-faded-bg); color: var(--pui-button-primary-faded-fg); border-color: transparent; }
.btn--primary-faded:hover { background-color: var(--pui-button-primary-faded-bg-hover); }
.btn--primary-faded:active { background-color: var(--pui-button-primary-faded-bg-active); border-color: var(--pui-button-primary-faded-border-active); }
.btn--primary-outline { background-color: var(--pui-button-primary-outline-bg); color: var(--pui-button-primary-outline-fg); border-color: var(--pui-button-primary-outline-border); }
.btn--primary-outline:hover { background-color: var(--pui-button-primary-outline-bg-hover); border-color: var(--pui-button-primary-outline-border-hover); }
.btn--primary-outline:active { background-color: var(--pui-button-primary-outline-bg-active); border-color: var(--pui-button-primary-outline-border-active); }
.btn--primary-ghost { background-color: transparent; color: var(--pui-button-primary-ghost-fg); border-color: transparent; }
.btn--primary-ghost:hover { background-color: var(--pui-button-primary-ghost-bg-hover); }
.btn--primary-ghost:active { background-color: var(--pui-button-primary-ghost-bg-active); }
.btn--secondary { background-color: var(--pui-button-secondary-solid-bg); color: var(--pui-button-secondary-solid-fg); border-color: var(--pui-button-secondary-solid-bg); }
.btn--secondary:hover { background-color: var(--pui-button-secondary-solid-bg-hover); }
.btn--secondary:active { background-color: var(--pui-button-secondary-solid-bg-active); border-color: var(--pui-button-secondary-solid-border-active); }
.btn--secondary:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--secondary-faded { background-color: var(--pui-button-secondary-faded-bg); color: var(--pui-button-secondary-faded-fg); border-color: transparent; }
.btn--secondary-faded:hover { background-color: var(--pui-button-secondary-faded-bg-hover); }
.btn--secondary-faded:active { background-color: var(--pui-button-secondary-faded-bg-active); border-color: var(--pui-button-secondary-faded-border-active); }
.btn--secondary-outline { background-color: var(--pui-button-secondary-outline-bg); color: var(--pui-button-secondary-outline-fg); border-color: var(--pui-button-secondary-outline-border); }
.btn--secondary-outline:hover { background-color: var(--pui-button-secondary-outline-bg-hover); border-color: var(--pui-button-secondary-outline-border-hover); }
.btn--secondary-outline:active { background-color: var(--pui-button-secondary-outline-bg-active); border-color: var(--pui-button-secondary-outline-border-active); }
.btn--secondary-ghost { background-color: transparent; color: var(--pui-button-secondary-ghost-fg); border-color: transparent; }
.btn--secondary-ghost:hover { background-color: var(--pui-button-secondary-ghost-bg-hover); }
.btn--secondary-ghost:active { background-color: var(--pui-button-secondary-ghost-bg-active); }
.btn--success { background-color: var(--pui-button-success-solid-bg); color: var(--pui-button-success-solid-fg); border-color: var(--pui-button-success-solid-bg); }
.btn--success:hover { background-color: var(--pui-button-success-solid-bg-hover); }
.btn--success:active { background-color: var(--pui-button-success-solid-bg-active); border-color: var(--pui-button-success-solid-border-active); }
.btn--success:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--success-faded { background-color: var(--pui-button-success-faded-bg); color: var(--pui-button-success-faded-fg); border-color: transparent; }
.btn--success-faded:hover { background-color: var(--pui-button-success-faded-bg-hover); }
.btn--success-faded:active { background-color: var(--pui-button-success-faded-bg-active); border-color: var(--pui-button-success-faded-border-active); }
.btn--success-outline { background-color: var(--pui-button-success-outline-bg); color: var(--pui-button-success-outline-fg); border-color: var(--pui-button-success-outline-border); }
.btn--success-outline:hover { background-color: var(--pui-button-success-outline-bg-hover); border-color: var(--pui-button-success-outline-border-hover); }
.btn--success-outline:active { background-color: var(--pui-button-success-outline-bg-active); border-color: var(--pui-button-success-outline-border-active); }
.btn--success-ghost { background-color: transparent; color: var(--pui-button-success-ghost-fg); border-color: transparent; }
.btn--success-ghost:hover { background-color: var(--pui-button-success-ghost-bg-hover); }
.btn--success-ghost:active { background-color: var(--pui-button-success-ghost-bg-active); }
.btn--warning { background-color: var(--pui-button-warning-solid-bg); color: var(--pui-button-warning-solid-fg); border-color: var(--pui-button-warning-solid-bg); }
.btn--warning:hover { background-color: var(--pui-button-warning-solid-bg-hover); }
.btn--warning:active { background-color: var(--pui-button-warning-solid-bg-active); border-color: var(--pui-button-warning-solid-border-active); }
.btn--warning:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--warning-faded { background-color: var(--pui-button-warning-faded-bg); color: var(--pui-button-warning-faded-fg); border-color: transparent; }
.btn--warning-faded:hover { background-color: var(--pui-button-warning-faded-bg-hover); }
.btn--warning-faded:active { background-color: var(--pui-button-warning-faded-bg-active); border-color: var(--pui-button-warning-faded-border-active); }
.btn--warning-outline { background-color: var(--pui-button-warning-outline-bg); color: var(--pui-button-warning-outline-fg); border-color: var(--pui-button-warning-outline-border); }
.btn--warning-outline:hover { background-color: var(--pui-button-warning-outline-bg-hover); border-color: var(--pui-button-warning-outline-border-hover); }
.btn--warning-outline:active { background-color: var(--pui-button-warning-outline-bg-active); border-color: var(--pui-button-warning-outline-border-active); }
.btn--warning-ghost { background-color: transparent; color: var(--pui-button-warning-ghost-fg); border-color: transparent; }
.btn--warning-ghost:hover { background-color: var(--pui-button-warning-ghost-bg-hover); }
.btn--warning-ghost:active { background-color: var(--pui-button-warning-ghost-bg-active); }
.btn--danger { background-color: var(--pui-button-danger-solid-bg); color: var(--pui-button-danger-solid-fg); border-color: var(--pui-button-danger-solid-bg); }
.btn--danger:hover { background-color: var(--pui-button-danger-solid-bg-hover); }
.btn--danger:active { background-color: var(--pui-button-danger-solid-bg-active); border-color: var(--pui-button-danger-solid-border-active); }
.btn--danger:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--danger-faded { background-color: var(--pui-button-danger-faded-bg); color: var(--pui-button-danger-faded-fg); border-color: transparent; }
.btn--danger-faded:hover { background-color: var(--pui-button-danger-faded-bg-hover); }
.btn--danger-faded:active { background-color: var(--pui-button-danger-faded-bg-active); border-color: var(--pui-button-danger-faded-border-active); }
.btn--danger-outline { background-color: var(--pui-button-danger-outline-bg); color: var(--pui-button-danger-outline-fg); border-color: var(--pui-button-danger-outline-border); }
.btn--danger-outline:hover { background-color: var(--pui-button-danger-outline-bg-hover); border-color: var(--pui-button-danger-outline-border-hover); }
.btn--danger-outline:active { background-color: var(--pui-button-danger-outline-bg-active); border-color: var(--pui-button-danger-outline-border-active); }
.btn--danger-ghost { background-color: transparent; color: var(--pui-button-danger-ghost-fg); border-color: transparent; }
.btn--danger-ghost:hover { background-color: var(--pui-button-danger-ghost-bg-hover); }
.btn--danger-ghost:active { background-color: var(--pui-button-danger-ghost-bg-active); }
.btn--info { background-color: var(--pui-button-info-solid-bg); color: var(--pui-button-info-solid-fg); border-color: var(--pui-button-info-solid-bg); }
.btn--info:hover { background-color: var(--pui-button-info-solid-bg-hover); }
.btn--info:active { background-color: var(--pui-button-info-solid-bg-active); border-color: var(--pui-button-info-solid-border-active); }
.btn--info:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--default { background-color: var(--pui-button-default-solid-bg); color: var(--pui-button-default-solid-fg); border-color: var(--pui-button-default-solid-bg); }
.btn--default:hover { background-color: var(--pui-button-default-solid-bg-hover); }
.btn--default:active { background-color: var(--pui-button-default-solid-bg-active); border-color: var(--pui-button-default-solid-border-active); }
.btn--default:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--default-faded { background-color: var(--pui-button-default-faded-bg); color: var(--pui-button-default-faded-fg); border-color: transparent; }
.btn--default-faded:hover { background-color: var(--pui-button-default-faded-bg-hover); }
.btn--default-faded:active { background-color: var(--pui-button-default-faded-bg-active); border-color: var(--pui-button-default-faded-border-active); }
.btn--default-outline { background-color: var(--pui-button-default-outline-bg); color: var(--pui-button-default-outline-fg); border-color: var(--pui-button-default-outline-border); }
.btn--default-outline:hover { background-color: var(--pui-button-default-outline-bg-hover); border-color: var(--pui-button-default-outline-border-hover); }
.btn--default-outline:active { background-color: var(--pui-button-default-outline-bg-active); border-color: var(--pui-button-default-outline-border-active); }
.btn--default-ghost { background-color: transparent; color: var(--pui-button-default-ghost-fg); border-color: transparent; }
.btn--default-ghost:hover { background-color: var(--pui-button-default-ghost-bg-hover); }
.btn--default-ghost:active { background-color: var(--pui-button-default-ghost-bg-active); }
.btn--discord { background-color: var(--pui-button-discord-solid-bg); color: var(--pui-button-discord-solid-fg); border-color: var(--pui-button-discord-solid-bg); }
.btn--discord:hover { background-color: var(--pui-button-discord-solid-bg-hover); }
.btn--discord:active { background-color: var(--pui-button-discord-solid-bg-active); border-color: var(--pui-button-discord-solid-border-active); }
.btn--discord:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--purple { background-color: var(--pui-button-purple-solid-bg); color: var(--pui-button-purple-solid-fg); border-color: var(--pui-button-purple-solid-bg); }
.btn--purple:hover { background-color: var(--pui-button-purple-solid-bg-hover); }
.btn--purple:active { background-color: var(--pui-button-purple-solid-bg-active); border-color: var(--pui-button-purple-solid-border-active); }
.btn--purple:focus-visible { box-shadow: 0 0 0 2px var(--pui-feedback-focus-ring); }
.btn--purple-faded { background-color: var(--pui-button-purple-faded-bg); color: var(--pui-button-purple-faded-fg); border-color: transparent; }
.btn--purple-faded:hover { background-color: var(--pui-button-purple-faded-bg-hover); }
.btn--purple-faded:active { background-color: var(--pui-button-purple-faded-bg-active); border-color: var(--pui-button-purple-faded-border-active); }
.btn--purple-outline { background-color: var(--pui-button-purple-outline-bg); color: var(--pui-button-purple-outline-fg); border-color: var(--pui-button-purple-outline-border); }
.btn--purple-outline:hover { background-color: var(--pui-button-purple-outline-bg-hover); border-color: var(--pui-button-purple-outline-border-hover); }
.btn--purple-outline:active { background-color: var(--pui-button-purple-outline-bg-active); border-color: var(--pui-button-purple-outline-border-active); }
.btn--purple-ghost { background-color: transparent; color: var(--pui-button-purple-ghost-fg); border-color: transparent; }
.btn--purple-ghost:hover { background-color: var(--pui-button-purple-ghost-bg-hover); }
.btn--purple-ghost:active { background-color: var(--pui-button-purple-ghost-bg-active); }
/* Stany. Dwa zapisy przepisane WIERNIE, bo są w kodzie i katalog ich nie poprawia:
   pusty fallback w var(--…-fg-disabled,) oraz nazwa z JEDNYM myślnikiem
   var(-pui-button-primary-solid-bg-disabled), która nie jest custom property. */
.btn.is-disabled, .btn:disabled {
  cursor: not-allowed !important;
  background-color: var(--pui-button-primary-solid-bg-disabled) !important;
  color: var(--pui-button-primary-solid-fg-disabled,) !important;
  border-color: var(-pui-button-primary-solid-bg-disabled) !important;
}
.btn.is-loading { cursor: wait !important; pointer-events: none; }
.btn.is-loading .btn__text, .btn.is-loading .btn__icon, .btn.is-loading .btn__slot { opacity: 0; }
.btn.is-loading::after {
  content: ''; position: absolute; width: 1.25em; height: 1.25em;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: btn-spin 0.75s linear infinite;
}
@keyframes btn-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* --- elements/badge.scss ---------------------------------------------------
   CIĘCIE 05.09.2026 (plan domknięcia atomów, poz. 2): zeszły klasy, które
   generowały się i nic nie malowały, bo nie miały z czego wziąć wartości —
   stopnie .badge--xl i .badge--md oraz .badge--info-faded i .badge--info-outline.
   Powody, każdy z pomiaru: skala --pui-label-* kończy się na lg (xl); role
   --pui-text-p-md-font-size i -line-height nie istnieją w żadnej warstwie, więc md
   brał wyściółkę base, a pismo spadało na dziedziczone 16 px / normal i dawał TRZECI
   stan zamiast powtórzenia base (md); pasmo blue ma tylko stopnie 400-700, bez
   50/100/200 (info-faded, info-outline).
   Pozostałe 14 pustych pól macierzy NIE zostało wycięte, tylko domknięte rolami
   w pa-tokens.css: solid i outline z wzoru rodziny przycisku, faded dla red
   z wzoru wariantu, który etykieta już miała.

   ORAZ: wariant outline przestał pożyczać obwiednię z rodziny FORMULARZA
   (--pui-form-border) i czyta własną rolę --pui-label-{kolor}-outline-border,
   a szerokość bierze z --pui-ui-border-outline-border-width zamiast wpisanego
   wprost 1px. Katalog jest specyfikacją, więc poprawka wchodzi tutaj, a rozjazd
   z dzisiejszym kodem produktu idzie do docs/Rozbieznosci jako pomiar. */
.badge {
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap; vertical-align: middle; box-sizing: border-box;
  transition: all 0.2s ease; height: fit-content; font-weight: 600;
  font-size: var(--pui-text-p-base-font-size);
  line-height: var(--pui-text-p-base-line-height);
  letter-spacing: var(--pui-text-p-base-letter-spacing);
  padding: var(--pui-label-base-padding-v) var(--pui-label-base-padding-h);
  gap: var(--pui-label-base-gap);
  border-radius: var(--pui-label-base-radius);
  border: none;
}
.badge__icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: var(--pui-label-base-icon-size); height: var(--pui-label-base-icon-size); }
.badge__icon svg, .badge__icon i { width: 100%; height: 100%; display: block; }
.badge__text { font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; }
.badge--lg { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); padding: var(--pui-label-lg-padding-v) var(--pui-label-lg-padding-h); gap: var(--pui-label-lg-gap); border-radius: var(--pui-label-lg-radius); }
.badge--lg .badge__icon { width: var(--pui-label-lg-icon-size); height: var(--pui-label-lg-icon-size); }
.badge--base { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); padding: var(--pui-label-base-padding-v) var(--pui-label-base-padding-h); gap: var(--pui-label-base-gap); border-radius: var(--pui-label-base-radius); }
.badge--base .badge__icon { width: var(--pui-label-base-icon-size); height: var(--pui-label-base-icon-size); }
.badge--sm { font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); padding: var(--pui-label-sm-padding-v) var(--pui-label-sm-padding-h); gap: var(--pui-label-sm-gap); border-radius: var(--pui-label-sm-radius); }
.badge--sm .badge__icon { width: var(--pui-label-sm-icon-size); height: var(--pui-label-sm-icon-size); }
.badge--xs { font-size: var(--pui-text-p-xxs-font-size); line-height: var(--pui-text-p-xxs-line-height); padding: var(--pui-label-xs-padding-v) var(--pui-label-xs-padding-h); gap: var(--pui-label-xs-gap); border-radius: var(--pui-label-xs-radius); }
.badge--xs .badge__icon { width: var(--pui-label-xs-icon-size); height: var(--pui-label-xs-icon-size); }
.badge--xxs { font-size: var(--pui-text-p-xxs-font-size); line-height: var(--pui-text-p-xxs-line-height); padding: var(--pui-label-xxs-padding-v) var(--pui-label-xxs-padding-h); gap: var(--pui-label-xxs-gap); border-radius: var(--pui-label-xxs-radius); }
.badge--xxs .badge__icon { width: var(--pui-label-xxs-icon-size); height: var(--pui-label-xxs-icon-size); }
/* Wariant koloru. Lista w kodzie przepisuje success→primary, warning→orange,
   danger→red PRZED zbudowaniem nazwy klasy, więc klasy .badge--success,
   .badge--warning i .badge--danger NIE POWSTAJĄ, a .badge--primary i
   .badge--orange powstają dwa razy. Przepisane wiernie — rozjazd RZ-65. */
.badge:not(.badge--hero).badge--primary { background-color: var(--pui-label-primary-solid-bg); color: var(--pui-label-primary-solid-fg); }
.badge:not(.badge--hero).badge--primary-faded { background-color: var(--pui-label-primary-faded-bg); color: var(--pui-label-primary-faded-fg); }
.badge:not(.badge--hero).badge--primary-outline { background-color: var(--pui-label-primary-outline-bg); color: var(--pui-label-primary-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-primary-outline-border); }
.badge:not(.badge--hero).badge--primary-link:hover, .badge:not(.badge--hero).badge--primary.badge--link:hover { background-color: var(--pui-label-primary-solid-bg-hover); color: var(--pui-label-primary-solid-fg-hover); }
.badge:not(.badge--hero).badge--orange { background-color: var(--pui-label-orange-solid-bg); color: var(--pui-label-orange-solid-fg); }
.badge:not(.badge--hero).badge--orange-faded { background-color: var(--pui-label-orange-faded-bg); color: var(--pui-label-orange-faded-fg); }
.badge:not(.badge--hero).badge--orange-outline { background-color: var(--pui-label-orange-outline-bg); color: var(--pui-label-orange-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-orange-outline-border); }
.badge:not(.badge--hero).badge--orange-link:hover, .badge:not(.badge--hero).badge--orange.badge--link:hover { background-color: var(--pui-label-orange-solid-bg-hover); color: var(--pui-label-orange-solid-fg-hover); }
.badge:not(.badge--hero).badge--purple { background-color: var(--pui-label-purple-solid-bg); color: var(--pui-label-purple-solid-fg); }
.badge:not(.badge--hero).badge--purple-faded { background-color: var(--pui-label-purple-faded-bg); color: var(--pui-label-purple-faded-fg); }
.badge:not(.badge--hero).badge--purple-outline { background-color: var(--pui-label-purple-outline-bg); color: var(--pui-label-purple-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-purple-outline-border); }
.badge:not(.badge--hero).badge--purple-link:hover, .badge:not(.badge--hero).badge--purple.badge--link:hover { background-color: var(--pui-label-purple-solid-bg-hover); color: var(--pui-label-purple-solid-fg-hover); }
.badge:not(.badge--hero).badge--default { background-color: var(--pui-label-default-solid-bg); color: var(--pui-label-default-solid-fg); }
.badge:not(.badge--hero).badge--default-faded { background-color: var(--pui-label-default-faded-bg); color: var(--pui-label-default-faded-fg); }
.badge:not(.badge--hero).badge--default-outline { background-color: var(--pui-label-default-outline-bg); color: var(--pui-label-default-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-default-outline-border); }
.badge:not(.badge--hero).badge--default-link:hover, .badge:not(.badge--hero).badge--default.badge--link:hover { background-color: var(--pui-label-default-solid-bg-hover); color: var(--pui-label-default-solid-fg-hover); }
.badge:not(.badge--hero).badge--primary { background-color: var(--pui-label-primary-solid-bg); color: var(--pui-label-primary-solid-fg); }
.badge:not(.badge--hero).badge--primary-faded { background-color: var(--pui-label-primary-faded-bg); color: var(--pui-label-primary-faded-fg); }
.badge:not(.badge--hero).badge--primary-outline { background-color: var(--pui-label-primary-outline-bg); color: var(--pui-label-primary-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-primary-outline-border); }
.badge:not(.badge--hero).badge--primary-link:hover, .badge:not(.badge--hero).badge--primary.badge--link:hover { background-color: var(--pui-label-primary-solid-bg-hover); color: var(--pui-label-primary-solid-fg-hover); }
.badge:not(.badge--hero).badge--info { background-color: var(--pui-label-info-solid-bg); color: var(--pui-label-info-solid-fg); }
.badge:not(.badge--hero).badge--info-link:hover, .badge:not(.badge--hero).badge--info.badge--link:hover { background-color: var(--pui-label-info-solid-bg-hover); color: var(--pui-label-info-solid-fg-hover); }
.badge:not(.badge--hero).badge--orange { background-color: var(--pui-label-orange-solid-bg); color: var(--pui-label-orange-solid-fg); }
.badge:not(.badge--hero).badge--orange-faded { background-color: var(--pui-label-orange-faded-bg); color: var(--pui-label-orange-faded-fg); }
.badge:not(.badge--hero).badge--orange-outline { background-color: var(--pui-label-orange-outline-bg); color: var(--pui-label-orange-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-orange-outline-border); }
.badge:not(.badge--hero).badge--orange-link:hover, .badge:not(.badge--hero).badge--orange.badge--link:hover { background-color: var(--pui-label-orange-solid-bg-hover); color: var(--pui-label-orange-solid-fg-hover); }
.badge:not(.badge--hero).badge--red { background-color: var(--pui-label-red-solid-bg); color: var(--pui-label-red-solid-fg); }
.badge:not(.badge--hero).badge--red-faded { background-color: var(--pui-label-red-faded-bg); color: var(--pui-label-red-faded-fg); }
.badge:not(.badge--hero).badge--red-outline { background-color: var(--pui-label-red-outline-bg); color: var(--pui-label-red-outline-fg); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--pui-label-red-outline-border); }
.badge:not(.badge--hero).badge--red-link:hover, .badge:not(.badge--hero).badge--red.badge--link:hover { background-color: var(--pui-label-red-solid-bg-hover); color: var(--pui-label-red-solid-fg-hover); }
.badge--hero { will-change: transform; transform: translateZ(0); backface-visibility: hidden; -webkit-font-smoothing: antialiased; }
.badge--hero.badge--primary { background: linear-gradient(93.73deg, var(--pui-hero-label-primary-bg-start) 0.25%, var(--pui-hero-label-primary-bg-end) 99.75%); color: var(--pui-hero-label-primary-fg); }
.badge--hero.badge--primary.badge--link:hover { background: linear-gradient(93.73deg, var(--pui-hero-label-primary-bg-hover-start) 0.25%, var(--pui-hero-label-primary-bg-hover-end) 99.75%); color: var(--pui-hero-label-primary-fg-hover); }
.badge--hero.badge--default { background: linear-gradient(93.73deg, var(--pui-hero-label-default-bg-start) 0.25%, var(--pui-hero-label-default-bg-end) 99.75%); color: var(--pui-hero-label-default-fg); }
.badge--hero.badge--default.badge--link:hover { background: linear-gradient(93.73deg, var(--pui-hero-label-default-bg-hover-start) 0.25%, var(--pui-hero-label-default-bg-hover-end) 99.75%); color: var(--pui-hero-label-default-fg-hover); }

/* WARSTWY STANU ETYKIETY HERO — DOPISANE 21.08.2026 ze zgłoszenia zamawiającego
   („popraw hovery dla tych labelek, brakuje powiększenia i transition").
   Odczyt elements/badge.scss 58-92: przy migracji nie został przepisany CAŁY
   blok `&.badge--link`, więc etykieta miała barwy hoveru (dwie linie wyżej),
   a nie miała ani powiększenia, ani warstwy `.after-hover`, ani stanu
   kliknięcia. Znacznik nosił `.badge--link` i `<div class="after-hover">`
   od początku — brakowało samych reguł, nie elementów.

   PRZEJŚCIA NIE DEKLARUJĘ PRZY POWIĘKSZENIU: baza `.badge` ma
   `transition: all 0.2s ease` (linia 389), więc `transform` animuje się nią
   — tak samo jak w kodzie, gdzie `&:hover { transform: scale(104%) }` też
   stoi bez własnego przejścia.

   ROZJAZD PRZEPISANY WIERNIE, NIE POPRAWIONY (RZ-106): tło warstwy stoi w SCSS
   jako `&.after-hover` WEWNĄTRZ pętli wariantu, czyli rozwiązuje się na
   `.badge--hero.badge--primary.badge--link.after-hover` — jeden element z obiema
   klasami naraz, podczas gdy `.after-hover` jest DZIECKIEM bez klas etykiety.
   Selektor nie trafia w produkcie w nic, więc warstwa hoveru zostaje bez tła,
   a widoczna zmiana pod wskaźnikiem to gradient `:hover` na samej etykiecie
   plus powiększenie. Przepisuję tak, jak stoi.

   POMINIĘTE: `.badge--hero.border-mask { position: relative }` z pętli SCSS —
   `.border-mask` ustawia to samo dla wszystkich (linia 667), więc reguła
   w kodzie jest bez skutku. */
.badge--hero.badge--link::after { content: ""; position: absolute; inset: 0; opacity: 0; transition: opacity 0.2s ease; pointer-events: none; z-index: -1; border-radius: inherit; }
.badge--hero.badge--link .after-hover { position: absolute; inset: 0; opacity: 0; transition: opacity 0.2s ease; pointer-events: none; z-index: -1; border-radius: inherit; }
.badge--hero.badge--link:hover { transform: scale(104%); }
.badge--hero.badge--link:hover .after-hover { opacity: 1; }
.badge--hero.badge--link:active::after { opacity: 1; }
.badge--hero.badge--primary.badge--link:active { color: var(--pui-hero-label-primary-fg-active); }
.badge--hero.badge--primary.badge--link::after { background: linear-gradient(90deg, var(--pui-hero-label-primary-bg-active-start) 0%, var(--pui-hero-label-primary-bg-active-end) 100%); }
.badge--hero.badge--primary.badge--link.after-hover { background: linear-gradient(90deg, var(--pui-hero-label-primary-bg-hover-start) 0%, var(--pui-hero-label-primary-bg-hover-end) 100%); }
.badge--hero.badge--default.badge--link:active { color: var(--pui-hero-label-default-fg-active); }
.badge--hero.badge--default.badge--link::after { background: linear-gradient(90deg, var(--pui-hero-label-default-bg-active-start) 0%, var(--pui-hero-label-default-bg-active-end) 100%); }
.badge--hero.badge--default.badge--link.after-hover { background: linear-gradient(90deg, var(--pui-hero-label-default-bg-hover-start) 0%, var(--pui-hero-label-default-bg-hover-end) 100%); }
.badge--hero.badge--lg { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); padding: var(--pui-hero-label-lg-padding-v) var(--pui-hero-label-lg-padding-h); gap: var(--pui-hero-label-lg-gap); border-radius: var(--pui-hero-label-lg-radius); }
.badge--hero.badge--lg .badge__icon { width: var(--pui-hero-label-lg-icon-size); height: var(--pui-hero-label-lg-icon-size); }
.badge--hero.badge--base { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); padding: var(--pui-hero-label-base-padding-v) var(--pui-hero-label-base-padding-h); gap: var(--pui-hero-label-base-gap); border-radius: var(--pui-hero-label-base-radius); }
.badge--hero.badge--base .badge__icon { width: var(--pui-hero-label-base-icon-size); height: var(--pui-hero-label-base-icon-size); }
.badge--hero.badge--sm { font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); padding: var(--pui-hero-label-sm-padding-v) var(--pui-hero-label-sm-padding-h); gap: var(--pui-hero-label-sm-gap); border-radius: var(--pui-hero-label-sm-radius); }
.badge--hero.badge--sm .badge__icon { width: var(--pui-hero-label-sm-icon-size); height: var(--pui-hero-label-sm-icon-size); }
.badge--hero.badge--xs { font-size: var(--pui-text-p-xs-font-size); line-height: var(--pui-text-p-xs-line-height); padding: var(--pui-hero-label-xs-padding-v) var(--pui-hero-label-xs-padding-h); gap: var(--pui-hero-label-xs-gap); border-radius: var(--pui-hero-label-xs-radius); }
.badge--hero.badge--xs .badge__icon { width: var(--pui-hero-label-xs-icon-size); height: var(--pui-hero-label-xs-icon-size); }
/* OBWIEDNIA PLAKIETKI HERO — DOPISANA 12.08.2026 (P2.2), brak wcześniejszej
   transpozycji. `.border-mask::before` z helpers/custom.scss rysuje maskę, ale
   NIE MA własnego tła; barwę obwiedni nadaje dopiero ta reguła z badge.scss.
   Bez niej `.badge--hero.border-mask` daje pierścień przezroczysty, czyli
   obwiednię zadeklarowaną i niewidoczną — ta sama rodzina co RZ-33.
   Znalezione przy przepinaniu etykiet banera poziomego z odrysu na klasy. */
.badge--hero.badge--default::before { background: linear-gradient(90deg, var(--pui-hero-label-default-border-start) 0%, var(--pui-hero-label-default-border-end) 100%); }
.badge--hero.badge--primary::before { background: linear-gradient(90deg, var(--pui-hero-label-primary-border-start) 0%, var(--pui-hero-label-primary-border-end) 50%, var(--pui-hero-label-primary-border-start) 100%); }

/* --- elements/input.scss --------------------------------------------------- */
.input-group { display: flex; flex-direction: column; width: 100%; gap: var(--pui-form-gap); }
.input-group__control { position: relative; display: flex; align-items: stretch; width: 100%; min-width: 0; height: var(--pui-form-base-height); background-color: var(--pui-form-bg); transition: border-color 0.2s, box-shadow 0.2s; border-radius: var(--pui-form-base-radius); overflow: hidden; }
.input-group__inner { position: relative; display: flex; align-items: center; flex: 1; min-width: 0; height: 100%; padding: 0 var(--pui-form-base-padding-h); border: var(--pui-form-base-border-width) solid var(--pui-form-border); background: var(--pui-form-bg); border-radius: var(--pui-form-base-radius); z-index: 1; transition: border-color 0.2s, box-shadow 0.2s; }
.input-group__input { flex: 1; min-width: 0; height: 100%; background: transparent; border: none; padding: 0; color: var(--pui-form-fg-filled); font-family: inherit; font-size: var(--pui-form-base-font-size); font-weight: inherit; }
.input-group__input::placeholder { color: var(--pui-form-fg); opacity: 1; }
.input-group__input:focus { outline: none; }
.input-group__icon { display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--pui-form-icon); transition: color 0.2s; font-size: var(--pui-form-base-icon-size); }
.input-group__icon--left { margin-right: var(--pui-form-base-gap); }
.input-group__icon--right { margin-left: var(--pui-form-base-gap); }
.input-group__icon svg { width: 1em; height: 1em; }
.input-group:focus-within .input-group__inner { border-color: var(--pui-form-border-active); box-shadow: 0 0 0 var(--pui-form-base-border-width) var(--pui-form-border-active); z-index: 2; }
.input-group--error .input-group__inner { border-color: var(--pui-form-border-error); }
.input-group--error .input-group__icon { color: var(--pui-form-icon-error); }
.input-group--error:focus-within .input-group__inner { border-color: var(--pui-form-border-error-active); box-shadow: 0 0 0 var(--pui-form-base-border-width) var(--pui-form-border-error-active); }
.input-group--success .input-group__inner { border-color: var(--pui-form-border-success); }
.input-group--success .input-group__icon { color: var(--pui-form-icon-success); }
.input-group--success:focus-within .input-group__inner { border-color: var(--pui-form-border-success-active); box-shadow: 0 0 0 var(--pui-form-base-border-width) var(--pui-form-border-success-active); }
.input-group.is-disabled { opacity: 0.6; cursor: not-allowed; }
.input-group.is-disabled .input-group__inner { background-color: var(--pui-form-bg-disabled); border-color: var(--pui-form-border-disabled); pointer-events: none; }
.input-group.is-disabled .input-group__input { color: var(--pui-text-faded); }
.input-group--sm .input-group__control { height: var(--pui-form-sm-height); border-radius: var(--pui-form-sm-radius); }
.input-group--sm .input-group__inner { padding: 0 var(--pui-form-sm-padding-h); border-radius: var(--pui-form-sm-radius); }
.input-group--sm .input-group__input { font-size: var(--pui-form-sm-font-size); }
.input-group--sm .input-group__icon { font-size: var(--pui-form-sm-icon-size); }
.input-group--sm .input-group__icon--left { margin-right: var(--pui-form-sm-gap); }
.input-group--sm .input-group__icon--right { margin-left: var(--pui-form-sm-gap); }
.input-group__actions { display: flex; align-items: center; margin-left: var(--pui-form-base-gap); }
.input-group--sm .input-group__actions { margin-left: var(--pui-form-sm-gap); }
.input-group--lg .input-group__actions { margin-left: var(--pui-form-lg-gap); }
.input-group--lg .input-group__icon--left { margin-right: var(--pui-form-lg-gap); }
.input-group--lg .input-group__icon--right { margin-left: var(--pui-form-lg-gap); }
/* KOMUNIKAT POD POLEM (05.09.2026, plan domknięcia atomów poz. 4). Klasa stała
   w markupie produktu i NIE MIAŁA w arkuszu ani jednej reguły — komunikat błędu
   rysował się stopniem i barwą dziedziczoną z miejsca użycia, więc ten sam błąd
   wyglądał inaczej w każdym gospodarzu. Reguły złożone z wzoru rodziny: stopień
   z pisma p-sm, barwa spokojna z tekstu pomocniczego, barwy stanów z ról błędu
   i powodzenia, które ta rodzina dostała w tej samej turze. */
.input-group__helper { font-size: var(--pui-form-helper-font-size); line-height: var(--pui-form-helper-line-height); color: var(--pui-form-helper-fg); }
.input-group--error .input-group__helper { color: var(--pui-form-helper-fg-error); }
.input-group--success .input-group__helper { color: var(--pui-form-helper-fg-success); }
.input-group--lg .input-group__control { height: var(--pui-form-lg-height); border-radius: var(--pui-form-lg-radius); }
.input-group--lg .input-group__inner { padding: 0 var(--pui-form-lg-padding-h); border-radius: var(--pui-form-lg-radius); }
.input-group--lg .input-group__input { font-size: var(--pui-form-lg-font-size); }

/* --- elements/accordion.scss ----------------------------------------------
   DOMKNIĘCIE RODZINY 05.09.2026 (plan domknięcia atomów). Ta rodzina jest
   ODWROTNOŚCIĄ pozostałych: nie miała ani jednej roli nierozwiązanej, miała
   SZEŚĆ RÓL, KTÓRYCH NIKT NIE CZYTAŁ — promień, szerokość obwiedni, tło,
   wymiar ikony (dwie role) i odstęp poziomy w nagłówku. Klasa stawiała w tych
   miejscach wartości wprost: 16 px, 1 px, 20 px.

   Sprawdzone przed przepięciem: role dają DOKŁADNIE te same wartości
   (--pui-ui-radius-3xl = 16px, --pui-ui-border-outline-border-width = 1px,
   --static-space-2-5x = 20px), więc render jest ten sam. Zmienia się to, że
   promień, obwiednia i ikona tej rodziny idą odtąd za skalą, a tło za warstwą
   (rola tła jest przedefiniowana w kontekście ciemnym — do 05.09 karta była
   przezroczysta i brała tło sekcji).

   Kod produktu tych wartości nie czyta z ról; rozjazd jest naszym pomiarem,
   nie kolejką napraw — katalog jest specyfikacją. */
.accordion { width: 100%; display: flex; flex-direction: column; gap: var(--pui-accordion-column-gap); }
.accordion__item { background: var(--pui-accordion-bg); border: var(--pui-accordion-border-width) solid var(--pui-accordion-border); border-radius: var(--pui-accordion-radius); transition: all 0.3s ease; cursor: pointer; overflow: hidden; padding: var(--pui-accordion-padding-v) var(--pui-accordion-padding-h); }
.accordion__item.is-open .accordion__header h4 { color: var(--pui-text-primary); }
.accordion__item.is-open .accordion__icon svg path { fill: var(--pui-text-primary); }
.accordion__item.is-open .accordion__content { margin-top: var(--pui-accordion-gap-v); }
.accordion .is-open .accordion__icon { transform: rotate(180deg); }
.accordion .is-open .accordion__content { grid-template-rows: 1fr; }
.accordion .is-open .accordion__header { color: var(--pui-text-primary); }
.accordion__item:hover h4 { color: var(--pui-text-primary); }
.accordion__item:hover .accordion__icon svg path { fill: var(--pui-text-primary); }
.accordion__header { display: flex; align-items: center; justify-content: space-between; gap: var(--pui-accordion-gap-h); width: 100%; background: none; border: none; cursor: pointer; text-align: left; }
.accordion__header h4 { font-weight: 600; }
.accordion__icon { display: flex; align-items: center; justify-content: center; transition: transform 0.3s ease; width: var(--pui-accordion-icon-container-size); height: var(--pui-accordion-icon-container-size); color: var(--pui-text-primary); }
.accordion__icon svg { width: 100%; height: 100%; }
.accordion__icon svg path { fill: var(--pui-text-heading); transition: fill .3s ease; }
.accordion__content { display: grid; grid-template-rows: 0fr; transition: all 0.3s ease; overflow: hidden; }
.accordion__body-wrapper { min-height: 0; }

/* --- sections/Faq.vue (blok scoped, linie 60-141) -----------------------------
   PRZEPISANE 18.08.2026 razem z pozycją sekcji.

   BRAK NAZWANY: reguła `.faq { padding: var(--pui-section-padding-v) 0 }` z kodu
   NIE WYBIERA NICZEGO. Korzeniem sekcji jest `<section class="section">`, klasy
   `faq` nie nosi w tym pliku żaden element, a styl jest `scoped`, więc rodzina
   `.faq__*` działa bez rodzica o tej nazwie. Sekcja bierze zatem SAM dolny
   padding z `.section`. Reguły tu nie ma świadomie — dopisanie jej dołożyłoby
   96 px górnego odstępu, którego produkt nie ma.

   BARWA OBWIEDNI KARTY: karta nosi `.border-mask`, więc `border: 1px solid gray`
   z kodu jest odwołane przez `border: none !important` pomocnika (ta sama rodzina
   co RZ-33). Widoczna jest wyłącznie maska z ::before i to ona czyta dwie role. */
.faq__layout { display: flex; gap: var(--pui-faq-gap); align-items: flex-start; }
.faq__left {
  flex: 0 0 var(--pui-faq-left-column-width-max);
  max-width: var(--pui-faq-left-column-width-max);
  gap: var(--pui-faq-left-column-gap);
  display: flex; flex-direction: column;
}
.faq__header { display: flex; flex-direction: column; gap: var(--pui-section-heading-vertical-content-gap); }
.faq__right { flex: 1; width: 100%; min-width: var(--pui-faq-min-width); }
.faq__card {
  display: flex;
  padding: var(--pui-faq-left-column-cta-padding-v) var(--pui-faq-left-column-cta-padding-h);
  flex-direction: column; align-items: center;
  gap: var(--pui-faq-left-column-cta-gap);
  border-radius: var(--pui-faq-left-column-radius);
  text-align: center;
  border: 1px solid gray;
}
.faq__card h6 { font-weight: 600; }
.faq__card-avatar {
  display: flex;
  width: var(--pui-faq-left-column-avatar-size);
  height: var(--pui-faq-left-column-avatar-size);
  align-items: center;
}
.faq__card-avatar img {
  border-radius: var(--pui-faq-left-column-avatar-radius);
  border: var(--pui-faq-left-column-avatar-border-width) solid var(--pui-faq-avatar-border);
}
.faq__card.border-mask::before {
  background: linear-gradient(99.28deg, var(--pui-faq-border-start) 0%, var(--pui-faq-border-end) 15%, var(--pui-faq-border-end) 85%, var(--pui-faq-border-start) 100%);
}
.faq__card .btn { width: 100%; }
/* @include media(tablet) → do 1023.98px: kolumna, lewa strona traci sztywną
   szerokość, przycisk karty kurczy się do treści. */
@media (max-width: 1023.98px) {
  .faq__layout { flex-direction: column; }
  .faq__left { flex: 1 1 100%; max-width: 100%; }
  .faq__card .btn { width: fit-content; }
}
/* @include media(mobile) → do 767.98px: prawa strona traci minimalną szerokość,
   przycisk wraca na pełną. Próg mobile stoi PO tablecie, bo w kodzie jest
   zagnieżdżony w tym samym bloku i wygrywa kolejnością. */
@media (max-width: 767.98px) {
  .faq__right { min-width: unset; }
  .faq__card .btn { width: 100%; }
}

/* --- elements/animations.scss ---------------------------------------------
   Cztery wartości stoją w kodzie zmiennymi SCSS ($ap-primary itd.), czyli
   literałami po kompilacji. Przepisane literałem — kandydat na token, RZ-66. */
[data-anim] { opacity: 0; transition: all 0.3s ease-out; }
[data-anim-element], [data-anim-graphic], [data-anim-feature] { transform: translateY(48px); }
[data-anim-side] { transform: translateX(48px); }
@keyframes pulse { 40% { opacity: 1; } 100% { width: 500%; height: 500%; opacity: 0; } }
@keyframes pulseOutline { 100% { width: 400%; height: 400%; opacity: 0; } }
.animation-pulse { opacity: 0; position: relative; }
.animation-pulse::before, .animation-pulse::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: -1; }
.animation-pulse::before { border: 1px solid var(--pui-animation-pulse-ring-outer); animation: pulse var(--pui-animation-pulse-duration) 0.1s ease-in-out infinite; animation-play-state: paused; opacity: 0; }
.animation-pulse::after { border: 1px solid var(--pui-animation-pulse-ring-inner); animation: pulse var(--pui-animation-pulse-duration) 1.1s ease-in-out infinite; animation-play-state: paused; opacity: 0; }
.animation-pulse[data-anim-in] { opacity: 1; }
.animation-pulse[data-anim-in]::before, .animation-pulse[data-anim-in]::after { animation-play-state: running; }
.animation-pulse--dot { width: 10px; height: 10px; background-color: var(--pui-animation-pulse-dot-bg); border-radius: 50%; position: absolute; }
.animation-pulse--dot::before { opacity: 0; border: unset; background-color: var(--pui-animation-pulse-dot-halo); }
.animation-pulse--dot::after { content: unset; }
.animation-pulse--dot-xs { width: 5px; height: 5px; }
.animation-pulse--dot-sm { width: 8px; height: 8px; }
.animation-pulse--dot-lg { width: 12px; height: 12px; }
.animation-pulse--outline::after { border-color: var(--pui-animation-pulse-dot-bg); animation: pulseOutline var(--pui-animation-pulse-duration) 1s ease-out infinite; content: ''; }

/* WARIANT --stars — PRZEPISANY 19.08.2026 ze zgłoszenia zamawiającego, z
   elements/animations.scss linie 163-188 oraz klatki 190-212.

   BRAK BYŁ NAZWANY I NIE ZOSTAŁ ZAMKNIĘTY: strona `Fundament - Animacje` ma go
   na liście „nieprzeniesione, do nadrobienia" od pierwszego przejazdu rodziny,
   a `Navigation.dc.html` stawia znacznik od 12.08 — czyli klasy
   `animation-pulse--stars`, `first-star` i `second-star` jechały przez tydzień
   BEZ ANI JEDNEJ REGUŁY. Objaw jest zerowy w zrzucie: gwiazdki mają w rysunku
   własny kształt i barwę, więc rysują się poprawnie; nie mają tylko położenia
   (position: absolute) ani migotania, a element bez animacji wygląda jak
   element ze skończoną animacją.

   `position: relative !important` jedzie ze `!important` z kodu — to nie nasza
   podniesiona ważność. W produkcie ta klasa wchodzi na `<a class="nav__link">`,
   które ma własne `position`, i tamten literał jest tu jedynym powodem. */
.animation-pulse--stars { position: relative !important; }
.animation-pulse--stars .first-star,
.animation-pulse--stars .second-star { display: inline-block; transform-origin: center; scale: 0.4; opacity: 0; position: absolute; }
.animation-pulse--stars .first-star { animation: pulseStar-1 var(--pui-animation-pulse-star-duration) infinite; bottom: -3px; left: -7px; }
.animation-pulse--stars .second-star { animation: pulseStar-2 var(--pui-animation-pulse-star-duration) infinite; right: 18px; top: 0px; }
/* @include respond-to("tablet") → do 1023.98px: druga gwiazdka przechodzi
   z prawej krawędzi na stałe 108 px od lewej. */
@media (max-width: 1023.98px) {
  .animation-pulse--stars .second-star { right: unset; left: 108px; }
}
@keyframes pulseStar-1 { 0% { opacity: 0; } 30% { opacity: 1; } 100% { opacity: 0; } }
@keyframes pulseStar-2 { 0% { opacity: 0; } 70% { opacity: 1; } 100% { opacity: 0; } }

/* =============================================================================
   PRZYCISK HERO — transpozycja bloku <style lang="scss" scoped> z
   `app/components/ui/controls/Button.vue` (linie 136-410) oraz `.border-mask`
   z `app/assets/css/helpers/custom.scss` (linie 1-17).

   DLACZEGO TO STOI TUTAJ, A NIE W CZĘŚCI PRZEPISANEJ Z elements/buttons.scss:
   wariant hero ma DRUGIEGO WŁAŚCICIELA. `elements/buttons.scss` o nim tylko WIE
   — wyłącza go ze swoich rozmiarów dziesięcioma zaprzeczeniami `:not(.btn--hero)`
   — ale ani jednej reguły, która hero maluje, w tym arkuszu nie ma. Cały wygląd
   mieszka w scoped style komponentu, więc do klasy nie da się dojść bez montowania
   komponentu Vue. To ta sama rodzina co RZ-72; zapisane jako RZ-76.

   Dwie rzeczy, które przy przepisywaniu wyszły i których nie poprawiam, bo są
   odczytem, nie usterką transpozycji:

   1. HERO MIESZA RODZINY ROZMIARÓW IKONY. W bazowym: szerokość z
      --pui-hero-button-base-icon-size, a WYSOKOŚĆ z --pui-button-sm-icon-size.
      W --lg: szerokość z --pui-hero-button-lg-icon-size, wysokość z
      --pui-button-base-icon-size. Tylko --sm bierze oba wymiary z rodziny hero.
      Ikona hero jest więc prostokątem, nie kwadratem, i to nie jest zaokrąglenie.
   2. TŁO HOVERU CZYTA ROLĘ SPOZA SYSTEMU NAZW: --Hero-button-solid-bg-hover,
      z wielką literą i bez prefiksu --pui-. Rola o tej nazwie nie istnieje
      w repozytorium, więc zawsze zadziała wartość zapasowa po przecinku.
      To jedna z jedenastu nazw spoza obu konwencji (RZ-35).

   Poświata hoveru i przygaszenie kliknięcia idą przez ELEMENT POTOMNY
   `.after-hover` i pseudoelement `::after`, oba z z-index: -1. Przy z-index
   ujemnym element potomny wchodzi POD tło przycisku, więc gradient hoveru
   pokazuje się tylko dlatego, że tło przycisku jest nieprzezroczyste, a
   pseudoelement rysuje się nad nim. Kolejność jest w kodzie i tu jest zachowana.
   ========================================================================== */

.border-mask { border: none !important; position: relative; }
.border-mask::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
}

/* DRUGA KLASA TEGO SAMEGO PLIKU — DOPISANA 19.08.2026 (RM-06), brak wcześniejszej
   transpozycji. helpers/custom.scss ma 38 linii i dwie klasy: .border-mask,
   czytaną przez 16 plików, oraz .section__frame — ramę SZKŁA, którą wołają
   dokładnie dwie strony (roadmap.vue, changelog.vue). Przepisana została ta
   pierwsza, bo tylko ona miała wtedy użycie; druga wyszła dopiero wtedy, gdy
   Roadmap weszła do katalogu, i wyszła z przeglądu, nie ze złożenia.
   Ta sama klasa błędu co RM-01 i RM-05, tym razem na poziomie PLIKU.

   position: relative W KODZIE NIE MA i to nie jest przeoczenie odczytu:
   .border-mask stawia go w pierwszej deklaracji, .section__frame nie stawia go
   wcale, a niesie ten sam ::before z inset: 0. Pierścień liczyłby się więc od
   najbliższego pozycjonowanego przodka, czyli od .container (Section.vue), i był
   o dwie wyściółki kontenera szerszy od ramy — rozpisane w RZ-93.

   NAZWANE ODSTĘPSTWO OD KODU, decyzja zamawiającego 19.08.2026: katalog dokłada
   position: relative, żeby pierścień otaczał ramę. Jedna deklaracja, wpisana
   TUTAJ i nigdzie więcej, żeby dług repozytorium został widoczny w RZ-93. */
.section__frame {
  position: relative;
  padding: 8px;
  background: var(--pui-banner-graphic-bg-overlay);
  border-radius: var(--pui-overlay-main-bg-outside-radius);
}
.section__frame::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
  background: linear-gradient(113.79deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 5.75%), linear-gradient(243.3deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 4.79%), linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 90%);
}

/* --- hero solid ----------------------------------------------------------- */
.btn--hero {
  display: flex; align-items: center; justify-content: center; position: relative;
  min-width: var(--pui-hero-button-base-width-min); min-height: var(--pui-hero-button-base-height-min);
  column-gap: var(--pui-hero-button-base-gap-h); row-gap: var(--pui-hero-button-base-gap-v);
  border-radius: var(--pui-hero-button-base-radius);
  background: linear-gradient(94deg, var(--pui-hero-button-solid-bg-start) 0.25%, var(--pui-hero-button-solid-bg-end) 99.75%);
  color: var(--pui-hero-button-solid-fg);
  will-change: transform; transform: translateZ(0); backface-visibility: hidden;
  height: auto; padding: var(--pui-hero-button-base-padding-v) var(--pui-hero-button-base-padding-h);
  -webkit-font-smoothing: antialiased;
}
.btn--hero:has(.btn__subtitle) { flex-direction: column; }
.btn--hero .btn__content { display: flex; flex-direction: column; align-items: center; justify-content: center; }
.btn--hero .btn__text { font-size: var(--pui-text-p-xlg-font-size); line-height: var(--pui-text-p-xlg-line-height); font-weight: 600; display: flex; align-items: center; gap: 8px; }
.btn--hero .btn__subtitle { font-size: var(--pui-text-p-xs-font-size); line-height: var(--pui-text-p-xs-line-height); font-weight: 300; }
/* Szerokość z rodziny hero, wysokość z rodziny zwykłego przycisku — tak w kodzie. */
.btn--hero .btn__icon { width: var(--pui-hero-button-base-icon-size); height: var(--pui-hero-button-base-icon-size); display: flex; align-items: center; justify-content: center; }
/* ZWĘŻONE DO DZIECKA BEZPOŚREDNIEGO, i to jest naprawa przeniesienia, nie zmiana
   produktu. W repo ta reguła stoi w bloku scoped Button.vue (linia 186) BEZ
   :deep(), więc Vue dokleja jej atrybut zakresu i nie ma ona jak dosięgnąć
   wnętrza innego komponentu — svg-i z AnimatedDownload.vue należą do zakresu
   ikony, nie przycisku. W płaskim arkuszu zakres znika, więc reguła sięgała tam,
   gdzie w produkcie nie sięga: rozciągała tackę 22×8 do 20×20 i rozbijała ikonę.
   Zmierzone 11.08.2026: .download-icon__union 20×20 zamiast 20×7.
   RZ-77 — cała rodzina reguł scoped bez :deep() ma ten sam problem. */
.btn--hero .btn__icon > svg { width: 100%; height: 100%; }

.btn--hero.btn--lg { min-width: var(--pui-hero-button-lg-width-min); min-height: var(--pui-hero-button-lg-height-min); padding: var(--pui-hero-button-lg-padding-v) var(--pui-hero-button-lg-padding-h); border-radius: var(--pui-hero-button-lg-radius); }
.btn--hero.btn--lg .btn__icon { width: var(--pui-hero-button-lg-icon-size); height: var(--pui-hero-button-lg-icon-size); }
.btn--hero.btn--lg .btn__text { font-size: var(--pui-text-p-xxlg-font-size); line-height: var(--pui-text-p-xxlg-line-height); }

.btn--hero.btn--sm { min-width: var(--pui-hero-button-sm-width-min); min-height: var(--pui-hero-button-sm-height-min); padding: var(--pui-hero-button-sm-padding-v) var(--pui-hero-button-sm-padding-h); border-radius: var(--pui-hero-button-sm-radius); }
.btn--hero.btn--sm .btn__icon { width: var(--pui-hero-button-sm-icon-size); height: var(--pui-hero-button-sm-icon-size); }
.btn--hero.btn--sm .btn__text { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); }
.btn--hero.btn--sm .btn__subtitle { font-size: var(--pui-text-p-xxs-font-size); line-height: var(--pui-text-p-xxs-line-height); }

/* WARIANT FIOLETOWY HERO — ATOM, 25.08.2026, polecenie zamawiającego („czy mozemy zrobic wariant
   fioletowy, ktory bedzie podobny do tego stylem? jezeli tak to zrob do atomu i zrob to samo
   w CTA"). ROZSZERZENIE DS, NIE ODCZYT: produkcja zna hero wyłącznie pomarańczowe, więc przy
   porcie ta klasa i rodzina ról `--pui-hero-button-purple-*` muszą pojechać razem.
   Cała geometria — rozmiar, promień, wyściółka, rozmiary pisma, stany, maska obwiedni —
   zostaje z `.btn--hero`; ta klasa zmienia WYŁĄCZNIE barwy, dlatego stoi jako modyfikator
   obok, a nie jako druga rodzina. */
.btn--hero-purple { background: linear-gradient(94deg, var(--pui-hero-button-purple-bg-start) 0.25%, var(--pui-hero-button-purple-bg-end) 99.75%); color: var(--pui-hero-button-purple-fg); }
.btn--hero-purple::after { background: var(--pui-hero-button-purple-bg-active); }
/* HOVER MALUJE WARSTWA `.after-hover`, NIE TŁO PRZYCISKU — poprawka 25.08.2026 ze zgłoszenia
   zamawiającego („hover buttona become partner tez ma byc fioletowa, nie pomaranczowa"). Wariant
   ustawiał tylko `background` korzenia, a rodzina hero rozjaśnia się WARSTWĄ nad nim
   (`.btn--hero .after-hover`, gradient z ról pomarańczowych) — więc fioletowy przycisk
   robił się po najechaniu pomarańczowy. Objaw do zapamiętania: barwa stanu, która wraca
   do rodziny bazowej mimo poprawnego wariantu, siedzi w OSOBNYM WĘŹLE, nie w tle. */
.btn--hero.btn--hero-purple .after-hover { background: linear-gradient(94deg, var(--pui-hero-button-purple-bg-hover-start) 0.25%, var(--pui-hero-button-purple-bg-hover-end) 99.75%); }
.btn--hero-purple:hover { background: linear-gradient(94deg, var(--pui-hero-button-purple-bg-hover-start) 0.25%, var(--pui-hero-button-purple-bg-hover-end) 99.75%); }

/* Obwiednia maski hero solid jest BIAŁA I WPISANA WPROST, bez roli. */
.btn--hero.border-mask::before { background: linear-gradient(180deg, rgba(255,255,255,0.3) 0%, #FFFFFF 50%, rgba(255,255,255,0.3) 100%); }

.btn--hero::after { content: ""; position: absolute; inset: 0; opacity: 0; transition: opacity 200ms ease; pointer-events: none; background: var(--pui-hero-button-solid-bg-active); z-index: -1; border-radius: inherit; }
.btn--hero .after-hover { position: absolute; inset: 0; opacity: 0; transition: opacity 200ms ease; pointer-events: none; z-index: -1; border-radius: inherit; background: linear-gradient(94deg, var(--pui-hero-button-solid-bg-hover-start) 0.25%, var(--pui-hero-button-solid-bg-hover-end) 99.75%); }
.btn--hero:hover { transform: scale(104%); }
.btn--hero:hover .after-hover { opacity: 1; }
.btn--hero:active::after { opacity: 1; }
.btn--hero:has(.download-icon):hover .download-icon__arrows { top: 1px; }
.btn--hero.btn--sm:has(.download-icon):hover .download-icon__arrows { top: -1px; }
.btn--hero.btn--lg:has(.download-icon):hover .download-icon__arrows { top: 4px; }
.btn--hero:has(.arrowright-icon):hover .arrowright-icon__arrows { right: -16px; }

/* --- hero outline --------------------------------------------------------- */
/* Wariant z wysuwaną strzałką: napis stoi odsunięty o 18px i wraca na 0 pod
   wskaźnikiem, a strzałka jedzie z prawej i wchodzi z przezroczystości. */
.btn--hero-outline {
  display: flex; align-items: center; justify-content: center; position: relative;
  min-width: var(--pui-hero-button-base-width-min); min-height: var(--pui-hero-button-base-height-min);
  column-gap: var(--pui-hero-button-lg-gap-h); row-gap: var(--pui-hero-button-base-gap-v);
  background: var(--pui-hero-button-outline-bg); color: var(--pui-hero-button-outline-fg);
  will-change: transform;
  padding: var(--pui-hero-button-base-padding-v) var(--pui-hero-button-base-padding-h);
  border-radius: var(--pui-hero-button-base-radius);
}
.btn--hero-outline .btn__content { display: flex; flex-direction: column; align-items: center; justify-content: center; }
/* PISMO OUTLINE ZRÓWNANE ZE SOLIDEM — 26.08.2026, decyzja zamawiającego („ok, rob 1”) po jego
   pytaniu „dlaczego te dwa buttony maja rozne rozmiary czcionek? to jest jedna rodzina
   wiec powinno byc jednakowe”. To POPRAWKA WZGLĘDEM REPO, nie odczyt: produkt daje parze
   hero dwa różne stopnie na każdym rozmiarze — base 20 kontra 17, lg 24 kontra 20,
   sm 15 kontra 14 (`Button.vue`, blok scoped). Wybrany kierunek: outline idzie W GÓRĘ do
   stopnia solidu, bo solid jest przyciskiem wiodącym i jego stopień stoi w mockupie.
   Rozjazd zgłoszony jako B-7 w `TODO - repo vs katalog.md` i tam ma być domknięty
   przy porcie: bez zmiany w repo to nadpisanie wróci jako różnica.
   ZASIĘG: każde hero z parą przycisków — homepage, osiem stron person, Partners, Coolify. */
.btn--hero-outline .btn__text { font-size: var(--pui-text-p-xlg-font-size); line-height: var(--pui-text-p-xlg-line-height); font-weight: 600; display: flex; align-items: center; gap: 8px; left: 18px; transition: all 0.3s ease; position: relative; }
.btn--hero-outline .animate-arrow { width: var(--pui-hero-button-base-icon-size); height: var(--pui-hero-button-base-icon-size); position: relative; right: 10px; opacity: 0; transition: all 0.3s ease; }

.btn--hero-outline.btn--lg { min-width: var(--pui-hero-button-lg-width-min); min-height: var(--pui-hero-button-lg-height-min); padding: var(--pui-hero-button-lg-padding-v) var(--pui-hero-button-lg-padding-h); border-radius: var(--pui-hero-button-lg-radius); }
.btn--hero-outline.btn--lg .btn__text { font-size: var(--pui-text-p-xxlg-font-size); line-height: var(--pui-text-p-xxlg-line-height); }
.btn--hero-outline.btn--lg .animate-arrow { width: var(--pui-hero-button-lg-icon-size); height: var(--pui-hero-button-lg-icon-size); }
.btn--hero-outline.btn--sm { min-width: var(--pui-hero-button-sm-width-min); min-height: var(--pui-hero-button-sm-height-min); padding: var(--pui-hero-button-sm-padding-v) var(--pui-hero-button-sm-padding-h); border-radius: var(--pui-hero-button-sm-radius); }
.btn--hero-outline.btn--sm .btn__text { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); left: 13px; }
.btn--hero-outline.btn--sm .animate-arrow { width: var(--pui-hero-button-sm-icon-size); height: var(--pui-hero-button-sm-icon-size); right: 10px; }

.btn--hero-outline.border-mask::before { background: linear-gradient(180deg, var(--pui-hero-button-outline-border-start) 0%, var(--pui-hero-button-outline-border-end) 50%, var(--pui-hero-button-outline-border-start) 100%); transition: background 0.2s ease; }
.btn--hero-outline.border-mask:hover::before { background: linear-gradient(180deg, var(--pui-hero-button-outline-border-hover-start) 0%, var(--pui-hero-button-outline-border-hover-end) 50%, var(--pui-hero-button-outline-border-hover-start) 100%); }
.btn--hero-outline.border-mask:active::before { background: linear-gradient(180deg, var(--pui-hero-button-outline-border-active-start) 0%, var(--pui-hero-button-outline-border-active-end) 50%, var(--pui-hero-button-outline-border-active-start) 100%); }

/* Hero outline ODWOŁUJE powiększenie, które hero solid dodaje. */
.btn--hero-outline:hover { transform: unset; background: var(--pui-hero-button-outline-bg-hover); }
.btn--hero-outline.btn:hover .btn__text { left: 0; }
.btn--hero-outline.btn:hover .animate-arrow { right: 0; opacity: 1; }
.btn--hero-outline:active { background: var(--pui-hero-button-outline-bg-active); }

/* --- ikony animowane hero ---------------------------------------------------
   Przepisane 11.08.2026 z bloków scoped `icons/AnimatedDownload.vue`
   i `icons/AnimatedArrowRight.vue`. Wchodzą do arkusza z tego samego powodu,
   z którego wszedł hero: bez nich reguły `:has(.download-icon):hover` mają co
   dosuwać w kodzie, a nie mają czego dosunąć w arkuszu — `top` na elemencie
   bez `position` jest deklaracją bez skutku, więc pomiar pokazywałby zgodność
   liczby, która niczego nie przesuwa.

   ODCZYT: te reguły NIE MAJĄ ANI JEDNEJ ROLI. Wszystkie dwadzieścia jeden
   wartości stoi w kodzie wprost, łącznie z dosunięciami -20px, -23px i -17px,
   które są korektą optyczną zależną od rozmiaru przycisku. To ta sama rodzina
   braku co RZ-72 i RZ-35: warstwa ruchu nie ma tokenów. */
.download-icon { width: inherit; height: inherit; position: relative; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.download-icon__arrows { position: absolute; display: flex; flex-direction: column; gap: 8px; align-self: center; top: -20px; transition: top .5s ease; }
.download-icon__arrows svg { height: inherit; }
.download-icon__union { position: absolute; bottom: 0; width: inherit; }
.btn.btn--hero.btn--sm .download-icon__arrows { top: -23px; }
.btn.btn--hero.btn--lg .download-icon__arrows { top: -17px; }

.arrowright-icon { width: inherit; height: inherit; position: relative; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.arrowright-icon__arrows { position: absolute; display: flex; flex-direction: row; gap: 6px; align-self: center; transition: right .5s ease; right: 4px; }

/* --- ui/typography/*.vue (bloki scoped) ------------------------------------
   Kolor nagłówka i akapitu NIE STOI w warstwie klas produktu — mieszka w blokach
   scoped komponentów Heading.vue i Paragraph.vue, jako reguła na TAG (h1..h6, p).
   Klasa .text-* niesie wyłącznie rozmiar, interlinię i tracking.

   Skutek zmierzony 12.08.2026: element z samą klasą .text-h7 dostaje czerń
   przeglądarki, a nie --pui-text-heading. W produkcie tego nie widać, bo klasę
   nadaje ten sam komponent, który niesie kolor; poza nim klasa jest niepełna.

   Przenosimy to na selektor klasowy, bo reguła na goły tag pomalowałaby także
   nagłówki katalogu, które do produktu nie należą. To JEDYNE odstępstwo od
   przepisania 1:1 w tej sekcji i stoi tu nazwane, nie ukryte. Zgłoszone jako RZ-78.

   DOMIAR 05.09.2026 — ODSTĘPSTWO MIAŁO SKUTEK, KTÓREGO NIKT NIE ZMIERZYŁ. Reguła na
   KLASIE ma tę samą specyficzność co `.text-variant-*` i stoi w arkuszu PÓŹNIEJ, więc
   **unieważniała całą oś barwy semantycznej**: element z klasą stopnia i klasą barwy
   dostawał barwę stopnia, a nie tę, o którą prosił. Trzynaście klas malowało jeden
   kolor. W produkcie tego skutku NIE MA, bo tam barwa siedzi na TAGU (specyficzność
   0,0,1) i przegrywa z każdą klasą.

   Poprawka wierna produktowi: te same deklaracje w `:where(…)`, czyli o specyficzności
   ZERO — dokładnie tak, jak zachowuje się reguła na tagu. Odstępstwo zostaje (kolor
   dochodzi do elementu z samą klasą stopnia), a oś barwy znów wygrywa. */
:where(.text-h1, .text-h2, .text-h3, .text-h4, .text-h5, .text-h6, .text-h7, .text-h8) { color: var(--pui-text-heading); transition: color 0.3s ease; }
:where(.text-p-xxlg, .text-p-xlg, .text-p-lg, .text-p-base, .text-p-sm, .text-p-xs, .text-p-xxs) { color: var(--pui-text-body); }


/* =============================================================================
   layout/Footer.vue + ui/footer/Column.vue + ui/footer/Link.vue (bloki scoped)
   Odczyt 12.08.2026. NAZWY KLAS BEZ ZMIAN — tak stoją w kodzie produkcyjnym.

   Pierwszy komponent przepisany w ramach P2.2a. Reguły pochodzą z trzech
   plików, bo stopka jest w kodzie złożeniem trzech komponentów; kolumna
   i odnośnik mają własne bloki scoped i własne rodziny klas.

   ZAWĘŻENIA WZGLĘDEM ŹRÓDŁA, wszystkie nazwane (RZ-77: reguła scoped bez
   :deep() sięga w płaskim arkuszu dalej niż w produkcie):
   — .footer__heading ma w źródle font-weight na sobie, nie na potomkach;
     tu zostaje tak samo, ale bez reguły na goły tag.
   — .footer-link:hover .footer-link__text: w źródle zagnieżdżone w bloku
     scoped odnośnika, więc trafia wyłącznie we własny tekst. Selektor
     potomka zapisany wprost daje ten sam zasięg.
   ============================================================================= */

/* --- layout/Footer.vue ---------------------------------------------------- */
/* var(--bg) NIE JEST ROLĄ i nie jest zdefiniowane nigdzie w app/ — nazwa
   występuje w całym repozytorium DOKŁADNIE RAZ, w tej jednej deklaracji.
   Tło stopki rozwiązuje się więc na nic i stopka jest przezroczysta, biorąc
   kolor tego, co pod nią leży. Przepisane wprost, bo tak stoi w kodzie.
   Zgłoszone jako RZ-84. */
.footer { width: 100%; background: var(--bg); }
.footer__top { padding: var(--pui-footer-padding-v) 0; }
.footer__sitemap { display: flex; flex-wrap: wrap; gap: var(--pui-footer-gap); justify-content: space-between; align-items: flex-start; }
/* flex: 1 1 1 — trzecia wartość jest długością bazową, nie liczbą, więc
   przeglądarka odrzuca całą deklarację skrótu. Przepisane wprost: usunięcie
   albo poprawienie byłoby zmianą wyglądu wprowadzoną po cichu. RZ-85. */
.footer__left { flex: 1 1 1; min-width: var(--pui-footer-left-column-min-width); max-width: var(--pui-footer-left-column-max-width); display: flex; flex-direction: column; gap: var(--pui-footer-left-column-gap); width: 100%; }
.footer__section { display: flex; flex-direction: column; gap: var(--pui-footer-right-column-section-gap); }
.footer__right { flex: 2; display: flex; gap: var(--pui-footer-gap); flex-wrap: wrap; align-items: flex-start; width: 100%; }
.footer__heading { font-weight: 600; }
.footer__heading--community { color: var(--pui-footer-community-heading); }
.footer__guides-card { border-color: var(--pui-footer-guides-border); border-radius: var(--pui-footer-left-column-guides-radius); padding: var(--pui-footer-left-column-guides-padding-v) var(--pui-footer-left-column-guides-padding-h); width: 100%; flex: unset; }
.footer__guides { display: flex; flex-direction: column; gap: var(--pui-footer-left-column-guides-gap); }
/* PAS FUNKCJI POD MAPĄ STRONY — wariant F-02 szkicu stopki (24.08.2026). Reguła stoi
   w arkuszu, a nie w atrybutach szkicu, bo tak każe warunek 2 schematu szkiców: wartość,
   która ma trafić do produktu, wchodzi od razu do klasy — inaczej wraca jako druga decyzja
   przy przepisywaniu. STAN: propozycja. Jeśli F-02 przegra, ta reguła schodzi razem
   ze szkicem (pozycja w `TODO.md`); dziś nie czyta jej żadna strona produktu.
   BRAK ZGŁOSZONY W CHWILI WPISANIA: rodzina `--pui-footer-*` nie ma roli na odstęp
   POZIOMY między pozycjami w wierszu — pas stoi tymczasowo na `--pui-footer-left-column-gap-h`,
   czyli roli z innego miejsca. Nie dorabiam roli sam. */
.footer__row { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--pui-footer-right-column-gap-v) var(--pui-footer-gap); }
.footer__row-links { display: flex; flex-wrap: wrap; flex: 1; gap: var(--pui-footer-right-column-gap-v) var(--pui-footer-left-column-gap-h); }
.footer__row-links .footer-link { flex: 0 0 auto; width: auto; }

/* WARIANTY KONDENSACJI STOPKI — szkic F-04…F-07 (24.08.2026, polecenie zamawiającego: „stopka ma
   byc bardziej skondensowana… podrasuj guides, na wysokosc ma byc mniejsza, moze guides
   wezsze, mniejsze, nie usuwaj linkow jezlei klient tego nie prosil”).
   Reguły stoją w arkuszu, nie w atrybutach szkicu — warunek 2 schematu szkiców. STAN:
   propozycje. Warianty, które przegrają, schodzą razem ze szkicem (pozycja w `TODO.md`).
   ŻADNA z nich nie usuwa treści: zmieniają wyłącznie to, ile miejsca ta sama treść zajmuje.
   BRAKI ZGŁOSZONE W CHWILI WPISANIA: rodzina `--pui-footer-*` nie ma roli na (1) odstęp
   poziomy pozycji w wierszu, (2) gęstszy wariant listy „Guides”. Oba miejsca pożyczają
   role z sąsiedztwa (`--pui-footer-left-column-gap-h`, `--pui-footer-right-column-gap-v`),
   co jest jawnym długiem, nie rozwiązaniem — nie dorabiam ról sam. */
.footer__guides--dwie { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--pui-footer-gap); }
.footer__guides--trzy { display: grid; grid-template-columns: repeat(3, 1fr); column-gap: var(--pui-footer-gap); }
.footer__guides--gesta { gap: var(--pui-footer-right-column-gap-v); }
.footer__guides--gesta .footer-link__text { font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height-tight); }
.footer__left--waska { min-width: 0; max-width: var(--pui-footer-left-column-min-width); }
.footer__left--pelna { min-width: 0; max-width: none; flex: 1 1 100%; width: 100%; }

/* CIAŚNIEJSZY RYTM LIST — wariant F-08. To jest PRZEDEFINIOWANIE RÓL, nie wpisanie wartości
   obok nich: klasa nadaje rolom stopki inne wartości ze skali, dokładnie tak, jak robi to
   warstwa tokenów. Nadpisanie stoi LOKALNIE przy szkicu i nie dotyka `pa-tokens.css` —
   etap roboczych mockupów, zasada 4. Po akceptacji przenosi się do tokenów jako zmiana
   wartości tych trzech ról, co dotknie CAŁEJ stopki na wszystkich stronach. */
.footer--ciasny { --pui-footer-right-column-gap-v: var(--static-space-1x); --pui-footer-right-column-section-gap: var(--static-space-1-5x); --pui-footer-left-column-guides-gap: var(--static-space-1x); }

/* GUIDES W JEDNEJ LINII — runda 3 szkicu stopki (24.08.2026, polecenie zamawiającego: „Guides
   trzeba przebudować mocniej"). Tytuły wpisów mają 60–80 znaków i to ONE robią wysokość:
   w wąskiej kolumnie każdy łamie się na dwie–trzy linie. Przycięcie do jednej linii nie
   usuwa ani jednego wpisu — pełny tytuł zostaje w `title`, więc czyta go i człowiek,
   i wyszukiwarka.
   NOWY MECHANIZM W PROJEKCIE: `-webkit-line-clamp` nie występuje dziś nigdzie indziej
   w `pa-klasy.css`. Zgłaszam to jako nowy wzorzec do decyzji, nie przemycam. */
/* TYTUŁ WPISU W JEDNEJ LINII — PRZEZ `text-overflow`, NIE PRZEZ `-webkit-line-clamp`.
   PRZYCZYNA, zmierzona 24.08.2026 przez przegląd: `.footer-link__text` jest DZIECKIEM FLEKSA
   (`.footer-link` ma `display:flex`), więc przeglądarka blokifikuje mu `display` — zadeklarowane
   `-webkit-box` stało się `flow-root` i clamp przestał istnieć. Tekst był ucinany samą
   szerokością pudełka, BEZ wielokropka: cztery wpisy wyglądały identycznie i nikt nie widział,
   że coś ucięto. Dwa warunki, oba konieczne: `min-width: 0` na dziecku fleksa (bez tego nie
   kurczy się poniżej treści) oraz `nowrap` + `ellipsis` na tekście. */
/* IKONA PASA PRZED NAPISEM, WIĘKSZA (zgłoszenie zamawiającego 24.08.2026: „ta ikonka całkiem z lewej
   strony i większa"). Nagłówek staje się dwukolumnowy: znak | napis z odnośnikiem. */
/* Klasa podwojona: `.footer__guides-head` z `flex-direction: column` stoi w tym arkuszu
   NIŻEJ, więc przy równej specyficzności wygrywała i ikona wracała nad napis. */
.footer__guides-head.footer__guides-head--z-ikona { flex-direction: row; align-items: center; justify-content: center; gap: var(--static-space-2x); }
.footer__guides-mark { flex: none; width: var(--static-space-5x); height: var(--static-space-5x); }

/* MAŁA IKONA ARTYKUŁU PRZY KAŻDYM WPISIE, W ZIELENI MARKI („dodaj małą ikonkę artykułu dla
   każdego elementu z lewej strony, może być zielona"). Barwę daje MASKA na tym samym pliku,
   który niesie ikonę pasa — nie druga, przemalowana kopia zasobu. */
/* ZNAK PRZY WPISIE: `assets/features/FlatArrowRight.svg` z zestawu UI (Twoje słowo: „mamy
   ikonki UI w SVG, przypisz jakąś"). Wybór jest świadomy i mówię dlaczego: w zestawie UI
   (`assets/flat`, `assets/features`, `assets/banner-icons` — 37 plików) NIE MA ikony artykułu
   ani dokumentu; jedyne dwie pasujące tematem, Blog.svg i Documentation.svg, leżą w rodzinie
   nawigacji, mają barwy wpisane w plik i nie reagują na motyw. Strzałka znaczy „przejdź do
   wpisu", czyli to, czym ten element jest, i jako jedyna nie udaje rysunku, którego nie ma.
   Barwę daje maska, więc znak bierze zieleń marki i zmieni się z rolą, nie z plikiem. */
.footer-link__mark { flex: none; width: var(--static-space-2x); height: var(--static-space-2x); background: var(--static-primary-500); -webkit-mask: url("assets/features/FlatArrowRight.svg") center / contain no-repeat; mask: url("assets/features/FlatArrowRight.svg") center / contain no-repeat; }
.footer__guides--jedna-linia .footer-link { min-width: 0; }
.footer__guides--jedna-linia .footer-link { gap: var(--static-space-1x); }
.footer__guides--jedna-linia .footer-link__text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ETYKIETA GRUPY W STOPCE — ten sam wygląd co w menu, ODSTĘP JEDEN. Zgłoszenie zamawiającego
   24.08.2026: „odstepy od tych nagłówkow z menu sa za duze od tekstu". Zmierzone:
   `.dropdown__sub-header` niesie 16 px wyściółki dolnej PLUS 12 px marginesu, a w stopce
   dochodzi jeszcze `gap` kontenera `.footer__section` — razem 36 px nad pierwszą pozycją.
   W menu te 28 px pracuje, bo pozycje mają ikonę i opis; w stopce nad nagą listą to dziura.
   ZERUJĘ OBA WŁASNE NOŚNIKI ETYKIETY i zostawiam sam `gap` kontenera — dokładnie ta sama
   poprawka co dziś w menu („dwa nośniki tego samego odstępu"), nie trzeci nośnik obok. */
.footer .dropdown__sub-header { padding-bottom: 0; margin-bottom: 0; }

/* PAS „GUIDES" — wariant F-14 (polecenie zamawiającego: „skondensuj box z guides, moze dodaj jakies
   ikonki artykułów, moze nagłówek w boxie, moze guides oddzielone dividerem od calosci").
   Cztery rzeczy naraz i każda jest osobną klasą, żeby dało się je rozdzielić przy ocenie. */
/* PAS „GUIDES" NA DOLE, BEZ KRESKI — zgłoszenie zamawiającego 24.08.2026: „mniejsze radiusy,
   mniejsze spacingi miedzy kolumnami, przenies na dol, usun divider pomiedzy".
   Kolejność robi `order`, nie przeniesienie w szablonie: pas ma w kodzie zostać przy swoim
   wariancie, a `.footer__sitemap` jest fleksem, więc miejsce w rzędzie jest własnością
   układu, nie znacznika. */
/* ODSTĘP LINKI → PAS „GUIDES": JEDEN NOŚNIK, NIE DWA (zgłoszenie zamawiającego 24.08.2026:
   „zmniejsz odstęp pomiędzy linkami i guides"). Zmierzone: 104 px = `row-gap` mapy strony
   (80 px, rola `--pui-footer-gap`, pomyślana jako odstęp MIĘDZY KOLUMNAMI) plus własny
   margines pasa (24 px). Margines schodzi, a sam odstęp bierze rolę sekcji — pas jest
   sąsiadem mapy, nie jej kolumną. */
/* ODSTĘP MAPA STRONY → PAS „GUIDES" +16 px (zgłoszenie zamawiającego 24.08.2026: odstęp między boxem
   Guides a sekcją wyżej). Jeden nośnik: wiersz siatki `.footer__sitemap`, 24 → 40 px. Pas nie
   dostaje własnego marginesu, bo dwa nośniki tego odstępu już raz dały 104 px. Wartość ze
   skali — rodzina `--pui-footer-*` nie ma roli na odstęp między wierszami mapy strony
   (jej `--pui-footer-gap` opisuje odstęp MIĘDZY KOLUMNAMI). Brak zgłoszony. */
.footer__sitemap { row-gap: var(--static-space-5x); }
/* PAS „GUIDES" POD MAPĄ STRONY. Krótko stał nad mapą („przenieś ją nad linki"), cofnięte
   na Twoje słowo w tej samej rozmowie. Kolejność robi `order`, nie przestawianie znaczników:
   pas ma w kodzie zostać przy swoim wariancie, a `.footer__sitemap` jest fleksem. */
.footer__guides-band { order: 2; padding: 0; margin: 0; border-bottom: 0; }
/* Klasa podwojona w selektorze celowo: `.footer__guides-card` z rolą promienia stoi w tym
   arkuszu NIŻEJ, a przy równej specyficzności wygrywa reguła późniejsza — promień wracał
   wtedy na 32 px. To samo rozstrzygnięcie co przy `.footer__col--szeroka`.
   WYŚCIÓŁKA I OBWIEDNIA po zgłoszeniu zamawiającego 24.08.2026: „delikatnie większy padding,
   delikatnie słabszy border, może tak jak divider w pasku niżej" — obwiednia bierze więc
   `--pui-footer-divider`, dokładnie tę samą rolę co kreska dolnego paska, zamiast
   mocniejszej `--pui-footer-guides-border`. */
.footer__guides-card.footer__guides-card--zbita { padding: var(--static-space-3x); border-radius: var(--pui-ui-radius-2xl); border-color: var(--pui-footer-separator); }
/* Pas bez grafik z bloga (Twoje słowo): miniatury schodzą, zostaje sam tytuł. */
.footer__guides--bez-grafik .footer__guides-thumb { display: none; }
.footer__guides-card--zbita .footer__guides { column-gap: var(--pui-footer-left-column-gap-h); }
.footer__guides-card--zbita .footer__guides-thumb { border-radius: var(--pui-ui-radius-sm); }
/* Nagłówek pasa stoi OBOK wpisów, nie nad nimi — jeden rząd mniej. Zmierzone: pas
   z nagłówkiem nad wpisami dawał stopce 991 px przy dzisiejszych 967, czyli kierunek dobry
   i wynik za wysoki o jeden rząd tekstu. */
/* KOLUMNA PODWÓJNEJ SZEROKOŚCI — propozycja zamawiającego 24.08.2026: „może to podzielić na dwie
   kolumny, aby cały pasek był niższy? więc ta kolumna zajmowałaby dwie kolumny, wiersz miałby
   5 kolumn". Panel „Features" ma 12 pozycji w dwóch grupach i to on dyktował wysokość całego
   rzędu; dostaje podwójną szerokość, a jego dwie grupy stają obok siebie. Wiersz ma wtedy pięć
   ścieżek przy CZTERECH kolumnach mapy — granica z `Opis DS` zostaje zachowana, bo piąta
   ścieżka nie jest osobną kolumną, tylko drugą połówką tej samej. Nagłówek panelu idzie
   przez obie połówki. */
.footer__col.footer__col--szeroka { flex: 2 1 0; }
.footer__col--szeroka > .footer__section { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pui-footer-gap); align-items: start; }
.footer__col--szeroka > .footer__section > .footer__heading { grid-column: 1 / -1; }

/* PIĘĆ POMYSŁÓW NA BOX „GUIDES" — WSZYSTKIE PODPORZĄDKOWANE KONDENSACJI (24.08.2026,
   brzmienie zamawiającego: „wymaganie klienta jest żeby stopka była skondensowana, więc masz robić
   mając to na uwadze"). Pierwsza wersja tych pomysłów była BŁĘDEM: kafle miały 328 px,
   czyli trzy razy więcej niż pas, który miały zastąpić (102 px). Kryterium jest odtąd twarde
   i mierzone: pomysł, który nie schodzi pod wysokość dzisiejszego pasa, nie jest pomysłem.
   Wszystkie mają ten sam znacznik i tę samą treść — 7 wpisów; różni je tylko arkusz. */
.gp { display: grid; gap: var(--pui-footer-right-column-gap-v) var(--pui-footer-left-column-gap-h); }
.gp .footer-link { min-width: 0; }
.gp .footer-link__text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* G1 — CZTERY kolumny, bez miniatur. Liczba kolumn dobrana do MINIMALNEJ DŁUGOŚCI TYTUŁU,
   przy której wpisy da się rozróżnić, a nie do liczby wpisów: przy siedmiu kolumnach na tytuł
   zostawało ~10 znaków i cztery wpisy czytały się identycznie („PanelAlpha…") — ta sama
   usterka, którą naprawiałem w F-14. Cztery kolumny pokazują 20–22 znaki, czyli tyle,
   ile różnicuje wszystkie siedem tytułów tych danych. Złapał to przegląd. */
.gp--g1 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gp--g1 .footer__guides-thumb { display: none; }

/* G2 — pastylki w SIATCE cztery na rząd, nie w swobodnym zawijaniu: `flex-wrap` z `max-width`
   rozkładało je na cztery rzędy przy węższym kontenerze (224 px, więcej niż pas). Siatka
   trzyma dwa rzędy przy każdej szerokości. */
.gp--g2 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gp--g2 .footer-link { padding: var(--static-space-0-5x) var(--static-space-1-25x); border-radius: var(--pui-ui-radius-rounded); background: var(--static-gray-50); }
.gp--g2 .footer__guides-thumb { display: none; }

/* G3 — cztery kolumny z małą okrągłą miniaturą: dwa rzędy, obrazek zostaje. */
.gp--g3 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gp--g3 .footer__guides-thumb { width: var(--static-space-2-5x); height: var(--static-space-2-5x); border-radius: var(--pui-ui-radius-rounded); }

/* G4 — dwa rzędy po cztery, wiersze rozdzielone kreską, bez miniatur. Spis treści. */
.gp--g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 var(--pui-footer-left-column-gap-h); }
.gp--g4 .footer-link { padding: var(--static-space-0-75x) 0; border-bottom: var(--pui-ui-border-divider-width) solid var(--pui-footer-divider); }
.gp--g4 .footer__guides-thumb { display: none; }

/* G6 — BELKA „CO NOWEGO", propozycja własna przyjęta 24.08.2026 („zbuduj, ale żeby była
   wizualnie ciekawa ale prosta"). Nie lista wpisów, a jeden rząd: ikona i napis po lewej,
   trzy PEŁNE tytuły w środku, odnośnik z akcentem po prawej. Trzy tytuły mieszczą się bez
   ucinania, więc znika cały problem wielokropka; wysokość to jeden rząd.
   Ciekawostka wizualna zrobiona jednym środkiem, nie pięcioma: tło bierze subtelny odcień
   powierzchni, a kropki rozdzielające tytuły są jedynym akcentem koloru. */
.gp--g6 { display: flex; align-items: center; gap: var(--pui-footer-left-column-gap-h); padding: var(--static-space-1-5x) var(--static-space-2-5x); border-radius: var(--pui-ui-radius-rounded); background: var(--static-gray-50); }
.gp--g6 .footer-link { flex: 0 1 auto; min-width: 0; }
/* ILE TYTUŁÓW POKAZUJE BELKA — ZALEŻY OD SZEROKOŚCI, nie od mojego pomiaru przy szerokim
   oknie. Zmierzone przeglądem: przy kontenerze 489 px oba tytuły były ucięte (62% i 43%
   długości), a opis obiecywał „pełne tytuły bez ucinania". Tytuły mają 60–70 znaków, więc
   jeden potrzebuje ~420 px. Reguła: dwa tytuły dopiero od 1200 px kontenera, niżej jeden.
   Teza belki („żadnego wielokropka") jest odtąd prawdziwa na każdej szerokości, bo liczba
   tytułów schodzi razem z miejscem. */
.gp--g6 .footer-link:nth-child(n+2) { display: none; }
@media (min-width: 1440px) { .gp--g6 .footer-link:nth-child(2) { display: flex; } }
.gp--g6 .footer-link + .footer-link::before { content: ""; flex: none; width: var(--static-space-0-5x); height: var(--static-space-0-5x); margin-right: var(--pui-footer-left-column-gap-h); border-radius: var(--pui-ui-radius-rounded); background: var(--static-primary-500); }
.gp--g6 .footer-link__text { white-space: nowrap; }
.gp--g6 .footer__guides-thumb { display: none; }
/* G5 — cztery kolumny, kwadratowa miniatura, mniejsze pismo. */
.gp--g5 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.gp--g5 .footer-link { gap: var(--static-space-1x); }
.gp--g5 .footer__guides-thumb { width: var(--static-space-2-5x); height: var(--static-space-2-5x); border-radius: var(--pui-ui-radius-xs); }
.gp--g5 .footer-link__text { font-size: var(--pui-text-p-sm-font-size); }

/* Kreska na CAŁĄ WYSOKOŚĆ pasa i treść wyśrodkowana w pionie (zgłoszenie zamawiającego 24.08.2026:
   „wyśrodkuj w pionie, divider pionowy na całą wysokość"). `align-items: stretch` rozciąga
   nagłówek do wysokości rzędu, więc jego prawa obwiednia staje się dzielnikiem pełnej
   wysokości; środkowanie robi `justify-content` WĘWNĄTRZ nagłówka i wpisów, nie wyrównanie
   rzędu — inaczej kreska znowu skróciłaby się do treści. */
.footer__guides-row { display: flex; align-items: stretch; gap: var(--static-space-5x); }
.footer__guides-row .footer__guides { flex: 1; min-width: 0; align-content: center; }
/* NAGŁÓWEK PASA: ikona, napis, kreska oddzielająca od wpisów i odnośnik pod spodem
   (propozycja zamawiającego 24.08.2026: „może lewa część jakaś lepsza wizualnie? może oddzielona
   kreską od prawej, może pod spodem link see all?"). Kreska bierze rolę dzielnika stopki,
   tę samą co obwiednia pasa i pasek dolny — jeden dzielnik na całą stopkę. */
/* Szerokość Z TREŚCI, bez `min-width`. Wpisanie tu roli minimalnej szerokości lewej kolumny
   (~350 px) rozdmuchało nagłówek pasa, którego nikt nie kazał poszerzać. Nagłówek jest
   podpisem, nie kolumną.
   ODSTĘP I KOLOR DZIELNIKA — zgłoszenie zamawiającego 24.08.2026: „odstęp pomiędzy Guides a linkami
   jest za duży, ustaw coś koło 40 px z obu stron dividera. Kolor dividera i borderu ustaw na
   taki sam jak w pasku niżej z logiem". Pasek dolny stoi na `--pui-footer-separator`, więc pas
   bierze TĄ SAMĄ rolę, nie podobną (`--pui-footer-divider` była o stopień mocniejsza).
   BRAK DO ZGŁOSZENIA: rodzina `--pui-footer-*` nie ma roli „odstęp wokół dzielnika pasa”,
   więc 40 px wchodzi ze skali (`space-5x`). Nie dorabiam roli sam. */
.footer__guides-head { display: flex; flex-direction: column; gap: var(--static-space-1x); margin-bottom: 0; flex: none; padding-right: var(--static-space-5x); border-right: var(--pui-ui-border-divider-width) solid var(--pui-footer-separator); }
/* ETYKIETY GRUP W STOPCE NIE ŁAMIĄ SIĘ NIGDY (zgłoszenie zamawiającego o „Features", to samo
   złapane przeglądem na „BY TECHNOLOGY" przy 924 px: 26 px zamiast 13). Reguła obejmuje
   WSZYSTKIE etykiety, nie tylko te dwie, którym dopisałem skróty — inaczej wada wraca przy
   każdej nowej nazwie grupy. */
.footer .dropdown__sub-header { white-space: nowrap; }
/* Miniatura wpisu. W projekcie NIE MA ikon artykułów ani miniatur wpisów — wszystkie
   siedem bierze `assets/blog-placeholder.png`, czyli placeholder, który w projekcie stoi.
   To pole zastępcze, nie decyzja graficzna: prawdziwe miniatury są brakiem po stronie treści. */
/* Pas wpisów: cztery kolumny na biurku, dwie niżej. `auto-fit` z minimum wziętym z roli
   lewej kolumny dał przy 1480 px tylko DWIE kolumny (minimum jest za duże), a sztywne
   `repeat(4, 1fr)` przy wąskim oknie zostawiało 100 px na kolumnę i ścinało tytuł do jednego
   wyrazu. Próg rozstrzyga to jednoznacznie i jest tym samym, którego używa reszta stopki.
   BRAK DO ZGŁOSZENIA: rodzina `--pui-footer-*` nie ma roli „minimalna szerokość kolumny
   wpisów” — stąd próg zamiast `minmax`. */
.footer__guides--cztery { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--pui-footer-gap); }
@media (min-width: 1024px) { .footer__guides--cztery { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* Miniatura wpisu bierze rozmiar POJEMNIKA IKONY wpisu „Guides", czyli rolę, która już
   opisuje to miejsce — kropka siedzi dziś w tym samym pojemniku. Bez literału. */
.footer__guides-thumb { flex: none; width: var(--pui-footer-left-column-guides-link-icon-container-size); height: var(--pui-footer-left-column-guides-link-icon-container-size); border-radius: var(--pui-ui-radius-md); object-fit: cover; background: var(--static-gray-100); }

.footer__col { flex: 1; display: flex; flex-direction: column; gap: var(--pui-footer-right-column-gap-v); }
.footer__community { display: flex; align-items: center; gap: var(--pui-footer-left-column-gap-h); align-self: stretch; }
.footer__community-button { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-decoration: none; padding: var(--pui-footer-left-column-community-padding-v) var(--pui-footer-left-column-community-padding-h); gap: var(--pui-footer-left-column-community-gap); border-radius: var(--pui-footer-left-column-community-radius); position: relative; overflow: hidden; z-index: 1; }
/* Hover i active NIE zmieniają tła: podmieniają widoczność dwóch warstw
   ::before i ::after, które leżą pod treścią. Dlatego przejście jest na
   opacity, a nie na background — gradientu nie da się animować. */
.footer__community-button::before,
.footer__community-button::after { content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0; transition: opacity 0.2s ease; z-index: -1; }
.footer__community-button--forum { background: linear-gradient(180deg, var(--pui-footer-community-forum-bg-start), var(--pui-footer-community-forum-bg-end)); }
.footer__community-button--forum::before { background: linear-gradient(180deg, var(--pui-footer-community-forum-bg-hover-start), var(--pui-footer-community-forum-bg-hover-end)); }
.footer__community-button--forum::after { background: linear-gradient(180deg, var(--pui-footer-community-forum-bg-active-start), var(--pui-footer-community-forum-bg-active-end)); }
.footer__community-button--subscribe { background: linear-gradient(180deg, var(--pui-footer-community-newsletter-bg-start), var(--pui-footer-community-newsletter-bg-end)); }
.footer__community-button--subscribe::before { background: linear-gradient(180deg, var(--pui-footer-community-newsletter-bg-hover-start), var(--pui-footer-community-newsletter-bg-hover-end)); }
.footer__community-button--subscribe::after { background: linear-gradient(180deg, var(--pui-footer-community-newsletter-bg-active-start), var(--pui-footer-community-newsletter-bg-active-end)); }
.footer__community-button--discord { background: linear-gradient(180deg, var(--pui-footer-community-discord-bg-start), var(--pui-footer-community-discord-bg-end)); }
.footer__community-button--discord::before { background: linear-gradient(180deg, var(--pui-footer-community-discord-bg-hover-start), var(--pui-footer-community-discord-bg-hover-end)); }
.footer__community-button--discord::after { background: linear-gradient(180deg, var(--pui-footer-community-discord-bg-active-start), var(--pui-footer-community-discord-bg-active-end)); }
.footer__community-button:hover::before { opacity: 1; }
.footer__community-button:active::after { opacity: 1; }
.footer__community-icon { width: var(--pui-footer-left-column-community-icon-size); height: var(--pui-footer-left-column-community-icon-size); display: block; position: relative; z-index: 2; }
.footer__community-text { color: var(--pui-footer-community-button-text); text-align: center; font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); font-weight: 300; position: relative; z-index: 2; }
.footer__bottom { border-top: 1px solid var(--pui-footer-separator); }
.footer__bottom-inner { display: flex; justify-content: space-between; align-items: center; padding: var(--pui-footer-bottom-padding-v) 0; gap: var(--pui-footer-bottom-gap); }
.footer__bottom-left { display: flex; align-items: center; gap: var(--pui-footer-bottom-gap); }

/* --- ui/Card.vue (blok scoped) · RODZINA DOMKNIĘTA 12.08.2026 --------------
   Stopka woła UiCard variant="default", więc karta przewodników stoi na
   .card i dopiero na niej siada nadpisanie gospodarza .footer__guides-card.

   Przy stopce (12.08 rano) stała tu WYŁĄCZNIE reguła bazowa z dwiema częściami,
   z zapowiedzią domknięcia razem z komponentem karty. Domknięte tego samego dnia
   przy przejeździe P2.2a: cała rodzina, pięć wariantów i próg mobile stoją teraz
   w jednym miejscu, więc rodzina nie jest rozcięta na dwa.

   ZNALEZIONE: klasy .card--default NIE MA W ARKUSZU ŹRÓDŁA ani jednej reguły.
   Komponent skleja nazwę wariantu z propsa, więc klasa powstaje zawsze, a dla
   wartości domyślnej nie wybiera niczego. Wygląd karty domyślnej robi w całości
   reguła bazowa. RZ-86.

   Dwie wartości stoją tu literałem, bo tak stoją w kodzie: #E1E1E1 w obwiedni
   (kolor spoza palety — najbliższy stopień to --static-gray-250 #E1E1EAFF,
   ale to NIE jest ten sam kolor) i #FFFFFF w tle. */
.card { display: flex; position: relative; overflow: hidden; align-self: stretch; text-decoration: none; color: inherit; border-radius: var(--pui-community-box-newsletter-body-radius); padding: var(--pui-community-box-newsletter-body-padding-v) var(--pui-community-box-newsletter-body-padding-h); border: var(--pui-community-box-newsletter-body-border-width) solid #E1E1E1; background: #FFFFFF; }
/* Dwie części, bo karta renderuje je BEZWARUNKOWO, gdy dostanie treść w slocie
   domyślnym — a stopka ją podaje. Bez nich kadr broniłby się przypadkiem:
   .card jest flexem w wierszu, więc lista przewodników dostałaby szerokość
   z kurczenia zamiast z flex: 1 i width: 100% na .card__main. */
.card__main { display: flex; flex-direction: column; gap: var(--pui-community-box-newsletter-main-gap); flex: 1; z-index: 2; width: 100%; }
.card__body { display: flex; flex-direction: column; }

/* Karta ze slotem górnym staje się kolumną — warunek zależy od TREŚCI slotu. */
.card:has(.card__top) { flex-direction: column; gap: 10px; }
.card.border-mask::before { background: linear-gradient(99.28deg, #07C07E 0%, #D9D9E3 15%, #D9D9E3 85%, #07C07E 100%); }
.card__top { width: 100%; }
.card__content { display: flex; flex-direction: column; gap: 12px; align-self: stretch; padding: 16px; }
.card__title-wrapper { display: flex; align-items: baseline; gap: 16px; }
.card__title { font-weight: 600; }
/* Ikona wyjścia na zewnątrz: rysowana zawsze przy forum i discord, widoczna
   dopiero pod wskaźnikiem KARTY (opacity 0 → 1). Kolor wpisany wprost. */
.card__external-icon { width: var(--pui-use-case-main-icon-size); height: var(--pui-use-case-main-icon-size); flex-shrink: 0; color: white; opacity: 0; transition: all .5s ease; }
.card:hover .card__external-icon { opacity: 1; }
.card__footer { display: flex; align-items: center; gap: 16px; }
.card__graphic { display: flex; align-items: center; justify-content: flex-end; position: relative; z-index: 1; pointer-events: none; flex: 1; max-width: 240px; min-height: 278px; }
/* :deep(img) i :deep(svg) — rysunek przychodzi slotem od hosta, więc reguła
   CELOWO sięga w cudzy element. `left` jest w kodzie zadeklarowane DWA RAZY
   z tą samą wartością; przepisane raz, bo druga deklaracja niczego nie zmienia. */
.card__graphic img { height: auto; max-height: 238px; position: absolute; left: 0; z-index: -1; max-width: unset; transition: left .5s ease; }
.card__graphic svg { position: absolute; right: 0; height: 100%; }

.card--newsletter { border-radius: var(--pui-community-box-newsletter-body-radius); padding: var(--pui-community-box-newsletter-body-padding-v) var(--pui-community-box-newsletter-body-padding-h); }
.card--newsletter .card__main { gap: var(--pui-community-box-newsletter-main-gap); }
.card--newsletter .card__content { gap: var(--pui-community-box-newsletter-main-content-gap); padding: var(--pui-community-box-newsletter-main-content-padding-v) var(--pui-community-box-newsletter-main-content-padding-h); }
.card--newsletter .card__body { display: flex; align-self: stretch; }
.card--newsletter.border-mask::before { background: linear-gradient(127.75deg, #D9D9E3 0%, #D9D9E3 15%, #FF6914 43.27%, #D9D9E3 52.88%, #FF6914 100%); }

.card--forum, .card--discord { border: none; border-radius: var(--pui-community-box-forum-body-radius); padding: 0; }
.card--forum .card__main, .card--discord .card__main { padding: var(--pui-community-box-forum-main-padding-v) var(--pui-community-box-forum-main-padding-h); gap: var(--pui-community-box-forum-main-gap); justify-content: center; }
.card--forum .card__content, .card--discord .card__content { gap: var(--pui-community-box-forum-main-text-gap); padding: 0; }
.card--forum .card__graphic, .card--discord .card__graphic { padding: var(--pui-community-box-forum-graphic-padding-v) 0; max-width: var(--pui-community-box-forum-graphic-max-width); }
/* ::before bez tła w tej regule — samo tło dokłada wariant niżej. Przy
   .border-mask ten sam pseudoelement niesie obwiednię, więc jeden element
   pełni dwie role zależnie od klasy. */
.card--forum::before, .card--discord::before { content: ""; position: absolute; inset: 0; opacity: 0; transition: all .5s ease; }
.card--forum:hover::before, .card--discord:hover::before { opacity: 1; }
.card--forum:hover .card__graphic img, .card--discord:hover .card__graphic img { left: -10px; }

.card--purple.border-mask::before { background: linear-gradient(-234.25deg, var(--pui-video-block-body-purple-border-start) 0%, var(--pui-video-block-body-purple-border-end) 15%, var(--pui-video-block-body-purple-border-end) 85%, var(--pui-video-block-body-purple-border-start) 100%); }

.card--forum { background: linear-gradient(270deg, var(--pui-community-box-forum-bg-end) 0%, var(--pui-community-box-forum-bg-start) 70%); }
.card--forum .card__graphic::before { content: ""; background: linear-gradient(270deg, rgba(2, 58, 41, 0.90) 0%, rgba(2, 58, 41, 0.00) 72.5%); height: 100%; width: 100%; right: 0; top: 0; position: absolute; }
.card--forum::before { background: linear-gradient(270deg, var(--pui-community-box-forum-bg-end) 0%, var(--pui-community-box-forum-bg-start) 99.7%); }
.card--discord { background: linear-gradient(270deg, var(--pui-community-box-discord-bg-end) 0%, var(--pui-community-box-discord-bg-start) 70%); }
.card--discord .card__graphic::before { content: ""; background: linear-gradient(270deg, rgba(18, 35, 227, 0.8) 0%, rgba(18, 35, 227, 0) 72.5%); height: 100%; width: 100%; right: 0; top: 0; position: absolute; }
.card--discord::before { background: linear-gradient(270deg, var(--pui-community-box-discord-bg-end) 0%, var(--pui-community-box-discord-bg-start) 100%); }

.card--clickable { cursor: pointer; }
/* @include media(mobile) → do 767.98px: rysunek znika w obu kartach społeczności. */
@media (max-width: 767.98px) {
  .card--forum .card__graphic, .card--discord .card__graphic { display: none; }
}

/* --- ui/footer/Column.vue ------------------------------------------------- */
/* Blok scoped kolumny powtarza .footer__section i .footer__heading słowo
   w słowo za Footer.vue. W produkcie to dwie osobne reguły w dwóch plikach
   o identycznej treści; w płaskim arkuszu byłyby duplikatem, więc stoją wyżej
   RAZ. Własna dla kolumny jest tylko jedna klasa. */
.footer__links { display: flex; flex-direction: column; gap: var(--pui-footer-right-column-links-gap); }

/* --- ui/footer/Link.vue --------------------------------------------------- */
.footer-link { display: flex; align-items: center; text-decoration: none; gap: var(--pui-footer-left-column-guides-link-gap); transition: color 0.2s ease; width: 100%; }
.footer-link__dot-wrap { display: flex; flex-shrink: 0; align-items: center; justify-content: center; width: var(--pui-footer-left-column-guides-link-icon-container-size); height: var(--pui-footer-left-column-guides-link-icon-container-size); align-self: flex-start; }
.footer-link__dot { width: var(--pui-footer-left-column-guides-link-icon-size); height: var(--pui-footer-left-column-guides-link-icon-size); border-radius: 50%; background-color: var(--pui-text-primary); }
.footer-link__text { color: var(--pui-text-body); font-family: var(--static-typography-font-family); font-size: var(--pui-text-p-base-font-size); font-weight: 300; line-height: var(--pui-text-p-base-line-height); letter-spacing: var(--pui-text-p-base-letter-spacing); transition: color 0.2s ease; }
.footer-link:hover .footer-link__text { color: var(--pui-text-primary); }
/* 6px literałem — jedyna wartość tej rodziny stojąca poza tokenami. */
.footer-link__badge { margin-left: 6px; }

/* --- @include media(tablet) → do 1023.98px --------------------------------
   Rodzina progów działa W DÓŁ (ustalone przy atomie Układu): @tablet znaczy
   „do 1024 px", nie „od". To JEDYNY próg, jaki stopka ma w kodzie. */
@media (max-width: 1023.98px) {
  .footer__sitemap { flex-direction: column; }
  .footer__bottom-left { flex-direction: column; align-items: flex-start; }
  .footer__bottom-inner { flex-wrap: wrap; }
}

/* --- ui/SocialIcons.vue ---------------------------------------------------
   Stopka woła ten komponent w prawym dolnym rogu, więc rodzina wchodzi razem
   z nią. Trzy role, wszystkie istnieją.

   Zawężenie RZ-77: w źródle reguła rysunku stoi w :deep(svg) i :deep(svg path),
   czyli świadomie przebija granicę scoped. W płaskim arkuszu :deep() nie ma
   znaczenia — selektor potomka daje dokładnie ten sam zasięg. */
.social-icons { display: flex; align-items: center; gap: var(--pui-section-heading-vertical-actions-gap); }
.social-icons__item { display: inline-flex; transition: transform 0.2s ease, filter 0.2s ease; }
.social-icons__item svg { width: 32px; height: 32px; }
.social-icons__item svg path { fill: var(--pui-icons-social-icons-fg); transition: fill .2s ease; }
.social-icons__item:hover svg path { fill: var(--pui-icons-social-icons-fg-hover); }

/* =============================================================================
   ui/Section.vue + ui/SectionBackground.vue (bloki <style lang="scss">, BEZ scoped)
   Odczyt 12.08.2026. NAZWY KLAS BEZ ZMIAN — tak stoją w kodzie produkcyjnym.

   Oba bloki są w kodzie GLOBALNE (brak atrybutu scoped), więc przeniesienie do
   płaskiego arkusza nie zmienia ich zasięgu — inaczej niż przy hero (RZ-77),
   gdzie reguły scoped sięgały po przeniesieniu dalej niż w produkcie.

   Sekcja CTA nie ma ANI JEDNEJ własnej reguły: sections/Cta.vue jest samym
   szablonem i składa się z UiSection (variant="cta"), UiSectionBackground
   (ctaOverlay), UiBadge hero i UiControlsButton hero. Cały wygląd CTA stoi
   więc w tych dwóch rodzinach plus w atomach, które katalog już ma.

   Pokrycie ról sprawdzone PRZED przepisaniem: wszystkie 12 ról rodziny
   --pui-section-* i --pui-container-*, których te bloki używają, istnieją
   w pa-tokens.css. Warstwa tła stoi natomiast prawie w całości na literałach
   (RZ, sekcja o SectionBackground) — jedyny token, jaki czyta, to
   --pui-section-cta-body-graphic-width.
   ============================================================================= */

/* --- ui/Section.vue ------------------------------------------------------- */
.section {
  display: flex; align-items: center; justify-content: center;
  padding: 0 0 var(--pui-section-padding-v) 0;
  position: relative; overflow: hidden;
}
.section--primary {
  padding-top: var(--pui-section-padding-v);
  background: linear-gradient(180deg, var(--pui-surface-gradient-primary-start) 0%, var(--pui-surface-gradient-primary-end) 100%);
}
.section--primary + .section { padding-top: var(--pui-section-padding-v); }

.section--cta { background: var(--pui-surface-solid-primary); }
.section--cta .section__header-content .section__desc { font-weight: 200; }

/* Trzy selektory :has() — sekcja z pasem opinii albo z suwakiem przestaje być
   rzędem i staje się kolumną. Przepisane 1:1, bo warunek jest w kodzie. */
.section:has(.testimonial-wrapper),
.section:has(.slider-features-wrapper),
.section:has(.slider-wrapper) { flex-direction: column; gap: var(--pui-container-gap); }

/* Kontener wewnątrz sekcji dostaje pozycjonowanie i kolumnę — .container sama
   (elements/container.scss) niesie tylko szerokość, padding i gap. */
.section .container { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--pui-container-gap); }

.section__header {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--pui-section-heading-vertical-gap);
  max-width: var(--pui-section-heading-vertical-width);
  align-self: center;
}
.section__header .section__header-content { display: flex; flex-direction: column; align-items: center; gap: var(--pui-section-heading-vertical-content-gap); }
.section__header .section__desc b { font-weight: 500; }
.section__header .section__heading,
.section__header .section__desc { text-align: center; }
/* .section__actions NIE MA odpowiednika w szablonie — element nazywa się
   .section__header-actions. Reguła jest w kodzie martwa; przepisana, bo
   katalog pokazuje stan, jaki jest. */
.section__header .section__actions { justify-content: center; }

.section__header--left { align-self: center; }
.section__header--left .section__header-content { align-items: flex-start; }
.section__header--left .section__heading,
.section__header--left .section__desc { text-align: left; }
.section__header--left .section__header-actions { justify-content: flex-start; }
.section__header--left .section__header-highlights { justify-content: flex-start; }

.section__header--horizontal { max-width: var(--pui-section-heading-horizontal-width); }
.section__header--horizontal .section__header-content { flex-direction: row; gap: var(--pui-section-heading-horizontal-content-gap); align-items: flex-start; }
.section__header--horizontal .section__heading { max-width: var(--pui-section-heading-horizontal-title-width); flex: 1 0 auto; }
.section__header--horizontal .section__desc { flex: 1; text-align: left; }

.section__header-actions { display: flex; align-items: center; gap: var(--pui-section-heading-vertical-actions-gap); justify-content: center; }
.section__header-highlights { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; justify-content: center; }
.section__content:has(.feature + .feature) { display: flex; flex-direction: column; gap: var(--pui-container-content-gap-v); }

/* --- @include media(mobile) → do 767.98px ---------------------------------
   Jedyny próg, jaki sekcja ma w kodzie. Rodzina progów działa W DÓŁ. */
@media (max-width: 767.98px) {
  .section .section__header-content { flex-direction: column; align-items: center; }
  .section .section__desc { text-align: center; }
  .section .section__header-actions { flex-direction: column; width: 100%; }
  .section .section__header-actions .btn.btn--hero,
  .section .section__header-actions .btn.btn--hero-outline { width: 100%; max-width: 100%; }
}

/* --- ui/SectionBackground.vue ---------------------------------------------
   Warstwa tła stoi na wartościach wpisanych wprost: 1920 px szerokości, 930 px
   i 572 px wysokości, 454 px wysokości pasa bocznego, wszystkie przesunięcia
   ilustracji i oba cienie. Jedyna rola w całym pliku to szerokość pasa.
   Przepisane literałem, bo tak stoi w kodzie — braku nie uzupełniam. */
.section__background {
  position: absolute; inset: 0; width: 100%; z-index: 0; pointer-events: none;
  max-width: 1920px; min-width: 1920px; min-height: 930px;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
}
.section__background--cta { min-height: 572px; display: flex; flex-direction: row; justify-content: space-between; }
.section__background--cta::before {
  content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  background: linear-gradient(0deg, #021710 0%, rgba(2, 23, 16, 0.00) 100%);
  z-index: 2; pointer-events: none;
}
.section__background-layer { position: absolute; pointer-events: none; }
.section__background-layer--glow { inset: 0; width: 100%; height: 100%; z-index: 1; }
.section__background-layer--glow img { width: 100%; height: 100%; object-fit: cover; }
.section__background-layer--center { inset: 0; display: flex; align-items: flex-end; justify-content: center; z-index: 1; }
.section__background-layer--center img { max-width: 100%; height: auto; }
.section__background-layer--left,
.section__background-layer--right {
  top: 50%; transform: translateY(-50%); height: 454px;
  max-width: var(--pui-section-cta-body-graphic-width); z-index: 3; position: relative; width: 100%;
}
.section__background-layer--left { left: 0; }
.section__background-layer--right { right: 0; }
.section__background-layer--left--1 { max-width: 220px; position: absolute; left: -24px; bottom: 0; border-radius: 16px; }
.section__background-layer--right--1 { max-width: 220px; position: absolute; right: 0; bottom: 0; border-radius: 16px; }
.section__background-layer--left--2,
.section__background-layer--right--2 {
  max-width: 266px; position: relative; border-radius: 16px;
  box-shadow: 0px 47px 52px 6px rgba(5, 109, 72, 0.0705882353), 0px 14px 30px 0px rgba(0, 0, 0, 0.0901960784);
  display: flex;
}
.section__background-layer--left--2 { top: 41px; left: 51px; }
.section__background-layer--right--2 { top: 48px; left: 49px; }
/* Obie warstwy szkła: ::before daje rozmycie tła, ::after obwiednię maską.
   W kodzie ::after nie ma -webkit-mask-composite pary w postaci
   mask-composite: exclude — przepisane bez niej, tak jak stoi. */
.section__background-layer--left--2::before,
.section__background-layer--right--2::before {
  content: ""; position: absolute; inset: 0; padding: 1px; border-radius: 16px;
  width: 278px; height: 305px; left: -6px; top: -6px;
  background: #FFFFFF0D; pointer-events: none; backdrop-filter: blur(20px);
}
.section__background-layer--left--2::after,
.section__background-layer--right--2::after {
  content: ""; position: absolute; inset: 0; padding: 1px; border-radius: 16px;
  width: 278px; height: 305px; left: -6px; top: -6px;
  background: linear-gradient(113.79deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 5.75%), linear-gradient(243.3deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 4.79%), linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 90%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  pointer-events: none;
}
.section__background-layer--left--2 img,
.section__background-layer--right--2 img { border-radius: 10px; width: 100%; z-index: 1; }
.section__background-layer--left--3 { max-width: 92px; left: 282px; position: absolute; top: 76px; }
.section__background-layer--right--3 { max-width: 92px; left: 0; position: absolute; top: 0; }

/* =============================================================================
   layout/MainBanner.vue (blok scoped) + layout/MainBannerVertical.vue
   (blok GLOBALNY). Odczyt 12.08.2026. NAZWY KLAS BEZ ZMIAN.

   Pokrycie ról sprawdzone PRZED przepisaniem: 24 role rodzin --pui-banner-*,
   --pui-container-* i --pui-surface-* obecne w pa-tokens.css, zero braków.
   Odwołania BEZ definicji, które przepisuję razem z wartością awaryjną, bo
   tak stoją w kodzie (RZ-35): --sys-banner-primary-graphic-bg-overlay
   (jedyne wystąpienie przestrzeni --sys-* w całym repo) oraz
   --pui-banner-parallax-x/y, które powstają w czasie działania ze skryptu
   komponentu i żaden arkusz ich nie definiuje — to jedyne POPRAWNE odwołanie
   bez definicji na tej stronie.

   Blok MainBanner.vue jest scoped, blok banera pionowego NIE — ten drugi
   przenosi się bez zmiany zasięgu, pierwszy zawężam do samego .banner,
   dokładnie tak, jak działa w produkcie (trzy reguły na jednym elemencie).
   ============================================================================= */

/* --- layout/MainBanner.vue (scoped) --------------------------------------- */
.banner { overflow: hidden; padding-top: 109px; }
.banner--primary { background: var(--pui-surface-solid-primary); }
.banner--purple { background: var(--pui-surface-solid-purple); }
.banner--red, .banner--orange { background: var(--pui-surface-solid-main); }

/* --- layout/MainBannerVertical.vue ---------------------------------------- */
/* Poświata dolna: primary, red i orange jadą ::before, purple ::after. Dwie
   drogi na jedną rzecz, rozdzielone kolorem — przepisane obiema. */
.banner--vertical::before,
.banner--vertical::after {
  content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 608px;
  z-index: 0; opacity: 0; pointer-events: none; transition: opacity 500ms ease-in-out;
}
.banner--vertical.banner--primary::before { opacity: 1; background: linear-gradient(180deg, var(--pui-banner-primary-bg-gradient-h-end) 0%, var(--pui-banner-primary-bg-gradient-h-start) 100%); }
.banner--vertical.banner--primary .banner__illustration::after { background: linear-gradient(180deg, var(--pui-banner-primary-bg-gradient-h-end) 0%, var(--pui-banner-primary-bg-gradient-h-start) 90%); }
.banner--vertical.banner--purple::after { opacity: 1; background: linear-gradient(180deg, var(--pui-banner-purple-bg-gradient-h-end) 0%, var(--pui-banner-purple-bg-gradient-h-start) 100%); }
.banner--vertical.banner--purple .banner__illustration::after { background: linear-gradient(180deg, var(--pui-banner-purple-bg-gradient-h-end) 0%, var(--pui-banner-purple-bg-gradient-h-start) 90%); }
.banner--vertical.banner--red::before { opacity: 1; background: linear-gradient(180deg, var(--pui-banner-red-bg-gradient-h-end) 0%, var(--pui-banner-red-bg-gradient-h-start) 100%); }
.banner--vertical.banner--red .banner__illustration::after { background: linear-gradient(180deg, var(--pui-banner-red-bg-gradient-h-end) 0%, var(--pui-banner-red-bg-gradient-h-start) 90%); }
.banner--vertical.banner--orange::before { opacity: 1; background: linear-gradient(180deg, var(--pui-banner-orange-bg-gradient-h-end) 0%, var(--pui-banner-orange-bg-gradient-h-start) 100%); }
/* Wariant orange ZNOSI wygaszenie ilustracji. */
.banner--vertical.banner--orange .banner__illustration::after { content: none; }

.banner--vertical { display: flex; flex-direction: column; align-items: center; position: relative; }

.banner--vertical .banner__shape {
  position: absolute; bottom: 0; left: 50%; width: 100%; height: auto;
  aspect-ratio: 1580 / 913; max-width: var(--pui-banner-gradient-max-width);
  transform: translate3d(calc(-50% + var(--pui-banner-parallax-x, 0px)), var(--pui-banner-parallax-y, 0px), 0);
  transition: transform 180ms ease-out;
  animation: bannerShapeOpacityIn 3s ease-out forwards;
  will-change: transform; pointer-events: none; z-index: 1;
}
.banner--vertical .banner__shape--crossfade { opacity: 0; animation: none; transition: opacity 500ms ease-in-out, transform 180ms ease-out; will-change: transform, opacity; }
.banner--vertical .banner__shape--active { opacity: 1; }
/* Nazwa klatkowania BEZ przedrostka katalogu — tak nazywa się w kodzie.
   ROZJAZD zmierzony wcześniej: arkusz mówi ease-out, pomiar na produkcji dał
   linear. Katalog rysuje arkusz, bo jest źródłem wskazywalnym. */
@keyframes bannerShapeOpacityIn { from { opacity: 0; } to { opacity: 1; } }

.banner--vertical .banner__container {
  display: flex; max-width: var(--pui-container-width-max);
  padding: var(--pui-banner-vertical-container-padding-top) var(--pui-banner-vertical-container-padding-h) var(--pui-banner-vertical-container-padding-bottom) var(--pui-banner-vertical-container-padding-h);
  flex-direction: column; align-items: center; z-index: 1;
}
.banner--vertical .banner__content { display: flex; max-width: var(--pui-banner-vertical-heading-width); flex-direction: column; align-items: center; gap: var(--pui-banner-vertical-heading-gap); }
.banner--vertical .banner__description { display: flex; flex-direction: column; align-items: center; gap: var(--pui-banner-vertical-heading-main-gap); text-align: center; font-weight: 200; }
.banner--vertical .banner__description p { font-weight: 200; }
.banner--vertical .banner__description strong,
.banner--vertical .banner__description b { font-weight: 500; }
.banner--vertical .banner__action { display: flex; justify-content: center; align-items: flex-end; flex-wrap: wrap; gap: var(--pui-banner-vertical-actions-gap); }
.banner--vertical .banner__labels { display: flex; justify-content: center; align-items: flex-start; align-content: flex-start; gap: var(--pui-banner-vertical-slot-gap); align-self: stretch; flex-wrap: wrap; }
.banner--vertical .banner__labels--top { order: -1; }

.banner--vertical .banner__illustration-container {
  display: flex; justify-content: center; flex: 1; max-width: var(--pui-container-width-max);
  padding: 0 var(--pui-banner-vertical-container-padding-h);
  max-height: var(--pui-banner-graphic-image-height); position: relative; width: 100%;
}
/* @include media(tablet, min) → OD 1024 px w górę. Wariant "min" jest w tym
   pliku jedyny w całym odczycie i odwraca kierunek rodziny progów. */
@media (min-width: 1024px) {
  .banner--vertical .banner__illustration-container { min-height: var(--pui-banner-graphic-image-height); min-width: 1480px; }
}
.banner--vertical .banner__illustration { position: relative; z-index: 1; display: flex; justify-content: center; width: 100%; }
.banner--vertical .banner__illustration::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 200px; opacity: 0.5; }
.banner--vertical .banner__illustration-frame {
  overflow: hidden;
  box-shadow: 0px 47px 52px 6px rgba(5, 109, 72, 0.07), 0px 14px 30px 0px rgba(0, 0, 0, 0.09);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  background: var(--sys-banner-primary-graphic-bg-overlay, rgba(255, 255, 255, 0.05));
  padding: var(--pui-banner-graphic-image-base-padding-v) var(--pui-banner-graphic-image-base-padding-h);
}
.banner--vertical .banner__illustration-frame::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  background: linear-gradient(113.79deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 5.75%), linear-gradient(243.3deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 4.79%), linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 90%);
  pointer-events: none;
}
.banner--vertical .banner__illustration-layer { border-radius: var(--pui-banner-graphic-image-sm-outside-radius); }
.banner--vertical .banner__illustration-layer img { border-radius: var(--pui-banner-graphic-image-sm-inside-radius); }
.banner--vertical .banner__illustration-layer svg { display: block; }
.banner--vertical .banner__illustration-layer:not(.banner__illustration-layer--main):not(.banner__illustration-layer--main-homepage) { position: absolute; }
.banner--vertical .banner__illustration-layer--main {
  padding: var(--pui-banner-graphic-image-base-padding-v) var(--pui-banner-graphic-image-base-padding-h) 0 var(--pui-banner-graphic-image-base-padding-h);
  border-radius: var(--pui-banner-graphic-image-base-outside-radius) var(--pui-banner-graphic-image-base-outside-radius) 0 0;
}
.banner--vertical .banner__illustration-layer--main img { width: 100%; max-width: 782px; border-radius: var(--pui-banner-graphic-image-base-inside-radius) var(--pui-banner-graphic-image-base-inside-radius) 0 0; }
.banner--vertical .banner__illustration-layer--main-homepage {
  padding: var(--pui-banner-graphic-image-base-padding-v) var(--pui-banner-graphic-image-base-padding-h) 0 var(--pui-banner-graphic-image-base-padding-h);
  border-radius: var(--pui-banner-graphic-image-base-outside-radius) var(--pui-banner-graphic-image-base-outside-radius) 0 0;
}
.banner--vertical .banner__illustration-layer--main-homepage img { border-radius: var(--pui-banner-graphic-image-base-inside-radius) var(--pui-banner-graphic-image-base-inside-radius) 0 0; width: 100%; max-width: 964px; }
.banner--vertical .banner__illustration-layer--left-bottom,
.banner--vertical .banner__illustration-layer--right-bottom {
  bottom: 0; padding-bottom: 0;
  border-radius: var(--pui-banner-graphic-image-sm-outside-radius) var(--pui-banner-graphic-image-sm-outside-radius) 0 0;
}
.banner--vertical .banner__illustration-layer--left-bottom img,
.banner--vertical .banner__illustration-layer--right-bottom img { border-radius: var(--pui-banner-graphic-image-sm-inside-radius) var(--pui-banner-graphic-image-sm-inside-radius) 0 0; }

/* @include media(tablet) → do 1023.98px. Warstwy poboczne znikają. */
@media (max-width: 1023.98px) {
  .banner--vertical .banner__illustration-layer:not(.banner__illustration-layer--main):not(.banner__illustration-layer--main-homepage):not(.banner__illustration-layer--trial) { display: none !important; }
}

/* --- layout/MainBannerHorizontal.vue (blok GLOBALNY, bez scoped) -----------
   Odczyt 18.08.2026, commit 1bcf0cc, przepisane przy zgłoszeniu zamawiającego
   („elementy bannera powinny korzystać z klas zamiast inline styli").
   Ostatnia rodzina banera bez klas — pionowy stoi tu od 12.08.

   ZASIĘG BEZ ZAWĘŻENIA i jest to jedyny taki blok w rodzinie banerów: styl
   w pliku NIE MA atrybutu scoped, więc reguły w produkcie sięgają globalnie
   dokładnie tak jak tutaj. Zawężanie czegokolwiek zmieniłoby zasięg.

   DWIE RZECZY, KTÓRE ROBIĄ TU PSEUDOELEMENTY, a katalog rysował je ELEMENTAMI:
   gradient tła korzenia (::before) i poświata pod ilustracją (::before slotu).
   Oba znaczniki zniknęły z pozycji przy tym przepięciu — nie było ich w kodzie.

   LITERAŁY SĄ LITERAŁAMI KODU: gap 64px, max-height 646px, poświata 480×480,
   blur 80px i dwie barwy rgba stoją w arkuszu wprost, choć rodzina ma na nie
   role o TYCH SAMYCH wartościach (--pui-banner-horizontal-container-gap,
   --pui-banner-horizontal-slot-height oraz katalogowe --src-banner-h-*).
   Katalog rysuje literałem, bo literał rysuje kod, i pokazuje role jako
   istniejące — martwe role zostają na liście rozjazdów. */
.banner--horizontal { display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; }
.banner--horizontal::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.banner--horizontal.banner--purple::before { background: linear-gradient(var(--pui-banner-purple-bg-gradient-h-end) 0%, var(--pui-banner-purple-bg-gradient-h-start) 100%); }
.banner--horizontal.banner--purple .banner__illustration::before { background: rgba(130, 83, 229, 0.42); }
.banner--horizontal.banner--primary::before { background: linear-gradient(var(--pui-banner-primary-bg-gradient-h-end) 0%, var(--pui-banner-primary-bg-gradient-h-start) 100%); }
.banner--horizontal.banner--primary .banner__illustration::before { background: rgba(54, 210, 165, 0.42); }
.banner--horizontal .banner__container {
  display: flex; flex-grow: 1; z-index: 1; gap: 64px;
  max-width: var(--pui-banner-horizontal-container-width);
  padding: var(--pui-banner-horizontal-container-padding-top) var(--pui-banner-horizontal-container-padding-h) var(--pui-banner-horizontal-container-padding-bottom) var(--pui-banner-horizontal-container-padding-h);
}
/* Szerokość treści czyta rolę banera PIONOWEGO — tak w kodzie, nie pomyłka
   przepisania: rodzina horizontal nie ma własnej roli na szerokość nagłówka. */
.banner--horizontal .banner__content { display: flex; flex: 1 0 0; flex-direction: column; align-items: center; justify-content: center; max-width: var(--pui-banner-vertical-heading-width); gap: var(--pui-banner-horizontal-heading-gap); }
.banner--horizontal .banner__description { display: flex; flex-direction: column; align-self: stretch; gap: var(--pui-banner-horizontal-heading-main-gap); font-weight: 200; }
.banner--horizontal .banner__description p { font-weight: 200; }
.banner--horizontal .banner__description strong,
.banner--horizontal .banner__description b { font-weight: 500; }
.banner--horizontal .banner__action { display: flex; align-items: center; width: 100%; gap: var(--pui-banner-horizontal-actions-gap); }
.banner--horizontal .banner__illustration { position: relative; display: grid; place-items: center; flex: 1 0 0; max-width: var(--pui-banner-horizontal-slot-width); max-height: 646px; }
.banner--horizontal .banner__illustration img,
.banner--horizontal .banner__illustration svg { position: relative; grid-area: 1 / 1; width: 100%; height: 100%; }
.banner--horizontal .banner__illustration::before {
  content: ''; grid-area: 1 / 1; width: 100%; height: 100%;
  max-width: 480px; max-height: 480px; border-radius: 100%;
  filter: blur(80px); opacity: 0;
  animation: bannerShapeOpacityIn 3s ease-out forwards;
}
/* Pas etykiet NIE MA W KODZIE ŻADNEJ REGUŁY — ani w rodzinie horizontal, ani
   globalnie (sprawdzone: `banner__labels` w repozytorium to wyłącznie trzy
   znaczniki, zero deklaracji; reguły pionowego są zawężone .banner--vertical).
   Katalog też jej nie dokłada: <div class="banner__labels"> jest w produkcie
   zwykłym blokiem, a plakietki układają się tokiem inline. Przy jednej etykiecie
   nie widać różnicy, przy dwóch odstęp niesie SPACJA w znaczniku — zgłoszone
   jako RZ-89, bo to brak po stronie kodu, nie miejsce na regułę katalogu. */

/* @include media(tablet) → do 1023.98px: kolumna i wyrównanie do środka. */
@media (max-width: 1023.98px) {
  .banner--horizontal .banner__container { flex-direction: column; align-items: center; }
  .banner--horizontal .banner__content { align-items: center; text-align: center; }
  .banner--horizontal .banner__action { justify-content: center; }
}
/* @include media(mobile) → do 767.98px: przyciski w kolumnie, na pełną szerokość. */
@media (max-width: 767.98px) {
  .banner--horizontal .banner__action { flex-direction: column; width: 100%; }
  .banner--horizontal .banner__action .btn.btn--hero,
  .banner--horizontal .banner__action .btn.btn--hero-outline { width: 100%; max-width: 100%; }
}

/* =============================================================================
   sections/LatestUpdates.vue (blok scoped). Odczyt 12.08.2026.
   NAZWY KLAS BEZ ZMIAN. Pokrycie ról sprawdzone przed przepisaniem: 14 ról
   rodzin --pui-blog-*, --pui-button-* i --pui-ui-* obecnych, zero braków.

   ZAWĘŻENIE ZASIĘGU. Blok jest scoped, więc w produkcie każda reguła ma
   dopisany atrybut instancji. W płaskim arkuszu tego atrybutu nie ma, ale
   wszystkie reguły są pisane od .latest-updates w dół i żadna nie sięga po
   sam tag, więc zasięg zachowuje się tak samo. Dwa wyjątki to :deep(h4)
   i :deep(p) w karcie — te CELOWO przechodzą do potomka (atom typografii)
   i przepisane są jako zwykłe selektory potomka, czyli 1:1 co do zasięgu.
   ============================================================================= */

.latest-updates { position: relative; width: 100%; box-sizing: border-box; }
.latest-updates__slider-container { margin: -36px 72px; padding: 36px 24px; overflow: hidden; }
.latest-updates__slider { width: 100%; overflow: visible; }
.latest-updates__slide {
  height: auto; display: flex; position: relative; cursor: pointer;
  border-radius: var(--pui-blog-card-latest-update-body-radius);
  box-shadow: rgba(0, 0, 0, 0) 0px 0px 1px 0px, rgba(0, 0, 0, 0) 0px 8px 24px 6px;
  transition: box-shadow 0.3s ease, top 0.3s ease; top: 0;
  color: inherit; text-decoration: none;
}
@media (min-width: 1480px) {
  .latest-updates__slide { max-width: 376px !important; min-width: 376px !important; }
}
.latest-updates__slide:hover {
  box-shadow: rgba(0, 0, 0, 0.12) 0px 0px 1px 0px, rgba(0, 0, 0, 0.05) 0px 8px 24px 6px;
  top: -16px;
}
.latest-updates__slide:hover .latest-updates__card-overlay-wrapper { opacity: 1; }
.latest-updates__slide:hover .latest-updates__card-text h4 { color: var(--pui-text-primary); }

.latest-updates__card-overlay-wrapper { opacity: 0; transition: opacity 0.3s ease; position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
.latest-updates__card-overlay { position: absolute; top: 0; left: 0; border-radius: var(--pui-blog-card-latest-update-body-radius); opacity: 0.3; width: 100%; height: 220px; }
/* Literówka gradeint w nazwie roli jest w kodzie i zostaje (PA-01: adres się
   zamraża, poprawia się treść pokazywaną człowiekowi). */
.latest-updates__card-overlay-gradient { background: linear-gradient(182deg, var(--pui-blog-latest-update-card-gradient-end) 1.6%, var(--pui-blog-latest-update-card-gradeint-start) 50.02%); width: 100%; height: 265px; position: absolute; }

/* KARTA MA DWIE OBWIEDNIE NARAZ i to jest pomiar, nie usterka przepisania:
   border 1px w kolorze #D9D9E3 z tej reguły ORAZ druga, rysowana maską przez
   .border-mask, której gradient nadpisuje reguła ::before niżej. Dwie role
   zdefiniowane pod tę obwiednię (--pui-blog-latest-update-card-border-start
   i -end) są NIEUŻYWANE i użyć się ich nie da bez zmiany: gradient ma trzy
   przystanki, rola ma dwa końce. */
.latest-updates__card {
  display: flex;
  padding: var(--pui-blog-card-latest-update-body-padding-v) var(--pui-blog-card-latest-update-body-padding-h);
  flex-direction: column; align-items: flex-start;
  gap: var(--pui-blog-card-latest-update-body-gap); flex: 1 0 0;
  border-radius: var(--pui-blog-card-latest-update-body-radius);
  border: var(--pui-blog-card-latest-update-body-border-width) solid #D9D9E3;
  height: 100%; box-sizing: border-box;
}
.latest-updates__card::before { z-index: 2; background: linear-gradient(177.85deg, #D9D9E3 3.51%, #07C07E 42.51%, #D9D9E3 100.07%); }
.latest-updates__card-image-wrapper { width: 100%; border-radius: var(--pui-blog-card-latest-update-image-radius); overflow: hidden; flex-shrink: 0; z-index: 2; }
.latest-updates__card-image { width: 100%; display: block; object-fit: cover; }
.latest-updates__card-content { display: flex; flex-direction: column; gap: var(--pui-blog-card-latest-update-main-gap); width: 100%; flex: 1; }
.latest-updates__card-content * { z-index: 2; }
.latest-updates__card-meta { display: flex; justify-content: space-between; align-items: center; width: 100%; }
.latest-updates__card-date { color: var(--pui-text-body); font-size: var(--pui-text-p-xs-font-size); line-height: var(--pui-text-p-xs-line-height); letter-spacing: var(--pui-text-p-xs-letter-spacing); }
.latest-updates__card-text { display: flex; flex-direction: column; gap: var(--pui-blog-card-latest-update-main-content-gap); }
/* :deep(h4) i :deep(p) — host sięga w ATOM TYPOGRAFII. Szóste nadpisanie
   hosta na stronie głównej i jedyne dotyczące typografii, nie przycisku. */
.latest-updates__card-text h4 { font-weight: 600; margin: 0; }
.latest-updates__card-text p { margin: 0; display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }

.latest-updates__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: var(--pui-button-lg-height);
  border-radius: var(--pui-ui-radius-rounded) !important;
  display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 10;
}
.latest-updates__nav svg { min-width: var(--pui-button-lg-icon-size); min-height: var(--pui-button-lg-icon-size); }
.latest-updates__nav--prev { left: 0; }
.latest-updates__nav--next { right: 0; }

.latest-updates__pagination { display: none; justify-content: center; align-items: center; gap: 16px; margin-top: 32px; }
.latest-updates__dot { width: 10px; height: 10px; border-radius: 50%; background: #E8E8EF; border: none; padding: 0; cursor: pointer; transition: all 0.3s ease; }
.latest-updates__dot--active { background: #06A06A; }

/* @include media(laptop) → do 1479.98px: strzałki znikają, kropki wchodzą. */
@media (max-width: 1479.98px) {
  .latest-updates__slider-container { margin: -36px -24px; }
  .latest-updates__nav { display: none; }
  .latest-updates__pagination { display: flex; }
}
/* @include media(tablet) → do 1023.98px. */
@media (max-width: 1023.98px) {
  .latest-updates__slide { min-width: 300px !important; max-width: 300px !important; box-shadow: none !important; }
}
/* @include media(mobile) → do 767.98px. */
@media (max-width: 767.98px) {
  .latest-updates__slider-container { margin: 0; padding: 0; }
}

/* =============================================================================
   sections/Feature.vue + ui/content/List.vue (bloki scoped) oraz
   ui/content/FeatureIllustration.vue (blok GLOBALNY). Odczyt 12.08.2026.
   NAZWY KLAS BEZ ZMIAN. Pozycja w katalogu nazywa się Content block, bo tak
   nazywa się rodzina ról tego pliku (--pui-content-block-*); plik w kodzie
   nazywa się Feature.vue i na stronie głównej stoi CZTERY RAZY.
   Pokrycie ról sprawdzone przed przepisaniem: 20 ról, zero braków.
   ============================================================================= */

/* --- sections/Feature.vue -------------------------------------------------- */
.feature {
  display: flex; align-items: center; align-self: stretch;
  border-radius: var(--pui-content-block-body-radius);
  background: var(--pui-content-block-body-primary-bg);
  overflow: hidden;
}
/* @include media(tablet) → do 1023.98px: kolumna ODWRÓCONA, czyli ilustracja
   ląduje NAD treścią niezależnie od wariantu side. */
@media (max-width: 1023.98px) { .feature { flex-direction: column-reverse; } }
.feature__slot-left,
.feature__slot-right {
  display: flex; padding: var(--pui-content-block-container-padding-v) var(--pui-content-block-container-padding-h);
  flex-direction: column; justify-content: center; align-items: flex-start; flex: 1 0 0; align-self: stretch;
}
.feature__content {
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--pui-section-desc-default-base-body-padding-v) var(--pui-section-desc-default-base-body-padding-h);
  gap: var(--pui-section-desc-default-base-body-gap); align-items: flex-start; flex: 1 0 0;
}
.feature__illustration {
  display: flex;
  padding: var(--pui-content-block-illustration-container-default-padding-v) var(--pui-content-block-illustration-container-default-padding-h);
  justify-content: center; align-items: center;
  border-radius: var(--pui-content-block-illustration-container-default-radius);
  width: 100%; height: 100%;
}
/* Bez modyfikatora ilustracja NIE MA TŁA WCALE — role szare
   (--pui-content-block-illustration-container-gray-*) istnieją i nie są
   czytane przez żadną regułę. */
.feature__illustration--primary { background: linear-gradient(180deg, var(--pui-content-block-illustration-container-primary-bg-start) 0%, var(--pui-content-block-illustration-container-primary-bg-end) 100%); }
.feature__illustration--purple { background: linear-gradient(180deg, var(--pui-content-block-illustration-container-purple-bg-start) 0%, var(--pui-content-block-illustration-container-purple-bg-end) 100%); }
.feature__content-description { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pui-section-desc-default-base-main-gap); align-self: stretch; }
/* :deep(h3) — host sięga w atom typografii, tak samo jak Latest updates. */
.feature__content-description h3 { font-weight: 600; }
.feature__content-actions { display: flex; align-items: flex-start; gap: 16px; align-self: stretch; flex-wrap: wrap; }
/* @include media(mobile) → do 767.98px: akcje w kolumnie, przycisk na 100%.
   Szerokość dokłada HOST, nie atom przycisku. */
@media (max-width: 767.98px) {
  .feature__content-actions { flex-direction: column; }
  .feature__content-actions .btn { width: 100%; }
}

/* Obwiednia gradientowa idzie przez ::before pomocnika .border-mask.
   Wariant default-purple POŻYCZA RODZINĘ WIDEO (--pui-video-block-body-purple-*),
   swojej nie ma. Wariant default-primary nie dostaje ani obwiedni, ani żadnej
   innej reguły — jest nazwą bez treści. */
.feature--default::before { background: linear-gradient(-234.25deg, var(--pui-content-block-body-primary-border-start) 0%, var(--pui-content-block-body-primary-border-end) 15%, var(--pui-content-block-body-primary-border-end) 85%, var(--pui-content-block-body-primary-border-start) 100%); }
.feature--default-purple::before { background: linear-gradient(-234.25deg, var(--pui-video-block-body-purple-border-start) 0%, var(--pui-video-block-body-purple-border-end) 15%, var(--pui-video-block-body-purple-border-end) 85%, var(--pui-video-block-body-purple-border-start) 100%); }
.feature--primary { background: linear-gradient(270deg, var(--pui-content-block-body-primary-primary-bg-start) 0%, var(--pui-content-block-body-primary-primary-bg-end) 100%); border: none; }
.feature--primary .feature__illustration { background: transparent; }
.feature:not(.feature--reverse) .feature__content--extra-padding { padding-left: var(--pui-section-desc-default-base-body-padding-extra-h); }
.feature--reverse .feature__content--extra-padding { padding-right: var(--pui-section-desc-default-base-body-padding-extra-h); }
/* @include media(tablet, min) → OD 1024 px: układ odwrócony. Poniżej progu
   wygrywa column-reverse z reguły bazowej. */
@media (min-width: 1024px) { .feature--reverse { flex-direction: row-reverse; } }
/* Dwie reguły :has(.graphic--sm) — justowanie ilustracji zależy od TREŚCI
   SLOTU, czyli od tego, czy host wstawił małą ramkę. */
.feature--reverse:has(.graphic--sm) .feature__illustration { justify-content: flex-end; }
.feature:has(.graphic--sm):not(.feature--reverse) .feature__illustration { justify-content: flex-start; }
@media (max-width: 1023.98px) {
  .feature--reverse:has(.graphic--sm) .feature__illustration,
  .feature:has(.graphic--sm):not(.feature--reverse) .feature__illustration { justify-content: center; }
}

/* --- ui/content/List.vue --------------------------------------------------- */
.list { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pui-section-desc-default-base-main-rows-gap); align-self: stretch; }
.list__item { display: flex; align-items: center; gap: 12px; align-self: stretch; }
.list__icon-wrap { display: flex; flex-shrink: 0; align-items: center; justify-content: center; width: 24px; height: 24px; color: var(--pui-text-primary); }
.list__icon { width: 20px; height: 20px; display: block; }
.list__content { flex: 1 0 0; display: flex; align-items: center; min-height: 24px; }
.list__text { color: var(--pui-text-body, #3A3A47); font-size: var(--pui-text-p-lg-font-size); font-weight: 300; line-height: var(--pui-text-p-lg-line-height); letter-spacing: var(--pui-text-p-lg-letter-spacing); }
.list__badge { margin-left: 6px; }
/* Wariant purple zmienia WYŁĄCZNIE barwę ikony. */
.list--purple .list__icon-wrap { color: var(--pui-text-purple); }

/* --- ui/content/FeatureIllustration.vue (blok globalny) -------------------- */
.graphic:not(.graphic--sm) { display: grid; max-width: var(--pui-content-block-illustration-container-default-slot-max-size); justify-content: center; align-items: center; }
.graphic:not(.graphic--sm) svg,
.graphic:not(.graphic--sm) img { display: block; grid-area: 1 / 1; width: 100%; height: 100%; }
.graphic:not(.graphic--sm) .watch-button { margin-top: 7.04%; }
/* KOMPENSACJA NOŚNIKA, nie reguła systemu (18.08.2026, złożenie strony
   Agencies). W produkcie gniazdo FeatureIllustration.vue nie ma elementu
   pośredniego: `.watch-button` jest DZIECKIEM `.graphic`, więc bierze
   `grid-area: 1 / 1` i procenty liczone od ramy. W katalogu każde osadzenie
   dostaje własny `div.sc-host`, który staje się komórką siatki — bez tej
   reguły przycisk odtwarzania wypada POD rysunkiem i traci wymiar, bo jego
   procenty liczą się od pudełka bez rozmiaru. Zakres jest wąski celowo:
   wyłącznie osadzenia stojące wprost w ramie ilustracji. */
.graphic > .sc-host { display: contents; }
/* KOMPENSACJA NOŚNIKA, drugi przypadek tej samej rodziny (18.08.2026, przegląd
   strony Hosting Resellers). Rama `.graphic` jest siatką BEZ własnego wymiaru:
   284 × 284 w blokach z rysunkiem bierze się z WARSTW, a `.feature__illustration`
   nie ma min-height, więc jej 300 px to 284 plus dwa razy 8 px wyściółki.
   Blok, którego warstw NIE MA W REPOZYTORIUM, zapada się przez to do paska
   16 px — zmierzone: rama 813 × 16, siatka 0 × 0 — i pasek nie tłumaczy sam
   siebie, bo numer braku stoi poza ramą. Rama oznaczona pustym gniazdem
   [data-cat-brak] dostaje więc geometrię, jaką miałaby z warstwami: kwadrat
   szerokości slotu, z tej samej roli, którą `.graphic` już czyta jako max-width.
   Zakres najwęższy możliwy — wyłącznie gniazdo z tym atrybutem. */
.graphic:has(> [data-cat-brak]) { width: 100%; aspect-ratio: 1 / 1; }

/* =============================================================================
   ui/UseCaseCard.vue + sections/UseCases.vue (oba bloki scoped).
   Odczyt 12.08.2026. NAZWY KLAS BEZ ZMIAN. 17 ról, zero braków.
   ============================================================================= */

/* --- ui/UseCaseCard.vue ---------------------------------------------------- */
/* PROMIEŃ 24 px WPISANY WPROST, a rodzina MA własną rolę promienia
   (--pui-use-case-body-default-radius = radius-3xl = 16 px na desktopie).
   Karta renderuje 24, rola mówi 16 — nie różnica jednostki, różnica liczby.
   `cursor: pointer` stoi w kodzie DWA RAZY pod sobą; przepisane raz. */
.use-case-card {
  display: flex; justify-content: space-between; align-items: center;
  border-radius: 24px; position: relative; overflow: hidden;
  min-height: var(--pui-use-case-body-default-min-height);
  text-decoration: none; cursor: pointer;
}
/* KLASA .border-mask STOI NA KARCIE, ale ta reguła gasi jej ::before do zera
   i włącza dopiero na hoverze. Ta sama klasa w karcie społeczności rysuje
   obwiednię NA STAŁE — jedna klasa, dwa zachowania, różnica jest w arkuszu
   hosta, nie w pomocniku. */
.use-case-card::before { opacity: 0; transition: all .5s ease; z-index: 1; }
.use-case-card::after { content: ""; position: absolute; inset: 0; opacity: 0; transition: all .5s ease; z-index: 0; }
.use-case-card__content {
  display: flex; position: relative; z-index: 1;
  padding: var(--pui-use-case-main-padding-v) var(--pui-use-case-main-padding-right) var(--pui-use-case-main-padding-v) var(--pui-use-case-main-padding-left);
  flex-direction: column; justify-content: center; align-items: flex-start;
  gap: var(--pui-use-case-main-gap); flex: 1 0 0;
}
.use-case-card__illustration {
  position: relative; flex-shrink: 0; z-index: 1; display: flex;
  align-items: center; justify-content: center;
  min-width: var(--pui-use-case-body-default-graphic-width);
  height: var(--pui-use-case-body-default-slot-height);
}
/* Rysunek ma 215×224 px wprost i jest WYŻSZY niż slot, w którym stoi
   (--pui-use-case-body-default-slot-height = 200 px) — wychodzi za jego kadr. */
.use-case-card__illustration img,
.use-case-card__illustration svg { position: absolute; width: 215px; height: 224px; max-width: unset; left: 0; transition: all .5s ease; }
.use-case-card__title-wrapper { display: inline-flex; align-items: center; position: relative; max-width: fit-content; }
.use-case-card__title { font-weight: 600; margin: 0; }
/* :deep(h6) — host sięga w atom typografii; siódme takie nadpisanie na
   stronie głównej i drugie dotyczące nagłówka, nie przycisku. */
.use-case-card__title h6 { transition: color 0.5s ease; }
.use-case-card__arrow { position: absolute; left: 100%; margin-left: 8px; opacity: 0; transform: translateX(-10px); transition: opacity 0.5s ease, transform 0.5s ease; }
.use-case-card:hover::after, .use-case-card:hover::before,
.use-case-card:active::after, .use-case-card:active::before { opacity: 1; }
.use-case-card:hover .use-case-card__arrow,
.use-case-card:active .use-case-card__arrow { opacity: 1; transform: translateX(0); }
.use-case-card:hover .use-case-card__illustration img,
.use-case-card:active .use-case-card__illustration img { left: -12px; }
/* Na tablecie przesunięcie rysunku jest COFANE do zera regułą w środku
   bloku hoveru — próg zagnieżdżony w stanie, nie obok niego. */
@media (max-width: 1023.98px) {
  .use-case-card:hover .use-case-card__illustration img,
  .use-case-card:active .use-case-card__illustration img { left: 0; }
}

/* OBWIEDNIA HOVERU: cztery wartości rgba wpisane wprost, każda równa
   istniejącej roli co do bajtu (rgba(159,230,208,0.2) = --static-primary-alpha-200,
   rgba(54,210,165,0.4) = --static-primary-alpha-400 i analogicznie purple).
   Role --pui-use-case-*-border-hover-start/-end są zdefiniowane i NIEUŻYWANE. */
.use-case-card--primary { background: linear-gradient(180deg, var(--pui-use-case-primary-bg-start), var(--pui-use-case-primary-bg-end)); }
.use-case-card--primary .use-case-card__arrow { color: var(--pui-text-primary); }
.use-case-card--primary::before { background: linear-gradient(180deg, rgba(159, 230, 208, 0.2) 0%, rgba(54, 210, 165, 0.4) 50%, rgba(159, 230, 208, 0.2) 100%); }
.use-case-card--primary:hover::after, .use-case-card--primary:active::after { background: var(--pui-use-case-primary-bg-hover); }
.use-case-card--primary:hover h6, .use-case-card--primary:active h6 { color: var(--pui-text-primary); }
.use-case-card--purple { background: linear-gradient(180deg, var(--pui-use-case-purple-bg-start), var(--pui-use-case-purple-bg-end)); }
.use-case-card--purple .use-case-card__arrow { color: var(--pui-text-purple); }
.use-case-card--purple::before { background: linear-gradient(180deg, rgba(197, 169, 243, 0.2) 0%, rgba(130, 83, 229, 0.4) 50%, rgba(197, 169, 243, 0.2) 100%); }
.use-case-card--purple:hover::after, .use-case-card--purple:active::after { background: var(--pui-use-case-purple-bg-hover); }
.use-case-card--purple:hover h6, .use-case-card--purple:active h6 { color: var(--pui-text-purple); }

/* @include media(tablet) → do 1023.98px. */
@media (max-width: 1023.98px) {
  .use-case-card { flex-direction: column; }
  .use-case-card__content { align-items: center; text-align: center; padding-bottom: 16px; }
  .use-case-card__illustration { bottom: -16px; height: 170px; width: 170px; min-width: unset; }
  .use-case-card__illustration img,
  .use-case-card__illustration svg { width: 170px; height: 170px; }
}

/* --- sections/UseCases.vue -------------------------------------------------
   Sekcja zastosowań jest jedynym miejscem w zakresie, gdzie host DOKŁADA
   klasy .section__* obok tych z ui/Section.vue — layout, left, right,
   heading-wrapper, arrow, title. Nazwy się nie gryzą, bo Section.vue nie ma
   żadnej z nich; są jednak w tej samej przestrzeni nazw i to jest cena
   nazywania od nazwy RODZICA, a nie od nazwy komponentu. */
.section--use-cases { display: block; overflow: clip; }
.section--use-cases .section__layout { display: flex; gap: var(--pui-container-content-gap-h); align-items: flex-start; }
/* Lewa kolumna jest PRZYKLEJONA (sticky, 100 px od góry) — karty przewijają
   się obok stojącego nagłówka. */
.section--use-cases .section__left { position: sticky; top: 100px; display: flex; flex-direction: column; gap: var(--pui-container-gap); }
.section--use-cases .section__heading-wrapper { position: relative; max-width: max-content; }
.section--use-cases .section__arrow { position: absolute; top: 16px; left: calc(100% + 24px); z-index: 0; pointer-events: none; }
.section--use-cases .section__title { position: relative; z-index: 1; }
.section--use-cases .section__title span { display: block; }
/* --heading-height pisze SKRYPT komponentu (ResizeObserver na nagłówku):
   prawa kolumna zaczyna się pod nagłówkiem, którego wysokości arkusz nie zna. */
.section--use-cases .section__right {
  display: flex; flex-direction: column; gap: var(--pui-use-case-container-gap);
  max-width: var(--pui-use-case-body-default-max-width);
  min-width: var(--pui-use-case-body-default-min-width);
  padding-top: calc(var(--heading-height) + var(--pui-container-gap));
}
/* @include media(laptop) → do 1479.98px: strzałka odręczna znika. */
@media (max-width: 1479.98px) {
  .section--use-cases .section__heading-wrapper .use-cases-arrow { display: none; }
}
/* @include media(tablet) → do 1023.98px: kolumna, koniec przyklejenia,
   prawa strona przechodzi z kolumny na siatkę auto-fit. */
@media (max-width: 1023.98px) {
  .section--use-cases .section__layout { flex-direction: column; }
  .section--use-cases .section__left { position: relative !important; top: 0; }
  .section--use-cases .section__right { display: grid; grid-template-columns: repeat(auto-fit, minmax(312px, 1fr)); gap: var(--pui-use-case-container-gap); padding-top: 0; width: 100%; max-width: unset; min-width: unset; }
}

/* --- ui/UseCasesArrow.vue (blok scoped) ------------------------------------
   Pozycjonowanie stoi DWA RAZY: raz tutaj, raz w arkuszu sekcji jako
   .section__arrow — i w produkcie obie reguły siadają na TYM SAMYM elemencie,
   bo host podaje swoją klasę przez atrybut komponentu. Wartości są identyczne
   (top 16px, left calc(100% + 24px)), więc rozjazdu dziś nie widać; zobaczy go
   dopiero ten, kto zmieni jedną z nich. */
.use-cases-arrow { position: absolute; top: 16px; left: calc(100% + 24px); z-index: 0; pointer-events: none; }
.use-cases-arrow__svg { display: block; overflow: visible; }
.use-cases-arrow__head { position: absolute; top: 0; left: 0; transform-origin: 9px 12px; }

/* =============================================================================
   ui/NewsletterForm.vue (blok scoped). Odczyt 12.08.2026. NAZWY KLAS BEZ ZMIAN.

   TRZY REGUŁY :deep() I KAŻDA JEST NADPISANIEM CUDZEGO ATOMU — to jest cała
   treść tego pliku poza obsługą błędu:
   · w kartce newslettera pole traci obwiednię CAŁKOWICIE,
   · w wariancie nawigacji traci ją TYLKO POZA FOCUSEM,
   · przycisk dostaje szerokość 100% (w kodzie razem z propsem `block`).
   Reguła `:deep(.btn)` stoi w bloku BEZ selektora rodzica, więc w produkcie
   sięga w każdy przycisk wewnątrz komponentu; przepisana z zawężeniem do obu
   wariantów formularza, bo w płaskim arkuszu bez tego sięgnęłaby w całą stronę.
   ============================================================================= */
.newsletter-form {
  display: flex; flex-direction: column; align-items: flex-start; align-self: stretch;
  padding: var(--pui-community-box-newsletter-form-padding-v) var(--pui-community-box-newsletter-form-padding-h);
  gap: var(--pui-community-box-newsletter-form-gap);
  border-radius: var(--pui-community-box-newsletter-form-radius);
  background: var(--pui-community-box-newsletter-form-bg);
}
.newsletter-form .input-group .input-group__inner { border: none; }
.newsletter-form-nav { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pui-sub-navigation-newsletter-form-gap-v); }
.newsletter-form-nav .input-group .input-group__inner:not(:focus-within) { border-color: transparent; }
.newsletter-form-nav .newsletter-form__error { background: var(--static-red-alpha-150); border-color: var(--static-red-alpha-250); }
.newsletter-form-nav .newsletter-form__error-text { color: var(--pui-text-red); }
.newsletter-form .btn, .newsletter-form-nav .btn { width: 100%; }

.newsletter-form__error-wrapper { width: 100%; display: grid; grid-template-rows: 1fr; transition: all var(--pui-animation-slide-fade-duration) var(--pui-animation-slide-fade-easing); }
.newsletter-form__error-content { min-height: 0; overflow: hidden; }
.newsletter-form__error {
  display: flex;
  padding: var(--pui-community-box-newsletter-validation-padding-v) var(--pui-community-box-newsletter-validation-padding-h);
  justify-content: center; align-items: center; gap: 10px; align-self: stretch;
  border-radius: var(--pui-community-box-newsletter-validation-radius);
  border: 1px solid var(--static-red-alpha-250); background: var(--static-red-alpha-150);
  position: relative; width: 100%;
}
/* Biel napisu błędu wpisana wprost, mimo że rodzina ma --pui-text-red;
   wariant nawigacji ZMIENIA ją na tę rolę regułą wyżej. Ta sama treść
   w dwóch kolorach zależnie od miejsca użycia. */
.newsletter-form__error-text {
  color: #fff; text-align: center; font-family: var(--static-typography-font-family);
  font-size: var(--pui-text-p-sm-font-size); font-weight: 500;
  line-height: var(--pui-text-p-sm-line-height); letter-spacing: var(--pui-text-p-sm-letter-spacing);
}
/* Komunikat captchy: SIEDEM wartości wpisanych wprost, zero ról — jedyny
   fragment tej rodziny, który nie czyta ani jednego tokenu. */
.captcha-message { background-color: #198754; color: #fff; border-radius: 5px; font-size: 14px; font-weight: 400; line-height: 24px; padding: 13px 16px; width: 100%; }
/* Przejście Vue <Transition name="slide-fade">: klasy stanu wstawia runtime
   frameworka, nie arkusz. Przepisane, bo są w tym samym bloku i opisują ruch
   komunikatu błędu. */
.slide-fade-enter-active, .slide-fade-leave-active { transition: all var(--pui-animation-slide-fade-duration) var(--pui-animation-slide-fade-easing); }
.slide-fade-enter-from, .slide-fade-leave-to { grid-template-rows: 0fr; opacity: 0; }

/* =============================================================================
   ui/Slider/Features.vue (blok scoped). Odczyt 12.08.2026. NAZWY KLAS BEZ ZMIAN.

   NAZWY KLATKOWAŃ scroll-left i scroll-right SĄ W KODZIE LOKALNE (PA-42:
   nazwa rozwiązywalna spoza pliku jest tokenem, nazwa lokalna zostaje przy
   komponencie). W płaskim arkuszu tracą tę lokalność — stają się globalne
   i pierwsze inne @keyframes o tej nazwie je nadpisze. Przepisane pod nazwą
   z kodu, bo nazwa jest identyfikatorem; ryzyko kolizji zapisane tutaj.
   ============================================================================= */
.slider { width: 100%; }
.slider-track { display: flex; width: max-content; gap: var(--pui-feature-slider-gap); }
/* Czas 75 s stoi w arkuszu DWA RAZY, a props `speed` jest zadeklarowany
   i NIGDZIE nieużyty — wejście, które nie ma jak zadziałać. */
.slider-track--left { animation: scroll-left var(--src-fslider-duration) linear infinite; }
.slider-track--right { animation: scroll-right var(--src-fslider-duration) linear infinite; }
/* Trzy kopie listy i −33.3333% muszą się zgadzać, a nic ich nie wiąże poza
   tym, że autor wpisał obie liczby ręcznie. */
@keyframes scroll-left { 0% { transform: translateX(0); } 100% { transform: translateX(-33.3333%); } }
@keyframes scroll-right { 0% { transform: translateX(-33.3333%); } 100% { transform: translateX(0); } }

/* OBWIEDNIA ZADEKLAROWANA I BEZSKUTECZNA (RZ-33): karta nosi .border-mask,
   a ten pomocnik zaczyna się od `border: none !important`, więc `border`
   z tej reguły nie rysuje nic. Jedyną widoczną obwiednią jest maska z ::before,
   trzema wartościami rgba wprost. Rola --pui-feature-icon-on-primary-border-start
   jest tu wołana i nie ma wpływu na to, co widać.
   Cień 0 8px 40px #00000029 — wprost, bez roli. */
.feature-card {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: var(--pui-feature-icon-padding-v) var(--pui-feature-icon-padding-h);
  gap: var(--pui-feature-icon-gap);
  box-shadow: 0px 8px 40px 0px #00000029;
  border-radius: var(--pui-feature-icon-radius);
  border: var(--pui-feature-icon-border-width) solid var(--pui-feature-icon-on-primary-border-start);
  background: linear-gradient(180deg, var(--pui-feature-icon-on-primary-bg-start) 0%, var(--pui-feature-icon-on-primary-bg-end) 100%);
  backdrop-filter: blur(var(--pui-ui-blur-sm));
  transition: transform 0.3s ease;
}
.feature-card::before { background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.5) 49.52%, rgba(255, 255, 255, 0.1) 100%); }
.feature-card__icon { width: var(--pui-feature-icon-icon-size); height: var(--pui-feature-icon-icon-size); display: flex; align-items: center; justify-content: center; }
.feature-card__icon svg { width: 100%; height: 100%; }
.feature-card__content { display: flex; flex-direction: column; align-items: center; gap: var(--pui-feature-icon-text-gap); text-align: center; transition: color 0.3s ease; }
/* :deep(.text-h8) — host sięga w atom typografii; ósme takie nadpisanie
   w zakresie strony głównej. */
.feature-card__content .text-h8 { font-weight: 500; }

/* KARTA NIE MA SZEROKOŚCI (RZ-57): rola --pui-feature-icon-width = 300 px
   istnieje i nie czyta jej żaden arkusz. Karta stoi na flex: 0 0 auto,
   czyli bierze szerokość z treści — karty są RÓŻNEJ szerokości. */

/* =============================================================================
   ui/WatchButton.vue + ui/Video.vue (oba bloki scoped). Odczyt 12.08.2026.
   NAZWY KLAS BEZ ZMIAN.
   ============================================================================= */

/* --- ui/WatchButton.vue ---------------------------------------------------- */
/* PIERWSZY BLOK PLIKU OPISUJE CUDZE MIEJSCE UŻYCIA: `.graphic .watch-button`
   przestawia przycisk na wymiary PROCENTOWE, gdy stoi w ramce ilustracji
   (Content block). Reguła mieszka w komponencie, a mówi o gospodarzu —
   odwrotnie niż nadpisania hosta, które widzieliśmy dotąd. */
.graphic .watch-button { z-index: 100; position: relative; }
.graphic .watch-button__content { gap: 1.4%; }
.graphic .watch-button__content .watch-button__label { width: 24.36%; height: 6.5%; justify-content: center; align-items: center; padding: 0; grid-area: unset; }
.graphic .watch-button__content .watch-button__button { margin-top: 7.04%; width: 12.23%; height: 12.23%; }
.graphic .watch-button__content .watch-button__button svg { width: 32.5%; height: 32.5%; }

.watch-button { display: flex; grid-area: 1 / 1; place-self: center; z-index: 10; width: 100%; height: 100%; justify-content: center; }
.watch-button__content {
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  width: 100%; gap: var(--pui-video-block-default-video-container-cta-gap);
  cursor: pointer; text-decoration: none; color: inherit;
}
/* Rozmiar base czyta rodzinę --pui-video-block-*; rozmiar sm ma wymiary
   WPISANE WPROST (68, 22, gap 8) i nie czyta ani jednej roli. */
.watch-button__content--base .watch-button__button {
  width: var(--pui-video-block-default-video-container-cta-button-max-width);
  max-width: var(--pui-video-block-default-video-container-cta-button-max-width);
  height: var(--pui-video-block-default-video-container-cta-button-max-height);
  transition: all .7s ease;
}
.watch-button__content--base .watch-button__button svg { width: var(--pui-video-block-default-video-container-cta-button-icon-size); height: var(--pui-video-block-default-video-container-cta-button-icon-size); }
.watch-button__content--base .watch-button__label { padding: var(--pui-video-block-default-video-container-cta-label-padding-v) var(--pui-video-block-default-video-container-cta-label-padding-h); }
.watch-button__content--base:hover .watch-button__button {
  max-width: var(--pui-video-block-default-video-container-cta-button-max-width-hover);
  max-height: var(--pui-video-block-default-video-container-cta-button-max-height-hover);
}
.watch-button__content--base:hover .watch-button__button::before { opacity: 1; }
.watch-button__content--sm { gap: 8px; }
.watch-button__content--sm .watch-button__button { width: 68px; height: 68px; }
.watch-button__content--sm .watch-button__button svg { width: 22px; height: 22px; }
/* DWA MECHANIZMY JEDNEGO POWIĘKSZENIA w jednym pliku: base zmienia maksymalny
   wymiar, sm skaluje transformacją. */
.watch-button__content--sm:hover .watch-button__button { transform: scale(105%); }
.watch-button__content--sm:hover .watch-button__button::before { opacity: 1; }
.watch-button__button {
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  border-radius: var(--pui-video-block-default-video-container-cta-button-radius);
  background: linear-gradient(180deg, var(--pui-video-block-video-container-button-bg-start) 0%, var(--pui-video-block-video-container-button-bg-end) 100%);
  transition: all .7s ease; position: relative; overflow: hidden; color: white;
}
.watch-button__button::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--pui-video-block-video-container-button-bg-hover-start) 0%, var(--pui-video-block-video-container-button-bg-hover-end) 100%);
  opacity: 0; transition: opacity .7s ease; z-index: 0;
}
.watch-button__button svg { position: relative; z-index: 1; }
/* Selektor :not(svg) jest w kodzie, bo w rozmiarze sm etykieta JEST elementem
   <svg> z tekstem zamienionym na ścieżki. Obwiednia rgba wprost; blur 10px
   zadeklarowany DWA RAZY pod rząd — przepisany raz. */
.watch-button .watch-button__label:not(svg) {
  display: flex; align-items: flex-start; gap: 10px; align-self: center;
  border-radius: var(--pui-video-block-default-video-container-cta-label-radius);
  border: var(--pui-video-block-default-video-container-cta-label-border-width) solid rgba(255, 255, 255, 0.40);
  background: linear-gradient(180deg, var(--pui-video-block-video-container-label-bg-start) 0%, var(--pui-video-block-video-container-label-bg-end) 100%);
  backdrop-filter: blur(10px);
  transition: background 0.7s ease, border-color 0.7s ease;
  width: fit-content;
}

/* --- ui/Video.vue ---------------------------------------------------------- */
/* Video jest KARTĄ: renderuje UiCard z borderMask, więc cały wygląd ramki
   przychodzi z rodziny .card, a ten blok dokłada wyłącznie układ. */
.video__inner { display: flex; width: 100%; }
.video__media { width: 100%; cursor: pointer; }
.video__media:hover .watch-button__content .watch-button__button { transform: scale(107%); }
.video__media:hover .watch-button__content .watch-button__button::before { opacity: 1; }
.video__media:hover .video__placeholder::before { opacity: 1; }
.video__content { display: flex; flex-direction: column; justify-content: center; }
.video__placeholder {
  width: 100%; height: 100%;
  background: linear-gradient(180deg, var(--pui-video-block-video-container-overlay-bg-start) 50.48%, var(--pui-video-block-video-container-overlay-bg-end) 100%);
  display: flex; align-items: center; justify-content: center; position: relative;
  border-radius: var(--pui-video-block-default-video-container-radius);
}
.video__placeholder::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--pui-video-block-video-container-overlay-bg-hover-start) 50.48%, var(--pui-video-block-video-container-overlay-bg-hover-end) 100%);
  opacity: 0; transition: opacity .7s ease;
  border-radius: var(--pui-video-block-default-video-container-radius); z-index: 0;
}
.video--row .video__inner { flex-direction: row; align-items: center; }
.video--row .video__title { font-weight: 600; }
.video--row .video__media { display: flex; justify-content: center; align-items: center; flex: 1 0 0; aspect-ratio: 310/237; }
.video--row .video__content { gap: var(--pui-section-desc-default-base-main-gap); padding: 0 var(--pui-section-desc-default-base-body-padding-h); }
.video--row .video__content-inner { display: flex; flex: 1 0 0; flex-direction: column; justify-content: center; padding: var(--pui-video-block-default-text-container-horizontal-padding-v) var(--pui-video-block-default-text-container-horizontal-padding-h); }
.video--row .video__placeholder { min-height: auto; height: 100%; border-radius: var(--pui-video-block-default-video-container-radius); }
.video--column .video__inner { flex-direction: column; }
.video--column .video__media { width: 100%; }
.video--column .video__content { gap: var(--pui-section-desc-default-sm-main-gap); padding: var(--pui-section-desc-default-sm-body-padding-v) var(--pui-section-desc-default-sm-body-padding-h); }
.video--column .video__content-inner { padding: var(--pui-video-block-default-text-container-vertical-padding-top) var(--pui-video-block-default-text-container-vertical-padding-h) var(--pui-video-block-default-text-container-vertical-padding-bottom) var(--pui-video-block-default-text-container-vertical-padding-h); }
.video--column .video__placeholder { aspect-ratio: 16 / 9; }
/* Trzy progi i wszystkie trzy dotyczą WYŁĄCZNIE wariantu row. */
@media (max-width: 1479.98px) { .video--row .video__media { min-width: 456px; } }
@media (max-width: 1023.98px) { .video--row .video__media { min-width: unset; align-self: baseline; aspect-ratio: 327/250; } }
@media (max-width: 767.98px) {
  .video--row .video__inner { flex-direction: column; }
  .video--row .video__content-inner { padding: var(--pui-video-block-default-text-container-horizontal-padding-v) 0; }
}

/* =============================================================================
   sections/Collaborate.vue (blok scoped). Odczyt 12.08.2026.

   ZAWĘŻENIE, KTÓRE TRZEBA BYŁO ZROBIĆ RĘCZNIE (rodzina RZ-77): w kodzie
   `:deep(.section__content)` działa w zasięgu TEJ instancji sekcji, bo blok
   jest scoped. W płaskim arkuszu ten sam selektor trafiłby w KAŻDĄ sekcję
   serwisu. Zawężone klasą, którą host i tak podaje sekcji przez sectionClass:
   .section--collaborate. To jest ta sama klasa, po której produkt rozpoznaje
   tę sekcję — nie nowa nazwa wymyślona na potrzeby zawężenia.
   ============================================================================= */
/* HOST SIĘGA W ŚRODEK SEKCJI: zmienia układ jej slotu z zewnątrz. */
.section--collaborate .section__content { display: flex; justify-content: center; }
.collaborate { display: grid; position: relative; max-width: 1268px; aspect-ratio: 1268 / 618; height: max-content; width: 100%; align-items: center; }
.collaborate img, .collaborate svg { grid-area: 1/1; height: auto; max-width: 100%; }
/* Kropki pulsu pozycjonowane SELEKTOREM KOLEJNOŚCI (div:nth-of-type),
   nie klasą. Położenia liczone z proporcji ilustracji: calc(y / 618 * 100%)
   i calc(x / 1268 * 100%) — przepisane co do liczby. Siódma ma z-index -1
   i jest jedyną, która idzie POD warstwy. */
.collaborate div { position: absolute; top: calc(349 / 618 * 100%); left: calc(126 / 1268 * 100%); }
.collaborate div:nth-of-type(2) { top: calc(228 / 618 * 100%); left: calc(195 / 1268 * 100%); }
.collaborate div:nth-of-type(3) { top: calc(70 / 618 * 100%); left: calc(365 / 1268 * 100%); }
.collaborate div:nth-of-type(4) { top: calc(524 / 618 * 100%); left: calc(883 / 1268 * 100%); }
.collaborate div:nth-of-type(5) { top: calc(359 / 618 * 100%); left: calc(1064 / 1268 * 100%); }
.collaborate div:nth-of-type(6) { top: calc(264 / 618 * 100%); left: calc(1126.5 / 1268 * 100%); }
.collaborate div:nth-of-type(7) { top: calc(469.5 / 618 * 100%); left: calc(228.8 / 1268 * 100%); z-index: -1; }

/* RYSOWANIE ŚCIEŻEK: cztery klasy .path-* z długościami wpisanymi wprost
   (180, 62, 280, 72) i cztery opóźnienia od 1.4s do 2.4s. Działa WYŁĄCZNIE
   wtedy, gdy plik SVG jest wstawiony DO DRZEWA (import ?component) — dwie
   z siedmiu warstw takie są, pozostałe pięć to obrazy. Katalog wczytuje
   wszystkie siedem jako obrazy, więc te reguły nie mają w nim czego dosięgnąć;
   przepisane, bo są częścią rodziny i mówią, czego kadr NIE pokazuje. */
.collaborate .path-1 { stroke-dasharray: 180; stroke-dashoffset: 180; }
.collaborate .path-2 { stroke-dasharray: 62; stroke-dashoffset: 62; }
.collaborate .path-3 { stroke-dasharray: 280; stroke-dashoffset: 280; }
.collaborate .path-4 { stroke-dasharray: 72; stroke-dashoffset: 72; }
.collaborate svg[data-anim-in] .path-1 { animation: draw 0.5s ease forwards 1.4s; }
.collaborate svg[data-anim-in] .path-2 { animation: draw 0.5s ease forwards 1.6s; }
.collaborate svg[data-anim-in] .path-3 { animation: draw 0.7s ease forwards 2s; }
.collaborate svg[data-anim-in] .path-4 { animation: draw 0.4s ease forwards 2.4s; }
@keyframes draw { to { stroke-dashoffset: 0; } }

/* --- sections/FeaturesShowcase.vue (blok scoped) ---------------------------
   ZATRZYMANIE RUCHU JEST W ARKUSZU HOSTA, nie w slajderze: `:hover` sekcji
   sięga selektorem w KLASĘ WEWNĘTRZNĄ osadzonego komponentu (.slider-track).
   Slajder nie ma propsu, który by to wyrażał — i to jest powód, dla którego
   katalog musiał trzymać wejście `paused`, dopóki reguły nie było w arkuszu. */
/* PRZYCIĘCIE TYLKO W POZIOMIE (zgłoszenie zamawiającego 24.08.2026: „od góry nie powinno być żadnego
   przycięcia, więc po prostu to usuń"). Pas jedzie w bok, więc przycinać trzeba wyłącznie boki:
   `overflow-x: clip` pozwala drugiej osi zostać widoczną, czego `hidden` nie potrafi —
   `hidden` na jednej osi wymusza `auto` na drugiej i to ono cięło górę i dół.
   Wyściółka 36 px z marginesem -36 px była OBEJŚCIEM tego samego problemu (miejsce na cień
   rozmyty na 40 px) i schodzi razem z przyczyną: wysokość i położenie pasa bez zmian, bo
   obie wartości i tak się znosiły. */
.slider-features-wrapper { width: 100%; overflow-x: clip; overflow-y: visible; display: flex; flex-direction: column; gap: var(--pui-feature-slider-gap); }
.slider-features-wrapper:hover .slider-track { animation-play-state: paused; }

/* --- sections/Community.vue (blok scoped) ---------------------------------- */
.community { display: flex; gap: var(--pui-container-grid-gap); align-items: stretch; flex-wrap: wrap; }
/* Obie kolumny mają tę samą minimalną szerokość i to ona rozstrzyga zawijanie;
   rola nazywa się od FORUM, choć trzyma szerokość obu kolumn sekcji. */
.community__left { flex: 1; display: flex; min-width: var(--pui-community-box-forum-body-min-width); height: fit-content; }
.community__right { display: flex; flex-direction: column; gap: var(--pui-container-grid-gap); min-width: var(--pui-community-box-forum-body-min-width); flex: 1; }

/* =============================================================================
   elements/navbar.scss — ARKUSZ GLOBALNY, 1120 linii. Odczyt 12.08.2026.
   NAZWY KLAS BEZ ZMIAN.

   To NIE JEST komponent, tylko rodzina w tej samej warstwie co buttons.scss
   i badge.scss: pasek górny, nawigacja główna, rozwijane menu, pozycja menu,
   hamburger, kafle społecznościowe. Pozycja katalogu „Navigation" (31 stylów)
   wyglądała na jeden komponent z listy P2.1 i jest w istocie tą całą rodziną.

   Progi: respond-to(tablet) → do 1023.98px, (laptop) → do 1479.98px,
   (mobile) → do 767.98px, (tablet, min) → od 1024px.
   ============================================================================= */

/* --- pasek górny ----------------------------------------------------------- */
/* min-height 40px i obwiednia mają w kodzie komentarz TODO: replace — autor
   wie, że to literały bez roli. W całym pliku jest ich CZTERNAŚCIE. */
.top-bar { display: flex; justify-content: center; align-items: center; position: absolute; top: 0; left: 0; z-index: 30; width: 100%; min-height: 40px; border-bottom: 1px solid var(--pui-navigation-separator); }
.top-bar__container { display: flex; align-items: center; justify-content: space-between; width: 100%; max-width: var(--pui-navigation-width-max); padding: var(--pui-navigation-secondary-padding-v) var(--pui-navigation-secondary-padding-h); gap: var(--pui-navigation-secondary-gap); }
.top-bar__nav { display: flex; align-items: center; justify-content: flex-end; width: 100%; list-style: none; }
.top-bar__link { display: inline-flex; align-items: center; justify-content: center; padding: var(--pui-navigation-secondary-item-padding-v) var(--pui-navigation-secondary-item-padding-h); color: var(--pui-text-heading); text-decoration: none; font-size: var(--pui-text-p-xs-font-size); font-weight: 300; line-height: var(--pui-text-p-xs-line-height); letter-spacing: var(--pui-text-p-xs-letter-spacing); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); }
.top-bar__link:hover, .top-bar__link:active, .top-bar__link.router-link-active { color: var(--pui-text-primary); }

/* --- nawigacja główna ------------------------------------------------------ */
/* top: 49px wprost — pasek górny ma 40px plus obwiednia; liczba jest sumą,
   której nikt nie liczy z ról. */
.nav { position: absolute; top: 49px; left: 0; z-index: 25; display: flex; justify-content: center; align-items: center; gap: var(--pui-navigation-secondary-gap); width: 100%; }
.nav.is-fixed { position: fixed; top: 0; padding-bottom: var(--pui-navigation-main-padding-bottom); background: var(--pui-navigation-bg-scroll); backdrop-filter: blur(calc(var(--pui-ui-blur-md) / 2)); box-shadow: 0 20px 40px 0 var(--static-overlay-dark-100); }
.nav__container { display: flex; position: relative; align-items: center; width: 100%; max-width: var(--pui-navigation-width-max); margin: 0 auto; padding: var(--pui-navigation-main-padding-top) var(--pui-navigation-main-padding-h) 0; }
.nav__brand { display: flex; align-items: center; flex-shrink: 0; height: var(--pui-logo-height); max-height: var(--pui-logo-height); }
.nav__brand svg { height: 100%; }
.nav__menu { display: flex; align-items: center; justify-content: flex-end; flex: 1; }
.nav__actions { display: flex; align-items: center; padding-left: var(--pui-navigation-main-action-padding-left); }
.nav__nav { display: flex; align-items: center; list-style: none; gap: var(--pui-navigation-main-items-wrap-gap); }
/* Podlista rozwinięcia pożycza rolę separatora ze STOPKI (--pui-footer-separator);
   rodzina nawigacji ma własną (--pui-navigation-separator) i nie jest tu wołana. */
.nav__subnav { display: flex; flex-direction: column; gap: var(--pui-sub-navigation-link-gap); align-items: start; padding: var(--pui-sub-navigation-list-heading-gap) var(--pui-sub-navigation-link-padding) var(--pui-sub-navigation-link-padding) var(--pui-sub-navigation-link-padding); border-top: 1px solid var(--pui-footer-separator); margin-top: var(--pui-sub-navigation-list-heading-gap); }
.nav__subnav--link { display: inline-flex; align-items: center; justify-content: center; list-style: none; color: var(--pui-text-lighter); text-decoration: none; font-size: var(--pui-text-p-xs-font-size); font-weight: 300; line-height: var(--pui-text-p-xs-line-height); letter-spacing: var(--pui-text-p-xs-letter-spacing); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); }
.nav__subnav--link:hover, .nav__subnav--link:active { color: var(--pui-text-primary); }
.nav__item.nav__item--active .nav__link { color: var(--pui-text-primary); }
.nav__item.nav__item--active .nav__link.nav__link--community { color: var(--pui-text-orange); }
.nav__item.nav__item--active .nav__link .nav__link-caret { transform: rotate(180deg); }
.nav__link { display: inline-flex; align-items: center; justify-content: center; gap: var(--pui-navigation-main-menu-item-gap); padding: var(--pui-navigation-main-menu-item-item-padding-v) var(--pui-navigation-main-menu-item-item-padding-h); color: var(--pui-text-heading); font-size: var(--pui-text-p-lg-font-size); line-height: var(--pui-text-p-lg-line-height); font-weight: 600; letter-spacing: var(--pui-text-p-lg-letter-spacing); text-decoration: none; cursor: pointer; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); }
/* Pozycja „Community" jest POMARAŃCZOWA W KAŻDYM STANIE — trzy reguły pilnują,
   żeby hover i stan aktywny jej nie przemalowały na primary. */
.nav__link.nav__link--community { color: var(--pui-text-orange); }
.nav__link:hover { color: var(--pui-text-primary); }
.nav__link:hover.nav__link--community { color: var(--pui-text-orange); }
.nav__link:active { color: var(--pui-text-primary); }
.nav__link.nav__link--open { color: var(--pui-text-primary); }
.nav__link.nav__link--open .nav__link-caret { transform: rotate(180deg); }
.nav__link-caret { display: inline-flex; align-items: center; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); }
.nav__link-caret > svg { width: var(--pui-navigation-main-menu-item-icon-size); height: var(--pui-navigation-main-menu-item-icon-size); }
.nav--h { flex-direction: row; }
.nav__link-text { display: inline-flex; align-items: center; justify-content: center; }
.nav__link-text .icon-image { padding-left: 10px; }

/* --- rozwinięcie ----------------------------------------------------------- */
.nav__dropdown { position: absolute; top: calc(100% + 8px); left: 0; right: 0; transform: none; z-index: 40; width: 100%; padding: 0 var(--pui-navigation-main-padding-h); max-width: var(--pui-navigation-width-max); opacity: 0; visibility: hidden; transition: opacity 0.2s ease, visibility 0.2s ease; animation-duration: .3s; animation-fill-mode: both; animation-name: fadeInUp; }
.nav__dropdown.is-open { opacity: 1; visibility: visible; }
.nav__dropdown > .container { padding: 0; max-width: var(--pui-navigation-width-max); }
@keyframes fadeInUp { 0% { opacity: 0; transform: translate3d(0, 10px, 0); } }
/* PANEL BEZ WYSCIOLKI I BEZ ODSTEPU MIEDZY KOLUMNAMI (przeniesione ze szkicu submenu
   23.08.2026, etap "szkic -> klasy"). Wysciolke niosa KONTENERY KOLUMN, kazdy swoja:
   kolumna z linkami wieksza, kolumna z pudelkiem mniejsza. Panel, ktory trzymal jedno
   i drugie, zmuszal pudelka do wychodzenia ujemnym marginesem - te marginesy zeszly.
   Role --pui-sub-navigation-padding-* NIE ZNIKAJA: czytaja je teraz kolumny, czyli rola
   znaczy to samo, tylko stoi o poziom nizej.
   `align-items: stretch` zamiast `flex-start`: kolumna z pudelkiem ma isc na cala wysokosc
   panelu, inaczej pod kaflem zostaje biala dziura. */
.dropdown__wrapper { display: flex; align-items: stretch; gap: 0; padding: 0; border-radius: var(--pui-sub-navigation-radius); background: var(--pui-sub-navigation-bg); box-shadow: 0 14px 30px 0 var(--pui-sub-navigation-shadow-black), 0 47px 52px 6px var(--pui-sub-navigation-shadow-green); }
/* SIATKA KOLUMN PANELU — DOPISANE 24.08.2026, BRAK Z WŁASNEJ MIGRACJI 23.08.
   Szkic w przyjętej wersji S8 stawiał panel na SIATCE, nie na flexie: jego własna lista
   zmian mówi wprost „.dropdown__wrapper (układ): z flex NA grid trzech kolumn
   minmax(0,…fr)". Do klas weszła wtedy wyściółka kolumn, a sama siatka została
   w atrybucie szkicu i nie przeszła nigdzie — panel wrócił do flexa, więc kolumna
   dostawała szerokość SWOJEJ TREŚCI: pozycje z krótkim opisem były węższe od pozycji
   z długim, a kolumna „Alternative To" ściskała się do 250 px i łamała nagłówek na dwie
   linie. Zgłoszenie zamawiającego 24.08.2026: „nadal nie wygląda tak samo".
   PROPORCJE PRZEPISANE ZE SZKICU CO DO ZNAKU, żadna nie jest moja:
   --triple     Use Cases: trzy kolumny tematyczne (S1/S8, stała COLS),
   --links-box  For Business: lista + karta klienta (kolumna karty na dwa slots 316 px),
   --box-links  Features S8-P: kafel 316 px + siatka pozycji.
   Panele bez siatki (Resources, Community) zostają na flexie z arkusza — tam kolumna
   z linkami bierze całą szerokość swoim `flex: 1`. */
.dropdown__wrapper--triple { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1.15fr) minmax(0, 0.8fr); }
.dropdown__wrapper--links-box { display: grid; grid-template-columns: minmax(min(320px, 100%), 1fr) minmax(min(316px, 100%), calc(316px * 2 + var(--static-space-8x))); }
.dropdown__wrapper--box-links { display: grid; grid-template-columns: 316px minmax(0, 1fr); }
/* KOLUMNA Z LINKAMI TRZYMAJACA WIECEJ NIZ JEDNA GRUPE (uklad "pudelko + lista", Features
   S8-P). Wysciolke niesie kontener kolumny, grupy w srodku swojej nie maja.
   ODSTEP MIEDZY GRUPAMI NIE JEST TU STANEM UZGODNIONYM I NIE UDAWAJ, ze jest (poprawione
   24.08.2026 po przegladzie, ktory zlapal moje nieprawdziwe zdanie w tym miejscu):
   szkic S8-P ma miedzy „Single-Server" i „Pro and Multi-Server" 40 px (`space-5x` wpisany
   w atrybucie, linia 1039 szkicu), a rola `--pui-sub-navigation-sections-gap` daje 20 px
   na desktopie i laptopie, 12 px na tablecie. ROLI O WARTOSCI SZKICU W DS NIE MA - zgloszone
   jako brak (TODO M.13), a nie zalatane skala w zastepstwie: skala nie zmienia sie z progiem
   i zostalaby desktopowa na telefonie. Do decyzji panuje tu rola, czyli 20 px, i to jest
   ROZJAZD Z PRZYJETA WERSJA, nie jej odwzorowanie. */
.dropdown__content-col--links:has(> .dropdown__content-group) { display: flex; flex-direction: column; gap: var(--pui-sub-navigation-sections-gap); }
.dropdown__content-col--links > .dropdown__content-group { width: 100%; }
/* ODSTĘP NAGŁÓWEK–LISTA MA JEDEN NOŚNIK (zgłoszenie zamawiającego 24.08.2026: „za duzy odstep,
   wiekszy niz w innych submenu"). Zmierzone: w każdym innym panelu przerwa wynosi 12 px
   i daje ją MARGINES nagłówka; w kolumnie Features nagłówek stoi dodatkowo w grupie, która
   niesie własny `gap` roli `section-heading-gap` (16 px) — dwa nośniki sumowały się do 28.
   Zeruję gap grupy, nie margines nagłówka: margines działa we wszystkich panelach, więc to
   on jest nośnikiem, a gap był tu drugim. */
.dropdown__content-col--links > .dropdown__content-group { row-gap: 0; }
/* POZYCJA WYPEŁNIA KOLUMNĘ. Szkic miał to w atrybucie (`style="…width:100%"` przy każdej
   pozycji) i przy przenoszeniu do komponentu wartość została po drodze: `.dropdown__content-items`
   niesie `align-items: flex-start`, więc pozycja w kolumnie pionowej dostawała szerokość
   swojego tekstu. SELEKTOR IDZIE PO DZIECKU KONTENERA, nie po `.nav-item` (poprawione
   24.08.2026 pomiarem: w komponencie pozycję niesie OSADZENIE, a `.nav-item` siedzi w jego
   środku — reguła na `.nav-item` rozciągała więc element wewnątrz pudełka, które samo już
   było zwężone; „For Business" miał pozycje 540 px w kolumnie o świetle 644 px).
   WYJĄTEK NA SIATKACH JEST ZMIERZONY, nie ostrożnościowy: w `--features` i `--resources`
   pudełko stoi w komórce i bierze `flex: 1`, bo przy `width: 100%` ujemny margines zwisu
   znikał z prawej strony (pomiar 23.08.2026, szkic). */
.dropdown__content-items:not(.dropdown__content-items--features):not(.dropdown__content-items--resources) > * { width: 100%; }
/* TRZY RODZAJE KOLUMNY PANELU. Rodzina ta sama co dotad (.dropdown__content-col--*),
   zadnej nowej. Roznica jest jedna i widac ja na ekranie: ile miejsca zostaje przy
   krawedzi panelu.
   --links  kolumna z pozycjami menu; w poziomie rola + zwis pudelka pozycji (12 px),
            bo pudelko zwis zjada i NA EKRANIE zostaje rowne 28,
   --box    kolumna, ktora jest samym pudelkiem (kafel, karta klienta, Alternative To):
            mniej i jedna wartoscia, wiec krawedz karty stoi ciasniej niz pozycje,
   --items  wyjatek Community: pudelka SA pozycjami menu, wiec biora wysciolke kolumny
            z linkami, ale bez doliczania zwisu, ktorego nie maja. */
.dropdown__content-col--links { flex: 1; min-width: 0; padding: var(--pui-sub-navigation-padding-v) calc(var(--pui-sub-navigation-padding-h) + var(--pui-sub-navigation-item-padding)); }
.dropdown__content-col--box { display: flex; flex-direction: column; padding: var(--static-space-2x); }
.dropdown__content-col--items { flex: 1; min-width: 0; padding: var(--pui-sub-navigation-padding-v) var(--pui-sub-navigation-padding-h); }

/* ===== PUDELKA PANELU (przeniesione ze szkicu submenu 23.08.2026) =====
   NOWE CZESCI RODZINY, i to jest zdanie uzasadnienia wymagane przez wzorzec: rodzina
   .dropdown__* nie miala nazwy na pudelko stojace JAKO KOLUMNA panelu. .dropdown__icon
   to slot boczny (sama szerokosc), .dropdown__content-box to WIERSZ kolumn - obie opisuja
   co innego. Stad .dropdown__box. */
.dropdown__box { padding: var(--static-space-3x); }
/* KAFEL WYROZNIONY (mockup klienta: "Connect AI"). Ciemna powierzchnia z gradientu rol,
   pierscien wewnetrzny zamiast ramki i tresc w kolumnie. Kafel wypelnia swoja kolumne,
   wiec CTA da sie przypiac do dolu, a kadr animacji przycina jego overflow. */
.dropdown__box--featured { flex: 1; position: relative; overflow: hidden; isolation: isolate; display: flex; flex-direction: column; gap: var(--static-space-2x); border-radius: var(--pui-ui-radius-2xl); background: linear-gradient(180deg, var(--pui-surface-gradient-primary-start) 0%, var(--pui-surface-gradient-primary-end) 100%); box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--static-overlay-light-100); }
.dropdown__box-eyebrow { letter-spacing: 0.1em; text-transform: uppercase; font-weight: 700; font-size: var(--pui-text-p-xs-font-size); color: var(--static-primary-400); }
.dropdown__box-title { font-size: var(--pui-text-h6-font-size); line-height: var(--pui-text-h6-line-height); font-weight: 700; color: var(--static-gray-0); }
.dropdown__box-desc { font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); color: var(--static-overlay-light-900); text-wrap: pretty; }
.dropdown__box-badges { display: flex; flex-wrap: wrap; gap: var(--static-space-1x); }
/* WARIANT FIOLETOWY KAFLA (25.08.2026, zgloszenie zamawiajacego: „musi byc w fioletowych kolorach,
   animacja tez"). Kafel partnerski prowadzi na strone Partners, ktora jest w rodzinie
   fioletowej — kafel zielony przy stronie fioletowej rozjezdza sie z celem, na ktory
   prowadzi.
   NIE MA OSOBNEJ RODZINY KLAS, jest MODYFIKATOR: trzy deklaracje, wszystkie z rol, ktore
   juz w projekcie stoja. Powierzchnia bierze pare `--pui-content-block-illustration-container
   -purple-bg-*` (purple-950 -> purple-700) — to jest rola CIEMNEJ POWIERZCHNI FIOLETOWEJ
   tego projektu, ta sama, ktorej uzywaja bloki tresci na trzech stronach B2B. Rodzina
   `--pui-surface-gradient-purple-*` NIE ISTNIEJE (0 wystapien) i jej nie dorabiam —
   brak zgloszony.
   Wierszyk nad tytulem idzie na ROLE `--pui-text-purple`, nie na stopien skali: kafel ma
   `data-context="on-dark"`, wiec rola rozwiazuje sie sama na wersje jasniejsza. */
.dropdown__box--purple { background: linear-gradient(180deg, var(--pui-content-block-illustration-container-purple-bg-start) 0%, var(--pui-content-block-illustration-container-purple-bg-end) 100%); }
.dropdown__box--purple .dropdown__box-eyebrow { color: var(--pui-text-purple); }
/* Plakietki kafla stoja na poswiacie, wiec potrzebuja rozmycia tla - ta sama rola,
   ktora nosi ikona funkcji na ciemnym tle. */
.dropdown__box-badges .badge { backdrop-filter: blur(var(--pui-ui-blur-sm)); -webkit-backdrop-filter: blur(var(--pui-ui-blur-sm)); }
/* PLAKIETKA PRZY TYTULE POZYCJI ZAWIJA SIE Z TEKSTEM, nie obok niego: w waskiej kolumnie
   pozycja z dluga nazwa i plakietka nie miesci sie w jednej linii, a plakietka trzymana
   w jednym wierszu rozpychala pudelko. Wartosci sa wlasciwoscia MENU, nie plakietki -
   dlatego zasieg idzie po tytule pozycji, a nie po samej klasie .badge. */
/* PLAKIETKA W LINII TEKSTU DOPASOWUJE SIE DO TEKSTU OBOK (zgloszenie zamawiajacego 24.08.2026,
   dwa razy: „za duza ta labelka” przy NI-06 i przy pozycji w szkicu). Rachunek jest jeden
   i opisany w `Opis DS - jezyk wizualny strony.md`: plakietka stojaca W WIERSZU z tekstem
   bierze stopien O DWA nizszy od tekstu obok i wysciolke tak dobrana, zeby jej wysokosc
   nie przekraczala wiersza tego tekstu. Zmierzone przed poprawka: tytul 17 px, plakietka
   13 px i 29 px wysokosci - czyli dokladnie tyle, co caly wiersz tytulu, wiec czytala sie
   jak drugi tytul, a nie jak dopisek. */
.nav-item__title .badge { white-space: normal; text-align: left; font-size: var(--pui-text-p-xxs-font-size); line-height: var(--pui-text-p-xxs-line-height); padding: var(--static-space-0-25x) var(--static-space-0-75x); }
.nav-item__title .badge .badge__text { font-size: inherit; line-height: inherit; }
/* KOLUMNA "ALTERNATIVE TO": to samo pudelko, ale na szarym tle i z gestszymi pozycjami.
   Wysokosc zbijamy GESTOSCIA, nie wyrzucaniem tresci (zgloszenie zamawiajacego 22.08.2026:
   kolumna dyktowala wysokosc calego panelu - 503 px przy sasiadach 371 i 352). */
.dropdown__box--alt { border-radius: var(--pui-ui-radius-2xl); background: var(--static-gray-50); }
.dropdown__box--alt .nav-item__title { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); }
.dropdown__box--alt .nav-item__link { padding-top: var(--static-space-0-5x); padding-bottom: var(--static-space-0-5x); transition: transform 160ms ease, color 160ms ease; }
.dropdown__box--alt .dropdown__content-items { gap: 0; }
/* NAJECHANIE W TEJ KOLUMNIE JEST RUCHEM, NIE OBWIEDNIA (zgloszenie zamawiajacego 22.08.2026:
   "nie podoba mi sie stan hover, ze jest tak blisko krawedzi, moze bez outline, moze
   jakies przesuniecie w prawo i dodatkowo kolor zielony"). Obwiednia w waskiej kolumnie
   stawala 4 px od krawedzi pudelka i czytala sie jak blad wyrownania. */
.dropdown__box--alt .nav-item__link:hover { transform: translateX(6px); }
.dropdown__box--alt .nav-item__link:hover .nav-item__title { color: var(--pui-text-primary); }
/* Strzalka niesie kolor w atrybucie (maska na --pui-text-faded), a styl w atrybucie
   wygrywa z arkuszem - tu !important jest konieczne, nie wygodne. */
.dropdown__box--alt .nav-item__link:hover span[aria-hidden] { background: var(--static-primary-500) !important; }

/* KARTA PROMOCJI pod lista pozycji. Odstep od listy daje LISTA, nie karta: karta bywa
   przypieta do dolu kolumny, wiec wlasnego marginesu gornego miec nie moze.
   ODSTEP CZYTA TE SAMA ROLE CO PRZERWY MIEDZY POZYCJAMI — 26.08.2026, zgloszenie
   zamawiajacego ze zrzutem („odstep pomiedzy boxem panelalpha go i reszta powinien byc taki
   sam jak pomiedzy innymi elementami menu"). Bylo `space-1x` wpisane skala, czyli
   8 px niezaleznie od progu, kiedy pozycje stoja na 16 px — przy karcie GO widac to
   od razu, bo ona zeruje swoj wlasny margines i zostaje sama ta wysciolka. */
.dropdown__content-items:has(+ .dropdown__promo) { padding-bottom: var(--pui-sub-navigation-gap-h); }
/* Karta rowno z OBRYSAMI pozycji, nie z ikonami (zgloszenie zamawiajacego 22.08.2026 ze zrzutem:
   "to ma byc na rowno z borderami menu") - ten sam zwis, ktory ma pudelko pozycji.
   MARGINESU GORNEGO KARTA NIE MA WCALE (26.08.2026): mial `space-1x` i dokladal sie
   do wysciolki listy, czyli byl DRUGIM nosnikiem jednego odstepu — karta zwykla stala
   przez to o 8 px dalej od listy niz karta GO, ktora go zerowala. */
.dropdown__promo { margin-top: 0; margin-left: calc(-1 * var(--pui-sub-navigation-item-padding)); margin-right: calc(-1 * var(--pui-sub-navigation-item-padding)); }
/* GRADIENT KARTY GO STOI TU, NIE W ATRYBUCIE, i to jest naprawa, nie porzadki: skrot
   tla w atrybucie ZERUJE background-clip, wiec gradient malowal sie takze pod przezroczysta
   obwiednia i odstep istnial w pomiarze, a nie na ekranie. */
.dropdown__promo--go { background-image: linear-gradient(93.73deg, var(--static-primary-950) 0%, var(--static-purple-600) 62%, var(--static-purple-400) 100%); }
/* W kolumnie-pudelku karta nie ma sie do czego rownac zwisem - pudelko juz ma wysciolke,
   wiec zwis tylko zjadalby polowe odstepu (zgloszenie zamawiajacego 22.08.2026: "ten element ma
   miec z boku odstepy takie jak na dole"). */
.dropdown__box--alt .dropdown__promo { margin-left: 0; margin-right: 0; background: var(--pui-surface-solid-main); padding: var(--static-space-2x) var(--static-space-3x); }

/* SIATKA POZYCJI W WIERSZACH (panel Features, wersja S8-P). Klasa siatki juz istniala
   (--features), doszly dwie rzeczy zmierzone przy pudelkach: pozycja jest kotwica i musi
   sie rozciagac, a jej pudelko rysuje dziecko - bez wysokosci 100% trzy pudelka w rzedzie
   mialy trzy rozne wysokosci. min-width: 0 na OBU, bo element fleksowy nie schodzi ponizej
   swojej szerokosci min-content i przy wezszym oknie pudelko wchodzilo w sasiednie. */
.dropdown__content-items--features > .nav-item,
.dropdown__content-items--resources > .nav-item { display: flex; min-width: 0; }
.dropdown__content-items--features > .nav-item > .nav-item__link,
.dropdown__content-items--resources > .nav-item > .nav-item__link { flex: 1; min-width: 0; height: 100%; }
/* W komponencie pozycje niesie OSADZENIE, wiec komorka siatki to ono, a `.nav-item` siedzi
   w jego srodku - bez tego pudelko konczy sie na tekscie i rzad ma trzy rozne wysokosci. */
.dropdown__content-items--features > *:not(.nav-item),
.dropdown__content-items--resources > *:not(.nav-item) { display: flex; min-width: 0; }
.dropdown__content-items--features > *:not(.nav-item) > .nav-item,
.dropdown__content-items--resources > *:not(.nav-item) > .nav-item { flex: 1; min-width: 0; display: flex; }
.dropdown__content-items--features > *:not(.nav-item) > .nav-item > .nav-item__link,
.dropdown__content-items--resources > *:not(.nav-item) > .nav-item > .nav-item__link { flex: 1; min-width: 0; height: 100%; }

/* KARTA CASE STUDY: cala karta jest odnosnikiem, wiec najechanie rusza trzy rzeczy naraz -
   zdjecie osoby, welon rozjasniajacy tlo i przycisk, ktory dostaje SWOJ stan z arkusza
   (zgloszenie zamawiajacego 23.08.2026: "jak robie hover na box to od razu hover na button"). */
.dropdown__case-card img { transition: transform 400ms ease; will-change: transform; }
.dropdown__case-card:hover img { transform: scale(1.04); }
.dropdown__case-card:hover .dropdown__case-card-veil { opacity: 1; }
.dropdown__case-card:hover .btn--primary { background-color: var(--pui-button-primary-solid-bg-hover); }
/* Tabliczka z nazwiskiem na zdjeciu: rozmycie 10 px, dokladnie tyle, ile ma
   .team__description-container - ten sam wzorzec podpisu, nie druga wartosc. */
.dropdown__case-card-plate { backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
/* WIERSZ TOZSAMOSCI: rzad na szeroko, slupek na wasko - i to jest PROG, nie zawijanie.
   Zawijanie zostawialo kreske w gornej linii z niczym po prawej, bo zawija sie tylko to,
   co sie nie miesci, a kreska miesci sie zawsze. Kreska jest KRAWEDZIA loga, wiec przy
   zejsciu w slupek schodzi razem z wysciolka. Prog 1200 px jest progiem NAWIGACJI. */
.dropdown__case-card-ident { align-self: flex-start; }
.dropdown__case-card-ident > :first-child + .dropdown__case-card-logo { border-inline-start: var(--pui-ui-border-divider-width) solid var(--static-overlay-light-200); padding-inline-start: var(--static-space-2x); margin-inline-start: var(--static-space-2x); }
@media (max-width: 1199.98px) {
  .dropdown__case-card-ident { flex-direction: column; align-items: flex-start; }
  .dropdown__case-card-ident > :first-child + .dropdown__case-card-logo { border-inline-start: none; padding-inline-start: 0; margin-inline-start: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .dropdown__case-card:hover img { transform: none; }
  .dropdown__box--alt .nav-item__link:hover { transform: none; }
}
.dropdown { position: relative; max-width: 100%; }
.dropdown__content { display: flex; flex-wrap: wrap; align-items: flex-start; flex-direction: column; gap: var(--pui-sub-navigation-sections-gap); width: 100%; }
.dropdown__content > *:last-child { margin-bottom: 0; }
.dropdown__content-group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pui-sub-navigation-section-heading-gap); }
/* JEDNA PRZERWA MIĘDZY PUDEŁKAMI W CAŁYM PANELU — 26.08.2026, polecenie zamawiającego:
   „ujednolic odstepy miedzy boxami w menu, mysle ze tak jak w use cases, najlepiej
   zeby to bylo z jednej zmiennej”.

   CO BYŁO, zmierzone na progu desktopu (pudełko pozycji ZWISA poza swoją komórkę
   o `--pui-sub-navigation-item-padding` z każdej strony, więc przerwa WIDOCZNA to
   przerwa siatki minus dwa zwisy):
     kolumna (Use Cases, For Business)  16 px w pionie   ← wzorzec wskazany przez zamawiającego
     Features                            10 px w poziomie, 5 px w pionie
     Resources                           10 px w poziomie, 10 px w pionie
   Trzy różne przerwy w jednym panelu, każda z innego wyliczenia.

   CO JEST: wszystkie trzy listy biorą JEDNĄ rolę, tę samą, którą miała kolumna
   Use Cases — `--pui-sub-navigation-gap-h`. Nowej roli NIE ZAKŁADAM: druga nazwa
   o tej samej wartości byłaby drugim rozwiązaniem obok istniejącego. Rola jest
   przedefiniowana na progach (16 px desktop i laptop, 8 px tablet), więc przerwa
   zwęża się z oknem — czego skala (`space-2x`) nie robi.

   ZAMIANA NAZW Z KODU ZOSTAJE OPISANA, nie odwrócona: w źródle `column-gap` czytał
   rolę „…-gap-v” (pionową), a `row-gap` rolę „…-gap-h” (poziomą). Po tej zmianie
   obie przerwy czyta jedna rola, więc zamiana nie ma już jak zaboleć, ale ROLA
   `--pui-sub-navigation-gap-v` PRZESTAJE BYĆ CZYTANA przez ten arkusz (była w tych
   czterech deklaracjach i nigdzie więcej) — zostaje w `pa-tokens.css` jako odczyt
   produktu i wchodzi na listę rozjazdów jako rola martwa po naszej stronie. */
.dropdown__content-items { display: flex; flex-direction: column; align-items: flex-start; column-gap: var(--pui-sub-navigation-gap-h); row-gap: var(--pui-sub-navigation-gap-h); }
.dropdown__content-items--features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(3, auto); }
.dropdown__content-items--resources { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: repeat(3, auto); }
/* PRZERWY W SIATKACH LICZONE, NIE WPISANE (przeniesione ze szkicu 24.08.2026, zgloszenie
   zamawiajacego „boxy na siebie nachodza, nie wiem dlaczego?").
   PRZYCZYNA NACHODZENIA, zmierzona: pudelko pozycji ZWISA poza swoja komorke o
   `--pui-sub-navigation-item-padding` (12 px) z kazdej strony - tak stoi w rodzinie
   `.nav-item`, zeby obrys najechania stal rowno z tekstem. Siatka brala przerwe kolumn
   wprost z roli odstepu (10 px), czyli MNIEJ niz dwa zwisy razem (24 px), i sasiednie
   pudelka wchodzily w siebie o 14 px.
   RACHUNEK ZE SZKICU: przerwa kolumn = odstep pozycji + dwa zwisy. Rzedy sa ciasniejsze
   (w szkicu polowa odstepu) - przy tej samej wartosci co kolumny rzedy rozjezdzaly sie
   bardziej niz kolumny.
   `align-items: stretch` zdejmuje druga polowe zgloszenia: bez tego trzy pudelka w rzedzie
   maja trzy rozne wysokosci. */
.dropdown__content-items--features,
.dropdown__content-items--resources {
  align-items: stretch;
  /* Doliczenie dwóch zwisów zostaje — bez niego sąsiednie pudełka nachodzą na
     siebie (zgłoszenie z 24.08). Zmienia się tylko rola, z której liczy. */
  column-gap: calc(var(--pui-sub-navigation-gap-h) + 2 * var(--pui-sub-navigation-item-padding));
  row-gap: var(--pui-sub-navigation-gap-h);
}
/* NAGLOWEK GRUPY po przyjeciu wersji S8 (przeniesione ze szkicu 23.08.2026).
   Zmiany wobec stanu z kodu, wszystkie z decyzji zamawiajacego:
   - pismo: mikro-etykieta (p-xxs, wersaliki, 700, swiatlo miedzyliterowe) zamiast p-sm 600.
     To ona odroznia naglowek grupy od pozycji, nie sama barwa,
   - kreska pod naglowkiem ZDJETA (border-bottom): dzielila kolumne w miejscu, w ktorym
     nic sie nie dzieli. Zostaje sam odstep,
   - naglowek wychodzi poza kolumne o tyle, ile pozycja: inaczej jego tekst stoi 12 px
     w prawo wzgledem tytulow pozycji, bo pudelko pozycji zwisa (RZ: "na rowno z borderami").
   Kreska przed napisem jest OSOBNYM elementem (.dropdown__sub-header-tick), nie
   pseudoelementem: znika razem z nia odstep, gdy grupa jej nie ma. */
.dropdown__sub-header { display: flex; justify-content: flex-start; align-items: center; gap: var(--pui-sub-navigation-item-padding); width: 100%; margin-left: calc(-1 * var(--pui-sub-navigation-item-padding)); margin-right: calc(-1 * var(--pui-sub-navigation-item-padding)); padding: 0 var(--pui-sub-navigation-item-padding) var(--static-space-2x); margin-bottom: var(--static-space-1-5x); color: var(--pui-text-lighter); font-size: var(--pui-text-p-xxs-font-size); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.dropdown__sub-header-tick { flex: none; width: 16px; height: 2px; border-radius: var(--pui-ui-radius-rounded); background: var(--static-primary-500); }
.dropdown__icon { width: 316px; flex-shrink: 0; }
.dropdown__content-row { display: flex; flex-direction: row; gap: var(--pui-sub-navigation-gap-h); width: 100%; }
.dropdown__content-col { display: flex; flex-direction: column; min-width: 0; gap: var(--pui-sub-navigation-social_media-button-column-gap); }
.dropdown__content-box { display: flex; flex-direction: row; gap: var(--pui-sub-navigation-gap-h); flex: 1; }
.dropdown__item { cursor: pointer; }

/* --- pozycja rozwinięcia --------------------------------------------------- */
/* POZYCJA PO PRZEJSCIU ZE SZKICU SUBMENU (23.08.2026, etap "szkic -> klasy"). Zmieniaja sie
   WARTOSCI tej rodziny, nie jej nazwy: rodzine nadaje jeden komponent w calym katalogu,
   wiec zmiana nie wychodzi poza rozwiniecie menu.
   - ikona rowno z pierwsza linia tytulu (flex-start), bo srodkowanie odsuwalo ja od tytulu,
     ktory ma opisywac,
   - pudelko pozycji wychodzi poza kolumne o tyle, ile ma wysciolki: dzieki temu TEKST stoi
     w linii naglowka grupy, a podswietlenie i tak siega dalej niz tekst,
   - promien i przejscie tla naleza do stanu najechania, ktory pozycja ma od 22.08. */
.nav-item__link { display: flex; align-items: flex-start; text-decoration: none; padding: var(--pui-sub-navigation-item-padding); margin: 0 calc(-1 * var(--pui-sub-navigation-item-padding)); border-radius: var(--pui-ui-radius-xl); transition: background-color 160ms ease; }
/* GNIAZDO IKONY: cztery literaly zeszly 23.08.2026 na role. Rozmiar 36 px zamiast 60
   (menu ma byc gestsze), odstep z nowej roli icon-gap, a PODKLADKA ZNIKA - ikon nie
   wrzucamy do pudelek z tlem, a pliki nav-icons maja wlasna podkladke wrysowana w plik,
   wiec promien 10 px dublowal ja. */
.nav-item__icon { display: flex; align-items: center; justify-content: center; width: var(--pui-sub-navigation-item-icon-size); min-width: var(--pui-sub-navigation-item-icon-size); height: var(--pui-sub-navigation-item-icon-size); margin-right: var(--pui-sub-navigation-item-icon-gap); }
.nav-item__content { display: flex; flex-direction: column; gap: var(--pui-sub-navigation-item-heading-gap-v); }
/* STOPIEN TYTULU POZYCJI ZESZEDL O JEDEN (zgloszenie zamawiajacego 24.08.2026 przy kadrze NI-01:
   „zmniejsz rozmiar czcionki na zmienna z 16px rozmiaru”). ZAPIS ROLA, nie liczba - i tu
   jest rozjazd do wiedzenia, bo polecenie mowi o 16 px, a TAKIEJ ROLI DZIS NIE MA:
   po Twojej decyzji z 23.08 („p-lg schodzi o 1 px na kazdym progu") skala niesie 17 (p-lg)
   i 15 (p-base), bez stopnia posredniego. Biore stopien nizszy ze skali, czyli p-base;
   gdyby mialo byc dokladnie 16, to jest zmiana WARTOSCI roli p-base, a ta dotyka calej
   strony, nie samego menu. Interlinia idzie para do stopnia, wersja `-tight` jak dotad. */
.nav-item__title { display: flex; align-items: center; flex-wrap: wrap; font-size: var(--pui-text-p-base-font-size); font-weight: 600; line-height: var(--pui-text-p-base-line-height-tight); letter-spacing: var(--pui-text-p-base-letter-spacing); gap: var(--pui-sub-navigation-item-heading-gap-h); color: var(--pui-text-heading); transition: color 0.2s ease; }
.nav-item__desc { color: var(--pui-text-lighter); font-size: var(--pui-text-p-sm-font-size); font-weight: 300; line-height: var(--pui-text-p-sm-line-height-tight); letter-spacing: var(--pui-text-p-sm-letter-spacing); transition: color 0.2s ease; align-self: center; }
.nav-item--horizontal { width: 100%; }
@media (min-width: 1024px) {
  .nav-item--horizontal .nav-item__title { align-items: flex-start; min-width: var(--pui-sub-navigation-item-horizontal-heading-width); flex-direction: column; gap: var(--pui-sub-navigation-item-heading-gap-v); }
  .nav-item--horizontal .nav-item__content { flex-direction: row; }
}

/* PĘTLA PIĘCIU WARIANTÓW, rozwinięta. W kodzie generuje ją @each po liście
   (primary, purple, orange, blue, red) i ma DWIE gałęzie warunkowe: kolor
   tytułu w spoczynku dostają WYŁĄCZNIE trzy warianty (orange, blue, red),
   a primary i purple nie — ich tytuł zostaje domyślny do czasu hoveru.
   Warunek jest w SCSS-ie, więc w skompilowanym arkuszu widać po nim tylko
   brak dwóch reguł. Obwiednia maską jest wspólna dla wszystkich pięciu
   i czyta jeden koniec z rodziny wariantu, a drugi z roli wspólnej. */
/* ===== STAN POZYCJI: OBWIEDNIA OD STARTU, SWIATLO KRAZACE PO NIEJ NA NAJECHANIU =====
   Przeniesione ze szkicu submenu 23.08.2026 (wersja S8, przyjeta przez zamawiajacego 22.08).
   ZASTEPUJE poprzedni stan tej rodziny: pierscien z gradientu liniowego, zapalany na
   najechaniu, oraz KOLOROWANIE TYTULU I OPISU w wariantach. Kolor pisma zszedl na
   polecenie zamawiajacego ("zadnych kolorowych tytulow w submenu") - wariant niesie odtad wylacznie
   AKCENT SWIATLA, a tytul zawsze stoi na --pui-text-heading.

   Jak to jest zbudowane i dlaczego tak:
   - obwiednia spoczynkowa idzie CIENIEM WEWNETRZNYM, nie borderem: border zmienialby
     szerokosc pudelka i przesuwal tekst o 1 px w chwili najechania,
   - swiatlo to stozkowy gradient obracany katem --pa-ring-ang, przyciety maska do samego
     pierscienia. Obracamy KAT, nie element: obrot elementu obraca tez maske i naroza
     przestaja sie zgadzac,
   - kat jest zarejestrowany przez @property, bo bez tego przegladarka nie umie animowac
     wartosci w gradiencie (interpolacja stoi na typie, nie na nazwie),
   - ::after jest pierscieniem, ::before ta sama rzecza rozmyta i wypuszczona poza pudelko;
     krycie poswiaty 0.55, zeby zielen nie zalewala opisu pozycji,
   - BEZ TRANSITION NA CIENIU: przy przejsciu box-shadow odczyt stanu spoczynku zwraca
     klatke startowa i obwiednia wyglada na nieobecna. Obwiednia jest STANEM, nie animacja. */
@property --pa-ring-ang { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@keyframes pa-ring-spin { to { --pa-ring-ang: 360deg; } }

.nav-item--primary .nav-item__link, .nav-item--purple .nav-item__link, .nav-item--orange .nav-item__link, .nav-item--blue .nav-item__link, .nav-item--red .nav-item__link { position: relative; border-radius: var(--pui-ui-radius-xl); isolation: isolate; box-shadow: inset 0 0 0 var(--pui-ui-border-outline-border-width) var(--static-gray-100); }
.nav-item--primary .nav-item__link::after, .nav-item--purple .nav-item__link::after, .nav-item--orange .nav-item__link::after, .nav-item--blue .nav-item__link::after, .nav-item--red .nav-item__link::after, .nav-item--primary .nav-item__link::before, .nav-item--purple .nav-item__link::before, .nav-item--orange .nav-item__link::before, .nav-item--blue .nav-item__link::before, .nav-item--red .nav-item__link::before { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: var(--pui-ui-border-outline-border-width); background: conic-gradient(from var(--pa-ring-ang), transparent 0deg 200deg, var(--pa-ring-c1) 300deg, var(--pa-ring-c2) 345deg, transparent 360deg); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude; opacity: 0; transition: opacity 200ms ease; pointer-events: none; }
.nav-item--primary .nav-item__link::before, .nav-item--purple .nav-item__link::before, .nav-item--orange .nav-item__link::before, .nav-item--blue .nav-item__link::before, .nav-item--red .nav-item__link::before { inset: -3px; padding: 3px; filter: blur(6px); }
.nav-item--primary .nav-item__link:hover::after, .nav-item--purple .nav-item__link:hover::after, .nav-item--orange .nav-item__link:hover::after, .nav-item--blue .nav-item__link:hover::after, .nav-item--red .nav-item__link:hover::after, .nav-item--primary .nav-item__link:hover::before, .nav-item--purple .nav-item__link:hover::before, .nav-item--orange .nav-item__link:hover::before, .nav-item--blue .nav-item__link:hover::before, .nav-item--red .nav-item__link:hover::before { opacity: 1; animation: pa-ring-spin 2.4s linear infinite; }
.nav-item--primary .nav-item__link:hover::before, .nav-item--purple .nav-item__link:hover::before, .nav-item--orange .nav-item__link:hover::before, .nav-item--blue .nav-item__link:hover::before, .nav-item--red .nav-item__link:hover::before { opacity: 0.55; }

/* AKCENT SWIATLA IDZIE ZA RODZINA POZYCJI, nie za kolumna (zgloszenie zamawiajacego 23.08.2026:
   "hover mial zgadzac sie z kolorem ikonki?"). Dwa stopnie palety, te same numery w kazdej
   rodzinie - poza czerwona, ktora stopnia 300 NIE MA (paleta: 100, 200, 400, 500...),
   wiec bierze 200. Brak stopnia jest w palecie, nie tutaj. */
.nav-item--primary { --pa-ring-c1: var(--static-primary-300); --pa-ring-c2: var(--static-primary-400); }
.nav-item--purple  { --pa-ring-c1: var(--static-purple-300);  --pa-ring-c2: var(--static-purple-400); }
.nav-item--orange  { --pa-ring-c1: var(--static-orange-300);  --pa-ring-c2: var(--static-orange-400); }
/* IKONA IDZIE ZA RODZINA POZYCJI (zgloszenie zamawiajacego 24.08.2026 przy kadrze NI-02:
   \u201ejezlei orange, to tutaj tez ikonka orange\u201d). Dotyczy WYLACZNIE rysunku zastepczego,
   ktory katalog wstawia tam, gdzie nie ma pliku ikony: taki rysunek maluje sie
   `currentColor`, wiec dotad bral kolor pisma i we wszystkich rodzinach byl ten sam.
   Pliki z `assets/nav-icons` maja wlasne barwy wrysowane w plik i tego NIE dotyka. */
.nav-item--primary .nav-item__icon { color: var(--static-primary-500); }
.nav-item--purple .nav-item__icon  { color: var(--static-purple-500); }
.nav-item--orange .nav-item__icon  { color: var(--static-orange-500); }
.nav-item--blue .nav-item__icon    { color: var(--static-blue-500); }
.nav-item--red .nav-item__icon     { color: var(--static-red-500); }
/* NIEBIESKA RODZINA NIE MA STOPNI 200 ANI 300 (paleta: 400, 500, 550, 600, 650, 700),
   wiec swiatlo bierze 400 i 500 - dwa sasiednie stopnie, tak jak w pozostalych rodzinach.
   To NIE JEST podstawienie w miejsce brakujacej wartosci: to jest wybor pary z tego, co
   paleta ma. Brak jasnych stopni w niebieskim zglaszam jako brak w PALECIE, nie tutaj -
   przy jasnym tle swiatlo tej rodziny bedzie ciemniejsze niz w zieleni. Zlapane pomiarem
   23.08.2026, nie okiem: dzis zadna pozycja nie jest niebieska, wiec pusty token nie mial
   jak sie pokazac - a psul cala deklaracje gradientu. */
.nav-item--blue    { --pa-ring-c1: var(--static-blue-400);    --pa-ring-c2: var(--static-blue-500); }
.nav-item--red     { --pa-ring-c1: var(--static-red-200);     --pa-ring-c2: var(--static-red-400); }

/* POZYCJE W KOLUMNIE-PUDELKU NIE MAJA PIERSCIENIA (decyzja zamawiajacego 22.08.2026 o kolumnie
   "Alternative To": "nie chce tego efektu i borderu, prawy sidebar ma byc prostszy").
   Kolumna stoi na szarym pudelku i tego jej wystarcza; obwiednia w pudelku stawalaby
   4 px od jego krawedzi i czytala sie jak blad wyrownania, nie jak stan.
   MIEJSCE TEJ REGULY JEST CZESCIA JEJ DZIALANIA, zmierzone 23.08.2026: ma te sama
   specyficznosc (0,2,0) co regula wariantu, ktora wyjmuje, wiec rozstrzyga KOLEJNOSC.
   Postawiona wyzej w pliku byla martwa - pozycja w Alternative To miala obwiednie mimo
   reguly, ktora ja zdejmowala. Wyjatek stoi ZAWSZE PO regule, z ktorej wyjmuje. */
.dropdown__content-col--box .nav-item__link { box-shadow: none; }
.dropdown__content-col--box .nav-item__link::after, .dropdown__content-col--box .nav-item__link::before { content: none; }

/* STAN AKTYWNY zostaje kolorowy - to jedyne miejsce, w ktorym rodzina maluje pismo.
   Najechanie NIE zmienia juz koloru tytulu ani opisu. */
.nav-item--primary .nav-item__link:active .nav-item__title, .nav-item--primary .nav-item__link.router-link-active .nav-item__title,
.nav-item--purple .nav-item__link:active .nav-item__title, .nav-item--purple .nav-item__link.router-link-active .nav-item__title,
.nav-item--orange .nav-item__link:active .nav-item__title, .nav-item--orange .nav-item__link.router-link-active .nav-item__title,
.nav-item--blue .nav-item__link:active .nav-item__title, .nav-item--blue .nav-item__link.router-link-active .nav-item__title,
.nav-item--red .nav-item__link:active .nav-item__title, .nav-item--red .nav-item__link.router-link-active .nav-item__title { color: var(--pui-text-primary); }

/* --- hamburger ------------------------------------------------------------- */
.burger { position: relative; display: none; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: auto; padding: 0; border: 0; background: transparent; cursor: pointer; }
.burger span { position: absolute; left: calc(50% - 10px); width: 20px; height: 2px; border-radius: 999px; background: var(--pui-text-icon); transition: 0.25s ease-in-out; }
.burger span:nth-child(1) { top: calc(50% - 8px); }
.burger span:nth-child(2) { top: 50%; }
.burger span:nth-child(3) { top: calc(50% + 8px); }
.burger:hover span { background: var(--pui-text-icon-primary); }
.burger.is-open span { background: var(--pui-text-icon-primary); }
.burger.is-open span:nth-child(1) { top: 50%; transform: rotate(135deg); }
.burger.is-open span:nth-child(2) { left: -60px; opacity: 0; }
.burger.is-open span:nth-child(3) { top: 50%; transform: rotate(-135deg); }

/* --- progi ------------------------------------------------------------------ */
@media (max-width: 1479.98px) {
  .dropdown__icon { display: none; }
  .nav__header { display: none; }
  .mob-dropdown-toggle { display: none; }
}
@media (max-width: 1023.98px) {
  .top-bar { display: none; }
  .nav { top: 0; }
  .nav__container { min-height: var(--pui-navigation-height); padding-bottom: var(--pui-navigation-main-padding-top); }
  /* Na tablecie menu przestaje być rzędem i staje się KARTĄ pod paskiem:
     własne tło, obwiednia, cień i przewijanie do wysokości okna minus 140px. */
  .nav__menu { position: absolute; top: calc(100% + 16px); left: var(--pui-navigation-main-padding-h); right: var(--pui-navigation-main-padding-h); z-index: 45; display: block; border-radius: var(--pui-sub-navigation-radius); background: var(--pui-sub-navigation-bg); border: var(--pui-sub-navigation-border-width) solid var(--pui-sub-navigation-border); box-shadow: 0 14px 30px 0 var(--pui-sub-navigation-shadow-black), 0 47px 52px 6px var(--pui-sub-navigation-shadow-green); opacity: 0; visibility: hidden; overflow: hidden; transition: opacity 0.2s ease, visibility 0.2s ease; }
  .nav__menu-inner { max-height: calc(100dvh - 140px); padding: var(--pui-sub-navigation-padding-v) var(--pui-sub-navigation-padding-h); overflow-y: auto; }
  .nav.is-fixed { padding-bottom: 0; }
  .nav.is-open .nav__menu { opacity: 1; visibility: visible; }
  .nav__nav { flex-direction: column; align-items: stretch; margin: 0; }
  .nav__item { width: 100%; }
  .nav__link { justify-content: flex-start; width: 100%; }
  .nav__actions { margin-top: var(--pui-sub-navigation-list-heading-gap); padding-left: 0; }
  .nav__actions > .btn { width: 100%; }
  .nav__brand { margin: 0 auto; }
  .burger { display: inline-flex; margin-left: 0; }
  .nav__dropdown { position: static; transform: none; min-width: 0; width: 100%; margin-top: var(--pui-sub-navigation-list-heading-gap); padding: 0 0; opacity: 1; visibility: visible; display: none; }
  .nav__dropdown.is-open { display: block; }
  /* `flex-direction: column` DOPISANE 24.08.2026 — BRAK Z WŁASNEJ MIGRACJI, nie nowa
     decyzja o wyglądzie. Do 23.08 panel miał w środku JEDNO dziecko (`.dropdown__content`),
     więc kierunek osi wrappera nie miał czego układać i nikt go tu nie deklarował.
     Po przeniesieniu szkicu wrapper trzyma OSOBNE KOLUMNY, a `display: flex` z desktopu
     zostaje w mocy na progu — kolumny stały więc w rzędzie przy oknie węższym niż 1024 px
     i kolumna z linkami zjeżdżała do 68 px (zmierzone przy oknie 924 px: nagłówek grupy
     12 px szerokości, karta klienta 664×1107 px, pionowy pas na całą stronę).
     Trzy modyfikatory kolumn wymienione WPROST, bo komponent wypisuje sam modyfikator
     bez klasy bazowej `.dropdown__content-col` — reguła niżej ich nie wybierała.
     TA SAMA LUKA DZIAŁAŁA W `Navigation.dc.html` od 23.08, więc poprawka zdejmuje ją
     w obu miejscach naraz. */
  .dropdown__wrapper { flex-direction: column; padding: 0; gap: 16px; border-radius: 0; box-shadow: none; }
  /* SIATKA SCHODZI NA PROGU DO JEDNEJ KOLUMNY (24.08.2026, razem z jej dopisaniem wyżej):
     modyfikatory siatki mają WIĘKSZĄ specyficzność niż sam `.dropdown__wrapper`, więc bez
     tej reguły trzy kolumny zostałyby trzema kolumnami na telefonie. */
  .dropdown__wrapper--triple, .dropdown__wrapper--links-box, .dropdown__wrapper--box-links { grid-template-columns: minmax(0, 1fr); }
  .nav-item { min-width: 0; }
  .dropdown__content-group, .dropdown__content-items, .dropdown__content-col { width: 100%; }
  .dropdown__content-col--links, .dropdown__content-col--box, .dropdown__content-col--items { width: 100%; }
  .dropdown__content-items--features, .dropdown__content-items--resources { grid-template-columns: repeat(1, minmax(0, 1fr)); }
  .dropdown__content-items { grid-template-columns: repeat(1, minmax(0, 1fr)) !important; }
  .dropdown__content-col--socials { width: 100% !important; min-width: unset !important; }
  .dropdown__sub-header { padding: 0 0 var(--pui-sub-navigation-section-heading-gap) var(--pui-sub-navigation-list-heading-padding-left); }
  .feature-nav-social__graphic { display: none; }
  .feature-nav-social--left, .feature-nav-social-right { padding-right: var(--pui-sub-navigation-social_media-padding-h); }
}
@media (max-width: 767.98px) {
  .nav-item__icon { align-self: baseline; }
  .nav-item__title { flex-wrap: wrap; }
  .dropdown__content-box, .dropdown__content-row { flex-direction: column; }
  .f-order { order: 1; }
  .has-mob-dropdown { position: relative; }
  .mob-dropdown { position: absolute; top: 100%; right: 0; z-index: 60; display: none; flex-direction: column; }
  .mob-dropdown > .btn { width: auto; border: none; background: none; box-shadow: none; text-align: left; }
  .is-open .mob-dropdown { display: flex; }
  .nav-socials { flex-direction: column; }
  .feature-nav-social--newsletter-nav { order: 1; max-width: unset; }
}

/* --- wejścia i wyjścia rozwinięcia ----------------------------------------- */
@keyframes fadeInRight { from { opacity: 0; transform: translate3d(8px, 0, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } }
@keyframes fadeInLeft { from { opacity: 0; transform: translate3d(-8px, 0, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } }
.fade-in-right { animation: fadeInRight 0.25s both; }
.fade-in-left { animation: fadeInLeft 0.25s both; }

/* --- kafle społecznościowe rozwinięcia -------------------------------------- */
.social-update { display: flex; align-items: center; gap: 8px; }
.social-update__indicator { display: flex; align-items: center; }
.social-update__indicator > svg { position: relative; }
.social-update__indicator > svg .secondary { transform-box: fill-box; transform-origin: center; animation: socialIndicatorPulse 3.2s ease-out infinite; }
/* LITERÓWKA W WARTOŚCI: w kodzie stoi `ar(--pui-text-body)` zamiast `var(…)`,
   więc deklaracja jest NIEPOPRAWNA i przeglądarka ją odrzuca — napis bierze
   kolor po rodzicu. Przepisane bez poprawki (PA-01: identyfikator i zapis
   odwzorowujemy, poprawiamy treść pokazywaną człowiekowi), bo poprawka
   ZMIENIŁABY wygląd produktu. Zgłoszenie idzie na listę rozjazdów. */
.social-update__text { color: ar(--pui-text-body); font-size: var(--pui-text-p-xs-font-size); font-weight: 300; line-height: var(--pui-text-p-xs-line-height); letter-spacing: var(--pui-text-p-xs-letter-spacing, 0); }
/* KLATKOWANIE Z POWTÓRZONYM KLUCZEM: `50%` występuje DWA RAZY (0.3 i 1),
   więc druga deklaracja wygrywa i klatka 0.7 przy 75% jest jedynym powrotem.
   Puls nie wraca do skali 1 tak, jak zapisał to autor. Przepisane 1:1. */
@keyframes socialIndicatorPulse { 0% { transform: scale(1); } 25% { transform: scale(0.7); } 50% { transform: scale(0.3); } 75% { transform: scale(0.7); } 50% { transform: scale(1); } }
.nav-socials { display: flex; gap: var(--pui-sub-navigation-social_media-button-row-gap); }
.social-box { display: flex; position: relative; align-items: center; min-width: var(--pui-sub-navigation-social_media-button-min-width); width: 100%; height: 64px; padding: var(--pui-sub-navigation-social_media-button-padding-v) var(--pui-sub-navigation-social_media-button-padding-h); gap: var(--pui-sub-navigation-social_media-button-gap); border-radius: var(--pui-sub-navigation-social_media-button-radius); background: linear-gradient(180deg, var(--pui-sub-navigation-social_media-button-bg-start) 0%, var(--pui-sub-navigation-social_media-button-bg-end) 100%); overflow: hidden; transition: color .24s ease; }
.social-box::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, var(--pui-sub-navigation-social_media-button-bg-hover-start) 0%, var(--pui-sub-navigation-social_media-button-bg-hover-end) 100%); opacity: 0; transition: opacity .24s ease; pointer-events: none; z-index: 0; }
.social-box > * { position: relative; z-index: 1; }
.social-box:hover::before { opacity: 1; }
.social-box__icon { display: flex; align-items: center; }
.social-box__icon > svg { width: var(--pui-sub-navigation-social_media-button-icon-size); height: var(--pui-sub-navigation-social_media-button-icon-size); }
.social-box__name { color: var(--pui-text-heading); font-size: var(--pui-text-p-sm-font-size); font-weight: 600; line-height: var(--pui-text-p-sm-line-height); letter-spacing: var(--pui-text-p-sm-letter-spacing); }

.feature-nav-social { display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; text-align: center; width: 100%; position: relative; padding: var(--pui-sub-navigation-social_media-padding-v) 0 var(--pui-sub-navigation-social_media-padding-v) var(--pui-sub-navigation-social_media-padding-h); gap: var(--pui-sub-navigation-social_media-gap); align-self: stretch; border-radius: var(--pui-sub-navigation-social_media-radius); transition: 0.2s; flex: 1; }
.feature-nav-social__icon { position: relative; z-index: 2; display: flex; }
/* `visibility: 0` NIE JEST WARTOŚCIĄ tej własności (dozwolone są visible,
   hidden, collapse) — deklaracja jest odrzucana, a ikona chowa się wyłącznie
   przezroczystością z linii obok. Przepisane 1:1. */
.feature-nav-social__link-icon { opacity: 0; visibility: 0; transition: all 0.2s ease; }
.feature-nav-social__body { display: flex; max-width: 100%; gap: var(--pui-sub-navigation-social_media-gap); }
.feature-nav-social__wrapper { display: flex; flex-direction: column; }
.feature-nav-social__title, .feature-nav-social__desc { text-align: left; }
.feature-nav-social__title { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.feature-nav-social__desc { color: var(--pui-text-body); font-weight: 300; margin-top: var(--pui-sub-navigation-social_media-content-gap); }
.feature-nav-social__graphic { display: flex; align-items: center; min-width: 115px; height: 160px; border-radius: 4px 0 0 4px; transform: translateX(5px); transition: all 0.2s ease; position: relative; }
.feature-nav-social__graphic > img { max-height: 100%; max-width: unset; position: absolute; top: 0; left: 0; border-radius: 4px 0 0 4px; }
.feature-nav-social__footer { display: flex; margin-top: var(--pui-sub-navigation-social_media-gap); width: 100%; }
/* Dwie nazwy o tym samym znaczeniu i RÓŻNYM zapisie: `--left` z dwoma
   myślnikami i `-right` z jednym. Druga nie jest modyfikatorem w rozumieniu
   konwencji pliku, a robi to samo. */
.feature-nav-social--left, .feature-nav-social-right { padding-right: 0; }
.feature-nav-social--discord, .feature-nav-social--community { position: relative; overflow: hidden; justify-content: center; }
.feature-nav-social--discord::before, .feature-nav-social--community::before { content: ""; position: absolute; inset: 0; opacity: 0; transition: opacity .24s ease; pointer-events: none; z-index: 0; }
.feature-nav-social--discord .feature-nav-social__body, .feature-nav-social--community .feature-nav-social__body { position: relative; z-index: 1; }
.feature-nav-social--discord:hover::before, .feature-nav-social--community:hover::before { opacity: 1; }
.feature-nav-social--discord:hover .feature-nav-social__link-icon, .feature-nav-social--community:hover .feature-nav-social__link-icon { opacity: 1; visibility: visible; }
/* Kafel przemalowuje PRZYCISK w swojej stopce na stan hoveru — hover kafla
   udaje hover przycisku, którego nikt nie dotknął. */
.feature-nav-social--discord:hover .feature-nav-social__footer .btn.btn--primary, .feature-nav-social--community:hover .feature-nav-social__footer .btn.btn--primary { background: var(--pui-button-primary-solid-bg-hover); }
.feature-nav-social--discord:hover .feature-nav-social__footer .btn.btn--discord, .feature-nav-social--community:hover .feature-nav-social__footer .btn.btn--discord { background: var(--pui-button-discord-solid-bg-hover); }
.feature-nav-social--discord:hover .feature-nav-social__graphic, .feature-nav-social--community:hover .feature-nav-social__graphic { transform: translateX(0px); }
.feature-nav-social--discord { background: linear-gradient(180deg, var(--pui-sub-navigation-social_media-discord-bg-start) 0%, var(--pui-sub-navigation-social_media-discord-bg-end) 100%); }
.feature-nav-social--discord::before { background: linear-gradient(180deg, var(--pui-sub-navigation-social_media-discord-bg-hover-start) 0%, var(--pui-sub-navigation-social_media-discord-bg-hover-end) 100%); }
.feature-nav-social--community { background: linear-gradient(180deg, var(--pui-sub-navigation-social_media-forum-bg-start) 0%, var(--pui-sub-navigation-social_media-forum-bg-end) 100%); }
.feature-nav-social--community::before { background: linear-gradient(180deg, var(--pui-sub-navigation-social_media-forum-bg-hover-start) 0%, var(--pui-sub-navigation-social_media-forum-bg-hover-end) 100%); }

/* --- ui/navigation/CommunityNav.vue + FeatureNewsletterNav.vue --------------
   PRZEPISANE 19.08.2026 przy uzupełnianiu rozwinięcia Community. Oba pliki
   trzymają swój wygląd w `<style scoped>`, więc w skompilowanym arkuszu
   produktu tych reguł NIE MA — to inny nośnik, nie brak w transkrypcji.
   ZAKRES DODANY PO STRONIE KATALOGU, bo w kodzie robi go `scoped`: nazwy
   `.feature__*` i `.dropdown__content-row` mają w repozytorium więcej niż
   jednego czytelnika (pozycja 58 wzorca migracji), więc reguły dostają zakres
   opakowania czytelnika zamiast stać same. Wartości bez zmian. */
.dropdown__content-col--newsletter { flex: 1; min-width: var(--pui-sub-navigation-newsletter-min-width); }
.dropdown__content-col--socials { flex: 1; width: calc((2 * var(--pui-sub-navigation-social_media-min-width)) + var(--pui-sub-navigation-gap-h)); min-width: calc((2 * var(--pui-sub-navigation-social_media-min-width)) + var(--pui-sub-navigation-gap-h)); max-height: fit-content; height: fit-content; }
.dropdown__content-row:has(> .dropdown__content-col--newsletter) { flex-wrap: wrap; }
/* Modyfikator `--newsletter` nie ma w kodzie ANI JEDNEJ własnej deklaracji:
   całość niesie `.feature-nav` w pliku newslettera. Tu zakres idzie po
   modyfikatorze, bo `.feature-nav` samo w sobie nie mówi, o który panel chodzi. */
.feature-nav--newsletter { display: flex; flex-direction: column; flex: 1; padding: var(--pui-sub-navigation-newsletter-padding-v) var(--pui-sub-navigation-newsletter-padding-h); border-radius: var(--pui-sub-navigation-newsletter-radius); background: linear-gradient(180deg, var(--pui-footer-community-newsletter-bg-start) -10.03%, var(--pui-footer-community-newsletter-bg-end) 99.97%); }
.feature-nav--newsletter .feature__container { display: flex; flex-direction: column; align-items: flex-start; gap: var(--pui-sub-navigation-newsletter-gap); flex: 1; }
.feature-nav--newsletter .feature__body { display: flex; flex-direction: column; gap: var(--pui-sub-navigation-newsletter-content-gap); }
.feature-nav--newsletter .feature__title { text-align: left; font-weight: 600; }
.feature-nav--newsletter .feature__desc { text-align: left; font-weight: 300; }
.feature-nav--newsletter .feature__footer { width: 100%; }

/* --- helpers/display.scss + make-responsive: WARIANTY PROGOWE --------------
   Dopisane 12.08.2026 przy nawigacji. Do dziś arkusz katalogu niósł wyłącznie
   warianty BAZOWE rodziny Układu (86 selektorów z 595) — a pomiar przy atomie
   Układu pokazał, że w całym `app/` bazowych używa się ZERO razy, a jedyne
   realne użycia to warianty progowe w MainNav.vue. Katalog mierzył więc tę
   część rodziny, której nikt nie używa, i nie miał tej, która pracuje.
   Dopisuję PIĘĆ selektorów faktycznie wołanych przez nawigację, nie całą
   siatkę 595 — reszta wejdzie razem z rodziną, gdy ktoś jej użyje.
   Znak @ w nazwie klasy wymaga ucieczki w selektorze; w znaczniku stoi wprost. */
@media (max-width: 1023.98px) {
  .d-none\@tablet { display: none !important; }
  .d-block\@tablet { display: block !important; }
}
@media (min-width: 1024px) {
  .d-none\@tablet-up { display: none !important; }
}
@media (max-width: 1479.98px) {
  .d-none\@laptop { display: none !important; }
}
@media (min-width: 1480px) {
  .d-none\@laptop-up { display: none !important; }
}

/* --- assets/css/main.scss — TRZY REGUŁY SĄSIEDZTWA -------------------------
   Odczyt 12.08.2026, przy złożeniu strony głównej. To one dokładają PIERWSZEJ
   sekcji odstęp pod banerem — a nie sekcja i nie baner. Do dziś katalog
   podstawiał je wejściem `afterHeader` na komponencie sekcji, bo sąsiedztwa
   nie da się odczytać z wnętrza komponentu; od 18.08.2026 widok stawia
   prawdziwy <header>, tak jak layout produktu, a rozcięte sąsiedztwo domyka
   NAZWANA kompensacja nośnika w bloku niżej.
   Trzecia reguła (baner z wariantem overlay) nie ma dziś użycia na stronie
   głównej, ale należy do tej samej trójki i wchodzi razem z nimi. */
header + .section { padding-top: var(--pui-section-padding-v); }
header:has(.banner--overlay) + .section { margin-top: var(--pui-overlay-main-gap-negative); padding-top: 0; }
.banner--overlay { padding-bottom: calc(var(--pui-overlay-main-gap-negative) * -1); height: auto !important; }

/* --- KOMPENSACJA NOŚNIKA KATALOGU — sąsiedztwo przez opakowania osadzeń -----
   Katalog wstawia między baner i pierwszą sekcję dwa elementy, których produkt
   nie ma: <div data-screen-label> ekranu przeglądu i div.sc-host osadzenia.
   Sąsiedztwo w CSS liczy się po DRZEWIE, więc para `header + .section` jest
   rozcięta i reguła wyżej nie ma na czym zadziałać. Zmierzone na Onboardingu:
   padding-top 0 px zamiast wartości roli (96 px w kadrze pomiaru z 18.08).
   Po przepięciu, trzy złożenia: 104 px, 104 px, 104 px — wartość roli w kadrze
   pomiaru — i zero stylów w atrybucie na czternastu korzeniach sekcji.

   DO 18.08.2026 PODSTAWIAŁO TO WEJŚCIE `afterHeader`/`afterPrimary` KOMPONENTU
   SEKCJI, czyli styl w atrybucie na korzeniu. Jedna reguła kodu miała wtedy dwa
   nośniki, a drugi trzeba było podać ręką przy każdym osadzeniu — sekcja funkcji
   Onboardingu stanęła bez odstępu właśnie dlatego, że nie został podany.
   Kompensacja stoi więc w arkuszu, nazwana i w najwęższym zakresie: wyłącznie
   sekcja będąca dzieckiem SĄSIADUJĄCEGO ekranu przeglądu, jedno albo dwa
   gniazda w głąb (drugie gniazdo ma Collaborate, które osadza sekcję u siebie).

   GŁĘBOKOŚĆ TRZEBA LICZYĆ PO OBU STRONACH PARY, nie tylko po tej, którą się
   maluje (dopisane 20.08.2026 przeglądem strony O nas). Pierwsze brzmienie
   dopuszczało dwa gniazda w sekcji NASTĘPNEJ i jedno w POPRZEDZAJĄCEJ, więc
   ekran, który sam osadza sekcję dwa gniazda w głąb, przestawał być rozpoznawany
   jako primary. Zmierzone: sekcja społeczności po sekcji lokalizacji miała
   padding-top 0 px zamiast 104 px, przy poprawnie działającej regule wyżej. */
header + [data-screen-label] > .sc-host > .section,
header + [data-screen-label] > .sc-host > .sc-host > .section,
[data-screen-label]:has(> .sc-host > .section--primary, > .sc-host > .sc-host > .section--primary) + [data-screen-label] > .sc-host > .section,
[data-screen-label]:has(> .sc-host > .section--primary, > .sc-host > .sc-host > .section--primary) + [data-screen-label] > .sc-host > .sc-host > .section {
  padding-top: var(--pui-section-padding-v);
}

/* DRUGA GALAZ TEJ SAMEJ KOMPENSACJI — baner NAKLADKOWY (19.08.2026, RM-05).
   Kompensacja wyzej przepisala z trojki main.scss regule PIERWSZA i tylko ja.
   Przy banerze z wariantem overlay kod idzie druga galezia: sekcja dostaje
   UJEMNY margines i zerowana wyscolke, bo baner ma o tyle samo wieksza wyscolke
   dolna i sekcja ma w nia wejsc. Bez tej galezi obie wartosci dzialaja przeciw
   sobie. Zmierzone na Roadmapie 19.08: wyscolka dolna banera 252 px ZASTOSOWANA,
   margines sekcji 0 px zamiast -252 px, wyscolka 96 px zamiast zera — rama planu
   stala 348 px PONIZEJ banera zamiast 252 px w jego wnetrzu, czyli 600 px obok.
   Zakres jak wyzej: wylacznie sekcja bedaca dzieckiem SASIADUJACEGO ekranu
   przegladu, jedno albo dwa gniazda w glab. */
header:has(.banner--overlay) + [data-screen-label] > .sc-host > .section,
header:has(.banner--overlay) + [data-screen-label] > .sc-host > .sc-host > .section {
  margin-top: var(--pui-overlay-main-gap-negative);
  padding-top: 0;
}


/* =============================================================================
   RAMA MAŁEJ ILUSTRACJI I JEJ TREŚĆ — odczyt 18.08.2026, commit 1bcf0cc.
   Pliki: ui/content/FeatureIllustrationSm.vue (blok scoped), reguła BAZOWA
   .instance-box z assets/css/elements/old-feature.scss oraz cztery pliki
   features/optimized-customer-onboarding/*.vue (bloki scoped).
   NAZWY KLAS BEZ ZMIAN.

   RZ-24 zostaje prawdą tej rodziny: reguła bazowa ramy wszystkich 83 ilustracji
   stoi w pliku z przedrostkiem „old" wciąż wczytywanym przez arkusz główny,
   a cztery z pięciu kolorów obwiedni nie istnieją w palette/main.scss. Wartości
   idą przez role --src-instance-*, które katalog nadał tym literałom przy
   stronie ramy (07.08) — jeden nośnik, nie dwa.

   ZAWĘŻENIE NAZWANE: cztery pliki ilustracji definiują TE SAME nazwy
   (.instance-box--1 … --6) z różnymi wartościami. W produkcie rozdziela je
   atrybut scoped Vue; w płaskim arkuszu nie ma go czym zastąpić, więc każdy
   blok jest zawężony atrybutem [data-illu="<nazwa pliku>"] stawianym przez
   stronę goszczącą na elemencie .graphic--sm. To kompensacja nośnika, nie
   reguła systemu: w kodzie tych selektorów nie ma.
   ============================================================================= */

/* --- elements/old-feature.scss (reguła bazowa) ----------------------------- */
.instance-box {
  position: absolute;
  box-shadow: var(--src-instance-shadow);
  background: var(--src-instance-bg);
  border-radius: var(--src-instance-radius);
  overflow: hidden;
  line-height: var(--src-instance-line-height);
}
/* W kodzie stoją tu DWIE deklaracje position pod rząd (relative, potem
   absolute) — wygrywa późniejsza. Zapisane jak w pliku, bo to znalezisko. */
.instance-wrapper { position: relative; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }

/* --- ui/content/FeatureIllustrationSm.vue ---------------------------------- */
.graphic--sm { position: relative; width: 100%; height: 100%; max-width: var(--src-instance-max-size); max-height: var(--src-instance-max-size); aspect-ratio: 1; }
@media (max-width: 1023.98px) { .graphic--sm { max-width: var(--src-instance-max-size-tablet); } }
@media (max-width: 767.98px) { .graphic--sm { max-width: var(--pui-content-block-illustration-container-default-slot-max-size); } }
.graphic--sm .instance-box img { width: 100%; height: auto; display: block; }
.graphic--sm .instance-box--light { box-shadow: var(--src-instance-shadow-light); }
.graphic--sm .instance-box--light-sides { box-shadow: var(--src-instance-shadow-light-sides); }
.graphic--sm .instance-box--blur { filter: blur(var(--src-instance-blur)); }
.graphic--sm .instance-box--border { border: var(--src-instance-border-width) solid var(--src-instance-border); }
.graphic--sm .instance-box--border-lg { border-width: var(--src-instance-border-width-lg); }
.graphic--sm .instance-box--border-red { border-color: var(--src-instance-border-red); }
.graphic--sm .instance-box--border-purple { border-color: var(--src-instance-border-purple); }
.graphic--sm .instance-box--border-orange { border-color: var(--src-instance-border-orange); }
.graphic--sm .instance-box--border-gray { border-color: var(--src-instance-border-gray); }
.graphic--sm .instance-box--border-radius-lg { border-radius: var(--src-instance-radius-lg); }
.graphic--sm .instance-box--no-shadow { box-shadow: unset; }
.graphic--sm .instance-box--no-background { background: unset; }
.graphic--sm .instance-box--avatar { border-radius: 50%; border: var(--src-instance-border-width-lg) solid var(--src-instance-avatar-border); }
.graphic--sm .instance-box--no-radius { border-radius: unset; }
.graphic--sm .instance-box--overflow-visible { overflow: visible; }

/* --- features/optimized-customer-onboarding/OneClickSiteCreation.vue ------- */
[data-illu="one-click-site-creation"] .instance-box--1 { left: 4%; top: 3%; width: 33%; z-index: 1; }
[data-illu="one-click-site-creation"] .instance-box--2 { right: 3%; top: 2%; width: 39%; z-index: 1; }
[data-illu="one-click-site-creation"] .instance-box--3 { top: 18%; height: 56.6%; left: 18%; width: 79%; z-index: 3; }
[data-illu="one-click-site-creation"] .instance-box--3 video { width: 100%; height: 100%; object-fit: cover; }
[data-illu="one-click-site-creation"] .instance-box--3 .video-background { display: flex; align-items: center; justify-content: center; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: linear-gradient(180deg, rgba(15, 130, 80, 0) 0.06%, rgba(15, 130, 80, 0.6) 95.8%); }
[data-illu="one-click-site-creation"] .instance-box--3 .video-background__icon { display: contents; }
[data-illu="one-click-site-creation"] .instance-box--3 .video-background svg { width: 22.3%; height: 33%; transition: all 0.24s ease; fill: white; }
[data-illu="one-click-site-creation"] .instance-box--3 .video-background:hover svg { fill: #07c07e; }
[data-illu="one-click-site-creation"] .instance-box--4 { bottom: 7%; left: 3.5%; width: 21.5%; height: 21.4%; z-index: 3; }
[data-illu="one-click-site-creation"] .instance-box--4 svg { max-width: 100%; max-height: 100%; }
[data-illu="one-click-site-creation"] .instance-box--5 { right: 13.6%; bottom: 16.7%; width: 70%; height: 9%; overflow: unset; }
[data-illu="one-click-site-creation"] .instance-box--5 svg { width: 100%; height: auto; }
[data-illu="one-click-site-creation"] .instance-box--5 .animation-pulse { bottom: -2px; right: 37%; background: #ff1010; }
[data-illu="one-click-site-creation"] .instance-box--5 .animation-pulse::before { background-color: rgba(255, 16, 16, 0.1); }
[data-illu="one-click-site-creation"] .instance-box--6 { left: 12%; top: 50%; height: 27.7%; width: 10%; overflow: unset; }
[data-illu="one-click-site-creation"] .instance-box--6 svg { width: 100%; height: auto; }
[data-illu="one-click-site-creation"] .instance-box--6 .animation-pulse { top: 38.3%; left: -3px; background: #ff1010; }
[data-illu="one-click-site-creation"] .instance-box--6 .animation-pulse::before { background-color: rgba(255, 16, 16, 0.1); }

/* --- features/optimized-customer-onboarding/SuperQuickOnboarding.vue ------- */
[data-illu="super-quick-onboarding"] .instance-box--1 { left: 7.7%; top: 14.2%; width: 73.1%; z-index: 1; }
[data-illu="super-quick-onboarding"] .instance-box--2 { right: 4.4%; top: 3.7%; width: 51.1%; z-index: 1; }
[data-illu="super-quick-onboarding"] .instance-box--3 { right: 2.8%; bottom: 9.4%; width: 21.4%; z-index: 1; }
[data-illu="super-quick-onboarding"] .instance-box--4 { left: 3%; bottom: 14.6%; width: 46.9%; z-index: 1; }
[data-illu="super-quick-onboarding"] .instance-box--5 { left: 26.7%; bottom: 4.2%; width: 60%; }
[data-illu="super-quick-onboarding"] .instance-box--5 svg { width: 100%; height: 100%; }
[data-illu="super-quick-onboarding"] .instance-box--6 { right: 12.5%; top: 21.4%; width: 5px; height: 48%; }
[data-illu="super-quick-onboarding"] .instance-box--6 svg { height: 100%; }

/* --- features/optimized-customer-onboarding/QuickOnboarding.vue ------------ */
[data-illu="quick-onboarding"] .instance-box--1 { left: 9.2%; top: 13.6%; width: 16.2%; }
[data-illu="quick-onboarding"] .instance-box--2 { right: 0px; top: 8.1%; width: 70.8%; }
[data-illu="quick-onboarding"] .instance-box--3 { right: 0px; bottom: 7.3%; width: 43.1%; }
[data-illu="quick-onboarding"] .instance-box--4 { left: 0px; bottom: 13.6%; width: 53.3%; }

/* --- features/optimized-customer-onboarding/ClassicOnboarding.vue ---------- */
[data-illu="classic-onboarding"] .instance-box--1 { left: 1px; top: 9.2%; width: 57.9%; }
[data-illu="classic-onboarding"] .instance-box--2 { left: 14.9%; bottom: 19.3%; width: 10.7%; }
[data-illu="classic-onboarding"] .instance-box--3 { right: 5.9%; bottom: 9.2%; width: 64.2%; }

/* --- features/collaboration-environment/SimpleSharing.vue ------------------ */
[data-illu="simple-sharing"] .instance-box--1 { right: 3.6%; top: 11%; width: 87.7%; }
[data-illu="simple-sharing"] .instance-box--2 { right: 0px; bottom: 4%; width: 42%; }
[data-illu="simple-sharing"] .instance-box--3 { right: 0px; top: 9.2%; width: 45%; }

/* --- features/collaboration-environment/FlexiblePriveleges.vue -------------
   Nazwa pliku ma w repozytorium literówkę („Priveleges"); atrybut zakresu idzie
   od nazwy KLASY układu w kodzie, nie od nazwy pliku, więc brzmi poprawnie.
   Czwarte pudełko ma `background: transparent` W BLOKU POŁOŻENIA, a nie przez
   modyfikator --no-background, choć taki modyfikator w rodzinie istnieje. */
[data-illu="flexible-privileges"] .instance-box--1 { left: 0px; top: 6%; width: 58.2%; }
[data-illu="flexible-privileges"] .instance-box--2 { right: 12.1%; top: 23.6%; width: 33.7%; }
[data-illu="flexible-privileges"] .instance-box--3 { right: 10.1%; bottom: 27.1%; width: 37.8%; }
[data-illu="flexible-privileges"] .instance-box--4 { right: 26%; top: 64.2%; width: 6%; background: transparent; }

/* --- features/collaboration-environment/FullControl.vue --------------------
   TRZY RZECZY, KTÓRYCH NIE MA W ŻADNEJ INNEJ ILUSTRACJI TEJ RAMY, i wszystkie
   trzy są w kodzie:
   1. blok scoped otwiera się od `.graphic` i NADPISUJE ramę: display flex
      zamiast siatki z FeatureIllustrationSm.vue. Zapisane jako nadpisanie
      gospodarza, dlatego selektor niesie oba zakresy naraz;
   2. pięć pudełek stoi wprost w ramie, a pięć następnych w `.instance-wrapper`,
      który ma własne położenie (nth-child odd/even) i trzy progi na odstępie;
   3. reguły pudełek 1-5 są pisane od `.graphic > .instance-box`, czyli DZIECKA
      bezpośredniego — pudełka w opakowaniu ich nie dostają, i to jest cała
      różnica między pierwszą piątką a drugą. */
[data-illu="full-control"] { display: flex; align-items: center; justify-content: center; }
[data-illu="full-control"] > .instance-box--1 { right: 6%; top: 20.2%; width: 31.5%; }
[data-illu="full-control"] > .instance-box--2 { left: 30px; top: 35.4%; width: 31.5%; }
[data-illu="full-control"] > .instance-box--3 { right: 0px; top: 51.8%; width: 31.5%; }
[data-illu="full-control"] > .instance-box--4 { left: 0px; top: 56%; width: 31.5%; }
[data-illu="full-control"] > .instance-box--5 { right: 8px; bottom: 15.3%; width: 31.5%; }
[data-illu="full-control"] > .instance-box--6 { left: 17.9%; top: 46px; }
[data-illu="full-control"] > .instance-box--7,
[data-illu="full-control"] > .instance-box--8,
[data-illu="full-control"] > .instance-box--9,
[data-illu="full-control"] > .instance-box--10 { right: 6%; top: 20.2%; }
[data-illu="full-control"] .instance-wrapper { width: 100%; }
[data-illu="full-control"] .instance-wrapper .instance-box { position: relative; width: 63.4%; }
[data-illu="full-control"] .instance-wrapper .instance-box + .instance-box { margin-top: 23px; }
[data-illu="full-control"] .instance-wrapper .instance-box:nth-child(odd) { left: 17.9%; }
[data-illu="full-control"] .instance-wrapper .instance-box:nth-child(even) { left: 25.2%; }
/* Trzy progi opakowania, wszystkie z bloku scoped tego pliku. Rodzina progów
   działa w dół, a te trzy NIE pokrywają się z progami reszty katalogu
   (1199.98 / 991.98 / 575.98 wobec 1023.98 / 767.98) — czwarty rozjazd nazw
   progów w repozytorium, przepisany jak stoi. */
@media (max-width: 1199.98px) {
  [data-illu="full-control"] .instance-wrapper .instance-box + .instance-box { margin-top: 16px; }
}
@media (max-width: 991.98px) {
  [data-illu="full-control"] .instance-wrapper .instance-box:nth-child(odd) { left: 15%; }
  [data-illu="full-control"] .instance-wrapper .instance-box:nth-child(even) { left: 25.3%; }
}
@media (max-width: 575.98px) {
  [data-illu="full-control"] .instance-wrapper .instance-box + .instance-box { margin-top: 10px; }
}

/* --- features/banners/OptimizedCustomerBanner.vue (blok scoped, :deep) -----
   Dwie reguły wywołania, nie komponentu: bez nich obie małe warstwy stoją
   w lewym dolnym rogu, bo reguła bazowa daje im tylko bottom: 0. Zawężone
   atrybutem [data-banner] z tego samego powodu co bloki ilustracji wyżej. */
[data-banner="optimized-customer"] .banner__illustration-layer--left-bottom { left: 8.48%; z-index: 2; }
[data-banner="optimized-customer"] .banner__illustration-layer--left-bottom img { width: 274px; }
[data-banner="optimized-customer"] .banner__illustration-layer--right-bottom { left: 72.30%; z-index: 2; }
[data-banner="optimized-customer"] .banner__illustration-layer--right-bottom img { width: 260px; }

/* --- features/next-level-client-panel/SuitableForSmallCustomers.vue --------- */
[data-illu="suitable-for-small-customers"] .instance-box--1 { right: 6.2%; bottom: 8.3%; width: 63.8%; }
[data-illu="suitable-for-small-customers"] .instance-box--2 { right: 2%; top: 11.6%; width: 63.7%; }
[data-illu="suitable-for-small-customers"] .instance-box--3 { right: 0; bottom: 27.8%; width: 11.07%; }
[data-illu="suitable-for-small-customers"] .instance-box--4 { left: 17.1%; top: 20.4%; width: 11.07%; }
[data-illu="suitable-for-small-customers"] .instance-box--5 { left: 9.2%; bottom: 13.1%; width: 76.9%; }

/* --- features/next-level-client-panel/Whitelabel.vue ----------------------- */
[data-illu="whitelabel"] .instance-box--1 { left: 2.7%; top: 15.1%; width: 40.2%; }
[data-illu="whitelabel"] .instance-box--2 { right: 4.6%; top: 50%; width: 40.2%; }
[data-illu="whitelabel"] .instance-box--3 { right: 26.9%; top: 29.3%; width: 37.6%; }
[data-illu="whitelabel"] .instance-box--4 { left: 31.7%; bottom: 5.5%; width: 34%; }
[data-illu="whitelabel"] .instance-box--5 { right: 13.8%; top: 8.8%; width: 37.4%; }
[data-illu="whitelabel"] .instance-box--6 { left: 36.7%; bottom: 34.7%; width: 12.7%; }

/* --- features/next-level-client-panel/TwoFactorAuthentication.vue ---------- */
[data-illu="twofactor-authentication"] .instance-box--1 { right: 0px; top: 12%; width: 31%; }
[data-illu="twofactor-authentication"] .instance-box--2 { right: 2.2%; bottom: 6.2%; width: 54.8%; }
[data-illu="twofactor-authentication"] .instance-box--3 { left: 8.1%; top: 12%; width: 57.2%; }

/* --- features/banners/CollaborationEnvironmentBanner.vue (blok scoped, :deep)
   Odczyt 18.08.2026. Cztery warstwy poboczne, każda z własnym położeniem
   w bloku wywołania — ta sama klasa rozjazdu co RZ-87: komponent banera nie ma
   dla położenia warstw ANI JEDNEGO wejścia, więc każde wywołanie dopisuje
   własny blok :deep(). Zawężone atrybutem [data-banner] z tego samego powodu
   co bloki ilustracji: kompensacja nośnika, w kodzie tych selektorów nie ma.
   DWIE RZECZY OSOBNE DLA TEGO WYWOŁANIA: warstwy poboczne mają z-index -1
   (u onboardingu 2), a dwie warstwy wektorowe (user-left, user-right) stoją
   w położeniach PIKSELOWYCH, nie procentowych. */
[data-banner="collaboration-environment"] .banner__illustration-layer--left-bottom { left: 140px; z-index: -1; }
[data-banner="collaboration-environment"] .banner__illustration-layer--left-bottom img { width: 462px; height: auto; }
[data-banner="collaboration-environment"] .banner__illustration-layer--right-bottom { top: 36.25%; left: 72.30%; z-index: -1; }
[data-banner="collaboration-environment"] .banner__illustration-layer--right-bottom img { width: 260px; height: auto; }
[data-banner="collaboration-environment"] .banner__illustration-layer--user-left { top: 96px; left: 197px; }
[data-banner="collaboration-environment"] .banner__illustration-layer--user-right { top: 68px; left: 1085px; }

/* --- features/banners/NextLevelClientPanelBanner.vue (blok scoped, :deep) ---
   Odczyt 18.08.2026. Trzy warstwy poboczne, wszystkie RASTROWE, i trzeci już
   zestaw położeń tej samej rodziny (RZ-87). Warstwa left-top ma tu klucz,
   którego nie ma żadne inne wywołanie: modyfikator --left-top powstaje z klucza,
   więc reguła bazowa daje mu tylko `position: absolute` z rodziny warstw. */
[data-banner="next-level-control-panel"] .banner__illustration-layer--left-bottom { left: 169.5px; z-index: -1; }
[data-banner="next-level-control-panel"] .banner__illustration-layer--left-bottom img { width: 283px; }
[data-banner="next-level-control-panel"] .banner__illustration-layer--left-top { top: 100px; left: 200px; z-index: 2; }
[data-banner="next-level-control-panel"] .banner__illustration-layer--left-top img { width: 216px; }
[data-banner="next-level-control-panel"] .banner__illustration-layer--right-bottom { left: 1005px; z-index: 2; }
[data-banner="next-level-control-panel"] .banner__illustration-layer--right-bottom img { width: 218px; }

/* --- features/developer-toolkit/StagingEnvironment.vue ---------------------
   Dwa z trzech pudełek trzymają IKONĘ SVG, nie zrzut, i mają w bloku scoped
   regułę :deep(svg) — przepisaną jako selektor potomka, bo zasięg jest ten sam.
   Pudełko 1 ma w kodzie z-index ZAKOMENTOWANY; nie przepisuję komentarzy, ale
   liczę je jako znalezisko: to samo miejsce ma je w CacheControl.vue. */
[data-illu="staging-environment"] .instance-box--1 { right: 10px; top: 17.1%; width: 83.7%; }
[data-illu="staging-environment"] .instance-box--2 { right: 22.5%; top: 13.4%; width: 17.9%; }
[data-illu="staging-environment"] .instance-box--2 svg { width: 100%; height: 100%; }
[data-illu="staging-environment"] .instance-box--3 { right: 44.4%; top: 8.4%; width: 10.1%; display: flex; }
[data-illu="staging-environment"] .instance-box--3 svg { width: 100%; height: 100%; }

/* --- features/developer-toolkit/CacheControl.vue --------------------------- */
[data-illu="cache-control"] .instance-box--1 { left: 17%; top: 11.6%; width: 31%; }
[data-illu="cache-control"] .instance-box--2 { right: 17px; top: 26.7%; width: 45.7%; }
[data-illu="cache-control"] .instance-box--3 { left: 4%; bottom: 10.5%; width: 43.8%; }

/* --- features/developer-toolkit/WordpressConfiguration.vue ----------------- */
[data-illu="wordpress-configuration"] .instance-box--1 { left: 2.9%; bottom: 11.4%; width: 50.5%; z-index: 1; }
[data-illu="wordpress-configuration"] .instance-box--2 { right: 0; top: 8.48%; width: 78.3%; }
[data-illu="wordpress-configuration"] .instance-box--3 { right: 5.3%; bottom: 15.86%; width: 38.4%; }

/* --- features/developer-toolkit/AutomatedUpgrades.vue ---------------------- */
[data-illu="automated-upgrades"] .instance-box--1 { left: 4.2%; top: 16.2%; width: 60.5%; }
[data-illu="automated-upgrades"] .instance-box--2 { right: 13.2%; top: 40%; width: 60.15%; }
[data-illu="automated-upgrades"] .instance-box--3 { left: 4.2%; bottom: 11.2%; width: 60.6%; }
[data-illu="automated-upgrades"] .instance-box--4 { right: 20.8%; top: 25.2%; width: 11.07%; height: 11.07%; }
[data-illu="automated-upgrades"] .instance-box--5 { left: 11.8%; top: 48.7%; width: 11.07%; height: 11.07%; }
[data-illu="automated-upgrades"] .instance-box--6 { right: 20.8%; bottom: 17%; width: 11.07%; height: 11.07%; }
[data-illu="automated-upgrades"] .instance-box--4 svg,
[data-illu="automated-upgrades"] .instance-box--5 svg,
[data-illu="automated-upgrades"] .instance-box--6 svg { width: 100%; height: 100%; }

/* --- features/developer-toolkit/DebugMaintenanceMode.vue ------------------- */
[data-illu="debug-and-maintenance-mode"] .instance-box--1 { left: 0px; bottom: 9.5%; width: 53.7%; }
[data-illu="debug-and-maintenance-mode"] .instance-box--2 { right: 0px; top: 11.2%; width: 53.7%; z-index: 1; }
[data-illu="debug-and-maintenance-mode"] .instance-box--3 { left: 23%; top: 22.1%; width: 30.4%; z-index: 2; }

/* --- features/developer-toolkit/InstanceLogs.vue --------------------------- */
[data-illu="instance-logs"] .instance-box--1 { left: 0px; top: 4.4%; width: 95.5%; }
[data-illu="instance-logs"] .instance-box--2 { right: 24%; bottom: 3.7%; width: 37.7%; }

/* --- features/billing-integration/* (siedem bloków) -------------------------
   Odczyt 18.08.2026. Siedem plików, 27 pudełek, wszystkie rastrowe. Cztery
   pliki mają WŁASNE progi na pudełkach o szerokości 11,07% (41 px i 26 px),
   czyli tę samą obcą rodzinę liczb co reszta rodziny (1199.98 / 575.98).
   Dwa pliki dokładają CIEŃ FILTREM na obrazku, czego nie robi żadna inna
   ilustracja w katalogu — drop-shadow zamiast box-shadow pudełka. */
[data-illu="bi-single-wordpress-instance"] .instance-box--1 { right: 17%; top: 10%; width: 45%; }
[data-illu="bi-single-wordpress-instance"] .instance-box--2 { left: 24%; bottom: 15.3%; width: 51.1%; }
[data-illu="bi-single-wordpress-instance"] .instance-box--3 { right: 11.4%; top: 38.2%; width: 11.07%; }
[data-illu="bi-single-wordpress-instance"] .instance-box--4 { right: 11.4%; top: 53%; width: 11.07%; }
[data-illu="bi-single-wordpress-instance"] .instance-box--5 { right: 11.4%; top: 67.7%; width: 11.07%; }
@media (max-width: 1199.98px) {
  [data-illu="bi-single-wordpress-instance"] .instance-box--3,
  [data-illu="bi-single-wordpress-instance"] .instance-box--4,
  [data-illu="bi-single-wordpress-instance"] .instance-box--5 { width: 41px; }
}
@media (max-width: 575.98px) {
  [data-illu="bi-single-wordpress-instance"] .instance-box--3,
  [data-illu="bi-single-wordpress-instance"] .instance-box--4,
  [data-illu="bi-single-wordpress-instance"] .instance-box--5 { width: 26px; border-radius: 5px; }
}

[data-illu="bi-service-with-multiple-wordpress"] .instance-box--1 { left: 6.4%; top: 11.8%; width: 31%; }
[data-illu="bi-service-with-multiple-wordpress"] .instance-box--2 { left: 14.5%; bottom: 23.6%; width: 31%; }
[data-illu="bi-service-with-multiple-wordpress"] .instance-box--3 { right: 29%; top: 20.4%; width: 31%; z-index: 1; }
[data-illu="bi-service-with-multiple-wordpress"] .instance-box--4 { right: 13.8%; bottom: 35.8%; width: 38.4%; }
[data-illu="bi-service-with-multiple-wordpress"] .instance-box--5 { right: 6.4%; bottom: 17.5%; width: 38.3%; }

[data-illu="bi-upselling-paid-plugins-or-themes"] .instance-box--1 { left: 1.6%; top: 20%; width: 48.3%; }
[data-illu="bi-upselling-paid-plugins-or-themes"] .instance-box--2 { right: 0; top: 8%; width: 46.5%; }
[data-illu="bi-upselling-paid-plugins-or-themes"] .instance-box--3 { left: 1.6%; bottom: 2.4%; width: 48.3%; overflow: visible; }
[data-illu="bi-upselling-paid-plugins-or-themes"] .instance-box--3 img { filter: drop-shadow(0px -5px 43px rgba(0, 0, 0, 0.03)) drop-shadow(0px 6px 15px rgba(1, 69, 45, 0.06)); }

[data-illu="bi-upgrading-plan"] .instance-box--1 { left: 0; bottom: 11.6%; width: 93.8%; }
[data-illu="bi-upgrading-plan"] .instance-box--2 { right: 18.2%; top: 2.6%; width: 49.5%; }
[data-illu="bi-upgrading-plan"] .instance-box--3 { left: 13.1%; top: 23.8%; width: 11.07%; }
@media (max-width: 1199.98px) { [data-illu="bi-upgrading-plan"] .instance-box--3 { width: 41px; } }
@media (max-width: 575.98px) { [data-illu="bi-upgrading-plan"] .instance-box--3 { width: 26px; border-radius: 4px; } }

[data-illu="bi-upselling-domain"] .instance-box--1 { right: 7.7%; bottom: 14.2%; width: 69.7%; }
[data-illu="bi-upselling-domain"] .instance-box--2 { left: 7.7%; bottom: 24.9%; width: 11.07%; }
[data-illu="bi-upselling-domain"] .instance-box--3 { right: 26.3%; top: 11.8%; width: 11.07%; }
@media (max-width: 1199.98px) { [data-illu="bi-upselling-domain"] .instance-box--2 { width: 41px; } }
@media (max-width: 575.98px) { [data-illu="bi-upselling-domain"] .instance-box--2 { width: 26px; border-radius: 5px; } }

/* WHMCSModule.vue — pudełko pierwsze ZDEJMUJE tło i promień w bloku położeń,
   choć rodzina ma na to modyfikatory --no-background i --no-radius. */
[data-illu="bi-whmcs-module"] .instance-box--1 { left: 9%; top: 20.4%; width: 69.9%; background: transparent; border-radius: unset; }
[data-illu="bi-whmcs-module"] .instance-box--2 { left: 28.6%; bottom: 19.4%; width: 42.8%; overflow: visible; }
[data-illu="bi-whmcs-module"] .instance-box--2 img { filter: drop-shadow(0px 47px 52px rgba(5, 109, 72, 0.07)) drop-shadow(0px 14px 30px rgba(0, 0, 0, 0.09)); }
[data-illu="bi-whmcs-module"] .instance-box--3 { left: 42.2%; top: 40%; width: 4.3%; }

[data-illu="bi-api"] .instance-box--1 { left: 5.3%; bottom: 11%; width: 58.9%; border-radius: unset; }
[data-illu="bi-api"] .instance-box--2 { right: 0; top: 7.5%; width: 65.5%; }
[data-illu="bi-api"] .instance-box--3 { left: 19.7%; top: 25.8%; width: 11.07%; }
@media (max-width: 1199.98px) { [data-illu="bi-api"] .instance-box--3 { width: 41px; } }
@media (max-width: 575.98px) { [data-illu="bi-api"] .instance-box--3 { width: 26px; border-radius: 4px; } }

/* --- features/banners/BillingIntegrationBanner.vue (scoped, :deep) ----------
   Dziewiąty zestaw położeń warstw (rodzina RZ-87) i jedyny, który używa klucza
   "trial" — czyli nazwy WYKLUCZONEJ z reguły ukrywania warstw pod progiem
   tabletu (:not(--trial)). Wywołanie dokłada dla niej własny blok progu:
   szerokość 16,10% i promień zdjęty. Ta warstwa jest więc jedyną warstwą
   poboczną w repozytorium, która na tablecie ZOSTAJE. */
[data-banner="billing-integration"] .banner__illustration-layer--left-bottom { left: 177px; z-index: -1; }
[data-banner="billing-integration"] .banner__illustration-layer--left-bottom img { width: 387px; }
[data-banner="billing-integration"] .banner__illustration-layer--right-bottom { left: 1011px; z-index: 2; }
[data-banner="billing-integration"] .banner__illustration-layer--right-bottom img { width: 213px; }
[data-banner="billing-integration"] .banner__illustration-layer--trial { top: 107px; left: 265px; z-index: 2; }
[data-banner="billing-integration"] .banner__illustration-layer--trial img { width: 228px; }
@media (max-width: 1023.98px) {
  [data-banner="billing-integration"] .banner__illustration-layer--trial { width: 16.10%; }
  [data-banner="billing-integration"] .banner__illustration-layer--trial img { border-radius: unset; width: 100%; }
}

/* --- features/web-hosting-integrations/* (siedem bloków) --------------------
   Odczyt 18.08.2026. NAJCIĘŻSZY zestaw ilustracji w katalogu: siedem plików,
   49 pudełek, film, pulsujące kropki, dwa opakowania .instance-wrapper
   i trzy różne rodziny progów (1199.98 / 991.98 / 575.98). Wszystkie bloki
   zawężone atrybutem [data-illu], tak jak pozostałe (kompensacja nośnika). */

/* UpgradeFromControlPanel.vue — film w pudełku trzecim, nakładka z ikoną,
   dwie linie z pulsem. Ta sama budowa co OneClickSiteCreation.vue z onboardingu. */
[data-illu="whi-upgrade-from-control-panel"] .instance-box--1 { right: 9%; top: 2.95%; width: 33%; z-index: 1; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--2 { left: 4.98%; top: 4.42%; width: 36.7%; z-index: 4; overflow: visible; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--3 { top: 18%; height: 56.6%; left: 18%; width: 79%; z-index: 3; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--3 video { width: 100%; height: 100%; object-fit: cover; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--3 .video-background { display: flex; align-items: center; justify-content: center; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: linear-gradient(180deg, rgba(15, 130, 80, 0) 0.06%, rgba(15, 130, 80, 0.6) 95.8%); }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--3 .video-background svg { width: 22.3%; height: 33%; transition: all 0.24s ease; fill: #fff; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--3 .video-background:hover svg { fill: #07c07e; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--4 { bottom: 7%; left: 3.5%; width: 21.4%; height: 21.4%; z-index: 3; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--4 svg { max-width: 100%; max-height: 100%; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--5 { right: 13.65%; bottom: 16.2%; width: 69.1%; height: 9.22%; overflow: unset; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--5 svg { width: 100%; height: auto; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--5 .animation-pulse { bottom: 0; right: 37%; background: #ff1010; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--5 .animation-pulse::before { background-color: rgba(255, 16, 16, 0.1); }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--6 { left: 13.1%; bottom: 17.34%; height: 27.67%; width: 9.2%; overflow: unset; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--6 svg { width: 100%; height: auto; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--6 .animation-pulse { top: 38.3%; left: -3px; background: #ff1010; }
[data-illu="whi-upgrade-from-control-panel"] .instance-box--6 .animation-pulse::before { background-color: rgba(255, 16, 16, 0.1); }

/* PanelAlphaEngine.vue — sześć pudełek w PIKSELACH wokół środkowego, ujemne
   przesunięcia i trzy progi. Szerokość wspólna (88px) stoi przed modyfikatorami. */
[data-illu="whi-panelalpha-engine"] .instance-box { width: 88px; }
[data-illu="whi-panelalpha-engine"] .instance-box--1 { width: 277px; position: relative; z-index: 1; }
[data-illu="whi-panelalpha-engine"] .instance-box--2 { top: -107px; left: 28px; }
[data-illu="whi-panelalpha-engine"] .instance-box--3 { top: -107px; right: 28px; }
[data-illu="whi-panelalpha-engine"] .instance-box--4 { top: 53px; left: -107px; width: 107px; }
[data-illu="whi-panelalpha-engine"] .instance-box--5 { top: 53px; right: -107px; width: 107px; }
[data-illu="whi-panelalpha-engine"] .instance-box--6 { bottom: -107px; left: 28px; }
[data-illu="whi-panelalpha-engine"] .instance-box--7 { bottom: -107px; right: 28px; }
@media (max-width: 1199.98px) {
  [data-illu="whi-panelalpha-engine"] .instance-box { width: 60px; border-radius: 0; }
  [data-illu="whi-panelalpha-engine"] .instance-box--1 { border-radius: 10px; width: 189px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--2 { top: -73px; left: 20px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--3 { top: -73px; right: 20px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--4 { top: 36px; left: -73px; width: 73px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--5 { top: 36px; right: -73px; width: 73px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--6 { bottom: -73px; left: 20px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--7 { bottom: -73px; right: 20px; }
}
@media (max-width: 575.98px) {
  [data-illu="whi-panelalpha-engine"] .instance-box { width: 39px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--1 { width: 122px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--2 { top: -47px; left: 12px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--3 { top: -47px; right: 12px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--4 { top: 23px; left: -47px; width: 47px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--5 { top: 23px; right: -47px; width: 47px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--6 { bottom: -47px; left: 12px; }
  [data-illu="whi-panelalpha-engine"] .instance-box--7 { bottom: -47px; right: 12px; }
}

/* ControlPanels.vue */
[data-illu="whi-control-panels"] .instance-box--1 { left: 0px; top: 35.6%; width: 99.4%; }
[data-illu="whi-control-panels"] .instance-box--2 { left: 13.4%; bottom: 14.5%; width: 29.3%; z-index: 1; }
[data-illu="whi-control-panels"] .instance-box--3 { right: 19.1%; top: 9.9%; width: 31.3%; z-index: 1; }
[data-illu="whi-control-panels"] .instance-box--4 { left: 25.4%; top: 19.3%; width: 27.6%; }
[data-illu="whi-control-panels"] .instance-box--5 { right: 7.9%; bottom: 14.5%; width: 45.5%; }

/* Cloud.vue — dziesięć pudełek, wszystkie z rysunkiem WEKTOROWYM, i jedyny
   plik w katalogu z pulsem NUMEROWANYM (.animation-pulse.dot--1..3). */
[data-illu="whi-cloud"] .instance-box { overflow: visible; }
[data-illu="whi-cloud"] .instance-box svg { width: 100%; height: 100%; overflow: visible; }
[data-illu="whi-cloud"] .instance-box--1 { width: 12%; height: 12%; top: 10%; left: 28.7%; z-index: 3; }
[data-illu="whi-cloud"] .instance-box--2 { left: 13%; top: 31.3%; width: 12%; height: 12%; z-index: 3; }
[data-illu="whi-cloud"] .instance-box--3 { width: 12%; height: 12%; bottom: 26%; right: 9.7%; z-index: 3; }
[data-illu="whi-cloud"] .instance-box--4 { width: 40.96%; height: 28%; top: 28.9%; right: 25.46%; z-index: 2; }
[data-illu="whi-cloud"] .instance-box--5 { width: 40.4%; height: 19.5%; left: 10.7%; bottom: 32.6%; z-index: 3; }
[data-illu="whi-cloud"] .instance-box--6 { width: 34.8%; height: 24.3%; left: 28%; bottom: 18.8%; z-index: 1; }
[data-illu="whi-cloud"] .instance-box--6 .animation-pulse { background: #e71d1d; }
[data-illu="whi-cloud"] .instance-box--6 .animation-pulse::before { background-color: #e71d1d26; }
[data-illu="whi-cloud"] .instance-box--6 .animation-pulse.dot--1 { right: 23.7%; top: 40.9%; opacity: 0.5 !important; width: 4.243%; height: 6.077%; }
[data-illu="whi-cloud"] .instance-box--6 .animation-pulse.dot--2 { right: 47.35%; bottom: 13.9%; width: 4.243%; height: 6.077%; }
[data-illu="whi-cloud"] .instance-box--6 .animation-pulse.dot--3 { left: 7.59%; bottom: 24.5%; width: 4.243%; height: 6.077%; }
[data-illu="whi-cloud"] .instance-box--7 { width: 17.8%; height: 19%; top: 15.86%; right: 16.78%; }
[data-illu="whi-cloud"] .instance-box--8 { width: 12.54%; height: 13.28%; top: 15.68%; left: 40.59%; z-index: 2; }
[data-illu="whi-cloud"] .instance-box--8 .animation-pulse { background: #07c07e; right: -5.9%; bottom: -5.5%; width: 11.76%; height: 11.12%; }
[data-illu="whi-cloud"] .instance-box--8 .animation-pulse::before { background-color: var(--pui-animation-pulse-dot-halo); }
[data-illu="whi-cloud"] .instance-box--9 { height: 0.369%; width: 8.48%; left: 24.9%; top: 37.2%; display: flex; z-index: 2; }
[data-illu="whi-cloud"] .instance-box--9 .animation-pulse { background: #07c07e; height: 403.5%; right: -12%; top: -200%; width: 17.41%; }
[data-illu="whi-cloud"] .instance-box--9 .animation-pulse::before { background-color: var(--pui-animation-pulse-dot-halo); }
[data-illu="whi-cloud"] .instance-box--10 { width: 9.22%; height: 9.96%; top: 53.1%; right: 15.7%; z-index: 2; }
[data-illu="whi-cloud"] .instance-box--10 .animation-pulse { background: #07c07e; left: -16%; top: 0%; width: 16%; height: 14.81%; }
[data-illu="whi-cloud"] .instance-box--10 .animation-pulse::before { background-color: var(--pui-animation-pulse-dot-halo); }

/* DNSManagement.vue */
[data-illu="whi-dns-management"] .instance-box--1 { left: 10px; top: 31.5%; width: 39.8%; }
[data-illu="whi-dns-management"] .instance-box--2 { right: 30.2%; bottom: 19.3%; width: 31.7%; }
[data-illu="whi-dns-management"] .instance-box--3 { right: 13.2%; top: 20.8%; width: 40.7%; }

/* EmailServers.vue — CZTERY pudełka w opakowaniu i cztery wprost w ramie,
   trzy progi, a przy progu tabletu i laptopa blok woła .feature__graphic,
   klasy, której w znaczniku NIE MA (rama nazywa się .graphic) — trzy reguły
   martwe w kodzie, przepisane jak stoją. */
[data-illu="whi-email-servers"] .instance-wrapper .instance-box--1 { width: 172px; position: relative; z-index: 1; }
[data-illu="whi-email-servers"] .instance-wrapper .instance-box--2 { bottom: -128px; left: -77px; width: 164px; }
[data-illu="whi-email-servers"] .instance-wrapper .instance-box--3 { bottom: -125px; left: calc(50% - 41px); width: 84px; }
[data-illu="whi-email-servers"] .instance-wrapper .instance-box--4 { bottom: -125px; right: -75px; width: 162px; }
[data-illu="whi-email-servers"] > .instance-box--5 { top: 13.8%; right: 7.5%; width: 38.9%; }
[data-illu="whi-email-servers"] > .instance-box--6 { top: 25.2%; left: 8.6%; width: 40.9%; z-index: 1; }
[data-illu="whi-email-servers"] > .instance-box--7 { top: 45.5%; left: 25.4%; width: 9.7%; }
[data-illu="whi-email-servers"] > .instance-box--8 { top: 27.3%; right: 14%; width: 9.8%; }
@media (max-width: 1199.98px) {
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--1 { width: 117px; }
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--2 { bottom: -92px; left: -53px; width: 112px; border-radius: 0; }
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--3 { bottom: -88px; left: calc(50% - 28px); width: 57px; border-radius: 0; }
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--4 { bottom: -91px; right: -53px; width: 112px; border-radius: 0; }
}
@media (max-width: 575.98px) {
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--1 { width: 76px; }
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--2 { bottom: -56px; left: -34px; width: 73px; }
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--3 { bottom: -56px; left: calc(50% - 18px); width: 37px; }
  [data-illu="whi-email-servers"] .instance-wrapper .instance-box--4 { bottom: -55px; right: -35px; width: 73px; }
}

/* IntegrateWithSystems.vue — dziewięć pudełek w PIKSELACH wokół środkowego,
   tło zdjęte wspólną regułą (background: unset), trzy progi. */
[data-illu="whi-integrate-with-systems"] .instance-box { background: unset; }
[data-illu="whi-integrate-with-systems"] .instance-box--1 { width: 100px; position: relative; z-index: 1; }
[data-illu="whi-integrate-with-systems"] .instance-box--2 { top: -124px; left: 0px; width: 100px; height: 125px; }
[data-illu="whi-integrate-with-systems"] .instance-box--3 { top: -124px; right: -124px; width: 125px; height: 125px; }
[data-illu="whi-integrate-with-systems"] .instance-box--4 { top: 0px; right: -124px; width: 125px; height: 100px; }
[data-illu="whi-integrate-with-systems"] .instance-box--5 { bottom: -124px; right: -124px; width: 125px; height: 125px; overflow: visible; }
[data-illu="whi-integrate-with-systems"] .instance-box--6 { bottom: -124px; left: 0; width: 100px; height: 125px; overflow: visible; }
[data-illu="whi-integrate-with-systems"] .instance-box--7 { bottom: -124px; left: -123px; width: 125px; height: 125px; overflow: visible; }
[data-illu="whi-integrate-with-systems"] .instance-box--7 > img { height: 100%; }
[data-illu="whi-integrate-with-systems"] .instance-box--8 { top: 0; left: -124px; width: 125px; height: 100px; overflow: visible; }
[data-illu="whi-integrate-with-systems"] .instance-box--9 { top: -124px; left: -124px; width: 125px; height: 125px; }
[data-illu="whi-integrate-with-systems"] .instance-box--9 > img { height: 100%; }
@media (max-width: 1199.98px) {
  [data-illu="whi-integrate-with-systems"] .instance-box { background: unset; border-radius: 0; display: flex; }
  [data-illu="whi-integrate-with-systems"] .instance-box--1 { width: 69px; border-radius: 10px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--2 { top: -85px; left: 0px; width: 69px; height: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--3 { top: -84px; right: -84px; width: 85px; height: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--4 { top: 0px; right: -85px; width: 85px; height: 69px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--4 img { height: 86px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--5 { bottom: -85px; right: -85px; width: 85px; height: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--5 img { width: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--6 { bottom: -85px; left: 0; width: 69px; height: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--6 img { width: 69px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--7 { bottom: -85px; left: -85px; width: 85px; height: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--7 img { width: 85px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--8 { top: 0; left: -85px; width: 85px; height: 69px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--9 { top: -85px; left: -85px; width: 85px; height: 85px; }
}
@media (max-width: 575.98px) {
  [data-illu="whi-integrate-with-systems"] .instance-box--1 { width: 45px; border-radius: 10px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--2 { top: -55px; left: 0px; width: 45px; height: 55px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--2 img { width: 45px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--3 { top: -54px; right: -55px; width: 55px; height: 55px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--4 { top: 0px; right: -55px; width: 55px; height: 45px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--4 img { height: 56px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--5 { bottom: -55px; right: -55px; width: 55px; height: 55px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--6 { bottom: -55px; left: 0; width: 45px; height: 55px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--7 { bottom: -55px; left: -55px; width: 55px; height: 55px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--8 { top: 0; left: -55px; width: 55px; height: 45px; }
  [data-illu="whi-integrate-with-systems"] .instance-box--9 { top: -55px; left: -55px; width: 55px; height: 55px; }
}

/* --- features/banners/WebHostingIntegrationsBanner.vue (scoped, :deep) ------
   Ósmy zestaw położeń warstw (rodzina RZ-87). */
[data-banner="web-hosting-integrations"] .banner__illustration-layer--left { top: 109px; left: 123px; z-index: 2; }
[data-banner="web-hosting-integrations"] .banner__illustration-layer--left img { width: 481px; }
[data-banner="web-hosting-integrations"] .banner__illustration-layer--right-bottom { left: 918px; z-index: 2; }
[data-banner="web-hosting-integrations"] .banner__illustration-layer--right-bottom img { width: 306px; }

/* --- features/administration/* (osiem bloków) ------------------------------
   Odczyt 18.08.2026. Ostatni blok (Integrations.vue) ma szerokość wspólną
   dla wszystkich czterech pudełek WYŻEJ w bloku, a nie przy każdym numerze —
   jedyny taki plik w rodzinie, przepisany tą samą drogą. */
[data-illu="administration-dashboard"] .instance-box--1 { right: 0px; top: 38.9%; width: 36.4%; }
[data-illu="administration-dashboard"] .instance-box--2 { left: 5px; top: 38.5%; width: 57.8%; }
[data-illu="administration-dashboard"] .instance-box--3 { right: 4px; top: 12%; width: 99.3%; }
[data-illu="administration-dashboard"] .instance-box--4 { right: 10%; bottom: 28px; width: 36.8%; }

[data-illu="administration-instances"] .instance-box--1 { left: 38.1%; bottom: 5.6%; width: 11.07%; }
[data-illu="administration-instances"] .instance-box--2 { right: 42.8%; top: 8.9%; width: 11.07%; }
[data-illu="administration-instances"] .instance-box--3 { right: 12%; bottom: 10.8%; width: 35%; z-index: 1; }
[data-illu="administration-instances"] .instance-box--4 { left: 11%; top: 4.4%; width: 31.6%; z-index: 1; }
[data-illu="administration-instances"] .instance-box--5 { left: 2px; top: 23.6%; width: 99.6%; }

[data-illu="administration-services"] .instance-box--1 { right: 0px; top: 1.2%; width: 32.2%; z-index: 1; }
[data-illu="administration-services"] .instance-box--2 { left: 0px; top: 33.5%; width: 40.4%; z-index: 1; }
[data-illu="administration-services"] .instance-box--3 { left: 6.4%; top: 8.3%; width: 76%; }
[data-illu="administration-services"] .instance-box--4 { left: 6.4%; bottom: 5.5%; width: 93.5%; }

[data-illu="administration-users"] .instance-box--1 { left: 11.4%; top: 31%; width: 33.4%; }
[data-illu="administration-users"] .instance-box--2 { right: 15.1%; top: 13.1%; width: 36.7%; z-index: 1; }
[data-illu="administration-users"] .instance-box--3 { left: 0px; bottom: 15.1%; width: 97.2%; }

[data-illu="administration-logs"] .instance-box--1 { right: 0px; bottom: 14%; width: 35.3%; z-index: 1; }
[data-illu="administration-logs"] .instance-box--2 { right: 7%; top: 9%; width: 47.3%; z-index: 1; }
[data-illu="administration-logs"] .instance-box--3 { left: 0px; bottom: 6.1%; width: 81%; }

[data-illu="administration-plans-configuration"] .instance-box--1 { left: 9.7%; top: 31.1%; width: 11.07%; }
[data-illu="administration-plans-configuration"] .instance-box--2 { left: 0px; bottom: 6.2%; width: 77.5%; z-index: 1; }
[data-illu="administration-plans-configuration"] .instance-box--3 { right: 5.7%; top: 7.2%; width: 69.9%; }

[data-illu="administration-automatic-ssl"] .instance-box--1 { left: 35.2%; top: 17.9%; width: 11.07%; }
[data-illu="administration-automatic-ssl"] .instance-box--2 { right: 7%; top: 15.3%; width: 43%; z-index: 1; }
[data-illu="administration-automatic-ssl"] .instance-box--3 { right: 1%; bottom: 18.1%; width: 98.5%; }

[data-illu="administration-integrations"] .instance-box { width: 47.6%; }
[data-illu="administration-integrations"] .instance-box--1 { right: 1%; bottom: 7.9%; }
[data-illu="administration-integrations"] .instance-box--2 { left: 1%; bottom: 20.2%; }
[data-illu="administration-integrations"] .instance-box--3 { left: 1%; top: 5.9%; }
[data-illu="administration-integrations"] .instance-box--4 { right: 1%; top: 18.2%; }

/* --- features/banners/AdministrationBanner.vue (blok scoped, :deep) ----------
   Siódmy zestaw położeń warstw (rodzina RZ-87). Kolejność kluczy w wywołaniu
   jest tu ODWRÓCONA wobec pozostałych: right-bottom przed left-bottom. */
[data-banner="administration"] .banner__illustration-layer--right-bottom { left: 1023px; z-index: 1; }
[data-banner="administration"] .banner__illustration-layer--right-bottom img { width: 221px; }
[data-banner="administration"] .banner__illustration-layer--left-bottom { left: 160px; z-index: 1; }
[data-banner="administration"] .banner__illustration-layer--left-bottom img { width: 344px; }

/* --- features/panelalpha-engine/SimpleSharedHosting.vue -------------------- */
[data-illu="simple-shared-hosting"] .instance-box--1 { width: 40.5%; top: 20.1%; left: 29.9%; }
[data-illu="simple-shared-hosting"] .instance-box--2 { bottom: 10.3%; right: 15.7%; width: 34.5%; }
[data-illu="simple-shared-hosting"] .instance-box--3 { bottom: 10.3%; left: 15.5%; width: 34.5%; }
[data-illu="simple-shared-hosting"] .instance-box--4 { bottom: 10.3%; left: 40.9%; width: 18.3%; }
[data-illu="simple-shared-hosting"] .instance-box--5 { top: 11.8%; right: 0; width: 43.7%; }

/* --- features/panelalpha-engine/ScalingPotential.vue -----------------------
   Trzy pudełka mają szerokość w PIKSELACH, nie w procentach ramy, i dlatego
   ten plik jako jedyny w rodzinie ma własne progi: dwa z rodziny 1199.98
   i 575.98, czyli tej samej obcej rodziny liczb co FullControl.vue (CE-03). */
[data-illu="scaling-potential"] .instance-box--1 { width: 64.7%; left: 10.5%; bottom: 15.1%; }
[data-illu="scaling-potential"] .instance-box--2 { width: 27.7%; left: 10.5%; bottom: 15.1%; }
[data-illu="scaling-potential"] .instance-box--3 { top: 37.4%; right: 15.5%; width: 99px; }
[data-illu="scaling-potential"] .instance-box--4 { top: 14.2%; right: 39.1%; width: 99px; }
[data-illu="scaling-potential"] .instance-box--5 { top: 40.2%; right: 42.2%; width: 78px; }
@media (max-width: 1199.98px) {
  [data-illu="scaling-potential"] .instance-box--3,
  [data-illu="scaling-potential"] .instance-box--4 { width: 68px; border-radius: 0; }
  [data-illu="scaling-potential"] .instance-box--5 { width: 53px; }
}
@media (max-width: 575.98px) {
  [data-illu="scaling-potential"] .instance-box--3,
  [data-illu="scaling-potential"] .instance-box--4 { width: 44px; }
  [data-illu="scaling-potential"] .instance-box--5 { width: 35px; }
}

/* --- features/banners/PanelalphaEngineBanner.vue (blok scoped, :deep) -------
   Szósty zestaw położeń warstw (rodzina RZ-87) i jedyny, w którym warstwa
   GŁÓWNA ma własny blok: klucz `main-custom` niesie position: relative
   z !important, przesunięcie 23px i promień z rodziny małej ramki, a obrazek
   w środku ma szerokość 440px i promień ZDJĘTY (border-radius: unset).
   Cztery pudełka wektorowe stoją w położeniach pikselowych. */
[data-banner="panelalpha-engine"] .banner__illustration-layer--main-custom {
  position: relative !important; top: 23px; z-index: 2; max-height: max-content;
  border-radius: var(--pui-banner-graphic-image-sm-inside-radius);
}
[data-banner="panelalpha-engine"] .banner__illustration-layer--main-custom img { width: 440px; border-radius: unset; }
[data-banner="panelalpha-engine"] .banner__illustration-layer--box-left-top { top: 37px; left: 180px; }
[data-banner="panelalpha-engine"] .banner__illustration-layer--box-right-top { top: 117px; left: 288px; }
[data-banner="panelalpha-engine"] .banner__illustration-layer--box-left-bottom { top: 117px; left: 936px; }
[data-banner="panelalpha-engine"] .banner__illustration-layer--box-right-bottom { top: 37px; left: 1171px; }
/* Przycisk w warstwie głównej — blok scoped PanelalphaEngineMainLayer.vue.
   Skala jedzie rolą --engine-main-layer-btn-scale z wartością awaryjną 1,
   której w repozytorium nie ma ani razu (rodzina RZ-35). */
.engine-main-layer { position: relative; max-width: 100%; }
.engine-main-layer img { max-width: 100%; height: auto; }
.engine-main-layer__btn {
  position: absolute; right: 50%; bottom: 30px; width: 100%; max-width: 360px; z-index: 10;
  transform: translateX(50%) scale(var(--engine-main-layer-btn-scale, 1));
  transform-origin: 50% 100%;
  border-radius: var(--pui-banner-graphic-image-base-outside-radius) !important;
  will-change: transform;
}
.engine-main-layer__btn svg { width: 20px; height: 20px; }
.engine-main-layer__btn:hover { transform: translateX(50%) scale(104%); }

/* =============================================================================
   sections/PanelalphaEngineWordpressFeatures.vue — siatka cech silnika.
   Odczyt 18.08.2026, commit 1bcf0cc. NOWA POZYCJA (PA-36).

   ZASIĘG: blok NIE MA scoped (styl globalny), więc reguły przepisane bez
   zawężania. Dwa wiersze po cztery karty, z tego DWIE karty w drugim wierszu
   to `--ghost`: puste pudełka bez tła i cienia, które tylko trzymają miejsce.
   Odstępy i wyściółka czytają rodzinę --pui-feature-*, cień stoi literałem
   w dwóch warstwach rgba (ten sam wzór co w suwaku obrazków). */
.wp-features { display: flex; flex-direction: column; gap: var(--pui-feature-slider-gap); width: 100%; }
.wp-features__row { display: flex; gap: var(--pui-feature-slider-gap); width: 100%; }
.wp-features__card {
  display: flex; flex: 1 0 0; align-items: center; justify-content: center; overflow: hidden;
  gap: var(--pui-feature-icon-gap);
  padding: var(--pui-feature-icon-padding-v) var(--pui-feature-icon-padding-h);
  background: var(--pui-feature-icon-on-primary-bg-solid);
  border-radius: var(--pui-feature-icon-radius);
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 24px 6px rgba(0, 0, 0, 0.05);
}
.wp-features__card--ghost { background: none; box-shadow: none; pointer-events: none; }
.wp-features__icon { display: flex; flex-shrink: 0; align-items: center; justify-content: center; width: var(--pui-feature-icon-icon-size); height: var(--pui-feature-icon-icon-size); }
.wp-features__icon svg { width: 100%; height: 100%; }
.wp-features__title { font-size: var(--pui-text-h8-font-size); line-height: var(--pui-text-h8-line-height); font-weight: 600; color: var(--pui-text-heading); white-space: nowrap; }
/* @include media(laptop) → do 1479.98px: wiersze się zawijają, karty biorą pół
   szerokości i wyrównują treść do lewej, a puste pudełka znikają. */
@media (max-width: 1479.98px) {
  .wp-features__row { flex-wrap: wrap; }
  .wp-features__card { flex: 1 0 calc(50% - var(--pui-feature-slider-gap)); min-width: calc(50% - var(--pui-feature-slider-gap)); justify-content: flex-start; }
  .wp-features__card--ghost { display: none; }
}
@media (max-width: 767.98px) {
  .wp-features__card { flex: 1 0 100%; min-width: 100%; }
}

/* --- features/wordpress-instances-management/* (dziewięć bloków) ------------
   Odczyt 18.08.2026. Największy zestaw ilustracji jednej strony w katalogu:
   dziewięć plików, 29 pudełek. TRZY KATALOGI RYSUNKÓW mają w repozytorium
   nazwy NIEZGODNE z nazwą pliku ilustracji (account-migration wobec
   AccountsMigration, plugins-themes wobec PluginsAndThemesManagement, ssl
   wobec SSLCertificatesManagement) — zapisane jako WIM-02, bo pierwsze
   zgadywanie ścieżek dało dziesięć pudłowań na trzydzieści dwa. */
[data-illu="smart-dashboard"] .instance-box--1 { left: 0px; top: 25%; width: 74.5%; z-index: 1; }
[data-illu="smart-dashboard"] .instance-box--2 { right: 0px; top: 8.4%; width: 73.3%; }
[data-illu="smart-dashboard"] .instance-box--3 { right: 1.4%; bottom: 4.9%; width: 75.6%; }

[data-illu="instance-details-preview"] .instance-box--1 { left: 0px; bottom: 7.9%; width: 91.3%; }
[data-illu="instance-details-preview"] .instance-box--2 { left: 3.3%; top: 7.8%; width: 40.8%; }
[data-illu="instance-details-preview"] .instance-box--3 { right: 12.3%; top: 17.9%; width: 39.4%; }

[data-illu="one-click-wordpress-updates"] .instance-box--1 { left: 4.4%; top: 43.7%; width: 51.6%; z-index: 1; }
[data-illu="one-click-wordpress-updates"] .instance-box--2 { right: 0px; top: 19%; width: 51.6%; z-index: 4; }
[data-illu="one-click-wordpress-updates"] .instance-box--3 { top: 25%; left: 4.4%; width: 38.16%; }

[data-illu="scheduled-backups"] .instance-box--1 { right: 2.5%; top: 6%; width: 41.8%; }
[data-illu="scheduled-backups"] .instance-box--2 { left: 0px; top: 21%; width: 52.3%; z-index: 1; }
[data-illu="scheduled-backups"] .instance-box--3 { right: 0px; bottom: 9.6%; width: 72.5%; }

[data-illu="monitoring"] .instance-box--1 { left: 0px; bottom: 12.7%; width: 83%; }
[data-illu="monitoring"] .instance-box--2 { right: 3.8%; top: 28.5%; width: 41.7%; z-index: 1; }
[data-illu="monitoring"] .instance-box--3 { left: 5.3%; top: 14%; width: 41.6%; }

[data-illu="plugins-and-themes-management"] .instance-box--1 { right: 0px; top: 2.2%; width: 73%; }
[data-illu="plugins-and-themes-management"] .instance-box--2 { left: 3.3%; bottom: 9.2%; width: 72.1%; }
[data-illu="plugins-and-themes-management"] .instance-box--3 { left: 12.1%; top: 18.6%; width: 11%; }
[data-illu="plugins-and-themes-management"] .instance-box--4 { right: 9.7%; bottom: 9.2%; width: 11%; }

[data-illu="accounts-migration"] .instance-box--1 { left: 10px; top: 17.3%; width: 55.3%; z-index: 1; }
[data-illu="accounts-migration"] .instance-box--2 { right: 12%; bottom: 7.9%; width: 60.8%; z-index: 1; }
[data-illu="accounts-migration"] .instance-box--3 { right: 12.9%; top: 7.3%; width: 38.7%; }

[data-illu="ssl-certificates-management"] .instance-box--1 { right: 17.8%; top: 24.1%; width: 11%; height: 11%; }
[data-illu="ssl-certificates-management"] .instance-box--1 svg { width: 100%; height: 100%; }
[data-illu="ssl-certificates-management"] .instance-box--2 { right: 4px; bottom: 18%; width: 68.2%; z-index: 1; }
[data-illu="ssl-certificates-management"] .instance-box--3 { left: 9.8%; bottom: 7.1%; width: 56.8%; }

[data-illu="cloudflare-integration"] .instance-box--1 { right: 15.4%; top: 12.1%; width: 44.9%; z-index: 1; }
[data-illu="cloudflare-integration"] .instance-box--2 { right: 1.9%; bottom: 23.9%; width: 43.7%; }
[data-illu="cloudflare-integration"] .instance-box--3 { right: 1.1%; top: 31.7%; width: 45.5%; }
[data-illu="cloudflare-integration"] .instance-box--4 { left: 0px; top: 17.5%; width: 51.7%; }

/* --- features/banners/WordpressInstancesManagementBanner.vue (scoped, :deep)
   Piąty zestaw położeń warstw (rodzina RZ-87). Klucze mieszają dwie konwencje
   w JEDNYM wywołaniu: `left` bez członu i `right-bottom` z członem. */
[data-banner="wordpress-instances-management"] .banner__illustration-layer--left { top: 125px; left: 180px; z-index: 1; }
[data-banner="wordpress-instances-management"] .banner__illustration-layer--left img { width: 227px; }
[data-banner="wordpress-instances-management"] .banner__illustration-layer--right-bottom { left: 1005px; z-index: 1; }
[data-banner="wordpress-instances-management"] .banner__illustration-layer--right-bottom img { width: 291px; }

/* --- features/banners/DeveloperToolkitBanner.vue (blok scoped, :deep) -------
   Czwarty zestaw położeń warstw banera (rodzina RZ-87) i pierwszy, w którym
   klucze warstw nazywają się `left` i `right` bez członu `-bottom` — a klucz
   jest nazwą modyfikatora, więc reguła bazowa (position: absolute) trafia,
   ale nic więcej. Dwie warstwy wektorowe, klucze `staging` i `live`. */
[data-banner="developer-toolkit"] .banner__illustration-layer--left { left: 140px; top: 115px; z-index: 2; }
[data-banner="developer-toolkit"] .banner__illustration-layer--left img { width: 259px; }
[data-banner="developer-toolkit"] .banner__illustration-layer--right { top: 145px; left: 975px; z-index: 2; }
[data-banner="developer-toolkit"] .banner__illustration-layer--right img { width: 259px; }
[data-banner="developer-toolkit"] .banner__illustration-layer--staging { top: 63px; left: 1134px; z-index: 2; }
[data-banner="developer-toolkit"] .banner__illustration-layer--live { top: 46px; left: 194px; z-index: 2; }

/* =============================================================================
   ui/Slider/Base.vue — suwak obrazków. Odczyt 18.08.2026, commit 1bcf0cc.
   NOWA POZYCJA (kryterium PA-36: własna nazwa w kodzie, własny arkusz).

   ZASIĘG: blok jest scoped i pisze od `.slider-wrapper` w dół, więc zawężenie
   zachowuje się tak samo w płaskim arkuszu. JEDEN wyjątek jest w kodzie
   celowo — `:deep(.section__content)` sięga do GOSPODARZA i przestawia jego
   slot na flex ze środkowaniem; przepisany jako selektor potomka sekcji
   zawężony klasą suwaka, żeby nie objął sekcji bez suwaka.

   CZTERY LITERAŁY BEZ ROLI, wszystkie w kodzie: max-width 720px (dwa razy,
   raz na opakowaniu i raz na slajdzie), odstęp 24px, wyściółka toru 40px 0
   i cień slajdu w dwóch warstwach rgba. Rodzina --pui-image-slider-* ma tylko
   szerokość i promień, więc reszta jest wpisana wprost — zgłoszone jako RZ-93.

   KROPKI CZYTAJĄ DWIE ROLE, KTÓRYCH W REPOZYTORIUM NIE MA: --pui-color-border
   i --pui-pagination-active, obie z wartością awaryjną (rgba(0,0,0,0.2) i #000).
   Przepisane z tymi wartościami, bo tak renderuje się w produkcie. */
.section:has(.slider-wrapper) .section__content { display: flex; justify-content: center; }
.slider-wrapper { display: flex; flex-direction: column; align-items: center; gap: 24px; width: 100%; max-width: 720px; }
/* ZAKRES DOPISANY 19.08.2026 (PR-17, uwaga zamawiającego przy slajdzie cennika).
   Nazwy .keen-slider i .keen-slider__slide należą do BIBLIOTEKI, więc wołają je
   dziś DWA komponenty: suwak obrazków i cennik pojedynczy. W produkcie te reguły
   są scoped, czyli nie wychodzą poza swój komponent; w płaskim arkuszu katalogu
   wychodziły i ustawiały slajdom cennika wyrównanie do środka, szerokość 720 px
   i cień suwaka obrazków — zmierzone: pudełka 406/447/447 px zamiast trzech
   razy 447. To pierwszy w katalogu przypadek KOLIZJI NAZW BIBLIOTEKI, i dokładnie
   ta rodzina, o której mówi pozycja 1 wzorca migracji: reguła scoped bez :deep
   sięga w płaskim arkuszu DALEJ niż w komponencie. Reguły dostają zakres
   swojego opakowania; wartości bez zmian. */
.slider-wrapper .keen-slider { width: 100%; padding: 40px 0; overflow: visible; }
.slider-wrapper .keen-slider__slide {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: var(--pui-image-slider-width); max-width: 720px;
  border-radius: var(--pui-image-slider-radius); background: #fff;
  box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.12), 0 8px 24px 6px rgba(0, 0, 0, 0.05);
}
.slider-wrapper .keen-slider__image { width: 100%; height: 100%; object-fit: cover; }
.slider-pagination { display: flex; align-items: center; gap: 8px; }
.slider-pagination__dot {
  width: 8px; height: 8px; padding: 0; border: none; border-radius: 50%; cursor: pointer;
  background: var(--pui-color-border, rgba(0, 0, 0, 0.2));
  transition: background 0.2s, transform 0.2s;
}
.slider-pagination__dot--active { background: var(--pui-pagination-active, #000); }
/* KOMPENSACJA NOŚNIKA, nazwana: w produkcie tor jest przesuwany transformem
   przez keen-slider, którego katalog nie uruchamia. Kadr pokazuje JEDEN slajd
   w torze bez transformu, więc tor dostaje ukrycie przelewu poziomego, żeby
   sąsiednie slajdy nie wychodziły poza kadr. Podstawienie, nie reguła kodu. */
.slider-wrapper .keen-slider[data-cat-static] { display: flex; overflow-x: clip; }

/* --- features/wp-cloud-integration/* (trzy bloki) ---------------------------
   Odczyt 18.08.2026. Trzy pliki, 19 pudelek, wszystkie WEKTOROWE, i DWA filmy
   — pierwsza strona w katalogu z dwoma. ZERO PROGOW WLASNYCH: zaden z trzech
   plikow nie ma bloku @media, co w tej rodzinie zdarza sie pierwszy raz.
   Dwa pliki sa BLIZNIAKAMI (Seembless i Discover): te same szesc pudelek,
   te same klasy, ten sam uklad pulsow; rozni je PIEC liczb polozenia, jeden
   rysunek (trzy chmury wobec znaku WP Cloud) i przelew na pudelku 2. */
[data-illu="wpc-seembless-integration"] .instance-box--1 { left: 6%; top: 1%; width: 33%; z-index: 1; }
[data-illu="wpc-seembless-integration"] .instance-box--2 { right: 0; top: 0; width: 39%; z-index: 1; }
[data-illu="wpc-seembless-integration"] .instance-box--3 { right: 0; top: 16%; width: 78.5%; height: 56%; z-index: 2; }
[data-illu="wpc-seembless-integration"] .instance-box--4 { left: 0; bottom: 3%; width: 64.5%; z-index: 3; }
[data-illu="wpc-seembless-integration"] .instance-box--5 { right: 11%; bottom: 22.3%; width: 24.3%; height: 5.7%; overflow: unset; }
[data-illu="wpc-seembless-integration"] .instance-box--6 { left: 17.7%; bottom: 26.4%; height: 17.4%; width: 4%; overflow: unset; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--1 { left: 6%; top: 1%; width: 33%; z-index: 1; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--2 { right: 0; top: 0; width: 39%; z-index: 1; overflow: visible; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--2 svg { overflow: visible; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--3 { right: 0; top: 14.7%; width: 78.5%; height: 56%; z-index: 2; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--4 { left: 0; bottom: 0; width: 64.5%; height: 32.4%; z-index: 3; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--5 { right: 11%; bottom: 23.7%; width: 24.3%; height: 5.7%; overflow: unset; }
[data-illu="wpc-discover-wp-cloud"] .instance-box--6 { left: 17.7%; top: 51%; height: 17.7%; width: 4%; overflow: unset; }

/* Film i jego nakladka — reguly IDENTYCZNE w obu plikach, wiec jeden zestaw
   na dwa zakresy. Nakladka jest ODNOSNIKIEM do YouTube z gradientem zieleni
   wpisanym WPROST (dwie wartosci rgba, bez roli) i przejsciem na wypelnieniu
   ikony; kolor pod wskaznikiem #07c07e tez stoi literalem. */
[data-illu="wpc-seembless-integration"] .instance-box--3 video,
[data-illu="wpc-discover-wp-cloud"] .instance-box--3 video { width: 100%; height: 100%; }
[data-illu="wpc-seembless-integration"] .instance-box--3 .video-background,
[data-illu="wpc-discover-wp-cloud"] .instance-box--3 .video-background {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, rgba(15, 130, 80, 0) 0.06%, rgba(15, 130, 80, 0.6) 95.8%);
}
[data-illu="wpc-seembless-integration"] .instance-box--3 .video-background svg,
[data-illu="wpc-discover-wp-cloud"] .instance-box--3 .video-background svg { width: 22.3%; height: 33%; fill: #fff; transition: all 0.24s ease; }
[data-illu="wpc-seembless-integration"] .instance-box--3 .video-background:hover svg,
[data-illu="wpc-discover-wp-cloud"] .instance-box--3 .video-background:hover svg { fill: #07c07e; }

/* Kreski z pulsem — pudelka 5 i 6 w obu plikach. Puls jest CZERWONY literalem
   (#ff1010 i rgba(255,16,16,0.1) na obwodce), a nie rola rodziny, i stoi
   w polozeniach pikselowych o wartosciach UJEMNYCH (-4px, -3px). */
[data-illu="wpc-seembless-integration"] .instance-box--5 svg,
[data-illu="wpc-seembless-integration"] .instance-box--6 svg,
[data-illu="wpc-discover-wp-cloud"] .instance-box--5 svg,
[data-illu="wpc-discover-wp-cloud"] .instance-box--6 svg { width: 100%; height: auto; }
[data-illu="wpc-seembless-integration"] .instance-box--5 .animation-pulse,
[data-illu="wpc-discover-wp-cloud"] .instance-box--5 .animation-pulse { bottom: -4px; left: 28.7%; background: #ff1010; }
[data-illu="wpc-seembless-integration"] .instance-box--6 .animation-pulse,
[data-illu="wpc-discover-wp-cloud"] .instance-box--6 .animation-pulse { top: 38.3%; left: -3px; background: #ff1010; }
[data-illu="wpc-seembless-integration"] .instance-box--5 .animation-pulse::before,
[data-illu="wpc-seembless-integration"] .instance-box--6 .animation-pulse::before,
[data-illu="wpc-discover-wp-cloud"] .instance-box--5 .animation-pulse::before,
[data-illu="wpc-discover-wp-cloud"] .instance-box--6 .animation-pulse::before { background-color: rgba(255, 16, 16, 0.1); }

/* BillingIntegration.vue — siedem pudelek, przelew widoczny na pieciu z nich.
   Pudelko 3 doklada CIEN FILTREM na rysunku zamiast korzystac z cienia rodziny
   (ta sama klasa dlugu co BI-04), a pudelko 6 ma wysokosc podana w PIKSELACH
   ULAMKOWYCH: 34.1px — jedyna taka liczba w tej rodzinie plikow. */
[data-illu="wpc-billing-integration"] .instance-box--1 { left: 0; top: 12.7%; width: 72.8%; z-index: 2; overflow: visible; }
[data-illu="wpc-billing-integration"] .instance-box--2 { right: 38%; top: 0; width: 23.2%; overflow: visible; }
[data-illu="wpc-billing-integration"] .instance-box--3 { right: 5.7%; bottom: 4.9%; width: 42.8%; z-index: 3; overflow: visible; }
[data-illu="wpc-billing-integration"] .instance-box--4 { right: 12.3%; bottom: 41.5%; width: 11.08%; z-index: 3; overflow: visible; }
[data-illu="wpc-billing-integration"] .instance-box--5 { left: 31%; bottom: 3.8%; width: 11.08%; z-index: 3; overflow: visible; }
[data-illu="wpc-billing-integration"] .instance-box--6 { width: 9.4%; height: 34.1px; top: 38%; right: 17.7%; overflow: unset; }
[data-illu="wpc-billing-integration"] .instance-box--7 { width: 39.8%; height: 9.5%; left: 18.2%; bottom: 9%; overflow: unset; }
[data-illu="wpc-billing-integration"] .instance-box--2 svg,
[data-illu="wpc-billing-integration"] .instance-box--4 svg,
[data-illu="wpc-billing-integration"] .instance-box--5 svg { overflow: visible; }
[data-illu="wpc-billing-integration"] .instance-box--3 svg {
  overflow: visible;
  filter: drop-shadow(0 47px 52px rgba(5, 109, 72, 0.07)) drop-shadow(0 14px 30px rgba(0, 0, 0, 0.09));
}
[data-illu="wpc-billing-integration"] .instance-box--6 svg,
[data-illu="wpc-billing-integration"] .instance-box--7 svg { width: 100%; height: auto; }

/* --- features/banners/WpCloudIntegrationBanner.vue (scoped, :deep) ----------
   Dziesiaty zestaw polozen warstw (rodzina RZ-87). Klucz warstwy WEKTOROWEJ
   nazywa sie w kodzie `cloude`, z literowka, a klucz jest nazwa modyfikatora
   klasy — czyli nazwa jest adresem i katalog jej nie poprawia (PA-01). */
[data-banner="wp-cloud-integration"] .banner__illustration-layer--left-bottom { left: 180px; z-index: -1; }
[data-banner="wp-cloud-integration"] .banner__illustration-layer--left-bottom img { width: 219px; }
[data-banner="wp-cloud-integration"] .banner__illustration-layer--right-bottom { left: 911px; z-index: 2; }
[data-banner="wp-cloud-integration"] .banner__illustration-layer--right-bottom img { width: 313px; }
[data-banner="wp-cloud-integration"] .banner__illustration-layer--cloude { left: 243px; top: 98px; z-index: 2; }

/* --- features/white-label-reselling/* (cztery bloki) ------------------------
   Odczyt 18.08.2026. Cztery pliki, 17 pudelek, wszystkie RASTROWE. Zero progow
   wlasnych, zero filmow, zero pulsow — i mimo to koszt nie jest zerowy, bo ta
   strona wprowadza MECHANIZM SZOSTY, ktorego piec zliczen jeszcze nie mialo:
   CIEN WPISANY LITERALEM NA KAZDYM PUDELKU. Ani jedno z 17 pudelek nie uzywa
   modyfikatora rodziny (--no-background, --light, --no-shadow); zamiast tego
   kazde niesie wlasna deklaracje box-shadow, a cztery dokladaja obwiednie
   i promien wprost. Kolor cienia jest przy tym z rodziny CYJANOWEJ (#0ea0c312),
   ktorej katalog dotad nie widzial — poprzednie strony mialy zielen
   rgba(5, 109, 72). Pudelko trzecie User Managment jest wyjatkiem w SWOIM
   pliku: cien filtrem ma odcien ZIELONY, gdy jego rodzenstwo ma cyjanowy. */
[data-illu="wlr-custom-branding-url"] .instance-box--1 { right: 7%; top: 8.85%; width: 36.34%; }
[data-illu="wlr-custom-branding-url"] .instance-box--2 { left: 6.82%; top: 21.95%; width: 51.66%; z-index: 1; }
[data-illu="wlr-custom-branding-url"] .instance-box--3 {
  right: 15.12%; bottom: 8.85%; width: 51.2%; background: transparent; box-shadow: none;
  filter: drop-shadow(0px 47px 52px rgba(14, 160, 195, 0.07)) drop-shadow(0px 14px 30px rgba(0, 0, 0, 0.09));
}
[data-illu="wlr-user-managment"] .instance-box--1 { left: 12.54%; top: 13.65%; width: 74.9%; }
[data-illu="wlr-user-managment"] .instance-box--2 { right: 18.08%; bottom: 13.5%; width: 23.61%; }
[data-illu="wlr-user-managment"] .instance-box--3 {
  left: 4.42%; bottom: 20.66%; width: 53.87%; background: transparent; box-shadow: none;
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, 0.09)) drop-shadow(0 47px 52px rgba(5, 109, 72, 0.07));
}
[data-illu="wlr-user-managment"] .instance-box--4 { right: 15.86%; bottom: 19.55%; width: 6.08%; background: transparent; box-shadow: none; }
[data-illu="wlr-multi-site-control"] .instance-box--1 { width: 88.93%; right: 3.13%; top: 17.89%; height: 12.55%; }
[data-illu="wlr-multi-site-control"] .instance-box--2 { width: 88.93%; right: 3.13%; top: 34.5%; height: 12.55%; }
[data-illu="wlr-multi-site-control"] .instance-box--3 { width: 88.93%; right: 3.13%; top: 52.02%; height: 12.55%; }
[data-illu="wlr-multi-site-control"] .instance-box--4 { width: 94.09%; left: 0; bottom: 21.21%; }
[data-illu="wlr-multi-site-control"] .instance-box--5 { width: 27.67%; top: 9.77%; right: 14.39%; }
[data-illu="wlr-multi-site-control"] .instance-box--6 { width: 20.298%; right: 0; top: 44.28%; }
[data-illu="wlr-multi-site-control"] .instance-box--7 { width: 17.52%; bottom: 8.48%; left: 15.86%; }
[data-illu="wlr-api-for-resellers"] .instance-box--1 { width: 68.3%; left: 3.9%; top: 6.9%; }
[data-illu="wlr-api-for-resellers"] .instance-box--2 { width: 68.3%; right: 3.9%; bottom: 8.7%; }
[data-illu="wlr-api-for-resellers"] .instance-box--3 { width: 21.8%; left: 8.3%; top: 49.6%; }

/* CIEN GLOWNY, jeden zestaw na dziesiec pudelek. W kodzie ta sama deklaracja
   stoi DZIESIEC RAZY, przepisana w kazdym bloku polozen osobno; tu jedzie
   jednym selektorem grupowym, bo wartosc jest identyczna do znaku. Piec liczb
   jest ULAMKOWYCH (44.42, 49.15, 5.67, 13.23, 28.36 px) i nie wynika z zadnej
   roli — rodzina .instance-box ma na cien wlasne reguly. */
[data-illu="wlr-custom-branding-url"] .instance-box--1,
[data-illu="wlr-custom-branding-url"] .instance-box--2,
[data-illu="wlr-user-managment"] .instance-box--1,
[data-illu="wlr-user-managment"] .instance-box--2,
[data-illu="wlr-multi-site-control"] .instance-box--1,
[data-illu="wlr-multi-site-control"] .instance-box--2,
[data-illu="wlr-multi-site-control"] .instance-box--3,
[data-illu="wlr-multi-site-control"] .instance-box--4,
[data-illu="wlr-api-for-resellers"] .instance-box--1,
[data-illu="wlr-api-for-resellers"] .instance-box--2 { box-shadow: 0px 44.42px 49.15px 5.67px #0ea0c312, 0px 13.23px 28.36px 0px #00000017; }

/* CIEN DROBNY plus OBWIEDNIA CYJANOWA — cztery pudelka w dwoch plikach.
   Trzy z nich (Multi-Site 5, 6, 7) dostaja go razem z obwiednia 1px #17bde6
   i promieniem 6px wpisanymi wprost, mimo ze rodzina ma modyfikatory obwiedni;
   czwarte (API 3) niesie sam cien, bez obwiedni. */
[data-illu="wlr-multi-site-control"] .instance-box--5,
[data-illu="wlr-multi-site-control"] .instance-box--6,
[data-illu="wlr-multi-site-control"] .instance-box--7,
[data-illu="wlr-api-for-resellers"] .instance-box--3 { box-shadow: 0px 7.05px 22.03px 0px #0e0d100a, 0px 7.05px 21.14px 5.29px #0000000d, 0px 0px 0.88px 0px #0000001f; }
[data-illu="wlr-multi-site-control"] .instance-box--5,
[data-illu="wlr-multi-site-control"] .instance-box--6,
[data-illu="wlr-multi-site-control"] .instance-box--7 { background: transparent; border: 1px solid #17bde6; border-radius: 6px; }
[data-illu="wlr-multi-site-control"] .instance-box--5 img,
[data-illu="wlr-multi-site-control"] .instance-box--6 img,
[data-illu="wlr-multi-site-control"] .instance-box--7 img { width: 100%; }

/* --- features/banners/WhiteLabelResellingBanner.vue (scoped, :deep) ---------
   Jedenasty zestaw polozen warstw (rodzina RZ-87) i pierwszy, w ktorym OBIE
   warstwy poboczne maja podane wejscie od gory — dziewiec pozostalych wywolan
   zostawia je na dolnej krawedzi z reguly rodziny albo podaje gorne tylko
   jednej. Katalog rysunkow banera nazywa sie w kodzie white-label-reseling,
   przez jedno L, i tak samo nazywaja sie trzy pliki: nazwa jest adresem. */
[data-banner="white-label-reselling"] .banner__illustration-layer--left-bottom { top: 165px; left: 180px; z-index: 2; }
[data-banner="white-label-reselling"] .banner__illustration-layer--left-bottom img { width: 216px; }
[data-banner="white-label-reselling"] .banner__illustration-layer--right-bottom { top: 127px; left: 1013px; z-index: 2; }
[data-banner="white-label-reselling"] .banner__illustration-layer--right-bottom img { width: 217px; }

/* --- features/automatic-migrations/* (cztery bloki + osiem rysunkow) --------
   Odczyt 18.08.2026. Cztery pliki polozen, 27 pudelek: 19 z rastrem, 8 z RYSUNKIEM
   WEKTOROWYM, ktory w kodzie NIE JEST PLIKIEM .svg — jest OSOBNYM KOMPONENTEM Vue
   z rysunkiem wpisanym w szablon (AutomaticMigrations*Line1..5). To siodmy mechanizm
   w wycenie: rysunek bez pliku, ktorego nie widzi ani import ?component, ani zadne
   z szesciu zliczen. Katalog wyciaga te osiem rysunkow do plikow .svg pod nazwami
   ICH KOMPONENTOW, bo nazwa jest adresem, a wstrzykiwanie idzie przez fetch.
   Ta strona jako jedyna w rodzinie uzywa modyfikatorow rodziny SZEROKO
   (--light-sides, --border, --light, --no-background, --no-shadow,
   --overflow-visible) — odwrotnie niz White-Label Reselling, gdzie nie ma ich wcale. */
[data-illu="am-migration-plugin"] .instance-box { border-radius: 6px; }
[data-illu="am-migration-plugin"] .instance-box--1 { width: 39.23%; height: 34.87%; left: 2.95%; top: 14.94%; }
[data-illu="am-migration-plugin"] .instance-box--2 { width: 51.29%; height: 12.18%; right: 1.66%; top: 16.79%; }
[data-illu="am-migration-plugin"] .instance-box--3 { width: 73.06%; height: 51.11%; right: 5.9%; top: 32.66%; }
[data-illu="am-migration-plugin"] .instance-box--4 { width: 23.99%; height: 8.86%; left: 1.66%; bottom: 19%; border-radius: 5px; }

/* SupportingSites.vue — jedenascie pudelek i JEDYNE wlasne progi tej strony,
   oba tylko na PROMIENIU: 12px, 8px pod 1199.98 i 6px pod 575.98. Rodzina liczb
   jest ta obca (1199.98 / 575.98), nie katalogowa. */
[data-illu="am-supporting-sites"] .instance-box { border-radius: 12px; }
[data-illu="am-supporting-sites"] .instance-box svg { overflow: visible; }
[data-illu="am-supporting-sites"] .instance-box--1 { width: 51.29%; height: 38.38%; left: 22.14%; top: 8.3%; z-index: 1; }
[data-illu="am-supporting-sites"] .instance-box--2 { width: 13.65%; height: 13.65%; top: 59.59%; left: 57.38%; z-index: 1; }
[data-illu="am-supporting-sites"] .instance-box--3 { width: 13.65%; height: 13.65%; top: 59.59%; left: 74.72%; z-index: 1; }
[data-illu="am-supporting-sites"] .instance-box--4 { width: 13.65%; height: 13.65%; top: 59.59%; left: 22.49%; z-index: 1; }
[data-illu="am-supporting-sites"] .instance-box--5 { width: 13.65%; height: 13.65%; top: 59.59%; left: 5.17%; z-index: 1; }
[data-illu="am-supporting-sites"] .instance-box--6 { width: 13.65%; height: 13.65%; top: 59.59%; left: 40.04%; z-index: 1; }
[data-illu="am-supporting-sites"] .instance-box--7 { width: 26.94%; height: 37.82%; top: 45.57%; left: 11.99%; }
[data-illu="am-supporting-sites"] .instance-box--8 { width: 13.65%; height: 37.82%; top: 44.64%; left: 29.15%; }
[data-illu="am-supporting-sites"] .instance-box--9 { width: 0.37%; height: 39.11%; top: 44.28%; left: 46.49%; }
[data-illu="am-supporting-sites"] .instance-box--10 { width: 13.84%; height: 44.1%; top: 44.64%; left: 50.37%; }
[data-illu="am-supporting-sites"] .instance-box--11 { width: 27.7%; height: 37.64%; top: 44.12%; left: 54.24%; }
@media (max-width: 1199.98px) {
  [data-illu="am-supporting-sites"] .instance-box { border-radius: 8px; }
}
@media (max-width: 575.98px) {
  [data-illu="am-supporting-sites"] .instance-box { border-radius: 6px; }
}

/* HandlingProviders.vue — dziewiec pudelek, trzy z nich niosa kreske wektorowa
   RAZEM z pulsem, a puls ma tu rozmiar 4x4 px podany W BLOKU ILUSTRACJI,
   nie w rodzinie. Trzy przesuniecia pulsow sa pikselowe, dwa UJEMNE. */
[data-illu="am-handling-providers"] .instance-box { border-radius: 12px; }
[data-illu="am-handling-providers"] .instance-box svg { overflow: visible; }
[data-illu="am-handling-providers"] .instance-box .animation-pulse { width: 4px; height: 4px; }
[data-illu="am-handling-providers"] .instance-box--1 { width: 41.7%; height: 39.85%; left: 27.49%; top: 27.49%; }
[data-illu="am-handling-providers"] .instance-box--2 { width: 13.65%; height: 13.65%; left: 66.43%; top: 16.6%; }
[data-illu="am-handling-providers"] .instance-box--3 { width: 13.65%; height: 13.65%; left: 78.22%; top: 42.62%; }
[data-illu="am-handling-providers"] .instance-box--4 { width: 13.65%; height: 13.65%; left: 54.61%; top: 63.83%; }
[data-illu="am-handling-providers"] .instance-box--5 { width: 13.65%; height: 13.65%; left: 13.1%; top: 54.43%; }
[data-illu="am-handling-providers"] .instance-box--6 { width: 13.65%; height: 13.65%; left: 11.63%; top: 28.23%; }
[data-illu="am-handling-providers"] .instance-box--7 { width: 28.41%; height: 11.07%; left: 7.93%; top: 22.51%; }
[data-illu="am-handling-providers"] .instance-box--8 { width: 12.55%; height: 16.61%; left: 19.74%; top: 54.61%; }
[data-illu="am-handling-providers"] .instance-box--9 { width: 16.42%; height: 10.33%; left: 68.63%; top: 49.82%; }
[data-illu="am-handling-providers"] .instance-box--7 .animation-pulse { bottom: 2px; right: 0px; }
[data-illu="am-handling-providers"] .instance-box--8 .animation-pulse { right: -1px; top: -1px; }
[data-illu="am-handling-providers"] .instance-box--9 .animation-pulse { left: -2px; top: -1px; }

/* SimpleWorkflow.vue — trzy pudelka. W kodzie blok drugiego pudelka stoi PRZED
   blokiem pierwszego; kolejnosc deklaracji przepisana jak stoi, bo przy rownej
   wadze selektorow kolejnosc jest tym, co rozstrzyga. */
[data-illu="am-simple-workflow"] .instance-box { border-radius: 6px; }
[data-illu="am-simple-workflow"] .instance-box--2 { width: 65.87%; height: 46.13%; left: 2.77%; top: 19.56%; }
[data-illu="am-simple-workflow"] .instance-box--1 { width: 28.23%; height: 7.01%; left: 6.09%; top: 72.14%; z-index: 1; }
[data-illu="am-simple-workflow"] .instance-box--3 { width: 65.31%; height: 76.75%; right: 2.77%; top: 11.81%; }

/* --- features/banners/AutomaticMigrationsBanner.vue (scoped, :deep) ---------
   Dwunasty i OSTATNI zestaw polozen warstw w rodzinie stron funkcji (RZ-87).
   Klucze mieszaja dwie konwencje w jednym wywolaniu: jeden bez czlonu, drugi
   z czlonem dolnym — to samo, co u WordPress Instances Management. Katalog
   rysunkow nazywa sie automatic-wordpress-migrations, czyli inaczej niz strona
   (automatic-migrations): nazwa jest adresem. */
[data-banner="automatic-migrations"] .banner__illustration-layer--left { top: 81px; left: 160px; z-index: 2; }
[data-banner="automatic-migrations"] .banner__illustration-layer--left img { width: 343px; }
[data-banner="automatic-migrations"] .banner__illustration-layer--right-bottom { left: 953px; z-index: 2; }
[data-banner="automatic-migrations"] .banner__illustration-layer--right-bottom img { width: 295px; }

/* --- pages/roadmap.vue (blok scoped strony, nie komponentu) -----------------
   Odczyt 18.08.2026. PIERWSZY blok w tym arkuszu, ktory nalezy do STRONY,
   a nie do komponentu: jedenascie stron funkcji i szesc zastosowan nie mialy
   wlasnych regul wcale, ich wyglad w calosci niosly komponenty. Roadmap ma
   szesc regul wlasnych i wszystkie dotycza JEDNEJ rzeczy — ramy z przewijaniem
   wokol obrazka planu. Nazwa bloku idzie po pliku strony, tak jak dotad po
   pliku komponentu.

   PASEK PRZEWIJANIA JEST TU CZESCIA WYGLADU, nie zachowaniem: kod rysuje go
   wlasnymi regulami -webkit-scrollbar (szerokosc 14px, uchwyt #e5e5f0 z ramka
   4px z przezroczystosci i przycieciem do wyscolki). Przepisane jak stoi,
   razem z przedrostkiem, bo to jedyny nosnik tego wygladu w repozytorium. */
.section--roadmap .section__content { overflow: hidden; }
.roadmap__outer { border-radius: var(--pui-changelog-content-radius); overflow: hidden; background: white; }
.roadmap__outer.border-mask::before {
  background: linear-gradient(99deg, var(--pui-content-block-body-primary-border-start) 0%, var(--pui-content-block-body-primary-border-end) 15%, var(--pui-content-block-body-primary-border-end) 85%, var(--pui-content-block-body-primary-border-start) 100%);
}
.roadmap__inner { max-height: 784px; overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable; }
.roadmap__inner img { width: 1352px; }
.roadmap__inner::-webkit-scrollbar { width: 14px; }
.roadmap__inner::-webkit-scrollbar-track { background: transparent; }
.roadmap__inner::-webkit-scrollbar-thumb { background: #e5e5f0; border-radius: 999px; border: 4px solid transparent; background-clip: padding-box; }


/* =============================================================================
   CHANGELOG — transpozycja `app/assets/css/elements/changelog.scss` (453 linie)
   oraz bloku znacznika z `app/pages/changelog.vue`. Odczyt 19.08.2026,
   kopia commit 1bcf0cc.

   NAJDŁUŻSZY ARKUSZ ELEMENTU W CAŁYM ODCZYCIE i pierwszy, w którym wygląd
   niesie DWIE rodziny klas naraz: `.changelog*` (rama, spis wersji, wpis)
   oraz `.box-content` (listy zmian i ich wypunktowanie). Druga nazwa nie ma
   przedrostka rodziny i jest w repozytorium jedyna taka — przepisana jak stoi.

   REGUŁA MARTWA, ZNALEZIONA PRZY TRANSPOZYCJI (CL-01, RZ-94): blok
   `.section.section--changelog` niesie `.section-content` z pojedynczym
   łącznikiem, a `Section.vue` renderuje `.section__content` z podwójnym
   podkreśleniem. Selektor nie trafia w nic w całym repozytorium. Przepisany
   jak stoi, razem z nietrafiającą nazwą — inaczej katalog pokazywałby układ,
   którego produkt nie ma.
   ========================================================================== */

.section.section--changelog { overflow: visible !important; }
/* Nazwa Z KODU, z jednym łącznikiem — patrz nagłówek bloku. Nie ma czytelnika. */
.section.section--changelog .section-content { display: flex; gap: var(--static-space-4x); }

.changelog {
  display: flex; position: relative; justify-content: center; flex: 1 0 0;
  padding: var(--pui-changelog-content-padding-v) var(--pui-changelog-content-padding-h);
  gap: var(--pui-changelog-content-content-gap-h);
  border-radius: var(--pui-changelog-content-radius);
  background: var(--pui-changelog-bullet-point-bg);
}
/* Obwiednia idzie przez ::before pomocnika .border-mask; gradient WPISANY
   WPROST w kodzie, bez roli — te same trzy barwy co w karcie (.card). */
.changelog.border-mask::before { background: linear-gradient(99.28deg, #07C07E 0%, #D9D9E3 15%, #D9D9E3 85%, #07C07E 100%); }

.changelog__versions {
  width: 240px; min-width: 240px; position: sticky; top: calc(80px + 24px);
  height: fit-content; display: flex; flex-direction: column;
}
.changelog__versions-title {
  color: var(--pui-text-lighter); font-size: var(--pui-text-p-xs-font-size); font-weight: 300;
  line-height: var(--pui-text-p-xs-line-height); letter-spacing: var(--pui-text-p-xs-letter-spacing);
}
.changelog__version-wrapper { margin-top: 3px; display: flex; flex-direction: column; flex: 1; min-height: 0; overscroll-behavior: contain; }
/* PROMIEŃ 5 px WPISANY WPROST — jedyna taka wartość w rodzinie, rola nie istnieje.
   Waga fontu zadeklarowana DWA RAZY w jednej regule (600, potem 500): wygrywa 500. */
.changelog__version-item {
  display: flex; align-items: center; font-weight: 600;
  padding: var(--pui-changelog-sub-nav-item-padding-v) var(--pui-changelog-sub-nav-item-padding-h);
  gap: var(--pui-changelog-sub-nav-gap); border-radius: 5px; transition: all .3s ease;
  color: var(--pui-text-heading); font-size: var(--pui-text-p-base-font-size);
  font-weight: 500; line-height: var(--pui-text-p-base-line-height);
  text-decoration: none; cursor: pointer;
}
.changelog__version-item:hover { color: var(--pui-text-primary); }
.changelog__version-item.is-active { color: var(--pui-text-primary); background: var(--static-primary-alpha-150); }

.changelog__content { position: relative; margin-left: var(--pui-changelog-description-gap); flex: 1; min-width: 0; }
/* PROWADNICA PIONOWA: 4 px szerokości, wysokość całej kolumny, przesuwana
   ujemnym marginesem na każdym progu — cztery wartości na jedną linię. */
.changelog__content::before {
  content: ""; position: absolute; top: 0; left: -32px; width: 4px; height: 100%;
  background: var(--pui-changelog-divider); border-radius: 200px; margin-left: -4px;
}
.changelog__content-wrapper { position: relative; display: flex; flex-direction: column; gap: var(--pui-changelog-description-gap); }
.changelog__content-item { position: relative; scroll-margin-top: calc(80px + 24px); }
.changelog__anchor { position: absolute; left: 0; top: -1px; scroll-margin-top: calc(80px + 24px); }
.changelog__entry {
  display: flex; flex-direction: column; gap: var(--pui-changelog-description-section-gap);
  padding: var(--pui-changelog-description-padding-v) var(--pui-changelog-description-padding-h); position: relative;
}
.changelog__heading { display: flex; flex-direction: column; gap: var(--pui-changelog-title-gap); }
.changelog__title { display: flex; align-items: center; justify-content: space-between; gap: var(--pui-changelog-title-gap); }
.changelog__version { display: flex; align-items: center; gap: var(--pui-changelog-title-version-date-gap); color: var(--pui-text-heading); text-align: center; font-weight: 600; margin: 0; }
/* Warunek na TREŚCI: plakietka NEW zwęża odstęp wersji od 24 px do 8 px. */
.changelog__version:has(.badge) { gap: 8px; }
/* WYŚCIÓŁKA, ODSTĘP I PROMIEŃ DATY WPISANE WPROST (8/12, 8, 4 px) — rodzina
   changelogu ma role na wszystko inne, na tę jedną rzecz nie ma żadnej. */
.changelog__date { display: flex; padding: 8px 12px; align-items: center; gap: 8px; border-radius: 4px; border: 1px solid var(--pui-changelog-guides-border); }
.changelog__date svg { color: var(--pui-text-lighter); flex-shrink: 0; }
.changelog__date span {
  color: var(--pui-text-lighter); font-family: var(--static-typography-font-family);
  font-size: var(--pui-text-p-sm-font-size); font-weight: 300;
  line-height: var(--pui-text-p-sm-line-height); letter-spacing: var(--pui-text-p-sm-letter-spacing); text-align: center;
}
.changelog__desc { color: var(--pui-text-lighter); }
.changelog__desc a { color: var(--pui-text-primary); text-decoration: underline; }
/* SEPARATOR SZERSZY OD KOLUMNY o 64 px, czyli o dwie wyściółki wpisu — wystaje
   w obie strony i to jest w kodzie, nie usterka przepisania. */
.changelog__divider { width: calc(100% + 64px); height: 1px; background: var(--pui-changelog-separator); position: relative; }
.changelog__subtitle {
  color: var(--pui-text-heading); font-size: var(--pui-text-h6-font-size); font-weight: 600;
  line-height: var(--pui-text-h6-line-height); letter-spacing: var(--pui-text-h6-letter-spacing); margin: 0;
}
/* KROPKA NA PROWADNICY: koło 26 px, wewnątrz pierścień z ::after i punkt 8 px
   z ::before. Położenie liczone od lewej krawędzi kolumny wartością ujemną,
   inną na każdym progu. */
.changelog__dot {
  position: absolute; left: -79px; top: 3px; width: 26px; height: 26px;
  background: var(--pui-changelog-bullet-point-bg); border-radius: 50%;
}
.changelog__dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--pui-changelog-bullet-point-new-features-light); }
.changelog__dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--pui-changelog-bullet-point-new-features);
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1;
}
.changelog__item { display: block; color: var(--pui-text-body); font-weight: 300; }
.changelog__item strong { color: var(--pui-text-heading); font-weight: 600; }

/* CZTERY WARIANTY BARWY KROPKI. Piąty i szósty rodzaj zmiany, które podaje
   plik danych (deprecations, engine-release), NIE MAJĄ tu reguły — jadą na
   barwie bazowej, czyli zielonej jak nowe funkcje (CL-02). */
.changelog__improvements .changelog__dot::before { background: var(--pui-changelog-bullet-point-improvements); }
.changelog__improvements .changelog__dot::after { background: var(--pui-changelog-bullet-point-improvements-light); }
.changelog__bug-fixes .changelog__dot::before { background: var(--pui-changelog-bullet-point-bug); }
.changelog__bug-fixes .changelog__dot::after { background: var(--pui-changelog-bullet-point-bug-light); }
.changelog__reported-cases .changelog__dot::before { background: var(--pui-changelog-bullet-point-cases-reported); }
.changelog__reported-cases .changelog__dot::after { background: var(--pui-changelog-bullet-point-cases-reported-light); }
.changelog__new-features .changelog__dot::before { background: var(--pui-changelog-bullet-point-new-features); }
.changelog__new-features .changelog__dot::after { background: var(--pui-changelog-bullet-point-new-features-light); }

.changelog__actions { display: flex; align-items: center; justify-content: center; margin-top: var(--pui-changelog-content-content-gap-v); }

/* PAS PYTANIA po pierwszym wpisie. Tło gradientem z rodziny bloku treści,
   rysunek pod nim to plik SVG rozmyty filtrem i przesunięty poza kadr. */
.changelog__cta-banner {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--pui-changelog-faq-padding-v) var(--pui-changelog-faq-padding-h);
  background: linear-gradient(270deg, var(--pui-content-block-body-primary-primary-bg-start) 0%, var(--pui-content-block-body-primary-primary-bg-end) 100%);
  border-radius: var(--pui-ui-radius-4xl); gap: var(--pui-changelog-faq-gap);
  position: relative; overflow: hidden;
}
.changelog__cta-banner-left { display: flex; align-items: center; gap: var(--pui-changelog-faq-gap); }
/* Promień 48 px przy boku 60 px, więc koło; obwódka 3 px rysowana OUTLINE,
   nie border — jedyne takie użycie w odczycie. */
.changelog__cta-banner-avatar {
  width: 60px; height: 60px; border-radius: 48px; overflow: hidden; flex-shrink: 0;
  outline: 3px solid var(--pui-button-primary-solid-border);
}
.changelog__cta-banner-avatar img { width: 100%; height: 100%; object-fit: cover; }
.changelog__cta-banner-bg {
  opacity: 0.4; filter: blur(3px); width: 1107px; height: 847px;
  position: absolute; left: -527.444px; bottom: -544px;
}
.changelog__cta-banner-title { margin: 0; font-weight: 600; }

.box-content { width: 100%; }
.box-content > div { display: flex; flex-direction: column; align-items: flex-start; position: relative; gap: var(--pui-changelog-description-gap); }
.box-content > div.changelog__improvements > ul > li::before { background: var(--pui-changelog-bullet-point-improvements); }
.box-content > div.changelog__improvements ul ul li::before { border-color: var(--pui-changelog-bullet-point-improvements); }
.box-content > div.changelog__reported-cases > ul > li::before { background: var(--pui-changelog-bullet-point-cases-reported); }
.box-content > div.changelog__reported-cases ul ul li::before { border-color: var(--pui-changelog-bullet-point-cases-reported); }
.box-content > div.changelog__bug-fixes > ul > li::before { background: var(--pui-changelog-bullet-point-bug); }
.box-content > div.changelog__bug-fixes ul ul li::before { border-color: var(--pui-changelog-bullet-point-bug); }
.box-content > div.changelog__new-features > ul > li::before { background: var(--pui-changelog-bullet-point-new-features); }
.box-content > div.changelog__new-features ul ul li::before { border-color: var(--pui-changelog-bullet-point-new-features); }
.box-content > div ul { display: flex; padding-left: var(--pui-changelog-description-list-padding-left); flex-direction: column; gap: var(--pui-changelog-description-rows-gap); margin: 0; list-style: none; }
/* Warunek na TREŚCI drugi raz na tej stronie: lista, która ma podlistę,
   rozsuwa wiersze z 10 px na 20 px. */
.box-content > div ul:has(li > ul) { gap: var(--pui-changelog-description-list-gap); }
.box-content > div ul li { padding-left: 18px; position: relative; }
.box-content > div ul li::before {
  content: ""; background: var(--pui-changelog-bullet-point-new-features); position: absolute;
  display: inline-flex; width: 6px; height: 6px; border-radius: 50%; left: 0; top: 10px;
}
.box-content > div ul li ul { padding-left: 0; gap: var(--pui-changelog-description-rows-gap); margin-top: var(--pui-changelog-description-rows-gap); }
.box-content > div ul li ul li { color: var(--pui-text-body); font-weight: 300; }
.box-content > div ul li ul li::before { background: var(--pui-changelog-bullet-point-bg); border: 1px solid var(--pui-changelog-bullet-point-new-features); }

/* --- KOMPENSACJA NOŚNIKA KATALOGU — odsunięcie rzeczy PRZYKLEJONYCH ---------
   Zgłoszone przeglądem zamawiającego 19.08.2026: spis wersji przykleja się ZA NISKO.

   Zmierzone w kadrze przy 1498 px: element stoi dokładnie tam, gdzie każe kod,
   czyli 104 px od górnej krawędzi okna (top: calc(80px + 24px)). W PRODUKCIE
   te 104 px to 80 px wysokości PRZYKLEJONEJ nawigacji plus 24 px odstępu, więc
   pod paskiem nie zostaje puste miejsce. Katalog nawigację strony osadza
   POŁOŻENIEM BEZWZGLĘDNYM u góry ramy, nie przyklejeniem — pasek odjeżdża
   z przewijaniem, a odsunięcie liczone na jego wysokość zostaje i czyta się
   jak usterka: spis wisi 80 px niżej bez powodu widocznego na ekranie.

   Kompensacja zdejmuje TĘ CZĘŚĆ odsunięcia, która opisuje nieistniejący tu
   pasek, i zostawia sam odstęp. Wartość stoi w JEDNEJ roli, bo czyta ją też
   skok do wersji w logice widoku — inaczej spis i skok rozjechałyby się o 80 px.
   Dotyczy wyłącznie nośnika katalogu; arkusz produktu tego nie widzi (CL-08). */
:root { --cat-changelog-sticky-top: var(--static-space-3x); }
.changelog__versions { top: var(--cat-changelog-sticky-top); }
.changelog__content-item,
.changelog__anchor { scroll-margin-top: var(--cat-changelog-sticky-top); }

/* @include media(laptop) → do 1479.98px: prowadnica i kropka odjeżdżają w lewo. */
@media (max-width: 1479.98px) {
  .changelog__content::before { margin-left: -19px; }
  .changelog__dot { left: -86px; }
}
/* @include media(tablet) → do 1023.98px: SPIS WERSJI ZNIKA CAŁY, prowadnica
   wraca do zera, kropka podjeżdża. */
@media (max-width: 1023.98px) {
  .changelog__versions { display: none; }
  .changelog__content::before { left: 0; }
  .changelog__dot { left: -50px; }
}
/* @include media(mobile) → do 767.98px: prowadnica i kropki znikają wcale,
   tytuł wpisu przechodzi w kolumnę ODWRÓCONĄ (data nad wersją), pas pytania
   staje się kolumną, a przycisk dostaje sztywne 200 px. */
@media (max-width: 767.98px) {
  .changelog__content::before { content: none; }
  .changelog__content { margin-left: 0; }
  .changelog__dot { display: none; }
  .changelog__title { align-items: flex-start; flex-direction: column-reverse; }
  .box-content > div ul { padding: var(--pui-changelog-title-gap); }
  .changelog__cta-banner { flex-direction: column; }
  .changelog__cta-banner .changelog__cta-banner-left { flex-direction: column; }
  .changelog__cta-banner .changelog__cta-banner-title { text-align: center; }
  .changelog__cta-banner .btn { width: 200px; }
  .changelog__cta-banner-bg { left: -550px; bottom: -478px; }
}


/* =============================================================================
   PRZEŁĄCZNIK EDYCJI, PUDEŁKO MULTI I DYMEK CENNIKA — transpozycja
   `app/components/ui/PricingSwitch.vue` (209 linii), `ui/pricing/PricingMulti.vue`
   (11 952 B) oraz bloków `scoped` i NIE-scoped strony `app/pages/prices.vue`.
   Odczyt 19.08.2026, kopia commit 1bcf0cc.

   TRZY RZECZY, KTÓRYCH KATALOG NIE MIAŁ, a strona prices je woła: przełącznik
   edycji (dwie zakładki i pigułka jeżdżąca po zmierzonym położeniu), pudełko
   MULTI z ceną liczoną z suwaka oraz dymek na zakotwiczeniu CSS.

   POŁOŻENIE PIGUŁKI NIE JEST W ARKUSZU i to jest własność kodu, nie brak
   transpozycji: komponent MIERZY aktywną zakładkę (offsetLeft/Top/Width/Height)
   i wpisuje cztery wartości w styl elementu, a klasa --ready włącza przejście
   dopiero po pierwszym pomiarze, żeby pigułka nie rozjeżdżała się z zera.

   DYMEK STOI NA ZAKOTWICZENIU CSS (anchor-name / position-anchor / popover),
   czyli na mechanizmie, którego nie ma żaden inny komponent w odczycie. Nazwa
   zakotwiczenia jest składana z INDEKSU pozycji w wywołaniu, więc w arkuszu nie
   ma jej wcale — tak samo jak w kodzie.
   ========================================================================== */

/* --- blok NIE-scoped strony: sekcje cennika przestają przycinać cienie ------ */
.section.section--pricing,
.section.section--plan-comparison { overflow-x: clip; overflow-y: visible; }

/* --- blok scoped strony ----------------------------------------------------- */
/* Wysokość banera z rodziny nakładki CENNIKA, nie z rodziny banera. */
[data-page="prices"] .banner { height: var(--pui-overlay-pricing-banner-height); }
.pricing { display: flex; flex-direction: column; align-items: center; gap: 48px; }
/* Odstęp 48 px i szerokość 720 px WPISANE WPROST, rola nie istnieje. */
.pricing-banner-actions { display: flex; flex-direction: column; align-items: center; gap: 48px; width: 100%; max-width: 720px; }
@media (max-width: 768px) { .pricing-banner-actions { gap: 24px; } }

/* --- ui/PricingSwitch.vue --------------------------------------------------- */
.pricing-switch {
  position: relative; display: flex; align-items: stretch;
  gap: var(--pui-banner-switch-gap); padding: var(--pui-banner-switch-padding);
  max-width: var(--pui-banner-switch-width-max); width: 100%;
  background: var(--pui-banner-switch-bg);
  border: 1px solid var(--pui-banner-switch-border-start);
  border-radius: var(--pui-ui-radius-rounded);
}
/* Cień pigułki WPISANY WPROST, dwie warstwy. */
.pricing-switch__pill {
  position: absolute; border-radius: var(--pui-ui-radius-rounded);
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 24px 0px rgba(0, 0, 0, 0.05);
  will-change: left, top, width, height;
}
.pricing-switch__pill--ready {
  transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1), top 0.35s cubic-bezier(0.4, 0, 0.2, 1), width 0.35s cubic-bezier(0.4, 0, 0.2, 1), height 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.pricing-switch__pill--single { background-image: linear-gradient(to bottom, var(--pui-banner-switch-primary-bg-start), var(--pui-banner-switch-primary-bg-end)); }
.pricing-switch__pill--multi { background-image: linear-gradient(to bottom, var(--pui-banner-switch-purple-bg-start), var(--pui-banner-switch-purple-bg-end)); }
.pricing-switch__tab {
  position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--pui-banner-switch-thumb-gap);
  padding: var(--pui-banner-switch-thumb-padding-v) var(--pui-banner-switch-thumb-padding-h);
  border-radius: var(--pui-ui-radius-rounded); border: none; background: transparent;
  cursor: pointer; text-align: center; transition: background-color 0.15s ease;
  font-family: inherit;
}
.pricing-switch__tab:not(.is-active):hover { background: var(--static-overlay-light-50); }
.pricing-switch__tab-title { display: block; font-size: var(--pui-text-h8-font-size); line-height: var(--pui-text-h8-line-height); font-weight: 600; color: var(--pui-text-heading); white-space: nowrap; }
.pricing-switch__tab-desc { display: block; font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); font-weight: 300; color: var(--pui-text-heading); white-space: nowrap; }
/* @include media(mobile) → do 767.98px: zakładki w kolumnie, pigułka jedzie w pionie. */
@media (max-width: 767.98px) {
  .pricing-switch { flex-direction: column; border-radius: var(--pui-ui-radius-8xl); }
  .pricing-switch__tab { width: 100%; }
  .pricing-switch__tab-title,
  .pricing-switch__tab-desc { white-space: normal; }
}

/* --- ui/pricing/PricingMulti.vue -------------------------------------------- */
.pricing-multi { display: flex; flex-direction: column; align-items: center; gap: 32px; width: 100%; }
/* Cień pudełka WPISANY WPROST, trzy warstwy — ta sama rodzina co w pudełku
   pojedynczym, ale zapis własny. Szerokość 717 px też wprost. */
.pricing-multi__box {
  display: flex; gap: var(--pui-pricing-box-gap); background: var(--pui-pricing-box-bg, #fff);
  padding: var(--pui-pricing-box-padding-v) var(--pui-pricing-box-padding-h);
  border-radius: var(--pui-pricing-box-radius); overflow: hidden;
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 25px 0px rgba(14, 13, 16, 0.04), 0px 8px 24px 6px rgba(0, 0, 0, 0.05);
  width: 100%; max-width: 717px;
}
.pricing-multi__main { display: flex; flex-direction: column; gap: var(--pui-pricing-box-main-gap); flex: 1; min-width: 0; }
.pricing-multi__header { display: flex; flex-direction: column; gap: var(--pui-pricing-box-header-gap); }
.pricing-multi__title { margin: 0; font-size: var(--pui-text-h6-font-size); line-height: var(--pui-text-h6-line-height); font-weight: 600; color: var(--pui-text-purple); width: 100%; }
.pricing-multi__subtitle { margin: 0; font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); font-weight: 300; color: var(--pui-text-body); width: 100%; }
.pricing-multi__price-section { display: flex; flex-direction: column; gap: 8px; }
.pricing-multi__price { display: flex; align-items: baseline; font-weight: 700; color: var(--pui-text-heading); letter-spacing: var(--pui-text-h2-letter-spacing); }
.pricing-multi__price-amount { font-size: var(--pui-text-h2-font-size); font-weight: 700; line-height: var(--pui-text-h2-line-height); }
.pricing-multi__price-unit { font-size: var(--pui-text-h8-font-size); font-weight: 300; color: var(--pui-text-body); letter-spacing: 0; }
.pricing-multi__price-custom { font-size: var(--pui-text-h2-font-size); font-weight: 700; line-height: var(--pui-text-h2-line-height); }
/* Plakietka ceny NIE JEST atomem odznaki: wysokość, wyściółka i promień wpisane
   wprost, a barwy czytają role odznaki purpurowej z wartością awaryjną. */
.pricing-multi__label {
  display: inline-flex; align-items: center; justify-content: center; height: 32px;
  padding: 4px 12px; border-radius: 999px;
  background: var(--pui-label-purple-faded-bg, #efe7fe);
  font-size: var(--pui-text-p-base-font-size); font-weight: 600;
  color: var(--pui-label-purple-faded-fg, #6a32e0); white-space: nowrap; align-self: flex-start;
}
.pricing-multi__btn { width: 100%; min-width: unset; }
.pricing-multi__features { display: flex; flex-direction: column; gap: var(--pui-pricing-box-features-gap); flex: 1; min-width: 0; justify-content: center; }
.pricing-multi__divider { height: 1px; background: var(--pui-pricing-box-divider); width: 100%; }
.pricing-multi__feature { display: flex; align-items: center; gap: var(--static-space-1x); width: 100%; cursor: default; }
.pricing-multi__feature:hover .pricing-multi__feature-help { color: var(--pui-text-purple); }
.pricing-multi__feature-star { flex-shrink: 0; color: var(--pui-text-purple); }
.pricing-multi__feature-text { margin: 0; font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); font-weight: 300; color: var(--pui-text-heading); white-space: nowrap; }
.pricing-multi__feature-text b { font-weight: 600; }
/* Barwa znaku zapytania WPISANA WPROST (#4D4D5C), poza paletą. */
.pricing-multi__feature-help { flex-shrink: 0; display: flex; align-items: center; color: #4D4D5C; transition: color 0.15s ease; }
.pricing-multi__footer { display: flex; align-items: center; justify-content: center; gap: 8px; }
.pricing-multi__footer-star { color: var(--pui-text-primary); flex-shrink: 0; }
.pricing-multi__footer-text { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); color: var(--pui-text-body); }
.pricing-multi__footer-text b { font-weight: 600; color: var(--pui-text-primary); }
/* PRÓG 540 px — JEDYNY W CAŁYM ODCZYCIE spoza rodziny 768/1024/1480, z odsyłaczem
   do węzła Figmy w komentarzu kodu. */
@media (max-width: 540px) {
  .pricing-multi__box { flex-direction: column; gap: var(--pui-pricing-box-main-gap, 16px); max-width: 360px; }
  .pricing-multi__feature-text { white-space: normal; }
}

/* --- dymek cennika: zakotwiczenie CSS + popover ----------------------------- */
.pricing-tooltip {
  position: fixed; inset: unset; margin: 0; border: none;
  top: calc(anchor(bottom) + 12px); left: calc(anchor(center) - 35px);
  overflow: visible; max-width: var(--pui-tooltip-width-max);
  background: var(--pui-tooltip-bg); border-radius: var(--pui-tooltip-radius);
  padding: var(--pui-tooltip-padding-v) var(--pui-tooltip-padding-h);
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 24px 0px rgba(0, 0, 0, 0.02), 0px 8px 32px 0px rgba(0, 0, 0, 0.08);
  opacity: 0; transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.pricing-tooltip:popover-open { opacity: 1; transform: translateY(0); }
.pricing-tooltip__arrow { position: absolute; top: -8px; left: 27px; display: block; overflow: visible; filter: drop-shadow(0px -2px 2px rgba(0, 0, 0, 0.06)); }
.pricing-tooltip__text { margin: 0; font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); font-weight: 300; color: var(--pui-text-body); }


/* =============================================================================
   SUWAK LICZBY STRON — transpozycja `app/components/ui/pricing/PricingSlider.vue`
   (blok scoped, linie 70-240). Odczyt 19.08.2026, kopia commit 1bcf0cc.

   DOPISANE PO UWADZE PAWŁA Z 19.08: komponent katalogu rysował suwak STYLAMI
   W ATRYBUCIE, na własnych rolach `--src-slider-*`, zamiast klasami z kodu
   (PR-10). Wygląd był zgodny, nośnik nie: strona nie dała się porównać z kodem
   po nazwach, a jedna deklaracja z arkusza produktu nie miała gdzie stanąć —
   dwie reguły gaszące NATYWNY uchwyt suwaka (`::-webkit-slider-thumb`,
   `::-moz-range-thumb`), których w stylu w atrybucie zapisać się nie da.

   POŁOŻENIE UCHWYTU IDZIE JEDNĄ ZMIENNĄ: `--thumb` na `.pricing-slider__inner`,
   tak jak w kodzie (`:style="{ '--thumb': …%}"`). Czytają ją cztery reguły —
   wypełnienie toru, dymek, cena i sam uchwyt — więc pozycja jest w jednym
   miejscu, a nie w czterech stylach.

   Wartości są LITERAŁAMI, bo literałami są w kodzie: 720/121/10/12/20 px,
   -66 px dymka, 34 px ceny, 31 px uchwytu, 91 px poświaty, pół piksela
   przesunięcia w `top: calc(50% - 0.5px)`. Katalogowe role `--src-slider-*`
   przestają być czytane przez komponent i zostają jako zapis pomiaru — tą samą
   drogą co role banera poziomego w RZ-90. Nadal czyta je znacznik osadzeń
   (`--src-slider-height`, `--src-slider-max-width` w rozmiarach zastępczych).
   ========================================================================== */

.pricing-slider { position: relative; box-sizing: border-box; width: 100%; max-width: 720px; height: 121px; padding: 10px; user-select: none; font-family: var(--static-typography-font-family), system-ui, sans-serif; }
/* @media (max-width: 768px) — próg WPISANY WPROST w kodzie, spoza rodziny mixinów. */
@media (max-width: 768px) { .pricing-slider { max-width: 100%; } }
.pricing-slider__inner { position: absolute; left: 10px; right: 10px; height: 12px; top: calc(50% + 11.5px); transform: translateY(-50%); }
.pricing-slider__shape { position: relative; height: 12px; border-radius: 20px; overflow: hidden; }
.pricing-slider__bg { position: absolute; inset: 0; border-radius: 20px; background: rgba(255, 255, 255, 0.15); }
.pricing-slider__fill {
  position: absolute; top: 0; left: 0; height: 100%; width: var(--thumb); border-radius: 20px;
  background: linear-gradient(270deg, var(--pui-pricing-slider-fg-end, #8253e5) 0%, var(--pui-pricing-slider-fg-start, #b48fef) 100%);
}
.pricing-slider__tooltip {
  position: absolute; top: -66px; left: var(--thumb); transform: translateX(-50%);
  background: var(--pui-tooltip-bg, white); border-radius: var(--pui-tooltip-radius, 8px);
  padding: var(--pui-pricing-slider-tooltip-padding-v, 6px) var(--pui-pricing-slider-tooltip-padding-h, 8px);
  white-space: nowrap;
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 24px 0px rgba(0, 0, 0, 0.02), 0px 8px 32px 0px rgba(0, 0, 0, 0.08);
}
.pricing-slider__tooltip-text { display: block; font-size: var(--pui-text-p-lg-font-size); line-height: var(--pui-text-p-lg-line-height); font-weight: 600; color: var(--pui-text-purple); white-space: nowrap; }
.pricing-slider__tooltip-arrow { position: absolute; bottom: -8px; left: 50%; transform: translateX(-50%); display: block; }
.pricing-slider__price {
  position: absolute; top: calc(50% + 34px); left: var(--thumb); transform: translate(-50%, -50%);
  white-space: nowrap; font-size: var(--pui-text-p-lg-font-size); line-height: var(--pui-text-p-lg-line-height);
  font-weight: 600; color: var(--pui-text-heading);
}
/* Pół piksela nad środkiem toru — zmierzone przy przejeździe 10.08 (PA-28). */
.pricing-slider__thumb { position: absolute; top: calc(50% - 0.5px); left: var(--thumb); transform: translate(-50%, -50%); width: 31px; height: 31px; pointer-events: none; }
.pricing-slider__thumb-glow {
  position: absolute; top: -22px; left: -30px; width: 91px; height: 91px; border-radius: 50%;
  background: radial-gradient(circle at center, rgba(106, 50, 224, 0.4) 0%, rgba(106, 50, 224, 0.2) 28%, rgba(106, 50, 224, 0) 68%);
}
.pricing-slider__thumb-dot {
  position: absolute; inset: 0; border-radius: 31px; background: var(--pui-pricing-slider-tooltip-bg, #fff);
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 25px 0px rgba(14, 13, 16, 0.04), 0px 8px 24px 6px rgba(0, 0, 0, 0.05);
}
.pricing-slider__thumb-inner { position: absolute; top: 8px; left: 8px; width: 15px; height: 15px; border-radius: 15px; background: var(--pui-pricing-slider-fg-end, #8253e5); }
/* Natywny suwak leży NAD rysunkiem z zerową przezroczystością i przyjmuje całą
   obsługę przeciągania. Dwie reguły niżej gaszą jego własny uchwyt — w stylu
   w atrybucie nie miały gdzie stanąć, więc do 19.08 nie było ich w katalogu. */
.pricing-slider__input { position: absolute; top: 50%; left: 0; width: 100%; height: 40px; transform: translateY(-50%); opacity: 0; cursor: pointer; margin: 0; padding: 0; }
.pricing-slider__input::-webkit-slider-thumb { -webkit-appearance: none; width: 0; height: 0; }
.pricing-slider__input::-moz-range-thumb { width: 0; height: 0; border: none; opacity: 0; }


/* =============================================================================
   PUDEŁKO PLANU — transpozycja `app/components/ui/pricing/PricingBox.vue`
   (blok scoped, linie 161-365). Odczyt 19.08.2026, kopia commit 1bcf0cc.

   DOPISANE PO PRZEGLĄDZIE 19.08 (PR-11), tą samą drogą co suwak dzień w dzień:
   pudełko było rysowane STYLAMI W ATRYBUCIE na rolach `--src-pricing-*`, czyli
   pod nazwami, których w kodzie nie ma. Zmierzone przed zmianą: 105 węzłów ze
   stylem, 81 węzłów bez ani jednej klasy, z rodziny kodu obecna była jedna
   nazwa (`pricing-box__btn`).

   TRZY DEKLARACJE Z ARKUSZA KODU NIE MIAŁY GDZIE STANĄĆ — i to jest cena tego
   zapisu, nie estetyka:
   1. `&__feature:hover .pricing-box__feature-help { color: … }` — barwa znaku
      zapytania pod wskaźnikiem; zmierzone: przed zmianą #4D4D5C i po najechaniu
      też #4D4D5C, czyli stan zgubiony;
   2. `:deep(.btn.btn--hero):hover` → `@supports (-moz-appearance: none)` →
      `&::before { transform: scale(104%) }` — powiększenie tła wyłącznie
      w jednej rodzinie przeglądarek;
   3. cały dymek `.pricing-tooltip` z `:popover-open` i `@starting-style` —
      pudełka pokazywały IKONĘ dymka, a dymka nie miały, choć pudełko MULTI na
      tej samej stronie miało cztery działające. Ta sama ikona, raz działa, raz
      nie — niespójność wewnątrz jednej strony.

   Reguły dymka stoją wyżej, w bloku pudełka MULTI: `.pricing-tooltip` jest
   w kodzie klasą WSPÓLNĄ dla pudełka planu, pudełka MULTI i tabeli porównania.
   ========================================================================== */

.pricing-box {
  display: flex; flex-direction: column; box-sizing: border-box; flex: 1;
  gap: var(--pui-pricing-box-gap); background: var(--pui-pricing-box-bg, #fff);
  padding: var(--pui-pricing-box-padding-v) var(--pui-pricing-box-padding-h);
  border-radius: var(--pui-pricing-box-radius); overflow: hidden;
  min-width: var(--pui-pricing-box-width-min);
  box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.12), 0px 8px 25px 0px rgba(14, 13, 16, 0.04), 0px 8px 24px 6px rgba(0, 0, 0, 0.05);
  font-family: var(--static-typography-font-family), system-ui, sans-serif;
}
.pricing-box__main { display: flex; flex-direction: column; gap: var(--pui-pricing-box-main-gap); width: 100%; }
.pricing-box__header { display: flex; flex-direction: column; gap: var(--pui-pricing-box-header-gap); }
.pricing-box__title { margin: 0; font-size: var(--pui-text-h6-font-size); line-height: var(--pui-text-h6-line-height); font-weight: 600; width: 100%; }
.pricing-box__title--orange { color: var(--pui-text-orange); }
.pricing-box__title--primary { color: var(--pui-text-primary); }
.pricing-box__subtitle { margin: 0; font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); font-weight: 300; color: var(--pui-text-body); width: 100%; }
.pricing-box__price { display: flex; align-items: baseline; font-weight: 700; color: var(--pui-text-heading); letter-spacing: var(--pui-text-h2-letter-spacing); }
.pricing-box__price-free,
.pricing-box__price-amount { font-size: var(--pui-text-h2-font-size); line-height: var(--pui-text-h2-line-height); font-weight: 700; }
.pricing-box__price-unit { font-size: var(--pui-text-h8-font-size); font-weight: 300; color: var(--pui-text-body); letter-spacing: 0; }
.pricing-box__btn-wrap { position: relative; width: 100%; }
/* Powiększenie tła przycisku hero WYŁĄCZNIE w rodzinie -moz — tak w kodzie. */
@supports (-moz-appearance: none) {
  .pricing-box__btn-wrap .btn.btn--hero:hover::before { transform: scale(104%); }
}
.pricing-box__btn { width: 100%; min-width: unset; }
.pricing-box__btn-help { display: flex; align-items: center; opacity: 0.7; }
.pricing-box__features { display: flex; flex-direction: column; gap: var(--pui-pricing-box-features-gap); width: 100%; }
.pricing-box__divider { height: 1px; background: var(--pui-pricing-box-divider); width: 100%; }
.pricing-box__feature { display: flex; align-items: center; gap: var(--static-space-1x); width: 100%; cursor: default; }
/* Stan, którego styl w atrybucie nie umiał zapisać (PR-11). Barwa jest w kodzie
   ZIELONA także w pudełku pomarańczowym — przepisane jak stoi. */
.pricing-box__feature:hover .pricing-box__feature-help { color: var(--pui-text-primary); }
/* Bez wymiaru: w kodzie arkusz nadaje gniazdu tylko flex-shrink, a rozmiar
   niesie sama ikona atrybutami width/height z wywołania (PR-12). */
.pricing-box__feature-star { flex-shrink: 0; display: inline-flex; }
.pricing-box__feature-star--orange { color: var(--pui-text-orange); }
.pricing-box__feature-star--primary { color: var(--pui-text-primary); }
.pricing-box__feature-text { margin: 0; font-size: var(--pui-text-p-sm-font-size); line-height: var(--pui-text-p-sm-line-height); font-weight: 300; color: var(--pui-text-heading); white-space: nowrap; }
.pricing-box__feature-text b { font-weight: 600; }
.pricing-box__feature-help { flex-shrink: 0; display: flex; align-items: center; color: #4D4D5C; transition: color 0.15s ease; }

/* --- KOMPENSACJA NOŚNIKA — RZĄD PUDEŁEK RÓWNEJ WYSOKOŚCI (PR-13) ------------
   Zgłoszone przeglądem zamawiającego 19.08.2026: pudełka planów mają różną wysokość.
   Zmierzone: 406 | 447 | 447 px, a w produkcie wszystkie trzy są równe.

   Powód jest ten sam co przy szerokości suwaka, tylko na drugiej osi:
   `.pricing-box` ma `flex: 1` i w produkcie jest BEZPOŚREDNIM dzieckiem rzędu
   z `align-items: stretch`, więc rośnie do najwyższego. W katalogu między
   rzędem a pudełkiem stoi opakowanie osadzenia, które jest BLOKIEM: opakowanie
   rozciąga się poprawnie, a pudełko w bloku bierze wysokość własnej treści.

   Kompensacja wybiera opakowanie WARUNKIEM NA ZAWARTOŚCI, więc nie dotyka
   żadnego innego osadzenia w katalogu. Dotyczy wyłącznie nośnika; arkusz
   komponentu zostaje bez zmian, bo jego `flex: 1` jest poprawne. */
.sc-host:has(> .pricing-box) { display: flex; }

/* --- KOMPENSACJA NOŚNIKA — SZEROKOŚĆ TORU CENNIKA POJEDYNCZEGO (PR-22) ------
   Zgłoszone przeglądem 19.08.2026: pierwsze pudełko planu przycięte 34 px
   od lewej razem z napisem — tytuł zaczynał się na -9 px względem sekcji.

   TRZECI przypadek tej samej rodziny co PR-09 (szerokość suwaka) i PR-13
   (wysokość pudełek), tylko objaw wygląda inaczej. Opakowanie osadzenia jest
   BLOKIEM w kolumnie z `align-items: center`, więc nie rozciąga się do rodzica,
   tylko bierze szerokość MAX-CONTENT swojej zawartości: trzy slajdy po 304 px
   i dwie przerwy po 32 px, razem 976 px przy rodzicu 845 px. `.pricing-single`
   ma `width: 100%`, więc liczy sto procent z 976 i tor wystaje symetrycznie
   po ~33 px na obie strony, a `overflow-x: clip` sekcji obcina go z LEWEJ.
   W produkcie tor stoi równo z lewą krawędzią kontenera, bo jest bezpośrednim
   dzieckiem `.pricing`, a podgląd sąsiedniego slajdu robi przesunięcie
   biblioteki — czyli wychodzi wyłącznie z prawej.

   Warunek na zawartości, jak w PR-13; arkusz komponentu bez zmian. */
.sc-host:has(> .pricing-single) { width: 100%; min-width: 0; }


/* =============================================================================
   CENNIK POJEDYNCZY — transpozycja `app/components/ui/pricing/PricingSingle.vue`
   (blok scoped). Odczyt 19.08.2026, kopia commit 1bcf0cc, po uwadze zamawiającego —
   trzecie przepięcie ze stylów w atrybucie na klasy z repozytorium w tej sesji
   (PR-14, po suwaku PR-10 i pudełku PR-11).

   NAZWY IDĄ Z KODU CO DO ZNAKU, także te, których katalog nie rysuje:
   `.keen-slider` i `.keen-slider__slide` należą do BIBLIOTEKI, nie do produktu,
   i stoją w znaczniku obok nazw własnych. Katalog nie ładuje biblioteki, więc
   niesie sam `.pricing-single*` i mówi o tym w liście różnic.

   TRZY WARTOŚCI WPISANE WPROST W KODZIE i tak samo tutaj: odstęp 32 px kolumny
   i toru, 8 px paginacji i stopki, kropka 10 px z barwą #e8e8ef. Klasa
   `--initialized` ZERUJE odstęp toru, bo po przejęciu przez bibliotekę odstęp
   robią przesunięcia — to jedyna reguła tego arkusza, która broni przed
   PODWÓJNYM odstępem, i dlatego kadr stanu `spacingDoubled` ma sens.
   ========================================================================== */

.pricing-single { display: flex; flex-direction: column; gap: 32px; width: 100%; font-family: var(--static-typography-font-family), system-ui, sans-serif; }
/* overflow: visible ŚWIADOMIE nadpisuje domyślne ukrycie biblioteki, żeby cienie
   pudełek nie były przycięte; przycięcie w poziomie robi sekcja. */
.pricing-single__slider { width: 100%; display: flex; gap: 32px; overflow: visible; }
.pricing-single__slider--initialized { gap: 0; }
.pricing-single__slide { height: auto; display: flex; box-sizing: border-box; overflow: visible !important; }
/* ROZKŁAD SLAJDU — NAZWY KATALOGU, nie produktu (PR-17, uwaga zamawiającego 19.08).
   Arkusz kodu nie nadaje slajdowi ANI szerokości, ani rozciągania: w produkcie
   te dwie wartości wpisuje w styl elementu keen-slider, licząc je z perView
   i spacing. Katalog biblioteki nie ładuje, więc musi je skądś wziąć — i bierze
   z dwóch klas we WŁASNEJ przestrzeni nazw (przedrostek src-), żeby nie dopisać
   do rodziny produktu nazwy, której w repozytorium nie ma. Ta sama granica,
   którą postawiło PR-15: nazwa nie do znalezienia w kodzie idzie do przestrzeni
   katalogu albo nie istnieje. */
.pricing-single__slide.src-slide--fill { flex: 1 1 0; min-width: var(--pui-pricing-box-width-min); }
.pricing-single__slide.src-slide--auto { flex: 0 0 auto; min-width: var(--pui-pricing-box-width-min); }
.pricing-single__pagination { display: flex; justify-content: center; align-items: center; gap: 8px; }
/* Kropka jest PRZYCISKIEM: cursor: pointer stoi w kodzie i był poprawiony
   w katalogu 10.08 (PA-28). Barwa nieaktywnej wpisana wprost. */
.pricing-single__dot { width: 10px; height: 10px; border-radius: 50%; background: #e8e8ef; border: none; padding: 0; cursor: pointer; transition: background 0.3s ease; }
.pricing-single__dot--active { background: var(--pui-text-primary, #06a06a); }
.pricing-single__footer { display: flex; align-items: center; justify-content: center; gap: 8px; }
.pricing-single__footer-star { color: var(--pui-text-primary); flex-shrink: 0; }
.pricing-single__footer-text { font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); color: var(--pui-text-body); }
.pricing-single__footer-text b { font-weight: 600; color: var(--pui-text-primary); }


/* --- PRZYKLEJENIE NAGŁÓWKA TABELI PLANÓW ------------------------------------
   Transpozycja `app/components/ui/PlanComparisonTable.vue` (blok scoped, reguły
   przyklejenia oraz reguła nie-scoped na dole pliku). Odczyt 19.08.2026,
   po uwadze zamawiającego: w katalogu przyklejenie nie działało wcale, bo stan „stuck"
   był PODSTAWIENIEM z wejścia galerii, a nie zachowaniem (PR-18).

   MECHANIZM Z KODU MA TRZY CZĘŚCI i wszystkie trzy muszą być, żeby to działało:
   1. `.plan-comparison__block--header` jest `position: sticky; top: 0`;
   2. nad tabelą stoi CZUJKA (`__sentinel`), a obserwator przecięcia gasi ją
      przy wyjściu za górną krawędź okna — to ona, nie przewijanie, ustawia stan;
   3. gdy nawigacja produktu jest przyklejona (`body:has(.nav.is-fixed)`),
      odsunięcie rośnie do 80 px, czyli do jej wysokości.

   Reguła trzecia jest w kodzie NIE-scoped, czyli jedyna w tym pliku, która
   wychodzi poza komponent — przepisana jak stoi. */
/* CZUJKA: w kodzie ma wysokość 0 i ukrytą widoczność — obserwator przecięcia
   nie potrzebuje piksela, wystarczy mu położenie pudełka. */
.plan-comparison__sentinel { height: 0; visibility: hidden; }

/* width: 100% JEST W KODZIE (linia 359) i do 19.08 nie było go w tej regule —
   stało w atrybucie na korzeniu razem z rodziną fontu, której kod tu NIE MA
   (w produkcie font schodzi z globalnej typografii, u nas z reguły body).
   Sąsiednie komponenty cennika mają font-family w arkuszu, bo ich kod ma ją
   u siebie; ta go nie ma, więc nie dostaje jej ani arkusz, ani atrybut. */
.plan-comparison { width: 100%; display: flex; flex-direction: column; --col-min-width: 0px; }
@media (max-width: 1023.98px) { .plan-comparison { --col-min-width: 220px; } }
@media (max-width: 767.98px) { .plan-comparison { --col-min-width: 195px; } }

.plan-comparison__block {
  display: flex; flex-direction: column; overflow: hidden;
  border: 1px solid var(--pui-table-border); border-radius: var(--pui-table-radius);
  background: white;
}
.plan-comparison__block--header {
  border-radius: var(--pui-table-radius) 0 var(--pui-table-radius) var(--pui-table-radius);
  position: sticky; top: 0; z-index: 20;
}
body:has(.nav.is-fixed) .plan-comparison__block--header { top: 80px; }

/* PRZYKLEJONY NAGŁÓWEK ZMIENIA CZTERY RZECZY NARAZ, wszystkie z tej jednej
   klasy — i to jest cała odpowiedź na pytanie, dlaczego opis ma znikać
   ANIMACJĄ, a nie skokiem: wysokość opisu jedzie siatką z 1fr na 0fr, a samo
   przejście stoi w regule opisu (400 ms, cubic-bezier(0.4, 0, 0.2, 1)), nie tu.
   W katalogu te cztery wartości szły dotąd stylem w atrybucie, czyli bez
   przejścia, więc opis gasł skokiem (PR-19, uwaga zamawiającego 19.08). */
.plan-comparison__block--header-stuck {
  border-radius: 0;
  box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.12), 0 8px 24px 6px rgba(0, 0, 0, 0.05);
}
.plan-comparison__block--header-stuck .plan-comparison__plan-subtitle-wrapper { grid-template-rows: 0fr; opacity: 0; }
.plan-comparison__block--header-stuck .plan-comparison__header-main { gap: 0; }

.plan-comparison__caption {
  display: grid; grid-template-columns: repeat(var(--cap-cols, 5), 1fr);
  align-items: stretch; margin: 0 1px;
}
.plan-comparison__caption-feature {
  grid-column: 1 / span 1; min-width: 0; display: flex; align-items: center; justify-content: flex-start;
  padding: var(--pui-table-caption-padding-v) var(--pui-table-caption-padding-h);
}
.plan-comparison__caption-license {
  grid-column: 2 / var(--cap-license-end, 5); min-width: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--pui-table-bg-muted);
  border-top: 1px solid var(--pui-table-border); border-left: 1px solid var(--pui-table-border);
  border-top-left-radius: var(--pui-table-radius);
  padding: var(--pui-table-caption-padding-v) var(--pui-table-caption-padding-h);
  font-size: var(--pui-text-h8-font-size); line-height: var(--pui-text-h8-line-height);
  font-weight: 300; color: var(--pui-text-lighter); text-align: center;
}
.plan-comparison__caption-purple {
  grid-column: var(--cap-cols, 5) / span 1; min-width: 0;
  background: var(--pui-table-bg-purple); border-top-right-radius: var(--pui-table-radius);
}
@media (max-width: 767.98px) {
  .plan-comparison__caption-license, .plan-comparison__caption-purple { min-width: 195px; }
}

.plan-comparison__row { display: flex; align-items: stretch; width: 100%; }
.plan-comparison__divider { height: 1px; background: var(--pui-table-divider); width: 100%; }

/* PODŚWIETLENIE WIERSZA robi warstwa ::after na każdej komórce, gaszona
   przejściem 250 ms — w katalogu nie było jej wcale, bo styl w atrybucie nie
   umie wyrazić ani stanu :hover, ani warstwy ::after. */
.plan-comparison__cell {
  flex: 1 1 0; min-width: 0; display: flex; align-items: center;
  gap: var(--pui-table-cell-gap);
  padding: var(--pui-table-cell-padding-v) var(--pui-table-cell-padding-h);
  position: relative;
}
.plan-comparison__cell::after {
  content: ""; width: 100%; height: 100%; background: var(--pui-table-hover);
  position: absolute; top: 0; left: 0; opacity: 0; transition: opacity 0.25s ease;
}
.plan-comparison__cell svg { width: var(--pui-table-cell-icon-size); height: var(--pui-table-cell-icon-size); }
.plan-comparison__row:not(.plan-comparison__row--header):hover .plan-comparison__cell::after { opacity: 1; }
.plan-comparison__row--header:hover .plan-comparison__cell::after { content: none; }

.plan-comparison__cell--feature { background: var(--pui-table-bg-muted); justify-content: flex-start; cursor: default; }
.plan-comparison__cell--feature:hover .plan-comparison__feature-help { color: var(--pui-text-primary); }
.plan-comparison__cell--value { justify-content: center; }
@media (min-width: 768px) { .plan-comparison__cell--value { min-width: var(--col-min-width); } }
.plan-comparison__cell--purple { background: var(--pui-table-bg-muted-purple); }
.plan-comparison__cell--header-feature {
  background: var(--pui-table-bg-muted); justify-content: center;
  padding: var(--pui-table-header-padding-v) var(--pui-table-header-padding-h);
  transition: padding 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.plan-comparison__cell--header-plan {
  flex-direction: column; align-items: stretch; justify-content: space-between;
  gap: var(--pui-table-header-gap); min-width: var(--col-min-width);
  padding: var(--pui-table-header-padding-v) var(--pui-table-header-padding-h);
  transition: padding 0.4s cubic-bezier(0.4, 0, 0.2, 1), align-items 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.plan-comparison__compare-features {
  font-size: var(--pui-text-h7-font-size); line-height: var(--pui-text-h7-line-height);
  font-weight: 300; color: var(--pui-text-lighter); text-align: center;
}
.plan-comparison__header-main {
  display: flex; flex-direction: column; gap: var(--pui-table-header-main-gap);
  transition: gap 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.plan-comparison__plan-title {
  font-size: var(--pui-text-h7-font-size); line-height: var(--pui-text-h7-line-height);
  font-weight: 600; color: var(--pui-text-heading);
}
.plan-comparison__plan-subtitle-wrapper {
  display: grid; grid-template-rows: 1fr; opacity: 1;
  transition: all var(--pui-animation-slide-fade-duration) var(--pui-animation-slide-fade-easing);
}
.plan-comparison__plan-subtitle {
  font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height);
  font-weight: 300; color: var(--pui-text-lighter); min-height: 0; overflow: hidden;
}
.plan-comparison__header-footer { display: flex; flex-direction: column; gap: var(--pui-table-header-footer-gap); }
.plan-comparison__btn-wrap { position: relative; width: 100%; }
.plan-comparison__btn-wrap .btn { width: 100%; }
.plan-comparison__btn-help { display: flex; align-items: center; }
.plan-comparison__price-wrap { display: flex; flex-direction: column; gap: var(--pui-table-header-price-gap, 4px); }
.plan-comparison__price-from {
  font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height);
  font-weight: 300; color: var(--pui-text-lighter);
}
.plan-comparison__price {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--pui-table-header-price-gap);
  font-weight: 600; color: var(--pui-text-heading);
}
.plan-comparison__price-amount { font-size: var(--pui-text-h4-font-size); line-height: var(--pui-text-h4-line-height); font-weight: 600; }
.plan-comparison__price-unit {
  font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height);
  font-weight: 300; color: var(--pui-text-lighter);
}
/* CZTERY LITERAŁY BEZ ROLI, wszystkie w kodzie: odstęp 4px, wysokość 26px,
   wyściółka 4px 8px i promień 999px. Rodzina --pui-label-purple-faded-* ma
   wyłącznie barwy — zgłoszone jako RZ-93. */
.plan-comparison__price-label {
  display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 4px 8px;
  border-radius: 999px; background: var(--pui-label-purple-faded-bg); color: var(--pui-label-purple-faded-fg);
  font-size: var(--pui-text-p-xxs-font-size); line-height: var(--pui-text-p-xxs-line-height); font-weight: 600;
}
.plan-comparison__price-label svg { flex-shrink: 0; width: 12px; height: 12px; }
.plan-comparison__section-header {
  padding-top: var(--pui-table-section-header-padding-v-top);
  padding-bottom: var(--pui-table-section-header-padding-v-bottom);
}
.plan-comparison__section-header p {
  font-size: var(--pui-text-h7-font-size); line-height: var(--pui-text-h7-line-height);
  font-weight: 600; color: var(--pui-text-heading);
}
.plan-comparison__feature-name {
  flex: 1 1 0; font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height);
  font-weight: 300; color: var(--pui-text-lighter);
}
.plan-comparison__feature-help {
  flex-shrink: 0; display: inline-flex; align-items: center;
  color: var(--pui-text-icon); transition: color 0.15s ease; z-index: 1;
}
.plan-comparison__value-text {
  font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height);
  font-weight: 300; color: var(--pui-text-heading); text-align: center;
}
.plan-comparison__icon--yes { color: var(--pui-text-primary); }
.plan-comparison__icon--no { color: var(--pui-text-red); }

/* KOMÓRKA, KTÓREJ ŹRÓDŁO NIE ROZSTRZYGA — dołożone 31.08.2026 przy cenniku 2.0 (PA-50).
   Nie jest to trzeci stan produktu: produkcyjny `planComparison.json` ma wszystkie 208
   komórek wypełnionych, więc na `Widok - Prices` ta rodzina nie wchodzi nigdy. Powstała,
   bo arkusz Konrada nie przypisuje części wierszy do planów, a krzyżyk znaczyłby „tego
   w planie nie ma" — czyli mówiłby coś, czego nie wiemy.
   DYMEK NA HOVER I NA FOCUS, nie popoverem: popover produktu wymaga stanu, którego
   katalog nie umie podstawić, a to jest dymek OBJAŚNIAJĄCY BRAK DANYCH, nie odwzorowanie
   zachowania produktu. Barwy, promień, cień i szerokość z rodziny `--pui-tooltip-*`,
   ta sama, którą rysuje dymek podstawiony na dole tabeli. */
.plan-comparison__icon--unknown { color: var(--pui-text-icon); }
.plan-comparison__unknown {
  position: relative; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px;
  color: var(--pui-text-icon);
  cursor: help; transition: color 0.15s ease;
}
.plan-comparison__unknown:hover,
.plan-comparison__unknown:focus-visible { color: var(--pui-text-primary); outline: none; }
.plan-comparison__unknown-tip {
  position: absolute; bottom: calc(100% + var(--static-space-1x)); left: 50%;
  z-index: 4;
  width: max-content; max-width: var(--pui-tooltip-width-max);
  padding: var(--pui-tooltip-padding-v) var(--pui-tooltip-padding-h);
  border-radius: var(--pui-tooltip-radius);
  background: var(--pui-tooltip-bg);
  box-shadow: var(--src-table-tooltip-shadow);
  opacity: 0; visibility: hidden;
  transform: translateX(-50%) translateY(var(--static-space-0-5x));
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
  pointer-events: none;
}
.plan-comparison__unknown:hover .plan-comparison__unknown-tip,
.plan-comparison__unknown:focus-visible .plan-comparison__unknown-tip {
  opacity: 1; visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.plan-comparison__nav { display: flex; align-items: center; gap: 8px; }
.plan-comparison__nav-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--pui-button-xs-height); height: var(--pui-button-xs-height);
  border-radius: var(--pui-button-xs-radius); background: transparent;
  color: var(--pui-button-default-outline-fg); cursor: pointer;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}
.plan-comparison__nav-btn svg { width: 20px; height: 20px; }
/* Nazwa .src-nav-btn--disabled stała tu do 19.08, bo katalog rysował strzałki
   jako span i nie miał czym wyrazić stanu wyłączenia. Po PR-20 strzałki są
   przyciskami z atrybutem disabled, tak jak w kodzie, więc nazwa własna zeszła
   i stan czyta ta sama pseudoklasa co w produkcie. */
.plan-comparison__nav-btn:disabled {
  border-color: var(--pui-button-default-outline-border-disabled);
  color: var(--pui-button-default-outline-fg-disabled); cursor: not-allowed;
}


/* =============================================================================
   STRONA O NAS — cztery sekcje i ilustracja zasad. Transpozycja
   `sections/Timeline.vue`, `sections/Team.vue`, `sections/Companies.vue`,
   `sections/Location.vue` oraz `features/about-us/CorePrinciplesIllustration.vue`
   (wszystkie bloki scoped). Odczyt 20.08.2026, kopia commit 1bcf0cc.
   NAZWY KLAS BEZ ZMIAN.

   REGUŁY :deep() ZAMIENIONE NA SELEKTOR POTOMKA, tą samą drogą co przy zespole
   ikon w stopce: w płaskim arkuszu zasięg znika, więc `:deep(path)` z bloku
   zespołu i ilustracji zapisuję jako ` path`. Zawężenie do dziecka nie jest tu
   potrzebne — w obu miejscach gospodarz ma w środku jeden svg.
   ============================================================================= */

/* --- sections/Timeline.vue -------------------------------------------------- */
.timeline { width: 100%; padding: var(--pui-timeline-container-padding-v) var(--pui-timeline-container-padding-h); border-radius: var(--pui-timeline-container-radius); background: linear-gradient(180deg, var(--pui-surface-gradient-primary-start) 0%, var(--pui-surface-gradient-primary-end) 100%); position: relative; overflow: hidden; isolation: isolate; }
/* Poświata pod prowadnicą: cztery stopnie zieleni WPISANE WPROST, poza paletą. */
.timeline__bg { position: absolute; inset: 0; z-index: 0; background: radial-gradient(ellipse at 50% 50%, rgba(6, 160, 106, 1) 0%, rgba(5, 126, 84, 0.75) 25%, rgba(4, 92, 61, 0.5) 50%, rgba(2, 23, 16, 0) 100%); opacity: 0.3; pointer-events: none; }
.timeline__inner { position: relative; z-index: 1; display: flex; flex-direction: column; }
.timeline__line { position: absolute; left: 50%; top: 0; bottom: 0; transform: translateX(-50%); width: 1px; height: 100%; pointer-events: none; z-index: 0; }
.timeline__row { display: grid; grid-template-columns: 1fr 30px 1fr; align-items: center; column-gap: var(--pui-timeline-container-gap); position: relative; z-index: 1; }
/* Strona wiersza to KOLEJNOŚĆ w siatce, nie inna siatka: te same trzy kolumny,
   przestawione order-em. Data i karta wymieniają się miejscami, kropka stoi. */
.timeline__row--left .timeline__date { order: 3; text-align: left; justify-content: flex-start; }
.timeline__row--left .timeline__dot { order: 2; }
.timeline__row--left .timeline__card { order: 1; align-items: flex-end; }
.timeline__row--right .timeline__date { order: 1; text-align: right; justify-content: flex-end; }
.timeline__row--right .timeline__dot { order: 2; }
.timeline__row--right .timeline__card { order: 3; align-items: flex-start; }
.timeline__date { display: flex; align-items: center; }
/* Cień karty WPISANY WPROST (0 8px 40px rgba(0,0,0,.16)), rozmycie tła 8 px.
   Wysokość minimalna 54 px też literałem. */
.timeline__card {
  display: flex; flex-direction: column; gap: var(--pui-timeline-dates-gap);
  padding: var(--pui-timeline-dates-padding-v) var(--pui-timeline-dates-padding-h);
  border-radius: var(--pui-timeline-dates-radius);
  border: 1px solid var(--pui-timeline-border-default-start);
  background: linear-gradient(180deg, var(--pui-timeline-bg-default-start) 0%, var(--pui-timeline-bg-default-end) 100%);
  box-shadow: 0 8px 40px 0 rgba(0, 0, 0, 0.16); backdrop-filter: blur(8px);
  text-decoration: none; min-height: 54px; justify-content: center; flex: 1;
}
.timeline__card::before { background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.5) 53.37%, rgba(255, 255, 255, 0.1) 96.15%); }
/* Stan pod wskaźnikiem robi DRUGA WARSTWA, nie podmiana tła: ::after z gotowym
   gradientem gaszony przezroczystością, żeby przejście miało od czego zacząć. */
.timeline__card::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; border-radius: var(--pui-timeline-dates-radius); background: linear-gradient(180deg, var(--pui-timeline-bg-hover-start) 0%, var(--pui-timeline-bg-default-end) 100%); opacity: 0; transition: opacity 0.2s ease; pointer-events: none; }
.timeline__card:hover { border-color: var(--pui-timeline-border-hover-start); }
.timeline__card:hover::before { background: rgba(255, 255, 255, 0.30); }
.timeline__card:hover::after { opacity: 1; }
.timeline__card-version { color: var(--pui-text-primary); }
/* @include media(mobile) → do 767.98px: pismo karty i daty spada do 14 px.
   TRZY REGUŁY TEGO BLOKU NIE ROBIĄ NIC i przepisuję je świadomie w komentarzu,
   nie w kodzie: wyściółka w media(tablet) oraz wyściółka i odstęp kolumn
   w media(mobile) podstawiają TĘ SAMĄ nazwę roli, którą niesie reguła bazowa,
   a wartość zmienia się w warstwie tokenów. Zapisane jako AB-01. */
@media (max-width: 767.98px) {
  .timeline__card-version,
  .timeline__card-name { font-size: 14px; }
  .timeline__date * { font-size: 14px; }
}

/* --- sections/Team.vue ------------------------------------------------------ */
.team { display: flex; flex-wrap: wrap; gap: var(--pui-team-container-gap); }
.team__card { display: flex; flex-direction: column; flex: 1 0 0; border-radius: var(--pui-team-graphic-container-radius); overflow: hidden; text-decoration: none; position: relative; height: var(--pui-team-graphic-container-height-max); }
/* @include media(tablet) → do 1023.98px: karty schodzą pod siebie, wysokość
   500 px WPISANA WPROST. Reguła stoi w kodzie WEWNĄTRZ bloku karty, przed
   promieniem, więc kolejność deklaracji w źródle jest inna niż tu; skutek ten
   sam, bo to osobne własności. */
@media (max-width: 1023.98px) { .team__card { min-width: 100%; height: 500px; } }
.team__card:hover .team__icon path { fill: var(--pui-team-graphic-container-icon-hover); }
.team__card:hover .team__graphic::before { opacity: 1; }
.team__card:hover .team__overlay { background: linear-gradient(180deg, var(--pui-team-graphic-container-overlay-hover-start) 50%, var(--pui-team-graphic-container-overlay-hover-end) 100%); }
.team__card:hover .team__description { border-color: var(--pui-team-description-container-border-hover); background: var(--pui-team-description-container-bg-hover); }
.team__graphic { position: absolute; inset: 0; overflow: hidden; display: flex; flex-direction: column; align-items: flex-start; padding: var(--pui-team-graphic-container-padding-v) var(--pui-team-graphic-container-padding-h); background: linear-gradient(180deg, var(--pui-team-graphic-container-bg-start) 0%, var(--pui-team-graphic-container-bg-end) 100%); }
.team__graphic::before { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, var(--pui-team-graphic-container-bg-hover-start) 0%, var(--pui-team-graphic-container-bg-hover-end) 100%); opacity: 0; transition: opacity 0.3s ease; }
/* Zdjęcie ma wymiar STAŁY 426×574 px i wyłączone oba ograniczenia maksymalne —
   inaczej reguła obrazków z base/reset.scss ścisnęłaby je do szerokości karty. */
.team__photo { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 426px; height: 574px; max-width: none; max-height: none; object-fit: cover; object-position: top center; }
.team__overlay { position: absolute; inset: 0; background: linear-gradient(180deg, var(--pui-team-graphic-container-overlay-start) 50%, var(--pui-team-graphic-container-overlay-end) 100%); transition: background 0.3s ease; }
.team__icon { position: relative; z-index: 1; width: var(--pui-team-graphic-container-icon-size); height: var(--pui-team-graphic-container-icon-size); margin-left: auto; transition: color 0.3s ease; }
.team__icon path { fill: var(--pui-team-graphic-container-icon); transition: fill 0.3s ease; }
.team__description {
  display: flex; flex-direction: column; gap: var(--pui-team-description-container-gap);
  padding: var(--pui-team-description-container-padding-v) var(--pui-team-description-container-padding-h);
  border-radius: var(--pui-team-description-container-radius);
  border: var(--pui-team-description-container-border-width) solid var(--pui-team-description-container-border);
  background: var(--pui-team-description-container-bg); backdrop-filter: blur(10px);
  position: absolute; bottom: var(--pui-team-graphic-container-padding-v);
  left: var(--pui-team-graphic-container-padding-h); right: var(--pui-team-graphic-container-padding-h);
  align-self: stretch; transition: border-color 0.3s ease, background 0.3s ease;
  max-width: var(--pui-team-description-container-text-max-width); text-align: center;
}
@media (max-width: 1023.98px) { .team__description { max-width: none; } }

/* --- sections/Companies.vue ------------------------------------------------- */
.companies { display: flex; flex-wrap: wrap; gap: var(--pui-companies-gap); justify-content: center; }
/* Cień w stanie spokoju jest ZEROWY (dwie warstwy o zerowej przezroczystości) —
   jest tu tylko po to, żeby `transition: all` miał od czego animować. */
.companies__card { display: flex; align-items: center; justify-content: center; padding: var(--pui-companies-padding-v) var(--pui-companies-padding-h); border-radius: var(--pui-companies-radius); border: var(--pui-companies-border-width) solid transparent; background: var(--pui-content-block-body-primary-bg); min-width: var(--pui-companies-min-width); text-decoration: none; box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0), 0 8px 24px 6px rgba(0, 0, 0, 0); transition: all .3s ease; }
.companies__card::before { background: linear-gradient(99.28deg, #07C07E 0%, #FFFFFF 15%, rgba(7, 192, 126, 0.74) 85%, #07C07E 100%); }
.companies__card:hover { box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.12), 0 8px 24px 6px rgba(0, 0, 0, 0.05); }
/* Klasa .companies__logo stoi w znaczniku i NIE MA ANI JEDNEJ REGUŁY w kodzie —
   rozmiar znaku niesie sam plik svg. Zapisane jako AB-02, nie uzupełniam. */

/* --- sections/Location.vue -------------------------------------------------- */
.section.section--location { padding: var(--pui-location-padding-v) 0; }
/* Jedyne miejsce w odczycie, w którym STRONA przesuwa warstwę tła sekcji. */
.section.section--location .section__background { top: 61%; }
/* Karta lokalizacji ZDEJMUJE z siebie wszystko, co daje jej atom karty: tło,
   obwiednię i wyściółkę. Zostaje sam promień i przycięcie — czyli karta jest tu
   opakowaniem, nie powierzchnią. */
.location { padding: 0; border-radius: var(--pui-content-block-body-radius); background: transparent; border: none; overflow: hidden; }
.location__inner { display: flex; align-items: stretch; height: 100%; }
@media (max-width: 1023.98px) { .location__inner { flex-direction: column; } }
.location__map-wrapper { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; padding: var(--pui-content-block-illustration-container-default-padding-v) var(--pui-content-block-illustration-container-default-padding-h); border-radius: var(--pui-content-block-body-radius); border: var(--border-width) solid rgba(255, 255, 255, 0.10); background: linear-gradient(176deg, var(--pui-feature-icon-on-primary-bg-start) 3.2%, var(--pui-feature-icon-on-primary-bg-end) 97.02%); backdrop-filter: blur(10px); }
.location__map { aspect-ratio: 237/161; border-radius: var(--pui-content-block-illustration-container-default-radius); }
.location__content-inner { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; flex: 1 0 0; }
.location__content { display: flex; flex-direction: column; padding: var(--pui-section-desc-default-base-body-padding-v) var(--pui-section-desc-default-base-body-padding-h); align-items: flex-start; gap: var(--pui-section-desc-default-base-main-gap); width: 100%; }
.location__address { display: flex; flex-direction: column; font-style: normal; font-size: var(--pui-text-p-base-font-size); line-height: var(--pui-text-p-base-line-height); color: var(--pui-text-body); }

/* --- features/about-us/CorePrinciplesIllustration.vue ----------------------- */
/* Szerokość 420 px i odstęp ikony 12 px WPISANE WPROST. */
.core-principles { display: flex; flex-direction: column; justify-content: center; align-items: center; gap: var(--pui-values-gap); width: 100%; height: 100%; max-width: 420px; }
.core-principles__item { display: flex; align-items: center; gap: 12px; padding: var(--pui-values-padding-v) var(--pui-values-padding-h); border-radius: var(--pui-values-radius); border: var(--pui-values-border-width) solid transparent; background: linear-gradient(180deg, var(--pui-values-bg-default-start) 0%, var(--pui-values-bg-default-end) 100%); align-self: stretch; position: relative; }
/* Reguła na TAG w środku komponentu — nagłówek h4 z rodziny typografii. */
.core-principles__item h4 { font-weight: 600; }
.core-principles__item::before { background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.5) 59.13%, rgba(255, 255, 255, 0.1) 100%); }
.core-principles__icon { width: var(--pui-values-icon-size); height: var(--pui-values-icon-size); flex-shrink: 0; }
/* Biel ikony WPISANA WPROST (#fff), nie rolą — tak w kodzie. */
.core-principles__icon path { fill: #fff; }

/* --- blok scoped strony app/pages/about-us.vue ------------------------------
   JEDYNE MIEJSCE W REPOZYTORIUM, w którym STRONA nadpisuje blok treści
   z zewnątrz (AB-07). Cała zawartość bloku to :deep() na klasie, którą strona
   sama dokłada osadzeniu — czyli reguły należące do STRONY, nie do komponentu,
   i dlatego stoją tu, a nie w bloku sections/Feature.vue.

   Zakres zapisany atrybutem [data-page="about-us"], tą samą drogą co blok
   strony cennika: w produkcie rozdziela je scoped Vue, którego płaski arkusz
   nie ma czym zastąpić.

   CO TA STRONA ROBI KOMPONENTOWI: gasi pierścień CAŁEGO bloku (::before
   z .border-mask) i przenosi go na samą kolumnę ilustracji, przepisując tam
   maskę słowo w słowo — z tą różnicą, że gradient jedzie z rodziny ciała bloku
   treści, a nie z rodziny obwiedni. Skutek: obramowana zostaje tylko prawa
   kolumna, a lewa (tekst) traci ramkę.

   REGUŁA MARTWA, PRZEPISANA W KOMENTARZU, NIE W KODZIE (AB-08): na końcu bloku
   stoi `:deep(.feature__illustration){ &:has{ .core-principles{} } }` — `:has`
   bez argumentu i z pustym ciałem. SCSS nie wypuszcza z tego ani jednej
   deklaracji, więc w arkuszu nie ma czego zapisać; wpis istnieje, żeby nikt
   nie uznał braku za przeoczenie transpozycji. */
[data-page="about-us"] .about-us-feature::before { content: none; }
[data-page="about-us"] .about-us-feature .feature__slot-right { position: relative; border-radius: var(--pui-content-block-body-radius); }
[data-page="about-us"] .about-us-feature .feature__slot-right::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
  background: linear-gradient(-234.25deg, var(--pui-content-block-body-primary-border-start) 0%, var(--pui-content-block-body-primary-border-end) 15%, var(--pui-content-block-body-primary-border-end) 85%, var(--pui-content-block-body-primary-border-start) 100%);
}

/* --- KOMPENSACJA NOŚNIKA — GNIAZDO ILUSTRACJI Z WŁASNYM KORZENIEM (AB-11) ---
   Zgłoszone przeglądem 20.08.2026. W kodzie `Feature.vue` wstawia treść gniazda
   #feature-illustration WPROST do `.feature__illustration`, a przy tym wywołaniu
   treścią jest komponent z własnym korzeniem (`.core-principles`, max-width
   420 px). Katalog stawia między nimi `.graphic` — element, który przy warstwach
   rysunku jest potrzebny (siatka jednokomórkowa dla warstw), a przy gnieździe
   z własnym korzeniem jest elementem, którego produkt tu NIE MA.

   Zmierzone przy 924 px: lista zasad zaciśnięta do 284 px zamiast 420 px, bo
   `.graphic` niesie max-width z roli gniazda ilustracji
   (--pui-content-block-illustration-container-default-slot-max-size), która na
   progu tabletu spada do 284 px. Na progu biurkowym różnicy nie widać (558 px
   jest większe od 420 px) i dlatego przy złożeniu nie wyszło.

   Kompensacja wybiera opakowanie WARUNKIEM NA ZAWARTOŚCI, tak jak PR-13 i PR-22:
   `display: contents` znosi sam element, więc korzeń treści gniazda staje się
   dzieckiem `.feature__illustration` — dokładnie jak w kodzie. Dotyczy wyłącznie
   nośnika katalogu; arkusz komponentu zostaje bez zmian, bo jego `.graphic` jest
   poprawny dla warstw. */
.graphic:has(> .core-principles) { display: contents; }

/* DRUGA POŁOWA TEJ SAMEJ KOMPENSACJI, zgłoszona przeglądem 20.08.2026 —
   `display: contents` ZNOSI PUDEŁKO, NIE ZASIĘG SELEKTORA. `.graphic` znika
   z układu, ale zostaje w drzewie, więc reguła potomka z bloku globalnego
   FeatureIllustration.vue (`.graphic:not(.graphic--sm) svg { width:100%;
   height:100% }`, swoistość 0,2,1) dalej sięga do ikon komponentu i wygrywa
   z `.core-principles__icon` (0,1,0).

   Zmierzone przy 1461 px: ikona 356×356 px przy roli mówiącej 28 px — rysunek
   16×16 rozdmuchany do szerokości karty. Objaw jest widoczny gołym okiem
   i mimo to przeszedł przez pierwszą kompensację, bo tamta naprawiała SZEROKOŚĆ
   LISTY i po niej lista wyglądała poprawnie.

   Deklaracje są POWTÓRZONE Z TYCH SAMYCH RÓL, nie dobrane — to przywrócenie
   reguły komponentu, nie nowy pomiar. W kodzie ta reguła nie ma z czym
   przegrywać, bo `.graphic` tam nie istnieje. */
.graphic:has(> .core-principles) .core-principles__icon {
  width: var(--pui-values-icon-size); height: var(--pui-values-icon-size);
}


/* =============================================================================
   OBWIEDNIE BEZ POŚWIATY — ROZSTRZYGNIĘCIE GLOBALNE, 24.08.2026
   Brzmienie zamawiającego: „usun poswiaty z borderow, globalnie, we wszystkich komponentach
   i elementach". Zgłoszone na karcie newslettera, ale dotyczy CAŁEJ rodziny.

   CO TO GASI: pomocnik `.border-mask` rysuje obwiednię pseudoelementem i każdy
   komponent podstawiał tam własny GRADIENT — zieleń i pomarańcz wjeżdżające w narożniki,
   czyli to, co widać jako poświatę na krawędzi. Zmierzone: dziewięć takich gradientów
   (karta, karta newslettera, karta purpurowa, FAQ, roadmapa, changelog, przycisk hero
   i dwa jego stany). Wszystkie schodzą do JEDNEJ płaskiej barwy.

   DLACZEGO TU, NA KOŃCU ARKUSZA, I Z `!important`: reguły komponentów mają wyższą
   specyficzność (`.card--newsletter.border-mask::before`), więc bez tego wygrywałyby
   dalej. To jest świadome nadpisanie rozstrzygnięciem, nie obejście — i stoi w jednym
   miejscu, żeby dało się je zdjąć jedną linią, gdy decyzja się zmieni.

   BARWA: `--pui-form-border`, czyli rola płaskiej obwiedni, której używają pola
   formularza. Neutralny koniec kasowanych gradientów miał #D9D9E3, czyli ten sam stopień.

   CZEGO NIE RUSZAM I DLACZEGO: pierścieni `:focus-visible` na przyciskach i polach —
   to nie ozdoba, tylko widoczność klawiatury; oraz cieni pudełek (`box-shadow` z rozmyciem
   pod kartami), bo to cień, nie obwiednia. Jeśli mają zejść, to osobna decyzja. */
/* JEDEN SZARY NA WSZYSTKIE OBWIEDNIE (polecenie zamawiajacego 24.08.2026: „ustaw solidny szary
   kolor, spojny wszedzie"). `background-image: none` jest tu KONIECZNE, nie ozdobne: skrot
   `background` w regulach komponentow niesie gradient jako OBRAZ tla, wiec ustawienie samej
   barwy zostawialo gradient na wierzchu. Dlatego poprzednia poprawka nie dawala skutku. */
/* SELEKTOR WYLICZA MIEJSCA, KTORE MIALY GRADIENT, i to jest POPRAWKA z 24.08.2026
   (zgloszenie zamawiajacego przy pasie opinii: „tutaj co sie rozjebalo? skad te dodatkowe border
   radiusy i paddingi sie zwiely?"). Pierwszy zapis bral SAMO `.border-mask::before`,
   czyli wszystko, co niesie ten pomocnik — a pomocnik rysuje TYLKO MASKE, bez tla, i
   barwe dostaje dopiero od reguly komponentu. Skutek: pudelka, ktore obwiedni NIE MIALY,
   dostaly ja z niczego. Zmierzone na slajdzie opinii — gradient stoi w
   `.testimonial__slide--active ...`, wiec pierscien nalezy do slajdu ROZWINIETEGO,
   a zwiniete slajdy dostaly obrys, ktorego w projekcie nigdy nie bylo.
   REGULA OGOLNA NIE NADAJE SIE DO GASZENIA CZEGOS, CO STOI TYLKO W CZESCI RODZINY. */
/* KARTA „LATEST UPDATES" jest w tym wyliczeniu (zgłoszenie zamawiającego 24.08.2026: „tutaj tez
   usun te kolorowe bordery"). Ma DWIE obwiednie naraz — płaską `border` 1 px i drugą,
   rysowaną maską; gradient ze środkiem #07C07E siedział w tej drugiej. Gaszony jest sam
   gradient, płaska krawędź zostaje.
   PUŁAPKA ZMIERZONA TU 24.08.2026: komentarz postawiony W ŚRODKU listy selektorów
   sprawił, że przeglądarka odrzuciła CAŁĄ regułę — w `document.styleSheets` jej nie było,
   a gradient stał dalej. Komentarze do wyliczenia stoją NAD nim, nigdy między selektorami. */
.faq__card.border-mask::before,
.feature--default::before,
.feature--default-purple::before,
.card.border-mask::before,
.card--newsletter.border-mask::before,
.card--purple.border-mask::before,
.roadmap__outer.border-mask::before,
.changelog.border-mask::before,
.latest-updates__card::before,
.btn--hero-outline.border-mask::before,
.btn--hero-outline.border-mask:hover::before,
.btn--hero-outline.border-mask:active::before,
.testimonial__slide--active .testimonial__slide-inner.border-mask::before { background-image: none !important; background-color: var(--pui-panel-border) !important; }
/* Rama SZKLA (`.section__frame`) ma WLASNY pseudoelement z gradientem, poza rodzina
   `.border-mask` — bez tej linii roadmapa i changelog zostawaly z kolorowa obwiednia. */
.section__frame::before { background-image: none !important; background-color: var(--pui-panel-border) !important; }
/* PRZYCISK HERO MA WŁASNĄ, DELIKATNĄ OBWIEDNIĘ (zgłoszenie zamawiającego 24.08.2026 przy banerze:
   „ustaw delikatny border z opacity dla tego buttona"). Jeden szary jest dobry dla pudełek
   na powierzchni strony, ale nie dla pomarańczowego przycisku: pełna barwa daje obrys
   twardszy niż samo tło przycisku. Rola `--pui-hero-button-solid-border-start` to biel
   na 30% (overlay-light-300) — czyli obwiednia PRZEZ przezroczystość, ta sama, którą
   rodzina hero ma po jasnej stronie. Płaska, bez gradientu, więc poz. 18 zostaje spełniona. */
.btn--hero.border-mask::before { background-image: none !important; background-color: var(--pui-hero-button-solid-border-start) !important; }
/* SWIATLO W OBWIEDNI SZKLANYCH WARSTW I RAM — TRZY OSTATNIE MIEJSCA Z TĄ SAMĄ RODZINĄ
   GRADIENTU (polecenie zamawiającego 24.08.2026: „usun swiatla czy gradient. z tych borderow").
   Zmierzone w renderze mockupu (przegląd pseudoelementów): po poprzednich poprawkach
   został DOKŁADNIE JEDEN widoczny gradient w obwiedni — szklane karty w tle sekcji CTA
   (`.section__background-layer--left/right--2::after`), trzy nałożone gradienty bieli
   0,5 / 0,6 / 0,2 gasnące w 5%, czyli ROZBŁYSK W DWÓCH NAROŻNIKACH. To jest właśnie
   „światło na borderze": nie poświata sekcji, tylko krawędź pudełka.
   Dwa pozostałe miejsca tej samej rodziny (rama ilustracji banera i plakietka hero) są
   dziś w mockupie wygaszone, więc na ekranie ich nie było — ale niosą ten sam gradient,
   a zakaz z poz. 18 jest globalny, nie „w tym kadrze".
   BARWA: rola `--pui-panel-border` (od 24.08.2026, decyzja zamawiającego — wariant A). Wszystkie
   trzy miejsca leżą w `[data-context="on-dark"]`, więc rola wskazuje biel 10% — tę samą,
   którą bierze kafel pasa funkcji i pudełka na ciemnym banerze.
   RODZINA PLAKIETKI HERO MA DWA WARIANTY Z WŁASNYM GRADIENTEM, nie jeden — `--default`
   (biel 5% → 15%) i `--primary` (zielony 047E55 → 36D2A5 → 047E55, rozjaśnienie w środku
   krawędzi). Policzone wyrażeniem `\.badge--hero\.badge--[a-z-]+::before`: dokładnie dwa,
   oba w wyliczeniu. Pierwszy zapis miał tylko `--default` i zielona plakietka „25x Faster
   than cPanel" w sekcji CTA została z gradientem — złapał to przegląd, nie ja.
   BŁĄD POMIARU, KTÓRY TO PRZEPUŚCIŁ, i to jest ważniejsze od samej poprawki: oba moje
   sprawdzenia filtrowały gradienty po BARWIE (`255, 255, 255, 0.[2-9]`), więc gradient
   ZIELONY był poza filtrem i pomiar zwrócił „zero". Kolor nie jest częścią definicji
   usterki — szuka się słowa `gradient` w `background-image` pseudoelementu z maską
   content-box, bez warunku na barwę.
   CIEŃ SZKLANYCH KART ZOSTAJE (0 47px 52px rgba(5,109,72,.07)) — cień nie jest obwiednią,
   granica z poz. 18. */
.section__background-layer--left--2::after,
.section__background-layer--right--2::after,
.banner--vertical .banner__illustration-frame::before,
.badge--hero.badge--default::before,
.badge--hero.badge--primary::before { background-image: none !important; background-color: var(--pui-panel-border) !important; }
/* KAFEL PASA FUNKCJI — OBWIEDNIA BIAŁA Z PRZEZROCZYSTOŚCIĄ (zgłoszenie zamawiającego 24.08.2026:
   „bordery w tych boxach biale z opacity, jakies 10%"). Ta sama rodzina rozwiązania co
   przy przycisku hero: pudełko stoi na CIEMNYM tle, więc obwiednia ma być rozjaśnieniem
   powierzchni, nie osobną szarą linią.
   OD 24.08.2026 STOI TU ROLA, NIE SKALA (decyzja zamawiającego, wariant A): `--pui-panel-border`.
   Kafel leży w `[data-context="on-dark"]` — zmierzone — więc rola wskazuje dokładnie tę
   samą biel 10% (#FFFFFF1A), a wpis przestaje być wartością przypisaną jednemu kaflowi. */
.feature-card.border-mask::before { background-image: none !important; background-color: var(--pui-panel-border) !important; }

/* KAFEL PASA FUNKCJI — NADPISANIE ZDJĘTE 24.08.2026 (zgłoszenie zamawiającego przy pasie
   „Developer Toolkit": „tutaj sie cos wyjbeało bo te boxy miały tło i shadow, border jest
   za mocny"). Poprzednia tura zgasiła tu tło gradientowe I cień, szukając poświaty — a to
   był ZA SZEROKI zamach: zakaz z poz. 18 dotyczy KRAWĘDZI pudełka, nie jego powierzchni
   ani cienia. Kafel wraca do reguły z linii 2019: gradient tła, cień 0 8px 40px #00000029,
   biała maska w ::before. Poświaty na krawędzi już nie ma, bo obwiednię wszystkich pudełek
   spłaszcza reguła wyżej — i to ona, po zmianie na rolę `--pui-form-border`, ściszyła
   „za mocny" border: na ciemnym tle rola wskazuje gray-700, nie gray-200. */
