/* ============================================================================
   Zosia i Piotrek - 28.08.2026
   theme.css: tokeny strony + wspolne slownictwo klas dla budowniczych sekcji.

   Ladowany PO engine/scrollcraft.css, wiec nadpisuje jego tokeny.

   WLASNOSC: ten plik nalezy do architekta buildu. Budowniczowie sekcji go NIE
   edytuja. Wlasne style pisza inline w swoim fragmencie, scopowane przez id
   sekcji (patrz DESIGN-SPEC.md).

   Wartosci kolorow ponizej to stan "wczesne popoludnie". assets/sky.js nadpisuje
   je w locie na :root wraz z pozycja scrolla. Bez JS strona zostaje w tym
   stanie i jest w pelni czytelna.
   ========================================================================== */

:root {
  /* --- role kolorow (sky.js przepisuje --sc-ink, --sc-ink-soft, --sc-surface,
         --sc-accent, --sc-accent-ink, --w-veil, --w-veil-soft) -------------- */
  --sc-canvas:      #f3e6c9;
  --sc-surface:     rgba(255, 247, 235, 0.72);
  --sc-ink:         #3b2417;
  --sc-ink-soft:    #6e4e3a;
  --sc-accent:      #b2521e;
  --sc-accent-ink:  #fff7ec;

  /* welon pod tekstem. NIE karta, tylko zageszczenie tla tam gdzie stoi tekst */
  --w-veil:      rgba(255, 247, 235, 0.74);
  --w-veil-soft: rgba(255, 247, 235, 0.34);
  /* Papier karty i kolor pasa swiatla. Obie wartosci sky.js nadpisuje co klatke,
     ale MUSZA byc tu zadeklarowane: bez JS color-mix() z niezdefiniowana
     zmienna uniewaznia cale tlo welonu, wiec strona bez skryptu zostawala
     z kopia wprost na zdjeciu. Wartosci startowe to stan "wczesne popoludnie". */
  --w-paper:     rgba(255, 247, 235, 0.93);
  --w-haze:      #fdf4e2;

  /* Wlos musi przezyc przewrot inkaustu. Na nocnym gruncie inkaust jest kosciany,
     a 16% kosci nad granatem to linia, ktorej po prostu nie widac: karta menu
     traci podzial na grupy, a lista informacji zaczyna czytac sie jak jeden blok.
     22% trzyma sie jeszcze wlosa na dziennym gruncie i wraca do widocznosci w nocy. */
  --sc-hairline:        color-mix(in oklab, var(--sc-ink) 22%, transparent);
  --sc-hairline-strong: color-mix(in oklab, var(--sc-ink) 34%, transparent);

  /* --- kroje. Dwa i tylko dwa. ----------------------------------------- */
  --sc-font-display: "Cormorant Garamond", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sc-font-text:    "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Garalda w duzym stopniu NIE chce ujemnego trackingu grotesku. */
  --sc-track-tight:  -0.012em;
  --sc-track-snug:   -0.006em;
  --sc-track-normal:  0.002em;
  --sc-track-wide:    0.18em;

  --sc-leading-none:  0.98;
  --sc-leading-tight: 1.12;
  --sc-leading-body:  1.66;

  --sc-measure: 58ch;

  /* skala plakatowa - tylko hero (akt 1) */
  --w-t-poster: clamp(3.4rem, 15vw, 12.5rem);
  /* godziny w harmonogramie */
  --w-t-hour:   clamp(1.35rem, 0.9rem + 1.6vw, 2.4rem);

  /* --- papeteria: promien prawie zerowy, cienie miekkie i cieple ---------- */
  --sc-r-sm: 2px;  --sc-r-md: 3px;  --sc-r-lg: 4px;  --sc-r-pill: 999px;
  --sc-shadow-color: 24 38% 14%;
  --sc-e1: 0 1px 2px hsl(var(--sc-shadow-color) / 0.10),
           0 2px 8px -2px hsl(var(--sc-shadow-color) / 0.12);
  --sc-e2: 0 2px 5px hsl(var(--sc-shadow-color) / 0.10),
           0 10px 26px -8px hsl(var(--sc-shadow-color) / 0.18);
  --sc-e3: 0 4px 10px hsl(var(--sc-shadow-color) / 0.10),
           0 22px 52px -14px hsl(var(--sc-shadow-color) / 0.22);
  --sc-edge: inset 0 1px 0 rgba(255, 252, 246, 0.55);

  --sc-maxw: 78rem;

  /* --- API nieba: wartosci startowe. sky.js je nadpisuje. ---------------- */
  --sky-t:      0;        /* 0..1 postep calej strony (wygladzony)          */
  --sky-hour:   13.15;    /* 13.0 .. 26.0 godzina dnia wesela               */
  --sky-alt:    1;        /* wysokosc slonca: 1 gora, 0 horyzont, <0 pod    */
  --sky-glow:   0;        /* 0..1 luna zachodu, szczyt ok. 19:50            */
  --sky-night:  0;        /* 0..1 noc (gwiazdy)                             */
  --sky-flip:   0;        /* 0..1 przejscie inkaustu dzien -> noc           */
  --sky-px:     0;        /* -1..1 wskaznik myszy, 0 bez fine pointer       */
  --sky-py:     0;

  --sky-sun-x:  34vw;
  --sky-sun-y:  16vh;

  --sky-top:    #79a6ce;
  --sky-mid:    #bfcfd6;
  --sky-hor:    #f3e6c9;
  --sky-water:  #63859a;
  --sky-deep:   #3f5f74;
  --sky-shape:  #4a3a2a;   /* sylwetki trzcin i brzegu */

  --w-horizon: 62%;        /* linia horyzontu w wysokosci okna */
  --w-rail: 3.25rem;       /* rezerwa prawego marginesu pod chrome */
  --w-chrome: 0rem;        /* pionowa rezerwa na pas chrome (tylko telefon) */
}

/* ---------------------------------------------------------------- baza -- */

html {
  background: #eadfc5;
  /* Kotwice menu maja dojechac, nie przeskoczyc. Skrypt chrome i tak podaje
     behavior jawnie; to jest zachowanie dla nawigacji bez JS. */
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Cale tlo strony robi warstwa nieba. Body musi byc przezroczyste. */
body {
  background: transparent;
  font-weight: 400;
  overscroll-behavior-y: none;
}

/* --- strona bez JS ------------------------------------------------------
   engine/scrollcraft.css parkuje [data-sc-cue], [data-sc-in] i dzieci
   [data-sc-stagger] na opacity 0 i liczy na to, ze silnik dopisze krycie
   inline. Gdy JS nie wystartuje (blad, wolne lacze, wylaczony JS), cala tresc
   strony zostaje niewidoczna: zaproszenie bez ani jednego slowa.

   Silnik dodaje .sc-ready na <html> synchronicznie w mount(), zanim przegladarka
   zdazy cokolwiek namalowac, a jego krycie i tak idzie stylem inline (wyzszy
   priorytet), wiec ta regula nie miga i niczego mu nie odbiera. Jest wylacznie
   siatka bezpieczenstwa. Kolory tokenow z :root to stan "wczesne popoludnie",
   wiec strona bez JS jest w pelni czytelna. */
html:not(.sc-ready) :is([data-sc-cue], [data-sc-in], [data-sc-stagger] > *, .sc-split__i) {
  opacity: 1;
  transform: none;
}
html:not(.sc-ready) [data-sc-reveal] { clip-path: none; }

/* Cormorant ma niska wysokosc x. Prosa idzie Manropem, wiec dotyczy to tylko
   display, ale gdyby ktos wstawil serif w akapit, ma go podniesc. */
.sc-display,
.w-h1, .w-h2, .w-h3, .w-hour, .w-fig {
  font-family: var(--sc-font-display);
  font-weight: 400;
  line-height: var(--sc-leading-tight);
  letter-spacing: var(--sc-track-snug);
  text-wrap: balance;
  margin: 0;
}

.w-h1 {
  font-size: var(--w-t-poster);
  font-weight: 300;
  line-height: 0.92;
  letter-spacing: -0.004em;
}
.w-h2 { font-size: var(--sc-t-2xl); font-weight: 300; }
.w-h3 {
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-lg);
  font-weight: 600;
  letter-spacing: var(--sc-track-normal);
  line-height: 1.24;
  margin: 0;
}

.w-lede {
  font-family: var(--sc-font-display);
  font-size: var(--sc-t-xl);
  font-weight: 300;
  font-style: italic;
  line-height: 1.3;
  color: var(--sc-ink);
  max-width: 30ch;
  margin: 0;
  text-wrap: balance;
}

.w-body {
  font-size: var(--sc-t-base);
  color: var(--sc-ink-soft);
  max-width: var(--sc-measure);
  text-wrap: pretty;
  margin: 0;
}

/* Etykiety TYLKO dla realnych danych (godzina, wariant menu, podpis telefonu).
   Nigdy jako brew nad naglowkiem. */
.w-label {
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-xs);
  font-weight: 600;
  letter-spacing: var(--sc-track-wide);
  text-transform: uppercase;
  color: var(--sc-ink-soft);
  margin: 0;
}

.w-hour {
  font-size: var(--w-t-hour);
  font-weight: 400;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: 0.01em;
  color: var(--sc-ink);
  white-space: nowrap;
}

/* --------------------------------------------------- wpis planu dnia ---- */
/* JEDEN BYT OD 14:00 DO 02:00.
   Wpis planu wyglada tak samo w akcie 3 (popoludnie), 4 (zachod) i 5 (wieczor):
   ta sama struktura DOM, te same role, ta sama skala, ten sam rytm, to samo
   traktowanie welonu. Zmienia sie wylacznie swiat za nim i inkaust, ktory ta
   godzina wymusza, oraz sposob wejscia - bo urzadzenie nalezy do aktu, nie do
   wpisu (reveal w akcie 3, cue w 4 i 5).
   Dlatego te style siedza TUTAJ, w jednym miejscu, a nie w trzech scopowanych
   wariantach w sekcjach; wczesniej kazdy akt mial wlasny uklad wiersza, wlasny
   kroj tytulu i wlasne odstepy, wiec ten sam punkt planu czytal sie jak trzy
   rozne rzeczy. */
:root { --w-item-air: clamp(2.25rem, 7.5vh, 6rem); }

.w-list { list-style: none; margin: 0; padding: 0; display: grid; }

.w-item {
  position: relative;
  list-style: none;
  width: fit-content;
  max-width: 100%;
  padding-block: clamp(0.35rem, 1.4vh, 1.1rem);
}
.w-item + .w-item { margin-block-start: var(--w-item-air); }
/* Cisza autorska (uroczysty obiad): jedyne dopuszczalne zroznicowanie wpisu to
   POWIETRZE wokol niego. Kroj, stopien i uklad zostaja te same. */
.w-item + .w-item--cisza,
.w-item--cisza + .w-item { margin-block-start: calc(var(--w-item-air) * 1.6); }

.w-item__in { display: grid; gap: var(--sc-2); }
@media (min-width: 720px) {
  .w-item__in {
    grid-template-columns: max-content fit-content(24rem);
    gap: clamp(1.1rem, 2.8vw, 2.5rem);
    align-items: baseline;
  }
}
.w-item__tresc { display: grid; gap: var(--sc-3); }

/* Tytul wpisu idzie glosem strony (display), nie glosem dokumentu. Na zdjeciu
   czyta sie lepiej, a przy okazji odroznia wpis planu od naglowka bloku
   informacyjnego, ktory zostaje przy .w-h3. */
.w-item__co {
  font-family: var(--sc-font-display);
  font-size: var(--sc-t-xl);
  font-weight: 300;
  line-height: var(--sc-leading-tight);
  letter-spacing: var(--sc-track-snug);
  color: var(--sc-ink);
  max-width: 22ch;
  text-wrap: balance;
  margin: 0;
}
/* Linia szczegolu bierze PELNY inkaust, nie przygaszony. Hierarchie niesie tu
   stopien i kroj, a przygaszony inkaust nie utrzymuje 4.5:1 nad nocnym gruntem
   przy zadnym rozsadnym welonie (zmierzone: 3.6:1 w akcie 5). */
.w-item__opis {
  font-size: var(--sc-t-base);
  color: var(--sc-ink);
  max-width: 44ch;
  text-wrap: pretty;
  margin: 0;
}

/* Lustro dla aktu 4. Kotwica trail jest wiazaca (DESIGN-SPEC rule 11), wiec
   zamiast lamac ja, odbijamy caly wiersz: ta sama siatka, te same proporcje,
   ta sama skala, tylko godzina po drugiej stronie. Ponizej 720 px lustro
   znika razem z siatka dwukolumnowa. */
.w-list--mirror { justify-items: end; }
.w-list--mirror .w-item__in { justify-items: end; text-align: right; }
@media (min-width: 720px) {
  .w-list--mirror .w-item__in { grid-template-columns: fit-content(24rem) max-content; }
  .w-list--mirror .w-item__hour { grid-column: 2; grid-row: 1; }
  .w-list--mirror .w-item__tresc { grid-column: 1; grid-row: 1; }
}
@media (max-width: 719px) {
  .w-list--mirror { justify-items: start; }
  .w-list--mirror .w-item__in { justify-items: start; text-align: left; }
}

.w-fig { font-variant-numeric: tabular-nums lining-nums; }

/* Link w prosie i link zamkniecia: podkreslenie, nigdy wyspa przycisku. */
.w-link {
  color: var(--sc-ink);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--sc-accent) 60%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.28em;
  transition: text-decoration-color var(--sc-d-fast) var(--sc-ease-out),
              color var(--sc-d-fast) var(--sc-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .w-link:hover { color: var(--sc-accent); text-decoration-color: var(--sc-accent); }
}
.w-link:active { transform: translateY(1px); }

/* ------------------------------------------------------------- uklad ---- */

.w-wrap {
  width: 100%;
  max-width: var(--sc-maxw);
  margin-inline: auto;
  padding-inline: var(--sc-gutter);
  padding-right: max(var(--sc-gutter), var(--w-rail));
}

.w-act { padding-block: var(--sc-section); position: relative; }
/* Sekcja flow zaraz po akcie pinowanym: scena i tak zjezdza cale okno. */
.w-act--tight { padding-block-start: var(--sc-6); }

/* Wnetrze pinowanej sceny. Ten sam element nosi .sc-stage z engine (sticky).
   UWAGA: theme.css laduje sie PO engine/scrollcraft.css, a obie klasy maja te
   sama wage, wiec cokolwiek tu napiszemy w `height` przebija
   `.sc-stage { height: 100svh }`. Wczesniejsze `height: 100%` rozciagalo scene
   do pelnej wysokosci aktu (np. 320vh w #zachod) i pin przestawal trzymac
   kadr. Powtarzamy wiec wysokosc okna 1:1 zamiast ja nadpisywac. */
.w-stage {
  display: grid;
  height: 100vh;
  height: 100svh;
  align-content: center;
  padding-block: var(--sc-8);
  padding-inline: var(--sc-gutter);
  padding-right: max(var(--sc-gutter), var(--w-rail));
}
.w-stage--center { justify-items: center; text-align: center; }
.w-stage--lead   { justify-items: start; }
.w-stage--trail  { justify-items: end; text-align: right; }

/* Kotwice tekstu w sekcjach flow */
.w-col        { display: grid; gap: var(--sc-5); }
.w-col--lead  { justify-items: start; max-width: 46rem; }
.w-col--trail { justify-items: end; text-align: right; margin-left: auto; max-width: 46rem; }
.w-col--center{ justify-items: center; text-align: center; margin-inline: auto; max-width: 44rem; }

.w-split {
  display: grid;
  gap: clamp(1.5rem, 4vw, 4rem);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 860px) {
  .w-split { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); align-items: start; }
}

/* .w-rule to element rysunkowy (horyzont, kreska podpisu, linia w szczycie),
   a nie krawedz kontenera, wiec bierze mocniejszy wlos. Przy slabszym gubil sie
   na nocnym gruncie i sekcje podbijaly go u siebie na wlasna reke. */
.w-rule {
  height: 1px; border: 0; margin: 0;
  background: var(--sc-hairline-strong);
  transform-origin: left center;
}

/* --------------------------------------------------------------- welon -- */
/* Welon nie moze byc KSZTALTEM. To jest twarde wymaganie tej strony i jedyny
   powod, dla ktorego wyglada tak, jak wyglada.

   Prostokat z wtopionymi bokami zostaje prostokatem nawet przy wtopieniu na
   200 px. Nad gradientem uchodzilo mu to na sucho, bo gradient nie mial ani
   jednej prostej, do ktorej oko moglo przylozyc krawedz welonu. Zdjecie ma ich
   trzy: linie horyzontu, pas trzcin i kolumne odbicia. Kazda z nich wchodzi
   pod welon i wychodzi spod niego z inna jasnoscia, wiec granica ujawnia sie
   natychmiast, a caly blok czyta sie jak naklejka polozona na fotografii.

   Wiec welon jest tu FILTREM POLOWKOWYM, dokladnie takim, jaki fotograf
   krajobrazu wkreca przed obiektyw:

     - w poziomie pelny bleed (-100vw na oba boki), czyli zadnej krawedzi
       bocznej i zadnego naroznika. Obcina go samo okno: body ma overflow-x:
       clip, a scena aktu pinowanego overflow: clip;
     - w pionie jedno dlugie, gladkie zejscie do zera po obu stronach bloku
       kopii, o dlugosci rzedu wysokosci tego bloku;
     - kolor z --w-haze, ktory sky.js wyprowadza z barw nieba biezacej godziny
       (dzien: horyzont podniesiony ku swiatlu, noc: glebia nieba sciagnieta
       w dol). Ani bieli, ani czerni na stronie nie ma;
     - krycie przez opacity, wiec sekcja stroi jedna liczba.

   Wynik nie ma zadnej krawedzi ani naroznika i czyta sie jak pas mgly nad
   woda albo jak zdjecie naswietlone o pol przyslony inaczej. Rownanie
   zlozenia jest przy tym to samo, co przy multiply (kolor nocny) i przy screen
   (kolor dzienny), bo --w-haze stoi blisko konca skali - z ta roznica, ze
   dziala w kazdym kontekscie ukladania, czego mix-blend-mode wewnatrz
   position: sticky nie gwarantuje.

   Welon jest RODZENSTWEM kopii, nigdy jej ::before: harness kontrastu chowa
   [data-sc-cue] wraz z pseudoelementami, wiec scrim schowany w srodku cue
   nie jest w ogole mierzony. Rodzic musi miec position: relative.

   Niezmiennik: wysokosc elementu = wysokosc bloku + 2 * --veil-y, wiec
   przystanek --veil-y NIGDY nie wyprzedza calc(100% - --veil-y) i gradient nie
   degeneruje sie w twarda krawedz. Dlatego nikt nie nadpisuje tu inset. */
.w-veil {
  --veil-y: clamp(3rem, 17vh, 12rem);
  position: absolute;
  inset-block: calc(-1 * var(--veil-y));
  inset-inline: -100vw;
  z-index: 0;
  pointer-events: none;
  opacity: 0.5;
  background: linear-gradient(to bottom,
              transparent 0,
              color-mix(in srgb, var(--w-haze) 2%, transparent)  calc(var(--veil-y) * 0.16),
              color-mix(in srgb, var(--w-haze) 6%, transparent)  calc(var(--veil-y) * 0.30),
              color-mix(in srgb, var(--w-haze) 13%, transparent) calc(var(--veil-y) * 0.44),
              color-mix(in srgb, var(--w-haze) 26%, transparent) calc(var(--veil-y) * 0.57),
              color-mix(in srgb, var(--w-haze) 43%, transparent) calc(var(--veil-y) * 0.69),
              color-mix(in srgb, var(--w-haze) 63%, transparent) calc(var(--veil-y) * 0.80),
              color-mix(in srgb, var(--w-haze) 83%, transparent) calc(var(--veil-y) * 0.90),
              var(--w-haze) var(--veil-y),
              var(--w-haze) calc(100% - var(--veil-y)),
              color-mix(in srgb, var(--w-haze) 83%, transparent) calc(100% - var(--veil-y) * 0.90),
              color-mix(in srgb, var(--w-haze) 63%, transparent) calc(100% - var(--veil-y) * 0.80),
              color-mix(in srgb, var(--w-haze) 43%, transparent) calc(100% - var(--veil-y) * 0.69),
              color-mix(in srgb, var(--w-haze) 26%, transparent) calc(100% - var(--veil-y) * 0.57),
              color-mix(in srgb, var(--w-haze) 13%, transparent) calc(100% - var(--veil-y) * 0.44),
              color-mix(in srgb, var(--w-haze) 6%, transparent)  calc(100% - var(--veil-y) * 0.30),
              color-mix(in srgb, var(--w-haze) 2%, transparent)  calc(100% - var(--veil-y) * 0.16),
              transparent 100%);
}
/* Dwa warianty dlugosci zejscia. Sam ksztalt jest zawsze ten sam. */
.w-veil--wide { --veil-y: clamp(4rem, 24vh, 17rem); }
.w-veil--tight { --veil-y: clamp(2rem, 11vh, 7.5rem); }

/* Welon wpisu planu dnia. Jest RODZENSTWEM elementu z cue/reveal, nigdy jego
   dzieckiem: [data-sc-reveal] dostaje clip-path do wlasnego border boxa, wiec
   welon schowany w srodku zostalby przyciety do prostokata wpisu i z
   bezksztaltnego pasa zrobilaby sie plyta o ostrej krawedzi. Harness kontrastu
   ma ten sam powod: chowa [data-sc-cue] wraz z zawartoscia, wiec welon w srodku
   cue nie jest w ogole mierzony.
   Krycie idzie z postepu aktu i z wlasnego progu wpisu, wiec pas przychodzi
   RAZEM ze swoim wpisem, a nie przed calym aktem. To jedyny sposob, zeby szczyt
   aktu zachodu zaczynal sie na czystym, niczym nie przykrytym niebie.
   Regula MUSI stac po .w-veil: obie maja te sama wage, wiec rozstrzyga
   kolejnosc. Postawiona wyzej przegrywala z .w-veil { opacity } i kazde
   podbicie gestosci w sekcji bylo bez zadnego efektu - dokladnie ten objaw,
   przed ktorym ostrzega verify.md. */
.w-item__veil {
  opacity: clamp(0, calc((var(--sc-p, 1) - var(--w-item-at, 0)) * 9), var(--w-item-veil, 0.5));
}
@media (prefers-reduced-motion: reduce) {
  /* Przy ograniczonym ruchu silnik zdejmuje clip-path z reveala, wiec wpis jest
     na ekranie od pierwszej klatki aktu. Pas swiatla musi wtedy byc od razu,
     inaczej tekst stoi przez chwile na golym zdjeciu (zmierzone: 2.72:1 na
     godzinie wpisu obiadowego). Wpisy prowadzone przez cue zostaja na rampie,
     bo tam tekst nadal wchodzi kryciem. */
  .w-item:has(> [data-sc-reveal]) .w-item__veil { opacity: var(--w-item-veil, 0.5); }
}
.w-above { position: relative; z-index: 1; }

/* Papier. Dozwolony DOKLADNIE dwa razy na calej stronie (karta menu,
   karta potwierdzenia). Wszedzie indziej: .w-veil. */
.w-panel {
  position: relative;
  background: var(--w-paper, var(--w-veil));
  border: 1px solid var(--sc-hairline);
  border-radius: var(--sc-r-md);
  box-shadow: var(--sc-e2), var(--sc-edge);
  padding: clamp(1.5rem, 3.4vw, 3.25rem) clamp(1.25rem, 3.6vw, 3.5rem);
}

/* ------------------------------------------------------------ niebo ----- */

/* Grunt swiata jest fotograficzny (assets/photo/, patrz PHOTO-WORLD.md).
   Gradient ponizej nie jest juz niebem, tylko podkladem na czas ladowania
   pierwszej planszy i siatka bezpieczenstwa, gdyby JPEG nie doszedl. Kolory
   nadal ida ze sky.js, wiec podklad ma zawsze barwe biezacej godziny. */
.sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      var(--sky-top) 0%,
      var(--sky-mid) 40%,
      var(--sky-hor) var(--w-horizon),
      var(--sky-hor) 100%);
}

/* Parallaksa jest KOMPOZYCYJNA: jedna warstwa gruntu przesuwana w calosci,
   bez wycinanego pierwszego planu. Trzciny siedza przy dolnej krawedzi kazdej
   planszy, wiec przesuw calego kadru czyta sie jako glebia, a nie jako blad.
   Amplituda 2.4vh na cala dlugosc strony: wiecej i horyzont zaczyna wedrowac,
   co przy nieruchomej kamerze wyglada na pomylke. Zapas na przesuw daje
   scale(1.07), czyli 3.5vh nadmiaru z kazdej strony. Tylko transform. */
.sky__photo {
  position: absolute;
  inset: 0;
  transform:
    translate3d(
      calc(var(--sky-px) * -0.4vw),
      calc(var(--sky-t) * -2.4vh + var(--sky-py) * -0.3vh),
      0)
    scale(1.07);
  will-change: transform;
}

/* Plansze. Krycie pisze photo-world.js; tu tylko stan spoczynkowy. */
.sky__plate {
  position: absolute;
  inset: 0;
  opacity: 0;
}
.sky__plate img {
  display: block;
  width: 100%;
  height: 100%;
  /* Horyzont siedzi na ok. 60 procentach kadru, wiec przy bardzo szerokim
     oknie lekkie podciagniecie trzyma go w tym samym miejscu i nie ucina
     kolumny odbicia, ktora biegnie od tarczy w dol. */
  object-fit: cover;
  object-position: 50% 55%;
}

/* ------------------------------------------------------------ chrome ---- */
/* Chrome strony = zegar dnia wesela plus JEDEN wyrazny przycisk do planu.
   Nie pasek marki, nie licznik sekcji.

   Zegar i przycisk sa celowo niepodobne, bo maja rozne role:
     .clock  - ozdoba. Sama godzina, bez ramki, bez kursora, bez roli
               przycisku i bez zdarzen wskaznika. Nic nie robi.
     .plan   - jedyna kontrolka. Papier z obrysem, ikona, slowo i pelne
               44 px celu dotykowego, wiec widac, ze da sie w nia kliknac.
   Wczesniej byly jednym chipem "13:10 PLAN" i nikt nie odgadywal, ze cos
   sie pod nim otwiera. */

.chrome {
  position: fixed;
  top: max(1rem, env(safe-area-inset-top));
  right: max(1rem, env(safe-area-inset-right));
  z-index: var(--sc-z-chrome);
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--sc-font-text);
}

/* --- zegar: ozdoba, nie kontrolka --------------------------------------- */
.clock {
  position: relative;
  z-index: 2;              /* nad pelnoekranowym arkuszem planu na telefonie */
  margin: 0;
  padding: 0.35rem 1rem;
  /* Welon, nie karta. Prostokat z ramka albo z backdrop-filter mial widoczna
     krawedz i znowu czytal sie jak chip do klikniecia; zageszczenie tla, ktore
     gasnie do zera, trzyma godzine czytelna i nie rysuje zadnego ksztaltu.
     Promienie sa liczone od SZEROKOSCI i WYSOKOSCI pudelka (nie od polowy),
     wiec musza byc rzedu 0.6, zeby zejscie do zera zdazylo sie zamknac
     wewnatrz krawedzi. */
  background: radial-gradient(62% 64% at 50% 50%,
              var(--w-veil) 0%,
              color-mix(in srgb, var(--w-veil) 50%, transparent) 42%,
              transparent 72%);
  pointer-events: none;    /* zaden kursor, zaden tap: to nie jest przycisk */
  user-select: none;
}
.clock__time {
  font-family: var(--sc-font-display);
  font-size: var(--sc-t-lg);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: 0.02em;
  color: var(--sc-ink-soft);
  line-height: 1;
}

/* --- przycisk planu: jedyna klikalna rzecz w chrome --------------------- */
.plan { position: relative; }

.plan__btn {
  position: relative;
  z-index: 2;              /* nad pelnoekranowym arkuszem: przycisk zamyka */
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 2.75rem;     /* 44 px celu dotykowego, takze na telefonie */
  padding: 0.5rem 0.9rem;
  list-style: none;
  cursor: pointer;
  font-size: var(--sc-t-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--sc-ink);
  background: var(--w-paper);
  border: 1px solid var(--sc-hairline-strong);
  border-radius: var(--sc-r-md);
  box-shadow: var(--sc-e1), var(--sc-edge);
  transition:
    color var(--sc-d-fast) var(--sc-ease-out),
    border-color var(--sc-d-fast) var(--sc-ease-out),
    transform var(--sc-d-fast) var(--sc-ease-out);
}
.plan__btn::-webkit-details-marker { display: none; }

@media (hover: hover) and (pointer: fine) {
  .plan__btn:hover { color: var(--sc-accent); border-color: var(--sc-accent); }
}
.plan__btn:active { transform: translateY(1px); }
/* Silnik daje globalny :focus-visible; tutaj mniejszy odstep, zeby obwodka
   nie wychodzila poza krawedz okna w rogu strony. */
.plan__btn:focus-visible {
  outline: 2px solid var(--sc-accent);
  outline-offset: 2px;
}

/* Trzy kreski. Po otwarciu skladaja sie w krzyzyk - samym transformem. */
.plan__kreski {
  position: relative;
  flex: none;
  width: 1.05rem;
  height: 0.7rem;
  background: linear-gradient(currentColor, currentColor) center / 100% 1px no-repeat;
}
.plan__kreski::before,
.plan__kreski::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: currentColor;
  transition: transform var(--sc-d-fast) var(--sc-ease-out);
}
.plan__kreski::before { top: 0; }
.plan__kreski::after { bottom: 0; }
.plan[open] .plan__kreski { background-image: none; }
.plan[open] .plan__kreski::before { transform: translateY(0.35rem) rotate(45deg); }
.plan[open] .plan__kreski::after { transform: translateY(-0.35rem) rotate(-45deg); }

/* Przycisk mowi, co zrobi klikniecie. Ukryta etykieta wypada tez z nazwy
   dostepnej, wiec czytnik slyszy dokladnie jedna. */
.plan__slowo--otwarty { display: none; }
.plan[open] .plan__slowo--zamkniety { display: none; }
.plan[open] .plan__slowo--otwarty { display: inline; }

/* --- panel: caly plan dnia + skroty. Papier, nie okno aplikacji. --------- */
.plan__panel {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 1;
  width: min(24rem, calc(100vw - 2rem));
  max-height: min(76vh, 44rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sc-5) var(--sc-5) var(--sc-6);
  background: var(--w-veil);
  border: 1px solid var(--sc-hairline);
  border-radius: var(--sc-r-md);
  box-shadow: var(--sc-e3), var(--sc-edge);
  backdrop-filter: blur(9px) saturate(1.05);
}
.plan__sheet { display: grid; gap: var(--sc-6); }
.plan__blok { display: grid; gap: var(--sc-4); }

.plan__tytul {
  margin: 0;
  font-family: var(--sc-font-text);
  font-size: var(--sc-t-xs);
  font-weight: 600;
  letter-spacing: var(--sc-track-wide);
  text-transform: uppercase;
  color: var(--sc-ink-soft);
}

.plan__skroty, .plan__godziny { list-style: none; margin: 0; padding: 0; }

.plan__skroty { display: grid; }
.plan__skroty a {
  display: block;
  padding: 0.42rem 0;
  font-family: var(--sc-font-display);
  font-size: var(--sc-t-lg);
  line-height: 1.2;
  color: var(--sc-ink);
  text-decoration: none;
  border-block-end: 1px solid var(--sc-hairline);
}
.plan__skroty li:last-child a { border-block-end: 0; }
.plan__skroty a[aria-current] { color: var(--sc-accent); }
@media (hover: hover) and (pointer: fine) {
  .plan__skroty a:hover { color: var(--sc-accent); }
}

/* Plan dnia: komplet, od razu, bez ani jednego efektu wejscia. Kazdy wpis
   wyglada dokladnie tak samo jak sasiedzi. */
.plan__godziny { display: grid; gap: 0.62rem; }
.plan__godziny li {
  display: grid;
  grid-template-columns: 6.9rem minmax(0, 1fr);
  gap: 0.75rem;
  font-size: var(--sc-t-sm);
  line-height: 1.42;
  color: var(--sc-ink);
}
.plan__godz {
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: 0.02em;
  color: var(--sc-ink-soft);
  white-space: nowrap;
}

/* --- indeks sekcji na prawym marginesie ---------------------------------
   Zamiast paska nawigacji: spis w marginesie, jak w papeterii. Miejsce ma
   zarezerwowane przez --w-rail, wiec nigdy nie wchodzi na kolumne tekstu.
   Ponizej 1040 px znika, a jego role przejmuje panel planu.               */
.wayfinder {
  display: none;
  position: fixed;
  z-index: calc(var(--sc-z-chrome) - 1);
  right: max(1rem, env(safe-area-inset-right));
  top: 50%;
  translate: 0 -50%;
  font-family: var(--sc-font-text);
  padding-right: 1.1rem;
}
/* Grunt pod indeksem sekcji. Ta sama zasada, co przy welonie: zaden ksztalt.
   Wczesniej byl to prostokat wtopiony z trzech stron i na zdjeciu widac bylo
   jego gorna krawedz. Teraz to filtr polowkowy przy prawej krawedzi kadru:
   pelna wysokosc okna (a wiec ani gornej, ani dolnej krawedzi), zejscie do zera
   wylacznie w lewo, na dlugosci ponad dwoch szerokosci kolumny etykiet, i ten
   sam kolor --w-haze, co welony kopii. */
.wayfinder::before {
  content: "";
  position: absolute;
  top: -100vh; bottom: -100vh;
  right: -3rem; left: -20rem;
  z-index: -1;
  pointer-events: none;
  opacity: 0.55;
  background: linear-gradient(to right,
              transparent 0,
              color-mix(in srgb, var(--w-haze) 4%, transparent) 18%,
              color-mix(in srgb, var(--w-haze) 13%, transparent) 34%,
              color-mix(in srgb, var(--w-haze) 30%, transparent) 50%,
              color-mix(in srgb, var(--w-haze) 55%, transparent) 65%,
              color-mix(in srgb, var(--w-haze) 80%, transparent) 80%,
              var(--w-haze) 92%,
              var(--w-haze) 100%);
}
.wayfinder ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.62rem;
  text-align: right;
}
.wayfinder a {
  display: block;
  font-size: var(--sc-t-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sc-ink-soft);
  text-decoration: none;
  transition: color var(--sc-d-fast) var(--sc-ease-out);
}
.wayfinder a[aria-current] { color: var(--sc-ink); font-weight: 600; }
@media (hover: hover) and (pointer: fine) {
  .wayfinder a:hover { color: var(--sc-accent); }
}

/* Szyna postepu: ta sama godzina dnia, tylko czytana pionowo. */
.wayfinder__rail {
  position: absolute;
  right: 0;
  top: -0.4rem; bottom: -0.4rem;
  width: 1px;
  background: var(--sc-hairline-strong);
  pointer-events: none;
}
.wayfinder__dot {
  position: absolute;
  left: 50%; top: 0;
  width: 7px; height: 7px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--sc-accent);
  transform: translateY(calc(var(--sky-t) * 100%));
}
@media (min-width: 1040px) {
  /* Indeks sekcji pojawia sie dopiero, gdy da sie na niego oddac margines bez
     okrajania kolumny tekstu. Ta sama liczba rezerwuje mu miejsce w .w-wrap
     i w .w-stage, wiec zaden naglowek nie wejdzie mu pod spod. */
  :root { --w-rail: 11rem; }
  .wayfinder { display: block; }
}

/* ------------------------------------------------------- dostepnosc ----- */

.w-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1rem;
  background: var(--sc-accent);
  color: var(--sc-accent-ink);
}
.w-skip:focus { left: 0.5rem; top: 0.5rem; }

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

/* ----------------------------------------------------- mniejsze ekrany -- */

@media (max-width: 700px) {
  :root {
    --w-t-poster: clamp(2.9rem, 17vw, 4.6rem);
    /* Szyny zegara nie ma ponizej 900 px, wiec nic nie rezerwuje miejsca po
       prawej i nie ma sensu okrawac z niego rynny. */
    --w-rail: 0rem;
    /* ...ale chrome zostaje, przyklejone do gornej krawedzi. Bez rezerwy
       naglowek kazdej sekcji flow wjezdzal pod nie w chwili, gdy gora sekcji
       dotykala gory okna. To jest ten pas, ktory chrome dostaje na wlasnosc:
       0.6rem odsuniecia + 2.75rem przycisku + oddech. Przycisk jest wyzszy od
       dawnego chipa, wiec pas musial urosnac z 2.75rem. */
    --w-chrome: 3.7rem;
  }
  .w-stage--trail { text-align: left; justify-items: start; }
  .w-col--trail { text-align: left; justify-items: start; margin-left: 0; }
  .sky { --w-horizon: 58%; }

  /* Rezerwa na chrome. Siedzi na .w-wrap, a nie na .w-act: sekcje maja wlasne
     nadpisania paddingu scopowane przez id (wyzsza waga), a .w-wrap jest
     wspolna dla wszystkich sekcji flow i nikt jej nie przestawia. */
  .w-wrap { padding-block-start: var(--w-chrome); }

  /* Chrome blizej krawedzi i ciasniej, ale przycisk NIE schudza ponizej 44 px:
     to jedyny cel dotykowy na stronie, ktory musi byc pod palcem od razu. */
  .chrome {
    top: max(0.6rem, env(safe-area-inset-top));
    right: max(0.6rem, env(safe-area-inset-right));
    gap: 0.5rem;
  }
  .clock { padding: 0.24rem 0.42rem; }
  .clock__time { font-size: var(--sc-t-base); }
  .plan__btn {
    gap: 0.45rem;
    padding: 0.5rem 0.78rem;
    font-size: 0.68rem;
    letter-spacing: 0.12em;
  }

  /* Panel na telefonie to arkusz na caly ekran: jeden tap i widac i plan dnia,
     i skroty, bez celowania w male pozycje. Przycisk i zegar zostaja nad nim,
     wiec zamkniecie jest w tym samym miejscu, w ktorym bylo otwarcie. */
  .plan__panel {
    position: fixed;
    inset: 0;
    width: auto;
    max-height: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding:
      calc(env(safe-area-inset-top) + 4.3rem) var(--sc-gutter)
      calc(env(safe-area-inset-bottom) + var(--sc-7));
    background: var(--w-veil);
    backdrop-filter: blur(18px) saturate(1.05);
  }
  .plan__sheet { max-width: 30rem; margin-inline: auto; }
  .plan__godziny li { grid-template-columns: 6.4rem minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  /* Przy ograniczonym ruchu zostaja same przenikania plansz: one nios zrozumienie
     (mija dzien), wiec ich sie nie zdejmuje. Przesuw gruntu i kontrruch od
     wskaznika znikaja, bo nie nios niczego poza glebia. */
  .sky__photo { transform: none; }
}
