/* =============================================================================
   BD Media — motion layer (2026-11-10)

   The estate had ZERO @keyframes and zero scroll-triggered anything: measured
   grep across assets/*.css before this file. A page where nothing ever moves
   reads as a document, not as something that is currently publishing. That is
   the actual reason the front page felt flat — not the type sizes.

   RULES THIS FILE OBEYS
   ---------------------
   1. Nothing here is needed to read the page. Every animation ends at the state
      the element already has in CSS, so with JS off or motion off, the layout is
      identical and complete. `.bdm-reveal` is only ever ADDED by JS, to elements
      that were below the fold at load — so there is no flash of invisible content
      and no "blank page if the script fails".
   2. Durations are 200-700ms for feedback, 16s for ambient. No infinite loops
      except the one small live dot, and that one is paused for reduced-motion.
   3. `prefers-reduced-motion: reduce` switches off everything in one block at the
      bottom. Not "shortened" — off.
   4. Animating transform and opacity only. No layout properties, no filters on
      large images (the estate has had paint-cost problems before).
   ============================================================================= */

/* ------------------------------------------------------------ ambient: the dot */
@keyframes bdm-pulse {
	0%   { transform: scale(.6); opacity: .45; }
	70%  { transform: scale(2.2); opacity: 0; }
	100% { transform: scale(2.2); opacity: 0; }
}

/* -------------------------------------------------------- the lead story's art
   A 16s push-in on the one image the page wants you to look at. It runs once and
   holds at 1.045 — the crop stays inside the frame at every step. */
@keyframes bdm-push {
	from { transform: scale(1); }
	to   { transform: scale(1.045); }
}
.bdm-fl__img {
	animation: bdm-push 16s cubic-bezier(.2, .6, .3, 1) both;
	will-change: transform;
}

/* --------------------------------------------------------- the hero's entrance
   The h1, deck and vitals arrive as one gesture, 90ms apart. Deliberately small
   movement (10px) — a big slide would look like a template, not a newsroom. */
@keyframes bdm-rise {
	from { opacity: 0; transform: translateY(10px); }
	to   { opacity: 1; transform: none; }
}
.bd-hero__kicker,
.bd-hero__title,
.bd-hero__deck,
.bdm-fv {
	animation: bdm-rise .62s cubic-bezier(.2, .7, .3, 1) both;
}
.bd-hero__title { animation-delay: .06s; }
.bd-hero__deck  { animation-delay: .12s; }
.bdm-fv         { animation-delay: .18s; }

/* ------------------------------------------------------------- scroll reveal
   Applied by bdm-motion.js ONLY to elements that start below the viewport, so
   nothing above the fold is ever hidden and then revealed. */
.bdm-reveal {
	opacity: 0;
	transform: translateY(14px);
	transition: opacity .5s cubic-bezier(.2, .7, .3, 1), transform .5s cubic-bezier(.2, .7, .3, 1);
}
.bdm-reveal.is-in {
	opacity: 1;
	transform: none;
}

/* Stagger inside a row: the nth child waits a little longer. Capped at 6 so a
   12-card grid does not end up with a 1.2s trickle. */
.bdm-reveal[data-bd-stagger='1'] { transition-delay: .06s; }
.bdm-reveal[data-bd-stagger='2'] { transition-delay: .12s; }
.bdm-reveal[data-bd-stagger='3'] { transition-delay: .18s; }
.bdm-reveal[data-bd-stagger='4'] { transition-delay: .24s; }
.bdm-reveal[data-bd-stagger='5'] { transition-delay: .3s; }
.bdm-reveal[data-bd-stagger='6'] { transition-delay: .36s; }

/* --------------------------------------------------------------- the count-up
   `.is-counting` is set by JS for the duration of the number's animation; the
   tabular figures stop the block re-flowing while the digits change. */
.is-counting { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------- hover that lifts
   Cards already scaled their image 1.03. A 2px lift plus the existing shadow token
   is the difference between "hover works" and "hover is invisible". */
.bd-card,
.bdm-h-card {
	transition: transform .22s cubic-bezier(.2, .7, .3, 1), box-shadow .22s cubic-bezier(.2, .7, .3, 1);
}
.bd-card:hover,
.bdm-h-card:hover {
	transform: translateY(-2px);
	box-shadow: var(--bd-shadow-lift);
}

/* ------------------------------------------------------------- reduced motion
   One block, everything off. The dot stops, the push-in does not run (the image
   rests at scale 1), and any element JS already marked .bdm-reveal becomes
   visible immediately — because the transition is what is disabled, not the
   .is-in state. */
@media (prefers-reduced-motion: reduce) {
	.bdm-fl__img,
	.bd-hero__kicker,
	.bd-hero__title,
	.bd-hero__deck,
	.bdm-fv,
	.bdm-fv__dot::after {
		animation: none !important;
	}
	.bdm-reveal {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
	.bd-card,
	.bdm-h-card,
	.bdm-fe__item,
	.bdm-fl__cta {
		transition: none !important;
	}
	.bd-card:hover,
	.bdm-h-card:hover,
	.bdm-fe__item:hover,
	.bdm-fl__cta:hover {
		transform: none !important;
	}
	.bdm-fs__spark path.line {
		stroke-dashoffset: 0 !important;
		transition: none !important;
	}
}
