@layer reset, tokens, base, components;

/* Barlow auto-hébergé — latin + latin-ext (le vietnamien du sous-ensemble Google n'est pas embarqué). */
@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/barlow-400.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/barlow-400-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("../fonts/barlow-500.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("../fonts/barlow-500-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/barlow-600.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/barlow-600-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("../fonts/barlow-700.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("../fonts/barlow-700-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 800;
	font-display: swap;
	src: url("../fonts/barlow-800.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Barlow";
	font-style: normal;
	font-weight: 800;
	font-display: swap;
	src: url("../fonts/barlow-800-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@layer tokens {
	:root {
		/* Couleurs — variables Figma « Marque / Surface / Sombre / Texte ». */
		--color-navy: #181932;
		--color-blue: #2f5be8;
		--color-blue-dark: #2447be;
		--color-blue-light: #8ca3f5;
		--color-blue-pale: #dde4fc;
		--color-blue-bright: #5a80ff; /* Départ des dégradés — hors palette documentée. */
		--color-white: #ffffff;
		--color-sand: #f8f4f1;
		--color-lavender: #f7f6fb;
		--color-lavender-alt: #f4f5fb;
		--color-rule: #e2e4ef;
		--color-rule-strong: #c9cbd8; /* Puces et filets qui doivent se détacher du filet courant. */
		--color-danger: #b3213a; /* Hors maquette : aucun état d'erreur n'y figure. 6,6:1 sur blanc. */
		--color-dark-900: #101127;
		--color-dark-700: #1d1e3a;
		--color-dark-600: #242645;
		--color-dark-500: #2c2e50;
		--color-dark-400: #3a3c63;
		--color-text: #4a4e66;
		--color-text-muted: #8b8fa6;
		--color-text-on-dark: rgba(255, 255, 255, 0.68);
		--color-rule-on-dark: rgba(255, 255, 255, 0.28);

		/* Typographie — styles Figma, tailles converties en rem sur une base de 16 px. */
		--font-sans: "Barlow", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
		/* Bornes hautes = cotes Figma, atteintes dès 1200 px. Interlignage en rapport. */
		--text-h1: 800 clamp(2rem, 1.318rem + 2.91vw, 3.5rem)/1.15 var(--font-sans); /* 32 → 56 / 64,4 ÷ 56 — ExtraBold, la maquette dit Bold */
		--text-h2: 700 clamp(1.625rem, 1.284rem + 1.46vw, 2.375rem)/1.15 var(--font-sans); /* 26 → 38 / 43,7 ÷ 38 — Bold, la maquette dit SemiBold */

		/* Sert aussi le titre du CTA, à 46 dans la maquette : 2 px n'appellent pas un token. */
		--text-h1-page: 800 clamp(1.75rem, 1.182rem + 2.424vw, 3rem)/1.1 var(--font-sans); /* 28 → 48 / 52,8 ÷ 48 */
		--text-h3-lg: 600 1.25rem/1.4375rem var(--font-sans); /* 20 / 23 */
		--text-h3: 600 1.0625rem/1.225rem var(--font-sans); /* 17 / 19,6 */
		--text-lead: 400 1.0625rem/1.80625rem var(--font-sans); /* 17 / 28,9 */
		--text-body: 400 1.03125rem/1.75rem var(--font-sans); /* 16,5 / 28 */
		--text-small: 400 0.90625rem/1.54375rem var(--font-sans); /* 14,5 / 24,7 */
		--text-eyebrow: 600 0.8125rem/1.375rem var(--font-sans); /* 13 / 22 */
		--text-button: 600 0.9375rem/1.375rem var(--font-sans); /* 15 / 22 */
		--text-name: 700 0.8125rem/1.125rem var(--font-sans); /* 13 / 18 */
		--text-section: 600 0.875rem/1.25rem var(--font-sans); /* 14 / 20 */
		--text-figure: 700 1.875rem/2.0625rem var(--font-sans); /* 30 / 33 */

		/* Interlettrage — Figma exprime ces valeurs en pourcentage, d'où les em. */
		--ls-tight: -0.015em;
		--ls-eyebrow: 0.02em;
		--ls-section: 0.04em;

		/* Un bloc à cheval sur la section précédente doit s'en déduire, pas figer sa valeur. */
		--section-pad: clamp(56px, 7.78vw, 112px); /* 112 dès 1440 de large */

		/* 5,84 et non 5,8333 : à la valeur exacte, le plafond n'est jamais atteint. */
		--section-pad-tight: clamp(42px, 5.84vw, 84px); /* 84 dès 1440 */

		/* Rayons */
		--radius-card: 20px;
		--radius-panel: 16px;
		--radius-media: 12px;
		--radius-pill: 99px;

		/*
		 * Ombres des boutons. Le débord latéral vaut `flou ÷ 2 + étalement` et
		 * doit rester nul, survol compris : au-dessus, il se lit comme un trait.
		 */
		--shadow-btn-primary: 0 12px 22px -11px rgba(47, 91, 232, 0.45);
		--shadow-btn-primary-hover: 0 16px 28px -14px rgba(47, 91, 232, 0.55);
		--shadow-btn-primary-sm: 0 10px 18px -9px rgba(47, 91, 232, 0.45);
		--shadow-btn-primary-sm-hover: 0 13px 22px -11px rgba(47, 91, 232, 0.55);
		/*
		 * Creusé du bas, dosé pour le fond clair : plus opaque, il y noircit le
		 * bord en un trait net. Le rendu sur fond sombre ne fait pas référence.
		 */
		--inset-btn-primary: inset 0 -14px 20px -13px rgba(13, 26, 92, 0.18);
		--shadow-btn-white: 0 10px 18px -9px rgba(24, 25, 50, 0.28);
		--shadow-btn-white-hover: 0 14px 24px -12px rgba(24, 25, 50, 0.34);
		--inset-btn-white: inset 0 -5px 10px rgba(140, 163, 245, 0.18), inset 0 1.5px 0 rgba(255, 255, 255, 0.9);
		--shadow-badge-live: 0 12px 11px rgba(47, 91, 232, 0.6);
		--shadow-raised: 0 14px 18px rgba(24, 25, 50, 0.14), 0 1px 1px rgba(24, 25, 50, 0.04);
		--shadow-soft: 0 14px 36px -18px rgba(24, 25, 50, 0.14), 0 1px 2px rgba(24, 25, 50, 0.04);

		/* Gabarit — 1440 px de contenu utile, hors marges. */
		--content-max: 1440px;
		--gutter: 30px;

		/* En-tête collant de 93 px, plus 20 de respiration sous lui. */
		--ancre-offset: 113px;
	}

	/*
	 * Paliers : téléphone ≤ 640, tablette ≤ 1024, portable ≤ 1440. Une media query
	 * n'acceptant pas de variable, ils sont répétés en clair dans tout le thème —
	 * y compris dans les scripts. Les changer impose de tous les reprendre.
	 */
	@media (max-width: 640px) {
		:root {
			--gutter: 20px;
		}
	}
}

@layer reset {
	*,
	*::before,
	*::after {
		box-sizing: border-box;
	}

	* {
		margin: 0;
	}

	html {
		-webkit-text-size-adjust: 100%;

		/*
		 * Les ancres internes glissent au lieu de sauter, le saut sec se lisant
		 * comme un rechargement. Neutralisé en fin de couche `components`.
		 */
		scroll-behavior: smooth;
	}

	img,
	picture,
	svg,
	video {
		display: block;
		max-width: 100%;
	}

	input,
	button,
	textarea,
	select {
		font: inherit;
		color: inherit;
	}

	/* Les niveaux de titre portent la sémantique, jamais la taille. */
	h1,
	h2,
	h3,
	h4,
	h5,
	h6 {
		font: inherit;
	}

	:focus-visible {
		outline: 2px solid var(--color-blue);
		outline-offset: 3px;
	}
}

@layer base {
	body {
		background: var(--color-white);
		color: var(--color-text);
		font: var(--text-body);
		-webkit-font-smoothing: antialiased;
	}
}

@layer components {
	/* ------------------------------------------------------------------ Grille */

	/* Les marges s'ajoutent en dehors du plafond de contenu, elles ne l'entament pas. */
	.container {
		width: 100%;
		max-width: calc(var(--content-max) + var(--gutter) * 2);
		margin-inline: auto;
		padding-inline: var(--gutter);
	}

	/*
	 * Cibles d'ancre. Sans ce retrait, l'en-tête collant recouvre le haut de la
	 * section qu'on vient d'atteindre — le titre passe dessous et l'arrivée
	 * paraît ratée.
	 */
	section[id],
	.contact-form {
		scroll-margin-top: var(--ancre-offset);
	}

	/* ---------------------------------------------------------------- Boutons */

	.btn {
		display: inline-flex;
		align-items: center;
		border: 0;
		border-radius: var(--radius-pill);
		font: var(--text-button);
		text-decoration: none;
		cursor: pointer;
		transition:
			transform 0.18s ease,
			box-shadow 0.18s ease,
			background-color 0.18s ease,
			border-color 0.18s ease;
	}

	/* La rotation porte sur la pastille, circulaire : inutile d'atteindre le SVG. */
	.btn:hover,
	.btn:focus-visible {
		transform: translateY(-2px);
	}

	.btn:hover .btn__pastille,
	.btn:focus-visible .btn__pastille {
		transform: rotate(45deg);
	}

	.btn__label {
		white-space: nowrap;
	}

	/*
	 * Padding réduit de l'épaisseur de la bordure : Figma dessine les contours en
	 * dedans, et la hauteur de 50 px doit tenir.
	 *
	 * Le liseré est transparent, et non absent, pour que la bordure garde sa
	 * place ; les fonds sombres le rallument par `--btn-rim`.
	 */
	.btn--primary {
		--btn-drop: var(--shadow-btn-primary);
		--btn-drop-hover: var(--shadow-btn-primary-hover);

		gap: 12px;
		padding: 4px 4px 4px 25px;
		border: 1px solid var(--btn-rim, transparent);

		/*
		 * Le liseré du haut est une couche de fond, pas une ombre interne : une
		 * ombre interne s'arrête au bord du padding, laissant voir le pixel de
		 * bordure tout autour du galet. Ne pas le repasser en `inset`.
		 */
		background:
			linear-gradient(rgba(255, 255, 255, 0.45) 0 1.5px, transparent 1.5px) border-box,
			linear-gradient(180deg, var(--color-blue-bright) 0%, var(--color-blue) 55%, var(--color-blue-dark) 100%) border-box;
		box-shadow: var(--btn-drop), var(--inset-btn-primary);
		color: var(--color-white);
	}

	/*
	 * Version compacte de l'en-tête. Se décline par variables, jamais par une
	 * seconde déclaration de `box-shadow` : celle-ci tient au repos mais se fait
	 * écraser au survol par une règle plus spécifique.
	 */
	.btn--sm {
		--btn-drop: var(--shadow-btn-primary-sm);
		--btn-drop-hover: var(--shadow-btn-primary-sm-hover);

		gap: 0;
		padding: 10px 17px; /* 11 / 18 moins la bordure */
		font: 600 0.875rem/1.25rem var(--font-sans); /* 14 / 20 */
	}

	.btn--primary:hover,
	.btn--primary:focus-visible {
		box-shadow: var(--btn-drop-hover), var(--inset-btn-primary);
	}

	.btn--white {
		gap: 12px;
		padding: 5px 5px 5px 26px;
		background: linear-gradient(180deg, var(--color-white) 0%, var(--color-lavender-alt) 100%);
		box-shadow: var(--shadow-btn-white), var(--inset-btn-white);
		color: var(--color-navy);
	}

	.btn--white:hover,
	.btn--white:focus-visible {
		box-shadow: var(--shadow-btn-white-hover), var(--inset-btn-white);
	}

	.btn--soft {
		padding: 14px 24px 14px 26px;
		background: var(--color-lavender-alt);
		color: var(--color-navy);
	}

	/* Bouton discret à pastille, plus compact que le primaire. */
	.btn--soft-pill {
		gap: 12px;
		padding: 5px 5px 5px 20px;
		background: var(--color-lavender-alt);
		color: var(--color-navy);
		font: 600 0.875rem/1.25rem var(--font-sans); /* 14 / 20 */
	}

	.btn--soft-pill:hover,
	.btn--soft-pill:focus-visible {
		background: var(--color-blue-pale);
	}

	.btn--soft-pill .btn__pastille {
		width: 34px;
		height: 34px;
		background: var(--color-blue);
		color: var(--color-white);
	}

	.btn--soft:hover,
	.btn--soft:focus-visible {
		background: var(--color-blue-pale);
	}

	.btn--ghost {
		padding: 12.5px 22.5px;
		border: 1.5px solid var(--color-rule-on-dark);
		background: transparent;
		color: var(--color-white);
	}

	.btn--ghost:hover,
	.btn--ghost:focus-visible {
		border-color: rgba(255, 255, 255, 0.5);
		background: rgba(255, 255, 255, 0.06);
	}

	.btn__pastille {
		display: grid;
		flex-shrink: 0;
		place-items: center;
		width: 40px;
		height: 40px;
		border-radius: 50%;
		transition: transform 0.18s ease;
	}

	.btn--primary .btn__pastille {
		background: var(--color-white);
		color: var(--color-blue);
	}

	.btn--white .btn__pastille {
		background: var(--color-blue);
		color: var(--color-white);
	}

	/* --------------------------------------------------------------- Étiquettes */

	.badge {
		display: inline-flex;
		align-items: center;
		border-radius: var(--radius-pill);
		white-space: nowrap;
	}

	.badge--eyebrow {
		padding: 6px 14px;
		background: var(--color-blue-pale);
		color: var(--color-blue-dark);
		font: var(--text-eyebrow);
		letter-spacing: var(--ls-eyebrow);
	}

	.badge--live {
		--dot-size: 7px;
		--dot-color: var(--color-white);

		gap: 8px;
		padding: 8px 16px;
		background: linear-gradient(180deg, var(--color-blue-bright) 0%, var(--color-blue-dark) 100%);
		box-shadow: var(--shadow-badge-live), inset 0 1px 0 rgba(255, 255, 255, 0.4);
		color: var(--color-white);
		font: 700 0.78125rem/1.125rem var(--font-sans); /* 12,5 / 18 — hors échelle documentée */
	}

	.badge--status {
		gap: 9px;
		padding: 9px 17px;
		border: 1px solid var(--color-rule);
		background: var(--color-white);
		box-shadow: var(--shadow-raised);
		color: var(--color-navy);
		font: 600 0.84375rem/1.25rem var(--font-sans); /* 13,5 / 20 — hors échelle documentée */
	}

	/* Étiquette pleine, sans relief : posée sur un fond clair et non sur un visuel. */
	.badge--soft {
		--dot-size: 6px;
		--dot-color: var(--color-blue-dark);

		gap: 8px;
		padding: 8px 14px;
		background: var(--color-blue-pale);
		color: var(--color-blue-dark);
		font: 600 0.78125rem/1.125rem var(--font-sans); /* 12,5 / 18 */
	}

	/* ------------------------------------------------------------------ Cartes */

	.card {
		display: flex;
		flex-direction: column;
		border-radius: var(--radius-card);
	}

	.card__name {
		font: var(--text-name);
	}

	.card__icon {
		display: flex;
		flex-shrink: 0;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		border-radius: var(--radius-media);
		background: var(--color-blue-pale);
		transition: background-color 0.2s ease;
	}

	/* Pictogramme déposé, dans une pastille de carte comme dans une étoile. */
	.card__icon img,
	.rosette img {
		width: 26px;
		height: 26px;
		object-fit: contain;
	}

	.card--dark .card__icon {
		background: rgba(255, 255, 255, 0.08);
	}

	/*
	 * Sélecteur composé pour passer devant `.link-arrow`, déclaré plus bas.
	 */
	.link-arrow.card__link {
		gap: 10px;
		padding-top: 8px;
		font: 500 0.875rem/1.25rem var(--font-sans); /* 14 / 20 */
		letter-spacing: 0.01em;
	}

	/* Sur fond navy, le bleu du lien fléché passerait sous le seuil de contraste. */
	.card--dark .card__link {
		color: var(--color-blue-light);
	}

	/* Contrepartie assumée : le texte de la carte n'est plus sélectionnable. */
	.card--clickable {
		position: relative;
		transition:
			transform 0.2s ease,
			box-shadow 0.2s ease,
			border-color 0.2s ease;
	}

	.card--clickable .card__link::after {
		content: "";
		position: absolute;
		inset: 0;
	}

	.card--clickable:hover,
	.card--clickable:focus-within {
		transform: translateY(-3px);
		border-color: var(--color-blue-light);
		box-shadow: var(--shadow-soft);
	}

	.card--clickable:hover .card__icon,
	.card--clickable:focus-within .card__icon {
		background: var(--color-blue);
	}

	/* Sans bordure à colorer, la carte navy s'appuie sur un halo bleu. */
	.card--dark.card--clickable:hover,
	.card--dark.card--clickable:focus-within {
		box-shadow: 0 12px 28px -12px rgba(47, 91, 232, 0.55);
	}

	.card__title {
		color: var(--color-navy);
		font: var(--text-h3);
	}

	.card__text {
		color: var(--color-text);
		font: var(--text-small);
	}

	.card--service,
	.card--sovereign {
		padding: 26px 24px;
		border: 1px solid var(--color-rule);
		background: var(--color-white);
	}

	.card--service {
		gap: 9px;
	}

	.card--service .card__name {
		color: var(--color-blue);
	}

	.card--dark {
		gap: 9px;
		padding: 34px 24px 26px;
		background: var(--color-navy);
	}

	.card--dark .card__name {
		color: var(--color-blue-light);
	}

	.card--dark .card__title {
		color: var(--color-white);
	}

	.card--dark .card__text {
		color: var(--color-text-on-dark);
	}

	.card--feature {
		gap: 10px;
		padding: 30px 28px;
		background: var(--color-blue-pale);
	}

	.card--feature .card__name {
		color: var(--color-blue-dark);
	}

	.card--feature .card__title {
		font: var(--text-h3-lg);
	}

	.card--feature .card__text {
		font: 400 0.9375rem/1.5625rem var(--font-sans); /* 15 / 25 — hors échelle documentée */
	}

	.card--sovereign {
		gap: 7px;
	}

	.card--sovereign .card__title {
		margin-top: 9px; /* Décalage de l'encart interne de la maquette. */
		font: 600 1.03125rem/1.1875rem var(--font-sans); /* 16,5 / 19 — hors échelle documentée */
	}

	.card--sovereign .card__text {
		font: 400 0.875rem/1.4375rem var(--font-sans); /* 14 / 23 — hors échelle documentée */
	}

	.card__media {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100%;
		aspect-ratio: 280 / 140;
		border-radius: var(--radius-media);
		background: var(--color-lavender-alt);
		color: var(--color-text-muted);
		font: 500 0.84375rem/1.25rem var(--font-sans); /* 13,5 / 20 — hors échelle documentée */
	}

	/* --------------------------------------------------------------- Formulaires */

	/* Partagés par le formulaire de contact et la modale des ressources. */
	.form-grid {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 14px;
	}

	.field {
		display: flex;
		flex-direction: column;
		gap: 6px;
	}

	/* Une zone de texte occupe la ligne entière. */
	.field--wide {
		grid-column: 1 / -1;
	}

	.field__label {
		color: var(--color-navy);
		font: 600 0.8125rem/1.125rem var(--font-sans); /* 13 / 18 */
	}

	.field__control {
		width: 100%;
		height: 48px;
		padding: 0 14px;
		border: 1px solid var(--color-rule);
		border-radius: var(--radius-media);
		background: var(--color-lavender-alt);
		color: var(--color-navy);
		font: var(--text-body);
		transition: border-color 0.18s ease, box-shadow 0.18s ease;
	}

	.field__control--area {
		height: 130px;
		padding: 12px 14px;
		resize: vertical;
	}

	.field__control:focus-visible {
		border-color: var(--color-blue);
		box-shadow: 0 0 0 3px rgba(47, 91, 232, 0.18);
		outline: none;
	}

	/*
	 * Hors maquette : aucun état d'erreur ni de confirmation n'y figure, ces règles
	 * restent à faire valider. Une seule couleur nouvelle, les nuances en dérivent.
	 */
	.form-feedback {
		display: flex;
		align-items: flex-start;
		gap: 10px;
		margin-top: 18px;
		padding: 12px 14px;
		border-left: 3px solid var(--color-danger);
		border-radius: var(--radius-media);
		background: color-mix(in srgb, var(--color-danger) 7%, var(--color-white));
		color: var(--color-danger);
		font: 500 0.875rem/1.375rem var(--font-sans); /* 14 / 22 */
	}

	/*
	 * Pas de filet à gauche sur la confirmation : le liseré est une alerte, et
	 * l'envoi réussi n'en est pas une. Le retrait reprend les 3 px de la bordure
	 * pour que le texte reste aligné avec celui du bandeau d'erreur.
	 */
	.form-feedback--ok {
		border-left: 0;
		padding-left: 17px;
		background: var(--color-blue-pale);
		color: var(--color-blue-dark);
	}

	.form-feedback__icon {
		display: grid;
		flex-shrink: 0;
		place-items: center;
		width: 20px;
		height: 20px;
		border-radius: 50%;
		background: var(--color-blue);
		color: var(--color-white);
	}

	.form-feedback__icon svg {
		width: 11px;
		height: 11px;
	}

	.field__error {
		color: var(--color-danger);
		font: 500 0.75rem/1.125rem var(--font-sans); /* 12 / 18 */
	}

	.field__control.is-invalid {
		border-color: var(--color-danger);
		background: color-mix(in srgb, var(--color-danger) 4%, var(--color-white));
	}

	.field__control.is-invalid:focus-visible {
		border-color: var(--color-danger);
		box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 18%, transparent);
	}

	/* ----------------------------------------------------------------- Marque */

	.brand {
		display: flex;
		align-items: center;
		gap: 10px;
		text-decoration: none;
	}

	.brand__mark {
		display: grid;
		flex-shrink: 0;
		place-items: center;
		width: 30px;
		height: 30px;
		border-radius: 9px;
		background: var(--color-blue);
		color: var(--color-white);
		font: var(--text-name);
	}

	.brand__name {
		color: var(--color-navy);
		font: 700 1.0625rem/1.5rem var(--font-sans); /* 17 / 24 */
	}

	.brand--light .brand__name {
		color: var(--color-white);
	}

	/* Au-delà de 61 px, c'est le logo qui fixe la hauteur de l'en-tête. */
	.brand__logo {
		width: auto;
		height: 80px;
		max-width: 640px;
		object-fit: contain;
	}

	/* ---------------------------------------------------------------- En-tête */

	/* Lien d'évitement : hors écran tant qu'il n'a pas le focus. */
	/* Libellé réservé aux lecteurs d'écran : retiré de l'affichage, pas de l'arbre. */
	.screen-reader-text {
		position: absolute;
		width: 1px;
		height: 1px;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap;
	}

	.skip-link {
		position: absolute;
		top: 0;
		left: -9999px;
		z-index: 200;
		padding: 12px 20px;
		border-radius: 0 0 var(--radius-media) 0;
		background: var(--color-blue);
		color: var(--color-white);
		font: var(--text-button);
		text-decoration: none;
	}

	.skip-link:focus {
		left: 0;
	}

	.site-header {
		position: sticky;
		top: 0;
		z-index: 100;
		border-bottom: 1px solid var(--color-rule);
		background: var(--color-white);
	}

	/*
	 * 73 px = les 74 de la maquette moins le filet bas. La barre s'agrandit si
	 * le logo dépasse cette hauteur, plutôt que de le laisser déborder.
	 */
	.site-header__inner {
		display: flex;
		align-items: center;
		justify-content: space-between;
		min-height: 73px;
		padding-block: 6px;
	}

	.nav {
		display: flex;
		align-items: center;
		gap: 26px;
	}

	.nav__item {
		position: relative;
	}

	.nav__link {
		display: flex;
		align-items: center;
		gap: 7px;
		padding: 0;
		border: 0;
		background: none;
		color: var(--color-text);
		font: 500 0.9375rem/1.375rem var(--font-sans); /* Medium 15 / 22 */
		text-decoration: none;
		cursor: pointer;
		transition: color 0.18s ease;
	}

	.nav__link:hover,
	.nav__link:focus-visible {
		color: var(--color-navy);
	}

	.nav__chevron {
		display: flex;
		transition: transform 0.2s;
	}

	.nav__link[aria-expanded="true"] .nav__chevron {
		transform: rotate(180deg);
	}

	/* Sous-menu absent de la maquette : apparence déduite de la charte, à valider. */
	.nav__sub {
		position: absolute;
		top: calc(100% + 18px);
		left: -12px;
		z-index: 1;
		display: flex;
		flex-direction: column;
		min-width: 264px;
		margin: 0;
		padding: 10px;
		border: 1px solid var(--color-rule);
		border-radius: var(--radius-media);
		background: var(--color-white);
		box-shadow: var(--shadow-raised);
		list-style: none;
	}

	.nav__sub[hidden] {
		display: none;
	}

	.nav__sub-link {
		display: block;
		padding: 9px 12px;
		border-radius: 8px;
		color: var(--color-text);
		font: 500 0.9375rem/1.375rem var(--font-sans);
		text-decoration: none;
	}

	.nav__sub-link:hover,
	.nav__sub-link:focus-visible {
		background: var(--color-lavender-alt);
		color: var(--color-navy);
	}

	/* ------------------------------------------------------------- Méga-menu */

	/*
	 * `static` retire son repère à l'entrée : le panneau se cale alors sur
	 * l'en-tête, déjà positionné par son `sticky`.
	 *
	 * Ne pas positionner `.site-header__inner`, qui deviendrait aussi le repère
	 * du tiroir mobile. À garder après `.nav__sub`, dont il dépend par l'ordre.
	 */
	.nav__item--mega {
		position: static;
	}

	/* Le retrait latéral refait le calcul de `.container` : pas de conteneur imbriqué. */
	.nav__sub--mega {
		top: 100%;
		right: 0;
		left: 0;
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		min-width: 0;
		padding: 30px max(var(--gutter), (100% - var(--content-max)) / 2);
		border: 0;
		border-bottom: 1px solid var(--color-rule);
		border-radius: 0;
	}

	/* La colonne d'accroche n'apparaît que si elle est renseignée : sans elle,
	   la grille reprend toute la largeur au lieu de rester dans sa colonne. */
	.nav__sub--mega:has(.nav__mega-intro) {
		grid-template-columns: minmax(0, 27%) minmax(0, 1fr);
	}

	/* ------------------------------------------------- Colonne d'accroche */

	.nav__mega-intro {
		display: flex;
		flex-direction: column;
		gap: 12px;
		padding-right: 34px;
		border-right: 1px solid var(--color-rule);
	}

	.nav__mega-eyebrow {
		color: var(--color-blue);
		font: var(--text-name);
	}

	.nav__mega-heading {
		color: var(--color-navy);
		font: 700 1.25rem/1.625rem var(--font-sans); /* 20 / 26 */
	}

	.nav__mega-lead {
		color: var(--color-text-muted);
		font: 400 0.875rem/1.5rem var(--font-sans); /* 14 / 24 */
	}

	/* ----------------------------------------------------- Grille d'entrées */

	.nav__mega-grid {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 2px;
		margin: 0;
		padding: 0 0 0 18px;
		list-style: none;
	}

	.nav__mega-link {
		display: flex;
		flex-direction: column;
		gap: 6px;
		height: 100%;
		padding: 14px 16px 18px;
		border-radius: var(--radius-media);
		color: var(--color-text);
		text-decoration: none;
		transition: background-color 0.18s ease;
	}

	.nav__mega-link:hover,
	.nav__mega-link:focus-visible {
		background: var(--color-lavender-alt);
	}

	.nav__mega-icon {
		display: block;
		color: var(--color-blue);
	}

	/* Marge négative : dessinés pour la rosace, ces tracés n'ont que 24 px
	   d'encre dans un cadre de 46. Les fichiers sont partagés avec les cartes. */
	.nav__mega-icon svg {
		display: block;
		width: 46px;
		height: 46px;
		margin: -11px;
	}

	/* Un visuel déposé n'a pas ces blancs : il se pose à la cote utile. */
	.nav__mega-icon img {
		display: block;
		width: 24px;
		height: 24px;
		object-fit: contain;
	}

	.nav__mega-name {
		color: var(--color-navy);
		font: 700 0.9375rem/1.375rem var(--font-sans); /* 15 / 22 */
	}

	/* Navy plutôt que bleu : sous le nom, le bleu se lit comme un second lien
	   à l'intérieur du lien. */
	.nav__mega-title {
		color: var(--color-navy);
		font: 500 0.875rem/1.3125rem var(--font-sans); /* 14 / 21 */
	}

	.nav__mega-text {
		color: var(--color-text-muted);
		font: 400 0.8125rem/1.3125rem var(--font-sans); /* 13 / 21 */
	}

	/* Dissous au-dessus de 1024 px ; il ne reprend corps qu'en tiroir. */
	.site-header__panel {
		display: contents;
	}

	.burger {
		display: none;
		place-items: center;
		width: 44px; /* Cible tactile de 44 px, minimum WCAG 2.5.8. */
		height: 44px;
		padding: 0;
		border: 0;
		background: none;
		color: var(--color-navy);
		cursor: pointer;
	}

	/*
	 * Trois vrais éléments, jamais des `box-shadow` : une ombre externe n'est
	 * peinte qu'au dehors, et à l'ouverture le fond devenant transparent, elle
	 * serait rognée — le bouton disparaîtrait.
	 */
	.burger__bars,
	.burger__bars::before,
	.burger__bars::after {
		width: 22px;
		height: 2px;
		border-radius: 2px;
		background: currentcolor;
		transition: transform 0.18s ease, background-color 0.18s ease;
	}

	.burger__bars {
		position: relative;
	}

	.burger__bars::before,
	.burger__bars::after {
		content: "";
		position: absolute;
		left: 0;
	}

	.burger__bars::before {
		top: -7px;
	}

	.burger__bars::after {
		top: 7px;
	}

	.burger[aria-expanded="true"] .burger__bars {
		background: transparent;
	}

	.burger[aria-expanded="true"] .burger__bars::before {
		transform: translateY(7px) rotate(45deg);
	}

	.burger[aria-expanded="true"] .burger__bars::after {
		transform: translateY(-7px) rotate(-45deg);
	}

	/* ----------------------------------------------------------- Pied de page */

	.site-footer {
		position: relative;
		overflow: hidden;
		background: var(--color-dark-900);
		color: var(--color-white);
	}

	.site-footer__watermark {
		position: absolute;
		top: 140px;
		left: calc(50% + 178px); /* x 898 dans le cadre de 1440 centré */
		color: rgba(255, 255, 255, 0.03);
		font: 700 15rem/1 var(--font-sans); /* 240 / 240 */
		letter-spacing: -0.05em; /* -12 px sur 240 */
		user-select: none;
	}

	.site-footer__inner {
		position: relative;
	}

	.site-footer__top {
		display: flex;
		align-items: flex-start;
		gap: 48px;
		padding-block: 72px 56px;
	}

	.site-footer__brand-col {
		display: flex;
		flex-direction: column;
		flex-shrink: 0;
		gap: 18px;
		width: 392px;
	}

	.site-footer__baseline {
		color: rgba(255, 255, 255, 0.6);
		font: var(--text-small);
	}

	.site-footer__contact {
		display: flex;
		flex-direction: column;
		gap: 8px;
		margin: 0;
		padding-top: 4px;
		color: rgba(255, 255, 255, 0.75);
		font: 400 0.875rem/1.375rem var(--font-sans); /* 14 / 22 */
		font-style: normal; /* <address> est italique par défaut */
	}

	.site-footer__col {
		display: flex;
		flex: 1;
		flex-direction: column;
		gap: 12px;
		min-width: 0;
	}

	.site-footer__heading {
		padding-bottom: 8px;
		color: var(--color-white);
		font: var(--text-section);
		letter-spacing: var(--ls-section);
	}

	/* Police et couleur portées par la liste : les <li> et les liens en héritent. */
	.site-footer__list {
		display: flex;
		flex-direction: column;
		gap: 12px;
		margin: 0;
		padding: 0;
		color: rgba(255, 255, 255, 0.6);
		font: 400 0.90625rem/1.375rem var(--font-sans); /* 14,5 / 22 */
		list-style: none;
	}

	.site-footer__legal {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding-block: 26px;
		border-top: 1px solid var(--color-dark-600);
		color: rgba(255, 255, 255, 0.45);
		font: 400 0.84375rem/1.25rem var(--font-sans); /* 13,5 / 20 */
	}

	.site-footer__legal-links {
		display: flex;
		gap: 22px;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	/*
	 * Les liens héritent de leur conteneur — c'est lui qui porte la couleur.
	 * Sans `inherit` ils repartiraient sur le bleu par défaut du navigateur.
	 */
	.site-footer a {
		color: inherit;
		text-decoration: none;
		transition: color 0.18s ease;
	}

	.site-footer a:hover,
	.site-footer a:focus-visible {
		color: var(--color-white);
	}

	/* --------------------------------------------------------------- Sections */

	.section {
		padding-block: var(--section-pad);
		/* Le décor de points déborde volontairement : on interdit le défilement latéral. */
		overflow-x: clip;
	}

	/*
	 * Trois quarts du rythme courant, et fluide comme lui : figée à 84 px, une
	 * section « resserrée » serait la plus aérée sur téléphone, où `.section`
	 * retombe à 56.
	 */
	.section--tight {
		padding-block: var(--section-pad-tight);
	}

	/*
	 * `clip` et non `hidden` : `hidden` ferait de la section un conteneur de
	 * défilement, et les animations pilotées par le scroll s'y résoudraient
	 * contre un conteneur immobile.
	 */
	.section--lavender,
	.section--sand {
		overflow: clip;
	}

	.section--deep {
		--title-color: var(--color-white);
		--text-color: rgba(255, 255, 255, 0.72);
		--btn-rim: var(--color-rule-on-dark);

		background: var(--color-navy);
		color: var(--color-white);
	}

	.section--lavender {
		background: var(--color-lavender);
	}

	.section--sand {
		background: var(--color-sand);
	}

	/*
	 * Les couleurs passent par des variables : une section sombre les redéfinit
	 * sur elle-même plutôt que de redéclarer la typographie.
	 */
	.section__title {
		color: var(--title-color, var(--color-navy));
		font: var(--text-h2);
		letter-spacing: var(--ls-tight);
	}

	.section__text {
		color: var(--text-color, var(--color-text));
		font: var(--text-lead);
	}

	/*
	 * Surligneur d'un mot dans un titre. Les retraits et l'interlignage sont
	 * exprimés en em pour garder les proportions de la maquette (2/9/4 px et
	 * 68,48 d'interlignage pour un corps de 56) quel que soit le niveau de titre.
	 */
	.highlight {
		display: inline-block;
		padding: 0.036em 0.161em 0.071em;
		border-radius: 0.161em;
		background: linear-gradient(90deg, var(--color-blue) 0%, var(--color-blue-dark) 100%);
		color: var(--color-white);
		line-height: 1.223em;
		transform: rotate(-1.2deg);
	}

	/* Deux colonnes texte / média, alternées selon l'ordre du balisage. */
	.split {
		display: flex;
		align-items: center;
		gap: var(--split-gap, 64px);
	}

	.split--tight {
		--split-gap: 56px;
	}

	.split--wide {
		--split-gap: 72px;
	}

	.split__text {
		display: flex;
		flex: 1;
		flex-direction: column;
		gap: 16px;
		min-width: 0;
	}

	/* ------------------------------------------------------------------ Médias */

	.media {
		position: relative;
		flex-shrink: 0;
	}

	/*
	 * Décor de taille fixe, positionné en proportion du cadre média.
	 *
	 * Aucun `z-index` ici : l'ordre de peinture est celui du DOM. Le motif doit
	 * précéder `.media-frame` dans le balisage, les étiquettes le suivre.
	 */
	.media__dots {
		position: absolute;
		top: 62%;
		width: 240px;
		height: 240px;
		background: url("../img/dots.svg") center / contain no-repeat;
		animation: dots-drift 9s ease-in-out infinite alternate;
	}

	.media__dots--start {
		left: -14%;
	}

	.media__dots--end {
		left: 69%;
		animation-delay: -4.5s;
	}

	@keyframes dots-drift {
		from {
			transform: translate3d(0, 0, 0);
		}

		to {
			transform: translate3d(8px, -16px, 0);
		}
	}

	.media-frame {
		position: relative;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 100%;
		height: 100%;
		overflow: hidden;
		border: 1px solid var(--color-rule);
		border-radius: var(--radius-card);
		background: var(--color-lavender-alt);
		box-shadow: var(--shadow-soft);
	}

	.media-frame img,
	.card__media img,
	.cta__visual img,
	.page-cta__visual img,
	.contact-map__figure img,
	.browser__screen img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	/*
	 * Emplacement d'un visuel en vis-à-vis d'une colonne de texte. Le rapport
	 * d'image varie d'une page à l'autre — 534/380 à l'accueil, 534/400 sur les
	 * pages intérieures — d'où une variable plutôt qu'un second modificateur.
	 */
	.media--split {
		flex: 0 0 47.17%; /* 534 / 1132 */
		aspect-ratio: var(--media-ratio, 534 / 380);
	}

	/* ------------------------------------------------- Décors de section */

	/*
	 * Trame de 54 px posée en fond de section sombre : hero de l'accueil, CTA
	 * des pages intérieures. Partagée, donc ici et non dans une feuille de page.
	 */
	.grid-lines {
		position: absolute;
		top: 0;
		right: 0;
		left: 0;
		/* La maquette arrête la trame avant le bas de la section sur les CTA hauts. */
		height: var(--grid-height, 100%);
		background-image:
			repeating-linear-gradient(to right, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 54px),
			repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 54px);
	}

	/* Halo radial diffus. Diamètre, couleur, flou et position réglés par l'hôte. */
	.halo {
		position: absolute;
		width: var(--halo-size, 620px);
		height: var(--halo-height, var(--halo-size, 620px));
		background: radial-gradient(ellipse at center, var(--halo-color, rgba(47, 91, 232, 0.35)) 0%, transparent 100%);
		filter: blur(var(--halo-blur, 45px));
	}

	/* Chapeau de section. La largeur est une contrainte de lecture, pas de grille. */
	.sec-head {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 16px;
		width: var(--head-width, 720px);
		max-width: 100%;
		margin-inline: auto;
		text-align: center;
	}

	.banner {
		--title-color: var(--color-white);
		--text-color: rgba(255, 255, 255, 0.75);

		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 24px;
		padding: var(--banner-padding, 24px 30px);
		border-radius: var(--radius-card);
		background: var(--color-navy);
	}

	.banner__text {
		width: 620px;
		max-width: 100%;
		color: rgba(255, 255, 255, 0.75);
		font: 400 0.9375rem/1.5625rem var(--font-sans); /* 15 / 25 */
	}

	/* Numéro de téléphone posé à côté du bouton d'un bloc d'appel à l'action. */
	.phone-link {
		color: var(--color-white);
		font: 600 1.03125rem/1.5rem var(--font-sans); /* 16,5 / 24 */
		text-decoration: none;
	}

	/* Pastille translucide posée sur un visuel clair. */
	.glass-pill {
		--dot-size: 7px;

		display: flex;
		align-items: center;
		gap: 8px;
		padding: 8px 15px; /* 9 / 16 moins la bordure */
		border: 1px solid rgba(24, 25, 50, 0.08);
		border-radius: var(--radius-pill);
		background: rgba(255, 255, 255, 0.72);
		backdrop-filter: blur(4px);
		color: var(--color-navy);
		font: 600 0.8125rem/1.125rem var(--font-sans); /* 13 / 18 */
		white-space: nowrap;
	}

	/*
	 * Macaron rond. Le diamètre pilote les corps de texte, exprimés en em : la
	 * maquette décline le même macaron à 132 px sur l'accueil et 176 ailleurs,
	 * dans les mêmes proportions. Le positionnement reste à la charge de l'hôte.
	 */
	.sticker {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 0.023em;
		width: var(--sticker-size, 132px);
		height: var(--sticker-size, 132px);
		border: 2px solid rgba(255, 255, 255, 0.3);
		border-radius: 50%;
		background: linear-gradient(180deg, var(--color-blue-bright) 0%, var(--color-blue) 55%, var(--color-blue-dark) 100%);
		box-shadow: 0 18px 30px rgba(13, 26, 92, 0.4);
		color: var(--color-white);
		font-size: var(--sticker-size, 132px);
	}

	.sticker__title {
		font: 700 0.0795em/1.238 var(--font-sans); /* 10,5 / 13 pour un macaron de 132 */
		letter-spacing: 0.06em;
	}

	.sticker__brand {
		color: rgba(255, 255, 255, 0.75);
		font: 700 0.0644em/1.294 var(--font-sans); /* 8,5 / 11 pour un macaron de 132 */
		letter-spacing: 0.12em;
	}

	/* Variante à chiffre, sur les macarons de page intérieure. */
	.sticker__figure {
		font: 700 0.2273em/1.1 var(--font-sans); /* 40 / 44 pour un macaron de 176 */
		letter-spacing: -0.02em;
	}

	/* ------------------------------------------------------------------ Divers */

	.link-arrow {
		display: inline-flex;
		align-items: center;
		gap: 9px;
		color: var(--color-blue);
		font: var(--text-button);
		text-decoration: none;
	}

	.link-arrow svg {
		transition: transform 0.18s ease;
	}

	.link-arrow:hover svg,
	.link-arrow:focus-visible svg {
		transform: translateX(3px);
	}

	/* Apparition à l'entrée dans le viewport — n'agit que si le script l'active. */
	.reveal {
		transition:
			opacity 0.55s cubic-bezier(0.22, 0.61, 0.36, 1),
			transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
		transition-delay: calc(var(--reveal-index, 0) * 70ms);
	}

	.has-reveal .reveal {
		opacity: 0;
		transform: translateY(24px);
	}

	.has-reveal .reveal.is-visible {
		opacity: 1;
		transform: none;
	}

	/* Pastille ronde : taille et couleur pilotées par le composant hôte. */
	.dot {
		flex-shrink: 0;
		width: var(--dot-size, 8px);
		height: var(--dot-size, 8px);
		border-radius: 50%;
		background: var(--dot-color, var(--color-blue));
	}

	/* Élément posé en absolu sur son parent, coordonnées fournies en ligne. */
	.pinned {
		position: absolute;
		top: var(--y);
		left: var(--x);
	}

	/*
	 * Parallaxe au défilement, sans JavaScript.
	 *
	 * C'est le resserrement de la course sur les 30 % centraux qui rend le
	 * mouvement lisible, pas l'amplitude : au-delà de 50 px les puces quittent
	 * le cadre. `site.js` reprend ces bornes à l'identique.
	 */
	@keyframes pinned-parallax {
		from {
			transform: translateY(var(--drift, 0px));
		}

		to {
			transform: translateY(calc(var(--drift, 0px) * -1));
		}
	}

	/* Sous 641 px les étiquettes passent sous le visuel : plus rien à faire dériver. */
	@supports (animation-timeline: view()) {
		@media (min-width: 641px) {
			.media {
				view-timeline-name: --media-view;
			}

			.pinned {
				animation: pinned-parallax linear both;
				animation-timeline: --media-view;
				animation-range: cover 35% cover 65%;
			}
		}
	}

	/* Étoile élargie à 56 : aux 46 de la maquette, le glyphe bute dans ses creux. */
	.rosette {
		display: grid;
		flex-shrink: 0;
		place-items: center;
		width: 56px;
		height: 56px;
		background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 46 46'%3E%3Cpath d='M23 0L27.8 5.6L34.8 3.6L36.8 10.6L46 23L40.4 27.8L42.4 34.8L35.4 36.8L23 46L18.2 40.4L11.2 42.4L9.2 35.4L0 23L5.6 18.2L3.6 11.2L10.6 9.2L23 0Z' fill='%23DDE4FC'/%3E%3C/svg%3E") center / contain no-repeat;
		color: var(--color-blue-dark);
	}

	/* À garder après `.rosette`, dont le raccourci `background` écraserait l'image. */
	.rosette--dark {
		background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 46 46'%3E%3Cpath d='M23 0L27.8 5.6L34.8 3.6L36.8 10.6L46 23L40.4 27.8L42.4 34.8L35.4 36.8L23 46L18.2 40.4L11.2 42.4L9.2 35.4L0 23L5.6 18.2L3.6 11.2L10.6 9.2L23 0Z' fill='%23242645'/%3E%3C/svg%3E");
		color: var(--color-blue-light);
	}

	/* ------------------------------------- Pages intérieures — socle commun */

	/*
	 * Hero et CTA sont préfixés `page-` : l'accueil définit déjà `.hero` et `.cta`,
	 * et les feuilles de page étant chargées conditionnellement, la collision ne
	 * se verrait que le jour où les deux se croiseraient.
	 */

	.breadcrumb {
		display: flex;
		gap: 9px;
		color: var(--color-navy);
		font: 400 0.84375rem/1.25rem var(--font-sans); /* 13,5 / 20 */
	}

	.breadcrumb a,
	.breadcrumb__sep {
		color: var(--color-text-muted);
		text-decoration: none;
		transition: color 0.18s ease;
	}

	.breadcrumb a:hover,
	.breadcrumb a:focus-visible {
		color: var(--color-navy);
	}

	.page-hero {
		position: relative;
		overflow: clip;
		padding-block: 56px 84px;
	}

	.page-hero__halo {
		--halo-color: rgba(47, 91, 232, 0.1);
		--halo-blur: 80px;

		top: -180px;
		left: calc(50% + 260px); /* x 980 dans le cadre de 1440 centré */
	}

	/*
	 * 568 et 484 sur les 1132 utiles ; les 16 px restants tombent après le visuel.
	 * L'écart de `.split__text` est annulé : la maquette rythme cette colonne par
	 * des retraits propres à chaque bloc, qui s'y additionneraient sinon.
	 */
	.page-hero__inner > .split__text {
		flex: 0 0 50.18%; /* 568 / 1132 */
		gap: 0;
	}

	.page-hero__title {
		padding-top: 30px;
		color: var(--color-navy);
		font: var(--text-h1-page);
		letter-spacing: var(--ls-tight);
	}

	.page-hero__lead {
		display: flex;
		flex-direction: column;
		gap: 14px;
		padding-top: 22px;
	}

	/* Premier paragraphe en avant : plus gros, plus gras, en navy. */
	.page-hero__intro {
		color: var(--color-navy);
		font: 500 1.125rem/1.6 var(--font-sans); /* 18 / 28,8 */
	}

	.page-hero__cta {
		display: flex;
		padding-top: 32px;
	}

	/* `.pinned` apporte la dérive au défilement ; les coordonnées viennent d'ici. */
	.page-hero__pills {
		--drift: 26px;

		top: 83.21%; /* 466 / 560 */
		left: 12.81%; /* 62 / 484 */
		display: flex;
		gap: 9px;
	}

	/* Le cadre ne remplit pas le bloc : il est décalé à droite et plus court. */
	.media--portrait {
		flex: 0 0 42.76%; /* 484 / 1132 */
		aspect-ratio: 484 / 560;
	}

	.media--portrait .media-frame {
		position: absolute;
		top: 0;
		left: 9.09%; /* 44 / 484 */
		width: 90.91%; /* 440 / 484 */
		height: 92.86%; /* 520 / 560 */
		box-shadow: var(--shadow-soft);
	}

	/*
	 * Partagée par À propos et les pages de service, d'où les variables. La place
	 * du chiffre se décide dans le balisage, jamais par une variante CSS.
	 */
	.deflist {
		margin: 0;
	}

	.deflist__row {
		display: flex;
		gap: 56px;
		padding-block: var(--deflist-pad, 38px);
		border-top: 1px solid var(--color-rule);
	}

	.deflist__label {
		display: flex;
		flex: 0 0 var(--deflist-label, 22.97%); /* 260 / 1132 */
		flex-direction: column;
		gap: 16px;
	}

	.deflist__title {
		color: var(--deflist-title-color, var(--color-blue-dark));
		font: 600 1.0625rem/1.4529 var(--font-sans); /* 17 / 24,7 */
	}

	/* Chiffre en contour : la maquette le pose sans remplissage. */
	.deflist__figure {
		color: transparent;
		font: 700 var(--deflist-figure, 4.5rem)/0.9444 var(--font-sans);
		letter-spacing: -0.04em;
		-webkit-text-stroke: 1px var(--color-blue-pale);
	}

	.deflist__text {
		display: flex;
		flex: 1;
		flex-direction: column;
		gap: 14px;
		min-width: 0;
		margin: 0;
		color: var(--color-text);
		font: 400 1rem/1.7 var(--font-sans); /* 16 / 27,2 */
	}

	/* Rangée de cartes. Le nombre de colonnes est la seule chose qui varie. */
	.card-grid {
		display: grid;
		grid-template-columns: repeat(var(--cards, 3), minmax(0, 1fr));
		gap: 20px;
	}

	.section__head {
		padding-bottom: var(--head-gap, 48px);
	}

	/* Chapeau aligné à gauche : le bloc reste centré, son contenu non. */
	.sec-head--start {
		align-items: flex-start;
		text-align: left;
	}

	.section__action {
		display: flex;
		justify-content: center;
		padding-top: 36px;
	}

	/* Carte de page intérieure : plus grande que celle de l'accueil. */
	.card--panel {
		position: relative;
		overflow: clip;
		padding: 30px 28px;
		border: 1px solid var(--color-rule);
		background: var(--color-white);
	}

	/*
	 * `.card--panel` porte un fond blanc plus spécifique que celui de `.card--dark` :
	 * la variante navy doit le reprendre explicitement, sans quoi elle reste blanche.
	 */
	.card--panel.card--dark {
		gap: 0;
		border-color: transparent;
		background: var(--color-navy);
	}

	.card--panel .rosette,
	.card--panel .card__title,
	.card--panel .card__text {
		position: relative; /* Au-dessus du halo de la variante navy. */
	}

	.card--panel .card__title {
		padding-top: 16px;
		color: var(--color-navy);
		font: 600 1.125rem/1.3889 var(--font-sans); /* 18 / 25 */
	}

	.card--panel .card__text {
		padding-top: 10px;
		color: var(--color-text);
		font: var(--text-small);
	}

	.card--panel.card--dark .card__title {
		color: var(--color-white);
	}

	.card--panel.card--dark .card__text {
		color: var(--color-text-on-dark);
	}

	/* Halo débordant du haut d'une carte sombre. Le décalage varie selon la carte. */
	.card__halo {
		--halo-size: 240px;
		--halo-color: rgba(47, 91, 232, 0.3);
		--halo-blur: 0px;

		top: -80px;
		left: var(--halo-x, 108px);
	}

	/* Bloc d'appel à l'action des pages intérieures. */
	.page-cta {
		--title-color: var(--color-white);
		--text-color: rgba(255, 255, 255, 0.72);
		--btn-rim: var(--color-rule-on-dark);

		position: relative;
		overflow: clip;
		/* Le retrait bas varie d'une page à l'autre : 121 sur Continuité, 96 ailleurs. */
		padding-block: 96px var(--cta-pad-bottom, 96px);
		background: var(--color-navy);
		color: var(--color-white);
	}

	/* Les sept ellipses de la maquette en couches de fond : pas sept éléments flous. */
	.page-cta__halos {
		position: absolute;
		inset: 0;

		/*
		 * Centres et rayons dérivés des ellipses Figma, ramenés au milieu du
		 * cadre de 1440 et rangés du plus petit au plus grand. Les opacités ne
		 * sont pas exposées par les exports SVG.
		 */
		background:
			radial-gradient(circle 130px at calc(50% + 360px) 290px, rgba(47, 91, 232, 0.3) 0%, transparent 100%),
			radial-gradient(circle 210px at calc(50% + 360px) 290px, rgba(47, 91, 232, 0.22) 0%, transparent 100%),
			radial-gradient(ellipse 240px 180px at calc(50% + 160px) 520px, rgba(47, 91, 232, 0.18) 0%, transparent 100%),
			radial-gradient(ellipse 260px 220px at calc(50% + 560px) 120px, rgba(47, 91, 232, 0.16) 0%, transparent 100%),
			radial-gradient(circle 300px at calc(50% + 360px) 290px, rgba(47, 91, 232, 0.14) 0%, transparent 100%),
			radial-gradient(ellipse 380px 300px at calc(50% + 330px) 280px, rgba(47, 91, 232, 0.12) 0%, transparent 100%),
			radial-gradient(circle 400px at calc(50% + 360px) 290px, rgba(47, 91, 232, 0.1) 0%, transparent 100%);
	}

	/* Voile posé au-dessus des halos, sous le contenu. */
	.page-cta__veil {
		position: absolute;
		inset: 0;
		background: linear-gradient(90deg, var(--color-navy) 0%, rgba(24, 25, 50, 0.72) 45%, rgba(24, 25, 50, 0) 100%);
	}

	.page-cta__inner {
		position: relative;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 40px;
	}

	.page-cta__text {
		flex: 0 0 var(--cta-text-width, 56.54%); /* 640 / 1132 */
	}

	.page-cta .section__title {
		font: var(--text-h1-page);
		letter-spacing: var(--ls-tight);
	}

	/* Écart entre paragraphes réglable : Souveraineté en veut un cran de plus. */
	.page-cta__lead {
		display: flex;
		flex-direction: column;
		gap: var(--lead-gap, 14px);
		padding-top: 14px;
	}

	.page-cta__actions {
		display: flex;
		align-items: center;
		gap: 24px;
		padding-top: 34px; /* 14 sous le texte, plus les 20 du bloc d'actions */
	}

	/* Le chiffre et la mention se touchent, contrairement au macaron de l'accueil. */
	.page-cta__sticker {
		--sticker-size: 176px;

		flex-shrink: 0;
		gap: 0;
		box-shadow: 0 22px 40px rgba(0, 0, 0, 0.5);
	}

	.page-cta__sticker .sticker__brand {
		font-size: 0.0511em; /* 9 pour un macaron de 176 */
		letter-spacing: 0.14em;
	}

	/*
	 * Colonne de droite dès qu'un visuel est déposé. Le retrait bas réserve la
	 * moitié du macaron, qui chevauche alors l'angle sans sortir du cadre : la
	 * section rogne ce qui déborde.
	 */
	.page-cta__media {
		position: relative;
		flex: 0 0 43.64%; /* 494 / 1132 */
		padding-bottom: 88px;
	}

	.page-cta__visual {
		aspect-ratio: 494 / 420;
		overflow: clip;
		border-radius: var(--radius-card);
	}

	.page-cta__sticker--pose {
		position: absolute;
		bottom: 0;
		left: 5.67%; /* 28 / 494, comme le badge de l'accueil */
	}

	/* Une section sombre habille ses propres cartes. */
	.section--deep .card {
		border-color: var(--color-dark-500);
		background: var(--color-dark-700);
	}

	.section--deep .card__title {
		color: var(--color-white);
	}

	.section--deep .card__text {
		color: var(--color-text-on-dark);
	}

	/* Le bleu de marque tombe sous le seuil de contraste sur navy. */
	.section--deep .link-arrow {
		color: var(--color-blue-light);
	}

	/* ------------------------------------------------ Tablette et en dessous */

	@media (max-width: 1024px) {
		/*
		 * La navigation devient un tiroir sous la barre. Le panneau, jusqu'ici
		 * dissous par `display: contents`, reprend corps pour l'accueillir.
		 */
		.site-header__panel {
			position: absolute;
			top: 100%;
			right: 0;
			left: 0;
			display: flex;
			flex-direction: column;
			align-items: stretch;
			gap: 4px;
			padding: 12px var(--gutter) 22px;
			border-bottom: 1px solid var(--color-rule);
			background: var(--color-white);
			box-shadow: var(--shadow-raised);
		}

		/*
		 * Le burger et le repli du tiroir dépendent de la classe posée par le
		 * script. Sans JavaScript, le tiroir reste déployé et le bouton n'apparaît
		 * pas : la navigation demeure atteignable, comme les blocs en fondu.
		 */
		.has-nav-toggle .burger {
			display: grid;
		}

		.has-nav-toggle .site-header__panel {
			display: none;
		}

		.has-nav-toggle .site-header__panel.is-open {
			display: flex;
		}

		.nav {
			flex-direction: column;
			align-items: stretch;
			gap: 0;
		}

		.nav__item {
			display: flex;
			flex-direction: column;
		}

		.nav__link {
			justify-content: space-between;
			padding-block: 13px;
		}

		/* Déplié en accordéon : dans un tiroir tactile, il n'y a rien à survoler. */
		.nav__sub {
			position: static;
			min-width: 0;
			padding: 0 0 8px 12px;
			border: 0;
			box-shadow: none;
		}

		/*
		 * Rendu au flux dans le tiroir, le panneau n'a plus de bandeau à cadrer.
		 * Le sélecteur reprend le `:has()` ci-dessus, plus spécifique — une
		 * media query ne pèse rien dans la cascade.
		 */
		.nav__sub--mega,
		.nav__sub--mega:has(.nav__mega-intro) {
			grid-template-columns: minmax(0, 1fr);
			padding: 0;
		}

		/* Du contexte, pas de la navigation : elle doublerait la hauteur du tiroir. */
		.nav__mega-intro {
			display: none;
		}

		.nav__mega-grid {
			grid-template-columns: repeat(2, minmax(0, 1fr));
			padding-left: 0;
		}

		.nav__mega-link {
			padding: 12px;
		}

		.site-header__panel .btn--sm {
			justify-content: center;
			margin-top: 12px;
		}

		/*
		 * Le débord gauche voulu par la maquette atteint 50 px, pour 30 px de
		 * gouttière : l'étiquette est ramenée au bord du visuel faute de place.
		 */
		.badge.pinned,
		.map-pin.pinned {
			left: max(var(--x), 0px);
		}

		/*
		 * Les sections en deux colonnes s'empilent. Les visuels portent un
		 * `flex-basis` en pourcentage : en colonne il s'appliquerait à leur
		 * hauteur, d'où la remise à plat de la base de tous les enfants.
		 */
		.split {
			flex-direction: column;
			gap: 40px;
		}

		/*
		 * `.page-hero__inner > .split__text` est plus spécifique : sans cette
		 * seconde ligne, la colonne de texte des heros garderait son flex-basis
		 * en pourcentage, qui s'appliquerait à sa hauteur une fois en colonne.
		 */
		.split > *,
		.page-hero__inner > .split__text {
			flex: none;
			width: 100%;
		}

		/* Le titre reste en tête une fois empilé, même quand le visuel le précède. */
		.split__text {
			order: -1;
		}

		.site-footer__top {
			flex-wrap: wrap;
			gap: 40px;
		}

		.site-footer__brand-col {
			flex-basis: 100%;
			width: auto;
		}

		.site-footer__col {
			flex: 1 1 170px;
		}

		/* --------------------------------------- Pages intérieures */

		.page-hero {
			padding-block: 48px 64px;
		}

		/* Le halo est calé sur un cadre de 1440 : il sort de l'écran sinon. */
		.page-hero__halo {
			left: 50%;
		}

		/*
		 * Les grilles de cartes passent à deux colonnes, quel que soit leur
		 * nombre de départ. Les feuilles de page ne règlent que `--cards` :
		 * agir sur `grid-template-columns` ne rencontre donc aucune surcharge.
		 */
		.card-grid {
			grid-template-columns: repeat(2, minmax(0, 1fr));
		}

		.page-cta {
			padding-block: 72px var(--cta-pad-bottom-md, 72px);
		}

		/* Le macaron de 176 px ne tient plus à côté du texte. */
		.page-cta__inner {
			flex-direction: column;
			align-items: flex-start;
			gap: 32px;
		}

		.page-cta__text {
			flex: none;
			width: 100%;
		}

		/* Le visuel passe sous le texte sans dépasser sa largeur de maquette. */
		.page-cta__media {
			flex: none;
			width: min(100%, 494px);
		}
	}

	/* ------------------------------------------------------------- Téléphone */

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

		/* Un tiroir tactile sert à naviguer, pas à lire : la description tombe. */
		.nav__mega-text {
			display: none;
		}

		.form-grid {
			grid-template-columns: 1fr;
		}

		.split {
			gap: 32px;
		}

		.deflist__row {
			flex-direction: column;
			gap: 20px;
			padding-block: 28px;
		}

		.deflist__label {
			flex: none;
		}

		.site-footer__top {
			flex-direction: column;
			gap: 30px;
			padding-block: 48px 36px;
		}

		.site-footer__legal {
			flex-direction: column;
			align-items: flex-start;
			gap: 14px;
		}

		.site-footer__legal-links {
			flex-wrap: wrap;
			gap: 8px 20px;
		}

		/* Le filigrane est calé sur un cadre de 1440 : il sort de l'écran sinon. */
		.site-footer__watermark {
			left: var(--gutter);
			font-size: 6rem;
		}

		/* Les 80 px demandés mangent un tiers de la barre sur un écran de téléphone. */
		.brand__logo {
			height: 56px;
		}

		/* Un libellé long ne tient pas sur une ligne à cette largeur. */
		.btn__label {
			white-space: normal;
			text-align: center;
		}

		.media__dots {
			width: 150px;
			height: 150px;
		}

		/* --------------------------------------- Visuels et étiquettes */

		/*
		 * Les coordonnées de la maquette n'ont plus cours à cette largeur : les
		 * étiquettes se rangent en bas du cadre, toujours en surimpression.
		 *
		 * `wrap-reverse` place la première ligne remplie en bas et renvoie le
		 * reste au-dessus — 1 + 2 plutôt que 2 + 1. L'axe croisé étant retourné,
		 * `flex-start` désigne ici le bas.
		 */
		.media {
			display: flex;
			flex-wrap: wrap-reverse;
			align-content: flex-start;
			justify-content: flex-end;
			gap: 6px;
			padding: 10px;
		}

		/*
		 * Le cadre remplit le conteneur, retrait compris — un enfant absolu se
		 * cale sur la boîte de padding. Les cotes du portrait doivent être
		 * remises à plat : sur-contraint, il laisserait deux bandes mortes.
		 */
		.media > .media-frame {
			position: absolute;
			inset: 0;
			width: 100%;
			height: 100%;
		}

		/*
		 * La remise dans le flux vaut pour tout `.pinned`, y compris les rangées
		 * d'étiquettes des pages intérieures. Les cotes d'étiquette, elles, ne
		 * valent que pour les vraies étiquettes.
		 */
		.pinned {
			position: relative;
			top: auto;
			left: auto;
			transform: none;
		}

		.badge.pinned,
		.map-pin.pinned {
			--dot-size: 7px;

			max-width: 100%;
			gap: 6px;
			padding: 6px 12px;
			font-size: 0.75rem; /* 12 */
		}

		/* --------------------------------------- Pages intérieures */

		.page-hero {
			padding-block: 36px 48px;
		}

		.card-grid {
			grid-template-columns: 1fr;
		}

		/* Les rangées d'étiquettes des pages intérieures deviennent des piles. */
		.page-hero__pills,
		.media__row {
			flex-wrap: wrap;
			justify-content: flex-end;
			gap: 6px;
		}

		.page-hero__pills .glass-pill,
		.media__row .badge {
			gap: 6px;
			padding: 6px 12px;
			font-size: 0.75rem; /* 12 */
		}

		.page-cta {
			padding-block: 56px var(--cta-pad-bottom-sm, 56px);
		}

		.page-cta__actions {
			flex-direction: column;
			align-items: flex-start;
			gap: 16px;
		}

		.page-cta__actions .btn {
			justify-content: center;
			width: 100%;
		}

		/* Le macaron se pose au-dessus du texte plutôt qu'à côté. */
		.page-cta__sticker {
			--sticker-size: 132px;
		}

		.page-cta__sticker .sticker__brand {
			font-size: 0.0682em; /* 9 pour un macaron de 132 */
		}

		.page-cta__media {
			padding-bottom: 66px; /* moitié du macaron réduit */
		}
	}

	/* Placé en fin de couche : neutralise les mouvements sans recourir à !important. */
	@media (prefers-reduced-motion: reduce) {
		html {
			scroll-behavior: auto;
		}

		.media__dots,
		.pinned {
			animation: none;
		}

		.btn,
		.btn__pastille,
		.nav__link,
		.nav__chevron,
		.link-arrow svg,
		.site-footer a,
		.card--clickable,
		.card__icon,
		.reveal,
		.burger__bars,
		.burger__bars::before,
		.burger__bars::after {
			transition: none;
		}

		.btn:hover,
		.btn:focus-visible,
		.btn:hover .btn__pastille,
		.btn:focus-visible .btn__pastille,
		.link-arrow:hover svg,
		.link-arrow:focus-visible svg,
		.card--clickable:hover,
		.card--clickable:focus-within {
			transform: none;
		}
	}
}
