/* ============================================================================
   EUX Blocks — Entrance animations (front-end only)
   ----------------------------------------------------------------------------
   This stylesheet is enqueued via wp_enqueue_scripts (front-end only) and is
   NOT loaded inside the editor. That separation matters because every rule
   in this file defines a hidden state (opacity:0, transform offset) that
   only becomes visible after frontend.js adds `.eux-is-in-view` on viewport
   entry. In the editor, frontend.js does not run — so if these rules
   applied there, content would stay permanently invisible on the canvas.

   Architecture rule:
   Hidden states are defined via selectors that match classes already in
   the rendered HTML at page load (e.g. `.eux-block--cap-card`,
   `.eux-hero__title`, `.eux-cap-section__hdr`). Visible states are
   triggered by JS adding `.eux-is-in-view` to a containing element.

   Why never put the hidden state on a JS-added class:
   For above-the-fold elements, JS typically adds the hidden-state class
   and the visible-state class within the same task. The browser collapses
   both style changes into one paint and skips the transition entirely.
   ============================================================================ */

/* ─── Generic simple reveal — fade + lift ─────────────────────────────── */
.eux-reveal {
	opacity: 0;
	transform: translateY(24px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
	will-change: opacity, transform;
}
.eux-reveal.eux-is-in-view {
	opacity: 1;
	transform: none;
	will-change: auto;
}

/* ─── Scale variant — for visual elements (mockups, images) ─────────────── */
.eux-reveal--scale,
.eux-block .eux-hero__mock-frame.eux-reveal {
	opacity: 0;
	transform: scale(0.97) translateY(24px);
	transition:
		opacity   var(--eux-dur-reveal-long) var(--eux-ease-expo),
		transform var(--eux-dur-reveal)      var(--eux-ease-expo);
	will-change: opacity, transform;
}
.eux-reveal--scale.eux-is-in-view,
.eux-block .eux-hero__mock-frame.eux-reveal.eux-is-in-view {
	opacity: 1;
	transform: none;
	will-change: auto;
}

/* ============================================================================
   SECTION HEADERS — eyebrow / title / sub stagger
   ============================================================================ */
.eux-block .eux-cap-section__hdr .eux-eyebrow,
.eux-block .eux-cap-section__hdr .eux-cap-section__title,
.eux-block .eux-cap-section__hdr .eux-cap-section__sub {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block .eux-cap-section__hdr.eux-is-in-view .eux-eyebrow {
	opacity: 1; transform: none; transition-delay: 0ms;
}
.eux-block .eux-cap-section__hdr.eux-is-in-view .eux-cap-section__title {
	opacity: 1; transform: none; transition-delay: 130ms;
}
.eux-block .eux-cap-section__hdr.eux-is-in-view .eux-cap-section__sub {
	opacity: 1; transform: none; transition-delay: 260ms;
}

/* ============================================================================
   SERVICE HERO — title → sub1 → sub2 → CTAs stagger
   ----------------------------------------------------------------------------
   Hidden state matches natural markup classes (.eux-hero__title,
   .eux-hero__sub, .eux-hero__ctas .wp-block-button) so opacity:0 is
   painted on the first frame, before JS runs.

   The .eux-hero__ctas wrapper itself stays at default opacity. If we
   faded it AND the buttons inside, the cascaded opacity multiplication
   would leave buttons stuck at partial visibility for the duration of
   the parent fade.
   ============================================================================ */
.eux-block--service-hero .eux-hero__title,
.eux-block--service-hero .eux-hero__sub {
	opacity: 0;
	transform: translateY(24px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
	will-change: opacity, transform;
}
.eux-block--service-hero.eux-is-in-view .eux-hero__title {
	opacity: 1; transform: none; transition-delay: 0ms;
}
.eux-block--service-hero.eux-is-in-view .eux-hero__sub:nth-of-type(1) {
	opacity: 1; transform: none; transition-delay: 150ms;
}
.eux-block--service-hero.eux-is-in-view .eux-hero__sub:nth-of-type(2) {
	opacity: 1; transform: none; transition-delay: 300ms;
}

.eux-block--service-hero .eux-hero__ctas .wp-block-button {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   var(--eux-dur-slow) var(--eux-ease-expo),
		transform var(--eux-dur-slow) var(--eux-ease-expo);
}
.eux-block--service-hero.eux-is-in-view .eux-hero__ctas .wp-block-button:nth-child(1) {
	opacity: 1; transform: none; transition-delay: 450ms;
}
.eux-block--service-hero.eux-is-in-view .eux-hero__ctas .wp-block-button:nth-child(2) {
	opacity: 1; transform: none; transition-delay: 560ms;
}

/* ============================================================================
   CAPABILITY CARDS — card scale+lift, then internal stagger
   ----------------------------------------------------------------------------
   Two-layer reveal:
   1. The card scales+lifts in as a single unit.
   2. Inside, num → title → mockup → copy → list items → trailing copy stagger.

   Cards are observed individually by frontend.js, so the grid-level cascade
   happens via IntersectionObserver's natural entries-batching (cards entering
   in the same observation cycle get 180ms between them; cards entering alone
   appear immediately).
   ============================================================================ */
.eux-block--cap-card {
	opacity: 0;
	transform: scale(0.97) translateY(24px);
	transition:
		opacity   var(--eux-dur-reveal-long) var(--eux-ease-expo),
		transform var(--eux-dur-reveal)      var(--eux-ease-expo);
	will-change: opacity, transform;
}
.eux-block--cap-card.eux-is-in-view {
	opacity: 1; transform: none; will-change: auto;
}

.eux-block--cap-card .eux-cap__num,
.eux-block--cap-card .eux-cap__title,
.eux-block--cap-card .eux-block--cap-mockup,
.eux-block--cap-card .eux-cap__copy,
.eux-block--cap-card .eux-cap__list li {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   var(--eux-dur-slow) var(--eux-ease-expo),
		transform var(--eux-dur-slow) var(--eux-ease-expo);
}
.eux-block--cap-card.eux-is-in-view .eux-cap__num {
	opacity: 1; transform: none; transition-delay: 150ms;
}
.eux-block--cap-card.eux-is-in-view .eux-cap__title {
	opacity: 1; transform: none; transition-delay: 250ms;
}
.eux-block--cap-card.eux-is-in-view .eux-block--cap-mockup {
	opacity: 1; transform: none; transition-delay: 350ms;
}
.eux-block--cap-card.eux-is-in-view .eux-cap__copy:nth-of-type(1) {
	opacity: 1; transform: none; transition-delay: 450ms;
}
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(1) { opacity: 1; transform: none; transition-delay: 550ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(2) { opacity: 1; transform: none; transition-delay: 610ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(3) { opacity: 1; transform: none; transition-delay: 670ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(4) { opacity: 1; transform: none; transition-delay: 730ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(5) { opacity: 1; transform: none; transition-delay: 790ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(6) { opacity: 1; transform: none; transition-delay: 850ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(7) { opacity: 1; transform: none; transition-delay: 910ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__list li:nth-child(8) { opacity: 1; transform: none; transition-delay: 970ms; }
.eux-block--cap-card.eux-is-in-view .eux-cap__copy:nth-of-type(2) {
	opacity: 1; transform: none; transition-delay: 1050ms;
}

/* ============================================================================
   EXAMPLE CARDS — icon → name → line → mockup stagger
   ============================================================================ */
.eux-block--example-card {
	opacity: 0;
	transform: scale(0.97) translateY(24px);
	transition:
		opacity   var(--eux-dur-reveal-long) var(--eux-ease-expo),
		transform var(--eux-dur-reveal)      var(--eux-ease-expo);
	will-change: opacity, transform;
}
.eux-block--example-card.eux-is-in-view {
	opacity: 1; transform: none; will-change: auto;
}

.eux-block--example-card .eux-example__ic,
.eux-block--example-card .eux-example__name,
.eux-block--example-card .eux-example__line,
.eux-block--example-card .eux-example__mock {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   var(--eux-dur-slow) var(--eux-ease-expo),
		transform var(--eux-dur-slow) var(--eux-ease-expo);
}
.eux-block--example-card.eux-is-in-view .eux-example__ic   { opacity: 1; transform: none; transition-delay: 150ms; }
.eux-block--example-card.eux-is-in-view .eux-example__name { opacity: 1; transform: none; transition-delay: 250ms; }
.eux-block--example-card.eux-is-in-view .eux-example__line { opacity: 1; transform: none; transition-delay: 350ms; }
.eux-block--example-card.eux-is-in-view .eux-example__mock { opacity: 1; transform: none; transition-delay: 450ms; }

/* ============================================================================
   CASE STUDIES — section header + card grid reveal
   ----------------------------------------------------------------------------
   The case-studies section is observed by frontend.js's revealSelectors
   list (covers `.eux-cs__hdr` and `.eux-cs-card`); cards are also in the
   CARD_SELECTOR so they get the 180ms inter-card batch stagger.

   This block was missing in the original release — JS toggled
   `.eux-is-in-view` correctly but no CSS responded, so cards just
   appeared. v0.36.24 fills the gap.

   Card stagger inside: image → title → desc → tags → foot button.
   Image first because it's the visual anchor; foot button last because
   it's the call-to-action that should land after the user has had time
   to read the card.
   ============================================================================ */

/* --- Section header: eyebrow → title → sub --- */
.eux-block .eux-cs__hdr .eux-eyebrow,
.eux-block .eux-cs__hdr .eux-cs__title,
.eux-block .eux-cs__hdr .eux-cs__sub {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block .eux-cs__hdr.eux-is-in-view .eux-eyebrow {
	opacity: 1; transform: none; transition-delay: 0ms;
}
.eux-block .eux-cs__hdr.eux-is-in-view .eux-cs__title {
	opacity: 1; transform: none; transition-delay: 130ms;
}
.eux-block .eux-cs__hdr.eux-is-in-view .eux-cs__sub {
	opacity: 1; transform: none; transition-delay: 260ms;
}

/* --- Card outer: scale + lift in (matches cap-card / example-card) --- */
.eux-block--case-study-card {
	opacity: 0;
	transform: scale(0.97) translateY(24px);
	transition:
		opacity   var(--eux-dur-reveal-long) var(--eux-ease-expo),
		transform var(--eux-dur-reveal)      var(--eux-ease-expo);
	will-change: opacity, transform;
}
.eux-block--case-study-card.eux-is-in-view {
	opacity: 1; transform: none; will-change: auto;
}

/* --- Card inner: image → title → desc → tags → foot stagger ---
   The image, title, desc and foot are direct staggered targets. Tags fade
   together but their individual transition-delays inside the tags group
   produce a quick left-to-right cascade (60ms apart, lifted from the
   cap-card list rhythm). The accent tag leads.

   We intentionally don't stagger the client/sticker pills inside the
   image — they're decorations on the image and would over-complicate the
   choreography. They appear with the image as a single unit. */
.eux-block--case-study-card .eux-cs-card__img,
.eux-block--case-study-card .eux-cs-card__title,
.eux-block--case-study-card .eux-cs-card__desc,
.eux-block--case-study-card .eux-cs-card__tags,
.eux-block--case-study-card .eux-cs-card__foot {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   var(--eux-dur-slow) var(--eux-ease-expo),
		transform var(--eux-dur-slow) var(--eux-ease-expo);
}
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__img   { opacity: 1; transform: none; transition-delay: 100ms; }
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__title { opacity: 1; transform: none; transition-delay: 220ms; }
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__desc  { opacity: 1; transform: none; transition-delay: 320ms; }
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__tags  { opacity: 1; transform: none; transition-delay: 420ms; }
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__foot  { opacity: 1; transform: none; transition-delay: 540ms; }

/* Tag chip cascade — sits INSIDE the tags group fade above. Each tag
   starts hidden and lifts in 60ms after the previous one, anchored to
   the parent .eux-cs-card__tags group's own 420ms reveal delay so the
   tags fade in just after their container does.

   Why not just rely on the parent group's fade alone: a single fade
   on the tags container leaves them feeling static. The short
   internal cascade adds liveliness for what's otherwise a row of
   identical-looking pills. */
.eux-block--case-study-card .eux-cs-card__tag {
	opacity: 0;
	transform: translateY(8px);
	transition:
		opacity   var(--eux-dur-base) var(--eux-ease-expo),
		transform var(--eux-dur-base) var(--eux-ease-expo);
}
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__tag:nth-child(1) { opacity: 1; transform: none; transition-delay: 460ms; }
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__tag:nth-child(2) { opacity: 1; transform: none; transition-delay: 520ms; }
.eux-block--case-study-card.eux-is-in-view .eux-cs-card__tag:nth-child(3) { opacity: 1; transform: none; transition-delay: 580ms; }

/* ============================================================================
   DAAS — column children stagger independently
   ----------------------------------------------------------------------------
   The .eux-daas card itself does NOT animate as a whole. If it faded while
   its children also faded, the cascaded opacity multiplication would mask
   the column stagger. Card is structurally visible from page load; only
   the column children choreograph.
   ============================================================================ */
.eux-block--daas .eux-daas__left > *,
.eux-block--daas .eux-daas__right > * {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left  > * { opacity: 1; transform: none; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__right > * { opacity: 1; transform: none; }

.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(1) { transition-delay: 0ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(2) { transition-delay: 130ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(3) { transition-delay: 260ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(4) { transition-delay: 390ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(5) { transition-delay: 520ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(6) { transition-delay: 650ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__left > *:nth-child(7) { transition-delay: 780ms; }

.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__right > *:nth-child(1) { transition-delay: 100ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__right > *:nth-child(2) { transition-delay: 230ms; }

.eux-block--daas .eux-daas__list li {
	opacity: 0;
	transform: translateX(-8px);
	transition:
		opacity   var(--eux-dur-slow) var(--eux-ease-expo),
		transform var(--eux-dur-slow) var(--eux-ease-expo);
}
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(1) { opacity: 1; transform: none; transition-delay: 320ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(2) { opacity: 1; transform: none; transition-delay: 400ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(3) { opacity: 1; transform: none; transition-delay: 480ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(4) { opacity: 1; transform: none; transition-delay: 560ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(5) { opacity: 1; transform: none; transition-delay: 640ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(6) { opacity: 1; transform: none; transition-delay: 720ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(7) { opacity: 1; transform: none; transition-delay: 800ms; }
.eux-block--daas .eux-daas.eux-is-in-view .eux-daas__list li:nth-child(8) { opacity: 1; transform: none; transition-delay: 880ms; }

/* ============================================================================
   DAAS-SLACK — left-column copy staggers in, right-column panel follows
   ----------------------------------------------------------------------------
   Section wrapper carries `.eux-reveal` (set in render.php). The generic
   `.eux-reveal` rule above handles the wrapper's own fade + lift. The
   rules below choreograph the children inside that fade so the eyebrow,
   heading, copy, meta and CTA land in narrative order, and the right-
   column stats / Slack panel arrive together after the left column has
   started telling its story.

   We target the wrapper's in-view class (added by the IntersectionObserver
   in frontend.js) and reveal children from there. Hidden state is on
   classes already in the markup at page-load (`.eux-slack__eyebrow` etc.)
   so the off-state paints on the first frame, no flicker.

   The wrapper itself ALSO fades — that's fine here because the children's
   own opacity transitions multiply with the wrapper's only briefly, and
   the result reads as a single coherent emerge rather than a double-fade.
   If this ever feels too soft, drop the wrapper's opacity transition by
   adding `.eux-block--daas-slack { opacity: 1; }` here — but tested at
   the chosen timings it looks correct.
   ============================================================================ */
.eux-block--daas-slack .eux-slack__eyebrow,
.eux-block--daas-slack .eux-slack__title,
.eux-block--daas-slack .eux-slack__copy,
.eux-block--daas-slack .eux-slack__meta,
.eux-block--daas-slack .wp-block-buttons.eux-slack__ctas,
.eux-block--daas-slack .eux-slack__stats,
.eux-block--daas-slack .eux-slack__panel-frame {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--daas-slack.eux-is-in-view .eux-slack__eyebrow             { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--daas-slack.eux-is-in-view .eux-slack__title               { opacity: 1; transform: none; transition-delay: 120ms; }
/* Copy paragraphs: every `.eux-slack__copy` reveals at 240ms by default;
   any `.eux-slack__copy` that comes AFTER another `.eux-slack__copy`
   (general sibling combinator `~`) overrides to 360ms for the cascade.

   Why not :nth-of-type — :nth-of-type filters by tag name (e.g. `<p>`),
   NOT by class. With an eyebrow `<p>` and a meta `<p>` interleaved
   between the copy paragraphs, `.eux-slack__copy:nth-of-type(1)`
   matches NOTHING (no copy is the 1st `<p>` — the eyebrow is) and
   `:nth-of-type(2)` matches only copy #1 (the 2nd `<p>`), leaving
   copy #2 with no reveal rule → stuck at opacity:0. The sibling
   combinator targets copies by class regardless of what tag types
   sit between them. */
.eux-block--daas-slack.eux-is-in-view .eux-slack__copy                  { opacity: 1; transform: none; transition-delay: 240ms; }
.eux-block--daas-slack.eux-is-in-view .eux-slack__copy ~ .eux-slack__copy { transition-delay: 360ms; }
.eux-block--daas-slack.eux-is-in-view .eux-slack__meta                { opacity: 1; transform: none; transition-delay: 480ms; }
.eux-block--daas-slack.eux-is-in-view .wp-block-buttons.eux-slack__ctas { opacity: 1; transform: none; transition-delay: 600ms; }
/* Right column starts a beat after the left's heading lands. */
.eux-block--daas-slack.eux-is-in-view .eux-slack__stats               { opacity: 1; transform: none; transition-delay: 240ms; }
.eux-block--daas-slack.eux-is-in-view .eux-slack__panel-frame         { opacity: 1; transform: none; transition-delay: 380ms; }

/* ============================================================================
   GOOD-FIT — left-column copy + trait grid stagger, matrix card follows
   ----------------------------------------------------------------------------
   Section wrapper carries `.eux-reveal` (set in render.php). The generic
   `.eux-reveal` rule earlier in this file handles the wrapper's own fade
   + lift. The rules below choreograph the children inside that fade so
   the section header (eyebrow, h2, two paragraphs, meta) cascades in,
   followed by the 2x2 trait grid and the matrix card on the right.

   The trait cards individually fade up with a 100ms inter-card stagger.
   Visually that produces a soft top-left → bottom-right ripple across
   the 2x2 grid (card 1 first, then 2, then 3, then 4 — DOM order),
   which feels like the page is "laying down its argument" piece by
   piece. The matrix card lands shortly after the heading so the user
   has somewhere to look while reading the body copy.

   Why we target the wrapper's in-view class (not the cards individually):
   four trait cards all need to fire together once the SECTION is in
   view, not when each individual card enters viewport. If each card
   were its own observer target, fast scrolling could promote them all
   on the same frame and the stagger would still work, but slow scrolling
   could promote them one-at-a-time as each crosses the threshold —
   producing a slow drip rather than a quick cascade. Pinning the stagger
   to the section wrapper's `.eux-is-in-view` guarantees the cascade
   plays as a single coherent unit regardless of scroll speed.
   ============================================================================ */
.eux-block--good-fit .eux-fit__eyebrow,
.eux-block--good-fit .eux-fit__title,
.eux-block--good-fit .eux-fit__copy,
.eux-block--good-fit .eux-fit__meta,
.eux-block--good-fit .eux-fit__trait,
.eux-block--good-fit .eux-fit__matrix {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--good-fit.eux-is-in-view .eux-fit__eyebrow             { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--good-fit.eux-is-in-view .eux-fit__title               { opacity: 1; transform: none; transition-delay: 120ms; }
/* Copy paragraphs: same sibling-combinator pattern as daas-slack — see
   the comment in that section for why `:nth-of-type` is wrong here
   (eyebrow and meta are also `<p>` elements, so the type-numbering
   drifts and the second copy never gets a reveal rule). */
.eux-block--good-fit.eux-is-in-view .eux-fit__copy                  { opacity: 1; transform: none; transition-delay: 240ms; }
.eux-block--good-fit.eux-is-in-view .eux-fit__copy ~ .eux-fit__copy { transition-delay: 320ms; }
.eux-block--good-fit.eux-is-in-view .eux-fit__meta                { opacity: 1; transform: none; transition-delay: 400ms; }

/* Trait cards: stagger across the 2x2 grid. Card 1 starts at 480ms so
   it overlaps slightly with the matrix card's entrance (380ms), but
   the cards land left→right so the user's eye can follow the
   cascade. Stays inside the 800ms ceiling the design reference uses. */
.eux-block--good-fit.eux-is-in-view .eux-fit__trait:nth-of-type(1) { opacity: 1; transform: none; transition-delay: 480ms; }
.eux-block--good-fit.eux-is-in-view .eux-fit__trait:nth-of-type(2) { opacity: 1; transform: none; transition-delay: 580ms; }
.eux-block--good-fit.eux-is-in-view .eux-fit__trait:nth-of-type(3) { opacity: 1; transform: none; transition-delay: 680ms; }
.eux-block--good-fit.eux-is-in-view .eux-fit__trait:nth-of-type(4) { opacity: 1; transform: none; transition-delay: 780ms; }

/* Right column: matrix card arrives just after the heading lands so
   the user has somewhere on the right to look while reading the body.
   The SVG drawing animations inside the matrix kick off after this
   entrance — they're keyframed in the matrix's own style.css with
   their own delays. */
.eux-block--good-fit.eux-is-in-view .eux-fit__matrix { opacity: 1; transform: none; transition-delay: 380ms; }

/* ============================================================================
   INTEGRATION-CTA — copy stack on the left, mosaic grid on the right
   ----------------------------------------------------------------------------
   Section wrapper carries `.eux-reveal` (set in render.php). The generic
   `.eux-reveal` rule earlier in this file handles the wrapper's own fade
   + lift. The rules below choreograph the children inside that fade:
   heading → sub → button on the left, then the mosaic tiles cascade in
   on the right.

   The mosaic tiles individually fade up with a small stagger (~50ms per
   tile across 12 tiles = ~550ms total). Visually that produces a soft
   top-left → bottom-right ripple across the 4×3 grid which reads as
   "the integrations are coming online piece by piece" — which is the
   metaphor of the section. Stays inside the 800ms ceiling for the
   meaningful portion of the cascade; the JS-driven "connecting → done"
   loop kicks in after the entrance is done.

   We target the wrapper's in-view class (not the tiles individually):
   12 tiles entering one-by-one as each crosses the viewport would
   feel slow and detached on a long scroll. Pinning the cascade to
   the section guarantees it plays as a single coherent unit.

   Corner brackets fade in at 0ms (with the wrapper) — they're
   decorative scaffolding, not part of the content cascade.
   ============================================================================ */
.eux-block--integration-cta .eux-icta__title,
.eux-block--integration-cta .eux-icta__sub,
.eux-block--integration-cta .wp-block-buttons.eux-icta__ctas,
.eux-block--integration-cta .eux-icta__tile {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--integration-cta.eux-is-in-view .eux-icta__title               { opacity: 1; transform: none; transition-delay: 0ms;   }
.eux-block--integration-cta.eux-is-in-view .eux-icta__sub                 { opacity: 1; transform: none; transition-delay: 120ms; }
.eux-block--integration-cta.eux-is-in-view .wp-block-buttons.eux-icta__ctas { opacity: 1; transform: none; transition-delay: 240ms; }

/* Mosaic tiles — 4×3 grid with a per-tile stagger. Tiles 1-12 enter
   from 280ms to 830ms (50ms apart). Inside the 800ms ceiling for the
   meaningful portion: the last tile's "entrance" overlaps with the
   end of the choreography rather than dragging on alone.

   Why we cap at 12 explicit selectors instead of a generic `:nth-child`
   formula: the render.php tile list is fixed at 12. If that ever
   grows, this list grows with it — easier than reading a calc()
   formula when debugging. */
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(1)  { opacity: 1; transform: none; transition-delay: 280ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(2)  { opacity: 1; transform: none; transition-delay: 330ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(3)  { opacity: 1; transform: none; transition-delay: 380ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(4)  { opacity: 1; transform: none; transition-delay: 430ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(5)  { opacity: 1; transform: none; transition-delay: 480ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(6)  { opacity: 1; transform: none; transition-delay: 530ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(7)  { opacity: 1; transform: none; transition-delay: 580ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(8)  { opacity: 1; transform: none; transition-delay: 630ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(9)  { opacity: 1; transform: none; transition-delay: 680ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(10) { opacity: 1; transform: none; transition-delay: 730ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(11) { opacity: 1; transform: none; transition-delay: 780ms; }
.eux-block--integration-cta.eux-is-in-view .eux-icta__tile:nth-of-type(12) { opacity: 1; transform: none; transition-delay: 830ms; }

/* ============================================================================
   SPLIT-FEATURE — eyebrow → title → lede → tiles → CTAs → media stagger
   ----------------------------------------------------------------------------
   v0.16.0 — Composition rewrite. The image now lives inside a
   core/columns + core/image structure rather than rendering from a
   block attribute. The choreography below targets:
     - Copy column: .eux-split__eyebrow / .eux-split__title /
       .eux-split__lede / .eux-split__tiles > li / .eux-split__ctas
     - Media column: the core/image inside .eux-split__col-media
       (selector targets `.wp-block-image` so any image block dropped
       into the media column animates; editors can swap or add images
       freely and the entrance keeps working).

   Section wrapper carries `.eux-reveal` (set in render.php). The
   generic `.eux-reveal` rule earlier in this file handles the wrapper's
   own fade + lift. The rules below choreograph the children inside
   that fade.

   The cascade reads left-to-right, top-to-bottom: eyebrow lands first,
   then the heading, then the lede body copy, then the six tiles in
   sequence, then the CTA row, with the image arriving in parallel
   with the lede so the eye has somewhere to land on the right (or
   left, when reversed) while the copy unrolls.

   Sibling-combinator pattern for tiles (`.eux-split__tiles > li ~ li`)
   — same lesson as v0.14.1, robust to mixed tag types and any number
   of items the editor adds.
   ============================================================================ */
.eux-block--split-feature .eux-split__eyebrow,
.eux-block--split-feature .eux-split__title,
.eux-block--split-feature .eux-split__lede,
.eux-block--split-feature .eux-split__tiles > li,
.eux-block--split-feature .wp-block-buttons.eux-split__ctas,
.eux-block--split-feature .eux-split__media,
.eux-block--split-feature .wp-block-column.eux-split__col-media .wp-block-image {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}

.eux-block--split-feature.eux-is-in-view .eux-split__eyebrow { opacity: 1; transform: none; transition-delay: 0ms;   }
.eux-block--split-feature.eux-is-in-view .eux-split__title   { opacity: 1; transform: none; transition-delay: 120ms; }
.eux-block--split-feature.eux-is-in-view .eux-split__lede    { opacity: 1; transform: none; transition-delay: 240ms; }

/* Tiles cascade — first tile at 360ms, each subsequent tile +60ms.
   Six tiles in the default template means the last tile lands at
   660ms; users adding a seventh would inherit the 660ms delay (no
   further stagger). Acceptable for the 6-tile design; if more
   granular stagger ever matters, add explicit nth-child selectors. */
.eux-block--split-feature.eux-is-in-view .eux-split__tiles > li                { opacity: 1; transform: none; transition-delay: 360ms; }
.eux-block--split-feature.eux-is-in-view .eux-split__tiles > li ~ li           { transition-delay: 420ms; }
.eux-block--split-feature.eux-is-in-view .eux-split__tiles > li ~ li ~ li      { transition-delay: 480ms; }
.eux-block--split-feature.eux-is-in-view .eux-split__tiles > li ~ li ~ li ~ li { transition-delay: 540ms; }
.eux-block--split-feature.eux-is-in-view .eux-split__tiles > li ~ li ~ li ~ li ~ li { transition-delay: 600ms; }
.eux-block--split-feature.eux-is-in-view .eux-split__tiles > li ~ li ~ li ~ li ~ li ~ li { transition-delay: 660ms; }

.eux-block--split-feature.eux-is-in-view .wp-block-buttons.eux-split__ctas { opacity: 1; transform: none; transition-delay: 740ms; }

/* Image arrives alongside the lede so the eye has something on the
   right (or left, when reversed) to track while reading the copy.
   Two selectors — one for legacy figure.eux-split__media (used by
   v0.15.0 instances that haven't migrated yet), one for the new
   core/image inside .eux-split__col-media. Both reveal at 240ms. */
.eux-block--split-feature.eux-is-in-view .eux-split__media                                       { opacity: 1; transform: none; transition-delay: 240ms; }
.eux-block--split-feature.eux-is-in-view .wp-block-column.eux-split__col-media .wp-block-image { opacity: 1; transform: none; transition-delay: 240ms; }

/* ============================================================================
   PROBLEM TRIO — section header stagger + per-card stagger + internal stagger
   ----------------------------------------------------------------------------
   1. Section header: eyebrow → title → sub stagger when .eux-problem-section__hdr
      gains .eux-is-in-view.
   2. Each .eux-problem-card is its own observer target (carries .eux-reveal
      via render.php), so cards reveal independently as they enter viewport.
      Within the grid, cards 1/2/3 get position-based delays so adjacent
      cards stagger gracefully when the user scrolls the entire grid into
      view at once.
   3. Inside each card, the mockup → eyebrow → title → list items stagger.
   ============================================================================ */

/* 1) Section header */
.eux-block--problem-trio .eux-problem-section__hdr .eux-eyebrow,
.eux-block--problem-trio .eux-problem-section__hdr .eux-problem-section__title,
.eux-block--problem-trio .eux-problem-section__hdr .eux-problem-section__sub {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--problem-trio .eux-problem-section__hdr.eux-is-in-view .eux-eyebrow {
	opacity: 1; transform: none; transition-delay: 0ms;
}
.eux-block--problem-trio .eux-problem-section__hdr.eux-is-in-view .eux-problem-section__title {
	opacity: 1; transform: none; transition-delay: 130ms;
}
.eux-block--problem-trio .eux-problem-section__hdr.eux-is-in-view .eux-problem-section__sub {
	opacity: 1; transform: none; transition-delay: 260ms;
}

/* 2) Per-card grid stagger — adjacent cards reveal in sequence when the
      whole grid enters viewport together. Each card carries .eux-reveal
      (added in render.php), so IntersectionObserver fires per-card; this
      transition-delay applies to the card's own reveal transition. */
.eux-block--problem-trio .eux-problem-grid > .eux-block--problem-card:nth-child(1) { transition-delay: 0ms; }
.eux-block--problem-trio .eux-problem-grid > .eux-block--problem-card:nth-child(2) { transition-delay: 130ms; }
.eux-block--problem-trio .eux-problem-grid > .eux-block--problem-card:nth-child(3) { transition-delay: 260ms; }

/* 3) Inside each card — internal stagger.
      Card itself uses the simple .eux-reveal (opacity + translateY).
      Body items (eyebrow, title, list, list items) reveal on a slight
      delay after the card finishes its lift, producing a "tier-down"
      effect rather than everything moving at once. */
.eux-block--problem-trio .eux-problem-card .eux-block--problem-mockup,
.eux-block--problem-trio .eux-problem-card .eux-problem-card__eyebrow,
.eux-block--problem-trio .eux-problem-card .eux-problem-card__title,
.eux-block--problem-trio .eux-problem-card .eux-problem-card__list li {
	opacity: 0;
	transform: translateY(16px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-block--problem-mockup        { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__eyebrow        { opacity: 1; transform: none; transition-delay: 200ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__title          { opacity: 1; transform: none; transition-delay: 320ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__list li:nth-child(1) { opacity: 1; transform: none; transition-delay: 440ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__list li:nth-child(2) { opacity: 1; transform: none; transition-delay: 500ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__list li:nth-child(3) { opacity: 1; transform: none; transition-delay: 560ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__list li:nth-child(4) { opacity: 1; transform: none; transition-delay: 620ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__list li:nth-child(5) { opacity: 1; transform: none; transition-delay: 680ms; }
.eux-block--problem-trio .eux-problem-card.eux-is-in-view .eux-problem-card__list li:nth-child(6) { opacity: 1; transform: none; transition-delay: 740ms; }

/* ============================================================================
   BENTO BOX — section header + per-card reveal + body internal stagger
   ----------------------------------------------------------------------------
   1. Section header staggers eyebrow → title → sub (same pattern as
      capabilities and problem-trio).
   2. Each .eux-bento-card carries .eux-reveal so it reveals individually
      when entering viewport.
   3. Cards within a row stagger by :nth-child position so adjacent cards
      animate in sequence rather than all at once.
   4. Inside each card, mockup → title → list-items stagger.
   ============================================================================ */

/* 1) Section header */
.eux-block--bento-box .eux-bento-section__hdr .eux-eyebrow,
.eux-block--bento-box .eux-bento-section__hdr .eux-bento-section__title,
.eux-block--bento-box .eux-bento-section__hdr .eux-bento-section__sub {
	opacity: 0;
	transform: translateY(20px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--bento-box .eux-bento-section__hdr.eux-is-in-view .eux-eyebrow              { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--bento-box .eux-bento-section__hdr.eux-is-in-view .eux-bento-section__title { opacity: 1; transform: none; transition-delay: 130ms; }
.eux-block--bento-box .eux-bento-section__hdr.eux-is-in-view .eux-bento-section__sub   { opacity: 1; transform: none; transition-delay: 260ms; }

/* 2) Per-card stagger within a row. Up to 4 columns per row, so we
      stagger up to 4 :nth-child positions. */
.eux-block--bento-box .eux-bento-row__inner > .eux-block--bento-card:nth-child(1) { transition-delay: 0ms; }
.eux-block--bento-box .eux-bento-row__inner > .eux-block--bento-card:nth-child(2) { transition-delay: 100ms; }
.eux-block--bento-box .eux-bento-row__inner > .eux-block--bento-card:nth-child(3) { transition-delay: 200ms; }
.eux-block--bento-box .eux-bento-row__inner > .eux-block--bento-card:nth-child(4) { transition-delay: 300ms; }

/* 3) Internal card stagger — mockup, title, list items */
.eux-block--bento-box .eux-bento-card .eux-bento-mockup,
.eux-block--bento-box .eux-bento-card .eux-bento-card__title,
.eux-block--bento-box .eux-bento-card .eux-bento-card__list li {
	opacity: 0;
	transform: translateY(14px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-mockup               { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__title          { opacity: 1; transform: none; transition-delay: 200ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__list li:nth-child(1) { opacity: 1; transform: none; transition-delay: 320ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__list li:nth-child(2) { opacity: 1; transform: none; transition-delay: 380ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__list li:nth-child(3) { opacity: 1; transform: none; transition-delay: 440ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__list li:nth-child(4) { opacity: 1; transform: none; transition-delay: 500ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__list li:nth-child(5) { opacity: 1; transform: none; transition-delay: 560ms; }
.eux-block--bento-box .eux-bento-card.eux-is-in-view .eux-bento-card__list li:nth-child(6) { opacity: 1; transform: none; transition-delay: 620ms; }

/* ============================================================================
   SIMPLE CTA — card scales in, then internal kicker → title → sub → button stagger
   ----------------------------------------------------------------------------
   The card (.eux-simple-cta__card) carries .eux-reveal so it fades up on
   viewport entry. Internal items stagger inside the card on a slightly
   delayed schedule so the card lifts first, content tier-downs after.
   ============================================================================ */
.eux-block--simple-cta .eux-simple-cta__card .eux-simple-cta__kicker,
.eux-block--simple-cta .eux-simple-cta__card .eux-simple-cta__title,
.eux-block--simple-cta .eux-simple-cta__card .eux-simple-cta__sub,
.eux-block--simple-cta .eux-simple-cta__card .wp-block-buttons {
	opacity: 0;
	transform: translateY(14px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--simple-cta .eux-simple-cta__card.eux-is-in-view .eux-simple-cta__kicker { opacity: 1; transform: none; transition-delay: 100ms; }
.eux-block--simple-cta .eux-simple-cta__card.eux-is-in-view .eux-simple-cta__title  { opacity: 1; transform: none; transition-delay: 200ms; }
.eux-block--simple-cta .eux-simple-cta__card.eux-is-in-view .eux-simple-cta__sub    { opacity: 1; transform: none; transition-delay: 320ms; }
.eux-block--simple-cta .eux-simple-cta__card.eux-is-in-view .wp-block-buttons       { opacity: 1; transform: none; transition-delay: 440ms; }

/* ============================================================================
   DAAS (THEMED) — left-column entrance stagger
   ----------------------------------------------------------------------------
   The left column carries .eux-reveal. Its children (eyebrow, title, copy
   paragraphs, meta line, button) stagger in on a tier-down schedule.
   The right column's mockup animations (Slack chat, live-dot, typing dots)
   are CSS-defined in the block's own style.css and run independently of
   viewport entry — they're an "always-animated" decoration.
   ============================================================================ */
.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__eyebrow,
.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__title,
.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__copy,
.eux-block--daas-themed .eux-daas-themed__left ul.wp-block-list,
.eux-block--daas-themed .eux-daas-themed__left ul,
.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__meta,
.eux-block--daas-themed .eux-daas-themed__left .wp-block-buttons {
	opacity: 0;
	transform: translateY(16px);
	transition:
		opacity   var(--eux-dur-reveal) var(--eux-ease-expo),
		transform var(--eux-dur-reveal) var(--eux-ease-expo);
}
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .eux-daas-themed__eyebrow { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .eux-daas-themed__title   { opacity: 1; transform: none; transition-delay: 130ms; }
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .eux-daas-themed__copy:nth-of-type(1) { opacity: 1; transform: none; transition-delay: 260ms; }
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .eux-daas-themed__copy:nth-of-type(2) { opacity: 1; transform: none; transition-delay: 360ms; }
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .eux-daas-themed__copy:nth-of-type(3) { opacity: 1; transform: none; transition-delay: 460ms; }
/* v0.36.54 — list slots in between the copy paragraphs and the meta line.
   460ms (copy:nth-of-type(2) is the 2nd default copy paragraph) + ~100ms
   step = ~560ms. Meta and buttons pushed back to keep the staircase. */
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view ul.wp-block-list,
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view ul             { opacity: 1; transform: none; transition-delay: 560ms; }
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .eux-daas-themed__meta    { opacity: 1; transform: none; transition-delay: 660ms; }
.eux-block--daas-themed .eux-daas-themed__left.eux-is-in-view .wp-block-buttons         { opacity: 1; transform: none; transition-delay: 780ms; }

/* ============================================================================
   PROCESS — UX-motion choreography
   ----------------------------------------------------------------------------
   Per the ux-motion skill: 30-50ms stagger between siblings, total budget
   under 700ms, ease-out for entering elements. The EUX system's default
   900ms reveal is too long here — each element would still be settling
   when the next starts. We use a tighter 360ms duration scoped to this
   block only.

   Two independent timelines (each driven by its own IntersectionObserver):
     - Section header: eyebrow → title → sub (0/60/120ms, completes 480ms)
     - Card grid: 5 phase cards stagger across nth-child (0/50/100/150/200ms)

   Header is separate from cards because they're separate observer targets —
   the header reveals when ITS element enters viewport; each card reveals
   when its own element does. The :nth-child delays still coordinate the
   visual stagger when multiple cards happen to enter the viewport together
   (which they do on first load — all 5 fit on screen in the 5-col grid).

   The 360ms duration + ease-out for the cards lives in blocks/process/style.css
   alongside the rest of the card's transition list (which also covers hover
   colour/shadow). That's the single source of truth for card timing. Here
   we only set transition-delay per :nth-child position.
   ============================================================================ */

/* Section header — three items, smooth 60ms stagger.
   We override the default 900ms reveal duration locally for this header
   so it matches the cards' 360ms timing for visual cohesion. */
.eux-block--process .eux-process-section__hdr .eux-eyebrow,
.eux-block--process .eux-process-section__hdr .eux-process-section__title,
.eux-block--process .eux-process-section__hdr .eux-process-section__sub {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}
.eux-block--process .eux-process-section__hdr.eux-is-in-view .eux-eyebrow                { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--process .eux-process-section__hdr.eux-is-in-view .eux-process-section__title { opacity: 1; transform: none; transition-delay: 60ms; }
.eux-block--process .eux-process-section__hdr.eux-is-in-view .eux-process-section__sub   { opacity: 1; transform: none; transition-delay: 120ms; }

/* Card stagger — 50ms between adjacent cards.
   The card's transition (timing + curve) lives in blocks/process/style.css.
   Up to 7 cards supported; beyond that they all share the 300ms delay. */
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(1) { transition-delay: 0ms; }
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(2) { transition-delay: 50ms; }
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(3) { transition-delay: 100ms; }
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(4) { transition-delay: 150ms; }
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(5) { transition-delay: 200ms; }
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(6) { transition-delay: 250ms; }
.eux-block--process .eux-process-section__grid > .eux-block--process-step:nth-child(7) { transition-delay: 300ms; }

/* ============================================================================
   PRO PARTNER — UX-motion choreography
   ----------------------------------------------------------------------------
   Per the ux-motion skill: stagger 30-50ms between siblings, total
   choreography budget under 500ms, ease-out for entering elements.
   The EUX system's default 900ms reveal is too long here — each item
   would still be settling when the next started. We use a tighter
   ~360ms duration scoped to this block only.

   Order (one after the other, smooth handoff with ~80% overlap):
     eyebrow → title → sub → stats   (left column, 0/60/120/180ms)
     row 1 → row 2                    (right column, 220/280ms)

   Total: 280ms + 360ms duration = ~640ms — within the 700ms ceiling.
   ============================================================================ */
.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__eyebrow,
.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__title,
.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__sub,
.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__stats {
	opacity: 0;
	transform: translateY(12px);
	/* Tighter than the EUX default — feels like a single smooth sweep
	   rather than a slow theatrical reveal. */
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}
.eux-block--pro-partner .eux-pro-partner__copy.eux-is-in-view .eux-pro-partner__eyebrow { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--pro-partner .eux-pro-partner__copy.eux-is-in-view .eux-pro-partner__title   { opacity: 1; transform: none; transition-delay: 60ms; }
.eux-block--pro-partner .eux-pro-partner__copy.eux-is-in-view .eux-pro-partner__sub     { opacity: 1; transform: none; transition-delay: 120ms; }
.eux-block--pro-partner .eux-pro-partner__copy.eux-is-in-view .eux-pro-partner__stats   { opacity: 1; transform: none; transition-delay: 180ms; }

/* Override the row's own .eux-reveal default (which uses the EUX 900ms
   token) so rows match the rest of the section. */
.eux-block--pro-partner .eux-pro-row {
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		box-shadow var(--eux-dur-base, 220ms) var(--eux-ease-out, ease);
}
.eux-block--pro-partner .eux-pro-partner__rows > .eux-block--pro-row:nth-child(1) { transition-delay: 220ms; }
.eux-block--pro-partner .eux-pro-partner__rows > .eux-block--pro-row:nth-child(2) { transition-delay: 280ms; }
.eux-block--pro-partner .eux-pro-partner__rows > .eux-block--pro-row:nth-child(3) { transition-delay: 340ms; }
.eux-block--pro-partner .eux-pro-partner__rows > .eux-block--pro-row:nth-child(4) { transition-delay: 400ms; }

/* ============================================================================
   BIG CTA — UX-motion entrance choreography
   ----------------------------------------------------------------------------
   Card itself uses .eux-reveal (set in render.php). We override the EUX
   default 900ms timing locally to match the ux-motion 360ms / ≤700ms
   ceiling, and stagger the body content (title → sub → buttons) inside.

   The card fade is paired with the body items rather than chained after
   them because the body sits centrally inside the card — they should
   appear as a single coordinated entrance, not "card first, then content."

   Decorative scenery (icons, frames, marquee) is NOT in the entrance
   stagger. It just shares the card's parent reveal — once the card is
   visible, the marquee auto-starts and icons sit in their resting
   positions until the visitor hovers.

   Order (each 360ms duration, ease-out):
     card     0ms   → done at 360ms
     title    80ms  → done at 440ms
     sub      140ms → done at 500ms
     buttons  200ms → done at 560ms

   Total: 560ms, well under the 700ms ceiling. Within the 300-500ms
   sweet spot for orchestrated reveals (top end).
   ============================================================================ */

/* Override the .eux-reveal default 900ms expo-out for the big-cta card.
   Same ease-out curve used elsewhere in the ux-motion-aligned blocks. */
.eux-block--big-cta .eux-big-cta__card.eux-reveal {
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* Body items — title, sub, buttons each fade up with a short stagger.
   They start hidden, then become visible when the card gets .eux-is-in-view.
   Selecting on the CARD's .eux-is-in-view (not each item's) makes them
   reveal as a coordinated group on a single trigger. */
.eux-block--big-cta .eux-big-cta__card .eux-big-cta__title,
.eux-block--big-cta .eux-big-cta__card .eux-big-cta__sub,
.eux-block--big-cta .eux-big-cta__card .wp-block-buttons {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}
.eux-block--big-cta .eux-big-cta__card.eux-is-in-view .eux-big-cta__title  { opacity: 1; transform: none; transition-delay: 80ms; }
.eux-block--big-cta .eux-big-cta__card.eux-is-in-view .eux-big-cta__sub    { opacity: 1; transform: none; transition-delay: 140ms; }
.eux-block--big-cta .eux-big-cta__card.eux-is-in-view .wp-block-buttons    { opacity: 1; transform: none; transition-delay: 200ms; }

/* ============================================================================
   STATS — UX-motion entrance choreography
   ----------------------------------------------------------------------------
   Per the ux-motion skill: 30-50ms stagger between siblings, 360ms ease-out
   duration, total budget under 700ms.

   Two independent timelines (each driven by its own IntersectionObserver):
     - Header row: eyebrow → title → sub → meta (0/60/120/180ms,
       last item completes at 540ms)
     - Card grid: featured card prominent first, then regulars stagger
       50ms apart by :nth-child (0/50/100/150/200/250ms)

   Each card carries .eux-reveal so it has its own observer trigger;
   the :nth-child delays only matter when multiple cards fire together
   on first load (which they do — all 5 visible at once on desktop).
   ============================================================================ */

/* Header row — four siblings: eyebrow, title, sub, meta */
.eux-block--stats .eux-stats__hd .eux-stats__eyebrow,
.eux-block--stats .eux-stats__hd .eux-stats__title,
.eux-block--stats .eux-stats__hd .eux-stats__sub,
.eux-block--stats .eux-stats__hd .eux-stats__meta {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}
.eux-block--stats .eux-stats__hd.eux-is-in-view .eux-stats__eyebrow { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--stats .eux-stats__hd.eux-is-in-view .eux-stats__title   { opacity: 1; transform: none; transition-delay: 60ms; }
.eux-block--stats .eux-stats__hd.eux-is-in-view .eux-stats__sub     { opacity: 1; transform: none; transition-delay: 120ms; }
.eux-block--stats .eux-stats__hd.eux-is-in-view .eux-stats__meta    { opacity: 1; transform: none; transition-delay: 180ms; }

/* Card grid — override .eux-reveal default 900ms timing for this block */
.eux-block--stats .eux-stat {
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* Per-card stagger — supports up to 8 cards. Featured card usually
   sits at position 1 so it's the leading element. */
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(1) { transition-delay: 0ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(2) { transition-delay: 50ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(3) { transition-delay: 100ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(4) { transition-delay: 150ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(5) { transition-delay: 200ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(6) { transition-delay: 250ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(7) { transition-delay: 300ms; }
.eux-block--stats .eux-stats__grid > .eux-block--stat:nth-child(8) { transition-delay: 350ms; }

/* ============================================================================
   GOOD FIT (THEMED) — UX-motion entrance choreography
   ----------------------------------------------------------------------------
   Per the ux-motion skill: 30-50ms stagger between siblings, 360ms ease-out
   duration. Left column's eyebrow → title → sub → meta → traits animates
   as one coordinated sweep. The 4 trait cards inside the traits grid then
   stagger 50ms apart.

   The right-column SVG matrix has its OWN designer-created animation
   sequence (~2.3s build, then infinite pulse) defined in the block's
   style.css. That sequence kicks in independently as a "Lottie-style"
   illustration playing through.

   Timeline (left column):
     eyebrow  0ms
     title    60ms
     sub      120ms
     meta     180ms
     traits   240ms (the wrapper)
       └─ trait 1  +0ms  (240ms total)
       └─ trait 2  +50ms (290ms)
       └─ trait 3  +100ms (340ms)
       └─ trait 4  +150ms (390ms)

   Last item starts at 390ms + 360ms = 750ms — slightly above the 700ms
   ceiling. We accept this because traits revealing AFTER the meta line
   reads as the correct narrative order. The skill's ceiling is "If your
   orchestrated animation takes longer than 700ms, users are waiting";
   here the eye is occupied watching the matrix illustration too, so
   waiting isn't perceived.
   ============================================================================ */

/* Left-column copy stagger */
.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__eyebrow,
.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__title,
.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__sub,
.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__meta,
.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__traits {
	opacity: 0;
	transform: translateY(12px);
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}
.eux-block--good-fit-themed .eux-good-fit__left.eux-is-in-view .eux-good-fit__eyebrow { opacity: 1; transform: none; transition-delay: 0ms; }
.eux-block--good-fit-themed .eux-good-fit__left.eux-is-in-view .eux-good-fit__title   { opacity: 1; transform: none; transition-delay: 60ms; }
.eux-block--good-fit-themed .eux-good-fit__left.eux-is-in-view .eux-good-fit__sub     { opacity: 1; transform: none; transition-delay: 120ms; }
.eux-block--good-fit-themed .eux-good-fit__left.eux-is-in-view .eux-good-fit__meta    { opacity: 1; transform: none; transition-delay: 180ms; }
.eux-block--good-fit-themed .eux-good-fit__left.eux-is-in-view .eux-good-fit__traits  { opacity: 1; transform: none; transition-delay: 240ms; }

/* Override .eux-reveal default for trait cards — use ux-motion 360ms timing */
.eux-block--good-fit-themed .eux-good-fit__trait {
	transition:
		opacity   360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
		transform 360ms var(--eux-ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* Per-trait stagger inside the 2x2 grid */
.eux-block--good-fit-themed .eux-good-fit__traits > .eux-block--good-fit-trait:nth-child(1) { transition-delay: 240ms; }
.eux-block--good-fit-themed .eux-good-fit__traits > .eux-block--good-fit-trait:nth-child(2) { transition-delay: 290ms; }
.eux-block--good-fit-themed .eux-good-fit__traits > .eux-block--good-fit-trait:nth-child(3) { transition-delay: 340ms; }
.eux-block--good-fit-themed .eux-good-fit__traits > .eux-block--good-fit-trait:nth-child(4) { transition-delay: 390ms; }

/* ============================================================================
   Reduced motion — replace entrances with instant visibility
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
	.eux-reveal,
	.eux-reveal--scale,
	.eux-block .eux-hero__mock-frame.eux-reveal,
	.eux-block .eux-cap-section__hdr .eux-eyebrow,
	.eux-block .eux-cap-section__hdr .eux-cap-section__title,
	.eux-block .eux-cap-section__hdr .eux-cap-section__sub,
	.eux-block--problem-trio .eux-problem-section__hdr .eux-eyebrow,
	.eux-block--problem-trio .eux-problem-section__hdr .eux-problem-section__title,
	.eux-block--problem-trio .eux-problem-section__hdr .eux-problem-section__sub,
	.eux-block--problem-trio .eux-problem-card,
	.eux-block--problem-trio .eux-problem-card .eux-block--problem-mockup,
	.eux-block--problem-trio .eux-problem-card .eux-problem-card__eyebrow,
	.eux-block--problem-trio .eux-problem-card .eux-problem-card__title,
	.eux-block--problem-trio .eux-problem-card .eux-problem-card__list li,
	.eux-block--bento-box .eux-bento-section__hdr .eux-eyebrow,
	.eux-block--bento-box .eux-bento-section__hdr .eux-bento-section__title,
	.eux-block--bento-box .eux-bento-section__hdr .eux-bento-section__sub,
	.eux-block--bento-box .eux-bento-card,
	.eux-block--bento-box .eux-bento-card .eux-bento-mockup,
	.eux-block--bento-box .eux-bento-card .eux-bento-card__title,
	.eux-block--bento-box .eux-bento-card .eux-bento-card__list li,
	.eux-block--simple-cta .eux-simple-cta__card,
	.eux-block--simple-cta .eux-simple-cta__card .eux-simple-cta__kicker,
	.eux-block--simple-cta .eux-simple-cta__card .eux-simple-cta__title,
	.eux-block--simple-cta .eux-simple-cta__card .eux-simple-cta__sub,
	.eux-block--simple-cta .eux-simple-cta__card .wp-block-buttons,
	.eux-block--daas-themed .eux-daas-themed__left,
	.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__eyebrow,
	.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__title,
	.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__copy,
	.eux-block--daas-themed .eux-daas-themed__left .eux-daas-themed__meta,
	.eux-block--daas-themed .eux-daas-themed__left .wp-block-buttons,
	.eux-block--process .eux-process-section__hdr .eux-eyebrow,
	.eux-block--process .eux-process-section__hdr .eux-process-section__title,
	.eux-block--process .eux-process-section__hdr .eux-process-section__sub,
	.eux-block--process .eux-process-step,
	.eux-block--pro-partner .eux-pro-partner__copy,
	.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__eyebrow,
	.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__title,
	.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__sub,
	.eux-block--pro-partner .eux-pro-partner__copy .eux-pro-partner__stats,
	.eux-block--pro-partner .eux-pro-row,
	.eux-block--pro-partner .eux-pro-stat,
	.eux-block--big-cta .eux-big-cta__card,
	.eux-block--big-cta .eux-big-cta__card .eux-big-cta__title,
	.eux-block--big-cta .eux-big-cta__card .eux-big-cta__sub,
	.eux-block--big-cta .eux-big-cta__card .wp-block-buttons,
	.eux-block--case-studies .eux-cs__hdr .eux-eyebrow,
	.eux-block--case-studies .eux-cs__hdr .eux-cs__title,
	.eux-block--case-studies .eux-cs__hdr .eux-cs__sub,
	.eux-block--case-study-card,
	.eux-block--case-study-card .eux-cs-card__img,
	.eux-block--case-study-card .eux-cs-card__title,
	.eux-block--case-study-card .eux-cs-card__desc,
	.eux-block--case-study-card .eux-cs-card__tags,
	.eux-block--case-study-card .eux-cs-card__tag,
	.eux-block--case-study-card .eux-cs-card__foot,
	.eux-block--stats .eux-stats__hd,
	.eux-block--stats .eux-stats__hd .eux-stats__eyebrow,
	.eux-block--stats .eux-stats__hd .eux-stats__title,
	.eux-block--stats .eux-stats__hd .eux-stats__sub,
	.eux-block--stats .eux-stats__hd .eux-stats__meta,
	.eux-block--stats .eux-stat,
	.eux-block--good-fit-themed .eux-good-fit__left,
	.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__eyebrow,
	.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__title,
	.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__sub,
	.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__meta,
	.eux-block--good-fit-themed .eux-good-fit__left .eux-good-fit__traits,
	.eux-block--good-fit-themed .eux-good-fit__trait,
	.eux-block--service-hero .eux-hero__title,
	.eux-block--service-hero .eux-hero__sub,
	.eux-block--service-hero .eux-hero__ctas .wp-block-button,
	.eux-block--cap-card,
	.eux-block--cap-card .eux-cap__num,
	.eux-block--cap-card .eux-cap__title,
	.eux-block--cap-card .eux-block--cap-mockup,
	.eux-block--cap-card .eux-cap__copy,
	.eux-block--cap-card .eux-cap__list li,
	.eux-block--example-card,
	.eux-block--example-card .eux-example__ic,
	.eux-block--example-card .eux-example__name,
	.eux-block--example-card .eux-example__line,
	.eux-block--example-card .eux-example__mock,
	.eux-block--daas .eux-daas__left > *,
	.eux-block--daas .eux-daas__right > *,
	.eux-block--daas .eux-daas__list li,
	.eux-block--daas-slack .eux-slack__eyebrow,
	.eux-block--daas-slack .eux-slack__title,
	.eux-block--daas-slack .eux-slack__copy,
	.eux-block--daas-slack .eux-slack__meta,
	.eux-block--daas-slack .wp-block-buttons.eux-slack__ctas,
	.eux-block--daas-slack .eux-slack__stats,
	.eux-block--daas-slack .eux-slack__panel-frame,
	.eux-block--good-fit .eux-fit__eyebrow,
	.eux-block--good-fit .eux-fit__title,
	.eux-block--good-fit .eux-fit__copy,
	.eux-block--good-fit .eux-fit__meta,
	.eux-block--good-fit .eux-fit__trait,
	.eux-block--good-fit .eux-fit__matrix,
	.eux-block--integration-cta .eux-icta__title,
	.eux-block--integration-cta .eux-icta__sub,
	.eux-block--integration-cta .wp-block-buttons.eux-icta__ctas,
	.eux-block--integration-cta .eux-icta__tile,
	.eux-block--split-feature .eux-split__eyebrow,
	.eux-block--split-feature .eux-split__title,
	.eux-block--split-feature .eux-split__lede,
	.eux-block--split-feature .eux-split__tiles > li,
	.eux-block--split-feature .wp-block-buttons.eux-split__ctas,
	.eux-block--split-feature .eux-split__media,
	.eux-block--split-feature .wp-block-column.eux-split__col-media .wp-block-image {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
		transition-delay: 0ms !important;
		will-change: auto;
	}
}
