/* =========================================================================
   RUH — components shared by every page: header, menu, clients list, footer,
   Insights slider, project cursor, ripple, text roll, site cursor.
   ========================================================================= */

/* =========================================================================
   Header — mobile: logo x20 y44 (81×30), icon 36×12 x384 y55
            desktop: icon x64 y45, logo centred y39, CTA right edge 1664 y39
   ========================================================================= */

.site-header {
	position: fixed;
	inset: 0 0 auto 0;
	z-index: 50;
	transition: transform 0.5s var(--ease-out);
}

.site-header__inner {
	position: relative;
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: start;
	max-width: 1920px;
	margin-inline: auto;
	padding: calc(44 * var(--u)) var(--gutter) 0;
	height: var(--header-h);
}

.wordmark { grid-column: 1; grid-row: 1; display: block; width: calc(81 * var(--u)); line-height: 0; }
.wordmark svg { display: block; width: 100%; height: auto; }

.menu-toggle { position: relative; grid-column: 2; grid-row: 1; display: block; margin-top: calc(11 * var(--u)); line-height: 0; }
.menu-toggle::after { content: ""; position: absolute; inset: -14px; } /* 44px touch target */
.menu-toggle__icon { display: block; line-height: 0; }
.menu-toggle__icon svg { display: block; width: 100%; height: auto; }
.menu-toggle__icon--mobile { width: calc(36 * var(--u)); }
.menu-toggle__icon--desktop { display: none; }

.site-header__cta { display: none; }

.site-header.is-hidden { transform: translateY(-100%); }
/* Black pages (body.has-dark-top: Agency, Insights list): white header until it docks. */
.has-dark-top .site-header:not(.is-sticky) { color: var(--white); }

/* Sticky (mobile, frame 1329:144 — the desktop-like one of the three 440 designs):
   square white bar 400×56 floating 20 from the top and sides, content inset 16;
   logo shrinks to 64×24, menu icon 36×12, both centred. (1329:2 = same, pill r85;
   1332:194 = full-width 80 bar from the top.) */
.site-header.is-sticky .site-header__inner {
	align-items: center;
	height: calc(56 * var(--u));
	margin: calc(20 * var(--u)) var(--gutter) 0;
	padding: 0 calc(16 * var(--u));
	background: var(--white);
}
.site-header.is-sticky .wordmark { width: calc(64 * var(--u)); }
.site-header.is-sticky .menu-toggle { margin-top: 0; }

@media (min-width: 1200px) {
	.site-header__inner {
		grid-template-columns: 1fr auto 1fr;
		padding-top: calc(39 * var(--u));
	}
	.menu-toggle { grid-column: 1; justify-self: start; margin-top: calc(4.5 * var(--u)); }
	.menu-toggle__icon--mobile { display: none; }
	.menu-toggle__icon--desktop { display: block; width: calc(64 * var(--u)); }
	.wordmark { grid-column: 2; }
	/* CTA: Neue Haas Display 500 16/24, gap 8, arrow 27w */
	.site-header__cta {
		display: inline-flex;
		grid-column: 3;
		justify-self: end;
		align-items: center;
		gap: calc(8 * var(--u));
		font-family: var(--nhg);
		font-size: calc(16 * var(--u));
		font-weight: var(--nhg-weight);
		line-height: calc(24 / 16);
	}
	.site-header__cta-arrow { display: block; width: calc(29 * var(--u)); line-height: 0; transition: transform 0.4s var(--ease-out); }
	.site-header__cta-arrow svg { display: block; width: 100%; height: auto; }
	@media (hover: hover) { .site-header__cta:hover .site-header__cta-arrow { transform: translateX(6px); } }

	/* Sticky (desktop, frame 1329:118): square white bar, 96 tall at y40, content inset 24.
	   The bar grows outward by that inset (x40 instead of Figma's x65) so the menu icon and
	   the CTA keep their exact x from the top state and never shift when the header docks. */
	.site-header.is-sticky { background: transparent; padding-inline: calc(var(--gutter) - 24 * var(--u)); }
	.site-header.is-sticky .site-header__inner {
		height: calc(96 * var(--u));
		margin: calc(40 * var(--u)) auto 0;
		max-width: calc(1920px - 2 * (var(--gutter) - 24 * var(--u)));
		padding: 0 calc(24 * var(--u));
		background: var(--white);
	}
	.site-header.is-sticky .wordmark { width: calc(81 * var(--u)); }
}

/* =========================================================================
   Menu — mobile (1322:1150): black, logo white, links 48/52 300, pitch 84,
          dividers white 30%, contact bottom 72
          desktop (1051:405): teal panel 910 wide over the page, close x65 y39,
          links 56/64 300 y132 pitch 124, dividers 40% at +92, contact bottom 57
   ========================================================================= */

/* --mu: the design unit, shrunk when the window is shorter than the frame (874 mobile / 1117 desktop, minus the
   logged-in toolbar) — the whole panel keeps Figma's proportions and fits without a scrollbar. Widths stay on --u. */
.menu-overlay { position: fixed; inset: 0; z-index: 60; --mu: min(var(--u), calc((100svh - var(--wp-bar, 0px)) / 874)); }
.menu-overlay[hidden] { display: none; }

.menu-overlay__panel {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	padding-inline: var(--gutter);
	background: var(--black);
	color: var(--white);
	overflow-y: auto;
}

.menu-overlay__top {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	padding-top: calc(44 * var(--mu));
}

.menu-overlay__logo { display: block; width: calc(81 * var(--mu)); line-height: 0; color: var(--white); }
.menu-overlay__logo svg { display: block; width: 100%; height: auto; }

.menu-close { position: relative; display: block; width: calc(28 * var(--mu)); margin-top: calc(1 * var(--mu)); line-height: 0; }
.menu-close::after { content: ""; position: absolute; inset: -8px; }
.menu-close__icon { display: block; width: 100%; line-height: 0; }
.menu-close__icon svg { display: block; width: 100%; height: auto; }
.menu-close__icon--desktop { display: none; }

.menu-overlay__nav { margin-top: calc(93 * var(--mu)); } /* first link y167 */

.menu-overlay__nav li {
	padding-bottom: calc(16 * var(--mu));
	margin-bottom: calc(16 * var(--mu));
	border-bottom: 1px solid rgb(255 255 255 / 0.3);
	overflow: hidden;
}

.menu-overlay__nav a {
	display: flex;
	align-items: center;
	font-size: calc(48 * var(--mu));
	font-weight: 300;
	line-height: calc(52 / 48);
}

.menu-overlay__nav li:first-child a { color: var(--cyan); }
.menu-overlay__arrow { display: none; }

.menu-overlay__contact {
	margin-top: auto;
	padding-top: 40px;
	padding-bottom: calc(72 * var(--mu));
	display: grid;
	gap: calc(1 * var(--mu));
}
.menu-overlay__contact p { font-size: calc(20 * var(--mu)); line-height: calc(28 / 20); color: rgb(255 255 255 / 0.5); }
.menu-overlay__email { font-size: calc(24 * var(--mu)); line-height: calc(30 / 24); }

.menu-overlay__backdrop { display: none; }
.menu-cursor { display: none; }

@media (min-width: 1200px) {
	.menu-overlay { --mu: min(var(--u), calc((100svh - var(--wp-bar, 0px)) / 1117)); }
	.menu-overlay__panel {
		right: auto;
		width: calc(910 * var(--u));
		padding-inline: calc(65 * var(--u)) calc(64 * var(--u));
		background: var(--teal);
		color: var(--black);
	}
	.menu-overlay__top { padding-top: calc(39 * var(--mu)); }
	.menu-overlay__logo { display: none; }
	.menu-close { order: -1; width: calc(28 * var(--mu)); margin-top: 0; }
	.menu-close__icon--mobile { display: none; }
	.menu-close__icon--desktop { display: block; }

	.menu-overlay__nav { margin-top: calc(65 * var(--mu)); } /* close ends y67 → first link y132 */
	.menu-overlay__nav li {
		padding-bottom: calc(28 * var(--mu));
		margin-bottom: calc(32 * var(--mu));
		border-bottom-color: rgb(0 0 0 / 0.4);
	}
	.menu-overlay__nav li:first-child a { color: inherit; }
	.menu-overlay__nav a { font-size: calc(56 * var(--mu)); line-height: calc(64 / 56); }

	/* Hover (design "Specialism"): arrow slides in, label moves 72 → x137 */
	.menu-overlay__arrow {
		display: flex;
		align-items: center;
		width: 0;
		overflow: hidden;
		transition: width 0.45s var(--ease-out);
	}
	.menu-overlay__arrow svg { flex: none; display: block; width: calc(57 * var(--mu)); height: auto; transform: translateY(-0.047em); }
	.menu-overlay__nav a:focus-visible .menu-overlay__arrow { width: calc(72 * var(--mu)); }
	@media (hover: hover) { .menu-overlay__nav a:hover .menu-overlay__arrow { width: calc(72 * var(--mu)); } }

	/* Contact: Neue Haas Display 500 32/45 +2%; "Let's work together" black 50% */
	.menu-overlay__contact { padding-bottom: calc(57 * var(--mu)); gap: 0; }
	.menu-overlay__contact p,
	.menu-overlay__email {
		font-family: var(--nhg);
		font-size: calc(32 * var(--mu));
		font-weight: var(--nhg-weight);
		line-height: calc(45 / 32);
		letter-spacing: 0.02em;
	}
	.menu-overlay__contact p { color: rgb(0 0 0 / 0.5); }

	.menu-overlay__backdrop { display: block; position: absolute; inset: 0 0 0 calc(910 * var(--u)); overflow: hidden; background: var(--white); color: var(--black); cursor: default; }
	/* MENU frame: the RUH روح mark x65 y771 1598×328 (bottom 18), its left half under the panel */
	.menu-overlay__mark { position: absolute; right: calc(65 * var(--u)); bottom: calc(18 * var(--mu)); width: calc(1598 * var(--u)); /* width-based: the panel edge falls between "H" and "روح" as in Figma */ line-height: 0; pointer-events: none; }
	.menu-overlay__mark svg { display: block; width: 100%; height: auto; }
	/* "Get in Touch" x1542 y39, as in the header */
	.menu-overlay__cta { position: absolute; top: calc(39 * var(--mu)); right: calc(65 * var(--u)); color: var(--black); }

	/* Menu cursor: 24px white dot, difference blend (design "Ellipse 1") */
	.menu-cursor {
		display: block;
		position: fixed;
		top: 0;
		left: 0;
		width: 24px;
		height: 24px;
		margin: -12px 0 0 -12px;
		border-radius: 50%;
		background: var(--white);
		mix-blend-mode: difference;
		pointer-events: none;
		opacity: 0;
		transition: opacity 0.2s;
	}
	.menu-overlay.has-pointer .menu-cursor { opacity: 1; }
	.menu-overlay.has-pointer .menu-overlay__panel,
	.menu-overlay.has-pointer .menu-overlay__panel * { cursor: none; }
}

/* =========================================================================
   Insights — mobile: title +60 36/40, cards +32, card 297w gap 12, img r5,
              caption +19 20/28, dots +32 (pill 63×6 teal, dots 6×6 #D9D9D9, gap 3)
              desktop: pad-top 156, desc x741 382w #565656 20/30, nav 20/30 gap 80,
              cards +104 after head, 517w gap 24, r10, caption +18 32/45, pad-bottom 180
   ========================================================================= */

.insights { padding-top: calc(60 * var(--u)); }

.insights__head { margin-bottom: calc(32 * var(--u)); }
.insights__title { font-size: calc(36 * var(--u)); font-weight: 300; line-height: calc(40 / 36); letter-spacing: 0.02em; }
.insights__desc,
.insights__nav { display: none; }

.insights__track {
	display: grid;
	max-width: none; /* WP post-template caps it at 100% — the track bleeds past the column */
	grid-auto-flow: column;
	grid-auto-columns: calc(297 * var(--u));
	gap: calc(12 * var(--u));
	margin: 0 calc(-1 * var(--gutter));
	padding: 0 var(--gutter);
	scroll-padding-inline: var(--gutter);
	overflow-x: auto;
	scroll-snap-type: none; /* free scrolling + momentum drag, as studio-kiln.com (Swiper freeMode, sticky: false) — slider.js */
	scrollbar-width: none;
	overscroll-behavior-x: contain;
	align-items: start;
	list-style: none;
}
.insights__track::-webkit-scrollbar { display: none; }
.insights__track > li { scroll-snap-align: start; margin: 0; }

/* Uneven grid (Figma): each card has its own crop. Mobile 297×305, 400×403 alternating;
   desktop 517 wide, heights 530 / 701 / 638 repeating, tops aligned. */
.insights__track { grid-auto-columns: auto; }
.insights__track > li { width: calc(297 * var(--u)); }
.insights__track > li:nth-child(2n) { width: calc(400 * var(--u)); }
.insight-card__img { position: relative; margin: 0; overflow: hidden; border-radius: calc(5 * var(--u)); aspect-ratio: 297 / 305; }
.insights__track > li:nth-child(2n) .insight-card__img { aspect-ratio: 400 / 403; }
.insight-card__img a { display: block; height: 100%; }
.insight-card__img img,
.insight-card__img video { display: block; width: 100%; height: 100%; object-fit: cover; }
.insight-card__title { margin-top: calc(19 * var(--u)); font-size: calc(20 * var(--u)); line-height: calc(28 / 20); }
.insight-card__title a { color: inherit; text-decoration: none; }
.insights__empty { color: var(--copy-grey); }

.insights__dots {
	display: flex;
	justify-content: center;
	gap: 3px;
	margin-top: calc(32 * var(--u));
	padding-bottom: calc(60 * var(--u));
}
.insights__dots span {
	width: 6px;
	height: 6px;
	border-radius: 54px;
	background: var(--dot);
	transition: width 0.35s var(--ease-out), background-color 0.35s;
}
.insights__dots span.is-active { width: 63px; background: var(--teal); }

@media (min-width: 1200px) {
	.insights { padding-top: calc(156 * var(--u)); padding-bottom: calc(180 * var(--u)); }
	.insights__head {
		display: grid;
		grid-template-columns: calc(677 * var(--u)) calc(382 * var(--u)) 1fr;
		align-items: start;
		margin-bottom: calc(100 * var(--u)); /* desc bottom y8087 → cards y8187 */
	}
	.insights__title { font-size: calc(56 * var(--u)); line-height: calc(64 / 56); letter-spacing: 0; }
	.insights__desc {
		display: block;
		margin-top: calc(4 * var(--u)); /* text box y7997 vs title y7993 */
		font-size: calc(20 * var(--u));
		line-height: calc(30 / 20);
		letter-spacing: 0.02em;
		color: var(--grey-text);
	}
	.insights__nav { justify-self: end; margin-top: calc(4 * var(--u)); }
	/* Prev / Next (Insights, Related): Figma boxes 44 + 74 + 42 wide, 20/30 +2%; fixed boxes
	   so both words start where the design has them. */
	.insights__nav,
	.related__nav { display: flex; gap: calc(74 * var(--u)); font-size: calc(20 * var(--u)); line-height: calc(30 / 20); letter-spacing: 0.02em; }
	.insights__nav button,
	.related__nav button { text-align: left; transition: opacity 0.3s; }
	.insights__nav button:first-child,
	.related__nav button:first-child { width: calc(44 * var(--u)); }
	.insights__nav button:last-child,
	.related__nav button:last-child { width: calc(42 * var(--u)); }
	.insights__nav button:disabled,
	.related__nav button:disabled { opacity: 0.3; cursor: default; }
	.insights__track > li,
	.insights__track > li:nth-child(2n) { width: calc(517 * var(--u)); }
	.insights__track > li:nth-child(3n + 1) .insight-card__img { aspect-ratio: 517 / 530; border-radius: 6px; }
	.insights__track > li:nth-child(3n + 2) .insight-card__img { aspect-ratio: 517 / 701; }
	.insights__track > li:nth-child(3n) .insight-card__img { aspect-ratio: 516 / 638; }
	.insights__track {
		gap: calc(24 * var(--u));
		margin: 0;
		padding: 0;
		scroll-padding-inline: 0;
	}
	.insight-card__img { border-radius: 10px; }
	.insight-card__title {
		margin-top: calc(18 * var(--u));
		font-size: calc(32 * var(--u));
		line-height: calc(45 / 32);
		letter-spacing: 0.02em;
	}
	.insights__dots { display: none; }
}

/* =========================================================================
   Clients — mobile: black, pad 60, title 36/40 204w, list +40 48/52 400 gap 21
             desktop: pad 172, title 56/64 418w, list x741 96/96 300 gap 80, pad-bottom 171
             active #00D9BF, others white 65%
   ========================================================================= */

.clients { background: var(--black); color: var(--white); padding-top: calc(60 * var(--u)); }
.clients__title { max-width: calc(204 * var(--u)); font-size: calc(36 * var(--u)); font-weight: 300; line-height: calc(40 / 36); letter-spacing: 0.02em; }
.clients__list { display: grid; gap: calc(21 * var(--u)); margin-top: calc(40 * var(--u)); }
.clients__item {
	font-size: calc(48 * var(--u));
	font-weight: 400;
	line-height: calc(52 / 48);
	color: rgb(255 255 255 / 0.65);
	transition: color 0.6s cubic-bezier(0.165, 0.84, 0.44, 1); /* iventions.com: .6s easeOutQuart */
}
.clients__item.is-active { color: var(--teal); }

/* Active client's logo (iventions.com swap): a one-row-tall box glides onto the active row;
   square logos (source 23.3rem @1440 ≈ 280u) stack in it, centred on that row's line, and
   swap in place from their centre: in = scale 0 → 1, out = scale → 0 (.8s power3.out). */
.clients__body { display: grid; grid-template-columns: 1fr auto; column-gap: calc(16 * var(--u)); margin-top: calc(40 * var(--u)); }
.clients__body .clients__list { margin-top: 0; } /* the body carries the list's offset, so both columns start on row 1 */
.clients__logos { --row-h: calc(52 * var(--u)); --logo-size: calc(96 * var(--u)); position: relative; width: var(--logo-size); }
.clients__logo-box { position: absolute; top: 0; left: 0; width: 100%; height: var(--row-h); } /* JS moves it onto the active row */
.clients__logo {
	position: absolute;
	top: calc((var(--row-h) - var(--logo-size)) / 2);
	left: 0;
	width: var(--logo-size);
	height: var(--logo-size);
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
	transform: scale(0);
	will-change: transform, opacity;
}
.clients__logo-img {
	--logo-k: calc(96 / 280);                 /* mobile logo box is 96u vs 280u desktop */
	width: calc(var(--lg-w, 240) * var(--u) * var(--logo-k));
	height: calc(var(--lg-h, 65) * var(--u) * var(--logo-k));
	background: var(--teal);
	-webkit-mask: var(--logo) center / contain no-repeat;
	mask: var(--logo) center / contain no-repeat;
}
.clients__logo-text { color: var(--teal); font-size: calc(18 * var(--u)); font-weight: 500; line-height: 1; text-align: center; }

@media (min-width: 1200px) {
	.clients { padding-top: calc(172 * var(--u)); }
	.clients__inner {
		display: grid;
		grid-template-columns: calc(677 * var(--u)) 1fr;
		align-items: start;
		padding-bottom: calc(171 * var(--u));
	}
	.clients__title {
		position: sticky;
		top: calc(176 * var(--u));
		max-width: calc(418 * var(--u));
		margin-left: calc(1 * var(--u));
		font-size: calc(56 * var(--u));
		line-height: calc(64 / 56);
		letter-spacing: 0;
	}
	.clients__list { gap: calc(80 * var(--u)); margin-top: calc(8 * var(--u)); }
	.clients__item { font-size: calc(96 * var(--u)); font-weight: 300; line-height: 1; }
	.clients__body { margin-top: calc(8 * var(--u)); column-gap: calc(40 * var(--u)); }
	.clients__logos { --row-h: calc(96 * var(--u)); --logo-size: calc(280 * var(--u)); }
	.clients__logo-img { --logo-k: 1; }
	.clients__logo-text { font-size: calc(48 * var(--u)); }
}

/* =========================================================================
   Footer — mobile: pad 60, title 400 36/40 304w, rows from +40 (pitch 216):
            line 40%, label 20/28, links x226 16/24 gap 8; logo 194×40, © 14/20 #9C9C9C; pad-bottom 43
            desktop: pad 167, title 600 56/64 +2% 420w, rows x741 (pitch 217) from +13:
            label 700 32/45, links x1230 20/30; logo 868×180 x67; © 20/30; pad-bottom 68
   ========================================================================= */

.site-footer { position: relative; isolation: isolate; padding-top: calc(60 * var(--u)); padding-bottom: calc(43 * var(--u)); }
/* Watercolour ink canvas (ink.js) sits behind the footer content. */
.ink-fx { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none; }
.site-footer__title { max-width: calc(304 * var(--u)); font-size: calc(36 * var(--u)); font-weight: 400; line-height: calc(40 / 36); letter-spacing: 0.02em; }
.site-footer__cols { margin-top: calc(40 * var(--u)); }
.site-footer__row {
	display: grid;
	grid-template-columns: calc(206 * var(--u)) 1fr;
	align-items: start;
	height: calc(216 * var(--u));
	padding-top: calc(24 * var(--u));
	border-top: 1px solid rgb(0 0 0 / 0.4);
}
.site-footer__row:last-child { height: calc(192 * var(--u)); }
.site-footer__label { font-size: calc(20 * var(--u)); line-height: calc(28 / 20); }
.site-footer__links { display: grid; gap: calc(8 * var(--u)); font-size: calc(16 * var(--u)); line-height: calc(24 / 16); }
.site-footer__links a { display: inline-block; }
.site-footer__bottom { display: flex; justify-content: space-between; align-items: flex-end; }
.brandmark--footer { width: calc(194 * var(--u)); }
.site-footer__copy { font-size: calc(14 * var(--u)); line-height: calc(20 / 14); color: var(--copy-grey); white-space: nowrap; }

@media (min-width: 1200px) {
	.site-footer { padding-top: calc(167 * var(--u)); padding-bottom: calc(68 * var(--u)); }
	.site-footer__top { display: grid; grid-template-columns: calc(677 * var(--u)) 1fr; align-items: start; }
	.site-footer__title {
		max-width: calc(420 * var(--u));
		margin-left: calc(1 * var(--u));
		font-size: calc(56 * var(--u));
		font-weight: 600;
		line-height: calc(64 / 56);
		letter-spacing: 0.02em;
	}
	.site-footer__cols { margin-top: calc(13 * var(--u)); max-width: calc(922 * var(--u)); }
	.site-footer__row { grid-template-columns: calc(489 * var(--u)) 1fr; height: calc(217 * var(--u)); }
	.site-footer__row:last-child { height: calc(338 * var(--u)); }
	.site-footer__label { font-size: calc(32 * var(--u)); font-weight: 700; line-height: calc(45 / 32); letter-spacing: 0.02em; }
	.site-footer__links { gap: 0; font-size: calc(20 * var(--u)); line-height: calc(30 / 20); letter-spacing: 0.02em; }
	.brandmark--footer { width: calc(868 * var(--u)); margin-left: calc(3 * var(--u)); }
	.site-footer__copy { margin: 0 calc(-7 * var(--u)) calc(-4 * var(--u)) 0; font-size: calc(20 * var(--u)); line-height: calc(30 / 20); letter-spacing: 0.02em; color: var(--black); }
}

/* =========================================================================
   Project cursor (fine pointers only) — Frame 150: 103px circle, white 10%,
   Figma "Glass" effect (lens: next step), arrow line 33×33 stroke 4
   ========================================================================= */

.cursor { position: fixed; top: 0; left: 0; z-index: 40; pointer-events: none; display: none; }
@media (hover: hover) and (pointer: fine) { .cursor { display: block; } }

.cursor__dot {
	position: absolute;
	top: 0;
	left: 0;
	width: 103px;
	height: 103px;
	margin: -51.5px 0 0 -51.5px;
	transform: scale(0);
}

/* The droplet: stretched by JS along the movement direction (squash & stretch) */
.cursor__blob {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	border-radius: 50%;
	color: var(--white);
	will-change: transform;
}
/* Fallback (no WebGL): frosted glass circle */
.cursor:not(.has-lens) .cursor__blob {
	background: rgb(255 255 255 / 0.1);
	backdrop-filter: blur(6px) saturate(1.3);
	-webkit-backdrop-filter: blur(6px) saturate(1.3);
}
.cursor__lens { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%; }
.cursor__arrow { position: relative; z-index: 1; width: 33px; height: 33px; }

.cursor__label {
	position: absolute;
	top: 0;
	left: 76px;
	transform: translateY(-50%);
	white-space: nowrap;
	font-size: calc(72 * var(--u));
	font-weight: 300;
	color: var(--white);
	mix-blend-mode: difference;
	opacity: 0;
	transition: opacity 0.3s ease;
}

.cursor.is-active .cursor__label { opacity: 1; }
.has-cursor [data-cursor-label] { cursor: none; }

/* ---------- Liquid hover (water.js): canvas replaces the image visually ---------- */

.water-fx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; transform-origin: 50% 50%; }
/* The edge wave (14islands) bends the image past its box: the host must not clip, the canvas draws the rounded corners. */
.has-water-host { position: relative; overflow: visible !important; background: none !important; }
picture[data-water] { display: block; }
img.has-water { opacity: 0; }

/* =========================================================================
   Text roll (cuberto.com): text slides up, a copy rises from below and scales in.
   0.8s cubic-bezier(.16,1,.3,1); copy scale .9 → 1 in 0.4s (footer .7 → 1).
   ========================================================================= */

.roll { display: inline-block; position: relative; overflow: hidden; vertical-align: top; }
.roll > span { display: block; position: relative; transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1); }
.roll > span::after {
	content: attr(data-text);
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	transform: scale(0.9);
	transition: transform 0.4s;
}
.roll--footer > span::after { transform: scale(0.7); }
a:focus-visible > .roll > span { transform: translateY(-100%); }
a:focus-visible > .roll > span::after { transform: scale(1); }
/* Hover only where a pointer can hover — on touch, :hover sticks after a tap (and after Back). */
@media (hover: hover) {
	a:hover > .roll > span { transform: translateY(-100%); }
	a:hover > .roll > span::after { transform: scale(1); }
}

/* =========================================================================
   Site cursor (cuberto.com behaviour, RUH colours): red dot everywhere;
   over links/buttons it grows into a white circle. Off over the zones with
   their own hover (project cards, hero/Insights images, open menu).
   ========================================================================= */

.site-cursor { position: fixed; top: 0; left: 0; z-index: 55; pointer-events: none; display: none; } /* above header (50), below menu (60) */
@media (hover: hover) and (pointer: fine) { .site-cursor { display: block; } }

.site-cursor__dot {
	position: absolute;
	top: -20px;
	left: -20px;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--red);
	box-shadow: inset 0 0 0 0 var(--red);
	transform: scale(0.4);                  /* 16px dot (source: 10rem × .1) */
	transition: transform 0.3s, background-color 0.3s, box-shadow 0.3s, opacity 0.15s;
}
.site-cursor.-pointer .site-cursor__dot { transform: scale(1); } /* 40px circle (source: .25) */

/* Ink: a white copy of the hovered link/logo/icon, clipped to the dot, so what
   sits under the red circle reads white (cuberto's exclusion look, in RUH red). */
.site-cursor-ink { position: fixed; inset: 0; z-index: 56; pointer-events: none; color: var(--white); clip-path: circle(0 at -99px -99px); }
.site-cursor-ink > * {
	position: absolute !important;
	margin: 0 !important;
	box-sizing: border-box;
	color: var(--white) !important;
	background: none !important;
	transform: none !important;
	opacity: 1 !important;
}
/* …and everything inside it: a part with its own colour (Specialism's black/teal title, tags) would
   otherwise stay dark under the red dot. */
.site-cursor-ink > * * { color: var(--white) !important; }
.site-cursor-ink .is-hover > .roll > span { transform: translateY(-100%); }
.site-cursor-ink .is-hover > .roll > span::after { transform: scale(1); }
.site-cursor-ink .site-header__cta.is-hover .site-header__cta-arrow { transform: translateX(6px); }
.site-cursor-ink .pill-button.is-hover { gap: calc(15 * var(--u)); }
.site-cursor.-active .site-cursor__dot { transform: scale(0.5); }
.site-cursor.-pointer.-active .site-cursor__dot { transform: scale(0.85); }
.site-cursor.-hidden .site-cursor__dot { transform: scale(0); opacity: 0; }

/* Hide the system cursor where the dot takes over; keep it in the special zones. */
/* The system arrow stays visible, as on cuberto.com; the dot trails behind it. */

/* Header enter: logo + menu icon parts start hidden (no flash before the pop-in) */
.js .site-header .wordmark svg path,
.js .site-header .menu-toggle__icon svg path,
.js .site-header .menu-toggle__icon svg rect { transform-box: fill-box; transform-origin: center; transform: scale(0); transition: transform 0.4s cubic-bezier(0.215, 0.61, 0.355, 1); }
.js .site-header.is-in .wordmark svg path,
.js .site-header.is-in .menu-toggle__icon svg path,
.js .site-header.is-in .menu-toggle__icon svg rect { transform: none; }
@media (min-width: 1200px) { .js [data-header-item] { opacity: 0; } }

/* =========================================================================
   Page intro (inner pages) — desktop, Figma "WORK – List" 1100:2952:
     label x65 y532 32/45 +2% ("Selected Work"); text x741 y529 922w 56/64 300.
   Same block on Agency / Specialism / Work Grid (y533).
   ========================================================================= */

/* Mobile (Figma 1261:731): label y239 20/28; text y367 400w 36/40 300 */
.page-intro { padding-top: calc(239 * var(--u)); }
.page-intro__label { font-size: calc(20 * var(--u)); line-height: calc(28 / 20); }
.page-intro__text { margin-top: calc(100 * var(--u)); font-size: calc(36 * var(--u)); font-weight: 300; line-height: calc(40 / 36); }

@media (min-width: 1200px) {
	.page-intro {
		display: grid;
		grid-template-columns: calc(676 * var(--u)) calc(922 * var(--u));
		align-items: start;
		padding-top: calc(529 * var(--u));
	}
	.page-intro__label { justify-self: start; margin: calc(3 * var(--u)) 0 0 calc(1 * var(--u)); font-size: calc(32 * var(--u)); line-height: calc(45 / 32); letter-spacing: 0.02em; }
	.page-intro__text { margin-top: 0; font-size: calc(56 * var(--u)); line-height: calc(64 / 56); }
}

/* Footer after the Insights block on inner pages: title 108 below it (Work List: 3694 → 3802),
   not the homepage's 167 (after the black About block). */
@media (min-width: 1200px) {
	body:not(.home) .site-footer { padding-top: calc(108 * var(--u)); }
}

/* =========================================================================
   Dark end (body.has-dark-end): Insights block + footer on black, white text.
   Figma "Frame 69" on Work List/Grid/Display, Article, Specialism (desktop) and
   "Frame 238" (440): fill #000; text #FFF; Insights intro #2A2A2A (as designed);
   footer lines white 40%; mobile © #9C9C9C.
   ========================================================================= */

.has-dark-end .insights,
.has-dark-end .site-footer { background: var(--black); color: var(--white); }
/* Text on the black block reveals by character, dim (Figma #2A2A2A) → light (reveal.js --reveal: chars) */
.has-dark-end .insights__title,
.has-dark-end .insights__desc,
.has-dark-end .site-footer__title,
.related__title { --reveal: chars; --reveal-from: #2a2a2a; --reveal-to: var(--white); }
.has-dark-end .insights__desc { color: var(--white); }
.has-dark-end .site-footer__row { border-top-color: rgb(255 255 255 / 0.4); }
.has-dark-end .site-footer__copy { color: var(--copy-grey); }
.has-dark-end .insights__dots { display: none; }                    /* 440: no dots on the dark block */
.has-dark-end .insights { padding-bottom: calc(15 * var(--u)); }    /* cards end → footer title 75 (15 + footer 60) */

@media (min-width: 1200px) {
	.has-dark-end .insights { padding-bottom: calc(180 * var(--u)); }
	.has-dark-end .site-footer__copy { color: var(--white); }
}

/* Case cursor (casecursor.js): 127px white circle, exclusion; label on its own layer (no blend).
   "Full Case ↗" on Work cards; "view" on Insights list cards. */
.case-cursor,
.case-cursor-label { position: fixed; top: 0; left: 0; z-index: 45; pointer-events: none; display: none; }
@media (min-width: 1200px) and (hover: hover) and (pointer: fine) {
	.case-cursor { display: block; }
	.case-cursor-label { display: flex; }
	[data-case-cursor] { cursor: none; }
}
.case-cursor { width: 127px; height: 127px; margin: -63.5px 0 0 -63.5px; border-radius: 50%; background: var(--white); mix-blend-mode: exclusion; }
.case-cursor-label {
	align-items: center;
	gap: 8px;
	translate: -50% -50%;
	font-size: 16px;
	line-height: 24px;
	white-space: nowrap;
	color: var(--black);
}
.case-cursor-label svg { width: 11.3px; height: 11.3px; }
.case-cursor-label--view { font-family: var(--nhg); font-weight: var(--nhg-weight); color: var(--white); }

/* Insights card (image, category, title) — Insights list grid, article Related Insights.
   Figma 1192:13328 / 1261:1591: image 506×653 r4 (mobile 195×265 r2), category Plex Mono
   20/30 #808080 (mobile 14/18 #BCBCBC) +32 (+12), title 32/45 +2% (16/24) +8 (+6). */
.insight-tile__link { display: block; color: inherit; text-decoration: none; }
.insight-tile__media { display: block; height: calc(265 * var(--u)); overflow: hidden; border-radius: 2px; background: #111; }
.insight-tile__media img,
.insight-tile__media video { display: block; width: 100%; height: 100%; object-fit: cover; }
.insight-tile__cat {
	display: block;
	margin-top: calc(12 * var(--u));
	font-family: var(--plex);
	font-size: calc(14 * var(--u));
	line-height: calc(18 / 14);
	letter-spacing: -0.01em;
	color: #bcbcbc;
}
.insight-tile__title { margin-top: calc(6 * var(--u)); font-weight: 400; font-size: calc(16 * var(--u)); line-height: calc(24 / 16); }
@media (min-width: 1200px) {
	.insight-tile__media { height: calc(653 * var(--u)); border-radius: 4px; }
	.insight-tile__cat { margin-top: calc(32 * var(--u)); font-size: calc(20 * var(--u)); line-height: calc(30 / 20); color: #808080; }
	.insight-tile__title { margin-top: calc(8 * var(--u)); font-size: calc(32 * var(--u)); line-height: calc(45 / 32); letter-spacing: 0.02em; }
}

/* =========================================================================
   Page transition (animmasterlib.dev/pagetr, row 1 centre — "pegetr-15"; PRO, no public code, so the
   values are measured from its preview video at 120fps): the old page holds still while the new one
   opens through a centred rounded window (≈5% of the screen, screen-shaped) to full screen in 0.5s,
   blurred at first and sharp by ~70%. Fitted curve cubic-bezier(.6, .25, .35, .9).
   Cross-document View Transitions: normal WordPress page loads, every effect boots fresh on the new
   page; browsers without support (Firefox today) simply navigate. Off for reduced motion.
   ========================================================================= */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
	@view-transition { navigation: none; }
}
::view-transition-group(root) { animation-duration: 0.5s; }
::view-transition-old(root) { animation: none; }
::view-transition-new(root) { animation: ruh-page-in 0.5s linear both; transform-origin: 50% 50%; }
/* The destination page also zooms out, 1.4× → 1 (measured by matching each video frame to the final
   one), on the same curve. Scaling the page scales its clip too, so the window is baked per 5%: the
   on-screen window = inset 47.5% → 0 on cubic-bezier(.6,.25,.35,.9), divided back by the scale; the
   animation itself runs linear. Corners ≈ 0.45vw on screen (measured — near-square, not an oval);
   fade-in over the first 15%; blur 24px → 0 by 70%. Generated — edit the numbers by regenerating. */
@keyframes ruh-page-in {
	0% { clip-path: inset(48.21% round 0.321vw); transform: scale(1.4000); filter: blur(24.0px); opacity: 0.00; }
	5% { clip-path: inset(47.43% round 0.324vw); transform: scale(1.3909); filter: blur(22.3px); opacity: 0.33; }
	10% { clip-path: inset(46.48% round 0.326vw); transform: scale(1.3802); filter: blur(20.6px); opacity: 0.67; }
	15% { clip-path: inset(45.34% round 0.329vw); transform: scale(1.3674); filter: blur(18.9px); opacity: 1.00; }
	20% { clip-path: inset(43.93% round 0.333vw); transform: scale(1.3520); filter: blur(17.1px); }
	25% { clip-path: inset(42.19% round 0.338vw); transform: scale(1.3333); filter: blur(15.4px); }
	30% { clip-path: inset(39.98% round 0.343vw); transform: scale(1.3104); filter: blur(13.7px); }
	35% { clip-path: inset(37.12% round 0.351vw); transform: scale(1.2820); filter: blur(12.0px); }
	40% { clip-path: inset(33.41% round 0.361vw); transform: scale(1.2469); filter: blur(10.3px); }
	45% { clip-path: inset(28.73% round 0.373vw); transform: scale(1.2052); filter: blur(8.6px); }
	50% { clip-path: inset(23.43% round 0.388vw); transform: scale(1.1612); filter: blur(6.9px); }
	55% { clip-path: inset(18.36% round 0.401vw); transform: scale(1.1221); filter: blur(5.1px); }
	60% { clip-path: inset(14.05% round 0.413vw); transform: scale(1.0908); filter: blur(3.4px); }
	65% { clip-path: inset(10.58% round 0.422vw); transform: scale(1.0669); filter: blur(1.7px); }
	70% { clip-path: inset(7.83% round 0.429vw); transform: scale(1.0486); filter: blur(0.0px); }
	75% { clip-path: inset(5.63% round 0.435vw); transform: scale(1.0345); filter: blur(0.0px); }
	80% { clip-path: inset(3.89% round 0.440vw); transform: scale(1.0236); filter: blur(0.0px); }
	85% { clip-path: inset(2.52% round 0.443vw); transform: scale(1.0151); filter: blur(0.0px); }
	90% { clip-path: inset(1.44% round 0.446vw); transform: scale(1.0086); filter: blur(0.0px); }
	95% { clip-path: inset(0.61% round 0.448vw); transform: scale(1.0037); filter: blur(0.0px); }
	100% { clip-path: inset(0.00% round 0.000vw); transform: scale(1.0000); filter: blur(0.0px); }
}
/* Same tone on both sides (white → white, black → black) leaves the window invisible — the reference
   always has imagery behind it. The held page then gets a veil as the window opens: light pages dim,
   dark pages lift. data-pt-from = the old page's visible tone (assets/js/pt.js);
   the new page's tone = body.has-dark-top. */
html[data-pt-from="light"]:not(.pt-work):not(:has(> body.has-dark-top))::view-transition-old(root) { animation: ruh-page-dim 0.5s cubic-bezier(0.6, 0.25, 0.35, 0.9) both; }
html[data-pt-from="dark"]:not(.pt-work):has(> body.has-dark-top)::view-transition-old(root) { animation: ruh-page-lift 0.5s cubic-bezier(0.6, 0.25, 0.35, 0.9) both; }
@keyframes ruh-page-dim { to { filter: brightness(0.55); } }
@keyframes ruh-page-lift { to { filter: invert(0.2); } }

/* Work only — shared image (html.pt-work, set by assets/js/pt.js): the clicked Work image (grid card,
   homepage project card, Related card, Work List preview/thumb) is one element across both pages,
   "ruh-work", that moves and resizes into the project hero (Back: hero → card) on the same measured
   curve, 0.8s; the rest of the page cross-fades underneath. Snapshots are cover-cropped so the
   different shapes (cards 780×875, hero 1598×875) never stretch. Tested side by side with the window
   transition in tests/transition-demo/. */
html.pt-work::view-transition-group(root) { animation-duration: 0.8s; }
html.pt-work::view-transition-old(root) { animation: ruh-fade-out 0.35s ease both; }
html.pt-work::view-transition-new(root) { animation: ruh-fade-in 0.45s ease 0.3s both; }
html.pt-work::view-transition-group(ruh-work) { animation-duration: 0.8s; animation-timing-function: cubic-bezier(0.6, 0.25, 0.35, 0.9); }
html.pt-work::view-transition-image-pair(ruh-work) { overflow: hidden; }
html.pt-work::view-transition-old(ruh-work),
html.pt-work::view-transition-new(ruh-work) { width: 100%; height: 100%; object-fit: cover; animation-duration: 0.8s; animation-timing-function: cubic-bezier(0.6, 0.25, 0.35, 0.9); }
@keyframes ruh-fade-out { to { opacity: 0; } }
@keyframes ruh-fade-in { from { opacity: 0; transform: translateY(calc(24 * var(--u))); } }
/* The carried image leaves its card's title/label behind (they fade with the page) */
.pt-carry .project-card__overlay { opacity: 0; }

/* Slider tracks: drag with the mouse (slider.js) */
@media (hover: hover) and (pointer: fine) {
	.insights__track, .related__track, .article-related__track { cursor: grab; }
	.insights__track.is-dragging, .related__track.is-dragging, .article-related__track.is-dragging { cursor: grabbing; user-select: none; }
	.is-dragging a { pointer-events: none; }
}
