/* ============================================================
   ck-anim-variants — three name variants collapse into one
   (Insurance post — the strongest candidate in the batch).
   Fully scoped under .szav-root. Obsidian & Ember tokens.
   Signal green (--szav-signal) is used ONLY on the resolved node.

   By DEFAULT (no JS, or prefers-reduced-motion): the merged node is
   shown prominently, static green ring, with the three source
   variants listed faintly below it — the traveling chips used for
   the animated "contract + crossfade" effect are display:none until
   JS explicitly enables them, so nothing is ever missing from the
   static read. Shared reduced-motion kill-switch lives in
   anim-base.css, scoped to [data-sz-anim].
   No <a> elements are rendered by this module, so no theme link
   bleed-guard is required.
   LIGHT CARD (2026-07-22): this card sits on a warm cream ground, not the
   obsidian it launched with. Notes that matter if you touch the colours:
     - The ground is cream (#F4F0E8), NOT #FFFFFF — a white card on a white
       article page stops reading as a figure at all.
     - Prominence inverts on a light ground: DARKNESS now carries emphasis,
       so former-#fff labels are ink (#17140F) and former-#B0A49E secondary
       text is #4A443B. --ink-dim was already legible on light and is unchanged.
     - Signal green is split in two: --*-signal (#157A44) for TEXT, and
       --*-signal-ring (#1C9350) for rings/strokes. Neon #00FC88 fails
       contrast badly as text on light.
     - The old wide neon glow is gone: a 20-30px coloured halo is a dark-UI
       device and reads as a smudge on light. Emphasis is now a crisp ring
       plus a tight offset shadow (lift, not radiance).
     - "Unresolved" chips use a translucent INK fill on light, never a
       translucent white. Soften the CONTAINER, keep the label text legible.

   ============================================================ */

.szav-root {
	--szav-ground:  #F4F0E8;
	--szav-ink-dim: #6B6257;
	--szav-flame:       #E5471D;
	--szav-ember:       #F7A823;
	--szav-line:    #E2DACB;
	--szav-signal:      #157A44;   /* text on cream: ~5.6:1 */
	--szav-signal-ring: #1C9350;   /* ring / stroke only */

	position: relative;
	box-sizing: border-box;
	max-width: 780px;
	margin: 0 auto;
	padding: clamp(20px, 3vw, 32px) clamp(16px, 3vw, 32px) clamp(28px, 4vw, 40px);
	background: var(--szav-ground);
	border: 1px solid #E2DACB;
	border-radius: 14px;
	box-shadow: 0 1px 2px rgba(23,20,15,.05), 0 14px 28px -14px rgba(23,20,15,.12);
	font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
	overflow: hidden;
}
.szav-root *, .szav-root *::before, .szav-root *::after { box-sizing: border-box; }

.szav-caption {
	text-align: center;
	font-size: 15px;
	font-weight: 600;
	color: #4A443B;
	margin-bottom: 22px;
}

.szav-stage {
	position: relative;
	width: 100%;
	/* 5/2, not 5/3: the merged node is small and centered, so a 5/3 stage left a
	   large empty band above and below it. The traveling chips are placed by
	   PERCENTAGE (see the PHP), so they still drift proportionally in the shorter
	   stage. */
	aspect-ratio: 5 / 2;
}

/* Traveling chips — only meaningful once the animated timeline is running.
   Hidden entirely in the static/no-JS/reduced-motion render. */
.szav-chip { display: none; }

.szav-node {
	position: absolute;
	z-index: 2;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: 220px;
	border-radius: 16px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 5px;
	text-align: center;
	padding: 18px 16px;
	background: radial-gradient(circle, rgba(21,122,68,.10), var(--szav-ground) 72%);
	border: 1.5px solid var(--szav-signal-ring);
	box-shadow: 0 0 0 1px rgba(28,147,80,.16), 0 8px 20px -10px rgba(21,122,68,.28), 0 2px 6px rgba(23,20,15,.06);
}
.szav-node-ring { display: none; } /* only used during the animated one-shot pulse */
.szav-node-eyebrow {
	font-family: 'Roboto Mono', monospace;
	text-transform: uppercase;
	letter-spacing: .12em;
	font-size: 10px;
	color: var(--szav-signal);
}
.szav-node-label {
	font-size: 17px;
	font-weight: 700;
	color: #17140F;
	line-height: 1.25;
}
.szav-node-count {
	margin-top: 4px;
	font-family: 'Roboto Mono', monospace;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .04em;
	color: var(--szav-ember);
}

.szav-vlist {
	list-style: none;
	margin: 22px 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px 22px;
}
.szav-vitem {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	opacity: .55;
}
.szav-vitem-name {
	font-size: 12.5px;
	font-weight: 600;
	color: #4A443B;
}
.szav-vitem-src {
	font-family: 'Roboto Mono', monospace;
	text-transform: uppercase;
	letter-spacing: .06em;
	font-size: 8.5px;
	color: var(--szav-ink-dim);
}

.szav-resolved-caption {
	text-align: center;
	margin-top: 18px;
	font-size: 15px;
	font-weight: 700;
	color: #17140F;
}

@media (max-width: 640px) {
	.szav-node { width: 176px; padding: 14px 12px; }
	.szav-node-label { font-size: 14px; }
	.szav-vlist { gap: 8px 14px; }
}

/* ============================================================
   ANIMATED MODE — JS adds .szav--anim, then stages the reveal:
   three chips drift in from different directions, hold, then
   contract toward the shared center and crossfade into the merged
   node. Without JS (or with reduced motion), the resolved end-state
   above is what's shown, unconditionally.
   ============================================================ */
.szav--anim .szav-chip {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 3px;
	position: absolute;
	z-index: 1;
	transform: translate(-50%, -50%);
	width: 160px;
	margin: 0;
	text-align: center;
	padding: 10px 12px;
	background: rgba(23,20,15,.03);
	border: 1.5px dashed rgba(107,98,87,.4);
	border-radius: 10px;
	opacity: 0;
	transition: opacity .6s ease, left .9s ease, top .9s ease;
}
.szav-chip-src {
	font-family: 'Roboto Mono', monospace;
	text-transform: uppercase;
	letter-spacing: .08em;
	font-size: 9px;
	color: var(--szav-ink-dim);
}
.szav-chip-name {
	font-size: 13px;
	font-weight: 700;
	color: #4A443B;
}
.szav--anim .szav-chip.is-in { opacity: 1; }
.szav--anim .szav-chip.is-merging {
	left: 50% !important;
	top: 50% !important;
	opacity: 0;
	transition: left .9s ease, top .9s ease, opacity .9s ease .35s;
}

.szav--anim .szav-node {
	opacity: 0;
	transform: translate(-50%, -50%) scale(.86);
	transition: opacity .6s ease, transform .6s ease;
}
.szav--anim .szav-node.is-in { opacity: 1; transform: translate(-50%, -50%) scale(1); }

.szav--anim .szav-node.is-pulse .szav-node-ring {
	display: block;
	position: absolute;
	inset: -1.5px;
	border-radius: 16px;
	border: 2px solid var(--szav-signal-ring);
	animation: szav-pulse .85s ease-out 1;
}
@keyframes szav-pulse {
	0%   { opacity: .9; transform: scale(1); }
	100% { opacity: 0;  transform: scale(1.3); }
}

.szav--anim .szav-node-count {
	opacity: 0;
	transition: opacity .5s ease;
}
.szav--anim .szav-node-count.is-in { opacity: 1; }

.szav--anim .szav-vlist .szav-vitem {
	opacity: 0;
	transition: opacity .5s ease;
}
.szav--anim .szav-vlist.is-in .szav-vitem { opacity: .55; }

.szav--anim .szav-resolved-caption {
	opacity: 0;
	transition: opacity .5s ease;
}
.szav--anim .szav-resolved-caption.is-in { opacity: 1; }
