/**
 * GVA — ISA-95 coverage map (front page, block 04). The prototype drew this
 * pyramid with Three.js into a <canvas>; production draws the same scene as
 * one inline SVG since it's a fixed orthographic projection — static fills
 * and CSS transforms suffice, no render loop.
 *
 * COORDINATE SYSTEM. The SVG viewBox is 1320 x 825 user units (100 units per
 * world unit x the camera's 8.25-unit vertical view height). One user unit
 * is always `stage-height / 825` on screen, and the viewBox centre is the
 * stage centre. Every constant below is that projection read once, offline;
 * each derivation is named where it is used.
 *
 * LAYOUT. Mobile-first: base rules are the stacked layout (pyramid + a plain
 * disclosure list). The tier-anchored composition (labels beside each tier,
 * AI card in the gutter, detail panel on the right) is a 1121px+ enhancement.
 *
 * Reuses main.css (`.container`, `.btn`) and front-page.css (`.eyebrow`,
 * `.section-title`, `.reveal`) without redefining them. See docs/REFERENCE.md
 * for the `.eyebrow--light` deviation.
 *
 * Loaded only on the front page, alongside assets/js/isa95.js.
 */

/* ==========================================================================
   Section and head
   ========================================================================== */

.isa95-section {
	position: relative;
	overflow: hidden;
	padding: clamp(120px, 12vw, 168px) 0;
	background: var(--black);
	color: var(--white);
}

.isa95-head {
	display: grid;
	gap: 28px;
}

.isa95-head__lede {
	max-width: 520px;
	color: #a8a8a8;
	font-size: clamp(19.5px, 1.75vw, 22px);
	line-height: 1.55;
}

/* ==========================================================================
   Stage
   ========================================================================== */

.isa95-stage {
	--isa95-stage-h: clamp(790px, 71vw, 900px);

	position: relative;
	margin-top: 52px;
	isolation: isolate;
}

/* ==========================================================================
   The drawing
   ========================================================================== */

.isa95-figure {
	position: relative;
	overflow: hidden;
	width: 100%;
	max-width: 460px;
	margin: 0 auto 10px;
	/* Crop window on the viewBox: x 320-960, y 80-760. Wide enough for the
	   pyramid, the descent arc, the AI bracket and the full explode travel. */
	aspect-ratio: 640 / 680;
}

.isa95-pyramid {
	position: absolute;
	top: -11.7647%; /* -80 / 680 */
	left: -50%; /* -320 / 640 */
	width: 206.25%; /* 1320 / 640 */
	height: 121.3235%; /* 825 / 680 */
	/* main.css resets every svg to `max-width: 100%`. This drawing is
	   deliberately wider than its crop window at every layout, so it opts out
	   here rather than the primitive being weakened for the whole theme. */
	max-width: none;
	pointer-events: none;
}

/* --- Tier faces ------------------------------------------------------- */

.isa95-tier {
	transition: transform 0.55s var(--ease);
}

.isa95-tier__face {
	fill: var(--isa95-tier-rest);
	stroke: #5e574c;
	stroke-width: 1;
	vector-effect: non-scaling-stroke;
	transition: fill 0.35s var(--ease), stroke 0.35s var(--ease), stroke-opacity 0.35s var(--ease);
}

/* The tonal ladder base to apex, with every state it can be in. These are the
   reference's five GRAPHITE values and its own material blends resolved:
   selected = 24% towards --red-dark, AI-lit = 12%, dimmed = 45% towards the
   cool shadow #0A0D12, hover = a further 16% towards --red-dark. A selected
   tier's top face additionally carries its 22% joint-shadow cap, which is the
   only cap this camera can see. */
.isa95-tier[data-isa95-tier="l0"] {
	--isa95-tier-rest: #22262e;
	--isa95-tier-selected: #46242d;
	--isa95-tier-selected-top: #391f26;
	--isa95-tier-lit: #34252e;
	--isa95-tier-dim: #171b21;
	--isa95-tier-hover: #3a252d;
	--isa95-tier-dim-hover: #311b23;
}

.isa95-tier[data-isa95-tier="l1"] {
	--isa95-tier-rest: #2f343c;
	--isa95-tier-selected: #502f38;
	--isa95-tier-selected-top: #41272e;
	--isa95-tier-lit: #3f313a;
	--isa95-tier-dim: #1e2229;
	--isa95-tier-hover: #453039;
	--isa95-tier-dim-hover: #372229;
}

.isa95-tier[data-isa95-tier="l2"] {
	--isa95-tier-rest: #3b4046;
	--isa95-tier-selected: #59383f;
	--isa95-tier-selected-top: #482e34;
	--isa95-tier-lit: #4a3c43;
	--isa95-tier-dim: #25292f;
	--isa95-tier-hover: #4f3b42;
	--isa95-tier-dim-hover: #3c272e;
}

.isa95-tier[data-isa95-tier="l3"] {
	--isa95-tier-rest: #464a4f;
	--isa95-tier-selected: #613f46;
	--isa95-tier-selected-top: #4f343a;
	--isa95-tier-lit: #54454b;
	--isa95-tier-dim: #2b2f34;
	--isa95-tier-hover: #584349;
	--isa95-tier-dim-hover: #422c32;
}

.isa95-tier[data-isa95-tier="l4"] {
	--isa95-tier-rest: #52534e;
	--isa95-tier-selected: #6a4645;
	--isa95-tier-selected-top: #563a39;
	--isa95-tier-lit: #5e4d4a;
	--isa95-tier-dim: #323433;
	--isa95-tier-hover: #624b48;
	--isa95-tier-dim-hover: #473032;
}

/* Something holds focus: everything not involved recedes. */
.isa95-stage[data-isa95-selected] .isa95-tier .isa95-tier__face {
	fill: var(--isa95-tier-dim);
	stroke-opacity: 0.34;
}

.isa95-stage[data-isa95-selected] .isa95-tier.is-selected .isa95-tier__face {
	fill: var(--isa95-tier-selected);
	stroke: var(--red);
	stroke-opacity: 1;
}

.isa95-stage[data-isa95-selected] .isa95-tier.is-selected .isa95-tier__face--top {
	fill: var(--isa95-tier-selected-top);
}

.isa95-stage[data-isa95-selected] .isa95-tier.is-lit .isa95-tier__face {
	fill: var(--isa95-tier-lit);
	stroke: var(--red);
	stroke-opacity: 1;
}

/* Explode. A selection splits the stack into three rigid blocks, exactly as
   the reference's LOWER_OPEN / UPPER_OPEN gaps do: 0.82 world units down for
   everything below the selected tier, 0.60 up for everything above. Projected
   through the camera's y basis (0.974328), those become 79.9 and 58.5 user
   units. */
.isa95-tier.is-below {
	transform: translateY(79.9px);
}

.isa95-tier.is-above {
	transform: translateY(-58.5px);
}

/* --- Engraved level code ---------------------------------------------- */

/* The reference sizes this against the viewport (`clamp(11px, 1.05vw, 16px)`);
   here it is 13.6 user units, so it scales with the pyramid it is cut into —
   13.1px to 14.8px across the desktop range. */
.isa95-tier__code {
	fill: var(--red);
	font-family: var(--font-mono);
	font-size: 13.6px;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-anchor: middle;
	text-shadow: 0 1px 5px rgba(0, 0, 0, 0.7);
	transform-box: fill-box;
	transform-origin: center;
	transition: transform 0.22s var(--ease);
}

.isa95-tier.is-selected .isa95-tier__code {
	transform: scale(1.05);
}

/* --- Brand descent arc: one shot on first reveal, then gone ----------- */

.isa95-descent {
	fill: none;
	stroke: var(--red);
	stroke-width: 1;
	stroke-dasharray: 700;
	stroke-dashoffset: 700;
	vector-effect: non-scaling-stroke;
	opacity: 0;
}

/* --- Industrial AI: a transversal relationship, not a box ------------- */

/* The bracket draws the run between the transversal card and the tiers it
   spans. It only means anything in the tier-anchored composition, where the
   card sits in the gutter at the end of it; in the stacked layout the card is
   an ordinary row in the list below and the arms would reach out to nothing,
   so the whole group is withheld rather than left dangling. */
.isa95-ai-link {
	display: none;
}

.isa95-ai-bracket {
	fill: none;
	stroke: var(--red);
	stroke-width: 1.05;
	stroke-dasharray: 3 6;
	vector-effect: non-scaling-stroke;
	opacity: 0.72;
	transition: opacity 0.45s var(--ease), stroke-width 0.25s var(--ease);
}

.isa95-ai-node {
	fill: var(--red);
	opacity: 0.9;
	transition: opacity 0.45s var(--ease);
}

.isa95-stage[data-isa95-selected="ai"] .isa95-ai-bracket {
	opacity: 1;
	stroke-width: 1.3;
}

/* While a single level holds focus the transversal layer is not the subject. */
.isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-ai-bracket,
.isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-ai-node {
	opacity: 0;
}

/* ==========================================================================
   Levels — stacked layout (base)
   ========================================================================== */

.isa95-levels {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.isa95-level {
	border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.isa95-level__button {
	display: flex;
	align-items: baseline;
	gap: 12px;
	width: 100%;
	padding: 18px 0;
	border: 0;
	background: transparent;
	color: #dadada;
	text-align: left;
	cursor: pointer;
	transition: color 0.22s var(--ease);
}

.isa95-level__button:hover {
	color: var(--white);
}

.isa95-level__code {
	flex: 0 0 auto;
	min-width: 3.6em;
	color: var(--red);
	font-family: var(--font-mono);
	font-size: 14px;
	font-weight: 700;
	letter-spacing: 0.12em;
	line-height: 1.4;
	text-transform: uppercase;
}

.isa95-level__name {
	flex: 1 1 auto;
	font-size: 17px;
	font-weight: 500;
	letter-spacing: -0.015em;
	line-height: 1.22;
}

.isa95-level__core {
	flex: 0 0 auto;
	align-self: center;
	padding: 3px 6px;
	border: 1px solid rgba(255, 255, 255, 0.26);
	color: #afafaf;
	font-family: var(--font-mono);
	font-size: 10px;
	font-weight: 400;
	letter-spacing: 0.12em;
	line-height: 1;
	text-transform: uppercase;
	transition: border-color 0.2s, color 0.2s;
}

.isa95-level.is-open .isa95-level__button {
	color: var(--white);
}

.isa95-level.is-open .isa95-level__core {
	border-color: var(--red);
	color: var(--red);
}

/* The transversal layer keeps its dashed identity in the stacked list too. */
.isa95-level--ai .isa95-level__code {
	min-width: 0;
	padding: 3px 6px;
	border: 1px dashed rgba(238, 39, 55, 0.55);
	line-height: 1;
}

/* ==========================================================================
   Detail panel
   ========================================================================== */

.isa95-panel {
	padding: 0 0 22px 18px;
	border-left: 2px solid var(--red);
}

.isa95-panel__close {
	display: none;
}

.isa95-panel__kicker {
	color: var(--red);
	font-family: var(--font-mono);
	font-size: 12px;
	letter-spacing: 0.16em;
	line-height: 1.45;
	text-transform: uppercase;
}

.isa95-panel__title {
	margin: 14px 0 11px;
	color: var(--white);
	font-size: clamp(25px, 2.6vw, 32px);
	letter-spacing: -0.027em;
	line-height: 1.06;
}

.isa95-panel__role {
	display: inline-flex;
	margin-bottom: 15px;
	padding: 5px 8px;
	border: 1px solid var(--red);
	background: var(--red);
	color: var(--white);
	font-family: var(--font-mono);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.12em;
	line-height: 1;
	text-transform: uppercase;
}

.isa95-panel__desc {
	max-width: 420px;
	color: #c9c9c9;
	font-size: 16px;
	line-height: 1.55;
}

.isa95-panel__desc b {
	color: var(--red);
	font-weight: 600;
}

.isa95-panel__list {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin: 19px 0 0;
	padding: 0;
	list-style: none;
}

.isa95-panel__list li {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	color: #d3d3d3;
	font-size: 14px;
	line-height: 1.5;
}

.isa95-panel__list li::before {
	flex: 0 0 auto;
	width: 14px;
	height: 1px;
	margin-top: 8px;
	background: var(--red);
	content: "";
}

.isa95-panel__meta {
	margin-top: 15px;
	padding-top: 13px;
	border-top: 1px dashed rgba(255, 255, 255, 0.15);
}

.isa95-panel__meta-title {
	margin: 0 0 9px;
	color: #858585;
	font-family: var(--font-mono);
	font-size: 11px;
	font-weight: 400;
	letter-spacing: 0.13em;
	line-height: 1;
	text-transform: uppercase;
}

.isa95-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.isa95-chip {
	padding: 5px 8px;
	border: 1px solid rgba(255, 255, 255, 0.16);
	background: rgba(255, 255, 255, 0.025);
	color: #c9c9c9;
	font-family: var(--font-mono);
	font-size: 11px;
	text-transform: uppercase;
}

.isa95-chip--accent {
	border-color: var(--red);
	background: var(--red);
	color: var(--white);
}

/* --- Disclosure gating ---------------------------------------------------
 * Collapsing only exists once assets/js/isa95.js adds the root class, so with
 * JavaScript unavailable every panel stays open and the section reads as a
 * plain, complete list of the six levels. The script also rewrites the
 * server-rendered `aria-expanded="true"` to `false` as it collapses them, so
 * the attribute never disagrees with what is on screen. */
html.has-isa95 .isa95-panel {
	visibility: hidden;
	opacity: 0;
}

html.has-isa95 .isa95-level.is-open .isa95-panel {
	visibility: visible;
	opacity: 1;
}

@media (max-width: 1120px) {

	html.has-isa95 .isa95-panel {
		max-height: 0;
		padding-bottom: 0;
		overflow: hidden;
		transition: opacity 0.4s var(--ease), max-height 0.5s var(--ease), padding-bottom 0.5s var(--ease), visibility 0.4s;
	}

	html.has-isa95 .isa95-level.is-open .isa95-panel {
		max-height: 1400px;
		padding-bottom: 22px;
	}
}

/* ==========================================================================
   Actions
   The reference names this row `.btn-row`, but it uses it here and nowhere
   else, so it is a component class rather than a global primitive. `.btn`
   itself comes untouched from main.css.
   ========================================================================== */

.isa95-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 34px;
}

/* ==========================================================================
   Hint
   ========================================================================== */

.isa95-hint {
	margin-top: 22px;
	color: #777;
	font-family: var(--font-mono);
	font-size: 12px;
	letter-spacing: 0.16em;
	line-height: 1;
	text-align: center;
	text-transform: uppercase;
}

/* ==========================================================================
   Build-in — one shot, keyed off the shared reveal observer
   Gated on `has-gva-reveal` exactly like `.reveal` itself, so nothing stays
   hidden when JavaScript never runs. Animations rather than delayed
   transitions, so a build delay can never leak into a later state change.
   ========================================================================== */

html.has-gva-reveal .isa95-tier,
html.has-gva-reveal .isa95-ai-bracket,
html.has-gva-reveal .isa95-ai-node,
html.has-gva-reveal .isa95-hint {
	opacity: 0;
}

.isa95-stage.is-revealed .isa95-tier {
	opacity: 1;
	animation: isa95-tier-in 0.52s var(--ease) var(--isa95-tier-delay, 0ms) backwards;
}

/* The reference's own reveal order — L4 lands before L3. */
.isa95-tier[data-isa95-tier="l0"] { --isa95-tier-delay: 0ms; }
.isa95-tier[data-isa95-tier="l1"] { --isa95-tier-delay: 170ms; }
.isa95-tier[data-isa95-tier="l2"] { --isa95-tier-delay: 340ms; }
.isa95-tier[data-isa95-tier="l4"] { --isa95-tier-delay: 510ms; }
.isa95-tier[data-isa95-tier="l3"] { --isa95-tier-delay: 680ms; }

.isa95-stage.is-revealed .isa95-ai-bracket {
	opacity: 0.72;
	animation: isa95-fade-in 0.45s var(--ease) 1250ms backwards;
}

.isa95-stage.is-revealed .isa95-ai-node {
	opacity: 0.9;
	animation: isa95-fade-in 0.45s var(--ease) 1250ms backwards;
}

.isa95-stage.is-revealed .isa95-hint {
	opacity: 1;
	animation: isa95-fade-in 0.5s var(--ease) 1800ms backwards;
}

.isa95-stage.is-revealed .isa95-descent {
	animation: isa95-descent 1.05s var(--ease) forwards;
}

@keyframes isa95-tier-in {
	from {
		opacity: 0.08;
	}
}

@keyframes isa95-fade-in {
	from {
		opacity: 0;
	}
}

@keyframes isa95-descent {
	0% {
		opacity: 0;
		stroke-dashoffset: 700;
	}

	18% {
		opacity: 0.56;
	}

	75% {
		opacity: 0.46;
	}

	100% {
		opacity: 0;
		stroke-dashoffset: 0;
	}
}

/* ==========================================================================
   Tier-anchored layout — 1121px and up
   The reference's own composition. Every anchor is the projection read as a
   fraction: a tier's vertical centre is a share of the stage height, and its
   horizontal anchor is `50% + F x stage-height`, where F is that tier's
   projected right edge expressed in stage heights — (edge - 660) / 825.

   The whole block is gated on `has-isa95`, the class the script adds only
   once it has found the DOM sound and bound every handler. This composition
   overlaps six absolutely positioned panels in one slot and relies on the
   script to keep exactly one of them open; without it they would pile up
   illegibly. So when the script is absent or fails, the stacked layout below
   1121px stays in force at every width — one panel after another, all
   readable, which is what the section must degrade to.
   ========================================================================== */

@media (min-width: 1121px) {

	html.has-isa95 .isa95-head {
		grid-template-columns: 1.15fr 0.85fr;
		gap: 64px;
		align-items: end;
	}

	html.has-isa95 .isa95-stage {
		--isa95-panel-w: clamp(330px, 34vw, 415px);
		--isa95-panel-left: min(64%, calc(100% - 12px - var(--isa95-panel-w)));
		/* The pyramid's shift under level focus. The reference computes it per
		   width, and at every width this layout applies to the computation
		   saturates at its own -3.1 clamp: 2.58 world units left of rest.
		   That translation is along world X, but the camera is tilted, so its
		   Y basis has an X component (-0.085947) — the pyramid therefore rises
		   as it slides. Both components are the same one move projected:
		   2.58 x 0.924261 x 100 = 238.5 user units across, and
		   2.58 x 0.085947 x 100 =  22.2 user units up. */
		--isa95-focus-shift: -238.5px;
		--isa95-focus-lift: -22.2px;
		--isa95-focus-shift-px: calc(-0.28909 * var(--isa95-stage-h));

		height: var(--isa95-stage-h);
		margin-top: 72px;
		overflow: hidden;
		border-top: 1px solid rgba(255, 255, 255, 0.08);
		border-bottom: 1px solid rgba(255, 255, 255, 0.08);
		background: radial-gradient(ellipse 62% 58% at 44% 52%, rgba(214, 206, 196, 0.055), rgba(120, 128, 140, 0.022) 46%, transparent 78%);
	}

	html.has-isa95 .isa95-stage::before {
		position: absolute;
		z-index: 0;
		inset: 0;
		opacity: 0.22;
		background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cpath d='M64 0H0V64' fill='none' stroke='%23ffffff' stroke-opacity='.03' stroke-width='1'/%3E%3C/svg%3E");
		-webkit-mask-image: radial-gradient(ellipse 76% 72% at 46% 48%, #000 5%, rgba(0, 0, 0, 0.52) 58%, transparent 92%);
		mask-image: radial-gradient(ellipse 76% 72% at 46% 48%, #000 5%, rgba(0, 0, 0, 0.52) 58%, transparent 92%);
		pointer-events: none;
		content: "";
	}

	/* The drawing fills the stage: viewBox height maps to stage height, so one
	   user unit is stage-height / 825 and the viewBox centre is the stage
	   centre — the same mapping the reference camera produces. */
	html.has-isa95 .isa95-figure {
		position: absolute;
		z-index: 1;
		inset: 0;
		max-width: none;
		margin: 0;
		aspect-ratio: auto;
	}

	/* One user unit must be exactly `stage-height / 825`, the scale the
	   reference camera produces (viewH 8.25 world units over the stage
	   height). `slice` guarantees it from the height alone — the viewBox is
	   1320 wide, so height governs at every aspect this layout can take, and
	   the surplus width is cropped symmetrically about the camera axis. */
	html.has-isa95 .isa95-pyramid {
		inset: 0;
		width: 100%;
		height: 100%;
		transform: none;
	}

	/* Desktop pointer users may pick a tier on the drawing. The semantic
	   buttons stay the canonical controls: faces are never focusable and the
	   SVG stays out of the accessibility tree. */
	html.has-isa95 .isa95-tier__face {
		pointer-events: auto;
		cursor: pointer;
	}

	html.has-isa95 .isa95-tier:hover .isa95-tier__face {
		fill: var(--isa95-tier-hover);
		stroke-opacity: 0.8;
	}

	html.has-isa95 .isa95-stage[data-isa95-selected] .isa95-tier:hover .isa95-tier__face {
		fill: var(--isa95-tier-dim-hover);
		stroke-opacity: 0.8;
	}

	html.has-isa95 .isa95-stage[data-isa95-selected] .isa95-tier.is-selected:hover .isa95-tier__face {
		fill: var(--isa95-tier-selected);
		stroke-opacity: 1;
	}

	html.has-isa95 .isa95-ai-link {
		display: block;
	}

	html.has-isa95 .isa95-pyramid__group {
		transition: transform 0.55s var(--ease);
	}

	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-pyramid__group {
		transform: translate(var(--isa95-focus-shift), var(--isa95-focus-lift));
	}

	/* --- Level labels ---------------------------------------------------- */

	html.has-isa95 .isa95-levels {
		position: absolute;
		z-index: 4;
		inset: 0;
		border: 0;
		pointer-events: none;
	}

	html.has-isa95 .isa95-level {
		border: 0;
	}

	html.has-isa95 .isa95-level__button {
		position: absolute;
		left: var(--isa95-label-left);
		top: calc(var(--isa95-row) + var(--isa95-label-shift, 0%));
		display: block;
		width: auto;
		min-width: 230px;
		max-width: 262px;
		padding: 7px 0 7px 40px;
		color: var(--white);
		line-height: 1.22;
		text-wrap: balance;
		pointer-events: auto;
		transform: translateY(-50%);
		transition: color 0.22s var(--ease), top 0.55s var(--ease), transform 0.22s var(--ease), opacity 0.3s, max-width 0.42s var(--ease);
	}

	/* Each label tracks the tier it names through the explode, so a name never
	   drifts off its own slab. The three offsets are the same projection the
	   drawing uses, as a share of the stage height (user units / 825): the
	   whole stack rises 22.2 under focus, and relative to the selected tier
	   everything below it drops a further 79.9 and everything above rises 58.5.
	   The transversal layer names no tier and keeps its place in the gutter. */
	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level:not(.isa95-level--ai) {
		--isa95-label-shift: -2.6909%;
	}

	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level.is-below {
		--isa95-label-shift: 6.9939%; /* (79.9 - 22.2) / 825 */
	}

	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level.is-above {
		--isa95-label-shift: -9.7758%; /* (-58.5 - 22.2) / 825 */
	}

	html.has-isa95 .isa95-level__button::before {
		position: absolute;
		left: 0;
		top: 50%;
		width: 26px;
		height: 1px;
		background: rgba(255, 255, 255, 0.28);
		transition: background 0.22s, width 0.22s, opacity 0.34s var(--ease);
		content: "";
	}

	html.has-isa95 .isa95-level__button:hover {
		transform: translate(3px, -50%);
	}

	html.has-isa95 .isa95-level__button:hover::before {
		width: 30px;
		background: rgba(255, 255, 255, 0.62);
	}

	/* The code is engraved on the slab at this size, so the label carries the
	   name only, as in the reference. It stays in the accessible name. */
	html.has-isa95 .isa95-level__code {
		position: absolute;
		width: 1px;
		height: 1px;
		margin: -1px;
		padding: 0;
		border: 0;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}

	html.has-isa95 .isa95-level__name {
		display: inline;
		color: #dadada;
		font-size: 19px;
	}

	html.has-isa95 .isa95-level__core {
		display: inline-flex;
		margin-left: 7px;
		vertical-align: 2px;
	}

	html.has-isa95 .isa95-level.is-open .isa95-level__button::before {
		width: 32px;
		background: var(--red);
	}

	html.has-isa95 .isa95-level.is-open .isa95-level__name {
		color: var(--white);
	}

	/* Row anchors: each tier's projected vertical centre as a share of the
	   stage height. The AI row sits midway between the bracket's two nodes. */
	html.has-isa95 .isa95-level[data-isa95-level="l0"]{ --isa95-row: 71.3312%; --isa95-label-left: calc(50% + 0.209134 * var(--isa95-stage-h) + 28px); }
	html.has-isa95 .isa95-level[data-isa95-level="l1"]{ --isa95-row: 59.6244%; --isa95-label-left: calc(50% + 0.157502 * var(--isa95-stage-h) + 28px); }
	html.has-isa95 .isa95-level[data-isa95-level="l2"]{ --isa95-row: 47.9177%; --isa95-label-left: calc(50% + 0.105870 * var(--isa95-stage-h) + 28px); }
	html.has-isa95 .isa95-level[data-isa95-level="l3"]{ --isa95-row: 36.2109%; --isa95-label-left: calc(50% + 0.054238 * var(--isa95-stage-h) + 28px); }
	html.has-isa95 .isa95-level[data-isa95-level="l4"]{ --isa95-row: 24.5041%; --isa95-label-left: calc(50% + 0.002606 * var(--isa95-stage-h) + 28px); }

	/* A level holds focus: the pyramid slides left, the labels ride with it and
	   give up whatever width the detail panel now needs. The reference measures
	   this every frame; here it is one expression the engine evaluates at
	   layout time. */
	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level:not(.isa95-level--ai) .isa95-level__button {
		min-width: 0;
		max-width: calc(var(--isa95-panel-left) - var(--isa95-label-left) - var(--isa95-focus-shift-px) - 20px);
		opacity: 0.4;
		transform: translate(var(--isa95-focus-shift-px), -50%);
	}

	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level:not(.isa95-level--ai) .isa95-level__button:hover {
		transform: translate(calc(var(--isa95-focus-shift-px) + 3px), -50%);
	}

	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level.is-open .isa95-level__button {
		opacity: 1;
	}

	/* The transversal layer takes the stage; the ladder steps back. */
	html.has-isa95 .isa95-stage[data-isa95-selected="ai"] .isa95-level:not(.isa95-level--ai) .isa95-level__button {
		opacity: 0;
		pointer-events: none;
	}

	/* --- The transversal AI card ---------------------------------------- */

	html.has-isa95 .isa95-level--ai {
		--isa95-row: 47.7697%;
	}

	html.has-isa95 .isa95-level--ai .isa95-level__button {
		left: 14px;
		display: flex;
		flex-wrap: wrap;
		align-items: flex-start;
		column-gap: 6px;
		/* The card lives in the gutter outboard of the bracket's vertical run
		   (user unit 298.1, i.e. 0.43867 of the stage height left of centre),
		   with 14px clear on both sides.
		   The reference does this the other way round — it measures the rendered
		   card each layout and moves the bracket to hug it. Production fixes the
		   bracket and caps the card instead, so no layout is ever read back. At
		   the design width the two agree exactly (a 206px card); a longer
		   translation wraps inside the cap rather than pushing the drawing. */
		min-width: 0;
		max-width: calc(50% - 0.43867 * var(--isa95-stage-h) - 28px);
		padding: 14px 16px;
		border: 1px dashed rgba(238, 39, 55, 0.55);
		background: rgba(18, 18, 18, 0.76);
		-webkit-backdrop-filter: blur(8px);
		backdrop-filter: blur(8px);
		text-wrap: normal;
		transition: opacity 0.45s var(--ease), transform 0.45s var(--ease), background 0.22s, border-color 0.22s, box-shadow 0.22s;
	}

	/* The marker dot centres on the first title line, never on the card's full
	   height — the reference's own note. */
	html.has-isa95 .isa95-level--ai .isa95-level__button::before {
		position: static;
		order: 1;
		flex: 0 0 auto;
		width: 7px;
		height: 7px;
		margin-top: 3.6px;
		margin-right: 4px;
		border-radius: 50%;
		background: var(--red);
	}

	html.has-isa95 .isa95-level--ai .isa95-level__button:hover, html.has-isa95 .isa95-level--ai.is-open .isa95-level__button {
		border-color: var(--red);
		background: rgba(18, 18, 18, 0.92);
		box-shadow: 0 8px 30px rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(238, 39, 55, 0.12);
		transform: translateY(-50%);
	}

	html.has-isa95 .isa95-level--ai .isa95-level__button:hover::before, html.has-isa95 .isa95-level--ai.is-open .isa95-level__button::before {
		width: 7px;
		background: var(--red);
	}

	html.has-isa95 .isa95-level--ai .isa95-level__name, html.has-isa95 .isa95-level--ai .isa95-level__code {
		flex: 0 0 auto;
		color: var(--red);
		font-family: var(--font-mono);
		font-size: 11px;
		font-weight: 700;
		letter-spacing: 0.13em;
		line-height: 1.3;
		text-transform: uppercase;
		white-space: nowrap;
	}

	html.has-isa95 .isa95-level--ai .isa95-level__name {
		order: 2;
	}

	html.has-isa95 .isa95-level--ai .isa95-level__code {
		position: static;
		order: 3;
		width: auto;
		height: auto;
		margin: 0;
		padding: 0;
		border: 0;
		overflow: visible;
		clip-path: none;
	}

	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-level--ai .isa95-level__button {
		opacity: 0;
		pointer-events: none;
		transform: translateY(calc(-50% + 6px));
	}

	/* --- Detail panel --------------------------------------------------- */

	html.has-isa95 .isa95-panel {
		position: absolute;
		z-index: 6;
		left: var(--isa95-panel-left);
		/* Anchored on the selected tier and clamped in one expression: with both
		   block offsets set and the block margins auto, the panel's centre is
		   fixed at (height + top - bottom) / 2, and `max-height` guarantees it
		   can never leave the stage. The bias is the tier's own offset from the
		   stage centre, damped to 0.57 so the tallest panel still fits. The
		   reference reaches the same result by measuring the rendered card on
		   every frame. */
		top: var(--isa95-panel-top, 20px);
		bottom: var(--isa95-panel-bottom, 20px);
		width: var(--isa95-panel-w);
		height: max-content;
		max-height: calc(100% - var(--isa95-panel-top, 20px) - var(--isa95-panel-bottom, 20px));
		margin-block: auto;
		padding: 16px 0 18px 24px;
		overflow-y: auto;
		border-left: 2px solid var(--red);
		background: linear-gradient(90deg, rgba(18, 18, 18, 0.96), rgba(18, 18, 18, 0.82) 76%, rgba(18, 18, 18, 0.38));
		pointer-events: auto;
	}

	html.has-isa95 .isa95-panel::before {
		position: absolute;
		left: -5px;
		top: 0;
		width: 8px;
		height: 8px;
		background: var(--red);
		content: "";
	}

	html.has-isa95 .isa95-level[data-isa95-level="l0"]{ --isa95-panel-top: calc(20px + 0.243176 * var(--isa95-stage-h)); }
	html.has-isa95 .isa95-level[data-isa95-level="l1"]{ --isa95-panel-top: calc(20px + 0.109718 * var(--isa95-stage-h)); }
	html.has-isa95 .isa95-level[data-isa95-level="l2"]{ --isa95-panel-bottom: calc(20px + 0.023738 * var(--isa95-stage-h)); }
	html.has-isa95 .isa95-level[data-isa95-level="l3"]{ --isa95-panel-bottom: calc(20px + 0.157196 * var(--isa95-stage-h)); }
	html.has-isa95 .isa95-level[data-isa95-level="l4"]{ --isa95-panel-bottom: calc(20px + 0.290653 * var(--isa95-stage-h)); }
	html.has-isa95 .isa95-level--ai{ --isa95-panel-bottom: calc(20px + 0.025425 * var(--isa95-stage-h)); }

	html.has-isa95 .isa95-level--ai .isa95-panel {
		left: min(max(67%, 760px), calc(100% - 12px - var(--isa95-panel-w)));
	}

	html.has-isa95 .isa95-panel__close {
		position: absolute;
		right: 4px;
		top: 0;
		z-index: 2;
		display: block;
		width: 34px;
		height: 34px;
		border: 0;
		background: transparent;
		color: #858585;
		font-family: var(--font-mono);
		font-size: 20px;
		line-height: 1;
		cursor: pointer;
	}

	html.has-isa95 .isa95-panel__close:hover {
		color: var(--white);
	}

	html.has-isa95 .isa95-panel__kicker {
		padding-right: 40px;
	}

	html.has-isa95 .isa95-panel {
		overflow: hidden;
		clip-path: inset(0 100% 0 0);
		transform: translateX(-12px);
		transition: opacity 0.62s var(--ease), transform 0.62s var(--ease), clip-path 0.72s var(--ease), visibility 0.62s;
	}

	html.has-isa95 .isa95-level.is-open .isa95-panel {
		overflow-y: auto;
		clip-path: inset(0);
		transform: none;
	}

	/* --- Hint ------------------------------------------------------------ */

	html.has-isa95 .isa95-hint {
		position: absolute;
		left: 50%;
		bottom: 28px;
		z-index: 5;
		margin: 0;
		transform: translateX(-50%);
		transition: opacity 0.5s var(--ease);
	}

	html.has-isa95 .isa95-stage[data-isa95-selected] .isa95-hint {
		opacity: 0;
	}
}

/* ==========================================================================
   Reduced motion
   No build, no explode, no slide, no arc. Selection changes state instantly
   and every control keeps working.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

	/* The tier-anchored block carries an `html.has-isa95` prefix on every rule,
	   so anything it also declares has to be answered at that weight here —
	   hence the paired selectors. The bare form covers the stacked layout and
	   the no-script fallback, where that prefix is absent. */
	.isa95-tier,
	.isa95-tier__face,
	.isa95-tier__code,
	.isa95-pyramid__group,
	.isa95-level__button,
	.isa95-panel,
	.isa95-ai-bracket,
	.isa95-ai-node,
	.isa95-hint,
	html.has-isa95 .isa95-pyramid__group,
	html.has-isa95 .isa95-level__button,
	html.has-isa95 .isa95-level__button::before,
	html.has-isa95 .isa95-level--ai .isa95-level__button,
	html.has-isa95 .isa95-hint,
	html.has-isa95 .isa95-stage[data-isa95-selected] .isa95-hint,
	html.has-isa95 .isa95-panel {
		transition: none;
	}

	.isa95-tier.is-below,
	.isa95-tier.is-above,
	.isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-pyramid__group,
	html.has-isa95 .isa95-stage[data-isa95-selected]:not([data-isa95-selected="ai"]) .isa95-pyramid__group {
		transform: none;
	}

	html.has-gva-reveal .isa95-tier,
	html.has-gva-reveal .isa95-hint {
		opacity: 1;
	}

	html.has-gva-reveal .isa95-ai-bracket {
		opacity: 0.72;
	}

	html.has-gva-reveal .isa95-ai-node {
		opacity: 0.9;
	}

	.isa95-stage.is-revealed .isa95-tier,
	.isa95-stage.is-revealed .isa95-ai-bracket,
	.isa95-stage.is-revealed .isa95-ai-node,
	.isa95-stage.is-revealed .isa95-hint,
	.isa95-stage.is-revealed .isa95-descent {
		animation: none;
	}

	html.has-isa95 .isa95-panel {
		clip-path: none;
		transform: none;
	}
}
