/*
 * ASR Quiz Patente – Motion v3 "strada" (docs/DESIGN-V3.md §3; API in docs/v3-motion.md).
 * Token di curve e durate, stati hover solo CSS (M6, M7), componenti di motion
 * (gauge, semaforo, strada di avanzamento, contatori, contachilometri), loop CSS (M2), regole reduced-motion.
 *
 * Principi vincolanti:
 * - il contenuto non dipende mai dall'animazione: OGNI regola qui sotto mostra lo stato finale senza JS;
 *   gli stati iniziali li imposta solo asr-motion.js (inline), dopo aver deciso il tier;
 * - si animano solo transform, opacity, stroke-dashoffset;
 * - le animazioni continue esistono solo dentro @media (prefers-reduced-motion: no-preference)
 *   e fuori da .asr-reduce-motion (classe impostabile dalle preferenze dell'app, su <html> o sulla radice);
 * - i loop CSS girano solo con .is-inview (impostata da asr-motion.js) e si fermano con
 *   html.asr-motion-paused (tab nascosta / pausa utente) o [data-asr-loops="paused"] su un antenato.
 */

/* ------------------------------------------------------------------ */
/* 1. Token (§3.2)                                                     */
/* ------------------------------------------------------------------ */
.asr-site,
.asr-scope,
.asr-trial {
	--asr-ease-drive: cubic-bezier(0.22, 0.61, 0.36, 1);
	--asr-ease-brake: cubic-bezier(0.16, 1, 0.3, 1);
	--asr-ease-throttle: cubic-bezier(0.65, 0, 0.35, 1);
	--asr-ease-cruise: linear;
	--asr-dur-sweep: 900ms;
	--asr-dur-drive: 700ms;
	--asr-dur-needle: 1400ms;
	--asr-dur-count: 1200ms;
	--asr-dur-draw: 1600ms;
	--asr-lane-speed: 1.6s;
	--asr-sweep-color: rgb(255 255 255 / 0.55);
}
@media (prefers-reduced-motion: reduce) {
	.asr-site, .asr-scope, .asr-trial { --asr-dur-sweep: 0ms; --asr-dur-drive: 0ms; --asr-dur-needle: 0ms; --asr-dur-count: 0ms; --asr-dur-draw: 0ms; }
}
.asr-reduce-motion :is(.asr-site, .asr-scope, .asr-trial),
:is(.asr-site, .asr-scope, .asr-trial).asr-reduce-motion {
	--asr-dur-sweep: 0ms; --asr-dur-drive: 0ms; --asr-dur-needle: 0ms; --asr-dur-count: 0ms; --asr-dur-draw: 0ms;
}

/* ------------------------------------------------------------------ */
/* 2. Coesistenza con il reveal v2 di asr-site.js                       */
/* ------------------------------------------------------------------ */
/* Con GSAP attivo (classe .asr-motion sulla radice) il reveal lo guida asr-motion.js con stili inline:
   il CSS v2 non nasconde più nulla e non transiziona opacity/transform (eviterebbe di "inseguire" GSAP). */
.asr-site.asr-motion.asr-site-js [data-asr-reveal]:not(.is-revealed) { opacity: 1; transform: none; }
.asr-site.asr-motion [data-asr-reveal] { transition-property: background-color, border-color, color; }

/* ------------------------------------------------------------------ */
/* 3. M6 – Fascio di faro sul bordo (.asr-headlight-sweep)              */
/* ------------------------------------------------------------------ */
/* Su card link e CTA: uno sweep di luce che corre SOLO sul bordo (maschera di 1 px), una volta per hover/focus.
   Usa ::after dell'elemento (variante --before se ::after è già occupato). Il focus ring resta visibile:
   lo sweep sta sotto l'outline. Bordo della maschera: --asr-sweep-w (default 1px; 2px per i pulsanti). */
:is(.asr-site, .asr-scope, .asr-trial) .asr-headlight-sweep {
	--asr-sweep-w: 1px;
	position: relative;
	isolation: isolate;
}
:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-btn, .asr-site-btn).asr-headlight-sweep { --asr-sweep-w: 2px; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-headlight-sweep:not(.asr-headlight-sweep--before)::after,
:is(.asr-site, .asr-scope, .asr-trial) .asr-headlight-sweep--before::before {
	content: "";
	position: absolute;
	inset: calc(-1 * var(--asr-sweep-w));
	z-index: 1;
	padding: var(--asr-sweep-w);
	pointer-events: none;
	/* banda 105° (trasparente 35% → bianco .55 → trasparente 65% della finestra), su un fondo largo 3×:
	   lo sweep sposta background-position. Deroga documentata a "solo transform/opacity": il ridisegno è
	   limitato all'anello di 1–2 px mascherato, una volta per hover; nessun layout. */
	background: linear-gradient(105deg, transparent 45%, var(--asr-sweep-color) 50%, transparent 55%) no-repeat;
	background-size: 300% 100%;
	background-position: 100% 0;
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
	opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-headlight-sweep:is(:hover, :focus-visible, :focus-within):not(.asr-reduce-motion *):not(.asr-headlight-sweep--before)::after,
	:is(.asr-site, .asr-scope, .asr-trial) .asr-headlight-sweep--before:is(:hover, :focus-visible, :focus-within):not(.asr-reduce-motion *)::before {
		animation: asr-sweep var(--asr-dur-sweep) var(--asr-ease-throttle) 1 both;
	}
}
@keyframes asr-sweep {
	0% { opacity: 1; background-position: 100% 0; }
	85% { opacity: 1; }
	100% { opacity: 0; background-position: 0% 0; }
}
/* Reduced motion: nessuno sweep, il bordo passa a --asr-color-border-strong */
@media (prefers-reduced-motion: reduce) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-headlight-sweep:is(:hover, :focus-visible) { border-color: var(--asr-color-border-strong, #6B7177); }
}
.asr-reduce-motion .asr-headlight-sweep:is(:hover, :focus-visible) { border-color: var(--asr-color-border-strong, #6B7177); }

/* ------------------------------------------------------------------ */
/* 4. Illustrazioni (tavole vehicles.svg inline) – classi del team icone  */
/* ------------------------------------------------------------------ */
/* Struttura attesa (DESIGN-V3 §2.3–2.4):
   <svg class="asr-ill" …> .asr-ill__body (contorno, pathLength="1") · .asr-ill__line (secondarie)
   .asr-ill__wheel (gruppo ruota) · .asr-ill__drl · .asr-ill__tail · .asr-ill__shadow · .asr-ill__lane · .asr-ill__reflector
   .asr-ill__beam (cono di luce) · .asr-ill__needle (cruscotto) */
:is(.asr-site, .asr-scope, .asr-trial) .asr-ill { overflow: visible; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-ill :is(.asr-ill__body, .asr-ill__line, .asr-ill__lane) { vector-effect: non-scaling-stroke; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-ill :is(.asr-ill__wheel, .asr-ill__needle, .asr-ill__shadow) {
	transform-box: fill-box;
	transform-origin: center;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-ill .asr-ill__needle { transform-origin: 50% 100%; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-ill .asr-ill__drl { opacity: 1; }

/* M7 (fallback CSS) – Veicolo che entra all'hover/focus della card: la tavola trasla, il DRL si accende,
   l'ombra si allarga. Con GSAP le ruote fanno anche un giro (asr-motion.js). Stato di riposo: DRL a .4. */
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *) .asr-ill {
		transition: transform var(--asr-dur-drive) var(--asr-ease-brake);
	}
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *) .asr-ill .asr-ill__drl {
		opacity: 0.4;
		transition: opacity 300ms var(--asr-ease-drive) 0ms;
	}
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *) .asr-ill .asr-ill__shadow {
		transform: scaleX(0.85);
		transition: transform var(--asr-dur-drive) var(--asr-ease-brake);
	}
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *):not(.is-gsap-drive) .asr-ill { transform: translateX(-12px); }
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *):not(.is-gsap-drive):is(:hover, :focus-within) .asr-ill { transform: none; }
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *):is(:hover, :focus-within) .asr-ill .asr-ill__drl { opacity: 1; transition-delay: 400ms; }
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-drive]:not(.asr-reduce-motion *):is(:hover, :focus-within) .asr-ill .asr-ill__shadow { transform: none; }
}

/* M2 – Corsia CSS: la mezzeria dell'illustrazione I6 scorre (stroke-dashoffset 0 → −48). */
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .is-inview .asr-ill__lane:not(.asr-reduce-motion *),
	:is(.asr-site, .asr-scope, .asr-trial) .asr-ill.is-inview .asr-ill__lane:not(.asr-reduce-motion *) {
		animation: asr-lane-dash var(--asr-lane-speed) linear infinite;
	}
}
@keyframes asr-lane-dash { to { stroke-dashoffset: -48; } }

/* ------------------------------------------------------------------ */
/* 5. M2 – .asr-roadline: mezzeria che scorre (decorativa)              */
/* ------------------------------------------------------------------ */
/* <span class="asr-roadline" aria-hidden="true"></span>  (orizzontale, 2 px)
   <span class="asr-roadline asr-roadline--v" aria-hidden="true"></span>  (verticale)
   Il tratteggio è un livello interno più lungo di un periodo (48 px) che trasla: solo transform. */
:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline {
	--asr-roadline-period: calc(var(--asr-lane-dash, 24px) + var(--asr-lane-gap, 24px));
	position: relative;
	display: block;
	width: 100%;
	height: var(--asr-lane-w, 2px);
	overflow: hidden;
	pointer-events: none;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: calc(-1 * var(--asr-roadline-period));
	right: 0;
	background: var(--asr-amb-lane);
	background-size: var(--asr-roadline-period) 100%;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline--v { width: var(--asr-lane-w, 2px); height: 100%; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline--v::before {
	left: 0;
	right: 0;
	top: calc(-1 * var(--asr-roadline-period));
	bottom: 0;
	background: var(--asr-amb-lane-v);
	background-size: 100% var(--asr-roadline-period);
}
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline.is-inview:not(.asr-reduce-motion *)::before { animation: asr-roadline-x var(--asr-lane-speed) linear infinite; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline--v.is-inview:not(.asr-reduce-motion *)::before { animation-name: asr-roadline-y; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-roadscape.is-inview:not(.asr-reduce-motion *) .asr-roadscape__lane::before { animation: asr-roadscape-lane calc(var(--asr-lane-speed) * 0.75) linear infinite; }
}
@keyframes asr-roadline-x { to { transform: translateX(var(--asr-roadline-period)); } }
@keyframes asr-roadline-y { to { transform: translateY(var(--asr-roadline-period)); } }
@keyframes asr-roadscape-lane { to { transform: translateY(120px); } }

/* Pausa globale dei loop CSS (tab nascosta, pulsante pausa dell'hero, ASRMotion.suspend()) */
html.asr-motion-paused :is(.asr-roadline, .asr-roadscape__lane, .asr-ill__lane, .asr-scroll-cue)::before,
html.asr-motion-paused :is(.asr-ill__lane, .asr-scroll-cue),
[data-asr-loops="paused"] :is(.asr-roadline, .asr-roadscape__lane)::before,
[data-asr-loops="paused"] :is(.asr-ill__lane, .asr-scroll-cue),
[data-asr-loops="paused"].asr-roadline::before { animation-play-state: paused !important; }

/* ------------------------------------------------------------------ */
/* 6. Freccia "scendi" dell'hero: scende di 4 px ogni 2.4 s, si ferma dopo 3 cicli */
/* ------------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-scroll-cue.is-inview:not(.asr-reduce-motion *) > svg {
		animation: asr-cue 2.4s var(--asr-ease-throttle) 1s 3 both;
	}
}
@keyframes asr-cue { 0%, 100% { transform: none; } 40% { transform: translateY(4px); } 60% { transform: translateY(4px); } }

/* ------------------------------------------------------------------ */
/* 7. M14 – Catarifrangenti che si accendono (su .asr-edgeline di asr-ambient.css) */
/* ------------------------------------------------------------------ */
/* Stato iniziale (spenti) solo quando il JS ha preso in carico l'elemento: classe .is-armed. */
:is(.asr-site, .asr-scope, .asr-trial) .asr-edgeline.is-armed::after { transform: scaleY(0); }
:is(.asr-site, .asr-scope, .asr-trial) .asr-edgeline--h.is-armed::after { transform: scaleX(0); }
:is(.asr-site, .asr-scope, .asr-trial) .asr-edgeline.is-armed.is-lit::after {
	transform: none;
	transition: transform var(--asr-reflector-dur, 900ms) steps(var(--asr-reflector-steps, 8), jump-end);
}

/* ------------------------------------------------------------------ */
/* 8. M17 – Linea dell'header allo scroll (.asr-header-line + .is-scrolled) */
/* ------------------------------------------------------------------ */
/* Le barre dell'area allievi/istruttori (sticky) e del sito (fixed) sono già posizionate: non vanno toccate,
   altrimenti position: relative le fa scorrere via con il contenuto (1.5.3). */
:is(.asr-site, .asr-scope, .asr-trial) .asr-header-line:not(.asr-header):not(.asr-site-header) { position: relative; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-header-line::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: var(--asr-brand-petrol-line, #3A8BA6);
	transform: scaleX(0);
	transform-origin: 0 50%;
	pointer-events: none;
	transition: transform 300ms var(--asr-ease-drive);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-header-line.is-scrolled::after { transform: none; }

/* ------------------------------------------------------------------ */
/* 9. M18 – Allarme timer: UN impulso d'opacità (1 → .55 → 1, 600 ms) a 60 s e a 10 s */
/* ------------------------------------------------------------------ */
/* L'app aggiunge .asr-timer-alert (60 s) e poi .asr-timer-alert--final (10 s); il colore resta, l'impulso no. */
:is(.asr-site, .asr-scope, .asr-trial) .asr-timer-alert { color: var(--asr-color-warning, #E8B65A); }
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-timer-alert:not(.asr-reduce-motion *) { animation: asr-pulse-a 600ms var(--asr-ease-throttle) 1; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-timer-alert--final:not(.asr-reduce-motion *) { animation: asr-pulse-b 600ms var(--asr-ease-throttle) 1; }
}
@keyframes asr-pulse-a { 50% { opacity: 0.55; } }
@keyframes asr-pulse-b { 50% { opacity: 0.55; } }

/* ------------------------------------------------------------------ */
/* 10. M16 – Mezzeria di pagina (solo ≥ 1280 px)                        */
/* ------------------------------------------------------------------ */
/* <div class="asr-page-lane" data-asr-page-lane aria-hidden="true"></div> come primo figlio della radice. */
:is(.asr-site, .asr-scope, .asr-trial) .asr-page-lane { display: none; }
@media (min-width: 1280px) and (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-page-lane:not(.asr-reduce-motion *) {
		display: block;
		position: fixed;
		top: -48px;
		bottom: 0;
		left: 24px;
		z-index: 0;
		width: 2px;
		pointer-events: none;
		background: var(--asr-amb-lane-v);
		background-size: 100% 48px;
		opacity: 0.6;
		will-change: transform;
	}
}

/* ------------------------------------------------------------------ */
/* 11. asr-counter (M10) e asr-odometer (M11)                           */
/* ------------------------------------------------------------------ */
/* <span class="asr-counter" data-asr-count="128"><span aria-hidden="true">128</span><span class="asr-sr-only">128</span></span>
   Senza JS il numero finale è già nel DOM. Cifre tabellari (font "ASR Raleway Tabular" se presente). */
:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-counter, .asr-odometer, .asr-gauge__value) {
	font-family: "ASR Raleway Tabular", var(--asr-font-brand, inherit);
	font-variant-numeric: tabular-nums lining-nums;
}
:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-counter, .asr-odometer, .asr-road-progress, .asr-gauge) .asr-sr-only {
	position: absolute !important;
	width: 1px !important;
	height: 1px !important;
	padding: 0 !important;
	margin: -1px !important;
	overflow: hidden !important;
	clip: rect(0 0 0 0) !important;
	white-space: nowrap !important;
	border: 0 !important;
}
/* Contachilometri: ogni cifra è un rullo 0–9 che scorre (costruito da asr-motion.js). */
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer { display: inline-flex; align-items: stretch; line-height: 1; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer__digits { display: inline-flex; gap: 2px; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer--framed .asr-odometer__cell {
	padding: 0.18em 0.12em;
	background: var(--asr-color-bg-deep, #080808);
	border: 1px solid var(--asr-color-border, #2A2E33);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer__cell {
	position: relative;
	display: inline-block;
	box-sizing: content-box;
}
/* finestra del rullo: solo lei ritaglia (la cornice può avere padding senza mostrare le cifre vicine) */
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer__win {
	display: block;
	height: 1em;
	overflow: hidden;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer__reel {
	display: flex;
	flex-direction: column;
	will-change: transform;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-odometer__reel > span { display: block; height: 1em; line-height: 1; text-align: center; }

/* ------------------------------------------------------------------ */
/* 12. asr-gauge – tachimetro SVG 200×140 (M9)                          */
/* ------------------------------------------------------------------ */
/* Markup: vedi docs/v3-motion.md (ASRMotion.build.gauge() lo genera). Lo stato finale è già nel markup. */
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge {
	display: inline-block;
	position: relative;
	width: min(100%, var(--asr-gauge-w, 200px));
	color: var(--asr-color-heading, #FFFFFF);
	line-height: 1;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge > svg { display: block; width: 100%; height: auto; overflow: visible; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__track { fill: none; stroke: var(--asr-color-surface-3, #23272B); stroke-width: 6; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__zone { fill: none; stroke-width: 6; opacity: 0.35; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__zone--danger { stroke: var(--asr-color-danger, #F2A097); }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__zone--warn { stroke: var(--asr-color-warning, #E8B65A); }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__zone--ok { stroke: var(--asr-color-success, #5CC79A); }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__tick { stroke: var(--asr-color-border-strong, #6B7177); stroke-width: 1.5; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__tick--major { stroke-width: 2; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__arc { fill: none; stroke: var(--asr-color-accent, #3A8BA6); stroke-width: 6; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__needle { stroke: var(--asr-color-heading, #FFFFFF); stroke-width: 2; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__pivot { fill: var(--asr-brand-petrol, #014359); stroke: var(--asr-brand-petrol-line, #3A8BA6); stroke-width: 1.5; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__value {
	fill: currentColor;
	font-family: "ASR Raleway Tabular", var(--asr-font-brand, sans-serif);
	font-weight: 800;
	font-size: 40px;
	letter-spacing: 0;
	/* alone del colore della superficie: il numero resta leggibile anche quando la lancetta ci passa sopra */
	paint-order: stroke;
	stroke: var(--asr-gauge-surface, var(--asr-color-surface, #141618));
	stroke-width: 6px;
	stroke-linejoin: round;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__unit { font-size: 16px; font-weight: 700; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__label {
	display: block;
	margin-top: 8px;
	text-align: center;
	font-size: var(--asr-text-label, 13px);
	font-weight: 700;
	letter-spacing: var(--asr-tracking-label, 0.16em);
	text-transform: var(--asr-transform-display, uppercase);
	color: var(--asr-color-text, #E6E6E6);
}
@media (forced-colors: active) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__track { stroke: GrayText; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__zone { display: none; }
	:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-gauge__arc, .asr-gauge__needle, .asr-gauge__tick) { stroke: CanvasText; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__pivot { fill: Canvas; stroke: CanvasText; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-gauge__value { fill: CanvasText; stroke: Canvas; }
}

/* ------------------------------------------------------------------ */
/* 13. asr-traffic-light – semaforo d'esito (M13), sempre aria-hidden   */
/* ------------------------------------------------------------------ */
/* <div class="asr-traffic-light" data-asr-semaphore="go|stop|wait" aria-hidden="true">
     <span class="asr-traffic-light__lamp asr-traffic-light__lamp--red"></span> …--yellow … --green </div>
   Lampada accesa: per lo stato finale ([data-asr-semaphore]) o per la fase in corso ([data-asr-light], JS). */
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light {
	--asr-tl-w: 28px;
	--asr-tl-lamp: 16px;
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: space-between;
	gap: 6px;
	width: var(--asr-tl-w);
	padding: 6px 0;
	background: var(--asr-tl-body, #0B0C0D);
	border: 1px solid var(--asr-color-border, #2A2E33);
	box-sizing: border-box;
}
@media (min-width: 1024px) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not(.asr-traffic-light--sm) { --asr-tl-w: 36px; --asr-tl-lamp: 22px; padding: 7px 0; gap: 8px; }
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light--h { flex-direction: row; width: auto; height: var(--asr-tl-w); padding: 0 6px; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light__lamp {
	display: block;
	width: var(--asr-tl-lamp);
	height: var(--asr-tl-lamp);
	border-radius: 50%; /* unica eccezione al raggio 0 (DESIGN-V2) */
	background: #1B1E21;
	border: 1px solid #2A2E33;
	box-sizing: border-box;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not([data-asr-light])[data-asr-semaphore="stop"] .asr-traffic-light__lamp--red,
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light[data-asr-light="red"] .asr-traffic-light__lamp--red {
	background: var(--asr-color-danger, #F2A097); border-color: var(--asr-color-danger, #F2A097);
	box-shadow: 0 0 24px rgb(242 160 151 / 0.45);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not([data-asr-light])[data-asr-semaphore="wait"] .asr-traffic-light__lamp--yellow,
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light[data-asr-light="yellow"] .asr-traffic-light__lamp--yellow {
	background: var(--asr-color-warning, #E8B65A); border-color: var(--asr-color-warning, #E8B65A);
	box-shadow: 0 0 24px rgb(232 182 90 / 0.45);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not([data-asr-light])[data-asr-semaphore="go"] .asr-traffic-light__lamp--green,
:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light[data-asr-light="green"] .asr-traffic-light__lamp--green {
	background: var(--asr-color-success, #5CC79A); border-color: var(--asr-color-success, #5CC79A);
	box-shadow: 0 0 24px rgb(92 199 154 / 0.45);
}
@media (forced-colors: active) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light__lamp { background: Canvas; border-color: CanvasText; box-shadow: none !important; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not([data-asr-light])[data-asr-semaphore="stop"] .asr-traffic-light__lamp--red,
	:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not([data-asr-light])[data-asr-semaphore="wait"] .asr-traffic-light__lamp--yellow,
	:is(.asr-site, .asr-scope, .asr-trial) .asr-traffic-light:not([data-asr-light])[data-asr-semaphore="go"] .asr-traffic-light__lamp--green { background: CanvasText; }
}

/* ------------------------------------------------------------------ */
/* 14. asr-road-progress – strada di avanzamento (M12)                  */
/* ------------------------------------------------------------------ */
/* <div class="asr-road-progress" role="progressbar" aria-valuemin="0" aria-valuemax="10" aria-valuenow="4"
        aria-valuetext="Domanda 4 di 10" style="--asr-road-p:.4">
     <span class="asr-road-progress__road"><span class="asr-road-progress__done"></span></span>
     <span class="asr-road-progress__track"><span class="asr-road-progress__vehicle" aria-hidden="true">(svg 24)</span></span>
   </div>
   L'avanzamento è SOLO la custom property --asr-road-p (0–1): funziona senza JS; ASRMotion.road() la aggiorna.
   .asr-road-progress--still: nessuna transizione (esame, ripasso). .asr-road-progress--thin: 4 px senza veicolo. */
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress {
	--asr-road-p: 0;
	--asr-road-h: 8px;
	--asr-road-vehicle: 28px;
	position: relative;
	display: block;
	width: 100%;
	height: calc(var(--asr-road-vehicle) + 2px);
	box-sizing: border-box;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__road {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: var(--asr-road-h);
	overflow: hidden;
	background: var(--asr-road-asphalt, #1B1E21);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__road::before {
	/* mezzeria 6/6 px bianco .2 */
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	height: 2px;
	margin-top: -1px;
	background: repeating-linear-gradient(90deg, var(--asr-road-lane, rgb(255 255 255 / 0.2)) 0 6px, transparent 6px 12px);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__done {
	position: absolute;
	inset: 0;
	background: var(--asr-color-accent, #3A8BA6);
	transform: scaleX(var(--asr-road-p));
	transform-origin: 0 50%;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__track {
	position: absolute;
	left: 0;
	bottom: calc(var(--asr-road-h) - 2px);
	width: calc(100% - var(--asr-road-vehicle));
	height: var(--asr-road-vehicle);
	transform: translateX(calc(var(--asr-road-p) * 100%));
	pointer-events: none;
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__vehicle {
	display: block;
	width: var(--asr-road-vehicle);
	height: var(--asr-road-vehicle);
	color: var(--asr-color-heading, #FFFFFF);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__vehicle > svg { display: block; width: 100%; height: 100%; }
/* veicolo di riserva (nessuna icona fornita): una "DRL" #6FB0C6 sul fronte */
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__vehicle:empty {
	height: 3px;
	margin-top: calc(var(--asr-road-vehicle) - 3px);
	background: var(--asr-brand-petrol-light, #6FB0C6);
	width: 14px;
	margin-left: calc(var(--asr-road-vehicle) - 14px);
}
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress--thin { --asr-road-h: 4px; --asr-road-vehicle: 0px; height: 4px; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress--thin .asr-road-progress__track { display: none; }
@media (prefers-reduced-motion: no-preference) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress:not(.asr-road-progress--still):not(.asr-reduce-motion *) :is(.asr-road-progress__done, .asr-road-progress__track) {
		transition: transform 500ms var(--asr-ease-drive);
	}
}
@media (forced-colors: active) {
	:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__road { background: Canvas; border: 1px solid CanvasText; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__done { background: Highlight; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-road-progress__vehicle { color: CanvasText; }
}

/* ------------------------------------------------------------------ */
/* 15. Scena 3D: il poster CSS si ferma quando il canvas lo copre        */
/* ------------------------------------------------------------------ */
:is(.asr-site, .asr-scope, .asr-trial) .asr-scene.is-poster-gone .asr-roadscape__lane::before { animation: none !important; }
:is(.asr-site, .asr-scope, .asr-trial) .asr-scene__canvas { transition: opacity 800ms var(--asr-ease-throttle); }
/* dissolvenza solo all'accensione: poi l'opacità segue lo scroll fotogramma per fotogramma (niente transizioni riavviate a ogni frame) */
:is(.asr-site, .asr-scope, .asr-trial) .asr-scene.is-poster-gone .asr-scene__canvas { transition: none; }

/* Tema chiaro dell'area allievi: asfalto e semaforo restano "oggetti scuri" ma meno pesanti */
.asr-scope[data-asr-theme="light"] { --asr-road-asphalt: #DADAD7; --asr-road-lane: rgb(8 8 8 / 0.35); --asr-tl-body: #1B1E21; }
@media (prefers-color-scheme: light) {
	.asr-scope[data-asr-theme="auto"] { --asr-road-asphalt: #DADAD7; --asr-road-lane: rgb(8 8 8 / 0.35); --asr-tl-body: #1B1E21; }
}

/* ------------------------------------------------------------------ */
/* 16. Reduced motion: stato finale immediato (anche con .asr-reduce-motion) */
/* ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
	:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-roadline, .asr-roadscape__lane)::before,
	:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-ill__lane, .asr-scroll-cue > svg, .asr-timer-alert) { animation: none !important; }
	:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-road-progress__done, .asr-road-progress__track, .asr-header-line)::after,
	:is(.asr-site, .asr-scope, .asr-trial) :is(.asr-road-progress__done, .asr-road-progress__track) { transition: none !important; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-edgeline.is-armed::after { transform: none; }
}
.asr-reduce-motion :is(.asr-roadline, .asr-roadscape__lane)::before,
.asr-reduce-motion :is(.asr-ill__lane, .asr-scroll-cue > svg, .asr-timer-alert) { animation: none !important; }
.asr-reduce-motion :is(.asr-road-progress__done, .asr-road-progress__track),
.asr-reduce-motion .asr-header-line::after { transition: none !important; }
.asr-reduce-motion .asr-edgeline.is-armed::after { transform: none; }

@media print {
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-reveal],
	:is(.asr-site, .asr-scope, .asr-trial) [data-asr-reveal] * { opacity: 1 !important; transform: none !important; }
	:is(.asr-site, .asr-scope, .asr-trial) .asr-page-lane,
	:is(.asr-site, .asr-scope, .asr-trial) .asr-roadline { display: none !important; }
}
