/*! PageForYou site-runtime.css — audyt 30.09.2026 (S1). Wspólny CSS 12 szablonów (enhancery: scroll-progress,
 *  active-nav, ripple, back-to-top, gradient hero, testimonial progress, team initials, card tilt, gallery masonry/filters,
 *  lightbox caption, hero-anim orb). Wyodrębniony przez scripts/extract-runtime.cjs; <link> stoi w miejscu dawnego </style>,
 *  więc kaskada jest taka sama. Zmienne CSS (--color-*, --heading-color…) definiuje szablon. */
/* ── Scroll progress bar ── */
#scroll-progress{position:fixed;top:0;left:0;height:3px;background:linear-gradient(90deg,var(--color-primary),var(--color-accent));z-index:9999;width:0;transition:none;pointer-events:none}
/* ── Active nav link ── */
#nav-links a.nav-active,#mobile-menu a.nav-active{color:var(--heading-color)}
#nav-links a.nav-active{box-shadow:inset 0 -2px 0 var(--color-primary)}
/* ── Ripple effect ── */
.btn-primary{position:relative;overflow:hidden}
.ripple-effect{position:absolute;border-radius:50%;background:rgba(255,255,255,.35);transform:scale(0);animation:ripple-anim .6s ease-out;pointer-events:none}
@keyframes ripple-anim{to{transform:scale(4);opacity:0}}
/* ── Back to top ── */
#back-to-top{position:fixed;bottom:24px;right:24px;z-index:90;width:44px;height:44px;border-radius:50%;background:var(--color-primary);color:var(--btn-text,#111);border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;opacity:0;transform:translateY(20px);transition:opacity .3s,transform .3s;pointer-events:none;box-shadow:0 4px 16px rgba(0,0,0,.3)}
#back-to-top.visible{opacity:1;transform:translateY(0);pointer-events:auto}
#back-to-top:hover{transform:translateY(-3px);box-shadow:0 8px 24px rgba(0,0,0,.4)}
/* ── Gradient text on hero title ── */
.hero-gradient-text{background:linear-gradient(135deg,var(--heading-color) 0%,var(--primary-text,var(--color-primary)) 50%,var(--accent-text,var(--color-accent)) 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
/* ── Testimonial progress ── */
.testimonial-progress{height:2px;background:color-mix(in srgb,var(--color-primary) 20%,transparent);border-radius:2px;overflow:hidden;margin-top:16px}
.testimonial-progress-bar{height:100%;background:var(--color-primary);width:0;border-radius:2px}
.testimonial-progress-bar.animating{animation:testim-progress 5s linear forwards}
@keyframes testim-progress{from{width:0}to{width:100%}}
/* ── Team initials avatar ── */
.team-initials{width:80px;height:80px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-family:var(--font-display,inherit);font-weight:700;font-size:1.5rem;color:var(--heading-color);background:linear-gradient(135deg,color-mix(in srgb,var(--color-primary) 25%,transparent),color-mix(in srgb,var(--color-accent) 20%,transparent));border:2px solid color-mix(in srgb,var(--color-primary) 30%,transparent);margin:0 auto 16px}
/* ── Enhanced card hover (3D tilt) ── */
.card-tilt{transition:transform .4s ease,box-shadow .4s ease}
.card-tilt:hover{box-shadow:0 24px 48px var(--shadow-card)}
/* ── Number highlight in stats ── */
/* przegląd 2.10.2026 (noc): gradient tylko w hero (skill §3) — cyfry statystyk jednolitym kolorem marki bezpiecznym jako tekst */
:where(.counter-value){color:var(--primary-text,var(--color-primary))} /* :where — warianty (pas liczb na zdjęciu) ustawiają własny kolor */
/* ── Gallery filter tabs ── */
.gallery-filters{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin-bottom:24px}
.gallery-filter-btn{padding:6px 16px;border-radius:9999px;font-size:.75rem;font-weight:600;border:1px solid var(--card-border);background:transparent;color:var(--text-muted);cursor:pointer;transition:all .3s}
.gallery-filter-btn:hover,.gallery-filter-btn.active{background:var(--color-primary);color:var(--btn-text,#111);border-color:var(--color-primary)}
.gallery-card.filtering-out{opacity:0;transform:scale(.8);pointer-events:none;position:absolute}
.gallery-card{transition:transform .4s ease,box-shadow .4s ease,opacity .4s ease}
/* ── Smooth section divider ── */
.section-divider{height:1px;background:linear-gradient(90deg,transparent,var(--card-border),transparent);margin:0 auto;max-width:80%}
/* ── Contact click links ── */
.contact-link{transition:color .3s}
.contact-link:hover{color:var(--primary-text,var(--color-primary))}
@media(prefers-reduced-motion:reduce){.ripple-effect,.testimonial-progress-bar.animating,#scroll-progress{animation:none;transition:none}#back-to-top{transition:none}}

/* ── Masonry gallery layout ── */
@media(min-width:640px){.gallery-masonry{column-count:2;column-gap:20px}}
@media(min-width:1024px){.gallery-masonry{column-count:3;column-gap:24px}}
.gallery-masonry .gallery-card{break-inside:avoid;margin-bottom:20px;display:inline-block;width:100%}
.gallery-masonry .gallery-card .aspect-\[4\/3\]{aspect-ratio:auto}
/* ── Lightbox caption ── */
.lb-caption{position:absolute;bottom:60px;left:50%;transform:translateX(-50%);max-width:80vw;text-align:center;color:rgba(255,255,255,.8);font-size:.85rem;line-height:1.5;padding:8px 20px;background:rgba(0,0,0,.5);border-radius:8px;opacity:0;transition:opacity .3s}
.lightbox.open .lb-caption{opacity:1}
/* ── Gallery card image number ── */
.gallery-number{position:absolute;top:12px;right:12px;width:28px;height:28px;border-radius:50%;background:rgba(0,0,0,.5);color:rgba(255,255,255,.7);font-size:.65rem;font-weight:600;display:flex;align-items:center;justify-content:center;z-index:3;opacity:0;transition:opacity .3s}
.gallery-card:hover .gallery-number{opacity:1}

/* ── Hero animation orb ─────────────────────────────────────── */
.hero-anim-orb{position:absolute;border-radius:50%;overflow:hidden;z-index:15;box-shadow:0 8px 32px rgba(0,0,0,.18)}
.hero-anim-orb video{width:100%;height:100%;object-fit:cover;filter:grayscale(.65) contrast(1.1)}
.hero-anim-orb::after{content:'';position:absolute;inset:0;background:var(--color-primary);mix-blend-mode:multiply;opacity:.55;border-radius:50%;pointer-events:none}
.hero-anim-float{position:absolute;border-radius:50%;overflow:hidden;z-index:5;box-shadow:0 4px 24px rgba(0,0,0,.15);animation:anim-float 6s ease-in-out infinite}
.hero-anim-float video{width:100%;height:100%;object-fit:cover;filter:grayscale(.7) contrast(1.1)}
.hero-anim-float::after{content:'';position:absolute;inset:0;background:var(--color-primary);mix-blend-mode:multiply;opacity:.5;border-radius:50%;pointer-events:none}
@keyframes anim-float{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-8px) scale(1.02)}}

/* ── Tokenowe klasy kolorów (2.10.2026, dług INFO walidatora L2) ──
 *  Warianty sprzed S2b miały klasy palety Tailwind (text-white, text-gray-400, bg-white/5…), które _base/tw-remap,
 *  _base/modern i custom.css szablonów przemapowywały na tokeny. Teraz warianty używają tych klas wprost — jedno źródło
 *  znaczenia. Specyficzność „body .x” = jak w tw-remap (wygląd bez zmian).
 *  Biel i czerń na zdjęciach i pasach w kolorze marki: tokeny KANAŁÓW --on-media-rgb / --scrim-rgb (domyślne niżej, szablon
 *  może nadpisać w template.json); kolor = rgb(var(--on-media-rgb) / .8). Celowo rgb(), nie color-mix(): gradient z kolorem
 *  spoza składni legacy jest interpolowany w oklab (inny przebieg niż dawne rgba() — widoczne pasy na overlayach hero). */
:where(:root){--on-media-rgb:255 255 255;--scrim-rgb:0 0 0}
body .tk-heading{color:var(--heading-color)}
body .tk-muted{color:var(--text-muted)}
body .hover\:tk-heading:hover{color:var(--heading-color)}
body .tk-bg-card{background-color:var(--card-bg)}
body .tk-bg-heading{background-color:var(--heading-color)}
.tk-on-media{color:rgb(var(--on-media-rgb))}
.tk-on-media-60{color:rgb(var(--on-media-rgb) / .6)}
.tk-on-media-80{color:rgb(var(--on-media-rgb) / .8)}
.tk-on-media-90{color:rgb(var(--on-media-rgb) / .9)}
.tk-scrim{color:rgb(var(--scrim-rgb))}
.tk-bg-on-media{background-color:rgb(var(--on-media-rgb))}
.tk-bg-on-media-5{background-color:rgb(var(--on-media-rgb) / .05)}
.hover\:tk-bg-on-media-5:hover{background-color:rgb(var(--on-media-rgb) / .05)}
.hover\:tk-bg-on-media-10:hover{background-color:rgb(var(--on-media-rgb) / .1)}
.hover\:tk-bg-on-media-90:hover{background-color:rgb(var(--on-media-rgb) / .9)}
.tk-border-on-media-10{border-color:rgb(var(--on-media-rgb) / .1)}
.tk-border-on-media-30{border-color:rgb(var(--on-media-rgb) / .3)}
.tk-border-on-media-40{border-color:rgb(var(--on-media-rgb) / .4)}
.hover\:tk-border-on-media:hover{border-color:rgb(var(--on-media-rgb))}
.tk-from-scrim-60{--tw-gradient-from:rgb(var(--scrim-rgb) / .6) var(--tw-gradient-from-position);--tw-gradient-to:transparent var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}
.tk-placeholder-muted::placeholder{color:var(--text-muted)}
.focus\:tk-bg-on-media:focus{background-color:rgb(var(--on-media-rgb))}
.focus\:tk-scrim:focus{color:rgb(var(--scrim-rgb))}
/* hover/focus wariantów sprzed S2b (dawniej inline onmouseenter/onfocus ustawiające style) — !important jak inline style */
.tk-hover-border-primary:hover,.tk-focus-border-primary:focus{border-color:var(--color-primary)!important}
.tk-hover-lift:hover{transform:translateY(-4px)!important}

/* ── Przegląd wizualny 2.10.2026 (noc) — kontrast i spójność (src/services/template-builder/merge-contrast.ts) ── */
/* Akcent jako tekst: --accent-text liczy silnik (≥ 4.5:1 dla schematu i motywu); tu tylko zapas dla starych dokumentów */
:where(:root){--accent-text:color-mix(in srgb,var(--color-accent) 55%,var(--heading-color))}
.tk-accent{color:var(--accent-text)}
/* Przycisk główny: jeden kolor tekstu na stronie (--btn-text, strażnik kontrastu) — bez wpływu klas wariantu
   (tk-heading, nav-active, text-white), które dawały ciemny tekst na kolorze marki w jednym miejscu i biały w innym */
body .btn-primary,body .btn-primary:hover,#nav-links a.btn-primary.nav-active{color:var(--btn-text,#fff)!important;-webkit-text-fill-color:currentColor}
#nav-links a.btn-primary.nav-active{box-shadow:none}
/* Tytuł hero na zdjęciu (tk-on-media): jednolity kolor zamiast gradientu z --heading-color (ginie na kadrze w jasnym motywie) */
.hero-gradient-text.tk-on-media{background:none;-webkit-text-fill-color:currentColor}
/* Nawigacja nad pełnoekranowym zdjęciem hero (hero/fullscreen-media): tło z tokenu od pierwszego malowania, jak w mm-hero */
body:has(#hero[data-hero-fullbleed]) #navbar{background:var(--nav-bg);-webkit-backdrop-filter:saturate(1.4) blur(12px);backdrop-filter:saturate(1.4) blur(12px);box-shadow:0 1px 0 var(--card-border)}
/* Przycisk na dole karty (cennik: karty o różnej liczbie punktów — przyciski w jednej linii); karta = flex-col */
.pfy-push-end{margin-top:auto}
/* Siatki kart wg liczby kart (merge-quality.ts finalizeGrids): silnik zastępuje klasy grid-cols-* wariantu kompletem
   pfy-cN dla wszystkich progów (bez konfliktu z Tailwind), a gdy liczba kart nie dzieli się bez sieroty — ostatnia karta
   na całą szerokość rzędu (pfy-last-full) */
.pfy-c1{grid-template-columns:repeat(1,minmax(0,1fr))}.pfy-c2{grid-template-columns:repeat(2,minmax(0,1fr))}.pfy-c3{grid-template-columns:repeat(3,minmax(0,1fr))}.pfy-c4{grid-template-columns:repeat(4,minmax(0,1fr))}.pfy-last-full>:last-child{grid-column:1/-1}.pfy-last-auto>:last-child{grid-column:auto}
@media(min-width:640px){.sm\:pfy-c1{grid-template-columns:repeat(1,minmax(0,1fr))}.sm\:pfy-c2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:pfy-c3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:pfy-c4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:pfy-last-full>:last-child{grid-column:1/-1}.sm\:pfy-last-auto>:last-child{grid-column:auto}}
@media(min-width:768px){.md\:pfy-c1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:pfy-c2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:pfy-c3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:pfy-c4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:pfy-last-full>:last-child{grid-column:1/-1}.md\:pfy-last-auto>:last-child{grid-column:auto}}
@media(min-width:1024px){.lg\:pfy-c1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:pfy-c2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:pfy-c3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:pfy-c4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:pfy-last-full>:last-child{grid-column:1/-1}.lg\:pfy-last-auto>:last-child{grid-column:auto}}
@media(min-width:1280px){.xl\:pfy-c1{grid-template-columns:repeat(1,minmax(0,1fr))}.xl\:pfy-c2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:pfy-c3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:pfy-c4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:pfy-last-full>:last-child{grid-column:1/-1}.xl\:pfy-last-auto>:last-child{grid-column:auto}}
/* ── Logo klienta w obu motywach (3.10.2026, LogoService + merge-slots.applyLogo) ──
 *  wysokość z tokenu --logo-height (compose.ts); szerokie logo (ratio > 4) niższe; plakietka tylko w motywie z kontrastem < 3:1;
 *  dwa warianty przełączane data-theme (motyw domyślny = data-default-theme, gdy brak data-theme) — bez JS */
img.pfy-logo{height:var(--logo-height,2.5rem)!important;width:auto!important;max-width:min(60vw,22rem);filter:none!important;object-fit:fill}
img.pfy-logo--wide{height:calc(var(--logo-height,2.5rem)*.72)!important}
@media (max-width:639px){img.pfy-logo{height:calc(var(--logo-height,2.5rem)*.8)!important}img.pfy-logo--wide{height:calc(var(--logo-height,2.5rem)*.6)!important}}
img.pfy-logo-plate{background:var(--pfy-plate,#fff);padding:4px 8px;border-radius:8px;box-sizing:content-box}
:root[data-theme="dark"] img.pfy-logo--l,:root:not([data-theme]):not([data-default-theme="light"]) img.pfy-logo--l{display:none!important}
:root[data-theme="light"] img.pfy-logo--d,:root:not([data-theme])[data-default-theme="light"] img.pfy-logo--d{display:none!important}
.pfy-sr{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}

/* 3.10.2026 (Piotr: „drżenie przy przewijaniu”): 100vh w hero zmienia się, gdy telefon chowa pasek adresu → cała strona
   podskakuje przy scrollu. svh = stabilna wysokość małego viewportu; przeglądarki bez svh zostają przy 100vh z klasy. */
#hero.min-h-screen,.mm-hero.min-h-screen{min-height:100svh}

/* ══ Sygnatury archetypów i warstwa powierzchni (3.10.2026, docs/template-design.md §15) ══════════════════════════════
 *  compose.ts wystawia na <body> data-signature="<archetyp>" + data-surface-hero / data-texture / data-card-style /
 *  data-accent-decoration / data-bg-motion / data-button-style (wartości: contract.ts SURFACE_VALUES, domyślne:
 *  archetypes.ts → signature.surface, nadpisanie: template.json → tokens.surface). Strona bez archetypu nie ma tych
 *  atrybutów — nic poniżej jej nie dotyczy. Hero statyczny w 1. malowaniu; ruch tylko pod html.pfy-loaded (site-runtime.js
 *  po `load`) i nigdy przy prefers-reduced-motion. */
/* odręczny akcent warm-local: Caveat (SIL OFL 1.1, data/sections/LICENSES.md) — plik pobierany dopiero, gdy font jest użyty */
@font-face{font-family:'PFY Hand';font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/caveat-sig-cyrillic.woff2) format('woff2');unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'PFY Hand';font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/caveat-sig-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:'PFY Hand';font-style:normal;font-weight:500 700;font-display:swap;src:url(fonts/caveat-sig-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}
/* ── faktura (--texture, krycie --texture-opacity ≤ .08): nakładka nad całą stroną, bez zdarzeń myszy ── */
body[data-texture]:not([data-texture="none"])::after{content:"";position:fixed;inset:0;z-index:2147483000;pointer-events:none;opacity:var(--texture-opacity,.05);background-repeat:repeat}
body[data-texture="grain"]::after{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
body[data-texture="paper"]::after{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.018 .6' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)'/%3E%3C/svg%3E")}
body[data-texture="grid"]::after{background-image:linear-gradient(var(--heading-color) 1px,transparent 1px),linear-gradient(90deg,var(--heading-color) 1px,transparent 1px);background-size:56px 56px}
/* ── karty (--card-style): flat/outline bez cienia (obrys z --card-border zostaje), glass półprzezroczyste; soft-shadow = cień szablonu ── */
body[data-card-style="flat"],body[data-card-style="outline"]{--shadow-card:transparent}
body[data-card-style="glass"]{--card-bg:color-mix(in srgb,var(--bg) 62%,transparent);--card-border:color-mix(in srgb,var(--heading-color) 14%,transparent)}
/* ── dekoracja nagłówków sekcji (--accent-decoration) ── */
body[data-accent-decoration="underline"] main section[data-section]:not(#hero) h2[data-slot$="Title"]::after{content:"";display:block;width:2.75rem;height:3px;border-radius:3px;margin-top:.85rem;background:var(--color-primary)}
body[data-accent-decoration="underline"] main :is(.text-center,[class*="--center"])>h2[data-slot$="Title"]::after,body[data-accent-decoration="underline"] main h2.text-center[data-slot$="Title"]::after{margin-inline:auto}
body[data-accent-decoration="bar"] main section[data-section]:not(#hero) p[data-slot$="Kicker"]::before{content:"";display:inline-block;width:1.75rem;height:2px;margin-right:.7rem;vertical-align:middle;background:currentColor}
/* ── tło hero (--surface-hero): gradient z palety pod treścią; image-overlay/video/flat = media daje wariant ── */
body[data-surface-hero="gradient-linear"] #hero{background-image:linear-gradient(155deg,color-mix(in srgb,var(--color-primary) 14%,transparent) 0%,transparent 55%,color-mix(in srgb,var(--color-accent) 10%,transparent) 100%)!important;background-size:180% 180%}
body[data-surface-hero="gradient-radial"] #hero{background-image:radial-gradient(60% 70% at 88% 12%,color-mix(in srgb,var(--color-primary) 16%,transparent),transparent 70%),radial-gradient(50% 60% at 8% 92%,color-mix(in srgb,var(--color-accent) 12%,transparent),transparent 70%)!important;background-size:180% 180%}
@keyframes pfy-drift{from{background-position:0% 0%}to{background-position:100% 100%}}
html.pfy-loaded body[data-bg-motion="drift"] #hero{animation:pfy-drift 20s ease-in-out infinite alternate}
/* ── plamy (--bg-motion: blobs): statyczne w 1. malowaniu, powolny dryf po load ── */
body[data-signature] #hero:has(>.pfy-sig-blobs){position:relative;isolation:isolate}
.pfy-sig-blobs{display:none}
body[data-bg-motion="blobs"] .pfy-sig-blobs{display:block;position:absolute;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
body[data-bg-motion="blobs"] .mm-hero>.pfy-sig-blobs{z-index:0} /* hero na zdjęciu: nad przyciemnieniem (z -1), pod treścią (później w DOM) */
.pfy-sig-blobs i{position:absolute;border-radius:50%;filter:blur(56px);opacity:.6}
.pfy-sig-blobs i:nth-child(1){width:44vmax;height:44vmax;top:-18vmax;right:-14vmax;background:color-mix(in srgb,var(--color-primary) 60%,transparent)}
.pfy-sig-blobs i:nth-child(2){width:36vmax;height:36vmax;bottom:-20vmax;left:-14vmax;background:color-mix(in srgb,var(--color-accent) 55%,transparent)}
.pfy-sig-blobs i:nth-child(3){width:16vmax;height:16vmax;bottom:8%;right:12%;opacity:.4;background:color-mix(in srgb,var(--color-accent) 50%,var(--color-primary))}
@keyframes pfy-blob{0%{transform:translate(0,0) scale(1)}50%{transform:translate(3vmax,2vmax) scale(1.08)}100%{transform:translate(-2vmax,3vmax) scale(.95)}}
html.pfy-loaded .pfy-sig-blobs i{animation:pfy-blob 24s ease-in-out infinite alternate}
html.pfy-loaded .pfy-sig-blobs i:nth-child(2){animation-duration:29s;animation-direction:alternate-reverse}
html.pfy-loaded .pfy-sig-blobs i:nth-child(3){animation-duration:19s}
/* ── przycisk główny (--button-style) ── */
body[data-button-style="hard-offset"]{--pfy-offset:var(--heading-color)}
body[data-button-style="hard-offset"] .mm-hero{--pfy-offset:rgb(var(--on-media-rgb))}
body[data-button-style="hard-offset"] .btn-primary{box-shadow:4px 4px 0 0 var(--pfy-offset);transition:transform .15s ease,box-shadow .15s ease}
body[data-button-style="hard-offset"] .btn-primary:hover{transform:translate(-2px,-2px);box-shadow:6px 6px 0 0 var(--pfy-offset)}
body[data-button-style="hard-offset"] .btn-primary:active{transform:translate(2px,2px);box-shadow:1px 1px 0 0 var(--pfy-offset)}
body[data-button-style="soft"] .btn-primary{box-shadow:0 10px 24px -12px color-mix(in srgb,var(--color-primary) 75%,transparent);transition:transform .3s ease,box-shadow .3s ease}
body[data-button-style="soft"] .btn-primary:hover{transform:translateY(-2px);box-shadow:0 16px 30px -12px color-mix(in srgb,var(--color-primary) 75%,transparent)}
body[data-button-style="springy"] :is(.btn-primary,.btn-ghost,.btn-outline){transition:transform .4s cubic-bezier(.34,1.56,.64,1),background-color .3s,color .3s,border-color .3s}
body[data-button-style="springy"] :is(.btn-primary,.btn-ghost,.btn-outline):hover{transform:scale(1.03)}
body[data-button-style="springy"] :is(.btn-primary,.btn-ghost,.btn-outline):active{transform:scale(.97)}

/* ── editorial: okładka magazynu ── */
body[data-signature="editorial"] #hero h1[data-sig-folio]{font-size:clamp(2.75rem,9vw,8.5rem);line-height:.94;letter-spacing:-.025em;font-weight:500;overflow-wrap:break-word;hyphens:auto}
body[data-signature="editorial"] #hero h1[data-sig-folio]::before{content:attr(data-sig-folio);content:attr(data-sig-folio) / "";display:block;width:min(100%,20rem);margin-bottom:1.4rem;padding-right:1rem;font:600 .75rem/1 system-ui,sans-serif;letter-spacing:.32em;opacity:.85;background:linear-gradient(currentColor,currentColor) 3.4em 50%/calc(100% - 3.4em) 1px no-repeat}
body[data-signature="editorial"] #hero :is(.text-center)>h1[data-sig-folio]::before,body[data-signature="editorial"] #hero h1.text-center[data-sig-folio]::before{margin-inline:auto}
/* 3.10.2026 (fala v2, recenzja): bez numeracji sekcji „01/02” jako ozdoby — zostaje światło między sekcjami */
body[data-signature="editorial"] main>section[data-section]:not(#hero){padding-block:clamp(6rem,11vw,9.5rem)}
body[data-signature="editorial"] [data-section="stats"] .counter-value{font-size:clamp(3rem,7vw,6rem);line-height:1;font-weight:500;letter-spacing:-.02em}
body[data-signature="editorial"] [data-section="gallery"] [data-slot-item="caption"]{font-style:italic;letter-spacing:.01em}

/* ── bold-video: kinetyczny nagłówek (słowa po load, ≤ 600 ms, transform/opacity — bez przesuwania layoutu) ── */
h1[data-sig-kinetic] .pfy-kw{display:inline-block}
@keyframes pfy-kw{from{opacity:0;transform:translateY(.55em)}}
html.pfy-kinetic h1[data-sig-kinetic] .pfy-kw{animation:pfy-kw var(--kw-d,.32s) cubic-bezier(.2,.75,.25,1) both;animation-delay:var(--kw-t,0s)}

/* ── minimal-portfolio: powietrze i odsłanianie ── */
.pfy-sig-word{color:var(--accent-text)}
body[data-signature="minimal-portfolio"] #hero.mm-hero .pfy-sig-word{color:inherit;text-decoration:underline;text-decoration-color:var(--color-primary);text-decoration-thickness:.07em;text-underline-offset:.14em}
body[data-signature="minimal-portfolio"] [data-gallery-item].pfy-rv{clip-path:inset(0 0 100% 0);transition:clip-path 1s cubic-bezier(.2,.7,.2,1)}
body[data-signature="minimal-portfolio"] [data-gallery-item].pfy-rv.is-in{clip-path:inset(0 0 0 0)}
@media (hover:hover) and (pointer:fine){
  body[data-signature="minimal-portfolio"].pfy-cursor-on [data-section="gallery"] [data-gallery-item]{cursor:none}
  body[data-signature="minimal-portfolio"].pfy-cursor-on [data-section="gallery"] [data-gallery-item] [data-slot-item="caption"]{opacity:0;transition:opacity .3s}
  body[data-signature="minimal-portfolio"].pfy-cursor-on [data-section="gallery"] [data-gallery-item]:focus-visible [data-slot-item="caption"]{opacity:1}
}
.pfy-sig-cursor{position:fixed;left:0;top:0;z-index:9990;pointer-events:none;display:flex;align-items:center;justify-content:center;min-width:5.5rem;min-height:5.5rem;max-width:15rem;padding:.75rem 1.25rem;border-radius:2.75rem;background:var(--color-primary);color:var(--btn-text,#fff);font-size:.8rem;font-weight:600;line-height:1.25;text-align:center;opacity:0;transform:translate3d(var(--x,0),var(--y,0),0) translate(-50%,-50%) scale(var(--s,.2));transition:opacity .2s,transform .25s cubic-bezier(.2,.8,.2,1)}
.pfy-sig-cursor.is-on{opacity:1;--s:1}
.pfy-sig-cursor svg{width:1.5rem;height:1.5rem}

/* ── warm-local: 3.10.2026 (recenzja zewnętrzna) polaroidy i odręczne kickery WYCOFANE z poziomu archetypu („AI template dla kwiaciarni”);
 *  gest archetypu = przerwanie krawędzi (niżej, „Gramatyka kompozycji”, tylko szablony v2). Zostaje spokojny kicker. ── */
:where(:root){--pfy-polaroid:#fbf8f1;--pfy-polaroid-ink:#3b342c}
body[data-signature="warm-local"] main section[data-section] p[data-slot$="Kicker"]{letter-spacing:.2em}

/* ── corporate-trust: pas zaufania pod hero, cienka rama zdjęcia, karty w obrysie ── */
body[data-signature="corporate-trust"] section[data-sig-band]{padding-block:1.5rem;border-block:1px solid var(--card-border)}
body[data-signature="corporate-trust"] section[data-sig-band] #stats-section{display:flex!important;flex-flow:row wrap!important;justify-content:center;gap:1rem 0!important;max-width:64rem;margin-inline:auto;padding:0!important;background:none!important;border:0!important;border-radius:0!important;box-shadow:none!important}
body[data-signature="corporate-trust"] section[data-sig-band] #stats-section>*{flex:1 1 40%;padding:.25rem 1rem!important;margin:0!important;background:none!important;border:0!important;box-shadow:none!important;text-align:center}
body[data-signature="corporate-trust"] section[data-sig-band] .counter-value{font-size:clamp(1.6rem,3vw,2.25rem)!important;line-height:1.1!important;color:var(--primary-text)!important}
@media(min-width:640px){
  body[data-signature="corporate-trust"] section[data-sig-band]{padding-block:1.75rem}
  body[data-signature="corporate-trust"] section[data-sig-band] #stats-section>*{flex:1 1 0;border-left:1px solid var(--card-border)!important}
  body[data-signature="corporate-trust"] section[data-sig-band] #stats-section>:first-child{border-left:0!important}
}
body[data-signature="corporate-trust"] #hero:not(.mm-hero) :is(img[data-slot-img="heroImage"],video){outline:1px solid rgb(var(--on-media-rgb) / .75);outline-offset:-12px}
/* pas zaufania widoczny w pierwszym ekranie: hero niższe o wysokość pasa */
body[data-signature="corporate-trust"] #hero:has(+ section[data-sig-band]){min-height:calc(100svh - 6.5rem)}

/* ── playful: duże ikony branżowe w pełnych kołach (plamy i sprężyste przyciski — warstwa powierzchni wyżej) ── */
body[data-signature="playful"] [data-section="services"] .flex.items-center.justify-center:has(>svg:only-child){width:4.5rem;height:4.5rem;border-radius:9999px}
body[data-signature="playful"] [data-section="services"] .flex.items-center.justify-center:has(>svg:only-child)>svg{width:2.25rem;height:2.25rem}

/* ── operational: rzeczowa typografia, etykiety nad H2 bez ozdobników, CTA bez efektów (decyzja, nie dekoracja) ── */
body[data-signature="operational"] main section[data-section] p[data-slot$="Kicker"]{letter-spacing:.14em}
body[data-signature="operational"] .btn-primary:hover{transform:none}

/* ── ruch sygnatur: zawsze stop przy prefers-reduced-motion ── */
@media (prefers-reduced-motion:reduce){
  .pfy-sig-blobs i,html.pfy-loaded body[data-bg-motion="drift"] #hero,html.pfy-kinetic h1[data-sig-kinetic] .pfy-kw{animation:none!important}
  body[data-button-style] :is(.btn-primary,.btn-ghost,.btn-outline),body[data-signature] [data-gallery-item],.pfy-sig-cursor{transition:none!important}
  body[data-button-style] :is(.btn-primary,.btn-ghost,.btn-outline):is(:hover,:active){transform:none!important}
  body[data-signature="minimal-portfolio"] [data-gallery-item].pfy-rv{clip-path:none!important}
}
/* bold-video: tytuł na wideo jednolitym kolorem (gradient tekstu nie przeżywa animacji słów) */
body[data-signature="bold-video"] #hero h1[data-sig-kinetic].hero-gradient-text{background:none;-webkit-text-fill-color:currentColor}
/* minimal-portfolio: słowo w kolorze marki także w tytule z gradientem tekstu */
.pfy-sig-word{-webkit-text-fill-color:currentColor}

/* ══ Traktowanie zdjęć i chrome per archetyp (3.10.2026, kierunek artystyczny — docs/template-design.md §16) ══════════════════
 *  compose: <body data-photo / data-photo-mask / data-photo-frame / data-photo-cutout> (contract.ts PHOTO_VALUES, domyślne archetypu
 *  archetypes.ts → signature.photo, nadpisanie template.json → tokens.photo). Filtry SVG #pfy-duotone / #pfy-film wstawia merge-photo.ts
 *  z kolorów schematu strony. Filtr nie zmienia wymiarów ani kolejności ładowania — LCP bez zmian. Wyjątek od traktowania: logo
 *  i wszystko w [data-photo-raw] (np. przed/po, gdzie liczy się prawdziwy kolor). */
body[data-photo="duotone"] main section[data-section] img:not([data-slot-img="logo"]):not([data-photo-raw] img){filter:url(#pfy-duotone)}
body[data-photo="film"] main section[data-section] img:not([data-slot-img="logo"]):not([data-photo-raw] img){filter:url(#pfy-film)}
body[data-photo="mono"] main section[data-section] img:not([data-slot-img="logo"]):not([data-photo-raw] img){filter:grayscale(1) contrast(1.08)}
body[data-photo="mono-accent"] main section[data-section] img:not([data-slot-img="logo"]):not([data-photo-raw] img){filter:grayscale(1) contrast(1.14) brightness(1.03);transition:filter .8s ease}
/* kolor wraca pod kursorem — „podejdź bliżej” (duotone i czarno-białe z kolorem; film zostaje ciepły) */
body:is([data-photo="duotone"],[data-photo="mono-accent"]) main :is(a,figure,[data-gallery-item],[data-slot-repeat]>*):is(:hover,:focus-visible) img:not([data-slot-img="logo"]){filter:none}
body[data-photo="duotone"] main section[data-section] img:not([data-slot-img="logo"]){transition:filter .8s ease}
/* maska i rama — tylko kadr „portretowy”, który wariant oznaczył [data-photo-portrait] (hero split, „o nas”) */
body[data-photo-mask="arch"] [data-photo-portrait] img,body[data-photo-mask="arch"] [data-photo-portrait]>.pfy-ph{border-radius:9999px 9999px 0 0}
body[data-photo-mask="circle"] [data-photo-portrait] img{clip-path:circle(closest-side)}
body[data-photo-mask="slant"] [data-photo-portrait] img{clip-path:polygon(0 0,100% 0,100% 86%,0 100%)}
body[data-photo-frame="hairline"] [data-photo-portrait]:not([data-cut="1"]) img{outline:1px solid color-mix(in srgb,var(--heading-color) 60%,transparent);outline-offset:10px}
body[data-photo-frame="offset"] [data-photo-portrait]:not([data-cut="1"]) img{box-shadow:1.25rem 1.25rem 0 0 color-mix(in srgb,var(--color-accent) 30%,var(--bg))}
body[data-photo-frame="polaroid"] [data-photo-portrait]:not([data-cut="1"]) img{padding:.65rem .65rem 2.6rem;background:var(--pfy-polaroid,#fbf8f1);box-shadow:0 18px 36px -18px rgba(0,0,0,.5),0 2px 6px rgba(0,0,0,.08)}
/* wycinanka bez tła: nigdy rama ani maska na samej postaci (kompozycję daje wariant), cień pod postacią */
[data-photo-cut][data-cut="1"] img[data-cutout]{border-radius:0!important;clip-path:none!important;outline:0!important;padding:0!important;background:none!important}

/* ── przyciski: hand (warm-local — miękki, drugorzędny z odręcznym zawijasem) / ink (corporate — prostokąt, drugorzędny = podkreślenie) ── */
body[data-button-style="hand"] .btn-primary{box-shadow:0 10px 24px -12px color-mix(in srgb,var(--color-primary) 75%,transparent);transition:transform .3s ease,box-shadow .3s ease}
body[data-button-style="hand"] .btn-primary:hover{transform:translateY(-2px) rotate(-1deg)}
body[data-button-style="hand"] main :is(.btn-ghost,.btn-outline){border-color:transparent!important;background:none!important;position:relative;padding-inline:.25rem!important}
body[data-button-style="hand"] main :is(.btn-ghost,.btn-outline)::after{content:"";position:absolute;left:0;right:0;bottom:.3rem;height:.6rem;opacity:.7;background:var(--primary-text);-webkit-mask:no-repeat center/100% 100% url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 12' preserveAspectRatio='none'%3E%3Cpath d='M2 8c18-5 38-6 58-3s40 2 58-3' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");mask:no-repeat center/100% 100% url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 12' preserveAspectRatio='none'%3E%3Cpath d='M2 8c18-5 38-6 58-3s40 2 58-3' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");transform-origin:left;transition:transform .4s ease}
body[data-button-style="hand"] main :is(.btn-ghost,.btn-outline):hover::after{transform:scaleX(1.08)}
body[data-button-style="ink"] :is(.btn-primary,.btn-ghost,.btn-outline){border-radius:0!important;letter-spacing:.04em}
body[data-button-style="ink"] .btn-primary:hover{transform:none;box-shadow:inset 0 -3px 0 0 var(--color-accent)}
body[data-button-style="ink"] main :is(.btn-ghost,.btn-outline){border:0!important;background:none!important;padding-inline:0!important;margin-inline:.75rem;box-shadow:inset 0 -1px 0 0 currentColor;transition:box-shadow .3s ease}
body[data-button-style="ink"] main :is(.btn-ghost,.btn-outline):hover{box-shadow:inset 0 -3px 0 0 var(--color-accent)}

/* ── karty: note (warm-local — karteczka z taśmą) / rule (corporate — bez pudełka, linia nad pozycją, podkreślenie jak w akcie) ── */
body[data-card-style="note"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"],[data-slot-repeat="testimonials"])>*{position:relative;background:var(--pfy-polaroid,#fbf8f1)!important;color:var(--pfy-polaroid-ink,#3b342c);border:0!important;border-radius:3px!important;box-shadow:0 16px 30px -18px rgba(0,0,0,.45),0 1px 3px rgba(0,0,0,.08)!important;transform:rotate(-.8deg);transition:transform .35s ease,box-shadow .35s ease}
body[data-card-style="note"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"],[data-slot-repeat="testimonials"])>:nth-child(2n){transform:rotate(.9deg)}
body[data-card-style="note"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"],[data-slot-repeat="testimonials"])>:nth-child(3n){transform:rotate(-.3deg)}
body[data-card-style="note"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"],[data-slot-repeat="testimonials"])>::before{content:"";position:absolute;z-index:2;top:-.7rem;left:50%;width:5.5rem;height:1.4rem;margin-left:-2.75rem;transform:rotate(-3deg);background:color-mix(in srgb,var(--color-accent) 22%,rgba(255,255,255,.55));box-shadow:0 1px 2px rgba(0,0,0,.08);pointer-events:none}
body[data-card-style="note"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"],[data-slot-repeat="testimonials"])>:is(:hover,:focus-within){transform:rotate(0) translateY(-4px)}
body[data-card-style="note"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"],[data-slot-repeat="testimonials"])>* :is(h3,h4,p,li,span:not(.sr-only)){color:inherit}
body[data-card-style="rule"]{--shadow-card:transparent}
body[data-card-style="rule"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"])>*{background:none!important;border:0!important;border-top:1px solid var(--heading-color)!important;border-radius:0!important;box-shadow:none!important;padding-inline:0!important;position:relative}
body[data-card-style="rule"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"])>* h3{background:linear-gradient(var(--color-accent),var(--color-accent)) 0 100%/0 2px no-repeat;transition:background-size .5s cubic-bezier(.2,.7,.2,1);display:inline;padding-bottom:.15em}
body[data-card-style="rule"] main [data-slot-repeat]:is([data-slot-repeat="services"],[data-slot-repeat="pricingPlans"])>:is(:hover,:focus-within) h3{background-size:100% 2px}

/* font faktów (corporate-trust): IBM Plex Mono (SIL OFL 1.1, static/fonts/LICENSES.md) — pobierany dopiero, gdy użyty */
@font-face{font-family:'PFY Mono';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/plexmono-sig-400-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:'PFY Mono';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/plexmono-sig-400-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:'PFY Mono';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/plexmono-sig-500-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:'PFY Mono';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/plexmono-sig-500-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}

@media (prefers-reduced-motion:reduce){
  body[data-photo] main section[data-section] img,body[data-card-style] main [data-slot-repeat]>*,body[data-card-style] main [data-slot-repeat]>* h3,body[data-button-style] main :is(.btn-ghost,.btn-outline)::after{transition:none!important}
  body[data-card-style="note"] main [data-slot-repeat]>:is(:hover,:focus-within){transform:none!important}
}

/* ══ Gramatyka kompozycji (3.10.2026, recenzja zewnętrzna rund 1–2 — docs/template-design.md §17) ═══════════════════════════════
 *  compose.ts (tylko szablon "composition": "v2"): <body data-composition="<archetyp>" data-grid data-gesture data-intensity
 *  [data-doc-frame]> + --intensity (subtle .6 / standard 1 / bold 1.4 — suwak CHARAKTER). Gest archetypu jest TU, raz — każdy nowy
 *  szablon v2 archetypu go dziedziczy; wariant tylko oznacza miejsce ([data-edge-break], [data-doc-grid], [data-work-media]). */
/* kadr bezpieczny (tokens.photo.crop = safe): kształt pudełka wariantu, środek kadru, BEZ powiększenia (agresywny kadr = crop_confidence ≥ 0,7) */
body[data-photo-crop="safe"] [data-photo-crop]{overflow:hidden}
body[data-photo-crop="safe"] [data-photo-crop] img{object-fit:cover;object-position:50% 50%}
/* warm-local — przerwanie krawędzi: zdjęcie wystaje 8/10/12 % poza siatkę, schodzi na następną sekcję, lekko przesunięte,
   nieregularna maska i prosta plama za nim; działa na każdym zdjęciu (bez wycinanki) */
body[data-gesture="edge-break"]{--edge-break:10%;--edge-overlap:clamp(4rem,13vw,11rem);--edge-tilt:-1.5deg}
body[data-gesture="edge-break"][data-intensity="subtle"]{--edge-break:8%;--edge-overlap:clamp(2.5rem,7vw,6rem);--edge-tilt:-.8deg}
body[data-gesture="edge-break"][data-intensity="bold"]{--edge-break:12%;--edge-overlap:clamp(5rem,16vw,14rem);--edge-tilt:-2.2deg}
body[data-gesture="edge-break"] main{overflow-x:clip}
body[data-gesture="edge-break"] main>section:has([data-edge-break]){position:relative;z-index:3;overflow:visible}
body[data-gesture="edge-break"] main>section#hero:has([data-edge-break]){z-index:5}
body[data-gesture="edge-break"] [data-edge-break]{position:relative;z-index:4;margin-right:calc(-1 * var(--edge-break));margin-bottom:calc(-1 * var(--edge-overlap));transform:translateX(1.5%) rotate(var(--edge-tilt))}
body[data-gesture="edge-break"] [data-edge-break]::before{content:"";position:absolute;z-index:-1;inset:8% -6% -7% 10%;background:color-mix(in srgb,var(--color-primary) 16%,var(--bg));border-radius:58% 42% 61% 39% / 47% 55% 45% 53%;transform:rotate(5deg)}
body[data-gesture="edge-break"] [data-edge-break] img{border-radius:44% 56% 47% 53% / 37% 41% 59% 63%}
/* 3.10.2026 (fala v2): przerwanie w lustrze (zdjęcie po lewej — eco-green) i poza hero (about/edge-note): sekcja pod spodem robi miejsce */
body[data-gesture="edge-break"] [data-edge-break="left"]{margin-right:0;margin-left:calc(-1 * var(--edge-break));transform:translateX(-1.5%) rotate(calc(-1 * var(--edge-tilt)))}
body[data-gesture="edge-break"] [data-edge-break="left"]::before{inset:8% 10% -7% -6%;transform:rotate(-5deg)}
body[data-gesture="edge-break"] main>section:not(#hero):has([data-edge-break]) + section{padding-top:calc(var(--edge-overlap) + 4rem)!important}
@media(max-width:1023px){body[data-gesture="edge-break"] #hero:has([data-edge-break]) + section{padding-top:calc(var(--edge-overlap) + 3rem)!important}}
/* corporate-trust — rama dokumentu: numer strony w stopce każdej sekcji, linia marginesu (2/12) w sekcjach z siatką dokumentu,
   kickery krojem faktów; natężenie: subtelny = bez linii, wyrazisty = linia w kolorze nagłówków */
body[data-doc-frame]{--doc-rule:var(--card-border)}
body[data-doc-frame][data-intensity="bold"]{--doc-rule:var(--heading-color)}
body[data-doc-frame] main>section[data-section][data-doc-page]{position:relative}
body[data-doc-frame] main>section[data-section][data-doc-page]::after{content:attr(data-doc-page);position:absolute;right:max(1rem,calc((100% - 80rem) / 2 + 1.5rem));bottom:.9rem;font-family:'PFY Mono',ui-monospace,monospace;font-size:.62rem;letter-spacing:.18em;text-transform:uppercase;color:var(--text-muted);pointer-events:none}
body[data-doc-frame] main section[data-section] p[data-slot$="Kicker"]{font-family:'PFY Mono',ui-monospace,monospace;letter-spacing:.18em}
@media(min-width:1024px){
  body[data-doc-frame]:not([data-intensity="subtle"]) main>section[data-doc-grid]::before{content:"";position:absolute;top:0;bottom:0;left:calc(max(0px,(100% - 80rem) / 2) + 4.5rem + (min(100%,80rem) - 25rem) / 6);width:1px;background:var(--doc-rule);pointer-events:none}
}
body[data-doc-frame][data-intensity="subtle"] [data-doc-seal]{display:none}
/* minimal-portfolio — praca jest layoutem: udział pierwszego ekranu dla zdjęcia (subtelny 70 % / standard 80 % / wyrazisty 88 %) */
body[data-gesture="work-is-layout"]{--work-share:.8}
body[data-gesture="work-is-layout"][data-intensity="subtle"]{--work-share:.7}
body[data-gesture="work-is-layout"][data-intensity="bold"]{--work-share:.88}


/* playful — żywy element (fala v2): 1–2 elementy mają fizykę (obrót, sprężyste wejście po `load`, reakcja na kursor), reszta strony cicha.
   [data-living="1"] = pierwszy element (naklejka / obrócone zdjęcie hero), [data-living="2"] i lista [data-living-list] (druga karta) = drugi;
   subtelny = tylko pierwszy, standard = dwa, wyrazisty = dwa + mocniejsze wejście. Wejście tylko transform (bez opacity — hero statyczny
   w 1. malowaniu), reduced-motion = stan końcowy bez ruchu. */
body[data-gesture="living-element"]{--live-in:1}
body[data-gesture="living-element"][data-intensity="bold"]{--live-in:1.8}
body[data-gesture="living-element"] [data-living]{transform:rotate(var(--live-rot,-4deg));transition:transform .55s cubic-bezier(.34,1.56,.64,1)}
body[data-gesture="living-element"] [data-living]:hover{transform:rotate(0deg) scale(1.04)}
body[data-gesture="living-element"] [data-living-list]>:nth-child(2){transform:rotate(1.6deg) translateY(-.5rem);box-shadow:0 22px 40px -24px rgb(var(--scrim-rgb) / .45);transition:transform .55s cubic-bezier(.34,1.56,.64,1)}
body[data-gesture="living-element"] [data-living-list]>:nth-child(2):hover{transform:rotate(0deg) translateY(-.75rem)}
body[data-gesture="living-element"][data-intensity="subtle"] [data-living="2"],body[data-gesture="living-element"][data-intensity="subtle"] [data-living-list]>:nth-child(2){transform:none;box-shadow:none}
@keyframes pfy-live-in{0%{transform:translateY(calc(1.25rem * var(--live-in))) rotate(calc(var(--live-rot,-4deg) * 2.5)) scale(.92)}60%{transform:translateY(-.2rem) rotate(calc(var(--live-rot,-4deg) * .6)) scale(1.02)}100%{transform:rotate(var(--live-rot,-4deg))}}
html.pfy-loaded body[data-gesture="living-element"] [data-living="1"]{animation:pfy-live-in calc(.8s * var(--live-in)) cubic-bezier(.34,1.56,.64,1) .15s both}
@media (prefers-reduced-motion:reduce){
  body[data-gesture="living-element"] [data-living],body[data-gesture="living-element"] [data-living-list]>*,html.pfy-loaded body[data-gesture="living-element"] [data-living="1"]{animation:none!important;transition:none!important}
}
/* operational („Operacyjny”, docs/archetype-operacyjny-spec.md) — WCIĘTY DOWÓD: zdjęcie ~1/3 sekcji, górna krawędź 12/15/18 % (subtelny /
   standard / wyrazisty) poniżej górnej krawędzi sąsiedniej treści. Kolumna dowodu = flex w komórce siatki rozciągniętej do wysokości
   treści; odstęp to procent tej wysokości (nie stała w px) — działa przy każdej długości tekstu. Telefon: zwykła kolejność, bez wcięcia. */
body[data-gesture="indented-proof"]{--indent:15%}
body[data-gesture="indented-proof"][data-intensity="subtle"]{--indent:12%}
body[data-gesture="indented-proof"][data-intensity="bold"]{--indent:18%}
@media(min-width:1024px){
  body[data-gesture="indented-proof"] [data-indent-row]{align-items:stretch}
  body[data-gesture="indented-proof"] [data-indent-proof]{display:flex;flex-direction:column;align-self:stretch}
  body[data-gesture="indented-proof"] [data-indent-proof]::before{content:"";flex:0 0 var(--indent)}
  body[data-gesture="indented-proof"] [data-indent-proof]>*{flex:1 1 auto;min-height:0}
}
/* 3.10.2026 (Piotr: „drżenie przy przewijaniu w każdym szablonie”). Dwie przyczyny wspólne dla wszystkich stron:
   1) .section-fade wjeżdżał translateY(24px→0) przez 0,6 s DOKŁADNIE wtedy, gdy użytkownik przewija — treść porusza się
      względem scrolla i wygląda jak drganie; zostaje samo wygaszenie opacity, bez przesunięcia, krócej;
   2) html{scroll-behavior:smooth} na całej stronie podwaja wygładzanie kółka/gestu w części przeglądarek (Firefox, Chrome na
      Windows) i daje „gumowe” dociąganie; płynne przewijanie zostaje tylko dla kliknięć w kotwice (site-runtime.js). */
.section-fade,.slide-up,.slide-left,.slide-right{transform:none!important;transition:opacity .35s ease!important}
.section-fade.visible,.slide-up.visible,.slide-left.visible,.slide-right.visible{transform:none!important}
html{scroll-behavior:auto!important}
/* ── zasoby marki branży (3.10.2026, merge-brand.ts): znak = dwie maski kolorowane tokenami; wzór = kafelek tła body (bez nakładki) ── */
body[data-texture="brand"]::after,body[data-texture-tile]::after{content:none!important}
.pfy-mark{position:relative;display:inline-block;flex:none;width:var(--logo-height,2.5rem);height:var(--logo-height,2.5rem);vertical-align:middle;margin-right:.6rem}
.pfy-mark i{position:absolute;inset:0;display:block;-webkit-mask:var(--m) center/contain no-repeat;mask:var(--m) center/contain no-repeat}
.pfy-mark__ink{--m:var(--pfy-mark-ink);background:var(--heading-color)}
.pfy-mark__tint{--m:var(--pfy-mark-tint);background:var(--color-primary)}
.pfy-mark[data-mono] .pfy-mark__ink{background:var(--color-primary)}
footer .pfy-mark{margin-right:.5rem}
/* faktura brand: sekcje na tle --bg przezroczyste (widać kafelek body); sekcje alt zostają PEŁNE — czyste przejścia rytmu zamiast
   półprzezroczystych szwów (Piotr 3.10: „niepokoją przejścia między sekcjami”) */
body[data-texture-tile] [data-section][style*="var(--bg)"]{background-color:transparent!important}
/* sekcje alt na tapecie: zamiast pasa koloru — miękka mgła z rozmytymi krawędziami (Piotr 3.10: „przejścia powinny być niewidoczne”);
   wzór prześwituje przez całą stronę, rytm zostaje jako delikatne pociemnienie środka sekcji */
body[data-texture-tile] [data-section][style*="var(--section-alt)"]{background-color:transparent!important;background-image:linear-gradient(180deg,transparent 0%,color-mix(in srgb,var(--section-alt) 78%,transparent) 22%,color-mix(in srgb,var(--section-alt) 78%,transparent) 78%,transparent 100%)!important}
/* materiały (3.10 noc): właściwy wygląd daje kafelek z merge-brand (data-texture-tile); poniżej AWARYJNA nakładka, gdy kafelka brak (walidator S-e) */
body[data-texture="linen"]::after,body[data-texture="kraft"]::after,body[data-texture="plaster"]::after,body[data-texture="concrete"]::after,body[data-texture="slate"]::after{background-image:linear-gradient(0deg,transparent 0 50%,color-mix(in srgb,var(--heading-color) 5%,transparent) 50%);background-size:3px 3px}
