/* ==========================================================================
   BosakDigital — Visual Alchemy
   Anton + Plus Jakarta Sans, zeleno-bílá paleta. Bez frameworků.

    1. Fonty
    2. Tokeny a reset
    3. Typografie
    4. Navigace
    5. Hero
    6. Projekty
    7. Kontakt
    8. Co nabízím (scroll-driven linka)
    9. Manifest
   10. Patička
   11. Reveal animace
   12. Responzivita
   ========================================================================== */

/* 1. Fonty ---------------------------------------------------------------- */

@font-face {
	font-family: 'Anton';
	src: url('../fonts/anton-latin-ext.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	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: 'Anton';
	src: url('../fonts/anton-latin.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
	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: 'Plus Jakarta Sans';
	src: url('../fonts/jakarta-latin-ext.woff2') format('woff2');
	font-weight: 300 700;
	font-style: normal;
	font-display: swap;
	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: 'Plus Jakarta Sans';
	src: url('../fonts/jakarta-latin.woff2') format('woff2');
	font-weight: 300 700;
	font-style: normal;
	font-display: swap;
	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;
}

/* 2. Tokeny a reset ------------------------------------------------------- */

:root {
	/* Hluboká zeleň, ne navy — token se jmenuje podle role, ne podle
	   odstínu, aby další překlopení palety nelhalo. */
	--ink: #0d2621;
	--mist: #b8ded6;
	--white: #ffffff;
	--muted: #8ba7a1;
	--sand: #c9f0e8;
	--glow: #d3fff6;
	--glow-soft: #a9eee0;
	--slate: #1c423a;
	--accent: #2b806f;
	--off-white: #f7fcfb;

	/* Neutrální tma. Zelené pole vedle zeleného webu splývalo — barvu nese
	   akcent, ne plocha. Dva odstíny, aby se sousední tmavé sekce neslily
	   do jednoho bloku. */
	--night: #0e1113;
	--night-2: #171b1e;

	/* Akcent pro tmavé podklady. --accent je na nich příliš tmavý. */
	--mint: #48e0b8;

	/* Nadpis sekce má jednu velikost na celém webu. Čtyři různé z nich
	   dělaly čtyři různé systémy. */
	--title-section: clamp(3rem, 6.6vw, 6.25rem);

	--font-display: 'Anton', 'Arial Narrow', Impact, sans-serif;
	--font-body: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

	--container: 90rem;
	--gutter: 2rem;
	--section-y: 10rem;

	/* Pružný dojezd podle zadání */
	--ease: cubic-bezier(0.16, 1, 0.3, 1);
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--ink);
	color: var(--white);
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 1rem;
	line-height: 1.6;
	cursor: crosshair;
	overflow-x: hidden;
	-webkit-font-smoothing: antialiased;
}

img,
svg {
	display: block;
	max-width: 100%;
}

a {
	color: inherit;
	text-decoration: none;
}

::selection {
	background: var(--mist);
	color: var(--ink);
}

/* 3. Typografie ----------------------------------------------------------- */

.container {
	width: 100%;
	max-width: var(--container);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.section {
	padding-block: var(--section-y);
}

.display {
	margin: 0;
	font-family: var(--font-display);
	font-weight: 400;
	text-transform: uppercase;
	/*
	 * Anton je kondenzovaný, písmena si sedí na klíně sama od sebe.
	 * Záporné prostrkání je lepilo dohromady a české háčky se dotýkaly
	 * sousedních písmen — proto lehce do plusu, ne do minusu.
	 */
	letter-spacing: 0.015em;
	/* Čeština má vysoké háčky; při 0.9 dosedaly na řádek nad sebou. */
	line-height: 0.95;
}

.label {
	margin: 0;
	font-family: var(--font-display);
	font-size: 0.75rem;
	letter-spacing: 0.25em;
	text-transform: uppercase;
}

.eyebrow {
	margin: 0;
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	color: #8d979b;
}

/* Obrys musí růst s písmem — pevná vlasová linka je na velkém wordmarku
   sotva vidět a na mobilu naopak podsaditá. */
/* Nadpis skládaný po písmenech. Používá ho kontakt i Co nabízím, proto
   je to sada sama pro sebe a ne dvakrát to samé pod jiným jménem.
   white-space: pre drží mezeru mezi slovy — span s mezerou by se sesypal. */
.split-letter {
	display: inline-block;
	white-space: pre;
}

.js .split-letter {
	opacity: 0;
	transform: translateY(0.45em) rotate(5deg);
	transition:
		opacity 0.7s var(--ease),
		transform 0.7s var(--ease);
	transition-delay: calc(var(--i) * 45ms);
}

.js .reveal.is-visible .split-letter {
	opacity: 1;
	transform: none;
}

.text-outline {
	color: transparent;
	-webkit-text-stroke-color: rgba(255, 255, 255, 0.92);
	-webkit-text-stroke-width: clamp(1px, 0.012em, 2.6px);
}

/*
 * Přístupnost — viditelné zaměření a přeskakovací odkaz
 *
 * :focus-visible, ne :focus — prsten se ukáže klávesnici, ne myši.
 * Barvu bere z currentColor, takže je vidět na světlé i tmavé sekci
 * bez jediného výjimečného pravidla.
 */
:where(a, button, input, textarea, [tabindex]):focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 3px;
	border-radius: 2px;
}

/* Obal, který není ovládací prvek, prsten nepotřebuje — dostal by ho
   jen proto, že na něj skáče přeskakovací odkaz. */
main:focus-visible {
	outline: none;
}

.skip {
	position: fixed;
	top: 0.75rem;
	left: 0.75rem;
	z-index: 100;
	padding: 0.75rem 1.25rem;
	border-radius: 4px;
	background: var(--white);
	color: var(--night);
	font-family: var(--font-display);
	font-size: 0.8125rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;

	/* Schovaný, ale ne display:none — ten by ho vyřadil z pořadí tabulátoru. */
	transform: translateY(-150%);
	transition: transform 0.2s var(--ease);
}

.skip:focus-visible {
	transform: none;
	outline-offset: 2px;
}

/* 4. Navigace ------------------------------------------------------------- */

.nav {
	position: fixed;
	inset: 0 0 auto;
	z-index: 100;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 2rem;
	padding: 2rem 3rem;
	/* Navigace se převrací podle podkladu, přes který zrovna jede. */
	mix-blend-mode: difference;
	color: var(--white);
}

.nav__logo {
	font-family: var(--font-display);
	font-size: 1.5rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	line-height: 1;
}

.nav__menu {
	display: flex;
	align-items: center;
	gap: 2.5rem;
}

.nav__link {
	position: relative;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
}

.nav__link::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: -0.375rem;
	width: 0;
	height: 1px;
	background: currentColor;
	transition: width 0.22s ease;
}

@media (hover: hover) and (pointer: fine) {
	.nav__link:hover::after {
		width: 100%;
	}
}

.nav__cta {
	padding: 0.875rem 1.75rem;
	border: 1px solid var(--white);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	white-space: nowrap;
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.14s ease-out;
}

@media (hover: hover) and (pointer: fine) {
	.nav__cta:hover {
		background: var(--white);
		color: var(--ink);
	}
}

/*
 * Odezva na stisk. Prvek, který se pod prstem ani nehne, působí jako
 * obrázek — tohle je jediné místo, kde rozhraní potvrdí, že už slyšelo.
 * Reaguje na stisk, ne na puštění, a rychle: přes 160 ms se z potvrzení
 * stává animáček. Není pod dotykovou podmínkou schválně — na telefonu
 * je zpětná vazba potřeba nejvíc.
 */
.nav__cta:active,
.form__submit:active,
.skip:active {
	transform: scale(0.97);
}

/* Tlačítko formuláře se při najetí zvedne; při stisku musí zdvih zaniknout,
   jinak by se stlačení neprojevilo. */
.form__submit:active {
	transform: translateY(0) scale(0.97);
}

/* Lišta s výzvou na telefonu ---------------------------------------------- */

/*
 * Patří k navigaci, ne k obsahu: na telefonu se odkazy v horní liště
 * schovávají a tohle je jejich náhrada tam, kam dosáhne palec.
 *
 * Zobrazuje se jen na úzké obrazovce. Na počítači drží výzvu horní lišta,
 * která je vidět pořád, a spodní pruh by jen ubíral plochu.
 *
 * Viditelnost řídí initStickyCta() v main.js — schovaná je nad heroem
 * (výzva je v něm) i nad kontaktní sekcí (překrývala by vlastní formulář).
 */
.sticky-cta {
	position: fixed;
	inset: auto 0 0;
	z-index: 90;
	display: none;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.75rem 1rem;
	/* Bezpečná zóna pod gestovou čárou na iPhonu — bez ní tlačítko končí pod ní. */
	padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
	border-top: 1px solid rgba(255, 255, 255, 0.1);
	background: rgba(14, 17, 19, 0.92);
	backdrop-filter: blur(12px);
	-webkit-backdrop-filter: blur(12px);
	color: var(--white);
	transform: translateY(110%);
	transition: transform 0.35s var(--ease);
}

/* Musí být až za předchozím pravidlem, jinak display z autorského stylu
   přebije [hidden] z prohlížeče a lišta by svítila i bez JS. */
.sticky-cta[hidden] {
	display: none;
}

.sticky-cta__text {
	display: flex;
	flex-direction: column;
	min-width: 0;
	font-size: 0.8125rem;
	line-height: 1.35;
}

.sticky-cta__text strong {
	font-weight: 700;
}

.sticky-cta__text span {
	color: #8d979b;
}

.sticky-cta__btn {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	flex-shrink: 0;
	padding: 0.8125rem 1.25rem;
	border-radius: 999px;
	background: var(--mint);
	color: #08211d;
	font-family: var(--font-display);
	font-size: 0.8125rem;
	letter-spacing: 0.12em;
	text-indent: 0.12em;
	text-transform: uppercase;
	transition: transform 0.14s ease-out;
}

.sticky-cta__btn svg {
	width: 1rem;
	height: 1rem;
}

.sticky-cta__btn:active {
	transform: scale(0.97);
}

@media (max-width: 760px) {
	.sticky-cta {
		display: flex;
	}

	.sticky-cta[hidden] {
		display: none;
	}

	.sticky-cta.is-on {
		transform: none;
	}
}

/* Na nejužších telefonech se vedle tlačítka vejde jen jeden řádek textu. */
@media (max-width: 380px) {
	.sticky-cta__text span {
		display: none;
	}
}
/* 5. Hero ----------------------------------------------------------------- */

.hero {
	position: relative;
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 8rem 0 4rem;
	/* Podklad shaderu. Drží plochu i než se plátno rozběhne. */
	background: #07070a;
	overflow: hidden;
}

.hero__canvas,
.hero__fallback {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

/* Musí být až za předchozím pravidlem: display z autorského stylu jinak
   přebije [hidden] z prohlížeče a náhrada by se kreslila pořád. */
.hero__canvas[hidden],
.hero__fallback[hidden] {
	display: none;
}

/* Náhrada pro prohlížeč bez WebGL — jeden zamrzlý snímek téhož nápadu. */
.hero__fallback {
	background:
		radial-gradient(28rem 60rem at 32% 100%, rgba(107, 34, 168, 0.45), transparent 70%),
		radial-gradient(22rem 52rem at 58% 100%, rgba(51, 235, 184, 0.28), transparent 68%),
		radial-gradient(26rem 56rem at 74% 100%, rgba(107, 34, 168, 0.3), transparent 72%);
}

.hero__inner {
	position: relative;
	z-index: 1;
	text-align: center;
}

/* Wordmark sedí přesně tam, kde je aurora nejsvětlejší, a bílá do bílé
   nefunguje. Měkký závoj mu podloží plochu, aniž by pozadí zakryl. */
.hero__inner::before {
	content: '';
	position: absolute;
	left: 50%;
	top: 50%;
	z-index: -1;
	width: 132%;
	aspect-ratio: 2 / 1;
	transform: translate(-50%, -50%);
	background: radial-gradient(closest-side, rgba(4, 14, 12, 0.82), rgba(4, 14, 12, 0.45) 55%, rgba(4, 14, 12, 0) 78%);
	pointer-events: none;
}

.hero__title {
	position: relative;
	font-size: clamp(1.75rem, 15vw, 13rem);
	line-height: 0.9;
	text-align: center;
	white-space: nowrap;
}

/* Psaný podtitul pod wordmarkem ------------------------------------------- */

.hero__typed {
	margin: 2.25rem 0 0;
	/* Pod wordmarkem vysokým přes 200 px byl dvanáctibodový řádek drobeček.
	   Prostrkání s velikostí klesá — na 24 px by 0.22em roztrhalo slova. */
	font-size: clamp(1.0625rem, 2.4vw, 1.75rem);
	font-weight: 600;
	line-height: 1.5;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--mist);
}

/*
 * Znaky jsou v layoutu od začátku a jen se rozsvěcují — řádek se tedy
 * nikdy nepřeskládá a zalomí se na úzkém displeji úplně normálně.
 * Do rozsekání držíme odstavec skrytý, ať neproblikne celý text.
 */
.js .hero__typed {
	visibility: hidden;
}

.js .hero__typed.is-ready {
	visibility: visible;
}

.hero__typed-char {
	position: relative;
	opacity: 0;
}

.hero__typed-char.is-on {
	opacity: 1;
}

/* Kurzor visí na posledním odkrytém znaku a putuje s ním. */
.hero__typed-char.is-cursor::after {
	content: '';
	position: absolute;
	top: 0.1em;
	right: -0.16em;
	width: 1px;
	height: 1em;
	background: currentColor;
	animation: caret 1s steps(2, start) infinite;
}

@keyframes caret {
	50% { opacity: 0; }
}


/* Na nízkém okně (notebook na výšku 600–700 px) by se wordmark s podtitulem
   nevešly a overflow: hidden by je uřízl. */
@media (max-height: 720px) {
	.hero {
		padding-block: 6rem 3rem;
	}

	.hero__typed {
		margin-top: 1.5rem;
	}
}
/* 6. Projekty ------------------------------------------------------------- */

.proj {
	background: var(--night-2);
	color: var(--white);
	overflow: hidden;
}

.proj__title {
	margin-bottom: 4rem;
	font-size: var(--title-section);
	text-align: center;
	color: var(--white);
}

/* Nadpis se odkrývá zdola maskou — písmena po sobě už dělají dva nadpisy
   výš na stránce, tady chceme jiný nástup.

   Maska sedí na vnitřním obalu, ne na .reveal prvku. Na jednom prvku se
   obojí zasekne: oříznutý nadpis nemá viditelnou plochu, pozorovatel ho
   nikdy neohlásí a on se nikdy neodkryje. */
.js .proj__title.reveal {
	opacity: 1;
	transform: none;
}

.proj__title-in {
	display: inline-block;
	padding: 0.16em 0;
	margin: -0.16em 0;
}

.js .proj__title-in {
	clip-path: inset(0 0 100% 0);
	transition: clip-path 1s var(--ease);
}

.js .proj__title.is-visible .proj__title-in {
	clip-path: inset(0 0 0 0);
}

/* Čtyři místa v řadě. Karty jsou úzké schválně — ukázka práce, ne
   výkladní skříň. */
.proj__list {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 3rem 2rem;
}

.js .proj__item.reveal {
	transition-delay: calc(var(--i) * 0.1s);
}

/*
 * Ukázka se odkrývá setřením zleva, ne prolnutím — táž řeč jako kresby
 * v sekci Co ještě řeším. Maska sedí na rámu, ne na .reveal prvku:
 * oříznutý prvek nemá viditelnou plochu a pozorovatel ho neohlásí.
 */
.js .proj__frame {
	clip-path: inset(0 100% 0 0);
	transition: clip-path 1s var(--ease) calc(var(--i) * 0.1s + 0.15s);
}

.js .proj__item.is-visible .proj__frame {
	clip-path: inset(0 0 0 0);
}

/* Rám okna prohlížeče — stejná řeč jako karty v sekci Co ještě řeším. */
.proj__frame {
	overflow: hidden;
	border-radius: 6px;
	background: #edeff1;
	box-shadow:
		0 1.5rem 3rem -1.25rem rgba(2, 20, 16, 0.7),
		0 0 0 1px rgba(255, 255, 255, 0.06);
}

.proj__bar {
	display: flex;
	align-items: center;
	gap: 0.45em;
	height: 2.5em;
	padding: 0 1.1em;
	font-size: 0.6875rem;
}

.proj__dot {
	width: 0.55em;
	height: 0.55em;
	flex: none;
	border-radius: 50%;
	background: #c8ccd0;
}

.proj__url {
	overflow: hidden;
	margin-left: 0.7em;
	padding: 0.25em 0.9em;
	border-radius: 999px;
	background: var(--white);
	font-size: 0.85em;
	color: #7b9791;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.proj__shot {
	position: relative;
	display: block;
	/* O kousek plošší než záznam (16:9), takže cover ubírá jen na výšku
	   a šířka zůstane celá. */
	aspect-ratio: 16 / 9.6;
	overflow: hidden;
	background: #e2f0ed;
}

/*
 * Vodorovně se neořezává nic. Ubírá se 7 % zespodu, kde v nahrávce svítí
 * ladicí lišta Tracy z vývojové verze webu M&Z — ta zabírá necelá 3 %,
 * takže je pryč s rezervou. object-position drží záběr u horní hrany,
 * aby ořez padl celý dolů.
 */
.proj__video {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center top;
	transform: scale(1.25);
	transform-origin: 50% 0;
}

/* Rozostření odsává barvu k okrajům, proto je fotka o kus větší. */
.proj__photo {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	transform: scale(1.06);
	filter: blur(7px);
}

.proj__veil {
	position: absolute;
	inset: 0;
	background: rgba(14, 43, 37, 0.55);
}

/* Prázdné místo je jen obrys s číslem. Žádný text, který by sliboval
   práci, co ještě není. */
/* Prázdné místo na neutrálně černém už není vidět tak jako na zeleném —
   okraj i číslo potřebují o kus víc. */
.proj__item--empty .proj__frame {
	background: none;
	box-shadow: none;
	border: 1px solid rgba(255, 255, 255, 0.16);
}

/* Setření patří ukázkám; prázdné místo se místo toho jen tichá nadechne. */
.js .proj__item--empty .proj__frame {
	clip-path: none;
}

.proj__item--empty.is-visible .proj__frame {
	animation: slot-breathe 5s var(--ease) infinite;
}

@keyframes slot-breathe {
	0%, 100% { border-color: rgba(255, 255, 255, 0.16); }
	50% { border-color: rgba(255, 255, 255, 0.3); }
}

/* Prázdné místo nemá lištu okna, takže by bylo o její výšku nižší než
   obsazené karty. Dorovnáváme ji odsazením — 2.5em lišty při jejím
   písmu 0.6875rem. */
.proj__item--empty .proj__frame {
	padding-top: 1.71875rem;
}

.proj__item--empty .proj__shot {
	display: grid;
	place-items: center;
	background: none;
}

.proj__badge {
	position: absolute;
	top: 50%;
	left: 50%;
	padding: 0.6rem 1.15rem;
	border: 1px solid rgba(255, 255, 255, 0.85);
	color: var(--white);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.28em;
	line-height: 1;
	text-indent: 0.28em;
	text-transform: uppercase;
	white-space: nowrap;
	transform: translate(-50%, -50%);
}

/* Popis ------------------------------------------------------------------ */

.proj__body {
	margin-top: 1.5rem;
}

/* Předěl mezi ukázkou a popiskem. Po čísle tu zůstala krátká linka
   visící ve vzduchu — přes celou šířku karty naopak obojí sváže. */
.proj__rule {
	display: block;
	width: 100%;
	height: 1px;
	margin-bottom: 1.125rem;
	background: rgba(255, 255, 255, 0.14);
	transform-origin: center;
}

.js .proj__rule {
	transform: scaleX(0);
	transition: transform 0.8s var(--ease) calc(var(--i) * 0.1s + 0.3s);
}

.js .proj__item.is-visible .proj__rule {
	transform: none;
}

.proj__name {
	margin: 0 0 0.5rem;
	font-family: var(--font-display);
	font-size: 1.375rem;
	line-height: 1.15;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.proj__meta {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	letter-spacing: 0.02em;
	color: var(--muted);
}

/* Čtyři úzké karty se pod 1100 px slepí, dvě jsou akorát. */
@media (max-width: 1100px) {
	.proj__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 620px) {
	.proj__list {
		grid-template-columns: 1fr;
	}

	/* V jednom sloupci by z prázdných míst byly jen dva rámy k prolistování. */
	.proj__item--empty {
		display: none;
	}
}

/* 7. Kontakt -------------------------------------------------------------- */

/*
 * Tmavá. Tmažší z dvojice nocí: nad ní leží řeč o ceně a pod ní Projekty,
 * obě ve světlejším odstínu. Celá spodní část stránky se tím střídá a žádné
 * dvě sekce se neslijou do jedné desky.
 */
.contact {
	background-color: var(--night);
	background-image: radial-gradient(52rem 30rem at 18% 8%, rgba(72, 224, 184, 0.06), transparent 68%);
	background-repeat: no-repeat;
	color: var(--white);
	overflow: hidden;
}

.contact__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(5rem, 11rem) minmax(24rem, 34rem);
	gap: 3rem;
	align-items: center;
}

/* Flex, ne inline: mezi inline-block písmeny by se jinak držela mezera
   z odřádkování ve zdroji a nadpis by se roztrhal. */
.contact__title {
	display: flex;
	flex-wrap: wrap;
	margin: 0 0 2rem;
	font-size: var(--title-section);
	color: var(--white);
}

/* Nadpis sám se nikam neposouvá, pohyb obstarávají písmena. */
.js .contact__title.reveal {
	opacity: 1;
	transform: none;
}

.contact__lead {
	max-width: 32rem;
	margin: 0 0 2.5rem;
	font-size: 1.0625rem;
	line-height: 1.7;
	color: #96a0a4;
	text-wrap: pretty;
}

/* Linka pod adresou doroste při najetí, stejně jako u názvů projektů. */
/* Adresa zůstává v běžném písmu a malými — verzálkami v kondenzovaném
   Antonu se e-mail hůř čte i přepisuje. */
.contact__mail {
	display: inline-block;
	font-size: clamp(1.0625rem, 1.5vw, 1.375rem);
	font-weight: 600;
	letter-spacing: -0.01em;
	color: var(--ink);
	background-image: linear-gradient(currentColor, currentColor);
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 100% 1px;
	transition: background-size 0.3s ease;
}

@media (hover: hover) and (pointer: fine) {
	.contact__mail:hover {
		background-size: 0 1px;
	}
}

/* Šipka mezi textem a kolečkem ------------------------------------------- */

.contact__pointer svg {
	width: 100%;
	height: auto;
	overflow: visible;
}

.contact__pointer path {
	fill: none;
	stroke: rgba(72, 224, 184, 0.42);
	/* S non-scaling-stroke je tloušťka v pixelech obrazovky, ne v jednotkách
	   viewBoxu — pathLength="1" mění jen výpočet čárkování, ne šířku tahu. */
	stroke-width: 1.75;
	stroke-linecap: round;
	stroke-linejoin: round;
	vector-effect: non-scaling-stroke;
	stroke-dasharray: 1;
	stroke-dashoffset: 1;
}

/* Křivka se kreslí, hrot dojde až za ní. */
.js .contact__pointer.is-visible .contact__pointer-line {
	transition: stroke-dashoffset 1.1s var(--ease) 0.35s;
	stroke-dashoffset: 0;
}

.js .contact__pointer.is-visible .contact__pointer-tip {
	transition: stroke-dashoffset 0.4s var(--ease) 1.3s;
	stroke-dashoffset: 0;
}

/* Bez JS se .is-visible nepřidá, tak ať šipka nezmizí úplně. */
html:not(.js) .contact__pointer path {
	stroke-dashoffset: 0;
}

/* Formulář ----------------------------------------------------------------
   Podtržená pole místo rámečků: sekce je světlá a čtyři obdélníky by v ní
   dělaly zbytečný hluk. */

.form {
	display: grid;
	gap: 1.75rem;
}

.form__pair {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 1.75rem;
}

.form__field {
	position: relative;
	display: grid;
	gap: 0.4rem;
	margin: 0;
}

.form__label {
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--muted);
	transition: color 0.4s var(--ease);
}

.form__field:focus-within .form__label {
	color: var(--accent);
}

.form__input {
	width: 100%;
	padding: 0.5rem 0 0.75rem;
	border: 0;
	border-bottom: 1px solid rgba(13, 38, 33, 0.18);
	border-radius: 0;
	background: none;
	font-family: inherit;
	font-size: 1.125rem;
	line-height: 1.5;
	color: var(--ink);
	transition: border-color 0.4s var(--ease);
}

.form__input::placeholder {
	color: #a4beb9;
}

.form__input:focus {
	outline: none;
	border-bottom-color: var(--accent);
}

.form__input--area {
	resize: vertical;
	min-height: 6.5rem;
}

/* Linka pod polem vyjíždí od kraje — proužek nad původním podtržením,
   ať se barva nepřepíná skokem. */
.form__field::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: 0;
	width: 0;
	height: 2px;
	background: var(--accent);
	transition: width 0.45s var(--ease);
}

.form__field:focus-within::after {
	width: 100%;
}

.form__error {
	font-size: 0.875rem;
	line-height: 1.4;
	color: #b03636;
}

/* Past na roboty nesmí být display:none — část jich takové pole přeskočí. */
.form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.form__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem 1.75rem;
	margin-top: 0.75rem;
}

.form__submit {
	display: inline-flex;
	align-items: center;
	gap: 0.875rem;
	padding: 1.125rem 2.25rem;
	border: 0;
	border-radius: 999px;
	background: var(--ink);
	color: var(--white);
	font-family: var(--font-display);
	font-size: 0.9375rem;
	letter-spacing: 0.18em;
	text-indent: 0.18em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 0.2s ease, transform 0.14s ease-out;
}

@media (hover: hover) and (pointer: fine) {
	.form__submit:hover {
		background: var(--accent);
		transform: translateY(-2px);
	}
}

.form__arrow {
	width: 1.25rem;
	height: 1.25rem;
	transition: transform 0.5s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
	.form__submit:hover .form__arrow {
		transform: translateX(0.25rem);
	}
}

.form__note {
	font-size: 0.9375rem;
	color: var(--muted);
}

.form__note a {
	color: var(--ink);
	border-bottom: 1px solid rgba(13, 38, 33, 0.25);
}

/* Formulář na tmavém podkladu ------------------------------------------- */

.contact .form__label {
	color: #7f898d;
}

.contact .form__field:focus-within .form__label {
	color: var(--mint);
}

.contact .form__input {
	border-bottom-color: rgba(255, 255, 255, 0.2);
	color: var(--white);
}

.contact .form__input::placeholder {
	color: #6b7477;
}

.contact .form__input:focus {
	border-bottom-color: var(--mint);
}

.contact .form__field::after {
	background: var(--mint);
}

.contact .form__error {
	color: #ff9a9a;
}

/* Tlačítko je jediná plná plocha v sekci, tak ať je to ta akcentní. */
.contact .form__submit {
	background: var(--mint);
	color: #08211d;
}

@media (hover: hover) and (pointer: fine) {
	.contact .form__submit:hover {
		background: var(--white);
		color: var(--night);
	}
}

.contact .form__note {
	color: #7f898d;
}

.contact .form__note a {
	color: var(--white);
	border-bottom-color: rgba(255, 255, 255, 0.32);
}

/* Poznámka pod formulářem. Tlumená schválně — patří k formuláři, ale
   nesmí s ním soupeřit o pozornost. */
.form__privacy {
	max-width: 34rem;
	margin: 2.5rem 0 0;
	padding-top: 1.75rem;
	border-top: 1px solid rgba(255, 255, 255, 0.1);
	font-size: 0.8125rem;
	line-height: 1.7;
	color: #7f898d;
}

.form__privacy strong {
	font-weight: 600;
	color: #b6bec1;
}

.form__flash {
	margin: 0 0 1.5rem;
	padding: 1.125rem 1.5rem;
	border-left: 2px solid var(--accent);
	background: rgba(43, 128, 111, 0.07);
	font-size: 1rem;
	line-height: 1.5;
	color: var(--ink);
}

/* Na tmavé kontaktní sekci by tmavý text na skoro průhledném podkladu
   nebyl vidět. Musí stát až za základem, jinak ho základ přebije. */
.contact .form__flash {
	border-left-color: var(--mint);
	background: rgba(72, 224, 184, 0.08);
	color: var(--white);
}

/* Pole nastupují po sobě, stejně jako písmena v nadpisu. */
.js .contact__form.reveal .form__field,
.js .contact__form.reveal .form__foot {
	opacity: 0;
	transform: translateY(0.75rem);
	transition:
		opacity 0.6s var(--ease),
		transform 0.6s var(--ease);
}

.js .contact__form.is-visible .form__field,
.js .contact__form.is-visible .form__foot {
	opacity: 1;
	transform: none;
}

.js .contact__form .form__pair .form__field:nth-child(2) { transition-delay: 0.08s; }
.js .contact__form > .form .form__field:nth-of-type(2) { transition-delay: 0.16s; }
.js .contact__form .form__foot { transition-delay: 0.24s; }

/* Stavy formuláře --------------------------------------------------------- */

/*
 * Chyba. Místo na hlášku je v DOM pořád — je cílem aria-describedby a JS
 * do něj chyby píše. Prázdné by ale drželo mezeru pod každým polem.
 */
.form__error:empty {
	display: none;
}

/*
 * Barva sama o sobě nestačí: kdo barvy nerozlišuje, vidí jen bledší linku.
 * Proto k ní patří i hláška textem — ta nese informaci, linka jen upozorní.
 */
.form__field--error .form__input {
	border-bottom-color: #b03636;
}

.contact .form__field--error .form__input {
	border-bottom-color: #ff9a9a;
}

.form__field--error .form__label {
	color: #b03636;
}

.contact .form__field--error .form__label {
	color: #ff9a9a;
}

/*
 * Odesílání. Šipka ustoupí kolečku na stejném místě, aby tlačítko
 * nepodskočilo — změna šířky v okamžiku kliknutí vypadá jako chyba.
 */
.form__submit {
	position: relative;
}

.form__submit:disabled {
	cursor: progress;
	opacity: 0.75;
}

/* Zdvih při najetí se nesmí prát se zamčeným stavem. */
@media (hover: hover) and (pointer: fine) {
	.form__submit:disabled:hover {
		background: var(--ink);
		transform: none;
	}

	.contact .form__submit:disabled:hover {
		background: var(--mint);
		color: #08211d;
	}
}

.form__spinner {
	display: none;
	width: 1.25rem;
	height: 1.25rem;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	animation: spin 0.7s linear infinite;
}

.form__submit.is-loading .form__arrow {
	display: none;
}

.form__submit.is-loading .form__spinner {
	display: block;
}

@keyframes spin {
	to { transform: rotate(360deg); }
}

/*
 * Při omezené pohyblivosti kolečko netočíme. Odezva ale zmizet nesmí —
 * nese ji text tlačítka („Odesílám…“) a zámek proti druhému kliknutí,
 * takže o informaci nikdo nepřijde.
 */
@media (prefers-reduced-motion: reduce) {
	.form__spinner {
		animation: none;
		border-top-color: currentColor;
		opacity: 0.5;
	}
}
/* 8. Co nabízím ------------------------------------------------------- */

/*
 * Bílá tu byla úplně plochá a od tmavé sekce nad ní ji dělil ostrý řez.
 * Spraví to světlo, ne prvky navíc — a všechno leží v pozadí sekce, takže
 * se to nemá jak plést do linky, textu ani kreseb.
 *
 * Plochy jsou schválně ukotvené za okraji (-8 %, 108 %): dovnitř zasahují
 * jen svým doznívajícím krajem, takže bílá mění teplotu, ale nikde nevznikne
 * skvrna, na kterou by šlo ukázat. Pořadí odshora dolů: doznívání tmavé
 * z předchozí sekce, mátová svatozář za názvem, chladné světlo zleva
 * v první třetině, teplejší zprava ve druhé, poslední nádech vlevo dole
 * a doznění do tmavé sekce pod tím.
 */
.how {
	position: relative;
	background-color: var(--white);
	background-image:
		radial-gradient(46rem 26rem at 50% 1%, rgba(72, 224, 184, 0.18), transparent 66%),
		radial-gradient(58rem 68rem at -12% 30%, rgba(72, 224, 184, 0.2), transparent 72%),
		radial-gradient(62rem 62rem at 112% 60%, rgba(43, 128, 111, 0.12), transparent 74%),
		radial-gradient(48rem 46rem at -8% 90%, rgba(72, 224, 184, 0.15), transparent 72%),
		linear-gradient(to bottom, transparent 12%, rgba(72, 224, 184, 0.05) 46%, transparent 86%),
		linear-gradient(to bottom, rgba(14, 17, 19, 0.055), rgba(14, 17, 19, 0) 26rem),
		linear-gradient(to top, rgba(14, 17, 19, 0.05), rgba(14, 17, 19, 0) 18rem);
	background-repeat: no-repeat;
	color: var(--night);

	/*
	 * Barvy linky a kroků vedou přes proměnné, ať se dají přeladit na jednom
	 * místě a ne roztroušeně po dvaceti pravidlech. Text je neutrálně černý,
	 * ne zelenočerný: zeleň zůstává akcentem — očku, číslům kroků a kresbám.
	 */
	--j-ink: var(--night);
	--j-accent: var(--accent);
	--j-hair: rgba(14, 17, 19, 0.12);
	--j-dot-ring: rgba(14, 17, 19, 0.35);
	--j-dot-fill: var(--white);
	--j-marker-off: rgba(14, 17, 19, 0.45);
	--j-rule-off: rgba(14, 17, 19, 0.24);
	--j-title-off: rgba(14, 17, 19, 0.46);
	--j-text: #5c6568;
	--j-text-off: rgba(92, 101, 104, 0.68);
	overflow: hidden;
}

/*
 * Hlavička: očko, název, krátká linka. Očko říká slovem, co následuje —
 * „01–05“ byl jen údaj z tabulky a nikomu nic neřekl. Název se odkrývá
 * maskou zdola (písmena po sobě už dělají hero i patičku) a pod ním doroste
 * krátká linka od středu do stran.
 */
.how__head {
	margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
	text-align: center;
}

/* Stejná velikost i prostrkání jako číslo kroku níž — dva mikropopisky
   v jedné sekci mají být jedna věc, ne dvě. Odsazení zprava dorovnává
   mezeru, kterou prostrkání přidá za poslední písmeno. */
.how__underline {
	display: block;
	width: 4.5rem;
	height: 2px;
	margin: 2rem auto 0;
	background: var(--accent);
	transform-origin: center;
}

/* Věta pod názvem. Běžné písmo a malá písmena schválně: v Antonu verzálkami
   by to byl třetí popisek ve stejném rejstříku jako popisky kroků. */
.how__lead {
	/* Na širokém displeji se věta vejde na jeden řádek; užší míra ji lámala
	   na dva a pod velkým názvem to vypadalo jako odstavec, ne jako podtitul. */
	max-width: 42rem;
	margin: 1.75rem auto 0;
	font-size: clamp(1.125rem, 1.3vw, 1.25rem);
	line-height: 1.6;
	color: var(--j-text);
	text-wrap: balance;
}

/* Nástup jde shora dolů: název, linka, věta — s odstupem 260 a 120 ms.
   Celý blok se přitom nepohne — dva pohyby najednou by se praly. */
.js .how__head.reveal {
	opacity: 1;
	transform: none;
}

.js .how__lead {
	opacity: 0;
	transform: translateY(0.625rem);
	transition: opacity 0.6s var(--ease) 0.46s, transform 0.6s var(--ease) 0.46s;
}

.js .how__head.is-visible .how__lead {
	opacity: 1;
	transform: none;
}

/* Maska sedí na vnitřním obalu, ne na .reveal prvku: oříznutý nadpis nemá
   viditelnou plochu, pozorovatel ho neohlásí a on se nikdy neodkryje. */
/*
 * Vycpávka a záporný okraj není kosmetika: inset() oříná podle rámečku
 * prvku a čárky nad verzálkami Antonu z něj čoučejí ven — bez toho se
 * z „NABÍZÍM“ stane „NABIZIM“. Okraj vrátí řádek tam, kde stál.
 */
.how__title-in {
	display: inline-block;
	padding: 0.16em 0;
	margin: -0.16em 0;
}

.js .how__title-in {
	clip-path: inset(0 0 100% 0);
	transition: clip-path 0.8s var(--ease);
}

.js .how__head.is-visible .how__title-in {
	clip-path: inset(0 0 0 0);
}

.js .how__underline {
	transform: scaleX(0);
	transition: transform 0.6s var(--ease) 0.34s;
}

.js .how__head.is-visible .how__underline {
	transform: none;
}

/*
 * Hlavička je vycentrovaná: nadpis a hned pod ním rozsah kroků
 * mezi dvěma linkami. Odsazení dolů drží krátké, mezera mezi
 * nadpisem a prvním krokem byla dřív skoro na půl obrazovky.
 */
.how__title {
	/* Nadpis je v hlavičce sám, odsazení řeší .how__head. */
	margin-bottom: 0;
	/* Flex, ne inline — mezi inline-block písmeny by se držela mezera
	   z odřádkování ve zdroji a nadpis by se roztrhal. */
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	font-size: var(--title-section);
	color: var(--night);
}

.how__body {
	position: relative;
	display: grid;
	grid-template-columns: 7.5rem minmax(0, 1fr);
	gap: 3rem;
}

/* Linka, která se dokresluje podle scrollu */
.how__track {
	position: relative;
}

/*
 * Krátký náběh, ať linka nezačíná ostrým seknutím. Delší úsek měl smysl,
 * dokud nadpis stál vlevo — u vycentrované hlavičky by visel ve vzduchu.
 */
.how__track::before {
	content: '';
	position: absolute;
	left: 50%;
	bottom: 100%;
	width: 2px;
	height: 3rem;
	margin-left: -1px;
	background: linear-gradient(to bottom, transparent, var(--j-hair));
}

.how__line {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
}

.how__line svg {
	width: 100%;
	height: 100%;
}

.how__path-bg {
	fill: none;
	stroke: var(--j-hair);
	stroke-width: 2;
}

.how__path {
	fill: none;
	stroke: var(--j-ink);
	stroke-width: 2.5;
	stroke-linecap: round;
}

/* Jezdec na špičce linky — ukazuje, kde přesně scroll právě je. */
.how__marker {
	position: absolute;
	top: 0;
	left: 0;
	width: 0.5rem;
	height: 0.5rem;
	margin: -0.25rem 0 0 -0.25rem;
	border-radius: 50%;
	/* Hlava linky je mátová, ne černá: čára je nakreslená stopa, tohle je
	   místo, kde se právě kreslí. Zář dělá box-shadow, ne další prvek. */
	background: var(--j-accent);
	box-shadow:
		0 0 0 4px rgba(43, 128, 111, 0.12),
		0 0 18px 5px rgba(72, 224, 184, 0.45);
	opacity: 0;
	transition: opacity 0.3s var(--ease);
}

.how__marker.is-on {
	opacity: 1;
}

.how__steps {
	display: flex;
	flex-direction: column;
}

/* Textový sloupec byl užší než kresba, takže se do něj nadpis lámal na tři
   řádky a působil stísněně. Teď je širší z dvojice on. */
.step {
	position: relative;
	min-height: 50vh;
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
	gap: 3.5rem;
	align-items: center;
	padding-block: 3rem;
}

.step__dot {
	position: absolute;
	left: -7.25rem;
	top: 50%;
	width: 1rem;
	height: 1rem;
	margin-top: -0.5rem;
	border: 1px solid var(--j-dot-ring);
	border-radius: 50%;
	background: var(--j-dot-fill);
	transition: border-color 0.4s var(--ease), transform 0.4s var(--ease);
}

.step.is-active .step__dot {
	border-color: var(--j-accent);
	box-shadow: 0 0 0 6px rgba(43, 128, 111, 0.1);
	transform: scale(1.35);
}

/*
 * Číslo bylo displejové, 3rem vysoké, a soupeřilo s nadpisem o pozornost.
 * Teď je to značka: krátká linka a číslo, stejný idiom jako seznam
 * v sekci Co umím. Na aktivním kroku linka povyroste a zbarví se.
 */
.step__marker {
	/* Zbyla po čísle jen linka. Drží nadpisu okraj a nese při tom nástup —
	   než se odkryje, není nad nadpisem nic. */
	display: flex;
	align-items: center;
	gap: 0.875rem;
	margin-bottom: 1.25rem;
	font-family: var(--font-display);
	font-size: 0.875rem;
	line-height: 1;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--j-marker-off);
	transition: color 0.4s var(--ease);
}

.step.is-active .step__marker {
	color: var(--j-accent);
}

.step__rule {
	display: block;
	width: 2.5rem;
	height: 1px;
	flex: none;
	background: var(--j-rule-off);
	transition: width 0.5s var(--ease), background-color 0.5s var(--ease);
}

.step.is-active .step__rule {
	width: 4rem;
	background: var(--j-accent);
}

/*
 * Nadpisy kroků jsou věty, ne štítky — a to je pro Anton špatná práce.
 * V českých verzálkách sedí čárky a háčky těsně nad výškou verzálek,
 * takže se lepí na řádek nad sebou, a kondenzovaná kresba slévá slova
 * dohromady. Anton proto zůstává na krátké nápisy (wordmark, názvy
 * sekcí, jména projektů) a věty přebírá Jakarta v běžné velikosti
 * písmen, kde mají háčky nad malými písmeny místo.
 */
.step__title {
	max-width: 20ch;
	margin: 0 0 1.75rem;
	font-family: var(--font-body);
	/* Dřív 76 px. Proti 100px nadpisu sekce to byl rozdíl 22 % — krok
	   s hlavičkou soupeřil místo aby se jí podřídil, a tři řádky té velikosti
	   dělaly ze sloupce zeď. */
	font-size: clamp(2.25rem, 4.2vw, 3.75rem);
	font-weight: 700;
	line-height: 1.16;
	/* Prostrkání patří k velikosti, ne k prvku: jedna hodnota přes celý
	   rozsah clampu je na jednom konci špatně. Na telefonu volněji, na
	   desktopu těžeji — velká písmena čtou od sebe dál, než jsou. */
	letter-spacing: -0.014em;
	/* Ať na konci nezůstane viset jedno slovo. */
	text-wrap: balance;
	color: var(--j-ink);
	transition: color 0.4s var(--ease);
}

/* Ztlumení jen když běží JS — bez něj by byl text nečitelný. */
.js .step__title {
	color: var(--j-title-off);
}

.js .step.is-active .step__title {
	color: var(--j-ink);
}

.step__text {
	/* Při 24px vychází 36 rem na zhruba 52 znaků — spodní hranice čitelné
	   míry. Užší sloupec lámal větu na příliš mnoho krátkých řádků. */
	max-width: 36rem;
	margin: 0;
	/* O stupeň pod nadpisem kroku; na mobilu zpátky do čitelných 17. */
	font-size: clamp(1.125rem, 1.55vw, 1.5rem);
	font-weight: 400;
	line-height: 1.58;
	color: var(--j-text);
	text-wrap: pretty;
	transition: color 0.4s var(--ease);
}

.js .step__text {
	color: var(--j-text-off);
}

.js .step.is-active .step__text {
	color: var(--j-text);
}


/* Ilustrace ke krokům -------------------------------------------------- */

/*
 * Žádný rámeček. Kresba leží rovnou na bílé ploše, stejně jako v sekci
 * Co ještě řeším leží rovnou na černé — světlé pole se stínem dělalo
 * z každé ilustrace kartu a sekce vypadala starší, než je.
 */
.step__viz {
	position: relative;
	aspect-ratio: 4 / 3;
}

/*
 * Ztlumená je samotná kresba, ne rám — jinak by se opacity nástupu
 * a opacity stavu praly o stejnou vlastnost.
 */
.js .viz {
	opacity: 0.72;
	transition: opacity 0.45s var(--ease);
}

.js .step.is-active .viz {
	opacity: 1;
}

/* Nástup obsahu kroku — číslo, nadpis, text, karta, po 60 ms za sebou. */
.js .step__marker,
.js .step__title,
.js .step__text,
.js .step__viz {
	opacity: 0;
	transform: translateY(10px);
}

.step.is-seen .step__marker {
	animation: step-in 0.5s var(--ease) forwards;
}

.step.is-seen .step__title {
	animation: step-in 0.5s var(--ease) 0.06s forwards;
}

.step.is-seen .step__text {
	animation: step-in 0.5s var(--ease) 0.12s forwards;
}

.step.is-seen .step__viz {
	animation: step-in 0.6s var(--ease) 0.1s forwards;
}

@keyframes step-in {
	to {
		opacity: 1;
		transform: none;
	}
}

/* Na světlém podkladu už přesvit jen vybělí kresbu — hloubku dělá gradient pozadí. */

.viz {
	width: 100%;
	height: 100%;
}

.viz text {
	font-family: var(--font-body);
	fill: #698a83;
}

.viz .t-strong { fill: var(--ink); }
.viz .t-soft { fill: #6f8a84; }
.viz .t-dim { fill: #93a8a3; }
.viz .t-accent { fill: var(--accent); }
.viz .fill-soft { fill: rgba(13, 38, 33, 0.22); }
.viz .fill-accent { fill: var(--accent); }

/*
 * Krytí je zrcadlem sekce Co ještě řeším — tam bílá do černé, tady inkoust
 * do bílé. O něco vyšší schválně: tmavé na světlém se čte hůř než
 * světlé na tmavém, při stejných číslech byla kresba bledá.
 */
.viz .stroke { fill: none; stroke: rgba(13, 38, 33, 0.4); stroke-width: 2; }
.viz .stroke-thin { fill: none; stroke: rgba(13, 38, 33, 0.26); stroke-width: 1.75; }
.viz .stroke-strong { fill: none; stroke: var(--ink); stroke-width: 2; }
.viz .stroke-accent { fill: none; stroke: var(--accent); stroke-width: 2.5; }

.viz .block { fill: rgba(13, 38, 33, 0.07); }
.viz .block-hi { fill: rgba(43, 128, 111, 0.14); }
.viz .block-dark { fill: rgba(13, 38, 33, 0.05); }
.viz .card-fill { fill: #ffffff; }
.viz .chrome-dot { fill: rgba(13, 38, 33, 0.28); }
.viz .btn-fill { fill: var(--accent); }
.viz .btn-text { fill: #ffffff; }
.viz .badge-fill { fill: rgba(43, 128, 111, 0.12); stroke: var(--accent); }

/*
 * Výchozí (skrytý) stav platí jen když běží JS — bez něj zůstane ilustrace
 * celá vykreslená. Animace se pouští třídou .is-seen, kterou krok dostane
 * při prvním projetí a už ji neztratí, takže projeté kroky nezůstanou prázdné.
 */
.js .viz .draw {
	stroke-dasharray: var(--len, 900);
	stroke-dashoffset: var(--len, 900);
}

.step.is-seen .viz .draw {
	animation: draw 0.9s var(--ease) forwards;
}

@keyframes draw {
	to { stroke-dashoffset: 0; }
}

.js .viz .rise {
	opacity: 0;
	transform: translateY(10px);
	transform-box: fill-box;
	transform-origin: center;
}

.step.is-seen .viz .rise {
	animation: rise 0.45s var(--ease) forwards;
}

@keyframes rise {
	to { opacity: 1; transform: none; }
}

.viz .d1 { animation-delay: 0.08s; }
.viz .d2 { animation-delay: 0.16s; }
.viz .d3 { animation-delay: 0.24s; }
.viz .d4 { animation-delay: 0.32s; }
.viz .d5 { animation-delay: 0.4s; }
.viz .d6 { animation-delay: 0.48s; }
.viz .d7 { animation-delay: 0.56s; }
.viz .d8 { animation-delay: 0.64s; }

/*
 * Smyčky. Dřív každá ilustrace jednou přehrála nástup a pak stála — vedle
 * sekce Co ještě řeším, kde se pořád něco děje, vypadala zamrzle. Každá
 * kresba má teď jeden děj, který se opakuje; delší část cyklu drží hotový
 * stav, ať to neposkakuje. Časy jsou uvnitř jedné kresby stejné, jinak by
 * se jednotlivé kusy rozešly.
 */

/* Krok 01 — křivka v přehledu se dokresluje, tlačítko u toho dýchne */
.viz .trend {
	stroke-dasharray: 1;
	stroke-dashoffset: 1;
}

.step.is-seen .viz .trend {
	animation: trend 5s var(--ease) 0.8s infinite;
}

@keyframes trend {
	0% { stroke-dashoffset: 1; }
	26%, 88% { stroke-dashoffset: 0; }
	100% { stroke-dashoffset: 1; }
}

.viz .cta {
	transform-box: fill-box;
	transform-origin: center;
}

.step.is-seen .viz .cta {
	animation: cta 5s var(--ease) 0.8s infinite;
}

@keyframes cta {
	0%, 26% { transform: none; }
	32% { transform: scale(1.035); }
	40%, 100% { transform: none; }
}

/* Krok 02 — kurzor klikne a formulář odletí */
.js .viz .cursor {
	opacity: 0;
	transform-box: fill-box;
}

.step.is-seen .viz .cursor {
	animation: cursor-move 5.5s var(--ease) 0.3s infinite;
}

@keyframes cursor-move {
	0% { opacity: 0; transform: translate(54px, 46px); }
	6% { opacity: 1; transform: translate(38px, 30px); }
	20% { opacity: 1; transform: translate(0, 0); }
	24% { transform: translate(1px, 2px); }
	28%, 80% { opacity: 1; transform: translate(0, 0); }
	92%, 100% { opacity: 0; transform: translate(54px, 46px); }
}

.js .viz .click-ring {
	opacity: 0;
	transform-box: fill-box;
	transform-origin: center;
}

.step.is-seen .viz .click-ring {
	animation: click-ring 5.5s var(--ease) 0.3s infinite;
}

@keyframes click-ring {
	0%, 21% { opacity: 0; transform: scale(0.35); }
	23% { opacity: 0.85; transform: scale(0.4); }
	34%, 100% { opacity: 0; transform: scale(1.3); }
}

.viz .send-btn {
	transform-box: fill-box;
	transform-origin: center;
}

.step.is-seen .viz .send-btn {
	animation: press 5.5s var(--ease) 0.3s infinite;
}

@keyframes press {
	0%, 21% { transform: none; }
	24% { transform: scale(0.955); }
	30%, 100% { transform: none; }
}

.js .viz .plane {
	opacity: 0;
	transform-box: fill-box;
}

.step.is-seen .viz .plane {
	animation: plane 5.5s var(--ease) 0.3s infinite;
}

@keyframes plane {
	0%, 28% { opacity: 0; transform: translate(0, 0) scale(0.7); }
	34% { opacity: 1; }
	56%, 100% { opacity: 0; transform: translate(90px, -130px) scale(1); }
}

/* Krok 03 — notifikace */
.js .viz .notif {
	opacity: 0;
	transform-box: fill-box;
}

.step.is-seen .viz .notif {
	animation: notif 5s var(--ease) 0.5s infinite;
}

@keyframes notif {
	0%, 8% { opacity: 0; transform: translateY(-30px) scale(0.96); }
	20%, 84% { opacity: 1; transform: none; }
	96%, 100% { opacity: 0; transform: translateY(-26px) scale(0.96); }
}

.viz .buzz {
	opacity: 0;
	transform-box: fill-box;
	transform-origin: center;
}

.step.is-seen .viz .buzz {
	animation: buzz 5s var(--ease) 0.5s infinite;
}

@keyframes buzz {
	0%, 14% { opacity: 0; transform: scale(0.9); }
	20% { opacity: 0.7; transform: scale(1); }
	32% { opacity: 0.2; transform: scale(1.12); }
	38%, 100% { opacity: 0; transform: scale(1.16); }
}

/* Krok 04 — nový řádek v přehledu */
.js .viz .row-new {
	opacity: 0;
	transform-box: fill-box;
}

.step.is-seen .viz .row-new {
	animation: row-in 5s var(--ease) 0.6s infinite;
}

@keyframes row-in {
	0%, 12% { opacity: 0; transform: translateX(-24px); }
	26%, 100% { opacity: 1; transform: none; }
}

.js .viz .badge-new {
	opacity: 0;
	transform-box: fill-box;
	transform-origin: center;
}

.step.is-seen .viz .badge-new {
	animation: badge 5s var(--ease) 0.6s infinite;
}

@keyframes badge {
	0%, 26% { opacity: 0; transform: scale(0.6); }
	34% { opacity: 1; transform: scale(1.08); }
	40%, 100% { opacity: 1; transform: scale(1); }
}

/* Krok 05 — e-mail */
.js .viz .bubble {
	opacity: 0;
	transform-box: fill-box;
	transform-origin: left bottom;
}

.step.is-seen .viz .bubble {
	animation: bubble 5.5s var(--ease) 0.5s infinite;
}

@keyframes bubble {
	0%, 6% { opacity: 0; transform: translateY(16px) scale(0.94); }
	18%, 100% { opacity: 1; transform: none; }
}

.js .viz .check {
	stroke-dasharray: 44;
	stroke-dashoffset: 44;
}

.step.is-seen .viz .check {
	animation: check-loop 5.5s var(--ease) 0.5s infinite;
}

@keyframes check-loop {
	0%, 24% { stroke-dashoffset: 44; }
	38%, 100% { stroke-dashoffset: 0; }
}


/* 9. Kolik to stojí ------------------------------------------------------- */

/*
 * Jediná vycentrovaná sekce v dolní půlce webu. Sazba proto drží jednu
 * svislou osu a všechno, co se hne, se hne symetricky kolem ní: písmena
 * názvu ven ze středu, linka ven ze středu, linky u podpisu ven od podpisu.
 * Sekce nemá co skrývat, tak se ani netváří složitě.
 */
.price {
	position: relative;
	/*
	 * Ořez kvůli nádechu níž: ten je široký min(64rem, 130%), takže pod
	 * zhruba 790 px vyčnívá přes okraj obrazovky a roztáhne vodorovný
	 * rozměr celé stránky. Vycentrovaný obsah se pak na telefonu kreslí
	 * mimo střed a napravo se ořezává. Sousední tmavé sekce (.hero,
	 * .contact) se ořezávají ze stejného důvodu.
	 */
	overflow: hidden;
	background: var(--night-2);
	color: var(--white);
}

/*
 * Mátový nádech za názvem. Nahrazuje rámeček, kterým by šlo sekci oddělit —
 * dá jí střed a hloubku, aniž by na ni cokoli nakreslil. Bez animace:
 * pomalu pulzující plocha přes celou šířku je přesně to, co lidem
 * citlivým na pohyb dělá zle.
 */
.price::before {
	content: '';
	position: absolute;
	top: clamp(1rem, 4vw, 4rem);
	left: 50%;
	width: min(64rem, 130%);
	aspect-ratio: 1 / 0.62;
	transform: translateX(-50%);
	background: radial-gradient(
		ellipse at center,
		rgba(72, 224, 184, 0.13),
		rgba(72, 224, 184, 0) 64%
	);
	pointer-events: none;
}

/* Nádech naskočí spolu s názvem. :has() umí každý dnešní prohlížeč; kde ne,
   svítí rovnou — lepší než sekce bez středu. */
@supports selector(:has(*)) {
	.js .price::before {
		opacity: 0;
		transition: opacity 1.6s var(--ease);
	}

	.js .price:has(.price__title.is-visible)::before {
		opacity: 1;
	}
}

.price__title {
	position: relative;
	margin: 0;
	font-size: var(--title-section);
	text-align: center;
	color: var(--white);
}

/*
 * Písmena se skládají od středu ven, ne zleva jako v sekci Co ještě řeším.
 * Ta má název u kraje, tenhle ho má na ose — a pohyb, který začne jinde než
 * kompozice, působí jako cizí těleso. Odstup 30 ms: kaskáda je dvojnásobně
 * dlouhá než u řádkového nadpisu, takže na krok musí zbýt míň času.
 */
.js .price__title .split-letter {
	transform: translateY(0.5em);
	transition-delay: calc(var(--i) * 30ms);
}

/* Linka pod názvem roste od středu do stran — z kraje by se rozjížděla
   mimo vycentrovaný název. */
.price__rule {
	display: block;
	width: 100%;
	height: 1px;
	margin: clamp(1.75rem, 3vw, 2.5rem) 0 0;
	background: rgba(255, 255, 255, 0.14);
	transform-origin: center;
}

.js .price__rule {
	transform: scaleX(0);
	transition: transform 0.8s var(--ease) 0.25s;
}

.js .price__title.is-visible + .price__rule {
	transform: none;
}

/*
 * Odpověď na název sekce. Velké písmo si žádá zápornější prostrkání —
 * čím větší text, tím dál od sebe písmena opticky jsou.
 */
.price__answer {
	max-width: 22ch;
	margin: clamp(3rem, 6vw, 4.5rem) auto 0;
	font-size: clamp(1.75rem, 3.2vw, 2.75rem);
	font-weight: 600;
	line-height: 1.16;
	letter-spacing: -0.022em;
	text-align: center;
	color: var(--white);
	text-wrap: balance;
}

/* Slova nabíhají po sobě, ne najednou — odpověď má znít, jako když ji někdo
   říká. Odstavec sám o sobě nikam nejede, hnou se jen slova v něm. */
.price__word {
	display: inline-block;
}

.js .price__answer.reveal {
	opacity: 1;
	transform: none;
}

.js .price__word {
	opacity: 0;
	transform: translateY(0.4em);
	transition:
		opacity 0.5s var(--ease) calc(var(--i) * 0.045s + 0.15s),
		transform 0.5s var(--ease) calc(var(--i) * 0.045s + 0.15s);
}

.js .price__answer.is-visible .price__word {
	opacity: 1;
	transform: none;
}

/* Vysvětlení. Drobné písmo naopak prostrkání potřebuje do plusu a delší
   proklad — jinak se řádky slepí. */
.price__lead {
	max-width: 44ch;
	margin: 1.5rem auto 0;
	font-size: clamp(1.125rem, 1.35vw, 1.3125rem);
	line-height: 1.65;
	letter-spacing: 0.002em;
	text-align: center;
	color: #b4bdc0;
	text-wrap: pretty;
}

/* Vyšší specificita než .js .reveal — zkratka transition v něm zpoždění
   jinak vynuluje a odstavec by naskakoval s odpovědí najednou. */
.js .price__lead.reveal {
	transition-delay: 0.3s;
}

/*
 * Podpis. Řeč o ceně má být od člověka, ne od webu — proto tu zůstal
 * i po zrušení sekce s manifestem, odkud pochází. Vlasové linky po jeho
 * stranách vyrůstají směrem od něj, takže i tenhle pohyb má střed
 * v ose sekce.
 */
.price__sign {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: clamp(1rem, 2.5vw, 2rem);
	margin-top: clamp(3.5rem, 7vw, 5.5rem);
	text-align: left;
}

.price__sign-rule {
	width: min(10rem, 14vw);
	height: 1px;
	flex: none;
	background: rgba(255, 255, 255, 0.16);
}

.price__sign-rule:first-child {
	transform-origin: right;
}

.price__sign-rule:last-child {
	transform-origin: left;
}

.js .price__sign-rule {
	transform: scaleX(0);
	transition: transform 0.8s var(--ease) 0.45s;
}

.js .price__sign.is-visible .price__sign-rule {
	transform: none;
}

.price__card {
	display: flex;
	align-items: center;
	gap: 1rem;
}

/* Nic se nesmí objevit z ničeho: kolečko nastupuje z 0.92, ne z nuly. */
.price__avatar {
	display: grid;
	place-items: center;
	width: 3.25rem;
	height: 3.25rem;
	flex: none;
	border-radius: 50%;
	background: var(--sand);
	color: var(--night);
	font-family: var(--font-display);
	font-size: 0.9375rem;
	letter-spacing: 0.05em;
}

.js .price__avatar {
	opacity: 0;
	transform: scale(0.92);
	transition:
		opacity 0.5s var(--ease) 0.5s,
		transform 0.5s var(--ease) 0.5s;
}

.js .price__sign.is-visible .price__avatar {
	opacity: 1;
	transform: none;
}

.price__name {
	margin: 0;
	font-family: var(--font-display);
	font-size: 1rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--white);
}

.price__role {
	margin: 0.25rem 0 0;
	font-size: 0.8125rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: #8d979b;
}

.js .price__card > div {
	opacity: 0;
	transform: translateY(0.5rem);
	transition:
		opacity 0.5s var(--ease) 0.58s,
		transform 0.5s var(--ease) 0.58s;
}

.js .price__sign.is-visible .price__card > div {
	opacity: 1;
	transform: none;
}


/* 10. Patička ------------------------------------------------------------- */

.site-footer {
	padding-top: 10rem;
	background: var(--night);
}

/*
 * Sloupce se dopočítávají podle počtu dětí, ne podle pevné šablony.
 * Sloupec se sítěmi se nevykreslí, dokud profily nemají adresu — s pevnými
 * třemi sloupci by po něm zbyla díra u pravého okraje.
 */
.site-footer__grid {
	display: grid;
	grid-template-columns: 1.4fr;
	grid-auto-flow: column;
	grid-auto-columns: minmax(0, 1fr);
	gap: 4rem;
	align-items: end;
	padding-bottom: 8rem;
}

.site-footer__title {
	margin-bottom: 2.5rem;
	font-size: var(--title-section);
}

.js .site-footer__title.reveal {
	opacity: 1;
	transform: none;
}

.site-footer__title-in {
	display: inline-block;
	padding: 0.16em 0;
	margin: -0.16em 0;
}

.js .site-footer__title-in {
	clip-path: inset(0 0 100% 0);
	transition: clip-path 1.1s var(--ease);
}

.js .site-footer__title.is-visible .site-footer__title-in {
	clip-path: inset(0 0 0 0);
}

.site-footer__mail {
	display: inline-block;
	font-size: clamp(1.5rem, 3vw, 2.25rem);
	font-weight: 300;
	letter-spacing: -0.01em;
	color: var(--mist);
	text-decoration: underline;
	text-underline-offset: 8px;
	text-decoration-thickness: 1px;
	transition: color 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
	.site-footer__mail:hover {
		color: var(--white);
	}
}

.site-footer__col h3 {
	margin: 0 0 1.5rem;
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.25em;
	text-transform: uppercase;
	color: var(--muted);
}

.site-footer__col ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-footer__col li + li {
	margin-top: 0.75rem;
}

.site-footer__col a {
	font-size: 0.9375rem;
	color: var(--white);
	transition: color 0.2s ease;
}

@media (hover: hover) and (pointer: fine) {
	.site-footer__col a:hover {
		color: var(--mist);
	}
}

.site-footer__col p {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.6;
	color: var(--white);
}

.site-footer__bottom {
	display: flex;
	justify-content: space-between;
	gap: 1.5rem;
	padding: 2.5rem 0;
	border-top: 1px solid rgba(255, 255, 255, 0.1);
	font-size: 0.8125rem;
	font-weight: 400;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--muted);
}

.site-footer__bottom p {
	margin: 0;
}

.site-footer__bottom nav {
	display: flex;
	/* Tři odkazy ve verzálkách s prostrkáním se na užší řádek nevejdou.
	   Bez zalomení by přetekly z kontejneru a vystrčily vodorovný posuvník. */
	flex-wrap: wrap;
	gap: 0.75rem 2.5rem;
}

.site-footer__bottom a {
	transition: color 0.5s var(--ease);
}

@media (hover: hover) and (pointer: fine) {
	.site-footer__bottom a:hover {
		color: var(--white);
	}
}

/* Povinné údaje ----------------------------------------------------------- */

/*
 * § 435 občanského zákoníku chce jméno, sídlo a IČO na obchodních listinách.
 * Tlumené, ale ne schované: text pod 0.8125rem a s nižším kontrastem už
 * není „diskrétní“, jen nečitelný — a nečitelný povinný údaj je stejný
 * problém jako žádný.
 */
.site-footer__address {
	margin: 0;
	font-style: normal;
	font-size: 0.9375rem;
	line-height: 1.7;
	color: var(--muted);
}

.site-footer__legal {
	margin-top: 4rem;
	padding-top: 2rem;
	border-top: 1px solid rgba(255, 255, 255, 0.08);
	font-size: 0.8125rem;
	line-height: 1.7;
	color: #7f898d;
}

.site-footer__legal p {
	margin: 0 0 0.25rem;
}

.site-footer__legal strong {
	font-weight: 600;
	color: var(--mist);
}
/* 11. Reveal animace ------------------------------------------------------ */

/* Bez JS zůstává obsah viditelný — skrýváme až když se skript opravdu spustí. */
.js .reveal {
	opacity: 0;
	transform: translateY(10px);
	transition: opacity 1s var(--ease), transform 1s var(--ease);
}

.js .reveal.is-visible {
	opacity: 1;
	transform: none;
}

/*
 * Uspaná kresba. animation-play-state, ne animation: none — po probuzení
 * pokračuje tam, kde stála, místo aby skočila na začátek. Třídu přepíná
 * initLoops() v main.js.
 */
.viz.is-idle,
.viz.is-idle * {
	animation-play-state: paused;
}

/* Prazdne misto dycha ramecek; mimo zaber taky nemusi. */
.proj__item--empty.is-idle .proj__frame {
	animation-play-state: paused;
}

/* 12. Responzivita -------------------------------------------------------- */

/* Diagonála na úzké obrazovce nedává smysl — dovětek se vrací pod odpověď. */
@media (max-width: 900px) {
	/* Na úzké obrazovce se vlasové linky u podpisu vedle textu nevejdou. */
	.price__sign-rule {
		display: none;
	}

	/* Podpis pod sebe a na osu — naširko by jako jediný v sekci visíval vlevo. */
	.price__card {
		flex-direction: column;
		gap: 0.875rem;
		text-align: center;
	}
}

/* Formulář sjede pod text — vedle nadpisu by na něj nezbylo místo. */
@media (max-width: 900px) {
	.contact__grid {
		grid-template-columns: 1fr;
		gap: 3.5rem;
	}

	/* Šipka ukazuje zleva doprava; ve sloupci pod sebou nemá kam mířit. */
	.contact__pointer {
		display: none;
	}
}

@media (max-width: 560px) {
	/* Dvě pole vedle sebe vyjdou na 160 px — do toho se e-mail nepíše. */
	.form__pair {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 1100px) {
	:root {
		--section-y: 7rem;
		--gutter: 1.5rem;
	}

	.nav {
		padding: 1.5rem;
	}

	.nav__menu {
		gap: 1.25rem;
	}

	.nav__link {
		display: none;
	}

	.proj__title {
		margin-bottom: 3rem;
	}

	.step {
		gap: 2.5rem;
	}

	/* Menší písmo snáší míně stažení. */
	.step__title {
		letter-spacing: -0.008em;
	}

	.site-footer__grid {
		grid-template-columns: 1fr;
		grid-auto-flow: row;
		gap: 3rem;
		padding-bottom: 5rem;
	}
}

@media (max-width: 760px) {
	.hero__title {
		font-size: 16vw;
	}

	/* Stejně velké plochy zabírají na úzké obrazovce mnohem větší díl šířky —
	   v desktopové síle by z nádechu byl zelený podklad. */
	.how {
		background-image:
			radial-gradient(30rem 16rem at 50% 1%, rgba(72, 224, 184, 0.14), transparent 66%),
			radial-gradient(32rem 48rem at -24% 30%, rgba(72, 224, 184, 0.12), transparent 72%),
			radial-gradient(34rem 42rem at 124% 62%, rgba(43, 128, 111, 0.08), transparent 74%),
			radial-gradient(28rem 30rem at -20% 90%, rgba(72, 224, 184, 0.1), transparent 72%),
			linear-gradient(to bottom, rgba(14, 17, 19, 0.055), rgba(14, 17, 19, 0) 26rem),
			linear-gradient(to top, rgba(14, 17, 19, 0.05), rgba(14, 17, 19, 0) 18rem);
	}

	/* Linka se stáhne k levému okraji, body sedí u nadpisu kroku */
	.how__body {
		grid-template-columns: 2.5rem minmax(0, 1fr);
		gap: 1.5rem;
	}

	.step {
		min-height: 42vh;
		grid-template-columns: 1fr;
		gap: 2rem;
		padding-block: 2rem;
	}

	.step__dot {
		left: -3.1875rem;
	}

	/* Na úzkém displeji je 13ch zbytečně krátká míra. */
	.step__title {
		max-width: none;
	}

	.site-footer__bottom {
		flex-direction: column;
	}

	.site-footer__bottom nav {
		gap: 0.75rem 1.5rem;
	}
}

/*
 * Kroky 01–05 na telefonu.
 *
 * Clamp drží na spodním konci 36 px nadpisu kroku a 18 px textu — míry
 * odvozené od širokého displeje, kde je vedle sloupce ještě kresba. Na
 * telefonu je sloupec celá obrazovka: 36 px láme krátkou větu na tři
 * řádky a proti nadpisu sekce (48 px) je to rozdíl jen čtvrtiny, takže
 * krok s hlavičkou soupeří místo aby se jí podřídil.
 *
 * Menší písmo zároveň vrací rozestup: nadpis kroku je proti sekci
 * o dvě třetiny menší a podtext o stupeň pod ním.
 */
@media (max-width: 620px) {
	.step__title {
		margin-bottom: 1.25rem;
		font-size: 1.75rem;
		line-height: 1.2;
		letter-spacing: -0.004em;
	}

	.step__text {
		font-size: 1rem;
		line-height: 1.6;
	}

	/* Popiska nad nadpisem je už tak malá; ubíráme jen prostrkání, ať se
	   číslo s názvem vejde na jeden řádek. */
	.step__marker {
		letter-spacing: 0.14em;
	}
}

/*
 * Lišta na telefonu mizí.
 *
 * Do 1100 px se z lišty ztratí odkazy a zbude značka a tlačítko. Jenže na
 * telefonu nemá lišta kam ustoupit: drží se napevno u horní hrany a hero
 * nadpis se pod ni podsouvá, takže značka i výzva leží přes první větu,
 * kterou má člověk přečíst. Zmenšování písma to jen oddalovalo.
 *
 * Obojí má o kus níž svůj protějšek: jméno stojí přes celou šířku hned
 * v hero sekci a výzvu přebírá spodní lišta (.sticky-cta), která najíždí
 * hned za hero. Na telefonu proto horní lištu schováváme celou.
 */
@media (max-width: 620px) {
	.nav {
		display: none;
	}
}

/* Hero na telefonu -------------------------------------------------------- */

/*
 * Skladba se mezi zařízeními nemění, mění se jen měřítko: wordmark zůstává
 * na jednom řádku, tak jako na počítači.
 */
@media (max-width: 620px) {
	/*
	 * Wordmark na jeden řádek. „Systemcraft“ je v Antonu široké 5.32 em
	 * (měřeno 9. 9. 2026), takže při 16vw dosedá skoro na oba okraje;
	 * 14.5vw mu nechá vzduch po stranách i na 320px displeji.
	 *
	 * Pozor: je to navázané na délku jména. Až se značka zase přejmenuje,
	 * přeměřte to — kratší jméno unese víc, delší míň. Mez je
	 * (100vw − 3rem) ÷ šířka jména v em.
	 */
	.hero__title {
		font-size: 14.5vw;
	}

	.hero__typed {
		margin-top: 1.5rem;
	}

}


@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}

	.js .reveal {
		opacity: 1;
		transform: none;
	}

	.hero__typed-char.is-cursor::after {
		animation: none;
		opacity: 0;
	}

	.js .viz .draw,
	.js .viz .check,
	.viz .trend {
		stroke-dashoffset: 0;
	}

	/* Kurzor, kliknutí, letadlo a bzučení jsou čistý pohyb — zamrzlé upro-
	   střed kresby by jen matly. Zbytek nese informaci a zůstává. */
	.viz .cursor,
	.viz .click-ring,
	.viz .plane,
	.viz .buzz {
		display: none;
	}

	.js .viz .rise,
	.js .viz .notif,
	.js .viz .row-new,
	.js .viz .badge-new,
	.js .viz .bubble,
	.js .step__marker,
	.js .step__title,
	.js .step__text,
	.js .step__viz {
		opacity: 1;
		transform: none;
	}

	/* Ztlumení aktivního kroku zůstává — je to informace, ne pohyb. */
	.js .viz {
		opacity: 0.72;
	}

	.js .step.is-active .viz {
		opacity: 1;
	}
}
