/*
Theme Name: Guevenatten (Etch Child)
Theme URI: https://jbkagency.com
Author: JBK Agency
Description: Child theme du thème Etch pour le site de la mairie de Guevenatten.
Requires at least: 6.9
Tested up to: 6.9
Requires PHP: 8.0
Version: 2.32.32
Template: etch-theme
Text Domain: guevenatten-etch-child
*/

/* Polices auto-hebergees (RGPD : pas d'appel a Google Fonts depuis le navigateur) */
@font-face {
	font-family: 'Space Grotesk';
	src: url('assets/fonts/space-grotesk-variable.woff2') format('woff2');
	font-weight: 500 700;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Public Sans';
	src: url('assets/fonts/public-sans-variable.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

/*
 * Palette derivee du blason communal ("D'azur a trois cabanes d'or"),
 * configuree DANS le dashboard ACSS (Palette > Main Colors), pas en CSS
 * perso : color-primary=#2f658f (azur), color-accent=#b9932a (or),
 * color-base=#1f3a5f (navy, footer) - via `wp acss settings set`, qui a
 * recalcule tous les OKLCH derives (ultra-light..ultra-dark, hover) pour
 * les 3 familles. Nos tokens --gv-* ci-dessous ne redefinissent PLUS de
 * hex : ils choisissent quelle marche de l'echelle ACSS utiliser pour
 * chaque usage (ex : le lien de contenu doit rester lisible sur fond
 * clair, donc --primary-semi-dark et pas --primary "brut" qui est
 * calibre pour du texte blanc sur bouton plein, pas l'inverse - verifie
 * au ratio de contraste WCAG : --primary brut ne fait que 2.87:1 sur le
 * fond creme, --primary-semi-dark fait 10:1).
 *
 * Tout ce qui est taille/espacement/typo passe aussi par les variables
 * generees par Automatic.css : --space-*, --section-space-*, --h1..--h6,
 * --content-width, --grid-auto-*, --gutter (clamp() fluides, calcules
 * par ACSS a partir de la largeur reelle du site vp-max/vp-min).
 */
:root {
	--gv-text:    #333;
	--gv-link:    var(--primary-semi-dark);
	--gv-hover:   var(--primary-dark);
	--gv-accent:  var(--accent);
	--gv-accent-on-dark: var(--accent-light);
	--gv-head:    #4b4b4b;
	--gv-bg:      var(--neutral-ultra-light);
	--gv-footer-bg:  var(--base-dark);
	--gv-shadow-soft: 0 2px 10px rgba(0, 0, 0, .08);
	--gv-font-heading: 'Space Grotesk', -apple-system, system-ui, sans-serif;
	--gv-font-body:    'Public Sans', -apple-system, system-ui, sans-serif;

	/* Branche nos polices/couleurs dans les hooks de variables qu'ACSS lit
	   lui-meme pour styler h1-h6 et le corps de texte (voir "Feat: Heading
	   Defaults" dans automatic.css) - pas besoin de re-ecrire les tailles,
	   ACSS s'en charge (--h1..--h6 deja fluides). */
	--heading-font-family: var(--gv-font-heading) !important;
	--heading-color: var(--gv-head) !important;
	--text-font-family: var(--gv-font-body) !important;
}

/*
 * ACSS expose --heading-font-family/--text-font-family comme simples
 * "matieres premieres" (aucune regle native d'ACSS ne les consomme,
 * verifie dans automatic.css genere) : c'est a nous de les brancher sur
 * les elements. Tailles/couleur/graisse restent gerees par ACSS
 * lui-meme (regle "Feat: Heading Defaults", specificite 0,0,1).
 */
body {
	background: var(--gv-bg);
	color: var(--gv-text);
	font-family: var(--text-font-family);
}
h1, h2, h3, h4, h5, h6 {
	font-family: var(--heading-font-family);
}
/*
 * !important necessaire ici : constate empiriquement qu'un <a> "nu" (sans
 * classe) resout `color: var(--gv-link)` vers la valeur de --primary de
 * base (L=.65) au lieu de --primary-semi-dark (L=.35) que --gv-link
 * reference pourtant correctement (verifie via getComputedStyle sur
 * l'element lui-meme et tous ses ancetres - la variable est bonne partout,
 * seule la propriete `color` sur `a` specifiquement se trompe). Cause
 * exacte non identifiee (aucune autre regle CSS ne cible `a` sur le
 * `color`, meme apres avoir parcouru les @layer) - possible interaction
 * de cascade layer entre le reset Etch et ACSS. Un <span> avec la meme
 * variable inline se comporte correctement, donc le bug est specifique
 * aux <a>. !important contourne le probleme de façon fiable (verifie).
 */
a { color: var(--gv-link) !important; }
a:hover, a:focus { color: var(--gv-hover) !important; }

/*
 * ---------- Nav ----------
 * Sortie de l'image (demande user) : le nav n'est plus superpose a la
 * photo (plus de position:fixed transparente), c'est une barre pleine,
 * sticky, au-dessus de l'image - qui vient juste apres dans le flux
 * normal. Un seul style desormais (fond creme, texte sombre), plus de
 * variante "sur photo"/"au scroll" a maintenir.
 */
.gv-nav {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--gv-footer-bg);
	box-shadow: var(--gv-shadow-soft);
}
.gv-nav-toggle-input { position: absolute; opacity: 0; pointer-events: none; }

/*
 * Offset des ancres (#horaires...) sous le nav sticky : ACSS a deja son
 * propre mecanisme natif ([id] { scroll-margin-top: var(--offset) },
 * automatic.css) mais --header-height/--scroll-margin valent 0 par defaut
 * (tokens prevus pour etre remplis par le theme, ACSS ne peut pas connaitre
 * la hauteur d'un header custom tout seul). Remplis dynamiquement en JS
 * (assets/header-offset.js) plutot qu'en CSS statique : --header-height
 * varie avec la largeur d'ecran/le contenu du blason-titre, un style inline
 * pose par JS sur <html> gagne aussi de facon fiable contre l'ordre de
 * cascade CSS (pas besoin de savoir si automatic.css charge avant ou apres
 * notre feuille).
 */
/*
 * Pas de padding ici : le <header> (.gv-nav) porte deja `.header--s`, la
 * vraie classe utilitaire ACSS pour un header (padding-block:--space-s +
 * padding-inline:--gutter, verifie dans automatic.css genere). En ajouter
 * un deuxieme ici doublait le decalage a gauche (blason a 2x le gutter
 * au lieu d'1x, constate et corrige).
 */
.gv-nav-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
}
.gv-nav-title {
	display: flex;
	align-items: center;
	flex-shrink: 0;
	gap: var(--space-xs);
	color: #fff !important;
	font-family: var(--gv-font-heading);
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}
/* Sans regle de survol dediee, le titre retombait sur la regle generique
   a:hover { color: var(--gv-hover) } du site (pensee pour les liens de
   contenu) - pas geree pour ce composant, couleur non voulue sur fond
   sombre. Meme paire blanc/vert que le reste du header (inversee : le
   titre est blanc au repos, vert au survol). */
.gv-nav-title:hover, .gv-nav-title:focus { color: var(--gv-accent-on-dark) !important; }
/* aspect-ratio explicite : PageSpeed signalait ce badge comme "taille inconnue"
   au chargement (CLS) malgre les attributs width/height sur la balise <img>. */
.gv-nav-badge { width: 36px; height: auto; aspect-ratio: 108 / 119; background: #fff; border-radius: 4px; padding: 2px; }
.gv-nav-hamburger {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	cursor: pointer;
	color: #fff;
}
.gv-nav-hamburger span:not(.gv-nav-hamburger-label) {
	display: block;
	width: 24px;
	height: 2px;
	background: currentColor;
}
.gv-nav-hamburger-label { font-size: var(--text-xs); }

.gv-nav-panel {
	max-height: 0;
	overflow: hidden;
	background: var(--gv-footer-bg);
	transition: max-height .25s ease;
}
.gv-nav-toggle-input:checked ~ .gv-nav-panel {
	max-height: 80vh;
	overflow-y: auto;
}
.gv-nav-list { list-style: none; margin: 0; padding: var(--space-s) 0 var(--space-m); }
/* Panneau mobile passe en fond sombre (uniformise avec la barre + les
   sous-menus desktop) : memes couleurs vert/blanc, separateurs eclaircis
   (rgba noir devenu invisible sur fond marine). */
.gv-nav-item > a {
	display: block;
	padding: var(--space-xs) 0;
	color: var(--gv-accent-on-dark) !important;
	font-size: var(--text-xs);
	text-decoration: none;
	border-bottom: 1px solid rgba(255, 255, 255, .15);
}
.gv-nav-item.gv-nav-current > a,
.gv-nav-item > a:hover { color: #fff !important; }
.gv-nav-has-children summary {
	display: flex;
	align-items: center;
	gap: var(--space-xs);
	list-style: none;
	cursor: pointer;
	border-bottom: 1px solid rgba(255, 255, 255, .15);
}
.gv-nav-has-children summary::-webkit-details-marker { display: none; }
.gv-nav-has-children summary .gv-nav-label {
	padding: var(--space-xs) 0;
	color: var(--gv-accent-on-dark) !important;
	font-size: var(--text-xs);
}
.gv-nav-arrow {
	width: 10px;
	height: 10px;
	border-right: 2px solid var(--gv-accent-on-dark);
	border-bottom: 2px solid var(--gv-accent-on-dark);
	transform: rotate(45deg);
	transition: transform .2s ease;
}
.gv-nav-has-children details[open] .gv-nav-arrow { transform: rotate(-135deg); }
.gv-nav-sublist { list-style: none; margin: 0; padding: 0 0 var(--space-xs) var(--space-m); }
/* Meme fond sombre que le reste du panneau mobile depuis peu : couleur mise
   a jour (etait pensee pour l'ancien fond clair, illisible sur fond marine). */
.gv-nav-sublist a {
	display: block;
	padding: var(--space-xs) 0;
	color: var(--gv-accent-on-dark) !important;
	font-size: var(--text-xs);
	text-decoration: none;
}
.gv-nav-sublist a:hover { color: #fff !important; }

@media (min-width: 1336px) {
	/*
	 * Menu sur la meme ligne que le blason/titre (demande user) : .gv-nav
	 * devient le conteneur flex commun, avec .gv-nav-bar (blason+titre) et
	 * .gv-nav-panel (liste des rubriques) comme deux enfants cote a cote -
	 * le centrage/largeur max qui etait sur .gv-nav-bar passe ici, au
	 * niveau du parent commun.
	 *
	 * Seuil a 1336px (demande user, pour que ca tienne des les ecrans
	 * portable courants) : a cette largeur le titre complet sur une seule
	 * ligne + blason + 7 rubriques ne rentrent pas (mesure : +117px de
	 * debordement a 1366px). Solution demandee : passer le texte du titre
	 * sur 2 lignes a droite du blason pour liberer de la largeur, hauteur
	 * du header plafonnee a 80px (voir .gv-nav-inner plus bas).
	 *
	 * IMPORTANT : le flex/max-width/centrage va sur .gv-nav-inner, PAS sur
	 * .gv-nav lui-meme - .gv-nav (le <header>) doit rester pleine largeur
	 * (fond + ombre bord a bord) quelle que soit la largeur d'ecran, avec
	 * juste son CONTENU centre a l'interieur. Regression precedente :
	 * max-width pose directement sur .gv-nav limitait aussi le fond/l'ombre
	 * a 1366px, laissant l'arriere-plan de la page visible sur les cotes
	 * en grand ecran - corrige.
	 */
	.gv-nav { padding: 0; }
	.gv-nav-inner { display: flex; align-items: center; gap: var(--space-s); max-width: var(--content-width); margin: 0 auto; }
	.gv-nav-bar { flex-shrink: 0; }
	.gv-nav-title { white-space: normal; }
	.gv-nav-title-text {
		max-width: 8.5em;
		font-size: var(--text-s);
		line-height: 1.2;
	}
	.gv-nav-hamburger { display: none; }
	.gv-nav-panel { max-height: none !important; overflow: visible; background: transparent; flex: 1; }
	.gv-nav-list { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2xs, var(--space-xs)); padding: 0; }
	/*
	 * A cette largeur, .gv-nav-panel a fond transparent (regle plus bas) :
	 * ces liens reposent directement sur le fond sombre de .gv-nav (pas sur
	 * le panneau clair mobile) - couleur vert accent pour rester lisibles,
	 * meme mecanisme que les liens du footer (--gv-accent-on-dark).
	 */
	.gv-nav-item > a { border-bottom: none; padding: var(--space-xs); white-space: nowrap; color: var(--gv-accent-on-dark) !important; }
	.gv-nav-item.gv-nav-current > a,
	.gv-nav-item > a:hover { color: #fff !important; }
	.gv-nav-has-children { position: relative; }
	.gv-nav-has-children summary { border-bottom: none; padding: var(--space-xs); }
	/* Sans ce reset, .gv-nav-label gardait aussi son padding vertical mobile
	   (var(--space-xs) 0), qui s'additionnait a celui de son parent summary
	   ci-dessus - double espacement vertical constate et corrige. */
	.gv-nav-has-children summary .gv-nav-label { padding: 0; color: var(--gv-accent-on-dark) !important; }
	.gv-nav-has-children summary:hover .gv-nav-label { color: #fff !important; }
	.gv-nav-arrow { border-right-color: var(--gv-accent-on-dark); border-bottom-color: var(--gv-accent-on-dark); }
	.gv-nav-has-children summary:hover .gv-nav-arrow { border-right-color: #fff; border-bottom-color: #fff; }

	/*
	 * Deroulement au survol (demande user), pas au clic : <details> cache
	 * nativement son contenu tant que [open] n'est pas pose (regle UA du
	 * navigateur) - on force l'affichage du sous-menu dans le DOM avec
	 * `display:block !important` (bypass le [open] natif, qui ne sert plus
	 * qu'au clic mobile), puis on pilote la VRAIE visibilite nous-memes
	 * via opacity/pointer-events sur :hover et :focus-within (clavier).
	 */
	.gv-nav-has-children details:not([open]) .gv-nav-sublist { display: block !important; }
	.gv-nav-has-children .gv-nav-sublist {
		position: absolute;
		top: 100%;
		left: 0;
		background: var(--gv-footer-bg);
		box-shadow: var(--gv-shadow-soft);
		padding: var(--space-xs) var(--space-s);
		min-width: 220px;
		opacity: 0;
		pointer-events: none;
		transition: opacity .15s ease;
		/* 5px = exactement le token ACSS --radius : plus de valeur en dur.
		   Seuls les 2 coins bas arrondis (le haut touche la barre). */
		border-radius: 0 0 var(--radius) var(--radius);
	}
	/* Test fond sombre (comme la barre) : le panneau mobile (.gv-nav-panel,
	   fond clair) n'est pas concerne, seul ce sous-menu desktop change. */
	.gv-nav-has-children .gv-nav-sublist a { color: var(--gv-accent-on-dark) !important; }
	.gv-nav-has-children .gv-nav-sublist a:hover { color: #fff !important; }
	.gv-nav-has-children:hover .gv-nav-sublist,
	.gv-nav-has-children:focus-within .gv-nav-sublist {
		opacity: 1;
		pointer-events: auto;
	}
}

/* ---------- Hero / bandeau photo ---------- */
/*
 * .gv-hero-caption etait en position:absolute (bottom:var(--space-m)) dans un
 * conteneur overflow:hidden a hauteur FIXE (celle de l'image) : un titre long
 * qui passe sur plusieurs lignes grandit vers le HAUT depuis son ancrage bas
 * et se fait rogner par l'overflow:hidden, invisible au-dessus du bandeau
 * (constate sur "Assainissement des eaux usees - ... : lagunage" en mobile).
 * Fix : .gv-hero devient un conteneur flex a min-height (pas height fixe) ;
 * l'image et dv-hero-overlay passent en calque de fond absolu (inset:0),
 * la legende reste dans le flux (margin-top:auto la pousse en bas) - si elle
 * a besoin de plus de place, c'est tout le bandeau qui grandit, rien n'est
 * jamais coupe.
 */
.gv-hero {
	position: relative;
	width: 100%;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	min-height: clamp(180px, 26vw, 320px);
}
/*
 * Etend le bandeau jusqu'au bas de l'ecran (hauteur de viewport moins le
 * header sticky) plutot qu'un plafond fixe - supprime le vide uni entre
 * l'image et "Actualites" sur les grands ecrans (ex. 1920x1080). Reutilise
 * --header-height, deja mesure en JS (assets/header-offset.js) pour le
 * scroll-margin des ancres - repli 80px le temps que le JS s'execute au
 * 1er paint. 100svh (pas 100vh) : meme convention que le reset du theme
 * (body { min-block-size: 100svh }), fiable sur mobile malgre les barres
 * d'adresse dynamiques (non impactant ici, ecrase par le breakpoint mobile
 * juste en dessous).
 */
.gv-hero-home { min-height: calc(100svh - var(--header-height, 80px)); }
/*
 * Incitation a scroller (bandeau home etendu a l'ecran, cf. .gv-hero-home
 * ci-dessus : sans repere, "Actualites" hors champ n'est plus evident).
 * Cible #gv-actualites, deja couvert par le mecanisme natif ACSS
 * [id] { scroll-margin-top: var(--offset) } - pas de JS de scroll a ecrire.
 * !important necessaire : `a{color:var(--gv-link)!important}` (regle
 * generique tout en haut du fichier) l'emporterait sinon.
 */
.gv-hero-scroll-cue {
	position: absolute;
	left: 50%;
	bottom: var(--space-m);
	transform: translateX(-50%);
	color: var(--gv-accent-on-dark) !important;
	display: flex;
	z-index: 1;
	animation: gv-scroll-cue-bounce 2s ease-in-out infinite;
}
.gv-hero-scroll-cue:hover, .gv-hero-scroll-cue:focus-visible { color: #fff !important; }
@keyframes gv-scroll-cue-bounce {
	0%, 100% { transform: translateX(-50%) translateY(0); }
	50% { transform: translateX(-50%) translateY(8px); }
}
@media (prefers-reduced-motion: reduce) {
	.gv-hero-scroll-cue { animation: none; }
}
@media (max-width: 600px) {
	/* Le plancher de 320px de .gv-hero-home donne un cadre quasi carre sur
	   mobile (ex. 320/390 = ratio 0.82) ; plancher abaisse ici pour rester
	   rectangulaire (~1.8:1) a toutes les largeurs de telephone. */
	.gv-hero-home { min-height: clamp(180px, 55vw, 260px); }
	/*
	 * Bandeau deja court sur mobile (~200px), Actualites reste visible sans
	 * scroller - l'incitation ne sert qu'au bandeau plein ecran desktop.
	 * DOIT venir apres la regle de base .gv-hero-scroll-cue{display:flex}
	 * ci-dessus (meme specificite classe=classe, sinon le "flex" plus bas
	 * dans le fichier regagnerait la cascade malgre le media query).
	 */
	.gv-hero-scroll-cue { display: none; }
}
/*
 * Sous ~1280px le titre "Bienvenue a Guevenatten" chevauche le chevron
 * centre (verifie : bord droit du titre a 874px a 1280px de large, chevron
 * a 618-646px - collision reelle, et l'ecart residuel entre le titre et le
 * bord d'ecran devient meme negatif en dessous de ~800px, donc un simple
 * decalage "a droite" a largeur fixe ne suffit pas partout). Mesure reelle
 * en JS (positionScrollCue, meme script que positionBar juste en dessous -
 * meme logique deja en place pour le soulignement du titre) : decale le
 * chevron seulement si necessaire, avec 24px d'ecart garanti quelle que
 * soit la largeur, plutot qu'un point de rupture CSS fixe.
 */
.gv-hero-scroll-cue.gv-hero-scroll-cue--dodge {
	left: var(--gv-cue-left);
	right: auto;
	transform: none;
	animation-name: gv-scroll-cue-bounce-right;
}
@keyframes gv-scroll-cue-bounce-right {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(8px); }
}
@media (prefers-reduced-motion: no-preference) {
	html { scroll-behavior: smooth; }
}
.gv-hero img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	z-index: 0;
}
.gv-hero-caption {
	position: relative;
	z-index: 2;
	margin: auto var(--gutter) var(--space-m) var(--gutter);
	margin-top: auto;
	/* rem au lieu de ch : ch se base sur la (grande) police du H1 et ne
	   contraint jamais rien en pratique. */
	max-width: 50rem;
	color: #fff;
	font-family: var(--gv-font-heading);
	font-weight: 600;
	font-size: var(--h1);
	text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
}
/* Historique : ::after en bloc avec width:100% calee sur une boite parente
   retrecie au contenu (width:fit-content, puis display:table, puis
   display:inline-block - jamais fiable sur le Huawei P30, seulement casse
   en portrait quand le titre passe sur 2 lignes). Etape suivante :
   border-bottom directement sur le <span> du texte (inline) - fiable
   partout, mais donne un trait sous CHAQUE ligne au lieu d'un seul sous la
   derniere. Solution definitive : .gv-hero-caption-bar est positionne par
   JS (voir le <script> juste apres le hero) via Range.getClientRects(),
   qui donne le rectangle exact de la derniere ligne de texte affichee -
   c'est l'API que les moteurs utilisent en interne pour dessiner un
   soulignement multi-lignes, donc fiable meme sur un WebView ancien. Pas
   de largeur par defaut : le trait reste invisible tant que le JS n'a pas
   mesure (pas de flash plein-largeur). */
.gv-hero-caption-text {
	display: inline;
}
.gv-hero-caption-bar {
	position: absolute;
	height: 4px;
	background: var(--gv-accent-on-dark);
	border-radius: 2px;
	pointer-events: none;
}
/* Degrade sombre en bas de la photo d'accueil, pour la lisibilite de la legende */
.gv-hero-overlay {
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(to top, rgba(0, 0, 0, .55), transparent 45%);
}

/*
 * ---------- Contenu ----------
 * Meme structure "outer plein ecran + inner centre" que .gv-nav/.gv-footer
 * (voir plus haut) : .gv-page-content (<main>, "outer") porte .section--m
 * (padding-block:var(--section-space-m) + padding-inline:var(--gutter)) et
 * RIEN d'autre - pas de max-width/margin ici. .gv-page-inner ("inner",
 * nouveau wrapper dans le HTML) centre le contenu a content-width, sans
 * aucun padding a lui. Avant cette separation, <main> cumulait centrage
 * ET son propre gutter sur le MEME element (ordre inverse de celui du
 * header/footer), ce qui decalait tout le contenu de page (ex.
 * "Actualites" sur la home) par rapport au blason/au footer - corrige.
 */
.gv-page-inner {
	max-width: var(--content-width);
	margin: 0 auto;
}
.gv-breadcrumb { font-size: var(--text-s); color: var(--gv-head); margin-bottom: var(--space-s); }
/* Etch/ACSS met tout <a> dans un <nav> en display:block par defaut (verifie
   sur un <nav><a> classless) : casse le fil sur une ligne, d'ou l'override. */
.gv-breadcrumb a { display: inline; color: var(--gv-link) !important; text-decoration: none; }
.gv-bc-sep { margin: 0 var(--space-xs); }

/* Centre la colonne de texte au lieu de la laisser collee a gauche dans un
   conteneur bien plus large (--content-width) : le vide a droite devient
   symetrique des deux cotes, lu comme un choix de mise en page plutot qu'un
   bug (demande user - le contenu editorial reste inchange). */
.entry-content > p,
.entry-content > ul:not(.gv-rubrique-children),
.entry-content > ol { max-width: 65ch; margin-left: auto; margin-right: auto; }
/*
 * Les titres n'utilisent PAS 65ch : l'unite ch se calcule sur la taille de
 * police de l'ELEMENT LUI-MEME, donc 65ch d'un H2 en gros caracteres donne
 * une largeur bien plus grande que 65ch de texte courant (mesure : 1495px
 * vs 715px sur ce site) - le titre ne se centrait pas visuellement, bug
 * invisible tant que rien n'etait centre. rem (absolu, hors echelle typo de
 * l'element) pour aligner visuellement sur la meme largeur que les paragraphes.
 */
.entry-content > h2,
.entry-content > h3,
.entry-content > h4 { max-width: 45rem; margin-left: auto; margin-right: auto; }
/*
 * Meme raisonnement que les titres juste au-dessus (rem plutot que ch, cf.
 * commentaire) : sans ca, le wrapper de tableau (.gv-table-scroll, ajoute
 * par le filtre the_content) reste cale a gauche sur toute la largeur de
 * --content-width, très desaligne par rapport a la colonne de texte/titres
 * centree juste au-dessus/en-dessous.
 */
.entry-content > .gv-table-scroll { max-width: 45rem; margin-left: auto; margin-right: auto; }
/*
 * Meme raisonnement que .gv-table-scroll juste au-dessus : ACSS stylise deja
 * le blockquote (bordure + fond, cf. --blockquote-* dans automatic.css) mais
 * ne connait pas la largeur de colonne de CE site - sans cadrage, une
 * citation deborde sur toute la largeur de --content-width et chevauche les
 * sidecards "En 1 clic"/"Vos demarches" a droite (constate en verifiant
 * visuellement apres l'ajout d'une premiere citation sur la page Patrimoine).
 */
.entry-content > blockquote { max-width: 45rem; margin-left: auto; margin-right: auto; }
/*
 * Idem pour un bloc Image ajouté par la mairie dans l'éditeur (29/09/2026) :
 * sans cadrage, il s'étale sur toute la largeur, bien au-delà de la colonne
 * de texte. Les images des galeries (albums photo) ne sont pas concernées,
 * elles ne sont pas des enfants directs de .entry-content.
 */
.entry-content > figure.wp-block-image { max-width: 45rem; margin-left: auto; margin-right: auto; }
.entry-content { line-height: 1.65; }
/*
 * Tableaux herites de la migration CMSMS (largeur/hauteur fixees en dur en
 * inline style) : un <table> reste dimensionne a son propre contenu meme en
 * display:block (n'adopte pas le comportement "largeur=conteneur" d'un vrai
 * bloc) - poser overflow-x:auto directement sur la table ne scrolle rien,
 * elle deborde juste de la page. Le vrai conteneur scrollable est le
 * wrapper .gv-table-scroll (ajoute autour de chaque <table> par le filtre
 * PHP the_content, functions.php) : LUI se comporte comme un bloc normal
 * (largeur = conteneur), le tableau a l'interieur garde sa largeur/hauteur
 * naturelles et scrolle en entier - colonnes lisibles, swipe pour voir la
 * suite, au lieu d'etre ecrasees illisibles ("Traubach- le-Bas" coupe) par
 * un ancien "width:auto!important" directement sur la table.
 */
.gv-table-scroll {
	max-width: 100%;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}
.gv-table-scroll table { max-width: none; }

/*
 * Galeries (bloc natif Gutenberg core/gallery, utilise sur les 3 albums
 * photos) : ce site ne charge pas la feuille de style bloc de coeur WP
 * (verifie : aucun <link wp-block-library> dans le <head>), donc la grille
 * native du bloc n'existe pas ici. On la refait avec le meme mecanisme de
 * grille fluide ACSS que .gv-rubrique-children/.gv-footer-cols
 * (var(--grid-auto-N), deja utilise ailleurs sur le site) plutot que
 * charger toute la feuille de bloc WP pour une seule regle.
 */
.wp-block-gallery {
	display: grid;
	grid-template-columns: var(--grid-auto-3);
	gap: var(--space-s);
	margin: 0;
	padding: 0;
	list-style: none;
	max-width: none;
}
.wp-block-gallery.columns-2 { grid-template-columns: var(--grid-auto-2); }
.wp-block-gallery.columns-4 { grid-template-columns: var(--grid-auto-4); }
/* WP imprime un petit CSS inline propre au bloc galerie (id="wp-block-gallery-inline-css")
   qui met chaque figure en flex + justify-content:center, plus specifique que nos regles :
   ca centre l'image dans une cellule de grille etiree, creant un vide en haut/bas. Override. */
.wp-block-gallery .wp-block-image { margin: 0; display: block !important; width: 100% !important; max-width: 100% !important; }
.wp-block-gallery.is-cropped .wp-block-image img {
	width: 100%;
	height: 100%;
	aspect-ratio: 1;
	object-fit: cover;
	display: block;
	border-radius: 6px;
	cursor: pointer;
}
.wp-block-gallery figcaption {
	margin-top: var(--space-2xs, var(--space-xs));
	font-size: var(--text-xs);
	color: var(--gv-head);
}
.gv-lb-trigger { cursor: pointer; }

/*
 * ---------- Lightbox (assets/lightbox.js) ----------
 * Le JS construit deja tout le DOM (#gv-lightbox, boutons, figure, legende,
 * compteur) et pose les classes d'etat, mais aucun CSS ne l'habillait
 * jusqu'ici : sans position:fixed, l'overlay s'inserait simplement dans le
 * flux de la page (verifie en l'ouvrant : #gv-lightbox restait en
 * position:static, visible seulement en scrollant tout en bas de la page).
 */
#gv-lightbox {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, .92);
	padding: var(--space-l);
	opacity: 1;
	transition: opacity .3s ease;
}
#gv-lightbox.gv-lb-closing { opacity: 0; }

.gv-lb-figure {
	margin: 0;
	max-width: 90vw;
	max-height: 85vh;
	display: flex;
	flex-direction: column;
	align-items: center;
}
.gv-lb-img {
	display: block;
	max-width: 90vw;
	max-height: 80vh;
	width: auto;
	height: auto;
	object-fit: contain;
	border-radius: 4px;
	opacity: 0;
	transform: scale(.94);
	transition: opacity .25s ease, transform .25s ease;
}
.gv-lb-img.gv-lb-loaded { opacity: 1; transform: scale(1); }

@keyframes gv-lb-out-to-left  { from { opacity: 1; transform: translateX(0); }    to { opacity: 0; transform: translateX(-40px); } }
@keyframes gv-lb-out-to-right { from { opacity: 1; transform: translateX(0); }    to { opacity: 0; transform: translateX(40px); } }
@keyframes gv-lb-in-from-left  { from { opacity: 0; transform: translateX(-40px); } to { opacity: 1; transform: translateX(0); } }
@keyframes gv-lb-in-from-right { from { opacity: 0; transform: translateX(40px); }  to { opacity: 1; transform: translateX(0); } }
.gv-lb-img.gv-lb-out-left  { animation: gv-lb-out-to-left .35s ease forwards; }
.gv-lb-img.gv-lb-out-right { animation: gv-lb-out-to-right .35s ease forwards; }
.gv-lb-img.gv-lb-in-left   { animation: gv-lb-in-from-left .35s ease forwards; }
.gv-lb-img.gv-lb-in-right  { animation: gv-lb-in-from-right .35s ease forwards; }

.gv-lb-caption {
	margin-top: var(--space-xs);
	color: #fff;
	font-size: var(--text-s);
	text-align: center;
	max-width: 65ch;
}
.gv-lb-counter {
	position: absolute;
	top: var(--space-s);
	left: 50%;
	transform: translateX(-50%);
	color: rgba(255, 255, 255, .75);
	font-size: var(--text-xs);
}
.gv-lb-btn {
	position: absolute;
	background: rgba(255, 255, 255, .12);
	color: #fff;
	border: none;
	border-radius: 50%;
	width: 44px;
	height: 44px;
	font-size: 1.5rem;
	line-height: 1;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background .15s ease;
}
.gv-lb-btn:hover, .gv-lb-btn:focus-visible { background: rgba(255, 255, 255, .25); }
.gv-lb-close { top: var(--space-s); right: var(--space-s); }
.gv-lb-prev  { left: var(--space-s); top: 50%; transform: translateY(-50%); }
.gv-lb-next  { right: var(--space-s); top: 50%; transform: translateY(-50%); }
@media (max-width: 600px) {
	.gv-lb-btn { width: 38px; height: 38px; font-size: 1.25rem; }
	.gv-lb-prev, .gv-lb-next { top: auto; bottom: var(--space-s); transform: none; }
	.gv-lb-prev { left: var(--space-s); }
	.gv-lb-next { right: var(--space-s); }
}

/*
 * Rythme vertical du contenu : rythme fluide ACSS (--space-*), pas de valeur
 * en dur. Les titres respirent plus que les paragraphes (rupture de
 * section) ; le tout premier enfant ne porte pas de marge haute.
 */
.entry-content > * + * { margin-top: var(--space-m); }
.entry-content > h2 { margin-top: var(--space-xl); }
.entry-content > h3 { margin-top: var(--space-l); }
.entry-content > :first-child { margin-top: 0; }

/* Page Contact en 2 colonnes fixes : var(--grid-auto-2) suppose un conteneur
   large de exactement --content-width (pense pour des grilles de cartes qui
   s'adaptent) - ici le conteneur EST --content-width pile, l'arrondi de la
   formule auto-fit fait retomber sur 1 colonne. Colonnes explicites pour un
   partage garanti 50/50, espacement lui reste une variable ACSS. */
.gv-contact-cols {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-l);
	align-items: start;
}
@media (max-width: 900px) {
	.gv-contact-cols { grid-template-columns: 1fr; }
}
.gv-contact-info > * + *,
.gv-contact-form > * + * { margin-top: var(--space-m); }
.gv-contact-info > h2,
.gv-contact-form > h2 { margin-top: var(--space-xl); }
.gv-contact-info > :first-child,
.gv-contact-form > :first-child { margin-top: 0; }

/*
 * Contenu importe (ancien CMS) : images en `float` + `padding` inline dans
 * le texte d'un <p>, ce qui ecrasait la colonne de texte a moins de 65ch
 * effectifs et melangeait image/texte dans le meme bloc. On neutralise le
 * float legacy pour que chaque image forme son propre bloc, separe du
 * texte, avec le meme rythme vertical que le reste du contenu.
 */
.entry-content img {
	display: block;
	float: none !important;
	margin: var(--space-s) auto !important;
	padding: 0 !important;
	max-width: 100%;
	height: auto;
	border-radius: 6px;
}

/* Grille auto-responsive ACSS (--grid-auto-2) : se rearrange seule sans
   media query a ecrire, sur la base de la largeur reelle du site. */
.gv-rubrique-children {
	list-style: none;
	margin: var(--space-m) 0 0;
	padding: 0;
	display: grid;
	grid-template-columns: var(--grid-auto-2);
	gap: var(--space-s);
}
.gv-rubrique-children li {
	background: #fff;
	border: 1px solid rgba(0, 0, 0, .08);
	border-radius: 6px;
	padding: var(--space-s);
}
.gv-rubrique-children a { font-weight: 600; text-decoration: none; }
.gv-rubrique-child-excerpt { color: var(--gv-head); font-size: var(--text-s); margin-top: var(--space-xs); }

/* ---------- Blocs actualite / agenda ---------- */
.gv-titre-section { margin-bottom: var(--space-s); }
.gv-bloc-actu { border-left: 3px solid var(--gv-accent); padding: var(--space-xs) 0 var(--space-xs) var(--space-s); margin-bottom: var(--space-m); }
.gv-bloc-titre { margin: 0 0 var(--space-xs); }

/* ---------- Quicklinks : pile d'onglets fixes (accordeon <details>) ---------- */
.gv-sidecards {
	position: fixed;
	top: 50%;
	right: 0;
	transform: translateY(-50%);
	z-index: 95;
	display: flex;
	flex-direction: column;
	gap: 2px;
}
.gv-sidecard { position: relative; }
.gv-sidecard-tab {
	display: block;
	list-style: none;
	cursor: pointer;
	background: var(--secondary-semi-dark);
	color: #fff;
	font-weight: 600;
	font-size: var(--text-xs);
	padding: var(--space-xs) var(--space-s);
	border-radius: 8px 0 0 8px;
	white-space: nowrap;
	box-shadow: var(--gv-shadow-soft);
}
.gv-sidecard-tab::-webkit-details-marker,
.gv-sidecard-tab::marker { display: none; content: ''; }
/* .gv-sidecard-tel est un <a> (pas un <details>) : la regle globale
   a{color:var(--gv-link)!important} l'emporterait sinon sur la couleur
   blanche du bandeau - override cible, meme mecanisme deja utilise sur
   les autres liens du site face a cette regle globale. */
.gv-sidecard-tel { text-decoration: none; }
.gv-sidecard-tel .gv-sidecard-tab { color: #fff !important; }
/* ACSS pin la teinte de base a L=0.65 (dans le gamut sRGB pour toute teinte) ;
   un assombrissement via filter evite de retester le gamut a chaque palette. */
.gv-sidecard[open] .gv-sidecard-tab,
.gv-sidecard-tab:hover { filter: brightness(0.88); }
.gv-sidecard-panel {
	position: absolute;
	top: 0;
	right: 100%;
	width: min(22rem, 85vw);
	background: #fff;
	color: var(--gv-text);
	padding: var(--space-m) var(--space-s) var(--space-s);
	border-radius: 8px 0 0 8px;
	box-shadow: var(--gv-shadow-soft);
	font-size: var(--text-xs);
}
.gv-sidecard-panel ul { margin: 0; padding-left: 1.1em; }
.gv-sidecard-panel li::marker { color: var(--gv-accent); }
.gv-sidecard-close {
	position: absolute;
	top: var(--space-2xs, var(--space-xs));
	right: var(--space-2xs, var(--space-xs));
	border: none;
	background: transparent;
	color: var(--gv-text);
	font-size: var(--text-m, 1.25rem);
	line-height: 1;
	cursor: pointer;
	padding: var(--space-3xs, 2px);
}
.gv-sidecard-close:hover { color: var(--gv-hover); }

@media (max-width: 899px) {
	.gv-sidecards {
		top: auto;
		bottom: 0;
		left: 0;
		right: 0;
		transform: none;
		flex-direction: row;
	}
	/* position:static : le panneau (absolute) se cale sur .gv-sidecards (fixed) et non sur son onglet, pour couvrir toute la largeur de la barre */
	.gv-sidecard { flex: 1; position: static; }
	.gv-sidecard-tab {
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 8px 8px 0 0;
		text-align: center;
		white-space: normal;
	}
	.gv-sidecard-panel {
		top: auto;
		right: 0;
		left: 0;
		bottom: 100%;
		width: auto;
		max-height: 60vh;
		overflow-y: auto;
		border-radius: 8px 8px 0 0;
	}
	/* La barre du bas ne doit pas cacher la fin de la page */
	.gv-footer { padding-bottom: calc(var(--space-xxl) + var(--space-s)); }
}

/* ---------- IntraMuros ---------- */
.gv-intramuros { font-family: var(--gv-font-body); }
/*
 * Le widget IntraMuros est un script tiers async qui monte son contenu en
 * React APRES le premier rendu : #intramuros_news part vide (0px), puis se
 * remplit d'un coup une fois les actus chargees. Sans reservation d'espace,
 * tout ce qui suit (le reste de la home + le footer en entier) se decale
 * brutalement vers le bas - constate via PageSpeed/Lighthouse : c'etait la
 * cause du plus gros score de CLS de la page (0.29 attribue au <footer>,
 * qui n'a lui-meme rien de casse, il ne fait que subir le decalage).
 * Hauteurs mesurees en prod (6 actus, mode grille) : ~1450px mobile,
 * ~735px desktop - valeurs ci-dessous legerement en dessous par prudence
 * (mieux vaut un residu de decalage minime que reserver trop et laisser un
 * grand vide si IntraMuros a un jour moins d'actus ou est indisponible).
 */
/*
 * Recalé le 29/09/2026 : le nombre d'actus varie (2 à ce jour, pas 6) et
 * 700/1300px laissaient un grand vide sous les cartes. On ne réserve plus
 * qu'UNE rangée de cartes (cartes compactes depuis le 29/09 : ~140px) : le minimum sûr dès qu'il y a au moins une actu.
 * Un petit décalage résiduel est accepté quand il y en a davantage.
 */
#intramuros_news { min-height: 130px; }
/*
 * Présentation du fil IntraMuros (2026-09-29) : bloc aligné sur la colonne
 * de lecture (45rem, comme le contenu natif au-dessus), titre H3 + ligne de
 * source, et chaque actu dans une vraie carte (fond blanc, liseré vert en
 * haut comme .gv-bloc-actu). Les styles inline posés par le widget (padding,
 * fond transparent, bordure 0) imposent les !important.
 */
/* <section> reçoit d'office l'espacement de section d'Automatic.css
   (padding 90px × 80px + flex gap 67px en desktop) : annulé, ce bloc est
   un sous-bloc de contenu. */
section.gv-intramuros { display: block; max-width: 45rem; margin: var(--space-l) auto 0; padding: 0; }
.gv-infos-titre { margin: 0 0 var(--space-s); }
/* Mention source + liens stores, sous les cartes, en discret. */
.gv-infos-source { margin: var(--space-s) 0 0; font-size: var(--text-xs); color: var(--gv-head); }
.gv-store { display: inline-flex; align-items: center; gap: .3em; margin-left: .6em; white-space: nowrap; }
.gv-store svg { flex: none; }
.gv-infos-source .gv-store:first-of-type { margin-left: 0; }
/* wpautop entoure les <script> du widget de <p>/<br> vides : neutralisés. */
.gv-intramuros > p:not(.gv-infos-source) { margin: 0; }
.gv-intramuros > p > br { display: none; }
/* Compense le padding des cellules de la grille : bords des cartes alignés sur le titre. */
.gv-intramuros #intramuros_news .MuiGrid-container { margin-inline: calc(-1 * var(--space-xs)); width: auto; align-items: stretch !important; }
.gv-intramuros #intramuros_news .MuiPaper-root {
	box-sizing: border-box;
	background-color: #fff !important;
	border-top: 3px solid var(--gv-accent) !important;
	border-radius: 8px !important;
	box-shadow: var(--gv-shadow-soft);
	transition: box-shadow .2s, transform .2s;
}
.gv-intramuros #intramuros_news .MuiPaper-root:hover { box-shadow: 0 6px 18px rgba(0, 0, 0, .12); transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
	.gv-intramuros #intramuros_news .MuiPaper-root { transition: none; }
	.gv-intramuros #intramuros_news .MuiPaper-root:hover { transform: none; }
}
/* Carte en 2 colonnes : vignette à gauche, titre + date à droite. */
.gv-intramuros #intramuros_news .MuiCardActionArea-root {
	display: grid !important;
	grid-template-columns: 56px 1fr;
	grid-template-rows: auto auto;
	column-gap: var(--space-s);
	align-items: center;
	align-content: center;
	height: 100%;
	text-align: left !important;
	padding: var(--space-s) !important;
}
.gv-intramuros #intramuros_news .MuiCardActionArea-root > .MuiGrid-item {
	grid-row: 1 / span 2;
	width: 56px;
	padding: 0 !important;
}
.gv-intramuros #intramuros_news .MuiCardActionArea-root > .MuiGrid-item > div,
.gv-intramuros #intramuros_news .MuiCardActionArea-root > .MuiGrid-item img {
	width: 56px !important;
	height: 56px !important;
	margin: 0 !important;
	object-fit: cover;
	border-radius: 6px;
}
.gv-intramuros #intramuros_news .MuiCardActionArea-root > p {
	grid-column: 2;
	margin: 0 !important;
	text-align: left !important;
}
/* Logo commune chargé en différé par le widget : pas de fond gris dans la vignette. */
.gv-intramuros #intramuros_news .MuiCardActionArea-root img[src*="/city_logo/"] { background: transparent; object-fit: contain !important; }
/* Cartes d'une même rangée à la même hauteur. */
.gv-intramuros #intramuros_news .MuiGrid-container > .MuiGrid-item { display: flex; }
.gv-intramuros #intramuros_news .MuiGrid-container > .MuiGrid-item > .MuiPaper-root { flex: 1; height: auto; }
.gv-intramuros #intramuros_news .MuiCardActionArea-root > p:first-of-type { -webkit-line-clamp: 3 !important; }
.gv-intramuros #intramuros_news .MuiCardActionArea-root > p + p { margin-top: var(--space-3xs) !important; }
.gv-intramuros #intramuros_news .MuiGrid-item { padding: var(--space-xs) !important; }
.gv-intramuros #intramuros_news button:hover,
.gv-intramuros #intramuros_news button:focus { background-color: transparent !important; color: inherit !important; }
.gv-intramuros #intramuros_news img[src*="/city_logo/"] {
	object-fit: contain !important;
	max-width: 110px;
	max-height: 110px;
	margin: var(--space-m) auto 0;
	background: var(--gv-bg);
}
/*
 * Depuis la MAJ IntraMuros du 14/09/2026 (actualite.js 5.1.0 modifié sur
 * place), une actu sans photo n'affiche plus le logo de la commune : le
 * widget laisse un <div> vide forcé à height:300px !important (classe JSS
 * générée, news-jssN, instable → ciblage par la structure + :empty).
 * On y remet le blason (en vignette, cf. cartes ci-dessus) au lieu de
 * 300px de vide au-dessus de chaque titre. Une actu AVEC photo n'est pas
 * concernée (le div contient alors l'image, il n'est plus :empty).
 */
.gv-intramuros #intramuros_news .MuiCardActionArea-root > .MuiGrid-item > div:empty {
	background: url("assets/img/blason-guevenatten.webp") center / contain no-repeat;
}
@media (min-width: 1200px) {
	.gv-intramuros .MuiGrid-grid-lg-4 {
		flex-grow: 0 !important;
		flex-basis: 50% !important;
		max-width: 50% !important;
	}
}

/* ---------- Home ---------- */
/* Ecart avec le hero au-dessus : sans lui le titre "Actualites" colle
   directement au bandeau. Descendu de l'echelle --section-space-* (reservee
   aux vraies coupures de section, comme avant le footer) vers l'echelle
   --space-* (rythme de contenu), le hero n'etant pas une section a part
   entiere ici - encore un cran en dessous a la demande du user. */
.gv-cols { padding-top: var(--space-m); }

/*
 * Contenu natif de la home (post_content, ajoutable via l'editeur WP par
 * le maire) : place entre le titre "Actualites" et le flux IntraMuros
 * (voir guevenatten_render_home_actu() dans functions.php). Le H2 gere
 * deja l'ecart au-dessus (.gv-titre-section margin-bottom) ; ici on gere
 * juste l'ecart en dessous, meme echelle que .gv-bloc-actu (articles
 * voisins) plutot qu'une valeur en dur.
 */
.gv-accueil .gv-col-gauche > .entry-content { margin-bottom: var(--space-m); }

/* ---------- Footer ---------- */
/*
 * Meme structure "outer plein ecran + inner centre" que .gv-nav/.gv-nav-inner
 * (voir plus haut) : le gutter se pose UNE FOIS ici, sur l'element plein
 * ecran, avant que les bandes internes ne centrent leur contenu - pas
 * l'inverse. C'est cet ordre des operations (gutter D'ABORD, centrage
 * ENSUITE) qui fait coincider exactement le bord gauche du footer avec
 * celui du header a toutes les largeurs, y compris tres grand ecran (le
 * centrage seul, gutter applique APRES, donnait un decalage different -
 * constate et corrige).
 */
.gv-footer { background: var(--gv-footer-bg); color: #f1ecdf; margin-top: var(--section-space-s); padding-inline: var(--gutter); }
/* Meme variable --gv-accent-on-dark que les liens du header (deja
   identique) ; il manquait juste l'etat survol - sans lui, .gv-footer a
   (specificite egale a la regle generique a:hover, mais plus tardive dans
   le fichier) gagnait aussi au survol et figeait la couleur en permanence. */
.gv-footer a { color: var(--gv-accent-on-dark) !important; }
.gv-footer a:hover, .gv-footer a:focus { color: #fff !important; }
/*
 * Hauteur reduite (demande user) : padding-block et gap descendus de
 * l'echelle "section" (--section-space-*, pensee pour de grandes zones)
 * vers l'echelle standard (--space-*, plus petite) - meme logique que
 * .header--xs pour la nav. .text--xs (vraie classe ACSS) sur les colonnes
 * reduit aussi la hauteur du contenu texte lui-meme, pas seulement les
 * marges autour.
 */
.gv-footer-cols {
	max-width: var(--content-width);
	margin: 0 auto;
	padding-block: var(--space-m);
	display: grid;
	grid-template-columns: var(--grid-auto-3);
	gap: var(--space-s);
}
.gv-footer-col h3 { color: #fff; font-size: var(--text-m); margin: 0 0 var(--space-xs); }
.gv-footer-col ul { list-style: none; margin: 0; padding: 0; }
.gv-footer-col li { margin-bottom: var(--space-xs); }
.gv-link-todo { opacity: .6; }
.gv-footer-bottom {
	border-top: 1px solid rgba(255, 255, 255, .15);
	padding-block: var(--space-xs);
	max-width: var(--content-width);
	margin: 0 auto;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-xs) var(--space-s);
	justify-content: space-between;
}
/* --text-xs est deja le plus petit palier de l'echelle ACSS (verifie dans
   automatic.css compile, pas de --text-2xs) : derive proportionnellement de
   ce token plutot qu'une valeur en px deconnectee de l'echelle. */
.gv-footer-bottom p { margin: 0; font-size: calc(var(--text-xs) * 0.85); }
/*
 * PageSpeed (audit accessibilite "liens identifiables") : le lien "JBK
 * Agency" dans "Site realise par JBK Agency" n'a que 1,3:1 de contraste
 * avec le texte autour (vert clair sur creme clair, mesure via canvas
 * getImageData - les deux couleurs individuellement sont lisibles sur le
 * fond fonce du footer, mais quasi indiscernables l'une de l'autre sans
 * soulignement). Fix : soulignement, le moyen non-couleur standard de
 * distinguer un lien dans un bloc de texte.
 */
.gv-footer-credits a { text-decoration: underline; }
/*
 * Cible tactile trop petite (audit "bonnes pratiques" PageSpeed) sur les
 * liens tel:/mailto: de l'adresse du footer, empiles par <br> en texte
 * tres petit (.text--xs) : hauteur de ligne insuffisante pour un doigt.
 * Padding vertical transparent sans changer la taille visible du texte.
 */
.gv-footer-col p a { display: inline-block; padding-block: .25em; }
