/* =============================================
   SELF-HOSTED MONTSERRAT — eliminates Google Fonts round trips
   Same WOFF2 file per subset (variable font), separate @font-face per weight for compatibility
   ============================================= */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* =============================================
   CSS VARIABLES — Used on: ALL (10 pages)
   ============================================= */
:root {
  /* ---- Colors ---- */
  --white: #FAF9F4;
  --black: #151515;
  --dark-gray: #151515;
  --orange: #EA6E2D;
  --orange-rgb: 234, 110, 45;
  --orange-end: #F89762;
  --orange-end-rgb: 248, 151, 98;
  --orange-gradient: linear-gradient(135deg, var(--orange), var(--orange-end));
  --dark-bg: #151515;
  --border-color: #ECE8DF;
  --gray-400: #999;
  --gray-500: #555;
  --google-yellow: #FBBC04;
  --success-green: #22c55e;

  /* ---- Typography ---- */
  --font-family: 'Montserrat', sans-serif;
  --heading-size: 52px;
  --heading-weight: 500;

  /* ---- Layout ---- */
  --max-width: 1200px;
  --max-width-wide: 1400px;
  --navbar-height: 64px;

  /* ---- Border Radius ---- */
  --radius-xs: 3px;
  --radius-sm: 5px;
  --radius-md: 9px;
  --radius-lg: 11px;
  --radius-xl: 14px;
  --radius-full: 50%;

  /* ---- Scroll reveal (section entrance) ----
     One duration + one curve for EVERY section entrance across the site.
     Before these existed the same gesture ran at 0.3s / 0.4s / 0.6s / 0.72s /
     0.8s / 0.84s / 1.2s depending on which stylesheet happened to own the
     section, so scrolling the page read as a series of unrelated animations.
     The curve is the same one the page transition uses (see eo-page-in) — it is
     strongly front-loaded, so the visible motion is done well before the
     duration elapses and the longer time reads as "settling", not "waiting".
     Interaction transitions (hover, press, popovers, navbar) deliberately do
     NOT use these — those must stay in the 0.15–0.3s range to feel responsive. */
  --reveal-duration: 0.9s;
  --reveal-ease: cubic-bezier(0.23, 1, 0.32, 1);
}


/* =============================================
   RESET & BASE
   ============================================= */
*, *::before, *::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  overflow-x: clip;
  /* iOS Safari: bez tego przeciagniecie ZA koniec strony odslania kremowe tlo canvasu
     pod ciemna stopka (rubber-band) i wyglada jak dziura w ukladzie. To NIE jest pusta
     przestrzen w dokumencie — zmierzone w WebKicie i Chromium: dolna krawedz `.footer`
     rowna sie `scrollHeight` co do piksela na kazdej trasie, a jedyne elementy pod nia
     to `position: fixed` (ukryte menu mobilne + baner cookies). Kolor bierze sie stad,
     ze `html` nie ma wlasnego tla, wiec canvas dziedziczy je z `body` (`--white`).
     KOSZT: blokuje takze gest odswiezania (pull-to-refresh) na gorze strony. */
  overscroll-behavior-y: none;
  scrollbar-width: none; /* Firefox — hide scrollbar */
  -ms-overflow-style: none; /* IE / old Edge — hide scrollbar */
  /* Kill the browser's default tap rectangle site-wide. On touch it paints a blue/gray
     box over the whole element and reads as "a link is opening". The property is
     inherited, so declaring it here covers every button/link/input on every page.
     Press feedback comes from each component's own :active / :hover / .touch-hover
     state instead — do NOT remove those thinking this rule replaced them. */
  -webkit-tap-highlight-color: transparent;
}

/* Hide the scrollbar (Chrome, Safari, new Edge) while keeping scroll functionality */
html::-webkit-scrollbar,
body::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

body {
  font-family: var(--font-family);
  background-color: var(--white);
  color: var(--dark-gray);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* =============================================
   KEYFRAME ANIMATIONS
   ============================================= */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

@keyframes fadeInLeft {
  from {
    opacity: 0;
    transform: translateX(-30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes fadeInRight {
  from {
    opacity: 0;
    transform: translateX(30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* Slide-only variant (no opacity) — used on LCP elements so Lighthouse can detect them */
@keyframes slideInRight {
  from {
    transform: translateX(30px);
  }
  to {
    transform: translateX(0);
  }
}

@keyframes marquee {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-33.333%);
  }
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(100%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes slideOut {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-100%);
  }
}

/* =============================================
   PAGE TRANSITIONS (cross-document view transitions)
   Every page opts in; browsers without support navigate instantly as before.
   ============================================= */
@view-transition {
  navigation: auto;
}

@keyframes eo-page-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

/* Opt out of the UA's plus-lighter crossfade so the incoming page composites
   over the outgoing one normally. */
::view-transition-image-pair(root) {
  isolation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  mix-blend-mode: normal;
}

/* The outgoing page holds still and fully opaque underneath. Fading or shrinking
   it would let the backdrop show through wherever the incoming page hasn't
   reached full opacity — including the 14px strip its rise leaves at the top. */
::view-transition-old(root) {
  animation: none;
}

::view-transition-new(root) {
  animation: eo-page-in 300ms cubic-bezier(0.23, 1, 0.32, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }
}

/* =============================================
   UNIVERSAL SECTION FADE-IN (scroll reveal)
   ============================================= */
.section-fade {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity var(--reveal-duration) var(--reveal-ease),
              transform var(--reveal-duration) var(--reveal-ease);
}

.section-fade.visible {
  opacity: 1;
  transform: translateY(0);
}

/* Site-wide reduced-motion guard for the reveal system. Individual stylesheets
   (trust-stats, cta-banner, footer, process, montage) have their own blocks for
   their own animations — this one only neutralises the shared reveal tokens, so
   every section that opted into them is covered without touching those. The
   opacity fade is deliberately kept (shortened): it aids comprehension, and
   reduced motion means less movement, not no transition at all. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --reveal-duration: 0.2s;
    --reveal-ease: ease;
  }

  .section-fade {
    transform: none;
  }
}

/* =============================================
   TELEFON — SZYBSZE WEJSCIA SEKCJI (globalna polityka ruchu, ≤768px)

   Wyzwalacze wejsc sa POZYCYJNE i sa poprawne (element przekracza linie ~80px
   nad dolna krawedzia). Problemem na telefonie jest CZAS: ruch 0.7s przy
   realnej predkosci przewijania palcem (~900 px/s) oznacza, ze element jest
   czytelny dopiero po przejechaniu ~500px w gore ekranu — czyli uzytkownik
   widzi pod soba biale tlo tam, gdzie tresc juz stoi. Ekran telefonu ma 844px,
   wiec kazde opoznienie „wypala sie" poza kadrem (ten sam mechanizm, ktory
   wymusil triggery pozycyjne w why-us v64 i services v35 — tam chodzilo o
   opoznienia, tu o sam czas trwania).

   Zmierzone Playwrightem @390x844, przewijanie 900 px/s — pozycja na ekranie,
   w ktorej element osiaga polowe widocznosci (wiecej = wczesniej widoczny):
   opinie 14 → 534, montaz 295 → 487, partnerzy 307 → 499, salon 317 → 509,
   proces 332 → 524, FAQ 342 → 535, realizacje 363 → 555. Przy spokojnym
   przewijaniu (400 px/s) wartosci ida z ~600 na ~650, wiec animacja NADAL jest
   widoczna — nie jest to wylaczenie efektu, tylko skrocenie.

   DLACZEGO TU, A NIE W 14 ARKUSZACH SEKCJI: to jedna polityka ruchu dla calego
   serwisu (jak blok reduced-motion wyzej), a rozbicie jej na pliki oznaczaloby
   14 bumpow `?v=` na ~20 stronach kazdy — czyli dokladnie ta sytuacja, w ktorej
   ten projekt juz raz zgubil strone przy bumpie. Kazdy selektor ma PODWOJONA
   klase (0,2,0), bo base.css laduje sie PIERWSZY, a arkusze sekcji definiuja te
   tokeny pojedyncza klasa (0,1,0) — bez podwojenia wygralyby kolejnoscia w
   zrodle. `.door-types` potrzebuje POTROJENIA, bo jego wlasny blok to juz
   (0,2,0). Zmieniamy WYLACZNIE czas trwania i krok kaskady — krzywa
   (`ease-out`) i dystans (30px) zostaja, bo to one daja charakter ruchu.

   Warunek `prefers-reduced-motion: no-preference` jest KONIECZNY: bloki
   reduced-motion w arkuszach sekcji skracaja czas do 0.2s pojedyncza klasa,
   wiec bez tego warunku ten blok by je przebijal.
   ============================================= */
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .why-us.why-us { --whyus-reveal-dur: 0.45s; }
  .services.services { --services-reveal-dur: 0.35s; --services-step: 0.12s; --services-card-dur: 0.45s; }
  .showroom--bento.showroom--bento { --showroom-reveal-dur: 0.45s; --showroom-step: 0.12s; }
  .testimonials.testimonials { --ts-reveal-dur: 0.45s; --ts-step: 0.12s; }
  .realizacje.realizacje { --rz-reveal-dur: 0.45s; --rz-step: 0.12s; }
  .montage.montage { --montage-reveal-dur: 0.45s; --montage-reveal-step: 0.12s; }
  .partners.partners { --partners-reveal-dur: 0.45s; --partners-step: 0.12s; }
  .faq.faq { --faq-reveal-dur: 0.45s; --faq-step: 0.12s; }
  .process--stack.process--stack { --ps-reveal-dur: 0.45s; --ps-step: 0.12s; }
  .cta-banner--dark.cta-banner--dark { --ctad-reveal-dur: 0.45s; }
  .cta-banner--image.cta-banner--image { --ctai-reveal-dur: 0.45s; }
  .testimonial-quote.testimonial-quote { --tq-reveal-dur: 0.45s; }

  /* System `data-reveal` — o-nas, strony oferty, realizacje i podstrona
     realizacji dziela te sama nazwe tokenu. */
  .eo-reveal.eo-reveal { --eo-reveal-dur: 0.45s; }
  .door-types.door-types.eo-reveal { --eo-reveal-dur: 0.45s; }

  /* ---- DYSTANS WJAZDU: 30px → 44px ----
     Na ekranie 390px przesuniecie o 30px to 7% szerokosci — klient zglosil, ze
     elementy „doslownie pojawiaja sie natychmiast", i mial racje takze tutaj:
     przy skroconym do 0.45s ruchu tak maly dystans czyta sie jak samo
     zapalenie, a nie jak wjazd. 44px to ~11% szerokosci telefonu i ~2.5x
     wysokosc wiersza tekstu, wiec ruch jest czytelny, a nadal nie przesadzony.
     Desktop zostaje na 30px (tam ekran jest szerszy, a ruch i tak widac).

     **Kompensacje klipow przelicza sie SAME** — `.cta-banner__list` i
     `.process-stack__values` licza swoj `padding`/`margin` z tego samego tokenu
     (`calc`), wiec linia ciecia dalej lezy dokladnie na dystansie ruchu i nic
     nie jest „rozkrojone" (patrz gotcha o wjazdach z boku). Nie zamieniaj tam
     tokenu na liczbe. */
  .why-us.why-us { --whyus-shift: 44px; }
  .showroom--bento.showroom--bento { --showroom-shift: 44px; }
  .testimonials.testimonials { --ts-shift: 44px; }
  .realizacje.realizacje { --rz-shift: 44px; }
  .montage.montage { --montage-reveal-shift: 44px; }
  .partners.partners { --partners-shift: 44px; }
  .faq.faq { --faq-shift: 44px; }
  .process--stack.process--stack { --ps-shift: 44px; }
  .cta-banner--dark.cta-banner--dark { --ctad-shift: 44px; }
  .cta-banner--image.cta-banner--image { --ctai-shift: 44px; }
  .testimonial-quote.testimonial-quote { --tq-shift: 44px; }
  .eo-reveal.eo-reveal { --eo-shift: 44px; }
  .door-types.door-types.eo-reveal { --eo-shift: 44px; }
}
