/**
 * Logo Reveal Hero
 *
 * On-load: the ATOMICDUST wordmark splits open, a stage grows in the gap,
 * flashes through work images, settles on a video, then the video fills the
 * screen and a bottom title + paragraph fade in. On scroll the hero is pinned
 * and the following white section parallaxes over it (mirrors the drift hero).
 *
 * Motion/positions are driven by assets/js/reveal-hero.js. Animation-specific
 * layout is gated behind .atmdst-reveal.is-ready so the editor (no JS) shows a
 * plain, editable stack of the image/video/text blocks.
 *
 * Colors come from block classes (primary bg / secondary text) in the markup.
 */

/* overflow:clip contains the two wordmark halves as they ride off-screen.
   z-index:0 makes this a stacking context the pinned hero sits inside, so the
   raised sections below can slide over it. */
.atmdst-reveal-outer {
	overflow: clip;
	position: relative;
	z-index: 0;
}

.atmdst-reveal {
	position: relative;
	min-height: 100svh;
	overflow: hidden;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* ── Editor / no-JS fallback: a plain editable stack ─────────────── */
.atmdst-reveal__logo-half {
	display: none; /* decorative; only shown once JS mounts the animation */
}

.atmdst-reveal__stage {
	position: relative;
	width: 100%;
	max-width: 30rem;
	margin-inline: auto;
}

/* ══════════════════════════════════════════════════════════════════
   JS-mounted animation layout
   ══════════════════════════════════════════════════════════════════ */
.atmdst-reveal.is-ready .atmdst-reveal__lockup {
	position: relative;
	z-index: 1;
	--logo-w: min(82vw, 900px);
	/* Fraction of the wordmark that is "ATOMIC" — the split falls here, in the
	   gap between C (ink ends x≈170) and D (ink starts x≈177) of the 334.64
	   viewBox, i.e. centre x≈173.5. Tune to move the split. */
	--split: 0.518;
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: center;
	width: 100%;
}

/* Logo halves — each clips to its share of the wordmark; adjacent (stage
   width 0) they read as one lockup, and part as the stage grows between them.
   Left shows ATOMIC, right shows DUST™. */
.atmdst-reveal.is-ready .atmdst-reveal__logo-half {
	display: flex;
	flex: 0 0 auto;
	overflow: hidden;
}
.atmdst-reveal.is-ready .atmdst-reveal__logo-half.is--left {
	width: calc(var(--logo-w) * var(--split));
	justify-content: flex-start;
}
.atmdst-reveal.is-ready .atmdst-reveal__logo-half.is--right {
	width: calc(var(--logo-w) * (1 - var(--split)));
	justify-content: flex-end;
}
.atmdst-reveal.is-ready .atmdst-reveal__logo-half svg {
	flex: 0 0 auto;
	width: var(--logo-w);
	height: auto;
	display: block;
}

/* Force white fill. The inlined logo SVGs (reveal + footer) share an unscoped
   `.cls-1` fill rule; the footer's copy (later in the DOM) otherwise wins and
   recolors this wordmark. Targeting the paths directly outranks `.cls-1`. */
.atmdst-reveal__logo-half svg path {
	fill: #fff;
}

/* Stage — the panel that grows open then fills the viewport. */
.atmdst-reveal.is-ready .atmdst-reveal__stage {
	flex: 0 0 auto;
	width: 0;            /* JS animates width (open → fullscreen) */
	height: 62vh;        /* JS animates height at fullscreen */
	max-width: none;
	margin: 0;
	overflow: hidden;
	background: #000;
	align-self: center;
}

/* Fullscreen end state. Up to this point the stage is a flex item, which is what
   levers the two wordmark halves apart — but flex centring puts it
   (split - 0.5) * --logo-w to the right of centre, so it never covers the hero's
   left edge. Absolute inset:0 makes it exactly the hero's box instead, at any
   viewport and through any resize. reveal-hero.js adds .is-filled to the hero
   once the growth finishes, and clears the inline width/height it tweened.

   The lockup has to be pinned open too. It is position:relative, so it — not the
   hero — is the stage's containing block; left as an auto-height flex row it
   collapses once the stage goes absolute, and inset:0 then resolves against a
   zero-height box. Filling the lockup first makes the two boxes identical, so
   the stage's inset:0 lands on the hero exactly. */
.atmdst-reveal.is-ready.is-filled .atmdst-reveal__lockup {
	position: absolute;
	inset: 0;
}

/* Explicit 100%/100% rather than inset:0 with auto sizing. The base rule gives
   the stage align-self:center for the flex phase, and that keeps winning over an
   auto cross-axis size — the box resolved to zero height sitting at the hero's
   vertical centre. Percentages against the containing block (the filled lockup,
   which is the hero's box) are unambiguous. */
.atmdst-reveal.is-ready.is-filled .atmdst-reveal__stage {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	align-self: stretch;
}

.atmdst-reveal.is-ready .atmdst-reveal__flash,
.atmdst-reveal.is-ready .atmdst-reveal__video {
	position: absolute;
	inset: 0;
	margin: 0;
}
.atmdst-reveal.is-ready .atmdst-reveal__flash img,
.atmdst-reveal.is-ready .atmdst-reveal__video video {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Stack order: flash images on top, video underneath (revealed as they fade). */
.atmdst-reveal.is-ready .atmdst-reveal__flash.is--1 { z-index: 3; }
.atmdst-reveal.is-ready .atmdst-reveal__flash.is--2 { z-index: 2; }
.atmdst-reveal.is-ready .atmdst-reveal__flash.is--3 { z-index: 1; }
.atmdst-reveal.is-ready .atmdst-reveal__video        { z-index: 0; }

/* Bottom scrim so the info + pause button stay legible over the video.

   Fades in with the words — reveal-hero.js animates --atmdst-reveal-scrim from
   0 to 1 just ahead of the text, so the video reads clean while the wordmark is
   still on screen and only darkens once there is copy to carry. Defaults to 1,
   which is what the editor, reduced-motion and already-scrolled paths get.

   Strength is set by contrast, not taste. The video is arbitrary footage, so the
   worst case is a blown-out white frame. Black at alpha a over white leaves sRGB
   (1 - a); white text needs a background luminance <= 0.183 to reach 4.5:1,
   which solves to a >= 0.54. The plateau below holds >= 0.75 across the whole
   text band, so even a white frame gives >= 10:1 — and the small copy passes on
   its own merit, not just the large heading. */
.atmdst-reveal.is-ready::after {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 70%;
	z-index: 4;
	pointer-events: none;
	opacity: var(--atmdst-reveal-scrim, 1);
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, 0.88) 0%,
		rgba(0, 0, 0, 0.75) 40%,
		rgba(0, 0, 0, 0.4) 70%,
		rgba(0, 0, 0, 0) 100%
	);
}

/* Bottom info bar — full-width row of three columns:
   title 50% | paragraph 45% | pause button 5%.

   The bar is anchored to the bottom, but the columns top-align to each other:
   the copy column (paragraph + button) is the taller of the two, so bottom-
   aligning left the headline hanging at the foot of the bar with its first line
   far below the paragraph's. Most obvious as the viewport narrows and the copy
   wraps to more lines. flex-start puts both first lines on the same baseline
   edge; the pause control opts back out to the corner below. */
.atmdst-reveal.is-ready .atmdst-reveal__info {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 5;
	display: flex;
	flex-direction: row;
	align-items: flex-start;
	gap: clamp(1.5rem, 5vw, 5rem);
	padding: clamp(1.25rem, 4vw, 3.25rem);
	padding-top: 0;
	text-align: left;
}
.atmdst-reveal.is-ready .atmdst-reveal__title-col {
	flex: 62 1 0;                 /* title column */
	min-width: 0;
	container-type: inline-size;  /* the h1 sizes to THIS column's width (cqw) */
}
.atmdst-reveal.is-ready .atmdst-reveal__title {
	margin: 0;
	font-size: 8.5cqw;            /* fluid — fills the column width (line 1 ≈ full width) */
	line-height: 1.02;
}
.atmdst-reveal.is-ready .atmdst-reveal__copy-col {
	flex: 30 1 0;                 /* paragraph column */
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.25rem;
}
.atmdst-reveal.is-ready .atmdst-reveal__copy {
	margin: 0;
	line-height: 1.4;
	opacity: 0.85;
}
.atmdst-reveal.is-ready .atmdst-reveal__actions {
	margin: 0;
}
.atmdst-reveal.is-ready .atmdst-reveal__pause-col {
	flex: 0 0 auto;               /* button's natural width, pinned to the right */
	align-self: flex-end;         /* stays in the corner while the text top-aligns */
	display: flex;
	justify-content: flex-end;
	align-items: flex-end;
}

/* Stack the bar on narrow screens (3 columns are too tight to read). */
@media (max-width: 767px) {
	.atmdst-reveal.is-ready .atmdst-reveal__info {
		flex-direction: column;
		align-items: flex-start;
		gap: 0.6rem;
	}
	.atmdst-reveal.is-ready .atmdst-reveal__title-col,
	.atmdst-reveal.is-ready .atmdst-reveal__copy-col {
		flex: 0 0 auto;
		width: 100%;
		max-width: 100%;
	}
	.atmdst-reveal.is-ready .atmdst-reveal__pause-col {
		flex: 0 0 auto;
		align-self: flex-end;
	}
}

/* Accessible pause/play toggle (WCAG 2.2.2). Lives in the info bar's last
   column; shape, colors, hover and focus ring come from the shared
   .ad-pause-btn component (global.css), matching every other pause control. */
.atmdst-reveal__pause {
	flex: 0 0 auto;
}

/* ── Parallax overlap (mirrors the drift/about hero) ──────────────
   reveal-hero.js pins .atmdst-reveal with pinSpacing:false; the content below
   rides up over it for one viewport, then the pin releases into natural flow.

   EVERY following section is raised, not just the immediate one. The outer is a
   stacking context at z-index 0, so a later section left unpositioned paints
   *underneath* the pinned hero — which is why only the services bar used to
   travel over it while the statement section behind stayed invisible until the
   pin released.

   A sibling selector rather than a JS-added class: the previous version tagged
   outer.nextElementSibling only, which is the single-sibling bug above.

   :where() on purpose — it contributes ZERO specificity, so these are the
   weakest possible declarations and anything that positions or paints itself
   wins outright. That matters: `~ *` also sweeps up floating blocks that are
   not sections at all. The PE sticky CTA (.ad-pe-cta) is position:fixed with
   z-index:1200 and its own frosted background, all at plain class specificity —
   with a normal `.atmdst-reveal-outer ~ *` selector this file loads later and
   overrides it, dropping the floating card into the flow and repainting it
   white. At zero specificity it keeps everything it declares. */
:where(.atmdst-reveal-outer) ~ * {
	position: relative;
	z-index: 2;
}

/* Sections that declare no background of their own would let the hero show
   through as they cross it. Give them the white they already sit on in normal
   flow — visually identical, opaque during the overlap. Guarded twice: the
   :not() skips sections with a background preset class (the muted services
   bar), and :where() yields to any element painting its own background.

   The :not() is itself wrapped in :where() because :not() otherwise inherits
   the specificity of its argument — the bare attribute selector made this rule
   (0,1,0), enough to beat the PE CTA's own frosted background and paint the
   floating card white. */
:where(.atmdst-reveal-outer) ~ *:where(:not([class*="-background-color"])) {
	background-color: var(--wp--preset--color--secondary);
}

@media (max-width: 767px) {
	.atmdst-reveal.is-ready .atmdst-reveal__lockup {
		--logo-w: min(92vw, 520px);
	}
}
