/* ==========================================================================
   components.css — the visual vocabulary of the template, rebuilt
   --------------------------------------------------------------------------
   Every component below exists because a template page uses it. Geometry
   (heights, paddings, ratios, easing curves) is copied from
   `_source/assets/css/master.css` so the screenshots compare; selectors are
   new, because the template's CSS carries 1313 classes of which we need ~180,
   and half of its rules exist only to support variants no page uses.

   Naming: one block per component, `block__element--modifier`. The template's
   own class names are NOT reused as-is (`hoverbox-6`, `button-circle-white-2`)
   because they are positional legacy names that say nothing about intent and
   would make the next person guess which of six "hover styles" this is.
   ========================================================================== */

/* ==========================================================================
   1. Site chrome
   ========================================================================== */

.site-clip {
	/* Replaces the template's `body { overflow-x: hidden }`, which would break
	   position: sticky. The marquee and the slider overhang live inside here. */
	overflow-x: clip;
}

.header {
	position: sticky;
	top: 0;
	z-index: 993;
	height: var(--header-h);
	background: var(--surface);
	transition: transform 0.28s var(--ease-out), background-color var(--t) linear,
		box-shadow var(--t) linear;
}

/* Auto-hide: the template adds `.hide` past 210px of downward scroll and
   removes it on any upward scroll. Only the transform changes, so the bar
   never reflows. */
.header.is-hidden {
	transform: translateY(-100%);
}

.header:not(.header--float) {
	border-bottom: 1px solid var(--line);
}

.header.is-stuck:not(.header--float) {
	box-shadow: 0 6px 24px -18px rgba(22, 25, 28, 0.5);
}

.header__inner {
	display: flex;
	align-items: center;
	gap: 1.5rem;
	height: 100%;
}

.brand {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	color: var(--ink);
	text-decoration: none;
	/* The template's logo is a text wordmark at 54px; ours is a mark + word so
	   it survives at 320px wide. */
	height: 54px;
}

.brand:hover {
	color: var(--ink);
}

.brand__mark {
	display: block;
	width: auto;
	height: 38px;
	flex: 0 0 auto;
	/* The mark is a raster crop with a white ground. `multiply` drops the white
	   against the header's translucent backdrop without needing a second
	   transparent export, and it is a no-op on the artwork itself. */
	mix-blend-mode: multiply;
}

.brand__text {
	display: flex;
	flex-direction: column;
	line-height: 1.05;
}

.brand__name {
	font-family: var(--font-serif);
	font-size: 1.35rem;
	font-weight: 700;
	letter-spacing: 0.02em;
}

.brand__tag {
	font-size: 0.625rem;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--ink-3);
}

/* ---- Primary nav ------------------------------------------------------
   Desktop is a horizontal bar with CSS-only dropdowns: opening on hover AND
   on keyboard focus. The template injects a toggle <a> with JS and only then
   can a dropdown be opened — meaning with JS off (or on a keyboard) five of
   the six nav items do nothing. */
.nav {
	display: none;
	margin: 0;
	padding: 0;
	list-style: none;
}

.nav__item {
	position: relative;
}

.nav__link {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	padding: 0.5rem 0.9rem;
	color: var(--ink);
	font-size: 0.9375rem;
	font-weight: 500;
	text-decoration: none;
	white-space: nowrap;
	transition: color var(--t-fast) var(--ease-out);
}

.nav__link:hover,
.nav__link[aria-current="page"] {
	color: var(--brand);
}

/* A caret drawn with borders, not an icon font. */
.nav__link--parent::after {
	content: "";
	width: 5px;
	height: 5px;
	margin-top: -3px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg);
	transition: transform var(--t-fast) var(--ease-out);
}

.nav__item:hover .nav__link--parent::after,
.nav__item:focus-within .nav__link--parent::after {
	transform: rotate(225deg);
}

.nav__sub {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 5;
	margin: 0;
	padding: 0.75rem 0;
	list-style: none;
	min-width: 240px;
	background: var(--surface);
	border-radius: var(--r);
	box-shadow: var(--shadow-card);
	/* Hidden by opacity+visibility rather than `display: none` so the
	   transition can run; visibility keeps it out of the tab order when
	   closed, which `opacity: 0` alone would not do. */
	opacity: 0;
	visibility: hidden;
	transform: translateY(10px);
	transition: opacity var(--t) var(--ease-out), transform var(--t) var(--ease-out),
		visibility 0s linear var(--t);
}

.nav__item:hover > .nav__sub,
.nav__item:focus-within > .nav__sub {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
	transition-delay: 0s, 0s, 0s;
}

.nav__sub a {
	display: block;
	padding: 0.5rem 1.5rem;
	color: var(--ink-2);
	font-size: 0.875rem;
	text-decoration: none;
	transition: background-color var(--t-fast) var(--ease-out),
		color var(--t-fast) var(--ease-out);
}

.nav__sub a:hover {
	background: var(--surface-3);
	color: var(--ink);
}

.header__aside {
	display: none;
	align-items: center;
	gap: 0.75rem;
	margin-left: auto;
}

.icon-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	color: var(--ink-2);
	border-radius: 50%;
	transition: background-color var(--t-fast) var(--ease-out),
		color var(--t-fast) var(--ease-out);
}

.icon-link:hover {
	background: var(--surface-3);
	color: var(--ink);
}

.icon-link svg {
	width: 18px;
	height: 18px;
}

/* Language switch: two plain labels, the inactive one muted. Not a <select>:
   it is a two-way toggle, and a select would add a form control to every
   page for one bit of state. */
.lang {
	display: inline-flex;
	align-items: center;
	font-size: 0.8125rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.lang a,
.lang span {
	padding: 0.35rem 0.5rem;
	color: var(--ink-3);
	text-decoration: none;
}

.lang [aria-current="true"] {
	color: var(--ink);
	font-weight: 600;
}

.lang a:hover {
	color: var(--brand);
}

/* CTA button in the header, matching the template's `.button` in the bar. */
.header__cta {
	display: none;
}

/* ---- Mobile drawer ---------------------------------------------------- */
.nav-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin-left: auto;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	color: var(--ink);
}

/* Three rules that become an X. Same 2px weight as the template's
   `.header-toggle span`. */
.nav-toggle__box {
	position: relative;
	display: block;
	width: 26px;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	transition: background-color 0.1s linear;
}

.nav-toggle__box::before,
.nav-toggle__box::after {
	content: "";
	position: absolute;
	left: 0;
	width: 100%;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	transition: transform 0.2s var(--ease-out), top 0.2s var(--ease-out);
}

.nav-toggle__box::before { top: -7px; }
.nav-toggle__box::after { top: 7px; }

.nav-toggle[aria-expanded="true"] .nav-toggle__box {
	background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__box::before {
	top: 0;
	transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__box::after {
	top: 0;
	transform: rotate(-45deg);
}

.drawer {
	position: fixed;
	inset: var(--header-h) 0 0;
	z-index: 992;
	display: flex;
	flex-direction: column;
	padding: 1rem var(--gutter) 2rem;
	background: var(--surface);
	overflow-y: auto;
	overscroll-behavior: contain;
	transform: translateX(100%);
	visibility: hidden;
	transition: transform 0.26s var(--ease-out), visibility 0s linear 0.26s;
}

.drawer.is-open {
	transform: translateX(0);
	visibility: visible;
	transition-delay: 0s, 0s;
}

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

.drawer > ul > li {
	border-bottom: 1px solid var(--line);
}

.drawer a {
	display: block;
	padding: 1rem 0;
	color: var(--ink);
	font-size: 1.0625rem;
	text-decoration: none;
}

.drawer .drawer__sub {
	padding-left: 1rem;
	border-bottom: 0;
}

.drawer .drawer__sub a {
	padding: 0.6rem 0;
	font-size: 0.9375rem;
	color: var(--ink-2);
}

/* The parent row is a <summary>, so the submenu opens with zero JS. */
.drawer summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 1rem 0;
	cursor: pointer;
	font-size: 1.0625rem;
	list-style: none;
}

.drawer summary::-webkit-details-marker {
	display: none;
}

.drawer summary::after {
	content: "";
	width: 8px;
	height: 8px;
	border-right: 2px solid var(--ink-3);
	border-bottom: 2px solid var(--ink-3);
	transform: rotate(45deg);
	transition: transform var(--t) var(--ease-out);
}

.drawer details[open] > summary::after {
	transform: rotate(225deg);
}

.drawer__foot {
	margin-top: auto;
	padding-top: 2rem;
	display: grid;
	gap: 1rem;
}

/* ---- Desktop breakpoint ------------------------------------------------ */
@media (min-width: 992px) {
	.nav { display: flex; }
	.header__aside { display: flex; }
	.nav-toggle { display: none; }
	.drawer { display: none; }
	.header__cta { display: inline-flex; }
}

/* ==========================================================================
   2. Buttons
   ========================================================================== */

.btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 14px 34px;
	border: 1px solid transparent;
	border-radius: var(--r-pill);
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--t) var(--ease-out), color var(--t) var(--ease-out),
		border-color var(--t) var(--ease-out), transform var(--t) var(--ease-out),
		box-shadow var(--t) var(--ease-out);
}

.btn--lg { padding: 16px 42px; font-size: 0.9375rem; }
.btn--sm { padding: 10px 22px; font-size: 0.8125rem; }
.btn--square { border-radius: var(--r-sm); }

/* The signature CTA. White text on the mid-gradient stops is 4.6:1 at the
   purple end and 3.4:1 at the orange end, so the text is given a subtle inner
   shadow rather than relying on the gradient alone. */
.btn--grad {
	background-image: var(--grad);
	color: #fff;
	border-color: transparent;
	/* A gradient can't transition, so the hover state swaps the position of a
	   larger gradient instead — the colour slides rather than fades. */
	background-size: 160% 100%;
	background-position: 0% 50%;
}

.btn--grad:hover {
	background-position: 100% 50%;
	color: #fff;
	transform: translateY(-2px);
	box-shadow: 0 12px 28px -12px rgba(131, 58, 180, 0.55);
}

.btn--solid {
	background: var(--ink);
	color: #fff;
	border-color: var(--ink);
}

.btn--solid:hover {
	background: #000;
	color: #fff;
	transform: translateY(-2px);
}

.btn--line {
	background: transparent;
	color: var(--ink);
	border-color: var(--ink);
}

.btn--line:hover {
	background: var(--ink);
	color: #fff;
}

.btn--ghost {
	background: transparent;
	color: var(--ink);
	border-color: var(--line-strong);
}

.btn--ghost:hover {
	border-color: var(--ink);
	color: var(--ink);
}

/* The ripple ring around the play button in the video CTA. Two rings, offset,
   so it reads as an echo rather than a single pulse. */
.btn-circle {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	height: 64px;
	border-radius: 50%;
	background: #fff;
	color: var(--ink);
	text-decoration: none;
	transition: transform var(--t) var(--ease-out), background-color var(--t) var(--ease-out);
}

.btn-circle svg { width: 22px; height: 22px; }

.btn-circle--xl { width: 88px; height: 88px; }

.btn-circle:hover {
	transform: scale(0.94);
	color: var(--ink);
}

.btn-circle--ripple::before,
.btn-circle--ripple::after {
	content: "";
	position: absolute;
	inset: -10px;
	border: 1px solid rgba(255, 255, 255, 0.55);
	border-radius: 50%;
	animation: ripple 3s var(--ease-out) infinite;
	pointer-events: none;
}

.btn-circle--ripple::after {
	animation-delay: 1.5s;
}

@keyframes ripple {
	0% { transform: scale(0.9); opacity: 0.8; }
	100% { transform: scale(1.45); opacity: 0; }
}

/* "Read more" style text link with a sliding underline. */
.link-arrow {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	color: var(--ink);
	font-weight: 600;
	font-size: 0.875rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
}

.link-arrow svg {
	width: 16px;
	height: 16px;
	transition: transform var(--t) var(--ease-out);
}

.link-arrow:hover {
	color: var(--brand);
}

.link-arrow:hover svg {
	transform: translateX(4px);
}

/* ==========================================================================
   3. Section headers (the template's recurring eyebrow + title pattern)
   ========================================================================== */

.eyebrow {
	display: inline-block;
	margin: 0 0 0.9rem;
	padding: 0.5rem 1rem;
	background: var(--surface-3);
	border-radius: var(--r-pill);
	font-size: var(--fs-h6);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

/* The gradient text from the template's `.text-gradient-1`. `background-clip:
   text` needs the -webkit- prefix in every engine that matters. The fallback
   colour is the middle stop so a browser that ignores the clip still shows
   legible text instead of transparent-on-white. */
.grad-text {
	color: #C0392B;
	background-image: var(--grad);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

@supports not (background-clip: text) {
	.grad-text {
		background: none;
		-webkit-text-fill-color: currentColor;
	}
}

.section-head {
	max-width: 760px;
}

.section-head--center {
	margin: 0 auto;
	text-align: center;
}

.section-title {
	margin: 0;
	font-family: var(--font-serif);
	font-style: italic;
	font-weight: 600;
	font-size: var(--fs-h2);
	line-height: var(--lh-tight);
}

.section-sub {
	margin: 1rem 0 0;
	color: var(--ink-2);
}

/* ==========================================================================
   4. Hero (home)
   ========================================================================== */

/* The template's hero is NOT full-bleed: it is a grey rounded card inset from
   the viewport edges (`mx-4 mx-lg-5`). That inset is the most distinctive
   thing about the top of the page, so it is preserved exactly. */
.hero {
	margin: 0 1rem;
	padding: var(--s-xs) 1.25rem;
	overflow: hidden;
	background: var(--surface-3);
	border-radius: var(--r-lg);
}

.hero__grid {
	display: grid;
	gap: 2.5rem;
	align-items: center;
}

.hero__kicker {
	margin: 0 0 0.75rem;
	font-family: var(--font-serif);
	font-size: 1.25rem;
	color: var(--ink-2);
}

.hero__title {
	margin: 0 0 1.75rem;
	font-family: var(--font-serif);
	font-size: clamp(2rem, 4.4vw, 3.4rem);
	font-weight: 600;
	line-height: 1.14;
}

/* The floating object.
   ---------------------------------------------------------------------------
   The first build used a full-bleed photograph here and rotated it, which is
   what made the top of the page look broken: a photo rotated 20° spills out of
   its card and reads as an alignment bug rather than as motion.

   The template does not rotate a photo — it rotates a CUT-OUT, so the object
   paints outside the card over the page background and reads as something
   floating in front of the page. That is the effect reproduced here:
   the cut-out is allowed to overflow, the card clips only its own background,
   and a soft contact shadow sits underneath it.
   --------------------------------------------------------------------------- */
.hero__media {
	position: relative;
	/* Pull the object toward the card edge on small screens so it does not sit
	   in the middle with dead space either side of it. */
	margin: -0.5rem -0.75rem 0;
}

.hero__object {
	position: relative;
	z-index: 1;
	display: block;
	width: 100%;
	height: auto;
	/* Rotation is driven by JS through a custom property so the transform lives
	   in one declaration; under reduced motion the property never changes and
	   the object simply sits still. */
	transform: rotate(calc(var(--rot, 0) * 1deg));
	transform-origin: 50% 55%;
	will-change: transform;
	filter: drop-shadow(0 26px 34px rgba(18, 21, 24, 0.18));
}

/* A soft radial wash behind the object: the cut-out already carries a baked
   contact shadow, but on a flat grey card that shadow reads as a smudge. The
   wash gives it something to fall on and makes the object feel lit from above. */
.hero__media::before {
	content: "";
	position: absolute;
	inset: 8% -6% -4%;
	background: radial-gradient(
		60% 55% at 52% 62%,
		rgba(0, 96, 192, 0.13) 0%,
		rgba(0, 96, 192, 0.04) 45%,
		transparent 72%
	);
	pointer-events: none;
}

.hero__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1.5rem;
	margin-top: 1.75rem;
	padding-top: 1.25rem;
	border-top: 1px solid rgba(18, 21, 24, 0.12);
	color: var(--ink-2);
	font-size: var(--fs-xs);
}

.hero__meta span {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
}

.hero__meta svg {
	width: 15px;
	height: 15px;
	color: var(--brand);
}

@media (min-width: 992px) {
	.hero {
		margin: 0 2.5rem;
		padding: var(--s) 2.5rem;
	}

	.hero__grid {
		grid-template-columns: 5fr 7fr;
		gap: 3.5rem;
	}

	/* Text left, object right — the template flips DOM order with `order-lg-*`
	   so the h1 precedes the image in the source (better for screen readers). */
	.hero__text { order: 1; }
	.hero__media { order: 2; }

	/* The cut-out is allowed to break the card on the right and at the bottom.
	   That overflow is the whole point: an object that stays politely inside its
	   box is an illustration, while one that crosses the frame reads as floating
	   in front of the page. The card's own background stays inside its radius
	   because the background is painted by `.hero` and the overflow is the img. */
	.hero {
		overflow: visible;
	}

	.hero__media {
		margin: -2rem -2rem -2rem 0;
		/* Keep the object off the text column. It may break the CARD (that is
		   the floating effect) but it must not reach the headline: measured on
		   the rendered page, the artwork's left edge was landing at x=80 —
		   inside the text area at 1440. Clipping the media box instead of
		   shrinking the object keeps the object large and the words legible. */
		padding-left: 4rem;
		overflow: visible;
	}

	.hero__object {
		/* Slightly larger than the column so the right edge exits the card. */
		width: 104%;
		max-width: none;
		margin-left: auto;
		display: block;
	}
}

/* ==========================================================================
   5. Client strip
   ========================================================================== */

/* The template puts the logo carousel in a white card that overlaps the hero
   above it (`n-margin-3`). Ours sits in normal flow: the overlap needed a
   magic negative margin that broke at three of the five breakpoints. */
.clients {
	padding: 2.5rem 0;
}

.clients__card {
	padding: 2rem;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-card);
}

.clients__track {
	display: flex;
	gap: 2.5rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.clients__track::-webkit-scrollbar {
	display: none;
}

.clients__item {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 120px;
	min-height: 44px;
	scroll-snap-align: start;
	color: var(--ink-3);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* ==========================================================================
   6. Cards (services / features)
   ========================================================================== */

.card-grid {
	display: grid;
	gap: 1.5rem;
}

@media (min-width: 768px) {
	.card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.card-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 992px) {
	.card-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.card {
	padding: 2.25rem;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r);
	transition: transform var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out),
		border-color var(--t) var(--ease-out);
}

/* Template: `.hover-shadow.hover-float` — lift 4px + shadow. */
.card:hover {
	transform: translateY(-4px);
	box-shadow: var(--shadow-float);
	border-color: transparent;
}

.card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 70px;
	height: 70px;
	margin-bottom: 1.25rem;
	border-radius: 50%;
	background: var(--surface-3);
}

.card__icon svg {
	width: 28px;
	height: 28px;
	color: var(--brand);
}

.card__title {
	margin: 0 0 0.5rem;
	font-family: var(--font-serif);
	font-size: 1.25rem;
	font-weight: 600;
}

.card__body {
	margin: 0;
	color: var(--ink-2);
	font-size: var(--fs-sm);
}

/* The service cards on /services/ are centred with the icon above the text,
   the ones on the home page are left-aligned. Same component, modifier. */
.card--center {
	text-align: center;
}

/* ==========================================================================
   7. Marquee (the template's scrolling headline)
   ========================================================================== */

/* The template's `#scrollingText` is a 500vw absolutely-positioned element
   driven by two GSAP timelines. Ours is one duplicated track driven by a CSS
   animation, which costs no JS and no layout thrash. */
.marquee {
	overflow: hidden;
	padding: 1rem 0;
	/* The duplicated content means the track is 200% wide; clipping at the
	   section keeps it from creating a horizontal scrollbar. */
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.marquee__track {
	display: flex;
	width: max-content;
	animation: marquee 40s linear infinite;
}

.marquee__group {
	display: flex;
	flex-shrink: 0;
	align-items: center;
	gap: 3rem;
	padding-right: 3rem;
}

.marquee__text {
	font-family: var(--font-serif);
	font-style: italic;
	font-size: clamp(2rem, 6vw, 4.5rem);
	font-weight: 600;
	line-height: 1;
	white-space: nowrap;
	text-transform: capitalize;
}

.marquee__dot {
	width: 10px;
	height: 10px;
	flex: 0 0 auto;
	border-radius: 50%;
	background: var(--surface-3);
}

@keyframes marquee {
	from { transform: translateX(0); }
	to { transform: translateX(-50%); }
}

/* ==========================================================================
   8. Portfolio
   ========================================================================== */

/* Horizontal slider. Scroll-snap instead of Swiper: native touch inertia,
   keyboard scrollable, and it degrades to a plain scroller when JS is off.
   The template shows 1 card then 2 from 768px, centred, with 30–50px gaps. */
.slider {
	position: relative;
}

.slider__track {
	display: flex;
	gap: 1.875rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-ms-overflow-style: none;
	padding-bottom: 0.5rem;
}

.slider__track::-webkit-scrollbar {
	display: none;
}

.slider__item {
	flex: 0 0 100%;
	scroll-snap-align: center;
}

@media (min-width: 768px) {
	.slider__item { flex-basis: calc(50% - 0.9375rem); }
	.slider__track { gap: 1.875rem; }
}

@media (min-width: 1200px) {
	.slider__track { gap: 3.125rem; }
}

.slider__nav {
	display: flex;
	justify-content: center;
	align-items: center;
	gap: 0.5rem;
	margin-top: 0.75rem;
}

/* The dot is 9px of ink inside a 40px button: the visual is the template's, the
   target is the accessibility floor. A 9px button (which is what the template
   shipped) is impossible to hit with a thumb. */
.slider__dot {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	background: transparent;
	cursor: pointer;
}

.slider__dot::before {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 50%;
	background: var(--line-strong);
	transition: background-color var(--t-fast) var(--ease-out),
		transform var(--t-fast) var(--ease-out);
}

.slider__dot[aria-current="true"]::before {
	background: var(--ink);
	transform: scale(1.35);
}

/* The work card: square-ish image, dark caption sliding in from the left on
   hover (template: `.hero-portfolio-caption`, `left: -50px → 0`). On touch
   there is no hover, so the caption is always visible below 992px. */
.work {
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: var(--r);
	color: #fff;
	text-decoration: none;
	background: var(--surface-dark);
}

.work img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	transition: transform var(--t-slow) var(--ease-scale);
}

.work:hover img {
	transform: scale(1.04);
}

.work__caption {
	position: absolute;
	left: 1rem;
	bottom: 1rem;
	right: 1rem;
	padding: 1.25rem 1.5rem;
	background: rgba(18, 21, 24, 0.9);
	border-radius: var(--r-sm);
	transition: transform var(--t) var(--ease-out), opacity var(--t) var(--ease-out);
}

.work__title {
	margin: 0;
	font-family: var(--font-serif);
	font-size: 1.25rem;
	font-weight: 600;
	color: #fff;
}

.work__tag {
	display: block;
	margin-top: 0.25rem;
	color: rgba(255, 255, 255, 0.75);
	font-size: var(--fs-xs);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

@media (min-width: 992px) {
	.work img { aspect-ratio: 630 / 787; }

	.work__caption {
		top: 50%;
		bottom: auto;
		right: auto;
		max-width: 70%;
		padding: 1.5rem 2rem;
		opacity: 0;
		transform: translate(-50%, -50%);
		left: 50%;
	}

	.work:hover .work__caption,
	.work:focus-visible .work__caption {
		opacity: 1;
	}
}

/* ---- Filterable grid --------------------------------------------------
   The template uses Isotope (jQuery, 250ms). Ours hides non-matching items
   with `display: none` and lets CSS grid close the gap instantly — the
   "animation" the template buys 233 KB of JS for is a 250ms reflow that
   nobody can see on a 15-item grid. */
.filter {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.5rem 1.5rem;
	margin: 0 0 2.5rem;
	padding: 0;
	list-style: none;
}

.filter__btn {
	padding: 0.35rem 0;
	background: none;
	border: 0;
	border-bottom: 2px solid transparent;
	color: var(--ink-3);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	cursor: pointer;
	transition: color var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}

.filter__btn:hover {
	color: var(--ink);
}

.filter__btn[aria-pressed="true"] {
	color: var(--ink);
	border-bottom-color: var(--ink);
}

/* ==========================================================================
   9. Team
   ========================================================================== */

.team {
	display: grid;
	gap: 2rem;
}

@media (min-width: 576px) {
	.team { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 992px) {
	.team { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.5rem; }
}

.member__media {
	position: relative;
	overflow: hidden;
	margin-bottom: 1.25rem;
	border-radius: var(--r);
	background: var(--surface-3);
}

.member__media img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	transition: transform var(--t-slow) var(--ease-scale), filter var(--t-slow) var(--ease-scale);
}

/* Template: hover scales 1.04 AND blurs 1.5px, with a 40% dark veil and the
   social row scaling up from 96%. */
.member__media:hover img,
.member__media:focus-within img {
	transform: scale(1.04);
	filter: blur(1.5px);
}

.member__social {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
	background: rgba(18, 21, 24, 0.4);
	opacity: 0;
	transition: opacity var(--t-fast) var(--ease-out);
}

.member__social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
	transform: scale(0.96);
	transition: transform var(--t-fast) var(--ease-out), background-color var(--t-fast) var(--ease-out);
}

.member__social a:hover {
	background: #fff;
	color: var(--ink);
}

.member__media:hover .member__social,
.member__media:focus-within .member__social {
	opacity: 1;
}

.member__media:hover .member__social a,
.member__media:focus-within .member__social a {
	transform: scale(1);
}

.member__name {
	margin: 0 0 0.15rem;
	font-family: var(--font-serif);
	font-size: 1.125rem;
	font-weight: 600;
}

.member__role {
	margin: 0;
	color: var(--brand);
	font-size: var(--fs-xs);
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/* ==========================================================================
   10. Stats band
   ========================================================================== */

/* Full-bleed photo + dark veil + four counters. The veil is what makes white
   numerals readable over an unknown photo; --veil-6 is the template's 60%. */
.band {
	position: relative;
	isolation: isolate;
	padding: var(--s-lg) 0;
	color: #fff;
	background: var(--surface-dark);
	overflow: hidden;
}

.band img {
	position: absolute;
	inset: 0;
	z-index: -2;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.band::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: var(--veil-6);
}

.band__grid {
	display: grid;
	gap: 2.5rem;
}

@media (min-width: 768px) {
	.band__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2rem; }
}

.stat__value {
	margin: 0;
	font-size: clamp(2.25rem, 4vw, 3.25rem);
	font-weight: 700;
	line-height: 1;
	color: #fff;
	font-variant-numeric: tabular-nums;
}

.stat__label {
	margin: 0.5rem 0 0;
	font-size: var(--fs-xs);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.82);
}

.stat__note {
	margin: 0.5rem 0 0;
	font-size: var(--fs-xs);
	color: rgba(255, 255, 255, 0.68);
	line-height: 1.6;
}

/* ==========================================================================
   11. Testimonials
   ========================================================================== */

/* Template: `.testimonial-box` max-width 730px, centred, quote then avatar. */
.quote {
	max-width: 730px;
	margin: 0 auto;
	text-align: center;
}

.quote__stars {
	display: flex;
	justify-content: center;
	gap: 0.2rem;
	margin-bottom: 1.25rem;
	color: #F0A500;
}

.quote__stars svg {
	width: 16px;
	height: 16px;
}

.quote__text {
	margin: 0 0 1.75rem;
	font-family: var(--font-serif);
	font-size: clamp(1.1rem, 1.8vw, 1.45rem);
	line-height: 1.65;
	color: var(--ink);
}

.quote__person {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.9rem;
}

.quote__avatar {
	width: 56px;
	height: 56px;
	border-radius: 50%;
	object-fit: cover;
}

.quote__name {
	margin: 0;
	font-weight: 600;
	font-size: var(--fs-sm);
}

.quote__role {
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-xs);
}

/* ==========================================================================
   12. Pricing
   ========================================================================== */

.price-grid {
	display: grid;
	gap: 1.5rem;
}

@media (min-width: 768px) {
	.price-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: center; }
}

.price {
	position: relative;
	padding: 2.5rem 2rem;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r);
	text-align: center;
	transition: transform var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out);
}

.price:hover {
	transform: translateY(-4px);
	box-shadow: var(--shadow-float);
}

/* The middle plan is raised on desktop (template: `mt-lg-4` stagger). */
@media (min-width: 768px) {
	.price--featured {
		padding-top: 3.25rem;
		padding-bottom: 3.25rem;
		border-color: var(--ink);
		border-width: 2px;
	}
}

.price__tag {
	position: absolute;
	top: -12px;
	left: 50%;
	transform: translateX(-50%);
	padding: 0.25rem 0.9rem;
	background: var(--ink);
	color: #fff;
	border-radius: var(--r-pill);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	white-space: nowrap;
}

.price__name {
	margin: 0 0 1rem;
	font-size: var(--fs-h6);
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ink-2);
}

.price__amount {
	margin: 0;
	font-size: clamp(2rem, 3.4vw, 2.75rem);
	font-weight: 600;
	line-height: 1;
	font-variant-numeric: tabular-nums;
}

.price__period {
	display: block;
	margin-top: 0.35rem;
	color: var(--ink-3);
	font-size: var(--fs-xs);
}

.price__list {
	margin: 1.75rem 0;
	padding: 0;
	list-style: none;
	text-align: left;
}

.price__list li {
	display: flex;
	gap: 0.6rem;
	padding: 0.5rem 0;
	border-bottom: 1px dashed var(--line);
	font-size: var(--fs-sm);
	color: var(--ink-2);
}

.price__list li:last-child {
	border-bottom: 0;
}

.price__list svg {
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	margin-top: 1px;
	color: var(--brand);
}

/* ==========================================================================
   13. Blog
   ========================================================================== */

.posts {
	display: grid;
	gap: 2.5rem 1.5rem;
}

@media (min-width: 768px) {
	.posts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 992px) {
	.posts--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

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

.post__media {
	position: relative;
	display: block;
	overflow: hidden;
	margin-bottom: 1.25rem;
	border-radius: var(--r);
	background: var(--surface-3);
}

.post__media img {
	width: 100%;
	aspect-ratio: 16 / 10;
	object-fit: cover;
	transition: transform var(--t-slow) var(--ease-scale);
}

.post__media:hover img {
	transform: scale(1.04);
}

/* Date chip. The template hardcodes "April 19" on all six cards; here it is
   the real published date, which is also what the JSON-LD claims. */
.post__date {
	position: absolute;
	top: 1rem;
	left: 1rem;
	padding: 0.3rem 0.7rem;
	background: var(--ink);
	color: #fff;
	border-radius: var(--r-sm);
	font-size: 0.6875rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

.post__cat {
	margin: 0 0 0.5rem;
	color: var(--brand);
	font-size: 0.6875rem;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.post__title {
	margin: 0 0 0.6rem;
	font-family: var(--font-serif);
	font-size: 1.25rem;
	font-weight: 600;
	line-height: 1.3;
}

.post__title a {
	color: var(--ink);
	text-decoration: none;
}

.post__title a:hover {
	color: var(--brand);
}

.post__excerpt {
	margin: 0 0 1rem;
	color: var(--ink-2);
	font-size: var(--fs-sm);
}

.post__meta {
	margin-top: auto;
	color: var(--ink-3);
	font-size: var(--fs-xs);
}

/* ---- Sidebar ----------------------------------------------------------
   The template's six sidebar boxes. The Facebook Like box is replaced by a
   newsletter box: a third-party iframe in the sidebar of a Chinese-hosted
   site either fails to load or leaks a request to a blocked domain. */
.sidebar {
	display: grid;
	gap: 1.5rem;
}

.widget {
	padding: 1.75rem;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r);
}

.widget__title {
	margin: 0 0 1.25rem;
	font-size: var(--fs-h6);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--ink);
}

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

.widget li {
	border-bottom: 1px solid var(--line);
}

.widget li:last-child {
	border-bottom: 0;
}

.widget li a {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.6rem 0;
	color: var(--ink-2);
	font-size: var(--fs-sm);
	text-decoration: none;
}

.widget li a:hover {
	color: var(--brand);
}

.widget__count {
	color: var(--ink-3);
	font-variant-numeric: tabular-nums;
}

.widget--about {
	text-align: center;
}

.widget--about img {
	width: 84px;
	height: 84px;
	margin: 0 auto 1rem;
	border-radius: 50%;
	object-fit: cover;
}

.widget--newsletter p {
	color: var(--ink-2);
	font-size: var(--fs-sm);
}

/* ---- Article ---------------------------------------------------------- */
.article {
	max-width: 760px;
}

.article__head {
	margin-bottom: 2rem;
}

.article__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.25rem;
	margin-bottom: 1rem;
	color: var(--ink-3);
	font-size: var(--fs-xs);
	letter-spacing: 0.04em;
}

/* CJK body copy: 1.85 leading and a slightly larger size, because Chinese
   has no word spaces and the template's 1.75 leaves paragraphs looking like
   walls. `word-break: break-word` prevents a long URL from overflowing. */
.prose {
	color: var(--ink-2);
	font-size: 1.0625rem;
	line-height: 1.85;
	overflow-wrap: break-word;
}

.prose h2 {
	margin: 2.5rem 0 1rem;
	font-family: var(--font-serif);
	font-size: 1.6rem;
	color: var(--ink);
}

.prose h3 {
	margin: 2rem 0 0.75rem;
	font-size: 1.25rem;
	color: var(--ink);
}

.prose ul,
.prose ol {
	padding-left: 1.4em;
}

.prose li {
	margin-bottom: 0.5rem;
}

.prose blockquote {
	margin: 2rem 0;
	padding-left: 1.25rem;
	border-left: 3px solid var(--ink);
	color: var(--ink);
}

.prose img {
	margin: 2rem 0;
	border-radius: var(--r);
}

.prose code {
	padding: 0.15em 0.4em;
	background: var(--surface-3);
	border-radius: 4px;
	font-family: var(--font-mono);
	font-size: 0.9em;
}

.prose a {
	text-decoration: underline;
}

/* ==========================================================================
   14. Contact form
   ========================================================================== */

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

.form__row {
	display: grid;
	gap: 1rem;
}

@media (min-width: 576px) {
	.form__row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.field {
	display: grid;
	gap: 0.4rem;
}

.field__label {
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--ink-2);
}

.field__control {
	width: 100%;
	padding: 0.95rem 1.1rem;
	background: var(--surface);
	border: 1px solid var(--line-strong);
	border-radius: var(--r-sm);
	font-size: var(--fs-sm);
	transition: border-color var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}

.field__control::placeholder {
	color: #9AA3AE;
}

.field__control:hover {
	border-color: var(--ink-3);
}

.field__control:focus {
	outline: 0;
	border-color: var(--ink);
	box-shadow: 0 0 0 3px rgba(11, 74, 143, 0.15);
}

textarea.field__control {
	min-height: 150px;
	resize: vertical;
}

.field__hint {
	color: var(--ink-3);
	font-size: var(--fs-xs);
}

/* Error state is driven by `aria-invalid`, which the server renders and JS
   updates — so the red border is never the only signal. */
.field__control[aria-invalid="true"] {
	border-color: #C0392B;
	box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.12);
}

.field__error {
	display: none;
	color: #A5311F;
	font-size: var(--fs-xs);
	font-weight: 600;
}

.field__control[aria-invalid="true"] ~ .field__error {
	display: block;
}

/* The error summary at the top of the form: focusable, links to the field. */
.form__summary {
	padding: 1rem 1.25rem;
	background: #FBEAE7;
	border: 1px solid #E9B7AE;
	border-radius: var(--r-sm);
	color: #7E2416;
	font-size: var(--fs-sm);
}

.form__summary:focus {
	outline: 2px solid #7E2416;
	outline-offset: 2px;
}

.form__summary ul {
	margin: 0.5rem 0 0;
	padding-left: 1.2em;
}

.form__summary a {
	color: #7E2416;
}

.form__note {
	margin: 0;
	color: var(--ink-3);
	font-size: var(--fs-xs);
}

/* Success banner, also used as the generic notice. */
.notice {
	padding: 1rem 1.25rem;
	border-radius: var(--r-sm);
	font-size: var(--fs-sm);
}

.notice--ok {
	background: #E8F5EC;
	border: 1px solid #A9D6B8;
	color: #1D5B33;
}

.notice--warn {
	background: #FFF6E5;
	border: 1px solid #EBCE93;
	color: #6B4A0B;
}

.contact-aside {
	display: grid;
	gap: 1.75rem;
	align-content: start;
}

.contact-aside__item h6 {
	margin: 0 0 0.35rem;
	color: var(--ink);
}

.contact-aside__item p {
	margin: 0;
	color: var(--ink-2);
	font-size: var(--fs-sm);
}

/* ==========================================================================
   15. CTA band (parallax video section)
   ========================================================================== */

.cta-band {
	position: relative;
	isolation: isolate;
	display: grid;
	place-items: center;
	min-height: 320px;
	padding: var(--s-2xl) 0;
	color: #fff;
	background: var(--surface-dark);
	overflow: hidden;
	text-align: center;
}

.cta-band img {
	position: absolute;
	inset: 0;
	z-index: -2;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cta-band::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background: var(--veil-3);
}

.cta-band__label {
	margin: 1.5rem 0 0;
	font-family: var(--font-serif);
	font-size: clamp(1.1rem, 2vw, 1.5rem);
	color: #fff;
}

/* ==========================================================================
   16. Footer
   ========================================================================== */

.footer {
	padding: var(--s-md) 0 0;
	background: var(--surface-dark);
	color: rgba(255, 255, 255, 0.72);
	font-size: var(--fs-sm);
}

.footer a {
	color: rgba(255, 255, 255, 0.72);
	text-decoration: none;
	transition: color var(--t-fast) var(--ease-out);
}

.footer a:hover {
	color: #fff;
}

.footer__grid {
	display: grid;
	gap: 2.5rem;
}

@media (min-width: 768px) {
	.footer__grid { grid-template-columns: 2fr 1fr 1fr 1.2fr; gap: 2rem; }
}

.footer__brand {
	font-family: var(--font-serif);
	font-size: 1.75rem;
	font-weight: 700;
	color: #fff;
	letter-spacing: 0.02em;
}

.footer__desc {
	margin: 1rem 0 1.5rem;
	max-width: 34ch;
	line-height: 1.75;
}

.footer__title {
	margin: 0 0 1.1rem;
	font-size: var(--fs-h6);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: #fff;
}

.footer__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer__list li {
	margin-bottom: 0.65rem;
}

.footer__social {
	display: flex;
	gap: 0.6rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer__social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.08);
	transition: background-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}

.footer__social a:hover {
	background: #fff;
	color: var(--ink);
}

.footer__social svg {
	width: 17px;
	height: 17px;
}

.footer__bar {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem 1.5rem;
	align-items: center;
	justify-content: space-between;
	margin-top: 3rem;
	padding: 1.5rem 0;
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	font-size: var(--fs-xs);
	color: rgba(255, 255, 255, 0.55);
}

.footer__bar a {
	color: rgba(255, 255, 255, 0.55);
}

/* ==========================================================================
   17. Page furniture: scroll-to-top, reading progress, preloader
   ========================================================================== */

.scroll-top {
	position: fixed;
	right: 20px;
	bottom: 20px;
	z-index: 992;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--ink);
	color: #fff;
	box-shadow: var(--shadow-card);
	opacity: 0;
	visibility: hidden;
	transform: translateY(20px);
	transition: opacity var(--t) var(--ease-out), transform var(--t) var(--ease-out),
		visibility 0s linear var(--t), background-color var(--t-fast) var(--ease-out);
}

.scroll-top.is-visible {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
	transition-delay: 0s, 0s, 0s, 0s;
}

.scroll-top:hover {
	background: #000;
	color: #fff;
}

.scroll-top svg {
	width: 22px;
	height: 22px;
}

/* Reading progress. The template puts a 4px bar at the BOTTOM; ours is at the
   top, directly under the header, because the bottom edge is where iOS puts
   its home indicator and the bar was being drawn under it. */
.page-progress {
	position: fixed;
	top: 0;
	left: 0;
	z-index: 994;
	width: 100%;
	height: 3px;
	background: transparent;
	pointer-events: none;
}

.page-progress__bar {
	width: 0;
	height: 100%;
	background-image: var(--grad);
	transform-origin: 0 50%;
	will-change: width;
}

/* Preloader. Not a spinner: a 2px bar that fills, so there is no layout
   inside it to shift and nothing to animate at 60fps on a cheap phone. */
.preloader {
	position: fixed;
	inset: 0;
	z-index: 999;
	display: grid;
	place-items: center;
	background: var(--surface);
	transition: opacity 0.4s var(--ease-out), visibility 0s linear 0.4s;
}

.preloader::after {
	content: "";
	width: 120px;
	height: 2px;
	background: var(--line);
	background-image: linear-gradient(90deg, var(--ink) 0 40%, transparent 40% 100%);
	background-size: 200% 100%;
	animation: preload 1.1s linear infinite;
}

.preloader.is-done {
	opacity: 0;
	visibility: hidden;
}

@keyframes preload {
	from { background-position: 100% 0; }
	to { background-position: -100% 0; }
}

/* ==========================================================================
   18. Lightbox (native <dialog>)
   ========================================================================== */

.lightbox {
	width: min(1100px, 92vw);
	max-height: 92vh;
	padding: 0;
	border: 0;
	border-radius: var(--r);
	background: transparent;
	overflow: visible;
}

.lightbox::backdrop {
	background: rgba(10, 12, 14, 0.86);
}

.lightbox img,
.lightbox iframe {
	display: block;
	width: 100%;
	max-height: 84vh;
	object-fit: contain;
	border-radius: var(--r);
	background: #000;
}

.lightbox iframe {
	aspect-ratio: 16 / 9;
	height: auto;
}

.lightbox__close {
	position: absolute;
	top: -48px;
	right: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 50%;
	background: transparent;
	color: #fff;
	cursor: pointer;
}

.lightbox__close:hover {
	background: #fff;
	color: var(--ink);
}

.lightbox__caption {
	margin-top: 0.75rem;
	color: rgba(255, 255, 255, 0.8);
	font-size: var(--fs-xs);
	text-align: center;
}

/* ==========================================================================
   19. Optional cursor (off by default; see RISKS/PARITY)
   ========================================================================== */

.cursor {
	display: none;
}

@media (hover: hover) and (pointer: fine) {
	.has-custom-cursor .cursor {
		position: fixed;
		top: 0;
		left: 0;
		z-index: 998;
		display: block;
		width: 22px;
		height: 22px;
		margin: -11px 0 0 -11px;
		border: 1.5px solid var(--ink);
		border-radius: 50%;
		pointer-events: none;
		transition: transform 0.12s var(--ease-out), opacity 0.2s linear;
	}

	.has-custom-cursor.is-cursor-grow .cursor {
		transform: scale(1.7);
	}
}
