/* ============================================================
   SPIS TREŚCI - components.css (style komponentów JS)
   1. ACCORDION (zwijanie tylko pod .is-collapsible z JS, + przycisk „Pokaż więcej")
   2. TABS
   3. MOBILE MENU (stan panelu poniżej lg, wariant bez JS: panel rozwinięty w przepływie)
   4. POPUP
   5. GALLERY (lightbox - kropki paginacji)
   6. MEGAMENU
   7. CUSTOM SCROLL
   8. SMOOTH SCROLL
   10. MENU GŁÓWNE (menu WP primary: desktop + panel mobilny, hovery pod (hover: hover))
   11. TYPED (kursor pisanych słów, typing.js)
   --- poniżej koniec @layer components ---
   9. CONTACT FORM 7 (bez warstwy, patrz niżej; obrys znika tylko przy fokusie z myszy; poza szablonem PBW)
   9a. FORMULARZ WYCENY (blok offer-form + szablon CF7, bez warstwy, stany formsteps.js)
   9b. FORMULARZ KONTAKTOWY (blok contact-main + szablon CF7 kontakt, bez warstwy, stany CF7)
   Kolejność jak w pliku. Sekcje 10-11 stoją przed 9, bo siedzą w warstwie; numery
   zostają, bo odwołują się do nich CLAUDE.md i komentarze w innych plikach.
   ------------------------------------------------------------
   Utility Tailwinda zawsze wygrywa z tym plikiem: sekcje 1-8 i 10-11 siedzą w
   @layer components, więc klasa TW na elemencie (hidden, lg:static, kolor)
   bije regułę komponentu bez !important i bez dodatkowych reguł .x.hidden.
   Bez warstwy tylko nadpisania cudzego CSS bez warstwy (sekcja 9: arkusz CF7),
   bo w warstwie przegrałyby z oryginałem.
   Pierwsza linia ustala kolejność warstw jak w tailwind.css - w edytorze ten
   plik ładuje się PRZED tailwind.css i bez niej components spadłoby pod base.
   ============================================================ */
@layer theme, base, components, utilities;

@layer components {

/* === 1. ACCORDION === */
    .accordion_margin:before {
        content: "";
        margin-top: 0;
        float: left;
        width: 100%;
    }
    .accordion_margin:after {
        content: "";
        margin-bottom: 20px;
        float: left;
        width: 100%;
    }

    [accordion-button].active .rotate_bar {
        rotate: -90deg;
        transition: rotate .3s ease-in-out;
    }

    [accordion-button] {
        cursor: pointer;
    }

    /* Zwija tylko .is-collapsible, którą accordion.js nadaje kontenerowi (także dopiero poniżej
       progu data-accordion-below). Bez JS i od progu panele zostają widoczne. Wysokość w trakcie
       animacji ustawia JS inline; czas i easing konkretnego akordeonu: klasy duration-* i ease-*
       na panelu (utility wygrywa z tą regułą). */
    [data-accordion].is-collapsible [accordion-panel] {
        overflow: hidden;
        transition: height .3s ease-in-out;
    }

    [data-accordion].is-collapsible [accordion-panel]:not(.active) {
        display: none;
    }

    @media (prefers-reduced-motion: reduce) {
        [data-accordion].is-collapsible [accordion-panel] {
            transition: none;
        }
    }

    /* Show more FAQ button */
    @keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
    }

    .hide-accordion {
        max-height: 0;
        display: none;
        overflow: hidden;
        transition: max-height 0.5s ease-out;
    }

    .show-more-btn {
        margin: 20px auto 0 auto;
        display: block;
        font-family: inherit;
        color: #fff;
        font-size: 14px;
        font-weight: 600;
        width: 100%;
        padding: 18px 0 18px 0;
        background-color: var(--color-primary-500, #000);
        transition: transform 300ms;
        border: none;
        cursor: pointer;
        border-radius: 24px;
    }

    @media (hover: hover) {
        .show-more-btn:hover {
            transform: scale(1.05);
        }
    }

/* === 2. TABS === */
    [tab-button].active {
        /* Active tab styles go here */
    }

    /* Panele przez [data-tab-panels] > *: WordPress gubi atrybut tab-panel na wrapperze
       bloku-dziecka. [tab-panel] zostaje dla starszego markupu. */
    [data-tab-panels] > *.active,
    [tab-panel].active {
        display: block;
        animation: fadeIn .5s ease-in-out;
    }

    [data-tab-buttons] > *,
    [tab-button] {
        cursor: pointer;
    }

    [data-tab-panels] > *,
    [tab-panel] {
        display: none;
    }

    @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
    }


/* === 3. MOBILE MENU === */
    /* Panel menu mobilnego (index.html, nav.nav-menu): pozycję, tło i wymiary trzymają klasy
       TW na elemencie, tutaj tylko stan zamknięty/otwarty przełączany klasą .active z JS.
       Kreski hamburgera i ich animację robią klasy TW (group-[.active]:) w index.html.
       Próg = lg (62rem) składnią zakresową jak w kompilacie TW4 i w mobilemenu.js, bez
       szczeliny 61.99-62rem. Od lg nav ma display: contents. */
    @media (width < 62rem) {
        .nav-menu {
            opacity: 0;
            visibility: hidden;
            transform: translateY(-0.5rem);
            transition: opacity .4s ease, transform .4s ease, visibility 0s linear .4s;
        }

        .nav-menu.active {
            opacity: 1;
            visibility: visible;
            transform: none;
            transition-delay: 0s;
        }
    }

    @media (width < 62rem) and (prefers-reduced-motion: reduce) {
        .nav-menu,
        .nav-menu.active {
            transform: none;
            transition: none;
        }
    }

    /* Bez JS hamburger nic nie otworzy, więc panel stoi rozwinięty pod paskiem, a header wraca
       do przepływu (fixed zasłoniłby treść na stałe). Warunek to (scripting: none), nie klasa
       z <head>: wb-anim zdejmuje też reduced-motion, a klasa stawiana przez mobilemenu.js
       (defer) dałaby mignięcie otwartego panelu przy każdym wejściu. Przeglądarka bez obsługi
       scripting zostaje przy zachowaniu z JS. !important tylko tam, gdzie wartość trzyma
       utility na elemencie (fixed, h-15, tło, flex): ważna deklaracja z warstwy components
       bije utility. Pierwsza sekcja strony ma swój odstęp pod header, bez JS to dodatkowe
       60/120 px nad treścią. */
    @media (width < 62rem) and (scripting: none) {
        .header {
            position: relative !important;
            height: auto !important;
            background: var(--color-ink-950) !important;
        }

        .header > div {
            flex-wrap: wrap;
            height: auto !important;
        }

        .header .hamburger {
            display: none !important;
        }

        .nav-menu {
            position: static !important;
            order: 1;
            flex: 0 0 auto;
            width: calc(100% + 2rem);
            margin-inline: -1rem;
            padding-bottom: 2.5rem;
            opacity: 1;
            visibility: visible;
            transform: none;
            transition: none;
        }

        /* Copyright z panelu powtarza stopkę, a z marginesami dokłada 240 px pustego tła. */
        .nav-menu p {
            display: none;
        }

        /* Prefiks .nav-menu: sekcja 10 stoi w pliku dalej i przy równej specyficzności by wygrała. */
        .nav-menu .mainMenu .sub-menu {
            display: flex;
            flex-direction: column;
            gap: 8px;
            margin-top: 8px;
        }

        .nav-menu .mainMenu > .menu-item-has-children > a::after {
            content: none;
        }
    }

/* === 4. POPUP === */
    /* Zamknięcie z animacją tylko na modalu z data-popup-fade="1": popup.js dodaje .is-closing
       i czeka na animationend. Bez atrybutu (okno wyboru, jak Modal-close w Webflow) i przy
       prefers-reduced-motion modal znika od razu. */
    @keyframes wbPopupOut {
        from { opacity: 1; }
        to { opacity: 0; }
    }

    .popup-modal[data-popup-fade].is-closing {
        animation: wbPopupOut .3s ease forwards;
    }


/* === 5. GALLERY (lightbox - kropki paginacji) === */
    .gallery-dot {
        width: 8px;
        height: 8px;
        border-radius: 9999px;
        background-color: #fff;
        opacity: 0.2;
        transition: opacity .2s ease;
    }

    .gallery-dot-active {
        opacity: 1;
    }


/* === 6. MEGAMENU === */
    [megamenu-panel] {
        display: none;
    }

    [megamenu-panel].active {
        display: flex;
    }

    .megamenu-item svg.active{
        rotate: 180deg;
    }

/* === 7. CUSTOM SCROLL === */
    .hide-scroll {
        -ms-overflow-style: none;
        scrollbar-width: none;
    }

    .hide-scroll::-webkit-scrollbar {
        display: none;
    }

    .scroller {
        scrollbar-width: auto;
        scrollbar-color: #1E1E1E #E2E2E2;
    }

    .scroller::-webkit-scrollbar {
        height: 5px;
    }

    .scroller::-webkit-scrollbar-track {
        background: #E2E2E2;
        border-radius: 20px;
    }

    .scroller::-webkit-scrollbar-thumb {
        background-color: #1E1E1E;
        border-radius: 20px;
    }


/* === 8. SMOOTH SCROLL === */
    @media (prefers-reduced-motion: no-preference) {
        html {
            scroll-behavior: smooth;
        }
    }

    /* Lenis (moduł gsap) sam przewija - natywne smooth koliduje z jego przewijaniem. */
    html.lenis {
        scroll-behavior: auto;
    }

/* === 10. MENU GŁÓWNE (menu WP „primary": pasek desktop + panel mobilny) === */
    /* Walker PG nadaje JEDEN szablon <li><a> pozycjom głównym i pozycjom podmenu, a klasy
       z WordPressa (menu-item-has-children, sub-menu, current-menu-item) nie stoją w HTML
       projektu. Wygląd linków menu siedzi więc tutaj, nie w klasach TW na szablonie: utility
       na linku wygrałaby z każdą regułą dla poziomu podmenu. Wartości z Webflow (.about-us-link,
       .dropdownlink, .phone-link-wrapper, .citiesbutton). Podmenu otwiera :hover/:focus-within
       (desktop) albo klasa .is-open na <li> (JS: panel mobilny, tap na dotyku od lg).
       .is-dismissed (Escape, klik w rodzica z href="#") chowa podmenu mimo :hover/:focus-within.
       Hovery tylko pod (hover: hover): na dotyku stan :hover zostaje po tapnięciu. Webflow
       przygasza cały .dropdown razem z otwartą listą; tu przygasa tylko link rodzica (także gdy
       kursor jest już w liście), a pozycja listy dostaje własne opacity .8 (w Webflow .dropdownlink
       nie ma hoveru, to domyślny dodatek). */
    .mainMenu a {
        display: block;
        color: var(--color-white);
        font-size: 0.875rem;
        line-height: 1.25rem;
        font-weight: 400;
        text-decoration: none;
        transition: opacity .2s;
    }

    @media (hover: hover) {
        .mainMenu > li > a:hover,
        .mainMenu > .menu-item-has-children:hover > a,
        .mainMenu .sub-menu a:hover {
            opacity: .8;
        }
    }

    .mainMenu > .menu-item-has-children > a {
        position: relative;
    }

    /* Strzałka rozwijania (glif w-icon-dropdown-toggle z Webflow), kolor z tekstu linku. */
    .mainMenu > .menu-item-has-children > a::after {
        content: "";
        position: absolute;
        top: 50%;
        width: 1em;
        height: 1em;
        transform: translateY(-50%);
        background-color: currentColor;
        -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 140 140'%3E%3Cpath d='M33 47l42 42 42-42' fill='none' stroke='black' stroke-width='20'/%3E%3C/svg%3E") center / contain no-repeat;
        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 140 140'%3E%3Cpath d='M33 47l42 42 42-42' fill='none' stroke='black' stroke-width='20'/%3E%3C/svg%3E") center / contain no-repeat;
    }

    .mainMenu .sub-menu {
        display: none;
    }

    .mainMenu .sub-menu .current-menu-item > a {
        color: var(--color-secondary-500);
    }

    /* Panel mobilny (poniżej lg): kafle 60px, podmenu pod rodzicem. */
    @media (width < 62rem) {
        .mainMenu > li > a,
        .mainMenu .sub-menu a {
            padding: 20px 0;
            border-radius: 2px;
            background-color: var(--color-ink-900);
            text-align: center;
        }

        .mainMenu > .menu-item-has-children > a::after {
            right: 20px;
            font-size: 0.75rem;
        }

        .mainMenu .sub-menu a {
            font-size: 13px;
            font-weight: 300;
        }

        .mainMenu .is-open > .sub-menu {
            display: flex;
            flex-direction: column;
            gap: 8px;
            margin-top: 8px;
        }
    }

    /* Pasek desktop: <ul> ma display: contents, więc <li> są elementami flexa wiersza headera
       (space-between jak w Webflow). Podmenu: lista pod etykietą, 20px oddechu jako padding,
       żeby kursor nie gubił :hover w drodze do listy. */
    @media (width >= 62rem) {
        .mainMenu > li {
            position: relative;
        }

        .mainMenu > li > a {
            font-size: 0.75rem;
        }

        .mainMenu > .menu-item-has-children > a {
            padding-right: 15px;
        }

        .mainMenu > .menu-item-has-children > a::after {
            right: -5px;
        }

        .mainMenu .sub-menu {
            position: absolute;
            top: 100%;
            left: 0;
            z-index: 900;
            min-width: 100%;
            padding-top: 20px;
        }

        .mainMenu .menu-item-has-children:hover > .sub-menu,
        .mainMenu .menu-item-has-children:focus-within > .sub-menu,
        .mainMenu .menu-item-has-children.is-open > .sub-menu {
            display: block;
        }

        /* Ta sama specyficzność co reguła wyżej, wygrywa kolejnością. */
        .mainMenu .menu-item-has-children.is-dismissed > .sub-menu {
            display: none;
        }

        .mainMenu .sub-menu a {
            padding: 10px 20px;
            background-color: var(--color-ink-950);
            white-space: nowrap;
        }

        .mainMenu .sub-menu > li:first-child > a {
            border-top-left-radius: 10px;
            border-top-right-radius: 10px;
        }

        .mainMenu .sub-menu > li:last-child > a {
            border-bottom-left-radius: 10px;
            border-bottom-right-radius: 10px;
        }
    }

    @media (width >= 80rem) {
        .mainMenu > li {
            margin-right: 5px;
        }

        .mainMenu > li > a {
            font-size: 0.875rem;
        }
    }

/* === 11. TYPED (typing.js, pisane słowa) === */
    /* Kursor 1:1 z arkusza, który Typed.js 2.0.12 wstrzykiwał w Webflow: znak „|" za spanem
       ze słowami (kolor i krój nagłówka), miga tylko w pauzie po napisaniu słowa. */
    .typed-cursor {
        opacity: 1;
    }

    .typed-cursor.typed-cursor--blink {
        animation: typedjsBlink .7s infinite;
    }

    @keyframes typedjsBlink {
        50% { opacity: 0; }
    }

} /* koniec @layer components */


/* === 9. CONTACT FORM 7 (bez warstwy: nadpisuje niewarstwowy arkusz wtyczki) === */
    /* Zakres: cały serwis poza szablonem PBW (body.pbwPage ma własne style formularzy w pbw.css).
       :where() nie podnosi specyficzności, więc 9a i 9b wygrywają jak wcześniej. */
    /* Układ formularza robimy klasami Tailwinda w shortcode (class:...), a <p>/<br>
       wyłącza filtr w inc/custom.php. Przez class: przechodzą TYLKO proste klasy
       (litery/cyfry/dywiz); warianty (focus:), arbitrary ([..]) i kroki .5 psują
       parser form-tagów - takie style siedzą tutaj. Wartości ramki/promienia
       podmień pod design projektu, kolory przez tokeny palety. */

    /* Ramka pól: to, czego nie da się podać przez class: (border z kryciem itd.). */
    :where(body:not(.pbwPage)) .wpcf7-form input[type="text"],
    :where(body:not(.pbwPage)) .wpcf7-form input[type="email"],
    :where(body:not(.pbwPage)) .wpcf7-form input[type="tel"],
    :where(body:not(.pbwPage)) .wpcf7-form input[type="number"],
    :where(body:not(.pbwPage)) .wpcf7-form select,
    :where(body:not(.pbwPage)) .wpcf7-form textarea {
        width: 100%;
        border: 1px solid color-mix(in srgb, currentColor 50%, transparent);
        border-radius: 0.625rem;
        background-color: transparent;
    }

    :where(body:not(.pbwPage)) .wpcf7-form input:focus,
    :where(body:not(.pbwPage)) .wpcf7-form select:focus,
    :where(body:not(.pbwPage)) .wpcf7-form textarea:focus {
        border-color: var(--color-primary-500, currentColor);
    }

    /* Obrys znika tylko przy fokusie z myszy. Z klawiatury pole dostaje :focus-visible
       z bazy (custom.css) albo własny obrys formularza (9a, 9b); samo outline: none
       zostawiłoby nowy formularz CF7 bez widocznego fokusu. */
    .wpcf7-form :is(input, select, textarea):focus:not(:focus-visible) {
        outline: none;
    }

    /* Select: bez natywnej strzałki (dubluje się z własnym SVG chevron w wrapperze .relative). */
    :where(body:not(.pbwPage)) .wpcf7-form select {
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        background-image: none;
    }

    /* Checkbox zgody: własny wygląd zamiast systemowego. Scope pod .wpcf7-acceptance,
       żeby wygrać z globalnymi regułami startera dla input[type=checkbox]. */
    :where(body:not(.pbwPage)) .wpcf7-acceptance input[type="checkbox"] {
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        width: 1.125rem;
        height: 1.125rem;
        flex-shrink: 0;
        margin-top: 0.125rem;
        border: 1px solid color-mix(in srgb, currentColor 50%, transparent);
        border-radius: 0.25rem;
        background-color: transparent;
        cursor: pointer;
    }

    :where(body:not(.pbwPage)) .wpcf7-acceptance input[type="checkbox"]:checked {
        border-color: var(--color-secondary-500, currentColor);
        background-color: var(--color-secondary-500, currentColor);
        background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3E%3C/svg%3E");
        background-size: 0.75rem;
        background-position: center;
        background-repeat: no-repeat;
    }

    /* Zerowanie marginesów wrapperów CF7 - bez tego akceptacja ma wcięcie z lewej
       i za duży odstęp od pola powyżej (odstęp reguluje klasa mt-* na kontenerze w shortcode). */
    :where(body:not(.pbwPage)) .wpcf7-list-item,
    :where(body:not(.pbwPage)) .wpcf7-form-control-wrap {
        margin: 0;
    }

    /* Wrapper pola jako blok: inline span psuje pola w gridzie i pływające etykiety (:has). */
    :where(body:not(.pbwPage)) .wpcf7-form-control-wrap {
        display: block;
    }

    /* Turnstile (tag [turnstile appearance:interaction-only]): zwykle 0 px, widget pokazuje się
       tylko, gdy Cloudflare chce interakcji, więc bez rezerwacji wysokości. Iframe siedzi w shadow
       DOM jako element inline i dziedziczy line-height: bez zera kontener ma 71 px. */
    :where(body:not(.pbwPage)) .wpcf7-turnstile {
        line-height: 0;
    }

    /* Wyrównanie checkboxa zgody z wieloliniowym tekstem zgody. */
    :where(body:not(.pbwPage)) .wpcf7-acceptance .wpcf7-list-item label {
        display: flex;
        align-items: flex-start;
        gap: 0.5rem;
        margin: 0;
    }

    /* Komunikat walidacji pod polem. */
    :where(body:not(.pbwPage)) .wpcf7-not-valid-tip {
        margin-top: 0.25rem;
        font-size: 0.75rem;
        color: #dc2626;
    }

    :where(body:not(.pbwPage)) .wpcf7-not-valid {
        border-color: #dc2626 !important;
    }

    /* Zbiorczy komunikat CF7 (sukces/błąd) pod formularzem. */
    :where(body:not(.pbwPage)) .wpcf7-response-output {
        margin: 1rem 0 0;
        padding: 0.75rem 1rem;
        border-radius: 0.5rem;
        font-size: 0.875rem;
    }

    :where(body:not(.pbwPage)) .wpcf7-spinner {
        margin-left: 0.5rem;
    }

/* === 9a. FORMULARZ WYCENY (blok offer-form + szablon CF7 wycena) ===
   Bez warstwy, jak reszta sekcji 9: nadpisuje niewarstwowy arkusz CF7 i ogólne reguły
   .wpcf7-form wyżej. Pola, grupy radio/checkbox i zgodę generuje CF7 (span.wpcf7-list-item >
   label > input + span.wpcf7-list-item-label), więc wygląd kafli i pigułek siedzi tutaj,
   a układ (odstępy, wiersze pól, przyciski) w klasach Tailwinda szablonu. Podgląd w
   blocks-zarzadzanie.html ma ten sam DOM co wynik CF7, więc reguły działają w obu miejscach. */

/* Stany modułu formsteps.js: bez JS widać wszystkie kroki jeden pod drugim i sam przycisk
   wysyłki; pasek postępu, Dalej i Wstecz mają sens dopiero z JS. */
.offerForm:not(.is-ready) :is([data-step-progress], [data-step-next], [data-step-prev]),
.offerForm:not(.is-sent) [data-step-success],
.offerForm:not(.is-failed) [data-step-fail] {
    display: none;
}

/* Osobno: przeglądarka bez :has() odrzuca całą listę selektorów, a panele sukcesu i błędu
   wyżej muszą się schować zawsze. */
.offerForm:not(.is-ready) [data-step-nav]:not(:has([type="submit"])) {
    display: none;
}

/* Z JS: po wysyłce karta znika (zostaje panel sukcesu), a zbiorczy komunikat CF7 zastępują
   panele bloku i komunikat w kroku. Selektor mocniejszy od .wpcf7 form.sent .wpcf7-response-output
   z arkusza wtyczki. Nieaktywne kroki, wstęp i postęp chowa atrybut hidden. */
.offerForm.is-sent [data-step-card],
.offerForm.is-ready .wpcf7 form .wpcf7-response-output {
    display: none;
}

/* Legenda kroku dostaje fokus programowo (tabindex -1) po zmianie kroku: to nie kontrolka. */
.offerForm legend[tabindex="-1"]:focus {
    outline: none;
}

/* Dymek błędu CF7 pod polem w kolorze komunikatu kroku (czerwień z sekcji 9 ginie na ciemnej karcie). */
.offerForm .wpcf7-not-valid-tip {
    margin-top: 0.375rem;
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--color-primary-300);
}

/* Warianty mieszkanie / dom liczone z kroku 1 (pierwsza opcja = mieszkanie, pozostałe = dom).
   Działa też bez JS; formsteps.js dokłada czyszczenie ukrytych pól i Windę. */
.offerForm:has([data-variant-source] .wpcf7-list-item:not(:first-child) input:checked) [data-variant-show="mieszkanie"],
.offerForm:not(:has([data-variant-source] .wpcf7-list-item:not(:first-child) input:checked)) [data-variant-show="dom"] {
    display: none;
}

/* Wspólne: kontrolki radio i checkbox rysowane na samym inpucie. */
.offerForm .wpcf7-list-item {
    margin: 0;
}

.offerForm .wpcf7-list-item label {
    cursor: pointer;
    color: var(--color-white);
    transition: border-color 0.3s ease;
}

.offerForm .wpcf7-list-item input[type="radio"],
.offerForm .wpcf7-list-item input[type="checkbox"] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    margin: 0;
    border: 2px solid var(--color-white);
    background-color: transparent;
    cursor: pointer;
    transition: border-color 0.2s ease, border-width 0.2s ease, background-color 0.2s ease;
}

.offerForm .wpcf7-list-item input[type="radio"] {
    border-radius: 50%;
}

.offerForm .wpcf7-list-item input[type="radio"]:checked {
    border-width: 5px;
    border-color: var(--color-secondary-500);
}

.offerForm .wpcf7-list-item input[type="checkbox"] {
    border-radius: 2px;
}

.offerForm .wpcf7-list-item input[type="checkbox"]:checked {
    border-color: var(--color-secondary-500);
    background-color: var(--color-secondary-500);
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3E%3C/svg%3E");
    background-size: 0.75rem;
    background-position: center;
    background-repeat: no-repeat;
}

.offerForm .wpcf7-list-item input:focus-visible {
    outline: 2px solid var(--color-secondary-500);
    outline-offset: 2px;
}

/* Kafle i pigułki: ramka, hover, zaznaczenie. */
.offerForm :is(.offerTiles, .offerPills, .offerChecks) .wpcf7-list-item label {
    border: 1px solid var(--color-ink-600);
    border-radius: 0.625rem;
}

.offerForm :is(.offerTiles, .offerPills, .offerChecks) .wpcf7-list-item label:hover {
    border-color: var(--color-ink-500);
}

.offerForm :is(.offerTiles, .offerPills, .offerChecks) .wpcf7-list-item label:has(input:checked) {
    border-color: var(--color-secondary-500);
}

/* Krok 1: kafle z ikonami (ikona = tło ::before, kolejność jak opcje w tagu CF7). */
.offerForm .offerTiles .wpcf7-form-control {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.offerForm .offerTiles .wpcf7-list-item {
    margin-bottom: 5px;
}

.offerForm .offerTiles .wpcf7-list-item label {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 86px;
    padding: 0.625rem 1.25rem 0.625rem 6.75rem;
    font-size: 0.875rem;
    line-height: 1.25rem;
}

.offerForm .offerTiles .wpcf7-list-item label::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 3.75rem;
    width: 2rem;
    height: 2rem;
    transform: translateY(-50%);
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
}

.offerForm .offerTiles .wpcf7-list-item:nth-child(1) label::before {
    background-image: url("../../inc/img/formularz-ikona-mieszkanie.svg");
}

.offerForm .offerTiles .wpcf7-list-item:nth-child(2) label::before {
    background-image: url("../../inc/img/formularz-ikona-dom.svg");
}

.offerForm .offerTiles .wpcf7-list-item:nth-child(3) label::before {
    background-image: url("../../inc/img/formularz-ikona-szeregowka.svg");
}

.offerForm .offerTiles .wpcf7-list-item input {
    position: absolute;
    top: 50%;
    left: 1rem;
    margin-top: -0.5rem;
}

/* Łamanie po pierwszym słowie jak w Webflow; druga para słów spięta twardą spacją w etykiecie. */
.offerForm .offerTiles .wpcf7-list-item-label {
    max-width: 7.5em;
}

/* Od 768 kafle w rzędzie z zawijaniem, wymiary z Webflow (ikona 48, tekst 14, od 992 tekst 16).
   Webflow ma rząd od 480, ale 480-767 Zarządzania to u nas świadomie układ mobilny. Przy 768-800
   zostają 2 + 1 jak w Webflow, na 880 Webflow ściskał 3 kafle i gubił ikony, u nas zawijają się.
   min-width: 0, bo etykiety z twardą spacją rozpychały rząd poza ekran. */
@media (min-width: 48rem) {
    .offerForm .offerTiles .wpcf7-form-control {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .offerForm .offerTiles .wpcf7-list-item {
        flex: 1 1 14rem;
        min-width: 0;
    }

    .offerForm .offerTiles .wpcf7-list-item label {
        height: 100%;
        min-height: 106px;
        padding: 0.75rem 1.25rem 0.75rem 7.25rem;
    }

    .offerForm .offerTiles .wpcf7-list-item label::before {
        left: 3.25rem;
        width: 3rem;
        height: 3rem;
    }

    .offerForm .offerTiles .wpcf7-list-item input {
        top: 0.75rem;
        left: 0.75rem;
        margin-top: 0;
    }
}

@media (min-width: 62rem) {
    .offerForm .offerTiles .wpcf7-list-item label {
        font-size: 1rem;
    }
}

@media (min-width: 80rem) {
    .offerForm .offerTiles .wpcf7-form-control {
        width: 80%;
    }
}

/* Kroki 2-5: pigułki w rzędzie z zawijaniem. Krok 7: te same pigułki w kolumnie. */
.offerForm :is(.offerPills, .offerChecks) .wpcf7-form-control {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.offerForm .offerChecks .wpcf7-form-control {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: flex-start;
    gap: 0.625rem;
}

.offerForm :is(.offerPills, .offerChecks) .wpcf7-list-item label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.375rem 0.75rem;
    font-size: 0.75rem;
    line-height: 1.125rem;
}

.offerForm .offerPills .wpcf7-radio .wpcf7-list-item label {
    gap: 0.625rem;
    padding: 0.5rem 1.125rem 0.5rem 0.625rem;
    line-height: 1.25rem;
}

@media (min-width: 30rem) {
    .offerForm :is(.offerPills, .offerChecks) .wpcf7-list-item label {
        gap: 0.625rem;
        padding: 0.375rem 0.625rem;
        font-size: 0.875rem;
        line-height: 1.25rem;
    }

    .offerForm .offerPills .wpcf7-radio .wpcf7-list-item label {
        padding: 0.5rem 1.125rem 0.5rem 0.625rem;
    }
}

/* Zgoda: bez ramki, kwadrat jak w pigułkach. Selektory mocniejsze od ogólnej zgody CF7 wyżej. */
.offerForm .offerConsent .wpcf7-acceptance .wpcf7-list-item label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: fit-content;
    margin: 0;
    /* Prawy margines 25 px odtwarza łamanie tekstu zgody z Webflow na telefonie. */
    padding: 0.375rem 1.5625rem 0.375rem 0.75rem;
    font-size: 0.75rem;
    line-height: 1.125rem;
}

.offerForm .offerConsent .wpcf7-acceptance input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    margin-top: 0;
    border: 2px solid var(--color-white);
    border-radius: 2px;
}

@media (min-width: 30rem) {
    .offerForm .offerConsent .wpcf7-acceptance .wpcf7-list-item label {
        gap: 0.625rem;
        padding: 0.375rem 0 0.375rem 0.625rem;
        font-size: 0.875rem;
        line-height: 1.25rem;
    }
}

/* Pola tekstowe i wiadomość: białe pola Webflow z zaokrągleniem 10 px. */
.offerForm .wpcf7-form-control-wrap :is(input[type="text"], input[type="email"], input[type="tel"], textarea) {
    display: block;
    width: 100%;
    min-height: 50px;
    margin: 0;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-ink-200);
    border-radius: 0.625rem;
    background-color: var(--color-white);
    color: var(--color-ink-700);
    font-size: 0.875rem;
    line-height: 1.25rem;
    transition: border-color 0.2s ease;
}

.offerForm .wpcf7-form-control-wrap textarea.wpcf7-textarea {
    min-height: 80px;
    padding: 0.75rem 1.25rem 1.25rem;
    color: var(--color-ink-800);
    resize: vertical;
}

.offerForm .wpcf7-form-control-wrap :is(input, textarea)::placeholder {
    color: var(--color-ink-400);
}

.offerForm .wpcf7-form-control-wrap :is(input[type="text"], input[type="email"], input[type="tel"], textarea):focus {
    outline: none;
    border-color: var(--color-secondary-500);
    box-shadow: none;
}

/* Zmiana ramki 1 px na białym polu to za słaby fokus z klawiatury: obrys na ciemnej karcie. */
.offerForm .wpcf7-form-control-wrap :is(input[type="text"], input[type="email"], input[type="tel"], textarea):focus-visible {
    outline: 2px solid var(--color-secondary-500);
    outline-offset: 2px;
}

/* Pole oznaczone przez formsteps.js po nieudanym Dalej (przed walidacją serwera CF7). */
.offerForm .wpcf7-form-control-wrap :is(input, textarea)[data-step-invalid] {
    border-color: var(--color-primary-300);
}

/* === 9b. FORMULARZ KONTAKTOWY (blok contact-main + szablon CF7 kontakt) ===
   Bez warstwy, jak 9 i 9a: nadpisuje niewarstwowy arkusz CF7 i ogólne reguły sekcji 9.
   Jasne pola Webflow (białe tło, ramka ink-200, zaokrąglenie 10 px, wysokość 50 px), zgoda
   i fokus w primary-500. Układ (odstępy, telefon i e-mail w rzędzie od 768) siedzi w klasach
   Tailwinda szablonu. Podgląd w blocks-kontakt.html ma ten sam DOM co wynik CF7, więc reguły
   pól działają w obu miejscach; reguły stanów wymagają form.wpcf7-form, czyli tylko front.
   Stany CF7 (klasa na <form>): submitting = przycisk z tekstem „Wysyłanie...", sent = pola
   znikają i zostaje komunikat jak w Webflow, failed / spam / aborted / invalid / unaccepted =
   komunikat pod formularzem. Zdarzenie form_send do GTM wysyła custom.js (sekcja 4). */

.contactForm .wpcf7-form-control-wrap :is(input[type="text"], input[type="email"], input[type="tel"], textarea) {
    display: block;
    width: 100%;
    min-height: 50px;
    margin: 0;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--color-ink-200);
    border-radius: 0.625rem;
    background-color: var(--color-white);
    color: var(--color-ink-800);
    font-size: 0.875rem;
    line-height: 1.25rem;
    transition: border-color 0.2s ease;
}

/* Selektor mocniejszy od reguły pól wyżej (min-height 50 px). */
.contactForm .wpcf7-form-control-wrap textarea.wpcf7-textarea {
    min-height: 160px;
    resize: vertical;
}

.contactForm .wpcf7-form-control-wrap :is(input, textarea)::placeholder {
    color: var(--color-ink-400);
}

.contactForm .wpcf7-form-control-wrap :is(input[type="text"], input[type="email"], input[type="tel"], textarea):focus {
    outline: none;
    border-color: var(--color-primary-500);
    box-shadow: none;
}

/* Sama zmiana ramki 1 px to za słaby fokus z klawiatury. */
.contactForm .wpcf7-form-control-wrap :is(input[type="text"], input[type="email"], input[type="tel"], textarea):focus-visible {
    outline: 2px solid var(--color-primary-500);
    outline-offset: 2px;
}

/* Sekcja 9 ma tu !important z czerwienią spoza palety. */
.contactForm .wpcf7-not-valid {
    border-color: var(--color-primary-500) !important;
}

.contactForm .wpcf7-not-valid-tip {
    margin-top: 0.25rem;
    font-size: 0.75rem;
    line-height: 1rem;
    color: var(--color-primary-500);
}

/* Zgoda: kwadrat 16 px z ramką 2 px, wcięcie 12 px i odstęp 12 px na telefonie, 10 px od 480
   (1:1 z Webflow). Klikalna cała etykieta z tekstem. */
.contactForm .contactConsent .wpcf7-acceptance .wpcf7-list-item label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0.375rem 0 0.375rem 0.75rem;
    font-size: 0.75rem;
    line-height: 1.125rem;
    color: var(--color-ink-800);
    cursor: pointer;
}

.contactForm .contactConsent .wpcf7-acceptance input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    margin: 0;
    border: 2px solid var(--color-ink-800);
    border-radius: 2px;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.contactForm .contactConsent .wpcf7-acceptance input[type="checkbox"]:checked {
    border-color: var(--color-primary-500);
    background-color: var(--color-primary-500);
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3E%3C/svg%3E");
    background-size: 0.75rem;
    background-position: center;
    background-repeat: no-repeat;
}

.contactForm .contactConsent .wpcf7-acceptance input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--color-primary-500);
    outline-offset: 2px;
}

@media (min-width: 30rem) {
    .contactForm .contactConsent .wpcf7-acceptance .wpcf7-list-item label {
        align-items: flex-start;
        gap: 0.625rem;
        padding-left: 0.625rem;
        line-height: 1.25rem;
    }

    .contactForm .contactConsent .wpcf7-acceptance input[type="checkbox"] {
        margin-top: 0.125rem;
    }
}

/* Przycisk w trakcie wysyłki (Webflow: data-wait). Raw <button> nie dostaje spinnera CF7. */
.contactForm .contactSubmitBusy {
    display: none;
}

.contactForm .wpcf7 form.submitting .contactSubmitIdle {
    display: none;
}

.contactForm .wpcf7 form.submitting .contactSubmitBusy {
    display: inline;
}

.contactForm .wpcf7 form.submitting button[type="submit"] {
    opacity: 0.7;
    pointer-events: none;
}

/* Komunikaty: błąd pod formularzem (Webflow w-form-fail), sukces zamiast pól (w-form-done).
   Selektory mocniejsze od .wpcf7 form.{stan} .wpcf7-response-output z arkusza CF7. */
.contactForm .wpcf7 form .wpcf7-response-output {
    margin: 0.625rem 0 0;
    padding: 0.625rem;
    border: 0;
    border-radius: 0;
    background-color: var(--color-primary-50);
    color: var(--color-ink-800);
    font-size: 0.875rem;
    line-height: 1.25rem;
}

.contactForm .wpcf7 form.sent .contactFields {
    display: none;
}

.contactForm .wpcf7 form.sent .wpcf7-response-output {
    margin: 0;
    padding: 1.25rem;
    background-color: var(--color-ink-100);
    text-align: center;
}
