/**
 * Theme Name: Blocksy Child
 * Description: Blocksy Child theme
 * Author: Creative Themes
 * Template: blocksy
 * Text Domain: blocksy
 */

/* op:head:806ccc38 — design system skupgastro.pl, zbudowany 2026-08-25 21:57
   Zrodlo: web/design/. NIE EDYTOWAC TUTAJ — zmiany gina przy nastepnym buildzie.
   Odtworzenie: python3 narzedzia/css.py --print */

/* ---- tokens.css ---- */
/* ============================================================
   skupgastro.pl — tokeny świata „tablica cieni"
   Kierunek a21ecf54, przyjęty 2026-08-21. Źródło: KIERUNEK-2026-08-21.md
   Materiał: dwuwarstwowa pianka narzędziowa (wierzch antracyt, spód cynober),
   chrom narzędzia, chłodna biel dokumentu.
   ============================================================ */

:root {
  /* --- pianka: ground i frez --- */
  --op-pianka: #16181A;
  --op-pianka-2: #202427;
  --op-pianka-3: #2B3034;
  --op-frez: #0E1012;

  /* --- spód pianki: to, co zostaje po zabranym narzędziu --- */
  --op-gniazdo: #D6350F;                /* pole, nigdy tekst 4,5:1 na ciemnym */
  --op-gniazdo-ciemny: #A82709;         /* tekst akcentowy na jasnym: 6,52:1 */
  --op-gniazdo-jasny: #FF6B3D;          /* tekst akcentowy na ciemnym: 6,49:1 */
  --op-gniazdo-mglisty: rgba(214, 53, 15, 0.14);

  /* --- biel: pełna i na polu cynobrowym --- */
  --op-biel: #fff;
  --op-biel-88: rgba(255, 255, 255, 0.88);
  --op-biel-55: rgba(255, 255, 255, 0.55);
  --op-biel-12: rgba(255, 255, 255, 0.12);

  /* --- metal --- */
  --op-metal: #C9CFD4;
  --op-metal-cien: #8A9299;

  /* --- dokument --- */
  --op-papier: #F4F5F6;
  --op-papier-2: #E4E7E9;
  --op-tusz: #14171A;
  --op-tusz-2: #4A5158;

  /* --- taśma ostrzegawcza, oszczędnie --- */
  --op-tasma: #E8B923;

  /* --- role tekstu na piance --- */
  --op-tekst: #EDEFF1;
  --op-tekst-2: #A7AFB6;
  --op-tekst-3: #8A9299;   /* 4,55:1 na piance-2 — próg AA dla drobnego tekstu */

  /* --- kreska: jedna gramatyka na cały system --- */
  --op-kreska: 1px;
  --op-kreska-2: 2px;
  /* Kant frezu: krawędź komponentu widoczna na swoim podłożu.
     zmierzone 3,8:1 na piance i 3,5:1 na papierze — próg WCAG 1.4.11 dla
     elementów interaktywnych. Kontrast tekstu tego nie zapewnia. */
  --op-kant: #6A737A;
  --op-kant-papier: #767E85;

  --op-linia: rgba(201, 207, 212, 0.16);
  --op-linia-mocna: rgba(201, 207, 212, 0.32);
  --op-linia-papier: rgba(20, 23, 26, 0.14);
  --op-obrys-karty: rgba(20, 23, 26, 0.16);

  /* --- ziarno pianki: splot wierzchniej warstwy --- */
  --op-ziarno-jasne: rgba(255, 255, 255, 0.014);
  --op-ziarno-ciemne: rgba(0, 0, 0, 0.16);

  /* --- promień: frez ma stały promień narzędziowy --- */
  --op-r-frez: 10px;
  --op-r-pole: 4px;
  --op-r-plytka: 2px;
  --op-r-pigulka: 999px;

  /* --- przestrzeń --- */
  --op-p1: 4px;
  --op-p2: 8px;
  --op-p3: 12px;
  --op-p4: 16px;
  --op-p5: 24px;
  --op-p6: 32px;
  --op-p7: 48px;
  --op-p8: 64px;
  --op-p9: 96px;

  /* --- siatka --- */
  --op-max: 1280px;
  --op-max-tekst: 68ch;
  --op-rynna: var(--op-p6);
  --op-margines: var(--op-p5);

  /* --- typografia: Archivo, osie wght + wdth --- */
  --op-font: "Archivo", "Archivo Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;

  --op-t-display: clamp(2.5rem, 1.5rem + 3.4vw, 4.25rem);
  --op-t-display-wpis: clamp(2rem, 1.3rem + 2.4vw, 3.25rem);
  --op-t-h2: clamp(1.9rem, 1.15rem + 2.9vw, 3rem);
  --op-t-h3: clamp(1.25rem, 1.05rem + 0.8vw, 1.5rem);
  --op-t-lead: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  --op-t-tytul: 1.125rem;
  --op-t-pole: 1rem;
  --op-t-body: 1.0625rem;
  --op-t-maly: 0.9375rem;
  --op-t-nav: 0.875rem;
  --op-t-etykieta: 0.8125rem;

  --op-tr-display: -0.035em;
  --op-tr-h2: -0.025em;
  --op-tr-etykieta: 0.1em;

  --op-lh-display: 0.94;
  --op-lh-naglowek: 1.08;
  --op-lh-tekst: 1.62;

  /* --- elewacja: jeden poziom, z offsetem i rozmyciem --- */
  --op-cien: 0 18px 44px -12px rgba(0, 0, 0, 0.66);
  --op-cien-plytki: 0 6px 18px -8px rgba(0, 0, 0, 0.5);

  /* --- ruch: jeden zorkiestrowany gest --- */
  --op-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --op-czas: 520ms;
  --op-czas-krotki: 180ms;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --op-czas: 1ms;
    --op-czas-krotki: 1ms;
  }
}

/* ---- base.css ---- */
/* ============================================================
   base — reset, typografia, siatka. Wszystko pod .op-swiat,
   żeby chrome Blocksy nie dostał tych reguł przypadkiem.
   ============================================================ */

.op-swiat {
  font-family: var(--op-font);
  font-size: var(--op-t-body);
  line-height: var(--op-lh-tekst);
  color: var(--op-tekst);
  background: var(--op-pianka);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

/* Reset przez :where() — zerowa specyficzność, żeby reguły odstępów
   w komponentach nie przegrywały z resetem. */
.op-swiat :where(p, ul, ol, h1, h2, h3, h4, figure, table) { margin: 0; }

.op-swiat img,
.op-swiat svg { max-width: 100%; display: block; }

/* Kreska obrysu ma trzymać grubość niezależnie od skali gniazda. Reguła stała
   kiedyś w `<defs><style>` sprite'a, ale `<style>` jest na liście bloków
   wpautop: WordPress wstawiał przed nim `</p>` i rozbijał całe SVG. */
[data-op="obrysy"] symbol :is(path, rect, circle, line, polyline) {
  vector-effect: non-scaling-stroke;
}

/* --- rampa typograficzna --- */

.op-swiat h1,
.op-h1 {
  font-size: var(--op-t-display);
  font-weight: 800;
  font-stretch: 112%;
  line-height: var(--op-lh-display);
  letter-spacing: var(--op-tr-display);
  text-wrap: balance;
}

.op-swiat h2,
.op-swiat .op-h2,
.op-h2 {
  font-size: var(--op-t-h2);
  font-weight: 700;
  font-stretch: 108%;
  line-height: var(--op-lh-naglowek);
  letter-spacing: var(--op-tr-h2);
  text-wrap: balance;
}

.op-swiat h3,
.op-swiat .op-h3,
.op-h3 {
  font-size: var(--op-t-h3);
  font-weight: 700;
  line-height: 1.24;
  letter-spacing: -0.012em;
}

.op-lead {
  font-size: var(--op-t-lead);
  line-height: 1.5;
  color: var(--op-tekst-2);
  max-width: 54ch;
}

.op-proza { max-width: var(--op-max-tekst); }
.op-proza p + p { margin-top: var(--op-p4); }
.op-proza > * + h2 { margin-top: var(--op-p8); }
.op-proza > * + h3 { margin-top: var(--op-p6); }
.op-proza h2 + *,
.op-proza h3 + * { margin-top: var(--op-p3); }

/* Etykieta gniazda — wyłącznie w tablicy i tabelach, nigdy nad nagłówkiem. */
.op-etykieta-gniazda {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-tekst-3);
}

/* --- siatka --- */

.op-obszar {
  width: 100%;
  max-width: var(--op-max);
  margin-inline: auto;
  padding-inline: var(--op-margines);
}

/* Tło sekcji jako zmienna: komponenty, które muszą wyciąć w sobie przerwę
   (numer kroku na linii), potrzebują koloru podłoża, nie zgadywania. */
.op-sekcja { --op-tlo-sekcji: var(--op-pianka); padding-block: var(--op-p9); }
.op-sekcja--ciasna { padding-block: var(--op-p8); }

.op-sekcja--dokument {
  --op-tlo-sekcji: var(--op-papier);
  background: var(--op-papier);
  color: var(--op-tusz);
}
.op-sekcja--dokument .op-lead { color: var(--op-tusz-2); }
.op-sekcja--dokument .op-etykieta-gniazda { color: var(--op-tusz-2); }

/* --- akcje --- */

.op-akcja {
  display: inline-flex;
  align-items: center;
  gap: var(--op-p3);
  min-height: 56px;
  padding-inline: var(--op-p6);
  border: 0;
  border-radius: var(--op-r-pole);
  background: var(--op-gniazdo);
  color: var(--op-biel);
  font: inherit;
  font-size: var(--op-t-body);
  font-weight: 700;
  font-stretch: 104%;
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--op-czas-krotki) var(--op-ease);
}
.op-akcja:hover { background: var(--op-gniazdo-ciemny); }

.op-akcja--druga {
  background: transparent;
  color: var(--op-tekst);
  border: var(--op-kreska-2) solid var(--op-linia-mocna);
}
.op-akcja--druga:hover {
  background: var(--op-pianka-2);
  border-color: var(--op-metal-cien);
}

.op-sekcja--dokument .op-akcja--druga {
  color: var(--op-tusz);
  border-color: var(--op-linia-papier);
}
.op-sekcja--dokument .op-akcja--druga:hover {
  background: var(--op-papier-2);
  border-color: var(--op-tusz-2);
}

/* --- focus: jedna reguła na cały świat --- */

.op-swiat :focus-visible {
  outline: 3px solid var(--op-tasma);
  outline-offset: 3px;
  border-radius: var(--op-r-plytka);
}

/* --- łącza w prozie --- */

.op-proza a {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  text-decoration-color: var(--op-gniazdo-jasny);
}
.op-proza a:hover { text-decoration-thickness: 3px; }

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

/* Łącza w treści przeniesionej ze starych stron — bez tego zostają
   domyślnym niebieskim przeglądarki (1,66:1 na piance). */
.op-swiat a:not(.op-akcja):not(.op-kat):not(.op-nav__link):not(.op-nav__marka):not(.op-stopka-nav a):not(.op-wpis__link):not(.op-powiazane a) {
  color: inherit;
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  text-decoration-color: var(--op-gniazdo-jasny);
}
.op-sekcja--dokument a:not(.op-akcja):not(.op-stopka-nav a):not(.op-wpis__link) { text-decoration-color: var(--op-gniazdo-ciemny); }
.op-swiat a:not(.op-akcja):not(.op-stopka-nav a):not(.op-wpis__link):hover { text-decoration-thickness: 3px; }

/* ---- komponenty/op-form.css ---- */
/* ============================================================
   op-form — karta zgłoszenia wpięta w tablicę jak narzędzie w gniazdo.
   Fluent Forms ID 3 stylujemy WYŁĄCZNIE z zewnątrz: nazwy pól karmią
   automat wycen (operacje/scripts/zapytania.py) i są nietykalne.
   ============================================================ */

.op-karta {
  position: relative;
  border-radius: var(--op-r-frez);
  background: var(--op-papier);
  color: var(--op-tusz);
  box-shadow: var(--op-cien);
  overflow: hidden;
}

/* wypust gniazda: karta siedzi we frezie */
.op-karta::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--op-obrys-karty);
  pointer-events: none;
}

.op-karta__glowa {
  padding: var(--op-p4) var(--op-p5);
  background: var(--op-tusz);
  color: var(--op-papier);
}
.op-karta__glowa + .op-karta__cialo { border-top: var(--op-kreska) solid var(--op-kant-papier); }
.op-karta__tytul {
  font-size: var(--op-t-tytul);
  font-weight: 700;
  font-stretch: 106%;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.op-karta__pod {
  margin-top: var(--op-p2);
  font-size: var(--op-t-maly);
  line-height: 1.45;
  color: rgba(244, 245, 246, 0.76);
}

.op-karta__cialo { padding: var(--op-p4) var(--op-p5) var(--op-p5); }

.op-karta__gwarancja {
  margin-top: var(--op-p3);
  padding-top: var(--op-p3);
  border-top: var(--op-kreska) solid var(--op-linia-papier);
  font-size: var(--op-t-maly);
  line-height: 1.5;
  color: var(--op-tusz-2);
}
.op-karta__gwarancja b { color: var(--op-tusz); font-weight: 700; }

/* --- Fluent Forms od zewnątrz --- */

.op-karta .frm-fluent-form { --fluentform-primary: var(--op-gniazdo); }

/* Znak zapytania przy etykiecie to PODPOWIEDŹ, nie ostrzeżenie. Wtyczka maluje
   go zmienną `--fluentform-primary`, a u nas to cynober — przy „Zdjęcia sprzętu"
   czytało się jak komunikat błędu nad pustym polem. Treść podpowiedzi zostaje
   (limity plików), zmienia się tylko ton. */
.op-karta .ff-el-tooltip svg { fill: var(--op-tusz-2); }
.op-karta .ff-el-tooltip:hover svg { fill: var(--op-tusz); }

.op-karta .ff-el-group { margin-bottom: var(--op-p3); }
.op-karta .ff-el-group:last-child { margin-bottom: 0; }

.op-karta .ff-el-input--label label {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 90%;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--op-tusz-2);
  margin-bottom: var(--op-p2);
  display: block;
}

.op-karta .ff-el-form-control {
  width: 100%;
  min-height: 48px;
  padding: var(--op-p2) var(--op-p4);
  border: var(--op-kreska-2) solid var(--op-kant-papier);   /* 0,2 alfa dawało 1,53:1 — pole ginęło w karcie */
  border-radius: var(--op-r-pole);
  background: var(--op-biel);
  color: var(--op-tusz);
  font-family: var(--op-font);
  font-size: var(--op-t-pole);
  line-height: 1.4;
  transition: border-color var(--op-czas-krotki) var(--op-ease);
}
.op-karta textarea.ff-el-form-control { min-height: 84px; line-height: 1.5; }

.op-karta .ff-el-form-control::placeholder { color: #6B7278; }
.op-karta .ff-el-form-control:hover { border-color: var(--op-tusz-2); }
.op-karta .ff-el-form-control:focus {
  border-color: var(--op-gniazdo);
  outline: 3px solid var(--op-gniazdo-mglisty);
  outline-offset: 0;
}

.op-karta .ff-el-form-check-label { font-size: var(--op-t-maly); line-height: 1.45; }
.op-karta .ff-el-form-check input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--op-gniazdo); }

.op-karta .ff-btn-submit,
.op-karta .ff_btn_style {
  width: 100%;
  min-height: 56px;
  padding-inline: var(--op-p5);
  border: 0;
  border-radius: var(--op-r-pole);
  background: var(--op-gniazdo);
  color: var(--op-biel);
  font-family: var(--op-font);
  font-size: var(--op-t-body);
  font-weight: 700;
  font-stretch: 104%;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background var(--op-czas-krotki) var(--op-ease);
}
.op-karta .ff-btn-submit:hover,
.op-karta .ff_btn_style:hover { background: var(--op-gniazdo-ciemny); }

.op-karta .ff-el-is-error .ff-el-form-control { border-color: var(--op-gniazdo-ciemny); }
.op-karta .error-text,
.op-karta .text-danger {
  margin-top: var(--op-p2);
  font-size: var(--op-t-maly);
  font-weight: 600;
  color: var(--op-gniazdo-ciemny);
}

/* dwukrokowiec: pasek postępu w gramatyce frezu */
.op-karta .ff-el-progress {
  height: 6px;
  border-radius: var(--op-r-pigulka);
  background: rgba(20, 23, 26, 0.12);
  overflow: hidden;
}
.op-karta .ff-el-progress-bar { background: var(--op-gniazdo); }
.op-karta .ff-step-titles li {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--op-tusz-2);
}
.op-karta .ff-step-titles li.active { color: var(--op-gniazdo-ciemny); }  /* pole cynobrowe jako tekst na papierze dawało 4,40:1 */

.op-karta .ff-el-help-message {
  margin-top: var(--op-p2);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--op-tusz-2);
}

/* ---- komponenty/op-nav.css ---- */
/* ============================================================
   op-nav — chrome nowego świata.
   NIE trafia na bliźniaki: tam header i stopkę renderuje Blocksy.
   Wejdzie na produkcję dopiero po przejęciu hooków w functions.php.
   ============================================================ */

/* --- belka nad nawigacją: dwie obietnice, statycznie.
   Nie jest sticky — przy przewijaniu schodzi, przykleja się dopiero op-nav.
   Separator to puste gniazdo, nie ozdoba: cynober zostaje polem. --- */

.op-belka {
  /* O stopień jaśniejsza od nagłówka (pianka-2 vs frez): 1,22:1 wobec niego —
     widać listwę, ale nie robi się z niej druga nawigacja. */
  background: var(--op-pianka-2);
  border-bottom: var(--op-kreska) solid var(--op-linia);
}

.op-belka__rzad {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--op-p2) var(--op-p4);
  min-height: 36px;
  /* margin-block, NIE margin: skrót zerował margin-inline: auto z .op-obszar
     i belka lądowała przy lewej krawędzi na każdym ekranie szerszym niż 1280. */
  margin-block: 0;
  padding-block: var(--op-p2);
  font-size: var(--op-t-etykieta);
  font-weight: 600;
  letter-spacing: var(--op-tr-etykieta);
  line-height: 1.35;
  text-transform: uppercase;
  text-align: center;
  color: var(--op-tekst-2);
}

/* Gniazda należą do hasła, nie do rzędu: przy stałej szerokości rolki
   krótsze hasło zostawiało między nimi lukę i grupa czytała się jak rozjechana.
   Teraz klamra oddycha razem z tekstem, a całość stoi na środku. */
.op-belka__rolka {
  position: relative;
  display: inline-block;
  min-width: 30em;
  height: 1.35em;
  text-align: center;
}

.op-belka__poz::before,
.op-belka__poz::after {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-inline: 0.9em;
  border-radius: var(--op-r-plytka);
  background: var(--op-gniazdo);
  vertical-align: 0.05em;
}

/* Ruch po zegarze, nie po scrollu: animation-timeline: view() zostawiał
   elementy na opacity 0, gdy zakres się nie zazębił (patrz STATE.md). */
.op-belka__poz {
  position: absolute;
  inset-inline: 0;
  top: 0;
  white-space: nowrap;
  opacity: 0;
  animation: op-belka-rolka 16s var(--op-ease) infinite;
}
/* Ujemne przesunięcie o czas wejścia (3% z 16 s): pierwsze hasło stoi
   na stronie od razu, zamiast wchodzić przez pół sekundy w pustą belkę. */
.op-belka__poz:nth-child(1) { animation-delay: -0.48s; }
.op-belka__poz:nth-child(2) { animation-delay: 3.52s; }
.op-belka__poz:nth-child(3) { animation-delay: 7.52s; }
.op-belka__poz:nth-child(4) { animation-delay: 11.52s; }

/* Zejście i wejście muszą się zazębić na 25% (opóźnienia idą co 4 s z 16 s).
   Przy wyjściu na 22% belka gasła na pół sekundy co cykl. */
@keyframes op-belka-rolka {
  0%   { opacity: 0; transform: translateY(7px); }
  3%   { opacity: 1; transform: translateY(0); }
  25%  { opacity: 1; transform: translateY(0); }
  28%  { opacity: 0; transform: translateY(-7px); }
  100% { opacity: 0; transform: translateY(-7px); }
}

/* Bez ruchu zostaje pierwsza obietnica — reszta znika z drzewa,
   żeby czytnik ekranu nie odczytał czterech haseł pod rząd. */
@media (prefers-reduced-motion: reduce) {
  .op-belka__rolka { min-width: 0; height: auto; }
  .op-belka__poz { position: static; opacity: 1; animation: none; }
  .op-belka__poz ~ .op-belka__poz { display: none; }
}

.op-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(14, 16, 18, 0.94);
  backdrop-filter: blur(10px);
  border-bottom: var(--op-kreska) solid var(--op-linia);
}

.op-nav__rzad {
  display: flex;
  align-items: center;
  gap: var(--op-p5);
  min-height: 68px;
}

.op-nav__marka {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 1.0625rem;
  font-weight: 800;
  font-stretch: 110%;
  letter-spacing: -0.015em;
  color: var(--op-tekst);
  text-decoration: none;
  white-space: nowrap;
}

.op-nav__linki {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p1) var(--op-p4);
  margin-inline-end: auto;
}

.op-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--op-t-maly);
  font-weight: 600;
  color: var(--op-tekst-2);
  text-decoration: none;
  white-space: nowrap;
}
.op-nav__link:hover { color: var(--op-tekst); }
.op-nav__link--tu {
  color: var(--op-tekst);
  box-shadow: inset 0 -2px 0 var(--op-gniazdo);
}

/* Telefon jest ZAWSZE drugi. Pełny cynober należy wyłącznie do formularza —
   solidna pigułka w nagłówku odwracała obietnicę z FIRST VIEWPORT. */
.op-nav__tel {
  min-height: 44px;
  padding-inline: var(--op-p4);
  white-space: nowrap;
  font-size: var(--op-t-maly);
  background: transparent;
  color: var(--op-tekst);
  border: var(--op-kreska-2) solid var(--op-linia-mocna);
}
.op-nav__tel:hover { background: var(--op-pianka-2); border-color: var(--op-metal-cien); }

/* --- ujawnienie na wąskim ekranie: natywne <details>, zero JS --- */

/* Zamknięty <details> zeruje szerokość dziecka w kontenerze flex, więc
   nawigacja ma dwa warianty przełączane breakpointem, nie jeden ukrywany. */
.op-nav__linki--szeroko { display: flex; }
.op-nav__menu { display: none; margin-inline-end: auto; }
.op-nav__menu > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--op-p2);
  min-height: 44px;
  padding-inline: var(--op-p3);
  border-radius: var(--op-r-pole);
  font-size: var(--op-t-maly);
  font-weight: 700;
  color: var(--op-tekst);
  cursor: pointer;
  list-style: none;
}
.op-nav__menu > summary::-webkit-details-marker { display: none; }

@media (max-width: 1023px) {
  .op-nav__rzad { gap: var(--op-p3); }
  /* Numer jest ważniejszy niż słowo „Menu": razem nie mieściły się w rzędzie
     i przycisk telefonu wychodził poza kontener na zero marginesu.
     Etykieta zostaje dla czytnika ekranu. */
  .op-nav__menu > summary { padding-inline: var(--op-p2); min-width: 44px; justify-content: center; }
  .op-nav__menu-napis {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .op-nav__tel { padding-inline: var(--op-p3); gap: var(--op-p2); font-size: var(--op-t-nav); }
  .op-nav__marka { font-size: var(--op-t-pole); }
  .op-nav__linki--szeroko { display: none; }
  .op-nav__menu { display: block; }
  .op-nav__linki--wasko {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    display: grid;
    gap: var(--op-p1);
    padding: var(--op-p4) var(--op-margines) var(--op-p5);
    background: var(--op-frez);
    border-bottom: var(--op-kreska) solid var(--op-linia);
    box-shadow: var(--op-cien);
  }
  .op-nav__link { min-height: 48px; font-size: var(--op-t-body); }
  .op-nav__rzad { position: relative; }
}

/* Wąsko obie obietnice łamią się na dwie linie. Gniazdo znika razem z rzędem:
   separator wiszący na końcu pierwszej linii czytał się jak literówka. */
/* Wąsko najdłuższe hasło ma 31 znaków — rolka schodzi na całą szerokość
   kontenera, żeby nic nie łamało się w drugą linię pod absolutnym elementem. */
/* Wąsko najdłuższe hasło ma 31 znaków i zajmuje cały wiersz — klamra
   nie zmieściłaby się bez łamania, więc znika. Tekst zostaje na środku. */
@media (max-width: 599px) {
  .op-belka__rzad {
    gap: var(--op-p2);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
  }
  .op-belka__rolka { min-width: 0; flex: 1 1 auto; height: 1.35em; }
  /* Jedna linia także wąsko: przy 375 px najdłuższe hasło ma ~217 px i mieści
     się w wierszu. Zapas na drugą linię powodował, że hasło w ruchu wychodziło
     poza pasek i było ucięte u góry. */
  .op-belka__poz {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .op-belka__poz::before,
  .op-belka__poz::after { display: none; }
}

/* --- stopka: mapa strony w materiale dokumentu --- */

.op-stopka-nav {
  display: grid;
  gap: var(--op-p6);
  margin-bottom: var(--op-p7);
  padding-bottom: var(--op-p6);
  border-bottom: var(--op-kreska) solid var(--op-linia-papier);
}
@media (min-width: 800px) {
  .op-stopka-nav { grid-template-columns: 2fr 1fr; gap: var(--op-p7); }
}
.op-stopka-nav__grupa .op-etykieta-gniazda { margin-bottom: var(--op-p1); }
/* Linki siedzą we własnym bloku: wpautop owijał je w akapit, gdy leżały
   bezpośrednio w kontenerze flex, i cały rząd sklejał się w jeden ciąg. */
.op-stopka-nav__linki {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p1) var(--op-p5);
  align-items: baseline;
}
.op-stopka-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
  font-size: var(--op-t-maly);
  font-weight: 600;
  color: var(--op-tusz);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  text-decoration-thickness: 2px;
}
.op-stopka-nav a:hover { text-decoration-color: var(--op-gniazdo-ciemny); }

/* ---- komponenty/op-sekcje.css ---- */
/* ============================================================
   op-sekcje — bloki treści w gramatyce wkładki i tabliczki znamionowej.
   ============================================================ */

/* --- tabliczka znamionowa: progi jako specyfikacja, nie jako licznik --- */

.op-tabliczka {
  border-radius: var(--op-r-pole);
  background: linear-gradient(180deg, var(--op-pianka-3) 0%, var(--op-pianka-2) 100%);
  box-shadow: inset 0 0 0 1px var(--op-kant), var(--op-cien-plytki);
  overflow: hidden;
}
.op-tabliczka__wiersz {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--op-p1);
  padding: var(--op-p4) var(--op-p5);
  border-top: var(--op-kreska) solid var(--op-linia);
}
.op-tabliczka__wiersz:first-child { border-top: 0; }

@media (min-width: 560px) {
  .op-tabliczka__wiersz {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--op-p5);
  }
}

.op-tabliczka__klucz {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-tekst-3);
}
.op-tabliczka__wartosc {
  font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.875rem);
  font-weight: 800;
  font-stretch: 110%;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--op-tekst);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.op-tabliczka__wartosc--pole { color: var(--op-gniazdo-jasny); }

/* --- kroki: schemat instalacji, nie trzy karty --- */

.op-kroki {
  display: grid;
  gap: var(--op-p6);
  padding-top: var(--op-p5);  /* padding, nie margin: margines zlewałby się z głową sekcji */
  counter-reset: op-krok;
}
@media (min-width: 900px) {
  .op-kroki { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--op-p7); }
}

.op-krok {
  position: relative;
  padding-top: var(--op-p7);
  border-top: var(--op-kreska-2) solid var(--op-kant);
  counter-increment: op-krok;
}
/* Numer siedzi NA linii i wycina w niej przerwę — wcześniej wisiał 2 px
   nad jej początkiem i czytał się jak guzik przyklejony do krawędzi. */
.op-krok::before {
  content: counter(op-krok);
  position: absolute;
  top: -14px;
  left: 0;
  box-shadow: 0 0 0 7px var(--op-tlo-sekcji);
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--op-r-pigulka);
  background: var(--op-gniazdo);
  color: var(--op-biel);
  font-size: 0.8125rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.op-krok h3 { margin-bottom: var(--op-p3); }
.op-krok p { color: var(--op-tekst-2); }
.op-sekcja--dokument .op-krok p { color: var(--op-tusz-2); }
.op-sekcja--dokument .op-krok { border-top-color: var(--op-kant-papier); }

.op-krok__czas {
  display: inline-block;
  margin-top: var(--op-p3);
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-gniazdo-jasny);
  font-variant-numeric: tabular-nums;
}
.op-sekcja--dokument .op-krok__czas { color: var(--op-gniazdo-ciemny); }

/* --- kategorie: gniazda jako łącza --- */

/* Siatka musi się domykać na KAŻDEJ szerokości. Przy 8 kolumnach span 3 i 6
   zostawiały ułamek rzędu, więc tablet dostaje 12 kolumn z szerszymi spanami. */
.op-kategorie {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--op-p3);
}
.op-kat {
  grid-column: span 3;
  display: flex;
  flex-direction: column;
  gap: var(--op-p5);
  min-height: 156px;
  padding: var(--op-p5) var(--op-p4) var(--op-p4);
  border-radius: var(--op-r-frez);
  background: var(--op-pianka-2);
  color: var(--op-tekst);
  text-decoration: none;
  box-shadow: inset 0 0 0 1px var(--op-kant);
  transition:
    background var(--op-czas-krotki) var(--op-ease),
    box-shadow var(--op-czas-krotki) var(--op-ease);
}
/* tekst ląduje przy dolnej krawędzi bez rozpychania ikony na całą wysokość */
.op-kat > span:last-child { margin-top: auto; }
.op-kat:hover {
  background: var(--op-pianka-3);
  box-shadow: inset 0 0 0 1px var(--op-metal-cien);
}
.op-kat--szer { grid-column: span 6; }

/* Media MUSZĄ stać za regułami bazowymi — mają tę samą specyficzność,
   więc o wyniku decyduje kolejność, nie waga selektora. */
/* Tablet: dwie równe kolumny. Hierarchia rozmiarów ma sens dopiero tam,
   gdzie w rzędzie mieszczą się cztery kafle. */
@media (min-width: 640px) {
  .op-kategorie { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .op-kat,
  .op-kat--szer { grid-column: span 6; }
}
@media (min-width: 1024px) {
  .op-kat { grid-column: span 3; }
  /* Szeroki kafel układa się poziomo — pionowy zostawiał pustkę
     na środku, bo ikona i tekst rozjeżdżały się na całą wysokość. */
  .op-kat--szer {
    grid-column: span 6;
    flex-direction: row;
    align-items: center;
    gap: var(--op-p5);
    padding: var(--op-p5);
    min-height: 128px;   /* poziomy układ nie potrzebuje wysokości pionowego */
  }
  .op-kat--szer .op-kat__obrys { flex: none; width: 104px; height: 76px; }
  .op-kat--szer > span:last-child { margin-top: 0; }
}

.op-kat__obrys { width: 100%; height: 66px; color: var(--op-metal-cien); transition: color var(--op-czas-krotki) var(--op-ease); }
.op-kat:hover .op-kat__obrys { color: var(--op-metal); }
.op-kat__nazwa { display: block; font-size: var(--op-t-maly); font-weight: 700; line-height: 1.25; }
.op-kat__kwota {
  display: block;
  margin-top: var(--op-p2);
  font-size: var(--op-t-etykieta);
  line-height: 1.4;
  color: var(--op-tekst-3);
  font-variant-numeric: tabular-nums;
}

/* --- widełki: co płacimy, w kolumnach spisu --- */

.op-widelki { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.op-widelki caption {
  text-align: left;
  padding-bottom: var(--op-p3);
  font-size: var(--op-t-maly);
  color: var(--op-tusz-2);
}
.op-widelki th,
.op-widelki td {
  padding: var(--op-p3) var(--op-p4);
  border-bottom: var(--op-kreska) solid var(--op-linia-papier);
  text-align: left;
}
.op-widelki th {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-tusz-2);
}
.op-widelki td:last-child,
.op-widelki th:last-child { text-align: right; white-space: nowrap; font-weight: 700; }
.op-widelki tbody tr:hover { background: var(--op-papier-2); }

.op-tabela-przewin { overflow-x: auto; }

/* --- FAQ: frez, zero JS --- */

.op-faq { display: grid; gap: var(--op-p3); }
.op-faq details {
  border-radius: var(--op-r-pole);
  background: var(--op-pianka-2);
  box-shadow: inset 0 0 0 1px var(--op-kant);
}
.op-faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--op-p4);
  min-height: 56px;
  padding: var(--op-p4) var(--op-p5);
  font-size: var(--op-t-body);
  font-weight: 700;
  line-height: 1.35;
  cursor: pointer;
  list-style: none;
}
.op-faq summary::-webkit-details-marker { display: none; }
.op-faq summary::after {
  content: "";
  flex: none;
  width: 14px;
  height: 14px;
  border-right: var(--op-kreska-2) solid var(--op-tekst-3);
  border-bottom: var(--op-kreska-2) solid var(--op-tekst-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--op-czas-krotki) var(--op-ease);
}
.op-faq details[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.op-faq details > div {
  padding: 0 var(--op-p5) var(--op-p5);
  color: var(--op-tekst-2);
  max-width: var(--op-max-tekst);
}

/* --- zamknięcie: pas z jedną akcją --- */

.op-zamkniecie {
  display: grid;
  gap: var(--op-p6);
  align-items: center;
  padding: var(--op-p8);
  border-radius: var(--op-r-frez);
  background: var(--op-gniazdo);
  color: var(--op-biel);
}
@media (min-width: 900px) {
  .op-zamkniecie { grid-template-columns: minmax(0, 1fr) auto; gap: var(--op-p7); }
}
.op-zamkniecie h2 { color: var(--op-biel); }
/* Biel 88% na cynobrze daje 4,02:1 — poniżej progu AA dla tekstu 17 px
   (zmierzone audytem na 27 stronach, 23 VIII). Pełna biel na tym samym
   polu daje 4,80:1. Cynober jest jedynym materiałem, na którym przyciemniona
   biel nie ma zapasu. */
.op-zamkniecie p { color: var(--op-biel); max-width: 46ch; margin-top: var(--op-p5); }
.op-zamkniecie .op-akcja {
  background: var(--op-biel);
  color: var(--op-gniazdo-ciemny);
}
.op-zamkniecie .op-akcja:hover { background: var(--op-papier-2); }
.op-zamkniecie .op-akcja--druga {
  background: transparent;
  color: var(--op-biel);
  border-color: var(--op-biel-55);
}
.op-zamkniecie .op-akcja--druga:hover { background: var(--op-biel-12); }
.op-zamkniecie__akcje { display: flex; flex-wrap: wrap; gap: var(--op-p3); }

/* --- nagłówek sekcji --- */

.op-sekcja__glowa { max-width: 58ch; margin-bottom: var(--op-p7); }
.op-sekcja__glowa p { margin-top: var(--op-p4); color: var(--op-tekst-2); }
.op-sekcja--dokument .op-sekcja__glowa p { color: var(--op-tusz-2); }


/* --- drobne role dopisane przy budowie stron --- */

.op-tabliczka__opis {
  margin-top: var(--op-p1);
  font-size: var(--op-t-maly);
  line-height: 1.45;
  color: var(--op-tekst-2);
  max-width: 46ch;
}

.op-ikona { flex: none; }

.op-karta__gwarancja {
  display: flex;
  gap: var(--op-p3);
  align-items: flex-start;
}
.op-karta__gwarancja .op-ikona { margin-top: 2px; color: var(--op-gniazdo); }

.op-tablica__akcje .op-etykieta-gniazda { color: var(--op-tekst-3); }

.op-stopka { display: grid; gap: var(--op-p6); }
@media (min-width: 800px) {
  .op-stopka { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--op-p7); }
}
.op-stopka p { font-size: var(--op-t-maly); line-height: 1.6; color: var(--op-tusz-2); }
.op-stopka p + p { margin-top: var(--op-p2); }
.op-stopka b { color: var(--op-tusz); }
.op-stopka a { display: inline-flex; align-items: center; min-height: 44px; color: var(--op-tusz); text-decoration-color: var(--op-gniazdo); text-underline-offset: 3px; }

/* --- powiązane strony: lista, nie karty --- */

.op-powiazane { display: grid; gap: var(--op-p1); max-width: var(--op-max-tekst); }
.op-powiazane a {
  display: flex;
  justify-content: space-between;
  gap: var(--op-p4);
  align-items: baseline;
  min-height: 48px;
  padding: var(--op-p3) 0;
  border-bottom: var(--op-kreska) solid var(--op-linia);
  color: inherit;
  text-decoration: none;
  font-weight: 600;
}
.op-powiazane a:hover { color: var(--op-gniazdo-jasny); }
.op-sekcja--dokument .op-powiazane a:hover { color: var(--op-gniazdo-ciemny); }
.op-powiazane a::after { content: "→"; color: var(--op-gniazdo-jasny); }
.op-sekcja--dokument .op-powiazane a::after { color: var(--op-gniazdo-ciemny); }
.op-sekcja--dokument .op-powiazane a { border-bottom-color: var(--op-linia-papier); }

/* --- TL;DR: odpowiedź od razu, w materiale dokumentu --- */

.op-tldr {
  padding: var(--op-p5);
  border-radius: var(--op-r-pole);
  background: var(--op-pianka-2);
  box-shadow: inset 0 0 0 1px var(--op-linia);
  max-width: var(--op-max-tekst);
}
.op-tldr p + p { margin-top: var(--op-p3); }
.op-tldr b { color: var(--op-tekst); }
.op-sekcja--dokument .op-tldr {
  background: var(--op-papier-2);
  box-shadow: inset 0 0 0 1px var(--op-linia-papier);
}

/* akcent tekstowy w prozie na jasnym materiale */
.op-sekcja--dokument .op-proza a { text-decoration-color: var(--op-gniazdo-ciemny); }

/* FAQ na materiale dokumentu: pianka pod ciemnym tuszem dawała 1,15:1 */
.op-sekcja--dokument .op-faq details {
  background: var(--op-papier-2);
  box-shadow: inset 0 0 0 1px var(--op-kant-papier);
}
.op-sekcja--dokument .op-faq details > div { color: var(--op-tusz-2); }
.op-sekcja--dokument .op-faq summary::after {
  border-right-color: var(--op-tusz-2);
  border-bottom-color: var(--op-tusz-2);
}
.op-faq details[open] summary::after,
.op-faq summary:hover::after {
  border-right-color: var(--op-gniazdo-jasny);
  border-bottom-color: var(--op-gniazdo-jasny);
}
.op-sekcja--dokument .op-faq details[open] summary::after,
.op-sekcja--dokument .op-faq summary:hover::after {
  border-right-color: var(--op-gniazdo-ciemny);
  border-bottom-color: var(--op-gniazdo-ciemny);
}

/* --- indeks aktualności: lista, nie siatka kart --- */

.op-wpisy { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.op-wpis + .op-wpis { border-top: var(--op-kreska) solid var(--op-kant); }
.op-sekcja--dokument .op-wpis + .op-wpis { border-top-color: var(--op-kant-papier); }

.op-wpis__link {
  display: grid;
  gap: var(--op-p2) var(--op-p6);
  align-items: baseline;
  padding-block: var(--op-p5);
  color: inherit;
  text-decoration: none;
}
@media (min-width: 800px) {
  .op-wpis__link {
    grid-template-columns: 7rem minmax(0, 1fr);
  }
  .op-wpis__lead { grid-column: 2; }
}

.op-wpis__data {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  color: var(--op-tekst-3);
  font-variant-numeric: tabular-nums;
}
.op-wpis__tytul {
  font-size: var(--op-t-tytul);
  font-weight: 700;
  font-stretch: 104%;
  line-height: 1.25;
  letter-spacing: -0.015em;
}
.op-wpis__lead {
  font-size: var(--op-t-maly);
  line-height: 1.55;
  color: var(--op-tekst-2);
  max-width: 68ch;
}
.op-sekcja--dokument .op-wpis__data { color: var(--op-tusz-2); }
.op-sekcja--dokument .op-wpis__lead { color: var(--op-tusz-2); }
.op-wpis__link:hover .op-wpis__tytul { color: var(--op-gniazdo-jasny); }
.op-sekcja--dokument .op-wpis__link:hover .op-wpis__tytul { color: var(--op-gniazdo-ciemny); }

/* Dwie sąsiednie sekcje tego samego materiału czytają się jak jedna —
   podwójny padding na niewidocznej granicy robił z tego pionową dziurę.
   Zmiana materiału nadal dostaje pełny oddech. */
.op-sekcja:not(.op-sekcja--dokument) + .op-sekcja:not(.op-sekcja--dokument),
.op-sekcja--dokument + .op-sekcja--dokument { padding-top: 0; }

.op-tablica + .op-sekcja:not(.op-sekcja--dokument) { padding-top: var(--op-p7); }

/* ============================================================
   Dowód, którym wolno się posługiwać. Opinii i case studies nie ma
   — klient nie wyraził zgody (PRODUCT.md). Zostają uprawnienia
   i dokumenty, oba potwierdzone.
   ============================================================ */

.op-legitymacje {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--op-p6);
}
@media (min-width: 860px) {
  .op-legitymacje { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--op-p7); }
}

.op-legitymacja {
  display: grid;
  gap: var(--op-p3);
  align-content: start;
  padding-top: var(--op-p5);
  border-top: var(--op-kreska-2) solid var(--op-kant);
}
.op-sekcja--dokument .op-legitymacja { border-top-color: var(--op-kant-papier); }

.op-legitymacja__znak {
  width: 76px;
  height: 58px;
  color: var(--op-gniazdo-jasny);
}
.op-sekcja--dokument .op-legitymacja__znak { color: var(--op-gniazdo-ciemny); }

.op-legitymacja__nazwa {
  font-size: var(--op-t-tytul);
  font-weight: 700;
  font-stretch: 104%;
  line-height: 1.25;
  letter-spacing: -0.015em;
}
.op-legitymacja__opis {
  font-size: var(--op-t-maly);
  line-height: 1.6;
  color: var(--op-tekst-2);
  max-width: 40ch;
}
.op-sekcja--dokument .op-legitymacja__opis { color: var(--op-tusz-2); }

/* --- dokumenty: rząd obrysów z podpisem --- */

.op-dokumenty {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--op-p4);
}
@media (min-width: 860px) {
  .op-dokumenty { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.op-dokument {
  display: grid;
  grid-template-rows: auto auto 1fr;
  gap: var(--op-p2);
  justify-items: start;
  padding: var(--op-p5) var(--op-p4);
  border-radius: var(--op-r-pole);
  box-shadow: inset 0 0 0 1px var(--op-kant);
}
.op-sekcja--dokument .op-dokument { box-shadow: inset 0 0 0 1px var(--op-kant-papier); }

.op-dokument__obrys { width: 58px; height: 50px; color: var(--op-metal-cien); }
.op-sekcja--dokument .op-dokument__obrys { color: var(--op-tusz-2); }

.op-dokument__nazwa { font-size: var(--op-t-maly); font-weight: 700; line-height: 1.3; }
.op-dokument__komu {
  align-self: end;
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-tekst-3);
}
.op-sekcja--dokument .op-dokument__komu { color: var(--op-tusz-2); }

/* --- scena: zdjęcie z podpisem --- */

.op-scena { margin: 0; }
.op-scena img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--op-r-frez);
  background: var(--op-pianka-2);
}
.op-scena figcaption {
  margin-top: var(--op-p3);
  font-size: var(--op-t-maly);
  line-height: 1.5;
  color: var(--op-tekst-2);
  max-width: 62ch;
}
.op-sekcja--dokument .op-scena figcaption { color: var(--op-tusz-2); }

/* zdjęcie obok treści, gdy jest miejsce */
.op-scena-obok { display: grid; gap: var(--op-p6); align-items: center; }
@media (min-width: 1024px) {
  .op-scena-obok { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: var(--op-p7); }
}

/* zdjęcie pod krokami potrzebuje oddechu od ostatniego wiersza tekstu */
/* Zdjęcie sceniczne stojące pod treścią sekcji potrzebuje własnego odstępu:
   `.op-scena` ma `margin: 0`, więc kadr przyklejał się do ostatniej pozycji
   listy albo do wiersza tabeli. Reguła celuje w bezpośrednie dziecko
   `.op-obszar` — figura w siatce `.op-scena-obok` jest zagnieżdżona głębiej
   i zostaje bez marginesu, bo tam odstęp daje `gap`. */
.op-obszar > * + .op-scena { margin-top: var(--op-p8); }

/* Obok zdjęcia legitymacje dostają jedną kolumnę — trzy w połowie szerokości
   łamały każdy opis na cztery linie. */
.op-scena-obok .op-legitymacje { grid-template-columns: minmax(0, 1fr); gap: var(--op-p5); }
.op-scena-obok .op-legitymacja__opis { max-width: none; }
.op-scena-obok .op-legitymacja__znak { width: 60px; height: 46px; }

/* ============================================================
   op-spis — spis treści wpisu. Materiał dokumentu, bo wpis czyta się
   na papierze; numeracja tabularna, żeby cyfry nie tańczyły.
   ============================================================ */

.op-spis {
  margin-bottom: var(--op-p7);
  padding: var(--op-p5) var(--op-p6);
  background: var(--op-papier-2);
  border-inline-start: var(--op-kreska-2) solid var(--op-gniazdo);
  border-radius: var(--op-r-pole);
}

.op-spis__lista {
  margin: var(--op-p3) 0 0;
  padding-inline-start: var(--op-p5);
  display: grid;
  gap: var(--op-p1);
  font-variant-numeric: tabular-nums;
}

.op-spis__link {
  display: inline-flex;
  align-items: center;
  /* 44 px, nie 32: pozycja spisu to pełnoprawny cel dotykowy — audyt złapał
     to na wszystkich 11 wpisach. */
  min-height: 44px;
  font-size: var(--op-t-maly);
  font-weight: 600;
  color: var(--op-tusz);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.op-spis__link:hover { text-decoration-color: var(--op-gniazdo-ciemny); }

@media (max-width: 599px) {
  .op-spis { padding: var(--op-p4) var(--op-p5); }
}

/* ============================================================
   op-okruszki — ścieżka powrotna nad tytułem wpisu.
   Materiał dokumentu, bo wpis stoi na papierze.
   ============================================================ */

.op-okruszki {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--op-p1) var(--op-p2);
  margin-bottom: var(--op-p4);
  font-size: var(--op-t-etykieta);
  color: var(--op-tusz-2);
}

.op-okruszki a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 600;
  color: var(--op-tusz);
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.op-okruszki a:hover { text-decoration-color: var(--op-gniazdo-ciemny); }

/* Ostatni element to bieżąca strona — nie jest linkiem i ma zostać stonowany. */
.op-okruszki [aria-current="page"] {
  color: var(--op-tusz-2);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 599px) {
  .op-okruszki [aria-current="page"] { display: none; }
  .op-okruszki { margin-bottom: var(--op-p3); }
}

/* ============================================================
   op-pasek — pasek konwersji na wpisie.

   Wpis nie ma formularza w pierwszym ekranie: wejście z frazy „ile jest wart
   używany okap" to intencja informacyjna, a dwukrokowiec ma 570 px i zjadłby
   cały ekran telefonu. Akcja jedzie więc z czytelnikiem przy dolnej krawędzi.
   Pokazuje się po zejściu z pierwszego ekranu, znika przy sekcji zamykającej.
   ============================================================ */

.op-pasek {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 30;
  background: rgba(14, 16, 18, 0.96);
  backdrop-filter: blur(10px);
  border-top: var(--op-kreska) solid var(--op-linia);
  box-shadow: var(--op-cien);
}
.op-pasek[hidden] { display: none; }

.op-pasek__rzad {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--op-p3) var(--op-p5);
  padding-block: var(--op-p3);
}

.op-pasek__tekst {
  margin: 0;
  font-size: var(--op-t-maly);
  font-weight: 600;
  color: var(--op-tekst-2);
}

.op-pasek__akcje {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p3);
  margin: 0;
}
.op-pasek .op-akcja--druga {
  color: var(--op-tekst);
  border-color: var(--op-linia-mocna);
}

/* Miejsce pod paskiem, żeby nie zasłaniał końca treści. Klasę zdejmuje
   i nakłada ten sam skrypt, który steruje widocznością. */
.op-pasek-widoczny body,
html.op-pasek-widoczny .op-swiat { padding-bottom: 84px; }

@media (max-width: 599px) {
  .op-pasek__rzad { justify-content: center; gap: var(--op-p2); }
  /* Na telefonie zapowiedź zabiera wiersz, którego potrzebują przyciski. */
  .op-pasek__tekst { display: none; }
  .op-pasek__akcje { width: 100%; }
  /* Jedna linia na przycisk: „Wyślij listę sprzętu" łamało się na dwie
     i pasek rósł do 120 px, czyli ~15% ekranu telefonu. */
  .op-pasek__akcje .op-akcja {
    flex: 1 1 0;
    justify-content: center;
    padding-inline: var(--op-p3);
    font-size: var(--op-t-nav);
    white-space: nowrap;
  }
  html.op-pasek-widoczny .op-swiat { padding-bottom: 88px; }
}

@media (prefers-reduced-motion: reduce) {
  .op-pasek { backdrop-filter: none; }
}

/* ---- komponenty/op-tablica.css ---- */
/* ============================================================
   op-tablica — wkładka piankowa lokalu.
   Gniazda mają różne rozmiary, bo urządzenia mają różne rozmiary.
   Równa siatka jednakowych kafli byłaby kartami udającymi materiał.
   ============================================================ */

.op-tablica {
  position: relative;
  background: var(--op-papier);
  color: var(--op-tusz);
  padding-block: var(--op-p6) var(--op-p8);
  overflow: hidden;
}

/* ziarno pianki — matowe, nie połyskliwe */
.op-tablica::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(0deg, rgba(20, 23, 26, 0.035) 0 1px, transparent 1px 5px);
  pointer-events: none;
}

.op-tablica > .op-obszar { position: relative; }

/* --- głowa: nagłówek + karta zgłoszenia --- */

.op-tablica__glowa {
  display: grid;
  gap: var(--op-p7);
  align-items: start;
}

/* Na wąskim ekranie karta leży nad pasem i bez odstępu się z nim skleja;
   na szerokim stoi obok, więc dodatkowy margines tylko zjadałby wkładkę. */
@media (max-width: 1023px) {
  .op-rejestr { margin-top: var(--op-p6); }
}

@media (min-width: 1024px) {
  .op-tablica__glowa {
    grid-template-columns: minmax(0, 1.18fr) minmax(392px, 0.82fr);
    gap: var(--op-rynna);
  }
}

.op-tablica__tekst > * + * { margin-top: var(--op-p4); }

.op-tablica__akcje {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p3);
  align-items: center;
}

/* --- pas rejestrowy: dowód podmiotu nad zgięciem, nie w stopce --- */

.op-rejestr {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p2) var(--op-p5);
  align-items: baseline;
  margin-top: var(--op-p3);
  padding-top: var(--op-p3);
  border-top: var(--op-kreska) solid var(--op-linia);
  line-height: 1.4;
  font-size: var(--op-t-etykieta);
  color: var(--op-tekst-3);
}
.op-rejestr b {
  color: var(--op-tekst-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* --- wkładka: siatka gniazd --- */

.op-wkladka { margin-top: var(--op-p5); }

.op-wkladka__glowa {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p3) var(--op-p5);
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--op-p4);
}

.op-wkladka__licznik {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-tekst-3);
}
.op-wkladka__licznik b {
  color: var(--op-gniazdo-jasny);
  font-variant-numeric: tabular-nums;
}

/* Ten sam wymóg co przy kategoriach: siatka domyka się na każdej szerokości.
   Osiem kolumn zostawiało ułamek rzędu przy spanach 3 i 6. */
.op-wkladka__siatka {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--op-p3);
}

/* --- gniazdo --- */

.op-gniazdo {
  position: relative;
  grid-column: span 3;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--op-p3);
  min-height: 132px;
  border: 0;
  color: var(--op-tekst-2);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* realne proporcje sprzętu — wkładka nie jest siatką kafli */
.op-gniazdo--duze  { grid-column: span 6; min-height: 172px; }
.op-gniazdo--szer  { grid-column: span 6; }
.op-gniazdo--male  { grid-column: span 3; min-height: 108px; }

/* Media za regułami bazowymi: ta sama specyficzność, decyduje kolejność. */
/* Tablet: dwie równe kolumny, jak przy kategoriach. */
@media (min-width: 640px) {
  .op-wkladka__siatka { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .op-gniazdo,
  .op-gniazdo--male,
  .op-gniazdo--duze,
  .op-gniazdo--szer { grid-column: span 6; }
}
@media (min-width: 1024px) {
  .op-gniazdo, .op-gniazdo--male { grid-column: span 3; }
  .op-gniazdo--duze, .op-gniazdo--szer { grid-column: span 6; }
}

@media (max-width: 639px) {
  .op-gniazdo,
  .op-gniazdo--male { grid-column: span 3; }
  .op-gniazdo--duze,
  .op-gniazdo--szer { grid-column: span 6; }
}

.op-gniazdo__wneka {
  position: relative;
  flex: 1;
  display: grid;
  place-items: center;
  padding-block: var(--op-p4);
  border-radius: var(--op-r-pole);
  background: var(--op-frez);
  /* ścianka frezu ma offset i rozmycie — to zagłębienie, nie kreska */
  box-shadow:
    inset 0 8px 14px -6px rgba(0, 0, 0, 0.95),
    inset 0 -3px 6px -2px rgba(201, 207, 212, 0.28),
    inset 0 0 0 1px var(--op-kant);
  transition: background var(--op-czas-krotki) var(--op-ease);
}

/* Sylwetka i kontur to ten sam przedmiot w tej samej skali — inaczej
   „wyjęte" narzędzie byłoby mniejsze niż to, które jeszcze stoi obok.
   Obie wysokości MUSZĄ iść parami; rozjechanie ich zabija mechanizm. */
.op-gniazdo__sylwetka,
.op-gniazdo__obrys { height: 84px; }
.op-gniazdo--duze .op-gniazdo__sylwetka,
.op-gniazdo--duze .op-gniazdo__obrys { height: 120px; }
.op-gniazdo--male .op-gniazdo__sylwetka,
.op-gniazdo--male .op-gniazdo__obrys { height: 62px; }

.op-gniazdo__sylwetka {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  transform: translateY(-50%);
  fill: var(--op-frez);
  transition: fill var(--op-czas-krotki) var(--op-ease);
}

.op-gniazdo__obrys {
  position: relative;
  width: 100%;
  color: var(--op-metal-cien);
  transition: color var(--op-czas-krotki) var(--op-ease);
}

.op-gniazdo__nazwa {
  font-size: var(--op-t-maly);
  font-weight: 600;
  line-height: 1.25;
  color: var(--op-tekst-2);
}

.op-gniazdo:hover .op-gniazdo__sylwetka { fill: #1D2124; }
.op-gniazdo:hover .op-gniazdo__obrys { color: var(--op-metal); }

/* stan zabrany: narzędzia nie ma — świeci spód pianki w jego kształcie */
.op-gniazdo:has(.op-gniazdo__pole:checked) .op-gniazdo__sylwetka { fill: var(--op-gniazdo); }
.op-gniazdo:has(.op-gniazdo__pole:checked) .op-gniazdo__obrys { opacity: 0; }
.op-gniazdo:has(.op-gniazdo__pole:checked) .op-gniazdo__nazwa { color: var(--op-tekst); }

.op-gniazdo__ptaszek {
  position: absolute;
  inset-block-start: var(--op-p2);
  inset-inline-end: var(--op-p2);
  width: 20px;
  height: 20px;
  opacity: 0;
  color: var(--op-biel);
  transform: scale(0.6);
  transition:
    opacity var(--op-czas-krotki) var(--op-ease),
    transform var(--op-czas-krotki) var(--op-ease);
}
.op-gniazdo:has(.op-gniazdo__pole:checked) .op-gniazdo__ptaszek {
  opacity: 1;
  transform: scale(1);
}

/* --- podsumowanie wyboru: to, co poleci do formularza --- */

.op-wybor {
  margin-top: var(--op-p5);
  padding: var(--op-p5);
  border-radius: var(--op-r-frez);
  background: var(--op-frez);
  box-shadow: inset 0 0 0 1px var(--op-kant);
}
.op-wybor__lista {
  margin-top: var(--op-p3);
  font-size: var(--op-t-maly);
  color: var(--op-tekst-2);
  line-height: 1.55;
}
.op-wybor__pusty { color: var(--op-tekst-3); }
.op-wybor__akcje { margin-top: var(--op-p4); }

.op-gniazdo:has(.op-gniazdo__pole:focus-visible) {
  outline: 3px solid var(--op-tasma);
  outline-offset: 3px;
}

.op-wybor__akcje .op-akcja[disabled] {
  background: var(--op-pianka-3);
  color: var(--op-metal);          /* 4,22:1 na piance-3 było poniżej AA */
  cursor: not-allowed;
}

/* --- jeden zorkiestrowany gest: wejście tablicy, raz, przy załadowaniu --- */

@media (prefers-reduced-motion: no-preference) {
  .op-tablica__tekst > *,
  .op-tablica .op-karta,
  .op-tablica .op-rejestr,
  .op-tablica .op-gniazdo {
    animation: op-wejdz 620ms var(--op-ease) both;
  }
  .op-tablica__tekst > *:nth-child(1) { animation-delay: 40ms; }
  .op-tablica__tekst > *:nth-child(2) { animation-delay: 110ms; }
  .op-tablica__tekst > *:nth-child(3) { animation-delay: 170ms; }
  .op-tablica .op-karta { animation-delay: 150ms; }
  .op-tablica .op-rejestr { animation-delay: 240ms; }
  .op-tablica .op-gniazdo { animation-delay: calc(300ms + var(--op-i, 0) * 34ms); }

  @keyframes op-wejdz {
    from { opacity: 0; transform: translateY(12px); filter: blur(5px); }
    to   { opacity: 1; transform: none; filter: none; }
  }
}

/* --- archetyp czytelniczy: tytuł wpisu bywa długi, a strony bez karty
       i bez wkładki nie potrzebują dolnego marginesu na całą sekcję --- */

.op-tablica--wpis { padding-block: var(--op-p7) var(--op-p7); }
.op-tablica--wpis h1 { font-size: var(--op-t-display-wpis); }
.op-tablica--wpis .op-tablica__glowa { display: block; }
.op-tablica--wpis .op-tablica__tekst { max-width: 46rem; }
.op-tablica--wpis .op-lead { max-width: 58ch; }

/* --- progi w pierwszym ekranie: konkret zamiast pustej kolumny --- */

.op-progi {
  display: grid;
  gap: 0;
  margin: 0;
  margin-top: var(--op-p6);
  max-width: 30rem;
  border-top: var(--op-kreska) solid var(--op-kant);
}
.op-progi > div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--op-p3) var(--op-p5);
  align-items: baseline;
  justify-content: space-between;
  padding-block: var(--op-p3);
  border-bottom: var(--op-kreska) solid var(--op-kant);
}
.op-progi dt {
  font-size: var(--op-t-etykieta);
  font-weight: 700;
  font-stretch: 88%;
  letter-spacing: var(--op-tr-etykieta);
  text-transform: uppercase;
  color: var(--op-tekst-3);
}
.op-progi dd {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 800;
  font-stretch: 108%;
  letter-spacing: -0.015em;
  color: var(--op-tekst);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.op-progi > div:nth-child(2) dd { color: var(--op-gniazdo-jasny); }


/* ============================================================
   Hero na papierze. Pianka zaczyna się przy wkładce, bo tam jest
   potrzebna: cynober świeci tylko na ciemnym spodzie.
   ============================================================ */

.op-tablica .op-lead { color: var(--op-tusz-2); }
.op-tablica .op-etykieta-gniazda { color: var(--op-tusz-2); }

.op-tablica .op-akcja--druga {
  color: var(--op-tusz);
  border-color: var(--op-kant-papier);
}
.op-tablica .op-akcja--druga:hover {
  background: var(--op-papier-2);
  border-color: var(--op-tusz);
}

.op-tablica .op-rejestr {
  border-top-color: var(--op-kant-papier);
  color: var(--op-tusz-2);
}
.op-tablica .op-rejestr b { color: var(--op-tusz); }

.op-tablica .op-progi { border-top-color: var(--op-kant-papier); }
.op-tablica .op-progi > div { border-bottom-color: var(--op-kant-papier); }
.op-tablica .op-progi dt { color: var(--op-tusz-2); }
.op-tablica .op-progi dd { color: var(--op-tusz); }
.op-tablica .op-progi > div:nth-child(2) dd { color: var(--op-gniazdo-ciemny); }

/* Karta na papierze musi się odciąć: biel plus kant, inaczej ginie w tle. */
.op-tablica .op-karta {
  background: var(--op-biel);
  box-shadow: inset 0 0 0 1px var(--op-kant-papier), var(--op-cien-plytki);
}
.op-tablica .op-karta .ff-el-form-control { background: var(--op-papier); }

/* --- wkładka: tu zaczyna się pianka --- */

.op-wkladka-sekcja {
  position: relative;
  background: var(--op-pianka);
  color: var(--op-tekst);
  padding-block: var(--op-p8) var(--op-p9);
  overflow: hidden;
}
.op-wkladka-sekcja::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    repeating-linear-gradient(90deg, var(--op-ziarno-jasne) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg, var(--op-ziarno-ciemne) 0 1px, transparent 1px 4px);
  pointer-events: none;
}
.op-wkladka-sekcja > .op-obszar { position: relative; }
.op-wkladka { margin-top: 0; }

/* ---- komponenty/op-zgodnosc.css ---- */
/* ============================================================
   op-zgodnosc — warstwa styku z motywem Blocksy.

   Ładowana jako ostatni komponent (kolejność alfabetyczna w css.py),
   więc przy remisie specyficzności to ona rozstrzyga.

   Każda reguła tutaj neutralizuje KONKRETNĄ regułę motywu, znalezioną
   w `blocksy/static/bundle/main.min.css`. Nic tu nie wchodzi „na wszelki
   wypadek" — jeśli reguła motywu zniknie, ta też ma zniknąć.
   ============================================================ */

/* Blocksy:
     .is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull))
       { width: var(--theme-block-width) }
   a `--theme-block-width` to szerokość kontenera motywu (~1290 px).
   `.op-swiat` jest bezpośrednim dzieckiem `.entry-content.is-layout-constrained`,
   więc bez tego cały świat zwęża się do kolumny motywu: ciemne sekcje i cynobrowe
   zamknięcie przestają sięgać krawędzi ekranu, a przejście jasne/ciemne — czyli
   granica między biurem a warsztatem — przestaje istnieć. */
.entry-content > .op-swiat,
.op-swiat {
  width: 100%;
  max-width: none;
  margin-inline: 0;
}

/* Blocksy: `.entry-content > *` dostaje `margin-block-start: var(--theme-content-spacing)`.
   Świat zaczyna się własną sekcją i nie potrzebuje odsadzenia od nagłówka. */
.entry-content > .op-swiat {
  margin-block: 0;
}

/* Blocksy: `.entry-content figcaption { text-align: center; margin-block: .5em 0 }`.
   Specyficzność (0,1,1) jest taka sama jak `.op-scena figcaption`, więc o wyniku
   decyduje kolejność — a podpis zdjęcia ma stać przy lewej krawędzi kadru,
   tak jak w podglądzie. */
.op-swiat .op-scena figcaption {
  text-align: start;
  margin-block: var(--op-p3) 0;
}

/* ------------------------------------------------------------
   Fluent Forms 6.2.4 — dwukrokowiec (formularz ID 3)

   Wtyczka dokleja własny <style> ZA treścią strony, malując tło przycisku
   wysyłki zielenią z ustawień formularza (paleta starego motywu). Robi to
   selektorem `form.fluent_form_N .wpf_has_custom_css.ff-btn-submit`, czyli ze
   specyficznością (0,3,1) — `.op-karta .ff-btn-submit` (0,2,0) przegrywa. Stąd `.op-swiat` na
   początku selektorów — (0,4,1) wygrywa uczciwie, bez !important.

   Podgląd lokalny tego nie pokazał: renderuje makietę pól, a nie wtyczkę.
   ------------------------------------------------------------ */

.op-swiat .op-karta form.frm-fluent-form .ff-btn-submit,
.op-swiat .op-karta form.frm-fluent-form .ff-btn-next {
  width: 100%;
  min-height: 56px;
  padding-inline: var(--op-p5);
  border: 0;
  border-radius: var(--op-r-pole);
  background-color: var(--op-gniazdo);
  color: var(--op-biel);
  font-family: var(--op-font);
  font-size: var(--op-t-body);
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.op-swiat .op-karta form.frm-fluent-form .ff-btn-submit:hover,
.op-swiat .op-karta form.frm-fluent-form .ff-btn-next:hover {
  background-color: var(--op-gniazdo-ciemny);
}

/* „Wstecz" jest akcją drugorzędną — kontur, nie pole. */
.op-swiat .op-karta form.frm-fluent-form .ff-btn-prev {
  min-height: 48px;
  padding-inline: var(--op-p5);
  border: var(--op-kreska-2) solid var(--op-kant-papier);
  border-radius: var(--op-r-pole);
  background: transparent;
  color: var(--op-tusz);
  font-family: var(--op-font);
  font-weight: 700;
}

/* Wybór zdjęć: 44 px celu dotykowego, materiał dokumentu. */
.op-swiat .op-karta form.frm-fluent-form .ff_upload_btn {
  min-height: 44px;
  padding-inline: var(--op-p4);
  border: var(--op-kreska-2) solid var(--op-kant-papier);
  border-radius: var(--op-r-pole);
  background: transparent;
  color: var(--op-tusz);
  font-family: var(--op-font);
  font-weight: 600;
}

/* Krok aktywny nosi u wtyczki klasę `ff_active`, nie `active` —
   reguła pisana pod `.active` nigdy nie trafiała w cel. */
.op-swiat .op-karta form.frm-fluent-form .ff-step-titles li.ff_active {
  color: var(--op-gniazdo-ciemny);
}

/* ------------------------------------------------------------
   Kolory dziedziczone — dwa różne źródła, ten sam skutek.

   1. Blocksy koloruje `h2` selektorem elementowym
      (`h2 { color: var(--theme-heading-color…) }`). Bezpośrednia reguła bije
      dziedziczenie po materiale sekcji, więc nagłówki na piance dostawały
      ciemny tusz motywu: zmierzone 1,16:1 na /o-nas/ po wdrożeniu.

   2. W `blocksy-child/style.css` wciąż leży arkusz z 17 VIII (poprzedni
      kierunek, 27 kB). Maluje `.op-karta__tytul` tokenem `--op-atrament`,
      którego dziś nie ma — kolor nie rozwiązuje się i tytuł karty zostaje
      prawie czarny na prawie czarnej głowie: 1,02:1.
      To łata do czasu podmiany pliku motywu; po podmianie ta sekcja znika.
   ------------------------------------------------------------ */

.op-swiat :is(h1, h2, h3, h4, h5, h6) { color: inherit; }

.op-karta .op-karta__tytul,
.op-karta .op-karta__pod { color: inherit; }

.op-swiat .op-rejestr { background: transparent; }

/* Pasek kroków dwukrokowca: numer siedzi w `li::before` i wtyczka maluje go
   niebieskim #007BFF — jedynym niebieskim w całej witrynie. Aktywny krok
   dostaje pole cynobrowe, nieaktywny pusty frez na papierze. */
.op-swiat .op-karta form.frm-fluent-form .ff-step-titles li::before {
  background-color: var(--op-papier-2);
  border: var(--op-kreska-2) solid var(--op-kant-papier);
  color: var(--op-tusz-2);
  font-family: var(--op-font);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.op-swiat .op-karta form.frm-fluent-form .ff-step-titles li.ff_active::before,
.op-swiat .op-karta form.frm-fluent-form .ff-step-titles li.ff_completed::before {
  background-color: var(--op-gniazdo);
  border-color: var(--op-gniazdo);
  color: var(--op-biel);
}
.op-swiat .op-karta form.frm-fluent-form .ff-step-titles li::after {
  background-color: var(--op-kant-papier);
}

/* ------------------------------------------------------------
   Siatka bezpieczeństwa na wpautop.

   WordPress owija inline'owe dziecko kontenera we własny akapit — element
   wypada wtedy z siatki rodzica. Renderery generują dziś blokowe dzieci
   wszędzie tam, gdzie to znaleziono, ale wystarczy jeden nowy `<span>`
   w kontenerze flex, żeby wada wróciła. `display: contents` zdejmuje
   dorobiony akapit z układu, zostawiając jego treść na miejscu dziecka.
   ------------------------------------------------------------ */
.op-tabliczka__wiersz > p:not([class]),
.op-kroki > p:not([class]),
.op-kategorie > p:not([class]),
.op-wkladka__siatka > p:not([class]),
.op-stopka-nav__linki > p:not([class]),
.op-powiazane > p:not([class]) {
  display: contents;
}

/* ------------------------------------------------------------
   Puste akapity od wpautop na początku treści.

   WordPress owija komentarz sterujący (`op:kierunek`) i sprite SVG we własne
   akapity. Są niewidoczne — mają zerową wysokość — ale dostają od motywu
   `margin-block-start: var(--theme-content-spacing)` (24 px), a ten margines
   zapada na zewnątrz kontenerów i odsuwa CAŁĄ stronę od nagłówka.
   Widać to było jako jasny pas pod menu: 24 px na `/`, `/kontakt/`
   i `/aktualnosci/`, 0 px tam, gdzie takich akapitów nie ma.
   ------------------------------------------------------------ */
.entry-content > p:not([class]):empty,
.entry-content > p:not([class]):has(> br:only-child) {
  display: none;
}
.entry-content > p:not([class]) {
  margin-block: 0;
}

/* ---- chrome.css ---- */
/* ============================================================
   chrome.css — nagłówek i stopka MOTYWU, przemalowane na materiał świata.

   To nie jest `op-nav`. Docelowy chrome wchodzi hookami w functions.php
   i wtedy ten plik znika. Do tego czasu nagłówek renderuje Blocksy, a my
   możemy go tylko przemalować — arkusz siedzi w treści strony, ale CSS
   obowiązuje cały dokument, więc sięga też ponad `.op-swiat`.

   Reguły są celowo trzymane osobno, żeby dało się je usunąć jednym ruchem.
   Ładowane jako ostatnie (KOLEJNOSC w css.py).
   ============================================================ */

/* --- podłoże dokumentu ---
   Między nagłówkiem a treścią zostaje 24 px odstępu od motywu (`#main`
   zaczyna się na 170, a jego kontener na 194; oba mają zerowe marginesy
   i paddingi, więc źródłem jest wewnętrzna arytmetyka Blocksy). Przez tę
   szparę widać `body`, a ono jest białe — pod ciemnym nagłówkiem czytało się
   to jako jasny pasek. Podłoże dostaje materiał pierwszego ekranu, więc
   przejście jest gładkie niezależnie od tego, skąd bierze się odstęp. */

body {
  background-color: var(--op-papier);
}

/* --- pas nad menu: ciemniejszy spód, na którym belka ma sens --- */

/* Blocksy maluje wiersze selektorem `[data-header*="type-1"] .ct-header
   [data-row*="middle"]` — (0,3,0). Bez `[data-header]` z przodu nasza reguła
   (0,2,0) przegrywa i nagłówek zostaje biały. */
[data-header] .ct-header [data-row="top"] {
  background-color: var(--op-pianka-2);
  border-bottom: var(--op-kreska) solid var(--op-linia);
}

/* --- wiersz główny: pianka, nie biel --- */

[data-header] .ct-header [data-row="middle"] {
  background-color: var(--op-frez);
  border-bottom: var(--op-kreska) solid var(--op-linia);
}

/* Content Block w nagłówku dostaje na wąskim ekranie zerową szerokość —
   Blocksy nie nadaje mu bazy w kontenerze flex. Tekst belki łamał się wtedy
   na trzy linie („DEMONTAŻ / I ODBIÓR / GRATIS") i wychodził poza pasek. */
[data-header] .ct-header .ct-header-content-block {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
}

/* --- stan przyklejony ---
   Blocksy maluje przyklejony nagłówek OSOBNYMI regułami:
     [data-header*="type-1"] .ct-header [data-sticky*="yes"] [data-row*="middle"]
       { background-color: var(--theme-palette-color-8) }   ← biel
   To (0,4,0), czyli więcej niż nasze (0,3,0) dla stanu spoczynku. Bez tego
   nagłówek po przewinięciu wracał do bieli, a jasne menu i biała marka
   znikały na białym tle. */

[data-header] .ct-header [data-sticky] [data-row="middle"] {
  background-color: var(--op-frez);
  box-shadow: var(--op-cien-plytki);
}
[data-header] .ct-header [data-sticky] [data-row="top"] {
  background-color: var(--op-pianka-2);
}

/* --- znak w nagłówku ---
   Do 24 VIII 2026 stało tu obejście: obraz logo schodził z widoku, a jego miejsce
   zajmowała marka złożona w Archivo — bo znak z 2025 r. niósł zieleń i granat spoza
   palety świata. Od 24 VIII w nagłówku stoi zestaw poziomy „Gniazdo” (media 2286),
   złożony z tych samych tokenów, więc obejście zniknęło. Nie przywracać go:
   napisy w zestawie są zamienione na krzywe, żaden webfont nie jest potrzebny.
   Zostaje samo wyrównanie i pole dotyku 44 px. */

.site-logo-container {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration: none;
}

/* Wysokością logo steruje Blocksy zmienną `--logo-max-height` na kontenerze;
   obraz dziedziczy po nim wysokość. Reguła nałożona wprost na `img` przegrywa
   z motywem, więc podmieniamy zmienną. Zestaw ma proporcję ~3,9:1 — przy
   domyślnych 120 px rozpycha nagłówek i zasłania menu. */
body [data-header] .ct-header [data-id=logo] .site-logo-container {
  --logo-max-height: 44px;
}

/* --- menu: Archivo zamiast Lexend, role tekstu z palety --- */

.ct-header .ct-menu-link,
.ct-header .ct-header-cta {
  font-family: var(--op-font);
}

/* Blocksy koloruje linki menu przez `nav[class*="menu"] .ct-menu-link` (0,2,1),
   więc `.ct-header .ct-menu-link` (0,2,0) przegrywa i menu zostaje w ciemnym
   tuszu motywu — na piance dawało 1,25:1. */
[data-header] .ct-header nav .ct-menu-link {
  min-height: 44px;
  font-size: var(--op-t-maly);
  font-weight: 600;
  color: var(--op-tekst-2);
}
/* `current-menu-ancestor` i `current-menu-parent` to pozycje, których dzieckiem
   jest bieżąca strona — motyw maluje je zielenią `#2D7A3F`, co na frezie dawało
   3,60:1. Wskazanie bieżącej gałęzi zostaje, ale w materiale świata. */
[data-header] .ct-header nav .ct-menu-link:hover,
[data-header] .ct-header nav .current-menu-item > .ct-menu-link,
[data-header] .ct-header nav .current-menu-ancestor > .ct-menu-link,
[data-header] .ct-header nav .current-menu-parent > .ct-menu-link,
[data-header] .ct-header nav .current_page_item > .ct-menu-link {
  color: var(--op-tekst);
}

/* Strzałka rozwijania podmenu: klikalny jest `…-ghost` (<button> z etykietą
   „Rozwiń menu"), a `…-desktop` to tylko wizualny <span>. Cel dotykowy miał
   24×24, więc próg 44 nakładamy na przycisk, nie na strzałkę. */
[data-header] .ct-header .ct-toggle-dropdown-desktop,
[data-header] .ct-header .ct-toggle-dropdown-mobile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--op-tekst-2);
}
[data-header] .ct-header .ct-toggle-dropdown-desktop-ghost,
[data-header] .ct-header .ct-toggle-dropdown-mobile-ghost {
  min-width: 44px;
  min-height: 44px;
}

/* Sama strzałka nie idzie za `color` rodzica: Blocksy maluje `<path>` kolorem
   z Customizera (`--theme-icon-color: #1E262E`), co na frezie daje 1,25:1 —
   praktycznie niewidoczne. Malujemy `path`, nie `svg`: fill na kontenerze
   przegrywa z tym, co motyw ustawia na ścieżce.
   Rozmiar 8×8 jest wpisany w atrybuty `width`/`height` renderowane po stronie
   serwera, więc trzeba go nadpisać właściwościami CSS. */
[data-header] .ct-header .ct-toggle-dropdown-desktop svg.ct-icon,
[data-header] .ct-header .ct-toggle-dropdown-mobile svg.ct-icon {
  width: 11px;
  height: 11px;
}
[data-header] .ct-header .ct-toggle-dropdown-desktop svg.ct-icon path,
[data-header] .ct-header .ct-toggle-dropdown-mobile svg.ct-icon path {
  fill: var(--op-tekst-2);
}
/* Strzałka trzyma się tekstu pozycji: rozjaśnia się razem z nim. */
[data-header] .ct-header .ct-sub-menu-parent:hover .ct-toggle-dropdown-desktop svg.ct-icon path,
[data-header] .ct-header .current-menu-ancestor .ct-toggle-dropdown-desktop svg.ct-icon path,
[data-header] .ct-header .current-menu-parent .ct-toggle-dropdown-desktop svg.ct-icon path {
  fill: var(--op-tekst);
}

/* Rozwijane podmenu jedzie na frezie, żeby nie świeciło bielą nad pianką. */
.ct-header .sub-menu {
  background-color: var(--op-frez);
  border: var(--op-kreska) solid var(--op-linia);
  border-radius: var(--op-r-pole);
}
.ct-header .sub-menu .ct-menu-link { color: var(--op-tekst-2); }
.ct-header .sub-menu .ct-menu-link:hover { color: var(--op-tekst); }

/* --- telefon: kontur, nie pole ---
   Pełny cynober należy do formularza. Zieleń #2D7A3F pochodzi ze starego
   motywu i jest jedyną zielenią w witrynie; przyciski miały też 34 px
   wysokości, poniżej progu celu dotykowego. */

/* ⚠️ Jedyne wymuszenia w całym systemie — trzy, wszystkie tutaj.
   Neutralizują regułę `a.ct-button` z Customizera (16 VIII), która wymusza
   zieleń rgb(45,122,63) na tle i na kancie przycisku. Powstała, żeby podnieść
   kontrast zielonych CTA na BIAŁYM nagłówku (2,20 → 5,29:1) — na piance nie ma
   już czego ratować, a zieleń jest jedynym takim kolorem w witrynie.
   Po sprzątnięciu tamtej reguły w Customizerze te trzy mają zniknąć. */
[data-header] .ct-header .ct-header-cta .ct-button,
[data-header] .ct-header .ct-header-cta a.ct-button {
  min-height: 44px;
  padding-inline: var(--op-p4);
  /* op:wyjatek */
  border: var(--op-kreska-2) solid var(--op-linia-mocna) !important;
  border-radius: var(--op-r-pole);
  /* op:wyjatek */
  background-color: transparent !important;
  color: var(--op-tekst);
  font-family: var(--op-font);
  font-size: var(--op-t-maly);
  font-weight: 700;
}
[data-header] .ct-header .ct-header-cta .ct-button:hover,
[data-header] .ct-header .ct-header-cta a.ct-button:hover {
  /* op:wyjatek */
  background-color: var(--op-pianka-2) !important;
  border-color: var(--op-metal-cien);
}

/* --- panel wysuwanego menu (mobile) ---
   Blocksy trzyma tło panelu na `.ct-panel-inner`, nie na `.ct-panel`. Po
   rozjaśnieniu linków menu panel został biały, a jasne linki dawały na nim
   2,22:1 — menu mobilne było nieczytelne. */

.ct-panel.ct-header .ct-panel-inner,
.ct-panel.ct-header .ct-panel-content {
  background-color: var(--op-frez);
}
.ct-panel.ct-header .ct-menu-link { color: var(--op-tekst-2); }
.ct-panel.ct-header .ct-menu-link:hover { color: var(--op-tekst); }
.ct-panel.ct-header .ct-toggle-close { color: var(--op-tekst); }

/* --- hamburger i ikony chromu --- */

.ct-header .ct-toggle,
.ct-header .ct-icon { color: var(--op-tekst); }

/* --- nagłówek wpisu/strony od motywu ---
   Blocksy renderuje własny hero z tytułem i datą: 650 px na wpisach, 45 px
   na stronach usługowych. Nasz pierwszy ekran niesie ten sam tytuł, więc
   strona miała DWA `<h1>` — 13 z 28 adresów. Do tego data szła bielą po
   jasnoszarym tle (1,36:1), bo hero był projektowany pod ciemne zdjęcie.
   Hero motywu znika tam, gdzie jest nasz świat; na stronach bez niego
   (gdyby jakaś została) zostaje nietknięty. */

body:has(.op-swiat) .hero-section {
  display: none;
}

/* --- pod wpisem: nawigacja i komentarze ---
   Oba bloki renderuje motyw, poza `.op-swiat`. Nawigacja „poprzedni/następny"
   szła granatem `rgb(44,74,107)`, a przycisk komentarza zielenią starego
   motywu — jedynymi takimi kolorami w witrynie. */

[data-prefix="single_blog_post"] .post-navigation .item-label,
[data-prefix="single_blog_post"] .post-navigation .item-title,
.post-navigation .item-label,
.post-navigation .item-title {
  font-family: var(--op-font);
  color: var(--op-tusz-2);
}
.post-navigation .item-title { color: var(--op-tusz); font-weight: 600; }
.post-navigation a:hover .item-title { color: var(--op-gniazdo-ciemny); }

/* Data i „Odpowiedz" w wątku komentarza to linki — poniżej progu 44 px. */
#comments .comment-metadata a,
#comments .reply a,
#comments .comment-reply-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

#comments,
.comment-respond {
  font-family: var(--op-font);
  color: var(--op-tusz);
}
#comments .comments-title,
.comment-reply-title {
  font-family: var(--op-font);
  color: var(--op-tusz);
}
.comment-form label,
.comment-form .comment-notes,
.comment-form .comment-form-cookies-consent label {
  color: var(--op-tusz-2);
}
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
  border: var(--op-kreska-2) solid var(--op-kant-papier);
  border-radius: var(--op-r-pole);
  background-color: var(--op-papier);
  color: var(--op-tusz);
  font-family: var(--op-font);
}
.comment-form .submit,
.comment-form [type="submit"] {
  min-height: 48px;
  padding-inline: var(--op-p5);
  border: 0;
  border-radius: var(--op-r-pole);
  /* op:wyjatek */
  background-color: var(--op-gniazdo) !important;
  color: var(--op-biel);
  font-family: var(--op-font);
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* --- stopka motywu: zostaje sam pasek praw autorskich ---
   Po przeniesieniu widgetów do nieaktywnych wiersz `middle` został pusty,
   ale trzymał 100 px wysokości — biały pas między naszą stopką a paskiem
   praw autorskich. `:has()` pilnuje, żeby wiersz wrócił, gdyby kiedyś
   wstawić w niego widget. */

[data-footer] .ct-footer [data-row="middle"]:not(:has([class*="widget"])) {
  display: none;
}


[data-footer] .ct-footer [data-row="bottom"],
.ct-footer [data-row="bottom"] {
  background-color: var(--op-frez);
  font-family: var(--op-font);
  font-size: var(--op-t-etykieta);
}
/* Kolor musi zejść na dzieci: motyw koloruje sam tekst paska granatem
   `rgb(44,74,107)`, co na frezie dawało 2,09:1. Dziedziczenie z rodzica
   przegrywa z każdą bezpośrednią regułą. */
[data-footer] .ct-footer [data-row="bottom"],
[data-footer] .ct-footer [data-row="bottom"] :is(p, span, div) {
  color: var(--op-tekst-3);
}
[data-footer] .ct-footer [data-row="bottom"] a { color: var(--op-tekst-2); }

/* --- hamburger: jedyny sposób na menu przy 375 px ---
   Blocksy maluje kreski ikony kolorem z Customizera: raz `--theme-icon-color`
   #1E262E, raz zieleń #2D7A3F — obie na frezie dają 1,25–3,60:1, więc na
   telefonie przycisk menu praktycznie znika. Customizer wymusza to `!important`,
   stąd wyjątek. */
[data-header] .ct-header .ct-header-trigger svg.ct-icon rect,
[data-header] .ct-header .ct-header-trigger svg.ct-icon path {
  /* op:wyjatek */
  fill: var(--op-tekst) !important;
}

/* --- panel wysuwany (mobile) ---
   Ciemne było tylko `.ct-panel-content`, a `.ct-panel-inner` zostawał biały —
   nad menu świecił biały pas, a pod treścią biała reszta panelu. Motyw trzyma
   to tło z `!important`. */
.ct-panel.ct-header .ct-panel-inner {
  /* op:wyjatek */
  background-color: var(--op-frez) !important;
}
.ct-panel.ct-header .ct-panel-content { background-color: transparent; }

/* Zamknięcie panelu: motyw daje granat #2C4A6B — czytelny tylko na tym białym
   pasie, którego już nie ma. */
.ct-panel.ct-header .ct-toggle-close svg.ct-icon path { fill: var(--op-tekst-2); }
.ct-panel.ct-header .ct-toggle-close:hover svg.ct-icon path { fill: var(--op-tekst); }

/* Marka w panelu: plik nagłówka ma 527 px szerokości, a panel 338 — logo
   wychodziło poza kadr i ucinało się w połowie słowa. */
.ct-panel.ct-header .site-logo-container { max-width: 100%; }
.ct-panel.ct-header .site-logo-container img {
  width: auto;
  max-width: 100%;
  height: 32px;
}

/* Blok kontaktowy w stopce panelu: #1E262E na frezie to 1,25:1. */
.ct-panel.ct-header .ct-header-text {
  color: var(--op-tekst-3);
  font-size: var(--op-t-maly);
}
.ct-panel.ct-header .ct-header-text strong,
.ct-panel.ct-header .ct-header-text a { color: var(--op-tekst); }

/* --- zieleń w stanach, których nie nazwaliśmy ---
   Motyw trzyma kolor podświetlenia w zmiennej `--theme-link-hover-color`
   (#2D7A3F, `--theme-palette-color-2`) i podstawia ją w stanach, do których
   nasze selektory nie sięgają — rozwinięta pozycja w panelu mobilnym,
   `:focus-visible`. Zamiast gonić kolejne nazwy klas, podmieniamy samą zmienną
   w obrębie chromu: każdy stan, który motyw nią maluje, ląduje w palecie. */
[data-header] .ct-header,
.ct-panel.ct-header {
  --theme-link-hover-color: var(--op-tekst);
}

/* Treść panelu musi się przewijać: przy rozwiniętym podmenu blok kontaktowy
   wychodził poza dolną krawędź i ostatnia linia adresu była ucięta w połowie. */
.ct-panel.ct-header .ct-panel-content {
  overflow-y: auto;
  overscroll-behavior: contain;
}
.ct-panel.ct-header .ct-panel-content-inner {
  padding-bottom: var(--op-p7);
}

/* --- podmenu w panelu: lista, nie karta ---
   Karta z tłem, ramką i promieniem ma sens tylko na desktopie, gdzie lista
   wisi NAD treścią strony. W panelu mobilnym tło jest już tym samym materiałem,
   więc ramka rysowała pudełko w pudełku. Zostaje wcięcie i kreska prowadząca.

   ⚠️ Selektor MUSI iść przez `#offcanvas`. Sprawdzone po kolei: `.ct-panel .sub-menu`
   i `.ct-panel.ct-header .sub-menu` nie wchodzą — motyw trzyma tę deklarację
   regułą z identyfikatorem, więc klasowa przegrywa niezależnie od liczby członów. */
#offcanvas .sub-menu {
  background-color: transparent;
  border: 0;
  border-left: var(--op-kreska) solid var(--op-linia);
  border-radius: 0;
  margin-right: 0;
  padding: var(--op-p1) 0 var(--op-p1) var(--op-p4);
}

/* op:tail:806ccc38 */
