/*
 * @author: Mathieu MARI <contact@mathieumari.com>
 * @date:   2026-09-04
 * @lastModifiedBy: Mathieu MARI <contact@mathieumari.com>
 * @lastModifiedTime: 2026-09-05
 *
 * Page d'accueil : hero, rail secteurs, extensions orbitales, timeline du chantier,
 * les bâtisseurs, formulaire de contact.
 * Shell (header / footer / nav) → css/custom.css (global).
 * Chargé via theme.addCustomCSS dans pages/root.php.
 */


/* ============================================================
   Hero
   ============================================================ */
.hero {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow-x: clip;
}

.hero__stage {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	flex: 0 0 auto;
	min-height: 100svh;
	box-sizing: border-box;
	padding-block:
		max(var(--header-h), env(safe-area-inset-top, 0px))
		clamp(3.5rem, 9vh, 6.5rem);
	isolation: isolate;
	overflow-x: clip;

	/* Échelle typo fluide — base desktop ; paliers viewport ci-dessous */
	--hero-title-min: 1.95rem;
	--hero-title-fluid: 1.05rem + 3.4cqi;
	--hero-title-max: 3.5rem;
	--hero-subtitle-min: .98rem;
	--hero-subtitle-fluid: .86rem + .55cqi;
	--hero-subtitle-max: 1.25rem;
	--hero-lead-min: .94rem;
	--hero-lead-fluid: .84rem + .35cqi;
	--hero-lead-max: 1.1rem;
	--hero-eyebrow-fluid: .58rem + .42cqi;
	--hero-eyebrow-max: .8rem;
	--hero-meta-value-max: .98rem;
}

.hero__bg {
	--hero-grid-fine: 44px;
	--hero-grid-major: 220px;
	--hero-grid-opacity: 1;
	/* Trait de plan : vert très désaturé (presque craie) — un vert brand à faible
	   alpha disparaît sur le noir, alors qu'une craie claire tient la trame. */
	--hero-grid-line: rgb(154 230 178 / .085);
	--hero-grid-line-strong: rgb(174 240 198 / .16);

	/* Palette poussière WebGL (lue par hero-smoke.js).
	   Le haut de rampe est une craie verte, pas un vert néon : une poussière est
	   éclairée, elle n'émet pas. Un point vif saturé la ferait relire comme un gaz. */
	--smoke-low: #091914;
	--smoke-mid: #12643f;
	--smoke-high: #8fd4a3;
	--smoke-alpha: 0.40;

	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
	background:
		radial-gradient(120% 90% at 82% 8%, rgba(23, 182, 47, .20), transparent 55%),
		radial-gradient(90% 70% at 12% 92%, rgba(11, 71, 38, .28), transparent 60%),
		linear-gradient(180deg, #0c0c12 0%, #08080b 60%, #050507 100%);
}

/* Plan d'architecte — trame technique 100 % CSS (zéro requête, zéro dépendance image).
   Papier millimétré fin + réseau porteur tous les 5 carreaux : le fond dit « chantier ». */
.hero__bg::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image:
		linear-gradient(var(--hero-grid-line) 1px, transparent 1px),
		linear-gradient(90deg, var(--hero-grid-line) 1px, transparent 1px),
		linear-gradient(var(--hero-grid-line-strong) 1.5px, transparent 1.5px),
		linear-gradient(90deg, var(--hero-grid-line-strong) 1.5px, transparent 1.5px);
	background-size:
		var(--hero-grid-fine) var(--hero-grid-fine),
		var(--hero-grid-fine) var(--hero-grid-fine),
		var(--hero-grid-major) var(--hero-grid-major),
		var(--hero-grid-major) var(--hero-grid-major);
	background-position: center center;
	opacity: var(--hero-grid-opacity);
	/* La trame s'estompe vers les bords : elle encadre le visuel sans écraser le copy */
	-webkit-mask-image: radial-gradient(ellipse 82% 76% at 62% 42%, #000 0%, rgb(0 0 0 / .55) 52%, transparent 88%);
	mask-image: radial-gradient(ellipse 82% 76% at 62% 42%, #000 0%, rgb(0 0 0 / .55) 52%, transparent 88%);
}

/* Overlays thème : gel vert brand, halo de profondeur, scrim éditorial, vignette cinéma */
.hero__bg::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	background-color: rgb(23 182 47 / .03);
	background-image:
		radial-gradient(ellipse 128% 108% at 50% 38%, transparent 40%, rgb(0 0 0 / .66) 100%),
		linear-gradient(180deg,
			color-mix(in srgb, var(--c-surface) 58%, transparent) 0%,
			transparent 34%,
			color-mix(in srgb, var(--c-bg) 38%, transparent) 58%,
			color-mix(in srgb, var(--c-bg) 88%, black) 100%
		),
		linear-gradient(108deg,
			color-mix(in srgb, var(--c-bg) 94%, var(--c-brand) 6%) 0%,
			color-mix(in srgb, var(--c-bg) 82%, transparent) 30%,
			color-mix(in srgb, var(--c-bg) 44%, transparent) 52%,
			color-mix(in srgb, var(--c-bg) 20%, var(--c-brand) 6%) 74%,
			color-mix(in srgb, var(--c-bg) 48%, var(--c-brand-strong) 10%) 100%
		),
		radial-gradient(ellipse 78% 58% at 6% 90%, rgb(11 71 38 / .34), transparent 64%),
		radial-gradient(ellipse 42% 34% at 70% 20%, rgb(13 138 36 / .20), transparent 70%),
		radial-gradient(ellipse 68% 52% at 84% 10%, rgb(23 182 47 / .26), transparent 66%);
	background-blend-mode: normal, multiply, normal, normal, soft-light, soft-light;
}

/* Poussière WebGL — calque intermédiaire : au-dessus du plan (::before, z 0),
   sous les scrims éditoriaux (::after, z 2) qui protègent la lisibilité du copy */
.hero__bg-smoke {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
	/* Dark : alpha normal → la poussière s'éclaire sur le fond noir */
	mix-blend-mode: normal;
	/* Révélé par le JS après le 1er rendu (anti-flash) */
	opacity: 0;
	transition: opacity 1.2s var(--ease);
}
.hero__bg-smoke.is-ready { opacity: 1; }

/* Light : multiply → la poussière ne peut qu'assombrir (jamais délaver) :
   les paquets denses se posent, le papier reste propre là où l'air est clair */
[data-bs-theme="light"] .hero__bg-smoke {
	mix-blend-mode: multiply;
}

/* Grains en suspension (dust-particles.js) — même calque que la nappe, mais rendus
   à pleine résolution : la nappe WebGL est étirée depuis ~60 %, un grain de 2px y
   perdrait ses bords. Sous les scrims, donc jamais devant le copy. */
.hero__bg-dust {
	--dust-color: #d8f5df;
	--dust-opacity: 0.58;

	position: absolute;
	inset: 0;
	z-index: 1;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
	opacity: 0;
	transition: opacity 1.6s var(--ease);
}
.hero__bg-dust.is-ready { opacity: 1; }

/* Light : craie sombre en multiply, des grains clairs seraient invisibles sur le papier */
[data-bs-theme="light"] .hero__bg-dust {
	--dust-color: #2f6b41;
	--dust-opacity: 0.38;
	mix-blend-mode: multiply;
}

/* Économie de données : on reste sur le fallback CSS pur (le JS n'initialise pas la poussière) */
@media (prefers-reduced-data: reduce) {
	.hero__bg-smoke,
	.hero__bg-dust { display: none; }
}

.hero__inner {
	flex: 0 1 auto;
	display: grid;
	grid-template-columns: minmax(0, 1.22fr) minmax(0, 0.78fr);
	align-items: center;
	gap: clamp(.85rem, 2.2vw, 2.25rem);
	padding-block: 0;
	min-width: 0;
	overflow: visible;
}

.hero__copy {
	container-type: inline-size;
	container-name: hero-copy;
	display: flex;
	flex-direction: column;
	justify-content: center;
	width: 100%;
	min-width: 0;
	max-width: none;
}

/* Kicker éditorial — filet brand + intitulé tracké (signature « magazine ») */
.hero__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .7rem;
	margin-block-end: clamp(.85rem, 1.8cqi, 1.3rem);
	font-size: clamp(.68rem, var(--hero-eyebrow-fluid), var(--hero-eyebrow-max));
	font-weight: 600;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--c-muted);
}
.hero__eyebrow::before {
	content: "";
	flex: none;
	width: clamp(1.6rem, 3.5cqi, 2.6rem);
	height: 2px;
	border-radius: 2px;
	background: var(--c-brand);
}

/* Titre — display serif système (chaleur éditoriale, anti « SaaS généré ») */
.hero__title {
	margin-block-end: clamp(.7rem, 1.4cqi, .95rem);
	font-family: var(--font-display);
	font-weight: 600;
	font-size: clamp(var(--hero-title-min), var(--hero-title-fluid), var(--hero-title-max));
	line-height: 1.08;
	letter-spacing: -.012em;
	text-wrap: balance;
}
/* Mot-clé du concept — italique + trait de surligneur brand (geste manuscrit) */
.hero__title-accent {
	font-style: italic;
	color: inherit;
	background:
		linear-gradient(101deg,
			transparent 1%,
			color-mix(in srgb, var(--c-brand) 30%, transparent) 0 98%,
			transparent 0
		) no-repeat;
	background-size: 100% .16em;
	background-position: 0 92%;
}

.hero__subtitle {
	margin-block-end: clamp(.95rem, 2cqi, 1.35rem);
	max-width: min(42ch, 100%);
	font-size: clamp(var(--hero-subtitle-min), var(--hero-subtitle-fluid), var(--hero-subtitle-max));
	font-weight: 500;
	line-height: 1.42;
	letter-spacing: -.015em;
	color: var(--c-muted);
}
.hero__subtitle strong {
	font-weight: 600;
	color: var(--c-text);
}

/* Repères clés — prix · délai · périmètre. Grille nette : libellés alignés sur une ligne, valeurs sur l'autre */
.hero__meta {
	--meta-gap: clamp(1.4rem, 1rem + 2cqi, 2.6rem);
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	align-self: flex-start;
	max-width: 100%;
	gap: var(--meta-gap);
	margin-block-end: clamp(1.4rem, 2.8cqi, 1.95rem);
}
.hero__meta-item {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: .5rem;
}
/* Filet vertical fin, centré dans la gouttière */
.hero__meta-item:not(:last-child)::after {
	content: "";
	position: absolute;
	inset-block: .05rem;
	inset-inline-end: calc(var(--meta-gap) / -2);
	width: 1px;
	background: var(--c-border);
}
.hero__meta-label {
	font-size: .66rem;
	font-weight: 600;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--c-faint);
	line-height: 1;
}
.hero__meta-value {
	display: inline-flex;
	align-items: baseline;
	gap: .3em;
	font-size: clamp(1.05rem, .92rem + .5cqi, 1.32rem);
	font-weight: 700;
	letter-spacing: -.02em;
	line-height: 1;
	color: var(--c-text);
	font-variant-numeric: tabular-nums;
}
/* Prix — distingué par la couleur + la graisse, MÊME taille → alignement parfait */
.hero__meta-item--accent .hero__meta-value {
	font-weight: 800;
	color: var(--c-brand);
}

.hero__lead {
	max-width: min(58ch, 100%);
	margin-block-end: clamp(1.35rem, 3cqi, 2.25rem);
	font-size: clamp(var(--hero-lead-min), var(--hero-lead-fluid), var(--hero-lead-max));
	line-height: 1.55;
	color: var(--c-muted);
}

/* Métaphore chantier — surlignage « crayon de chantier » (geste humain, pas une puce UI) */
.hero__build-tag {
	--mark: color-mix(in srgb, var(--c-brand) 32%, transparent);
	display: inline-block;
	padding-inline: .14em;
	font-weight: 600;
	color: var(--c-text);
	white-space: nowrap;
	background:
		linear-gradient(101deg,
			transparent 2%,
			var(--mark) 0 97%,
			transparent 0
		) no-repeat;
	background-size: 100% .62em;
	background-position: 0 78%;
}
/* Léger désalignement alterné = passage de surligneur fait main */
.hero__build-tag:nth-of-type(odd)  { rotate: -.5deg; }
.hero__build-tag:nth-of-type(even) { rotate: .5deg; background-position: 0 74%; }

.hero__actions { display: flex; flex-wrap: wrap; gap: .9rem; }

/* Visuel device — laptop.webp (cadre) + logo SVG affiché DANS l'écran */
.hero__visual {
	--hero-device-size: clamp(340px, 36vw, 600px);
	/* Zone dalle noire mesurée sur laptop.webp (1165x775) */
	--hero-screen-top: 2.1%;
	--hero-screen-left: 9.5%;
	--hero-screen-width: 80.9%;
	--hero-screen-height: 82.9%;
	--hero-orbit-gap: 18%;
	margin: 0;
	justify-self: end;
	width: var(--hero-device-size);
	max-width: 100%;
	min-width: 0;
	overflow: visible;
}
.hero__visual-scene {
	position: relative;
	display: grid;
	place-items: center;
	width: 100%;
	overflow: visible;
	perspective: 1200px;
}
.hero__visual-orbit {
	position: relative;
	width: 100%;
	display: grid;
	place-items: center;
	overflow: visible;
}
.hero__visual-ambient {
	position: absolute;
	inset: calc(var(--hero-orbit-gap) * -1);
	pointer-events: none;
}
.hero__visual-glow {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	width: 88%;
	height: 88%;
	border-radius: 50%;
	background:
		radial-gradient(circle, rgba(23, 182, 47, .38) 0%, rgba(23, 182, 47, .10) 42%, transparent 72%);
	filter: blur(clamp(20px, 4vw, 32px));
	transform: translate(-50%, -50%);
	animation: hero-glow-breathe 5.5s ease-in-out infinite;
}
.hero__visual-float {
	position: relative;
	z-index: 1;
	width: 100%;
	transform-style: preserve-3d;
	animation: hero-logo-levitate 7s ease-in-out infinite;
	will-change: transform;
}
.hero__visual-device {
	position: relative;
	width: 100%;
}
/* Laptop = calque de base (cadre) */
.hero__visual-laptop {
	position: relative;
	z-index: 0;
	display: block;
	width: 100%;
	height: auto;
	pointer-events: none;
	user-select: none;
	filter: drop-shadow(0 26px 48px rgba(0, 0, 0, .5));
}
/* Écran = calque transparent calé pile sur la dalle noire du laptop ;
   on n'ajoute pas de fond opaque (l'écran de l'image est déjà noir), juste un glow + le logo */
.hero__visual-screen {
	position: absolute;
	inset-block-start: var(--hero-screen-top);
	inset-inline-start: var(--hero-screen-left);
	z-index: 1;
	box-sizing: border-box;
	width: var(--hero-screen-width);
	height: var(--hero-screen-height);
	overflow: hidden;
	border-radius: clamp(2px, 1.4%, 12px);
	background: radial-gradient(58% 52% at 50% 48%, rgba(23, 182, 47, .20) 0%, transparent 70%);
}
/* ============================================================
   Maison isométrique — le concept en un seul visuel
   Vue éclatée : dalle, RDC, étage, toiture et cheminée respirent
   niveau par niveau, comme un chantier qui s'assemble.
   Réutilisée dans l'écran du laptop (hero) et dans le hub (extensions).
   ============================================================ */
/* Palette de l'objet — volontairement figée, PAS branchée sur --c-brand-soft :
   ce token s'inverse en thème clair (il sert d'accent typo) et retournerait
   l'ombrage isométrique (dessus plus sombre que les façades). */
.iso-house {
	overflow: visible;
	--iso-top: #4fd166;
	--iso-left: #17b62f;
	--iso-right: #0b7a1f;
	--iso-slab-top: #e6ece7;
	--iso-slab-left: #b0bcb2;
	--iso-slab-right: #8a978c;
}

/* Faces — lumière venant de la gauche : dessus clair, face droite dans l'ombre */
.iso-house .iso-top   { fill: var(--iso-top); }
.iso-house .iso-left  { fill: var(--iso-left); }
.iso-house .iso-right { fill: var(--iso-right); }

/* Pans de toiture — le pan qui regarde la lumière (arrière-gauche) est le plus clair */
.iso-house .iso-roof-far  { fill: var(--iso-top); }
.iso-house .iso-roof-near { fill: color-mix(in srgb, var(--iso-top) 22%, var(--iso-left)); }

/* Dalle de fondation — teinte béton : hors palette brand, elle ancre la construction */
.iso-house .iso-slab-top   { fill: var(--iso-slab-top); }
.iso-house .iso-slab-left  { fill: var(--iso-slab-left); }
.iso-house .iso-slab-right { fill: var(--iso-slab-right); }

/* Percements (porte, fenêtres) — vitrage sombre, lisible à toute taille */
.iso-house .iso-glass {
	fill: #06110a;
	opacity: .5;
}

/* Arêtes du plan — faîtage + rives du pignon, trait « plan d'architecte » */
.iso-house .iso-edge {
	fill: none;
	stroke: color-mix(in srgb, #ffffff 62%, var(--iso-top));
	stroke-width: 5;
	stroke-linecap: round;
	stroke-linejoin: round;
	opacity: .5;
}

/* Niveaux — respiration décalée : la toiture flotte plus haut que la dalle */
.iso-house .iso-part {
	transform-box: fill-box;
	transform-origin: center;
	will-change: transform;
}
.iso-house .iso-part--chimney {
	animation: house-lift-chimney 2.6s cubic-bezier(.45, .05, .55, .95) infinite;
}
.iso-house .iso-part--roof {
	animation: house-lift-roof 2.6s cubic-bezier(.45, .05, .55, .95) infinite;
	animation-delay: -.12s;
}
.iso-house .iso-part--upper {
	animation: house-lift-upper 2.85s cubic-bezier(.45, .05, .55, .95) infinite;
	animation-delay: -.4s;
}
.iso-house .iso-part--ground {
	animation: house-lift-ground 3.05s cubic-bezier(.45, .05, .55, .95) infinite;
	animation-delay: -.65s;
}
.iso-house .iso-part--slab {
	animation: house-lift-slab 3.25s cubic-bezier(.45, .05, .55, .95) infinite;
	animation-delay: -.9s;
}

@keyframes house-lift-chimney {
	0%, 100% { transform: translate3d(0, 0, 0); }
	50% { transform: translate3d(0, -46px, 0); }
}
@keyframes house-lift-roof {
	0%, 100% { transform: translate3d(0, 0, 0); }
	50% { transform: translate3d(0, -38px, 0); }
}
@keyframes house-lift-upper {
	0%, 100% { transform: translate3d(0, 0, 0); }
	50% { transform: translate3d(0, -21px, 0); }
}
@keyframes house-lift-ground {
	0%, 100% { transform: translate3d(0, 0, 0); }
	50% { transform: translate3d(0, -8px, 0); }
}
@keyframes house-lift-slab {
	0%, 100% { transform: translate3d(0, 0, 0); }
	50% { transform: translate3d(0, 5px, 0); }
}

/* Maison centrée en absolu dans la dalle du laptop (containing block défini).
   Dimensionnée par la HAUTEUR : l'écran est plus large que haut, la caler sur la
   largeur ferait dépasser la toiture hors du cadre (overflow:hidden de l'écran). */
.hero__visual-house {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	z-index: 1;
	display: block;
	width: auto;
	height: var(--hero-house-height, 88%);
	transform: translate(-50%, -50%);
	filter:
		drop-shadow(0 0 22px rgba(23, 182, 47, .42))
		drop-shadow(0 8px 18px rgba(0, 0, 0, .5));
}
.hero__visual-shadow {
	position: absolute;
	inset-block-end: calc(var(--hero-orbit-gap) * -0.35);
	inset-inline-start: 50%;
	z-index: 0;
	width: 52%;
	height: 10%;
	border-radius: 50%;
	background: radial-gradient(ellipse, rgba(23, 182, 47, .28) 0%, transparent 72%);
	filter: blur(14px);
	transform: translateX(-50%);
	animation: hero-shadow-pulse 7s ease-in-out infinite;
}

@keyframes hero-logo-levitate {
	0%, 100% {
		transform: translate3d(0, 0, 0) rotateX(0deg) rotateY(0deg);
	}
	35% {
		transform: translate3d(0, -16px, 0) rotateX(3deg) rotateY(-5deg);
	}
	70% {
		transform: translate3d(0, -8px, 0) rotateX(-2deg) rotateY(4deg);
	}
}
@keyframes hero-glow-breathe {
	0%, 100% { opacity: .55; transform: translate(-50%, -50%) scale(1); }
	50% { opacity: .9; transform: translate(-50%, -50%) scale(1.07); }
}
@keyframes hero-shadow-pulse {
	0%, 100% { opacity: .34; transform: translateX(-50%) scaleX(1); }
	35% { opacity: .18; transform: translateX(-50%) scaleX(.82); }
	70% { opacity: .26; transform: translateX(-50%) scaleX(.92); }
}

@media (prefers-reduced-motion: reduce) {
	.hero__visual-float,
	.hero__visual-glow,
	.hero__visual-shadow,
	.iso-house .iso-part { animation: none; }
}

/* ============================================================
   Rail secteurs phares (scroll-snap + drag souris)
   ============================================================ */
.hero__rail {
	--rail-card-w: clamp(13.5rem, 24vw, 16.5rem);
	--rail-media-ratio: 4 / 5;

	position: relative;
	z-index: 1;
	flex: 0 0 auto;
	padding-block: clamp(2.75rem, 6vh, 4.25rem);
	overflow: visible;
	isolation: isolate;
	background: var(--c-bg);
	border-block-start: 1px solid var(--c-border);
}

/* Pont de fusion — conservé dans le DOM pour compat, désactivé (sections empilées) */
.hero__rail-bridge {
	display: none;
}

.container.rail {
	position: relative;
	z-index: 1;
}

.rail__head {
	margin-block-end: clamp(1.75rem, 4vh, 2.75rem);
}

.rail__intro {
	display: flex;
	flex-direction: column;
	gap: clamp(.4rem, .8cqi, .65rem);
	min-width: 0;
	max-width: min(58ch, 100%);
}

.rail__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .65rem;
	font-size: clamp(.72rem, .62rem + .3cqi, .82rem);
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--c-text) 42%, var(--c-muted));
}
.rail__eyebrow::before {
	content: "";
	flex: none;
	width: clamp(1.4rem, 3cqi, 2.25rem);
	height: 2px;
	border-radius: 2px;
	background: var(--c-brand);
}

.rail__title {
	font-family: var(--font-display);
	font-size: clamp(1.65rem, 1.1rem + 1.8cqi, 2.35rem);
	font-weight: 600;
	line-height: 1.1;
	letter-spacing: -.018em;
	text-wrap: balance;
	color: var(--c-text);
}

.rail__lead {
	font-size: clamp(.92rem, .86rem + .25cqi, 1.05rem);
	line-height: 1.55;
	color: var(--c-muted);
	max-width: 52ch;
}

.rail__track-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin-block-end: clamp(1rem, 2.5vh, 1.5rem);
}

.rail__track-label {
	font-size: clamp(.78rem, .72rem + .2cqi, .88rem);
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--c-text) 55%, var(--c-muted));
}

.rail__nav {
	display: flex;
	flex-shrink: 0;
	gap: .5rem;
}
.rail__btn {
	display: inline-grid;
	place-items: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 1px solid var(--c-border);
	border-radius: var(--r-pill);
	background: color-mix(in srgb, var(--c-surface) 88%, transparent);
	color: var(--c-muted);
	font-size: 1.2rem;
	line-height: 1;
	box-shadow: 0 1px 0 color-mix(in srgb, var(--c-text) 6%, transparent) inset;
	/* `manipulation` supprime la détection de double-tap-zoom : sans elle, le
	   navigateur mobile retarde (voire abandonne) le clic sur une cible étroite. */
	touch-action: manipulation;
	-webkit-tap-highlight-color: transparent;
	transition:
		border-color .22s var(--ease),
		color .22s var(--ease),
		background-color .22s var(--ease),
		opacity .22s var(--ease),
		transform .12s var(--ease);
}
.rail__btn:hover:not(:disabled) {
	border-color: color-mix(in srgb, var(--c-brand) 42%, var(--c-border));
	color: var(--c-text);
	background: color-mix(in srgb, var(--c-surface) 92%, var(--c-brand));
}
.rail__btn:focus-visible {
	outline: 2px solid color-mix(in srgb, var(--c-brand) 65%, transparent);
	outline-offset: 3px;
}
.rail__btn:disabled {
	opacity: .38;
	cursor: default;
}
/* Au doigt il n'y a pas de :hover : l'appui est le seul retour visuel. */
.rail__btn:active:not(:disabled) {
	border-color: color-mix(in srgb, var(--c-brand) 55%, var(--c-border));
	color: var(--c-text);
	background: color-mix(in srgb, var(--c-surface) 86%, var(--c-brand));
	transform: scale(.94);
}

/* Pointeur grossier (doigt) : cible de 44px, le minimum tapable. */
@media (pointer: coarse) {
	.rail__nav {
		gap: .65rem;
	}
	.rail__btn {
		width: 44px;
		height: 44px;
		font-size: 1.3rem;
	}
}

.rail__scroller {
	position: relative;
	margin-inline: calc(var(--gutter) * -1);
}

/* Masque droit uniquement — pas d'estompe à gauche : la 1re carte reste parfaitement visible.
   En fin de course, on l'éteint : la dernière carte ne doit jamais être rognée. */
.rail__scroller::after {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-end: 0;
	width: clamp(1.25rem, 3.5vw, 2.75rem);
	z-index: 2;
	pointer-events: none;
	background: linear-gradient(-90deg, var(--c-bg) 35%, transparent);
	opacity: 1;
	transition: opacity .28s var(--ease);
}
.rail.is-at-end .rail__scroller::after {
	opacity: 0;
}

/* Pas de `touch-action: pan-x` : au doigt il interdit aussi le scroll vertical, donc
   la page se bloque dès qu'on pose le doigt sur le rail. Le navigateur arbitre déjà
   swipe horizontal / scroll page selon la direction du geste, et le drag JS ignore
   les pointeurs tactiles. `overflow-y: hidden` (au lieu de `visible`, que la spec
   recalcule en `auto`) évite que le rail capte le geste vertical. */
.rail__track {
	display: flex;
	align-items: stretch;
	gap: clamp(.85rem, 2vw, 1.15rem);
	padding-inline: var(--gutter);
	padding-block: .25rem .85rem;
	overflow-x: auto;
	overflow-y: hidden;
	overscroll-behavior-x: contain;
	scroll-snap-type: x mandatory;
	scroll-padding-inline: var(--gutter);
	scrollbar-width: none;
	cursor: grab;
}
.rail__track::-webkit-scrollbar { display: none; }
.rail__track.is-dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	user-select: none;
}
.rail__track.is-dragging .sector-card__link {
	pointer-events: none;
}
/* Trajet d'une flèche (animation rAF de sector-rail.js) : le snap doit lâcher,
   sinon le navigateur ramène le scroll au point de snap à chaque frame et la
   flèche semble morte (mobile / WebKit). Il reprend à l'arrivée et recale. */
.rail__track.is-animating {
	scroll-snap-type: none;
}

/* --- Carte secteur — illustration + copy en dessous (pas d'overlay) */
.sector-card {
	flex: 0 0 var(--rail-card-w);
	scroll-snap-align: start;
}
.sector-card:last-child {
	scroll-snap-align: end;
}

.sector-card__link {
	--sector-accent: color-mix(in srgb, var(--c-brand) 72%, transparent);

	display: flex;
	flex-direction: column;
	height: 100%;
	border: 1px solid var(--c-border);
	border-radius: calc(var(--r-md) + 2px);
	background: var(--c-surface);
	overflow: hidden;
	transition:
		border-color .28s var(--ease),
		background-color .28s var(--ease),
		box-shadow .28s var(--ease);
}
.sector-card__link:focus-visible {
	outline: 2px solid color-mix(in srgb, var(--c-brand) 65%, transparent);
	outline-offset: 3px;
}
.sector-card__link:hover,
.sector-card__link:focus-visible {
	border-color: color-mix(in srgb, var(--c-brand) 28%, var(--c-border));
	background: color-mix(in srgb, var(--c-surface) 96%, var(--c-brand));
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 10%, transparent),
		0 12px 32px -24px rgb(0 0 0 / .22);
}

/* Zone illustration — trame de plan par défaut, photo posée par-dessus si le secteur en a une */
.sector-card__media {
	position: relative;
	display: block;
	flex: 0 0 auto;
	width: 100%;
	aspect-ratio: var(--rail-media-ratio);
	min-height: clamp(15rem, 36vw, 18.5rem);
	background-color: var(--c-surface-2);
	background-image:
		repeating-linear-gradient(var(--sector-hatch-angle, 135deg),
			var(--c-blueprint-line-strong) 0 1px,
			transparent 1px 12px
		),
		linear-gradient(
			168deg,
			color-mix(in srgb, var(--c-surface-2) 72%, var(--c-text)) 0%,
			var(--c-surface-2) 48%,
			color-mix(in srgb, var(--c-surface-2) 88%, var(--c-bg)) 100%
		);
	background-size: auto, cover;
	background-position: center;
	background-repeat: repeat, no-repeat;
	overflow: hidden;
	isolation: isolate;
	transition: filter .32s var(--ease);
}
.sector-card__link:hover .sector-card__media,
.sector-card__link:focus-visible .sector-card__media {
	filter: brightness(1.03) saturate(1.06);
}

/* Accent fin — filet brand en bas du visuel (pas de scale = pas de rognage) */
.sector-card__media::before {
	content: "";
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	height: 2px;
	background: var(--sector-accent);
	transform: scaleX(0);
	transform-origin: inline-start;
	transition: transform .34s var(--ease);
	pointer-events: none;
	z-index: 1;
}
.sector-card__link:hover .sector-card__media::before,
.sector-card__link:focus-visible .sector-card__media::before {
	transform: scaleX(1);
}

/* Voile léger — attente visuelle sobre avant les vraies images */
.sector-card__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		linear-gradient(180deg, rgb(255 255 255 / .04) 0%, transparent 42%),
		linear-gradient(0deg, rgb(0 0 0 / .12) 0%, transparent 38%);
	opacity: 1;
	transition: opacity .32s var(--ease);
	pointer-events: none;
}
.sector-card__link:hover .sector-card__media::after,
.sector-card__link:focus-visible .sector-card__media::after {
	opacity: .55;
}

/* Pictogramme de secteur — trait de plan, posé sur la trame ; tient lieu de visuel
   tant que le secteur n'a pas de photo. Avec photo, il se replie en pastille (plus bas). */
.sector-card__icon {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-start: 50%;
	z-index: 1;
	width: 42%;
	height: auto;
	color: color-mix(in srgb, var(--c-brand) 62%, var(--c-text));
	opacity: .5;
	transform: translate(-50%, -50%);
	transition: opacity .32s var(--ease), transform .32s var(--ease);
}
.sector-card__link:hover .sector-card__icon,
.sector-card__link:focus-visible .sector-card__icon {
	opacity: .78;
	transform: translate(-50%, -50%) scale(1.05);
}

/* --- Photo de secteur — recouvre la trame ; srcset injecté par Maestra (worker responsive_images) */
.sector-card__photo {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .5s var(--ease);
}
/* Photo paysage dans une carte 4/5 : on garde les visages en haut, pas le sol */
.sector-card__photo[data-fit="wide"] {
	object-position: center 28%;
}
/* Sujet à droite (réception, cabine d'essayage) : le cover 4/5 rogne les côtés */
.sector-card__photo[data-fit="end"] {
	object-position: 78% 24%;
}
.sector-card__link:hover .sector-card__photo,
.sector-card__link:focus-visible .sector-card__photo {
	transform: scale(1.045);
}

/* Avec photo, le pictogramme se replie en pastille : la carte reste signée sans
   masquer l'image. Fond opaque propre = lisible quel que soit le cliché. */
.sector-card__media:has(.sector-card__photo) .sector-card__icon {
	inset-block-start: auto;
	inset-block-end: .7rem;
	inset-inline-start: .7rem;
	width: 2.15rem;
	height: 2.15rem;
	padding: .48rem;
	border: 1px solid color-mix(in srgb, var(--c-brand) 26%, transparent);
	border-radius: var(--r-pill);
	background: color-mix(in srgb, var(--c-surface) 82%, transparent);
	backdrop-filter: blur(8px);
	color: var(--c-brand);
	opacity: 1;
	transform: none;
}
.sector-card__link:hover .sector-card__media:has(.sector-card__photo) .sector-card__icon,
.sector-card__link:focus-visible .sector-card__media:has(.sector-card__photo) .sector-card__icon {
	border-color: color-mix(in srgb, var(--c-brand) 55%, transparent);
	background: color-mix(in srgb, var(--c-surface) 94%, transparent);
	opacity: 1;
	transform: none;
}

/* Trame de plan dans le visuel — l'angle des hachures change par secteur :
   chaque carte a sa signature sans réclamer d'image. */
.sector-card__media[data-variant] {
	--sector-hatch-angle: 135deg;
}
.sector-card__media[data-variant="2"] { --sector-hatch-angle: 45deg; }
.sector-card__media[data-variant="3"] { --sector-hatch-angle: 90deg; }
.sector-card__media[data-variant="4"] { --sector-hatch-angle: 160deg; }
.sector-card__media[data-variant="5"] { --sector-hatch-angle: 20deg; }
.sector-card__media[data-variant="6"] { --sector-hatch-angle: 0deg; }
.sector-card__media[data-variant="7"] { --sector-hatch-angle: 70deg; }
.sector-card__media[data-variant="8"] { --sector-hatch-angle: 110deg; }
.sector-card__media[data-variant="9"] { --sector-hatch-angle: 200deg; }
.sector-card__media[data-variant="10"] { --sector-hatch-angle: 150deg; }

.sector-card__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	justify-content: center;
	gap: .35rem;
	min-height: 5.25rem;
	padding: 1rem 1.05rem 1.1rem;
}

.sector-card__name {
	font-size: clamp(.98rem, .9rem + .25cqi, 1.08rem);
	font-weight: 600;
	line-height: 1.25;
	letter-spacing: -.01em;
	color: var(--c-text);
	transition: color .28s var(--ease);
}
.sector-card__link:hover .sector-card__name,
.sector-card__link:focus-visible .sector-card__name {
	color: color-mix(in srgb, var(--c-brand) 18%, var(--c-text));
}

.sector-card__desc {
	font-size: clamp(.8rem, .76rem + .15cqi, .88rem);
	line-height: 1.45;
	color: var(--c-muted);
	transition: color .28s var(--ease);
}
.sector-card__link:hover .sector-card__desc,
.sector-card__link:focus-visible .sector-card__desc {
	color: color-mix(in srgb, var(--c-text) 42%, var(--c-muted));
}

/* ============================================================
   Catégories phares — duo de gros blocs (au-dessus du rail)
   Signature « angle » : coin net asymétrique + média en diagonale,
   les deux blocs en composition miroir.
   ============================================================ */
.feature-duo {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(.9rem, 1.8vw, 1.4rem);
	margin-block-end: clamp(2.25rem, 5vh, 3.25rem);
}

.feature-block { display: flex; }

.feature-block__link {
	--fb-radius: clamp(18px, 1.4vw + 14px, 26px);
	--fb-media-w: clamp(7rem, 26%, 10.5rem);

	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr) var(--fb-media-w);
	width: 100%;
	height: 100%;
	border: 1px solid var(--c-border);
	/* Coin net en bas-gauche : la rupture d'angle volontaire */
	border-radius: var(--fb-radius) var(--fb-radius) var(--fb-radius) 6px;
	background: var(--c-surface);
	overflow: hidden;
	isolation: isolate;
	transition:
		border-color .3s var(--ease),
		box-shadow .3s var(--ease),
		transform .3s var(--ease);
}
/* Bloc 2 — miroir : média à gauche, coin net en bas-droite */
.feature-block--alt .feature-block__link {
	grid-template-columns: var(--fb-media-w) minmax(0, 1fr);
	border-radius: var(--fb-radius) var(--fb-radius) 6px var(--fb-radius);
}

.feature-block__link:hover,
.feature-block__link:focus-visible {
	transform: translateY(-3px);
	border-color: color-mix(in srgb, var(--c-brand) 34%, var(--c-border));
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 12%, transparent),
		0 26px 50px -34px rgb(0 0 0 / .5);
}
.feature-block__link:focus-visible {
	outline: 2px solid color-mix(in srgb, var(--c-brand) 65%, transparent);
	outline-offset: 3px;
}

/* --- Contenu */
.feature-block__content {
	order: 1;
	display: flex;
	flex-direction: column;
	gap: .65rem;
	padding: clamp(1.25rem, 2.2vw, 1.9rem);
}
.feature-block--alt .feature-block__content { order: 2; }

.feature-block__topline {
	display: flex;
	align-items: center;
	gap: .6rem;
}
.feature-block__index {
	font-size: .82rem;
	font-weight: 800;
	letter-spacing: .04em;
	color: var(--c-brand);
	font-variant-numeric: tabular-nums;
}
.feature-block__eyebrow {
	font-size: .7rem;
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--c-muted);
}

.feature-block__title {
	font-size: clamp(1.5rem, 1rem + 1.8vw, 2.15rem);
	font-weight: 800;
	line-height: 1.08;
	letter-spacing: -.025em;
	color: var(--c-text);
}

.feature-block__desc {
	font-size: clamp(.9rem, .86rem + .2vw, 1rem);
	line-height: 1.5;
	color: var(--c-muted);
	max-width: 42ch;
}

/* Lots du chantier (métaphore construction) */
.feature-block__tags {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
	margin-block-start: .1rem;
}
.feature-block__tag {
	display: inline-flex;
	align-items: center;
	padding: .32rem .7rem;
	font-size: .76rem;
	font-weight: 600;
	line-height: 1;
	color: var(--c-text);
	background: var(--c-mark-bg);
	border: 1px solid var(--c-mark-border);
	border-radius: var(--r-pill);
}

.feature-block__cta {
	display: inline-flex;
	align-items: center;
	gap: .45rem;
	margin-block-start: auto;
	padding-block-start: .9rem;
	font-size: .9rem;
	font-weight: 700;
	color: var(--c-text);
	transition: color .25s var(--ease);
}
.feature-block__cta svg {
	width: 1.1em;
	height: 1.1em;
	transition: transform .3s var(--ease);
}
.feature-block__link:hover .feature-block__cta,
.feature-block__link:focus-visible .feature-block__cta { color: var(--c-brand); }
.feature-block__link:hover .feature-block__cta svg,
.feature-block__link:focus-visible .feature-block__cta svg { transform: translateX(4px); }

/* --- Média : panneau coupé en diagonale = la signature « angle » */
.feature-block__media {
	order: 2;
	position: relative;
	min-height: clamp(9rem, 22vw, 13rem);
	display: grid;
	place-items: center;
	background:
		radial-gradient(120% 120% at 82% 0%, color-mix(in srgb, var(--c-brand) 20%, transparent), transparent 60%),
		linear-gradient(155deg,
			color-mix(in srgb, var(--c-surface-2) 70%, var(--c-text)) 0%,
			var(--c-surface-2) 55%,
			color-mix(in srgb, var(--c-surface-2) 86%, var(--c-bg)) 100%
		);
	clip-path: polygon(16% 0, 100% 0, 100% 100%, 0 100%);
}
.feature-block--alt .feature-block__media {
	order: 1;
	background:
		radial-gradient(120% 120% at 18% 0%, color-mix(in srgb, var(--c-brand) 20%, transparent), transparent 60%),
		linear-gradient(205deg,
			color-mix(in srgb, var(--c-surface-2) 70%, var(--c-text)) 0%,
			var(--c-surface-2) 55%,
			color-mix(in srgb, var(--c-surface-2) 86%, var(--c-bg)) 100%
		);
	clip-path: polygon(0 0, 84% 0, 100% 100%, 0 100%);
}

.feature-block__icon {
	width: clamp(2.75rem, 7vw, 4rem);
	height: clamp(2.75rem, 7vw, 4rem);
	color: color-mix(in srgb, var(--c-brand) 78%, var(--c-text));
	transition: transform .4s var(--ease);
}
.feature-block__link:hover .feature-block__icon,
.feature-block__link:focus-visible .feature-block__icon {
	transform: scale(1.08) rotate(-2deg);
}

/* --- Photo du chantier — remplit le panneau diagonal ; srcset injecté par Maestra */
.feature-block__photo {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .45s var(--ease);
}
.feature-block__link:hover .feature-block__photo,
.feature-block__link:focus-visible .feature-block__photo {
	transform: scale(1.05);
}

/* Voile léger, recette identique aux cartes du rail (.sector-card__media::after) :
   un lustre blanc en haut, un socle sombre discret sous la pastille. Assez pour
   asseoir la photo dans la carte, trop léger pour l'assombrir. */
.feature-block__media:has(.feature-block__photo)::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background:
		linear-gradient(180deg, rgb(255 255 255 / .04) 0%, transparent 42%),
		linear-gradient(0deg, rgb(0 0 0 / .12) 0%, transparent 38%);
	pointer-events: none;
	transition: opacity .32s var(--ease);
}
.feature-block__link:hover .feature-block__media:has(.feature-block__photo)::after,
.feature-block__link:focus-visible .feature-block__media:has(.feature-block__photo)::after {
	opacity: .55;
}

/* Pictogramme en pastille basse — même langage que les cartes du rail, et il
   ne se pose plus sur un visage comme le faisait la version centrée. */
.feature-block__media:has(.feature-block__photo) {
	align-items: end;
	padding-block-end: .9rem;
}
.feature-block__media:has(.feature-block__photo) .feature-block__icon {
	position: relative;
	z-index: 1;
	width: 2.35rem;
	height: 2.35rem;
	padding: .52rem;
	border: 1px solid color-mix(in srgb, var(--c-brand) 30%, transparent);
	border-radius: var(--r-pill);
	background: color-mix(in srgb, var(--c-surface) 82%, transparent);
	backdrop-filter: blur(8px);
	color: var(--c-brand);
}

/* Duo → 1 colonne sur tablette */
@media (max-width: 980px) {
	.feature-duo { grid-template-columns: 1fr; }
}
/* Blocs empilés (média au-dessus) sur petit écran : on neutralise la diagonale */
@media (max-width: 560px) {
	.feature-block__link,
	.feature-block--alt .feature-block__link { grid-template-columns: 1fr; }
	.feature-block__media,
	.feature-block--alt .feature-block__media {
		order: 0;
		min-height: 7.5rem;
		clip-path: polygon(0 0, 100% 0, 100% 88%, 0 100%);
	}
	/* Avec photo, 7,5rem sur toute la largeur ne laisserait qu'une tranche du cliché */
	.feature-block__media:has(.feature-block__photo),
	.feature-block--alt .feature-block__media:has(.feature-block__photo) {
		min-height: 11.5rem;
	}
	.feature-block__content,
	.feature-block--alt .feature-block__content { order: 1; }
}

/* Thème clair — ombres adoucies */
[data-bs-theme="light"] .feature-block__link {
	box-shadow: 0 12px 30px -24px rgb(12 12 18 / .12);
}
[data-bs-theme="light"] .feature-block__link:hover,
[data-bs-theme="light"] .feature-block__link:focus-visible {
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 9%, transparent),
		0 22px 44px -30px rgb(12 12 18 / .2);
}

/* Thème clair — lustre blanc appuyé, socle sombre encore plus discret : mêmes
   valeurs que [data-bs-theme="light"] .sector-card__media::after */
[data-bs-theme="light"] .feature-block__media:has(.feature-block__photo)::after {
	background:
		linear-gradient(180deg, rgb(255 255 255 / .28) 0%, transparent 42%),
		linear-gradient(0deg, rgb(12 12 18 / .06) 0%, transparent 38%);
}

/* ============================================================
   Extensions — écosystème orbital
   ============================================================ */
.modules {
	position: relative;
	isolation: isolate;
	padding-block: clamp(3.25rem, 7vh, 5rem);
	background: var(--c-bg);
	border-block-start: 1px solid var(--c-border);
	overflow-x: clip;
}

.modules__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 4.5vh, 3rem);
}

.modules__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: clamp(.45rem, 1cqi, .75rem);
	max-width: min(62ch, 100%);
	margin-inline: auto;
}

.modules__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .65rem;
	font-size: clamp(.72rem, .62rem + .3cqi, .82rem);
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--c-brand);
}
.modules__eyebrow::before,
.modules__eyebrow::after {
	content: "";
	flex: none;
	width: clamp(1rem, 2.5cqi, 1.75rem);
	height: 1px;
	background: color-mix(in srgb, var(--c-brand) 55%, transparent);
}

.modules__title {
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 1.15rem + 2cqi, 2.65rem);
	font-weight: 600;
	line-height: 1.08;
	letter-spacing: -.02em;
	text-wrap: balance;
	color: var(--c-text);
}

.modules__lead {
	font-size: clamp(.94rem, .88rem + .25cqi, 1.08rem);
	line-height: 1.58;
	color: var(--c-muted);
	max-width: 54ch;
}
.modules__lead strong { color: var(--c-text); font-weight: 700; }

.modules__tag {
	display: inline-block;
	padding-inline: .12em;
	font-weight: 600;
	color: var(--c-text);
	background: linear-gradient(180deg, transparent 62%, var(--c-mark-bg) 62%);
}

/* --- Scène orbitale */
.modules__stage {
	position: relative;
	width: 100%;
}

/* --- Poussière WebGL — full-bleed, masque radial = le plan de masse repousse la brume (même moteur que le hero) */
.modules__smoke {
	--smoke-hole: 23.5rem;
	/* Palette poussière WebGL (lue par hero-smoke.js) — alignée sur le hero */
	--smoke-low: #091914;
	--smoke-mid: #12643f;
	--smoke-high: #8fd4a3;
	--smoke-alpha: 0.36;

	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 0;
	width: 100vw;
	height: min(48rem, 160%);
	transform: translate(-50%, -50%);
	pointer-events: none;
	overflow: hidden;
	/* Fallback CSS pur si WebGL indisponible ou prefers-reduced-data */
	background:
		radial-gradient(closest-side at 0% 50%, rgb(23 182 47 / .14), transparent 68%),
		radial-gradient(closest-side at 100% 50%, rgb(23 182 47 / .14), transparent 68%),
		radial-gradient(closest-side at 0% 38%, rgb(20 110 55 / .1), transparent 62%),
		radial-gradient(closest-side at 100% 62%, rgb(20 110 55 / .1), transparent 62%);
	-webkit-mask-image:
		radial-gradient(circle var(--smoke-hole) at 50% 50%,
			transparent 0,
			transparent 84%,
			rgb(0 0 0 / .5) 93%,
			#000 100%);
	mask-image:
		radial-gradient(circle var(--smoke-hole) at 50% 50%,
			transparent 0,
			transparent 84%,
			rgb(0 0 0 / .5) 93%,
			#000 100%);
}

.modules__smoke-canvas {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
	mix-blend-mode: normal;
	opacity: 0;
	transition: opacity 1.2s var(--ease);
}
.modules__smoke-canvas.is-ready { opacity: 1; }

[data-bs-theme="light"] .modules__smoke-canvas {
	mix-blend-mode: multiply;
}

@media (prefers-reduced-data: reduce) {
	.modules__smoke-canvas { display: none; }
}

.modules__galaxy {
	--modules-orbit-inner: clamp(7.5rem, 22vw, 10.75rem);
	--modules-orbit-outer: clamp(11.5rem, 34vw, 16.25rem);
	--modules-hub-size: clamp(6.5rem, 16vw, 8.75rem);
	--modules-galaxy-opacity: .62;

	position: relative;
	z-index: 1;
	width: min(100%, 42rem);
	aspect-ratio: 1;
	margin-inline: auto;
	isolation: isolate;
}

/* Plan de masse — trame polaire dans le rond, fondu radial 360° (100 % CSS) */
.modules__galaxy-media {
	position: absolute;
	inset: 0;
	z-index: 0;
	border-radius: 50%;
	overflow: hidden;
	pointer-events: none;
}

.modules__galaxy-media::before {
	content: "";
	position: absolute;
	inset: 0;
	/* Courbes de niveau + papier millimétré : lecture « plan de masse » du terrain à bâtir */
	background-image:
		repeating-radial-gradient(circle at 50% 50%,
			var(--c-blueprint-line-strong) 0 1px,
			transparent 1px 36px
		),
		linear-gradient(var(--c-blueprint-line) 1px, transparent 1px),
		linear-gradient(90deg, var(--c-blueprint-line) 1px, transparent 1px);
	background-size:
		auto,
		36px 36px,
		36px 36px;
	background-position: center center;
	opacity: var(--modules-galaxy-opacity);
	-webkit-mask-image:
		radial-gradient(circle at 50% 50%,
			#000 0%,
			#000 58%,
			rgb(0 0 0 / .78) 72%,
			rgb(0 0 0 / .38) 86%,
			transparent 100%);
	mask-image:
		radial-gradient(circle at 50% 50%,
			#000 0%,
			#000 58%,
			rgb(0 0 0 / .78) 72%,
			rgb(0 0 0 / .38) 86%,
			transparent 100%);
}

/* Vignette — fusion du rond dans le fond de section */
.modules__galaxy-media::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 50%;
	pointer-events: none;
	background:
		radial-gradient(circle at 50% 50%,
			transparent 42%,
			color-mix(in srgb, var(--c-bg) 22%, transparent) 72%,
			var(--c-bg) 100%
		),
		radial-gradient(circle at 50% 50%, rgb(23 182 47 / .1), transparent 58%);
}

.modules__rings {
	position: absolute;
	inset: 0;
	z-index: 1;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.modules__ring {
	stroke: color-mix(in srgb, var(--c-text) 14%, transparent);
	stroke-width: 1;
	fill: none;
}
.modules__spoke {
	stroke: color-mix(in srgb, var(--c-text) 7%, transparent);
	stroke-width: 1;
	stroke-dasharray: 3 7;
}
.modules__dot {
	fill: var(--c-brand);
	opacity: .75;
}

/* --- Hub central */
.modules__hub {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	z-index: 3;
	pointer-events: none;
}

.modules__hub-glow {
	position: absolute;
	width: calc(var(--modules-hub-size) * 1.65);
	height: calc(var(--modules-hub-size) * 1.65);
	border-radius: 50%;
	background: radial-gradient(circle, color-mix(in srgb, var(--c-brand) 22%, transparent) 0%, transparent 68%);
	filter: blur(10px);
	animation: modules-hub-glow 6s ease-in-out infinite;
}

.modules__hub-core {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: .2rem;
	width: var(--modules-hub-size);
	height: var(--modules-hub-size);
	padding: .85rem;
	border-radius: 50%;
	background: color-mix(in srgb, var(--c-surface) 78%, transparent);
	border: 1px solid color-mix(in srgb, var(--c-text) 12%, var(--c-border));
	backdrop-filter: blur(14px) saturate(145%);
	-webkit-backdrop-filter: blur(14px) saturate(145%);
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 8%, transparent),
		0 18px 42px -28px rgb(0 0 0 / .55),
		0 1px 0 color-mix(in srgb, var(--c-text) 8%, transparent) inset;
}

/* Hub — la même maison, en miniature : c'est bien le socle qu'on agrandit */
.modules__hub-house {
	/* Calée sur la hauteur : le viewBox de la maison est plus haut que large */
	width: auto;
	height: clamp(2.9rem, 7vw, 3.7rem);
	filter: drop-shadow(0 4px 10px rgba(23, 182, 47, .28));
}
/* Rythme plus lent que dans le hero : le hub est un repère, pas le sujet */
.modules__hub-house .iso-part--chimney { animation-duration: 3.6s; }
.modules__hub-house .iso-part--roof    { animation-duration: 3.6s; }
.modules__hub-house .iso-part--upper   { animation-duration: 3.85s; }
.modules__hub-house .iso-part--ground  { animation-duration: 4.05s; }
.modules__hub-house .iso-part--slab    { animation-duration: 4.25s; }

.modules__hub-name {
	font-size: clamp(.62rem, .55rem + .25cqi, .74rem);
	font-weight: 600;
	line-height: 1.1;
	letter-spacing: -.01em;
	color: var(--c-text);
	text-align: center;
}
.modules__hub-name strong { color: var(--c-brand); font-weight: 800; }

.modules__hub-kicker {
	font-size: .58rem;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--c-muted);
}

/* --- Orbites & planètes */
.modules__orbit {
	position: absolute;
	inset: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	pointer-events: none;
}

.modules__orbit--inner { z-index: 2; }
.modules__orbit--outer { z-index: 1; }

.modules__planet,
.modules__sat {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 0;
	height: 0;
	--angle: 0deg;
	--radius: var(--modules-orbit-inner);
	transform: rotate(var(--angle)) translateX(var(--radius)) rotate(calc(-1 * var(--angle)));
}
.modules__sat {
	--radius: var(--modules-orbit-outer);
}

.modules__planet-card,
.modules__sat-icon {
	animation: modules-orbit-float 7s ease-in-out infinite;
}
.modules__sat-icon { animation-duration: 8.5s; }

.modules__planet:nth-child(1) .modules__planet-card { animation-delay: 0s; }
.modules__planet:nth-child(2) .modules__planet-card { animation-delay: -.6s; }
.modules__planet:nth-child(3) .modules__planet-card { animation-delay: -1.2s; }
.modules__planet:nth-child(4) .modules__planet-card { animation-delay: -1.8s; }
.modules__planet:nth-child(5) .modules__planet-card { animation-delay: -2.4s; }
.modules__planet:nth-child(6) .modules__planet-card { animation-delay: -3s; }

.modules__sat:nth-child(1) .modules__sat-icon { animation-delay: -.3s; }
.modules__sat:nth-child(2) .modules__sat-icon { animation-delay: -.9s; }
.modules__sat:nth-child(3) .modules__sat-icon { animation-delay: -1.5s; }
.modules__sat:nth-child(4) .modules__sat-icon { animation-delay: -2.1s; }
.modules__sat:nth-child(5) .modules__sat-icon { animation-delay: -2.7s; }
.modules__sat:nth-child(6) .modules__sat-icon { animation-delay: -3.3s; }

.modules__planet-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: .12rem;
	width: clamp(4.75rem, 12vw, 6.25rem);
	padding: .55rem .45rem .5rem;
	text-align: center;
	border-radius: var(--r-md);
	background: color-mix(in srgb, var(--c-surface) 76%, transparent);
	border: 1px solid color-mix(in srgb, var(--c-border) 88%, var(--c-text));
	backdrop-filter: blur(10px) saturate(140%);
	-webkit-backdrop-filter: blur(10px) saturate(140%);
	box-shadow:
		0 10px 28px -22px rgb(0 0 0 / .45),
		0 1px 0 color-mix(in srgb, var(--c-text) 6%, transparent) inset;
	transform: translate(-50%, -50%);
	transition:
		border-color .28s var(--ease),
		box-shadow .28s var(--ease);
}

.modules__planet-icon {
	display: grid;
	place-items: center;
	width: 2.15rem;
	height: 2.15rem;
	border-radius: 50%;
	color: var(--c-brand);
	background: var(--c-mark-bg);
	border: 1px solid var(--c-mark-border);
}
.modules__planet-icon svg {
	width: 1.1rem;
	height: 1.1rem;
}

.modules__planet-name {
	font-size: .72rem;
	font-weight: 700;
	line-height: 1.15;
	color: var(--c-text);
}
.modules__planet-desc {
	font-size: .62rem;
	line-height: 1.2;
	color: var(--c-muted);
}

.modules__sat-icon {
	display: grid;
	place-items: center;
	width: 2.35rem;
	height: 2.35rem;
	border-radius: 50%;
	color: color-mix(in srgb, var(--c-text) 72%, var(--c-muted));
	background: color-mix(in srgb, var(--c-surface-2) 72%, transparent);
	border: 1px solid color-mix(in srgb, var(--c-border) 90%, var(--c-text));
	backdrop-filter: blur(8px) saturate(135%);
	-webkit-backdrop-filter: blur(8px) saturate(135%);
	box-shadow: 0 8px 22px -18px rgb(0 0 0 / .4);
	transform: translate(-50%, -50%);
}
.modules__sat-icon svg {
	width: 1rem;
	height: 1rem;
}

@keyframes modules-hub-glow {
	0%, 100% { opacity: .55; transform: scale(1); }
	50% { opacity: .9; transform: scale(1.06); }
}
@keyframes modules-orbit-float {
	0%, 100% { transform: translate(-50%, -50%); }
	50% { transform: translate(-50%, calc(-50% - 5px)); }
}

/* --- Grille mobile (fallback) */
.modules__grid {
	display: none;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: .65rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.modules__chip {
	display: flex;
	align-items: center;
	gap: .65rem;
	padding: .75rem .8rem;
	border: 1px solid color-mix(in srgb, var(--c-border) 90%, var(--c-text));
	border-radius: var(--r-md);
	background: color-mix(in srgb, var(--c-surface) 82%, transparent);
	backdrop-filter: blur(10px) saturate(140%);
	-webkit-backdrop-filter: blur(10px) saturate(140%);
}
.modules__chip--soft {
	background: color-mix(in srgb, var(--c-surface) 92%, var(--c-surface-2));
}

.modules__chip-icon {
	display: grid;
	place-items: center;
	flex: none;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 50%;
	color: var(--c-brand);
	background: var(--c-mark-bg);
	border: 1px solid var(--c-mark-border);
}
.modules__chip-icon svg {
	width: 1.05rem;
	height: 1.05rem;
}

.modules__chip-copy {
	display: flex;
	flex-direction: column;
	gap: .08rem;
	min-width: 0;
}
.modules__chip-copy strong {
	font-size: .82rem;
	font-weight: 700;
	color: var(--c-text);
}
.modules__chip-copy span {
	font-size: .7rem;
	line-height: 1.25;
	color: var(--c-muted);
}

/* --- Pied de section */
.modules__foot {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 1.15rem;
	max-width: min(58ch, 100%);
	margin-inline: auto;
}

.modules__note {
	font-size: clamp(.88rem, .84rem + .2cqi, .98rem);
	line-height: 1.55;
	color: var(--c-muted);
}
.modules__note strong { color: var(--c-text); }

.modules__cta { min-width: min(100%, 16rem); }

/* Responsive — bascule grille / orbite */
@media (max-width: 820px) {
	.modules__galaxy { display: none; }
	.modules__smoke { display: none; }
	.modules__grid { display: grid; }
}

@media (max-width: 480px) {
	.modules__grid { grid-template-columns: 1fr; }
}

/* Poussière light — palette alignée hero (mode multiply sur fond clair) */
[data-bs-theme="light"] .modules__smoke {
	--smoke-low: #eef6ef;
	--smoke-mid: #8fc39c;
	--smoke-high: #3f7d51;
	--smoke-alpha: 0.30;
	background:
		radial-gradient(closest-side at 0% 50%, rgb(23 182 47 / .1), transparent 68%),
		radial-gradient(closest-side at 100% 50%, rgb(23 182 47 / .1), transparent 68%);
}

/* Thème clair — trame du plan de masse adoucie sur papier blanc */
[data-bs-theme="light"] .modules__galaxy {
	--modules-galaxy-opacity: .78;
}

[data-bs-theme="light"] .modules__galaxy-media::after {
	background:
		radial-gradient(circle at 50% 50%,
			transparent 40%,
			rgb(255 255 255 / .35) 72%,
			var(--c-bg) 100%
		),
		radial-gradient(circle at 50% 50%, rgb(23 182 47 / .07), transparent 58%);
}

[data-bs-theme="light"] .modules__ring {
	stroke: color-mix(in srgb, var(--c-text) 18%, transparent);
}
[data-bs-theme="light"] .modules__spoke {
	stroke: color-mix(in srgb, var(--c-text) 10%, transparent);
}

[data-bs-theme="light"] .modules__hub-core {
	background: rgb(255 255 255 / .86);
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 6%, transparent),
		0 20px 44px -30px rgb(12 12 18 / .18);
}
[data-bs-theme="light"] .modules__planet-card,
[data-bs-theme="light"] .modules__chip {
	background: rgb(255 255 255 / .84);
	box-shadow: 0 10px 26px -22px rgb(12 12 18 / .12);
}
[data-bs-theme="light"] .modules__sat-icon {
	background: rgb(255 255 255 / .78);
}

@media (prefers-reduced-motion: reduce) {
	.modules__hub-glow,
	.modules__planet-card,
	.modules__sat-icon,
	.modules__hub-house .iso-part { animation: none; }
}

/* ============================================================
   Comment ça marche — cadran de progression au scroll + étapes
   ============================================================ */
.process {
	position: relative;
	padding-block: clamp(3.5rem, 8vh, 5.5rem);
	background: var(--c-bg);
	border-block-start: 1px solid var(--c-border);
	overflow-x: clip;
	isolation: isolate;
	--draw: 0;
	--pay: 0.5;
	--pay-a: 1;
	--pay-b: 0;
}

/* --- Film du chantier — timelapse dont la tête de lecture suit le scroll (mm_scroll_video) */
.process__film {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	/* [clip] borne le film à la section SANS créer de scroll container : la scène sticky reste
	   calée sur le viewport. [hidden] n'est là que comme repli pour les moteurs qui ignorent [clip]. */
	overflow: hidden;
	overflow: clip;
	/* Le film naît et meurt avec la section : aucune arête franche en entrée / sortie de scroll */
	-webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 82%, transparent 100%);
	mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 82%, transparent 100%);
}

/* Scène plein écran : la vidéo décodée ne fait jamais plus d'un viewport, quelle que soit la hauteur de la section */
.process__film-stage {
	/* Densité du scrim : bande = sous le contenu, veil = sur les côtés, edge = vignette */
	--film-band: 58%;
	--film-veil: 44%;
	--film-edge: 86%;
	position: sticky;
	top: 0;
	height: 100vh;
	isolation: isolate;
}

.process__film-media {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Ce qui casse la lecture d'un texte sur vidéo, ce n'est pas la luminosité, c'est le détail
	   (doigts, clés, calculatrice). Le défocus garde le mouvement et supprime ce détail :
	   le film devient une matière, pas une image concurrente. Le scale masque les bords du flou. */
	opacity: .72;
	filter: blur(3px) saturate(.5) contrast(1.02) brightness(.95);
	transform: scale(1.06);
}

/* Scrim en 3 couches, calé sur le viewport (donc stable pendant tout le scroll de la section) */
.process__film-stage::after {
	content: "";
	position: absolute;
	inset: 0;
	background:
		/* 1. Bande de lecture : dense sous la colonne des étapes, plus ouverte sur les côtés */
		linear-gradient(90deg,
			color-mix(in srgb, var(--c-bg) var(--film-veil), transparent) 0%,
			color-mix(in srgb, var(--c-bg) var(--film-band), transparent) 20%,
			color-mix(in srgb, var(--c-bg) var(--film-band), transparent) 88%,
			color-mix(in srgb, var(--c-bg) var(--film-veil), transparent) 100%),
		/* 2. Vignette : le film s'éteint vers les bords de la scène */
		radial-gradient(ellipse 82% 62% at 50% 45%, transparent 0%, color-mix(in srgb, var(--c-bg) var(--film-edge), transparent) 100%),
		/* 3. Raccord vertical : la scène rejoint le fond de section en haut et en bas */
		linear-gradient(180deg, var(--c-bg) 0%, transparent 20%, transparent 80%, var(--c-bg) 100%);
}

/* Contraste renforcé demandé : le film passe derrière un voile quasi plein */
@media (prefers-contrast: more) {
	.process__film-stage {
		--film-band: 88%;
		--film-veil: 82%;
		--film-edge: 96%;
	}
	.process__film-media { opacity: .5; }
}

@media (prefers-reduced-data: reduce) {
	.process__film { display: none; }
}

/* --- Poussière WebGL — colonnes ascendantes depuis le bas de section */
.process__smoke {
	--smoke-low: #091914;
	--smoke-mid: #12643f;
	--smoke-high: #8fd4a3;
	/* Plus bas que le hero : le banc de poussière se pose sur le film du chantier,
	   il ne doit pas le masquer */
	--smoke-alpha: 0.14;

	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	overflow: hidden;
	/* Fallback CSS pur si WebGL indisponible ou prefers-reduced-data */
	background:
		radial-gradient(ellipse 92% 38% at 50% 100%, rgb(23 182 47 / .24), transparent 70%),
		radial-gradient(ellipse 48% 30% at 24% 98%, rgb(20 110 55 / .16), transparent 64%),
		radial-gradient(ellipse 48% 30% at 76% 98%, rgb(20 110 55 / .16), transparent 64%);
	-webkit-mask-image:
		linear-gradient(to top,
			#000 0%,
			rgb(0 0 0 / .94) 22%,
			rgb(0 0 0 / .62) 52%,
			rgb(0 0 0 / .22) 78%,
			transparent 100%);
	mask-image:
		linear-gradient(to top,
			#000 0%,
			rgb(0 0 0 / .94) 22%,
			rgb(0 0 0 / .62) 52%,
			rgb(0 0 0 / .22) 78%,
			transparent 100%);
}

.process__smoke-canvas {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
	mix-blend-mode: normal;
	opacity: 0;
	transition: opacity 1.4s var(--ease);
}
.process__smoke-canvas.is-ready { opacity: 1; }

@media (prefers-reduced-data: reduce) {
	.process__smoke-canvas { display: none; }
}

.process__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 5vh, 3.25rem);
}

.process__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: clamp(.45rem, 1cqi, .75rem);
	max-width: min(62ch, 100%);
	margin-inline: auto;
}

.process__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .65rem;
	font-size: clamp(.72rem, .62rem + .3cqi, .82rem);
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--c-brand);
}
.process__eyebrow::before,
.process__eyebrow::after {
	content: "";
	flex: none;
	width: clamp(1rem, 2.5cqi, 1.75rem);
	height: 1px;
	background: color-mix(in srgb, var(--c-brand) 55%, transparent);
}

.process__title {
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 1.15rem + 2cqi, 2.65rem);
	font-weight: 600;
	line-height: 1.08;
	letter-spacing: -.02em;
	text-wrap: balance;
	color: var(--c-text);
}

.process__lead {
	font-size: clamp(.94rem, .88rem + .25cqi, 1.08rem);
	line-height: 1.58;
	color: var(--c-muted);
	max-width: 54ch;
}

/* Métaphore chantier — surlignage léger dans le lead */
.process__tag {
	display: inline-block;
	padding-inline: .12em;
	font-weight: 600;
	color: var(--c-text);
	background:
		linear-gradient(101deg,
			transparent 2%,
			color-mix(in srgb, var(--c-brand) 28%, transparent) 0 97%,
			transparent 0
		) no-repeat;
	background-size: 100% .55em;
	background-position: 0 82%;
	white-space: nowrap;
}

/* Disposition — cadran de progression (gauche) + étapes (droite) */
.process__layout {
	display: grid;
	grid-template-columns: minmax(0, 24rem) minmax(0, 1fr);
	gap: clamp(1.75rem, 5vw, 5rem);
	align-items: start;
}

/* --- Cadran circulaire (sticky, se remplit au scroll via --draw) */
.process__dial {
	position: sticky;
	top: calc(var(--header-h) + clamp(1rem, 16vh, 7rem));
	align-self: start;
	display: grid;
	place-items: center;
	gap: clamp(.9rem, 2.2vh, 1.5rem);
}

.process__dial-figure {
	position: relative;
	display: grid;
	place-items: center;
	/* 44vh : le cadran est sticky et la planche photo vit juste dessous, donc la colonne
	   entière doit tenir dans l'écran. Au-delà de 840px de haut la borne ne mord pas
	   (44vh > 23rem) ; sur un portable elle rétrécit l'anneau au lieu de couper la planche. */
	width: min(100%, 23rem, 44vh);
	aspect-ratio: 1;
	isolation: isolate;
}

/* Pastille de fond sous le compteur : sans elle, le film défile derrière les chiffres
   et l'anneau semble flotter dans une soupe. Dégradé doux, aucune arête visible. */
.process__dial-figure::before {
	content: "";
	grid-area: 1 / 1;
	z-index: 0;
	width: 68%;
	aspect-ratio: 1;
	border-radius: 50%;
	background: radial-gradient(circle,
		color-mix(in srgb, var(--c-bg) 94%, transparent) 0 56%,
		transparent 100%);
}

.process__ring,
.process__dial-core {
	grid-area: 1 / 1;
}

.process__ring {
	position: relative;
	z-index: 1;
	width: 100%;
	height: 100%;
	overflow: visible;
	/* Traits OPAQUES (mélangés au fond, jamais vers transparent) : le film et la poussière défilent
	   derrière la section. Un stroke translucide les laisse transparaître et l'anneau paraît délavé. */
	--ring-off: color-mix(in srgb, var(--c-brand) 30%, var(--c-bg));
	--ring-pay-off: color-mix(in srgb, var(--c-text) 13%, var(--c-bg));
	/* Étape en cours : mélangée à la couleur du texte, donc plus claire sur fond sombre
	   et plus dense sur fond clair. Elle tranche sur le vert des étapes franchies dans les deux thèmes. */
	--ring-current: color-mix(in srgb, var(--c-brand) 62%, var(--c-text));
}
.process__ring-track {
	fill: none;
	stroke-linecap: round;
}
/* Rail paiement — 2 créneaux de 480 u. avec 20 u. de jour en haut et en bas */
.process__ring-track--pay {
	stroke: var(--ring-pay-off);
	stroke-width: 3;
	stroke-dasharray: 480 20;
	transform: rotate(-86.4deg);
	transform-origin: 100px 100px;
	transform-box: view-box;
}
.process__ring-progress {
	fill: none;
	stroke-linecap: round;
	transform-origin: 100px 100px;
	transform-box: view-box;
	transition: stroke-dashoffset .45s var(--ease);
}
/* Anneau étapes — 6 arcs (104 u. / 1000 ≈ 37,4°, interstice 60° entre centres) */
.process__ring-steps {
	transform-origin: 100px 100px;
	transform-box: view-box;
}
.process__ring-seg {
	fill: none;
	stroke: var(--ring-off);
	stroke-width: 6;
	stroke-linecap: round;
	stroke-dasharray: 104 896;
	transition: stroke .4s var(--ease), stroke-width .4s var(--ease);
}
.process__ring-seg.is-on {
	stroke: url(#process-ring-grad);
	stroke-width: 6.5;
}
/* Étape en cours — le seul segment clair : un repère net, sans halo qui baverait sur le film */
.process__ring-seg.is-current {
	stroke: var(--ring-current);
	stroke-width: 8;
}
/* Anneau paiement — les 2 créneaux se remplissent à la signature puis à la remise des clés.
   Chaque arc part de sa propre origine (rotation) : 480 u. dessinées, 1000 u. de jour derrière,
   pour que le remplissage ne déborde jamais dans le créneau voisin. */
.process__ring-progress--pay {
	stroke: var(--c-brand-soft);
	stroke-width: 4.5;
	/* Jour de 1200 u. (et non 1000) : le motif ne peut pas boucler avant la fin du tracé,
	   sinon un tiret de longueur nulle s'y rallume et son bout arrondi laisse une pastille. */
	stroke-dasharray: 480 1200;
}
/* 486 et non 480 : la course intègre le rayon des bouts arrondis, sinon un créneau vide
   laisse dépasser une demi-pastille verte à son point de départ. */
.process__ring-progress--pay-a {
	transform: rotate(-86.4deg);
	stroke-dashoffset: calc(486 - 486 * var(--pay-a, 0));
}
.process__ring-progress--pay-b {
	transform: rotate(93.6deg);
	stroke-dashoffset: calc(486 - 486 * var(--pay-b, 0));
}

.process__dial-core {
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: .3rem;
	max-width: 62%;
	margin-inline: auto;
	text-align: center;
	/* La pastille de fond fait le gros du travail : un seul halo court suffit ici */
	text-shadow: 0 0 12px color-mix(in srgb, var(--c-bg) 88%, transparent);
}
.process__dial-kicker {
	font-size: .68rem;
	font-weight: 700;
	letter-spacing: .22em;
	text-transform: uppercase;
	color: var(--c-faint);
}
.process__dial-count {
	display: inline-flex;
	align-items: baseline;
	gap: .25rem;
	font-family: var(--font-display);
	font-size: clamp(2.6rem, 7cqi, 3.6rem);
	font-weight: 700;
	line-height: 1;
	letter-spacing: -.02em;
	color: var(--c-text);
	font-variant-numeric: tabular-nums;
}
.process__dial-count b { color: var(--c-brand); font-weight: 700; }
.process__dial-total { font-size: .42em; color: var(--c-faint); letter-spacing: 0; }
.process__dial-label {
	min-height: 2.5em;
	font-size: clamp(.84rem, .78rem + .25cqi, .98rem);
	font-weight: 600;
	line-height: 1.25;
	color: var(--c-muted);
	text-wrap: balance;
}
.process__dial-payline {
	display: inline-flex;
	align-items: baseline;
	gap: .4rem;
	margin-block-start: .15rem;
	padding-block-start: .35rem;
	border-block-start: 1px dashed color-mix(in srgb, var(--c-brand) 28%, var(--c-border));
}
.process__dial-pay-kicker {
	font-size: .58rem;
	font-weight: 700;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--c-faint);
}
.process__dial-pay-kicker::before {
	content: "▸";
	margin-inline-end: .25em;
	font-size: .85em;
	color: var(--c-brand);
	opacity: .7;
}
.process__dial-pay {
	font-family: var(--font-display);
	font-size: clamp(.95rem, .88rem + .35cqi, 1.12rem);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--c-brand);
}

/* --- Planche photo sous le cadran — 3 tirages portrait en éventail, celui du milieu
   au-dessus. Largeur d'un tirage indexée sur la hauteur d'écran (--plate-card) : le
   cadran est sticky, donc toute la colonne doit tenir dans l'écran sans se faire
   couper au scroll. Les rotations sortent du cadre de mise en page (pas d'overflow
   hidden ici) : chaque tirage porte donc son propre liseré et son ombre. */
.process__plate {
	--plate-card: clamp(6.75rem, 16.5vh, 9rem);
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	width: min(100%, 23rem);
	padding-block: .5rem;
}

.process__plate-tile {
	position: relative;
	display: block;
	flex: none;
	width: var(--plate-card);
	aspect-ratio: 4 / 5;
	/* Fond opaque : le film du chantier et la poussière défilent derrière la section,
	   un fond translucide les laisserait transparaître le temps du lazy-load. */
	background: var(--c-surface);
	/* Liseré clair, pas teinté marque : c'est le bord d'un tirage papier, et sur ce fond
	   sombre il détache la photo au lieu de la noyer. */
	border: 1px solid color-mix(in srgb, var(--c-text) 18%, transparent);
	border-radius: var(--r-sm);
	box-shadow: 0 20px 34px -22px rgb(0 0 0 / .8);
	overflow: hidden;
	isolation: isolate;
	transition: transform .42s var(--ease), box-shadow .42s var(--ease);
}

/* Éventail : les deux tirages extérieurs basculent et passent sous celui du milieu,
   qui remonte et grossit un peu pour tenir le regard. */
.process__plate-tile:nth-child(1) {
	z-index: 1;
	transform: rotate(-5.5deg) translateY(.4rem);
}
.process__plate-tile:nth-child(2) {
	z-index: 3;
	/* -30 % de part et d'autre : l'éventail reste plus étroit que le cadran, même
	   ouvert au survol. Au-delà, les tirages extérieurs sortent de la colonne. */
	margin-inline: calc(var(--plate-card) * -.3);
	transform: translateY(-.45rem) scale(1.07);
}
.process__plate-tile:nth-child(3) {
	z-index: 2;
	transform: rotate(5.5deg) translateY(.4rem);
}

/* Au survol, l'éventail s'ouvre : les tirages extérieurs s'écartent, celui du milieu
   se redresse. Assez pour donner vie sans décoller de la colonne. */
.process__plate:hover .process__plate-tile:nth-child(1) {
	transform: rotate(-8deg) translate(-.5rem, .25rem);
}
.process__plate:hover .process__plate-tile:nth-child(2) {
	transform: translateY(-.75rem) scale(1.1);
	box-shadow: 0 24px 40px -20px rgb(0 0 0 / .85);
}
.process__plate:hover .process__plate-tile:nth-child(3) {
	transform: rotate(8deg) translate(.5rem, .25rem);
}

.process__plate-photo {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Ces trois clichés sont là pour être beaux : on ne les désature pas, on remonte
	   juste un peu le contraste pour qu'ils tiennent sur ce fond très sombre. */
	filter: contrast(1.04) saturate(1.02);
	transition: filter .42s var(--ease);
}
/* Source plus haute que le cadre 4/5 : le recadrage centré coupe sous le menton,
   on remonte le point d'ancrage sur le sujet. */
.process__plate-photo[data-fit="high"] {
	object-position: center 32%;
}
.process__plate:hover .process__plate-photo { filter: contrast(1.06) saturate(1.08); }

/* Ancrage par le bas seulement, et une pointe de vert à peine lisible dans l'angle :
   assez pour rattacher les tirages à la section, pas assez pour éteindre les visages.
   Un voile plein (ou une teinte marque marquée) rendait les photos verdâtres et ternes. */
.process__plate-tile::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background:
		radial-gradient(130% 90% at 80% 4%, color-mix(in srgb, var(--c-brand) 10%, transparent), transparent 58%),
		linear-gradient(to top, rgb(6 8 12 / .38) 0%, rgb(6 8 12 / .1) 38%, transparent 62%);
	pointer-events: none;
	transition: opacity .42s var(--ease);
}
.process__plate:hover .process__plate-tile::after { opacity: .6; }

@media (prefers-reduced-motion: reduce) {
	.process__plate:hover .process__plate-tile:nth-child(1) { transform: rotate(-5.5deg) translateY(.4rem); }
	.process__plate:hover .process__plate-tile:nth-child(2) { transform: translateY(-.45rem) scale(1.07); }
	.process__plate:hover .process__plate-tile:nth-child(3) { transform: rotate(5.5deg) translateY(.4rem); }
}

/* Écran très court : même avec l'anneau rétréci, la colonne sticky déborderait
   sous la ligne de flottaison. On retire la planche plutôt que de la rogner. */
@media (max-height: 620px) {
	.process__plate { display: none; }
}

.process__steps {
	--marker: clamp(2.85rem, 4vw, 3.35rem);
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: clamp(2.5rem, 7vh, 5.5rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Épine verticale — rail discret + progression (scaleY piloté par --draw) */
.process__steps::before,
.process__steps::after {
	content: "";
	position: absolute;
	z-index: 0;
	inset-block-start: clamp(1.35rem, 3vw, 1.65rem);
	inset-block-end: clamp(1.35rem, 3vw, 1.65rem);
	inset-inline-start: calc(var(--marker) / 2);
	width: 2px;
	border-radius: 2px;
	pointer-events: none;
}
.process__steps::before {
	background: color-mix(in srgb, var(--c-brand) 14%, transparent);
	transform: translateX(-50%);
}
.process__steps::after {
	background: linear-gradient(180deg, var(--c-brand), var(--c-brand-strong));
	transform: translateX(-50%) scaleY(var(--draw, 0));
	transform-origin: 50% top;
	transition: transform .3s var(--ease);
}

.process__step {
	position: relative;
	display: grid;
	grid-template-columns: var(--marker) minmax(0, 1fr);
	gap: clamp(.9rem, 2vw, 1.5rem);
	align-items: start;
	min-width: 0;
}
/* Révélation au scroll — on atténue le texte seulement (pas le marqueur ni les jalons paiement) */
.process.is-scroll-ready .process__step:not(.is-active) .process__body {
	transform: translateY(12px);
	transition: transform .55s var(--ease);
}
.process.is-scroll-ready .process__step:not(.is-active) .process__body > :not(.process__paymile) {
	opacity: .42;
	transition: opacity .55s var(--ease);
}
.process.is-scroll-ready .process__step:not(.is-active) .process__paymile {
	opacity: .82;
}
.process.is-scroll-ready .process__step.is-active .process__body {
	transform: none;
}
.process.is-scroll-ready .process__step.is-active .process__body > * {
	opacity: 1;
}

/* Corps de l'étape */
.process__body {
	display: flex;
	flex-direction: column;
	gap: .4rem;
	min-width: 0;
	padding-block-start: clamp(.1rem, .5vw, .35rem);
}

/* En-tête d'étape : numéro (toujours visible) + intitulé */
.process__topline {
	display: flex;
	align-items: baseline;
	gap: .65rem;
}
.process__num {
	flex: none;
	font-family: var(--font-display);
	font-size: clamp(1.5rem, 1.1rem + 1cqi, 2.05rem);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	letter-spacing: -.02em;
	color: var(--c-brand);
}

/* Badge « délai non garanti » (étape Révisions) */
.process__flag {
	display: inline-flex;
	align-items: center;
	gap: .45rem;
	align-self: start;
	margin-block-start: .35rem;
	padding: .38rem .75rem;
	font-size: .74rem;
	font-weight: 600;
	line-height: 1.2;
	color: color-mix(in srgb, var(--c-brand) 80%, var(--c-text));
	background: var(--c-mark-bg);
	border: 1px dashed var(--c-mark-border);
	border-radius: var(--r-sm);
}
.process__flag svg { width: 1.05em; height: 1.05em; flex: none; }

/* Jalons paiement — étapes 1 (acompte) et 4 (solde) */
.process__paymile {
	display: flex;
	flex-direction: column;
	gap: .45rem;
	align-self: start;
	margin-block-start: .55rem;
	padding: .7rem .9rem;
	border: 1px dashed var(--c-mark-border);
	border-radius: calc(var(--r-sm) + 2px);
	background: color-mix(in srgb, var(--c-mark-bg) 70%, transparent);
	transition: border-color .35s var(--ease), box-shadow .35s var(--ease), background-color .35s var(--ease);
}
.process__paymile-head {
	display: flex;
	align-items: center;
	gap: .55rem;
	min-width: 0;
}
.process__paymile-icon {
	display: grid;
	place-items: center;
	flex: none;
	width: 1.85rem;
	height: 1.85rem;
	border-radius: 8px;
	color: var(--c-brand);
	background: color-mix(in srgb, var(--c-brand) 10%, var(--c-surface));
	border: 1px dashed color-mix(in srgb, var(--c-brand) 30%, var(--c-border));
}
.process__paymile-icon svg { width: 1rem; height: 1rem; }
.process__paymile-kicker {
	font-size: .66rem;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--c-muted);
}
.process__paymile-value {
	margin-inline-start: auto;
	flex: none;
	font-family: var(--font-display);
	font-size: clamp(1.05rem, .95rem + .35cqi, 1.25rem);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
	color: var(--c-brand);
}
.process__paymile-track {
	position: relative;
	height: 5px;
	border-radius: var(--r-pill);
	background: repeating-linear-gradient(
		90deg,
		color-mix(in srgb, var(--c-brand) 22%, transparent) 0 3px,
		transparent 3px 9px
	);
	overflow: hidden;
}
.process__paymile-fill {
	display: block;
	height: 100%;
	width: calc(var(--pay-fill, 0) * 100%);
	border-radius: inherit;
	background: linear-gradient(90deg, var(--c-brand), var(--c-brand-strong));
	box-shadow: 0 0 10px -2px color-mix(in srgb, var(--c-brand) 55%, transparent);
	transition: width .45s var(--ease);
}
.process__paymile-desc {
	margin: 0;
	font-size: clamp(.78rem, .74rem + .12cqi, .86rem);
	line-height: 1.45;
	color: var(--c-muted);
}
.process__paymile-desc strong {
	font-weight: 600;
	color: color-mix(in srgb, var(--c-text) 82%, var(--c-muted));
}
.process__step.is-active .process__paymile {
	border-color: color-mix(in srgb, var(--c-brand) 42%, var(--c-mark-border));
	background: color-mix(in srgb, var(--c-mark-bg) 95%, transparent);
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 10%, transparent),
		0 10px 28px -22px color-mix(in srgb, var(--c-brand) 35%, transparent);
}
.process__step.is-active .process__paymile-icon {
	background: color-mix(in srgb, var(--c-brand) 14%, var(--c-surface));
	border-color: color-mix(in srgb, var(--c-brand) 45%, var(--c-border));
}
.process__paymile--final .process__paymile-fill {
	background: linear-gradient(90deg, var(--c-brand-strong), var(--c-brand));
}
/* Marqueur sur l'épine */
.process__node {
	grid-column: 1;
	position: relative;
	z-index: 2;
	display: grid;
	place-items: center;
	width: var(--marker);
	height: var(--marker);
}

.process__hex {
	display: grid;
	place-items: center;
	width: 100%;
	height: 100%;
	border-radius: 16px;
	color: var(--c-brand);
	background: var(--c-surface);
	border: 1px solid color-mix(in srgb, var(--c-brand) 22%, var(--c-border));
	box-shadow:
		0 0 0 4px var(--c-surface),
		0 12px 28px -18px rgb(0 0 0 / .45),
		0 0 24px -8px color-mix(in srgb, var(--c-brand) 28%, transparent);
	transform: rotate(-3deg);
	transition: transform .35s var(--ease), box-shadow .35s var(--ease), background-color .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease);
}
.process__hex svg {
	width: 1.35rem;
	height: 1.35rem;
}

/* Étape atteinte : marqueur allumé */
.process__step.is-active .process__hex {
	color: #fff;
	background: var(--c-brand);
	border-color: transparent;
	transform: rotate(0deg) scale(1.06);
	box-shadow:
		0 0 0 4px var(--c-brand),
		0 12px 30px -14px color-mix(in srgb, var(--c-brand) 80%, transparent),
		0 0 22px -6px color-mix(in srgb, var(--c-brand) 55%, transparent);
}

.process__meta {
	font-size: .7rem;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--c-muted);
}

.process__name {
	font-size: clamp(1rem, .92rem + .35cqi, 1.18rem);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -.015em;
	color: var(--c-text);
	text-wrap: balance;
}

.process__desc {
	font-size: clamp(.82rem, .78rem + .15cqi, .92rem);
	line-height: 1.52;
	color: var(--c-muted);
}
.process__desc strong {
	font-weight: 600;
	color: color-mix(in srgb, var(--c-text) 78%, var(--c-muted));
}

.process__footnote {
	margin: 0;
	padding: clamp(1rem, 2.5cqi, 1.35rem) clamp(1.1rem, 2.5cqi, 1.5rem);
	font-size: clamp(.86rem, .82rem + .15cqi, .94rem);
	line-height: 1.55;
	text-align: center;
	color: var(--c-muted);
	border: 1px dashed color-mix(in srgb, var(--c-border) 85%, var(--c-brand));
	border-radius: var(--r-md);
	background: color-mix(in srgb, var(--c-surface) 55%, transparent);
	max-width: min(58ch, 100%);
	margin-inline: auto;
}

/* Tablette / mobile : le cadran devient une barre compacte collée en haut,
   qui suit la progression tant qu'on parcourt les étapes */
@media (max-width: 980px) {
	/* [block] et non une grille 1 colonne : en grille, la zone du cadran ne fait que sa propre
	   hauteur, donc le sticky n'a aucune course et la barre disparaît dès le premier scroll.
	   En flux normal, elle reste collée pendant toute la liste des étapes. */
	.process__layout {
		display: block;
	}

	/* Une seule ligne : anneau · compteur · étape en cours · jalon paiement.
	   Hauteur figée, donc la barre ne saute pas d'un cran à l'autre pendant le scroll. */
	.process__dial {
		position: sticky;
		top: calc(var(--header-h) + .4rem);
		z-index: 5;
		grid-template-columns: auto auto minmax(0, 1fr) auto;
		place-items: center start;
		gap: .7rem;
		min-height: 3.6rem;
		margin-block-end: clamp(1.1rem, 3.5vw, 1.75rem);
		padding: .4rem .65rem;
		border: 1px solid var(--c-border);
		border-radius: var(--r-md);
		/* Fond plein, pas de verre dépoli : les pastilles d'étape et l'épine verticale défilent
		   pile sous la barre, et le moindre reste de transparence les laisse baver sur l'anneau. */
		background: var(--c-surface);
		box-shadow: 0 16px 34px -24px rgb(0 0 0 / .75);
	}

	/* [contents] : la figure et le noyau s'effacent pour que leurs enfants deviennent
	   directement les colonnes de la barre. Sans ça, tout s'empile dans la figure. */
	.process__dial-figure,
	.process__dial-core {
		display: contents;
	}
	/* La barre a son propre fond : ni pastille ni halo de texte à l'intérieur */
	.process__dial-figure::before { display: none; }
	.process__dial-core { text-shadow: none; }

	/* Le cadran n'est plus une colonne mais une barre d'une ligne : la planche photo
	   y deviendrait une colonne de la barre et ferait exploser sa hauteur. */
	.process__plate { display: none; }

	.process__ring {
		grid-area: auto;
		width: 2.6rem;
		height: 2.6rem;
	}

	/* Anneaux plus épais pour rester lisibles en petit (sélecteurs alignés sur ceux
	   du desktop, sinon .is-on / .is-current gardent la main par spécificité) */
	.process__ring-seg,
	.process__ring-seg.is-on { stroke-width: 10; }
	.process__ring-seg.is-current { stroke-width: 12; }
	.process__ring-track--pay { stroke-width: 4; }
	.process__ring-progress--pay { stroke-width: 7; }

	/* « Étape » : la barre est déjà un fil de progression, le mot mange une place utile */
	.process__dial-kicker { display: none; }

	.process__dial-count { font-size: 1.05rem; }
	.process__dial-total { font-size: .58em; }

	/* Le libellé occupe la colonne élastique et se coupe proprement plutôt que de passer
	   à la ligne : c'est ce qui garde la barre à une hauteur constante. */
	.process__dial-label {
		min-height: 0;
		font-size: .82rem;
		line-height: 1.2;
		color: var(--c-text);
		text-align: start;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	/* Jalon paiement : pastille calée à droite, à la place du filet pointillé du cadran vertical */
	.process__dial-payline {
		justify-self: end;
		align-items: center;
		gap: .3rem;
		margin-block-start: 0;
		padding: .2rem .5rem;
		border: 1px solid color-mix(in srgb, var(--c-brand) 26%, var(--c-border));
		border-radius: var(--r-pill);
		background: color-mix(in srgb, var(--c-brand) 9%, transparent);
	}
	.process__dial-pay-kicker { font-size: .54rem; letter-spacing: .12em; }
	.process__dial-pay { font-size: .82rem; }
}

@media (max-width: 560px) {
	.process__steps {
		--marker: 2.65rem;
		gap: clamp(1.75rem, 6vw, 2.75rem);
	}

	.process__step {
		gap: .9rem;
	}

	.process__hex {
		border-radius: 13px;
	}
	.process__hex svg {
		width: 1.2rem;
		height: 1.2rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.process__hex { transition: none; }
}

/* Thème clair — process */
[data-bs-theme="light"] .process {
	background: var(--c-bg);
	border-block-start-color: color-mix(in srgb, var(--c-border) 55%, transparent);
}

/* Fond blanc : seules les zones sombres du film ressortent (clés, calculatrice), et ce sont
   justement elles qui gênent le texte noir. Scrim blanc un peu plus dense qu'en sombre. */
[data-bs-theme="light"] .process__film-stage {
	--film-band: 64%;
	--film-veil: 50%;
	--film-edge: 88%;
}
[data-bs-theme="light"] .process__film-media {
	opacity: .6;
	filter: blur(3px) saturate(.6) contrast(1.12) brightness(.9);
}

[data-bs-theme="light"] .process__smoke {
	--smoke-low: #eef6ef;
	--smoke-mid: #8fc39c;
	--smoke-high: #3f7d51;
	--smoke-alpha: 0.12;
	background:
		radial-gradient(ellipse 92% 38% at 50% 100%, rgb(23 182 47 / .14), transparent 70%),
		radial-gradient(ellipse 48% 30% at 24% 98%, rgb(95 209 115 / .1), transparent 64%),
		radial-gradient(ellipse 48% 30% at 76% 98%, rgb(95 209 115 / .1), transparent 64%);
}
[data-bs-theme="light"] .process__smoke-canvas {
	mix-blend-mode: multiply;
}

[data-bs-theme="light"] .process__ring {
	--ring-off: color-mix(in srgb, var(--c-brand) 22%, var(--c-bg));
	--ring-pay-off: color-mix(in srgb, var(--c-text) 14%, var(--c-bg));
}

[data-bs-theme="light"] .process__dial-core {
	text-shadow: 0 0 10px rgb(255 255 255 / .95);
}
[data-bs-theme="light"] .process__paymile {
	background: color-mix(in srgb, var(--c-mark-bg) 85%, #fff);
}
[data-bs-theme="light"] .process__step.is-active .process__paymile {
	background: rgb(255 255 255 / .92);
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 8%, transparent),
		0 12px 30px -22px rgb(12 12 18 / .1);
}
[data-bs-theme="light"] .process__paymile-icon {
	background: #fff;
}

[data-bs-theme="light"] .process__steps::before {
	background: color-mix(in srgb, var(--c-brand) 18%, transparent);
}

[data-bs-theme="light"] .process__num {
	color: var(--c-brand);
}

[data-bs-theme="light"] .process__hex {
	background: #fff;
	box-shadow:
		0 0 0 4px #fff,
		0 10px 26px -18px rgb(12 12 18 / .14),
		0 0 20px -8px color-mix(in srgb, var(--c-brand) 18%, transparent);
}
[data-bs-theme="light"] .process__step.is-active .process__hex {
	box-shadow:
		0 0 0 4px var(--c-brand),
		0 10px 26px -18px rgb(12 12 18 / .14);
}

[data-bs-theme="light"] .process__footnote {
	background: rgb(255 255 255 / .72);
	border-color: color-mix(in srgb, var(--c-brand) 18%, var(--c-border));
}

/* ============================================================
   Responsive
   ============================================================ */
/* Desktop compact — zoom 150–175 %, laptops étroits */
@media (min-width: 1141px) and (max-width: 1360px) {
	.hero__stage {
		--hero-title-max: 3.15rem;
		--hero-subtitle-max: 1.18rem;
		--hero-lead-max: 1.05rem;
	}

	.hero__inner {
		grid-template-columns: minmax(0, 1.18fr) minmax(0, 0.82fr);
		gap: clamp(.75rem, 1.8vw, 1.5rem);
	}

	.hero__visual {
		--hero-device-size: clamp(320px, 34vw, 480px);
		--hero-orbit-gap: 16%;
	}

	.hero__meta { --meta-gap: clamp(1.1rem, 2.4vw, 1.9rem); }
}

@media (min-width: 1361px) {
	.hero__stage {
		--hero-title-fluid: 1.2rem + 3.9cqi;
		--hero-title-max: 4.35rem;
		--hero-subtitle-fluid: .9rem + .68cqi;
		--hero-subtitle-max: 1.38rem;
		--hero-lead-fluid: .88rem + .45cqi;
		--hero-lead-max: 1.18rem;
		--hero-eyebrow-max: .85rem;
		--hero-meta-value-max: 1.05rem;
	}

	.hero__inner {
		grid-template-columns: minmax(0, 1.32fr) minmax(0, 0.68fr);
	}

	.hero__lead { max-width: min(64ch, 100%); }
}

@media (min-width: 1600px) {
	.hero__stage {
		--hero-title-fluid: 1.35rem + 4.2cqi;
		--hero-title-max: 4.85rem;
		--hero-subtitle-max: 1.45rem;
		--hero-lead-max: 1.22rem;
		--hero-meta-value-max: 1.1rem;
	}

	.hero__visual {
		--hero-device-size: clamp(480px, 32vw, 680px);
	}
}

@media (min-width: 1680px) {
	.hero__stage {
		--hero-title-fluid: 1.45rem + 4.4cqi;
		--hero-title-max: 5rem;
		--hero-subtitle-max: 1.48rem;
		--hero-lead-max: 1.25rem;
	}
}

@media (min-width: 1280px) {
	.hero__visual {
		--hero-device-size: clamp(420px, 34vw, 620px);
	}
}

@media (min-width: 1440px) {
	.hero__rail {
		--rail-card-w: clamp(15rem, 13vw, 17.5rem);
		--rail-media-ratio: 4 / 5;
	}
}

@media (max-width: 1140px) {
	.hero__inner {
		grid-template-columns: 1fr;
		justify-items: center;
		text-align: center;
		gap: clamp(1.75rem, 6vw, 2.75rem);
	}

	.hero__copy {
		align-items: center;
		max-width: min(680px, 100%);
	}

	.hero__title {
		font-size: clamp(1.85rem, 6.2vw, 2.65rem);
		max-width: 16ch;
	}

	.hero__subtitle { max-width: min(36ch, 100%); }

	.hero__meta { justify-content: center; align-self: center; }
	.hero__actions { justify-content: center; }

	.hero__visual {
		--hero-device-size: min(68vw, 400px);
		--hero-orbit-gap: 15%;
		justify-self: center;
		order: -1;
		margin-block-start: clamp(2rem, 7vw, 3.5rem);
		margin-block-end: clamp(2.5rem, 7.5vw, 4rem);
	}
}

@media (max-width: 768px) {
	.hero__stage {
		padding-block-end: clamp(3rem, 10vh, 5rem);
	}

	.hero__visual {
		--hero-device-size: min(66vw, 340px);
		margin-block-start: clamp(1.75rem, 6.5vw, 3rem);
		margin-block-end: clamp(2.75rem, 9vw, 4.25rem);
	}
}

@media (max-width: 480px) {
	.hero__visual {
		--hero-device-size: min(72vw, 300px);
		--hero-orbit-gap: 13%;
		margin-block-start: clamp(1.5rem, 5.5vw, 2.5rem);
		margin-block-end: clamp(2.25rem, 8vw, 3.5rem);
	}
}


@media (max-width: 720px) {
	.hero__rail {
		--rail-card-w: clamp(12.75rem, 72vw, 15rem);
	}


	.sector-card__media {
		min-height: clamp(13.5rem, 58vw, 16rem);
	}

	.sector-card__body {
		min-height: 4.75rem;
		padding: .9rem .95rem 1rem;
	}

	.hero__meta {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}
	.hero__meta-item {
		gap: .35rem;
		padding-block: .85rem;
	}
	.hero__meta-item:first-child { padding-block-start: 0; }
	.hero__meta-item:last-child { padding-block-end: 0; }
	.hero__meta-item:not(:last-child) { border-block-end: 1px solid var(--c-border); }
	.hero__meta-item:not(:last-child)::after { display: none; }
}

/* ============================================================
   Thème clair — hero & composants home
   ============================================================ */
[data-bs-theme="light"] .hero__bg {
	/* Poussière light (mode multiply) : la densité assombrit sans délaver.
	   low ≈ quasi-blanc (invisible sur fond clair), high = vert grisé (craie de
	   chantier). Un vert saturé donnerait une vapeur colorée, pas une poussière. */
	--smoke-low: #eef6ef;
	--smoke-mid: #8fc39c;
	--smoke-high: #3f7d51;
	--smoke-alpha: 0.34;
	/* Trait de plan inversé : la craie claire du dark disparaîtrait sur le papier blanc */
	--hero-grid-line: rgb(13 138 36 / .13);
	--hero-grid-line-strong: rgb(13 138 36 / .22);
	/* Papier blanc dominant + accent vert contenu dans le coin haut-droit */
	background:
		radial-gradient(72% 64% at 102% -2%, rgb(23 182 47 / .16), transparent 48%),
		linear-gradient(180deg, #ffffff 0%, #f5fdf7 50%, var(--c-bg) 100%);
}

/* Plan clair — papier calque : trame contenue à droite, le copy reste sur blanc franc */
[data-bs-theme="light"] .hero__bg::before {
	-webkit-mask-image:
		radial-gradient(ellipse 96% 104% at 104% -6%, #000 0%, #000 38%, rgb(0 0 0 / .35) 62%, transparent 80%);
	mask-image:
		radial-gradient(ellipse 96% 104% at 104% -6%, #000 0%, #000 38%, rgb(0 0 0 / .35) 62%, transparent 80%);
}

@media (max-width: 720px) {
	[data-bs-theme="light"] .hero__bg::before {
		-webkit-mask-image:
			radial-gradient(ellipse 120% 70% at 108% -8%, #000 0%, #000 36%, rgb(0 0 0 / .32) 60%, transparent 80%);
		mask-image:
			radial-gradient(ellipse 120% 70% at 108% -8%, #000 0%, #000 36%, rgb(0 0 0 / .32) 60%, transparent 80%);
	}
}

[data-bs-theme="light"] .hero__bg::after {
	background-color: transparent;
	background-image:
		/* Scrim gauche net — protège le copy, coupe avant le centre */
		linear-gradient(100deg,
			rgb(255 255 255 / .97) 0%,
			rgb(255 255 255 / .85) 20%,
			rgb(255 255 255 / 0) 42%
		),
		/* Halo focal net derrière le laptop (le produit) */
		radial-gradient(34% 40% at 77% 47%, rgb(23 182 47 / .16), transparent 56%),
		/* Fonte verticale franche vers le rail */
		linear-gradient(180deg, transparent 56%, var(--c-bg) 100%);
}

[data-bs-theme="light"] .hero__rail {
	background: var(--c-bg);
	border-block-start-color: color-mix(in srgb, var(--c-border) 42%, transparent);
}

[data-bs-theme="light"] .rail__btn {
	background: rgb(255 255 255 / .92);
	box-shadow:
		0 1px 0 rgb(255 255 255 / .98) inset,
		0 10px 28px -18px rgb(12 12 18 / .12);
}
[data-bs-theme="light"] .rail__btn:hover:not(:disabled) {
	background: rgb(255 255 255 / .98);
	box-shadow:
		0 1px 0 rgb(255 255 255 / .98) inset,
		0 12px 28px -16px rgb(12 12 18 / .16);
}

[data-bs-theme="light"] .sector-card__link {
	box-shadow: 0 10px 28px -22px rgb(12 12 18 / .08);
}

[data-bs-theme="light"] .sector-card__link:hover,
[data-bs-theme="light"] .sector-card__link:focus-visible {
	background: color-mix(in srgb, var(--c-surface) 98%, var(--c-brand));
	box-shadow:
		0 0 0 1px color-mix(in srgb, var(--c-brand) 8%, transparent),
		0 14px 34px -22px rgb(12 12 18 / .12);
}

[data-bs-theme="light"] .sector-card__media {
	background-image:
		repeating-linear-gradient(var(--sector-hatch-angle, 135deg),
			var(--c-blueprint-line-strong) 0 1px,
			transparent 1px 12px
		),
		linear-gradient(
			168deg,
			color-mix(in srgb, var(--c-surface-2) 55%, white) 0%,
			var(--c-surface-2) 52%,
			color-mix(in srgb, var(--c-surface-2) 90%, var(--c-bg)) 100%
		);
}

[data-bs-theme="light"] .sector-card__media::after {
	background:
		linear-gradient(180deg, rgb(255 255 255 / .28) 0%, transparent 42%),
		linear-gradient(0deg, rgb(12 12 18 / .06) 0%, transparent 38%);
}

[data-bs-theme="light"] .hero__copy {
	position: relative;
	z-index: 1;
}

/* En thème clair : dalle gardée « allumée » (sombre), ombre du laptop adoucie */
[data-bs-theme="light"] .hero__visual-laptop {
	filter:
		drop-shadow(0 16px 30px rgb(12 32 52 / .18))
		drop-shadow(0 4px 10px rgb(12 32 52 / .08));
}

[data-bs-theme="light"] .hero__visual-glow {
	background:
		radial-gradient(circle,
			rgb(150 235 178 / .16) 0%,
			rgb(23 182 47 / .08) 38%,
			transparent 72%);
}

/* Ombre au sol — contact réaliste sur surface claire, teinte eau */
[data-bs-theme="light"] .hero__visual-shadow {
	background:
		radial-gradient(ellipse,
			rgb(12 32 52 / .14) 0%,
			rgb(80 160 210 / .07) 42%,
			transparent 72%);
	filter: blur(16px);
}

[data-bs-theme="light"] .hero__eyebrow {
	color: rgba(18, 18, 26, .72);
}

[data-bs-theme="light"] .hero__subtitle {
	color: rgba(18, 18, 26, .78);
}

[data-bs-theme="light"] .hero__lead {
	color: rgba(18, 18, 26, .82);
}

[data-bs-theme="light"] .hero__meta-item:not(:last-child)::after {
	background: rgba(12, 12, 18, .16);
}
[data-bs-theme="light"] .hero__meta-item:not(:last-child) {
	border-block-end-color: rgba(12, 12, 18, .14);
}


/* Marqueur calibré pour le fond clair */
[data-bs-theme="light"] .hero__build-tag {
	--mark: color-mix(in srgb, var(--c-brand) 25%, transparent);
}




/* ============================================================
   Les bâtisseurs — équipe derrière le chantier
   ============================================================ */
/* Bloc de confiance juste après le hero : surface légèrement relevée pour
   qu'il se détache du fond commun aux autres sections. */
.team {
	position: relative;
	padding-block: clamp(3.75rem, 8vh, 6rem);
	background: color-mix(in srgb, var(--c-surface) 52%, var(--c-bg));
	border-block: 1px solid var(--c-border);
	overflow-x: clip;
	isolation: isolate;
}

/* Trame d'architecte — rappel du hero, sous le contenu */
.team::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background-image:
		linear-gradient(to right, var(--c-blueprint-line) 1px, transparent 1px),
		linear-gradient(to bottom, var(--c-blueprint-line) 1px, transparent 1px);
	background-size: 48px 48px;
	-webkit-mask-image: radial-gradient(ellipse 72% 62% at 50% 42%, #000 18%, transparent 80%);
	mask-image: radial-gradient(ellipse 72% 62% at 50% 42%, #000 18%, transparent 80%);
}

.team__inner {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: clamp(2rem, 5vh, 3.25rem);
}

/* --- En-tête de section (aligné sur .process__head) */
.team__head {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: clamp(.45rem, 1cqi, .75rem);
	max-width: min(62ch, 100%);
	margin-inline: auto;
}

.team__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .65rem;
	font-size: clamp(.72rem, .62rem + .3cqi, .82rem);
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--c-brand);
}
.team__eyebrow::before,
.team__eyebrow::after {
	content: "";
	flex: none;
	width: clamp(1rem, 2.5cqi, 1.75rem);
	height: 1px;
	background: color-mix(in srgb, var(--c-brand) 55%, transparent);
}

.team__title {
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 1.15rem + 2cqi, 2.65rem);
	font-weight: 600;
	line-height: 1.08;
	letter-spacing: -.02em;
	text-wrap: balance;
	color: var(--c-text);
}

.team__lead {
	font-size: clamp(.94rem, .88rem + .25cqi, 1.08rem);
	line-height: 1.58;
	color: var(--c-muted);
	max-width: 56ch;
	text-wrap: balance;
}

/* Surlignage métaphore — même traitement que .process__tag */
.team__tag {
	display: inline-block;
	padding-inline: .12em;
	font-weight: 600;
	color: var(--c-text);
	background:
		linear-gradient(101deg,
			transparent 2%,
			color-mix(in srgb, var(--c-brand) 28%, transparent) 0 97%,
			transparent 0
		) no-repeat;
}

/* --- Grille des fiches */
.team__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(1rem, 2.4vw, 1.75rem);
	margin: 0;
	padding: 0;
	list-style: none;
}

.team__card {
	display: grid;
	grid-template-columns: clamp(180px, 22vw, 240px) minmax(0, 1fr);
	gap: clamp(1.15rem, 2.2vw, 1.75rem);
	padding: clamp(1rem, 1.8vw, 1.45rem);
	border: 1px solid color-mix(in srgb, var(--c-border) 90%, var(--c-text));
	border-radius: var(--r-md);
	background: color-mix(in srgb, var(--c-surface) 88%, transparent);
	box-shadow: 0 10px 30px -22px rgb(0 0 0 / .55);
	backdrop-filter: blur(10px) saturate(140%);
	-webkit-backdrop-filter: blur(10px) saturate(140%);
	transition: transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.team__card:hover {
	transform: translateY(-4px);
	border-color: color-mix(in srgb, var(--c-brand) 46%, transparent);
	box-shadow: 0 24px 50px -26px rgb(0 0 0 / .75);
}

/* --- Portrait */
.team__media {
	position: relative;
	aspect-ratio: 4 / 5;
	border-radius: calc(var(--r-md) - 4px);
	overflow: hidden;
	background: var(--c-surface-2);
}

/* Équerres d'angle — repère de plan sur le portrait */
.team__frame {
	--corner: 26%;
	position: absolute;
	inset: .5rem;
	z-index: 2;
	pointer-events: none;
	border: 1px solid color-mix(in srgb, var(--c-brand) 46%, transparent);
	-webkit-mask:
		linear-gradient(#000 0 0) 0 0 / var(--corner) var(--corner) no-repeat,
		linear-gradient(#000 0 0) 100% 0 / var(--corner) var(--corner) no-repeat,
		linear-gradient(#000 0 0) 0 100% / var(--corner) var(--corner) no-repeat,
		linear-gradient(#000 0 0) 100% 100% / var(--corner) var(--corner) no-repeat;
	mask:
		linear-gradient(#000 0 0) 0 0 / var(--corner) var(--corner) no-repeat,
		linear-gradient(#000 0 0) 100% 0 / var(--corner) var(--corner) no-repeat,
		linear-gradient(#000 0 0) 0 100% / var(--corner) var(--corner) no-repeat,
		linear-gradient(#000 0 0) 100% 100% / var(--corner) var(--corner) no-repeat;
}

.team__photo {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Les deux prises de vue viennent de décors différents : on rapproche les rendus */
	filter: saturate(.96) contrast(1.03);
	transition: transform .5s var(--ease), filter .4s var(--ease);
}
.team__card:hover .team__photo {
	transform: scale(1.035);
	filter: saturate(1.02) contrast(1.05);
}

/* --- Identité — centrée sur la hauteur du portrait, qui dicte celle de la fiche */
.team__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: .5rem;
	min-width: 0;
	padding-block: clamp(.15rem, 1vw, .5rem);
}

.team__role {
	font-size: clamp(.68rem, .62rem + .2cqi, .76rem);
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--c-brand);
}

.team__name {
	font-family: var(--font-display);
	font-size: clamp(1.4rem, 1.05rem + 1.3cqi, 1.95rem);
	font-weight: 600;
	line-height: 1.08;
	letter-spacing: -.015em;
	color: var(--c-text);
}

.team__bio {
	font-size: clamp(.9rem, .86rem + .22cqi, 1.02rem);
	line-height: 1.58;
	color: var(--c-muted);
}
.team__bio strong { color: var(--c-text); font-weight: 700; }

.team__skills {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
	margin: .2rem 0 0;
	padding: 0;
	list-style: none;
}

.team__skill {
	padding: .3rem .6rem;
	font-size: clamp(.7rem, .66rem + .15cqi, .78rem);
	font-weight: 600;
	line-height: 1.2;
	color: var(--c-text);
	border: 1px solid var(--c-mark-border);
	border-radius: var(--r-pill);
	background: var(--c-mark-bg);
}

.team__footnote {
	max-width: 68ch;
	margin-inline: auto;
	text-align: center;
	font-size: clamp(.84rem, .8rem + .2cqi, .94rem);
	line-height: 1.6;
	color: var(--c-faint);
	text-wrap: balance;
}
.team__footnote strong { color: var(--c-muted); font-weight: 700; }

/* --- Une colonne : les fiches gardent le portrait à gauche */
@media (max-width: 980px) {
	.team__grid { grid-template-columns: minmax(0, 1fr); }
	.team__card { max-width: 640px; margin-inline: auto; }
}

@media (max-width: 560px) {
	.team__card { grid-template-columns: clamp(124px, 36vw, 170px) minmax(0, 1fr); }
	.team__frame { inset: .35rem; }

	/* Colonne texte plus haute que le portrait : celui-ci comble la hauteur
	   au lieu de laisser un vide sous lui. */
	.team__media {
		aspect-ratio: auto;
		height: 100%;
		min-height: calc(clamp(124px, 36vw, 170px) * 1.25);
	}

	.team__skill { padding: .26rem .5rem; }
}

@media (prefers-reduced-motion: reduce) {
	.team__card,
	.team__photo { transition: none; }
	.team__card:hover { transform: none; }
	.team__card:hover .team__photo { transform: none; }
}

/* --- Thème clair */
[data-bs-theme="light"] .team__card {
	background: color-mix(in srgb, #fff 76%, transparent);
	border-color: rgba(12, 12, 18, .12);
}
[data-bs-theme="light"] .team__card:hover {
	box-shadow: 0 18px 40px -26px rgb(12 24 18 / .3);
}
[data-bs-theme="light"] .team__lead {
	color: rgba(18, 18, 26, .82);
}
[data-bs-theme="light"] .team__bio {
	color: rgba(18, 18, 26, .74);
}
[data-bs-theme="light"] .team__footnote {
	color: rgba(18, 18, 26, .6);
}
[data-bs-theme="light"] .team__footnote strong {
	color: rgba(18, 18, 26, .8);
}




/* ============================================================
   Contact — dépôt du plan (call to action final)
   ============================================================ */
/* Dernier bloc du <main>, juste avant la bannière « Fondations solides ».
   Fond plus sombre que .team : le formulaire doit capter l'oeil en fin de page. */
.contact {
	position: relative;
	padding-block: clamp(3.75rem, 8vh, 6rem);
	background: color-mix(in srgb, var(--c-surface) 30%, var(--c-bg));
	border-block-start: 1px solid var(--c-border);
	overflow-x: clip;
	isolation: isolate;
}

/* Trame d'architecte + halo vert côté formulaire (rappel du hero) */
.contact__bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background-image:
		linear-gradient(to right, var(--c-blueprint-line) 1px, transparent 1px),
		linear-gradient(to bottom, var(--c-blueprint-line) 1px, transparent 1px);
	background-size: 48px 48px;
	-webkit-mask-image: radial-gradient(ellipse 74% 66% at 62% 44%, #000 16%, transparent 82%);
	mask-image: radial-gradient(ellipse 74% 66% at 62% 44%, #000 16%, transparent 82%);
}
.contact__bg::after {
	content: "";
	position: absolute;
	inset: 0;
	background: radial-gradient(70% 60% at 78% 30%, color-mix(in srgb, var(--c-brand) 12%, transparent), transparent 62%);
}

/* --- Poussière WebGL — grains en suspension, nappe basse appuyée à gauche */
.contact__smoke {
	/* Palette poussière WebGL (lue par hero-smoke.js) — alignée sur le hero */
	--smoke-low: #091914;
	--smoke-mid: #12643f;
	--smoke-high: #8fd4a3;
	/* Plus bas que le hero : ici le voile n'est qu'un fond, ce sont les grains
	   de .contact__dust qui portent l'effet. Une nappe dense les noierait */
	--smoke-alpha: 0.22;

	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	overflow: hidden;
	/* Fallback CSS pur si WebGL indisponible ou prefers-reduced-data */
	background:
		radial-gradient(ellipse 88% 40% at 26% 100%, rgb(23 182 47 / .2), transparent 70%),
		radial-gradient(ellipse 60% 32% at 72% 100%, rgb(20 110 55 / .12), transparent 66%);
	-webkit-mask-image:
		linear-gradient(to top,
			#000 0%,
			rgb(0 0 0 / .92) 24%,
			rgb(0 0 0 / .55) 56%,
			rgb(0 0 0 / .18) 80%,
			transparent 100%);
	mask-image:
		linear-gradient(to top,
			#000 0%,
			rgb(0 0 0 / .92) 24%,
			rgb(0 0 0 / .55) 56%,
			rgb(0 0 0 / .18) 80%,
			transparent 100%);
}

.contact__smoke-canvas {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
	opacity: 0;
	transition: opacity 1.4s var(--ease);
}
.contact__smoke-canvas.is-ready { opacity: 1; }

@media (prefers-reduced-data: reduce) {
	.contact__smoke-canvas { display: none; }
}

/* --- Grains en suspension (dust-particles.js) — couche nette, pleine résolution.
       Hors de .contact__smoke : le masque de la nappe les couperait à mi-hauteur,
       or c'est justement en haut qu'ils font lire « air chargé » plutôt que « brume ». */
.contact__dust {
	--dust-color: #d8f5df;
	--dust-opacity: 0.70;

	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	width: 100%;
	height: 100%;
	pointer-events: none;
	opacity: 0;
	transition: opacity 1.6s var(--ease);
	-webkit-mask-image: linear-gradient(to top, #000 0%, rgb(0 0 0 / .8) 62%, rgb(0 0 0 / .34) 88%, transparent 100%);
	mask-image: linear-gradient(to top, #000 0%, rgb(0 0 0 / .8) 62%, rgb(0 0 0 / .34) 88%, transparent 100%);
}
.contact__dust.is-ready { opacity: 1; }

@media (prefers-reduced-data: reduce) {
	.contact__dust { display: none; }
}

.contact__inner {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr);
	gap: clamp(2rem, 4.5vw, 4rem);
	align-items: start;
}

/* --- Argumentaire (colonne de gauche) */
.contact__pitch {
	display: flex;
	flex-direction: column;
	gap: clamp(.9rem, 2vh, 1.35rem);
	padding-block-start: clamp(0rem, 1.5vw, 1rem);
}

.contact__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: .65rem;
	font-size: clamp(.72rem, .62rem + .3cqi, .82rem);
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--c-brand);
}
.contact__eyebrow::before {
	content: "";
	flex: none;
	width: clamp(1rem, 2.5cqi, 1.75rem);
	height: 1px;
	background: color-mix(in srgb, var(--c-brand) 55%, transparent);
}

.contact__title {
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 1.15rem + 2cqi, 2.65rem);
	font-weight: 600;
	line-height: 1.08;
	letter-spacing: -.02em;
	text-wrap: balance;
	color: var(--c-text);
}

.contact__lead {
	max-width: 46ch;
	font-size: clamp(.94rem, .88rem + .25cqi, 1.08rem);
	line-height: 1.58;
	color: var(--c-muted);
	text-wrap: pretty;
}
.contact__lead strong { color: var(--c-text); font-weight: 700; }

/* --- Points de réassurance */
.contact__points {
	display: flex;
	flex-direction: column;
	gap: clamp(.75rem, 1.6vh, 1.1rem);
	margin: .35rem 0 0;
	padding: 0;
	list-style: none;
}

.contact__point {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: .85rem;
	align-items: start;
}

.contact__point-icon {
	display: inline-grid;
	place-items: center;
	width: 2.35rem;
	height: 2.35rem;
	flex: none;
	color: var(--c-brand);
	border: 1px solid var(--c-mark-border);
	border-radius: var(--r-sm);
	background: var(--c-mark-bg);
}
.contact__point-icon svg { width: 1.15rem; height: 1.15rem; }

.contact__point-copy {
	display: flex;
	flex-direction: column;
	gap: .15rem;
	min-width: 0;
}
.contact__point-copy strong {
	font-size: clamp(.92rem, .88rem + .2cqi, 1rem);
	font-weight: 700;
	line-height: 1.35;
	color: var(--c-text);
}
.contact__point-copy span {
	font-size: clamp(.84rem, .8rem + .18cqi, .92rem);
	line-height: 1.5;
	color: var(--c-muted);
}

/* Flex plutôt qu'un espace de texte : l'espacement libellé / lien ne dépend
   plus du repli des blancs par le minifieur de pages. */
.contact__direct {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: .4rem;
	margin-block-start: .35rem;
	font-size: clamp(.84rem, .8rem + .2cqi, .94rem);
	color: var(--c-faint);
}

.contact__direct-link {
	font-weight: 600;
	color: var(--c-text);
	border-block-end: 1px solid color-mix(in srgb, var(--c-brand) 55%, transparent);
	transition: color .2s var(--ease), border-color .2s var(--ease);
}
.contact__direct-link:hover,
.contact__direct-link:focus-visible {
	color: var(--c-brand);
	border-block-end-color: var(--c-brand);
}

/* --- Carte formulaire (colonne de droite) */
.contact__card {
	padding: clamp(1.25rem, 2.4vw, 2rem);
	border: 1px solid color-mix(in srgb, var(--c-border) 90%, var(--c-text));
	border-radius: var(--r-md);
	background: color-mix(in srgb, var(--c-surface) 90%, transparent);
	box-shadow: 0 22px 54px -32px rgb(0 0 0 / .8);
	backdrop-filter: blur(12px) saturate(140%);
	-webkit-backdrop-filter: blur(12px) saturate(140%);
}

.contact__form {
	display: flex;
	flex-direction: column;
	gap: clamp(.85rem, 1.8vh, 1.15rem);
}

.contact__row {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(.85rem, 1.6vw, 1.15rem);
}

.contact__field {
	display: flex;
	flex-direction: column;
	gap: .4rem;
	min-width: 0;
}

/* L'astérisque « obligatoire » est injecté par Maestra sur .mm-field-required : rien à écrire ici */
.contact__label {
	font-size: clamp(.72rem, .68rem + .15cqi, .79rem);
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--c-muted);
}

.contact__input {
	width: 100%;
	padding: .8rem .95rem;
	font-size: .95rem;
	line-height: 1.45;
	color: var(--c-text);
	background: color-mix(in srgb, var(--c-bg) 62%, transparent);
	border: 1px solid var(--c-border);
	border-radius: var(--r-sm);
	transition: border-color .2s var(--ease), background-color .2s var(--ease), box-shadow .2s var(--ease);
}
.contact__input::placeholder { color: var(--c-faint); }
.contact__input:hover { border-color: var(--c-ghost-border-hover); }
.contact__input:focus,
.contact__input:focus-visible {
	outline: none;
	border-color: color-mix(in srgb, var(--c-brand) 62%, transparent);
	background: color-mix(in srgb, var(--c-bg) 78%, transparent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-brand) 18%, transparent);
}

/* Champ refusé par la validation Maestra (classe [mm_error]) */
.contact__input.mm_error {
	border-color: #e5484d;
	box-shadow: 0 0 0 3px rgb(229 72 77 / .16);
}

/* --- Téléphone international (plugin input_tel / .iti)
       Le CSS du plugin parle encore les tokens admin Maestra
       (--brand-primary, --bs-primary → bleu #00a1ff, surface #161d21).
       On les remappe ici sur --c-* pour que drapeau, recherche et liste
       suivent le vert Palmer Tech, clair comme sombre. */
.contact,
.contact .iti,
.contact .iti--container {
	--brand-primary: var(--c-brand);
	--bs-primary: var(--c-brand);
	--iti-surface: var(--c-panel-bg);
	--iti-border: var(--c-border);
	--iti-text: var(--c-text);
	--iti-muted: var(--c-muted);
	--iti-hover: color-mix(in srgb, var(--c-brand) 16%, transparent);
	--iti-shadow: 0 26px 56px -26px rgb(0 0 0 / .78);
	--iti-radius: var(--r-md);
}

.contact__field--tel { position: relative; }
.contact__field--tel:focus-within { z-index: 4; }

.contact .iti {
	display: block;
	width: 100%;
}

/* Préfixe drapeau : même hauteur que le champ, fond discret pour le
   séparer du numéro (comme le visuel de référence). */
.contact .iti__selected-flag {
	border-radius: var(--r-sm) 0 0 var(--r-sm);
	background: var(--c-ghost-bg);
}
.contact .iti--allow-dropdown .iti__flag-container:hover .iti__selected-flag,
.contact .iti--allow-dropdown .iti__flag-container:focus .iti__selected-flag,
.contact .iti--allow-dropdown .iti__flag-container:focus-within .iti__selected-flag {
	background: var(--c-ghost-bg-hover) !important;
}

.contact .iti__arrow {
	border-top-color: var(--c-muted);
}
.contact .iti__arrow--up {
	border-top: none;
	border-bottom-color: var(--c-brand);
}

/* Panneau pays : même carte que le Customizable Select du formulaire */
.contact .iti__dropdown-content {
	margin-block-start: .45rem !important;
	padding: .35rem !important;
	background: var(--c-panel-bg) !important;
	border: 1px solid color-mix(in srgb, var(--c-brand) 22%, var(--c-border)) !important;
	border-radius: var(--r-md) !important;
	box-shadow: 0 26px 56px -26px rgb(0 0 0 / .78) !important;
	overflow: hidden;
}

.contact .iti__search-input {
	width: calc(100% - .7rem) !important;
	margin: .15rem .35rem .45rem !important;
	padding: .55rem .7rem !important;
	color: var(--c-text) !important;
	background: color-mix(in srgb, var(--c-bg) 62%, transparent) !important;
	border: 1px solid var(--c-border) !important;
	border-radius: var(--r-sm) !important;
	box-shadow: none !important;
}
.contact .iti__search-input::placeholder { color: var(--c-faint); }
.contact .iti__search-input:focus,
.contact .iti__search-input:focus-visible {
	outline: none;
	border-color: color-mix(in srgb, var(--c-brand) 62%, transparent) !important;
	background: color-mix(in srgb, var(--c-bg) 78%, transparent) !important;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-brand) 18%, transparent) !important;
}

.contact .iti__search-input + .iti__country-list { border-top: none !important; }

.contact .iti__country-list {
	background: transparent !important;
	scrollbar-color: var(--scrollbar-thumb) transparent;
}

.contact .iti__country {
	border-radius: var(--r-sm);
	color: var(--c-text) !important;
	background: transparent !important;
}
.contact .iti__country-name { color: var(--c-text) !important; }
.contact .iti__dial-code { color: var(--c-muted) !important; }

.contact .iti__country.iti__highlight,
.contact .iti__country:hover,
.contact .iti__country:focus {
	background: color-mix(in srgb, var(--c-brand) 16%, transparent) !important;
}

.contact .iti__divider { border-bottom-color: var(--c-border) !important; }

.contact__textarea {
	min-height: 8.5rem;
	resize: vertical;
}

/* Select — flèche maison, la native ne suit pas le thème */
.contact__select-wrap { position: relative; display: block; }

.contact__select {
	appearance: none;
	-webkit-appearance: none;
	padding-inline-end: 2.6rem;
	cursor: pointer;
}

/* Rien de choisi : le libellé de l'option vide doit se lire comme un placeholder */
.contact__select:has(option[value=""]:checked) { color: var(--c-faint); }

.contact__select-caret {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: .95rem;
	width: 1.05rem;
	height: 1.05rem;
	transform: translateY(-50%);
	pointer-events: none;
	color: var(--c-muted);
}

/* Sans Customizable Select, la liste est peinte par l'OS : seul un couple
   clair reste lisible, quel que soit le thème de la page. */
@supports not (appearance: base-select) {
	.contact__select option { color: #12121a; background: #ffffff; }
}

/* --- Options « best design » — moteur Customizable Select de maestra.css
       (appearance: base-select + ::picker(select)), repeint avec les tokens
       du thème pour que le panneau suive le clair / sombre du site. */
@supports (appearance: base-select) {
	.contact__select {
		appearance: base-select;
		display: flex;
		align-items: center;
		gap: .6rem;
		padding-inline-end: .95rem;
	}

	/* La flèche vient de ::picker-icon : la nôtre ferait doublon */
	.contact__select-wrap .contact__select-caret { display: none; }

	.contact__select selectedcontent {
		flex: 1 1 auto;
		min-width: 0;
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
	}

	/* Le triangle par défaut fait daté : on repeint un chevron au trait,
	   identique aux icônes SVG du reste de la page (masque, donc thémable). */
	.contact__select::picker-icon {
		content: "";
		flex: none;
		width: 1.05rem;
		height: 1.05rem;
		margin-inline-start: auto;
		background-color: var(--c-muted);
		-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
		mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
		transition: transform .2s var(--ease), background-color .2s var(--ease);
	}
	.contact__select:open::picker-icon {
		transform: rotate(180deg);
		background-color: var(--c-brand);
	}

	/* Panneau ouvert : même traitement que le focus clavier */
	.contact__select:open {
		border-color: color-mix(in srgb, var(--c-brand) 62%, transparent);
		background: color-mix(in srgb, var(--c-bg) 78%, transparent);
		box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-brand) 18%, transparent);
	}

	/* Le panneau vit dans le top layer : il hérite des variables du champ, donc du thème */
	.contact__select::picker(select) {
		appearance: base-select;
		min-width: anchor-size(width);
		margin-block-start: .45rem;
		padding: .35rem;
		border: 1px solid color-mix(in srgb, var(--c-brand) 22%, var(--c-border));
		border-radius: var(--r-md);
		background: var(--c-panel-bg);
		backdrop-filter: blur(18px) saturate(150%);
		-webkit-backdrop-filter: blur(18px) saturate(150%);
		box-shadow: 0 26px 56px -26px rgb(0 0 0 / .78);
		opacity: 1;
		transform: translateY(0);
		transition: opacity .18s var(--ease), transform .18s var(--ease);
	}

	@starting-style {
		.contact__select::picker(select) {
			opacity: 0;
			transform: translateY(-6px);
		}
	}

	.contact__select option {
		display: flex;
		align-items: center;
		gap: .65rem;
		padding: .62rem .7rem;
		border-radius: var(--r-sm);
		font-size: .92rem;
		line-height: 1.3;
		color: var(--c-text);
		background: transparent;
		cursor: pointer;
		transition: background-color .12s var(--ease), color .12s var(--ease);
	}

	.contact__select option:where(:hover, :focus, :active) {
		outline: none;
		background: color-mix(in srgb, var(--c-brand) 16%, transparent);
	}

	.contact__select option:checked { font-weight: 600; }

	/* Ligne d'invite : présente pour l'accessibilité, jamais un choix valable */
	.contact__select option[value=""] { color: var(--c-muted); }

	/* Coche de l'option retenue, renvoyée à droite.
	   Escape \2713 plutôt que le glyphe : pas de mojibake si le CSS perd son charset. */
	.contact__select option::checkmark {
		order: 1;
		margin-inline-start: auto;
		content: "\2713";
		color: var(--c-brand);
		font-weight: 700;
	}
}

/* --- Pied du formulaire */
.contact__actions {
	display: flex;
	flex-direction: column;
	gap: .7rem;
	margin-block-start: .25rem;
}

.contact__submit { align-self: flex-start; }

.contact__legal {
	font-size: clamp(.76rem, .73rem + .15cqi, .83rem);
	line-height: 1.5;
	color: var(--c-faint);
	text-wrap: pretty;
}

/* --- Une colonne : l'argumentaire passe au-dessus du formulaire */
@media (max-width: 980px) {
	.contact__inner { grid-template-columns: minmax(0, 1fr); }
	.contact__pitch { padding-block-start: 0; }
	.contact__card { max-width: 640px; }
}

@media (max-width: 560px) {
	.contact__row { grid-template-columns: minmax(0, 1fr); }
	.contact__submit { align-self: stretch; }
}

/* --- Thème clair */
[data-bs-theme="light"] .contact {
	background: color-mix(in srgb, var(--c-surface-2) 55%, var(--c-bg));
}
/* Poussière light : palette craie et rendu en multiply, sinon les grains
   éclaircissent le papier au lieu de s'y déposer */
[data-bs-theme="light"] .contact__smoke {
	--smoke-low: #eef6ef;
	--smoke-mid: #8fc39c;
	--smoke-high: #3f7d51;
	--smoke-alpha: 0.30;
	background:
		radial-gradient(ellipse 88% 40% at 26% 100%, rgb(23 182 47 / .12), transparent 70%),
		radial-gradient(ellipse 60% 32% at 72% 100%, rgb(95 209 115 / .09), transparent 66%);
}
[data-bs-theme="light"] .contact__smoke-canvas {
	mix-blend-mode: multiply;
}
/* Grains light : craie sombre en multiply. Des grains clairs sur papier blanc
   seraient purement et simplement invisibles */
[data-bs-theme="light"] .contact__dust {
	--dust-color: #2f6b41;
	--dust-opacity: 0.42;
	mix-blend-mode: multiply;
}

[data-bs-theme="light"] .contact__card {
	background: color-mix(in srgb, #fff 88%, transparent);
	border-color: rgba(12, 12, 18, .12);
	box-shadow: 0 20px 44px -30px rgb(12 24 18 / .32);
}
[data-bs-theme="light"] .contact__input {
	background: #ffffff;
	border-color: rgba(12, 12, 18, .16);
}
[data-bs-theme="light"] .contact__input:focus,
[data-bs-theme="light"] .contact__input:focus-visible {
	background: #ffffff;
}

/* input_tel — le plugin force un hover blanc 9 % en dark et un bleu admin
   en light : on les recouvre avec le vert de marque, plus le champ
   recherche / le préfixe drapeau calés sur les inputs du formulaire. */
[data-bs-theme="light"] .contact .iti__dropdown-content {
	background: #ffffff !important;
	border-color: rgba(12, 12, 18, .12) !important;
	box-shadow: 0 20px 44px -24px rgb(12 24 18 / .38) !important;
}
[data-bs-theme="light"] .contact .iti__search-input,
[data-bs-theme="light"] .contact .iti__search-input:focus,
[data-bs-theme="light"] .contact .iti__search-input:focus-visible {
	background: #ffffff !important;
}
[data-bs-theme="light"] .contact .iti__selected-flag {
	background: rgba(12, 12, 18, .04);
}
[data-bs-theme="dark"] .contact .iti__country.iti__highlight,
[data-bs-theme="dark"] .contact .iti__country:hover,
[data-bs-theme="dark"] .contact .iti__country:focus,
html[data-bs-theme="dark"] .contact .iti__country.iti__highlight,
html[data-bs-theme="dark"] .contact .iti__country:hover,
html[data-bs-theme="dark"] .contact .iti__country:focus {
	background: color-mix(in srgb, var(--c-brand) 16%, transparent) !important;
}
[data-bs-theme="dark"] .contact .iti--allow-dropdown .iti__flag-container:hover .iti__selected-flag,
html[data-bs-theme="dark"] .contact .iti--allow-dropdown .iti__flag-container:hover .iti__selected-flag {
	background: var(--c-ghost-bg-hover) !important;
}
[data-bs-theme="light"] .contact__lead {
	color: rgba(18, 18, 26, .82);
}
[data-bs-theme="light"] .contact__point-copy span {
	color: rgba(18, 18, 26, .7);
}
[data-bs-theme="light"] .contact__direct {
	color: rgba(18, 18, 26, .6);
}
[data-bs-theme="light"] .contact__legal {
	color: rgba(18, 18, 26, .58);
}
