.hero {
  position: relative;
  --hero-scenes: 5;        /* nadpisywane z JS realną liczbą captionów */
  --hero-scene-vh: 90;     /* JEDYNE pokrętło tempa: vh scrolla na scenę.
                              5 scen × 90 = 450vh — komfortowe tempo scruba.
                              Sensowny zakres ~70–100 */
  height: calc(var(--hero-scenes) * var(--hero-scene-vh) * 1vh);
  background: #000;
}
.hero__sticky { position: sticky; top: 0; height: 100vh; overflow: hidden; background: var(--bg); }

.hero__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; background: #000; }
/* Canvas is laid out from the start (so it has a measurable size to draw into)
   but invisible until the engine paints it — no-JS / pre-init therefore shows
   the <video> (with its poster) through it, not an opaque black canvas. */
.hero__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; visibility: hidden; z-index: 0; background: #000; }

/* Canvas scrub is live: reveal the canvas, retire the <video>, and let GSAP —
   not CSS — drive the captions, so their transitions must not double-animate. */
.hero.is-scrub .hero__canvas,
.hero.is-reduced .hero__canvas { visibility: visible; }
.hero.is-scrub .hero__video,
.hero.is-reduced .hero__video { display: none; }
.hero.is-scrub .hero__cap { transition: none; }

/* Reduced motion: canvas holds frame 0, captions crossfade on opacity only. */
.hero.is-reduced .hero__cap { transform: none; transition: opacity 0.45s linear; }
.hero.is-reduced .hero__cap.is-active { opacity: 1; transform: none; }
.hero__scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    radial-gradient(120% 85% at 50% 18%, transparent 0%, rgba(10, 10, 11, 0.35) 58%, rgba(10, 10, 11, 0.86) 100%),
    linear-gradient(to bottom, rgba(10, 10, 11, 0.55), rgba(10, 10, 11, 0.15) 32%, rgba(10, 10, 11, 0.8));
}

.hero__chrome {
  position: absolute; inset: 0; z-index: 3;
  display: flex; align-items: flex-start; justify-content: space-between;
  padding: clamp(1rem, 3vw, 1.8rem) clamp(1.2rem, 5vw, 3rem); pointer-events: none;
}
.hero__brand { display: inline-flex; align-items: baseline; gap: 2px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.hero__scroll { font-family: var(--font-mono); font-size: var(--step--1); letter-spacing: 0.28em; color: var(--text-muted); }
.hero__scroll-cue { display: inline-block; }

.hero__stage { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; padding: 0 clamp(1.2rem, 5vw, 3rem); }
.hero__cap {
  grid-area: 1 / 1; margin: 0; max-width: 20ch;
  opacity: 0; transform: translateY(28px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); will-change: opacity, transform;
}
.hero__cap p, .hero__cap blockquote { font-family: var(--font-display); font-size: var(--step-4); font-weight: 400; line-height: 1.05; letter-spacing: -0.02em; margin: 0; text-wrap: balance; }
.hero__cap em { font-style: italic; color: var(--accent); }
.hero__cap--left { justify-self: start; text-align: left; }
.hero__cap--right { justify-self: end; text-align: right; }
.hero__cap--center { justify-self: center; text-align: center; max-width: 24ch; }
.hero__cap.is-active { opacity: 1; transform: translateY(0); }

.hero__cap blockquote { font-size: var(--step-2); font-weight: 400; line-height: 1.25; letter-spacing: -0.01em; }
.hero__cap figcaption { margin-top: var(--space-4); font-family: var(--font-mono); font-size: var(--step--1); color: var(--text-muted); }
.hero__cap--finale p { font-size: var(--step-5); letter-spacing: -0.04em; }
.hero__cap--finale em { color: var(--accent); }

.hero__progress { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; z-index: 3; background: rgba(255, 255, 255, 0.08); }
.hero__progress-bar { display: block; height: 100%; width: 100%; transform: scaleX(0); transform-origin: 0 50%; background: var(--accent); }

@media (prefers-reduced-motion: no-preference) {
  .hero__scroll-cue { animation: heroCue 1.8s var(--ease) infinite; }
  @keyframes heroCue { 0%, 100% { transform: translateY(0); opacity: 0.6; } 50% { transform: translateY(4px); opacity: 1; } }
}

/* ---- reduced motion / no-JS-friendly static fallback ---- */
.hero.is-static { height: auto; }
.hero.is-static .hero__sticky { position: static; height: auto; overflow: visible; padding: clamp(4rem, 12vh, 8rem) clamp(1.2rem, 5vw, 3rem); }
.hero.is-static .hero__video { display: none; }
.hero.is-static .hero__scrim { display: none; }
.hero.is-static .hero__chrome { position: static; padding: 0 0 var(--space-7); }
.hero.is-static .hero__stage { position: static; display: grid; gap: var(--space-7); place-items: start; padding: 0; }
.hero.is-static .hero__cap { grid-area: auto; opacity: 1; transform: none; max-width: 40ch; }
.hero.is-static .hero__cap--right { justify-self: start; text-align: left; }
.hero.is-static .hero__cap--center { justify-self: start; text-align: left; }
.hero.is-static .hero__progress { display: none; }

/* Fallback when JS is disabled: the <video> plays as before, and every caption
   is revealed — stacked in flow (not piled on one grid cell) over the film. */
.no-js .hero { height: auto; }
.no-js .hero__sticky { position: static; height: auto; overflow: visible; min-height: 100vh; }
.no-js .hero__stage {
  position: static; display: flex; flex-direction: column; justify-content: center;
  gap: var(--space-7); align-items: flex-start;
  min-height: 100vh; padding: clamp(4rem, 12vh, 8rem) clamp(1.2rem, 5vw, 3rem);
}
.no-js .hero__cap { position: static; opacity: 1; transform: none; max-width: 40ch; }
.no-js .hero__cap--right, .no-js .hero__cap--center { justify-self: start; text-align: left; }
