/* ==========================================================================
   ODYSEJA — wyprawa w głąb jaskini
   Strona na fundamencie KONTRA. Mechanika: unieruchomione (sticky) kadry tła,
   które przy scrollu crossfade'ują się na kolejne (scroll-driven animations).
   Paleta (Prawo 2, ≤3): abyss (czerń-teal) · bone (kość) · glow (błękit groty).
   Kroje (Prawo 2, ≤2): Newsreader (aktor) · JetBrains Mono (log wyprawy).
   ========================================================================== */

@layer tokens {
  :root {
    /* Tokeny komponentowe projektu — paleta POWIETRZA: granat burzy + złoto świtu */
    --c-abyss:      oklch(0.16 0.02 255);   /* chłodny granat burzy */
    --c-abyss-deep: oklch(0.10 0.02 255);
    --c-bone:       oklch(0.95 0.01 240);   /* chłodna biel — tekst */
    --c-glow:       oklch(0.80 0.13 75);    /* złoto świtu — akcent/nagroda */
    --c-glow-soft:  color-mix(in oklch, var(--c-glow), transparent 70%);

    --font-mono-stack: "JetBrains Mono", ui-monospace, monospace;

    /* ziarno mocniejsze niż domyślne — materiał kinowy (Prawo 6) */
    --grain: url("data:image/svg+xml,%3Csvg viewBox='0 0 240 240' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='0.5'/%3E%3C/svg%3E");
  }
}

@layer base {
  html { overflow-x: clip; }     /* domyka clip na korzeniu — duchy tnie krawędź okna */
  body {
    background: var(--c-abyss-deep);
    color: var(--c-bone);
    font-family: var(--font-body);
    overflow-x: clip;            /* numery-duchy tnie krawędź okna, bez poziomego scrolla */
  }
  /* Globalna nakładka ziarna — nad treścią, nieklikalna (Prawo 6) */
  body::after {
    content: "";
    position: fixed; inset: 0;
    z-index: var(--z-noise);
    pointer-events: none;
    background-image: var(--grain);
    background-size: 240px 240px;
    opacity: 0.55;
    mix-blend-mode: overlay;
  }
}

@layer components {

  /* Skip-link: widoczny tylko przy fokusie klawiatury */
  .skip-link {
    position: fixed;
    inset-block-start: var(--space-4);
    inset-inline-start: 50%;
    translate: -50% 0;
    z-index: calc(var(--z-nav) + 10);
    padding: var(--space-3) var(--space-6);
    background: var(--c-glow);
    color: var(--c-abyss);
    font-family: var(--font-mono-stack);
    font-size: var(--font-size-caption);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    border-radius: var(--radius-pill);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-fast) var(--ease-standard);
  }
  .skip-link:focus-visible {
    opacity: 1;
    pointer-events: auto;
    outline: 2px solid var(--c-abyss);
    outline-offset: 2px;
  }

  /* ---------- Pasek postępu wyprawy (scroll-driven) ---------- */
  .progress {
    position: fixed; inset-block-start: 0; inset-inline: 0;
    block-size: 3px; z-index: var(--z-nav);
    background: color-mix(in oklch, var(--c-bone), transparent 88%);
  }
  .progress__bar {
    display: block; block-size: 100%; transform-origin: left center;
    transform: scaleX(0);
    background: var(--c-glow);
    box-shadow: 0 0 12px var(--c-glow), 0 0 4px var(--c-glow);
  }

  /* ---------- Topbar ---------- */
  .topbar {
    position: fixed; inset-block-start: 0; inset-inline: 0;
    z-index: var(--z-nav);
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-4) var(--spacing-fluid);
    /* blend przeniesiony z topbara na .brand — langs nie dziedziczy */
  }
  .brand {
    font-family: var(--font-mono-stack);
    font-weight: 600; letter-spacing: 0.18em;
    font-size: var(--font-size-caption);
    color: var(--c-bone); text-decoration: none; text-transform: uppercase;
    mix-blend-mode: difference;
  }
  .brand__dot { color: var(--c-glow); }
  .topbar__cta { font-family: var(--font-mono-stack); }

  /* ---------- Prawa grupa topbara — czysty kontener, BEZ chipa ----------
     Strona ciemna: langs (--c-bone) i CTA (własna pigułka-outline) czytają się
     bez podkładu. Wspólny chip zdjęty — był najmocniejszym punktem w kadrze. */
  .topbar__nav {
    display: flex;
    gap: 1rem;
    align-items: center;
    margin-inline-start: auto;
  }

  /* ---------- Przełącznik języków ---------- */
  .langs {
    display: flex;
    gap: .8ch;
    align-items: center;
    font-family: var(--font-mono-stack);
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    mix-blend-mode: normal;
  }
  .langs a {
    color: var(--c-bone);
    text-decoration: none;
    padding-block: var(--space-1);
    transition: color var(--duration-fast) var(--ease-standard);
  }
  .langs a[aria-current="true"] {
    color: var(--c-gold);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
  .langs a:not([aria-current]):hover,
  .langs a:not([aria-current]):focus-visible {
    color: color-mix(in oklch, var(--c-gold), var(--c-bone) 55%);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
  .langs a:focus-visible { outline: 2px solid var(--c-gold); outline-offset: 3px; border-radius: 1px; }

  /* ---------- Przyciski ---------- */
  .btn {
    --_pad: var(--space-3) var(--space-6);
    display: inline-flex; align-items: center; gap: var(--space-2);
    padding: var(--_pad);
    font-size: var(--font-size-caption); font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
    border-radius: var(--radius-pill);
    transition: transform var(--duration-fast) var(--ease-spring),
                background-color var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard);
  }
  .btn:hover { transform: translateY(-2px); }
  .btn--ghost {
    color: var(--c-bone);
    border: 1px solid color-mix(in oklch, var(--c-bone), transparent 55%);
  }
  .btn--ghost:hover { background: var(--c-bone); color: var(--c-abyss); }
  .btn--solid {
    color: var(--c-abyss); background: var(--c-glow);
    box-shadow: 0 0 24px var(--c-glow-soft);
  }
  .btn--solid:hover { background: color-mix(in oklch, var(--c-glow), white 12%); }
  .btn--text {
    color: var(--c-abyss); padding-inline: 0;
    border-bottom: 2px solid var(--c-glow); border-radius: 0;
  }
  .btn--text:hover { color: var(--c-glow); }

  /* ---------- Etykiety (mono) ---------- */
  .kicker {
    font-family: var(--font-mono-stack);
    font-size: var(--font-size-caption);
    letter-spacing: 0.28em; text-transform: uppercase;
    color: color-mix(in oklch, var(--c-bone), transparent 25%);
    margin-block-end: var(--space-4);
  }
  .kicker--glow { color: var(--c-glow); text-shadow: 0 0 18px var(--c-glow-soft); }
  .kicker--ink { color: color-mix(in oklch, var(--c-abyss), transparent 30%); }

  /* ====================================================================
     WYPRAWA — sticky tło + przewijane rozdziały
     ==================================================================== */
  .journey {
    position: relative;
    /* udostępnia osie czasu rozdziałów elementom z innego poddrzewa */
    timeline-scope: --c1, --c2, --c3, --c4, --c5;
  }

  /* Unieruchomione kadry */
  .frames {
    position: sticky; inset-block-start: 0;
    block-size: 100svh; overflow: clip;
    z-index: var(--z-base);
  }
  .frame {
    position: absolute; inset: 0;
    inline-size: 100%; block-size: 100%;
    object-fit: cover; opacity: 0;
    transform: scale(1.06);
    will-change: opacity, transform;
  }
  .frame:first-child { opacity: 1; transform: scale(1); }  /* warstwa bazowa */

  /* Finał: wysoki kadr, przez który „unosi się kamera" (object-position) */
  .frame--tall { transform: none; object-position: 50% 100%; }  /* start: dół = jezioro w mroku */

  /* Scrim: czytelność tekstu + winieta (Prawo 6/7) — nad kadrami */
  .frames::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      radial-gradient(120% 80% at 50% 0%, transparent 40%, var(--c-abyss-deep) 100%),
      linear-gradient(180deg,
        color-mix(in oklch, var(--c-abyss-deep), transparent 35%) 0%,
        transparent 28%, transparent 60%,
        color-mix(in oklch, var(--c-abyss-deep), transparent 10%) 100%);
  }

  /* Rozdziały nad tłem (negatywny margines = nakładanie na sticky) */
  .chapters {
    position: relative; z-index: var(--z-content);
    margin-block-start: -100svh;
  }
  .chapter {
    min-block-size: 100svh;
    display: grid; align-content: center;
    gap: var(--space-5, 1.25rem);
    padding: var(--space-16) var(--spacing-fluid);
    max-inline-size: 1400px; margin-inline: auto;
    position: relative;
  }
  /* Asymetria (Prawo 3): rozdziały raz z lewej, raz z prawej, różne pasy */
  .chapter > * { max-inline-size: min(42ch, 100%); }
  .chapter--hero  { align-content: end; padding-block-end: var(--space-24); }
  .chapter--right { justify-items: end; text-align: right; }
  .chapter--right > * { margin-inline-start: auto; }
  .chapter--left  { justify-items: start; }
  /* Finał: wysoki TOR przewijania (daje dystans na odsłonę), bez własnego layoutu */
  .chapter--climax {
    min-block-size: 230svh;
    display: block; max-inline-size: none; padding: 0; margin-inline: 0;
  }
  /* Tekst PRZYKLEJONY — trzyma się ekranu, gdy tło się unosi; zwalnia na końcu toru */
  .climax-text {
    position: sticky; inset-block-start: 0;
    min-block-size: 100svh;
    display: grid; align-content: center; justify-items: start;
    gap: var(--space-5, 1.25rem);
    padding: var(--space-16) var(--spacing-fluid);
    max-inline-size: min(1400px, 100%); margin-inline: auto;
  }
  .climax-text > * { max-inline-size: min(46ch, 100%); }
  .climax-text .ghost { inset-block-start: 12vh; transform: none; }
  /* miękki scrim pod tekstem — pełny viewport (jak .frames::after), lewa strona ciemna, prawa odsłonięta */
  .climax-text::before {
    content: ""; position: absolute;
    inset-block: 0;
    inset-inline-start: calc(50% - 50vw);
    inline-size: 100vw;
    z-index: -2; pointer-events: none;
    background: linear-gradient(90deg,
      color-mix(in oklch, var(--c-abyss-deep), transparent 20%) 0%,
      color-mix(in oklch, var(--c-abyss-deep), transparent 45%) 28%,
      transparent 62%);
  }

  /* Typografia-aktor (Prawo 4): hero gigant */
  .display {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(2.6rem, 7vw, 6.5rem);
    line-height: 0.98; letter-spacing: -0.02em;
    max-inline-size: 16ch;
    text-shadow: 0 2px 40px var(--c-abyss-deep);
  }
  .lead {
    font-size: clamp(1.05rem, 1.4vw + 0.6rem, 1.5rem);
    color: color-mix(in oklch, var(--c-bone), transparent 12%);
    text-shadow: 0 1px 24px var(--c-abyss-deep);
  }
  .step {
    font-family: var(--font-display); font-weight: 500;
    font-size: clamp(1.9rem, 4.5vw, 4rem);
    line-height: 1.0; letter-spacing: -0.015em;
    text-shadow: 0 2px 36px var(--c-abyss-deep);
  }
  .step--climax em {
    font-style: italic; color: var(--c-glow);
    text-shadow: 0 0 40px var(--c-glow-soft);
  }
  .body {
    font-size: clamp(1rem, 0.6vw + 0.85rem, 1.2rem);
    color: color-mix(in oklch, var(--c-bone), transparent 15%);
    text-shadow: 0 1px 20px var(--c-abyss-deep);
  }
  .scrollcue {
    font-family: var(--font-mono-stack); font-size: var(--font-size-caption);
    letter-spacing: 0.3em; text-transform: uppercase; margin-block-start: var(--space-8);
    color: var(--c-glow); animation: cue 2.2s var(--ease-in-out) infinite;
  }
  @keyframes cue { 0%,100% { opacity: 0.35; transform: translateY(0); }
                   50% { opacity: 1; transform: translateY(4px); } }

  /* Gigantyczny duch numeru etapu — aktor typograficzny ucięty na krawędzi (Prawo 1+4) */
  .ghost {
    position: absolute; z-index: -1;
    inset-block-start: 50%; inset-inline-end: -0.08em;
    transform: translateY(-50%);
    font-family: var(--font-display); font-weight: 600;
    font-size: clamp(14rem, 34vw, 30rem); line-height: 0.7;
    color: transparent;
    -webkit-text-stroke: 1.5px color-mix(in oklch, var(--c-bone), transparent 80%);
    mix-blend-mode: soft-light; pointer-events: none; user-select: none;
  }
  .chapter--left .ghost { inset-inline-end: auto; inset-inline-start: -0.08em; }
  .ghost--glow {
    -webkit-text-stroke: 2px var(--c-glow);
    opacity: 0.5; mix-blend-mode: screen;
  }

  /* ====================================================================
     NAGRODA — wyjście w światło (pacing jasny po ciemnym, Prawo 5)
     ==================================================================== */
  .reward {
    position: relative; z-index: var(--z-content);
    background: var(--c-bone); color: var(--c-abyss);
    padding: clamp(var(--space-16), 12vh, var(--space-40)) var(--spacing-fluid);
    display: grid; gap: var(--space-8);
    justify-items: start;
    /* górna krawędź łamana — wyłom z prostokąta (Prawo 1) */
    clip-path: polygon(0 2.5vw, 100% 0, 100% 100%, 0 100%);
  }
  .reward > * { max-inline-size: var(--container-lg); }
  .reward__title {
    font-family: var(--font-display); font-weight: 500;
    font-size: clamp(2.4rem, 6vw, 5rem); line-height: 0.98; letter-spacing: -0.02em;
    max-inline-size: 18ch;
  }
  .reward__lead {
    font-size: clamp(1.05rem, 1.2vw + 0.7rem, 1.4rem);
    color: color-mix(in oklch, var(--c-abyss), transparent 20%);
  }

  /* Łupy — bento z asymetrią skali, nie równy grid (Prawo 1/3) */
  .spoils {
    display: grid; gap: var(--space-4); inline-size: 100%;
    max-inline-size: 100%;
    grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
  }
  .spoil {
    border-top: 2px solid var(--c-abyss);
    padding-block-start: var(--space-4);
    display: grid; gap: var(--space-2); align-content: start;
  }
  .spoil:nth-child(2) { transform: translateY(var(--space-8)); }  /* asymetria */
  .spoil__no {
    font-family: var(--font-mono-stack); font-weight: 600;
    color: var(--c-glow); font-size: var(--font-size-h2);
    -webkit-text-stroke: 0.5px var(--c-abyss);
  }
  .spoil__h {
    font-family: var(--font-display); font-weight: 600;
    font-size: var(--font-size-h2); color: var(--c-abyss); letter-spacing: -0.01em;
  }
  .spoil p { color: color-mix(in oklch, var(--c-abyss), transparent 25%); }

  .reward__cta { display: flex; flex-wrap: wrap; gap: var(--space-6); align-items: center;
                 margin-block-start: var(--space-4); }

  /* ---------- Stopka ---------- */
  .foot {
    background: var(--c-abyss-deep); color: var(--c-bone);
    padding: var(--space-8) var(--spacing-fluid);
    display: flex; flex-wrap: wrap; gap: var(--space-4);
    align-items: baseline; justify-content: space-between;
  }
  .foot__note {
    font-family: var(--font-display); font-style: italic;
    color: color-mix(in oklch, var(--c-bone), transparent 35%);
    font-size: var(--font-size-h2);
  }
}

/* ==========================================================================
   RUCH STEROWANY SCROLLEM (Prawo 8) — progres + crossfade kadrów
   ========================================================================== */
@supports (animation-timeline: view()) {
  @layer utilities {
    /* pasek postępu: skala wg pozycji scrolla całego dokumentu */
    .progress__bar {
      animation: grow linear both;
      animation-timeline: scroll(root block);
    }
    @keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }

    /* każdy rozdział wystawia własną oś czasu „view” */
    .chapter:nth-of-type(1) { view-timeline-name: --c1; }
    .chapter:nth-of-type(2) { view-timeline-name: --c2; }
    .chapter:nth-of-type(3) { view-timeline-name: --c3; }
    .chapter:nth-of-type(4) { view-timeline-name: --c4; }
    .chapter:nth-of-type(5) { view-timeline-name: --c5; }

    /* kadr N wyłania się, gdy rozdział N wchodzi w kadr; zostaje na wierzchu
       (kolejność DOM) i przykrywa poprzedni — czysty dissolve */
    .frame { animation: reveal both linear; }
    .frame:nth-child(2) { animation-timeline: --c2; }
    .frame:nth-child(3) { animation-timeline: --c3; }
    .frame:nth-child(4) { animation-timeline: --c4; }
    .frame:nth-child(n+2):not(.frame--tall) { animation-range: entry 8% entry 60%; }

    /* FINAŁ: pan w górę przez wysoki kadr przez cały (długi) rozdział climax */
    .frame--tall {
      animation-name: reveal-pan;
      animation-timeline: --c5;
      /* pan dzieje się, GDY tekst jest już przyklejony (climax pinned ~30–70%);
         potem niebo PRZYTRZYMANE (fill both), zanim wjedzie sekcja nagrody */
      animation-range: cover 4% cover 70%;
    }

    @keyframes reveal {
      from { opacity: 0; transform: scale(1.06); }
      to   { opacity: 1; transform: scale(1); }
    }
    /* fade-in na dole (jezioro w mroku) → TRZYMAJ, aż tekst się przyklei →
       dopiero potem unoszenie kamery do odsłony nieba (tekst pozostaje pinned) */
    @keyframes reveal-pan {
      0%   { opacity: 0; object-position: 50% 100%; }
      14%  { opacity: 1; object-position: 50% 100%; }
      42%  { opacity: 1; object-position: 50% 100%; }
      100% { opacity: 1; object-position: 50% 0%; }
    }
  }
}

/* ==========================================================================
   DOSTĘPNOŚĆ (Prawo 10) — fallback bez ruchu: spokojny, statyczny hero
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  /* Reduced-motion: NIE chowamy narracji. Crossfade opacity (sterowany scrollem)
     zostaje — to nie ruch wstrzasowy. Wycinamy tylko ruch wektorowy: zoom kadrow
     (scale) i pionowy pan finalu. Kazda scena nadal sie pojawia. */
  .frame { transform: none !important; }
  .frame--tall { object-position: 50% 82% !important; }
  .progress__bar { transform: scaleX(0) !important; }
}

/* ---------- Fix: topbar znika w strefie NAGRODY (light), by ODYSSEY nie nachodziło
   na tytuł przy końcu scrolla. Scroll-driven; degraduje sie lagodnie (gdy brak
   wsparcia, topbar po prostu zostaje). Marka pozostaje w stopce. ---------- */
@layer components {
  body { timeline-scope: --prize; }
  .reward { view-timeline: --prize block; }
  .topbar {
    animation: topbar-vanish linear both;
    animation-timeline: --prize;
    animation-range: cover 0% cover 10%;
  }
}
@keyframes topbar-vanish { to { opacity: 0; visibility: hidden; } }

/* ==========================================================================
   TOR 5 — BRAMKA ORIENTACJI (portrait rotate-gate)
   Interstitial-ekspedycja: telefon w pionie → poproś o obrót.
   Memorable: złota ramka-kadr ≈16:9 przechylająca się pion→poziom.
   Pokazywana TYLKO: portrait + dotyk (coarse/no-hover) + max-width telefonu.
   Paleta §4: czerń + kość + złoto. Typografia §5: Newsreader + JetBrains Mono.
   ========================================================================== */
@layer components {
  .gate {
    /* domyślnie schowana — odsłania ją wyłącznie media query telefonu w pionie */
    display: none;
    position: fixed;
    inset: 0;
    /* ponad wszystkim w obrębie systemu: nav (50), ziarno (10), toast (100) */
    z-index: calc(var(--z-toast) + 10);
    background: var(--c-abyss-deep);
    color: var(--c-bone);
    overflow: hidden;
  }
  /* delikatne ziarno także na bramie — ten sam materiał kinowy */
  .gate::after {
    content: "";
    position: absolute; inset: 0;
    pointer-events: none;
    background-image: var(--grain);
    background-size: 240px 240px;
    opacity: 0.5;
    mix-blend-mode: overlay;
  }

  .gate__inner {
    position: relative;
    height: 100%;
    min-height: 100svh;
    display: grid;
    grid-template-rows: 1fr auto auto;
    align-items: stretch;
    padding: clamp(1.75rem, 7vw, 3rem);
    gap: clamp(1.5rem, 5vh, 2.75rem);
  }

  /* --- Memorable element: złota ramka-kadr 16:9 (W5 słowo/rzeźba-jako-obiekt) --- */
  .gate__stage {
    align-self: center;
    justify-self: start;          /* off-center, blocking osi (W10) */
    width: min(68vw, 280px);
    aspect-ratio: 16 / 9;
    margin-inline-start: clamp(0.5rem, 4vw, 2rem);
    display: grid;
    place-items: center;
    /* spoczynek: kadr stoi pionowo, jak trzymany telefon */
    transform: rotate(90deg);
    transform-origin: center;
    animation: gate-tilt 4.8s var(--ease-in-out) infinite;
  }
  .gate__frame {
    width: 100%;
    height: 100%;
    border: 1.5px solid var(--c-gold, oklch(0.80 0.12 80));
    border-radius: 2px;
    box-shadow:
      0 0 24px color-mix(in oklch, var(--c-gold, oklch(0.80 0.12 80)), transparent 78%),
      inset 0 0 18px color-mix(in oklch, var(--c-gold, oklch(0.80 0.12 80)), transparent 88%);
  }

  @keyframes gate-tilt {
    /* powolny gest pion→poziom→pion, z wyraźną pauzą w obu skrajach */
    0%, 22%   { transform: rotate(90deg); }
    50%, 72%  { transform: rotate(0deg); }
    100%      { transform: rotate(90deg); }
  }

  /* --- Tekst: eyebrow mono / serif-aktor / mikro-szept + wentyl --- */
  .gate__text {
    align-self: end;
    max-width: 32ch;
  }
  .gate__eyebrow {
    font-family: var(--font-mono-stack);
    font-size: var(--font-size-caption);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: color-mix(in oklch, var(--c-bone), transparent 35%);
    margin: 0 0 var(--space-4);
  }
  .gate__line {
    font-family: var(--font-display);   /* Newsreader (editorial) */
    font-weight: 500;
    font-size: clamp(1.9rem, 8.5vw, 2.9rem);
    line-height: 1.04;
    letter-spacing: -0.01em;
    margin: 0;
  }
  .gate__line em {
    font-style: italic;
    color: var(--c-gold, oklch(0.80 0.12 80));
  }
  .gate__whisper {
    font-family: var(--font-mono-stack);
    font-size: calc(var(--font-size-caption) - 0.05rem);
    line-height: 1.5;
    letter-spacing: 0.02em;
    color: color-mix(in oklch, var(--c-bone), transparent 52%);
    margin: 0;
    max-width: 34ch;
  }
  /* wentyl „Enter anyway" — dyskretny, mały, NIGDY główny CTA */
  .gate__vent {
    display: inline-block;
    margin-top: var(--space-2);
    font-family: var(--font-mono-stack);
    font-size: calc(var(--font-size-caption) - 0.05rem);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: color-mix(in oklch, var(--c-bone), transparent 45%);
    text-decoration: none;
    border: 0;
    background: none;
    padding: var(--space-2) 0;
    cursor: pointer;
    border-bottom: 1px solid color-mix(in oklch, var(--c-bone), transparent 72%);
  }
  .gate__vent:hover,
  .gate__vent:focus-visible { color: var(--c-bone); }
  .gate__vent:focus-visible { outline: 2px solid var(--c-gold, oklch(0.80 0.12 80)); outline-offset: 3px; }

  .gate__foot {
    align-self: end;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  /* statyczny znak kierunku — pokazywany TYLKO w reduced-motion */
  .gate__arc { display: none; }
}

/* --- WARUNEK WYŚWIETLANIA: telefon w pionie (§5.4) ---
   portrait + dotyk (coarse/no-hover) + szerokość telefonu (NIE tablet). */
@media (orientation: portrait) and (pointer: coarse) and (hover: none) and (max-width: 768px) {
  .gate { display: block; }
  /* treść pod bramą zatrzymana: climax nie składa się od razu w pionie */
  body > main,
  body > header.topbar,
  body > footer,
  body > .progress { visibility: hidden; }
}

/* wentyl: po kliknięciu „Enter anyway" brama znika mimo portretu, treść wraca.
   Specyficzność html.gate-dismissed .gate (0,2,1) > .gate w MQ (0,1,1) — bez !important. */
html.gate-dismissed .gate { display: none; }
@media (orientation: portrait) and (pointer: coarse) and (hover: none) and (max-width: 768px) {
  html.gate-dismissed > body > main,
  html.gate-dismissed > body > header.topbar,
  html.gate-dismissed > body > footer,
  html.gate-dismissed > body > .progress { visibility: visible; }
}

/* --- reduced-motion (OBOWIĄZKOWY §9): zero przechyłu i pętli --- */
@media (prefers-reduced-motion: reduce) {
  .gate__stage {
    animation: none;
    transform: rotate(0deg);    /* statyczna ramka pozioma */
  }
  .gate__arc {
    display: block;
    margin-top: var(--space-3);
    width: 44px; height: 1.5px;
    background: linear-gradient(90deg, transparent, var(--c-gold, oklch(0.80 0.12 80)));
    position: relative;
  }
  .gate__arc::after {
    content: "";
    position: absolute; right: 0; top: 50%;
    width: 8px; height: 8px;
    border-top: 1.5px solid var(--c-gold, oklch(0.80 0.12 80));
    border-right: 1.5px solid var(--c-gold, oklch(0.80 0.12 80));
    transform: translateY(-50%) rotate(45deg);
  }
}

/* ==========================================================================
   FIX RESPONSYWNY — telefon w poziomie (landscape) z niskim viewportem
   Cel: tekst rozdziałów nie zasłania kadru; kadr dominuje jak na desktopie.
   Warunki: landscape + max-height 480px + dotyk (pointer: coarse) —
   nie ruszamy desktopu (pointer: fine) ani tabletu w poziomie (zwykle >480px).
   ========================================================================== */
@media (orientation: landscape) and (max-height: 480px) and (pointer: coarse) {
  /* HIERARCHIA (jak desktop): headline-aktor WYRAŹNIE dominuje nad akapitem.
     Stosunek step:body ~2.4:1 (desktop ~3:1) — headline czyta się jako bohater. */
  .step {
    font-size: 1.85rem;
    line-height: 1.04;
  }
  /* Climax step jeszcze mocniejszy — to puenta aktu */
  .step--climax {
    font-size: 2.1rem;
  }
  /* Body copy: subtelny podpis pod headlinem — wyraźnie mniejszy, ciaśniejszy */
  .body {
    font-size: 0.78rem;
    line-height: 1.4;
  }
  /* Akapit w spoil (reward) — ten sam token */
  .spoil p {
    font-size: 0.78rem;
  }
  /* Padding pionowy rozdziału: skróć by blok tekstu był kompaktowy */
  .chapter {
    padding-block: var(--space-6);
    min-block-size: 100svh;
  }
  /* Climax-text: zmniejsz padding pionowy */
  .climax-text {
    padding-block: var(--space-6);
  }
  /* Ghost numer: powściągliwy akcent — wpisany w kadr, nie zasłona, nie plamka */
  .ghost {
    font-size: clamp(8rem, 24vw, 15rem);
  }

  /* --- B: przełącznik języków na telefonie ---
     isolation: isolate w .langs (desktop) już wyłącza blend.
     Na telefonie podbijamy rozmiar i tap-target. */
  .topbar { mix-blend-mode: normal; }
  .langs { font-size: .8rem; }
  .langs a { padding-block: var(--space-2); }

  /* --- C: PILLARBOX — dyskretne czarne paski L+R ---
     Zbliża kadr telefonu do proporcji desktopu (kadr poziomy = sens marki).
     Subtelnie: ~5% szerokości na stronę, czerń kanonu (--c-abyss-deep).
     Jedno fixed pseudo, gradient czarny-przezroczysty-czarny = oba paski naraz;
     nieklikalne, pod ziarnem/treścią nie chowa (jest nad kadrem, pod nawigacją). */
  body::before {
    content: "";
    position: fixed; inset: 0;
    z-index: calc(var(--z-nav) - 1);   /* nad kadrem i tekstem, pod topbarem */
    pointer-events: none;
    background:
      linear-gradient(90deg,
        var(--c-abyss-deep) 0,
        var(--c-abyss-deep) 4.5%,
        transparent 4.5%,
        transparent 95.5%,
        var(--c-abyss-deep) 95.5%,
        var(--c-abyss-deep) 100%);
  }
  /* treść siedzi MIĘDZY paskami — padding > szerokość paska, by tekst nie wpadał pod czerń */
  .chapter,
  .climax-text,
  .reward { padding-inline: 6.5%; }
  .topbar { padding-inline: 6.5%; }
}
