/*
 * IntegraTPS.Portal — tokeny stylu i layout bazowy.
 * Prefiks klas: .pt-*. Bez frameworka JS / CSS (Tailwind itp.) — czysty CSS na tokenach.
 * Responsywność przez flex-wrap / grid auto-fit, @media tylko dla wyjątków.
 *
 * Visual uplift (patrz docs uplift-brief): tokeny gradientu/cieni/ruchu poniżej, warstwa motion,
 * sygnatura "sloty terminarza" (.pt-slots) i font display Schibsted Grotesk — WSZYSTKO wyłączane
 * przez prefers-reduced-motion (sekcja "Motion" niżej) i musi mieć odpowiedniki w OBU motywach
 * (żaden kolor zdefiniowany tylko w bloku dark!).
 */

/* Font display — Schibsted Grotesk (OFL, Google Fonts), pobrany lokalnie do wwwroot/fonts (zero CDN).
   Wagi 500/700/800 jako plik wariable-font (Google serwuje ten sam plik dla kilku wag — przeglądarka
   dopasowuje oś "wght" do zadeklarowanej wagi @font-face). Fallback: stos systemowy, font-display:swap
   (brak przeskoku layoutu przy wolnym FOFT — waga systemowa i Schibsted mają zbliżoną szerokość). */
@font-face {
    font-family: 'Schibsted Grotesk';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url('/fonts/schibsted-grotesk-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: 'Schibsted Grotesk';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url('/fonts/schibsted-grotesk-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;
}

:root {
    --pt-bg: #eef1f6;
    --pt-card: #ffffff;
    --pt-border: #dfe4ee;
    --pt-text: #1c2434;
    --pt-muted: #5b6479;
    --pt-accent: #26406e;
    --pt-accent-h: color-mix(in srgb, var(--pt-accent) 85%, black);
    --pt-accent-contrast: #ffffff;
    --pt-hero: #f5f7fb;

    --pt-pill: #e7ebf3;
    --pt-pillfg: #33415c;

    --pt-ok: #1c7c4d;
    --pt-okbg: #e1f4e9;

    --pt-warn: #92400e;
    --pt-warnbg: #fef3c7;

    --pt-radius-card: 12px;
    --pt-radius-field: 8px;
    --pt-radius-pill: 999px;

    --pt-shadow: 0 1px 2px rgba(15, 23, 42, .05);

    /* Uplift: stopnie granatu do gradientu hero/CTA, cienie warstwowe, easing/motion, tinty. */
    --pt-accent-deep: #1b2f52;
    --pt-accent-2: #3f6ab0;
    --pt-grad: linear-gradient(135deg, var(--pt-accent-deep), var(--pt-accent) 55%, var(--pt-accent-2));
    --pt-shadow-sm: 0 1px 2px rgba(15, 23, 42, .05);
    --pt-shadow-md: 0 4px 14px rgba(15, 23, 42, .09);
    --pt-shadow-lg: 0 12px 32px rgba(15, 23, 42, .14);
    --pt-ease: cubic-bezier(.2, .7, .3, 1);
    --pt-t-fast: 160ms;
    --pt-t-med: 280ms;
    /* Tylko dla zoomu obrazków w kafelkach/galerii (pkt 4 iteracji "mikro-interakcje") — reszta
       portalu zostaje na t-fast/t-med, ten token celowo nie jest używany nigdzie indziej. */
    --pt-t-slow: 500ms;
    --pt-tint: color-mix(in srgb, var(--pt-accent) 8%, transparent);
    --pt-chip: color-mix(in srgb, var(--pt-accent) 12%, transparent);

    --pt-font-display: 'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
    :root {
        --pt-bg: #0e1424;
        --pt-card: #161d31;
        --pt-border: #28324b;
        --pt-text: #e7ebf4;
        --pt-muted: #9aa5bb;
        --pt-accent: #5f7fb8;
        --pt-accent-h: color-mix(in srgb, var(--pt-accent) 85%, white);
        --pt-accent-contrast: #0e1424;
        --pt-hero: #141b2e;

        --pt-pill: #202940;
        --pt-pillfg: #c7d1e6;

        --pt-ok: #34d399;
        --pt-okbg: #10301f;

        --pt-warn: #fbbf24;
        --pt-warnbg: #3a2a0a;

        /* Uplift dark: stopnie gradientu przesunięte ciemniej/jaśniej dla kontrastu na ciemnym tle,
           cienie z mocniejszą alfą (widoczne na ciemnym tle), tint/chip przez color-mix z dark accent. */
        --pt-accent-deep: #0a1730;
        --pt-accent-2: #7fa0d9;
        --pt-shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
        --pt-shadow-md: 0 4px 14px rgba(0, 0, 0, .45);
        --pt-shadow-lg: 0 12px 32px rgba(0, 0, 0, .55);
        --pt-tint: color-mix(in srgb, var(--pt-accent) 14%, transparent);
        --pt-chip: color-mix(in srgb, var(--pt-accent) 20%, transparent);
    }
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

html, body {
    margin: 0;
    padding: 0;
}

body.pt-body {
    background: var(--pt-bg);
    color: var(--pt-text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-size: 15px;
    line-height: 1.5;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

a {
    color: var(--pt-accent);
}

h1, h2, h3 {
    font-family: var(--pt-font-display);
    text-wrap: balance;
}

/* Focus visible — jeden wzorzec w całym portalu (ring 2px accent, offset 2px). Domyślny outline
   usuwany tylko gdy :focus-visible jest wspierane (nie dla starych przeglądarek — degradacja miękka). */
:focus-visible {
    outline: 2px solid var(--pt-accent);
    outline-offset: 2px;
    border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

.pt-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

.pt-main {
    flex: 1 0 auto;
}

.pt-page {
    padding: 32px 20px;
}

.pt-muted-text {
    color: var(--pt-muted);
    /* Opis stanowiska/usługi bez NadpiszOpis bywa wielolinijkowy (pierwsza linia = tekst kafla,
       reszta = długi opis - konwencja kafli ai_rs, patrz Station.OpisNaKaflu) - bez pre-line obie
       części sklejają się w jedną linię (patrz odpowiednik .ibsl-mutedtext w edytorze sekcji). */
    white-space: pre-line;
}

/* ==========================================================================
   Motion — warstwa globalna. Wszystko wyłączone pod prefers-reduced-motion:
   reduce (reguła na końcu pliku wyłącza transitions/animations wszędzie).
   ========================================================================== */

.pt-card,
.pt-tile,
.pt-result-card,
.pt-category-card,
.pt-step-card {
    transition: transform var(--pt-t-med) var(--pt-ease), box-shadow var(--pt-t-med) var(--pt-ease), border-color var(--pt-t-med) var(--pt-ease);
}

a.pt-card:hover,
a.pt-card:focus-visible,
.pt-tile:hover,
.pt-tile:focus-within,
.pt-result-card:hover,
.pt-result-card:focus-within,
.pt-category-card:hover,
.pt-category-card:focus-visible,
.pt-step-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--pt-shadow-md);
    /* Delikatny akcent na hover kart (feedback iteracji: hover "surowy/zbyt techniczny") -
       tylko lekki tint tła + obrys w stronę accent, bez zmiany całego koloru karty. */
    border-color: color-mix(in srgb, var(--pt-accent) 35%, var(--pt-border));
    background: color-mix(in srgb, var(--pt-accent) 3%, var(--pt-card));
}

.pt-btn {
    transition: background-color var(--pt-t-fast) var(--pt-ease), background-position var(--pt-t-fast) var(--pt-ease), border-color var(--pt-t-fast) var(--pt-ease), box-shadow var(--pt-t-fast) var(--pt-ease), transform var(--pt-t-fast) var(--pt-ease), color var(--pt-t-fast) var(--pt-ease);
}

.pt-btn:hover {
    box-shadow: var(--pt-shadow-sm);
}

.pt-btn:active {
    transform: scale(.98);
}

.pt-btn--primary:hover,
.pt-btn--primary:focus-visible {
    background-position: 100% 0%;
    border-color: var(--pt-accent-h);
}

.pt-field input,
.pt-field select {
    transition: border-color var(--pt-t-fast) var(--pt-ease), box-shadow var(--pt-t-fast) var(--pt-ease);
}

.pt-field input:focus,
.pt-field select:focus {
    outline: none;
    border-color: var(--pt-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--pt-accent) 18%, transparent);
}

/* Reveal-on-scroll: klasa dodawana od razu w markupie (.pt-reveal), portal.js dopisuje .is-in
   przez IntersectionObserver (raz, threshold .12). Bez JS / bez IO / reduced-motion → stan
   końcowy natychmiast (patrz portal.js i reguła reduced-motion niżej), więc treść NIGDY nie
   zostaje trwale ukryta gdy skrypt się nie wykona. */
.pt-reveal {
    opacity: 0;
    transform: translateY(14px);
    /* filter:blur dodany w iteracji mikro-interakcji (pkt 6) - hero jest w viewport od razu przy
       wejściu, więc to głównie TAM widać efekt "wyostrzenia" przy pierwszym renderze. */
    filter: blur(4px);
    transition: opacity var(--pt-t-med) var(--pt-ease), transform var(--pt-t-med) var(--pt-ease), filter var(--pt-t-med) var(--pt-ease);
}

.pt-reveal.is-in {
    opacity: 1;
    transform: none;
    filter: none;
}

.pt-reveal[data-d="1"] { transition-delay: 60ms; }
.pt-reveal[data-d="2"] { transition-delay: 120ms; }
.pt-reveal[data-d="3"] { transition-delay: 180ms; }
.pt-reveal[data-d="4"] { transition-delay: 240ms; }

/* Header: sticky + cień/tło po scrollu (klasa .is-scrolled, patrz portal.js). */
.pt-header {
    position: sticky;
    top: 0;
    z-index: 40;
    transition: box-shadow var(--pt-t-med) var(--pt-ease), background-color var(--pt-t-med) var(--pt-ease);
}

.pt-header.is-scrolled {
    box-shadow: var(--pt-shadow-md);
    background: var(--pt-card);
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }

    .pt-reveal {
        opacity: 1;
        transform: none;
        filter: none;
    }

    a.pt-card:hover, .pt-tile:hover, .pt-result-card:hover, .pt-category-card:hover, .pt-step-card:hover {
        transform: none;
    }

    /* Nowe transform-y z iteracji mikro-interakcji (pkt 2/5) - te same guardy co karty wyżej,
       żeby reduced-motion nie zostawił niczego "przyklejonego" w stanie hover. */
    .pt-category-card:hover .pt-category-icon,
    .pt-category-card:hover .pt-chip,
    .pt-step-card:hover .pt-category-icon,
    .pt-step-card:hover .pt-chip,
    .pt-social-btn:hover,
    .pt-tag-chip:hover {
        transform: none;
    }
}

/* ==========================================================================
   Sygnatura "sloty terminarza" (.pt-slots) — rząd małych prostokątów, część
   wypełniona accent/accent-2. CICHA (mono-hue, mała) — sygnatura, nie konfetti.
   Warianty: --hero (duże sloty pod H1, animacja wypełniania), --mini (eyebrow
   sekcji), badge terminu ma własne mikro-sloty przez ::before/::after (niżej).
   ========================================================================== */

.pt-slots {
    display: inline-flex;
    gap: 4px;
    align-items: center;
}

.pt-slots__cell {
    width: 10px;
    height: 14px;
    border-radius: 3px;
    border: 1.5px solid color-mix(in srgb, var(--pt-accent) 45%, transparent);
    background: transparent;
}

.pt-slots__cell.is-filled {
    background: var(--pt-accent-2);
    border-color: var(--pt-accent-2);
}

.pt-slots--hero .pt-slots__cell {
    border-color: rgba(255, 255, 255, .45);
}

.pt-slots--hero .pt-slots__cell.is-filled {
    background: rgba(255, 255, 255, .85);
    border-color: rgba(255, 255, 255, .85);
}

.pt-slots--mini .pt-slots__cell {
    width: 6px;
    height: 9px;
    border-radius: 2px;
}

/* Animacja wypełniania kolejnych slotów hero — jednorazowa (steps, 1x), tylko slot już
   oznaczony .is-filled dostaje "wjazd"; reszta zostaje statycznym obrysem. Kolejność przez
   nth-child, bez potrzeby inline style / JS. Reduced-motion wyłącza (reguła wyżej zeruje czas
   animacji, więc końcowy stan .is-filled jest widoczny natychmiast). */
.pt-slots--animated .pt-slots__cell.is-filled {
    animation: pt-slot-fill var(--pt-t-fast) var(--pt-ease) both;
}

.pt-slots--animated .pt-slots__cell:nth-child(1).is-filled { animation-delay: 40ms; }
.pt-slots--animated .pt-slots__cell:nth-child(2).is-filled { animation-delay: 120ms; }
.pt-slots--animated .pt-slots__cell:nth-child(3).is-filled { animation-delay: 200ms; }
.pt-slots--animated .pt-slots__cell:nth-child(4).is-filled { animation-delay: 280ms; }
.pt-slots--animated .pt-slots__cell:nth-child(5).is-filled { animation-delay: 360ms; }
.pt-slots--animated .pt-slots__cell:nth-child(6).is-filled { animation-delay: 440ms; }
.pt-slots--animated .pt-slots__cell:nth-child(7).is-filled { animation-delay: 520ms; }
.pt-slots--animated .pt-slots__cell:nth-child(8).is-filled { animation-delay: 600ms; }

@keyframes pt-slot-fill {
    from { transform: scaleY(.35); opacity: .4; }
    to { transform: scaleY(1); opacity: 1; }
}

/* Header */

.pt-header {
    border-bottom: 1px solid var(--pt-border);
    background: var(--pt-card);
}

.pt-header-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    padding: 14px 20px;
}

.pt-logo {
    display: flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    font-weight: 800;
    font-family: var(--pt-font-display);
    font-size: 17px;
    color: var(--pt-text);
}

.pt-logo-mark {
    width: 30px;
    height: 30px;
    border-radius: var(--pt-radius-field);
    background: var(--pt-grad);
    flex: 0 0 auto;
}

.pt-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    margin-right: auto;
}

/* Podkreślenie animowane na hover/focus (feedback iteracji: hover "surowy/zbyt techniczny") -
   ten sam wzorzec co scrollspy .pt-firm-nav-links (pseudo-element, scaleX(0)->scaleX(1), niżej),
   tu sterowany czystym CSS :hover/:focus-visible zamiast klasy z JS. Kolor sam nie wystarcza
   jako jedyny sygnał, więc zostaje obok podkreślenia. */
.pt-nav a {
    position: relative;
    display: inline-block;
    padding-bottom: 2px;
    color: var(--pt-text);
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    transition: color var(--pt-t-fast) var(--pt-ease);
}

.pt-nav a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--pt-accent);
    border-radius: 1px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--pt-t-fast) var(--pt-ease);
}

.pt-nav a:hover,
.pt-nav a:focus-visible {
    color: var(--pt-accent);
}

.pt-nav a:hover::after,
.pt-nav a:focus-visible::after {
    transform: scaleX(1);
}

.pt-login-link {
    position: relative;
    display: inline-block;
    padding-bottom: 2px;
    font-size: 14px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--pt-t-fast) var(--pt-ease);
}

.pt-login-link::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--pt-accent);
    border-radius: 1px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--pt-t-fast) var(--pt-ease);
}

.pt-login-link:hover,
.pt-login-link:focus-visible {
    color: var(--pt-accent);
}

.pt-login-link:hover::after,
.pt-login-link:focus-visible::after {
    transform: scaleX(1);
}

/* Cards */

.pt-card {
    background: var(--pt-card);
    border: 1px solid var(--pt-border);
    border-radius: var(--pt-radius-card);
    box-shadow: var(--pt-shadow);
    padding: 24px;
}

/* Buttons */

.pt-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 18px;
    border-radius: var(--pt-radius-field);
    border: 1px solid var(--pt-border);
    background: var(--pt-card);
    color: var(--pt-text);
    font-size: 14px;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
}

.pt-btn:hover {
    border-color: var(--pt-accent);
}

/* Gradient-shift zamiast płaskiej zmiany tła na hover (feedback iteracji: hover "surowy") -
   dwustopniowy gradient accent->accent-h szerszy niż przycisk (150%), hover przesuwa
   background-position zamiast podmieniać kolor (płynne "przelanie" zamiast cięcia). Osobny,
   prostszy gradient niż --pt-grad (3 stopy pod 135deg, pomyślany pod duże tła hero/CTA) -
   na wąskim przycisku dawałby za mało miejsca na czytelne przesunięcie. */
.pt-btn--primary {
    background-color: var(--pt-accent);
    background-image: linear-gradient(90deg, var(--pt-accent), var(--pt-accent-h));
    background-size: 150% 100%;
    background-position: 0% 0%;
    border-color: var(--pt-accent);
    color: var(--pt-accent-contrast);
}

/* Grid */

.pt-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 16px;
}

/* Badge */

.pt-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    border-radius: var(--pt-radius-pill);
    background: var(--pt-pill);
    color: var(--pt-pillfg);
    font-size: 12.5px;
    font-weight: 700;
}

.pt-badge--ok {
    background: var(--pt-okbg);
    color: var(--pt-ok);
}

.pt-badge--warn {
    background: var(--pt-warnbg);
    color: var(--pt-warn);
}

/* Cechy/udogodnienia stanowiska (Iteracja 4, pkt C.2) - mini-pigułki pod opisem, sam token
   --pt-pill/--pt-pillfg co .pt-tag-chip (jeden wzorzec pigułki tekstowej w portalu). */
.pt-feature-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.pt-feature-pill {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: var(--pt-radius-pill);
    background: var(--pt-pill);
    color: var(--pt-pillfg);
    font-size: 12px;
    font-weight: 600;
}

/* Uwagi/wymagania usługi (Iteracja 4, pkt C.3) - drobny tekst z ikoną info pod opisem usługi. */
.pt-note {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    font-size: 13px;
    color: var(--pt-muted);
}

.pt-note .pt-icon {
    flex: none;
    width: 16px;
    height: 16px;
    margin-top: 1px;
}

/* "Co obejmuje" jako lista (Iteracja 4, pkt C.4) - zamiennik pojedynczego akapitu Opis, gdy
   TextHelpers.SplitList wykryje separator ";"/nowa linia - czyste wykrywanie prezentacyjne. */
.pt-list-check {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.pt-list-check li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 14px;
    color: var(--pt-muted);
}

.pt-list-check .pt-icon {
    flex: none;
    width: 16px;
    height: 16px;
    margin-top: 2px;
    color: var(--pt-ok);
}

/* Eyebrow nagłówka sekcji (landing): mini-sloty + label uppercase. Współdzielony wzorzec dla
   wszystkich sekcji landingu — jeden format nagłówka w całym portalu (patrz zasada "jeden
   wzorzec na problem"). */
.pt-eyebrow {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}

.pt-eyebrow-label {
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--pt-accent);
}

/* Footer */

.pt-footer {
    border-top: 1px solid var(--pt-border);
    background: var(--pt-card);
    margin-top: 40px;
}

.pt-footer-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 26px;
    padding: 32px 20px 20px;
}

.pt-footer-col {
    flex: 1 1 200px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pt-footer-col h3 {
    margin: 0 0 4px;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--pt-muted);
}

.pt-footer-col a {
    position: relative;
    display: inline-block;
    width: fit-content;
    padding-bottom: 2px;
    color: var(--pt-text);
    text-decoration: none;
    font-size: 14px;
    transition: color var(--pt-t-fast) var(--pt-ease);
}

/* Ten sam wzorzec podkreślenia scaleX co .pt-nav a wyżej (pkt 1 mikro-interakcji) - width:fit-content
   na kotwicy, żeby pasek podkreślenia trzymał się szerokości tekstu, nie całej rozciągniętej
   kolumny flex (bez tego left:0/right:0 rozciąga się na całą szerokość .pt-footer-col). */
.pt-footer-col a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--pt-accent);
    border-radius: 1px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--pt-t-fast) var(--pt-ease);
}

.pt-footer-col a:hover,
.pt-footer-col a:focus-visible {
    color: var(--pt-accent);
}

.pt-footer-col a:hover::after,
.pt-footer-col a:focus-visible::after {
    transform: scaleX(1);
}

.pt-footer-bottom {
    padding: 14px 20px 24px;
    font-size: 12.5px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

/* ==========================================================================
   Strona główna: hero + wyszukiwarka + kafle kategorii + wyróżnione firmy
   ========================================================================== */

.pt-hero-home {
    position: relative;
    background: var(--pt-grad);
    color: #fff;
    padding: 64px 20px 96px;
    text-align: center;
    overflow: hidden;
}

/* Subtelny pattern slotów w tle hero — SVG data-uri, bardzo niska opacity (.06), czysto
   dekoracyjny (aria-hidden na kontenerze tekstu nie jest potrzebny, tło nie niesie treści). */
.pt-hero-home::before {
    content: "";
    position: absolute;
    inset: 0;
    opacity: .06;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='56' viewBox='0 0 96 56'%3E%3Cg fill='none' stroke='white' stroke-width='2'%3E%3Crect x='4' y='8' width='10' height='16' rx='2'/%3E%3Crect x='22' y='8' width='10' height='16' rx='2'/%3E%3Crect x='40' y='8' width='10' height='16' rx='2'/%3E%3Crect x='58' y='8' width='10' height='16' rx='2'/%3E%3Crect x='76' y='8' width='10' height='16' rx='2'/%3E%3Crect x='4' y='32' width='10' height='16' rx='2'/%3E%3Crect x='22' y='32' width='10' height='16' rx='2'/%3E%3Crect x='40' y='32' width='10' height='16' rx='2'/%3E%3Crect x='58' y='32' width='10' height='16' rx='2'/%3E%3Crect x='76' y='32' width='10' height='16' rx='2'/%3E%3C/g%3E%3C/svg%3E");
    background-size: 220px 128px;
    pointer-events: none;
}

.pt-hero-home > * {
    position: relative;
}

.pt-hero-home .pt-slots {
    justify-content: center;
    margin: 0 0 18px;
}

.pt-hero-home h1 {
    margin: 0 0 12px;
    font-size: clamp(28px, 4.4vw, 52px);
    line-height: 1.08;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.pt-hero-home .pt-muted-text {
    margin: 0 auto 30px;
    max-width: 640px;
    font-size: 16px;
    color: rgba(255, 255, 255, .82);
}

/* Karta wyszukiwarki "na styku" hero/treści — margines ujemny wciąga ją częściowo w hero,
   cień mocniejszy (lg) bo unosi się nad gradientem. Szerokość dostosowana do wspólnego kontenera. */
.pt-search-card {
    max-width: 1200px;
    margin: 0 auto -56px;
    text-align: left;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-end;
    border-radius: 14px;
    box-shadow: var(--pt-shadow-lg);
    color: var(--pt-text);
    padding: 0 20px;
}

.pt-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1 1 200px;
}

.pt-field label {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--pt-muted);
}

.pt-field input,
.pt-field select {
    height: 40px;
    padding: 0 12px;
    border-radius: var(--pt-radius-field);
    border: 1px solid var(--pt-border);
    background: var(--pt-bg);
    color: var(--pt-text);
    font-size: 14px;
}

.pt-search-card .pt-btn--primary {
    flex: 0 0 auto;
    height: 40px;
}

.pt-section {
    padding: 40px 20px;
}

/* Sekcja na styku z hero (kategorie) potrzebuje dodatkowego odstępu od góry, bo karta
   wyszukiwarki zachodzi na nią ujemnym marginesem. */
.pt-section--after-hero {
    padding-top: 96px;
}

.pt-section h2 {
    margin: 0 0 20px;
    font-size: 22px;
    font-weight: 800;
}

.pt-section-head {
    text-align: center;
    max-width: 640px;
    margin: 0 auto 28px;
}

.pt-section-head h2 {
    margin: 0;
}

.pt-section-head .pt-eyebrow {
    justify-content: center;
}

.pt-category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
    gap: 14px;
}

.pt-category-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    text-align: center;
    text-decoration: none;
    color: var(--pt-text);
    background: var(--pt-card);
    border: 1px solid var(--pt-border);
    border-radius: var(--pt-radius-card);
    padding: 22px 12px;
}

/* border-color na hover .pt-category-card idzie teraz ze wspólnej reguły kart (color-mix,
   sekcja "Motion" wyżej) - nie duplikujemy tu innej wartości, żeby nie kolidować w kaskadzie. */

.pt-category-icon,
.pt-chip {
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: var(--pt-chip);
    color: var(--pt-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform var(--pt-t-fast) var(--pt-ease), background-color var(--pt-t-fast) var(--pt-ease);
}

/* Chip/ikona rośnie i mocniej się tintuje gdy hover/focus trafia w kartę-rodzica (kategoria,
   krok "jak to działa") - ten sam wzorzec co .pt-social-btn niżej (Kontakt), bo to
   strukturalnie ta sama pigułka-ikona 44x44. */
.pt-category-card:hover .pt-category-icon,
.pt-category-card:focus-visible .pt-category-icon,
.pt-category-card:hover .pt-chip,
.pt-category-card:focus-visible .pt-chip,
.pt-step-card:hover .pt-category-icon,
.pt-step-card:hover .pt-chip {
    transform: scale(1.08);
    background: color-mix(in srgb, var(--pt-accent) 20%, transparent);
}

.pt-icon {
    width: 22px;
    height: 22px;
    stroke: currentColor;
}

.pt-category-name {
    font-size: 14.5px;
    font-weight: 700;
}

.pt-category-count {
    font-size: 12.5px;
    color: var(--pt-muted);
}

/* "Jak to działa" — 3 kroki numerowane */

.pt-steps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
}

.pt-step-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
}

.pt-step-number {
    font-family: var(--pt-font-display);
    font-size: 28px;
    font-weight: 800;
    color: var(--pt-accent);
}

.pt-step-card .pt-chip {
    margin-bottom: 2px;
}

.pt-step-card h3 {
    margin: 0;
    font-size: 16px;
}

.pt-featured-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 16px;
}

.pt-avatar {
    width: 52px;
    height: 52px;
    flex: 0 0 auto;
    border-radius: 10px;
    background: var(--pt-chip);
    color: var(--pt-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--pt-font-display);
    font-weight: 700;
    font-size: 17px;
}

.pt-firm-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.pt-firm-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
}

.pt-firm-card h3 {
    margin: 0;
    font-size: 15.5px;
}

.pt-firm-card .pt-muted-text {
    font-size: 13px;
}

.pt-pill-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Pas statystyk katalogu — tło tintowane accentem (--pt-tint), liczby tabular-nums (żeby się
   nie "trzęsły" przy zmianie cyfr — tu statyczne, ale spójne z resztą liczników w portalu). */
.pt-stats-band {
    background: var(--pt-tint);
}

.pt-stats-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px 36px;
    padding: 28px 20px;
    text-align: center;
}

.pt-stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.pt-stat-value {
    font-family: var(--pt-font-display);
    font-variant-numeric: tabular-nums;
    font-size: 26px;
    font-weight: 800;
    color: var(--pt-accent);
}

.pt-stat-label {
    font-size: 13px;
    color: var(--pt-muted);
}

/* CTA band — gradient identyczny w hero, używany na stronie głównej i na landingu firmy
   (jeden wzorzec CTA w całym portalu). */
.pt-cta-band {
    background: var(--pt-grad);
    color: #fff;
    border-radius: var(--pt-radius-card);
    padding: 40px 24px;
    text-align: center;
}

.pt-cta-band h2 {
    margin: 0 0 8px;
    font-size: 24px;
    color: #fff;
}

.pt-cta-band .pt-muted-text {
    color: rgba(255, 255, 255, .82);
}

.pt-cta-band .pt-btn--primary {
    margin-top: 16px;
    background: #fff;
    border-color: #fff;
    color: var(--pt-accent-deep);
}

.pt-cta-band .pt-btn--primary:hover {
    background: rgba(255, 255, 255, .9);
    border-color: rgba(255, 255, 255, .9);
}

/* Badge terminu / statusu otwarcia - jedna rodzina wariantów używana wszędzie
   (strona główna, wyniki, landing firmy). Zielony = blisko/otwarte, neutralny (.pt-badge
   bazowy) = dalej, ostrzegawczy = brak terminów w widocznym horyzoncie.
   Mikro-sloty z lewej (sygnatura .pt-slots, wariant "ciche" przez pseudo-elementy) — ostatni
   slot w pełnej opacity ("wypełniony"), pierwsze dwa przytłumione; mono-hue = currentColor,
   więc kolor slotów podąża automatycznie za wariantem badge'a (ok/neutralny/brak). */
.pt-slot-badge {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px 4px 32px;
    border-radius: var(--pt-radius-pill);
    font-size: 12.5px;
    font-weight: 700;
    background: var(--pt-pill);
    color: var(--pt-pillfg);
}

.pt-slot-badge::before,
.pt-slot-badge::after {
    content: "";
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 8px;
    border-radius: 1px;
    background: currentColor;
}

.pt-slot-badge::before {
    left: 12px;
    opacity: .35;
    box-shadow: 6px 0 0 currentColor;
}

.pt-slot-badge::after {
    left: 24px;
    opacity: 1;
}

.pt-slot-badge--ok {
    background: var(--pt-okbg);
    color: var(--pt-ok);
}

.pt-slot-badge--brak {
    background: var(--pt-warnbg);
    color: var(--pt-warn);
}

/* ==========================================================================
   Wyniki wyszukiwania / strona kategorii
   ========================================================================== */

/* Pas full-bleed (tło na całą szerokość okna), ale TREŚĆ (formularz) zawsze w .pt-container - patrz
   design-guidance "spójny layout stron katalogu": pasy tła mogą być pełnej szerokości, ich treść nie. */
.pt-results-header {
    position: sticky;
    top: 0;
    z-index: 15;
    background: var(--pt-card);
    border-bottom: 1px solid var(--pt-border);
    padding: 12px 0;
}

.pt-results-header form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.pt-results-header .pt-field {
    flex: 1 1 160px;
}

.pt-results-header .pt-field input,
.pt-results-header .pt-field select {
    height: 40px;
}

.pt-results-layout {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    padding: 24px 20px;
}

.pt-filter-panel {
    flex: 0 1 240px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.pt-filter-group h3 {
    margin: 0 0 8px;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--pt-muted);
}

/* Link filtra kategorii - był klikalny bez żadnego hover/focus poza generycznym ringiem
   (luka znaleziona w przeglądzie pkt 7 mikro-interakcji). Kolor to już domyślny --pt-accent
   z bazowej reguły `a` na górze pliku (brak własnego koloru tutaj), więc bez text-decoration:none
   ta kotwica byłaby na stałe podkreślona (domyślny UA-stylesheet) - jawnie zdejmujemy
   podkreślenie w spoczynku i przywracamy je na hover/focus jako sygnał. */
.pt-filter-option {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    padding: 4px 0;
    text-decoration: none;
}

.pt-filter-option:hover,
.pt-filter-option:focus-visible {
    text-decoration: underline;
}

/* Chipy filtra tagów specjalizacji (pod formularzem wyszukiwarki, tylko gdy wybrana kategoria) —
   mirror .pt-pill-row w layoucie, ale klikalne i z widocznym stanem aktywnym jak .pt-btn--primary. */
.pt-tag-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.pt-tag-chip {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: var(--pt-radius-pill);
    background: var(--pt-pill);
    color: var(--pt-pillfg);
    font-size: 13px;
    text-decoration: none;
    transition: background-color var(--pt-t-fast) var(--pt-ease), color var(--pt-t-fast) var(--pt-ease), transform var(--pt-t-fast) var(--pt-ease);
}

.pt-tag-chip:hover,
.pt-tag-chip:focus-visible {
    background: var(--pt-chip);
    color: var(--pt-accent);
    /* Lekkie uniesienie (nie skala - to pigułka tekstowa, nie ikona) obok istniejącego tintu tła. */
    transform: translateY(-1px);
}

.pt-tag-chip.is-active {
    background: var(--pt-accent);
    color: var(--pt-accent-contrast);
}

.pt-results-list {
    flex: 1 1 480px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pt-results-list-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 6px;
}

/* Karta wyniku — cała klikalna (link opakowujący całą kartę), monogram + treść + strzałka.
   Strzałka jedzie w prawo na hover (translateX), spójnie z resztą motion-language kart. */
.pt-result-card {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    padding: 16px;
    text-decoration: none;
    color: inherit;
}

.pt-result-card-body {
    flex: 1 1 260px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.pt-result-card h2 {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
}

.pt-result-card-address {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.pt-result-card-address .pt-icon {
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
}

.pt-result-arrow {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    color: var(--pt-muted);
    transition: transform var(--pt-t-fast) var(--pt-ease), color var(--pt-t-fast) var(--pt-ease);
}

.pt-result-card:hover .pt-result-arrow,
.pt-result-card:focus-visible .pt-result-arrow {
    /* translateX(3px) - brak przycisku z ikoną w portalu (sprawdzone w Views), więc ten
       wzorzec "ikona jedzie w prawo na hover" (pkt 3 mikro-interakcji) ląduje tutaj, na
       jedynej istniejącej strzałce w portalu. */
    transform: translateX(3px);
    color: var(--pt-accent);
}

.pt-btn--outline {
    background: transparent;
}

.pt-empty-state {
    text-align: center;
    padding: 48px 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}

.pt-empty-state .pt-icon {
    width: 40px;
    height: 40px;
    color: var(--pt-muted);
}

/* ==========================================================================
   Landing firmy
   ========================================================================== */

.pt-firm-nav {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--pt-card);
    border-bottom: 1px solid var(--pt-border);
}

.pt-firm-nav-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    padding: 12px 20px;
}

.pt-firm-nav-links {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-right: auto;
}

.pt-firm-nav-links a {
    position: relative;
    display: inline-block;
    padding: 4px 2px;
    margin: 0 8px;
    color: var(--pt-text);
    text-decoration: none;
    font-size: 13.5px;
    font-weight: 600;
}

/* Scrollspy — podświetlenie linku aktywnej sekcji (patrz portal.js), podkreślenie "wjeżdża"
   przez transform: scaleX zamiast width (tańsze dla przeglądarki, jeden transition ease). */
.pt-firm-nav-links a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -4px;
    height: 2px;
    background: var(--pt-accent);
    border-radius: 1px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--pt-t-fast) var(--pt-ease);
}

.pt-firm-nav-links a.is-active {
    color: var(--pt-accent);
}

/* Podkreślenie na hover/focus - obok wariantu is-active sterowanego scrollspy z portal.js
   (pkt 1 mikro-interakcji). Oba dzielą ten sam ::after, więc odjazd myszki z linku, który nie
   jest aktywną sekcją, sam wraca do scaleX(0) (żaden dodatkowy stan do pilnowania). */
.pt-firm-nav-links a.is-active::after,
.pt-firm-nav-links a:hover::after,
.pt-firm-nav-links a:focus-visible::after {
    transform: scaleX(1);
}

.pt-firm-hero {
    position: relative;
    padding: 56px 20px;
    color: #fff;
    background: var(--pt-grad);
    background-size: cover;
    background-position: center;
    overflow: hidden;
}

.pt-firm-hero-inner {
    max-width: 640px;
}

/* Overlay przyciemniający zdjęcie tła hero (gradient accent-deep → transparent), żeby biały
   tekst zachował kontrast niezależnie od jasności zdjęcia. Bez zdjęcia hero używa samego
   --pt-grad (bez overlay) + patternu slotów jak strona główna. */
.pt-firm-hero--photo::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, color-mix(in srgb, var(--pt-accent-deep) 75%, transparent), transparent 75%);
}

.pt-firm-hero:not(.pt-firm-hero--photo)::before {
    content: "";
    position: absolute;
    inset: 0;
    opacity: .07;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='56' viewBox='0 0 96 56'%3E%3Cg fill='none' stroke='white' stroke-width='2'%3E%3Crect x='4' y='8' width='10' height='16' rx='2'/%3E%3Crect x='22' y='8' width='10' height='16' rx='2'/%3E%3Crect x='40' y='8' width='10' height='16' rx='2'/%3E%3Crect x='58' y='8' width='10' height='16' rx='2'/%3E%3Crect x='76' y='8' width='10' height='16' rx='2'/%3E%3Crect x='4' y='32' width='10' height='16' rx='2'/%3E%3Crect x='22' y='32' width='10' height='16' rx='2'/%3E%3Crect x='40' y='32' width='10' height='16' rx='2'/%3E%3Crect x='58' y='32' width='10' height='16' rx='2'/%3E%3Crect x='76' y='32' width='10' height='16' rx='2'/%3E%3C/g%3E%3C/svg%3E");
    background-size: 220px 128px;
}

.pt-firm-hero > * {
    position: relative;
}

.pt-firm-hero .pt-slot-badge {
    background: rgba(255, 255, 255, .16);
    color: #fff;
}

.pt-firm-hero h1 {
    margin: 10px 0;
    font-size: clamp(24px, 3.6vw, 34px);
    font-weight: 800;
}

.pt-firm-hero .pt-muted-text {
    color: rgba(255, 255, 255, .85);
}

.pt-firm-hero .pt-cta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 16px;
}

.pt-firm-hero .pt-btn--primary {
    background: #fff;
    border-color: #fff;
    color: var(--pt-accent-deep);
}

.pt-firm-hero .pt-btn--outline {
    border-color: rgba(255, 255, 255, .55);
    color: #fff;
}

/* HeroConfig.Wysokosc/Wyrownanie (Iteracja 3, pkt B) - "kompakt"/"lewo" to zachowanie sprzed
   Iteracji 3 (brak modyfikatora), więc bez dodatkowych reguł tutaj. */
.pt-firm-hero--duzy {
    padding-top: 112px;
    padding-bottom: 96px;
    min-height: 56vh;
    display: flex;
    align-items: center;
}

.pt-firm-hero--align-srodek .pt-firm-hero-inner {
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
}

.pt-firm-hero--align-srodek .pt-pill-row,
.pt-firm-hero--align-srodek .pt-cta-row {
    justify-content: center;
}

/* Rytm sekcji landingu: naprzemiennie tło strony (bg) → karta (card), na całą szerokość pasa,
   treść w kontenerze. Sekcje bookingowe (Usługi/Stanowiska/Grupy*) zostają zawsze na wariancie
   "card" niezależnie od parzystości, dla kontrastu z ich wewnętrznymi kartami. */
.pt-section--bg {
    background: var(--pt-bg);
}

.pt-section--card {
    background: var(--pt-card);
    border-top: 1px solid var(--pt-border);
    border-bottom: 1px solid var(--pt-border);
}

/* Tlo jawny per sekcja (Iteracja 3, pkt B) - wygrywa z rytmem "auto" powyżej, patrz
   Views/Landing/Index.cshtml. "jasne"/"karta" to te same tła co --bg/--card na wyższej alfabetycznie
   nazwie modyfikatora (bo o wyborze między nimi decyduje teraz panel, nie parzystość), "akcent-tint"
   to nowy, subtelny odcień marki (ta sama zmienna --pt-tint co pasek statystyk katalogu). */
.pt-section--bg-jasne {
    background: var(--pt-bg);
}

.pt-section--bg-karta {
    background: var(--pt-card);
    border-top: 1px solid var(--pt-border);
    border-bottom: 1px solid var(--pt-border);
}

.pt-section--bg-akcent-tint {
    background: var(--pt-tint);
}

.pt-services {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: 1px solid var(--pt-border);
    border-radius: var(--pt-radius-card);
    background: var(--pt-card);
    overflow: hidden;
}

.pt-pricing-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--pt-border);
    transition: background-color var(--pt-t-fast) var(--pt-ease);
}

.pt-pricing-row:hover {
    background: var(--pt-bg);
}

.pt-pricing-row:last-child {
    border-bottom: none;
}

.pt-pricing-row-body {
    flex: 1 1 240px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.pt-pricing-row-body h3 {
    margin: 0;
    font-size: 15px;
}

.pt-pricing-price {
    font-variant-numeric: tabular-nums;
    font-weight: 800;
    font-size: 16px;
    white-space: nowrap;
}

.pt-pricing-row .pt-btn--outline:hover {
    background: var(--pt-accent);
    border-color: var(--pt-accent);
    color: var(--pt-accent-contrast);
}

.pt-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
}

.pt-tile {
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow: hidden;
    padding: 0;
}

.pt-tile-media {
    position: relative;
    overflow: hidden;
    aspect-ratio: 16 / 10;
}

.pt-tile-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* Ujednolicone z .pt-gallery img (były dwa niezależne wdrożenia zoomu, różna skala i czas) -
       pkt 4 mikro-interakcji: wolniej (t-slow, 500ms) czyta się jako celowy, "kinowy" zoom,
       zamiast odruchowego "kliknięcia" przy t-med. */
    transition: transform var(--pt-t-slow) var(--pt-ease);
}

.pt-tile:hover .pt-tile-media img,
.pt-tile:focus-within .pt-tile-media img {
    transform: scale(1.04);
}

/* Przyciemnienie pod zoomowanym zdjęciem (pkt 4) - ten sam trigger co skalowanie obrazka,
   ::after zamiast dodatkowego diva (kontener ma już overflow:hidden, position:relative
   dopisany wyżej). pointer-events:none, żeby nie łapało kliknięć nad kafelkiem. */
.pt-tile-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .15);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--pt-t-fast) var(--pt-ease);
}

.pt-tile:hover .pt-tile-media::after,
.pt-tile:focus-within .pt-tile-media::after {
    opacity: 1;
}

.pt-tile-body {
    padding: 14px 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pt-tile-body h3 {
    margin: 0;
    font-size: 15.5px;
}

.pt-station-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--pt-border);
    transition: background-color var(--pt-t-fast) var(--pt-ease);
}

.pt-station-row:hover {
    background: var(--pt-bg);
}

.pt-station-row:last-child {
    border-bottom: none;
}

.pt-station-thumb {
    width: 52px;
    height: 52px;
    flex: 0 0 auto;
    border-radius: var(--pt-radius-field);
    object-fit: cover;
    background: var(--pt-pill);
}

.pt-station-row-body {
    flex: 1 1 220px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.pt-station-row-body h3 {
    margin: 0;
    font-size: 15px;
}

.pt-about {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 28px;
}

/* ONasConfig.UkladObrazu (Iteracja 3, pkt B) - split obraz/tekst jak logo-med. Kolejność wizualna
   wynika z kolejności w DOM (ustawianej w _ONas.cshtml), nie z CSS "order": --prawo ma tekst
   pierwszy/obraz drugi (zachowanie sprzed Iteracji 3, więc bez własnej reguły), --lewo ma obraz
   pierwszy (dziedziczy tę samą siatkę 2-kolumnową - auto-placement grida wystarczy), --gora ma
   obraz pierwszy w jednej kolumnie na całą szerokość. Mobile zawsze stack z obrazem NAD tekstem -
   dla --prawo to jedyny wariant, w którym DOM nie ma już obrazu pierwszego, więc dostaje "order". */
.pt-about--gora {
    grid-template-columns: 1fr;
}

@media (max-width: 680px) {
    .pt-about--prawo .pt-about-media {
        order: -1;
    }
}

.pt-about-stats {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.pt-about-stats li {
    flex: 1 1 100px;
    text-align: center;
}

.pt-about-stat-value {
    display: block;
    font-size: 28px;
    font-weight: 800;
    color: var(--pt-accent);
}

.pt-about-stat-label {
    font-size: 12.5px;
    color: var(--pt-muted);
}

.pt-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
}

/* GaleriaConfig.Kolumny (Iteracja 3, pkt B) - liczba kolumn jawna zamiast auto-fit; base .pt-gallery
   wyżej zostaje jako fallback dla configów bez tej klasy (nie powinno się zdarzyć, Kolumny ma
   default 3, ale walidacja server-side normalizuje nieznaną wartość zamiast rzucać wyjątkiem). */
.pt-gallery--cols-2 {
    grid-template-columns: repeat(2, 1fr);
}

.pt-gallery--cols-3 {
    grid-template-columns: repeat(3, 1fr);
}

.pt-gallery--cols-4 {
    grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 640px) {
    .pt-gallery--cols-3,
    .pt-gallery--cols-4 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 420px) {
    .pt-gallery--cols-2,
    .pt-gallery--cols-3,
    .pt-gallery--cols-4 {
        grid-template-columns: 1fr;
    }
}

.pt-gallery button {
    position: relative;
    display: block;
    width: 100%;
    border: 1px solid var(--pt-border);
    border-radius: var(--pt-radius-field);
    overflow: hidden;
    padding: 0;
    background: none;
    cursor: zoom-in;
}

/* Przyciemnienie pod zoomowanym zdjęciem galerii - lustro .pt-tile-media::after wyżej, ten sam
   token/timing (pkt 4 mikro-interakcji), tu na <button> bo to on jest kontenerem overflow:hidden. */
.pt-gallery button::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .15);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--pt-t-fast) var(--pt-ease);
}

.pt-gallery button:hover::after,
.pt-gallery button:focus-visible::after {
    opacity: 1;
}

.pt-gallery img {
    width: 100%;
    height: 140px;
    object-fit: cover;
    display: block;
    /* Ujednolicone z .pt-tile-media img - jeden wzorzec zoomu w całym portalu (skala + czas). */
    transition: transform var(--pt-t-slow) var(--pt-ease);
}

.pt-gallery button:hover img,
.pt-gallery button:focus-visible img {
    transform: scale(1.04);
}

/* Lightbox — <dialog> natywny (focus trap + Esc gratis), otwierany/zamykany z portal.js.
   Nawigacja strzałkami wymienia tylko src obrazka wewnątrz tego samego dialogu. */
.pt-lightbox {
    border: none;
    border-radius: var(--pt-radius-card);
    padding: 0;
    background: transparent;
    max-width: min(92vw, 1100px);
    max-height: 88vh;
}

.pt-lightbox::backdrop {
    background: rgba(10, 14, 26, .82);
}

.pt-lightbox img {
    display: block;
    max-width: min(92vw, 1100px);
    max-height: 80vh;
    width: auto;
    height: auto;
    border-radius: var(--pt-radius-card);
}

.pt-lightbox-controls {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    pointer-events: none;
    padding: 12px;
}

.pt-lightbox-controls button {
    pointer-events: auto;
}

/* Przyciski lightboxa - były klikalne bez żadnego hover/focus poza generycznym ringiem (luka
   znaleziona w przeglądzie pkt 7 mikro-interakcji). Ciemniejsze tło na hover, bo to jasne ikony
   na już ciemnym backdropie (--pt-accent tutaj zginąłby wizualnie / nie dawałby kontrastu). */
.pt-lightbox-close,
.pt-lightbox-prev,
.pt-lightbox-next {
    background: rgba(15, 23, 42, .55);
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    font-size: 18px;
    cursor: pointer;
    transition: background-color var(--pt-t-fast) var(--pt-ease);
}

.pt-lightbox-close:hover,
.pt-lightbox-close:focus-visible,
.pt-lightbox-prev:hover,
.pt-lightbox-prev:focus-visible,
.pt-lightbox-next:hover,
.pt-lightbox-next:focus-visible {
    background: rgba(15, 23, 42, .8);
}

.pt-lightbox-close {
    position: fixed;
    top: 16px;
    right: 16px;
}

/* Akordeon FAQ animowany przez technikę CSS grid-template-rows (0fr → 1fr) — details/summary
   zostaje semantyczne, ale toggle jest przechwytywany w portal.js, żeby animować otwarcie
   i zamknięcie zamiast natychmiastowego show/hide natywnego <details>. */
.pt-faq {
    display: flex;
    flex-direction: column;
}

.pt-faq details {
    padding: 14px 0;
    border-bottom: 1px solid var(--pt-border);
}

.pt-faq details:last-child {
    border-bottom: none;
}

.pt-faq summary {
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-weight: 700;
    font-size: 15px;
    list-style: none;
}

.pt-faq summary::-webkit-details-marker {
    display: none;
}

.pt-faq-icon {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    color: var(--pt-accent);
    transition: transform var(--pt-t-fast) var(--pt-ease);
}

.pt-faq details[open] .pt-faq-icon {
    transform: rotate(45deg);
}

.pt-faq-body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows var(--pt-t-med) var(--pt-ease);
}

/* Fallback BEZ JS: natywny <details> przełącza [open] bez animacji (portal.js przechwytuje
   toggle i steruje grid-template-rows przez inline style — patrz komentarz w portal.js), więc ta
   reguła musi tylko odsłonić treść, nie musi animować. Celowo "auto", nie "1fr": w niektórych
   przeglądarkach grid-template-rows:1fr ustawiony przez SELEKTOR (nie inline style) nie licząc
   się poprawnie wewnątrz naywnego <details> (zaobserwowane w Chromium) — "auto" nie ma tego
   problemu i nie wymaga animowalności, bo bez JS i tak nie ma tu żadnej animacji. */
.pt-faq details[open] .pt-faq-body {
    grid-template-rows: auto;
}

.pt-faq-body-inner {
    overflow: hidden;
}

.pt-faq-body p {
    margin: 10px 0 0;
    color: var(--pt-muted);
}

.pt-contact {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 24px;
}

.pt-contact-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    font-size: 14.5px;
}

/* Kontakt atrakcyjniej + mapa Google (Iteracja 3, pkt D) - karta 2-kolumnowa (dane / mapa),
   mobile stack. --sole (PokazMape=false albo brak adresu do zmapowania) wraca do jednej kolumny
   na pełną szerokość zamiast zostawiać pustą prawą kolumnę. */
.pt-contact-card {
    display: grid;
    grid-template-columns: minmax(260px, 1fr) minmax(260px, 1.2fr);
    gap: 24px;
    align-items: stretch;
}

.pt-contact-card--sole {
    grid-template-columns: 1fr;
}

@media (max-width: 780px) {
    .pt-contact-card {
        grid-template-columns: 1fr;
    }
}

.pt-contact-info {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pt-contact-row {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 14.5px;
}

.pt-contact-row .pt-icon {
    color: var(--pt-accent);
}

a.pt-contact-row-link {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-radius: var(--pt-radius-field);
    background: var(--pt-tint);
    color: var(--pt-text);
    text-decoration: none;
    font-weight: 700;
    font-size: 16px;
    transition: background-color var(--pt-t-fast) var(--pt-ease);
}

a.pt-contact-row-link:hover {
    background: var(--pt-chip);
}

a.pt-contact-row-link .pt-icon {
    color: var(--pt-accent);
}

/* Linki zaufania w Kontakcie (Iteracja 4, pkt C.1/C.4) - rząd przycisków-ikon, renderowany tylko gdy
   firma wypełniła link w panelu. Wizualnie ten sam "chip" 44x44 co ikona kategorii (.pt-chip) - jeden
   wzorzec ikony w portalu zamiast trzeciego wariantu. */
.pt-social-row {
    display: flex;
    gap: 10px;
    margin-top: 4px;
}

.pt-social-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: var(--pt-chip);
    color: var(--pt-accent);
    transition: background-color var(--pt-t-fast) var(--pt-ease), color var(--pt-t-fast) var(--pt-ease), transform var(--pt-t-fast) var(--pt-ease);
}

/* Ten sam wzorzec "chip rośnie i mocniej się tintuje" co ikona kategorii/kroku wyżej (pkt 2
   mikro-interakcji) - tu hoverowany bezpośrednio, nie przez rodzica, bo to samodzielny link. */
.pt-social-btn:hover,
.pt-social-btn:focus-visible {
    transform: scale(1.08);
    background: color-mix(in srgb, var(--pt-accent) 20%, transparent);
}

.pt-contact-map {
    border: 1px solid var(--pt-border);
    border-radius: var(--pt-radius-card);
    overflow: hidden;
    min-height: 320px;
}

.pt-contact-map iframe {
    width: 100%;
    height: 100%;
    min-height: 320px;
    border: 0;
    display: block;
}

/* Typografia treści REGULAMINU (Iteracja 3, pkt C) - jedyny poza JSON-LD Html.Raw w portalu,
   patrz komentarz przy tym Html.Raw w Views/Landing/Sections/_Regulamin.cshtml. */
.pt-prose h3,
.pt-prose h4 {
    margin: 24px 0 10px;
    font-weight: 800;
}

.pt-prose h3:first-child,
.pt-prose h4:first-child {
    margin-top: 0;
}

.pt-prose p {
    margin: 0 0 12px;
    color: var(--pt-muted);
}

.pt-prose ul,
.pt-prose ol {
    margin: 0 0 12px;
    padding-left: 22px;
    color: var(--pt-muted);
}

.pt-prose li {
    margin: 4px 0;
}

.pt-prose a {
    color: var(--pt-accent);
    text-decoration: underline;
}

.pt-prose blockquote {
    margin: 0 0 12px;
    padding: 10px 16px;
    border-left: 3px solid var(--pt-accent);
    color: var(--pt-muted);
}

.pt-prose hr {
    border: none;
    border-top: 1px solid var(--pt-border);
    margin: 20px 0;
}

.pt-firm-footer {
    border-top: 1px solid var(--pt-border);
    padding: 18px 20px;
    font-size: 12.5px;
    color: var(--pt-muted);
    text-align: center;
}

/* Sticky pasek CTA na mobile landingu firmy - patrz wytyczne pkt 27. Ukryty od szerokości,
   na której CTA w hero jest już wystarczająco widoczny bez scrolla. */
.pt-mobile-cta-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: flex;
    gap: 10px;
    align-items: center;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
    background: var(--pt-card);
    border-top: 1px solid var(--pt-border);
    box-shadow: 0 -4px 16px rgba(15, 23, 42, .12);
}

.pt-mobile-cta-bar .pt-btn--primary {
    flex: 1 1 auto;
    text-align: center;
}

@media (min-width: 720px) {
    .pt-mobile-cta-bar {
        display: none;
    }
}

.pt-body--has-mobile-cta .pt-main {
    padding-bottom: 0;
}

@media (max-width: 719px) {
    .pt-body--has-mobile-cta .pt-main {
        padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
    }
}

/* === Stanowiska: duze zdjecie + badge dostepnosci przy nazwie (feedback 2026-08-24) === */
.pt-station-row { align-items: center; }
.pt-station-thumb {
    width: 300px;
    max-width: 38%;
    height: auto;
    aspect-ratio: 16 / 10;
    border-radius: var(--pt-radius-card, 12px);
    box-shadow: var(--pt-shadow-sm, 0 1px 2px rgba(15,23,42,.08));
    object-fit: cover;
}
.pt-station-row-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pt-station-row-head h3 { margin: 0; }
@media (max-width: 760px) {
    .pt-station-thumb { width: 100%; max-width: 100%; }
}

/* CTA rezerwacji przy stanowisku: primary z ikona, zwarta kolumna akcji (feedback 2026-08-24) */
.pt-station-row-cta { flex: 0 0 auto; align-self: center; display: flex; flex-direction: column; gap: 8px; }
.pt-book-btn { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.pt-tile-body .pt-book-btn { width: 100%; justify-content: center; margin-top: auto; }
@media (max-width: 760px) { .pt-station-row-cta { width: 100%; } .pt-station-row-cta .pt-book-btn { width: 100%; justify-content: center; } }
