/* ==========================================================================
   Covartim, Composants
   Chaque section est marquée :
   - [Relevé]  : mesuré dans la source (nœud Figma cité en commentaire) ;
   - [Dérivé]  : construit à partir des tokens, absent de la source, à faire valider par le design.
   Les sections du socle partent toutes en [Dérivé] : passer en [Relevé] une fois les valeurs mesurées.
   Règle : un composant ne contient aucune valeur en dur qui existe déjà en token.
   ========================================================================== */

/* ==========================================================================
   1. Icônes [Dérivé], masque SVG, la couleur suit currentColor
   Les classes .i-* et variables --i-* sont générées dans icons.css (scripts/build-icons.py)
   ========================================================================== */
.icon {
  display: inline-block; flex-shrink: 0;
  width: var(--icon-size, var(--icon-m)); height: var(--icon-size, var(--icon-m));
  background-color: currentColor;
  -webkit-mask: var(--icon-src, none) center / contain no-repeat;
          mask: var(--icon-src, none) center / contain no-repeat;
}
.icon--s { --icon-size: var(--icon-s); }
.icon--l { --icon-size: var(--icon-l); }

/* ==========================================================================
   2. Boutons [Dérivé, inspirations], pilotés par des propriétés locales
   Hiérarchie = couleurs (--btn-bg/fg/bd) · taille = padding (--btn-py/px/fs).
   Ajouter une variante en réglant ces variables, jamais en réécrivant la boîte.
   Hauteurs : xs 32 · sm 40 · md 48 (défaut) · lg 56. Tout est en pilule ; les boutons d'icône sont ronds.
   Hiérarchie : un seul bouton plein (primary ou accent) par bloc ; le reste en secondary, tertiary ou lien à flèche.
   ========================================================================== */
.btn {
  --btn-bg: transparent; --btn-fg: var(--text-primary); --btn-bd: transparent;
  --btn-py: 14px; --btn-px: var(--pad-l); --btn-gap: var(--space-sm); --btn-fs: var(--fs-3);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--btn-gap);
  padding: calc(var(--btn-py) - 1px) calc(var(--btn-px) - 1px);
  border: 1px solid var(--btn-bd); border-radius: var(--radius-full);
  background: var(--btn-bg); color: var(--btn-fg);
  font-size: var(--btn-fs); line-height: 20px; font-weight: var(--fw-medium);
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
/* Retour de pression : le bouton « entend » le doigt (0,97, 160 ms). Jamais scale(0). */
.btn:active { transform: scale(.97); }

/* Tailles */
.btn--xs { --btn-py: 6px; --btn-px: 14px; --btn-gap: var(--space-xs); --btn-fs: var(--fs-2); }
.btn--xs .icon { --icon-size: var(--icon-s); }
.btn--sm { --btn-py: 10px; --btn-px: 18px; --btn-fs: var(--fs-2); }
.btn--lg { --btn-py: 18px; --btn-px: 28px; --btn-fs: var(--fs-4); }
.btn--block { width: 100%; }
.btn--icon { --btn-px: var(--btn-py); }

/* Hiérarchies */
.btn--primary   { --btn-bg: var(--action-primary); --btn-fg: var(--text-inverse); --btn-bd: var(--action-primary); }
.btn--accent    { --btn-bg: var(--action-accent); --btn-fg: var(--text-primary); --btn-bd: var(--action-accent-border); }   /* sur navy ou sur visuel : lime clair cerclé de lime ; texte navy, jamais blanc */
.btn--secondary { --btn-bg: var(--bg-card); --btn-bd: var(--bg-card); }                                                  /* plein gris froid */
.card .btn--secondary { --btn-bg: var(--bg-page); --btn-bd: var(--bg-page); }                                             /* … et blanc dans une carte grise */
.btn--tertiary  { --btn-bd: var(--border-control-subtle); }
.btn--inverse   { --btn-fg: var(--text-inverse); --btn-bd: var(--glass-border); }                                         /* contour clair sur navy ou visuel */
.btn--round     { --btn-bg: var(--bg-stone); --btn-bd: var(--bg-stone); --btn-py: 13px; --btn-px: 13px; }               /* 48 px, flèches et actions d'icône */
.section--muted .btn--round { --btn-bg: var(--bg-raised); --btn-bd: var(--bg-raised); }   /* sur une section grise, le rond est blanc [Relevé, Figma 24626:11625] */
.on-dark .btn--round, .section--dark .btn--round, .media .btn--round { --btn-bg: var(--bg-inverse-soft); --btn-bd: transparent; --btn-fg: var(--text-inverse); }

/* Survol : couleur seulement, à la souris */
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover   { --btn-bg: var(--action-primary-hover); --btn-bd: var(--action-primary-hover); }
  .btn--accent:hover    { --btn-bg: var(--action-accent-hover); --btn-bd: var(--action-accent-hover-border); }
  .btn--secondary:hover { --btn-bg: var(--bg-stone); --btn-bd: var(--bg-stone); }
  .btn--tertiary:hover  { --btn-bd: var(--border-strong); }
  .btn--inverse:hover   { --btn-bg: var(--bg-inverse-soft); }
  .btn--round:hover     { --btn-bg: var(--hover-fill); --btn-bd: var(--hover-fill); --btn-fg: var(--hover-fill-fg); }   /* survol unifié des ronds d'icône */
  :is(.on-dark, .section--dark, .media) .btn--round:hover { --btn-bg: var(--hover-fill-inverse); --btn-bd: var(--hover-fill-inverse); --btn-fg: var(--hover-fill-inverse-fg); }
}

/* États */
.btn:disabled, .btn[aria-disabled="true"] { opacity: .4; pointer-events: none; }
/* Chargement : <button aria-busy="true">, le libellé reste en place (largeur stable), une roue tourne dessus */
.btn[aria-busy="true"] { color: transparent; pointer-events: none; }
.btn[aria-busy="true"] > * { visibility: hidden; }
.btn[aria-busy="true"]::before {
  content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px;
  border: 2px solid var(--btn-fg); border-right-color: transparent; border-radius: var(--radius-full);
  animation: btn-spin 700ms linear infinite;
}
@keyframes btn-spin { to { transform: rotate(1turn); } }

/* RÈGLE TACTILE COMMUNE, sur écran tactile (et sous 1024 px, presque toujours tactile), tout élément cliquable
   dessiné sous 44 px garde son dessin mais reçoit une zone invisible de --tap-min par un ::after.
   Une seule liste pour tout le DS : y ajouter chaque nouveau petit élément cliquable (puce, pagination,
   lien de fil d'Ariane, bouton de quantité, pastille de filtre…) au lieu d'écrire un ::after par composant.
   Ne pas y mettre un élément qui utilise déjà ::after (lien étiré d'une carte). Garder --tap-gap entre voisins. */
@media (pointer: coarse), (max-width: 1024px) {
  :is(.btn--xs, .btn--sm, .tap-target, .chip, .tabs [role="tab"], .site-footer__links a, .breadcrumb a) { position: relative; }
  /* inset négatif par axe (top/bottom en % de la hauteur, left/right de la largeur) :
     28 px de haut → −8 px en haut et en bas = 44 px ; un élément déjà assez grand n'est pas agrandi */
  :is(.btn--xs, .btn--sm, .tap-target, .chip, .tabs [role="tab"], .site-footer__links a, .breadcrumb a)::after {
    content: ""; position: absolute;
    inset: min(0px, calc((100% - var(--tap-min)) / 2));
  }
}

/* ==========================================================================
   3. Header + menu mobile [Dérivé, inspirations], gabarit dans js/covartim.js
   Sur fond blanc : navigation à sous-menus (au clic, pas au survol), langue, contact.
   Sans filet au repos ; un filet apparaît dès qu'on défile (data-scrolled).
   Variante data-variant="hero" : fixe, transparente et en blanc sur le hero plein cadre (§24), puis fond blanc et
   boutons navy dès qu'on défile. Variante data-variant="overlay" : transparente, non collante (démo posée dans un visuel).
   Deux rangées (wireframe) : une rangée utilitaire discrète (Qui sommes-nous, Carrières, Contact, langue), puis
   logo + Services, Domaines d'expertise, Cas client + « Contactez-nous ».
   Repli selon la largeur du header lui-même (requêtes de conteneur, pas de la fenêtre) : il se replie au bon
   moment partout, y compris dans une colonne étroite. ≤ 900 px : navigation, rangée utilitaire et langue dans le
   tiroir (sous-menus en accordéon) ; ≤ 600 px : contact dans le tiroir.
   ========================================================================== */
.site-header {
  --screen-max: var(--screen-max-wide);   /* header, hero et footer sur 1520 px : le cadre de la page ; les sections restent à 1320 (demande du 3 novembre 2026) */
  container: site-header / inline-size;
  position: sticky; top: 0; z-index: 50;
  background: var(--bg-page); color: var(--text-primary);
  border-bottom: 1px solid transparent;
  padding-top: var(--safe-top);
  transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.site-header[data-scrolled] { border-bottom-color: var(--border-default); }
/* Compact en descendant (data-compact) : la rangée utilitaire glisse sous le bord haut et le logo rétrécit, sans
   changer la hauteur réservée dans la page (aucun saut du contenu). Puis masqué (data-hidden), réaffiché dès qu'on
   remonte (js/covartim.js) : la page garde toute sa hauteur à la lecture. Règle globale du 4 novembre 2026. */
.site-header[data-compact] { transform: translateY(calc(var(--header-utility-h, 0px) * -1)); }
.site-header__utility, .site-header__logo { transition: opacity var(--dur-fast) var(--ease-out), scale var(--dur-base) var(--ease-out); }
.site-header__logo { transform-origin: left center; }
.site-header[data-compact] .site-header__utility { opacity: 0; }
.site-header[data-compact] .site-header__logo { scale: .8; }
.site-header[data-hidden] { transform: translateY(-100%); }
.site-header[data-variant="overlay"] { position: absolute; inset: 0 0 auto; background: transparent; color: var(--text-inverse); }
.site-header[data-variant="hero"] { position: fixed; inset: 0 0 auto; background: transparent; color: var(--text-inverse); }
.site-header[data-variant="hero"][data-scrolled] { background: var(--bg-page); color: var(--text-primary); }
[data-variant="hero"][data-scrolled] .site-header__cta { --btn-bg: var(--action-primary); --btn-bd: var(--action-primary); --btn-fg: var(--text-inverse); }
[data-variant="hero"][data-scrolled] .site-header__menu { --btn-bg: var(--bg-card); --btn-bd: var(--bg-card); --btn-fg: var(--text-primary); }
@media (hover: hover) and (pointer: fine) { [data-variant="hero"][data-scrolled] .site-header__cta:hover { --btn-bg: var(--action-primary-hover); --btn-bd: var(--action-primary-hover); } }
/* Rangée utilitaire (wireframe) : petite, alignée à droite, sans fond ni filet, elle ne concurrence pas la navigation */
.site-header__utility { display: flex; justify-content: flex-end; align-items: center; gap: var(--space-m); padding-top: var(--pad-sm); font-size: var(--fs-2); line-height: var(--lh-2); }
.site-header__utility nav { display: flex; gap: var(--space-l); }
.site-header__utility a { display: inline-flex; align-items: center; min-height: 32px; color: inherit; text-decoration: none; text-underline-offset: 3px; }   /* même couleur que la navigation et la langue ; la petite taille suffit à la hiérarchie */
.site-header__utility a[aria-current] { text-decoration: underline; }
@media (hover: hover) and (pointer: fine) { .site-header__utility a:hover { text-decoration: underline; } }
.site-header__utility .nav-menu__trigger { min-height: 32px; padding-inline: var(--pad-smm); }
.site-header__inner { position: relative; display: flex; align-items: center; gap: var(--space-xl); min-height: var(--header-h); }
.site-header__nav { margin-left: auto; }
.site-header__brand { display: inline-flex; align-items: center; min-height: var(--tap-min); flex-shrink: 0; }
.site-header__logo { height: var(--logo-h); width: auto; }   /* logo officiel COVARTIM__Logo_POS_RGB.svg (covartim.com), 320 × 69,3 → 244 × 53 [Relevé, Figma 24626:12132] */
@container site-header (max-width: 900px) { .site-header__logo { height: min(var(--logo-h), 40px); } }   /* header replié : le logo laisse la place au bouton et au menu */
.site-header__list { display: flex; align-items: center; gap: var(--space-xs); margin: 0; }
.site-header__actions { display: flex; align-items: center; gap: var(--space-sm); flex-shrink: 0; }
.site-header__menu { display: none; }
@container site-header (max-width: 900px) {
  .site-header__utility, .site-header__nav, .site-header__actions > .nav-menu { display: none; }
  .site-header__actions { margin-left: auto; }
  .site-header__menu { display: inline-flex; }
}
@container site-header (max-width: 600px) { .site-header__cta { display: none; } }   /* le contact reste en tête du tiroir */

/* Déclencheur de sous-menu : texte + chevron qui pivote à l'ouverture */
.nav-menu { position: relative; }
.nav-menu__trigger {
  display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap-min);
  padding: 0 var(--pad-m-2); border: 0; border-radius: var(--radius-full); background: transparent; color: inherit;   /* 20 px de chaque côté : la pilule ouverte respire autour du libellé (demande du 3 novembre 2026) */
  font-size: var(--fs-3); font-weight: var(--fw-medium); white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.nav-menu__trigger .icon { transition: transform var(--dur-fast) var(--ease-out); }
.nav-menu__trigger[aria-expanded="true"] .icon { transform: rotate(180deg); }
.nav-menu__trigger[aria-expanded="true"], .nav-menu__trigger[data-current] { background: var(--bg-stone); }
.nav-menu__trigger--lang { font-size: var(--fs-2); letter-spacing: var(--ls-caps); }
a.nav-menu__trigger { text-decoration: none; }
a.nav-menu__trigger[aria-current] { background: var(--bg-stone); }
@media (hover: hover) and (pointer: fine) { .nav-menu__trigger:hover { background: var(--bg-stone); } }
:is([data-variant="overlay"], [data-variant="hero"]:not([data-scrolled])) .nav-menu__trigger:is([aria-expanded="true"], [data-current]) { background: var(--bg-inverse-soft); }
@media (hover: hover) and (pointer: fine) { :is([data-variant="overlay"], [data-variant="hero"]:not([data-scrolled])) .nav-menu__trigger:hover { background: var(--bg-inverse-soft); } }

/* Panneau : carte blanche ancrée sous son déclencheur, qui s'ouvre depuis lui (origine en haut).
   Entrée 200 ms, sortie 120 ms : le système répond vite, la fermeture ne se fait pas attendre. */
.nav-panel {
  position: absolute; top: calc(100% + var(--space-sm)); left: 0; z-index: 60;
  display: flex; gap: var(--space-sm); width: max-content; max-width: min(720px, calc(100vw / var(--zoom) - 2 * var(--gutter)));
  --panel-radius: var(--radius-xl); --panel-pad: var(--pad-sm);
  --panel-inner-radius: calc(var(--panel-radius) - var(--panel-pad));   /* rayons concentriques : intérieur = extérieur − marge (24 − 8 = 16) */
  padding: var(--panel-pad); border-radius: var(--panel-radius);
  background: var(--bg-raised); color: var(--text-primary);
  box-shadow: 0 24px 48px -12px rgb(15 15 50 / .18), 0 0 0 1px rgb(15 15 50 / .04);
  transform-origin: top left;
  opacity: 0; visibility: hidden; transform: translateY(-4px) scale(.98);
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out), visibility 0s linear 120ms;
}
.nav-panel[data-open] {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility 0s;
}
.nav-menu--end .nav-panel { left: auto; right: 0; transform-origin: top right; }
/* Grand panneau (avec carte) : ancré au bord droit du conteneur du header, pour ne jamais sortir de l'écran */
.nav-menu:has(> .nav-panel--feature) { position: static; }
.nav-panel--feature { left: auto; right: max(var(--gutter), var(--safe-right)); transform-origin: top center; }
.nav-panel__list { display: flex; flex-direction: column; margin: 0; min-width: 300px; }
.nav-panel--compact .nav-panel__list { min-width: 200px; }
.nav-panel--plain .nav-panel__list { min-width: 260px; }
.nav-panel__link {
  display: flex; flex-direction: column; gap: 2px; justify-content: center; min-height: var(--tap-min);
  padding: var(--pad-smm) var(--pad-m); border-radius: var(--panel-inner-radius);
  color: inherit; text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.nav-panel--compact .nav-panel__link { flex-direction: row; align-items: center; justify-content: space-between; }
.nav-panel__label { font-weight: var(--fw-medium); }
.nav-panel__desc { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }
.nav-panel__link[aria-current] { background: var(--bg-muted); }
@media (hover: hover) and (pointer: fine) { .nav-panel__link:hover { background: var(--bg-muted); } }
.nav-panel .nav-panel__feature { width: 280px; flex-shrink: 0; padding: var(--pad-l); border-radius: var(--panel-inner-radius); gap: var(--space-sm); }
.nav-panel__feature .eyebrow { color: var(--text-on-brand); }

/* Tiroir : plein écran sur mobile, panneau latéral sur tablette. Courbe « drawer » (type iOS). */
.drawer {
  position: fixed; inset: 0; z-index: 100;
  display: flex; justify-content: flex-end;
  background: var(--bg-overlay);
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base);
}
.drawer[data-open] { opacity: 1; visibility: visible; transition-delay: 0s; }
.drawer[hidden] { display: none; }
.drawer__panel {
  display: flex; flex-direction: column;
  width: min(440px, 100%); height: 100%;
  background: var(--bg-page); color: var(--text-primary);
  padding: calc(var(--safe-top) + var(--pad-m)) max(var(--gutter), var(--safe-right)) calc(var(--safe-bottom) + var(--pad-l)) var(--gutter);
  overflow-y: auto; overscroll-behavior: contain;
  transform: translateX(100%);
  transition: transform var(--dur-base) var(--ease-drawer);
}
.drawer[data-open] .drawer__panel { transform: none; }
.drawer__head { display: flex; align-items: center; justify-content: space-between; min-height: calc(var(--header-h) - var(--pad-m)); }
.drawer__nav { display: flex; flex-direction: column; margin-top: var(--space-l); }
.drawer__group { border-bottom: 1px solid var(--border-default); }
.drawer__group > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-m);
  min-height: 64px; cursor: pointer; list-style: none;
  font-size: var(--fs-h5); line-height: var(--lh-h5); font-weight: var(--fw-regular); letter-spacing: var(--ls-small);
}
.drawer__group > summary::-webkit-details-marker { display: none; }
.drawer__group > summary .icon { transition: transform var(--dur-fast) var(--ease-out); }
.drawer__group[open] > summary .icon { transform: rotate(180deg); }
.drawer__group ul { display: flex; flex-direction: column; margin: 0 0 var(--space-m); }
.drawer__group a { display: flex; align-items: center; min-height: var(--tap-min); color: var(--text-body); text-decoration: none; }
.drawer__group a[aria-current="page"] { color: var(--text-primary); font-weight: var(--fw-medium); }
.drawer__link {
  display: flex; align-items: center; min-height: 64px; border-bottom: 1px solid var(--border-default);
  font-size: var(--fs-h5); line-height: var(--lh-h5); letter-spacing: var(--ls-small); color: inherit; text-decoration: none;
}
.drawer__utility { display: flex; flex-direction: column; margin: var(--space-m) 0 0; }
.drawer__utility a { display: flex; align-items: center; min-height: var(--tap-min); color: var(--text-body); text-decoration: none; }
.drawer__foot { margin-top: auto; padding-top: var(--space-xl); display: flex; flex-direction: column; gap: var(--space-sm); }
.drawer__langs { display: flex; gap: var(--space-sm); margin-top: var(--space-sm); }
.drawer__langs .chip[aria-current] { background: var(--action-primary); border-color: var(--action-primary); color: var(--text-inverse); }
@media (max-width: 640px) { .drawer__panel { width: 100%; } }

/* ==========================================================================
   4. Footer [Dérivé, inspirations], gabarits dans js/covartim.js
   Léger par défaut : une ligne sur fond blanc (copyright, liens légaux).
   Complet (data-variant="full") [Relevé, Figma 24626:11910] : bloc navy uni, logo, accroche, contacts à icône ronde,
   colonnes de liens tirées de NAV (filet et flèche sous chaque lien), bureaux, réseaux, signature Synchrone, et le
   nom en filigrane sous la dernière ligne, coupé par le bas. Grille commune aux trois rangées (1,5 + 3 × 1). Le logo couleur reste lisible sur navy (lime 9,2:1) : pas besoin de version négative ici.
   ========================================================================== */
.site-footer {
  margin-top: auto; border-top: 1px solid var(--border-default);
  padding-block: var(--pad-l) calc(var(--pad-l) + var(--safe-bottom));
  color: var(--text-muted); font-size: var(--fs-2); line-height: var(--lh-2);
}
.site-footer__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-m); }
.site-footer__links { display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-l); }
.site-footer__links a { color: inherit; text-decoration: none; padding-block: var(--pad-smm); }   /* 22 + 2 × 12 ≥ 44 */
@media (hover: hover) and (pointer: fine) { .site-footer__links a:hover { color: var(--text-primary); text-decoration: underline; text-underline-offset: 3px; } }

.site-footer--full {
  --ft-gap: var(--space-3xl);
  --screen-max: var(--screen-max-wide);   /* ses .container sont plus larges que ceux de la page */
  position: relative; overflow: clip; isolation: isolate; border-top: 0;   /* clip, pas hidden : le filigrane déborde en bas et un bloc hidden pouvait défiler tout seul (focus, ancre), ce qui mangeait l'espace au-dessus du logo */
  padding-block: var(--stack-l) var(--safe-bottom);
  background: var(--bg-dark);
  color: var(--text-body-inverse); font-size: var(--fs-3); line-height: var(--lh-3);
}
/* Une grille commune aux trois rangées : l'accroche dans une colonne large (1,5), les trois listes dans trois colonnes ; les bureaux et les
   liens légaux s'alignent sur les mêmes colonnes que les listes (corrections du 3 novembre 2026 : « mieux agencé, plus aéré »). */
.site-footer__main, .site-footer__offices, .site-footer__bottom { display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr)); column-gap: var(--ft-gap); }
.site-footer__intro { grid-column: 1; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-xl); padding-right: var(--ft-gap); }
.site-footer__tagline {
  font-family: var(--font-display); font-size: var(--fs-h4); line-height: var(--lh-h4); font-weight: var(--fw-light);
  letter-spacing: var(--ls-tight); color: var(--text-inverse); max-width: 18ch;
}
.site-footer__contact { display: flex; flex-direction: column; gap: var(--space-xs); margin: 0; }
.site-footer__contact a { display: inline-flex; align-items: center; gap: var(--space-sm-2); min-height: var(--tap-min); color: var(--text-inverse); text-decoration: none; }
.site-footer__intro > .btn { margin-top: var(--space-sm); }
.site-footer__ico { display: grid; place-items: center; width: 36px; height: 36px; flex-shrink: 0; border-radius: var(--radius-full); background: var(--bg-inverse-soft); color: var(--text-inverse); }
.site-footer__ico .icon { --icon-size: var(--icon-s); }
.site-footer__muted { color: var(--text-muted-inverse); }

.site-footer__nav { grid-column: 2 / 5; display: grid; grid-template-columns: subgrid; row-gap: var(--space-3xl); align-content: start; }
.site-footer__title { margin-bottom: var(--space-sm); font-size: var(--fs-1); line-height: var(--lh-1); font-weight: var(--fw-medium); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted-inverse); }
/* Colonnes en <details> : toujours ouvertes et sans déclencheur au-dessus de 640 (le JS le garantit), repliées en mobile (règle globale) */
.site-footer__col > summary { list-style: none; display: flex; align-items: center; justify-content: space-between; cursor: default; }
.site-footer__col > summary::-webkit-details-marker { display: none; }
.site-footer__col > summary .icon { display: none; }
.site-footer__col ul { display: flex; flex-direction: column; margin: 0; }
.site-footer__col a {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-m);
  min-height: 56px; padding-block: var(--pad-smm); border-bottom: 1px solid var(--border-inverse);
  color: var(--text-inverse); text-decoration: none; line-height: var(--lh-2);
}
.site-footer__col a .icon { opacity: .6; transition: transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .site-footer__col a:hover .icon { opacity: 1; transform: translate(2px, -2px); }
  .site-footer__contact a:hover { text-decoration: underline; text-underline-offset: 3px; }
}

/* Bureaux : le titre sous l'accroche, un bureau sous chaque liste ; sans pictogramme (demande du 3 novembre 2026) */
.site-footer__offices { row-gap: var(--space-xl); margin-top: var(--stack-m); padding-block: var(--space-3xl); border-top: 1px solid var(--border-inverse); }
.site-footer__offices > .site-footer__title { grid-column: 1; margin: 0; padding-top: var(--space-xs); }
.site-footer__office { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-xs); font-style: normal; font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-body-inverse); }
.site-footer__office strong { color: var(--text-inverse); font-weight: var(--fw-medium); font-size: var(--fs-3); }

/* Dernière ligne : copyright sous l'accroche ; liens légaux, réseaux et signature sous les listes */
.site-footer__bottom {
  align-items: center; row-gap: var(--space-m); padding-block: var(--space-xl); border-top: 1px solid var(--border-inverse);
  font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted-inverse);
}
.site-footer__bottom > :first-child { grid-column: 1; }
.site-footer__end { grid-column: 2 / 5; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-m) var(--space-xl); }
.site-footer__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-m); }   /* bouton de contact + réseaux sociaux, sous les coordonnées (demande utilisateur) */
.site-footer--full .site-footer__links a { color: var(--text-muted-inverse); }
@media (hover: hover) and (pointer: fine) { .site-footer--full .site-footer__links a:hover { color: var(--text-inverse); } }
.site-footer__social { display: flex; flex-wrap: wrap; gap: var(--space-sm); }
/* Signature Synchrone : le sigle seul (assets/icons/synchrone.svg, depuis le DS Synchrone), discret, zone de 44 px */
.site-footer:not(.site-footer--full) .site-footer__credit { color: var(--text-muted); }
@media (hover: hover) and (pointer: fine) { .site-footer:not(.site-footer--full) .site-footer__credit:hover { color: var(--text-primary); } }
.site-footer__credit { display: inline-grid; place-items: center; width: var(--tap-min); height: var(--tap-min); margin-right: calc((var(--tap-min) - var(--icon-m)) / -2); color: var(--text-muted-inverse); transition: color var(--dur-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .site-footer__credit:hover { color: var(--text-inverse); } }

/* Nom en filigrane : le mot-symbole du logo (assets/brand/wordmark.svg, sans le sigle ni le ®), en masque blanc à 6 %.
   Décor masqué aux lecteurs d'écran ; il occupe toute la largeur de l'écran sous la dernière ligne (il ne passe plus
   sous le texte) et sort par le bas d'un tiers de sa hauteur. */
.site-footer__wordmark {
  display: block; width: 100%; aspect-ratio: 224 / 37; margin-bottom: calc(-100vw / var(--zoom) * 37 / 224 / 3);
  background: rgb(255 255 255 / .06); pointer-events: none;
  -webkit-mask: var(--i-wordmark) center / contain no-repeat; mask: var(--i-wordmark) center / contain no-repeat;
}
/* Arrivée en bas de page : le logotype monte et apparaît, une fois (data-draw → .is-drawn, js/covartim.js) ; demande du 4 novembre 2026 */
@media (prefers-reduced-motion: no-preference) {
  .site-footer__wordmark { opacity: 0; transform: translateY(45%); transition: opacity 700ms var(--ease-out), transform 1100ms var(--ease-out); }
  .site-footer__wordmark.is-drawn { opacity: 1; transform: none; }
}

@media (max-width: 1024px) {
  .site-footer__main, .site-footer__offices, .site-footer__bottom { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .site-footer__main { row-gap: var(--stack-s); }
  .site-footer__intro, .site-footer__nav, .site-footer__offices > .site-footer__title, .site-footer__bottom > :first-child, .site-footer__end { grid-column: 1 / -1; padding-right: 0; }
}
@media (max-width: 640px) {
  .site-footer__main, .site-footer__offices, .site-footer__bottom { grid-template-columns: minmax(0, 1fr); }
  .site-footer__nav { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .site-footer__col { border-bottom: 1px solid var(--border-inverse); }
  .site-footer__col:first-child { border-top: 1px solid var(--border-inverse); }
  .site-footer__offices { border-top: 0; padding-top: 0; }   /* le filet sous la dernière colonne repliée suffit (demande utilisateur) */
  .site-footer__col > summary { min-height: 56px; margin: 0; cursor: pointer; }
  .site-footer__col > summary .icon { display: block; transition: rotate var(--dur-fast) var(--ease-out); }
  .site-footer__col[open] > summary .icon { rotate: 180deg; }
  .site-footer__col > summary:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-card); }
  .site-footer__col[open] > ul { padding-bottom: var(--space-m); cursor: pointer; }
  .site-footer__end { flex-direction: column; align-items: flex-start; }
  .site-footer__credit { margin-left: calc((var(--tap-min) - var(--icon-m)) / -2); }
}

/* ==========================================================================
   5. Formulaires [Dérivé, inspirations], champs blancs de 52 px, rayon 12, label au-dessus
   Contour slate-500 (3,2:1 sur blanc, WCAG 1.4.11), plus foncé au survol, navy + halo sky au focus,
   coral en erreur. Le texte saisi est en 16 px partout (pas de zoom iOS). On signale le facultatif,
   pas l'obligatoire : la plupart des champs d'un formulaire de contact sont requis.
   ========================================================================== */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-l) var(--space-m); }
.form-grid .span-2 { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-grid { grid-template-columns: minmax(0, 1fr); } }

.field { display: flex; flex-direction: column; gap: var(--space-sm); min-width: 0; }
.field__label { font-size: var(--fs-label); line-height: var(--lh-2); font-weight: var(--fw-medium); color: var(--text-primary); }
.field__optional { font-weight: var(--fw-regular); color: var(--text-muted); }
.field__hint { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }
.field__error { display: flex; align-items: flex-start; gap: var(--space-xs); font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-danger); }
.field__error::before { content: ""; width: 16px; height: 16px; margin-top: 3px; flex-shrink: 0; background: currentColor; -webkit-mask: var(--i-x) center / contain no-repeat; mask: var(--i-x) center / contain no-repeat; }

.input, .select, .textarea {
  width: 100%; min-height: 52px;
  padding: 14px var(--pad-m);
  border: 1px solid var(--border-control); border-radius: var(--radius-field);
  background: var(--bg-field); color: var(--text-primary);
  font-size: var(--fs-input); line-height: 22px;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .input:hover, .select:hover, .textarea:hover { border-color: var(--border-control-hover); }
}
.input:focus-visible, .select:focus-visible, .textarea:focus-visible, .input:focus, .select:focus, .textarea:focus { outline: none; border-color: var(--border-strong); box-shadow: var(--focus-ring); }
:is(.input, .select, .textarea)[aria-invalid="true"] { border-color: var(--text-danger); }
:is(.input, .select, .textarea)[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgb(195 43 47 / .25); }
:is(.input, .select, .textarea):disabled { background: var(--bg-field-disabled); border-color: var(--border-control-subtle); color: var(--text-muted); cursor: not-allowed; }
.input::placeholder, .textarea::placeholder { color: var(--text-muted); opacity: 1; }
.textarea { min-height: 144px; resize: vertical; }
.select {
  appearance: none; padding-right: 48px; cursor: pointer;
  background: var(--bg-field) var(--i-chevron-down) right 16px center / 16px no-repeat;
}
.select:disabled { background-color: var(--bg-field-disabled); }

/* Case et radio dessinées : le <label> entier est la cible (≥ 44 px de haut) */
.choice {
  display: flex; align-items: flex-start; gap: var(--space-sm-2);
  min-height: var(--tap-min); padding-block: 12px; cursor: pointer;
  font-size: var(--fs-3); line-height: 20px;
}
.choice input {
  appearance: none; position: relative; display: grid; place-items: center;
  width: 20px; height: 20px; margin: 0; flex-shrink: 0; cursor: pointer;
  border: 1px solid var(--border-control); border-radius: 6px; background: var(--bg-field);
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.choice input[type="radio"] { border-radius: var(--radius-full); }
.choice input::before { content: ""; width: 14px; height: 14px; background: var(--text-inverse); opacity: 0; transform: scale(.8); transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.choice input[type="checkbox"]::before { -webkit-mask: var(--i-check) center / contain no-repeat; mask: var(--i-check) center / contain no-repeat; }
.choice input[type="radio"]::before { width: 8px; height: 8px; border-radius: var(--radius-full); }
.choice input:checked { background: var(--action-primary); border-color: var(--action-primary); }
.choice input:checked::before { opacity: 1; transform: none; }
.choice input:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.choice input[aria-invalid="true"] { border-color: var(--text-danger); }
.choice input:disabled { background: var(--bg-field-disabled); border-color: var(--border-control-subtle); }
.choice:has(input:disabled) { color: var(--text-muted); cursor: not-allowed; }
@media (hover: hover) and (pointer: fine) { .choice:hover input:not(:checked, :disabled) { border-color: var(--border-control-hover); } }
/* Quand le texte contient du balisage (lien, compteur), l'envelopper dans un seul <span> */
.choice-group { display: grid; gap: 0; border: 0; padding: 0; margin: 0; min-width: 0; }
.choice-group > legend { padding: 0; margin-bottom: var(--space-xs); }

/* Interrupteur : piste slate-500 (3,2:1) éteinte, navy allumée */
.switch { display: inline-flex; align-items: center; gap: var(--space-sm-2); min-height: var(--tap-min); cursor: pointer; }
.switch input {
  appearance: none; position: relative; width: 44px; height: 26px; margin: 0; flex-shrink: 0; cursor: pointer;
  border-radius: var(--radius-full); background: var(--border-control);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.switch input::before {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  border-radius: 50%; background: var(--bg-page); box-shadow: 0 1px 2px rgb(15 15 50 / .25);
  transition: transform var(--dur-base) var(--ease-out);
}
.switch input:checked { background: var(--action-primary); }
.switch input:checked::before { transform: translateX(18px); }
.switch input:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* Formulaire sur fond sombre (carte en verre d'un bloc contact) : champs translucides, contour clair */
:is(.on-dark, .card--glass, .card--dark) :is(.input, .select, .textarea) { background-color: rgb(255 255 255 / .08); border-color: rgb(255 255 255 / .45); color: var(--text-inverse); }
:is(.on-dark, .card--glass, .card--dark) :is(.input, .textarea)::placeholder { color: var(--text-muted-inverse); }
:is(.on-dark, .card--glass, .card--dark) .field__label { color: var(--text-inverse); }
:is(.on-dark, .card--glass, .card--dark) .field__hint { color: var(--text-muted-inverse); }

/* ==========================================================================
   6. Tags et étiquettes [Dérivé]
   ========================================================================== */
.chip {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  padding: 4px 10px; border-radius: var(--radius-full);
  background: var(--bg-card); font-size: var(--fs-1); line-height: var(--lh-1); font-weight: var(--fw-medium);
  color: inherit; text-decoration: none;
}
/* [Dérivé, inspirations] Pilule à contour (niveaux, catégories), pilule lime pour l'élément actif */
.chip--outline { background: transparent; border: 1px solid var(--border-default); padding: 7px 15px; font-size: var(--fs-2); line-height: var(--lh-2); }
.chip--accent  { background: var(--action-accent); color: var(--text-primary); padding: 8px 16px; font-size: var(--fs-2); line-height: var(--lh-2); }
.on-dark .chip--outline, .media .chip--outline { border-color: var(--glass-border); color: var(--text-inverse); }
.chip--glass { background: var(--glass-bg); color: var(--text-inverse); -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur)); padding: 8px 16px; font-size: var(--fs-2); line-height: var(--lh-2); }
/* Étiquette [Dérivé, logique du 3 novembre 2026] : pilule de 28 px, casse normale, jamais cliquable.
   La couleur dit QUELLE EXPERTISE est en jeu, avec la teinte du survol de la carte de service correspondante :
     teal = développement de produit (R&D, prototypage, cybersécurité) · sky = stratégie réglementaire (MDR, IVDR, affaires réglementaires)
     navy = audits et suivi post-market (audits, clinique) · lime = système qualité (QMS, qualité) · sun = formation.
   Tout le reste (type de dispositif, type de contenu, norme) reste neutre (mist) : il dit QUOI, pas QUI. Fond 200 + texte 800 (navy 900), ≥ 7:1. */
.tag {
  --tag-bg: var(--bg-stone); --tag-fg: var(--text-body);
  display: inline-flex; align-items: center; width: fit-content; height: 28px; padding-inline: var(--space-sm-2);
  border-radius: var(--radius-full); background: var(--tag-bg); color: var(--tag-fg);
  font-size: var(--fs-1); line-height: 20px; font-weight: var(--fw-medium);
}
.tag[data-tone="teal"]  { --tag-bg: var(--color-teal-200);  --tag-fg: var(--color-teal-800); }
.tag[data-tone="sky"]   { --tag-bg: var(--color-sky-200);   --tag-fg: var(--color-sky-800); }
.tag[data-tone="lime"]  { --tag-bg: var(--color-lime-200);  --tag-fg: var(--color-lime-800); }
.tag[data-tone="navy"]  { --tag-bg: var(--color-navy-200);  --tag-fg: var(--color-navy-900); }
.tag[data-tone="sun"]   { --tag-bg: var(--color-sun-100);   --tag-fg: var(--color-sun-800); }
.tag--domain { --tag-bg: var(--pict-tint, var(--bg-card)); --tag-fg: var(--text-primary); }   /* normes de l'en-tête des fiches domaine : pastel du domaine (--pict-tint posé sur <main>), demande du 4 novembre 2026 */

/* Rangée de filtres : sur mobile, défile horizontalement au lieu de passer sur 3 lignes */
.chip-row { display: flex; flex-wrap: wrap; gap: var(--space-sm); }
@media (max-width: 640px) {
  .chip-row--scroll {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter);
    scroll-padding-inline: var(--gutter);
  }
  .chip-row--scroll::-webkit-scrollbar { display: none; }
  .chip-row--scroll > * { flex-shrink: 0; }
}

/* ==========================================================================
   7. Onglets [Dérivé, direction], role="tablist" ; filtres réels via data-filter-target (js)
   Pilules comme tout ce qui est cliquable : contour léger au repos, navy plein pour l'onglet actif.
   ========================================================================== */
.tabs {
  display: flex; gap: var(--space-sm);
  overflow-x: auto; scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs [role="tab"] {
  flex-shrink: 0; min-height: var(--tap-min); padding: 0 var(--pad-m-2);
  border: 1px solid var(--border-default); border-radius: var(--radius-full);
  background: transparent; color: var(--text-primary);
  font: inherit; font-size: var(--fs-2); font-weight: var(--fw-medium); white-space: nowrap; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.tabs [role="tab"][aria-selected="true"] { background: var(--action-primary); border-color: var(--action-primary); color: var(--text-inverse); }
@media (hover: hover) and (pointer: fine) { .tabs [role="tab"]:not([aria-selected="true"]):hover { background: var(--bg-card); border-color: var(--bg-card); } }
.tabs [role="tab"]:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.on-dark .tabs [role="tab"], .section--dark .tabs [role="tab"] { border-color: var(--glass-border); color: var(--text-inverse); }
.on-dark .tabs [role="tab"][aria-selected="true"], .section--dark .tabs [role="tab"][aria-selected="true"] { background: var(--action-accent); border-color: var(--action-accent-border); color: var(--text-primary); }
@media (max-width: 640px) { .tabs { margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter); scroll-padding-inline: var(--gutter); } }

/* ==========================================================================
   8. Carrousel [Dérivé], défilement natif + scroll-snap ; flèches masquées sur tactile
   ========================================================================== */
.scroller {
  display: grid; grid-auto-flow: column; grid-auto-columns: var(--scroller-item, calc((100% - 2 * var(--grid-gap)) / 3));
  gap: var(--grid-gap); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.scroller::-webkit-scrollbar { display: none; }
.scroller > * { scroll-snap-align: start; min-width: 0; }
.scroller--4 { --scroller-item: calc((100% - 3 * var(--grid-gap)) / 4); }   /* quatre visibles sur desktop */
@media (max-width: 1024px) { .scroller, .scroller--4 { --scroller-item: calc((100% - var(--grid-gap)) / 2.2); } }
@media (max-width: 640px) {
  /* 1 carte + un bout de la suivante : montre qu'on peut faire défiler */
  .scroller, .scroller--4 { --scroller-item: 82%; }
}
/* Pleine largeur par défaut (règle globale : un carrousel n'est jamais contenu dans le container). La rangée déborde
   jusqu'aux deux bords de l'écran ; au repos la première carte s'aligne sur le contenu et la carte coupée à droite
   annonce la suite [Relevé, Figma 24626:11663]. La section sert de conteneur : 100cqw = largeur visible sans la barre
   de défilement. --bleed = marge entre le bord de l'écran et le contenu du .container, reprise en marge négative, en
   padding et en scroll-padding (aimantation calée sur le bord du contenu). */
.section:has(.scroller) { container-type: inline-size; overflow-x: clip; }
.scroller {
  --bleed: max(var(--gutter), (100cqw - var(--screen-max)) / 2);
  margin-inline: calc(var(--bleed) * -1); padding-inline: var(--bleed); scroll-padding-inline: var(--bleed);
}
/* --bleed : cartes de 312 px (largeur relevée) au-dessus de 1024 ; mêmes largeurs que les autres rangées en dessous. */
@media (min-width: 1025px) { .scroller--bleed { --scroller-item: 312px; } }
.scroller-arrows { display: flex; gap: var(--space-sm); }
.scroller-arrows .btn:disabled { opacity: .35; }
/* Visuel en carrousel : hauteur fixée par le rapport, pas par la grille */
.scroller > .media { aspect-ratio: var(--media-ratio, 4 / 5); }
@media (pointer: coarse) { .scroller-arrows { display: none; } }

/* ==========================================================================
   9. Tableau [Dérivé], .table--stack + data-label : cartes empilées sous 640 px
   ========================================================================== */
.table-wrap { border-radius: var(--radius-card); background: var(--bg-page); box-shadow: inset 0 0 0 1px var(--border-default); overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-2); line-height: var(--lh-2); }
.table th, .table td { padding: var(--pad-m) var(--pad-m-2); text-align: left; vertical-align: top; border-bottom: 1px solid var(--border-default); }
.table th { font-weight: var(--fw-medium); color: var(--text-muted); background: var(--bg-muted); white-space: nowrap; }
.table td:first-child { color: var(--text-primary); font-weight: var(--fw-medium); }
.table tr:last-child td { border-bottom: 0; }
.table .is-num { text-align: right; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) {
  .table-wrap:has(.table--stack) { border: 0; border-radius: 0; overflow: visible; }
  .table--stack thead { display: none; }
  .table--stack, .table--stack tbody, .table--stack tr, .table--stack td { display: block; }
  .table-wrap:has(.table--stack) { box-shadow: none; background: none; }
  .table--stack tr { border: 1px solid var(--border-default); border-radius: var(--radius-card); padding: var(--pad-sm) var(--pad-m); background: var(--bg-page); }
  .table--stack tr + tr { margin-top: var(--space-sm); }
  .table--stack td { display: flex; justify-content: space-between; gap: var(--space-m); padding: var(--pad-sm) 0; text-align: right; }
  .table--stack td::before { content: attr(data-label); color: var(--text-muted); font-weight: var(--fw-regular); text-align: left; }
  .table--stack td:not([data-label])::before { content: none; }
}

/* ==========================================================================
   10. Popup / feuille [Dérivé], <dialog class="modal">
   Centrée sur desktop ; feuille ancrée en bas sur mobile (pouce, clavier).
   ========================================================================== */
.modal {
  width: min(640px, calc(100% - 2 * var(--gutter))); max-height: calc(100dvh / var(--zoom) - 2 * var(--space-xl));
  padding: 0; border: 0; border-radius: var(--radius-xl);   /* grand panneau : 24 (médias), au-dessus des cartes à 12 */
  background: var(--bg-page); color: var(--text-primary);
  overscroll-behavior: contain;
}
.modal::backdrop { background: var(--bg-overlay); }
.modal__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-m); padding: var(--pad-xl) var(--pad-xl) 0; }
.modal__body { padding: var(--pad-l) var(--pad-xl) var(--pad-xl); }
.modal__foot {
  position: sticky; bottom: 0; display: flex; gap: var(--space-sm); justify-content: flex-end;
  padding: var(--pad-m) var(--pad-xl); background: var(--bg-page); border-top: 1px solid var(--border-default);
}
@media (max-width: 640px) {
  /* Feuille : ne jamais mettre height: auto sur un <dialog> positionné, il s'étire alors jusqu'en haut de
     l'écran. Laisser la hauteur par défaut (fit-content) ; une feuille de filtres peut fixer height: 92dvh. */
  .modal {
    width: 100%; max-width: 100%; max-height: calc(92dvh / var(--zoom));
    margin: auto 0 0; border-radius: var(--radius-xl) var(--radius-xl) 0 0;
  }
  .modal__head { padding: var(--pad-m) var(--pad-m) 0; }
  .modal__head::before {   /* poignée : signale une feuille qu'on peut fermer */
    content: ""; position: absolute; top: 8px; left: 50%; translate: -50% 0;
    width: 36px; height: 4px; border-radius: 2px; background: var(--border-default);
  }
  .modal__body { padding: var(--pad-m); }
  .modal__foot { padding: var(--pad-m) var(--pad-m) calc(var(--pad-m) + var(--safe-bottom)); }
  .modal__foot .btn { flex: 1; }
}

/* ==========================================================================
   11. Barre d'action mobile [Dérivé], l'action principale reste sous le pouce
   À placer en fin de <main>. La page réserve sa hauteur pour ne rien masquer.
   ========================================================================== */
.sticky-bar {
  position: fixed; inset: auto 0 0; z-index: 40;
  display: none; align-items: center; justify-content: space-between; gap: var(--space-m);
  min-height: var(--sticky-bar-h);
  padding: var(--pad-sm) max(var(--gutter), var(--safe-right)) calc(var(--pad-sm) + var(--safe-bottom)) max(var(--gutter), var(--safe-left));
  background: var(--bg-page); border-top: 1px solid var(--border-default);
}
.sticky-bar .btn { flex: 1; max-width: 60%; }
@media (max-width: 1024px) {
  .sticky-bar { display: flex; }
  body:has(.sticky-bar) { padding-bottom: calc(var(--sticky-bar-h) + var(--safe-bottom)); }
}

/* ==========================================================================
   12. Accordéon [Dérivé, inspirations], <details class="accordion"><summary>…</summary><div class="accordion__body">…</div></details>
   Question en Medium 18 px, bouton rond (plus / moins) à droite, filet sous chaque question.
   Pour une FAQ : une seule question ouverte par défaut, la première.
   ========================================================================== */
.accordion { border-bottom: 1px solid var(--border-default); }
.accordion > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-l);
  min-height: 72px; padding-block: var(--pad-m); cursor: pointer; list-style: none;
  font-size: var(--fs-4); line-height: var(--lh-4); font-weight: var(--fw-medium); letter-spacing: var(--ls-small);
}
.accordion > summary::-webkit-details-marker { display: none; }
.accordion > summary { position: relative; }
.accordion > summary::after {
  content: ""; width: 40px; height: 40px; flex-shrink: 0; border-radius: var(--radius-full); background: var(--bg-stone);
  transition: background-color var(--dur-fast) var(--ease-out);
}
/* Icône plus / moins posée sur le rond, en masque : sa couleur suit le survol unifié (navy plein, icône blanche) */
.accordion > summary::before {
  content: ""; position: absolute; z-index: 1; right: 12px; top: 50%; width: 16px; height: 16px; margin-top: -8px;
  background: var(--text-primary); -webkit-mask: var(--i-plus) center / contain no-repeat; mask: var(--i-plus) center / contain no-repeat;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.accordion[open] > summary::before { -webkit-mask-image: var(--i-minus); mask-image: var(--i-minus); }
/* Toute la zone ouvre et ferme, réponse comprise (règle globale ; clic sur la réponse géré dans covartim.js) */
.accordion[open] > .accordion__body { cursor: pointer; }
@media (hover: hover) and (pointer: fine) { .accordion:hover > summary::after { background-color: var(--hover-fill); } .accordion:hover > summary::before { background-color: var(--hover-fill-fg); } }
.accordion > summary:focus-visible { outline: none; }
.accordion > summary:focus-visible::after { box-shadow: var(--focus-ring); }
.accordion__body { padding: 0 var(--space-5xl) var(--pad-l) 0; color: var(--text-body); max-width: calc(540px + var(--space-5xl)); }   /* réponse de 540 px [Relevé, Figma 24630:7286] */

/* ==========================================================================
   13. Cartes et surfaces [Dérivé, inspirations], <article class="card card--stone">
   Une carte = une surface pleine, rayon 12 (relevé dans les corrections Figma), sans ombre ni bordure : la couleur suffit à la détacher.
   Fonds : gris froid (défaut, sur la page blanche), --muted (gris très clair : cartes de service, bandeau d'appel),
   --raised (blanc, sur une section grise), pierre, navy, teal (carte de couleur), verre (posée sur un visuel).
   Texte en haut, pied (.card__foot) poussé en bas : c'est la grammaire des mosaïques.
   ========================================================================== */
.card {
  --card-bg: var(--bg-card); --card-fg: inherit;
  position: relative; display: flex; flex-direction: column; gap: var(--space-m);
  min-width: 0; padding: var(--pad-xl); border-radius: var(--radius-card);
  background: var(--card-bg); color: var(--card-fg);
}
.card--stone { --card-bg: var(--bg-stone); }
.card--muted { --card-bg: var(--bg-muted); }   /* [Relevé, Figma 24627:12254 et 24626:11817] */
/* Carte « Liseré » [Dérivé, 4 novembre 2026] : la carte de domaine (§25) en version non cliquable, pour les fiches domaine.
   Fond blanc (section mist), pastel de la famille (--pict-tint, posé sur <main>) en bandeau du haut fondu en oklab, trame de points
   vivante (canvas .domain-card__dots, js/covartim.js) ; le texte est calé en bas, sous le bandeau. */
.card--lisere {
  position: relative; isolation: isolate; overflow: clip; justify-content: flex-end; min-height: 300px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--pict-tint, var(--color-teal-200)) 90%, var(--bg-raised)) 0%, var(--bg-raised) 40%);
  background: linear-gradient(180deg in oklab, color-mix(in oklab, var(--pict-tint, var(--color-teal-200)) 90%, var(--bg-raised)) 0%, var(--bg-raised) 40%);
}
.card--lisere:hover .domain-card__dots { opacity: .36; }
@media (max-width: 640px) { .card--lisere { min-height: 220px; } }
/* Carte de service (.card--service) : au survol ou au focus, un dégradé de marque monte du bas (transform seul, 420 ms,
   --ease-out), le texte passe en blanc et « En savoir plus » en lime, la flèche glisse de 4 px. Une teinte par carte
   avec data-tone : teal (vif), sky, navy, lime ; sans data-tone, teal-600 → ocean. Souris et clavier ;
   en mouvement réduit, le dégradé apparaît en fondu. */
.card--service { --card-bg: var(--bg-card); isolation: isolate; overflow: clip; transition: color var(--dur-base) var(--ease-out); }   /* mist-100 au repos : un cran plus marqué que mist-50 sur la page blanche (demande du 3 novembre 2026) */
.card--service::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: var(--svc-flat, var(--bg-brand));   /* aplat, comme la carte du menu (3 novembre 2026) */
  transform: translateY(101%); transition: transform 420ms var(--ease-out);
}
/* Une teinte de la charte par carte (data-tone), en aplat : texte teal-50 ≥ 5,4:1, blanc ≥ 5,8:1 sur les quatre */
.card--service[data-tone="teal"]  { --svc-flat: var(--color-teal-600); }
.card--service[data-tone="sky"]   { --svc-flat: var(--color-ocean-600); }
.card--service[data-tone="navy"]  { --svc-flat: var(--color-navy-700); }
.card--service[data-tone="lime"]  { --svc-flat: var(--color-lime-700); }
.card--service .text-muted { transition: color var(--dur-base) var(--ease-out); }
.card__more { display: inline-flex; align-items: center; gap: var(--space-xs); transition: color var(--dur-base) var(--ease-out); }
.card__more .icon { transition: transform var(--dur-base) var(--ease-out); }
.card--service:has(.card__link:focus-visible) { --card-fg: var(--text-inverse); }
.card--service:has(.card__link:focus-visible)::before { transform: none; }
.card--service:has(.card__link:focus-visible) .text-muted { color: var(--text-on-brand); }
.card--service:has(.card__link:focus-visible) .card__more { color: var(--action-accent); }
@media (hover: hover) and (pointer: fine) {
  .card--service:hover { --card-fg: var(--text-inverse); }
  .card--service:hover::before { transform: none; }
  .card--service:hover .text-muted { color: var(--text-on-brand); }
  .card--service:hover .card__more { color: var(--action-accent); }
  .card--service:hover .card__more .icon { transform: translateX(4px); }
}
.card--raised { --card-bg: var(--bg-raised); }
.section--muted .card:not([class*="card--"]) { --card-bg: var(--bg-raised); }   /* carte par défaut sur section grise : blanche */
.card--dark  { --card-bg: var(--bg-dark-raised); --card-fg: var(--text-inverse); }
.card--brand { --card-bg: var(--bg-brand); --card-fg: var(--text-inverse); }
.card--glass {
  --card-bg: var(--glass-bg); --card-fg: var(--text-inverse);
  border: 1px solid var(--glass-border);
  -webkit-backdrop-filter: blur(var(--glass-blur)); backdrop-filter: blur(var(--glass-blur));
}
.card--tall { min-height: var(--card-min-h); }
@media (max-width: 640px) { .grid-4 > .card--tall { min-height: 0; } .grid-4 > .card--tall .card__foot { margin-top: var(--space-xl); } }   /* cartes empilées : pas de vide sous le titre */
.card__foot { margin-top: auto; display: flex; flex-direction: column; gap: var(--space-m); }
.card :is(.text-body, p:not([class])) { color: inherit; }
.card--brand .text-muted, .card--dark .text-muted, .card--glass .text-muted { color: var(--text-on-brand); }
.card--dark .eyebrow { color: var(--text-muted-inverse); }
.card--dark .text-body { color: var(--text-body-inverse); }
/* Carte cliquable : lien étiré sur le titre (jamais un <a> autour de la carte) */
.card__link { color: inherit; text-decoration: none; }
.card__link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.card__link:focus-visible { outline: none; }
/* Bandeau d'appel à l'action : grand panneau gris, rayon 32 (grands panneaux), phrase à gauche, bouton en bas à droite */
.cta-band { --card-bg: var(--bg-muted); padding: var(--pad-2xl); border-radius: var(--radius-2xl); }
.cta-band > .split { align-items: flex-end; gap: var(--space-xl); }
/* Schéma technique animé [Dérivé, d'après une mise en plan de pièce, 3 novembre 2026] : <svg class="cta-band__drawing" data-draw>
   Monochrome, ton sur ton (mist-300 sur mist-50), contours continus, décalage et axes en pointillés : un fond dessiné, pas une illustration. Plus grand que la place disponible,
   il déborde du bandeau par le haut et y est coupé (overflow: clip) ; le texte et le bouton passent devant.
   Les traits se dessinent une fois à l'arrivée à l'écran (js : .is-drawn), puis un point « palpeur » suit le contour en boucle lente (12 s).
   Mouvement réduit : schéma complet et immobile. Masqué sous 1024 px, où le texte prend toute la largeur. */
.cta-band { isolation: isolate; overflow: clip; }
.cta-band > .split { position: relative; z-index: 1; }
.cta-band__drawing {
  position: absolute; top: -88px; right: calc(var(--pad-2xl) + 48px); z-index: 0;
  width: min(50%, 620px); height: 296px;
  fill: none; stroke: var(--drawing-line); stroke-width: 1; stroke-linecap: round; stroke-linejoin: round; pointer-events: none;
}
/* Pas de vector-effect: non-scaling-stroke : il fausse le calcul des tirets normalisés (pathLength) et le tracé restait incomplet. */
.cta-band__drawing .tx { fill: var(--drawing-line); stroke: none; font-size: 12px; font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.cta-band__probe { fill: var(--drawing-line); stroke: none; opacity: 0;
  offset-path: path("M216 30 H284 A26 26 0 0 1 310 56 V144 A26 26 0 0 1 284 170 H216 A26 26 0 0 1 190 144 V56 A26 26 0 0 1 216 30 Z"); offset-rotate: 0deg; }
@media (prefers-reduced-motion: no-preference) {
  .cta-band__drawing .ln { stroke-dasharray: 1; stroke-dashoffset: 1; }
  .cta-band__drawing :is(.dash, .tx) { opacity: 0; }
  .cta-band__drawing.is-drawn .ln { animation: draw-line 1.2s var(--ease-out) forwards; animation-delay: calc(var(--i) * 110ms); }
  .cta-band__drawing.is-drawn :is(.dash, .tx) { animation: draw-fade .6s var(--ease-out) forwards; animation-delay: calc(300ms + var(--i) * 110ms); }
  .cta-band__drawing.is-drawn .cta-band__probe { animation: draw-fade .4s var(--ease-out) 1.6s forwards, probe-run 12s linear 1.6s infinite; }
}
@keyframes draw-line { to { stroke-dashoffset: 0; } }
@keyframes draw-fade { to { opacity: 1; } }
@keyframes probe-run { from { offset-distance: 0%; } to { offset-distance: 100%; } }
@media (max-width: 1024px) { .cta-band__drawing { display: none; } }
/* Carte d'article : sans fond ni marge, visuel 16/10 puis étiquette, titre et extrait [Relevé, Figma 24626:11507] */
.card--article { --card-bg: transparent; padding: 0; gap: var(--space-m); }
.card--article > .media { --media-ratio: 16 / 10; }
:is(.card, .case-row, .job-row):has(.card__link:focus-visible) { outline: 2px solid var(--focus-outline); outline-offset: 2px; }   /* toute ligne ou carte à lien étiré montre le focus clavier */
:is(.case-row, .job-row):has(.card__link:focus-visible) { outline-offset: 6px; border-radius: var(--radius-card); }

/* ==========================================================================
   14. Visuels [Dérivé, inspirations], <figure class="media media--shade">
   Photo ou vidéo plein cadre, rayon 24 (32 pour un hero). Titre posé en haut, légende en bas précédée d'un
   filet vertical blanc. Le dégradé --media-shade garantit la lisibilité du texte blanc.
   Sans photo, .media--placeholder affiche un dégradé de marque (prototype uniquement).
   ========================================================================== */
.media {
  position: relative; isolation: isolate; overflow: hidden; display: block; min-width: 0; margin: 0;
  aspect-ratio: var(--media-ratio, 4 / 5); border-radius: var(--radius-xl);
  background: var(--bg-dark); color: var(--text-inverse);
}
.media--wide { --media-ratio: 16 / 9; }
.media--square { --media-ratio: 1 / 1; }
.media--portrait { --media-ratio: 4 / 5; }
@media (max-width: 640px) { .media--portrait { --media-ratio: 4 / 3; } }   /* un visuel de hero ne repousse pas le contenu sur mobile */
.media--hero { --media-ratio: auto; min-height: min(calc(86dvh / var(--zoom)), 820px); border-radius: var(--radius-2xl); }
.media > img, .media > video { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; }
.media--shade::before { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--media-shade); }
.media__inner { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-l); padding: var(--pad-xl); }
/* Visuel teinté + texte défilant [Dérivé, demande du 4 novembre 2026, version sobre] : bloc formations. Léger calque de
   couleur en produit (--media-tint, donnée de teinte) et une phrase en grand, blanche, qui traverse le cadre à plat.
   La piste contient deux fois la phrase : translateX(-50 %) boucle sans raccord. Défile aussi au survol ; vidéo sans bouton pause (demandes du 4 novembre 2026) ; vidéo et texte immobiles en mouvement réduit. */
.media--tint::after { content: ""; position: absolute; inset: 0; z-index: -1; background: var(--media-tint); mix-blend-mode: multiply; opacity: .45; pointer-events: none; }
.media__ticker { position: absolute; inset-inline: 0; top: 50%; translate: 0 -50%; overflow: hidden; color: var(--text-inverse); }
.media__ticker-track { display: flex; width: max-content; }
.media__ticker-track > span {
  flex: none; padding-right: 0.6em; white-space: nowrap;
  font-size: var(--fs-display); line-height: 1.1; font-weight: var(--fw-light); letter-spacing: var(--ls-display);
}
@media (prefers-reduced-motion: no-preference) {
  .media__ticker-track { animation: ticker 24s linear infinite; }
}
@keyframes ticker { to { transform: translateX(-50%); } }
@media (max-width: 640px) { .media__ticker-track > span { font-size: var(--fs-h1); } }
/* Hero : le contenu suit le flux et fait grandir le cadre s'il dépasse (titre long, petit écran) */
.media--hero > .media__inner { position: relative; min-height: inherit; padding: var(--pad-2xl); }
.media__caption {
  padding-left: var(--pad-m); border-left: 1px solid var(--border-on-media);
  font-size: var(--fs-4); line-height: var(--lh-4); max-width: 36ch;
}
/* Visuels d'attente : dégradés décoratifs, seule exception à la règle des rôles (ce sont des images, pas de l'interface). */
.media--placeholder { background:
  radial-gradient(120% 80% at 85% 10%, color-mix(in srgb, var(--color-sky-400) 55%, transparent), transparent 60%),
  radial-gradient(90% 70% at 10% 90%, color-mix(in srgb, var(--color-lime-400) 45%, transparent), transparent 60%),
  linear-gradient(160deg, var(--color-teal-700), var(--color-navy-950)); }
.media--placeholder-2 { background:
  radial-gradient(80% 60% at 30% 30%, color-mix(in srgb, var(--color-lime-300) 50%, transparent), transparent 65%),
  linear-gradient(200deg, var(--color-teal-500), var(--color-teal-900)); }
.media--placeholder-3 { background:
  radial-gradient(70% 70% at 70% 60%, color-mix(in srgb, var(--color-sky-300) 45%, transparent), transparent 65%),
  linear-gradient(180deg, var(--color-ocean-600), var(--color-navy-950)); }
@media (hover: hover) and (pointer: fine) {
  .media > img { transition: transform var(--dur-slow) var(--ease-out); }
  .card:hover .media > img, .case-row:hover .media > img, a.media:hover > img { transform: scale(1.03); }   /* même retour au survol sur les lignes de cas que sur les cartes */
}

/* ==========================================================================
   15. Mosaïque [Dérivé, inspirations], <div class="bento">
   Grille serrée (gap 16) de cartes et de visuels de même hauteur. 3 colonnes, 2 sous 1024, 1 sous 640.
   .span-2 occupe deux colonnes (visuel large) et redevient simple sur mobile.
   ========================================================================== */
.bento { display: grid; gap: var(--bento-gap); grid-template-columns: repeat(var(--bento-cols, 3), minmax(0, 1fr)); }
.bento--4 { --bento-cols: 4; }
.bento > * { min-height: var(--card-min-h); }
.bento > .media { aspect-ratio: auto; }
.bento > .span-2 { grid-column: span 2; }
@media (max-width: 1024px) { .bento, .bento--4 { --bento-cols: 2; } }
@media (max-width: 640px) {
  .bento, .bento--4 { --bento-cols: 1; }
  .bento > .span-2 { grid-column: auto; }
}

/* ==========================================================================
   16. Chiffres clés [Dérivé, inspirations], <div class="stat"><span class="stat__value">…</span><span class="stat__label">…</span></div>
   Valeur fine et grande, libellé discret. En liste (.stat-list) dans une section sombre, ou en grand dans une carte.
   ========================================================================== */
.stat {
  --stat-bg: var(--bg-card); --stat-fg: var(--text-primary);
  display: flex; align-items: baseline; gap: var(--space-m);
  padding: var(--pad-m) var(--pad-l); border-radius: var(--radius-l); background: var(--stat-bg);
}
.stat__value {
  font-family: var(--font-display); font-size: var(--fs-h4); line-height: var(--lh-h4);
  font-weight: var(--fw-light); letter-spacing: var(--ls-tight); font-variant-numeric: tabular-nums;
  color: var(--stat-fg); white-space: nowrap;
}
.stat__label { color: var(--text-muted); }
.stat--bare { --stat-bg: transparent; padding: 0; flex-direction: column; gap: var(--space-xs); }
.stat--bare .stat__value { font-size: var(--fs-h1); line-height: var(--lh-h1); letter-spacing: var(--ls-title); }
.stat-list { display: grid; gap: var(--space-sm); max-width: 440px; }
/* Variante sans fond prioritaire sur le fond des sections sombres ; --rule ajoute le filet vertical du wireframe */
:is(.section--dark, .on-dark, .card) .stat.stat--bare, .stat.stat--bare { --stat-bg: transparent; }
.section--dark .stat, .on-dark .stat { --stat-bg: var(--bg-dark-raised); --stat-fg: var(--text-inverse); }   /* chiffres en blanc, la couleur reste au titre [Relevé, Figma 24626:11702] */
.section--dark .stat__label, .on-dark .stat__label, .card--dark .stat__label, .media .stat__label { color: var(--text-body-inverse); }
.card--brand .stat__label { color: var(--text-on-brand); }   /* navy-200 sur teal-600 = 4,4:1 ; teal-50 = 5,8:1 */
.card--brand .stat, .card--dark .stat, .media .stat { --stat-bg: transparent; --stat-fg: inherit; }

/* ==========================================================================
   17. Lien à flèche [Dérivé, inspirations], <a class="link-arrow">Libellé<span class="link-arrow__icon">…</span></a>
   Appel secondaire : libellé + bouton rond fléché. Au survol (souris uniquement), la flèche glisse de 2 px.
   ========================================================================== */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--space-m); min-height: var(--tap-min);
  color: inherit; text-decoration: none; font-weight: var(--fw-medium);
}
.link-arrow__icon {
  display: grid; place-items: center; width: 48px; height: 48px; flex-shrink: 0;
  border-radius: var(--radius-full); background: var(--bg-stone);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.link-arrow__icon .icon { transition: transform var(--dur-fast) var(--ease-out); }
.link-arrow:active .link-arrow__icon { transform: scale(.95); }
@media (hover: hover) and (pointer: fine) {
  .link-arrow:hover .link-arrow__icon { background: var(--hover-fill); color: var(--hover-fill-fg); }   /* rempli en navy, flèche blanche (demande du 3 novembre 2026) */
  :is(.section--dark, .on-dark, .card--brand, .card--dark, .card--glass, .media) .link-arrow:hover .link-arrow__icon { background: var(--hover-fill-inverse); color: var(--hover-fill-inverse-fg); }
  .link-arrow:hover .link-arrow__icon .icon { transform: translate(2px, -2px); }
}
.section--muted .link-arrow__icon { background: var(--bg-raised); }   /* [Relevé, Figma 24626:11836] */
.section--dark .link-arrow__icon, .on-dark .link-arrow__icon, .card--brand .link-arrow__icon, .card--dark .link-arrow__icon, .card--glass .link-arrow__icon, .media .link-arrow__icon { background: var(--bg-inverse-soft); }

/* ==========================================================================
   18. Liste clé–valeur [Dérivé, inspirations], <dl class="kv"><div><dt>…</dt><dd>…</dd></div></dl>
   Libellé discret à gauche, valeur en Medium à droite, filet sous chaque ligne.
   ========================================================================== */
.kv { display: grid; margin: 0; }
.kv > div { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-l); padding-block: var(--pad-m); border-bottom: 1px solid var(--border-default); }
.kv dt { color: var(--text-muted); }
.kv dd { font-weight: var(--fw-medium); text-align: right; }

/* ==========================================================================
   19. Pastille d'icône [Dérivé], <span class="icon-tile"><span class="icon i-compass"></span></span>
   Rond de 48 px teal-50, icône teal-700 : la touche de couleur d'une carte de service.
   ========================================================================== */
.icon-tile { display: grid; place-items: center; width: 48px; height: 48px; flex-shrink: 0; border-radius: var(--radius-full); background: var(--bg-brand-soft); color: var(--icon-brand); }
.on-dark .icon-tile, .card--dark .icon-tile { background: var(--bg-inverse-soft); color: var(--icon-accent-inverse); }

/* ==========================================================================
   20. Liste à coches [Dérivé], <ul class="checklist" role="list"><li>…</li></ul>
   ========================================================================== */
.checklist { display: grid; gap: var(--space-sm-2); margin: 0; }
.checklist li { display: flex; gap: var(--space-sm-2); align-items: flex-start; }
.checklist li::before {
  content: ""; width: 24px; height: 24px; flex-shrink: 0; border-radius: var(--radius-full);
  background: var(--bg-success) var(--i-check) center / 14px no-repeat;
}

/* ==========================================================================
   21. Ligne d'étude de cas [Dérivé], <article class="case-row">visuel + catégorie + titre + extrait + pilules
   Visuel à gauche, texte à droite ; carte cliquable par lien étiré sur le titre.
   ========================================================================== */
.case-row { position: relative; display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--space-xl); align-items: center; padding-block: var(--space-2xl); border-bottom: 1px solid var(--border-default); }
.case-row:first-child { padding-top: 0; }
.case-row:last-child { padding-bottom: 0; border-bottom: 0; }   /* filet entre les cas seulement, pas sous le dernier (demande du 3 novembre 2026) */
.case-row .media { --media-ratio: 4 / 3; }
.case-row__body { display: flex; flex-direction: column; gap: var(--space-sm-2); min-width: 0; }
.case-row__body .chip-row { margin-top: var(--space-xs); }
@media (max-width: 640px) { .case-row { grid-template-columns: minmax(0, 1fr); gap: var(--space-m); } }

/* ==========================================================================
   22. Citation [Dérivé], <figure class="quote"><blockquote class="statement">…</blockquote><figcaption>…</figcaption></figure>
   ========================================================================== */
.quote { display: flex; flex-direction: column; gap: var(--space-l); margin: 0; }
.quote blockquote { margin: 0; }
.quote figcaption { display: flex; align-items: center; gap: var(--space-sm-2); }
.quote__avatar { display: grid; place-items: center; width: 48px; height: 48px; flex-shrink: 0; border-radius: var(--radius-full); background: var(--bg-stone); font-weight: var(--fw-medium); color: var(--text-primary); }
.on-dark .quote__avatar { background: var(--bg-inverse-soft); color: var(--text-inverse); }

/* ==========================================================================
   23. Rangée de clients [Dérivé], <ul class="logo-row" role="list"><li>Tasso</li>…</ul>
   Logo en SVG quand on l'a : <li><span class="logo-row__logo" role="img" aria-label="Bloomlife" style="-webkit-mask-image:url(…);mask-image:url(…);--logo-ratio:148/28"></span></li>.
   Le SVG sert de masque, rempli de la couleur du texte : tous les logos ont la même teinte discrète que les noms.
   Sans SVG (Tasso, WishBone, MexBrain, Guerbet au 4 novembre 2026), le nom en texte. Usage soumis à l'accord des clients.
   ========================================================================== */
.logo-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xl) var(--stack-m);   /* écart doublé (demande du 4 novembre 2026) */ margin: 0; font-size: var(--fs-h5); line-height: var(--lh-h5); font-weight: var(--fw-medium); letter-spacing: var(--ls-small); color: var(--text-muted); }
.on-dark .logo-row { color: var(--text-muted-inverse); }
.logo-row__logo {
  display: block; height: var(--logo-h-row, 28px); aspect-ratio: var(--logo-ratio); background: currentColor;
  -webkit-mask: center / contain no-repeat; mask: center / contain no-repeat;
  /* l'image du masque est posée dans le style de la page (mask-image), jamais par une variable : une url() passée par
     une variable se résout depuis cette feuille (design-system/), pas depuis la page, et le logo disparaît */
}

/* ==========================================================================
   24. Hero plein cadre [Relevé, Figma 24630:10333, corrections du 3 novembre 2026]
   <section class="hero-full"><figure class="media media--hero-bg hero-full__media"><video class="hero-full__video">
   <span class="hero-full__reflet"></span><div class="media__inner"><div class="container hero-full__content">…
   Photo plein cadre sous deux dégradés bleus (lisibilité du texte blanc en bas à gauche) et un reflet lumineux en
   lumière douce. Plein écran (100 % de la hauteur, 600 px au moins). Vidéo en boucle (.hero-full__video) à la place de la photo. Titre blanc sur trois lignes, une
   ligne courte, deux boutons ; à droite, une paire de cartes accolées : une trame animée (.hero-card--dither,
   js/covartim.js), une carte sombre floutée. Avec le header data-variant="hero". Une seule fois par page, en tête.
   ========================================================================== */
.hero-full { --screen-max: var(--screen-max-wide); position: relative; isolation: isolate; }   /* aligné sur le header */
.hero-full > .media { --media-ratio: auto; min-height: max(600px, calc(100dvh / var(--zoom))); border-radius: 0; }   /* plein écran (demande du 3 novembre 2026) */
.hero-full .media__inner {
  position: relative; min-height: inherit; justify-content: flex-end;
  padding: calc(var(--header-h) + 40px + var(--pad-2xl)) 0 var(--stack-l);   /* 168 en haut, 120 en bas [Relevé] */
}
/* Fond de secours si la photo ne charge pas */
.media--hero-bg { background: linear-gradient(180deg, var(--color-teal-700), var(--color-navy-950)); }
.hero-full__video { object-position: 70% 30%; }
/* Vidéo de fond : montage de 17,6 s (assets/video, 1920 et 1280 px, sans son), en boucle, sous les dégradés et le reflet.
   Bouton pause obligatoire (WCAG 2.2.2) ; à l'arrêt sur l'image d'attente en mouvement réduit (js/covartim.js). */
.hero-full__video { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; }
.hero-full__pause { --btn-py: 20px; --btn-fg: rgb(255 255 255 / .7); --btn-bd: var(--glass-border); align-self: center; }   /* discret, à côté des boutons (demande du 3 novembre 2026) : rond de 56 px, la hauteur des boutons lg ; icône de 16 px */
@media (hover: hover) and (pointer: fine) { .hero-full__pause:hover { --btn-bg: var(--hover-fill-inverse); --btn-bd: var(--hover-fill-inverse); --btn-fg: var(--hover-fill-inverse-fg); } }
.hero-full__pause .icon { --icon-size: var(--icon-s); }
/* Deux dégradés relevés : navy en bas à gauche (sous le texte), bleu en haut à droite */
.hero-full__media::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(63.7deg, rgb(15 15 50) 3%, rgb(46 46 152 / .5) 32%, rgb(46 46 152 / 0) 61%),
    linear-gradient(241.8deg, rgb(21 15 50 / 0) 29%, rgb(88 123 225 / .5) 64%, rgb(0 44 121) 100%);
}
/* Reflet tourné de −90° (demande du 3 novembre 2026) : le calque a la hauteur du hero en largeur et la largeur de l'écran
   en hauteur, puis pivote autour de son centre ; il couvre ainsi tout le hero une fois tourné. */
.hero-full__reflet {
  position: absolute; left: 50%; top: 50%; z-index: -1; pointer-events: none; opacity: .8; mix-blend-mode: soft-light;   /* 80 % (50 % dans Figma) : plus visible, demande du 3 novembre 2026 */
  width: calc(max(600px, calc(100dvh / var(--zoom))) * 1.6); height: calc(100vw / var(--zoom)); translate: -50% calc(-50% + 140px); rotate: -90deg;   /* descendu de 140 px ; calque agrandi pour couvrir encore le haut */
  background: url("assets/img/hero-reflet.jpg") center / cover no-repeat;   /* reflet provisoire extrait de Figma, à remplacer par le fichier HD */
  /* Masque alpha : plein à gauche, effacé à droite pour dégager la photo. Le calque est tourné de −90°, son bas est donc
     la droite de l'écran : le dégradé va de haut en bas. */
  -webkit-mask-image: linear-gradient(to bottom, #000 25%, transparent 70%);
          mask-image: linear-gradient(to bottom, #000 25%, transparent 70%);
}
.hero-full__content { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-2xl); width: 100%; }
.hero-full__text { display: flex; flex-direction: column; gap: var(--space-2xl); max-width: 640px; }   /* 580 relevés + marge */
.hero-full__title { font-size: var(--fs-hero); line-height: var(--lh-hero); font-weight: var(--fw-light); letter-spacing: -0.045em; color: var(--text-inverse); }
.hero-full__title > span { display: block; }   /* une ligne par segment, comme dans Figma */
.hero-full__foot { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3xl); }
.hero-full__line { font-size: var(--fs-4); line-height: var(--lh-4); color: var(--text-body-inverse); }

/* Paire de cartes : 2 × 184 px, hauteur 171 (−10 % sur Figma), rayon 12 à l'extérieur seulement [Relevé, Figma 24630:10355] */
.hero-full__cards { display: flex; }
.hero-card {
  position: relative; display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-m);
  width: 184px; min-height: 171px; padding: var(--pad-m-2); color: var(--text-inverse); overflow: clip;   /* 204 × 190 relevés, −10 % (demande du 3 novembre 2026) */
}
.hero-card:first-child { border-radius: var(--radius-card) 0 0 var(--radius-card); }
.hero-card:last-child { border-radius: 0 var(--radius-card) var(--radius-card) 0; background: rgb(0 24 41 / .7); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.hero-card__title { font-size: var(--fs-4); line-height: 23px; font-weight: var(--fw-medium); letter-spacing: var(--ls-small); }
.hero-card > .btn { align-self: flex-start; }
/* Carte tramée : dégradé teal dessiné et tramé (Bayer 8 × 8, points de 3 px) dans un <canvas> ; des points apparaissent
   et disparaissent en continu. Image fixe en mouvement réduit, animation suspendue hors écran. */
.hero-card--dither { padding: 0; }
.hero-card--dither canvas { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; }   /* opaque (82 % dans Figma) : la vidéo ne transparaît plus, demande du 3 novembre 2026 */
@media (min-width: 1025px) {
  .hero-full__content { flex-wrap: nowrap; }   /* texte et cartes toujours côte à côte */
  .hero-full__text { flex: 1 1 auto; min-width: 0; }
  .hero-full__cards { flex-shrink: 0; }
  .hero-full__title { font-size: min(var(--fs-hero), calc(5.4vw / var(--zoom))); line-height: 1; }   /* trois lignes jusqu'à 1025 px */
}
@media (max-width: 1024px) { .hero-full__cards { display: none; } }   /* sous 1024 px, le titre et les deux actions suffisent */
@media (max-width: 640px) {
  .hero-full > .media { min-height: max(520px, calc(100svh / var(--zoom))); }
  .hero-full .media__inner { padding-bottom: var(--stack-s); }
  .hero-full__foot { gap: var(--space-xl); }
}

/* ==========================================================================
   25. Carte de domaine « Liseré » [Dérivé, prototype choisi le 4 novembre 2026, préférée à « Brume » pour sa légèreté ; remplace la carte blanche relevée Figma 24627:12315]
   <a class="domain-card" style="--pict-tint:var(--color-teal-200);--dot-tint:var(--color-teal-500)">
     <span class="domain-card__top"><span class="domain-card__tag">IEC 62304</span><span class="domain-card__go" aria-hidden="true">…flèche…</span></span>
     <span class="domain-card__foot"><span class="domain-card__title">…</span><span class="domain-card__text"><span>…</span></span></span></a>
   Carte blanche : le pastel de la famille (--pict-tint) n'occupe qu'un bandeau en haut et s'efface vers le blanc
   (dégradé de haut en bas interpolé en oklab, sans cassure), texte navy ; au survol le bandeau s'agrandit. Trame de points (--dot-tint, ton 500 de la famille) dessinée en canvas par js/covartim.js :
   au passage de la souris, les points proches s'écartent du pointeur et grossissent, puis reviennent en place.
   Au survol ou au focus, la description se déploie et la flèche se remplit (survol unifié). Ouverte d'office sous 640 px
   et en .domain-card--open ; .is-demo-hover fige l'état survolé (style guide).
   ========================================================================== */
.domain-card {
  position: relative; isolation: isolate; overflow: clip; display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-l);
  min-height: 390px; padding: var(--pad-xl); border-radius: var(--radius-card); color: var(--text-primary); text-decoration: none;
  background: linear-gradient(180deg, color-mix(in srgb, var(--pict-tint, var(--color-teal-200)) 90%, var(--bg-raised)) 0%, var(--bg-raised) 34%);
  background: linear-gradient(180deg in oklab, color-mix(in oklab, var(--pict-tint, var(--color-teal-200)) 90%, var(--bg-raised)) 0%, var(--bg-raised) 34%);
  transition: transform var(--dur-press) var(--ease-out);
}
.domain-card:active { transform: scale(.98); }
.domain-card__dots { position: absolute; inset: 0; z-index: -1; display: block; width: 100%; height: 100%; pointer-events: none; color: var(--dot-tint, var(--text-muted)); opacity: .26; transition: opacity 300ms var(--ease-out);
  -webkit-mask: linear-gradient(180deg, #000 0%, transparent 30%); mask: linear-gradient(180deg, #000 0%, transparent 30%); }   /* trame confinée au bandeau */
.domain-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-m); }
.domain-card__tag {
  display: inline-flex; align-items: center; height: 32px; padding-inline: var(--pad-smm); white-space: nowrap;
  border: 1px solid color-mix(in oklab, var(--pict-tint, var(--color-teal-200)) 40%, var(--border-default)); border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--bg-raised) 70%, transparent); font-size: var(--fs-1); line-height: 20px; font-weight: var(--fw-medium);
}
.domain-card__go { display: grid; place-items: center; width: 40px; height: 40px; flex-shrink: 0; border-radius: var(--radius-full); background: color-mix(in srgb, var(--bg-raised) 70%, transparent); transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }
.domain-card__go .icon { --icon-size: var(--icon-s); }
.domain-card__foot { display: flex; flex-direction: column; }
.domain-card__title { display: block; font-size: var(--fs-card); line-height: var(--lh-card); font-weight: var(--fw-medium); letter-spacing: var(--ls-small); text-wrap: balance; }
.domain-card__text { display: grid; grid-template-rows: 0fr; opacity: 0; color: var(--text-body); font-size: var(--fs-2); line-height: var(--lh-2); transition: grid-template-rows var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out); }
.domain-card__text > span { overflow: hidden; }
.domain-card__text > span::before { content: ""; display: block; height: var(--space-sm); }
.domain-card:is(:hover, :focus-visible, .is-demo-hover) .domain-card__text { grid-template-rows: 1fr; opacity: 1; }
.domain-card:is(:hover, .is-demo-hover) .domain-card__dots { opacity: .36; }
.domain-card:is(:hover, :focus-visible, .is-demo-hover) { background: linear-gradient(180deg in oklab, var(--pict-tint, var(--color-teal-200)) 0%, var(--bg-raised) 52%); }
.domain-card:is(:hover, :focus-visible, .is-demo-hover) .domain-card__go { background: var(--hover-fill); color: var(--hover-fill-fg); }
.domain-card:focus-visible { outline: 2px solid var(--focus-outline); outline-offset: 2px; }
@media (max-width: 640px) { .domain-card__text { grid-template-rows: 1fr; opacity: 1; } }
.domain-card--open .domain-card__text { grid-template-rows: 1fr; opacity: 1; }   /* page Domaines : description toujours visible, la carte mène à la fiche du domaine */
.domain-card--open { scroll-margin-top: calc(var(--header-h) + var(--space-l)); }
@media (max-width: 640px) { .domain-card { min-height: 320px; } }

/* ==========================================================================
   26. En-tête de page intérieure [Dérivé, wireframe 24620:4977 et suivants], <header class="page-head">
   Fil d'Ariane, sur-titre de rubrique, grand titre fin bicolore à gauche, chapô aligné en bas à droite.
   Le wireframe empile tout en une colonne de 768 px ; ici le titre prend 7/12 et le chapô 5/12, pour une entrée éditoriale.
   ========================================================================== */
.page-head { padding-block: var(--space-xl) var(--stack-m); }   /* fil d'Ariane rapproché du header (demande du 4 novembre 2026) ; la section suivante est en .section--flush-top : 80 px entre l’en-tête et le contenu */
.page-head__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl) var(--space-5xl); align-items: end; }   /* mêmes colonnes que .layout-split : le chapô s'aligne sur la colonne droite du contenu, son bas sur la ligne de base du titre (demande du 4 novembre 2026) */
.page-head__title { display: flex; flex-direction: column; gap: var(--space-l); align-self: start; }   /* sur-titre et titre toujours à la même hauteur d'une page à l'autre, quelle que soit la longueur du chapô (demande du 4 novembre 2026) ; le chapô reste calé en bas s'il est plus court que le titre */
.page-head__lead { display: flex; flex-direction: column; gap: var(--space-l); align-items: flex-start; max-width: 52ch; padding-bottom: .4em; }
.page-head__media { margin-top: var(--stack-s); --media-ratio: 21 / 9; }
/* Variante photo (fiches domaine, demande du 4 novembre 2026) : sur-titre, titre, chapô, normes et bouton empilés à gauche,
   photo 4:3 à droite, calée en haut avec le sur-titre */
.page-head__grid--media { align-items: start; }
.page-head__grid--media .page-head__title > .lead { max-width: 52ch; }
.page-head__grid--media .cluster { margin-top: calc(var(--space-sm) * -1); }
.page-head__photo { --media-ratio: 4 / 3; }
@media (max-width: 1024px) {
  .page-head__grid { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .page-head__media { --media-ratio: 16 / 9; }
}

/* Fil d'Ariane : séparateur « / » en texte atténué (jamais de point), page courante non cliquable */
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-sm); margin: 0; padding: 0; list-style: none; font-size: var(--fs-1); line-height: var(--lh-1); color: var(--text-muted); }
.page-head .breadcrumb { margin-bottom: var(--stack-m); }   /* petit (12 px) et nettement détaché du sur-titre : 100 px à 1920, 50 en mobile (demandes du 3 et du 4 novembre 2026) */
.breadcrumb li { display: inline-flex; gap: var(--space-sm); }
.breadcrumb li + li::before { content: "/"; color: var(--text-tone); }
.breadcrumb a { color: var(--text-body); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .breadcrumb a:hover { color: var(--text-primary); text-decoration: underline; text-underline-offset: 3px; } }
.breadcrumb [aria-current] { color: var(--text-primary); }

/* ==========================================================================
   27. Étapes numérotées [Dérivé, wireframe 24620:4997], <ol class="steps" role="list"><li><span class="steps__num">01</span>…</li></ol>
   Grand chiffre fin en ton atténué, filet au-dessus, titre et texte. Pas de pastille ni de rond.
   ========================================================================== */
.steps { display: grid; grid-template-columns: repeat(var(--steps, 3), minmax(0, 1fr)); gap: var(--space-3xl) var(--grid-gap); margin: 0; padding: 0; list-style: none; }
/* Couleur (demande du 4 novembre 2026) : numéro et amorce du filet dans la teinte de l'expertise, comme les tags
   (data-tone="teal|sky|navy|lime|sun", donnée de teinte) ; vert de titre par défaut. */
.steps { --steps-tone: var(--text-heading); }
.steps--4 { --steps: 4; }   /* fiche domaine : quatre volets ; repasse à une colonne sous 1024 (règle plus bas) */
.steps[data-tone="teal"] { --steps-tone: var(--color-teal-600); }
.steps[data-tone="sky"] { --steps-tone: var(--color-sky-700); }
.steps[data-tone="navy"] { --steps-tone: var(--color-navy-700); }
.steps[data-tone="lime"] { --steps-tone: var(--color-lime-700); }
.steps[data-tone="sun"] { --steps-tone: var(--color-sun-700); }
.steps[data-tone="lilac"] { --steps-tone: var(--color-lilac-600); }   /* produits combinés (teinte de leur carte de domaine) */
/* Fiches domaine : teintes vives (demande du 4 novembre 2026) ; chiffres et filets décoratifs (aria-hidden), en grand.
   Couleurs pures de la charte quand elles existent ; Équipements (navy, terne en ton moyen) prend l'ocean de la charte. */
.steps--vivid[data-tone="teal"]  { --steps-tone: var(--color-teal-600); }
.steps--vivid[data-tone="lime"]  { --steps-tone: var(--color-lime-500); }
.steps--vivid[data-tone="navy"]  { --steps-tone: var(--color-ocean-600); }
.steps--vivid[data-tone="sun"]   { --steps-tone: var(--color-sun-400); }
.steps--vivid[data-tone="sky"]   { --steps-tone: var(--color-sky-400); }
.steps--vivid[data-tone="lilac"] { --steps-tone: var(--color-lilac-vivid); }
.steps > li { position: relative; display: flex; flex-direction: column; gap: var(--space-sm-2); padding-top: var(--space-l); border-top: 1px solid var(--border-default); }
.steps > li::before { content: ""; position: absolute; top: -2px; left: 0; width: 64px; height: 3px; border-radius: var(--radius-full); background: var(--steps-tone); }
.steps__num { font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: var(--fw-light); letter-spacing: var(--ls-title); color: var(--steps-tone); font-variant-numeric: tabular-nums; margin-bottom: var(--space-sm); }
.section--dark .steps > li, .on-dark .steps > li { border-top-color: var(--border-inverse); }
.section--dark .steps, .on-dark .steps { --steps-tone: var(--text-heading-inverse); }
@media (max-width: 1024px) { .steps { --steps: 1; gap: var(--space-xl); } }

/* ==========================================================================
   29. Liste de blocs texte [Dérivé, wireframe 24620:5027], <div class="rule-list"><div><h3>…</h3><p>…</p></div>…</div>
   Titre et paragraphe séparés par des filets ; sert à « Notre approche » et aux accréditations.
   ========================================================================== */
.rule-list { display: flex; flex-direction: column; }
.rule-list > * { display: grid; gap: var(--space-sm-2); padding-block: var(--space-xl); border-top: 1px solid var(--border-default); }
.rule-list > :first-child { padding-top: 0; border-top: 0; }
.rule-list > :last-child { padding-bottom: 0; }
.rule-list p { max-width: 64ch; }   /* longueur de ligne confortable dans une colonne 7/12 */
/* Variante compacte (fiches domaine, cadre de référence) : deux colonnes, filets plus serrés */
.rule-list--compact { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-2xl); }
.rule-list--compact > * { gap: var(--space-xs); padding-block: var(--space-l); }
.rule-list--compact > :nth-child(-n+2) { padding-top: 0; border-top: 0; }
.rule-list--compact > :last-child { padding-bottom: var(--space-l); }
@media (max-width: 640px) {
  .rule-list--compact { grid-template-columns: minmax(0, 1fr); }
  .rule-list--compact > :nth-child(2) { padding-top: var(--space-l); border-top: 1px solid var(--border-default); }
}
/* Ligne avec repère à gauche (accréditations : sigle de l'organisme) */
.rule-list--mark > * { grid-template-columns: 148px minmax(0, 1fr); column-gap: var(--space-xl); align-items: start; }
.rule-list--mark > * > :not(.rule-list__mark) { grid-column: 2; }
.rule-list__mark { grid-row: 1 / span 4; display: grid; place-items: center; height: 80px; border-radius: var(--radius-card); background: var(--bg-card); font-size: var(--fs-h6); font-weight: var(--fw-medium); letter-spacing: var(--ls-small); color: var(--text-primary); }
.rule-list__mark img { width: 62%; height: auto; max-height: 44%; }   /* logo officiel de l'organisme quand il existe en SVG (Bpifrance) ; sinon le sigle en texte */
@media (max-width: 640px) {
  .rule-list--mark > * { grid-template-columns: minmax(0, 1fr); }
  .rule-list--mark > * > :not(.rule-list__mark) { grid-column: 1; }
  .rule-list__mark { grid-row: auto; width: 120px; height: 64px; }
}

/* ==========================================================================
   30. Atout [Dérivé, wireframe 24620:5048 et 24620:5072], <div class="feature"><span class="icon-tile">…</span><h3 class="h6">…</h3><p>…</p></div>
   ========================================================================== */
.feature { display: flex; flex-direction: column; gap: var(--space-sm-2); align-items: flex-start; }
.feature .icon-tile { margin-bottom: var(--space-sm); }

/* ==========================================================================
   31. Citation centrée [Dérivé, wireframe 24620:4981], <figure class="quote quote--center">
   ========================================================================== */
.quote--center { align-items: center; text-align: center; margin-inline: auto; max-width: 1040px; }
.quote--center .statement { max-width: 32ch; text-wrap: balance; }
.quote--center figcaption { flex-direction: column; gap: var(--space-sm); text-align: center; }   /* auteur empilé et centré sous la citation : pastille, nom, fonction (demande du 4 novembre 2026) */
.quote--center figcaption > span:last-child { line-height: var(--lh-3); }

/* ==========================================================================
   32. Membre de l'équipe [Dérivé, wireframe 24620:5085], <article class="person">
   Pas de photo pour l'instant : carré mist avec les initiales en grand corps fin (à remplacer par les portraits).
   ========================================================================== */
.person { display: flex; flex-direction: column; gap: var(--space-xs); min-width: 0; }
.person__photo { display: grid; place-items: center; aspect-ratio: 1; margin-bottom: var(--space-sm-2); border-radius: var(--radius-card); background: var(--bg-card); overflow: hidden;
  font-size: var(--fs-h3); line-height: 1; font-weight: var(--fw-light); letter-spacing: var(--ls-title); color: var(--text-tone); }
.person__photo img { width: 100%; height: 100%; object-fit: cover; }
.person__name { font-size: var(--fs-4); line-height: var(--lh-4); font-weight: var(--fw-medium); color: var(--text-primary); }
.person__role { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }

/* ==========================================================================
   33. Offre d'emploi [Dérivé, wireframe 24620:5064], <article class="job-row">
   Ligne cliquable (lien étiré) : intitulé + étiquette, phrase, lieu et contrat ; rond fléché à droite.
   ========================================================================== */
.job-list { border-top: 1px solid var(--border-default); }
.job-row { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-sm-2) var(--space-xl); align-items: center; padding-block: var(--space-xl); border-bottom: 1px solid var(--border-default); }
.job-row__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm) var(--space-m); }
.job-row__meta { display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-l); font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }
.job-row__meta > span { display: inline-flex; align-items: center; gap: var(--space-xs); }
.job-row > :not(.link-arrow__icon) { grid-column: 1; }
.job-row > .link-arrow__icon { grid-column: 2; grid-row: 1 / span 3; }
@media (hover: hover) and (pointer: fine) {
  .job-row:hover .link-arrow__icon { background: var(--hover-fill); color: var(--hover-fill-fg); }
}

/* ==========================================================================
   34. Pagination [Dérivé, wireframe 24620:5325], <nav class="pagination" aria-label="Pagination">
   Précédent / numéros / Suivant ; la page courante est une pilule navy (aria-current), les numéros des ronds de 44 px.
   ========================================================================== */
.pagination { display: flex; align-items: center; justify-content: space-between; gap: var(--space-m); padding-top: var(--space-xl); border-top: 1px solid var(--border-default); }
.pagination__pages { display: flex; align-items: center; gap: var(--space-xs); margin: 0; padding: 0; list-style: none; }
.pagination__pages a, .pagination__pages span { display: grid; place-items: center; min-width: var(--tap-min); height: var(--tap-min); padding-inline: var(--space-sm); border-radius: var(--radius-full); font-size: var(--fs-2); font-weight: var(--fw-medium); color: var(--text-primary); text-decoration: none; font-variant-numeric: tabular-nums; }
.pagination__pages [aria-current="page"] { background: var(--action-primary); color: var(--text-inverse); }
.pagination__pages span { color: var(--text-muted); }
@media (hover: hover) and (pointer: fine) { .pagination__pages a:not([aria-current]):hover { background: var(--bg-card); } }
@media (max-width: 640px) {
  .pagination__pages li:not(:has([aria-current])):not(:first-child):not(:last-child) { display: none; }   /* téléphone : première, courante, dernière */
  .pagination .btn__label { display: none; }
}

/* ==========================================================================
   35. Grille de cas clients [Dérivé, wireframe 24620:5325], <div class="case-grid"> de .case-row
   Deux colonnes de lignes horizontales ; filet au-dessus de chaque ligne. Une colonne sous 1024 px.
   ========================================================================== */
.case-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-3xl); }
.case-grid > .case-row { padding-block: var(--space-xl); border-bottom: 0; border-top: 1px solid var(--border-default); grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-l); }
.case-grid > .case-row .case-row__body > p { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

@media (max-width: 1024px) { .case-grid { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .case-grid > .case-row { grid-template-columns: minmax(0, 1fr); } }
.filter-bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-m); margin-bottom: var(--space-2xl); }
.filter-bar .field { width: min(100%, 320px); }
.filter-bar__count { margin-left: auto; padding-bottom: 14px; }   /* compteur aligné sur la base des champs */
@media (max-width: 640px) {
  .filter-bar .field { width: 100%; }
  .filter-bar__count { margin-left: 0; padding-bottom: 0; }
  .case-grid > .case-row .media { --media-ratio: 16 / 9; }
}

/* ==========================================================================
   36. Bloc de coordonnées [Dérivé, wireframe 24620:5320], <div class="contact-block">
   ========================================================================== */
.contact-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2xl) var(--space-xl); }
.contact-block { display: flex; flex-direction: column; gap: var(--space-xs); align-items: flex-start; }
.contact-block .icon-tile { margin-bottom: var(--space-sm-2); }
.contact-block address { font-style: normal; color: var(--text-muted); }
@media (max-width: 640px) { .contact-grid { grid-template-columns: minmax(0, 1fr); } }

/* Panneau de formulaire : gris mist, rayon 24 ; ses champs (12) restent concentriques à l'œil grâce à la marge de 40 */
.form-panel { --panel-radius: var(--radius-xl); --panel-pad: var(--pad-2xl); padding: var(--panel-pad); border-radius: var(--panel-radius); background: var(--bg-muted); }
@media (max-width: 640px) { .form-panel { --panel-pad: var(--pad-l); } }

/* ==========================================================================
   37. Dépôt de fichier [Dérivé, wireframe 24620:5320], <label class="file-drop"><input type="file">…</label>
   L'input reste dans la zone (clavier, lecteurs d'écran), visuellement masqué ; le nom du fichier choisi s'affiche (js).
   ========================================================================== */
.file-drop { position: relative; display: flex; align-items: center; gap: var(--space-m); padding: var(--pad-m); border: 1px dashed var(--border-control); border-radius: var(--radius-field); background: var(--bg-field); cursor: pointer; transition: border-color var(--dur-fast) var(--ease-out), background-color var(--dur-fast) var(--ease-out); }
.file-drop input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.file-drop:focus-within { border-style: solid; border-color: var(--border-strong); box-shadow: var(--focus-ring); }
.file-drop.is-dragover { border-color: var(--border-strong); background: var(--bg-brand-soft); }
@media (hover: hover) and (pointer: fine) { .file-drop:hover { border-color: var(--border-control-hover); } }
.file-drop__text { display: flex; flex-direction: column; font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }
.file-drop__text b { font-weight: var(--fw-medium); color: var(--text-primary); }

/* Bandeau centré (candidature, projet similaire) : variante du bandeau d'appel à l'action */
.cta-band--center { text-align: center; }
.cta-band--center > .stack { align-items: center; margin-inline: auto; max-width: 720px; }

/* ==========================================================================
   38. Comparaison en lignes [Dérivé, wireframe 24620:4979, piste C choisie le 3 novembre 2026] : <div class="compare">
   Deux offres qui se répondent point par point, comme un tableau sans cadre : thème à gauche, une cellule par offre.
   Ordre du balisage : en-tête (vide, offre 1, offre 2), puis par ligne (thème, cellule 1, cellule 2), puis pied (vide, lien 1, lien 2).
   Sous 1024 px, la colonne des thèmes disparaît et les deux offres restent face à face.
   ========================================================================== */
.compare { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 4fr) minmax(0, 4fr); column-gap: var(--space-2xl); }
.compare > * { min-width: 0; padding-block: var(--space-l); border-top: 1px solid var(--border-default); }
.compare__head { display: flex; flex-direction: column; gap: var(--space-sm); padding-top: 0; border-top: 0; }
.compare__key { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }
.compare__cell { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted); }
.compare__cell b { display: block; margin-bottom: 2px; font-size: var(--fs-3); line-height: var(--lh-3); font-weight: var(--fw-medium); color: var(--text-primary); }
.compare__foot { border-top: 0; }
@media (max-width: 1024px) {
  .compare { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .compare__key, .compare > .compare__blank { display: none; }
}
@media (max-width: 640px) {
  .compare { column-gap: var(--space-m); }
  .compare__head > :is(h2, h3, h4) { font-size: var(--fs-h6); line-height: var(--lh-h6); font-weight: var(--fw-medium); }   /* deux colonnes de 150 px : à 28 px, « Accompagnement » se coupait au milieu du mot ; à 18 px, il tient */
  .compare__head p, .compare__cell { hyphens: auto; }
  .compare__foot .link-arrow { white-space: normal; gap: var(--space-sm); }
  .compare__foot .link-arrow__icon { flex-shrink: 0; width: 36px; height: 36px; }   /* « Résoudre ma problématique » tient dans la colonne à 360 px */
}

/* ==========================================================================
   Mouvement réduit
   ========================================================================== */
/* ==========================================================================
   39. Chiffres en croix [Dérivé, corrections du 4 novembre 2026], <ul class="stat-cross" role="list"><li><span class="stat-cross__value">15+</span><span class="stat-cross__label">…</span></li>…</ul>
   Quatre chiffres en 2 × 2, séparés par une croix centrale : filet vertical entre les colonnes, horizontal entre les
   rangées, rien sur les bords. Sans picto. Chiffres à 80 % du h1.
   ========================================================================== */
.stat-cross { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; padding: 0; list-style: none; }
.stat-cross > li { display: flex; flex-direction: column; gap: var(--space-sm); padding: var(--space-2xl) var(--space-3xl); }
.stat-cross > li:nth-child(odd) { padding-left: 0; border-right: 1px solid var(--border-default); }
.stat-cross > li:nth-child(even) { padding-right: 0; }
.stat-cross > li:nth-child(-n+2) { padding-top: 0; border-bottom: 1px solid var(--border-default); }
.stat-cross > li:nth-child(n+3) { padding-bottom: 0; }
:is(.section--dark, .on-dark) .stat-cross > li { border-color: var(--border-inverse); }
.stat-cross__value { font-size: calc(var(--fs-h1) * .8); line-height: 1.05; font-weight: var(--fw-light); letter-spacing: var(--ls-title); font-variant-numeric: tabular-nums; white-space: nowrap; }
.stat-cross__label { color: var(--text-body); }
:is(.section--dark, .on-dark) .stat-cross__label { color: var(--text-body-inverse); }
@media (max-width: 640px) { .stat-cross > li { padding: var(--space-l); } }

/* ==========================================================================
   40. Preuves et globe [Dérivé, prototype « Horizon » du 4 novembre 2026], section sombre de l'accueil
   <section class="section section--xl section--dark on-dark proof"> : .proof__top (titre | .stat-cross), .proof__logos
   (.logo-row--spread), puis <div class="globe" data-globe data-src="…/content/preuves.md" data-land="…/assets/data/land-dots.json">.
   Le globe (js/globe.js) est un dôme pleine largeur coupé par le bas de la section : halo bleu, aurore verte, terres en
   pointillés, épingles clients ; une épingle ouvre l'avis dans une carte floutée (feuille en bas d'écran sur mobile).
   Contenu : content/preuves.md (format destiné au CMS). Couleurs du canvas : dans js/globe.js (dessin, pas interface).
   ========================================================================== */
.proof { padding-bottom: 0; overflow: clip; }
.proof__top { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: var(--space-3xl) var(--space-5xl); align-items: start; }
.proof__logos { display: flex; flex-direction: column; gap: var(--space-l); margin-top: var(--stack-m); }
.logo-row--spread { justify-content: space-between; column-gap: var(--space-xl); }   /* logos répartis sur toute la largeur du contenu */
@media (max-width: 1024px) { .proof__top { grid-template-columns: minmax(0, 1fr); } }

.globe {
  position: relative; margin-top: var(--space-xl); cursor: grab; touch-action: none;
  width: calc(100vw / var(--zoom)); margin-left: calc(50% - 50vw / var(--zoom));   /* pleine largeur : le halo n'est pas coupé */
}
.globe:active { cursor: grabbing; }
@media (pointer: coarse) { .globe { touch-action: pan-y; } }   /* au doigt, le glisser vertical reste au défilement de la page */
.globe canvas { display: block; width: 100%; height: 100%; -webkit-mask: linear-gradient(transparent, #000 22%); mask: linear-gradient(transparent, #000 22%); }
.globe::after { content: ""; position: absolute; inset: auto 0 0; z-index: 1; height: 38%; background: linear-gradient(transparent, var(--bg-dark) 92%); pointer-events: none; }   /* le bas du globe se fond dans le navy */
.globe__pin {
  position: absolute; z-index: 2; display: grid; place-items: center; width: var(--tap-min); height: var(--tap-min); margin: calc(var(--tap-min) / -2) 0 0 calc(var(--tap-min) / -2);
  padding: 0; border: 0; border-radius: var(--radius-full); background: transparent; cursor: pointer; transition: opacity var(--dur-fast) var(--ease-out);
}
.globe__pin::before { content: ""; position: absolute; width: 22px; height: 22px; border-radius: var(--radius-full); background: color-mix(in srgb, var(--action-accent) 18%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--action-accent) 50%, transparent); transition: scale var(--dur-fast) var(--ease-out); }
.globe__pin::after { content: ""; position: relative; width: 8px; height: 8px; border-radius: var(--radius-full); background: var(--action-accent); }   /* repère de carte (indicateur), pas une puce décorative */
.globe__pin[aria-expanded="true"]::before { scale: 1.45; background: color-mix(in srgb, var(--action-accent) 30%, transparent); }
@media (hover: hover) and (pointer: fine) { .globe__pin:hover::before { scale: 1.3; } }
.globe__pin:focus-visible { outline: none; }
.globe__pin:focus-visible::before { box-shadow: 0 0 0 2px var(--action-accent); }
.globe__pin[data-back] { pointer-events: none; }   /* opacité gérée en continu par js/globe.js (fondu au bord du globe) */
.globe__tip { position: absolute; left: 50%; bottom: calc(100% - 6px); translate: -50% 0; white-space: nowrap; font-size: var(--fs-1); line-height: var(--lh-1); color: var(--text-muted-inverse); pointer-events: none; }
/* Avis : carte transparente floutée, posée au-dessus de l'épingle */
.globe__card {
  position: absolute; z-index: 3; width: min(400px, calc(100% - 2 * var(--gutter))); padding: var(--pad-xl);
  border: 1px solid color-mix(in srgb, var(--text-inverse) 14%, transparent); border-radius: var(--radius-xl);
  background: color-mix(in srgb, var(--text-inverse) 7%, transparent); -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  color: var(--text-inverse); box-shadow: 0 24px 60px rgb(0 0 0 / .35);
  transform-origin: var(--origin, 50% 100%); transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.globe__card[hidden] { display: block !important; visibility: hidden; opacity: 0; transform: scale(.96); pointer-events: none; transition: opacity 150ms var(--ease-out), transform 150ms var(--ease-out), visibility 0s 150ms; }
.globe__card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-m); margin-bottom: var(--space-m); }
.globe__card-client { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted-inverse); }
.globe__card-client strong { display: block; font-size: var(--fs-3); font-weight: var(--fw-medium); color: var(--text-inverse); }
.globe__card blockquote { margin: 0 0 var(--space-l); font-size: var(--fs-h5); line-height: var(--lh-h5); font-weight: var(--fw-light); letter-spacing: var(--ls-small); }
.globe__card figcaption { font-size: var(--fs-2); line-height: var(--lh-2); color: var(--text-muted-inverse); }
.globe__card figcaption strong { font-weight: var(--fw-medium); color: var(--text-inverse); }
.globe__card-close { flex-shrink: 0; --btn-bg: color-mix(in srgb, var(--text-inverse) 8%, transparent); --btn-bd: transparent; --btn-fg: var(--text-inverse); }
/* Visite guidée : compteur, précédent / suivant */
.globe__card-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-sm) var(--space-m); margin-top: var(--space-l); padding-top: var(--space-m); border-top: 1px solid color-mix(in srgb, var(--text-inverse) 14%, transparent); }
.globe__count { font-size: var(--fs-1); line-height: var(--lh-1); color: var(--text-muted-inverse); font-variant-numeric: tabular-nums; }
.globe__card-nav { display: flex; align-items: center; gap: var(--space-sm); }
.globe__card-nav .btn { --btn-bg: color-mix(in srgb, var(--text-inverse) 8%, transparent); --btn-bd: transparent; --btn-fg: var(--text-inverse); }
@media (hover: hover) and (pointer: fine) { .globe__card-nav .btn:hover { --btn-bg: var(--hover-fill-inverse); --btn-bd: var(--hover-fill-inverse); --btn-fg: var(--hover-fill-inverse-fg); } }
/* Mobile : l'avis s'ouvre en feuille depuis le bas de l'écran */
.globe__card.is-sheet { position: fixed; z-index: 60; inset: auto var(--space-sm) calc(var(--space-sm) + var(--safe-bottom)); width: auto; background: color-mix(in srgb, var(--bg-dark) 72%, transparent); transform-origin: 50% 100%; }
.globe__card.is-sheet[hidden] { transform: translateY(12px); }
/* Pause / lecture de l'animation (WCAG 2.2.2), en bas à droite du contenu, même style discret que la pause vidéo du hero */
.globe__pause { position: absolute; z-index: 4; bottom: var(--space-xl); --btn-fg: var(--text-muted-inverse); --btn-bd: var(--border-inverse); --btn-bg: transparent; }
@media (hover: hover) and (pointer: fine) { .globe__pause:hover, .globe__card-close:hover { --btn-bg: var(--hover-fill-inverse); --btn-bd: var(--hover-fill-inverse); --btn-fg: var(--hover-fill-inverse-fg); } }
.globe__pause .icon { --icon-size: var(--icon-s); }
@media (max-width: 640px) { .globe__tip { display: none; } }

/* ==========================================================================
   41. Cartes de cas « Vitrine » [Dérivé, prototype choisi le 4 novembre 2026], bloc « Exemples d'interventions »
   <div class="section-head">…</div><div class="case-cards"><article class="case-card"><figure class="media">…</figure>
   <span class="eyebrow">…</span><h3 class="h4"><a class="card__link">…</a></h3><p>…</p><div class="chip-row">…</div></article>…</div>
   Deux cas à égalité, grands visuels 16/10 ; toute la carte est cliquable (lien étiré), le visuel zoome légèrement au survol.
   ========================================================================== */
.case-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3xl) var(--grid-gap); }
.case-card { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-m); }
.case-card > .media { --media-ratio: 16 / 10; width: 100%; margin-bottom: var(--space-sm); }
.case-card > .media img { transition: transform 500ms var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .case-card:hover > .media img { transform: scale(1.03); } }
.case-card:has(.card__link:focus-visible) { outline: 2px solid var(--focus-outline); outline-offset: 6px; border-radius: var(--radius-xl); }
@media (max-width: 640px) { .case-cards { grid-template-columns: minmax(0, 1fr); } }


/* ==========================================================================
   42. Mouvement de continuité [Dérivé, 4 novembre 2026] : passage d'une page à l'autre, FAQ, filtres
   Pages : View Transitions entre documents (Chrome, Edge, Safari 18.2+ ; ailleurs, navigation normale). L'ancienne page
   s'efface vite, la nouvelle monte de 12 px ; le header (nom « site-header », posé par covartim.js) ne clignote plus. Filtres : html[data-vt="filtre"]
   (covartim.js), les cartes restantes glissent, la page ne fond pas. Mouvement réduit : fondus seulement.
   ========================================================================== */
@view-transition { navigation: auto; }
@keyframes vt-page-out { to { opacity: 0; } }
@keyframes vt-page-in { from { opacity: 0; transform: translateY(12px); } }
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: vt-page-out 160ms var(--ease-out) both; }
  ::view-transition-new(root) { animation: vt-page-in 360ms var(--ease-out) 60ms both; }
  ::view-transition-group(site-header) { animation-duration: 280ms; animation-timing-function: var(--ease-out); }
  html[data-vt="filtre"]::view-transition-group(*) { animation-duration: 340ms; animation-timing-function: var(--ease-out); }
}
html[data-vt="filtre"]::view-transition-old(root) { display: none; }
html[data-vt="filtre"]::view-transition-new(root) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*) { animation: none !important; }
}

/* Entrée du hero (accueil, demande du 4 novembre 2026), une seule séquence au chargement, en CSS seul (rien ne dépend du script) :
   les trois lignes du titre sortent du flou en montant, l'une après l'autre ; puis la ligne courte et les boutons ;
   la paire de cartes se découvre de gauche à droite (clip-path), le texte de la carte sombre arrive en dernier.
   1,7 s en tout ; remplissage « backwards » seulement, pour rendre ensuite la main aux survols et à la pression des boutons. Mouvement réduit : fondus seuls, plus courts. */
@keyframes hero-rise { from { opacity: 0; transform: translateY(.45em); filter: blur(8px); } }
@keyframes hero-up { from { opacity: 0; transform: translateY(14px); } }
@keyframes hero-wipe { from { clip-path: inset(0 100% 0 0 round var(--radius-card)); } to { clip-path: inset(0 0 0 0 round var(--radius-card)); } }
@keyframes hero-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .hero-full__title > span { animation: hero-rise 1000ms var(--ease-out) backwards; animation-delay: calc(150ms + var(--line, 0) * 120ms); }
  .hero-full__title > span:nth-child(2) { --line: 1; }
  .hero-full__title > span:nth-child(3) { --line: 2; }
  .hero-full__line { animation: hero-up 800ms var(--ease-out) 620ms backwards; }
  .hero-full__foot .cluster > * { animation: hero-up 800ms var(--ease-out) backwards; animation-delay: calc(720ms + var(--i, 0) * 70ms); }
  .hero-full__foot .cluster > :nth-child(2) { --i: 1; }
  .hero-full__foot .cluster > :nth-child(3) { --i: 2; }
  .hero-full__cards { animation: hero-wipe 900ms var(--ease-in-out) 800ms backwards; }
  .hero-card:last-child > * { animation: hero-up 700ms var(--ease-out) backwards; animation-delay: calc(1300ms + var(--i, 0) * 80ms); }
  .hero-card:last-child > :nth-child(2) { --i: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-full__title > span, .hero-full__line, .hero-full__foot .cluster > *, .hero-full__cards { animation: hero-fade 500ms linear backwards; }
  .hero-full__line, .hero-full__foot .cluster > *, .hero-full__cards { animation-delay: 200ms; }
}

/* Apparition des sections (covartim.js pose data-reveal sur les blocs encore sous l'écran, puis data-reveal="in") :
   fondu et montée de 16 px en 700 ms, une fois ; mouvement réduit : fondu seul, plus court */
[data-reveal] { transition: opacity 700ms var(--ease-out) var(--reveal-delay, 0ms), transform 700ms var(--ease-out) var(--reveal-delay, 0ms); }
[data-reveal=""] { opacity: 0; transform: translateY(16px); }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { transition: opacity 400ms linear var(--reveal-delay, 0ms); }
  [data-reveal=""] { transform: none; }
}
@media print { [data-reveal] { opacity: 1 !important; transform: none !important; } }

/* FAQ et colonnes du footer mobile : la réponse se déplie (hauteur jusqu'à « auto », Chrome 131+, sinon ouverture
   franche) et apparaît en fondu ; fermeture plus rapide que l'ouverture */
@supports (interpolate-size: allow-keywords) {
  @media (prefers-reduced-motion: no-preference) {
    .accordion { interpolate-size: allow-keywords; }
    .accordion::details-content { block-size: 0; overflow: clip; transition: block-size 200ms var(--ease-out), content-visibility 200ms allow-discrete; }
    .accordion[open]::details-content { block-size: auto; transition-duration: 320ms; }
  }
}
.accordion__body { transition: opacity 200ms var(--ease-out); }
.accordion:not([open]) .accordion__body { opacity: 0; }
.accordion[open] .accordion__body { transition-duration: 320ms; transition-delay: 40ms; @starting-style { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .site-footer__col a .icon, .nav-panel, .nav-panel[data-open], .nav-menu__trigger .icon, .drawer__group > summary .icon, .site-header, .site-header__logo,
  .drawer, .drawer__panel, .btn, .switch input, .switch input::before, .choice input, .choice input::before { transition: none !important; }
  .btn[aria-busy="true"]::before { animation-duration: 1.6s; }
  .btn:active, .link-arrow:active .link-arrow__icon { transform: none; }
  .media > img, .link-arrow__icon .icon, .domain-card, .domain-card__text, .domain-card__go, .domain-card__dots { transition: none !important; transform: none !important; }
  .domain-card:active { transform: none; }
  .card--service::before { transform: none !important; opacity: 0; transition: opacity var(--dur-base) linear !important; }
  .card--service:hover::before, .card--service:has(.card__link:focus-visible)::before { opacity: 1; }
  .card__more .icon { transition: none !important; transform: none !important; }
  .globe__card, .globe__card[hidden], .globe__pin::before { transition: none; }
  .case-card > .media img { transition: none; transform: none !important; }
}
