/*
  AUXERIA — strony usług/filarów z osobnym URL-em (SSG).
  PRZEBUDOWANE (2026-09-28) wg zatwierdzonego, dokładnego redline —
  design-system/concepts/service-page-redline/variant-c.html — po tym
  jak pierwsza wersja tego pliku (własny sidebar, cała treść w jednej
  karcie) odjechała wizualnie od reszty strony. Zasady z redline:
  1. Lewa kolumna to DOSŁOWNA sekcja .hero-chat z site/index.html
     (topbar, karta czatu .msg-agent/.msg-item*, pasek pigułek+input) —
     ZERO nowego CSS dla niej tutaj, tylko ograniczenie szerokości jako
     flex-child (patrz .service-shell .hero-chat niżej).
  2. Prawa kolumna to nowy panel DOŁOŻONY OBOK (sibling), nie wewnątrz
     .hero-chat.
  3. W prawej kolumnie karta (.service-highlight-card, oparta na tych
     samych wartościach co .msg-agent) jest ZAREZERWOWANA dla
     wyróżnionych momentów (dowód/statystyka, przykład/scenariusz) —
     NIE opakowuje całej strony. Reszta treści leży bezpośrednio na tle
     strony, oddzielona cienkimi liniami.
*/

/* html/body są zablokowane globalnie (overflow:hidden, patrz
   docs/decisions.md — naprawa bugu z całą stroną przewijalną na
   Chrome-iOS) — .service-shell jest więc jedynym właścicielem scrolla
   na najwyższym poziomie tej strony, tak jak .hero-chat jest nim na
   stronie głównej. */
.service-shell {
  --shadow-ink: 16, 11, 0;
  --shadow-accent: 0, 111, 112;
  display: flex;
  align-items: stretch;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  /* Duże ekrany (2026-09-28, poprawka po żywym teście): bez tego dwie
     procentowe kolumny (34%/66%) rozjeżdżały się na szerokim monitorze —
     czat uciekał w lewo, treść w prawo, odstęp między nimi rósł bez
     końca. Ten sam duch co max-width:1180px na stronie głównej (patrz
     .hero-chat w styles.css), tylko szerzej, bo tu mieszczą się obie
     kolumny naraz. Powyżej tej szerokości: puste marginesy po bokach
     (tło strony), nie rozciąganie zawartości. */
  max-width: 1400px;
  margin: 0 auto;
}

/* Proporcje 1/3–2/3 (2026-09-28, poprawka po transition-prototype.html
   — poprzednie flex:0 0 480px w PX dawało różny % szerokości zależnie
   od viewportu, zgłoszone jako "1/4 zamiast 1/3"). Procentowe flex-basis
   zamiast stałego px, dokładnie jak w prototypie. transition na
   flex-basis/max-width/flex-grow: bez efektu w normalnym stanie (SSG
   renderuje już-split od razu), aktywne WYŁĄCZNIE podczas wejścia z
   czatu (.js-chat-entry niżej), kiedy service-transition.js odejmuje tę
   klasę i pozwala przejściu się odegrać. */
.service-shell .hero-chat {
  flex: 0 0 34%;
  max-width: none;
  /* Więcej oddechu niż na stronie głównej (2026-09-28, Runda 7 — Maciek:
     kolumna czatu przy max-width:1400px na powłoce czuje się ciasna).
     Na stronie głównej .hero-chat ma 0 24px, ale tam zajmuje pełną
     szerokość (do 1180px) — tutaj to tylko 34% z max. 1400px (~476px),
     więc te same 24px proporcjonalnie ściskają bardziej. Nadpisane tylko
     tutaj, homepage nietknięty. */
  padding: 0 32px;
  border-right: 1px solid rgba(16, 11, 0, 0.1);
  transition: flex-basis .48s cubic-bezier(.4, 0, .2, 1), flex-grow .48s cubic-bezier(.4, 0, .2, 1);
}

/* Runda 12: .service-content przestało SAMO przewijać — dokładnie ten
   sam podział odpowiedzialności co .hero-chat/.chat-transcript na
   stronie głównej. .service-content jest teraz zwykłym flex-column
   kontenerem z dwoma dziećmi: .service-sticky-header (zwykły,
   nieprzewijany flex-child — patrz niżej) i .service-content-scroll
   (JEDYNY właściciel scrolla, patrz dalej). Powód: sticky header
   wewnątrz przewijanego kontenera nie dawał się porządnie obciąć
   (clip-path) pod kątem prześwitującego cienia/tekstu (Rundy 10-11) —
   clip-path na .service-content ucinałby też sam nagłówek. Rozdzielenie
   na dwa elementy pozwala na PRAWDZIWY clip-path na samym scrollu,
   dokładnie jak na stronie głównej (.chat-transcript). */
.service-content {
  flex: 1 1 auto;
  min-width: 0;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--color-paper-secondary);
  position: relative;
  /* Poziomy padding WSPÓLNY dla obu dzieci (2026-09-28, Runda 14 — Maciek
     na iPhone złapał regresję z Rundy 12: header i scroll rozjechały się
     poziomo, bo padding wylądował tylko na .service-content-scroll, a
     .service-sticky-header — teraz sibling, nie dziecko — nie dziedziczył
     go już wcale, więc dotykał krawędzi ekranu). Ten sam wzorzec co
     .hero-chat na stronie głównej: padding na WSPÓLNYM rodzicu, .chat-topbar
     i .chat-transcript (analogicznie tutaj: header i scroll) go dziedziczą
     za darmo, zero duplikacji, zero rozjazdu. Pionowy padding zostaje
     osobno na każdym dziecku (górny na headerze, dolny na scrollu) — to
     dwie różne krawędzie, nie to samo co poziome wyrównanie. */
  padding: 0 48px;
  transition: opacity .3s ease .1s, flex-basis .48s cubic-bezier(.4, 0, .2, 1), flex-grow .48s cubic-bezier(.4, 0, .2, 1);
}

/* Nagłówek — eyebrow+H1 (2026-09-28, Runda 12: nie jest już position:sticky.
   Skoro scroll dzieje się NIŻEJ, w .service-content-scroll, ten element w
   ogóle nie jest częścią przewijanej treści — zostaje na miejscu z tego
   samego powodu co .chat-topbar na stronie głównej: nic go nie przewija,
   bo leży POZA przewijanym kontenerem, nie "przypięty" do niego trickiem
   CSS). flex:0 0 auto — naturalna wysokość, nigdy się nie kurczy. */
.service-sticky-header {
  flex: 0 0 auto;
  position: relative;
  background: var(--color-paper-secondary);
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 0 16px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

/* Miękkie zniknięcie treści pod nagłówkiem sticky podczas scrolla
   (2026-09-28 — ten sam duch co .chat-topbar::after w styles.css/
   .chat-bottom::before, na stronie głównej). Bez tego karty/listy
   znikały pod paskiem na twardo, na ostrej krawędzi. */
.service-sticky-header::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  /* Te same wspólne zmienne co .chat-topbar::after (Runda 23, :root w
     styles.css): pełne do --scroll-clip, wygaszanie przez --scroll-fade. */
  height: calc(var(--scroll-clip) + var(--scroll-fade));
  background: linear-gradient(to bottom, var(--color-paper-secondary) 0, var(--color-paper-secondary) var(--scroll-clip), transparent calc(var(--scroll-clip) + var(--scroll-fade)));
  pointer-events: none;
  /* z-index:-1 dla spójności z .chat-topbar::after (Runda 20) — tu
     `top:100%` (nie przesunięte jak na homepage, Runda 15 świadomie
     pominęła podstrony usług) więc ::after i tak nigdy nie zachodzi na
     .service-sticky-header-text/.service-sheet-close dzisiaj; to czysto
     zapobiegawcze, na wypadek gdyby ktoś kiedyś zastosował tu ten sam
     "zachodzenie na bar" trik co na homepage. */
  z-index: -1;
}
.service-sticky-header-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Własny stacking context NAD .service-sticky-header::after (2026-09-28,
     Runda 20 — ta sama, PRAWDZIWA przyczyna "loga uciętego" na
     homepage/topbarze, znaleziona przez CC-Design: generowana treść
     (::after) maluje się PO rzeczywistych dzieciach w kolejności
     dokumentu, a pierwsze 28px gradientu to pełna nieprzezroczystość w
     kolorze tła — identycznym co tło pod eyebrow/H1 — więc zasłonięcie
     kamuflowałoby się tak samo, tylko nikt jeszcze tego nie zgłosił tutaj.
     Naprawione zapobiegawczo, ten sam mechanizm co .chat-topbar-logo w
     styles.css. */
  position: relative;
  z-index: 1;
}

/* Jedyny właściciel scrolla w .service-content (Runda 12 — patrz komentarz
   przy .service-content powyżej). clip-path: inset(28px...) to PRAWDZIWE
   obcięcie (usuwa treść, łącznie z jej box-shadow, nie tylko ją wizualnie
   przykrywa) — dokładnie jak .chat-transcript na stronie głównej. Bez
   tego (sam gradient) cień zaokrąglonego rogu karty i zwykły tekst linii
   prześwitywały przy różnych wartościach przezroczystości (Rundy 10-11);
   clip-path usuwa problem u źródła, gradient nad nim zostaje czysto
   dekoracyjny. */
.service-content-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Strefa clip/fade i padding-top ze wspólnych zmiennych na :root
     (Runda 23, styles.css) — zamiast 28px clipu z 33px paddingiem pod
     nim, co dawało ~58px pustki między H1 a pierwszym akapitem.
     Poziomy padding dziedziczony z .service-content (Runda 14). */
  padding: var(--scroll-safe-top) 0 120px;
  clip-path: inset(var(--scroll-clip) 0 0 0);
}

/* Domyślny margin-top <p> (1em ≈ 15.5px) dokładał się do odstępu pod
   H1 niezamierzenie — .service-content-inner i tak ma gap:20px. */
.service-content-inner > .msg-agent-intro:first-child { margin-top: 0; }

/* Gdy bottom sheet jest otwarty na mobile, blokujemy scroll strony pod
   spodem — bez tego przewijanie wewnątrz sheeta "przecieka" do reszty
   strony po dojściu do granicy jego własnego scrolla. Przełączane w
   service-transition.js. */
body.sheet-open { overflow: hidden; }

/* ============ Wejście z czatu (?from=chat) ============
   Patrz homepage-chat.js ("Read full details", prawdziwy <a>, zero
   fetchowania) i site/js/service-transition.js. .js-chat-entry na
   <html> jest dodawana SYNCHRONICZNIE w <head>, przed pierwszym
   malowaniem (unikamy błysku już-rozdzielonego stanu przed animacją) —
   to WYŁĄCZNIE stan startowy animacji. Bez parametru ?from=chat (albo
   bez JS w ogóle) klasa nigdy się nie pojawia i strona renderuje się
   od razu w pełni "split", dokładnie jak dziś — zero zmiany zachowania
   dla bezpośrednich wejść/crawlerów. */
html.js-chat-entry .service-shell .hero-chat {
  flex: 1 1 auto;
  max-width: none;
}
html.js-chat-entry .service-content {
  flex: 0 0 0%;
  opacity: 0;
  overflow: hidden;
}

/* Nakładka "Building the page…" — DOKŁADNIE wzorzec kropek
   .msg-item-loading, który czat już ma (nie nowy spinner). Leży NA
   WIERZCHU już obecnej w DOM-ie (SSG) treści (pokrywa TYLKO
   .service-content-body — karty/listy, NIE eyebrow/H1/wstęp, które są
   poza nią) i znika po chwili, odsłaniając to, co już tam było — treść
   nigdy nie jest dociągana ani wstrzykiwana przez JS. Domyślnie UKRYTA
   (opacity:0). Od Rundy 8 odgrywana przy KAŻDYM wejściu na stronę (nie
   tylko ?from=chat) — patrz service-transition.js — czysto rytm/spójność
   z resztą strony. Widoczność sterowana WYŁĄCZNIE klasą .is-visible
   nadawaną przez JS, NIE selektorem html.js-chat-entry — czas pokazania
   kropek musi być niezależny od czasu trwania przejścia flex-basis
   (.48s, który przy zwykłym wejściu w ogóle się nie odgrywa). */
.service-loading-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: var(--color-paper-secondary);
  color: var(--color-accent);
  font-size: 13.5px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease;
  z-index: 5;
}
.service-loading-overlay .msg-item-loading-dots { display: flex; gap: 6px; }
.service-loading-overlay .msg-item-loading-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--color-accent); animation: ax-dot 1.1s infinite; }
.service-loading-overlay .msg-item-loading-dot:nth-child(2) { animation-delay: .18s; }
.service-loading-overlay .msg-item-loading-dot:nth-child(3) { animation-delay: .36s; }
.service-loading-overlay.is-visible { opacity: 1; pointer-events: auto; }

.service-sheet-close { display: none; }

.service-content-inner {
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Wrapper na "treść pod rytmem ładowania" (karty, listy — WSZYSTKO poza
   eyebrow/H1 w .service-sticky-header i wstępem w .service-content-inner,
   które są widoczne od razu, patrz Runda 8). .service-loading-overlay
   siedzi tutaj — position:relative daje jej (position:absolute;inset:0)
   właściwy zasięg, nie pokrywa nagłówka ani wstępu. */
.service-content-body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.service-eyebrow {
  display: block;
  font-size: 11.5px;
  font-weight: var(--weight-body-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent);
}

/* .msg-agent-title/.msg-agent-intro reużyte 1:1 (te same klasy co w
   karcie czatu) dla typograficznej spójności — .service-headline tylko
   dokłada większy rozmiar dla nagłówka h1, zgodnie z redline. */
.service-headline {
  font-size: 23px;
  margin-top: 6px;
}

/* Karta-wyróżnik — oparta na DOKŁADNIE tych samych wartościach co
   .msg-agent (kolor, radius), ale ze wzmocnionym cieniem (wartość z
   redline) — to jest "to jest ważne", nie generyczny kontener. */
.service-highlight-card {
  max-width: 720px;
  width: 100%;
  box-sizing: border-box;
  background: var(--color-paper);
  border-radius: 22px 22px 22px 6px;
  padding: 20px 24px;
  box-shadow: 0 32px 64px -28px rgba(var(--shadow-ink), 0.32), 0 8px 20px -10px rgba(var(--shadow-ink), 0.22);
  font-size: 15.5px;
  line-height: 1.6;
  opacity: 0.94;
}
.service-highlight-card strong { color: var(--color-ink); }

/* Druga, tealowa odmiana — przykład/scenariusz/cytat, nie
   dowód/statystyka (biała odmiana powyżej). Obie odmiany współistnieją
   na tej samej stronie. PŁASKA — bez box-shadow (2026-09-28, poprawka po
   żywym teście: Maciek, dwie karty obok siebie z tym samym mocnym
   cieniem wyglądały dziwnie; wzmocniony cień z redline miał dotyczyć
   tylko białej karty). Reset na `none`, bo .service-highlight-card
   (biała, wspólna baza) już ustawia box-shadow. */
.service-highlight-card--teal {
  background: rgba(0, 111, 112, 0.06);
  border: 1px solid rgba(0, 111, 112, 0.16);
  box-shadow: none;
}

/* Zwykła sekcja BEZ karty — nagłówek + treść na tle strony, oddzielone
   cienką linią. Karta jest zarezerwowana wyłącznie dla
   .service-highlight-card powyżej. */
.service-plain-section {
  border-top: 1px solid rgba(var(--shadow-ink), 0.1);
  padding-top: 20px;
}
.service-content-body > .service-plain-section:first-of-type,
.service-content-body > .service-highlight-card:first-child {
  border-top: none;
  padding-top: 0;
}

.service-plain-heading {
  font-family: var(--font-heading);
  font-weight: var(--weight-heading-bold);
  font-size: 16px;
  margin: 0 0 10px;
}

.service-plain-section p {
  font-size: 15.5px;
  line-height: 1.65;
  opacity: 0.86;
  margin: 0 0 12px;
}

/* Zwykłe wypunktowanie — domyślne kropki przeglądarki (nie własne
   kropki/karty), dokładnie jak w redline (.msg-item-text-detail z
   padding-left:18px, list-style zostawiony domyślny). */
.service-plain-list {
  max-width: none;
  margin: 0;
  padding-left: 18px;
  display: block;
  opacity: 0.86;
  font-size: 15.5px;
  line-height: 1.6;
}
.service-plain-list li { margin-bottom: 8px; }
.service-plain-list li:last-child { margin-bottom: 0; }
.service-plain-list strong { color: var(--color-ink); opacity: 1; }

/* "How it runs" — redline nie pokazuje tej sekcji explicite (urwana na
   "dalsze sekcje w tym samym rytmie"), więc kontynuacja tej samej
   zasady (zwykła lista, bez kart/odznak), zamiast wymyślać nową
   dekorację numerków, której nikt nie widział/zatwierdził. */
.service-plain-list--numbered { list-style: decimal; }

.service-timeline {
  display: block;
  font-size: 13.5px;
  color: var(--color-ink-muted);
  margin-top: 8px;
}

.service-flag {
  font-size: 10px;
  font-weight: var(--weight-body-medium);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  background: rgba(var(--shadow-accent), 0.12);
  border-radius: 999px;
  padding: 2px 8px;
}
.service-flag--muted {
  color: var(--color-ink-muted);
  background: rgba(var(--shadow-ink), 0.08);
}

.service-related { list-style: none; }
.service-related a { font-weight: var(--weight-body-medium); }
.service-related span { opacity: 0.72; }

.service-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
}
.service-cta-email { font-family: var(--font-heading); font-weight: var(--weight-heading-bold); font-size: 16px; color: var(--color-accent); text-decoration: none; }
/* accent (nie accent-light) — accent-light jako kolor tekstu na jasnym
   tle ma tylko 2.57:1 kontrastu, poniżej progu WCAG AA (2026-09-28,
   Runda 17 — CC-Design, audyt kontrastu). */
.service-cta-email:hover { color: var(--color-accent); }

/* Visualizations — patrz docs/specs/media-viewer-spec.md. Miniatura
   klikalna, otwiera PhotoSwipe (site/js/media-viewer.js): lightbox z
   przyciemnionym, nie w pełni nieprzezroczystym tłem, pinch-zoom/pan/
   swipe na dotyku, kółko/drag na desktopie. Grafika na razie to
   on-brandowy placeholder (assets/visual-placeholder.svg) — realne
   diagramy dojdą później (CC-Design), sam mechanizm już finalny.
   NIETKNIĘTE przy przebudowie redline — zatwierdzone osobno wcześniej. */
.service-visualizations {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.service-visual-card {
  border: 1px solid rgba(var(--shadow-ink), 0.14);
  border-radius: 16px;
  overflow: hidden;
  background: var(--color-paper);
}
.service-visual-thumb {
  display: block;
  position: relative;
  cursor: zoom-in;
  line-height: 0;
}
.service-visual-thumb img {
  display: block;
  width: 100%;
  height: auto;
}
.service-visual-thumb::after {
  content: '';
  position: absolute;
  right: 14px;
  bottom: 14px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background-color: rgba(16, 11, 0, 0.55);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FCFAFA' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3Cline x1='11' y1='8' x2='11' y2='14'/%3E%3Cline x1='8' y1='11' x2='14' y2='11'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 18px;
  opacity: 0;
  transition: opacity .15s ease;
}
.service-visual-thumb:hover::after,
.service-visual-thumb:focus-visible::after { opacity: 1; }
.service-visual-card-text { padding: 16px 20px; }
.service-visual-card-title {
  font-family: var(--font-heading);
  font-weight: var(--weight-heading-bold);
  font-size: 14.5px;
  margin-bottom: 6px;
}
.service-visual-card-caption {
  font-size: 13.5px;
  opacity: 0.7;
  font-style: italic;
}

/* Podpis WEWNĄTRZ otwartego viewera (PhotoSwipe) — osobny od
   .service-visual-card-caption powyżej. Styl dokładnie ze spec:
   uppercase, letter-spacing, kolor z rodziny accent. accent-light
   (jaśniejszy teal) zamiast accent — lepsza czytelność na ciemnym,
   przyciemnionym tle viewera niż ciemniejszy stormy teal. */
.pswp-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 20px;
  text-align: center;
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: var(--weight-body-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent-light);
  pointer-events: none;
  z-index: 100000;
}

/* Zgłoszony bug: pasek strony pod spodem (np. logo AUXERIA, wysoki
   kontrast czarny na jasnym) zostawał na tyle czytelny przez
   bgOpacity:0.65, że wizualnie nakładał się na przyciski PhotoSwipe w
   .pswp__top-bar. Zweryfikowane: to NIE jest błąd pokrycia/z-index —
   .pswp__bg faktycznie przykrywa cały viewport (potwierdzone testem
   z pełną nieprzezroczystością), po prostu wysokokontrastowe elementy
   strony pod spodem przebijają się przez jednolite 65% przyciemnienie
   bardziej niż np. niskokontrastowa pigułka na dole. Naprawa celowana
   tylko w pasek przycisków (nie zmienia bgOpacity całego viewera, więc
   nie cofa już zaakceptowanego efektu "tło rozpoznawalne"): dodatkowy
   gradient-scrim wyłącznie za .pswp__top-bar, najciemniejszy na samej
   górze, zanikający do przezroczystości na dole paska. */
.pswp__top-bar {
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 100%);
}

/* Mobile: bottom sheet zamiast stacka (2026-09-28, wg
   transition-prototype.html, breakpoint 860px z tego samego pliku).
   Czat wypełnia cały ekran pod spodem, zawsze widoczny/dostępny — sheet
   z treścią usługi wjeżdża znad dołu i przykrywa jego większość, ale
   nie cały ekran. Domyślnie (bezpośrednie wejście, bez ?from=chat)
   sheet jest już otwarty (translateY(0)) — ten sam "od razu w pełni
   split" co na desktopie, tylko innym mechanizmem wizualnym (transform
   zamiast szerokości kolumn, bo na wąskim ekranie nie ma miejsca na
   dwie kolumny obok siebie). .js-chat-entry (wejście z czatu) startuje
   zamknięty i animuje się w górę, dokładnie jak w prototypie. */
@media (max-width: 860px) {
  .service-shell {
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
  }
  .service-shell .hero-chat {
    flex: 1 1 auto;
    max-width: none;
    width: 100%;
    height: 100%;
    border-right: none;
    transition: none;
    /* Reset z 32px (Runda 7 — potrzebne tylko na desktopie, gdzie
       .hero-chat to wąska 34% kolumna). Na mobile hero-chat jest pełnej
       szerokości, dokładnie jak na stronie głównej, więc dostaje tę samą
       wartość 20px co ona (2026-09-28, Runda 12 — ujednolicenie
       marginesu krawędź-ekranu→krawędź-karty ze stroną główną i z
       .service-content poniżej). */
    padding: 0 20px;
  }
  /* Topbar NAD sheetem (z-index 50) — część wariantu "sheet pod
     topbarem" wyżej; dropdown Menu jest w kontekście topbara, więc też
     ląduje nad sheetem. */
  .service-shell .chat-topbar { z-index: 60; }
  .service-content {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* WARIANT DO OCENY MAĆKA (2026-09-29): sheet zaczyna się dokładnie
       na dolnej krawędzi topbara (--topbar-h w styles.css), więc logo,
       telefon i Menu zostają w całości widoczne i klikalne nad nim.
       Poprzednio (Runda 16): brak `top`, a zamiast niego
         height: 96vh;
         height: 96dvh;
       — cofnięcie = usunąć `top` poniżej i przywrócić te dwie linie
       (oraz usunąć z-index topbara niżej). height:auto nadpisuje
       desktopowe 100dvh z bazowej reguły — wysokość wynika z top+bottom. */
    top: var(--topbar-h);
    height: auto;
    background: var(--color-paper-secondary);
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -20px 50px -20px rgba(16, 11, 0, 0.35);
    transform: translateY(0%);
    transition: transform .38s cubic-bezier(.4, 0, .2, 1);
    opacity: 1;
    flex: none;
    z-index: 50;
    /* Runda 12: .service-content sam już nie scrolluje (patrz komentarz
       przy bazowej regule) — overflow:hidden, żeby zaokrąglone rogi
       (border-radius powyżej) faktycznie przycinały .service-content-scroll
       pod spodem, zamiast pozwalać mu wystawać poza nie. */
    overflow: hidden;
    /* 48px→20px na mobile (Runda 14 — ten sam poziomy padding co
       .service-content-scroll poniżej, żeby header i scroll się zrównały;
       patrz komentarz przy bazowej regule .service-content). */
    padding: 0 20px;
  }
  /* Jedyny właściciel scrolla na mobile — patrz baza .service-content-scroll.
     -webkit-overflow-scrolling przeniesiony tutaj z .service-content
     (Runda 12). Poziomy padding USUNIĘTY stąd w Rundzie 14 — dziedziczy się
     teraz z .service-content (patrz komentarz przy bazowej regule), zostaje
     tylko dolny, właściwy tylko dla scrolla. -webkit-overflow-scrolling:
     2026-09-28, Runda 12 — Maciek na prawdziwym iPhone (Safari): sticky
     header znikał całkowicie przy przewijaniu palcem, mimo że
     position:sticky działał poprawnie przy programowym scrollTop i w
     emulacji mobile na Chromium — znany problem realnego iOS Safari
     (position:sticky + overflow-y:auto bez tej własności potrafi się łamać
     przy prawdziwym dotykowym momentum-scrollu). Ten sam property już użyty
     gdzie indziej w projekcie (#chatPillsBar). Runda 12 usuwa właściwy
     powód problemu (sticky header w ogóle znika z przewijanego kontenera),
     ale zostawiam tę własność jako dodatkowe zabezpieczenie. */
  .service-content-scroll {
    padding: var(--scroll-safe-top) 0 40px;
    -webkit-overflow-scrolling: touch;
  }
  html.js-chat-entry .service-content {
    transform: translateY(100%);
    opacity: 1;
  }
  /* Nagłówek sticky, wersja mobilna: samo tło+odstęp, węższy niż na
     desktopie (2026-09-28, Runda 8 — "breadcrumb + ×", mniejsza czcionka
     H1 niż reszta treści, żeby nie zajmował za dużo trwale przypiętej
     wysokości na małym ekranie). */
  .service-sticky-header {
    padding: 14px 0 10px;
  }
  .service-sticky-header .service-headline {
    font-size: 15px;
    margin-top: 2px;
  }
  /* Biały krążek (2026-09-28, poprawka po teście Maćka: tekstowy link
     "Close" zamieniony na przycisk) — sheet sam jest w kolorze tła
     (paper-secondary), więc × musi się od niego odróżnić, nie zlewać.
     Ten sam język co przycisk zamknięcia w lightboxie PhotoSwipe, tylko
     odwrócony kolorystycznie pod jasne tło zamiast ciemnego scrimu.
     Zwykły flex-child w .service-sticky-header teraz (nie
     position:absolute) — Runda 8, odkąd nagłówek jest sticky. */
  .service-sheet-close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--color-paper);
    color: var(--color-ink);
    border: none;
    box-shadow: 0 10px 24px -10px rgba(16, 11, 0, 0.4);
    cursor: pointer;
    padding: 0;
    /* Własny stacking context NAD .service-sticky-header::after (Runda 20)
       — ten sam powód co .service-sticky-header-text powyżej. */
    position: relative;
    z-index: 1;
  }
}
