/* =========================================================================
   Consultant IT — feuille de style principale
   Clair, minimaliste, touches tech discrètes.
   Mobile-first. Variables centralisées dans :root.
   ========================================================================= */

/* ----------------------------------------------------------------------
   1. Variables (charte « Signal », cf. DESIGN-SYSTEM-HANDOFF.md +
      SPECS-TECHNIQUES.md) — tout se change ici.
   ---------------------------------------------------------------------- */
:root {
	/* Couleurs — palette OKLCH « Signal ». */
	--color-white: #ffffff;              /* blanc pur : nav, cartes de la grille services */
	--color-bg: oklch(98% 0.004 240);     /* fond de page */
	--color-surface: oklch(96% 0.006 240); /* fond de sections / cartes */
	--color-text: oklch(20% 0.02 240);    /* encre — texte principal */
	--color-text-muted: oklch(50% 0.01 240); /* texte secondaire */
	--color-accent: oklch(48% 0.09 195);  /* sarcelle — accent principal, liens, CTA */
	--color-accent-hover: oklch(40% 0.09 195);
	--color-marine: oklch(20% 0.05 250);  /* fonds forts, nav active, texte fort */
	--color-border: oklch(90% 0.005 240);
	--color-alert: oklch(58% 0.14 25);    /* erreurs de formulaire */

	/* Fonds de section (accueil, en alternance) */
	--color-section-neutral: oklch(98% 0.004 240);
	--color-section-sarcelle: oklch(95% 0.02 195);
	--color-section-marine: oklch(94% 0.015 250);
	--color-section-bluegray: oklch(96% 0.01 220);

	/* Nuances carrousel de services (alternance stricte position par position) */
	--color-ticker-sarcelle: oklch(91% 0.045 195);
	--color-ticker-marine: oklch(90% 0.035 250);

	/* Typographie — polices locales dans assets/fonts/, avec repli système. */
	--font-heading: 'Sora', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
	--font-body: 'Work Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
	--font-mono: 'JetBrains Mono', ui-monospace, 'Fira Code', 'SFMono-Regular', Menlo, Consolas, monospace;

	/* Layout */
	--content-max: 1200px;
	--gutter: 1.5rem;
	--section-gap: 4rem;

	/* Divers */
	--radius: 6px;
	--transition: 0.2s ease;
}

/* ----------------------------------------------------------------------
   2. Reset léger
   ---------------------------------------------------------------------- */
*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	font-family: var(--font-body);
	font-size: 1rem;
	line-height: 1.65;
	color: var(--color-text);
	background: var(--color-bg);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

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

a {
	color: var(--color-accent);
	text-decoration: none;
	transition: color var(--transition);
}

a:hover {
	color: var(--color-accent-hover);
	text-decoration: underline;
}

ul,
ol {
	padding-left: 1.25rem;
}

/* ----------------------------------------------------------------------
   3. Typographie
   ---------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
	font-family: var(--font-heading);
	font-weight: 700;
	line-height: 1.2;
	margin: 0 0 0.75em;
	color: var(--color-text);
}

/* Échelle « Signal » : H1 800/40–54px, H2 700/28–36px, H3 600/18–21px. */
h1 { font-weight: 800; font-size: clamp(2.5rem, 5vw, 3.375rem); }
h2 { font-weight: 700; font-size: clamp(1.75rem, 3.5vw, 2.25rem); }
h3 { font-weight: 600; font-size: clamp(1.125rem, 2vw, 1.3125rem); }

p {
	margin: 0 0 1.25rem;
}

/* Touche tech : monospace pour petits accents uniquement. */
.mono,
.section-number {
	font-family: var(--font-mono);
	font-size: 0.85em;
	letter-spacing: 0.02em;
	color: var(--color-text-muted);
}

.section-number {
	color: var(--color-accent);
}

/* ----------------------------------------------------------------------
   4. Layout — conteneur centré
   ---------------------------------------------------------------------- */
.container {
	width: 100%;
	max-width: var(--content-max);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.site-main {
	display: block;
}

.content-area {
	padding-block: var(--section-gap);
}

.entry-content > * {
	margin-bottom: 1.25rem;
}

.page-header {
	padding-top: var(--section-gap);
}

/* Lien de retour vers "Services" (pôles uniquement) : discret, dans le flux
   normal AVANT le titre — jamais en overlay/position absolue, donc jamais
   de superposition possible avec le titre ou un autre texte. */
.page-back-link {
	display: inline-block;
	margin-bottom: 1rem;
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 0.875rem;
	color: var(--color-text-muted);
}

.page-back-link:hover {
	color: var(--color-accent);
	text-decoration: none;
}

/* Taille de titre de page unique, sur toutes les pages (Contact, À propos,
   Services et ses pôles, Références, mentions légales…) — auparavant
   seules les pages Services avaient cette taille réduite (règle plus bas),
   les autres retombaient sur le h1 générique, plus grand : incohérent. */
.page-title {
	font-size: clamp(2.25rem, 4vw, 2.75rem); /* 40–44px */
}

/* ----------------------------------------------------------------------
   Pages Services (vue d'ensemble + pages dédiées) — cf. SPECS-TECHNIQUES.md.
   Repère posé sur <body> par inc/services-grid.php (vnn_body_class_services).
   ---------------------------------------------------------------------- */
body.vnn-service-page .page-header {
	padding: 64px 96px 44px;
}

/* Vue d'ensemble (page Services elle-même, pas ses pages enfants) : plus de
   label "// Catalogue de services" au-dessus de l'accroche → le padding-bas
   hérité de la règle ci-dessus (pensé pour ce label) laisse un vide trop
   grand avant le paragraphe d'intro. On le resserre, uniquement ici (les
   pages enfants gardent leur label "// SERVICE" et donc leur espacement). */
body.vnn-services-overview .page-header {
	padding-bottom: 8px;
}

/* Paragraphe d'intro : même largeur que la grille des 2 pôles juste en
   dessous (pas de plafond en "ch" comme le .lead générique, sinon le texte
   reste plus étroit que les cartes). */
body.vnn-services-overview .lead {
	max-width: none;
}

body.vnn-service-page .entry-content {
	padding-inline: 96px;
}

/* Corps d'une page dédiée (amorce + lead + liste) : largeur de lecture
   restreinte, cf. grille générale (820–900px pour le texte). */
.service-page__body {
	max-width: 880px;
}

/* Liste à puces 2 colonnes des pages dédiées, puce = point coloré 7×7px.
   En colonnes CSS (pas grid) : avec une grille 2 colonnes classique, une
   ligne de la grille se cale sur son élément le plus haut — dès qu'un
   intitulé passe sur 2 lignes, ça laisse un trou dans la colonne voisine.
   Les colonnes CSS remplissent chaque colonne indépendamment (comme un
   journal), donc plus de trou, sans avoir à dupliquer la liste en 2 blocs. */
.service-bullets {
	list-style: none;
	margin: 1.5rem 0 0;
	padding: 0;
	column-count: 2;
	column-gap: 32px;
}

.service-bullets li {
	position: relative;
	padding-left: 1.1rem;
	margin: 0 0 14px;
	break-inside: avoid; /* un intitulé ne se coupe jamais entre 2 colonnes */
}

.service-bullets li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--color-accent);
}

@media (max-width: 640px) {
	.service-bullets {
		column-count: 1;
	}
	body.vnn-service-page .page-header,
	body.vnn-service-page .entry-content {
		padding-inline: 1.5rem;
	}
}

/* ----------------------------------------------------------------------
   5. Boutons — convention unique (cf. CLAUDE.md section 7)
   ---------------------------------------------------------------------- */
.btn,
.wp-block-button__link {
	display: inline-block;
	font-family: var(--font-body);
	font-size: 1rem;
	font-weight: 600;
	line-height: 1.2;
	padding: 0.875rem 1.75rem; /* 14px / 28px — dans la fourchette 13–16px / 26–32px */
	border-radius: var(--radius);
	cursor: pointer;
	text-decoration: none;
	transition: background var(--transition), color var(--transition), border-color var(--transition);
}

/* Désactivé */
.btn:disabled,
.btn--disabled,
.wp-block-button__link:disabled {
	background: var(--color-surface);
	color: var(--color-text-muted);
	border-color: transparent;
	cursor: not-allowed;
}

.btn:disabled:hover,
.btn--disabled:hover,
.wp-block-button__link:disabled:hover {
	background: var(--color-surface);
	color: var(--color-text-muted);
}

.btn:hover,
.wp-block-button__link:hover {
	text-decoration: none;
}

/* Primaire */
.btn--primary,
.wp-block-button__link {
	background: var(--color-accent);
	color: #ffffff;
	border: 1px solid transparent;
}

.btn--primary:hover,
.wp-block-button__link:hover {
	background: var(--color-accent-hover);
	color: #ffffff;
}

/* Secondaire — contour marine (cf. handoff : distinct de l'accent sarcelle). */
.btn--secondary,
.is-style-outline .wp-block-button__link {
	background: transparent;
	color: var(--color-marine);
	border: 1.5px solid var(--color-marine);
	padding: calc(0.875rem - 0.5px) calc(1.75rem - 0.5px); /* compense le contour +0.5px vs primaire */
}

.btn--secondary:hover,
.is-style-outline .wp-block-button__link:hover {
	background: var(--color-surface);
	color: var(--color-marine);
}

/* Lien — texte sarcelle, soulignement 2px sarcelle (pas de fond/contour). */
.btn--link {
	display: inline-block;
	font-family: var(--font-body);
	font-weight: 600;
	color: var(--color-accent);
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
	padding: 0;
	background: none;
	border: none;
}

.btn--link:hover {
	color: var(--color-accent-hover);
}

/* Focus visible partout (accessibilité). */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
	outline: 2px solid var(--color-accent);
	outline-offset: 2px;
}

/* ----------------------------------------------------------------------
   6. En-tête du site
   ---------------------------------------------------------------------- */
.site-header {
	position: sticky;
	top: 0;
	z-index: 1000;
	border-bottom: 1px solid var(--color-border);
	background: var(--color-white); /* barre blanche, cf. handoff nav */
}

.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	min-height: 72px;
	padding-block: 0.5rem;
	padding-inline: 40px;
	flex-wrap: wrap;
}

.site-branding {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

/* Bloc texte de marque à côté du logo : nom (plus grand) + accroche sur 2 lignes. */
.site-branding__text {
	display: flex;
	flex-direction: column;
	justify-content: center;
	line-height: 1.25;
}

.site-title {
	font-family: var(--font-heading);
	font-weight: 700;
	font-size: 1.125rem; /* 18px */
}

.site-title a {
	color: var(--color-text);
}

.site-title a:hover {
	color: var(--color-accent);
	text-decoration: none;
}

.site-tagline {
	font-family: var(--font-body);
	font-size: 0.75rem; /* 12px */
	font-weight: 400;
	color: oklch(55% 0.01 240);
}

.custom-logo {
	/* Logo blason (portrait) : 38px dans la nav (cf. handoff — sur l'accueil,
	   le logo est retiré de la nav et affiché en grand dans le hero). */
	max-height: 38px;
	width: auto;
}

.custom-logo-link {
	display: inline-flex;
	align-items: center;
}

/* Navigation — liens en pastille (cf. handoff nav). */
.main-navigation__list {
	list-style: none;
	display: flex;
	align-items: center;
	gap: 30px;
	margin: 0;
	padding: 0;
}

.main-navigation__list > li {
	position: relative;
}

.main-navigation__list a {
	display: inline-block;
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 0.875rem; /* 14px */
	color: var(--color-text);
	padding: 10px 16px;
	border-radius: 24px;
	transition: background var(--transition), color var(--transition), box-shadow var(--transition);
}

.main-navigation__list a:hover,
.main-navigation .current-menu-item > a,
.main-navigation__list a.is-current,
.main-navigation__list a[aria-expanded="true"] {
	background: var(--color-white);
	box-shadow: 0 4px 14px rgba(20, 30, 45, 0.12);
	color: var(--color-accent);
	text-decoration: none;
}

.main-navigation__empty {
	font-size: 0.9rem;
	color: var(--color-text-muted);
	margin: 0;
}

/* Bouton menu (mobile) */
.menu-toggle {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 44px;
	height: 44px;
	padding: 0;
	background: transparent;
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	cursor: pointer;
}

.menu-toggle__bar,
.menu-toggle__bar::before,
.menu-toggle__bar::after {
	display: block;
	width: 22px;
	height: 2px;
	margin-inline: auto;
	background: var(--color-text);
	transition: transform var(--transition), opacity var(--transition);
	content: '';
}

.menu-toggle__bar {
	position: relative;
}

.menu-toggle__bar::before { position: absolute; top: -7px; left: 0; }
.menu-toggle__bar::after  { position: absolute; top: 7px; left: 0; }

/* ----------------------------------------------------------------------
   7. Pied de page
   ---------------------------------------------------------------------- */
.site-footer {
	margin-top: var(--section-gap);
	border-top: 1px solid var(--color-border);
	background: var(--color-surface);
}

.site-footer__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	padding-block: 1.25rem;
}

.site-footer__name {
	font-weight: 700;
}

.site-footer__desc {
	margin: 0.25rem 0 0;
	color: var(--color-text-muted);
	font-size: 0.95rem;
}

.site-footer__nav {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 1.25rem;
	margin: 0;
	padding: 0;
}

.site-footer__copy {
	margin: 0;
	color: var(--color-text-muted);
	font-size: 0.9rem;
}

/* ----------------------------------------------------------------------
   8. Page 404
   ---------------------------------------------------------------------- */
.error-404 {
	text-align: center;
}

.error-404__code {
	font-size: 3rem;
	margin-bottom: 0.5rem;
}

/* ----------------------------------------------------------------------
   9. Accessibilité — texte réservé aux lecteurs d'écran
   ---------------------------------------------------------------------- */
.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 1000;
	background: var(--color-accent);
	color: #fff;
	padding: 0.5rem 1rem;
	border-radius: 0 0 var(--radius) 0;
}

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

/* ----------------------------------------------------------------------
   10. Pagination
   ---------------------------------------------------------------------- */
.pagination {
	display: flex;
	gap: 0.5rem;
	margin-top: 2rem;
	flex-wrap: wrap;
}

.pagination .page-numbers {
	display: inline-block;
	padding: 0.4rem 0.75rem;
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	color: var(--color-text);
}

.pagination .page-numbers.current {
	background: var(--color-accent);
	color: #fff;
	border-color: var(--color-accent);
}

/* ----------------------------------------------------------------------
   11. Responsive — menu mobile
   ---------------------------------------------------------------------- */
@media (max-width: 768px) {
	/* Le burger ne doit jamais passer sous le logo : sans nowrap, dès que le
	   bloc marque (logo + nom + accroche) est un peu large, le flex-wrap de
	   .site-header__inner (pensé pour le desktop) fait passer le burger à la
	   ligne suivante. min-width:0 sur .site-branding permet en plus au bloc
	   marque de rétrécir/passer son propre texte à la ligne si besoin, plutôt
	   que de pousser le burger hors du bandeau. */
	.site-header__inner {
		flex-wrap: nowrap;
		padding-inline: 1.25rem;
	}
	.site-branding {
		min-width: 0;
		flex: 1 1 auto;
	}
	.site-branding__text {
		min-width: 0;
	}
	.menu-toggle {
		display: flex;
		flex: 0 0 auto;
	}

	.main-navigation {
		flex-basis: 100%;
		display: none;
	}

	.main-navigation.is-open {
		display: block;
	}

	.main-navigation__list {
		flex-direction: column;
		align-items: stretch;
		gap: 0.5rem;
		padding-block: 0.5rem;
	}

	/* Croix quand le menu est ouvert. */
	.menu-toggle[aria-expanded="true"] .menu-toggle__bar {
		background: transparent;
	}

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

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

/* ----------------------------------------------------------------------
   12. Sections de contenu (accueil, services, à propos…)
   Composants stylés via des classes posées dans le contenu éditable.
   Pas de fond pleine largeur : on joue sur le blanc, l'espace et de
   fines bordures (cf. CLAUDE.md section 7).
   ---------------------------------------------------------------------- */

/* Rythme vertical entre sections */
.entry-content .section {
	margin-block: var(--section-gap);
}

.entry-content .section:first-child {
	margin-top: 2.5rem;
}

/* Texte d'introduction */
.lead {
	font-size: 1.2rem;
	color: var(--color-text-muted);
	max-width: 65ch;
}

/* Variante sans plafond de largeur (ex. accroche courte à garder sur une
   ligne quand la colonne le permet) — s'adapte librement en dessous. */
.lead--full {
	max-width: none;
	color: var(--color-text);
}

/* Espacement par défaut entre blocs du contenu */
.entry-content > * + *,
.entry-content .section > * + * {
	margin-top: 1.25rem;
}

/* --- Hero (charte « Signal ») : contenu à gauche (eyebrow/titre/accroche/CTA),
   photo diagonale à droite. Logo retiré d'ici : affiché en compact dans la
   nav (header.php), sur toutes les pages y compris l'accueil. --- */
.hero {
	position: relative;
	overflow: hidden;
	background: var(--color-marine);
	color: #fff;
	display: flex;
	flex-direction: column;
}

/* Le bloc groupe "hero" est en layout "constrained" : WordPress insère un
   .wp-block-group__inner-container entre .hero et .hero__media.
   Sans ce correctif, le flex de .hero ne s'applique jamais à .hero__media
   (qui n'est plus un enfant direct) : flex:1 n'a alors aucun effet, la photo
   retombe sur son ratio naturel et laisse un grand vide marine en dessous. */
.hero > .wp-block-group__inner-container {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.hero__media {
	display: flex;
	flex: 1;
	min-height: 0;
	margin: 0;
	gap: 0;
}

.hero__media > .hero__media-content,
.hero__media > .hero__media-photo {
	margin: 0;
}

/* Colonne de contenu : bloc de texte (eyebrow/titre/accroche/CTA) à gauche,
   logo à droite — tous les deux sur le fond marine plein (pas sur la
   photo), groupe centré verticalement dans la hauteur du hero. */
.hero__media-content {
	flex: 1;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: flex-start;
	gap: 1.5rem;
	padding: 1.5rem 3rem;
}

/* .hero__text est un bloc groupe WP : même défaut que .hero plus haut dans
   ce fichier — WordPress insère un .wp-block-group__inner-container entre
   .hero__text et son contenu réel (eyebrow/titre/accroche/CTA), même sans
   attribut "layout" explicite sur le bloc. Le flex doit donc s'appliquer à
   CE conteneur (c'est lui qui porte l'ancien empilement de .hero__media-content).
   flex:1 (au lieu d'une largeur calée sur le contenu) : le bloc de texte
   garde une largeur STABLE quelle que soit la longueur du mot affiché par
   l'animation machine à écrire du titre — sinon le logo, poussé à droite
   par margin-left:auto ci-dessous, se décalait à chaque changement de mot. */
.hero__text {
	flex: 1 1 auto;
	min-width: 0;
}

.hero__text > .wp-block-group__inner-container {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.25rem;
}

/* Logo sur le fond marine plein (pas sur la photo) : poussé au bord droit
   de la colonne (margin-left:auto) — sa position ne dépend donc plus de la
   largeur du bloc de texte à côté. */
.hero__media-logo-small {
	flex: 0 0 auto;
	margin-left: auto;
}

.hero__media-logo-small img {
	height: 170px;
	width: auto;
	max-width: 100%;
	object-fit: contain;
}

.hero__media-photo {
	flex: 1.15;
	position: relative;
	overflow: hidden;
}

.hero__media-photo img {
	/* Positionnement absolu (au lieu de height:100% sur l'img directement) :
	   entre .hero__media-photo (flex item étiré) et l'img se trouve le
	   <figure> du bloc image, qui n'a pas de hauteur propre (auto → dépend
	   de l'img → cercle). height:100% y était donc ignoré et l'img retombait
	   sur son ratio naturel, laissant un grand vide marine sous la photo.
	   En absolute sur le parent positionné (.hero__media-photo), on
	   court-circuite le <figure> et on cale l'img exactement sur son
	   conteneur, quelle que soit sa hauteur. */
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	clip-path: polygon(12% 0, 100% 0, 100% 100%, 0% 100%);
}

/* Mobile : contenu puis photo empilés, hauteurs contraintes retirées. */
@media (max-width: 1100px) {
	.hero {
		min-height: 0 !important;
	}
	.hero__media {
		flex-direction: column;
		align-items: stretch; /* logo/texte/photo occupent toute la largeur par défaut */
		gap: 1.25rem;
		padding: 2rem 1.5rem;
	}
	/* Aplati sur mobile : .hero__media-content, .hero__text et son
	   inner-container disparaissent de l'arbre de rendu (display:contents,
	   ne garde que leurs ENFANTS). Sur PC ce sont des conteneurs de mise en
	   page (colonne texte à gauche du logo, elle-même à gauche de la photo) ;
	   sur mobile on veut un ordre différent avec la PHOTO intercalée entre le
	   titre et l'accroche — impossible avec ces enfants enfermés dans des
	   boîtes séparées de la photo (l'ordre flex ne joue qu'entre éléments
	   d'un même conteneur). Aplatir les rend tous frères direct de
	   .hero__media, où l'ordre ci-dessous peut les mélanger librement. */
	.hero__media-content,
	.hero__text,
	.hero__text > .wp-block-group__inner-container {
		display: contents;
	}

	.hero__media-logo-small {
		order: -3;
		align-self: center; /* seul élément centré ; le reste du bloc reste aligné à gauche */
		/* Sans ce reset, le margin-left:auto desktop (qui plaque le logo au
		   bord droit à côté du texte, cf. règle non scopée plus haut) prend
		   le pas sur align-self:center ci-dessus — une marge auto gagne
		   toujours sur l'alignement flex sur son axe. */
		margin-left: 0;
		margin-bottom: 0.5rem;
	}
	.hero__eyebrow {
		order: -2;
	}
	.hero__title {
		order: -1;
		/* font-size et min-height mobile sont définis PLUS BAS dans ce fichier
		   (après la règle de base .hero__title, cf. juste après §".hero__title"),
		   pour ne pas être écrasés par elle : même sélecteur, même spécificité
		   → la dernière déclaration du fichier gagne, peu importe la media
		   query. Les garder groupées ici les aurait rendues sans effet. */
	}
	.hero__media-photo {
		/* Retirée sur mobile uniquement (pas sur PC) : hero plus compact,
		   photo dispensable une fois le texte empilé sur petit écran. */
		display: none;
	}
	.hero__subtitle {
		order: 1;
		/* min-height:0 mobile est plus bas dans ce fichier (après la règle de
		   base .hero__subtitle), même raison que pour .hero__title ci-dessus. */
	}
	.hero__cta {
		order: 2;
	}
}

.hero__eyebrow {
	margin: 0;
	font-family: var(--font-body);
	font-weight: 700;
	font-size: 0.8125rem; /* 13px */
	letter-spacing: 0.07em;
	text-transform: uppercase;
	color: #fff;
}

/* Desktop (par défaut) : une seule ligne avec le point milieu "·" ; la
   virgule et le retour à la ligne insérés dans le contenu (cf. page
   Accueil), pensés pour le mobile, restent masqués. */
.hero__eyebrow-break,
.hero__eyebrow-comma {
	display: none;
}

@media (max-width: 1100px) {
	/* Mobile : 2 lignes distinctes, centrées. Le "·" cède la place à une
	   virgule en fin de 1re ligne (le "·" seul en début de 2e ligne était
	   moche, même correctif déjà fait sur le pied de page). */
	.hero__eyebrow {
		text-align: center;
	}
	.hero__eyebrow-sep {
		display: none;
	}
	.hero__eyebrow-break {
		display: block;
	}
	.hero__eyebrow-comma {
		display: inline;
	}
}

.hero__title {
	color: #fff;
	font-family: var(--font-heading);
	font-weight: 800;
	/* La 1re ligne ("Votre <mot>,") ne doit JAMAIS revenir à la ligne, quelle
	   que soit la longueur du mot saisi dans le Customizer (jusqu'à 27
	   caractères garantis, cf. plus bas). Un mot trop long qui excéderait la
	   police calculée ci-dessous déborderait plutôt que de wrapper — mais la
	   taille est justement calibrée pour que ça n'arrive pas jusqu'à 27
	   caractères, aux largeurs d'écran testées (colonne texte du hero). */
	white-space: nowrap;
	/* 1.075rem (17px) est le plancher calculé pour tenir "Votre " + 27
	   caractères + "," à 1101px de large (le point le plus étroit du hero
	   PC, juste au-dessus du seuil mobile/tablette de 1100px) ; 1.55vw est
	   volontairement en dessous de la pente idéale à cette largeur (marge de
	   sécurité), 2.25rem plafonne la taille sur très grand écran. */
	font-size: clamp(1.075rem, 1.55vw, 2.25rem);
	line-height: 1.2;
	max-width: none;
	margin: 0;
	/* 2 lignes fixes : la 1re ("Votre <mot>,") ne wrap plus jamais (nowrap
	   ci-dessus), la 2e ("entre de bonnes mains.") est un texte fixe qui ne
	   change pas avec le mot animé — plus de saut de hauteur possible. */
	min-height: calc(1.2em * 2);
}

@media (max-width: 1100px) {
	.hero__title {
		/* Garantit qu'aucun mot dynamique jusqu'à 27 caractères ne force de
		   retour à la ligne sur "Votre <mot>," (cf. white-space:nowrap sur la
		   règle de base) : le plancher 0.8125rem (13px) est calculé pour
		   tenir 27 caractères à 320px de large, le point le plus étroit visé.
		   La valeur fluide (4vw) grandit ensuite jusqu'au plafond 1.75rem
		   pour les écrans plus larges (tablette). */
		font-size: clamp(0.8125rem, 4vw, 1.75rem);
		/* 2 lignes fixes maintenant (jamais plus, jamais moins) : la 1re ligne
		   ne wrap plus jamais (nowrap) et la 2e ("entre de bonnes mains.")
		   est un texte fixe qui ne change pas avec le mot animé — plus besoin
		   de réserver de la place pour un éventuel 3e/4e/5e ligne. */
		min-height: calc(1.2em * 2);
	}
}

.hero__title .vnn-typewriter {
	display: inline-block;
	color: oklch(78% 0.12 195); /* sarcelle vive : met le mot animé en valeur */
}

/* Curseur clignotant, désactivé si prefers-reduced-motion ou mot unique (is-static). */
.hero__title .vnn-typewriter::after {
	content: '';
	display: inline-block;
	width: 3px;
	height: 0.8em;
	margin-left: 2px;
	background: currentColor;
	vertical-align: -0.1em;
	animation: vnn-caretblink 1s steps(1) infinite;
}

.hero__title .vnn-typewriter.is-static::after {
	animation: none;
}

@keyframes vnn-caretblink {
	50% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
	.hero__title .vnn-typewriter::after {
		animation: none;
	}
}

/* Accroche sous le titre : alignée à gauche, largeur réduite pour rester
   lisible (cf. maquette). */
/* Centré verticalement dans son propre espace (min-height plus grand que le
   texte) entre le titre et les boutons — même principe que .hero__eyebrow
   plus haut : le <p> devient un mini conteneur flex pour centrer son texte
   dans sa boîte, désormais plus haute que son contenu. */
.hero__subtitle {
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-height: 13rem;
	font-family: var(--font-body);
	font-size: 1rem;
	line-height: 1.6;
	color: rgba(255, 255, 255, 0.8);
	max-width: 50ch;
	text-align: left;
	margin: 0;
}

@media (max-width: 1100px) {
	.hero__subtitle {
		/* Le centrage vertical (13rem) visait l'espace fixe du desktop entre
		   titre et boutons ; en flux normal mobile ça ne ferait qu'ajouter un
		   grand vide inutile. */
		min-height: 0;
	}
}

.hero__subtitle strong {
	color: #fff;
}

/* Boutons d'appel à l'action du hero. */
.hero__cta {
	margin-top: 0.5rem;
}

/* Bouton secondaire adapté au fond sombre du hero : le contour marine de la
   convention "outline" (cf. CLAUDE.md section 7) est invisible sur ce fond
   très foncé — même principe (fond transparent, juste un contour), en blanc
   translucide ici uniquement. */
.hero__cta .is-style-outline .wp-block-button__link {
	color: #fff;
	border-color: rgba(255, 255, 255, 0.5);
}

.hero__cta .is-style-outline .wp-block-button__link:hover {
	background: rgba(255, 255, 255, 0.12);
	border-color: #fff;
	color: #fff;
}

/* ----------------------------------------------------------------------
   Accueil plein écran (scroll-snap) — charte « Signal ».
   Layout racine : nav (72px, cf. header.php) / conteneur de scroll-snap
   (flex:1) / bandeau carrousel (172px, hors scroll-snap). Body.vnn-home
   pose le cadre 100vh ; #main devient la colonne flex qui contient le
   conteneur de scroll ET le bandeau carrousel.
   ---------------------------------------------------------------------- */
body.vnn-home {
	/* min-height (pas height + overflow:hidden) : #main occupe pile 100vh
	   (règle suivante), mais le pied de page qui le suit dans le flux normal
	   doit rester atteignable en scrollant la page — sinon les mentions
	   légales du footer (pourtant bien générées, cf. footer.php commun à
	   toutes les pages) deviennent invisibles et inaccessibles sur l'accueil. */
	min-height: 100vh;
}

/* Scrollbar de la page masquée sur l'accueil, comme celle de .home-scroll
   (cf. plus bas) : les points de navigation jouent déjà ce rôle de repère,
   et cette barre-ci ne réapparaît que ponctuellement (sous "cta", pour
   atteindre le pied de page) — pas de raison qu'elle ait un rendu différent
   du reste de la page plein écran. Ciblée sur <html> (pas <body>) : c'est
   lui l'élément qui défile réellement ici. Scopé à l'accueil via :has(),
   pas touché sur les autres pages (scrollbar normale et voulue là-bas). */
html:has(body.vnn-home) {
	scrollbar-width: none;
	-ms-overflow-style: none;
}

html:has(body.vnn-home)::-webkit-scrollbar {
	display: none;
}

body.vnn-home #main {
	display: flex;
	flex-direction: column;
	height: calc(100vh - var(--header-h, 72px));
	min-height: 0;
}

.home-scroll {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overflow-x: hidden;
	scroll-snap-type: y mandatory;
	/* Repli pour les défilements non interceptés par le JS (clavier, ascenseur) :
	   scroll-behavior:smooth ne vaut que pour SON élément, le poser sur <html>
	   ne suffit pas ici puisque c'est ce conteneur qui défile réellement. */
	scroll-behavior: smooth;
	/* Scrollbar masquée : les points de navigation (.home-dots) jouent déjà
	   ce rôle de repère de rubrique. Le défilement reste fonctionnel (clavier,
	   molette, tactile), seule la barre visuelle disparaît. */
	scrollbar-width: none; /* Firefox */
	-ms-overflow-style: none; /* Edge legacy */
}

.home-scroll::-webkit-scrollbar {
	display: none; /* Chrome, Safari, Edge Chromium */
}

.home-sections > .section {
	scroll-snap-align: start;
	min-height: calc(100vh - var(--header-h, 72px) - 172px);
	padding: 40px 96px;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.home-sections > .section.hero {
	padding: 0;
	justify-content: flex-start;
	/* Hauteur FERME (pas juste min-height) : hero__media-photo img est en
	   height:100%, qui ne peut se résoudre que si toute la chaîne de parents
	   a une hauteur déterminée. Sans ça, la photo retombe sur son ratio
	   naturel et laisse un grand vide marine sous elle (cf. correctif). */
	height: calc(100vh - var(--header-h, 72px) - 172px);
}

/* Fonds de section distincts (marquer le changement de bloc). */
.home-sections > .section--conseil { background: var(--color-section-neutral); }
.home-sections > .section--secteur { background: var(--color-section-sarcelle); }
.home-sections > .section.cta { background: var(--color-section-marine); }

/* --- Secteur : texte à gauche, image à droite (quinconce au scroll) --- */
.section--secteur__row {
	margin: 0;
}

/* Ce bloc groupe est en layout "default" : WordPress insère un
   .wp-block-group__inner-container entre .section--secteur__row et ses deux
   enfants (texte/image). Le flex doit donc s'appliquer à CE conteneur, sinon
   texte et image restent empilés au lieu d'être côte à côte (même défaut que
   pour le hero, cf. plus haut dans ce fichier). */
.section--secteur__row > .wp-block-group__inner-container {
	display: flex;
	align-items: center;
	gap: 56px;
}

.section--secteur__text {
	flex: 1;
	margin: 0;
}

/* Texte un peu plus grand côté "Secteur" (demande spécifique à cette
   rubrique) — scopé ici pour ne pas toucher .lead ailleurs sur le site. */
.section--secteur__text .lead {
	font-size: 1.35rem;
}

/* Colonne image 1/3 plus large que la colonne texte (flex: 2 contre 1 =
   2/3 de l'espace dispo au lieu de 1/2, soit +33% de largeur d'image). */
.section--secteur__image {
	flex: 2;
	margin: 0;
}

.section--secteur__image img {
	width: 100%;
	height: auto;
	border-radius: 12px;
	object-fit: cover;
}

@media (max-width: 768px) {
	.section--secteur__row > .wp-block-group__inner-container {
		flex-direction: column;
		gap: 24px;
	}
}

/* --- Points de navigation (dots) --- */
.home-dots {
	position: fixed;
	right: 26px;
	top: 50%;
	transform: translateY(-50%);
	z-index: 900;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
}

.home-dots__dot {
	display: block;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: oklch(80% 0.01 240);
	transition: background var(--transition), width var(--transition), height var(--transition);
}

.home-dots__dot:hover,
.home-dots__dot:focus-visible {
	background: var(--color-accent);
}

.home-dots__dot.is-active {
	width: 10px;
	height: 10px;
	background: var(--color-accent);
}

@media (max-width: 900px) {
	.home-dots {
		display: none;
	}
}

/* --- Bandeau carrousel (services), fixe en bas, hors scroll-snap --- */
.home-ticker {
	flex: 0 0 172px;
	height: 172px;
	overflow: hidden;
	display: flex;
	align-items: center;
	background: oklch(98% 0.004 240 / 0.45);
	backdrop-filter: blur(16px);
	-webkit-backdrop-filter: blur(16px);
	border-top: 1px solid oklch(100% 0 0 / 0.5);
	mask-image: linear-gradient(90deg, transparent, black 6%, black 94%, transparent);
	-webkit-mask-image: linear-gradient(90deg, transparent, black 6%, black 94%, transparent);
}

.home-ticker__track {
	display: flex;
	gap: 18px;
	width: max-content;
	/* Délai avant démarrage : laisse le temps aux polices/à l'apparition au
	   défilement de se stabiliser au premier affichage — sinon le défilement
	   horizontal du bandeau se superpose à ces mouvements initiaux et donne
	   une impression de tremblement (cf. CLAUDE.md, retour utilisateur). */
	animation: vnn-marquee 38s linear infinite;
	animation-delay: 1s;
}

@keyframes vnn-marquee {
	to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
	.home-ticker__track {
		animation-play-state: paused;
	}
}

.home-ticker__card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: center;
	gap: 0.4rem;
	width: 300px;
	flex: 0 0 auto;
	border-radius: 8px;
	padding: 20px 22px;
	color: var(--color-text);
}

.home-ticker__card--sarcelle { background: var(--color-ticker-sarcelle); }
.home-ticker__card--marine { background: var(--color-ticker-marine); }

.home-ticker__card-title {
	font-family: var(--font-heading);
	font-weight: 600;
	font-size: 0.95rem;
}

.home-ticker__card-desc {
	font-family: var(--font-body);
	font-weight: 400;
	font-size: 0.8125rem;
	line-height: 1.4;
	color: var(--color-text-muted);
	/* 2 lignes max : la carte garde une hauteur fixe même si l'intitulé varie. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* --- Responsive : en dessous de 900px, l'accueil repasse en défilement
   normal (le plein écran par section n'a plus de sens sur petit viewport
   avec nav mobile + clavier virtuel). --- */
@media (max-width: 900px) {
	body.vnn-home {
		height: auto;
		overflow: visible;
	}
	body.vnn-home #main {
		height: auto;
		display: block;
	}
	.home-scroll {
		overflow: visible;
		scroll-snap-type: none;
	}
	.home-sections > .section {
		min-height: 0;
		scroll-snap-align: none;
		padding: 48px 24px;
	}
	.home-sections > .section.hero {
		height: auto;
	}
	.home-ticker {
		flex: 0 0 auto;
	}
}

/* --- Grille de piliers (approche) --- */
/* Grille appliquée au conteneur direct des cartes (cf. remarque sur
   .wp-block-group__inner-container au niveau de .services-grid). */
.pillars-grid > .wp-block-group__inner-container {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 40px;
}

.pillars-grid:not(:has(> .wp-block-group__inner-container)) {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 40px;
}

@media (max-width: 900px) {
	.pillars-grid > .wp-block-group__inner-container,
	.pillars-grid:not(:has(> .wp-block-group__inner-container)) {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 560px) {
	.pillars-grid > .wp-block-group__inner-container,
	.pillars-grid:not(:has(> .wp-block-group__inner-container)) {
		grid-template-columns: 1fr;
	}
}

.pillar {
	padding-top: 1rem;
	border-top: 2px solid var(--color-accent);
}

.pillar h3 {
	margin-bottom: 0.5rem;
}

.pillar p {
	color: var(--color-text-muted);
	margin: 0;
}

/* --- Grille de services (cartes) ---
   2 colonnes régulières, espacement uniforme de 0,5 cm. WordPress enrobe le
   groupe d'un .wp-block-group__inner-container : la grille doit donc s'appliquer
   au conteneur DIRECT des cartes, sinon elle n'atteint pas les cartes. On gère
   les deux cas (avec ou sans ce conteneur interne). */
.services-grid > .wp-block-group__inner-container {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.5cm;
}

/* Fallback : markup moderne sans conteneur interne (grille directe sur le groupe). */
.services-grid:not(:has(> .wp-block-group__inner-container)) {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.5cm;
}

/* Vue d'ensemble (page Services, [vnn_services_grid]) : grille dynamique,
   gap 28px, max-width 1280px — cf. SPECS-TECHNIQUES.md. */
.services-grid--overview {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 28px;
	max-width: 1280px;
}

.service-card {
	/* L'espacement vient du gap de la grille : pas de marge d'inter-blocs. */
	margin: 0;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	padding: 1.75rem;
	transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
}

/* Cartes de la vue d'ensemble : carte entière cliquable, fond blanc, coins
   10px, padding 32px (cf. handoff). */
.service-card--overview {
	display: block;
	background: var(--color-white);
	border-radius: 10px;
	padding: 32px;
	color: inherit;
	text-decoration: none;
}

.service-card--overview:hover {
	text-decoration: none;
}

/* Icône + titre côte à côte, ligne d'accent EN DESSOUS du duo (pas entre
   l'icône et le titre comme avant). */
.service-card__head {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding-bottom: 0.75rem;
	margin-bottom: 0.6rem;
	border-bottom: 2px solid var(--color-accent);
}

.service-card__icon-box {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	flex: 0 0 auto;
	border-radius: 8px;
	color: var(--color-marine);
}

.service-card__icon-box--sarcelle { background: var(--color-ticker-sarcelle); }
.service-card__icon-box--marine { background: var(--color-ticker-marine); }

.service-card:hover {
	transform: translateY(-3px);
	border-color: var(--color-accent);
	box-shadow: 0 8px 24px oklch(48% 0.09 195 / 0.08);
}

.service-card h3 {
	margin: 0;
	font-size: 1.2rem;
}

.service-card p {
	color: var(--color-text-muted);
	margin: 0 0 1rem;
}

.service-card .wp-block-list,
.service-card ul {
	margin: 0;
	padding-left: 1.1rem;
	font-size: 0.95rem;
	color: var(--color-text);
}

.service-card li {
	margin-bottom: 0.35rem;
}

/* Catalogue : une seule colonne sur mobile. */
@media (max-width: 768px) {
	.services-grid > .wp-block-group__inner-container {
		grid-template-columns: 1fr;
	}
	.services-grid:not(:has(> .wp-block-group__inner-container)) {
		grid-template-columns: 1fr;
	}
	.services-grid--overview {
		grid-template-columns: 1fr;
	}
}

/* --- Picklist des pôles d'expertise (page d'accueil) ---
   Liste épurée en chips à puce « check », sans descriptions (le détail vit
   sur la page Services). 2 colonnes en desktop, 1 sur mobile. */
.expertise-picklist {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 0.85rem 1.25rem;
}

.expertise-picklist li {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.6rem;
	margin: 0;
	min-height: 3.5rem;
	padding: 0.75rem 1.1rem;
	text-align: center;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: 12px;
	font-weight: 600;
	color: var(--color-text);
	transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.expertise-picklist li::before {
	content: "✓";
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 1.4rem;
	height: 1.4rem;
	border-radius: 50%;
	background: var(--color-accent);
	color: #fff;
	font-size: 0.78rem;
	font-weight: 700;
	line-height: 1;
}

.expertise-picklist li:hover {
	transform: translateY(-2px);
	border-color: var(--color-accent);
	box-shadow: 0 8px 24px oklch(48% 0.09 195 / 0.08);
}

.expertise-picklist__note {
	margin: 1.5rem 0 0;
	font-weight: 600;
}

@media (max-width: 600px) {
	.expertise-picklist {
		grid-template-columns: 1fr;
	}
}

/* --- Appel à l'action (contact) --- */
.cta {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	padding: 3rem 1.5rem;
	text-align: center;
}

.cta h2 {
	margin-bottom: 0.75rem;
}

.cta p {
	color: var(--color-text-muted);
	max-width: 50ch;
	margin-inline: auto;
}

.cta .wp-block-buttons {
	justify-content: center;
	margin-top: 1.5rem;
	/* Boutons « Nous contacter » / « Prendre rendez-vous » espacés de 1 cm. */
	gap: 1cm;
}

/* Pages de pôles (Services) : juste le bouton « Nous contacter », aligné à
   gauche comme le reste de la page — plus le cadre "Parlons de votre
   projet" (titre + paragraphe + fond), jugé trop imposant ici. */
.service-page__cta {
	margin-top: 2.5rem;
}

/* --- Carte coordonnées (page contact) --- */
.contact-card {
	display: inline-block;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	padding: 1.25rem 1.75rem;
}

.contact-card .mono {
	margin: 0 0 0.25rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

.contact-card__value {
	margin: 0;
	font-size: 1.2rem;
	font-weight: 600;
}

/* --- Galerie réalisations --- */
.realisations-gallery {
	margin-top: 2rem;
}

/* ----------------------------------------------------------------------
   13. Témoignages clients (« Ils nous font confiance »)
   Pattern « Témoignage client » : logo + témoignage côte à côte.
   ---------------------------------------------------------------------- */
.testimonial {
	align-items: center;
	gap: 1.5rem;
	padding: 1.5rem 1.75rem;
	margin-block: 1.25rem;
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
}

/* Survol identique aux cartes de services (cf. CLAUDE.md, conventions). */
.testimonial:hover {
	transform: translateY(-3px);
	border-color: var(--color-accent);
	box-shadow: 0 8px 24px oklch(48% 0.09 195 / 0.08);
}

.testimonial__logo {
	margin: 0;
}

.testimonial__logo img {
	max-height: 90px;
	width: auto;
	margin-inline: auto;
	object-fit: contain;
}

.testimonial__quote {
	font-size: 1.15rem;
	line-height: 1.55;
	margin: 0;
}

.testimonial__cite {
	margin: 0.6rem 0 0;
	color: var(--color-text-muted);
}

/* ----------------------------------------------------------------------
   14. Formulaire de contact ([vnn_contact])
   ---------------------------------------------------------------------- */
/* Zone formulaire : 2 colonnes — formulaire (≤640px) à gauche, logo à droite
   (comble le vide). Sur écran étroit : une colonne, logo masqué (décoratif). */
.vnn-form-wrap {
	margin-top: 2rem;
	display: grid;
	grid-template-columns: minmax(0, 640px) 1fr;
	gap: 2.5rem;
	align-items: center;
}

.vnn-form-main {
	min-width: 0;
}

.vnn-form-aside {
	display: flex;
	justify-content: center;
	align-items: center;
}

.vnn-form-logo {
	width: 100%;
	max-width: 240px;
	height: auto;
}

@media (max-width: 900px) {
	.vnn-form-wrap {
		grid-template-columns: 1fr;
	}
	.vnn-form-main {
		max-width: 640px;
	}
	.vnn-form-aside {
		display: none;
	}
}

.vnn-form__row {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
	margin: 0 0 1.25rem;
}

.vnn-form label {
	font-weight: 600;
	font-size: 0.95rem;
}

.vnn-form input,
.vnn-form textarea {
	width: 100%;
	font-family: inherit;
	font-size: 1rem;
	color: var(--color-text);
	background: var(--color-bg);
	border: 1px solid var(--color-border);
	border-radius: var(--radius);
	padding: 0.7rem 0.85rem;
	transition: border-color var(--transition);
}

.vnn-form input:focus,
.vnn-form textarea:focus {
	border-color: var(--color-accent);
}

.vnn-form textarea {
	resize: vertical;
}

/* Honeypot : masqué pour les humains. */
.vnn-form__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.vnn-form__notice {
	padding: 0.85rem 1rem;
	border-radius: var(--radius);
	border: 1px solid var(--color-border);
	margin-bottom: 1.5rem;
}

.vnn-form__notice--success {
	background: #ecfdf5;
	border-color: #a7f3d0;
	color: #065f46;
}

.vnn-form__notice--error {
	background: #fef2f2;
	border-color: #fecaca;
	color: #991b1b;
}

/* Coordonnées dans le pied de page */
.site-footer__contact {
	margin: 0.5rem 0 0;
	font-size: 0.95rem;
}

/* Liens sociaux du pied de page (liste en ligne). */
.site-footer__social {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 1rem;
	margin: 0.6rem 0 0;
	padding: 0;
	list-style: none;
	font-size: 0.95rem;
}

.site-footer__social a {
	color: var(--color-text-muted);
	transition: color var(--transition);
}

.site-footer__social a:hover {
	color: var(--color-accent);
}

/* ----------------------------------------------------------------------
   15. E-mail anti-spam + barre légale du pied de page
   ---------------------------------------------------------------------- */
/* E-mail obfusqué : non sélectionnable (anti-copie/anti-bot). */
.vnn-email,
.vnn-email-link {
	-webkit-user-select: none;
	-moz-user-select: none;
	user-select: none;
}

.vnn-email-link {
	color: var(--color-accent);
}

/* Barre légale (mentions légales, confidentialité) */
.site-footer__legal {
	border-top: 1px solid var(--color-border);
	padding-top: 0.625rem;
	margin-top: 0.25rem;
}

.site-footer__legal-list {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 1.25rem;
	margin: 0;
	padding: 0;
	font-size: 0.85rem;
}

.site-footer__legal-list a {
	color: var(--color-text-muted);
}

.site-footer__legal-list a:hover {
	color: var(--color-accent);
}

/* E-mail rendu en image (anti-spam) */
.vnn-email-img {
	display: inline-block;
	vertical-align: middle;
	max-width: 100%;
	height: auto;
}

.vnn-email-img-link {
	display: inline-block;
	line-height: 0;
	text-decoration: none;
}

/* ----------------------------------------------------------------------
   16. Page À propos (accroche, chiffre clé « 18 », certifications, valeurs)
   ---------------------------------------------------------------------- */

/* Accroche : texte + portrait optionnel (mobile : empilé) */
.about-intro {
	display: flex;
	flex-wrap: wrap;
	gap: 2.5rem;
	align-items: center;
}

.about-intro__text {
	flex: 1 1 320px;
}

/* Icône LinkedIn (profil perso de Kévin Mahner), sous le nom/titre. */
.about-portrait {
	flex: 0 0 auto;
	width: clamp(150px, 28vw, 230px);
	margin: 0;
}

/* .about-portrait-wrap (nouveau groupe autour de la seule photo) sert
   d'ancre de position pour l'icône ci-dessous, plutôt que le <figure> du
   bloc image lui-même : WordPress restructure silencieusement le contenu
   d'un bloc wp:image si on lui ajoute un enfant qu'il ne reconnaît pas
   (l'icône se retrouvait à mauvais escient à l'intérieur du lien de l'image
   à l'enregistrement). Un wp:group générique autour n'a pas ce problème. */
.about-portrait-wrap {
	position: relative;
	display: inline-block;
}

/* Icône LinkedIn (profil perso), à droite de la photo. Icône en CSS
   (mask-image, pas de <svg> dans le contenu) : WordPress assainit le
   contenu à l'enregistrement et retire silencieusement les balises <svg>
   brutes — un <svg> collé dans le contenu de la page disparaît donc sans
   erreur visible. Carrée (coins arrondis), comme le logo LinkedIn officiel
   — pas un rond. Couleur bleu LinkedIn d'origine (#0A66C2), pas celle du
   site : demande explicite, distincte du bleu marine utilisé ailleurs. */
.about-intro__social {
	position: absolute;
	bottom: 0;
	left: 100%;
	margin: 0 0 0 14px;
}

.about-intro__social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 8px;
	background: #0a66c2; /* bleu LinkedIn officiel */
	font-size: 0; /* cache le texte "LinkedIn" du lien ; seule l'icône (::before) reste visible */
	transition: background var(--transition);
}

.about-intro__social a::before {
	content: '';
	display: block;
	width: 18px;
	height: 18px;
	background-color: #fff;
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M20.447%2020.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853%200-2.136%201.445-2.136%202.939v5.667H9.351V9h3.414v1.561h.046c.477-.9%201.637-1.85%203.37-1.85%203.601%200%204.267%202.37%204.267%205.455v6.286zM5.337%207.433c-1.144%200-2.063-.926-2.063-2.065%200-1.14.92-2.065%202.063-2.065%201.14%200%202.064.925%202.064%202.065%200%201.139-.925%202.065-2.064%202.065zm1.782%2013.019H3.555V9h3.564v11.452zM22.225%200H1.771C.792%200%200%20.774%200%201.729v20.542C0%2023.227.792%2024%201.771%2024h20.451C23.2%2024%2024%2023.227%2024%2022.271V1.729C24%20.774%2023.2%200%2022.222%200h.003z%22/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M20.447%2020.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853%200-2.136%201.445-2.136%202.939v5.667H9.351V9h3.414v1.561h.046c.477-.9%201.637-1.85%203.37-1.85%203.601%200%204.267%202.37%204.267%205.455v6.286zM5.337%207.433c-1.144%200-2.063-.926-2.063-2.065%200-1.14.92-2.065%202.063-2.065%201.14%200%202.064.925%202.064%202.065%200%201.139-.925%202.065-2.064%202.065zm1.782%2013.019H3.555V9h3.564v11.452zM22.225%200H1.771C.792%200%200%20.774%200%201.729v20.542C0%2023.227.792%2024%201.771%2024h20.451C23.2%2024%2024%2023.227%2024%2022.271V1.729C24%20.774%2023.2%200%2022.222%200h.003z%22/%3E%3C/svg%3E");
	-webkit-mask-size: contain;
	mask-size: contain;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
}

.about-intro__social a:hover {
	background: #004182; /* survol bleu LinkedIn foncé (teinte officielle) */
}

.about-portrait img {
	width: 100%;
	height: auto;
	border-radius: 14px;
	border: 1px solid var(--color-border);
}

/* Chiffre clé mis en valeur (ex. « 18 » ans) — touche mono/accent */
.stat {
	margin-block: 1.5rem;
}

.stat__number {
	font-family: var(--font-mono);
	font-size: clamp(3.5rem, 11vw, 6rem);
	line-height: 1;
	font-weight: 700;
	color: var(--color-accent);
	margin: 0;
}

.stat__label {
	font-size: 1.1rem;
	color: var(--color-text-muted);
	margin: 0.25rem 0 0;
}

/* Grille de certifications (badges) — grille sur le conteneur direct des cartes
   (cf. remarque .wp-block-group__inner-container au niveau de .services-grid). */
.cert-grid {
	margin-block: 1.5rem;
}

.cert-grid > .wp-block-group__inner-container {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 1.5rem;
}

.cert-grid:not(:has(> .wp-block-group__inner-container)) {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 1.5rem;
}

.certification {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-top: 2px solid var(--color-accent);
	border-radius: 12px;
	padding: 1.75rem;
}

/* Logo de certification (image téléversée : badge officiel) */
.certification__logo {
	margin: 0 0 0.9rem;
}

.certification__logo img {
	max-height: 56px;
	width: auto;
}

.certification__title {
	margin: 0 0 0.4rem;
	font-size: 1.2rem;
}

.certification__benefit {
	margin: 0;
	color: var(--color-text-muted);
}

@media (max-width: 600px) {
	.about-intro {
		gap: 1.5rem;
	}
	.about-portrait {
		width: 150px;
		margin-inline: auto;
	}
	/* "À droite de la photo" n'a plus de sens une fois la photo centrée en
	   colonne étroite (l'icône sortirait de l'écran, calée sur left:100%
	   d'un bloc déjà centré) : on repasse l'icône sous la photo, centrée. */
	.about-portrait-wrap {
		display: block;
		width: 150px;
		margin-inline: auto;
	}
	.about-intro__social {
		position: static;
		transform: none;
		display: flex;
		justify-content: center;
		margin: 0.75rem 0 0;
	}
}

/* Ligne d'informations légales du pied de page (forme, capital, SIRET) —
   c'est aussi une .site-footer__legal-list (cf. footer.php) : même liste à
   puces "·" que le menu juste à côté, pour un espacement uniforme sur toute
   la ligne. Ne fixe plus que la couleur ; taille/espacement viennent de
   .site-footer__legal-list. */
.site-footer__legal-info {
	color: var(--color-text-muted);
}

/* ----------------------------------------------------------------------
   18. Apparition au défilement (activée par .has-reveal posée en <head>)
   ---------------------------------------------------------------------- */
.has-reveal .section {
	opacity: 0;
	transform: translateY(20px);
	transition: opacity 0.9s ease, transform 0.9s ease;
}

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

/* Cartes du catalogue de services : fondu progressif, carte par carte au fil du
   scroll (chaque carte apparaît quand elle entre dans le viewport). Le survol
   (translateY(-3px)) reste rapide (transform 0.5s / transitions courtes). */
.has-reveal .service-card {
	opacity: 0;
	transform: translateY(16px);
	transition: opacity 0.8s ease, transform 0.5s ease, border-color var(--transition), box-shadow var(--transition);
}

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

/* Apparition « en quinconce » (gauche/droite), ex. section Secteur de l'accueil. */
.has-reveal .reveal-left {
	opacity: 0;
	transform: translateX(-40px);
	transition: opacity 0.7s ease, transform 0.7s ease;
}

.has-reveal .reveal-right {
	opacity: 0;
	transform: translateX(40px);
	transition: opacity 0.7s ease, transform 0.7s ease;
}

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

@media (prefers-reduced-motion: reduce) {
	.has-reveal .section,
	.has-reveal .service-card,
	.has-reveal .reveal-left,
	.has-reveal .reveal-right {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* Pied de page légal : menu + infos légales sur UNE seule ligne, séparés par « · ». */
.site-footer__legal {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	column-gap: 0.85rem;
	row-gap: 0.3rem;
}

.site-footer__legal-list {
	gap: 0.85rem;
}

.site-footer__legal-list li + li::before,
.site-footer__legal nav + .site-footer__legal-info::before {
	content: "·";
	margin-right: 0.85rem;
	color: var(--color-text-muted);
}

.site-footer__legal-info {
	margin: 0;
}

/* Sur mobile, la ligne légale (menu + SIRET/RCS) ne tient plus sur une seule
   ligne : le retour à la ligne au milieu des séparateurs "·" générés laisse
   un "·" orphelin en début de ligne suivante. On empile plutôt chaque
   élément sur sa propre ligne, sans séparateur (inutile une fois empilé). */
@media (max-width: 600px) {
	.site-footer__legal {
		flex-direction: column;
		align-items: flex-start;
		row-gap: 0.5rem;
	}
	.site-footer__legal-list {
		flex-direction: column;
		align-items: flex-start;
		row-gap: 0.5rem;
	}
	.site-footer__legal-list li + li::before,
	.site-footer__legal nav + .site-footer__legal-info::before {
		content: none;
	}
}
