/* =============================================================================
   dawidkuklinski.pl — sekcje landinga (przenos z Figmy)
   =============================================================================
   Źródło: „Dawid_Kukliński_Home_v2A", frame 68:1214 (1920 × 15932).

   Figma eksportuje ten layout jako pozycjonowanie absolutne z pikselowymi
   offsetami (top: 10535px itd.). To jest zapis WYGLĄDU, nie układu — przepisany
   1:1 nie przetrwałby zmiany długości jednego akapitu, nie mówiąc o telefonie.
   Dlatego układ odtwarzam normalnym przepływem na gridzie, a z makiety biorę
   proporcje, rytm i wartości — nie współrzędne.

   Wczytywany wyłącznie na szablonie „DK — Nowa strona główna (v2)".
   ========================================================================== */

/* -----------------------------------------------------------------------------
   Reset lokalny — landing nie korzysta z nagłówka i stopki Divi
   -------------------------------------------------------------------------- */

body.dk-v2 {
	overflow-x: hidden; /* dekoracja i kadry celowo wychodzą poza kontener */
}

body.dk-v2 #dk-main {
	display: block;
}

.dk-section {
	padding-block: clamp(48px, 30px + 2.4vw, 96px);
}

.dk-center {
	display: flex;
	justify-content: center;
}

/* -----------------------------------------------------------------------------
   Łamanie wierszy 1:1 z makiety

   `<br class="dk-br">` odtwarza złamania odczytane z warstwy tekstowej PDF-a
   (Dawid_Kukliński_Home_v2A.pdf). Stosowane WYŁĄCZNIE w nagłówkach, gdzie
   złamanie jest decyzją kompozycyjną — „Razem / stworzymy ubranie, / które
   opowiada / Twoją historię" to rytm, nie przypadek.

   Poniżej 980px znikają. Na telefonie „Razem" samo w wierszu dałoby cztery
   linie po dwa słowa i kolumnę zamiast nagłówka — tam tekst musi płynąć.

   ⚠ PO KAŻDYM `<br class="dk-br">` MUSI STAĆ BIAŁY ZNAK W KODZIE (nowa linia
   albo spacja). `display: none` usuwa złamanie razem z odstępem, więc bez tego
   wyrazy sklejają się na telefonie w jeden: „Nie każdeszycie na miaręjest
   bespoke". Na desktopie ta spacja jest niewidoczna — biały znak tuż po
   wymuszonym złamaniu wiersza jest z definicji usuwany przy składzie tekstu,
   więc dopisanie go niczego nie psuje. Zgłoszone przez klienta 2026-08-02
   („masa zgubionych spacji") — 14 sklejeń, wszystkie w nagłówkach.

   W AKAPITACH treści świadomie ich NIE ma: tam złamanie wynika z szerokości
   kolumny (457px w makiecie), a nie z decyzji projektanta. Zakodowane na sztywno
   psułoby się przy każdej innej szerokości i przy powiększeniu czcionki.
   -------------------------------------------------------------------------- */

@media (max-width: 980px) {
	.dk-br {
		display: none;
	}
}

/* Sieroty: żaden akapit nie kończy się pojedynczym wyrazem w wierszu.
   `pretty` każe przeglądarce przeliczyć łamanie tak, aby ostatni wiersz nie
   został sam. Dotyczy tekstu PŁYNĄCEGO — nagłówków z twardymi <br class="dk-br">
   nie ruszamy, bo tam łamanie jest podyktowane makietą.

   Drugą połowę reguły (jednoliterowe spójniki na końcu wiersza) załatwia
   dk_typo() w functions.php twardą spacją — CSS tego nie potrafi. */
body.dk-v2 p,
body.dk-v2 .dk-body,
body.dk-v2 .dk-lead,
body.dk-v2 .dk-h3-loose,
body.dk-v2 .dk-h-alt,
body.dk-v2 .dk-h-hero-s,
body.dk-v2 .dk-card__body h3 {
	/* Także na nagłówkach akapitowych (.dk-h-hero-s) — przy ~820px zostawała
	   tam sierota „rezultatów.". Tam, gdzie taki nagłówek ma twarde <br>,
	   `pretty` z nimi nie walczy: złamania wymuszone mają pierwszeństwo. */
	text-wrap: pretty;
}

/* -----------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.dk-hero {
	align-items: flex-end;
	display: flex;
	isolation: isolate;
	margin: var(--dk-fluid-gutter);
	min-height: min(84vh, 900px);
	overflow: hidden;
	position: relative;
}

.dk-hero__bg {
	height: 100%;
	inset: 0;
	object-fit: cover;
	object-position: center 28%;
	position: absolute;
	width: 100%;
	z-index: -1;
}

/* Zdjęcie hero jest jasne u góry — bez przyciemnienia biały tytuł na nim ginie.
   W makiecie tekst leży na ciemniejszym fragmencie kadru; gradient odtwarza ten
   kontrast niezależnie od tego, jak kadr się przytnie na wąskim ekranie. */
.dk-hero::after {
	background: linear-gradient(180deg, rgba(0, 0, 0, .15) 0%, rgba(0, 0, 0, .55) 100%);
	content: "";
	inset: 0;
	position: absolute;
	z-index: -1;
}

.dk-hero__title {
	color: var(--dk-on-dark);
	margin: 0;
	padding: var(--dk-fluid-sp-7);
	text-wrap: balance;
}

/* -----------------------------------------------------------------------------
   Wstęp
   -------------------------------------------------------------------------- */

.dk-intro {
	/* align-items: flex-start — bez tego przycisk (od kiedy ma width: auto)
	   rozciągał się na całą szerokość kolumny, bo flex domyślnie stretchuje. */
	align-items: flex-start;
	display: flex;
	flex-direction: column;
	gap: var(--dk-fluid-sp-6);
	margin-left: auto;
	max-width: 906px;
	width: min(100%, 906px);
}

/* Akapity i nagłówki mają brać pełną szerokość kolumny — stretch wyłączyliśmy
   dla wszystkich dzieci, więc przywracamy go tam, gdzie jest potrzebny. */
.dk-intro > :not(.dk-btn) {
	align-self: stretch;
}

.dk-measure-wide {
	max-width: min(906px, 100%);
}

/* Nagłówek 49px z makiety („H1" w Figmie) — mniejszy niż nagłówki sekcji.
   letter-spacing: normal — tracking -2% jest w Figmie wyłącznie stylem „Body". */
.dk-h-alt {
	font-family: var(--dk-font-display);
	font-size: var(--dk-fluid-h1);
	font-variation-settings: var(--dk-display-axes);
	font-weight: var(--dk-fw-regular);
	letter-spacing: normal;
	line-height: var(--dk-lh-h1);
	margin: 0;
}

/* Nagłówek sekcji 61px („Hero S") użyty w miejscach, gdzie nie ma <h2>. */
.dk-h-hero-s {
	font-family: var(--dk-font-display);
	font-size: var(--dk-fluid-h2);
	font-variation-settings: var(--dk-display-axes);
	font-weight: var(--dk-fw-regular);
	letter-spacing: normal;
	line-height: var(--dk-lh-h2);
	margin: 0;
}

.dk-h3-loose {
	font-family: var(--dk-font-display);
	font-size: var(--dk-fluid-h3);
	font-variation-settings: var(--dk-display-axes);
	letter-spacing: normal;
	line-height: var(--dk-lh-h3-loose);
	margin: 0;
}

/* Wyróżnienie w trzech kolumnach „o mnie" (Figma 83:1677 i sąsiednie).
   W makiecie to WYŁĄCZNIE zmiana koloru z #2c2721 na czarny — bez pogrubienia.
   Znacznik <strong> zostaje ze względu na semantykę i czytniki ekranu, ale wagę
   dziedziczymy, żeby nie robić boldu, którego w projekcie nie ma. */
.dk-cols-3 strong,
.dk-card__body strong {
	color: var(--dk-ink);
	font-weight: inherit;
}

.dk-body {
	font-size: var(--dk-fluid-body);
	letter-spacing: var(--dk-ls-body-r);
	line-height: var(--dk-lh-body);
	margin: 0;
}

.dk-accent-warm {
	color: var(--dk-accent-warm);
}

/* -----------------------------------------------------------------------------
   Sekcja dzielona: karta tekstowa + zdjęcie

   W makiecie karta nachodzi na zdjęcie. Odtwarzam to gridem z nakładającymi się
   obszarami — dzięki temu przy zwężeniu wystarczy zmienić grid-template, a nie
   przeliczać offsety.
   -------------------------------------------------------------------------- */

/* align-items: stretch, nie center.
   Przy centrowaniu krótsza kolumna (mozaika zdjęć) ustawia się w pionie na
   środku wyższej (karta z tekstem), przez co nad nią i pod nią powstawała
   kilkusetpikselowa dziura. Rozciągnięcie zrównuje starty obu kolumn. */
/* Proporcje kolumn wprost z makiety: zdjęcia 1188px, karta 673px.
   Gap zero — w makiecie karta styka się ze zdjęciami bez odstępu (zdjęcia kończą
   się na 1216px i dokładnie tam zaczyna się karta). Powietrze robi padding karty,
   nie odstęp siatki. */
.dk-split {
	align-items: stretch;
	display: grid;
	gap: 0;
	grid-template-columns: minmax(0, 673fr) minmax(0, 1188fr);
}

.dk-split--card-right {
	grid-template-columns: minmax(0, 1188fr) minmax(0, 673fr);
}

/* Kolumna ze zdjęciami NIE wyznacza wysokości sekcji — przejmuje ją z kolumny
   tekstowej i przycina kadry. W makiecie obie kolumny są równej wysokości;
   bez tego zdjęcia (wysokie pionowe kadry) rozpychały sekcję dużo poniżej tekstu.

   `height: 0` sprawia, że element nie zgłasza własnej wysokości do siatki,
   a `min-height: 100%` każe mu wypełnić wiersz wyznaczony przez kartę. */
.dk-split__media,
.dk-mosaic {
	height: 0;
	min-height: 100%;
}

.dk-split__media {
	display: block;
	margin: 0;
	width: 100%;
}

.dk-split__media img {
	display: block;
	height: 100%;
	object-fit: cover;
	width: 100%;
}

/* Obrót kadru z makiety (Figma 68:1224).
   Zapisany tam jako `rotate-180` + `-scale-y-100`. Złożenie obrotu o 180° z
   odbiciem w pionie daje w efekcie ODBICIE W POZIOMIE — postać zostaje w pionie,
   zmienia się strona, w którą jest zwrócona. Sam `rotate(180deg)` postawiłby ją
   na głowie, więc zapisuję obie operacje tak, jak są w projekcie. */
.dk-split__media--flip img {
	transform: rotate(180deg) scaleY(-1);
}

.dk-card {
	display: flex;
	flex-direction: column;
	gap: var(--dk-fluid-sp-6);
	/* Padding z makiety (100px w poziomie, 50px w pionie) — to on daje kartę,
	   bo jej tło jest takie samo jak tło strony. */
	padding: var(--dk-fluid-sp-6) var(--dk-fluid-sp-7);
	position: relative;
	z-index: 1;
}

.dk-card > h2 {
	margin: 0;
	font-size: var(--dk-fluid-h2);
	line-height: var(--dk-lh-h2);
}

/* RYTM PIONOWY — odstępy celowo NIEJEDNAKOWE (2026-08-04, uwaga klienta).

   Wcześniej stało tu `gap: var(--dk-fluid-sp-6)`, czyli jeden odstęp między
   wszystkim: między akapitami opisowymi, przed leadem i po leadzie. Efekt był
   płaski — akapity rozstrzelone, a lead („Bespoke to coś zupełnie innego…")
   niczym się od nich nie odcinał, mimo że ma inną rangę.

   Zasada od klienta: mniej przestrzeni w tekstach opisowych, więcej tam, gdzie
   pojawia się lead, cytat, a tym bardziej nagłówek. Odstęp robią więc marginesy
   sąsiadów, a nie `gap` — bo `gap` z definicji nie potrafi być różny dla różnych
   par elementów.

   Proporcja z makiety: przed leadem ≈ 1,6× odstępu między akapitami. */
.dk-card__body {
	display: flex;
	flex-direction: column;
	gap: 0;
}

/* ⚠ ZEROWANIE PRZEZ `> *`, NIE PRZEZ NAZWY ELEMENTÓW — i to nie jest kosmetyka.
   Gwiazdka nie wnosi ŻADNEJ wagi do specyficzności, więc reguła sąsiedztwa
   `.dk-card__body > * + *` ma tylko (0,1,0). Napisane wcześniej
   `.dk-card__body p { margin: 0 }` ma (0,1,1) i po prostu ją biło — odstęp
   między akapitami wychodził ZEROWY, mimo że reguła stała niżej w pliku.
   Kolejność tu nie pomaga, bo to nie remis: (0,1,1) wygrywa z (0,1,0) zawsze.

   `> *` daje (0,1,0), czyli równo z regułą sąsiedztwa — a wtedy rozstrzyga już
   kolejność i wygrywa ta późniejsza, czyli właściwa. */
.dk-card__body > * {
	margin: 0;
}

/* Domyślnie — tekst płynący, najciaśniej. */
.dk-card__body > * + * {
	margin-top: var(--dk-fluid-sp-blok);
}

/* Przed leadem/nagłówkiem — oddech, który sygnalizuje zmianę rangi tekstu.
   Selektor na `* + h3`, a nie `p + h3`: lead może iść także po liście albo
   po innym nagłówku i odstęp ma się wtedy zachować tak samo. */
.dk-card__body > * + h3 {
	margin-top: var(--dk-fluid-sp-lead);
}

/* -----------------------------------------------------------------------------
   Mozaika trzech zdjęć (sekcje „bespoke" i „proces")

   Makieta: dwa kadry jeden pod drugim po lewej + jeden wysoki po prawej,
   wszystkie STYKAJĄCE SIĘ — w Figmie kadr lewy kończy się na 623px i dokładnie
   tam zaczyna się prawy, a dolny zaczyna się tam, gdzie kończy się górny.
   Stąd gap: 0.
   -------------------------------------------------------------------------- */

.dk-mosaic {
	display: grid;
	gap: 0;
	grid-template-areas:
		"a tall"
		"b tall";
	grid-template-columns: 1fr 1fr;
}

/* Kolejność wysokości kadrów RÓŻNI SIĘ między sekcjami — sprawdzone we
   współrzędnych z Figmy, nie założone:
     „bespoke" (68:1226/68:1225): górny 426, dolny 669,
     „proces"  (68:1235/68:1236): górny 669, dolny 426.  */
.dk-mosaic--low-first {
	grid-template-rows: 426fr 669fr;
}

.dk-mosaic--tall-first {
	grid-template-rows: 669fr 426fr;
}

.dk-mosaic img {
	display: block;
	height: 100%;
	min-height: 0;
	object-fit: cover;
	width: 100%;
}

.dk-mosaic__a    { grid-area: a; }
.dk-mosaic__b    { grid-area: b; }
.dk-mosaic__tall { grid-area: tall; }

/* -----------------------------------------------------------------------------
   Ciemny pas + zdjęcie pełnej szerokości
   -------------------------------------------------------------------------- */

.dk-band {
	/* Szerokość jak reszta strony (w makiecie pas ma 1860 z 1920) i wyśrodkowanie.
	   Sam margines gutter rozciągał pas na całą szerokość ekranu 2K+, przez co
	   nie trzymał się linii pozostałych sekcji. */
	margin-inline: auto;
	max-width: var(--dk-container);
	width: calc(100% - 2 * var(--dk-fluid-gutter));
	padding-block: clamp(48px, 26px + 2.8vw, 104px);
}

.dk-band .dk-content {
	display: flex;
	flex-direction: column;
	gap: var(--dk-fluid-sp-6);
}

.dk-band h3 {
	margin: 0;
}

/* BEZ własnego marginesu. Ten element ma też klasę .dk-container, która
   ustawia `margin-inline: auto` (centrowanie) i `padding-inline` (gutter).
   Nadpisanie marginesem zabijało centrowanie: powyżej 1860px kontener zostawał
   przy lewej krawędzi, a po prawej robiła się pusta przestrzeń. */

/* Kadr pełnej szerokości.

   Wysokość liczona z PROPORCJI MAKIETY (1860×1370 → 0.7366), nie sztywnym
   clampem — wcześniej dawał 353px przy 1440, czyli pasek zamiast zdjęcia.
   `max-height: 82vh` pilnuje, żeby na niskim oknie kadr nie przykrył całego
   ekranu; nadmiar jest przycinany przez object-fit, nie skalowany.

   object-position odtwarza kadrowanie z Figmy: tam obraz jest przeskalowany do
   181.02% wysokości i przesunięty o -33.14%, więc widoczne jest pasmo od 18.3%
   do 73.6% oryginału — czyli środek wypada na 46%, nie na 50%. */
.dk-fullbleed img {
	display: block;
	/* Wysokość liczona WPROST, bez aspect-ratio.
	   Poprzednia wersja łączyła `aspect-ratio` z `max-height` — a gdy max-height
	   przycinał wysokość, przeglądarka przeliczała z proporcji także SZEROKOŚĆ.
	   Na szerokim, niskim oknie obraz zwężał się do ~870px i wisiał przy lewej
	   krawędzi z pustką obok. Przy jawnej wysokości szerokość zostaje 100%,
	   a nadmiar przycina object-fit.

	   50vw ≈ proporcja z makiety (1370/1860 = 0.74 szerokości kontenera,
	   który sam ma ~96vw), 78vh pilnuje, żeby kadr nie przykrył całego ekranu. */
	height: min(50vw, 78vh);
	min-height: 300px;
	object-fit: cover;
	object-position: center 46%;
	width: 100%;
}

/* -----------------------------------------------------------------------------
   Sekcja „Wszystko zaczęło się od"
   -------------------------------------------------------------------------- */

.dk-story {
	display: flex;
	flex-direction: column;
	gap: var(--dk-fluid-sp-6);
}

.dk-story__kicker {
	margin: 0;
	max-width: min(var(--dk-measure), 100%);
}

.dk-story__display {
	margin: 0;
}

/* Tekst dekoracyjny — w makiecie ogromny, półprzezroczysty, wystaje poza kadr. */
/* W makiecie słowo siedzi ciasno pod „zaczęło się od" — jest dopełnieniem
   zdania, nie osobnym blokiem. Playfair ma wysokie wydłużenia górne, więc sam
   zerowy odstęp nie wystarcza: nad literami zostaje pusty pas wewnątrz linii.
   Stąd ujemny margines liczony w em rozmiaru samego słowa, a nie w px —
   skaluje się razem z nim. */
.dk-decor {
	/* Marginesy w em rozmiaru samego słowa, żeby skalowały się razem z nim.
	   Góra ciasno (wydłużenia górne Playfaira zostawiają pusty pas w linii),
	   dół z zapasem na ogonki („ę" w „chęci", „j" w „pasji") — przy interlinii
	   0.8 wychodzą poza pudełko i przy zerowym marginesie wchodziły na kolumny. */
	margin: -.18em 0 .2em;
}

/* Parametry odczytane z nagrania makiety (Dawid_Kukliński_Home_v2A.mp4):
   8 s pełnego cyklu, 2 s na słowo, kolejność pytań → pasji → pracy → chęci,
   przejście to czysty crossfade — bez przesunięcia w pionie.
   Zmierzone na klatkach: 0.2 s słowo ledwo widoczne, 1.0 s pełne, 1.8 s gaśnie. */
.dk-decor__word {
	animation: dk-decor-rotate 8s linear infinite;
	grid-area: 1 / 1;
	opacity: 0;
}

.dk-decor__word:nth-child(2) { animation-delay: 2s; }
.dk-decor__word:nth-child(3) { animation-delay: 4s; }
.dk-decor__word:nth-child(4) { animation-delay: 6s; }

@keyframes dk-decor-rotate {
	0%        { opacity: 0; }
	6%        { opacity: 1; }
	19%       { opacity: 1; }
	25%, 100% { opacity: 0; }
}

/* Bez ruchu zostaje pierwsze słowo. Zmieniający się napis tej wielkości to
   dokładnie ten rodzaj animacji, którego dotyczy ta preferencja. */
@media (prefers-reduced-motion: reduce) {
	.dk-decor__word {
		animation: none;
	}

	.dk-decor__word:first-child {
		opacity: 1;
	}
}

/* -----------------------------------------------------------------------------
   Portfolio — kadr środkowy pełny, boczne przygaszone (opacity .3 z makiety)
   -------------------------------------------------------------------------- */

.dk-portfolio {
	display: grid;
	gap: var(--dk-sp-4);
	grid-template-columns: 1fr 1.4fr 1fr;
	margin-inline: auto;
	max-width: var(--dk-container);
	width: calc(100% - 2 * var(--dk-fluid-gutter));
}

.dk-portfolio img {
	display: block;
	height: clamp(260px, 14vw + 180px, 620px);
	object-fit: cover;
	width: 100%;
}

.dk-portfolio__side {
	opacity: .3;
}

/* -----------------------------------------------------------------------------
   Formularz
   -------------------------------------------------------------------------- */

.dk-form {
	display: flex;
	flex-direction: column;
	gap: var(--dk-fluid-sp-6);
	margin-top: var(--dk-fluid-sp-7);
}

.dk-form__note {
	margin: 0 0 calc(var(--dk-fluid-sp-6) * -1);
	padding-left: var(--dk-sp-4);
}

.dk-form__note label {
	color: var(--dk-ink-placeholder);
	font-size: var(--dk-fluid-body);
	letter-spacing: var(--dk-ls-body-r);
}

/* SPECYFICZNOŚĆ: `body.dk-v2` przed .dk-field to nie ozdobnik.
   Divi styluje pola selektorami typu `input[type="text"]` — to specyficzność
   (0,1,1), która bije samo `.dk-field` (0,1,0). Bez prefiksu pola dostawały
   pełną ramkę Divi zamiast samego podkreślenia z makiety. */
body.dk-v2 .dk-field {
	background: transparent;
	border: 0;
	border-bottom: var(--dk-rule-width) solid var(--dk-rule);
	border-radius: 0;
	box-shadow: none;
	color: var(--dk-ink);
	font-family: var(--dk-font-body);
	font-size: var(--dk-fluid-body);
	letter-spacing: var(--dk-ls-body-r);
	line-height: var(--dk-lh-body);
	padding: var(--dk-sp-2) var(--dk-sp-4);
	transition: border-color .2s ease;
	width: 100%;
}

body.dk-v2 .dk-field::placeholder {
	color: var(--dk-ink-placeholder);
	opacity: 1;
}

/* Stan wypełniony i aktywny — złota linia z makiety (83:1713).
   W Figmie widać go jako „wygląd pola z tekstem"; tutaj jest to realny stan:
   linia zmienia kolor, gdy w polu coś jest albo gdy jest ono aktywne. */
body.dk-v2 .dk-field:focus,
body.dk-v2 .dk-field:not(:placeholder-shown) {
	border-bottom-color: var(--dk-rule-active);
}

/* Tekst wpisany jest w makiecie CZARNY (83:1712), w odróżnieniu od szarych
   etykiet i podpowiedzi (#585862). Domyślny kolor pola jest już czarny —
   reguła jest tu po to, żeby nie zgubić tego przy ewentualnym nadpisaniu. */
body.dk-v2 .dk-field:not(:placeholder-shown) {
	color: var(--dk-ink);
}

body.dk-v2 .dk-field--area {
	resize: vertical;
}

/* -----------------------------------------------------------------------------
   Formularz — stany wysyłki (od 2026-08-03, podpięcie prawdziwej obsługi)

   Makieta nie opisuje ani błędu, ani potwierdzenia — projektant pokazał tylko
   stan spoczynkowy i wypełniony. Poniższe stany są więc DOPISANE, ale trzymają
   się palety i typografii z tokenów: żadnego czerwonego alertu z bootstrapa,
   błąd niesie ten sam ciepły akcent (#4a453e), co kursywa nagłówka sekcji.
   -------------------------------------------------------------------------- */

/* Honeypot — pole pułapka na automaty.

   NIE `display: none` ani `visibility: hidden`: prostsze boty pomijają pola
   ukryte w ten sposób, bo to najbardziej oczywisty wzorzec. Zdejmujemy je
   z układu geometrią, zostawiając „widoczne" dla maszyny wypełniającej
   wszystko, co znajdzie w DOM-ie.

   `position: absolute` względem formularza (ma position: relative niżej),
   więc pole nie rozpycha kolumny. */
.dk-hp {
	height: 1px;
	left: -9999px;
	overflow: hidden;
	position: absolute;
	top: auto;
	width: 1px;
}

.dk-form {
	position: relative;
}

/* Komunikat błędu — pod polem, którego dotyczy. */
.dk-form-blad {
	color: var(--dk-accent-warm);
	font-size: var(--dk-fluid-body);
	letter-spacing: var(--dk-ls-body-r);
	line-height: var(--dk-lh-body);
	/* Ujemny górny margines kasuje gap flexa: komunikat ma przylegać do swojego
	   pola, a nie wisieć w połowie drogi do następnego. */
	margin: calc(var(--dk-fluid-sp-6) * -1 + var(--dk-sp-1)) 0 0;
	padding-left: var(--dk-sp-4);
}

/* Błąd ogólny (nonce, limit, nieudana wysyłka) stoi nad całym formularzem,
   więc nie podciągamy go pod żadne pole. */
.dk-form-blad--ogolny {
	margin: 0;
}

/* Pole z błędem — linia w kolorze akcentu zamiast szarej.
   Prefiks body.dk-v2 z tego samego powodu co przy .dk-field: Divi styluje
   `input[type="text"]` i bez tego wygrywa. Reguła musi też bić stan
   `:not(:placeholder-shown)` wyżej — stąd ta sama waga i późniejsza pozycja. */
body.dk-v2 .dk-field--zle,
body.dk-v2 .dk-field--zle:focus,
body.dk-v2 .dk-field--zle:not(:placeholder-shown) {
	border-bottom-color: var(--dk-accent-warm);
	border-bottom-width: 2px;
}

/* Potwierdzenie wysyłki — zastępuje formularz. */
.dk-form-ok {
	border-top: var(--dk-rule-width) solid var(--dk-rule-active);
	margin-top: var(--dk-fluid-sp-7);
	padding-top: var(--dk-fluid-sp-6);
}

.dk-form-ok__title {
	margin: 0 0 var(--dk-sp-3);
}

.dk-form-ok .dk-body {
	margin: 0;
	max-width: min(var(--dk-measure), 100%);
}

.dk-check {
	align-items: center;
	cursor: pointer;
	display: flex;
	font-size: var(--dk-fluid-body);
	gap: var(--dk-sp-3);
	letter-spacing: var(--dk-ls-body-r);
}

/* Kwadrat 46×46 z obrysem — makieta nie ma stanu zaznaczonego, więc zostawiam
   natywny znacznik przeglądarki i tylko skaluję pole.
   Prefiks body.dk-v2 z tego samego powodu co przy .dk-field — Divi styluje
   `input[type="checkbox"]` z wyższą specyficznością. */
body.dk-v2 .dk-check input {
	accent-color: var(--dk-btn-bg);
	block-size: clamp(28px, 20px + 1.2vw, 46px);
	border: var(--dk-rule-width) solid var(--dk-rule);
	flex: none;
	inline-size: clamp(28px, 20px + 1.2vw, 46px);
	margin: 0;
}

/* -----------------------------------------------------------------------------
   Przycisk — ikona strzałki z makiety
   -------------------------------------------------------------------------- */

.dk-btn__icon {
	filter: brightness(0) invert(1); /* strzałka z Figmy jest czarna, na przycisku ma być biała */
	flex: none;
	height: var(--dk-fluid-btn-icon);
	transition: transform .25s cubic-bezier(.2, .7, .3, 1);
	width: var(--dk-fluid-btn-icon);
}

/* Strzałka „w górę w prawo" — na hover jedzie w swoją stronę.
   Makieta nie opisuje tego ruchu (Figma daje tylko zmianę tła), więc to
   dodatek: kierunek animacji wynika wprost z kształtu ikony. */
.dk-btn:hover .dk-btn__icon,
.dk-btn:focus-visible .dk-btn__icon {
	transform: translate(.22em, -.22em);
}

@media (prefers-reduced-motion: reduce) {
	.dk-btn__icon {
		transition: none;
	}

	.dk-btn:hover .dk-btn__icon,
	.dk-btn:focus-visible .dk-btn__icon {
		transform: none;
	}
}

/* -----------------------------------------------------------------------------
   Stopka
   -------------------------------------------------------------------------- */

.dk-footer {
	align-items: center;
	display: flex;
	/* flex-wrap od 2026-08-04: w stopce stoi teraz trzeci element (menu),
	   a trzy bloki obok siebie nie mieszczą się poniżej ~900px. */
	flex-wrap: wrap;
	gap: var(--dk-fluid-sp-6);
	justify-content: space-between;
	padding-block: clamp(40px, 24px + 2vw, 80px);
}

.dk-footer__nav-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--dk-sp-3);
	list-style: none;
	margin: 0;
	padding: 0;
}

body.dk-v2 .dk-footer__nav-list a {
	color: var(--dk-ink-body);
	font-family: var(--dk-font-body);
	font-size: clamp(11px, 9.4px + 0.21vw, 14px);
	letter-spacing: .12em;
	text-decoration: none;
	text-transform: uppercase;
	white-space: nowrap;
}

body.dk-v2 .dk-footer__nav-list a:hover,
body.dk-v2 .dk-footer__nav-list a:focus-visible {
	text-decoration: underline;
	text-underline-offset: .35em;
}

.dk-footer__logo {
	height: auto;
	width: clamp(160px, 120px + 8vw, 274px);
}

.dk-footer__contact {
	display: flex;
	flex-direction: column;
	font-size: var(--dk-fluid-lead);
	font-style: normal;
	gap: var(--dk-sp-1);
	line-height: var(--dk-lh-lead);
	text-align: right;
}

.dk-footer__contact a {
	color: inherit;
	text-decoration: none;
}

.dk-footer__contact a:hover {
	text-decoration: underline;
}

/* =============================================================================
   PRZEŁAMANIA
   ========================================================================== */

@media (max-width: 980px) {
	/* Karta i zdjęcie przestają stać obok siebie. Kolejność w HTML jest tak
	   ułożona, żeby po zwinięciu tekst szedł przed obrazem — czyta się sensownie
	   bez dodatkowego order. */
	.dk-split,
	.dk-split--card-right {
		gap: var(--dk-fluid-sp-6);
		grid-template-columns: minmax(0, 1fr);
	}

	/* OBOWIĄZKOWY reset sztuczki „height: 0 / min-height: 100%".
	   W jednej kolumnie każdy wiersz siatki ma własną wysokość, więc bez tego
	   kolumna ze zdjęciami dostałaby wysokość zero i zniknęła. */
	.dk-split__media,
	.dk-mosaic {
		height: auto;
		min-height: 0;
	}

	.dk-mosaic--low-first,
	.dk-mosaic--tall-first {
		grid-template-rows: auto auto;
	}

	.dk-split__media img {
		aspect-ratio: 4 / 3;
	}

	.dk-card {
		padding-inline: 0;
	}

	.dk-intro {
		margin-left: 0;
	}

	.dk-portfolio {
		/* Boczne kadry były w makiecie tylko tłem — na tablecie zostaje główny. */
		grid-template-columns: 1fr;
	}

	.dk-portfolio__side {
		display: none;
	}

	.dk-footer {
		align-items: flex-start;
		flex-direction: column;
	}

	.dk-footer__contact {
		text-align: left;
	}
}

@media (max-width: 767px) {
	/* Stopka: trzy bloki jeden pod drugim, wyrównane do lewej. Kontakt miał
	   `text-align: right`, co przy pełnej szerokości kolumny wyglądało na błąd. */
	.dk-footer {
		align-items: flex-start;
		flex-direction: column;
		gap: var(--dk-fluid-sp-6);
	}

	.dk-footer__contact {
		text-align: left;
	}

	.dk-mosaic {
		/* Trzy kadry w pionie zamiast siatki 2×2 — inaczej każdy ma po ~160px. */
		grid-template-areas: "a" "b" "tall";
		grid-template-columns: 1fr;
		grid-template-rows: auto;
	}

	.dk-mosaic img {
		aspect-ratio: 4 / 3;
	}

	.dk-hero {
		min-height: 70vh;
	}
}
