/* Feuille generee : ne pas editer. Les sources sont dans assets/css/src/. */

/* ============================================================================
   00-settings — alias des presets theme.json
   ----------------------------------------------------------------------------
   Ce fichier ne produit AUCUN style. Il ne fait que raccourcir les variables
   emises par theme.json (`--wp--preset--*`, `--wp--custom--*`) en noms courts
   `--sbc-*`, seuls autorises dans le reste de la feuille.

   Regle (CLAUDE.md, section CSS) : couleurs, espacements et tailles ne sont
   JAMAIS ecrits en dur ailleurs qu'ici. Une valeur en dur dans un fichier
   03-components/ ou 04-sections/ est un bug.

   Les noms des echelles (tiny -> huge, radius tiny -> circle) sont ceux du
   site de reference, repris tels quels dans brand/charte.md et
   template/extraction-manifest.json : ils restent tracables jusqu'a la source.
   ========================================================================== */

:root {

	/* --- Couleurs -----------------------------------------------------------
	   Nommees par ROLE, jamais par teinte (brand/charte.md). Changer la palette
	   doit rester une modification a un seul endroit : theme.json. */

	--sbc-color-primary:              var(--wp--preset--color--primary);
	--sbc-color-primary-dark:         var(--wp--preset--color--primary-dark);

	/* Aplats. Aucun texte ne se pose dessus, dans aucun sens : 1,96:1. */
	--sbc-color-surface-accent:        var(--wp--preset--color--surface-accent);
	--sbc-color-surface-accent-soft:   var(--wp--preset--color--surface-accent-soft);
	--sbc-color-surface-accent-subtle: var(--wp--preset--color--surface-accent-subtle);

	--sbc-color-surface:              var(--wp--preset--color--surface);

	/* Aplat d'une section sur deux — hero, Film solaire, Comment ca se passe,
	   FAQ depuis le 11 septembre 2026 (voir CLAUDE.md, Charte). Les sections
	   alternent blanc / bande, pour qu'on voie ou l'une finit et ou la
	   suivante commence.

	   Ce role n'existait pas : les sections partageaient toutes le meme
	   #F8F8F7, a 1,06:1 du blanc — un ecart que l'oeil ne voit pas. La bande
	   est a 1,13:1, ce qui se voit sans jamais devenir un aplat colore.

	   Contrastes mesures sur #F2F1EE : texte 16,02:1, texte secondaire 6,11:1,
	   teal 4,58:1. Le teal y passe AA de justesse : du TEXTE teal pose sur une
	   bande doit prendre --sbc-color-primary-dark (6,64:1). */
	--sbc-color-surface-band:         var(--wp--preset--color--surface-band);

	--sbc-color-surface-muted:        var(--wp--preset--color--surface-muted);
	--sbc-color-border:               var(--wp--preset--color--border);
	--sbc-color-text:                 var(--wp--preset--color--text);
	--sbc-color-text-muted:           var(--wp--preset--color--text-muted);
	--sbc-color-contrast:             var(--wp--preset--color--contrast);
	--sbc-color-white:                var(--wp--preset--color--white);

	/* Texte secondaire POSE SUR UN APLAT SOMBRE (pied de page). Le gris de
	   --sbc-color-text-muted tombe a 2,4:1 sur #111111 : il n'y tient pas.
	   Cette valeur est celle du site de reference (`text-color--ashy-gray`,
	   #B4B0B0), qui donne 7,9:1 sur le noir du pied de page. Elle n'est PAS
	   dans la palette de theme.json a dessein : sur fond clair elle chute a
	   1,94:1, elle n'a donc rien a faire dans le selecteur de couleurs. */
	--sbc-color-text-on-dark-muted:   var(--wp--custom--color--text-on-dark-muted);

	/* Etats de formulaire. Hors palette a dessein, comme le gris ci-dessus :
	   ce sont des couleurs de systeme, elles n'ont rien a faire dans le
	   selecteur de couleurs de l'editeur. Le rouge donne 6,2:1 sur blanc.
	   Il n'y a pas de vert de succes : c'est le teal de marque qui le porte
	   (--sbc-color-primary-dark), le vert sauge etant reserve aux aplats. */
	--sbc-color-error:                var(--wp--custom--color--error);
	--sbc-color-error-surface:        var(--wp--custom--color--error-surface);
	--sbc-color-success-surface:      var(--wp--custom--color--success-surface);

	/* Voile de la visionneuse (03-components/visionneuse.css). Hors palette a
	   dessein : c'est un voile pose sur la page, pas une couleur d'interface,
	   et il n'a rien a faire dans le selecteur de couleurs de l'editeur. Le
	   noir du pied de page a 88 % : la page reste devinable dessous. Compose
	   sur une page claire, le voile donne 13,7:1 avec le blanc des legendes et
	   des boutons, et 6,4:1 avec le gris --sbc-color-text-on-dark-muted (pire
	   cas) : AA dans les deux cas. */
	--sbc-color-backdrop:             var(--wp--custom--color--backdrop);

	/* Decoratif uniquement : le vert sauge fait echouer tout texte blanc. */
	--sbc-gradient-brand:             var(--wp--preset--gradient--brand);

	/* --- Typographie ------------------------------------------------------- */

	--sbc-font-base:        var(--wp--preset--font-family--base);
	--sbc-weight-regular:   400;
	--sbc-weight-medium:    500;

	--sbc-text-small:       var(--wp--preset--font-size--small);
	--sbc-text-base:        var(--wp--preset--font-size--medium);
	--sbc-text-m:           var(--wp--preset--font-size--large);
	--sbc-text-l:           var(--wp--preset--font-size--x-large);
	--sbc-text-h6:          var(--wp--preset--font-size--heading-6);
	--sbc-text-h5:          var(--wp--preset--font-size--heading-5);
	--sbc-text-h4:          var(--wp--preset--font-size--heading-4);
	--sbc-text-h3:          var(--wp--preset--font-size--heading-3);
	--sbc-text-h2:          var(--wp--preset--font-size--heading-2);
	--sbc-text-h1:          var(--wp--preset--font-size--heading-1);
	--sbc-text-display:     var(--wp--preset--font-size--display);

	--sbc-leading-body:     1.4;
	--sbc-leading-heading:  1.1;
	--sbc-leading-tight:    1;

	/* Role « sur-titre / etiquette / libelle de bouton ». Le site de reference
	   le portait en monospace ; il est rendu ici en Jost 500 capitales espacees
	   (voir la note d'arbitrage en tete de 01-base.css). */
	--sbc-tracking-label:   var(--wp--custom--tracking--label);

	/* --- Espacements ------------------------------------------------------- */

	--sbc-space-tiny:       var(--wp--preset--spacing--tiny);
	--sbc-space-xsmall:     var(--wp--preset--spacing--xsmall);
	--sbc-space-xxsmall:    var(--wp--preset--spacing--xxsmall);
	--sbc-space-xxxsmall:   var(--wp--preset--spacing--xxxsmall);
	--sbc-space-small:      var(--wp--preset--spacing--small);
	--sbc-space-medium:     var(--wp--preset--spacing--medium);
	--sbc-space-regular:    var(--wp--preset--spacing--regular);
	--sbc-space-xnormal:    var(--wp--preset--spacing--xnormal);
	--sbc-space-normal:     var(--wp--preset--spacing--normal);
	--sbc-space-large:      var(--wp--preset--spacing--large);
	--sbc-space-big:        var(--wp--preset--spacing--big);
	--sbc-space-xbig:       var(--wp--preset--spacing--xbig);
	--sbc-space-jumbo:      var(--wp--preset--spacing--jumbo);
	--sbc-space-massive:    var(--wp--preset--spacing--massive);
	--sbc-space-colossal:   var(--wp--preset--spacing--colossal);
	--sbc-space-huge:       var(--wp--preset--spacing--huge);

	/* --- Rayons ------------------------------------------------------------ */

	--sbc-radius-tiny:      var(--wp--preset--border-radius--tiny);
	--sbc-radius-xsmall:    var(--wp--preset--border-radius--xsmall);
	--sbc-radius-xxsmall:   var(--wp--preset--border-radius--xxsmall);
	--sbc-radius-small:     var(--wp--preset--border-radius--small);
	--sbc-radius-medium:    var(--wp--preset--border-radius--medium);
	--sbc-radius-regular:   var(--wp--preset--border-radius--regular);
	--sbc-radius-large:     var(--wp--preset--border-radius--large);
	--sbc-radius-big:       var(--wp--preset--border-radius--big);
	--sbc-radius-soft:      var(--wp--preset--border-radius--soft);
	--sbc-radius-pill:      var(--wp--preset--border-radius--pill);
	--sbc-radius-circle:    var(--wp--preset--border-radius--circle);

	/* --- Ombres ------------------------------------------------------------ */

	--sbc-shadow-card:      var(--wp--preset--shadow--card);
	--sbc-shadow-raised:    var(--wp--preset--shadow--raised);

	/* --- Mouvement ---------------------------------------------------------
	   Valeurs du site de reference : .25s sur 15 declarations, .3s sur une.
	   Toute transition du theme passe par ces deux variables : c'est ce qui
	   permet de neutraliser le mouvement plus bas sans un seul !important. */

	--sbc-transition-base:  var(--wp--custom--transition--base);
	--sbc-transition-slow:  var(--wp--custom--transition--slow);

	/* --- Champs et cibles tactiles ----------------------------------------
	   Contraintes non negociables de brand/charte.md : cibles 44 px minimum,
	   boutons 48 px de haut. La hauteur de champ du site de reference
	   (3.5625rem = 57 px) est au-dessus des deux. */

	--sbc-control-height:   var(--wp--custom--control--height);
	--sbc-control-radius:   var(--wp--custom--control--radius);
	--sbc-control-textarea: var(--wp--custom--control--textarea);
	--sbc-target-min:       var(--wp--custom--control--target);
	--sbc-button-height:    var(--wp--custom--control--button);

	/* --- Focus -------------------------------------------------------------
	   Porte par le teal #0F7A74 (5,18:1 sur blanc). Jamais supprime. */

	--sbc-focus-width:      var(--wp--custom--focus--width);
	--sbc-focus-offset:     var(--wp--custom--focus--offset);

	/* --- Mise en page ------------------------------------------------------
	   Une seule largeur de conteneur dans tout le systeme : 81rem. */

	--sbc-container-max:    var(--wp--style--global--content-size, 81rem);
	--sbc-container-gutter: var(--sbc-space-small);
	--sbc-measure:          var(--wp--custom--measure);

	/* Decalage d'ancre : le header est colle en haut, les liens #devis et
	   #faq doivent s'arreter dessous. Ajuste par le header une fois pose. */
	--sbc-header-height:    5rem;
}

/* Respect de prefers-reduced-motion sans !important : on annule les durees a
   la source. Toute transition du theme lisant --sbc-transition-*, il n'y a
   rien d'autre a neutraliser. */
@media (prefers-reduced-motion: reduce) {

	:root {
		--sbc-transition-base: 0s;
		--sbc-transition-slow: 0s;
	}
}


/* ============================================================================
   01-base — reset minimal et elements HTML
   ----------------------------------------------------------------------------
   Seul fichier de la feuille ou un selecteur d'element nu est autorise
   (CLAUDE.md, section CSS). Tout le reste est en BEM.

   Ce qui n'est PAS ici : la police, les couleurs, les tailles de titre, les
   styles de lien et de bouton, le fond / la bordure / le rayon / le padding
   des champs. Ils viennent de theme.json (styles.elements) et sont servis par
   les styles globaux de WordPress. On ne les redouble pas ici : une seule
   source par decision.

   Une exception assumee : les HAUTEURS de champ restent ici. L'element
   `textInput` de theme.json vise `textarea` et `input[...]` d'un seul tenant,
   et ne sait donc pas donner 3.5625 rem a l'un et 11.9375 rem a l'autre.

   ---------------------------------------------------------------------------
   ARBITRAGE — le role monospace laisse ouvert par brand/charte.md
   ---------------------------------------------------------------------------
   Le site de reference pose ses sur-titres, ses etiquettes et ses libelles de
   bouton en monospace capitales espacees (Geist Mono, 26 usages). Option (a)
   retenue : Jost partout, aucune seconde fonte.

   Trois raisons, dans l'ordre de poids :

   1. La signature du logo n'est pas monospace. La baseline « PRINT. LETTER.
      SIGN. » est en capitales SERIF espacees (brand/charte.md, section Logo).
      Ce qui la caracterise est l'espacement des capitales, pas la chasse fixe.
      Une monospace serait donc un emprunt au template, pas un rappel de la
      marque.
   2. La raison d'etre de la v1 est un formulaire. Le template porte ses
      libelles de champ dans ce meme role : les passer en monospace capitales a
      0,875 rem degrade la lisibilite exactement la ou la charte l'exige la
      plus haute (« labels toujours visibles »). Ils restent donc en Jost, en
      casse normale.
   3. Une seconde fonte, c'est 20 Ko de plus pour un role decoratif, sur un
      site dont la cible est Lighthouse mobile >= 90.

   Le role n'est pas supprime pour autant, il est retypographie : Jost 500,
   capitales, interlettrage +0,08 em (--sbc-tracking-label). Revenir sur cet
   arbitrage tient en une ligne : redefinir --sbc-font-label ici et l'appliquer
   la ou --sbc-tracking-label est deja pose.
   ========================================================================== */

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

html {
	-webkit-text-size-adjust: 100%;
	text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--sbc-header-height) + var(--sbc-space-small));
}

@media (prefers-reduced-motion: reduce) {

	html {
		scroll-behavior: auto;
	}
}

body {
	margin: 0;
	min-height: 100vh;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

/* Marges verticales : on les remet a zero et le rythme est porte par les
   blocs eux-memes (gap, .u-flow), jamais par des marges d'element qui
   fusionnent. */
h1,
h2,
h3,
h4,
h5,
h6,
p,
figure,
blockquote,
dl,
dd,
ul,
ol,
pre {
	margin: 0;
}

ul,
ol {
	padding-left: var(--sbc-space-medium);
}

h1,
h2,
h3,
h4,
h5,
h6 {
	text-wrap: balance;
}

p {
	text-wrap: pretty;
}

/* Medias : jamais de debordement, jamais de saut de mise en page. Les
   attributs width et height restent obligatoires dans le HTML pour reserver
   la place (CLS) ; height: auto les laisse respirer. */
img,
picture,
video,
canvas,
svg,
iframe {
	display: block;
	max-width: 100%;
}

img,
video {
	height: auto;
}

/* Les icones pleines suivent la couleur du texte. La condition `:not([fill])`
   est essentielle : une regle CSS l'emporte toujours sur un attribut de
   presentation, donc `svg { fill: currentColor }` ecrasait le `fill="none"`
   des traces au trait — fleches de bouton et glyphes de .icone — et les
   transformait en aplats noirs. En ne visant que les SVG SANS attribut fill,
   on laisse chaque trace decider. */
svg:not([fill]) {
	fill: currentColor;
}

hr {
	border: 0;
	border-top: 1px solid var(--sbc-color-border);
	margin: var(--sbc-space-big) 0;
}

strong,
b {
	font-weight: var(--sbc-weight-medium);
}

abbr[title] {
	text-decoration: underline dotted;
	cursor: help;
}

::selection {
	background-color: var(--sbc-color-surface-accent-soft);
	color: var(--sbc-color-text);
}

/* --- Focus ---------------------------------------------------------------
   Non negociable (brand/charte.md, Accessibilite) : anneau visible sur tous
   les elements interactifs, porte par le teal. Jamais d'outline: none nulle
   part ailleurs dans la feuille. */

:focus-visible {
	outline: var(--sbc-focus-width) solid var(--sbc-color-primary);
	outline-offset: var(--sbc-focus-offset);
}

/* --- Formulaires ---------------------------------------------------------
   L'habillage (fond, bordure, rayon, hauteur, padding) vient de theme.json,
   elements.textInput et elements.select. On ne traite ici que ce que
   theme.json ne sait pas exprimer : heritage de police, etats, et les
   contraintes de taille de cible. */

button,
input,
optgroup,
select,
textarea {
	font: inherit;
	letter-spacing: inherit;
	margin: 0;
}

label {
	display: inline-block;
	font-weight: var(--sbc-weight-medium);
}

input,
select,
textarea {
	max-width: 100%;
	transition: border-color var(--sbc-transition-base);
}

input:hover,
select:hover,
textarea:hover {
	border-color: var(--sbc-color-text-muted);
}

input:focus,
select:focus,
textarea:focus {
	border-color: var(--sbc-color-primary);
}

/* 3.5625 rem = 57 px, valeur du site de reference. Elle depasse les deux
   planchers de la charte (cible 44 px, bouton 48 px), on la garde telle
   quelle. Les cases a cocher et les boutons radio en sont exclus. */
input:not([type="checkbox"], [type="radio"], [type="hidden"]),
select {
	min-height: var(--sbc-control-height);
}

textarea {
	min-height: var(--sbc-control-textarea);
	padding-top: var(--sbc-space-small);
	padding-bottom: var(--sbc-space-small);
	resize: vertical;
}

/* Le placeholder ne remplace jamais un label : il ne porte que des exemples,
   donc il est volontairement en texte secondaire. */
::placeholder {
	color: var(--sbc-color-text-muted);
	opacity: 1;
}

/* Chevron dessine en deux degrades plutot qu'en image : il herite de
   currentColor, donc il suit le texte du champ sans second fichier a servir. */
select {
	appearance: none;
	background-image:
		linear-gradient(45deg, transparent 50%, currentColor 50%),
		linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position:
		calc(100% - var(--sbc-space-medium) - 0.375rem) center,
		calc(100% - var(--sbc-space-medium)) center;
	background-size: 0.375rem 0.375rem;
	background-repeat: no-repeat;
}

input[type="checkbox"],
input[type="radio"] {
	accent-color: var(--sbc-color-primary);
	width: 1.125rem;
	height: 1.125rem;
}

input[type="file"] {
	min-height: var(--sbc-target-min);
	padding: var(--sbc-space-xsmall);
}

/* Cibles tactiles : 44 px minimum partout, 48 px pour les boutons
   (brand/charte.md). Le rayon et les couleurs viennent de theme.json,
   elements.button, pour tout ce qui porte .wp-element-button ; la hauteur
   minimale est imposee ici a tous les boutons natifs, y compris ceux emis
   par le plugin de formulaire. */
button,
[type="button"],
[type="reset"],
[type="submit"] {
	min-height: var(--sbc-button-height);
	cursor: pointer;
	transition: background-color var(--sbc-transition-base), color var(--sbc-transition-base);
}

button[disabled],
input[disabled],
select[disabled],
textarea[disabled] {
	cursor: not-allowed;
	opacity: 0.55;
}

fieldset {
	border: 0;
	margin: 0;
	min-width: 0;
	padding: 0;
}

legend {
	padding: 0;
	font-weight: var(--sbc-weight-medium);
}

/* --- Tableaux ------------------------------------------------------------ */

table {
	border-collapse: collapse;
	width: 100%;
}

th,
td {
	border-bottom: 1px solid var(--sbc-color-border);
	padding: var(--sbc-space-xxsmall) var(--sbc-space-small);
	text-align: left;
	vertical-align: top;
}

th {
	font-weight: var(--sbc-weight-medium);
}


/* ============================================================================
   02-layout — conteneur et rythme vertical
   ----------------------------------------------------------------------------
   Une seule largeur de conteneur dans tout le systeme : 81 rem
   (brand/charte.md, section Echelles). Il n'y a donc PAS de modificateur
   `--wide` ou `--large` : s'il en faut un un jour, c'est la charte qu'on
   rouvre, pas ce fichier.

   Le padding lateral appartient au conteneur, jamais a <body> : les sections
   doivent pouvoir porter un aplat pleine largeur sans bande blanche sur les
   bords. C'est pour cette raison que `useRootPaddingAwareAlignments` est
   desactive dans theme.json.

   Rythme vertical d'une section : le site de reference pose un padding `huge`
   en haut et en bas sur sa `.wrapper` — 7,5 rem au repos, qui redescend a
   5 rem puis 4 rem sur les petits ecrans. Notre `--sbc-space-huge` est un
   clamp() de 4 a 7,5 rem : il rend ces trois paliers sans une seule media
   query.

   ATTENTION : ce commentaire a d'abord annonce `massive` (5 rem), par lecture
   trop rapide de la feuille de reference. C'etait faux, et toutes les sections
   l'ont suivi avant correction. Le rythme du template est ce qui lui donne sa
   respiration ; le raccourcir de deux tiers suffisait a rendre la page
   dense et a la faire paraitre eloignee du modele.

   Il n'y a volontairement pas de classe `.section` generique ici : la regle du
   projet est un bloc BEM par partial (`.hero`, `.faq`, `.film-sable`), chacun
   posant `padding-block: var(--sbc-space-huge)` dans son propre fichier de
   04-sections/. L'ecart entre l'en-tete d'une section et son contenu est,
   lui, `xbig` — c'est le `gap` de la `.wrapper` de reference.

   Media queries en min-width uniquement (CLAUDE.md, section CSS).
   ========================================================================== */

/* `overflow-x: clip` et non `hidden` : `clip` rogne le debordement sans creer
   de conteneur de defilement, les positions collees a l'interieur continuent
   donc de fonctionner (l'apparte du formulaire de devis en depend). Il protege
   la page des deplacements lateraux des apparitions au defilement, qui
   ajouteraient sinon une barre horizontale le temps de l'animation. */
.site-main {
	display: block;
	overflow-x: clip;
}

/* --- Conteneur ------------------------------------------------------------
   Le seul primitif de mise en page global. Un bloc BEM pleine largeur pose un
   `.container` a l'interieur de sa `<section>`, jamais autour : c'est ce qui
   permet a la section de garder son aplat de bord a bord.

   `max-width` inclut le padding (box-sizing: border-box, 01-base.css), comme
   dans le site de reference : 81 rem de boite, 79 rem de contenu. */

.container {
	width: 100%;
	max-width: var(--sbc-container-max);
	margin-inline: auto;
	padding-inline: var(--sbc-container-gutter);
}


/* ============================================================================
   .bouton — seul composant bouton du theme
   ----------------------------------------------------------------------------
   `primary-button` du site de reference : capitales espacees, fleche dans sa
   propre boite, rayon xxsmall. Le template superpose deux copies du texte et
   les fait glisser au survol ; l'effet est ramene ici a un deplacement de la
   fleche.

   REPARTITION DES COULEURS — c'est ce qui donne au template son economie.
   Le bouton de corps de page est NOIR. La couleur d'accent n'apparait que deux
   fois : dans la barre de navigation, et sur le petit bouton pose sur une
   carte. On suit cette repartition, qui recoupe les 5 % de teal reserves a
   l'action par brand/charte.md.

   ---------------------------------------------------------------------------
   TAILLE — CE QUI PEUT SE REDUIRE ET CE QUI NE LE PEUT PAS
   ---------------------------------------------------------------------------
   Le bouton a d'abord ete pose a `padding: medium regular` sur du texte de
   1 rem, soit 3,75 rem de haut : il ecrasait tout ce qui l'entourait. Il est
   ramene a `xsmall medium` sur du texte de 0,875 rem — le calibre exact du
   bouton de la barre de navigation, qui devient ainsi le seul calibre de
   bouton du site.

   La HAUTEUR, elle, ne descend pas : --sbc-button-height vaut 3 rem, soit les
   48 px que brand/charte.md pose comme plancher pour un bouton. Le padding
   reduit ne rapetisse donc pas la cible tactile, il resserre le texte dedans.
   C'est la seule limite non negociable de ce fichier : ce qui se reduit ici,
   c'est le remplissage et le corps du texte, jamais la boite.
   ========================================================================== */

.bouton {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sbc-space-tiny);
	min-height: var(--sbc-button-height);
	padding: var(--sbc-space-xsmall) var(--sbc-space-medium);
	border: 1px solid transparent;
	border-radius: var(--sbc-radius-xxsmall);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-tight);
	text-align: center;
	text-decoration: none;
	text-transform: uppercase;
	transition:
		background-color var(--sbc-transition-base),
		border-color var(--sbc-transition-base),
		color var(--sbc-transition-base),
		transform var(--sbc-transition-base);
}

/* Le bouton s'enfonce d'un cheveu au clic : c'est le seul retour tactile du
   composant, et il ne coute rien puisque transform est deja anime. */
.bouton:active {
	transform: translateY(1px);
}

/* --- Variantes ----------------------------------------------------------- */

.bouton--primaire {
	background-color: var(--sbc-color-contrast);
	color: var(--sbc-color-white);
}

.bouton--primaire:hover,
.bouton--primaire:focus-visible {
	background-color: var(--sbc-color-primary);
	color: var(--sbc-color-white);
}

/* Ecart assume au template : celui-ci pose du texte NOIR sur sa couleur
   d'accent (3,5:1). Le blanc sur le teal donne 5,18:1, il est conserve. */
.bouton--accent {
	background-color: var(--sbc-color-primary);
	color: var(--sbc-color-white);
}

.bouton--accent:hover,
.bouton--accent:focus-visible {
	background-color: var(--sbc-color-primary-dark);
	color: var(--sbc-color-white);
}

.bouton--clair {
	background-color: var(--sbc-color-white);
	color: var(--sbc-color-text);
}

.bouton--clair:hover,
.bouton--clair:focus-visible {
	background-color: var(--sbc-color-surface-accent);
	color: var(--sbc-color-text);
}

/* --- Secondaire -----------------------------------------------------------
   Le meme bouton que le noir, en blanc. C'est la demande du client (11
   septembre 2026) : les liens secondaires — « Voir nos realisations » dans le
   hero et les sections de films, « Demander un devis » en face du titre de la
   galerie — portaient la pilule blanche a fleche dans un disque teal du site
   de reference (« All Case Studies »). Ils reprennent desormais le calibre, le
   rayon et les capitales du bouton principal, pour que les deux boutons du
   hero se lisent comme une paire.

   L'ombre est ce qui le distingue d'un blanc sur blanc : sans elle, sur les
   sections blanches, le bouton n'aurait plus de bord. Elle reste legere
   (--sbc-shadow-card, celle des cartes), et passe a --sbc-shadow-raised au
   survol, le meme cran que les cartes qui se soulevent.

   Pourquoi pas la variante « clair » : elle est faite pour un aplat sombre et
   son survol pose le vert sauge en fond, ce qui mettrait une tache verte au
   milieu des 80 % de blanc de la page. Ici, le survol ne change que la couleur
   du texte, au teal fonce, et la fleche glisse comme sur tous les boutons. */

.bouton--secondaire {
	background-color: var(--sbc-color-white);
	box-shadow: var(--sbc-shadow-card);
	color: var(--sbc-color-text);
	transition:
		background-color var(--sbc-transition-base),
		border-color var(--sbc-transition-base),
		box-shadow var(--sbc-transition-base),
		color var(--sbc-transition-base),
		transform var(--sbc-transition-base);
}

.bouton--secondaire:hover,
.bouton--secondaire:focus-visible {
	box-shadow: var(--sbc-shadow-raised);
	color: var(--sbc-color-primary-dark);
}

/* Glyphe de tete, facultatif. Il double le libelle, il ne le remplace jamais :
   c'est pour cela qu'il peut etre `aria-hidden` sans rien couter. */
.bouton__icone {
	flex: none;
}

/* --- Fleche --------------------------------------------------------------
   Le decalage au survol est le seul mouvement du composant. Il passe par
   --sbc-transition-base, donc il tombe a 0s sous prefers-reduced-motion sans
   une ligne de plus. */

.bouton__fleche {
	display: inline-flex;
	flex: none;
	transition: transform var(--sbc-transition-base);
}

.bouton:hover .bouton__fleche,
.bouton:focus-visible .bouton__fleche {
	transform: translateX(0.25rem);
}

/* Bouton pleine largeur sur mobile : un CTA de fin de section ne doit pas
   flotter seul au milieu d'une colonne etroite. */
.bouton--bloc {
	display: flex;
	width: 100%;
}

@media (min-width: 40rem) {

	.bouton--bloc {
		display: inline-flex;
		width: auto;
	}
}


/* ============================================================================
   .carte-media — photo a panneau de verre depoli
   ----------------------------------------------------------------------------
   Motif signature du site de reference (`case-card` + `case-card-details`).
   Valeurs reprises telles quelles : panneau en position absolue a
   `inset: auto .625rem .625rem`, flou de 22 px, fond blanc a 35 %, rayon bas
   `regular`, grille 1fr .5fr, padding `xnormal`.

   La photo, elle, porte le rayon `regular` sur ses quatre coins.
   ========================================================================== */

.carte-media {
	position: relative;
	overflow: hidden;
	border-radius: var(--sbc-radius-regular);
	background-color: var(--sbc-color-surface-muted);
}

.carte-media__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Les sources melangent du 450x800 et du 800x450 : sans ratio impose, une
   rangee de cartes part en escalier. Les photos sont publiees en 1920 px au
   plus (1249 px pour les plus anciennes) : le cadre rogne, il n'agrandit
   jamais. */
.carte-media--carre {
	aspect-ratio: 1 / 1;
}

.carte-media--portrait {
	aspect-ratio: 3 / 4;
}

/* --- Panneau de verre -----------------------------------------------------
   Le fond blanc translucide ne suffit pas seul a garantir le contraste : le
   flou est ce qui aplatit la photo derriere lui. La regle @supports plus bas
   remplace donc le duo par un fond opaque partout ou le flou n'est pas rendu,
   plutot que de laisser le texte se poser sur une photo a peine voilee. */

.carte-media__panneau {
	position: absolute;
	inset: auto 0.625rem 0.625rem;
	z-index: 1;
	display: grid;
	gap: var(--sbc-space-medium);
	padding: var(--sbc-space-normal);
	border-radius: var(--sbc-radius-medium);
	background-color: rgb(255 255 255 / 82%);
	color: var(--sbc-color-text);
}

@supports (backdrop-filter: blur(22px)) or (-webkit-backdrop-filter: blur(22px)) {

	.carte-media__panneau {
		background-color: rgb(255 255 255 / 62%);
		-webkit-backdrop-filter: blur(22px);
		backdrop-filter: blur(22px);
	}
}

.carte-media__texte {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: var(--sbc-space-tiny);
}

/* Le titre reprend la taille du corps augmente plutot que celle d'un h3 : dans
   un panneau de 1,5 rem de padding, l'echelle de titre du theme (3,375 rem)
   deborderait. La hierarchie du document reste celle du niveau de balise —
   et quand la carte precede le titre de sa section, ce niveau peut etre un
   simple <p>, qui prend ici exactement la meme apparence. */
.carte-media__titre {
	font-weight: var(--sbc-weight-medium);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-h6);
	line-height: var(--sbc-leading-heading);
	letter-spacing: -0.02em;
}

.carte-media__resume {
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-base);
	line-height: var(--sbc-leading-body);
}

.carte-media__action {
	display: flex;
	align-items: flex-start;
}

/* --- Mobile : la carte se redresse ----------------------------------------
   Le panneau est ancre en bas (`inset: auto .625rem .625rem`) : il grandit donc
   vers le HAUT. Dans un cadre en 16/9 de 343 px de large, il depassait le bord
   superieur de la carte et se faisait rogner par l'overflow — le titre
   disparaissait purement et simplement.

   La reference regle cela en redressant ses cartes sur petit ecran (328x384,
   soit 5/6) et en resserrant le padding du panneau. On fait pareil : le cadre
   gagne en hauteur, le panneau en occupe une part raisonnable, et le titre
   reste dans le champ.

   C'est une regle mobile-first, donc elle vient AVANT la media query : les
   ratios paysage et large ne reprennent leur valeur qu'a partir de 48 rem. */

.carte-media--paysage,
.carte-media--large {
	aspect-ratio: 5 / 6;
}

.carte-media__panneau {
	padding: var(--sbc-space-small);
}

/* En dessous de 48 rem le panneau passe en une colonne : une carte de 320 px
   ne peut pas porter un texte et un bouton cote a cote. */
@media (min-width: 48rem) {

	.carte-media--paysage {
		aspect-ratio: 16 / 10;
	}

	.carte-media--large {
		aspect-ratio: 16 / 9;
	}


	.carte-media__panneau {
		grid-template-columns: 1fr auto;
		align-items: center;
		gap: var(--sbc-space-normal);
		padding: var(--sbc-space-xnormal);
	}

	.carte-media__action {
		align-items: center;
	}
}

/* --- Survol ---------------------------------------------------------------
   La photo avance d'un cheveu sous le panneau. Le mouvement passe par
   --sbc-transition-slow, il tombe donc a 0s sous prefers-reduced-motion sans
   une ligne de plus.

   `:focus-within` autant que `:hover` : une carte dont le bouton recoit le
   focus au clavier doit reagir comme sous la souris. */

.carte-media__image {
	transition: transform var(--sbc-transition-slow);
}

.carte-media:hover .carte-media__image,
.carte-media:focus-within .carte-media__image {
	transform: scale(1.04);
}


/* ============================================================================
   .figure — visuel de la mediatheque dans son cadre
   ----------------------------------------------------------------------------
   Le fonds photo melange des 450x800 et des 800x450 dans une meme serie
   (CLAUDE.md, « Medias ») : sans ratio impose, une grille de vignettes part en
   escalier. Les modificateurs recadrent en dur via object-fit, ce qui est
   assume, plutot que de laisser chaque photo dicter sa hauteur.

   Le rayon et le rognage sont portes par le <figure>, pas par l'image : c'est
   lui qui doit masquer le debordement quand l'image se rapproche au survol.
   Le <figure> n'a pas de fond propre, sa legende n'herite donc de rien.

   Les photos sont publiees en 1920 px au plus (1249 px pour les plus
   anciennes) : on n'agrandit jamais une image au-dela de sa source, on la
   rogne.
   ========================================================================== */

.figure {
	margin: 0;
	overflow: hidden;
	border-radius: var(--sbc-radius-medium);
}

.figure__image {
	width: 100%;
	height: auto;
	background-color: var(--sbc-color-surface-muted);
	transition: transform var(--sbc-transition-slow);
}

/* --- Recadrages ---------------------------------------------------------- */

.figure--paysage .figure__image,
.figure--portrait .figure__image,
.figure--carre .figure__image {
	object-fit: cover;
}

.figure--paysage .figure__image {
	aspect-ratio: 16 / 10;
}

.figure--carre .figure__image {
	aspect-ratio: 1 / 1;
}

.figure--portrait .figure__image {
	aspect-ratio: 3 / 4;
}

/* --- Survol ---------------------------------------------------------------
   Meme rapprochement que sur .carte-media, pour que les deux familles de
   visuels se comportent pareil. Le mouvement passe par --sbc-transition-slow,
   il tombe donc a 0s sous prefers-reduced-motion.

   `:focus-within` autant que `:hover` : une vignette dont le lien recoit le
   focus au clavier doit reagir comme sous la souris. */

.figure:hover .figure__image,
.figure:focus-within .figure__image {
	transform: scale(1.04);
}

/* La legende vit sous le cadre. Le <figure> n'ayant pas de fond, son rayon
   n'a rien a rogner autour d'elle. */
.figure__legende {
	padding-block-start: var(--sbc-space-xsmall);
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}


/* ============================================================================
   .footer — pied de page
   ----------------------------------------------------------------------------
   Bloc de `footer.php`. Reprend la structure du pied de page du site de
   reference : aplat sombre, colonne de marque a gauche separee par un filet
   vertical, colonnes de liens a droite, barre de mentions en bas. Ce qui n'est
   PAS repris : le bloc newsletter (aucune liste de diffusion) et le paragraphe
   de description en pied, qui n'a pas d'equivalent dans le contenu Sobecom.

   Contraste, sur l'aplat #111111 :
     blanc                          18,9:1
     vert sauge #82C7AB              9,4:1  (accent, ici en TEXTE, pas en fond)
     --sbc-color-text-on-dark-muted  7,9:1  (etiquettes, mentions)

   Rappel de brand/charte.md : l'interdiction porte sur le TEXTE POSE SUR un
   aplat de vert sauge. En texte sur fond sombre, le meme vert est le role
   d'accent du site de reference. Il n'y a donc ici aucun aplat sauge.
   ========================================================================== */

.footer {
	background-color: var(--sbc-color-contrast);
	color: var(--sbc-color-white);
	padding-block: var(--sbc-space-xbig) var(--sbc-space-medium);
}

.footer__inner {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-large);
}

.footer__haut {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sbc-space-big);
}

/* --- Colonne de marque ---------------------------------------------------- */

.footer__marque {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-normal);
	padding-block-end: var(--sbc-space-large);
	border-block-end: 1px solid var(--sbc-color-text-muted);
}

/* Marque en toutes lettres, pas en image : le logo blanc disponible est un
   derive automatique dont la banderole de baseline devient un aplat plein
   (brand/charte.md). Le site de reference pose lui aussi sa marque en texte
   ici. A remplacer par une <img> des reception du logo vectoriel. */
.footer__wordmark {
	color: var(--sbc-color-surface-accent);
	font-size: var(--sbc-text-h4);
	font-weight: var(--sbc-weight-medium);
	line-height: var(--sbc-leading-tight);
	letter-spacing: -0.03em;
}

.footer__wordmark-fin {
	color: var(--sbc-color-white);
}

.footer__coordonnees {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-regular);
}

.footer__bloc {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-tiny);
}

/* Role « sur-titre / etiquette » : le site de reference le porte en monospace
   capitales espacees, retypographie ici en Jost 500 capitales (arbitrage en
   tete de 01-base.css). */
/* Le glyphe des trois etiquettes de coordonnees. Les etiquettes de colonne
   (« Sur cette page », « Ce que nous faisons ») n'en portent pas : elles
   nomment une rubrique, pas un moyen de contact. */
/* `inline-block` explicite : 01-base.css pose `svg { display: block }` pour les
   visuels, ce qui ferait sauter le glyphe a la ligne au-dessus de son
   etiquette. */
.footer__glyphe {
	display: inline-block;
	margin-inline-end: var(--sbc-space-tiny);
	vertical-align: -0.2em;
}

.footer__etiquette {
	color: var(--sbc-color-text-on-dark-muted);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
}

.footer__adresse {
	color: var(--sbc-color-white);
	font-style: normal;
	line-height: var(--sbc-leading-body);
}

.footer__lien-contact {
	display: flex;
	align-items: center;
	min-height: var(--sbc-target-min);
	color: var(--sbc-color-white);
	text-decoration: none;
	transition: color var(--sbc-transition-base);
}

.footer__lien-contact:hover,
.footer__lien-contact:focus-visible {
	color: var(--sbc-color-surface-accent);
}

/* --- Reseaux sociaux ------------------------------------------------------
   Un seul reseau atteste, la page Facebook (brief/recherche-presence-en-ligne.md).
   La grille est prete a en accueillir d'autres le jour ou il y en aura. */

.footer__reseaux {
	display: flex;
	align-items: center;
	gap: var(--sbc-space-xsmall);
}

.footer__reseau {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--sbc-target-min);
	height: var(--sbc-target-min);
	color: var(--sbc-color-text-on-dark-muted);
	transition: color var(--sbc-transition-base);
}

.footer__reseau:hover,
.footer__reseau:focus-visible {
	color: var(--sbc-color-surface-accent);
}

.footer__icone {
	width: var(--sbc-space-regular);
	height: var(--sbc-space-regular);
}

/* --- Colonnes de liens ----------------------------------------------------
   `auto-fit` plutot qu'un point de bascule : les libelles metier vont jusqu'a
   « Impression grand format », ils reclament une colonne large. */

.footer__colonnes {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
	gap: var(--sbc-space-normal);
}

.footer__colonne {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-xxsmall);
}

.footer__menu {
	display: flex;
	flex-direction: column;

	/* Pas d'ecart : les liens font 44 px de haut, ils se touchent. Un ecart
	   creerait des zones mortes entre deux cibles tactiles. */
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
}

.footer__lien {
	display: flex;
	align-items: center;
	min-height: var(--sbc-target-min);
	color: var(--sbc-color-white);
	text-decoration: none;
	transition: color var(--sbc-transition-base);
}

.footer__lien:hover,
.footer__lien:focus-visible,
.footer__lien--actif {
	color: var(--sbc-color-surface-accent);
}

.footer__metiers {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-tiny);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Libelles, pas des liens : les pages metier n'arrivent qu'en v2. */
.footer__metier {
	color: var(--sbc-color-white);
}

/* --- Barre de mentions ---------------------------------------------------- */

.footer__bas {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-small);
	padding-block-start: var(--sbc-space-small);
	border-block-start: 1px solid var(--sbc-color-text-muted);
}

.footer__menu--legal {
	flex-direction: row;
	flex-wrap: wrap;
	gap: var(--sbc-space-medium);
}

.footer__mentions {
	color: var(--sbc-color-text-on-dark-muted);
	font-size: var(--sbc-text-small);
}

/* --- Grand ecran ---------------------------------------------------------- */

@media (min-width: 62rem) {

	.footer {
		padding-block: var(--sbc-space-jumbo) var(--sbc-space-medium);
	}

	.footer__haut {
		grid-template-columns: 0.55fr 1fr;
		gap: var(--sbc-space-colossal);
	}

	.footer__marque {
		justify-content: space-between;
		padding-block-end: 0;
		padding-inline-end: var(--sbc-space-big);
		border-block-end: 0;
		border-inline-end: 1px solid var(--sbc-color-text-muted);
	}

	.footer__bas {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
	}
}


/* ============================================================================
   .header — barre du haut et menu mobile
   ----------------------------------------------------------------------------
   Bloc de `header.php`. Reprend la barre du site de reference : aplat de fond
   de page, filet bas de 1 px, marque a gauche, liens au centre-droit, action a
   droite. Ce qui n'est PAS repris : le mega-menu deroulant (la v1 n'a qu'une
   page) et l'icone Lottie du bouton, qui demandait 900 Ko de runtime Webflow
   pour animer trois barres.

   Sous 62 rem, `.header__panneau` — le meme noeud, pas une copie — quitte le
   flux et devient un panneau plein ecran. Il n'y a donc qu'un seul jeu de
   liens dans le document, donc un seul ordre de tabulation a piloter.

   Le panneau se ferme et s'ouvre par `visibility`, pas par `display` : c'est
   ce qui permet a la transition d'exister ET aux liens de sortir de l'ordre de
   tabulation quand il est ferme, sans que le script ait a poser `inert`.

   Media queries en min-width uniquement. Point de bascule : 62 rem (992 px),
   celui du site de reference.
   ========================================================================== */

.header {

	/* Largeur du logo. Deux valeurs hors echelle, et c'est assume : le logo
	   n'est disponible qu'en PNG 500x125 (brand/charte.md, « Ce qui manque »).
	   140 px est le plancher fixe par la charte pour que la baseline
	   « PRINT. LETTER. SIGN. » reste lisible ; 170 px reste sous les 500 px
	   de la source, donc sans agrandissement. */
	--header-logo: 8.75rem;

	position: sticky;
	top: 0;
	z-index: 100;
	background-color: var(--sbc-color-surface);
	border-block-end: 1px solid var(--sbc-color-border);
}

.header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sbc-space-small);

	/* Hauteur pilotee par le meme jeton que le decalage d'ancre
	   (`scroll-padding-top`, 01-base.css) : les deux ne peuvent pas diverger. */
	min-height: var(--sbc-header-height);
}

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

.header__marque {
	display: flex;
	align-items: center;
	flex: none;
	text-decoration: none;
}

.header__logo {
	width: var(--header-logo);
	height: auto;
}

/* --- Panneau -------------------------------------------------------------- */

.header__panneau {
	position: fixed;
	inset: var(--sbc-header-height) 0 0;
	z-index: 90;
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-big);
	padding-block: var(--sbc-space-big) var(--sbc-space-massive);
	padding-inline: var(--sbc-container-gutter);
	overflow-y: auto;
	overscroll-behavior: contain;
	background-color: var(--sbc-color-surface);
	visibility: hidden;
	opacity: 0;
	translate: 0 -0.75rem;

	/* `visibility` n'est pas interpolee, elle est retardee : elle bascule a
	   `hidden` UNE FOIS le fondu termine (0s de duree, 0,25s de delai), et
	   revient a `visible` sans delai a l'ouverture. Une transition interpolee
	   laisserait le panneau `hidden` pendant la premiere image, juste assez
	   pour que `.focus()` echoue si l'utilisateur tabule tout de suite. */
	transition:
		opacity var(--sbc-transition-base),
		translate var(--sbc-transition-base),
		visibility 0s var(--sbc-transition-base);
}

.header--ouvert .header__panneau {
	visibility: visible;
	opacity: 1;
	translate: 0 0;
	transition:
		opacity var(--sbc-transition-base),
		translate var(--sbc-transition-base),
		visibility 0s;
}

/* Fige le defilement de la page derriere le panneau. Derive de l'etat du
   bloc plutot que d'une classe posee sur <body> par le script : l'etat n'est
   ecrit qu'a un seul endroit, sur `.header`. */
body:has(.header--ouvert) {
	overflow: hidden;
}

/* --- Menu ----------------------------------------------------------------- */

.header__menu {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xsmall);
	margin: 0;
	padding: 0;
	list-style: none;
}

.header__lien {
	display: flex;
	align-items: center;
	min-height: var(--sbc-target-min);
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-h6);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.02em;
	text-decoration: none;
	transition: color var(--sbc-transition-base);
}

.header__lien:hover,
.header__lien:focus-visible,
.header__lien--actif {
	color: var(--sbc-color-text);
}

/* --- Actions -------------------------------------------------------------- */

.header__actions {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--sbc-space-small);
	margin-block-start: auto;
	padding-block-start: var(--sbc-space-regular);
	border-block-start: 1px solid var(--sbc-color-border);
}

.header__tel {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: var(--sbc-target-min);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-m);
	font-weight: var(--sbc-weight-medium);
	text-decoration: none;
	transition: color var(--sbc-transition-base);
}

.header__tel:hover,
.header__tel:focus-visible {
	color: var(--sbc-color-primary);
}

/* Le fond, la couleur, le rayon et les etats viennent de theme.json
   (`styles.elements.button`, servi par la classe `wp-element-button`). Ne
   restent ici que les reglages propres a la barre : rendre le bouton compact
   sans descendre sous les 48 px de la charte. */
.header__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding-block: var(--sbc-space-xsmall);
	padding-inline: var(--sbc-space-medium);
	font-size: var(--sbc-text-small);
	white-space: nowrap;
}

/* --- Bouton du menu ------------------------------------------------------- */

.header__bascule {
	display: flex;
	flex: none;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--sbc-space-tiny);
	width: var(--sbc-button-height);
	padding: 0;
	border: 0;
	background-color: transparent;
	color: var(--sbc-color-text);
}

.header__barre {
	width: var(--sbc-space-regular);
	height: 2px;
	background-color: currentcolor;
	transition:
		translate var(--sbc-transition-base),
		rotate var(--sbc-transition-base),
		opacity var(--sbc-transition-base);
}

.header--ouvert .header__barre:first-child {
	translate: 0 0.375rem;
	rotate: 45deg;
}

.header--ouvert .header__barre:nth-child(2) {
	opacity: 0;
}

.header--ouvert .header__barre:last-child {
	translate: 0 -0.375rem;
	rotate: -45deg;
}

/* --- Grand ecran ---------------------------------------------------------- */

@media (min-width: 62rem) {

	.header {
		--header-logo: 10.625rem;
	}

	/* Le panneau redevient une simple rangee : plus de position fixe, plus
	   d'etat masque, donc plus rien a piloter par le script. */
	.header__panneau {
		position: static;
		z-index: auto;
		flex-direction: row;
		align-items: center;
		gap: var(--sbc-space-normal);
		padding: 0;
		overflow: visible;
		background-color: transparent;
		visibility: visible;
		opacity: 1;
		translate: none;
	}

	.header__menu {
		flex-direction: row;
		align-items: center;
		gap: var(--sbc-space-regular);
	}

	.header__lien {
		font-size: var(--sbc-text-base);
		font-weight: var(--sbc-weight-regular);
		letter-spacing: 0;
	}

	.header__actions {
		flex-direction: row;
		align-items: center;
		margin-block-start: 0;
		padding-block-start: 0;
		border-block-start: 0;
	}

	.header__bascule {
		display: none;
	}
}

/* ============================================================================
   .annonce — barre d'annonce au-dessus de la navigation
   ----------------------------------------------------------------------------
   « Announcement bar » du site de reference. Aplat sauge, texte noir
   (12,17:1) : c'est le seul couple autorise sur cet aplat par la charte.

   Elle defile avec la page plutot que de rester collee : coller deux barres
   l'une sur l'autre mangerait un cinquieme de l'ecran sur un portable.
   ========================================================================== */

.annonce {
	padding-block: var(--sbc-space-xsmall);
	background-color: var(--sbc-color-surface-accent);
	color: var(--sbc-color-text);
	text-align: center;
}

.annonce__texte {
	padding-inline: var(--sbc-space-small);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}

.annonce__lien {
	color: var(--sbc-color-text);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.annonce__lien::before {
	content: "\2192";
	padding-inline: 0.35em;
	text-decoration: none;
	display: inline-block;
}

.annonce__lien:hover,
.annonce__lien:focus-visible {
	text-decoration-thickness: 2px;
}

/* ============================================================================
   Etat de l'en-tete au defilement
   ----------------------------------------------------------------------------
   `.header--defile` est posee par assets/js/modules/animations.js des que la
   page quitte le haut. Sans elle, l'en-tete colle flotte sur le contenu sans
   limite visible. Le repli sans JavaScript est l'en-tete au repos, qui reste
   parfaitement lisible : la classe n'ajoute qu'une ombre et une bordure.
   ========================================================================== */

.header--defile {
	border-bottom-color: transparent;
	box-shadow: var(--sbc-shadow-card);
}


/* ============================================================================
   .icone — pastille d'icone ronde
   ----------------------------------------------------------------------------
   `icon-box` du site de reference : un cercle de 3,375 rem. La reference
   alterne les teintes de fond d'une carte a l'autre pour rythmer une rangee —
   un cercle a filet, un cercle rose, un cercle turquoise. On garde ce principe
   avec les aplats de la charte.

   Le glyphe herite de currentColor : c'est la variante qui decide sa couleur,
   pas le SVG.
   ========================================================================== */

.icone {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 3.375rem;
	height: 3.375rem;
	border-radius: var(--sbc-radius-circle);
}

.icone--contour {
	border: 1px solid var(--sbc-color-border);
	color: var(--sbc-color-text);
}

.icone--sauge {
	background-color: var(--sbc-color-surface-accent);
	color: var(--sbc-color-text);
}

.icone--teal {
	background-color: var(--sbc-color-surface-accent-subtle);
	color: var(--sbc-color-primary-dark);
}


/* ============================================================================
   .pastille — etiquette de categorie posee sur un visuel
   ----------------------------------------------------------------------------
   `tag` du site de reference : un aplat arrondi cale en haut a gauche d'une
   carte, PAR-DESSUS la photo. La reference le decale d'un cran vers l'interieur
   (margin small) plutot que de le coller au bord.

   Fond sauge, texte noir : 12,17:1. C'est le seul couple autorise sur cet
   aplat par brand/charte.md — ni le blanc (1,49:1) ni le teal (3,48:1) n'y
   passent.
   ========================================================================== */

.pastille {
	position: absolute;
	top: var(--sbc-space-small);
	left: var(--sbc-space-small);
	z-index: 2;
	padding: var(--sbc-space-tiny) var(--sbc-space-small);
	border-radius: var(--sbc-radius-pill);
	background-color: var(--sbc-color-surface-accent);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}


/* ============================================================================
   .section-entete — sur-titre + titre + chapo
   ----------------------------------------------------------------------------
   Deux declinaisons, celles du site de reference :

   CENTRE  — sur-titre, titre sur deux ou trois lignes, chapo au milieu. C'est
             l'ouverture des sections « manifeste ». Le titre y est volontairement
             large : la reference le laisse remplir la ligne.
   GAUCHE  — titre cale a gauche, action posee en face a droite sur la meme
             ligne de base. C'est l'ouverture des sections de contenu.

   Le composant ne porte AUCUN espacement exterieur : c'est la section qui le
   place. Un composant qui pousse ses voisins n'est pas reutilisable.
   ========================================================================== */

.section-entete {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-normal);
}

.section-entete__principal {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: var(--sbc-space-medium);
}

/* --- Aligne a gauche ------------------------------------------------------ */

.section-entete--gauche .section-entete__principal {
	align-items: flex-start;
}

.section-entete--gauche .section-entete__titre {
	max-width: 18ch;
}

.section-entete__titre--large {
	max-width: none;
}

/* --- Centre --------------------------------------------------------------- */

.section-entete--centre {
	align-items: center;
	text-align: center;
}

.section-entete--centre .section-entete__principal {
	align-items: center;
}

.section-entete--centre .section-entete__titre {
	max-width: 20ch;
}

/* Le chapo centre du template est un vrai enonce, pas une legende : il est a
   la taille d'un titre h5 et il occupe la largeur du conteneur. */
.section-entete--centre .section-entete__chapo {
	max-width: 40ch;
	font-size: var(--sbc-text-h6);
	line-height: var(--sbc-leading-heading);
}

/* --- Chapo ---------------------------------------------------------------- */

.section-entete__chapo {
	max-width: var(--sbc-measure);
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-m);
	line-height: var(--sbc-leading-body);
}

.section-entete__chapo > p + p {
	margin-block-start: var(--sbc-space-small);
}

/* --- Sur aplat sombre ----------------------------------------------------- */

.section-entete--clair .section-entete__titre {
	color: var(--sbc-color-white);
}

.section-entete--clair .section-entete__chapo {
	color: var(--sbc-color-text-on-dark-muted);
}

/* --- Action en vis-a-vis --------------------------------------------------
   A partir de 62 rem, le titre et son action se partagent la ligne, alignes
   sur le bas : c'est ce qui donne au template ses ouvertures de section larges
   plutot que des blocs empiles. */

@media (min-width: 48rem) {

	.section-entete--gauche .section-entete__titre {
		max-width: 22ch;
	}
}

@media (min-width: 62rem) {

	.section-entete--avec-action {
		flex-direction: row;
		align-items: flex-end;
		justify-content: space-between;
		gap: var(--sbc-space-jumbo);
	}

	.section-entete--avec-action .section-entete__action {
		flex: none;
		padding-block-end: var(--sbc-space-xsmall);
	}
}


/* ============================================================================
   .sur-titre — texte de rubrique au-dessus d'un titre
   ----------------------------------------------------------------------------
   `strategy-text` du site de reference : capitales espacees, poids moyen, en
   TEXTE NU. La reference ne met jamais de fond derriere ce role ; ce qui le
   signale, c'est l'interlettrage et la casse, pas un aplat.

   Le role etait porte en monospace par la reference ; il est rendu ici en Jost
   500, arbitrage documente en tete de 01-base.css.
   ========================================================================== */

.sur-titre {
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}

/* Gris et non noir : c'est la couleur du `subtitle-text` de la reference
   (#5A5A5A, notre --sbc-color-text-muted). Le sur-titre annonce la section, il
   ne la titre pas — en noir plein il concurrence le H2 qui le suit. 7:1 sur le
   fond de page. */
.sur-titre--sombre {
	color: var(--sbc-color-text-muted);
}

.sur-titre--clair {
	color: var(--sbc-color-white);
}


/* ============================================================================
   .visionneuse — agrandissement d'une realisation
   ----------------------------------------------------------------------------
   Bloc du <dialog> rendu par template-parts/components/visionneuse.php,
   appele en fin de la section realisations, pilote par
   assets/js/modules/visionneuse.js. Le site de reference n'a pas de
   visionneuse : la composition suit les conventions du theme, cadre au milieu,
   boutons ronds blancs, legende en clair.

   LE DIALOGUE EST LE VOILE. Il occupe tout l'ecran et porte lui-meme le fond
   sombre ; ::backdrop est rendu transparent. Le pseudo-element ::backdrop ne
   herite pas des variables CSS de :root dans tous les navigateurs (Chrome
   avant 122, Safari avant 17.4), et la couleur du voile y serait tombee sur
   du transparent. Porter le voile par le dialogue lui-meme regle le point sans
   une valeur en dur, et permet au module de reconnaitre un clic « a cote du
   cadre » : sa cible est alors le dialogue.

   L'IMAGE N'EST JAMAIS AGRANDIE. Elle est en width et height auto sous un
   max-width et une hauteur maximale en vh : sa boite est sa taille naturelle,
   et quand l'une des deux bornes joue, le navigateur reduit la boite au ratio
   intrinseque. La boite est donc exactement la photo peinte, sans bande
   transparente qui intercepterait le clic destine au voile. Les attributs
   width et height, poses par le module depuis les dimensions REELLES de la
   taille servie, ne servent plus qu'a reserver la place et a fournir le ratio
   avant chargement. object-fit: contain reste par securite : il n'a rien a
   centrer tant que la boite suit le ratio.

   Les boutons de commande sont FIXES au viewport, pas au cadre : sur un
   grand ecran les fleches vivent sur les flancs, la croix en haut a droite,
   quelle que soit la largeur de la photo. Le padding du dialogue leur reserve
   leur bande pour qu'ils ne recouvrent jamais l'image. Sous 48 rem, les
   fleches rentrent dans le flux, de part et d'autre du compteur, sous
   l'image : sur un telephone, deux boutons fixes sur les flancs mangeraient la
   photo.

   Le mouvement passe par --sbc-transition-base : il tombe a 0s sous
   prefers-reduced-motion sans une ligne de plus.

   Media queries en min-width uniquement.
   ========================================================================== */

.visionneuse {

	/* Hauteur de tout ce qui n'est pas la photo, du haut du voile au bas du
	   bouton d'action : bande de Fermer, ecarts, legende, compteur, fleches
	   en flux sous 48 rem, bouton, marge basse. Mesuree a 16 rem sur grand
	   ecran comme sur telephone, portee a 17 pour qu'une legende qui passe a
	   la ligne ne fasse pas deborder le cadre. C'est ce qui borne la photo :
	   elle prend tout le reste de l'ecran, et le dialogue n'a pas a defiler. */
	--visionneuse-reserve: 17rem;

	position: fixed;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	max-height: none;
	margin: 0;

	/* La bande du haut est celle du bouton Fermer, fixe au viewport. */
	padding: calc(var(--sbc-button-height) + var(--sbc-space-small) * 2) var(--sbc-space-small) var(--sbc-space-small);
	border: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	background-color: var(--sbc-color-backdrop);
	color: var(--sbc-color-white);
}

/* `[open]` et non le bloc nu : le navigateur masque un dialogue ferme par
   display: none, et une declaration display sur le bloc l'emporterait. */
.visionneuse[open] {
	display: flex;
}

.visionneuse::backdrop {
	background: transparent;
}

/* Verrou de defilement, pose sur <html> par le module tant que le dialogue est
   ouvert : un dialogue modal rend la page inerte, mais la molette y ferait
   encore defiler le document derriere le voile. */
.js-visionneuse-ouverte {
	overflow: hidden;
}

/* --- Cadre ----------------------------------------------------------------
   `margin: auto` et non `align-items: center` sur le dialogue : quand le
   cadre est plus haut que l'ecran, le centrage flex rognerait le haut du
   contenu hors de portee du defilement. La marge automatique centre quand il
   y a de la place et cale en haut quand il n'y en a pas. */

.visionneuse__cadre {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	grid-template-areas:
		"figure figure figure"
		"precedent compteur suivant"
		"action action action";
	gap: var(--sbc-space-small);
	align-items: center;
	width: 100%;
	max-width: var(--sbc-container-max);
	margin: auto;
}

/* --- Image et legende ---------------------------------------------------- */

.visionneuse__figure {
	grid-area: figure;
	min-width: 0;
}

/* Deux declarations de max-height : la seconde, en `svh`, mesure l'ecran
   d'un telephone barre d'adresse deployee et l'emporte la ou elle est
   comprise ; la premiere reste le repli. Le plancher de 40 vh sert aux ecrans
   tres bas (telephone en paysage) : le cadre y deborde et le dialogue
   defile, plutot que de reduire la photo a une vignette. */
.visionneuse__image {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: max(40vh, calc(100vh - var(--visionneuse-reserve)));
	max-height: max(40svh, calc(100svh - var(--visionneuse-reserve)));
	margin-inline: auto;
	object-fit: contain;
}

.visionneuse__legende {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sbc-space-tiny) var(--sbc-space-xsmall);
	align-items: baseline;
	justify-content: center;
	margin-block-start: var(--sbc-space-xsmall);
	text-align: center;
	line-height: var(--sbc-leading-body);
}

/* Meme badge que sous les vignettes (.realisations__ref) : la reference doit
   se reconnaitre d'un coup d'oeil entre la galerie et l'agrandissement. Teal
   fonce sur l'aplat teal 20 % : 5,67:1, la ou le teal de marque echoue
   (CLAUDE.md, « Charte »). */
.visionneuse__ref {
	padding: var(--sbc-space-tiny) var(--sbc-space-xsmall);
	border-radius: var(--sbc-radius-xsmall);
	background-color: var(--sbc-color-surface-accent-subtle);
	color: var(--sbc-color-primary-dark);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
}

/* Gris du site de reference pour du texte secondaire sur aplat sombre, celui
   du pied de page. Le voile est a 88 % : compose sur une page claire, il
   donne 6,4:1 avec ce gris (pire cas) et 13,7:1 avec le blanc, AA dans les
   deux cas. */
.visionneuse__categorie {
	color: var(--sbc-color-text-on-dark-muted);
	font-size: var(--sbc-text-small);
}

.visionneuse__compteur {
	grid-area: compteur;
	color: var(--sbc-color-text-on-dark-muted);
	font-size: var(--sbc-text-small);
	font-variant-numeric: tabular-nums;
	line-height: var(--sbc-leading-body);
	text-align: center;
}

/* --- Boutons ronds --------------------------------------------------------
   Blanc sur le voile, 3 rem de cote : le plancher des 48 px de brand/charte.md
   pour un bouton, et un disque, pas une pilule. L'anneau de focus du theme est
   teal (01-base.css) : sur le voile sombre il se verrait mal, il passe au blanc
   ici, avec le meme decalage. */

.visionneuse__fermer,
.visionneuse__precedent,
.visionneuse__suivant {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--sbc-button-height);
	height: var(--sbc-button-height);
	padding: 0;
	border: 0;
	border-radius: var(--sbc-radius-circle);
	background-color: var(--sbc-color-white);
	box-shadow: var(--sbc-shadow-raised);
	color: var(--sbc-color-text);
	transition:
		background-color var(--sbc-transition-base),
		color var(--sbc-transition-base);
}

.visionneuse__fermer:hover,
.visionneuse__precedent:hover,
.visionneuse__suivant:hover {
	background-color: var(--sbc-color-primary);
	color: var(--sbc-color-white);
}

.visionneuse__fermer:focus-visible,
.visionneuse__precedent:focus-visible,
.visionneuse__suivant:focus-visible {
	outline: var(--sbc-focus-width) solid var(--sbc-color-white);
	outline-offset: var(--sbc-focus-offset);
}

/* Le lien d'action aussi : le teal de 01-base.css tombe a 2,6:1 sur le voile,
   sous le plancher de 3:1 des elements d'interface ; le blanc tient 13,7:1.
   Meme precedent que contact.css sur son aplat noir. */
.visionneuse__action .bouton:focus-visible {
	outline-color: var(--sbc-color-white);
}

/* Une seule photo retenue par le filtre : le module masque les fleches. La
   regle est necessaire, la declaration display ci-dessus l'emporterait sur
   la feuille du navigateur. */
.visionneuse__precedent[hidden],
.visionneuse__suivant[hidden] {
	display: none;
}

.visionneuse__fermer {
	position: fixed;
	top: var(--sbc-space-small);
	right: var(--sbc-space-small);
	z-index: 1;
}

.visionneuse__precedent {
	grid-area: precedent;
}

.visionneuse__suivant {
	grid-area: suivant;
}

/* --- Action ---------------------------------------------------------------
   Le lien vers le formulaire. Sur un telephone il prend la largeur du cadre,
   comme tout appel a l'action de fin de section. */

.visionneuse__action {
	display: flex;
	grid-area: action;
	justify-content: center;
}

@media (min-width: 48rem) {

	.visionneuse {

		/* Les flancs sont ceux des fleches, fixes au viewport. */
		padding-inline: calc(var(--sbc-button-height) + var(--sbc-space-small) * 2);
	}

	.visionneuse__cadre {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas:
			"figure"
			"compteur"
			"action";
		gap: var(--sbc-space-medium);
	}

	.visionneuse__precedent,
	.visionneuse__suivant {
		position: fixed;
		top: 50%;
		z-index: 1;
		translate: 0 -50%;
	}

	.visionneuse__precedent {
		left: var(--sbc-space-small);
	}

	.visionneuse__suivant {
		right: var(--sbc-space-small);
	}
}


/* ============================================================================
   .atelier — bandeau de separation
   ----------------------------------------------------------------------------
   Une photo, rien d'autre. Elle separe le recit du service de celui de
   l'entreprise.

   PAS DE `padding-block: huge` ICI, contrairement aux neuf sections : le
   bandeau vit ENTRE deux sections qui portent deja chacune leur padding
   `huge`. En ajouter un troisieme creuserait un trou de 22 rem au milieu de la
   page.

   Il en porte tout de meme un, de `big` : sans lui, la photo commencait
   exactement la ou le fond de la section precedente s'arretait, et la ligne de
   changement de fond passait au ras de son bord superieur arrondi. Ce n'est pas
   une question d'espace — les deux voisines en donnent deja beaucoup — mais de
   bord : le blanc doit se voir AUTOUR du cadre pour qu'il se lise comme une
   image posee, pas comme un aplat colle au precedent.

   Le rapport du cadre change avec la largeur : la facade est un batiment tres
   allonge, un cadrage large la rend lisible sur grand ecran mais la reduit a
   une bande de 60 px sur telephone. Sous 48 rem, le cadre se redresse en 16/10
   et rogne les cotes.
   ========================================================================== */

.atelier {
	padding-block: var(--sbc-space-big);
	background-color: var(--sbc-color-white);
}

.atelier__cadre {
	overflow: hidden;
	border-radius: var(--sbc-radius-large);
	background-color: var(--sbc-color-surface-muted);
}

.atelier__image {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 16 / 10;
	object-fit: cover;
}

@media (min-width: 48rem) {

	/* 1360 / 636, le rapport natif du fichier : au-dela de ce point de bascule
	   le cadre est assez large pour l'accueillir sans rogner. */
	.atelier__image {
		aspect-ratio: 1360 / 636;
	}
}


/* ============================================================================
   .contact — section 9, bloc de cloture
   ----------------------------------------------------------------------------
   Bloc de `template-parts/sections/contact.php`. Reprend `section cta` du site
   de reference, valeur par valeur :

     aplat                        noir, de bord a bord          (.section.cta)
     photo                        plein cadre, derriere le texte (.cta-image)
     padding vertical             10,5 rem / 8 rem / 5 rem      (.cta-wrap)
     ecart titre / action         spacing-big, regular sous 991 px
     ecart sur-titre / titre      spacing-small                 (.cta-header)
     titre                        h2 blanc centre, 35 rem, 28 rem sous 991 px

   Le padding vertical du template est ecrit en dur a trois paliers. Il est
   rendu ici par `huge + xbig`, deux echelles fluides dont la somme vaut
   10,62 rem a 1440 px, 8,3 rem a 768 px et 6,25 rem a 375 px : les trois
   paliers, sans media query et sans valeur en dur.

   ---------------------------------------------------------------------------
   LA PHOTO DE FOND : DIMENSIONS ET CONTRASTE
   ---------------------------------------------------------------------------
   DIMENSIONS. La reference sert un fond de 2000 px et plus. Le fond pose ici
   fait 2400 px : il n'est agrandi sur aucun ecran, pas meme un 1920 px. C'est
   une image generee (photos/generees/README.md) parce qu'au 4 septembre 2026
   aucun visuel de vitrophanie de la mediatheque ne depassait 1249 px de large
   (CLAUDE.md, « Medias ») : le fond precedent, le plus large du fonds, etait
   agrandi de 54 % sur un ecran de 1920 px. Le lot du 16 septembre 2026 est
   publie en 1920 px ; une photo de chantier pourrait reprendre ce fond.

   CONTRASTE. Le texte est blanc, il ne doit jamais descendre sous 4,5:1. La
   photo est passee en niveaux de gris et posee a 35 % d'opacite SUR l'aplat
   noir : chaque pixel rendu vaut donc 0,35 x photo + 0,65 x l'aplat. Le pire
   cas theorique, un pixel blanc pur, ressort a un gris moyen qui donne 5,9:1
   avec du blanc, et aucun pixel ne peut faire moins. Mesure faite sur la
   capture a 1440 px : 10,4:1 median dans la zone de texte, 5,9:1 sur le pixel
   le plus clair. Le ratio est donc garanti par le calcul, pas par l'aspect de
   la photo : changer d'image ne peut pas casser le contraste tant que
   l'opacite reste a cette valeur.

   L'anneau de focus, lui, ne tient PAS avec le teal : sur les zones claires de
   la photo il tombe a 1,6:1, sous le plancher de 3:1 des elements d'interface.
   Il passe donc au blanc dans cette section, et seulement ici.
   ========================================================================== */

.contact {
	position: relative;
	overflow: clip;
	padding-block: calc(var(--sbc-space-huge) + var(--sbc-space-xbig));
	background-color: var(--sbc-color-contrast);
}

/* --- Fond -----------------------------------------------------------------
   L'element reste un <img> et non un `background-image` : c'est ce qui lui
   garde son srcset, son chargement differe et le texte alternatif saisi a
   l'import. La reference fait le meme choix. */

.contact__fond {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	filter: grayscale(1);
	object-fit: cover;
	opacity: 0.35;
}

/* `position: relative` sans z-index suffit a passer devant la photo : les deux
   sont dans le meme contexte d'empilement et celui-ci vient apres dans le
   document. */
.contact__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sbc-space-regular);
}

/* --- En-tete --------------------------------------------------------------
   28 rem puis 35 rem : les deux largeurs de `cta-title`. Le titre du template
   y tient sur deux lignes ; « Parlons de vos vitres » est plus court et tient
   sur une, a la meme taille. La contrainte est gardee telle quelle : c'est
   elle qui borne le chapo et centre le bloc. */

.contact__entete {
	width: 100%;
	max-width: 28rem;
}

/* Le chapo passe au blanc, et c'est la photo qui l'impose. Le gris de
   --sbc-color-text-on-dark-muted tient a 7,9:1 sur l'aplat nu, mais il retombe
   a 2,8:1 sur les pixels les plus clairs de l'image -- ici le reflet blanc
   d'une camionnette, exactement sous ces deux phrases. En blanc, le pire cas
   remonte a 5,9:1. La hierarchie avec le titre reste portee par la taille :
   1,5 rem contre 4 rem. C'est aussi ce que fait la reference, dont tout le
   texte pose sur la photo est blanc. */
.contact .section-entete__chapo {
	color: var(--sbc-color-white);
}

/* --- Actions -------------------------------------------------------------- */

.contact__actions {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: var(--sbc-space-small);
	width: 100%;
	max-width: 22rem;
}

/* Le lien e-mail est la seconde action. Il emprunte au bouton sa casse, son
   interlettrage et sa hauteur de cible, mais pas son fond : deux blocs blancs
   cote a cote se liraient comme deux actions de meme poids.

   Il reste BLANC au survol, et ce n'est pas un oubli. Le sauge 60 % ferait un
   joli survol mais il retombe a 4,0:1 sur les pixels les plus clairs de la
   photo, sous le plancher de 4,5:1 -- et le teal 20 % a 4,5:1 tout juste. Le
   retour visuel est donc porte par la fleche et par le soulignement, qui ne
   coutent aucun contraste. */
.contact__lien {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sbc-space-tiny);
	min-height: var(--sbc-button-height);
	padding: var(--sbc-space-xsmall) var(--sbc-space-medium);
	color: var(--sbc-color-white);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-tight);
	text-align: center;
	text-decoration: none;
	text-transform: uppercase;
}

.contact__lien-libelle {
	text-decoration: underline;
	text-underline-offset: var(--sbc-space-tiny);
	transition: text-underline-offset var(--sbc-transition-base);
}

.contact__lien-fleche {
	display: inline-flex;
	flex: none;
	transition: transform var(--sbc-transition-base);
}

.contact__lien:hover .contact__lien-libelle,
.contact__lien:focus-visible .contact__lien-libelle {
	text-underline-offset: var(--sbc-space-xsmall);
}

.contact__lien:hover .contact__lien-fleche,
.contact__lien:focus-visible .contact__lien-fleche {
	transform: translateX(var(--sbc-space-tiny));
}

/* L'enveloppe de tete. `flex: none` la protege d'un ecrasement quand le lien
   se retrouve dans une rangee etroite. */
.contact__lien-icone {
	flex: none;
}

/* --- Focus sur aplat sombre ----------------------------------------------
   Le teal de 01-base.css se voit mal sur les zones claires de la photo. Il
   passe au blanc, qui tient a 7,6:1 sur le pire pixel possible. C'est la seule
   surcharge de focus du theme, et elle ne sort pas de cette section. */

.contact__lien:focus-visible,
.contact .bouton:focus-visible {
	outline-color: var(--sbc-color-white);
}

/* --- Ecrans plus larges ---------------------------------------------------
   40 rem : les deux actions passent en rangee. 62 rem : le point de bascule du
   template (991 px), ou l'ecart s'ouvre et le titre s'elargit. */

@media (min-width: 40rem) {

	.contact__actions {
		flex-direction: row;
		align-items: center;
		justify-content: center;
		max-width: none;
	}
}

@media (min-width: 62rem) {

	.contact__inner {
		gap: var(--sbc-space-big);
	}

	.contact__entete {
		max-width: 35rem;
	}
}


/* ============================================================================
   .devis — section 8, demande de devis
   ----------------------------------------------------------------------------
   La raison d'etre de la v1. Deux colonnes : a gauche l'aparte (titre, chapo,
   telephone, atelier), a droite le formulaire. La colonne de gauche n'est pas
   decorative — seize champs rebutent, et l'entreprise convertit
   historiquement par telephone : la sortie non-formulaire est mise au meme
   niveau, pas releguee au pied de page.

   ---------------------------------------------------------------------------
   POURQUOI L'HABILLAGE DE CONTACT FORM 7 EST REECRIT ICI
   ---------------------------------------------------------------------------
   La feuille du plugin est retiree (inc/forms.php). Elle habille le formulaire
   avec ses propres couleurs en dur (#00a0d2, #46b450, #dc3232, #f56e28,
   #ffb900) et des selecteurs a trois classes du type
   `.wpcf7 form .wpcf7-response-output`. Les surcharger demanderait un
   `!important` ou des selecteurs plus profonds encore, tous deux interdits par
   CLAUDE.md.

   Tout ce qu'elle apportait est donc reecrit plus bas, aux couleurs de la
   charte : reponse pour lecteur d'ecran, etats de la zone de reponse, message
   d'erreur au ras du champ, indicateur d'envoi, champs neutralises. Le
   JavaScript du plugin, lui, reste charge : c'est lui qui bascule ces classes.
   ========================================================================== */

.devis {
	padding-block: var(--sbc-space-huge);
	background-color: var(--sbc-color-surface-accent-subtle);
}

.devis__inner {
	display: grid;
	gap: var(--sbc-space-jumbo);
}

/* Les deux colonnes sont des elements de grille : sans `min-width: 0`, elles
   refusent de descendre sous la largeur intrinseque de leur contenu, et les
   champs de Contact Form 7 en ont une confortable (leurs <input> portent un
   attribut `size="40"`). C'est ce qui faisait deborder la section sous 400 px.
   Le meme piege guette chaque conteneur de grille plus bas. */
.devis__aparte,
.devis__formulaire {
	min-width: 0;
}

/* --- Colonne de gauche ---------------------------------------------------- */

.devis__aparte {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-normal);
}

.devis__alternatives {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xsmall);
	align-items: flex-start;
}

.devis__alternative-intro {
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-m);
}

/* Le numero est la sortie de repli principale de la section : c'est une vraie
   cible tactile, pas un lien de texte courant. Le padding vertical lui donne
   les 44 px du plancher de brand/charte.md, que sa seule hauteur de ligne
   (22 px sur mobile) ne suffit pas a atteindre. Le retrait lateral negatif
   garde le chiffre aligne sur la colonne malgre ce padding. */
/* Les trois voies de repli — appeler, passer, ecrire — portent chacune leur
   glyphe. Elles se lisent alors comme une liste de moyens de contact plutot
   que comme trois paragraphes qui se suivent. */
/* ---------------------------------------------------------------------------
   POURQUOI LE TEAL FONCE, ET PAS LE TEAL DE MARQUE, DANS CETTE COLONNE
   ---------------------------------------------------------------------------
   Cette colonne est posee sur l'aplat --sbc-color-surface-accent-subtle
   (#CFE4E3). Le teal de marque y tombe a 3,91:1, sous le plancher de 4,5:1 des
   textes courants — et le numero de telephone, a 1,25 rem sur mobile, est bien
   un texte courant au sens de WCAG : il faudrait 24 px, ou 18,66 px en gras,
   pour beneficier du seuil abaisse a 3:1.

   Le teal fonce donne 5,67:1 sur le meme aplat. C'est la seule teinte de la
   charte qui tienne ici. Mesure faite, pas estimee.

   Cela vaut pour TOUT texte teal pose sur un aplat : ni le teal de marque ni le
   vert sauge ne s'y hasardent. */
.devis__glyphe {
	flex: none;
	color: var(--sbc-color-primary-dark);
}

.devis__tel {
	display: inline-flex;
	align-items: center;
	gap: var(--sbc-space-xsmall);
	min-height: var(--sbc-target-min);
	padding-block: var(--sbc-space-xsmall);
	padding-inline: var(--sbc-space-xsmall);
	margin-inline-start: calc(var(--sbc-space-xsmall) * -1);
	border-radius: var(--sbc-radius-xsmall);
	color: var(--sbc-color-primary-dark);
	font-size: var(--sbc-text-h5);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.02em;
	line-height: var(--sbc-leading-heading);
	text-decoration: none;
}

/* Le repos etant deja au teal fonce, le survol ne peut plus se signaler par la
   couleur : il n'y a pas de cran plus sombre dans la charte. C'est le
   soulignement qui porte l'etat, comme sur la carte du hero. */
.devis__tel:hover,
.devis__tel:focus-visible {
	text-decoration: underline;
}

/* `inline` sur le glyphe et non `flex` sur le paragraphe : le texte de
   l'atelier se replie sur deux ou trois lignes, et un conteneur flex le
   sortirait du flux de la phrase. Le decalage vertical le pose sur la ligne. */
.devis__atelier,
.devis__email {
	max-width: var(--sbc-measure);
	line-height: var(--sbc-leading-body);
}

.devis__atelier {
	color: var(--sbc-color-text-muted);
}

.devis__email {
	font-weight: var(--sbc-weight-medium);
}

/* Le lien heritait du teal de marque pose par theme.json (styles.elements.link)
   et retombait donc a 3,91:1 sur l'aplat. Meme correction que ci-dessus. */
.devis__email a {
	color: var(--sbc-color-primary-dark);
}

/* `inline-block` explicite : 01-base.css pose `svg { display: block }` pour les
   visuels, ce qui ferait sauter le glyphe a la ligne au-dessus de sa phrase. */
.devis__atelier .devis__glyphe,
.devis__email .devis__glyphe {
	display: inline-block;
	margin-inline-end: var(--sbc-space-tiny);
	vertical-align: -0.2em;
}

/* --- Colonne de droite ---------------------------------------------------- */

.devis__formulaire {
	padding: var(--sbc-space-normal);
	border-radius: var(--sbc-radius-medium);
	background-color: var(--sbc-color-white);
	box-shadow: var(--sbc-shadow-card);
}

.devis__repli {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-medium);
	align-items: flex-start;
}

@media (min-width: 62rem) {

	.devis__inner {
		grid-template-columns: 1fr 1.35fr;
		align-items: start;
	}

	/* L'aparte suit le defilement du formulaire : le telephone reste atteignable
	   pendant qu'on remplit les seize champs. Le decalage superieur laisse
	   passer l'en-tete colle. */
	.devis__aparte {
		position: sticky;
		top: calc(var(--sbc-header-height) + var(--sbc-space-normal));
	}

	.devis__formulaire {
		padding: var(--sbc-space-xbig);
	}
}

/* ============================================================================
   .devis-form — le gabarit du formulaire Contact Form 7
   ----------------------------------------------------------------------------
   Les classes .devis-form__* sont ecrites a la main dans le gabarit du
   formulaire, cote administration. Les classes .wpcf7-* sont emises par le
   plugin et ne peuvent pas etre renommees : elles sont stylees telles quelles.
   ========================================================================== */

.devis-form {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xbig);
}

/* --- Blocs ---------------------------------------------------------------- */

.devis-form__bloc {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-normal);
}

/* La marge basse est indispensable : un <legend> n'est pas un element de
   grille ni de flex, les navigateurs le sortent du flux de son fieldset. Le
   `gap` du bloc ne s'applique donc pas apres lui, et sans cette marge le
   premier champ vient se coller sous le filet. */
.devis-form__legende {
	display: flex;
	min-width: 0;
	align-items: baseline;
	gap: var(--sbc-space-xsmall);
	width: 100%;
	margin-block-end: var(--sbc-space-normal);
	padding-block-end: var(--sbc-space-xsmall);
	border-bottom: 1px solid var(--sbc-color-border);
	font-size: var(--sbc-text-h6);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.02em;
}

.devis-form__numero {
	color: var(--sbc-color-primary);
	font-size: var(--sbc-text-small);
	letter-spacing: var(--sbc-tracking-label);
}

.devis-form__groupe {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xsmall);
}

/* --- Champs --------------------------------------------------------------- */

.devis-form__champ {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: var(--sbc-space-tiny);
}

/* ---------------------------------------------------------------------------
   ALIGNEMENT DES CHAMPS D'UNE MEME RANGEE
   ---------------------------------------------------------------------------
   Deux champs cote a cote n'ont pas la meme hauteur de tete : « Localite » a un
   libelle d'une ligne, « Code postal » en a deux plus deux lignes d'aide. Les
   champs s'etirent bien a la meme hauteur — c'est le comportement par defaut
   d'une grille — mais leur contenu partait du haut, et les deux cadres de
   saisie se retrouvaient donc a des hauteurs differentes.

   La marge automatique pousse le cadre de saisie en bas de sa colonne. Les
   LIBELLES restent alignes en haut, les CADRES sont alignes en bas : les deux
   lectures que l'oeil fait d'une rangee de formulaire.

   Le selecteur vise l'enveloppe emise par Contact Form 7 plutot que le champ
   lui-meme : c'est elle qui est l'enfant direct de la boite flex.

   Sans effet hors rangee : un champ isole ne s'etire pas, la marge automatique
   n'a alors rien a distribuer. */
.devis-form__rangee .devis-form__champ > .wpcf7-form-control-wrap {
	margin-block-start: auto;
}

/* L'attribut `size` des champs emis par Contact Form 7 leur donne une largeur
   intrinseque d'une quarantaine de caracteres. On la neutralise : un champ
   occupe la largeur de sa colonne, jamais celle de son attribut. */
.devis-form .wpcf7-form-control {
	width: 100%;
}

.devis-form .wpcf7-checkbox,
.devis-form .wpcf7-acceptance,
.devis-form .wpcf7-submit {
	width: auto;
}

.devis-form__rangee {
	display: grid;
	gap: var(--sbc-space-normal);
}

.devis-form__rangee > .devis-form__champ {
	min-width: 0;
}

/* Le libelle n'est jamais remplace par un placeholder (brand/charte.md,
   Accessibilite) : il est toujours au-dessus du champ, toujours visible.

   ---------------------------------------------------------------------------
   CAPITALES ESPACEES — REVIREMENT SUR L'ARBITRAGE DE 01-base.css
   ---------------------------------------------------------------------------
   L'arbitrage initial gardait les libelles de champ en casse normale, au motif
   que des capitales a 0,875 rem degradent la lisibilite la ou la charte
   l'exige la plus haute. Le client a demande de reproduire fidelement le site
   de reference, qui pose ses libelles de champ ET sa ligne de consentement en
   capitales espacees (`.text-field` + `.checkbox-field` de template.css).

   Ce qui rend le revirement acceptable : la penalite de lisibilite des
   capitales porte sur la prose suivie, pas sur des libelles de deux a quatre
   mots. Les TEXTES D'AIDE, eux, sont de la prose : ils restent en casse
   normale, juste en dessous. C'est la ou se joue vraiment la comprehension
   d'un champ.

   Revenir en arriere tient en trois lignes : retirer text-transform,
   letter-spacing et remonter font-size a --sbc-text-base. */
.devis-form__label {
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}

/* La mention « (obligatoire) » reste en casse normale : c'est une precision
   lue, pas une etiquette. */
.devis-form__requis {
	color: var(--sbc-color-text-muted);
	font-weight: var(--sbc-weight-regular);
	letter-spacing: normal;
	text-transform: none;
}

/* Rattache au champ par aria-describedby (inc/forms.php pour les champs
   simples, attribut du <fieldset> pour les deux groupes). */
.devis-form__aide {
	display: block;
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}

.devis-form__champ--court {
	max-width: 12rem;
}

/* --- Apercu de la realisation choisie -------------------------------------
   Bloc cree par assets/js/modules/formulaire-devis.js sous le select « Une
   réalisation qui vous plaît ? » : la vignette de la galerie et la
   reference, pour que le demandeur verifie qu'il a pris la
   bonne photo sans remonter la page. Sans JavaScript, le bloc n'existe pas et
   le select se suffit.

   La vignette suit l'echelle d'espacement plutot qu'une taille en dur :
   `massive` va de 2,5 rem sur telephone, ou la colonne du formulaire est
   etroite, a 5 rem sur grand ecran. C'est un rappel, pas une visionneuse : la
   galerie en offre une pour regarder la photo en grand. */

.devis-form__apercu {
	display: flex;
	align-items: center;
	gap: var(--sbc-space-small);
	margin-block-start: var(--sbc-space-xsmall);
}

/* Meme necessite que pour .realisations__pilotage : le `display: flex` du bloc
   l'emporterait sur le [hidden] de la feuille du navigateur, l'attribut doit
   etre redit ici pour garder son effet. */
.devis-form__apercu[hidden] {
	display: none;
}

.devis-form__apercu-image {
	flex: none;
	width: var(--sbc-space-massive);
	height: var(--sbc-space-massive);
	border-radius: var(--sbc-radius-xsmall);
	background-color: var(--sbc-color-surface-muted);
	object-fit: cover;
}

.devis-form__apercu-texte {
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}

/* --- Cases a cocher ------------------------------------------------------- */

.devis-form__groupe .wpcf7-checkbox {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-tiny);
	padding-block-start: var(--sbc-space-tiny);
}

/* Toute la ligne est cliquable, pas seulement la case : 44 px de haut, le
   plancher de cible tactile de la charte.

   Le selecteur d'element nu est ici une exception assumee a la regle de
   CLAUDE.md : Contact Form 7 emet ce <label> sans classe, et il n'existe aucun
   filtre pour lui en donner une. C'est la seule facon de l'atteindre. */
.wpcf7-list-item {
	margin: 0;
}

.wpcf7-list-item label {
	display: flex;
	align-items: center;
	gap: var(--sbc-space-xsmall);
	min-height: var(--sbc-target-min);
	font-weight: var(--sbc-weight-regular);
	line-height: var(--sbc-leading-body);
	cursor: pointer;
}

.wpcf7-list-item-label {
	flex: 1;
}

/* --- Televersements ------------------------------------------------------- */

.devis-form__groupe--fichiers {
	gap: var(--sbc-space-xsmall);
}

.devis-form__fichier {
	display: block;
}

/* Masque tant que le module JS n'a pas pris la main. Sans JavaScript, les cinq
   champs restent visibles : le televersement multiple ne depend pas du script
   (brand/charte.md, « Zone d'upload utilisable sans glisser-deposer »). */
.devis-form__fichier--replie {
	display: none;
}

/* --- Conformite ----------------------------------------------------------- */

.devis-form__bloc--conformite {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-normal);
}

.devis-form__consentement {
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}

/* Le lien vers la politique de confidentialite garde sa casse : c'est un nom
   de document, le mettre en capitales le rendrait meconnaissable. */
.devis-form__consentement a {
	color: var(--sbc-color-primary);
	letter-spacing: normal;
	text-transform: none;
}

.devis-form__consentement .wpcf7-list-item label {
	align-items: flex-start;
	min-height: 0;
}

/* Piege a miel. Un humain ne le voit pas, un robot le remplit et sa soumission
   part au rebut (inc/forms.php). L'input porte tabindex="-1", le conteneur
   aria-hidden : rien de focalisable n'est masque aux technologies d'assistance. */
.devis-form__piege {
	display: none;
}

.devis-form__envoi {
	display: flex;
	align-items: center;
	gap: var(--sbc-space-medium);
}

/* ============================================================================
   Etats emis par Contact Form 7 — remplacent sa feuille retiree
   ========================================================================== */

/* Resume de validation annonce aux lecteurs d'ecran. Retire de l'affichage,
   jamais du document : c'est lui qui porte le nombre d'erreurs. */
.screen-reader-response {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	border: 0;
}

.hidden-fields-container {
	display: none;
}

.wpcf7-form-control-wrap {
	position: relative;
	display: block;
}

/* Message d'erreur textuel, au ras du champ concerne (brand/charte.md :
   « Messages d'erreur textuels, a cote du champ »). */
.wpcf7-not-valid-tip {
	display: block;
	padding-block-start: var(--sbc-space-tiny);
	color: var(--sbc-color-error);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	line-height: var(--sbc-leading-body);
}

/* La couleur ne porte jamais l'information seule : le champ est borde de
   rouge ET accompagne du message ci-dessus. */
.wpcf7-not-valid {
	border-color: var(--sbc-color-error);
}

/* --- Zone de reponse ------------------------------------------------------
   Masquee au repos et pendant l'envoi, sinon un cadre vide s'affiche au
   chargement. Les classes d'etat sont posees sur le <form> par le script du
   plugin. */

.wpcf7-response-output {
	display: none;
	margin-block-start: var(--sbc-space-normal);
	padding: var(--sbc-space-small) var(--sbc-space-medium);
	border-radius: var(--sbc-radius-xsmall);
	border-left: var(--sbc-focus-width) solid var(--sbc-color-primary);
	background-color: var(--sbc-color-surface-muted);
	font-size: var(--sbc-text-base);
	line-height: var(--sbc-leading-body);
}

.wpcf7-form.sent .wpcf7-response-output,
.wpcf7-form.failed .wpcf7-response-output,
.wpcf7-form.aborted .wpcf7-response-output,
.wpcf7-form.spam .wpcf7-response-output,
.wpcf7-form.invalid .wpcf7-response-output,
.wpcf7-form.unaccepted .wpcf7-response-output,
.wpcf7-form.payment-required .wpcf7-response-output {
	display: block;
}

/* Succes en teal de marque : le vert sauge est un aplat, il ne porte pas de
   sens, et un vert de reussite supplementaire jurerait avec lui. */
.wpcf7-form.sent .wpcf7-response-output {
	border-left-color: var(--sbc-color-primary);
	background-color: var(--sbc-color-success-surface);
	color: var(--sbc-color-text);
}

.wpcf7-form.failed .wpcf7-response-output,
.wpcf7-form.aborted .wpcf7-response-output,
.wpcf7-form.spam .wpcf7-response-output,
.wpcf7-form.invalid .wpcf7-response-output,
.wpcf7-form.unaccepted .wpcf7-response-output,
.wpcf7-form.payment-required .wpcf7-response-output {
	border-left-color: var(--sbc-color-error);
	background-color: var(--sbc-color-error-surface);
	color: var(--sbc-color-error);
}

/* --- Indicateur d'envoi ---------------------------------------------------
   Un disque qui pulse plutot qu'un satellite en rotation : une seule propriete
   animee, et la duree passe par les variables du theme, donc elle tombe a 0s
   sous prefers-reduced-motion sans une ligne de plus. */

.wpcf7-spinner {
	display: inline-block;
	width: var(--sbc-space-small);
	height: var(--sbc-space-small);
	border-radius: var(--sbc-radius-circle);
	background-color: var(--sbc-color-primary);
	visibility: hidden;
	animation: sbc-pulsation calc(var(--sbc-transition-slow) * 4) ease-in-out infinite;
}

.wpcf7-form.submitting .wpcf7-spinner {
	visibility: visible;
}

@keyframes sbc-pulsation {

	0%,
	100% {
		opacity: 0.25;
		transform: scale(0.75);
	}

	50% {
		opacity: 1;
		transform: scale(1);
	}
}

/* Champs neutralises pendant la soumission : le plugin pose [inert]. */
.wpcf7-form [inert] {
	opacity: 0.55;
}

@media (min-width: 40rem) {

	.devis-form__rangee {
		grid-template-columns: 1fr 1fr;
	}

	/* Le code postal n'a pas besoin de la moitie d'une rangee : quatre chiffres
	   en Belgique, cinq en France. La localite prend le reste. */
	.devis-form__rangee--adresse {
		grid-template-columns: 9rem 1fr;
	}
}


/* ============================================================================
   .faq — section 7, questions frequentes
   ----------------------------------------------------------------------------
   Bloc de `template-parts/sections/faq.php`. Reprend `section faq` du site de
   reference, valeur par valeur :

     padding vertical de section  spacing-huge      (.wrapper)
     ecart en-tete / liste        spacing-xbig      (.wrapper)
     en-tete centre               36 rem, 24 rem sous 991 px   (.faq-top)
     ecart sur-titre / titre      spacing-small     (.faq-top)
     largeur de la liste          44,25 rem         (.faq-items-wrapper)
     ecart entre deux cartes      spacing-tiny      (.faq-items-wrapper)
     carte                        fond off-white, rayon small, padding xnormal
                                  (medium sous 767 px)         (.faq-list)
     question                     paragraphe M, graisse 500     (.faq-ques)
     ecart icone / question       spacing-small     (.faq-question)
     boite d'icone                1,5 rem, 1,25 rem sous 767 px (.faq-arrow-box)
     reponse                      retrait haut de 1 rem         (.faq-para)

   Ce qui n'est PAS repris : les 900 Ko de runtime Webflow qui portaient
   l'ouverture. Elle est refaite en vanilla (assets/js/modules/accordeon.js) et
   ne repose sur AUCUN `display: none`.

   Deux ecarts assumes :

   1. Le padding de la carte est porte par le <button>, pas par le <li>. La
      reference le met sur le conteneur : la zone cliquable n'y fait que la
      hauteur du texte, 25 px, au milieu d'une carte de 85 px. Ici le
      declencheur remplit la ligne, la hauteur reste celle du template et la
      cible depasse largement les 44 px de la charte.
   2. La reponse est en graisse 400 la ou la reference met 500. brand/charte.md
      reserve le 500 aux titres et a l'interface, le corps reste en 400.

   ---------------------------------------------------------------------------
   POURQUOI L'ETAT FERME EST PORTE PAR UN MODIFICATEUR, ET PAS PAR L'ETAT PAR
   DEFAUT
   ---------------------------------------------------------------------------
   Sans JavaScript, toutes les reponses doivent etre lisibles : c'est une exigence
   de referencement (le balisage FAQPage veut la reponse dans le document) et
   d'accessibilite. L'etat par defaut de cette feuille est donc OUVERT, et
   c'est le script qui pose `.faq__item--replie` au chargement.

   Le repli se joue sur `grid-template-rows` (1fr -> 0fr) plutot que sur
   `display: none` ou `hidden` : le texte reste dans le document, dans le flux,
   simplement de hauteur nulle. `visibility: hidden` sur le corps le retire en
   plus de l'arbre d'accessibilite et de l'ordre de tabulation, pour que
   `aria-expanded="false"` ne mente pas au lecteur d'ecran. Il est transitionne
   avec la hauteur : c'est ce qui le fait disparaitre a la FIN du repli et
   reapparaitre au DEBUT du deploiement, sans une ligne de JavaScript.
   ========================================================================== */

.faq {
	padding-block: var(--sbc-space-huge);
	background-color: var(--sbc-color-surface-band);
}

.faq__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sbc-space-xbig);
}

/* --- En-tete --------------------------------------------------------------
   24 rem puis 36 rem : les deux largeurs de `faq-top`. C'est cette colonne
   etroite au milieu d'un conteneur de 81 rem qui fait tout l'effet de
   l'ouverture centree. Le titre du template y tient sur deux lignes ; celui de
   Sobecom est plus court et tient sur une, la taille reste la meme. */

.faq__entete {
	width: 100%;
	max-width: 24rem;
}

/* --- Liste ----------------------------------------------------------------
   44,25 rem est la largeur de `faq-items-wrapper` : c'est ce qui garde les
   questions sur une ou deux lignes et les reponses a une longueur de ligne
   lisible, dans un conteneur qui fait 81 rem. */

.faq__liste {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-tiny);
	width: 100%;
	max-width: 44.25rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.faq__item {
	border-radius: var(--sbc-radius-small);
	background-color: var(--sbc-color-white);
}

/* --- Question -------------------------------------------------------------
   Le <h3> ne porte que la hierarchie de titres : sa taille est celle du
   paragraphe M du template (`faq-ques`), pas celle d'un h3 de theme.json. Une
   question d'accordeon a 3,375 rem n'aurait aucun sens. */

.faq__question {
	font-size: var(--sbc-text-m);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: normal;
	line-height: var(--sbc-leading-body);
}

/* Un vrai <button>, donc un reset : le navigateur lui donnerait sinon son fond
   gris, sa bordure et son centrage. `font: inherit` vient de 01-base.css, et
   `min-height` y est deja pose sur tous les boutons natifs.

   Le rayon ne se voit jamais au repos — le fond est transparent — mais
   l'anneau de focus le suit : il epouse donc l'angle de la carte au lieu de la
   couper au carre. */
.faq__declencheur {
	display: flex;
	align-items: center;
	gap: var(--sbc-space-small);
	width: 100%;
	padding: var(--sbc-space-medium);
	border: 0;
	border-radius: var(--sbc-radius-small);
	background-color: transparent;
	color: inherit;
	text-align: left;
	transition: color var(--sbc-transition-base);
}

.faq__declencheur:hover,
.faq__declencheur:focus-visible {
	color: var(--sbc-color-primary);
}

.faq__intitule {
	display: block;
}

/* --- Icone ----------------------------------------------------------------
   PLUS/MOINS REMPLACE PAR UN CHEVRON. Le marqueur etait deux traits empiles
   dont l'un pivotait de 90 degres : une croix qui devient un moins. C'est
   desormais le `chevron-down` de Lucide (sobecom_traces_icones()), pour la
   meme raison que partout ailleurs sur la page — un seul jeu d'icones, pas des
   traces maison a cote.

   Le chevron dit AUSSI quelque chose que la croix ne disait pas : il pointe
   vers le contenu qu'il va deplier. Etat ouvert, il pointe vers le haut ; etat
   replie, vers le bas. L'ancien commentaire est conserve ci-dessous.

   Deux traits de 0,875 rem sur 0,125 rem, l'un fixe, l'autre pivote : ouvert,
   ils se superposent en tiret ; ferme, ils forment une croix. Valeurs du
   template (`faq-arrow-box`, `faq-horizontal-line`, `faq-vertical-line`). */

.faq__icone {
	position: relative;
	display: flex;
	overflow: clip;
	flex-shrink: 0;
	align-items: center;
	justify-content: center;

	/* --sbc-space-regular vaut clamp(1.25rem, ..., 1.5rem) : il rend a lui seul
	   les deux tailles de `faq-arrow-box` du template, 1,25 rem sous 991 px et
	   1,5 rem au-dela, sans media query. */
	width: var(--sbc-space-regular);
	height: var(--sbc-space-regular);
	border-radius: var(--sbc-radius-circle);
}

/* Etat OUVERT — c'est l'etat par defaut du document servi : le chevron pointe
   donc vers le haut au chargement, avant meme que le script ne s'execute. */
.faq__icone svg {
	transform: rotate(180deg);
}

/* --- Reponse -------------------------------------------------------------- */

.faq__reponse {
	display: grid;
	grid-template-rows: 1fr;
}

.faq__reponse-corps {
	overflow: hidden;
	min-height: 0;
	visibility: visible;
}

/* Le retrait est porte par le texte et non par le corps : un padding sur le
   corps ne se replierait pas avec la hauteur. Le haut vaut le 1 rem de
   `faq-para`, les trois autres cotes prolongent le padding du declencheur pour
   que la reponse s'aligne sur la question. */
.faq__texte {
	padding: var(--sbc-space-small) var(--sbc-space-medium) var(--sbc-space-medium);
	color: var(--sbc-color-text);
	line-height: var(--sbc-leading-body);
}

/* --- Mouvement, arme par le script une fois le repli initial commit ------
   Les transitions ne sont PAS dans les regles ci-dessus a dessein. La feuille
   ouvre les panneaux, le script les replie : si la transition etait active des
   le premier rendu, on verrait toutes les reponses se refermer au chargement.
   `.faq--interactif` est posee apres coup, donc le repli initial est instantane
   et les suivants sont animes. Sans JavaScript, la classe n'apparait jamais et
   il n'y a rien a animer. */

.faq--interactif .faq__reponse {
	transition: grid-template-rows var(--sbc-transition-base);
}

.faq--interactif .faq__reponse-corps {
	transition: visibility var(--sbc-transition-base);
}

.faq--interactif .faq__icone svg {
	transition: transform var(--sbc-transition-base);
}

/* --- Etat replie, pose par le script uniquement --------------------------- */

.faq__item--replie .faq__reponse {
	grid-template-rows: 0fr;
}

.faq__item--replie .faq__reponse-corps {
	visibility: hidden;
}

.faq__item--replie .faq__icone svg {
	transform: rotate(0deg);
}

/* --- Relance -------------------------------------------------------------- */

.faq__relance {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sbc-space-medium);
	text-align: center;
}

.faq__relance-texte {
	font-size: var(--sbc-text-m);
	font-weight: var(--sbc-weight-medium);
}

/* --- Ecrans plus larges ---------------------------------------------------
   40 rem : la relance passe en rangee. 48 rem : le point de bascule du
   template (767 px), ou la carte reprend son padding plein. 62 rem : celui de
   `faq-top` (991 px), ou l'en-tete s'elargit a 36 rem. */

@media (min-width: 40rem) {

	.faq__relance {
		flex-direction: row;
		justify-content: center;
		gap: var(--sbc-space-regular);
	}
}

@media (min-width: 48rem) {

	.faq__declencheur {
		padding: var(--sbc-space-xnormal);
	}

	.faq__texte {
		padding: var(--sbc-space-small) var(--sbc-space-xnormal) var(--sbc-space-xnormal);
	}
}

@media (min-width: 62rem) {

	.faq__entete {
		max-width: 36rem;
	}
}


/* ============================================================================
   .film-sable — section 2, le service principal
   ----------------------------------------------------------------------------
   Bloc de `template-parts/sections/film-sable.php`. Enchaine deux motifs du
   site de reference, valeur pour valeur :

   1. `measured-impact-wrap` — en-tete aligne a gauche, action en face du titre.
      C'est le composant `section-entete` qui le porte, rien a faire ici.

   2. `impact-wrap` — le bloc « visuel + grille ». Grille 0,75 fr / 1 fr,
      gouttiere `medium`. A droite, quatre cartes SUR LA BANDE separees par un
      filet de `tiny` : ce n'est pas une bordure, c'est le blanc de la page
      qui se voit entre elles. Seuls les quatre coins exterieurs du pave sont
      arrondis, en `regular` — d'ou les quatre modificateurs de coin.
      Padding de carte `xnormal`, cercle d'icone puis titre a `big`, titre puis
      texte a `xxsmall`.

   3. La grille des trois usages, en `carte-media`, gouttiere `medium`.

   FOND BLANC, CARTES SUR LA BANDE. La section etait sur la bande avec des
   cartes blanches tant que « Le probleme » la precedait en blanc. Cette
   section a ete retiree le 11 septembre 2026 (demande du client) : le film
   sable suit maintenant directement le hero, qui est sur la bande, et
   l'alternance blanc / bande de CLAUDE.md impose le blanc ici. Les cartes
   suivent la regle inverse — une section blanche porte ses cartes sur la
   bande — sinon elles disparaitraient dans le fond.

   Media queries en min-width uniquement.
   ========================================================================== */

.film-sable {
	background-color: var(--sbc-color-white);
	padding-block: var(--sbc-space-huge);
}

.film-sable__inner {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-jumbo);
}

/* --- Bloc « visuel + grille » --------------------------------------------- */

.film-sable__bloc {
	display: grid;
	gap: var(--sbc-space-medium);
}

.film-sable__visuel {
	display: flex;
	min-width: 0;
	flex-direction: column;
}

/* La carte de media remplit la colonne : c'est la hauteur de la grille de
   cartes qui commande, comme dans la reference ou la video s'etire. Base
   `auto` et non `0` : en colonne unique, la carte n'a plus de hauteur imposee
   et doit retomber sur son propre rapport d'image. */
.film-sable__visuel > * {
	flex: 1 1 auto;
}

.film-sable__cartes {
	display: grid;
	gap: var(--sbc-space-tiny);
	margin: 0;
	padding: 0;
	list-style: none;
}

.film-sable__carte {
	display: flex;
	min-width: 0;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-big);
	padding: var(--sbc-space-xnormal);
	border-radius: var(--sbc-radius-regular);
	background-color: var(--sbc-color-surface-band);
}

.film-sable__carte-texte {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: var(--sbc-space-xxsmall);
}

/* Echelle du corps augmente plutot que celle d'un h3 : dans une carte de
   353 px, l'echelle de titre du theme (3,375 rem) deborderait. La hierarchie
   du document reste celle de la balise. */
.film-sable__carte-titre {
	font-size: var(--sbc-text-h6);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.02em;
	line-height: 1.3;
}

.film-sable__carte-resume {
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-base);
	line-height: var(--sbc-leading-body);
}

/* --- Les trois usages ----------------------------------------------------- */

.film-sable__usages {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-normal);
}

.film-sable__amorce {
	max-width: var(--sbc-measure);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-h6);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.02em;
	line-height: 1.3;
}

.film-sable__grille {
	display: grid;
	gap: var(--sbc-space-medium);
	margin: 0;
	padding: 0;
	list-style: none;
}

.film-sable__usage {
	display: flex;
	min-width: 0;
	flex-direction: column;
}

.film-sable__usage > * {
	width: 100%;
}

/* --- Tablette -------------------------------------------------------------
   Les quatre cartes passent en deux colonnes et le pave prend ses coins :
   seuls les quatre coins exterieurs sont arrondis, les coins interieurs
   restent vifs pour que le filet de blanc de `tiny` se lise comme une
   separation. */

@media (min-width: 48rem) {

	.film-sable__cartes {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.film-sable__carte {
		border-radius: 0;
	}

	.film-sable__carte:nth-child(1) {
		border-start-start-radius: var(--sbc-radius-regular);
	}

	.film-sable__carte:nth-child(2) {
		border-start-end-radius: var(--sbc-radius-regular);
	}

	.film-sable__carte:nth-child(3) {
		border-end-start-radius: var(--sbc-radius-regular);
	}

	.film-sable__carte:nth-child(4) {
		border-end-end-radius: var(--sbc-radius-regular);
	}

	.film-sable__grille {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* --- Desktop -------------------------------------------------------------- */

@media (min-width: 62rem) {

	.film-sable__grille {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

/* --- Grand desktop --------------------------------------------------------
   Le bloc « visuel + grille » ne se dedouble qu'a 75 rem, la ou la reference
   le fait a 62. Motif : nos quatre textes de carte sont plus longs que les
   siens. A 1024 px, deux colonnes de 275 px les font monter a un millier de
   pixels de haut, et la photo, qui s'etire pour les suivre, se retrouve rognee
   a un bandeau vertical. A 75 rem le rapport revient a celui de la reference
   (0,9), la photo n'y perd qu'une marge laterale. */

@media (min-width: 75rem) {

	.film-sable__bloc {
		grid-template-columns: 0.75fr 1fr;
	}
}


/* ============================================================================
   .film-solaire — section 3, bloc media / texte alterne
   ----------------------------------------------------------------------------
   Bloc de `template-parts/sections/film-solaire.php`. Reprend
   `innovation-wrap` du site de reference : texte a gauche, visuel a droite,
   colonnes 0,8 fr / 1 fr, gouttiere `jumbo`, centrees l'une sur l'autre.

   Les colonnes sont centrees et NON etirees : le visuel garde son rapport
   natif de 16/9, ce qui evite de rogner la seule photo de film solaire du
   fonds — un seul vantail y est filme, la comparaison disparaitrait au
   rognage.

   Fond de bande : la page alterne blanc et bande, et le film sable qui
   precede est passe en blanc le 11 septembre 2026, quand la section
   « Le probleme » qui le precedait a ete retiree. La carte de media est une
   photo a coins arrondis : elle se detache de la bande comme du blanc.

   Media queries en min-width uniquement.
   ========================================================================== */

.film-solaire {
	background-color: var(--sbc-color-surface-band);
	padding-block: var(--sbc-space-huge);
}

.film-solaire__inner {
	display: grid;
	gap: var(--sbc-space-normal);
	align-items: center;
}

.film-solaire__contenu {
	display: flex;
	min-width: 0;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-normal);
}

.film-solaire__texte {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xxsmall);
	max-width: var(--sbc-measure);
}

.film-solaire__amorce {
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-m);
	line-height: var(--sbc-leading-body);
}

.film-solaire__supports {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xsmall);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* La reference coiffe chaque ligne d'un petit cercle. C'etait une pastille
   vide ; elle porte maintenant le glyphe du support (bureau, veranda, vitrine,
   vehicule), ce qui la rend lisible d'un coup d'oeil au lieu de simplement
   ponctuer. Meme geometrie que les cercles d'icone des cartes, a l'echelle
   d'une puce.

   Alignement en `flex-start` et non `baseline` : une pastille carree n'a pas de
   ligne de base a partager avec un texte qui peut se replier sur deux lignes.
   La marge haute la recale sur la premiere ligne. */
.film-solaire__support {
	display: flex;
	align-items: flex-start;
	gap: var(--sbc-space-xsmall);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-m);
	line-height: var(--sbc-leading-body);
}

.film-solaire__puce {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: var(--sbc-space-normal);
	height: var(--sbc-space-normal);
	margin-block-start: 0.1em;
	border: 1px solid var(--sbc-color-primary);
	border-radius: var(--sbc-radius-circle);
	background-color: var(--sbc-color-surface-accent-subtle);
	color: var(--sbc-color-primary-dark);
}

.film-solaire__media {
	display: flex;
	min-width: 0;
	flex-direction: column;
}

.film-solaire__media > * {
	width: 100%;
}

/* --- Desktop -------------------------------------------------------------- */

@media (min-width: 62rem) {

	.film-solaire__inner {
		grid-template-columns: 0.8fr 1fr;
		gap: var(--sbc-space-jumbo);
	}
}


/* ============================================================================
   .hero — section 1, premier ecran
   ----------------------------------------------------------------------------
   Bloc de `template-parts/sections/hero.php`. Reprend `home-hero-wrap` du site
   de reference, valeur pour valeur :

     - grille 1fr / 0,9fr, gouttiere `colossal`, colonnes centrees l'une sur
       l'autre a partir de 62 rem ;
     - padding haut `massive`, et NON `huge` comme les huit autres sections :
       c'est l'unique bloc ou la reference deroge a son propre rythme
       (`home-hero-wrap { padding-top: spacing-massive }`), parce que la barre
       de navigation est juste au-dessus. Padding bas `huge`, le rythme commun :
       le bandeau defilant qui fermait la section, et qui portait cette
       fermeture a sa place, a ete retire le 11 septembre 2026 a la demande du
       client ;
     - colonne de gauche en pile, gouttiere `big` ;
     - rangee de deux boutons (le noir vers le devis, le blanc vers les
       realisations), gouttiere `xsmall`, qui se replie ;
     - preuves sous la rangee, gouttiere `xnormal` ;
     - visuel a droite, coin bas-gauche entaille, carte blanche au ras du coin
       bas-droit, rayon nul sur ce seul coin pour qu'elle epouse le cadre.

   L'entaille du coin est cuite dans le fichier image chez la reference (canal
   alpha). Elle est refaite ici en `clip-path`, en pourcentages releves sur ce
   fichier : 21,5 % de la largeur, 24,8 % de la hauteur. Des pourcentages, donc
   l'entaille garde ses proportions a toutes les tailles d'ecran.

   Media queries en min-width uniquement. Point de bascule : 62 rem, celui de
   l'en-tete.
   ========================================================================== */

.hero {

	/* Largeur de la carte flottante. Valeur du `rating-block` de la reference
	   (19.5625rem), hors echelle d'espacement a dessein : c'est une largeur de
	   composition, pas un espacement. Elle vit ici plutot qu'en dur plus bas,
	   pour rester une decision a un seul endroit. */
	--hero-carte-max: 19.5625rem;

	/* Entaille du coin bas-gauche du visuel. */
	--hero-entaille-x: 21.5%;
	--hero-entaille-y: 75.2%;

	background-color: var(--sbc-color-surface-band);
	padding-block-start: var(--sbc-space-massive);
	padding-block-end: var(--sbc-space-huge);
}

.hero__inner {
	display: grid;
	gap: var(--sbc-space-big);
	align-items: center;
}

/* --- Colonne de texte ----------------------------------------------------- */

.hero__contenu {
	display: flex;
	min-width: 0;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-big);
}

/* Zone d'action : la rangee de boutons, puis les preuves. La reference y met
   un bouton, des avatars et un texte en capitales espacees ; nous, deux
   boutons et trois faits verifiables. */
.hero__actions {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-regular);
}

/* Les deux boutons cote a cote. Ils partagent le calibre unique du site
   (3 rem de haut, 03-components/bouton.css) ; le centrage sur l'axe ne sert
   que le jour ou un libelle se replie sur deux lignes et rehausse l'un des
   deux. La rangee se replie des que la colonne est trop etroite pour les
   deux, plutot que d'ecraser le second. */
.hero__boutons {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sbc-space-xsmall);
}

.hero__preuves {
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: var(--sbc-space-tiny);
	margin: 0;
	padding: 0;
	list-style: none;
}

.hero__preuve {
	display: flex;
	align-items: baseline;
	gap: var(--sbc-space-xsmall);
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}

/* Pastille de puce, purement decorative : le teal de l'action, en dose
   homeopathique, pour que la rangee se lise d'un coup d'oeil. */
.hero__preuve::before {
	content: "";
	flex: none;
	width: var(--sbc-space-xsmall);
	height: var(--sbc-space-xsmall);
	border-radius: var(--sbc-radius-circle);
	background-color: var(--sbc-color-primary);
}

/* --- Colonne du visuel ---------------------------------------------------- */

.hero__media {
	position: relative;
	display: flex;
	min-width: 0;
	flex-direction: column;
	gap: var(--sbc-space-regular);
}

/* Le cadre du visuel n'a AUCUN rayon : la reference lui laisse ses angles
   vifs et ne creuse que le coin bas-gauche. */
.hero__visuel {
	overflow: hidden;
	clip-path: polygon(
		0 0,
		100% 0,
		100% 100%,
		var(--hero-entaille-x) 100%,
		0 var(--hero-entaille-y)
	);
}

/* 4/3 exactement, soit le rapport natif de la photo (1360x1020) : elle n'est
   donc ni rognee ni agrandie. */
.hero__image {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	background-color: var(--sbc-color-surface-muted);
}

/* --- Carte flottante ------------------------------------------------------
   Sous 62 rem elle reste dans le flux, sous le visuel : posee par-dessus une
   photo de 257 px de haut, elle la masquerait presque entierement. */

.hero__carte {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-xsmall);
	padding: var(--sbc-space-regular);
	border-radius: var(--sbc-radius-xxsmall);
	background-color: var(--sbc-color-white);
	box-shadow: var(--sbc-shadow-card);
}

.hero__carte-label {
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}

.hero__carte-tel {
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-h6);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.02em;
	line-height: var(--sbc-leading-heading);
	text-decoration: none;
	transition: color var(--sbc-transition-base);
}

.hero__carte-tel:hover,
.hero__carte-tel:focus-visible {
	color: var(--sbc-color-primary-dark);
	text-decoration: underline;
}

.hero__carte-adresse {
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}

/* --- Tablette ------------------------------------------------------------- */

@media (min-width: 48rem) {

	/* Les preuves passent SOUS les boutons, en rangee, plutot qu'a cote d'eux.

	   La reference pose bien les deux cote a cote, mais son texte tient en
	   trois mots (« trusted by worldwide ») ; le notre en compte sept, et la
	   troisieme preuve — « conception, fabrication et pose par notre equipe »,
	   qui vient telle quelle de content/contenu.md — s'empilait sur trois
	   lignes dans la colonne etroite laissee par le bouton, deformant toute la
	   rangee.

	   En rangee sous les boutons, les trois preuves disposent de la pleine
	   largeur de la colonne et se replient naturellement. Les boutons, eux,
	   gardent leur ligne pour eux seuls, ce qui les pose davantage. */
	.hero__actions {
		gap: var(--sbc-space-xnormal);
	}

	.hero__preuves {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		gap: var(--sbc-space-xsmall) var(--sbc-space-normal);
	}
}

/* --- Desktop -------------------------------------------------------------- */

@media (min-width: 62rem) {

	.hero__inner {
		grid-template-columns: 1fr 0.9fr;
		gap: var(--sbc-space-colossal);
	}

	/* La carte quitte le flux et vient se caler au ras du coin bas-droit du
	   visuel, a `xsmall` des deux bords. Son coin bas-droit est le seul a
	   n'avoir aucun rayon : il epouse celui du cadre. */
	.hero__carte {
		position: absolute;
		inset: auto var(--sbc-space-xsmall) var(--sbc-space-xsmall) auto;
		width: 100%;
		max-width: var(--hero-carte-max);
		gap: var(--sbc-space-medium);
		border-radius: var(--sbc-radius-xxsmall) var(--sbc-radius-xxsmall) 0 var(--sbc-radius-xxsmall);
	}
}


/* ============================================================================
   .page-legal — mentions legales et politique de confidentialite
   ----------------------------------------------------------------------------
   Bloc partage par `page-mentions-legales.php` et
   `page-politique-de-confidentialite.php`. Les deux pages ont exactement la
   meme charpente : en-tete, sommaire ancre, puis une suite de <section>
   numerotees. Un seul bloc les habille donc toutes les deux.

   ---------------------------------------------------------------------------
   CE QUI COMPTE DANS UNE PAGE JURIDIQUE
   ---------------------------------------------------------------------------
   Personne ne lit ces pages en entier : on y cherche un point precis. Toute la
   mise en page sert cette lecture-la.

     - LONGUEUR DE LIGNE. Le corps est bride a --sbc-measure et non aux 81 rem
       du conteneur. C'est la seule regle non negociable du fichier : soixante
       caracteres de large, pas cent trente.
     - SOMMAIRE COLLE. A partir de 64 rem il quitte le flux et suit le
       defilement, en face du texte. C'est ce qui remplace le « Ctrl+F » : on
       voit toujours ou l'on est dans le document.
     - FILET AVANT CHAQUE SECTION. Il donne les paliers de lecture sans ajouter
       de couleur ni de fond.

   `top` du sommaire colle : --sbc-header-height plus une respiration, la meme
   formule que la colonne collee du formulaire de devis. La barre du site est en
   position: sticky, un sommaire cale a 0 passerait dessous.

   Le saut d'ancre, lui, est deja regle globalement par le `scroll-padding-top`
   de 01-base.css : il n'y a rien a poser ici.

   ---------------------------------------------------------------------------
   POURQUOI DES SELECTEURS D'ELEMENT ICI
   ---------------------------------------------------------------------------
   `.page-legal__section p`, `.page-legal__tableau th` : ce sont des elements
   vises depuis une classe, pas des selecteurs nus au sens de CLAUDE.md — la
   portee reste le bloc. Une page juridique est de la prose longue ; poser une
   classe sur chacun de ses deux cents paragraphes et sur chaque cellule de
   tableau produirait un balisage illisible pour un gain nul. La regle vise les
   selecteurs qui fuient hors de leur bloc, ce que ceux-ci ne font pas.

   Media queries en min-width uniquement. Point de bascule : 64 rem, la ou la
   colonne de sommaire tient sans etrangler le texte.
   ========================================================================== */

.page-legal {
	padding-block: var(--sbc-space-huge);
	background-color: var(--sbc-color-white);
}

.page-legal__inner {
	display: grid;
	gap: var(--sbc-space-big);
}

/* --- En-tete --------------------------------------------------------------- */

.page-legal__entete {
	display: flex;
	flex-direction: column;
	gap: var(--sbc-space-medium);
	max-width: var(--sbc-measure);
}

.page-legal__titre {
	margin: 0;
}

.page-legal__chapo {
	margin: 0;
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-m);
	line-height: var(--sbc-leading-body);
}

/* La date de mise a jour est une information de service : elle se lit comme
   une etiquette, pas comme du corps de texte. */
.page-legal__maj {
	margin: 0;
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
}

/* --- Sommaire -------------------------------------------------------------- */

.page-legal__sommaire {
	padding: var(--sbc-space-regular);
	border-radius: var(--sbc-radius-small);
	background-color: var(--sbc-color-surface-band);
}

.page-legal__sommaire-titre {
	margin: 0 0 var(--sbc-space-xsmall);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
}

/* Le compteur de la liste est masque : les libelles portent DEJA leur numero,
   parce que le corps de la page numerote ses titres (« 1. Qui traite vos
   donnees »). Le laisser afficherait « 1. 1. Qui traite vos donnees ».

   La balise reste un <ol> : c'est une suite ordonnee, et un lecteur d'ecran
   annonce le rang meme sans puce visible. */
.page-legal__sommaire-liste {
	margin: 0;
	padding-inline-start: 0;
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
	list-style: none;
}

.page-legal__sommaire-item {
	margin-block-start: var(--sbc-space-xsmall);
}

/* Le soulignement n'apparait qu'au survol : dans une liste de vingt entrees,
   vingt liens soulignes forment un mur. La cible reste pleine largeur. */
.page-legal__sommaire-lien {
	display: block;
	color: var(--sbc-color-text);
	text-decoration: none;
	transition: color var(--sbc-transition-base);
}

.page-legal__sommaire-lien:hover,
.page-legal__sommaire-lien:focus-visible {
	color: var(--sbc-color-primary-dark);
	text-decoration: underline;
}

/* --- Corps ----------------------------------------------------------------- */

.page-legal__contenu {
	min-width: 0;
	max-width: var(--sbc-measure);
}

/* Filet de separation porte par la section SUIVANTE : jamais avant la
   premiere, jamais apres la derniere. */
.page-legal__section + .page-legal__section {
	margin-block-start: var(--sbc-space-big);
	padding-block-start: var(--sbc-space-big);
	border-block-start: 1px solid var(--sbc-color-border);
}

.page-legal__section-titre {
	margin: 0 0 var(--sbc-space-medium);
	font-size: var(--sbc-text-h5);
	line-height: var(--sbc-leading-heading);
}

.page-legal__soustitre {
	margin: var(--sbc-space-normal) 0 var(--sbc-space-xsmall);
	font-size: var(--sbc-text-m);
	line-height: var(--sbc-leading-heading);
}

.page-legal__section p {
	margin-block: 0 var(--sbc-space-medium);
	line-height: var(--sbc-leading-body);
}

.page-legal__section p:last-child {
	margin-block-end: 0;
}

/* --- Listes ---------------------------------------------------------------- */

.page-legal__points,
.page-legal__etapes {
	margin-block: 0 var(--sbc-space-medium);
	padding-inline-start: var(--sbc-space-medium);
	line-height: var(--sbc-leading-body);
}

.page-legal__points > li + li,
.page-legal__etapes > li + li {
	margin-block-start: var(--sbc-space-xsmall);
}

.page-legal__points > li::marker,
.page-legal__etapes > li::marker {
	color: var(--sbc-color-primary-dark);
}

/* --- Liste de definitions -------------------------------------------------
   Terme et valeur sur deux lignes en dessous de 40 rem, en deux colonnes
   au-dela : une adresse de siege ne se coupe pas bien dans 12 rem. */

.page-legal__liste {
	margin-block: 0 var(--sbc-space-medium);
	line-height: var(--sbc-leading-body);
}

.page-legal__ligne {
	display: grid;
	gap: var(--sbc-space-tiny);
	padding-block: var(--sbc-space-xsmall);
}

.page-legal__ligne + .page-legal__ligne {
	border-block-start: 1px solid var(--sbc-color-border);
}

.page-legal__terme {
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
}

.page-legal__valeur {
	margin: 0;
}

/* --- Tableaux --------------------------------------------------------------
   L'enveloppe defile lateralement plutot que de laisser le tableau pousser la
   page : un tableau de trois colonnes ne se replie pas sous 375 px, et la
   regle du projet est qu'aucun contenu ne fasse defiler le document entier.

   L'enveloppe porte `tabindex="0"` dans le balisage : une zone qui defile doit
   etre atteignable au clavier, sinon son contenu cache est inaccessible a qui
   n'a ni souris ni ecran tactile (WCAG 2.1.1). Elle ne porte PAS de `role`,
   donc elle n'a pas besoin de nom accessible ; le <caption> de chaque tableau
   fait deja ce travail.

   Le contour de focus vient de 01-base.css et s'applique tel quel : il faut le
   voir, c'est ce qui signale que la zone se pilote aux fleches. */

.page-legal__tableau {
	overflow-x: auto;
	margin-block: 0 var(--sbc-space-medium);
	border: 1px solid var(--sbc-color-border);
	border-radius: var(--sbc-radius-xsmall);
}

.page-legal__tableau table {
	width: 100%;
	border-collapse: collapse;
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
	text-align: left;
}

.page-legal__tableau th,
.page-legal__tableau td {
	padding: var(--sbc-space-xsmall) var(--sbc-space-small);
	border-block-start: 1px solid var(--sbc-color-border);
	vertical-align: top;
}

.page-legal__tableau thead th {
	border-block-start: 0;
	background-color: var(--sbc-color-surface-band);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
	white-space: nowrap;
}

/* En-tete de groupe de lignes : il coupe le tableau en blocs de lecture
   (les quatre blocs du formulaire de devis, par exemple). */
.page-legal__groupe {
	background-color: var(--sbc-color-surface);
	color: var(--sbc-color-text-muted);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
}

/* --- Ecrans larges ---------------------------------------------------------
   Le sommaire passe a gauche et suit le defilement. L'en-tete traverse les
   deux colonnes : il annonce la page entiere, pas la colonne de texte. */

@media (min-width: 64rem) {

	.page-legal__inner {
		grid-template-columns: 17rem minmax(0, 1fr);
		column-gap: var(--sbc-space-colossal);
		align-items: start;
	}

	.page-legal__entete {
		grid-column: 1 / -1;
	}

	.page-legal__sommaire {
		position: sticky;
		top: calc(var(--sbc-header-height) + var(--sbc-space-normal));

		/* Un sommaire plus haut que l'ecran doit pouvoir se parcourir seul,
		   sinon ses dernieres entrees sont inatteignables. */
		max-height: calc(100vh - var(--sbc-header-height) - var(--sbc-space-big));
		overflow-y: auto;
	}

	.page-legal__ligne {
		grid-template-columns: 12rem minmax(0, 1fr);
		gap: var(--sbc-space-small);
		align-items: baseline;
	}
}


/* ============================================================================
   .pourquoi-sobecom — la section de preuve
   ----------------------------------------------------------------------------
   Bloc de template-parts/sections/pourquoi-sobecom.php.

   Section « Consultancy result » du site de reference : le titre a gauche, le
   texte en vis-a-vis, puis la bande de trois panneaux jointifs. Valeurs du
   template : panneaux sans gouttiere (`gap: 0`), padding `spacing-xnormal`
   (30,08 px), ecart entre la mesure et le paragraphe du bas `spacing-massive`
   (80 px), filet sous la mesure a `spacing-xxsmall` (9,92 px dans le
   template), rayon `radius-medium` (20 px) aux coins exterieurs de la bande.

   LES COULEURS. Le template alterne rose / blanc / vert. Les seuls aplats de
   brand/charte.md sont le teal a 20 %, le blanc et le vert sauge clair : la
   bande les prend dans cet ordre. Le texte y est NOIR dans les trois cas, et
   c'est le seul couple autorise — le blanc tombe a 1,49:1 sur le sauge.

   LE RAYON EXTERIEUR est porte par la LISTE, pas par les panneaux : avec
   `overflow: hidden`, les coins se rognent tout seuls, que la bande soit en une
   colonne ou en trois. Aucun panneau n'a de rayon a declarer.

   La bande reste dans le conteneur. Dans le site de reference elle fait
   exactement la largeur du contenu (1264 px mesures pour un conteneur de
   1296 px), et ses coins exterieurs sont arrondis : elle n'est pas pleine page.

   Aucune photo : la facade de l'atelier n'est pas dans la mediatheque et le
   fonds n'a rien d'autre a proposer ici. Voir la note en tete du partial.
   ========================================================================== */

.pourquoi-sobecom {
	padding-block: var(--sbc-space-huge);
	background-color: var(--sbc-color-white);
}

.pourquoi-sobecom__haut {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sbc-space-big);
}

.pourquoi-sobecom__texte {
	max-width: var(--sbc-measure);
	font-size: var(--sbc-text-m);
	line-height: var(--sbc-leading-body);
}

/* Meme motif que .section-entete__chapo : le rythme des paragraphes est porte
   par le bloc, pas par une marge d'element qui fusionnerait avec ses voisines. */
.pourquoi-sobecom__texte > p + p {
	margin-block-start: var(--sbc-space-medium);
}

/* --- La bande de statistiques -------------------------------------------- */

.pourquoi-sobecom__chiffres {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 0;
	overflow: hidden;
	margin-block-start: var(--sbc-space-xbig);
	padding-left: 0;
	border-radius: var(--sbc-radius-medium);
	list-style: none;
}

/* `space-between` colle le paragraphe en bas du panneau, quelle que soit la
   hauteur imposee par le voisin le plus haut. Le gap fixe le plancher entre
   les deux quand le panneau n'est pas etire. */
.pourquoi-sobecom__chiffre {
	display: flex;
	min-width: 0;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--sbc-space-massive);
	padding: var(--sbc-space-xnormal);
	color: var(--sbc-color-text);
}

.pourquoi-sobecom__chiffre--1 {
	background-color: var(--sbc-color-surface-accent-subtle);
}

.pourquoi-sobecom__chiffre--2 {
	background-color: var(--sbc-color-surface-band);
}

.pourquoi-sobecom__chiffre--3 {
	background-color: var(--sbc-color-surface-accent-soft);
}

/* Le nombre et son libelle partagent la ligne, cales en haut : c'est ce qui
   donne a la bande sa signature. Le filet court sous les deux. */
.pourquoi-sobecom__mesure {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: var(--sbc-space-xxsmall);
	padding-block-end: var(--sbc-space-xxsmall);
	border-block-end: 1px solid var(--sbc-color-white);
}

/* Le filet est blanc, il se lit sur les deux panneaux verts. Sur le panneau du
   milieu il etait blanc sur blanc, donc invisible : la bande le fait
   reapparaitre, mais de justesse (1,13:1). Il prend donc le gris de filet, qui
   est fait pour ca. */
.pourquoi-sobecom__chiffre--2 .pourquoi-sobecom__mesure {
	border-block-end-color: var(--sbc-color-border);
}

/* Sur le panneau blanc, un filet blanc ne se verrait pas : il y passe au noir
   de la charte, comme dans le template. */
.pourquoi-sobecom__chiffre--2 .pourquoi-sobecom__mesure {
	border-block-end-color: var(--sbc-color-text);
}

.pourquoi-sobecom__valeur {
	font-size: var(--sbc-text-h4);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: -0.03em;
	line-height: var(--sbc-leading-tight);
}

.pourquoi-sobecom__libelle {
	font-size: var(--sbc-text-l);
	font-weight: var(--sbc-weight-medium);
	line-height: var(--sbc-leading-heading);
}

.pourquoi-sobecom__detail {
	line-height: var(--sbc-leading-body);
}

@media (min-width: 48rem) {

	.pourquoi-sobecom__chiffres {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (min-width: 62rem) {

	/* Le titre a gauche, le texte en vis-a-vis : c'est la ligne du haut de la
	   section « Consultancy result ». */
	.pourquoi-sobecom__haut {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: var(--sbc-space-jumbo);
	}
}


/* ============================================================================
   .processus — les quatre etapes, de l'appel a la pose
   ----------------------------------------------------------------------------
   Bloc de template-parts/sections/processus.php.

   Grand panneau blanc a coins arrondis (`choose-bottom` du site de reference,
   rayon 32 px, padding 30,08 px), dans lequel les quatre etapes sont separees
   par un filet : vertical en grand ecran, horizontal en colonne. Cercle
   d'icone de 3,375 rem en tete de chaque etape, puis le marquage
   « 01 / Contact » en capitales espacees, le titre a 1,5 rem et le texte au
   corps courant. Ecart icone / texte `spacing-medium` (20 px), comme la
   `growth-card` du template.

   Le filet remplace la carte a ombre : c'est la grammaire du template, et cela
   evite que cette section et « Ou l'on pose », qui se suivent, ne se
   ressemblent trait pour trait.

   Pas de trait de liaison entre les etapes : en quatre colonnes il tomberait
   juste, en une colonne il faudrait le retourner, et il ne dit rien que la
   numerotation ne dise deja.
   ========================================================================== */

.processus {
	padding-block: var(--sbc-space-huge);
	background-color: var(--sbc-color-surface-band);
}

.processus__etapes {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sbc-space-normal);
	margin-block-start: var(--sbc-space-xbig);
	padding: var(--sbc-space-xnormal);
	border-radius: var(--sbc-radius-big);
	background-color: var(--sbc-color-white);
	list-style: none;
}

.processus__etape {
	display: flex;
	min-width: 0;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--sbc-space-xxsmall);
}

/* Le filet separe, il n'encadre pas : porte par l'etape SUIVANTE, il n'y en a
   donc jamais avant la premiere ni apres la derniere. */
.processus__etape + .processus__etape {
	padding-block-start: var(--sbc-space-normal);
	border-block-start: 1px solid var(--sbc-color-border);
}

/* L'icone a besoin d'air avant le marquage, plus que le marquage n'en a besoin
   avant son titre. La marge est portee par l'enveloppe de section, jamais par
   le composant : un composant qui pousse ses voisins n'est pas reutilisable. */
.processus__icone {
	display: block;
	margin-block-end: var(--sbc-space-xsmall);
}

.processus__titre {
	font-size: var(--sbc-text-h6);
	font-weight: var(--sbc-weight-medium);
	line-height: var(--sbc-leading-heading);
}

.processus__texte {
	color: var(--sbc-color-text-muted);
	line-height: var(--sbc-leading-body);
}

/* L'en-tete etant centre, l'action qui ferme la section l'est aussi : elle
   repond au titre, pas a la derniere etape. */
.processus__cta {
	display: flex;
	justify-content: center;
	margin-block-start: var(--sbc-space-big);
}

@media (min-width: 48rem) {

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

	/* En grille, le filet ne suit plus l'ordre du document : il se pose a
	   gauche des colonnes qui en ont une avant elles, et au-dessus des rangees
	   qui en ont une au-dessus. */
	.processus__etape + .processus__etape {
		padding-block-start: 0;
		border-block-start: 0;
	}

	.processus__etape:nth-child(even) {
		padding-inline-start: var(--sbc-space-normal);
		border-inline-start: 1px solid var(--sbc-color-border);
	}

	.processus__etape:nth-child(n+3) {
		padding-block-start: var(--sbc-space-normal);
		border-block-start: 1px solid var(--sbc-color-border);
	}
}

@media (min-width: 75rem) {

	.processus__etapes {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.processus__etape:nth-child(n+3) {
		padding-block-start: 0;
		border-block-start: 0;
	}

	.processus__etape:nth-child(n+2) {
		padding-inline-start: var(--sbc-space-normal);
		border-inline-start: 1px solid var(--sbc-color-border);
	}
}


/* ============================================================================
   .realisations — galerie filtrable
   ----------------------------------------------------------------------------
   Bloc de template-parts/sections/realisations.php. L'agrandissement d'une
   vignette a son propre bloc, 03-components/visionneuse.css.

   En-tete a gauche avec son bouton secondaire en vis-a-vis, repris de la section
   « Case studies » du site de reference, puis la galerie : cinq filtres
   (« Tout » et les quatre categories de inc/realisations.php), le compteur,
   la grille, « voir plus ».

   Chaque vignette est un LIEN vers l'image en grand, qui enveloppe la figure
   et sa legende « G07 · Cercles et anneaux ». Le zoom au survol est celui du
   composant `figure` (:hover). Sa parite clavier, elle, est portee ICI : le
   lien est l'ANCETRE de la figure, le `.figure:focus-within` de figure.css ne
   peut donc pas jouer, le focus n'etant jamais a l'interieur de la figure.

   La grille de vignettes garde la gouttiere `spacing-medium` (20 px) et le
   rayon `radius-medium` du composant `figure`.

   Sans JavaScript, `.realisations__pilotage` et `.realisations__plus` restent
   sur leur attribut `hidden` et les 185 vignettes sont toutes visibles. La
   regle [hidden] ci-dessous est necessaire : sans elle, la declaration
   `display` d'un bloc l'emporterait sur celle de la feuille du navigateur et
   l'attribut n'aurait aucun effet.

   Les vignettes sont carrees a dessein : le fonds melange du 800x450 et du
   450x800 (CLAUDE.md, « Medias »), et le carre est le recadrage qui ampute le
   moins les deux orientations a la fois.

   Nombre de colonnes : quatre au maximum. A 81 rem de conteneur, une colonne
   sur quatre fait environ 300 px, soit moins que la plus petite source de la
   serie (345 px). C'est ce qui garantit qu'aucune photo n'est agrandie.
   ========================================================================== */

.realisations {
	padding-block: var(--sbc-space-huge);
	background-color: var(--sbc-color-white);
}

/* --- Galerie --------------------------------------------------------------
   `xbig` et non `jumbo` : la galerie suit maintenant directement l'en-tete, ce
   qui etait auparavant l'ecart entre l'en-tete et les cartes en vedette. */

.realisations__galerie {
	margin-block-start: var(--sbc-space-xbig);
}

.realisations__pilotage[hidden],
.realisations__plus[hidden] {
	display: none;
}

.realisations__filtres {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sbc-space-xsmall);
}

/* Cible tactile : le plancher de 44 px de brand/charte.md est tenu par
   min-height, pas par le seul padding. */
.realisations__filtre {
	display: inline-flex;
	align-items: center;
	gap: var(--sbc-space-xsmall);
	min-height: var(--sbc-target-min);
	padding: var(--sbc-space-xsmall) var(--sbc-space-medium);
	border: 1px solid var(--sbc-color-border);
	border-radius: var(--sbc-radius-pill);
	background-color: var(--sbc-color-white);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
	transition:
		background-color var(--sbc-transition-base),
		border-color var(--sbc-transition-base),
		color var(--sbc-transition-base);
}

.realisations__filtre:hover {
	border-color: var(--sbc-color-primary);
	color: var(--sbc-color-primary);
}

/* Etat actif porte par aria-pressed, pas par une classe : l'attribut qui
   informe le lecteur d'ecran est le meme que celui qui peint le bouton, ils ne
   peuvent donc pas diverger. */
.realisations__filtre[aria-pressed="true"] {
	border-color: var(--sbc-color-primary);
	background-color: var(--sbc-color-primary);
	color: var(--sbc-color-white);
}

/* Le nombre de photos est une information, pas une decoration : il ne peut pas
   etre attenue a l'opacite. Sur le bouton actif, du blanc a 65 % sur le teal
   tomberait a 3,1:1, sous le plancher de 4,5:1 des petits textes. Il est donc
   distingue par une COULEUR, qui tient ses contrastes dans les trois etats :
   #5A5A5A sur blanc au repos (7:1), le teal au survol (5,18:1), le blanc du
   libelle sur le teal a l'etat actif (5,18:1). */
.realisations__filtre-compte {
	color: var(--sbc-color-text-muted);
	font-variant-numeric: tabular-nums;
}

.realisations__filtre:hover .realisations__filtre-compte,
.realisations__filtre[aria-pressed="true"] .realisations__filtre-compte {
	color: currentColor;
}

.realisations__resultat {
	margin-block-start: var(--sbc-space-regular);
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}

.realisations__grille {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--sbc-space-small) var(--sbc-space-xsmall);
	margin-block-start: var(--sbc-space-small);
	padding-left: 0;
	list-style: none;
}

/* --- Vignette -------------------------------------------------------------
   L'anneau de focus est celui de 01-base.css (:focus-visible, teal) : rien a
   redoubler ici. Le lien porte le rayon du composant `figure` pour que cet
   anneau epouse les angles arrondis au lieu de dessiner un rectangle autour. */

.realisations__lien {
	display: block;
	border-radius: var(--sbc-radius-medium);
	color: inherit;
	text-decoration: none;
}

/* Parite clavier du zoom de la figure : le lien est l'ancetre de la figure,
   `.figure:focus-within` de figure.css ne peut pas jouer, c'est le lien qui
   porte le focus. Meme facteur, meme transition (celle de .figure__image). */
.realisations__lien:focus-visible .figure__image {
	transform: scale(1.04);
}

.realisations__legende {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sbc-space-tiny) var(--sbc-space-xsmall);
	align-items: baseline;
	margin-block-start: var(--sbc-space-xsmall);
	color: var(--sbc-color-text-muted);
	font-size: var(--sbc-text-small);
	line-height: var(--sbc-leading-body);
}

/* La reference en badge, seule dans la legende depuis le 16 septembre 2026
   (le client a retire les noms de motif) : c'est ce que le visiteur notera et
   nous citera. Teal fonce sur l'aplat teal 20 % : le teal de
   marque y tombe a 3,91:1 et echoue (CLAUDE.md, « Charte »), le fonce tient
   5,67:1. Chiffres tabulaires pour que G07 et G12 aient la meme largeur. */
.realisations__ref {
	padding: var(--sbc-space-tiny) var(--sbc-space-xsmall);
	border-radius: var(--sbc-radius-xsmall);
	background-color: var(--sbc-color-surface-accent-subtle);
	color: var(--sbc-color-primary-dark);
	font-weight: var(--sbc-weight-medium);
	font-variant-numeric: tabular-nums;
	letter-spacing: var(--sbc-tracking-label);
	text-transform: uppercase;
}

.realisations__plus {
	display: flex;
	justify-content: center;
	margin-block-start: var(--sbc-space-regular);
}

/* Meme peau que les filtres : c'est la meme commande de galerie, elle ne doit
   pas se confondre avec l'appel a l'action noir qui ferme la section. */
.realisations__bouton-plus {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--sbc-target-min);
	padding: var(--sbc-space-xsmall) var(--sbc-space-normal);
	border: 1px solid var(--sbc-color-border);
	border-radius: var(--sbc-radius-pill);
	background-color: var(--sbc-color-white);
	color: var(--sbc-color-text);
	font-size: var(--sbc-text-small);
	font-weight: var(--sbc-weight-medium);
	letter-spacing: var(--sbc-tracking-label);
	line-height: var(--sbc-leading-body);
	text-transform: uppercase;
	transition:
		border-color var(--sbc-transition-base),
		color var(--sbc-transition-base);
}

.realisations__bouton-plus:hover {
	border-color: var(--sbc-color-primary);
	color: var(--sbc-color-primary);
}

@media (min-width: 48rem) {

	.realisations__grille {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: var(--sbc-space-regular) var(--sbc-space-medium);
		margin-block-start: var(--sbc-space-regular);
	}
}

@media (min-width: 64rem) {

	.realisations__grille {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}


/* ============================================================================
   05-utilities — helpers d'accessibilite et de flux
   ----------------------------------------------------------------------------
   Prefixe `u-`. Ce fichier ne contient AUCUNE classe de mise en forme
   (couleur, marge, alignement) : celles-la sont interdites dans le HTML de
   contenu (CLAUDE.md, section CSS). Il n'y a ici que des primitives
   structurelles, dont deux d'accessibilite.
   ========================================================================== */

/* Retire du flux visuel, conserve pour les lecteurs d'ecran. Sert aux
   <legend> de groupe, aux libelles de bouton icone et au lien d'evitement. */
.u-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Variante du lien d'evitement : masque jusqu'a la premiere tabulation, puis
   rendu visible en tete de page. */
.u-visually-hidden--focusable:focus-visible {
	position: fixed;
	top: var(--sbc-space-small);
	left: var(--sbc-space-small);
	z-index: 999;
	width: auto;
	height: auto;
	margin: 0;
	padding: var(--sbc-space-xxsmall) var(--sbc-space-medium);
	overflow: visible;
	clip-path: none;
	background-color: var(--sbc-color-primary);
	color: var(--sbc-color-white);
	border-radius: var(--sbc-radius-xsmall);
	text-decoration: none;
}

/* Rythme vertical d'une suite d'elements de meme nature (titre + paragraphes
   + bouton). Espace regle par --sbc-flow, redefinissable par le bloc parent.
   Le selecteur adjacent evite toute marge orpheline en debut et en fin. */
.u-flow > * + * {
	margin-block-start: var(--sbc-flow, var(--sbc-space-medium));
}

/* Longueur de ligne confortable pour un bloc de texte long : mentions
   legales, politique de confidentialite, reponses de FAQ. */
.u-measure {
	max-width: var(--sbc-measure);
}

/* ============================================================================
   Apparitions au defilement
   ----------------------------------------------------------------------------
   Etat initial masque applique UNIQUEMENT sous `.js-anim`, classe posee sur
   <html> par le script en ligne de inc/enqueue.php — et seulement si
   l'utilisateur n'a pas demande a reduire les animations. Sans JavaScript,
   sous prefers-reduced-motion, ou si le module echoue, rien n'est masque :
   une animation ne conditionne jamais l'affichage d'un contenu.

   C'est pour cela que la classe est posee par un script EN LIGNE dans <head>
   plutot que par le module : pose plus tard, elle ferait clignoter la page,
   qui afficherait puis masquerait son contenu.
   ========================================================================== */

.js-anim [data-anim] {
	opacity: 0;
	transition:
		opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
		transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
	transition-delay: var(--sbc-anim-delai, 0s);
	will-change: opacity, transform;
}

.js-anim [data-anim=""],
.js-anim [data-anim="bas"] {
	transform: translateY(1.75rem);
}

/* ATTENTION AUX DEPLACEMENTS LATERAUX
   Un bloc qui occupe deja toute la largeur de son conteneur et qu'on decale de
   1,75 rem sort de la page et y ajoute une barre de defilement horizontale, le
   temps de l'animation. `.site-main` porte donc un `overflow-x: clip` en
   02-layout.css, qui rogne ce debordement sans creer de conteneur de
   defilement — contrairement a `hidden`, qui casserait les positions collees.

   Reserve malgre tout ces deux valeurs aux elements PLUS ETROITS que leur
   conteneur : une carte dans une grille, une colonne dans une rangee. */
.js-anim [data-anim="gauche"] {
	transform: translateX(-1.75rem);
}

.js-anim [data-anim="droite"] {
	transform: translateX(1.75rem);
}

.js-anim [data-anim="echelle"] {
	transform: scale(0.96);
}

/* Le fondu seul ne pose aucune transformation : il sert aux visuels lourds,
   qu'un deplacement ferait scintiller. */
.js-anim [data-anim="fondu"] {
	transform: none;
}

.js-anim [data-anim].est-visible {
	opacity: 1;
	transform: none;
	will-change: auto;
}

/* Cascade d'une rangee de cartes. Six crans suffisent : au-dela, le dernier
   element se revele trop longtemps apres le premier et la rangee parait
   cassee. */
.js-anim [data-anim-delai="1"] { --sbc-anim-delai: 0.08s; }
.js-anim [data-anim-delai="2"] { --sbc-anim-delai: 0.16s; }
.js-anim [data-anim-delai="3"] { --sbc-anim-delai: 0.24s; }
.js-anim [data-anim-delai="4"] { --sbc-anim-delai: 0.32s; }
.js-anim [data-anim-delai="5"] { --sbc-anim-delai: 0.40s; }
.js-anim [data-anim-delai="6"] { --sbc-anim-delai: 0.48s; }

