/* ═══ CARMA · Website v2 ═══
   Locked brand: loop mark + CARMA wordmark.
   Type: Instrument Sans (display) + Geist (body), IBM Plex Mono (data).
   Single colorway: Cream (Hai × Sumi). Mobile-first, centered, calm.
   Tokens sourced from carma-tokens.css (single source of truth). */

/* NOTE: :root tokens removed from here — imported via carma-tokens.css.
   The two --radius tokens are the one sanctioned refactor per TOKENS.md §3. */

* { box-sizing: border-box; margin: 0; padding: 0; }
/* Scroll restoration on a history back-navigation is a PROGRAMMATIC scroll on the
   scrolling element, so it obeys this property. Unconditional `smooth` therefore made
   every "back" ANIMATE from the top of the document down to the restored offset — the
   page visibly travelled through its whole length before settling. Measured on /pl:
   one scrollTo produced 64 intermediate positions over ~1.2s.

   Gate it on :has(:target) so smooth applies only while a fragment is actually
   targeted — clicking an in-page #link, which is the case it was added for — and never
   on a back-navigation, which carries no fragment. #main-content is excluded because a
   keyboard user following the skip link wants focus to arrive at once. */
html { scroll-behavior: auto; }
@media (prefers-reduced-motion: no-preference) {
  html:has(:target:not(#main-content)) { scroll-behavior: smooth; }
}
body {
  font-family: var(--f-body); background: var(--paper); color: var(--ink);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  transition: background 0.4s ease, color 0.4s ease;
}
/* The frozen _design/ oracle renders body with the UA-default line-height
   (`normal`); the EmDash template's global Base.astro layout injects
   `body { line-height: 1.6 }`, which leaks onto CARMA pages via the dev/route
   style graph and inflates every heading that inherits it (e.g. `.aud-h`,
   `.aud-earn strong`, `.label` on /ambasadorzy). `body.carma` (added by
   CarmaBase) out-specifies the plain `body` rule and restores `normal`,
   keeping the CMS-driven pages pixel-identical to the design. */
body.carma { line-height: normal; }
::selection { background: var(--accent-tint); }

.wrap { width: 100%; max-width: var(--wrap-max); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
.narrow { width: 100%; max-width: var(--narrow-max); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }
.center { text-align: center; }

.label { font-family: var(--f-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.24em; text-transform: uppercase; color: var(--gray-soft); }
.h2 { font-family: var(--f-display); font-size: clamp(30px, 5.4vw, 50px); font-weight: 400; letter-spacing: -0.025em; line-height: 1.08; margin-top: 20px; text-wrap: balance; }
.sub { font-size: clamp(15px, 2.3vw, 18px); line-height: 1.7; color: var(--gray); margin: 20px auto 0; max-width: 540px; text-wrap: pretty; }
.section { padding: var(--section-y) 0; }
.hr { border: none; border-top: 1px solid var(--line-soft); }
.hr.wrap { max-width: var(--wrap-max); }

.rv { opacity: 0; transform: translateY(20px); transition: opacity 0.7s ease, transform 0.7s ease; }
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { animation: none !important; transition-duration: 0.001s !important; }
  html { scroll-behavior: auto; }
}

/* ── Logo ── */
.logo { display: flex; align-items: center; gap: 11px; text-decoration: none; color: var(--ink); }
.logo svg { display: block; flex-shrink: 0; }
.logo-text { display: flex; flex-direction: column; align-items: stretch; gap: 4px; }
.logo-word { font-family: var(--f-body); font-size: 15px; font-weight: 400; letter-spacing: 0.4em; line-height: 1; }

/* letter-spacing also applies AFTER the final A, so the wordmark's box is 0.4em
   wider than its ink. Pulling that back makes the box equal the visible letters,
   which is what the sub-line below is justified against — otherwise it would
   overshoot CARMA's right edge by 6px. Scoped to .logo-text so the footer logo,
   which has no sub-line, keeps its original box. */
.logo-text .logo-word { margin-right: -0.4em; }

/* Justified to the wordmark's width: the letters are individual spans and
   space-between pushes the first and last hard against the edges, so "dobra
   jazda" lines up with the C and the A above it. Works for any string, so PL and
   EN both fit without per-locale tracking values. */
.logo-sub {
  display: flex; justify-content: space-between;
  font-family: var(--f-body); font-size: 7px; font-weight: 500;
  letter-spacing: 0; text-transform: lowercase;
  color: var(--gray-soft); line-height: 1;
}
/* The word gap. Without a width of its own the space would be distributed like
   any other letter gap and "dobra jazda" would read as one run of letters. */
.logo-sub-sp { width: 0.34em; flex: 0 0 auto; }
.logo-word--lg { font-size: 22px; }

/* ── Nav ── */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.nav-inner { max-width: 1180px; margin: 0 auto; padding: 0 24px; height: 66px; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.nav-links { display: none; list-style: none; gap: 34px; }
.nav-links a { font-size: 13px; font-weight: 500; letter-spacing: 0.02em; color: var(--ink); text-decoration: none; opacity: 0.66; transition: opacity 0.18s; }
.nav-links a:hover { opacity: 1; }
@media (min-width: 900px) { .nav-links { display: flex; } }
.nav-cta {
  display: inline-flex; align-items: center; min-height: 42px; padding: 0 20px; white-space: nowrap;
  background: var(--ink); color: var(--paper); border: 1px solid var(--ink); border-radius: var(--radius);
  font-size: 12px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  transition: opacity 0.18s;
}
.nav-cta:hover { opacity: 0.84; }

/* ── Nav: active state + mobile menu ──
   MUST live here, not in carma-pages.css. Nav.astro is global chrome — every
   page renders .nav-toggle/.nav-menu — but carma-pages.css is loaded only when
   `includePagesCss` is true, and the homepage sets it false (mirroring the
   design oracle, whose index.html had no mobile menu markup at all). While
   these rules sat in carma-pages.css the homepage rendered the menu
   permanently expanded and unstyled, with the hamburger showing at desktop.
   Guarded by src/lib/nav-chrome-css.test.ts. */
.nav-links a.active { opacity: 1; color: var(--ink); }
.nav-links a.active::after {
  content: ''; display: block; height: 1px; background: var(--ink);
  margin-top: 5px; opacity: 0.85;
}
.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin-right: -10px; background: none; border: none;
  cursor: pointer; color: var(--ink);
}
.nav-toggle svg { display: block; }
.nav-menu { display: none; }
/* Desktop tail — language switcher + CTA, grouped so .nav-inner keeps three
   flex items and the centred nav links don't shift. Below 900px the whole tail
   is hidden and the mobile overlay carries both controls. */
.nav-end { display: none; align-items: center; gap: 14px; }
@media (min-width: 900px) { .nav-end { display: inline-flex; } }
@media (max-width: 899px) {
  .nav-cta { display: none; }
  .nav-toggle { display: inline-flex; }
  .nav-menu {
    display: block; overflow: hidden; max-height: 0;
    border-top: 1px solid transparent; background: var(--paper);
    transition: max-height 0.34s ease, border-color 0.34s ease;
  }
  .nav-menu.open { max-height: 80vh; border-top-color: var(--line-soft); }
  .nav-menu ul { list-style: none; padding: 8px 24px 22px; }
  .nav-menu li { border-bottom: 1px solid var(--line-soft); }
  .nav-menu li:last-child { border-bottom: none; }
  .nav-menu a {
    display: flex; align-items: center; justify-content: space-between;
    padding: 16px 2px; font-size: 16px; color: var(--ink); text-decoration: none;
  }
  .nav-menu a.active { color: var(--gray); }
  .nav-menu .nav-menu-cta { margin-top: 16px; }
  .nav-menu .nav-menu-cta a { justify-content: center; background: var(--ink); color: var(--paper); padding: 16px; border-radius: var(--radius); letter-spacing: 0.1em; text-transform: uppercase; font-size: 13px; }
}

/* ── Buttons ── */
.btn-solid {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 54px; padding: 0 34px;
  background: var(--ink); color: var(--paper); border: 1px solid var(--ink); border-radius: var(--radius);
  font-family: var(--f-body); font-size: 12px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  text-decoration: none; cursor: pointer; transition: opacity 0.18s;
}
.btn-solid:hover { opacity: 0.84; }
.btn-out {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 54px; padding: 0 32px;
  background: transparent; color: var(--ink); border: 1px solid var(--line); border-radius: var(--radius);
  font-size: 12px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none; cursor: pointer;
  transition: border-color 0.18s;
}
.btn-out:hover { border-color: var(--ink); }

/* ── Hero ── */
.hero { padding: 152px 24px 0; text-align: center; position: relative; overflow: hidden; }
.hero-aura {
  position: absolute; top: -10%; left: 50%; transform: translateX(-50%);
  width: min(900px, 120vw); height: 560px; pointer-events: none; z-index: 0;
  background: radial-gradient(ellipse at center, var(--accent-tint) 0%, transparent 68%);
}
.hero > *:not(.hero-aura) { position: relative; z-index: 1; }
.hero h1 {
  font-family: var(--f-display); font-size: clamp(40px, 8vw, 82px); font-weight: 400; letter-spacing: -0.03em;
  line-height: 1.04; max-width: 16ch; margin: 28px auto 0; text-wrap: balance;
}
.hero-sub { font-size: clamp(15px, 2.4vw, 19px); line-height: 1.65; color: var(--gray); max-width: 470px; margin: 26px auto 0; text-wrap: pretty; }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 40px; }
.hero-visual {
  margin: clamp(56px, 9vw, 100px) auto 0; max-width: 1180px; height: clamp(280px, 48vw, 600px);
  background: repeating-linear-gradient(-45deg, var(--panel) 0 16px, color-mix(in srgb, var(--panel) 60%, var(--silver)) 16px 32px);
  display: flex; align-items: center; justify-content: center; position: relative; border: 1px solid var(--line-soft);
}
.hero-visual span { font-family: var(--f-mono); font-size: 11px; color: var(--gray-soft); border: 1px dashed var(--line); padding: 10px 16px; background: color-mix(in srgb, var(--paper) 70%, transparent); }
.hero-visual figcaption { position: absolute; bottom: 16px; left: 20px; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--gray-soft); }

/* ── Cinematic scroll sequence ──────────────────────────────────────────────
 *
 * Two layouts live in this block, and which one you get is decided by a single
 * class on <html>.
 *
 *   DEFAULT (no class)  — a plain, vertically-flowing, readable document:
 *     hero → testimonials → process steps → stats → outro, with a static poster
 *     for the car. This is what renders with JS off, after a JS error, and under
 *     prefers-reduced-motion. It has to stand on its own, because it is the floor
 *     the cinematic mode falls back to.
 *
 *   .cine-motion        — the scroll-scrubbed cinematic sequence.
 *     Added pre-paint by the inline script in CinematicHero.astro, and only when
 *     motion is allowed.
 *
 * Adding the class is what opts IN. Nothing opts out. So every path that fails to
 * run the driver — any of them — leaves the safe layout standing.
 *
 * This used to be inverted: the cinematic layout was the default and JS added
 * `is-live` to HIDE the stacked beats. Every path that skipped that class
 * (reduced motion, JS disabled, a throw before the class was added) painted all
 * five absolutely-positioned beat layers on top of one another.
 */
.cine { position: relative; }
.cine-stage {
  position: relative; display: block;
  background:
    radial-gradient(ellipse 70% 60% at 50% 42%, var(--accent-tint) 0%, transparent 62%),
    linear-gradient(180deg, var(--paper) 0%, var(--panel) 100%);
}

.cine-motion .cine { height: 540vh; }
.cine-motion .cine-stage {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.cine-rule { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line-soft); pointer-events: none; z-index: 3; }
.cine-rule.l { left: max(24px, calc((100vw - 1180px) / 2 + 24px)); }
.cine-rule.r { right: max(24px, calc((100vw - 1180px) / 2 + 24px)); }
/* Scroll affordances belong to the cinematic mode only — there is nothing to
   scrub in the static layout, so promising a scrub would be a lie. */
.cine-tick, .cine-progress { display: none; }
.cine-motion .cine-tick { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gray-soft); display: flex; align-items: center; gap: 10px; z-index: 5; }
.cine-tick span { width: 30px; height: 1px; background: var(--line); display: inline-block; }
.cine-motion .cine-progress { position: absolute; bottom: 0; left: 0; height: 2px; background: var(--ink); z-index: 6; width: 0; display: block; }

.cine-floor {
  position: absolute; left: 50%; bottom: 21%; transform: translateX(-50%);
  width: min(60vw, 620px); height: 60px; border-radius: 50%;
  background: radial-gradient(ellipse at center, color-mix(in srgb, var(--ink) 22%, transparent) 0%, transparent 70%);
  filter: blur(8px); will-change: opacity, transform; z-index: 1;
}
.car-layer {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  will-change: transform, opacity, filter; z-index: 2;
}
.car-layer image-slot { width: min(80vw, 940px); height: min(52vh, 520px); }

.cine-3d { position: absolute; inset: 0; z-index: 2; opacity: 0; will-change: opacity; }
.cine-3d canvas { display: block; width: 100% !important; height: 100% !important; }
/* The canvas is only ever painted by the scroll driver, so in the static layout
   it would be an empty beige box. The poster takes its place there instead. */
.cine-video { display: none; }
.cine-motion .cine-video { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; display: block; background: var(--paper); }

.cine-reduced-poster { display: block; width: min(620px, 100%); height: auto; margin: 4px auto 8px; }
.cine-motion .cine-reduced-poster { display: none; }

/* Static default: each beat is an ordinary stacked section. The hero clears the
   66px fixed nav, which in cinematic mode the 92px stage padding handled. */
.beat { position: relative; display: flex; flex-direction: column; align-items: center; gap: 26px; padding: 52px 24px; z-index: 3; }
.beat-hero { padding-top: 100px; }
.beat > * { pointer-events: auto; }
/* The gap is load-bearing: .beat-outro h2 has no bottom margin, so before this
   the CTA's top edge sat exactly on the headline's box bottom (measured 0px) and
   the descenders in "Poznaj pełną ofertę." rendered into the black button. */
.cine-motion .beat { position: absolute; inset: 0; gap: 0; padding: 96px 24px 84px; pointer-events: none; will-change: transform, opacity; }
.cine-motion .beat-hero { justify-content: space-between; padding-top: 92px; padding-bottom: 76px; }
.beat-hero .bh-top, .beat-hero .bh-bottom, .beat-outro .bh-top, .beat-outro .bh-bottom { display: flex; flex-direction: column; align-items: center; width: 100%; }
.beat-hero .label { margin-top: 8px; }
.beat-hero h1 {
  font-family: var(--f-display); font-size: clamp(34px, 6.4vw, 68px); font-weight: 400; letter-spacing: -0.03em;
  line-height: 1.03; max-width: 16ch; margin: 18px auto 0; text-align: center; text-wrap: balance; color: var(--ink);
}
.beat-hero .hero-sub { font-size: clamp(15px, 2.3vw, 18px); line-height: 1.6; color: var(--gray); max-width: 440px; margin: 16px auto 0; text-align: center; text-wrap: pretty; }
.beat-hero .hero-ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 22px; }

/* Short viewports: compress hero text so the top/bottom clusters clear the car.
   Only relevant in cinematic mode — the static layout is not height-constrained. */
@media (max-height: 720px) {
  .cine-motion .beat-hero, .cine-motion .beat-outro { padding-top: 76px; padding-bottom: 38px; }
  .beat-hero .label, .beat-outro .label { margin-top: 2px; }
  .beat-hero h1 { font-size: clamp(28px, 4.4vw, 42px); margin-top: 12px; }
  .beat-hero .hero-sub { font-size: 13px; line-height: 1.5; margin-top: 10px; max-width: 400px; }
  .beat-hero .hero-ctas { margin-top: 14px; }
  .beat-outro h2 { font-size: clamp(26px, 4.4vw, 40px); margin-top: 10px; }
}

.beat-stats { justify-content: space-between; }
.beat-stats .beat-cap { font-family: var(--f-display); font-size: clamp(24px, 4vw, 40px); font-weight: 400; letter-spacing: -0.02em; color: var(--ink); text-align: center; max-width: 14ch; }
.beat-stats .trust { width: 100%; max-width: 940px; }

.beat-claim { justify-content: center; }
.beat-claim p { font-family: var(--f-display); font-size: clamp(28px, 5.6vw, 60px); font-weight: 300; letter-spacing: -0.025em; line-height: 1.1; max-width: 18ch; text-align: center; color: var(--ink); text-wrap: balance; }
.beat-claim p strong { font-weight: 500; }

.beat-cta { justify-content: flex-end; }
.beat-cta .label { color: var(--gray-soft); }
.beat-cta h2 { font-family: var(--f-display); font-size: clamp(26px, 5vw, 46px); font-weight: 400; letter-spacing: -0.025em; line-height: 1.1; max-width: 16ch; text-align: center; margin: 16px auto 26px; color: var(--ink); text-wrap: balance; }

/* outro — cluster text at top, CTA at bottom so the car lineup stays clear */
.cine-motion .beat-outro { justify-content: space-between; padding-top: 92px; padding-bottom: 76px; }
.beat-outro .label { margin-top: 8px; }
.beat-outro h2 { font-family: var(--f-display); font-size: clamp(28px, 5.6vw, 56px); font-weight: 400; letter-spacing: -0.025em; line-height: 1.08; max-width: 14ch; text-align: center; margin: 14px auto 0; color: var(--ink); text-wrap: balance; }

/* ── Technical annotation overlay ──
   Static default: the leader lines and dots point at a car that isn't there, so
   they're dropped and the five figures become a plain stat grid. */
.cine-annot {
  position: relative; z-index: 4; opacity: 1;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px 18px;
  max-width: 680px; margin: 0 auto; padding: 8px 24px 56px;
}
.cine-annot > svg, .cine-annot .annot-dot { display: none; }
/* Five figures in two columns leaves the fifth alone in column 1, reading as a
   dangling orphan. Span it so it centres under the other four. */
.cine-annot .annot-label:nth-of-type(5) { grid-column: 1 / -1; }
/* Anchored to the drawn car band, not the stage.
   The dots, leader lines and labels inside this layer are positioned in
   percentages authored against the FRAME. While the frame was cover-filled the
   frame and the stage were the same rectangle and `inset: 0` was correct; now
   that the frame is a centred band (see MAX_UPSCALE in CinematicHero.astro) the
   overlay has to take that band as its containing block or every label points at
   bare paper. --car-* are published each draw by publishRect(); the fallbacks
   reproduce `inset: 0` for the frames before the first draw lands. */
.cine-motion .cine-annot {
  position: absolute;
  left: var(--car-x, 0px);
  top: var(--car-y, 0px);
  width: var(--car-w, 100%);
  height: var(--car-h, 100%);
  display: block; max-width: none; margin: 0; padding: 0;
  pointer-events: none; opacity: 0; will-change: opacity, transform;
}
.cine-motion .cine-annot > svg { display: block; }
.cine-motion .cine-annot .annot-dot { display: block; }
.cine-annot svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.cine-annot svg line.lead { stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0.45; }
.cine-annot svg line.rule { stroke: var(--ink); stroke-width: 1.5; vector-effect: non-scaling-stroke; opacity: 0.9; }
.annot-dot { position: absolute; width: 7px; height: 7px; border-radius: 50%; background: var(--ink); transform: translate(-50%, -50%); box-shadow: 0 0 0 4px color-mix(in srgb, var(--paper) 70%, transparent); }
.annot-label { position: static; transform: none; text-align: center; white-space: normal; padding-bottom: 0; max-width: none; }
.cine-motion .annot-label { position: absolute; transform: translate(-50%, -100%); white-space: nowrap; padding-bottom: 9px; }
.annot-label .al-v { display: block; font-family: var(--f-display); font-size: clamp(18px, 2.6vw, 30px); font-weight: 400; letter-spacing: -0.02em; color: var(--ink); line-height: 1; }
.annot-label .al-k { display: block; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gray); margin-top: 7px; }
.annot-title { position: static; transform: none; text-align: center; grid-column: 1 / -1; order: -1; }
.cine-motion .annot-title {
  position: absolute; left: 50%; bottom: 8%; transform: translateX(-50%);
  /* The outer labels are authored at left:13% and left:87% and are centred on
     those points, so each occupies roughly a quarter of the band. The title is
     centred at 50% with no width limit, so as soon as it wraps it grows sideways
     INTO them: below 1440px its first line ran under "100% / AUT Z GWARANCJĄ
     PRODUCENTA" and across that label's leader line.
     Capping the box at 46% of the band keeps it inside the corridor between the
     two outer columns at every width. It is wider than the one-line title needs
     at >=1440px, so the large-screen layout is unchanged; below that the title
     simply wraps a line earlier and grows upward into the empty space under the
     car instead of sideways into the labels. */
  max-width: 46%;
}
/* Between the phone fallback (<=760px) and 1280px the overlay still works, but the
   title wraps to three lines at the body size used on wide screens and then grows
   UPWARD into the bottom-right label instead of sideways. Shrinking the type and
   dropping the block closer to the floor keeps it clear without giving up the
   leader lines on small laptops. */
@media (min-width: 761px) and (max-width: 1279px) {
  .cine-motion .annot-title { bottom: 2%; max-width: 34%; }
  .cine-motion .annot-title p { font-size: 15px; line-height: 1.3; margin-top: 6px; }
}
.annot-title p { font-family: var(--f-display); font-size: clamp(15px, 2vw, 19px); font-weight: 400; color: var(--ink); margin-top: 8px; }
/* Phones: the leader-line overlay does not survive here, so it is retired rather
   than patched.
   Two reasons. The labels sit at left:10%/87%/92% with `white-space: nowrap`,
   which defeats the `max-width` that was supposed to contain them — three of the
   five ran off the screen edge ("...JE WYJŚCIA Z UMOWY", "SPRAWDZEŃ BIK /").
   And the dots are pinned to percentages authored against the desktop
   cover-fill framing, so once the portrait crop moves the car they point at bare
   floor. Chasing the crop with the dots would mean re-authoring five positions
   per beat against a scale that changes with scroll.
   So on narrow screens the five figures become a legible stat grid instead:
   heading at the top, figures below the car. Same numbers, no false precision. */
@media (max-width: 760px) {
  /* Annotation beat on phones — same band structure as the four-step beat.
     Previously this used align-content: space-between, which spread the rows over
     the full height and dropped four of the five figures onto the car (measured:
     frame occupied y 248–708, figures sat at 321–354 and 543–576). Rows are now
     explicit, with a 1fr middle that narrowFill() keeps the car inside:
       row 1  heading
       row 2  two figures
       row 3  1fr — the car
       row 4  two figures
       row 5  the fifth figure, spanning and centred */
  .cine-motion .cine-annot {
    display: grid; grid-template-columns: 1fr 1fr;
    /* Same structure as the four-step beat: equal 1fr rows flank the car band so
       it centres exactly, and rows 2 and 4 each hold one row of figures so they
       balance. The heading sits at the bottom of row 1, the fifth figure at the
       top of row 5 — both hugging inward rather than pinned to the screen. */
    grid-template-rows: 1fr auto var(--cine-band) auto 1fr;
    gap: 12px;
    padding: 56px 18px;
  }
  .cine-motion .cine-annot > svg,
  .cine-motion .cine-annot .annot-dot { display: none; }
  .cine-motion .annot-label {
    position: static; transform: none; white-space: normal;
    max-width: none; padding-bottom: 0; text-align: center;
  }
  .cine-motion .annot-label:nth-of-type(1) { grid-column: 1; grid-row: 2; align-self: end; }
  .cine-motion .annot-label:nth-of-type(2) { grid-column: 2; grid-row: 2; align-self: end; }
  .cine-motion .annot-label:nth-of-type(3) { grid-column: 1; grid-row: 4; align-self: start; }
  .cine-motion .annot-label:nth-of-type(4) { grid-column: 2; grid-row: 4; align-self: start; }
  .cine-motion .annot-label:nth-of-type(5) { grid-column: 1 / -1; grid-row: 5; align-self: start; }
  .cine-motion .annot-title {
    position: static; transform: none; left: auto; bottom: auto;
    grid-column: 1 / -1; grid-row: 1; align-self: end;
  }
  .cine-motion .annot-label .al-v { font-size: 17px; }
  .cine-motion .annot-label .al-k { font-size: 8.5px; letter-spacing: 0.1em; margin-top: 5px; }

  /* Outro on phones: the headline and CTA hug the car band instead of floating.
     narrowFill() returns exactly 0 for the lineup, i.e. fit by width, so the
     drawn band is exactly `100vw * 9 / 16` tall and centred in the canvas. Naming
     the same value as the middle row — between two equal 1fr rows, with SYMMETRIC
     vertical padding so the content box centre coincides with the viewport
     centre — puts that row precisely over the band. Measured before: 187px of
     dead space above the cars and 221px below.
     If narrowFill's lineup value stops being 0, this must change with it. */
  .cine-motion .beat-outro {
    display: grid;
    /* Explicit full-width column. `.beat` sets align-items:center for its flex
       layout; switching to grid leaves the implicit column content-sized, which
       left-aligned the headline and the CTA against the padding edge. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 1fr calc(100vw * 9 / 16) 1fr;
    justify-items: stretch;
    padding: 70px 24px;
  }
  .cine-motion .beat-outro .bh-top    { grid-row: 1; align-self: end;   padding-bottom: 20px; }
  .cine-motion .beat-outro .bh-bottom { grid-row: 3; align-self: start; padding-top: 20px; }
}

/* ── Flanking overlays (testimonials / steps) ──
   Static default: the cards stop flanking a car and become a plain responsive
   grid, so this content stays readable when the sequence never runs. */
.cine-flank {
  position: relative; z-index: 4; opacity: 1;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr));
  gap: 18px; max-width: 900px; margin: 0 auto; padding: 8px 24px 56px;
}
.cine-motion .cine-flank { position: absolute; inset: 0; display: block; max-width: none; margin: 0; padding: 0; pointer-events: none; opacity: 0; will-change: opacity; }

/* testimonials */
.testi {
  position: static; width: auto; pointer-events: auto;
  background: var(--paper); border: 1px solid var(--line-soft); border-radius: var(--radius-lg);
  padding: 20px 22px; box-shadow: 0 22px 50px -18px rgba(17,19,20,0.28);
  transition: transform 0.28s ease, box-shadow 0.28s ease;
}
.cine-motion .testi { position: absolute; width: min(28vw, 290px); }
.testi:hover { transform: translateY(-6px); box-shadow: 0 34px 64px -20px rgba(17,19,20,0.36); }
.testi .stars { font-size: 13px; letter-spacing: 2px; color: var(--ink); }
.testi .t-q { font-size: 14px; line-height: 1.55; color: var(--ink); margin-top: 12px; text-wrap: pretty; }
.testi .t-n { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.06em; color: var(--ink); margin-top: 14px; }
.testi .t-n span { color: var(--gray-soft); text-transform: uppercase; letter-spacing: 0.12em; }
.cine-motion .testi.t1 { left: 4.5%; top: 20%; }
.cine-motion .testi.t2 { left: 4.5%; bottom: 17%; }
.cine-motion .testi.t3 { right: 4.5%; top: 20%; }
.cine-motion .testi.t4 { right: 4.5%; bottom: 17%; }

/* four-step process */
.steps-head { position: static; transform: none; grid-column: 1 / -1; order: -1; text-align: center; }
.cine-motion .steps-head { position: absolute; top: 11%; left: 50%; transform: translateX(-50%); }
.pstep { position: static; width: auto; display: flex; gap: 16px; align-items: flex-start; pointer-events: auto; }
.cine-motion .pstep { position: absolute; width: min(27vw, 280px); }
.pstep .ps-n { font-family: var(--f-mono); font-size: 12px; letter-spacing: 0.1em; color: var(--accent); padding-top: 4px; flex-shrink: 0; }
.pstep .ps-t { font-family: var(--f-display); font-size: clamp(17px, 2.2vw, 21px); font-weight: 400; letter-spacing: -0.01em; color: var(--ink); }
.pstep .ps-b { font-size: 13px; line-height: 1.5; color: var(--gray); margin-top: 6px; }
.cine-motion .pstep.p1 { left: 4.5%; top: 27%; }
.cine-motion .pstep.p2 { left: 4.5%; bottom: 24%; }
.cine-motion .pstep.p3 { right: 4.5%; top: 27%; text-align: right; flex-direction: row-reverse; }
.cine-motion .pstep.p4 { right: 4.5%; bottom: 24%; text-align: right; flex-direction: row-reverse; }

@media (max-width: 760px) {
  /* ── The drawn car band, in CSS ──────────────────────────────────────────────
   * drawCover() scales a 1280x720 frame by
   *     scale = fit + k * (cover - fit),   fit = cw/sw,  cover = ch/sh
   * so the drawn height, converted out of device pixels, is
   *     band = 56.25vw + k * (100vh - 56.25vw)
   * because sh*cw/sw / dpr = 56.25vw and ch/dpr = 100vh (the canvas is 100% of
   * .cine-stage, which is 100vh). dpr cancels. Verified against the live canvas
   * at 440x956: k=0.10 predicts 318.4px, measured 318; k=0.20 predicts 389.2px,
   * measured 390.
   *
   * ⚠ The k values below MUST match narrowFill() in CinematicHero.astro. They are
   * how the text knows where the car is. If you change one, change the other or
   * the overlays drift back onto the bodywork. */
  .cine-motion .cine-stage { --cine-fit-band: calc(100vw * 9 / 16); }
  .cine-motion .flank-steps { --cine-band: calc(var(--cine-fit-band) + 0.10 * (100vh - var(--cine-fit-band))); }
  .cine-motion .cine-annot  { --cine-band: calc(var(--cine-fit-band) + 0.20 * (100vh - var(--cine-fit-band))); }

  .cine-motion .testi { width: 44vw; padding: 14px 15px; }
  .testi .t-q { font-size: 12px; }
  .cine-motion .testi.t1, .cine-motion .testi.t3 { top: 13%; }
  .cine-motion .testi.t2, .cine-motion .testi.t4 { bottom: 11%; }
  .pstep .ps-b { font-size: 11.5px; }

  /* Four-step beat on phones.
     Two fixes here. The steps were absolutely positioned at top/bottom 19%, and
     with the frame filling y 53–903 of a 956px screen all four labels sat on
     bodywork and washed out — they are plain text, not opaque cards like the
     testimonials, so there was nothing to read them against.
     And the order was wrong: p1/p3 shared the top row and p2/p4 the bottom, so
     the numbers read 01 03 / 02 04 down the screen. They now read 01 02 / 03 04.
     The middle row is 1fr — reserved empty space that narrowFill() keeps the car
     inside. Do not give it a fixed height; the band scales with the viewport. */
  .cine-motion .flank-steps {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* The middle row is the CAR, sized to the drawn band — not 1fr. A 1fr row
       swallowed every spare pixel, which pushed the labels out to the screen
       edges and left 79px of dead space above the car and 112px below.
       Equal 1fr rows top and bottom centre the band row, so it lands on the
       drawn band (which drawCover also centres). The heading sits at the BOTTOM
       of row 1 rather than in its own auto row — an auto row would have made the
       group above the car taller than the one below and tilted the whole thing. */
    /* Both label rows share a floor so they come out the same height. Without it
       row 4 measured 81px against row 2's 61px — "Kup / Zwróć / Sprzedaj" wraps to
       two lines — which shifted the band row 10px up and left gaps of 24px above
       the car and only 4px below. If CMS copy ever exceeds this floor the rows go
       unequal again, but the failure is a slight tilt, never an overlap. */
    grid-template-rows: 1fr minmax(88px, auto) var(--cine-band) minmax(88px, auto) 1fr;
    gap: 14px;
    padding: 60px 18px;
  }
  .cine-motion .flank-steps .steps-head {
    position: static; transform: none; top: auto; left: auto;
    grid-column: 1 / -1; grid-row: 1; align-self: end; text-align: center;
  }
  .cine-motion .flank-steps .pstep {
    position: static; width: auto; gap: 10px;
    text-align: left; flex-direction: row;
  }
  /* `end` aligned the two cards by their BOTTOMS, so step 02 — whose body runs
     to two lines — pushed its own number and title a line higher than step 01's.
     Aligning by the top puts the two headings on one baseline, which is what the
     row is read along. Same rule as row 4, which already starts. */
  .cine-motion .flank-steps .pstep.p1 { grid-column: 1; grid-row: 2; align-self: start; }
  .cine-motion .flank-steps .pstep.p2 { grid-column: 2; grid-row: 2; align-self: start; }
  .cine-motion .flank-steps .pstep.p3 { grid-column: 1; grid-row: 4; align-self: start; }
  .cine-motion .flank-steps .pstep.p4 { grid-column: 2; grid-row: 4; align-self: start; }
  /* "Kup / Zwróć / Sprzedaj" is the one title that cannot fit a half-width
     column at 17px — it needs 173px and the column gives ~140 at 390px. It is a
     three-part label, so breaking it mid-list reads as two separate steps.
     Only this one shrinks, and only on the narrow grid; the other three keep
     their size because they already fit. */
  .cine-motion .flank-steps .pstep.p4 .ps-t {
    white-space: nowrap; font-size: clamp(12.5px, 3.6vw, 17px);
  }
}

/* Cinematic mode: only the hero beat is lit before the driver takes over, so a
   driver that never starts leaves one readable screen rather than a pile. */
.cine-motion .beat { opacity: 0; }
.cine-motion .beat-hero { opacity: 1; }
.cine-motion .car-side, .cine-motion .car-rear { opacity: 0; }

/* ── Trust strip ── */
.trust { display: grid; grid-template-columns: repeat(2, 1fr); max-width: 940px; margin: 0 auto; border-top: 1px solid var(--line-soft); }
@media (min-width: 720px) { .trust { grid-template-columns: repeat(4, 1fr); } }
.trust-cell { padding: 38px 16px; text-align: center; border-bottom: 1px solid var(--line-soft); }
@media (min-width: 720px) { .trust-cell { border-bottom: none; border-right: 1px solid var(--line-soft); } .trust-cell:last-child { border-right: none; } }
.trust-cell strong { display: block; font-family: var(--f-display); font-size: clamp(32px, 5vw, 46px); font-weight: 300; letter-spacing: -0.03em; }
.trust-cell small { display: block; font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gray-soft); margin-top: 12px; }

/* ════ Page sections below the hero ════ */
.panel-band { background: var(--panel); }

/* Oferta — photo cards */
.cars { display: grid; grid-template-columns: 1fr; gap: 28px; margin-top: clamp(44px, 7vw, 72px); }
@media (min-width: 760px) { .cars { grid-template-columns: repeat(3, 1fr); gap: 22px; } }
.car { text-decoration: none; color: var(--ink); display: block; }
.car-img {
  height: 210px; position: relative;
  background: repeating-linear-gradient(-45deg, var(--panel) 0 14px, color-mix(in srgb, var(--panel) 55%, var(--silver)) 14px 28px);
  display: flex; align-items: center; justify-content: center; border: 1px solid var(--line-soft);
  transition: opacity 0.2s;
}
.car:hover .car-img { opacity: 0.86; }
.car-ph { font-family: var(--f-mono); font-size: 10px; color: var(--gray-soft); border: 1px dashed var(--line); padding: 8px 12px; background: color-mix(in srgb, var(--paper) 70%, transparent); }
.car-tag { position: absolute; top: 0; left: 0; font-size: 10px; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; background: var(--ink); color: var(--paper); padding: 7px 12px; }
.car-body { padding: 20px 2px 0; }
.car-name { font-family: var(--f-display); font-size: 19px; font-weight: 500; letter-spacing: -0.01em; }
/* The spec line now also carries the mileage, so it is longer than the design
   oracle's. It must stay on ONE line under the title: these are scan-and-compare
   tiles, and a second line pushes the price row out of alignment across a row of
   cards. Tracking is tightened and the size scales with the viewport so the long
   strings ("FURGON MAXI L4H2 · DIESEL · 180 KM · AUTOMAT · 117 046 KM") fit the
   narrowest card; `nowrap` is what guarantees the one-line rule, and the ellipsis
   is the safety valve for a spec line longer than any car currently has. */
.car-spec {
  /* Sized against the CARD, not the viewport (`cqi` = 1% of the card's inline
     size). Viewport units were wrong here: the catalogue's filter rail makes a
     card ~320px at 1280-1600px wide, narrower than a card on the 1-column phone
     layout, so a viewport-based clamp sized the text largest exactly where the
     box was smallest. The card declares the container in samochody.astro. */
  font-size: clamp(8.5px, 3.05cqi, 11px);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--gray-soft);
  margin-top: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The spec line is uppercased, which in Polish makes the mileage unit identical
   to the power unit: "197 KM · 117 706 KM" reads as two power figures, when the
   first is 197 hp and the second is 117 706 kilometres. Keeping the distance
   lowercase ("197 KM · 117 706 km") is the only thing separating them. */
.car-spec .car-km { text-transform: none; letter-spacing: 0.04em; }
.car-prices { display: flex; gap: 28px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.cp small { display: block; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--gray-soft); }
.cp strong { font-size: 16px; font-weight: 500; letter-spacing: -0.01em; }

.cars-more { text-align: center; margin-top: 52px; }

/* Kalkulator */
.calc { max-width: 640px; margin: clamp(44px, 7vw, 64px) auto 0; background: var(--paper); padding: clamp(28px, 5vw, 48px); border: 1px solid var(--line-soft); }
.calc-label { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gray-soft); }
.calc-row { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-top: 24px; }
.calc-val { font-family: var(--f-display); font-size: clamp(26px, 5vw, 34px); font-weight: 400; letter-spacing: -0.02em; }
.calc-val i { font-style: normal; font-size: 14px; color: var(--gray-soft); }
.calc-cap { text-align: right; }
.calc-cap small { display: block; font-family: var(--f-mono); font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gray-soft); }
.calc-cap span { font-family: var(--f-mono); font-size: 16px; color: var(--gray); }
input[type="range"].slider { width: 100%; appearance: none; -webkit-appearance: none; height: 1px; background: var(--line); outline: none; cursor: pointer; margin: 28px 0 8px; }
input[type="range"].slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 22px; height: 22px; border-radius: 50%; background: var(--ink); border: none; }
input[type="range"].slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--ink); border: none; }
.calc-range { display: flex; justify-content: space-between; font-family: var(--f-mono); font-size: 9px; color: var(--gray-soft); }
.calc-out { margin-top: 30px; background: var(--ink); color: var(--paper); padding: clamp(26px, 4vw, 38px) 24px; text-align: center; }
.calc-out .calc-label { color: rgba(255,255,255,0.46); }
.calc-big { font-family: var(--f-display); font-size: clamp(46px, 9vw, 66px); font-weight: 300; letter-spacing: -0.03em; line-height: 1; margin-top: 12px; color: var(--paper); }
/* The unit beside the big figure.

   `letter-spacing` MUST be reset here. `.calc-big` sets -0.03em, which resolves
   against ITS OWN 66px font-size to -1.98px and then inherits as that absolute
   length — not as -0.03em of the child's 15px. A space in Instrument Sans at
   15px is ~3px wide, so it came out 1.03px and the unit rendered as
   "PLNnetto/mies." with the words run together. Measured, not guessed. */
.calc-big i { font-style: normal; font-size: 15px; letter-spacing: normal; margin-left: 4px; color: rgba(255,255,255,0.5); }

/* Net/gross switch for the WHOLE widget — it sits above the inputs, on the
   paper background, so it takes the catalogue's `.seg` colours rather than the
   inverted ones it had while it lived on the dark result tile. */
.calc-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 2px; overflow: hidden; }
.calc-seg--top { margin-bottom: 18px; }
.calc-seg button { appearance: none; min-width: 84px; height: 32px; padding: 0 16px; border: none; background: transparent; font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--gray); cursor: pointer; }
.calc-seg button + button { border-left: 1px solid var(--line); }
.calc-seg button:hover { color: var(--ink); }
.calc-seg button.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.calc-seg button:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

/* Marks the split row as net while the headline shows gross — the two halves
   are only defined in net (see the note in CalculatorIsland). */
.calc-split-net { color: rgba(255,255,255,0.38); }
.calc-split { display: flex; justify-content: center; gap: 8px 24px; flex-wrap: wrap; margin-top: 20px; padding-top: 18px; border-top: 1px solid rgba(255,255,255,0.14); font-family: var(--f-mono); font-size: 11px; color: rgba(255,255,255,0.5); }
.calc-cta { display: flex; margin-top: 28px; }
.calc-cta .btn-solid { width: 100%; }

/* Home calculator CTAs.
   These used to carry inline `flex:1 1 0; min-width:220px` / `min-width:160px`.
   220 + 160 + 12px gap = 392px — which is EXACTLY the container width at a 440px
   viewport (iPhone 16 Pro Max), so the pair squeezed onto one row at precisely
   that size and "Otwórz szczegółowy kalkulator" wrapped to three cramped lines.
   Narrower phones wrapped and looked fine, which is why 375/393 testing missed
   it. Stack until there is genuinely room to read both labels. */
.calc-cta-home { display: flex; gap: 12px; flex-wrap: wrap; max-width: 560px; margin: 0 auto; }
.calc-cta-home > a { flex: 1 1 100%; width: auto; }
@media (min-width: 620px) {
  .calc-cta-home > a { flex: 1 1 0; }
  .calc-cta-home .btn-solid { min-width: 260px; }
  .calc-cta-home .btn-out { min-width: 190px; }
}
.calc-note { font-family: var(--f-mono); font-size: 10px; color: var(--gray-soft); margin-top: 14px; text-align: center; }
.calc-example { max-width: 640px; margin: 20px auto 0; font-size: 13.5px; line-height: 1.7; color: var(--gray); text-align: center; padding: 0 8px; }
.calc-example strong { color: var(--ink); font-weight: 500; }

/* Opcje wyjścia */
/* Single column (mobile) draws a rule BETWEEN cards only. The grid's own
   border-top duplicated the section rule sitting right above it, and the last
   card's border-bottom duplicated the one right below — two hairlines a couple
   of pixels apart, twice per section. Restored at 760px, where the top rule is
   the only thing closing the three columns. */
.exits { display: grid; grid-template-columns: 1fr; margin-top: clamp(44px, 7vw, 72px); }
@media (min-width: 760px) { .exits { border-top: 1px solid var(--line-soft); } }
.exits > .exit:last-child { border-bottom: none; }
@media (min-width: 760px) { .exits { grid-template-columns: repeat(3, 1fr); } }
.exit { padding: 36px 28px 40px 0; border-bottom: 1px solid var(--line-soft); text-align: left; }
@media (min-width: 760px) { .exit { border-bottom: none; padding-right: 36px; } .exit + .exit { border-left: 1px solid var(--line-soft); padding-left: 36px; } }
.exit-n { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.18em; color: var(--accent); }
.exit-t { font-family: var(--f-display); font-size: 24px; font-weight: 400; letter-spacing: -0.015em; margin-top: 12px; }
.exit-b { font-size: 14px; line-height: 1.65; color: var(--gray); margin-top: 10px; max-width: 320px; }
.exit ul { list-style: none; margin-top: 18px; display: flex; flex-direction: column; gap: 8px; }
.exit ul li { font-size: 13px; color: var(--gray); line-height: 1.5; padding-left: 18px; position: relative; }
.exit ul li::before { content: '—'; position: absolute; left: 0; color: var(--gray-soft); }

/* Porównanie */
.compare-scroll { overflow-x: auto; margin-top: clamp(44px, 7vw, 64px); -webkit-overflow-scrolling: touch; }
.compare { width: 100%; min-width: 640px; border-collapse: collapse; }
.compare th, .compare td { padding: 16px 16px; font-size: 14px; text-align: left; border-bottom: 1px solid var(--line-soft); }
.compare thead th { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gray-soft); font-weight: 500; }
.compare td:first-child { font-weight: 500; }
.compare .ac { font-weight: 600; border-left: 1px solid var(--ink); border-right: 1px solid var(--ink); }
.compare thead .ac { border-top: 1px solid var(--ink); color: var(--ink); }
.compare tbody tr:last-child .ac { border-bottom: 1px solid var(--ink); }
.compare .no { color: var(--gray-soft); }

/* FAQ */
/* The accordion is a direct child of `.section` with no `.wrap` around it, so
   it ran edge to edge on a phone. The gutter is added to the padding AND to the
   max-width together, so the content box stays exactly 760px on desktop — the
   oracle's width — while a narrow screen finally gets its margins. */
.faq { max-width: calc(760px + 2 * var(--gutter)); padding-inline: var(--gutter); margin: clamp(44px, 7vw, 64px) auto 0; border-top: 1px solid var(--line-soft); }
.faq details { border-bottom: 1px solid var(--line-soft); }
.faq summary { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 26px 4px; cursor: pointer; list-style: none; font-size: 17px; font-weight: 500; letter-spacing: -0.01em; text-align: left; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; font-size: 20px; font-weight: 300; color: var(--gray-soft); flex-shrink: 0; transition: transform 0.25s ease; }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq-a { padding: 0 4px 28px; font-size: 14.5px; line-height: 1.75; color: var(--gray); max-width: 640px; text-align: left; }
.faq-a strong { color: var(--ink); font-weight: 500; }

/* Ambasadorzy — ink panel */
.amb { background: var(--ink); color: var(--paper); max-width: 1060px; margin: 0 auto; padding: clamp(56px, 9vw, 104px) 24px; text-align: center; }
.amb .label { color: rgba(255,255,255,0.45); }
.amb h2 { font-family: var(--f-display); font-size: clamp(28px, 5.4vw, 50px); font-weight: 400; letter-spacing: -0.025em; line-height: 1.08; margin-top: 18px; text-wrap: balance; }
.amb p.lead { font-size: 15px; line-height: 1.7; color: rgba(255,255,255,0.66); max-width: 460px; margin: 18px auto 0; }
.amb-num { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255,255,255,0.45); margin-top: 30px; }
.amb-num strong { display: block; font-family: var(--f-display); font-size: clamp(28px, 5vw, 40px); font-weight: 300; letter-spacing: -0.02em; color: var(--paper); margin-top: 8px; text-transform: none; }
.amb-ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 36px; }
.btn-paper { display: inline-flex; align-items: center; justify-content: center; min-height: 54px; padding: 0 32px; background: var(--paper); color: var(--ink); border: 1px solid var(--paper); border-radius: var(--radius); font-size: 12px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none; cursor: pointer; transition: opacity 0.18s; }
.btn-paper:hover { opacity: 0.84; }
.btn-ghost-d { display: inline-flex; align-items: center; justify-content: center; min-height: 54px; padding: 0 30px; background: transparent; color: rgba(255,255,255,0.85); border: 1px solid rgba(255,255,255,0.28); border-radius: var(--radius); font-size: 12px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none; cursor: pointer; transition: border-color 0.18s; }
.btn-ghost-d:hover { border-color: rgba(255,255,255,0.7); }

/* Footer */
.site-footer { padding: clamp(64px, 10vw, 110px) 24px 48px; text-align: center; }
.site-footer .logo { justify-content: center; }
.footer-by { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--gray-soft); margin-top: 14px; }
.footer-tag { font-size: 15px; color: var(--gray); margin-top: 20px; }
.footer-links { display: flex; flex-wrap: wrap; gap: 12px 30px; justify-content: center; margin-top: 36px; list-style: none; padding: 0; }
.footer-links a { font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gray); text-decoration: none; }
.footer-links a:hover { color: var(--ink); }
.footer-fine { font-family: var(--f-mono); font-size: 10px; color: var(--gray-soft); margin-top: 44px; }

/* Kalkulator — typed inputs (shared homepage + subpage) */
.calc-inputs { display: grid; grid-template-columns: 1fr; gap: 18px; }
@media (min-width: 540px) { .calc-inputs { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.calc-input { min-width: 0; }
.calc-input label { display: block; font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gray-soft); margin-bottom: 9px; }
.calc-input-wrap { display: flex; align-items: baseline; gap: 8px; border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 2px 16px; transition: border-color 0.18s, background 0.18s; background: var(--panel); }
.calc-input-wrap:focus-within { border-color: var(--ink); background: var(--paper); }
.calc-input-wrap input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: var(--f-display); font-size: clamp(22px, 4vw, 30px); font-weight: 400; letter-spacing: -0.02em; color: var(--ink); padding: 13px 0; }
.calc-input-wrap .calc-unit { font-family: var(--f-mono); font-size: 12px; color: var(--gray-soft); flex-shrink: 0; }
.calc-cap-row { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line-soft); }
.calc-cap-row > span:first-child { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gray-soft); }
/* Sits under the capital row in net mode: the formula consumes the GROSS
   capital, so the figure above cannot be divided by 120 to reach the split. */
.calc-cap-note { font-family: var(--f-mono); font-size: 10px; color: var(--gray-soft); margin-top: 6px; text-align: right; }
.calc-cap-row > span:last-child { font-family: var(--f-mono); font-size: 15px; color: var(--gray); }
.calc-netto { font-family: var(--f-mono); font-size: 12px; color: rgba(255,255,255,0.55); margin-top: 12px; }
.calc-netto span { color: var(--paper); }
/* The amount and its unit travel together; the prefix may wrap above them. */
.calc-netto .calc-netto-amt { white-space: nowrap; color: rgba(255,255,255,0.55); }

/* ── Version switcher ── */
.switcher {
  position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 60;
  display: flex; gap: 4px; padding: 4px; border-radius: var(--radius-lg);
  background: rgba(17,19,20,0.9); backdrop-filter: blur(10px); box-shadow: 0 8px 32px rgba(17,19,20,0.25);
}
.switcher a { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.06em; color: rgba(255,255,255,0.6); text-decoration: none; padding: 8px 13px; border-radius: var(--radius); white-space: nowrap; }
.switcher a.on { background: rgba(255,255,255,0.16); color: #fff; }
.switcher a:hover { color: #fff; }

/* ══ Finansowanie (formy płatności) ══ */
/* Four ways to pay, rendered as four objects rather than one ruled block. This
   was a "hairline table": a 1px grid gap with the grid's own background showing
   through it, so the four options read as rows of a table and the featured card's
   panel fill looked like a shaded row rather than a highlight. A real gap plus a
   per-card border separates them. Gap uses the exact spacing scale. */
/* The grid used to butt straight up against the lead paragraph. It needs real
   separation anyway, and the badge straddling the featured card's top edge rises
   ~11px above it — at tablet and mobile the lead is wide enough to run under that
   badge, so without this margin the two collided. */
.fin-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-3); margin-top: var(--space-8); }
@media (min-width: 620px) { .fin-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .fin-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-4); } }
/* --line, not --line-soft: the cards sit on --paper and are themselves --paper, so
   once the shared grid background is gone the border is the only thing defining
   them. At 7% it disappeared; 13% is the same weight the rest of the site uses. */
.fin-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: clamp(24px, 3vw, 34px) clamp(20px, 2.4vw, 28px); display: flex; flex-direction: column; position: relative; min-height: 196px; }
.fin-card.feature { background: var(--panel); }
/* The badge straddles the card's top edge instead of sitting inside it. Two earlier
   placements both broke alignment: absolutely positioned at top:15px it floated above
   the kicker on a baseline of its own, and laid out beside the kicker it did not fit
   — the card's inner width is ~215px at the 1180px wrap and kicker + badge need ~290px,
   so "AUTORSKI MODEL" wrapped to two lines and pushed "Buy&Rent" below the other three
   titles. Out of flow and on the border, it costs the content no width at all, so all
   four kickers and all four titles stay on one line. */
.fin-flag { position: absolute; top: 0; right: clamp(20px, 2.4vw, 28px); transform: translateY(-50%); font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--paper); background: var(--ink); padding: 5px 9px; border-radius: var(--radius); }
.fin-k { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gray-soft); }
/* The lead is centred over four lines, where `text-wrap: pretty` (inherited from
   .sub) only protects the last line and left a lopsided rag. `balance` evens the
   measure across all four. */
.fin-lead { text-wrap: balance; }
.fin-t { font-family: var(--f-display); font-size: clamp(21px, 2.3vw, 26px); font-weight: 400; letter-spacing: -0.02em; color: var(--ink); margin-top: 9px; }
.fin-b { font-size: 13.5px; line-height: 1.62; color: var(--gray); margin-top: 12px; }
.fin-btn { display: inline-flex; align-items: center; gap: 8px; align-self: flex-start; margin-top: 18px; height: 40px; padding: 0 18px; border: 1px solid var(--ink); border-radius: var(--radius); font-family: var(--f-body); font-size: 13px; font-weight: 500; color: var(--ink); text-decoration: none; transition: background 0.16s ease, color 0.16s ease; }
.fin-btn:hover { background: var(--ink); color: var(--paper); }

/* ══ Blog — pinned horizontal scroll (strona główna) ══ */
.blog-pin { position: relative; }
.blog-sticky { padding: clamp(48px, 8vh, 88px) 0; }
.blog-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px 28px; flex-wrap: wrap; text-align: left; }
.blog-head .label { text-align: left; }
.blog-head-cta { flex-shrink: 0; }
.blog-track-wrap { margin-top: clamp(26px, 4vh, 40px); overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.blog-track-wrap::-webkit-scrollbar { display: none; }
.blog-track { display: flex; gap: 20px; width: max-content; padding: 4px max(24px, calc((100vw - 1240px) / 2)) 10px; }
/* Vertical scroll drives horizontal travel through the articles.
   This used to be gated at `min-width: 900px`, so phones fell back to a native
   sideways swipe — an affordance that is easy to miss, and which had no visual
   hint. The owner asked for the desktop behaviour on mobile too, so the width
   gate is gone; only reduced-motion still opts out, and that fallback is the
   swipe rail, which stays fully usable.
   The JS media query in index.astro MUST match this one — it is what sets the
   section height that the travel is mapped onto. */
@media (prefers-reduced-motion: no-preference) {
  .blog-pin.js-pin .blog-sticky {
    position: sticky; top: 0; height: 100vh; box-sizing: border-box;
    display: flex; flex-direction: column; justify-content: center; gap: clamp(22px, 4vh, 44px);
    overflow: hidden; padding: 0;
  }
  .blog-pin.js-pin .blog-track-wrap { overflow: visible; margin-top: 0; }
  .blog-pin.js-pin .blog-track { will-change: transform; }
  /* On phones the pinned viewport is short and the section head eats into it,
     so the head sits tighter and the cards keep their full height. */
  @media (max-width: 760px) {
    .blog-pin.js-pin .blog-sticky { gap: 18px; }
    .blog-pin.js-pin .blog-head { flex-direction: column; align-items: flex-start; gap: 12px; }
    .blog-pin.js-pin .blog-head-cta { display: none; }
  }
}
/* An explicit `width` — not just a flex-basis — because `.blog-track` is sized
   `width: max-content`. A flex item's max-content CONTRIBUTION comes from its
   content unless its width is definite, so with only a basis the track sized
   itself to the cards' unwrapped title+excerpt (~790px each) while the cards
   still rendered at the basis. That left the rail scrollable far past the last
   card: 3763px of empty space on a 440px viewport, 3431px at 1440px. A definite
   width makes the contribution the width, so the track measures its cards. */
.blog-card { flex: 0 0 auto; width: clamp(266px, 30vw, 328px); display: flex; flex-direction: column; text-decoration: none; border: 1px solid var(--line-soft); background: var(--paper); transition: border-color 0.18s ease, transform 0.18s ease; }
.blog-card:hover { border-color: var(--silver); transform: translateY(-3px); }
.bc-thumb { position: relative; aspect-ratio: 3 / 2; background: var(--panel); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.bc-thumb .bc-ph { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gray-soft); }
.bc-cat { position: absolute; top: 12px; left: 12px; font-family: var(--f-mono); font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink); background: color-mix(in srgb, var(--paper) 82%, transparent); backdrop-filter: blur(4px); padding: 5px 9px; }
.bc-body { padding: 20px 20px 22px; display: flex; flex-direction: column; flex: 1; }
.bc-meta { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gray-soft); }
.bc-title { font-family: var(--f-display); font-size: 19px; font-weight: 400; letter-spacing: -0.02em; line-height: 1.25; color: var(--ink); margin-top: 12px; text-wrap: balance; }
.bc-ex { font-size: 13.5px; line-height: 1.6; color: var(--gray); margin-top: 10px; flex: 1; }
.bc-read { font-family: var(--f-mono); font-size: 11px; letter-spacing: 0.06em; color: var(--ink); margin-top: 18px; }
.blog-card:hover .bc-read { text-decoration: underline; }
/* Definite width for the same reason as .blog-card above. */
.blog-all { flex: 0 0 auto; width: clamp(196px, 20vw, 232px); flex-direction: column; align-items: center; justify-content: center; gap: 16px; text-align: center; background: var(--panel); }
.blog-all span:last-child { font-family: var(--f-display); font-size: 18px; color: var(--ink); max-width: 12ch; line-height: 1.2; }
.blog-all-arw { display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; border: 1px solid var(--ink); border-radius: 50%; font-size: 17px; color: var(--ink); }
.blog-all:hover { border-color: var(--silver); transform: translateY(-3px); }

/* ── Consent banner ──────────────────────────────────────────────────────────
 * Hidden unless the inline script in CookieConsent.astro marks the visitor as
 * undecided. Driving it from an attribute set BEFORE paint means someone who
 * already chose never sees it flash; driving it from CSS rather than JS means it
 * cannot appear at all when scripting is off, which is correct — no script can
 * run, so there is nothing to consent to.
 *
 * The two buttons are deliberately the same size, weight and hit area. Only the
 * fill differs, and decline is placed FIRST. Making refusal visually harder than
 * acceptance is the single most common way these banners fail GDPR. */
.cc { display: none; }
html[data-consent="unset"] .cc {
  display: block;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  background: var(--paper);
  border-top: 1px solid var(--line);
  box-shadow: 0 -18px 44px -24px rgba(17, 19, 20, 0.3);
}
.cc-inner {
  max-width: 1180px; margin: 0 auto; padding: 18px 24px calc(18px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 18px 28px; flex-wrap: wrap;
}
.cc-copy { flex: 1 1 320px; min-width: 0; }
.cc-title { font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gray-soft); }
.cc-body { font-size: 13px; line-height: 1.55; color: var(--gray); margin-top: 7px; text-wrap: pretty; }
.cc-body a { color: var(--ink); text-underline-offset: 3px; }
.cc-actions { display: flex; gap: 10px; flex: 0 0 auto; }
.cc-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 0 22px; cursor: pointer;
  font-family: var(--f-body); font-size: 12px; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  background: transparent; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: border-color 0.18s ease, opacity 0.18s ease;
}
.cc-btn:hover { border-color: var(--ink); }
.cc-btn--solid { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.cc-btn--solid:hover { opacity: 0.84; border-color: var(--ink); }
.cc-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

@media (max-width: 620px) {
  .cc-inner { padding: 16px 20px calc(16px + env(safe-area-inset-bottom, 0px)); gap: 14px; }
  .cc-actions { width: 100%; }
  .cc-btn { flex: 1 1 0; padding: 0 12px; }
}

/* Footer control that re-opens the banner. Rendered as a button, not a link,
   because it performs an action rather than navigating. */
.footer-consent {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: inherit; color: inherit;
  text-decoration: underline; text-underline-offset: 3px;
}

/* No JS → no scripts to consent to → nothing to withdraw, so hide the control
   rather than offering one that cannot work. */
.footer-consent-item { display: none; }
html[data-consent] .footer-consent-item { display: revert; }
