/*
Theme Name: Cburnettweb
Theme URI: https://cburnettweb.com
Author: Cedrick Burnett
Author URI: https://cburnettweb.com
Description: Thème sur mesure : conception de sites web (Acton Vale · Québec).
Version: 1.34.4
Requires at least: 6.0
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: cburnettweb
*/

/* ==================================================================
   Cburnettweb
   ------------------------------------------------------------------
   Le site est la démonstration. Le héros montre un site en train de
   se construire — le code se tape, la mise en page s'assemble, le
   vrai site apparaît — plutôt que de le raconter. Panneaux marine
   pour les moments forts, corps clair pour l'offre et la preuve.
   Le dégradé sarcelle → cyan → bleu vient du logo.

   Tout ce qui bouge est décoratif : le site reste lisible et
   utilisable sans JavaScript, et immobile sous prefers-reduced-motion.
   ================================================================== */

/* ---------- Jetons ---------- */
:root {
	/* Panneaux sombres — marine relevé du logo */
	--encre:          #0A1220;
	--encre-2:        #0E1B31;
	--encre-3:        #101B31;
	--texte-sombre:   #EAF1FA;
	--attenue-sombre: #A9BCD4;
	--trait-sombre:   rgba(234, 241, 250, .12);

	/* Corps clair */
	--couleur-fond:    #ffffff;
	--papier:          #F4F8FB;
	--couleur-texte:   #13233B;
	--couleur-attenue: #45586F;
	--couleur-trait:   #E2EAF2;

	/* Le cyan du logo ne tient que 1,9:1 sur blanc : réservé aux fonds
	   sombres. Sur fond clair, l'accent est sa version profonde. */
	--cyan:           #2AC7D4;
	--couleur-accent: #0C7D8F;
	--degrade:        linear-gradient(100deg, #54C4BE, #2AC7D4 48%, #4BA3E8);

	/* La couleur d'action, et elle seule.
	   Le bouton d'appel vit toujours sur la barre marine : le blanc plein y
	   est ce qui ressort le plus, sans ajouter de teinte étrangère à la
	   palette. L'ambre essayé avant tirait le regard vers lui plutôt que vers
	   la marque. Au survol, la pastille bascule dans le cyan — le geste est
	   confirmé par la couleur de la maison. */
	--action:      #FFFFFF;
	--action-vive: #2AC7D4;
	--action-ink:  #0A1220;

	--police-titres: 'Space Grotesk', system-ui, sans-serif;
	--police-corps:  'Inter', system-ui, sans-serif;
	--police-mono:   'IBM Plex Mono', ui-monospace, monospace;

	/* Élargi de 1220 à 1600 : à 1220 px, un écran de 1440 laissait 110 px
	   morts de chaque côté et un écran de 1920 en laissait 350 — le site
	   se lisait comme une colonne étroite posée au milieu du vide. La
	   longueur de ligne du texte reste protégée par le `max-width: 68ch`
	   des paragraphes, donc élargir le cadre n'abîme pas la lecture. */
	--largeur-max: 1600px;
	--gouttiere:   clamp(1.25rem, 4vw, 3.5rem);
	/* Resserré : à 7vw le site respirait au point de paraître vide, avec de
	   petits titres flottant dans de grands blancs. Les concurrents sont
	   plus denses, et c'est ce qui les fait paraître assurés. */
	--rythme:      clamp(2.6rem, 5vw, 4.2rem);

	/* Hauteur de l'en-tête, en dur parce que la marge négative qui le fait
	   flotter par-dessus le héros doit valoir exactement cette hauteur. */
	--h-entete: 90px;

	--rayon:       16px;
	--rayon-petit: 10px;
	--ombre-carte: 0 14px 40px rgba(14, 30, 51, .12);
}

/* ---------- Réinitialisation ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
	margin: 0;
	background: var(--couleur-fond);
	color: var(--couleur-texte);
	font-family: var(--police-corps);
	font-size: 1rem;
	line-height: 1.65;
	overflow-x: hidden;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
	margin: 0 0 .5em;
	font-family: var(--police-titres);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: -.02em;
	text-wrap: balance;
}

/* Échelle relevée d'un cran : les titres de section paraissaient timides à
   côté de l'espace qu'ils occupaient. */
h1 { font-size: clamp(2.6rem, 6.4vw, 4.8rem); }
h2 { font-size: clamp(2.1rem, 4.8vw, 3.4rem); }
h3 { font-size: 1.15rem; }

p { margin: 0 0 1em; max-width: 68ch; }

a { color: inherit; }

/* Les images sont fluides par défaut. Sans `height:auto`, les dimensions
   posées par inc/perf.php — indispensables contre le CLS — écrasent le ratio
   dès que la largeur est contrainte. */
img, video { max-width: 100%; height: auto; display: block; }

/* ---------- Accessibilité ---------- */
.screen-reader-text {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.skip-link:focus {
	position: fixed;
	top: .5rem; left: .5rem;
	z-index: 999;
	width: auto; height: auto;
	padding: .75rem 1rem;
	clip-path: none;
	background: var(--couleur-accent);
	color: #fff;
}

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

/* Sur les panneaux marine, l'anneau sarcelle profond disparaît. */
.heros :focus-visible,
.appel :focus-visible,
.pied :focus-visible,
.entete :focus-visible,
.section--marine :focus-visible {
	outline-color: var(--cyan);
}

/* Mouvement réduit : PLUS DOUX, pas coupé.
   La version précédente ramenait toutes les transitions à .01ms, ce qui
   supprimait aussi les fondus de couleur et d'opacité — inoffensifs, et
   utiles pour comprendre qu'un bouton a réagi. Ce qui gêne, c'est le
   DÉPLACEMENT : on ne garde donc que les propriétés qui ne bougent rien, et
   les animations en boucle s'arrêtent toujours net. */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-property: opacity, color, background-color, border-color, box-shadow, fill !important;
		transition-duration: .2s !important;
	}
	html { scroll-behavior: auto; }
}

/* ==================================================================
   À PARTIR D'ICI — le design propre à Cburnettweb
   ================================================================== */

/* ---------- Primitives ---------- */

.cadre {
	max-width: var(--largeur-max);
	margin-inline: auto;
	padding-inline: var(--gouttiere);
}

.section { padding-block: var(--rythme); }
.section--papier { background: var(--papier); }
.section--marine {
	position: relative;
	overflow: hidden;
	background: var(--encre);
	color: var(--texte-sombre);
}

.surtitre {
	display: block;
	margin-bottom: 1rem;
	font-family: var(--police-mono);
	font-size: .82rem;
	letter-spacing: .08em;
	color: var(--couleur-accent);
}

.section--marine .surtitre, .heros .surtitre { color: var(--cyan); }

.section__intro { color: var(--couleur-attenue); font-size: 1.05rem; margin-top: .6rem; }
.section--marine .section__intro { color: var(--attenue-sombre); }

/* Le mot en dégradé, avec son reflet qui passe — la signature du site.
   Réservé aux panneaux sombres : sur blanc le dégradé tombe sous le
   seuil de contraste. */
.brille {
	background: linear-gradient(100deg, #54C4BE, #2AC7D4 35%, #9BE8F0 50%, #2AC7D4 65%, #4BA3E8);
	background-size: 220% 100%;
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	animation: cbw-reflet 4.5s linear infinite;
}

@keyframes cbw-reflet { to { background-position: -220% 0; } }

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

.bouton {
	display: inline-block;
	border: 0;
	border-radius: var(--rayon-petit);
	padding: 1.05rem 1.9rem;
	font: 700 1rem/1.2 var(--police-corps);
	text-decoration: none;
	cursor: pointer;
	transition: transform .18s ease, box-shadow .18s ease;
}

.bouton--degrade {
	position: relative;
	background: var(--degrade);
	color: #06222a;
	box-shadow: 0 0 30px rgba(42, 199, 212, .28);
}

/* Le bouton magnétique : le script écrit une translation qui suit le curseur,
   puis la remet à vide quand il part. Sans transition, le bouton se
   téléportait à sa place d'origine — sur l'appel à l'action de chaque page.
   160 ms suffisent : au-delà, le bouton traîne derrière la souris. */
.magnet {
	transition: transform .16s cubic-bezier(.23, 1, .32, 1);
}

/* `will-change` seulement au survol. Posé en permanence, il gardait un calque
   de composition ouvert pour chaque bouton d'appel de chaque page, alors que
   seul le bouton magnétique sous le curseur se déplace. */
.bouton--degrade:hover {
	box-shadow: 0 0 44px rgba(42, 199, 212, .45);
	will-change: transform;
}

.bouton--principal { background: var(--encre); color: #fff; }
.bouton--principal:hover { transform: translateY(-2px); }

.bouton--contour {
	background: transparent;
	color: inherit;
	border: 2px solid var(--couleur-trait);
}

.section--marine .bouton--contour { border-color: var(--trait-sombre); color: var(--texte-sombre); }

.lien-tel {
	font-family: var(--police-mono);
	font-size: .95rem;
	text-decoration: none;
	border-bottom: 1px solid var(--couleur-accent);
	padding-bottom: .15rem;
	white-space: nowrap;
}

.heros .lien-tel, .appel .lien-tel, .section--marine .lien-tel {
	border-color: var(--cyan);
	color: var(--texte-sombre);
}

.groupe-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem 1.4rem;
	align-items: center;
}

/* ---------- Barre de progression de lecture ---------- */

.progres {
	position: fixed;
	top: 0; left: 0;
	z-index: 200;
	height: 3px;
	width: 100%;
	transform: scaleX(0);
	transform-origin: 0 0;
	background: var(--degrade);
}

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

/* L'en-tête.
   Par défaut il a son fond : sur une page qui s'ouvre en clair, un en-tête
   transparent au lettrage blanc serait invisible.

   Sur les pages qui commencent par du sombre — l'accueil et les gabarits à
   bandeau — le corps porte `entete-flottante` et l'en-tête passe PAR-DESSUS
   la section suivante grâce à une marge basse négative. Sans elle, un
   en-tête « transparent » laisse simplement voir le blanc du corps, parce
   qu'un élément `sticky` occupe sa place dans le flux au lieu de recouvrir
   ce qui suit. */
.entete {
	position: sticky;
	top: 0;
	z-index: 100;
	color: var(--texte-sombre);
	background: rgba(10, 18, 32, .88);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid rgba(255, 255, 255, .08);
	transition: background .3s ease, border-color .3s ease;
}

.entete-flottante .entete {
	margin-bottom: calc(-1 * var(--h-entete));
	background: transparent;
	border-bottom-color: transparent;
	backdrop-filter: none;
}

/* Posé par le script au défilement. Le fond revient dès qu'on quitte le
   haut de page, pour que le menu reste lisible sur le corps clair. */
.entete-flottante .entete.est-defile {
	background: rgba(10, 18, 32, .9);
	border-bottom-color: rgba(255, 255, 255, .08);
	backdrop-filter: blur(14px);
}

/* La première section rend la place que la marge négative lui a prise.
   Tout nouveau gabarit qui s'ouvre sur un panneau sombre DOIT ajouter son
   conteneur ici : sans ça, l'en-tête se pose par-dessus la première ligne
   de la page — c'est arrivé à l'ouverture d'À propos. */
.entete-flottante .heros__cadre,
.entete-flottante .tete-sombre__cadre,
.entete-flottante .page-bandeau__cadre { padding-top: calc(var(--h-entete) + clamp(1.5rem, 3vw, 2.5rem)); }

.entete__cadre {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	height: var(--h-entete);
}

.entete__logo { display: block; flex-shrink: 0; line-height: 0; }

/* Le mot-symbole, pas la pastille ronde.
   Le logo rond est un JPEG sur fond blanc : découpé en cercle sur une barre
   marine, il donnait une tache blanche où on ne lisait pas le nom. La
   version `-blanc.png` a un fond transparent et un lettrage clair. */
.entete__logo img { height: 56px; width: auto; }

.entete__nav ul {
	display: flex;
	gap: 1.8rem;
	margin: 0; padding: 0;
	list-style: none;
}

.entete__nav a {
	font-size: .78rem;
	font-weight: 600;
	letter-spacing: .11em;
	text-transform: uppercase;
	text-decoration: none;
	color: #C5D2E4;
	transition: color .2s ease;
}

.entete__nav a:hover,
.entete__nav .current-menu-item > a,
.entete__nav .current_page_item > a { color: var(--cyan); }

.entete__droite { display: flex; align-items: center; gap: 1.3rem; }

/* Le bouton d'appel : pastille blanche, gommette marine, flèche blanche.
   Sur la barre marine, le blanc plein est le plus fort contraste disponible
   et n'introduit aucune teinte hors palette. */
.entete__action {
	display: inline-flex;
	align-items: center;
	gap: .7rem;
	padding: .42rem .42rem .42rem 1.25rem;
	border-radius: 999px;
	background: var(--action);
	color: var(--action-ink);
	font: 700 .78rem/1.2 var(--police-corps);
	letter-spacing: .07em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
}

.entete__action:hover {
	background: var(--action-vive);
	transform: translateY(-2px);
	box-shadow: 0 10px 28px rgba(42, 199, 212, .38);
}

.entete__action .gommette {
	display: grid;
	place-items: center;
	width: 30px; height: 30px;
	flex: none;
	border-radius: 50%;
	background: var(--action-ink);
	color: var(--action);
	transition: transform .25s ease;
}

.entete__action:hover .gommette { transform: rotate(45deg); }
.entete__action svg { width: 13px; height: 13px; }

/* Tiroir mobile : <details>, donc fonctionnel sans JavaScript. */
.entete__tiroir { display: none; position: relative; }

.entete__burger {
	list-style: none;
	cursor: pointer;
	padding: .5rem;
	border-radius: var(--rayon-petit);
}

.entete__burger::-webkit-details-marker { display: none; }

.entete__burger .trait {
	display: block;
	width: 24px; height: 2px;
	margin-block: 5px;
	background: var(--texte-sombre);
	transition: transform .2s ease, opacity .2s ease;
}

.entete__tiroir[open] .trait:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.entete__tiroir[open] .trait:nth-child(2) { opacity: 0; }
.entete__tiroir[open] .trait:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.entete__panneau {
	position: absolute;
	top: calc(100% + .8rem);
	right: 0;
	min-width: min(78vw, 20rem);
	background: var(--encre-2);
	border: 1px solid var(--trait-sombre);
	border-radius: var(--rayon);
	padding: 1rem 1.2rem 1.3rem;
	box-shadow: 0 24px 50px rgba(0, 0, 0, .45);
}

.entete__panneau ul { margin: 0; padding: 0; list-style: none; }

.entete__panneau a {
	display: block;
	padding: .75rem 0;
	font: 600 1.02rem/1.2 var(--police-titres);
	text-decoration: none;
	border-bottom: 1px solid var(--trait-sombre);
}

.entete__panneau .lien-tel { display: inline-block; margin-top: 1rem; }

/* Entre 1160 et 1280 px, l'en-tête complet ne rentre plus : le mot-symbole,
   sept entrées de menu, le téléphone et le bouton demandent environ 1220 px.
   Le tout débordait de 260 px vers la droite sans que rien ne le montre,
   `overflow-x: hidden` sur le corps masquant le dépassement.
   On resserre d'abord, on bascule ensuite. Le téléphone n'est pas perdu :
   il reste dans le tiroir, dans le pied et sur la page Contact. */
@media (max-width: 1280px) {
	.entete__nav ul { gap: 1.05rem; }
	.entete__droite .lien-tel { display: none; }
	/* Le sélecteur part avec le téléphone : deux éléments à sacrifier valent
	   mieux qu'une barre qui déborde. Il est repris dans le tiroir. */
	.entete__droite .langues { display: none; }
}

@media (max-width: 1160px) {
	.entete__nav, .entete__droite { display: none; }
	.entete__tiroir { display: block; }
	.entete__logo img { height: 46px; }
}

/* ---------- Sélecteur de langue ----------
 * Le bloc plein : deux codes côte à côte et un pavé rempli du dégradé de la
 * maison sous celui en cours. C'est la forme que tout le monde reconnaît
 * sans avoir à l'apprendre, et c'est précisément ce qu'on lui demande — un
 * sélecteur de langue n'a rien à gagner à être une devinette.
 *
 * Ce qui le rattache au site plutôt qu'à une bibliothèque : le pavé porte
 * `--degrade`, le même que la carte vedette des Tarifs et la dalle du socle,
 * et les codes sont en mono bas-de-casse comme les surtitres de section.
 *
 * LE PAVÉ EST UN ::before, PAS UN FOND SUR L'ÉLÉMENT ACTIF
 * Posé sur l'élément lui-même, il ne pourrait pas glisser, et il faudrait
 * arrondir les coins différemment selon le côté actif. En couche séparée, il
 * se déplace d'une translation et le conteneur porte seul le rayon. */
.langues {
	position: relative;
	display: inline-flex;
	isolation: isolate;
	border-radius: var(--rayon-petit);
	overflow: hidden;
	background: rgba(255, 255, 255, .07);

	/* La police du CORPS en capitales espacées, et non la mono.
	   Le sélecteur a deux voisins dans la barre : le menu et le téléphone. En
	   mono il se rangeait avec le numéro, qui est un bloc technique, alors
	   qu'il appartient à la navigation — on choisit sa langue comme on choisit
	   une page. Repris au traitement exact des entrées du menu, il se lit
	   enfin comme l'une d'elles. */
	font: 700 .72rem/1 var(--police-corps);
	letter-spacing: .09em;
}

/* Le pavé. 50 % de largeur : « FR » et « EN » font deux capitales de largeur
   voisine dans Inter et portent le même rembourrage, donc les deux moitiés
   sont égales sans qu'aucune largeur soit écrite en dur. Le libellé pour
   lecteur d'écran du lien est en .screen-reader-text, réduit à 1 px et sorti
   du flux : il n'entre pas dans le calcul. */
.langues::before {
	content: '';
	position: absolute;
	z-index: -1;
	inset-block: 0;
	left: 0;
	width: 50%;
	background: var(--degrade);
}

/* Sur une page anglaise, l'actif est le second.
   Le pavé n'a PAS de transition, et c'est délibéré : changer de langue est un
   chargement de document, pas un changement d'état. Une transition posée ici
   ne peut jamais jouer, et une animation qui ne s'exécute pas est du code
   mort qui donne l'illusion d'une intention. */
.langues--en::before { transform: translateX(100%); }

.langues__actif,
.langues__lien {
	padding: .5rem .7rem;
	text-decoration: none;
	text-transform: uppercase;
	transition: color .25s ease;
}

/* Encre sur le dégradé : c'est le contraste le plus fort disponible, et le
   blanc y serait délavé. */
.langues__actif { color: var(--action-ink); }
.langues__lien  { color: var(--attenue-sombre); }
.langues__lien:hover,
.langues__lien:focus-visible { color: var(--texte-sombre); }

/* Le pavé étant lui-même coloré, l'anneau de focus par défaut se perdrait
   dedans : on le décale vers l'intérieur. */
.langues__lien:focus-visible { outline-offset: -3px; }

/* Dans le tiroir mobile, il se pose seul sous le téléphone. */
.langues--tiroir { margin-top: 1.4rem; align-self: flex-start; }

/* ---------- Héros ---------- */

/* Le fond du héros : une photo d'atelier de nuit, écran allumé.
   Le voile n'est pas uniforme — il est opaque à gauche, où se pose le
   titre, et s'allège à droite pour laisser voir l'écran et la lueur
   sarcelle. Un voile plat aurait soit noyé la photo, soit rendu le texte
   illisible ; le dégradé fait les deux à la fois. */
.heros {
	position: relative;
	overflow: hidden;
	color: var(--texte-sombre);
	background:
		linear-gradient(100deg, rgba(10, 18, 32, .96) 26%, rgba(10, 18, 32, .74) 55%, rgba(10, 18, 32, .58)),
		url('assets/img/fond-heros.jpg') center right / cover no-repeat,
		var(--encre);
}

.heros::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background: radial-gradient(46% 60% at 72% 45%, rgba(42, 199, 212, .10), transparent 70%);
}

/* Le réseau de nœuds, dessiné au canevas par main.js.
   Ce n'est pas un fond décoratif choisi au hasard : le logo EST un globe
   fait de nœuds reliés. Le fond reprend donc la marque plutôt qu'un dégradé
   quelconque, et il réagit au curseur. Sans JavaScript le canevas reste
   vide et le héros garde son fond dégradé — rien ne manque. */
.heros__reseau {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.heros__cadre {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 1.02fr .98fr;
	gap: 2.6rem;
	align-items: center;
	padding-block: clamp(2.4rem, 4.5vw, 3.6rem) clamp(2rem, 4vw, 3rem);
}

/* Sans `min-width: 0`, une piste `1fr` ne descend pas sous la largeur
   min-content de son contenu : l'adresse en `white-space: nowrap` du cadre
   navigateur élargissait la grille au-delà de l'écran, ce qui rognait le
   texte ET poussait le bouton du menu hors du cadre. */
.heros__cadre > * { min-width: 0; }

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

/* La pastille d'offre, au-dessus du titre. */
.pastille {
	display: inline-flex;
	align-items: center;
	gap: .55rem;
	margin-bottom: 1.5rem;
	padding: .5rem 1rem .5rem .8rem;
	border: 1px solid rgba(42, 199, 212, .4);
	border-radius: 999px;
	background: rgba(42, 199, 212, .08);
	font-size: .84rem;
	color: var(--attenue-sombre);
	text-decoration: none;
	transition: border-color .2s ease, background .2s ease;
}

.pastille:hover { border-color: var(--cyan); background: rgba(42, 199, 212, .14); }
.pastille strong { color: var(--cyan); font-weight: 600; }
.pastille__fleche { color: var(--cyan); }

.pastille__point {
	width: 7px; height: 7px;
	border-radius: 50%;
	background: var(--cyan);
	box-shadow: 0 0 0 0 rgba(42, 199, 212, .7);
	animation: cbw-pouls 2.4s ease-out infinite;
}

@keyframes cbw-pouls {
	70%  { box-shadow: 0 0 0 7px rgba(42, 199, 212, 0); }
	100% { box-shadow: 0 0 0 0 rgba(42, 199, 212, 0); }
}

.heros__titre { font-size: clamp(2.5rem, 6vw, 4.4rem); line-height: 1.02; max-width: 15ch; }

/* Chaque mot entre séparément. L'état masqué n'existe que si main.js a
   posé .est-pret sur <html> : sans JavaScript, tout est visible. */
.heros__titre .mot { display: inline-block; }
html.est-pret .heros__titre .mot { opacity: 0; transform: translateY(.6em) rotate(2deg); }
html.est-pret .heros.pret .heros__titre .mot {
	animation: cbw-entre .7s cubic-bezier(.2, .7, .2, 1) forwards;
	animation-delay: var(--d, 0ms);
}

@keyframes cbw-entre { to { opacity: 1; transform: none; } }

.heros__accroche {
	margin-top: 1.4rem;
	max-width: 48ch;
	color: var(--attenue-sombre);
	font-size: 1.08rem;
	line-height: 1.7;
}

.heros .groupe-actions { margin-top: 2.1rem; }

/* Les chiffres vivent DANS le héros. Sur une bande blanche à part, ils
   laissaient le héros à moitié vide et n'apportaient rien là où ils
   étaient. C'est aussi ce que font les concurrents les plus solides. */
.heros__preuves {
	display: flex;
	flex-wrap: wrap;
	gap: 1.6rem 2.8rem;
	margin-top: clamp(2rem, 4vw, 3rem);
	padding-top: 1.6rem;
	border-top: 1px solid var(--trait-sombre);
}

.heros__preuves strong {
	display: block;
	font-family: var(--police-titres);
	font-size: clamp(1.6rem, 2.6vw, 2.1rem);
	line-height: 1;
	color: var(--texte-sombre);
}

.heros__preuves span { font-size: .82rem; color: var(--attenue-sombre); }

html.est-pret .heros__accroche,
html.est-pret .heros .groupe-actions { opacity: 0; transform: translateY(16px); }

/* Délais courts volontairement. À 0,85 s et 1,05 s le visiteur fixait un
   héros à moitié vide le temps que le texte daigne apparaître — l'effet
   inverse de celui recherché. */
html.est-pret .heros.pret .heros__accroche {
	transition: opacity .5s ease .3s, transform .5s ease .3s;
	opacity: 1; transform: none;
}
html.est-pret .heros.pret .groupe-actions {
	transition: opacity .5s ease .42s, transform .5s ease .42s;
	opacity: 1; transform: none;
}
html.est-pret .heros__preuves { opacity: 0; transform: translateY(16px); }
html.est-pret .heros.pret .heros__preuves {
	transition: opacity .5s ease .54s, transform .5s ease .54s;
	opacity: 1; transform: none;
}

/* ---------- Le chantier : un site qui se construit ---------- */

.chantier { position: relative; }

/* La perspective vit ici et non sur .chantier : elle ne doit s'appliquer
   qu'au cadre qui s'incline, pas à la rangée d'étapes. */
.chantier__fenetre { position: relative; perspective: 1100px; }

.navig {
	position: relative;
	border-radius: var(--rayon);
	overflow: hidden;
	background: var(--encre-3);
	border: 1px solid rgba(255, 255, 255, .14);
	box-shadow: 0 34px 80px rgba(0, 0, 0, .5);
	transition: transform .3s ease;
}

.navig__barre {
	display: flex;
	align-items: center;
	gap: .45rem;
	padding: .65rem .9rem;
	background: #111E36;
	border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.navig__barre i { width: 10px; height: 10px; border-radius: 50%; background: #33415C; }
.navig__barre i:nth-child(1) { background: #E0655A; }
.navig__barre i:nth-child(2) { background: #E8B44C; }
.navig__barre i:nth-child(3) { background: #57BE6C; }

.navig__url {
	flex: 1;
	min-width: 0;
	text-overflow: ellipsis;
	margin-left: .6rem;
	padding: .3rem .7rem;
	border-radius: 6px;
	background: rgba(255, 255, 255, .06);
	font-family: var(--police-mono);
	font-size: .74rem;
	color: #9FB3CE;
	white-space: nowrap;
	overflow: hidden;
}

.navig__url b { color: #57BE6C; font-weight: 500; margin-right: .35rem; }

.navig__page {
	position: relative;
	/* 16/10, la proportion d'un écran d'ordinateur portable : avec la barre
	   d'adresse par-dessus, le cadre a exactement les proportions d'une vraie
	   fenêtre. En 16/11,5 il était plus haut que large ne l'est un navigateur,
	   ce qui ajoutait au malaise de l'étape « en ligne ». */
	aspect-ratio: 16 / 10;
	overflow: hidden;
	background: var(--encre-3);
}

.calque { position: absolute; inset: 0; opacity: 0; transition: opacity .45s ease; }
.calque.actif { opacity: 1; }

/* Étape 1 — le code se tape */
.calque-code {
	margin: 0;
	padding: 1rem 1.1rem;
	font-family: var(--police-mono);
	font-size: .78rem;
	line-height: 1.75;
	color: #8FA4C2;
	white-space: pre-wrap;
}

.calque-code .t { color: var(--cyan); }
.calque-code .a { color: #7FB5F0; }
.calque-code .v { color: #C9A2F5; }

.calque-code .curseur {
	display: inline-block;
	width: .55em; height: 1.1em;
	vertical-align: -.2em;
	background: var(--cyan);
	animation: cbw-cligne .9s steps(1) infinite;
}

@keyframes cbw-cligne { 50% { opacity: 0; } }

/* Étape 2 — la mise en page s'assemble */
.calque-squelette {
	display: flex;
	flex-direction: column;
	gap: .7rem;
	padding: 1rem 1.2rem;
	background: var(--papier);
}

.sq {
	position: relative;
	overflow: hidden;
	border-radius: 6px;
	background: #DCE6F0;
	opacity: 0;
	transform: translateY(10px) scaleX(.6);
	transform-origin: left;
	transition: opacity .45s cubic-bezier(.2,.7,.2,1), transform .45s cubic-bezier(.2,.7,.2,1);
}

.calque-squelette.pose .sq { opacity: 1; transform: none; }

.sq::after {
	content: '';
	position: absolute;
	inset: 0;
	transform: translateX(-100%);
	background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .7), transparent);
}

.calque-squelette.pose .sq::after { animation: cbw-mirroite 1.3s ease .3s; }

@keyframes cbw-mirroite { to { transform: translateX(100%); } }

.sq-entete {
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 26px;
	padding-inline: .6rem;
	background: #CBD9E8;
	transition-delay: .05s;
}

.sq-entete b { width: 52px; height: 8px; border-radius: 4px; background: #9FB3CE; }
.sq-entete span { width: 90px; height: 6px; border-radius: 3px; background: #AFC2D6; }

.sq-titre { height: 20px; width: 68%; background: #B9CCE0; transition-delay: .18s; }
.sq-ligne { height: 9px; width: 88%; transition-delay: .3s; }
.sq-ligne.courte { width: 55%; transition-delay: .4s; }

.sq-btn {
	height: 22px; width: 32%;
	border-radius: 11px;
	background: var(--cyan);
	transition-delay: .52s;
}

.calque-squelette.pose .sq-btn { opacity: .85; }

.sq-grille { display: grid; grid-template-columns: repeat(3, 1fr); gap: .6rem; margin-top: .2rem; }
.sq-img { aspect-ratio: 4 / 3; }
.sq-grille .sq:nth-child(1) { transition-delay: .62s; }
.sq-grille .sq:nth-child(2) { transition-delay: .72s; }
.sq-grille .sq:nth-child(3) { transition-delay: .82s; }

/* Étape 3 — le vrai site, en entier.
   La capture fait 1440x900, soit exactement le 16/10 du cadre : elle le
   remplit d'un bord à l'autre sans rien couper. `object-fit` n'est là que
   pour absorber l'arrondi d'un pixel aux largeurs intermédiaires. */
.calque-site img {
	width: 100%; height: 100%;
	object-fit: cover;
	object-position: top center;
}

/* Débordement franc du coin plutôt qu'un empiétement sur la capture : la
   pastille annonce le résultat, elle ne doit pas cacher ce qu'elle note. */
.score {
	position: absolute;
	z-index: 5;
	right: -26px; bottom: -26px;
	width: 92px; height: 92px;
	border-radius: 50%;
	background: #0F2B1C;
	border: 3px solid #57BE6C;
	color: #7BE495;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	opacity: 0;
	transform: scale(.4);
	transition: opacity .5s cubic-bezier(.2, 1.4, .4, 1), transform .5s cubic-bezier(.2, 1.4, .4, 1);
}

.score.pop { opacity: 1; transform: scale(1); }
.score b { font-family: var(--police-titres); font-size: 1.5rem; line-height: 1; }
.score span { font-size: .58rem; letter-spacing: .06em; text-transform: uppercase; }

/* Sur mobile le cadre touche presque les bords : un débordement de 26 px
   sortait la pastille de l'écran, où `overflow-x: hidden` la tranchait.
   Elle rentre donc dans la largeur et ne déborde plus que vers le bas. */
@media (max-width: 700px) {
	.score { right: 4px; bottom: -22px; width: 76px; height: 76px; }
	.score b { font-size: 1.25rem; }
}

.etapes {
	display: flex;
	gap: 1.6rem;
	justify-content: center;
	margin-top: 1.2rem;
	font-family: var(--police-mono);
	font-size: .76rem;
	color: #55677F;
	flex-wrap: wrap;
}

/* Les étapes sont des boutons : le visiteur peut reprendre la construction
   à l'étape qu'il veut. Une démonstration qu'on peut piloter retient bien
   plus qu'une boucle qu'on subit. */
.etapes button {
	position: relative;
	padding: .35rem .2rem .35rem 1rem;
	border: 0;
	background: none;
	font: inherit;
	color: inherit;
	cursor: pointer;
	transition: color .3s ease;
}

.etapes button:hover { color: var(--texte-sombre); }
.etapes button:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 4px; }

.etapes span { position: relative; padding-left: 1rem; transition: color .3s ease; }

.etapes button::before,
.etapes span::before {
	content: '';
	position: absolute;
	left: 0; top: 50%;
	translate: 0 -50%;
	width: 7px; height: 7px;
	border-radius: 50%;
	background: #33415C;
	transition: background .3s ease, box-shadow .3s ease;
}

.etapes button.actif, .etapes span.actif { color: var(--cyan); }

.etapes button.actif::before,
.etapes span.actif::before { background: var(--cyan); box-shadow: 0 0 10px rgba(42, 199, 212, .8); }

/* ---------- Bande de confiance : les logos des clients ---------- */

.confiance { background: var(--couleur-fond); border-bottom: 1px solid var(--couleur-trait); }

/* Marge trouvée en deux essais. À 1,8 rem, les logos passés de 32 à 42 px
   touchaient le bord et le papier de la section suivante affleurait juste
   dessous. À 3,6 rem, la bande devenait une section à elle seule et
   poussait les logos hors du premier écran. Deux rem et demi tiennent les
   deux : les logos respirent et restent visibles sans défiler. */
.confiance__cadre {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 1.4rem clamp(2rem, 5vw, 4rem);
	padding-block: clamp(1.9rem, 2.6vw, 2.5rem);
}

/* `width: 100%` et non `flex-basis` : un élément flexible rétrécit par
   défaut, donc la mention se tassait sur la même ligne que les logos au
   lieu de leur servir de titre. */
.confiance__mention {
	width: 100%;
	/* `max-width: none` annule le 68ch posé sur tous les <p> : sans lui la
	   mention plafonnait à ~509 px, n'atteignait jamais 100 %, et restait
	   donc sur la même ligne que les logos au lieu de les coiffer. */
	max-width: none;
	flex: none;
	margin: 0 0 .4rem;
	text-align: center;
	font-family: var(--police-mono);
	font-size: .78rem;
	letter-spacing: .08em;
	color: var(--couleur-attenue);
}

/* Les logos gardent leurs vraies couleurs. Le `brightness(0)` d'avant les
   ramenait tous au même noir — pratique, mais l'or de Béton SW et le rouge
   de Cindy Roy disparaissaient avec.

   Ce que le filtre réglait pour de vrai, c'est la POLARITÉ : trois de ces
   marques ont un mot-symbole blanc, fait pour un fond sombre, et donc
   invisible ici. Elles ont été passées à l'encre dans le fichier lui-même
   plutôt qu'au filtre — c'est le traitement inversé que prévoit n'importe
   quelle charte, et ça ne coûte rien aux quatre autres.

   Une taille plus généreuse aussi : à 32 px, un mot-symbole ne se lisait
   pas, et un logo qu'on ne lit pas ne prouve rien. */
/* Les huit logos arrivent dans des formats qui n'ont rien à voir : L'Établi
   fait 4:1, Habitations Savard 4,8:1, Minecraft Québec est carré. Une hauteur
   commune avec la largeur libre — ce qu'il y avait ici — les rend donc tous
   de tailles très différentes à l'œil : le logo le plus large occupait cinq
   fois la surface du plus étroit et mangeait la rangée.

   On borne les DEUX dimensions. Chaque logo tient alors dans la même boîte :
   un carré bute sur la hauteur, une bannière bute sur la largeur, et aucun
   ne peut écraser ses voisins. C'est la seule façon d'aligner des logos dont
   on ne choisit pas les proportions. */
.confiance__logo {
	max-height: clamp(30px, 3.6vw, 42px);
	max-width: clamp(96px, 12vw, 150px);
	width: auto;
	height: auto;
	object-fit: contain;
	opacity: .82;
	transition: opacity .25s ease, transform .25s ease;
}

.confiance__logo:hover { opacity: 1; transform: translateY(-2px); }

/* ---------- Ruban défilant ---------- */

.ruban {
	position: relative;
	overflow: hidden;
	background: var(--encre);
	border-top: 1px solid rgba(255, 255, 255, .07);
}

.ruban__piste {
	display: flex;
	gap: 3.5rem;
	width: max-content;
	padding-block: 1.1rem;
	animation: cbw-file 26s linear infinite;
}

.ruban:hover .ruban__piste { animation-play-state: paused; }

@keyframes cbw-file { to { transform: translateX(-50%); } }

.ruban span {
	font-family: var(--police-titres);
	font-weight: 700;
	font-size: 1rem;
	letter-spacing: .04em;
	color: #5E7492;
	white-space: nowrap;
}

.ruban b { color: var(--cyan); font-weight: 500; }

/* ---------- Chiffres ---------- */

.chiffres { background: var(--couleur-fond); border-bottom: 1px solid var(--couleur-trait); }

.chiffres__cadre {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1.5rem;
	padding-block: 2.2rem;
	text-align: center;
}

@media (max-width: 720px) { .chiffres__cadre { grid-template-columns: repeat(2, 1fr); } }

.chiffres strong {
	display: block;
	font-family: var(--police-titres);
	font-size: clamp(1.8rem, 3.4vw, 2.6rem);
	line-height: 1;
}

.chiffres span { color: var(--couleur-attenue); font-size: .88rem; }

/* ---------- Révélations au défilement ---------- */

/* 12 px et non 28 : au-delà, l'œil suit le déplacement au lieu de lire le
   contenu qui arrive. */
html.est-pret [data-anim] { opacity: 0; transform: translateY(12px); }

/* `--retard` échelonne l'entrée d'une série d'éléments : posé en style
   dans le gabarit, il fait apparaître les cartes l'une après l'autre au
   lieu d'un bloc. Sans lui, la valeur par défaut vaut zéro et rien ne
   change pour tout le reste du site. */
[data-anim] {
	/* 450 ms et non 700 : avec les retards échelonnés, la dernière carte d'une
	   rangée arrivait près d'une seconde après la première. */
	transition: opacity .45s ease, transform .45s cubic-bezier(.2, .7, .2, 1);
	transition-delay: var(--retard, 0ms);
}

html.est-pret [data-anim].vu { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
	html.est-pret [data-anim],
	html.est-pret .tableau-defile tbody tr,
	html.est-pret .socle__plan .socle__pierre,
	html.est-pret .heros__titre .mot,
	html.est-pret .heros__accroche,
	html.est-pret .heros .groupe-actions { opacity: 1 !important; transform: none !important; }
}

/* ---------- Vitrine des réalisations ---------- */

/* Deux colonnes, pas quatre. Les captures des sites clients sont le meilleur
   argument de la page : les montrer à 290 px de large les rendait illisibles
   et faisaient paraître le travail plus petit qu'il ne l'est. */
.vitrine {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1.6rem;
	margin-top: 2.4rem;
	perspective: 1400px;
}

.vitrine--page { grid-template-columns: repeat(3, 1fr); }

@media (max-width: 980px) { .vitrine--page { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .vitrine, .vitrine--page { grid-template-columns: 1fr; } }

.carte {
	position: relative;
	margin: 0;
	border-radius: var(--rayon);
	overflow: hidden;
	background: var(--couleur-fond);
	box-shadow: var(--ombre-carte);
	transform-style: preserve-3d;
	/* La transformation est écrite par le script au survol et remise à vide au
	   départ du curseur. Sans elle dans la transition, la carte se redressait
	   d'un coup sec. */
	transition: box-shadow .3s ease, transform .2s cubic-bezier(.2, .7, .2, 1);
}

/* `will-change` seulement pendant le survol : posé en permanence, il gardait
   un calque de composition ouvert pour chacune des huit cartes de la page
   Réalisations, qu'on les survole ou non. */
.carte:hover { will-change: transform; }

.carte:hover { box-shadow: 0 26px 60px rgba(14, 30, 51, .22); }

.carte__ecran {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: linear-gradient(155deg, var(--teinte-a, var(--encre-2)), var(--teinte-b, var(--encre)));
}

.carte__ecran img {
	width: 100%; height: 100%;
	object-fit: cover;
	object-position: top;
	transition: transform .5s cubic-bezier(.2, .7, .2, 1);
}

.carte:hover .carte__ecran img { transform: scale(1.06); }

/* Sans capture : le nom se lit sur l'aplat aux couleurs du client. */
.carte__nom {
	position: absolute;
	left: 1.1rem; bottom: 1rem;
	font: 700 1.1rem/1.2 var(--police-titres);
	color: #fff;
	text-shadow: 0 1px 8px rgba(0, 0, 0, .35);
}

.carte figcaption {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 1rem;
	padding: 1.1rem 1.4rem 1.3rem;
	font-size: .88rem;
	color: var(--couleur-attenue);
}

.carte figcaption b {
	display: block;
	margin-bottom: .15rem;
	font-family: var(--police-titres);
	font-size: 1.25rem;
	color: var(--couleur-texte);
}

.carte__visite {
	font-family: var(--police-mono);
	font-size: .74rem;
	color: var(--couleur-accent);
	text-decoration: none;
	white-space: nowrap;
}

.carte__visite:hover { text-decoration: underline; }

/* La lueur qui suit la souris — posée par main.js. */
.carte__lueur {
	position: absolute;
	inset: 0;
	pointer-events: none;
	opacity: 0;
	transition: opacity .3s ease;
	background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, .35), transparent 45%);
}

.carte:hover .carte__lueur { opacity: 1; }

/* ---------- Offres ---------- */

.offres {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	gap: 1.3rem;
	margin-top: 2.4rem;
	position: relative;
}

.offre {
	position: relative;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	gap: .3rem;
	border-radius: var(--rayon);
	padding: 1.7rem;
	background: rgba(255, 255, 255, .045);
	border: 1px solid rgba(255, 255, 255, .1);
	transition: transform .3s cubic-bezier(.2, .7, .2, 1), border-color .3s ease, background .3s ease;
}

.offre:hover {
	transform: translateY(-8px);
	border-color: rgba(42, 199, 212, .6);
	background: rgba(42, 199, 212, .07);
}

/* Le reflet qui traverse la carte au survol. */
.offre::before {
	content: '';
	position: absolute;
	top: 0; left: -80%;
	width: 60%; height: 100%;
	transform: skewX(-18deg);
	background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .09), transparent);
	transition: left .6s ease;
}

.offre:hover::before { left: 130%; }

/* `.offre__no` a été retiré : quatre tailles de site ne forment pas une
   suite, et « 01 » laissait croire à un ordre d'étapes. */
/* h2 ET h3 : sur Tarifs les cartes suivent le h1 et sont des h2 ; sur
   l'accueil et les pages de ville, elles vivent sous un h2 de section et
   restent des h3. Le niveau change, l'apparence non. */
.offre h2, .offre h3 { margin: .7rem 0 0; font-size: 1.12rem; }

/* Le prix est le sujet de la carte, pas son sous-titre. À 1,9 rem il se
   lisait comme une légende sous le nom du forfait ; sur une page de tarifs,
   c'est le chiffre qu'on vient chercher. */
.offre__prix {
	margin: .35rem 0 .7rem;
	font: 700 clamp(2.3rem, 3.2vw, 3rem)/1 var(--police-titres);
	background: var(--degrade);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.offre__prix small { font-size: .78rem; font-weight: 500; color: var(--attenue-sombre); -webkit-text-fill-color: var(--attenue-sombre); }

/* Le prix régulier, barré au-dessus du prix de lancement.
 *
 * Le `background: none` et le `-webkit-text-fill-color` ne sont pas
 * décoratifs : le prix parent est écrit en dégradé découpé sur le texte
 * (`background-clip: text` + `color: transparent`), et un enfant qui hérite de
 * ça s'affiche INVISIBLE. C'est la même précaution que pour le `small`
 * ci-dessus, et elle se paie d'un bogue silencieux quand on l'oublie.
 *
 * En mono et en petit : c'est une annotation factuelle, pas un argument. Le
 * prix qu'on paie doit rester le plus gros chiffre de la carte. */
.offre__avant {
	display: inline-block;
	margin-left: .6rem;
	vertical-align: baseline;
	background: none;
	font: 500 clamp(1rem, 1.25vw, 1.25rem)/1 var(--police-mono);
	letter-spacing: .01em;
	color: var(--attenue-sombre);
	-webkit-text-fill-color: var(--attenue-sombre);
}

/* Le trait est tracé dans la couleur d'accent, pas dans celle du texte : sur
   le fond marine, une rature grise sur un chiffre gris disparaissait — le
   montant se lisait comme un second prix plutôt que comme un prix annulé. */
.offre__avant s {
	text-decoration-line: line-through;
	text-decoration-color: var(--cyan);
	text-decoration-thickness: 2px;
}

/* Seul cas sur fond clair. Les autres blocs de prix — accueil, pages de ville,
   refonte, forfaits récurrents — vivent tous dans une `section--marine`, où le
   gris pâle par défaut est le bon. Étendre cette règle à `.refonte__prix`
   « par précaution » rendrait le montant presque invisible : la précaution
   inverse était le vrai risque. */
.offres--clair .offre__avant {
	color: var(--couleur-attenue);
	-webkit-text-fill-color: var(--couleur-attenue);
}

/* Le médaillon d'icône. Quatre colonnes de texte gris se ressemblent
   toutes : c'est le repère qui les sépare avant même qu'on lise le titre.
   Il s'allume au survol, en même temps que le projecteur. */
.offre__icone {
	display: grid;
	place-items: center;
	width: 44px; height: 44px;
	margin-bottom: .9rem;
	border-radius: 14px;
	background: rgba(42, 199, 212, .12);
	border: 1px solid rgba(42, 199, 212, .3);
	color: var(--cyan);
	transition: background .3s ease, border-color .3s ease, transform .3s cubic-bezier(.2, .7, .2, 1);
}

.offre__icone svg { width: 22px; height: 22px; }

.offre:hover .offre__icone {
	background: rgba(42, 199, 212, .22);
	border-color: rgba(42, 199, 212, .6);
	transform: translateY(-2px) rotate(-4deg);
}

.offres--clair .offre__icone {
	background: rgba(12, 125, 143, .09);
	border-color: rgba(12, 125, 143, .22);
	color: var(--couleur-accent);
}

/* `:not(.offre__prix)` n'est pas de la coquetterie : `.offre p` a une
   spécificité plus forte que `.offre__prix`, donc cette règle écrasait la
   taille du prix. Le prix s'affichait à 0,92 rem — plus petit que le titre
   du forfait — quelle que soit la valeur écrite plus haut. */
.offre p:not(.offre__prix) { font-size: .92rem; color: var(--attenue-sombre); line-height: 1.6; margin: 0; }

.offre__liste { margin: .6rem 0 0; padding: 0; list-style: none; font-size: .9rem; color: var(--attenue-sombre); }
.offre__liste li { position: relative; padding-left: 1.4rem; margin-bottom: .45rem; }

/* Les options sont séparées des inclusions par un filet tireté : elles ne
   sont PAS comprises dans le prix, et les mêler aux coches serait trompeur.
   Le tireté dit « en plus », le plein dirait « avec ». */
.offre__options {
	margin: 1rem 0 0;
	padding-top: .85rem;
	border-top: 1px dashed rgba(255, 255, 255, .2);
}

.offre__options-titre {
	margin: 0 0 .5rem;
	font: 600 .7rem/1 var(--police-mono);
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--cyan);
}

.offre__options ul { margin: 0; padding: 0; list-style: none; font-size: .82rem; color: var(--attenue-sombre); }
.offre__options li { margin-bottom: .3rem; }

/* Le tarif annuel, juste sous le prix mensuel : il dit le rabais sans
   transformer la carte en grille de prix. */
.offre__annuel {
	margin: -.25rem 0 .6rem;
	font-size: .82rem;
	font-weight: 600;
	color: var(--cyan);
}

.offres--clair .offre__options { border-top-color: var(--couleur-trait); }
.offres--clair .offre__options-titre { color: var(--couleur-accent); }
.offres--clair .offre__options ul { color: var(--couleur-attenue); }

/* La coche est dessinée, pas un emoji : même rendu partout. */
.offre__liste li::before {
	content: '';
	position: absolute;
	left: 0; top: .35em;
	width: .8em; height: .45em;
	border-left: 2px solid var(--cyan);
	border-bottom: 2px solid var(--cyan);
	transform: rotate(-45deg);
}

/* Version claire des offres, pour la page Tarifs. */
.offres--clair .offre {
	background: var(--couleur-fond);
	border-color: var(--couleur-trait);
	box-shadow: var(--ombre-carte);
}

/* `background-color` et non `background` : la forme courte remettrait
   `background-image` à zéro, et c'est elle qui porte le projecteur — la
   lueur s'éteignait donc exactement au survol, quand on veut la voir. */
.offres--clair .offre:hover { border-color: var(--couleur-accent); background-color: var(--couleur-fond); }
.offres--clair .offre p, .offres--clair .offre__liste { color: var(--couleur-attenue); }
.offres--clair .offre__prix { background: none; -webkit-text-fill-color: var(--couleur-accent); color: var(--couleur-accent); }
.offres--clair .offre__prix small { -webkit-text-fill-color: var(--couleur-attenue); color: var(--couleur-attenue); }
.offres--clair .offre__liste li::before { border-color: var(--couleur-accent); }

/* ---------- L'aurore de la page Tarifs ----------
   Deux voiles flous qui dérivent lentement derrière les forfaits. C'est ce
   qui remplace le bandeau d'ouverture supprimé : la page ne s'ouvre plus sur
   du blanc, mais elle ne s'ouvre pas non plus sur un pavé de texte — on
   arrive directement sur les prix, posés sur quelque chose de vivant.

   `filter: blur()` sur deux grandes formes coûte cher à repeindre ; elles ne
   sont donc animées qu'en `transform`, que le compositeur traite sans
   redessiner, et `will-change` le lui annonce. Sous prefers-reduced-motion
   la règle globale fige l'animation : les voiles restent, immobiles. */
.fond-aurore {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	background: #F7FAFD;
}

/* Sur l'encre, les voiles montent en intensité : sur un fond quasi blanc,
   la même aurore ne se lisait que comme « pas tout à fait blanc », autant
   dire rien. C'est ce qui manquait pour que la page ait un premier plan. */
.section--marine.fond-aurore { background: var(--encre); }
.section--marine.fond-aurore::before {
	background: radial-gradient(circle, rgba(42, 199, 212, .34), rgba(42, 199, 212, 0) 68%);
}
.section--marine.fond-aurore::after {
	background: radial-gradient(circle, rgba(107, 130, 200, .32), rgba(107, 130, 200, 0) 68%);
}

.fond-aurore::before,
.fond-aurore::after {
	content: '';
	position: absolute;
	z-index: -1;
	border-radius: 50%;
	filter: blur(80px);
	will-change: transform;
	pointer-events: none;
}

.fond-aurore::before {
	top: -22%; left: -14%;
	width: 46%; padding-bottom: 34%;
	background: radial-gradient(circle, rgba(42, 199, 212, .40), rgba(42, 199, 212, 0) 70%);
	animation: cbw-derive-a 26s ease-in-out infinite alternate;
}

.fond-aurore::after {
	top: 6%; right: -18%;
	width: 52%; padding-bottom: 40%;
	background: radial-gradient(circle, rgba(107, 130, 200, .34), rgba(107, 130, 200, 0) 70%);
	animation: cbw-derive-b 34s ease-in-out infinite alternate;
}

@keyframes cbw-derive-a {
	from { transform: translate3d(0, 0, 0) scale(1); }
	to   { transform: translate3d(14%, 18%, 0) scale(1.18); }
}

@keyframes cbw-derive-b {
	from { transform: translate3d(0, 0, 0) scale(1.1); }
	to   { transform: translate3d(-12%, 22%, 0) scale(.92); }
}

.tarifs__titre { font-size: clamp(2.2rem, 4.6vw, 3.4rem); max-width: 20ch; }

/* Le prix en chiffres tabulaires : sans ça, la largeur du nombre saute à
   chaque image pendant que le compteur monte, et toute la carte tremble. */
.offre__prix .compte {
	font-variant-numeric: tabular-nums;
	-webkit-text-fill-color: inherit;
}

/* Le projecteur : une lueur qui suit le curseur dans la carte. Elle vit
   dans le `background-image` plutôt que dans un élément de plus, parce que
   ::before porte déjà le reflet et ::after la hauteur réservée du repère.
   Sans JavaScript, --x et --y n'existent pas et la carte reste unie. */
.offres--clair .offre {
	background-color: var(--couleur-fond);
	background-image: radial-gradient(
		18rem circle at var(--x, 50%) var(--y, -30%),
		rgba(42, 199, 212, .17), rgba(42, 199, 212, 0) 68%
	);
	transition: transform .3s cubic-bezier(.2, .7, .2, 1), border-color .3s ease,
	            box-shadow .3s ease, background-image .3s ease;
}

.section--marine .offre[data-projecteur] {
	background-image: radial-gradient(
		18rem circle at var(--x, 50%) var(--y, -30%),
		rgba(42, 199, 212, .22), rgba(42, 199, 212, 0) 68%
	);
}

/* Le forfait le plus souvent retenu. Un seul repère sur quatre cartes :
   au-delà, plus rien ne ressort. */
.offre--vedette {
	border-color: rgba(42, 199, 212, .55);
	background-color: rgba(42, 199, 212, .06);
	box-shadow: 0 20px 50px rgba(0, 0, 0, .35);
}

.offres--clair .offre--vedette {
	border-color: var(--couleur-accent);
	background-color: var(--couleur-fond);
	box-shadow: 0 18px 46px rgba(12, 125, 143, .18);
}

/* Le filet du haut, où passe le dégradé de la marque. C'est le seul
   mouvement permanent de la page : il désigne la carte sans clignoter.
   Le ::after est libre ici — la hauteur réservée du repère ne concerne que
   les cartes qui n'ont PAS de repère. */
.offre--vedette::after {
	content: '';
	position: absolute;
	top: 0; left: 0; right: 0;
	height: 3px;
	background: linear-gradient(90deg, #54C4BE, #2AC7D4, #4BA3E8, #2AC7D4, #54C4BE);
	background-size: 200% 100%;
	animation: cbw-filet 5s linear infinite;
}

@keyframes cbw-filet { to { background-position: -200% 0; } }

.offre__repere {
	display: inline-flex;
	align-items: center;
	align-self: flex-start;
	height: 1.45rem;
	margin-bottom: .5rem;
	padding: 0 .7rem;
	border-radius: 999px;
	background: var(--couleur-accent);
	color: #fff;
	font: 600 .68rem/1 var(--police-mono);
	letter-spacing: .06em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* Les trois autres cartes réservent la même hauteur, sinon le titre de
   Signature descend seul d'un cran et la rangée paraît de travers.
   `order: -1` place ce vide en tête de la carte, qui est un flex vertical.
   Portée à .offres--tarifs seulement : les cartes d'hébergement n'ont pas
   de repère et n'ont donc rien à réserver. */
.offres--tarifs .offre:not(.offre--vedette)::after {
	content: '';
	order: -1;
	display: block;
	height: 1.45rem;
	margin-bottom: .5rem;
}

/* La refonte : une bande large plutôt qu'une cinquième colonne orpheline.
   Elle ne se compare pas aux quatre tailles, elle répond à une autre
   question — « et si j'ai déjà un site ? ». */
/* Le bloc refonte vit sur le même panneau marine que les forfaits : il en
   reprend donc le verre translucide plutôt que le papier clair d'avant. */
.refonte {
	display: grid;
	grid-template-columns: minmax(200px, 260px) 1fr;
	gap: clamp(1.5rem, 4vw, 3rem);
	align-items: start;
	margin-top: clamp(1.5rem, 3vw, 2.2rem);
	padding: clamp(1.5rem, 3vw, 2.2rem);
	border: 1px solid rgba(255, 255, 255, .14);
	border-left: 3px solid var(--cyan);
	border-radius: var(--rayon);
	background: rgba(255, 255, 255, .04);
	color: var(--texte-sombre);
}

.refonte .offre__icone { margin-bottom: .8rem; }
.refonte .surtitre { color: var(--cyan); margin-bottom: .4rem; }
.refonte h2, .refonte h3 { margin: 0 0 .3rem; font-size: 1.45rem; }
.refonte__prix {
	margin: 0;
	font: 700 clamp(2.3rem, 3.2vw, 3rem)/1 var(--police-titres);
	background: var(--degrade);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	font-variant-numeric: tabular-nums;
}
.refonte p { color: var(--attenue-sombre); max-width: 62ch; }
.refonte .offre__liste { color: var(--attenue-sombre); }
.refonte .offre__liste li::before { border-color: var(--cyan); }
.refonte__liste { columns: 2; column-gap: 2.5rem; margin-top: 1rem; }
.refonte__liste li { break-inside: avoid; }

@media (max-width: 760px) {
	.refonte { grid-template-columns: 1fr; }
	.refonte__liste { columns: 1; }
}

/* ---------- Procédé ---------- */

/* Un filet en tête de chaque entrée, pas un numéro. Ces quatre arguments
   ne forment aucune suite : les numéroter laissait croire à un ordre — de
   priorité, d'étape — qui n'existe pas. Même raison que sur Réalisations. */
.procede {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 2rem 1.6rem;
	margin: 2.4rem 0 0;
	padding: 0;
	list-style: none;
}

.procede li::before {
	content: '';
	display: block;
	width: 2.2rem; height: 2px;
	margin-bottom: .9rem;
	background: var(--couleur-accent);
}

.section--marine .procede li::before { background: var(--cyan); }

.procede h3 { font-size: 1.06rem; margin-bottom: .35rem; }
.procede p { font-size: .93rem; color: var(--couleur-attenue); margin: 0; }
.section--marine .procede p { color: var(--attenue-sombre); }

/* ---------- Tableau des inclusions ---------- */

.tableau-defile { overflow-x: auto; margin-top: 2.2rem; border: 1px solid var(--couleur-trait); border-radius: var(--rayon); background: var(--couleur-fond); }

.inclusions { width: 100%; min-width: 620px; border-collapse: collapse; }

.inclusions th, .inclusions td {
	padding: .8rem 1.1rem;
	text-align: left;
	border-bottom: 1px solid var(--couleur-trait);
	font-size: .92rem;
}

.inclusions thead th {
	background: var(--papier);
	font: 700 .7rem/1.3 var(--police-mono);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--couleur-attenue);
	white-space: nowrap;
}

.inclusions thead th:not(:first-child) { text-align: center; }
.inclusions tbody tr:last-child th, .inclusions tbody tr:last-child td { border-bottom: 0; }
.inclusions tbody th { font-weight: 500; color: var(--couleur-attenue); }

.inclusions td.v {
	text-align: center;
	font-family: var(--police-mono);
	font-size: .84rem;
	color: var(--couleur-attenue);
	white-space: nowrap;
}

.inclusions td.v.oui { color: var(--couleur-accent); font-weight: 600; }
.inclusions td.v.non { opacity: .45; }

/* La rangée survolée s'éclaire : sur douze lignes et cinq colonnes, l'œil
   perd la ligne qu'il suit dès qu'il arrive à droite. */
.inclusions tbody tr { transition: background-color .2s ease; }
.inclusions tbody tr:hover { background-color: rgba(42, 199, 212, .07); }

/* La colonne Signature est teintée en permanence, comme sa carte plus haut :
   c'est le même forfait qu'on désigne, il doit se retrouver du même œil.
   Quatrième cellule : la première est l'intitulé de ligne. */
.inclusions thead th:nth-child(4),
.inclusions tbody td:nth-child(4) { background-color: rgba(42, 199, 212, .06); }
.inclusions tbody tr:hover td:nth-child(4) { background-color: rgba(42, 199, 212, .13); }

/* Le tableau se remplit de haut en bas plutôt que d'apparaître d'un bloc :
   chaque rangée entre avec le retard posé par le gabarit. C'est le conteneur
   qui porte [data-anim] et reçoit `.vu` ; les rangées suivent. */
html.est-pret .tableau-defile tbody tr {
	opacity: 0;
	transform: translateY(10px);
	transition: opacity .45s ease, transform .45s cubic-bezier(.2, .7, .2, 1);
	transition-delay: var(--retard, 0ms);
}

html.est-pret .tableau-defile.vu tbody tr { opacity: 1; transform: none; }

.note-fine { margin-top: 1rem; font-size: .86rem; color: var(--couleur-attenue); max-width: 74ch; }

/* ---------- FAQ ---------- */

.faq { margin-top: 2.2rem; max-width: 780px; }
.faq details { border-bottom: 1px solid var(--couleur-trait); }

.faq summary {
	position: relative;
	padding: 1.1rem 2rem 1.1rem 0;
	cursor: pointer;
	font: 700 1.04rem/1.4 var(--police-titres);
	list-style: none;
}

.faq summary::-webkit-details-marker { display: none; }

/* Le <h3> à l'intérieur du <summary> ne doit rien changer à l'œil : il est là
   pour la structure du document, pas pour l'apparence. Sans ces trois lignes,
   la marge et la taille par défaut de h3 casseraient l'alignement du chevron
   et l'espacement des huit lignes. */
.faq summary h3 {
	display: inline;
	margin: 0;
	font: inherit;
	color: inherit;
}

/* Le marqueur est un chevron dessiné, pas un « + » remplacé par un « − » :
   un changement de `content` ne s'anime pas, une rotation oui. */
.faq summary::after {
	content: '';
	position: absolute;
	right: .5rem; top: calc(50% - .28rem);
	width: .55rem; height: .55rem;
	border-right: 2px solid var(--couleur-accent);
	border-bottom: 2px solid var(--couleur-accent);
	transform: rotate(45deg);
	transition: transform .3s cubic-bezier(.2, .7, .2, 1);
}

.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover { color: var(--couleur-accent); }

.faq details > p { color: var(--couleur-attenue); padding-bottom: 1.1rem; }

/* La réponse ne peut pas s'ouvrir en hauteur sans JavaScript, mais elle
   peut entrer en fondu : c'est ce qui enlève l'effet de saut. */
.faq details[open] > p { animation: cbw-repli .38s cubic-bezier(.2, .7, .2, 1); }

@keyframes cbw-repli {
	from { opacity: 0; transform: translateY(-8px); }
	to   { opacity: 1; transform: none; }
}

/* ---------- Partenaire ---------- */

/* Le bloc porte les couleurs de BrandNous et non les nôtres : leur noir
   #171519 et leur orange #F58922, relevés sur brandnous.ca. C'est une carte
   de visite posée dans notre page — elle doit ressembler à eux, sinon le
   partenariat a l'air d'un argument de vente qu'on s'est écrit soi-même.
   Comme elle est sombre des deux côtés, elle n'a plus de variante claire. */
.partenaire {
	display: grid;
	grid-template-columns: 168px 1fr;
	gap: 2rem;
	align-items: center;
	margin-top: 2.2rem;
	padding: 1.9rem 2rem;
	border-radius: var(--rayon);
	background: #171519;
	border: 1px solid rgba(245, 137, 34, .3);
	color: #F3EFEA;
	box-shadow: 0 18px 46px rgba(0, 0, 0, .28);
}

.partenaire__marque {
	display: block;
	padding-right: 2rem;
	border-right: 1px solid rgba(255, 255, 255, .14);
}

.partenaire__marque img { width: 100%; height: auto; }

.partenaire__etiquette {
	margin: 0 0 .5rem;
	font-family: var(--police-mono);
	font-size: .74rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: #F58922;
}

.partenaire h3 { margin-bottom: .35rem; color: #fff; }
.partenaire p { margin: 0; font-size: .95rem; color: #B9B2AC; max-width: 62ch; }
.partenaire a {
	color: #F58922;
	text-underline-offset: .2em;
	text-decoration-thickness: 1px;
}
.partenaire a:hover { color: #FFA451; }

@media (max-width: 620px) {
	.partenaire { grid-template-columns: 1fr; gap: 1.4rem; }
	.partenaire__marque {
		max-width: 140px;
		padding: 0 0 1.3rem;
		border-right: 0;
		border-bottom: 1px solid rgba(255, 255, 255, .14);
	}
}

/* ---------- Territoire ---------- */

.territoire__liste {
	display: flex;
	flex-wrap: wrap;
	gap: .6rem;
	margin: 1.8rem 0 0;
	padding: 0;
	list-style: none;
}

.territoire__liste a {
	display: inline-block;
	padding: .55rem 1.05rem;
	border: 1px solid var(--couleur-trait);
	border-radius: 999px;
	background: var(--couleur-fond);
	font-size: .9rem;
	font-weight: 500;
	text-decoration: none;
	transition: border-color .15s ease, color .15s ease;
}

.territoire__liste a:hover { border-color: var(--couleur-accent); color: var(--couleur-accent); }
.territoire__ailleurs { margin-top: 1.4rem; font-size: .95rem; color: var(--couleur-attenue); }

/* ---------- Appel final ---------- */

/* La vague animait `background-position`, une propriété de PEINTURE : toute
   la bande était redessinée en continu, sur chaque page, sans fin. Le même
   mouvement passe maintenant par la translation d'un calque deux fois plus
   large, que le compositeur déplace sans redessiner un seul pixel. */
.appel {
	position: relative;
	isolation: isolate;
	overflow: hidden;
	text-align: center;
	color: var(--texte-sombre);
	background: var(--encre);
}

.appel::before {
	content: '';
	position: absolute;
	z-index: -1;
	inset-block: 0;
	left: -50%;
	width: 200%;
	background: linear-gradient(120deg, #0A1220, #0E2A3C 30%, #123D53 50%, #0E2A3C 70%, #0A1220);
	animation: cbw-vague 18s ease-in-out infinite alternate;
	will-change: transform;
	pointer-events: none;
}

@keyframes cbw-vague {
	from { transform: translate3d(0, 0, 0); }
	to   { transform: translate3d(25%, 0, 0); }
}

.appel__titre { max-width: 22ch; margin-inline: auto; }
.appel__note { max-width: 46ch; margin: .8rem auto 0; color: var(--attenue-sombre); }
.appel .groupe-actions { justify-content: center; margin-top: 2rem; }

/* ---------- Bandeau des pages intérieures ---------- */

.page-bandeau {
	position: relative;
	overflow: hidden;
	color: var(--texte-sombre);
	background: linear-gradient(175deg, var(--encre) 60%, #0C1B30);
}

.page-bandeau::after {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: radial-gradient(50% 70% at 78% 30%, rgba(42, 199, 212, .12), transparent 70%);
}

.page-bandeau__cadre { position: relative; z-index: 1; padding-block: clamp(2.8rem, 6vw, 4.5rem); }
.page-bandeau h1 { margin-bottom: 0; max-width: 18ch; }
.page-bandeau__intro { margin: 1rem 0 0; max-width: 56ch; color: var(--attenue-sombre); font-size: 1.05rem; }

/* ==================================================================
   Signatures de page
   ------------------------------------------------------------------
   Chaque page intérieure a son ossature. Un bandeau sombre suivi de
   sections alternées sur les cinq pages donnait un site « gabarit » :
   les mots changeaient, la forme jamais.
   ================================================================== */

/* ---------- Ouverture claire, pour les pages qui n'ont pas de bandeau ---------- */

.ouverture { padding-block: clamp(3rem, 7vw, 5rem) clamp(1.5rem, 3vw, 2.5rem); }
.ouverture__titre { font-size: clamp(2.6rem, 7vw, 5rem); line-height: .98; max-width: 16ch; }
.ouverture__intro { margin-top: 1.4rem; max-width: 54ch; font-size: 1.1rem; color: var(--couleur-attenue); }

.ouverture__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 1.2rem 2.4rem;
	margin-top: 2.2rem;
	padding-top: 1.4rem;
	border-top: 2px solid var(--couleur-texte);
	font-family: var(--police-mono);
	font-size: .8rem;
	color: var(--couleur-attenue);
}

/* ---------- Le dégradé maillé des Réalisations ----------
   Quatre lueurs radiales superposées sur un blanc cassé froid : bleu-acier
   en haut à gauche, bleu poussiéreux en bas à droite, deux voiles pâles au
   milieu pour éviter une transition franche.

   La première version reprenait le sarcelle du rendu Firefly à la lettre et
   virait au vert : le sarcelle a autant de vert que de bleu, et sur une
   grande surface pâle c'est le vert qui domine. La lueur a donc été
   rebasculée vers le bleu, et le blanc de fond n'est plus verdi.

   En CSS plutôt qu'en image, et c'est un choix : zéro octet à télécharger,
   aucune requête, net à toutes les densités d'écran, et le dégradé épouse
   la hauteur de la page quel que soit le nombre de projets. Une image de
   2400 px aurait dû être étirée ou répétée dès la douzième réalisation.

   Le voile blanc du bas éteint la teinte avant le panneau marine de
   l'appel : sans lui, le sarcelle butait sur le marine. */
.fond-maille {
	background:
		linear-gradient(to bottom, rgba(255, 255, 255, 0) 80%, #ffffff 100%),
		radial-gradient(118% 82% at -4% -6%,   rgba(84, 146, 178, .82), rgba(84, 146, 178, 0) 58%),
		radial-gradient(104% 76% at 104% 106%, rgba(128, 148, 196, .86), rgba(128, 148, 196, 0) 56%),
		radial-gradient(72% 54% at 88% 34%,    rgba(218, 231, 243, .85), rgba(218, 231, 243, 0) 62%),
		radial-gradient(64% 46% at 26% 62%,    rgba(255, 255, 255, .80), rgba(255, 255, 255, 0) 60%),
		#F2F5F9;
}

/* Le montage des appareils n'a plus de panneau derrière lui, donc les
   captures se posent à même le dégradé. Une ombre un peu plus dense les
   décolle de la teinte, sinon elles y flottaient. */
.fond-maille .appareil { box-shadow: 0 18px 42px rgba(19, 35, 59, .26); }
.fond-maille .appareil--tablette { box-shadow: 0 16px 34px rgba(19, 35, 59, .30); }
.fond-maille .appareil--mobile { box-shadow: 0 14px 28px rgba(19, 35, 59, .34); }

/* ---------- Réalisations ----------
   Une grille de cartes plutôt qu'une bande pleine largeur par projet. Les
   bandes alternées montraient le travail en grand, mais huit d'entre elles
   faisaient 5 600 px de page : à vingt projets la page devenait intenable,
   et c'est exactement le sens de cette section, qui va s'allonger.

   `auto-fill` avec un minimum de 400 px règle seul le nombre de colonnes :
   trois sur un grand écran, deux sur un portable, une sur un téléphone.
   Rien à retoucher quand un projet s'ajoute. */
.projets {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 400px), 1fr));
	gap: clamp(1.8rem, 3.5vw, 3rem) clamp(1.5rem, 2.5vw, 2.5rem);
	padding-block: clamp(1.5rem, 3vw, 2.5rem) clamp(2.5rem, 5vw, 4rem);
}

.projet { position: relative; display: flex; flex-direction: column; }

/* Aucun panneau derrière les appareils. Il y a eu d'abord un dégradé aux
   couleurs du client, puis un plan clair uniforme : dans les deux cas, une
   grosse pastille arrondie posée derrière les écrans, qui ajoutait un objet
   là où il n'y en avait pas besoin. Les appareils reposent maintenant
   directement sur la page, et seules leurs ombres les décollent. */
.projet__media { position: relative; }

/* Le repli : l'ancienne capture unique, quand un site n'a pas encore ses
   trois formats. */
.projet__media > img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	object-position: top;
}

/* ---------- Le montage à trois appareils ----------
   Un socle en ratio fixe, trois cadres posés dessus en pourcentages : tout
   se met à l'échelle avec la colonne, sans média-requête pour les tailles.
   Les cadres sont dessinés en CSS et les captures sont trois fichiers
   distincts — pas une image de maquette aplatie. On garde donc des bords
   nets à toute densité, et on remplace une capture sans rouvrir un
   éditeur d'images. */
/* `container-type: inline-size` transforme le socle en unité de mesure : les
   `cqw` qui suivent valent 1 % de SA largeur, quelle que soit celle de
   l'écran. C'est ce qui permet de donner aux cadres des proportions
   d'appareils réels — une bordure d'iPhone fait 2,7 % de la largeur du
   téléphone, pas 5 px. En px fixes, la même bordure paraissait fine sur un
   grand écran et énorme dans une colonne étroite : c'est ce qui donnait au
   téléphone son air de jouet. Chaque valeur est doublée d'un repli en px
   pour les navigateurs qui ignorent les unités de conteneur. */
.appareils {
	position: relative;
	container-type: inline-size;
	aspect-ratio: 16 / 11;
	padding: 7% 6% 8%;
}

/* Les ombres sont calées sur le plan clair : les valeurs sombres d'avant
   avaient été réglées sur un fond teinté et faisaient des taches ici. */
.appareil {
	position: absolute;
	overflow: hidden;
	background: #0A1220;
	box-shadow: 0 16px 38px rgba(19, 35, 59, .20);
}

.appareil img { display: block; width: 100%; height: auto; }

/* L'écran de bureau, au fond et à gauche. */
.appareil--bureau {
	left: 0; top: 3%;
	width: 80%;
	border-radius: 8px;
	border-radius: 1.1cqw;
	padding-top: 22px;               /* la place de la barre du navigateur */
	padding-top: 3.6cqw;
	border: 1px solid rgba(19, 35, 59, .14);
}

.appareil__barre {
	position: absolute;
	top: 0; left: 0; right: 0;
	height: 22px;
	height: 3.6cqw;
	display: flex;
	align-items: center;
	gap: 5px;
	gap: .8cqw;
	padding-left: 9px;
	padding-left: 1.4cqw;
	background: #16233C;
}

.appareil__barre i {
	width: 6px; height: 6px;
	width: .95cqw; height: .95cqw;
	border-radius: 50%;
	background: rgba(255, 255, 255, .3);
}

/* La tablette ferme le montage à droite. Les deux appareils portatifs
   partagent la même ligne de base : posés à ras du bord, leurs coins
   arrondis se faisaient trancher par l'`overflow: hidden` du panneau.

   Le cadre est un dégradé et non un aplat : la diagonale claire imite le
   reflet sur la tranche métallique, et c'est ce détail-là, plus que la
   forme, qui fait lire « appareil » plutôt que « rectangle noir ». */
.appareil--tablette {
	right: 0; bottom: 7%;
	width: 27%;
	border: 0;
	border-radius: 12px;
	border-radius: 1.9cqw;
	padding: 7px;
	padding: .95cqw;                 /* 3,5 % de la largeur : bordure d'iPad */
	background: linear-gradient(145deg, #48505F, #14171D 26%, #14171D 74%, #48505F);
	box-shadow: 0 14px 32px rgba(19, 35, 59, .26);
}

.appareil--tablette img { border-radius: 5px; border-radius: 1cqw; }

/* L'œil de la caméra, en haut de la bordure. */
.appareil--tablette::after {
	content: '';
	position: absolute;
	top: .3cqw; left: 50%;
	transform: translateX(-50%);
	width: .28cqw; height: .28cqw;
	border-radius: 50%;
	background: #4C5566;
}

/* Le téléphone est à GAUCHE de la tablette, et devant elle. Les trois
   appareils se lisent ainsi du plus grand au plus petit en s'avançant vers
   le lecteur, et le plus petit n'est plus coincé contre le bord droit. */
.appareil--mobile {
	right: 24%; bottom: 7%;
	width: 15%;
	z-index: 2;
	border: 0;
	border-radius: 14px;
	border-radius: 2.2cqw;           /* 14,7 % de la largeur, comme un iPhone */
	padding: 5px;
	padding: .4cqw;                  /* 2,7 % : la bordure d'un vrai téléphone */
	background: linear-gradient(145deg, #525B6B, #14171D 22%, #14171D 78%, #525B6B);
	box-shadow: 0 12px 26px rgba(19, 35, 59, .32);
}

.appareil--mobile img { border-radius: 9px; border-radius: 1.8cqw; }

/* Pas d'îlot dynamique. La pastille noire posée sur l'écran cachait le haut
   du site présenté — c'est-à-dire son logo et son menu, exactement ce qu'on
   vient montrer. La forme du cadre suffit à dire « téléphone ». */

/* Les boutons latéraux. Un seul pseudo-élément suffit : une `box-shadow`
   sans étalement redessine la même forme ailleurs, ce qui donne les deux
   touches de volume à gauche et le bouton de veille à droite. */
.appareil--mobile::before {
	content: '';
	position: absolute;
	z-index: 3;
	left: -.22cqw; top: 7.4cqw;
	width: .22cqw; height: 1.5cqw;
	border-radius: .2cqw 0 0 .2cqw;
	background: #39414F;
	box-shadow:
		0 2.1cqw 0 #39414F,          /* la seconde touche de volume */
		15.22cqw 1.4cqw 0 #39414F;   /* le bouton de veille, sur l'autre tranche */
}

/* Le montage ne bouge plus au survol. Un montage d'appareils est une
   image de produit : le faire grossir donne l'impression qu'il flotte,
   et le déplacement décollait les ombres du plan sur lequel ils reposent. */

/* Les trois appareils tiennent jusqu'à 520 px de large : c'est le montage
   qui fait la démonstration, le retirer sur les écrans étroits reviendrait
   à ne plus rien montrer là où ça compte le plus. En dessous, la colonne
   descend sous 300 px et le téléphone n'y est plus qu'un trait : il sort,
   et la tablette prend sa place. */
@media (max-width: 520px) {
	.appareil--mobile { display: none; }
	.appareil--tablette { width: 30%; }
}

/* La légende, sous le montage. Elle occupe la hauteur restante pour que la
   mention « Visiter le site » s'aligne d'une carte à l'autre, même quand un
   métier tient sur deux lignes. */
.projet__pied {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding-top: 1.1rem;
}

.projet__nom { font-size: clamp(1.25rem, 1.6vw, 1.5rem); margin-bottom: .3rem; }
.projet__metier { margin-bottom: .2rem; font-size: .92rem; color: var(--couleur-attenue); }
.projet__region { margin: 0; font-family: var(--police-mono); font-size: .76rem; color: var(--couleur-attenue); }

/* La date de validité des prix. Discrète : c'est une garantie, pas un
   argument — elle rassure celui qui la cherche sans distraire les autres. */
.tarifs__maj {
	margin-top: .9rem;
	font-family: var(--police-mono);
	font-size: .76rem;
	letter-spacing: .04em;
	color: var(--couleur-attenue);
}

/* La description du projet. Un filet à gauche plutôt qu'un encadré : la carte
   porte déjà un montage à trois écrans, et un second bloc fermé l'aurait
   alourdie. La marge haute est plus grande que l'écart métier/région pour que
   l'identification du projet reste un groupe, et la description un second. */
.projet__resume {
	margin: .9rem 0 0;
	padding-left: .85rem;
	border-left: 2px solid var(--couleur-trait);
	font-size: .93rem;
	line-height: 1.62;
	color: var(--couleur-attenue);
	text-wrap: pretty;
}

/* Le récit du travail livré dans la ville. Un paragraphe d'accroche, plus
   grand que le corps mais pas un titre : c'est le texte qui donne son sens aux
   cartes de projet qui le suivent, sur le fond clair de la section « papier ». */
.ville__recit {
	max-width: 66ch;
	margin: 1.4rem 0 0;
	font-size: clamp(1.02rem, 1.5vw, 1.18rem);
	line-height: 1.65;
	color: var(--couleur-texte);
	text-wrap: pretty;
}

.projet__lien { color: inherit; text-decoration: none; }

/* Le lien du titre couvre toute la carte : on peut cliquer n'importe où,
   sans imbriquer un lien autour du montage ni doubler la cible pour les
   lecteurs d'écran. */
.projet__lien::after { content: ''; position: absolute; inset: 0; }

.projet__visite {
	display: block;
	margin-top: auto;
	padding-top: 1rem;
	font-weight: 600;
	font-size: .9rem;
	color: var(--couleur-accent);
}

.projet:hover .projet__nom { color: var(--couleur-accent); }
.projet__lien:focus-visible::after { outline: 2px solid var(--couleur-accent); outline-offset: 4px; }

/* ---------- Services ----------
   L'ancienne « échelle » — un index collant à gauche, cinq paliers avec
   leurs prix à droite — a été retirée : elle répétait mot pour mot la page
   Tarifs. Services montre maintenant le travail, le déroulement et le socle
   commun ; les prix n'existent plus que sur Tarifs. */

/* Les prestations : une grille de trois vraies cartes.
   Elles étaient de simples colonnes de texte séparées par un filet, sans
   encadré ni icône — c'est ce qui faisait de Services la page la plus fade
   du site, et la seule à ne pas partager son langage. Elles reprennent
   maintenant le traitement des cartes de forfait : médaillon d'icône,
   projecteur qui suit le curseur, filet dégradé qui se remplit en haut.
   Le numéro 01–06 a sauté au passage : six prestations ne forment pas une
   suite, et l'icône dit mieux ce que le numéro ne disait pas. */
.prestations {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: clamp(1.5rem, 3vw, 2.2rem);
	margin-top: clamp(1.8rem, 3vw, 2.6rem);
}

/* Cartes SOMBRES sur l'aplat cyan. En blanc sur blanc, elles n'avaient
   qu'un filet gris et une ombre douce : aucune présence. C'est le même
   défaut que les forfaits avant qu'ils passent sur l'encre — mais posé à
   l'envers ici, cartes sombres sur fond clair, pour que Services et Tarifs
   restent deux pages et pas la même deux fois. */
.prestation {
	position: relative;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	padding: clamp(1.5rem, 2.6vw, 2rem);
	border: 1px solid rgba(255, 255, 255, .12);
	border-radius: var(--rayon);
	background-color: var(--encre);
	background-image: radial-gradient(
		18rem circle at var(--x, 50%) var(--y, -30%),
		rgba(42, 199, 212, .22), rgba(42, 199, 212, 0) 68%
	);
	color: var(--texte-sombre);
	box-shadow: 0 18px 42px rgba(19, 35, 59, .22);
	transition: transform .3s cubic-bezier(.2, .7, .2, 1), border-color .3s ease,
	            box-shadow .3s ease;
}

.prestation:hover {
	transform: translateY(-5px);
	border-color: rgba(42, 199, 212, .6);
	box-shadow: 0 28px 58px rgba(19, 35, 59, .3);
}

/* Le filet du haut, qui se remplit au survol. Posé PAR-DESSUS la bordure et
   animé en largeur : animer la bordure elle-même ferait sauter la mise en
   page d'un pixel à chaque survol. */
.prestation::before {
	content: '';
	position: absolute;
	top: 0; left: 0;
	width: 0; height: 3px;
	background: var(--degrade);
	transition: width .5s cubic-bezier(.2, .7, .2, 1);
}

.prestation:hover::before { width: 100%; }

/* Médaillon plus grand, et qui rayonne. À 44 px avec une icône de 22, il se
   lisait comme une décoration ; à 58 avec une icône de 28 et une lueur
   cyan, il se voit à distance — c'est ce qui distingue les six cartes
   avant même qu'on lise un titre. */
.prestation__icone {
	display: grid;
	place-items: center;
	width: 58px; height: 58px;
	margin-bottom: 1.1rem;
	border-radius: 18px;
	background: rgba(42, 199, 212, .14);
	border: 1px solid rgba(42, 199, 212, .38);
	box-shadow: 0 0 26px rgba(42, 199, 212, .18) inset;
	color: var(--cyan);
	transition: background .3s ease, border-color .3s ease, box-shadow .3s ease,
	            transform .3s cubic-bezier(.2, .7, .2, 1);
}

.prestation__icone svg { width: 28px; height: 28px; }

.prestation:hover .prestation__icone {
	background: rgba(42, 199, 212, .24);
	border-color: rgba(42, 199, 212, .75);
	box-shadow: 0 0 34px rgba(42, 199, 212, .35) inset, 0 0 18px rgba(42, 199, 212, .35);
	transform: translateY(-2px) rotate(-4deg);
}

.prestation h3 { font-size: 1.3rem; margin-bottom: .5rem; }
.prestation > p { color: var(--attenue-sombre); font-size: .95rem; }

/* Le lien du titre couvre toute la carte : elles étaient six culs-de-sac
   qui décrivaient le travail sans mener nulle part. */
.prestation__lien { color: inherit; text-decoration: none; }
.prestation__lien::after { content: ''; position: absolute; inset: 0; }
.prestation:hover h3 { color: var(--cyan); }
.prestation__lien:focus-visible::after { outline: 2px solid var(--cyan); outline-offset: -4px; border-radius: var(--rayon); }

/* `margin-top: auto` colle la mention au bas de la carte : sur six cartes
   de hauteurs différentes, elles s'alignent toutes sur la même ligne. */
.prestation__voir {
	display: block;
	margin-top: auto;
	padding-top: 1.1rem;
	font-weight: 600;
	font-size: .88rem;
	color: var(--cyan);
}

.prestation__points {
	list-style: none;
	margin: 1rem 0 0;
	padding: 0;
	font-size: .88rem;
	color: var(--attenue-sombre);
}

.prestation__points li { position: relative; padding-left: 1.1rem; margin-bottom: .35rem; }
.prestation__points li::before {
	content: '';
	position: absolute;
	left: 0; top: .55em;
	width: 5px; height: 5px;
	border-radius: 50%;
	background: var(--cyan);
}

@media (max-width: 1000px) { .prestations { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .prestations { grid-template-columns: 1fr; } }

/* Un aplat cyan pleine saturation a été essayé sous les prestations puis
   retiré : il faisait entrer une quatrième sorte de fond dans le site pour
   un seul bloc. Elles reprennent `.fond-maille`, le maillage bleu-acier des
   Réalisations — le contraste vient des cartes sombres, pas du fond. */

/* Le parcours, en colonne verticale.
 *
 * Il était en rang de six : à 1 600 px, chaque étape n'avait que 230 px de
 * large, le texte y descendait en colonnes étroites, et l'ensemble se
 * lisait comme une bande dense plutôt que comme un déroulement. En vertical
 * chaque étape a toute la mesure et la durée peut être grosse.
 *
 * Et pas de numéros : la ligne continue et la position de haut en bas
 * portent l'ordre à elles seules. Un « 3 » ne faisait que répéter ce que
 * l'œil savait déjà.
 */
.parcours {
	position: relative;
	list-style: none;
	margin: clamp(2.2rem, 4vw, 3.2rem) 0 0;
	padding: 0;
}

/* La ligne qui relie les étapes, tirée derrière les pastilles. Elle
   s'arrête à la dernière : prolongée jusqu'en bas, elle pendait dans le
   vide sous le dernier paragraphe. */
.parcours::before {
	content: '';
	position: absolute;
	left: 5px; top: .6rem; bottom: 4.5rem;
	width: 1px;
	background: var(--trait-sombre);
}

/* Une seule colonne depuis qu'on a retiré la durée : l'étape n'est plus qu'un
   titre et un texte, tenus par la ligne verticale et sa pastille. */
.parcours__etape {
	position: relative;
	padding: 0 0 clamp(1.8rem, 3vw, 2.6rem) 2.6rem;
}

.parcours__etape:last-child { padding-bottom: 0; }

/* La pastille sur la ligne. Pleine et cyan : c'est le seul repère, il doit
   se voir sans porter de chiffre. */
.parcours__etape::before {
	content: '';
	position: absolute;
	left: 0; top: .55rem;
	width: 11px; height: 11px;
	border-radius: 50%;
	background: var(--cyan);
	box-shadow: 0 0 0 4px var(--encre), 0 0 12px rgba(42, 199, 212, .6);
}

.parcours__etape h3 { margin: 0 0 .35rem; font-size: 1.25rem; }

.parcours__etape p {
	margin: 0;
	font-size: .95rem;
	color: var(--attenue-sombre);
	max-width: 62ch;
}

/* ---------- À propos ---------- */

/* L'ouverture, sur l'encre. Deux colonnes : le titre à gauche, les faits à
   droite. Avant, la moitié droite de l'écran restait vide et le titre
   flottait — sur une page dont le sujet est « qui nous sommes », ce vide
   était le premier message. */
.tete-sombre { padding-block: clamp(3rem, 7vw, 5.5rem) clamp(3rem, 6vw, 4.5rem); }

.tete-sombre__cadre {
	display: grid;
	grid-template-columns: 1.15fr .85fr;
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: center;
}

.tete-sombre .ouverture__titre { max-width: 14ch; }

.tete-sombre__intro {
	margin-top: 1.4rem;
	max-width: 52ch;
	font-size: 1.1rem;
	color: var(--attenue-sombre);
}

@media (max-width: 900px) { .tete-sombre__cadre { grid-template-columns: 1fr; } }

/* Les engagements, et non des statistiques : « 8 sites livrés » se lisait
   comme un palmarès maigre, alors que « 1 jour pour obtenir une réponse »
   est une promesse que le client peut nous opposer. */
.faits {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1.4rem 2rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.faits li { padding-top: 1rem; border-top: 1px solid var(--trait-sombre); }

.faits strong {
	display: block;
	font: 700 clamp(1.9rem, 3vw, 2.6rem)/1 var(--police-titres);
	background: var(--degrade);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	font-variant-numeric: tabular-nums;
}

.faits span { display: block; margin-top: .35rem; font-size: .85rem; color: var(--attenue-sombre); }

/* Les deux fiches. Le monogramme tient la place d'un portrait : le jour où
   deux vraies photos existent, elles se glissent dans le même carré sans
   toucher au reste. Une photo d'agence achetée en banque d'images serait
   pire que ces initiales sur une page dont l'argument est qu'on est deux
   vraies personnes. */
.equipe {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: clamp(1.5rem, 3vw, 2.2rem);
	margin-top: clamp(1.8rem, 3vw, 2.6rem);
}

.equipier {
	position: relative;
	overflow: hidden;
	padding: clamp(1.6rem, 3vw, 2.2rem);
	border: 1px solid var(--couleur-trait);
	border-radius: var(--rayon);
	background-color: var(--couleur-fond);
	background-image: radial-gradient(
		18rem circle at var(--x, 50%) var(--y, -30%),
		rgba(12, 125, 143, .10), rgba(12, 125, 143, 0) 68%
	);
	box-shadow: var(--ombre-carte);
	transition: transform .3s cubic-bezier(.2, .7, .2, 1), border-color .3s ease;
}

.equipier:hover { transform: translateY(-4px); border-color: var(--couleur-accent); }

/* Le monogramme a disparu du gabarit : un carré de couleur aux initiales
   tenait la place d'un portrait qui n'existe pas, et sur une page qui promet
   qu'on parle à du vrai monde, un avatar inventé se voit. Le rôle monte donc
   au-dessus du nom et devient le premier repère de la carte : le visiteur
   cherche « qui répond au téléphone » avant de chercher un prénom. */
.equipier__role {
	margin: 0 0 .35rem;
	font: 500 .78rem/1.3 var(--police-mono);
	letter-spacing: .07em;
	color: var(--couleur-accent);
}

.equipier h3 { font-size: 1.5rem; margin-bottom: .8rem; }

/* La ligne directe : le pied de carte, détaché par un filet. C'est ce qui
   remplace le portrait — une carte qui compose un appel vaut mieux qu'une
   carte qui montre un visage. */
.equipier__ligne {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: .35rem 1.2rem;
	margin: 1.3rem 0 0;
	padding-top: 1.1rem;
	border-top: 1px solid var(--couleur-trait);
	font-family: var(--police-mono);
	font-size: .84rem;
}

.equipier__ligne-titre {
	flex: 0 0 100%;
	margin-bottom: .25rem;
	font-size: .72rem;
	letter-spacing: .08em;
	color: var(--couleur-attenue);
}

.equipier__ligne a {
	color: var(--couleur-accent);
	text-underline-offset: .25em;
	text-decoration-thickness: 1px;
}

.equipier__ligne a:hover { color: var(--couleur-texte); }

/* `:not([class])` vise le SEUL paragraphe descriptif de la carte. Sans lui,
   `.equipier p` (une classe + un type) l'emporte sur `.equipier__role`,
   `.equipier__faire` et `.equipier__ligne` (une classe chacun) : le rôle
   repassait en .95 rem attenué et la ligne directe perdait sa mono. C'est le
   troisième cas de ce piège dans ce fichier, après `.offre p` contre
   `.offre__prix` et `.parcours__etape p` contre `.parcours__quand`. */
.equipier p:not([class]) { color: var(--couleur-attenue); font-size: .95rem; }

/* Ce que chacun fait, en étiquettes : on repère son interlocuteur d'un coup
   d'œil, sans relire le paragraphe. */
.equipier__faire { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1.1rem 0 0; }

.equipier__faire span {
	padding: .3rem .7rem;
	border: 1px solid var(--couleur-trait);
	border-radius: 999px;
	font-family: var(--police-mono);
	font-size: .72rem;
	color: var(--couleur-attenue);
}

/* La citation en pleine largeur. Seule dans une demi-colonne, elle laissait
   les deux tiers de sa hauteur vides ; une phrase qu'on veut voir lue
   occupe toute la mesure. */
.edito__citation--large {
	max-width: 30ch;
	font-size: clamp(1.8rem, 4vw, 3rem);
	margin-bottom: clamp(1.8rem, 3vw, 2.6rem);
}

/* Colonne de gauche qui suit le défilement, pour les sections où la liste
   de droite est bien plus haute que son titre. `align-self: start` est
   indispensable : dans une grille, un enfant est étiré par défaut, et un
   élément étiré ne peut pas coller. */
.edito--suiveur { grid-template-columns: .85fr 1.15fr; }
.edito--suiveur .edito__tete { position: sticky; top: calc(var(--h-entete) + 2rem); align-self: start; }

@media (max-width: 860px) {
	.edito--suiveur { grid-template-columns: 1fr; }
	.edito--suiveur .edito__tete { position: static; }
}

.edito__colonnes { columns: 2; column-gap: clamp(2rem, 4vw, 3.5rem); }
.edito__colonnes p { break-inside: avoid; color: var(--couleur-attenue); max-width: none; }

@media (max-width: 820px) {
	.edito__citation--large { max-width: none; }
	.edito__colonnes { columns: 1; }
}

/* ---------- Le socle ----------
 * Ce bloc portait le meilleur argument des Services — ce qui ne se retire
 * d'aucun forfait — sous la forme la plus faible qui soit : une liste à
 * puces en deux colonnes, texte à gauche, cochées à droite. Une puce
 * énumère des détails ; elle ne dit pas qu'ils forment un ensemble.
 *
 * D'où la plaque. Le texte passe en tête sur toute la largeur, et les huit
 * lignes deviennent huit cases d'une même dalle. Les filets entre elles ne
 * sont pas des bordures mais les `gap` du conteneur, qui laissent voir son
 * fond : un seul pixel partout, jamais doublé aux jonctions, ce qu'aucune
 * combinaison de border-right/border-bottom n'obtient proprement.
 *
 * Et par-dessus, la ligne dégradée : elle traverse les quatre colonnes d'un
 * trait continu, et c'est elle le socle. C'est la seule chose de la page qui
 * relie les huit cases entre elles. */
.socle { display: block; }
.socle__mot { max-width: 56ch; }

.socle__plan {
	position: relative;
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 1px;
	margin-top: clamp(1.8rem, 3vw, 2.6rem);
	background: var(--couleur-trait);
	border: 1px solid var(--couleur-trait);
	border-radius: var(--rayon);
	/* Sans ça, les coins carrés des cases débordent des coins arrondis de la
	   dalle et le filet se voit dépasser aux quatre angles. */
	overflow: hidden;
}

/* La ligne continue, posée PAR-DESSUS les cases : en fond du conteneur elle
   serait masquée par la première rangée, qui est opaque. */
.socle__plan::before {
	content: '';
	position: absolute;
	inset-inline: 0;
	top: 0;
	height: 3px;
	background: var(--degrade);
	z-index: 2;
	pointer-events: none;
}

.socle__pierre {
	display: flex;
	align-items: flex-start;
	gap: .85rem;
	/* Assez haut pour que la dalle pèse : à 1,45 rem, les huit cases faisaient
	   une bande de 180 px sous un titre qui en fait 140, et la plaque avait
	   l'air d'un pied de page. La hauteur minimale égalise du même coup les
	   cases d'une ligne et celles qui passent sur deux. */
	min-height: 116px;
	padding: 1.7rem 1.45rem;
	background-color: var(--couleur-fond);
	transition: background-color .25s ease;
}

/* Le survol teinte la case sans toucher `background`, qui porte déjà le
   blanc du jeton : une couche d'image par-dessus, et le fond reste le fond. */
.socle__pierre:hover { background-color: #EEFAFC; }

/* La police des titres, pas celle du corps : ce sont des affirmations
   courtes, pas de la prose. C'est ce qui les fait lire comme un relevé. */
.socle__pierre p {
	margin: 0;
	font-family: var(--police-titres);
	font-weight: 500;
	font-size: 1.02rem;
	line-height: 1.35;
	color: var(--couleur-texte);
	text-wrap: balance;
}

/* Même coche en deux traits que partout ailleurs sur le site, mais posée sur
   une plaquette teintée : seule, à cette taille de case, elle disparaissait. */
.socle__coche {
	position: relative;
	flex: 0 0 26px;
	height: 26px;
	margin-top: .1rem;
	border-radius: 8px;
	background: rgba(12, 125, 143, .09);
}

.socle__coche::before {
	content: '';
	position: absolute;
	left: 8px; top: 9px;
	width: 10px; height: 5px;
	border-left: 2px solid var(--couleur-accent);
	border-bottom: 2px solid var(--couleur-accent);
	transform: rotate(-45deg);
}

/* Les cases se remplissent une colonne après l'autre quand la dalle entre —
   même mécanique que les rangées du tableau des inclusions : c'est le
   conteneur qui porte [data-anim] et reçoit `.vu`.
   En opacité seule, sans translation : la dalle est en `overflow: hidden`,
   et une case qui glisse y laisse voir un filet vide sous elle. Comme le
   fond du conteneur est le gris des filets, la dalle est là dès le départ
   et les pierres s'y posent — ce qui est exactement le propos. */
html.est-pret .socle__plan .socle__pierre {
	opacity: 0;
	/* Le raccourci `transition` de .socle__pierre est écrasé ici : la teinte
	   de survol doit être reconduite, sinon elle claque. Le retard est porté
	   par la seule opacité — en `transition-delay` global, il retardait aussi
	   la teinte, et la dernière colonne réagissait un quart de seconde après
	   le curseur. */
	transition: opacity .5s ease var(--retard, 0ms), background-color .25s ease;
}

html.est-pret .socle__plan.vu .socle__pierre { opacity: 1; }

/* Le sceau chiffre la portée de la dalle plutôt que de répéter l'intro. */
.socle__sceau {
	margin: 1rem 0 0;
	font-family: var(--police-mono);
	font-size: .78rem;
	letter-spacing: .03em;
	color: var(--couleur-attenue);
	text-align: right;
	max-width: none;
}

@media (max-width: 1080px) { .socle__plan { grid-template-columns: repeat(2, 1fr); } }

@media (max-width: 560px) {
	.socle__plan { grid-template-columns: 1fr; }
	.socle__sceau { text-align: left; }
}

/* ---------- Ce qu'on ne fait pas soi-même ----------
 * La section n'avait qu'un titre, une phrase et la carte du partenaire seule
 * au milieu du blanc : elle se lisait comme une note de bas de page alors
 * qu'elle dit une chose qu'aucun concurrent n'écrit. Elle prend donc la forme
 * éditoriale du reste du site (titre à gauche, raisonnement à droite), et
 * l'atmosphère bascule dans l'orange de BrandNous là où leur carte se pose.
 *
 * Une seule voile, immobile et floue, derrière le contenu. Elle n'est pas
 * animée : `fond-aurore` est le fond des grands panneaux du site, et le
 * reprendre ici en ferait un panneau, alors que c'est un accent. */
.horslot {
	position: relative;
	isolation: isolate;
	overflow: hidden;
}

.horslot::before {
	content: '';
	position: absolute;
	z-index: -1;
	/* Calée sur la carte, pas sur la section : la voile doit sembler émaner du
	   panneau de BrandNous. Posée plus bas ou plus large, elle teintait le
	   titre, qui n'est pas d'eux. */
	left: 50%;
	bottom: 6%;
	width: min(1000px, 92%);
	padding-bottom: 20%;
	transform: translateX(-50%);
	border-radius: 50%;
	background: radial-gradient(ellipse, rgba(245, 137, 34, .30), rgba(245, 137, 34, 0) 70%);
	filter: blur(76px);
	pointer-events: none;
}

.horslot__tete {
	display: grid;
	grid-template-columns: 1fr 1.2fr;
	gap: clamp(1.4rem, 4vw, 3.5rem);
	align-items: start;
}

.horslot__texte p { color: var(--couleur-attenue); font-size: 1.02rem; }
.horslot__texte p + p { margin-top: .9rem; }

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

/* Le renvoi vers Tarifs : le seul endroit de la page où un prix apparaît. */
.renvoi__cadre {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.6rem 3rem;
}

.renvoi__cadre h2 { margin-bottom: .4rem; }
.renvoi__cadre .section__intro { margin-top: 0; max-width: 58ch; }

/* ---------- À propos : éditorial, asymétrique ---------- */

.edito { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }

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

.edito__citation {
	font-family: var(--police-titres);
	font-weight: 700;
	font-size: clamp(1.5rem, 3.2vw, 2.3rem);
	line-height: 1.2;
	letter-spacing: -.02em;
	text-wrap: balance;
}

.edito__citation em { font-style: normal; color: var(--couleur-accent); }
.edito__source { margin-top: 1.2rem; font-family: var(--police-mono); font-size: .8rem; color: var(--couleur-attenue); }
.edito__texte p { color: var(--couleur-attenue); }

/* Quatre règles, sans numéros : elles se valent toutes, et « 01 » laissait
   croire à un classement. Une coche dessinée dit ce qu'il faut — c'est une
   règle tenue, pas une étape. */
.principes { margin: 2rem 0 0; padding: 0; list-style: none; }

.principes li {
	display: grid;
	grid-template-columns: 2.4rem 1fr;
	gap: 1rem;
	padding-block: 1.4rem;
	border-bottom: 1px solid var(--trait-sombre);
}

.principes li:last-child { border-bottom: 0; }

.principes li::before {
	content: '';
	width: 13px; height: 7px;
	margin-top: .55rem;
	border-left: 2px solid var(--cyan);
	border-bottom: 2px solid var(--cyan);
	transform: rotate(-45deg);
}

.principes h3 { margin-bottom: .3rem; }
.principes p { margin: 0; color: var(--attenue-sombre); font-size: .95rem; }

/* ---------- Contact : le formulaire, et ce qui suit ---------- */

/* ---------- Page contact ----------
 * Le rapport clair/sombre est inversé par rapport au reste du site : le
 * panneau est sur l'encre, et le formulaire est la plaque blanche posée
 * dessus. Sur une page dont le seul but est qu'on remplisse un formulaire,
 * l'objet le plus lumineux de l'écran doit être ce formulaire. */

/* Le titre et l'intro côte à côte : empilés, ils laissaient toute la moitié
   droite du premier écran vide. Sur les autres pages c'est la liste des faits
   qui occupe cette colonne ; ici il n'y a pas de chiffre à y mettre qui ne
   répète pas déjà le « ce qui arrive ensuite », alors c'est l'intro qui monte. */
.contact-tete {
	display: grid;
	grid-template-columns: 1.1fr .9fr;
	gap: clamp(1.4rem, 4vw, 3.5rem);
	align-items: end;
	margin-bottom: clamp(2.2rem, 4vw, 3.4rem);
}

.contact-tete__intro { margin: 0 0 .4rem; font-size: 1.1rem; color: var(--attenue-sombre); max-width: 48ch; }

@media (max-width: 860px) {
	.contact-tete { grid-template-columns: 1fr; align-items: start; }
	.contact-tete__intro { margin-bottom: 0; }
}

/* Deux colonnes : la plaque du formulaire, et à droite les coordonnées pour
   qui préfère appeler. La bande claire qui fermait la page a été remontée ici :
   elle remplit la moitié droite laissée vide par le « ce qui arrive ensuite »
   retiré, et évite au panneau marine de couler seul dans le pied sombre. */
.contact-grille { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }

@media (max-width: 860px) { .contact-grille { grid-template-columns: 1fr; } }

.contact-grille .formulaire { margin-top: 0; max-width: none; }

/* La plaque rétablit le thème clair à l'intérieur du panneau sombre : tout
   ce qu'elle contient hérite de `--couleur-texte`, donc les étiquettes des
   champs n'ont besoin d'aucune règle propre. L'ombre est plus lourde que
   `--ombre-carte` : sur l'encre, une ombre de fond clair ne se voit pas, et
   c'est elle qui décolle la plaque du panneau. */
.contact-plaque {
	padding: clamp(1.5rem, 3vw, 2.4rem);
	border-radius: var(--rayon);
	background: var(--couleur-fond);
	color: var(--couleur-texte);
	box-shadow: 0 30px 70px rgba(0, 0, 0, .45);
}

/* Sur la plaque blanche, des champs blancs ne se voyaient pas : ils prennent
   le papier, et c'est le creux qui les désigne comme des champs. */
.contact-plaque .champ input,
.contact-plaque .champ textarea { background: var(--papier); }

.contact-plaque .champ input:focus-visible,
.contact-plaque .champ textarea:focus-visible { background: var(--couleur-fond); }

/* `.section--marine :focus-visible` passe l'anneau au cyan pour les panneaux
   sombres. À l'intérieur de la plaque, le fond est blanc et le cyan n'y tient
   que 1,9:1 : on rétablit l'accent profond. */
.contact-plaque :focus-visible { outline-color: var(--couleur-accent); }

.formulaire__note {
	grid-column: 1 / -1;
	margin: .2rem 0 0;
	font-size: .85rem;
	color: var(--couleur-attenue);
}

/* La colonne des coordonnées, à droite du formulaire, dans le panneau marine :
   texte clair, accents cyan, et un filet à gauche qui la rattache à la plaque.
   Elle a remplacé la bande claire qui fermait la page. */
.contact-coord {
	padding-left: clamp(1.2rem, 2.5vw, 2.4rem);
	border-left: 1px solid var(--trait-sombre);
	color: var(--attenue-sombre);
}

.contact-coord__titre {
	margin: .2rem 0 1.8rem;
	font-size: clamp(1.3rem, 2vw, 1.55rem);
	color: var(--texte-sombre);
}

.contact-coord__bloc { margin-bottom: 1.7rem; }
.contact-coord__bloc:last-child { margin-bottom: 0; }

.contact-coord__quoi {
	margin: 0 0 .35rem;
	font: 600 .78rem/1.3 var(--police-mono);
	letter-spacing: .07em;
	text-transform: uppercase;
	color: var(--cyan);
}

.contact-coord__grand {
	display: inline-block;
	font-size: clamp(1.35rem, 2.2vw, 1.7rem);
	font-weight: 600;
	line-height: 1.15;
	color: var(--texte-sombre);
	text-decoration: none;
}

.contact-coord__grand:hover { color: var(--cyan); }
.contact-coord__grand--mail { font-size: clamp(1rem, 1.6vw, 1.15rem); word-break: break-word; }

.contact-coord__note { margin: .35rem 0 0; font-size: .9rem; color: var(--attenue-sombre); }

@media (max-width: 860px) {
	.contact-coord {
		border-left: 0;
		border-top: 1px solid var(--trait-sombre);
		padding-left: 0;
		padding-top: 1.8rem;
	}
}

/* Le bouton d'envoi est le seul geste de la page : il occupe toute la largeur
   de la plaque sous le champ le plus large, plutôt que de flotter en pastille
   dans un coin. */
.contact-plaque .formulaire__pied { margin-top: .4rem; }
.contact-plaque .formulaire__pied .bouton { padding-inline: 2.4rem; font-size: 1.02rem; }

@media (max-width: 520px) {
	.contact-plaque .formulaire__pied .bouton { width: 100%; }
}

/* ---------- Contenu libre et gabarits génériques ---------- */

.prose { padding-block: var(--rythme); }
.prose > .cadre > * + * { margin-top: 1em; }
.prose h2 { margin-top: 1.6em; }
.prose ul { padding-left: 1.2rem; }
.prose a { color: var(--couleur-accent); }

/* Le conteneur de repli d'index.php.
   IL S'APPELLE `cbw-page` ET NON `page` : WordPress pose lui-même la classe
   `page` sur le <body> de toute page statique (comme `home`, `blog`,
   `single`, `search`, `archive`, `error404`). Un sélecteur `.page` attrapait
   donc le body entier et enfermait tout le site — en-tête et bandeaux
   compris — dans 1220 px. Ne jamais réutiliser un de ces noms réservés. */
.cbw-page {
	max-width: var(--largeur-max);
	margin-inline: auto;
	padding-inline: var(--gouttiere);
	padding-block: 1.5rem var(--rythme);
}

.cbw-page > * + * { margin-top: 1em; }
.cbw-page a { color: var(--couleur-accent); }

/* ---------- Formulaire ---------- */

.formulaire {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1.2rem;
	margin-top: 2.2rem;
	max-width: 720px;
}

.champ--large { grid-column: 1 / -1; }

@media (max-width: 640px) {
	.formulaire { grid-template-columns: 1fr; }
	.champ--large { grid-column: 1; }
}

.champ label { display: block; margin-bottom: .4rem; font: 600 .88rem/1.3 var(--police-corps); }

.champ input, .champ textarea {
	width: 100%;
	padding: .85rem 1rem;
	border: 1px solid var(--couleur-trait);
	border-radius: var(--rayon-petit);
	background: var(--couleur-fond);
	font: 1rem/1.5 var(--police-corps);
	color: var(--couleur-texte);
}

.champ input:focus-visible, .champ textarea:focus-visible {
	outline: 2px solid var(--couleur-accent);
	outline-offset: 0;
	border-color: var(--couleur-accent);
}

.champ textarea { min-height: 9rem; resize: vertical; }

.formulaire__pied {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem 1.6rem;
}

.formulaire__etat { margin: 0; font-size: .95rem; color: var(--couleur-accent); }

/* ---------- Survol : seulement là où il y a un vrai curseur ----------
 * Sur un écran tactile, `:hover` COLLE après le doigt : la carte reste
 * soulevée, l'image agrandie et le logo déplacé jusqu'à ce qu'on touche
 * ailleurs. Ce n'est pas un détail sur un site dont la moitié du trafic se
 * lit au téléphone.
 *
 * On neutralise le DÉPLACEMENT, pas le survol entier : les changements de
 * couleur et de bordure restent, ils ne collent pas de la même façon et
 * confirment le tap. */
@media (hover: none), (pointer: coarse) {
	.bouton--principal:hover,
	.confiance__logo:hover,
	.equipier:hover,
	.carte:hover .carte__ecran img,
	.entete__action:hover .gommette {
		transform: none;
	}

	/* ---------- Cibles tactiles ----------
	 *
	 * Mesuré sur le site en ligne à 375 px : vingt-six liens et boutons sous
	 * les 44 px que demandent Apple, Google et le critère WCAG 2.5.8. Les
	 * pires étaient les plus utiles — le téléphone à 28 px de haut alors que
	 * c'est l'action principale sur mobile, le sélecteur de langue à 22 px de
	 * large, et « visiter → » à 20 px.
	 *
	 * Rien de tout ça ne se voyait à l'œil : la cible est plus petite que ce
	 * qu'on croit viser, et le doigt rate sans qu'on sache pourquoi.
	 *
	 * Agrandi ICI seulement, sous `pointer: coarse`. À la souris, un lien de
	 * 28 px se clique très bien, et gonfler tous les liens du site casserait
	 * le rythme typographique des pages. */
	.lien-tel,
	.carte__visite,
	a.pied__ligne,
	.chantier .etapes button,
	.territoire__liste a,
	.pied__nav-liste a,
	.pastille {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	/* Un mot court fait une cible étroite : « Tarifs » à 39 px, « Work » à
	   37 px dans le pied, alors que la hauteur était déjà bonne. La largeur
	   minimale règle les mots d'une syllabe sans toucher aux autres. */
	.pied__nav-liste a { min-width: 44px; }

	/* Le doigt vise le centre : une largeur de 22 px se rate une fois sur
	   trois, même quand la hauteur est bonne. */
	.langues__lien {
		min-width: 44px;
		justify-content: center;
	}

	/* 40x42 : il manquait peu, mais c'est le bouton qui ouvre tout le menu.
	   Le rater, c'est ne plus pouvoir naviguer. */
	.entete__burger {
		min-width: 44px;
		min-height: 44px;
	}

	/* Sous 12 px, un libellé se lit mal sur un écran tenu à bout de bras.
	   Mesuré à 375 px : le sélecteur FR/EN à 11,5 px, « visiter → » à
	   11,8 px. Ce sont les deux seuls textes INTERACTIFS sous ce seuil, et
	   ils montent à 12,8 px. La devise du pied, à 11,5 px elle aussi, reste
	   telle quelle : elle se regarde, elle ne se tape pas. */
	.langues,
	.carte__visite {
		font-size: .8rem;
	}

	/* NE SONT PAS AGRANDIS, et c'est volontaire : « BrandNous Média » dans le
	   bloc partenaire et « Confidentialité » au bas du pied sont des liens au
	   milieu d'une phrase. Le critère WCAG 2.5.8 les exempte explicitement,
	   parce que leur taille est dictée par l'interligne du texte autour : les
	   pousser à 44 px crèverait des trous dans le paragraphe pour gagner une
	   cible que personne ne vise en urgence. */
}

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

/* Un filet clair en haut du pied : sur les pages qui finissent par un panneau
   sombre (contact, appels marine), il empêche le pied de couler dans la
   section précédente sans avoir besoin d'une bande claire intermédiaire. */
.pied { background: var(--encre); color: var(--attenue-sombre); font-size: .93rem; border-top: 1px solid var(--trait-sombre); }

/* Quatre colonnes plutôt que trois, et un rythme à lui plutôt que le
   --rythme des sections : le pied empilait « on dessert » sous le menu, ce
   qui allongeait la colonne la plus haute et donc tout le bloc. Étalé sur
   quatre pistes avec des marges resserrées, il perd environ un tiers de sa
   hauteur sans rien perdre de son contenu. */
.pied__cadre {
	display: grid;
	grid-template-columns: 1.5fr .9fr .8fr .9fr;
	gap: 2.2rem;
	padding-block: clamp(2rem, 3.4vw, 2.8rem) 1.9rem;
}

@media (max-width: 1080px) { .pied__cadre { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (max-width: 820px)  { .pied__cadre { grid-template-columns: 1fr 1fr; gap: 1.8rem; } }
@media (max-width: 520px)  { .pied__cadre { grid-template-columns: 1fr; } }

.pied__marque { display: flex; align-items: center; gap: .8rem; margin-bottom: .8rem; }
.pied__badge { width: 46px; height: 46px; flex: none; border-radius: 50%; overflow: hidden; }
.pied__nom { margin: 0; font: 700 1.15rem/1.15 var(--police-titres); color: var(--texte-sombre); }

.pied__devise {
	margin: .1rem 0 0;
	font-family: var(--police-mono);
	font-size: .72rem;
	letter-spacing: .06em;
	color: var(--cyan);
}

.pied__titre {
	margin-bottom: .7rem;
	font: 500 .8rem/1.3 var(--police-mono);
	letter-spacing: .07em;
	color: var(--texte-sombre);
}

.pied address { font-style: normal; }
.pied a { color: var(--texte-sombre); text-decoration: none; }
.pied a:hover { color: var(--cyan); }
.pied__ligne { display: block; margin-bottom: .45rem; }

.pied__nav ul { margin: 0; padding: 0; list-style: none; }
.pied__nav li { margin-bottom: .45rem; }

.pied__zones-liste { margin: 0; color: var(--attenue-sombre); }

.pied__partenaire { margin: .9rem 0 0; font-size: .85rem; }
.pied__partenaire a { color: #F58922; }
.pied__partenaire a:hover { color: #FFA451; }

.pied__legal {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem 2rem;
	justify-content: space-between;
	padding-block: 1.1rem 1.2rem;
	border-top: 1px solid var(--trait-sombre);
	font-size: .85rem;
}

.pied__legal a { text-decoration: underline; text-underline-offset: 3px; }


/* ================================================================== *
 * Consentement — Loi 25
 * Bannière de témoins et fenêtre d'explication du formulaire. Habillées
 * aux mêmes jetons que le reste : encre et cyan, pas un bandeau gris générique.
 * ================================================================== */

.consent {
	position: fixed;
	left: 50%;
	bottom: clamp(.8rem, 2vw, 1.5rem);
	transform: translateX(-50%);
	z-index: 200;
	width: min(700px, calc(100vw - 1.6rem));
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .9rem 1.4rem;
	padding: 1.05rem 1.3rem;
	background: var(--encre);
	color: var(--attenue-sombre);
	border: 1px solid rgba(255, 255, 255, .12);
	border-radius: var(--rayon);
	box-shadow: 0 18px 50px rgba(0, 0, 0, .42);
	font-size: .9rem;
	line-height: 1.5;
	animation: consent-entree .4s cubic-bezier(.2, .7, .2, 1) both;
}

@keyframes consent-entree {
	from { opacity: 0; transform: translate(-50%, 14px); }
	to   { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
	.consent { animation: none; }
}

.consent__texte { margin: 0; flex: 1 1 320px; }
.consent__texte a {
	color: var(--cyan);
	text-decoration: none;
	border-bottom: 1px solid rgba(42, 199, 212, .45);
}
.consent__texte a:hover { border-bottom-color: var(--cyan); }

.consent__actions { display: flex; gap: .6rem; flex: 0 0 auto; }
.consent .bouton { padding: .55rem 1.15rem; font-size: .85rem; }
.consent__refuser {
	background: transparent;
	color: var(--attenue-sombre);
	border: 1px solid rgba(255, 255, 255, .22);
}
.consent__refuser:hover { color: #fff; border-color: rgba(255, 255, 255, .45); }

/* Sur un petit écran, les deux boutons prennent toute la largeur, côte à côte. */
@media (max-width: 520px) {
	.consent__actions { flex: 1 1 100%; }
	.consent__actions .bouton { flex: 1; text-align: center; }
}

/* L'avis de consentement du formulaire : consentement par l'envoi, pas de
   case. Fine print, couleur héritée pour coller au fond de la section. */
.formulaire__consent {
	margin: .2rem 0 1.2rem;
	color: inherit;
	opacity: .85;
	font-size: .88rem;
	line-height: 1.5;
}
.formulaire__case {
	display: flex;
	gap: .6rem;
	align-items: flex-start;
	color: inherit;
	font-size: .92rem;
	line-height: 1.45;
	cursor: pointer;
}
.formulaire__case input {
	margin-top: .2rem;
	width: 1.15rem;
	height: 1.15rem;
	flex: 0 0 auto;
	accent-color: var(--couleur-accent);
}
.formulaire__consent-plus {
	display: inline-block;
	margin-top: .5rem;
	padding: 0;
	background: none;
	border: 0;
	color: inherit;
	font: inherit;
	font-size: .85rem;
	text-decoration: underline;
	text-underline-offset: 3px;
	opacity: .85;
	cursor: pointer;
}
.formulaire__consent-plus:hover { opacity: 1; }

/* La fenêtre <dialog> : fond clair, lisible, refermable. */
.consent-modal {
	max-width: 460px;
	width: calc(100vw - 2rem);
	padding: clamp(1.4rem, 3vw, 2rem);
	border: 1px solid var(--couleur-trait);
	border-radius: var(--rayon);
	color: var(--couleur-texte);
	background: #fff;
	box-shadow: 0 24px 60px rgba(10, 18, 32, .3);
}
.consent-modal::backdrop { background: rgba(10, 18, 32, .55); }
.consent-modal h2 { margin: 0 0 .8rem; font-size: 1.3rem; }
.consent-modal p { margin: 0 0 .8rem; color: var(--couleur-attenue); line-height: 1.6; font-size: .95rem; }
.consent-modal a { color: var(--couleur-accent); }
.consent-modal .bouton { margin-top: .4rem; }

/* La date de mise à jour de la politique, discrète. */
.prose__maj {
	margin: 0 0 1.8rem;
	font-family: var(--police-mono);
	font-size: .82rem;
	color: var(--couleur-attenue);
}
