/* ============================================================================
   Jared Lockhart — main stylesheet
   Design tokens come from theme.json as CSS custom properties:
     --wp--preset--color--*, --wp--preset--font-size--*, --wp--preset--spacing--*,
     --wp--preset--font-family--*
   ============================================================================ */

/* --------------------------------------------------------------------------
   1. Reset / base
   -------------------------------------------------------------------------- */

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

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

body {
	margin: 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--base);
	line-height: 1.4;
	color: var(--wp--preset--color--foreground);
	background: var(--wp--preset--color--background);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

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

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

p { margin: 0 0 1em; }

ul, ol { margin: 0; padding: 0; list-style: none; }

button {
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	color: inherit;
	cursor: pointer;
}

/* Accessibility — skip link visible on focus only */
.skip-link {
	position: absolute;
	left: -10000px;
	top: auto;
	width: 1px;
	height: 1px;
	overflow: hidden;
	z-index: 9999;
}
.skip-link:focus {
	left: var(--wp--preset--spacing--md);
	top: var(--wp--preset--spacing--md);
	width: auto;
	height: auto;
	padding: var(--wp--preset--spacing--sm) var(--wp--preset--spacing--md);
	background: var(--wp--preset--color--foreground);
	color: var(--wp--preset--color--background);
}

.screen-reader-text {
	position: absolute !important;
	clip: rect(1px, 1px, 1px, 1px);
	width: 1px; height: 1px;
	overflow: hidden;
}

/* --------------------------------------------------------------------------
   2. Layout helpers
   -------------------------------------------------------------------------- */

/* Outer page gutter — scales 20 → 50px (matches the 50px design margin) */
:root {
	--page-gutter: clamp(20px, 3vw, 50px);
	/* Section-to-section gap — used between the page frame, hero, and footer.
	   Scales in lockstep with the gutter so the visual rhythm stays consistent
	   from mobile to desktop. Desktop target = 40px (designer's spec). */
	--jl-section-gap: clamp(24px, 2.8vw, 40px);
	/* Logo dimensions — width drives, height follows the SVG aspect ratio
	   567 × 291 (~1.948:1). Height clamp = width clamp × 291/567 = × 0.5132. */
	--jl-logo-width:  clamp(220px, 24vw, 360px);
	--jl-logo-height: clamp(113px, 12.32vw, 185px);

	/* Space below the logo before the next frame element (frame bottom on the
	   home and projects-landing templates, the project meta hairline on single
	   project). Defined once so every framed template stays in lockstep —
	   change here and every page updates. */
	--jl-frame-pad-below-logo: calc(var(--jl-logo-height) + var(--jl-section-gap));

	/* Additional inset for cover + gallery images and the bottom nav, beyond
	   the standard page-gutter. Keeps images narrower than the framed text
	   box above so the two don't share a left/right edge. ~32px at 1922vp
	   per the Figma "Projects B" mockup. */
	--jl-image-inset: clamp(15px, 1.7vw, 32px);

	/* --- Modular type scale ------------------------------------------------
	   --jl-text-base is the anchor — think of it as our "rem". Every other
	   step in the bespoke templates derives from it via a calc() multiplier,
	   so changing this single value rescales the whole hierarchy in one move.
	   Ratios come from the Figma "Projects B" mockup, with the user's
	   override that intro = body × 1.3 (vs Figma's 1.6).

	     base    × 1.0 → body copy, eyebrows, credits, nav
	     display × 1.4 → project title + location value (Larish Semibold)
	     intro   × 1.6 → hero pull-quote (matches Figma 48 / 30)
	   --------------------------------------------------------------------- */
	--jl-text-base:    clamp(18px, 1.55vw, 24px);
	--jl-text-display: calc(var(--jl-text-base) * 1.4);
	--jl-text-intro:   calc(var(--jl-text-base) * 1.6);
}

.site-main {
	min-height: 60vh;
	width: calc(100% - 2 * var(--page-gutter));
	max-width: 1600px;
	margin-left: auto;
	margin-right: auto;
}

/* --------------------------------------------------------------------------
   Page frame — the recurring hairline olive rectangle from the Figma.
   Used per-template (front-page, projects landing, single project, studio).
   Templates that don't need it (How we work) simply don't render this wrapper.
   Whatever content the template puts inside grows the frame naturally;
   anything rendered AFTER the closing </div> sits outside the frame.
   -------------------------------------------------------------------------- */

.jl-page-frame {
	position: relative;
	margin: var(--jl-section-gap) auto 0;
	width: calc(100% - 2 * var(--page-gutter));
	max-width: 1600px;
	border: 1.35px solid var(--wp--preset--color--accent);
	/* Default bottom padding gives the frame visible height below the nav.
	   Per-template modifiers below can override this. */
	padding-bottom: var(--wp--preset--spacing--xxl);
}

/* Per-template heights. The gap directly below the logo is the same on every
   framed page — it's driven by --jl-frame-pad-below-logo so all three
   templates stay aligned. Per-template modifiers only override behaviour
   that legitimately differs (e.g. the single project page extends past the
   frame to render the meta + gallery). */
.jl-page-frame--home,
.jl-page-frame--projects {
	padding-bottom: var(--jl-frame-pad-below-logo);
}

.jl-page-frame--project {
	padding-bottom: var(--jl-section-gap);  /* tight bottom — project meta determines the height */
}

/* Below the frame: matching section gap before the next block (e.g. hero) */
.jl-page-frame + .site-main > * {
	margin-top: var(--jl-section-gap);
}

/* --------------------------------------------------------------------------
   3. Site header
   Design notes:
     - Desktop: SVG wordmark top-left, three nav items top-right.
       Big top padding (~80px) before the hero starts. All text #000.
     - Mobile (default): smaller wordmark top-left, hamburger top-right.
     - Mobile (.nav-open on body): wordmark + hamburger hidden; X close icon
       takes the wordmark slot; menu list appears below it (olive #3C411E,
       regular weight; current item Medium 500).
   -------------------------------------------------------------------------- */

.site-header {
	padding: var(--wp--preset--spacing--xl) var(--page-gutter) 0;
	position: relative;
	z-index: 10;
}

/* When the header lives inside a page frame, drop the big standalone-page
   top padding — the frame already provides outer breathing room. */
.jl-page-frame > .site-header {
	padding-top: var(--jl-section-gap);
}

/* Standalone header — used on frameless pages (Studio, How We Work). It
   reproduces the .jl-page-frame box so the blank header space + logo position
   stay consistent with the framed pages, just without the visible border.
   Same margin/width/padding as the frame; the transparent border preserves the
   exact geometry (the framed box's 1.35px border offsets its content the same
   way), so the logo lands in the identical spot. */
.site-header--standalone {
	margin: var(--jl-section-gap) auto 0;
	width: calc(100% - 2 * var(--page-gutter));
	max-width: var(--wp--style--global--wide-size, 1600px);
	box-sizing: border-box;
	border: 1.35px solid transparent;
	padding: var(--jl-section-gap) var(--page-gutter) var(--jl-frame-pad-below-logo);
}

.site-header__inner {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--md);
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1600px);
	margin: 0 auto;
}

/* Logo --------------------------------------------------------------------- */

.site-header__logo {
	display: inline-block;
	flex: 0 0 auto;
	line-height: 0;
}

.site-header__logo-img {
	/* Design has logo 567px wide at 1922 viewport (~29%). We cap at 360 on
	   desktop, never go below 220 on mobile. Width-only — height auto by ratio. */
	width: var(--jl-logo-width);
	height: auto;
}

/* Nav (desktop default) ---------------------------------------------------- */

.site-header__nav {
	flex: 0 0 auto;
}

.site-header__menu {
	display: flex;
	align-items: center;
	gap: clamp(24px, 3vw, 60px);
	margin-right: 60px;
}

.site-header__menu a {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--nav);
	font-weight: 400;
	line-height: 1.1;
	color: var(--wp--preset--color--foreground);
	letter-spacing: 0;
	transition: opacity 0.15s ease;
}

.site-header__menu a:hover {
	opacity: 0.6;
}

/* Active item — WordPress adds .current-menu-item */
.site-header__menu .current-menu-item > a,
.site-header__menu .current-menu-ancestor > a {
	font-weight: 500;
}

/* --- Submenu (Projects → categories) --------------------------------------
   Desktop: hidden by default, revealed on hover or keyboard focus-within.
            Positioned absolutely beneath the parent link.
   Mobile:  always visible, indented under parent (handled in the
            (max-width: 768px) block further down).
   -------------------------------------------------------------------------- */

.site-header__menu .menu-item-has-children {
	position: relative;
}

.site-header__menu .sub-menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

.site-header__menu .sub-menu a {
	/* Slightly smaller than the parent nav (which caps at 24px). Matches the
	   Figma sub-menu where category items are the same family but a step down. */
	font-size: clamp(16px, 1.4vw, 21px);
	font-weight: 400;
	line-height: 1.4;
	color: var(--wp--preset--color--foreground);
}

/* Desktop dropdown */
@media (min-width: 769px) {
	.site-header__menu .menu-item-has-children > .sub-menu {
		position: absolute;
		top: 100%;
		/* Shift the panel left by its own horizontal padding so the items
		   inside align visually with the parent link text (no indent). */
		left: calc(-1 * var(--wp--preset--spacing--md));
		min-width: 200px;
		/* Cream background so the dropdown is readable when it overlaps a
		   hero image or other content sitting below the header. */
		background: var(--wp--preset--color--background);
		/* Gap above first sub-item (matches Figma's empty-line spacing between
		   the parent label and the first category). Horizontal padding gives
		   the items room inside the cream panel. */
		padding: var(--wp--preset--spacing--md) var(--wp--preset--spacing--md) var(--wp--preset--spacing--sm);
		display: flex;
		flex-direction: column;
		gap: 6px;
		opacity: 0;
		visibility: hidden;
		transform: translateY(-4px);
		transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s linear 0.18s;
		pointer-events: none;
	}

	/* Reveal on hover or when any descendant has focus (keyboard a11y) */
	.site-header__menu .menu-item-has-children:hover > .sub-menu,
	.site-header__menu .menu-item-has-children:focus-within > .sub-menu {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
		pointer-events: auto;
		transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s linear 0s;
	}

	.site-header__menu .sub-menu a:hover {
		opacity: 0.6;
	}
}

/* Hamburger / X toggle (mobile only) --------------------------------------- */

.site-header__toggle {
	display: none; /* shown only at mobile breakpoint */
	position: relative;
	width: 32px;
	height: 32px;
	flex: 0 0 auto;
	/* Same olive/dark-green as the logo (#3C411E) — the icon uses currentColor
	   for its bars + square, so this drives both. Matches the open-state too. */
	color: var(--wp--preset--color--accent);
}

.site-header__toggle-icon {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	transition: opacity 0.2s ease;
}

/* Three bars */
.site-header__toggle-icon--bars span {
	display: block;
	height: 3.66px;
	width: 100%;
	background: currentColor;
}

/* Square close icon — shown when nav is open (swaps in for the bars) */
.site-header__toggle-icon--close {
	opacity: 0;
	pointer-events: none;
}
.site-header__toggle-icon--close svg {
	width: 100%;
	height: 100%;
}

/* --------------------------------------------------------------------------
   3b. Compact sticky header
   Sits offscreen above the viewport by default. Slides in once the main
   header has fully scrolled out of view (body.is-scrolled toggled by JS).
   Desktop only — hidden at mobile widths.
   -------------------------------------------------------------------------- */

.site-header-compact {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	background: var(--wp--preset--color--background);
	border-bottom: 1px solid rgba(0, 0, 0, 0.06);
	/* Double gutter on sides so the inner content sits at the same x as the
	   main header's inner (which is inset by frame-margin + header-padding,
	   i.e. 2× the page gutter). Keeps the nav visually identical between
	   the full and sticky states. */
	padding: var(--wp--preset--spacing--md) calc(var(--page-gutter) * 2);
	z-index: 100;
	transform: translateY(-100%);
	transition: transform 0.28s ease;
	will-change: transform;
}

body.is-scrolled .site-header-compact {
	transform: translateY(0);
}

.site-header-compact__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--md);
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1600px);
	margin: 0 auto;
}

.site-header-compact__logo {
	display: inline-block;
	flex: 0 0 auto;
	line-height: 0;
}

.site-header-compact__logo img {
	display: block;
	width: clamp(220px, 22vw, 320px);
	height: auto;
}

/* Re-use most of the main menu styles. The compact-specific overrides keep
   nav items vertically centered against the smaller bar. */
.site-header-compact__menu {
	align-items: center;
}

/* --------------------------------------------------------------------------
   4. Site footer
   Design notes:
     - Hairline 1.35px black divider on top.
     - Tall vertical block (~400px) with wordmark top-left, then big space,
       then a row at the bottom: tagline+email (left) + Instagram (right).
     - All text #000. 30px desktop / 16px mobile.
     - No menu, no social icons, no copyright string per design.
   -------------------------------------------------------------------------- */

.site-footer {
	padding: var(--jl-section-gap) var(--page-gutter);
}

.site-footer__inner {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1600px);
	margin: 0 auto;
	border-top: 1.35px solid var(--wp--preset--color--foreground);
	padding-top: var(--jl-section-gap);
	display: flex;
	flex-direction: column;
	gap: clamp(80px, 18vh, 240px); /* big vertical gap matches the 400px footer */
}

.site-footer__logo {
	/* Match the compact sticky bar's wordmark size for consistency */
	width: clamp(220px, 22vw, 320px);
	height: auto;
}

.site-footer__bottom {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--md);
	flex-wrap: wrap;
}

.site-footer__tagline {
	margin: 0;
	font-size: var(--wp--preset--font-size--nav);
	line-height: 1.2;
	display: flex;
	flex-wrap: wrap;
	gap: clamp(16px, 3vw, 56px);
}

.site-footer__practice {
	display: inline-block;
}

.site-footer__email {
	text-decoration: underline;
	text-underline-offset: 0.18em;
}

.site-footer__social {
	margin: 0;
	font-size: var(--wp--preset--font-size--nav);
}

.site-footer__social a {
	text-decoration: underline;
	text-underline-offset: 0.18em;
}

.site-footer__email:hover,
.site-footer__social a:hover {
	opacity: 0.6;
}

/* --------------------------------------------------------------------------
   5. Mobile breakpoint (≤ 768px)
   -------------------------------------------------------------------------- */

@media (max-width: 768px) {

	/* Compact sticky bar is desktop-only */
	.site-header-compact {
		display: none;
	}

	.site-header {
		padding-top: var(--wp--preset--spacing--md);
	}

	.site-header__inner {
		align-items: flex-start; /* burger + logo align at the top, equal padding above */
	}

	.site-header__logo-img {
		width: 220px; /* min size on mobile, matches min in the clamp() */
	}

	/* Closed header frame (home + projects) is grown to the SAME height as the
	   open nav box, so the bordered box doesn't change size when the menu
	   opens/closes. Mirrors the open panel's height: its top padding
	   (2×page-gutter + the 28.8px scaled close icon) + 3 menu lines & gaps
	   (≈134.4px) + 2 borders (≈2.7px) on top of the shared frame bottom padding.
	   box-sizing is border-box, so min-height is the full box height. */
	.jl-page-frame--home,
	.jl-page-frame--projects,
	.site-header--standalone {
		min-height: calc(var(--jl-frame-pad-below-logo) + 2 * var(--page-gutter) + 165px);
	}

	/* Hamburger is FIXED to the viewport's top-right so it follows the page as
	   you scroll; tapping it opens the full-screen takeover. The top/right
	   offsets reproduce its at-rest spot inside the frame (equal ~21px gaps to
	   the frame's top + right edges) so it doesn't jump when scrolling begins:
	     top   = frame top inset (section-gap) + gap (page-gutter)
	     right = frame side inset (page-gutter) + gap (page-gutter)
	   transform: scale(.9) shrinks the whole icon 10% toward its top-right
	   anchor, so the insets stay put while the glyph reads slightly smaller. */
	.site-header__toggle {
		display: block;
		position: fixed;
		top: calc(var(--jl-section-gap) + var(--page-gutter));
		right: calc(2 * var(--page-gutter));
		transform: scale(0.9);
		transform-origin: top right;
		z-index: 12;
	}

	/* Open menu = an OUTER cream field + an INNER bordered panel.
	   The cream field is full-bleed across the top of the viewport; its padding
	   is the gap of cream shown OUTSIDE the panel border — to the top edge, the
	   left/right edges, and (via padding-bottom) the same gap extending below
	   the panel before the page content resumes. Hidden until body.nav-open. */
	.site-header__nav {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: auto;
		background: var(--wp--preset--color--background);
		padding: var(--jl-section-gap) var(--page-gutter);
		opacity: 0;
		pointer-events: none;
		/* Opacity-only fade — no translate, so the menu never appears to slide
		   in/out (it just fades). Kept short so there's no perceptible drift. */
		transition: opacity 0.15s ease;
		z-index: 5;
	}

	/* Inner bordered panel — the box. Height runs to the same frame-style
	   bottom padding so it reads as the top header box. */
	.site-header__menu {
		flex-direction: column;
		align-items: flex-start;
		font-size: 24px;                 /* base for the em gaps + the items */
		gap: 0.7em;                       /* spacing between menu items */
		/* Reset the desktop margin-right:60px so the panel fills the cream
		   field width (and the fixed close square lands inside its top-right). */
		margin: 0;
		width: 100%;
		box-sizing: border-box;
		border: 1.35px solid var(--wp--preset--color--accent);
		/* Push the first item below the close square. The close sits page-gutter
		   below the top border and is ~28.8px tall (32px × 0.9 scale); add
		   another page-gutter so the gap BELOW the close (to the first item)
		   equals the border-to-close gap. */
		padding: calc(2 * var(--page-gutter) + 28.8px) var(--page-gutter) var(--jl-frame-pad-below-logo);
	}

	.site-header__menu a {
		color: var(--wp--preset--color--accent);
		/* Match the desktop nav size exactly (24px) — don't let the fluid
		   token shrink it on mobile. */
		font-size: 24px;
		line-height: 1.4;
	}

	/* Sub-menus are hidden entirely on mobile — only top-level items show in
	   the takeover. */
	.site-header__menu .sub-menu {
		display: none;
	}

	/* --- Open state -------------------------------------------------------- */
	body.nav-open .site-header__nav {
		opacity: 1;
		pointer-events: auto;
	}

	/* No page-scroll lock — the fixed menu panel stays put while the page can
	   still scroll behind it. */

	body.nav-open .site-header__logo {
		visibility: hidden;
	}

	/* On framed pages the open nav box overlays the page frame; hide the
	   frame's border so we don't get a faint double line — the nav box's own
	   border is the single border shown. (No-op on frameless pages.) */
	body.nav-open .jl-page-frame {
		border-color: transparent;
	}

	/* Open state: the square close icon stays exactly where the hamburger was
	   (top-right, fixed — inherits the position above). Just lift it above the
	   takeover overlay and switch to the olive accent. */
	body.nav-open .site-header__toggle {
		z-index: 20;
		color: var(--wp--preset--color--accent);
	}

	body.nav-open .site-header__toggle-icon--bars {
		opacity: 0;
		pointer-events: none;
	}

	body.nav-open .site-header__toggle-icon--close {
		opacity: 1;
		pointer-events: auto;
	}

	/* Footer mobile sizing */
	.site-footer {
		padding-top: var(--wp--preset--spacing--md);
		padding-bottom: var(--wp--preset--spacing--md);
	}

	.site-footer__inner {
		gap: var(--wp--preset--spacing--lg);
	}

	.site-footer__tagline,
	.site-footer__social {
		font-size: var(--wp--preset--font-size--sm);
	}

	/* Stack the practice line + email on their own lines at normal line
	   spacing (no big horizontal gap), instead of side-by-side. */
	.site-footer__tagline {
		flex-direction: column;
		gap: 0;
		line-height: 1.5;
	}

	/* Stack tagline group, then a clear gap down to the Instagram link. */
	.site-footer__bottom {
		flex-direction: column;
		align-items: flex-start;
		gap: var(--wp--preset--spacing--md);
	}
}



/* ============================================================================
   6. Single Project page  (matches Figma "Projects B")
   Inside the page frame:
     .project-meta = 2-column grid
       .project-meta__left  → meta + credits
       .project-meta__right → intro + details
       (vertical hairline between them via column gap + border-left on right)
   Outside the frame:
     .project-cover         → full-width featured image
     .project-gallery       → list of .project-gallery__row blocks
       .row--single.--landscape → full-width
       .row--single.--portrait  → ~70% width, centred
       .row--two                → 2-column grid
     .project-nav           → ↑ Back to top above a hairline + ← Prev / Next →
   ============================================================================ */

/* --- Project meta: 2-column layout inside the frame ---------------------- */

.project-meta {
	display: grid;
	grid-template-columns: minmax(220px, 1fr) minmax(0, 1.7fr);
	column-gap: clamp(20px, 2.5vw, 45px);
	row-gap: calc(var(--jl-section-gap) / 2);
	max-width: 1620px;
	/* Same gap-below-logo rule as the home and projects-landing frames. */
	margin: var(--jl-frame-pad-below-logo) auto 0;
	/* Interior padding is the same compressed value on all four sides — keeps
	   the text sitting tight inside the framed box, matching Figma. */
	padding: calc(var(--jl-section-gap) / 2);
	border-top: 1.35px solid var(--wp--preset--color--accent);
}

/* Vertical hairline between the columns. The padding-left + negative
   margin-left pair keeps the hairline sitting at the grid column boundary
   while the right-col content sits inset from it by the same amount as
   the .project-meta column-gap above.

   The column is also a flex container so the Next Project link can pin
   to the bottom via `margin-top: auto`, sitting level with the last
   credit line on the left. */
.project-meta__right {
	display: flex;
	flex-direction: column;
	border-left: 1.35px solid var(--wp--preset--color--accent);
	padding-left: clamp(20px, 2.5vw, 45px);
	margin-left: calc(-1 * clamp(20px, 2.5vw, 45px));
}

.project-meta__left {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--xxl);
}

/* --- Project info (top of left column) ----------------------------------- */

/* No global reset here on purpose — each element below sets its own
   margins. Margin-bottom on the eyebrow and margin-top on the second
   eyebrow drive the within-group and between-group spacing rhythm. */
.project-meta__title,
.project-meta__location {
	margin: 0;
}

/* Eyebrow labels ("Project", "Location") — Untitled Sans Medium at the
   anchor body size. Tight line-height + a small em-based margin keeps the
   eyebrow sitting close to the value it labels while still letting the
   pair breathe (eyebrow → value reads as one unit, not a single line). */
.project-meta__eyebrow {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	font-weight: 500;
	line-height: 1.2;
	color: var(--wp--preset--color--foreground);
	margin-bottom: 0.3em;
}

/* Paragraph-style break between info groups — value → next eyebrow. Using
   em ties the gap to the eyebrow's own size, so it scales with the base.
   Double-class selector lifts specificity past the `margin: 0` reset on
   `.project-meta__info p` above. */
.project-meta__eyebrow.project-meta__eyebrow--mt {
	margin-top: 1.5em;
}

/* Project title + location value share typography in the design — both
   render as the display family at Semibold, sized on the --jl-text-display
   step (1.35× body). Shared selector keeps them from drifting apart. */
.project-meta__title,
.project-meta__location {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--jl-text-display);
	font-weight: 600;
	line-height: 1.05;
	color: var(--wp--preset--color--foreground);
}

/* --- Intro pull-quote (top of right column) ------------------------------ */

/* Intro pull-quote — sits 30% above the body on the modular scale. */
.project-meta__intro {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-intro);
	line-height: 1.25;
	margin-bottom: var(--jl-section-gap);
}

.project-meta__intro p { margin: 0 0 0.6em; }
.project-meta__intro p:last-child { margin-bottom: 0; }

/* --- Details (right column, below intro) --------------------------------- */

.project-meta__details {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	line-height: 1.45;
}

.project-meta__details-label {
	font-weight: 500;
	margin: 0 0 0.4em;
}

/* On desktop, the body of the right column (intro + details) sits narrower
   than the column so the eye gets a clear measure to read, while the Next
   Project link keeps reaching the right edge of the column. Kicks in at
   1200px+ — below that, the column is already narrow enough. */
@media (min-width: 1200px) {
	.project-meta__intro,
	.project-meta__details {
		margin-right: 20%;
	}
}

/* --- "Next Project" link (right column, below details) ------------------
   Mirrors the Figma "Projects B" layout: arrow-first, label after, pinned
   to the bottom-right of the column so it aligns with the last credit on
   the left. `margin-top: auto` does the bottom-pin in the column-flex
   parent. Sized at the body anchor (Figma's 32.5/30 = 1.08× — close
   enough that we just use base). */

.project-meta__next {
	display: flex;
	justify-content: flex-end;
	align-items: center;
	gap: 0.5em;
	margin-top: auto;
	padding-top: var(--jl-section-gap);   /* min gap above when content is short */
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	font-weight: 400;
	line-height: 1.1;
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
	transition: opacity 0.15s ease;
}

.project-meta__next:hover { opacity: 0.6; }

.project-meta__next-arrow {
	flex: 0 0 auto;
	width: auto;
	height: 0.65em;          /* arrow ≈ two-thirds the cap height — matches Figma proportion */
}

.project-meta__details p { margin: 0 0 0.6em; }
.project-meta__details p:last-child { margin-bottom: 0; }

/* --- Credits (bottom of left column) ------------------------------------- */

/* Credits — natural block flow inside <dl>. Within a credit pair (role on
   one line, name on the next) we let line-height alone control the gap so
   they read as one unit. Between pairs, a 1em margin-bottom on the name
   gives the paragraph-style break. */
.project-credits {
	margin: 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	line-height: 1.2;
	color: var(--wp--preset--color--foreground);
}

.project-credits__role,
.project-credits__name {
	margin: 0;
}

.project-credits__name {
	margin-bottom: 1em;
}

.project-credits__name:last-child { margin-bottom: 0; }

.project-credits__name a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.18em;
}

.project-credits__name a:hover { opacity: 0.6; }

/* --- Cover image + gallery + bottom nav: shared horizontal inset --------
   .site-main already insets its contents by --page-gutter (so it lines up
   with the frame above). The padding here adds an extra --jl-image-inset
   so the images sit visibly narrower than the framed text box. */
.project-main {
	padding-left:  var(--jl-image-inset);
	padding-right: var(--jl-image-inset);
}

/* --- Cover image (full-width below frame) -------------------------------- */

.project-cover {
	margin: 0;
	width: 100%;
}

.project-cover__img {
	width: 100%;
	height: auto;
	display: block;
}

/* --- Gallery rows -------------------------------------------------------- */

.project-gallery {
	margin: 0;
	display: flex;
	flex-direction: column;
	/* Figma "Projects B" sets ~99px between gallery rows at 1922vp. The clamp
	   scales that down to ~40px on tablet and tracks 5vw across desktop. */
	gap: clamp(40px, 5vw, 90px);
}

/* Override the generic `.jl-page-frame + .site-main > *` margin-top (40px)
   so the gap from cover image to first gallery row matches the between-row
   gap above, per Figma. */
.project-main > .project-gallery {
	margin-top: clamp(40px, 5vw, 90px);
}

.project-gallery__row {
	margin: 0;
}

.project-gallery__img {
	display: block;
	width: 100%;
	height: auto;
}

/* Landscape: full-width inside the wrapper (which is already capped) */
.project-gallery__row--landscape {
	width: 100%;
}

/* Portrait: narrower, centred (matches Figma — image 10 indented ~10% each side) */
.project-gallery__row--portrait {
	max-width: 70%;
	margin-left: auto;
	margin-right: auto;
}

/* --- Project navigation (bottom of single project) -----------------------
   Layout per Figma "Projects B":
     ↑ Back to Top                                  ← Back to Top above the hairline, left
     ────────────────────────────────────────────   ← horizontal hairline
     ← Previous Project          → Next Project    ← Prev (left) / Next (right) below

   All three links share the same typography (--jl-text-base, matching the
   meta-area Next Project link) and use the arrow-on-the-left convention. */

.project-nav {
	margin-top: var(--jl-section-gap);
	width: 100%;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	font-weight: 400;
}

.project-nav__top {
	padding-bottom: calc(var(--jl-section-gap) / 2);
}

/* The bottom of the project page is a thumbnail carousel of OTHER projects,
   not standard adjacent-post nav. The Previous/Next buttons step the
   carousel by one thumbnail at a time; clicking a thumbnail navigates. */
.project-nav__feed {
	padding-top: calc(var(--jl-section-gap) / 2);
	border-top: 1.35px solid var(--wp--preset--color--foreground);
	/* Read by project-carousel.js to pick how many thumbnails step at once.
	   Overridden on mobile (in the mobile block below) so that narrow
	   viewports show two thumbnails rather than squeezing three. */
	--carousel-visible: 3;
}

.project-nav__feed-controls {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--md);
	margin-bottom: var(--jl-section-gap);
}

.project-nav__feed-controls > [data-carousel="prev"] { justify-self: start; }
.project-nav__feed-controls > [data-carousel="next"] { justify-self: end; }

.project-nav__feed-btn {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	cursor: pointer;
	font: inherit;
}

.project-nav__feed-btn:disabled {
	opacity: 0.3;
	cursor: not-allowed;
}

.project-nav__feed-viewport {
	overflow: hidden;
}

.project-nav__feed-track {
	display: flex;
	column-gap: clamp(20px, 1.5vw, 30px);
	transition: transform 0.4s ease;
	will-change: transform;
}

/* Each item takes exactly one third of the viewport, accounting for the
   column-gap. JS reads the same gap to compute its translateX step. */
.project-nav__feed-item {
	/* Width = (track - (N-1) gaps) / N, where N is --carousel-visible.
	   Keeps math in sync with the JS step calculation. */
	flex: 0 0 calc(
		(100% - (var(--carousel-visible) - 1) * clamp(20px, 1.5vw, 30px))
		/ var(--carousel-visible)
	);
	aspect-ratio: 3 / 2;
	overflow: hidden;
	display: block;
}

.project-nav__feed-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: opacity 0.2s ease;
}

.project-nav__feed-item:hover .project-nav__feed-img,
.project-nav__feed-item:focus-visible .project-nav__feed-img {
	opacity: 0.85;
}

.project-nav__link {
	display: inline-flex;
	align-items: center;
	gap: 0.5em;
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
	line-height: 1.1;
	transition: opacity 0.15s ease;
}

.project-nav__link:hover { opacity: 0.6; }

.project-nav__arrow {
	display: inline-block;
	width: auto;
	height: 0.65em;          /* matches the meta-area Next Project arrow */
	max-width: none;
	flex: 0 0 auto;
}

/* The up arrow is taller than wide (16×23 vs the horizontals' 23×16), so
   size it by width — same width as the horizontal arrows' height — and
   let height follow. Gives all three arrows a balanced visual weight. */
.project-nav__arrow--up {
	height: auto;
	width: 0.65em;
}

.project-nav__arrow--up    { transform: translateY(-1px); }
.project-nav__arrow--left  { transform: translateY(1px); }
.project-nav__arrow--right { transform: translateY(1px); }

/* --- Mobile overrides ---------------------------------------------------- */

@media (max-width: 768px) {

	.project-meta {
		grid-template-columns: 1fr;
		row-gap: var(--jl-section-gap);
	}

	/* Drop the vertical divider on mobile — replace with a top hairline */
	.project-meta__right {
		border-left: 0;
		padding-left: 0;
		margin-left: 0;
		padding-top: var(--jl-section-gap);
		border-top: 1.35px solid var(--wp--preset--color--accent);
	}

	.project-meta__left {
		gap: var(--jl-section-gap);
	}

	.project-meta__title    { font-size: var(--wp--preset--font-size--lg); }
	.project-meta__intro    { font-size: var(--wp--preset--font-size--lg); }

	/* Hide the meta-area "Next Project" link on mobile — the foot-of-page
	   thumbnail carousel covers project navigation on small screens. (Kept on
	   desktop.) */
	.project-meta__next {
		display: none;
	}

	/* Gallery: portrait fills the full width on mobile */
	.project-gallery__row--portrait {
		max-width: 100%;
	}

	/* Nav: stack columns vertically */
	.project-nav__bottom {
		grid-template-columns: 1fr;
	}

	.project-nav__col--next {
		justify-self: start;
		text-align: left;
	}

	/* Thumbnail carousel: 2 visible at a time on mobile (was 3 on desktop). */
	.project-nav__feed {
		--carousel-visible: 2;
	}
}


/* ============================================================================
   7. Projects landing page
   Rendered by page-projects.php — matches Figma "Gallery B".
   Layout: 2-column grid of project cards (image + caption).
   Rows are grouped in .projects-grid__row wrappers so we can put a hairline
   divider above every row except the first.
   ============================================================================ */

.projects-landing__intro {
	max-width: 880px;
	margin: 0 0 var(--jl-section-gap);
	font-size: var(--wp--preset--font-size--lg);
	line-height: 1.4;
}

/* Category archive header — single breadcrumb line: "Projects / Residential".
   Marked up as an <h1> for SEO + a11y, but styled small to match the design. */
.projects-landing__heading {
	margin: 0 0 var(--jl-section-gap);
}

.projects-landing__breadcrumb {
	margin: 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 500;
	letter-spacing: 0.04em;
	line-height: 1.4;
	color: var(--wp--preset--color--foreground);
}

.projects-landing__crumb {
	color: inherit;
	text-decoration: none;
}

.projects-landing__crumb:hover {
	opacity: 0.6;
}

.projects-landing__sep {
	display: inline-block;
	margin: 0 0.4em;
	opacity: 0.4;
}

.projects-landing__current {
	font-weight: 500;
}

.projects-landing__description {
	margin: var(--wp--preset--spacing--xs) 0 0;
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--foreground);
	max-width: 640px;
}

.projects-grid__empty {
	font-size: var(--wp--preset--font-size--base);
	color: var(--wp--preset--color--foreground);
	margin: var(--wp--preset--spacing--lg) 0;
}

.projects-grid {
	display: flex;
	flex-direction: column;
	gap: var(--jl-section-gap);
}

.projects-grid__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--jl-section-gap);
}

/* Hairline above every row except the first */
.projects-grid__row + .projects-grid__row {
	padding-top: var(--jl-section-gap);
	border-top: 1.35px solid var(--wp--preset--color--foreground);
}

.projects-grid__item {
	display: flex;
	flex-direction: column;
	gap: 20px;                                          /* matches Figma image → caption gap */
	color: var(--wp--preset--color--foreground);
	text-decoration: none;
	transition: opacity 0.2s ease;
}

.projects-grid__item:hover .projects-grid__img {
	opacity: 0.92;
}

.projects-grid__image {
	margin: 0;
	width: 100%;
	aspect-ratio: 889 / 556;                            /* Figma proportions */
	overflow: hidden;
	background: var(--wp--preset--color--muted-surface);
}

.projects-grid__image--placeholder::after {
	content: '';                                        /* keeps the slot visible if no image */
	display: block;
	width: 100%;
	height: 100%;
}

.projects-grid__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	transition: opacity 0.2s ease;
}

.projects-grid__caption {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--wp--preset--font-size--base);
	line-height: 1.25;
}

.projects-grid__title {
	font-weight: 500;
	color: var(--wp--preset--color--foreground);
}

.projects-grid__location {
	color: var(--wp--preset--color--foreground);
}

/* --- Mobile --------------------------------------------------------------- */

@media (max-width: 768px) {

	.projects-grid__row {
		grid-template-columns: 1fr;
	}

	/* When the row collapses to 1 column, the divider should also move accordingly
	   so a divider sits between every project, not just every (visual) row. */
	.projects-grid__row + .projects-grid__row {
		padding-top: var(--jl-section-gap);
	}
}

/* ============================================================================
   Section heading — shared across templates that use the "The Studio ———" /
   "How we work ———" pattern: 60px-in-design Larish Semibold with a trailing
   string of em-dashes acting as visual rule.
   ============================================================================ */

.section-heading {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--jl-text-intro);   /* 1.6× base — large but tracks the body anchor */
	font-weight: 600;
	line-height: 1.1;
	margin: 0;
	/* Page titles ("The Studio", "How we work") are the olive/dark green. */
	color: var(--wp--preset--color--accent);
}

.section-heading--centred {
	text-align: center;
}

.section-heading__dashes {
	display: inline-block;
	margin-left: 0.2em;
	letter-spacing: -0.05em;
}

/* ============================================================================
   Studio page (page-studio.php)
   ============================================================================ */

/* Studio is frameless (mirrors How We Work). Top padding pushes the hero
   below the standalone site-header by the same gap-below-logo rule used on
   the framed templates. */
.studio-main {
	display: flex;
	flex-direction: column;
	gap: var(--jl-section-gap);
	/* The standalone header box now supplies the header space; this is just the
	   gap from that box down to the first section (matches the framed pages'
	   .jl-page-frame + .site-main gap). */
	padding-top: var(--jl-section-gap);
}

/* --- Section 1: Hero ---------------------------------------------------- */

/* Same shape as .hww-hero — heading left, image right, heading vertically
   centred against the image's height. */
.studio-hero {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) minmax(0, 2fr);
	column-gap: clamp(40px, 5vw, 90px);
	align-items: center;
}

.studio-hero__heading {
	grid-column: 1;
	margin: 0;
}

.studio-hero__image {
	grid-column: 2;
	margin: 0;
}

.studio-hero__img {
	width: 100%;
	height: auto;
	display: block;
}

/* --- Section 2: Intro --------------------------------------------------- */

/* Mirrors .hww-intro: standalone paragraph in the right column. Studio's
   intro does NOT carry a vertical hairline (the line restarts at the team
   bios section below — see CSS for that section in the next step). */
.studio-intro {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) minmax(0, 2fr);
	column-gap: clamp(40px, 5vw, 90px);
}

.studio-intro__body {
	grid-column: 2;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-intro);
	line-height: 1.25;
}

.studio-intro__body p { margin: 0 0 1em; }

/* --- Section 4: Image Layout (fixed 9-slot grid) ------------------------
   Three rows, 9 slots total. Each slot is either an image or a pull
   quote (admin chooses per slot in ACF). Tints per row are hard-coded
   to match the Figma "Studio A" panels. Mobile collapses to single
   column.

   Row 1: orange-tinted panel
     ┌─────────┬──────────┐
     │ slot 1  │          │
     ├─────────┤  slot 3  │
     │ slot 2  │  (tall)  │
     └─────────┴──────────┘

   Row 2: untinted
     ┌──────────┬─────────┐
     │          │ slot 5  │
     │  slot 4  ├─────────┤
     │  (tall)  │ slot 6  │
     └──────────┴─────────┘

   Row 3: beige-tinted panel — 3 stacked full-width slots
     ┌────────────────────┐
     │ slot 7             │
     ├────────────────────┤
     │ slot 8             │
     ├────────────────────┤
     │ slot 9             │
     └────────────────────┘
*/

.studio-layout {
	display: flex;
	flex-direction: column;
	/* Larger gap above the image layout, separating it from the studio
	   team section. Matches the doubled inter-image gap (80px) used inside
	   Row 1 + Row 2, so the rhythm is consistent throughout the layout. */
	margin-top: calc(var(--jl-section-gap) * 2);
	/* Rows 1 and 2 sit flush so the orange panel can flow continuously
	   from Row 1 into Row 2's top 25%. Row 3 keeps its own gap via an
	   explicit margin-top. */
}

/* --- Row 1 + Row 2: 2-col grid with named slot areas -------------------
   Background panel (Row 1's orange tint) spans 100% of the container; the
   grid content sits at 90% width, leaving 5% on each side for the tint to
   show. Row 2 has the same 90% content width and uses a pseudo-element to
   carry the orange tint across its top 25% so the panel continues from
   Row 1 into Row 2. */

.studio-layout__row--1,
.studio-layout__row--2 {
	display: grid;
	grid-template-columns: 1fr 1fr;
	/* Auto-sized rows — each row fits its content. The spanning slot
	   (slot 3 in Row 1, slot 4 in Row 2) only expands the rows enough to
	   hold its image at the column width. Result: text in slot 1 sits
	   at the same vertical position as the top of the spanning image
	   in slot 3, so column 1's content extent doesn't exceed column 2's. */
	grid-template-rows: auto auto;
	/* Doubled gap — applies BOTH between images inside a row (column-gap
	   + inner row-gap) and between Row 1 and Row 2 via the padding-top
	   /padding-bottom overrides below. */
	gap: calc(var(--jl-section-gap) * 2);
	/* Padding around the panel content matches the inter-image gap on all
	   sides (80px = section-gap × 2). The padding-bottom on Row 1 and
	   padding-top on Row 2 overrides below halve each side back to 40px,
	   so the seam between rows still sums to 80px. */
	padding: calc(var(--jl-section-gap) * 2);
}

/* Row 1 image slots cluster IMAGES at the BOTTOM of the cell;
   Row 2 image slots cluster IMAGES at the TOP. Quote slots (text) stay
   top-aligned in BOTH rows so the reading flow starts at the top of the
   space. :has() selectors keep this content-type-aware. */
.studio-layout__row--1 > .studio-layout__slot:has(.studio-layout__figure) {
	justify-content: flex-end;
}

.studio-layout__row--1 > .studio-layout__slot:has(.studio-layout__quote) {
	justify-content: center;
}

.studio-layout__row--2 > .studio-layout__slot {
	justify-content: flex-start;
}

/* The two rows sit flush. Each row contributes a full --jl-section-gap of
   padding on its touching edge, so the gap between Row 1's bottom content
   and Row 2's top content is 40 + 40 = 80px — double the previous value,
   matching the doubled inner-row gap above. */
.studio-layout__row--1 {
	padding-bottom: var(--jl-section-gap);
}

.studio-layout__row--2 {
	padding-top: var(--jl-section-gap);
}

/* Row 2 extends the orange panel down — the ::before paints orange across
   the top 25% of the row, flush against Row 1's orange bottom. */
.studio-layout__row--2 {
	position: relative;
}

.studio-layout__row--2::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 25%;
	background: var(--wp--preset--color--terracotta-tint);
	z-index: 0;
	pointer-events: none;
}

.studio-layout__row--2 > .studio-layout__slot {
	position: relative;
	z-index: 1;
}

.studio-layout__row--1 .studio-layout__slot--top-left    { grid-area: 1 / 1 / 2 / 2; }
.studio-layout__row--1 .studio-layout__slot--bottom-left { grid-area: 2 / 1 / 3 / 2; }
.studio-layout__row--1 .studio-layout__slot--tall-right  { grid-area: 1 / 2 / 3 / 3; }

.studio-layout__row--2 .studio-layout__slot--tall-left    { grid-area: 1 / 1 / 3 / 2; }
.studio-layout__row--2 .studio-layout__slot--top-right    { grid-area: 1 / 2 / 2 / 3; }
.studio-layout__row--2 .studio-layout__slot--bottom-right { grid-area: 2 / 2 / 3 / 3; }

/* --- Row 1 hardcoded tint (background only — padding controlled above) - */

.studio-layout__row--1 {
	background: var(--wp--preset--color--terracotta-tint);
}

/* --- Row 3: three stacked slots, mixed widths + decorative beige panel
   The beige panel is a 100%-page-wide layer that sits BEHIND slots 8 and
   9 only — starts roughly halfway down slot 8, ends roughly 75% down
   slot 9. Slot 7 sits above the panel at full container width; slot 8
   is narrower (65%), slot 9 sits at 90%. Mobile collapses to full width. */

.studio-layout__row--3 {
	display: flex;
	flex-direction: column;
	gap: clamp(20px, 2vw, 40px);
	position: relative;
	margin-top: var(--jl-section-gap);   /* explicit gap from Row 2
	                                         (parent flex gap was removed) */
}

.studio-layout__row--3::before {
	content: '';
	position: absolute;
	/* Span the full container width (.site-main max-width 1600px) — NOT
	   to viewport edges. Stays bounded by the page-gutter on either side. */
	left: 0;
	right: 0;
	/* Approximate vertical extent. Slots are content-sized so this is
	   percentage-based — tune with concrete values if the design needs
	   pixel-precise control. */
	top: 50%;
	bottom: 10%;
	background: var(--wp--preset--color--muted-surface);
	z-index: 0;
	pointer-events: none;
}

.studio-layout__row--3 > .studio-layout__slot {
	position: relative;   /* lift slots above the ::before panel */
	z-index: 1;
}

/* Slot 7 — first child — full container width */
.studio-layout__row--3 > .studio-layout__slot:nth-child(1) {
	width: 100%;
}

/* Slot 8 — second child — narrower, centred */
.studio-layout__row--3 > .studio-layout__slot:nth-child(2) {
	width: 65%;
	align-self: center;
}

/* Slot 9 — third child — wider, centred */
.studio-layout__row--3 > .studio-layout__slot:nth-child(3) {
	width: 90%;
	align-self: center;
}

/* --- Slot contents -----------------------------------------------------
   Slots are flex columns. Images get `flex: 1` so they stretch to fill the
   slot; quotes sit at their natural height and the parent's
   justify-content vertically centres them. */

.studio-layout__slot {
	display: flex;
	flex-direction: column;
	justify-content: center;
	overflow: hidden;
}

.studio-layout__figure {
	margin: 0;
	width: 100%;
	flex: 1;
	min-height: 0;       /* allows the figure to shrink inside its slot */
}

.studio-layout__img {
	width: 100%;
	height: 100%;
	display: block;
	object-fit: contain;   /* fits inside the cell, no cropping */
}

/* Row 1 + 2 — push images toward the inter-row + inter-column intersection
   so the cell tints frame each image on the OUTSIDE while images cluster
   toward the centre cross. */
.studio-layout__row--1 > .studio-layout__slot--top-left .studio-layout__img,
.studio-layout__row--1 > .studio-layout__slot--bottom-left .studio-layout__img {
	object-position: 100% 100%;    /* right (toward col gap), bottom (toward row gap) */
}

.studio-layout__row--1 > .studio-layout__slot--tall-right .studio-layout__img {
	object-position: 0% 100%;      /* left (toward col gap), bottom */
}

.studio-layout__row--2 > .studio-layout__slot--tall-left .studio-layout__img {
	object-position: 100% 0%;      /* right (toward col gap), top */
}

.studio-layout__row--2 > .studio-layout__slot--top-right .studio-layout__img,
.studio-layout__row--2 > .studio-layout__slot--bottom-right .studio-layout__img {
	object-position: 0% 0%;        /* left (toward col gap), top */
}

.studio-layout__quote {
	margin: 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-intro);
	line-height: 1.25;
	padding: 0 clamp(10px, 1.5vw, 30px);
}

.studio-layout__quote p { margin: 0 0 0.6em; }
.studio-layout__quote p:last-child { margin-bottom: 0; }

/* --- Mobile: collapse each row to single column ------------------------ */

@media (max-width: 768px) {
	.studio-layout__row--1,
	.studio-layout__row--2 {
		grid-template-columns: 1fr;
		grid-template-rows: auto;
	}

	.studio-layout__row--1 .studio-layout__slot,
	.studio-layout__row--2 .studio-layout__slot {
		grid-area: auto;
	}

	/* Row 3: collapse slots to full width on mobile */
	.studio-layout__row--3 > .studio-layout__slot:nth-child(2),
	.studio-layout__row--3 > .studio-layout__slot:nth-child(3) {
		width: 100%;
	}

	.studio-layout__img {
		height: auto;
	}
}

/* --- Section 3: Team --------------------------------------------------- */

/* 2-col layout matching the Figma "Studio A" team area (node 127:207):
   continuous vertical hairline through the section, all team content
   (heading + intro + member list) sits in the right column. */
.studio-team {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) 1.35px minmax(0, 2fr);
	column-gap: clamp(20px, 2.5vw, 45px);
	position: relative;
}

.studio-team::before {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	/* Same column-math as .hww-intro/.hww-stage__head so the line sits at
	   the same x position as the divider on the How We Work page. */
	left: calc((100% - 1.35px - 2 * clamp(20px, 2.5vw, 45px)) / 3 + clamp(20px, 2.5vw, 45px));
	width: 1.35px;
	background: var(--wp--preset--color--accent);
	pointer-events: none;
}

.studio-team__content {
	grid-column: 3;
	display: flex;
	flex-direction: column;
	gap: var(--jl-section-gap);
}

.studio-team__heading {
	margin: 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-display);
	font-weight: 500;
}

.studio-team__intro {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	line-height: 1.45;
}

.studio-team__intro p { margin: 0 0 1em; }
.studio-team__intro p:last-child { margin-bottom: 0; }

.studio-team__list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--jl-section-gap);
}

.studio-team__member {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	line-height: 1.4;
}

/* Head — uniform stack for every member: name on line 1, email on line 2.
   When a bio exists, the name is rendered inside .studio-team__toggle with
   the arrow on its right (visual cue that a bio is collapsed below). When
   there's no bio, .studio-team__name--static replaces the toggle (no arrow,
   not clickable). The arrow's presence is what indicates a hidden bio. */
.studio-team__head {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 0.15em;
}

.studio-team__name--static {
	display: inline-block;
	font-weight: 500;
}

.studio-team__toggle {
	display: inline-flex;
	align-items: baseline;
	gap: 0.5em;
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
	font: inherit;
	color: inherit;
	text-align: left;
	transition: opacity 0.15s ease;
}

.studio-team__toggle:hover { opacity: 0.75; }

.studio-team__name {
	font-weight: 500;
}

.studio-team__arrow {
	display: inline-block;
	width: auto;
	height: 0.5em;
	flex: 0 0 auto;
	transition: transform 0.2s ease;
	transform-origin: center;
}

.studio-team__toggle[aria-expanded="true"] .studio-team__arrow {
	transform: rotate(90deg);
}

.studio-team__email {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 0.18em;
}

.studio-team__email:hover { opacity: 0.6; }

/* Collapsible bio — opens directly below its head row. Matches the
   single-open accordion behaviour from HWW (handled in studio-team.js). */
.studio-team__bio {
	margin-top: calc(var(--jl-section-gap) / 2);
}

.studio-team__bio[hidden] {
	display: none;
}

.studio-team__bio p { margin: 0 0 0.6em; }
.studio-team__bio p:last-child { margin-bottom: 0; }

/* ============================================================================
   How We Work page (page-how-we-work.php)
   ============================================================================ */

.hww-main {
	display: flex;
	flex-direction: column;
	/* Tighter rhythm between sections — matches the proportional gaps in
	   the Figma rather than the larger gallery-style spacing used elsewhere. */
	gap: var(--jl-section-gap);
	/* The standalone header box now supplies the header space; this is just the
	   gap from that box down to the first section (matches the framed pages'
	   .jl-page-frame + .site-main gap). */
	padding-top: var(--jl-section-gap);
}

/* ============================================================================
   How We Work — three independent sections (Hero, Intro, Stages).
   ============================================================================ */

/* --- Section 1: Hero ---------------------------------------------------- */

/* Title on the left, image on the right, title vertically centred against
   the image's height. No divider between them. */
.hww-hero {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) minmax(0, 2fr);
	column-gap: clamp(40px, 5vw, 90px);
	align-items: center;
}

.hww-hero__heading {
	grid-column: 1;
	margin: 0;
}

.hww-hero__image {
	grid-column: 2;
	margin: 0;
}

.hww-hero__img {
	width: 100%;
	height: auto;
	display: block;
}

/* --- Section 2: Intro --------------------------------------------------- */

/* Uses the same 3-col template as the Stages section so the vertical hairline
   sits at exactly the same x position in both sections. The intro body lives
   in col 3; the divider in col 2 is drawn by the ::before pseudo-element. */
.hww-intro {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) 1.35px minmax(0, 2fr);
	column-gap: clamp(20px, 2.5vw, 45px);
	position: relative;
}

.hww-intro__body {
	grid-column: 3;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-intro);
	line-height: 1.25;
	color: var(--wp--preset--color--accent);
}

/* Standard paragraph margin applies to every <p>, including the last one.
   The trailing space pushes Stage 1 (and the start of the divider→stages
   bridge) further from the intro copy, giving the intro its own breathing
   room before the collapsible content. */
.hww-intro__body p { margin: 0 0 1em; }

/* Vertical hairline — extends past the section bottom by one .hww-main gap
   so it visually meets the stages divider below, giving the appearance of
   one continuous line running through both sections. */
.hww-intro::before {
	content: '';
	position: absolute;
	top: 0;
	bottom: calc(-1 * var(--jl-section-gap));
	left: calc((100% - 1.35px - 2 * clamp(20px, 2.5vw, 45px)) / 3 + clamp(20px, 2.5vw, 45px));
	width: 1.35px;
	background: var(--wp--preset--color--accent);
	pointer-events: none;
}

/* --- Section 3: Stages -------------------------------------------------- */

/* Container holds each <article class="hww-stage"> (head + body) stacked
   vertically. A single ::before pseudo-element draws the continuous
   vertical hairline through every head row; expanded bodies paint over
   the line with their own background and add horizontal hairlines above
   and below themselves, matching the Figma's bracketing rule pattern.
   The negative margin pulls the stages tighter to the intro paragraph. */
.hww-stages {
	margin-top: calc(-1 * var(--jl-section-gap) / 2);
}

/* Vertical hairline drawn PER head (was a single line on .hww-stages). The
   per-head approach gives us natural gaps around an open body — each head's
   line only spans its own box, so when a body opens between two heads the
   body's vertical margin sits between the previous line's bottom and the
   next line's top, with no line painting through it. Adjacent collapsed
   heads stack directly so their lines meet visually and read as one. */

/* Individual stage — head (clickable button) + optional body. Block-stacked
   inside the parent (no display:contents — keeps the <article> in the
   accessibility tree as a proper landmark for assistive tech). The head's
   own padding controls vertical breathing room between stage rows. */
.hww-stage {
	display: block;
}

/* Stage head — uses the 3-col grid: label (right-aligned), divider gap,
   arrow + title. Padding gives vertical breathing room between rows. */
.hww-stage__head {
	display: grid;
	grid-template-columns: minmax(260px, 1fr) 1.35px minmax(0, 2fr);
	column-gap: clamp(20px, 2.5vw, 45px);
	align-items: baseline;
	width: 100%;
	padding: 0 0 calc(var(--jl-section-gap) / 2);
	background: none;
	border: 0;
	cursor: pointer;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-display);
	font-weight: 400;
	text-align: left;
	color: var(--wp--preset--color--accent);
	transition: opacity 0.15s ease;
	position: relative;            /* anchor for the per-head vertical line */
}

/* Per-head vertical hairline — spans the head's full height (incl.
   padding-bottom) so collapsed heads stacked one after another show a
   continuous line. Horizontal x position matches .hww-intro::before so
   the line aligns with the intro section's divider above. */
.hww-stage__head::before {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	left: calc((100% - 1.35px - 2 * clamp(20px, 2.5vw, 45px)) / 3 + clamp(20px, 2.5vw, 45px));
	width: 1.35px;
	background: var(--wp--preset--color--accent);
	pointer-events: none;
}

.hww-stage__head:hover { opacity: 0.75; }

.hww-stage__label {
	grid-column: 1;
	justify-self: end;
	text-align: right;
	font-weight: 500;
}

.hww-stage__right {
	grid-column: 3;
	display: flex;
	align-items: baseline;
	gap: clamp(16px, 1.5vw, 30px);
}

.hww-stage__arrow {
	display: inline-block;
	width: auto;
	height: 0.5em;
	flex: 0 0 auto;
	transition: transform 0.2s ease;
	transform-origin: center;
}

.hww-stage__head[aria-expanded="true"] .hww-stage__arrow {
	transform: rotate(90deg);
}

/* Active stage's title gets no underline — the rotated arrow already
   indicates which one is open. */

/* Body — full-width content shown when a stage is expanded. The background
   paints over the vertical hairline behind it; the top + bottom borders
   show as the horizontal lines bracketing the body in the Figma. Inter-
   section gap uses the standard --jl-section-gap so it matches the
   site-wide rhythm (40px at desktop) rather than the larger gallery gap. */
.hww-stage__body {
	display: flex;
	flex-direction: column;
	gap: var(--jl-section-gap);
	padding: var(--jl-section-gap) 0;
	/* Top/bottom margin sits between the previous head's vertical-line
	   bottom and the next head's vertical-line top, creating the gap the
	   design calls for between the vertical hairline and the body's
	   horizontal hairlines. Per-head lines (above) don't extend through
	   this margin, so the gap reads as a clean visual break. */
	margin: var(--jl-section-gap) 0;
	background: var(--wp--preset--color--background);
	border-top: 1.35px solid var(--wp--preset--color--accent);
	border-bottom: 1.35px solid var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent);
}

.hww-stage__body[hidden] {
	display: none;
}

/* Last stage's body has no bottom border when open — the footer's own
   border-top sits immediately below, so leaving the body's border-bottom
   in place produces a double horizontal line. */
.hww-stage:last-child .hww-stage__body {
	border-bottom: 0;
}

/* No explicit horizontal rule between the stages section and the footer —
   the site-footer's own border-top supplies it (avoids a double line). */

/* Old .hww-stage-row / .hww-stage-body rules were removed in favour of
   .hww-stage / .hww-stage__head / .hww-stage__body — see the Section 3
   block above for current styles. */

/* --- Stage section variants -------------------------------------------- */

/* Text block — bold intro + bullet list. Body copy size; the column sits
   at ~60% of the parent width (matching Figma 127:313 where the body text
   spans 1161/1922 ≈ 60%) and centres between the full-width images above
   and below. align-self:center is needed because the parent .hww-stage__body
   is a flex column — margin: 0 auto won't centre on its own. */
.hww-section--text {
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-base);
	line-height: 1.4;
	width: 60%;
	align-self: center;
}

.hww-section--text p { margin: 0 0 0.6em; }
.hww-section--text p:last-child { margin-bottom: 0; }
.hww-section--text strong { font-weight: 500; }

.hww-section--text ul {
	list-style: disc outside;
	padding-left: 1.2em;
	margin: 0.6em 0;
}

.hww-section--text li { margin-bottom: 0.4em; }
.hww-section--text li:last-child { margin-bottom: 0; }

/* Image block — full width inside the stage body. */
.hww-section--image {
	margin: 0;
}

.hww-section__img {
	width: 100%;
	height: auto;
	display: block;
}

/* Image with caption — image left (60%), descriptive text right (40%).
   Stacks below the breakpoint so the caption drops underneath the image.
   The caption is editor-supplied (per-section ACF field), independent of
   the attachment's global media-library caption — so different placements
   of the same image can use different captions. */
.hww-section--image-with-caption {
	display: grid;
	grid-template-columns: 1.5fr 1fr;
	column-gap: clamp(30px, 4vw, 80px);
	align-items: center;
}

.hww-section__image-side {
	margin: 0;
}

.hww-section__caption {
	margin: 0;
	font-family: var(--wp--preset--font-family--sans);
	font-size: var(--jl-text-intro);   /* 1.6× base — matches Figma's 60px caption */
	line-height: 1.25;
}

.hww-section__caption p { margin: 0 0 0.6em; }
.hww-section__caption p:last-child { margin-bottom: 0; }

@media (max-width: 768px) {
	.hww-section--image-with-caption {
		grid-template-columns: 1fr;
		row-gap: var(--jl-section-gap);
	}
}

/* ============================================================================
   Tablet (≤1024px) — hide the positioned vertical hairlines.
   The 3-column layouts (HWW intro + stages, Studio team) keep their desktop
   grid down to the 768px collapse, but between ~769–1024px the column
   proportions shift enough that these absolutely-positioned dividers drift
   over the text columns. Hiding them avoids lines crossing the copy; the
   layout still reads fine without the hairline at these widths.
   ============================================================================ */

@media (max-width: 1024px) {
	.hww-intro::before,
	.hww-stage__head::before,
	.studio-team::before {
		display: none;
	}
}

/* ============================================================================
   Mobile (≤768px) overrides for Studio + How We Work
   ============================================================================ */

@media (max-width: 768px) {

	/* --- Shared heroes: title above image ---------------------------------- */
	.studio-hero,
	.hww-hero {
		grid-template-columns: 1fr;
		/* When stacked, give the page title a decent gap above the image. */
		row-gap: var(--jl-section-gap);
	}

	.studio-hero__image,
	.hww-hero__image {
		grid-column: 1;
		grid-row: auto;
	}

	.studio-hero .section-heading,
	.studio-hero__intro,
	.hww-hero .section-heading,
	.hww-hero__intro {
		grid-column: 1;
		grid-row: auto;
	}

	.studio-quote,
	.studio-quote--right {
		max-width: none;
		text-align: left;
		margin-left: var(--jl-image-inset);
		margin-right: var(--jl-image-inset);
	}

	.studio-gallery {
		grid-template-columns: 1fr;
	}

	/* --- How We Work: drop the 3-col grid (intro + stage heads) ------------
	   Mobile can't carry the desktop's narrow-left-label + hairline + body
	   layout — there's not enough horizontal room. Collapse to a single
	   column and hide the vertical hairline so the head reads as a simple
	   accordion: label on top, title + arrow below. */
	.hww-intro {
		display: block;
	}

	.hww-intro__body {
		font-size: var(--jl-text-base);
	}

	.hww-intro::before {
		display: none;
	}

	.hww-stage__head {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		gap: 0.25em;
		font-size: var(--jl-text-intro);
		/* More separation between stacked stages on mobile (was section-gap/2). */
		padding-bottom: var(--jl-section-gap);
	}

	.hww-stage__head::before {
		display: none;
	}

	.hww-stage__label {
		justify-self: flex-start;
		text-align: left;
		font-size: var(--jl-text-base);
	}

	.hww-stage__right {
		gap: clamp(12px, 3vw, 24px);
	}

	/* Text section inside an expanded stage: drop the 60% centred column —
	   no value at narrow widths and it leaves wasted gutters. */
	.hww-section--text {
		width: 100%;
	}

	/* --- Studio team: drop the 3-col grid + hairline ----------------------- */
	.studio-team {
		display: block;
	}

	.studio-team::before {
		display: none;
	}

	.studio-team__heading {
		font-size: var(--jl-text-display);
	}

	/* --- Studio image rows: tighten the orange-panel padding ---------------
	   Desktop uses section-gap × 2 (≈80px) on all sides, which eats most of
	   a 375px viewport. Halve it for mobile. Same logic for the inter-image
	   gap inside each row. */
	.studio-layout__row--1,
	.studio-layout__row--2 {
		padding: var(--jl-section-gap);
		gap: var(--jl-section-gap);
	}

	.studio-layout__row--1 {
		padding-bottom: calc(var(--jl-section-gap) / 2);
	}

	.studio-layout__row--2 {
		padding-top: calc(var(--jl-section-gap) / 2);
	}

	/* Once rows are 1-column the row 2 orange ::before continuation looks
	   odd (it tints the top quarter of a tall single-column stack); cap it. */
	.studio-layout__row--2::before {
		height: calc(var(--jl-section-gap) * 1.5);
	}
}
