/* GabionX — home: hero ken-burns, draggable works gallery (tooltip lives in components.css) */

/* hero image slow ken-burns */
@keyframes gx-kenburns {
	0% {
		transform: scale(1.04) rotate(0deg);
	}

	50% {
		transform: scale(1.12) rotate(0.8deg);
	}

	100% {
		transform: scale(1.04) rotate(0deg);
	}
}

.gx-hero-img {
	animation: gx-kenburns 26s ease-in-out infinite;
	transform-origin: 56% 48%;
	will-change: transform;
}

/* mobile variant per GabionX Mobile design: slightly stronger zoom/rotation */
@keyframes gx-kenburns-m {
	0% {
		transform: scale(1.06) rotate(0deg);
	}

	50% {
		transform: scale(1.16) rotate(0.9deg);
	}

	100% {
		transform: scale(1.06) rotate(0deg);
	}
}

/* ---- hero intro choreography (initHeroIntro): line masks for the h1.
		The split spans exist only during the entrance; JS restores the original
		markup when the timeline completes.
		The h1 sits at line-height 1.0, so descenders (у, р, щ) paint BELOW the
		line box — a bare overflow:hidden mask decapitates them until the markup
		swap pops them back (the visible blink). The padding/negative-margin pair
		gives each mask descender headroom without touching the line rhythm; the
		resting offset is >100% + that padding so nothing peeks pre-entrance. ---- */
.gxh-line {
	display: block;
	overflow: hidden;
	padding-bottom: .18em;
	margin-bottom: -.18em;
}

.gxh-line__in {
	display: block;
	transform: translateY(135%);
}

/* ---- hero scrims (unique diagonal wash, home only) ----
				explicit z-index needed: .home-hero__slide.is-active sits at z-index:1 for the
				crossfade, and a z-index:auto sibling never beats a positive z-index sibling
				regardless of DOM order — without this the scrims silently painted behind the
				active slide once the slider markup was introduced. */
.home-hero__scrim-a {
	z-index: 2;
	background: linear-gradient(95deg, rgba(10, 14, 20, .92) 0%, rgba(10, 14, 20, .72) 30%, rgba(10, 14, 20, .34) 56%, rgba(10, 14, 20, .12) 100%);
}

.home-hero__scrim-b {
	z-index: 2;
	background: linear-gradient(to top, rgba(8, 11, 16, .82) 0%, rgba(8, 11, 16, .4) 26%, transparent 52%);
}

/* ---- hero top scrim: independent of scrim-a's diagonal wash (which fades to almost
				nothing on the right, under Зроби сам / Контакти / phone pill) — bright slides
				like hero2/hero3 washed out those nav items. Fixed-height top-down fade sits
				above the slide images but under the nav content, on every slide, every breakpoint. ---- */
.home-hero__scrim-top {
	z-index: 3;
	background: linear-gradient(to bottom, rgba(5, 8, 13, .9) 0%, rgba(5, 8, 13, .3) 30%, transparent 100%);
}

.home-hero__img {
	object-position: 58% 50%;
}

/* ---- hero slider: infinite crossfade loop across hero/hero2/hero3, each slide keeps the same ken-burns zoom ---- */
.home-hero__slides {
	position: absolute;
	inset: 0;
}

.home-hero__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	z-index: 0;
	transition: opacity 1.6s ease;
}

.home-hero__slide.is-active {
	opacity: 1;
	z-index: 1;
}

/* only the visible slide runs ken-burns — hidden layers animating transforms
		cost real frames on phones */
.home-hero__slide:not(.is-active) .gx-hero-img {
	animation-play-state: paused;
}

/* ---- services: what we build — four portfolio-preview categories ----
		image-led architectural cards, not service boxes: media dominates, the title
		row carries a quiet arrow, hover = slow zoom + lighter wash + green accents */
.svc-head-side {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	max-width: 340px;
	flex: none;
}

.svc-head-side .gx-lead {
	margin: 0;
}

.svc-badge {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 10px 18px;
	border-radius: var(--radius-full);
	background: var(--green-wash);
	border: 1px solid var(--green-border);
	font: 500 11px/1 var(--font-sans);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--green-ink);
}

.svc-badge__dot {
	width: 3px;
	height: 3px;
	border-radius: 50%;
	background: var(--green);
}

/* closing trust line under the stack */
.svc-cycle {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 20px;
	margin: clamp(40px, 7vh, 72px) 0 0;
	font: 500 11px/1.6 var(--font-sans);
	letter-spacing: .22em;
	text-transform: uppercase;
	text-align: center;
	color: var(--ink-58);
}

.svc-cycle span {
	flex: 1;
	max-width: 200px;
	height: 1px;
	background: var(--ink-16);
}

@media (max-width: 768px) {
	.svc-head-side {
		max-width: none;
	}
}

/* ---- catalog: featured board + compact category rows (mockup-faithful) ---- */
.ctl-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(18px, 2vw, 30px);
	align-items: stretch;
}

.ctl-feat-col {
	display: flex;
	flex-direction: column;
}

.ctl-feat {
	position: relative;
	display: block;
	flex: 1;
	min-height: 540px;
	border-radius: var(--radius-md);
	overflow: hidden;
	background: var(--charcoal);
	text-decoration: none;
}

.ctl-feat__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: opacity .35s ease, transform .8s var(--ease);
}

.ctl-feat:hover .ctl-feat__img {
	transform: scale(1.03);
}

.ctl-feat__scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to bottom, rgba(10, 14, 20, .3) 0%, transparent 22%),
		linear-gradient(to top, rgba(10, 14, 20, .82) 0%, rgba(10, 14, 20, .32) 40%, transparent 64%);
}

.ctl-feat__num {
	position: absolute;
	top: clamp(18px, 2.6vh, 28px);
	left: clamp(20px, 2.2vw, 40px);
	font: 300 clamp(17px, 1.4vw, 20px)/1 var(--font-serif);
	letter-spacing: .1em;
	color: var(--white-85);
}

.ctl-feat__body {
	position: absolute;
	left: clamp(20px, 2.2vw, 40px);
	right: clamp(20px, 2.2vw, 40px);
	bottom: clamp(20px, 3vh, 36px);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 12px;
	transition: opacity .35s ease;
}

.ctl-feat__title {
	font: 300 clamp(26px, 2.4vw, 38px)/1.1 var(--font-serif);
	color: var(--white);
}

.ctl-feat__text {
	max-width: 440px;
	font: 400 14px/1.6 var(--font-sans);
	color: var(--white-85);
}

.ctl-dashes {
	display: flex;
	gap: 10px;
	margin-top: 16px;
}

.ctl-dash {
	width: 48px;
	height: 3px;
	border-radius: 3px;
	background: var(--ink-16);
	transition: background-color .3s ease;
}

.ctl-dash.is-active {
	background: var(--green);
}

.ctl-dash:hover {
	background: var(--ink-40);
}

.ctl-dash.is-active:hover {
	background: var(--green);
}

/* right column: three compact category rows */
.ctl-rows {
	display: flex;
	flex-direction: column;
	gap: clamp(14px, 2vh, 22px);
	/* 19px = dash strip below the featured card (16px margin + 3px height):
			the last row's bottom lines up with the card, not with the dashes */
	margin-bottom: 19px;
}

.ctl-row {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: clamp(14px, 1.6vw, 24px);
	padding: clamp(16px, 1.8vw, 26px);
	background: var(--panel-light);
	border: 1px solid var(--ink-10);
	border-radius: var(--radius-md);
	text-align: left;
	flex: 1;
	transition: border-color .3s ease, transform .4s var(--ease), box-shadow .4s ease;
}

.ctl-row:hover {
	border-color: var(--ink-16);
	transform: translateY(-2px);
	box-shadow: var(--shadow-sm);
}

.ctl-row__info {
	display: flex;
	flex-direction: column;
	gap: 7px;
	min-width: 0;
}

.ctl-row__num {
	font: 300 clamp(19px, 1.6vw, 24px)/1 var(--font-serif);
	color: var(--green-ink);
}

.ctl-row__title {
	font: 400 clamp(19px, 1.7vw, 24px)/1.2 var(--font-serif);
	color: var(--ink);
}

.ctl-row__text {
	font: 400 13.5px/1.55 var(--font-sans);
	color: var(--ink-58);
	max-width: 300px;
}

.ctl-row__thumb {
	width: clamp(120px, 12vw, 176px);
	height: clamp(96px, 10vw, 140px);
	object-fit: cover;
	border-radius: var(--radius-sm);
	flex: none;
}

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

	.ctl-feat {
		min-height: 440px;
	}

	.ctl-rows {
		margin-bottom: 0;
	}
}

@media (max-width: 768px) {
	.ctl-feat {
		min-height: 380px;
	}

	.ctl-row {
		grid-template-columns: 1fr;
	}

	.ctl-row__thumb {
		display: none;
	}
}

/* ---- services: CTA to the constructions page ---- */
.svc-all-cta {
	display: flex;
	justify-content: center;
	margin-top: clamp(28px, 3.4vw, 44px);
}

@media (max-width: 768px) {
	.svc-all-cta { margin-top: 10px; }

	.svc-all-cta .gx-btn {
		width: 100%;
		justify-content: center;
		padding-top: 17px;
		padding-bottom: 17px;
	}
}

/* ---- hero content ----
		a flow child, vertically centered by the flex hero: no absolute offsets or
		percentage transforms, so nothing can misresolve under DevTools device
		emulation or unusual viewports. The header overlays the hero instead of
		sitting in flow (it's visually a full-width top bar either way). */
.gx-page--home .gx-hero--full {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

/* desktop only: on mobile the shared fixed-header rule (sections.css) takes over */
@media (min-width: 769px) {
	.gx-page--home .gx-hero__head {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
	}
}

.gx-hero__content--home {
	position: relative;
	z-index: 5;
	margin-left: var(--section-pad-x);
	max-width: 680px;
}

/* ---- brand information ticker: the hero's lower edge ----
		an architectural information strip, not a banner: near-still marquee
		(~20px/s, duration measured by initTicker), seamless via a duplicated group,
		paused and clarified on hover. Static list under reduced motion. */
.gx-ticker {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 5;
	height: 60px;
	display: flex;
	align-items: center;
	overflow: hidden;
	background: rgba(10, 14, 20, .38);
	-webkit-backdrop-filter: blur(8px);
	backdrop-filter: blur(8px);
	border-top: 1px solid var(--white-13);
	opacity: .82;
	transition: opacity var(--dur-fast) ease;
}

.gx-ticker:hover {
	opacity: 1;
}

.gx-ticker:hover .gx-ticker__track {
	animation-play-state: paused;
}

.gx-ticker__track {
	display: flex;
	width: max-content;
	animation: gx-ticker-run var(--gx-ticker-dur, 90s) linear infinite;
	will-change: transform;
}

.gx-ticker__group {
	display: flex;
	align-items: center;
	list-style: none;
	margin: 0;
	padding: 0;
}

.gx-ticker__group li {
	display: flex;
	align-items: center;
	white-space: nowrap;
	padding-right: clamp(26px, 2.6vw, 44px);
	font: 500 12px/1 var(--font-sans);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--white-60);
}

.gx-ticker__group li::before {
	content: '';
	width: 4px;
	height: 4px;
	border-radius: 50%;
	background: var(--green);
	margin-right: clamp(26px, 2.6vw, 44px);
}

@media (max-width: 768px) {
	.gx-ticker {
		height: 48px;
	}

	.gx-ticker__group li {
		font-size: 10.5px;
		letter-spacing: .13em;
		padding-right: 20px;
	}

	.gx-ticker__group li::before {
		margin-right: 20px;
	}
}

@keyframes gx-ticker-run {
	from {
		transform: translate3d(0, 0, 0);
	}

	to {
		transform: translate3d(-50%, 0, 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.gx-ticker__track {
		animation: none;
	}
}

/* ---- how we work: pinned typographic presentation ----
		one stage per viewport; a 400vh track with a sticky 100vh stage. The leading
		"0" is static; only the second digit and the title roll vertically inside
		their masks like a mechanical flip counter — a discrete transition fired on
		stage change (never scrubbed, no fades/scales on the digit), with the right
		panel switching at the exact same moment. A fixed vertical progress rail on
		the far left fills green continuously with scroll. Snapping to stages is
		done in JS (initProcess) — a cancellable rAF tween that runs only after the
		scroll goes idle and dies on any user input. CSS scroll-snap on html is
		deliberately NOT used: combined with scroll-behavior:smooth it eats wheel
		events mid-snap in Chromium and the page appears frozen on fast direction
		reversals. The presentation holds FIVE slides: four stages + the final CTA
		chapter, which pushes in from below over the stage and only then does the
		pin release. */
.hw {
	/* heavy, engineered ease — mechanical counter feel, no bounce; one shared
			duration so digit, title and the right slide move as a single beat */
	--hw-ease: cubic-bezier(.76, 0, .18, 1);
	--hw-dur: .65s;
	position: relative;
	/* 4 stages + CTA at 100vh each, plus one extra viewport of CTA dwell:
			the finale stays pinned ~2 viewport heights before the release */
	height: 600vh;
	background: var(--white);
}

.hw__pin {
	position: sticky;
	top: 0;
	height: 100vh;
	overflow: hidden;
}

/* dots + both line layers tile from the SAME top-left 72px grid, so every
		dot sits exactly on a line crossing at any viewport size (repeating-
		linear-gradient at 0deg tiles from the bottom edge — at heights not
		divisible by 72px the lines drifted off the dots) */
.hw__gridbg {
	position: absolute;
	inset: 0;
	background-image:
		radial-gradient(circle at 0 0, rgba(33, 30, 24, .14) 1.7px, transparent 2.2px),
		linear-gradient(to bottom, rgba(33, 30, 24, .025) 1px, transparent 1px),
		linear-gradient(to right, rgba(33, 30, 24, .025) 1px, transparent 1px);
	background-size: 72px 72px, 72px 72px, 72px 72px;
}

.hw__stage {
	position: relative;
	display: grid;
	transition: transform 1.05s var(--hw-ease);
	will-change: transform;
	grid-template-columns: 1.25fr .75fr;
	align-items: center;
	gap: clamp(28px, 4vw, 80px);
	height: 100%;
	padding: 0 var(--section-pad-x);
}

/* ---- left: static zero + mechanical rolling digit/title ----
		the "0" never moves; the second digit and the title live in overflow masks
		and roll vertically (enter from below, exit upward) on stage change. JS sets
		the roll offset once per stage; the CSS transition does the physical move. */
.hw__num {
	display: flex;
	align-items: baseline;
	font: 700 clamp(220px, 30vw, 465px)/0.86 var(--font-sans);
	letter-spacing: -.05em;
	color: var(--ink);
}

.hw__zero {
	display: block;
}

.hw__digit-mask {
	display: block;
	height: .86em;
	overflow: hidden;
}

.hw__digit-roll {
	display: flex;
	flex-direction: column;
	transition: transform var(--hw-dur) var(--hw-ease);
	will-change: transform;
}

.hw__digit-roll > span {
	display: block;
	height: .86em;
}

.hw__title-mask {
	overflow: hidden;
	height: 1.12em;
	font: 700 clamp(40px, 6.6vw, 114px)/1.12 var(--font-sans);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--ink);
	margin-top: clamp(8px, 1.6vh, 20px);
}

.hw__title-roll {
	display: flex;
	flex-direction: column;
	transition: transform var(--hw-dur) var(--hw-ease);
	will-change: transform;
}

.hw__title {
	display: block;
	height: 1.12em;
	white-space: nowrap;
}

/* ---- final chapter: the CTA slide pushes in from below over the stage ---- */
.hw__pin.is-final .hw__stage {
	transform: translateY(-10vh);
}

.hw__cta {
	position: absolute;
	inset: 0;
	z-index: 3;
	background: var(--white);
	display: grid;
	place-items: center;
	padding: 0 var(--section-pad-x);
	transform: translateY(102%);
	/* visibility flips only after the exit push finishes (keeps the button
			out of the tab order while parked below the mask) */
	transition: transform 1.05s var(--hw-ease), visibility 0s 1.05s;
	will-change: transform;
	visibility: hidden;
}

.hw__cta.is-active {
	transform: translateY(0);
	visibility: visible;
	transition: transform 1.05s var(--hw-ease), visibility 0s;
}

.hw__cta-inner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 0;
}

.hw__cta-inner .hw__label {
	margin-bottom: 30px;
}

.hw__cta-title {
	margin: 0 0 22px;
	font: 700 clamp(38px, 4.8vw, 78px)/1.08 var(--font-sans);
	letter-spacing: .02em;
	text-transform: uppercase;
	color: var(--ink);
}

.hw__cta-text {
	margin: 0 0 38px;
	font: 400 17.5px/1.65 var(--font-sans);
	color: var(--ink-70);
}

/* step 2 of the finale: the button group waits ~35% into the CTA dwell,
		then fades in with a soft upward slide */
.hw__cta-step2 {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity .6s ease, transform var(--hw-dur) var(--hw-ease);
}

.hw__cta.is-step2 .hw__cta-step2 {
	opacity: 1;
	transform: none;
}

/* while the finale is pinned the scene stays quietly alive: the grid creeps
		one cell per 45s, the headline drifts ~2px, the button breathes — all
		barely perceptible, none of it on interactive transforms */
.hw__cta.is-active .hw__gridbg {
	animation: hw-gridslide 45s linear infinite;
}

.hw__cta.is-active .hw__cta-title {
	animation: hw-drift 6s ease-in-out infinite alternate;
}

.hw__cta.is-active .hw__cta-btnwrap {
	animation: hw-breathe 3.8s ease-in-out infinite;
}

@keyframes hw-gridslide {
	from {
		background-position: 0 0, 0 0, 0 0;
	}

	to {
		background-position: 72px 72px, 72px 72px, 72px 72px;
	}
}

@keyframes hw-drift {
	from {
		transform: translateY(0);
	}

	to {
		transform: translateY(-2px);
	}
}

@keyframes hw-breathe {
	0%,
	100% {
		transform: scale(1);
	}

	50% {
		transform: scale(1.015);
	}
}

/* ---- far-left progress: a single quiet line, no numbers/labels/dots ----
		the big animated number is the only stage number on screen; the line alone
		communicates progress */
.hw__rail {
	position: absolute;
	left: clamp(20px, 2.6vw, 44px);
	top: 50%;
	transform: translateY(-50%);
	height: min(52vh, 440px);
	/* above the CTA slide (z-index 3): the line completes its fill during the
			finale and only leaves the screen together with the pin */
	z-index: 4;
}

.hw__rail-track {
	height: 100%;
	position: relative;
	width: 2px;
	border-radius: var(--radius-full);
	background: var(--ink-10);
	overflow: hidden;
}

.hw__rail-fill {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 0;
	background: var(--green);
	will-change: height;
}

/* ---- right: stage details, identical layout each stage ---- */
.hw__info {
	position: relative;
	max-width: 440px;
}

/* section heading above the giant number (h2 on the left column; the CTA
		slide reuses the same look for its eyebrow) */
/* the .hw scene sits on --white — green type needs the AA-safe ink green */
.hw__label {
	display: block;
	margin: 0 0 clamp(20px, 3.6vh, 36px);
	font: 500 11px/1 var(--font-sans);
	letter-spacing: .24em;
	text-transform: uppercase;
	color: var(--green-ink);
}

/* one persistent fixed-height container for the right column: JS reserves
		the tallest panel's height once (and on resize), so the layout never
		shifts, reflows or jumps between stages */
.hw__panes {
	position: relative;
}

/* the whole panel (title + description + rows + icons) is ONE composition:
		it leaves slightly upward while the next enters from below, overlapping,
		with the SAME trigger, duration and easing as the digit/title roll —
		nothing staggers, nothing lags */
.hw__panel {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	opacity: 0;
	transform: translateY(28px);
	transition: opacity .6s ease, transform var(--hw-dur) var(--hw-ease);
	pointer-events: none;
	will-change: transform, opacity;
}

.hw__panel.is-active {
	opacity: 1;
	transform: none;
	pointer-events: auto;
}

.hw__panel.is-past {
	transform: translateY(-28px);
}

.hw__panel-title {
	margin: 0 0 14px;
	font: 300 clamp(26px, 2.2vw, 35px)/1.15 var(--font-serif);
	color: var(--ink);
}

.hw__panel-text {
	margin: 0 0 10px;
	font: 400 17.5px/1.65 var(--font-sans);
	color: var(--ink-70);
}

/* ---- premium information rows: icon + title + description ---- */
.hw__rows {
	list-style: none;
	margin: 0;
	padding: 0;
}

.hw__row {
	display: grid;
	grid-template-columns: 20px 1fr;
	gap: 0 16px;
	align-items: start;
	padding: 15px 0;
}

.hw__row + .hw__row {
	border-top: 1px solid var(--ink-10);
}

.hw__row-icon {
	width: 20px;
	height: 20px;
	color: var(--ink-58);
	margin-top: 1px;
}

.hw__row-title {
	display: block;
	font: 500 13.5px/1.35 var(--font-sans);
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--ink);
}

.hw__row-text {
	margin: 5px 0 0;
	font: 400 14px/1.55 var(--font-sans);
	color: var(--ink-58);
}

@media (max-width: 1040px) {
	.hw__stage {
		grid-template-columns: 1fr;
		align-content: center;
		align-items: start;
		gap: clamp(22px, 4vh, 40px);
	}

	.hw__info {
		max-width: 560px;
	}

	.hw__num {
		font-size: clamp(150px, 24vw, 260px);
	}

	.hw__title-mask {
		font-size: clamp(34px, 6vw, 64px);
	}

	.hw__rail {
		left: 12px;
		height: 42vh;
	}
}

@media (max-width: 768px) {
	.hw__num {
		font-size: clamp(150px, 42vw, 220px);
	}

	.hw__title-mask {
		font-size: clamp(30px, 9.2vw, 48px);
	}

	.hw__label {
		margin-bottom: 18px;
	}

	.hw__panel-text {
		font-size: 16px;
	}

	.hw__row {
		padding: 12px 0;
	}

	/* the 3.5vw gutter can't host the rail without colliding with content */
	.hw__rail {
		display: none;
	}
}

/* ---- works: entrance as the direct continuation of the presentation ----
		home.js adds .is-preenter on init and .is-enter the moment the CTA finishes
		(still pinned), so the gallery is already rising and its intro (gallery.js
		playIntro, triggered by the same gx:hw-done event) is already running when
		the section scrolls into view — no static waiting state, no dead scroll */
.works-shell.is-preenter {
	opacity: 0;
	transform: translateY(44px);
	transition: opacity .9s ease, transform 1.1s var(--ease);
}

.works-shell.is-preenter.is-enter {
	opacity: 1;
	transform: none;
}

/* ---- hero project slider (autoplay, home only) ---- */
#gxh-slider {
	position: absolute;
	right: 5vw;
	bottom: 106px;
	z-index: 6;
	width: 330px;
	max-width: 84vw;
	text-decoration: none;
	opacity: 0;
}

.gxh-progress {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 0 8px 14px;
}

#gxh-idx {
	font: 600 12px/1 var(--font-sans);
	letter-spacing: .1em;
	color: var(--white);
}

#gxh-total {
	font: 600 12px/1 var(--font-sans);
	letter-spacing: .1em;
	color: var(--white-60);
}

.gxh-track {
	flex: 1;
	height: 2px;
	border-radius: var(--radius-full);
	background: rgba(255, 255, 255, .25);
	position: relative;
	overflow: hidden;
}

#gxh-bar {
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 0%;
	background: var(--white);
	border-radius: var(--radius-full);
}

.gxh-card {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	border-radius: var(--radius-lg);
	background: rgba(22, 20, 15, .55);
	border: 1px solid var(--white-13);
	backdrop-filter: blur(16px);
	-webkit-backdrop-filter: blur(16px);
	/* NO overflow:hidden here — an overflow clip on the same element kills the
	   backdrop blur in Chromium, and nothing inside needs clipping anyway
	   (the thumb rounds itself) */
	transition: border-color var(--dur-base) var(--ease);
}

/* proof header: 50+ counts up once (initHeroProof), hairline splits it from the case row */
.gxh-proof {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 11px 16px;
	border-bottom: 1px solid var(--white-13);
}

.gxh-proof__num {
	display: flex;
	align-items: baseline;
	font: 700 21px/1 var(--font-sans);
	color: var(--white);
	font-variant-numeric: tabular-nums;
	letter-spacing: -.02em;
}

.gxh-proof__num i {
	font-style: normal;
	font-size: 14px;
	color: var(--green);
	margin-left: 1px;
}

.gxh-proof__label {
	font: 500 12px/1 var(--font-sans);
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--white-60);
}

/* the case row (previous .gxh-card layout) */
.gxh-main {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 13px;
}

.gxh-card:hover {
	border-color: var(--green);
}

.gxh-thumb {
	flex: none;
	width: 88px;
	height: 80px;
	border-radius: var(--radius-sm);
	overflow: hidden;
	background: #11161e;
}

#gxh-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: opacity var(--dur-base) ease;
}

.gxh-text {
	flex: 1;
	min-width: 0;
}

#gxh-title {
	font: 600 15px/1.3 var(--font-sans);
	color: var(--white);
}

#gxh-sub {
	margin-top: 6px;
	font: 400 13px/1.4 var(--font-sans);
	color: var(--white-60);
}

/* ---- scroll cue (home only) ---- */
.gx-hero__cue {
	position: absolute;
	left: var(--section-pad-x);
	bottom: 96px;
	z-index: 5;
	display: flex;
	align-items: center;
	gap: 12px;
}

.gx-hero__cue-label {
	font: 500 10px/1 var(--font-sans);
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--white-50);
}

.gx-hero__cue-icon {
	animation: gx-cue 2.4s ease-in-out infinite;
}

/* ---- works gallery shell ---- */
.works-shell {
	position: relative;
	width: 100%;
	height: 100vh;
	min-height: 640px;
	overflow: hidden;
	background: var(--charcoal);
}

/* ---- draggable works gallery ---- */
.gxw-viewport {
	position: absolute;
	inset: 0;
	z-index: 1;
	overflow: hidden;
	opacity: 0;
	cursor: grab;
	background: var(--charcoal);
}

.gxw-viewport.gxw-dragging {
	cursor: grabbing;
}

.gxw-canvas {
	position: absolute;
	top: 0;
	left: 0;
	transform-origin: 0 0;
	will-change: transform;
	isolation: isolate;
	z-index: 2;
}

.gxw-cage {
	position: absolute;
	background-image: url('../assets/works/gxw-cell.svg');
	background-repeat: repeat;
	background-position: 0 0;
	opacity: .28;
	pointer-events: none;
	z-index: 0;
}

/* cursor-lit cage: masked light copy of the net, follows the pointer in canvas space (gallery.js) */
.gxw-cage-lit {
	position: absolute;
	top: 0;
	left: 0;
	width: 1200px;
	height: 1200px;
	background-image: url('../assets/works/gxw-cell-lit.svg');
	background-repeat: repeat;
	pointer-events: none;
	z-index: 1;
	opacity: 0;
	-webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, rgba(0, 0, 0, .95) 0%, rgba(0, 0, 0, .4) 45%, rgba(0, 0, 0, 0) 72%);
	mask-image: radial-gradient(circle closest-side at 50% 50%, rgba(0, 0, 0, .95) 0%, rgba(0, 0, 0, .4) 45%, rgba(0, 0, 0, 0) 72%);
	will-change: transform, opacity;
}

.gxw-grid {
	position: relative;
	z-index: 2;
}

.gxw-item {
	position: absolute;
	width: 359px;
	height: 359px;
	background: transparent;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
}

.gxw-item img {
	width: 300px;
	height: 300px;
	object-fit: cover;
	display: block;
	pointer-events: none;
	background: var(--charcoal);
	box-shadow: 0 10px 28px rgba(0, 0, 0, .55);
	transition: transform .55s var(--ease);
}

.gxw-item:hover img {
	transform: scale(1.04);
}

.gxw-item:focus-visible {
	outline: 2px solid var(--green);
	outline-offset: 3px;
}

#gxw-spot {
	position: absolute;
	top: 0;
	left: 0;
	width: 400px;
	height: 400px;
	margin: -200px 0 0 -200px;
	border-radius: 50%;
	pointer-events: none;
	z-index: 1;
	opacity: 0;
	mix-blend-mode: screen;
	background: radial-gradient(circle, rgba(255, 233, 196, 0.1) 0%, rgb(255 221 160 / 5%) 0%, rgba(255, 221, 160, 0) 60%);
	will-change: transform, opacity;
}

.gxw-item.gxw-dim {
	opacity: .12;
}

.gxw-zb {
	transition: color .3s ease;
	border-radius: 2px;
}

.gxw-zb.is-on {
	color: var(--cream);
}

.gxw-zb:hover {
	color: var(--green);
}

#gxw-close:hover {
	background: var(--green-cta);
	border-color: var(--green-cta);
}

.gxw-overlay {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 9100;
	pointer-events: none;
	will-change: transform;
	overflow: hidden;
}

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

.gxw-descline {
	display: block;
	font: 400 16px/1.6 var(--font-sans);
	color: var(--cream-62);
	overflow: hidden;
}

/* ---- works: header overlay ---- */
#gxw-head {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	z-index: 6;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 30px;
	padding: clamp(40px, 6vh, 64px) var(--section-pad-x) 0;
	pointer-events: none;
	opacity: 0;
}

.gxw-head-note {
	font: 400 13px/1.5 var(--font-sans);
	color: var(--cream-50);
	max-width: 230px;
	text-align: right;
}

/* ---- works: vignette + controls ---- */
.gxw-vignette {
	position: absolute;
	inset: 0;
	z-index: 4;
	pointer-events: none;
	background: linear-gradient(to bottom, rgba(12, 17, 24, .82) 0%, rgba(12, 17, 24, .25) 16%, transparent 34%, transparent 78%, rgba(12, 17, 24, .55) 100%);
}

#gxw-controls {
	position: absolute;
	left: 50%;
	bottom: 30px;
	transform: translateX(-50%);
	z-index: 6;
	display: flex;
	align-items: stretch;
	gap: 10px;
	opacity: 0;
}

#gxw-pct {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 64px;
	padding: 10px 16px;
	border-radius: var(--radius-xs);
	background: var(--cream);
	color: var(--charcoal);
	font: 600 11px/1 var(--font-sans);
	letter-spacing: .12em;
}

.gxw-zoomgroup {
	display: flex;
	align-items: center;
	gap: 4px;
	padding: 5px;
	border-radius: var(--radius-xs);
	background: var(--charcoal);
}

.gxw-zb {
	padding: 8px 13px;
	border: none;
	background: none;
	cursor: pointer;
	color: var(--cream-50);
	font: 600 10.5px/1 var(--font-sans);
	letter-spacing: .1em;
	text-transform: uppercase;
	transition: color .3s ease;
	border-radius: 2px;
}

/* +/− zoom steps: square symbol buttons (replace the verbose «Наблизити/Віддалити»
   labels to free up room in the controls bar) */
.gxw-zb--icon {
	min-width: 30px;
	padding: 6px 8px;
	font-size: 17px;
	line-height: 1;
	letter-spacing: 0;
}

/* ============================================================
   Works section → Google Maps «Карта проєктів»
   ============================================================ */

/* toggle button in the controls bar (gallery ⇄ map) */
.gxw-map-toggle {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 9px 15px;
	border: none;
	border-radius: var(--radius-xs);
	background: var(--green-cta);
	color: var(--white);
	font: 600 10.5px/1 var(--font-sans);
	letter-spacing: .1em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color .3s ease;
}

.gxw-map-toggle:hover {
	background: var(--green-cta-hover);
}

.gxw-map-toggle svg {
	flex: none;
}

.gxw-map-toggle__icon {
	display: inline-flex;
	align-items: center;
}

/* mobile: gallery.js hides #gxw-controls, so the toggle rides in the header */
.gxw-map-toggle--mob {
	position: absolute;
	top: 18px;
	right: 18px;
	z-index: 7;
}

/* map surface fills the works-shell, hidden until «Карта» is on */
/* FULLSCREEN overlay (works-map.js moves #gxw-map to <body> so `fixed` is always
   viewport-relative). Opens instantly on «Карта» — no scroll to the works section. */
.gxw-map {
	position: fixed;
	inset: 0;
	z-index: 9500;
	background: var(--cream);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity .4s var(--ease), visibility 0s linear .4s;
}

.gxw-map.is-open {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition: opacity .4s var(--ease);
}

/* close/back button (returns to the page/gallery) */
.gxw-map__close {
	position: absolute;
	top: 18px;
	right: 18px;
	z-index: 5;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 16px 10px 13px;
	border: none;
	border-radius: var(--radius-full);
	background: var(--charcoal);
	color: var(--cream);
	font: 600 11px/1 var(--font-sans);
	letter-spacing: .1em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color .3s ease;
}

.gxw-map__close:hover {
	background: #000;
}

.gxw-map__close svg {
	flex: none;
}

/* «Дивитись на карті» — button in the gallery project detail (dark split-right) */
.gxw-detail-maplink {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	align-self: flex-start;
	margin-top: 26px;
	padding: 12px 22px;
	border: 1px solid rgba(255, 255, 255, .28);
	border-radius: var(--radius-full);
	color: var(--cream);
	font: 600 12px/1 var(--font-sans);
	letter-spacing: .08em;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .3s ease, border-color .3s ease, color .3s ease;
}

.gxw-detail-maplink:hover {
	background: var(--green-cta);
	border-color: var(--green-cta);
	color: var(--white);
}

.gxw-detail-maplink svg {
	flex: none;
}

.gxw-map__canvas {
	position: absolute;
	inset: 0;
}

/* map fills with our own placeholder tone before Google paints */
.gxw-map__hint {
	position: absolute;
	top: 20px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 2;
	max-width: min(88%, 420px);
	padding: 9px 16px;
	border-radius: var(--radius-full);
	background: rgba(22, 20, 15, .82);
	color: var(--cream);
	font: 500 12px/1.35 var(--font-sans);
	text-align: center;
	pointer-events: none;
}

.gxw-map__state {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	z-index: 2;
	display: none;
	padding: 12px 20px;
	border-radius: var(--radius-sm);
	background: var(--charcoal);
	color: var(--cream);
	font: 500 13px/1.4 var(--font-sans);
	text-align: center;
}

.gxw-map.is-loading .gxw-map__state--load,
.gxw-map.is-error .gxw-map__state--err {
	display: block;
}

.gxw-map.is-error .gxw-map__hint {
	display: none;
}

/* ---- custom photo pin (OverlayView, anchored bottom-centre at its coordinate) ---- */
.gxw-pin {
	position: absolute;
	transform: translate(-50%, -100%);
	padding: 0;
	border: none;
	background: none;
	cursor: pointer;
	line-height: 0;
	filter: drop-shadow(0 6px 12px rgba(12, 17, 24, .38));
	transition: transform .2s var(--ease);
	will-change: transform;
}

.gxw-pin:hover,
.gxw-pin:focus-visible {
	transform: translate(-50%, -100%) scale(1.08);
	outline: none;
	z-index: 5;
}

.gxw-pin__img {
	display: block;
	width: 50px;
	height: 50px;
	border-radius: 50%;
	background-size: cover;
	background-position: center;
	border: 3px solid var(--white);
}

/* downward triangle tip (arrow pointing at the exact coordinate) */
.gxw-pin::after {
	content: '';
	position: absolute;
	left: 50%;
	bottom: -9px;
	transform: translateX(-50%);
	width: 0;
	height: 0;
	border-left: 7px solid transparent;
	border-right: 7px solid transparent;
	border-top: 11px solid var(--white);
}

/* hover + active both glow green (active persists after the popup closes) */
.gxw-pin.is-active .gxw-pin__img,
.gxw-pin:hover .gxw-pin__img,
.gxw-pin:focus-visible .gxw-pin__img {
	border-color: var(--green-cta);
}

.gxw-pin.is-active::after,
.gxw-pin:hover::after,
.gxw-pin:focus-visible::after {
	border-top-color: var(--green-cta);
}

/* ---- site popup: LARGE-photo lightbox over the map ---- */
.gxw-map-pop {
	position: absolute;
	inset: 0;
	z-index: 8;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 30px;
	opacity: 0;
	transition: opacity .3s var(--ease);
}

.gxw-map-pop.is-open {
	opacity: 1;
}

.gxw-map-pop__scrim {
	position: absolute;
	inset: 0;
	background: rgba(12, 17, 24, .74);
	-webkit-backdrop-filter: blur(3px);
	backdrop-filter: blur(3px);
}

.gxw-map-pop__panel {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	width: min(940px, 100%);
	max-height: 100%;
	background: var(--cream);
	border-radius: var(--radius-lg);
	overflow: hidden;
	box-shadow: 0 40px 90px rgba(12, 17, 24, .5);
	transform: translateY(14px) scale(.985);
	transition: transform .35s var(--ease);
}

.gxw-map-pop.is-open .gxw-map-pop__panel {
	transform: none;
}

.gxw-map-pop__close {
	position: absolute;
	top: 12px;
	right: 12px;
	z-index: 3;
	width: 38px;
	height: 38px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: none;
	border-radius: 50%;
	background: rgba(12, 17, 24, .55);
	color: var(--white);
	cursor: pointer;
	transition: background-color .3s ease;
}

.gxw-map-pop__close:hover {
	background: rgba(12, 17, 24, .82);
}

/* big photo stage */
.gxw-map-pop__stage {
	flex: none;
	height: min(56vh, 520px);
	display: flex;
	align-items: center;
	justify-content: center;
	background: #0c1118;
}

.gxw-map-pop__main {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
	display: block;
}

/* thumbnail strip (hidden when a single photo) */
.gxw-map-pop__thumbs {
	flex: none;
	display: flex;
	gap: 8px;
	padding: 10px 14px;
	overflow-x: auto;
	background: var(--cream);
}

.gxw-map-pop__thumbs[hidden] {
	display: none;
}

.gxw-map-pop__thumb {
	flex: none;
	width: 76px;
	height: 54px;
	padding: 0;
	border: 2px solid transparent;
	border-radius: var(--radius-xs);
	background-size: cover;
	background-position: center;
	cursor: pointer;
	opacity: .6;
	transition: opacity .25s ease, border-color .25s ease;
}

.gxw-map-pop__thumb:hover {
	opacity: .9;
}

.gxw-map-pop__thumb.is-active {
	opacity: 1;
	border-color: var(--green-cta);
}

/* info + directions bar */
.gxw-map-pop__body {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px;
	padding: 16px 20px 18px;
}

.gxw-map-pop__type {
	font: 700 10px/1 var(--font-sans);
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--green-ink);
	margin-bottom: 7px;
}

.gxw-map-pop__title {
	font: 400 21px/1.2 var(--font-serif);
	color: var(--ink);
	margin: 0 0 3px;
}

.gxw-map-pop__loc {
	font: 400 13px/1.5 var(--font-sans);
	color: var(--ink-58);
}

.gxw-map-pop__route {
	flex: none;
}

/* mobile: bottom-sheet lightbox */
@media (max-width: 640px) {
	.gxw-map-pop {
		padding: 0;
		align-items: flex-end;
	}
	.gxw-map-pop__panel {
		width: 100%;
		max-height: 94%;
		border-radius: var(--radius-lg) var(--radius-lg) 0 0;
		transform: translateY(100%);
	}
	.gxw-map-pop.is-open .gxw-map-pop__panel {
		transform: none;
	}
	.gxw-map-pop__stage {
		height: 44vh;
	}
	.gxw-map-pop__body {
		flex-direction: column;
		align-items: stretch;
	}
	.gxw-map-pop__route {
		justify-content: center;
	}
}

/* ---- works: split-screen project detail ---- */
.gxw-split {
	position: fixed;
	inset: 0;
	z-index: 9000;
	display: flex;
	opacity: 0;
	pointer-events: none;
}

#gxw-split-left {
	position: relative;
	width: 54vw;
	height: 100vh;
	background: #070a0e;
	overflow: hidden;
	cursor: pointer;
}

#gxw-zoomtarget {
	position: absolute;
	inset: 0;
}

#gxw-detail-clean {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0;
	pointer-events: none;
	left: 6px;
	top: 2px;
}

#gxw-split-right {
	position: relative;
	width: 46vw;
	height: 100vh;
	background: var(--dark);
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: clamp(40px, 6vw, 90px) clamp(36px, 5vw, 78px);
	cursor: pointer;
}

.gxw-clip {
	overflow: hidden;
	margin-bottom: 24px;
}

#gxw-num {
	font: 500 11px/1 var(--font-sans);
	letter-spacing: .24em;
	text-transform: uppercase;
	color: var(--green);
}

#gxw-title {
	margin: 0;
	font: 300 clamp(30px, 3.8vw, 52px)/1.08 var(--font-serif);
	letter-spacing: -.015em;
	color: var(--white);
}

#gxw-desc {
	max-width: 380px;
	margin-bottom: 40px;
}

.gxw-meta-row {
	display: flex;
	gap: 36px;
	padding-top: 28px;
	border-top: 1px solid var(--cream-16);
}

.gxw-meta-clip {
	overflow: hidden;
}

.gxw-meta-label {
	font: 500 10px/1 var(--font-sans);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--cream-40);
	margin-bottom: 9px;
}

#gxw-loc,
#gxw-type {
	font: 400 16px/1.3 var(--font-serif);
	color: var(--cream);
}

#gxw-close {
	position: fixed;
	top: 30px;
	right: 5vw;
	z-index: 9200;
	width: 54px;
	height: 54px;
	border-radius: 50%;
	border: 1px solid rgba(237, 232, 222, .28);
	background: rgba(12, 17, 24, .55);
	color: var(--cream);
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	pointer-events: none;
	backdrop-filter: blur(6px);
	transition: background-color .3s ease, border-color .3s ease;
}


/* ================= MOBILE WORKS: snap carousel + stacked detail ================= */
@media (max-width: 768px) {
	.works-mob {
		height: auto;
		min-height: 0;
	}

	.works-mob #gxw-head {
		position: static;
		opacity: 1;
		pointer-events: auto;
		flex-direction: column;
		align-items: flex-start;
		gap: 10px;
		padding: 56px var(--section-pad-x) 4px;
	}

	.works-mob #gxw-head span {
		text-align: left;
		max-width: none;
	}

	.gxw-mob {
		display: flex;
		gap: 14px;
		overflow-x: auto;
		padding: 20px var(--section-pad-x) 52px;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}

	.gxw-mob::-webkit-scrollbar {
		display: none;
	}

	@keyframes gxw-shimmer {
		to { background-position: -200% 0; }
	}

	.gxw-mcard {
		flex: 0 0 82%;
		max-width: 340px;
		scroll-snap-align: center;
		border: 0;
		padding: 0;
		border-radius: var(--radius-lg);
		overflow: hidden;
		position: relative;
		background: linear-gradient(100deg, #11161e 40%, #1c2430 50%, #11161e 60%);
		background-size: 200% 100%;
		animation: gxw-shimmer 1.5s linear infinite;
		text-align: left;
		cursor: pointer;
		aspect-ratio: 4 / 4.6;
	}

	.gxw-mcard img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		display: block;
		position: absolute;
		inset: 0;
		z-index: 0;
		opacity: 0;
		transition: opacity .5s ease;
	}

	.gxw-mcard img.is-loaded {
		opacity: 1;
	}

	/* the caption is white type straight on the photo — a pale stone shot left it
			at ~1.2:1. Same scrim idiom as .ctl-feat__scrim: opaque at the base, gone
			by mid-card, so the image reads untouched above the text. */
	/* the scrim is the card's ::after — i.e. its LAST child — so with auto z-index
			it painted on top of the caption instead of behind it: white type sat on a
			bare pale photo at ~1.2:1. Explicit layers: photo 0 · scrim 1 · caption 2. */
	.gxw-mcard::after {
		content: '';
		position: absolute;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 1;
		height: 62%;
		background: linear-gradient(to top, rgba(12,17,24,.94) 0%, rgba(12,17,24,.78) 26%, rgba(12,17,24,.34) 58%, transparent 100%);
		pointer-events: none;
	}

	.gxw-mcard-t {
		position: absolute;
		left: 18px;
		right: 18px;
		bottom: 36px;
		z-index: 2;
		padding: 0;
		font: 500 16px/1.3 var(--font-sans);
		color: var(--white);
	}

	.gxw-mcard-m {
		position: absolute;
		left: 18px;
		bottom: 14px;
		z-index: 2;
		padding: 0;
		font: 400 12px/1.4 var(--font-sans);
		letter-spacing: normal;
		text-transform: none;
		color: var(--white-60);
	}

	.gxw-mcard:focus-visible {
		outline: 2px solid var(--green);
		outline-offset: 3px;
	}

	.gxw-mob-count {
		font: 600 12px/1 var(--font-sans);
		letter-spacing: .1em;
		color: var(--cream-50);
	}

	.gxw-dots {
		display: flex;
		justify-content: center;
		gap: 7px;
		margin: 4px 0 44px;
	}

	.gxw-dots span {
		width: 7px;
		height: 7px;
		border-radius: 50%;
		background: rgba(255,255,255,.25);
		transition: background-color .3s ease, transform .3s ease;
	}

	.gxw-dots span.is-on {
		background: var(--green);
		transform: scale(1.3);
	}

	/* with many projects (40) dots don't fit a phone — gallery.js builds this
			slim progress bar instead once the list passes ~10 entries */
	.gxw-prog {
		width: min(220px, 56vw);
		height: 2px;
		border-radius: var(--radius-full);
		background: rgba(255,255,255,.18);
		margin: 14px auto 44px;
		overflow: hidden;
	}

	.gxw-prog span {
		display: block;
		height: 100%;
		width: 0%;
		border-radius: inherit;
		background: var(--green);
		transition: width .25s ease-out;
	}

	/* project detail stacks: photo on top, scrollable story below */
	#gxw-split {
		flex-direction: column;
	}

	#gxw-split-left {
		width: 100%;
		height: 42svh;
		flex: none;
	}

	#gxw-split-right {
		width: 100%;
		height: auto;
		flex: 1;
		overflow-y: auto;
		overscroll-behavior: contain;
		justify-content: flex-start;
		padding-top: 26px;
		cursor: default;
	}

	#gxw-detail-clean {
		left: 0;
		top: 0;
	}

	.gxw-mob-desc {
		font: 400 15.5px/1.65 var(--font-sans);
		color: var(--cream-62);
	}

	/* tooltips become a thumb-reachable bottom sheet */
	.gx-tip-pop {
		position: fixed;
		left: 16px;
		right: 16px;
		top: auto;
		bottom: calc(84px + env(safe-area-inset-bottom, 0px));
		width: auto;
		transform: translateY(8px);
		box-shadow: 0 18px 44px rgba(0, 0, 0, .4);
	}

	.gx-tip-pop::after {
		display: none;
	}
}

@media (min-width: 769px) {
	/* ---- "Як ми працюємо" — desktop 4-col card grid (mobile keeps the vertical timeline) ---- */
}

/* ---- "Як ми працюємо" — shared step card look (dark cards + one highlighted light card) ---- */
/* the CTA row survives the redesign — restyled for the light presentation surface */

/* ================= calc lead popup — shared head + desktop centered modal =================
		.calc-sheet__head is shared by the details sheet (mobile-only) and the lead popup (both
		breakpoints); style it unconditionally here so the lead popup's title/close row lines up
		without needing the .mobile-only escape hatch. The lead sheet itself is a bottom sheet on
		mobile (@media max-width:768px below) and a centered modal here on desktop — gated by
		min-width so the two presentations never fight over specificity. */
.calc-sheet__head {
	display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px;
}
.calc-sheet__title { font: 300 24px/1.1 var(--font-serif); color: var(--white); }
.calc-sheet__title--serif { font-size: 26px; }
.calc-sheet__close {
	width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--white-24);
	background: none; color: var(--cream); display: flex; align-items: center; justify-content: center;
}
.calc-lead__intro { margin: 0 0 16px; font: 400 13.5px/1.6 var(--font-sans); color: var(--cream-62); }
.calc-lead__context {
	display: inline-flex; align-items: center; gap: 8px; margin-bottom: 20px;
	padding: 10px 14px; border-radius: var(--radius-full); background: var(--green-wash-strong);
	font: 500 12.5px/1.3 var(--font-sans); color: var(--white-85);
}
.calc-lead__input {
	width: 100%; padding: 16px 18px; border: 1px solid var(--white-24); border-radius: var(--radius-full);
	background: rgba(255,255,255,.04); font: 400 15px/1.2 var(--font-sans); color: var(--white); outline: none;
}
.calc-lead__input:focus { border-color: var(--green); }
@media (min-width: 769px) {
	#calc-lead-scrim {
		position: fixed; inset: 0; z-index: 970; background: rgba(12,17,24,.55);
		-webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
		opacity: 0; visibility: hidden; pointer-events: none;
		transition: opacity .35s ease, visibility .35s ease;
	}
	#calc-lead-scrim.is-open { opacity: 1; visibility: visible; pointer-events: auto; }

	#calc-lead-sheet {
		position: fixed; top: 50%; left: 50%; z-index: 971;
		width: min(440px, calc(100% - 48px));
		background: var(--charcoal); color: var(--cream);
		border-radius: var(--radius-lg); padding: 36px;
		max-height: 86vh; overflow-y: auto;
		transform: translate(-50%, -46%);
		opacity: 0; visibility: hidden; pointer-events: none;
		transition: opacity .35s var(--ease), transform .35s var(--ease), visibility .35s ease;
	}
	#calc-lead-sheet.is-open {
		opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, -50%);
	}
}

/* mini popup: the lead dialog must fit the 560px iframe without a scrollbar —
   tighter padding and a taller cap than the default 86vh */
.gx-page--calc-embed.is-mini #calc-lead-sheet {
	padding: 26px 26px 28px;
	max-height: calc(100vh - 32px);
}

.gx-page--calc-embed.is-mini #calc-lead-sheet .calc-sheet__head {
	margin-bottom: 14px;
}

.gx-page--calc-embed.is-mini #calc-lead-sheet .calc-lead__context {
	margin-bottom: 14px;
}

/* ================================================================
		MOBILE HOME REDESIGN — ported from "GabionX Mobile.dc.html"
		(claude.ai/design project 723ffc3a). Scoped to .gx-page--home so
		contacts.html keeps its existing mobile nav/hero.
		================================================================ */
@media (max-width: 768px) {

	/* ---- hero: bottom-anchored content, stacked buttons ---- */
	/* design's mobile scrim: one to-top wash (heavy bottom, moderate top) instead of the
			desktop diagonal pair; ken-burns runs the design's stronger mobile curve */
	.gx-page--home .home-hero__scrim-a {
		background: linear-gradient(to top, rgba(10, 14, 20, .94) 0%, rgba(10, 14, 20, .45) 42%, rgba(10, 14, 20, .3) 70%, rgba(10, 14, 20, .55) 100%);
	}
	.gx-page--home .home-hero__scrim-b { display: none; }
	.gx-page--home .gx-hero-img { animation-name: gx-kenburns-m; }
	.gx-page--home .gx-hero__cue { display: none; }
	/* content drops to the bottom of the flex hero, 112px above the edge */
	.gx-page--home .gx-hero--full { justify-content: flex-end; }
	.gx-page--home .gx-hero__content--home {
		margin: 0 22px 140px;
		max-width: none;
	}
	.gx-page--home .gx-hero__eyebrow { margin-bottom: 18px; }
	.gx-page--home .gx-h1--display { font-size: clamp(38px, 11vw, 50px); line-height: 1.0; }
	.gx-page--home .gx-lead--hero { margin: 18px 0 26px; font-size: 15.5px; max-width: 330px; }
	.gx-page--home .gx-hero__actions { flex-direction: column; align-items: stretch; }
	.gx-page--home .gx-hero__actions .gx-btn { width: 100%; }
	.gx-page--home .mobile-only.gx-btn { display: inline-flex; }

	/* ---- services: category cards ---- */
	.gx-page--home #services .gx-head-split { margin-bottom: 36px; }

	/* ---- process/timeline section ---- */
	/* rail runs through the centers of the 32px icon-dots (dot center = tl x 16) */
	/* dot doubles as the step-icon holder on mobile (icon moved in by initProcessTimeline) */
	.hw__cta .gx-btn { width: 100%; justify-content: center; }

	/* ---- calculator: "надіслати розрахунок" share row (Telegram/Viber, prefilled estimate) ---- */
	.gx-page--home .calc-share.mobile-only { display: block; margin-top: 16px; }
	.calc-share__label {
		font: 500 10px/1 var(--font-sans); letter-spacing: .16em; text-transform: uppercase;
		color: var(--cream-40); margin-bottom: 10px;
	}
	.calc-share__row { display: flex; gap: 10px; }
	.calc-share__row a {
		flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
		padding: 13px 10px; border-radius: var(--radius-full); border: 1px solid var(--cream-16);
		color: var(--cream); font: 600 12px/1 var(--font-sans); letter-spacing: .04em; text-decoration: none;
	}

	/* ---- callbar: slides in once the hero is scrolled past, slides away at the footer
					(toggled via .is-shown in home.js). Selector is bare .gx-callbar because the bar
					sits OUTSIDE .gx-page--home in the markup — home.css only loads on this page,
					so contacts keeps its always-visible bar. ---- */
	.gx-callbar {
		transform: translateY(110%);
		transition: transform .45s var(--ease);
	}
	.gx-callbar.is-shown { transform: translateY(0); }

	/* ---- calculator: mobile keeps only the «Сітка оцинкована · граніт 70–120»
	        line of the materials board — photos and the note are desktop reading ---- */
	.gx-page .gx-highlight-box .calc-materials,
	.gx-page .gx-highlight-box__note { display: none; }
	.gx-page .gx-highlight-box__row { margin: 0; }
	.gx-page .gx-highlight-box { padding: 14px 16px; }

	/* ---- calculator: compact card + "Деталі" bottom sheet + lead bottom sheet ---- */
	.calc-details-btn.mobile-only {
		margin-top: 14px; display: inline-flex; align-items: center; gap: 7px;
		padding: 10px 14px; border-radius: var(--radius-full); border: 1px solid var(--white-24);
		background: none; color: var(--cream); font: 600 11px/1 var(--font-sans);
		letter-spacing: .06em; text-transform: uppercase;
	}
	.calc-sheet-scrim {
		position: fixed; inset: 0; z-index: 970; background: rgba(12,17,24,.55);
		-webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
		opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .35s ease, visibility .35s ease;
	}
	.calc-sheet {
		position: fixed; left: 0; right: 0; bottom: 0; z-index: 971;
		background: var(--charcoal); color: var(--cream);
		border-radius: 22px 22px 0 0; padding: 14px 22px calc(24px + env(safe-area-inset-bottom));
		transform: translateY(105%);
		/* closed sheets are also visibility:hidden — even if a revealed ancestor
		   briefly acts as their containing block (will-change), nothing can peek */
		visibility: hidden;
		transition: transform .45s var(--ease), visibility 0s linear .45s;
		max-height: 78svh; overflow-y: auto;
	}

	.calc-sheet.is-open {
		visibility: visible;
		transition: transform .45s var(--ease), visibility 0s;
	}
	#calc-details-sheet.is-open, #calc-details-scrim.is-open,
	#calc-lead-sheet.is-open, #calc-lead-scrim.is-open { transform: translateY(0); opacity: 1; visibility: visible; pointer-events: auto; }
	/* visually a 40×4 bar, but a 64×28 tap target — tapping it closes the sheet
			(.gx-page--home prefix outranks the blanket .mobile-only display rule above) */
	.gx-page--home .calc-sheet__handle {
		display: flex; align-items: center; justify-content: center;
		width: 64px; height: 28px; margin: -8px auto 6px; cursor: pointer;
	}
	.calc-sheet__handle::after {
		content: ''; width: 40px; height: 4px; border-radius: 4px; background: var(--white-24);
	}
	.calc-sheet__head.mobile-only { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
}
/* ---- calculator: the section surface eases out of the dark process block ---- */
#calc {
	background: linear-gradient(180deg, #EBE5DA 0%, var(--bg) 320px);
}

/* ---- calculator embed (calc-embed.html, shown inside the popup iframe) ----
		premium configurator fit: on desktop the whole flow sits in one viewport —
		compact single-row header, tighter panel rhythm, zero internal scrolling.
		Mobile keeps the natural scrolling document. */
/* ---- compact popup (calc-embed.html?mini=1): type + sliders + total only ---- */
.gx-page--calc-embed.is-mini #calc {
	padding: clamp(18px, 3vh, 30px) clamp(16px, 3vw, 28px);
	min-height: 0;
}

/* панелі в iframe: без власних тіней — межа iframe їх обрізала («обрізана тінь»).
   Бордери + кольори панелей дають визначення, а сам попап уже має свою тінь. */
.gx-page--calc-embed .gx-panel {
	box-shadow: none;
}

.gx-page--calc-embed.is-mini .calc-grid {
	grid-template-columns: 1fr;
	gap: 16px;
}

.gx-page--calc-embed.is-mini .gx-head--left {
	margin-bottom: 10px;
}

.gx-page--calc-embed.is-mini .gx-h2 {
	font-size: clamp(24px, 5vw, 30px);
	margin-bottom: 8px;
}

.gx-page--calc-embed.is-mini .gx-eyebrow {
	margin-bottom: 8px;
}

/* everything except тип + повзунки + підсумок is hidden (the whole
   breakdown sheet included — the CTA button sits outside it) */
.gx-page--calc-embed.is-mini .gx-lead,
.gx-page--calc-embed.is-mini .gx-highlight-box,
.gx-page--calc-embed.is-mini #calc-details-sheet,
.gx-page--calc-embed.is-mini #calc-details-scrim,
.gx-page--calc-embed.is-mini .calc-share,
.gx-page--calc-embed.is-mini #calc-details-btn,
.gx-page--calc-embed.is-mini .calc-result__head .gx-tip {
	display: none;
}

/* compact: no inner scroll, two columns on desktop */
.gx-page--calc-embed.is-mini .calc-total {
	font-size: clamp(30px, 4vw, 38px);
}

@media (min-width: 769px) {
	.gx-page--calc-embed.is-mini .calc-grid {
		grid-template-columns: 1.15fr 1fr;
		gap: 14px;
		align-items: stretch;
	}

	.gx-page--calc-embed.is-mini .gx-panel--dark {
		display: flex;
		flex-direction: column;
		justify-content: center;
	}
}

.gx-page--calc-embed.is-mini .gx-panel--light,
.gx-page--calc-embed.is-mini .gx-panel--dark {
	padding: clamp(16px, 2.6vh, 24px);
}

/* mini: tighter spacing only. Colours stay the base CREAM — the desktop mini
   result panel is DARK. The mobile .mcp light-green card flips them to ink in
   home-mobile.css (#calc.mcp-on .calc-area). */
.gx-page--calc-embed.is-mini .calc-area {
	margin-top: 12px;
	padding-top: 12px;
}

.gx-page--calc-embed.is-mini .gx-panel--sticky {
	position: static;
}

.gx-page--calc-embed #calc {
	min-height: 100svh;
	padding: clamp(24px, 4vh, 36px) clamp(20px, 3vw, 40px) clamp(18px, 3vh, 28px);
	display: flex;
	flex-direction: column;
}

/* narrow popup frame (≤999px iframe): panels stack, the document scrolls naturally */
@media (min-width: 769px) and (max-width: 999px) {
	.gx-page--calc-embed .calc-grid {
		grid-template-columns: 1fr;
	}
}

@media (min-width: 1000px) and (min-height: 600px) {
	.gx-page--calc-embed #calc {
		height: 100svh;
		overflow: hidden;
	}

	/* header: eyebrow + title share one baseline row, lead tucks under */
	.gx-page--calc-embed .gx-head--left {
		display: flex;
		align-items: baseline;
		gap: 20px;
		flex-wrap: wrap;
		max-width: none;
		margin: 0 0 clamp(14px, 2.4vh, 24px);
	}

	.gx-page--calc-embed .gx-eyebrow {
		margin-bottom: 0;
	}

	.gx-page--calc-embed .gx-h2 {
		margin: 0;
		font-size: clamp(24px, 3.8vh, 34px);
	}

	.gx-page--calc-embed .gx-head--left .gx-lead {
		flex-basis: 100%;
		font-size: 14px;
		line-height: 1.5;
	}

	/* the two panels split the remaining height and never overflow it */
	.gx-page--calc-embed .calc-grid {
		flex: 1;
		min-height: 0;
		grid-template-columns: 1.1fr 1fr;
		gap: 16px;
	}

	.gx-page--calc-embed .gx-panel {
		padding: clamp(18px, 3vh, 28px) clamp(20px, 2vw, 30px);
		display: flex;
		flex-direction: column;
		min-height: 0;
		overflow: hidden;
	}

	/* materials: slim photo band instead of big squares */
	.gx-page--calc-embed .gx-thumb {
		aspect-ratio: auto;
		height: clamp(88px, 15vh, 132px);
	}

	.gx-page--calc-embed .gx-thumb img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.gx-page--calc-embed .gx-highlight-box {
		margin-bottom: clamp(12px, 2.2vh, 22px);
		padding: 12px 16px;
	}

	.gx-page--calc-embed .calc-controls__group + .calc-controls__group {
		margin-top: clamp(12px, 2vh, 20px);
	}

	/* sliders breathe with the frame instead of a fixed 24px */
	.gx-page--calc-embed .calc-controls__group:last-child {
		flex: 1;
		display: flex;
		flex-direction: column;
		justify-content: space-evenly;
	}

	.gx-page--calc-embed .calc-field {
		margin-bottom: clamp(10px, 1.8vh, 20px);
	}

	/* estimate: tighter vertical rhythm, itemized lines fill the space evenly */
	.gx-page--calc-embed .calc-total {
		font-size: clamp(28px, 4.6vh, 42px);
		margin: 8px 0 2px;
	}

	.gx-page--calc-embed .calc-usd {
		font-size: 13px;
	}

	.gx-page--calc-embed .calc-badge {
		margin: clamp(10px, 1.8vh, 18px) 0 clamp(10px, 1.6vh, 16px);
		padding: 10px 14px;
	}

	.gx-page--calc-embed .calc-lines {
		flex: 1;
		min-height: 0;
		justify-content: space-evenly;
		gap: clamp(6px, 1vh, 12px);
	}

	.gx-page--calc-embed .calc-line {
		font-size: 13px;
	}

	.gx-page--calc-embed .calc-line__qty {
		margin-top: 2px;
		font-size: 10.5px;
	}

	.gx-page--calc-embed .calc-line--total {
		padding-top: clamp(8px, 1.4vh, 14px);
	}

	.gx-page--calc-embed .gx-panel--dark .gx-btn {
		margin-top: clamp(10px, 1.8vh, 16px);
		padding-top: 14px;
		padding-bottom: 14px;
	}

	.gx-page--calc-embed .calc-disclaimer {
		margin-top: clamp(8px, 1.4vh, 14px);
	}
}

/* ---------- hero proof card: 50+ реалізованих проєктів ----------
   The hero's right rail: a compact glass chip that sits right above the case
   slider (same right edge). Number counts up once (initHeroProof, home.js).
   Mobile: a slim full-width strip in the free zone between the content block
   and the ticker. Entrance runs on the hero intro timeline. */
.hero-proof {
	z-index: 6;
	display: inline-flex;
	align-items: center;
	gap: 14px;
	padding: 13px 18px;
	border: 1px solid var(--white-24);
	border-radius: var(--radius-md);
	background: rgba(12, 17, 24, .38);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	color: var(--white);
	text-decoration: none;
	transition: transform .4s var(--ease), border-color .4s var(--ease), background-color .4s var(--ease);
}

.hero-proof:hover {
	transform: translateY(-3px);
	border-color: rgba(43, 162, 74, .5);
	background: rgba(12, 17, 24, .5);
}

.hero-proof__num {
	display: flex;
	align-items: baseline;
	font: 700 30px/1 var(--font-sans);
	font-variant-numeric: tabular-nums;
	letter-spacing: -.02em;
}

.hero-proof__num i {
	font-style: normal;
	font-size: 19px;
	color: var(--green);
	margin-left: 2px;
}

.hero-proof__label {
	font: 500 13px/1.3 var(--font-sans);
	color: var(--white-85);
	max-width: 12ch;
	padding-left: 14px;
	border-left: 1px solid var(--white-24);
}

.hero-proof__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	flex: none;
	border-radius: 50%;
	border: 1px solid var(--white-24);
	color: var(--white);
	transition: background-color .4s var(--ease), border-color .4s var(--ease);
}

.hero-proof:hover .hero-proof__arrow {
	background: var(--green-cta);
	border-color: var(--green-cta);
}

@media (max-width: 768px) {
	/* the free band between the content block (140px bottom margin) and the ticker */
	.hero-proof {
		position: absolute;
		left: 22px;
		right: 22px;
		bottom: 62px;
		padding: 11px 14px;
		gap: 12px;
	}

	.hero-proof__num { font-size: 26px; }
	.hero-proof__num i { font-size: 17px; }
	.hero-proof__label { max-width: none; padding-left: 12px; }
	.hero-proof__arrow { margin-left: auto; width: 30px; height: 30px; }
}
