/* ============================================================
   bl-anim.css — shared CSS for every Behavior Lab homepage
   animation module. Loaded once by inc/animations.php alongside
   bl-anim-base.js, only on pages that use at least one [bl_*]
   animation hook.

   CONVENTION (matches bl-anim-base.js): every animated element's
   DEFAULT state (no modifier class) is its fully resolved, correct
   content — exactly what a no-JS / old-browser / reduced-motion
   visitor sees. A module's JS adds a "bl-anim--*" modifier class
   ONLY once it is actually about to animate; every rule below that
   hides or offsets content is scoped under one of those modifier
   classes, never under the bare selector. Reveal state is "is-in".
   ============================================================ */

/* Belt-and-suspenders reduced-motion kill switch, in case a
   "bl-anim--*" class ever ends up in the DOM regardless (e.g. the OS
   setting changes mid-session). Every animated root below carries
   [data-bl-anim]. */
@media (prefers-reduced-motion: reduce) {
	[data-bl-anim],
	[data-bl-anim] * {
		transition: none !important;
		animation: none !important;
	}
}

/* ---------- 1. Hero specimen slot machine ---------- */
/* bl-hero-slot.js turns each [bl_typecard] tile into a masked vertical
   reel (.bl-reel of stacked .bl-frame rows) that spins to a landed frame.
   .bl-tile keeps its existing overflow:hidden (style.css) as the mask; the
   JS locks its height to one frame before building the reel so the mask
   actually clips instead of the box growing to fit every row. */
.bl-tile { position: relative; }
.bl-reel { display: flex; flex-direction: column; will-change: transform; }
.bl-reel.is-rolling { filter: blur(1.6px); }
.bl-reel.is-settling { filter: blur(0); transition: filter .18s ease-out; }
.bl-frame .bl-top  { color:#fff; font-family:var(--bl-font-mono); font-weight:700; font-size:12.5px; padding:7px 4px; letter-spacing:.05em; background:var(--bl-accent); }
.bl-frame .bl-face { height:60px; display:flex; align-items:center; justify-content:center; color:var(--bl-ink); }
.bl-frame .bl-nm   { font-size:11px; color:var(--bl-muted); padding:6px 2px; height:18px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.bl-typecard .bl-fam-dot { display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--bl-accent); margin-right:6px; vertical-align:middle; }
.bl-typecard .bl-type b.is-scrambling { opacity:.55; }
@keyframes bl-ring-flash { 0%{box-shadow:0 0 0 0 var(--bl-flash-color,var(--bl-accent));} 40%{box-shadow:0 0 0 3px var(--bl-flash-color,var(--bl-accent));opacity:.55;} 100%{box-shadow:0 0 0 0 transparent;} }
.bl-typecard.bl-flash { animation: bl-ring-flash .5s ease-out; }
.bl-sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }

/* ---------- 2. Interactive 16-type explorer ---------- */
.bl-typefams.bl-anim--stagger .bl-trow {
	opacity: 0;
	transform: translateY(14px);
}
.bl-typefams.bl-anim--stagger .bl-trow.is-in {
	opacity: 1;
	transform: none;
	transition: opacity .32s cubic-bezier(.16,1,.3,1), transform .32s cubic-bezier(.16,1,.3,1);
}
.bl-typefams.is-filtered .bl-fam { transition: opacity .25s ease; }
.bl-typefams.is-filtered .bl-fam:not(.is-active) { opacity: .32; }
.bl-famhead { cursor: pointer; }
.bl-famhead:focus-visible { outline: 2px solid var(--bl-accent); outline-offset: 3px; border-radius: 4px; }
.bl-trow {
	border-left: 3px solid transparent;
	padding-left: 9px;
	margin-left: -12px;
	transition: border-color .18s ease, background .18s ease;
}
.bl-trow:hover { border-left-color: var(--fc); background: rgba(20,24,31,.025); }

/* ---------- 3. Spectrum fill ---------- */
.bl-track { overflow: hidden; }
.bl-fill { position: absolute; inset: 0 auto 0 0; height: 100%; border-radius: 99px; opacity: .32; }
/* No CSS-class-based hidden state here on purpose: bl-spectrum-fill.js owns
   the whole 0 -> value transition directly via inline styles (explicit
   reset, forced reflow, then animate), so there is nothing here that could
   fight the server-rendered inline width/left values. */

/* ---------- 4. Temperament quadrant reveal ---------- */
/* A crisp staggered scale-in on scroll (bl-quadrant-anim.js), not the
   earlier near-imperceptible per-cell canvas dot-drift — more visible, no
   canvas/rAF loop per cell. */
.bl-quadrant.bl-anim--stagger .bl-q {
	opacity: 0;
	transform: scale(.9);
}
.bl-quadrant.bl-anim--stagger .bl-q.is-in {
	opacity: 1;
	transform: none;
	transition: opacity .38s cubic-bezier(.16,1,.3,1), transform .38s cubic-bezier(.16,1,.3,1);
}

/* ---------- 5. Science cards + Venn ---------- */
.bl-cards.bl-anim--stagger .bl-card {
	opacity: 0;
	transform: translateY(20px) scale(.95);
}
.bl-cards.bl-anim--stagger .bl-card.is-in {
	opacity: 1;
	transform: none;
	transition: opacity .38s cubic-bezier(.16,1,.3,1), transform .38s cubic-bezier(.16,1,.3,1);
}
/* Rescaled ~2.6x (r 54 -> 140, viewBox 220x160 -> 572x400) so the Venn
   reads as a real diagram, not a decoration. Lives inside the dark
   ".bl-band" now (right column of .bl-band-grid, see style.css), so every
   stroke/fill/label below is chosen for legibility on the dark ink
   background, not the light card background it started on: Type = light
   accent blue, Temperament = orange (already reads fine on dark), CBT =
   a light neutral instead of the old dark --bl-ink (which went invisible
   on the band). The "System" badge is a light pill with dark text so it
   stays a distinct, legible shape against the band. */
.bl-venn { display: flex; justify-content: center; max-width: 480px; margin: 28px auto 10px; }
.bl-venn svg { display: block; width: 100%; height: auto; overflow: visible; }
.bl-venn-c { fill: none; stroke-width: 3; opacity: .6; transition: stroke-width .18s ease, opacity .18s ease, fill .18s ease; }
.bl-venn .bl-venn-c1 { stroke: #7db8ec; }
.bl-venn .bl-venn-c2 { stroke: var(--bl-orange); }
.bl-venn .bl-venn-c3 { stroke: rgba(255,255,255,.55); opacity: .7; }
.bl-venn-label { font-family: var(--bl-font-mono); font-size: 17px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; opacity: .9; }
.bl-venn-label1 { fill: #7db8ec; }
.bl-venn-label2 { fill: var(--bl-orange); }
.bl-venn-label3 { fill: rgba(255,255,255,.8); }
.bl-venn-badge rect { fill: #fff; }
.bl-venn-badge text { fill: var(--bl-ink); font-family: var(--bl-font-mono); font-weight: 700; font-size: 15px; letter-spacing: .08em; text-transform: uppercase; }
.bl-venn-badge { opacity: 1; } /* default (no-JS / reduced-motion) end-state: badge already showing */
/* Hover/focus-link state (bl-venn-link.js adds/removes "is-hl" on the
   matching circle when its paired .bl-band-fw framework block is
   hovered or keyboard-focused). Progressive enhancement only: with no
   JS the circles simply never gain this class. Under
   prefers-reduced-motion the transitions above are killed by the
   belt-and-suspenders rule at the top of this file, so the highlight
   still applies, just as an instant state change instead of an eased one. */
.bl-venn-c.is-hl { stroke-width: 5; opacity: 1; }
.bl-venn-c1.is-hl { fill: rgba(125,184,236,.14); }
.bl-venn-c2.is-hl { fill: rgba(233,106,12,.14); }
.bl-venn-c3.is-hl { fill: rgba(255,255,255,.12); }
.bl-venn.bl-anim--anim .bl-venn-c { transition: transform .8s cubic-bezier(.16,1,.3,1), stroke-width .18s ease, opacity .18s ease, fill .18s ease; }
.bl-venn.bl-anim--anim .bl-venn-c1 { transform: translate(-78px,-36px); }
.bl-venn.bl-anim--anim .bl-venn-c2 { transform: translate(78px,-36px); }
.bl-venn.bl-anim--anim .bl-venn-c3 { transform: translate(0,57px); }
.bl-venn.bl-anim--anim.is-in .bl-venn-c { transform: none; }
/* Badge fades in ~0.5s after the circles finish converging (.8s converge +
   .5s pause = 1.3s delay), only once JS is actually about to animate —
   the "bl-anim--anim" gate means a no-JS/reduced-motion visitor never sees
   it hidden in the first place (see rule above). */
.bl-venn.bl-anim--anim .bl-venn-badge { opacity: 0; transition: opacity .5s ease 1.3s; }
.bl-venn.bl-anim--anim.is-in .bl-venn-badge { opacity: 1; }

/* ---------- 6. How-it-works connector ---------- */
.bl-steps-wrap { position: relative; }
.bl-steps-line { position: absolute; top: 9px; left: 0; right: 0; height: 2px; background: var(--bl-line); z-index: 0; }
.bl-steps-line i { display: block; height: 100%; width: 100%; background: var(--bl-accent); transform-origin: left; transform: scaleX(1); }
.bl-steps-wrap.bl-anim--scrub .bl-steps-line i { transform: scaleX(0); transition: transform .12s linear; }
.bl-steps { position: relative; z-index: 1; }

/* ---------- 7. Batch reveal (specs, trust logos, testimonials, CTA) ---------- */
[data-bl-anim="fade"].bl-anim--anim {
	opacity: 0;
	transform: translateY(24px);
	transition: opacity .46s cubic-bezier(.16,1,.3,1), transform .46s cubic-bezier(.16,1,.3,1);
}
[data-bl-anim="fade"].bl-anim--anim.is-in { opacity: 1; transform: none; }

.bl-quotes-more.bl-anim--stagger .bl-quote { opacity: 0; transform: translateY(16px); }
.bl-quotes-more.bl-anim--stagger .bl-quote.is-in {
	opacity: 1;
	transform: none;
	transition: opacity .34s cubic-bezier(.16,1,.3,1), transform .34s cubic-bezier(.16,1,.3,1);
}

/* FAQ smooth open + chevron rotate (JS-enhanced only; native <details> is
   the correct, fully-functional no-JS fallback). */
.bl-faq details { overflow: hidden; }
.bl-faq summary { position: relative; padding-right: 26px; }
.bl-faq summary::after {
	content: "+";
	position: absolute;
	right: 2px;
	top: 0;
	font-weight: 400;
	color: var(--bl-accent);
	transition: transform .25s ease;
}
.bl-faq.bl-anim--js details[open] summary::after { transform: rotate(45deg); }
.bl-faq.bl-anim--js details > p { overflow: hidden; transition: max-height .3s ease; }

/* ---------- 8. Count-up (Why it matters band) ---------- */
.bl-metrics--countup .bl-metric b { font-variant-numeric: tabular-nums; }
