/* =============================================
   ORGATYPIK - LA FEUILLE PROPRE À LA MARQUE (pages bâties sur le socle commun)

   Chargée après socle.css (commun/css/, partagé avec pylotik) et avant
   utilitaires.css. Elle porte ce qui n'est qu'à orgatypik : héros, verbatims,
   méthode, témoignages, tuiles, panneaux, et l'habillage de marque des composants
   communs (bille des listes, accordéon « + », champs). Le reste de l'apparence
   passe par les rôles de design-system/tokens.css. Dérivée de style.css au lot 3 du
   chantier sites-web, sélecteurs renommés vers le vocabulaire du socle.

   Ancien en-tête de style.css :
   Charte de marque V2.1

   Cette feuille ne contient AUCUNE valeur de couleur, d'espacement ni de
   police. Elles vivent toutes dans ../design-system/tokens.css, qui doit être
   chargé avant celle-ci. Ici, on ne consomme que des alias sémantiques
   (--navy, --link, --on-navy-*, --space-*), jamais les primitives --ds-*.

   Y réintroduire une valeur en dur casserait la propriété qui fait tout
   l'intérêt du découpage : une couleur changée dans tokens.css se propage à
   toute la maquette, sans aucune autre modification.
   ============================================= */

/* =============================================
   UTILITAIRES
   ============================================= */

.narrow { max-width: 800px; margin-left: auto; margin-right: auto; }
.narrow-sm { max-width: 720px; margin-left: auto; margin-right: auto; }
.mt-xl { margin-top: var(--space-12); }

/* Note de section : commentaire d'auteur sous un bloc, plus discret qu'un paragraphe
   de corps. Sert notamment aux clauses explicatives (« pourquoi ça marche »). */
.section-note {
  max-width: 720px;
  margin: var(--space-10) auto 0;
  text-align: center;
  color: var(--gray-600);
  font-size: 0.95rem;
}

/* Pied de section : rappel de CTA sous une grille */
.section-footer { text-align: center; margin-top: var(--space-12); }
.section-footer .btn { margin-top: var(--space-4); }

.section-footer-lead {
  font-family: var(--font-heading);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--navy);
}

/* Groupe de boutons */
.btn-group { display: flex; gap: var(--space-4); flex-wrap: wrap; }

/* Rangée de pastilles */
.tag-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }

/* =============================================
   LOGO
   ============================================= */

/* Le logo associe le SYMBOLE (image) et le WORDMARK (texte).
   Le wordmark reste du texte : il est net à toute taille, sélectionnable, et
   son dégradé suit les tokens. Le dégradé porte sur .logo-word et non sur
   .logo, faute de quoi background-clip: text masquerait l'image.
   Les fichiers source d'origine sont en 4480x5440 : ne jamais les servir tels
   quels, employer les dérivés de assets/. */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
}

.logo-mark {
  width: 34px;
  height: 34px;
  display: block;
  flex-shrink: 0;
}

/* Le wordmark est désormais une IMAGE (assets/wordmark-light.png / -dark.png), plus
   un texte à dégradé : background-clip:text ne se rendait pas de façon fiable dans
   l'éditeur WordPress. La variante claire ou sombre est choisie par le src, jamais par
   le CSS. Hauteur = l'ink du wordmark à son ancienne taille (133/144 × 1.5rem = 1.386rem).
   Les trois classes partagent le dimensionnement ; seul leur contexte diffère
   (logo d'en-tête/pied, en-tête de tableau, carte visuelle). */
.logo-word,
.brand-word,
.brand-word-on-dark {
  display: inline-block;
  height: 1.386rem;
  width: auto;
  vertical-align: middle;
}

/* 0.65 rem faisait 10,4 px : sous le seuil de lisibilité confortable, et la baseline
   se lisait mal. 0.75 rem (12 px) la rend lisible sans qu'elle concurrence le wordmark,
   qui reste trois fois plus grand. */
.logo-tagline {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--gray-400);
  letter-spacing: 0.03em;
  display: block;
  /* Collée au wordmark. Le line-height du wordmark (1.7, hérité du corps) laissait un
     talon sous les lettres : la baseline flottait à distance. On le ramène à 1 sur le
     wordmark - il n'a qu'une ligne - et la marge négative absorbe ce qui reste. */
  margin-top: -2px;
  /* PLUS DE RETRAIT. Les 44 px valaient exactement la largeur du symbole (34) plus
     l'écart du logo (10) : ils alignaient la baseline sur le wordmark, à droite du
     symbole. Le symbole ayant quitté l'en-tête, ce retrait n'alignait plus rien -
     il décalait la phrase de 44 px vers la droite du wordmark. */
}

.site-footer .logo-mark { width: 40px; height: 40px; }

/* LE LOGO DU PIED : SYMBOLE AU-DESSUS DU WORDMARK, ET CENTRÉ SUR LUI.

   Ailleurs (en-tête), le logo est une ligne : symbole à gauche, mot à droite. Dans le
   pied il s'empile, et le symbole se centre sur la largeur du mot - pas sur celle de la
   colonne. D'où « width: fit-content » : sans lui, align-items centrerait le symbole
   dans toute la colonne de marque, qui est bien plus large que le wordmark, et le
   symbole partirait à droite du mot au lieu de le coiffer.

   Le bloc, lui, reste calé à gauche comme le reste de la colonne. */
.site-footer .logo {
  flex-direction: column;
  align-items: center;
  width: fit-content;
  gap: var(--space-2);
}

/* =============================================
   EN-TÊTE : CE QUI EST À ORGATYPIK

   Le socle porte l'en-tête (collant, et non plus fixe : les héros n'ont plus à
   compenser sa hauteur). Restent la baseline sous le wordmark, le soulignement fin
   des liens, et le menu mobile pleine largeur, ancré sous l'en-tête.
   ============================================= */

.nav-brand { flex-direction: column; align-items: flex-start; justify-content: center; gap: 0; }
.nav-links { gap: var(--space-8); }
.nav-links a { letter-spacing: 0.02em; padding: var(--space-1) 0; }
.nav-links a:hover { color: var(--navy); }
.nav-cta { letter-spacing: 0.01em; }
.nav-cta:hover { transform: translateY(-1px); }
.nav-disclosure { position: static; }

/* --- Menu mobile --- */
.nav-disclosure { display: none; }

.nav-burger {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
  transition: var(--transition);
}

.nav-burger::-webkit-details-marker { display: none; }
.nav-burger:hover { background: var(--gray-100); }

.nav-burger-icon,
.nav-burger-icon::before,
.nav-burger-icon::after {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--navy);
  border-radius: 2px;
  transition: var(--transition);
}

.nav-burger-icon { position: relative; }
.nav-burger-icon::before,
.nav-burger-icon::after { content: ''; position: absolute; left: 0; }
.nav-burger-icon::before { top: -7px; }
.nav-burger-icon::after { top: 7px; }

.nav-disclosure[open] .nav-burger-icon { background: transparent; }
.nav-disclosure[open] .nav-burger-icon::before { top: 0; transform: rotate(45deg); }
.nav-disclosure[open] .nav-burger-icon::after { top: 0; transform: rotate(-45deg); }

.nav-panel {
  position: absolute;
  top: var(--header-height);
  left: 0; right: 0;
  background: var(--white);
  border-bottom: 1px solid var(--gray-200);
  box-shadow: var(--shadow);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.nav-panel a {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--gray-600);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--gray-100);
}

.nav-panel a:hover,
.nav-panel a.active { color: var(--navy); }

.nav-panel .nav-cta {
  color: var(--white);
  text-align: center;
  border-bottom: none;
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-6);
}

/* =============================================
   BOUTONS
   ============================================= */


.btn { letter-spacing: 0.01em; }

.btn-block { width: 100%; justify-content: center; }

.btn-primary {
  background: var(--violet);
  color: var(--white);
  box-shadow: var(--shadow-violet);
}

.btn-primary:hover {
  background: var(--violet-dark);
  color: var(--white);
  transform: translateY(-2px);
  box-shadow: var(--shadow-violet-lg);
}

.btn-secondary {
  background: transparent;
  color: var(--navy);
  border: 2px solid var(--navy);
}

.btn-secondary:hover {
  background: var(--navy);
  color: var(--white);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.btn-white {
  background-color: var(--white);
  color: var(--navy);
  box-shadow: var(--shadow-on-dark);
}

.btn-white:hover {
  background-color: var(--off-white);
  color: var(--navy);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.btn-arrow::after { content: '→'; transition: var(--transition); }
.btn-arrow:hover::after { transform: translateX(4px); }

/* Boutons sur fond sombre. Le sélecteur :not(.btn) plus bas empêche les
   règles de couleur de lien d'atteindre les boutons - c'est ce qui rend
   inutiles les !important et la couche de correctifs de l'ancienne v2. */
.hero-home .btn-secondary,
.page-hero .btn-secondary,
.band-dark .btn-secondary,
.cta-band .btn-secondary {
  color: var(--white);
  border-color: var(--white);
}

/* LE SURVOL PREND LA MÊME GRAMMAIRE QUE LE BOUTON PRIMAIRE : l'aplat s'inverse, le
   bouton se soulève de 2 px et porte une ombre. Sans le soulèvement, l'inversion seule
   claquait - un aplat qui bascule d'un coup se lit comme un défaut d'affichage plutôt
   que comme une réaction. --shadow-on-dark est le token des objets clairs posés sur un
   fond sombre, celui qu'emploie déjà .btn-white : rien de nouveau n'est inventé ici. */
.hero-home .btn-secondary:hover,
.page-hero .btn-secondary:hover,
.band-dark .btn-secondary:hover,
.cta-band .btn-secondary:hover {
  background: var(--white);
  color: var(--navy);
  transform: translateY(-2px);
  box-shadow: var(--shadow-on-dark);
}

/* =============================================
   HERO
   ============================================= */

.hero { padding: 160px 0 var(--space-25); position: relative; overflow: hidden; }

.hero-home {
  background: var(--gradient-hero);
  color: var(--white);
  padding: 160px 0 120px;
}

.hero-home h1 { color: var(--on-navy-title); max-width: 800px; margin-bottom: var(--space-6); }

.hero-highlight { color: var(--on-navy-stat-violet); }

.hero-home .hero-sub {
  font-size: clamp(1.1rem, 2vw, 1.3rem);
  color: var(--on-navy-body);
  max-width: 640px;
  margin-bottom: var(--space-10);
  line-height: 1.8;
}

/* Le fond est un violet à 15 % composé sur le dégradé : --violet-light n'y
   atteint que 4.17:1. --on-navy-accent donne 6.59:1 au même endroit. */
.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--on-navy-accent);
  background: var(--on-navy-badge-bg);
  border: 1px solid var(--on-navy-badge-border);
  padding: 6px var(--space-4);
  border-radius: var(--radius-pill);
  /* 48px, et non 24 : l'air entre la pastille et le titre est une DÉCISION, prise
     après coup. Studio l'avait déjà - mais par accident : le blockGap du groupe posait
     un margin-top de 24px sur le <h1> (et sur lui seul, le <p> ayant un margin explicite
     qui l'annulait), ce qui s'ajoutait à cette marge. Le rendu était plus aéré que la
     maquette, en mieux, mais par un effet de bord - et le thème divergeait de sa source
     sans que rien ne le dise. On garde donc le rendu, et on le rend intentionnel :
     48px ici, blockGap coupé sur le hero côté thème. Les deux retombent sur la même
     hauteur, par construction. */
  margin-bottom: var(--space-12);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.hero-decoration {
  position: absolute;
  top: 0; right: 0;
  width: 50%;
  height: 100%;
  opacity: 0.08;
  background: radial-gradient(circle at 70% 30%, var(--navy-light) 0%, transparent 60%),
              radial-gradient(circle at 30% 80%, var(--violet) 0%, transparent 50%);
}

.hero-stats {
  display: flex;
  gap: var(--space-12);
  margin-top: var(--space-14);
  padding-top: var(--space-10);
  border-top: 1px solid var(--on-navy-border);
}

/* --on-navy-accent plutôt que --violet-light (3.14:1 en fin de dégradé),
   et cohérent avec les grands chiffres de la page résultats. */
.hero-stat-number {
  font-family: var(--font-heading);
  font-size: 2.4rem;
  font-weight: 800;
  color: var(--on-navy-accent);
  display: block;
}

.hero-stat-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--on-navy-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: var(--space-1);
}

/* Hero des pages internes */
.page-hero {
  background: var(--gradient-hero-page);
  color: var(--white);
  padding: 140px 0 var(--space-20);
  text-align: center;
}

/* LE HERO EN DEUX COLONNES : le discours à gauche, la marque à droite.

   .hero-page centre son texte, et c'est juste pour un hero pleine largeur. Dès qu'il
   se scinde, le centrage devient un défaut : deux colonnes centrées chacune sur
   elle-même ne s'alignent sur rien. La variante rétablit donc l'alignement à gauche,
   et annule le « margin: 0 auto » qui bornait le paragraphe au milieu.

   La colonne de marque EMPILE le symbole au-dessus du mot, centrés l'un sur l'autre.
   C'est la même disposition que le pied de page, pour la même raison : le symbole se
   centre sur la largeur du MOT, pas sur celle de la colonne, d'où width: fit-content. */
.page-hero--split { text-align: left; }

.hero-split {
  display: flex;
  align-items: center;
  gap: var(--space-16);
}

.hero-split-texte { flex: 1; min-width: 0; }

/* Sans colonne de marque, c'est l'ILLUSTRATION qui occupe la droite : le texte se
   borne donc à la moitié gauche, sinon il court dessous. 52 % et non 50 : le motif
   des illustrations laisse le tiers gauche vide, on peut donc mordre un peu. */
/* Pas « > .container » : côté WordPress, la Bannière glisse un
   .wp-block-cover__inner-container entre la section et le conteneur. Le sélecteur
   descendant couvre les deux rendus. */
.page-hero--split .container > * { max-width: 64%; }
/* LE TITRE DU HERO SCINDÉ EST PLUS PETIT, ET C'EST UNE CONTRAINTE DE LARGEUR.
   Mesuré au rendu : à 3.4rem (54.4 px), « de vingt-cinq ans de terrain » demande 803 px.
   La colonne n'en a que 650 - au-delà, le texte court sous la partie pleine de
   l'illustration, qui commence à 724 px du bord. À 2.6rem (41.6 px) la même ligne tombe
   à 614 px : les trois lignes voulues tiennent, et aucune ne se recasse.
   Le titre reste du TEXTE LARGE au sens WCAG (seuil 3:1) : les 6.46:1 mesurés tiennent. */
.page-hero--split h1 { font-size: clamp(2rem, 4vw, 3.1rem); }

.page-hero--split .hero-badge { margin-left: 0; margin-right: 0; }
/* (0,2,1) et non (0,1,1) : « .hero-page p:where(…) » pèse autant et vient plus bas
   dans le fichier, donc gagnerait par l'ordre. On qualifie par la colonne. */
.page-hero--split .container p:where(:not(.eyebrow)) {
  margin-left: 0;
  margin-right: 0;
  max-width: 34rem;
}

.hero-split-marque {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  width: fit-content;
}

.marque-symbole { width: 148px; height: auto; display: block; }
/* LE LOGO DANS LA BANDE FINALE. C'est le seul endroit de la page où la marque SIGNE
   au lieu de se présenter : le lecteur y est invité à partir vers pylotik.com. Le logo
   seul, transparent, dans sa variante des fonds sombres (charte V3.2), plutôt que le
   symbole et le mot posés l'un sur l'autre (Charley, 25/10/2026). Pas le carré blanc
   pylotik-logo.png : il est réservé aux moteurs et aux annuaires. */
.cta-marque {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  width: fit-content;
  margin: 0 auto var(--space-8);
}
.cta-marque .marque-logo { width: 96px; height: auto; display: block; }

.marque-mot { width: 232px; height: auto; display: block; }

/* Variante de marque. Le dégradé finit sur --violet (8.23:1 sous du blanc)
   et non sur --navy-light, qui n'offrait que 2.75:1. */
.page-hero--brand { background: var(--gradient-hero-brand); }

/* Le hero ILLUSTRÉ. En WordPress c'est une Bannière (core/cover) : une image, un voile
   coloré par-dessus, le contenu au-dessus. Ici on le rend à l'identique.

   Le voile est un PSEUDO-ÉLÉMENT À OPACITÉ, et non un dégradé de couleurs transparentes :
   c'est l'exact équivalent du dimRatio de core/cover, et cela n'oblige à inventer aucune
   couleur hors charte.

   La classe est « hero--visuel » et NON « hero-page--visuel » : l'accueil n'est pas un
   .hero-page, et le mécanisme doit valoir pour les deux familles de hero.

   ⚠ L'OPACITÉ DU VOILE EST UNE CONTRAINTE DE CONTRASTE, PAS UN RÉGLAGE D'ESTHÉTIQUE.
   Elle n'est donc PAS déclarée ici, mais page par page, plus bas : elle dépend des pixels
   de l'illustration, et une valeur commune serait soit trop faible quelque part, soit
   inutilement opaque partout. Sans déclaration, l'opacité vaut 1 : le voile est plein et
   l'on retombe sur le dégradé seul - un échec SÛR, jamais un échec de contraste. */
/* « contain » et non « cover », et à DROITE. Trois raisons, dans cet ordre :
   - cover RECADRE : sur resultats, la trajectoire perdait son sommet, qui est le sujet ;
   - cover AGRANDIT dès que le hero est plus large que l'image (au-delà de 1424px de
     viewport), et une illustration agrandie se dégrade ;
   - la composition des illustrations est faite POUR ça : le motif occupe la droite, le
     tiers gauche est vide. Les caler à droite les remet dans leur cadrage d'origine.

   ⚠ D'OÙ TROIS COUCHES, ET NON UNE. En « cover » l'image couvrait tout et se suffisait.
   En « contain » elle ne couvre plus que la droite, ce qui a fait apparaître DEUX défauts
   successifs, chacun réglé par une couche :

     le fond    le dégradé, opaque. Sans lui, le voile se posait sur le BLANC de la page
                à gauche de l'image : une couture verticale franche. Avec lui, le côté
                gauche vaut « dégradé x opacité + dégradé x (1 - opacité) », c'est-à-dire
                exactement le dégradé nu. La jonction disparaît par construction.
     ::after    l'illustration, FONDUE À GAUCHE. Les illustrations portent leur propre
                fond navy opaque, qui n'est pas tout à fait le nôtre : leur bord gauche
                dessinait une arête nette, d'autant plus visible que le voile est léger
                (flagrant sur hpi-en-entreprise à 0.4). Le masque l'efface sur les 22 %
                de gauche - une zone où les illustrations sont vides de toute façon.
     ::before   le voile, dont l'opacité est mesurée page par page.

   L'ordre de peinture est tenu par z-index, et NON par l'ordre des pseudo-éléments :
   ::after est peint APRÈS ::before à z-index égal, ce qui mettrait l'illustration
   par-dessus son propre voile. */
.hero--visuel {
  position: relative;
  background: var(--hero-degrade);
}

/* Le dégradé de SA famille de hero, déclaré UNE fois : le fond et le voile le lisent
   tous deux. L'illustration ne change donc rien à la couleur du hero - elle s'y ajoute,
   elle ne s'y substitue pas. */
.hero-home.hero--visuel { --hero-degrade: var(--gradient-hero); }
.page-hero.hero--visuel { --hero-degrade: var(--gradient-hero-page); }
.page-hero--brand.hero--visuel { --hero-degrade: var(--gradient-hero-brand); }

.hero--visuel::after {
  content: "";
  position: absolute;
  /* L'en-tête est collant depuis le socle commun (lot 4 du chantier) : il ne recouvre
     plus le haut du hero, qui a perdu les 72 px qu'il lui réservait. L'image part donc
     du haut de la boîte et en prend toute la hauteur : c'est exactement le cadrage
     d'avant, où elle partait sous l'en-tête fixe, sur la partie visible du hero. */
  top: 0;
  bottom: 0;
  right: 0;
  /* Le calage vertical est réglable PAR PAGE. Par défaut l'illustration est centrée dans
     la partie visible du hero ; l'accueil la veut en bas (« margin-bottom: 0 » l'y pousse,
     le « margin-top: auto » absorbant tout le reste). Le calage horizontal, lui, est
     toujours à droite : c'est la composition même des illustrations. */
  margin-block: auto;

  /* ⚠ LA BOÎTE ÉPOUSE L'IMAGE, ET IL Y A DEUX RÉGIMES POUR Y ARRIVER.
     Par défaut l'illustration remplit la HAUTEUR du hero, et sa largeur suit le ratio.
     Mais quand on veut la borner (l'accueil, dont le hero est très haut), c'est la
     LARGEUR qui commande et la hauteur qui suit. Étirer la boîte tout en bornant sa
     largeur donnerait une boîte au mauvais ratio, dans laquelle « contain » letterboxe
     l'image : elle flotterait alors avec des bords francs au milieu du hero - ce qui
     s'est produit, et se voyait d'autant plus que le fond propre des illustrations n'est
     pas exactement le nôtre. Deux variables, un seul jeu de règles. */
  height: 100%;
  width: auto;
  aspect-ratio: 1424 / 752;
  max-width: 100%;
  z-index: 1;

  /* L'illustration est déclarée par la page, sur la section : style="--illu: url(...)",
     comme sur pylotik. Le voile, lui, reste réglé par page ci-dessous. */
  background-image: var(--illu);
  background-size: contain;
  background-position: right bottom;
  background-repeat: no-repeat;

  /* LE FONDU PORTE SUR TOUS LES BORDS, et non plus sur le seul bord gauche. Les
     illustrations portent un fond navy opaque proche du nôtre sans lui être égal : tout
     bord qui ne coïncide pas avec un bord du hero se voit. À pleine hauteur, seul le bord
     gauche était dans ce cas ; bornée, l'image a aussi un haut et un bas. Le bord DROIT
     touche toujours celui du hero : il n'a rien à fondre. */
  /* LE FONDU ESTOMPE LES BORDS DE L'IMAGE. Les illustrations portent un fond navy opaque
     proche du nôtre sans lui être égal : tout bord qui ne coïncide pas avec un bord du
     hero se verrait. Le bord DROIT ne fond jamais - il touche toujours celui du hero. */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 22%),
                      linear-gradient(to bottom, transparent 0%, #000 26%, #000 74%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, #000 22%),
              linear-gradient(to bottom, transparent 0%, #000 26%, #000 74%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

.hero--visuel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--hero-degrade);
}

/* Le contenu repasse au-dessus des deux. */
.hero--visuel > .container { position: relative; z-index: 3; }

/* L'ILLUSTRATION ET SON VOILE, PAGE PAR PAGE. L'image ne peut pas vivre dans le HTML, où
   l'attribut style= est banni (§7). Côté WordPress elle n'est ici ni l'une ni l'autre :
   « url » et « dimRatio » sont des attributs du bloc - c'est tout l'intérêt de la
   Bannière. Les valeurs jumelles vivent dans contenu/convertir.py (HERO_VISUELS).

   ⚠ CES VALEURS SONT MESURÉES SUR LE RENDU, PAS CALCULÉES SUR UN MODÈLE - et la différence
   n'est pas académique : elle vaut un facteur deux. Le modèle prenait le pire pixel de
   l'image ENTIÈRE, sans savoir où le texte tombe. Depuis que les illustrations sont en
   « contain » calées à droite, le texte n'en recouvre plus qu'une partie, et le modèle
   condamnait des voiles parfaitement lisibles : approche passait de 0.85 à 0.45, resultats
   de 0.90 à 0.50. La sonde masque le texte, photographie le fond, relève la boîte et la
   couleur calculée de chaque bloc, et ne compare QUE les pixels réellement recouverts.

   Chaque valeur est la plus LÉGÈRE qui garde une marge de x1.12 sur le seuil AA (4.5:1,
   ou 3:1 pour le texte large). La marge est volontaire : un ratio au ras du seuil ne
   survit ni à un changement d'illustration, ni à une réécriture du texte.

   Baisser une valeur à la main, c'est reprendre la mesure. */

/* corps 5.38:1. */
.hero-visuel-collectif::before { opacity: 0.9; }

/* badge 5.26:1. */
.hero-visuel-services::before { opacity: 0.7; }

/* titre 3.70:1 (seuil 3, texte large). */
.hero-visuel-approche::before { opacity: 0.5; }

/* corps 5.27:1. */
.hero-visuel-resultats::before { opacity: 0.7; }

/* corps 5.43:1. */
.hero-visuel-contact-entreprise::before { opacity: 0.5; }

/* corps 5.28:1. */
.hero-visuel-contact::before { opacity: 0.7; }

/* corps 7.32:1 - la plus sombre. */
.hero-visuel-hpi::before { opacity: 0.4; }

/* corps 5.08:1. */
.hero-visuel-nombre-hpi::before { opacity: 0.7; }

/* H1 8.10:1, chapô 9.27:1, pastille 9.66:1 - mesurés sur le RENDU, texte masqué, au
   pixel de fond le plus clair de la BOÎTE RÉELLE de chaque bloc (et non d'une zone
   estimée : la première mesure débordait sous le hero et relevait le blanc de la
   section suivante).
   Le point dur reste le H1 : le faisceau lumineux de l'illustration passe derrière sa
   troisième ligne. Les ratios ont GAGNÉ depuis que l'illustration est bornée en largeur
   - elle recule, donc son faisceau aussi. À 0.60 le H1 tombait à 5.17:1 dans la
   disposition précédente ; 0.68 est conservé, il donne maintenant 8.10:1. */
.hero-visuel-produit::before { opacity: 0.68; }
/* LE SEUL HERO DONT L'ILLUSTRATION N'A PAS LE RAPPORT DE LA SÉRIE. Les huit autres font
   1424x752 ; celle-ci est RECADRÉE à partir de 34 % de sa largeur, parce que son motif
   d'origine est SYMÉTRIQUE - deux structures en miroir - et que le mécanisme du hero
   suppose un motif à droite et un tiers gauche vide. Mesuré sur l'image entière : la
   structure de gauche commençait à 35 % de la largeur, exactement là où le texte finit.
   Le recadrage rend le motif asymétrique ; la structure coupée à gauche se lit comme
   continuant hors cadre. Sans cette ligne, « contain » letterboxerait l'image dans une
   boîte au mauvais rapport et ses bords se verraient. */
.hero-visuel-produit::after {
  aspect-ratio: 940 / 752;
  /* BORNÉE EN LARGEUR, donc c'est la hauteur qui suit - le second régime décrit
     plus haut. Sans cela l'illustration remontait jusqu'à 555 px du bord gauche et
     ne laissait que 666 px au titre : à peine 2.6rem. Bornée à 46 %, elle démarre à
     694 px et son fondu se termine à 824, ce qui rend 774 px au titre et permet de
     le remonter à 3.1rem. Le motif reste entier, il est seulement plus petit. */
  width: 46%;
  height: auto;
}

/* libellés des chiffres clés 5.06:1. */
.hero-visuel-accueil::before { opacity: 0.7; }

.page-hero h1 { color: var(--on-navy-title); margin-bottom: var(--space-4); }

/* Même raison : le surtitre est un <span> ici, un paragraphe dans WordPress. */
.page-hero p:where(:not(.eyebrow)) {
  color: var(--on-navy-body);
  font-size: 1.15rem;
  max-width: 600px;
  margin: 0 auto;
}

/* =============================================
   SECTIONS
   ============================================= */


.band-dark {
  background: var(--gradient-section-dark);
  color: var(--on-navy-body);
}

.band-dark h2,
.band-dark h3 { color: var(--on-navy-title); }
.band-dark .eyebrow { color: var(--on-navy-overline); }
/* LE SURTITRE D'UN HERO SOMBRE. Il manquait, et c'était un défaut de contraste ANCIEN,
   antérieur aux heros illustrés : « .band-dark .eyebrow » recevait bien une teinte
   lisible, mais rien n'existait pour « .hero-page .eyebrow ». Le surtitre y restait donc
   en --violet sur navy, soit 1.46:1 - un ratio que le projet documente lui-même plus bas.
   L'illustration de fond ne l'a pas causé : elle l'a rendu visible. */
.page-hero .eyebrow { color: var(--on-navy-overline); }
.band-dark p { color: var(--on-navy-body); }

.section-head { text-align: center; max-width: 700px; margin: 0 auto var(--space-16); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--violet);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: var(--space-3);
  display: block;
}

.eyebrow--left { text-align: left; }

.section-head h2 { margin-bottom: var(--space-4); }

/* Le :not(.eyebrow) n'est pas une precaution oiseuse : c'est ce qui rend la regle
   independante de la BALISE qui porte le surtitre.
   Ici, l'overline est un <span>, que « .section-head p » n'atteint pas. Mais dans
   WordPress, un surtitre est forcement un PARAGRAPHE - Gutenberg n'a pas de bloc
   <span> - et il tombait alors sous cette regle, dont la specificite (0,1,1) bat
   celle de .eyebrow (0,1,0). Le surtitre y passait a 1.1rem et au gris, au lieu de
   0.75rem et du violet. Le defaut est apparu au portage, la faute etait ici.
   Aucun changement de rendu dans la maquette : elle n'a pas de p.eyebrow. */
.section-head p:where(:not(.eyebrow)) { font-size: 1.1rem; color: var(--text-light); line-height: 1.8; }

/* .section-head p et .band-dark p ont la même spécificité (0,1,1) : sans
   cette règle, le gris clair l'emporte par ordre de déclaration et tombe à
   2.24:1 sur navy.
   Même :not(.eyebrow), et pour la même raison : (0,2,1) battrait
   « .band-dark .eyebrow » (0,2,0), et le surtitre perdrait sa teinte lisible sur
   fond sombre - celle qui donne 6.97:1 là où le violet n'en donne que 1.46. */
.band-dark .section-head p:where(:not(.eyebrow)) { color: var(--on-navy-body); }

/* Liens sur fonds sombres. Le :not(.btn) est essentiel : sans lui, les
   boutons héritent de la couleur de lien et il faut des !important. */
.band-dark a:not(.btn),
.cta-band a:not(.btn),
.hero-home a:not(.btn),
.page-hero a:not(.btn) { color: var(--on-navy-overline); }

.band-dark a:not(.btn):hover,
.cta-band a:not(.btn):hover,
.hero-home a:not(.btn):hover,
.page-hero a:not(.btn):hover { color: var(--white); }

/* =============================================
   GRILLES
   ============================================= */

.grid-2 { align-items: center; }

.gap-sm { --grid-gap: var(--space-4); }
.gap-md { --grid-gap: var(--space-6); }
.gap-lg { --grid-gap: var(--space-8); }
.gap-xl { --grid-gap: var(--space-12); }
.gap-2xl { --grid-gap: var(--space-16); }

.grid--top { align-items: flex-start; }

/* =============================================
   CARTES
   ============================================= */


/* Le soulèvement au survol est commun à toutes les cartes, tarifs compris. Il est
   déclaré ICI, et une seule fois : le -4px est une valeur, pas un token, et deux
   copies auraient fini par diverger. */
.card:hover,
.pricing-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* =============================================
   ICÔNES
   =============================================

   Les icônes étaient des emoji, ce sont désormais des images. Leur taille ne se
   règle donc plus par `font-size` : les conteneurs continuent d'en porter un,
   sans effet sur elles, mais il sert encore à l'alignement du texte voisin.

   max-width et max-height plutôt que width et height : les 44 illustrations
   n'ont pas toutes le même rapport (de 96 à 250 px de large), et une boîte
   carrée les contient toutes sans en déformer aucune.

   Un seul défaut est prévu ici : la valeur par défaut vaut pour les icônes
   posées dans un titre (mini-cartes, panneaux), où elles suivent le texte. */

.icone {
  display: inline-block;
  vertical-align: middle;
  width: auto;
  height: auto;
  max-width: 1.5rem;
  max-height: 1.5rem;
}

.card-icon .icone            { max-width: 34px;  max-height: 34px; }
.card-media .icone           { max-width: 76px;  max-height: 76px; }
.visual-card-icon .icone     { max-width: 104px; max-height: 104px; }
.visual-card-icon--md .icone { max-width: 84px;  max-height: 84px; }
.value-tile-icon .icone      { max-width: 34px;  max-height: 34px; }
.value-tile-icon--lg .icone  { max-width: 46px;  max-height: 46px; }
.h-icon-glyph .icone         { max-width: 32px;  max-height: 32px; }
.pain-icon .icone            { max-width: 26px;  max-height: 26px; }

/* Ces deux emplacements portaient un glyphe de 12 à 14 px, illisible pour une
   illustration. Ils sont agrandis, ce que leur conteneur absorbe sans casse. */
.hero-badge .icone           { max-width: 22px;  max-height: 22px; }
.footer-location .icone      { max-width: 18px;  max-height: 18px; }

.card-icon {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  margin-bottom: var(--space-5);
}

.card-icon-navy { background: var(--surface-tint-navy); color: var(--navy); }
.card-icon-violet { background: var(--surface-tint-violet); color: var(--violet); }
.card-icon-blue { background: var(--surface-tint-blue); color: var(--navy-light); }

.card h3 { margin-bottom: var(--space-3); }
/* Le :not() rend la règle indépendante de la BALISE. Dans la maquette, .card-icon est
   un <div> et .card-link un <a> : « .card p » ne les atteint pas. Dans WordPress, les
   deux sont des PARAGRAPHES - Gutenberg n'a ni bloc <div> ni bloc <a> - et ils
   tombaient sous cette règle, dont la spécificité (0,1,1) bat la leur (0,1,0).
   L'icône passait de 1.6rem à 0.95rem, et le lien de 0.85 à 0.95. Sans effet ici. */
.card p:where(:not(.card-icon)):where(:not(.card-link)) { color: var(--text-light); font-size: 0.95rem; }

.card-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-heading);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--violet);
  margin-top: var(--space-4);
}

.card-link:hover { gap: 10px; }

/* LE LOGOTYPE D'UNE CARTE DE MARQUE. Les deux mots de marque n'ont pas le même rapport
   (orgatypik 4.55, pylotik 3.46) : on borne la HAUTEUR, jamais la largeur, sinon l'un
   paraîtrait deux fois plus gros que l'autre. 30 px les met à la même présence optique.

   En blocs, l'image est enveloppée d'une <figure> : la règle porte donc sur les deux. */
.card-logo { margin-bottom: var(--space-5); }
.card-logo img { height: 30px; width: auto; display: block; }

/* Carte à vignette (articles de blog) */
.card--media { padding: 0; overflow: hidden; }

.card-media {
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3rem;
}

.card-media--1 { background: var(--gradient-media-1); }
.card-media--2 { background: var(--gradient-media-2); }
.card-media--3 { background: var(--gradient-media-3); }

.card-body { padding: var(--space-7) var(--space-6); }
.card-body h3 { font-size: 1.05rem; margin: var(--space-3) 0 var(--space-2); }
.card-body p { font-size: 0.85rem; color: var(--gray-400); }

/* =============================================
   VERBATIMS
   ============================================= */

/* Flex plutôt que grille : la grille aligne les orphelins de la dernière rangée à
   gauche, sans moyen de les centrer. En flex, `justify-content: center` centre la
   rangée incomplète, et le `max-width` à un tiers empêche les deux cartes de la
   dernière rangée de s'étirer sur toute la largeur. Les rangées pleines, elles,
   remplissent exactement (3 × un tiers + 2 gouttières = 100 %). */
.pain-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-5);
}

.pain-card {
  flex: 1 1 280px;
  max-width: calc((100% - 2 * var(--space-5)) / 3);
  margin: 0;                       /* le verbatim est un <blockquote> : on ôte sa marge par défaut */
  background: var(--white);
  border-radius: var(--radius);
  padding: var(--space-7) var(--space-6);
  /* Filet fin et transparent sur tout le pourtour : au repos il ne se voit pas,
     mais il réserve la place, si bien que l'apparition au survol ne décale rien.
     Pas de barre latérale colorée - trop marquée. */
  border: 1px solid transparent;
  box-shadow: var(--shadow);
  font-size: 0.95rem;
  color: var(--gray-600);
  font-style: italic;
  line-height: 1.7;
  transition: var(--transition);
}

/* Au survol : le filet passe en violet et la carte grossit légèrement. */
.pain-card:hover { border-color: var(--violet); transform: scale(1.03); }
.pain-card .pain-icon { font-style: normal; font-size: 1.3rem; margin-right: var(--space-2); }

/* =============================================
   ÉTAPES DE MÉTHODE
   ============================================= */

.method-step {
  display: flex;
  gap: var(--space-10);
  align-items: flex-start;
  padding: var(--space-12) 0;
  border-bottom: 1px solid var(--gray-200);
}

.method-step:last-child { border-bottom: none; }

.step-number {
  font-family: var(--font-heading);
  font-size: 4rem;
  font-weight: 900;
  background: var(--gradient-brand-text);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  opacity: 0.15;
  line-height: 1;
  flex-shrink: 0;
  width: 100px;
  text-align: center;
}

.step-content h3 { margin-bottom: var(--space-3); display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

.step-tag {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: 600;
  color: var(--violet);
  background: var(--surface-tint-violet);
  padding: var(--space-1) 10px;
  border-radius: var(--radius-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* =============================================
   TÉMOIGNAGES
   ============================================= */

.testimonial {
  margin: 0;                       /* le témoignage est un <blockquote> : on ôte sa marge par défaut */
  background: var(--white);
  border-radius: var(--radius);
  padding: var(--space-10);
  box-shadow: var(--shadow);
  position: relative;
  border: 1px solid var(--gray-200);
}

.testimonial::before {
  content: '❝';
  font-size: 4rem;
  color: var(--violet);
  opacity: 0.15;
  position: absolute;
  top: var(--space-4);
  left: var(--space-6);
  line-height: 1;
}

.testimonial p {
  font-size: 1rem;
  line-height: 1.8;
  color: var(--gray-600);
  margin: 0 0 var(--space-5);
}

/* L'auteur et son rôle vivent dans le <cite> de la citation : l'auteur en gras
   (le <strong>), le rôle sur la ligne suivante (après le <br>). */
.testimonial cite {
  display: block;
  font-style: normal;
  font-size: 0.8rem;
  color: var(--gray-400);
}

.testimonial cite strong {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--navy);
}

/* Les études de cas ne portent plus de témoignage imbriqué : nommer un client
   à côté de la description de ses difficultés relèverait du secret des affaires.
   Les avis clients restent sur la page d'accueil, publiés avec leur accord. */

/* =============================================
   TARIFS
   ============================================= */

.pricing-card {
  background: var(--white);
  border-radius: var(--radius);
  padding: var(--space-10) var(--space-8);
  border: 2px solid var(--gray-200);
  text-align: center;
  transition: var(--transition);
}

.pricing-card.featured { border-color: var(--violet); position: relative; }

.pricing-card.featured::before {
  content: 'Populaire';
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--violet);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  padding: var(--space-1) var(--space-4);
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Le survol de .pricing-card est déclaré avec celui de .card, section CARTES. */

.pricing-title {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--navy);
  margin-bottom: var(--space-2);
}

.pricing-price {
  font-family: var(--font-heading);
  font-size: 1.8rem;
  font-weight: 800;
  color: var(--navy);
  margin: var(--space-4) 0 var(--space-1);
}

.pricing-price small { font-size: 0.9rem; font-weight: 500; color: var(--gray-400); }
.pricing-desc { font-size: 0.85rem; color: var(--gray-400); margin-bottom: var(--space-6); }
.pricing-note { text-align: center; color: var(--gray-400); font-size: 0.85rem; margin-top: var(--space-6); }

.pricing-features { list-style: none; text-align: left; margin-bottom: var(--space-8); }

.pricing-features li {
  padding: var(--space-2) 0;
  font-size: 0.9rem;
  color: var(--gray-600);
  border-bottom: 1px solid var(--gray-100);
  display: flex;
  align-items: center;
  gap: 10px;
}

.pricing-features li::before { content: '✓'; color: var(--violet); font-weight: 700; flex-shrink: 0; }

/* =============================================
   TABLE COMPARATIVE
   ============================================= */

/* De l'air au-dessus. Le tableau suivait le chapeau de section sans respiration : il
   commençait là où le texte finissait. */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin-top: var(--space-12);
}

/* AUCUN TRAIT SOUS L'EN-TÊTE. L'aplat pastel suffit à le séparer des lignes : un trait
   par-dessus ferait double emploi. La règle est écrite en NÉGATIF, et c'est délibéré -
   WordPress, lui, pose « thead { border-bottom: 3px solid } » sur son bloc Tableau, à la
   couleur du texte. Sans cette ligne, un trait noir de 3 px barrait le tableau sur le
   site, là où la maquette n'en avait aucun. */
.table thead { border-bottom: none; }

/* L'en-tête est un APLAT CLAIR - le pastel navy de la charte, --surface-table-head.

   Il était navy foncé, ce qui obligeait le wordmark à sa variante « fond sombre ».
   Or le wordmark d'orgatypik EST le dégradé navy -> violet : le montrer sur clair,
   c'est le montrer tel qu'il est. Le fond clair n'est donc pas un choix esthétique,
   c'est ce qui rend le logotype fidèle.

   Contrastes vérifiés sur le pastel (#D4D9EC) : navy 8.55:1, et l'arrêt violet du
   wordmark 5.85:1 - AA en texte courant l'un comme l'autre, sans avoir à invoquer
   la clause du texte large. Le point gris, lui, change de gris : voir .brand-word.

   L'aplat se distingue du zébrage des lignes paires (--off-white), bien plus clair :
   l'en-tête se lit comme un en-tête. */
.table th {
  font-family: var(--font-heading);
  font-weight: 600;   /* un cran au-dessus des lignes (400), sans l'excès du 700 */
  padding: var(--space-3) var(--space-5);   /* 12px, et non 16 : l'en-tête était plus
                                               haut que les lignes qu'il coiffe */
  text-align: left;
  vertical-align: middle;   /* centre « Cabinet classique » et l'image du wordmark sur la
                               même ligne : sans lui, l'alignement se fait sur la baseline
                               et le texte remonte au-dessus de l'image. */
  background: var(--surface-table-head);
  color: var(--navy);
  width: 50%;
}

.table th:first-child { border-radius: var(--radius-md) 0 0 0; }
.table th:last-child { border-radius: 0 var(--radius-md) 0 0; }

/* 1.2rem en graisse 800 font 19.2px gras : « texte large » au sens WCAG, seuil 3:1.
   Le wordmark y est très au-dessus (5.85:1 au pire arrêt), donc contrairement à la
   variante sur fond sombre, le réduire ne le mettrait pas en défaut. line-height: 1
   empêche la ligne de grandir : sans lui, l'en-tête gagnerait 8px pour rien. */
.table th .brand-word { height: 1.109rem; }   /* wordmark plus petit dans le tableau (ink de 1.2rem) */

.table td { padding: 14px var(--space-5); border-bottom: 1px solid var(--gray-200); }
.table tr:last-child td { border-bottom: none; }
.table tr:nth-child(even) { background: var(--off-white); }

/* LA LIGNE MISE EN ÉVIDENCE : LA DERNIÈRE DU CORPS, ET C'EST STRUCTUREL.

   Aucune classe sur le <tr>, et ce n'est pas une préférence : le save() de core/table
   ne conserve d'une cellule que « content », « tag », « align », « colspan » et
   « rowspan ». Une rangée porteuse de classe rendrait le bloc INVALIDE dans l'éditeur.
   Le repère est donc positionnel - la ligne mise en avant est la dernière -, ce qui est
   la seule forme que WordPress sait reproduire à l'identique.

   L'aplat est le PASTEL VIOLET de la charte (#E2DAF0, aplat only) : il se distingue du
   pastel navy de l'en-tête sans sortir de la palette. Contrastes mesurés dessus :
   navy 8.89:1, et le wordmark 7.12:1 sur son segment bleu - le segment terracotta
   (3.19:1) et le point (2.36:1) relèvent du logotype, exempté par WCAG 1.4.11.

   Le zébrage des lignes paires est battu SANS !important : (0,2,1) contre (0,2,0). Le
   « border-bottom: none » de tr:last-child, lui, est à égalité - d'où la position de
   ce bloc APRÈS lui dans le fichier, qui est ce qui tranche. */
.table tbody tr:last-child td {
  background: var(--pastel-violet);
  color: var(--navy);
  font-weight: 500;
  border-top: 2px solid var(--violet);
  border-bottom: none;
}
.table tbody tr:last-child td:first-child { border-radius: 0 0 0 var(--radius-md); }
.table tbody tr:last-child td:last-child { border-radius: 0 0 var(--radius-md) 0; }

/* =============================================
   BANDE D'APPEL À L'ACTION
   ============================================= */

.cta-band {
  background: var(--gradient-cta);
  color: var(--white);
  padding: var(--space-20) 0;
  text-align: center;
  position: relative;
  overflow: hidden;
}

.cta-band--deep { background: var(--gradient-cta-deep); }

.cta-band h2 { color: var(--on-navy-title); margin-bottom: var(--space-4); }
.cta-band p { color: var(--on-navy-body); font-size: 1.1rem; max-width: 560px; margin: 0 auto var(--space-8); }

/* =============================================
   FORMULAIRE
   ============================================= */

.form-heading { margin-bottom: var(--space-2); }
.form-intro { color: var(--gray-600); margin-bottom: var(--space-8); }

.field { margin-bottom: var(--space-6); }

.field label {
  display: block;
  font-family: var(--font-heading);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: var(--space-2);
}

.field input,
.field textarea,
.field select {
  width: 100%;
  padding: 14px var(--space-4);
  font-family: var(--font-body);
  font-size: 0.95rem;
  border: 2px solid var(--gray-200);
  border-radius: var(--radius-md);
  transition: var(--transition);
  background: var(--white);
  color: var(--text);
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 4px var(--ring-focus);
}

.field textarea { resize: vertical; min-height: 140px; }

/* Champ de téléversement : le remplissage vertical du sélecteur natif diffère
   d'un navigateur à l'autre, on l'aligne sur les autres champs. */
.field input[type="file"] { padding: 11px var(--space-4); font-size: 0.9rem; cursor: pointer; }

.form-hint-inline { font-size: 0.8rem; color: var(--gray-400); margin-top: var(--space-1); }

/* La validation sans JavaScript des champs vit dans le socle (.form--validation). */

/* Les modificateurs .form-hint--error / --success / --attention ont été RETIRÉS.
   Ils n'étaient posés sur aucun élément, et .form-hint doublait exactement
   .form-hint-inline, plus haut. Leur commentaire prétendait « donner un usage aux
   tokens d'état » : c'est faux, --error et --success colorent les bordures
   :invalid et :valid ci-dessus, et --attention colore .legal-todo. Ils vivent
   sans ces classes.

   Le formulaire de production apportera son propre balisage, et donc ses propres
   classes. Écrire un contrat que personne ne signera, c'est du code mort qui a
   l'air d'une intention. */

.form-consent {
  font-size: 0.8rem;
  color: var(--gray-400);
  margin-top: var(--space-3);
  text-align: center;
}

/* --link (6.58:1) plutôt que --navy : dans un paragraphe déjà gris,
   le navy manque d'affordance de lien. */
.form-consent a { color: var(--link-in-grey); text-decoration: underline; }
.form-consent a:hover { color: var(--violet); }

::placeholder { color: var(--gray-400); opacity: 1; }

/* =============================================
   PIED DE PAGE
   ============================================= */

.site-footer {
  background: var(--gradient-footer);
  color: var(--on-navy-body);
  padding: var(--space-16) 0 var(--space-8);
}

.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--space-12); margin-bottom: var(--space-12); }

.footer-brand p { font-size: 0.9rem; line-height: 1.7; color: var(--on-navy-muted); margin-top: var(--space-3); }
.footer-brand a { color: var(--on-navy-muted); }

/* Les survols emploient --on-navy-accent (5.88:1) et non --violet-light,
   qui ne donne que 3.72:1 sur navy - un état de survol reste soumis à l'AA. */
.footer-brand a:hover { color: var(--on-navy-accent); }

.footer-location { margin-top: var(--space-4); font-size: 0.85rem; }

/* Titres de colonnes. Ce sont des <h2> et non des <h4> : après le <h2> de
   la bande d'appel à l'action, un <h4> créait un saut de niveau. */
.footer-col-title {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--on-navy-muted);
  margin-bottom: var(--space-5);
}

.footer-col a { display: block; font-size: 0.9rem; color: var(--on-navy-muted); padding: var(--space-1) 0; }
.footer-col a:hover { color: var(--on-navy-accent); }

.footer-bottom {
  border-top: 1px solid var(--on-navy-border-subtle);
  padding-top: var(--space-6);
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  font-family: var(--font-mono);
}

.footer-bottom a { color: var(--on-navy-muted); }
.footer-bottom a:hover { color: var(--on-navy-accent); }

.footer-legal { display: flex; gap: var(--space-6); flex-wrap: wrap; }

/* =============================================
   RANGÉE DE PRÉSENTATION
   ============================================= */

.feature-row { display: flex; align-items: center; gap: var(--space-16); padding: 60px 0; }
.feature-row.reverse { flex-direction: row-reverse; }
.feature-visual { flex: 1; min-width: 0; }
.feature-content { flex: 1; min-width: 0; }

.feature-lead { font-size: 1.05rem; margin: var(--space-4) 0 var(--space-5); }

/* Ligne de crédibilité sous un titre : une affirmation courte, pas un paragraphe. */
.feature-credential {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--violet);
  letter-spacing: 0.02em;
  border-left: 3px solid var(--violet);
  padding-left: var(--space-3);
  margin-top: var(--space-4);
  margin-bottom: 0;
}

.feature-visual-box {
  background: var(--gradient-surface);
  border-radius: var(--radius);
  padding: var(--space-12);
  text-align: center;
  border: 1px solid var(--gray-200);
  min-height: 320px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 4rem;
}

/* Le conteneur porte font-size: 4rem pour les glyphes décoratifs posés
   directement dedans. Toute carte de contenu doit donc remettre à l'échelle. */
.visual-card { text-align: center; font-size: 1rem; }

/* Panneau de marque CLAIR : pastels navy → violet. Les traits fins du réseau de
   l'icône collectif ressortent sur ce fond, que le dégradé sombre écrasait. La
   carte y garde ses couleurs par défaut (titre navy, sous-titre violet) et le
   wordmark des fonds clairs (assets/wordmark-light.png, classe .brand-word). */
.feature-visual-box--brand {
  background: var(--gradient-panel-soft);
  border-color: var(--pastel-navy);
}

/* LES DEUX EMBLÈMES DE SOUVERAINETÉ. Une seule image pour les deux : ils se lisent
   ensemble - le lieu d'hébergement et le périmètre de conservation - et les séparer
   en deux fichiers aurait laissé leur alignement à la merci du conteneur. */
.emblemes {
  display: block;
  width: 100%;
  max-width: 480px;
  height: auto;
  margin: 0 auto var(--space-8);
}

/* Illustration servie en fichier .svg via <img> : porte un alt, contrairement
   à un <svg> inline. Ses couleurs sont figées, elles ne suivent pas les tokens. */
.feature-figure {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  border: 1px solid var(--gray-200);
  background: var(--white);
}

/* Variante posée à même un fond sombre : le SVG y est transparent. */
.feature-figure--bare { border: none; background: transparent; }

/* Citation d'une source externe. À distinguer d'un témoignage client :
   ici on cite un tiers, pas un client. */
.quote-source {
  max-width: 760px;
  margin: var(--space-12) auto 0;
  padding: var(--space-6) var(--space-8);
  border-left: 4px solid var(--violet);
  background: var(--white);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.quote-source p {
  font-size: 1rem;
  line-height: 1.8;
  color: var(--gray-600);
  font-style: italic;
  margin-bottom: var(--space-3);
}

.quote-source cite {
  font-family: var(--font-heading);
  font-style: normal;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--navy);
}

.visual-card-icon { font-size: 5rem; margin-bottom: var(--space-4); }
.visual-card-icon--md { font-size: 4rem; margin-bottom: var(--space-4); }

.visual-card-title {
  font-family: var(--font-heading);
  font-weight: 700;
  color: var(--navy);
  font-size: 1rem;
  margin: 0;
}

.visual-card-sub { color: var(--violet); }

.visual-card--on-dark { color: var(--white); }
.visual-card--on-dark .visual-card-title { color: var(--white); font-size: 1.2rem; }
/* Sur navy, --violet ne donne que 1.46:1. --on-navy-overline donne 6.97:1. */
.visual-card--on-dark .visual-card-sub { color: var(--on-navy-overline); font-size: 0.9rem; }

/* Le schéma silo/transversal était construit en CSS. Il est désormais servi
   comme fichier assets/silo-transversal.svg, via <img class="feature-figure">,
   afin de porter un attribut alt exploitable. */

/* =============================================
   LISTE À PUCES
   ============================================= */

.checklist { list-style: none; margin: var(--space-5) 0; }

/* Surtout PAS `display: flex` sur le <li>. Il transformait chaque enfant en
   élément flex : dans « <strong>Exploration simultanée</strong> de toutes les
   pistes », le <strong> et le texte qui suit devenaient DEUX éléments, et le
   `gap` s'insérait entre eux. D'où l'espace étrange après chaque terme en gras.
   La puce est donc détachée du flux, en position absolue. */
.checklist li {
  position: relative;
  padding: 3px 0 3px var(--space-6);
  font-size: 0.95rem;
  line-height: 1.6;
}

/* Une bille, pas un glyphe : un caractère aurait sa propre chasse et son propre
   calage vertical, impossibles à centrer proprement.

   Le centrage vertical porte sur la PREMIÈRE ligne, pas sur le bloc : sur une
   puce qui passe à la ligne, la bille doit rester en face du début du texte.

   Attention au piège : une boîte en `position: absolute` se cale sur la
   PADDING-BOX du parent. `top: 0` vise donc le bord du <li>, pas le début du
   texte, qui commence 3 px plus bas (le padding-top). Le calcul doit les ajouter :
     3px (padding) + 0.8em (demi-hauteur de ligne) - 3.5px (rayon de la bille)
   Sans le padding, la bille remonte de 3 px.

   Le +0.5px final est mesuré, pas devine : la demi-hauteur de ligne vise le milieu
   de l'INTERLIGNE, or l'encre du texte n'y est pas centree (les jambages la tirent
   vers le bas). Le rendu montrait la bille 1 px trop haut. */
.checklist li::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(0.8em + 0.5px);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--violet);
}

/* Sur fond sombre, le violet de la bille tombe à 1.46:1 sur --navy-mid : elle
   disparaîtrait. La lavande y tient 4.96:1. Le texte des <li>, lui, hérite
   déjà de --on-navy-body via .band-dark. */
.band-dark .checklist li::before { background: var(--on-navy-accent); }

/* =============================================
   COMPTEURS ET STATISTIQUES
   ============================================= */

.counter-row { display: flex; justify-content: center; gap: var(--space-20); text-align: center; flex-wrap: wrap; }

.counter-item .stat-value {
  font-family: var(--font-heading);
  font-size: 3rem;
  font-weight: 900;
  background: var(--gradient-brand-text);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.counter-item .stat-label {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--gray-400);
  margin-top: var(--space-1);
}

/* Les grands chiffres d'engagement étaient composés en CSS. Ils sont désormais
   servis par assets/engagement-gallup.svg, qui porte un attribut alt exploitable.
   Les tokens --on-navy-stat-* restent la référence des couleurs de ce SVG :
   toute modification du fichier doit reprendre leurs valeurs. */

/* p.stat-caption : porte le même poids (0,1,1) que .band-dark p, et le
   suit dans la feuille - sans le sélecteur de type, la couleur serait écrasée. */
p.stat-caption {
  text-align: center;
  color: var(--on-navy-muted);
  margin: var(--space-10) auto 0;
  max-width: 600px;
}

.stat-caption strong { color: var(--on-navy-body); }

/* Encart de note statistique sous une grille sombre */
.stat-note {
  text-align: center;
  margin-top: var(--space-12);
  padding-top: var(--space-10);
  border-top: 1px solid var(--on-navy-divider);
}

.stat-note p { color: var(--on-navy-muted); font-size: 0.9rem; font-family: var(--font-heading); }

/* Les deux chiffres reprennent EXACTEMENT les couleurs des barres du graphe
   (assets/engagement-gallup.svg) : la prune du 8 % France, l'émeraude du 70 %.
   La phrase est ainsi lisible comme une légende du graphe.

   LA TAILLE EST CE QUI REND LA PRUNE EMPLOYABLE, et non un choix d'esthétique.
   1.2rem en graisse 700 font 19.2px gras, donc « texte large » au sens WCAG : le
   seuil tombe à 3:1, et la prune passe avec ses 3.72:1 sur --navy-mid. À la taille
   du reste de la phrase (0.9rem), elle relèverait du texte courant, où le seuil est
   de 4.5:1 : elle échouerait. NE PAS LES RÉDUIRE.

   Seul le CHIFFRE est coloré, jamais le libellé qui suit. C'est exactement ce que
   fait le SVG, où « France » est en gris et le « 8 % » en prune. */
.stat-inline-low,
.stat-inline-high { font-size: 1.2rem; }

.stat-inline-low { color: var(--on-navy-stat-plum); }  /* 3.72:1 sur navy-mid - TEXTE LARGE */
.stat-inline-high { color: var(--on-navy-stat-high); } /* 5.87:1 sur navy-mid */

/* =============================================
   TUILES DE VALEUR
   ============================================= */

.value-tile { padding: var(--space-6) 0; }
.value-tile--center { text-align: center; padding: var(--space-6) var(--space-4); }

.value-tile-icon { font-size: 1.6rem; margin-bottom: var(--space-3); }
.value-tile-icon--lg { font-size: 2.2rem; margin-bottom: var(--space-3); }

.value-tile h3 { color: var(--on-navy-title); margin-bottom: var(--space-2); font-size: 1.1rem; }
.value-tile--center h3 { font-size: 1rem; }
/* Même raison : .value-tile-icon est un <div> ici, un paragraphe dans WordPress. */
.value-tile p:where(:not(.value-tile-icon)) { color: var(--on-navy-muted); font-size: 0.9rem; }
.value-tile--center p { font-size: 0.85rem; }

/* =============================================
   PANNEAUX
   ============================================= */

.panel {
  background: var(--white);
  border-radius: var(--radius);
  padding: var(--space-10);
  border: 1px solid var(--gray-200);
  text-align: center;
}

.panel h3 { margin-bottom: var(--space-4); }
.panel p { max-width: 640px; margin: 0 auto; color: var(--gray-600); }

/* Un .panel garde son fond blanc à l'intérieur d'une section sombre. Sans ces
   trois règles, la cascade de .band-dark y repeindrait le texte en blanc :
   `.band-dark h3` et `.band-dark h3` ont la même spécificité que
   `.panel h3`, et le second perdrait à l'ordre d'apparition. On qualifie donc,
   plutôt que de forcer. Ratios sur blanc : navy 12.03:1, gray-600 7.04:1,
   link 6.58:1. */
.band-dark .panel h3 { color: var(--navy); }
.band-dark .panel p { color: var(--gray-600); }
/* LE PANNEAU EST UNE ÎLE CLAIRE DANS UNE SECTION SOMBRE, et ses liens doivent suivre
   la règle du fond CLAIR - sans quoi « .band-dark a:not(.btn) » leur donnerait la
   couleur du fond sombre, illisible sur ce blanc.

   Le sauvetage se faisait avec --link, et c'était le mauvais bleu : --link est réservé
   aux textes DÉJÀ GRIS, où le navy manque d'affordance (CLAUDE.md §3). Le texte du
   panneau n'est pas gris. On obtenait donc un lien bleu vif au milieu d'une page dont
   tous les autres liens de corps sont navy. C'est --navy qu'il faut, comme partout
   ailleurs sur fond clair : 12.03:1 sur blanc. */
.band-dark .panel a:not(.btn) { color: var(--navy); }

.panel--sm { padding: var(--space-8); text-align: left; }

/* PANNEAU DE MARQUE : LE PANNEAU BLANC DISPARAISSAIT SUR SECTION BLANCHE.

   .panel est blanc bordé de gris ; posé sur .section (blanc lui aussi), il ne se
   détachait plus - seul son filet le signalait. Cette variante lui donne l'aplat
   PASTEL VIOLET de la charte (#E2DAF0, aplat only), le même que la ligne mise en
   avant du tableau comparatif : sur cette page, tout ce qui parle de pylotik porte
   la même teinte, et c'est ce qui en fait un repère plutôt qu'une décoration.

   Le gradient --gradient-panel-soft a été écarté, et pour une raison mesurée : son
   premier arrêt est le pastel navy #D4D9EC, sur lequel --gray-600 (la couleur de
   .panel p) ne donne que 4.44:1 - sous le seuil AA de 4,5:1. Sur le pastel violet
   seul, les trois encres du panneau passent : gris 4.62:1, navy 8.89:1, lien 4.87:1.
   Un aplat plat vaut mieux qu'un dégradé dont une extrémité échoue. */
.panel--brand {
  background: var(--pastel-violet);
  border-color: var(--pastel-navy);
}

/* LE MOT DE MARQUE pylotik AU FIL DU TEXTE.

   Le wordmark composé (trois segments colorés) ne peut pas être du texte : il faudrait
   trois <span> imbriqués, et Gutenberg n'en conserve aucun. C'est donc une IMAGE, comme
   celui d'orgatypik - mais posée EN LIGNE, à la taille du texte qui l'entoure, et non
   en logotype de bloc (.brand-word, qui est fixe à 1.386rem).

   Deux fichiers, et le choix se fait par le FOND, jamais par le CSS : -light sur fond
   clair, -dark sur fond sombre. Un background-image aurait permis de basculer par
   sélecteur de contexte, mais le mot de marque est du TEXTE au sens du lecteur d'écran :
   il lui faut un alt, donc un <img>. C'est l'inverse du choix fait pour les icônes, et
   pour la raison inverse - elles sont décoratives, lui ne l'est pas.

   Sans point final : le point appartient au logotype composé, pas à la marque citée dans
   une phrase, où il se lirait comme une fin de phrase (convention pylotik).

   1.05em et non 1em : la hauteur du fichier couvre l'ascendante ET la descendante du
   « p », là où la capitale d'une police n'occupe qu'une part du cadratin. Sans cette
   correction le mot paraissait rétréci au milieu du texte. Le décalage de baseline
   compense la descendante.

   Contraste : aucune exigence. WCAG 1.4.3 exempte explicitement « le texte qui fait
   partie d'un logo ou d'un nom de marque ». Pour mémoire, les valeurs mesurées : sur
   blanc, segment bleu 9.64:1 et terracotta 4.31:1 ; sur --navy-mid (le stop le plus
   clair de nos fonds sombres), la variante sombre donne 3.29:1 sur ses trois segments. */
.wm-pylotik {
  display: inline-block;
  height: 1.05em;
  width: auto;
  vertical-align: -0.19em;
}

/* DANS UN TITRE, LE MOT DE MARQUE MONTE D'UN CRAN.

   La hauteur est en em, donc il suit déjà la taille du titre. Mais un logotype composé
   paraît plus petit qu'un texte de même corps : sa hauteur d'x est basse et ses lettres
   sont bas-de-casse, là où un titre aligne des capitales. À 1.05em il se lisait comme un
   mot en retrait au milieu de son propre titre. 1.45em le remet au niveau de ce qui
   l'entoure. Le décalage de baseline suit la même proportion. */
h1 .wm-pylotik {
  /* EN BLOC, ET C'EST CE QUI LUI DONNE DE L'AIR. Une image en ligne ne peut pas
     écarter les lignes : ses marges verticales n'entrent pas dans le calcul de la
     hauteur de ligne, seuls line-height et vertical-align y entrent. Le mot de marque
     se retrouvait donc collé au titre qui le suit, jambe du « p » contre capitale.
     Passé en bloc, il crée sa propre ligne et sa marge s'applique enfin. Le <br> qui
     le suivait dans le markup devient inutile, et il a été retiré. */
  display: block;
  height: 1.45em;
  width: auto;
  margin: 0 auto var(--space-5);
}
.panel--sm h3 { margin-bottom: var(--space-4); font-size: 1rem; }

/* Panneau d'appel à candidature, bordure pointillée */
.callout-panel {
  text-align: center;
  margin-top: var(--space-12);
  padding: var(--space-10);
  background: var(--surface-accent-soft);
  border-radius: var(--radius);
  border: 1px dashed var(--violet);
}

.callout-panel p { color: var(--gray-600); max-width: 500px; margin: 0 auto var(--space-5); }

/* Encarts latéraux de la page contact */
.info-panel {
  background: var(--off-white);
  border-radius: var(--radius);
  padding: var(--space-8);
  margin-bottom: var(--space-8);
  border: 1px solid var(--gray-200);
}

.info-panel h3 { margin-bottom: var(--space-5); }

.info-panel--dark {
  background: var(--gradient-panel-dark);
  border: none;
  color: var(--white);
}

.info-panel--dark h3 { color: var(--white); margin-bottom: var(--space-4); }
.info-panel--dark p { color: var(--on-navy-body); font-size: 0.9rem; margin: 0; }
.info-panel--dark a { color: var(--on-navy-overline); font-weight: 600; }
.info-panel--dark a:hover { color: var(--white); }

.info-panel--accent {
  background: var(--surface-accent-soft);
  border: 1px solid var(--border-accent-soft);
  padding: var(--space-6);
}

.info-panel--accent h3 { color: var(--violet); margin-bottom: var(--space-3); font-size: 1rem; }
.info-panel--accent p { font-size: 0.9rem; color: var(--gray-600); margin: 0; }

.info-field { margin-bottom: var(--space-4); }
.info-field:last-child { margin-bottom: 0; }

.info-field-label {
  font-family: var(--font-heading);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--on-navy-muted);
  text-transform: uppercase;
  margin-bottom: var(--space-1);
}

.info-note { color: var(--on-navy-muted); font-size: 0.85rem; }

/* Sous-cartes d'une grille de présentation */
.mini-card h3 { font-size: 1rem; margin-bottom: var(--space-2); }
.mini-card p { font-size: 0.9rem; color: var(--gray-600); }

/* Titre précédé d'un glyphe */
.h-icon { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-6); }

/* Le glyphe est enfermé dans une boîte de taille FIXE, avec line-height: 1.
   Sans cela, deux titres côte à côte ne s'alignent pas : les glyphes sont rendus
   par des polices différentes (⚡ est un symbole texte, 🧠 un emoji), aux métriques
   différentes. Le <h3> le plus haut voyait alors son texte descendre, puisque
   .h-icon centre verticalement. La boîte fixe rend les deux titres identiques. */
.h-icon-glyph {
  font-size: 2rem;
  line-height: 1;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* =============================================
   ÉTUDES DE CAS
   ============================================= */

.case-study {
  background: var(--white);
  border-radius: var(--radius);
  padding: var(--space-12);
  margin-bottom: var(--space-8);
  border: 1px solid var(--gray-200);
}

.case-study:last-child { margin-bottom: 0; }
.case-study h3 { margin-bottom: var(--space-4); }
.case-study p { font-size: 0.95rem; color: var(--gray-600); }
.case-study .tag-row { margin-top: 0; margin-bottom: var(--space-6); align-items: center; }

.case-label { color: var(--violet); margin-bottom: var(--space-3); }
.case-label--spaced { margin-top: var(--space-5); }
.case-label--result { color: var(--navy); margin-bottom: var(--space-3); }

/* =============================================
   PAGES LÉGALES

   Contenu rédactionnel long, une seule colonne. Les liens y sont en --link
   plutôt qu'en --navy : dans un texte dense, le navy se confond avec les
   titres et perd son affordance de lien.
   ============================================= */

.prose { max-width: 760px; margin: 0 auto; }
.prose h2 { font-size: clamp(1.4rem, 2.4vw, 1.8rem); margin: var(--space-12) 0 var(--space-4); }
.prose h2:first-of-type { margin-top: 0; }
.prose h3 { font-size: 1.05rem; margin: var(--space-6) 0 var(--space-3); }
.prose p { color: var(--gray-600); }
.prose a { color: var(--link-in-grey); text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--violet); }

.prose ul { list-style: none; margin: var(--space-4) 0; }

.prose ul li {
  padding: var(--space-2) 0 var(--space-2) var(--space-6);
  position: relative;
  margin-bottom: 0;
  color: var(--gray-600);
  font-size: 0.95rem;
}

/* Même bille que .checklist, pour ne pas avoir deux puces différentes dans le
   site. Le `top` diffère parce que le padding diffère : ici 8px (--space-2), là
   3px. Il vaut padding + demi-hauteur de ligne - rayon, plus la correction de
   0.5px mesurée au rendu (l'encre n'est pas centrée dans l'interligne). */
.prose ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(8px + 0.85em - 3px);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--violet);
}

/* Le sélecteur porte le type `p` et le contexte : `.hero-page p` a une
   spécificité supérieure à `.legal-updated` seul, et lui imposait sa
   font-size de 1.15rem ainsi que sa couleur. On qualifie, on ne force pas.
   --gradient-hero-page se termine sur --navy : c'est ce stop qui contraint.
   --on-navy-muted y donne 5.37:1, au-delà du seuil AA de 4.5:1 exigé par
   ce texte de 0.72rem. */
.page-hero p.updated {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--on-navy-muted);
  margin-top: var(--space-4);
}

/* Champ juridique restant à renseigner. Volontairement voyant : aucune de ces
   pages ne doit partir en production tant qu'il en subsiste un seul. */
.legal-todo {
  font-family: var(--font-mono);
  font-size: 0.85em;
  font-weight: 600;
  color: var(--attention);
  background: var(--surface-attention);
  border-bottom: 1px dashed var(--attention);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
}

/* =============================================
   PASTILLES
   ============================================= */

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.tag-navy { background: var(--surface-tint-navy); color: var(--navy); }
.tag-violet { background: var(--surface-tint-violet); color: var(--violet); }

/* =============================================
   RESPONSIVE
   ============================================= */

@media (max-width: 960px) {
  /* PAS D'ILLUSTRATION SOUS 960px. Elle est composée pour occuper la DROITE d'un hero
     large, le texte tenant à gauche. Sur un écran étroit, le hero se resserre et
     s'allonge : l'image, dont la largeur suit la hauteur, finit par le couvrir
     entièrement et passe sous le titre - elle cesse d'être un décor pour devenir du
     bruit. 960px et non 600 : c'est là que la navigation passe au burger, donc là que
     le site entre en mode mobile.

     Le voile reste : posé sur le dégradé de fond, il redonne exactement le dégradé nu.
     Le hero retrouve donc son rendu d'avant les Bannières, sans règle de rattrapage. */
  .hero--visuel::after { display: none; }

  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
  .feature-row, .feature-row.reverse { flex-direction: column; gap: var(--space-10); }
  .hero-stats { flex-wrap: wrap; gap: var(--space-8); }
  .counter-row { gap: var(--space-10); }
  .method-step { flex-direction: column; gap: var(--space-4); }
  .step-number { width: auto; font-size: 2.5rem; text-align: left; }

  .nav-desktop { display: none; }
  .nav-disclosure { display: block; }

  /* Deux cartes par rangée : le max-width passe à une demie largeur. */
  .pain-card { max-width: calc((100% - var(--space-5)) / 2); }
}

@media (max-width: 600px) {
  /* La baseline « Performance opérationnelle & organisationnelle » débordait sur deux
     ou trois lignes sous le wordmark, cassant la hauteur fixe de l'en-tête : le symbole
     et le wordmark suffisent sur mobile. */
  .logo-tagline { display: none; }
  .hero-home { padding: 130px 0 var(--space-20); }
  .page-hero { padding: 120px 0 var(--space-16); }
  /* Le min du clamp (2.2rem = 35px) était trop grand sur un téléphone étroit, surtout
     avec un mot long. On le ramène à 1.9rem sous 600px. */
  h1 { font-size: 1.9rem; }
  .section { padding: var(--space-16) 0; }
  .section-head { margin-bottom: var(--space-10); }
  .pain-card { max-width: 100%; }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-bottom { flex-direction: column; gap: var(--space-2); }
  .case-study { padding: var(--space-8) var(--space-6); }
  .feature-visual-box { padding: var(--space-8); min-height: 260px; }
  .counter-row { gap: var(--space-8); }
}

/* =============================================
   ACCORDÉON (details.faq-item du socle)

   Le socle dessine une carte à chevron ; orgatypik garde sa liste à filets et son
   « + » qui pivote en croix.
   ============================================= */

.faq-item { background: none; border: 0; border-bottom: 1px solid var(--gray-200); border-radius: 0; padding: 0; margin: 0; }
.section-alt .faq-item { background: none; }
.faq-item > summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-6) 0;
  font-family: var(--font-heading);
  font-size: 1.05rem;
  color: var(--navy);
}
.faq-item > summary::after {
  content: '+';
  position: static;
  width: auto;
  height: auto;
  border: 0;
  transform: none;
  font-size: 1.4rem;
  font-weight: 300;
  line-height: 1;
  color: var(--violet);
  flex-shrink: 0;
  transition: var(--transition);
}
.faq-item[open] > summary::after { transform: rotate(45deg); }
.faq-item > p, .faq-item > div {
  margin: 0;
  padding: 0 0 var(--space-6);
  color: var(--gray-600);
  line-height: 1.8;
  font-size: 0.95rem;
}

/* Listes : la bille d'orgatypik, et non le carré du socle. */
.checklist { display: block; }
.checklist li { color: inherit; }

/* =============================================
   AJUSTEMENTS AU SOCLE

   L'en-tête n'est plus fixe : les héros perdent la hauteur qu'ils lui réservaient
   (écart admis du chantier). Le pied garde ses liens serrés et sa colonne de marque
   pleine largeur.
   ============================================= */

.hero-home { padding-top: calc(160px - var(--header-height)); }
.page-hero { padding-top: calc(140px - var(--header-height)); }
@media (max-width: 600px) {
  .hero-home { padding-top: calc(130px - var(--header-height)); }
  .page-hero { padding-top: calc(120px - var(--header-height)); }
}
.footer-col { gap: 0; }
.footer-brand p { max-width: none; }
/* Le socle pose le terme gras d'une liste sur sa propre ligne (pylotik) ; orgatypik
   le garde en tête de phrase. */
.checklist strong { display: inline; margin: 0; font-family: inherit; color: inherit; }
/* Le champ du socle est une grille à gouttière ; orgatypik espace son libellé par sa
   marge, comme avant. */
.field { display: block; }
/* L'en-tête de tableau du socle est en capitales mono (pylotik) ; orgatypik garde son
   titre de colonne en Montserrat, sur l'aplat pastel. Même spécificité que la règle du
   socle (0,1,2), placée après elle. */
.table thead th {
  font-family: var(--font-heading);
  font-size: inherit;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  color: var(--navy);
  border-bottom: none;
}

/* Le mot-marque pylotik sur les fonds sombres propres à orgatypik : le socle couvre
   .hero, .page-hero, .band-dark et .site-footer ; la bande d'appel en est un aussi.
   Dans un bouton blanc, il reprend les teintes des fonds clairs. */
.cta-band .wm-p {
  color: var(--wm-pylot-on-navy);
  background-image: linear-gradient(90deg, var(--wm-pylot-on-navy) var(--wm-cut), var(--wm-ik-on-navy) var(--wm-cut));
}
.cta-band .wm-p .dot { color: var(--wm-pylotik-dot-on-navy); -webkit-text-fill-color: var(--wm-pylotik-dot-on-navy); }
.btn-white .wm-p, .cta-band .btn-white .wm-p {
  color: var(--wm-pylot);
  background-image: linear-gradient(90deg, var(--wm-pylot) var(--wm-cut), var(--wm-ik) var(--wm-cut));
}

/* =============================================
   BLOG : L'ARTICLE ET LA LISTE (chantier sites-web, lot 6)

   Les pages sont générées par outils/blog/generer-articles.py depuis
   orgatypik/articles/ et le gabarit _gabarits/article.html. Ces règles reprennent
   l'article du thème WordPress (single.html, .article-body) : hero sombre centré
   (date, titre, auteur, catégories), image à la une à la largeur de lecture, puis le
   corps, du HTML nu écrit en Markdown, qu'on habille ici faute de composant.
   ============================================= */

/* Dans le hero : la date en surtitre, l'auteur en signature, les catégories en
   pastilles (sans lien : les archives de catégorie n'existent plus). Teintes on-navy,
   le fond est sombre. (0,2,0) : bat « .page-hero p:where(…) ». */
.article-hero .article-date {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--on-navy-overline);
  margin: 0 auto var(--space-4);
}
.article-hero h1 { max-width: 900px; margin-left: auto; margin-right: auto; }
.article-hero .article-auteur {
  font-size: 0.9rem;
  color: var(--on-navy-muted);
  margin-top: var(--space-3);
}
.article-categories {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  list-style: none;
  padding: 0;
}
.article-categories li {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--on-navy-accent);
  background: var(--on-navy-badge-bg);
  border: 1px solid var(--on-navy-badge-border);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
}

/* L'image à la une et le corps partagent la colonne de lecture, avec des gouttières
   sur mobile (sans elles, le texte touchait les deux bords). */
.article-couverture,
.article-corps {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--space-6);
  padding-right: var(--space-6);
}
.article-couverture { margin-top: var(--space-12); }
.article-couverture img { display: block; width: 100%; height: auto; border-radius: var(--radius); }
.article-corps { padding-top: var(--space-10); padding-bottom: var(--space-16); }

.article-corps > * + * { margin-top: var(--space-6); }
.article-corps h2 { margin-top: var(--space-14); }
.article-corps h3 { margin-top: var(--space-10); }
.article-corps h2 + *, .article-corps h3 + *, .article-corps h4 + * { margin-top: var(--space-4); }
.article-corps a { text-decoration: underline; text-underline-offset: 2px; }

/* Les listes : billes de la charte sur les <ul>, retrait rendu aux <ol>. */
.article-corps ul { list-style: none; padding-left: 0; }
.article-corps ul > li { position: relative; padding-left: var(--space-6); }
.article-corps ul > li::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(0.8em - 2.5px);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--violet);
}
.article-corps ol { padding-left: var(--space-6); }
.article-corps li { line-height: 1.6; }
.article-corps li + li { margin-top: var(--space-2); }
.article-corps li > ul, .article-corps li > ol, .article-corps li > p + * { margin-top: var(--space-2); }

/* La citation, et l'encadré à fond (une citation d'habit différent, écrite
   <blockquote class="encadre"> : c'était le bloc Citation à fond coloré de l'éditeur). */
.article-corps blockquote {
  border-left: 3px solid var(--violet);
  padding-left: var(--space-5);
  color: var(--text-soft);
}
.article-corps blockquote.encadre {
  border-left: none;
  background: var(--surface-tint-violet);
  border-radius: var(--radius);
  padding: var(--space-6);
  color: var(--text);
}
.article-corps blockquote > * + * { margin-top: var(--space-4); }
.article-corps blockquote > :first-child { margin-top: 0; }

/* La mise en valeur colorée de l'éditeur : une couleur, pas un surligneur. */
.article-corps mark { background: none; color: inherit; }
.article-corps mark.accent { color: var(--violet); font-weight: 600; }

.article-corps hr { border: none; border-top: 1px solid var(--gray-200); }
/* Les tableaux d'article, à l'habit qu'ils avaient sous WordPress (.article-body
   .wp-block-table du thème) : en-tête en aplat pastel, zébrage discret, coins
   arrondis, et AUCUNE ligne mise en évidence. */
.tableau-article { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.tableau-article th {
  font-family: var(--font-heading);
  font-weight: 500;
  text-align: left;
  padding: var(--space-3) var(--space-5);
  background: var(--surface-table-head);
  color: var(--navy);
}
.tableau-article th:first-child { border-radius: var(--radius-md) 0 0 0; }
.tableau-article th:last-child { border-radius: 0 var(--radius-md) 0 0; }
.tableau-article td { padding: 14px var(--space-5); border-bottom: 1px solid var(--gray-200); vertical-align: top; }
.tableau-article tbody tr:last-child td { border-bottom: none; }
.tableau-article tbody tr:nth-child(even) td { background: var(--off-white); }

/* La liste du blog : des cartes à vignette, d'une hauteur commune par rangée. */
.blog-intro p + p { margin-top: var(--space-4); }
.article-liste { list-style: none; padding: 0; }
.article-liste > li { display: flex; }
.article-carte { flex: 1; display: flex; flex-direction: column; }
.article-carte img { display: block; width: 100%; height: 200px; object-fit: cover; }
.article-carte .card-body { flex: 1; }
.article-carte .article-carte-date {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-soft);
}
.article-carte h3 { font-size: 1.05rem; line-height: 1.35; }
.article-carte h3 a { color: var(--text-title); text-decoration: none; }
.article-carte h3 a:hover { color: var(--violet); }
