/* =====================================================================
   Aurelia Moon — placeholder brand
   Editorial layout, recoloured onto a six-tone calm palette: cool blue-greys
   (steel/mist/sage) alternating with warm greiges (sand/sand-deep/taupe),
   deep-slate ink, hand-drawn doodles.
   All colours/fonts/spacing are tokenised below — swap freely.
   ===================================================================== */

/* ---------- Design tokens ---------- */
:root {
  /* ---------- Palette ----------
     Six given tones: cool blue-greys on one side, warm greiges on the other.
     The page alternates between the two families so it reads calm without
     going flat. Every other colour here is a tint/shade of one of the six. */
  --steel:      #7DB2C4;   /* deepest cool  — pills, brand mark, accents   */
  --mist:       #A3CBDB;   /* light cool    — the "featured" band          */
  --sage:       #B4DAD1;   /* pale green    — testimonial band, highlighter*/
  --sand:       #DBE8E5;   /* warm off-white— warm panels                  */
  --sand-deep:  #C3D6D2;   /* warm greige   — copyright band, rules        */
  --taupe:      #9EBFC3;   /* warm mid grey — depth in gradients           */

  /* Derived — the six tones give no page-white and no readable text colour.
     Ink is the steel hue pushed dark, so it sits inside the same family. */
  --canvas:       #F7F7F5;  /* page background — a lighter --sand          */
  --canvas-alt:   #EFF1F0;
  --shell:        #E9F0EF;  /* the quiz blob: warm, to offset the b/w video*/
  --ink:          #1F3238;  /* 11.7:1 on canvas                            */
  --ink-soft:     #47646E;  /*  5.8:1 on canvas                            */
  --accent:       #2F6F84;  /* solid CTAs — 6.2:1 with white text          */
  --accent-deep:  #245A6D;  /* hovers                                      */
  --taupe-deep:   #7EA3AB;
  --white:        #FFFFFF;

  /* Gradients — same six tones, blended cool-into-warm */
  --grad-hero:
    radial-gradient(85% 75% at 12% 8%, #A3CBDB 0%, rgba(188,203,210,0) 46%),
    radial-gradient(75% 65% at 55% 18%, #B4DAD1 0%, rgba(201,215,212,0) 52%),
    radial-gradient(90% 85% at 100% 60%, #DBE8E5 0%, rgba(228,222,215,0) 54%),
    radial-gradient(95% 90% at 4% 100%, #7DB2C4 0%, rgba(166,187,196,0) 58%),
    linear-gradient(152deg, #C3D6D2 0%, #B4DAD1 55%, #7DB2C4 100%);
  --grad-programs:
    radial-gradient(70% 85% at 6% 28%, #B4DAD1 0%, rgba(201,215,212,0) 58%),
    radial-gradient(55% 65% at 48% 65%, #DBE8E5 0%, rgba(228,222,215,0) 58%),
    radial-gradient(85% 95% at 100% 40%, #7DB2C4 0%, rgba(166,187,196,0) 64%),
    linear-gradient(108deg, #A3CBDB 0%, #C3D6D2 48%, #7DB2C4 100%);
  /* Section washes. Where a wave meets a section, the gradient must hit the
     wave's flat colour exactly at that edge — otherwise the seam shows.
     Edge colours are therefore pinned, and the movement happens in between. */

  /* Sand at the top edge (matches .wave--struggle-top), with a light bloom
     behind the figure so the eye lands in the middle of the ring. */
  --grad-struggle:
    radial-gradient(58% 46% at 50% 54%, rgba(249,247,243,.85) 0%, rgba(249,247,243,0) 70%),
    linear-gradient(180deg, #DBE8E5 0%, #DAD3CA 100%);
  /* „Dlaczego TU jestem” i „Pulsing holistyczny” siedziały na gołym canvasie
     i przez to górna połowa strony robiła się biała. Teraz obie mają wlasny
     wash, a ponieważ nie dzieli ich żadna fala, muszą się stykać dokładnie
     tym samym kolorem: about kończy na #CFE3DE, pulsing od niego zaczyna
     i kończy na #DCE9E6, od którego rusza sekcja z ofertą.
     Rozświetlenia radialne trzymają się środka wysokości — gdyby sięgnęły
     krawędzi, szew między sekcjami przestałby być niewidoczny. */
  --grad-about:
    radial-gradient(46% 40% at 84% 46%, #A3CBDB 0%, rgba(163,203,219,0) 72%),
    radial-gradient(40% 34% at 10% 60%, #B4DAD1 0%, rgba(180,218,209,0) 74%),
    linear-gradient(180deg, #E3EDEA 0%, #CFE3DE 100%);
  --grad-pulsing:
    radial-gradient(44% 38% at 14% 44%, #A3CBDB 0%, rgba(163,203,219,0) 72%),
    radial-gradient(48% 36% at 88% 56%, #B4DAD1 0%, rgba(180,218,209,0) 72%),
    linear-gradient(180deg, #CFE3DE 0%, #DCE9E6 100%);
  /* Zaczyna tam, gdzie kończy pulsing. Ends on sand, which .wave--price-top
     is filled with. */
  --grad-offer:   linear-gradient(180deg, #DCE9E6 0%, #DBE8E5 100%);
  /* Sage pinned top and bottom — waves on both sides are filled with it. */
  --grad-reviews: linear-gradient(180deg, #B4DAD1 0%, #C5E3DB 48%, #B4DAD1 100%);
  --grad-footer:  linear-gradient(180deg, #23404A 0%, #192E36 100%);

  --grad-price:
    radial-gradient(70% 80% at 12% 16%, #B4DAD1 0%, rgba(201,215,212,0) 58%),
    radial-gradient(62% 70% at 80% 28%, #A3CBDB 0%, rgba(188,203,210,0) 60%),
    radial-gradient(90% 95% at 46% 104%, #7DB2C4 0%, rgba(166,187,196,0) 64%),
    linear-gradient(152deg, #DBE8E5 0%, #B4DAD1 52%, #7DB2C4 100%);
  --grad-photo-warm: linear-gradient(150deg, #DBE8E5, #C3D6D2 60%, #9EBFC3);
  --grad-photo-cool: linear-gradient(150deg, #B4DAD1, #A3CBDB 60%, #7DB2C4);
  --grad-photo-mono: linear-gradient(150deg, #C3D6D2, #9EBFC3 60%, #7EA3AB);

  /* Type */
  --font-display: "Instrument Serif", Georgia, "Times New Roman", serif;
  --font-body:    "Newsreader", Georgia, serif;
  --font-label:   "Oswald", "Arial Narrow", sans-serif;
  --font-script:  "Caveat", "Segoe Script", cursive;

  --fs-hero:   clamp(2.5rem, 4.6vw, 4rem);
  --fs-h2:     clamp(2rem, 4.2vw, 3.4rem);
  --fs-h3:     clamp(1.2rem, 1.8vw, 1.45rem);
  --fs-script: clamp(1.9rem, 3.6vw, 3rem);
  --fs-body:   1.0625rem;
  --fs-eyebrow:0.78rem;

  /* Space (from reference preset scale) */
  --sp-1: 0.44rem;
  --sp-2: 0.67rem;
  --sp-3: 1rem;
  --sp-4: 1.5rem;
  --sp-5: 2.25rem;
  --sp-6: 3.38rem;
  --sp-7: 5.06rem;
  --section-y: clamp(3.5rem, 8vw, 7rem);

  /* Shape */
  --radius-pill: 999px;
  --radius-img: 6px;
  --container: 1180px;
  --header-h: 74px;
  /* Shared plus marker. Kept here so list bullets and any future use draw
     the same shape at the same weight. */
  --plus-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M6 1.2v9.6M1.2 6h9.6' stroke='%23000' stroke-width='1.5' stroke-linecap='round' fill='none'/%3E%3C/svg%3E");
  --shadow-soft: 0 18px 40px -24px rgba(36,50,56,.35);
  --shadow-frame: 6px 8px 0 rgba(36,50,56,.08);
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
em { font-style: italic; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}

/* ---------- Shared type helpers ---------- */
.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: 1.04;
  letter-spacing: .01em;
}
.section-title--center { text-align: center; }

.eyebrow {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .2em;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
}
.eyebrow--pill {
  display: inline-block;
  background: var(--steel);
  color: var(--ink);
  padding: .55em 1.2em;
  border-radius: var(--radius-pill);
}

.script {
  font-family: var(--font-script);
  font-size: var(--fs-script);
  line-height: .95;
  color: var(--ink);
}

.link-accent {
  color: var(--accent-deep);
  border-bottom: 2px solid rgba(68,101,116,.4);
  transition: border-color .2s;
}
.link-accent:hover { border-color: var(--accent-deep); }

/* Was an em dash glued to a → with letter-spacing:-.15em. The two glyphs
   resolve from different fallback fonts, so their bar heights and stroke
   weights never lined up and the join drifted per button. One path now, so
   the shaft and the head are the same weight by construction. */
.arrow {
  flex: 0 0 auto;
  width: 2.15em;
  height: .62em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .25s ease;
}

/* ---------- Pills / buttons ----------
   Klient poprosił, żeby wszystkie przyciski na stronie wyglądały jednakowo:
   kształt pigułki, morskie wypełnienie, biały napis. Pięć wariantów
   kolorystycznych (--solid, --dark, --steel, --outline, --steel-outline)
   sprowadzono więc do dwóch ROL: pełnej i obrysowej. Nazwy klas zostają
   nietknięte, bo siedzą w jedenastu plikach HTML, a rola i tak wynika z tego,
   czy przycisk stoi sam, czy w parze — a pary już były zapisane jako
   „pełny + obrysowy”. */
.pill {
  --pill-bg: var(--accent);
  --pill-fg: var(--white);
  --pill-line: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: .5em;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .13em;
  font-size: .74rem;
  font-weight: 500;
  padding: .95em 1.6em;
  border-radius: var(--radius-pill);
  background: var(--pill-bg);
  color: var(--pill-fg);
  border: 1.5px solid var(--pill-line);
  cursor: pointer;
  transition: transform .2s ease, box-shadow .2s ease, background .2s ease,
              color .2s ease, border-color .2s ease;
  white-space: nowrap;
}
/* Najechanie ZMIENIA KOLOR, nie tylko podnosi — wzorcem był okrągły „Wyślij”
   w formularzu na podstronie kontaktowej, który rozjaśnia się ze stalowego
   w szałwiowy. Tutaj ten sam ruch: ciemny morski rozjaśnia się w stalowy,
   a napis przeskakuje na atramentowy, żeby utrzymać kontrast. */
.pill:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-soft);
  --pill-bg: var(--steel);
  --pill-fg: var(--ink);
  --pill-line: var(--steel);
}
.pill:hover .arrow { transform: translateX(4px); }

/* Pełny — główna akcja. */
.pill--solid,
.pill--dark,
.pill--steel { --pill-bg: var(--accent); --pill-fg: var(--white); --pill-line: var(--accent); }

/* Obrysowy — druga akcja, gdy przyciski stoją obok siebie. Napis w kolorze
   obrysu, zgodnie z prośbą. Ciemniejszy odcień niż w wersji pełnej, bo dwa
   takie przyciski leżą na szałwiowym tle, gdzie jaśniejszy morski dawałby
   3.7:1 — poniżej progu dla tak drobnego pisma. */
.pill--outline,
.pill--steel-outline,
.pill--ghost {
  --pill-bg: transparent;
  --pill-fg: var(--accent-deep);
  --pill-line: var(--accent-deep);
}
/* Obrysowy po najechaniu wypełnia się — to jego odpowiednik zmiany koloru. */
.pill--outline:hover,
.pill--steel-outline:hover,
.pill--ghost:hover {
  --pill-bg: var(--accent-deep);
  --pill-fg: var(--white);
  --pill-line: var(--accent-deep);
}
.pill--bare { --pill-bg: transparent; --pill-fg: var(--ink); border-color: transparent; padding-inline: .5em; }
.pill--bare:hover { box-shadow: none; }
.pill--user::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent); margin-right: .1em;
}
.pill--login {
  --pill-bg: transparent; --pill-fg: var(--ink);
  border-color: rgba(36,50,56,.25);
  padding: .6em 1.2em; font-size: .68rem;
}
.pill--login::before {
  content: "";
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
}

/* ---------- Placeholder photos ---------- */
.photo {
  position: relative;
  display: grid;
  place-items: center;
  border-radius: var(--radius-img);
  background: var(--grad-photo-mono);
  color: rgba(255,255,255,.6);
  overflow: hidden;
  aspect-ratio: 4 / 5;
}
.photo > svg { width: 42%; height: auto; }
.photo--warm { background: var(--grad-photo-warm); }
.photo--cool { background: var(--grad-photo-cool); }
.photo--mono { background: var(--grad-photo-mono); }
.photo__tag {
  position: absolute;
  bottom: .7rem;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .58rem;
  color: rgba(255,255,255,.85);
  background: rgba(36,50,56,.28);
  padding: .35em .8em;
  border-radius: var(--radius-pill);
}

/* ---------- Reveal animation (progressive enhancement) ----------
   Hidden state only applies when JS is active (html.js), so the page
   still shows all content if JS is disabled or fails. */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s ease, transform .7s cubic-bezier(.2,.7,.2,1);
}
.js .reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  /* Duration only, not `none`: the drawer's visibility delay has to survive
     or the panel disappears the instant it starts moving. */
  .nav-drawer, .nav-scrim { transition-duration: 0s; }
}

/* =====================================================================
   HEADER / NAV
   ===================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  /* Tło nieprzezroczyste, bez backdrop-filter. Wcześniej pasek był
     półprzezroczysty z rozmyciem i leżał na odtwarzanym wideo — przeglądarka
     przeliczała rozmycie przy każdej klatce filmu, przez co obraz się ciął.
     Różnica w wyglądzie to 10% krycia, koszt był ciągły. */
  background: var(--canvas);
  transition: box-shadow .3s ease, background .3s ease;
}
.site-header.is-scrolled { box-shadow: 0 1px 0 rgba(36,50,56,.1); }
/* Three columns so the brand sits dead centre regardless of how wide the
   two link groups are: JA · PULSING | LOGO | DLA CIEBIE · SPOTKAJMY SIĘ */
.header__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-4);
  /* Shared with the drawer, which pads its top by exactly this much so the
     first link clears the bar. Keep the two in step through the variable. */
  min-height: var(--header-h);
}
/* Scroll lock while the drawer is open — set by main.js on <html>. */
.is-nav-locked { overflow: hidden; }
.brand { display: inline-flex; align-items: center; gap: .6rem; }
/* The emblem is already a circle on a transparent background, so it gets no
   plate and no border-radius behind it — a steel disc would just draw a
   second, slightly-off circle around the drawn one. Height drives the size;
   width follows the artwork's 1.26:1 ratio. */
/* Sam sygnet, bez napisu obok — dlatego większy niż wcześniej, inaczej
   ginąłby w pasku nawigacji jako samotny drobiazg. */
.brand__mark {
  height: 58px;
  width: auto;
  object-fit: contain;
}
.brand__name {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .82rem;
  font-weight: 500;
}
/* The wrapper vanishes from the box tree here, so its two <nav> children are
   grid items of .header__inner directly. Columns are stated outright because
   the brand now precedes them in the DOM. */
.nav-drawer { display: contents; }
/* Row 1 has to be stated too. The brand precedes the navs in the DOM and
   takes column 2, so auto-placement cannot walk back to column 1 and would
   drop the left nav onto a second row — a 26px taller bar. */
.nav--left  { grid-column: 1; grid-row: 1; }
.brand      { grid-column: 2; grid-row: 1; }
.nav--right { grid-column: 3; grid-row: 1; }
.nav--left, .nav--right, .brand { justify-self: center; }
.nav-scrim { display: none; }
.nav__list {
  --nav-gap: clamp(.9rem, 1.8vw, 1.7rem);
  display: flex;
  gap: var(--nav-gap);
}
/* Hairline between links, drawn as a pseudo-element on every item but the
   first — no extra markup, and nothing to remove when the menu stacks.
   The matching margin makes the gap read the same either side of the rule,
   instead of flex-gap on one side and nothing on the other. */
.nav__list li { display: flex; align-items: center; }
.nav__list li + li::before {
  content: "";
  flex: 0 0 auto;
  width: 1px;
  height: .75em;
  margin-right: var(--nav-gap);
  background: currentColor;
  opacity: .22;
}
.nav__list a {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .13em;
  font-size: .74rem;
  font-weight: 400;
  padding: .4em 0;
  position: relative;
}
.nav__list a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 0; height: 1.5px; background: var(--accent);
  transition: width .25s ease;
}
.nav__list a:hover::after { width: 100%; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 42px; height: 42px;
  background: none; border: none; cursor: pointer;
  margin-left: auto;
}
.nav-toggle span {
  display: block; height: 2px; width: 24px;
  background: var(--ink);
  transition: transform .3s ease, opacity .3s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* =====================================================================
   HERO
   ===================================================================== */
.hero {
  position: relative;
  width: 100%;
  overflow: hidden;
  display: flex;
  /* stretch (not center) so .hero__content spans the full hero height:
     the copy then sits high, and the quiz badge can anchor to the bottom. */
  align-items: stretch;
  min-height: min(90vh, 800px);
}
/* Full-bleed video background layer (mesh gradient is the fallback) */
.hero__bg { position: absolute; inset: 0; background: var(--grad-hero); }
/* Source clip is portrait 3:4, so a wide hero crops it hard top/bottom.
   object-position biases the visible band upward, where the faces sit. */
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Nowy materiał jest poziomy 16:9, a hero na desktopie ma prawie tę samą
     proporcję — kadr niemal się nie przycina. Poprzednie 12% podnosiło kadr,
     bo źródło było pionowe 3:4 i traciło góra-dół. Teraz środek. */
  object-position: center center;
  display: block;
  /* Czerń-biel jest WYPALONA W PLIKU, nie robiona filtrem CSS. Filtr na
     odtwarzanym wideo każe przeglądarce przeliczać każdą klatkę na nowo —
     dokładnie ten mechanizm powodował wcześniejsze ścinanie (wtedy przez
     backdrop-filter w pasku nawigacji). Przy okazji odjęcie koloru odchudza
     plik, więc ten sam ciężar wystarczył na 1920x1080 zamiast 1600x900. */
}
/* Przyciemnienie zamiast rozjaśnienia: napis w hero jest teraz biały, więc
   podkład pod nim musi iść w drugą stronę niż wcześniej. Najmocniejsze po
   lewej, gdzie siedzi tekst, i wygasa przed prawą krawędzią, żeby nie
   zabić kadru. */
.hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(18,28,32,.62) 0%, rgba(18,28,32,.40) 42%, rgba(18,28,32,.14) 72%, rgba(18,28,32,.08) 100%),
    linear-gradient(0deg, rgba(18,28,32,.30), rgba(18,28,32,0) 52%);
}
/* Odznaka z quizem zniknęła, więc nic już nie kotwiczy się przy dolnej
   krawędzi — tekst wyrównuje się do środka pionu zamiast siedzieć wysoko. */
.hero__content {
  position: relative;
  z-index: 2;
  width: 100%;
  display: flex;
  align-items: center;
  padding-block: clamp(3rem, 7vw, 6rem);
}
.hero__copy { max-width: 620px; }
.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-hero);
  line-height: 1.02;
  letter-spacing: .005em;
  margin-bottom: var(--sp-3);
  /* Biały napis na czarno-białym kadrze. Cień jest ubezpieczeniem: klatki
     wideo bywają jasne i sam scrim nie zawsze wystarcza. */
  color: var(--white);
  text-shadow: 0 2px 18px rgba(12,20,24,.5);
  /* Podniesiony o dwa wiersze względem środka kadru. Wartość w em liczy się
     od własnego stopnia pisma (2 × line-height 1.02), więc przesunięcie
     skaluje się razem z nagłówkiem i na telefonie nie robi się nadmierne.
     transform, nie margines — nie rusza układu, a hero ma stałą wysokość. */
  transform: translateY(-2.04em);
}
/* Gdy nagłówek jest w hero sam, jego dolny margines byłby martwą przestrzenią
   i przesuwałby tekst w górę względem środka kadru. */
.hero__title:last-child { margin-bottom: 0; }
/* Sage highlighter behind the emphasised word.
   Stops are % of the inline content box (font ascent + descent). In
   Instrument Serif the lowercase letters run 36%–76% and the baseline sits
   at 76%, so 56%→90% starts at the middle of the letters and runs just past
   the baseline — a marker stroke, not a block behind the whole word. */
/* Zakreślenie w fiolecie z nowego logo. Wcześniej był tu morski --accent-deep,
   a jeszcze wcześniej szałwiowy — ten ostatni odpadł, bo biel na nim daje
   1.5:1 i dolna połowa liter znikała. Fiolet trzyma 4.73:1 z bielą, czyli
   przechodzi próg 4.5:1 nawet jak na drobne pismo, a nagłówek jest duży. */
.hero__title .mark {
  --zakreslacz: #9541FC;
  background: linear-gradient(transparent 56%, var(--zakreslacz) 56%, var(--zakreslacz) 90%, transparent 90%);
  padding: 0 .1em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.hero__sub {
  max-width: 34ch;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--ink);
}

/* Circular quiz badge — overlaps the seam between panels.
   Anchored to the bottom rather than centred with translateY(-50%):
   .reveal's `transform: none` would cancel that transform and drop the
   badge out of the hero. Leaving transform free keeps the reveal intact. */
.quiz-badge {
  position: absolute;
  /* Left edge lines up with the hero copy: the offset is measured from the
     container's padding box, so reusing the container's inline padding puts
     the badge flush with the text above it. */
  left: clamp(1.25rem, 4vw, 2.5rem);
  /* Clears the wave rising out of the section below — the badge and the wave
     are nearly the same tone, so any overlap reads as a smudge. */
  bottom: clamp(3rem, 7vw, 6.5rem);
  z-index: 3;
  background: var(--shell);
  border-radius: 49% 51% 50% 50% / 52% 52% 48% 48%;
  width: clamp(250px, 26vw, 330px);
  aspect-ratio: 1 / 0.96;
  display: grid;
  place-content: center;
  text-align: center;
  padding: clamp(1.5rem, 3vw, 2.75rem);
  box-shadow: var(--shadow-soft);
}
.quiz-badge__kicker {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.3vw, 1.95rem);
  line-height: 1.1;
  margin-bottom: .6rem;
}
/* Wariant „grubszy” — większy padding, ale kształt już taki sam jak reszta.
   Wcześniej miał tu prostokąt o promieniu 8px; klient chce jeden kształt
   na całej stronie, więc promień wraca do odziedziczonej pigułki. */
.pill--quiz {
  padding: 1em 1.7em;
  font-size: .72rem;
}
.quiz-badge__text {
  font-size: .78rem;
  line-height: 1.4;
  color: var(--ink-soft);
  max-width: 24ch;
  margin: 0 auto var(--sp-3);
}
.quiz-badge .pill { justify-self: center; }
/* Rotated upright so the wave runs vertically down the badge's left edge. */
/* Wewnątrz bąbla, poziomo, nad tekstem. Poprzednio ozdobnik wisiał na lewej
   krawędzi obrócony o 90° — przy linii pulsu wyglądało to jak przypadkowa
   czarna plama, bo puls czyta się wyłącznie w poziomie. */
.doodle--pulse {
  display: block;
  width: 108px; height: 34px;
  margin: 0 auto .6rem;
  fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round;
  stroke-linejoin: round;
}

/* =====================================================================
   STRUGGLE — figure ringed by nine questions
   ===================================================================== */
.struggle {
  position: relative;
  padding-block: var(--section-y);
  /* Warm band so the section reads as its own chapter — a wave divider is
     only visible where two different colours meet. */
  background: var(--grad-struggle);
  /* Wider than --container: the ring needs the extra room to breathe. */
  --stage-w: min(1360px, 94vw);
}
/* Sits above the section edge, so the band curves up into the hero video.
   top:1px + a full -100% shift lands the wave's bottom 1px *inside* the
   section. A -99% shift leaves a sub-pixel gap that the dark video shows
   through as a hairline. */
.wave--struggle-top {
  position: absolute; top: 1px; left: 0;
  width: 100%;
  height: clamp(58px, 5.5vw, 92px);
  fill: var(--sand);
  transform: translateY(-100%);
}
/* Filled with the About section's colour, which curves up into the band.
   Musi być dokładnie górna krawędź --grad-about, inaczej na styku widać pasek. */
.wave--struggle-bottom {
  position: absolute; bottom: -1px; left: 0;
  width: 100%; height: 56px;
  fill: #E3EDEA;
}
.struggle__title {
  margin-inline: auto;
  margin-bottom: clamp(1.5rem, 3.5vw, 2.75rem);
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
  max-width: 20ch;
}
.struggle__stage {
  position: relative;
  width: var(--stage-w);
  margin-inline: auto;
  min-height: 780px;
  display: grid;
  place-items: center;
}
.struggle__figure {
  width: clamp(220px, 24vw, 340px);
  height: auto;
  /* Maska wygaszająca dół sprawia, że sylwetka optycznie osiada niżej niż
     środek pierścienia. Podniesienie wyrównuje ją względem elipsy. */
  transform: translateY(-6%);
  /* Half-desaturated so the colour photo sits with the b/w hero footage. */
  filter: grayscale(.45) contrast(.97);
  /* The cut-out is clean, but the frame chops his thighs off square. Fading
     the bottom out dissolves that hard edge into the canvas. */
  -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent 96%);
          mask-image: linear-gradient(to bottom, #000 58%, transparent 96%);
}

.struggle__questions { position: absolute; inset: 0; }
/* Nine points on an ellipse (rx 40%, ry 44%), 40° apart from 12 o'clock.
   The pair of long questions lands bottom-left/bottom-right where there is
   the most horizontal room; the short ones take the tight side positions. */
.struggle__q {
  position: absolute;
  transform: translate(-50%, -50%) rotate(var(--tilt, 0deg));
  /* width:max-content jest tu konieczne. Element pozycjonowany absolutnie bez
     podanej szerokości zwęża się do przestrzeni, jaka została od jego `left`
     do prawej krawędzi kontenera — a chmurka na godzinie 3 stoi na 90%
     szerokości sceny, więc zostawało jej 10% i rozpadała się na cztery wiersze,
     robiąc się kwadratem. max-content ignoruje tę dostępną szerokość, a limit
     trzyma max-width poniżej. */
  width: max-content;
  /* 13rem, nie 15.5: po zamianie tekstów miejscami najdłuższa chmurka trafiła
     do pary przy godzinie 12, obok równie długiej. Przy 15.5rem ta para
     zachodziła na siebie poniżej ~1150px szerokości okna, a rozsunięcie
     promieniem wypychało chmurki z boków poza scenę. Węższe pudełko rozwiązuje
     jedno i drugie i nadal daje prostokąt, nie kwadrat. */
  max-width: 13rem;
  padding: .72em 1.15em;
  border-radius: 14px;
  background: var(--shell);
  color: var(--ink);
  font-size: 1.08rem;
  line-height: 1.35;
  text-align: center;
  text-wrap: balance;
  box-shadow: var(--shadow-soft);
  /* Fades in with the stage — opacity only, so nothing fights the transform. */
  opacity: 1;
  transition: opacity .6s ease;
  transition-delay: calc(var(--i) * 70ms);
}
.js .struggle__stage:not(.is-visible) .struggle__q { opacity: 0; }

/* Pozycje liczone wprost z kąta, zamiast dwudziestu ręcznie wpisanych
   sinusów. --i siedzi już w atrybucie style każdej chmurki (steruje
   opóźnieniem pojawiania się), więc wystarczy przez nie pomnożyć krok.
   Doszła dziesiąta chmurka, więc krok to 360/10 = 36°.

   --obrot obraca cały pierścień o pół kroku. Na szerokim ekranie jest
   ustawiony, żeby żadna chmurka nie stanęła dokładnie nad ani pod sylwetką.
   Na telefonie schodzi do zera — tam pierścień ma 33% szerokości sceny
   i para chmurek przy godzinie 12 nie ma się jak rozminąć, więc na górze
   i na dole musi stać po jednej. */
.struggle__questions { --rx: 38%; --ry: 44%; --krok: 36deg; --obrot: 18deg; }
.struggle__q {
  --kat: calc(var(--i) * var(--krok) + var(--obrot));
  left: calc(50% + sin(var(--kat)) * var(--rx));
  top:  calc(50% - cos(var(--kat)) * var(--ry));
}
/* Lekkie przekrzywienie, żeby pierścień nie wyglądał jak wydruk. */
.struggle__q:nth-child(4n+1) { --tilt: -1.5deg; }
.struggle__q:nth-child(4n+2) { --tilt:  2deg; }
.struggle__q:nth-child(4n+3) { --tilt: -1deg; }
.struggle__q:nth-child(4n)   { --tilt:  1.5deg; }

/* Rotate through three tones so the ring is not one flat colour. Note the
   first is canvas, not sand — sand is now the section background. */
.struggle__q:nth-child(3n+1) { background: var(--canvas); }
.struggle__q:nth-child(3n+2) { background: var(--mist); }
.struggle__q:nth-child(3n)   { background: var(--sage); }
/* Dziesięć nie dzieli się przez trzy, więc ostatnia chmurka wypadała w tym
   samym odcieniu co pierwsza, a na pierścieniu stoją obok siebie. */
.struggle__q:nth-child(10)   { background: var(--mist); }

.struggle__lead {
  /* 68, nie 62: dwa najdłuższe zdania i tak nie mieszczą się w jednym wierszu,
     a przy tej szerokości zawijają się dokładnie po przecinku zamiast rozrywać
     „poczucia porażki” na pół. Nadal w wygodnej mierze czytania. */
  max-width: 68ch;
  margin: clamp(2rem, 4vw, 3.25rem) auto 0;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
  text-align: center;
  font-size: 1.08rem;
  line-height: 1.75;
  color: var(--ink-soft);
}
.struggle__lead strong { color: var(--ink); font-weight: 500; }

/* =====================================================================
   ABOUT / INTRO
   ===================================================================== */
.about { background: var(--grad-about); padding-block: var(--section-y); }
.about__grid {
  display: grid;
  grid-template-columns: .9fr 1.1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
/* Collage: portrait main + tilted two-frame filmstrip */
.collage { position: relative; padding: 0 2.5rem 3rem 0; }
.collage__main {
  position: relative;
  overflow: hidden;
  aspect-ratio: 3 / 3.7;
  border-radius: 2px;
  box-shadow: var(--shadow-soft);
  /* Shows through until the first slide decodes. */
  background: var(--grad-photo-cool);
}
/* Pojedyncze zdjęcie zamiast slajdera — wypełnia kontener tak samo jak
   wcześniej robiły to slajdy, tylko bez przenikania i bez pozycjonowania
   absolutnego (nie ma już czego na siebie nakładać). */
.collage__photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Slides are stacked; only .is-active is opaque, so they cross-fade. */
.slider__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.slider__slide.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .slider__slide { transition: none; }
}
.filmstrip {
  position: absolute;
  right: 0; bottom: 0;
  width: 33%;
  display: grid;
  gap: 4px;
  padding: 6px;
  background: #1B262B;
  border-radius: 2px;
  box-shadow: var(--shadow-soft);
  transform: rotate(-11deg);
}
.filmstrip__frame {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 0.9;
  object-fit: cover;
  border-radius: 0;
  filter: grayscale(1) contrast(1.05);
}
.photo--dark { background: linear-gradient(150deg, #46585F, #26343A); color: rgba(255,255,255,.45); }

/* Copy: centered head with overlapping script + divider */
.about__copy { display: flex; flex-direction: column; align-items: center; }
.about__head { width: 100%; text-align: center; margin-bottom: var(--sp-4); }
.about__script {
  position: relative;
  z-index: 2;
  display: block;
  margin: 0 0 -0.6rem 4.5rem;
}
.about__title { text-align: center; }
.about__rule {
  display: block;
  width: 82px; height: 1px;
  background: var(--ink);
  opacity: .45;
  margin: var(--sp-3) auto 0;
}
.about__lead {
  width: 100%;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.3vw, 1.95rem);
  line-height: 1.3;
  text-align: center;
  margin-bottom: var(--sp-4);
}
/* Ten sam fiolet co zakreślacz w hero, ale przepuszczony przez krycie.
   W hero litery są białe i leżą na ciemnym kadrze, więc pełna moc koloru
   działa. Tutaj tekst jest atramentowy na jasnej sekcji — pełny #9541FC dałby
   pod nim 2.7:1, czyli dolna połowa liter zrobiłaby się nieczytelna.
   Przezroczystość zachowuje odcień, a przepuszcza tło sekcji. */
.mark-soft {
  --zakreslacz-jasny: rgba(149, 65, 252, .42);
  background: linear-gradient(transparent 56%, var(--zakreslacz-jasny) 56%,
                              var(--zakreslacz-jasny) 90%, transparent 90%);
  /* Zakreślone słowa idą na pełny atrament. W nagłówku i tak taki jest, ale
     w akapicie tekst jest przygaszony do --ink-soft i na fiolecie schodził
     do 2.3:1. Pełny atrament daje 4.9:1 w najgorszym miejscu gradientu —
     i przy okazji zakreślenie faktycznie podbija te słowa, a nie przygasza. */
  color: var(--ink);
  padding: 0 .06em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.about__secondary {
  /* 54, nie 48: doszły wymuszone łamania po każdym zdaniu i przy 48 znakach
     ostatnie słowo każdego z nich zostawało samo w linii („forsuję.”,
     „zawodowym.”). Przy 54 żadne zdanie nie zostawia sieroty. */
  max-width: 54ch;
  text-align: center;
  color: var(--ink-soft);
  font-size: .96rem;
  margin-bottom: var(--sp-4);
}
/* Wyróżnienie zamiast zakreślacza — na życzenie klienta. Ta sama recepta co
   w „.struggle__lead strong” i „.creed__body strong”: pełny atrament plus
   500. Sam font-weight by tu nie wystarczył, bo akapit jest przygaszony do
   --ink-soft i pogrubienie ledwo by się odcinało. */
.about__secondary strong { color: var(--ink); font-weight: 500; }
/* No align-self here: the button inherits the column's align-items: center. */

/* =====================================================================
   PULSING — copy left, media column bleeding off the right edge
   ===================================================================== */
.pulsing { background: var(--grad-pulsing); padding-block: var(--section-y); }
.pulsing__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .78fr);
  align-items: center;
  column-gap: clamp(2rem, 5vw, 4.5rem);
  /* Oba marginesy liczone tą samą formułą co w .container: jego wewnętrzny
     padding albo połowa tego, co zostaje poza maksymalną szerokością strony —
     zależnie od tego, co w danym oknie większe. Dzięki temu prawa krawędź
     wideo odbija się dokładnie w lewej krawędzi treści strony. Wcześniej
     z prawej był osobny, węższy zapas i materiał lgnął do brzegu okna. */
  --margines-strony: max(clamp(1.25rem, 4vw, 2.5rem), calc((100vw - var(--container)) / 2));
  padding-left: var(--margines-strony);
  padding-right: var(--margines-strony);
}
.pulsing__title {
  /* isolate keeps the z-index:-1 bar inside the heading, so it paints over
     the section background instead of disappearing behind it. */
  isolation: isolate;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: 1.05;
  margin-bottom: var(--sp-3);
}
.pulsing__title span { position: relative; display: inline-block; }
/* Podkreślenie pod „Pulsing holistyczny” usunięte na prośbę klienta.
   Zostawione zakomentowane, gdyby miało wrócić — wystarczy odkomentować.

.pulsing__title span::before {
  content: "";
  position: absolute;
  left: -.08em; right: -2.5em;
  bottom: .16em;
  height: .19em;
  background: #9541FC;
  z-index: -1;
}
*/
.pulsing__intro {
  max-width: 46ch;
  margin-bottom: var(--sp-4);
  color: var(--ink-soft);
}
/* Ta sama miara co przycisk pod spodem (31rem ≈ 52 znaki), żeby ich prawe
   krawędzie schodziły się co do piksela. Wcześniej lista była w ch, a przycisk
   w rem i zostawały 2px różnicy. */
.pulsing__list { max-width: 31rem; margin-bottom: var(--sp-5); }
/* Przycisk zachowuje własną szerokość, ale jest dosunięty do PRAWEJ krawędzi
   bloku z tekstem — nie do krawędzi kolumny, bo ta jest od tekstu szersza.
   Margines z lewej na auto zbiera wolne miejsce i spycha go w prawo, a margines
   z prawej odsuwa go od krawędzi kolumny dokładnie o tyle, o ile kolumna jest
   szersza od tekstu (31rem = szerokość listy powyżej). max(0px, …) chroni przed
   ujemną wartością, gdyby kolumna była węższa od tekstu.
   display:flex zamiast inline-flex, bo marginesy auto działają dopiero na
   elemencie blokowym. */
.pulsing__copy .pill {
  display: flex;
  width: max-content;
  margin-left: auto;
  margin-right: max(0px, 100% - 31rem);
}
.pulsing__list li {
  position: relative;
  padding-left: 1.9rem;
  margin-bottom: .7rem;
  line-height: 1.55;
}
/* A drawn plus, not the "+" glyph: the character's arm lengths and optical
   centre shift with whatever font resolves it, so the markers never matched
   each other or sat on the first line properly. Masked so it still takes its
   colour from CSS. */
.pulsing__list li::before {
  content: "";
  position: absolute;
  left: .2rem;
  top: .46em;
  width: .68rem;
  height: .68rem;
  background: var(--steel);
  -webkit-mask: var(--plus-mask) center / contain no-repeat;
          mask: var(--plus-mask) center / contain no-repeat;
}
/* Selektor obejmuje i obrazek, i wideo — kolumna trzyma tę samą proporcję
   niezależnie od tego, co w niej stoi. */
.pulsing__media img,
.pulsing__media video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1.12;
  object-fit: cover;
  border-radius: 2px 0 0 2px;
  box-shadow: var(--shadow-soft);
}

/* =====================================================================
   OFFER — four products, two rows of two
   ===================================================================== */
.offer {
  /* Warm band: About and Pulsing both sit on canvas, so a third one in a
     row would flatten the page. */
  background: var(--grad-offer);
  padding-block: var(--section-y);
}
/* Na osobnej podstronie sekcja nie ma nad sobą fali z poprzedniego bloku,
   więc jej górna krawędź stykałaby się z paskiem nawigacji. */
.offer--page { padding-top: clamp(4.5rem, 9vw, 7rem); }
.offer__intro {
  max-width: 54ch;
  margin: var(--sp-3) auto var(--sp-6);
  text-align: center;
  text-wrap: balance;
  font-size: 1.08rem;
  color: var(--ink-soft);
}
.offer__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3.5vw, 2.5rem);
  /* Narrower than the container: at full width a square tile becomes a
     500px slab and only two cards fit on screen. */
  max-width: 860px;
  margin-inline: auto;
}
.offer__card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  background: var(--canvas);
  border-radius: 3px;
  padding: clamp(1rem, 1.8vw, 1.4rem);
  box-shadow: var(--shadow-soft);
}
/* Zdjęcie prowadzi na podstronę produktu — klient chciał łapkę na fotce,
   nie tylko na przycisku. Kadr obcięty na linku, żeby powiększenie przy
   najechaniu działo się wewnątrz ramki, a nie rozpychało karty. */
.offer__link {
  display: block;
  overflow: hidden;
  border-radius: 2px;
  margin-bottom: var(--sp-3);
}
.offer__media {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 2px;
  margin-bottom: var(--sp-3);
  transition: transform .45s ease;
}
/* Wewnątrz linku margines schodzi na link, inaczej odstęp liczyłby się dwa razy. */
.offer__link .offer__media { margin-bottom: 0; border-radius: 0; }
/* Powiększenie odpala też najechanie na nazwę i na przycisk — cała karta
   ma się zachowywać jak jeden cel. */
.offer__card:hover .offer__media { transform: scale(1.045); }
.offer__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Przycisk w karcie dosunięty do prawej krawędzi. Karta jest kolumną flex
   z align-items:flex-start, więc wystarczy nadpisać wyrównanie samego przycisku. */
.offer__cta { align-self: flex-end; }
.offer__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-h3);
  line-height: 1.15;
  margin-bottom: .4rem;
}
.offer__namelink { color: inherit; transition: color .2s ease; }
.offer__card:hover .offer__namelink { color: var(--accent); }
.offer__namelink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.offer__text {
  color: var(--ink-soft);
  font-size: .95rem;
  line-height: 1.55;
  /* Pushes every CTA to the same baseline regardless of copy length. */
  margin-bottom: var(--sp-4);
  flex: 1 1 auto;
}

/* =====================================================================
   PRICE — gradient band, organic blob, overlapping filmstrip
   ===================================================================== */
.price {
  position: relative;
  background: var(--grad-price);
}
/* Sand cap: the offer grid above curves down into the gradient. */
.wave--price-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--sand);
  transform: rotate(180deg);
}
/* Sage cap: the reviews band below curves up into the gradient. */
.wave--price-bottom {
  position: absolute; bottom: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--sage);
}
/* Wariant dla podstrony „ja": ta sama sekcja, ale sąsiaduje z canvas z obu
   stron zamiast z sand nad i sage pod. Bez tego pod falami prześwitywałyby
   kolory sekcji, których na tamtej stronie w ogóle nie ma. */
.price--plain .wave--price-top,
.price--plain .wave--price-bottom { fill: var(--canvas); }
/* Wariant dla podstron produktów. Nad sekcją stoi blok z opisem (canvas),
   pod nią „Zobacz też” na --grad-offer, który startuje z #DCE9E6. Dolna fala
   przejęła przy okazji robotę fali, która siedziała na górze „Zobacz też” —
   ta została z tych stron usunięta, bo dwie fale na jednym szwie dublowałyby
   się nawzajem. */
.price--post .wave--price-top { fill: var(--canvas); }
.price--post .wave--price-bottom { fill: #DCE9E6; }

.price__inner {
  position: relative;
  display: flex;
  justify-content: center;
  padding-block: clamp(4.5rem, 10vw, 8rem);
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}
.price__blob {
  background: var(--canvas);
  /* Irregular radii — a plain circle reads as a widget, not a shape.
     Needs real variance; small deviations just render as an ellipse. */
  border-radius: 57% 43% 47% 53% / 43% 56% 44% 57%;
  padding: clamp(2.75rem, 5.5vw, 4.75rem) clamp(2.5rem, 5vw, 4rem);
  width: min(620px, 100%);
  text-align: center;
  box-shadow: var(--shadow-soft);
}
.price__title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: 1.05;
}
.price__rule {
  display: block;
  width: 96px; height: 1px;
  background: var(--ink);
  opacity: .4;
  margin: var(--sp-3) auto var(--sp-4);
}
.price__lead {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  margin-bottom: var(--sp-3);
}
.price__text {
  /* 48, nie 34: doszły twarde łamania i przy poprzedniej szerokości pierwszy
     wiersz („Nie dlatego… Nie pod jakimiś warunkami.”) rozpadał się na dwa,
     przez co zamiast czterech wierszy wychodziło pięć. Bąbel daje 492px
     w środku, więc 48 znaków się mieści z zapasem. */
  max-width: 48ch;
  margin: 0 auto .55rem;
  font-size: .97rem;
  line-height: 1.6;
  color: var(--ink-soft);
}
.price__blob .pill { margin-top: var(--sp-4); }

/* Klisza. Wcześniej były to dwa niemal kwadratowe kadry w cienkiej ramce
   i czytało się to jak dwa zdjęcia, a nie jak film — stąd uwaga klienta.
   Teraz kadry mają proporcję 3:2 jak klatka małego obrazka, a po bokach
   biegną perforacje.
   Zaczepiona od środka, nie od prawej krawędzi: bąbel z ceną ma stałe 620px,
   więc jego prawa krawędź zawsze wypada na 50% + 310px. Przesunięcie o 250px
   wsuwa kliszę jakieś 60px na bąbel niezależnie od szerokości okna. */
.price__strip {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(250px, -50%) rotate(9deg);
  width: clamp(140px, 15vw, 210px);
  display: grid;
  gap: 7px;
  padding: 9px 13px;
  background: #1B262B;
  border-radius: 2px;
  box-shadow: 0 18px 40px -18px rgba(20,30,34,.7);
}
/* Perforacje wzdłuż obu krawędzi taśmy. */
.price__strip::before,
.price__strip::after {
  content: "";
  position: absolute;
  top: 7px; bottom: 7px;
  width: 6px;
  background-image: repeating-linear-gradient(180deg,
    rgba(247,247,245,.9) 0 7px, transparent 7px 15px);
  border-radius: 1px;
}
.price__strip::before { left: 3.5px; }
.price__strip::after  { right: 3.5px; }
.price__strip img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
}
/* Kadr 3:2 zdejmuje z tych zdjęć 210 px wysokości, domyślnie po równo z góry
   i z dołu — a w obu ważna treść siedzi przy przeciwnych krawędziach: numer
   63 tuż pod górną, filiżanka tuż nad dolną. Każde jedzie więc w swoją stronę.
   Wybór po nazwie pliku, nie po kolejności w kodzie, żeby przetrwał kolejną
   zamianę kadrów miejscami. */
.price__strip img[src$="price-2.jpg"] { object-position: center top; }
.price__strip img[src$="price-1.jpg"] { object-position: center bottom; }

/* =====================================================================
   REVIEWS — one quote at a time, arrows either side
   ===================================================================== */
.reviews {
  background: var(--grad-reviews);
  padding-block: clamp(3.5rem, 7vw, 5.5rem);
}
.reviews__inner {
  display: flex;
  align-items: center;
  gap: clamp(.75rem, 3vw, 2.5rem);
}
.reviews__nav {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1.5px solid rgba(36,50,56,.28);
  background: transparent;
  color: var(--ink);
  font-size: 1.1rem;
  cursor: pointer;
  transition: background .2s ease, border-color .2s ease, transform .2s ease;
}
.reviews__nav:hover { background: var(--canvas); border-color: transparent; transform: translateY(-2px); }
.reviews__nav:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Slides share one grid cell, so the band is as tall as the longest quote
   and never jumps height when you page through. The --md/--long tiers below
   keep that tallest quote in check; align-items centres the shorter ones in
   the leftover space instead of pinning them to the top. */
.reviews__viewport {
  flex: 1 1 auto;
  display: grid;
  align-items: center;
}
.review {
  grid-area: 1 / 1;
  margin: 0;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  /* Delaying visibility lets the outgoing quote stay painted while it fades. */
  transition: opacity .45s ease, visibility 0s linear .45s;
}
.review.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity .45s ease;
}
.review blockquote {
  margin: 0 auto var(--sp-4);
  max-width: 46ch;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2.1vw, 1.6rem);
  line-height: 1.4;
  text-wrap: balance;
}
.review blockquote p { margin: 0 0 .7em; }
.review blockquote p:last-child { margin-bottom: 0; }

/* Google reviews come in wildly different lengths. Two step-downs keep the
   long ones from turning into a wall of display type: wider measure, smaller
   size, looser leading. `balance` is dropped past a few lines — browsers cap
   it anyway, and `pretty` is what long-form actually wants. */
.review--md blockquote {
  max-width: 54ch;
  font-size: clamp(1.02rem, 1.6vw, 1.24rem);
  line-height: 1.5;
  text-wrap: pretty;
}
.review--long blockquote {
  max-width: 62ch;
  font-size: clamp(.95rem, 1.3vw, 1.08rem);
  line-height: 1.6;
  text-wrap: pretty;
}
.review__by {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .55rem;
}
.review__avatar {
  display: grid;
  place-items: center;
  /* 2× względem poprzednich 54px — zdjęcia klientów mają być widoczne,
     a nie ledwo zauważalne. Pliki źródłowe mają 160px, więc starcza. */
  width: 108px; height: 108px;
  border-radius: 50%;
  object-fit: cover;              /* applies once this becomes an <img> */
  background: var(--steel);
  color: var(--ink);
  font-family: var(--font-label);
  font-size: .8rem;
  letter-spacing: .1em;
}
.review__name {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .72rem;
  color: var(--ink-soft);
}
.reviews__dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: .5rem;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}
.reviews__dot {
  flex: 0 0 auto;
  width: 8px; height: 8px;
  border-radius: 100px;
  background: rgba(36,50,56,.22);
  transition: background .25s ease, width .25s ease;
}
/* The active one stretches into a short pill — at five slides a colour-only
   change is easy to miss against the sage band. */
.reviews__dot.is-active { width: 22px; background: var(--ink); }

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

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

/* =====================================================================
   FEATURED-IN BAR
   ===================================================================== */
/* Tło standardowe zamiast błękitnego pasa i prosta linia u góry zamiast
   fali — pas partnerów ma być cichy, nie ma konkurować z sekcjami wokół. */
.featured {
  position: relative;
  background: var(--canvas);
  border-top: 1px solid rgba(31,50,56,.14);
}
/* Sage cap so the wavy edge continues the bottom line of the reviews band. */
.wave--featured-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 56px;
  fill: var(--sage);
  transform: rotate(180deg);
}
.featured__inner {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  flex-wrap: wrap;
  /* Extra top padding clears the wave sitting over the band's top edge. */
  padding-block: clamp(3rem, 5.5vw, 4.25rem) clamp(1.75rem, 4vw, 2.75rem);
}
.featured__label {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .72rem;
  line-height: 1.5;
  flex: 0 0 auto;
}
.featured__logos {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 4vw, 3rem);
  flex-wrap: wrap;
  flex: 1;
  justify-content: space-around;
}
/* White tile behind each mark. Both partners supplied square emblems on an
   opaque white background, so the tile is pure --white, not --canvas: the
   file's own white then merges into it seamlessly and no cut-out is needed. */
/* Kafelek to teraz odnośnik z podpisem pod spodem. Nazwa jest częścią
   klikalnego obszaru, więc cel dotyku obejmuje logo i tekst razem. */
.partner { display: block; }
.partner__link { display: grid; justify-items: center; gap: .7rem; }
/* Bez białego kafelka i bez cienia. Białe tło jest wypalone w samych plikach,
   więc zostało przemalowane na kolor sekcji — logotypy wtapiają się w tło
   i żaden prostokąt nie prześwituje. */
.partner__link > .partner__logo {
  width: clamp(126px, 14vw, 158px);
  aspect-ratio: 1;
  transition: transform .25s ease;
}
.partner__link:hover > .partner__logo { transform: translateY(-3px); }
.partner__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; }
.partner__name {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: .72rem;
  color: var(--ink-soft);
  text-align: center;
}
/* Dashed frame reads as "drop the logo here" — a solid box would look like
   an image that failed to load. Kept for any future empty slot. */
.partner__slot {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: .5rem;
  border: 1.5px dashed rgba(36,50,56,.32);
  border-radius: 3px;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .66rem;
  color: var(--ink-soft);
  text-align: center;
}
/* What a real logo becomes once dropped in. */
.partner__logo {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* =====================================================================
   INVITE / CONTACT — copy left, tilted photo collage right, form below
   ===================================================================== */
.invite {
  position: relative;
  background: var(--grad-programs);
  padding-block: clamp(4.5rem, 9vw, 7rem) var(--section-y);
  /* Kotwica z przycisku „chcę się umówić” przy 63 złotówkach ląduje tutaj —
     bez tego górna fala i początek nagłówka chowają się pod przyklejonym
     paskiem nawigacji. */
  scroll-margin-top: var(--header-h);
}
/* Fala musi mieć kolor sekcji NAD nią. Pas partnerów dostał jasne tło,
   więc wypełnienie zeszło z --mist na --canvas — inaczej na szwie wychodził
   niebieski pasek z sekcji, która już nie jest niebieska. */
.wave--invite-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 56px;
  fill: var(--canvas);
  transform: rotate(180deg);
}
.invite__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.invite__title { max-width: 20ch; }
.doodle--pulse-flat {
  width: 120px; height: 40px;
  margin: var(--sp-3) 0;
  fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-linecap: round;
}
.invite__lead {
  max-width: 34ch;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  line-height: 1.35;
}
.invite__channels {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin-top: var(--sp-4);
}

/* The collage sits below the grid at full width now, so the three prints run
   as a row instead of overlapping inside a narrow column. The tilt stays —
   it is what makes them read as prints laid down, not a stock photo grid.
   Capped well under the container so they stay prints and not billboards. */
.invite__collage {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1rem, 3vw, 2.75rem);
  align-items: center;
  max-width: 940px;
  margin-top: clamp(3rem, 6vw, 4.5rem);
}
.invite__shot {
  width: 100%;
  /* height:auto is required — the HTML height attribute is a presentational
     hint that would otherwise win and cancel aspect-ratio. */
  height: auto;
  /* Cream mount, like a print laid on the gradient. */
  border: 10px solid var(--canvas);
  border-radius: 2px;
  box-shadow: var(--shadow-soft);
  object-fit: cover;
}
.invite__shot--a { aspect-ratio: 700 / 860; transform: rotate(-3deg); }
.invite__shot--b { aspect-ratio: 760 / 580; transform: rotate(2.5deg); }
.invite__shot--c { aspect-ratio: 640 / 780; transform: rotate(3.5deg); }

/* Zdjęcie w prawej kolumnie, na miejscu dawnego formularza. */
.invite__photo {
  width: 100%;
  height: auto;
  aspect-ratio: 700 / 860;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: var(--shadow-soft);
}

/* Trzy drogi kontaktu, wyśrodkowane, każdy przycisk w dwóch wierszach. */
.invite__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(.6rem, 1.8vw, 1.4rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.invite__or {
  font-family: var(--font-label);
  text-transform: lowercase;
  letter-spacing: .1em;
  font-size: .8rem;
  color: var(--ink-soft);
}
/* AKTUALNY WYGLĄD — nieregularny bąbel. To dosłownie pomniejszony bąbel
   z ceną: te same promienie ORAZ ta sama proporcja 620:526. Sama kopia
   promieni nie wystarcza — są procentowe, więc na prostokącie 2,2:1
   rozciągają się w gładką elipsę. Kształt trzyma się dopiero przy
   proporcji oryginału. */
.cta-tri {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: .25rem;
  width: clamp(150px, 15vw, 190px);
  aspect-ratio: 620 / 526;
  padding-inline: 1.4em;
  border-radius: 57% 43% 47% 53% / 43% 56% 44% 57%;
  background: var(--accent);
  color: var(--canvas);
  text-align: center;
  box-shadow: 0 12px 30px -18px rgba(31,50,56,.5);
  transition: transform .22s ease, box-shadow .22s ease;
}

/* ---------------------------------------------------------------------
   WERSJA OKRĄGŁA — odstawiona na prośbę klienta, zostawiona na wypadek
   powrotu. Koło jest ciaśniejsze niż bąbel: napisy stoją w dwóch wierszach
   powyżej i poniżej środka, gdzie krąg już się zwęża, więc średnica musiała
   być większa, żeby zmieścił się adres e-mail.

.cta-tri {
  width: clamp(178px, 16vw, 214px);
  aspect-ratio: 1;
  padding-inline: 1.1em;
  border-radius: 50%;
}
   --------------------------------------------------------------------- */
/* Uniesienie i cień tylko dla tego, który faktycznie gdzieś prowadzi.
   Dwa pozostałe to tabliczki informacyjne — reagowanie na najechanie
   obiecywałoby działanie, którego nie mają. */
a.cta-tri:hover { transform: translateY(-2px); box-shadow: 0 18px 36px -18px rgba(31,50,56,.6); }
a.cta-tri:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Numer i adres zostają do zaznaczenia i skopiowania. */
.cta-tri--info { cursor: default; user-select: text; }
.cta-tri__label {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .74rem;
  /* Przygaszona względem wartości pod spodem, ale na ciemnym tle robi się to
     rozjaśnieniem tła, nie przyciemnieniem tekstu — inaczej kontrast leci. */
  color: rgba(247,247,245,.93);
}
/* Pogrubiony jest wyłącznie ten dolny wiersz — numer, adres, słowo
   „formularz”. Rodzina zmieniona z display na body celowo: Instrument Serif
   ma w zestawie tylko grubość 400, więc bold musiałaby domalować przeglądarka,
   a taki sztuczny pogrubiacz przy jasnym tekście na ciemnym tle się rozlewa.
   Newsreader ma prawdziwe 600. */
.cta-tri__value {
  font-family: var(--font-body);
  font-weight: 600;
  /* Skalowany razem z bąblem, bo bąbel też jest na clamp(). Adres e-mail to
     jeden ciąg bez spacji — nie zawinie się, tylko wyjdzie na krawędź, więc
     to on wyznacza dolną granicę. */
  font-size: clamp(.94rem, .62rem + .58vw, 1.12rem);
  line-height: 1.3;
}

/* Formularz zszedł pod przyciski i jest wyśrodkowany. scroll-margin-top
   odsuwa go spod przyklejonego paska nawigacji, gdy przyjdzie tu kotwica
   z przycisku „wypełnij formularz”. */
.invite__form {
  /* Punkt odniesienia dla okrągłego przycisku wysyłki — wisi on przy prawym
     dolnym rogu formularza na ujemnych offsetach, więc bez tego zaczepiłby
     się o pierwszego pozycjonowanego przodka gdzieś wyżej. */
  position: relative;
  max-width: 620px;
  margin-top: clamp(2rem, 4vw, 3rem);
  scroll-margin-top: calc(var(--header-h) + 1.5rem);
}
.invite__form-label {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .72rem;
  margin-bottom: var(--sp-3);
}
.invite__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}
/* Klauzula informacyjna RODO pod formularzem. Górny odstęp musi przeskoczyć
   okrągły przycisk wysyłki — ten zwisa 29px poniżej dolnej krawędzi formularza,
   więc mniejszy margines wpuściłby tekst pod niego. Na telefonie przycisk
   wraca do zwykłego przepływu i taki zapas jest już niepotrzebny. */
/* Komunikat po wysyłce formularza. Przejmuje ten sam duży odstęp co
   klauzula RODO, bo tak samo musi przeskoczyć okrągły przycisk wysyłki,
   który zwisa poniżej dolnej krawędzi formularza. Gdy komunikat jest
   widoczny, klauzula pod nim wraca do zwykłego odstępu — inaczej między
   nimi zrobiłaby się dziura na dwa przeskoki przycisku. */
.form-status {
  max-width: 620px;
  margin: clamp(3.5rem, 6vw, 4.5rem) auto 0;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: .82rem;
  text-align: center;
}
/* Zieleń własna, nie --sage: szałwia to pastel do wypełnień i na jasnym tle
   sekcji dawałaby 1.9:1. Ten odcień trzyma 4.6:1 na --canvas i 4.1:1 na
   najciemniejszym miejscu gradientu pod formularzem. */
.form-status--ok { color: #1E6B4F; }
.form-status--err { color: #9B3B2E; }
.form-status[hidden] { display: none; }
.form-status:not([hidden]) + .form-nota { margin-top: var(--sp-4); }

.form-nota {
  max-width: 620px;
  margin: clamp(3.5rem, 6vw, 4.5rem) auto 0;
  font-size: .8rem;
  line-height: 1.65;
  color: var(--ink-soft);
  text-align: center;
}
.form-nota a { border-bottom: 1px solid rgba(36,50,56,.32); }
.form-nota a:hover { color: var(--accent); border-bottom-color: var(--accent); }

.field { display: block; margin-bottom: 1rem; }
.field__label {
  display: block;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: .66rem;
  margin-bottom: .35rem;
}
.field__input {
  width: 100%;
  padding: .8em 1em;
  border: 1.5px solid rgba(36,50,56,.22);
  border-radius: 4px;
  background: color-mix(in srgb, var(--canvas) 90%, transparent);
  font-family: var(--font-body);
  font-size: .95rem;
  color: var(--ink);
  resize: vertical;
}
.field__input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: transparent;
}
.invite__submit { margin-top: var(--sp-2); }

/* =====================================================================
   FAQ — native <details> accordion
   ===================================================================== */
.faq { padding-block: var(--section-y); }
.faq__eyebrow {
  display: block;
  text-align: center;
  color: var(--ink-soft);
  margin-bottom: var(--sp-2);
}
.faq__list {
  max-width: 780px;
  margin: var(--sp-6) auto 0;
}
.faq__item { border-top: 1px solid rgba(36,50,56,.14); }
.faq__item:last-of-type { border-bottom: 1px solid rgba(36,50,56,.14); }

.faq__q {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(.85rem, 2vw, 1.35rem);
  padding: 1.2rem .25rem;
  cursor: pointer;
  /* Kill the default triangle in every engine. */
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { content: ""; }
.faq__q:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

.faq__num {
  font-family: var(--font-label);
  font-size: .78rem;
  letter-spacing: .12em;
  color: var(--ink-soft);
  transition: color .25s ease;
}
.faq__text {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.7vw, 1.28rem);
  line-height: 1.3;
}
/* Plus that spins into a cross when the row opens.
   Drawn as one SVG rather than two pseudo-elements: the old version centred
   1.5px bars with margin:auto inside a 31px inner box, so the horizontal bar
   landed on a half pixel and smeared across two rows while the vertical one
   sat clean — every mark rasterised a little differently. Here the ring and
   both bars come from a single 34-unit viewBox, so all eight are identical.
   r=16.25 puts the outer edge of the 1.5 stroke exactly on the viewBox edge. */
.faq__mark {
  display: block;
  width: 34px; height: 34px;
  flex: 0 0 auto;
  transition: transform .3s ease;
}
.faq__mark-ring {
  fill: transparent;
  stroke: rgba(36,50,56,.26);
  stroke-width: 1.5;
  transition: fill .25s ease, stroke .25s ease;
}
.faq__mark-plus {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.faq__item[open] .faq__num { color: var(--accent); }
.faq__item[open] .faq__mark { transform: rotate(135deg); }
.faq__item[open] .faq__mark-ring { fill: var(--steel); stroke: transparent; }

.faq__a {
  padding: 0 0 1.5rem clamp(2rem, 4vw, 2.9rem);
  max-width: 64ch;
  color: var(--ink-soft);
  line-height: 1.65;
}
.faq__a p + p { margin-top: .8rem; }
.faq__address { font-style: normal; }

/* Smooth open/close where the engine supports animating to auto height.
   Everywhere else the panel just snaps open — no layout breakage. */
@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .faq__item::details-content {
    block-size: 0;
    overflow: hidden;
    transition: block-size .35s ease, content-visibility .35s allow-discrete;
  }
  .faq__item[open]::details-content { block-size: auto; }
}

.faq__more {
  margin-top: var(--sp-5);
  text-align: center;
  color: var(--ink-soft);
  font-size: .95rem;
}
.faq__more a {
  color: var(--accent-deep);
  border-bottom: 1.5px solid rgba(68,101,116,.4);
  transition: border-color .2s ease;
}
.faq__more a:hover { border-color: var(--accent-deep); }

@media (prefers-reduced-motion: reduce) {
  .faq__mark,
  .faq__item::details-content { transition: none; }
}

/* =====================================================================
   FOOTER
   ===================================================================== */
.footer {
  position: relative;
  background: var(--grad-footer);
  color: var(--canvas);
  /* Top padding also clears the wave sitting over the footer's top edge. */
  padding-block: clamp(4.5rem, 8vw, 6.5rem) 0;
}
/* Fala stopki jest wypełniona kolorem sekcji NAD nią, a ta zmienia się
   zależnie od podstrony — stąd zmienna zamiast sztywnego koloru. */
.footer { --footer-wave: var(--canvas); }
.footer--after-sage { --footer-wave: var(--sage); }
.footer--after-sand { --footer-wave: var(--sand); }
.wave--footer-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--footer-wave);
  transform: rotate(180deg);
}
.footer__grid {
  display: grid;
  /* Equal outer tracks keep the social icons on the page's centre line. */
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: clamp(1.5rem, 4vw, 3rem);
}
.footer__heading {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .68rem;
  color: var(--steel);
  margin-bottom: .8rem;
}
.footer__address,
.footer__lines {
  font-style: normal;
  line-height: 1.75;
  font-size: .95rem;
  color: rgba(244,241,236,.82);
}
.footer__lines { margin-top: .8rem; }
.footer__lines a {
  border-bottom: 1px solid rgba(244,241,236,.28);
  transition: border-color .2s ease, color .2s ease;
}
.footer__lines a:hover { color: var(--white); border-color: var(--steel); }

/* Środkowa kolumna: ikona, pod nią telefon i mail. */
.footer__center { display: grid; justify-items: center; }
.footer__center .footer__lines { text-align: center; }
.footer__social {
  display: flex;
  justify-content: center;
  gap: .85rem;
  /* Nudged down so the icons sit level with the address, not the headings. */
  margin-top: .35rem;
}
.social {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1.5px solid rgba(244,241,236,.28);
  color: var(--canvas);
  transition: background .22s ease, color .22s ease, border-color .22s ease, transform .22s ease;
}
.social svg { width: 21px; height: 21px; }
/* Only the solid mark gets a fill — a blanket `fill: currentColor` here would
   override the Instagram icon's inline fill="none" and paint a solid square. */
.social--fb svg { fill: currentColor; }
.social:hover {
  background: var(--steel);
  border-color: transparent;
  color: var(--ink);
  transform: translateY(-2px);
}
.social:focus-visible { outline: 2px solid var(--steel); outline-offset: 3px; }

.footer__legal {
  display: grid;
  gap: .5rem;
  justify-items: end;
  text-align: right;
}
.footer__legal a {
  font-size: .95rem;
  color: rgba(244,241,236,.82);
  border-bottom: 1px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.footer__legal a:hover { color: var(--white); border-color: var(--steel); }

.footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: clamp(2rem, 5vw, 3.25rem);
  padding-block: 1.1rem;
  border-top: 1px solid rgba(244,241,236,.14);
  font-size: .8rem;
  color: rgba(244,241,236,.6);
}
/* Floating back-to-top, in place of the old text link in the footer bar.
   Parked below the fold until there is something to scroll back from —
   visibility keeps it out of the tab order while hidden. */
.totop {
  position: fixed;
  right: clamp(1rem, 3vw, 1.75rem);
  bottom: clamp(1rem, 3vw, 1.75rem);
  z-index: 90;
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  padding: 0;
  border: 1px solid rgba(36,50,56,.12);
  border-radius: 50%;
  background: var(--canvas);
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 10px 26px -12px rgba(36,50,56,.5);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity .28s ease, transform .28s ease, visibility 0s linear .28s;
}
.totop.is-shown {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .28s ease, transform .28s ease;
}
.totop:hover { background: var(--white); }
.totop:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.totop svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
@media (prefers-reduced-motion: reduce) {
  .totop { transition-duration: 0s; }
}
.footer__credit {
  border-bottom: 1px solid transparent;
  transition: color .2s ease, border-color .2s ease;
}
.footer__credit:hover { color: var(--canvas); border-color: var(--steel); }

/* =====================================================================
   PODSTRONA „JA" — wariant hero, moja droga, jak pracuję, domknięcie
   ===================================================================== */
/* Hero podstrony nie ma własnych reguł — używa dokładnie tych samych klas co
   strona główna, żeby wysokość, kadrowanie wideo i pozycja bąbla zgadzały się
   co do piksela. Wcześniejszy wariant --page został usunięty właśnie dlatego,
   że skracał sekcję i rozjeżdżał proporcje.

   ---------- Credo ---------- */
.creed { position: relative; padding-block: var(--section-y); }
/* Ta sama geometria co .wave--struggle-top na stronie głównej: kotwica u góry
   sekcji i wypchnięcie nad własną krawędź, żeby fala wcięła się w hero.
   Wypełnienie canvas — to kolor sekcji, która wsuwa się w wideo. Fala należy
   do sekcji POD hero, więc gdy kiedyś wejdzie tam inna, musi powędrować z nią. */
.wave--creed-top {
  position: absolute; top: 1px; left: 0;
  width: 100%;
  height: clamp(58px, 5.5vw, 92px);
  fill: var(--canvas);
  transform: translateY(-100%);
}
.creed__inner {
  max-width: 720px;
  margin-inline: auto;
  text-align: center;
}
/* isolate trzyma pasek zakreślacza (z-index:-1) wewnątrz nagłówka, więc
   maluje się nad tłem sekcji zamiast pod nim zniknąć — ten sam zabieg co
   w .pulsing__title. */
/* Wariant dwukolumnowy — treść po lewej, wideo po prawej, jak w sekcji
   „Pulsing holistyczny” na stronie głównej. Sekcja zastąpiła hero, więc ma
   własny odstęp od góry: nad nią nie ma już nic poza przyklejonym paskiem. */
.creed--split { padding-top: clamp(2.5rem, 6vw, 4.5rem); }
.creed--split .creed__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .62fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}
.creed--split .creed__inner { margin: 0; max-width: none; }
.film { position: relative; }
.creed__video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 810 / 1440;
  object-fit: cover;
  border-radius: 3px;
  background: var(--ink);
  box-shadow: var(--shadow-soft);
}
/* Nakładka pokazuje się tylko wtedy, gdy JavaScript działa — inaczej zasłoniłaby
   natywne sterowanie, które jest wówczas jedynym sposobem uruchomienia. */
.film__play { display: none; }
.js .film:not(.is-playing) .film__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: .9rem;
  width: 100%;
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  /* Przyciemnienie od dołu — kadr plakatu jest u góry jasny, a podpis siedzi
     pod ikoną i musi być czytelny niezależnie od klatki. */
  background: linear-gradient(180deg, rgba(18,28,32,.12) 0%, rgba(18,28,32,.42) 100%);
  transition: background .25s ease;
}
.js .film:not(.is-playing) .film__play:hover { background: linear-gradient(180deg, rgba(18,28,32,.22) 0%, rgba(18,28,32,.52) 100%); }
.film__play:focus-visible { outline: 3px solid var(--white); outline-offset: -6px; }
.film__ikona {
  display: grid;
  place-items: center;
  width: clamp(58px, 16%, 78px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(247,247,245,.94);
  box-shadow: 0 10px 30px -12px rgba(12,20,24,.6);
  transition: transform .25s ease, background .25s ease;
}
.film__ikona svg { width: 46%; fill: var(--accent); }
.film__play:hover .film__ikona { transform: scale(1.07); background: var(--white); }
.film__podpis {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .74rem;
  color: var(--white);
  text-shadow: 0 1px 10px rgba(12,20,24,.6);
}

.creed__title {
  isolation: isolate;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: 1.1;
  letter-spacing: .01em;
}
/* Druga linia odręcznie. Caveat ma małą wysokość x, więc przy równym
   stopniu wyglądałby drobniej niż szeryfowa linia nad nim — stąd 1.34em. */
.creed__script {
  position: relative;
  display: inline-block;
  font-family: var(--font-script);
  font-size: 1.34em;
  line-height: 1;
  /* Ściągnięte z .12em — razem z marginesem „vs” dawało pod nim prawie dwa razy
     większą przerwę niż nad nim. */
  margin-top: .05em;
}
/* Przeciwstawienie dwóch pytań — własny wiersz, drobniej i przygaszone,
   żeby nie konkurowało z samymi pytaniami. */
.creed__vs {
  display: block;
  font-family: var(--font-label);
  text-transform: lowercase;
  letter-spacing: .18em;
  /* Dolna granica, bo .3em liczone od nagłówka schodziło na wąskich
     ekranach do 9.6px — poniżej progu czytelności. */
  font-size: max(.72rem, .3em);
  color: var(--ink);
  /* Odstępy dobrane pomiarem realnego zasięgu pisma na zrzucie, nie pudełek
     z interlinią — te ostatnie zachodzą na siebie i nic nie mówią. Przed
     korektą było 12px nad „vs” i 22px pod, bo dolną przerwę powiększał jeszcze
     górny margines linii pisanej pod spodem. */
  margin: .66em 0 .2em;
  /* Opuszczone o ~10% przestrzeni między wierszami. transform, nie margines —
     przesuwa sam napis i nie rozpycha nagłówka ani treści pod nim. */
  transform: translateY(.19em);
}
.creed__script::before {
  content: "";
  position: absolute;
  left: -.14em; right: -.14em;
  /* Dobrane tak, by pasek biegł mniej więcej od 57% do 85% wysokości glifów
     — tak samo jak marker w .hero__title. Dolne wydłużenia liter Caveat
     przebijają go od spodu, dokładnie jak w referencji. */
  bottom: .06em;
  height: .36em;
  /* Ten sam fiolet co w hero, przepuszczony przez krycie — pod paskiem leży
     ciemny tekst, a pełna moc koloru dałaby pod nim 2.7:1. To samo rozwiązanie
     co w .mark-soft, ta sama wartość, żeby oba zakreślenia były identyczne. */
  background: rgba(149, 65, 252, .42);
  z-index: -1;
}
.creed__body {
  margin-top: clamp(2rem, 4vw, 3.25rem);
  /* Wyśrodkowany na prośbę klienta. Justowanie zniknęło razem z dzieleniem
     wyrazów — przy tekście do środka nie ma rzek do wyrównywania. */
  text-align: center;
  font-size: 1.05rem;
  line-height: 1.75;
  color: var(--ink-soft);
}
.creed__body p + p { margin-top: var(--sp-4); }
.creed__body strong { color: var(--ink); font-weight: 500; }
/* Zdanie domykające — szeryfowe i w kolorze --ink, więc odcina się od
   szarawych akapitów nad nim i czyta się jako puenta, a nie kolejny akapit. */
.creed__closing {
  margin-top: clamp(2rem, 4vw, 3rem);
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.9vw, 1.6rem);
  line-height: 1.35;
  text-wrap: balance;
}

/* ---------- Moja droga ---------- */
.story { padding-block: var(--section-y); }
.story__grid {
  display: grid;
  grid-template-columns: .85fr 1.15fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
/* Kreska pod tytułem sekcji. Jedna klasa dla wszystkich trzech miejsc na tej
   podstronie — wariant --center dla tytułów wyśrodkowanych. */
.rule {
  display: block;
  width: 82px; height: 1px;
  background: var(--ink);
  opacity: .45;
  margin: var(--sp-3) 0;
}
.rule--center { margin-inline: auto; }

/* Dopisek w tytule po myślniku: mówi klientowi, co znajdzie w sekcji.
   Mniejszy i w kolorze --ink-soft, żeby czytał się jako ciąg dalszy tytułu,
   a nie druga, konkurująca z nim linia. Zawija razem z tytułem. */
.section-title__cont {
  font-size: .46em;
  line-height: 1.25;
  color: var(--ink-soft);
  letter-spacing: 0;
  white-space: nowrap;
}
.story__lead {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.7rem);
  line-height: 1.35;
  margin-bottom: var(--sp-4);
}
/* Ranged left on every width. This is the longest reading block on the site
   and centring it would cost the eye a fixed left edge to return to. */
.prose { max-width: 60ch; color: var(--ink-soft); }
.prose p + p { margin-top: var(--sp-3); }

/* ---------- Jak pracuję ---------- */
.approach {
  position: relative;
  background: var(--grad-offer);
  padding-block: clamp(4.5rem, 9vw, 7rem);
}
/* Same trick as every other band: the cap is filled with the colour of the
   neighbouring section, so the curve reads as one surface folding into the
   next. Canvas above and below here. */
.wave--approach-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
  transform: rotate(180deg);
}
.wave--approach-bottom {
  position: absolute; bottom: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
}
.approach__inner { position: relative; }
.approach__intro {
  max-width: 52ch;
  margin: var(--sp-3) auto var(--sp-6);
  text-align: center;
  text-wrap: balance;
  font-size: 1.08rem;
  color: var(--ink-soft);
}
.approach__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.25rem);
  max-width: 900px;
  /* Odstęp od tytułu niósł wcześniej akapit wprowadzający w swoim dolnym
     marginesie. Akapit zniknął, więc separacja przechodzi tutaj — ta sama
     wartość, żeby rytm sekcji został bez zmian. */
  margin: var(--sp-6) auto 0;
}
.approach__list li {
  background: var(--canvas);
  border-radius: 3px;
  padding: clamp(1.35rem, 2.4vw, 1.9rem);
  box-shadow: var(--shadow-soft);
}
.approach__list h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.22rem;
  line-height: 1.2;
  margin-bottom: .5rem;
}
.approach__list p { color: var(--ink-soft); font-size: .97rem; line-height: 1.6; }

/* ---------- Domknięcie / CTA ---------- */
.closing { position: relative; padding-block: var(--section-y); }
/* Wariant na pasie — na podstronie „pulsing" domknięcie wypada zaraz po
   sekcji 10, która siedzi na canvas. Bez własnego tła oba bloki zlewałyby
   się w jeden długi kremowy pas bez żadnej granicy. */
/* Dolna krawędź przypięta do płaskiego sage — ta sama dyscyplina co przy
   pozostałych pasach: tam gdzie pas styka się z falą, gradient musi trafić
   dokładnie w jej kolor, inaczej na szwie widać pasek. */
.closing--band { background: linear-gradient(180deg, #C5E3DB 0%, #B4DAD1 100%); }
.wave--closing-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
  transform: rotate(180deg);
}
.closing__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.closing__text { max-width: 46ch; color: var(--ink-soft); margin-bottom: var(--sp-4); }
.closing__actions {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  justify-content: center;
}

/* =====================================================================
   PODSTRONA „PULSING" — wstęp + cztery numerowane sekcje
   ===================================================================== */
.pintro {
  position: relative;
  padding-block: clamp(3.5rem, 8vw, 6.5rem) clamp(4.5rem, 9vw, 7rem);
}
/* Tytuł po lewej dosunięty do prawej krawędzi swojej kolumny, tekst po
   prawej — tak jak w referencji, gdzie obie kolumny stykają się w osi. */
.pintro__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
}
.pintro__title {
  margin: 0;
  /* Wyśrodkowany w swojej kolumnie na prośbę klienta — wcześniej dosuwany
     do prawej, jak w referencji. */
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  /* Finalny tytuł to pełne zdanie, nie dwa słowa jak w referencji. Przy
     poprzednim stopniu (3,9rem) rozlewał się na pięć linii i przytłaczał
     kolumnę obok. */
  font-size: clamp(1.6rem, 2.8vw, 2.5rem);
  line-height: 1.12;
  letter-spacing: .01em;
}
.pintro__title span { display: block; }
.pintro__lead {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.9vw, 1.5rem);
  line-height: 1.3;
  max-width: 34ch;
}
.pintro__rule {
  display: block;
  height: 1px;
  background: rgba(36,50,56,.28);
  margin: clamp(1.25rem, 2.5vw, 1.9rem) 0;
  /* Ta sama miara co akapity pod spodem (40ch). Przy 34ch kreska była
     krótsza nawet od napisu nad nią i wyglądała na uciętą. */
  max-width: 40ch;
}
.pintro__text {
  max-width: 40ch;
  color: var(--ink-soft);
  text-align: justify;
  hyphens: auto;
}
.pintro__text + .pintro__text { margin-top: var(--sp-3); }
/* Kółko zjazdu w prawym dolnym rogu sekcji. */
.pintro__scroll {
  position: absolute;
  right: clamp(1.25rem, 4vw, 3.5rem);
  bottom: clamp(1.25rem, 3vw, 2.5rem);
  display: grid;
  place-items: center;
  width: 66px; height: 66px;
  border-radius: 50%;
  background: var(--steel);
  color: var(--ink);
  transition: transform .25s ease, background .25s ease;
}
.pintro__scroll:hover { transform: translateY(3px); background: var(--sage); }
.pintro__scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.pintro__scroll svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}

/* ---------- Numerowane sekcje ---------- */
.value {
  position: relative;
  padding-block: clamp(4rem, 9vw, 7.5rem);
}
/* Pasy barwne przeplatają się z canvas, tak jak w referencji przeplatały
   się lawenda i róż z kremem. Fale po obu stronach wypełnione canvas, bo
   z obu stron sąsiaduje właśnie canvas. */
/* Pasy cyklują przez gradienty użyte na stronie głównej, więc podstrona
   trzyma się tej samej kolorystyki co reszta serwisu. */
.value--sage { background: var(--grad-reviews); }
.value--cool { background: var(--grad-price); }
.value--warm { background: var(--grad-offer); }
.value--mist { background: var(--grad-programs); }
.wave--value-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
  transform: rotate(180deg);
}
.wave--value-bottom {
  position: absolute; bottom: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
}
.value__inner {
  position: relative;
  max-width: 720px;
  margin-inline: auto;
  text-align: center;
}
/* Etykieta na łuku — tekst po ścieżce SVG, jak „CORE VALUES" w referencji. */
/* Ramka dopasowana do spłaszczonego łuku — tekst siedzi teraz w środku,
   a nie nad nią, więc etykieta zeszła tuż nad liczbę. */
.value__arc {
  display: block;
  width: 140px; height: 24px;
  margin: 0 auto .4rem;
  overflow: visible;
}
.value__arc text {
  fill: var(--ink);
  font-family: var(--font-label);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
}
/* W referencji numery są ledwo widoczne — tu byłyby poniżej progu 3:1, który
   obowiązuje dla tego stopnia pisma. Przy .8 są nadal wyraźnie przygaszone
   względem tytułu, ale dają się przeczytać. */
.value__num {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.1rem);
  line-height: 1;
  color: var(--ink-soft);
  opacity: .8;
  margin-bottom: .35rem;
}
.value__title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.75rem, 3.6vw, 3rem);
  line-height: 1.12;
  letter-spacing: .01em;
}
/* Dwa najdłuższe tytuły („Detoksykacja i naturalne oczyszczenie" oraz
   „Poczucie bezpieczeństwa i radość z życia") nie mieszczą się w mierze
   kolumny i łamią się na dwa wiersze — reszta zostaje jednowierszowa, więc
   te dwa odstają. Sam tytuł dostaje szerszą miarę; opis pod spodem zostaje
   wąski, więc hierarchia bloku się nie zmienia. Tylko od 961px w górę, bo
   niżej font maleje razem z szerokością okna i wszystko mieści się samo. */
@media (min-width: 961px) {
  .value__title {
    margin-inline: -3rem;
  }
}
/* Zakreślacz pod fragmentem tytułu. Te same stopy procentowe co w hero:
   56%–90% pola liniowego, czyli od środka liter do tuż pod linią bazową.
   Domyślnie sage — sekcje bez pasa siedzą na canvas. */
/* Ten sam fiolet co zakreślenia na stronie głównej — i ta sama wartość
   krycia, bo tu również pod paskiem leży ciemny tekst. Jedno krycie działa
   na wszystkich tłach tej podstrony, więc osobny wariant dla pasów
   (wcześniej biel, bo sage znikał na sage) przestał być potrzebny. */
.value__title .mark {
  background: linear-gradient(transparent 56%, rgba(149, 65, 252, .42) 56%,
                              rgba(149, 65, 252, .42) 90%, transparent 90%);
  padding: 0 .1em;
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}

/* Podtytuł między tytułem a kreską — z tekstu Joanny. */
/* Kreska jest teraz podkreśleniem samego podtytułu, a nie osobnym paskiem
   wiszącym w połowie odstępu. Dlatego siedzi na obramowaniu tego elementu,
   a nie w oddzielnym <span> o stałej szerokości — tamten bywał węższy od
   napisu (podtytuły mają od 214 do 308px) i czytał się jak zabłąkana kreska.
   inline-block zwęża blok do treści, a wyśrodkowanie dziedziczy po rodzicu. */
.value__sub {
  display: inline-block;
  margin-top: .6rem;
  padding-bottom: .5rem;
  border-bottom: 1px solid rgba(36,50,56,.32);
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: .72rem;
  color: var(--ink-soft);
}
.value__body {
  max-width: 58ch;
  /* Odstęp od podkreślenia — wcześniej niósł go dolny margines kreski. */
  margin: clamp(1.5rem, 3vw, 2.5rem) auto 0;
  color: var(--ink-soft);
  line-height: 1.7;
}
.value__body p + p { margin-top: var(--sp-3); }

/* =====================================================================
   PODSTRONY PRODUKTOWE — nagłówek na pasie, treść + kolumna boczna
   ===================================================================== */
.post-hero {
  position: relative;
  background: var(--grad-programs);
  padding-block: clamp(3rem, 7vw, 5rem) clamp(4.5rem, 9vw, 7rem);
}
/* Bez własnego max-width: nagłówek ma trzymać tę samą linię co treść,
   kolumna boczna i karty pod spodem. Wcześniejsze ograniczenie do 1020px
   wcinało go o 80px głębiej niż resztę strony i to właśnie czytało się
   jako nierówne marginesy. Szerokość i wyśrodkowanie daje .container. */
/* Prawa kolumna dostaje szerokość swojej treści, nie „całą resztę”.
   Wcześniej była 1fr, czyli 585px, a mieściła 261px tekstu — stąd ta pusta
   przestrzeń. Para zdjęcie-tekst jest teraz centrowana jako całość, więc
   marginesy z obu stron wychodzą równe bez martwej kolumny. */
.post-hero__grid {
  display: grid;
  grid-template-columns: clamp(280px, 34vw, 470px) max-content;
  justify-content: center;
  gap: clamp(1.75rem, 4.5vw, 3.5rem);
  align-items: center;
}
.post-hero__media {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: var(--shadow-soft);
}
.post-hero__kicker { display: block; color: var(--ink-soft); margin-bottom: var(--sp-2); }
.post-hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.9rem, 3.8vw, 3.2rem);
  line-height: 1.08;
  letter-spacing: .01em;
}
/* Kolumna zwęża się do własnej treści — bez tego rozciągałaby się na całą
   szerokość gridu i zostawiała pustkę po prawej. */
.post-hero__col { width: fit-content; }
/* Kreska pod tytułem usunięta na życzenie — odstęp przejmuje metryczka. */
.post-hero__meta { margin-top: clamp(1.25rem, 2.6vw, 2rem); }
/* Dwie pozycje meta rozdzielone pionową kreską — jak w referencji. */
.post-hero__meta { display: flex; gap: clamp(1.25rem, 3vw, 2.5rem); }
.post-hero__meta > div + div { padding-left: clamp(1.25rem, 3vw, 2.5rem); border-left: 1px solid rgba(36,50,56,.25); }
.post-hero__label {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .68rem;
  color: var(--ink-soft);
  margin-bottom: .2rem;
}
.post-hero__value { font-family: var(--font-display); font-style: italic; font-size: 1.05rem; }
/* Główne wezwanie w nagłówku produktu, pod metryczką. */
.post-hero__cta { margin-top: clamp(1.4rem, 2.8vw, 2.1rem); }

/* ---------- Przełącznik ofert ----------
   Dwa kółka ze strzałkami pod wezwaniem, przeskakujące do poprzedniej
   i następnej oferty. Kolejność (jak w siatce na „Dla Ciebie”) i zawinięcie
   z ostatniej do pierwszej siedzą w samych adresach na podstronach — dzięki
   temu działa bez JavaScriptu, ma poprawne adresy i wstecz w przeglądarce.
   Krawędź i rozmiary te same co w nawigacji opinii na stronie głównej. */
.post-hero__switch {
  display: flex;
  gap: .6rem;
  margin-top: clamp(1rem, 2vw, 1.4rem);
}
.post-hero__switchbtn {
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1.5px solid rgba(36,50,56,.28);
  color: var(--ink);
  transition: background .2s ease, border-color .2s ease, transform .2s ease;
}
.post-hero__switchbtn:hover {
  background: var(--canvas);
  border-color: transparent;
  transform: translateY(-2px);
}
.post-hero__switchbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.post-hero__switchbtn svg {
  width: 19px; height: 19px;
  fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}

/* ---------- Kółko zjazdu ----------
   Ten sam gest i ten sam rozmiar co „.pintro__scroll” na podstronie
   „Pulsing”, z dwiema różnicami wymuszonymi przez tło:
   1. Podniesione ponad falę zamykającą pas (58px), żeby nie siedziało na
      niej okrakiem — na „Pulsingu” pod sekcją nie ma fali.
   2. Wypełnienie canvas, nie steel. Prawa krawędź --grad-programs kończy
      się dokładnie na --steel, więc stalowe kółko zlałoby się z pasem;
      na „Pulsingu” tło jest jasne i stal na nim widać.
   Wisi w marginesie na prawo od wyśrodkowanej siatki nagłówka. */
.post-hero__scroll {
  position: absolute;
  right: clamp(1.25rem, 4vw, 3.5rem);
  bottom: clamp(3.75rem, 6vw, 5rem);
  display: grid;
  place-items: center;
  width: 66px; height: 66px;
  border-radius: 50%;
  background: var(--canvas);
  color: var(--ink);
  box-shadow: var(--shadow-soft);
  transition: transform .25s ease, background .25s ease;
}
.post-hero__scroll:hover { transform: translateY(3px); background: var(--sage); }
.post-hero__scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.post-hero__scroll svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}

/* Próbka nagrania — tylko na podstronie „Głos”. Kontrolki natywne, bo klient
   prosił o „prosty player”: własny wymagałby skryptu, obsługi klawiatury
   i etykiet, a i tak wyglądałby inaczej w każdej przeglądarce. Szerokość
   pilnowana z obu stron, żeby odtwarzacz nie rozpychał wąskiej kolumny
   nagłówka do swojej domyślnej szerokości. */
.post-hero__probka { margin-top: clamp(1.4rem, 2.8vw, 2.1rem); }
.post-hero__probka .post-hero__label { margin-bottom: .45rem; }
.post-hero__audio {
  display: block;
  width: 100%;
  max-width: 300px;
  height: 38px;
}
.wave--post-bottom {
  position: absolute; bottom: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
}

/* ---------- Treść + kolumna boczna ---------- */
/* scroll-margin-top odsuwa sekcję spod przyklejonego paska nawigacji, gdy
   przyjeżdża tu kotwica z kółka zjazdu w nagłówku. */
.post { padding-block: var(--section-y); scroll-margin-top: var(--header-h); }
/* Kolumna boczna (Joanna / pozostałe sesje / cena) zniknęła na prośbę
   klienta. Tekst ma przy tym zostać DOKŁADNIE tak szeroki jak wcześniej,
   tylko wyśrodkowany — dlatego szerokość liczy się tą samą formułą, z której
   wychodziła w siatce dwukolumnowej: kontener minus kolumna boczna minus
   przerwa. Wpisanie na sztywno jednej liczby rozjechałoby się przy innych
   szerokościach okna, bo oba składniki są na clamp(). */
.post__grid { display: block; }
.post__body {
  width: calc(100% - clamp(240px, 24vw, 300px) - clamp(2rem, 5vw, 4.5rem));
  margin-inline: auto;
  text-align: justify;
  hyphens: auto;
}
.post__body p + p { margin-top: var(--sp-3); }
.post__body h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.35rem, 2.3vw, 1.8rem);
  line-height: 1.2;
  text-align: center;
  margin: var(--sp-5) 0 var(--sp-3);
}
.post__body ul { margin: var(--sp-3) 0; text-align: left; }
.post__body li {
  position: relative;
  padding-left: 1.6rem;
  margin-bottom: .55rem;
  line-height: 1.6;
}
.post__body li::before {
  content: "";
  position: absolute;
  left: .2rem; top: .5em;
  width: .6rem; height: .6rem;
  background: var(--steel);
  -webkit-mask: var(--plus-mask) center / contain no-repeat;
          mask: var(--plus-mask) center / contain no-repeat;
}
/* Cytat wzięty w kreski nad i pod — dokładnie jak w referencji. */
.post__quote {
  margin: var(--sp-5) 0;
  padding: var(--sp-4) 0;
  border-top: 1px solid rgba(36,50,56,.2);
  border-bottom: 1px solid rgba(36,50,56,.2);
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.1rem, 1.8vw, 1.35rem);
  line-height: 1.4;
  text-align: center;
}
/* Dwa przyciski obok siebie: „Dowiedz się więcej” (pełny) i „Chcę się umówić”
   (obrysowy). Zawijają się jeden pod drugi, gdy kolumna jest za wąska. */
.post__cta {
  margin-top: var(--sp-5);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .75rem;
}
.post__quote cite { display: block; margin-top: .6rem; font-style: normal; font-size: .8rem; font-family: var(--font-label); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }

/* ---------- Kolumna boczna ---------- */
.aside { position: sticky; top: calc(var(--header-h) + 1rem); }
.aside__block + .aside__block { margin-top: var(--sp-5); }
.aside__kicker { display: block; text-align: center; color: var(--ink-soft); margin-bottom: .3rem; }
.aside__name {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.5rem;
  text-align: center;
  margin-bottom: var(--sp-3);
}
.aside__photo { width: 100%; height: auto; aspect-ratio: 3 / 3.4; object-fit: cover; border-radius: 2px; }
.aside__text { margin-top: var(--sp-3); text-align: center; font-size: .92rem; color: var(--ink-soft); line-height: 1.6; }
.aside__panel { background: var(--sand); border-radius: 3px; padding: var(--sp-4); text-align: center; }
.aside__heading {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .68rem;
  color: var(--ink-soft);
  margin-bottom: var(--sp-3);
}
.aside__list li + li { margin-top: .7rem; }
.aside__list a {
  font-family: var(--font-display);
  font-size: 1.08rem;
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease;
}
.aside__list a:hover { border-color: var(--ink); }
.aside__promo { background: var(--grad-reviews); border-radius: 3px; padding: var(--sp-4); text-align: center; }
.aside__promo p { font-family: var(--font-display); font-size: 1.25rem; line-height: 1.25; margin-bottom: var(--sp-3); }

/* ---------- Zobacz też ---------- */
.related { background: var(--grad-offer); padding-block: clamp(3.5rem, 7vw, 5.5rem); position: relative; }
.wave--related-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: var(--canvas);
  transform: rotate(180deg);
}
.related__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.25rem);
  margin-top: var(--sp-5);
}
.related__media { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 2px; margin-bottom: var(--sp-3); }
.related__name { font-family: var(--font-display); font-size: 1.2rem; line-height: 1.25; }
.related__back { display: flex; justify-content: center; margin-top: var(--sp-5); }

/* =====================================================================
   PODSTRONA „SPOTKAJMY SIĘ" — formularz + pas z zaproszeniem
   ===================================================================== */
/* Etykiety pól są w markupie, ale schowane: referencja pokazuje same
   placeholdery, a te znikają po wpisaniu tekstu i nie są odczytywane jako
   etykieta. Ukryta etykieta daje wygląd z referencji i poprawny formularz. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Sekcja siedziała na gołym canvasie i przez to cała góra podstrony robiła się
   biała — ten sam problem co kiedyś na „Dlaczego TU jestem”, więc i to samo
   rozwiązanie: wspólny wash --grad-about.
   Górny odstęp zerowy — zdjęcie ma stykać się z dolną krawędzią przyklejonego
   paska, bez paska tła między jednym a drugim.
   Wash kończy się na #CFE3DE — dokładnie tym kolorem musi być wypełniona
   fala .wave--promo-top, inaczej na szwie z pasem zaproszenia widać pasek. */
.chat {
  background: var(--grad-about);
  padding-block: 0 var(--section-y);
}
.chat__photo {
  display: block;
  width: 100%;
  max-width: 780px;
  margin-inline: auto;
  height: auto;
  /* 4:3, nie panorama — plik jest już przycięty do tej proporcji, więc
     object-fit nic tu nie obcina i otwór w skale zostaje w całości. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 2px;
}
/* Podpis wchodzi na dolną krawędź zdjęcia — ujemny margines zamiast
   pozycjonowania, żeby dalsza treść przesunęła się razem z nim. */
.chat__title {
  position: relative;
  z-index: 2;
  margin-top: -.42em;
  text-align: center;
  font-family: var(--font-script);
  font-weight: 600;
  font-size: clamp(3rem, 7vw, 5.5rem);
  line-height: 1;
}
.chat__lead {
  max-width: 46ch;
  margin: var(--sp-3) auto 0;
  text-align: center;
  color: var(--ink-soft);
  text-wrap: balance;
}
.chat__mail {
  display: block;
  margin: var(--sp-3) auto var(--sp-6);
  text-align: center;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .18em;
  font-size: .9rem;
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease;
}
.chat__mail:hover { border-color: var(--ink); }

.chat__form {
  position: relative;
  max-width: 780px;
  margin: var(--sp-6) auto 0;
  /* Odsuwa formularz spod przyklejonego paska, gdy przyjdzie tu kotwica
     z przycisku „wypełnij formularz”. */
  scroll-margin-top: calc(var(--header-h) + 1.5rem);
}
/* Bez margin-bottom: odstęp niosą teraz same pola (.field ma własny margines,
   tak jak w formularzu na stronie głównej). Zostawiony dawałby między rzędami
   podwójną przerwę — 32px zamiast 16px. */
.chat__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.chat__input {
  width: 100%;
  padding: 1.1em 1.2em;
  border: 1px solid rgba(36,50,56,.1);
  border-radius: 2px;
  background: var(--white);
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .78rem;
  color: var(--ink);
  resize: vertical;
}
.chat__input::placeholder { color: rgba(36,50,56,.45); }
.chat__input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-color: transparent; }
.chat__input--area { min-height: 210px; }
/* Okrągły przycisk zachodzi na prawy dolny róg pola tekstowego. */
.chat__send {
  position: absolute;
  right: clamp(-2.5rem, -2vw, -1rem);
  bottom: clamp(-2rem, -2vw, -1rem);
  display: grid;
  place-items: center;
  gap: .3rem;
  width: 104px; height: 104px;
  border: none;
  border-radius: 50%;
  background: var(--steel);
  color: var(--ink);
  cursor: pointer;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: .72rem;
  transition: transform .25s ease, background .25s ease;
}
.chat__send:hover { transform: translateY(-3px); background: var(--sage); }
.chat__send:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.chat__send .arrow { width: 2.4em; }

/* ---------- Pas z zaproszeniem ---------- */
/* Warstwy radialne dają głębię jak gradient w referencji, a warstwa liniowa
   kończy się płaskim sage — tym samym, którym wypełniona jest fala stopki.
   Bez tego przypięcia na szwie widać pasek. */
.promo {
  position: relative;
  background:
    radial-gradient(70% 80% at 12% 16%, #A3CBDB 0%, rgba(188,203,210,0) 58%),
    radial-gradient(62% 70% at 82% 30%, #7DB2C4 0%, rgba(166,187,196,0) 60%),
    linear-gradient(180deg, #C5E3DB 0%, #B4DAD1 100%);
  padding-block: clamp(4rem, 9vw, 7rem);
  overflow: hidden;
}
/* Kolor sekcji NAD falą, nie pod nią. Formularz dostał wash --grad-about,
   który kończy się na #CFE3DE — dopóki było tu --canvas, na szwie leżał
   jasny pasek szerokości całej strony. */
.wave--promo-top {
  position: absolute; top: -1px; left: 0;
  width: 100%; height: 58px;
  fill: #CFE3DE;
  transform: rotate(180deg);
}
.promo__inner { position: relative; display: flex; justify-content: center; }
.promo__blob {
  position: relative;
  z-index: 2;
  width: min(560px, 100%);
  background: var(--canvas);
  /* Ten sam nieregularny kształt co bąbel z ceną na stronie głównej. */
  border-radius: 57% 43% 47% 53% / 43% 56% 44% 57%;
  padding: clamp(2.5rem, 5vw, 4rem) clamp(2.25rem, 4.5vw, 3.5rem);
  text-align: center;
  box-shadow: var(--shadow-soft);
}
.promo__chip {
  display: inline-block;
  background: var(--ink);
  color: var(--canvas);
  padding: .55em 1.1em;
  border-radius: 2px;
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-size: .68rem;
  margin-bottom: var(--sp-3);
}
.promo__title {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.5rem, 2.8vw, 2.2rem);
  line-height: 1.15;
}
.promo__rule {
  display: block;
  width: clamp(140px, 18vw, 210px);
  height: 1px;
  background: rgba(36,50,56,.3);
  margin: var(--sp-3) auto;
}
.promo__text { color: var(--ink-soft); font-size: .96rem; line-height: 1.65; margin-bottom: var(--sp-4); }
/* Przechylony pasek klatek zachodzi na prawą krawędź bąbla. */
.promo__strip {
  position: absolute;
  left: calc(50% + min(200px, 34vw));
  top: 50%;
  transform: translateY(-50%) rotate(9deg);
  width: clamp(110px, 13vw, 165px);
  display: grid;
  gap: 4px;
  padding: 6px;
  background: #1B262B;
  border-radius: 2px;
  box-shadow: var(--shadow-soft);
}
.promo__strip img {
  width: 100%; height: auto;
  aspect-ratio: 1 / 0.9;
  object-fit: cover;
  filter: grayscale(1) contrast(1.05);
}

/* =====================================================================
   STRONY PRAWNE — regulamin, polityka prywatności
   ===================================================================== */
.legal { padding-block: clamp(3.5rem, 8vw, 6rem) var(--section-y); }
/* 940, nie 760: przy 760 strona odstawała szerokością od reszty serwisu,
   a zagnieżdżone listy dodatkowo zjadały wcięciami miejsce w poziomie.
   Zmierzone: 84 znaki w wierszu akapitu i 77 w najgłębszym zagnieżdżeniu,
   czyli nadal w wygodnej mierze czytania (45–90). */
.legal__inner { max-width: 940px; margin-inline: auto; }
.legal__title { margin-bottom: var(--sp-2); }
.legal__meta { color: var(--ink-soft); font-size: .88rem; margin-bottom: var(--sp-5); }
/* Ostrzeżenie o brakujących danych. Celowo krzykliwe: ma nie przejść
   niezauważone przy publikacji. */
.legal__warn {
  background: var(--sand);
  border-left: 3px solid var(--accent);
  border-radius: 2px;
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-5);
  font-size: .92rem;
  line-height: 1.6;
}
.legal__body h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.25rem, 2.1vw, 1.6rem);
  line-height: 1.2;
  margin: var(--sp-5) 0 var(--sp-3);
}
.legal__body h3 {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: .78rem;
  margin: var(--sp-4) 0 var(--sp-2);
}
.legal__body p { margin-bottom: var(--sp-3); line-height: 1.75; }
.legal__body ul, .legal__body ol { margin: 0 0 var(--sp-3) 1.4rem; }
.legal__body ol { list-style: decimal; }
.legal__body ul li { position: relative; padding-left: 1rem; margin-bottom: .5rem; line-height: 1.65; }
.legal__body ul li::before {
  content: "";
  position: absolute;
  left: 0; top: .62em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--steel);
}
.legal__body ol li { margin-bottom: .5rem; line-height: 1.65; }
.legal__body a { border-bottom: 1px solid rgba(36,50,56,.3); }
.legal__body a:hover { border-color: var(--ink); }
/* Pola do wypełnienia — mają rzucać się w oczy w gotowym dokumencie. */
.legal__fill {
  background: rgba(199,107,79,.16);
  padding: .1em .4em;
  border-radius: 2px;
  font-family: var(--font-label);
  font-size: .82em;
  letter-spacing: .04em;
}

/* =====================================================================
   BANER ZGODY
   ===================================================================== */
.cookies {
  position: fixed;
  left: clamp(.75rem, 2vw, 1.5rem);
  bottom: clamp(.75rem, 2vw, 1.5rem);
  z-index: 200;
  width: min(420px, calc(100vw - 1.5rem));
  background: var(--canvas);
  border: 1px solid rgba(36,50,56,.14);
  border-radius: 4px;
  box-shadow: 0 18px 44px -20px rgba(36,50,56,.55);
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
  /* Schowany do czasu, aż main.js sprawdzi zapisany wybór — inaczej mignąłby
     przy każdym wejściu, także po wyrażeniu zgody. */
  display: none;
}
.cookies.is-shown { display: block; }
.cookies__title {
  font-family: var(--font-display);
  font-size: 1.15rem;
  margin-bottom: .5rem;
}
.cookies__text { font-size: .88rem; line-height: 1.6; color: var(--ink-soft); margin-bottom: var(--sp-3); }
.cookies__text a { border-bottom: 1px solid rgba(36,50,56,.3); }
.cookies__actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.cookies__actions .pill { font-size: .68rem; padding: .8em 1.2em; }

/* =====================================================================
   RESPONSIVE
   ===================================================================== */
@media (max-width: 960px) {
  /* Szerokość tekstu na podstronach produktów była liczona jako „kontener
     minus nieistniejąca już kolumna boczna”. Na desktopie to jest sens —
     blok zostaje taki, jak był. Poniżej tego progu zostawałoby z niego
     ~385px wyśrodkowanych na 700px ekranu, więc tu bierze całą szerokość. */
  .post__body { width: 100%; }

  /* backdrop-filter makes an element the containing block for fixed-position
     descendants, which would trap the drawer and the scrim inside the bar
     instead of the viewport. The mobile header is opaque anyway. */
  /* Pasek jest już nieprzezroczysty i bez rozmycia globalnie — tu zostaje
     tylko komentarz, żeby nie wróciło: backdrop-filter tworzy blok zawierający
     dla potomków position:fixed, co uwięziłoby panel boczny i przyciemnienie
     wewnątrz paska zamiast na całym ekranie. */

  /* Brand left, burger right, nothing else in the bar. */
  .header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    /* Lifts the bar over the scrim and the drawer, so only the page behind
       dims and the panel slides in beneath a bar that stays legible. */
    position: relative;
    z-index: 130;
  }
  /* The drawer is a descendant of .header__inner, so the bar's z-index does
     not lift the burger above it — inside that stacking context the panel
     (120) paints over an untouched button and swallows the X. It needs its
     own layer above the drawer. */
  .nav-toggle {
    display: flex;
    position: relative;
    z-index: 140;
  }

  /* Off-canvas panel. visibility keeps the links out of the tab order while
     it is parked off-screen; the 0s delay holds it painted as it slides out. */
  .nav-drawer {
    display: flex;
    flex-direction: column;
    position: fixed;
    inset: 0 0 0 auto;
    width: min(82vw, 320px);
    padding: calc(var(--header-h) + 1.75rem) clamp(1.5rem, 6vw, 2.25rem) 2rem;
    background: var(--canvas);
    box-shadow: -24px 0 60px -34px rgba(36,50,56,.75);
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 120;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform .35s ease, visibility 0s linear .35s;
  }
  .site-header.is-nav-open .nav-drawer {
    transform: translateX(0);
    visibility: visible;
    transition: transform .35s ease;
  }

  .nav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 110;
    background: rgba(36,50,56,.45);
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s ease, visibility 0s linear .3s;
  }
  .site-header.is-nav-open .nav-scrim {
    opacity: 1;
    visibility: visible;
    transition: opacity .3s ease;
  }

  .nav__list { flex-direction: column; gap: 0; }
  /* Stacked menu separates items with a border under each link; the vertical
     rule would just be a stray tick to the left of the text. */
  .nav__list li { display: block; }
  .nav__list li + li::before { content: none; }
  .nav__list a {
    display: block;
    padding: .85em 0;
    font-size: .95rem;
    border-bottom: 1px solid rgba(36,50,56,.1);
  }

  /* Hero przestaje mieć narzuconą wysokość i jest wyznaczone samą treścią,
     więc nie ma tu ani piksela zapasu. Podniesienie nagłówka o dwa wiersze
     wypchnęłoby go poza kadr, pod przyklejony pasek nawigacji — zmierzone
     16px ponad górną krawędź. Na tych szerokościach zostaje wyśrodkowany. */
  .hero { min-height: auto; }
  .hero__title { transform: none; }
  .hero__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.75rem;
    padding-block: clamp(2.5rem, 9vw, 4.5rem);
  }
  .hero__scrim {
    background: linear-gradient(0deg,
      rgba(244,241,236,.5), rgba(244,241,236,.12) 45%, rgba(244,241,236,.4));
  }
  .quiz-badge {
    position: relative;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    margin: 0;
    width: clamp(240px, 74vw, 320px);
  }
  /* Linia pulsu nie jest już pozycjonowana absolutnie — zostaje w środku
     bąbla, tylko węższa. */
  .doodle--pulse { width: 92px; }

  /* The ring has no room to be a ring — drop it to a stacked list. */
  /* The ring survives down to phones instead of unwinding into a column.
     It has to shrink on three axes at once: a tighter --rx keeps the side
     chips inside the stage, a taller stage stops the ellipse squashing the
     rows together, and narrower chips stop neighbours touching. The chips
     are opaque, so where they cross the figure the text stays readable. */
  /* Scena urosła razem z czcionką w chmurkach — przy poprzedniej wysokości
     rzędy elipsy schodziły się na siebie u góry pierścienia. */
  /* Dziesiąta chmurka wymusiła wyższą scenę: dziesięć bąbli ma razem ~730px
     wysokości, a pierścień o poprzedniej wysokości dawał 636px pionowego
     rozpiętu — nie mieściły się fizycznie. Zmierzone: przy 1000px znikają
     wszystkie zachodzenia (poprzedni układ z dziewięcioma jedno miał). */
  .struggle__stage { min-height: clamp(1000px, 260vw, 1080px); }
  .struggle__figure { width: clamp(150px, 42vw, 250px); }
  /* Bez obrotu: przy dziesięciu chmurkach i tak wąskim pierścieniu para przy
     godzinie 12 zachodziła na siebie o 86px. Zerowy obrót stawia tam jedną
     chmurkę, a szerszy promień rozsuwa pozostałe pary. */
  .struggle__questions { --rx: 34%; --ry: 43%; --obrot: 0deg; }
  .struggle__q {
    /* Z powrotem szerokość z dostępnego miejsca, nie max-content. Na desktopie
       max-content ratuje chmurkę na godzinie 3 przed zwężeniem do kwadratu,
       ale tutaj rozpycha wszystkie do pełnych 10rem i pierścień przestaje się
       mieścić — sprawdzone, żadna kombinacja promieni i wysokości sceny tego
       nie ratuje. Na wąskim ekranie zwężanie do dostępnego miejsca akurat
       pomaga, więc zostaje. */
    width: auto;
    max-width: 10rem;
    font-size: .88rem;
    padding: .58em .8em;
    border-radius: 12px;
  }
  /* The bottom pair are the two longest questions and the closest together
     on the ellipse — at phone width they collide. Pushed out to the corners,
     which is free space: nothing else sits that low. */
  .struggle__q:nth-child(5) { left: calc(50% + .78 * var(--rx)); }
  .struggle__q:nth-child(6) { left: calc(50% - .78 * var(--rx)); }

  /* Collage drops below the copy and the tilted stack unwinds into a row. */
  .invite__grid { grid-template-columns: 1fr; }
  /* Three narrow columns leave no room for the tilt — rotated prints would
     clip each other — so the row flattens to a plain, even strip. */
  .invite__collage { gap: .75rem; margin-top: clamp(2rem, 7vw, 3rem); }
  .invite__shot {
    aspect-ratio: 3 / 4;
    transform: none;
    border-width: 6px;
  }
  .invite__row { grid-template-columns: 1fr; gap: 0; }

  /* The blob fills the width here, so the strip would land on the copy.
     It is decorative (aria-hidden), so it just goes away. */
  .price__strip { display: none; }

  /* Media drops below the copy and stops bleeding off the edge. */
  .pulsing__grid {
    grid-template-columns: 1fr;
    row-gap: 2.25rem;
    padding-inline: clamp(1.25rem, 4vw, 2.5rem);
  }
  .pulsing__media img,
  .pulsing__media video { aspect-ratio: 4 / 3; border-radius: 2px; }

  .about__grid { grid-template-columns: 1fr; }
  /* width:100% is load-bearing. Auto inline margins switch a grid item from
     stretch to shrink-to-fit, and every slider slide is absolutely positioned,
     so .collage__main has no intrinsic width — the whole collage collapsed to
     its own padding (40x48px) and the portraits vanished on phones. */
  .collage { width: 100%; max-width: 440px; margin-inline: auto; }

  /* Podstrona „ja": zdjęcia nad tekstem, kafelki metody jeden pod drugim. */
  .story__grid { grid-template-columns: 1fr; }
  .approach__list { grid-template-columns: 1fr; max-width: 460px; }

  /* Podstrona „pulsing": dwie kolumny wstępu schodzą pod siebie, a tytuł
     wraca do wyrównania do lewej — dosunięcie do prawej ma sens tylko wtedy,
     gdy styka się z sąsiednią kolumną. */
  .pintro__grid { grid-template-columns: 1fr; }
  /* Tytuł zostaje wyśrodkowany także tutaj — wcześniej wracał do lewej,
     bo dosunięcie do prawej miało sens tylko przy sąsiedniej kolumnie.
     Teraz jest wyśrodkowany na każdej szerokości. */

  /* Sekcja „credo” schodzi do jednej kolumny: najpierw tekst, potem wideo.
     Nagranie jest pionowe (9:16) i przy pełnej szerokości telefonu miałoby
     ponad 600px wysokości, więc dostaje limit i środkowanie. */
  .creed--split .creed__grid { grid-template-columns: 1fr; }
  .creed__media { max-width: 320px; margin-inline: auto; width: 100%; }
  .pintro__lead, .pintro__rule, .pintro__text { max-width: none; }
  /* Kółko zjazdu zabierałoby pół szerokości ekranu obok treści — a strzałkę
     w dół i tak zastępuje naturalne przewijanie. */
  .pintro__scroll { display: none; }

  /* Podstrony produktowe: zdjęcie nad tytułem, kolumna boczna pod treścią
     (przestaje być przyklejona, bo nie ma już obok czego stać), a karty
     „zobacz też" schodzą do jednej kolumny. */
  /* W jednej kolumnie centrowanie ścieżek i zwężanie do treści nie mają
     sensu — blok ma wypełnić szerokość ekranu. */
  .post-hero__grid { grid-template-columns: 1fr; justify-content: stretch; }
  .post-hero__col { width: auto; }
  /* W jednej kolumnie nie ma już wolnego marginesu po prawej, w którym
     kółko zjazdu mogłoby wisieć — wraca więc do przepływu, pod treść
     nagłówka i nad falę. */
  .post-hero__scroll {
    position: static;
    margin: clamp(1.75rem, 5vw, 2.5rem) auto 0;
  }
  .post__body { text-align: left; }
  .related__grid { grid-template-columns: 1fr; max-width: 380px; margin-inline: auto; }

  /* Kontakt: pola jedno pod drugim, przycisk przestaje zachodzić na róg
     pola tekstowego (poza kadrem nie ma na co zachodzić) i siada pod nim. */
  .chat__row { grid-template-columns: 1fr; }
  /* Przycisk wrócił do przepływu, więc klauzula nie musi go już przeskakiwać. */
  .form-nota { margin-top: var(--sp-5); }
  .chat__send {
    position: static;
    width: 100%;
    height: auto;
    border-radius: var(--radius-pill);
    padding: 1.1em 1.6em;
    margin-top: var(--sp-4);
    grid-auto-flow: column;
    justify-content: center;
  }
  /* Pasek klatek zachodziłby na treść bąbla — na wąskim ekranie znika,
     tak samo jak jego odpowiednik przy sekcji z ceną. */
  .promo__strip { display: none; }
}

@media (max-width: 620px) {
  /* Tighter bar on phones — 74px of sticky chrome eats a lot of a short
     viewport, and it is pinned to the top of every scroll position. The
     drawer reads the same variable for its top padding. */
  :root { --header-h: 62px; }
  .brand__mark { height: 38px; }

  /* Ten centred lines of body copy on a narrow screen give the eye no fixed
     left edge to return to. The display-size lead stays centred — it is short
     and reads as a pull quote — but the long paragraph ranges left. */
  .about__secondary { text-align: left; }

  /* Main CTAs go full width — a 200px pill floating in a 375px column reads
     as an afterthought, and the wider tap target is easier to hit. Only the
     --quiz CTAs: the short paired links (Zadzwoń / Napisz maila) still fit
     side by side and look wrong stretched. */
  .pill--quiz {
    width: 100%;
    justify-content: center;
  }
  /* Na telefonie kolumna jest wąska jak tekst, więc dosuwanie do prawej nie ma
     do czego dosuwać — przycisk wraca na pełną szerokość, jak pozostałe.
     Limit pilnuje, żeby nigdy nie wyszedł poza szerokość tekstu nad nim. */
  .pulsing__copy .pill {
    width: 100%;
    max-width: 31rem;
    margin-left: 0;
    margin-right: 0;
    justify-content: center;
  }
  /* Except inside a blob. Te kształty nie są prostokątami — przy dolnej
     krawędzi obrys zawija się do środka, więc przycisk na pełną szerokość
     przebija go po bokach. Szerokość z treści trzyma go wewnątrz krzywizny.
     Dotyczy obu bąbli: tego z ceną i tego z zaproszeniem na kontakcie. */
  .price__blob .pill--quiz,
  .promo__blob .pill--quiz { width: auto; }

  /* W wąskiej kolumnie justowanie rozpycha spacje w widoczne dziury —
     na telefonie tekst idzie do lewej. Nie dotyczy już .creed__body: ten jest
     wyśrodkowany na życzenie klienta i ma zostać taki na każdej szerokości. */
  .pintro__text { text-align: left; }

  /* Jedna pod drugą i wyśrodkowane. Pełna szerokość nie wchodzi w grę —
     przy zachowanej proporcji bąbla urosłyby do 284px wysokości. */
  .cta-tri { width: min(100%, 200px); }
  .invite__actions { flex-direction: column; align-items: center; }
  .invite__or { display: none; }

  /* Podstrona „ja": dwa CTA obok siebie i tak by się nie zmieściły —
     stackują się na pełną szerokość, którą daje im reguła .pill--quiz. */
  .closing__actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    max-width: 22rem;
  }

  /* The highlighter runs 2.5em past the word so it trails off the phrase on
     wide screens. In a narrow column that overshoot is most of the line and
     reads as a stray bar, so it stops just after the text. */
  .pulsing__title span::before { right: -.5em; }
  .brand__name { font-size: .72rem; letter-spacing: .13em; }

  /* Three columns collapse to one, everything centred. */
  .footer__grid { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .footer__legal { justify-items: center; text-align: center; }
  .footer__bottom { justify-content: center; text-align: center; }

  /* Two squares side by side get too narrow to read — go single file. */
  .offer__grid { grid-template-columns: 1fr; max-width: 380px; margin-inline: auto; }
  .featured__inner { flex-direction: column; text-align: center; }
  .featured__label { text-align: center; }
}


/* Najwęższe telefony. Osobny blok NA KOŃCU pliku, celowo — wcześniejsza
   próba wstawienia go w środku bloku 960px zamknęła tamten w połowie
   i wszystkie dalsze reguły mobilne przeskoczyły na próg 400px. Liczba
   nawiasów się przy tym zgadzała, więc nie wyłapała tego żadna kontrola
   składni; wyszło dopiero przy pomiarze układu na 430px. */
/* Osobny próg 400px został usunięty. Miał chronić najwęższe telefony
   ciaśniejszym promieniem, ale po zamianie tekstów miejscami zaczął szkodzić:
   przy mniejszym promieniu para chmurek przy godzinie 12 zachodziła na siebie.
   Zmierzone na siedmiu szerokościach — 34% jest jedyną wartością działającą
   w całym paśmie 360–430px, więc obowiązuje jedna reguła dla całej mobilki. */
