/* =========================================================
   Pan Pieseł — style.css
   Źródło prawdy dla UI: DESIGN.md v1.0 (zamrożony 02.09.2026).
   Poprzedni kierunek (design-system.md v3, playful/graficzny —
   Bricolage Grotesque + Manrope, mocne kolory, grube obrysy) jest
   NIEAKTUALNY. Wszystkie sekcje homepage są już przebudowane pod
   DESIGN.md v1.0 (etapy 1–10). Etap 12A (global cleanup) usunął z
   :root stare tokeny kolorów/kontenera/radiusów, które nie miały już
   żadnego aktywnego użycia (--cream, --charcoal, --pink, --pink-dark,
   --yellow, --aqua, --blush, --ink, --container-w, --container-w-wide,
   --r-sm, --r-md, --r-lg). Pozostałe aktywne stare referencje (jest
   ich niewiele) są opisane w TASKS.md wraz z uzasadnieniem, dlaczego
   zostały — to celowe, zgłoszone wyjątki, nie przeoczenia.
   ========================================================= */

:root {
  --r-pill: 999px;

  --ease: cubic-bezier(.22,.68,.24,1);

  --section-pad: 56px;

  /* ---------- Fonty — przełączone na docelowe już teraz ---------- */
  --font-display: 'Fraunces', Georgia, serif;
  --font-body: 'DM Sans', Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* ---------- NOWE TOKENY — DESIGN.md v1.0 ---------- */
  --color-bg: #F1F1F3;
  --color-surface: #FFFFFF;
  --color-surface-alt: #E7E7EA;
  --color-ink: #222126;
  --color-text: #4F4B53;
  --color-muted: #746F78;
  --color-line: #D4D1D7;

  --color-fuchsia: #D52D8B;
  --color-fuchsia-hover: #B92373;
  --color-fuchsia-soft: #F9DCEA;

  --color-aqua: #46CFC8;
  --color-aqua-soft: #D9F4F2;

  --color-yellow: #F2DF46;
  --color-yellow-soft: #FBF5BF;

  /* Dodane etapem 17F.3 dla hover 3 sytuacji klienta w hero — kolory
     jawnie podane wprost w poleceniu (pomarańcz / pudrowy róż),
     nie istniały wcześniej w palecie. */
  --color-orange: #F0923D;
  --color-orange-soft: #FBE3CC;
  --color-orange-hover: #FF7A1F;

  --color-powder-pink: #E8AAB4;
  --color-powder-pink-soft: #FBE9EC;
  --color-powder-pink-hover: #FF8FAE;

  /* Wariant hover żółtego (etap 17F.5) — sam --color-yellow jest już
     jasny/nasycony, "neonowy" efekt to głównie mocniejsze nasycenie
     względem dotychczasowego bardzo jasnego --color-yellow-soft. */
  --color-yellow-hover: #FFDD00;

  --color-graphite: #232127;
  --color-white: #FFFFFF;

  /* Jedyny nowy token spoza DESIGN.md §5.1 — dodany w etapie 15, bo
     §13 "Formularze" wprost wymaga czerwonego komunikatu błędu, a
     system kolorów nie miał dotąd czerwieni. Kontrast na bieli
     zweryfikowany: ~6.5:1 (WCAG AA dla zwykłego tekstu). */
  --color-error: #B3261E;

  --container: 1200px;
  --container-text: 760px;
  --gutter-desktop: 32px;
  --gutter-tablet: 24px;
  --gutter-mobile: 18px;

  --section-space-desktop: 112px;
  --section-space-tablet: 88px;
  --section-space-mobile: 68px;

  --radius-sm: 14px;
  --radius-md: 24px;
  --radius-lg: 36px;
  --radius-pill: 999px;

  --border-width: 1px;
  --border-color: var(--color-line);
  --shadow-elevated: 0 18px 48px rgba(28, 24, 31, 0.08);
  --shadow-none: none;

  /* Skala typografii, desktop (DESIGN.md §6.2); mobile via clamp(), patrz §6.3 */
  --fs-hero: clamp(4rem, 7vw, 6.5rem);
  --fs-h2: clamp(2.625rem, 5vw, 4.25rem);
  --fs-h3: clamp(2rem, 3vw, 2.5rem);
  --fs-lead: clamp(1.1875rem, 1.6vw, 1.3125rem);
  --fs-body: clamp(1rem, 1.2vw, 1.125rem);
  --fs-button: clamp(0.875rem, 1vw, 1rem);
  --fs-eyebrow: clamp(0.6875rem, 0.8vw, 0.75rem);

  /* Breakpointy robocze (DESIGN.md §16) — dokumentacyjne;
     CSS nie pozwala użyć var() w warunku @media, więc @media
     w tym pliku nadal używają literalnych px zgodnych z tymi wartościami. */
  --bp-mobile: 480px;
  --bp-tablet: 768px;
  --bp-small-desktop: 1050px;
  --bp-wide: 1280px;
}

@media (min-width: 768px) { :root { --section-pad: 84px; } }
@media (min-width: 1024px) { :root { --section-pad: 120px; } }
@media (min-width: 1440px) { :root { --section-pad: 136px; } }

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
@media (min-width: 768px) { body { font-size: 17px; } }
@media (min-width: 1024px) { body { font-size: 18px; } }
@media (min-width: 1440px) { body { font-size: 19px; } }

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p, blockquote, figure { margin: 0; }
button { font: inherit; background: none; border: none; cursor: pointer; color: inherit; }
sup { font-size: .6em; }

.wrap {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 24px;
}
@media (min-width: 768px) { .wrap { padding-inline: 40px; } }
@media (min-width: 1280px) { .wrap { padding-inline: 64px; } }

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--color-fuchsia);
  color: var(--color-white);
  font-weight: 700;
  padding: 14px 22px;
  border-radius: 0 0 10px 0;
  z-index: 1000;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }

section { padding-block: var(--section-pad); position: relative; }

/* ---------- Type ---------- */
.eyebrow {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: var(--fs-eyebrow);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--color-muted);
}
.eyebrow span { color: var(--color-muted); font-weight: 700; letter-spacing: .1em; }

.section-heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.3rem, 4vw, 4.6rem);
  line-height: 1.02;
  color: var(--color-ink);
  letter-spacing: -.02em;
  /* etap 17F.6 — nagłówki nie mają łamać się na 3 linie tylko dlatego,
     że element ma niepotrzebnie wąską szerokość; naturalne 2 linie
     zostają, ale bez wymuszania krótszych łamań niż to konieczne. */
  word-break: normal;
  overflow-wrap: normal;
  hyphens: none;
  text-wrap: balance;
}
.section-heading--onlight { color: var(--color-white); }
.section-heading--onphoto { color: var(--color-white); max-width: 20ch; }

em, strong { font-family: inherit; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-shrink: 0;
  white-space: nowrap;
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 15px;
  padding: 15px 28px;
  border-radius: var(--r-pill);
  transition: transform .18s var(--ease), background-color .18s var(--ease), box-shadow .18s var(--ease), color .18s var(--ease);
  min-height: 48px;
  border: 2px solid transparent;
}
/* .btn ustawia display:inline-flex, więc bije domyślne [hidden]{display:none}
   przeglądarki (ta sama specyficzność, reguła autorska zawsze wygrywa) -
   ten sam, wcześniej już znaleziony wzorzec błędu co .field/.field__error
   (etap 15) i .pricing-group (etap 32). Jawny override raz, dla całego
   .btn w każdym miejscu, gdzie kod ustawia .hidden na przycisku
   (np. panel/dyspozycyjnosc - stan zamknięty ukrywa CTA zapisu). */
.btn[hidden] { display: none; }
.btn--large { font-size: 16px; padding: 18px 34px; min-height: 56px; }
.btn--small { padding: 11px 20px; font-size: 13px; min-height: 40px; }
.btn__arrow { width: 16px; height: 16px; flex-shrink: 0; transition: transform .18s var(--ease); }

.btn--primary { background: var(--color-fuchsia); color: var(--color-white); }
.btn--primary:hover, .btn--primary:focus-visible {
  background: var(--color-fuchsia-hover);
  color: var(--color-white);
  transform: translateY(-3px);
  box-shadow: 0 14px 28px -10px rgba(30,26,26,.4);
}
.btn--primary:hover .btn__arrow { transform: translateX(4px); }

.btn--outline {
  background: transparent;
  color: var(--color-ink);
  border-width: var(--border-width);
  border-color: var(--color-line);
}
.btn--outline:hover, .btn--outline:focus-visible {
  background: var(--color-fuchsia);
  border-color: var(--color-fuchsia);
  color: var(--color-white);
  transform: translateY(-3px);
}

/* =========================================================
   LOCATION BAR + HEADER
   DESIGN.md §12.1 — pasek lokalizacji nad headerem; header sticky,
   jasny, subtelny blur dopiero po scrollu; logo w całości; maks.
   5 linków + 1 CTA na desktopie; sticky ≤ ~88px wysokości.
   ========================================================= */
.location-bar {
  background: var(--color-graphite);
  color: var(--color-white);
  text-align: center;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .02em;
  padding: 9px 12px;
}
@media (min-width: 768px) { .location-bar { font-size: 13px; } }

.site-header {
  background: var(--color-surface);
  border-bottom: var(--border-width) solid var(--color-line);
  position: sticky;
  top: 0;
  z-index: 200;
  transition: box-shadow .2s var(--ease), background-color .2s var(--ease);
}
.site-header.is-scrolled {
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 12px 24px -18px rgba(34, 33, 38, .18);
}

.header-inner, .hero-inner {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter-mobile);
}
@media (min-width: 768px) { .header-inner, .hero-inner { padding-inline: var(--gutter-tablet); } }
@media (min-width: 1280px) { .header-inner, .hero-inner { padding-inline: var(--gutter-desktop); } }

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 76px;
}
@media (min-width: 1280px) { .header-inner { min-height: 84px; } }

/* Etap 17C: header nie ma już podpisu "trening i behawior" — logo samo
   ma nieść markę, więc przeszliśmy z małej wersji zbiorczej (ikona+napis
   w kwadracie) na assets/logo-pan-piesel-wordmark.png (sam kolorowy
   napis, format poziomy) w większym rozmiarze niż poprzednio. */
.wordmark { display: flex; align-items: center; flex-shrink: 0; gap: 8px; }
/* Ikona psa + wordmark obok siebie, etap 17F.6A — zastępuje pojedynczy
   niemal-kwadratowy plik logo-pan-piesel.png z etapu 17F.6, w którym
   ograniczenie wysokością ściskało tekst do nieczytelności (ten sam
   problem, co przy dawnym wordmark-only w stopce). Oba assety istniały
   już w projekcie nieużywane — łączymy je flexboxem, bez tworzenia
   nowego pliku/logo i bez zmiany typografii/proporcji żadnego z nich. */
.wordmark__icon { height: 38px; width: auto; max-width: 100%; object-fit: contain; display: block; }
.wordmark__logo { height: 30px; width: auto; max-width: 100%; object-fit: contain; display: block; }
@media (min-width: 768px) { .wordmark__icon { height: 44px; } .wordmark__logo { height: 34px; } }
@media (min-width: 1280px) { .wordmark__icon { height: 46px; } .wordmark__logo { height: 36px; } }

.header-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.header-cta { display: none; }

.menu-toggle {
  width: 44px;
  height: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
  transition: background-color .15s var(--ease);
}
.menu-toggle:hover, .menu-toggle:focus-visible { background: var(--color-surface-alt); }
.menu-toggle span {
  width: 20px;
  height: 2px;
  background: var(--color-ink);
  transition: transform .2s var(--ease), opacity .2s var(--ease);
}
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-scrim {
  position: fixed;
  inset: 0;
  background: rgba(34, 33, 38, .45);
  z-index: 150;
}
.nav-scrim[hidden] { display: none; }

@media (max-width: 1279px) {
  .site-nav {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(360px, 88vw);
    background: var(--color-surface);
    border-left: var(--border-width) solid var(--color-line);
    box-shadow: -24px 0 48px -24px rgba(34, 33, 38, .18);
    padding: 96px 28px 32px;
    transform: translateX(100%);
    transition: transform .28s var(--ease);
    overflow-y: auto;
    z-index: 200;
  }
  .site-nav.is-open { transform: translateX(0); }
  .site-nav__list { display: flex; flex-direction: column; gap: 4px; margin-bottom: 28px; }
  .site-nav__list a {
    font-family: var(--font-display);
    font-size: 26px;
    font-weight: 600;
    display: block;
    padding-block: 8px;
    color: var(--color-ink);
  }
  .site-nav__cta { display: inline-flex; }
}

@media (min-width: 1280px) {
  .menu-toggle { display: none; }
  .header-cta { display: inline-flex; }
  .site-nav { display: flex; align-items: center; gap: 28px; }
  .site-nav__list { display: flex; gap: 22px; }
  .site-nav__list a {
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--color-ink);
    transition: color .15s var(--ease);
    position: relative;
  }
  .site-nav__list a::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -4px;
    height: 2px;
    background: var(--color-fuchsia);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .18s var(--ease);
  }
  .site-nav__list a:hover::after, .site-nav__list a:focus-visible::after { transform: scaleX(1); }
  .site-nav__cta { display: none; }
}
@media (min-width: 1440px) {
  .site-nav { gap: 34px; }
  .site-nav__list { gap: 28px; }
  .site-nav__list a { font-size: 16px; }
}

/* body scroll lock while mobile menu open */
body.menu-open { overflow: hidden; }

/* =========================================================
   HERO — PHOTO ONLY (etap 17F.6) — dogs-on-sofa.jpg jako tło sekcji
   zdjęciowej, H1 wyrównany do GÓRY zdjęcia (dawniej do dołu — zmiana
   17F.6, żeby pasować do nowej kolejności: zdjęcie → biała sekcja
   "Co najlepiej..." → kafle, patrz .hero-choices niżej). Na mobile
   zdjęcie NIE jest croppowane, patrz media query (max-width:767px).
   ========================================================= */
.hero { position: relative; overflow: hidden; padding-top: 40px; padding-bottom: 40px; min-height: 480px; display: flex; align-items: flex-start; }
@media (min-width: 768px) { .hero { min-height: 560px; padding-top: 56px; padding-bottom: 56px; } }
@media (min-width: 1024px) { .hero { min-height: 620px; } }

.hero__bg { position: absolute; inset: 0; z-index: 0; }
.hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 38%; display: block; }
/* delikatny gradient wyłącznie od góry (gdzie teraz siedzi H1) —
   zastępuje dawny gradient od dołu, bo tekst przeniósł się na górę
   zdjęcia (etap 17F.6). Zdjęcie poniżej zostaje w pełni odsłonięte. */
.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20,17,16,.34) 0%, rgba(20,17,16,.06) 40%, rgba(20,17,16,0) 60%);
}

.hero-inner { position: relative; z-index: 1; width: 100%; }

/* Mobile: zdjęcie w naturalnych proporcjach, bez przycinania (etap
   17F.6 — wymóg "widać WSZYSTKIE psy z kanapy"). .hero__bg wraca do
   normalnego przepływu (nie position:absolute), więc .hero rośnie do
   wysokości zdjęcia; H1 zostaje nałożony na górę przez position:absolute
   na .hero-inner, niezależnie od faktycznej wysokości obrazu. */
@media (max-width: 767px) {
  .hero { min-height: 0; padding: 0; display: block; overflow: visible; }
  .hero__bg { position: static; }
  .hero__bg img { position: static; width: 100%; height: auto; object-fit: initial; object-position: initial; }
  .hero__bg::after { content: none; }
  .hero-inner { position: absolute; top: 0; left: 0; right: 0; padding: 20px var(--gutter-mobile) 0; }
}

/* ---------- Headline bezpośrednio na zdjęciu (etap 17F.3) ----------
   Zastępuje wcześniejszy frosted .hero__panel (białą kartę z eyebrow +
   H1 + lead, etap 17F) — na zdjęciu ma zostać wyłącznie mocny headline,
   biały z czarną obwódką, bez karty/tła/dodatkowego tekstu. Lokalizacje
   (dawny .hero__eyebrow) i lead nie mają dziś innego miejsca na
   homepage — świadomie usunięte z hero, nie przeniesione gdzie indziej
   (poza zakresem tej poprawki, patrz CLAUDE.md/TASKS.md). */
.hero__heading--onphoto {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.4rem, 7vw, 5rem);
  line-height: 1.18;
  letter-spacing: -.01em;
  color: var(--color-white);
  -webkit-text-stroke: 1.5px var(--color-graphite);
  text-stroke: 1.5px var(--color-graphite);
  paint-order: stroke fill;
  text-shadow: 0 2px 8px rgba(0, 0, 0, .3);
  max-width: 14ch;
  margin: 0;
}
/* Jedna linia od tabletu w górę (etap 17F.5) — mniejsza, dedykowana
   skala fontu (nie ta sama co mobile 2-liniowe clamp) + wymuszone
   nie-zawijanie, żeby "Opowiedz mi o swoim psie." zmieściło się w
   .hero-inner bez overflow na 768/1024/1440. */
@media (min-width: 768px) {
  .hero__heading--onphoto {
    font-size: clamp(2.4rem, 4.6vw, 4.4rem);
    white-space: nowrap;
    max-width: none;
    -webkit-text-stroke-width: 2px;
  }
  .hero__heading-break { display: none; }
}

/* ---------- "Co najlepiej opisuje Was dzisiaj?" + 3 kafle — biała
   sekcja pod zdjęciem hero (etap 17F.6, zastępuje wersję na zdjęciu z
   17F/17F.3/17F.5). Czyste białe tło gwarantuje czytelność niezależnie
   od treści fotografii nad nią. ---------- */
.hero-choices { background: var(--color-surface); padding-top: 40px; padding-bottom: var(--section-space-mobile); }
@media (min-width: 768px) { .hero-choices { padding-top: 48px; padding-bottom: var(--section-space-tablet); } }
@media (min-width: 1024px) { .hero-choices { padding-top: 56px; } }

.hero-choices__intro {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.15rem, 1.8vw, 1.5rem);
  color: var(--color-ink);
  margin-bottom: 20px;
}

.intent-list { display: flex; flex-direction: column; gap: 12px; max-width: 720px; }

.intent-choice {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 22px;
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-line);
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  box-shadow: 0 10px 28px -14px rgba(20, 17, 16, .35);
  transition: border-color .18s var(--ease), background-color .18s var(--ease), transform .18s var(--ease);
}
.intent-choice:hover, .intent-choice:focus-visible, .intent-choice:active {
  border-color: var(--color-ink);
  transform: translateX(4px);
}
.intent-choice__dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.intent-choice--orange .intent-choice__dot { background: var(--color-orange); }
.intent-choice--yellow .intent-choice__dot { background: var(--color-yellow); }
.intent-choice--pink .intent-choice__dot { background: var(--color-powder-pink); }
/* Mocniejsze, bardziej nasycone kolory hover/focus/active (etap 17F.5)
   — poprzednie -soft warianty oceniono jako za delikatne. Tekst na
   tych tłach przechodzi na --color-ink (zamiast --color-text) na
   hover, żeby zachować bardzo dobrą czytelność bez glow/efektów. */
.intent-choice--orange:hover, .intent-choice--orange:focus-visible, .intent-choice--orange:active { background: var(--color-orange-hover); }
.intent-choice--yellow:hover, .intent-choice--yellow:focus-visible, .intent-choice--yellow:active { background: var(--color-yellow-hover); }
.intent-choice--pink:hover, .intent-choice--pink:focus-visible, .intent-choice--pink:active { background: var(--color-powder-pink-hover); }
.intent-choice:hover .intent-choice__desc, .intent-choice:focus-visible .intent-choice__desc, .intent-choice:active .intent-choice__desc { color: var(--color-ink); }

.intent-choice__body { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.intent-choice__title { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.02rem, 1.5vw, 1.2rem); color: var(--color-ink); line-height: 1.2; }
.intent-choice__desc { font-size: .86em; line-height: 1.4; color: var(--color-text); transition: color .18s var(--ease); }
.intent-choice__arrow { width: 18px; height: 18px; flex-shrink: 0; color: var(--color-ink); transition: transform .18s var(--ease); }
.intent-choice:hover .intent-choice__arrow, .intent-choice:focus-visible .intent-choice__arrow, .intent-choice:active .intent-choice__arrow { transform: translateX(4px); }

@media (min-width: 640px) {
  .intent-choice { padding: 20px 26px; }
  .intent-choice__desc { max-width: 44ch; }
}

/* Desktop: 3 zbliżone do kwadratu kafle w jednym rzędzie (etap 18) —
   zastępuje poziome rzędy z mobile/tablet tylko od 1024px. Mobile/tablet
   układ (flex column, wiersze) zostaje BEZ ZMIAN — jawne polecenie
   "na telefonie obecna forma jest dobra". */
@media (min-width: 1024px) {
  .intent-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; max-width: none; }
  .intent-choice {
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    aspect-ratio: 1 / 1;
    padding: 32px 30px;
    gap: 20px;
  }
  .intent-choice__dot { width: 12px; height: 12px; }
  .intent-choice__body { gap: 10px; }
  .intent-choice__title { font-size: clamp(1.15rem, 1.6vw, 1.35rem); }
  .intent-choice__desc { max-width: none; }
  .intent-choice__arrow { align-self: flex-end; }
  .intent-choice:hover, .intent-choice:focus-visible, .intent-choice:active { transform: translateY(-4px); }
}

/* =========================================================
   "MA BYĆ WAM PO PROSTU ŁATWIEJ ŻYĆ RAZEM" (etap 17D — skrócone do
   jednego kompaktowego editorial bandu, bez card-chrome; poprzednia
   wersja z trzema pełnymi kartami — etap 17C — zastąpiona).
   ========================================================= */
.benefits { background: var(--color-aqua-soft); padding-block: var(--section-space-mobile); overflow: hidden; }
@media (min-width: 768px) { .benefits { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .benefits { padding-block: var(--section-space-desktop); } }

.benefits__heading { max-width: 32ch; }
.benefits__lead { font-size: var(--fs-lead); line-height: 1.55; color: var(--color-text); max-width: 62ch; margin-top: 24px; }

.benefit-row { display: grid; gap: 28px; margin-top: 48px; }
.benefit-point { padding-top: 20px; border-top: 2px solid rgba(34, 33, 38, .14); }
.benefit-point__num { display: block; font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--color-ink); opacity: .5; margin-bottom: 10px; }
.benefit-point__title { font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; color: var(--color-ink); margin-bottom: 8px; }
.benefit-point__text { font-size: .95em; line-height: 1.5; color: var(--color-text); }

@media (min-width: 768px) { .benefit-row { grid-template-columns: repeat(3, 1fr); gap: 32px; } }

/* =========================================================
   JAK MOŻEMY PRACOWAĆ? (etap 13) — DESIGN.md §12.4
   Trzy zróżnicowane kafle (nie identyczne białe SaaS cards, nie kopia
   kart "Od czego chcesz zacząć") — wspólny system (biała powierzchnia,
   cienka linia, radius-md), ale różny akcent koloru na każdym i lekki
   pionowy offset środkowego kafla dla odmiany rytmu.
   ========================================================= */
.work { background: var(--color-bg); padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .work { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .work { padding-block: var(--section-space-desktop); } }

.work-tiles { display: grid; gap: 20px; margin-top: 48px; }
.work-tile {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 32px 28px;
}
.work-tile::before {
  content: "";
  display: block;
  height: 3px;
  width: 56px;
  border-radius: var(--radius-pill);
  margin-bottom: 24px;
}
.work-tile--a::before { background: var(--color-aqua); }
.work-tile--b::before { background: var(--color-fuchsia); }
.work-tile--c::before { background: var(--color-yellow); }

.work-tile__num {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.2rem, 3.5vw, 3rem);
  color: var(--color-line);
  line-height: 1;
  margin-bottom: 16px;
}
.work-tile h3 { font-family: var(--font-display); font-size: clamp(1.5rem, 2.2vw, 1.9rem); font-weight: 600; line-height: 1.1; color: var(--color-ink); margin-bottom: 14px; }
.work-tile p { font-size: 1em; line-height: 1.55; color: var(--color-text); }
.work-tile__note { margin-top: 12px; font-weight: 700; font-size: .85em; color: var(--color-muted); }
.work-tile__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 18px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .85em;
  color: var(--color-ink);
}
.work-tile__cta svg { width: 14px; height: 14px; transition: transform .18s var(--ease); }
.work-tile__cta:hover, .work-tile__cta:focus-visible { color: var(--color-fuchsia); }
.work-tile__cta:hover svg, .work-tile__cta:focus-visible svg { transform: translateX(3px); }

/* Rozszerzenia .work-tile dla pełnej treści /szkolenia/ (etap 18) —
   badge trybu pracy, lista cech/sytuacji, wiersz z dwoma CTA. Homepage
   nadal używa samego podstawowego .work-tile (num/h3/p/note/cta), te
   klasy są dla niego martwym, nieużywanym CSS — nic tu nie zmienia
   wyglądu istniejących kafli homepage. */
.work-tile__badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 14px;
  margin-bottom: 16px;
  border-radius: var(--radius-pill);
  background: var(--color-aqua-soft);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .76em;
  letter-spacing: .02em;
}
.work-tile__list { display: flex; flex-direction: column; gap: 8px; margin: 16px 0; }
.work-tile__list li { position: relative; padding-left: 20px; font-size: .92em; line-height: 1.5; color: var(--color-text); }
.work-tile__list li::before { content: ""; position: absolute; left: 0; top: .55em; width: 6px; height: 6px; border-radius: 50%; background: var(--color-fuchsia); }
.work-tile__cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; margin-top: 18px; }
.work-tile__cta-row .work-tile__cta { margin-top: 0; }

/* Krótki lead pod H2 "Jak możemy pracować?" na /szkolenia/ (etap 18) —
   homepage nie ma tego akapitu, klasa tam nieużywana. */
.work__lead { font-size: var(--fs-lead); line-height: 1.55; color: var(--color-text); max-width: 62ch; margin-top: 20px; }

/* Wariant .work-tiles na 2 kolumny (etap 19, /klasy/ i /obrona/) — moduły
   "pies-pies"/"pies-człowiek" itp. Reużywa dokładnie .work-tile (karta,
   akcent, h3, p), tylko inna liczba kolumn na desktopie. */
@media (min-width: 768px) { .work-tiles.work-tiles--2 { grid-template-columns: repeat(2, 1fr); } }

/* =========================================================
   ETAP: /klasy/ — FINALNA PRZEBUDOWA POD SPRZEDAŻ (19.09.2026)
   Instagram Reels (poprzednia tura) całkowicie ZASTĄPIONE własnym HTML5
   <video> (autoplay/muted/loop/playsinline, bez dźwięku, bez dużych
   natywnych kontrolek) - pliki leżą w assets/video/, ładowane leniwie
   przez IntersectionObserver w script.js (są bardzo duże, kilkadziesiąt
   MB - nic nie pobiera się, dopóki sekcja nie wjedzie w viewport).
   ========================================================= */

/* POPRAWKA /klasy/ - TYLKO WSKAZANE RZECZY (20.09.2026) §1 polecenia -
   film BEZ ramki i bez czarnego kontenera wokół niego - poprzednia tura
   robiła z niego pełnoekranowe "cover" tło (position:absolute + min-height
   + object-fit:cover + czarne tło sekcji jako "obudowa"), co jest
   dokładnie tym, czego to polecenie każe się pozbyć. Dziś: video w
   naturalnych proporcjach, width:100%, zero cropowania/pozycjonowania/
   tła. Jeśli w samym pliku MP4 są zakodowane czarne pasy - zostają,
   CSS ich nie dotyka (jawne zastrzeżenie polecenia). */
.klasy-hero-video__frame video { display: block; width: 100%; height: auto; }
/* BUG /klasy/ - REGRESJA PO OSTATNICH ZMIANACH CSS (20.09.2026) §1 - biały
   pas wokół hero-video pochodził z GLOBALNEJ reguły `section { padding-block:
   var(--section-pad) }` (56-136px zależnie od breakpointu, patrz :root) -
   `.klasy-hero-video` to zwykły element `<section>`, więc dostawał ten sam
   odstęp co każda inna sekcja strony, mimo że ma być pełnoszerokościowym,
   przylegającym do krawędzi filmem. Naprawione dokładnie tym samym,
   ustalonym wzorcem co `.quiz-step { padding-block: 0; }` wyżej w tym pliku
   - scoped WYŁĄCZNIE do tej jednej klasy, zero zmiany globalnej reguły
   `section` (nie dotyczy żadnej innej sekcji /klasy/ ani innej strony). */
.klasy-hero-video { padding-block: 0; }

/* §1 polecenia - pasek "KLASY KOMUNIKACJI" pod filmem: dokładnie
   #000000, WYRAŹNIE niższy niż w poprzedniej turze (padding-block
   40/56px → 14/20px). "KLASY KOMUNIKACJI" jedną linią nawet na 375px -
   `white-space:nowrap` + `font-size` skalowany WYŁĄCZNIE przez `vw`
   (zweryfikowane headless Chrome, patrz raport tej tury i poprzedniej -
   6.8vw z tym stringiem/tą czcionką bezpiecznie mieści się od 320px
   wzwyż). Górny pułap clamp obniżony z 5rem do 3rem - węższy pasek nie
   udźwignąłby wcześniejszej, bardzo dużej litery. `letter-spacing`
   zredukowany do 0 poniżej 480px - tracking kosztuje dodatkowe px na
   każdym z 17 znaków. Rozszerza .section-heading (już ma text-wrap:
   balance/word-break:normal) o uppercase + rozmiar - nie duplikuje
   tamtych reguł. */
.klasy-title-block { background: #000; padding-block: 14px; text-align: center; }
@media (min-width: 768px) { .klasy-title-block { padding-block: 20px; } }
.klasy-title-block__heading {
  text-transform: uppercase;
  letter-spacing: .03em;
  font-size: clamp(1.2rem, 6.8vw, 3rem);
  white-space: nowrap;
  margin: 0;
}
@media (max-width: 479px) { .klasy-title-block__heading { letter-spacing: 0; } }

/* KOREKTA /klasy/ (20.09.2026) §3 polecenia - "Co robią klasy
   komunikacji?" - numer teraz NAD nagłówkiem (block layout zamiast
   dawnego flex-row numer|tekst) - wyraźniejsza hierarchia numer→
   nagłówek→tekst. Numer powiększony (2.4rem→3.2rem) z małym marginesem
   pod spodem, żeby czytał się jako oddzielny, mocny akcent, nie
   "etykietka" obok tytułu. Nagłówek pogrubiony wizualnie przez większy
   odstęp, tekst pod nim przygaszony (--color-muted zamiast --color-text)
   i węższy (max-width w ch) - mniej "dokumentu tekstowego", bardziej
   redakcyjna karta. Aqua na numerach bez zmian. */
.klasy-editorial-list { display: grid; gap: 40px; margin-top: 32px; }
@media (min-width: 768px) { .klasy-editorial-list { grid-template-columns: repeat(2, 1fr); gap: 48px; } }
.klasy-editorial-item__num { display: block; font-family: var(--font-display); font-weight: 700; font-size: 3.2rem; color: var(--color-aqua); line-height: 1; margin-bottom: 8px; }
.klasy-editorial-item h3 { font-family: var(--font-display); font-weight: 700; font-size: 1.2rem; color: var(--color-ink); margin-bottom: 8px; }
.klasy-editorial-item p { font-size: .9em; color: var(--color-muted); line-height: 1.5; max-width: 34ch; }

/* KOREKTA /klasy/ (20.09.2026) §4 polecenia - "Klasy komunikacji vs
   spacer równoległy" przepisane od zera pod nowy sens: to dwa etapy
   jednej drogi, nie dwie alternatywy. ".klasy-journey" to wizualne
   podsumowanie tej drogi (01→02) NAD pełnym porównaniem - pionowo na
   mobile (strzałka obrócona o 90°), poziomo od 768px (strzałka wraca do
   naturalnej orientacji). */
.klasy-journey { display: flex; flex-direction: column; align-items: center; gap: 20px; margin-top: 32px; margin-bottom: 40px; text-align: center; }
@media (min-width: 768px) { .klasy-journey { flex-direction: row; justify-content: center; gap: 40px; } }
.klasy-journey__step { max-width: 220px; }
.klasy-journey__num { display: block; font-family: var(--font-display); font-weight: 700; font-size: 1.8rem; color: var(--color-aqua); line-height: 1; margin-bottom: 4px; }
.klasy-journey__step h3 { font-family: var(--font-display); font-weight: 700; font-size: 1.2rem; color: var(--color-ink); margin-bottom: 2px; }
.klasy-journey__step p { font-size: .88em; color: var(--color-muted); font-style: italic; }
.klasy-journey__arrow { display: block; font-size: 1.6rem; font-weight: 700; color: var(--color-fuchsia); transform: rotate(90deg); }
@media (min-width: 768px) { .klasy-journey__arrow { transform: none; } }

/* Pełne porównanie pod journeyem - dwie kolumny (nie tabela), z pionowym
   separatorem od 768px. Kolejność kolumn: Klasy komunikacji → Spacer
   równoległy (ta sama kolejność co journey wyżej). */
.klasy-compare { display: grid; gap: 32px; margin-top: 0; align-items: start; }
@media (min-width: 768px) { .klasy-compare { grid-template-columns: 1fr auto 1fr; gap: 40px; } }
.klasy-compare__col h3 { font-family: var(--font-display); font-weight: 600; font-size: 1.3rem; color: var(--color-ink); margin-bottom: 12px; }
.klasy-compare__col p { font-size: .95em; color: var(--color-text); line-height: 1.55; margin-bottom: 12px; }
.klasy-compare__divider { display: none; }
@media (min-width: 768px) { .klasy-compare__divider { display: block; width: 1px; background: var(--color-line); align-self: stretch; } }
/* POPRAWKA /klasy/ (20.09.2026) §3 polecenia - jedna krótka nota
   ("na spacer równoległy pies musi być gotowy...") między porównaniem a
   puentą, zastępuje usunięty ".klasy-vs-subpunchline" (dawne drugie
   zdanie pod puentą - martwe, nieużywane nigdzie indziej, usunięte). */
.klasy-vs-note { margin-top: 24px; max-width: 64ch; margin-inline: auto; font-size: .95em; color: var(--color-text); text-align: center; line-height: 1.5; }
.klasy-vs-punchline { margin-top: 20px; font-family: var(--font-display); font-weight: 700; font-style: italic; font-size: clamp(1.4rem, 2.6vw, 1.9rem); color: var(--color-fuchsia); text-align: center; }

/* KOREKTA /klasy/ (20.09.2026, poprzednia tura) - "Zobacz, co może się
   zmienić" - szerszy wewnętrzny kontener WYŁĄCZNIE dla tej sekcji
   (scoped .klasy-zmiana .wrap, nie dotyka globalnego --container/.wrap
   używanego przez resztę serwisu) - filmy były "za małe względem całej
   szerokości sekcji" w standardowym 1200px kontenerze.
   POPRAWKA (20.09.2026) §4 polecenia - oba filmy są zmontowane poziomo -
   dawna "premium karta" (border-radius/czarne tło/cień, myślana pod
   film pionowy) USUNIĘTA - dziś naturalne proporcje, zero
   ramki/mockupu, bez zmiany układu 2 kolumny desktop / 1 kolumna mobile. */
@media (min-width: 1024px) { .klasy-zmiana .wrap { max-width: 1400px; } }
.klasy-video-grid { display: grid; gap: 32px; margin-top: 32px; }
@media (min-width: 768px) { .klasy-video-grid { grid-template-columns: repeat(2, 1fr); } }
.klasy-video-grid__item { text-align: center; }
.klasy-video-grid__frame video { display: block; width: 100%; height: auto; }
.klasy-video-grid__heading { margin-top: 18px; font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--color-ink); }

/* Kontrast PRZED/PÓŹNIEJ (§6 polecenia) - zastępuje dawny długi akapit
   pod każdym filmem. */
.klasy-contrast { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 14px; flex-wrap: wrap; }
.klasy-contrast__before, .klasy-contrast__after { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.klasy-contrast__label { font-size: .7em; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; color: var(--color-muted); }
.klasy-contrast__value { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--color-ink); }
.klasy-contrast__after .klasy-contrast__value { color: var(--color-fuchsia); }
.klasy-contrast__arrow { font-size: 1.3rem; font-weight: 700; color: var(--color-fuchsia); }

/* §9 polecenia (etap poprzedni) - "Najbliższe wydarzenie" (pojedyncze,
   wyeksponowane) - wyłącznie CSS-owe wzmocnienie już istniejącego
   .event-row/.event-rows (współdzielonego z /wydarzenia/ i homepage) -
   scoped selektor, zero zmian w bazowych klasach używanych gdzie indziej.
   KOREKTA (20.09.2026) §9 polecenia - powiększona typografia daty/tytułu
   w tej jednej, wyeksponowanej karcie ("wizualnie ważniejsza niż teraz"). */
.klasy-nastepny-featured .event-row {
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  background: var(--color-surface);
  box-shadow: var(--shadow-elevated);
}
.klasy-nastepny-featured .event-row:first-child { border-top: var(--border-width) solid var(--color-line); padding-top: 28px; }
.klasy-nastepny-featured .event-row__title { font-size: 1.3rem; }
.klasy-nastepny-featured .event-row__date-day { font-size: 2.1rem; }

/* KOREKTA /klasy/ (20.09.2026) §10 polecenia - "Cena" - prosty, duży
   nagłówek "Cena: 100 zł" (dawne hasło "100 zł. I nie płacisz tylko za
   godzinę na placu." usunięte, jawny zakaz) + CTA "Wybieram najbliższy
   termin" w tej samej sekcji (#klasy-cena-cta, href ustawiany dynamicznie
   w script.js na TEN SAM event_id co reszta strony). Tło zostaje
   --color-fuchsia-soft (istniejący token, modyfikator .info-section--
   fuchsia z poprzedniej tury). */
.info-section--fuchsia { background: var(--color-fuchsia-soft); }
.klasy-price-heading { font-size: clamp(2rem, 4vw, 3.2rem); }
.klasy-price-sublead { font-weight: 700; color: var(--color-ink); margin-top: 24px; }

/* POPRAWKA /klasy/ (20.09.2026) §7 polecenia - "Historie z klas" - TREŚĆ
   historii bez zmian + Paulina + Rollo (nowa, piąta) - patrz HTML.
   Fotograficzne tło PRZYWRÓCONE (assets/testimonials-background.jpg +
   ciemny gradient overlay) - odwraca poprzednią turę (płaskie
   --color-surface-alt) na wyraźne polecenie tej tury. Tekst wraca z
   ciemnego (na jasnym tle) na biały (na ciemnym zdjęciu), taby wracają
   do białych obwódek na przezroczystym tle - dokładnie ten sam wzorzec,
   co przed poprzednią korektą. Rozmiar contentu (920px, powiększone
   cytat/cite/before/taby z poprzedniej tury) BEZ ZMIAN - to polecenie
   go nie dotyczy. */
.klasy-stories { position: relative; padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .klasy-stories { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .klasy-stories { padding-block: var(--section-space-desktop); } }
.klasy-stories__bg { position: absolute; inset: 0; background: url("assets/testimonials-background.jpg") center 30% / cover no-repeat; }
.klasy-stories__bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(165deg, rgba(20, 17, 16, .85), rgba(20, 17, 16, .65) 55%, rgba(20, 17, 16, .88)); }
.klasy-stories__inner { position: relative; z-index: 1; }
.klasy-stories .section-heading { text-align: center; margin: 0 auto 36px; max-width: none; color: var(--color-white); }

.klasy-stories__tabs { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-bottom: 40px; }
.klasy-stories__tab {
  min-height: 48px;
  padding: 12px 22px;
  border: var(--border-width) solid rgba(255, 255, 255, .35);
  border-radius: var(--radius-sm);
  background: transparent;
  color: rgba(255, 255, 255, .85);
  font-weight: 700;
  font-size: .95rem;
  cursor: pointer;
}
.klasy-stories__tab.is-active { background: var(--color-white); color: var(--color-ink); border-color: var(--color-white); }
.klasy-stories__tab:focus-visible { outline: 2px solid var(--color-white); outline-offset: 2px; }

.klasy-story { max-width: 920px; margin: 0 auto; text-align: center; }
.klasy-story__quote p { font-family: var(--font-display); font-weight: 500; font-size: clamp(1.4rem, 2.8vw, 2.1rem); line-height: 1.4; color: var(--color-white); }
.klasy-story__quote footer { margin-top: 20px; }
.klasy-story__quote cite { font-style: normal; font-weight: 700; font-size: 1.1rem; color: var(--color-white); }
.klasy-story__before { max-width: 60ch; margin: 22px auto 0; color: rgba(255, 255, 255, .75); font-size: 1em; }
.klasy-story__before strong { color: var(--color-white); }

/* Historia D (Ania + Dragon) jest wizualna - prawdziwego zdjęcia nie ma
   jeszcze w repo (potwierdzone, assets/Ania.jpg to inna, niezwiązana
   osoba - groomerka). Miejsce zarezerwowane jawnym placeholderem, NIE
   wymyślonym/wygenerowanym obrazem - patrz raport tej tury po dokładną
   docelową ścieżkę pliku. Kolory z powrotem dostosowane do ciemnego tła. */
.klasy-story__photo-placeholder {
  aspect-ratio: 4 / 3;
  max-width: 420px;
  margin: 0 auto 24px;
  border-radius: var(--radius-md);
  border: 2px dashed rgba(255, 255, 255, .4);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, .6);
  font-size: .85em;
  line-height: 1.5;
  text-align: center;
  padding: 16px;
}

/* =========================================================
   /KLASY/, /OBRONA/ (etap 19) — podstrony w tym samym kierunku
   wizualnym co homepage/szkolenia, zero nowego systemu designu.
   ========================================================= */
/* Hero z zdjęciem obok tekstu (reużywa .apply-hero__heading/__text/
   __actions/__link z /szkolenia/, .eyebrow, .btn — tylko układ 2-kolumnowy
   i kadr zdjęcia są nowe, oparte o --radius-lg i istniejące zdjęcia
   assets/communication-classes.jpg, assets/sport-defense.jpg). */
.subpage-hero { background: var(--color-bg); padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .subpage-hero { padding-block: var(--section-space-tablet); } }
.subpage-hero__grid { display: grid; gap: 32px; align-items: center; }
@media (min-width: 1024px) { .subpage-hero__grid { grid-template-columns: 1fr 1fr; gap: 56px; } }
.subpage-hero__photo { border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 16 / 10; margin: 0; }
.subpage-hero__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* MAŁY PATCH COPY + HERO /KLASY/ (17.09.2026) - kolumna tekstu 50/50 była
   zbyt wąska dla H1 (łamał się na bardzo dużo krótkich linii) - modyfikator
   WYŁĄCZNIE na /klasy/ (nie zmienia /obrona/, która reużywa tę samą bazową
   klasę .subpage-hero__grid) daje tekstowi większy udział szerokości,
   zamiast zmniejszać font. Mobile/tablet (poniżej 1024px) bez zmian -
   dziedziczy bazowe .subpage-hero__grid (jedna kolumna). */
@media (min-width: 1024px) {
  .subpage-hero__grid--text-wide { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
}

/* MAŁY PATCH MOBILE HERO /KLASY/ (17.09.2026) - zdjęcie ma iść PRZED
   tekstem WYŁĄCZNIE na mobile/tablet, zero duplikacji HTML - `order` na
   elemencie grida, scoped tym samym modyfikatorem `--text-wide` co wyżej
   (obecnym WYŁĄCZNIE na /klasy/, nigdy na /obrona/, która dzieli tę samą
   bazową .subpage-hero__grid). Poniżej 1024px .subpage-hero__grid nie ma
   zdefiniowanych kolumn (jedna kolumna, elementy w rzędach) - `order`
   zmienia wyłącznie kolejność wierszy. Reguła żyje w tym samym @media co
   pojawia się w źródle CSS zdjęcia (max-width tuż poniżej progu wyżej) -
   automatycznie przestaje obowiązywać od 1024px, przywracając kolejność
   z HTML (tekst, potem zdjęcie) bez jawnego resetu. */
@media (max-width: 1023.98px) {
  .subpage-hero__grid--text-wide .subpage-hero__photo { order: -1; }
}

/* Uniwersalna sekcja treściowa (etap 19) — H2 + opcjonalny .work__lead +
   opcjonalna .work-tile__list/.work-tiles, naprzemienne tło z istniejących
   tokenów dla rytmu kolorystycznego (DESIGN.md), bez nowych kolorów. */
.info-section { padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .info-section { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .info-section { padding-block: var(--section-space-desktop); } }
.info-section--bg { background: var(--color-bg); }
.info-section--surface { background: var(--color-surface); }
.info-section--aqua { background: var(--color-aqua-soft); }
.info-section--yellow { background: var(--color-yellow-soft); }

@media (min-width: 768px) { .work-tiles { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1024px) { .work-tile--b { margin-top: -20px; padding-top: 48px; padding-bottom: 48px; } }

/* Informacja o zapisie bezpośrednim na Klasy/Obronę (etap 18) —
   zastępuje dawny .work-callout (fuksjowy box+ikona+border, etap 17F.6),
   uznany za zbyt bannerowy/niejasny co do tego, czego dotyczy. Zwykły
   tekst BEZ boxa/tła/ramki, bezpośrednio nad kartami Klasy/Obrona — sama
   bliskość ma tłumaczyć relację. Współdzielone z homepage i /szkolenia/.
   Homepage: <p><strong>...</strong> ...</p>. /szkolenia/ (osobna sekcja,
   wymaga własnego H2 dla hierarchii H1→H2→H3): .direct-booking-note__heading. */
.direct-booking-note { margin-top: 32px; max-width: 64ch; }
.direct-booking-note p { font-size: 1.02em; line-height: 1.5; color: var(--color-ink); }
.direct-booking-note strong { font-weight: 800; }
.direct-booking-note__heading {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 1.02em;
  line-height: 1.5;
  color: var(--color-ink);
  margin-bottom: 2px;
}

/* /szkolenia/ (etap 18): Klasy/Obrona jako OSOBNA sekcja (nie zagnieżdżona
   w .work jak na homepage) — jawne polecenie tego etapu. Naprzemienne tło
   względem .work (--color-bg) dla zachowania rytmu kolorystycznego. */
.work-direct { background: var(--color-surface); padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .work-direct { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .work-direct { padding-block: var(--section-space-desktop); } }

/* etap 17F — Klasy komunikacji / Obrona jako widoczne, fotograficzne
   moduły WEWNĄTRZ tej samej sekcji oferty (nie osobna sekcja) */
.work-specialties { display: grid; gap: 20px; margin-top: 28px; }
@media (min-width: 768px) { .work-specialties { grid-template-columns: 1fr 1fr; gap: 24px; } }

.work-specialty { background: var(--color-surface); border-radius: var(--radius-lg); overflow: hidden; border: var(--border-width) solid var(--color-line); }
.work-specialty__photo { aspect-ratio: 16 / 10; margin: 0; }
.work-specialty__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.work-specialty__copy { padding: 24px 24px 28px; }
.work-specialty__accent { display: block; height: 4px; width: 52px; border-radius: var(--radius-pill); margin-bottom: 16px; background: var(--color-fuchsia); }
.work-specialty__accent--aqua { background: var(--color-aqua); }
.work-specialty__title { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.3rem, 2vw, 1.6rem); color: var(--color-ink); margin-bottom: 10px; }
.work-specialty__text { font-size: .98em; line-height: 1.5; color: var(--color-text); }
.work-specialty__cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; margin-top: 18px; }
.work-specialty__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .88em;
  color: var(--color-ink);
}
.work-specialty__link svg { width: 14px; height: 14px; transition: transform .18s var(--ease); }
.work-specialty__link:hover, .work-specialty__link:focus-visible { color: var(--color-fuchsia); }
.work-specialty__link:hover svg, .work-specialty__link:focus-visible svg { transform: translateX(3px); }

/* =========================================================
   CENNIK CTA (etap 17E) — zastępuje ceny pokazywane bezpośrednio przy
   formach współpracy. Jeden wyraźny pas, nie kolejna duża sekcja.
   ========================================================= */
.pricing-cta { background: var(--color-fuchsia-soft); padding-block: 80px; }
@media (min-width: 1024px) { .pricing-cta { padding-block: 100px; } }
.pricing-cta__inner {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
@media (min-width: 640px) { .pricing-cta__inner { flex-direction: row; align-items: center; justify-content: space-between; gap: 32px; } }
.pricing-cta__heading { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.4rem, 2.2vw, 1.8rem); color: var(--color-ink); margin-bottom: 4px; }
.pricing-cta__text { font-size: .95em; color: var(--color-text); }
.pricing-cta .btn--primary { flex-shrink: 0; }

/* =========================================================
   ROZWIJAJ SIĘ Z PANEM PIESEŁEM (etap 17C §15-18, podłączone etapem 9 §15).
   ETAP: UPROSZCZENIE WYDARZEŃ WWW + INTUICYJNE DOŁĄCZANIE W PANELU
   (18.09.2026, §1-§3 polecenia) - dawny system dużych kart (`.event-card`,
   z miniaturą i dwoma wariantami `--compact`/`--full`) ZASTĄPIONY jednym,
   kompaktowym, jednowierszowym układem (`.event-row`), IDENTYCZNYM na
   homepage i /wydarzenia/ ("ten sam system list", §1/§3 polecenia) - bez
   miniatur, cienkie separatory zamiast dużych kart z cieniem/ramką, żeby
   kilka wydarzeń mieściło się na ekranie 15" bez dużego scrollowania.
   ========================================================= */
.events { background: var(--color-yellow-soft); padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .events { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .events { padding-block: var(--section-space-desktop); } }

.events__lead { font-size: 1.05em; color: var(--color-text); max-width: 56ch; margin-top: 12px; }

/* Kontener listy - WSPÓLNY dla homepage (`#events-grid`) i /wydarzenia/
   (`#wydarzenia-list`), cienkie separatory między wierszami zamiast
   dużego `gap` między kartami (§1 polecenia: "dużo oddechu, cienkie
   separatory zamiast ciężkich, dużych kart"). */
.event-rows { display: flex; flex-direction: column; margin-top: 32px; }

.event-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-block: 20px;
  border-top: var(--border-width) solid var(--color-line);
}
.event-row:first-child { border-top: none; padding-top: 0; }

/* Desktop/tablet (≥768px) - jeden rząd: DATA | TYTUŁ+META | CENA/MIEJSCA |
   CTA (§1 polecenia, przykładowy układ ticketu), wyrównane pionowo do
   środka. Mobile - jedna kolumna, kolejność DOM (data nad tytułem, CTA na
   końcu) - bez poziomego scrolla. */
@media (min-width: 768px) {
  .event-row {
    flex-direction: row;
    align-items: center;
    gap: 24px;
    padding-block: 22px;
  }
}

.event-row__date {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 6px;
  flex-shrink: 0;
}
@media (min-width: 768px) {
  .event-row__date { flex-direction: column; align-items: flex-start; gap: 0; width: 56px; }
}
.event-row__date-day { font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; line-height: 1; color: var(--color-ink); }
.event-row__date-month { font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--color-fuchsia); }
.event-row__date-weekday { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--color-muted); }

.event-row__info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.event-row__badge {
  align-self: flex-start;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--color-fuchsia-soft);
  color: var(--color-fuchsia);
  margin-bottom: 2px;
}
.event-row__title { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.1rem, 1.6vw, 1.25rem); line-height: 1.3; color: var(--color-ink); }
.event-row__meta { font-size: .92em; color: var(--color-muted); font-weight: 600; }
.event-row__desc { font-size: .9em; color: var(--color-text); line-height: 1.5; margin-top: 2px; }

.event-row__price-block { flex-shrink: 0; display: flex; flex-direction: column; gap: 2px; }
@media (min-width: 768px) { .event-row__price-block { text-align: right; width: 160px; } }
.event-row__price { font-size: 1em; color: var(--color-ink); font-weight: 700; }
.event-row__price-discount { font-size: .88em; color: var(--color-fuchsia); font-weight: 700; }
.event-row__spots { font-size: .85em; color: var(--color-muted); }

.event-row__cta-block { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; flex-shrink: 0; }
/* `.event-row__cta` - dawny, zwykły link tekstowy (zachowany w kodzie,
   dziś nieużywany - appendEventCta() renderuje wyłącznie przyciski).
   `.event-row__cta-btn` - prawdziwe CTA (klasy .btn/.btn--primary/
   .btn--outline dodawane w JS), primary i secondary jeden obok drugiego. */
.event-row__cta { font-weight: 700; color: var(--color-ink); display: inline-flex; align-items: center; gap: 6px; }

/* POPRAWKA: FACEBOOK JAKO DRUGORZĘDNY LINK NA HOMEPAGE (19.09.2026) - MAŁY,
   drugorzędny link tekstowy (nigdy .btn) dla wydarzeń z dedykowaną stroną
   usługi na homepage (communication_classes/protection) - świadomie
   mniejszy/przygaszony niż główne CTA ".event-row__cta-btn.btn--primary"
   obok niego (to ono ma wizualnie dominować), ale nadal czytelny i z
   wygodnym obszarem dotyku (min-height, bez wizualnego powiększania tekstu). */
.event-row__cta-fb {
  font-size: .85em;
  font-weight: 600;
  color: var(--color-muted);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.event-row__cta-fb:hover, .event-row__cta-fb:focus-visible { color: var(--color-fuchsia-hover); }

/* =========================================================
   OPINIE (etap 13) — DESIGN.md §12.7. Kompozycja "unoszących się"
   karteczek zamiast slidera: wszystkie widoczne naraz, różne wielkości,
   lekka rotacja/asymetria (CSS columns = naturalna masonry bez JS),
   miękkie cienie, subtelne pionowe unoszenie (translate, niezależne od
   statycznej rotacji na transform). prefers-reduced-motion wyłącza
   unoszenie całkowicie. Mobile: pojedyncza kolumna = czytelny strumień.
   ========================================================= */
.testimonials { position: relative; padding-top: 140px; padding-bottom: 64px; scroll-margin-top: 96px; }
@media (min-width: 1024px) { .testimonials { padding-top: 168px; padding-bottom: 80px; } }
.testimonials__bg { position: absolute; inset: 0; background: url("assets/testimonials-background.jpg") center 30% / cover no-repeat; }
.testimonials__bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(165deg, rgba(20,17,16,.82), rgba(20,17,16,.6) 55%, rgba(20,17,16,.85)); }
.testimonials__inner { position: relative; z-index: 1; }
.testimonials .section-heading { margin-bottom: 40px; }

.quote-cloud {
  margin-top: 48px;
  column-count: 1;
  column-gap: 24px;
}
@media (min-width: 640px) { .quote-cloud { column-count: 2; } }
@media (min-width: 1100px) { .quote-cloud { column-count: 3; column-gap: 28px; } }

.quote-card {
  display: inline-block;
  width: 100%;
  break-inside: avoid;
  margin-bottom: 24px;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  padding: 28px 26px;
  box-shadow: 0 16px 32px -14px rgba(20, 17, 16, .2);
}
.quote-card--featured { padding: 36px 32px; }

/* lekkie, zróżnicowane rotacje — delikatna asymetria, nie chaos */
.quote-card--a { transform: rotate(-1deg); }
.quote-card--b { transform: rotate(1.2deg); }
.quote-card--c { transform: rotate(-0.8deg); }
.quote-card--d { transform: rotate(1deg); }
.quote-card--e { transform: rotate(-1.3deg); }
.quote-card--f { transform: rotate(0.7deg); }
@media (max-width: 639px) { .quote-card { transform: none !important; } }

.quote-card p {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.1rem, 2vw, 1.4rem);
  line-height: 1.35;
  color: var(--color-ink);
  margin-bottom: 18px;
}
.quote-card--featured p { font-size: clamp(1.25rem, 2.6vw, 1.9rem); }
@media (max-width: 479px) {
  .quote-card p { font-size: 1.05rem; line-height: 1.42; }
}
.quote-card footer { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.quote-card cite { font-style: normal; font-family: var(--font-body); font-weight: 700; color: var(--color-ink); }
.quote-card footer span { font-size: .85em; color: var(--color-muted); font-weight: 600; }

/* delikatne unoszenie — niezależne od statycznej rotacji dzięki
   CSS Individual Transform Properties (translate osobno od transform) */
@media (prefers-reduced-motion: no-preference) {
  .quote-card--a { animation: quote-float 7.5s ease-in-out .1s infinite; }
  .quote-card--b { animation: quote-float 8.5s ease-in-out .6s infinite; }
  .quote-card--c { animation: quote-float 6.8s ease-in-out 1.1s infinite; }
  .quote-card--d { animation: quote-float 9s ease-in-out .3s infinite; }
  .quote-card--e { animation: quote-float 7.8s ease-in-out .8s infinite; }
  .quote-card--f { animation: quote-float 8.2s ease-in-out 1.4s infinite; }
  @keyframes quote-float {
    0%, 100% { translate: 0 0; }
    50% { translate: 0 -8px; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .quote-card { animation: none !important; }
}

/* =========================================================
   O MNIE (DESIGN.md §12.7)
   Zdjęcie 42–46% / treść 54–58% na desktopie; kwalifikacje jako ciche,
   uporządkowane tagi — element drugorzędny wizualnie, nie ściana
   certyfikatów. Hierarchia: główny opis (H2 + tekst) → CTA →
   kwalifikacje → nota prawna, w tej kolejności malejącej wagi.
   ========================================================= */
.about { background: var(--color-bg); padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .about { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .about { padding-block: var(--section-space-desktop); } }

.about__grid { display: grid; gap: 40px; align-items: start; }
.about__photo {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: var(--border-width) solid var(--color-line);
  box-shadow: var(--shadow-elevated);
  aspect-ratio: 3 / 4;
}
/* etap 17F: było 4/5 + object-position 50% 20% — ucinało nogi w
   nienaturalnym miejscu (kadr skupiony zbyt wysoko na zdjęciu pełnej
   sylwetki). Zdjęcie asset/about-martyna-baldur.webp to Martyna z psem
   w pełnej sylwetce na chodniku (pion 1206×2117) — 3/4 (mniej agresywny
   crop niż 4/5) + object-position Y 38% pokazuje więcej dołu kadru,
   obejmując buty/nogi, kosztem odrobiny nieba nad czapką. */
.about__photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 38%; }
.about__eyebrow { margin-bottom: 6px; }
.about__text { font-size: clamp(1.05rem, 1.5vw, 1.3rem); line-height: 1.55; margin-top: 20px; max-width: 52ch; color: var(--color-text); }
.about__highlight {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 700;
  font-size: clamp(1.4rem, 2.2vw, 1.9rem);
  line-height: 1.35;
  color: var(--color-fuchsia);
  margin-top: 24px;
  max-width: 46ch;
}
.about__copy .btn { margin-top: 32px; }

.about__more { margin-top: 64px; padding-top: 40px; border-top: var(--border-width) solid var(--color-line); }
.about__more-heading {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-muted);
  margin-bottom: 20px;
}
.credentials {
  display: grid;
  gap: 16px 32px;
}
@media (min-width: 768px) { .credentials { grid-template-columns: 1fr 1fr; } }
.credentials li { display: flex; flex-direction: column; gap: 4px; }
.credentials__name { font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; color: var(--color-ink); }
/* "Wkrótce" pozycja (etap 17F.6) — spójna z resztą listy, subtelnie
   wyróżniona kursywą + przygaszonym kolorem, nie osobnym badge'em. */
.credentials__name--soon { font-style: italic; color: var(--color-muted); font-weight: 500; }
.credentials__desc { font-family: var(--font-body); font-size: .85em; color: var(--color-muted); }
.disclaimer { margin-top: 20px; font-size: 12px; color: var(--color-muted); max-width: 60ch; }

/* etap 17D — wariant skrócony, użyty bezpośrednio w .about__copy (bez
   .about__more wrappera i bez nagłówka "Moje zaplecze"), lista pozioma
   zamiast siatki 2-kolumnowej z opisami pod każdą pozycją */
.credentials--compact { display: flex; flex-wrap: wrap; gap: 10px 24px; margin-top: 28px; }
.credentials--compact li { flex-direction: row; align-items: baseline; gap: 8px; }
.credentials--compact .credentials__name { font-size: .96rem; }
.credentials--compact .credentials__desc { font-size: .87em; }

@media (min-width: 1024px) { .about__grid { grid-template-columns: 4fr 5fr; gap: 64px; } }

/* =========================================================
   GROOMER — mały cross-sell blok (etap 17D, zastępuje pełną sekcję
   editorial 50/50 z etapu 12B/17C — groomer nie jest głównym celem
   homepage szkoleń, nie potrzebuje dużego zdjęcia ani rozbudowanego copy).
   ========================================================= */
.groomer-teaser {
  background: var(--color-surface);
  border-top: var(--border-width) solid var(--color-line);
  padding-block: 40px;
}
.groomer-teaser__inner {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
@media (min-width: 640px) { .groomer-teaser__inner { flex-direction: row; align-items: center; justify-content: space-between; gap: 32px; } }

.groomer-teaser__heading { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.3rem, 2vw, 1.6rem); color: var(--color-ink); margin-bottom: 4px; }
.groomer-teaser__text { font-size: .95em; color: var(--color-text); }

.groomer-teaser__cta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; flex-shrink: 0; }
.groomer-teaser__link { font-family: var(--font-body); font-weight: 700; font-size: .9em; color: var(--color-ink); }
.groomer-teaser__link:hover, .groomer-teaser__link:focus-visible { color: var(--color-fuchsia); }

@media (min-width: 1024px) {
  .groomer__grid { grid-template-columns: 4fr 5fr; gap: 64px; }
  .groomer__photo { order: 2; }
  .groomer__copy { order: 1; }
}

/* =========================================================
   FAQ
   ========================================================= */
/* DESIGN.md §12.8 — wstęp po lewej, accordion po prawej; cienkie linie
   1px zamiast kart; plus obraca się do × (rotacja 45°); fuksja tylko
   jako akcent hover/focus/otwartego stanu, nie kolor statyczny. */
/* Sekcja wysmuklona etapem 17F.6 — dawny wspólny --section-space-*
   token (68-112px) oceniony jako za duży dla FAQ, własny, mniejszy
   padding tylko tutaj. */
.faq { background: var(--color-bg); padding-block: 32px; }
@media (min-width: 768px) { .faq { padding-block: 48px; } }
@media (min-width: 1024px) { .faq { padding-block: 56px; } }

/* Ułożenie w jednej kolumnie na wszystkich szerokościach (etap 17F.6A)
   — zastępuje dawny 2-kolumnowy układ na desktopie (wstęp po lewej,
   accordion po prawej, od etapu 17D). Jawne nowe polecenie: eyebrow
   ma siedzieć BEZPOŚREDNIO nad accordionem, bez osobnej kolumny i bez
   pustej przestrzeni między nimi. */
.faq__grid { display: block; }
.faq__intro { margin-bottom: 20px; }

/* Mały eyebrow zamiast dawnego ogromnego section-heading (etap 17F.6),
   wielkość skorygowana etapem 18 — ma być TYLKO delikatnie większy od
   pytań accordionu, nie mały label. Hierarchia: heading > pytania >
   odpowiedzi. Desktop ~24px, mobile ~19px (patrz .accordion__trigger
   niżej dla porównania: ~19-21px desktop, ~17px mobile). */
.faq__eyebrow {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: clamp(1.2rem, 2.6vw, 1.5rem);
  letter-spacing: 0;
  color: var(--color-fuchsia);
  line-height: 1.3;
  max-width: 34ch;
}

.accordion { border-top: var(--border-width) solid var(--color-line); }
.accordion__item { border-bottom: var(--border-width) solid var(--color-line); }
.accordion__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-block: 16px;
  text-align: left;
  font-family: var(--font-display);
  font-size: clamp(1.0625rem, 1.6vw, 1.3rem);
  font-weight: 600;
  color: var(--color-ink);
}
.accordion__icon { width: 20px; height: 20px; flex-shrink: 0; color: var(--color-muted); transition: transform .22s var(--ease), color .18s var(--ease); }
.accordion__trigger:hover .accordion__icon,
.accordion__trigger:focus-visible .accordion__icon,
.accordion__trigger[aria-expanded="true"] .accordion__icon { color: var(--color-fuchsia); }
.accordion__trigger[aria-expanded="true"] .accordion__icon { transform: rotate(45deg); }
.accordion__trigger:hover span { text-decoration: underline; text-decoration-color: var(--color-fuchsia); text-decoration-thickness: 2px; text-underline-offset: 5px; }
.accordion__panel { padding-bottom: 16px; max-width: 68ch; }
.accordion__panel p { font-size: .92em; line-height: 1.55; color: var(--color-text); }
.accordion__panel p + p { margin-top: 10px; }
/* Linki wewnątrz odpowiedzi akordeonu (np. panel/zasady/) - globalny
   `a { color:inherit }` (reset u góry pliku) zostawiałby je wizualnie
   nieodróżnialne od zwykłego tekstu. */
.accordion__panel a { color: var(--color-fuchsia); font-weight: 700; }
.accordion__panel a:hover, .accordion__panel a:focus-visible { color: var(--color-fuchsia-hover); }

@media (prefers-reduced-motion: no-preference) {
  .accordion__panel:not([hidden]) { animation: faq-in .28s var(--ease); }
  @keyframes faq-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
}

/* =========================================================
   FINAL CTA (DESIGN.md §12.11, etap 17C) — mocny fuksjowy blok
   (wcześniej grafitowy — grafit zarezerwowany teraz dla stopki, patrz
   DESIGN.md §12). Przycisk primary i link secondary dostają lokalne
   nadpisania, bo domyślny .btn--primary (fuksja na białym) i domyślny
   hover .final-cta__secondary (fuksja) znikałyby na fuksjowym tle.
   ========================================================= */
.final-cta {
  background: var(--color-fuchsia);
  text-align: center;
  padding-block: var(--section-space-mobile);
}
@media (min-width: 768px) { .final-cta { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .final-cta { padding-block: var(--section-space-desktop); } }

.final-cta__inner { display: flex; flex-direction: column; align-items: center; }
.final-cta .eyebrow,
.final-cta .eyebrow span { color: rgba(255, 255, 255, .75); }
.final-cta__eyebrow { margin-bottom: 4px; }
.final-cta .section-heading { color: var(--color-white); }
.final-cta__text {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(1.3rem, 2vw, 1.8rem);
  color: rgba(255, 255, 255, .92);
  margin-block: 22px 40px;
}

.final-cta .btn--primary {
  background: var(--color-white);
  color: var(--color-fuchsia);
}
.final-cta .btn--primary:hover, .final-cta .btn--primary:focus-visible {
  background: var(--color-ink);
  color: var(--color-white);
}
/* domyślny :focus-visible (fuksjowy outline) byłby niewidoczny na fuksjowym
   tle tej sekcji — biały outline zamiast tego, tylko tutaj */
.final-cta :focus-visible { outline-color: var(--color-white); }

.final-cta__row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}
@media (min-width: 480px) { .final-cta__row { flex-direction: row; justify-content: center; gap: 32px; } }

.final-cta__secondary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  color: rgba(255, 255, 255, .85);
  transition: color .18s var(--ease);
}
.final-cta__secondary svg { width: 16px; height: 16px; transition: transform .18s var(--ease); }
.final-cta__secondary:hover, .final-cta__secondary:focus-visible { color: var(--color-white); text-decoration: underline; }
.final-cta__secondary:hover svg, .final-cta__secondary:focus-visible svg { transform: translateX(3px); }

/* =========================================================
   FOOTER (etap 17F — całkowity redesign) — poprzednia wersja (DESIGN.md
   §12.10, etap 17C) oceniona jako za ciemna/ciasna/mało czytelna.
   Nadal grafit, ale: wyższy kontrast tekstu (.7→.82 opacity na tekście
   pomocniczym), większy font, znacznie więcej przestrzeni pionowej i
   poziomej, wyraźne nagłówki kolumn z cienką linią pod spodem (nie
   tylko waga fontu), pełne logo z psem większe niż poprzedni sam
   wordmark. Wysokość celowo NIE jest minimalizowana — czytelność ważniejsza.
   ========================================================= */
/* Wysmuklone etapem 17F.6 — logo usunięte (branding jest już widoczny
   w headerze, patrz .wordmark__logo), mniejsze paddingi/odstępy/fonty
   na całej stopce. Footer ma być lekki, nie kolejna duża sekcja. */
.site-footer { background: var(--color-graphite); color: var(--color-white); padding-top: 40px; }
.site-footer__inner { padding-bottom: 28px; border-bottom: var(--border-width) solid rgba(255, 255, 255, .2); }

.site-footer__location { color: rgba(255, 255, 255, .82); font-size: .9em; font-weight: 700; margin-bottom: 6px; }
.site-footer__address { color: rgba(255, 255, 255, .82); font-size: .9em; line-height: 1.5; margin: 10px 0 8px; }
.site-footer__social { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 10px; }
.site-footer__social a { margin: 0; min-height: 36px; display: inline-flex; align-items: center; }

/* Link Booksy w stopce jako klikalny obrazek (etap 18.2) — zastępuje
   oficjalny widget Booksy (etap 18), oceniony jako wizualnie niepasujący
   do stopki. assets/booksy.png (dostarczony asset), skalowany po
   wysokości, proporcje zachowane (bez deformacji), kompaktowy rozmiar
   dopasowany do rzędu ikon social. URL bez zmian — ten sam, którego
   projekt już używa (CTA "Sprawdź usługi / umów wizytę" w groomer-teaser). */
.site-footer__booksy-link { display: inline-flex; align-items: center; min-height: 36px; }
.site-footer__booksy-link img { height: 32px; width: auto; display: block; }

/* Ikony social media (etap 17F.6A) — prawdziwe assety dostarczone w projekcie
   (assets/instagram.svg, facebook.svg, tiktok.svg, Bootstrap Icons, fill="currentColor"),
   przebarwione na kolor footeru przez CSS mask zamiast inline SVG/sprite'a.
   Mask jako base64 data-URI (dokładna, niezmieniona zawartość tych samych
   plików assets/*.svg) — url(assets/*.svg) w mask-image jest blokowane przez
   CORS przy otwarciu strony bezpośrednio z dysku (protokół file://, origin
   "null"), co czyniło ikony niewidoczne przy takim uruchomieniu (wymóg
   projektu, patrz CLAUDE.md §3). Data-URI nie ma tego problemu. */
.social-icon { display: inline-block; width: 21px; height: 21px; background-color: rgba(255, 255, 255, .82); mask-repeat: no-repeat; mask-position: center; mask-size: contain; -webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain; transition: background-color .15s ease; }
.site-footer__social a:hover .social-icon,
.site-footer__social a:focus-visible .social-icon { background-color: var(--color-white); }
.social-icon--instagram { mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktaW5zdGFncmFtIiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik04IDBDNS44MjkgMCA1LjU1Ni4wMSA0LjcwMy4wNDggMy44NS4wODggMy4yNjkuMjIyIDIuNzYuNDJhMy45IDMuOSAwIDAgMC0xLjQxNy45MjNBMy45IDMuOSAwIDAgMCAuNDIgMi43NkMuMjIyIDMuMjY4LjA4NyAzLjg1LjA0OCA0LjcuMDEgNS41NTUgMCA1LjgyNyAwIDguMDAxYzAgMi4xNzIuMDEgMi40NDQuMDQ4IDMuMjk3LjA0Ljg1Mi4xNzQgMS40MzMuMzcyIDEuOTQyLjIwNS41MjYuNDc4Ljk3Mi45MjMgMS40MTcuNDQ0LjQ0NS44OS43MTkgMS40MTYuOTIzLjUxLjE5OCAxLjA5LjMzMyAxLjk0Mi4zNzJDNS41NTUgMTUuOTkgNS44MjcgMTYgOCAxNnMyLjQ0NC0uMDEgMy4yOTgtLjA0OGMuODUxLS4wNCAxLjQzNC0uMTc0IDEuOTQzLS4zNzJhMy45IDMuOSAwIDAgMCAxLjQxNi0uOTIzYy40NDUtLjQ0NS43MTgtLjg5MS45MjMtMS40MTcuMTk3LS41MDkuMzMyLTEuMDkuMzcyLTEuOTQyQzE1Ljk5IDEwLjQ0NSAxNiAxMC4xNzMgMTYgOHMtLjAxLTIuNDQ1LS4wNDgtMy4yOTljLS4wNC0uODUxLS4xNzUtMS40MzMtLjM3Mi0xLjk0MWEzLjkgMy45IDAgMCAwLS45MjMtMS40MTdBMy45IDMuOSAwIDAgMCAxMy4yNC40MmMtLjUxLS4xOTgtMS4wOTItLjMzMy0xLjk0My0uMzcyQzEwLjQ0My4wMSAxMC4xNzIgMCA3Ljk5OCAwem0tLjcxNyAxLjQ0MmguNzE4YzIuMTM2IDAgMi4zODkuMDA3IDMuMjMyLjA0Ni43OC4wMzUgMS4yMDQuMTY2IDEuNDg2LjI3NS4zNzMuMTQ1LjY0LjMxOS45Mi41OTlzLjQ1My41NDYuNTk4LjkyYy4xMS4yODEuMjQuNzA1LjI3NSAxLjQ4NS4wMzkuODQzLjA0NyAxLjA5Ni4wNDcgMy4yMzFzLS4wMDggMi4zODktLjA0NyAzLjIzMmMtLjAzNS43OC0uMTY2IDEuMjAzLS4yNzUgMS40ODVhMi41IDIuNSAwIDAgMS0uNTk5LjkxOWMtLjI4LjI4LS41NDYuNDUzLS45Mi41OTgtLjI4LjExLS43MDQuMjQtMS40ODUuMjc2LS44NDMuMDM4LTEuMDk2LjA0Ny0zLjIzMi4wNDdzLTIuMzktLjAwOS0zLjIzMy0uMDQ3Yy0uNzgtLjAzNi0xLjIwMy0uMTY2LTEuNDg1LS4yNzZhMi41IDIuNSAwIDAgMS0uOTItLjU5OCAyLjUgMi41IDAgMCAxLS42LS45MmMtLjEwOS0uMjgxLS4yNC0uNzA1LS4yNzUtMS40ODUtLjAzOC0uODQzLS4wNDYtMS4wOTYtLjA0Ni0zLjIzM3MuMDA4LTIuMzg4LjA0Ni0zLjIzMWMuMDM2LS43OC4xNjYtMS4yMDQuMjc2LTEuNDg2LjE0NS0uMzczLjMxOS0uNjQuNTk5LS45MnMuNTQ2LS40NTMuOTItLjU5OGMuMjgyLS4xMS43MDUtLjI0IDEuNDg1LS4yNzYuNzM4LS4wMzQgMS4wMjQtLjA0NCAyLjUxNS0uMDQ1em00Ljk4OCAxLjMyOGEuOTYuOTYgMCAxIDAgMCAxLjkyLjk2Ljk2IDAgMCAwIDAtMS45Mm0tNC4yNyAxLjEyMmE0LjEwOSA0LjEwOSAwIDEgMCAwIDguMjE3IDQuMTA5IDQuMTA5IDAgMCAwIDAtOC4yMTdtMCAxLjQ0MWEyLjY2NyAyLjY2NyAwIDEgMSAwIDUuMzM0IDIuNjY3IDIuNjY3IDAgMCAxIDAtNS4zMzQiLz4KPC9zdmc+); -webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktaW5zdGFncmFtIiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik04IDBDNS44MjkgMCA1LjU1Ni4wMSA0LjcwMy4wNDggMy44NS4wODggMy4yNjkuMjIyIDIuNzYuNDJhMy45IDMuOSAwIDAgMC0xLjQxNy45MjNBMy45IDMuOSAwIDAgMCAuNDIgMi43NkMuMjIyIDMuMjY4LjA4NyAzLjg1LjA0OCA0LjcuMDEgNS41NTUgMCA1LjgyNyAwIDguMDAxYzAgMi4xNzIuMDEgMi40NDQuMDQ4IDMuMjk3LjA0Ljg1Mi4xNzQgMS40MzMuMzcyIDEuOTQyLjIwNS41MjYuNDc4Ljk3Mi45MjMgMS40MTcuNDQ0LjQ0NS44OS43MTkgMS40MTYuOTIzLjUxLjE5OCAxLjA5LjMzMyAxLjk0Mi4zNzJDNS41NTUgMTUuOTkgNS44MjcgMTYgOCAxNnMyLjQ0NC0uMDEgMy4yOTgtLjA0OGMuODUxLS4wNCAxLjQzNC0uMTc0IDEuOTQzLS4zNzJhMy45IDMuOSAwIDAgMCAxLjQxNi0uOTIzYy40NDUtLjQ0NS43MTgtLjg5MS45MjMtMS40MTcuMTk3LS41MDkuMzMyLTEuMDkuMzcyLTEuOTQyQzE1Ljk5IDEwLjQ0NSAxNiAxMC4xNzMgMTYgOHMtLjAxLTIuNDQ1LS4wNDgtMy4yOTljLS4wNC0uODUxLS4xNzUtMS40MzMtLjM3Mi0xLjk0MWEzLjkgMy45IDAgMCAwLS45MjMtMS40MTdBMy45IDMuOSAwIDAgMCAxMy4yNC40MmMtLjUxLS4xOTgtMS4wOTItLjMzMy0xLjk0My0uMzcyQzEwLjQ0My4wMSAxMC4xNzIgMCA3Ljk5OCAwem0tLjcxNyAxLjQ0MmguNzE4YzIuMTM2IDAgMi4zODkuMDA3IDMuMjMyLjA0Ni43OC4wMzUgMS4yMDQuMTY2IDEuNDg2LjI3NS4zNzMuMTQ1LjY0LjMxOS45Mi41OTlzLjQ1My41NDYuNTk4LjkyYy4xMS4yODEuMjQuNzA1LjI3NSAxLjQ4NS4wMzkuODQzLjA0NyAxLjA5Ni4wNDcgMy4yMzFzLS4wMDggMi4zODktLjA0NyAzLjIzMmMtLjAzNS43OC0uMTY2IDEuMjAzLS4yNzUgMS40ODVhMi41IDIuNSAwIDAgMS0uNTk5LjkxOWMtLjI4LjI4LS41NDYuNDUzLS45Mi41OTgtLjI4LjExLS43MDQuMjQtMS40ODUuMjc2LS44NDMuMDM4LTEuMDk2LjA0Ny0zLjIzMi4wNDdzLTIuMzktLjAwOS0zLjIzMy0uMDQ3Yy0uNzgtLjAzNi0xLjIwMy0uMTY2LTEuNDg1LS4yNzZhMi41IDIuNSAwIDAgMS0uOTItLjU5OCAyLjUgMi41IDAgMCAxLS42LS45MmMtLjEwOS0uMjgxLS4yNC0uNzA1LS4yNzUtMS40ODUtLjAzOC0uODQzLS4wNDYtMS4wOTYtLjA0Ni0zLjIzM3MuMDA4LTIuMzg4LjA0Ni0zLjIzMWMuMDM2LS43OC4xNjYtMS4yMDQuMjc2LTEuNDg2LjE0NS0uMzczLjMxOS0uNjQuNTk5LS45MnMuNTQ2LS40NTMuOTItLjU5OGMuMjgyLS4xMS43MDUtLjI0IDEuNDg1LS4yNzYuNzM4LS4wMzQgMS4wMjQtLjA0NCAyLjUxNS0uMDQ1em00Ljk4OCAxLjMyOGEuOTYuOTYgMCAxIDAgMCAxLjkyLjk2Ljk2IDAgMCAwIDAtMS45Mm0tNC4yNyAxLjEyMmE0LjEwOSA0LjEwOSAwIDEgMCAwIDguMjE3IDQuMTA5IDQuMTA5IDAgMCAwIDAtOC4yMTdtMCAxLjQ0MWEyLjY2NyAyLjY2NyAwIDEgMSAwIDUuMzM0IDIuNjY3IDIuNjY3IDAgMCAxIDAtNS4zMzQiLz4KPC9zdmc+); }
.social-icon--facebook { mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktZmFjZWJvb2siIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTE2IDguMDQ5YzAtNC40NDYtMy41ODItOC4wNS04LTguMDVDMy41OCAwLS4wMDIgMy42MDMtLjAwMiA4LjA1YzAgNC4wMTcgMi45MjYgNy4zNDcgNi43NSA3Ljk1MXYtNS42MjVoLTIuMDNWOC4wNUg2Ljc1VjYuMjc1YzAtMi4wMTcgMS4xOTUtMy4xMzEgMy4wMjItMy4xMzEuODc2IDAgMS43OTEuMTU3IDEuNzkxLjE1N3YxLjk4aC0xLjAwOWMtLjk5MyAwLTEuMzAzLjYyMS0xLjMwMyAxLjI1OHYxLjUxaDIuMjE4bC0uMzU0IDIuMzI2SDkuMjVWMTZjMy44MjQtLjYwNCA2Ljc1LTMuOTM0IDYuNzUtNy45NTEiLz4KPC9zdmc+); -webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktZmFjZWJvb2siIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPHBhdGggZD0iTTE2IDguMDQ5YzAtNC40NDYtMy41ODItOC4wNS04LTguMDVDMy41OCAwLS4wMDIgMy42MDMtLjAwMiA4LjA1YzAgNC4wMTcgMi45MjYgNy4zNDcgNi43NSA3Ljk1MXYtNS42MjVoLTIuMDNWOC4wNUg2Ljc1VjYuMjc1YzAtMi4wMTcgMS4xOTUtMy4xMzEgMy4wMjItMy4xMzEuODc2IDAgMS43OTEuMTU3IDEuNzkxLjE1N3YxLjk4aC0xLjAwOWMtLjk5MyAwLTEuMzAzLjYyMS0xLjMwMyAxLjI1OHYxLjUxaDIuMjE4bC0uMzU0IDIuMzI2SDkuMjVWMTZjMy44MjQtLjYwNCA2Ljc1LTMuOTM0IDYuNzUtNy45NTEiLz4KPC9zdmc+); }
.social-icon--tiktok { mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktdGlrdG9rIiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik05IDBoMS45OGMuMTQ0LjcxNS41NCAxLjYxNyAxLjIzNSAyLjUxMkMxMi44OTUgMy4zODkgMTMuNzk3IDQgMTUgNHYyYy0xLjc1MyAwLTMuMDctLjgxNC00LTEuODI5VjExYTUgNSAwIDEgMS01LTV2MmEzIDMgMCAxIDAgMyAzeiIvPgo8L3N2Zz4=); -webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iY3VycmVudENvbG9yIiBjbGFzcz0iYmkgYmktdGlrdG9rIiB2aWV3Qm94PSIwIDAgMTYgMTYiPgogIDxwYXRoIGQ9Ik05IDBoMS45OGMuMTQ0LjcxNS41NCAxLjYxNyAxLjIzNSAyLjUxMkMxMi44OTUgMy4zODkgMTMuNzk3IDQgMTUgNHYyYy0xLjc1MyAwLTMuMDctLjgxNC00LTEuODI5VjExYTUgNSAwIDEgMS01LTV2MmEzIDMgMCAxIDAgMyAzeiIvPgo8L3N2Zz4=); }

/* Wiersz kontaktowy z małą ikoną (etap 17F.5, zagęszczone 17F.6) */
.site-footer__contact-row { display: flex; align-items: center; gap: 9px; color: rgba(255, 255, 255, .85); font-size: .92em; font-weight: 600; margin: 0 0 8px; min-height: 0; line-height: 1.3; }
.site-footer__contact-row span { min-width: 0; }
.site-footer__contact-icon { width: 15px; height: 15px; flex-shrink: 0; color: var(--color-orange); }
a.site-footer__contact-row { width: fit-content; }

.site-footer__col h3 {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-white);
  padding-bottom: 8px;
  margin-bottom: 10px;
  border-bottom: var(--border-width) solid rgba(255, 255, 255, .22);
}
.site-footer__col p { color: rgba(255, 255, 255, .82); font-size: .92em; }

.site-footer__col a {
  display: flex;
  align-items: center;
  width: fit-content;
  min-height: 36px;
  color: rgba(255, 255, 255, .9);
  font-size: .96em;
  font-weight: 600;
  margin: 0 0 -4px -2px;
  padding: 0 2px;
  border-bottom: var(--border-width) solid transparent;
  transition: color .15s var(--ease), border-color .15s var(--ease);
}
.site-footer__col a:hover, .site-footer__col a:focus-visible {
  color: var(--color-white);
  border-color: var(--color-fuchsia);
}
.site-footer__col a.site-footer__contact-row:hover, .site-footer__col a.site-footer__contact-row:focus-visible { border-color: transparent; text-decoration: underline; }

.site-footer__bottom { padding-block: 16px; font-size: 12px; color: rgba(255, 255, 255, .65); }

/* 3 RÓWNOWAŻNE kolumny — ta sama szerokość dla wszystkich trzech,
   odstępy zmniejszone etapem 17F.6. */
.site-footer__columns { display: grid; gap: 28px; }
@media (min-width: 768px) { .site-footer__columns { grid-template-columns: repeat(3, 1fr); gap: 28px; } }
@media (min-width: 1024px) { .site-footer__columns { gap: 40px; } }

/* =========================================================
   /ZAPISZ-SIĘ — formularz zgłoszeniowy (etap 15, DESIGN.md §13)
   Editorialowa kontynuacja homepage: krótki hero (skala H2, bez
   zdjęcia), formularz jako biała, uniesiona karta na jasnym tle,
   pola pogrupowane w 4 fieldsety. Token --color-error zdefiniowany
   w głównym :root na górze pliku.
   ========================================================= */
.apply-hero { background: var(--color-bg); padding-top: 56px; padding-bottom: var(--section-space-mobile); }
@media (min-width: 768px) { .apply-hero { padding-bottom: var(--section-space-tablet); } }
.apply-hero__inner { max-width: var(--container-text); }
.apply-hero__heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -.01em;
  color: var(--color-ink);
  margin-block: 16px 20px;
}
.apply-hero__text { font-size: var(--fs-lead); line-height: 1.55; color: var(--color-text); max-width: 56ch; }

/* Krótka linia lokalizacji pod leadem hero /szkolenia/ (etap 18) —
   zapisz-sie/co-wybrac nie mają tego elementu, klasa tam nieużywana. */
.apply-hero__meta { font-size: .88em; font-weight: 700; color: var(--color-muted); margin-top: 14px; }

/* Hero /szkolenia/ ze zdjęciem (etap 18.4) — grid-template-areas
   zamiast .subpage-hero (klasy/obrona), bo tu zdjęcie ma zajmować
   ok. 40-48% (nie 50/50) I kolejność mobile musi wstawić zdjęcie
   MIĘDZY tekst a CTA, nie tylko obok tekstu — stąd CTA jako osobny
   obszar grida, nie część .szkolenia-hero__copy. Nietknięte .apply-hero
   i .apply-hero__inner zostają używane bez zmian przez /zapisz-sie/. */
.szkolenia-hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "copy" "photo" "actions";
  gap: 28px;
  align-items: center;
}
.szkolenia-hero__copy { grid-area: copy; }
.szkolenia-hero__photo {
  grid-area: photo;
  margin: 0;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-elevated);
}
.szkolenia-hero__photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; display: block; }
.szkolenia-hero__actions { grid-area: actions; margin-top: 0; }

@media (min-width: 1024px) {
  .szkolenia-hero__grid {
    grid-template-columns: 1.25fr 1fr;
    grid-template-areas: "copy photo" "actions photo";
    gap: 56px;
  }
}

/* /szkolenia/ placeholder (etap 17F.6A) — dwa CTA pod krótkim tekstem,
   reużywa istniejący .btn i prosty wzorzec tekstowego linku ze strzałką
   już użyty gdzie indziej (np. .groomer-teaser__link). */
.apply-hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 24px; margin-top: 32px; }
.apply-hero__link { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; color: var(--color-ink); border-bottom: var(--border-width) solid var(--color-ink); transition: color .15s var(--ease); }
.apply-hero__link svg { width: 18px; height: 18px; transition: transform .18s var(--ease); }
.apply-hero__link:hover, .apply-hero__link:focus-visible { color: var(--color-fuchsia); border-color: var(--color-fuchsia); }
.apply-hero__link:hover svg, .apply-hero__link:focus-visible svg { transform: translateX(3px); }

.apply-form-section { background: var(--color-bg); padding-top: 0; padding-bottom: var(--section-space-mobile); }
@media (min-width: 768px) { .apply-form-section { padding-bottom: var(--section-space-tablet); } }
@media (min-width: 1024px) { .apply-form-section { padding-bottom: var(--section-space-desktop); } }
.apply-form-section__inner { max-width: 760px; }

/* Podsumowanie wyboru z /cennik-szkolen (etap 24) — lekki, jasny box nad
   formularzem (nie kolejna pełna .form-owa karta), fuksjowy tint spina
   wizualnie z .price-option/.pricing-summary na samym cenniku. */
.pricing-recap { background: var(--color-fuchsia-soft); border-radius: var(--radius-sm); padding: 20px 24px; margin-bottom: 24px; }
.pricing-recap .eyebrow { margin-bottom: 6px; }
.pricing-recap__variant { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.15rem, 2vw, 1.4rem); color: var(--color-ink); margin-bottom: 6px; }
.pricing-recap__addon { font-size: .92em; color: var(--color-text); margin-bottom: 4px; }
.pricing-recap__total { margin-bottom: 10px; }
.pricing-recap__total strong { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.25rem, 2.2vw, 1.55rem); color: var(--color-fuchsia); }
.pricing-recap__note { font-size: .88em; color: var(--color-text); }

.form, .quiz-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-elevated);
  padding: 28px 20px;
}
@media (min-width: 640px) { .form, .quiz-card { padding: 40px; } }
@media (min-width: 1024px) { .form, .quiz-card { padding: 56px; } }
/* formularz kontaktowy w /co-wybrac żyje już wewnątrz .quiz-card —
   zdejmujemy własny card-chrome .form, żeby nie powielać karty w karcie;
   stylowanie pól (.form input itd.) działa dalej przez selektory potomne */
.quiz-card .form { background: none; border: none; box-shadow: none; padding: 0; }

/* honeypot antyspamowy (etap 17) — niewidoczny dla ludzi i czytników
   ekranu (aria-hidden na wrapperze, poza kolejnością Tab), ale obecny w
   DOM, więc naiwne boty wciąż go wypełniają */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form__summary {
  background: var(--color-error);
  color: var(--color-white);
  font-weight: 700;
  font-size: 14px;
  line-height: 1.4;
  padding: 14px 18px;
  border-radius: var(--radius-sm);
  margin-bottom: 28px;
}

fieldset { border: none; margin: 0; padding: 0; min-width: 0; }
legend { padding: 0; }

.form__group { margin-bottom: 40px; }
/* BETA: "MOJE DANE" (20.09.2026) - blok "Zmień hasło" pod formularzem profilu. */
.profile-password-block { margin-top: 40px; }
.profile-password-note { margin-top: 12px; font-size: .92em; color: var(--color-muted); }
.form__legend {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--color-ink);
  margin-bottom: 20px;
  padding-bottom: 12px;
  border-bottom: var(--border-width) solid var(--color-line);
  width: 100%;
}

.field { display: flex; flex-direction: column; gap: 8px; margin-bottom: 22px; }
/* etap 17C: pola warunkowe (#f-duration-wrap, #f-previous-work-wrap) łączą
   class="field" z atrybutem [hidden] — bez tego override .field { display:
   flex } (reguła autorska) wygrywa z domyślną regułą UA [hidden]{display:
   none}, bo reguły autorskie zawsze biją UA niezależnie od specyficzności.
   Ten sam wzorzec błędu co .field__error[hidden] wyżej w pliku (etap 15). */
.field[hidden] { display: none; }
.field:last-child { margin-bottom: 0; }
.field > label, .field > legend {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  color: var(--color-ink);
}
.field__optional { font-weight: 500; color: var(--color-muted); }

.field-row { display: grid; gap: 20px; margin-bottom: 22px; }
.field-row .field { margin-bottom: 0; }
@media (min-width: 640px) { .field-row { grid-template-columns: 1fr 1fr; } }

/* Etap 9E.4 §16/§17/§18/§19 polecenia - GLOBAL FORM POLISH. Panel pages
   (cele/psy/dyspozycyjność/notatki/ustaw-hasło i in.) w większości NIE
   opakowują swoich pól w klasę `.form` (używają wyłącznie `.field` jako
   wrappera na pojedyncze pole) - dlatego runtime pokazał "zbyt kanciaste"
   pola: input/textarea/select bez `.form` w drzewie spadały na goły,
   nieostylowany wygląd przeglądarki. Selektor rozszerzony o `.field` jako
   RÓWNORZĘDNY kontekst (nie zamiennik) - te same miękkie zaokrąglenia
   (--radius-sm, 14px - już w duchu poleconych 14-18px) i wygląd wszędzie,
   bez zmiany istniejącego layoutu/rozmiarów tam, gdzie `.form` już działało. */
.form input[type="text"],
.form input[type="tel"],
.form input[type="email"],
.form input[type="time"],
.form input[type="password"],
.form input[type="date"],
.form select,
.form textarea,
.field input[type="text"],
.field input[type="tel"],
.field input[type="email"],
.field input[type="time"],
.field input[type="password"],
.field input[type="date"],
.field select,
.field textarea,
input.panel-control[type="text"],
input.panel-control[type="tel"],
input.panel-control[type="email"],
input.panel-control[type="time"],
input.panel-control[type="password"],
input.panel-control[type="date"],
select.panel-control,
textarea.panel-control {
  min-height: 48px;
  padding: 12px 16px;
  background: var(--color-surface);
  color: var(--color-ink);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: 16px;
  width: 100%;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.form textarea, .field textarea, textarea.panel-control { min-height: 120px; padding-top: 14px; resize: vertical; }
.form select, .field select, select.panel-control {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6' fill='none' stroke='%23222126' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 18px;
  padding-right: 44px;
}
.form input::placeholder, .form textarea::placeholder,
.field input::placeholder, .field textarea::placeholder,
input.panel-control::placeholder, textarea.panel-control::placeholder { color: var(--color-muted); opacity: 1; }

.form input:focus-visible,
.form select:focus-visible,
.form textarea:focus-visible,
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible,
input.panel-control:focus-visible,
select.panel-control:focus-visible,
textarea.panel-control:focus-visible {
  outline: none;
  border-color: var(--color-fuchsia);
  box-shadow: 0 0 0 4px var(--color-fuchsia-soft);
}

.radio-group { display: flex; flex-direction: column; gap: 4px; }
.radio-group--inline { flex-direction: row; flex-wrap: wrap; gap: 8px 28px; }

.radio-option {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  color: var(--color-text);
  cursor: pointer;
}
.radio-option input[type="radio"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--color-fuchsia);
}
.radio-option input[type="radio"]:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }

.field--invalid input[type="text"],
.field--invalid input[type="tel"],
.field--invalid input[type="email"],
.field--invalid input[type="time"],
.field--invalid select,
.field--invalid textarea {
  border-color: var(--color-error);
}

.field__error {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--color-error);
  font-size: 13px;
  font-weight: 600;
}
.field__error[hidden] { display: none; }
.field__error-icon { width: 16px; height: 16px; flex-shrink: 0; }

.apply-form__note { font-size: 14px; line-height: 1.5; color: var(--color-muted); margin-bottom: 24px; }
.apply-form__privacy { font-size: 13px; line-height: 1.5; color: var(--color-muted); margin: -12px 0 24px; }

.apply-form__submit { width: 100%; justify-content: center; }
@media (min-width: 480px) { .apply-form__submit { width: auto; } }

.apply-success {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-elevated);
  padding: 48px 28px;
  text-align: center;
}
.apply-success h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  color: var(--color-ink);
  margin-bottom: 12px;
}
.apply-success p { color: var(--color-text); font-size: 1.05rem; max-width: 46ch; margin-inline: auto; }

/* ETAP: WYDARZENIA NA WWW + PUBLICZNE ZAPISY (17.09.2026, §E polecenia) -
   podsumowanie wydarzenia u góry `/zapis-na-wydarzenie/`, nad formularzem.
   PATCH: UX WYDARZEŃ (18.09.2026, §D ticketu) - dostała TĘ SAMĄ elewację
   (box-shadow + responsywny padding) co `.form` niżej na tej samej stronie -
   wcześniej płaska karta (sam border, bez cienia) wyglądała jak "wklejony
   klocek" obok właściwie uniesionego formularza; teraz oba elementy mają
   spójny, "premium" ciężar wizualny. */
.event-summary {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-elevated);
  padding: 28px 24px;
  margin-bottom: 32px;
}
@media (min-width: 640px) { .event-summary { padding: 32px; } }
.event-summary__type { font-family: var(--font-body); font-weight: 800; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-fuchsia); margin-bottom: 6px; }
.event-summary__title { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.3rem, 2.4vw, 1.7rem); color: var(--color-ink); margin-bottom: 10px; }
.event-summary__row { font-size: .98em; color: var(--color-text); line-height: 1.6; }
.event-summary__price { font-weight: 700; color: var(--color-ink); }
.event-summary__price-discount { font-weight: 700; color: var(--color-fuchsia); font-size: .92em; }
/* "Chcę wiedzieć więcej" (§D ticketu) - dyskretny, ale czytelny przycisk
   blisko podsumowania (WEWNĄTRZ tej samej karty, nie na dole strony). */
.event-summary__more { margin-top: 18px; }

/* =========================================================
   /CO-WYBRAC — krótka ścieżka decyzyjna (etap 16)
   Jeden krok na ekran, karta w stylu /zapisz-sie (.quiz-card dzieli
   card-chrome z .form, patrz wyżej). Odpowiedzi jako duże karty radio
   (.answer-card) — prawdziwe kontrolki formularza, nie div-y.
   ========================================================= */
.quiz-hero { background: var(--color-bg); padding-top: 56px; padding-bottom: 40px; }
.quiz-hero__inner { max-width: var(--container-text); }
.quiz-hero__heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -.01em;
  color: var(--color-ink);
  margin-block: 16px 20px;
}
.quiz-hero__text { font-size: var(--fs-lead); line-height: 1.55; color: var(--color-text); max-width: 56ch; }
.quiz-hero__note { margin-top: 10px; font-size: 14px; color: var(--color-muted); max-width: 56ch; }

.quiz-section { background: var(--color-bg); padding-top: 0; padding-bottom: var(--section-space-mobile); }
@media (min-width: 768px) { .quiz-section { padding-bottom: var(--section-space-tablet); } }
@media (min-width: 1024px) { .quiz-section { padding-bottom: var(--section-space-desktop); } }
.quiz-section__inner { max-width: 760px; }

.quiz-noscript { background: var(--color-surface-alt); border-radius: var(--radius-sm); padding: 16px 20px; margin-bottom: 24px; font-size: 14px; color: var(--color-text); }
.quiz-noscript a { font-weight: 700; color: var(--color-ink); text-decoration: underline; }

.quiz-progress {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 24px;
  min-height: 1em;
}

/* nadpisanie globalnego "section { padding-block: var(--section-pad) }"
   — kroki quizu to zagnieżdżone stany UI wewnątrz .quiz-card, nie
   sekcje strony, więc nie mają dostawać sekcyjnego odstępu */
.quiz-step { padding-block: 0; }

.quiz-step__question {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1.15;
  color: var(--color-ink);
}

.answer-list { display: flex; flex-direction: column; gap: 12px; margin-top: 24px; }
.answer-card {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  background: var(--color-surface-alt);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.answer-card:hover { border-color: var(--color-fuchsia); background: var(--color-surface); }
.answer-card:has(input:checked) { border-color: var(--color-fuchsia); background: var(--color-fuchsia-soft); }
.answer-card input[type="radio"] {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-top: 2px;
  accent-color: var(--color-fuchsia);
}
.answer-card input[type="radio"]:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
.answer-card__body { display: flex; flex-direction: column; gap: 4px; }
.answer-card__title { font-family: var(--font-body); font-weight: 700; font-size: 16px; color: var(--color-ink); line-height: 1.35; }
.answer-card__desc { font-size: 14px; color: var(--color-text); line-height: 1.45; }

.quiz-nav { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; margin-top: 28px; }
.quiz-nav__back {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  color: var(--color-muted);
}
.quiz-nav__back:hover, .quiz-nav__back:focus-visible { color: var(--color-ink); }

.quiz-result__heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.8rem, 3.2vw, 2.6rem);
  color: var(--color-ink);
  margin-block: 6px 16px;
}
.quiz-result__text { font-size: 1.05rem; line-height: 1.55; color: var(--color-text); max-width: 60ch; margin-bottom: 16px; }
.quiz-result__disclaimer { font-size: 13px; color: var(--color-muted); max-width: 60ch; margin-bottom: 20px; }
.quiz-result__change { margin-bottom: 4px; }

.quiz-decision { margin-top: 32px; padding-top: 28px; border-top: var(--border-width) solid var(--color-line); }
.quiz-decision__question {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.1rem, 1.8vw, 1.4rem);
  color: var(--color-ink);
  margin-bottom: 8px;
}
.quiz-decision__note { font-size: 14px; line-height: 1.5; color: var(--color-muted); margin-bottom: 20px; max-width: 56ch; }
.quiz-decision__row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; }
.quiz-decision__no {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  color: var(--color-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.quiz-decision__no:hover, .quiz-decision__no:focus-visible { color: var(--color-ink); }

.quiz-declined { margin-top: 32px; padding-top: 28px; border-top: var(--border-width) solid var(--color-line); }
.quiz-declined p { color: var(--color-text); margin-bottom: 14px; }
.quiz-declined__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-weight: 700;
  color: var(--color-ink);
}
.quiz-declined__link svg { width: 16px; height: 16px; transition: transform .18s var(--ease); }
.quiz-declined__link:hover, .quiz-declined__link:focus-visible { color: var(--color-fuchsia); }
.quiz-declined__link:hover svg, .quiz-declined__link:focus-visible svg { transform: translateX(3px); }

.quiz-success h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  color: var(--color-ink);
  margin-bottom: 12px;
}
.quiz-success p { color: var(--color-text); font-size: 1.05rem; max-width: 52ch; }

/* =========================================================
   /CENNIK-SZKOLEN — premium redesign (etap 26)
   Wyłącznie warstwa wizualna/layout - JS (script.js, blok
   "/CENNIK-SZKOLEN") NIETKNIĘTY, wszystkie ID/klasy poniżej istnieją
   dokładnie tam, gdzie JS ich szuka. Kierunek: dużo bieli, cienkie
   obrysy zamiast wypełnień --color-surface-alt (dawny "szary na
   szarym"), fuksja jako jedyny mocny akcent, premium przez typografię/
   proporcje/światło, nie przez nowe kolory czy ciężkie cienie. Zdjęcia
   (assets/cennik/) użyte 1:1, bez modyfikacji.
   ========================================================= */

/* HERO — ≥768px (tablet+desktop) ZAMROŻONY od etapu 34/35/36/37
   (polecenie: "nie zmieniaj ani jednej reguły wizualnej"). .pricing-
   hero__photo (background z etapu 30, oparty na cennik-hero-dog-mobile
   .webp/-desktop.webp) i jego reguły @media (min-width:768px)/
   (min-width:1024px) niżej są bit-w-bit takie same jak przed etapem 37.
   Telefon (≤767px) — etap 37, PIĄTA i ostateczna zmiana koncepcji:
   etap 36 (CSS-owe kadrowanie samego cennik-hero.jpg) matematycznie
   potwierdził, że przy tym zdjęciu oko psa zawsze zaczyna się przed
   końcem 62%-owej kolumny tekstu, niezależnie od doboru background-
   size - dlatego zamiast dalszego dobierania CSS, powstał DEDYKOWANY,
   raz wygenerowany asset assets/cennik/cennik-hero-mobile-final.webp
   (860×1200, programowo skomponowany z tego samego, niezmienionego
   cennik-hero.jpg - pies dosunięty w prawo + naturalne tło stopione w
   jedną kompozycję przez piórkowanie (feather) lewej/górnej/dolnej
   krawędzi, tło canvasa próbkowanym kolorem #F8F3EF). Bezpieczna strefa
   dla tekstu (0-500px z 860 bez sierści/oka/nosa/ucha, zweryfikowana
   programowo na gotowym pliku) jest już zaszyta w SAMYM assetcie -
   CSS wyłącznie go pokazuje: `background-image` wprost na .pricing-hero
   (nie .pricing-hero__photo - ten div zostaje wyłącznie mechanizmem
   ≥768px, nietkniętym), `background-size:100% auto` (skalowanie po
   szerokości, zero dodatkowego CSS-owego kadrowania/pozycjonowania).
   Nad zdjęciem: .pricing-hero::before (biała/kremowa mgła, ten sam
   sampled kolor) i .pricing-hero::after (wąska strefa backdrop-filter
   :blur, zamaskowana gradientową maską po obu krawędziach - kończy się
   bezpiecznie przed sierścią/okiem). Tekst (.pricing-hero__inner) ma
   z-index wyższy niż obie warstwy. Reguły @media (max-width:767px)
   niżej są jedynym miejscem definiującym ten mechanizm. */
.pricing-hero { position: relative; overflow: hidden; isolation: isolate; min-height: 540px; display: flex; align-items: center; background: var(--color-bg); }
.pricing-hero__photo { display: none; }

.pricing-hero__inner { position: relative; z-index: 2; width: 100%; padding-block: 32px; }
.pricing-hero__heading-col { margin-bottom: 16px; }
.pricing-hero__heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 6.4vw, 2rem);
  line-height: 1.08;
  letter-spacing: -.01em;
  color: var(--color-ink);
  margin-block: 8px 0;
}
.pricing-hero__text { font-size: .88rem; line-height: 1.48; color: var(--color-text); }
.pricing-hero__text + .pricing-hero__text { margin-top: 8px; }

@media (min-width: 480px) {
  .pricing-hero__heading { font-size: clamp(1.9rem, 6vw, 2.3rem); }
  .pricing-hero__text { font-size: .95rem; }
}

/* Telefon (≤767px), etap 38 — cofnięcie koncepcji "safe zone" z etapu
   37 (wymusiła zbyt małego psa, ocenione jako wyglądające jak doklejony
   fragment). Powrót do oryginalnego assets/cennik/cennik-hero.jpg jako
   prawdziwego background-image CAŁEGO .pricing-hero, tym razem z
   background-size:cover (dozwolony kontrolowany crop tułowia/boku/tła,
   NIE oczu/nosa/pyska/uszu) - pies renderuje się znacznie większy.
   Mgła (::before) MOŻE teraz zachodzić na sierść (jawnie dozwolone) -
   zapewnia kontrast tekstu bez wymogu czystego "pustego" pasa pod nim.
   Blur (::after) to wąska, zamaskowana na obu krawędziach strefa
   ustawiona tak, by nie dotykać oka/pyska. */
@media (max-width: 767px) {
  .pricing-hero {
    min-height: 460px;
    background-color: #F8F3EF;
    background-image: url("assets/cennik/cennik-hero.jpg");
    background-repeat: no-repeat;
    background-position: 78% center;
    background-size: cover;
  }
  .pricing-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(
      90deg,
      rgba(248, 243, 239, .97) 0%,
      rgba(248, 243, 239, .93) 28%,
      rgba(248, 243, 239, .8) 43%,
      rgba(248, 243, 239, .48) 54%,
      rgba(248, 243, 239, .22) 63%,
      rgba(248, 243, 239, .06) 72%,
      rgba(248, 243, 239, 0) 80%
    );
  }
  .pricing-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    left: 53%;
    width: 18%;
    z-index: 1;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 35%, black 65%, transparent 100%);
    mask-image: linear-gradient(to right, transparent 0%, black 35%, black 65%, transparent 100%);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
  }
  .pricing-hero__inner { max-width: 62%; margin-inline: 0; }
}

@media (min-width: 768px) {
  .pricing-hero { min-height: 520px; }
  .pricing-hero__photo {
    display: block;
    position: absolute;
    right: 0;
    bottom: 0;
    height: 100%;
    width: 42%;
    z-index: 0;
    pointer-events: none;
    background-image: url("assets/cennik/cennik-hero-dog-mobile.webp");
    background-repeat: no-repeat;
    background-position: right bottom;
    background-size: contain;
  }
  .pricing-hero__inner { padding-block: 40px; }
  .pricing-hero__grid { max-width: 54%; }
  .pricing-hero__heading { font-size: clamp(2.1rem, 4.4vw, 2.5rem); }
  .pricing-hero__text { font-size: 1rem; }
}

/* Desktop od 1024px — prawdziwy grid 52%/48% WEWNĄTRZ strefy tekstowej
   (H1 po lewej, lead bardziej z boku/środka, nie pod H1), pies jako
   niezależna warstwa tła po prawej, poza tym gridem - patrz sekcja 3/5
   polecenia. Od tej szerokości używamy kadru desktopowego (więcej
   widocznego tułowia/kontekstu, nie tylko blisko twarzy). */
@media (min-width: 1024px) {
  .pricing-hero { min-height: 560px; }
  .pricing-hero__inner { padding-block: 0; }
  .pricing-hero__photo {
    /* Desktop (zaakceptowany, etap 30) ma WŁASNY, pełny mechanizm
       pozycjonowania niezależny od reguły bazowej mobile/tablet z
       etapu 32 (bottom:0/height:100%/contain) - stąd jawny reset
       top/transform/bottom/height/background-size tutaj, żeby zmiana
       reguły bazowej dla mobile nie zepsuła tego, co tu już działa. */
    top: 50%;
    bottom: auto;
    height: auto;
    transform: translateY(-50%);
    width: 40%;
    aspect-ratio: 1000 / 1023;
    background-image:
      linear-gradient(90deg, var(--color-bg) 0%, rgba(241, 241, 243, 0) 32%),
      linear-gradient(180deg, var(--color-bg) 0%, rgba(241, 241, 243, 0) 18%, rgba(241, 241, 243, 0) 82%, var(--color-bg) 100%),
      url("assets/cennik/cennik-hero-dog-desktop.webp");
    background-repeat: no-repeat, no-repeat, no-repeat;
    background-position: center, center, center;
    background-size: 100% 100%, 100% 100%, cover;
  }
  .pricing-hero__grid {
    max-width: 58%;
    display: grid;
    grid-template-columns: 52% 48%;
    column-gap: 24px;
    align-items: center;
  }
  .pricing-hero__heading-col { margin-bottom: 0; }
  .pricing-hero__heading { font-size: var(--fs-h2); margin-block: 14px 0; }
  .pricing-hero__lead-col { max-width: 300px; }
  .pricing-hero__text { font-size: .95rem; line-height: 1.55; }
  .pricing-hero__text + .pricing-hero__text { margin-top: 12px; }
}
@media (min-width: 1280px) {
  .pricing-hero { min-height: 600px; }
  .pricing-hero__photo { width: 38%; }
  .pricing-hero__grid { max-width: 60%; }
  .pricing-hero__lead-col { max-width: 340px; }
  .pricing-hero__text { font-size: var(--fs-lead); }
}

.pricing-section { background: var(--color-surface); padding-top: var(--section-space-mobile); padding-bottom: var(--section-space-mobile); }
@media (min-width: 768px) { .pricing-section { padding-top: var(--section-space-tablet); padding-bottom: var(--section-space-tablet); } }
@media (min-width: 1024px) { .pricing-section { padding-top: var(--section-space-desktop); padding-bottom: var(--section-space-desktop); } }
.pricing-section__inner { max-width: 960px; }

/* Wprowadzenie przed wyborem formy pracy (etap 28) — zwykły tekst
   zgodny z typografią homepage (ten sam przepis co .work__lead), nie
   nagłówek/alert/box. */
.pricing-choices__intro { font-size: var(--fs-lead); line-height: 1.55; color: var(--color-text); margin-bottom: 24px; }

/* KROK 1 — trzy duże, numerowane karty (jak .work-tile na homepage:
   num + tytuł + opis), zamiast klasycznego widocznego radia. Input
   zostaje prawdziwym, dostępnym radiem (klawiatura, focus-visible),
   tylko wizualnie ukryty - stan aktywny idzie przez :has(input:checked)
   na całej karcie, czytelny bez hovera. */
.pricing-choices { display: grid; gap: 20px; margin-top: 8px; }
@media (min-width: 1024px) { .pricing-choices { grid-template-columns: repeat(3, 1fr); gap: 24px; } }

.pricing-choice {
  position: relative;
  display: block;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 32px 28px;
  cursor: pointer;
  transition: border-color .18s var(--ease), background-color .18s var(--ease), box-shadow .18s var(--ease);
}
.pricing-choice:hover { border-color: var(--color-fuchsia); }
.pricing-choice:has(input:checked) { border-color: var(--color-fuchsia); background: var(--color-fuchsia-soft); box-shadow: 0 14px 34px rgba(213, 45, 139, .10); }
.pricing-choice:has(input:focus-visible) { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
.pricing-choice input[type="radio"] { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.pricing-choice__num {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.2rem, 3.5vw, 3rem);
  color: var(--color-line);
  line-height: 1;
  margin-bottom: 18px;
  transition: color .18s var(--ease);
}
.pricing-choice:has(input:checked) .pricing-choice__num { color: var(--color-fuchsia); }
.pricing-choice__title { display: block; font-family: var(--font-display); font-weight: 600; font-size: clamp(1.3rem, 2vw, 1.6rem); color: var(--color-ink); margin-bottom: 10px; }
.pricing-choice__desc { display: block; font-size: .92em; line-height: 1.5; color: var(--color-text); }

/* KROK 2 — grupy wariantów, jedna na formę pracy. Ukrywane w runtime
   przez script.js (hidden), widoczne wszystkie w bazowym HTML. */
.pricing-group { margin-top: 64px; padding-top: 44px; border-top: var(--border-width) solid var(--color-line); }
/* Zabezpieczenie jak przy .field[hidden]/.field__error[hidden] wyżej w
   tym pliku - żadna reguła tutaj nie ustawia własnego "display" na
   .pricing-group, więc [hidden] z UA stylesheet powinno wystarczyć,
   ale jawna reguła to gwarantuje niezależnie od kolejności/specyfiki
   (etap 32, stan początkowy cennika musi być ukryty w samym HTML). */
.pricing-group[hidden] { display: none; }
.pricing-group .eyebrow { margin-bottom: 10px; }
.pricing-group__heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.7rem, 2.8vw, 2.3rem);
  color: var(--color-ink);
  margin-bottom: 4px;
}

.price-options { display: grid; gap: 18px; margin-top: 28px; }
@media (min-width: 640px) { .price-options { grid-template-columns: repeat(2, 1fr); gap: 20px; } }

.price-option {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 28px 26px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color .15s var(--ease), background-color .15s var(--ease), box-shadow .15s var(--ease);
}
.price-option:hover { border-color: var(--color-fuchsia); }
.price-option:has(input:checked) { border-color: var(--color-fuchsia); background: var(--color-fuchsia-soft); box-shadow: 0 12px 30px rgba(213, 45, 139, .10); }
.price-option__row { display: flex; align-items: center; gap: 12px; }
.price-option input[type="radio"] { width: 22px; height: 22px; flex-shrink: 0; accent-color: var(--color-fuchsia); }
.price-option input[type="radio"]:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
.price-option__title { font-family: var(--font-body); font-weight: 700; font-size: 17px; color: var(--color-ink); }
.price-option__price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 12px; margin-top: 2px; }
.price-option__old { font-size: .85em; font-weight: 600; color: var(--color-muted); }
.price-option__current {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.9rem, 3.2vw, 2.5rem);
  color: var(--color-ink);
  transition: color .15s var(--ease);
}
.price-option:has(input:checked) .price-option__current { color: var(--color-fuchsia); }
/* .price-option__save (badge "Oszczędzasz X zł") usunięty etapem 31 na
   polecenie - regularPrice zostaje w PRICING (script.js) wyłącznie do
   przekreślonej ceny standardowej powyżej. */
.pricing-note { font-size: .82em; line-height: 1.5; color: var(--color-muted); }

/* KROK 3 — prowadzenie: lekkie, bezwypełnieniowe pigułki (biel + cienki
   obrys), nie ciężkie szare przyciski. */
.pricing-addon { margin-top: 64px; padding-top: 44px; border-top: var(--border-width) solid var(--color-line); }
.pricing-addon[hidden] { display: none; }
.pricing-addon .eyebrow { margin-bottom: 10px; }
.addon-options { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 24px; }
.addon-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 12px 22px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.addon-option:hover { border-color: var(--color-fuchsia); }
.addon-option:has(input:checked) { border-color: var(--color-fuchsia); background: var(--color-fuchsia-soft); }
.addon-option input[type="radio"] { width: 18px; height: 18px; flex-shrink: 0; accent-color: var(--color-fuchsia); }
.addon-option input[type="radio"]:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
.addon-option__title { font-family: var(--font-body); font-weight: 700; font-size: .95em; color: var(--color-ink); }
.addon-option__price { font-family: var(--font-body); font-weight: 700; font-size: .85em; color: var(--color-muted); }
.addon-option:has(input:checked) .addon-option__price { color: var(--color-fuchsia); }

/* Delikatny fade/slide przy odsłonięciu kroku (etap 26, §14) - ten sam
   wzorzec co .accordion__panel/faq-in, wyłączony pod reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .pricing-group:not([hidden]),
  .pricing-addon:not([hidden]),
  .pricing-summary:not([hidden]) { animation: pricing-reveal .32s var(--ease); }
  @keyframes pricing-reveal { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
}

/* PODSUMOWANIE — osobna, pełnoszeroka sekcja premium (nie wnętrze
   #pricing-config), fuksjowy tint, duża cena, dyskretna grafika
   dog-line.png w tle (nigdy nie zasłania tekstu/CTA - niski z-index,
   niska opacity, position:absolute poza obszarem treści). */
.pricing-summary { background: var(--color-fuchsia-soft); padding-block: 56px; position: relative; overflow: hidden; }
.pricing-summary[hidden] { display: none; }
@media (min-width: 768px) { .pricing-summary { padding-block: 72px; } }
@media (min-width: 1024px) { .pricing-summary { padding-block: 96px; } }
.pricing-summary__inner { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 32px; }
@media (min-width: 768px) { .pricing-summary__inner { flex-direction: row; align-items: center; justify-content: space-between; gap: 48px; } }
.pricing-summary__copy { max-width: 480px; }
.pricing-summary__variant {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.8rem, 3.2vw, 2.6rem);
  color: var(--color-ink);
  margin-block: 6px 10px;
  line-height: 1.1;
}
.pricing-summary__addon { font-size: 1.05em; color: var(--color-text); }
.pricing-summary__price { flex-shrink: 0; }
@media (min-width: 768px) { .pricing-summary__price { text-align: right; } }
.pricing-summary__total-label { font-size: .95em; font-weight: 700; color: var(--color-text); margin-bottom: 2px; }
.pricing-summary__total { margin-bottom: 22px; }
.pricing-summary__total strong { font-family: var(--font-display); font-weight: 700; font-size: clamp(2.6rem, 5.5vw, 4rem); color: var(--color-fuchsia); line-height: 1; }
.pricing-summary__actions { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
@media (min-width: 768px) { .pricing-summary__actions { align-items: flex-end; } }
.pricing-summary__link { font-family: var(--font-body); font-weight: 700; font-size: 15px; color: var(--color-muted); text-decoration: underline; text-underline-offset: 3px; }
.pricing-summary__link:hover, .pricing-summary__link:focus-visible { color: var(--color-ink); }

.pricing-summary__dog {
  position: absolute;
  right: 6px;
  bottom: 0;
  width: 100px;
  opacity: .14;
  pointer-events: none;
  z-index: 0;
}
@media (min-width: 768px) { .pricing-summary__dog { width: 160px; right: 16px; } }
@media (min-width: 1024px) { .pricing-summary__dog { width: 220px; right: 24px; } }

/* CO MASZ OPRÓCZ ZAJĘĆ — lekkie kolumny z ikonami zamiast ciężkich
   kart. 1 kolumna mobile, 2x2 tablet, 4 z cienkimi separatorami od
   1024px. */
.pricing-benefits { background: var(--color-surface); padding-block: var(--section-space-mobile); }
@media (min-width: 768px) { .pricing-benefits { padding-block: var(--section-space-tablet); } }
@media (min-width: 1024px) { .pricing-benefits { padding-block: var(--section-space-desktop); } }
.pricing-benefits__row { display: grid; gap: 36px; margin-top: 40px; }
@media (min-width: 640px) { .pricing-benefits__row { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) {
  .pricing-benefits__row { grid-template-columns: repeat(4, 1fr); gap: 0; }
  .pricing-benefit { padding-inline: 28px; border-left: var(--border-width) solid var(--color-line); }
  .pricing-benefit:first-child { border-left: none; padding-left: 0; }
}
.pricing-benefit__icon { display: block; width: 40px; height: 40px; margin-bottom: 20px; }
.pricing-benefit h3 { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.1rem, 1.6vw, 1.3rem); color: var(--color-ink); margin-bottom: 8px; }
.pricing-benefit p { font-size: .92em; line-height: 1.5; color: var(--color-text); }

/* Fallback statyczny /cennik_szkolenia/ → /cennik-szkolen/ (etap 23) -
   sama strona nie ma headera/footera (to techniczny stub przekierowania,
   nie strona treściowa), tylko krótki komunikat na wypadek, gdy meta
   refresh/.htaccess nie zadziała od razu. */
.redirect-notice { max-width: 480px; margin: 18vh auto; padding: 0 24px; text-align: center; }
.redirect-notice p { color: var(--color-text); margin-bottom: 12px; }
.redirect-notice a { font-weight: 700; color: var(--color-fuchsia); }

/* =========================================================
   Reveal + reduced motion
   ========================================================= */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(20px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
  .reveal.is-visible { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .site-nav { transition: none !important; }
}

/* =========================================================
   Panel podopiecznego (Panel MVP — etap 1, patrz PANEL_KLIENTA.md)
   Osobny, minimalny "app chrome" — nie reużywa .site-header/.site-nav
   marketingowych (te obsługują lejek sprzedażowy z pełną nawigacją do
   sekcji homepage; panel jest osobną, zalogowaną częścią systemu z inną
   listą pozycji nawigacji). Reużywa wyłącznie globalne tokeny i istniejące
   klasy komponentów (.wrap, .btn, .field, .field__error, .form__summary,
   .eyebrow, .wordmark) — zero nowych wariantów tych komponentów.
   ========================================================= */

/* Finalny redesign (patrz CLAUDE.md, "Finalne wdrożenie — panel zgodny z
   WWW") — poprzednia, ciepła kremowo-beżowa "brandowa" paleta panelu
   (etap 9D) jest COFNIĘTA. Audyt wykazał, że łamała DESIGN.md §4 (twardy
   zakaz "beżowej, kremowej... dominanty") i wprowadzała kolory marki
   (--panel-brown/--panel-sage) nigdzie w DESIGN.md niezatwierdzone. Panel
   dziś NIE nadpisuje już kolorów tokenów globalnych — dziedziczy dokładnie
   tę samą jasnoszaro-białą paletę co reszta strony (--color-bg:#F1F1F3,
   --color-surface:#FFFFFF, itd. z :root). Jedyny override, który zostaje,
   to --container (patrz niżej) - czysto funkcjonalna potrzeba szerszego
   contentu dla layoutu z sidebarem, nie kwestia koloru/marki. */
.panel-page {
  /* Popr. po live review (2 tury) — panel wyglądał zbyt drobno na dużych
     ekranach. Szerszy content (bez zmiany --container na reszcie serwisu -
     nadpisanie WYŁĄCZNIE w zasięgu .panel-page), doprecyzowany do
     1180-1280px zakresu po drugiej turze feedbacku. */
  --container: 1240px;

  background: var(--color-bg);
}

/* ---- Ekran ładowania, zanim frontend potwierdzi token (panel/index.html) ----
   [hidden] override konieczny - .panel-loading{display:flex} ma tę samą
   specyficzność co domyślne [hidden]{display:none} przeglądarki i jako
   późniejsza reguła autorska wygrywa (ten sam błąd znaleziony wcześniej
   przy .pricing-group, etap 32 - patrz CLAUDE.md). */
.panel-loading { min-height: 60vh; display: flex; align-items: center; justify-content: center; padding: 24px; text-align: center; }
.panel-loading[hidden] { display: none; }
.panel-loading p { color: var(--color-muted); font-size: .95em; }

/* Logo w headerze stron BEZ sidebara/nawigacji (wyłącznie panel/onboarding/
   - świadomie bez .panel-nav, patrz sekcja "Onboarding" niżej w pliku) -
   te strony nie mają .panel-sidebar__brand, więc marka zostaje w
   .panel-header jak dotychczas, w niezmienionym, mniejszym rozmiarze. */
.panel-header__wordmark .wordmark__icon,
.panel-header__wordmark .wordmark__logo { height: 32px; width: auto; }

/* ---- Sidebar (marka + nawigacja) ----
   KOREKTA "Content + Mobile + Panel UX" §5 — poniżej 1024px pasek linków
   poziomo przewijalny (dawny "bez hamburgera" mechanizm) jest teraz
   ZASTĄPIONY mobilnym drawerem (patrz .panel-drawer* wyżej) jako główny
   sposób nawigacji - sam <nav class="panel-nav"> zostaje w HTML (żeby nie
   duplikować logiki JS ani ryzykować rozjazdu treści), ale jest ukryty na
   tej szerokości (patrz reguła `.panel-sidebar > .panel-nav` niżej) - jego
   treść żyje teraz w .panel-drawer__nav (dokładna kopia tego samego
   markupu). Marka/logo zostaje widoczna na górze strony niezależnie od
   drawera. Od 1024px: pełnowymiarowy, stały pionowy sidebar (patrz siatka
   .panel-shell niżej) z dekoracją psa na kocyku u dołu
   (dog-decoration-sidebar-blanket, WYŁĄCZNIE jako mały background-image
   lokalnej dekoracji). ---- */
/* "Final background cleanup" (13.09.2026) - sidebar (mobile pasek u góry
   I desktopowa kolumna, ta sama klasa) dostaje jasnoróżowe tło #FFF3F8 -
   jedyny kolor panelu poza fuksją-akcentem, patrz .panel-nav__link niżej. */
.panel-sidebar { background: #FFF3F8; border-bottom: var(--border-width) solid var(--color-line); }
.panel-sidebar__brand { display: flex; align-items: center; gap: 10px; padding: 16px 20px; }
.panel-sidebar__brand-icon { height: 44px; width: auto; }
.panel-sidebar__brand-logo { height: 30px; width: auto; }
@media (max-width: 1023.98px) {
  .panel-sidebar > .panel-nav { display: none; }
  /* Hamburger siedzi teraz OBOK loga w tym samym wierszu (poprzednio osobny
     wiersz w .panel-header, z tekstem "Menu") - .panel-sidebar staje się
     poziomym paskiem brand+przycisk, justify-content:space-between rozpycha
     je do przeciwległych krawędzi bez potrzeby margin-left:auto na
     przycisku. */
  .panel-sidebar { display: flex; align-items: center; justify-content: space-between; padding-right: 16px; }
}
/* Ikony liniowe przy pozycjach nawigacji (patrz sprite SVG na każdej
   stronie panelu, symbole #icon-nav-*) - proste, generyczne piktogramy
   (dom/łapa/zegar/kalendarz/cel/gwiazda/dokument/play/książka/koperta),
   NIE loga marek - to jedyny przypadek, gdzie hand-drawn SVG jest bezpieczne
   (zasada z CLAUDE.md dot. etapu 17F.6 zabraniała odtwarzania Z PAMIĘCI
   kształtów LOGO Instagram/Facebook/TikTok, nie generycznych piktogramów). */
.panel-nav__icon { width: 20px; height: 20px; flex-shrink: 0; }

/* ---- Nagłówek panelu ("topbar" prawej kolumny od 1024px) ---- */
.panel-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  padding: 14px 20px;
  background: var(--color-surface);
  border-bottom: var(--border-width) solid var(--color-line);
}
@media (min-width: 768px) { .panel-header { padding-inline: 40px; } }
@media (min-width: 1024px) { .panel-header { min-height: 76px; padding-block: 14px; } }
.panel-header__greeting-wrap { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.panel-header__greeting { font-family: var(--font-display); font-weight: 600; font-size: 1.25rem; color: var(--color-ink); margin: 0; }
@media (min-width: 1024px) { .panel-header__greeting { font-size: 1.6rem; } }
.panel-header__subgreeting { font-size: .9em; color: var(--color-muted); margin: 0; }
/* MAŁY UX FIX: KARNET W POWITANIU KLIENTA (17.09.2026) - jedna linia na
   aktywny typ karnetu, bezpośrednio pod powitaniem (zastępuje osobny
   kafel "Karnety i pakiety", usunięty jako redundantny). */
.panel-header__passes { margin-top: 4px; }
.panel-header__passes[hidden] { display: none; }
/* ETAP: KOMPAKTOWE PAKIETY W NAGŁÓWKU PANELU (19.09.2026) - <summary>
   niesie zarówno tytuł "Twoje pakiety (X)", jak i jednolinijkowe
   podsumowanie (oba muszą być wewnątrz <summary>, bo tylko ono jest
   widoczne, gdy <details> jest zwinięty - reszta jest chowana natywnie
   przez przeglądarkę, zero JS do tego potrzebne). Lekki wizualnie: mały
   font, brak tła/ramki/cienia, tylko kolor + wskaźnik "da się kliknąć". */
.panel-header__passes-summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 6px;
  font-size: .9em;
}
.panel-header__passes-summary::-webkit-details-marker { display: none; }
.panel-header__passes-summary::marker { content: ""; }
.panel-header__passes-summary::before {
  content: "▸";
  font-size: .8em;
  color: var(--color-muted);
  transition: transform .15s var(--ease);
}
.panel-header__passes[open] .panel-header__passes-summary::before { transform: rotate(90deg); }
.panel-header__passes-title { font-weight: 700; color: var(--color-fuchsia-hover); }
.panel-header__passes-compact { color: var(--color-muted); }
.panel-header__passes[open] .panel-header__passes-compact { display: none; }
.panel-header__passes-full { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.panel-header__passes-line { font-size: .9em; font-weight: 600; color: var(--color-fuchsia-hover); margin: 0; }
/* NOTYFIKACJA ZAKOŃCZENIA KARNETU (08.10.2026) - §14 ticketu: "zauważalne,
   ale NIE czerwony alarm, lekko odróżnione od aktywnego karnetu, nadal
   kompaktowe" - ten sam rozmiar/miejsce co .panel-header__passes-line,
   wyłącznie stonowany kolor (istniejący --color-muted, ten sam token co
   podsumowanie zwinięte) + kursywa zamiast pogrubienia/fuksji. */
.panel-header__passes-line--ended { font-weight: 500; font-style: italic; color: var(--color-muted); }
/* margin-left:auto (nie justify-content:space-between na rodzicu) - status
   i wylogowanie zawsze przy prawej krawędzi, niezależnie od szerokości
   powitania po lewej. KOREKTA po 2. turze live review §4 — powitanie jest
   teraz w topbarze na WSZYSTKICH stronach z sidebarem, w tym na
   Dashboardzie (wcześniej Dashboard miał je wyłącznie jako duży H1 w
   treści - usunięte stamtąd, patrz panel/index.html, żeby nie dublować
   tego samego "Cześć, [Imię]!" w dwóch miejscach na tej samej stronie). */
.panel-header__actions { display: flex; align-items: center; flex-wrap: nowrap; flex-shrink: 0; gap: 10px; margin-left: auto; }
/* BUG UX (20.09.2026) - trzeci element ("Moje dane") w tym rzędzie
   potrafił wypchnąć .panel-header (flex-wrap:wrap) na drugą linię,
   zwiększając wysokość headera. greeting-wrap dostał min-width:0 (wyżej)
   żeby ustąpić miejsca zamiast wymuszać zawinięcie - actions zostaje
   nierozciągliwe i w jednym, zwartym rzędzie. */
/* KOREKTA "kontrola po live review" §4 - status współpracy i "Wyloguj się"
   nie mają zajmować miejsca w głównym mobile headerze <1024px (oba
   dostępne w drawerze: #panel-drawer-status-badge/#panel-drawer-logout-btn,
   mirrorowane przez script.js). Powitanie (.panel-header__greeting-wrap)
   zostaje widoczne - dotyczy wyłącznie statusu/wylogowania. Od 1024px
   (brak drawera) oba wracają jako jedyny sposób ich pokazania. */
@media (max-width: 1023.98px) { .panel-header__actions { display: none; } }

/* Przycisk otwierający mobilny drawer (polecenie "Content + Mobile + Panel
   UX" §5, ikonka-bez-podpisu i pozycja obok loga - poprawka live review) -
   żyje dziś jako bezpośrednie dziecko .panel-sidebar (obok
   .panel-sidebar__brand, patrz reguła @media wyżej), nie .panel-header.
   Widoczny WYŁĄCZNIE <1024px - na desktopie sidebar jest już zawsze
   widoczny więc hamburger jest zbędny i jawnie ukryty (reguła @media
   niżej), zamiast dublować całą nawigację jako drugi, zbędny napis "Menu"
   w topbarze. Tylko 3 kreski, bez tekstu - aria-label niesie nazwę dla
   czytników ekranu. */
.panel-header__menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  background: none;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-pill);
  color: var(--color-ink);
  cursor: pointer;
}
.panel-header__menu-btn:hover, .panel-header__menu-btn:focus-visible { background: var(--color-surface-alt); }
.panel-header__menu-icon { width: 20px; height: 20px; flex-shrink: 0; }
@media (min-width: 1024px) { .panel-header__menu-btn { display: none; } }

/* Etap 9D — "aktywny" traktowany jako stan pozytywny/premium (miękki
   różowy tint zamiast zimnego turkusu), spójny z resztą palety. */
.panel-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background: var(--color-fuchsia-soft);
  color: var(--color-ink);
  font-weight: 700;
  font-size: 12px;
  white-space: nowrap;
}
.panel-status-badge[hidden] { display: none; }
.panel-status-badge--inactive { background: var(--color-surface-alt); color: var(--color-muted); }

.panel-nav {
  display: flex;
  gap: 6px;
  padding: 10px 24px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
@media (min-width: 768px) { .panel-nav { padding-inline: 40px; } }
.panel-nav__link {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 700;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
/* "Final background cleanup" (13.09.2026) - hover subtelnie ciemniejszy
   od jasnoróżowego tła sidebara (#FFF3F8), ale wyraźnie słabszy niż
   aktywna pozycja (#F8D9E9) - hover nie może wyglądać jak "prawie
   aktywne". */
a.panel-nav__link:hover, a.panel-nav__link:focus-visible { background: #FCE5F0; color: var(--color-ink); }
.panel-nav__link.is-active { background: #F8D9E9; color: var(--color-fuchsia-hover); font-weight: 800; }
.panel-nav__link--soon { color: var(--color-muted); cursor: default; }
.panel-nav__link--soon em { font-style: normal; font-weight: 500; opacity: .7; font-size: .9em; }

/* =========================================================
   Mobilny drawer (polecenie "Content + Mobile + Panel UX" §5-6) - JEDEN
   spójny komponent (te same klasy/CSS/JS) na wszystkich 10 stronach z
   sidebarem. Zastępuje pozioty, przewijalny pasek nawigacji <1024px jako
   GŁÓWNY sposób nawigacji na telefonie/tablecie (sam .panel-nav zostaje w
   DOM z tych samych powodów co dotychczas - fallback bez JS, patrz niżej -
   ale drawer jest tym, czego użytkownik faktycznie dotyka). Wyłączony
   całkowicie od 1024px (desktop ma stały sidebar, drawer jest zbędny).
   Markup: .panel-drawer (fixed, position:relative dla dzieci) >
   .panel-drawer__overlay (tło) + .panel-drawer__panel (właściwy wysuwany
   panel, position:absolute left:0). Stan otwarty/zamknięty to WYŁĄCZNIE
   klasa .is-open (nie atrybut [hidden] - hidden blokowałby animację
   transform/opacity, [hidden] nie da się animować). ========================================================= */
.panel-drawer { position: fixed; inset: 0; z-index: 60; }
@media (min-width: 1024px) { .panel-drawer { display: none; } }
.panel-drawer:not(.is-open) { pointer-events: none; }
.panel-drawer__overlay {
  position: absolute;
  inset: 0;
  background: rgba(34, 33, 39, .45);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s var(--ease), visibility .2s var(--ease);
}
.panel-drawer.is-open .panel-drawer__overlay { opacity: 1; visibility: visible; }
.panel-drawer__panel {
  position: absolute;
  top: 0;
  left: 0;
  /* POPRAWKA MOBILE (26.09.2026) - `100vh` jako bezpieczny fallback dla
     przeglądarek bez wsparcia dla `dvh` (kaskada: druga deklaracja z
     nieznaną jednostką jest ignorowana, zostaje pierwsza) - bez tego
     `height` cichnie wracał do `auto` (dopasowanie do treści zamiast
     pełnej wysokości ekranu) na starszych silnikach. `dvh` (gdy wspierane)
     nadal poprawnie reaguje na chowający/pokazujący się pasek adresu. */
  height: 100vh;
  height: 100dvh;
  width: min(86vw, 340px);
  background: #FFF3F8;
  box-shadow: 0 0 48px rgba(28, 24, 31, .22);
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform .25s var(--ease);
  overflow-y: auto;
}
.panel-drawer.is-open .panel-drawer__panel { transform: translateX(0); }
@media (prefers-reduced-motion: reduce) {
  .panel-drawer__overlay, .panel-drawer__panel { transition: none; }
}
.panel-drawer__header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 20px; border-bottom: var(--border-width) solid var(--color-line); flex-shrink: 0; }
.panel-drawer__brand { padding: 0; }
.panel-drawer__brand .panel-sidebar__brand-icon { height: 40px; }
.panel-drawer__brand .panel-sidebar__brand-logo { height: 28px; }
.panel-drawer__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--color-ink);
  cursor: pointer;
}
.panel-drawer__close:hover, .panel-drawer__close:focus-visible { background: var(--color-surface-alt); }
.panel-drawer__close svg { width: 22px; height: 22px; display: block; }
/* Nav wewnątrz drawera reużywa dokładnie .panel-nav/.panel-nav__link (te
   same klasy co pasek pod topbarem i desktopowy sidebar) - nadpisany
   wyłącznie układ na pionową listę pełnej szerokości. */
.panel-drawer__nav {
  flex: 1;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  padding: 14px;
  overflow: visible;
}
.panel-drawer__nav .panel-nav__link, .panel-drawer__nav .panel-nav__link--soon {
  width: 100%;
  justify-content: flex-start;
  gap: 12px;
  padding: 13px 16px;
  font-size: 15px;
  white-space: normal;
}
.panel-drawer__footer { display: flex; align-items: center; flex-wrap: wrap; justify-content: space-between; gap: 12px; padding: 16px 20px; border-top: var(--border-width) solid var(--color-line); flex-shrink: 0; }
/* BUG UX - "Moje dane" w footerze drawera (20.09.2026): badge statusu
   dostaje pełną szerokość własnego wiersza (jeśli widoczny, `hidden`
   domyślnie) - dwa przyciski ("Moje dane"/"Wyloguj się") schodzą
   automatycznie na kolejny wiersz przez flex-wrap, zamiast ściskać się
   w jednym rzędzie z badge'em na 320-375px. */
.panel-drawer__footer .panel-status-badge { flex: 1 1 100%; }

/* Siatka "sidebar + content" od 1024px.
   KOREKTA po live review §1 — poprzednia wersja opierała się na
   ":has(> .panel-sidebar)" I NIEZALEŻNIE, bezwarunkowo stylowała
   .panel-sidebar/.panel-nav jako pionowy flex w tym samym media query.
   To dwie osobne reguły, które MUSIAŁY zadziałać razem, żeby wyglądać
   poprawnie - a nie były do siebie w żaden sposób "spięte". Jeśli z
   jakiegokolwiek powodu selektor grida nie dopasował się (np. inna wersja
   przeglądarki/silnika w Local, kolejność przetwarzania :has()), sidebar
   i tak dostawał display:flex/flex-direction:column i rozciągał się na
   PEŁNĄ szerokość strony (bo rodzic .panel-shell zostawał zwykłym
   display:block, nie gridem) - dokładnie zgłoszony błąd. Naprawione przez
   jawną klasę .has-sidebar na #panel-shell (dodaną w HTML na wszystkich
   10 stronach z nawigacją, brak na panel/onboarding/) - WSZYSTKIE reguły
   niżej są teraz zagnieżdżone pod TYM SAMYM selektorem `.panel-shell.
   has-sidebar`, więc siatka i wygląd sidebara stosują się ZAWSZE razem,
   nigdy częściowo. Krócej: grid i "pionowy sidebar" są teraz jedną,
   atomową regułą zamiast dwóch osobnych, które musiały się zgadzać. */
@media (min-width: 1024px) {
  .panel-shell.has-sidebar:not([hidden]) {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    align-items: stretch;
    min-height: 100vh;
  }
  /* KOREKTA "ostatnia korekta sidebara" - zastępuje CAŁY mechanizm
     max-height/padding-bottom-rezerwa z poprzedniej tury (zgadywany
     breakpoint 950px fałszywie łapał typowe ekrany ok. 900px wysokości).
     Dziś sidebar to zwykły, stabilny flex-column BEZ żadnego breakpointu
     wysokości: brand (flex:0 0 auto, naturalna wysokość) → nav (flex:1 1
     auto + min-height:0, wypełnia CAŁĄ resztę dostępnej przestrzeni) →
     decor (flex:0 0 auto, stała wysokość ~260px, NORMALNY ostatni element
     kolumny, nie position:absolute/fixed). `min-height:0` na nav jest tu
     kluczowe - bez tego flex item domyślnie nie kurczy się poniżej
     wysokości własnej treści, więc `overflow-y:auto` nigdy by się nie
     uruchomił. Z `min-height:0` nav faktycznie przyjmuje dokładnie tyle
     miejsca, ile zostaje po brand+decor, i dopiero gdy jego RZECZYWISTA
     treść (10 pozycji) jest wyższa niż ta przestrzeń, samoistnie
     uruchamia się wewnętrzny scroll - bez zgadywania żadnej konkretnej
     wysokości viewportu, działa poprawnie na każdej. `position:sticky;
     top:0; height:100dvh` na samym sidebarze (bez zmian) - box zawsze ma
     wysokość viewportu i zostaje przyklejony do góry podczas
     scrollowania długiej strony głównej treści. */
  .panel-shell.has-sidebar > .panel-sidebar {
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100dvh;
    overflow: hidden;
    border-bottom: none;
    border-right: var(--border-width) solid var(--color-line);
    background-color: #FFF3F8;
  }
  /* KOREKTA "live review 3" - logo/wordmark było przycinane. Prawdziwa
     przyczyna: `logo-pan-piesel-icon.png` (kwadrat 1:1) w wysokości 70px
     ma szerokość 70px, a `logo-pan-piesel-wordmark.png` (proporcje 6.4:1)
     w wysokości 46px ma szerokość 46×6.4≈294px - razem z gapem 18px i
     paddingiem 32px×2 to ~446px potrzebnej szerokości W KOLUMNIE SZEROKIEJ
     NA 300px. Wcześniej (bez overflow:hidden na .panel-sidebar) ten
     nadmiar po prostu wylewał się poza sidebar bez wizualnej skargi -
     odkąd sidebar dostał `overflow:hidden` (poprawka sticky/decor, patrz
     niżej), ten sam nadmiar zaczął być realnie ucinany. Naprawione
     ZMNIEJSZENIEM wysokości obu obrazków (NIE assetów - te same pliki,
     mniejszy render) tak, żeby całość + padding mieściła się w 300px z
     zapasem: icon 38px (szer. 38px) + logo 28px (szer. 28×6.4≈179px) +
     gap 10px + padding 24px×2 = ok. 275px - mieści się z ~25px zapasu,
     bez cropu, bez rozciągania, proporcje bez zmian (height/width:auto). */
  .panel-shell.has-sidebar .panel-sidebar__brand { position: relative; z-index: 1; padding: 32px 24px 26px; gap: 10px; flex: 0 0 auto; }
  .panel-shell.has-sidebar .panel-sidebar__brand-icon { height: 38px; }
  .panel-shell.has-sidebar .panel-sidebar__brand-logo { height: 28px; }
  /* flex:1 1 auto + min-height:0 - nav wypełnia dokładnie tyle miejsca,
     ile zostaje w kolumnie po brand i decor (oba flex:0 0 auto, stała
     wysokość). Bez żadnego breakpointu: jeśli 10 pozycji nav mieści się
     w tej przestrzeni, stoi nieruchomo (overflow-y:auto nic nie robi,
     bo nie ma czego przewijać); jeśli nie mieści się (bardzo niski
     viewport), scrolluje się WEWNĘTRZNIE samoistnie - przeglądarka sama
     to wykrywa z realnej wysokości treści, nie z zgadywanego px. */
  .panel-shell.has-sidebar .panel-nav {
    flex: 1 1 auto;
    min-height: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding: 10px 18px;
    position: relative;
    z-index: 1;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .panel-shell.has-sidebar .panel-nav__link,
  .panel-shell.has-sidebar .panel-nav__link--soon {
    width: 100%;
    justify-content: flex-start;
    gap: 12px;
    padding: 13px 16px;
    font-size: 15px;
  }
  /* Aktywna pozycja w desktopowym sidebarze - świadomie NIE typowa SaaS
     pigułka (polecenie §3): mniejszy, "chip" radius zamiast pełnej
     pigułki + cienki fuksjowy marker po lewej krawędzi. padding-left
     zmniejszony o dokładnie szerokość markera, żeby tekst nie "skakał"
     względem nieaktywnych pozycji. */
  .panel-shell.has-sidebar .panel-nav__link.is-active {
    border-radius: var(--radius-sm);
    padding-left: 13px;
    border-left: 3px solid var(--color-fuchsia);
  }
  .panel-shell.has-sidebar .panel-shell__content { display: flex; flex-direction: column; min-height: 100vh; }

  /* Editorial dolny blok sidebara (pies na kocyku + "dobrze, że tu jesteś" +
     serduszko) - dekoracja jest NORMALNYM, ostatnim elementem flex-column
     sidebara (flex:0 0 auto, stała wysokość - patrz komentarz "§M" niżej
     za aktualną wartość i historię kolejnych korekt), nie position:
     absolute/fixed nachodzącym na nav. Efekt: brand na górze, nav w
     środku (wypełnia resztę, przewija się WEWNĘTRZNIE tylko gdy realnie
     potrzeba - patrz .panel-nav wyżej), dekoracja zawsze na samym dole -
     trzy zwykłe bloki jeden pod drugim, zero nakładania z definicji (nie
     z rezerwowanego marginesu). `position:relative` zostaje - to kontekst
     dla trzech obrazków w środku (handwriting/heart/dog), które nadal są
     position:absolute WZGLĘDEM TEGO diva. `overflow:hidden` -
     zabezpieczenie, gdyby któryś z trzech obrazków w środku wystawał poza
     własny box. pointer-events:none - to czysta dekoracja, nigdy nie
     przechwytuje kliknięć. */
  /* "Finalna ankieta startowa" §M - wysokość zmniejszona 265px→200px (w
     żądanym zakresie 190-215px). Sam dog (bottom:0, wysokość ~106px przy
     szerokości 185px, 700×400 oryginał) NIETKNIĘTY - kompresji podlega
     wyłącznie pusta przestrzeń MIĘDZY psem a napisem (było 79px, jest
     14px), żeby napis był bliżej psa, tak jak explicite poproszono. */
  .panel-shell.has-sidebar .panel-sidebar__decor {
    display: block;
    flex: 0 0 auto;
    position: relative;
    left: auto;
    right: auto;
    bottom: auto;
    width: 100%;
    height: 200px;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
  }
  .panel-shell.has-sidebar .panel-sidebar__decor-handwriting {
    position: absolute;
    left: 38px;
    bottom: 120px;
    width: 140px;
    height: auto;
    display: block;
  }
  .panel-shell.has-sidebar .panel-sidebar__decor-heart {
    position: absolute;
    left: 157px;
    bottom: 110px;
    width: 24px;
    height: auto;
    display: block;
  }
  .panel-shell.has-sidebar .panel-sidebar__decor-dog {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 0;
    width: 185px;
    height: auto;
    display: block;
  }
}
/* Poza desktopowym sidebarem (<1024px, gdzie .panel-sidebar jest poziomym
   paskiem na górze strony) dekoracja jest całkowicie ukryta - ten sam
   .panel-sidebar__decor div istnieje w HTML na wszystkich stronach, ale
   nie renderuje się poniżej 1024px. */
.panel-sidebar__decor { display: none; }
@media (min-width: 1024px) {
  .panel-shell.has-sidebar .panel-main { flex: 1; }
}

/* ---- Treść dashboardu ---- */
.panel-main { padding-block: 40px 64px; }
@media (min-width: 1024px) { .panel-main { padding-block: 56px 80px; } }
@media (min-width: 1440px) { .panel-main { padding-block: 64px 96px; } }

/* "Final background cleanup" (13.09.2026) - REZYGNACJA z całego systemu
   pastelowych teł per strona / Dalmatian spots / pattern A/B/C (obie
   poprzednie tury tego kierunku, "pastel page backgrounds" i "white +
   dalmatian spots" + "shape correction", USUNIĘTE CAŁKOWICIE, łącznie z
   --spot-1/--spot-2/--spot-graphite, .panel-spots--a/--b/--c i
   .panel-main::before). Finalny kierunek jest prosty: jednolite białe
   .panel-main na wszystkich stronach panelu - kolor/charakter żyje dziś
   wyłącznie w sidebarze (patrz .panel-shell.has-sidebar > .panel-sidebar
   niżej). */
.panel-main { background: #FFFFFF; }
.panel-main__heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 4vw, 3.4rem);
  letter-spacing: -.01em;
  color: var(--color-ink);
  margin-top: 10px;
}
.panel-main__lead { font-size: 1.15rem; line-height: 1.6; color: var(--color-text); max-width: 68ch; margin-top: 14px; margin-bottom: 40px; }
/* Drugorzędna notatka pod leadem (np. "Moje cele" - limit 2 aktywnych na
   psa) - mniejsza i przygaszona, nie konkuruje z głównym leadem. Odstęp
   od bezpośrednio poprzedzającego leadu zmniejszony WYŁĄCZNIE w tej
   konkretnej kombinacji (sąsiedzki selektor), nie dotyka .panel-main__lead
   używanego samodzielnie na innych stronach panelu. */
.panel-main__lead + .panel-main__note { margin-top: -26px; }
.panel-main__note { font-size: .95em; color: var(--color-muted); margin-bottom: 40px; }

/* Friends × Premium (polecenie §4) — hero to teraz OTWARTA sekcja, bez
   karty/obrysu/tła (poprzednia "banner-karta" z poprzedniej tury świadomie
   cofnięta). Dużo white space zamiast card chrome; jedyny akcent to ten
   sam CSS-owy fuksjowy marker pod H1 co na "Moje psy" (spójny, systemowy
   sygnet dwóch analogicznych intro bloków aplikacji) - żadnego obrazka
   underline. */
.panel-hero { margin-bottom: 48px; }
@media (min-width: 1024px) { .panel-hero { margin-bottom: 56px; } }
.panel-hero .panel-main__heading { position: relative; display: inline-block; padding-bottom: 14px; }
.panel-hero .panel-main__heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 64px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--color-fuchsia);
}
.panel-hero .panel-main__lead { margin-bottom: 0; }

/* "Final UI pass - full section shells" (13.09.2026) - ZASTĘPUJE poprzednią
   turę ("friendly premium pass"): małe pastelowe page-hero (WYŁĄCZNIE
   H1+lead+decor) uznane za niewystarczające - CAŁA zawartość każdej z 9
   głównych stron panelu (poza Dashboardem, który ma własny
   .panel-hero/.panel-card--featured wyżej i tej tury nie dotyczy) żyje
   dziś w JEDNYM dużym pastelowym prostokącie: intro (tekst+decor) na
   górze, właściwa treść strony (listy/formularze/accordiony, wszystkie
   BIAŁE) poniżej, w tym samym boxie. `.page-hero*` (poprzednia tura)
   USUNIĘTE CAŁKOWICIE, zastąpione przez `.section-shell*` niżej. */
.section-shell {
  width: 100%;
  box-sizing: border-box;
  border-radius: 30px;
  padding: 38px;
}
@media (max-width: 767px) {
  /* "Mobile shell fix" (13.09.2026) - §3 polecenia: mniejszy poziomy
     padding na mobile (18px zamiast 23px na obu bokach) odzyskuje ~10px
     szerokości contentu - niewielka, celowa korekta, nie rezygnacja z
     "oddechu" (pionowy padding zostaje praktycznie bez zmian). */
  .section-shell { border-radius: 24px; padding: 22px 18px; }
}
/* "Mobile shell fix" (13.09.2026) - ZNALEZIONA PRAWDZIWA PRZYCZYNA "tekst
   łamie się za wcześnie mimo widocznego miejsca": poprzednia wersja
   trzymała H1+lead+note RAZEM w jednym .section-shell__text, które na
   mobile było CAŁYM grid-itemem w kolumnie 1fr obok ikony - więc nie
   tylko H1, ale też lead/note (którym ikona wcale nie przeszkadza) były
   ściśnięte do tej samej wąskiej kolumny przez CAŁĄ wysokość nagłówka.
   Naprawione podziałem nagłówka na 3 niezależne obszary grida: "title"
   (H1, ew. eyebrow) i "decor" dzielą górny wiersz na WSZYSTKICH
   szerokościach; "text" (lead/note) na desktopie zostaje w tej samej
   wąskiej kolumnie co dawniej (decor rozciąga się na oba wiersze, patrz
   niżej - zero zmiany wizualnej na desktopie), ale na mobile (patrz
   @media niżej) dostaje WŁASNY, PEŁNOSZEROKI wiersz - tylko H1 faktycznie
   sąsiaduje z ikoną, lead/note dostają tam pełną szerokość shellu.
   Wymagało to drobnej zmiany HTML na wszystkich 9 stronach shellowych
   (nowy wrapper .section-shell__title wokół H1/eyebrow, .section-shell__
   text zostaje wyłącznie na lead/note) - ten sam jeden system na
   wszystkich, zero nowej treści/kopii poza Celami. */
.section-shell__header {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "title decor" "text decor";
  column-gap: 24px;
  margin-bottom: 32px;
}
.section-shell__title { grid-area: title; min-width: 0; }
.section-shell__title .panel-main__heading { margin-top: 0; }
.section-shell__title .eyebrow { margin-bottom: 6px; }
.section-shell__text { grid-area: text; max-width: 620px; min-width: 0; }
.section-shell__text .panel-main__lead { margin-bottom: 0; }
.section-shell__text .panel-main__note { margin-bottom: 0; }
/* Naprawia znaleziony overlap na "Moje cele" (poprzednia tura) - stary
   `.panel-main__lead + .panel-main__note { margin-top: -26px; }` (patrz
   niżej w pliku) był skalibrowany pod DAWNY margin-bottom:40px leadu;
   wewnątrz shellu lead ma margin-bottom:0 (wyżej), więc ten sam -26px
   ciągnął notatkę wprost NA tekst leadu, nie pod niego. Tekst pozostaje
   w normalnym block flow (żadnego position:absolute) - to była wyłącznie
   kolizja dwóch marginesów, nie błąd pozycjonowania. */
.section-shell__text .panel-main__lead + .panel-main__note { margin-top: 6px; }
/* Dekoracja spina OBA wiersze kolumny 2 na desktopie (ta sama nazwa
   obszaru "decor" powtórzona w obu wierszach grid-template-areas wyżej =
   jeden item rozciągnięty na oba wiersze) - `align-self:center` centruje
   ją pionowo względem całej wysokości title+text, dokładnie jak poprzedni
   flex `align-items:center`. Style/rozmiar ikon bez zmian względem
   poprzedniej tury ("osadzona" w boxie dzięki własnemu marginesowi). */
.section-shell__decor { grid-area: decor; align-self: center; flex-shrink: 0; margin-right: 10px; margin-top: 6px; }
/* Dwie kategorie źródłowych rozmiarów assetów: "mini" ilustracje 512×512
   (mini-availability/next-session/goals/next-event/courses) dostają
   większy render niż płaskie doodle 200-300×200-300 (doodle-heart-
   graphite-single/hearts-graphite-trio/pair, zarowka-brown) - inaczej te
   drugie wyglądałyby nienaturalnie duże/pikselowe względem swojej
   faktycznej szczegółowości. */
.section-shell__decor--mini { width: 122px; height: auto; }
.section-shell__decor--doodle { width: 112px; height: auto; }
@media (max-width: 767px) {
  /* Na mobile dekoracja NIE spina już 2 wierszy (w odróżnieniu od
     desktopu, gdzie zostaje pionowo wyśrodkowana względem title+text) -
     "text" (lead/note) dostaje WŁASNY wiersz na PEŁNĄ szerokość, dekoracja
     zostaje wyłącznie w wierszu z H1. To jest kluczowa różnica względem
     desktopu, nie tylko dostrojenie odstępów. Ikona: `align-self:start`
     przypina ją do SAMEJ GÓRY tego wiersza, czyli wizualnie w linii z H1,
     nigdy niżej (dawny bug: cały tekst nad ikoną w flex-column). */
  .section-shell__header { grid-template-areas: "title decor" "text text"; column-gap: 14px; row-gap: 6px; }
  .section-shell__decor { align-self: start; margin-right: 0; margin-top: 2px; }
  .section-shell__decor--mini { width: 70px; }
  .section-shell__decor--doodle { width: 64px; }
}
/* "Final micro fix - availability mobile" (13.09.2026) - poprzednia tura
   podniosła ikonę Dyspozycyjności do 92px na mobile (patrz historia wyżej),
   co przy realnym teście na 360px nachodziło na H1 "Dyspozycyjność".
   Zmniejszona do 66px (mieści się w żądanym zakresie 64-68px, nadal
   wyraźnie większa niż bazowe 70px innych mini-ikon... nie, mniejsza -
   ale nadal czytelna) + H1 tej jednej strony zmniejszony do 28px (z
   ogólnego ~32px na mobile) + gap w górnym rzędzie title/decor zawężony
   do 8px - WYŁĄCZNIE dla .section-shell--availability, inne strony z
   mini-ilustracjami (grafik/cele/wydarzenia/kursy) zostają nietknięte
   przy 70px/domyślnym H1/14px gap. */
@media (max-width: 767px) {
  .section-shell--availability .section-shell__decor--mini { width: 60px; }
  .section-shell--availability .section-shell__title .panel-main__heading { font-size: 28px; }
  .section-shell--availability .section-shell__header { column-gap: 14px; }
}
.section-shell--dogs { background: #EDF7FC; }
.section-shell--availability { background: #EEF8F2; }
.section-shell--schedule { background: #FFF3EA; }
.section-shell--goals { background: #FCEEF5; }
.section-shell--events { background: #FFF8D9; }
.section-shell--materials { background: #F8F3E9; }
.section-shell--courses { background: #EDF7F1; }
.section-shell--rules { background: #F3EEFB; }
.section-shell--contact { background: #FFF0F6; }
/* Kontakt (§12 polecenia) - jeden CTA, teraz WEWNĄTRZ shellu, bez
   własnego drugiego kolorowego boxu (`.contact-community` traciło tu
   swoje tło/padding - patrz reguła niżej w pliku, sekcja "Panel — Kontakt") -
   sam wyśrodkowuje się w normalnym block flow shellu. */
.section-shell__body { margin-top: 8px; }
/* Formularze BEZ własnej karty (avail-form/goals-custom-form - reszta,
   np. .dog-add__form, już ma białe tło) dostają je tu, jawnie i wąsko
   (WYŁĄCZNIE te dwa ID, nie generyczne `.form` sitewide - login/kontakt/
   inne formularze poza shellami mają zostać dokładnie takie, jak są). */
#avail-form, #goals-custom-form {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 28px;
}
#goals-custom-form { margin-top: 16px; }

/* Dashboard — hierarchia zamiast ściany identycznych kafelków (DESIGN.md
   zakazuje "layoutu złożonego wyłącznie z podobnych białych kafelków").
   Etap 9E.3a - .panel-dashboard jest teraz JEDNĄ kolumną na każdej
   szerokości (featured karta zajęć -> opcjonalna karta "po zajęciach" ->
   sekcja skrótów), zastępuje dawny układ 2fr/1fr z wąską kolumną po prawej
   (skróty siedziały OBOK karty zajęć, nie pod nią) - jawne polecenie:
   sekcja skrótów ma być bezpośrednio POD główną kartą. Dawny pasek "Szybkie
   skróty" USUNIĘTY całkowicie wcześniej (patrz CLAUDE.md) - te linki są już
   dostępne w głównym menu; TA sekcja (.panel-dashboard__secondary) to
   osobny, treściowy zestaw 4 kart (cele/dyspozycyjność/wydarzenia/notatki). */
.panel-dashboard { display: grid; gap: 24px; }
/* RESPONSYWNOŚĆ PANELU KLIENTA - dzieci grida bez jawnego min-width:0 mają
   domyślnie min-width:auto, czyli mogą wymusić na wspólnej kolumnie
   (i przez to na całym gridzie/karcie/viewport) szerokość opartą o
   min-content dowolnego z nich, zamiast po prostu wypełnić dostępną
   szerokość i pozwolić własnej treści się zawinąć. Zero zmiany wizualnej
   tam, gdzie karty i tak już mieszczą się w kolumnie (co dotyczy większości
   przypadków) - to wyłącznie siatka bezpieczeństwa przed przyszłą, nawet
   jedną zbyt szeroką treścią w którejkolwiek karcie dashboardu. */
.panel-dashboard > * { min-width: 0; }

/* "Na teraz" (FINALNA PRZEBUDOWA DASHBOARDU, 25.09.2026) - kontener zbiera
   ISTNIEJĄCE warunkowe karty (patrz panel/index.html), z których max. 2
   naraz mają `hidden=false` (resolveNaTerazZone(), script.js). Zwykły blok -
   każda karta wewnątrz ma już własny margin-bottom (.panel-card--note-prompt/
   .panel-card--current-session/.trainer-blackout-notice), więc kontener nie
   potrzebuje własnego layoutu do stackowania. Jawny [hidden] override -
   ten sam, wcześniej wielokrotnie znaleziony w tym pliku wzorzec ostrożności
   (zobacz .btn[hidden]/.field[hidden] itd.) na wypadek przyszłej reguły o
   równej specyficzności ustawiającej display na tej klasie. */
.panel-na-teraz[hidden] { display: none; }

/* Szybkie ankiety / polle (29.09.2026) - kontener MOŻE trzymać kilka kart
   naraz (§14 polecenia, "nie zakładaj, że zawsze będzie tylko jedna"), w
   przeciwieństwie do .panel-na-teraz wyżej (max. 2, każda już z własnym
   marginesem) - własny, jawny odstęp między kartami. Ten sam, defensywny
   [hidden] override co .panel-na-teraz. */
.panel-polls { display: flex; flex-direction: column; gap: 16px; }
.panel-polls[hidden] { display: none; }

/* Szybkie ankiety / polle - koleżeński redesign + pominięcie (poprawka
   29.09.2026, §12 polecenia - "na telefonie karta ma wyglądać jak krótka
   wiadomość od Martyny, nie jak formalny formularz"). Wyłącznie ta jedna
   karta - reużywa .panel-card/.choice-list/.btn (§12 "nie twórz nowego
   design systemu"), skalowane w dół gdzie potrzeba, zero zmiany globalnych
   reguł tych komponentów (inne moduły - dyspozycyjność/ankieta startowa/
   itd. - używają tych samych klas i zostają nietknięte). */
.panel-card--poll { padding: 20px; }
@media (min-width: 1024px) { .panel-card--poll { padding: 24px; } }
.panel-poll__eyebrow { margin-bottom: 6px; }
.panel-poll__question {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.02rem;
  line-height: 1.4;
  color: var(--color-ink);
  margin: 0 0 12px;
}
.panel-poll__deadline { font-size: .82em; color: var(--color-muted); margin: -6px 0 12px; }
.panel-poll__options { margin-bottom: 14px; }
/* Kompaktowe opcje WYŁĄCZNIE wewnątrz karty polla - scoped selektor, zero
   zmiany bazowego .choice-list__option (10px/14px) używanego gdzie indziej. */
.panel-poll__options .choice-list__option { padding: 9px 12px; font-size: .88em; }
.panel-poll__options[hidden] { display: none; }
.panel-poll__actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.panel-poll__actions[hidden] { display: none; }
.panel-poll__dismiss-link { font-size: .85em; }
.panel-poll__confirm-dismiss { margin-top: 2px; }
.panel-poll__confirm-text { font-size: .95em; font-weight: 700; color: var(--color-ink); margin: 0 0 10px; }
.panel-poll__confirm-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.panel-poll__success { font-size: .95em; font-weight: 700; color: var(--color-fuchsia); margin: 0; }

/* Etap 9E.3a - 4 karty skrótów: 1 kolumna mobile (<640px), 2 kolumny od
   640px wzwyż (włącznie z desktopem - zastępuje dawne repeat(3,1fr) na
   tablecie + powrót do 1 kolumny na desktopie, bo skróty nie są już wąską
   kolumną boczną). */
.panel-dashboard__secondary { display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .panel-dashboard__secondary { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Karty skrótów nie mają wyglądać jak kopie tej samej karty - polecenie
   "Friends × Premium" §6 zastępuje kolorowe kropki (poprzednia tura)
   prawdziwymi mini-ilustracjami (mini-goals/mini-availability/
   mini-next-event/mini-notes.png). Wydarzenie dostaje dodatkowo mały akcent
   doodle-star-yellow.png w rogu ikony - drobny editorialowy detal, nie
   główna ilustracja. */
/* KOREKTA "live review 3" §8 - ikona i nazwa karty są teraz jednym wierszem
   (.panel-card__heading-row) zamiast miniatury osobno NAD nazwą. Rozmiary
   ikon dopasowane do nowego, mniejszego kontekstu w jednym rzędzie z
   tekstem (44-52px cele/dyspozycyjność, 48-56px wydarzenie - to drugie
   dostaje dodatkowo mały akcent doodle-star-yellow.png w rogu). */
.panel-card__heading-row { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.panel-card__heading-row .panel-card__heading { margin-bottom: 0; }
.panel-card__icon { display: block; width: 48px; height: 48px; object-fit: contain; margin-bottom: 14px; flex-shrink: 0; }
.panel-card__heading-row .panel-card__icon { margin-bottom: 0; }
.panel-card__icon-wrap { position: relative; display: inline-block; margin-bottom: 14px; flex-shrink: 0; }
.panel-card__heading-row .panel-card__icon-wrap { margin-bottom: 0; }
.panel-card__icon-wrap .panel-card__icon { margin-bottom: 0; width: 52px; height: 52px; }
.panel-card__icon-accent { position: absolute; top: -8px; right: -12px; width: 26px; height: 26px; object-fit: contain; }
.panel-card__empty--emphasis { font-weight: 600; color: var(--color-ink); }
/* KOREKTA "live review 4" §2 - na 390px długie nazwy ("Moja dyspozycyjność",
   "Najbliższe wydarzenie") łamały się w sposób kolidujący z ikoną (ikona
   i heading nie miały jawnego flex-basis, więc wiersz zachowywał się
   nieprzewidywalnie przy zawijaniu). `min-width:0` na headingu jest tu
   kluczowe - bez tego flex item domyślnie nie kurczy się poniżej długości
   najdłuższego słowa, co mogło rozpychać kartę/viewport. Ikona ma stały
   flex-basis (flex-shrink:0, ustawiony wyżej) - tekst łamie się WYŁĄCZNIE
   we własnej kolumnie po prawej, nigdy pod/na ikonę. */
@media (max-width: 640px) {
  .panel-card__heading-row { gap: 10px; width: 100%; }
  .panel-card__heading-row .panel-card__icon,
  .panel-card__heading-row .panel-card__icon-wrap .panel-card__icon {
    width: 38px;
    height: 38px;
  }
  .panel-card__heading-row .panel-card__heading {
    flex: 1;
    min-width: 0;
    font-size: 1.125rem;
    line-height: 1.2;
  }
}

/* Karta podstawowa = dokładnie system strony WWW (DESIGN.md §8.1): biały
   surface, cienka linia, radius, ZERO cienia. Cień wolno tylko jednej
   wyróżnionej karcie na widok (--shadow-elevated, ten sam token co reszta
   strony) - tu dostaje go wyłącznie .panel-card--featured. */
.panel-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 28px;
}
@media (min-width: 1024px) { .panel-card { padding: 34px; } }
.panel-card__heading { font-family: var(--font-display); font-weight: 600; font-size: 1.3rem; color: var(--color-ink); margin-bottom: 12px; }
.panel-card__empty { font-size: 1em; line-height: 1.55; color: var(--color-muted); }
.panel-card__link { display: inline-flex; margin-top: 14px; font-weight: 700; font-size: .95em; color: var(--color-fuchsia); }
.panel-card__link[hidden] { display: none; }
.panel-card__link:hover, .panel-card__link:focus-visible { color: var(--color-fuchsia-hover); }

/* MODUŁ OPINII GOOGLE/FACEBOOK - "×" zamyka kartę WYŁĄCZNIE w bieżącej
   sesji (localStorage, script.js), bez żadnej mutacji stanu w bazie -
   scoped do #panel-review-card, żeby position:relative nie wpłynęło na
   inne karty tego samego wariantu (.panel-card--note-prompt). */
#panel-review-card { position: relative; }
.panel-card__dismiss {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--color-muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.panel-card__dismiss:hover, .panel-card__dismiss:focus-visible { color: var(--color-ink); background: var(--color-surface-alt); }

/* PATCH UX DASHBOARDU: ZAJĘCIA + LISTA WYDARZEŃ (17.09.2026, §B/§C ticketu)
   - zastępuje dawny pojedynczy strukturalny podgląd ("Najbliższe wydarzenie",
   etap "Miniatury + UI wydarzeń") listą do 3 kompaktowych wierszy - miniatura
   MAŁA (kwadrat, nigdy pełna szerokość karty jak na stronie Wydarzenia). */
.panel-events-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.panel-events-list[hidden] { display: none; }
.panel-event-mini { border-top: var(--border-width) solid var(--color-line); padding-top: 12px; }
.panel-event-mini:first-child { border-top: none; padding-top: 0; }
.panel-event-mini__link { display: flex; align-items: center; gap: 12px; color: inherit; }
.panel-event-mini__link:hover .panel-event-mini__title,
.panel-event-mini__link:focus-visible .panel-event-mini__title { color: var(--color-fuchsia-hover); }
.panel-event-mini__thumb {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--color-surface-alt);
}
.panel-event-mini__thumb--placeholder { display: block; }
.panel-event-mini__body { display: flex; flex-direction: column; min-width: 0; }
.panel-event-mini__title { font-family: var(--font-display); font-weight: 600; font-size: .98rem; color: var(--color-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel-event-mini__meta { font-size: .85em; color: var(--color-muted); margin-top: 2px; }
.panel-event-mini__status { font-size: .82em; font-weight: 700; color: var(--color-fuchsia-hover); margin-top: 2px; }
@media (max-width: 480px) {
  .panel-event-mini__title { white-space: normal; }
}

/* Etap 9E.4e §18/§19 polecenia - PRZEBUDOWANE: zamiast wspólnego przycisku +
   pickera "Dla którego celu?", >1 aktywny cel dostaje osobny, kompaktowy
   blok PER cel (.panel-quick-goal-block) - każda akcja od razu zna właściwe
   goal_id, zero dodatkowego kroku wyboru. Mobile-first: pełna szerokość,
   duże tap-targety, kolejne bloki pod sobą (nigdy nested cards w cards). */
.panel-quick-goal-block { margin-top: 16px; padding-top: 16px; border-top: var(--border-width) solid var(--color-line); }
.panel-quick-goal-block:first-child { margin-top: 14px; padding-top: 0; border-top: none; }
.panel-quick-goal-block__title { font-weight: 700; font-size: .95em; color: var(--color-ink); margin-bottom: 2px; }
.panel-quick-goal-block__context { font-size: .85em; color: var(--color-muted); margin-bottom: 10px; }
.panel-quick-goal-actions { display: flex; flex-direction: column; gap: 10px; }
.panel-quick-goal-actions .btn { width: 100%; min-height: 44px; }
@media (min-width: 480px) { .panel-quick-goal-actions { flex-direction: row; } .panel-quick-goal-actions .btn { width: auto; flex: 1 1 0; } }
.panel-quick-goal-panel { margin-top: 12px; }
.panel-quick-goal-panel:empty { margin-top: 0; }
/* "Moja dyspozycyjność" ma być bardziej "action oriented" (polecenie §6) -
   CTA jako prawdziwy wypełniony przycisk zamiast gołego linku. Zadeklarowana
   PO .panel-card__link, więc wygrywa w kaskadzie przy tej samej
   specyficzności - bez !important, bez mieszania z globalnym .btn (który
   ma inną, sprzeczną regułę koloru zdefiniowaną wcześniej w pliku). */
.panel-card__link--cta {
  background: var(--color-fuchsia);
  color: var(--color-white);
  padding: 11px 20px;
  border-radius: var(--radius-pill);
  font-weight: 800;
}
.panel-card__link--cta:hover, .panel-card__link--cta:focus-visible { background: var(--color-fuchsia-hover); color: var(--color-white); }

/* Etap 9E.2 §41/§47 polecenia - karta "Jesteś po zajęciach ♡" na dashboardzie,
   widoczna WYŁĄCZNIE gdy jest zakończona sesja bez notatki/bez "Nie teraz". */
.panel-card--note-prompt { background: var(--color-fuchsia-soft); border-color: var(--color-fuchsia-soft); margin-bottom: 24px; }
.panel-card--note-prompt[hidden] { display: none; }

/* MODUŁ OPINII GOOGLE/FACEBOOK (25.09.2026) - osobny, jasnoniebieski
   wariant WYŁĄCZNIE dla karty opinii - odróżnia ją wizualnie od różowych
   kart "Jesteś po zajęciach"/"Czas na podsumowanie" (.panel-card--note-
   prompt), z którą dzieli layout/spacing. Selektor złożony
   (.panel-card--note-prompt.panel-card--review) gwarantuje nadpisanie
   koloru niezależnie od kolejności reguł w pliku - żadna inna karta w
   panelu nie dostaje tego koloru. #EDF7FC to ten sam jasny błękit, którego
   projekt już używa gdzie indziej w panelu (.section-shell--dogs). */
.panel-card--note-prompt.panel-card--review { background: #EDF7FC; border-color: #EDF7FC; }

/* FINALNY TICKET - BLACKOUT TRENERA (20.09.2026) §2/§3 polecenia - JEDEN,
   współdzielony komponent notice/info (NIE `.panel-card`/duża biała karta -
   §2 "ma wyglądać jak notice, nie jak zwykła karta dashboardu"), reużyty
   identycznie na dashboardzie (panel/index.html) i na
   /panel/dyspozycyjnosc/ (§3 - poprzednia wersja "zlewała się" z przyciskami
   wyboru tygodnia, bo była zwykłym <p> bez wyraźnego tła/ikony/mniejszego
   radiusu). Kompaktowy: mniejszy padding i mniejszy radius (--radius-sm) niż
   duże karty (--radius-lg), delikatne neutralne tło (nie fuksja - to
   rzeczowa informacja, nie "dobra wiadomość"), mała ikona z istniejącego
   sprite'u (#icon-nav-availability - zero nowego SVG). */
.trainer-blackout-notice {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--color-surface-alt);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  margin-bottom: 20px;
}
.trainer-blackout-notice[hidden] { display: none; }
.trainer-blackout-notice__icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  color: var(--color-fuchsia);
}
.trainer-blackout-notice__body { min-width: 0; }
.trainer-blackout-notice__heading { font-weight: 700; color: var(--color-ink); margin: 0; }
.trainer-blackout-notice__text { margin: 2px 0 0; color: var(--color-text); }
.trainer-blackout-notice__message { margin: 6px 0 0; color: var(--color-muted); font-size: .92em; }
.trainer-blackout-notice__message[hidden] { display: none; }

/* BETA UX - "Na dobry start" (20.09.2026) §3 polecenia - ten sam wzorzec co
   .panel-card--current-session (jasne, neutralne tło + margin-bottom, żeby
   nie sklejać się z kartą pod spodem). */
.panel-card--onboarding-start { background: var(--color-surface-alt); border-color: var(--color-surface-alt); margin-bottom: 24px; }
.panel-card--onboarding-start[hidden] { display: none; }
.panel-onboarding-checklist { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
/* MAŁY BUG/UX PATCH §3 polecenia - punkt wykonany dostaje spokojniejszy,
   niż-CTA wygląd (przygaszony kolor, bez pogrubienia) - zostaje klikalny. */
.panel-onboarding-checklist__link--done { color: var(--color-muted); font-weight: 500; }
.panel-onboarding-checklist__link--done:hover, .panel-onboarding-checklist__link--done:focus-visible { color: var(--color-text); }
.panel-card__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 14px; }

/* ETAP: SZYBKA NOTATKA W TRAKCIE ZAJĘĆ (19.09.2026) §1 polecenia - karta
   "Zajęcia trwają teraz", widoczna WYŁĄCZNIE gdy klient ma sesję trwającą
   w tym momencie. Ten sam wzorzec co .panel-card--note-prompt wyżej
   (jasne, neutralne tło zamiast fuksji - to informacyjna karta, nie
   "celebracyjny" prompt). */
.panel-card--current-session { background: var(--color-surface-alt); border-color: var(--color-surface-alt); margin-bottom: 24px; }
.panel-card--current-session[hidden] { display: none; }
.panel-current-session__list { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.panel-current-session__item + .panel-current-session__item { padding-top: 16px; border-top: 1px solid var(--color-line); }
.panel-current-session__item-heading { margin: 0 0 8px; font-weight: 700; }
.panel-current-session__dog-rows { display: flex; flex-direction: column; gap: 10px; }
.panel-current-session__dog-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.panel-current-session__dog-name { font-weight: 600; }
.panel-current-session__dog-note-done { color: var(--color-muted); font-size: 0.92em; }

/* Główny, wyróżniony blok dashboardu ("Najbliższe zajęcia") - wizualny
   bohater dashboardu, przebudowany pod zaakceptowaną makietę "Friends ×
   Premium" (polecenie §5): poziomy blok, bardzo lekkie fuchsia-soft tło
   (NIE biel + border-left jak w poprzedniej turze), bez cienia, tekst po
   lewej / pies + odręczne hasło + serca po prawej na desktopie, tekst nad
   psem na mobile. */
.panel-card--featured {
  background: var(--color-fuchsia-soft);
  border: none;
  box-shadow: none;
  padding: 32px 28px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
}
/* KOREKTA "precyzyjne pozycjonowanie" §3 — jawne minmax na obu kolumnach
   (nie "1.3fr 1fr" bez dolnej granicy): kolumna art nigdy nie skurczy się
   poniżej 280px, kolumna treści nigdy nie zabierze jej całej szerokości.
   align-items:center dotyczy kolumny treści (naturalnie krótsza); art
   dostaje własny align-self:stretch niżej, żeby mieć pełną wysokość
   wiersza niezależnie od tego, jak krótki jest tekst. */
@media (min-width: 1024px) {
  .panel-card--featured { grid-template-columns: minmax(0, 1.25fr) minmax(280px, .75fr); align-items: center; gap: 32px; padding: 48px; min-height: 320px; }
}
/* Szerokość zwiększona z 460px (poprzednia tura, przypadkowo za wąska -
   wymuszała niepotrzebne dodatkowe łamanie H2) - polecenie §6 dopuszcza
   zmianę proporcji kolumn, jeśli treść łamie się nienaturalnie. Font H2
   BEZ ZMIAN (2.2rem), tylko więcej miejsca na tę samą treść. */
.panel-card--featured__body { max-width: 520px; }
.panel-card--featured__eyebrow { color: var(--color-fuchsia-hover); }
.panel-card--featured__heading { font-family: var(--font-display); font-weight: 600; font-size: 1.9rem; color: var(--color-ink); margin-top: 10px; }
@media (min-width: 1024px) { .panel-card--featured__heading { font-size: 2.2rem; } }
/* "Friendly premium pass" (13.09.2026) - godzina jest RÓWNIE dużym tekstem
   co data (§1 polecenia - "duży tekst: data / godzina"), tuż pod nią, bez
   dodatkowego odstępu (ta sama wizualna "jedna duża informacja" w dwóch
   liniach). [hidden] w stanie pustym/błędu/ładowania. */
.panel-card--featured__time { font-family: var(--font-display); font-weight: 600; font-size: 1.9rem; color: var(--color-ink); margin-top: 0; }
@media (min-width: 1024px) { .panel-card--featured__time { font-size: 2.2rem; } }
.panel-card--featured__time[hidden] { display: none; }
.panel-card--featured__lead { font-size: 1.05rem; color: var(--color-text); margin-top: 10px; }
.panel-card--featured__location { font-size: .92rem; color: var(--color-muted); margin-top: 4px; }
.panel-card--featured__location[hidden] { display: none; }
/* FINAL PATCH 3 §8 polecenia - "nie przeładowuj hero dodatkowymi
   tekstami": gdy dostępny jest zapisany snapshot Google Maps, nazwa
   lokalizacji sama staje się klikalnym linkiem (patrz script.js) - bez
   podkreślenia domyślnie, wyraźny fuchsia + podkreślenie na hover/focus,
   żeby nadal było jasne, że to link. */
.panel-card--featured__location a { color: var(--color-fuchsia); font-weight: 700; }
.panel-card--featured__location a:hover, .panel-card--featured__location a:focus-visible { text-decoration: underline; color: var(--color-fuchsia-hover); }
.panel-card--featured .panel-card__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 22px;
  padding: 12px 22px;
  border: var(--border-width) solid var(--color-fuchsia);
  border-radius: var(--radius-pill);
  font-weight: 800;
  color: var(--color-fuchsia);
  transition: background-color .15s var(--ease), color .15s var(--ease);
}
.panel-card--featured .panel-card__link:hover, .panel-card--featured .panel-card__link:focus-visible {
  background: var(--color-fuchsia);
  color: var(--color-white);
}

/* DASHBOARD UX (08.10.2026 ticket) §2/§11 - zastępuje usunięty duży,
   pill-shaped "Zobacz grafik" (.panel-card__link wyżej) kompaktowym blokiem
   szybkich akcji - "nie chcemy kolejnego dużego niebieskiego/różowego
   przycisku", małe linki tekstowe w akcencie marki, ten sam wzorzec
   wizualny co już istniejące .schedule-card__maps-link/
   .schedule-card__instruction-link (Mój grafik) - spójność w całym panelu,
   zero nowego stylu przycisku. */
.panel-card--featured__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 18px;
}
.panel-card--featured__actions[hidden] { display: none; }

.panel-card--featured__action-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 700;
  font-size: .9em;
  color: var(--color-fuchsia);
}
.panel-card--featured__action-link[hidden] { display: none; }
.panel-card--featured__action-link:hover,
.panel-card--featured__action-link:focus-visible {
  color: var(--color-fuchsia-hover);
}

/* Mobile (§11 ticketu - "żadnego poziomego overflow, nie zmniejszaj tekstu
   do mikroskopijnego rozmiaru") - jedna kolumna zamiast zawijania w
   nierówne, trudne do skanowania wiersze; font-size NIETKNIĘTY. */
@media (max-width: 480px) {
  .panel-card--featured__actions { flex-direction: column; gap: 2px; }
}
/* Prawa kolumna (<1024px, jedna kolumna, art POD tekstem) - KOREKTA "live
   review 3": poprzednia wersja kładła hasło absolutnie w lewym górnym rogu
   (left:4%;top:2%), co realnie nachodziło na twarz wyśrodkowanego psa.
   Dziś .panel-card--featured__art jest kolumnowym flexem: 1) pies (zwykły
   flow, wyśrodkowany), 2) hasło POD psem (też zwykły flow, nie absolute) -
   kolejność w DOM = kolejność wizualna, zero nachodzenia z definicji.
   Serce zostaje jedynym elementem position:absolute - mały akcent w
   górnym prawym rogu kompozycji, poza obszarem psa. */
.panel-card--featured__art {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 8px;
  min-height: 200px;
}
.panel-card--featured__dog { position: relative; width: 240px; max-width: 70%; height: auto; display: block; }
.panel-card--featured__handwriting {
  position: relative;
  margin-top: 12px;
  width: 140px;
  max-width: 55%;
  height: auto;
  transform: rotate(-2deg);
}
.panel-card--featured__heart { position: absolute; right: 10%; top: 0; width: 26px; height: auto; }
@media (max-width: 640px) {
  .panel-card--featured__dog { max-width: 230px; }
  .panel-card--featured__handwriting { width: 132px; }
}

/* KOREKTA "precyzyjne pozycjonowanie" §3-§5 — desktop (≥1024px): jawny art
   container zamiast luźnych procentów względem całej karty. min-height +
   align-self:stretch (nadpisuje align-items:center rodzica WYŁĄCZNIE dla
   tego dziecka) - art ma zawsze pełną wysokość wiersza, niezależnie od
   długości tekstu po lewej. overflow:hidden - wyłącznie zabezpieczenie na
   wypadek skrajnie wąskiej kolumny (grid ma minmax(280px,...)), NIE
   mechanizm przycinania psa (dog ma object-fit:contain + max-height
   dobrany tak, żeby zmieścić się w całości, patrz niżej). */
@media (min-width: 1024px) {
  .panel-card--featured__art {
    position: relative;
    display: block;
    min-height: 300px;
    align-self: stretch;
    overflow: hidden;
    margin-top: 0;
  }
  /* Pies zakotwiczony bottom-right, NIE centrowany, NIE procentami
     viewportu. max-height (nie height:100%) celowo zostawia czyste pole
     u góry art containera dla hasła/serc - inaczej pies (portretowe
     zdjęcie, wysoki format) wypełniłby całą wysokość kolumny aż po sam
     szczyt i wszedł pod hasło. object-fit:contain gwarantuje, że głowa/
     uszy nigdy nie są przycięte niezależnie od finalnych proporcji boxu. */
  .panel-card--featured__dog {
    position: absolute;
    right: 24px;
    bottom: 0;
    top: auto;
    left: auto;
    width: 295px;
    max-width: 85%;
    height: auto;
    max-height: 235px;
    object-fit: contain;
    object-position: bottom right;
  }
  /* KOREKTA "kontrola po live review" - poprzednia wersja kotwiczyła
     hasło/serca do PRAWEJ krawędzi (`right:215px`/`right:185px`), co
     zakładało szeroki art container (~430-460px, jak na bardzo szerokim
     desktopie). Przy węższym art containerze (kolumna ma tylko
     minmax(280px,...) - realny floor przy 1024-1280px) ten sam `right`
     w pikselach przesuwał lewą krawędź hasła POZA container (280-215-155
     = -90px), a `.panel-card--featured__art` ma `overflow:hidden` - ok.
     90px szerokości hasła było ucinane, zostawał tylko wąski, ledwo
     widoczny skrawek. Naprawione kotwiczeniem do LEWEJ krawędzi małymi,
     stałymi wartościami - matematycznie mieści się w KAŻDEJ szerokości
     art containera (floor 280px), niezależnie od proporcji. Pies jest
     zakotwiczony do DOŁU (bottom:0, max-height:235 w kontenerze
     min-height:300) - jego górna krawędź jest zawsze ≥65px od góry, więc
     hasło/serca umieszczone w paśmie y:0-60px nigdy nie nachodzą na psa,
     niezależnie od szerokości art containera. */
  .panel-card--featured__handwriting {
    left: 20px;
    right: auto;
    top: 18px;
    width: 150px;
    max-width: 55%;
    height: auto;
  }
  .panel-card--featured__heart {
    left: 150px;
    right: auto;
    top: 6px;
    width: 30px;
    height: auto;
  }
}

.panel-footer { padding: 24px 24px 40px; text-align: center; }
.panel-footer p { font-size: .85em; color: var(--color-muted); }
.panel-footer a { color: var(--color-text); font-weight: 700; }

/* Etap 9D — drugorzędne przyciski panelu ("Edytuj", "+ Dodaj psa", "Wybierz
   zdjęcie" itd.) dostają delikatniejszy, "soft premium" hover niż globalny
   .btn--outline (który na reszcie serwisu zalewa się pełnym różem + unosi -
   dobre dla marketingowych CTA, zbyt mocne dla gęstego UI panelu z wieloma
   drugorzędnymi przyciskami obok siebie). WYŁĄCZNIE nadpisanie hover/focus w
   zasięgu .panel-page - globalny .btn/.btn--outline/.btn--primary używany
   na reszcie serwisu pozostaje w 100% nietknięty. */
.panel-page .btn--outline:hover, .panel-page .btn--outline:focus-visible {
  background: var(--color-fuchsia-soft);
  border-color: var(--color-fuchsia);
  color: var(--color-ink);
  transform: none;
}

/* RESPONSYWNOŚĆ PANELU KLIENTA - .btn ma sitewide świadome white-space:
   nowrap + flex-shrink:0 (etykieta przycisku nigdy nie łamie się w środku
   ani nie ściska) - poprawne założenie na reszcie serwisu, gdzie przyciski
   mają szeroki kontekst, ale w wąskich kartach panelu (≤480px) długa,
   samodzielna etykieta bez sąsiada do zawinięcia w rządku fizycznie
   wychodzi poza kartę i poza viewport. Potwierdzone realnym renderem
   Chrome (headless, statyczny harness z rzeczywistym style.css) na 320px:
   CTA "Dołącz do grupy na WhatsApp" (panel/kontakt/, .contact-community
   { display:flex;justify-content:center } wokół pojedynczego przycisku,
   zero sąsiada, do którego mógłby "ustąpić" miejsca) mierzalnie wychodził
   3px poza prawą krawędź. Ten sam mechanizm (samotny, długi .btn bez
   sąsiada w rzędzie) jest realnym ryzykiem gdziekolwiek indziej w panelu
   przy prawdziwych webfontach (Fraunces/DM Sans 800, szersze niż fallback
   fontu użytego w tym teście) - m.in. "Wypełnij ankietę startową"
   (panel/psy/), "Dodaj notatkę z ostatnich zajęć" (panel/notatki/).
   WYŁĄCZNIE w zasięgu .panel-page i WYŁĄCZNIE ≤480px - reszta serwisu
   (marketing, /zapisz-sie, /co-wybrac) i panel na desktopie/tablecie
   zostają całkowicie nietknięte. Buttony, które już mieszczą się na
   jednej linii, wyglądają identycznie (white-space:normal nie zmienia
   niczego, dopóki nie brakuje miejsca) - to czysta siatka bezpieczeństwa,
   nie redesign. */
@media (max-width: 480px) {
  .panel-page .btn {
    white-space: normal;
    text-align: center;
  }
}

/* ---- Ekran logowania (panel/logowanie/index.html) ---- */
.panel-auth-header { padding: 20px 24px; }
@media (min-width: 768px) { .panel-auth-header { padding-inline: 40px; } }
/* Wordmark trochę większy niż w reszcie serwisu (polecenie §6
   "czytelniejszy wordmark") - login jest samodzielną, prawie pustą stroną,
   może sobie na to pozwolić bez konfliktu z resztą layoutu jak w headerze
   marketingowym. Scope wyłącznie do .panel-auth-header - globalny
   .wordmark używany w reszcie serwisu nietknięty. */
.panel-auth-header .wordmark__icon { height: 48px; }
.panel-auth-header .wordmark__logo { height: 36px; }
@media (min-width: 768px) { .panel-auth-header .wordmark__icon { height: 54px; } .panel-auth-header .wordmark__logo { height: 40px; } }
/* Sekcja loginu dostaje własne, lekko odróżnione tło (--color-surface-alt,
   istniejący token) zamiast jednolitego --color-bg całej reszty panelu -
   daje "obecność" bloku zamiast wrażenia przypadkowej pustki wokół
   pływającej białej karty (polecenie §6), bez żadnego nowego koloru. */
.panel-auth { min-height: 70vh; display: flex; align-items: center; padding-block: 24px 64px; background: var(--color-surface-alt); }
.panel-auth__wrap { display: flex; justify-content: center; }
.panel-auth__card {
  width: 100%;
  max-width: 620px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 48px 44px;
}
.panel-auth__heading { position: relative; display: inline-block; padding-bottom: 12px; font-family: var(--font-display); font-weight: 600; font-size: clamp(1.7rem, 2.8vw, 2.1rem); color: var(--color-ink); margin-top: 8px; }
.panel-auth__heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 56px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--color-fuchsia);
}
.panel-auth__lead { font-size: 1em; line-height: 1.55; color: var(--color-text); margin-top: 12px; margin-bottom: 6px; }
.panel-auth__lead-note { font-size: .92em; line-height: 1.5; color: var(--color-muted); margin-bottom: 30px; }
/* KOREKTA po live review §2 — przyczyna "karty w karcie": globalna reguła
   .form (patrz góra pliku) nadaje KAŻDEMU elementowi z klasą "form" WŁASNE
   tło/obrys/cień/padding (ten sam mechanizm, który już wcześniej wymagał
   analogicznego zdjęcia stylu dla .quiz-card .form w /co-wybrac). Formularz
   logowania/ustawiania hasła dostał klasę "form" (żeby odziedziczyć
   stylowanie inputów), ale nigdy nie dostał zdjęcia WŁASNEGO card-chrome -
   stąd druga, wewnętrzna karta. Formularz ma być teraz bezpośrednią
   częścią .panel-auth__card, bez własnego tła/obrysu/cienia/paddingu. */
.panel-auth__card .form { background: none; border: none; box-shadow: none; padding: 0; }
.panel-auth__form .field { margin-bottom: 22px; gap: 10px; }
.panel-auth__form .field:last-of-type { margin-bottom: 28px; }
.panel-auth__form input[type="text"], .panel-auth__form input[type="password"] { min-height: 54px; padding: 15px 18px; font-size: 17px; }
.panel-auth__submit { width: 100%; justify-content: center; min-height: 54px; font-size: 16px; }
/* Final patch przed premierą §2 polecenia - link "Nie pamiętasz hasła?" pod
   polem hasła, zachowuje istniejący wygląd strony logowania (bez redesignu). */
.panel-auth__forgot { text-align: center; margin: -8px 0 18px; }
.panel-auth__forgot:last-child { margin: 18px 0 0; }
#panel-forgot-wrap[hidden] { display: none; }
.panel-auth-footer { padding: 24px 24px 40px; text-align: center; }
.panel-auth-footer p { font-size: .85em; color: var(--color-muted); }
.panel-auth-footer a { color: var(--color-text); font-weight: 700; }

/* =========================================================
   Panel — Moja dyspozycyjność (Panel MVP — etap 2, panel/dyspozycyjnosc/)
   Reużywa .field/.field__error/.form__summary/.btn/.panel-card - zero
   nowego systemu wizualnego, wyłącznie układ specyficzny dla tego
   formularza (karty dni, przedziały godzinowe).
   ========================================================= */

.avail-closed-notice {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 24px;
  margin-bottom: 28px;
}
.avail-closed-notice p:first-child { font-weight: 700; color: var(--color-ink); margin-bottom: 12px; }
.avail-closed-notice__contacts { display: flex; flex-wrap: wrap; gap: 10px 24px; }
.avail-closed-notice__contacts a { font-weight: 700; color: var(--color-fuchsia); }
.avail-closed-notice__contacts a:hover, .avail-closed-notice__contacts a:focus-visible { color: var(--color-fuchsia-hover); }

.avail-saved-note { font-size: .9em; color: var(--color-muted); margin: -10px 0 24px; }
.avail-saved-note[hidden] { display: none; }

/* Final patch przed premierą §7/§8/§9 polecenia - krótka informacja o dniu
   pojawienia się grafiku (§9) + blok "Stały termin" zastępujący cały
   formularz dla klientów, którzy nie podają cotygodniowej dyspozycyjności
   (§8) - reużywa istniejący .panel-main__note (już zdefiniowany globalnie
   wyżej w tym pliku), zero nowego systemu wizualnego poza samym
   kontenerem `.avail-fixed-notice`. */
.avail-fixed-notice {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 24px;
  margin-bottom: 28px;
}
.avail-fixed-notice[hidden] { display: none; }
/* FINALNY TICKET - BLACKOUT TRENERA (20.09.2026) §3 polecenia - dawny,
   samodzielny `.avail-trainer-blackout-notice` (wyglądał jak kolejna duża
   karta tygodnia, "zlewał się" z przyciskami) USUNIĘTY - `#avail-trainer-
   blackout-notice` w HTML używa dziś współdzielonego `.trainer-blackout-
   notice` (patrz komponent przy .panel-card--note-prompt wyżej w pliku),
   identycznego z dashboardem. */
.avail-fixed-notice__heading { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--color-ink); margin-bottom: 8px; }
/* Fix "stały termin, tydzień bez zajęć" - druga, dyskretna linia z domyślnym
   terminem na kolejne tygodnie (widoczna WYŁĄCZNIE przy "changed"/
   "no_session" - patrz script.js), ten sam styl co .panel-main__note. */
.avail-fixed-notice__default { font-size: .9em; color: var(--color-muted); margin-top: 6px; }
.avail-fixed-notice__default[hidden] { display: none; }
.avail-fixed-notice__hint { font-size: .88em; color: var(--color-muted); margin-top: 10px; }
.avail-fixed-notice__hint a { color: var(--color-fuchsia); font-weight: 700; }
.avail-fixed-notice__cta { margin-top: 14px; }
.avail-fixed-notice__confirmed { font-size: .9em; color: var(--color-muted); margin-top: 6px; }
.avail-fixed-notice__confirmed[hidden] { display: none; }
.avail-fixed-notice__confirmed a { color: var(--color-fuchsia); font-weight: 700; }

/* FINAL PATCH 2/4 §C polecenia - klient ze stałym terminem samodzielnie
   zgłasza wyjątek na TEN tydzień ("inne godziny"/"nie dam rady"). */
.avail-fixed-notice__exception {
  margin-top: 18px;
  padding-top: 18px;
  border-top: var(--border-width) solid var(--color-line);
}
.avail-fixed-notice__exception[hidden] { display: none; }
.avail-fixed-notice__exception-question { font-size: .92em; font-weight: 700; color: var(--color-ink); margin: 0 0 10px; }
.avail-fixed-notice__exception-actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* FINAL PATCH 2D §1 polecenia - min. 44px tap target (dziedziczony
   .btn--small ma 40px) - scoped WYŁĄCZNIE do akcji na tej karcie. */
.avail-fixed-notice__exception-actions .btn { min-height: 44px; }

/* FINAL PATCH 2/4 §A/§B polecenia - "stała dyspozycyjność" (per pies):
   podsumowanie zamiast pustego formularza co tydzień, ten sam wzorzec
   karty co .avail-fixed-notice. */
.avail-recurring-notice {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 24px;
  margin-bottom: 28px;
}
.avail-recurring-notice[hidden] { display: none; }
.avail-recurring-notice__summary { font-size: .92em; line-height: 1.7; color: var(--color-text); margin: 10px 0 18px; }
.avail-recurring-notice__actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* FINAL PATCH 2D §1 polecenia - min. 44px tap target (dziedziczony
   .btn--small ma 40px) - scoped WYŁĄCZNIE do akcji na tej karcie. */
.avail-recurring-notice__actions .btn { min-height: 44px; }

/* FINAL PATCH 2D §1 polecenia - na 360px przyciski akcji (3 na karcie
   stałej dyspozycyjności, 2 na karcie stałego terminu) wychodziły poza
   kartę - dawny `flex-wrap:wrap` z auto-width przyciskami nie gwarantował
   mieszczenia się długich tekstów w wąskiej karcie. Pod 480px: pełna
   szerokość, jedna kolumna, tekst może się zawijać (nigdy przycięty),
   nic nie wychodzi poza `padding` karty (dziedziczone z .avail-fixed-
   notice/.avail-recurring-notice, oba mają `box-sizing:border-box`
   z globalnego resetu). */
@media (max-width: 480px) {
  .avail-fixed-notice__exception-actions,
  .avail-recurring-notice__actions {
    flex-direction: column;
    align-items: stretch;
  }
  .avail-fixed-notice__exception-actions .btn,
  .avail-recurring-notice__actions .btn {
    width: 100%;
    white-space: normal;
    text-align: center;
  }
}

/* FINAL PATCH 2/4 §A polecenia - "To moja stała dyspozycyjność", teraz
   pełnoszeroki kafelek (FINAL PATCH 2B §C - dawny ciasny checkbox
   zgłoszony jako za mały, szczególnie na mobile). */
.avail-recurring-field { margin-bottom: 24px; }
.avail-recurring-field[hidden] { display: none; }
.avail-recurring-tile {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  width: 100%;
  min-height: 44px;
  padding: 16px 20px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.avail-recurring-tile:has(.avail-recurring-tile__input:checked) { background: var(--color-fuchsia-soft); border-color: var(--color-fuchsia); }
.avail-recurring-tile:has(.avail-recurring-tile__input:focus-visible) { outline: 3px solid var(--color-fuchsia); outline-offset: 2px; }
.avail-recurring-tile__input { width: 22px; height: 22px; flex-shrink: 0; margin-top: 2px; accent-color: var(--color-fuchsia); }
.avail-recurring-tile__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.avail-recurring-tile__heading { font-family: var(--font-body); font-weight: 700; font-size: 15px; color: var(--color-ink); }
.avail-recurring-tile__desc { font-size: .9em; line-height: 1.45; color: var(--color-muted); }
@media (max-width: 480px) {
  .avail-recurring-tile { padding: 16px; }
}

/* FINAL PATCH 2B §A/§I polecenia - przełącznik dwóch tygodni ("21-27
   września"/"28 września-4 października"), zastępuje dawny dynamiczny H1 +
   #avail-week-range (usunięte - nagłówek jest dziś statyczny). */
.avail-week-switch { display: flex; flex-wrap: wrap; gap: 10px; margin: 4px 0 20px; }
.avail-week-switch[hidden] { display: none; }
.avail-week-switch__btn {
  flex: 1 1 200px;
  min-height: 48px;
  padding: 12px 18px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: .95em;
  color: var(--color-ink);
  text-align: center;
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.avail-week-switch__btn:hover { border-color: var(--color-fuchsia); }
.avail-week-switch__btn:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 2px; }
.avail-week-switch__btn[aria-pressed="true"] { background: var(--color-fuchsia); border-color: var(--color-fuchsia); color: #fff; }
@media (max-width: 480px) {
  .avail-week-switch { flex-direction: column; }
  .avail-week-switch__btn { flex: 1 1 auto; }
}

/* FINAL PATCH 2B §F polecenia - stan "brak dyspozycyjności w tym tygodniu",
   ten sam wzorzec karty co .avail-fixed-notice/.avail-recurring-notice. */
.avail-no-availability-notice {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 24px;
  margin-bottom: 28px;
}
.avail-no-availability-notice[hidden] { display: none; }
.avail-no-availability-notice p { font-size: .96em; color: var(--color-ink); margin: 0 0 16px; }

/* Etap 9 §1 — stan sukcesu po zapisie dyspozycyjności, zastępuje formularz (nie usuwa go z DOM). */
.avail-success {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  max-width: 60ch;
}
.avail-success[hidden] { display: none; }
.avail-success__heading { font-family: var(--font-display); font-weight: 600; font-size: 1.4rem; color: var(--color-ink); margin-bottom: 14px; }
.avail-success p { font-size: .96em; line-height: 1.55; color: var(--color-text); margin-bottom: 12px; }
.avail-success__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 18px; }

/* Etap 9 §2 — rodzaje zajęć, multi-select checkboxy. */
.avail-activities { border: none; padding: 0; margin: 0 0 28px; }
.avail-activities__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px 16px; margin-top: 12px; }
.avail-activity-checkbox { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: .95em; color: var(--color-ink); }
.avail-activity-checkbox input { width: 18px; height: 18px; flex-shrink: 0; accent-color: var(--color-fuchsia); }
.avail-activity-checkbox input:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
.avail-activities__error { margin-top: 10px; }

/* "Micro polish" (13.09.2026) - selektor psa jako chips/karty zamiast
   natywnego <select> (§2 polecenia), pokazywany dla KAŻDEJ liczby psów
   ≥1. Pusty stan (0 psów) spójny z resztą prostych pól formularza
   (.field) i istniejącym wzorcem pustego stanu (.dogs-empty). */
.avail-no-dogs { color: var(--color-muted); margin-bottom: 24px; }
.avail-dog-field { margin-bottom: 28px; }
.avail-dog-field[hidden] { display: none; }
.avail-dog-field__label { font-family: var(--font-body); font-weight: 700; font-size: .95em; color: var(--color-ink); margin: 0 0 10px; }
.avail-dog-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.avail-dog-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px 8px 8px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.avail-dog-chip:has(.avail-dog-chip__input:checked) { background: var(--color-fuchsia-soft); border-color: var(--color-fuchsia); }
.avail-dog-chip:has(.avail-dog-chip__input:focus-visible) { outline: 2px solid var(--color-fuchsia); outline-offset: 2px; }
.avail-dog-chip__input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.avail-dog-chip__avatar { position: relative; flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; overflow: hidden; background: var(--color-surface-alt); }
.avail-dog-chip__photo, .avail-dog-chip__placeholder { width: 32px; height: 32px; border-radius: 50%; }
.avail-dog-chip__photo { display: block; object-fit: cover; }
.avail-dog-chip__photo[hidden] { display: none; }
.avail-dog-chip__placeholder { display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 600; font-size: .9em; color: var(--color-fuchsia); }
.avail-dog-chip__placeholder[hidden] { display: none; }
.avail-dog-chip__name { font-weight: 700; font-size: .95em; color: var(--color-ink); }
/* KOREKTA MODELU KARNETÓW + UX DYSPOZYCYJNOŚCI (§C polecenia) - "Wszystkie
   psy" (bez avatara) dostaje delikatną przerywaną obwódkę, żeby odróżnić
   się od kart konkretnych psów - reszta wyglądu WSPÓLNA z .avail-dog-chip. */
.avail-dog-chip--all { border-style: dashed; padding-left: 16px; }
.avail-dog-field__error { margin-top: 10px; }

/* "W tym tygodniu nie mam możliwości..." - traktowana jak zwykły checkbox
   w karcie, spójnie z resztą formularza (nie osobny komponent "switch"). */
.avail-no-availability {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 18px 20px;
  margin-bottom: 24px;
}
.avail-checkbox { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; font-family: var(--font-body); font-weight: 600; font-size: 15px; color: var(--color-ink); }
.avail-checkbox input[type="checkbox"] { width: 20px; height: 20px; flex-shrink: 0; margin-top: 1px; accent-color: var(--color-fuchsia); }
.avail-checkbox input[type="checkbox"]:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }

.avail-days { display: flex; flex-direction: column; gap: 16px; margin-bottom: 28px; }
.avail-days[hidden] { display: none; }

/* POPRAWKA MOBILE (08.10.2026) - ROOT CAUSE znalezionego bugu "karta
   rozszerza się poza telefon po dodaniu przedziału godzin": `.avail-day`
   to <fieldset> (patrz avail-day-template w panel/dyspozycyjnosc/
   index.html), a <fieldset> ma długo znaną, specyficzną dla UA
   właściwość domyślną `min-width: min-content` - fieldset ODMAWIA
   zmniejszenia się poniżej intrinsic-width swojej treści, NIEZALEŻNIE od
   `width:100%`/flex-stretch ustawionego na jego dzieciach (to jest
   OSOBNA, nadrzędna reguła, nie to samo co min-width dzieci - żadna z
   poprzednich poprawek 2D/2F/2G jej nie dotykała, bo wszystkie fixowały
   WYŁĄCZNIE potomne flex-itemy, nigdy sam fieldset). Dlatego problem
   pojawiał się dokładnie PO dodaniu przedziału - dopiero wtedy w DOM
   pojawia się <input type="time">/<select> o realnej intrinsic
   szerokości, która na 320-430px przekracza viewport i fieldset wymusza
   tę szerokość na całą kartę. `min-width:0` jest bezwarunkowe (nie w
   media query) - to czysto strukturalna korekta błędnego domyślnego
   zachowania UA, nie decyzja projektowa specyficzna dla mobile: na
   desktopie karta i tak jest szersza niż intrinsic-min treści, więc
   usunięcie tej "podłogi" niczego tam wizualnie nie zmienia. */
.avail-day {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 18px 20px;
  margin: 0;
  min-width: 0;
  transition: border-color .15s var(--ease);
}
.avail-day:has(.avail-day__checkbox:checked) { border-color: var(--color-fuchsia); }

/* FINAL PATCH 2F polecenia - NAPRAWIA regresję z Patch 2D: `overflow-wrap:
   break-word` na `.avail-day__name` (niżej) w połączeniu z `min-width:0`
   pozwalało przeglądarce łamać nazwę dnia W ŚRODKU SŁOWA ("Poniedziałek" ->
   "Poni/edzi/ałek"), gdy w wierszu faktycznie brakowało miejsca (patrz
   root cause w raporcie tej tury - podwójny padding .section-shell+.form).
   Zamiast tego: `.avail-day__legend` dostaje `flex-wrap:wrap` - jeśli
   [checkbox+nazwa dnia] i status nie mieszczą się razem w jednym wierszu,
   TO STATUS (nie nazwa dnia) schodzi pod spód jako całość. Nazwa dnia ma
   `white-space:nowrap` - fizycznie nie da się jej złamać w środku słowa. */
.avail-day__legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  width: 100%;
  padding: 0;
}
.avail-day__toggle { display: flex; align-items: center; gap: 12px; cursor: pointer; min-width: 0; }
.avail-day__checkbox { width: 22px; height: 22px; flex-shrink: 0; accent-color: var(--color-fuchsia); }
.avail-day__checkbox:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
.avail-day__name { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--color-ink); white-space: nowrap; }
.avail-day__state { font-size: 13px; font-weight: 700; color: var(--color-muted); white-space: nowrap; flex-shrink: 0; }
.avail-day:has(.avail-day__checkbox:checked) .avail-day__state { color: var(--color-fuchsia); }

/* FINAL PATCH 2G polecenia - Patch 2F naprawił łamanie słowa, ale
   `flex-wrap:wrap` dawał NIESPÓJNY układ: krótsze nazwy (Wtorek/Środa)
   mieściły status obok siebie, a "Poniedziałek" (najdłuższa nazwa)
   zrzucał status pod spód - różne dni wyglądały inaczej. Zamiast wrapować,
   CAŁY wiersz przechodzi na mobile na CSS Grid o 3 STAŁYCH kolumnach
   (checkbox/nazwa/status, `auto minmax(0,1fr) auto` - dokładnie wzorzec z
   polecenia) + typografia zmniejszona na tyle, żeby NAJDŁUŻSZA możliwa
   kombinacja (Poniedziałek + Niedostępny) zawsze mieściła się w jednym
   wierszu na 360-480px, bez łamania/ucinania/przewijania. `.avail-day__toggle`
   (dawniej flex, teraz `display:contents`) "znika" jako własny box, ale
   zachowuje semantykę <label> - klik na checkbox LUB nazwę dnia nadal
   przełącza dzień, jego dzieci (checkbox + nazwa) stają się bezpośrednimi
   elementami grida i trafiają automatycznie do kolumn 1/2 w kolejności
   DOM, status do kolumny 3. */
@media (max-width: 480px) {
  .avail-day__legend {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
  }
  .avail-day__toggle { display: contents; }
  .avail-day__checkbox { cursor: pointer; }
  .avail-day__name { font-size: 0.95rem; white-space: nowrap; cursor: pointer; }
  .avail-day__state { font-size: 12px; white-space: nowrap; }
}
/* Druga, węższa warstwa dla najciaśniejszych telefonów (360px z polecenia)
   - domyka lukę: sama warstwa ≤480px ma zapas na 390-480px, ale przy
   360px "Poniedziałek" + "Niedostępny" w tamtych rozmiarach fontu wciąż
   był na granicy. Copy NIEZMIENIONE (ten sam pełny tekst "Niedostępny") -
   wyłącznie mniejszy font, zgodnie z jawnie dozwolonym zakresem 11-12px. */
@media (max-width: 375px) {
  .avail-day__name { font-size: 0.85rem; }
  .avail-day__state { font-size: 11px; }
}

.avail-day__body { margin-top: 16px; padding-top: 16px; border-top: var(--border-width) solid var(--color-line); }
.avail-day__body[hidden] { display: none; }

.avail-day__slots { display: flex; flex-direction: column; gap: 12px; margin-bottom: 14px; }
/* FINAL PATCH 2D §2 polecenia - min. 44px tap target (dziedziczony
   .btn--small ma 40px) - scoped WYŁĄCZNIE do tego przycisku, nie do
   globalnej klasy .btn--small używanej gdzie indziej w panelu. */
.avail-day__add { min-height: 44px; }

.avail-slot { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; min-width: 0; }
.avail-slot__field { flex: 1 1 110px; min-width: 110px; margin-bottom: 0; }
.avail-slot__field label { font-size: 13px; }
/* POPRAWKA MOBILE (08.10.2026) - zabezpieczenie uzupełniające fix fieldsetu
   wyżej: natywne kontrolki iOS Safari (input[type=time]/select) same w
   sobie też mogą mieć niezerowy "automatic minimum size" jako potomkowie
   .field (display:flex;flex-direction:column) - jawne min-width:0
   bezpośrednio na kontrolkach, scoped WYŁĄCZNIE do tego komponentu (nie
   do globalnej .form input/.field input używanej na innych stronach),
   gwarantuje że mogą się skurczyć do pełnej szerokości:100% nawet gdyby
   silnik przeglądarki inaczej liczył ich intrinsic minimum. */
.avail-slot__field input[type="time"],
.avail-slot__field select { min-width: 0; }
/* FINAL PATCH 2D §2 polecenia - zastępuje dawny samotny "×" (ikona bez
   widocznego tekstu) czytelnym przyciskiem "Usuń przedział" - zawsze, nie
   tylko na mobile (jaśniejsze na pierwszy rzut oka wszędzie). */
.avail-slot__remove {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  height: 44px;
  padding: 0 14px;
  border-radius: var(--radius-sm);
  color: var(--color-muted);
  background: transparent;
  border: var(--border-width) solid var(--color-line);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}
.avail-slot__remove-icon { width: 16px; height: 16px; flex-shrink: 0; }
.avail-slot__remove:hover, .avail-slot__remove:focus-visible { color: var(--color-error); border-color: var(--color-error); }
.avail-slot__remove[hidden] { display: none; }

.avail-day__error { margin-top: 10px; margin-bottom: 0; }

.avail-note-field textarea { min-height: 88px; }
/* KOREKTA "final polish" §14 - pole istniało już wcześniej ("Dodatkowa
   informacja"), backend (kolumna `note` na ppfb_availability) już je
   czytał/zapisywał - WYŁĄCZNIE relabeling, zero zmian backendu/migracji. */
.avail-note-field__eyebrow { margin-bottom: 6px; color: var(--color-fuchsia-hover); }
.avail-note-counter { font-size: 12px; color: var(--color-muted); text-align: right; margin-top: 6px; }
.avail-note-counter--limit { color: var(--color-error); font-weight: 700; }

/* FINAL PATCH 2D §2 polecenia - KOREKTA breakpointu: dawny próg 389px
   zostawiał 390px (jedna z dwóch szerokości wymienionych w teście
   polecenia) tuż POZA regułą, więc pola Od/Do/Forma próbowały się mieścić
   obok siebie dokładnie tam, gdzie brakowało na to miejsca. Podniesiony do
   480px (spójne z resztą nowych komponentów tej strony - patrz
   .avail-week-switch/.avail-recurring-tile) - każdy przedział jest teraz
   w pełni pionowy (Od / Do / Forma / Usuń przedział), pełna szerokość,
   min. 44px wysokości na każdym elemencie interaktywnym. */
@media (max-width: 480px) {
  .avail-slot { flex-direction: column; align-items: stretch; gap: 10px; }
  .avail-slot__field { flex-basis: auto; width: 100%; min-width: 0; }
  .avail-slot__remove { width: 100%; justify-content: center; white-space: normal; }
  .avail-day__add { width: 100%; }
}

/* FINAL PATCH 2F polecenia - ROOT CAUSE części 1 zgłoszonego bugu: `<form
   id="avail-form" class="form">` dziedziczy generyczny, sitewide `.form`
   card-chrome (tło+ramka+cień+PADDING 28px/20px), który jest DRUGĄ,
   zagnieżdżoną warstwą paddingu WEWNĄTRZ już wypełnionego .section-shell
   (18px na mobile) i .wrap (24px) - "karta w karcie" zjadała ~124px
   szerokości na 360px (2×24 + 2×18 + 2×20), zanim .avail-day w ogóle
   dostał swój WŁASNY padding (18px/20px). Suma tych czterech niezależnie
   ustalonych warstw paddingu zostawiała za mało miejsca w wierszu nazwy
   dnia, co (patrz wyżej) uruchamiało łamanie "Poniedziałek" w środku
   słowa. Naprawione WYŁĄCZNIE dla `#avail-form` (ID, nie generyczna klasa
   `.form` używana też na innych stronach/formularzach serwisu) i WYŁĄCZNIE
   pod 480px - desktop/`.form` sitewide bez zmian. */
@media (max-width: 480px) {
  #avail-form { padding: 20px 10px; }
  .avail-day { padding: 16px 12px; }
}

/* =========================================================
   Panel — Mój grafik (Panel MVP — etap 3, panel/grafik/) i karta
   "Najbliższe zajęcia" na Dashboardzie. Read-only dla klienta — karty
   zamiast tabeli, żeby dobrze skanować się na telefonie (§23 polecenia).
   ========================================================= */

.schedule-list { display: flex; flex-direction: column; gap: 16px; }

.schedule-empty {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  color: var(--color-muted);
  font-size: .95em;
  line-height: 1.5;
}

.schedule-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 22px 24px;
}
.schedule-card--cancelled { background: var(--color-surface-alt); border-color: var(--color-line); }
/* Mały patch grafiku (16.09.2026) - UX poprawka: badge "Nieobecność" ma być
   wyraźnie widoczny w Historii współpracy, ten sam tint co "Anulowane"
   (istniejący token, nie nowy kolor) odróżnia kartę od zwykłego "Odbyte". */
.schedule-card--no-show { background: var(--color-surface-alt); border-color: var(--color-line); }

.schedule-card__day { font-family: var(--font-display); font-weight: 600; font-size: 1.1rem; color: var(--color-ink); }
.schedule-card__time { font-size: .95em; color: var(--color-text); margin-top: 2px; }

.schedule-card__badge {
  display: inline-flex;
  align-items: center;
  margin-top: 10px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: var(--color-error);
  color: var(--color-white);
  font-size: 12px;
  font-weight: 700;
}
.schedule-card__badge[hidden] { display: none; }

.schedule-card__body { margin-top: 14px; padding-top: 14px; border-top: var(--border-width) solid var(--color-line); }
.schedule-card__title { font-weight: 700; color: var(--color-ink); }
/* ETAP: KLASY I OBRONA W HISTORII WSPÓŁPRACY (18.09.2026) - mała pigułka z
   typem zajęć, WYŁĄCZNIE na wpisach historii pochodzących z wydarzeń (ten
   sam wzorzec pigułki co .wydarzenie-card__type w panelu wydarzeń). */
.schedule-card__type {
  display: inline-flex;
  align-items: center;
  margin-top: 4px;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-fuchsia-soft);
  font-size: .78em;
  font-weight: 700;
  color: var(--color-fuchsia-hover);
}
.schedule-card__type[hidden] { display: none; }
.schedule-card__location { font-size: .92em; color: var(--color-text); margin-top: 4px; }
/* FINAL PATCH 3 §7 polecenia - link do zapisanego snapshotu Google Maps,
   ten sam wzorzec co .schedule-card__instruction-link (patrz niżej w
   pliku) - min-height 44px, żeby był łatwy do kliknięcia na mobile. */
/* Patch 3B - `inline-flex` (block-level tekst) pozwalał temu linkowi i
   .schedule-card__instruction-link płynąć obok siebie w jednej linii,
   gdy było na to miejsce (desktop) - na mobile "poprawność" była
   przypadkowa, wynikała wyłącznie z braku miejsca (zawijanie). `flex`
   (blokowy) wymusza pełną szerokość, więc oba linki są ZAWSZE, na każdej
   szerokości, jeden pod drugim - mobile wygląda identycznie jak wcześniej. */
.schedule-card__maps-link { display: flex; align-items: center; min-height: 44px; margin-top: 6px; font-weight: 700; font-size: .9em; color: var(--color-fuchsia); }
.schedule-card__maps-link[hidden] { display: none; }
.schedule-card__maps-link:hover, .schedule-card__maps-link:focus-visible { color: var(--color-fuchsia-hover); }
.schedule-card__note { font-size: .9em; color: var(--color-muted); margin-top: 10px; }

/* ---- Karta "Najbliższe zajęcia" na Dashboardzie (panel/index.html) ---- */
.panel-card__schedule-day { font-family: var(--font-display); font-weight: 600; color: var(--color-ink); }
.panel-card__schedule-meta { font-size: .92em; color: var(--color-text); margin-top: 4px; }

/* =========================================================
   Panel — Moje cele — FINALNY MODEL (etap 9E, panel/cele/). Cele są per
   user_id+dog_id (nie per miesiąc) - patrz CLAUDE.md. Etap pracy pokazany
   jako spokojny badge (albo neutralny tekst, gdy jeszcze nieustalony,
   §21 polecenia) - nigdy "brak danych"/"null". Historia (completed/
   archived) NEUTRALNA - nigdy czerwony komunikat "nie udało się"
   (--color-error zarezerwowany dla błędów formularzy, nie dla tego).
   ========================================================= */

.goals-current { display: flex; flex-direction: column; gap: 16px; margin-bottom: 32px; }
#goals-paused { display: flex; flex-direction: column; gap: 16px; margin-bottom: 32px; }

.goal-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 22px 24px;
}
/* Etap 9E.4a §7 polecenia - mobile spacing: mniej pionowych odstępów na
   360-390px, bez ściskania samego tekstu (font-size/line-height bez zmian) -
   karta ma być krótka, ale nadal czytelna z dużymi tap-targetami. */
@media (max-width: 480px) {
  .goal-card { padding: 18px 18px; }
  .goal-card__text { margin-bottom: 8px; }
  .goal-card__element-row, .goal-card__desired-outcome { margin-bottom: 8px; }
  /* Etap 9E.4d §1/§2 polecenia - stage-row zaczyna nowy "blok" karty
     (stage badge + opis), stąd większy odstęp niż zwykłe 8px na mobile -
     margin-top+margin-bottom collapsują z sąsiadami do tej większej wartości
     niezależnie od tego, czym kończy się poprzedni blok (edycja celu głównego
     otwarta czy nie, element-row obecny czy nie). */
  .goal-card__stage-row { margin-top: 18px; margin-bottom: 18px; }
  .goal-card__stage { margin-bottom: 6px; }
  .goal-card__training-count { margin-bottom: 10px; }
}
.goal-card__text { font-size: 1.05em; line-height: 1.5; color: var(--color-ink); margin-bottom: 12px; }
/* DOPRECYZOWANIE MODELU CELÓW (24.09.2026) - "Cel z zajęć" jako osobny,
   dyskretny badge NAD tytułem (nigdy sklejony z nazwą celu - §UI polecenia),
   neutralny (nie fuksja - ten kolor jest już zajęty przez .panel-status-badge
   gdzie indziej w panelu). */
.goal-card__origin-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  color: var(--color-muted);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .03em;
  margin-bottom: 8px;
}
.goal-card__origin-badge[hidden] { display: none; }

.goal-card__stage {
  display: inline-flex;
  align-items: center;
  padding: 5px 14px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 700;
  background: var(--color-yellow-soft);
  color: var(--color-ink);
  margin-bottom: 12px;
}
/* Etap jeszcze nieustalony (stage IS NULL) - ten sam neutralny, przygaszony
   chip co status ankiety startowej w innych miejscach panelu, nigdy alarm. */
.goal-card__stage--pending { background: var(--color-surface-alt); color: var(--color-muted); font-weight: 600; }

.goal-card__meta { font-size: .82em; color: var(--color-muted); margin-bottom: 4px; }
.goal-card__training-count { font-size: .9em; color: var(--color-text); margin-bottom: 14px; }

/* Etap 9E.2 - desired_outcome/element/target/stage-picker na karcie celu. */
.goal-card__desired-outcome { font-size: .92em; color: var(--color-text); margin-bottom: 10px; }
.goal-card__desired-outcome[hidden] { display: none; }
.goal-card__element-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; font-size: .9em; color: var(--color-text); }
.goal-card__element-row[hidden] { display: none; }
.goal-card__element-picker { margin: 4px 0 12px; }
.goal-card__element-picker[hidden] { display: none; }
/* Etap 9E.4d §1 polecenia - edycja "Jaki jest Twój główny cel?" na karcie:
   mały odstęp Edytuj->label, normalny odstęp helper->textarea, mały odstęp
   textarea->Zapisz. Traktowana jako blok A razem z current_element/
   desired_outcome nad nią. */
.goal-card__do-edit { margin-top: 4px; }
.goal-card__do-form { margin-top: 8px; }
.goal-card__do-form[hidden] { display: none; }
.goal-card__do-form > .goals-question__label { margin-bottom: 4px; }
.goal-card__do-form > .field__hint { margin-bottom: 12px; }
.goal-card__do-form > textarea { margin-bottom: 8px; }
/* Etap 9E.4d §1/§2 polecenia - stage-row (blok B: badge+opis etapu) dostaje
   WIĘKSZY odstęp od bloku A (desired_outcome/edycja) i od bloku C (training
   count + "Trening zrobiony") niż zwykłe odstępy wewnątrz bloku - margin-top
   collapsuje z margin-bottom poprzedniego elementu do wartości większej z
   dwóch, więc gap jest zagwarantowany niezależnie od tego, czym kończy się
   blok A (sam desired_outcome, otwarta edycja, czy element-row). */
.goal-card__stage-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 24px; margin-bottom: 24px; }
.goal-card__stage-row[hidden] { display: none; }
.btn--link { background: none; border: none; padding: 0; color: var(--color-fuchsia); font-weight: 600; font-size: .85em; text-decoration: underline; cursor: pointer; }
.goal-card__stage-hint { flex-basis: 100%; font-size: .88em; color: var(--color-muted); line-height: 1.5; margin: 0; }
.goal-card__stage-hint[hidden] { display: none; }
.goal-card__stage-picker { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex-basis: 100%; }
.goal-card__stage-picker select { max-width: 260px; }
.goal-card__checkin-panel { margin-top: 14px; padding: 16px; background: var(--color-surface-alt); border-radius: var(--radius-md); }
.goal-card__checkin-panel[hidden] { display: none; }
/* Etap 9E.4e §10 polecenia - resume choice cards: CAŁY kafelek klikalny
   (nie osobny przycisk + akapit obok), jedna karta pod drugą, min. 44px
   tap-target - dotyczy WYŁĄCZNIE wyboru "Szybkie sprawdzenie"/"Przejdź
   pełną ankietę" po kliknięciu "Wznów". */
.resume-choice-list { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; }
.resume-choice-card {
  display: block;
  width: 100%;
  min-height: 44px;
  text-align: left;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  cursor: pointer;
  transition: border-color .15s var(--ease);
}
.resume-choice-card:hover, .resume-choice-card:focus-visible { border-color: var(--color-fuchsia); outline: none; }
.resume-choice-card__title { display: block; font-weight: 700; font-size: .95em; color: var(--color-ink); margin-bottom: 4px; }
.resume-choice-card__desc { display: block; font-size: .85em; color: var(--color-muted); line-height: 1.4; }
.goal-card__foundations-note { font-size: .85em; color: var(--color-muted); font-style: italic; margin-top: 10px; }
.goal-card__foundations-note[hidden] { display: none; }
.goal-card--paused { opacity: .92; }

.goal-card__actions { display: flex; flex-wrap: wrap; gap: 12px; }
/* Etap 9E.4 §10/§11 polecenia - hierarchia zamiast rzędu jednakowych
   przycisków: "Trening zrobiony" duże, prawie pełna szerokość, łatwy tap
   jednym kciukiem; "Dodaj notatkę" drugorzędne pod nim; reszta akcji
   (checkin/pauza/cel osiągnięty) dyskretnie niżej jako tekstowe linki. */
.goal-card__training-btn--primary { display: block; width: 100%; text-align: center; margin-bottom: 10px; padding-top: 14px; padding-bottom: 14px; font-size: 1.02em; }
.goal-card__note-btn { display: block; width: 100%; text-align: center; margin-bottom: 14px; }
.goal-card__note-panel { margin-bottom: 14px; }
.goal-card__note-panel[hidden] { display: none; }
.goal-card__note-panel textarea { width: 100%; }
/* Etap 9E.4b §2/§3 polecenia - WYŁĄCZNIE 2 linki w tym rzędzie ("Sprawdź,
   gdzie jesteśmy" / "Więcej") - blisko siebie, nie rozrzucone po karcie
   (mniejszy gap niż dawne 16px na 4 linki); reszta rzadkich akcji chowa się
   w .goal-card__more-panel, lekkie rozwinięcie pod linkiem, bez modala.
   §4 polecenia - min. 44px tappable mimo wizualnie małego linku (padding
   niewidoczny, bez tła) - scoped tylko do tej karty, nie globalnie .btn--link. */
.goal-card__actions--secondary { gap: 10px; padding-top: 4px; border-top: var(--border-width) solid var(--color-line); }
.goal-card__actions--secondary .btn--link,
.goal-card__more-panel .btn--link { display: inline-flex; align-items: center; min-height: 44px; padding: 10px 2px; }
.goal-card__more-panel { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; margin-top: 6px; }
.goal-card__more-panel[hidden] { display: none; }
.goal-card__more-toggle[hidden] { display: none; }
/* Etap 9E.4c §3/§4/§6 polecenia - na mobile "Sprawdź, gdzie jesteśmy" i
   "Więcej" też jedna akcja na linię (nie w jednym rzędzie) - karta ma nie
   rozciągać linków na pełną szerokość, tylko ułożyć je pionowo, zwarcie. */
@media (max-width: 480px) {
  .goal-card__actions--secondary { flex-direction: column; align-items: flex-start; gap: 2px; }
}
@media (min-width: 640px) {
  .goal-card__training-btn--primary, .goal-card__note-btn { width: auto; display: inline-flex; justify-content: center; }
  .goal-card__training-btn--primary { min-width: 220px; }
}

/* Etap 9E.4 §12 polecenia - krótka, lekka celebracja po "Trening zrobiony"
   (kilka serduszek unoszących się znad przycisku) - nigdy pełnoekranowa,
   nie wymaga zamykania, pointer-events:none żeby nigdy nie blokować tapów. */
.training-celebration { position: fixed; transform: translate(-50%, -8px); pointer-events: none; z-index: 999; width: 1px; height: 1px; }
/* Etap 9E.4d §4 polecenia - WYŁĄCZNIE serduszka (♡/♥), różne rozmiary
   (ustawiane inline per-piece w JS), rotacja/czas trwania też per-piece -
   efekt ma czuć się jak wysłanie serca w Messengerze, nie konfetti. */
.training-celebration__piece {
  position: absolute;
  left: 0;
  top: 0;
  line-height: 1;
  color: var(--color-fuchsia);
  opacity: 0;
  animation-name: training-celebration-float;
  animation-timing-function: ease-out;
  animation-fill-mode: forwards;
}
@keyframes training-celebration-float {
  0% { opacity: 0; transform: translate(0, 0) scale(.5) rotate(0deg); }
  15% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--tc-dx, 0px), -92px) scale(1.1) rotate(var(--tc-rot, 0deg)); }
}
@media (prefers-reduced-motion: reduce) {
  .training-celebration { display: none; }
}
.goal-card__confirm {
  margin-top: 14px;
  padding: 14px 16px;
  background: var(--color-fuchsia-soft);
  border-radius: var(--radius-md);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.goal-card__confirm[hidden] { display: none; }
.goal-card__confirm-text { flex: 1 1 100%; font-size: .95em; color: var(--color-ink); margin: 0; }

.goal-card__saved-note { font-size: .85em; color: var(--color-muted); margin-top: 12px; }
.goal-card__saved-note[hidden] { display: none; }

/* Etap 9E §24 polecenia - CTA "Dodaj cel" / komunikat limitu (2 aktywne/psa).
   Etap 9E.4b §5 polecenia - wyraźny odstęp po "Dodaj cel", żeby nie stykał
   się wizualnie z nagłówkiem "Wstrzymane cele" niżej na stronie. */
#goals-add-trigger { margin-bottom: 32px; }
#goals-add-trigger[hidden] { display: none; }
.goals-limit-note { font-size: .9em; color: var(--color-muted); margin-bottom: 32px; }
.goals-limit-note[hidden] { display: none; }

/* Etap 9E.1 §6/§7 polecenia - mini wizard 3 kroki (Wybierz cel -> Kilka
   pytań -> Podsumowanie), NIE jeden ciągły formularz - każdy krok to
   osobny, chowany blok w tej samej karcie/section-shell. */
#goals-add-section { margin-bottom: 40px; }
#goals-add-section[hidden] { display: none; }
.goals-wizard__step-label { font-size: .82em; font-weight: 700; color: var(--color-muted); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 14px; }
.goals-wizard__step[hidden] { display: none; }
.goals-wizard__nav { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 24px; }
.goals-picker { border: none; padding: 0; margin: 0 0 20px; }
#goals-library-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px; }
.goals-picker__custom-option { margin-bottom: 10px; }
.goals-custom-field { margin: 12px 0 0 4px; }
.goals-custom-field[hidden] { display: none; }
.goals-question { margin-bottom: 20px; }
.goals-question__label { font-weight: 700; font-size: .95em; color: var(--color-ink); margin-bottom: 8px; display: block; }
.goals-question__pills { margin-bottom: 8px; }
/* Krok 3 - podsumowanie (pies/cel/odpowiedzi ankiety) przed finalnym zapisem. */
.goals-summary__line { font-size: .95em; color: var(--color-text); line-height: 1.6; margin-bottom: 8px; }
.goals-summary__line strong { color: var(--color-ink); }

.goals-empty {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  color: var(--color-muted);
  font-size: .95em;
  line-height: 1.5;
  margin-bottom: 32px;
}

/* Historia (completed/archived) - lista prosta, bez miesięcznego
   grupowania jako głównej logiki (§22 polecenia), od najnowszych. */
.goals-history__item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 12px 0;
  border-top: var(--border-width) solid var(--color-line);
}
.goals-history__item-text { color: var(--color-text); font-size: .95em; }
.goals-history__item-status { flex-shrink: 0; font-size: .85em; font-weight: 700; color: var(--color-muted); white-space: nowrap; }
.goals-history__item-date { flex-basis: 100%; font-size: .8em; color: var(--color-muted); margin-top: 2px; }
/* Etap 9E.2 §31 - "Wznów" (WYŁĄCZNIE completed, nigdy archived/foundations). */
.goals-history__item-resume-btn { flex-basis: 100%; align-self: flex-start; margin-top: 6px; }
.goals-history__item-resume-btn[hidden] { display: none; }

@media (max-width: 389px) {
  .goals-history__item { flex-direction: column; gap: 4px; }
}

/* =========================================================
   Panel — Moje notatki (etap 9E.2 §35-46, panel/notatki/).
   ========================================================= */

/* Etap 9E.4i §7/§22 polecenia - segmented control "Treningi własne"/
   "Zajęcia" - mobile-first, dwie duże, równe, czytelne zakładki. */
.notes-tabs { display: flex; gap: 8px; margin-bottom: 20px; }
.notes-tabs__btn {
  flex: 1 1 0;
  min-height: 48px;
  padding: 10px 12px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
  font-weight: 700;
  font-size: .95em;
  cursor: pointer;
  text-align: center;
}
.notes-tabs__btn.is-active { border-color: var(--color-fuchsia); background: var(--color-fuchsia-soft); color: var(--color-fuchsia); }
.notes-tabs__btn:focus-visible { outline: 2px solid var(--color-fuchsia); outline-offset: 2px; }

.notes-latest-stale { font-size: .88em; color: var(--color-muted); font-style: italic; margin-bottom: 10px; }
.notes-latest-stale[hidden] { display: none; }
.note-item {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  margin-bottom: 12px;
}
.note-item__meta { font-size: .8em; color: var(--color-muted); margin-bottom: 6px; text-transform: uppercase; letter-spacing: .02em; }
/* Etap 9E.4e §31 polecenia - "Jak poszło"/"Na następny raz" WYŁĄCZNIE gdy
   dana ma realną wartość (historyczne notatki sprzed tej tury jej nie mają)
   - [hidden] jawnie, zgodnie z resztą projektu (attribute selector nie
   wystarcza samo z siebie bez tej reguły w kilku miejscach tego pliku). */
.note-item__rating { font-size: .85em; font-weight: 700; color: var(--color-ink); margin-bottom: 6px; }
.note-item__rating[hidden] { display: none; }
.note-item__text { font-size: .95em; color: var(--color-text); line-height: 1.6; white-space: pre-wrap; }
.note-item__text[hidden] { display: none; }
/* Etap 9E.4j §1 polecenia - "Co zrobiłbyś inaczej?" PRZYWRÓCONE, wyłącznie
   dla notatek własnego treningu (.note-item, nie .note-item--session). */
.note-item__next { margin-top: 10px; padding-top: 10px; border-top: var(--border-width) solid var(--color-line); }
.note-item__next[hidden] { display: none; }
.note-item__next-label { font-size: .78em; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--color-muted); margin-bottom: 4px; }
.note-item__next-text { font-size: .92em; color: var(--color-text); line-height: 1.5; white-space: pre-wrap; }

/* Etap 9E.4i §9/§18 polecenia - notatka Z ZAJĘĆ: pierwsza warstwa (data/typ/
   temat/ocena) w <summary> zawsze widoczna, "Powiązany cel" i treść dopiero
   po rozwinięciu - ten sam <details> wzorzec co .notes-older-details. */
.note-item--session { padding: 0; }
.note-item__session-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 16px 18px;
  cursor: pointer;
  list-style: none;
}
.note-item__session-summary::-webkit-details-marker { display: none; }
.note-item__session-summary .note-item__meta { margin-bottom: 0; }
.note-item__session-focus { font-size: .95em; font-weight: 700; color: var(--color-ink); flex: 1 1 100%; }
.note-item__session-body { padding: 0 18px 16px; }
.note-item__goal-link { font-size: .82em; color: var(--color-muted); margin-bottom: 8px; }
.note-item__goal-link[hidden] { display: none; }

/* Etap 9E.4e §21/§25 polecenia - ocena treningu: 5 kolumn x 2 rzędy na
   mobile, duże tap-targety (min. ~44px) - "Trudno ocenić" jako osobna,
   równorzędna opcja pod spodem (reużywa .choice-list__option). */
.note-rating-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin: 8px 0 6px; }
.note-rating-grid__option {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  font-weight: 700;
  font-size: .95em;
  color: var(--color-ink);
  cursor: pointer;
}
.note-rating-grid__option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.note-rating-grid__option:has(input:checked) { border-color: var(--color-fuchsia); background: var(--color-fuchsia-soft); color: var(--color-fuchsia); }
.note-rating-grid__option:has(input:focus-visible) { outline: 2px solid var(--color-fuchsia); outline-offset: 2px; }
.note-rating-scale-labels { display: flex; justify-content: space-between; font-size: .8em; color: var(--color-muted); margin-bottom: 10px; }
/* Etap 9E.4d §18 polecenia - .notes-older-details/-summary/-list zastępują
   dawne, sztywne ID (#notes-older-details itd.) - renderGoalNotesBlock()
   tworzy te elementy dynamicznie, reużywany zarówno dla aktualnej pracy,
   jak i dla historii (paused/completed/archived), stąd klasy, nie ID. */
.notes-older-details { margin-top: 8px; margin-bottom: 8px; }
.notes-older-summary { cursor: pointer; font-weight: 700; color: var(--color-fuchsia); font-size: .9em; margin-bottom: 10px; }
.notes-older-list { margin-top: 12px; }

/* Etap 9E.4d §9/§10 polecenia - "Nad czym teraz pracujecie" (1 active goal =
   auto-wybór, tekst only; 2 = duże choice cards, ten sam wzorzec co
   .choice-list gdzie indziej w panelu - reużyte 1:1, zero nowego CSS). */
#notes-active-goal-info { margin-bottom: 20px; }
#notes-active-picker { max-width: 520px; margin-bottom: 20px; }

#notes-older-goals-list {
  display: block;
  max-width: 680px;
  margin-bottom: 18px;
}

.notes-history-search {
  margin-bottom: 12px;
}

.notes-history-search__input {
  width: 100%;
  min-height: 46px;
  padding: 10px 14px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
  font: inherit;
}

.notes-history-search__input:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.notes-history-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.notes-history-goal {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 12px 14px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
  text-align: left;
  cursor: pointer;
  font: inherit;
}

.notes-history-goal:hover,
.notes-history-goal:focus-visible,
.notes-history-goal.is-selected {
  border-color: var(--color-accent);
}

.notes-history-goal.is-selected {
  background: var(--color-accent-soft);
}

.notes-history-goal__title {
  font-weight: 700;
}

.notes-history-goal__meta,
.notes-history-selected__meta,
.notes-history-no-results {
  color: var(--color-muted);
  font-size: .88em;
  line-height: 1.45;
}

.notes-history-more {
  margin-top: 12px;
}

.notes-history-selected {
  margin: 4px 0 16px;
  padding: 14px 16px;
  border-left: 3px solid var(--color-accent);
  background: var(--color-surface);
}

.notes-history-selected__title {
  font-weight: 800;
  margin-bottom: 3px;
}

#notes-older-goal-notes:empty {
  display: none;
}

/* =========================================================
   Panel — Wydarzenia (Panel MVP — etap 5, panel/wydarzenia/).
   UWAGA NAZEWNICZA: świadomie NIE `.event-card` — ta nazwa jest już zajęta
   przez istniejący, niezwiązany komponent "Co się teraz dzieje?" na
   homepage (`.events`/`.event-card`, etap 17C, dziś zawsze pusty/hidden).
   Użycie tej samej nazwy klasy powodowało realną kolizję w kaskadzie
   (obie reguły `.event-card` łączyły się we wspólny zestaw właściwości —
   `display:flex;flex-direction:column` z homepage'owej reguły przeciekało
   też tutaj, przez co `.event-card__badge` z `align-items:stretch`
   rozciągał się na całą szerokość karty zamiast być małą pigułką) —
   znalezione i naprawione przed oddaniem, patrz PANEL_KLIENTA.md §18.10.
   Stąd `.wydarzenie-card` jako osobna, jednoznaczna nazwa.
   ========================================================= */

.events-list { display: flex; flex-direction: column; gap: 16px; }

.events-empty {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  color: var(--color-muted);
  font-size: .95em;
  line-height: 1.5;
}

.wydarzenie-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 22px 24px;
}
.wydarzenie-card--cancelled { background: var(--color-surface-alt); }

/* Etap "Miniatury + UI wydarzeń" (17.09.2026) - miniatura + treść jedna
   pod drugą na mobile (domyślnie, mobile-first), obok siebie od 640px -
   zdjęcie NIE dominuje karty (szerokość ograniczona do 200px na desktopie). */
.wydarzenie-card__layout { display: flex; flex-direction: column; gap: 16px; }
@media (min-width: 640px) {
  .wydarzenie-card__layout { flex-direction: row; align-items: flex-start; }
  .wydarzenie-card__thumbnail { flex: 0 0 200px; width: 200px; }
}
.wydarzenie-card__main { flex: 1 1 auto; min-width: 0; }

.wydarzenie-card__thumbnail {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--color-surface-alt);
}
.wydarzenie-card__thumbnail[hidden] { display: none; }

/* "Badge typu" - mała pigułka zamiast gołego, kolorowego tekstu (bardziej
   premium/czytelne, §"PANEL KLIENTA WYDARZENIA" polecenia). */
.wydarzenie-card__type {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  background: var(--color-fuchsia-soft);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--color-fuchsia-hover);
}
.wydarzenie-card__title { font-family: var(--font-display); font-weight: 600; font-size: 1.15rem; color: var(--color-ink); margin-top: 8px; }
.wydarzenie-card__day { font-size: .95em; color: var(--color-text); margin-top: 8px; }
.wydarzenie-card__time { font-size: .95em; color: var(--color-text); }
.wydarzenie-card__location { font-size: .92em; color: var(--color-text); margin-top: 2px; }

.wydarzenie-card__badge {
  display: inline-flex;
  align-items: center;
  margin-top: 10px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: var(--color-error);
  color: var(--color-white);
  font-size: 12px;
  font-weight: 700;
}
.wydarzenie-card__badge[hidden] { display: none; }

.wydarzenie-card__benefit {
  display: inline-flex;
  align-items: center;
  margin-top: 12px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 700;
}
.wydarzenie-card__benefit[hidden] { display: none; }
.wydarzenie-card__benefit--free { background: var(--color-aqua-soft); color: var(--color-ink); }
.wydarzenie-card__benefit--discount { background: var(--color-yellow-soft); color: var(--color-ink); }

.wydarzenie-card__description { font-size: .92em; line-height: 1.5; color: var(--color-text); margin-top: 14px; padding-top: 14px; border-top: var(--border-width) solid var(--color-line); }
.wydarzenie-card__description[hidden] { display: none; }

/* Etap 9 §10-14 — dołączanie/limit miejsc/cel klas komunikacji/instrukcja. */
.wydarzenie-card__target { font-size: .85em; font-weight: 700; color: var(--color-muted); margin-top: 8px; }
.wydarzenie-card__target[hidden] { display: none; }
.wydarzenie-card__capacity { font-size: .85em; color: var(--color-muted); margin-top: 8px; }
.wydarzenie-card__capacity[hidden] { display: none; }
.wydarzenie-card__instruction-link { display: inline-flex; margin-top: 12px; font-weight: 700; font-size: .9em; color: var(--color-fuchsia); }
.wydarzenie-card__instruction-link[hidden] { display: none; }
.wydarzenie-card__instruction-link:hover, .wydarzenie-card__instruction-link:focus-visible { color: var(--color-fuchsia-hover); }

/* Etap "Wydarzenia + zapisy klientów" (17.09.2026) - link Google Maps, ten
   sam wzorzec co .schedule-card__maps-link (Mój grafik, FINAL PATCH 3). */
.wydarzenie-card__maps-link { display: flex; align-items: center; min-height: 44px; margin-top: 6px; font-weight: 700; font-size: .9em; color: var(--color-fuchsia); }
.wydarzenie-card__maps-link[hidden] { display: none; }
.wydarzenie-card__maps-link:hover, .wydarzenie-card__maps-link:focus-visible { color: var(--color-fuchsia-hover); }

.wydarzenie-card__signup-window { font-size: .85em; font-weight: 700; color: var(--color-muted); margin-top: 8px; }
.wydarzenie-card__signup-window[hidden] { display: none; }
.wydarzenie-card__no-dogs { font-size: .9em; color: var(--color-text); margin-top: 16px; }
.wydarzenie-card__no-dogs[hidden] { display: none; }
/* POPRAWKA UX: INFORMACJA O LIŚCIE REZERWOWEJ (18.09.2026) - WYŁĄCZNIE
   informacyjna, ten sam wzorzec co .wydarzenie-card__signup-window (muted,
   pogrubiona) - nigdy nie blokuje "Dołącz" pod spodem. */
.wydarzenie-card__waitlist-note { font-size: .85em; font-weight: 700; color: var(--color-muted); margin: 16px 0 8px; }
.wydarzenie-card__waitlist-note[hidden] { display: none; }

/* ETAP: UPROSZCZENIE WYDARZEŃ WWW + INTUICYJNE DOŁĄCZANIE W PANELU
   (18.09.2026) §4-§11 - karta jest domyślnie kompaktowa: zwięzły status
   ("Zapisani: ...") + jeden przycisk "Dołącz"/"Dołącz z kolejnym psem",
   zastępuje dawną zawsze widoczną listę wszystkich psów z osobnym
   przyciskiem "Zapisz" na każdego (duże scrollowanie). */
.wydarzenie-card__success {
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--color-aqua-soft);
  color: var(--color-ink);
  font-size: .92em;
  line-height: 1.5;
}
.wydarzenie-card__success[hidden] { display: none; }

.wydarzenie-card__status-section { margin-top: 20px; padding-top: 16px; border-top: var(--border-width) solid var(--color-line); }
.wydarzenie-card__status-line { font-weight: 700; color: var(--color-ink); margin: 0 0 10px; }
.wydarzenie-card__status-line[hidden] { display: none; }
.wydarzenie-card__status-dogs { display: flex; flex-direction: column; gap: 10px; }
.wydarzenie-card__status-dog { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.wydarzenie-card__status-dog-name { font-weight: 700; color: var(--color-ink); }
/* ETAP: POKAŻ SOCIAL_FOCUS PO ZAPISIE (18.09.2026) - flex-basis:100% (ten
   sam wzorzec co .wydarzenie-card__status-dog-note niżej) - zawsze na
   własnej linii, pod imieniem psa, zgodnie z przykładowym układem ticketu
   ("Bonzo" / "Socjal: z ludźmi" / "Zrezygnuj"). */
.wydarzenie-card__status-dog-social-focus { flex-basis: 100%; font-size: .9em; color: var(--color-text); }
.wydarzenie-card__status-dog-social-focus[hidden] { display: none; }
.wydarzenie-card__status-dog-label {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--color-fuchsia-soft);
  font-size: .8em;
  font-weight: 700;
  color: var(--color-fuchsia-hover);
}
.wydarzenie-card__status-dog-label[hidden] { display: none; }
/* ETAP: NOTATKI KLIENTA PO ZAJĘCIACH (18.09.2026) - "Dodaj notatkę", ten
   sam dyskretny wzorzec linku co "Zrezygnuj" niżej (min-height 44px na
   tap-target mobile). */
.wydarzenie-card__status-dog-add-note { display: inline-flex; align-items: center; min-height: 44px; padding: 10px 2px; }
.wydarzenie-card__status-dog-add-note[hidden] { display: none; }
/* "Zrezygnuj" jako dyskretny link, nie pełny przycisk (ten sam wzorzec co
   dawne .wydarzenie-card__dog-leave-btn - świadomie zachowany). */
.wydarzenie-card__status-dog-leave { display: inline-flex; align-items: center; min-height: 44px; padding: 10px 2px; }
/* ETAP: POPRAWKA LATE_CANCEL (18.09.2026) - psu ze statusem `late_cancel`
   ten przycisk jest ukrywany atrybutem `hidden` w JS (buildStatusDogRow())
   - bez tej reguły klasa wyżej (display:inline-flex, wyższa specyficzność
   niż samo `[hidden]`) nadpisywałaby domyślne ukrycie. */
.wydarzenie-card__status-dog-leave[hidden] { display: none; }
/* §10 polecenia - spokojna, trwała notatka 12h przy psie już zapisanym na
   klasy/obronę (joined) - flex-basis:100%, żeby zawsze lądowała pod
   imieniem/statusem/akcją, nigdy nie ściskała ich w jednej linii. */
.wydarzenie-card__status-dog-note { flex-basis: 100%; font-size: .85em; color: var(--color-muted); }
.wydarzenie-card__status-dog-note[hidden] { display: none; }

.wydarzenie-card__dogs-section { margin-top: 20px; padding-top: 16px; border-top: var(--border-width) solid var(--color-line); }
.wydarzenie-card__join-toggle[hidden] { display: none; }

/* ZLOT PRZEWODNIKÓW I PODOBNE (27.09.2026) §2 ticketu - wydarzenie bez
   wymaganego psa dostaje osobną, prostą ścieżkę zamiast pickera psów (patrz
   script.js renderNoDogUI()). Ten sam, sprawdzony wzorzec zabezpieczenia
   [hidden] co .wydarzenie-card__join-toggle wyżej - .btn/.btn--link
   ustawiają własny `display`, więc goły atrybut `hidden` sam w sobie by
   przegrał specyficznością. */
.wydarzenie-card__dogs-picker-mode[hidden],
.wydarzenie-card__no-dog-mode[hidden],
.wydarzenie-card__no-dog-status[hidden],
.wydarzenie-card__no-dog-waitlist-note[hidden],
.wydarzenie-card__no-dog-join[hidden],
.wydarzenie-card__no-dog-leave[hidden] { display: none; }

/* §5 polecenia - picker inline WEWNĄTRZ tej samej karty, otwierany przez
   "Dołącz" - lista checkboxów zamiast osobnej strony/modala. */
.wydarzenie-card__picker { margin-top: 16px; padding-top: 16px; border-top: var(--border-width) solid var(--color-line); }
.wydarzenie-card__picker[hidden] { display: none; }
.wydarzenie-card__picker-heading { font-family: var(--font-display); font-weight: 600; font-size: 1rem; color: var(--color-ink); margin: 0 0 12px; }
.wydarzenie-card__picker-dogs { display: flex; flex-direction: column; gap: 4px; }
.wydarzenie-card__picker-dog { padding: 10px 0; border-top: var(--border-width) solid var(--color-line); }
.wydarzenie-card__picker-dog:first-child { padding-top: 0; border-top: none; }
.checkbox-option {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  color: var(--color-ink);
  cursor: pointer;
}
.checkbox-option input[type="checkbox"] { width: 20px; height: 20px; flex-shrink: 0; accent-color: var(--color-fuchsia); }
.checkbox-option input[type="checkbox"]:focus-visible { outline: 3px solid var(--color-fuchsia); outline-offset: 3px; }
/* §6 polecenia - kierunek socjalu odsłaniany DOPIERO po zaznaczeniu psa,
   WYŁĄCZNIE dla klas komunikacji, wcięty pod nazwą tego psa. */
.wydarzenie-card__picker-dog .wydarzenie-card__dog-social-focus { margin: 8px 0 0 32px; }
.wydarzenie-card__picker-dog .wydarzenie-card__dog-social-focus[hidden] { display: none; }
.wydarzenie-card__picker-error { margin-top: 12px; }
.wydarzenie-card__picker-error[hidden] { display: none; }
.wydarzenie-card__picker-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; margin-top: 16px; }

/* Etap 9 §9/§18 — link instrukcji + notatka po zajęciach na kartach grafiku. */
.schedule-card__dog { font-size: .9em; color: var(--color-text); margin-top: 4px; }
.schedule-card__dog[hidden] { display: none; }
.schedule-card__personal-note { font-size: .9em; color: var(--color-text); margin-top: 10px; padding-top: 10px; border-top: var(--border-width) solid var(--color-line); }
.schedule-card__personal-note[hidden] { display: none; }
/* Patch 3B - `flex` (blokowy) zamiast `inline-flex`, żeby ten link zawsze
   lądował w NOWEJ linii pod .schedule-card__maps-link (gdy oba widoczne),
   niezależnie od dostępnej szerokości - patrz komentarz przy tamtej regule. */
.schedule-card__instruction-link { display: flex; align-items: center; margin-top: 10px; font-weight: 700; font-size: .9em; color: var(--color-fuchsia); }
.schedule-card__instruction-link[hidden] { display: none; }
.schedule-card__instruction-link:hover, .schedule-card__instruction-link:focus-visible { color: var(--color-fuchsia-hover); }

/* POPRAWKA: NOTATKA W TRAKCIE ZWYKŁYCH ZAJĘĆ (18.09.2026) - ten sam wzorzec
   co .schedule-card__instruction-link wyżej (własna linia, min. tap-target). */
.schedule-card__add-note-link { display: flex; align-items: center; min-height: 44px; margin-top: 10px; font-weight: 700; font-size: .9em; color: var(--color-fuchsia); }
.schedule-card__add-note-link[hidden] { display: none; }
.schedule-card__add-note-link:hover, .schedule-card__add-note-link:focus-visible { color: var(--color-fuchsia-hover); }

/* =========================================================
   Panel — Materiały (Panel MVP — etap 7, panel/materialy/). Sprawdzone
   grepem przed użyciem: ".material" nie występuje nigdzie indziej w tym
   pliku ani w HTML strony — brak ryzyka kolizji nazw jak przy
   ".event-card" w etapie 5 (patrz komentarz przy .wydarzenie-card wyżej).
   ========================================================= */

/* Final patch przed premierą §12 polecenia - biblioteka materiałów: siatka
   kart zamiast pionowej listy z grafiką na prawie całą szerokość strony.
   2-3 karty w rzędzie na desktopie (zależnie od dostępnej szerokości,
   auto-fit), 1 kolumna na mobile. WYŁĄCZNIE prezentacja - reszta modułu
   (uprawnienia/backend pobierania/przypisywanie) bez zmian.
   BUGFIX (24.09.2026) - `1fr` w minmax() rozciągał pojedynczą kartę na
   cały rząd, gdy była tylko jedna (albo kilka niedopełniających rzędu).
   Kolumny mają dziś stałą, ograniczoną szerokość (320-340px, nie 1fr),
   więc auto-fill nigdy nie ma czego rozciągać - działa identycznie dla
   1, 2, 3 czy 5 materiałów, karty zawsze trzymają się od lewej
   (justify-content: start). Mobile bez zmian - `1fr` poniżej 640px. */
.materials-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 340px)); justify-content: start; gap: 20px; }
@media (max-width: 640px) {
  .materials-list { grid-template-columns: 1fr; justify-content: stretch; }
}

/* UX MATERIAŁY (08.10.2026 ticket) §2/§4 - dawne grupowanie na sekcje/
   kategorie (Dla Ciebie / Materiały ogólne / Twoje treningi / Trening
   grupowy / Klasy komunikacji / Obrona, etap "MATERIAŁY WG FORM
   WSPÓŁPRACY" 17.09.2026) USUNIĘTE z prezentacji - `.materials-section`/
   `.materials-section__heading` były wyłącznie dla tamtych, teraz
   nigdy-nietworzonych wrapperów, usunięte jako martwy kod (żadna reguła
   JS/HTML już ich nie używa - `#materials-sections` dostaje dziś wprost
   klasę `.materials-list` wyżej, jedna płaska lista bez <section>/<h2>). */

.materials-empty {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  color: var(--color-muted);
  font-size: .95em;
  line-height: 1.5;
}

.material-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* Miniatura: wysokość stała, nigdy nie rozciąga się na całą szerokość
   strony (dawny bug - .material-card__image miało wcześniej max-width:100%
   bez żadnego ograniczenia wysokości/kontenera). object-fit:cover
   przycina bezpiecznie zamiast deformować proporcje. */
.material-card__thumb {
  position: relative;
  width: 100%;
  height: 128px;
  background: var(--color-surface-alt);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.material-card__thumb .material-card__image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; margin: 0; border-radius: 0; }
.material-card__thumb .material-card__image[hidden] { display: none; }
.material-card__thumb-placeholder { width: 40px; height: 40px; color: var(--color-muted); }
.material-card__thumb-placeholder[hidden] { display: none; }

/* UX MATERIAŁY (08.10.2026 ticket) §6/§7 - estetyczna mini-okładka
   WYŁĄCZNIE dla PDF, zamiast gołego 40px placeholdera. Żyje w TYM SAMYM
   .material-card__thumb (128px, wyśrodkowane, --color-surface-alt) co
   reszta miniatur - rozmiar/proporcje identyczne, grid nigdy nie "skacze".
   Ikona reużywa istniejący symbol sprite'u (#icon-nav-materials) - zero
   nowego obrazka/biblioteki/emoji. */
.material-card__thumb-pdf {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--color-fuchsia);
}
.material-card__thumb-pdf[hidden] { display: none; }
.material-card__thumb-pdf-icon { width: 34px; height: 34px; }
.material-card__thumb-pdf-label {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-fuchsia);
}

.material-card__body { padding: 18px 20px 20px; display: flex; flex-direction: column; flex: 1 1 auto; }
.material-card__type { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--color-fuchsia); }
.material-card__title { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--color-ink); margin-top: 6px; }
.material-card__description { font-size: .92em; line-height: 1.5; color: var(--color-text); margin-top: 10px; }
.material-card__description[hidden] { display: none; }
.material-card__meta { font-size: .85em; color: var(--color-muted); margin-top: 10px; }
.material-card__file-meta { font-size: .85em; color: var(--color-muted); margin-top: 4px; }
.material-card__file-meta[hidden] { display: none; }

.material-card__actions { margin-top: 16px; }
.material-card__error { margin-top: 12px; }
.material-card__error[hidden] { display: none; }

/* =========================================================
   Panel — Psy + ankieta startowa (etap 9 §5-6; profil psa,
   wiele psów i zdjęcie profilowe: etap 9C; skrócony finalny
   zakres profilu: etap 9C.3, panel/psy/).
   ========================================================= */
/* Etap 9C.3 — krótka podpowiedź pod polem (np. "jeśli nie znasz dokładnej
   daty..."), ten sam ton co .field__optional, ale jako osobny akapit pod
   inputem zamiast fragmentu labelki. */
.field__hint { margin: 6px 0 0; font-size: 13px; font-weight: 500; color: var(--color-muted); }

/* Finalny redesign — audyt wykazał nadmiar dekoracji (7+ doodli na jednej
   stronie, w tym kształty wprost zakazane przez DESIGN.md §4 - łapka,
   serduszko). Wszystkie doodle poza jednym (pies na kocyku w sidebarze,
   patrz sekcja sidebara wyżej) COFNIĘTE z "Moje psy" - .dogs-eyebrow i
   .dogs-lead wracają do zwykłego .eyebrow/.panel-main__lead bez żadnej
   dodatkowej dekoracji. Same pliki PNG zostają w assets/images/panel/,
   tylko przestały być renderowane w tym UI (patrz CLAUDE.md). ID/klasy
   używane przez script.js (.dogs-list/.dog-card*/.dog-add*/#dog-add-form/
   itd.) zostają nietknięte funkcjonalnie. */
.dogs-empty { color: var(--color-muted); margin-bottom: 20px; }

/* "Final UI pass" (13.09.2026) - H1+lead+CTA "+Dodaj psa"+karty psów żyją
   dziś razem w .section-shell--dogs (patrz wyżej), więc .dogs-header to
   wewnątrz shellu WYŁĄCZNIE przycisk/formularz "+ Dodaj psa" - zachowuje
   tylko odstęp + cienką linię oddzielającą od gridu kart poniżej (flex/
   justify-content/align-items/gap z jeszcze wcześniejszej wersji
   USUNIĘTE jako martwe przy pojedynczym dziecku). Dawny akcent-heart w
   H1 (.dogs-header__accent-heart) i fuksjowy underline pod H1
   (.dogs-header__intro .panel-main__heading::after) USUNIĘTE razem z
   .dogs-header__intro - to samo serce żyje dziś w .section-shell__decor,
   kolorowy box shellu zastępuje underline. */
.dogs-header {
  padding-bottom: 28px;
  margin-bottom: 32px;
  border-bottom: var(--border-width) solid var(--color-line);
}

/* KOREKTA "friendly editorial" — karty psa powiększone (zdjęcie ma być
   bohaterem, nie avatarem), minmax podniesiony z 340px do 440px: przy
   szerokości contentu panelu (~1240px) daje to dokładnie 2 karty w rzędzie
   (nie 3 jak poprzednio), 3+ psów naturalnie przechodzi do kolejnego rzędu.
   .dog-card max-width podniesiony do 640px - przy 1 psie karta jest duża i
   wyraźna, nie sztucznie ograniczona jak poprzednio (560px). */
.dogs-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(440px, 1fr)); gap: 28px; margin-bottom: 24px; width: 100%; max-width: 100%; min-width: 0; }

/* KOREKTA "final polish" §6 - na ≤640px `minmax(440px,...)` wymuszał ślad
   kolumny SZERSZY niż sam viewport (440px > 360-390px dostępnej
   szerokości) - grid nie mógł się skurczyć poniżej tej wartości, więc
   `.dog-card` (naturalnie rozciągnięty na szerokość swojej kolumny)
   wychodził poza ekran ("ucięty prostokąt", zgłoszony błąd). Naprawione
   jawnym, węższym breakpointem: jedna kolumna, `minmax(0,1fr)` (nie
   sztywne px). Reguły samej `.dog-card` (padding/max-width na mobile)
   przeniesione do JEDNEGO, końcowego bloku mobile na końcu tej sekcji
   (patrz "BUG MOBILE - AUDYT CASCADE" niżej) - zostawienie ich tutaj,
   PRZED bazową (bezwarunkową) regułą `.dog-card`, powodowało realny bug:
   przy tej samej specyficzności (0,0,1,0) WYGRYWAŁA reguła bazowa, bo jest
   PÓŹNIEJ w pliku - ta mobile-owa wersja padding/max-width nigdy faktycznie
   się nie stosowała, mimo że wyglądała poprawnie w kodzie. */
@media (max-width: 640px) {
  .dogs-list { grid-template-columns: minmax(0, 1fr); }
}

/* Jedyny editorialowy akcent strony (patrz .section-shell__decor wyżej) -
   "Psy zmieniają wszystko" + wcześniejszy blok pod gridem kart USUNIĘTE
   (kontrola po live review) - mały graphite heart żyje dziś w page hero
   zamiast osobnego bloku pod listą kart. */

/* Karta psa = system strony WWW (DESIGN.md §8.1): biały surface, cienka
   linia, radius, ZERO cienia. Jedyny akcent to bardzo subtelna fuksja-soft
   "aureola" wokół zdjęcia (patrz .dog-card__media niżej) - NIE całe różowe
   tło karty. Bez dekoracji korony/serca/scribble - te trzy COFNIĘTE (patrz
   CLAUDE.md, audyt: łapka/serduszko to kształty wprost zakazane w
   DESIGN.md §4). Więcej paddingu ("dużo oddechu", polecenie §1). */
/* BUG UX (20.09.2026) - PRZYCZYNA "za wąskiego" formularza "Dane psa":
   .dog-card był `display:flex`, a .dog-card__body (jedyny kontener WSZYSTKICH
   sekcji poza zdjęciem - nazwa/status/akcje/edit-form/ankieta/zdjęcie-upload)
   miał `flex: 1 1 240px` - jako flex-sibling .dog-card__media (stały krążek
   ~166px), body dostawał WYŁĄCZNIE pozostałą szerokość (ok. 366px na karcie
   640px) i NIC wewnątrz niego (w tym .dog-card__edit-form, niezależnie od
   jego własnego paddingu/chrome) nie mogło być szersze niż ten wąski,
   odziedziczony flex-column. Zmiana paddingu SAMEGO formularza (poprzednia
   tura) nie mogła tego naprawić - ograniczenie leżało wyżej, na rodzicu.
   Naprawione przejściem na CSS Grid.
   MAŁY PATCH UX (20.09.2026) §1 - PIERWSZA wersja tej naprawy dawała
   .dog-card__body `display:contents` (znika jako box, jego DZIECI stają się
   bezpośrednimi elementami grida) - to psuło zamknięty widok karty: auto-
   placement rozkładał name/details/status/actions/archive-btn na 5 osobnych,
   niezależnych rzędów grida zamiast trzymać je razem jako jeden zwarty blok,
   a na mobile `.dog-card__media` (bez jawnego `justify-self`) domyślnie
   ROZCIĄGAŁO SIĘ na pełną szerokość jedynej kolumny (grid item default:
   justify-self:stretch) - stąd "rozjechany", owalny różowy krążek zamiast
   okrągłego. Naprawione: 3 pełnoszerokościowe sekcje (edit-form/ankieta/
   upload zdjęcia) PRZENIESIONE w HTML na bezpośrednie dzieci .dog-card
   (rodzeństwo .dog-card__body, nie jego potomkowie) - .dog-card__body
   wraca do bycia PRAWDZIWYM, pojedynczym gridowym itemem (jeden zwarty blok,
   normalny block-flow w środku, jak przed jakąkolwiek zmianą grida), a te
   3 sekcje dostają własne, jawne miejsce w gridzie (`grid-column:1/-1`,
   rząd niżej). .dog-card__media dostaje `justify-self:start`, żeby nigdy
   nie rozciągać się poza swój naturalny rozmiar (krążek zawsze okrągły). */
.dog-card {
  position: relative;
  width: 100%;
  max-width: 640px;
  min-width: 0;
  margin-inline: 0;
  box-sizing: border-box;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 40px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 28px;
  row-gap: 0;
  align-items: start;
}
/* Zdjęcie zostaje wyłącznie w rzędzie 1 (obok imienia/danych), nie rozciąga
   się na kolejne rzędy ani na szerokość kolumny (justify-self:start, patrz
   komentarz wyżej) - stały, okrągły krążek niezależnie od breakpointu. */
.dog-card__media { grid-column: 1; grid-row: 1; justify-self: start; }
.dog-card__edit-form, .dog-card__questionnaire, .dog-card__photo-upload { grid-column: 1 / -1; }
/* Ten grid (media/body jako rzędy) obowiązuje WYŁĄCZNIE na desktopie (działa
   poprawnie, potwierdzone). Na mobile grid jest CAŁKOWICIE wyłączony (patrz
   jeden, końcowy blok `@media(max-width:640px)` na końcu tej sekcji, tuż nad
   `.dog-add`) - poprzednia próba mobile'owego override'u przez grid-row
   (usunięta stąd) NIGDY faktycznie nie działała: ustawiała te same
   selektory co reguły PONIŻEJ w tym pliku (np. `.dog-card__body` linia
   ~4820) przy IDENTYCZNEJ specyficzności (0,0,1,0) - przy remisie wygrywa
   reguła PÓŹNIEJSZA w źródle, więc mobile-owy override cicho przegrywał z
   bazową regułą i nigdy się nie renderował, mimo że wyglądał poprawnie w
   kodzie. Stąd decyzja: na mobile .dog-card wraca do `display:block`
   (prosty, odporny układ, zero rywalizacji o grid-row/column w cascade). */
/* Zdjęcie psa jest głównym elementem wizualnym karty (polecenie "friendly
   editorial" §1) - powiększone ze 124px do 150px, object-fit:cover.
   .dog-card__media dostaje bardzo lekką fuksja-soft "aureolę" (padding +
   tło + border-radius:50% wokół samego zdjęcia/placeholdera) - jedyny
   kolorowy akcent karty, celowo nie całe różowe tło. Etap 9C §7/§16 -
   miniatura albo neutralny placeholder (inicjał imienia), nigdy
   broken-image: <img> zostaje [hidden] dopóki fetch()+Blob nie dostarczy
   prawdziwego zdjęcia (patrz script.js, "sam <img src>" nie wysłałby
   nagłówka Authorization). */
.dog-card__media {
  position: relative;
  flex: 0 0 auto;
  padding: 8px;
  background: var(--color-fuchsia-soft);
  border-radius: 50%;
}
.dog-card__photo, .dog-card__photo-placeholder {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  border: 3px solid var(--color-surface);
}
.dog-card__photo { display: block; object-fit: cover; }
.dog-card__photo[hidden] { display: none; }
.dog-card__photo-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface-alt);
  color: var(--color-fuchsia);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 2.8rem;
}
.dog-card__photo-placeholder[hidden] { display: none; }
/* MAŁY PATCH UX (20.09.2026) §1 - .dog-card__body to dziś JEDEN, prawdziwy
   element grida (kolumna 2, rząd 1, obok zdjęcia) - jego dzieci (imię/dane/
   status/akcje) stackują się WEWNĄTRZ niego normalnym block-flow (własne
   marginesy, bez zmian), a nie jako osobne rzędy grida karty. */
.dog-card__body { grid-column: 2; grid-row: 1; min-width: 0; }
/* Imię wyraźnie większe (1.7rem -> 2.1rem) - ma dominować nad danymi i
   statusem ankiety, nie odwrotnie (polecenie §1 "Treść"). */
.dog-card__name { font-family: var(--font-display); font-weight: 600; font-size: 2.1rem; color: var(--color-ink); }
/* "Dane psa spokojniejsze i czytelniejsze" - przygaszony kolor
   (--color-muted zamiast --color-text) i odstęp od imienia. */
.dog-card__details { font-size: 1em; color: var(--color-muted); margin-top: 10px; line-height: 1.5; }
/* Status ankiety ma być "mały i pomocniczy, nie dominować nad imieniem i
   zdjęciem" (polecenie §1 "Treść") - zmniejszony font/padding względem
   poprzedniej wersji. Fuksja "soft" = jeszcze nie wypełniona (wymaga
   uwagi/akcji), neutralny grafitowy chip = wypełniona (zamknięty temat) -
   żadnej wymyślonej zieleni, oba warianty to istniejące tokeny globalnego
   systemu. Klasa modyfikatora przełączana w script.js
   (statusEl.classList.toggle - WYŁĄCZNIE zmiana klasy prezentacyjnej, ten
   sam fetch/te same dane co dotychczas, zero nowej logiki/endpointów). */
.dog-card__questionnaire-status {
  display: inline-flex;
  align-items: center;
  margin-top: 12px;
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  color: var(--color-muted);
  font-size: .78em;
  font-weight: 600;
}
.dog-card__questionnaire-status--pending { background: var(--color-fuchsia-soft); color: var(--color-fuchsia-hover); }
.dog-card__questionnaire-status--done { background: var(--color-surface-alt); color: var(--color-ink); }
.dog-card__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 22px; }
/* BETA PATCH ARCHIWIZACJA PSA (20.09.2026) §2 polecenia - dyskretna,
   drugorzędna akcja pod głównymi przyciskami karty (ten sam wzorzec co
   .btn--link na kartach celu), nie osobny duży przycisk "destrukcyjny". */
.dog-card__archive-btn { display: inline-flex; align-items: center; min-height: 44px; padding: 10px 2px; margin-top: 10px; }
.dog-card__archive-summary[hidden] { display: none; }
.dog-card__edit-form, .dog-card__questionnaire, .dog-card__photo-upload { margin-top: 20px; padding-top: 20px; border-top: var(--border-width) solid var(--color-line); }
/* MAŁY PATCH UX (20.09.2026) §1 polecenia - ta sama "karta w karcie" wada co
   .panel-auth__card .form/.quiz-card .form (patrz komentarz przy tamtych
   regułach): globalna .form dodaje WŁASNE tło/obrys/cień/duży padding
   (do 56px na desktopie), więc formularz "Dane psa" wewnątrz już
   wypełnionej białej karty psa wyglądał za wąsko. Zdjęte własne card-chrome
   - formularz wypełnia teraz pełną szerokość .dog-card__edit-form (który ma
   wyłącznie górny odstęp/obwódkę, bez bocznego paddingu), więc dziedziczy
   normalny, pojedynczy padding samej karty psa (.dog-card). Mobile bez
   zmian (te same reguły .form input/select nadal stylują pola).*/
.dog-card__edit-form .dog-edit-form { background: none; border: none; box-shadow: none; padding: 0; }
.dog-card__edit-form[hidden], .dog-card__questionnaire[hidden], .dog-card__photo-upload[hidden] { display: none; }
/* KRÓTKI AUDYT PRZED TESTEM (20.09.2026) §1 polecenia - "Bragi vel. Nani"
   widoczne WYŁĄCZNIE wewnątrz formularza "Dane psa", nie na tytule karty. */
.dog-edit-form__display-name { font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; color: var(--color-ink); margin: 0 0 16px; }
.dog-card__photo-summary[hidden] { display: none; }
/* Etap 9C.3 §7 — proste 2-krokowe UI: "Wybierz zdjęcie" (label udający
   przycisk, opakowuje wizualnie ukryty <input type=file> - kliknięcie
   gdziekolwiek na labelce otwiera natywny picker plików) + nazwa wybranego
   pliku jako potwierdzenie + "Zapisz zdjęcie". Zero wzmianki o MB/limicie
   w widocznym UI (§7 polecenia - klient nie ma wiedzieć, ile waży zdjęcie). */
.dog-card__photo-upload {
  background: var(--color-bg);
  padding: 18px 18px 20px;
  border-radius: var(--radius-md);
  border-top: none;
}
.dog-card__photo-upload-heading { font-family: var(--font-body); font-weight: 700; font-size: 15px; color: var(--color-ink); margin: 0 0 10px; }
.dog-card__photo-upload-row { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 14px; }
.dog-card__photo-choose-label { cursor: pointer; }
.dog-card__photo-filename { font-size: .9em; color: var(--color-muted); word-break: break-all; }
/* Wzorzec "visually hidden, ale nadal dostępny klawiaturą/czytnikiem ekranu"
   (sr-only) - w odróżnieniu od .hp-field (honeypot) to jest prawdziwe,
   używane pole formularza, tylko wizualnie zastąpione przyciskiem-labelką. */
.file-input-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* BUG MOBILE /panel/psy/ - JEDEN, KOŃCOWY zestaw reguł mobile dla karty psa
   (20.09.2026). Umieszczony CELOWO jako ostatni w tej sekcji pliku - każda
   z powyższych, bezwarunkowych reguł `.dog-card`/`.dog-card__media`/
   `.dog-card__body`/`.dog-card__questionnaire`/`.dog-card__edit-form`/
   `.dog-card__photo-upload` ma tę samą specyficzność (0,0,1,0) jak swój
   odpowiednik tutaj - przy remisie wygrywa reguła PÓŹNIEJSZA w źródle, więc
   ten blok, jako ostatni, zawsze wygrywa na <=640px. Dwie wcześniejsze próby
   mobile-owego override'u (grid-gap/padding w bloku przy `.dogs-list`, potem
   grid-row w bloku przy `.dog-card__media`) siedziały PRZED tymi bazowymi
   regułami i dlatego były cicho ignorowane - usunięte, skonsolidowane tutaj.
   Na mobile grid jest CAŁKOWICIE wyłączony (display:block) - .dog-card__body
   i pełnoszerokościowe sekcje po prostu stackują się w naturalnej kolejności
   DOM, zero rywalizacji o grid-row/column. .dog-card__media dostaje jawną
   szerokość/wysokość (166px = 150px zdjęcie + 8px padding z każdej strony,
   patrz baza wyżej) + `margin-inline:auto` - bez tego, jako zwykły blok,
   rozciągałby się na 100% szerokości rodzica, a border-radius:50% na
   szerokim-ale-niskim boksie dawał widoczny w zgłoszeniu "pionowy owal"
   zamiast koła. */
@media (max-width: 640px) {
  .dog-card {
    display: block;
    max-width: 100%;
    padding: 24px;
    box-sizing: border-box;
  }
  .dog-card__media {
    display: block;
    width: 166px;
    height: 166px;
    margin: 0 auto;
  }
  .dog-card__body {
    display: block;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    margin-top: 20px;
  }
  .dog-card__questionnaire,
  .dog-card__edit-form,
  .dog-card__photo-upload {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }
  .dog-card__actions {
    display: flex;
    flex-direction: column;
    width: 100%;
  }
  .dog-card__actions .btn {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }
  .dog-card__archive-btn {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    justify-content: center;
  }
}

/* Popr. po live review — usunięty duży, pusty różowy pasek. "+ Dodaj psa"
   to teraz WYŁĄCZNIE duży różowy przycisk (.btn.btn--primary.btn--large na
   <summary> w HTML) osadzony w rzędzie obok nagłówka sekcji (.dogs-header
   wyżej). Domknięty .dog-add zajmuje tylko szerokość przycisku
   (flex: 0 0 auto - dziedziczone z domyślnego zachowania flex item), więc
   nie ma już efektu "wielkiego pustego pudła". Otwarty (klient kliknął
   przycisk) rozciąga się na pełny wiersz (flex-basis:100%) i formularz
   dostaje własną, jasną kartę - <details>/<summary> i cała reszta
   zachowania BEZ ZMIAN (natywny toggle, ten sam #dog-add-form, te same ID
   pól) - wyłącznie warstwa wizualna. */
.dog-add { position: relative; flex: 0 0 auto; }
.dog-add[open] { flex-basis: 100%; }
.dog-add summary { cursor: pointer; list-style: none; }
.dog-add summary::-webkit-details-marker { display: none; }
.dog-add__form {
  margin-top: 24px;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 28px;
}
.questionnaire-section { border: none; padding: 0; margin: 0 0 24px; }
.questionnaire-section__fields { display: flex; flex-direction: column; gap: 14px; margin-top: 10px; }

/* KOREKTA "final polish" §38 - nowe typy pytań ankiety startowej (scale/
   single/multi/yesno) - proste, dostępne (radio/checkbox+label, klawiatura
   działa natywnie), spójne z resztą systemu formularzy (.field, kolory
   fuksji przy zaznaczeniu). */
.field__question-label { font-family: var(--font-body); font-weight: 700; font-size: .95em; color: var(--color-ink); margin: 0 0 8px; }
.scale-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.scale-pills__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: var(--border-width) solid var(--color-line);
  font-size: .85em;
  font-weight: 700;
  color: var(--color-text);
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.scale-pills__option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.scale-pills__option:has(input:checked) { background: var(--color-fuchsia); border-color: var(--color-fuchsia); color: var(--color-white); }
.scale-pills__option:has(input:focus-visible) { outline: 2px solid var(--color-fuchsia); outline-offset: 2px; }
.scale-pills__anchors { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; font-size: .82em; color: var(--color-muted); }
.choice-list { display: flex; flex-direction: column; gap: 8px; }
.choice-list__option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: var(--border-width) solid var(--color-line);
  /* Etap 9E.4 §17 polecenia - choice cards ok. 14-16px, --radius-md (24px)
     wyglądał zbyt "pigułkowo" na tak kompaktowym elemencie listy. */
  border-radius: var(--radius-sm);
  font-size: .92em;
  color: var(--color-text);
  cursor: pointer;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.choice-list__option:has(input:checked) { background: var(--color-fuchsia-soft); border-color: var(--color-fuchsia); color: var(--color-ink); font-weight: 700; }
.choice-list__option:has(input:focus-visible) { outline: 2px solid var(--color-fuchsia); outline-offset: 2px; }

/* "Finalna ankieta startowa" (13.09.2026) - wizard "jedno pytanie na
   ekran" (panel/psy/index.html, script.js buildQuestionnaireWizard()),
   zastępuje poprzedni jednoekranowy formularz ze wszystkimi sekcjami
   naraz. Reużywa istniejących .scale-pills/.choice-list/.field/
   .form__summary (zero nowego systemu formularzy) - poniższe klasy to
   wyłącznie powłoka/layout wokół tych już istniejących komponentów. */
.questionnaire-wizard { max-width: 520px; }
.questionnaire-wizard__category { margin: 0 0 6px; }
.questionnaire-wizard__progress-label { font-size: .82em; color: var(--color-muted); margin: 0 0 8px; }
.questionnaire-wizard__progress-bar { height: 6px; border-radius: 999px; background: var(--color-surface-alt); overflow: hidden; margin-bottom: 22px; }
.questionnaire-wizard__progress-fill { height: 100%; background: var(--color-fuchsia); border-radius: 999px; transition: width .2s var(--ease); }
/* "Questionnaire optional/skip flow" (13.09.2026) - §2 polecenia: spokojny
   helper text pod "Pytanie X z 22", świadomie ten sam przygaszony,
   drobny styl co reszta pomocniczych podpowiedzi w tym komponencie
   (.questionnaire-wizard__helper niżej) - NIE wielki alert/box. */
.questionnaire-wizard__skip-hint { font-size: .85em; color: var(--color-muted); margin: 0 0 18px; }
.questionnaire-wizard__question { margin-bottom: 18px; }
.questionnaire-wizard__question-label { font-size: 1.05em; margin-bottom: 14px; }
.questionnaire-wizard__helper { font-size: .85em; color: var(--color-muted); margin: -10px 0 14px; }
.questionnaire-wizard__scale-extra { margin-top: 10px; width: 100%; box-sizing: border-box; }
.questionnaire-wizard__subfield { margin-top: 14px; }
.questionnaire-wizard__main-textarea textarea { min-height: 4.5em; }
/* "Questionnaire final 15" (13.09.2026) - nagłówek podpytania wewnątrz
   złożonych kroków `dual-scale` (krok 3: "W domu"/"Poza domem") i
   `compound` (krok 15: prior_work/anything_else) - mały eyebrow-podobny
   label oddzielający kolejne pod-pytania na tym samym ekranie. */
.questionnaire-wizard__sub-heading { font-weight: 700; font-size: .95em; color: var(--color-ink); margin: 22px 0 10px; }
/* §8 polecenia - "Pomiń to pytanie": subtelny tekstowy link, NIGDY drugi
   duży primary button - stąd zwykły <button> odchudzony do wyglądu linku
   (bez tła/ramki/paddingu), nie .btn--outline/.btn--primary. */
.questionnaire-wizard__skip-link {
  display: inline-block;
  margin-top: 16px;
  background: none;
  border: none;
  padding: 0;
  font-size: .9em;
  color: var(--color-muted);
  text-decoration: underline;
  cursor: pointer;
}
.questionnaire-wizard__skip-link:hover, .questionnaire-wizard__skip-link:focus-visible { color: var(--color-fuchsia-hover); }
.questionnaire-wizard__skip-link:focus-visible { outline: 2px solid var(--color-fuchsia); outline-offset: 3px; }
.questionnaire-wizard__error { margin-bottom: 18px; }
.questionnaire-wizard__nav { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.questionnaire-wizard__back:only-child { margin-left: 0; }
.questionnaire-wizard__nav .questionnaire-wizard__back[hidden] { display: none; }
.questionnaire-wizard__nav .questionnaire-wizard__next { margin-left: auto; }
.questionnaire-wizard__next:disabled { opacity: .5; cursor: not-allowed; }
.questionnaire-resume { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; max-width: 480px; }
.questionnaire-resume .btn { align-self: flex-start; }
.questionnaire-success { max-width: 480px; }
.questionnaire-success__heading { font-family: var(--font-display); font-size: 1.4em; margin: 0 0 10px; }
.questionnaire-success .btn { margin-top: 16px; }
/* BETA FINALNA ANKIETA (20.09.2026) §3 polecenia - "Zanim zaczniemy". */
.questionnaire-intro { max-width: 560px; }
.questionnaire-intro__heading { font-family: var(--font-display); font-size: 1.4em; margin: 0 0 14px; }
.questionnaire-intro p { margin: 0 0 14px; line-height: 1.6; color: var(--color-text); }
/* MAŁY PATCH UX (20.09.2026) §2 - ostatnie zdanie ("nie będzie można
   edytować") wyróżnione wizualnie, ale bez czerwonego/alarmowego stylu -
   pogrubienie + istniejący, neutralny kolor marki (fuksja), nie --color-error. */
.questionnaire-intro__emphasis { font-weight: 600; color: var(--color-fuchsia-hover); }
.questionnaire-intro .btn { margin-top: 6px; }
/* MIKROPOPRAWKA (20.09.2026) - krótki ekran potwierdzenia przed faktyczną
   wysyłką ankiety (między ostatnim pytaniem a POST-em), ten sam wzorzec co
   .questionnaire-intro/.questionnaire-success. */
.questionnaire-confirm { max-width: 480px; }
.questionnaire-confirm__heading { font-family: var(--font-display); font-size: 1.4em; margin: 0 0 10px; }
.questionnaire-confirm p { margin: 0 0 14px; line-height: 1.6; color: var(--color-text); }
.questionnaire-confirm .btn { margin-top: 6px; margin-right: 10px; }
@media (prefers-reduced-motion: reduce) {
  .questionnaire-wizard__progress-fill { transition: none; }
}

/* =========================================================
   Panel — Zasady i instrukcje (etap 9 §8-9, panel/zasady/).
   PRZEBUDOWANE "live review 3" - dedykowany, page-scoped komponent
   (.rules-section/.rules-accordion*) zamiast reużycia globalnego
   .accordion (poprzednia tura) - jawne żądanie tej tury, niezależne od
   FAQ homepage. Wcześniejsze `.rules-group`/`.rules-group__heading`
   USUNIĘTE jako martwy kod (HTML już ich nie używa).
   ========================================================= */
/* "Final UI pass" (13.09.2026) - CAŁA strona (intro + obie grupy
   accordionów) żyje dziś w JEDNYM .section-shell--rules (patrz wyżej) -
   odstęp intro→pierwsza sekcja liczy się z .section-shell__header{margin-
   bottom:32px}, nie z samego leadu. Poprzednia reguła `.rules-page
   .panel-main__lead { margin-bottom: 40px; }` jest USUNIĘTA (nadawałaby
   margines WEWNĄTRZ kolorowego boxu, nie pod nim). Sam spacing MIĘDZY
   dwiema grupami accordionów (.rules-section margin-bottom, patrz niżej)
   jest CAŁKOWICIE nietknięty tą turą. */
/* "Visual polish" (13.09.2026) - ZNALEZIONA PRZYCZYNA "ogromnych przerw"
   (nie tylko mobile): globalna, sitewide reguła elementu `section {
   padding-block: var(--section-pad) }` (56px, pomyślana dla dużych
   sekcji marketingowych homepage) cicho stosowała się też TUTAJ, bo
   `.rules-section` jest semantycznie `<section>`. Efekt: każda grupa
   dostawała DODATKOWE 56px paddingu na górze I na dole, ponad własny
   margin-bottom (36px) - między ostatnim akordeonem grupy a kolejnym
   nagłówkiem realnie było blisko 150px, nie 36px zadeklarowane w tym
   komponencie. Jawny reset do 0 usuwa tę ukrytą, przypadkową warstwę -
   cała reszta odstępu poniżej jest już w pełni jawna/zamierzona. */
/* POPRAWKA: COPY + SCROLL DO SEKCJI ZASAD (19.09.2026) - mały odstęp od
   góry przy scrollIntoView() z linków "Jak przygotować się do zajęć?"
   (script.js, openAccordionSectionFromHash()), żeby nagłówek panelu nie
   przylegał bezpośrednio do początku sekcji - ten sam wzorzec co
   .testimonials na homepage. */
.rules-section { padding-block: 0; margin-bottom: 32px; scroll-margin-top: 24px; }
.rules-section:last-child { margin-bottom: 0; }
@media (min-width: 768px) { .rules-section { margin-bottom: 44px; } }
.rules-section__heading { font-family: var(--font-display); font-weight: 600; font-size: 1.6rem; color: var(--color-ink); margin-bottom: 14px; }
@media (min-width: 768px) { .rules-section__heading { font-size: 1.85rem; margin-bottom: 20px; } }

/* Zwarty akordeon: każda pozycja to WŁASNA biała karta (border+radius
   panelu), nie płaska lista z border-top/border-bottom (jak FAQ) - stąd
   osobny komponent zamiast .accordion. Karty mają naturalną wysokość
   (brak min-height) i małe odstępy (gap), więc bez "ogromnych przerw"
   znanych z poprzedniej wersji. */
.rules-accordion { display: flex; flex-direction: column; gap: 8px; }
@media (min-width: 768px) { .rules-accordion { gap: 12px; } }
.rules-accordion__item {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  scroll-margin-top: 24px;
}
.rules-accordion__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 18px;
  text-align: left;
  background: none;
  border: none;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
}
@media (min-width: 768px) { .rules-accordion__trigger { padding: 20px 22px; } }
.rules-accordion__icon { width: 20px; height: 20px; flex-shrink: 0; color: var(--color-muted); transition: transform .22s var(--ease), color .18s var(--ease); }
.rules-accordion__trigger:hover .rules-accordion__icon,
.rules-accordion__trigger:focus-visible .rules-accordion__icon,
.rules-accordion__trigger[aria-expanded="true"] .rules-accordion__icon { color: var(--color-fuchsia); }
.rules-accordion__trigger[aria-expanded="true"] .rules-accordion__icon { transform: rotate(45deg); }
.rules-accordion__trigger:hover span { text-decoration: underline; text-decoration-color: var(--color-fuchsia); text-decoration-thickness: 2px; text-underline-offset: 5px; }
.rules-accordion__panel { padding: 0 18px 18px; max-width: 68ch; }
@media (min-width: 768px) { .rules-accordion__panel { padding: 0 22px 20px; } }
.rules-accordion__panel p { font-size: .95em; line-height: 1.55; color: var(--color-text); }
.rules-accordion__panel p + p { margin-top: 10px; }
/* KOREKTA "final polish" §21 - `.rules-accordion__panel a{color:fuchsia}`
   (bez :not(.btn)) miało WYŻSZĄ specyficzność (0,1,1) niż `.btn--primary`
   (0,1,0), więc wygrywał na CTA "Napisz do Martyny" - tekst fuksja NA
   tle fuksja, czyli wizualnie pusty, różowy przycisk (dokładnie zgłoszony
   błąd). `:not(.btn)` ogranicza tę regułę do zwykłych tekstowych linków,
   `.btn--primary`/`:hover`/`:focus-visible` (globalne, białe na fuksji)
   znów w pełni rządzą przyciskiem - widoczny tekst, prawidłowy kontrast,
   normalny hover/focus (dziedziczone z komponentu .btn, nietknięte). */
.rules-accordion__panel a:not(.btn) { color: var(--color-fuchsia); font-weight: 700; }
.rules-accordion__panel a:not(.btn):hover, .rules-accordion__panel a:not(.btn):focus-visible { color: var(--color-fuchsia-hover); }
@media (prefers-reduced-motion: reduce) {
  .rules-accordion__icon { transition: none; }
}

/* KOREKTA "live review 4" §5-§7 - instrukcje zajęć priorytetyzują "Jak się
   przygotować?" (zwarta, skanowalna lista) nad opisem przebiegu zajęć.
   .rules-prep__heading/__list to GŁÓWNA treść panelu (zawsze widoczna po
   otwarciu akordeonu); .rules-details to natywny <details>/<summary> -
   drugorzędny, domyślnie zwinięty blok "Jak wyglądają zajęcia?" - zero
   nowego JS (natywna funkcja przeglądarki), dodawany WYŁĄCZNIE gdy wnosi
   realną wartość (część typów zajęć go nie ma). */
.rules-prep__heading { font-family: var(--font-display); font-weight: 600; font-size: 1em; color: var(--color-ink); margin: 0 0 8px; }
.rules-prep__list { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.rules-prep__list li { font-size: .95em; line-height: 1.5; color: var(--color-text); }
.rules-prep__list + .rules-details { margin-top: 14px; }
.rules-details summary {
  font-size: .92em;
  font-weight: 700;
  color: var(--color-fuchsia);
  cursor: pointer;
  list-style: none;
}
.rules-details summary::-webkit-details-marker { display: none; }
.rules-details summary::before { content: "+ "; }
.rules-details[open] summary::before { content: "- "; }
.rules-details p { font-size: .92em; line-height: 1.5; color: var(--color-text); margin-top: 8px; }

/* =========================================================
   Panel — Kontakt i społeczność (etap 9 §23, przebudowane turą
   "Content + Mobile + Panel UX", panel/kontakt/).
   ========================================================= */
/* "Final UI pass" (13.09.2026) - CTA żyje teraz WEWNĄTRZ .section-shell--
   contact (§12 polecenia - "nie może zostać drugi osobny różowy box").
   .contact-community traci własne tło/padding - zostaje WYŁĄCZNIE
   wyśrodkowującym wrapperem, bez żadnego koloru/karty na drugim poziomie. */
.contact-community {
  margin-top: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

/* =========================================================
   Panel — Kursy online (etap 9 §22, panel/kursy/).
   ========================================================= */
.courses-grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
@media (min-width: 640px) { .courses-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .courses-grid { grid-template-columns: repeat(3, 1fr); } }
.course-card {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  padding: 24px;
  text-align: center;
}
.course-card--locked { opacity: .92; }
/* Status "Masz dostęp"/"Dostęp do kupienia" (polecenie "Content + Mobile +
   Panel UX" §17-18) - subtelna ikona kłódki wyłącznie przy braku dostępu,
   jako wizualna informacja, nie zabezpieczenie (patrz komentarz w HTML). */
.course-card__status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 5px 14px;
  border-radius: var(--radius-pill);
  font-size: .8em;
  font-weight: 700;
  margin-bottom: 14px;
  background: var(--color-fuchsia-soft);
  color: var(--color-fuchsia-hover);
}
.course-card--locked .course-card__status { background: var(--color-surface-alt); color: var(--color-muted); }
.course-card__lock { width: 14px; height: 14px; flex-shrink: 0; }
.course-card__lock[hidden] { display: none; }
.course-card__title { font-family: var(--font-display); font-weight: 600; font-size: 1.1rem; color: var(--color-ink); margin-bottom: 12px; }
.courses-empty {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  padding: 28px 24px;
  color: var(--color-muted);
  font-size: .95em;
}

/* =========================================================
   Panel — Onboarding (etap 9 §7, panel/onboarding/). Świadomie BEZ
   .panel-nav/.panel-status-badge - onboarding poprzedza zwykły Dashboard.
   ========================================================= */
.onboarding-page { max-width: 640px; }
/* BETA BLOCKER: ONBOARDING + RESET HASŁA (20.09.2026) §2 polecenia -
   duża pusta przestrzeń między "Cześć!" a "1. Dodaj swojego psa" -
   .panel-main__lead (współdzielone z resztą panelu) ma margin-bottom:40px,
   .onboarding-step miało dodatkowo margin-top:32px - te dwie wartości
   kolapsują się do 40px, co na tak krótkiej, jednostronicowej ścieżce
   (intro → krok 1 → krok 2 → koniec) wyglądało na zbyt duży odstęp.
   Scoped WYŁĄCZNIE do leadu na tej stronie (.onboarding-page), nie rusza
   .panel-main__lead gdzie indziej w panelu. */
.onboarding-page .panel-main__lead { margin-bottom: 16px; }
/* BETA — "MOJE DANE" + SPACING PIERWSZEGO LOGOWANIA (20.09.2026) §4 -
   powyższa korekta z poprzedniej tury nie usunęła całego problemu:
   .onboarding-step to <section>, więc dziedziczyło globalne
   `section { padding-block: var(--section-pad) }` (56px na mobile, do
   136px od 1440px) - DODATKOWO do margin-top, czyli realny odstęp przed
   "1. Dodaj swojego psa" sięgał nawet ~160px na desktopie. Ten sam,
   już wcześniej ustalony wzorzec co `.quiz-step { padding-block:0 }`
   (kroki UI wewnątrz strony, nie sekcje strony same w sobie). */
.onboarding-step { padding-block: 0; margin-top: 24px; }
.onboarding-step[hidden] { display: none; }
.onboarding-step h2 { font-family: var(--font-display); font-weight: 600; font-size: 1.2rem; color: var(--color-ink); margin-bottom: 14px; }
.onboarding-rules-list { display: flex; flex-direction: column; gap: 12px; margin: 0 0 24px; padding-left: 20px; }
.onboarding-rules-list li { font-size: .95em; line-height: 1.5; color: var(--color-text); }
#onboarding-dog-added { font-weight: 700; color: var(--color-fuchsia); margin-top: 12px; }
#onboarding-dog-added[hidden] { display: none; }

/* =========================================================
   NOWA STATYCZNA STRONA /regulamin/ (21.09.2026) - reużywa .info-section/
   .info-section--surface/--fuchsia (naprzemienne tło, ten sam rytm co
   /klasy/), .work-tile__list (listy). Dwie nowe, wąskie klasy poniżej
   wypełniają jedyną realną lukę design systemu: brak umiarkowanej
   (nie hero-owej) klasy nagłówka dla wielu kolejnych sekcji na jednej
   stronie prawnej, i brak subtelnego, wyróżnionego boxu na dane firmy -
   obie zbudowane WYŁĄCZNIE z istniejących tokenów, zero nowych wartości.
   ========================================================= */
.legal-content p { max-width: 68ch; font-size: .96em; line-height: 1.65; color: var(--color-text); }
.legal-content p + p { margin-top: 16px; }
.legal-content .work-tile__list { max-width: 68ch; }
.legal-content .work-tile__list + p { margin-top: 16px; }
.legal-content__heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.1;
  color: var(--color-ink);
  letter-spacing: -.01em;
  margin-bottom: 20px;
}
.legal-info-box {
  background: var(--color-surface-alt);
  border-radius: var(--radius-sm);
  padding: 20px 24px;
  margin: 16px 0;
  max-width: 68ch;
}
.legal-info-box p { margin: 0; max-width: none; }
.legal-info-box a { color: var(--color-fuchsia); font-weight: 700; }
.legal-info-box a:hover, .legal-info-box a:focus-visible { color: var(--color-fuchsia-hover); }

/* KOREKTA PROJEKTU ANKIETY OKRESOWEJ (22.09.2026) §1 - cytat poprzedniej odpowiedzi klienta (hardest_now), przywoływany przed pytaniem "Jak jest z tym dzisiaj?". */
.checkpoint-recall-quote { font-style: italic; color: var(--color-text); background: var(--color-surface-alt); border-radius: var(--radius-sm); padding: 14px 18px; margin: 0 0 16px; }

/* PRE-MEETING QUESTIONNAIRE POLISH */

.pre-meeting-card .field__input,
.pre-meeting-card .field__textarea {
  width: 100%;
  box-sizing: border-box;
  border-radius: 16px;
  padding: 14px 16px;
  font: inherit;
}

.pre-meeting-card .field__textarea {
  min-height: 110px;
  resize: vertical;
}

.pre-meeting-card .choice-list {
  margin-top: 18px;
}

.pre-meeting-card .questionnaire-wizard__skip-link {
  margin-top: 14px;
}

.pre-meeting-card .questionnaire-wizard__category {
  margin-bottom: 8px;
}

.pre-meeting-card .questionnaire-wizard__nav {
  margin-top: 24px;
}


/* PRE-MEETING FRAME V5 START */

/* =========================================================
   PRE-MEETING — spójne z późniejszym panelem
   ========================================================= */

.pre-meeting-hero,
.pre-meeting-section {
  background:
    radial-gradient(circle at top center, rgba(242, 223, 70, 0.10), transparent 34%),
    linear-gradient(180deg, #F7F3F6 0%, #F3EEF2 100%);
}

.pre-meeting-hero {
  padding: 72px 0 28px;
  border: 0;
}

.pre-meeting-section {
  padding: 12px 0 86px;
  border: 0;
}

/* =========================================================
   HERO
   ========================================================= */

.pre-meeting-hero .quiz-hero__inner {
  width: min(980px, calc(100% - 40px));
  margin: 0 auto;
  text-align: center;
}

.pre-meeting-hero .quiz-hero__heading {
  margin: 0 auto 18px;
  max-width: none;

  color: #D52D8B;
  font-size: clamp(52px, 5vw, 84px);
  line-height: 0.95;
  white-space: nowrap;
}

.pre-meeting-hero .quiz-hero__text {
  max-width: 680px;
  margin: 0 auto;

  color: #2E2930;
  font-size: 18px;
  line-height: 1.55;
}

/* =========================================================
   SZEROKOŚĆ ANKIETY
   ========================================================= */

.pre-meeting-section .quiz-section__inner {
  width: min(760px, calc(100% - 40px));
  margin: 0 auto;
}

/* =========================================================
   KARTA
   ========================================================= */

.pre-meeting-card {
  position: relative;
  background: #FFFFFF;
  color: #232127;

  border: 1px solid #E7DCE5;
  border-radius: 28px;

  padding: 42px 46px;

  box-shadow: 0 20px 50px rgba(35, 33, 39, 0.08);
  overflow: hidden;
}

.pre-meeting-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 6px;
  background: linear-gradient(90deg, #D52D8B 0%, #F2DF46 100%);
}

.pre-meeting-card::after {
  content: "";
  position: absolute;
  right: -60px;
  top: -60px;
  width: 180px;
  height: 180px;
  background: radial-gradient(circle, rgba(213, 45, 139, 0.08), transparent 70%);
  pointer-events: none;
}

/* =========================================================
   START
   ========================================================= */

#pre-meeting-start {
  min-height: 150px;

  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  text-align: center;
}

#pre-meeting-start .quiz-step__question {
  margin: 0 0 24px;
  color: #232127;
  font-size: clamp(40px, 4.5vw, 54px);
  line-height: 1;
}

#pre-meeting-start .btn {
  min-width: 165px;
}

/* =========================================================
   POSTĘP I NAGŁÓWKI
   ========================================================= */

.pre-meeting-card .questionnaire-wizard__progress-label {
  margin: 0;
  color: #746D77;
}

.pre-meeting-card .questionnaire-wizard__progress-bar {
  height: 4px;
  margin: 0 0 28px;
  background: #E8E1E7;
  border-radius: 999px;
  overflow: hidden;
}

.pre-meeting-card .questionnaire-wizard__progress-fill {
  height: 100%;
  background: #D52D8B;
  border-radius: 999px;
}

.pre-meeting-card .questionnaire-wizard__category {
  margin: 0 0 12px;
  color: #8A818D;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.pre-meeting-card .questionnaire-wizard__category::before {
  content: none;
}

.pre-meeting-card .quiz-step__question {
  margin: 0 0 22px;
  color: #232127;
  font-size: clamp(28px, 3vw, 38px);
  line-height: 1.08;
}

/* =========================================================
   ODPOWIEDZI
   ========================================================= */

.pre-meeting-card .choice-list {
  display: grid;
  gap: 10px;
  margin-top: 18px;
}

.pre-meeting-card .choice-list__option {
  min-height: 56px;
  display: flex;
  align-items: center;
  gap: 12px;

  padding: 14px 17px;

  background: #FBF9FB;
  border: 1px solid #E5DDE4;
  border-radius: 18px;

  color: #2B252B;

  transition:
    background .18s ease,
    border-color .18s ease,
    transform .18s ease,
    box-shadow .18s ease;
}

.pre-meeting-card .choice-list__option:hover {
  background: #FFFDFE;
  border-color: #D6C6D1;
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(35, 33, 39, 0.06);
}

.pre-meeting-card .choice-list__option:has(input:checked) {
  background: #FFF0F8;
  border-color: #D52D8B;
}

.pre-meeting-card input[type="checkbox"],
.pre-meeting-card input[type="radio"] {
  accent-color: #D52D8B;
}

/* =========================================================
   INPUTY
   ========================================================= */

.pre-meeting-card .field__input,
.pre-meeting-card .field__textarea,
.pre-meeting-card input[type="text"],
.pre-meeting-card input[type="email"],
.pre-meeting-card textarea,
.pre-meeting-card select {
  width: 100%;
  box-sizing: border-box;

  background: #FFFFFF;
  color: #232127;

  border: 1px solid #DED3DB;
  border-radius: 18px;

  padding: 15px 17px;

  font: inherit;
  outline: none;

  transition:
    border-color .18s ease,
    box-shadow .18s ease,
    background .18s ease;
}

.pre-meeting-card input::placeholder,
.pre-meeting-card textarea::placeholder {
  color: #948A95;
}

.pre-meeting-card .field__input:focus,
.pre-meeting-card .field__textarea:focus,
.pre-meeting-card input[type="text"]:focus,
.pre-meeting-card input[type="email"]:focus,
.pre-meeting-card textarea:focus,
.pre-meeting-card select:focus {
  border-color: #D52D8B;
  box-shadow: 0 0 0 3px rgba(213, 45, 139, 0.14);
  background: #FFFFFF;
}

/* =========================================================
   POMIŃ / NAV
   ========================================================= */

.pre-meeting-card .questionnaire-wizard__skip-link {
  display: inline-block;
  margin-top: 14px;
  padding: 2px 0;
  border: 0;
  background: transparent;

  color: #746D77;
  font-size: 13px;
  font-weight: 600;

  text-decoration: underline;
  text-underline-offset: 4px;
}

.pre-meeting-card .questionnaire-wizard__skip-link:hover {
  color: #232127;
}

.pre-meeting-card .questionnaire-wizard__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;

  margin-top: 28px;
  padding-top: 0;
  border: 0;
}

.pre-meeting-card .questionnaire-wizard__back {
  background: transparent;
  border-color: #D8CBD4;
  color: #5B535D;
}

.pre-meeting-card .questionnaire-wizard__back:hover {
  border-color: #C5B4C0;
  color: #232127;
}

/* =========================================================
   BŁĘDY
   ========================================================= */

.pre-meeting-card .field__error {
  color: #C83D5B;
}

/* =========================================================
   MOBILE
   ========================================================= */

@media (max-width: 900px) {
  .pre-meeting-hero .quiz-hero__heading {
    white-space: normal;
  }
}

@media (max-width: 700px) {
  .pre-meeting-hero {
    padding: 52px 0 24px;
  }

  .pre-meeting-hero .quiz-hero__inner {
    width: min(100% - 28px, 980px);
  }

  .pre-meeting-hero .quiz-hero__heading {
    font-size: 48px;
    margin-bottom: 16px;
  }

  .pre-meeting-hero .quiz-hero__text {
    font-size: 15px;
  }

  .pre-meeting-section {
    padding: 10px 0 56px;
  }

  .pre-meeting-section .quiz-section__inner {
    width: min(100% - 24px, 760px);
  }

  .pre-meeting-card {
    padding: 28px 22px;
    border-radius: 22px;
  }

  #pre-meeting-start .quiz-step__question {
    font-size: 36px;
  }
}

/* PRE-MEETING FRAME V5 END */


/* PRE-MEETING FINAL POLISH */

.pre-meeting-hero {
  padding: 48px 0 18px !important;
}

.pre-meeting-hero .quiz-hero__heading {
  font-size: clamp(48px, 4.6vw, 74px) !important;
  margin-bottom: 12px !important;
}

.pre-meeting-hero .quiz-hero__text {
  max-width: 620px !important;
  font-size: 17px !important;
}

.pre-meeting-section {
  padding-top: 4px !important;
}

.pre-meeting-section .quiz-section__inner {
  width: min(560px, calc(100% - 40px)) !important;
}

.pre-meeting-card {
  padding: 34px 38px !important;
  border-radius: 24px !important;
  box-shadow: 0 16px 38px rgba(35,33,39,.07) !important;
}

.pre-meeting-card::before,
.pre-meeting-card::after {
  content: none !important;
}

#pre-meeting-start {
  min-height: 110px !important;
}

#pre-meeting-start .quiz-step__question {
  font-size: 42px !important;
  margin-bottom: 20px !important;
}

@media (max-width: 700px) {
  .pre-meeting-hero {
    padding-top: 36px !important;
  }

  .pre-meeting-section .quiz-section__inner {
    width: min(100% - 24px, 560px) !important;
  }

  .pre-meeting-card {
    padding: 26px 22px !important;
  }
}


/* PRE-MEETING PANEL MATCH V1 START */

/* =========================================================
   CAŁA STREFA = JĘZYK PANELU
   ========================================================= */

.pre-meeting-hero,
.pre-meeting-section {
  background: #F1F1F3 !important;
  background-image: none !important;
  border: 0 !important;
}


/* =========================================================
   HERO
   ========================================================= */

.pre-meeting-hero {
  padding: 46px 0 20px !important;
}

.pre-meeting-hero .quiz-hero__inner {
  width: min(1000px, calc(100% - 40px)) !important;
  margin: 0 auto !important;
  text-align: center !important;
}

.pre-meeting-hero .quiz-hero__heading {
  margin: 0 auto 14px !important;
  max-width: none !important;

  color: #D52D8B !important;

  font-size: clamp(46px, 4.3vw, 68px) !important;
  line-height: .98 !important;
}

.pre-meeting-hero .quiz-hero__text {
  max-width: 620px !important;
  margin: 0 auto !important;

  color: #4F4B53 !important;

  font-size: 16px !important;
  line-height: 1.5 !important;
}


/* =========================================================
   SEKCJA ANKIETY
   ========================================================= */

.pre-meeting-section {
  padding: 8px 0 72px !important;
}

.pre-meeting-section .quiz-section__inner {
  width: min(680px, calc(100% - 40px)) !important;
  margin: 0 auto !important;
}


/* =========================================================
   KARTA JAK W PANELU
   ========================================================= */

.pre-meeting-card {
  position: relative !important;

  background: #FFFFFF !important;

  border: 1px solid #D4D1D7 !important;
  border-radius: 26px !important;

  padding: 36px 40px !important;

  color: #232127 !important;

  box-shadow:
    0 12px 30px rgba(35, 33, 39, .06) !important;

  overflow: hidden !important;
}

.pre-meeting-card::before,
.pre-meeting-card::after {
  content: none !important;
  display: none !important;
}


/* =========================================================
   WAŻNE: START ZNIKA PO URUCHOMIENIU WIZARDA
   ========================================================= */

.pre-meeting-card:has(#pre-meeting-wizard:not([hidden]))
#pre-meeting-start {
  display: none !important;
}


/* =========================================================
   START
   ========================================================= */

#pre-meeting-start {
  min-height: 110px !important;

  display: flex;
  flex-direction: column;

  justify-content: center;
  align-items: center;

  text-align: center;
}

#pre-meeting-start .quiz-step__question {
  margin: 0 0 20px !important;

  color: #232127 !important;

  font-size: 38px !important;
  line-height: 1 !important;
}


/* =========================================================
   PYTANIA
   ========================================================= */

.pre-meeting-card .questionnaire-wizard__category {
  margin: 0 0 9px !important;

  color: #746F78 !important;

  font-size: 11px !important;
  font-weight: 700 !important;

  letter-spacing: .09em !important;
  text-transform: uppercase !important;
}

.pre-meeting-card .questionnaire-wizard__category::before {
  content: none !important;
}

.pre-meeting-card .quiz-step__question {
  margin: 0 0 22px !important;

  color: #232127 !important;

  font-size: clamp(28px, 3vw, 36px) !important;
  line-height: 1.08 !important;
}


/* =========================================================
   POSTĘP
   ========================================================= */

.pre-meeting-card .questionnaire-wizard__progress-label {
  display: none !important;
}

.pre-meeting-card .questionnaire-wizard__progress-bar {
  height: 4px !important;

  margin: 0 0 28px !important;

  background: #E7E7EA !important;

  border-radius: 999px !important;

  overflow: hidden !important;
}

.pre-meeting-card .questionnaire-wizard__progress-fill {
  height: 100% !important;

  background: #D52D8B !important;

  border-radius: 999px !important;
}


/* =========================================================
   ODPOWIEDZI
   ========================================================= */

.pre-meeting-card .choice-list {
  display: grid !important;
  gap: 10px !important;

  margin-top: 16px !important;
}

.pre-meeting-card .choice-list__option {
  min-height: 54px !important;

  display: flex !important;
  align-items: center !important;

  gap: 12px !important;

  padding: 14px 16px !important;

  background: #F7F7F8 !important;

  border: 1px solid #D4D1D7 !important;
  border-radius: 17px !important;

  color: #232127 !important;

  box-shadow: none !important;

  transition:
    background .18s ease,
    border-color .18s ease,
    transform .18s ease !important;
}

.pre-meeting-card .choice-list__option:hover {
  background: #FFFFFF !important;

  border-color: #AAA5AD !important;

  transform: translateY(-1px) !important;

  box-shadow: none !important;
}

.pre-meeting-card .choice-list__option:has(input:checked) {
  background: #F9DCEA !important;

  border-color: #D52D8B !important;
}

.pre-meeting-card input[type="checkbox"],
.pre-meeting-card input[type="radio"] {
  accent-color: #D52D8B !important;
}


/* =========================================================
   INPUTY
   ========================================================= */

.pre-meeting-card .field__input,
.pre-meeting-card .field__textarea,
.pre-meeting-card input[type="text"],
.pre-meeting-card input[type="email"],
.pre-meeting-card textarea,
.pre-meeting-card select {
  width: 100% !important;

  box-sizing: border-box !important;

  background: #FFFFFF !important;
  color: #232127 !important;

  border: 1px solid #D4D1D7 !important;
  border-radius: 17px !important;

  padding: 14px 16px !important;

  font: inherit !important;

  outline: none !important;

  box-shadow: none !important;
}

.pre-meeting-card input::placeholder,
.pre-meeting-card textarea::placeholder {
  color: #8A858D !important;
}

.pre-meeting-card .field__input:focus,
.pre-meeting-card .field__textarea:focus,
.pre-meeting-card input[type="text"]:focus,
.pre-meeting-card input[type="email"]:focus,
.pre-meeting-card textarea:focus,
.pre-meeting-card select:focus {
  border-color: #D52D8B !important;

  box-shadow:
    0 0 0 3px rgba(213, 45, 139, .12) !important;
}


/* =========================================================
   POMIŃ
   ========================================================= */

.pre-meeting-card .questionnaire-wizard__skip-link {
  display: inline-block !important;

  margin-top: 14px !important;
  padding: 2px 0 !important;

  border: 0 !important;

  background: transparent !important;

  color: #746F78 !important;

  font-size: 13px !important;
  font-weight: 600 !important;

  text-decoration: underline !important;
  text-underline-offset: 4px !important;
}

.pre-meeting-card .questionnaire-wizard__skip-link:hover {
  color: #D52D8B !important;
}


/* =========================================================
   NAWIGACJA
   ========================================================= */

.pre-meeting-card .questionnaire-wizard__nav {
  display: flex !important;

  justify-content: space-between !important;
  align-items: center !important;

  gap: 14px !important;

  margin-top: 28px !important;
  padding-top: 0 !important;

  border: 0 !important;
}


/* =========================================================
   FINAŁ
   ========================================================= */

.pre-meeting-card .questionnaire-success,
.pre-meeting-card .questionnaire-confirm {
  text-align: left !important;
}

.pre-meeting-card .questionnaire-success__heading {
  color: #232127 !important;

  font-size: 36px !important;
}


/* =========================================================
   BŁĘDY
   ========================================================= */

.pre-meeting-card .field__error,
.pre-meeting-card .form__summary {
  color: #B42318 !important;
}


/* =========================================================
   MOBILE
   ========================================================= */

@media (max-width: 900px) {

  .pre-meeting-hero .quiz-hero__heading {
    white-space: normal !important;
  }

}

@media (max-width: 700px) {

  .pre-meeting-hero {
    padding: 38px 0 18px !important;
  }

  .pre-meeting-hero .quiz-hero__inner {
    width: min(100% - 28px, 1000px) !important;
  }

  .pre-meeting-hero .quiz-hero__heading {
    font-size: 44px !important;
  }

  .pre-meeting-hero .quiz-hero__text {
    font-size: 15px !important;
  }

  .pre-meeting-section {
    padding: 6px 0 52px !important;
  }

  .pre-meeting-section .quiz-section__inner {
    width: min(100% - 24px, 680px) !important;
  }

  .pre-meeting-card {
    padding: 26px 22px !important;

    border-radius: 22px !important;
  }

  #pre-meeting-start .quiz-step__question {
    font-size: 34px !important;
  }

}

/* PRE-MEETING PANEL MATCH V1 END */

/* PANEL_HOWTO_CSS_START */

.panel-howto-card {
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
}

.panel-howto-card__summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 22px;
  cursor: pointer;
  color: var(--color-ink);
}

.panel-howto-card__summary::-webkit-details-marker {
  display: none;
}

.panel-howto-card__summary > span:first-child {
  min-width: 0;
}

.panel-howto-card__summary strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.08rem;
  font-weight: 600;
}

.panel-howto-card__summary small {
  display: block;
  margin-top: 2px;
  color: var(--color-muted);
  font-size: .85rem;
}

.panel-howto-card__chevron {
  color: var(--color-fuchsia);
  font-size: 1.5rem;
  line-height: 1;
  transition: transform .15s var(--ease);
}

.panel-howto-card[open] .panel-howto-card__chevron {
  transform: rotate(180deg);
}

.panel-howto-card__body {
  padding: 0 22px 22px;
  border-top: var(--border-width) solid var(--color-line);
}

.panel-howto-card__grid {
  display: grid;
  grid-template-columns: 1fr;
}

.panel-howto-card__item {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 16px 0;
  color: inherit;
  border-bottom: var(--border-width) solid var(--color-line);
}

.panel-howto-card__item:last-child {
  border-bottom: 0;
}

/* Trwałe wyłączenie instrukcji (25.09.2026) - "Nie pokazuj więcej" jest
   dyskretne (btn--link), nie konkuruje wizualnie z 6 pozycjami instrukcji
   powyżej. Confirm mirrored po .goal-card__confirm (ten sam prosty wzorzec:
   pudełko + tekst + 2 przyciski), własna, scoped klasa - żeby nie dzielić
   stanu/stylu z niepowiązanym komponentem celów. */
.panel-howto-card__dismiss-row { margin: 16px 0 0; text-align: right; }
.panel-howto-card__confirm {
  margin-top: 12px;
  padding: 14px 16px;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
}
.panel-howto-card__confirm[hidden] { display: none; }
.panel-howto-card__confirm-text { margin: 0 0 12px; font-size: .95em; line-height: 1.5; color: var(--color-ink); }
.panel-howto-card__confirm-actions { display: flex; flex-wrap: wrap; gap: 10px; }

.panel-howto-card__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--color-fuchsia-soft);
  color: var(--color-fuchsia-hover);
  font-weight: 800;
  font-size: .85rem;
}

.panel-howto-card__item strong {
  display: block;
  color: var(--color-ink);
  font-size: .95rem;
}

.panel-howto-card__item small {
  display: block;
  margin-top: 2px;
  color: var(--color-muted);
  font-size: .86rem;
  line-height: 1.45;
}

.panel-howto-card__item:hover strong,
.panel-howto-card__item:focus-visible strong {
  color: var(--color-fuchsia-hover);
}

@media (min-width: 720px) {
  .panel-howto-card__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 28px;
  }
}

@media (max-width: 480px) {
  .panel-howto-card__summary {
    padding: 16px 18px;
  }

  .panel-howto-card__body {
    padding-inline: 18px;
  }
}

/* PANEL_HOWTO_CSS_END */
/* ONBOARDING_HOWTO_CSS_START */

.onboarding-howto__intro {
  color: var(--color-text);
  line-height: 1.6;
  margin: 0 0 20px;
}

.onboarding-howto {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 22px;
}

.onboarding-howto__item {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 14px 16px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.onboarding-howto__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--color-fuchsia-soft);
  color: var(--color-fuchsia-hover);
  font-weight: 800;
  font-size: .85rem;
  flex-shrink: 0;
}

.onboarding-howto__item strong {
  display: block;
  color: var(--color-ink);
  margin-bottom: 3px;
}

.onboarding-howto__item p {
  margin: 0;
  color: var(--color-text);
  font-size: .92em;
  line-height: 1.5;
}

.onboarding-howto__tip {
  margin: 4px 0 18px;
  padding: 16px 18px;
  border-radius: var(--radius-md);
  background: var(--color-fuchsia-soft);
  color: var(--color-text);
  line-height: 1.55;
}

.onboarding-howto__tip strong {
  color: var(--color-ink);
}

.onboarding-howto__contact {
  margin: 0 0 20px;
  color: var(--color-muted);
  font-size: .92em;
  line-height: 1.55;
}

@media (max-width: 480px) {
  .onboarding-howto__item {
    padding: 13px 14px;
  }
}

/* ONBOARDING_HOWTO_CSS_END */

/* DOCUMENTS_PAGE_UX_START */

.documents-page {
  max-width: 760px;
}

.documents-page #documents-form a {
  color: var(--color-fuchsia);
  font-weight: 700;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}

.documents-page #documents-form a:hover,
.documents-page #documents-form a:focus-visible {
  color: var(--color-fuchsia-hover);
}

.documents-page #documents-submit {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

@media (min-width: 700px) {
  .documents-page #documents-heading {
    white-space: nowrap;
  }
}

/* DOCUMENTS_PAGE_UX_END */


/* MEDIA CONSENTS UX 2026-09-23 */

.documents-form {
  display: grid;
  gap: 0;
}

.documents-group {
  padding: 20px 0;
}

.documents-group:first-child {
  padding-top: 2px;
}

.documents-group + .documents-group {
  border-top: 1px solid var(--color-line);
}

.documents-group__title-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}

.documents-group__heading {
  margin: 0 0 10px;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.35;
  font-weight: 700;
  color: var(--color-ink);
}

.documents-group__title-row .documents-group__heading {
  margin-bottom: 0;
}

.documents-group__optional {
  font-size: 0.78rem;
  line-height: 1;
  font-weight: 400;
  opacity: 0.6;
}

.documents-group__intro {
  margin: 0 0 13px;
  font-size: 0.92rem;
  line-height: 1.45;
}

.documents-check-row {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 7px 0;
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.4;
  font-weight: 400;
  cursor: pointer;
}

.documents-check-row input {
  flex: 0 0 auto;
  margin-top: 3px;
}

.documents-check-row--all {
  margin: 2px 0 4px;
}

.documents-check-row a {
  font-weight: 600;
}

.documents-consent-meta {
  margin-top: 10px;
  font-size: 0.78rem;
  line-height: 1.4;
  opacity: 0.68;
}

.documents-consent-details {
  display: inline;
  margin-left: 4px;
}

.documents-consent-details summary {
  display: inline;
  cursor: pointer;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.documents-consent-details div {
  margin-top: 10px;
}

.documents-consent-details p {
  margin: 0 0 7px;
}

.documents-submit {
  justify-self: start;
  margin-top: 5px;
}


/* MOJE DANE */

.media-consent-label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
}

.media-consent-label input {
  flex: 0 0 auto;
  margin-top: 4px;
}

.profile-consents-details {
  margin-top: 24px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
}

.profile-consents-details__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 20px;
  cursor: pointer;
  font-weight: 700;
}

.profile-consents-details__title {
  font-family: var(--font-display);
}

.profile-consents-details__status {
  font-size: 0.82rem;
  font-weight: 600;
  text-align: right;
  opacity: 0.7;
}

.profile-consents-details__content {
  padding: 3px 20px 20px;
}

.profile-consents-details__legal {
  margin: 14px 0 16px;
  font-size: 0.86rem;
  line-height: 1.45;
  opacity: 0.78;
}

@media (max-width: 640px) {

  .documents-group {
    padding: 17px 0;
  }

  .profile-consents-details__summary {
    align-items: flex-start;
    padding: 16px;
  }

  .profile-consents-details__content {
    padding: 2px 16px 16px;
  }

  .profile-consents-details__status {
    max-width: 135px;
  }
}


/* PROFILE SETTINGS SPLIT 2026-09-23 */

.profile-settings-section {
  padding-block: 0;
  margin-top: 22px;
}

.profile-settings-section > .form__legend {
  margin: 0 0 18px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--color-line);
}

.profile-account-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.profile-account-item {
  padding: 20px;
  border: var(--border-width) solid var(--color-line);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.profile-account-item__title {
  margin: 0 0 12px;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.3;
  font-weight: 700;
}

.profile-account-item__text {
  margin: 0 0 14px;
  font-size: 0.92rem;
  line-height: 1.45;
}

.profile-settings-section--privacy {
  margin-top: 28px;
}

.profile-settings-section--privacy .profile-consents-details {
  margin-top: 0;
}

@media (max-width: 760px) {
  .profile-account-grid {
    grid-template-columns: 1fr;
  }

  .profile-settings-section {
    margin-top: 20px;
  }

  .profile-settings-section--privacy {
    margin-top: 24px;
  }
}