/*
Theme Name: Sisko Theme
Author: Entropia Digital Agency
Author URI: https://www.entropia.gr/
Description: Custom theme for the Sisko company
Version: 1
Requires at least: 5.0
Tested up to: 5.4
Requires PHP: 7.0
Text Domain: entropia
*/

/* ---------- Fonts (self-hosted variable woff2) ---------- */
@font-face {
	font-display: swap;
	font-family: "Manrope";
	font-style: normal;
	font-weight: 400 800;
	src: url("assets/fonts/manrope-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-display: swap;
	font-family: "Manrope";
	font-style: normal;
	font-weight: 400 800;
	src: url("assets/fonts/manrope-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-display: swap;
	font-family: "Manrope";
	font-style: normal;
	font-weight: 400 800;
	src: url("assets/fonts/manrope-greek.woff2") format("woff2");
	unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

@font-face {
	font-display: swap;
	font-family: "Roboto Flex";
	font-stretch: 100%;
	font-style: normal;
	font-weight: 300 600;
	src: url("assets/fonts/roboto-flex-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-display: swap;
	font-family: "Roboto Flex";
	font-stretch: 100%;
	font-style: normal;
	font-weight: 300 600;
	src: url("assets/fonts/roboto-flex-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-display: swap;
	font-family: "Roboto Flex";
	font-stretch: 100%;
	font-style: normal;
	font-weight: 300 600;
	src: url("assets/fonts/roboto-flex-greek.woff2") format("woff2");
	unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

:root {
	--bg: #ffffff;
	--col: 696px;
	--ease: cubic-bezier(0.65, 0, 0.2, 1);
	--ink: #151516;
	--line: rgba(45, 45, 50, 0.14);
	--maxw: 1360px;
	--muted: #9a9a9f;
	--soft: #f2f1ee;
}

* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

html {
	scroll-behavior: smooth;
}

body {
	-webkit-font-smoothing: antialiased;
	background: var(--bg);
	color: var(--ink);
	font-family: "Roboto Flex", "Helvetica Neue", Arial, sans-serif;
	line-height: 1.6;
}

/* Titles use Manrope, content uses Roboto Flex */
h1, h2, h3, h4, h5, h6, .pullquote, .footer-cta {
	font-family: "Manrope", "Helvetica Neue", Arial, sans-serif;
}

/* Scroll reveal: content rises up and fades in when scrolled into view.
   Targets are hidden before first paint (gated by .js, so no-JS shows all),
   then revealed with a keyframe animation. */
@keyframes revealUp {
	from {
		opacity: 0;
		transform: translateY(32px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}
.js .reveal {
	opacity: 0;
}
/* Revealed state declares the final values directly, so content is visible
   even if the animation timeline is unavailable; the animation adds motion. */
.js .reveal.is-in {
	animation: revealUp 0.8s var(--ease);
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.js .reveal {
		opacity: 1;
	}
	
	.js .reveal.is-in {
		animation: none;
	}
}

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

/* ---------- Header ---------- */
header {
	align-items: center;
	/* Fully transparent on every page: only the logo and the menu toggle are
	   visible — and, via pointer-events below, the only clickable areas. The bar
	   itself never shows a background or intercepts clicks meant for content. */
	background: transparent;
	display: flex;
	justify-content: space-between;
	padding: 18px 48px; /* trimmed to keep header height ~unchanged with the bigger logo */
	pointer-events: none;
	position: sticky;
	top: 0;
	z-index: 60; /* above the fullscreen overlay */
}

header .logo, header .menu-toggle {
	pointer-events: auto;
}

/* when the menu is open the bar goes transparent so the dark overlay shows through */
.menu-open header {
	backdrop-filter: none;
	background: transparent;
}

.logo {
	display: block;
	height: 75px;
	position: relative;
	transition: height 0.4s var(--ease);
	z-index: 60;
}

/* When the page is scrolled the sticky header condenses: the logo shrinks
   so the bar takes up less vertical space. */
.scrolled .logo {
	height: 40px;
}

.logo img {
	height: 100%;
	transition: filter 0.4s var(--ease);
}

/* Stand-in for the logo when no image is set in Site Settings. */
.logo-text {
	color: var(--ink);
	font-family: "Manrope", sans-serif;
	font-size: 24px;
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 75px;
	transition: color 0.4s var(--ease);
}

.menu-open .logo img {
	filter: invert(1) brightness(2);
} /* dark logo -> white */

/* Burger toggle: "Menu" word + icon */
.menu-toggle {
	align-items: center;
	background: none;
	border: 0;
	color: var(--ink);
	cursor: pointer;
	display: flex;
	font-family: "Manrope", sans-serif;
	gap: 14px;
	padding: 6px 0;
	position: relative;
	z-index: 60;
}

.menu-word {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	transition: color 0.4s var(--ease);
}

.burger {
	flex: none;
	height: 12px;
	position: relative;
	width: 26px;
}

.burger span {
	background: currentColor;
	height: 2px;
	left: 0;
	position: absolute;
	transition: transform 0.4s var(--ease), opacity 0.3s var(--ease), background 0.4s var(--ease);
	width: 100%;
}

.burger span:nth-child(1) {
	top: 0;
}

.burger span:nth-child(2) {
	bottom: 0;
}

/* open state: morph into an X */
.menu-open .burger span:nth-child(1) {
	top: 5px;
	transform: rotate(45deg);
}

.menu-open .burger span:nth-child(2) {
	bottom: 5px;
	transform: rotate(-45deg);
}

.menu-open .menu-toggle {
	color: #fff;
}

/* Adaptive header colour: dark-background sections carry data-nav="light"; when
   one sits under the bar, custom.js adds .is-light so the logo and menu switch
   from the default dark ink to white (transitions already defined above). */
header.is-light .menu-toggle {
	color: #fff;
}

header.is-light .logo img {
	filter: brightness(0) invert(1);
}
header.is-light .logo-text {
	color: #fff;
}

/* Fullscreen overlay menu */
.menu-overlay {
	-webkit-overflow-scrolling: touch;
	background: var(--ink);
	display: flex;
	inset: 0;
	opacity: 0;
	/* scrollable when the content (e.g. open submenus on short screens) is
	 taller than the viewport; margin:auto on the list keeps it centred
	 when it fits, but stays reachable from the top when it overflows. */
	overflow-y: auto;
	overscroll-behavior: contain;
	position: fixed;
	transition: opacity 0.5s var(--ease), visibility 0.5s var(--ease);
	visibility: hidden;
	z-index: 55;
}

.menu-open .menu-overlay {
	opacity: 1;
	visibility: visible;
}

.menu-overlay ul {
	list-style: none;
	text-align: center;
}

.menu-overlay > ul {
	margin: auto; /* centre vertically & horizontally when it fits */
	padding: 96px 24px; /* clear the header/close button and screen edges */
}

.menu-overlay li {
	overflow: hidden;
}

.menu-overlay a {
	color: #fff; /* white at first */
	display: inline-block;
	font-family: "Manrope", sans-serif;
	font-size: clamp(34px, 6.5vw, 62px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.14;
	opacity: 0;
	overflow: hidden; /* masks the word roll */
	position: relative;
	text-decoration: none;
	text-transform: uppercase;
	transform: translateY(110%); /* entrance: slide up into view when menu opens */
	transition: transform 0.5s var(--ease), opacity 0.5s var(--ease);
}

.menu-open .menu-overlay a {
	opacity: 1;
	transform: translateY(0);
}

/* staggered entrance (top-level items only, so submenu links aren't
   given an entrance delay that would also lag their hover transition) */
.menu-overlay > ul > li:nth-child(1) > a {
	transition-delay: 0.06s;
}

.menu-overlay > ul > li:nth-child(2) > a {
	transition-delay: 0.12s;
}

.menu-overlay > ul > li:nth-child(3) > a {
	transition-delay: 0.18s;
}

.menu-overlay > ul > li:nth-child(4) > a {
	transition-delay: 0.24s;
}

.menu-overlay > ul > li:nth-child(5) > a {
	transition-delay: 0.30s;
}

.menu-overlay > ul > li:nth-child(6) > a {
	transition-delay: 0.36s;
}

.menu-overlay > ul > li:nth-child(7) > a {
	transition-delay: 0.42s;
}

/* hover: hovered top-level link stays white, the rest dim to gray
   (scoped to top-level items so submenu links are governed on their own) */
.menu-overlay > ul:hover > li > a {
	color: rgba(255, 255, 255, 0.32);
}

.menu-overlay > ul > li > a:hover {
	color: #fff;
}

/* "words go up" roll: main word exits upward, duplicate rises from below */
.menu-overlay a .txt {
	display: block;
	transition: transform 0.5s var(--ease), color 0.35s var(--ease);
}

.menu-overlay a .txt-dup {
	left: 0;
	position: absolute;
	top: 0;
	transform: translateY(100%);
	width: 100%;
}

.menu-overlay a:hover .txt {
	transform: translateY(-100%);
}

.menu-overlay a:hover .txt-dup {
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.menu-overlay a .txt, .menu-overlay a .txt-dup {
		transition: color 0.35s var(--ease);
	}
	
	.menu-overlay a:hover .txt {
		transform: none;
	}
	
	.menu-overlay a:hover .txt-dup {
		transform: translateY(100%);
	}
}

/* ---------- Submenu (Portfolio / Extra) ----------
   Clicking the item expands a list of sub-links below it (Serano-style).
   A "+" sign marks items that have a submenu, rotating into an "×" when
   open so the affordance is clear before clicking. */
.menu-overlay .sub-plus {
	color: #fff;
	cursor: pointer;
	display: inline-block;
	font-size: clamp(34px, 6.5vw, 62px); /* match the menu item so the sign scales & aligns with it */
	height: 0.26em;
	margin-left: 0.3em;
	opacity: 0; /* fades in with the menu entrance */
	position: relative;
	transition: opacity 0.5s var(--ease), transform 0.4s var(--ease);
	vertical-align: 0.44em; /* lift to the optical centre of the caps */
	width: 0.26em;
}

.menu-open .menu-overlay .sub-plus {
	opacity: 1;
}

.menu-overlay .sub-plus::before, .menu-overlay .sub-plus::after {
	background: currentColor;
	content: "";
	left: 50%;
	position: absolute;
	top: 50%;
	transform: translate(-50%, -50%);
}

.menu-overlay .sub-plus::before {
	height: 2px; width: 100%;
} /* horizontal bar */

.menu-overlay .sub-plus::after {
	height: 100%; width: 2px;
} /* vertical bar */

.menu-overlay .has-sub.is-open .sub-plus {
	transform: rotate(135deg);
} /* + -> × */

/* The expanding list of sub-links. */
.menu-overlay .submenu {
	list-style: none;
	margin-top: 0;
	max-height: 0;
	opacity: 0;
	overflow: hidden;
	transition: max-height 0.5s var(--ease), opacity 0.4s var(--ease), margin-top 0.5s var(--ease);
}

.menu-overlay .has-sub.is-open .submenu {
	margin-top: 12px;
	max-height: 60vh;
	opacity: 1;
}

.menu-overlay .submenu li {
	overflow: visible;
}

.menu-overlay .submenu a {
	color: #fff; /* white when the submenu opens */
	display: inline-block;
	font-family: "Manrope", sans-serif;
	font-size: clamp(15px, 2.2vw, 20px);
	font-weight: 600;
	letter-spacing: 0.04em;
	line-height: 1.7;
	opacity: 1;
	text-decoration: none;
	text-transform: uppercase;
	transform: none; /* opt out of the big-item entrance */
	transition: color 0.02s linear;
}

/* hovering the open submenu dims the rest; the hovered one stays white */
.menu-overlay .submenu:hover a {
	color: rgba(255, 255, 255, 0.32);
}

.menu-overlay .submenu a:hover {
	color: #fff;
}

/* ---------- Layout helpers ---------- */
.wide {
	margin: 0 auto;
	max-width: var(--maxw);
	padding: 0 48px;
}

.narrow {
	margin: 0 auto;
	max-width: var(--col);
	padding: 0 48px;
}

section {
	padding: 0;
}

.pad-lg {
	padding-bottom: 130px;
	padding-top: 130px;
}

.pad-md {
	padding-bottom: 90px;
	padding-top: 90px;
}

.mb-lg {
	margin-bottom: 130px;
}

/* ---------- Title hero ---------- */
.title-hero {
	background: var(--bg);
	padding: 150px 0 90px;
}

.title-hero h1 {
	font-size: clamp(40px, 7vw, 75px);
	font-weight: 700;
	letter-spacing: -0.03em;
	line-height: 0.96;
}

.title-hero h1 span {
	display: block;
}

.meta {
	display: flex;
	flex-wrap: wrap;
	gap: 48px;
	margin-top: 48px;
}

.meta-item .label {
	color: var(--muted);
	display: block;
	font-size: 11px;
	letter-spacing: 0.16em;
	margin-bottom: 6px;
	text-transform: uppercase;
}

.meta-item .value {
	font-size: 15px;
	font-weight: 500;
}

/* ---------- Full-bleed media ---------- */
.media-full {
	width: 100%;
}

.media-full img {
	height: auto; width: 100%;
}

/* Contained (non full-bleed) media, held to the page max-width */
.media-contained {
	position: relative;
}

.media-contained img {
	height: auto;
	width: 100%;
}

.media-caption {
	position: relative;
}

.vertical-caption {
	color: var(--muted);
	font-size: 12px;
	letter-spacing: 0.22em;
	position: absolute;
	right: 22px;
	text-transform: uppercase;
	top: 50%;
	transform: translateY(-50%) rotate(180deg);
	writing-mode: vertical-rl;
}

/* ---------- Text blocks ---------- */
.pullquote {
	font-size: clamp(22px, 3vw, 32px);
	font-weight: 600;
	letter-spacing: -0.01em;
	line-height: 1.25;
}

.body-text {
	color: #55555b;
	font-size: 16px;
	margin-top: 34px;
}

.body-text + .body-text {
	margin-top: 20px;
}

/* Wrapper around a Work text section's WYSIWYG output. Its paragraphs arrive as
   bare <p> and so cannot carry .body-text; they are matched here instead. The
   spacing lives on the wrapper: 34px below a pull quote, and none when the text
   leads the section — the structural replacement for an inline margin-top:0. */
.work-body {
	margin-top: 34px;
}

.work-body:first-child {
	margin-top: 0;
}

.work-body > p {
	color: #55555b;
	font-size: 16px;
}

.work-body > p + p {
	margin-top: 20px;
}

.detail-row {
	border-top: 1px solid var(--line);
	display: grid;
	gap: 30px;
	grid-template-columns: repeat(3, 1fr);
	margin-top: 56px;
	padding-top: 40px;
}

/* A Details section is an appendix to the block above it, not a section break:
   the rule belongs 56px under the preceding text, which is what .detail-row's
   own margin gives. So this block drops its top padding, and the block before it
   drops its bottom padding — otherwise the two .pad-lg sections stack 260px of
   air between the paragraph and the rule. */
.work-details {
	padding-top: 0;
}

.pad-lg:has(+ .work-details) {
	padding-bottom: 0;
}

.detail-row h4 {
	color: var(--muted);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.12em;
	margin-bottom: 8px;
	text-transform: uppercase;
}

.detail-row p {
	font-size: 17px;
	font-weight: 500;
}

.section-label {
	color: var(--muted);
	font-size: 12px;
	letter-spacing: 0.22em;
	margin-bottom: 40px;
	text-transform: uppercase;
}

/* ---------- Gallery: scroll-driven pinned slider ---------- */
/* Tall wrapper provides the vertical scroll distance that drives the slide */
.cargal-pin {
	position: relative;
}

/* Sticky viewport pins the slider while the page scrolls through the wrapper */
.cargal-sticky {
	display: flex;
	flex-direction: column;
	gap: 34px;
	height: 100vh;
	justify-content: center;
	overflow: hidden;
	position: sticky;
	top: 0;
}

.cargal {
	--gap: 40px;
	/* slide width matches the big (non full-width) contained images */
	--slideW: min(1264px, calc(100vw - 96px));
	overflow-x: clip; /* clips off-screen slides without breaking sticky header */
	width: 100%;
}

.cargal-track {
	display: flex;
	gap: var(--gap);
	position: relative;
	will-change: transform;
}

.cargal-item {
	flex: 0 0 var(--slideW);
	opacity: 0.4;
	position: relative;
	transition: opacity 0.5s var(--ease);
}

.cargal-item.is-active {
	opacity: 1;
}

.cargal-item img {
	cursor: zoom-in;
	height: auto;
	width: 100%;
}

/* ---------- Lightbox ---------- */
.lightbox {
	align-items: center;
	background: rgba(20, 20, 22, 0.94);
	display: flex;
	inset: 0;
	justify-content: center;
	opacity: 0;
	position: fixed;
	transition: opacity 0.35s var(--ease), visibility 0.35s var(--ease);
	visibility: hidden;
	z-index: 100;
}

.lightbox.open {
	opacity: 1;
	visibility: visible;
}

.lb-figure {
	align-items: center;
	display: flex;
	flex-direction: column;
	gap: 18px;
	margin: 0;
	max-height: 82vh;
	max-width: min(88vw, 1400px);
	transform: scale(0.96);
	transition: transform 0.35s var(--ease);
}

.lightbox.open .lb-figure {
	transform: scale(1);
}

.lb-img {
	box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
	height: auto;
	max-height: 74vh;
	max-width: 100%;
	object-fit: contain;
	user-select: none;
	width: auto;
}

.lb-cap {
	color: rgba(255, 255, 255, 0.75);
	font-size: 13px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.lb-btn {
	align-items: center;
	background: rgba(255, 255, 255, 0.08);
	border: 1px solid rgba(255, 255, 255, 0.25);
	border-radius: 50%;
	color: #fff;
	cursor: pointer;
	display: flex;
	height: 54px;
	justify-content: center;
	position: absolute;
	transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
	width: 54px;
}

.lb-btn:hover {
	background: rgba(255, 255, 255, 0.2);
	border-color: #fff;
}

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

.lb-close {
	right: 28px;
	top: 28px;
}

.lb-prev {
	left: 28px;
	top: 50%;
	transform: translateY(-50%);
}

.lb-next {
	right: 28px;
	top: 50%;
	transform: translateY(-50%);
}

.lb-counter {
	bottom: 28px;
	color: rgba(255, 255, 255, 0.7);
	font-size: 13px;
	left: 50%;
	letter-spacing: 0.14em;
	position: absolute;
	transform: translateX(-50%);
}

.lb-counter b {
	color: #fff;
	font-weight: 600;
}

@media (max-width: 700px) {
	.lb-btn {
		height: 46px;
		width: 46px;
	}
	
	.lb-close {
		right: 16px;
		top: 16px;
	}
	
	.lb-prev {
		left: 12px;
	}
	
	.lb-next {
		right: 12px;
	}
}

/* ---------- Footer: "Let's talk" ---------- */
footer {
	background: var(--ink);
	color: #fff;
	padding: 120px 0 50px;
}

.footer-head {
	text-align: center;
}

.footer-eyebrow {
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.footer-talk {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: clamp(34px, 5vw, 55px);
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1;
	margin-top: 16px;
	text-transform: uppercase;
}

/* "Let's talk" word-roll link — same effect as the main menu items:
   the word rolls up and out while an identical copy rises from below. */
.talk-link {
	color: inherit;
	display: inline-block;
	overflow: hidden; /* masks the roll */
	position: relative;
	text-decoration: none;
	vertical-align: top;
}

.talk-link .txt {
	display: block;
	transition: transform 0.5s var(--ease);
}

.talk-link .txt-dup {
	left: 0;
	position: absolute;
	top: 0;
	transform: translateY(100%); /* waits just below, out of view */
	width: 100%;
}

.talk-link:hover .txt {
	transform: translateY(-100%);
}

.talk-link:hover .txt-dup {
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.talk-link .txt, .talk-link .txt-dup {
		transition: none;
	}
  
	.talk-link:hover .txt {
		transform: none; }
  
	.talk-link:hover .txt-dup {
		transform: translateY(100%);
	}
}

.footer-row {
	align-items: flex-start;
	display: flex;
	gap: 40px;
	justify-content: space-between;
	margin-top: 90px;
}

/* Two dark contact columns (left) */
.contact-cols {
	display: flex;
	flex-wrap: wrap;
	gap: 64px;
}

.contact-col {
	min-width: 200px;
}

.contact-col h4 {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: 20px;
	font-weight: 700;
	margin-bottom: 20px;
}

.contact-col p {
	color: #fff;
	font-size: 15px;
	line-height: 1.9;
}

/* Footer links: white, dimming to a soft gray on hover. */
.contact-col a, .footer-bottom a {
	color: #fff;
	text-decoration: none;
	transition: color 0.3s var(--ease);
}

.contact-col a:hover, .footer-bottom a:hover {
	color: rgba(255, 255, 255, 0.55);
}

/* Follow Us (right): the label stays put; on hover the icons open out
   below it, fanning downward and to the left. The icons are anchored to
   the right edge and revealed right-to-left, so the group grows toward the
   bottom-left of the label. */
.socials-wrap {
	cursor: pointer;
	height: 88px;
	margin-left: auto; /* keep it on the right of the row */
	position: relative;
	width: 240px;
}

.socials-label {
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.16em;
	position: absolute;
	right: 0;
	text-transform: uppercase;
	top: 4px; /* aligned with the Staff / Conversation titles */
	white-space: nowrap;
}

.socials {
	align-items: center;
	display: flex;
	gap: 10px;
	list-style: none;
	pointer-events: none; /* icons stay unclickable until revealed */
	position: absolute;
	right: 0;
	top: 40px; /* sits just below the label, anchored to the right */
}

.socials-wrap:hover .socials, .socials-wrap:focus-within .socials {
	pointer-events: auto;
}

.socials li {
	flex: none;
	opacity: 0;
	transform: translateY(-8px); /* tucked up under the label */
	transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}

.socials-wrap:hover .socials li, .socials-wrap:focus-within .socials li {
	opacity: 1;
	transform: translateY(0); /* drop down into place */
}

/* reveal right -> left so it reads as opening toward the left */
.socials li:nth-child(5) {
	transition-delay: 0.02s;
}

.socials li:nth-child(4) {
	transition-delay: 0.07s;
}

.socials li:nth-child(3) {
	transition-delay: 0.12s;
}

.socials li:nth-child(2) {
	transition-delay: 0.17s;
}

.socials li:nth-child(1) {
	transition-delay: 0.22s;
}

.socials a {
	align-items: center;
	border: 1px solid rgba(255, 255, 255, 0.3);
	border-radius: 50%;
	color: #fff;
	display: flex;
	font-size: 11px;
	height: 34px;
	justify-content: center;
	letter-spacing: 0.02em;
	text-decoration: none;
	transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
	width: 34px;
}

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

.footer-bottom {
	color: #fff;
	font-size: 13px;
	margin-top: 90px;
	text-align: center;
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
	header { padding: 16px 22px; }
	
	.wide, .narrow {
		padding: 0 22px;
	}
	
	.title-hero {
		padding: 100px 0 60px;
	}
	
	.pad-lg {
		padding-bottom: 80px;
		padding-top: 80px;
	}
	
	.pad-md {
		padding-bottom: 60px;
		padding-top: 60px;
	}
	
	.mb-lg {
		margin-bottom: 80px;
	}
	
	.cargal {
		--gap: 20px;
		--slideW: calc(100vw - 44px);
	}
	
	.meta {
		gap: 30px;
	}
	
	.detail-row {
		gap: 24px;
		grid-template-columns: 1fr;
	}
	
	.footer-row {
		align-items: stretch;
		flex-direction: column;
		gap: 44px;
		margin-top: 60px;
	}
	
	/* on touch/mobile show the label then the icons statically (no hover) */
	.socials-wrap {
		height: auto;
		margin-left: 0;
		width: auto;
	}
	
	.socials-label {
		position: static;
	}
	
	.socials {
		margin-top: 20px;
		pointer-events: auto;
		position: static;
	}
	
	.socials li {
		opacity: 1;
		transform: none;
		transition: none;
	}
	
	.contact-cols {
		gap: 40px;
	}
	
	.contact-col {
		flex: 1;
		min-width: 0;
	}
}

/* ---------- Custom cursor: a trailing outline ring ----------
   The ring lags slightly behind the pointer and grows over anything
   clickable. The native cursor is kept as-is; the ring rides alongside it.
   mix-blend-mode: difference keeps it visible over light and dark sections.
   It grows by animating its width/height (not transform: scale), so the
   border stays crisp at every size instead of pixelating.
   Only enabled for real (fine, hover-capable) pointers. */
@media (hover: hover) and (pointer: fine) {
	.cursor-ring {
		border: 1.5px solid #fff;
		border-radius: 50%;
		height: 40px; /* JS drives the size; centred via translate */
		left: 0;
		mix-blend-mode: difference;
		pointer-events: none;
		position: fixed;
		top: 0;
		transition: opacity 0.25s ease;
		width: 40px;
		will-change: transform;
		z-index: 2147483647;
	}
	
	.cursor-ring.is-hidden {
		opacity: 0;
	}
}

/* ---------- About page: parallax hero ---------- */
/* Full-bleed image that drifts slower than the page (parallax), with the page
   title overlaid. The media is 130% tall and offset -15% so it can translate
   ±15% without ever exposing an edge; custom.js drives the transform.
   The negative margin pulls the hero up under the sticky header (75px logo +
   2×18px padding = 111px) so the image runs edge-to-edge to the very top and the
   frosted header floats over it — without altering the shared header itself. */
.about-hero {
	height: 88vh;
	margin-top: -111px;
	min-height: 520px;
	overflow: hidden;
	position: relative;
}

.about-hero-media {
	height: 170%;
	left: 0;
	position: absolute;
	top: -35%;
	width: 100%;
	will-change: transform;
}

.about-hero-media img {
	height: 100%;
	object-fit: cover;
	width: 100%;
}

/* Dark scrim so the overlaid white title stays legible over any image */
.about-hero::after {
	background: linear-gradient(180deg, rgba(20, 20, 22, 0.25) 0%, rgba(20, 20, 22, 0.5) 100%);
	content: "";
	inset: 0;
	position: absolute;
	z-index: 1;
}

.about-hero-overlay {
	align-items: center;
	display: flex;
	inset: 0;
	justify-content: center;
	position: absolute;
	z-index: 2;
}

.about-hero-title {
	color: #fff;
	font-size: clamp(46px, 9vw, 116px);
	font-weight: 700;
	letter-spacing: -0.03em;
	line-height: 0.96;
	text-align: center;
}

/* The Services hero adds a subtitle under the title (the About hero has none).
   It is deliberately a little larger than body copy so it reads as a statement. */
.about-hero-subtitle {
	color: rgba(255, 255, 255, 0.92);
	font-size: clamp(18px, 2.2vw, 27px);
	font-weight: 400;
	letter-spacing: -0.01em;
	line-height: 1.4;
	margin: 26px auto 0;
	max-width: 780px;
	text-align: center;
}

/* The Services hero is taller than the shared About hero, and its subtitle is
   lifted out of the centred title block and anchored in the lower third: the
   title stays vertically centred while the statement sits near the bottom, well
   clear of it. Scoped to --services so the About/Manifesto hero is unaffected. */
.about-hero--services {
	height: 100vh;
	min-height: 640px;
}

.about-hero--services .about-hero-subtitle {
	bottom: 15vh;
	left: 24px;
	margin: 0 auto;
	position: absolute;
	right: 24px;
}

/* On the Services hero the subtitle is hidden on load and fades up into place on the
   first scroll (custom.js adds .hero-revealed), like the reference site — reusing the
   same rise-and-fade as the site's scroll reveal. The title stays visible on load.
   Scoped to .js so the subtitle is always visible if the script never runs. */
.js .about-hero--services .about-hero-subtitle {
	opacity: 0;
	transform: translateY(32px);
	transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.js .about-hero--services.hero-revealed .about-hero-subtitle {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.js .about-hero--services .about-hero-subtitle {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* ---------- Services page: pinned service sections ---------- */
/* Each service is a two-column row. The heading column spans the full height of
   the image beside it (grid stretches the columns equal), and its heading + text
   are pushed to the top and bottom of that height — so the title lines up with the
   top of the image and the text with its bottom. The heading and image swap sides
   on every other row via :nth-child + order, and a CSS counter numbers them. */
.services-sections {
	counter-reset: svc;
	padding-bottom: 130px;
	padding-top: 130px;
}

.service-row {
	counter-increment: svc;
}

.service-row + .service-row {
	margin-top: 120px;
}

.service-grid {
	display: grid;
	gap: 48px 80px;
	grid-template-columns: 1fr 1fr;
}

/* Even rows put the content column first, so the heading sits on the right. */
.service-row:nth-child(even) .service-content-col {
	order: -1;
}

/* The heading + text pin (position: sticky) so they stay put while the taller
   image scrolls past, then release as the row leaves. There is deliberately NO
   transform here: a translateY used to centre the block on top:50vh, but a
   transform also shifts the block in its non-stuck flow positions, so before it
   stuck the title sat above the image top and after it released the text ended
   above the image bottom. Without it the block rests at the column top (= image
   top) before sticking and rides to the column bottom (= image bottom) after, so
   the edges line up; top: 38vh is just where it holds while stuck. */
.service-heading-inner {
	position: sticky;
	top: 38vh;
}

.service-heading {
	font-size: clamp(34px, 5vw, 55px);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 0.95;
}

/* Zero-padded index above each heading (01, 02, …). */
.service-heading::before {
	color: var(--muted);
	content: counter(svc, decimal-leading-zero);
	display: block;
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.08em;
	margin-bottom: 22px;
}

/* A tall image (taller than the viewport) is what gives the sticky heading room to
   stay pinned while the picture scrolls past it. Capped so it can't run away on very
   tall screens. Landscape sources are cropped to this portrait via object-fit below. */
.service-figure {
	height: 130vh;
	margin: 0;
	max-height: 1250px;
	overflow: hidden;
}

.service-figure img {
	height: 100%;
	object-fit: cover;
	width: 100%;
}

.service-text {
	margin-top: 30px;
}

.service-text p {
	color: #55555b;
	font-size: 17px;
	line-height: 1.7;
}

.service-text p + p {
	margin-top: 18px;
}

/* ---------- About page: two-column "who we are" ---------- */
/* Bilingual section title on the left (~1/3), stacked items on the right (~2/3). */
.about-split {
	display: grid;
	gap: 48px 80px;
	grid-template-columns: 1fr 2fr;
}

.about-split-title {
	font-size: clamp(34px, 5vw, 55px);
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1.02;
}

.about-item + .about-item {
	margin-top: 64px;
}

.about-item-title {
	font-size: clamp(22px, 2.4vw, 28px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.2;
}

.about-item p {
	color: #55555b;
	font-size: 16px;
	margin-top: 18px;
}

/* The 18px above sits the text under the item title. When an item has no title
   the first paragraph leads the block, so it must not carry that offset — it
   only matches while no <h3> precedes it. */
.about-item p:first-child {
	margin-top: 0;
}

/* Manifesto variant: the right column is plain stacked paragraphs. */
.about-split-body > p {
	color: #55555b;
	font-size: 18px;
	line-height: 1.7;
}

.about-split-body > p + p {
	margin-top: 24px;
}

/* ---------- About page: scroll-driven zoom gallery ---------- */
/* A pinned section: three images sit as a composition, then the first (left-hand)
   image zooms up to fill the screen as the page scrolls through the pin, while
   the other two shrink and fade away. Each image is transformed on its own — the
   row is never scaled — so the zooming one can travel from the left to the centre
   of the screen as it grows; custom.js drives the transforms/opacity. */
.zoomgal-pin {
	/* Pull up to halve the gap left by the previous section's .pad-lg bottom
	   padding (130px), without altering the shared .pad-lg class. */
	margin-top: -65px;
	position: relative;
}

.zoomgal-sticky {
	height: 100vh;
	overflow: hidden;
	/* Seat the composition high in the pin (just clear of the header) rather than
	   dead-centre, so it sits close to the previous section instead of floating in
	   the middle. The zoom scale in custom.js compensates for the raised origin. */
	padding-top: 14vh;
	position: sticky;
	top: 0;
}

.zoomgal-row {
	align-items: center;
	display: flex;
	gap: 2vw;
	justify-content: center;
}

/* All three images are equal in size at first; the zooming one sits above the
   others so it cleanly covers them as it grows to fullscreen. Both are scaled
   about their own centre — the zooming image is translated to the middle of the
   screen at the same time, so its origin stays put. */
.zoomgal-side-img,
.zoomgal-zoom-img {
	height: 46vh;
	object-fit: cover;
	transform-origin: center center;
	width: 30vw;
	will-change: opacity, transform;
}

.zoomgal-side-img {
	z-index: 1;
}

.zoomgal-zoom-img {
	z-index: 2;
}

/* ---------- About page: team accordion ---------- */
/* A full-width list of names; clicking a name expands a panel with a smaller
   portrait. A "+" before each name (rotating to × when open) signals it opens,
   mirroring the fullscreen menu's submenus. Hovering the list dims the other
   names — same effect as the menu. custom.js toggles .is-open. */
/* Shared small section heading + intro line (used by Team and Clients). */
.about-heading {
	font-size: clamp(20px, 2.4vw, 26px);
	font-weight: 600;
	letter-spacing: 0.02em;
	margin-bottom: 16px;
}

.about-lead {
	color: var(--muted);
	font-size: 16px;
	line-height: 1.75;
	margin-bottom: 52px;
	max-width: 560px;
}

/* Team intro: match the Manifesto title/body sizes and colour (the shared
   .about-heading/.about-lead base is kept for the dark Clients section). */
.team-section .about-heading {
	font-size: clamp(34px, 5vw, 55px);
	font-weight: 800;
	letter-spacing: -0.02em;
}

.team-section .about-lead {
	color: #55555b;
	font-size: 18px;
}

.team-accordion {
	border-top: 1px solid var(--line);
	list-style: none;
}

.team-member {
	border-bottom: 1px solid var(--line);
}

.team-name {
	align-items: center;
	background: none;
	border: 0;
	color: var(--ink);
	cursor: pointer;
	display: flex;
	font-family: "Manrope", sans-serif;
	gap: 24px;
	padding: 26px 0;
	text-align: left;
	transition: color 0.3s var(--ease);
	width: 100%;
}

.team-name-text {
	font-size: clamp(30px, 5vw, 45px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1;
	text-transform: uppercase;
}

.team-role {
	color: inherit; /* black by default, and dims with the name on hover */
	font-size: 13px;
	letter-spacing: 0.16em;
	margin-left: auto;
	text-transform: uppercase;
}

/* "+" affordance, built from two bars; rotates to × when the row is open.
   Uses currentColor so it follows the name's colour through the hover dim. */
.team-plus {
	flex: none;
	height: 20px;
	position: relative;
	transition: transform 0.4s var(--ease);
	width: 20px;
}

.team-plus::before, .team-plus::after {
	background: currentColor;
	content: "";
	left: 50%;
	position: absolute;
	top: 50%;
	transform: translate(-50%, -50%);
}

.team-plus::before {
	height: 2px;
	width: 100%;
}

.team-plus::after {
	height: 100%;
	width: 2px;
}

.team-member.is-open .team-plus {
	transform: rotate(135deg);
}

/* Hover dims the other names; the hovered one stays dark (like the menu). */
.team-accordion:hover .team-name {
	color: var(--muted);
}

.team-accordion .team-name:hover {
	color: var(--ink);
}

/* Accordion panel holding the smaller portrait alongside a short bio. */
.team-panel {
	align-items: flex-end;
	display: flex;
	gap: 40px;
	max-height: 0;
	opacity: 0;
	overflow: hidden;
	padding-left: 44px;
	transition: max-height 0.5s var(--ease), opacity 0.4s var(--ease), margin-bottom 0.5s var(--ease), margin-top 0.5s var(--ease);
}

.team-member.is-open .team-panel {
	margin-bottom: 34px;
	margin-top: 20px;
	max-height: 560px;
	opacity: 1;
}

.team-panel img {
	flex: none;
	height: auto;
	max-width: 100%;
	width: 160px;
}

.team-bio {
	color: #55555b;
	font-size: 15px;
	line-height: 1.7;
	max-width: 520px;
}

/* ---------- About page: clients logo grid ---------- */
/* Dark full-bleed section. Locally flipping --line and --muted to light values
   recolours the grid borders and the intro line for the dark ground; the heading
   inherits white from the section colour. */
.clients-section {
	--line: rgba(255, 255, 255, 0.16);
	--muted: rgba(255, 255, 255, 0.55);
	background: var(--ink);
	color: #fff;
	text-align: center;
}

/* Bigger, centred heading + intro so they sit in scale with the team names and
   the footer's "Let's talk". */
.clients-section .about-heading {
	font-size: clamp(34px, 5vw, 55px);
	font-weight: 800;
	letter-spacing: -0.01em;
}

.clients-section .about-lead {
	margin-left: auto;
	margin-right: auto;
}

/* A bordered grid of client logos, each dimmed and desaturated, brightening to
   full on hover. Placeholder logos for now. */
.clients-grid {
	border-left: 1px solid var(--line);
	border-top: 1px solid var(--line);
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	list-style: none;
}

.clients-grid li {
	align-items: center;
	aspect-ratio: 3 / 2;
	border-bottom: 1px solid var(--line);
	border-right: 1px solid var(--line);
	display: flex;
	justify-content: center;
	padding: 32px;
}

.clients-grid img {
	filter: grayscale(1);
	max-height: 46px;
	opacity: 0.55;
	transition: filter 0.3s var(--ease), opacity 0.3s var(--ease);
	width: auto;
}

.clients-grid li:hover img {
	filter: grayscale(0);
	opacity: 1;
}

/* ---------- Work archive: two-column reverse showcase ---------- */
/* A dark page, pulled up under the transparent sticky header (like the contact
   page) so it flows straight into the dark footer. The two columns translate in
   opposite directions while the section is pinned — the left travels up as the
   right travels down (the "reverse" effect); custom.js adds .is-pinned and drives
   the transforms. Without JS, on reduced-motion, or on small screens it stays a
   plain two-column (then single-column) grid, with every title always visible. */
.work-showcase {
	background: var(--ink);
	color: #fff;
	margin-top: -111px;
	padding-bottom: 120px;
	padding-top: 111px;
}

/* Intro: eyebrow, big title, project count and the filter bar. */
.showcase-intro {
	padding-bottom: 64px;
	padding-top: 96px;
	text-align: center;
}

.showcase-eyebrow {
	color: rgba(255, 255, 255, 0.55);
	display: block;
	font-family: "Manrope", sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.showcase-title {
	font-size: clamp(46px, 8vw, 96px);
	font-weight: 700;
	letter-spacing: -0.03em;
	line-height: 0.96;
	margin-top: 18px;
}

.showcase-count {
	color: rgba(255, 255, 255, 0.55);
	display: block;
	font-size: 13px;
	letter-spacing: 0.16em;
	margin-top: 20px;
	text-transform: uppercase;
}

/* Filter pills (the active one fills white). They live only in the fixed bottom
   bar now — see .showcase-nav-filters. */
.showcase-filter {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, 0.28);
	border-radius: 999px;
	color: #fff;
	cursor: pointer;
	font-family: "Manrope", sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.04em;
	padding: 11px 24px;
	/* The pill is a <button> on the /works/ archive, where it filters in place, and
	   an <a> on a category archive and on a single work, where it navigates. */
	text-decoration: none;
	transition: background 0.3s var(--ease), border-color 0.3s var(--ease), color 0.3s var(--ease);
}

.showcase-filter:hover {
	border-color: #fff;
}

.showcase-filter.is-active {
	background: #fff;
	border-color: #fff;
	color: var(--ink);
}

/* Pin wrapper: custom.js sets its height so vertical scroll drives the columns;
   the sticky viewport pins them while the page scrolls through it. */
.showcase-pin {
	position: relative;
}

/* Pull the pinned pin up under the transparent header (matching .work-showcase's
   own -111px) so the sticky sits at the very top of the viewport from load. Without
   this the title screen starts pushed down by the full-height header and only snaps
   to true centre once the sticky engages a scroll later. Desktop-only (pinned). */
.showcase-pin.is-pinned {
	margin-top: -111px;
}

.showcase-pin.is-pinned .showcase-sticky {
	height: 100vh;
	overflow: hidden;
	position: sticky;
	top: 0;
}

/* Title screen: while pinned it overlays the columns, centered, and custom.js
   fades it out (opacity + a slight rise) as the reader scrolls into the works.
   Unpinned (fallback / no-JS) it falls back to the shared static intro block. */
.showcase-pin.is-pinned .showcase-intro {
	align-items: center;
	display: flex;
	flex-direction: column;
	inset: 0;
	justify-content: center;
	padding: 0 24px;
	position: absolute;
	will-change: opacity, transform;
	z-index: 3;
}

/* Empty state (no works): the shared intro as a tall centered block. */
.showcase-intro-static {
	padding-bottom: 120px;
	padding-top: 140px;
}

.showcase-cols {
	align-items: start;
	display: grid;
	gap: 0 40px;
	grid-template-columns: 1fr 1fr;
}

/* While pinned the columns start hidden; custom.js fades and slides them in
   during the reveal, then drives the opposing scroll. */
.showcase-pin.is-pinned .showcase-col {
	opacity: 0;
}

.showcase-col {
	will-change: opacity, transform;
}

.showcase-card + .showcase-card {
	margin-top: 12vh;
}

.showcase-card.is-hidden {
	display: none;
}

.showcase-card-link {
	color: inherit;
	display: block;
	text-decoration: none;
}

/* Each card is a portrait image sized to the viewport height, so at each step
   one card per column sits centred on screen with its neighbours peeking. The
   title and category are laid over the bottom of the image (a scrim keeps them
   legible over any picture or placeholder). */
.showcase-card-media {
	background: rgba(255, 255, 255, 0.05);
	height: 78vh;
	margin: 0 auto;
	max-width: 100%;
	overflow: hidden;
	position: relative;
	width: calc(78vh * 3 / 4);
}

.showcase-card-media img {
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ease);
	width: 100%;
}

.showcase-card-link:hover .showcase-card-media img {
	transform: scale(1.05);
}

/* Bottom scrim for the overlaid caption. */
.showcase-card-media::after {
	background: linear-gradient(to top, rgba(20, 20, 22, 0.74) 0%, rgba(20, 20, 22, 0) 62%);
	bottom: 0;
	content: "";
	height: 58%;
	left: 0;
	pointer-events: none;
	position: absolute;
	right: 0;
	z-index: 1;
}

.showcase-card-index {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: 13px;
	font-weight: 600;
	left: 22px;
	letter-spacing: 0.12em;
	mix-blend-mode: difference;
	position: absolute;
	top: 20px;
	z-index: 2;
}

.showcase-card-caption {
	bottom: 0;
	left: 0;
	padding: 30px;
	position: absolute;
	right: 0;
	z-index: 2;
}

.showcase-card-title {
	color: #fff;
	font-size: clamp(24px, 2.4vw, 34px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.1;
}

.showcase-card-cat {
	color: rgba(255, 255, 255, 0.72);
	display: block;
	font-size: 12px;
	letter-spacing: 0.16em;
	margin-top: 10px;
	text-transform: uppercase;
}

.showcase-empty {
	color: rgba(255, 255, 255, 0.55);
	font-size: 16px;
	padding: 40px 0 120px;
	text-align: center;
}

/* Fixed bottom bar, visible from load: Prev (far left), the category filters
   (centre column), Next (far right). The 1fr auto 1fr grid keeps the filters
   centred whatever the side widths. custom.js fades the whole bar out (inline
   opacity) as the footer arrives; it is hidden on small screens (media block). */
.showcase-nav {
	align-items: center;
	bottom: 36px;
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	left: 0;
	padding: 0 40px;
	position: fixed;
	right: 0;
	transition: opacity 0.4s var(--ease);
	z-index: 45;
}

/* Category filters — the centre column of the bottom bar. */
.showcase-nav-filters {
	align-items: center;
	display: flex;
	gap: 8px;
	justify-self: center;
}

.showcase-nav .showcase-filter {
	align-items: center;
	background: rgba(20, 20, 22, 0.55);
	display: inline-flex;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.04em;
	padding: 11px 24px;
}

.showcase-nav .showcase-filter.is-active {
	background: #fff;
	color: var(--ink);
}

/* Lighten the fill on hover. */
.showcase-nav .showcase-filter:not(.is-active):hover {
	background: rgba(255, 255, 255, 0.16);
	border-color: #fff;
}

/* Prev / Next: styled identically to the filter pills, pinned to the outer
   columns of the bar. On the archive they are buttons that snap to the previous /
   next centred pair (custom.js disables them at the ends); on a single work they
   are links to the neighbouring project, and a <span> where there is none. */
.showcase-nav-btn {
	align-items: center;
	background: rgba(20, 20, 22, 0.55);
	border: 1px solid rgba(255, 255, 255, 0.28);
	border-radius: 999px;
	color: #fff;
	cursor: pointer;
	display: inline-flex;
	font-family: "Manrope", sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.04em;
	padding: 11px 24px;
	text-decoration: none;
	transition: background 0.25s var(--ease), border-color 0.25s var(--ease), opacity 0.25s var(--ease);
}

.showcase-nav-prev {
	justify-self: start;
}

.showcase-nav-next {
	justify-self: end;
}

.showcase-nav-btn:not(.is-disabled):hover {
	background: rgba(255, 255, 255, 0.16);
	border-color: #fff;
}

.showcase-nav-btn.is-disabled,
.showcase-nav-btn:disabled {
	cursor: default;
	opacity: 0.3;
}

/* The same bar on a single work (parts/work-nav.php) keeps the archive's
   translucent fill. Only the current category needs adjusting: its white pill would
   otherwise carry a white border and vanish against the project page's white, so it
   takes an ink outline there. */
.showcase-nav-single .showcase-filter.is-active {
	border-color: var(--ink);
}

/* ---------- Front page: full-screen "impact" panels ---------- */
/* Full-bleed image panels shown one at a time. custom.js scroll-jacks this page
   (adds .is-jacked): each scroll step plays a transition where the current panel
   shrinks and slides up off the top while the next grows in from below. Without a
   fine pointer, or under reduced motion, the panels fall back to a plain 100vh
   stack that scrolls natively (dots jump with scrollIntoView). */

/* Pull the first panel up under the transparent sticky header so it fills the
   viewport from the very top (matches the about hero's -111px desktop offset). */
.impact {
	display: block;
	margin-top: -111px;
}

/* Fallback (no scroll-jack): panels are a normal-flow stack, each a full screen. */
.impact-panel {
	height: 100vh;
	overflow: hidden;
	position: relative;
}

/* Scroll-jacked: the section is a single fixed-height viewport window and the
   panels are stacked on top of each other, moved between three states — below
   (default, waiting), current (in view) and prev (gone up and shrunk). */
.impact.is-jacked {
	background: var(--ink);
	height: 100vh;
	overflow: hidden;
	position: relative;
}

.impact.is-jacked .impact-panel {
	inset: 0;
	position: absolute;
	transform: translateY(100%) scale(0.8);
	transition: transform 0.9s var(--ease);
	will-change: transform;
}

.impact.is-jacked .impact-panel.is-current {
	transform: translateY(0) scale(1);
	z-index: 2;
}

.impact.is-jacked .impact-panel.is-prev {
	transform: translateY(-100%) scale(0.8);
	z-index: 1;
}

/* The overlay holding the centred text: a full-cover layer stacked above the image
   (z0) and scrim (z1). On most panels it is a link (.impact-link) covering the whole
   panel; the first panel is a non-clickable .impact-static instead. The header (z60)
   and dots (z40) sit above it, so those stay independently clickable. */
.impact-link, .impact-static {
	align-items: center;
	color: inherit;
	display: flex;
	inset: 0;
	justify-content: center;
	position: absolute;
	text-decoration: none;
	z-index: 2;
}

.impact-media {
	inset: 0;
	position: absolute;
	z-index: 0;
}

.impact-media img {
	height: 100%;
	object-fit: cover;
	width: 100%;
}

/* Dark scrim so the overlaid white text stays legible over any image. */
.impact-panel::after {
	background: linear-gradient(180deg, rgba(20, 20, 22, 0.35) 0%, rgba(20, 20, 22, 0.55) 100%);
	content: "";
	inset: 0;
	position: absolute;
	z-index: 1;
}

.impact-inner {
	text-align: center;
}

.impact-eyebrow {
	color: #fff;
	display: block;
	font-family: "Manrope", sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.16em;
	margin-bottom: 26px;
	text-transform: uppercase;
}

.impact-title {
	color: #fff;
	font-size: clamp(40px, 6vw, 88px);
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.02;
	margin: 0 auto;
	max-width: 15ch;
}

.impact-cta {
	background: #fff;
	border-radius: 999px;
	color: var(--ink);
	display: inline-block;
	font-family: "Manrope", sans-serif;
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.04em;
	margin-top: 40px;
	padding: 16px 34px;
	text-decoration: none;
	transition: background 0.4s var(--ease), color 0.4s var(--ease), transform 0.4s var(--ease);
}

/* Hovering anywhere on the panel (the whole link) animates the pill. */
.impact-cta:hover, .impact-link:hover .impact-cta {
	background: var(--ink);
	color: #fff;
	transform: translateY(-2px);
}

/* Vertical dot navigation pinned to the right edge; one dot per panel. */
.impact-dots {
	display: flex;
	flex-direction: column;
	gap: 16px;
	position: fixed;
	right: 34px;
	top: 50%;
	transform: translateY(-50%);
	z-index: 40;
}

.impact-dot {
	background: transparent;
	border: 0;
	cursor: pointer;
	height: 22px;
	padding: 0;
	position: relative;
	width: 22px;
}

.impact-dot::after {
	background: rgba(255, 255, 255, 0.45);
	border-radius: 50%;
	content: "";
	height: 8px;
	left: 50%;
	position: absolute;
	top: 50%;
	transform: translate(-50%, -50%);
	transition: background 0.3s var(--ease), height 0.3s var(--ease), width 0.3s var(--ease);
	width: 8px;
}

.impact-dot.is-active::after {
	background: #fff;
	height: 12px;
	width: 12px;
}

/* ---------- Contact page ---------- */
/* A dark page that flows seamlessly into the dark footer. The negative top margin
   pulls it under the transparent sticky header (matching the about hero), and the
   matching padding puts the content back below the bar. */
.contact-page {
	background: var(--ink);
	color: #fff;
	margin-top: -111px;
	padding-top: 111px;
}

/* Title centred on top, form below (centred, constrained width). */
.contact-intro {
	margin-bottom: 70px;
	padding-bottom: 100px;
	padding-top: 100px;
	text-align: center;
}

.contact-intro-head {
	margin-bottom: 100px;
}

.contact-form-wrap {
	margin: 0 auto;
	max-width: 720px;
	text-align: left;
}

.contact-eyebrow {
	color: #fff;
	display: block;
	font-family: "Manrope", sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.24em;
	text-transform: uppercase;
}

.contact-talk {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: clamp(46px, 8vw, 88px);
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1;
	margin-top: 16px;
	text-transform: uppercase;
}

/* Contact Form 7: two fields per row (name/email), then full-width subject/message.
   The [contact-form-7] wrapper and each field's <p> get reset so the grid controls
   spacing. */
.contact-form-wrap .wpcf7 {
	margin: 0;
}

.contact-form-grid {
	display: grid;
	gap: 30px;
	grid-template-columns: 1fr 1fr;
}

.contact-form-field {
	margin: 0;
}

.contact-form-field--full {
	grid-column: 1 / -1;
}

/* Visually-hidden labels: fields show placeholders, but each keeps an accessible
   name for screen readers. */
.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* Dark, transparent fields with an underline; white text and white placeholders. */
.contact-form-field input,
.contact-form-field textarea {
	background: transparent;
	border: 0;
	border-bottom: 1px solid rgba(255, 255, 255, 0.3);
	color: #fff;
	font-family: "Roboto Flex", "Helvetica Neue", Arial, sans-serif;
	font-size: 16px;
	padding: 12px 0;
	transition: border-color 0.3s var(--ease);
	width: 100%;
}

.contact-form-field textarea {
	min-height: 130px;
	resize: vertical;
}

.contact-form-field input:focus,
.contact-form-field textarea:focus {
	border-bottom-color: #fff;
	outline: 0;
}

.contact-form-field input::placeholder,
.contact-form-field textarea::placeholder {
	color: #fff;
	opacity: 1;
}

.contact-form-actions {
	margin: 40px 0 0;
	position: relative;
	text-align: center;
}

/* Take the CF7 spinner out of flow so it can't push the submit off-centre;
   it sits at the right edge, vertically aligned with the button. */
.contact-form-wrap .wpcf7-spinner {
	margin: 0;
	position: absolute;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
}

/* Submit: white pill, inverting on hover (matches the front-page CTA). */
.contact-form-wrap .wpcf7-submit {
	background: #fff;
	border: 0;
	border-radius: 999px;
	color: var(--ink);
	cursor: pointer;
	font-family: "Manrope", sans-serif;
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.04em;
	padding: 16px 38px;
	transition: background 0.4s var(--ease), color 0.4s var(--ease), transform 0.4s var(--ease);
}

.contact-form-wrap .wpcf7-submit:hover {
	background: rgba(255, 255, 255, 0.85);
	transform: translateY(-2px);
}

/* CF7 feedback: validation tips and the response line, legible on the dark page. */
.contact-form-wrap .wpcf7-not-valid-tip {
	color: #ff8a8a;
	font-size: 13px;
	margin-top: 8px;
}

.contact-form-wrap .wpcf7-response-output {
	border-color: rgba(255, 255, 255, 0.3);
	color: #fff;
	font-size: 14px;
	margin: 30px 0 0;
	padding: 14px 18px;
}

/* Contact details: a centred row of items, each stacked icon / value / small label. */
.contact-details {
	margin-bottom: 100px;
	padding-bottom: 100px;
	text-align: center;
}

.contact-info {
	display: flex;
	flex-wrap: wrap;
	gap: 40px 72px;
	justify-content: center;
	list-style: none;
}

.contact-info-item {
	align-items: center;
	display: flex;
	flex-direction: column;
	min-width: 200px;
}

.contact-info-icon {
	height: 30px;
	margin-bottom: 18px;
	width: 30px;
}

.contact-info-value {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: clamp(18px, 2.4vw, 24px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.35;
	text-decoration: none;
}

a.contact-info-value {
	transition: color 0.3s var(--ease);
}

a.contact-info-value:hover {
	color: rgba(255, 255, 255, 0.6);
}

.contact-info-label {
	color: rgba(255, 255, 255, 0.55);
	font-family: "Manrope", sans-serif;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.18em;
	margin-top: 14px;
	text-transform: uppercase;
}

/* Find us: section title above the (placeholder) map image. */
.contact-map-section {
	padding-bottom: 120px;
}

/* "Find us" echoes the "Let's talk" title: centred, uppercase and large. */
.contact-map-title {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: clamp(46px, 8vw, 88px);
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1;
	margin-bottom: 90px;
	text-align: center;
	text-transform: uppercase;
}

/* Google Maps renders into this box and needs a height of its own — it used to
   inherit one from the placeholder image that lived here. The 16/7 ratio keeps
   the proportions that image had; min-height stops the map collapsing to a
   letterbox on narrow screens, where the ratio alone would leave ~160px.
   Note there is deliberately no `.contact-map img` rule: Google builds the map
   out of <img> tiles, and sizing them here would tear the tiling apart. */
.contact-map {
	aspect-ratio: 16 / 7;
	background: #000;
	min-height: 320px;
	width: 100%;
}

/* ---------- "Let's talk" popup (footer) ---------- */
/* A centred dark dialog holding the contact form; reuses the .contact-form-*
   styling. Hidden until custom.js adds .is-open. */
.talk-modal {
	align-items: center;
	display: flex;
	inset: 0;
	justify-content: center;
	opacity: 0;
	padding: 24px;
	position: fixed;
	transition: opacity 0.4s var(--ease), visibility 0.4s var(--ease);
	visibility: hidden;
	z-index: 80;
}

.talk-modal.is-open {
	opacity: 1;
	visibility: visible;
}

.talk-modal-overlay {
	background: rgba(15, 15, 17, 0.72);
	inset: 0;
	position: absolute;
}

.talk-modal-dialog {
	background: var(--ink);
	border-radius: 14px;
	max-height: 90vh;
	max-width: 760px;
	overflow-y: auto;
	padding: 60px 56px;
	position: relative;
	text-align: center;
	transform: translateY(24px);
	transition: transform 0.4s var(--ease);
	width: 100%;
}

.talk-modal.is-open .talk-modal-dialog {
	transform: none;
}

.talk-modal-close {
	background: none;
	border: 0;
	color: #fff;
	cursor: pointer;
	font-size: 32px;
	line-height: 1;
	padding: 4px;
	position: absolute;
	right: 22px;
	top: 16px;
}

.talk-modal-title {
	color: #fff;
	font-family: "Manrope", sans-serif;
	font-size: clamp(34px, 5vw, 52px);
	font-weight: 800;
	letter-spacing: -0.02em;
	line-height: 1;
	margin: 14px 0 44px;
	text-transform: uppercase;
}

/* ---------- Single blog post ---------- */
/* Reuses the work single's title hero + narrow reading column, on white. */

/* "Stacking" gallery: up to three images, each climbing up to cover the previous
   one while the gallery is pinned to the viewport. The motion is scroll-driven in
   JavaScript (see the .post-gallery block in custom.js) — CSS sticky cannot hold an
   outgoing image in place while the next fully covers it, so the effect is done
   with transforms, matching the reference and the theme's other galleries.
   Two states:
   - Base (below): the JS-off / reduced-motion fallback. Images just stack in normal
     flow with a little space between them.
   - .is-pinned (added by the script): .post-gallery becomes a tall scroll track and
     .post-gallery-viewport pins to the viewport as a full-height stage; each image
     is absolutely stacked inside it and positioned every frame by the script. Later
     images sit above earlier ones (DOM order = paint order), so each covers the one
     before with no z-index needed. */
.post-gallery {
	margin-bottom: 40px;
	margin-top: 24px;
}

.post-gallery-item {
	margin-bottom: 24px;
}

.post-gallery-item:last-child {
	margin-bottom: 0;
}

/* height:auto is load-bearing, not tidiness. These images carry width/height
   attributes, and the height attribute lands as a presentational hint — which
   author CSS outranks, but only if it actually sets height. Without this the box
   is width:100% AND height:1525px, both axes definite, so aspect-ratio is ignored
   entirely and the image renders full-height. The pin script measures that height
   to centre each frame, so it takes the effect down with it. */
.post-gallery-item img {
	aspect-ratio: 16 / 9;
	background: #fff;
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

.post-gallery.is-pinned .post-gallery-viewport {
	height: 100vh;
	overflow: hidden;
	position: sticky;
	top: 0;
}

.post-gallery.is-pinned .post-gallery-item {
	left: 0;
	margin: 0;
	position: absolute;
	top: 0;
	width: 100%;
	will-change: transform;
}

/* Reading column: post content blocks styled to match the site's body copy. */
.post-content > :first-child {
	margin-top: 0;
}

.post-content h2,
.post-content h3,
.post-content h4 {
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.2;
}

.post-content h2 {
	font-size: clamp(34px, 5vw, 55px);
	font-weight: 800;
	margin-top: 56px;
}

.post-content h3 {
	font-size: clamp(23px, 2.4vw, 30px);
	margin-top: 48px;
}

.post-content h4 {
	font-size: clamp(20px, 2vw, 24px);
	margin-top: 40px;
}

.post-content p {
	color: #55555b;
	font-size: 16px;
	line-height: 1.7;
	margin-top: 22px;
}

.post-content a {
	color: var(--ink);
	text-decoration: underline;
	text-underline-offset: 3px;
	transition: color 0.3s var(--ease);
}

.post-content a:hover {
	color: var(--muted);
}

.post-content blockquote {
	border-left: 2px solid var(--ink);
	font-family: "Manrope", sans-serif;
	font-size: clamp(22px, 3vw, 30px);
	font-weight: 600;
	letter-spacing: -0.01em;
	line-height: 1.3;
	margin: 48px 0;
	padding-left: 40px;
}

.post-content blockquote p {
	color: var(--ink);
	font-size: inherit;
	margin-top: 0;
}

.post-content ul,
.post-content ol {
	color: #55555b;
	font-size: 16px;
	line-height: 1.7;
	margin-top: 22px;
	padding-left: 24px;
}

.post-content li {
	margin-top: 8px;
}

.post-content img {
	height: auto;
	margin: 40px 0;
	width: 100%;
}

/* Tags */
.post-tags {
	border-top: 1px solid var(--line);
	color: var(--muted);
	font-size: 13px;
	letter-spacing: 0.06em;
	margin-top: 56px;
	padding-top: 28px;
}

.post-tags-label {
	color: var(--ink);
	font-family: "Manrope", sans-serif;
	font-weight: 700;
	margin-right: 14px;
}

.post-tags a {
	color: var(--muted);
	text-decoration: none;
	transition: color 0.3s var(--ease);
}

.post-tags a:hover {
	color: var(--ink);
}

/* Previous / next navigation */
.post-nav {
	border-top: 1px solid var(--line);
	display: flex;
	gap: 40px;
	justify-content: space-between;
	margin-bottom: 130px;
	padding-top: 44px;
}

.post-nav-item {
	display: flex;
	flex-direction: column;
	gap: 12px;
	max-width: 46%;
}

.post-nav-next {
	text-align: right;
}

.post-nav-cap {
	color: var(--muted);
	font-size: 12px;
	letter-spacing: 0.16em;
	text-transform: uppercase;
}

.post-nav-title {
	color: var(--ink);
	font-family: "Manrope", sans-serif;
	font-size: clamp(22px, 2.4vw, 30px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.15;
	text-decoration: none;
	transition: color 0.3s var(--ease);
}

a.post-nav-title:hover {
	color: var(--muted);
}

.post-nav-item.is-disabled .post-nav-title {
	color: var(--muted);
}

/* ---------- Blog listing (Blog / category) ---------- */
/* Dark page (like the works archive), pulled under the header and flowing into
   the dark footer; a works-archive-style intro (reusing .showcase-intro) over an
   alternating asymmetric grid: rows of two cards that swap wide/narrow each row.
   The grid uses 8 tracks — wide cards span 5, narrow span 3 — so each pair fills
   a row and the columns alternate down the page. */
.blog-listing {
	background: var(--ink);
	color: #fff;
	margin-top: -111px;
	padding-bottom: 120px;
	padding-top: 111px;
}

.story-grid {
	align-items: start;
	display: grid;
	gap: 70px 40px;
	grid-template-columns: repeat(8, 1fr);
}

.story-card--wide {
	grid-column: span 5;
}

.story-card--narrow {
	grid-column: span 3;
}

.story-card-link {
	color: inherit;
	display: block;
	text-decoration: none;
}

.story-card-media {
	aspect-ratio: 3 / 2;
	background: rgba(255, 255, 255, 0.05);
	overflow: hidden;
}

.story-card-media img {
	height: 100%;
	object-fit: cover;
	transition: transform 0.7s var(--ease);
	width: 100%;
}

.story-card-link:hover .story-card-media img {
	transform: scale(1.05);
}

.story-card-title {
	font-size: clamp(24px, 2.4vw, 34px);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.15;
	margin-top: 22px;
}

.story-card-date {
	color: rgba(255, 255, 255, 0.55);
	display: block;
	font-size: 12px;
	letter-spacing: 0.16em;
	margin-top: 12px;
	text-transform: uppercase;
}

@media (max-width: 900px) {
	.work-showcase {
		margin-top: -107px; /* mobile header: 75px logo + 2×16px padding */
		padding-bottom: 80px;
		padding-top: 107px;
	}

	.showcase-intro {
		padding-bottom: 48px;
		padding-top: 64px;
	}

	.showcase-cols {
		gap: 0 20px;
		grid-template-columns: 1fr;
	}

	/* Stacked single column: cards flow at their natural 3:4 size (no viewport
	   sizing, no pinning), so every title stays visible while scrolling. */
	.showcase-card-media {
		aspect-ratio: 3 / 4;
		height: auto;
		width: 100%;
	}

	.showcase-card + .showcase-card {
		margin-top: 40px;
	}

	.showcase-col + .showcase-col {
		margin-top: 40px; /* keep rhythm where the two columns stack into one */
	}

	.showcase-nav {
		display: none;
	}
}

@media (max-width: 900px) {
	.about-hero {
		height: 74vh;
		margin-top: -107px; /* mobile header: 75px logo + 2×16px padding */
		min-height: 420px;
	}

	/* Single column here, so the subtitle returns to the centred flow under the
	   title rather than being anchored to the hero's bottom. */
	.about-hero--services {
		height: 82vh;
	}

	.about-hero--services .about-hero-subtitle {
		bottom: auto;
		left: auto;
		margin: 22px auto 0;
		position: static;
		right: auto;
	}

	.about-split {
		gap: 32px;
		grid-template-columns: 1fr;
	}

	.about-item + .about-item {
		margin-top: 44px;
	}

	.zoomgal-pin {
		margin-top: -40px; /* half the mobile .pad-lg bottom (80px) */
	}

	.team-name {
		flex-wrap: wrap;
		gap: 16px;
	}

	.team-role {
		flex-basis: 100%;
		margin-left: 36px;
		margin-top: 8px;
	}

	.team-panel {
		align-items: flex-start;
		flex-direction: column;
		gap: 24px;
		padding-left: 36px;
	}

	.clients-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 900px) {
	.impact {
		margin-top: -107px; /* mobile header: 75px logo + 2×16px padding */
	}

	.impact-dots {
		right: 18px;
	}
}

@media (max-width: 900px) {
	.contact-page {
		margin-top: -107px; /* mobile header: 75px logo + 2×16px padding */
		padding-top: 107px;
	}

	.contact-intro {
		padding-bottom: 70px;
		padding-top: 70px;
	}

	.contact-form-grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 900px) {
	.post-gallery-item {
		--post-gallery-h: calc((min(var(--maxw), 100vw) - 44px) * 9 / 16);
	}

	.post-nav {
		flex-direction: column;
		gap: 32px;
		margin-bottom: 80px;
	}

	.post-nav-item {
		max-width: 100%;
	}

	.post-nav-next {
		text-align: left;
	}

	.blog-listing {
		margin-top: -107px; /* mobile header: 75px logo + 2×16px padding */
		padding-bottom: 80px;
		padding-top: 107px;
	}

	.story-grid {
		gap: 44px 0;
		grid-template-columns: 1fr;
	}

	.story-card--wide,
	.story-card--narrow {
		grid-column: 1 / -1;
	}
}

@media (max-width: 900px) {
	.services-sections {
		padding-bottom: 80px;
		padding-top: 80px;
	}

	.service-row + .service-row {
		margin-top: 72px;
	}

	.service-grid {
		gap: 24px;
		grid-template-columns: 1fr;
	}

	/* Single column: heading always leads, and it no longer pins. */
	.service-row:nth-child(even) .service-content-col {
		order: 0;
	}

	.service-heading-inner {
		position: static;
	}

	/* A normal portrait crop reads better than a viewport-tall image in one column. */
	.service-figure {
		aspect-ratio: 3 / 4;
		height: auto;
		max-height: none;
	}
}