/**
 * AquaGones — residual CSS (design « Innovant » : bento éditorial).
 *
 * Only what theme.json cannot express: bento grids, hover states, floating
 * pill navbar, decorative gradients/glows, photo-header cards, the connected
 * process frieze, the asymmetric realisations mosaic, form inputs, FAQ marker
 * and the responsive collapse. Colours reference theme.json preset tokens
 * (var(--wp--preset--color--*)) so the palette stays single-sourced.
 */

:root {
	/* Autorise l'interpolation des mots-clés de taille (`auto`) : indispensable
	   pour animer la hauteur des réponses de la FAQ vers leur hauteur réelle. */
	interpolate-size: allow-keywords;
	/* Warm editorial neutrals (kept out of the palette: text/borders only). */
	--aqg-page: #F4EFE7;
	--aqg-border-warm: #ECE0D0;
	--aqg-border-warm-2: #F0E8DD;
	--aqg-border-aide: #D7E9DD;
	--aqg-header-border: rgba(13, 34, 51, .08);
	/* Secondary text on white must stay >= 4.5:1 (WCAG AA); #5C6670 = 5.8:1. */
	--aqg-muted: #5C6670;
	--aqg-muted-2: #5C6670;
	/* Nom de marque du bandeau : gris chaud « logo », maintenu >= 4.5:1 sur blanc (#7C7264 = 4.7:1 AA). */
	--aqg-brand: #7C7264;
	/* Texte des pilules. Créé le 2026-08-21 quand le bleu de la palette, alors
	   #0092D6, ne tenait pas l'AA sur une pilule (3,45:1 sur blanc pour un lien
	   de 15px) ; il valait alors #0077B0, en dur. Depuis le bleu foncé de la
	   palette (#14387F, 11,04:1 sur blanc), il n'est plus qu'un alias de `primary` :
	   les règles qui le lisent restent inchangées. */
	--aqg-chip-ink: var(--wp--preset--color--primary);
	--aqg-input-bg: #F7F2EA;
	/* Délimitation des champs. WCAG 1.4.11 demande 3:1 pour ce qui identifie un
	   composant d'interface, et l'aplat seul ne suffisait pas : #F7F2EA sur le
	   panneau blanc du formulaire ne vaut que 1,11:1, mesuré sur 150 champs.
	   #8C8579 tient 3,66:1 contre le panneau blanc et 3,28:1 contre l'aplat du
	   champ, donc des deux côtés du trait. */
	--aqg-input-border: #8C8579;
	/* Alias de lecture sur `accent-light`. Le jeton vit dans la PALETTE et non
	   ici en dur, pour deux raisons. `theme.json` déclare `custom: false`, donc le
	   client ne peut poser que des couleurs de la palette : sorti d'elle, cet
	   orange devenait inatteignable, et un intertitre « Orange AquaGones » posé
	   sur une section marine serait tombé à 3,29:1 sans que rien ne le signale. Et
	   l'en-tête de ce fichier promet que les couleurs sont mono-sourcées depuis
	   `theme.json` : une valeur en dur ici, dupliquée dans `editor.css`, aurait
	   recréé le défaut de parité que ce dépôt paie déjà ailleurs.

	   Orange de MARQUE, conservé tel quel et RÉSERVÉ au fond marine `ink-deep`,
	   où il vaut 5,22:1. Le jeton de palette a été foncé à #AF590C pour que du
	   blanc tienne l'AA dessus, mais ce même assombrissement le fait tomber à
	   3,29:1 sur le marine : sous le seuil de 4,5 pour du TEXTE. L'orange est en
	   effet à la fois surface sous du blanc et encre sur du sombre, et aucune
	   valeur unique ne satisfait les deux. Mesuré : blanc sur orange ≥ 4,5
	   impose une luminosité ≤ 38,7 %, orange sur marine ≥ 4,5 en impose ≥ 44,0 %.
	   NE JAMAIS poser ce jeton sur un fond clair : 2,71:1 sur la toile crème de
	   la page, donc sous le seuil de 3:1 y compris pour un objet non textuel. Le
	   3,11:1 sur blanc, souvent cité, est le cas le plus favorable. */
	--aqg-accent-on-dark: var(--wp--preset--color--accent-light);
	/* Marine section text ramps. */
	--aqg-marine-soft: #C3D3DE;
	--aqg-marine-faint: #8FA7B8;
	--aqg-blue-bright: var(--wp--preset--color--primary-light);
	/* Soft editorial shadows. */
	--aqg-shadow-card: 0 26px 46px -28px rgba(13, 34, 51, .32);
	--aqg-shadow-nav: 0 16px 40px -26px rgba(13, 34, 51, .4);
	--aqg-shadow-stat: 0 22px 44px -24px rgba(13, 34, 51, .28);
	--aqg-ico-blue: linear-gradient(135deg, #EAF0FA, #D6E1F3);
	--aqg-ico-orange: linear-gradient(135deg, #FDEEE0, #FBDDC3);
}

/* Warm cream page canvas (slightly warmer than the surface preset). */
body {
	background-color: var(--aqg-page);
	/* Largeur des titres (Archivo, police à axe de largeur) : 108 % au bureau,
	   100 % sous 768px, où les titres longs en français déborderaient. La
	   propriété est héritée, mais seule la face d'Archivo déclare une plage de
	   largeur (`fontStretch` dans theme.json) : Manrope et Space Grotesk, à face
	   unique, restent dessinées telles quelles. */
	font-stretch: 108%;
}

@media (max-width: 767px) {
	body {
		font-stretch: 100%;
	}
}

/* Liseré décoratif bleu et rouge, en haut de page et au-dessus du pied de
   page : 3px de bleu, 3px de rouge. Jamais sur un élément cliquable. Ce
   rouge (#DA0812) est réservé au liseré, distinct du rouge des erreurs du
   formulaire (#B42318). Pseudo-élément sans texte, ignoré des lecteurs
   d'écran. */
body::before,
.aqg-footer::before {
	content: "";
	display: block;
	height: 6px;
	background: linear-gradient(to bottom, var(--wp--preset--color--primary) 0 3px, #DA0812 3px 6px);
}

/* ---------- Shell & section rhythm ---------- */
.aqg-shell {
	width: 100%;
	max-width: 1240px;
	margin-inline: auto;
	padding-inline: 40px;
}

.aqg-shell--narrow {
	max-width: 980px;
}

.aqg-main > section {
	padding-block-end: 72px;
}

/* Higher specificity than `.aqg-main > section` so these tighter rhythms win. */
.aqg-main > section.aqg-hero {
	padding-block: 26px 0;
}

.aqg-main > section.aqg-stats-wrap,
.aqg-main > section.aqg-certs-wrap {
	padding-block-end: 46px;
}

/* ---------- Floating pill navbar ---------- */
/* Navbar sticky. Le sticky doit porter sur le WRAPPER du template part (enfant
   direct de .wp-site-blocks, qui fait toute la hauteur de page) : posé sur
   .aqg-header, il ne collait pas car son parent .wp-block-template-part ne fait
   que la hauteur du header. */
.wp-site-blocks > header.wp-block-template-part {
	position: sticky;
	top: 0;
	z-index: 50;
}

.aqg-header {
	position: relative;
	z-index: 50;
	padding: 16px 20px 0;
	background: transparent;
}

.aqg-navpill {
	/* Bloc conteneur du méga-menu : la pilule est centrée dans la fenêtre et
	   plafonnée à 1240px, un panneau ancré dessus ne peut donc pas déborder du
	   viewport. `position: relative` sans z-index ne crée pas de contexte
	   d'empilement, l'ordre de peinture du header est inchangé. */
	position: relative;
	max-width: 1240px;
	margin-inline: auto;
	gap: 20px;
	padding: 10px 12px 10px 16px;
	border-radius: 22px;
	/* Pas de backdrop-filter ici : sous 900px la feuille du menu est en
	   position:fixed, et tout ancêtre portant backdrop-filter devient son bloc
	   conteneur, ce qui l'enfermerait dans la pilule. Le flou est rétabli à
	   partir de 901px (voir la requête média) ; sur mobile un fond presque
	   opaque garde la pilule lisible sans lui. Point de bascule UNIQUE, cf. le
	   bloc « Navigation principale » plus bas : 900px. */
	background: rgba(251, 247, 241, .96);
	border: 1px solid var(--aqg-header-border);
	box-shadow: var(--aqg-shadow-nav);
	transition: box-shadow .25s ease, background-color .25s ease;
}

/* Règle 1/3 du point de bascule unique (900px) : le flou de la pilule. */
@media (min-width: 901px) {
	.aqg-navpill {
		background: rgba(251, 247, 241, .82);
		backdrop-filter: blur(14px);
		-webkit-backdrop-filter: blur(14px);
	}
}

/* ==========================================================================
   Navigation principale — méga-menu (ordinateur) et feuille mobile
   --------------------------------------------------------------------------
   POINT DE BASCULE UNIQUE : 900 px. Trois règles DOIVENT partager cette
   valeur, faute de quoi la feuille mobile, qui est en `position: fixed`, se
   retrouve enfermée dans la pilule :
     1. le `backdrop-filter` de `.aqg-navpill`  → @media (min-width: 901px)
     2. le `transform` de l'intro du header     → @media (min-width: 901px)
     3. la bascule méga-menu → feuille          → @media (max-width: 900px)
   Tout ancêtre portant `backdrop-filter`, `transform` ou `filter` devient le
   bloc conteneur d'un descendant `position: fixed` et l'y enferme. Au-dessus
   de 900 px la feuille n'existe pas : la pilule peut flouter et coulisser
   librement. En dessous elle n'a droit qu'à de l'opacité et à un fond opaque.
   Valeur mesurée sur le rendu réel : la barre horizontale tient jusque vers
   820 px avant que les respirations entre marque, menu et actions ne tombent
   sous 25 px ; 900 px laisse la marge nécessaire et donne au panneau sa
   pleine largeur.
   --------------------------------------------------------------------------
   Le bloc core/navigation a été retiré : son sous-menu n'accepte que des
   liens simples (ni icône, ni description), son parent est forcément un lien,
   et son overlay mobile n'est pas paramétrable. Markup sur mesure dans
   patterns/nav-primary.php.
   ========================================================================== */

.aqg-nav__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* PIÈGE — le thème block ne normalise PAS `box-sizing`. Les `<a>` de la liste
   sont donc en `content-box` (les `<button>`, eux, sont en `border-box` par la
   feuille de l'agent utilisateur) : sur mobile, `width: 100%` leur ajoutait les
   28px de rembourrage horizontal et la feuille défilait latéralement de 12px,
   le déclencheur « Services » restant seul à la bonne largeur. Mesuré. */
.aqg-nav__link {
	box-sizing: border-box;
	display: flex;
	align-items: center;
	gap: 7px;
	margin: 0;
	border: 0;
	background: transparent;
	font-family: inherit;
	font-size: 15px;
	font-weight: 700;
	line-height: 1.2;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	cursor: pointer;
	transition: color .2s ease, background-color .2s ease;
}

.aqg-nav__link:hover {
	color: var(--wp--preset--color--primary);
}

.aqg-brand__name a:focus-visible,
.aqg-nav__link:focus-visible,
.aqg-nav__burger:focus-visible,
.aqg-mega__item:focus-visible,
.aqg-mega__promo:focus-visible,
.aqg-nav__act:focus-visible {
	/* Anneau bi-ton, identique à celui des boutons : voir son commentaire.
	   Une couleur unique est intenable ici, ces pilules et ces liens vivant
	   tantôt sur du clair, tantôt sur du marine. */
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
}

/* Chevron du déclencheur : dessiné en bordures, pas d'icône ajoutée au jeu. */
.aqg-nav__chev {
	width: 7px;
	height: 7px;
	margin-top: -3px;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	opacity: .6;
	transform: rotate(45deg);
	transition: transform .25s ease, opacity .2s ease;
}

.aqg-nav__trigger[aria-expanded="true"] .aqg-nav__chev {
	margin-top: 3px;
	opacity: 1;
	transform: rotate(-135deg);
}

/* ---------- Panneau « Services » : contenu commun aux deux présentations ---------- */
.aqg-mega__grid {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* `min-width: auto` est la valeur par défaut d'un enfant de grille ou de flex :
   il refuse alors de se réduire sous la largeur de son contenu. */
.aqg-nav__list,
.aqg-nav__item,
.aqg-mega__grid > li,
.aqg-mega__item,
.aqg-mega__promo {
	min-width: 0;
}

.aqg-mega__item {
	box-sizing: border-box;
	display: flex;
	align-items: flex-start;
	gap: 12px;
	height: 100%;
	padding: 11px 12px;
	border-radius: 15px;
	text-decoration: none;
	transition: background-color .18s ease;
}

/* Pastille plus petite que la `.aqg-ico` des cartes de contenu (56px). Cette
   classe est déclarée plus bas dans le fichier, à spécificité égale : on monte
   d'un cran pour l'emporter sans `!important`. */
.aqg-mega__item .aqg-mega__ico {
	width: 40px;
	height: 40px;
	min-width: 40px;
	border-radius: 13px;
}

.aqg-mega__item .aqg-mega__ico::before {
	width: 21px;
	height: 21px;
}

.aqg-mega__txt {
	display: block;
	min-width: 0;
}

.aqg-mega__title {
	display: block;
	font-size: 14.5px;
	font-weight: 800;
	line-height: 1.25;
	color: var(--wp--preset--color--contrast);
}

.aqg-mega__desc {
	display: block;
	margin-top: 3px;
	font-size: 12.5px;
	line-height: 1.35;
	color: var(--aqg-muted);
}

/* La fiche service ouverte est signalée dans le panneau. */
.aqg-mega__item[aria-current="page"] .aqg-mega__title {
	color: var(--wp--preset--color--primary);
}

/* PIÈGE — la carte est une cellule de grille, donc étirée par défaut sur toute
   la hauteur de la colonne de gauche : 314px mesurés à 1440px avec sept métiers
   sur quatre rangées, pour ~200px de contenu. Étirée, elle formait un grand
   rectangle sombre à moitié vide, et redistribuer le contenu à l'intérieur n'y
   changeait rien : c'est la HAUTEUR qui était le défaut, pas la répartition.
   `align-self: center` la ramène à la hauteur de son contenu et la centre ; le
   vide restant est du blanc de carte, qui respire, au lieu du marine plein. */
.aqg-mega__promo {
	box-sizing: border-box;
	position: relative;
	align-self: center;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	gap: 5px;
	padding: 20px;
	border-radius: 18px;
	background: var(--wp--preset--color--ink-deep);
	color: #fff;
	text-decoration: none;
}

/* Même piège que `.aqg-mega__item .aqg-mega__ico` : `.aqg-ico` est déclarée
   plus bas dans le fichier et lui impose 56px à spécificité égale. On monte
   d'un cran pour l'emporter sans `!important` (mesuré : 56px sans le parent). */
.aqg-mega__promo .aqg-mega__promo-ico {
	width: 44px;
	height: 44px;
	min-width: 44px;
	border-radius: 14px;
}

.aqg-mega__promo .aqg-mega__promo-ico::before {
	width: 22px;
	height: 22px;
}

.aqg-mega__promo::before {
	content: "";
	position: absolute;
	right: -70px;
	top: -70px;
	width: 200px;
	height: 200px;
	border-radius: 50%;
	background: radial-gradient(circle, var(--wp--preset--color--primary) 0%, transparent 68%);
	opacity: .55;
	pointer-events: none;
}

.aqg-mega__promo > * {
	position: relative;
}

.aqg-mega__promo-eyebrow {
	/* Pousse le texte en pied de carte quand il reste de la place (menu large).
	   Sans espace libre — la feuille mobile, où la carte prend sa hauteur
	   naturelle — la marge automatique vaut zéro et le bloc reste compact. */
	margin-top: auto;
	font-family: var(--wp--preset--font-family--label);
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--aqg-blue-bright);
}

.aqg-mega__promo-title {
	font-family: var(--wp--preset--font-family--display);
	font-size: 19px;
	font-weight: 800;
	line-height: 1.15;
	letter-spacing: -.01em;
}

.aqg-mega__promo-link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 6px;
	font-size: 13.5px;
	font-weight: 800;
	color: var(--aqg-blue-bright);
}

.aqg-mega__promo-link::after {
	content: "";
	width: 6px;
	height: 6px;
	border-top: 2px solid currentColor;
	border-right: 2px solid currentColor;
	transform: rotate(45deg);
	transition: transform .2s ease;
}

.aqg-mega__promo:hover .aqg-mega__promo-link,
.aqg-mega__promo:focus-visible .aqg-mega__promo-link {
	color: #fff;
}

.aqg-mega__promo:hover .aqg-mega__promo-link::after {
	transform: rotate(45deg) translate(2px, -2px);
}

/* ---------- Rangée d'actions : zone du pouce de la feuille mobile ---------- */
.aqg-nav__act {
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 52px;
	padding: 13px 18px;
	border-radius: 100px;
	font-size: 16px;
	font-weight: 800;
	text-align: center;
	text-decoration: none;
}

/* Couleurs par défaut = contexte clair (rendu sans JS, hors feuille marine). */
.aqg-nav__act--tel {
	border: 1.5px solid var(--aqg-border-warm);
	background: #fff;
	color: var(--wp--preset--color--contrast);
}

.aqg-nav__act--devis {
	background: var(--wp--preset--color--accent);
	color: #fff;
}

/* Bouton d'ouverture, poignée, croix, voile : n'existent que sur mobile ET
   seulement avec JS. Masqués par défaut, donc invisibles sans script. */
.aqg-nav__burger,
.aqg-nav__scrim,
.aqg-nav__grab,
.aqg-nav__actions {
	display: none;
}

.aqg-nav__burger {
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid var(--aqg-header-border);
	border-radius: 14px;
	background: #fff;
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
}

.aqg-nav__bars,
.aqg-nav__bars::before,
.aqg-nav__bars::after {
	width: 18px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
}

.aqg-nav__bars {
	position: relative;
	display: block;
}

.aqg-nav__bars::before,
.aqg-nav__bars::after {
	content: "";
	position: absolute;
	left: 0;
}

.aqg-nav__bars::before { top: -6px; }
.aqg-nav__bars::after { top: 6px; }

/* Poignée de la feuille. Ce n'est pas un décor : c'est le bouton de fermeture
   (convention des feuilles modales) et la surface de préhension du glissement
   vers le bas. La barre grise n'en est que la partie visible, la cible de
   frappe fait toute la largeur de la feuille sur 46px de haut. Une croix
   flottante en position absolue chevauchait l'angle arrondi de la feuille et
   recouvrait le chevron de l'accordéon : elle est supprimée. */
.aqg-nav__grip {
	display: block;
	width: 46px;
	height: 4px;
	border-radius: 100px;
	background: rgba(255, 255, 255, .32);
	transition: background-color .2s ease, width .2s ease;
}

/* ==========================================================================
   ORDINATEUR (> 900 px) — barre horizontale + méga-menu flottant
   ========================================================================== */
@media (min-width: 901px) {
	.aqg-nav {
		display: flex;
		align-items: center;
	}

	.aqg-nav__list {
		display: flex;
		align-items: center;
		gap: 2px;
	}

	/* Pastille en PILULE, comme le bouton téléphone et le bouton devis qui la
	   jouxtent : un rectangle à coins doux au milieu de pilules se lisait comme
	   un élément étranger. Hauteur ramenée de 40 à 32px dans une pilule de 66.
	   `color-mix` garde la palette mono-sourcée : aucun hexadécimal recopié. */
	.aqg-nav__link {
		padding: 7px 15px;
		border-radius: 100px;
		white-space: nowrap;
	}

	/* TROIS états distincts, à ne pas confondre :
	   repos = transparent · survol = bleu très dilué · ouvert = pastille
	   blanche cerclée, qui reprend le blanc de la carte ouverte juste dessous
	   et le gabarit du bouton téléphone voisin. La règle « ouvert » est
	   déclarée APRÈS le survol, à spécificité égale, pour l'emporter quand la
	   souris est encore sur le déclencheur. */
	.aqg-nav__link:hover {
		background: color-mix(in srgb, var(--wp--preset--color--primary) 10%, transparent);
		color: var(--wp--preset--color--primary-dark);
	}

	.aqg-nav__trigger[aria-expanded="true"] {
		background: var(--wp--preset--color--base);
		color: var(--wp--preset--color--primary-dark);
		box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--wp--preset--color--primary) 32%, transparent);
	}

	/* PIÈGE — `box-shadow` ne s'additionne pas d'une règle à l'autre.
	   L'anneau de focus bi-ton pose sa bande sombre en `box-shadow`, et l'état
	   ouvert ci-dessus en pose une autre, à spécificité égale et déclarée plus
	   loin : elle gagne. Or focaliser ce déclencheur l'OUVRE, le JS suivant le
	   focus, donc les deux états coexistent toujours. Sans cette règle, l'anneau
	   perdait sa bande sombre et tombait à 1,08:1 sur la pilule, mesuré. Les deux
	   ombres sont donc déclarées ensemble.
	   Règle générale : un composant qui utilise déjà `box-shadow` pour un état
	   doit rejouer la bande de l'anneau dans la même déclaration. */
	.aqg-nav__trigger[aria-expanded="true"]:focus-visible {
		box-shadow:
			inset 0 0 0 1.5px color-mix(in srgb, var(--wp--preset--color--primary) 32%, transparent),
			0 0 0 5px var(--wp--preset--color--ink-deep);
	}

	/* Le panneau est ancré sur la PILULE, pas sur son item : la pilule est
	   centrée dans la fenêtre et large de 1240 px au plus, le panneau ne peut
	   donc ni déborder du viewport ni être coupé, quelle que soit la position
	   du déclencheur dans la barre. */
	.aqg-nav__item--mega {
		position: static;
	}

	.aqg-mega {
		position: absolute;
		top: calc(100% + 6px);
		left: 50%;
		z-index: 5;
		width: min(920px, 100%);
		opacity: 0;
		visibility: hidden;
		pointer-events: none;
		transform: translate(-50%, 7px);
		transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
	}

	/* UNE SEULE SOURCE DE VÉRITÉ. L'affichage du panneau ne dépend que de
	   `aria-expanded` sur le déclencheur, que le JS est seul à écrire : l'état
	   annoncé aux lecteurs d'écran et l'état affiché sont littéralement le même
	   sélecteur, ils ne peuvent plus diverger.
	   Les anciennes règles `:hover` et `:focus-within` sur l'item ouvraient le
	   panneau en parallèle du JS : après un clic, le focus restait sur le
	   bouton, `:focus-within` rouvrait le panneau alors que le JS venait de le
	   déclarer fermé, et `aria-expanded` mentait. Supprimées. */
	.aqg-nav__trigger[aria-expanded="true"] + .aqg-mega {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		transform: translate(-50%, 0);
		transition-delay: 0s;
	}

	/* Repli SANS JavaScript, et lui seul. Le thème pose `.js` sur <html> en
	   wp_head, avant peinture : cette règle ne s'applique jamais en conditions
	   normales, elle ne peut donc plus entrer en concurrence avec le JS. */
	html:not(.js) .aqg-nav__item--mega:hover > .aqg-mega,
	html:not(.js) .aqg-nav__item--mega:focus-within > .aqg-mega {
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		transform: translate(-50%, 0);
		transition-delay: 0s;
	}

	.aqg-mega__card {
		position: relative;
		display: grid;
		grid-template-columns: minmax(0, 1fr) 238px;
		gap: 10px;
		padding: 12px;
		border: 1px solid var(--aqg-border-warm);
		border-radius: 24px;
		background: var(--wp--preset--color--base);
		box-shadow: var(--aqg-shadow-card);
	}

	/* PONT DE SURVOL. Bande transparente collée sous la pilule, sur TOUTE la
	   largeur du panneau : sans elle le survol se coupe dès que la souris
	   traverse l'interstice et le panneau se referme sous le curseur. Elle
	   appartient à la carte, donc elle disparaît avec elle (pointer-events
	   none quand le panneau est fermé) et ne bloque jamais un clic. */
	.aqg-mega__card::before {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		bottom: 100%;
		height: 30px;
	}

	.aqg-mega__grid {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 2px;
	}

	.aqg-mega__item:hover,
	.aqg-mega__item:focus-visible,
	.aqg-mega__item[aria-current="page"] {
		background: var(--wp--preset--color--surface-blue);
	}

	.aqg-mega__item:focus-visible {
		outline-offset: -2px;
	}

	/* La marque et les actions passent AU-DESSUS du pont de survol (bande
	   transparente qui court sous toute la largeur de la pilule) : sans ce
	   z-index, leurs derniers pixels cessaient d'être cliquables dès que le
	   panneau était ouvert. */
	.aqg-brand,
	.aqg-header__actions {
		position: relative;
		z-index: 6;
	}
}

/* Le téléphone de l'en-tête réapparaît à 961 px : liens resserrés jusqu'à 1023 px pour tenir sur une ligne. */
@media (min-width: 961px) and (max-width: 1023px) {
	.aqg-nav__link {
		padding-inline: 10px;
	}
}

/* ==========================================================================
   MOBILE (<= 900 px) — feuille qui monte du bas
   Deux couches : d'abord un repli SANS JS (liste simple en flux, panneau
   déplié, aucun lien inatteignable), puis la feuille elle-même, entièrement
   gatée sur `.js`.
   ========================================================================== */
@media (max-width: 900px) {
	/* Les deux actions de la pilule migrent dans la rangée épinglée de la
	   feuille : la pilule ne garde que la marque et le bouton d'ouverture. */
	.aqg-navpill .aqg-header__actions {
		display: none;
	}

	.aqg-nav__list {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 2px;
	}

	.aqg-nav__link {
		justify-content: space-between;
		width: 100%;
		padding: 13px 14px;
		border-radius: 14px;
		font-family: var(--wp--preset--font-family--display);
		font-size: 19px;
		font-weight: 800;
		letter-spacing: -.01em;
	}

	.aqg-nav__item + .aqg-nav__item {
		border-top: 1px solid var(--aqg-border-warm);
	}

	.aqg-mega__card {
		padding-left: 6px;
	}

	.aqg-mega__card > :last-child {
		margin-bottom: 10px;
	}

	.aqg-mega__grid {
		display: grid;
		grid-template-columns: 1fr;
		gap: 2px;
	}

	.aqg-mega__promo {
		margin-top: 8px;
	}

	.aqg-nav__actions {
		display: grid;
		gap: 10px;
	}

	/* PIÈGE — sans JS, l'en-tête ne doit PLUS être collant. La liste dépliée
	   rend la pilule plus haute que l'écran (environ 1140px à 390px) : collée
	   en `top: 0`, son bas ne serait jamais atteignable au défilement et les
	   cinq dernières entrées deviendraient inaccessibles. Vérifié. La pilule
	   passe aussi en `flex-wrap: wrap` pour que la liste prenne toute sa
	   largeur au lieu de se comprimer à côté de la marque. */
	html:not(.js) .wp-site-blocks > header.wp-block-template-part {
		position: static;
	}

	html:not(.js) .aqg-navpill {
		flex-wrap: wrap;
	}

	html:not(.js) .aqg-nav {
		flex-basis: 100%;
	}

	/* ---------- La feuille (JS requis) ---------- */
	.js .aqg-nav {
		display: block;
	}

	.js .aqg-nav__burger {
		display: inline-flex;
	}

	.js .aqg-nav__grab {
		box-sizing: border-box;
		display: flex;
		flex: none;
		align-items: center;
		justify-content: center;
		width: 100%;
		min-height: 46px;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: 26px 26px 0 0;
		background: transparent;
		cursor: pointer;
		/* Le geste vertical appartient à la feuille, pas au défilement de la
		   page : sans ceci le navigateur préempte le glissement. */
		touch-action: none;
	}

	.js .aqg-nav__grab:hover .aqg-nav__grip,
	.js .aqg-nav__grab:focus-visible .aqg-nav__grip {
		width: 58px;
		background: rgba(255, 255, 255, .6);
	}

	.js .aqg-nav__scrim {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 90;
		background: rgba(13, 34, 51, .58);
		opacity: 0;
		visibility: hidden;
		transition: opacity .3s ease, visibility 0s linear .3s;
	}

	.js .aqg-nav.is-open .aqg-nav__scrim {
		opacity: 1;
		visibility: visible;
		transition-delay: 0s;
	}

	.js .aqg-nav__panel {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 100;
		display: flex;
		visibility: hidden;
		transform: translateY(100%);
		transition: transform .34s cubic-bezier(.2, .8, .2, 1), visibility 0s linear .34s;
	}

	.js .aqg-nav.is-open .aqg-nav__panel {
		visibility: visible;
		transform: translateY(0);
		transition-delay: 0s;
	}

	/* La feuille reçoit le focus à l'ouverture (motif de dialogue WAI-ARIA).
	   Neutraliser son anneau est admis pour un conteneur non interactif focalisé
	   par programme : aucun élément interactif ne perd son indicateur, la
	   poignée garde le sien à la première tabulation. */
	.js .aqg-nav__sheet:focus {
		outline: none;
	}

	.js .aqg-nav__sheet {
		position: relative;
		display: flex;
		flex-direction: column;
		width: 100%;
		/* `dvh` et non `vh` : sur iOS la barre d'URL fausse `vh` et la feuille
		   dépasserait sous le bas de l'écran. `vh` reste en repli. */
		max-height: 86vh;
		max-height: 86dvh;
		overflow: hidden;
		border-radius: 26px 26px 0 0;
		background: var(--wp--preset--color--ink-deep);
		box-shadow: 0 -18px 50px -22px rgba(13, 34, 51, .7);
		color: #fff;
	}

	.js .aqg-nav__scroll {
		flex: 1 1 auto;
		min-height: 0;
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: 6px 16px 10px;
	}

	.js .aqg-nav__sheet .aqg-nav__link {
		color: #fff;
	}

	.js .aqg-nav__sheet .aqg-nav__link:hover {
		background: rgba(255, 255, 255, .08);
		color: #fff;
	}

	.js .aqg-nav__sheet .aqg-nav__item + .aqg-nav__item {
		border-top-color: rgba(255, 255, 255, .1);
	}

	.js .aqg-nav__sheet .aqg-mega__title {
		color: #fff;
	}

	.js .aqg-nav__sheet .aqg-mega__desc {
		color: var(--aqg-marine-soft);
	}

	.js .aqg-nav__sheet .aqg-mega__item:hover {
		background: rgba(255, 255, 255, .08);
	}

	.js .aqg-nav__sheet .aqg-mega__promo {
		border: 1px solid rgba(255, 255, 255, .14);
	}

	.js .aqg-nav__sheet .aqg-mega__item[aria-current="page"] {
		background: rgba(255, 255, 255, .1);
	}

	.js .aqg-nav__sheet .aqg-mega__item[aria-current="page"] .aqg-mega__title {
		color: var(--aqg-blue-bright);
	}

	/* Anneau bi-ton, comme partout ailleurs. Cette règle écrivait sa propre
	   couleur en dur et traitait donc le problème une quatrième fois, avec un
	   quatrième moyen. */
	.js .aqg-nav__sheet .aqg-nav__link:focus-visible,
	.js .aqg-nav__sheet .aqg-mega__item:focus-visible,
	.js .aqg-nav__sheet .aqg-mega__promo:focus-visible,
	.js .aqg-nav__sheet .aqg-nav__act:focus-visible {
		outline: 2px solid var(--wp--preset--color--base);
		outline-offset: 2px;
		box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
	}

	.js .aqg-nav__grab:focus-visible {
		outline: 2px solid var(--aqg-blue-bright);
		outline-offset: -3px;
	}

	.js .aqg-nav__sheet .aqg-nav__act--tel {
		border-color: rgba(255, 255, 255, .24);
		background: rgba(255, 255, 255, .12);
		color: #fff;
	}

	.js .aqg-nav__actions {
		position: relative;
		flex: none;
		border-top: 1px solid rgba(255, 255, 255, .16);
		background: rgba(255, 255, 255, .04);
		/* Marge du bas réservée à l'indicateur d'accueil iPhone. */
		padding: 12px 16px calc(14px + env(safe-area-inset-bottom));
	}

	/* Fondu au-dessus de la rangée épinglée : sans lui, la rangée tranchait le
	   contenu en plein milieu (la carte de mise en avant coupée dans son titre
	   à 320px) et le bord se lisait comme une fin de contenu au lieu d'une
	   limite de zone défilante. */
	.js .aqg-nav__actions::before {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		bottom: 100%;
		height: 28px;
		pointer-events: none;
		background: linear-gradient(to top, var(--wp--preset--color--ink-deep), transparent);
	}

	/* Accordéon « Services » : hauteur animée par la bascule 0fr → 1fr, jamais
	   par une hauteur codée en dur. Replié par défaut, pour que les cinq
	   entrées principales tiennent sans défilement. */
	.js .aqg-mega {
		display: grid;
		grid-template-rows: 1fr;
		transition: grid-template-rows .3s cubic-bezier(.2, .8, .2, 1);
	}

	.js .aqg-nav__trigger[aria-expanded="false"] + .aqg-mega {
		grid-template-rows: 0fr;
	}

	.js .aqg-mega__card {
		min-height: 0;
		overflow: hidden;
	}
}

/* Barre de défilement aux couleurs du site (au bureau ; les barres
   superposées des mobiles ne changent pas). Chrome et Firefox appliquent
   scrollbar-width/scrollbar-color ; les règles ::-webkit- ne servent qu'à
   Safari (survol plus foncé compris), et y habillent aussi les zones qui
   défilent dans la page, feuille du menu comprise. */
html {
	scrollbar-width: thin;
	scrollbar-color: var(--wp--preset--color--primary) var(--wp--preset--color--surface-blue);
}

::-webkit-scrollbar {
	width: 10px;
	height: 10px;
}

::-webkit-scrollbar-track {
	background: var(--wp--preset--color--surface-blue);
}

::-webkit-scrollbar-thumb {
	background: var(--wp--preset--color--primary);
	border-radius: 10px;
}

::-webkit-scrollbar-thumb:hover {
	background: var(--wp--preset--color--primary-dark);
}

/* Défilement de la page verrouillé tant que la feuille est ouverte. La largeur
   de la barre de défilement est rendue en rembourrage là où elle en occupe
   (ordinateur redimensionné), sinon la page saute au moment de l'ouverture. */
html.aqg-nav-open {
	overflow: hidden;
	padding-right: var(--aqg-scrollbar, 0px);
}

/* La barre d'appel des pages service est en `position: fixed` avec un z-index
   supérieur à celui de l'en-tête : elle passerait PAR-DESSUS la feuille. On la
   retire tant que la feuille est ouverte (le numéro y figure déjà, en tête de
   la rangée d'actions). */
html.aqg-nav-open .aqg-callbar {
	display: none;
}

/* Les sélecteurs gatés sur `.js` sont repris tels quels : sans leur préfixe,
   la règle perdrait en spécificité et la transition survivrait au réglage. */
@media (prefers-reduced-motion: reduce) {
	.aqg-mega,
	.aqg-nav__link,
	.aqg-nav__chev,
	.aqg-mega__item,
	.aqg-mega__promo-link::after,
	.js .aqg-mega,
	.js .aqg-nav__panel,
	.js .aqg-nav__scrim,
	.aqg-nav__grip {
		transition: none;
	}
}

.aqg-brand__id {
	line-height: 1;
}

.aqg-brand__name {
	margin: 0;
	line-height: 1;
}

/* Mot-marque de l'en-tête, le même fichier que le pied de page :
   logo-marque.png, 541x139. Le texte « AquaGones » du lien reste lu par les
   lecteurs d'écran (image-replacement, comme .aqg-footer__brand). Sous-titre
   retiré et logo agrandi le 2026-10-10 (retour de Kevin) ; largeurs mesurées
   le jour même, nav sur une ligne :
   - jusqu'à 900 px, 200 px (51,4 px de haut, pilule de 62 à 69 px ; 24 px
     d'écart avec le bouton du menu à 320 px) ;
   - de 901 à 960 px, 160 px (36 px de marge à 901 px) ;
   - de 961 à 1099 px, 124 px : nav, téléphone et « Votre devis » remplissent
     déjà la pilule au pixel près à 961 px, aucune place pour plus ;
   - à partir de 1100 px, 190 px (88 px libres à 1100 px). */
.aqg-brand__name a {
	display: block;
	width: 200px;
	aspect-ratio: 541 / 139;
	background: url("../images/logo-marque.png") left center / contain no-repeat;
	text-indent: -9999px;
	overflow: hidden;
	white-space: nowrap;
}

@media (min-width: 901px) {
	.aqg-brand__name a {
		width: 160px;
	}
}

@media (min-width: 961px) {
	.aqg-brand__name a {
		width: 124px;
	}
}

@media (min-width: 1100px) {
	.aqg-brand__name a {
		width: 190px;
	}
}


.aqg-header__actions {
	gap: 10px;
}

.aqg-header__tel {
	margin: 0;
	padding: 9px 15px;
	border-radius: 100px;
	border: 1.5px solid var(--aqg-border-warm);
	background: #fff;
	font-weight: 800;
	font-size: 14px;
	display: inline-flex;
	align-items: center;
	white-space: nowrap;
}

.aqg-header__tel a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.aqg-btn-sm .wp-block-button__link {
	padding: 11px 18px;
	font-size: 14px;
	border-radius: 100px;
	white-space: nowrap;
}

/* Anneau bi-ton par défaut de tout lien et de toute question de FAQ, pour
   qu'aucun n'hérite de l'anneau « auto » du navigateur. `:where()` le laisse
   à spécificité minimale : les porteurs listés plus bas l'emportent. */
:where(a[href], summary):focus-visible {
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
}

/* Titres-liens à interligne serré : en bloc, l'anneau ne chevauche plus la ligne voisine. */
:where(h2, .aqg-phero__side-title) > a[href] {
	display: inline-block;
}

/* Indicateur de focus des boutons.
   Il n'existait aucun style de focus propre : `theme.json` n'écrivait qu'un
   échange d'aplat accent vers accent-dark, soit 1,31:1, invisible, et le seul
   indicateur réel était l'anneau par défaut du navigateur, différent d'un
   navigateur à l'autre et nul en contraste forcé.

   Pourquoi ici et pas dans `theme.json`, en deux temps, parce que la réponse
   évidente est fausse. `theme.json` accepte `:focus-visible` pour
   `elements.button`, et il accepte aussi `outline` et `shadow` : vérifié dans
   le cœur installé, WP 7.1. MAIS le support date de **WP 6.8**, or ce thème
   déclare `Requires at least: 6.6` : sur 6.6 et 6.7 la règle serait ignorée
   sans erreur. Et surtout, `theme.json` génère
   `:root :where(.wp-element-button, .wp-block-button__link)`, quand
   `.aqg-form__submit` est un `<button>` nu qui ne porte ni l'une ni l'autre :
   aucun `theme.json` ne peut l'atteindre. Écrire l'anneau là-bas laisserait
   donc le bouton d'envoi du formulaire sans indicateur, et l'écrire aux deux
   endroits recréerait un défaut de parité du type de celui que ce dépôt paie
   déjà entre `extras.css` et `editor.css`.

   PIÈGE — un anneau décalé se dessine sur le fond du PARENT, jamais sur le
   bouton. Une couleur unique ne peut donc pas convenir : ce thème pose des
   boutons sur la toile crème, sur des aplats marine, sur l'encre du pied de
   page ET sur des halos en dégradé. Un anneau `ink-deep` uni donnait 1,000:1
   dans les deux héros marine et sur la carte sombre du pied de page, soit un
   anneau strictement invisible sur 63 boutons de 30 pages, mesuré.

   D'où un anneau BI-TON, qui est la réponse du navigateur au même problème :
   une bande sombre de 0 à 2px, une bande blanche de 2 à 4px, une bande sombre
   de 4 à 5px. Sur un fond clair c'est le sombre qui se lit, sur un fond sombre
   c'est le blanc, et sur un dégradé l'une des deux se lit toujours. Aucune
   énumération de conteneurs à maintenir, donc aucune à oublier au prochain
   bloc sombre ajouté. */

/* UNE SEULE RÈGLE, TOUS LES PORTEURS. La soumission en place a ajouté trois
   blocs focalisables (le message de retour, le panneau de confirmation, le
   bouton de retour au formulaire) et le lien téléphone du panneau. Ils ont
   d'abord été écrits dans leurs propres déclarations, plus bas dans ce
   fichier, mot pour mot identiques à celle-ci : trois copies de la même
   géométrie, quand le bloc `forced-colors` de la fin de fichier, lui,
   énumérait déjà tous les sélecteurs. La liste des porteurs existait donc à
   deux endroits qui ne disaient pas la même chose, ce qui est exactement la
   divergence que cette règle unique existe pour empêcher. Les commentaires de
   mesure des trois blocs sont restés sur place, à côté de leurs composants.

   La fusion est sûre, et c'est vérifié : aucun des quatre nouveaux porteurs ne
   pose de `box-shadow` au repos (`.aqg-form__again:hover, :focus-visible` ne
   pose que `border-color`, `background` et `color`), le piège de
   non-addition des `box-shadow` ne mord donc pas. Si l'un d'eux reçoit un jour
   une ombre portée, elle devra être REJOUÉE ici, dans cette déclaration.

   Le lien « politique de confidentialité » de la mention d'information
   (`.aqg-form__hint a`) est le cinquième porteur ajouté, le 2026-09-25. Il
   gardait l'anneau par défaut de Chrome, mesuré `auto 1px rgb(168,199,250)`
   sur le panneau blanc du formulaire, soit 1,72:1 sous les 3:1 de la SC 1.4.11 ;
   un anneau `auto` échappe en outre à `npm run a11y:contraste`, qui l'écarte.
   Il ne pose pas de `box-shadow` au repos non plus (mesuré : `none`).

   Le résumé des listes de la section TVA (`.aqg-aide-card__more > summary`)
   est le neuvième, le 2026-09-26 : un résumé de bloc « Détails » gardait
   sinon l'anneau `auto` du navigateur. Il n'a pas de `box-shadow` au repos.
   `npm run a11y:contraste` ne le mesure pas (sa liste de focalisables ne
   contient pas `summary`) : mesuré à la main, focus au clavier (Tab), sous
   1240 px, anneau peint sur la carte blanche, bande sombre à 16,23:1.

   DEUX PORTEURS EN LIGNE, les deux liens de texte : `.aqg-form__hint a` et
   `.aqg-form__done-tel a` (le numéro du panneau de confirmation). Un lien en
   ligne se coupe en fin de ligne, et un anneau posé sur un élément coupé se
   dessinait en deux morceaux OUVERTS au point de coupure (`slice`, défaut du
   navigateur). D'où le `box-decoration-break: clone` ci-dessous : chaque
   morceau reçoit son propre anneau, fermé. Mesuré le 2026-09-26 (Chrome sans
   interface, focus au clavier, pixels lus morceau par morceau) : en `slice`,
   un côté sans bande sombre par morceau ; en `clone`, bande sombre sur les
   quatre côtés de chaque morceau, 16,23:1 sur le panneau blanc pour la
   mention, 14,60:1 sur l'aplat vert pour le numéro. Sans effet sur les autres
   porteurs, blocs ou boîtes atomiques qui ne se coupent pas, et sans effet
   sur la mise en page : les deux liens n'ont ni marge interne ni bordure.
   Écarté : `white-space: nowrap` sur le lien, qui faisait déborder le
   DOCUMENT entier dès que le texte était agrandi seul (200 % en 320px de
   large : 383px de contenu pour 305 de fenêtre), et `display: inline-block`,
   qui laissait le point ou la virgule qui suit le lien seul en début de
   ligne (13 largeurs de fenêtre sur 501 pour la mention, 11 pour le numéro).
   La règle suffit donc à tout futur lien de texte ajouté ici.

   Onzième porteur, le 2026-09-27 : `.aqg-contact__line a`, le lien « Voir
   les communes desservies » de la page de coordonnées (/contact/), posé dans
   la carte blanche. Troisième lien de texte : il hérite du `clone` ci-dessus.
   Pas de `box-shadow` au repos. Les boutons de cette page, variantes
   `.aqg-btn-outline` et `.aqg-btn-ic` comprises, sont déjà couverts par
   `.wp-block-button__link:focus-visible`.

   Treizième porteur, le 2026-10-03 : la poignée du comparateur avant / après
   (`.aqg-ba__knob`), qui porte l'anneau à la place du curseur natif, invisible
   (opacité nulle) et posé sur toute la photo. Anneau mesuré à la main :
   l'outil de contraste écarte un élément à opacité nulle.

   Quatorzième et quinzième, le même jour : la carte d'une vignette
   agrandissable (`.aqg-realis-card:has(.aqg-zoom:focus-visible)`, la carte
   coupant tout anneau posé sur son lien) et le bouton « Fermer » de la
   fenêtre d'agrandissement (`.aqg-lightbox__close`).

   ⚠️ TOUT AJOUT DE PORTEUR SE FAIT ICI *ET* DANS LE BLOC `forced-colors` DE LA
   FIN DE CE FICHIER, jamais dans une déclaration nouvelle. */
.wp-block-button__link:focus-visible,
.wp-element-button:focus-visible,
.aqg-form__submit:focus-visible,
.aqg-form__feedback:focus-visible,
.aqg-form__done:focus-visible,
.aqg-form__again:focus-visible,
.aqg-form__done-tel a:focus-visible,
.aqg-form__hint a:focus-visible,
.aqg-aide-card__more > summary:focus-visible,
.aqg-optout:focus-visible,
.aqg-contact__line a:focus-visible,
.aqg-footer__credit a:focus-visible,
.aqg-ba__range:focus-visible ~ .aqg-ba__handle .aqg-ba__knob,
.aqg-realis-card:has(.aqg-zoom:focus-visible),
.aqg-lightbox__close:focus-visible {
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
	-webkit-box-decoration-break: clone;
	box-decoration-break: clone;
}

/* ---------- Button variants ---------- */
.aqg-btn-accent .wp-block-button__link {
	background: var(--wp--preset--color--accent);
	color: #fff;
}

.aqg-btn-light .wp-block-button__link {
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary);
}

.aqg-btn-light .wp-block-button__link:hover,
.aqg-btn-light .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--surface-blue);
	color: var(--wp--preset--color--primary-dark);
}

.aqg-btn-green .wp-block-button__link {
	background: var(--wp--preset--color--aide);
	color: #fff;
}

/* Le repos est passé à #176E48, la valeur qui servait ici : le survol descend
   donc d'un cran, sinon repos et survol deviennent identiques et le bouton perd
   son seul retour visuel de couleur. Blanc sur #124F34 = 9,57:1. */
.aqg-btn-green .wp-block-button__link:hover,
.aqg-btn-green .wp-block-button__link:focus-visible {
	background: #124F34;
	color: #fff;
}

/* Ghost phone button (outlined, for the marine hero cell). */
.aqg-btn-phone--ghost .wp-block-button__link {
	background: transparent;
	color: #fff;
	border: 1.5px solid rgba(255, 255, 255, .45);
}

.aqg-btn-phone--ghost .wp-block-button__link:hover,
.aqg-btn-phone--ghost .wp-block-button__link:focus-visible {
	background: rgba(255, 255, 255, .12);
	color: #fff;
}

/* Bouton secondaire en contour, POUR FOND CLAIR (carte blanche, toile crème,
   aplats `surface`). C'est le pendant, pour les boutons du cœur, de la pilule
   `.aqg-optout` et de `.aqg-form__again`, qui ne sont pas des `core/button` :
   mêmes couleurs, mêmes mesures. Libellé primary-dark sur blanc 8,22:1 ; au
   survol et au focus, blanc sur primary-dark 8,22:1 ; bordure primary 5,52:1
   sur blanc et 4,82:1 sur la toile, au-dessus des 3:1 d'un composant.

   ⚠️ JAMAIS SUR UN FOND SOMBRE, où le marine a `.aqg-btn-phone--ghost`. Et
   réciproquement : le texte blanc de ce dernier tombe à 1,14:1 sur la toile
   (calculé), c'était le défaut du bouton téléphone de la page 404, qui porte
   désormais cette variante-ci.

   Marges internes retranchées de l'épaisseur de la bordure (15 et 28 px dans
   `theme.json`, moins 1,5 px) : posé à côté d'un bouton plein, il garde la
   même hauteur. Aucune `box-shadow` au repos : l'anneau de focus de la règle
   unique la remplacerait (les `box-shadow` ne s'additionnent pas). */
.aqg-btn-outline .wp-block-button__link {
	padding: 13.5px 26.5px;
	border: 1.5px solid var(--wp--preset--color--primary);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary-dark);
}

.aqg-btn-outline .wp-block-button__link:hover,
.aqg-btn-outline .wp-block-button__link:focus-visible {
	border-color: var(--wp--preset--color--primary-dark);
	background: var(--wp--preset--color--primary-dark);
	color: #fff;
}

/* ---------- Hero (bento éditorial) ---------- */
.aqg-hero__bento {
	display: grid;
	grid-template-columns: 1.35fr 1fr;
	grid-template-rows: 1fr auto;
	gap: 18px;
}

/* Neutralise la marge de flux que WP pose sur les enfants (décalait la colonne
   droite de 24px vers le bas) : les cellules remplissent exactement leur piste. */
.aqg-hero__bento > * {
	margin-block: 0;
}

.aqg-hero__main {
	position: relative;
	overflow: hidden;
	grid-column: 1;
	grid-row: 1 / span 2;
	padding: 52px 50px;
	border-radius: 28px;
	background: var(--wp--preset--color--ink-deep);
	color: #fff;
}

.aqg-hero__main > *:not(.aqg-hero__glow) {
	position: relative;
	z-index: 1;
}

.aqg-hero__glow {
	position: absolute;
	right: -80px;
	top: -80px;
	width: 320px;
	height: 320px;
	border-radius: 50%;
	background: radial-gradient(circle, var(--wp--preset--color--primary) 0%, transparent 66%);
	opacity: .5;
	pointer-events: none;
	z-index: 0;
}

.aqg-hero__main h1 {
	color: #fff;
	margin: 0 0 20px;
}

.aqg-hl {
	color: var(--aqg-blue-bright);
}

.aqg-hero__lead {
	max-width: 500px;
	margin: 0 0 28px;
	color: var(--aqg-marine-soft);
	font-weight: 500;
}

.aqg-hero__cta {
	margin-bottom: 18px;
	gap: 14px;
}

.aqg-hero__cta .wp-block-button__link {
	font-size: 16px;
	font-weight: 800;
	padding: 16px 28px;
}

.aqg-hero__reassure {
	margin: 0 0 26px;
	font-size: 14px;
	font-weight: 700;
	color: var(--aqg-marine-soft);
}

.aqg-trust {
	gap: 12px 22px;
}

.aqg-trust__item {
	margin: 0;
	font-size: 14px;
	font-weight: 700;
	color: #D5E3EE;
}

/* Hero image cell + floating chips. */
.aqg-hero__media {
	position: relative;
	overflow: hidden;
	grid-column: 2;
	grid-row: 1;
	height: 100%;
	min-height: 280px;
	border-radius: 28px;
	background: var(--wp--preset--color--surface-blue);
}

/* Image en absolu : la cellule ne se dimensionne plus sur l'image, elle remplit
   sa piste de grille → bas de la colonne droite aligné sur la grande carte. */
.aqg-hero__media-img {
	position: absolute;
	inset: 0;
	margin: 0;
	height: 100%;
}

.aqg-hero__media-img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.aqg-hero__chip {
	position: absolute;
	left: 16px;
	bottom: 16px;
	margin: 0;
	padding: 9px 15px;
	border-radius: 100px;
	background: rgba(255, 255, 255, .94);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	color: var(--wp--preset--color--primary);
	font-size: 13px;
	font-weight: 800;
	box-shadow: 0 10px 24px -14px rgba(13, 34, 51, .5);
}

.aqg-hero__chip--2 {
	left: auto;
	right: 16px;
	top: 16px;
	bottom: auto;
	color: var(--wp--preset--color--accent);
}

/* Hero urgence cell (orange). The whole card is a phone link via a stretched
   pseudo-element on the text link — keeps the markup to valid core blocks. */
.aqg-hero__urgence {
	position: relative;
	grid-column: 2;
	grid-row: 2;
	height: 100%;
	padding: 26px 28px;
	border-radius: 28px;
	background: var(--wp--preset--color--accent);
	color: #fff;
	transition: transform .2s ease, box-shadow .2s ease;
}

.aqg-hero__urgence:hover {
	transform: translateY(-3px);
	/* Alignée sur le jeton foncé : écrite en dur, elle ne le suit pas, et un
	   halo orange vif autour d'un objet devenu terre cuite se verrait. */
	box-shadow: 0 24px 44px -26px rgba(175, 89, 12, .8);
}

.aqg-hero__urgence-text a {
	color: inherit;
	text-decoration: none;
}

.aqg-hero__urgence-text a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 28px;
}

/* Voile SOMBRE et non plus clair, et c'est un geste de composant, pas de jeton.
   Un voile blanc translucide éclaircit son propre fond : posé à 18 % sur
   l'orange, il compose un aplat sur lequel le blanc ne vaut que 2,54:1, et
   foncer l'orange n'y change rien puisque le voile suit. Mesuré : même sur
   #AF590C un voile blanc à 20 % plafonne à 3,46:1. Retourné en noir à 22 %, le
   blanc y vaut 7,20:1, et le geste s'améliore à chaque assombrissement au lieu
   de se dégrader. Piège à connaître : augmenter l'opacité d'un voile BLANC pour
   « renforcer le contraste » aggrave l'échec. */
.aqg-hero__urgence-badge {
	display: inline-flex;
	align-items: center;
	margin: 0 0 12px;
	padding: 6px 13px;
	border-radius: 100px;
	background: rgba(0, 0, 0, .22);
	color: #fff;
	font-size: 12px;
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: .03em;
}

.aqg-hero__urgence-title {
	margin: 0 0 6px;
	color: #fff;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 22px;
	letter-spacing: -.01em;
}

/* Blanc pur, et non plus le crème #FFE6D0 : mesuré, ce crème plafonne à 4,11:1
   même sur l'orange foncé, alors que le blanc y donne 4,93:1. La hiérarchie
   entre le titre et ce texte se lit désormais à la taille et à la graisse
   plutôt qu'à la teinte. Même geste sur `.aqg-cta__lead` et
   `.aqg-phero__side-text`, qui portaient le même crème. */
.aqg-hero__urgence-text {
	margin: 0;
	color: #fff;
	font-size: 15px;
	font-weight: 600;
}

/* ---------- Stats (floating band) ---------- */
.aqg-stats {
	display: flex;
	flex-wrap: wrap;
	/* Override core `.is-layout-flex { align-items: center }` so the four tiles
	   share one height (aligned top and bottom); their inner content stays
	   vertically centred via each tile's own flex alignment. */
	align-items: stretch;
	gap: 16px;
	margin-top: 18px;
	position: relative;
	z-index: 5;
}

.aqg-stat {
	flex: 1;
	min-width: 180px;
	/* Chiffre au-dessus, libellé dessous. En ligne, le `white-space: nowrap` du
	   chiffre comprimait le libellé jusqu'à le faire déborder de la tuile
	   (un libellé de deux mots cassait dès ~500px de large). */
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: 6px;
	padding: 22px 26px;
	border-radius: 22px;
	background: #fff;
	border: 1px solid var(--aqg-border-warm-2);
	box-shadow: var(--aqg-shadow-stat);
}

.aqg-stat--dark {
	background: var(--wp--preset--color--ink-deep);
	border-color: transparent;
}

.aqg-stat__num {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 34px;
	line-height: 1;
	white-space: nowrap;
	color: var(--wp--preset--color--primary);
}

/* A text marker longer than a figure (« SAV / Entretien ») : smaller and
   allowed to wrap, so it never spills out of its tile (2026-10-03). */
.aqg-stat__num--long {
	font-size: clamp(22px, 2vw, 28px);
	white-space: normal;
	text-wrap: balance;
}

.aqg-stat--dark .aqg-stat__num {
	color: var(--aqg-blue-bright);
}

.aqg-stat__label {
	margin: 0;
	max-width: 100%;
	font-size: 14.5px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--aqg-muted);
}

.aqg-stat--dark .aqg-stat__label {
	color: var(--aqg-marine-soft);
}

/* ---------- Certifications (merged bandeau) ---------- */
.aqg-certs {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	padding: 24px 34px;
	border-radius: 22px;
	background: #fff;
	border: 1px solid var(--aqg-border-warm-2);
}

/* Neutralise le margin-block-start que WP pose sur les enfants d'un groupe en flux. */
.aqg-certs > * {
	margin: 0;
}

/* Une rangée = un intitulé + ses pastilles, centrés, qui wrappent proprement. */
.aqg-certs__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 12px 16px;
	width: 100%;
}

/* Fin filet séparateur entre la rangée « Entreprise assurée » et la rangée
   « Experts de la pose ». */
.aqg-certs__row--brands {
	padding-top: 16px;
	border-top: 1px solid var(--aqg-border-warm-2);
}

.aqg-certs__label {
	margin: 0;
	font-family: var(--wp--preset--font-family--label);
	font-size: 12.5px;
	font-weight: 700;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--aqg-muted);
}

/* Pastille d’assurance : bouclier teinté + libellé. */
.aqg-qual {
	margin: 0;
	display: inline-flex;
	align-items: center;
	padding: 9px 16px;
	border-radius: 100px;
	background: #fff;
	border: 1px solid var(--aqg-border-aide);
	color: var(--wp--preset--color--aide);
	font-family: var(--wp--preset--font-family--label);
	font-weight: 700;
	font-size: 14.5px;
	line-height: 1;
	white-space: nowrap;
}

/* Variante « assurance » : bleu marque plutôt que vert label. */
.aqg-qual--blue {
	border-color: var(--aqg-border-warm);
	color: var(--wp--preset--color--primary);
}

.aqg-brand-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--label);
	font-weight: 700;
	font-size: 18px;
	letter-spacing: -.01em;
	color: var(--aqg-brand);
}

/* ---------- Section head & eyebrow ---------- */
.aqg-section-head {
	text-align: center;
	margin-bottom: 44px;
}

/* Le raccourci `margin` remet AUSSI la marge haute à zéro, et il écrase la
   gouttière de flux de WordPress (`:where(.is-layout-flow) > :where(:not(
   :first-child)) { margin-block-start: var(--wp--style--block-gap) }`, dont la
   spécificité est nulle). L'accroche se collait donc sous le H2 : 0px mesuré
   sur les huit sections concernées (« Nos savoir-faire » de l'accueil et
   « Nos prestations » des sept fiches). Le `margin-top` est rétabli
   explicitement, sur la même valeur que la gouttière du site — c'est le pas
   qui sépare déjà l'eyebrow du H2 juste au-dessus. */
.aqg-lead {
	margin: var(--wp--style--block-gap, 24px) auto 0;
	color: var(--aqg-muted);
}

.aqg-eyebrow {
	margin: 0 0 12px;
	font-family: var(--wp--preset--font-family--label);
	color: var(--wp--preset--color--primary);
	font-weight: 700;
	font-size: 14px;
	letter-spacing: .08em;
	text-transform: uppercase;
}

/* Seul texte orange posé sur le marine de tout le site (`feature-gainable`).
   Le jeton de palette y donnerait 3,29:1, pour un seuil de 4,5. */
.aqg-eyebrow--accent {
	color: var(--aqg-accent-on-dark);
}

.aqg-eyebrow--green {
	color: var(--wp--preset--color--aide);
}

/* ---------- Services (photo-header cards, 3-col grid) ---------- */
.aqg-services-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 20px;
}

/* ---------- Grille des métiers de l'accueil : pavage des sept cartes --------
   Sept cartes dans trois colonnes laisseraient une orpheline seule en
   troisième rangée. Deux cartes occupent donc deux colonnes, ce qui porte le
   total à neuf unités, soit trois rangées pleines. Les deux élues sont des
   cartes SANS photo (chauffage et pompe à chaleur, dépannage et entretien) :
   un en-tête image de 190px étiré sur deux colonnes se recadrerait au
   détriment de son sujet, une carte à icône ne perd rien à s'élargir.
   Dans l'ordre du catalogue, le pavage tombe juste sans réordonner :
     1 1 1 | 2 1 | 1 2
   Tout est scopé à `.aqg-services` : `.aqg-services-grid` sert aussi aux
   grilles de prestations des sept pages service, qui n'ont pas ce découpage. */
.aqg-services .aqg-service-card--wide {
	grid-column: span 2;
}

/* ---------- Carte entièrement cliquable ------------------------------------
   Le lien vit dans le `h3` (l'ancre est le nom du métier) et un pseudo-élément
   couvrant porte la surface jusqu'aux bords de la carte. Leçon capitalisée au
   lot précédent : une cible dont seuls 35 % de la surface visible réagissent
   au clic est un défaut, pas un détail. Un seul `<a>` de navigation par carte,
   donc aucun lien imbriqué et aucune double annonce au lecteur d'écran. */
.aqg-services .aqg-service-card {
	position: relative;
	/* Contexte d'empilement propre à la carte : sans lui, le halo repoussé en
	   `z-index: -1` juste dessous passerait DERRIÈRE le fond de la carte et
	   disparaîtrait. */
	isolation: isolate;
}

/* TITRE DE SECTION CLIQUABLE : encre du titre, jamais l'encre de lien.
   Le H2 de la grille des métiers lie `/nos-services/` depuis l'accueil. Sans
   cette règle il sort en `--primary` souligné, 44px : le seul titre du site à
   ressembler à un lien, alors que les trois autres titres cliquables du thème
   (`.aqg-service-card__title`, `.aqg-ville-card__title`, `.aqg-phero__side-title`)
   suivent tous la même convention. Le contraste redevient celui des titres,
   très au-delà de AA, et l'affordance passe par le survol et le focus. */
.aqg-section-head h2 a {
	color: inherit;
	text-decoration: none;
}

.aqg-section-head h2 a:hover,
.aqg-section-head h2 a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.aqg-services .aqg-service-card__title a {
	color: inherit;
	text-decoration: none;
}

.aqg-services .aqg-service-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 2;
}

/* Le survol de la carte souligne son titre : c'est le seul repère visuel qui
   reste depuis que le paragraphe « Découvrir … » a été retiré (il faisait un
   second lien vers la même page dans la même carte). */
.aqg-services .aqg-service-card:hover .aqg-service-card__title a {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* PIÈGE MESURÉ — la carte marine empile TOUS ses enfants au-dessus du halo
   (`--dark > *:not(.aqg-glow) { position: relative; z-index: 1 }`), et cette
   règle casse la carte cliquable de DEUX façons distinctes :
   1. `position: relative` sur le titre en fait le bloc conteneur du
      pseudo-élément, qui se réduit alors à la boîte du titre ;
   2. le titre est un ITEM FLEX, or `z-index` s'applique à un item flex même
      en `position: static` : il crée un contexte d'empilement, et le
      `z-index: 2` du pseudo-élément y reste enfermé, donc sous les
      paragraphes voisins qui suivent dans le DOM.
   Mesuré avant correctif : 70 % de surface cliquable sur cette carte, les
   30 % manquants étant exactement l'accroche et la ligne de tags. Le titre
   redevient donc statique ET sans `z-index`, et c'est le halo qu'on repousse
   sous le contenu. */
.aqg-services .aqg-service-card--dark > .aqg-service-card__title {
	position: static;
	z-index: auto;
}

.aqg-services .aqg-service-card--dark .aqg-glow {
	z-index: -1;
}

/* Retour client : « un badge puis un logo puis le texte, ça fait beaucoup
   d'empilement ». Mesuré : la carte marine empilait CINQ éléments (badge,
   icône, titre, texte, tags) là où les cartes photo en empilent quatre, et la
   carte dépannage quatre aussi. Le badge passe donc sur la LIGNE de l'icône,
   calé à droite : les deux signaux se lisent en une seule rangée, l'icône est
   conservée, et aucun markup ne change (le badge reste le premier enfant, donc
   annoncé en premier par un lecteur d'écran). Les décalages reprennent le
   rembourrage de la carte : un élément absolu se cale sur la boîte de
   REMBOURRAGE, pas sur la boîte de contenu. */

/* Le bouton d'appel de la carte dépannage doit rester atteignable : il passe
   au-dessus du pseudo-élément. Le `z-index` porte sur le LIEN, pas sur le
   conteneur `wp-block-buttons` : ce dernier occupe toute la largeur de la
   carte, et le remonter rendait 12 % de la carte inerte (mesuré). Aucun lien
   imbriqué ici, le bouton est SŒUR du lien de titre. */
.aqg-services .aqg-service-card__cta .wp-block-button__link {
	position: relative;
	z-index: 3;
}

/* Le focus clavier entoure la CARTE, pas le titre : c'est la surface réellement
   activable.

   ⚠️ CET ANNEAU N'EST PAS BI-TON, ET C'EST VOULU. Il n'en a pas besoin : il
   entoure la carte, donc il se dessine toujours sur la toile crème de la page,
   jamais sur un aplat variable. `--aqg-chip-ink` y donne 4,30:1.

   LA RÈGLE GÉNÉRALE, apprise trois fois dans ce lot et à retenir : un anneau
   posé avec un `outline-offset` positif ne se dessine ni sur l'élément, ni
   forcément sur son parent. Il tombe sur le premier ancêtre PLUS GRAND que le
   porteur, car le parent peut avoir exactement la même boîte que lui. C'est le
   cas des pilules de ce thème, où le lien porte `flex: 1` dans un conteneur à
   `padding: 0` : leur anneau se peint sur le panneau qui contient la pilule, pas
   sur la pilule. Une couleur d'anneau ne peut donc pas se déduire de l'aplat que
   l'on voit sous l'élément.

   D'où le choix, partout ailleurs, d'un anneau bi-ton qui ne dépend d'aucun
   fond, plutôt que d'une liste de conteneurs sombres à tenir à jour. Ici, la
   géométrie est connue et fixe, une couleur unique suffit. */
.aqg-services .aqg-service-card:has(.aqg-service-card__title a:focus-visible) {
	outline: 2px solid var(--aqg-chip-ink);
	outline-offset: 3px;
}

.aqg-services .aqg-service-card__title a:focus-visible {
	outline: none;
	box-shadow: none;
}

/* Une carte à deux colonnes mesure 766px de large à 1440px : son texte y
   courrait sur une centaine de caractères, très au-delà de la mesure
   confortable. Le contenu passe donc À CÔTÉ de l'icône plutôt qu'en dessous,
   et retrouve une largeur de ligne comparable à celle des cartes simples. */
@media (min-width: 961px) {
	.aqg-services .aqg-service-card--wide {
		display: grid;
		grid-template-columns: 56px minmax(0, 1fr);
		grid-auto-rows: min-content;
		align-content: center;
		column-gap: 22px;
	}

	.aqg-services .aqg-service-card--wide > * {
		grid-column: 2;
		max-width: 60ch;
	}

	.aqg-services .aqg-service-card--wide > .aqg-ico {
		grid-column: 1;
		grid-row: 1;
	}

	/* L'icône fait 56px et impose donc la hauteur de la première rangée, où se
	   trouve aussi le titre. Sans ce centrage, le titre se cale en haut de la
	   rangée et laisse un vide de 22px entre lui et son texte, alors que le
	   même vide manque au-dessus. */
	.aqg-services .aqg-service-card--wide > .aqg-service-card__title {
		align-self: center;
	}

	/* Carte large AVEC photo : le média passe en COLONNE DE GAUCHE sur toute la
	   hauteur, au lieu du bandeau de 190px des cartes simples. `chauffage.jpg`
	   est un portrait (1067×1600) : étiré sur 767px de large pour 190px de
	   haut, `object-fit: cover` n'en garderait qu'une tranche centrale de
	   264px, c'est-à-dire des tuyaux sans le local autour. En colonne, la
	   fenêtre visible fait 300×387 et le sujet tient entier.
	   Le sélecteur `:has()` évite d'inventer une variante de plus : une carte
	   large est en icône à gauche si elle n'a pas de média, en photo à gauche
	   si elle en a un. */
	.aqg-services .aqg-service-card--wide:has(.aqg-service-card__media) {
		display: flex;
		flex-direction: row;
		align-items: stretch;
	}

	.aqg-services .aqg-service-card--wide > .aqg-service-card__media {
		flex: 0 0 300px;
	}

	.aqg-services .aqg-service-card--wide > .aqg-service-card__body {
		flex: 1;
		justify-content: center;
		padding: 28px 32px;
	}

	.aqg-services .aqg-service-card--wide .aqg-service-card__img,
	.aqg-services .aqg-service-card--wide .aqg-service-card__img img {
		height: 100%;
	}
}

.aqg-service-card {
	display: flex;
	flex-direction: column;
	border-radius: 24px;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--aqg-border-warm);
	overflow: hidden;
	transition: transform .34s cubic-bezier(.22, .61, .36, 1), box-shadow .34s cubic-bezier(.22, .61, .36, 1), border-color .25s ease;
}

.aqg-service-card:hover {
	transform: translateY(-8px);
	box-shadow: var(--aqg-shadow-card);
	border-color: var(--wp--preset--color--primary);
}

.aqg-service-card__media {
	position: relative;
}

.aqg-service-card__img {
	margin: 0;
}

.aqg-service-card__img img {
	width: 100%;
	height: 190px;
	object-fit: cover;
	display: block;
}

.aqg-service-card__chip {
	position: absolute;
	left: 16px;
	bottom: 16px;
	margin: 0;
	padding: 8px 14px;
	border-radius: 100px;
	background: rgba(255, 255, 255, .94);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	color: var(--wp--preset--color--primary);
	font-size: 13px;
	font-weight: 800;
	box-shadow: 0 10px 24px -14px rgba(13, 34, 51, .5);
}

.aqg-service-card__chip--accent {
	color: var(--wp--preset--color--accent);
}

.aqg-service-card__body {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 24px 26px;
	flex: 1;
}

.aqg-service-card__title {
	margin: 0;
	font-size: 21px;
}

.aqg-service-card__title--lg {
	font-size: 24px;
}

.aqg-service-card__text {
	margin: 0;
	font-size: 14.5px;
	line-height: 1.6;
	color: var(--aqg-muted);
}

.aqg-service-card__tags {
	margin: auto 0 0;
	padding-top: 14px;
	border-top: 1px solid var(--aqg-border-warm-2);
	font-size: 12.5px;
	font-weight: 700;
	color: var(--aqg-muted);
}

/* Dark spécialité card (gainable). */
.aqg-service-card--dark {
	position: relative;
	overflow: hidden;
	background: var(--wp--preset--color--ink-deep);
	border: none;
	padding: 32px 30px;
	gap: 14px;
	color: #fff;
}

.aqg-service-card--dark > *:not(.aqg-glow) {
	position: relative;
	z-index: 1;
}

.aqg-service-card--dark .aqg-service-card__title {
	color: #fff;
}

.aqg-service-card--dark .aqg-service-card__text {
	color: var(--aqg-marine-soft);
}

.aqg-service-card--dark .aqg-service-card__tags {
	margin-top: auto;
	border-top-color: rgba(255, 255, 255, .14);
	color: var(--aqg-marine-faint);
}

/* SOS card (near-black). */
.aqg-service-card--sos {
	background: var(--wp--preset--color--contrast);
	border: none;
	padding: 32px 30px;
	gap: 14px;
	color: #fff;
}

.aqg-service-card--sos .aqg-service-card__title {
	color: #fff;
}

.aqg-service-card--sos .aqg-service-card__text {
	color: #BBB;
}

.aqg-service-card__cta {
	margin-top: auto;
}

/* Icon boxes — professional line icons rendered as CSS masks (see § Icônes). */
.aqg-ico {
	width: 56px;
	height: 56px;
	min-width: 56px;
	margin: 0;
	border-radius: 16px;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--wp--preset--color--primary);
}

.aqg-ico::before {
	content: "";
	width: 27px;
	height: 27px;
	background: currentColor;
	-webkit-mask: var(--aqg-icon, none) center / contain no-repeat;
	mask: var(--aqg-icon, none) center / contain no-repeat;
}

.aqg-ico--blue { background: var(--aqg-ico-blue); color: var(--wp--preset--color--primary); }
.aqg-ico--orange { background: var(--aqg-ico-orange); color: var(--wp--preset--color--accent); }
.aqg-ico--ghost { background: rgba(255, 255, 255, .1); color: #fff; }
.aqg-ico--plain { background: #fff; color: var(--wp--preset--color--primary); }
.aqg-ico--green { background: var(--wp--preset--color--aide-surface); color: var(--wp--preset--color--aide); }

/* En-tête des cartes sans photo : icône et badge sur UNE ligne.
   Empilés, ils présentaient deux objets visuels avant le titre, là où une carte
   photo n'en montre qu'un (son média, chip compris). z-index : la carte sombre
   pose un .aqg-glow en absolu, l'en-tête doit passer devant. */
.aqg-service-card__head {
	display: flex;
	align-items: center;
	gap: 14px;
	flex-wrap: wrap;
	position: relative;
	z-index: 1;
}

.aqg-badge--spec {
	align-self: flex-start;
	margin: 0;
	padding: 6px 13px;
	border-radius: 100px;
	background: var(--wp--preset--color--accent);
	color: #fff;
	font-size: 11.5px;
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: .04em;
}

.aqg-glow {
	position: absolute;
	right: -50px;
	top: -50px;
	width: 200px;
	height: 200px;
	border-radius: 50%;
	background: radial-gradient(circle, var(--wp--preset--color--primary) 0%, transparent 68%);
	opacity: .4;
	pointer-events: none;
	z-index: 0;
}

/* ---------- Feature (gainable) ---------- */
.aqg-feature {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: stretch;
	border-radius: 32px;
	overflow: hidden;
	background: var(--wp--preset--color--ink-deep);
}

.aqg-feature__body {
	padding: 58px 50px;
	color: #fff;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.aqg-feature__body h2 {
	color: #fff;
	margin: 0 0 20px;
}

.aqg-feature__text {
	margin: 0 0 26px;
	color: var(--aqg-marine-soft);
	line-height: 1.6;
}

.aqg-feature__checks {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 14px;
}

.aqg-check {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	color: #fff;
}

.aqg-feature__media {
	position: relative;
	margin: 0;
	min-height: 420px;
	height: 100%;
}

/* Image en absolu (comme la maquette) : elle remplit la cellule sans imposer sa
   hauteur naturelle — sinon une photo portrait étire toute la card. */
.aqg-feature__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* ---------- TVA réduite (section verte, ancre #aides) ----------
   Chaque carte porte une phrase d'entrée (le taux ET ses conditions), puis la
   liste des travaux qu'elle couvre, dans un bloc « Détails » du cœur. Mise en
   page COMPACTE, parce que les listes triplaient le volume de texte de la
   section. Mesuré le 2026-09-26 (Chrome 151, polices chargées) sur la hauteur
   de `.aqg-aides`, avant les listes, avec les listes sans style, puis avec ce
   qui suit : 568, 1036 et 765 px à 1440 ; 664, 1251 et 700 px à 1100 ;
   1167, 2187 et 1195 px à 390 ; 1303, 2822 et 1409 px à 320. Le même soir,
   titre de carte rétabli à 20 px et condition de pose déplacée dans les
   listes : 821 px à 1440, 843 à 1240, 745 à 1100, 942 à 820, 1196 à 390 et
   1425 à 320. Plus tard le même soir, carte 10 % complétée, poids des
   colonnes recalés et une seule colonne jusqu'à 900 px : 852 px à 1440, 872
   à 1240, 745 à 1100, 1058 à 820, 1056 à 783, 1219 à 390 et 1449 à 320. Sur
   mobile, ce qui reste de croissance tient surtout à la mention des sources,
   plus longue qu'avant ; de 783 à 900 px, la colonne unique coûte de 116 px
   (à 820) à 183 px (à 900) de plus que trois colonnes illisibles (règle
   `max-width: 900px`, plus bas).
   Trois gestes :
   1. Sur ordinateur (à partir de 1240 px, largeur à laquelle la section atteint
      sa taille maximale), les listes sont dépliées d'office et le résumé du
      bloc « Détails » est masqué : colonnes pondérées par le volume de texte de
      chaque carte, pour que les trois cartes aient à peu près la même hauteur
      au lieu de s'aligner sur la plus longue, et liste serrée.
   2. En dessous, où les colonnes deviennent trop étroites pour une liste, le
      bloc « Détails » reprend son rôle natif : la liste se replie derrière son
      résumé, la phrase d'entrée restant toujours visible. Clavier et lecteur
      d'écran : ceux du navigateur, rien à réécrire.
   3. La note d'en-tête et la mention des sources prennent la largeur
      disponible au lieu de s'empiler sur quatre ou cinq lignes étroites.
   Le dépli forcé passe par `::details-content` et n'est posé QUE si le
   navigateur le connaît (`@supports`) : ailleurs, le résumé reste visible et la
   liste s'ouvre au clic, jamais une liste masquée sans moyen de l'ouvrir. */
.aqg-aides {
	padding: 52px 50px;
	border-radius: 32px;
	background: var(--wp--preset--color--aide-surface);
	border: 2px solid #CFE9D4;
}

.aqg-aides__head {
	margin-bottom: 32px;
	gap: 24px;
}

.aqg-aides__intro h2 {
	max-width: 620px;
}

/* À côté du titre, la note occupe la place qui reste ; sous le titre, quand
   la rangée se replie, elle s'aligne sur sa largeur au lieu de garder 320 px. */
.aqg-aides__note {
	flex: 1 1 320px;
	margin: 0;
	max-width: 620px;
	font-size: 16px;
	color: #3C5A48;
}

/* `minmax(0, …)` et non `1fr` seul : une colonne `1fr` ne descend pas sous la
   largeur de son plus long mot, et la rangée débordait de la page vers 790 px. */
.aqg-aides__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 20px;
}

/* `.aqg-aide-card`, `.aqg-aide-card__title` et `.aqg-aides__grid` servent
   AUSSI aux blocs budget des sept fiches service (`.aqg-budget`). Tout ce qui
   est calé sur la section TVA se préfixe donc de `.aqg-aides` : padding,
   interlignage, titre, poids des colonnes, colonne unique jusqu’à 900 px. Les
   cartes budget gardent leur rendu d'avant la section TVA (relevé dans Chrome
   le 2026-09-26 sur les sept fiches : titres de 15 px, gris du corps, sans
   marge, padding de 30 px, colonnes égales). */
.aqg-aide-card {
	padding: 30px;
	border-radius: 20px;
	background: #fff;
}

.aqg-aides .aqg-aide-card {
	padding: 26px 26px 24px;
}

/* Hors section TVA, `.aqg-aide-card p`, plus bas, pèse 0,1,1 et écrase la
   taille, la couleur et la marge de ce titre (15 px, gris du corps, sans
   marge) depuis l'origine du thème : c'est le rendu des cartes budget, gardé
   tel quel. Dans la section TVA, deux classes rétablissent le titre prévu
   (20 px, vert), relevé dans Chrome le 2026-09-26. */
.aqg-aide-card__title {
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
}

.aqg-aides .aqg-aide-card__title {
	margin: 0 0 8px;
	font-size: 20px;
	color: var(--wp--preset--color--aide);
}

.aqg-aide-card p {
	margin: 0;
	font-size: 15px;
	line-height: 1.6;
	color: #4B5A51;
}

.aqg-aides .aqg-aide-card p {
	line-height: 1.55;
}

.aqg-aide-card__more {
	margin: 0;
}

/* Puces natives, et non dessinées : le marqueur reste du texte, donc lu par
   le contraste forcé et annoncé comme une liste par tous les lecteurs d'écran
   (`list-style: none` retire la sémantique de liste à VoiceOver). */
.aqg-aide-card__list {
	margin: 10px 0 0;
	padding-left: 1.15em;
	list-style: disc;
	font-size: 14px;
	line-height: 1.5;
	color: #4B5A51;
}

.aqg-aide-card__list > li {
	margin: 0;
	padding-left: 2px;
}

.aqg-aide-card__list > li + li {
	margin-top: 6px;
}

.aqg-aide-card__list > li::marker {
	color: var(--wp--preset--color--aide);
}

/* Le résumé : un bouton vert pleine largeur de la carte, 41 px de haut sur
   une ligne. Rayon de 14 px et non de pilule : dans les colonnes étroites (de
   901 à 1084 px depuis la colonne unique jusqu'à 900 px, et sous 347 px,
   mesuré le 2026-09-26) le libellé passe sur deux lignes, et une pilule y devient un ovale. #176E48 sur #EAF6EC = 5,65:1, et 5,27:1 sur
   l'aplat de survol. Son anneau de focus est celui de la règle unique
   (chercher « UNE SEULE RÈGLE »). */
.aqg-aide-card__more > summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: 14px;
	padding: 10px 16px;
	border-radius: 14px;
	background: var(--wp--preset--color--aide-surface);
	border: 1px solid #CFE9D4;
	color: var(--wp--preset--color--aide);
	font-size: 14px;
	font-weight: 700;
	line-height: 1.4;
	cursor: pointer;
	list-style: none;
}

.aqg-aide-card__more > summary::-webkit-details-marker {
	display: none;
}

.aqg-aide-card__more > summary:hover {
	background: #DDF0E1;
}

/* Même signe que la FAQ : « + » qui tourne en « × » à l'ouverture. Texte de
   remplacement vide (`/ ""`) : sans lui, le signe entre dans le nom accessible
   (« Voir les travaux concernés + », relevé dans l'arbre d'accessibilité de
   Chrome) ; l'état ouvert ou fermé est déjà annoncé par le navigateur. La
   première déclaration sert aux navigateurs qui ignorent cette syntaxe. */
.aqg-aide-card__more > summary::after {
	content: "+";
	content: "+" / "";
	flex: none;
	font-size: 20px;
	line-height: 1;
}

.aqg-aide-card__more[open] > summary::after {
	transform: rotate(135deg);
}

.aqg-aides__foot {
	margin-top: 30px;
	gap: 20px 30px;
}

/* Base de 420 px : la mention reste à côté du bouton tant qu'elle garde cette
   largeur, et s'étale jusqu'à 760 px pour tenir en trois lignes à 1440. */
.aqg-aides__legal {
	flex: 1 1 420px;
	margin: 0;
	max-width: 760px;
	color: #4F6B5A;
}

@media (min-width: 1240px) {
	/* Poids calés sur le volume de texte des trois cartes (616, 584 et 466
	   signes le 2026-09-26 au soir, après l'ajout à la carte 10 % des
	   équipements qui n'atteignent pas les performances exigées) : contenus de
	   416, 393 et 426 px à 1440, section de 852 px, contre 500 px pour la carte
	   du milieu et 926 px avec les poids d'avant (1,25, 1 et 1,1), et 886 px
	   pour trois colonnes égales. Si un texte change beaucoup, rééquilibrer ces
	   poids plutôt que d'accepter une carte seule beaucoup plus haute que les
	   deux autres. Préfixés de `.aqg-aides` : les cartes budget des fiches, de
	   volume comparable entre elles, gardent des colonnes égales. */
	.aqg-aides .aqg-aides__grid {
		grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.2fr) minmax(0, 1fr);
	}

	@supports selector(::details-content) {
		.aqg-aide-card__more > summary {
			display: none;
		}

		.aqg-aide-card__more::details-content {
			content-visibility: visible;
		}
	}
}

/* Sous 1240 px, une liste ouverte n'étire plus les deux autres cartes à sa
   hauteur : à 820 px, ouvrir la première portait les trois cartes de 433 à
   971 px, deux pavés presque vides (mesuré le 2026-09-26). Fermées, les cartes
   gardent la hauteur commune de la rangée. Sans `:has()`, rendu d'avant. */
@media (max-width: 1239px) {
	.aqg-aides .aqg-aides__grid:has(> .aqg-aide-card > .aqg-aide-card__more[open]) {
		align-items: start;
	}
}

/* Une seule colonne dès 900 px (point de rupture déjà employé par le thème),
   et non 782 comme les autres grilles : de 783 à 900 px, trois colonnes ne
   laissaient que 132 à 168 px de texte par carte, la phrase d'entrée de la
   carte 5,5 % y tenait sur 7 à 10 lignes et le résumé sur deux ou trois
   (81 px de haut à 820 et 860 px). Mesuré le 2026-09-26 : à 820 px, section
   de 942 px en trois colonnes, 1058 px en une, phrase d'entrée sur 2 lignes
   au lieu de 9 ; à 901 px, en trois colonnes, 169 px de texte par carte et
   résumé sur deux lignes. Section TVA seule : les cartes budget des fiches
   gardent leurs trois colonnes jusqu'à 782 px. */
@media (max-width: 900px) {
	.aqg-aides .aqg-aides__grid {
		grid-template-columns: 1fr;
	}
}

/* Ouverture animée sous 1240 px, sur le modèle de la FAQ (même mécanique, même
   courbe, cf. `.aqg-faq__item::details-content`). */
@media (max-width: 1239px) and (prefers-reduced-motion: no-preference) {
	.aqg-aide-card__more::details-content {
		block-size: 0;
		overflow: hidden;
		opacity: 0;
		transition:
			block-size .34s cubic-bezier(.2, .7, .2, 1),
			opacity .26s ease,
			content-visibility .34s allow-discrete;
	}

	.aqg-aide-card__more[open]::details-content {
		block-size: auto;
		opacity: 1;
	}

	.aqg-aide-card__more > summary::after {
		transition: transform .34s cubic-bezier(.2, .7, .2, 1);
	}
}

/* ---------- Processus (connected frieze) ---------- */
.aqg-processus__card {
	padding: 52px 44px;
	border-radius: 32px;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--aqg-border-warm);
}

.aqg-steps {
	position: relative;
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
}

/* Gradient line linking the four numbered dots. Sits behind the dots (z-index 0
   vs the dots' z-index 1) so their surface-coloured border cleanly cuts it. */
.aqg-steps::before {
	content: "";
	position: absolute;
	/* Through the vertical centre of the 52px dots (border-box → half = 26px). */
	top: 26px;
	transform: translateY(-50%);
	/* From the centre of the first dot to the centre of the last: each of the 4
	   equal columns is (100% - 3 × 24px gap) / 4 wide, so a dot centre sits half
	   a column in from each edge = (100% - 72px) / 8 = 12.5% - 9px. */
	left: calc(12.5% - 9px);
	right: calc(12.5% - 9px);
	height: 3px;
	border-radius: 2px;
	background: linear-gradient(90deg, var(--wp--preset--color--primary), var(--wp--preset--color--accent));
	z-index: 0;
}

.aqg-step {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.aqg-step__dot {
	/* border-box keeps the outer size at exactly 52px so the frieze line, placed
	   at top:26px, lands on the true vertical centre regardless of the border. */
	box-sizing: border-box;
	width: 52px;
	height: 52px;
	margin: 0 auto 18px;
	border-radius: 50%;
	background: var(--wp--preset--color--primary);
	border: 4px solid var(--wp--preset--color--surface);
	color: #fff;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 21px;
	display: flex;
	align-items: center;
	justify-content: center;
	/* Alignée sur le jeton foncé, comme sa jumelle orange six lignes plus bas :
	   écrite en dur, elle ne suit pas la palette. Non alignée, le halo était
	   1,81 fois plus lumineux que le disque qu'il entoure, et les quatre pastilles
	   de la frise sont côte à côte. */
	box-shadow: 0 8px 18px -8px rgba(20, 56, 127, .7);
}

.aqg-step__dot--accent {
	background: var(--wp--preset--color--accent);
	/* Voir plus haut : ombre en dur réalignée sur le jeton foncé. */
	box-shadow: 0 8px 18px -8px rgba(175, 89, 12, .7);
}

.aqg-step__title {
	margin: 0 0 8px;
	font-size: 19px;
}

/* `:not(.aqg-step__dot)` : la pastille numérotée est aussi un <p> — sans ça, ce
   style écrase sa marge (18px), sa taille (21px) et sa couleur (blanc). */
.aqg-step p:not(.aqg-step__dot) {
	margin: 0;
	font-size: 14px;
	line-height: 1.55;
	color: var(--aqg-muted);
}

/* ---------- Réalisations (asymmetric mosaic) ---------- */
.aqg-realis-head {
	margin-bottom: 30px;
	gap: 16px;
}

.aqg-realis {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1fr;
	grid-template-rows: 220px 220px;
	gap: 18px;
}

.aqg-realis-card {
	position: relative;
	display: grid;
	border-radius: 22px;
	overflow: hidden;
	background: var(--wp--preset--color--surface-blue);
}

/* Carte en grille : la figure, étirée dans l'unique piste, a une hauteur
   DÉFINIE, que son lien d'agrandissement (`a.aqg-zoom`) et l'image peuvent
   remplir à 100 %. Sans cela, sous 960px où la carte n'a qu'un `min-height`,
   les pourcentages ne se résolvaient pas et l'image retombait sur sa hauteur
   naturelle : une bande vide sous la photo, 79px sur la carte large en 3:1
   (mesuré le 2026-10-03 à 390px). Pastille et voile restent en absolu. */
.aqg-realis-card > .aqg-realis-card__img {
	min-height: 0;
}

.aqg-realis-card__img img {
	display: block;
}

.aqg-realis-card--tall {
	grid-row: 1 / span 2;
}

.aqg-realis-card--wide {
	grid-column: 2 / span 2;
}

.aqg-realis-card__img {
	margin: 0;
	height: 100%;
}

.aqg-realis-card__img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* Bottom scrim so the caption chip stays legible over any photo. */
.aqg-realis-card::after {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 45%;
	background: linear-gradient(to top, rgba(13, 34, 51, .55), transparent);
	pointer-events: none;
}

.aqg-realis-card__chip {
	position: absolute;
	left: 16px;
	bottom: 16px;
	z-index: 1;
	margin: 0;
	padding: 8px 14px;
	border-radius: 100px;
	background: rgba(13, 34, 51, .72);
	backdrop-filter: blur(6px);
	-webkit-backdrop-filter: blur(6px);
	color: #fff;
	font-size: 13px;
	font-weight: 700;
}

/* ---------- Avis (« Nos derniers avis », réarmé le 2026-10-03) ----------
   Cinq avis Google réels (patterns/avis.php). Grille de six pistes : trois
   cartes sur la première rangée, deux centrées sur la seconde, toutes de même
   largeur (5 % 3 = 2, pas d'orpheline). De 601 à 960px, quatre pistes : 2 + 2,
   la cinquième centrée (deux colonnes jusqu'à 601px). En dessous, une
   colonne. La règle commune des grilles à 782px ne touche plus `.aqg-avis`.
   Les étoiles sont un pseudo-élément (masque d'une étoile répété cinq fois) :
   décoratives, muettes pour un lecteur d'écran, qui lit à la place le texte
   masqué « Note : 5 sur 5. » du même paragraphe. Elles ne valent que pour un
   avis noté 5 sur 5 : un autre avis demanderait une autre variante. */
.aqg-avis-wrap {
	--aqg-i-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12 2.5l2.94 5.96 6.56.95-4.75 4.63 1.12 6.54L12 17.5l-5.87 3.08 1.12-6.54L2.5 9.41l6.56-.95z'/%3E%3C/svg%3E");
}

.aqg-avis-head {
	margin-bottom: 30px;
}

.aqg-avis-head .aqg-eyebrow,
.aqg-avis-head h2 {
	margin-block: 0;
}

.aqg-avis-head h2 {
	margin-top: 8px;
}

.aqg-avis-head__note {
	margin: 12px 0 0;
	color: var(--aqg-muted);
}

.aqg-avis {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 20px;
}

.aqg-avis > .aqg-avis-card {
	grid-column: span 2;
}

.aqg-avis > .aqg-avis-card:nth-child(4) {
	grid-column: 2 / span 2;
}

.aqg-avis > .aqg-avis-card:nth-child(5) {
	grid-column: 4 / span 2;
}

.aqg-avis-card {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 28px;
	border-radius: 22px;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--aqg-border-warm-2);
}

.aqg-avis-card > * {
	margin-block: 0;
}

/* Ligne d'en-tête : étoiles à gauche, mention « Avis Google » à droite. */
.aqg-avis-card__note {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	font-family: var(--wp--preset--font-family--label);
	font-size: 13px;
	font-weight: 700;
	color: var(--aqg-muted);
}

.aqg-avis-card__note::before {
	content: "";
	flex: none;
	width: 90px;
	height: 18px;
	/* `accent`, pas `accent-light` : ce dernier est réservé au fond marine. */
	background: var(--wp--preset--color--accent);
	-webkit-mask: var(--aqg-i-star) left center / 18px 18px repeat-x;
	mask: var(--aqg-i-star) left center / 18px 18px repeat-x;
}

.aqg-avis-card__quote {
	display: flex;
	flex-direction: column;
	flex: 1;
	gap: 12px;
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 16px;
	line-height: 1.6;
	color: var(--wp--preset--color--contrast);
}

.aqg-avis-card__quote p {
	margin: 0;
	font-size: inherit;
	font-style: normal;
}

/* La signature descend en bas de carte : sur une rangée, toutes les
   signatures s'alignent quelle que soit la longueur de l'avis. */
.aqg-avis-card__quote cite {
	margin-top: auto;
	padding-top: 14px;
	border-top: 1px solid var(--aqg-border-warm-2);
	font-style: normal;
	font-weight: 800;
	font-size: 15px;
	color: var(--wp--preset--color--primary-dark);
}

.aqg-avis-more {
	margin-top: 28px;
}

@media (max-width: 960px) {
	.aqg-avis {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.aqg-avis > .aqg-avis-card:nth-child(4) {
		grid-column: span 2;
	}

	.aqg-avis > .aqg-avis-card:nth-child(5) {
		grid-column: 2 / span 2;
	}
}

@media (max-width: 600px) {
	.aqg-avis {
		grid-template-columns: minmax(0, 1fr);
	}

	.aqg-avis > .aqg-avis-card,
	.aqg-avis > .aqg-avis-card:nth-child(4),
	.aqg-avis > .aqg-avis-card:nth-child(5) {
		grid-column: auto;
	}

	.aqg-avis-card {
		padding: 22px;
	}
}

/* ---------- CTA + form ---------- */
.aqg-cta {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 48px;
	align-items: center;
	padding: 56px 50px;
	border-radius: 32px;
	background: var(--wp--preset--color--accent);
}

.aqg-cta__body {
	color: #fff;
}

.aqg-cta__body h2 {
	color: #fff;
	line-height: 1.05;
	margin: 0 0 18px;
	/* Lignes équilibrées : sans cela, « ouvrées. » restait seul sur la
	   dernière ligne à 412 et 430 px (voir le commentaire du titre dans
	   patterns/cta-contact.php). Ignoré sans dommage par un navigateur qui
	   ne le connaît pas. */
	text-wrap: balance;
}

.aqg-cta__lead {
	margin: 0 0 30px;
	/* Voir `.aqg-hero__urgence-text` : le crème ne tient sur aucun orange. */
	color: #fff;
	font-weight: 500;
}

.aqg-cta__phone {
	margin: 0 0 14px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 26px;
}

.aqg-cta__phone a {
	color: #fff;
	text-decoration: none;
}

.aqg-cta__line {
	margin: 0 0 14px;
	font-size: 16px;
	font-weight: 600;
	color: #fff;
}

.aqg-cta__line a {
	color: #fff;
}

.aqg-form {
	padding: 34px;
	border-radius: 24px;
	background: #fff;
}

.aqg-form__row {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 12px;
	margin-bottom: 12px;
}

.aqg-form__field {
	display: block;
	margin-bottom: 12px;
}

.aqg-form__row .aqg-form__field {
	margin-bottom: 0;
}

.aqg-form__field > span {
	display: block;
	margin-bottom: 6px;
	font-size: 13px;
	font-weight: 700;
	color: var(--wp--preset--color--contrast);
}

.aqg-form__field input,
.aqg-form__field select,
.aqg-form__field textarea {
	box-sizing: border-box;
	width: 100%;
	height: 48px;
	padding: 0 14px;
	border: 1px solid var(--aqg-input-border);
	border-radius: 12px;
	background: var(--aqg-input-bg);
	font-size: 15px;
	font-family: inherit;
	color: #444;
}

.aqg-form__field select {
	cursor: pointer;
	appearance: none;
	-webkit-appearance: none;
	/* Chevron maison — évite le rendu natif hétérogène entre OS. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235C6670' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 18px;
	padding-right: 40px;
}

.aqg-form__field textarea {
	height: auto;
	padding: 12px 14px;
	resize: vertical;
}

.aqg-form__submit {
	display: block;
	margin-top: 4px;
	padding: 16px;
	border-radius: 12px;
	background: var(--wp--preset--color--primary);
	color: #fff;
	font-weight: 800;
	font-size: 16px;
	text-align: center;
	text-decoration: none;
}

.aqg-form__submit:hover,
.aqg-form__submit:focus-visible {
	background: var(--wp--preset--color--primary-dark);
	color: #fff;
}

.aqg-form__hint {
	margin: 10px 0 0;
	font-size: 12px;
	text-align: center;
	color: var(--aqg-muted-2);
}

/* Lien « politique de confidentialité » de la mention d'information.
   COULEUR : `primary`, 5,52:1 sur le panneau blanc, c'est-à-dire la couleur que
   `theme.json` lui donnait déjà. La règle ne change donc rien au rendu : elle
   le FIGE contre une retouche future des liens dans `theme.json`, et rejoue le
   survol en `primary-dark`, qu'une règle de classe écraserait sinon.
   SÉCABLE, volontairement : le lien se coupe en fin de ligne à de nombreuses
   largeurs (163 largeurs de fenêtre sur 501 entre 300 et 1300px, mobile comme
   bureau, mesuré le 2026-09-26), et c'est la règle unique de l'anneau, plus
   haut, qui ferme l'anneau de chaque morceau (`box-decoration-break: clone`).
   Le rendre insécable (`white-space: nowrap`) faisait déborder la page quand
   le texte est agrandi seul : motif et mesures avec la règle unique. */
.aqg-form__hint a {
	color: var(--wp--preset--color--primary);
}

.aqg-form__hint a:hover {
	color: var(--wp--preset--color--primary-dark);
}

/* Légende de l'astérisque (RGAA 11.10). L'astérisque était posée sur trois
   champs sans qu'aucun texte n'en donne le sens. Encre `--aqg-muted`, 5,85:1
   sur le panneau blanc du formulaire. */
.aqg-form__legend {
	margin: 0 0 14px;
	font-size: 13px;
	color: var(--aqg-muted);
}

/* Posée d'avance, et c'est délibéré : ce thème n'a AUCUN reset sur `a`, et
   `theme.json` peint tout lien en `primary` depuis une règle de spécificité
   nulle. Un renvoi ajouté un jour dans cette légende sortait donc à 3,45:1 sur
   le panneau blanc tant que `primary` valait #0092D6 ; depuis qu'il vaut
   #14387F, ce serait 11,04:1, et la règle garde son sens : elle
   fige la couleur contre une retouche de `theme.json`. Le piège s'est déjà
   refermé deux fois sur ce projet. Un tel lien serait aussi à ajouter à la
   règle d'anneau unique, comme `.aqg-form__hint a`. */
.aqg-form__legend a {
	color: var(--aqg-chip-ink);
}

/* Réserve de dépannage sous le sélecteur « Votre besoin » (cta-contact.php),
   rendue HORS du <label>. Marge haute négative : elle se combine avec les 12px
   de `.aqg-form__field` (une positive, une négative : 12 - 6 = 6px, l'écart
   intitulé / champ). Encre `--aqg-muted`, 5,85:1 sur le panneau blanc, comme la
   légende. Aucun lien : un lien demanderait sa règle de couleur, une place dans
   la règle d'anneau unique ET dans le bloc forced-colors (05-design-system.md).
   Sécable, sans nowrap (texte agrandi seul à 200 %). */
.aqg-form__note {
	margin: -6px 0 12px;
	font-size: 13px;
	line-height: 1.45;
	color: var(--aqg-muted);
}

/* ---------- FAQ ---------- */
.aqg-faq {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.aqg-faq__item {
	padding: 22px 26px;
	border-radius: 18px;
	background: #fff;
	border: 1px solid var(--aqg-border-warm-2);
}

/* Block flow (not flex) so the question text wraps naturally and the trailing
   « ? » never gets pushed onto its own line; the marker is absolutely placed. */
.aqg-faq__item summary {
	display: block;
	position: relative;
	padding-right: 40px;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: 18px;
	cursor: pointer;
	list-style: none;
}

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

.aqg-faq__item summary::after {
	content: "+";
	position: absolute;
	top: 50%;
	right: 0;
	transform: translateY(-50%);
	color: var(--wp--preset--color--accent);
	font-size: 24px;
	line-height: 1;
	transition: transform .34s cubic-bezier(.2, .7, .2, 1);
}

.aqg-faq__item[open] summary::after {
	transform: translateY(-50%) rotate(135deg);
}

.aqg-faq__item p {
	margin: 16px 0 0;
	font-size: 15.5px;
	line-height: 1.6;
	color: #555;
}

/* Ouverture et fermeture animées.
   Le bloc « Détails » du cœur bascule d'un coup. `::details-content` donne prise
   sur le contenu replié et permet d'en animer la hauteur réelle, sans JS et sans
   hauteur codée en dur :
   - `interpolate-size: allow-keywords`, posé sur `:root` et hérité, autorise
     l'interpolation vers `block-size: auto` (donc vers la hauteur du texte, quel
     qu'il soit) ;
   - `content-visibility` doit être transitionné en `allow-discrete`, sinon le
     navigateur masque le contenu dès la première frame de la fermeture et seule
     l'ouverture s'anime ;
   - `overflow: hidden` crée un contexte de formatage : la marge haute du
     paragraphe reste dans la boîte animée au lieu de s'échapper.
   Navigateur sans `::details-content` : bascule instantanée, exactement comme
   aujourd'hui. Coupé net si l'utilisateur préfère moins d'animations. */
@media (prefers-reduced-motion: no-preference) {
	.aqg-faq__item::details-content {
		block-size: 0;
		overflow: hidden;
		opacity: 0;
		transition:
			block-size .34s cubic-bezier(.2, .7, .2, 1),
			opacity .26s ease,
			content-visibility .34s allow-discrete;
	}

	.aqg-faq__item[open]::details-content {
		block-size: auto;
		opacity: 1;
	}
}

/* ---------- Zone ---------- */
/* ---------- Zone d'intervention : le titre sur sa ligne, les communes en grille
   Retour client : « les badges cassent l'UI, ça se retrouve sur une ligne. Il
   vaut mieux mettre le titre centré puis les badges alignés en dessous, en
   faisant attention à ce qu'ils ne se retrouvent pas seuls. »

   MESURÉ AVANT CORRECTIF, nombre de pilules sur la DERNIÈRE ligne :
   1440px → 1 · 1200px → 1 · 900px → 3 · 640px → 1 · 390px → 2 · 320px → 1.
   L'orpheline était « + sud lyonnais » sur ordinateur, et le titre partageait
   en plus la ligne des pilules partout au-dessus de 640px.

   Deux gestes, et le second est un choix de COMPTAGE, pas de style.
   1. Le titre passe sur sa propre ligne à TOUTES les largeurs. La règle
      existait déjà, mais seulement sous 640px : on la généralise plutôt que
      d'inventer une mise en page.
   2. « + sud lyonnais » n'est pas une commune, c'est une mention de portée :
      elle quitte la liste et prend la ligne entière sous les communes. Il
      reste alors SIX communes, et six se divise par 6, 3, 2 et 1. Toutes les
      rangées sont pleines à chaque point de bascule PAR CONSTRUCTION, et non
      par coïncidence de largeurs. Avec les sept d'origine, un nombre premier,
      trois découpages sur quatre laissaient une orpheline (3+3+1, 2+2+2+1).

   Colonnes en `auto` et non en `1fr` : les libellés vont de « Lyon » (66px) à
   « Sérézin-du-Rhône » (166px), des colonnes égales gaspilleraient la moitié
   de la largeur sur ordinateur. Les pilules gardent leur largeur naturelle et
   s'alignent colonne par colonne, ce que le flux libre ne garantissait pas.

   Le groupe est passé en layout `default` côté pattern : en layout `flex`, le
   cœur injecte `display: flex` et le `gap` sur une classe de conteneur
   générée, qu'aucune règle d'ici ne peut surcharger proprement. Même recette
   que `.aqg-services-grid`.

   Tout est scopé à `.aqg-zone` : `.aqg-chip` sert aussi au bloc « Nos métiers »
   des sept pages service, qui a son propre découpage (`.aqg-voiraussi__links`).
   ------------------------------------------------------------------------- */
.aqg-zone {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	padding: 30px 34px;
	border-radius: 24px;
	background: #fff;
	border: 1px solid var(--aqg-border-warm-2);
}

/* PIÈGE MESURÉ — les six communes ont besoin de LEUR PROPRE conteneur.
   Première tentative : une seule grille sur `.aqg-zone`, le titre et la note
   « hors zone » traversant les colonnes en `grid-column: 1 / -1`. Un élément
   qui couvre toutes les pistes leur distribue sa largeur, or la note fait
   1090px de texte : les six pistes `auto` gonflaient jusqu'à remplir le bloc
   et les pilules s'éparpillaient sur toute la largeur, séparées par des vides
   irréguliers. La grille ne porte donc QUE les pilules, et `.aqg-zone` reste
   une simple colonne. */
.aqg-zone__chips {
	display: grid;
	grid-template-columns: repeat(6, auto);
	justify-content: center;
	justify-items: center;
	gap: 12px 14px;
}

.aqg-zone__extend {
	align-self: stretch;
}

/* MESURÉ, ET C'EST LE SECOND ESSAI. La mention a d'abord été posée en pilule à
   contour, hors de la grille : structurellement ce n'était plus une commune,
   mais à l'écran elle restait une PILULE SEULE sur la dernière ligne, à tous
   les paliers, donc exactement le défaut que le client demandait d'éviter.
   Elle est maintenant une ligne de texte : il n'y a plus de pilule à compter,
   et le « + » se lit comme la suite de la liste. */
.aqg-zone__more {
	margin: 0;
	color: var(--aqg-muted);
	font-size: 14.5px;
	font-weight: 700;
}

/* La mention de portée est devenue un lien vers le hub local au lot maillage.
   La règle est CONSERVÉE bien que son motif d'origine soit levé : elle avait été
   écrite parce que `--primary`, alors #0092D6, donnait 3,45:1 sur le fond blanc
   de la carte, un échec AA à 14,5px. Depuis l'assombrissement de la palette,
   `--primary` y donne 11,04:1 et suffirait. On garde `--primary-dark` (13,85:1)
   pour aligner ce lien sur son voisin `.aqg-zone__extend a`, six lignes plus bas
   dans la MÊME carte, plutôt que de les laisser diverger d'un cran. */
.aqg-zone__more a {
	color: var(--wp--preset--color--primary-dark);
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Une pilule sans lien ne réagit pas au survol : l'effet hérité de `.aqg-chip`
   lui donnerait le comportement d'un bouton à côté d'un vrai lien, fausse
   affordance. Depuis le 2026-08-22 cinq des six pilules SONT des liens, et
   c'est `--link` qui les distingue ; « Lyon », qui n'a pas de page, garde le
   comportement inerte décrit ici. */
.aqg-zone .aqg-chip:hover {
	transform: none;
	background: var(--wp--preset--color--surface-blue);
	color: var(--aqg-chip-ink);
}

/* Pilule-lien : cliquable EN ENTIER, comme celles du bloc « Nos métiers ».
   Le rembourrage passe au lien, jamais au paragraphe : posé sur le <p>, seul
   le texte réagit au clic, mesuré à 35 % de la surface visible sur le bloc de
   maillage. `box-sizing: border-box` est obligatoire, sinon le `min-height`
   s'AJOUTE au rembourrage et la pilule passe de 42 à 62px. */
.aqg-zone .aqg-chip--link {
	display: flex;
	padding: 0;
}

.aqg-zone .aqg-chip--link a {
	display: flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 44px;
	padding: 9px 16px;
	border-radius: inherit;
	color: inherit;
	text-decoration: none;
}

/* Contraste : `--aqg-chip-ink`, comme sur les autres pilules du site. Le motif
   d'origine est levé : le blanc sur `--primary` tombait à 3,45:1 quand il
   valait #0092D6, il donne 11,04:1 sur #14387F (cf. `--aqg-chip-ink` en tête). */
.aqg-zone .aqg-chip--link:hover {
	background: var(--aqg-chip-ink);
	color: #fff;
}

.aqg-zone .aqg-chip--link a:focus-visible {
	/* Anneau bi-ton, identique à celui des boutons : voir son commentaire.
	   Une couleur unique est intenable ici, ces pilules et ces liens vivant
	   tantôt sur du clair, tantôt sur du marine. */
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
}

@media (max-width: 1023px) {
	.aqg-zone__chips {
		grid-template-columns: repeat(3, auto);
	}
}

@media (max-width: 699px) {
	.aqg-zone__chips {
		grid-template-columns: repeat(2, auto);
	}
}

/* Sous 480px, deux colonnes demanderaient 291px de pilules pour 224px utiles à
   320px : les colonnes `auto` ne peuvent pas rétrécir sous leur contenu, qui
   est en `white-space: nowrap`, et le bloc déborderait. Une colonne, donc, et
   toutes les rangées restent pleines. */
@media (max-width: 479px) {
	.aqg-zone__chips {
		grid-template-columns: auto;
	}
}

.aqg-zone__label {
	margin: 0;
	text-align: center;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 800;
	font-size: 22px;
}

.aqg-chip {
	margin: 0;
	padding: 9px 16px;
	border-radius: 100px;
	background: var(--wp--preset--color--surface-blue);
	color: var(--aqg-chip-ink);
	font-weight: 700;
	font-size: 15px;
}

/* Mention « hors zone » : ligne pleine largeur sous les communes. */
.aqg-zone__extend {
	margin: 4px 0 0;
	padding-top: 20px;
	border-top: 1px solid var(--aqg-border-warm-2);
	text-align: center;
	font-size: 15px;
	line-height: 1.6;
	color: var(--aqg-muted);
}

.aqg-zone__extend strong {
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
}

.aqg-zone__extend a {
	color: var(--wp--preset--color--primary-dark);
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* ---------- Footer ---------- */
.aqg-footer {
	background: var(--wp--preset--color--contrast);
	color: #999;
}

.aqg-footer__grid {
	padding: 52px 40px;
	gap: 30px;
	margin-inline: auto;
	max-width: 1240px;
}

.aqg-footer__brand {
	margin: 0;
	width: 170px;
	max-width: 62%;
	aspect-ratio: 541 / 139;
	background: url("../images/logo-marque.png") left center / contain no-repeat;
	/* Wordmark en image ; le texte « AquaGones » reste lu par les lecteurs
	   d'écran (déporté hors écran, technique d'image-replacement). */
	text-indent: -9999px;
	overflow: hidden;
	white-space: nowrap;
}

.aqg-footer__desc {
	margin: 12px 0 0;
	max-width: 280px;
	line-height: 1.6;
	color: #999;
}

.aqg-footer__title {
	margin: 0 0 8px;
	color: #fff;
	font-weight: 700;
}

.aqg-footer__list {
	margin: 0;
	padding: 0;
	list-style: none;
	line-height: 2;
	font-size: 14px;
}

.aqg-footer__list a {
	color: #999;
	text-decoration: none;
}

.aqg-footer__list a:hover {
	color: #fff;
}

/* Bas de page : le « © » centré sur la largeur, le crédit de réalisation
   à sa droite à partir de 1160px ; en dessous, les deux centrés l'un sous
   l'autre. Le filet court sur toute la largeur, le contenu s'aligne sur les
   colonnes du pied. */
.aqg-footer__bottom {
	display: grid;
	justify-items: center;
	row-gap: 6px;
	margin: 0;
	padding-block: 18px;
	padding-inline: max(40px, calc((100% - 1240px) / 2 + 40px));
	border-top: 1px solid #2A2A2A;
	text-align: center;
}

.aqg-footer__copy,
.aqg-footer__credit {
	margin: 0;
	color: #8C9298;
}

/* Lien souligné, même gris que le texte (5,5:1 sur l'encre), blanc au survol
   comme les autres liens du pied ; sans cette règle il prendrait le bleu
   `primary`, illisible sur ce fond. */
.aqg-footer__credit a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.aqg-footer__credit a:hover {
	color: #fff;
}

@media (min-width: 1160px) {
	.aqg-footer__bottom {
		grid-template-columns: 1fr auto 1fr;
	}

	.aqg-footer__copy {
		grid-column: 2;
	}

	.aqg-footer__credit {
		grid-column: 3;
		justify-self: end;
	}
}

@media (max-width: 782px) {
	.aqg-footer__bottom {
		padding-inline: 22px;
	}
}

/* ---------- Post / page / 404 ---------- */
.aqg-page {
	padding-block: 56px 80px;
}

.aqg-page__thumb img {
	border-radius: 16px;
}

/* Bouton d'opposition à la mesure d'audience, dans la politique de
   confidentialité (section « Mesure d’audience », écrite par la routine
   `06-pages-legales.sh`). Il est rendu avec l'attribut `hidden`, et seul le
   script de mesure d'audience du plugin le rend visible, là où la mesure
   tourne : sans JavaScript, en local et sur l'aperçu, il n'apparaît pas, comme
   la politique l'annonce. D'où `[hidden]` réaffirmé : une règle de classe qui
   pose un `display` bat la feuille du navigateur, et le bouton resterait à
   l'écran (même piège que `.aqg-form__fields[hidden]`, plus bas).

   Pilule secondaire calquée sur `.aqg-form__again`, posée sur la toile crème
   de la page : libellé primary-dark sur blanc 8,22:1, blanc sur primary-dark
   au survol et au focus 8,22:1, bordure primary 4,82:1 sur la toile. La zone
   d'état, `role="status"`, est vide au chargement et reçoit ses phrases du
   script : texte `contrast`, 15,21:1 sur la toile. Son anneau est celui de la
   règle unique, dont le bouton est porteur. */
.aqg-optout-zone {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
}

.aqg-optout {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 11px 20px;
	border: 1.5px solid var(--wp--preset--color--primary);
	border-radius: 100px;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary-dark);
	font-family: inherit;
	font-size: 15px;
	font-weight: 800;
	line-height: 1.2;
	cursor: pointer;
}

.aqg-optout[hidden] {
	display: none;
}

.aqg-optout:hover,
.aqg-optout:focus-visible {
	border-color: var(--wp--preset--color--primary-dark);
	background: var(--wp--preset--color--primary-dark);
	color: #fff;
}

.aqg-optout__etat {
	color: var(--wp--preset--color--contrast);
	font-size: 15px;
}

.aqg-post-item {
	padding-block: 22px;
	border-bottom: 1px solid var(--aqg-border-warm);
}

.aqg-post-meta {
	gap: 16px;
	margin-bottom: 16px;
	color: var(--aqg-muted-2);
}

.aqg-404 {
	text-align: center;
	padding-block: 90px;
}

/* ---------- Page contact (/contact/, cible du QR code) ----------
   Corps de la page de coordonnées, pattern `aquagones/page-contact`, rendu par
   `page.html` (H1 = titre de la page, contentSize 780px) sur la toile crème.
   Une carte blanche qui porte, dans l'ordre : l'accroche, la pile des boutons
   (appeler, laisser un avis, enregistrer, écrire), puis les horaires et la
   zone d'intervention.

   Tout est visible dès le premier rendu : aucune classe de la liste
   d'apparition au défilement d'`interactions.js`. La page s'ouvre depuis un
   QR code, téléphone en main, et ses boutons ne doivent jamais attendre un
   script ni entrer en fondu.

   L'espacement vient des `gap` de grille, jamais des marges : les enfants
   directs sont remis à `margin-block: 0`, sans quoi la gouttière de flux du
   cœur (24px) s'ajouterait aux `gap` (même mécanisme que « Cartes, hauteur
   égale par rangée », plus bas).

   Pas d'`overflow: hidden` sur la carte : l'anneau de focus bi-ton déborde de
   5px autour des boutons pleine largeur et serait rogné. Il se peint sur la
   carte blanche (bande sombre `ink-deep`, 16,23:1 sur blanc, calculé). */
.aqg-contact {
	display: grid;
	gap: 28px;
	padding: 32px;
	border: 1px solid var(--aqg-border-warm-2);
	border-radius: 24px;
	background: var(--wp--preset--color--base);
	box-shadow: var(--aqg-shadow-card);
}

.aqg-contact > *,
.aqg-contact__infos > *,
.aqg-contact__bloc > * {
	margin-block: 0;
}

/* Accroche : gris atténué, 5,85:1 sur la carte blanche. */
.aqg-contact__lead {
	max-width: 60ch;
	color: var(--aqg-muted);
	line-height: 1.5;
}

/* Pile verticale des boutons. Le parent est nommé pour passer devant la règle
   de conteneur que le cœur génère pour une mise en page flex verticale
   (`flex-direction: column; align-items: flex-start`, spécificité 0,1,0),
   dont l'ordre d'impression par rapport à cette feuille n'est pas garanti.
   `stretch` donne à chaque bouton toute la largeur de la pile, et la pile est
   bornée sur ordinateur : pleine largeur de la carte, les boutons feraient
   environ 716px, une barre plus qu'un bouton. Sous 420px de carte, la borne
   ne joue plus et les boutons occupent toute la largeur.

   Cibles d'au moins 48px de haut (le rembourrage de `theme.json` en donne
   déjà environ 55 sur une ligne ; `min-height` garde le plancher si le
   libellé ou la taille de police changent). Le numéro du premier bouton est
   écrit avec des espaces insécables dans le pattern : à la taille de texte
   normale il ne se coupe pas, 320px compris, seul « Appeler le » passant à
   la ligne au-dessus de lui ; texte agrandi à 200 % sur 320px, le
   `word-break: break-word` du cœur le coupe plutôt que de faire déborder la
   page, et c'est voulu. Pas de
   `white-space: nowrap` sur le libellé entier, qui ferait déborder le
   document dès que le texte est agrandi seul (cf. règle unique de l'anneau). */
.aqg-contact .aqg-contact__actions {
	flex-direction: column;
	align-items: stretch;
	gap: 12px;
	width: 100%;
	max-width: 420px;
}

.aqg-contact__actions > .wp-block-button {
	width: 100%;
	margin: 0;
}

.aqg-contact__actions .wp-block-button__link {
	box-sizing: border-box;
	width: 100%;
	min-height: 48px;
}

/* Horaires et zone : deux blocs côte à côte dès que la carte leur laisse
   260px chacun, l'un sous l'autre sinon. Filet chaud de séparation avec la
   pile des boutons, décoratif. */
.aqg-contact__infos {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
	gap: 24px 32px;
	padding-top: 28px;
	border-top: 1px solid var(--aqg-border-warm-2);
}

.aqg-contact__bloc {
	display: grid;
	align-content: start;
	gap: 8px;
}

.aqg-contact__title {
	display: flex;
	align-items: center;
}

/* Pictogramme de l'intertitre en `primary`, 5,52:1 sur blanc (3:1 exigé pour
   un élément graphique). Spécificité 0,2,1, à égalité avec le repeint du bloc
   `forced-colors` n° 2 de fin de fichier, qui gagne donc par l'ordre source. */
.aqg-contact__title.aqg-ic::before {
	background: var(--wp--preset--color--primary);
}

/* Lien placé dans le texte (« Voir les communes desservies »). Sans cette
   règle, il sortirait en `primary` depuis `theme.json`. `primary-dark` souligné,
   8,22:1 sur blanc. `theme.json` génère son survol sous la forme
   `:root :where(a:where(:not(.wp-element-button)):hover)`, en (0,1,0) (WP 7.1,
   class-wp-theme-json.php) : cette règle, en (0,1,1), l'emporte donc aussi au
   survol sans dépendre de l'ordre d'impression, et la règle de survol ne porte
   que l'épaisseur du soulignement. Porteur de la règle unique de l'anneau de
   focus ET du bloc `forced-colors` n° 4. */
.aqg-contact__line a {
	color: var(--wp--preset--color--primary-dark);
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.aqg-contact__line a:hover {
	text-decoration-thickness: 2px;
}

/* Sous 480px, carte et boutons resserrés : à 320px de fenêtre, la carte ne
   laisse plus qu'environ 256px aux boutons (marges de `.aqg-shell` à 14px
   sous 400px, 18px de rembourrage de carte). Marges internes des boutons
   ramenées de 28 à 20px (18,5px plus la bordure pour le contour), soit 16px
   de libellé regagnés. */
@media (max-width: 480px) {
	.aqg-contact {
		gap: 24px;
		padding: 24px 18px;
		border-radius: 20px;
	}

	.aqg-contact .aqg-contact__actions .wp-block-button__link {
		padding-inline: 20px;
	}

	.aqg-contact .aqg-contact__actions .aqg-btn-outline .wp-block-button__link {
		padding-inline: 18.5px;
	}
}

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
	.aqg-hero__bento {
		grid-template-columns: 1fr;
		grid-template-rows: auto;
	}

	.aqg-hero__main,
	.aqg-hero__media,
	.aqg-hero__urgence {
		grid-column: 1;
		grid-row: auto;
	}

	.aqg-hero__media {
		min-height: 240px;
	}

	.aqg-feature {
		grid-template-columns: 1fr;
	}

	.aqg-header__tel {
		display: none;
	}

	.aqg-services-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	/* Deux colonnes : les spans d'ordinateur laisseraient un trou, un span de
	   deux ne pavant que s'il démarre en première colonne. Dans l'ordre du
	   catalogue, la seule position qui remplit cette condition est la carte
	   « spécialité », qui prend donc la rangée entière. Total : huit unités,
	   quatre rangées pleines. */
	.aqg-services .aqg-service-card--wide {
		grid-column: auto;
	}

	.aqg-services .aqg-service-card--feature {
		grid-column: span 2;
	}

	/* Stack the mosaic into a simple 2-col grid. */
	.aqg-realis {
		grid-template-columns: 1fr 1fr;
		grid-template-rows: auto;
	}

	.aqg-realis-card {
		min-height: 200px;
	}

	.aqg-realis-card--tall {
		grid-row: auto;
	}

	/* Cellule simple elle aussi : sur deux colonnes, la carte haute redevenue
	   simple et les deux petites occupent trois cases, et une carte large sur
	   toute la rangée laissait la quatrième vide (mesuré à 900px le
	   2026-10-03). Quatre cartes, deux rangées pleines. */
	.aqg-realis-card--wide {
		grid-column: auto;
	}

	/* Drop the horizontal frieze line once steps wrap. */
	.aqg-steps {
		grid-template-columns: repeat(2, 1fr);
		gap: 30px 24px;
	}

	.aqg-steps::before {
		display: none;
	}
}

@media (max-width: 782px) {
	.aqg-shell {
		padding-inline: 22px;
	}

	.aqg-services-grid,
	.aqg-aides__grid,
	.aqg-feature__checks {
		grid-template-columns: 1fr;
	}

	/* Une seule colonne : un span de deux y créerait une colonne IMPLICITE,
	   donc un débordement horizontal. Les deux modificateurs sont neutralisés. */
	.aqg-services .aqg-service-card--wide,
	.aqg-services .aqg-service-card--feature {
		grid-column: auto;
	}

	.aqg-cta {
		grid-template-columns: 1fr;
		gap: 30px;
	}

	.aqg-hero__main,
	.aqg-feature__body {
		padding: 40px 28px;
	}

	.aqg-aides,
	.aqg-cta,
	.aqg-processus__card {
		padding: 34px 26px;
	}

	.aqg-feature__media {
		min-height: 260px;
	}

	.aqg-footer__grid {
		padding: 40px 22px;
	}
}

/* Mobile band (≤600px = where the navigation collapses to the overlay menu). */
@media (max-width: 600px) {
	/* M3 — Certifs banner: chaque rangée a son intitulé sur une ligne centrée,
	   pastilles/marques wrappent dessous, aucun chevauchement, jamais de coupure. */
	.aqg-certs {
		gap: 14px;
		padding: 18px 16px;
	}

	.aqg-certs__row {
		gap: 9px 10px;
	}

	.aqg-certs__label {
		flex-basis: 100%;
		text-align: center;
		font-size: 11.5px;
	}

	.aqg-qual {
		font-size: 13px;
		padding: 8px 13px;
	}

	.aqg-brand-name {
		font-size: 15px;
		white-space: nowrap;
	}

	/* M4 — Process timeline: single column, no horizontal frieze line,
	   comfortable vertical spacing (dots stacked, centred). */
	.aqg-steps {
		grid-template-columns: 1fr;
		gap: 26px;
	}

	.aqg-steps::before {
		display: none;
	}

	.aqg-step__dot {
		margin-bottom: 12px;
	}

	/* Gouttière resserrée et titre plus petit. Le passage du titre sur sa propre
	   ligne, qui ne vivait ici que pour le mobile, est désormais général (cf.
	   `.aqg-zone`, `grid-column: 1 / -1`). */
	.aqg-zone {
		gap: 12px;
	}

	.aqg-zone__chips {
		gap: 8px 10px;
	}

	.aqg-zone__label {
		font-size: 18px;
	}

	.aqg-chip {
		white-space: nowrap;
	}
}

@media (max-width: 560px) {
	.aqg-realis {
		grid-template-columns: 1fr;
	}

	.aqg-realis-card--wide {
		grid-column: 1;
	}

	.aqg-steps {
		grid-template-columns: 1fr;
	}

	/* Le duo Nom / Téléphone s'empile pour respirer. */
	.aqg-form__row {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 480px) {
	.aqg-shell {
		padding-inline: 18px;
	}

	.aqg-header {
		padding: 12px 14px 0;
	}

	.aqg-navpill {
		padding: 8px 10px 8px 12px;
		gap: 12px;
	}

	.aqg-main > section {
		padding-block-end: 50px;
	}

	.aqg-hero__cta {
		flex-direction: column;
		align-items: stretch;
	}

	.aqg-hero__cta .wp-block-button,
	.aqg-hero__cta .wp-block-button__link {
		width: 100%;
	}

	.aqg-hero__main,
	.aqg-feature__body {
		padding: 34px 22px;
	}

	.aqg-aides,
	.aqg-cta,
	.aqg-processus__card {
		padding: 30px 20px;
	}

	/* Section TVA : 20 px de texte en plus par ligne, sur une carte qui n'en
	   laissait que 246 à 390 px de large. */
	.aqg-aides .aqg-aide-card {
		padding: 22px 20px;
	}

	.aqg-cta__phone {
		font-size: 22px;
	}

	.aqg-service-card--sos .wp-block-buttons,
	.aqg-service-card--sos .wp-block-button,
	.aqg-service-card--sos .wp-block-button__link {
		width: 100%;
	}

	.aqg-service-card--sos .wp-block-button__link {
		text-align: center;
		justify-content: center;
	}

	.aqg-stat {
		flex: 1 1 100%;
		min-width: 0;
	}

	.aqg-certs {
		padding: 16px 16px;
	}

	.aqg-btn-sm .wp-block-button__link {
		padding: 10px 14px;
		font-size: 13px;
	}

}

@media (max-width: 400px) {
	.aqg-shell {
		padding-inline: 14px;
	}

	.aqg-hero__main,
	.aqg-feature__body {
		padding: 28px 18px;
	}

	.aqg-form {
		padding: 26px 20px;
	}

	.aqg-service-card__body,
	.aqg-service-card--dark,
	.aqg-service-card--sos {
		padding: 24px 20px;
	}

	/* Les cartes à icône de la grille des métiers suivent leurs voisines : sans
	   cette ligne elles gardaient les 30px de `--plain` quand les cartes photo,
	   marine et dépannage passaient à 20px, et leur texte se décalait de 11px
	   sur la même colonne. Scopé à l'accueil : `--plain` sert aussi aux grilles
	   de prestations des sept fiches, dont le gabarit n'est pas en cause. */
	.aqg-services .aqg-service-card--plain {
		padding: 24px 20px;
	}


	.aqg-cta__phone {
		font-size: 20px;
	}
}

/* ==========================================================================
   Icônes — jeu de pictos « line » (style Lucide, ISC) rendus en CSS mask.
   100 % auto-hébergé (data-URI), RGPD-safe, teinté par `currentColor`.
   La forme est portée par une classe `.i-*`, la couleur par le contexte.
   ========================================================================== */
:root {
	--aqg-i-wrench: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z'/%3E%3C/svg%3E");
	--aqg-i-leaf: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z'/%3E%3Cpath d='M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12'/%3E%3C/svg%3E");
	--aqg-i-flame: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z'/%3E%3C/svg%3E");
	--aqg-i-snow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 12h20'/%3E%3Cpath d='M12 2v20'/%3E%3Cpath d='m20 16-4-4 4-4'/%3E%3Cpath d='m4 8 4 4-4 4'/%3E%3Cpath d='m16 4-4 4-4-4'/%3E%3Cpath d='m8 20 4-4 4 4'/%3E%3C/svg%3E");
	--aqg-i-fan: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.827 16.379a6.082 6.082 0 0 1-8.618-7.002l5.412 1.45a6.082 6.082 0 0 1 7.002-8.618l-1.45 5.412a6.082 6.082 0 0 1 8.618 7.002l-5.412-1.45a6.082 6.082 0 0 1-7.002 8.618l1.45-5.412Z'/%3E%3Cpath d='M12 12v.01'/%3E%3C/svg%3E");
	--aqg-i-life: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m4.93 4.93 4.24 4.24'/%3E%3Cpath d='m14.83 9.17 4.24-4.24'/%3E%3Cpath d='m14.83 14.83 4.24 4.24'/%3E%3Cpath d='m9.17 14.83-4.24 4.24'/%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3C/svg%3E");
	--aqg-i-droplet: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z'/%3E%3C/svg%3E");
	--aqg-i-clipboard: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E");
	--aqg-i-zap: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='13 2 3 14 12 14 11 22 21 10 12 10 13 2'/%3E%3C/svg%3E");
	--aqg-i-headset: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 11h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H4a1 1 0 0 1-1-1v-5a9 9 0 0 1 18 0v5a1 1 0 0 1-1 1h-2a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3'/%3E%3Cpath d='M21 16v2a4 4 0 0 1-4 4h-5'/%3E%3C/svg%3E");
	--aqg-i-phone: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E");
	--aqg-i-mail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='20' height='16' x='2' y='4' rx='2'/%3E%3Cpath d='m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7'/%3E%3C/svg%3E");
	--aqg-i-pin: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
	--aqg-i-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
	/* New « Innovant » shapes. */
	--aqg-i-clock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E");
	--aqg-i-shield: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E");
	/* Formes ajoutées pour les pages service. */
	--aqg-i-reverse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8'/%3E%3Cpath d='M21 3v5h-5'/%3E%3Cpath d='M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16'/%3E%3Cpath d='M8 16H3v5'/%3E%3C/svg%3E");
	--aqg-i-grid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='14' y='3' rx='1'/%3E%3Crect width='7' height='7' x='14' y='14' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3C/svg%3E");
	--aqg-i-eyeoff: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.73 5.08a10.74 10.74 0 0 1 11.21 6.57 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-1.45 2.49'/%3E%3Cpath d='M14.08 14.16a3 3 0 0 1-4.24-4.24'/%3E%3Cpath d='M17.48 17.5a10.75 10.75 0 0 1-15.42-5.15 1 1 0 0 1 0-.7 10.75 10.75 0 0 1 4.45-5.14'/%3E%3Cpath d='m2 2 20 20'/%3E%3C/svg%3E");
	--aqg-i-thermo: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z'/%3E%3C/svg%3E");
	--aqg-i-quiet: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolygon points='11 5 6 9 2 9 2 15 6 15 11 19 11 5'/%3E%3Cline x1='22' x2='16' y1='9' y2='15'/%3E%3Cline x1='16' x2='22' y1='9' y2='15'/%3E%3C/svg%3E");
	--aqg-i-bulb: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5'/%3E%3Cpath d='M9 18h6'/%3E%3Cpath d='M10 22h4'/%3E%3C/svg%3E");
	--aqg-i-ruler: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0z'/%3E%3Cpath d='m14.5 12.5 2-2'/%3E%3Cpath d='m11.5 9.5 2-2'/%3E%3Cpath d='m8.5 6.5 2-2'/%3E%3Cpath d='m17.5 15.5 2-2'/%3E%3C/svg%3E");
	--aqg-i-house: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8'/%3E%3Cpath d='M3 10a2 2 0 0 1 .71-1.53l7-6a2 2 0 0 1 2.58 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3C/svg%3E");
	--aqg-i-building: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z'/%3E%3Cpath d='M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2'/%3E%3Cpath d='M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M10 6h4'/%3E%3Cpath d='M10 10h4'/%3E%3Cpath d='M10 14h4'/%3E%3Cpath d='M10 18h4'/%3E%3C/svg%3E");
	--aqg-i-bath: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 6 6.5 3.5a1.5 1.5 0 0 0-1-.5C4.683 3 4 3.683 4 4.5V17a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5'/%3E%3Cpath d='M10 5 8 7'/%3E%3Cpath d='M2 12h20'/%3E%3Cpath d='M7 19v2'/%3E%3Cpath d='M17 19v2'/%3E%3C/svg%3E");
	/* Formes ajoutées pour la page de coordonnées (/contact/) : « user-plus »
	   pour la fiche de contact à enregistrer, et une bulle de message
	   (« message-square ») pour l'avis. Volontairement PAS une étoile : une
	   étoile écrite en dur évoque une note, que le site n'affiche pas. */
	--aqg-i-user-plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cline x1='19' x2='19' y1='8' y2='14'/%3E%3Cline x1='22' x2='16' y1='11' y2='11'/%3E%3C/svg%3E");
	--aqg-i-message: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'/%3E%3C/svg%3E");
}

/* Shape selectors — set the mask on any icon consumer. */
.i-wrench { --aqg-icon: var(--aqg-i-wrench); }
.i-pac    { --aqg-icon: var(--aqg-i-leaf); }
.i-flame  { --aqg-icon: var(--aqg-i-flame); }
.i-snow   { --aqg-icon: var(--aqg-i-snow); }
.i-fan    { --aqg-icon: var(--aqg-i-fan); }
.i-life   { --aqg-icon: var(--aqg-i-life); }
.i-droplet { --aqg-icon: var(--aqg-i-droplet); }
.i-devis  { --aqg-icon: var(--aqg-i-clipboard); }
.i-zap    { --aqg-icon: var(--aqg-i-zap); }
.i-sav    { --aqg-icon: var(--aqg-i-headset); }
.i-phone  { --aqg-icon: var(--aqg-i-phone); }
.i-mail   { --aqg-icon: var(--aqg-i-mail); }
.i-pin    { --aqg-icon: var(--aqg-i-pin); }
.i-check  { --aqg-icon: var(--aqg-i-check); }
.i-clock  { --aqg-icon: var(--aqg-i-clock); }
.i-shield { --aqg-icon: var(--aqg-i-shield); }
.i-reverse  { --aqg-icon: var(--aqg-i-reverse); }
.i-grid     { --aqg-icon: var(--aqg-i-grid); }
.i-eyeoff   { --aqg-icon: var(--aqg-i-eyeoff); }
.i-thermo   { --aqg-icon: var(--aqg-i-thermo); }
.i-quiet    { --aqg-icon: var(--aqg-i-quiet); }
.i-bulb     { --aqg-icon: var(--aqg-i-bulb); }
.i-ruler    { --aqg-icon: var(--aqg-i-ruler); }
.i-house    { --aqg-icon: var(--aqg-i-house); }
.i-building { --aqg-icon: var(--aqg-i-building); }
.i-bath     { --aqg-icon: var(--aqg-i-bath); }
.i-contact  { --aqg-icon: var(--aqg-i-user-plus); }
.i-avis     { --aqg-icon: var(--aqg-i-message); }

/* Inline icon (before text): buttons, badges, contact lines, checks, chips.
   Context-agnostic: works inside block, flex and list-item parents alike. */
.aqg-ic::before {
	content: "";
	display: inline-block;
	flex: none;
	width: 1.05em;
	height: 1.05em;
	margin-right: .55em;
	vertical-align: -0.16em;
	background: currentColor;
	-webkit-mask: var(--aqg-icon, none) center / contain no-repeat;
	mask: var(--aqg-icon, none) center / contain no-repeat;
}


/* Checks read as accent, whatever the surrounding text colour. */
/* Les 88 coches vivent sur le marine des héros et de la carte « feature ».
   L'orange foncé y resterait conforme (3,29:1 pour un seuil non textuel de 3),
   mais il y perdrait son éclat sans aucune contrepartie d'accessibilité :
   on garde donc l'orange de marque, pour l'identité et non pour la norme. */
.aqg-ic.i-check::before { background: var(--aqg-accent-on-dark); }

/* Phone icon inside pill buttons — icon + number stay centred together, even
   when the button is stretched full-width (hero on mobile, SOS card). */
.aqg-btn-phone .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .5em;
}

.aqg-btn-phone .wp-block-button__link::before {
	content: "";
	flex: none;
	width: 1.05em;
	height: 1.05em;
	background: currentColor;
	-webkit-mask: var(--aqg-i-phone) center / contain no-repeat;
	mask: var(--aqg-i-phone) center / contain no-repeat;
}

/* Icône quelconque dans un bouton du cœur : même géométrie que le bouton
   téléphone ci-dessus, mais la forme vient de la classe `.i-*` posée sur le
   conteneur `.wp-block-button`, que le lien reçoit par héritage de
   `--aqg-icon` (`aqg-btn-outline aqg-btn-ic i-mail`, par exemple). Le bouton
   téléphone garde sa propre règle, figée sur `--aqg-i-phone`, pour ne rien
   déplacer sur les pages qui l'emploient. Le pictogramme est un pseudo-élément
   sans texte, donc sans nom accessible : le libellé du bouton suffit. Il est
   repeint en `CanvasText` par le bloc `forced-colors` de fin de fichier. */
.aqg-btn-ic .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .5em;
}

.aqg-btn-ic .wp-block-button__link::before {
	content: "";
	flex: none;
	width: 1.05em;
	height: 1.05em;
	background: currentColor;
	-webkit-mask: var(--aqg-icon, none) center / contain no-repeat;
	mask: var(--aqg-icon, none) center / contain no-repeat;
}

/* ==========================================================================
   Cartes — hauteur égale par rangée.
   WordPress applique `margin-block-start` aux enfants des groupes en flux
   (`is-layout-flow`) ; posé sur des items de grille CSS, ce décalage
   désaligne les cartes. On neutralise : l'espacement vient du `gap`, jamais
   des marges.
   ========================================================================== */
.aqg-services-grid > *,
.aqg-avis > *,
.aqg-steps > *,
.aqg-aides__grid > *,
.aqg-realis > * {
	margin-block: 0;
}

/* ==========================================================================
   Animations — révélation au scroll + micro-interactions.
   Gated sur `.aqg-reveal` (posée par JS) : sans JS, rien n'est masqué.
   Coupé net si l'utilisateur préfère moins d'animations.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
	/* Uniform, ordered fade-in: every element rises the same way as it enters
	   the viewport (no per-index stagger — see interactions.js). */
	.js .aqg-reveal {
		opacity: 0;
		transform: translateY(14px);
		transition: opacity .5s ease, transform .5s cubic-bezier(.2, .7, .2, 1);
		will-change: opacity, transform;
	}

	.js .aqg-reveal.is-visible {
		opacity: 1;
		transform: none;
		will-change: auto;
	}
}

/* --------------------------------------------------------------------------
   Intro au chargement — header + hero.

   Le scroll-reveal ne couvre que ce qui ENTRE dans le viewport : le header et
   le hero, déjà à l'écran au premier rendu, restaient donc figés pendant que
   tout le reste s'animait. Ils entrent ici en cascade.

   100 % CSS, aucun JS : l'animation démarre seule, donc aucun élément ne peut
   rester invisible si un script échoue — contrairement à `.aqg-reveal`, qui
   dépend de JS. Gaté sur `.js` (posé en wp_head avant peinture) : rien ne
   s'anime dans l'éditeur de blocs, et rien n'est masqué sans JS.

   `fill-mode: backwards` et NON `both` : `backwards` applique l'état masqué
   pendant le délai (donc aucun flash au chargement) mais ne laisse RIEN une
   fois l'animation finie. Avec `both`, l'élément conserverait à vie un
   `transform: matrix(1,0,0,1,0,0)` — pas `none` — qui (1) resterait un bloc
   conteneur pour tout descendant `position:fixed`, (2) garderait une couche
   GPU inutile et (3) écraserait les `:hover` en transform, une animation
   primant sur les déclarations normales dans la cascade. C'est le même
   écueil que celui documenté dans interactions.js pour `.aqg-reveal`.
   -------------------------------------------------------------------------- */
@keyframes aqg-intro-rise {
	from { opacity: 0; transform: translateY(16px); }
	to { opacity: 1; transform: none; }
}

@keyframes aqg-intro-drop {
	from { opacity: 0; transform: translateY(-14px); }
	to { opacity: 1; transform: none; }
}

@keyframes aqg-intro-fade {
	from { opacity: 0; }
	to { opacity: 1; }
}

/* Les candidats au LCP n'entrent JAMAIS par l'opacité, ni avec un délai.

   Sous Chrome, un élément animé en opacité depuis 0 n'est rapporté au LCP
   qu'à la FIN de son fondu. Le H1, l'accroche et le média du héro, et la
   pastille de l'accueil qui les coiffe, sont donc peints dès le premier rendu
   et n'entrent que par ce glissement, en transform seul. Le reste de la
   cascade garde son fondu : aucun de ses éléments n'est candidat.

   Ne pas « harmoniser » en rendant un fondu ou un animation-delay aux éléments
   qui portent aqg-intro-lift : c'est le retard que ce glissement supprime.
   Mesures, chiffres et effet sur le CLS : règles de code du dépôt, standards
   de code, puce « Intro au chargement ». */
@keyframes aqg-intro-lift {
	from { transform: translateY(12px); }
	to { transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
	.js .aqg-navpill,
	.js .aqg-hero__cta,
	.js .aqg-hero__reassure,
	.js .aqg-trust,
	.js .aqg-hero__urgence {
		animation: aqg-intro-rise .62s cubic-bezier(.2, .7, .2, 1) backwards;
	}

	/* PIÈGE — sous 900px, le header ne reçoit QUE de l'opacité. Un transform
	   sur la pilule (ou sur un de ses ancêtres) deviendrait le bloc conteneur
	   de la feuille `position:fixed` du menu mobile et l'enfermerait dans la
	   pilule : exactement le piège documenté plus haut pour backdrop-filter. */
	.js .aqg-navpill {
		animation-name: aqg-intro-fade;
	}

	/* Candidats au LCP : glissement seul, SANS délai (cf. aqg-intro-lift).
	   Aucun animation-delay ne doit les viser. La pastille qui coiffait le H1 a
	   été retirée du héro le 2026-09-26 : le H1 en est le premier élément. */
	.js .aqg-hero__main > h1,
	.js .aqg-hero__lead,
	.js .aqg-hero__media {
		animation: aqg-intro-lift .62s cubic-bezier(.2, .7, .2, 1) backwards;
	}

	/* Cascade en fondu : l'en-tête d'abord, puis la suite du héro dans l'ordre
	   de lecture. Le H1, l'accroche et le média n'y figurent plus : ils sont
	   déjà à l'écran au premier rendu. */
	.js .aqg-hero__cta { animation-delay: .28s; }
	.js .aqg-hero__reassure { animation-delay: .34s; }
	.js .aqg-trust { animation-delay: .38s; }
	.js .aqg-hero__urgence { animation-delay: .42s; }
}

/* Règle 2/3 du point de bascule unique (900px) : à partir de 901px la feuille
   mobile n'existe plus, la pilule peut donc descendre en transform. */
@media (prefers-reduced-motion: no-preference) and (min-width: 901px) {
	.js .aqg-navpill {
		animation-name: aqg-intro-drop;
	}
}

/* Buttons & interactive cards get a touch of spring.

   `box-shadow` est volontairement HORS de cette liste depuis que l'anneau de
   focus bi-ton s'en sert : mesuré, la bande sombre de l'anneau reste entièrement
   cachée sous la bande blanche tant que le `spread` n'a pas atteint 4px, soit
   pendant environ 135 des 200 ms de la transition. Le contour extérieur de
   l'indicateur y est du blanc pur, à 1,00:1 sur une carte blanche. Et en
   tabulation maintenue, Chrome enchaîne les focus toutes les 33 ms : l'anneau
   n'atteindrait jamais 22 % d'opacité. Un indicateur d'accessibilité s'affiche,
   il ne s'installe pas. */
.wp-block-button__link {
	transition: background-color .2s ease, transform .12s ease;
}

.wp-block-button__link:hover { transform: translateY(-1px); }
.wp-block-button__link:active { transform: translateY(0); }

.aqg-chip { transition: transform .15s ease, background-color .15s ease, color .15s ease; }

.aqg-chip:hover {
	transform: translateY(-2px);
	/* L'aplat de survol reprend --aqg-chip-ink. Motif d'origine levé depuis
	   l'assombrissement de la palette : le blanc sur `--primary` valait 3,45:1
	   quand il était #0092D6, il vaut 11,04:1 sur #14387F, dont `--aqg-chip-ink`
	   n'est plus qu'un alias (cf. son commentaire en tête). */
	background: var(--aqg-chip-ink);
	color: #fff;
}

/* Navbar shadow deepens once the page is scrolled. */
.aqg-navpill.is-scrolled {
	box-shadow: 0 20px 46px -24px rgba(13, 34, 51, .5);
	background: rgba(251, 247, 241, .94);
}

/* Anchor links must clear the sticky navbar. */
html { scroll-behavior: smooth; }

:where(#top, #services, #aides, #processus, #realisations, #avis, #contact, #faq, #zone) {
	scroll-margin-top: 100px;
}

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
}

/* ==========================================================================
   Formulaire de contact — fonctionnel (handler dans le plugin aquagones-core).
   ========================================================================== */
.aqg-form__feedback {
	margin: 0 0 18px;
	padding: 13px 16px;
	border-radius: 12px;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.4;
}

.aqg-form__feedback--ok {
	background: var(--wp--preset--color--aide-surface);
	color: #14663f;
	border: 1px solid #CFE9D4;
}

.aqg-form__feedback--err {
	background: #FDECEC;
	color: #B42318;
	border: 1px solid #F6C9C6;
}

/* Quota d'envoi atteint : ni un succès, ni une erreur du visiteur. Ambre, pour
   qu'il ne se lise ni comme une confirmation ni comme un champ à corriger. */
.aqg-form__feedback--warn {
	background: #FEF6E7;
	color: #8A5A00;
	border: 1px solid #F3DFB4;
}

.aqg-form__field .aqg-req { color: var(--wp--preset--color--accent); }

.aqg-form__field input,
.aqg-form__field select,
.aqg-form__field textarea {
	transition: box-shadow .16s ease, background-color .16s ease;
}

.aqg-form__field input:focus,
.aqg-form__field select:focus,
.aqg-form__field textarea:focus {
	outline: none;
	background: #fff;
	box-shadow: 0 0 0 2px var(--wp--preset--color--primary);
}

/* La classe `was-validated` est posée par `interactions.js`, sur l'événement
   `invalid` capté en phase de CAPTURE. Ce n'est pas un détail d'implémentation :
   sur le chemin ordinaire, la validation interactive du navigateur bloque le
   clic AVANT que `submit` ne parte, si bien qu'une pose de classe faite dans le
   gestionnaire de soumission ne s'exécuterait jamais et cette règle ne
   s'allumerait pas. C'était le cas jusqu'au 2026-08-30, et le seul retour était
   la bulle native, transitoire et absente de Safari iOS.

   Aucune classe `is-invalid` ici : elle a existé dans ces sélecteurs sans
   qu'aucun script ne la pose jamais. Une règle que rien ne déclenche fait
   croire à une couverture qui n'existe pas. */
.aqg-form.was-validated .aqg-form__field input:invalid,
.aqg-form.was-validated .aqg-form__field select:invalid,
.aqg-form.was-validated .aqg-form__field textarea:invalid {
	box-shadow: 0 0 0 2px #E5484D;
}

.aqg-form__submit {
	width: 100%;
	border: none;
	cursor: pointer;
	font-family: inherit;
}

/* ÉTAT D'ATTENTE DU BOUTON D'ENVOI, pendant la soumission en place.

   Le script ne pose plus `disabled` mais `aria-disabled="true"`. `disabled`
   sortait le bouton de l'ordre de tabulation au moment même où il portait le
   focus : `document.activeElement` retombait sur `<body>`, l'utilisateur au
   clavier perdait sa position et n'avait plus rien à écouter pendant
   l'aller-retour. Le sélecteur suit donc l'attribut, et garde `:disabled` :
   rien n'interdit de désactiver ce bouton autrement un jour, et les deux
   états doivent se ressembler.

   L'`opacity: .7` qui portait cet état est SUPPRIMÉE, et ce n'est pas un choix
   esthétique. L'opacité compose le bouton entier avec le panneau blanc qui est
   derrière : avec l'ancien bleu #006FA3, rendu à #4C9ABF, le libellé blanc
   tombait à 3,13:1, sous les 4,5:1 dus à un texte de 16px (16px n'est pas du
   grand texte au sens WCAG, qui commence à 18,66px en graisse 700).
   `opacity: .85` ne rattrape rien, mesuré à 4,16:1. Le défaut était invisible
   pour `npm run a11y:contraste`, qui n'observe jamais cet état : il ne dure
   que le temps d'un envoi.

   L'attente se dit donc par l'aplat foncé, celui du survol, et par le curseur.
   Le signal qui porte vraiment reste le libellé, qui passe à « Envoi… ». */
.aqg-form__submit:disabled,
.aqg-form__submit[aria-disabled="true"] {
	background: var(--wp--preset--color--primary-dark);
	cursor: progress;
}

/* Honeypot — hidden from humans, catches bots. */
.aqg-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* ==========================================================================
   Formulaire — soumission en place.

   Le script poste le formulaire en arrière-plan, puis remplace les champs par
   un panneau de confirmation. Trois surfaces nouvelles à peindre : l'enveloppe
   des champs, le panneau et son bouton de retour. Le message des quatre
   drapeaux, lui, existait déjà mais change de POSITION.
   ========================================================================== */

/* L'ENVELOPPE DES CHAMPS NE PORTE AUCUNE DÉCLARATION `display`, ET C'EST MESURÉ.

   `.aqg-form` dispose ses enfants en flux de blocs : `display: block`,
   `gap: normal`, aucune grille, aucun flex, chaque champ portant sa propre
   `margin-bottom`. Un `<div>` nu posé autour d'eux y est donc rigoureusement
   transparent. Vérifié en exécution sur l'accueil : les huit boîtes du
   formulaire gardent le même `top` et la même hauteur au pixel près, et le
   formulaire mesure 697px avant comme après l'insertion de l'enveloppe.

   D'OÙ LE REFUS DE `display: contents`, qui est pourtant le réflexe. Il n'a
   rien à corriger ici, et il arme un piège : une règle de classe bat la feuille
   du navigateur, donc `[hidden]` cesse de masquer quoi que ce soit. Mesuré sur
   la même page : avec `.aqg-form__fields { display: contents }` et l'attribut
   `hidden` posé, le `display` calculé reste `contents` et la légende de
   l'astérisque mesure toujours 20,8px de haut. Les champs que l'on croit cachés
   restent alors à l'écran, sous le panneau de confirmation, avec les valeurs
   que `form.reset()` vient d'effacer.

   La règle ci-dessous est posée D'AVANCE, exactement comme `.aqg-form__legend a`
   plus haut : elle ne sert à rien tant que l'enveloppe reste un bloc nu, et elle
   rattrape le jour où quelqu'un lui donnera un `display` — par exemple si
   `.aqg-form` passait en flex et que l'enveloppe devait s'effacer du flux.
   Mesuré : avec cette règle, `hidden` rend bien `display: none` et la légende
   retombe à 0px de haut. */
.aqg-form__fields[hidden] {
	display: none;
}

/* MOITIÉ CSS DU MÊME FILET. Le `<template>` du panneau de confirmation n'est
   masqué que par la feuille du navigateur. Sur un moteur sans
   `HTMLTemplateElement` (et la règle « ES5 prudent » du projet dit que ces
   moteurs sont dans le périmètre), son contenu est analysé comme du DOM
   ordinaire : les quatre paragraphes du panneau et un bouton « Envoyer une
   autre demande » SANS gestionnaire s'afficheraient en permanence sous les
   champs. Le script garde déjà ce cas (`showDone()` renonce si
   `doneTpl.content` manque) ; voici l'autre moitié. */
.aqg-form__done-tpl {
	display: none;
}

/* Le message des quatre drapeaux vit désormais à DEUX endroits, et il lui faut
   deux rythmes. Rendu par le serveur (repli sans JavaScript, sur une URL
   `?devis=`), il ouvre le formulaire et sa marge est en dessous : c'est celle
   qui est écrite plus haut. Inséré par le script, il se pose JUSTE APRÈS le
   bouton d'envoi, là où le regard vient de cliquer, et il lui faut sa marge
   au-dessus. Sans cette règle il se collerait au bouton.

   POURQUOI CETTE POSITION, ET C'EST MESURÉ. Posé en tête de formulaire, le
   message tombait hors écran. Protocole : `/?devis=err` en 1280x800, le bouton
   d'envoi centré dans la fenêtre, comme il l'est pour qui vient de cliquer
   dessus, les trois rectangles lus dans la même passe de mise en page. Le
   bouton est à `top` 373 `bottom` 427, donc bien en vue ; le message en tête de
   formulaire est à `top` -182 `bottom` -75, donc entièrement au-dessus de la
   fenêtre ; le même message posé après le bouton est à `top` 441 `bottom` 548,
   à 14px du bouton. Le formulaire mesurant 942px pour une fenêtre de 800, les
   deux extrémités ne peuvent tout simplement pas être vues ensemble.

   ⚠️ Mesurer cela demande deux précautions, toutes deux payées ici. Insérer le
   message APRÈS avoir lu la position du bouton donne un faux chiffre :
   l'ancrage de défilement de Chrome déplace la page entre les deux lectures, et
   le message ressort à `top` 381, au-dessus du bas du bouton, ce qui est
   géométriquement impossible. Et `html { scroll-behavior: smooth }` est global
   dans cette feuille : un `scrollIntoView` lu dans la foulée mesure une
   position de transit, pas la position finale. */
.aqg-form__submit + .aqg-form__feedback,
.aqg-form__fields .aqg-form__feedback {
	margin: 14px 0 0;
}

/* ANNEAU DE FOCUS DES DEUX BLOCS QUE LE SCRIPT FOCALISE.

   Le message de retour et le panneau de confirmation portent `tabindex="-1"` et
   reçoivent le focus par script, pour être annoncés et pour donner au clavier
   sa nouvelle position. Sans règle, l'indicateur est celui de Chrome par
   défaut. Relevé sur `/?devis=err` : `outline: auto 1px rgb(168,199,250)`,
   décalage nul, soit 1,51:1 contre l'aplat du message et 1,72:1 contre le
   panneau blanc. Les deux sont sous les 3:1 de la SC 1.4.11. Avec la règle
   ci-dessous, la bande sombre remonte à 16,23:1, mesuré au même endroit.

   ⚠️ CE DÉFAUT ÉTAIT HORS DE PORTÉE DE L'OUTIL POUR DEUX RAISONS INDÉPENDANTES,
   et les deux tiennent encore : `tabindex="-1"` exclut ces blocs de la liste
   des focalisables d'`audit-contraste.mjs`, ET cet outil ignore délibérément
   tout anneau de style `auto`, celui que le navigateur dessine lui-même, pour
   ne pas produire de faux échec. Le corriger ne le rend donc pas surveillé.

   Anneau bi-ton du thème, identique à celui des boutons : voir son commentaire.
   Ici la géométrie est connue et fixe. Les deux blocs sont des enfants du
   panneau blanc du formulaire, qui est plus large qu'eux de ses 34px de padding
   (20px sous 700px) : avec `outline-offset: 2px`, l'anneau se peint donc sur ce
   blanc, jamais sur l'aplat du bloc lui-même. `ink-deep` y donne 16,23:1, et
   14,6:1 contre l'aplat vert si le calcul du support venait à changer. Le
   bi-ton est gardé par cohérence, et parce qu'il ne coûte rien.

   ⚠️ Ces deux blocs n'ont AUCUNE `box-shadow` au repos : la bande sombre peut
   donc s'écrire seule. Si l'un d'eux reçoit un jour une ombre portée, il
   faudra la REJOUER dans la déclaration de l'anneau, deux `box-shadow` de deux
   règles ne s'additionnant pas.

   LA DÉCLARATION, ELLE, N'EST PAS ICI. Elle a d'abord été écrite à cet
   endroit, mot pour mot identique à celle des boutons : la mesure ci-dessus
   reste ici, à côté du composant qu'elle décrit, mais les deux sélecteurs ont
   rejoint la règle unique de l'anneau, plus haut dans ce fichier (chercher
   « UNE SEULE RÈGLE, TOUS LES PORTEURS »). */

/* Panneau de confirmation. Il prend la place des champs après un envoi abouti,
   à l'intérieur du panneau blanc du formulaire. Il reprend la langue visuelle
   du message de succès (`--feedback--ok`) : même aplat vert, même famille de
   bordure. Les deux disent la même chose au visiteur, ils doivent se
   ressembler. La bordure passe par `--aqg-border-aide`, le jeton du thème pour
   ce vert, plutôt que par un hexadécimal de plus. */
.aqg-form__done {
	margin: 0;
	padding: 24px 22px;
	border: 1px solid var(--aqg-border-aide);
	border-radius: 16px;
	background: var(--wp--preset--color--aide-surface);
}

/* PAS DE FILET SUR L'ORDRE INVERSE, et c'est délibéré. Une règle
   `.aqg-form__hint + .aqg-form__done` a existé ici « au cas où l'ordre
   changerait » : elle ne pouvait jamais s'appliquer (le script insère le
   panneau par `insertBefore( panel, fields.nextSibling )`, son frère précédent
   est donc toujours l'enveloppe des champs, jamais la mention RGPD, qui est le
   dernier enfant du formulaire) et surtout elle documentait un ordre que le
   contrat INTERDIT : la mention d'information doit rester sous le panneau,
   c'est le point de collecte. Retirée pour qu'aucune relecture ne la lise
   comme un cas prévu et supporté. */

/* 20px en graisse 700 : c'est du grand texte au sens WCAG (seuil 3:1). L'encre
   `contrast` y donne 15,66:1 sur l'aplat vert, très au-delà. */
.aqg-form__done-title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 20px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--wp--preset--color--contrast);

	/* ⚠️ SANS CETTE DÉCLARATION, UN NOM SANS ESPACE FAIT DÉBORDER LA PAGE
	   ENTIÈRE. Le titre reprend ce que le visiteur a tapé dans le champ « Nom »,
	   et le garde-fou du script (`trim40`) borne le NOMBRE de caractères, jamais
	   leur capacité à se couper. Le cas courant n'est même pas hostile : c'est le
	   visiteur qui colle son adresse e-mail dans le champ « Nom ». Mesuré en
	   390x844, page rechargée sous émulation : avec 20 caractères insécables,
	   `documentElement.scrollWidth` passe à 407 pour un `clientWidth` de 390 ;
	   à 30 caractères 549 ; à 40 caractères 691, le formulaire passant de 322 à
	   512px. Ce n'est pas le panneau qui déborde, c'est le DOCUMENT : la mention
	   RGPD et le bouton de retour sortent du cadre, au moment exact de la
	   conversion. Contre-épreuve : les mêmes longueurs AVEC des espaces ne
	   débordent pas d'un pixel, la cause est bien l'insécabilité.
	   `anywhere` et non `break-word` : `break-word` ne compte pas dans le calcul
	   de la largeur intrinsèque minimale, il ne rétracte donc pas un conteneur
	   déjà élargi par le mot. */
	overflow-wrap: anywhere;
}

/* Le besoin repris de ce que le visiteur vient de choisir. AUCUNE déclaration
   `display` ici, et c'est délibéré : la ligne est rendue masquée par
   l'attribut `hidden` quand aucun besoin n'a été choisi, et un `display` de
   classe la ferait réapparaître, vide, comme démontré plus haut sur
   l'enveloppe. Encre `aide`, 5,62:1 sur l'aplat vert. */
.aqg-form__done-besoin {
	margin: 12px 0 0;
	font-size: 14px;
	font-weight: 700;
	color: var(--wp--preset--color--aide);

	/* Par prudence, la même garde qu'au titre : ce libellé vient de la liste des
	   objets du plugin, aujourd'hui court, mais rien ne borne sa longueur. */
	overflow-wrap: anywhere;
}

.aqg-form__done-next {
	margin: 12px 0 0;
	font-size: 15px;
	line-height: 1.55;
	color: var(--wp--preset--color--contrast);
}

.aqg-form__done-tel {
	margin: 8px 0 0;
	font-size: 14px;
	line-height: 1.55;
	color: var(--aqg-muted);
}

/* PIÈGE DU THÈME, troisième occurrence, et cette fois il ne se referme pas.
   `theme.json` peint tout lien en `primary` depuis une règle de spécificité
   nulle et ce thème n'a aucun reset sur `a` : sans cette règle, le numéro de
   téléphone sortirait en `primary` sur l'aplat vert du panneau. Avec l'ancien
   bleu #006FA3, c'était 4,97:1, de justesse ; avec #14387F c'est 9,93:1.

   L'ancienne encre des pilules (#0077B0) y tombait à 4,43:1, SOUS le seuil de
   4,5:1 : c'était le premier fond du thème où elle échouait, l'aplat vert étant
   plus clair que le crème et que le blanc. La règle reste, pour figer la
   couleur : `primary-dark` donne 12,46:1.

   ⚠️ LA COULEUR NE SUFFIT PAS : L'INDICATEUR DE FOCUS EST L'AUTRE MOITIÉ. Ce
   lien est le PREMIER arrêt de tabulation de l'état de confirmation, et il
   gardait l'anneau par défaut de Chrome, mesuré `outline: auto 1px
   rgb(168,199,250)` sur l'aplat vert du panneau, soit 1,55:1 : le chiffre même
   au nom duquel l'anneau du message et celui du panneau ont été corrigés, à
   deux blocs de là. Le sélecteur `.aqg-form__done-tel a:focus-visible` a donc
   rejoint la règle unique de l'anneau, plus haut, et le bloc `forced-colors`
   de la fin de fichier. L'anneau se peint sur le `<p>` porteur, plus large que
   le lien, donc sur l'aplat vert : `ink-deep` y donne 14,6:1. Le numéro se
   coupe en fin de ligne (à 320px de large, par exemple) : c'est le
   `box-decoration-break: clone` de la règle unique qui ferme alors l'anneau
   de chacun des deux morceaux.

   (Les liens d'en-tête du site rendent le même anneau par défaut : c'est une
   dette site-wide antérieure à ce lot, hors périmètre ici. Ce qui est corrigé,
   c'est la contradiction INTERNE au panneau.) */
.aqg-form__done-tel a {
	color: var(--wp--preset--color--primary-dark);
}

/* Retour au formulaire. Bouton secondaire, et c'est voulu : le geste attendu du
   panneau est d'être lu, pas d'être recliqué. Il reprend la pilule du site
   (rayon 100px, bordure 1,5px) plutôt que l'aplat plein du bouton d'envoi, qui
   se lirait comme un second envoi à faire.
   Contrastes : bordure `primary` 5,52:1 sur son propre fond blanc et 4,97:1 sur
   l'aplat vert du panneau, au-delà des 3:1 dus à la limite d'une commande ;
   libellé `primary-dark` 8,22:1 sur le blanc. */
.aqg-form__again {
	/* `inline-flex` et `min-height` plutôt qu'un simple `inline-block` : le
	   calibrage naturel donnait 43px de haut, mesuré, un pixel sous la cible
	   tactile de 44px que tient le reste du site (voir
	   `.aqg-voiraussi .aqg-chip a`). */
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	margin: 18px 0 0;
	padding: 11px 20px;
	border: 1.5px solid var(--wp--preset--color--primary);
	border-radius: 100px;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary-dark);
	font-family: inherit;
	font-size: 14px;
	font-weight: 800;
	cursor: pointer;
}

/* Aplat de survol : `primary-dark`, le même que le bouton d'envoi, plutôt que
   `--aqg-chip-ink` des pilules. Le blanc y donne 8,22:1 contre 4,92:1 sur
   `chip-ink`, et un libellé de 14px en graisse 800 n'est pas du grand texte :
   il lui faut ses 4,5:1 pleins, pas 0,42 point de marge. */
.aqg-form__again:hover,
.aqg-form__again:focus-visible {
	border-color: var(--wp--preset--color--primary-dark);
	background: var(--wp--preset--color--primary-dark);
	color: #fff;
}

/* Anneau bi-ton du thème : le bouton de retour est un porteur de la règle
   unique, plus haut dans ce fichier (chercher « UNE SEULE RÈGLE, TOUS LES
   PORTEURS »), il n'a pas sa déclaration à lui. La mesure reste ici, à côté du
   composant : le bouton ne porte AUCUNE `box-shadow`, ni au repos ni au
   survol, la bande sombre s'écrit donc sans rien à rejouer ; et avec
   `outline-offset: 2px` l'anneau se peint sur le premier ancêtre PLUS GRAND
   que lui, ici l'aplat vert du panneau, où `ink-deep` donne 14,6:1. */

/* ==========================================================================
   Pages service (gabarit interne)

   Le contenu d'une fiche service est un pattern posé dans post_content : les
   sections sont enfants de `.aqg-page-flow` (le bloc post-content) et non de
   `.aqg-main` comme sur l'accueil. Tout le reste est repris tel quel de la
   page d'accueil — même rythme vertical, mêmes cartes arrondies posées sur le
   fond crème, mêmes composants (`.aqg-service-card`, `.aqg-steps`,
   `.aqg-aide-card`, `.aqg-realis-card`, `.aqg-faq`, `.aqg-chip`) : une seule
   source de vérité, et un site qui se lit comme un seul système.
   ========================================================================== */

/* RYTHME — strictement celui de l'accueil.
   Une section porte 72px de padding bas, et WordPress ajoute 24px de marge de
   flux entre frères : 96px au total. Cette marge NE DOIT PAS être neutralisée.
   (Sa règle cœur `:where(.is-layout-flow) > :where(:not(:first-child))` a une
   spécificité nulle : n'importe quelle règle de classe l'écrase. Un
   `.aqg-page-flow > * { margin-block: 0 }` suffisait donc à ramener l'écart à
   72px et à coller les sections les unes aux autres.) */
.aqg-page-flow > section {
	padding-block-end: 72px;
}

/* La barre d'appel est en position fixe : elle ne pèse pas dans le flux. */
.aqg-page-flow > .aqg-callbar {
	margin-block: 0;
}

/* Rythmes plus serrés : spécificité supérieure à `.aqg-page-flow > section`. */
.aqg-page-flow > section.aqg-phero {
	padding-block: 26px 0;
}

/* Même respiration que les bandeaux stats / certifications de l'accueil. */
.aqg-page-flow > section.aqg-reassure-wrap {
	padding-block-end: 46px;
}

/* ---------- Héro interne (bento marine, calqué sur celui de l'accueil) ---------- */
.aqg-phero__bento {
	display: grid;
	grid-template-columns: 1.35fr 1fr;
	grid-template-rows: 1fr auto;
	gap: 18px;
}

.aqg-phero__bento > * {
	margin-block: 0;
}

.aqg-phero__main {
	position: relative;
	overflow: hidden;
	grid-column: 1;
	grid-row: 1 / span 2;
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 52px 50px;
	border-radius: 28px;
	background: var(--wp--preset--color--ink-deep);
	color: #fff;
}

.aqg-phero__main > *:not(.aqg-phero__glow) {
	position: relative;
	z-index: 1;
}

.aqg-phero__glow {
	position: absolute;
	right: -80px;
	top: -80px;
	width: 320px;
	height: 320px;
	border-radius: 50%;
	background: radial-gradient(circle, var(--wp--preset--color--primary) 0%, transparent 66%);
	opacity: .5;
	pointer-events: none;
	z-index: 0;
}

.aqg-phero__main h1 {
	margin: 0 0 20px;
	color: #fff;
}

.aqg-phero__lead {
	max-width: 500px;
	margin: 0 0 28px;
	color: var(--aqg-marine-soft);
	font-weight: 500;
}

.aqg-phero__cta {
	gap: 13px;
	margin-bottom: 16px;
}

.aqg-phero__reassure {
	margin: 0 0 20px;
	color: var(--aqg-marine-faint);
	font-size: 13.5px;
	font-weight: 600;
}

/* Photo du service. `position:absolute` sur l'image (figure en relative +
   min-height) : sinon une photo portrait s'affiche à sa hauteur naturelle et
   étire toute la cellule, comme sur la carte gainable de l'accueil. */
.aqg-phero__media {
	position: relative;
	overflow: hidden;
	grid-column: 2;
	grid-row: 1;
	min-height: 260px;
	border-radius: 28px;
}

.aqg-phero__media-img {
	position: absolute;
	inset: 0;
	margin: 0;
	height: 100%;
}

.aqg-phero__media-img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.aqg-phero__chip {
	position: absolute;
	left: 18px;
	bottom: 16px;
	z-index: 1;
	margin: 0;
	padding: 8px 14px;
	border-radius: 100px;
	background: rgba(255, 255, 255, .92);
	color: var(--wp--preset--color--primary-dark);
	font-size: 12.5px;
	font-weight: 800;
}

/* Carte orange : entièrement cliquable via le lien étiré du titre. */
.aqg-phero__side {
	position: relative;
	overflow: hidden;
	grid-column: 2;
	grid-row: 2;
	height: 100%;
	padding: 26px 28px;
	border-radius: 28px;
	background: var(--wp--preset--color--accent);
	color: #fff;
}

.aqg-phero__side::after {
	content: "";
	position: absolute;
	right: -30px;
	bottom: -30px;
	width: 150px;
	height: 150px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .12);
	pointer-events: none;
}

.aqg-phero__side > * {
	position: relative;
	z-index: 1;
}

/* Voir `.aqg-hero__urgence-badge` : un voile blanc éclaircit son propre fond et
   échoue quel que soit l'orange. Retourné en noir. */
.aqg-phero__side-badge {
	display: inline-flex;
	align-items: center;
	width: fit-content;
	margin: 0 0 10px;
	padding: 6px 13px;
	border-radius: 100px;
	background: rgba(0, 0, 0, .22);
	font-size: 12px;
	font-weight: 800;
	letter-spacing: .03em;
	text-transform: uppercase;
}

.aqg-phero__side-title {
	margin: 0 0 6px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 23px;
	font-weight: 800;
	line-height: 1.1;
}

.aqg-phero__side-title a {
	color: inherit;
	text-decoration: none;
}

.aqg-phero__side-title a::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 28px;
}

.aqg-phero__side-text {
	margin: 0;
	/* Voir `.aqg-hero__urgence-text` : le crème ne tient sur aucun orange. */
	color: #fff;
	font-size: 14px;
	font-weight: 600;
}

/* ---------- Bandeau de réassurance ----------
   Carte arrondie posée sur le fond crème, comme le bandeau « certifications »
   de l'accueil : le site n'a aucune section pleine largeur, on n'en introduit
   pas ici.

   PIÈGE — ce bandeau se peint en BLANC, jamais en marine. Il suit
   immédiatement le héro, dont la carte est marine : peint en marine lui aussi,
   il se lisait comme un morceau du héro détaché par la marge de flux, et le
   bas d'écran donnait l'impression d'un héro qui déborde. En blanc bordé chaud,
   il rejoint la famille des bandeaux de confiance de l'accueil (`.aqg-certs`),
   dont il partage déjà le rayon et le gabarit. */
.aqg-reassure {
	gap: 12px 28px;
	margin-top: 18px;
	padding: 20px 34px;
	border-radius: 22px;
	background: #fff;
	border: 1px solid var(--aqg-border-warm-2);
	color: var(--wp--preset--color--contrast);
}

.aqg-reassure > * {
	margin: 0;
}

.aqg-reassure__item {
	margin: 0;
	font-size: 14.5px;
	font-weight: 700;
}

/* `.aqg-ic::before` teinte le masque via `background`, pas via `color`. */
.aqg-reassure__item::before {
	background: var(--wp--preset--color--primary);
}

/* ---------- Cartes de prestation (variantes sans photo) ---------- */
.aqg-service-card--plain,
.aqg-service-card--invite {
	gap: 14px;
	padding: 30px;
	border: 1px solid var(--aqg-border-warm);
	background: var(--wp--preset--color--base);
}

.aqg-service-card--invite {
	justify-content: center;
	border-color: #CDD9EE;
	background: var(--wp--preset--color--surface-blue);
}

.aqg-service-card--invite .aqg-service-card__text {
	color: #41586A;
}

.aqg-service-card__more {
	margin: auto 0 0;
	font-weight: 800;
	font-size: 14px;
}

/* Souligné posé sur la carte marine. Le `color: #fff` n'est PAS redondant :
   sans lui `theme.json` repeindrait ce lien en `primary`, sa règle
   `elements.link` étant de spécificité nulle mais bien appliquée. Ne pas le
   retirer en croyant nettoyer. */
.aqg-service-card__more a {
	display: inline-block;
	padding-bottom: 2px;
	/* Orange de marque conservé : sur le marine il vaut 5,22:1 contre 3,29:1
	   pour le jeton foncé. Les deux passent le seuil non textuel de 3, on garde
	   donc l'éclat, comme pour les coches. */
	border-bottom: 2px solid var(--aqg-accent-on-dark);
	color: #fff;
	text-decoration: none;
}

.aqg-btn-blue .wp-block-button__link {
	background: var(--wp--preset--color--primary);
	color: #fff;
}

.aqg-btn-blue .wp-block-button__link:hover,
.aqg-btn-blue .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--primary-dark);
	color: #fff;
}

/* ---------- Arguments numérotés ---------- */
.aqg-args {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 18px;
	margin-top: 34px;
}

.aqg-args > * {
	margin-block: 0;
}

.aqg-arg {
	position: relative;
	overflow: hidden;
	padding: 28px;
	border: 1px solid var(--aqg-border-warm);
	border-top: 3px solid var(--wp--preset--color--primary);
	border-radius: 22px;
	background: var(--wp--preset--color--base);
	transition: transform .2s ease, box-shadow .2s ease;
}

.aqg-arg:hover {
	transform: translateY(-5px);
	box-shadow: var(--aqg-shadow-card);
}

.aqg-arg--accent { border-top-color: var(--wp--preset--color--accent); }
.aqg-arg--green { border-top-color: var(--wp--preset--color--aide); }

/* Le grand chiffre est décoratif : hors du flux, sous le contenu. */
.aqg-arg__num {
	position: absolute;
	right: 16px;
	top: 4px;
	z-index: 0;
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 62px;
	font-weight: 800;
	line-height: 1;
	color: #F0F5F8;
	pointer-events: none;
}

.aqg-arg--accent .aqg-arg__num { color: #FBF1E8; }
.aqg-arg--green .aqg-arg__num { color: #EEF6F0; }

.aqg-arg > *:not(.aqg-arg__num) {
	position: relative;
	z-index: 1;
}

.aqg-arg .aqg-ico {
	width: 50px;
	height: 50px;
	min-width: 50px;
	margin-bottom: 14px;
}

.aqg-arg__title {
	margin: 0 0 8px;
	font-size: 18px;
	line-height: 1.2;
}

/* `:not(.aqg-ico)` : l'icône est elle aussi un <p>. Sans cette exclusion, ce
   `margin: 0` écrase le `margin-bottom: 14px` posé plus haut sur `.aqg-arg
   .aqg-ico` (il est plus spécifique, 0-2-1 contre 0-2-0, et vient après), et
   le titre vient coller l'icône : écart mesuré à 0px. Même piège que
   `.aqg-step p:not(.aqg-step__dot)`, qui l'avait neutralisé ; `.aqg-arg` avait
   été oublié. */
.aqg-arg p:not(.aqg-arg__num):not(.aqg-ico) {
	margin: 0;
	color: var(--aqg-muted);
	font-size: 14px;
	line-height: 1.55;
}

/* ---------- Pour qui (carte, calquée sur .aqg-processus__card) ---------- */
.aqg-pourqui {
	padding: 52px 44px;
	border-radius: 32px;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--aqg-border-warm);
}

.aqg-section-head--left {
	margin-bottom: 30px;
	text-align: left;
}

.aqg-pourqui__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 18px;
}

.aqg-pourqui__grid > * {
	margin-block: 0;
}

.aqg-pourqui__card {
	padding: 32px;
	border: 1px solid var(--aqg-border-warm);
	border-radius: 24px;
	background: var(--wp--preset--color--base);
}

.aqg-pourqui__card .aqg-ico {
	margin-bottom: 16px;
}

.aqg-pourqui__title {
	margin: 0 0 10px;
	font-size: 22px;
}

.aqg-pourqui__card p {
	margin: 0;
	color: var(--aqg-muted);
	font-size: 15px;
	line-height: 1.65;
}

/* ---------- Budget (carte verte, calquée sur .aqg-aides) ---------- */
.aqg-budget {
	padding: 52px 50px;
	border-radius: 32px;
	background: var(--wp--preset--color--aide-surface);
	border: 2px solid #CFE9D4;
}

.aqg-budget__head {
	max-width: 780px;
	margin-bottom: 32px;
}

.aqg-budget__head h2 {
	margin: 0 0 14px;
	color: var(--wp--preset--color--ink-deep);
}

.aqg-budget__lead {
	margin: 0;
	color: #3C5A48;
}

.aqg-budget__foot {
	gap: 20px;
	margin-top: 26px;
}

.aqg-budget__legal {
	/* Note plus longue que celle de l'accueil : pleine largeur sous le bouton
	   plutôt qu'en colonne étroite à côté, où elle devenait illisible. */
	flex: 1 1 100%;
	margin: 0;
	color: #4A6654;
	line-height: 1.6;
	max-width: 900px;
}

.aqg-budget__legal a {
	color: var(--wp--preset--color--aide);
	font-weight: 700;
}

/* ---------- Réalisations : grille régulière (pages service) ----------
   La mosaïque de l'accueil déclare deux pistes de 220px pour ses cartes
   `--tall`/`--wide`. Ici les trois cartes tiennent sur une ligne : sans remise
   à zéro, la seconde piste vide ajoutait 220px de blanc avant la FAQ. */
.aqg-realis--even {
	grid-template-columns: repeat(3, 1fr);
	grid-template-rows: auto;
	grid-auto-rows: auto;
}

/* Hauteur DÉFINIE et non `min-height` : la figure et l'image héritées portent
   `height: 100%`, qui ne se résout que contre une hauteur définie. Avec un
   simple `min-height`, elles retombaient sur la hauteur naturelle de la photo
   (562px), l'`object-fit: cover` se calculait sur cette boîte-là et la carte
   n'en montrait que le haut, souvent hors sujet. */
.aqg-realis--even .aqg-realis-card {
	grid-column: auto;
	grid-row: auto;
	height: 260px;
}

/* Bandeau à DEUX photos (`--duo`, /ventilation-vmc/ depuis le 2026-10-03) :
   deux colonnes au bureau, sans case vide, et des cartes plus hautes pour
   garder le ratio 3:2 des photos (environ 571×380 à 1440px). Sous 961px, les
   règles de `--even` reprennent la main : deux colonnes, puis une sous 601px,
   en 260px de haut. */
@media (min-width: 961px) {
	.aqg-realis--duo {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.aqg-realis--duo .aqg-realis-card {
		height: 380px;
	}
}

/* Bloc « Focus gainable » de l'accueil : les grilles de soufflage de
   `gainable-grilles-plafond-escalier.jpg` sont dans le haut de l'image. Sur
   les fenêtres en bandeau (tablette, mobile), une bande centrée coupait la
   grande grille ; ancrée en haut, elle la garde. */
.aqg-feature__media--crop-top img {
	object-position: center top;
}

/* Recadrage haut, pour un sujet en tête d'image. Au 2026-10-03, seule la
   carte « Adoucisseur d'eau » de l'accueil le porte ; les photos de chantier
   sont recadrées hors du dépôt au ratio de leur fenêtre et n'en ont pas
   besoin (les variantes `--crop-top` et `--crop-bottom` des cartes de
   réalisation et du héro des fiches, sans usage, ont été retirées). */
.aqg-service-card--crop-top .aqg-service-card__img img {
	object-position: center top;
}

/* ---------- Maillage interne ---------- */
.aqg-voiraussi {
	padding: 32px 34px;
	border: 1px solid var(--aqg-border-warm);
	border-radius: 24px;
	background: var(--wp--preset--color--base);
}

.aqg-voiraussi__title {
	margin: 0 0 18px;
	font-size: 22px;
}

/* Grille plutôt que flex libre. Le bloc porte HUIT pilules sur les sept pages
   depuis que le « Voir aussi » propose les six autres métiers, et le flex-wrap
   laissait deux défauts mesurés le 2026-08-21 : sur ordinateur une première
   ligne pleine à 98 % suivie d'un reste de deux pilules ; à 390px, les pilules
   mesurant de 106 à 250px pour un conteneur de 301px, AUCUNE paire ne tenait
   sur une ligne et les huit s'empilaient en escalier sur 420px de haut. Une
   grille auto-fit donne des lignes pleines aux largeurs de bureau. Sous 700px,
   la colonne unique de pilules pleine largeur montait trop haut (1304px pour
   les vingt communes à 390px) : retour au flex, chaque pilule à la largeur de
   son texte, alignées à gauche. Le minimum est à 260px parce que le plus long
   libellé du catalogue, « Chauffage et pompe à chaleur », demande 218px de
   texte plus 32px de rembourrage : en dessous il se replierait sur deux lignes
   et étirerait toute la rangée. Le min() évite le débordement si le conteneur
   descend un jour sous ce minimum. */
.aqg-voiraussi__links {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
	gap: 12px;
}

.aqg-voiraussi__links > * {
	margin-block: 0;
}

@media (max-width: 699px) {
	.aqg-voiraussi__links {
		display: flex;
		flex-wrap: wrap;
		gap: 10px;
	}
}

/* La pilule est cliquable EN ENTIER. Le lien était un <a> inline posé dans un
   <p> qui portait le rembourrage : la surface cliquable mesurait 74×21 px sur
   une pilule de 106×42, soit 35 % de ce que le visiteur voit comme un bouton.
   Le rembourrage passe donc au lien, qui remplit la pilule. La hauteur minimale
   de 44px est la cible tactile recommandée. */
.aqg-voiraussi .aqg-chip {
	display: flex;
	padding: 0;
}

.aqg-voiraussi .aqg-chip a {
	display: flex;
	flex: 1;
	align-items: center;
	justify-content: center;
	/* box-sizing explicite : sans lui le min-height s'AJOUTE au rembourrage et la
	   pilule passe de 42 à 62px (44 + 9 + 9), mesuré le 2026-08-21. */
	box-sizing: border-box;
	min-height: 44px;
	padding: 9px 16px;
	border-radius: inherit;
	color: inherit;
	text-align: center;
	text-decoration: none;
	/* Annule le white-space: nowrap posé sur .aqg-chip sous 600px : en colonne
	   unique, un libellé long doit pouvoir se replier plutôt que déborder. */
	white-space: normal;
}

/* Le lien remplissant la pilule, l'anneau de focus doit en épouser la forme :
   sans cette règle il ne cerclait que le texte. */
.aqg-voiraussi .aqg-chip a:focus-visible {
	/* Anneau bi-ton, identique à celui des boutons : voir son commentaire.
	   Une couleur unique est intenable ici, ces pilules et ces liens vivant
	   tantôt sur du clair, tantôt sur du marine. */
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
}

/* Pilule du métier de la page en cours. Elle est PRÉSENTE pour que le bloc soit
   rigoureusement identique d'une page à l'autre et que le visiteur se situe dans
   le catalogue, mais elle ne porte pas de lien. Son traitement est volontairement
   différent du survol des autres pilules, qui passent en aplat bleu : un contour
   plein sur fond blanc se lit « vous êtes ici », un aplat se lirait « cliquable ».
   Le contour est en box-shadow interne et non en border, pour ne pas changer la
   taille de la boîte au milieu d'une grille à colonnes égales. */
.aqg-voiraussi .aqg-chip--current {
	display: flex;
	box-sizing: border-box;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 9px 16px;
	background: var(--wp--preset--color--base);
	box-shadow: inset 0 0 0 2px var(--aqg-chip-ink);
	color: var(--aqg-chip-ink);
	font-weight: 800;
	text-align: center;
	cursor: default;
	/* Même repli que les pilules-liens : le white-space: nowrap posé sur .aqg-chip
	   sous 600px s'appliquerait sinon ici aussi, et la pilule courante se
	   comporterait autrement que ses voisines. Mesuré à 320px avant correctif :
	   texte de 226px dans une boîte de 199px, rembourrage écrasé de 16 à 2,5px. */
	white-space: normal;
}

/* Elle ne bouge pas au survol : .aqg-chip:hover s'appliquerait sinon et
   laisserait croire à un bouton. */
.aqg-voiraussi .aqg-chip--current:hover {
	transform: none;
	background: var(--wp--preset--color--base);
	color: var(--aqg-chip-ink);
}

/* Masqué à l'œil, lu par les lecteurs d'écran : c'est ce qui porte « (page
   actuelle) » sur la pilule ci-dessus. Le thème n'avait pas d'utilitaire de ce
   genre, celui-ci est le premier. */
.aqg-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.aqg-chip--dark {
	background: var(--wp--preset--color--ink-deep);
	color: #fff;
}

.aqg-chip--dark:hover {
	background: var(--wp--preset--color--contrast);
	color: #fff;
}

/* ---------- Barre d'appel mobile ----------
   Repliée au-dessus de 960px : sur desktop le numéro est déjà dans la pilule
   d'en-tête et dans le héro. Aucun ancêtre en transform / backdrop-filter ne
   la surplombe, son `position:fixed` se rattache donc bien au viewport. */
.aqg-callbar {
	display: none;
}

/* Barre collée au bas de l'écran : l'anneau se dessine à l'intérieur. */
.aqg-callbar:focus-visible {
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: -6px;
	box-shadow: inset 0 0 0 4px var(--wp--preset--color--ink-deep), 0 -6px 20px rgba(0, 0, 0, .18);
}

/* ---------- Ancres de la page service ---------- */
:where(#prestations, #budget) {
	scroll-margin-top: 100px;
}

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
	.aqg-phero__bento {
		grid-template-columns: 1fr;
		grid-template-rows: auto;
	}

	.aqg-phero__main,
	.aqg-phero__media,
	.aqg-phero__side {
		grid-column: 1;
		grid-row: auto;
	}

	/* Empilée, la photo du bento repoussait le H1 et l'accroche sous la ligne
	   de flottaison sans rien apporter : sur mobile le titre et le texte
	   ouvrent la page, la carte orange suit. Le markup reste dans le pattern
	   (le client garde la main dessus dans l'éditeur), la photo réapparaît
	   telle quelle au-delà de 960px. */
	.aqg-phero__media {
		display: none;
	}

	.aqg-phero__main {
		padding: 36px 28px;
	}

	.aqg-args,
	.aqg-realis--even {
		grid-template-columns: 1fr 1fr;
	}

	.aqg-pourqui__grid {
		grid-template-columns: 1fr;
	}

	.aqg-pourqui,
	.aqg-budget {
		padding: 36px 26px;
	}

	.aqg-callbar {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 100;
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 16px;
		background: var(--wp--preset--color--accent);
		color: #fff;
		font-weight: 800;
		font-size: 17px;
		text-decoration: none;
		box-shadow: 0 -6px 20px rgba(0, 0, 0, .18);
	}

	/* Réserve la hauteur de la barre. Le rembourrage va sur le PIED DE PAGE et
	   non sur `body` : posé sur `body`, il laissait apparaître une bande de fond
	   crème entre la fin du pied de page sombre et la barre orange, une fois la
	   page défilée jusqu'en bas. */
	body:has(.aqg-callbar) .aqg-footer {
		padding-bottom: 66px;
	}
}

@media (max-width: 600px) {
	.aqg-reassure {
		padding: 18px 22px;
	}

	.aqg-args,
	.aqg-realis--even {
		grid-template-columns: 1fr;
	}

	.aqg-voiraussi {
		padding: 26px 22px;
	}

	.aqg-phero__main {
		padding: 30px 22px;
	}
}

/* ---------- Intro au chargement (même cascade que l'accueil) ----------
   `backwards` et jamais `both` : voir la note détaillée plus haut. */
@media (prefers-reduced-motion: no-preference) {
	.js .aqg-phero__cta,
	.js .aqg-phero__reassure,
	.js .aqg-phero__main .aqg-trust,
	.js .aqg-phero__side,
	.js .aqg-reassure {
		animation: aqg-intro-rise .62s cubic-bezier(.2, .7, .2, 1) backwards;
	}

	/* Candidats au LCP : glissement seul, SANS délai (cf. aqg-intro-lift, dans la
	   section de l'intro de l'accueil). Les trois sont traités ensemble parce que
	   l'élément retenu change selon la page et l'écran (relevé dans les règles
	   de code du dépôt, même puce). */
	.js .aqg-phero__main > h1,
	.js .aqg-phero__lead,
	.js .aqg-phero__media {
		animation: aqg-intro-lift .62s cubic-bezier(.2, .7, .2, 1) backwards;
	}

	/* Le badge du héro a été retiré des pages service (il répétait le H1, qui
	   nomme désormais la commune ET la zone), puis de l'accueil le 2026-09-26.
	   Le H1, l'accroche et le média étant peints dès le premier rendu, la
	   cascade en fondu démarre sur le CTA. */
	.js .aqg-phero__cta { animation-delay: .28s; }
	.js .aqg-phero__reassure { animation-delay: .34s; }
	.js .aqg-phero__main .aqg-trust { animation-delay: .38s; }
	.js .aqg-phero__side { animation-delay: .42s; }
	/* Le bandeau de réassurance ferme la cascade : sur un écran d'ordinateur il
	   est visible dès le premier rendu, il doit donc entrer avec le héro et non
	   rester figé pendant que tout le reste s'anime. C'est aussi pour cela que
	   ses items sont sortis du scroll-reveal de interactions.js : deux
	   propriétaires pour la même opacité finissaient par se contredire. */
	.js .aqg-reassure { animation-delay: .46s; }
}

/* ==========================================================================
   Pages villes (gabarit local)

   Trois surfaces nouvelles, et une seule règle de conduite : ne rien inventer
   qui existe déjà. Le héro, les boutons, les pilules, les cartes blanches et le
   rythme vertical sont ceux des sept pages service ; ce qui est ajouté ici est
   ce que le CPT ville rend et que rien ne stylait.

   Le bloc `aquagones/fiche-locale` émettait DIX-SEPT classes `aqg-fiche*` et
   n'en avait AUCUNE de définie : il rendait une liste à puces brute et des
   photos pleine largeur. Il est en place depuis le socle et n'a jamais été vu
   en ligne, faute de fiche ville publiée.
   ========================================================================== */

/* ---------- Héro plein (variante sans média) ----------
   Les pages service ouvrent sur un bento à trois cases dont une photo. Une page
   ville n'a pas de photo honnête à y mettre : aucune des images du site ne
   montre un chantier d'AquaGones, et une photo de banque dans le héro d'une
   page qui nomme une commune se lit comme une preuve locale. La carte marine
   prend donc toute la largeur, et le seul ajout est le découpage de la grille.

   `grid-row: 1` est explicite : `.aqg-phero__main` porte `1 / span 2` pour le
   bento à deux rangées, et ce span créerait ici une seconde rangée implicite,
   donc 18px de gouttière ajoutés à la hauteur de la carte. */
.aqg-phero--solo .aqg-phero__bento {
	grid-template-columns: 1fr;
	grid-template-rows: auto;
}

.aqg-phero--solo .aqg-phero__main {
	grid-column: 1;
	grid-row: 1;
}

/* Le héro d'une page ville est enfant de `.aqg-main` (il vient du template),
   là où celui d'une fiche service est enfant de `.aqg-page-flow` (il vient de
   post_content). La règle de rythme serré existait pour le second seulement :
   sans celle-ci, le héro ville hérite des 72px de `.aqg-main > section` et
   décolle du menu. */
.aqg-main > section.aqg-phero {
	padding-block: 26px 0;
}

/* ---------- Corps de la page ville ----------
   Le texte local ET la fiche partagent la MÊME colonne de lecture (780px, la
   mesure du thème), la section étant en layout `constrained`.

   Premier essai mesuré, écarté : section en layout `default`, prose contrainte
   à 780px par le bloc post-content et fiche en pleine largeur du shell. Les
   cartes de faits gagnaient de la place (573px de large pour une ligne de
   texte, donc à moitié vides) mais commençaient 190px à GAUCHE du paragraphe
   juste au-dessus. Deux bords gauches différents dans une même section se
   lisent comme un défaut de gabarit, et le gain de place ne servait rien. */
.aqg-main > section.aqg-ville-body {
	padding-block: 56px 0;
}

.aqg-ville-body > * + * {
	margin-block-start: 40px;
}

/* ---------- Fiche locale (bloc ACF) ---------- */
.aqg-fiche {
	display: flex;
	flex-direction: column;
	gap: 40px;
}

.aqg-fiche__titre {
	margin: 0 0 18px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 22px;
	font-weight: 800;
	line-height: 1.15;
}

/* Les faits locaux : ce sont EUX qui rendent la page unique, ils ouvrent donc
   la fiche. Rendus en <ul> hors de post_content, ils n'héritent d'aucun style
   de liste du cœur : la puce et le retrait de 40px du navigateur sont à
   neutraliser à la main. */
.aqg-fiche__faits {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
	gap: 14px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.aqg-fiche__fait {
	padding: 18px 20px;
	border: 1px solid var(--aqg-border-warm-2);
	border-radius: 18px;
	background: #fff;
	font-size: 15px;
	line-height: 1.55;
	color: #444;
}

.aqg-fiche__fait strong {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: 20px;
	font-weight: 800;
	color: var(--wp--preset--color--ink-deep);
}

/* Les quartiers sont saisis un par ligne et rendus en <br> : la carte prend la
   largeur entière plutôt que d'imposer sa hauteur à toute la rangée. */
.aqg-fiche__fait--quartiers {
	grid-column: 1 / -1;
}

.aqg-fiche__fait--quartiers span {
	display: block;
	margin-top: 6px;
	font-weight: 700;
	color: var(--wp--preset--color--ink-deep);
}

/* Chantiers : mêmes cartes blanches que partout, photo en 4/3 recadrée.
   L'aspect-ratio est porté par l'image ET par un fond, pour que la carte ne
   saute pas pendant le chargement (l'image est en lazy). */
.aqg-fiche__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
	gap: 20px;
}

.aqg-fiche__carte {
	overflow: hidden;
	border: 1px solid var(--aqg-border-warm-2);
	border-radius: 22px;
	background: #fff;
}

.aqg-fiche__photo {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background: var(--wp--preset--color--surface-blue);
}

.aqg-fiche__carte-titre {
	margin: 20px 22px 8px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 18px;
	font-weight: 800;
	line-height: 1.2;
}

.aqg-fiche__carte-desc {
	margin: 0 22px 22px;
	font-size: 15px;
	line-height: 1.6;
	color: #444;
}

/* Avis local. Aucun avis réel n'existe à ce jour et le champ reste vide : ce
   style attend le premier avis vérifiable, il n'en fabrique pas. Pas de note
   en étoiles ici, contrairement aux cartes de l'accueil : une note affichée
   sans avis sourcé est exactement ce que la règle d'honnêteté interdit. */
.aqg-fiche__avis {
	margin: 0;
	padding: 30px 34px;
	border: 1px solid var(--aqg-border-warm-2);
	border-left: 4px solid var(--wp--preset--color--primary);
	border-radius: 22px;
	background: #fff;
}

.aqg-fiche__avis-texte {
	margin: 0 0 14px;
	font-size: 17px;
	line-height: 1.6;
	color: #333;
}

.aqg-fiche__avis-auteur {
	font-size: 14px;
	font-style: normal;
	font-weight: 800;
	color: var(--aqg-muted);
}

/* Communes voisines : pilules-liens, et cliquables EN ENTIER.
   Le piège est celui déjà mesuré sur le bloc « Nos métiers » : un <a> inline
   dans un conteneur qui porte le rembourrage ne laisse cliquable qu'un tiers
   de ce que le visiteur voit comme un bouton. Le rembourrage est donc sur le
   lien, avec `box-sizing: border-box` sans lequel le `min-height` s'AJOUTE au
   rembourrage. */
.aqg-fiche__voisines-liste {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.aqg-fiche__voisines-liste li {
	margin: 0;
}

.aqg-fiche__voisines-liste a {
	display: inline-flex;
	box-sizing: border-box;
	align-items: center;
	min-height: 44px;
	padding: 9px 18px;
	border-radius: 100px;
	background: var(--wp--preset--color--surface-blue);
	color: var(--aqg-chip-ink);
	font-weight: 700;
	font-size: 15px;
	text-decoration: none;
	transition: transform .15s ease, background-color .15s ease, color .15s ease;
}

/* CONTRASTE — l'aplat de survol reprend `--aqg-chip-ink`. Motif d'origine levé :
   `--primary` avec du blanc dessus tombait à 3,45:1 quand il valait #0092D6,
   sous les 4,5:1 exigés pour un lien de 15px. Sur #14387F il donne 11,04:1. La
   règle reste, par cohérence avec les autres pilules du site. */
.aqg-fiche__voisines-liste a:hover {
	transform: translateY(-2px);
	background: var(--aqg-chip-ink);
	color: #fff;
}

.aqg-fiche__voisines-liste a:focus-visible {
	/* Anneau bi-ton, identique à celui des boutons : voir son commentaire.
	   Une couleur unique est intenable ici, ces pilules et ces liens vivant
	   tantôt sur du clair, tantôt sur du marine. */
	outline: 2px solid var(--wp--preset--color--base);
	outline-offset: 2px;
	box-shadow: 0 0 0 5px var(--wp--preset--color--ink-deep);
}

/* Le renvoi au hub n'est pas une commune : il se distingue des voisines, comme
   « Nous contacter » se distingue des sept métiers dans le bloc du même nom. */
.aqg-fiche__voisines-hub a {
	background: var(--wp--preset--color--ink-deep);
	color: #fff;
}

.aqg-fiche__voisines-hub a:hover {
	background: var(--wp--preset--color--contrast);
	color: #fff;
}

/* ---------- Hub « Zone d'intervention » (archive du CPT ville) ----------

   ORDRE DE LA PAGE : la portée de la zone D'ABORD, les pages détaillées
   ensuite. Retour client du 2026-08-22 : une page intitulée « Zone
   d'intervention » qui n'affiche que les communes ayant une fiche répond à côté
   de la question posée, et laisse croire que le reste du secteur n'est pas
   desservi. Le bandeau `aquagones/zone` de l'accueil a été RETIRÉ de ce
   gabarit : il ne liste que six communes et contredirait la liste complète. */
.aqg-zonehub {
	padding: 32px 34px;
	border: 1px solid var(--aqg-border-warm-2);
	border-radius: 24px;
	background: #fff;
}

.aqg-zonehub__title {
	margin: 0 0 10px;
	font-size: 26px;
}

.aqg-zonehub__lead {
	margin: 0 0 22px;
	color: var(--aqg-muted);
	line-height: 1.6;
}

/* FLEX CENTRÉ, ET PAS UNE GRILLE, contrairement au bandeau de l'accueil.
   La règle documentée « vérifier que N % colonnes != 1 » ne peut pas s'appliquer
   ici : le bandeau de l'accueil a SIX communes pour toujours, cette liste suit
   les communes réellement couvertes, elle en compte seize aujourd'hui et en
   comptera d'autres demain. Mesuré avec une grille auto-fit : 16 pilules sur
   5 colonnes donnent des rangées de 5, 5, 5 et **1**, soit exactement la pilule
   orpheline que le client avait fait corriger sur l'accueil. Aucun réglage de
   colonnes ne tient pour un N qui bouge.
   Un flex centré résout le cas par construction : la dernière rangée, complète
   ou non, est centrée et se lit comme une fin de liste, jamais comme un oubli
   de mise en page. */
.aqg-zonehub__communes {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
	margin: 0 0 22px;
}

.aqg-zonehub__communes .aqg-chip {
	text-align: center;
}

/* Ces pilules ne sont pas des liens : on neutralise l'effet de survol hérité de
   `.aqg-chip`, qui leur donnerait une fausse affordance de bouton. Même règle
   que sur le bandeau de l'accueil. */
.aqg-zonehub .aqg-chip:hover {
	transform: none;
	background: var(--wp--preset--color--surface-blue);
	color: var(--aqg-chip-ink);
}

.aqg-zonehub__open {
	margin: 0 0 22px;
	font-size: 15px;
	line-height: 1.6;
	color: var(--aqg-muted);
}

.aqg-zonehub__extend {
	margin: 0;
	padding-top: 20px;
	border-top: 1px solid var(--aqg-border-warm-2);
	font-size: 15px;
	line-height: 1.6;
	color: var(--aqg-muted);
}

.aqg-villes__title {
	margin: 0 0 10px;
	font-size: 30px;
}

.aqg-villes__lead {
	max-width: 780px;
	margin: 0 0 26px;
	color: var(--aqg-muted);
	line-height: 1.6;
}

/* La grille est posée sur `.wp-block-post-template` et non par le layout
   `grid` du cœur : celui-ci injecte ses colonnes sur une classe générée que
   les règles d'ici ne peuvent pas surcharger proprement. Même choix que
   `.aqg-services-grid` et `.aqg-zone__chips`. */
.aqg-villes-wrap .wp-block-post-template {
	display: grid;
	/* Minimum à 260px, pas 300 : à 1440px cela donne QUATRE colonnes au lieu de
	   trois, et seize cartes s'y répartissent sans reste là où trois colonnes
	   laissaient une carte seule sur la dernière rangée. Une carte orpheline se
	   voit moins qu'une pilule orpheline, les colonnes étant visibles, mais le
	   défaut est le même et il ne coûtait rien à corriger. Le compte des communes
	   bougeant à chaque ajout, aucun réglage ne garantit un reste nul à toutes
	   les largeurs : c'est une amélioration, pas une règle. */
	grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
	gap: 20px;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* PIÈGE, LE MÊME QUE PARTOUT AILLEURS DANS CE FICHIER — la gouttière de flux
   de WordPress traverse la grille. Le bloc post-template est en layout `default`,
   donc le cœur lui pose `is-layout-flow` et sa règle
   `:where(.is-layout-flow) > :where(:not(:first-child)) { margin-block-start }`
   s'applique à ses <li>, qui sont pourtant des cellules de GRILLE. Mesuré avant
   correctif : la deuxième carte commençait 24px plus bas que la première et
   mesurait 155px contre 179, sur la même rangée. Les cellules ne s'étirent
   correctement qu'une fois cette marge remise à zéro. */
.aqg-villes-wrap .wp-block-post-template > li {
	margin-block: 0;
}

.aqg-ville-card {
	height: 100%;
	padding: 26px 28px;
	border: 1px solid var(--aqg-border-warm-2);
	border-radius: 22px;
	background: #fff;
	transition: transform .18s ease, box-shadow .18s ease;
}

.aqg-ville-card:hover {
	transform: translateY(-3px);
	box-shadow: var(--aqg-shadow-card);
}

.aqg-ville-card__title {
	margin: 0 0 10px;
	font-size: 20px;
	line-height: 1.2;
}

.aqg-ville-card__title a {
	color: var(--wp--preset--color--ink-deep);
	text-decoration: none;
}

.aqg-ville-card:hover .aqg-ville-card__title a {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.aqg-ville-card__desc {
	margin: 0;
	line-height: 1.6;
	color: var(--aqg-muted);
}

.aqg-ville-card__desc p {
	margin: 0;
}

.aqg-villes__empty {
	margin: 0;
	padding: 26px 28px;
	border: 1px dashed var(--aqg-border-warm);
	border-radius: 22px;
	color: var(--aqg-muted);
}

.aqg-villes__pagination {
	margin-top: 28px;
}

@media (max-width: 700px) {
	.aqg-zonehub {
		padding: 26px 22px;
	}

	.aqg-ville-body {
		padding-block-start: 40px;
	}

	.aqg-fiche {
		gap: 30px;
	}

	.aqg-fiche__avis {
		padding: 24px 22px;
	}
}

/* ==========================================================================
   Comparateur avant / après (`.aqg-ba`, patterns `avant-apres`,
   `avant-apres-accueil` et section « Avant / après » de /plomberie/).

   Deux états, et le premier est le défaut :
   - SANS script (et dans l'éditeur) : les deux photos côte à côte, chacune
     avec sa pastille (la légende du bloc Image), curseur et poignée masqués ;
   - AVEC script (`assets/js/photos.js` pose `.is-on`) : les deux photos
     dans la même cellule de grille, l'« après » découpée à gauche par
     `clip-path` jusqu'à `--aqg-ba-pos`, une ligne et une poignée ronde à cette
     position. Souris et doigt sont gérés sur la photo par le script, qui ne
     prend que les gestes horizontaux (`touch-action: pan-y` : un geste
     vertical fait défiler la page) ; le curseur natif, posé dessus à opacité
     nulle et sans pointeur, sert au clavier et aux lecteurs d'écran.

   Pastilles : voile `ink-deep` à 92 %, texte blanc, soit plus de 12:1 même
   sur un blanc pur derrière ; au-dessus de 90 % de couverture, l'outil de
   contraste mesure le fond au lieu de le déclarer indéterminé.

   Pointeur : depuis le 2026-10-03, souris et doigt sont gérés sur la photo
   par le script (le curseur natif bloquait le défilement vertical au doigt) ;
   le curseur ne sert plus qu'au clavier et aux lecteurs d'écran.

   Focus : le curseur est invisible, l'anneau se peint donc sur la POIGNÉE,
   par la règle unique de l'anneau bi-ton (sélecteur
   `.aqg-ba__range:focus-visible ~ .aqg-ba__handle .aqg-ba__knob`, plus haut,
   et bloc `forced-colors` de fin de fichier). Aucune transition : rien à
   couper sous `prefers-reduced-motion`.
   ========================================================================== */
.aqg-ba > *,
.aqg-ba__stage > *,
.aqg-ba-grid > *,
.aqg-ba-home__card > * {
	margin-block: 0;
}

.aqg-ba {
	--aqg-ba-pos: 50%;
	margin: 0;
}

.aqg-ba__stage {
	position: relative;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
}

.aqg-ba__img {
	position: relative;
	margin: 0;
	border-radius: 18px;
	overflow: hidden;
	background: var(--wp--preset--color--surface-blue);
}

.aqg-ba__img img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

.aqg-ba__img .wp-element-caption {
	position: absolute;
	top: 12px;
	left: 12px;
	z-index: 1;
	margin: 0;
	padding: 5px 12px;
	border-radius: 100px;
	background: rgba(13, 34, 51, .92);
	color: #fff;
	font-size: 13px;
	font-weight: 700;
	line-height: 1.3;
	text-align: left;
}

.aqg-ba__range,
.aqg-ba__handle {
	display: none;
}

.aqg-ba > .aqg-ba__caption {
	margin-top: 12px;
	color: var(--aqg-muted);
	text-align: center;
}

/* ---- État activé par le script ---- */
.aqg-ba.is-on .aqg-ba__stage {
	grid-template-columns: minmax(0, 1fr);
	gap: 0;
	border-radius: 18px;
	overflow: hidden;
}

.aqg-ba.is-on .aqg-ba__img {
	grid-area: 1 / 1;
	border-radius: 0;
}

.aqg-ba.is-on .aqg-ba__img--apres {
	clip-path: inset(0 0 0 var(--aqg-ba-pos));
}

.aqg-ba.is-on .aqg-ba__img--apres .wp-element-caption {
	right: 12px;
	left: auto;
}

.aqg-ba.is-on .aqg-ba__range {
	display: block;
	position: absolute;
	inset: 0;
	z-index: 3;
	width: 100%;
	height: 100%;
	margin: 0;
	opacity: 0;
	-webkit-appearance: none;
	appearance: none;
	outline: none;
	/* Clavier et lecteur d'écran seulement : le pointeur est géré sur la
	   photo par `photos.js` (cf. `.aqg-ba.is-on .aqg-ba__stage`). */
	pointer-events: none;
}

/* La photo reçoit souris et doigt : `pan-y` laisse le navigateur faire
   défiler la page d'un geste vertical, le script ne prend que les gestes
   horizontaux. Images et sélection neutralisées, sinon la souris lancerait
   un glisser-déposer natif de l'image. */
.aqg-ba.is-on .aqg-ba__stage {
	cursor: ew-resize;
	touch-action: pan-y;
	-webkit-user-select: none;
	user-select: none;
}

.aqg-ba.is-on .aqg-ba__img img {
	pointer-events: none;
	-webkit-user-drag: none;
}

/* Pouce natif réduit à 2px : avec sa largeur par défaut, la valeur ne suit
   pas exactement le pointeur (clic à 85 % de la photo lu 87, mesuré le
   2026-10-03), et la poignée dessinée tombait à côté du doigt. */
.aqg-ba__range::-webkit-slider-thumb {
	width: 2px;
	height: 44px;
	-webkit-appearance: none;
	appearance: none;
}

.aqg-ba__range::-moz-range-thumb {
	width: 2px;
	height: 44px;
	border: 0;
}

.aqg-ba.is-on .aqg-ba__handle {
	display: block;
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--aqg-ba-pos);
	z-index: 2;
	width: 3px;
	margin-left: -1.5px;
	background: #fff;
	box-shadow: 0 0 0 1px rgba(13, 34, 51, .35);
	pointer-events: none;
}

/* Poignée de 44px (cible tactile), bordure `primary-dark` : elle se détache
   de n'importe quelle photo, claire ou sombre. */
.aqg-ba__knob {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 44px;
	height: 44px;
	border: 2px solid var(--wp--preset--color--primary-dark);
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 2px 10px rgba(13, 34, 51, .35);
	transform: translate(-50%, -50%);
}

.aqg-ba__knob::before {
	content: "";
	position: absolute;
	inset: 0;
	margin: auto;
	width: 22px;
	height: 22px;
	background: var(--wp--preset--color--primary-dark);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 7-5 5 5 5'/%3E%3Cpath d='m15 7 5 5-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 7-5 5 5 5'/%3E%3Cpath d='m15 7 5 5-5 5'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ---- Section « Avant / après » de /plomberie/ : trois comparateurs ---- */
.aqg-ba-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
}

/* ---- Bloc compact de l'accueil ---- */
.aqg-ba-home__card {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
	gap: 48px;
	align-items: center;
	padding: 48px;
	border: 1px solid var(--aqg-border-warm);
	border-radius: 28px;
	background: var(--wp--preset--color--base);
}

.aqg-ba-home__text {
	color: var(--aqg-muted);
}

.aqg-ba-home__cta {
	margin-top: 28px;
}

@media (max-width: 960px) {
	.aqg-ba-grid {
		grid-template-columns: minmax(0, 440px);
		justify-content: center;
		gap: 36px;
	}

	.aqg-ba-home__card {
		grid-template-columns: minmax(0, 1fr);
		gap: 32px;
		padding: 36px 28px;
	}

	.aqg-ba-home__card > .aqg-ba {
		width: 100%;
		max-width: 440px;
		margin-inline: auto;
	}
}

@media (max-width: 600px) {
	.aqg-ba-home__card {
		padding: 28px 20px;
	}
}

/* ==========================================================================
   Agrandissement au clic (vignettes de la mosaïque de l'accueil et de toutes
   les sections « Nos réalisations » : /plomberie/, /climatisation/,
   /climatisation-gainable/, /chauffage-pompe-a-chaleur/, /ventilation-vmc/).

   Le bloc Image porte un lien `a.aqg-zoom` vers la photo ENTIÈRE, non
   recadrée (`<nom>-entiere.jpg`). Sans script, le lien ouvre le fichier ;
   `assets/js/photos.js` l'ouvre dans un `<dialog>` modal natif, cloné depuis
   le `<template id="aqg-lightbox-tpl">` que le thème imprime en pied de page
   (`functions.php`) : Échap, bouton « Fermer », clic sur le fond, focus rendu
   à la vignette. La pastille de légende reste au-dessus du lien, sans
   intercepter le clic.

   Focus de la vignette : la carte coupe ce qui déborde (`overflow: hidden`),
   un anneau posé sur le lien serait rogné. L'anneau bi-ton est donc porté par
   la CARTE, par `:has()` (sélecteur ajouté à la règle unique de l'anneau et
   au bloc `forced-colors`), et le lien n'en dessine aucun.
   ========================================================================== */
.aqg-realis-card__img .aqg-zoom {
	display: block;
	height: 100%;
	cursor: zoom-in;
}

.aqg-realis-card__img .aqg-zoom:focus-visible {
	outline: none;
	box-shadow: none;
}

.aqg-realis-card:has(.aqg-zoom) .aqg-realis-card__chip {
	pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
	.aqg-realis-card__img .aqg-zoom img {
		transition: transform .45s cubic-bezier(.22, .61, .36, 1);
	}

	.aqg-realis-card__img .aqg-zoom:hover img,
	.aqg-realis-card__img .aqg-zoom:focus-visible img {
		transform: scale(1.04);
	}
}

/* `fit-content` and not `auto`: an open modal dialog is fixed with inset 0,
   so `auto` stretched it to max-width and left the close button 1200px away
   from a 540px wide photo. */
.aqg-lightbox {
	width: fit-content;
	max-width: min(94vw, 1200px);
	max-height: 100vh;
	margin: auto;
	padding: 0;
	border: 0;
	background: transparent;
	overflow: visible;
}

.aqg-lightbox::backdrop {
	background: rgba(13, 34, 51, .9);
}

html:has(.aqg-lightbox[open]) {
	overflow: hidden;
}

.aqg-lightbox__close {
	display: block;
	margin: 0 0 10px auto;
	padding: 9px 18px;
	border: 0;
	border-radius: 100px;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary-dark);
	font: inherit;
	font-size: 15px;
	font-weight: 700;
	cursor: pointer;
}

.aqg-lightbox__close:hover {
	background: var(--wp--preset--color--surface-blue);
}

.aqg-lightbox__figure {
	margin: 0;
	text-align: center;
}

/* Boîte réservée AVANT le chargement : les photos entières sont toutes en
   3:4 (1200×1600). Sans cela, l'image mesurait 0×0 tant qu'elle n'était pas
   arrivée (relevé à 390px le 2026-10-03). La hauteur est la plus petite de
   « écran moins bouton et légende » et « largeur disponible × 4/3 ». */
.aqg-lightbox__img {
	display: block;
	width: auto;
	max-width: 100%;
	height: min(calc(90vh - 90px), calc(min(94vw, 1200px) * 4 / 3));
	aspect-ratio: 3 / 4;
	margin: 0 auto;
	border-radius: 14px;
	background: rgba(255, 255, 255, .06);
	object-fit: contain;
}

.aqg-lightbox__caption {
	margin: 12px 0 0;
	color: #fff;
	font-size: 15px;
	font-weight: 600;
}

/* Opening effect: the backdrop fades in, the photo rises and scales up
   slightly. The dialog is cloned ONCE at load; the animation replays on each
   `showModal()` because it is keyed on `[open]`, which toggles at every
   opening and closing. */
@media (prefers-reduced-motion: no-preference) {
	.aqg-lightbox[open] {
		animation: aqg-lightbox-in .32s cubic-bezier(.22, .61, .36, 1);
	}

	.aqg-lightbox[open]::backdrop {
		animation: aqg-lightbox-fade .32s ease-out;
	}
}

@keyframes aqg-lightbox-in {
	from {
		opacity: 0;
		transform: translateY(12px) scale(.96);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes aqg-lightbox-fade {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

/* ==========================================================================
   Contraste forcé (mode « contraste élevé » de Windows).

   Le navigateur y remplace les couleurs de l'auteur par la palette du système
   et, surtout, il ANNULE les `box-shadow` et les images de fond. Trois gestes
   du thème reposaient précisément là-dessus et disparaissaient donc sans
   filet, pour les utilisateurs qui ont le plus besoin de les voir. Rien ici
   n'a d'effet en rendu normal.
   ========================================================================== */
@media (forced-colors: active) {
	/* 1. Le focus des champs ne tenait qu'à une `box-shadow`, posée juste après
	      un `outline: none` : les deux sont neutralisés ici, le champ actif
	      devenait indiscernable du champ au repos. */
	.aqg-form__field input:focus,
	.aqg-form__field select:focus,
	.aqg-form__field textarea:focus {
		outline: 2px solid Highlight;
		outline-offset: 2px;
	}

	/* 1 bis. L'état invalide repose sur la MÊME `box-shadow` rouge, annulée
	      elle aussi : un champ en erreur redevenait indiscernable d'un champ
	      valide, alors que c'est précisément l'information à transmettre. */
	.aqg-form.was-validated .aqg-form__field input:invalid,
	.aqg-form.was-validated .aqg-form__field select:invalid,
	.aqg-form.was-validated .aqg-form__field textarea:invalid {
		outline: 2px dashed Mark;
		outline-offset: 2px;
	}

	/* 2. Les pictogrammes sont des masques peints par un aplat de fond. Le
	      contraste forcé ramène cet aplat à la couleur de la toile et les fait
	      disparaître entièrement.

	      La classe est doublée pour porter la spécificité à (0,2,1), à ÉGALITÉ
	      avec `.aqg-ic.i-check::before` : ce n'est donc pas la spécificité qui
	      tranche mais l'ORDRE SOURCE, ce bloc étant en fin de feuille. Déplacer
	      ce bloc plus haut casserait la règle en silence.

	      Le pictogramme des boutons du cœur à icône (`.aqg-btn-ic`, page de
	      coordonnées, 2026-09-27) est peint de la même façon : il rejoint la
	      liste, à spécificité égale (0,2,1) avec sa règle nominale. */
	.aqg-ic.aqg-ic::before,
	.aqg-ico.aqg-ico::before,
	.aqg-btn-phone .wp-block-button__link::before,
	.aqg-btn-ic .wp-block-button__link::before {
		background: CanvasText;
	}

	/* 3. Le bouton d'ouverture du menu est peint par le MÊME mécanisme que les
	      glyphes ci-dessus : trois barres en `background: currentColor`. En
	      contraste forcé il rendait une boîte vide, et sous 901px c'est le seul
	      accès à la navigation du site. Recensement fait : sur les 8
	      `currentColor` de la feuille, deux sont des `border-*-color` que
	      l'agent utilisateur force lui-même, trois sont couvertes ci-dessus,
	      celle-ci était la dernière. Le bouton à icône de la page de
	      coordonnées (`.aqg-btn-ic`, 2026-09-27) en a ajouté une, couverte
	      au n° 2. */
	.aqg-nav__bars,
	.aqg-nav__bars::before,
	.aqg-nav__bars::after {
		background: CanvasText;
	}

	/* 4. L'anneau de focus des boutons doit suivre la couleur de sélection du
	      système plutôt que le marine du thème.

	      Les quatre sélecteurs qui suivent les trois boutons sont ceux de la
	      soumission en place. Le bouton de retour au formulaire est un bouton
	      comme les autres ; le message de retour et le panneau de confirmation,
	      eux, ne sont focalisables que par script, et leur anneau est le seul
	      repère qui dise au clavier où il a été déplacé. Viennent ensuite le
	      lien de la mention d'information, porteur de la règle unique depuis
	      le 2026-09-25, le résumé des listes de la section TVA, depuis le
	      2026-09-26, le bouton d'opposition à la mesure d'audience de la
	      politique de confidentialité, depuis le 2026-09-27, et le lien
	      « Voir les communes desservies » de la page de coordonnées
	      (/contact/), le même jour. Enfin le lien du crédit de réalisation
	      en bas de page, depuis le 2026-10-02. */
	.wp-block-button__link:focus-visible,
	.wp-element-button:focus-visible,
	.aqg-form__submit:focus-visible,
	.aqg-form__again:focus-visible,
	.aqg-form__feedback:focus-visible,
	.aqg-form__done:focus-visible,
	.aqg-form__done-tel a:focus-visible,
	.aqg-form__hint a:focus-visible,
	.aqg-aide-card__more > summary:focus-visible,
	.aqg-optout:focus-visible,
	.aqg-contact__line a:focus-visible,
	.aqg-footer__credit a:focus-visible,
	.aqg-ba__range:focus-visible ~ .aqg-ba__handle .aqg-ba__knob,
	.aqg-realis-card:has(.aqg-zoom:focus-visible),
	.aqg-lightbox__close:focus-visible {
		outline-color: Highlight;
	}

	/* 5. Comparateur avant / après : la ligne et la poignée sont des aplats, que
	      le contraste forcé ramène à la toile ; le picto de la poignée est un
	      masque, comme ceux du n° 2. */
	.aqg-ba.is-on .aqg-ba__handle,
	.aqg-ba__knob::before {
		background: CanvasText;
	}

	.aqg-ba__knob {
		border-color: CanvasText;
	}

	:where(a[href], summary):focus-visible,
	.aqg-callbar:focus-visible {
		outline-color: Highlight;
	}
}
