/* Copie générée par outils/qualite/generer-blocs.py depuis
   commun/css/ (01-base.css, 02-mise-en-page.css, 03-entete.css, 04-boutons.css, 05-cartes.css, 06-chiffres.css, 07-tableau.css, 08-bandeau-sombre.css, 09-listes.css, 10-encadre.css, 11-formulaire.css, 12-pages-texte.css, 13-appel-final.css, 14-pied.css, 15-accessibilite.css, 16-fil-ariane.css, 17-icones-et-survols.css, 18-mots-de-marque.css).
   Ne pas modifier ici : modifier la source dans commun/, puis relancer. */
/* =============================================
   BASE
   ============================================= */

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

/* scroll-padding-top : quand on saute à une ancre (#categorie, #pilier...), la
   cible ne doit pas se loger SOUS l'en-tête collant. On réserve la hauteur du
   header. Sans quoi le titre visé disparaît derrière la barre fixe. */
html { scroll-behavior: smooth; font-size: 16px; scroll-padding-top: 5rem; }

body {
  font-family: var(--font-body);
  color: var(--text);
  background: var(--shell);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  /* Garde-fou global : aucune page ne défile horizontalement. Les tableaux et
     les schémas larges défilent DANS leur propre conteneur (.scroll-x). */
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--text-title);
  line-height: var(--heading-leading);
  /* Un mot ne déborde jamais du viewport. overflow-wrap ne coupe un mot QUE
     s'il est trop long pour tenir seul sur une ligne. Pas de hyphens: auto. */
  overflow-wrap: break-word;
}

h1 { font-size: var(--h1-size); font-weight: var(--h1-weight); letter-spacing: var(--h1-tracking); }
h2 { font-size: var(--h2-size); font-weight: 700; letter-spacing: var(--h2-tracking); }
h3 { font-size: var(--h3-size); font-weight: var(--h3-weight); }
h4 { font-size: 1.05rem; font-weight: 600; }

p { margin-bottom: var(--space-4); }
p:last-child { margin-bottom: 0; }

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

/* Liens DANS LE TEXTE COURANT : non soulignés, ils ne se distinguent du texte que
   par le terracotta. La graisse ajoute un repère NON coloré (WCAG 1.4.1, « ne pas
   reposer sur la couleur seule »). La couleur de la charte #CC5500 reste inchangée.
   Wordmarks et boutons exclus : ils portent déjà leur propre graisse et sont déjà
   identifiables autrement. La graisse est un rôle (--link-weight) : orgatypik, dont le
   lien navy se distingue sans elle, la laisse au texte. Les exclusions sont sous
   :where(), à spécificité nulle : la règle pèse (0,0,3), et la feuille d'une marque
   reprend la main sur un lien de composant sans surenchère de sélecteurs. */
main p a:where(:not(.btn):not([class*="wm-"])),
main li a:where(:not(.btn):not([class*="wm-"])),
main td a:where(:not(.btn):not([class*="wm-"])) { font-weight: var(--link-weight); }

strong { color: var(--strong-color); font-weight: var(--strong-weight); }
img { max-width: 100%; height: auto; }

:focus-visible {
  outline: 2px solid var(--interact);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}
/* Sur un fond navy (héros, bandeaux) et sur le pied de page, le navy ne se voit
   plus : le repère passe au bleu éclairci, 6.4:1 sur le navy, dans les deux
   thèmes (charte V3.1 : les repères d'interaction sont le primary). */
.hero :focus-visible, .page-hero :focus-visible, .band-dark :focus-visible, footer :focus-visible { outline-color: var(--interact-on-navy); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
/* =============================================
   MISE EN PAGE
   ============================================= */

.container { max-width: var(--max-width); margin: 0 auto; padding: 0 var(--space-6); }
.narrow { max-width: 780px; margin-left: auto; margin-right: auto; }
.section { padding: var(--section-pad-y) 0; }
.section-sm { padding: var(--space-12) 0; }
.section-alt { background: var(--section-alt-bg); }

.section-head { max-width: var(--section-head-width); margin-bottom: var(--section-head-gap); }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head p { color: var(--text-soft); font-size: 1.08rem; margin-top: var(--space-4); }

/* Surtitre monospace : le libellé de section de la charte (JetBrains Mono,
   lettrage espacé, majuscules). */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--eyebrow-size);
  font-weight: var(--eyebrow-weight);
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--accent);
  display: block;
  margin-bottom: var(--space-3);
}
.eyebrow.muted { color: var(--text-soft); }
/* Surtitre logé DANS le h1 de l'accueil (octobre 2026), pour que la catégorie
   « logiciel de pilotage opérationnel » fasse partie du titre lu par les moteurs.
   Il héritait de l'interlignage serré du titre : on lui rend celui du texte. */
h1 > .eyebrow { line-height: 1.7; }
/* Les ancres atterrissent sous l'en-tête collant (68 px) et le fil d'Ariane. */
section[id] { scroll-margin-top: 120px; }

/* Conteneur de défilement pour les contenus larges (tableaux, schémas). */
.scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.lead { font-size: 1.14rem; color: var(--text-soft); }

/* Note de bas de section : source, méthode, réserve. */
.note {
  font-size: 0.88rem;
  color: var(--text-soft);
  margin-top: var(--space-6);
}

/* Une phrase qui énumère deux cas symétriques est une LISTE, pas un paragraphe
   à virgules : la mettre en <ul> lui rend sa structure, et un lecteur d'écran
   annonce alors « liste de deux éléments ». La puce est dessinée plutôt
   qu'héritée, pour qu'elle prenne l'accent sans coloriser le texte. */
.note-list {
  list-style: none;
  margin-top: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.note-list li { position: relative; padding-left: var(--space-4); }
.note-list li::before {
  content: '';
  position: absolute;
  left: 0;
  /* Centré sur la hauteur de la première ligne, pas du <li> : sur un élément
     qui passe à la ligne, une puce centrée sur le bloc descendrait au milieu. */
  top: calc(0.88rem * 1.7 / 2);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-flat);
  transform: translateY(-50%);
}
.note-source {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-soft);
  letter-spacing: 0.02em;
}
/* =============================================
   EN-TÊTE & NAVIGATION
   ============================================= */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--header-bg);
  border-bottom: 1px solid var(--line);
}

.nav-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--space-6);
  height: var(--header-height);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
}

.nav-brand { display: flex; align-items: center; gap: var(--space-3); }
.nav-brand .logo { display: flex; align-items: center; gap: var(--space-3); }
/* line-height: 1 sur le mot de marque et sur la baseline : hérité du corps
   (1.7), leur talon les décentrait tous deux par rapport au symbole, qui n'en a
   pas. C'est la boîte de ligne qu'on aligne, pas les lettres. */
/* Le symbole a quitté l'en-tête : le mot de marque y suffit, et le bloc respire.
   Il reste au pied de page, posé au-dessus du mot. */
.nav-brand .logo-word { height: 25px; width: auto; display: block; }

/* La baseline flottait : son filet séparateur ne faisait que la hauteur du texte,
   soit un onzième de la hauteur du logo, ce qui donnait un tiret perdu entre les
   deux plutôt qu'une séparation. Le filet prend donc la hauteur du bloc de
   texte, et les deux lignes se centrent dedans.

   Deux lignes, et non une phrase repliée au hasard de la largeur : la coupure
   est portée par deux <span>, donc elle tombe toujours au même endroit, entre
   ce que fait le produit et ce sur quoi il le fait. */
.nav-tagline {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 30px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  line-height: 1.35;
  color: var(--text-soft);
  border-left: 1px solid var(--line);
  padding-left: var(--space-4);
  /* Correction optique vers le haut. Le mot de marque descend plus bas qu'il ne
     monte, à cause des jambages du « p » et du « y » : centré sur sa boîte, la
     baseline tombe sous le corps des lettres, qui est ce que l'œil prend pour la
     ligne médiane. Un pixel suffit ici, le bloc étant plus haut qu'avant. */
  transform: translateY(-1px);
}

.nav-desktop { display: flex; align-items: center; gap: var(--space-6); }
/* Écart entre les entrées porté à 1,75 rem (1,25 avant) : les chevrons des
   sous-menus tassaient la barre (Charley, 23/10/2026). */
.nav-links { display: flex; gap: var(--space-7); list-style: none; }
.nav-links a {
  position: relative;
  color: var(--nav-link-color);
  font-family: var(--nav-link-font);
  font-size: var(--nav-link-size);
  font-weight: var(--nav-link-weight);
  padding-bottom: 4px;
}
.nav-links a:hover { color: var(--accent); }
.nav-links a.active { color: var(--text-title); }

/* Le filet se déploie de la droite vers la gauche au survol. Il est animé en
   scaleX plutôt qu'en largeur : une transition de `width` recalcule la mise en
   page à chaque image, un `transform` non. transform-origin donne le sens. */
.nav-links a::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--accent-flat);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--transition);
}
.nav-links a:hover::after, .nav-links a.active::after { transform: scaleX(1); }
/* La page courante garde son filet, sans animation d'entrée. */
.nav-links a.active::after { transition: none; }

/* Sous-menus Produit, Solutions, Ressources (octobre 2026). Des <details> et
   aucun JavaScript, comme le menu mobile : l'état ouvert ou fermé est porté par
   le DOM et annoncé tel quel aux lecteurs d'écran. L'attribut name les rend
   exclusifs : en ouvrir un referme l'autre. Revers assumé, faute de script : un
   clic ailleurs ne referme pas le panneau ; un second clic sur le titre, si.
   Les liens du panneau sont des liens « nus » : generer-blocs.py les marque comme
   ceux de la barre, et le titre du sous-menu qui contient la page courante prend
   le même filet que le lien actif. */
.nav-links > li { display: flex; align-items: center; }
.nav-sub { position: relative; }
.nav-sub > summary {
  list-style: none;
  cursor: pointer;
  color: var(--nav-link-color);
  font-family: var(--nav-link-font);
  font-size: var(--nav-link-size);
  font-weight: var(--nav-link-weight);
  padding-bottom: 4px;
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  position: relative;
}
.nav-sub > summary::-webkit-details-marker { display: none; }
.nav-sub > summary::before {
  content: '';
  order: 2;
  width: 0.38em; height: 0.38em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.12em) rotate(45deg);
  transition: transform var(--transition);
}
.nav-sub[open] > summary::before { transform: translateY(0.08em) rotate(-135deg); }
.nav-sub > summary:hover, .nav-sub[open] > summary { color: var(--accent); }
.nav-sub > summary::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--accent-flat);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--transition);
}
.nav-sub > summary:hover::after, .nav-sub[open] > summary::after { transform: scaleX(1); }
.nav-sub:has(a[aria-current]) > summary { color: var(--text-title); }
.nav-sub:has(a[aria-current]) > summary::after { transform: scaleX(1); transition: none; }
.nav-sub-panel {
  position: absolute;
  left: calc(-1 * var(--space-3));
  top: calc(100% + 18px);
  z-index: 60;
  min-width: 260px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-links .nav-sub-panel a {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}
.nav-links .nav-sub-panel a::after { content: none; }
.nav-links .nav-sub-panel a:hover { background: var(--surface-alt); color: var(--accent); }
.nav-links .nav-sub-panel a.active { color: var(--text-title); font-weight: 600; }
.nav-sub-tag {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  color: var(--text-soft);
  margin-left: var(--space-2);
}

/* Menu mobile en <details> : aucun JavaScript, l'état est porté par le DOM. */
.nav-disclosure { display: none; position: relative; }
.nav-burger { list-style: none; cursor: pointer; padding: var(--space-2); }
.nav-burger::-webkit-details-marker { display: none; }
.nav-burger-icon, .nav-burger-icon::before, .nav-burger-icon::after {
  display: block;
  width: 22px; height: 2px;
  background: var(--text-title);
  border-radius: 2px;
}
.nav-burger-icon { position: relative; }
.nav-burger-icon::before, .nav-burger-icon::after { content: ''; position: absolute; }
.nav-burger-icon::before { top: -7px; }
.nav-burger-icon::after { top: 7px; }

.nav-panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-3));
  min-width: 240px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.nav-panel a {
  color: var(--text);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
}
.nav-panel a:hover { background: var(--surface-alt); color: var(--accent); }
.nav-panel a.active { color: var(--text-title); font-weight: 600; }
/* Le panneau mobile porte désormais une vingtaine d'entrées : il défile au lieu
   de sortir de l'écran, et Solutions comme Ressources s'y replient. */
.nav-panel { max-height: calc(100vh - 90px); overflow-y: auto; }
.nav-panel-group > summary {
  list-style: none;
  cursor: pointer;
  color: var(--text);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.nav-panel-group > summary::-webkit-details-marker { display: none; }
.nav-panel-group > summary::after {
  content: '';
  width: 0.4em; height: 0.4em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.nav-panel-group[open] > summary::after { transform: rotate(-135deg); }
.nav-panel-group > summary:hover { background: var(--surface-alt); color: var(--accent); }
.nav-panel-group:has(a[aria-current]) > summary { color: var(--text-title); font-weight: 600; }
.nav-panel-group > a { display: block; padding-left: var(--space-6); }

/* Lien vers l'application (app.pylotik.com). Il ne s'adresse pas au visiteur à
   convertir mais à l'utilisateur déjà invité, le plus souvent le client d'un
   client venu par le nom de marque plutôt que par son lien d'invitation. Il lui
   faut donc être trouvable d'un coup d'œil, sans disputer au terracotta le rôle
   d'appel à l'action. D'où le couple bouton fantôme / bouton plein : la forme
   dit « action », le remplissage dit laquelle des deux est celle du site.
   Pas de filet animé : ce n'est pas une page du site, c'est la sortie. */
.nav-login {
  font-size: 0.9rem;
  color: var(--text-soft);
  white-space: nowrap;
}
.nav-login:hover { color: var(--accent); }

/* Le tracé reprend .btn-secondary, à la taille compacte de .nav-cta plutôt qu'à
   celle de .btn, qui déséquilibrerait la barre. */
.nav-desktop .nav-login {
  font-weight: 600;
  color: var(--text-title);
  background: transparent;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 0.5rem 1.05rem;
  transition: border-color var(--transition), color var(--transition);
}
.nav-desktop .nav-login:hover { border-color: var(--accent); color: var(--accent); }

/* Dans le panneau mobile il reste un lien : les entrées y sont déjà des pavés
   pleine largeur, un contour de plus n'y distinguerait rien. C'est le filet qui
   sépare, on ne navigue plus dans le site vitrine, on en sort. */
.nav-panel .nav-login {
  margin-top: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  color: var(--text-title);
  font-weight: 600;
}

/* Avec trois sous-menus, la barre ne tient plus le filet de formule entre 961 et
   1 180 px : il s'y repliait sur trois lignes et poussait « À propos » et le
   bouton sur deux. Il cède sa place à la navigation sur cette plage (octobre 2026,
   écart signalé à Charley) ; au-delà, rien ne change. */
.nav-links a, .nav-sub > summary, .nav-login, .nav-cta { white-space: nowrap; }
@media (max-width: 1180px) {
  .nav-tagline { display: none; }
}
@media (max-width: 960px) {
  .nav-desktop { display: none; }
  .nav-disclosure { display: block; }
  .nav-tagline { display: none; }
}
/* =============================================
   BOUTONS
   ============================================= */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: var(--btn-weight);
  padding: var(--btn-padding);
  border-radius: var(--btn-radius);
  border: var(--btn-border) solid transparent;
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
/* Un bouton PLEIN accent ne peut pas porter un mot de marque : le segment
   « ik » de pylotik est précisément de cette couleur, il disparaîtrait dans le
   fond. Les deux mots de marque veulent un fond neutre ou transparent, d'où le
   bouton fantôme partout où ils apparaissent dans un bouton. */
.btn-primary { background: var(--accent); color: var(--on-dark); }
.btn-primary:hover { background: var(--accent-hover); color: var(--on-dark); }
.btn-secondary { background: transparent; color: var(--text-title); border-color: var(--line); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }
.btn-ghost-light { background: transparent; color: var(--on-dark); border-color: var(--on-dark-a35); }
.btn-ghost-light:hover { background: var(--on-dark-a10); color: var(--on-dark); }

/* Même bouton fantôme, mais accentué : il porte le terracotta sans le remplir,
   ce qui le fait ressortir de son voisin neutre tout en laissant les mots de
   marque lisibles. Réservé aux fonds sombres, comme --btn-ghost-light : la
   teinte lue est celle qui tient sur du bleu (4,65:1), pas l'accent de la
   charte, qui y tomberait à 3,3:1. */
.btn-ghost-accent {
  background: transparent;
  color: var(--accent-on-navy);
  border-color: var(--accent-on-navy);
}
.btn-ghost-accent:hover {
  background: var(--accent-on-navy-a12);
  color: var(--accent-on-navy);
}
.btn-arrow::after { content: '\2192'; transition: transform var(--transition); }
.btn-arrow:hover::after { transform: translateX(3px); }

.nav-cta {
  background: var(--accent);
  color: var(--on-dark);
  font-weight: var(--nav-cta-weight);
  font-size: var(--nav-cta-size);
  padding: var(--nav-cta-padding);
  border-radius: var(--nav-cta-radius);
}
.nav-cta:hover { background: var(--accent-hover); color: var(--on-dark); }

/* Cibles tactiles. Sur écran tactile (pointer: coarse), les contrôles compacts
   de l'en-tête et les boutons portent une zone de contact d'au moins 44 px -
   la cible de confort tactile, au-delà du minimum WCAG 2.5.8 (24 px). Le garde
   `pointer: coarse` laisse le rendu au POINTEUR FIN (souris) strictement
   inchangé : le poids visuel de l'en-tête sur desktop ne bouge pas, seule la
   surface cliquable grandit là où c'est un doigt qui vise. Icône et libellés
   sont inchangés ; c'est le padding qui absorbe la hauteur. */
@media (pointer: coarse) {
  .btn { min-height: 44px; }
  .nav-cta { display: inline-flex; align-items: center; min-height: 44px; }
  .nav-desktop .nav-login { display: inline-flex; align-items: center; min-height: 44px; }
  .nav-burger {
    display: flex; align-items: center; justify-content: center;
    min-width: 44px; min-height: 44px;
  }
}

.btn-group { display: flex; gap: var(--space-4); flex-wrap: wrap; }
/* =============================================
   CARTES
   ============================================= */

.grid { display: grid; gap: var(--grid-gap); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 900px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--card-padding);
  box-shadow: var(--card-shadow);
}
/* Une carte ne prend jamais le fond de la section qui la porte, sinon elle s'y
   dissout : sur fond gris elle est blanche (règle par défaut), sur fond blanc
   elle repasse au gris. Le lavis de couleur se pose par-dessus dans les deux cas. */
.section-alt .card { background: var(--card-on-alt); }
.card h3 { margin-bottom: var(--space-3); }
/* Cartes de la FAQ (objections) : titre-question calibré pour tenir sur une seule
   ligne à la largeur du conteneur étroit ; il se replie sur mobile. */
.faq-grid .card h3 { font-size: 1.05rem; line-height: 1.35; }

/* FAQ en accordéon des pages de capture. En <details>/<summary> natifs : l'état
   est porté par le DOM, donc aucun script, et le clavier comme les lecteurs
   d'écran fonctionnent sans qu'on ait rien à recâbler. Le marqueur par défaut est
   remplacé par un chevron dessiné en bordures, qui pivote à l'ouverture. */
.faq { margin-top: var(--space-6); }
.faq-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-3);
}
.section-alt .faq-item { background: var(--card-on-alt); }
.faq-item > summary {
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  line-height: 1.4;
  padding-right: var(--space-6);
  position: relative;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0.35em;
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}
.faq-item[open] > summary::after { transform: rotate(-135deg); }
.faq-item > summary:focus-visible {
  outline: 2px solid var(--interact);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}
.faq-item > p {
  margin-top: var(--space-3);
  color: var(--text-soft);
  font-size: 0.97rem;
}
/* Le pivot du chevron est une décoration : on le fige pour qui demande moins
   d'animation, sans rien retirer à l'ouverture elle-même. */
@media (prefers-reduced-motion: reduce) {
  .faq-item > summary::after { transition: none; }
}
.card p { color: var(--text-soft); font-size: 0.97rem; }
/* Les cartes ne portent pas de filet sur un seul côté : la couleur entre par un
   lavis diffus dans l'angle supérieur gauche, dérivé de --c, plus la pastille
   d'icône et le numéro. Le lavis est en `rgb(from ...)` : sur un navigateur qui
   ne connaît pas la syntaxe de couleur relative, la déclaration est ignorée et
   la carte reste unie, sans rien de cassé. */
.card-accent, .feature {
  --c: var(--accent);
  background-image: radial-gradient(115% 85% at 0% 0%, rgb(from var(--c) r g b / 0.14) 0%, rgb(from var(--c) r g b / 0) 62%);
}
/* Au survol, seul le lavis se renforce. Le filet, lui, ne bouge pas - mais la
   règle qui l'en empêche est plus bas, à côté de .card:hover : à spécificité
   égale, c'est l'ordre du fichier qui tranche, et la poser ici ne servirait à
   rien. */
.card-accent:hover, .feature:hover {
  background-image: radial-gradient(115% 85% at 0% 0%, rgb(from var(--c) r g b / 0.22) 0%, rgb(from var(--c) r g b / 0) 66%);
}
.card-accent .card-num, .feature .card-num { color: var(--c); }

.card-num {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
  display: block;
  margin-bottom: var(--space-3);
}
/* =============================================
   CHIFFRES

   Chiffres tabulaires : les colonnes de montants s'alignent, quel que soit le
   chiffre. --font-num bascule sur Inter le jour où elle est auto-hébergée.
   Un chiffre n'apparaît JAMAIS sans sa source : .stat-source est obligatoire.
   ============================================= */

/* Une tuile de chiffre-clé n'est pas une carte de texte : elle doit accrocher.
   D'où un peu plus d'air, une élévation au survol comme les cartes, et le lavis
   d'angle qui prend la couleur du chiffre qu'elle porte. */
.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.stat:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); border-color: rgb(from var(--c, var(--brand)) r g b / 0.45); }
.section-alt .stat { background: var(--card-on-alt); }
.stat-value {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.2rem, 4.2vw, 3rem);
  font-weight: 700;
  line-height: 1;
  color: var(--brand);
  letter-spacing: -0.02em;
}
.stat-value.accent { color: var(--accent); }
.stat-label { font-family: var(--font-heading); font-weight: 600; color: var(--text-title); margin-top: var(--space-3); }
.stat-source {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--text-soft);
  margin-top: var(--space-2);
  display: block;
  line-height: 1.5;
}
/* =============================================
   TABLEAU COMPARATIF (familles d'outils)
   ============================================= */

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.93rem;
  background: var(--surface);
}
/* Le seuil au-delà duquel un tableau doit défiler plutôt que se comprimer dépend
   du NOMBRE de colonnes, pas du composant : il est donc porté par un modificateur,
   posé au cas par cas. Un min-width global imposait une barre de défilement au
   tableau des sources, qui n'a que deux colonnes et vit dans une colonne étroite :
   il défilait ET ses colonnes étaient comprimées. Sans le modificateur, le tableau
   se dimensionne sur son contenu et remplit sa colonne. */
.table-wide { min-width: 720px; }

.table th, .table td { padding: var(--space-4); text-align: left; border-bottom: 1px solid var(--line); vertical-align: top; }
.table thead th {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-soft);
  font-weight: 500;
  border-bottom: 2px solid var(--line);
}
.table tbody th {
  font-family: var(--font-heading);
  font-weight: 600;
  color: var(--text-title);
}
/* Le non-retour à la ligne ne vaut que pour les libellés courts des tableaux
   larges (« PM d'exécution », « PME · 30 personnes »). Appliqué à tous, il
   forçait les en-têtes de ligne du tableau des sources, qui sont des phrases,
   à tenir sur une seule ligne : le tableau débordait et ses colonnes se
   comprimaient. */
.table-wide tbody th { white-space: nowrap; }
.table td { color: var(--text-soft); }
.table tr:last-child td, .table tr:last-child th { border-bottom: none; }

/* La ligne pylotik : c'est la conclusion du tableau, elle se lit d'un coup d'œil. */
.table .row-highlight { background: var(--tint-accent); }
.table .row-highlight th, .table .row-highlight td { color: var(--text-title); border-bottom: none; }
.table .row-highlight td { font-weight: 500; }

.mark-yes { color: var(--state-success); font-weight: 700; }
.mark-part { color: var(--state-running); font-weight: 700; }
.mark-no { color: var(--state-alert); font-weight: 700; }
/* =============================================
   BANDEAU SOMBRE

   Îlot sombre dans une page claire. La charte impose alors la variante FONCÉE
   du logo et les couleurs remontées : c'est le rôle des alias --dark-*.
   ============================================= */

.band-dark { background: var(--gradient-band); color: var(--on-dark-soft); padding: var(--band-pad-y) 0; }
.band-dark h2, .band-dark h3 { color: var(--on-dark); }
.band-dark .eyebrow { color: var(--dark-accent); }
.band-dark p { color: var(--on-dark-soft); }
.band-dark strong, .site-footer strong { color: var(--on-dark); }
.band-dark a:not(.btn) { color: var(--on-dark); }
.band-dark a:not(.btn):hover { color: var(--on-dark); }
.band-dark .card {
  background: var(--dark-surface);
  border-color: var(--dark-line);
}
.band-dark .card h3 { color: var(--on-dark); }
.band-dark .card p { color: var(--on-dark-soft); }
.band-dark .stat { background: var(--dark-surface); border-color: var(--dark-line); }
.band-dark .stat-value { color: var(--on-dark); }
.band-dark .stat-value.accent { color: var(--dark-accent); }
.band-dark .stat-label { color: var(--on-dark); }
.band-dark .stat-source { color: var(--on-dark-soft); }
.band-dark .note, .band-dark .note-source { color: var(--on-dark-soft); }
/* =============================================
   LISTES DE POINTS
   ============================================= */

.checklist { list-style: none; display: grid; gap: var(--space-4); }
.checklist li { position: relative; padding-left: var(--space-8); color: var(--text-soft); }
.checklist li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.55em;
  width: 10px; height: 10px;
  border-radius: 2px;
  background: var(--accent-flat);
}
.checklist strong { display: block; color: var(--text-title); font-family: var(--font-heading); margin-bottom: var(--space-1); }

/* Liste numérotée à gros numéro : la spirale, le cycle de vie. */
/* La numérotation est celle de la LISTE, pas un compteur CSS posé en ::before.
   La différence n'est pas cosmétique : `list-style: none` fait perdre à Safari et
   VoiceOver la sémantique de liste ordonnée, et un ::before n'est ni du texte
   sélectionnable, ni une position annoncée par les lecteurs d'écran. Avec
   `decimal-leading-zero` sur le <ol> et ::marker pour l'habiller, le numéro
   redevient celui de l'élément, il se renumérote tout seul si l'ordre change, et
   l'utilisateur entend « élément 3 sur 7 ».

   ::marker n'accepte que la typographie et la couleur, pas de fond ni de boîte.
   C'est sans conséquence ici : la pastille a été retirée, faute de contraste. */
.steps {
  list-style: decimal-leading-zero outside;
  display: grid;
  gap: var(--space-5);
  padding-left: 2.9rem;
}
.steps li { padding-left: var(--space-3); color: var(--text-soft); }
.steps li::marker {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
}
.steps strong { display: block; color: var(--text-title); font-family: var(--font-heading); margin-bottom: var(--space-1); }
/* =============================================
   ENCADRÉ

   Sert aux réserves de méthode (« modélisation interne, non auditée ») que les
   documents sources signalent systématiquement. Ne pas les diluer.
   ============================================= */

.callout {
  background: var(--tint-brand);
  border-left: 3px solid var(--brand-soft);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: var(--space-5) var(--space-6);
  font-size: 0.95rem;
}
.callout-title { font-family: var(--font-heading); font-weight: 600; color: var(--text-title); display: block; margin-bottom: var(--space-2); }
.callout-accent { background: var(--tint-accent); border-left-color: var(--accent); }
/* =============================================
   FORMULAIRE
   ============================================= */

.form { display: grid; gap: var(--space-5); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
@media (max-width: 620px) { .form-row { grid-template-columns: 1fr; } }

.field { display: grid; gap: var(--space-2); }
.field label { font-family: var(--font-heading); font-size: 0.9rem; font-weight: 600; color: var(--text-title); }
.field input, .field select, .field textarea {
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.7rem 0.9rem;
  width: 100%;
}
.field textarea { min-height: 150px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--tint-accent); }
.field-hint { font-size: 0.83rem; color: var(--text-soft); }

.consent { display: flex; gap: var(--space-3); align-items: flex-start; font-size: 0.9rem; color: var(--text-soft); }
/* accent-color habille la case COCHÉE : sans lui elle sort au bleu par défaut
   du navigateur, la seule couleur de la page à n'appartenir à personne. Le
   thème du widget lui-même vient de color-scheme, déclaré dans les tokens. */
.consent input { margin-top: 0.35em; width: auto; flex: none; accent-color: var(--accent); }
/* Le libellé est du texte courant, pas un libellé de champ : il ne prend ni la
   graisse ni la couleur des autres <label> du formulaire. */
.consent label { font-family: var(--font-body); font-weight: 400; color: var(--text-soft); }

/* Astérisque des champs obligatoires. En accent plutôt qu'en rouge d'alerte : le
   formulaire ne doit pas se présenter en état d'erreur avant la moindre saisie.
   Les <span> porteurs sont en aria-hidden, l'attribut required suffisant aux
   lecteurs d'écran ; la mention en tête de formulaire, elle, reste lue. */
.req { color: var(--accent); font-weight: 700; }

/* Retour d'envoi du formulaire de contact.
   envoi.php redirige vers contact.html#envoye ou #erreur ; « :target » fait le
   reste. Aucun JavaScript n'est nécessaire pour afficher ces deux blocs, et rien
   ne s'affiche tant qu'aucune ancre n'est visée — donc jamais à l'arrivée
   normale sur la page. Le voile et l'encre viennent des voyants de la charte :
   pas de couleur inventée ici, et le mode sombre suit tout seul. */
.envoi-retour { display: none; }
.envoi-retour:target {
  display: block;
  margin-top: var(--space-6);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-sm);
  border-left: 3px solid;
}
.envoi-retour p { margin: 0; font-size: 0.95rem; }
.envoi-ok:target { background: var(--tint-green); border-left-color: var(--state-success); }
.envoi-ko:target { background: var(--tint-alert); border-left-color: var(--state-alert); }
.envoi-ok:target strong { color: var(--state-success); }
.envoi-ko:target strong { color: var(--state-alert); }
/* Le bloc reçoit le focus au retour d'envoi (tabindex="-1") : sans ce retrait,
   le navigateur dessinerait un anneau de focus permanent autour du message. */
.envoi-retour:focus { outline: none; }

/* Avertissement du formulaire : même habillage que le retour d'erreur, mais révélé
   par le balisage (<noscript>) ou par le script, jamais par « :target ». Il prévient
   AVANT que le visiteur écrive, depuis que le jeton est exigé — le prévenir après
   coup lui ferait perdre son message. */
.envoi-avert {
  margin-top: var(--space-6);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-sm);
  border-left: 3px solid var(--state-alert);
  background: var(--tint-alert);
}
.envoi-avert[hidden] { display: none; }
.envoi-avert p { margin: 0; font-size: 0.95rem; }
.envoi-avert strong { color: var(--state-alert); }

/* Formulaire à gauche, encadrés de contexte à droite */
.contact-layout { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--space-12); align-items: start; }
@media (max-width: 900px) { .contact-layout { grid-template-columns: 1fr; } }

/* Variante : validation sans JavaScript (.form--validation, sur le <form>).
   :required n'annote que les champs contraints ; :not(:placeholder-shown) n'annote
   qu'un champ déjà saisi, jamais un champ vierge. Les champs requis portent donc tous
   un placeholder, même une simple espace. Repris d'orgatypik (lot 4 du chantier). */
.form--validation .field input:required:not(:placeholder-shown):invalid,
.form--validation .field textarea:required:not(:placeholder-shown):invalid { border-color: var(--state-alert); }
.form--validation .field input:required:not(:placeholder-shown):valid,
.form--validation .field textarea:required:not(:placeholder-shown):valid { border-color: var(--state-success); }
/* =============================================
   PAGES DE TEXTE (légales)

   Structure identique à celle des pages légales d'orgatypik : les deux sites se
   renvoient l'un à l'autre, leurs pages doivent se lire de la même façon.
   ============================================= */

.prose { max-width: 780px; margin: 0 auto; background: var(--prose-bg); border: var(--prose-border); border-radius: var(--radius); padding: var(--prose-pad); }
.prose h2 { font-size: 1.2rem; margin: var(--space-10) 0 var(--space-4); }
.prose h2:first-child { margin-top: 0; }
.prose h3 { font-size: 1rem; margin: var(--space-6) 0 var(--space-2); }
.prose ul, .prose ol { margin: 0 0 var(--space-4) var(--space-6); }
.prose li { margin-bottom: var(--space-2); }
.prose .updated { font-family: var(--font-mono); font-size: 0.78rem; color: var(--text-soft); }
/* Le même tampon de version, mais posé sur la bande d'en-tête SOMBRE des pages
   légales : --text-soft y est un gris de mode clair, donc illisible sur le bleu.
   La couleur d'encre sur fond sombre, à pleine valeur : une version se lit. */
.page-hero .updated { font-family: var(--font-mono); font-size: 0.78rem; color: var(--on-dark); margin-top: var(--space-4); }
.prose a { text-decoration: underline; text-underline-offset: 2px; }

/* Zone à compléter avant mise en ligne. Volontairement visible. */
.todo {
  background: var(--tint-accent);
  border: 1px dashed var(--accent);
  border-radius: var(--radius-sm);
  padding: 0 0.35em;
  font-family: var(--font-mono);
  font-size: 0.85em;
  color: var(--accent);
}
/* =============================================
   APPEL À L'ACTION FINAL
   ============================================= */

.cta-final { text-align: center; }
.cta-final h2 { max-width: 20ch; margin: 0 auto var(--space-5); }
/* Variante pour un titre d'appel plus long, qui casserait mal sur 20 caractères. */
.cta-final h2.cta-title-wide { max-width: 28ch; }
.cta-final p { max-width: 60ch; margin-left: auto; margin-right: auto; }
.cta-final .btn-group { justify-content: center; margin-top: var(--space-8); }
/* =============================================
   PIED DE PAGE
   ============================================= */

.site-footer { background: var(--footer-shell); color: var(--on-dark-soft); padding: var(--space-16) 0 var(--space-8); }
.site-footer a { color: var(--on-dark-soft); }
.site-footer a:hover { color: var(--dark-accent); }

.footer-grid { display: grid; grid-template-columns: var(--footer-columns); gap: var(--space-8); }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }


.footer-brand p { font-size: 0.92rem; margin-top: var(--space-4); max-width: 34ch; }

.footer-col-title {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-dark);
  margin-bottom: var(--space-4);
}
.footer-col { display: flex; flex-direction: column; gap: var(--space-2); font-size: 0.92rem; }

.footer-badge { margin-top: var(--space-12); }
.footer-badge + .footer-bottom { margin-top: var(--space-6); }

.footer-bottom {
  margin-top: var(--space-12);
  padding-top: var(--space-6);
  border-top: 1px solid var(--dark-line);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  justify-content: space-between;
  font-size: 0.85rem;
}
.footer-legal { display: flex; flex-wrap: wrap; gap: var(--space-4); }
/* =============================================
   ACCESSIBILITÉ
   ============================================= */

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--space-2);
  background: var(--accent);
  color: var(--on-dark);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  z-index: 100;
}
.skip-link:focus { left: var(--space-4); color: var(--on-dark); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
/* Fil d'Ariane des deux pages profondes : elles ne sont plus au menu, donc rien
   dans l'en-tête ne dit où l'on est ni comment remonter.

   Il forme sa propre barre, collée sous l'en-tête et collante avec lui. Le
   décalage n'est pas un nombre magique : 68 px de .nav-inner plus le filet d'un
   pixel de .site-header. Ces valeurs doivent bouger ensemble. */
.crumb-bar {
  position: sticky;
  top: 69px;
  z-index: 40;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
/* La barre porte deux choses : à gauche le fil d'Ariane (où l'on est), à droite
   les liens vers les AUTRES pages de la même section (où aller). Le padding
   vertical vit sur la rangée, pas sur les nav, pour que les deux s'alignent. */
.crumb-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-6);
  flex-wrap: wrap;
  padding: var(--space-2) 0;
}
.crumb {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-soft);
  line-height: 1.3;
}
.crumb a { color: var(--text-soft); }
.crumb a:hover { color: var(--accent); }
/* Liens latéraux : bleus, pour se distinguer du fil d'Ariane gris à leur gauche,
   et signaler qu'ils mènent ailleurs plutôt que de dire où l'on est. */
.crumb-jump {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--brand-soft);
}
.crumb-jump a { color: var(--brand-soft); }
.crumb-jump a:hover { color: var(--accent); }
.crumb-jump span { margin: 0 var(--space-2); opacity: 0.4; }
/* « voir aussi : » en DM Sans (corps), à gauche des liens complémentaires ;
   annule l'héritage mono/capitales du fil et le style des séparateurs. */
.crumb-jump .crumb-jump-label { font-family: var(--font-body); font-size: 0.8rem; letter-spacing: 0; text-transform: none; color: var(--text-soft); margin: 0 var(--space-2) 0 0; opacity: 1; }
.crumb span { margin: 0 var(--space-2); opacity: 0.55; }
/* =============================================
   ICÔNES & ENRICHISSEMENTS VISUELS
   (ajout : héros en atmosphère, cartes plus vivantes, pastilles d'icônes)

   Les icônes sont des SVG inline à trait (stroke: currentColor) : elles suivent
   la couleur de leur pastille, donc le thème. Elles sont décoratives -
   aria-hidden côté HTML - et ne portent jamais seules le sens d'une carte.
   Jeu provisoire, à remplacer par des originaux.
   ============================================= */

.card-icon {
  width: 46px;
  height: 46px;
  border-radius: 13px;
  display: grid;
  place-items: center;
  margin-bottom: var(--space-5);
  background: var(--tint-accent);
  color: var(--accent);
}
.card-icon svg {
  width: 24px; height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Variantes de couleur, pour promener toute la palette identitaire au fil des
   cartes plutôt que de rester sur le seul terracotta. */
.ci-brand  { background: var(--tint-brand); color: var(--brand); }
.ci-blue   { background: var(--tint-brand); color: var(--brand-soft); }
.ci-accent  { background: var(--tint-accent); color: var(--accent); }
.ci-green  { background: var(--tint-green); color: var(--state-success); }
.ci-alert  { background: var(--tint-alert); color: var(--state-alert); }
.ci-yellow { background: var(--tint-yellow); color: var(--state-waiting); }

/* Sur fond bleu (bandeaux, héros), la pastille s'éclaire. */
.band-dark .card-icon, .hero .card-icon, .page-hero .card-icon {
  background: var(--on-dark-a10);
  color: var(--dark-accent);
}
.band-dark .ci-brand, .band-dark .ci-blue { color: var(--dark-brand); }
/* Sur un bandeau bleu, les autres icônes prennent leur variante « sur navy » vive,
   pour ressortir dans les deux thèmes (leur couleur de base est trop sombre sur bleu
   en thème clair). */
.band-dark .ci-accent  { color: var(--accent-on-navy); }
.band-dark .ci-green  { color: var(--state-success-on-navy); }
.band-dark .ci-alert  { color: var(--state-alert-on-navy); }
.band-dark .ci-yellow { color: var(--state-waiting-on-navy); }

/* Cartes plus vivantes : une élévation douce au survol, un filet coloré animé.
   Rien de tape-à-l'œil - juste de quoi ôter l'aspect « fiche ». */
.card { transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition); }
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); border-color: var(--brand-soft); }
.band-dark .card:hover { border-color: var(--dark-brand); }

/* Sauf les cartes qui portent déjà une couleur propre par --c : leur filet NE
   BOUGE PAS au survol, seul leur lavis se renforce. Deux signaux pour un seul
   geste, c'était un cadre qui se rallume à chaque passage de souris dans une
   grille de six.

   Ces trois lignes doivent rester ICI, après .card:hover, et non près de la
   définition de .feature : les deux sélecteurs ont la même spécificité (0,2,0)
   et c'est le dernier écrit qui gagne. Déclarées plus haut, elles étaient
   silencieusement écrasées, et le filet virait au bleu. Le troisième sélecteur
   passe la spécificité à (0,3,0) pour reprendre la main sur .band-dark
   .card:hover, qui sans lui l'emporterait où que soit la règle. Les deux
   thèmes sont couverts : --line et --dark-line suivent le thème. */
.card-accent:hover, .feature:hover { border-color: var(--line); }

/* Variante « éclairée » des cartes feature : la couleur est présente sur toute
   la carte dès le repos (lavis plus dense et plus étendu), et s'intensifie au
   survol. Employée sur « La mécanique » (accueil) et « Cinq dynamiques » (à propos). */
.cards-lit .feature {
  background-image: radial-gradient(135% 135% at 0% 0%, rgb(from var(--c) r g b / 0.20) 0%, rgb(from var(--c) r g b / 0.06) 78%);
}
.cards-lit .feature:hover {
  background-image: radial-gradient(135% 135% at 0% 0%, rgb(from var(--c) r g b / 0.32) 0%, rgb(from var(--c) r g b / 0.11) 80%);
}
.band-dark .card-accent:hover, .band-dark .feature:hover { border-color: var(--dark-line); }

/* Carte « feature » : la même carte, mais dont le filet supérieur prend une
   couleur au choix (--c), accordée à la pastille. */

/* Pastilles de couleur pour les chiffres-clés : un KPI n'est plus
   systématiquement bleu, il emprunte à toute la palette selon ce qu'il dit. */
.stat-value.c-brand { color: var(--brand); }
.stat-value.c-blue  { color: var(--brand-soft); }
.stat-value.c-accent { color: var(--accent); }
.stat-value.c-alert { color: var(--state-alert); }
.stat-value.c-green { color: var(--state-success); }

/* Les deux mêmes couleurs, hors des KPI : quand une phrase NOMME un état, le
   mot porte la couleur de cet état. Sur fond bleu elles prennent leur variante
   lisible, comme l'accent et le mot de marque avant elles. */
.c-green { color: var(--state-success); }
.c-alert { color: var(--state-alert); }
.hero .c-green, .page-hero .c-green, .band-dark .c-green { color: var(--state-success-on-navy); }
.hero .c-alert, .page-hero .c-alert, .band-dark .c-alert { color: var(--state-alert-on-navy); }

/* Les KPI suivent la même règle : pas de filet de tête, un lavis d'angle. */
.stat.bar {
  --c: var(--brand);
  background-image: radial-gradient(110% 80% at 0% 0%, rgb(from var(--c) r g b / 0.12) 0%, rgb(from var(--c) r g b / 0) 60%);
}

/* --- Correctifs contraste sur fond bleu ---------------------------------------
   Les listes à puces héritaient des couleurs de texte CLAIR : sur une carte
   bleue (« Ce qu'il y voit »), elles devenaient sombre sur sombre. */
.band-dark .checklist li, .hero .checklist li, .page-hero .checklist li { color: var(--on-dark-soft); }
.band-dark .checklist strong, .hero .checklist strong, .page-hero .checklist strong { color: var(--on-dark); }
.band-dark .checklist li::before, .hero .checklist li::before, .page-hero .checklist li::before { background: var(--dark-accent); }
.band-dark .steps li, .hero .steps li, .page-hero .steps li { color: var(--on-dark-soft); }
.band-dark .steps strong, .hero .steps strong, .page-hero .steps strong { color: var(--on-dark); }

/* Les numéros prenaient l'accent de la palette claire : le terracotta #CC5500 ne
   donne que 2.23:1 sur le bandeau bleu, il y était illisible. Ils passent au
   terracotta éclairci, celui des fonds bleus, qui y tient 4.65:1. */
.band-dark .steps li::marker, .hero .steps li::marker, .page-hero .steps li::marker {
  color: var(--dark-accent);
}
/* =============================================
   MOTS DE MARQUE AU FIL DU TEXTE (les deux marques, sur les deux sites)

   Commun depuis le lot 4 du chantier sites-web : pylotik écrit orgatypik, orgatypik
   écrit pylotik, et chaque nom garde sa composition partout. Les couleurs sont des
   rôles (--wm-*) : chaque site les fait pointer vers les primitives de la charte,
   jamais vers ses propres alias de marque (le violet d'orgatypik n'est pas l'accent
   de pylotik).

   Le logotype composé (en-tête, pied de page, tableau comparatif) est une IMAGE :
   voir le bloc « MOTS DE MARQUE EN IMAGE » en fin de feuille. Ce qui suit ne
   concerne QUE les mentions au fil du texte, qui restent du texte : elles
   doivent se chercher, se sélectionner et se traduire.

   Composition : Nunito ExtraBold 800, bas-de-casse, interlettrage resserré. Le
   point est TOUJOURS gris, règle explicite des deux chartes. Nunito ne sert
   QU'ICI.
   ============================================= */

/* --- Le mot de marque DANS LE TEXTE COURANT ---------------------------------

   Les deux marques ont une règle de composition stricte, et elle vaut partout
   où leur nom est écrit, pas seulement dans le bloc de logo. On garde donc la
   typographie du logotype - Nunito ExtraBold, bas-de-casse, interlettrage
   resserré - à la taille du texte qui l'entoure.

   Une seule liberté prise, et elle est délibérée : le point final n'est PAS
   repris en cours de phrase, où il se lirait comme une fin de phrase. Il
   appartient au logotype composé (en-tête, pied de page, tableau), qui le
   porte. */
.wm-p, .wm-o {
  font-family: var(--font-brand);
  font-weight: 800;
  text-transform: lowercase;
  white-space: nowrap;
  /* Nunito a une hauteur d'x plus petite que DM Sans : à taille égale, le mot de
     marque paraissait rétréci au milieu du texte courant. On compense
     optiquement, en em pour que le rapport tienne à toutes les tailles. */
  font-size: 1.08em;
}

/* pylotik : interlettrage -0,065 em.
   À la taille du texte courant (16 px), le terracotta de la charte ne tient pas
   l'AA : le segment « ik » prend donc l'accent assombri, comme tout texte de
   cette taille. Le logotype composé, lui, garde la valeur exacte. */
/* Jamais souligné non plus, pour la même raison que son voisin : un trait
   posé sous « pylotik » traverse la descendante du « p » et du « y », et il
   coupe le point gris de la signature. Et comme pour orgatypik, un
   soulignement venu d'un ANCÊTRE ne s'annule pas depuis l'enfant : c'est le
   display qui l'arrête, pas une déclaration text-decoration. */
/* UN SEUL nœud texte depuis octobre 2026 : <span class="wm-p">pylotik</span>.
   Coupé en deux balises (pylot + <span class="ik">), le mot sortait « pylot ik »
   des extracteurs qui séparent chaque balise, moteurs de réponse compris. La
   couleur du segment « ik » est donc peinte par un dégradé à arrêt franc et
   background-clip, le procédé déjà employé pour orgatypik. L'arrêt est en
   pourcentage de la boîte du mot, mesuré sur l'ENCRE des glyphes dans Nunito 800
   et non sur la limite des balises : le « t » déborde sur le « i » (interlettrage
   négatif), et un arrêt posé au début du « i » peignait la barre du « t » en
   orange. Mesuré à 400 px : encre du « t » jusqu'à 876 px, du « i » dès 874 px,
   arrêt à 2,187 em ; surtitres (-0,02 em) : 948 et 964 px, arrêt à 2,39 em.
   L'arrêt est en em, pas en pourcentage, pour ne pas bouger avec le
   prolongement de boîte ci-dessous, et tenir à toutes les tailles.
   Seul écart mesuré avec l'ancien rendu : l'anticrénelage passe en niveaux de
   gris, comme pour orgatypik. La forme à deux balises, qui subsiste dans les
   pages légales, est peinte par le même dégradé et rend à l'identique.
   Repli : sans background-clip, la couleur déclarée reste visible. */
.wm-p {
  --wm-cut: 2.187em;
  /* Le « k » final déborde de la boîte (interlettrage négatif) : sans ce
     prolongement, background-clip n'en peindrait pas le bord droit. La marge
     négative rend la place, la mise en page ne bouge pas. */
  padding-right: 0.08em;
  margin-right: -0.08em;
  letter-spacing: -0.065em;
  color: var(--wm-pylot);
  background: linear-gradient(90deg, var(--wm-pylot) var(--wm-cut), var(--wm-ik) var(--wm-cut));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
}
/* Quand le mot termine une phrase ou un titre, le point qui suit est celui du
   logotype : gris, comme dans « pylotik. » composé (Charley, 23/10/2026). Il vit
   dans le span du mot, et sort du dégradé comme le point d'orgatypik. */
.wm-p .dot {
  color: var(--wm-pylotik-dot);
  -webkit-text-fill-color: var(--wm-pylotik-dot);
}

/* orgatypik : dégradé CONTINU navy → violet, de gauche à droite, interlettrage
   -0,065 em. Le point reste gris, donc hors du dégradé : il vit dans son propre
   span, avec -webkit-text-fill-color pour échapper au background-clip du
   parent. Repli : sur un navigateur sans background-clip: text, la couleur
   déclarée juste avant reste visible - jamais de texte transparent. */
.wm-o {
  letter-spacing: -0.065em;
  color: var(--wm-orga-from);
  background: linear-gradient(90deg, var(--wm-orga-from) 0%, var(--wm-orga-to) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  /* JAMAIS de soulignement sous ce mot. Le trait n'est pas peint par le
     dégradé - background-clip ne s'applique qu'aux glyphes - il sort donc dans
     la couleur de repli, un navy plein sous des lettres violettes, et il passe
     en plus sous les jambages du « g » et du « y » qu'il coupe.

     Un soulignement posé sur un ANCÊTRE ne peut pas être annulé par l'enfant :
     la spécification le fait se propager, et `text-decoration: none` ici
     n'aurait aucun effet. Seul un contexte de formatage en ligne l'arrête,
     d'où le display. C'est la ligne à ne pas retirer. */
  display: inline-block;
  /* Même raison que pour pylotik : le « k » final débordait de la boîte et son
     bord droit n'était pas peint (constaté en octobre 2026). */
  padding-right: 0.08em;
  margin-right: -0.08em;
}
.wm-o .dot {
  color: var(--wm-orga-dot);
  -webkit-text-fill-color: var(--wm-orga-dot);
}

/* --- Les deux marques sur fond sombre ---------------------------------------

   Tous les fonds sombres du site sont BLEUS : héros, bandeaux, pied de page.
   Charte V3.2 (24/10/2026) : sur le navy de marque, le logotype pylotik prend les
   teintes de la coque sombre, une seule série pour tous les fonds foncés : pylot
   #6B9BF6 (4,38:1), ik #E2752C (3,90:1), point #B7B2AB (5,71:1). Au-dessus du seuil
   de 3:1 d'un logotype, jamais pour du texte courant : la phrase de définition du
   héros est en blanc, comme tout texte courant sur le navy. orgatypik ne change pas :
   #9EBEFA -> #C4A8F5 sur le navy. */
.hero .wm-p, .page-hero .wm-p, .band-dark .wm-p, .site-footer .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));
}

.hero .wm-o, .page-hero .wm-o, .band-dark .wm-o, .site-footer .wm-o {
  color: var(--wm-orga-from-on-navy);
  background-image: linear-gradient(90deg, var(--wm-orga-from-on-navy) 0%, var(--wm-orga-to-on-navy) 100%);
}
.hero .wm-p .dot, .page-hero .wm-p .dot,
.band-dark .wm-p .dot, .site-footer .wm-p .dot {
  color: var(--wm-pylotik-dot-on-navy);
  -webkit-text-fill-color: var(--wm-pylotik-dot-on-navy);
}
.hero .wm-o .dot, .page-hero .wm-o .dot,
.band-dark .wm-o .dot, .site-footer .wm-o .dot {
  color: var(--wm-orga-dot-on-navy);
  -webkit-text-fill-color: var(--wm-orga-dot-on-navy);
}

/* Dans un lien, aucun des deux mots de marque ne prend la couleur du lien, et
   AUCUN DES DEUX N'EST SOULIGNÉ : le trait les abîme, chacun à sa manière (voir
   .wm-p et .wm-o). Le survol se signale donc par un éclaircissement. C'est un
   signal plus faible, assumé, et jamais seul : ces liens vivent dans une phrase
   dont le reste, lui, reste souligné. */
/* Impression sans les fonds, contraste forcé : un texte peint par background-clip
   y disparaîtrait. Les deux mots de marque retombent alors sur leur couleur pleine. */
/* Dans les titres (h1, h2), le mot se lit comme le logotype : il porte son point
   gris, même en cours de phrase (Charley, 23/10/2026). Le point est peint par le
   CSS, pas écrit dans le texte : les titres restent identiques pour les moteurs,
   les données structurées et la recette. Le surtitre, même logé dans le h1, n'est
   pas un titre. Quand le mot finit déjà la phrase, son point (.dot) suffit. */
:is(h1, h2) .wm-p:not(.eyebrow .wm-p):not(:has(.dot))::after,
:is(h1, h2) .wm-o:not(.eyebrow .wm-o):not(:has(.dot))::after {
  content: ".";
  content: "." / "";
  color: var(--wm-pylotik-dot);
  -webkit-text-fill-color: var(--wm-pylotik-dot);
}
:is(h1, h2) .wm-o:not(.eyebrow .wm-o):not(:has(.dot))::after {
  color: var(--wm-orga-dot);
  -webkit-text-fill-color: var(--wm-orga-dot);
}
/* Sur fond bleu : mêmes sélecteurs que ci-dessus, plus le fond, pour l'emporter
   (sans la répétition des :not(), la règle générale gagnait et peignait le point
   en gris foncé sur le navy). */
:is(.hero, .page-hero, .band-dark, .site-footer) :is(h1, h2) .wm-p:not(.eyebrow .wm-p):not(:has(.dot))::after,
:is(.hero, .page-hero, .band-dark, .site-footer) :is(h1, h2) .wm-o:not(.eyebrow .wm-o):not(:has(.dot))::after {
  color: var(--wm-pylotik-dot-on-navy);
  -webkit-text-fill-color: var(--wm-pylotik-dot-on-navy);
}

@media print, (forced-colors: active) {
  /* !important : les variantes sur fond bleu (.hero .wm-p…) sont plus spécifiques
     et repeindraient sinon le dégradé en rectangle derrière le texte. */
  .wm-p, .wm-o { background: none !important; -webkit-text-fill-color: currentColor !important; }
  .wm-o .dot, .wm-p .dot, .wm-p::after, .wm-o::after { -webkit-text-fill-color: currentColor !important; }
}

a .wm-p, a .wm-o { text-decoration: none; }
a:hover .wm-p, a:hover .wm-o { opacity: 0.78; transition: opacity var(--transition); }
