/* Hero — Default (Image). Title overlapping a featured image — the same
   absolute-media / relative-text overlay technique as the Audience Page
   template's "V1 Stacked" layout (audience-page.css .audienceHero), plus a
   bottom shadow gradient scrim for text legibility. Tokens: Design Tokens
   → Heroes → Default (Image) (inc/hero-tokens.php), all under the
   --hero-default-image-* namespace — independent of every other hero
   style, nothing shared. */

/* GP (core or Premium's Page Header module) still renders its own featured
   image ahead of this hero — unhooking it in PHP doesn't reach Premium's
   render path (see assets/css/conditional/heroes/hero-v1.css), so hide it
   here too. This style renders its own image via .defaultImageHero__media
   above, so GP's copy is always redundant. */
#SD.hero-style-default-image .page-header-image
{
	display: none;
}

.defaultImageHero
{
	position: relative;
	overflow: hidden;
	margin-top: var(--hero-default-image-margin-top, 0);
	margin-bottom: var(--hero-default-image-margin-bottom, 0);
}
/* When a Color Banner follows, its own margin-bottom (below) takes over
   that spacing-to-next-content job so the banner can sit flush under the
   image (Gap defaults to 0) instead of inheriting a gap meant for whatever
   comes after the whole hero block. */
.defaultImageHero.has-palette
{
	margin-bottom: 0;
}

.defaultImageHero.has-image
{
	height: var(--hero-default-image-height-mobile, 60vw);
}

@media only screen and (min-width: 768px)
{
	.defaultImageHero.has-image { height: var(--hero-default-image-height-tablet, 60vw); }
}
@media only screen and (min-width: 1024px)
{
	.defaultImageHero.has-image { height: var(--hero-default-image-height-desktop, 70vh); }
}
@media only screen and (min-width: 1440px)
{
	.defaultImageHero.has-image { height: var(--hero-default-image-height-desktop-lg, 70vh); }
}

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

/* Ken Burns / parallax — same engine and sitewide settings (Design Tokens
   Heroes, the hero_parallax_, hero_kenburns_, and hero_fade_duration option
   fields) as V1 Classic, generalized in assets/js/conditional/heroes/
   hero-v1.js to look for either hero style's markup. .kenBurnsMask masks
   the scaled/panned image so it never overflows visible bounds;
   .parallaxWrapper is what the scroll-driven translateY targets;
   .imageWrapper (the actual background-image layer) is what GSAP's
   fade-in + zoom targets, same three-layer split as
   .projectIntro.version01 .hero for the same reason.
   inset:0 rather than width/height:100% - .defaultImageHero__media only
   gets its own size implicitly (position:absolute + inset:0, stretched
   against .defaultImageHero's explicit height), not via a declared height
   property, so percentage heights on these children don't reliably resolve
   against it. V1 Classic's own .hero container has an actual declared
   height, which is why the equivalent width:100%/height:100% rule works
   there but not here. inset:0 sidesteps percentage resolution entirely. */
.defaultImageHero .kenBurnsMask
{
	position: absolute;
	inset: 0;
	transform-origin: center;
	overflow: hidden;
}
/* Oversized vertically (not a flush inset:0 like the mask) so scroll-driven
   translateY never slides the image's own edge into view within the mask —
   at inset:0, ANY nonzero vertical offset immediately exposes whatever's
   behind it (the page background) as a "lip" at the opposite edge, tinted
   by the scrim into a visible gray band. 20% each side (40% total) comfortably
   covers the default parallax intensity's realistic scroll range;
   .imageWrapper inherits this same oversized box since it's inset:0 to this
   element.

   top/bottom are driven by --hero-default-image-parallax-top/-bottom
   (template, based on the Vertical Alignment field) rather than a fixed
   -20%/-20% split — see that field's own comment in the template for why
   vertical alignment has to be expressed as a shift of this box's position
   instead of background-position: background-size:cover is calculated
   against THIS (already-oversized) box, and for wide-aspect images that
   leaves zero pixels of internal slack for background-position to move
   within, so Top/Center/Bottom would otherwise render identically. Shifting
   the box itself works regardless of the image's own aspect ratio. Total
   height stays 40% of mask height in every case, just redistributed
   asymmetrically (5%/35% instead of 20%/20%) — same scroll-parallax
   headroom, just weighted toward whichever edge the chosen alignment
   exposes. */
.defaultImageHero .parallaxWrapper
{
	position: absolute;
	top: var(--hero-default-image-parallax-top, -20%);
	right: 0;
	bottom: var(--hero-default-image-parallax-bottom, -20%);
	left: 0;
	transform-origin: center;
}
.defaultImageHero .imageWrapper
{
	position: absolute;
	inset: 0;
	transform-origin: center;
	background-size: cover;
	/* Image Alignment (group_hero.json) — only the horizontal axis is
	   expressed here; .parallaxWrapper isn't oversized horizontally, so
	   background-position has real slack to work with on this axis. The
	   vertical axis is handled by shifting .parallaxWrapper's own position
	   above instead (see its comment) — hardcoded to center here rather
	   than reading the align-y var, so the two mechanisms can't compound. */
	background-position: var(--hero-default-image-align-x, center) center;
}
/* Fixed Background parallax mode (Design Tokens → Heroes → Default (Image)
   → Parallax) used to be plain background-attachment:fixed here. Removed —
   that property computes background-size:cover and background-position
   against the *viewport*, not this element's own box, no matter what.
   Confirmed empirically (isolated test page + live screenshots): for any
   image whose aspect ratio is close to the viewport's own aspect ratio
   (e.g. a ~16:9 photo on a widescreen browser window — common), that
   leaves ~0 vertical slack, silently breaking Vertical Alignment
   (.defaultImageHero .imageWrapper's background-position above) no matter
   what the field is set to. hero-v1.js now reproduces the same "pinned to
   the viewport while the page scrolls past" look with a 1:1 counter-scroll
   translateY on .parallaxWrapper instead (its .isFixedMode branch) — that
   keeps background-size/position computed against this local (oversized)
   box, the same math Scroll mode already used correctly, so alignment
   works in both modes now. */

.defaultImageHero__scrim
{
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, 0.65) 0%,
		rgba(0, 0, 0, 0) var(--hero-default-image-gradient-stop-mobile, 60%)
	);
}
@media only screen and (min-width: 768px)
{
	.defaultImageHero__scrim { background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) var(--hero-default-image-gradient-stop-tablet, 60%)); }
}
@media only screen and (min-width: 1024px)
{
	.defaultImageHero__scrim { background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) var(--hero-default-image-gradient-stop-desktop, 40%)); }
}

.defaultImageHero__text
{
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	min-height: 100%;
	box-sizing: border-box;
	padding-top: var(--hero-default-image-content-padding-top-mobile, var(--projInterval));
	padding-bottom: var(--hero-default-image-content-padding-bottom-mobile, var(--projInterval));
	padding-left: var(--hero-default-image-content-padding-h-mobile, var(--projInterval));
	padding-right: var(--hero-default-image-content-padding-h-mobile, var(--projInterval));
}

@media only screen and (min-width: 768px)
{
	.defaultImageHero__text
	{
		padding-top: var(--hero-default-image-content-padding-top-tablet, var(--projInterval));
		padding-bottom: var(--hero-default-image-content-padding-bottom-tablet, var(--projInterval));
		padding-left: var(--hero-default-image-content-padding-h-tablet, var(--projInterval));
		padding-right: var(--hero-default-image-content-padding-h-tablet, var(--projInterval));
	}
}
@media only screen and (min-width: 1024px)
{
	.defaultImageHero__text
	{
		padding-top: var(--hero-default-image-content-padding-top-desktop, var(--projInterval));
		padding-bottom: var(--hero-default-image-content-padding-bottom-desktop, var(--projInterval));
		padding-left: var(--hero-default-image-content-padding-h-desktop, var(--projInterval));
		padding-right: var(--hero-default-image-content-padding-h-desktop, var(--projInterval));
	}
}
@media only screen and (min-width: 1440px)
{
	.defaultImageHero__text
	{
		padding-top: var(--hero-default-image-content-padding-top-desktop-lg, var(--projInterval));
		padding-bottom: var(--hero-default-image-content-padding-bottom-desktop-lg, var(--projInterval));
		padding-left: var(--hero-default-image-content-padding-h-desktop-lg, var(--projInterval));
		padding-right: var(--hero-default-image-content-padding-h-desktop-lg, var(--projInterval));
	}
}

/* No image — same vertical alignment as Default (No Image): a plain block
   in normal document flow, not flex-aligned to the bottom of an image band
   that no longer exists. */
.defaultImageHero:not(.has-image) .defaultImageHero__text
{
	display: block;
	min-height: 0;
	padding-left: 0;
	padding-right: 0;
}

/* Supertitle — every hero-enabled post type (acf-json/group_page_supertitle.json,
   expanded from Page-only). Independent Type Role + animation, unlike
   Client/Date below which reuse V1's shared controls — no other hero style
   renders a supertitle, so there's nothing to share it with. */
.defaultImageHero__text .supertitle
{
	display: block;
	margin: 0 0 0.4em;
	font-family: var(--hero-default-image-supertitle-family, inherit);
	font-weight: var(--hero-default-image-supertitle-weight, inherit);
	font-style: var(--hero-default-image-supertitle-style, inherit);
	font-size: var(--hero-default-image-supertitle-size, 0.85rem);
	line-height: var(--hero-default-image-supertitle-line-height, 1);
	letter-spacing: var(--hero-default-image-supertitle-letter-spacing, 0.05em);
	text-transform: var(--hero-default-image-supertitle-text-transform, uppercase);
	color: var(--hero-default-image-supertitle-color, var(--hero-default-image-headline-color, #fff));
	opacity: 0.85;
}

/* Client name badge — brand/website/video only (see the template's own
   $client resolution). Shares the exact same Type Role control as V1 —
   Classic's own client badge (hero_v1_client_type_role) under a second
   --hero-default-image-client-* namespace, rather than an independent
   field — "one set of controls" for whichever hero style renders it. */
/* #SD prefix needed to outrank the sitewide #SD H1 reset (SDstandards.css)
   — .client is a literal <h1> tag, unlike .headline's WYSIWYG-flexible
   wrapper, so plain-class specificity alone would lose to it. Same fix V1
   — Classic's own client badge already applies (hero-v1.css). */
#SD .defaultImageHero__text .client
{
	margin: 0 0 0.4em;
	font-family: var(--hero-default-image-client-family, inherit);
	font-weight: var(--hero-default-image-client-weight, inherit);
	font-style: var(--hero-default-image-client-style, normal);
	font-size: var(--hero-default-image-client-size, 0.9rem);
	line-height: var(--hero-default-image-client-line-height, inherit);
	letter-spacing: var(--hero-default-image-client-letter-spacing, inherit);
	text-transform: var(--hero-default-image-client-text-transform, inherit);
	color: var(--hero-default-image-client-color, var(--hero-default-image-headline-color, #fff));
}
.defaultImageHero__text .client .label
{
	opacity: 0.7;
	margin-right: 0.4em;
}

/* Date — Blog Post only, same shared control as V1's date (hero_date_type_role,
   hero_date_anim_*) under a --hero-default-image-date-* namespace. */
.defaultImageHero__text .headline .heroDate
{
	display: block;
	font-family: var(--hero-default-image-date-family, inherit);
	font-weight: var(--hero-default-image-date-weight, inherit);
	font-style: var(--hero-default-image-date-style, inherit);
	font-size: var(--hero-default-image-date-size, 0.85rem);
	line-height: var(--hero-default-image-date-line-height, 1);
	letter-spacing: var(--hero-default-image-date-letter-spacing, 0.05em);
	text-transform: var(--hero-default-image-date-text-transform, uppercase);
	color: var(--hero-default-image-date-color, var(--hero-default-image-headline-color, #fff));
	opacity: 0.85;
	margin-bottom: 0.5em;
}

/* Headline — wrapped in .headline regardless of whether it's the plain-title
   <h1> fallback or real WYSIWYG content (acf-json/group_hero.json `headline`
   field), same convention as V1 — Classic
   (template-parts/heroes/hero-v1.php, .projectIntro.version01 .headline) —
   targeting the wrapper class works either way; targeting `h1` directly
   wouldn't match when the WYSIWYG field holds real content. */
.defaultImageHero__text .headline
{
	margin: 0;
	font-family: var(--hero-default-image-headline-family, var(--font-primary));
	font-weight: var(--hero-default-image-headline-weight, 700);
	font-size: var(--hero-default-image-headline-size, var(--titleSizeSmall));
	line-height: var(--hero-default-image-headline-line-height, 1);
	letter-spacing: var(--hero-default-image-headline-letter-spacing, normal);
	text-transform: var(--hero-default-image-headline-text-transform, none);
	color: var(--hero-default-image-headline-color, #fff);
}

/* The `headline` field's own child element (the plain-title <h1> fallback,
   or a wpautop-wrapped <p> from real WYSIWYG content) carries its own
   browser-default margin-bottom. That stacks on top of the container's
   configured content-padding-bottom, so the visible gap below the title
   ends up bigger than the configured value — never matching the h-padding
   even when both tokens are set equal. Zeroing it here (same fix V1 —
   Classic already applies to its own .headline h1) makes the container's
   own padding the only source of bottom spacing. */
.defaultImageHero__text .headline > *:last-child
{
	margin-bottom: 0;
}

.defaultImageHero:not(.has-image) .defaultImageHero__text .headline
{
	color: var(--hero-default-image-headline-color, inherit);
}

/* Desktop alignment (min-width: 1024px) — the headline lines up with the
   page's own body-text width instead of using its own padding tokens.
   Reuses the sitewide page-width tier system (shew_page_width ACF field,
   body class width-{boxed|wide|very_wide|full} from
   inc/hooks/page-width-control.php, tokens from
   assets/css/global/components/page-width-control.css) that
   H1.entry-title and .entry-content's children already align to, rather
   than a bespoke width control — so the hero title, the page title on
   every other hero style, and the body copy all share one left edge with
   no extra field to keep in sync.

   width-* classes only exist on page/brand/website/process (see that
   hook) — Post has its own separate width system (--maxWidth, see the
   block below this one) and Video has no width system to align to at
   all, so it falls through to the plain content-padding-h-desktop/
   -desktop-lg padding unchanged.

   Below 1024px this block doesn't apply at all — the responsive
   content-padding-h-mobile/-tablet tokens above are the only thing
   controlling horizontal spacing there, for every post type. That's the
   "padding kicks in on mobile/tablet" half of this. */
@media only screen and (min-width: 1024px)
{
	#SD.width-boxed .defaultImageHero__text,
	#SD.width-wide .defaultImageHero__text,
	#SD.width-very_wide .defaultImageHero__text,
	#SD.width-full .defaultImageHero__text
	{
		padding-left: 0;
		padding-right: 0;
	}

	#SD.width-boxed .defaultImageHero__text .headline,
	#SD.width-boxed .defaultImageHero__text .client,
	#SD.width-boxed .defaultImageHero__text .supertitle
	{
		width: 100%;
		max-width: var(--boxedWidth);
		margin-left: auto;
		margin-right: auto;
	}
	#SD.width-wide .defaultImageHero__text .headline,
	#SD.width-wide .defaultImageHero__text .client,
	#SD.width-wide .defaultImageHero__text .supertitle
	{
		width: 100%;
		max-width: var(--wideWidth);
		margin-left: auto;
		margin-right: auto;
	}
	#SD.width-very_wide .defaultImageHero__text .headline,
	#SD.width-very_wide .defaultImageHero__text .client,
	#SD.width-very_wide .defaultImageHero__text .supertitle
	{
		width: 100%;
		max-width: var(--veryWideWidth);
		margin-left: auto;
		margin-right: auto;
	}
	#SD.width-full .defaultImageHero__text .headline,
	#SD.width-full .defaultImageHero__text .client,
	#SD.width-full .defaultImageHero__text .supertitle
	{
		max-width: none;
		margin-left: var(--insetLMargin);
		margin-right: 0;
	}
}

/* Post alignment (min-width: 1024px) — Post isn't part of the page-width
   tier system above at all (page-width-control.php only runs for
   page/brand/website/process). Its body text uses a completely separate
   width mechanism instead: single_post.css's own
   `body.single-post.full-width-content div.entry-content { max-width:
   var(--maxWidth); }`, combined with .entry-content's sitewide
   margin:auto (global.min.css). Same --maxWidth token, same selector
   scope, so the headline lands on the same left edge as the post body. */
@media only screen and (min-width: 1024px)
{
	body.single-post.full-width-content .defaultImageHero__text
	{
		padding-left: 0;
		padding-right: 0;
	}
	body.single-post.full-width-content .defaultImageHero__text .headline,
	body.single-post.full-width-content .defaultImageHero__text .client,
	body.single-post.full-width-content .defaultImageHero__text .supertitle
	{
		width: 100%;
		max-width: var(--maxWidth);
		margin-left: auto;
		margin-right: auto;
	}
}

/* Color Palette swatch strip — Blog Post only (Design Tokens → Heroes,
   shared --hero-palette-* tokens — same source V1 — Classic's own palette
   strip uses, "one set of controls"). Renders below the hero in normal
   document flow rather than overlapping the image, since .defaultImageHero
   has a fixed height for its image band and isn't meant to grow to fit it. */
.defaultImagePalette
{
	position: relative;
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	margin-top: var(--hero-palette-gap-desktop, 0px);
	margin-bottom: var(--hero-default-image-margin-bottom, 0);
}
.defaultImagePalette .swatch
{
	height: var(--hero-palette-height-desktop, 2.75rem);
	position: relative;
	display: flex;
	align-items: center;
	padding: var(--hero-palette-padding-desktop, 0 0.6rem);
	transition: transform var(--hero-palette-reveal-duration, 0.6s) ease, opacity var(--hero-palette-reveal-duration, 0.6s) ease;
	transition-delay: calc(var(--hero-palette-stagger-step, 0s) * var(--i, 0));
}
@media only screen and (max-width: 1024px)
{
	.defaultImagePalette
	{
		margin-top: var(--hero-palette-gap-tablet, 0px);
	}
	.defaultImagePalette .swatch
	{
		height: var(--hero-palette-height-tablet, 2.75rem);
		padding: var(--hero-palette-padding-tablet, 0 0.6rem);
	}
}
@media only screen and (max-width: 600px)
{
	.defaultImagePalette
	{
		margin-top: var(--hero-palette-gap-mobile, 0px);
	}
	.defaultImagePalette .swatch
	{
		height: var(--hero-palette-height-mobile, 2.75rem);
		padding: var(--hero-palette-padding-mobile, 0 0.5rem);
	}
}
body:not(.launch) .defaultImagePalette .swatch
{
	transform: translateY(100%);
	opacity: 0;
}
.defaultImagePalette .swatch .hex
{
	font-family: var(--font-primary, inherit);
	font-size: 0.68rem;
	letter-spacing: 0.03em;
	font-variant-numeric: tabular-nums;
	text-transform: uppercase;
	padding: 0.15rem 0.4rem;
	border-radius: 2px;
	background: rgba(255, 255, 255, 0.14);
	color: #f4f3ee;
}
.defaultImagePalette .swatch.is-light .hex
{
	background: rgba(0, 0, 0, 0.12);
	color: #15181c;
}
