/* Polices auto-hébergées (licence SIL OFL 1.1) : Source Serif 4, IBM Plex Sans, IBM Plex Mono.
   Sous-ensembles latin et latin-ext. Généré par téléchargement unique, jamais d'appel à Google au chargement. */
@font-face{font-family:"Source Serif 4";font-style:italic;font-weight:400 700;font-display:swap;src:url("/assets/fonts/source-serif-4-italic-400-700-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:"Source Serif 4";font-style:italic;font-weight:400 700;font-display:swap;src:url("/assets/fonts/source-serif-4-italic-400-700-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400 700;font-display:swap;src:url("/assets/fonts/source-serif-4-normal-400-700-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:"Source Serif 4";font-style:normal;font-weight:400 700;font-display:swap;src:url("/assets/fonts/source-serif-4-normal-400-700-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"IBM Plex Sans";font-style:italic;font-weight:400;font-display:swap;src:url("/assets/fonts/ibm-plex-sans-italic-400-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:"IBM Plex Sans";font-style:italic;font-weight:400;font-display:swap;src:url("/assets/fonts/ibm-plex-sans-italic-400-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url("/assets/fonts/ibm-plex-sans-normal-400-700-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400 700;font-display:swap;src:url("/assets/fonts/ibm-plex-sans-normal-400-700-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/ibm-plex-mono-normal-400-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url("/assets/fonts/ibm-plex-mono-normal-400-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/fonts/ibm-plex-mono-normal-500-latin-ext.woff2") format("woff2");unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url("/assets/fonts/ibm-plex-mono-normal-500-latin.woff2") format("woff2");unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

/* ==========================================================================
   QUOD — charte CSS v2 (QV2-050)
   Une seule feuille, organisée en couches. Toute valeur visuelle passe par un
   jeton ; les univers (CORPORATE bleu nuit, EDTECH clair, FONDATIONS hérité)
   ne redéfinissent que des jetons sémantiques, jamais une règle de composant.
   Langage : typographie, espace, grille, filets. Pas de dégradé décoratif, pas
   d'ombre de carte, pas d'emoji ; la couleur signale, elle ne structure pas.
   ========================================================================== */

@layer reset, jetons, base, mise-en-page, composants, pages, utilitaires;

/* --------------------------------------------------------------------------
   1. RESET
   -------------------------------------------------------------------------- */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  body { min-height: 100svh; }
  img, svg, video { display: block; max-width: 100%; height: auto; }
  input, button, textarea, select { font: inherit; color: inherit; }
  button { cursor: pointer; background: none; border: 0; padding: 0; }
  ul, ol { padding: 0; }
  [hidden] { display: none !important; }
}

/* --------------------------------------------------------------------------
   2. JETONS
   2a. Primitifs : la palette brute, jamais appelée par un composant.
   2b. Sémantiques : ce que les composants appellent (texte, fond, filet…).
   2c. Univers : redéfinition des seuls jetons sémantiques.
   Contrastes calculés (WCAG 2.x) et consignés en commentaire.
   -------------------------------------------------------------------------- */
@layer jetons {
  :root {
    /* 2a — primitifs */
    --nuit-950: #060B16;
    --nuit-900: #0A1325;
    --nuit-850: #0E1930;
    --nuit-800: #13203A;
    --nuit-700: #1D2C4B;
    --nuit-600: #2B3D63;
    --craie-0:  #FFFFFF;
    --craie-50: #F5F7FB;
    --craie-100:#ECF0F6;
    --craie-200:#DCE2EC;
    --craie-300:#C3CCDA;
    --encre-900:#0B1320;
    --encre-700:#2A3548;
    --encre-600:#465267;
    --encre-400:#8994A8;
    --violet-200:#CBC4FF;
    --violet-300:#B3A9FF;
    --violet-400:#9687FF;
    --violet-600:#5646D6;
    --violet-700:#4336B2;
    --orange-400:#FF8C42;
    --orange-700:#B54A0C;

    /* typographie */
    --police-titre: "Source Serif 4", "Source Serif Pro", Georgia, "Times New Roman", serif;
    --police-texte: "IBM Plex Sans", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --police-repere: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

    /* échelle typographique fluide, rapport ≈ 1,25 → 1,333 (320 px → 1 440 px) */
    --t-moins: clamp(0.8125rem, 0.79rem + 0.1vw, 0.875rem);
    --t-0:     clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
    --t-1:     clamp(1.125rem, 1.07rem + 0.28vw, 1.25rem);
    --t-2:     clamp(1.3125rem, 1.2rem + 0.55vw, 1.625rem);
    --t-3:     clamp(1.625rem, 1.36rem + 1.3vw, 2.375rem);
    --t-4:     clamp(2rem, 1.55rem + 2.25vw, 3.5rem);
    --t-5:     clamp(2.375rem, 1.6rem + 3.9vw, 5.125rem);
    --t-6:     clamp(2.75rem, 1.6rem + 5.8vw, 7rem);

    --interligne-serre: 1.08;
    --interligne-titre: 1.18;
    --interligne-texte: 1.62;
    --approche-capitales: 0.12em;

    /* espace : pas de 4 px, nommés */
    --e-1: 0.25rem;  --e-2: 0.5rem;  --e-3: 0.75rem; --e-4: 1rem;
    --e-5: 1.5rem;   --e-6: 2rem;    --e-7: 3rem;    --e-8: 4rem;
    --e-9: 6rem;     --e-10: 8rem;
    --rythme-section: clamp(3rem, 2rem + 3.5vw, 5.5rem);

    /* grille */
    --largeur: 82rem;
    --gouttiere: clamp(1rem, 0.4rem + 3vw, 3rem);
    --colonnes-gap: clamp(1rem, 0.5rem + 2.2vw, 2.75rem);
    --mesure: 66ch;

    /* forme et mouvement */
    --rayon: 2px;
    --filet-epaisseur: 1px;
    --duree: 180ms;
    --courbe: cubic-bezier(0.2, 0.7, 0.2, 1);

    /* 2b — sémantiques, valeurs par défaut = thème clair (EDTECH) */
    --fond: var(--craie-0);
    --fond-alt: var(--craie-50);
    --surface: var(--craie-0);
    --surface-haute: var(--craie-50);
    --texte: var(--encre-900);            /* 18,1:1 sur --fond */
    --texte-doux: var(--encre-600);       /* 7,9:1 sur --fond */
    --texte-discret: var(--encre-400);    /* 3,3:1 : repères non textuels seulement */
    --filet: var(--craie-200);
    --filet-fort: var(--craie-300);
    --accent: var(--violet-600);          /* 6,6:1 sur blanc : texte et liens */
    --accent-fort: var(--violet-700);
    --sur-accent: var(--craie-0);         /* 6,6:1 sur --accent */
    --accent-doux: #EEECFF;
    --signal: var(--orange-700);          /* 5,3:1 sur blanc : repère rare */
    --focus: var(--violet-600);
    --pied-fond: var(--nuit-950);
    --pied-texte: var(--craie-100);
    --pied-doux: #A9B5CA;
    --voile: rgb(6 11 22 / 0.62);
    color-scheme: light;
  }

  /* 2c — CORPORATE : bleu nuit */
  :root[data-theme="corporate"] {
    --fond: var(--nuit-900);
    --fond-alt: var(--nuit-850);
    --surface: var(--nuit-800);
    --surface-haute: var(--nuit-700);
    --texte: #EEF2F8;                     /* 16,0:1 sur --fond */
    --texte-doux: #AEB9CC;                /* 9,0:1 sur --fond */
    --texte-discret: #6F7C94;             /* repères non textuels */
    --filet: rgb(238 242 248 / 0.13);
    --filet-fort: rgb(238 242 248 / 0.26);
    --accent: var(--violet-400);          /* 6,1:1 sur --fond */
    --accent-fort: var(--violet-300);
    --sur-accent: var(--nuit-950);        /* 6,9:1 sur --accent */
    --accent-doux: rgb(150 135 255 / 0.12);
    --signal: var(--orange-400);          /* 7,4:1 sur --fond */
    --focus: var(--violet-300);
    color-scheme: dark;
  }

  /* 2c — EDTECH : clair (valeurs par défaut, déclarées pour lisibilité) */
  :root[data-theme="edtech"] { color-scheme: light; }

  /* 2c — FONDATIONS & ASSOCIATIONS : troisième couleur (Mathieu, 28/09). Ivoire chaud,
     accent vert d'eau profond : la chaleur humaine et la durée, distinct du bleu nuit
     CORPORATE et du blanc EDTECH. Contrastes mesurés (WCAG 2.x) sur --fond #FAF6EF.
     Un univers nouveau s'ajoute ici, jetons seulement. */
  :root[data-theme="fondations"] {
    --fond: #FAF6EF;
    --fond-alt: #F2ECE2;
    --surface: #FFFFFF;
    --surface-haute: #F2ECE2;
    --texte: #1D1B18;                     /* 16,0:1 */
    --texte-doux: #56504A;                /* 7,4:1 */
    --texte-discret: #8C857C;             /* 3,4:1 : repères non textuels */
    --filet: #E4DCCF;
    --filet-fort: #CDC3B3;
    --accent: #0D6B63;                    /* 5,9:1 ; blanc sur accent 6,4:1 */
    --accent-fort: #0A524C;               /* 8,4:1 */
    --sur-accent: #FFFFFF;
    --accent-doux: #E1EFEC;
    --signal: #A8440C;                    /* 5,6:1 : repère rare */
    --focus: #0D6B63;
    color-scheme: light;
  }
}

/* --------------------------------------------------------------------------
   3. BASE
   -------------------------------------------------------------------------- */
@layer base {
  /* Ancres : l'en-tête collant (barre de rubrique comprise) est mesuré en direct par menu.js (--hauteur-entete). */
  html { background: var(--fond); scroll-padding-top: calc(var(--hauteur-entete, 10rem) + 1.25rem); }
  @media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
  body {
    background: var(--fond);
    color: var(--texte);
    font-family: var(--police-texte);
    font-size: var(--t-0);
    line-height: var(--interligne-texte);
    font-kerning: normal;
    font-optical-sizing: auto;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }
  h1, h2, h3 { text-wrap: balance; }
  h1, h2 {
    font-family: var(--police-titre);
    font-weight: 600;
    line-height: var(--interligne-titre);
    letter-spacing: -0.012em;
    font-variation-settings: "opsz" 48;
  }
  h3 { font-size: var(--t-1); font-weight: 600; line-height: 1.35; letter-spacing: -0.005em; }
  /* Aucune césure, nulle part (Mathieu, 29/09, référence apple.com/fr) : un mot coupé ralentit la lecture ;
     « pretty » évite les veuves et équilibre la dernière ligne. */
  /* Jamais de coupure dans un mot, ni par césure ni par retour forcé (« Établissement / s », Mathieu, 29/09). */
  p, li, h1, h2, h3 { hyphens: manual; -webkit-hyphens: manual; overflow-wrap: normal; word-break: normal; }
  p { text-wrap: pretty; }
  a { color: var(--accent); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
  a:hover { color: var(--accent-fort); text-decoration-thickness: 2px; }
  :focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: var(--rayon); }
  main:focus { outline: none; }
  ::selection { background: var(--accent); color: var(--sur-accent); }
  strong { font-weight: 600; }
  hr { border: 0; border-top: var(--filet-epaisseur) solid var(--filet-fort); }
}

/* --------------------------------------------------------------------------
   4. MISE EN PAGE : enveloppe et grille à 12 colonnes
   -------------------------------------------------------------------------- */
@layer mise-en-page {
  .enveloppe,
  .fil-ariane,
  .page-tete,
  .liens-lies,
  .enfants,
  .mention,
  .retour {
    width: 100%;
    max-width: var(--largeur);
    margin-inline: auto;
    padding-inline: var(--gouttiere);
  }

  .section { border-top: var(--filet-epaisseur) solid var(--filet); padding-block: var(--rythme-section); }
  .section:nth-of-type(even) { background: var(--fond-alt); }

  .section-grille {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: var(--colonnes-gap);
    row-gap: var(--e-6);
  }
  .section-tete, .section-corps, .blocs, .carte-invitation { grid-column: 1 / -1; }
  @media (min-width: 64rem) {
    .section-tete  { grid-column: 1 / span 4; align-self: start; position: sticky; top: calc(var(--hauteur-entete, 10rem) + 1.5rem); }
    .section-corps { grid-column: 6 / -1; }
    .blocs         { grid-column: 6 / -1; }
    .carte-invitation { grid-column: 6 / -1; }
    .section-corps:empty { display: none; }
    .section-corps:empty + .blocs { grid-row: 1; }
  }
}

/* Sections empilées (Mathieu, 29/09 : « dommage de ne pas occuper toute la largeur […] c'est sur toutes les pages ») :
   le numéro et le titre en haut, le texte dessous à la mesure de lecture, et le texte déplié réparti sur deux colonnes
   qui occupent toute la largeur. Plus de colonne gauche vide. */
@layer pages {
  @media (min-width: 64rem) {
    .section-grille > .section-tete { grid-column: 1 / -1; position: static; }
    .section-grille > .section-tete h2 { max-width: 32ch; }
    .section-grille > .section-corps { grid-column: 1 / -1; max-width: none; }
    .section-grille > .section-corps > p, .section-grille > .section-corps > .section-actions { max-width: var(--mesure); }
    .section-grille > .blocs, .section-grille > .carte-invitation { grid-column: 1 / -1; }
    .section-grille > .section-corps:empty + .blocs { grid-row: auto; }
    .section-grille > .carte-invitation { max-width: 56rem; }
    .repli[open] { column-count: 2; column-gap: var(--colonnes-gap); max-width: none; }
    .section-actions > .repli[open] { max-width: none; }
    .section-grille > .section-corps:has(> .section-actions > .repli[open]) > .section-actions { max-width: none; }
    .repli[open] > summary { column-span: all; margin-bottom: var(--e-2); }
    .repli[open] > p { break-inside: avoid; margin-top: 0; margin-bottom: var(--e-5); }
  }
}

/* --------------------------------------------------------------------------
   5. COMPOSANTS
   -------------------------------------------------------------------------- */
@layer composants {

  /* ---- lien d'évitement ---- */
  .evitement {
    position: absolute; left: var(--e-4); top: -10rem; z-index: 100;
    background: var(--accent); color: var(--sur-accent);
    padding: var(--e-3) var(--e-4); font-weight: 600; text-decoration: none;
  }
  .evitement:focus { top: var(--e-4); }
  .visuellement-masque {
    position: absolute !important; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }

  /* ---- boutons ---- */
  .bouton, .cta-entete {
    display: inline-flex; align-items: center; gap: var(--e-3);
    min-height: 2.875rem; padding: 0.75em 1.35em;
    font-family: var(--police-texte); font-size: var(--t-moins); font-weight: 600;
    letter-spacing: 0.06em; text-transform: uppercase; text-decoration: none;
    border: var(--filet-epaisseur) solid currentColor; border-radius: var(--rayon);
    color: var(--texte); background: transparent;
    transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe),
                border-color var(--duree) var(--courbe);
  }
  .bouton::after, .cta-entete::after {
    content: "→"; font-weight: 400; letter-spacing: 0;
    transition: translate var(--duree) var(--courbe);
  }
  .bouton:hover, .cta-entete:hover { color: var(--texte); text-decoration: none; }
  .bouton:hover::after, .cta-entete:hover::after { translate: 0.25em 0; }
  .bouton-principal, .bouton-univers:first-child {
    background: var(--accent); border-color: var(--accent); color: var(--sur-accent);
  }
  .bouton-principal:hover, .bouton-univers:first-child:hover {
    background: var(--accent-fort); border-color: var(--accent-fort); color: var(--sur-accent);
  }

  /* ---- en-tête ---- */
  .entete {
    position: sticky; top: 0; z-index: 50;
    background: var(--fond);
    border-bottom: var(--filet-epaisseur) solid var(--filet);
  }
  .entete-univers { background: var(--fond-alt); border-bottom: var(--filet-epaisseur) solid var(--filet); }
  .entete-univers .enveloppe { display: flex; justify-content: flex-end; }
  .selecteur-univers ul { display: flex; list-style: none; }
  .selecteur-univers a {
    display: block; padding: 0.55rem 0.9rem;
    font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--texte-doux); text-decoration: none;
    border-inline-start: var(--filet-epaisseur) solid var(--filet);
  }
  .selecteur-univers li:last-child a { border-inline-end: var(--filet-epaisseur) solid var(--filet); }
  .selecteur-univers a:hover { color: var(--texte); background: var(--surface); }
  .selecteur-univers a[aria-current] { color: var(--texte); background: var(--fond); box-shadow: inset 0 -2px 0 var(--accent); }

  .entete-barre .enveloppe {
    display: flex; align-items: center; gap: var(--e-5);
    min-height: 4.5rem;
    transition: min-height var(--duree) var(--courbe);
  }
  .entete.defile .entete-barre .enveloppe { min-height: 3.75rem; }
  .marque {
    font-family: var(--police-texte); font-weight: 700; font-size: 1.375rem;
    letter-spacing: 0.16em; color: var(--texte); text-decoration: none; margin-inline-end: auto;
  }
  .marque:hover { color: var(--texte); }

  .entete-menu { display: flex; align-items: center; gap: var(--e-5); }
  .nav-principale > ul { display: flex; list-style: none; align-items: center; }
  .nav-principale > ul > li { display: flex; align-items: center; }
  .nav-principale > ul > li > a {
    display: block; padding: 0.5rem 0.45rem;
    font-size: 0.8125rem; font-weight: 500; letter-spacing: 0.04em;
    color: var(--texte); text-decoration: none; white-space: nowrap;
  }
  .nav-principale > ul > li > a:hover { color: var(--accent); }
  .nav-principale > ul > li > a[aria-current] { color: var(--accent); box-shadow: inset 0 -2px 0 var(--accent); }
  .nav-principale button[aria-controls] {
    width: 1.5rem; height: 2rem; margin-inline-start: -0.25rem; margin-inline-end: 0.2rem;
    display: grid; place-items: center; color: var(--texte-doux);
  }
  .nav-principale button[aria-controls]::before {
    content: ""; width: 0.4rem; height: 0.4rem;
    border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    rotate: 45deg; translate: 0 -0.1rem;
    transition: rotate var(--duree) var(--courbe), translate var(--duree) var(--courbe);
  }
  .nav-principale button[aria-expanded="true"] { color: var(--accent); }
  .nav-principale button[aria-expanded="true"]::before { rotate: 225deg; translate: 0 0.12rem; }

  /* panneau de sous-menu : pleine largeur sous la barre, groupes en colonnes */
  /* Ouverture animée (Mathieu, 28/09 : « une animation sur le format ordinateur, plus contemporaine ») : le panneau glisse
     et apparaît, puis ses colonnes arrivent l'une après l'autre. Rien si l'utilisateur demande moins de mouvement. */
  @media (min-width: 82rem) and (prefers-reduced-motion: no-preference) {
    .nav-principale [id^="sous-menu-"]:not([hidden]) { animation: panneau-entree 260ms var(--courbe) both; }
    .nav-principale [id^="sous-menu-"]:not([hidden]) > * { animation: panneau-colonne 360ms var(--courbe) both; }
    .nav-principale [id^="sous-menu-"]:not([hidden]) > :nth-child(3), .nav-principale [id^="sous-menu-"]:not([hidden]) > :nth-child(4) { animation-delay: 60ms; }
    .nav-principale [id^="sous-menu-"]:not([hidden]) > :nth-child(5), .nav-principale [id^="sous-menu-"]:not([hidden]) > :nth-child(6) { animation-delay: 120ms; }
    .nav-principale [id^="sous-menu-"]:not([hidden]) > :nth-child(n+7) { animation-delay: 180ms; }
  }
  @keyframes panneau-entree { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
  @keyframes panneau-colonne { from { opacity: 0; translate: 0 -0.6rem; } to { opacity: 1; translate: 0 0; } }
  .nav-principale [id^="sous-menu-"] {
    position: absolute; inset-inline: 0; top: 100%;
    background: var(--surface);
    border-top: var(--filet-epaisseur) solid var(--filet);
    border-bottom: var(--filet-epaisseur) solid var(--filet-fort);
    padding: var(--e-6) max(var(--gouttiere), calc((100% - var(--largeur)) / 2 + var(--gouttiere)));
    /* Chaque groupe = un titre (p) posé sur sa liste (ul) : deux rangées, les groupes côte à côte. */
    display: grid; grid-template-rows: auto 1fr; grid-auto-flow: column; grid-auto-columns: minmax(15rem, 1fr);
    gap: var(--e-3) var(--colonnes-gap); align-items: start;
  }
  .nav-principale [id^="sous-menu-"] > p {
    font-family: var(--police-repere); font-size: 0.72rem; letter-spacing: var(--approche-capitales);
    text-transform: uppercase; color: var(--texte-doux);
    padding-bottom: var(--e-2); border-bottom: var(--filet-epaisseur) solid var(--filet);
  }
  /* Groupe long (six entrées et plus) : sur deux colonnes, pour tenir dans la hauteur d'écran. */
  .nav-principale [id^="sous-menu-"] ul:has(> li:nth-child(6)) { display: block; columns: 2; column-gap: var(--colonnes-gap); }
  .nav-principale [id^="sous-menu-"] ul:has(> li:nth-child(6)) > li { break-inside: avoid; }
  .nav-principale [id^="sous-menu-"]:has(ul:nth-of-type(2)) { grid-auto-columns: auto; }
  .nav-principale [id^="sous-menu-"]:has(> ul > li:nth-child(6)):not(:has(> ul:nth-of-type(3))) > ul:has(> li:nth-child(6)) { min-width: min(38rem, 60vw); }
  /* Plusieurs groupes titrés (Services Augmentés) : « Vue d'ensemble » garde une colonne lisible, les groupes se partagent
     le reste sans déborder de l'écran (Mathieu, 28/09 : mise en page du menu). */
  .nav-principale [id^="sous-menu-"]:has(> ul:nth-of-type(3)) {
    grid-template-columns: minmax(12rem, 16rem); grid-auto-columns: minmax(0, 1fr);
  }
  .nav-principale [id^="sous-menu-"]:has(> ul:nth-of-type(3)) > p:has(+ ul > li:nth-child(6)) { grid-column: span 2; }
  .nav-principale [id^="sous-menu-"]:has(> ul:nth-of-type(3)) > ul:has(> li:nth-child(6)) {
    min-width: 0; columns: auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--e-5);
    grid-column: span 2; /* une liste longue prend deux colonnes du panneau, pas une seule */
  }
  .nav-principale [id^="sous-menu-"] ul { list-style: none; display: grid; }
  /* Groupe sans titre (après « Vue d'ensemble ») : il occupe les deux rangées de sa colonne, sinon il fixe la hauteur de
     la rangée des titres et repousse le lien de la page de garde en bas du panneau (Mathieu, 28/09). */
  .nav-principale [id^="sous-menu-"] > ul + ul { grid-row: span 2; }
  .nav-principale [id^="sous-menu-"] a {
    display: grid; gap: 0.15rem; padding: var(--e-3) 0;
    font-weight: 600; font-size: 0.9375rem; color: var(--texte); text-decoration: none;
    border-bottom: var(--filet-epaisseur) solid var(--filet);
  }
  .nav-principale [id^="sous-menu-"] a span { font-weight: 400; font-size: var(--t-moins); color: var(--texte-doux); line-height: 1.45; }
  .nav-principale [id^="sous-menu-"] a:hover { color: var(--accent); }
  .nav-principale [id^="sous-menu-"] a[aria-current] { color: var(--accent); }

  .cta-entete { min-height: 2.5rem; padding: 0.55em 1em; font-size: 0.75rem; color: var(--accent); white-space: nowrap; }
  /* Entre la bascule du burger (82rem ; 78rem avant ACCUEIL, 29/09) et au-delà, la barre n'a jamais la place du bouton (29/09 : il sortait du cadre de 1536 à 2048 px) : il reste au pied et sur Contact (QV2-118 : seuils relevés, le menu a gagné FONDATIONS). */
  @media (min-width: 82rem) { .cta-entete { display: none; } }
  .cta-entete:hover { color: var(--sur-accent); background: var(--accent); border-color: var(--accent); }

  /* bouton du menu mobile */
  .bouton-menu {
    display: none; align-items: center; gap: var(--e-3);
    min-height: 2.75rem; padding-inline: var(--e-3);
    font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--texte);
  }
  .bouton-menu-trait { position: relative; width: 1.25rem; height: 1.5px; background: currentColor; transition: background-color var(--duree); }
  .bouton-menu-trait::before, .bouton-menu-trait::after {
    content: ""; position: absolute; left: 0; width: 100%; height: 1.5px; background: currentColor;
    transition: translate var(--duree) var(--courbe), rotate var(--duree) var(--courbe);
  }
  .bouton-menu-trait::before { translate: 0 -0.4rem; }
  .bouton-menu-trait::after  { translate: 0 0.4rem; }
  .bouton-menu[aria-expanded="true"] .bouton-menu-trait { background: transparent; }
  .bouton-menu[aria-expanded="true"] .bouton-menu-trait::before { translate: 0; rotate: 45deg; }
  .bouton-menu[aria-expanded="true"] .bouton-menu-trait::after  { translate: 0; rotate: -45deg; }

  @media (max-width: 81.99rem) {
    .js .bouton-menu { display: inline-flex; }
    .entete-barre .enveloppe { flex-wrap: wrap; }
    .js .entete-menu { display: none; }
    .entete-menu {
      flex-basis: 100%; flex-direction: column; align-items: stretch; gap: var(--e-5);
      padding-block: var(--e-2) var(--e-6);
    }
    .js .entete-menu.ouvert { display: flex; max-height: calc(100svh - 7.5rem); overflow-y: auto; }
    .nav-principale > ul { flex-direction: column; align-items: stretch; }
    .nav-principale > ul > li { flex-wrap: wrap; border-bottom: var(--filet-epaisseur) solid var(--filet); }
    .nav-principale > ul > li > a { flex: 1; padding: var(--e-4) 0; font-size: 0.9375rem; }
    .nav-principale button[aria-controls] { width: 2.75rem; height: 2.75rem; margin: 0; }
    .nav-principale [id^="sous-menu-"] {
      position: static; flex-basis: 100%; padding: 0 0 var(--e-4);
      border: 0; background: transparent; grid-template-columns: 1fr;
      grid-template-rows: none; grid-auto-flow: row; grid-auto-columns: auto;
    }
    .nav-principale [id^="sous-menu-"] ul:has(> li:nth-child(6)) { columns: 1; min-width: 0; }
    .nav-principale [id^="sous-menu-"] > p { margin-top: var(--e-4); }
    .nav-principale [id^="sous-menu-"] > ul + ul { grid-row: auto; }
    .cta-entete { align-self: flex-start; }
    html.menu-ouvert { overflow: hidden; }
  }

  /* ---- encart « autre technologie » des mini-sites d'éditeur (Mathieu, 28/09) ---- */
  .encart-autre { border-top: var(--filet-epaisseur) solid var(--filet); background: var(--fond-alt); padding-block: var(--e-7); }
  .encart-autre .enveloppe { display: grid; gap: var(--e-4); max-width: 52rem; }
  .encart-autre h2 { font-size: var(--t-3); }
  .encart-autre p { color: var(--texte-doux); font-size: var(--t-1); max-width: 60ch; }
  .encart-autre .bouton { justify-self: start; }

  .retour-liste { padding-block: var(--e-6); }
  .retour-liste.retour-haut { padding-block: var(--e-4) 0; }
  .retour-liste .bouton::after { content: none; }
  .retour-liste .bouton::before { content: "←"; font-weight: 400; }

  /* ---- sommaire de mini-site d'éditeur (QV2-091) : barre secondaire, défilement horizontal sur mobile ---- */
  .mini-site { border-bottom: var(--filet-epaisseur) solid var(--filet); background: var(--fond-alt); }
  .mini-site .enveloppe { display: flex; align-items: center; gap: var(--e-5); min-height: 3rem; overflow-x: auto; scrollbar-width: thin; }
  .mini-site-titre { flex: none; font-family: var(--police-titre); font-weight: 600; font-size: var(--t-0); color: var(--texte); text-decoration: none; }
  .mini-site-titre:hover { color: var(--accent); }
  .mini-site ul { display: flex; list-style: none; gap: var(--e-1); }
  .mini-site li a { display: block; white-space: nowrap; padding: 0.75rem 0.6rem; font-size: var(--t-moins); font-weight: 500;
    color: var(--texte-doux); text-decoration: none; box-shadow: inset 0 -2px 0 transparent; }
  .mini-site li a:hover { color: var(--texte); }
  .mini-site li a[aria-current] { color: var(--texte); box-shadow: inset 0 -2px 0 var(--accent); }
  /* Barre de rubrique (Mathieu, 28/09) : dans l'en-tête collant, donc toujours visible ; titre = page de garde. */
  .entete .sous-nav { border-top: var(--filet-epaisseur) solid var(--filet); border-bottom: 0; }
  .entete .sous-nav .enveloppe { min-height: 2.75rem; }
  .sous-nav .mini-site-titre { font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: var(--approche-capitales); text-transform: uppercase; }
  .sous-nav .mini-site-titre[aria-current] { color: var(--accent); }
  .sous-nav li a { padding: 0.7rem 0.5rem; }
  /* CORPORATE a dix entrées depuis la page Événements (01/10) : barre resserrée pour qu'elles tiennent sur ordinateur. */
  .sous-nav ul { gap: 0; }
  .sous-nav li a { padding-inline: 0.45rem; font-size: 0.8125rem; }
  .sous-nav .enveloppe { gap: var(--e-3); scrollbar-width: none; }
  /* Le titre de la rubrique reste fixe à gauche : seule la liste défile. Un clic sur le titre ramène à la page de garde. */
  .mini-site .enveloppe { overflow: visible; }
  .mini-site ul { flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .mini-site ul::-webkit-scrollbar { display: none; }
  .sous-nav .enveloppe::-webkit-scrollbar { display: none; }
  /* Bord droit fondu quand la barre déborde : il reste des entrées à droite. */
  @supports (mask-image: linear-gradient(#000, #000)) {
    .mini-site ul.deborde:not(.au-bout) { mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent); }
  }
  /* Mobile et tablette (sous la bascule du burger) : pas de barre horizontale ; une liste verticale repliable en haut de page. */
  .sous-nav-mobile { display: none; }
  @media (max-width: 81.99rem) {
    .entete .mini-site { display: none; }
    .sous-nav-mobile { display: block; border-bottom: var(--filet-epaisseur) solid var(--filet); background: var(--fond-alt); }
    .sous-nav-mobile summary {
      display: flex; align-items: center; gap: var(--e-3); min-height: 3rem; cursor: pointer; list-style: none;
      padding-inline: var(--gouttiere);
    }
    .sous-nav-mobile summary::-webkit-details-marker { display: none; }
    .sous-nav-mobile summary::after { content: ""; margin-inline-start: auto; width: 0.5rem; height: 0.5rem;
      border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; rotate: 45deg; translate: 0 -0.15rem; }
    .sous-nav-mobile details[open] summary::after { rotate: 225deg; translate: 0 0.15rem; }
    .sous-nav-mobile-rubrique { font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: var(--approche-capitales);
      text-transform: uppercase; color: var(--accent); }
    .sous-nav-mobile-page { font-weight: 600; color: var(--texte); }
    .sous-nav-mobile ul { list-style: none; padding: 0 var(--gouttiere) var(--e-3); }
    .sous-nav-mobile li a { display: block; padding: 0.8rem 0; border-top: var(--filet-epaisseur) solid var(--filet);
      color: var(--texte-doux); text-decoration: none; font-size: var(--t-0); }
    .sous-nav-mobile li a[aria-current] { color: var(--texte); font-weight: 600; box-shadow: inset 3px 0 0 var(--accent); padding-inline-start: var(--e-3); }
  }
  /* Colonne « Vue d'ensemble » du panneau : le lien vers la page de garde, mis en avant. */
  .nav-principale [id^="sous-menu-"] .sous-menu-garde a { color: var(--accent); border-bottom-color: var(--accent); }

  /* ---- fil d'Ariane ---- */
  .fil-ariane { padding-block: var(--e-4) 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--e-3) var(--e-5); }
  /* Bouton « Revenir » : pilule à la couleur de l'univers, dans la ligne du fil d'Ariane. */
  .bouton-revenir {
    display: inline-flex; align-items: center; gap: 0.4em; padding: 0.4em 0.95em; max-width: 100%;
    border: var(--filet-epaisseur) solid var(--accent); border-radius: 1.4em;
    font-size: var(--t-moins); font-weight: 600; color: var(--accent); text-decoration: none; line-height: 1.35;
    transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
  }
  /* Survol : le bouton se remplit, son texte passe en --sur-accent. Le préfixe « .fil-ariane » bat « .fil-ariane a:hover »,
     qui recolorait le texte à la couleur du fond : texte invisible au survol dans les trois thèmes (Mathieu, 29/09). */
  .bouton-revenir:is(:hover, :focus-visible), .fil-ariane .bouton-revenir:is(:hover, :focus-visible) {
    background: var(--accent); color: var(--sur-accent); text-decoration: none;
  }
  .revenir-flottant {
    position: fixed; z-index: 40; right: max(var(--gouttiere), env(safe-area-inset-right)); bottom: max(1.25rem, env(safe-area-inset-bottom));
    padding: 0.6em 1.1em; background: var(--surface); box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 0.28);
    opacity: 0; translate: 0 0.75rem; visibility: hidden; pointer-events: none;
    transition: opacity var(--duree) var(--courbe), translate var(--duree) var(--courbe), visibility 0s linear var(--duree),
      background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
  }
  .revenir-flottant[data-visible="true"] { opacity: 1; translate: 0 0; visibility: visible; pointer-events: auto; transition-delay: 0s; }
  @media print { .revenir-flottant { display: none; } }
  /* Le pied garde la place du bouton flottant : il ne recouvre jamais les mentions légales. */
  body:has(.revenir-flottant) .pied { padding-bottom: calc(var(--e-6) + 3.5rem); }
  .fil-ariane ol { display: flex; flex-wrap: wrap; list-style: none; gap: var(--e-1) var(--e-2);
    font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: 0.04em; color: var(--texte-doux); }
  .fil-ariane li + li::before { content: "/"; color: var(--texte-discret); margin-inline-end: var(--e-2); }
  .fil-ariane a { color: var(--texte-doux); text-decoration: none; }
  .fil-ariane a:hover { color: var(--accent); text-decoration: underline; }
  .fil-ariane [aria-current] { color: var(--texte); }

  /* ---- tête de page standard ---- */
  .page-tete { padding-block: clamp(1.75rem, 1rem + 2.5vw, 3.5rem) clamp(2.5rem, 1.5rem + 3vw, 4.5rem); display: grid; gap: var(--e-5); }
  .surtitre {
    display: flex; align-items: center; gap: var(--e-3);
    font-family: var(--police-repere); font-size: 0.78rem; font-weight: 500;
    letter-spacing: var(--approche-capitales); text-transform: uppercase; color: var(--accent);
  }
  .surtitre::before { content: ""; width: 2.25rem; height: var(--filet-epaisseur); background: currentColor; }
  .page-tete h1 { font-size: var(--t-4); max-width: 24ch; line-height: var(--interligne-titre); }
  /* ---- décor des pages de garde d'univers : strates (six fondations) qui se posent au chargement ---- */
  /* Mobile et tablette (Mathieu, 28/09 : « sur le mobile je ne vois pas les super SVG des heros ») : le décor passe sous le texte. */
  .page-tete-decor { display: block; color: var(--accent); width: 100%; max-width: min(22rem, 86%); margin: var(--e-5) auto 0; }
  .decor-strates { width: 100%; height: auto; overflow: visible; }
  .strate-face { fill: var(--fond); }
  .strate-epaisseur { stroke-opacity: 0.45; }
  .strate-fil { stroke-opacity: 0.25; stroke-dasharray: 2 5; }
  .strate { opacity: 0.55; }
  .strate-6 { opacity: 1; }
  .strate-6 .strate-face { fill: var(--accent-doux); }
  @media (min-width: 64rem) {
    .page-tete:has(> .page-tete-decor) { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: var(--colonnes-gap); }
    .page-tete:has(> .page-tete-decor) > :not(.page-tete-decor) { grid-column: 1; }
    .page-tete-decor { display: block; grid-column: 2; grid-row: 1 / span 6; align-self: center; max-width: 30rem; justify-self: end; width: 100%; }
  }
  /* ---- famille de décors des pages de garde (un motif par page, même langage) ---- */
  .decor { width: 100%; height: auto; overflow: visible; }
  .decor .d-face { fill: var(--fond); }
  .decor .d-plein, .decor .d-plein-haut, .decor .d-plein-feuillet .d-face { fill: var(--accent-doux); }
  .decor .d-plein { stroke-width: 1.5; }
  .decor .d-ep, .decor .d-cote, .decor .d-cote2 { stroke-opacity: 0.5; }
  .decor .d-lien, .decor .d-anneau, .decor .d-emplacement { stroke-opacity: 0.4; }
  .decor .d-sol, .decor .d-texte { stroke-opacity: 0.35; }
  .decor .d-noeud { fill: currentColor; stroke: none; opacity: 0.85; }
  .decor .d-noeud-grand { fill: var(--fond); }
  .decor .d-personne { fill: var(--fond); }
  .decor .d-existant { opacity: 0.55; }
  .decor [pathLength] { stroke-dasharray: 1; stroke-dashoffset: 0; }
  /* Hero éditorial EDTECH : l'accroche et son décor côte à côte sur grand écran. */
  /* L'accroche garde ses deux lignes d'un seul tenant ; le décor prend la place restante, et s'efface
     sous 80rem plutôt que de faire casser l'accroche mot par mot. */
  .page-tete-une .page-tete-decor { display: block; max-width: min(18rem, 80%); margin: var(--e-4) auto 0; }
  @media (min-width: 64rem) {
    .page-tete-une { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--colonnes-gap); align-items: center; }
    .page-tete-une .page-tete-decor { display: block; grid-column: auto; grid-row: auto; justify-self: stretch; max-width: 20rem; margin-inline-start: auto; width: 100%; }
  }
  @keyframes d-trace { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
  @keyframes d-apparait { from { opacity: 0; } }
  @keyframes d-ouvre { from { opacity: 0; transform: scale(0.82); } }
  @keyframes d-eleve { from { transform: scaleY(0); } }
  @keyframes d-descend { from { opacity: 0; transform: translateY(-2.25rem); } }
  @keyframes d-glisse { from { opacity: 0; transform: translateX(-1.25rem); } }
  @media (prefers-reduced-motion: no-preference) {
    .decor [pathLength] { animation: d-trace 1100ms var(--courbe) both; }
    .decor .d-noeud, .decor .d-plein, .decor .d-fleche { animation: d-apparait 700ms var(--courbe) both; }
    .decor .d-1 { animation-delay: 80ms; } .decor .d-2 { animation-delay: 200ms; } .decor .d-3 { animation-delay: 320ms; }
    .decor .d-4 { animation-delay: 440ms; } .decor .d-5 { animation-delay: 560ms; } .decor .d-6 { animation-delay: 680ms; }
    .decor .d-plein { animation-delay: 700ms; }
    .decor-diffusion .d-anneau { transform-box: view-box; transform-origin: 240px 210px; animation: d-ouvre 900ms var(--courbe) both; }
    .decor-diffusion .d-anneau.d-2 { animation-delay: 220ms; } .decor-diffusion .d-anneau.d-3 { animation-delay: 440ms; }
    .decor-maison .d-couche { animation: d-descend 800ms var(--courbe) both; }
    .decor-maison .d-metiers { animation: d-apparait 700ms var(--courbe) both; }
    .decor-maison .d-pont { animation: d-apparait 700ms var(--courbe) 900ms both; }
    .decor-maison .d-faisceau [pathLength] { animation-delay: 650ms; }
    .decor-augmenter .d-module { animation: d-descend 1000ms var(--courbe) 350ms both; }
    .decor-feuillets .d-feuillet { animation: d-glisse 700ms var(--courbe) both; }
    .decor-lyon-rencontres .d-savoirs { animation: d-descend 900ms var(--courbe) 250ms both; }
  }

  /* ---- onglets (QV2-111) : longs blocs lus un par un, en pleine largeur ---- */
  .onglets { grid-column: 1 / -1; margin-top: var(--e-4); }
  .section-grille:has(> .onglets) > .section-tete { position: static; }
  .onglets-liste { display: none; }
  .onglets.js-onglets .onglets-liste { display: flex; flex-wrap: wrap; gap: 0; border-bottom: var(--filet-epaisseur) solid var(--filet); margin-bottom: var(--e-5); }
  .onglets-liste button { font: inherit; font-size: var(--t-moins); font-weight: 600; color: var(--texte-doux); background: none; border: 0;
    padding: var(--e-3) var(--e-4); cursor: pointer; box-shadow: inset 0 -2px 0 transparent; transition: color var(--duree) var(--courbe), box-shadow var(--duree) var(--courbe); }
  .onglets-liste button:hover { color: var(--texte); }
  .onglets-liste button[aria-selected="true"] { color: var(--accent); box-shadow: inset 0 -2px 0 var(--accent); }
  .onglets-liste button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
  /* Panneau d'onglet sur toute la largeur (Mathieu, 28/09 : « les textes sont tous à gauche alors que nous avons de la
     place ») : le titre, puis les paragraphes en fiches sur deux colonnes. */
  .onglet-fiches { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); gap: var(--e-4) var(--colonnes-gap); }
  .onglet-fiches:has(> .onglet-fiche:only-child) { max-width: 72ch; }
  .onglet-fiches > .onglet-fiche { border-top: var(--filet-epaisseur) solid var(--filet-fort); padding-top: var(--e-3); margin: 0; font-size: var(--t-0); }
  .onglet-fiches > .onglet-fiche strong { display: block; color: var(--texte); font-weight: 600; margin-bottom: var(--e-1); }
  .onglets:not(.js-onglets) .onglet-panneau + .onglet-panneau { margin-top: var(--e-6); padding-top: var(--e-5); border-top: var(--filet-epaisseur) solid var(--filet); }
  .onglet-panneau h3 { font-family: var(--police-titre); font-size: var(--t-3); margin-bottom: var(--e-3); }
  .onglet-panneau p { color: var(--texte-doux); font-size: var(--t-1); line-height: 1.6; }
  .onglet-panneau p + p:not(.onglet-fiche) { margin-top: var(--e-3); }
  @media (max-width: 47.99rem) {
    .onglets.js-onglets .onglets-liste { flex-direction: column; flex-wrap: nowrap; border-bottom: 0; border-left: var(--filet-epaisseur) solid var(--filet); }
    .onglets-liste button { text-align: left; padding: var(--e-2) var(--e-4); box-shadow: inset 2px 0 0 transparent; }
    .onglets-liste button[aria-selected="true"] { box-shadow: inset 3px 0 0 var(--accent); }
  }

  /* ---- illustrations explicatives pleine largeur (QV2-106) : textes lisibles pour des non-spécialistes ---- */
  .section-illustration { grid-column: 1 / -1; margin: var(--e-4) 0 var(--e-6); color: var(--accent); }
  .section-grille:has(> .section-illustration) > .section-tete { position: static; }
  .section-grille:has(> .blocs-large, > .blocs:not(.blocs-reperes, [data-nombre="1"], [data-nombre="2"]), > .tableau-cadre, > .parcours) > .section-tete { position: static; }
  /* Sous une illustration pleine largeur (Mathieu, 28/09 : « des colonnes à droite de textes alors que nous avons la
     largeur de page ») : le texte et les blocs occupent aussi toute la largeur, sous le schéma. */
  @media (min-width: 64rem) {
    .section-grille:has(> .section-illustration) > .section-corps { grid-column: 1 / -1; max-width: var(--mesure); }
    .section-grille:has(> .section-illustration) > .blocs { grid-column: 1 / -1; }
    /* Blocs en pleine largeur sous le titre et le paragraphe (clé de section blocs_large, 29/09). */
    .section-grille > .blocs.blocs-large { grid-column: 1 / -1; }
    /* Trois blocs ou plus : toujours sur toute la largeur, sous le titre et le paragraphe (Mathieu, 29/09 : colonnes
       étroites illisibles ; la disposition de la page Lyon est « encore plus lisible »). Les repères restent à droite. */
    .section-grille > .blocs:not(.blocs-reperes, [data-nombre="1"], [data-nombre="2"]) { grid-column: 1 / -1; }
    .section-grille:has(> .section-illustration) > .blocs[data-nombre="2"],
    .section-grille:has(> .section-illustration) > .blocs[data-nombre="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .section-grille:has(> .section-illustration) > .blocs[data-nombre="3"],
    .section-grille:has(> .section-illustration) > .blocs[data-nombre="6"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  /* Maquettes d'écran (QV2-109) : taille lisible, pas en pleine largeur. */
  .section-illustration svg.illustration-maquette { max-width: 44rem; min-width: 0; margin-inline: auto; }
  .section-illustration .illustration { overflow-x: auto; }
  .section-illustration svg { width: 100%; min-width: 40rem; height: auto; display: block; }
  .section-illustration figcaption { margin-top: var(--e-3); font-size: var(--t-moins); color: var(--texte-doux); max-width: 62ch; }
  .illustration text { fill: var(--texte); stroke: none; font-family: var(--police-texte); font-size: 13px; }
  .illustration .ill-etape { fill: var(--accent); font-family: var(--police-repere); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; }
  .illustration .ill-etiquette { fill: var(--accent); font-family: var(--police-repere); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
  .illustration .ill-attenue { fill: var(--texte-doux); }
  .illustration .ill-flux { stroke-opacity: 0.55; }
  .illustration .ill-coupure { stroke: var(--signal, currentColor); stroke-width: 1.6; }
  .illustration .ill-fleche-trait { stroke-width: 1.6; }
  @media (prefers-reduced-motion: no-preference) {
    .illustration .ill-flux { animation: d-trace 1400ms var(--courbe) both; }
    .illustration .ill-source { animation: d-apparait 600ms var(--courbe) both; }
    .illustration .ill-reseau, .illustration .ill-modele { animation: d-apparait 800ms var(--courbe) 900ms both; }
    .illustration .ill-fleche-trait { animation: d-trace 900ms var(--courbe) 1400ms both; }
  }
  /* ---- décors des sous-pages (QV2-104, équipe décors, lots A à E) ---- */
  /* QV2-104, lot B (CORPORATE) : animations propres aux décors corp-*, jouées une fois au chargement.
     Les décalages d-1 à d-6 de site.css s'appliquent : les règles décalées ne passent pas par le raccourci « animation ».
     Les tracés (pathLength), nœuds, pleins et flèches gardent l'animation commune de site.css. */
  @keyframes d-B-apparait { from { opacity: 0; } }
  @keyframes d-B-descend { from { opacity: 0; transform: translateY(-1.75rem); } }
  @keyframes d-B-tiroir { from { transform: translate(-171px, -62px); } }
  @keyframes d-B-sortie { from { opacity: 0; transform: translate(-40px, -10px); } }
  @keyframes d-B-monte { from { transform: translateY(88px); } }
  @keyframes d-B-gain { from { transform: scaleY(0.04); } }
  @media (prefers-reduced-motion: no-preference) {
    .decor-corp-vue-ensemble .d-plan { animation: d-B-descend 900ms var(--courbe) 250ms both; }
    .decor-corp-retrouver .d-tiroir { animation: d-B-tiroir 1000ms var(--courbe) 300ms both; }
    .decor-corp-une-source .d-contenu { animation: d-B-apparait 800ms var(--courbe) 200ms both; }
    .decor-corp-reversibilite .d-donnees { animation: d-B-sortie 1000ms var(--courbe) 350ms both; }
    .decor-corp-couche-ajoutee .d-couche { animation: d-B-descend 1000ms var(--courbe) 350ms both; }
    .decor-corp-ecart-mesure .d-gain { transform-box: fill-box; transform-origin: 50% 100%; animation: d-B-gain 1100ms var(--courbe) 300ms both; }
    .decor-corp-quatre-regles .d-org { animation-name: d-B-descend; animation-duration: 800ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    .decor-corp-promotions .d-promo { animation-name: d-B-apparait; animation-duration: 600ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    .decor-corp-seance .d-sortie { animation: d-B-monte 1000ms var(--courbe) 300ms both; }
    .decor-corp-plus-vaste .d-case { animation-name: d-B-apparait; animation-duration: 600ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    .decor-corp-plus-vaste .d-arrivee { animation: d-B-descend 1000ms var(--courbe) 800ms both; }
  }
  /* QV2-104 — lot C (Services augmentés et Plateformes) : animations propres, jouées une fois. */
  @keyframes d-C-apparait { from { opacity: 0; } }
  @keyframes d-C-descend { from { opacity: 0; transform: translateY(-2.5rem); } }
  @keyframes d-C-pose { from { opacity: 0; transform: translateY(-1.5rem); } }
  @media (prefers-reduced-motion: no-preference) {
    /* Audit : l'existant apparaît d'abord, la carte se relève ensuite. */
    .decor-serv-releve .d-existant { animation-name: d-C-apparait; animation-duration: 600ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    .decor-serv-releve .d-emplacement, .decor-serv-releve .d-texte { animation: d-C-apparait 700ms var(--courbe) 500ms both; }
    .decor-serv-releve [pathLength] { animation-delay: 700ms; }
    /* Mise en œuvre et plateformes : les liaisons se tracent l'une après l'autre. */
    .decor-serv-relier .d-existant, .decor-serv-plateformes .d-existant { animation-name: d-C-apparait; animation-duration: 600ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    /* Archivage : les copies, puis la restauration. */
    .decor-serv-restaurer .d-5[pathLength] { animation-delay: 900ms; }
    .decor-serv-restaurer .d-fleche { animation-delay: 1700ms; }
    /* Production : la pièce sur mesure vient se poser entre les deux outils. */
    .decor-serv-sur-mesure .d-piece { animation: d-C-pose 900ms var(--courbe) 300ms both; }
    /* Services Mediasite : les salles s'ajoutent, la plateforme les couvre. */
    .decor-serv-exploitation .d-existant { animation-name: d-C-apparait; animation-duration: 500ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    .decor-serv-exploitation .d-plateforme { animation: d-C-descend 900ms var(--courbe) 700ms both; }
  }
  /* QV2-104, lot D : animations propres, jouées une fois, désactivées si l'utilisateur réduit les animations.
     Propriétés détaillées (pas de raccourci `animation`) pour garder les délais d-1 à d-6 du site. */
  @media (prefers-reduced-motion: no-preference) {
    @keyframes d-D-monte { from { opacity: 0; transform: translateY(0.75rem); } }
    /* Fondations : les six blocs apparaissent l'un après l'autre (délais d-1 à d-6). */
    .decor-meth-fondations .d-fondation { animation-name: d-D-monte; animation-duration: 600ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
    /* Patrimoine digital : les deux assises du socle se forment après l'accumulation (délais d-3, d-4). */
    .decor-meth-patrimoine-digital g.d-3, .decor-meth-patrimoine-digital g.d-4 { animation-name: d-D-monte; animation-duration: 700ms; animation-timing-function: var(--courbe); animation-fill-mode: both; }
  }
  /* QV2-104 lot E (ressources) : animations propres, jouées une fois, désactivées si l'utilisateur réduit les animations. */
  @keyframes d-E-eleve { from { transform: scaleY(0); } }
  @keyframes d-E-sort { from { opacity: 0; transform: translateY(2.5rem); } }
  @keyframes d-E-transit { from { opacity: 0; transform: translate(-3rem, -1rem); } }
  @media (prefers-reduced-motion: no-preference) {
    .decor-res-usage-reel .d-barre { transform-box: fill-box; transform-origin: 50% 100%; animation: d-E-eleve 900ms var(--courbe) 200ms both; }
    .decor-res-usage-reel .d-barre-focale { animation-delay: 650ms; }
    .decor-res-usage-reel .d-barre-focale .d-plein { animation: none; }
    .decor-res-lexique .d-fiche { animation: d-E-sort 900ms var(--courbe) 400ms both; }
    .decor-res-migration .d-transit { animation: d-E-transit 1100ms var(--courbe) 500ms both; }
    .decor-res-grille-criteres .d-usages { animation: d-E-sort 800ms var(--courbe) 300ms both; }
  }
  @keyframes strate-pose { from { opacity: 0; transform: translateY(-1.5rem); } }
  @media (prefers-reduced-motion: no-preference) {
    .strate { animation: strate-pose 900ms var(--courbe) both; }
    .strate-2 { animation-delay: 90ms; } .strate-3 { animation-delay: 180ms; } .strate-4 { animation-delay: 270ms; }
    .strate-5 { animation-delay: 360ms; } .strate-6 { animation-delay: 450ms; }
  }
  .page-tete-visuel { margin: var(--e-4) 0 0; }
  .page-tete-visuel img { width: 100%; max-height: 32rem; object-fit: cover; }
  @media (min-width: 64rem) {
    .page-tete:has(> .page-tete-visuel) { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: var(--colonnes-gap); align-items: start; }
    .page-tete:has(> .page-tete-visuel) > :not(.page-tete-visuel) { grid-column: 1; }
    .page-tete:has(> .page-tete-visuel) > .page-tete-visuel { grid-column: 2; grid-row: 1 / span 6; margin: 0; }
  }
  .chapo { font-size: var(--t-1); color: var(--texte-doux); max-width: 60ch; line-height: 1.55; }
  /* Suite du chapo (QV2-114) : la conclusion d'une page portée en tête, sous un filet d'accent. */
  .chapo-suite { max-width: 60ch; display: grid; gap: var(--e-3); padding-inline-start: var(--e-4);
    border-inline-start: 2px solid var(--accent); }
  .chapo-suite-titre { font-weight: 600; color: var(--texte); font-size: var(--t-1); line-height: 1.35; }
  .chapo-suite p:not(.chapo-suite-titre, .chapo-suite-signature) { color: var(--texte-doux); line-height: 1.6; }
  .chapo-suite-signature { font-family: var(--police-titre); font-style: italic; color: var(--texte); line-height: 1.5; }
  /* H1 coupé à la main (h1_lignes) : une ligne par phrase, sans la limite de 24ch. */
  .page-tete h1:has(.h1-ligne) { max-width: none; }
  .h1-ligne { display: block; }
  @media (min-width: 48rem) {
    .h1-ligne { white-space: nowrap; }
    .page-tete h1:has(.h1-ligne) { font-size: min(var(--t-4), 3.2vw); }
  }
  /* Hero long (suite du chapo) : le décor s'aligne sur le haut du texte plutôt qu'au milieu. */
  .page-tete:has(.chapo-suite) > .page-tete-decor { align-self: start; }

  /* ---- sections ---- */
  .section-rang {
    font-family: var(--police-repere); font-size: 0.78rem; letter-spacing: 0.08em; color: var(--accent);
    margin-bottom: var(--e-4); display: flex; align-items: center; gap: var(--e-3);
  }
  .section-rang::after { content: ""; flex: 0 0 2rem; height: var(--filet-epaisseur); background: var(--filet-fort); }
  .section-tete h2 { font-size: var(--t-3); max-width: 20ch; }
  .section-corps { display: grid; gap: var(--e-5); max-width: var(--mesure); }
  /* Lecture par couches (QV2-115). Hiérarchie des liens (29/09, référence apple.com/fr) : un bouton plein pour
     aller ailleurs, un lien texte pour lire plus. Le détail s'ouvre sur un lien sans cadre, suivi d'un « + » cerclé
     qui pivote en « × » à l'ouverture. */
  .repli { display: block; }
  .repli > summary {
    justify-self: start; list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.55em;
    min-height: 2.75rem; padding: 0; font-size: var(--t-0); font-weight: 600; color: var(--accent);
    border-radius: 0.3em;
  }
  .repli > summary::-webkit-details-marker { display: none; }
  .repli-signe {
    position: relative; flex: none; width: 1.6em; height: 1.6em; border-radius: 50%;
    border: var(--filet-epaisseur) solid currentColor;
    transition: rotate var(--duree) var(--courbe), background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
  }
  .repli-signe::before, .repli-signe::after {
    content: ""; position: absolute; inset: 50% auto auto 50%; width: 0.7em; height: 1.5px;
    background: currentColor; translate: -50% -50%;
  }
  .repli-signe::after { rotate: 90deg; }
  .repli[open] .repli-signe { rotate: 45deg; }
  .repli > summary:hover .repli-signe, .repli > summary:focus-visible .repli-signe { background: var(--accent); color: var(--sur-accent); border-color: var(--accent); }
  .repli > summary:hover > span:not(.repli-signe), .repli > summary:focus-visible > span:not(.repli-signe) { text-decoration: underline; text-underline-offset: 0.2em; }
  .repli > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
  @media (prefers-reduced-motion: reduce) { .repli-signe { transition: none; } }
  .repli .repli-fermer, .repli[open] .repli-ouvrir { display: none; }
  .repli[open] .repli-fermer { display: inline; }
  .repli > p { font-size: var(--t-0); color: var(--texte-doux); margin-top: var(--e-5); }
  .repli > summary + p { margin-top: var(--e-5); }
  @media print { .repli > summary { display: none; } }
  /* Rangée d'actions d'une section : liens pleins puis « + En savoir plus » ; déplié, le détail occupe toute la largeur. */
  .section-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3) var(--e-5); }
  .section-actions > .voir-aussi { display: contents; }
  .section-actions > .repli[open] { flex-basis: 100%; }
  /* Repères : étiquettes arrondies à la couleur de l'univers, au lieu de titres de blocs sans texte. */
  .blocs.blocs-reperes, .blocs.blocs-reperes[data-nombre] { display: flex; flex-wrap: wrap; gap: var(--e-3); }
  .blocs.blocs-reperes > .bloc {
    border: 0; border-radius: 0.4em; padding: 0.45em 0.8em;
    background: var(--surface); display: block;
  }
  .blocs.blocs-reperes > .bloc h3 { font-size: var(--t-moins); font-weight: 500; line-height: 1.3; }
  /* Carte « Et chez vous ? » (QV2-115) : la question retournée au lecteur, à la couleur de l'univers. */
  .carte-invitation {
    display: grid; gap: var(--e-3); justify-items: start; padding: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
    border: var(--filet-epaisseur) solid var(--accent); border-radius: 1.25rem; background: var(--accent-doux);
  }
  .carte-invitation-titre { font-family: var(--police-titre); font-size: var(--t-2); line-height: 1.2; color: var(--texte); }
  .carte-invitation p:not(.carte-invitation-titre) { max-width: 60ch; color: var(--texte); line-height: 1.6; }
  .carte-invitation .bouton { margin-top: var(--e-2); }
  .section-corps > p { font-size: var(--t-0); }
  .section-corps > p:first-child { font-size: var(--t-1); line-height: 1.55; color: var(--texte); }
  .section-corps > p + p { color: var(--texte-doux); }
  /* Liens de section : boutons pleins à la couleur de l'univers, clairs sur le fond sombre de CORPORATE, foncés sur les
     fonds clairs d'EDTECH et de Fondations, par les jetons --accent et --sur-accent (Mathieu, 28/09). */
  .voir-aussi { display: flex; flex-wrap: wrap; gap: var(--e-3); font-size: var(--t-moins); }
  .voir-aussi a {
    display: inline-flex; align-items: center; gap: 0.45em; padding: 0.6em 1.15em; border-radius: 1.4em;
    background: var(--accent); color: var(--sur-accent); font-weight: 600; text-decoration: none; line-height: 1.3;
    border: var(--filet-epaisseur) solid var(--accent);
    transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
  }
  .voir-aussi a::after { content: "→"; }
  .voir-aussi a:hover, .voir-aussi a:focus-visible { background: transparent; color: var(--accent); }
  /* Un seul bouton plein par rangée (29/09, référence apple.com/fr) : les suivants passent en contour, bouton secondaire. */
  .voir-aussi a ~ a { background: transparent; color: var(--accent); }
  .voir-aussi a ~ a:hover, .voir-aussi a ~ a:focus-visible { background: var(--accent); color: var(--sur-accent); }

  /* ---- blocs (sous-parties H3) : filets, jamais de cartes ---- */
  .blocs {
    container-type: inline-size;
    display: grid; gap: var(--e-6) var(--colonnes-gap);
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
    counter-reset: bloc;
  }
  .bloc { border-top: var(--filet-epaisseur) solid var(--filet-fort); padding-top: var(--e-4); display: grid; gap: var(--e-3); align-content: start; }
  .bloc h3 { font-family: var(--police-texte); font-size: var(--t-1); }
  .bloc p { color: var(--texte-doux); font-size: 0.9375rem; line-height: 1.6; }
  .bloc h3:only-child { font-weight: 500; }
  @media (min-width: 48rem) {
    .blocs[data-nombre="2"], .blocs[data-nombre="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .blocs[data-nombre="3"], .blocs[data-nombre="6"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    /* Sept blocs : 4 puis 3 sur toute la largeur, jamais un bloc seul et étroit en dernière ligne (29/09). */
    .blocs[data-nombre="7"] { grid-template-columns: repeat(12, minmax(0, 1fr)); }
    .blocs[data-nombre="7"] > .bloc { grid-column: span 3; }
    .blocs[data-nombre="7"] > .bloc:nth-child(n+5) { grid-column: span 4; }
    /* Dix blocs : 3, 3 puis 4, sans bloc seul en dernière ligne. */
    .blocs[data-nombre="10"] { grid-template-columns: repeat(12, minmax(0, 1fr)); }
    .blocs[data-nombre="10"] > .bloc { grid-column: span 4; }
    .blocs[data-nombre="10"] > .bloc:nth-child(n+7) { grid-column: span 3; }
    /* Treize blocs : 4 puis 3, 3, 3. */
    .blocs[data-nombre="13"] { grid-template-columns: repeat(12, minmax(0, 1fr)); }
    .blocs[data-nombre="13"] > .bloc { grid-column: span 4; }
    .blocs[data-nombre="13"] > .bloc:nth-child(-n+4) { grid-column: span 3; }
    .blocs[data-nombre="8"] { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--e-5) var(--colonnes-gap); }
    .blocs[data-nombre="5"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }
    .blocs[data-nombre="5"] > .bloc { grid-column: span 2; }
    .blocs[data-nombre="5"] > .bloc:nth-child(n+4) { grid-column: span 3; }
  }
  /* Bloc unique (Mathieu, 29/09 : « ils ne sont pas en largeur, il faut scroller ») : toute la largeur de la colonne,
     texte à la taille du corps de section, ligne limitée à la mesure de lecture. */
  .blocs[data-nombre="1"] { grid-template-columns: minmax(0, 1fr); }
  .blocs[data-nombre="1"] > .bloc h3 { font-size: var(--t-1); }
  .blocs[data-nombre="1"] > .bloc p:not(.bloc-lien) { font-size: var(--t-0); line-height: 1.6; max-width: var(--mesure); }
  /* Longues listes (9 à 12 blocs, par exemple les formats décomposés) : colonnes plus étroites, 3 ou 4 selon la largeur. */
  .blocs:is([data-nombre="9"], [data-nombre="11"], [data-nombre="12"]) {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 10.5rem), 1fr)); gap: var(--e-5) var(--colonnes-gap);
  }
  /* Neuf blocs à paragraphes, pleine largeur (pages Événements, 05/10) : trois colonnes lisibles, pas six colonnes étroites (leçon du 29/09). */
  .blocs.blocs-large:is([data-nombre="9"], [data-nombre="11"], [data-nombre="12"]):has(.bloc p) { grid-template-columns: minmax(0, 1fr); }
  @media (min-width: 48rem) {
    .blocs.blocs-large:is([data-nombre="9"], [data-nombre="11"], [data-nombre="12"]):has(.bloc p) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  /* Les blocs réduits à un intitulé (listes de domaines, d'indicateurs) : une grille de repères. */
  .blocs:not(:has(.bloc p)) .bloc { padding-top: var(--e-3); }
  .blocs:not(:has(.bloc p)) .bloc h3 { font-size: var(--t-0); }
  /* Bloc à bouton : colonne flexible, le bouton se pose en bas, à la même hauteur d'un bloc à l'autre. */
  .bloc:has(> .bloc-lien) { display: flex; flex-direction: column; }
  .bloc:has(> .bloc-lien) > :nth-last-child(2) { margin-bottom: var(--e-4); }
  /* Lien de bloc : lien texte « Libellé › » à la couleur de l'univers, comme les liens tertiaires d'apple.com (29/09) ;
     tout le bloc reste cliquable, le libellé se souligne au survol. */
  .bloc > .bloc-lien {
    align-self: flex-start; margin-top: auto; display: inline; width: fit-content; max-width: 100%;
    line-height: 1.4; font-weight: 600; font-size: var(--t-0); color: var(--accent); text-wrap: balance;
  }
  .bloc-lien::after { content: "\00a0›"; display: inline-block; transition: translate var(--duree) var(--courbe); }
  .bloc-lie:hover .bloc-lien, .bloc-lie:has(a:focus-visible) .bloc-lien { text-decoration: underline; text-underline-offset: 0.2em; }
  .bloc-lie:hover .bloc-lien::after { translate: 0.2em 0; }
  /* Bloc relié : le lien du titre couvre tout le bloc (un seul lien, une seule tabulation). */
  .bloc-lie { position: relative; }
  .bloc-lie h3 a { color: inherit; text-decoration: none; }
  .bloc-lie h3 a::before { content: ""; position: absolute; inset: 0; }
  .bloc-lie:hover h3 a, .bloc-lie h3 a:focus-visible { color: var(--accent); }
  .bloc-lie:has(a:focus-visible) { outline: 2px solid var(--accent); outline-offset: 4px; }
  .bloc-lie h3 a:focus-visible { outline: none; }
  /* Blocs porteurs d'un lien = accès (univers) : panneaux larges, titre serif. */
  .blocs:is([data-nombre="2"], [data-nombre="3"]):has(.bloc-lien) .bloc { padding: var(--e-6) var(--e-6) var(--e-6) 0; border-top-width: 2px; }
  .blocs:is([data-nombre="2"], [data-nombre="3"]):has(.bloc-lien) .bloc h3 { font-family: var(--police-titre); font-size: var(--t-2); line-height: 1.2; hyphens: manual; font-weight: 600; letter-spacing: -0.01em; }
  .blocs:is([data-nombre="2"], [data-nombre="3"]):has(.bloc-lien) .bloc p:not(.bloc-lien) { font-size: var(--t-1); line-height: 1.55; color: var(--texte); }
  .bloc-lie:hover { border-top-color: var(--accent); }

  /* ---- liens liés : « À lire aussi » ---- */
  .liens-lies { padding-block: var(--rythme-section) var(--e-7); border-top: var(--filet-epaisseur) solid var(--filet); }
  .liens-lies::before {
    content: attr(aria-label); display: block; margin-bottom: var(--e-5);
    font-family: var(--police-repere); font-size: 0.78rem; letter-spacing: var(--approche-capitales);
    text-transform: uppercase; color: var(--texte-doux);
  }
  /* Liens liés en boutons-cartes (Mathieu, 28/09 : « des boutons CSS, pas que des textes ») ; la couleur suit l'univers
     de la page par les jetons --accent et --accent-doux. */
  .liens-lies ul { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); gap: var(--e-3) var(--e-4); }
  .liens-lies a {
    display: flex; justify-content: space-between; gap: var(--e-4); align-items: center; height: 100%;
    padding: var(--e-4) var(--e-5); border: var(--filet-epaisseur) solid var(--filet-fort); border-radius: 0.875rem;
    background: var(--surface); color: var(--texte); text-decoration: none; font-weight: 500; line-height: 1.4;
    transition: border-color var(--duree) var(--courbe), background-color var(--duree) var(--courbe), translate var(--duree) var(--courbe);
  }
  .liens-lies a::after {
    content: "→"; flex: none; display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%;
    border: var(--filet-epaisseur) solid var(--accent); color: var(--accent);
    transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe);
  }
  .liens-lies a:hover, .liens-lies a:focus-visible { border-color: var(--accent); background: var(--accent-doux); }
  .liens-lies a:hover::after, .liens-lies a:focus-visible::after { background: var(--accent); color: var(--sur-accent); }
  @media (prefers-reduced-motion: no-preference) { .liens-lies a:hover { translate: 0 -2px; } }

  /* ---- pages enfants (listes de rubrique) ---- */
  .enfants { padding-block: 0 var(--rythme-section); }
  .enfants ul { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr)); gap: 0 var(--colonnes-gap); border-top: var(--filet-epaisseur) solid var(--filet-fort); }
  .enfants li { display: grid; gap: var(--e-3); align-content: start; padding-block: var(--e-5) var(--e-6); border-bottom: var(--filet-epaisseur) solid var(--filet); }
  .enfants a { font-family: var(--police-titre); font-size: var(--t-2); font-weight: 600; line-height: 1.25; color: var(--texte); text-decoration: none; text-wrap: balance; }
  .enfants a:hover { color: var(--accent); }
  .enfants p { color: var(--texte-doux); font-size: var(--t-moins); }
  /* Liste avec photographies (références) : image au format constant, recadrée, sans cadre ni ombre. */
  .enfants li.avec-visuel { grid-template-rows: auto; padding-top: var(--e-4); }
  .enfant-visuel { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; background: var(--surface);
    filter: saturate(0.85); transition: filter var(--duree) var(--courbe); }
  .enfants li.avec-visuel:hover .enfant-visuel { filter: saturate(1); }
  /* Cas sans photographie publiable : un aplat à filets (la signature des strates) garde la grille régulière. */
  .enfants ul:has(.avec-visuel) > li:not(.avec-visuel) { padding-top: var(--e-4); }
  .enfants ul:has(.avec-visuel) > li:not(.avec-visuel)::before {
    content: ""; display: block; aspect-ratio: 4 / 3; background-color: var(--surface);
    background-image: repeating-linear-gradient(to bottom, var(--filet-fort) 0 1px, transparent 1px 0.75rem);
    background-size: 100% 45%; background-position: bottom; background-repeat: no-repeat;
  }
  .enfants li.avec-visuel:has(a:focus-visible) .enfant-visuel { outline: 2px solid var(--focus); outline-offset: 3px; }

  /* ---- appel à l'action ---- */
  .cta { border-top: var(--filet-epaisseur) solid var(--filet); background: var(--fond-alt); padding-block: var(--e-8); }
  .cta .enveloppe { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: var(--e-5); }

  /* ---- mention et retour (références) ---- */
  .mention { padding-block: 0 var(--e-6); }
  .mention { font-family: var(--police-repere); font-size: 0.78rem; letter-spacing: 0.04em; color: var(--texte-doux); }
  .retour { padding-block: var(--e-6); }
  .retour a { font-weight: 600; text-decoration: none; }
  .retour a::before { content: "← "; }

  /* ---- pied de page : toujours bleu nuit ---- */
  .pied {
    background: var(--pied-fond); color: var(--pied-texte);
    padding-block: var(--e-9) var(--e-6); padding-inline: var(--gouttiere);
    display: grid; gap: var(--e-7);
  }
  /* Colonne bornée à l'écran : sans minmax(0, 1fr), la signature en capitales imposait sa largeur (débordement mobile). */
  .pied { grid-template-columns: minmax(0, 1fr); }
  .pied > * { width: 100%; max-width: calc(var(--largeur) - 2 * var(--gouttiere)); margin-inline: auto; min-width: 0; }
  .pied .signature { overflow-wrap: anywhere; }
  .pied a { color: var(--pied-texte); text-decoration: none; }
  .pied a:hover { color: var(--violet-200); text-decoration: underline; }
  .pied-colonnes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr)); gap: var(--e-6) var(--colonnes-gap); }
  .pied-colonnes ul { list-style: none; display: grid; gap: var(--e-2); font-size: var(--t-moins); }
  .pied-titre { font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: var(--approche-capitales); text-transform: uppercase; color: var(--pied-doux); margin-bottom: var(--e-4); }
  .pied .signature {
    font-family: var(--police-titre); font-weight: 600; font-size: var(--t-3); line-height: 1.12;
    letter-spacing: 0; padding-top: var(--e-7); border-top: var(--filet-epaisseur) solid rgb(238 242 248 / 0.16);
  }
  .pied .mentions { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--e-4); font-size: 0.8125rem; color: var(--pied-doux); }
  .pied .mentions ul { display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-5); list-style: none; }


  /* ---- tableau éditorial (QV2-070) : filets horizontaux, en-tête de ligne en gras ---- */
  .tableau-cadre { grid-column: 1 / -1; overflow-x: auto; border-top: 2px solid var(--texte); }
  /* Tableaux et frises sur toute la largeur, sous le titre et le paragraphe (Mathieu, 29/09 : « dommage de ne pas occuper
     toute la largeur »). */
  @media (min-width: 64rem) { .tableau-cadre { grid-column: 1 / -1; } }
  .tableau-cadre:focus-visible { outline-offset: 4px; }
  .tableau { width: 100%; border-collapse: collapse; font-size: 0.9375rem; line-height: 1.5; }
  .tableau th, .tableau td { text-align: start; vertical-align: top; padding: var(--e-3) var(--e-4) var(--e-3) 0;
    border-bottom: var(--filet-epaisseur) solid var(--filet); }
  .tableau thead th { font-family: var(--police-repere); font-size: 0.75rem; font-weight: 500; letter-spacing: var(--approche-capitales);
    text-transform: uppercase; color: var(--texte-doux); padding-block: var(--e-3); }
  .tableau tbody th { font-weight: 600; color: var(--texte); width: 45%; }
  .tableau td { color: var(--texte-doux); }
  .tableau tbody tr:hover > * { color: var(--texte); }
  .tableau tbody tr:hover th { box-shadow: inset 2px 0 0 var(--accent); padding-inline-start: var(--e-3); }

  /* ---- formulaire de qualification (QV2-070 §4) ---- */
  .formulaire-bloc { border-top: var(--filet-epaisseur) solid var(--filet); padding-block: var(--rythme-section); background: var(--fond-alt); }
  .formulaire-bloc .enveloppe { display: grid; gap: var(--e-5); max-width: 52rem; }
  .formulaire-bloc h2 { font-size: var(--t-3); }
  .formulaire-intro { color: var(--texte-doux); font-size: var(--t-1); max-width: 56ch; }
  .formulaire-avis { padding: var(--e-4); border-inline-start: 2px solid var(--signal); background: var(--surface); }
  .formulaire { display: grid; gap: var(--e-6); }
  .etape { border: 0; padding: 0; min-inline-size: 0; display: grid; gap: var(--e-5); }
  .etape + .etape { border-top: var(--filet-epaisseur) solid var(--filet); padding-top: var(--e-6); }
  .formulaire.js-actif .etape + .etape { border-top: 0; padding-top: 0; }
  .etape-titre { font-family: var(--police-titre); font-size: var(--t-2); font-weight: 600; padding: 0; display: grid; gap: var(--e-2); }
  .etape-titre-long .etape-titre { font-size: var(--t-1); line-height: 1.35; max-width: 48ch; }
  .etape-libelle { display: block; }
  .etape-titre:focus { outline: none; }
  .etape-titre:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
  .etape-rang { font-family: var(--police-repere); font-size: 0.75rem; font-weight: 500; letter-spacing: var(--approche-capitales);
    text-transform: uppercase; color: var(--accent); }
  .etape-aide, .etape-mention { color: var(--texte-doux); font-size: var(--t-moins); }
  .champ { display: grid; gap: var(--e-2); border: 0; padding: 0; margin: 0; min-inline-size: 0; }
  .champ > label, .champ > legend { font-weight: 600; font-size: var(--t-moins); padding: 0; }
  .champ > legend { margin-bottom: var(--e-3); }
  /* L'aide de l'étape dit déjà ce que liste le groupe de cases : l'intitulé reste pour les lecteurs d'écran. */
  .champ-cases > legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .requis { color: var(--signal); }
  .champ input:not([type="checkbox"], [type="radio"]), .champ textarea {
    width: 100%; min-height: 2.875rem; padding: 0.7rem 0.85rem; font-size: var(--t-0);
    color: var(--texte); background: var(--surface); border: var(--filet-epaisseur) solid var(--filet-fort);
    border-radius: var(--rayon); transition: border-color var(--duree) var(--courbe), box-shadow var(--duree) var(--courbe);
  }
  .champ textarea { resize: vertical; line-height: 1.5; }
  /* Listes déroulantes au style des champs (QV2-119 : elles restaient au rendu natif, minuscules). */
  .champ select {
    appearance: none; -webkit-appearance: none; width: 100%; min-height: 2.875rem; padding: 0.7rem 2.5rem 0.7rem 0.85rem;
    font: inherit; font-size: var(--t-0); color: var(--texte); border: var(--filet-epaisseur) solid var(--filet-fort);
    border-radius: var(--rayon); cursor: pointer;
    background-color: var(--surface);
    background-image: linear-gradient(45deg, transparent 50%, var(--texte-doux) 50%), linear-gradient(135deg, var(--texte-doux) 50%, transparent 50%);
    background-position: calc(100% - 1.15rem) 52%, calc(100% - 0.8rem) 52%; background-size: 0.36rem 0.36rem; background-repeat: no-repeat;
    transition: border-color var(--duree) var(--courbe), box-shadow var(--duree) var(--courbe);
  }
  .champ select:hover { border-color: var(--texte-doux); }
  .champ select:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-doux); }
  /* Champs deux par deux (QV2-119, Mathieu : « tout devrait tenir dans un écran… pas scroller pleins de fois ») ;
     les groupes d'options, les zones de texte et les champs marqués « pleine » gardent toute la largeur. */
  @media (min-width: 48rem) {
    .formulaire .etape { grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--e-4); row-gap: var(--e-4); }
    .formulaire .etape > div.champ { grid-column: span 2; }
    .formulaire .etape > div.champ.champ-quart { grid-column: span 1; }
    .formulaire .etape > :not(div.champ), .formulaire .etape > div.champ.champ-pleine, .formulaire .etape > div.champ.champ-autre,
    .formulaire .etape > div.champ:has(textarea) { grid-column: 1 / -1; }
    .formulaire .champ-quart input, .formulaire .champ-quart select { min-width: 0; padding-inline: 0.6rem; }
    .formulaire .champ-quart select { padding-inline-end: 2rem; }
    .formulaire .etape .champ + .champ { margin-top: 0; }
  }
  /* Pages de contact à formulaire : l'explication à gauche, le formulaire à droite dans une carte, le tout dans un écran. */
  @media (min-width: 64rem) {
    .page-contact:has(> .formulaire-bloc) {
      display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); column-gap: var(--colonnes-gap); align-items: start;
      max-width: var(--largeur); margin-inline: auto; padding: var(--e-5) var(--gouttiere) var(--e-7);
    }
    .page-contact:has(> .formulaire-bloc) > :not(.formulaire-bloc) { grid-column: 1; }
    .page-contact:has(> .formulaire-bloc) > .page-tete { padding: 0 0 var(--e-5); max-width: none; }
    .page-contact:has(> .formulaire-bloc) > .page-tete h1 { font-size: var(--t-4); }
    .page-contact:has(> .formulaire-bloc) > .section { border-top: var(--filet-epaisseur) solid var(--filet); padding-block: var(--e-4); background: transparent; }
    .page-contact:has(> .formulaire-bloc) > .section .enveloppe { padding: 0; max-width: none; }
    .page-contact:has(> .formulaire-bloc) > .section .section-grille { display: block; }
    .page-contact:has(> .formulaire-bloc) > .section .section-tete { position: static; margin-bottom: var(--e-3); }
    .page-contact:has(> .formulaire-bloc) > .section .section-rang { display: none; }
    .page-contact:has(> .formulaire-bloc) > .section h2 { font-size: var(--t-1); font-family: var(--police-texte); font-weight: 600; }
    .page-contact:has(> .formulaire-bloc) > .section .section-corps > p:first-child { font-size: var(--t-0); }
    .page-contact:has(> .formulaire-bloc) > .formulaire-bloc {
      grid-column: 2; grid-row: 1 / span 12; border: var(--filet-epaisseur) solid var(--filet); border-radius: 1.25rem;
      padding: var(--e-6); position: sticky; top: calc(var(--hauteur-entete, 8rem) + var(--e-4));
    }
    .page-contact:has(> .formulaire-bloc) > .formulaire-bloc .enveloppe { padding: 0; max-width: none; gap: var(--e-4); }
    .page-contact:has(> .formulaire-bloc) .formulaire-bloc h2 { font-size: var(--t-2); }
    .page-contact:has(> .formulaire-bloc) .formulaire { gap: var(--e-4); }
    .page-contact:has(> .formulaire-bloc) > .formulaire-bloc { padding: var(--e-4) var(--e-5); }
    .page-contact:has(> .formulaire-bloc) { padding-top: var(--e-3); }
    .page-contact:has(> .formulaire-bloc) > .formulaire-bloc .enveloppe { gap: var(--e-3); }
    .page-contact:has(> .formulaire-bloc) .formulaire-intro { font-size: var(--t-0); }
    /* Une seule étape : son numéro et son titre sont masqués à l'œil (le titre de la carte suffit), pas aux lecteurs d'écran. */
    .page-contact:has(> .formulaire-bloc) .etape:only-of-type > .etape-titre {
      position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
    }
    .page-contact:has(> .formulaire-bloc) .etape { row-gap: var(--e-3); }
    .page-contact:has(> .formulaire-bloc) .champ { gap: var(--e-1); }
    .page-contact:has(> .formulaire-bloc) .champ input:not([type="checkbox"], [type="radio"]),
    .page-contact:has(> .formulaire-bloc) .champ select { min-height: 2.5rem; padding-block: 0.5rem; }
    /* Civilité sur une ligne : l'intitulé puis les deux choix. */
    .page-contact:has(> .formulaire-bloc) .etape:only-of-type > .champ-liste { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3); }
    /* Civilité, prénom et nom sur la même ligne. */
    .page-contact:has(> .formulaire-bloc) .etape:only-of-type > .champ-liste { grid-column: span 2; align-self: end; min-height: 2.5rem; }
    .page-contact:has(> .formulaire-bloc) .etape:only-of-type > .champ-liste > legend { float: left; margin: 0; }
    .page-contact:has(> .formulaire-bloc) .champ-liste .option { padding-block: 0.35rem; }
    .page-contact:has(> .formulaire-bloc) .etape-mention { font-size: 0.8125rem; }
    /* Une seule étape : le récapitulatif répéterait ce qui est sous les yeux. */
    .formulaire:has(.etape:only-of-type) .formulaire-recap { display: none; }
    /* Plusieurs étapes : la barre dit déjà « Étape 1 sur 6 », le numéro au-dessus du titre ferait doublon. */
    .page-contact:has(> .formulaire-bloc) .formulaire.js-actif .etape-rang { display: none; }
    .page-contact:has(> .formulaire-bloc) .formulaire-progres { margin-bottom: var(--e-2); }
    .page-contact:has(> .formulaire-bloc) .etape-titre { font-size: var(--t-1); }
    .page-contact:has(> .formulaire-bloc) .formulaire .option { padding-block: 0.3rem; }
    .page-contact:has(> .formulaire-bloc) .formulaire .options { gap: var(--e-2); }
    .page-contact:has(> .formulaire-bloc) .formulaire-pourquoi { padding-block: var(--e-2); }
  }
  .champ input:hover, .champ textarea:hover { border-color: var(--texte-doux); }
  .champ input:focus-visible, .champ textarea:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-doux); }
  .champ input:user-invalid, .champ textarea:user-invalid { border-color: var(--signal); }
  .options { display: grid; gap: 0; border-top: var(--filet-epaisseur) solid var(--filet); }
  .champ-choix .options { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); column-gap: var(--colonnes-gap); }
  .champ-liste .options, .champ-cases:not(:has(> legend.visuellement-masque)) .options {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr)); column-gap: var(--colonnes-gap);
  }
  .champ-autre { margin-top: var(--e-3); max-width: 28rem; }
  .champ-autre > label { font-weight: 500; color: var(--texte-doux); }
  .groupes { display: grid; gap: var(--e-5) var(--colonnes-gap); grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); }
  .groupe-titre { font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: var(--approche-capitales);
    text-transform: uppercase; color: var(--accent); margin-bottom: var(--e-2); }
  .formulaire-pourquoi { border-top: var(--filet-epaisseur) solid var(--filet); border-bottom: var(--filet-epaisseur) solid var(--filet); padding-block: var(--e-3); }
  .formulaire-pourquoi summary { cursor: pointer; font-weight: 600; font-size: var(--t-moins); color: var(--accent); }
  .formulaire-pourquoi p { margin-top: var(--e-3); color: var(--texte-doux); max-width: 60ch; }
  .etape .champ + .champ { margin-top: var(--e-2); }
  .option { display: grid; grid-template-columns: 1.25rem 1fr; gap: var(--e-3); align-items: start; cursor: pointer;
    padding: var(--e-3) 0; border-bottom: var(--filet-epaisseur) solid var(--filet); font-size: 0.9375rem; line-height: 1.45; }
  .champ-case.option { border: 0; padding: 0; font-weight: 400; }
  .option input { width: 1.125rem; height: 1.125rem; margin: 0.15rem 0 0; accent-color: var(--accent); }
  .option:hover span { color: var(--accent); }
  .option:has(input:checked) span { color: var(--texte); font-weight: 600; }
  /* Pastilles (v1, QV2-105) : choix courts cliquables ; les questions longues (« ce qui vous freine ») gardent la liste. */
  .formulaire :is(.champ-liste, .champ-cases):not(:has(input[name="freins"])) .options,
  .formulaire .groupe-options .options { display: flex; flex-wrap: wrap; gap: var(--e-2); border-top: 0; }
  .formulaire :is(.champ-liste, .champ-cases):not(:has(input[name="freins"])) .option,
  .formulaire .groupe-options .option {
    position: relative; display: inline-flex; align-items: center; gap: 0; padding: 0.5rem 0.95rem;
    border: 1.5px solid var(--filet-fort); border-radius: 999px; font-size: var(--t-moins); line-height: 1.3;
    transition: border-color var(--duree) var(--courbe), background var(--duree) var(--courbe); }
  .formulaire :is(.champ-liste, .champ-cases):not(:has(input[name="freins"])) .option input,
  .formulaire .groupe-options .option input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
  .formulaire :is(.champ-liste, .champ-cases):not(:has(input[name="freins"])) .option:has(input:checked),
  .formulaire .groupe-options .option:has(input:checked) { border-color: var(--accent); background: var(--accent-doux); }
  .formulaire :is(.champ-liste, .champ-cases):not(:has(input[name="freins"])) .option:has(input:checked) span,
  .formulaire .groupe-options .option:has(input:checked) span { color: var(--accent); font-weight: 600; }
  .formulaire .option:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
  .champ-aide { font-size: var(--t-moins); color: var(--texte-doux); font-weight: 400; margin: var(--e-1) 0 var(--e-2); max-width: 62ch; }
  /* Progression et récapitulatif (v1). */
  .formulaire-progres { margin-bottom: var(--e-5); }
  .progres-etapes { display: flex; gap: 0.25rem; margin-bottom: var(--e-2); }
  .progres-etapes span { flex: 1; height: 4px; border-radius: 2px; background: var(--filet); transition: background var(--duree) var(--courbe); }
  .progres-etapes span.fait { background: var(--accent); }
  .progres-texte { font-size: var(--t-moins); color: var(--texte-doux); }
  .formulaire-recap { margin-top: var(--e-5); padding: var(--e-4) var(--e-5); background: var(--fond-alt); border-left: 3px solid var(--accent); font-size: var(--t-moins); }
  .recap-titre { font-weight: 600; margin-bottom: var(--e-2); }
  .formulaire-recap ul { list-style: none; display: grid; gap: 0.35rem; }
  .formulaire-recap strong { font-weight: 600; margin-right: 0.35em; }
  .formulaire-recap strong::after { content: " :"; }
  /* Grille d'autodiagnostic (QV2-107). */
  .diagnostic { grid-column: 1 / -1; display: grid; gap: var(--e-5); margin-top: var(--e-4); }
  .diag-consigne { color: var(--texte-doux); }
  .diag-score { position: sticky; top: calc(var(--hauteur-entete, 10rem) + 0.5rem); z-index: 2; display: flex; align-items: baseline; gap: var(--e-4);
    padding: var(--e-3) var(--e-4); background: var(--fond); border: var(--filet-epaisseur) solid var(--filet); border-left: 4px solid var(--accent); }
  .diag-compte { font-family: var(--police-titre); font-size: var(--t-4); font-weight: 600; color: var(--accent); white-space: nowrap; }
  .diag-texte { color: var(--texte); font-weight: 500; }
  .diagnostic[data-niveau="excellent"] .diag-score { border-left-color: #1f9d6b; }
  .diag-grille { display: grid; gap: var(--e-5) var(--colonnes-gap); grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr)); }
  .diag-cat { border: 0; border-top: 2px solid var(--filet-fort); margin: 0; min-inline-size: 0; padding: var(--e-3) 0 0; display: grid; gap: var(--e-2); }
  .section-grille:has(> .diagnostic) > .section-tete { position: static; }
  .diag-cat legend { font-weight: 600; display: flex; align-items: center; gap: var(--e-2); padding-bottom: var(--e-2); }
  .diag-lettre { display: inline-grid; place-items: center; width: 1.9rem; height: 1.9rem; border-radius: 50%;
    background: var(--accent-doux); color: var(--accent); font-family: var(--police-repere); font-size: 0.85rem; }
  .diag-item { display: grid; grid-template-columns: 1.25rem 1fr; gap: var(--e-3); align-items: start; cursor: pointer; font-size: 0.9375rem; line-height: 1.45; }
  .diag-item input { width: 1.125rem; height: 1.125rem; margin: 0.15rem 0 0; accent-color: var(--accent); }
  .diag-item:has(input:checked) span { color: var(--texte-doux); text-decoration: line-through; text-decoration-color: var(--accent); }
  .diag-suite { border-top: var(--filet-epaisseur) solid var(--filet); padding-top: var(--e-5); display: grid; gap: var(--e-3); max-width: 52rem; }
  .diag-suite-titre { font-family: var(--police-titre); font-size: var(--t-3); }
  .diag-note { color: var(--texte-doux); font-size: var(--t-moins); max-width: 60ch; }
  .diag-rappel { border-top: var(--filet-epaisseur) solid var(--filet); padding-top: var(--e-3); }
  .diag-rappel summary { cursor: pointer; font-weight: 600; color: var(--accent); }
  .diag-rappel > p { margin-block: var(--e-3); color: var(--texte-doux); max-width: 60ch; }
  .diag-colonnes { display: grid; gap: var(--e-4) var(--colonnes-gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
  .diag-form label { display: grid; gap: 0.3rem; font-weight: 500; font-size: var(--t-moins); margin-bottom: var(--e-3); }
  .diag-form input, .diag-form select { font: inherit; font-weight: 400; padding: 0.7rem 0.8rem; border: var(--filet-epaisseur) solid var(--filet-fort); background: var(--fond); color: var(--texte); }
  .diag-creneau { background: var(--fond-alt); padding: var(--e-3); margin-bottom: var(--e-3); display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--e-3); }
  .diag-creneau p { grid-column: 1 / -1; font-weight: 600; font-size: var(--t-moins); margin-bottom: var(--e-2); }
  .diag-etat { font-weight: 500; }
  .formulaire-diagnostic { padding: var(--e-3) var(--e-4); background: var(--accent-doux); border-left: 3px solid var(--accent); margin-bottom: var(--e-4); font-weight: 500; }
  /* EDTECH : le formulaire sur fond blanc (Mathieu, 28/09). */
  :root[data-theme="edtech"] .formulaire-bloc { background: #fff; }
  .formulaire-actions { display: flex; flex-wrap: wrap; gap: var(--e-3); align-items: center; }
  .formulaire-actions .bouton-retour::after { content: none; }
  .formulaire-actions .bouton-retour::before { content: "←"; font-weight: 400; }
  .formulaire-actions .bouton[hidden] { display: none; }
  .formulaire[aria-busy="true"] { opacity: 0.7; }
  .formulaire-etat:empty { display: none; }
  .formulaire-etat { padding: var(--e-4); background: var(--surface); border-inline-start: 2px solid var(--accent); font-size: var(--t-1); }
  .formulaire-etat.echoue { border-color: var(--signal); }

  /* ---- icônes (QV2-049) : au trait, couleur du texte d'accent, jamais seules porteuses de sens ---- */
  .icone { width: 1.75rem; height: 1.75rem; flex: none; color: var(--accent); }
  /* Icône de bloc portée à 2,5rem, trait affiné (Mathieu, 28/09 : une icône sur chaque point, qui se voie). */
  .bloc-icone > .icone { width: 2.5rem; height: 2.5rem; stroke-width: 1.2; margin-bottom: var(--e-2); }
  .blocs:has(.bloc-icone) .bloc { border-top-color: var(--filet); }
  .blocs:has(.bloc-icone) .bloc-lie:hover { border-top-color: var(--accent); }
  .blocs:has(.bloc-icone) .bloc-lie:hover .icone { transform: translateY(-2px); }
  .bloc .icone { transition: transform var(--duree) var(--courbe); }

  /* ---- parcours (QV2-081) : liste ordonnée, filet qui relie les étapes ---- */
  /* Valeur à copier (QV2-140) : adresse en police de repère, bouton contour qui passe à l'accent une fois copié. */
  .copie { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-2) var(--e-3); margin-block: var(--e-4);
    padding: var(--e-3) var(--e-4); border: var(--filet-epaisseur) solid var(--filet-fort); border-radius: var(--rayon);
    background: var(--surface); grid-column: 1 / -1; width: 100%; max-width: var(--mesure); box-sizing: border-box; }
  .copie-libelle { flex-basis: 100%; font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--texte-discret); }
  .copie-valeur { font-family: var(--police-repere); font-size: var(--t-1); color: var(--texte); user-select: all; overflow-wrap: anywhere; }
  .copie-bouton { display: inline-flex; align-items: center; gap: var(--e-2); margin-inline-start: auto; padding: 0.5rem 1rem;
    border: 1.5px solid var(--accent); border-radius: 999px; background: transparent; color: var(--accent);
    font: inherit; font-size: var(--t-moins); font-weight: 600; cursor: pointer;
    transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe); }
  .copie-bouton .icone { width: 1.125rem; height: 1.125rem; color: currentColor; }
  .copie-bouton:hover, .copie-bouton[data-copiee] { background: var(--accent); color: var(--sur-accent); }
  .copie-bouton:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
  .parcours {
    grid-column: 1 / -1; list-style: none; position: relative; counter-reset: etape;
    display: grid; gap: var(--e-6) var(--colonnes-gap);
  }
  @media (min-width: 64rem) { .parcours { grid-column: 1 / -1; } }
  .parcours::before {                   /* le filet vertical (mobile) ou horizontal (large) */
    content: ""; position: absolute; inset-block: 0.75rem; inset-inline-start: 0.6875rem;
    width: 1px; background: var(--filet-fort); transform-origin: top;
  }
  .parcours-etape { position: relative; display: grid; gap: var(--e-2); align-content: start; padding-inline-start: var(--e-7); }
  .parcours-etape > .icone + h3, .parcours-rang + h3 { margin-top: var(--e-1); }
  .parcours-etape::before {             /* le jalon */
    content: ""; position: absolute; inset-inline-start: 0.3125rem; top: 0.45rem;
    width: 0.75rem; height: 0.75rem; border-radius: 50%;
    background: var(--fond); border: 2px solid var(--accent);
  }
  .parcours-rang { font-family: var(--police-repere); font-size: 0.75rem; letter-spacing: 0.1em; color: var(--accent); }
  /* Icône d'étape : assez grande pour se lire comme un dessin (Mathieu, 28/09 : « je ne comprends pas le dessin »). */
  .parcours-etape .icone { width: 3rem; height: 3rem; stroke-width: 1.1; margin-block: var(--e-2) var(--e-1); }
  .parcours-etape h3 { font-size: var(--t-1); }
  .parcours-etape p { color: var(--texte-doux); font-size: 0.9375rem; }
  @media (min-width: 64rem) {
    .parcours[data-nombre="3"], .parcours[data-nombre="4"] {
      grid-column: 1 / -1; grid-template-columns: repeat(var(--colonnes, 4), minmax(0, 1fr));
      margin-top: var(--e-5); padding-top: var(--e-6); border-top: var(--filet-epaisseur) solid var(--filet);
    }
    .parcours[data-nombre="3"] { --colonnes: 3; }
    .parcours:is([data-nombre="3"], [data-nombre="4"])::before {
      inset-block: auto; top: calc(var(--e-6) + 0.8rem); inset-inline: 0.375rem 0; width: auto; height: 1px; transform-origin: left;
    }
    .parcours:is([data-nombre="3"], [data-nombre="4"]) .parcours-etape { padding-inline-start: 0; padding-top: var(--e-6); }
    .parcours:is([data-nombre="3"], [data-nombre="4"]) .parcours-etape::before { inset-inline-start: 0; top: 0.4rem; }
  }
  /* Animation : le filet se trace, les jalons s'allument l'un après l'autre. Pilotée par le défilement
     là où le navigateur le permet ; ailleurs, l'état final s'affiche d'emblée. Arrêtée par
     prefers-reduced-motion (couche utilitaires). */
  @keyframes parcours-trace { from { transform: scaleY(0); } to { transform: scaleY(1); } }
  @keyframes parcours-trace-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  @keyframes parcours-jalon { from { background: var(--fond); box-shadow: 0 0 0 0 var(--accent-doux); }
                              to { background: var(--accent); box-shadow: 0 0 0 6px var(--accent-doux); } }
  @keyframes parcours-apparait { from { opacity: 0.35; translate: 0 0.5rem; } to { opacity: 1; translate: 0 0; } }
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .parcours::before { animation: parcours-trace linear both; animation-timeline: view(); animation-range: entry 10% cover 55%; }
      .parcours-etape { animation: parcours-apparait linear both; animation-timeline: view(); animation-range: entry 0% entry 60%; }
      .parcours-etape::before { animation: parcours-jalon linear both; animation-timeline: view(); animation-range: entry 40% cover 45%; }
      @media (min-width: 64rem) {
        .parcours:is([data-nombre="3"], [data-nombre="4"])::before { animation-name: parcours-trace-x; }
      }
    }
  }

  /* ---- fenêtre de confirmation d'envoi (formulaires) : même langage que l'aiguillage ---- */
  .confirmation {
    width: min(32rem, calc(100% - 2 * var(--gouttiere))); margin: auto; padding: clamp(1.5rem, 1rem + 2vw, 2.5rem);
    background: var(--surface); color: var(--texte); border-radius: 1.5rem;
    border: var(--filet-epaisseur) solid color-mix(in srgb, var(--texte) 12%, transparent);
    box-shadow: 0 1.5rem 4rem -1rem rgb(0 0 0 / 0.55); display: grid; gap: var(--e-4); text-align: center;
  }
  .confirmation::backdrop { background: rgb(6 11 22 / 0.38); backdrop-filter: blur(10px) saturate(120%); -webkit-backdrop-filter: blur(10px) saturate(120%); }
  .confirmation-signe { width: 3.5rem; height: 3.5rem; margin: 0 auto; border-radius: 50%; display: grid; place-items: center;
    background: var(--accent-doux); color: var(--accent); }
  .confirmation-signe svg { width: 1.75rem; height: 1.75rem; }
  .confirmation h2 { font-size: var(--t-3); }
  .confirmation p { color: var(--texte-doux); }
  .confirmation .bouton { justify-self: center; }
  @media (prefers-reduced-motion: no-preference) { .confirmation[open] { animation: aiguillage-entree 320ms var(--courbe) both; } }

  /* ---- aiguillage d'accueil ---- */
  .aiguillage {
    width: min(44rem, calc(100% - 2 * var(--gouttiere))); max-height: calc(100svh - 4rem);
    margin: auto; padding: clamp(1.5rem, 1rem + 2.5vw, 3rem);
    background: var(--surface); color: var(--texte);
    border: var(--filet-epaisseur) solid color-mix(in srgb, var(--texte) 12%, transparent); border-radius: 1.5rem;
    display: grid; gap: var(--e-5);
    box-shadow: 0 1.5rem 4rem -1rem rgb(0 0 0 / 0.55), 0 0 0 1px rgb(255 255 255 / 0.03) inset;
  }
  /* Fond visible mais flouté (Mathieu, 28/09) ; ouverture douce, respectant la réduction des animations. */
  .aiguillage::backdrop { background: rgb(6 11 22 / 0.38); backdrop-filter: blur(10px) saturate(120%); -webkit-backdrop-filter: blur(10px) saturate(120%); }
  @media (prefers-reduced-motion: no-preference) {
    .aiguillage[open] { animation: aiguillage-entree 320ms var(--courbe) both; }
    .aiguillage[open]::backdrop { animation: d-apparait 320ms var(--courbe) both; }
  }
  @keyframes aiguillage-entree { from { opacity: 0; transform: translateY(0.75rem) scale(0.98); } }
  .aiguillage:focus-visible { outline: none; }
  .aiguillage h2 { font-size: var(--t-3); }
  .aiguillage > p { color: var(--texte-doux); max-width: 52ch; }
  .aiguillage ul { list-style: none; display: grid; gap: var(--e-2); }
  .aiguillage li a {
    display: grid; grid-template-columns: 1fr auto; gap: var(--e-1) var(--e-5); align-items: center;
    padding: var(--e-4) var(--e-5); border-radius: 1rem; border: var(--filet-epaisseur) solid var(--filet);
    background: color-mix(in srgb, var(--texte) 3%, transparent);
    transition: background var(--duree) var(--courbe), border-color var(--duree) var(--courbe);
    font-family: var(--police-titre); font-size: var(--t-2); font-weight: 600; color: var(--texte); text-decoration: none;
  }
  .aiguillage li a::after { content: "→"; grid-row: 1 / 3; grid-column: 2; color: var(--accent); font-family: var(--police-texte); transition: translate var(--duree) var(--courbe); }
  .aiguillage li a span { grid-column: 1; font-family: var(--police-texte); font-size: var(--t-moins); font-weight: 400; color: var(--texte-doux); }
  .aiguillage li a:hover, .aiguillage li a:focus-visible { color: var(--accent); border-color: var(--accent); background: var(--accent-doux); }
  .aiguillage li a:hover::after { translate: 0.3em 0; }
  .aiguillage button[data-fermer] {
    font-size: var(--t-moins); font-weight: 600; letter-spacing: 0.04em; color: var(--texte-doux);
    padding: var(--e-2) 0; justify-self: start;
  }
  .aiguillage button[data-fermer]:hover { color: var(--texte); text-decoration: underline; }
  .aiguillage button[aria-label] {
    position: absolute; top: var(--e-3); right: var(--e-3); width: 2.75rem; height: 2.75rem;
    display: grid; place-items: center; font-size: 1.5rem; line-height: 1; color: var(--texte-doux);
  }
  @media (max-width: 47.99rem) {
    .aiguillage:not([open]:modal) { margin: auto 0 0; width: 100%; max-height: 40svh; overflow-y: auto; border-inline: 0; border-bottom: 0; }
  }
}

/* --------------------------------------------------------------------------
   6. PAGES : l'accueil et la page de garde EDTECH
   -------------------------------------------------------------------------- */
@layer pages {

  /* ---- accueil : principe final, univers CORPORATE ---- */
  .page-accueil .page-tete {
    position: relative;
    padding-block: clamp(2rem, 1rem + 3vw, 4rem) clamp(3rem, 2rem + 3vw, 5rem);
    gap: var(--e-5);
  }
  .page-accueil .page-tete h1 {
    font-size: var(--t-6); font-weight: 500; line-height: 1.02;
    letter-spacing: -0.028em; max-width: 16ch; font-variation-settings: "opsz" 60;
  }
  .sous-marque {
    font-family: var(--police-titre); font-style: italic; font-weight: 400;
    font-size: var(--t-2); line-height: 1.3; color: var(--texte-doux); max-width: 34ch;
  }
  .page-accueil .chapo { font-size: var(--t-2); line-height: 1.4; color: var(--texte); max-width: 40ch; }
  /* Hero d'accueil en composition asymétrique : la marque et le titre à gauche, la méthode à droite,
     calée sur la ligne de base du titre. La colonne de droite accueillera la photographie (décision 15). */
  @media (min-width: 64rem) {
    .page-accueil .page-tete {
      grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: var(--colonnes-gap); align-items: start;
    }
    .page-accueil .page-tete > .surtitre,
    .page-accueil .page-tete > .sous-marque,
    .page-accueil .page-tete > h1 { grid-column: 1; }
    .page-accueil .page-tete > h1 { grid-row: 3 / span 4; align-self: start; }
    .page-accueil .page-tete > :is(.chapo, .methode, .signature, .actions) { grid-column: 2; }
    .page-accueil .page-tete > .chapo { grid-row: 3; font-size: var(--t-1); color: var(--texte-doux); }
    .page-accueil .page-tete > .methode { grid-row: 4; flex-direction: column; gap: var(--e-2); letter-spacing: 0.18em; }
    .page-accueil .page-tete > .signature { grid-row: 5; }
    .page-accueil .page-tete > .actions { grid-row: 6; }
    .page-accueil .methode .separateur { display: none; }
    /* Hero inversé (QV2-116) : l'offre en titre à gauche, l'explication et les boutons à droite ; le manifeste dessous. */
    .page-accueil .page-tete:has(> .manifeste) > h1 { grid-row: 3 / span 2; }
    .page-accueil .page-tete:has(> .manifeste) > .actions { grid-row: 4; align-self: start; }
    .page-accueil .page-tete > .manifeste { grid-column: 1 / -1; grid-row: 5; }
  }
  .page-accueil .page-tete:has(> .manifeste) h1 { font-size: clamp(2.3rem, 1.4rem + 2.6vw, 3.9rem); max-width: 16ch; text-wrap: balance; }
  .page-accueil .page-tete:has(> .manifeste) .h1-ligne { white-space: normal; }
  .page-accueil .page-tete:has(> .manifeste) h1:has(.h1-ligne) { max-width: 16ch; }
  .page-accueil .manifeste {
    display: grid; gap: var(--e-4) var(--colonnes-gap); margin-top: var(--e-6); padding-top: var(--e-6);
    border-top: var(--filet-epaisseur) solid var(--filet-fort);
  }
  .page-accueil .manifeste-texte { font-size: var(--t-1); line-height: 1.5; color: var(--texte-doux); max-width: 44ch; }
  .page-accueil .manifeste-titre {
    font-family: var(--police-titre); font-size: var(--t-3); line-height: 1.15; color: var(--texte); max-width: 24ch;
  }
  @media (min-width: 64rem) {
    .page-accueil .manifeste { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: start; }
    .page-accueil .manifeste > :is(.sous-marque, .manifeste-titre, .manifeste-texte) { grid-column: 1; }
    .page-accueil .manifeste > .methode { grid-row: 1 / span 3; }
    .page-accueil .manifeste > .methode { grid-column: 2; grid-row: 1 / span 2; flex-direction: column; gap: var(--e-2); letter-spacing: 0.18em; }
    .page-accueil .manifeste > .methode .separateur { display: none; }
    .page-accueil .manifeste > .signature { grid-column: 2; }
  }
  .page-accueil .methode {
    display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-4);
    font-family: var(--police-repere); font-size: clamp(0.8125rem, 0.75rem + 0.3vw, 1rem); font-weight: 500;
    letter-spacing: 0.16em; color: var(--accent);
    padding-block: var(--e-4); border-block: var(--filet-epaisseur) solid var(--filet-fort);
    max-width: 52rem;
  }
  .page-accueil .signature {
    font-family: var(--police-texte); font-weight: 600; font-size: var(--t-1); line-height: 1.4;
    letter-spacing: 0.08em; color: var(--texte);
    padding-inline-start: var(--e-4); border-inline-start: 2px solid var(--signal);
  }
  .actions { display: flex; flex-wrap: wrap; gap: var(--e-3); margin-top: var(--e-3); }

  /* strates : cinq filets horizontaux, la « fondation » de la page d'accueil */
  .page-accueil .page-tete::after {
    content: ""; position: absolute; inset-inline: var(--gouttiere); bottom: 0; height: 2.25rem;
    background: repeating-linear-gradient(to bottom, var(--filet-fort) 0 1px, transparent 1px 0.5625rem);
    mask-image: linear-gradient(to right, #000 0 55%, transparent);
    -webkit-mask-image: linear-gradient(to right, #000 0 55%, transparent);
    pointer-events: none;
  }

  /* ---- page de garde EDTECH : hero éditorial repris de l'accueil v1 ---- */
  .page-tete-editoriale { gap: var(--e-5); padding-block: clamp(1.75rem, 1rem + 2.5vw, 3.5rem) clamp(2.5rem, 1.5rem + 3vw, 4.5rem); }
  .page-tete-editoriale .accroche {
    font-family: var(--police-titre); font-weight: 500; font-size: clamp(2.5rem, 1.6rem + 3.2vw, 4.5rem);
    line-height: 1.04; letter-spacing: -0.022em; font-variation-settings: "opsz" 60; text-wrap: balance;
  }
  .page-tete-editoriale .accroche br + * , .page-tete-editoriale .accroche::first-line { color: var(--texte); }
  .page-tete-etapes { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3) var(--e-6); }
  .etapes {
    font-family: var(--police-repere); font-size: 0.8125rem; letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--texte-doux);
  }
  .page-tete-colonnes { display: grid; gap: var(--e-7); }
  @media (min-width: 60rem) {
    .page-tete-colonnes { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 0; }
    .page-tete-gauche { padding-inline-end: var(--colonnes-gap); }
    .page-tete-droite { padding-inline-start: var(--colonnes-gap); border-inline-start: var(--filet-epaisseur) solid var(--filet-fort); }
  }
  .page-tete-gauche, .page-tete-droite { display: grid; gap: var(--e-5); align-content: start; }
  .page-tete-editoriale h1 { font-size: var(--t-3); max-width: 22ch; }
  .themes { display: flex; flex-wrap: wrap; list-style: none; gap: var(--e-2) 0; }
  .themes li + li::before { content: ""; display: inline-block; width: 1px; height: 0.9em; background: var(--filet-fort); margin-inline: var(--e-3); translate: 0 0.12em; }
  .themes a { font-size: var(--t-moins); font-weight: 600; letter-spacing: 0.04em; text-decoration: none; }
  .themes a:hover { text-decoration: underline; }
  .baseline { font-family: var(--police-titre); font-style: italic; font-size: var(--t-1); color: var(--texte-doux); }

  /* ---- pages de liste et références ---- */
  .page-liste .page-tete, .page-reference .page-tete { padding-block-end: var(--e-7); }

  /* ---- pages légales : lecture continue ---- */
  .gabarit-legal .section-tete { position: static; }
}

/* --------------------------------------------------------------------------
   7. UTILITAIRES ET PRÉFÉRENCES
   -------------------------------------------------------------------------- */
@layer utilitaires {
  @media (prefers-reduced-motion: reduce) {
    /* Le bouton MCP a sa propre onde lente pour ce mode (QV2-140) : sans cette exception, son animation sans fin tournait
       à 0,01 ms par cycle, d'où le clignotement vu par Mathieu. */
    *:not(.relais-ia, .relais-ia-rond), *:not(.relais-ia, .relais-ia-rond)::before, *::after {
      transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; scroll-behavior: auto !important; }
  }
  @media (forced-colors: active) {
    .bouton, .cta-entete { border: 1px solid ButtonText; }
    .section-rang::after, .surtitre::before { background: CanvasText; }
  }
}

/* Chaque bloc et chaque étape de frise mesure sa propre largeur : justifié seulement à partir de 18rem. */
@layer composants {
  .blocs:not(.blocs-reperes) > .bloc, .parcours-etape { container-type: inline-size; }
  @container (max-width: 18rem) { .bloc p, .parcours-etape p { text-align: start !important; } }
}

/* ---- justification, tout le site (Mathieu, 29/09 : « vérifie les hero si les paragraphes sont justifiés, ne fais pas à
   moitié » ; « et ces paragraphes ne sont pas justifiés ??? ») : tout le texte courant, heros compris, est justifié.
   Restent tels quels les lignes d'affiche (sous-marque, titres, signature, méthode) et les textes centrés.
   Jamais de césure ; alignement à gauche sous 30rem, où la justification ouvre de grands blancs. */
@layer composants {
  :is(.page-tete, .page-tete-droite) :is(.chapo, .chapo-suite > p:not(.chapo-suite-titre, .chapo-suite-signature), .manifeste-texte),
  main :is(.section-corps > p, .repli > p, .bloc p:not(.bloc-lien), .carte-invitation p:not(.carte-invitation-titre),
           .onglet-fiche, .onglet-panneau > p, .parcours-etape p, .section-illustration figcaption, .encart-autre p,
           .enfants li > p, .avec-visuel > p, .mention, .formulaire-intro, .diag-consigne, .diag-note, .champ-aide, .etape-aide) {
    text-align: justify; text-justify: inter-word; hyphens: manual; -webkit-hyphens: manual;
  }
  @media (max-width: 30rem) {
    :is(.page-tete, .page-tete-droite) :is(.chapo, .chapo-suite > p, .manifeste-texte),
    main :is(.section-corps > p, .repli > p, .bloc p, .carte-invitation p, .onglet-fiche, .onglet-panneau > p,
             .parcours-etape p, .section-illustration figcaption, .encart-autre p, .enfants li > p, .avec-visuel > p,
             .mention, .formulaire-intro, .diag-consigne, .diag-note, .champ-aide, .etape-aide) { text-align: start; }
  }
}

/* ---- vignettes de section et repères à icône (Mathieu, 30/09) ---- */
@layer composants {
  .section-vignette { display: none; margin: 0; color: var(--accent); }
  .section-vignette .decor { width: 100%; height: auto; max-height: 18rem; }
  @media (min-width: 64rem) {
    .section-vignette { display: block; grid-column: 9 / -1; grid-row: 1 / span 3; align-self: center; }
    .section-grille:has(> .section-vignette) > .section-tete { grid-column: 1 / span 8; grid-row: 1; }
    .section-grille:has(> .section-vignette) > .section-corps { grid-column: 1 / span 8; grid-row: 2; }
    .section-grille:has(> .section-vignette) > .blocs { grid-column: 1 / span 8; grid-row: 3; }
  }
  .blocs.blocs-reperes > .bloc.bloc-icone { display: inline-flex; align-items: center; gap: 0.5em; }
  .blocs.blocs-reperes > .bloc-icone > .icone { width: 1.15rem; height: 1.15rem; margin: 0; flex: none; color: var(--accent); stroke-width: 1.6; }
  .blocs.blocs-reperes > .bloc-icone:hover .icone { transform: none; }
}

/* ---- pastille d'événement dans le hero de l'accueil (QV2-123, amovible : reglages.json › pastille_accueil) ----
   Claire et haute, texte sur deux lignes (Mathieu, 29/09) : aux couleurs claires de la page de Lyon, lisible sur fond sombre. */
@layer composants {
  .pastille-accueil {
    display: grid; grid-template-columns: auto 1fr; column-gap: 0.8em; row-gap: 0.25em; align-items: center;
    width: fit-content; max-width: 100%; margin-block: var(--e-3) var(--e-2); padding: 0.95em 1.4em 0.95em 1.15em;
    border-radius: 1.1rem; background: #F5F4FF; color: #1A1830; text-decoration: none; line-height: 1.3;
    rotate: -1.5deg; box-shadow: 0 0.6rem 1.6rem -0.7rem rgb(0 0 0 / 0.55);
    transition: rotate var(--duree) var(--courbe);
  }
  .pastille-accueil::before {
    content: ""; grid-row: 1 / span 2; width: 0.7em; height: 0.7em; border-radius: 50%; background: #5646D6;
    box-shadow: 0 0 0 0.3em rgb(86 70 214 / 0.18);
  }
  .pastille-accueil-texte { grid-column: 2; grid-row: 1; font-size: var(--t-1); font-weight: 600; }
  .pastille-accueil-ligne { grid-column: 2; grid-row: 2; font-size: var(--t-moins); }
  .pastille-accueil-date { color: #4A4766; }
  .pastille-accueil-date::after { content: "\00a0·"; }
  .pastille-accueil-lien { color: #5646D6; font-weight: 600; white-space: nowrap; }
  .pastille-accueil-lien::after { content: "\00a0›"; }
  .pastille-accueil:hover, .pastille-accueil:focus-visible { rotate: 0deg; text-decoration: none; }
  .pastille-accueil:hover .pastille-accueil-lien, .pastille-accueil:focus-visible .pastille-accueil-lien { text-decoration: underline; text-underline-offset: 0.2em; }
  .pastille-accueil:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
  @media (prefers-reduced-motion: reduce) { .pastille-accueil { rotate: none; transition: none; } }
}

/* Page compacte (QV2-140, guide court) : même charte, rythme resserré ; sur grand écran, le titre de section à gauche
   et le texte à droite, pour que la page tienne presque en un écran. */
@layer pages {
  .page-compacte { --rythme-section: clamp(1.75rem, 1.25rem + 1.25vw, 2.5rem); }
  .page-compacte .page-tete { padding-block: clamp(1.25rem, 0.75rem + 1.5vw, 2.25rem) clamp(1.5rem, 1rem + 1.5vw, 2.5rem); }
  @media (max-width: 63.99rem) { .page-compacte .page-tete-decor { display: none; } }
  .page-compacte .section-grille { row-gap: var(--e-4); }
  .page-compacte .section-actions { margin-top: var(--e-3); }
  .page-compacte .copie { margin-block: 0; }
  .page-tete .copie { margin-block: var(--e-2) 0; grid-column: 1; }
  @media (min-width: 64rem) {
    .page-compacte .page-tete-decor { max-width: 19rem; }
    .page-compacte .page-tete { padding-block-end: var(--e-5); }
    .page-compacte .section-grille > .section-tete { grid-column: 1 / span 4; grid-row: 1 / span 2; }
    .page-compacte .section-grille > .section-tete h2 { max-width: none; }
    .page-compacte .section-grille > .section-corps,
    .page-compacte .section-grille > .blocs,
    .page-compacte .section-grille > .copie { grid-column: 5 / -1; }
    .page-compacte .section-grille > .section-corps { grid-row: 1; }
    .page-compacte .section-grille > .parcours { grid-column: 1 / -1; }
    .page-compacte .repli[open] { column-count: 1; }
  }
}

/* Bouton rond « MCP » (QV2-140) : en haut à droite, dans la marge, sur toutes les pages, à la couleur d'accent du thème ;
   un halo plein pulse dessous ; au survol ou au focus, une bulle dit ce que le connecteur apporte, avec l'adresse à copier
   et le guide. Affiché seulement quand la marge le permet (grille de 82rem). */
@layer pages {
  .relais-ia { display: none; }
  @media (min-width: 96rem) {
    .relais-ia { display: block; position: fixed; z-index: 20; top: calc(var(--hauteur-entete, 7rem) + var(--e-6));
      inset-inline-end: max(1rem, calc((100vw - var(--largeur)) / 4 - 2rem)); }
    .relais-ia-rond {
      position: relative; display: grid; place-content: center; justify-items: center; gap: 0.25rem;
      width: 4.25rem; height: 4.25rem; border-radius: 50%; border: 2px solid var(--accent);
      background: var(--surface-haute, var(--surface)); color: var(--accent); text-decoration: none;
      box-shadow: 0 6px 20px rgb(0 0 0 / 0.25);
      transition: background-color var(--duree) var(--courbe), color var(--duree) var(--courbe), transform var(--duree) var(--courbe);
    }
    .relais-ia-rond::before {             /* le halo plein qui pulse sous le bouton */
      content: ""; position: absolute; inset: -2px; z-index: -1; border-radius: 50%; background: var(--accent);
      opacity: 0.45; transform: scale(1.3);
    }
    .relais-ia-rond .icone { width: 1.5rem; height: 1.5rem; stroke-width: 1.6; color: currentColor; }
    .relais-ia-sigle { font-family: var(--police-texte); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.12em;
      margin-inline-start: 0.12em; line-height: 1; color: var(--texte); }
    .relais-ia-rond:focus-visible { outline: 2px solid var(--focus); outline-offset: 10px; }
    .relais-ia:is(:hover, :focus-within) .relais-ia-rond { background: var(--accent); color: var(--sur-accent); transform: scale(1.05); }
    .relais-ia:is(:hover, :focus-within) .relais-ia-sigle { color: var(--sur-accent); }
    .relais-ia-nom { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

    /* La bulle, sous le bouton, avec sa pointe ; le retrait intérieur fait pont pour le survol. */
    .relais-ia-bulle {
      position: absolute; inset-inline-end: -0.5rem; top: 100%; width: 23rem; padding-block-start: var(--e-5);
      transform: translateY(-0.5rem); opacity: 0; visibility: hidden;
      transition: opacity var(--duree) var(--courbe), transform var(--duree) var(--courbe), visibility 0s linear var(--duree);
    }
    .relais-ia:is(:hover, :focus-within) .relais-ia-bulle { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
    .relais-ia-bulle::before {            /* le cadre */
      content: ""; position: absolute; inset: var(--e-5) 0 0 0; z-index: -1; border-radius: calc(var(--rayon) * 2);
      border: var(--filet-epaisseur) solid color-mix(in srgb, var(--accent) 55%, transparent); border-top: 3px solid var(--accent);
      background: var(--surface-haute, var(--surface)); box-shadow: 0 18px 44px rgb(0 0 0 / 0.3);
    }
    .relais-ia-bulle::after {             /* la pointe, vers le bouton */
      content: ""; position: absolute; top: calc(var(--e-5) - 7px); inset-inline-end: 2.4rem; width: 12px; height: 12px;
      background: var(--accent); transform: rotate(45deg); border-radius: 2px;
    }
    .relais-ia-bulle > * { margin-inline: var(--e-5); }
    .relais-ia-surtitre { margin-block: var(--e-5) var(--e-2); font-family: var(--police-repere); font-size: 0.6875rem;
      letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
    .relais-ia-titre { margin-block: 0 var(--e-4); font-family: var(--police-titre); font-size: 1.3125rem; line-height: var(--interligne-titre); color: var(--texte); }
    .relais-ia-bulle ul { margin-block: 0 var(--e-4); padding: 0; list-style: none; display: grid; gap: var(--e-3); }
    .relais-ia-bulle li { display: grid; grid-template-columns: 1.75rem 1fr; gap: var(--e-3); align-items: start;
      font-size: 0.875rem; line-height: 1.45; color: var(--texte-doux); text-align: start; }
    .relais-ia-bulle li .icone { width: 1.75rem; height: 1.75rem; padding: 0.3rem; border-radius: 50%; stroke-width: 1.6;
      color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); }
    .relais-ia-compat { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin-block: 0 var(--e-4);
      font-size: 0.75rem; color: var(--texte-discret); }
    .relais-ia-compat > span:first-child { margin-inline-end: 0.25rem; }
    .relais-ia-puce { padding: 0.15rem 0.55rem; border-radius: 999px; border: var(--filet-epaisseur) solid var(--filet-fort); color: var(--texte); }
    .relais-ia-bulle .copie { margin-block: 0 var(--e-3); padding: var(--e-3); width: auto; max-width: none; gap: var(--e-3);
      background: var(--fond); border-color: var(--filet-fort); }
    .relais-ia-bulle .copie-libelle { display: none; }
    .relais-ia-bulle .copie-valeur { flex-basis: 100%; font-size: 0.9375rem; }
    .relais-ia-bulle .copie-bouton { flex: 1; justify-content: center; margin: 0; padding: 0.55rem 1rem;
      background: var(--accent); color: var(--sur-accent); }
    .relais-ia-bulle .copie-bouton:hover, .relais-ia-bulle .copie-bouton[data-copiee] { background: var(--accent-fort); }
    .relais-ia-lien { display: flex; justify-content: center; margin-block-end: var(--e-5); padding: 0.5rem 1rem; border-radius: 999px;
      border: 1.5px solid var(--accent); font-weight: 600; font-size: 0.875rem; color: var(--accent); text-decoration: none; }
    .relais-ia-lien:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
    .relais-ia-lien::after { content: " →"; white-space: pre; }
  }
  /* Une onde, pas un clignotement (Mathieu, 30/09 : « doux et smooth comme une onde ») : deux cercles décalés d'une
     demi-période naissent invisibles, apparaissent en douceur, s'élargissent lentement et s'effacent ; aucun saut. */
  @media (min-width: 96rem) and (prefers-reduced-motion: no-preference) {
    .relais-ia::before {
      content: ""; position: absolute; top: 0; inset-inline-end: 0; width: 4.25rem; height: 4.25rem; z-index: -1;
      border-radius: 50%; background: var(--accent); opacity: 0; pointer-events: none;
      animation: relais-ia-onde 6s cubic-bezier(0.22, 0.61, 0.36, 1) -3s 10;
    }
    .relais-ia-rond::before { opacity: 0; animation: relais-ia-onde 6s cubic-bezier(0.22, 0.61, 0.36, 1) 10; }
    @keyframes relais-ia-onde {
      0% { transform: scale(1); opacity: 0; }
      18% { opacity: 0.32; }
      100% { transform: scale(1.75); opacity: 0; }
    }
    .relais-ia:is(:hover, :focus-within)::before { animation: none; opacity: 0; }
  }
  /* Animations réduites (réglage actif sur le Mac de Mathieu, vérifié le 30/09) : la même onde, plus lente et plus courte,
     au lieu d'un disque qui s'allume et s'éteint (perçu comme un clignotement). */
  @media (min-width: 96rem) and (prefers-reduced-motion: reduce) {
    .relais-ia::before {
      content: ""; position: absolute; top: 0; inset-inline-end: 0; width: 4.25rem; height: 4.25rem; z-index: -1;
      border-radius: 50%; background: var(--accent); opacity: 0; pointer-events: none;
      animation: relais-ia-onde-lente 8s cubic-bezier(0.22, 0.61, 0.36, 1) -4s 8;
    }
    .relais-ia-rond::before { opacity: 0; animation: relais-ia-onde-lente 8s cubic-bezier(0.22, 0.61, 0.36, 1) 8; }
    @keyframes relais-ia-onde-lente {
      0% { transform: scale(1); opacity: 0; }
      20% { opacity: 0.28; }
      100% { transform: scale(1.45); opacity: 0; }
    }
    .relais-ia:is(:hover, :focus-within)::before { animation: none; opacity: 0; }
  }
  @media (min-width: 96rem) { .relais-ia:is(:hover, :focus-within) .relais-ia-rond::before { animation: none; opacity: 0; } }
  @media print { .relais-ia { display: none !important; } }
}

/* Surtitre « EdTech » de la page Éducation, avec le drapeau européen (QV2-140) : bien lisible dans l'en-tête. */
@layer pages {
  .accroche-bloc > .surtitre-drapeau { margin-bottom: var(--e-5); }
  .surtitre-drapeau { display: inline-flex; align-items: center; gap: var(--e-3); font-size: clamp(0.875rem, 0.8rem + 0.35vw, 1.0625rem);
    letter-spacing: 0.14em; color: var(--texte); }
  .surtitre-drapeau .drapeau { width: 2.25em; height: 1.5em; flex: none; border-radius: 2px; box-shadow: 0 0 0 1px color-mix(in srgb, var(--texte) 15%, transparent); }
}
