/* ==========================================================================
   TOKENY — LP „Okna PIXEL −25%" (09/2026)
   Jedyne miejsce, w którym żyją wartości designu. Nigdzie indziej nie
   hardkodujemy kolorów, odstępów ani rozmiarów czcionek.

   Kolory nazwane tak jak zmienne w Figmie (deep-mint, energy-mint, …), żeby
   przy kolejnych sekcjach nie trzeba było niczego tłumaczyć w głowie.
   Wartości oznaczone [FIGMA?] wciąż pochodzą z odczytu makiety — do
   potwierdzenia, gdy dana sekcja trafi do implementacji.
   ========================================================================== */

:root {
  /* ---------- Kolory: paleta kampanii (Figma: get_variable_defs) ---------- */
  --k-deep-mint: #107567;         /* tło hero, tekst na jasnych przyciskach */
  --k-energy-mint: #10a994;       /* akcja główna, ikony */
  --k-power-mint: #39ffe4;        /* badge, tekst licznika */
  --k-baby-mint: #b8eae4;         /* tło stanu hover */
  --k-hl-mint: #ebfffc;           /* tło przycisku „x3" */
  --k-lime: #f6ff47;              /* H1 hero, CTA akcentowe */

  /* ---------- Kolory: marka OKNOPLAST (stopka, elementy korporacyjne) ---------- */
  /* Kolory korporacyjne OKNOPLAST — bez konsumenta po przebudowie stopki,
     zostawione, bo mogą wrócić przy elementach spoza kampanii. */
  --k-brand-blue: #00b1eb;
  --k-brand-blue-dark: #0091c2;

  /* ---------- Kolory: neutralne ---------- */
  /* Pełna skala szarości z Figmy (get_variable_defs na frame 166:17719) —
     numeracja tokenów idzie za numeracją zmiennych w projekcie. */
  --k-white: #ffffff;             /* Grayscale/01 White */
  /* Stan błędu — do 09/2026 wpisany na sztywno (#c0392b) w czterech miejscach
     w komponentach. Figma nie ma dla niego zmiennej, więc nazwa jest
     funkcjonalna, nie „mintowa". */
  --k-error: #c0392b;
  --k-gray-050: #f9fafc;          /* Grayscale/Section Background Gray-50 */
  --k-gray-100: #f6f8f9;          /* Grayscale/02 Gray-100 */
  --k-gray-200: #dce3e9;          /* Grayscale/03 Gray-200 — obramowania */
  --k-gray-300: #b9c6d4;          /* Grayscale/04 Gray-300 */
  --k-gray-400: #a7b7c9;          /* Grayscale/05 Gray-400 — linia w stopce */
  --k-gray-500: #616d7f;          /* Grayscale/06 Gray-500 — copyright i linki prawne */
  --k-gray-600: #444d5a;          /* Grayscale/07 Gray-600 — tekst treści */
  --k-gray-700: #484950;          /* Grayscale/08 Gray-700 (Brand) — logo */
  --k-gray-800: #292d37;          /* Grayscale/09 Gray-800 — nagłówki, etykiety */
  --k-plr-black: #121212;         /* plr.black */

  /* ---------- Role semantyczne (używaj TYCH w kodzie sekcji) ---------- */
  --k-surface: var(--k-white);
  --k-surface-alt: var(--k-gray-050);
  --k-surface-mint: var(--k-hl-mint);
  --k-surface-mint-strong: var(--k-baby-mint);
  --k-surface-deep: var(--k-deep-mint);

  --k-text: var(--k-gray-800);
  --k-text-muted: var(--k-gray-600);
  --k-text-on-deep: var(--k-white);
  --k-text-accent: var(--k-energy-mint);

  --k-border: var(--k-gray-200);
  --k-border-strong: var(--k-energy-mint);

  --k-action: var(--k-energy-mint);
  --k-action-hover: var(--k-baby-mint);
  --k-action-accent: var(--k-lime);
  --k-focus-ring: var(--k-energy-mint);

  /* ---------- Typografia ----------
     Wartości mobilne pochodzą wprost z Figmy. clamp() ma minimum równe liczbie
     z projektu, więc przy 390 px trafiamy dokładnie w makietę, a rośnie dopiero
     powyżej. Nie zmieniaj minimów bez sprawdzenia frame'a. */

  --k-font-sans: "Clan Pro", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Etykiety przycisków — Figma składa je krojem wąskim (Clan N Bold).
     Clan Pro jako zapas: różni się szerokością, ale nie rozjedzie layoutu. */
  --k-font-label: "Clan N", "Clan Pro", system-ui, -apple-system, sans-serif;

  /* Sufit ZRÓWNANY z --k-fs-display-desktop (64 px), nie 72 px — patrz blok
     desktopowy nizej. Sufit wchodzi dopiero od 800 px szerokosci, wiec telefony
     tej wartosci nigdy nie dotykaja; jedyne pasmo, na ktore wplywa, to 800-1023 px. */
  --k-fs-display: clamp(2.5rem, 1rem + 6vw, 4rem);          /* 40 px → 64 px */
  --k-fs-hero-sub: clamp(1.1875rem, 0.8rem + 1.1vw, 1.5rem); /* 19 px → 24 px */
  --k-fs-h2: clamp(1.625rem, 1.1rem + 2.2vw, 3rem);         /* 26 px → 48 px */
  --k-fs-h3: clamp(1.25rem, 1.05rem + 0.85vw, 1.75rem);
  --k-fs-h4: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);        /* 20 px → 24 px */
  --k-fs-lead: clamp(0.875rem, 0.82rem + 0.25vw, 1.0625rem);/* 14 px → 17 px */
  --k-fs-body: 1rem;
  --k-fs-count: clamp(1.75rem, 1.2rem + 2.2vw, 2.75rem);    /* 28 px → 44 px */
  --k-fs-count-unit: 0.875rem;                              /* 14 px */
  --k-fs-count-intro: 0.9375rem;                            /* 15 px */
  --k-fs-sm: 0.875rem;
  /* 16 px — minimum, przy którym iOS Safari nie przybliża strony po kliknięciu
     w pole formularza. Poniżej tej wartości zoom jest wymuszony przez system. */
  --k-fs-input-touch: 1rem;
  --k-fs-xs: 0.75rem;
  --k-fs-label: 0.75rem;                                    /* 12 px — badge, przyciski */
  --k-fs-label-sm: 0.8125rem;                               /* 13 px — badge kroku w poradniku */
  --k-fs-caption: 0.75rem;                                  /* 12 px — podpisy pod zdjęciami */
  --k-fs-note: 0.8125rem;                                   /* 13 px — opisy pod tytułami korzyści */
  --k-fs-pill: 1.625rem;                                    /* 26 px — „1700+" na zdjęciu fabryki */
  --k-fs-guarantee: 1.171875rem;                            /* 18,73 px — „7 LAT" w kole gwarancji */
  --k-fs-guarantee-sm: 0.658125rem;                         /* 10,54 px — druga linia koła */
  --k-fs-stat: clamp(2.75rem, 2.2rem + 2.2vw, 4rem);        /* 44 px → 64 px */

  /* Nagłówek sekcji na desktopie — frame #poradnik (234:22456) składa go
     stylem H3 (Clan Medium 28/40, LS −1,6), nie H2. Stała, nie clamp:
     Figma podaje jedną wartość dla 1440 px. */
  --k-fs-h3-desktop: 1.75rem;                               /* 28 px */

  /* Hero na desktopie — frame # hero-banner (706:6020). Stałe, nie clampy:
     Figma podaje po jednej wartości dla 1440 px, a clampy wyżej obsługują
     warstwę bazową i przy 1440 px przestrzeliwują.

     H1: sufit clampa został OBNIŻONY do 4rem, żeby zgadzał się z wartością poniżej.
     Powod: sufit 4.5rem (72 px) wchodził dopiero od 933 px, czyli wyłącznie
     w paśmie 933-1023 px — gdzie układ jest jeszcze mobilny, jednokolumnowy.
     Mobilny H1 przy 1023 px byl wtedy WIEKSZY (72) niz desktopowy przy 1024 (64),
     wiec tytul KURCZYL sie przy poszerzaniu okna. Argument "clamp dziala tez
     ponizej 1024, gdzie uklad jest mobilny" nie chronil tu niczego: sufit
     wlacza sie od 800 px, wiec telefony go nigdy nie siegaly.

     Cyfra licznika (--k-fs-count, sufit 44 px vs 36 px desktop) ma ten sam
     problem i NIE zostala ruszona — osobny temat, mniejsza widocznosc. */
  --k-fs-display-desktop: 4rem;                             /* 64 px — H1, styl Headers/XL Desktop */
  --k-lh-display-desktop: 80px;
  --k-ls-display-desktop: -3.2px;                           /* −0,05 em */
  --k-lh-hero-sub-desktop: 32px;
  --k-ls-hero-sub-desktop: -1.2px;
  --k-fs-count-desktop: 2.25rem;                            /* 36 px — cyfra licznika */
  --k-lh-count-desktop: 28px;
  --k-fs-count-intro-desktop: 1rem;                         /* 16 px — „Promocja trwa tylko do…" */

  --k-lh-tight: 1.1;
  --k-lh-heading: 1.2;                                      /* 40/48 = 1.2 */
  --k-lh-h2: 32px;                                          /* stała z Figmy (26/32) */
  --k-lh-h3: 40px;                                          /* stała z Figmy (28/40) */
  --k-lh-lead: 20px;                                        /* stała z Figmy (14/20) */
  --k-lh-h4: 28px;                                          /* stała z Figmy (20/28) */
  --k-lh-body: 1.55;
  --k-lh-label: 16px;                                       /* stała z Figmy */
  --k-ls-label: -0.2px;                                     /* etykiety i przyciski */
  --k-ls-tight: -0.6px;                                     /* treść 14–16 px: FAQ, benefity, pola formularza */
  --k-ls-note: -0.4px;                                      /* opisy 13–14 px i etykiety pól */
  --k-ls-h3: -1.6px;                                        /* Headers/H3 na desktopie — 28/40 */
  --k-ls-h5: -0.8px;                                        /* Headers/H5 (Basic) — 16/24 */
  --k-ls-heading: -1px;                                     /* nagłówki H3/H4 sekcji */
  --k-ls-display: -1px;                                     /* H1 hero */

  --k-fw-book: 300;
  --k-fw-news: 400;
  --k-fw-medium: 500;
  --k-fw-bold: 700;
  --k-fw-black: 900;

  /* zgodność wstecz — nazwy używane w sekcjach napisanych wcześniej */
  --k-fw-regular: var(--k-fw-news);

  /* ---------- Odstępy (skala 4 px) ---------- */
  --k-space-1: 0.25rem;
  --k-space-2: 0.5rem;
  --k-space-3: 0.75rem;
  --k-space-4: 1rem;
  --k-space-5: 1.5rem;
  --k-space-6: 2rem;
  --k-space-7: 2.5rem;
  --k-space-8: 3rem;
  --k-space-9: 4rem;
  --k-space-10: 5rem;
  --k-space-11: 6rem;

  /* rytm pionowy sekcji — jeden token, spójne odstępy w całej stronie */
  --k-section-y: clamp(2rem, 1.2rem + 4vw, 5rem);            /* 32 px z Figmy → 80 px */
  --k-gutter: clamp(1rem, 0.6rem + 1.6vw, 2.5rem);           /* 16 px z Figmy → 40 px */
  --k-container: 1440px;
  --k-container-narrow: 960px;
  --k-container-wide: 1200px;     /* kalkulator na desktopie (Figma: 203:22072) */

  /* Siatka desktopowa z Figmy: 1440 − 2 × 120 px marginesu. Tę samą
     szerokość trzyma już stopka (frame # footer, 508:7591). */
  --k-container-desktop: 1200px;

  /* Miara bloku copy i pojedynczego kroku poradnika — Figma 234:22460
     i 234:22476. Kolumna ma 584 px, ale tekst kończy się na 481 px:
     powyżej ~65 znaków w wierszu przestaje się wygodnie czytać. */
  --k-measure-copy: 481px;

  /* Kolumna parametrów w #benefity-top — Figma 166:21647 i 166:17776.
     Ta sama szerokość w obu makietach, węższa niż kolumna copy (588 px). */
  --k-measure-params: 339px;

  /* Kwadrat animacji/packshotu w karcie #benefity-top — Figma 166:21720.
     Karta ma tę samą wysokość, więc medium wypełnia ją w pionie. */
  --k-media-square: 394px;

  /* Kafel packshotu na desktopie — Figma 166:21740. Mobile trzyma 282 px
     (--k-kafel w sections.css); proporcja kadru zostaje ta sama, 0,94. */
  --k-packshot-desktop: 360px;

  /* Wysokość kafla galerii na desktopie — Figma 183:22010. Bezwymiarowa,
     bo wchodzi do aspect-ratio razem z --k-shot-w-d z atrybutu kafla:
     poziome 690/517, pionowe 384/517. */
  --k-gallery-img-h: 517;
  /* Szerokość kafla poziomego — powtórzona z atrybutów kafli, bo tor
     potrzebuje jej do wyliczenia zapasu na końcu przewijania. */
  --k-shot-wide-d: 690;
  /* Zdjęcia w galerii idą o 25 % w dół względem makiety — decyzja klienta
     po obejrzeniu sekcji na żywo. Skala jednorodna, proporcja bez zmian. */
  --k-gallery-scale: 0.75;

  /* Kadr zdjęcia fabryki na desktopie — Figma 234:22513. Pliki są trzymane
     w 16:9 właśnie po to, żeby proporcja mogła się zmieniać między
     breakpointami; 690:397 to 1,738 wobec 1,778, czyli praktycznie ten sam. */
  --k-about-img-w: 690;
  --k-about-img-h: 397;

  /* Boczny padding paska statystyk (234:22520). Nie mieści się w skali 4 px. */
  --k-stats-pad-x: 101px;

  /* Biały margines wewnątrz pliku packshotu, przeliczony na kadr 360 px.
     Zmierzony bounding boxem niebiałych pikseli na wszystkich ośmiu kolorach:
     19–20 px z lewej, 16–17 z prawej. Potrzebny, bo odstęp strzałek liczymy
     od WIDOCZNEGO okna, nie od krawędzi pliku. */
  --k-packshot-bleed: 20px;
  /* to samo od góry — potrzebne, bo o tę wartość zielona karta jest
     odsunięta w dół, żeby jej krawędź stanęła równo z górą okna */
  --k-packshot-bleed-top: 14px;

  /* Odstęp strzałki karuzeli od widocznego okna (wytyczna projektanta) */
  --k-carousel-arrow-gap: 40px;

  /* Karta gwarancji na desktopie jest węższa niż kolumna (584) — Figma
     166:21753. Nadmiar po prawej wypełnia wystająca plakietka. */
  --k-guarantee-desktop: 486px;
  /* O tyle plakietka „7 LAT" wychodzi poza prawą krawędź karty (166:21752).
     Ta sama liczba rezerwuje jej miejsce w kolumnie, gdy ta jest za wąska
     na pełne 486 px — inaczej koło wychodzi poza treść i zostaje ucięte. */
  --k-guarantee-badge-bleed: 44px;

  /* Dolny padding sekcji „Zobacz Okno PIXEL" — 72 px z referencji.
     Nie mieści się w skali 4 px (między --k-space-9 a --k-space-10),
     stąd własny token zamiast naciągania skali. */
  --k-product-block-pb: 72px;

  /* o tyle pozycja menu odsuwa się w prawo pod kursorem (referencja: 16 px) */
  --k-menu-hover-shift: 16px;

  /* ---------- Promienie ---------- */
  --k-radius-xs: 6px;
  --k-radius-sm: 10px;
  --k-radius-card: 12px;          /* karty sekcyjne: #benefity, statystyki, kalkulator */
  --k-radius-md: 16px;
  --k-radius-lg: 24px;
  --k-radius-xl: 32px;
  --k-radius-map: 21px;           /* mapa salonów (Figma: 355:4789) */
  --k-radius-pill: 999px;

  /* ---------- Cienie ---------- */
  --k-shadow-sm: 0 1px 2px rgba(12, 40, 35, 0.06);
  --k-shadow-md: 0 6px 20px rgba(12, 40, 35, 0.08);
  --k-shadow-lg: 0 18px 48px rgba(12, 40, 35, 0.12);
  /* Figma → efekt „Drop shadow": X 1, Y 7, Blur 10.4, Spread 0, #000000 15%.
     Blur z Figmy przekłada się 1:1 na promień rozmycia w box-shadow
     (w eksporcie SVG to stdDeviation 5.2, czyli połowa). */
  /* Figma → Drops/Input/01 Basic: X 0, Y 1, Blur 2, #DCE3E9 50 % */
  --k-shadow-input: 0 1px 2px rgba(220, 227, 233, 0.5);
  --k-shadow-badge: 1px 7px 10.4px rgba(0, 0, 0, 0.15);

  /* ---------- Szkło (UI Web 3.0: „Glass Effect") ----------
     Przyciski leżące na tle mediów. Kolor i obrys są z biblioteki
     (Glass Effect / Recreated Gray #DCE3E9, biel 30 % na obrysie),
     rozmycie 24 px zdjęte z żywego playera na oknoplast.com.pl/okna/pixel/
     — Figma ma w zmiennych tylko dwa stopnie, 12 i 48 px. */
  --k-glass-bg: rgba(220, 227, 233, 0.4);
  --k-glass-border: rgba(255, 255, 255, 0.3);
  --k-glass-blur: 24px;
  --k-shadow-glass: 0 1px 0 rgba(0, 0, 0, 0.1);
  /* Wariant „Play, Size=64 x 64" (9930:382308) — tyle renderuje też
     żywy player na oknoplast.com.pl/okna/pixel/. */
  --k-btn-play: 64px;

  /* ---------- Ruch ---------- */
  --k-dur-fast: 160ms;
  --k-dur-base: 280ms;
  --k-dur-slow: 520ms;
  /* Rozwijanie karty i przejście ikony + → −; dzieli je zwijany tekst zgody
     w formularzu. Czas zdjęty z .ivn-BlockFAQ__answer na
     oknoplast.com.pl/okna/pilar. */
  --k-dur-accordion: 300ms;
  --k-dur-hover: 200ms;           /* przejścia stanu hover — obrys i kolor tekstu */
  /* Wysuwanie panelu menu — czas i krzywa zdjęte z oknoplast.com.pl/pilar
     (.c-header-menu: transition .5s, .c-header: cubic-bezier(.33,1,.68,1)).
     Wolniej i łagodniej niż --k-dur-base + --k-ease-out. */
  --k-dur-menu: 500ms;
  /* Programowe przewijanie — wartości czyta js/modules/scroll.js */
  --k-dur-scroll: 500ms;          /* karuzela po strzałce, zjazd do kotwicy */
  --k-dur-scroll-reduced: 220ms;  /* profil skrócony przy prefers-reduced-motion */
  /* Timing przycisków zdjęty wprost z belki oknoplast.com.pl — pigułka
     „Gdzie kupić" (.ivn-Btn--primary) ma `background-color .3s ease-in-out`.
     Jeden czas w obie strony: przejście deklarujemy w stanie spoczynku
     i NIE nadpisujemy go na :hover, więc dojście i powrót trwają tyle samo. */
  --k-dur-btn: 300ms;
  /* Jeden obrót spinnera na przycisku formularza (submitLead() w
     js/modules/form.js) — poza globalną skalą fast/base/slow, bo to pętla
     ciągła, nie przejście stanu. */
  --k-dur-spin: 800ms;

  /* Opóźnienia pojawiania — czytane przez [data-reveal] w css/base.css.
     Warianty „solo" i „center" (js/modules/reveal.js) nie dostają staggeru,
     więc opóźnienie zostaje tutaj, w tokenach, zamiast w kodzie. */
  --k-delay-hero-badge: 1200ms;   /* plakietka hero czeka, aż pierwszy widok się poskłada */
  --k-delay-badge: 200ms;         /* oddech po dojechaniu do środka ekranu */
  /* Warstwy KV na desktopie wchodzą PO kaskadzie copy (badge → H1 → sub → CTA →
     licznik to 5 × 80 ms staggeru + 520 ms przejścia), ale PRZED plakietką. */
  --k-delay-hero-okno: 700ms;
  --k-delay-hero-chlopiec: 900ms;

  /* Kołysanie chłopca w KV — jedyny ruch, który nie kończy się po wejściu.
     Długie i płytkie z premedytacją: to tło pod treścią, nie ma przyciągać oka. */
  --k-dur-hero-idle: 4.5s;
  --k-hero-idle-shift: 4px;

  /* Dystans skoku przy pojawianiu — parametr ruchu, nie odstęp w rytmie sekcji,
     dlatego własny token, a nie --k-space-*. */
  --k-reveal-shift: 24px;
  --k-reveal-shift-sm: 12px;      /* plakietki — krótszy skok, koło jest małe */

  --k-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --k-ease-out-cubic: cubic-bezier(0.33, 1, 0.68, 1);
  --k-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  /* Krzywa przycisków — dokładnie słowo kluczowe `ease-in-out` z CSS, bo tego
     używa oknoplast.com.pl. Łagodniejsza od --k-ease-in-out wyżej i celowo
     inna od --k-ease-out*: kolor rusza powoli, zamiast skakać od pierwszej
     klatki. Stąd wrażenie „wolniejszego" hoveru mimo krótszego czasu. */
  --k-ease-btn: cubic-bezier(0.42, 0, 0.58, 1);
  /* Krzywa przewijania i przygaszeń na mediach — dokładnie słowo kluczowe
     `ease` z CSS, zdjęte ze slidera na oknoplast.com.pl/pilar. W przeciwieństwie
     do --k-ease-out* ma WEJŚCIE w ruch: rusza łagodnie, płynie, zwalnia.
     Odwzorowana też w js/modules/scroll.js — tam liczymy ten bezier wprost. */
  --k-ease-glide: cubic-bezier(0.25, 0.1, 0.25, 1);
  /* Rozsuwanie panelu FAQ — słowo kluczowe `ease-out` z CSS, zdjęte
     z .ivn-BlockFAQ__answer. NIE mylić z --k-ease-out mimo nazwy: tamta
     jest niemal wykładnicza i przy krótkim czasie czyta się jak szarpnięcie,
     ta rusza pełną prędkością i tylko łagodnie hamuje. */
  --k-ease-panel: cubic-bezier(0, 0, 0.58, 1);

  /* ---------- Warstwy ---------- */
  --k-z-base: 0;
  --k-z-sticky-badge: 20;
  /* Pasek CTA na dole — pod belka (100), pod lightboxem (900) i pod menu (1000),
     zeby nigdy nie przebil sie nad nakladke. */
  --k-z-cta-bar: 90;
  --k-z-header: 100;
  /* Przy otwartym menu belka musi zostac NAD nakladka — to ona trzyma logo
     i przycisk zamkniecia, wiec nie moze zniknac pod panelem. */
  --k-z-header-open: 1010;
  --k-z-lightbox: 900;
  --k-z-modal: 1000;
}

/* Wysokość sticky baru — czytana przez JS i CSS (scroll-margin kotwic) */
:root {
  --k-header-h: 64px;
  /* Pasek CTA na dole (Figma 331:4401, 390x80). Stopka odejmuje go sobie
     z wysciolki, zeby linki prawne nie zostaly trwale przykryte. */
  --k-cta-bar-h: 80px;
}

@media (min-width: 1024px) {
  :root {
    --k-header-h: 76px;
  }
}
