/* ============================================================
   garbewajda.com, design system
   Direction : noir et blanc, bleu profond #14345f en accent (12,5:1 sur blanc),
   bleu acier #8fb0e8 en sombre, une seule lumière vive #2997ff (section 32).
   Blanc, gris froid #f5f5f7, bandes noires, encre #1d1d1f. Inter auto-hébergée.
   Les apparitions au défilement ont été retirées le 11 septembre 2026 ;
   les mouvements restants sont ceux de la section 25 (fond) et de la section 32
   (portrait, défilé, chiffres, auréoles), tous coupés sous prefers-reduced-motion.
   Ce fichier sert toutes les pages ; s'y ajoutent etude.css et estimation.css sur
   les études de cas, erreur.css sur la page 404. Aucun style en ligne dans les pages
   (section 33), la politique de sécurité du contenu s'appuie dessus.
   ============================================================ */

/* ------------------------------------------------------------
   0. Polices : Inter (variable, licence OFL) et Atkinson Hyperlegible (OFL),
   servies depuis assets/fonts en sous-ensembles latin et latin étendu.
   Aucune requête vers un tiers ; Atkinson ne se télécharge que si le réglage
   « police très lisible » l'emploie.
   ------------------------------------------------------------ */
@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("../fonts/inter-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: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("../fonts/inter-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: "Atkinson Hyperlegible";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/atkinson-hyperlegible-latin-ext-400.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: "Atkinson Hyperlegible";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/atkinson-hyperlegible-latin-400.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: "Atkinson Hyperlegible";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/atkinson-hyperlegible-latin-ext-700.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: "Atkinson Hyperlegible";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/atkinson-hyperlegible-latin-700.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;
}

/* ------------------------------------------------------------
   1. Tokens
   ------------------------------------------------------------ */
:root {
    /* Couleurs, mode clair */
    --bg: #ffffff;
    --bg-alt: #f5f5f7;
    --panel: #000000;          /* bandes noires signature */
    --panel-ink: #f5f5f7;
    --panel-mute: #86868b;
    --ink: #1d1d1f;
    --mute: #636366;
    --rule: #d2d2d7;
    /* Bordure des composants qu'on manipule : champs, filtres, boutons de réglage.
       #d2d2d7 ne tient que 1,51:1 sur blanc, sous le seuil de 3:1 du critère RGAA 3.3
       (contraste des composants d'interface). #86868b tient 3,52:1 sur blanc,
       4,84:1 sur le fond des champs en sombre et 5,96:1 sur le noir : une seule
       valeur pour les deux thèmes. Les filets décoratifs gardent --rule. */
    --bord-controle: #86868b;
    --accent: #14345f;         /* bleu profond, 12,5:1 sur blanc */
    --accent-hover: #1d477f;
    --accent-on-dark: #8fb0e8; /* bleu acier sur fond noir, 9,5:1 */
    --navy: #0e2a4d;           /* blocs visuels */
    --sur-accent: #ffffff;     /* texte posé sur un fond --accent */
    --nav-bg: rgba(255, 255, 255, 0.72);
    --card: #ffffff;
    --card-on-alt: #ffffff;

    /* Typographie : Inter partout, hébergée avec le site (assets/fonts, déclarée en tête de feuille),
       la police système ne sert que de relais le temps du chargement */
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
            "Helvetica Neue", Roboto, Arial, sans-serif;
    --text-sm: 0.875rem;       /* 14px */
    --text-base: 1.0625rem;    /* 17px : corps Apple */
    --text-lg: 1.3125rem;      /* 21px */
    --text-xl: 1.75rem;        /* 28px */

    /* Espacements */
    --s-1: 0.25rem;
    --s-2: 0.5rem;
    --s-3: 0.75rem;
    --s-4: 1rem;
    --s-5: 1.25rem;
    --s-6: 1.5rem;
    --s-8: 2rem;
    --s-10: 2.5rem;
    --s-12: 3rem;
    --s-16: 4rem;
    --s-20: 5rem;

    /* Géométrie */
    --container: 980px;
    --container-text: 692px;
    --gutter: max(22px, env(safe-area-inset-left));
    --section-pad: clamp(5rem, 10vw, 8.5rem);
    --r: 10px;
    --r-lg: 14px;
    --r-pill: 980px;

    /* Mouvement */
    --ease: cubic-bezier(0.25, 0.1, 0.25, 1);
    --ease-out: cubic-bezier(0.32, 0.72, 0, 1);
    /* le mouvement (section 42) */
    --mv-entree: cubic-bezier(0.05, 0.7, 0.1, 1);
    --mv-sortie: cubic-bezier(0.3, 0, 0.8, 0.15);
    --mv-appui: cubic-bezier(0.2, 0, 0, 1);
    --mv-t-appui: 90ms;
    --mv-t-relache: 180ms;
    --mv-t-survol: 160ms;
    --mv-court: 180ms;
    --mv-moyen: 320ms;
    --mv-long: 560ms;

    color-scheme: light;
}

html[data-theme="dark"] {
    --bg: #000000;
    --bg-alt: #161617;
    --panel: #161617;
    --panel-ink: #f5f5f7;
    --panel-mute: #86868b;
    --ink: #f5f5f7;
    --mute: #86868b;
    --rule: #424245;
    --accent: #8fb0e8;
    --accent-hover: #a9c4f0;
    --accent-on-dark: #8fb0e8;
    --navy: #1b3a63;           /* blocs visuels en sombre : 5,2:1 avec #8fb0e8, visible sur --card */
    --sur-accent: #000000;
    --nav-bg: rgba(22, 22, 23, 0.72);
    --card: #1d1d1f;
    --card-on-alt: #1d1d1f;
    color-scheme: dark;
}
/* Préférence système « sombre », avant que le script n'ait posé data-theme : mêmes jetons, en CSS pur,
   pour que le premier affichage soit déjà sombre (plus d'écran blanc qui fond vers le noir).
   Un choix explicite « clair » dans le panneau l'emporte. */
@media (prefers-color-scheme: dark) {
    html:not([data-theme="light"]) {
        --bg: #000000;
        --bg-alt: #161617;
        --panel: #161617;
        --panel-ink: #f5f5f7;
        --panel-mute: #86868b;
        --ink: #f5f5f7;
        --mute: #86868b;
        --rule: #424245;
        --accent: #8fb0e8;
        --accent-hover: #a9c4f0;
        --accent-on-dark: #8fb0e8;
        --navy: #1b3a63;
        --sur-accent: #000000;
        --nav-bg: rgba(22, 22, 23, 0.72);
        --card: #1d1d1f;
        --card-on-alt: #1d1d1f;
        color-scheme: dark;
    }
}

/* ------------------------------------------------------------
   2. Base
   ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--font);
    font-size: var(--text-base);
    line-height: 1.6;
    letter-spacing: -0.011em;
    color: var(--ink);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    transition: background 0.4s var(--ease), color 0.4s var(--ease);
}

body.menu-open { overflow: hidden; }

::selection { background: var(--accent); color: var(--sur-accent); }

/* Citations courtes : la balise q porte la sémantique, le navigateur pose les guillemets
   français à la place de ceux qui étaient écrits à la main (RGAA 9.4). */
q { quotes: "« " " »" "“" "”"; }

img, svg { max-width: 100%; height: auto; display: block; }

/* Les images sont servies en AVIF, WebP puis JPEG par <picture>. Le conteneur ne doit
   rien changer à la mise en page : « display: contents » l'efface de la disposition,
   l'<img> se comporte exactement comme s'il était resté seul dans son parent. */
picture { display: contents; }

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4 {
    font-weight: 700;
    letter-spacing: -0.022em;
    line-height: 1.08;
    text-wrap: balance;
}

h1 { font-size: clamp(2.6rem, 7vw, 4.5rem); }
h2 { font-size: clamp(2rem, 5vw, 3.25rem); }
h3 { font-size: clamp(1.35rem, 2.6vw, 1.75rem); letter-spacing: -0.017em; }

p { text-wrap: pretty; }

.skip-link {
    position: fixed;
    top: -100px;
    left: var(--s-4);
    z-index: 10001;
    padding: var(--s-3) var(--s-6);
    background: var(--accent);
    color: var(--sur-accent);
    border-radius: var(--r-pill);
    font-weight: 600;
    transition: top 0.2s var(--ease);
}
.skip-link:focus { top: var(--s-4); }
/* Deuxième accès rapide, en tête de page : arrêter les mouvements automatiques.
   Même traitement que le lien d'évitement, posé à droite pour ne pas le recouvrir.
   Il commande le même réglage que le panneau (RGAA 13.8, WCAG 2.2.2) : un moyen
   d'arrêt existe en tête de chaque page, pas seulement au fond d'un tiroir. */
.skip-link--mouvement {
    left: auto;
    right: var(--s-4);
    font: inherit;
    font-size: var(--text-base);
    font-weight: 600;
    border: 0;
    cursor: pointer;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ------------------------------------------------------------
   3. Navigation : barre translucide
   ------------------------------------------------------------ */
.nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    border-bottom: 1px solid transparent;
    transition: border-color 0.3s var(--ease);
}
/* Le voile translucide et son flou vivent sur un pseudo-élément, pas sur la barre elle-même : un backdrop-filter posé
   sur .nav en faisait le bloc conteneur du menu mobile (position: fixed), qui se retrouvait haut de 64 px et laissait
   ses liens déborder sur la page, sans fond (bug relevé par Maël le 12 septembre 2026 sur téléphone). */
.nav::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--nav-bg);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    transition: background 0.4s var(--ease);
}
.nav.scrolled { border-bottom-color: var(--rule); }
/* Au téléphone, et pour qui demande moins de transparence : un fond presque plein, sans flou. Un flou de 20 px au-dessus
   d'une toile qui change à chaque image se paie sur le processeur graphique d'un téléphone ; à 97 %, le texte qui passe
   dessous se devine à peine et ne se mêle plus au nom. Contraste renforcé : fond plein partout. Le nom de transition
   vit sur .nav-container (section 38) : posé sur .nav, il coupait le flou du bureau (la barre ne voyait plus la page). */
@media (max-width: 820px), (prefers-reduced-transparency: reduce) {
    .nav::before {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: color-mix(in srgb, var(--bg) 97%, transparent);
    }
}
html.a11y-contraste .nav::before { background: var(--bg); }

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

.nav-logo {
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.02em;
}

.nav-menu {
    display: flex;
    align-items: center;
    gap: var(--s-8);
    list-style: none;
}

.nav-menu a {
    font-size: 0.8125rem;
    color: var(--mute);
    letter-spacing: -0.01em;
    transition: color 0.2s var(--ease);
}
.nav-menu a.active, .nav-menu a:focus-visible { color: var(--ink); }
@media (hover: hover) and (pointer: fine) { .nav-menu a:hover { color: var(--ink); } }

.nav-menu a.nav-cta {
    color: var(--sur-accent);
    background: var(--accent);
    padding: 6px 14px;
    border-radius: var(--r-pill);
    font-weight: 500;
}
/* en bloc pour l'appui (section 42), à la taille et à la place de la pastille en ligne : 28 px, la ligne inchangée */
@media (min-width: 821px) { .nav-menu a.nav-cta { display: inline-block; line-height: normal; margin-block: -1px; } .nav-menu a.nav-cta:focus-visible { background: var(--accent-hover); color: var(--sur-accent); } .nav-menu a.nav-cta.active { box-shadow: 0 0 0 2px var(--bg), 0 0 0 3.5px var(--accent); } }
@media (hover: hover) and (pointer: fine) and (min-width: 821px) { .nav-menu a.nav-cta:hover { background: var(--accent-hover); color: var(--sur-accent); } }
/* « Appeler » : au téléphone seulement, à côté du bouton du menu, hors de la liste : appeler sans ouvrir le menu */
.nav-appel { display: none; }

.menu-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;                 /* cible tactile 44 px minimum */
    height: 44px;
    padding: 0 10px;
    background: none;
    border: 0;
    cursor: pointer;
}
.menu-toggle span {
    display: block;
    height: 1.5px;
    background: var(--ink);
    border-radius: 2px;
    transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
}
.menu-toggle.active span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.menu-toggle.active span:nth-child(2) { opacity: 0; }
.menu-toggle.active span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

@media (max-width: 820px) {
    .menu-toggle { display: flex; }
    .nav-appel {
        display: inline-flex; align-items: center; height: 40px; padding: 0 14px; margin-left: auto; margin-right: calc(var(--s-2) - var(--s-6));
        border-radius: var(--r-pill); background: var(--accent); color: var(--sur-accent); font-size: 0.875rem; font-weight: 600; white-space: nowrap;
        touch-action: manipulation; -webkit-tap-highlight-color: transparent;
    }
    .nav-appel:focus-visible { background: var(--accent-hover); color: var(--sur-accent); }
    .nav-menu {
        position: fixed;
        inset: 52px 0 0 0;
        flex-direction: column;
        align-items: flex-start;
        justify-content: flex-start;
        gap: 0;
        padding: var(--s-8) var(--gutter);
        background: var(--bg);
        overflow-y: auto;            /* petits écrans en paysage : la liste défile dans le menu */
        opacity: 0;
        visibility: hidden;
        transform: translateY(-8px);
        transition: opacity 0.3s var(--ease), transform 0.3s var(--ease),
                    visibility 0s 0.3s;
    }
    .nav-menu.active {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
    }
    .nav-menu li { width: 100%; border-bottom: 1px solid var(--rule); }
    .nav-menu a {
        display: block;
        padding: var(--s-4) 0;
        font-size: 1.5rem;
        font-weight: 600;
        letter-spacing: -0.02em;
        color: var(--ink);
    }
    .nav-menu a.nav-cta {
        background: none;
        color: var(--accent);
        padding: var(--s-4) 0;
        border-radius: 0;
    }
    /* la page où l'on est, soulignée dans le menu déplié */
    .nav-menu a.active { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.3em; }
    /* En sombre, le lien Contact du menu déplié reprend l'accent : la règle « texte noir sur pastille claire » du
       bouton de bureau (section 22) le rendait noir sur noir (bug relevé par Maël le 12 septembre 2026). */
    html[data-theme="dark"] .nav-menu a.nav-cta,
    html.a11y-contraste .nav-menu a.nav-cta,
    html.a11y-contraste[data-theme="dark"] .nav-menu a.nav-cta { color: var(--accent); background: none; }
}

/* ------------------------------------------------------------
   4. Boutons & liens
   ------------------------------------------------------------ */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    padding: 12px 22px;
    border-radius: var(--r-pill);
    font-size: var(--text-base);
    font-weight: 500;
    letter-spacing: -0.01em;
    line-height: 1.2;
    cursor: pointer;
    border: 0;
    transition: background 0.2s var(--ease), color 0.2s var(--ease),
                transform 0.2s var(--ease);
}
/* l'appui : la couleur ; l'enfoncement en section 42 */
.btn { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

.btn-primary { background: var(--accent); color: var(--sur-accent); }
.btn-primary:focus-visible { background: var(--accent-hover); }

.btn-ghost {
    background: transparent;
    color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent);
}
.btn-ghost:focus-visible { background: var(--accent); color: var(--sur-accent); }
@media (hover: hover) and (pointer: fine) {
    .btn-primary:hover { background: var(--accent-hover); }
    .btn-ghost:hover { background: var(--accent); color: var(--sur-accent); }
}
.btn-primary:active, .btn-ghost:active { background: color-mix(in srgb, var(--accent) 84%, #000); color: var(--sur-accent); }

.btn-lg { padding: 15px 28px; font-size: var(--text-lg); }

/* Lien fléché « En savoir plus › » */
.link-more {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--accent);
    font-size: var(--text-base);
    font-weight: 400;
}
.link-more::after { content: "›"; font-size: 1.15em; transition: transform 0.2s var(--ease); }
.link-more:focus-visible { text-decoration: underline; }
.link-more:focus-visible::after { transform: translateX(2px); }

.text-link { color: var(--accent); }
.text-link:focus-visible { text-decoration: underline; }
@media (hover: hover) and (pointer: fine) {
    .link-more:hover, .text-link:hover { text-decoration: underline; }
    .link-more:hover::after { transform: translateX(2px); }
}

/* ------------------------------------------------------------
   5. Sections & structure
   ------------------------------------------------------------ */
.section {
    padding: var(--section-pad) var(--gutter);
}
.section--alt { background: var(--bg-alt); }

.section-head {
    max-width: var(--container-text);
    margin: 0 auto var(--s-16);
    text-align: center;
}
.section-head h2 { margin-bottom: var(--s-4); }
.section-head p {
    font-size: var(--text-lg);
    color: var(--mute);
    letter-spacing: -0.015em;
}

.overline {
    display: block;
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--mute);
    margin-bottom: var(--s-3);
    letter-spacing: -0.01em;
}

/* ------------------------------------------------------------
   6. Hero
   ------------------------------------------------------------ */
.hero {
    padding: calc(52px + clamp(4.5rem, 12vw, 9rem)) var(--gutter) var(--section-pad);
    text-align: center;
}
.hero-inner { max-width: 820px; margin: 0 auto; }

.hero-kicker {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--mute);
    margin-bottom: var(--s-4);
    letter-spacing: -0.015em;
}

.hero h1 { margin-bottom: var(--s-6); }

.hero-lede {
    font-size: clamp(1.1875rem, 2.4vw, 1.5rem);
    line-height: 1.45;
    color: var(--mute);
    letter-spacing: -0.017em;
    max-width: 640px;
    margin: 0 auto var(--s-10);
}
.hero-lede strong { color: var(--ink); font-weight: 600; }

.hero-cta {
    display: flex;
    gap: var(--s-4);
    justify-content: center;
    flex-wrap: wrap;
    align-items: center;
}

/* ------------------------------------------------------------
   7. Bande sombre : méthode de travail
   ------------------------------------------------------------ */
.panel {
    background: var(--panel);
    color: var(--panel-ink);
    padding: var(--section-pad) var(--gutter);
}
.panel-inner { max-width: var(--container); margin: 0 auto; text-align: center; }

.panel .overline { color: var(--panel-mute); }

.panel h2 {
    font-size: clamp(2.2rem, 6vw, 4rem);
    margin-bottom: var(--s-6);
}

.panel-lede {
    font-size: var(--text-lg);
    color: var(--panel-mute);
    max-width: 620px;
    margin: 0 auto var(--s-12);
    letter-spacing: -0.015em;
}
.panel-lede strong { color: var(--panel-ink); font-weight: 600; }

.panel .link-more { font-size: var(--text-lg); color: var(--accent-on-dark); }

/* Piliers : principes intemporels, sans chiffres qui vieillissent */
.pillars {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-8);
    text-align: left;
    max-width: 860px;
    margin: 0 auto;
}
@media (max-width: 820px) { .pillars { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .pillars { grid-template-columns: 1fr; } }

.pillar { padding-top: var(--s-4); border-top: 1px solid rgba(255, 255, 255, 0.22); }
.pillar h3 {
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -0.018em;
    margin-bottom: var(--s-2);
}
.pillar p { font-size: var(--text-sm); color: var(--panel-mute); line-height: 1.5; }

/* ------------------------------------------------------------
   8. Cards
   ------------------------------------------------------------ */
.card {
    background: var(--bg-alt);
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    padding: clamp(1.75rem, 4vw, 3rem);
}
.section--alt .card { background: var(--card-on-alt); }

a.card { display: block; }

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--s-6);
    max-width: var(--container);
    margin: 0 auto;
}

/* Grille à deux colonnes quand quatre cartes doivent rester en carré */
/* minmax(0, 1fr) : une colonne peut descendre sous la largeur naturelle de son contenu (un tableau,
   une adresse longue), sinon la grille s'élargit au-delà de la page entre 641 et 1023 pixels */
.card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 640px) { .card-grid--2 { grid-template-columns: 1fr; } }

.card .overline { margin-bottom: var(--s-2); font-size: var(--text-sm); }
.card h3 { margin-bottom: var(--s-3); }
.card p { color: var(--mute); font-size: var(--text-base); }
.card .link-more { margin-top: var(--s-6); }

/* ------------------------------------------------------------
   9. Timeline (parcours) : l'ordre est l'information
   ------------------------------------------------------------ */
.timeline { max-width: var(--container-text); margin: 0 auto; }

.timeline-item {
    position: relative;
    padding: 0 0 var(--s-12) var(--s-10);
    border-left: 1px solid var(--rule);
}
.timeline-item:last-child { padding-bottom: 0; }
.timeline-item::before {
    content: "";
    position: absolute;
    left: -5px;
    top: 8px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--accent);
}

.timeline-date {
    font-size: var(--text-sm);
    color: var(--mute);
    margin-bottom: var(--s-1);
}
.timeline-item h3 { margin-bottom: var(--s-1); }
.timeline-role {
    font-size: var(--text-base);
    color: var(--accent);
    font-weight: 500;
    margin-bottom: var(--s-3);
}
.timeline-item p { color: var(--mute); }
.timeline-item p strong { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------
   11. Pages article : leurs règles vivent dans journal.css ; reste ici le cadre
   qui fait défiler un tableau large, commun aux études et aux mesures
   ------------------------------------------------------------ */
.table-scroll { overflow-x: auto; }

/* ------------------------------------------------------------
   12. Pages « document » : mentions légales, déclaration d'accessibilité,
   plan du site. Une mise en page de dossier plutôt que de blocs : en-tête
   avec une forme géométrique propre à la page, bande de faits clés entre
   deux filets, sommaire collant à gauche sur grand écran, numéros de
   section en grands chiffres évidés, tableaux réduits à leurs filets,
   encadrés remplacés par un filet d'accent. Rien n'est en boîte.
   ------------------------------------------------------------ */
.legal-page {
    max-width: var(--container-text);
    margin: 0 auto;
    padding: calc(52px + clamp(3.5rem, 9vw, 6rem)) var(--gutter) var(--section-pad);
}
.legal-page header { margin-bottom: var(--s-16); }
.legal-page header h1 { margin-bottom: var(--s-4); }
.legal-page header p { color: var(--mute); }

/* Variante document : plus large, deux colonnes à partir de 1024 px (sommaire + lecture) */
.legal-page--doc {
    max-width: var(--container);
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    column-gap: clamp(2.5rem, 6vw, 5rem);
    row-gap: 0;
}
.legal-page--doc > header { grid-column: 1 / -1; position: relative; margin-bottom: var(--s-12); }
.legal-page--doc > header h1 { font-size: clamp(2.375rem, 6vw, 3.75rem); line-height: 1.02; letter-spacing: -0.03em; margin-bottom: var(--s-6); }
.legal-page--doc > header > p { font-size: var(--text-lg); line-height: 1.5; max-width: 640px; }
.legal-page--doc .doc-corps { min-width: 0; max-width: var(--container-text); }
.legal-page--doc .legal-update { grid-column: 1 / -1; }
@media (min-width: 761px) {
    /* le titre et le chapeau laissent la place à la forme, la bande de faits reprend toute la largeur */
    .legal-page--doc > header h1, .legal-page--doc > header > p { max-width: min(62%, 640px); }
}
@media (min-width: 1024px) {
    .legal-page--doc { grid-template-columns: 200px minmax(0, var(--container-text)); }
    .legal-page--doc .doc-sommaire { grid-column: 1; }
    .legal-page--doc .doc-corps { grid-column: 2; }
    .legal-page--doc:not(:has(.doc-sommaire)) .doc-corps { grid-column: 1 / -1; max-width: 820px; }
}
/* Une page document devenue scène (questions fréquentes, méthode) : après les deux stations, la page elle-même porte le
   fond de lecture, d'un bord à l'autre de l'écran et jusqu'au palier. Un calque posé de la troisième ligne de la grille
   (l'en-tête) au bas de la page, derrière le texte : un bord fondu de 36 vh au-dessus de l'en-tête, le fond plein, puis
   un bord de 30 vh qui fond la page dans le palier. Le débord sur toute la largeur passe par border-image-outset, qui
   ne crée aucun défilement horizontal. La scène ne se voit plus ni ne bouge à gauche et à droite du texte. */
html.accueil-3d main.legal-page--doc.etage::after {
    content: ""; position: absolute; z-index: -1; grid-row: 3 / auto; top: -36vh; bottom: -30vh; left: 0; right: 0;
    border-image: linear-gradient(to bottom,
        color-mix(in srgb, var(--bg) 0%, transparent), color-mix(in srgb, var(--bg) 3%, transparent) 4.3vh,
        color-mix(in srgb, var(--bg) 12%, transparent) 9.4vh, color-mix(in srgb, var(--bg) 30%, transparent) 15.1vh,
        color-mix(in srgb, var(--bg) 55%, transparent) 20.9vh, color-mix(in srgb, var(--bg) 80%, transparent) 27.4vh,
        color-mix(in srgb, var(--bg) 95%, transparent) 32.4vh, var(--bg) 36vh, var(--bg) calc(100% - 30vh),
        color-mix(in srgb, var(--bg) 95%, transparent) calc(100% - 27vh), color-mix(in srgb, var(--bg) 80%, transparent) calc(100% - 22.8vh),
        color-mix(in srgb, var(--bg) 55%, transparent) calc(100% - 17.4vh), color-mix(in srgb, var(--bg) 30%, transparent) calc(100% - 12.6vh),
        color-mix(in srgb, var(--bg) 12%, transparent) calc(100% - 7.8vh), color-mix(in srgb, var(--bg) 3%, transparent) calc(100% - 3.6vh),
        color-mix(in srgb, var(--bg) 0%, transparent)) fill 0 / 0 / 0 100vmax;
}

/* La forme : un dessin au trait, bleu profond, posé dans le coin haut droit de l'en-tête.
   Décorative, elle n'entre pas dans la lecture. */
.doc-forme {
    position: absolute;
    top: -0.5rem;
    right: 0;
    width: clamp(160px, 28vw, 320px);
    height: auto;
    color: var(--accent);
    pointer-events: none;
}
.doc-forme svg { display: block; width: 100%; height: auto; }
.doc-forme .trait { fill: none; stroke: currentColor; stroke-width: 1.25; vector-effect: non-scaling-stroke; opacity: 0.55; }
.doc-forme .trait--fin { opacity: 0.28; }
.doc-forme .plein { fill: currentColor; }
.doc-glyphe {
    position: absolute;
    top: -1.2rem;
    right: 0;
    font-size: clamp(11rem, 26vw, 22rem);
    line-height: 0.8;
    font-weight: 700;
    letter-spacing: -0.05em;
    color: var(--accent);
    opacity: 0.16;
    pointer-events: none;
    user-select: none;
}
@supports (-webkit-text-stroke: 1px black) {
    .doc-glyphe { color: transparent; -webkit-text-stroke: 1.5px var(--accent); opacity: 0.5; }
}
@media (max-width: 760px) {
    .doc-forme { position: static; width: 112px; margin: 0 0 var(--s-6); }
    .doc-glyphe { position: static; display: block; font-size: 6rem; line-height: 1; margin-bottom: var(--s-4); }
}
html.a11y-images .doc-forme, html.a11y-images .doc-glyphe { display: none; }

/* Faits clés : une bande entre deux filets, chaque fait séparé par un filet vertical */
.doc-fiche {
    display: flex;
    flex-wrap: wrap;
    margin: var(--s-10) 0 0;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}
.doc-fiche > div { padding: var(--s-4) var(--s-8) var(--s-4) 0; margin-right: var(--s-8); border-right: 1px solid var(--rule); }
.doc-fiche > div:last-child { border-right: 0; margin-right: 0; padding-right: 0; }
.doc-fiche dt { font-size: var(--text-sm); color: var(--mute); margin-bottom: 2px; }
.doc-fiche dd { margin: 0; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
@media (max-width: 600px) {
    .doc-fiche { display: grid; grid-template-columns: 1fr 1fr; }
    .doc-fiche > div { padding: var(--s-3) var(--s-4) var(--s-3) 0; margin-right: 0; border-right: 0; border-bottom: 1px solid var(--rule); }
    .doc-fiche > div:nth-last-child(-n + 2) { border-bottom: 0; }
}

/* Sommaire : liste de liens, numéros en retrait, collant sur grand écran ; la section
   visible est soulignée par main.js (section 15), sans script il reste une liste */
.doc-sommaire { margin-bottom: var(--s-12); }
.doc-sommaire h2 { font-size: var(--text-sm); font-weight: 600; color: var(--mute); margin-bottom: var(--s-3); letter-spacing: -0.005em; }
.doc-sommaire ol { list-style: none; columns: 2; column-gap: var(--s-8); }
.doc-sommaire li { break-inside: avoid; border-top: 1px solid var(--rule); }
.doc-sommaire li:last-child { border-bottom: 1px solid var(--rule); }
.doc-sommaire a {
    display: flex;
    gap: var(--s-3);
    padding: 9px 0;
    color: var(--mute);
    font-size: var(--text-sm);
    line-height: 1.35;
    text-decoration: none;
}
.doc-sommaire a span:first-child { flex: none; width: 1.8em; font-variant-numeric: tabular-nums; color: var(--accent); font-weight: 600; }
.doc-sommaire a:hover, .doc-sommaire a:focus-visible { color: var(--ink); }
/* section visible : le lien passe en encre et reçoit un trait d'accent à gauche, sans bouger la ligne */
.doc-sommaire a[aria-current="true"] { color: var(--ink); font-weight: 600; box-shadow: inset 2px 0 0 var(--accent); padding-left: var(--s-3); }
@media (min-width: 1024px) {
    .doc-sommaire { position: sticky; top: 84px; align-self: start; margin-bottom: 0; }
    .doc-sommaire ol { columns: 1; }
    /* page document devenue scène (questions fréquentes, méthode) : le sommaire collé tient dans la fenêtre et défile en
       lui-même quand l'écran est bas (à 900 px de haut, sa douzième entrée passait sous le bord) ; arrivé à son bout, la
       molette passe à la page (aucun overscroll-behavior : la page ne se bloque jamais sous le pointeur) ; la marge
       intérieure garde entier l'anneau du focus */
    main.legal-page--doc.etage .doc-sommaire { top: 78px; max-height: calc(100vh - 90px); overflow-y: auto; scrollbar-width: thin; padding: 6px; margin: -6px; }
}

/* Sections : numéro évidé au-dessus du titre */
.legal-section { margin-bottom: var(--s-16); }
.legal-section h2 { font-size: var(--text-xl); margin-bottom: var(--s-6); }
.legal-section h3 { font-size: var(--text-lg); margin: var(--s-8) 0 var(--s-3); }
.legal-section p, .legal-section li { color: var(--mute); }
.legal-section p + p { margin-top: var(--s-4); }
.legal-section ul { padding-left: 1.4em; margin-top: var(--s-3); }
.legal-section li + li { margin-top: var(--s-2); }
.legal-section a { color: var(--accent); }
.legal-section a:hover { text-decoration: underline; }
.legal-section strong { color: var(--ink); font-weight: 600; }
.doc-corps .legal-section { scroll-margin-top: 84px; padding-top: var(--s-6); border-top: 1px solid var(--rule); }
.doc-corps .legal-section h2 { display: flex; flex-direction: column; gap: var(--s-2); font-size: clamp(1.5rem, 2.6vw, 1.875rem); letter-spacing: -0.022em; line-height: 1.15; }
.doc-num {
    display: block;
    font-size: clamp(2.75rem, 5vw, 3.5rem);
    font-weight: 700;
    line-height: 0.9;
    letter-spacing: -0.045em;
    color: var(--accent);
    opacity: 0.35;
    font-variant-numeric: tabular-nums;
}
@supports (-webkit-text-stroke: 1px black) {
    .doc-num { color: transparent; -webkit-text-stroke: 1.5px var(--accent); opacity: 0.85; }
}

/* Tableaux : deux colonnes, filets seulement */
.legal-table { width: 100%; border-collapse: collapse; }
.legal-table th, .legal-table td {
    text-align: left;
    vertical-align: top;
    padding: var(--s-3) var(--s-4) var(--s-3) 0;
    border-bottom: 1px solid var(--rule);
    font-size: var(--text-base);
}
.legal-table th { font-weight: 600; white-space: nowrap; width: 220px; color: var(--ink); }
.legal-table td { color: var(--mute); }
.legal-table a { color: var(--accent); }
.doc-corps .legal-table th { font-weight: 500; color: var(--mute); font-size: var(--text-sm); padding-top: calc(var(--s-3) + 2px); width: 180px; }
.doc-corps .legal-table td { color: var(--ink); }
.doc-corps .legal-table tr:first-child th, .doc-corps .legal-table tr:first-child td { border-top: 1px solid var(--rule); }
@media (max-width: 600px) {
    .legal-table th { width: 130px; white-space: normal; }
    .doc-corps .legal-table th, .doc-corps .legal-table td { display: block; width: auto; padding-right: 0; }
    .doc-corps .legal-table th { border-bottom: 0; padding-bottom: 0; }
    .doc-corps .legal-table td { padding-top: 4px; }
}
/* Un tableau légal posé dans une card vit dans une colonne, pas sur la largeur
   de lecture. Entre 641 et 1023 pixels, la grille reste à deux colonnes : la colonne
   de gauche du tableau ne garde pas ses 220 pixels fixes, et une valeur insécable
   (adresse électronique, adresse web) se coupe plutôt que de déborder. */
.card .legal-table td { overflow-wrap: anywhere; }
@media (max-width: 1023px) {
    .card .legal-table th { width: auto; white-space: normal; padding-right: var(--s-4); }
}
/* Sous 600 pixels, deux colonnes ne tiennent plus dans une card : l'étiquette passe
   au-dessus de sa valeur, comme le fait déjà le même tableau dans les pages document
   (RGAA 10.11, aucun défilement horizontal à 320 pixels). */
@media (max-width: 600px) {
    .card .legal-table th, .card .legal-table td { display: block; width: auto; padding-right: 0; }
    .card .legal-table th { border-bottom: 0; padding-bottom: 0; }
    .card .legal-table td { padding-top: 4px; }
}

/* Encadré : plus de boîte grise, un filet d'accent et une taille de lecture */
.legal-highlight {
    padding: var(--s-2) 0 var(--s-2) var(--s-6);
    border-left: 2px solid var(--accent);
    margin-bottom: var(--s-6);
}
.legal-highlight p { color: var(--ink); font-weight: 500; font-size: var(--text-lg); line-height: 1.45; letter-spacing: -0.012em; }

.legal-update {
    text-align: center;
    color: var(--mute);
    font-size: var(--text-sm);
    margin-top: var(--s-16);
}

/* Plan du site : une arborescence à nœuds. Un tronc à gauche, un nœud par page,
   la description à droite du nom. Les groupes portent le titre de niveau 2. */
.plan-arbre, .plan-arbre ol, .plan-arbre ul { list-style: none; padding: 0; margin: 0; }
.plan-racine { position: relative; padding-left: var(--s-8); }
.plan-racine::before { content: ""; position: absolute; left: 4px; top: 14px; bottom: 0; border-left: 1px solid var(--rule); }
.plan-noeud {
    display: inline-flex;
    align-items: center;
    gap: var(--s-3);
    font-weight: 600;
    color: var(--ink);
    margin-left: calc(-1 * var(--s-8));
    margin-bottom: var(--s-8);
}
.plan-noeud::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px var(--bg); }
.plan-groupe { position: relative; padding: 0 0 var(--s-10) var(--s-8); }
.plan-groupe:last-child { padding-bottom: 0; }
.plan-groupe::before { content: ""; position: absolute; left: calc(-1 * var(--s-8) + 4px); top: 0.7em; width: var(--s-8); border-top: 1px solid var(--rule); }
.plan-groupe > h2 { font-size: var(--text-lg); margin-bottom: var(--s-4); position: relative; }
.plan-groupe > h2::before { content: ""; position: absolute; left: calc(-1 * var(--s-8) - 4px); top: 0.5em; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--accent); background: var(--bg); box-shadow: 0 0 0 4px var(--bg); }
.plan-groupe > ul { border-left: 1px solid var(--rule); margin-left: 4px; padding-left: var(--s-6); }
.plan-groupe > ul > li { position: relative; padding: 7px 0; display: flex; flex-wrap: wrap; gap: 2px var(--s-3); align-items: baseline; }
.plan-groupe > ul > li::before { content: ""; position: absolute; left: calc(-1 * var(--s-6)); top: 1.15em; width: var(--s-4); border-top: 1px solid var(--rule); }
.plan-groupe > ul > li > a { color: var(--ink); font-weight: 600; text-decoration: none; }
.plan-groupe > ul > li > a:hover, .plan-groupe > ul > li > a:focus-visible { color: var(--accent); text-decoration: underline; text-underline-offset: 0.15em; }
.plan-desc { color: var(--mute); font-size: var(--text-sm); }
@media print { .doc-forme, .doc-glyphe, .doc-sommaire { display: none !important; } .legal-page--doc { display: block; } }

/* ------------------------------------------------------------
   13. Presse
   ------------------------------------------------------------ */
.press-card {
    max-width: var(--container);
    margin: 0 auto;
    background: var(--panel);
    color: var(--panel-ink);
    border-radius: var(--r-lg);
    padding: clamp(2.25rem, 5vw, 4rem);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}
@media (max-width: 820px) { .press-card { grid-template-columns: 1fr; } }

.press-card-quote {
    font-size: clamp(1.6rem, 3.6vw, 2.4rem);
    font-weight: 700;
    letter-spacing: -0.022em;
    line-height: 1.15;
}
.press-card-source { margin-top: var(--s-6); color: var(--panel-mute); font-size: var(--text-sm); }
.press-card-body p { color: var(--panel-mute); }
.press-card-body p + p { margin-top: var(--s-4); }
.press-card-body p strong { color: var(--panel-ink); font-weight: 600; }
.press-card-body .btn { margin-top: var(--s-8); }
.press-card-body .btn-ghost {
    color: var(--panel-ink);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.4);
}
.press-card-body .btn-ghost:focus-visible { background: rgba(255,255,255,0.12); color: #fff; }
@media (hover: hover) and (pointer: fine) { .press-card-body .btn-ghost:hover { background: rgba(255,255,255,0.12); color: #fff; } }
.press-card-body a { color: var(--accent-on-dark); }

.bio-block p { color: var(--mute); }

/* ------------------------------------------------------------
   14. Contact
   ------------------------------------------------------------ */
.contact-list { max-width: var(--container-text); margin: 0 auto; }
.contact-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s-6);
    padding: var(--s-8) 0;
    border-bottom: 1px solid var(--rule);
}
.contact-item:first-child { border-top: 1px solid var(--rule); }
.contact-item-label { font-size: var(--text-sm); color: var(--mute); min-width: 110px; }
.contact-item-value { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.018em; }
a.contact-item:hover .contact-item-value { color: var(--accent); }
@media (max-width: 600px) {
    .contact-item { flex-direction: column; gap: var(--s-1); }
    .contact-item-value { font-size: var(--text-lg); }
}

/* ------------------------------------------------------------
   15. CTA final
   ------------------------------------------------------------ */
.cta-final { text-align: center; }
.cta-final h2 { margin-bottom: var(--s-4); }
.cta-final p {
    font-size: var(--text-lg);
    color: var(--mute);
    max-width: 540px;
    margin: 0 auto var(--s-10);
}
.cta-final .hero-cta { justify-content: center; }

/* ------------------------------------------------------------
   16. Footer
   ------------------------------------------------------------ */
footer {
    background: var(--bg-alt);
    padding: var(--s-16) var(--gutter) var(--s-10);
    font-size: var(--text-sm);
}
.footer-inner { max-width: var(--container); margin: 0 auto; }

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr 1fr;   /* marque + Site, Lectures, Langues, Ailleurs */
    gap: var(--s-8);
    padding-bottom: var(--s-10);
    border-bottom: 1px solid var(--rule);
}
@media (max-width: 820px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--s-8) var(--s-10); } .footer-brand { grid-column: 1 / -1; } }
@media (max-width: 480px) { .footer-grid { grid-template-columns: 1fr; } }

/* Colonne Langues : la langue courante en encre, les autres annoncées sans lien tant que les versions n'existent pas */
.footer-langue { display: block; color: var(--mute); padding: 4px 0; }
.footer-langue--active { color: var(--ink); font-weight: 600; }
.footer-langue small { font-size: 0.85em; color: var(--mute); font-weight: 400; }

.footer-brand .footer-logo { font-weight: 600; font-size: var(--text-base); }
.footer-brand p { color: var(--mute); margin-top: var(--s-3); }

.footer-col a {
    display: block;
    color: var(--mute);
    padding: 4px 0;              /* zone cliquable 25 px : au-dessus du plancher WCAG 2.5.8 */
    transition: color 0.2s var(--ease);
}
.footer-col a:hover { color: var(--ink); }

.footer-bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-4);
    padding-top: var(--s-8);
    color: var(--mute);
}
.footer-bottom a { color: var(--accent); }
.footer-bottom a:hover { text-decoration: underline; }
/* Pied court des pages légales et de la page 404 : la ligne de mentions seule, sans filet ni colonnes */
.footer-bottom.footer-bottom--seul { border-top: 0; padding-top: 0; }

/* ------------------------------------------------------------
   17. Bouton d'accessibilité (remplace la bascule de thème le 12/09/2026 ;
   le thème se règle dans le panneau, section 26). Transition de thème conservée.
   ------------------------------------------------------------ */
.a11y-bouton {
    position: fixed;
    bottom: var(--s-6);
    right: var(--s-6);
    z-index: 900;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent);
    color: var(--sur-accent);
    border: 1px solid var(--accent);
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.14);
    transition: transform 0.2s var(--ease), background 0.2s var(--ease), opacity 0.25s var(--ease);
}
.a11y-bouton { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.a11y-bouton:focus-visible { background: var(--accent-hover); border-color: var(--accent-hover); }
@media (hover: hover) and (pointer: fine) { .a11y-bouton:hover { background: var(--accent-hover); border-color: var(--accent-hover); } }
.a11y-bouton[aria-expanded="true"] { transform: scale(0.94); }
/* Les boutons flottants s'effacent devant la saisie et la lecture (main.js section 19) : tant qu'un formulaire, les
   moyens de contact qui le suivent, le champ de recherche, un lien de station ou l'élément au focus passent sous lui, le
   bouton fond et laisse passer le pointeur. Il reste dans la suite du clavier et revient au focus, puis dès que la
   place est libre. La pastille « Retourner à l'ascenseur » suit la même règle (immeuble.css). */
.a11y-bouton.est-effacee { opacity: 0; pointer-events: none; }
.a11y-bouton.est-effacee:focus-visible { opacity: 1; pointer-events: auto; }
/* Et, sans attendre le script, les zones de saisie passent devant eux : au-dessus de la pastille (950) et du bouton
   (900), toujours sous la barre de menu (1000). Le centre d'un champ ou du bouton d'envoi n'est jamais sous un bouton
   flottant. Jamais devant le voile de chargement des pages à scène (immeuble.css, .scene-voile, z-index 4) : tant qu'il
   couvre la page, elles restent sous lui avec le reste ; levé, elles passent devant à la fin de son fondu (0,6 s). */
main form, .formulaire-liens, .journal-recherche { position: relative; z-index: 960; transition: z-index 0s linear 0.6s; }
.scene-voile:not(.est-leve) ~ main :is(form, .formulaire-liens, .journal-recherche),
.scene-voile.est-actif ~ main :is(form, .formulaire-liens, .journal-recherche) { z-index: 0; transition: none; }
@media (prefers-reduced-motion: reduce) { main form, .formulaire-liens, .journal-recherche { transition-delay: 0s; } }
/* sans script, pas de voile (sans-script.css) : les zones de saisie gardent leur place devant les boutons */
@media (scripting: none) {
    .scene-voile:not(.est-leve) ~ main :is(form, .formulaire-liens, .journal-recherche) { z-index: 960; }
}
/* La dernière ligne de la page reste au-dessus des boutons flottants : 24 px du bord, 48 px de bouton, 8 px d'air.
   Cette marge est la seule : le pied court de la page Blog n'ajoute pas la sienne (journal.css, .footer-inner 64 px). */
footer:not(.palier) { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
main.etage ~ footer:not(.palier) .footer-inner { padding-bottom: 0; }
/* Au clavier, l'élément qui prend le focus s'arrête au-dessus de la même bande : il n'est jamais caché par un bouton.
   L'accueil garde sa règle (immeuble.css, scroll-padding-block de la page à cabine) : son parcours ne change pas. */
html:not(:has(.station--cabine)) { scroll-padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
/* Une page à scène lue à plat (mouvement réduit, animations arrêtées) : l'élément qui prend le focus en remontant s'arrête
   aussi sous la barre de menu (52 px et 16 px d'air), et le défilement reste immédiat. Ses ancres gardent leur place
   (immeuble.css pour les blocs du contenu ; ici les sections des pages document). En trois dimensions, le script de la
   scène amène lui-même l'élément à l'écran (commun-etage.js, le clavier). */
html:has([data-station]):not(.accueil-3d):not(:has(.station--cabine)) { scroll-padding-top: 68px; }
html:has([data-station]):not(.accueil-3d) .doc-corps .legal-section { scroll-margin-top: 16px; }

html.theme-vt::view-transition-old(root),
html.theme-vt::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
}

/* ------------------------------------------------------------
   19. Divers : erreur 404, plan du site
   ------------------------------------------------------------ */
.error-page {
    min-height: 82vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: calc(52px + var(--s-16)) var(--gutter) var(--s-16);
}
/* (le code « 404 » en grand est devenu le téléviseur sans signal, dessiné dans erreur.css) */
.error-page h1 { font-size: clamp(1.8rem, 4vw, 2.6rem); margin: var(--s-4) 0; }
.error-page p { color: var(--mute); max-width: 460px; margin-bottom: var(--s-8); }

/* (la liste du plan du site est devenue une arborescence, section 12) */

/* ------------------------------------------------------------
   20. Filet sous les titres de section
   ------------------------------------------------------------ */
.hero { position: relative; }

/* Filet fin sous le titre des sections, la seule ponctuation graphique */
.section-head h2::after,
.panel h2::after {
    content: "";
    display: block;
    width: 44px;
    height: 2px;
    margin: var(--s-6) auto 0;
    background: var(--accent);
}
.panel h2::after { background: var(--accent-on-dark); }

/* ------------------------------------------------------------
   21. Accessibilité & impression
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Contenu réservé à l'impression (ex. contact sur le CV) */
.print-only { display: none; }

@media print {
    .nav, footer, .a11y-bouton, .a11y-panneau, .a11y-voile, .a11y-guide, .skip-link, .reading-progress,
    .no-print, .cta-final { display: none !important; }
    body { background: #fff; color: #000; font-size: 11pt; }
    .panel, .press-card, .section--alt { background: #fff !important; color: #000 !important; }

    .print-only {
        display: block;
        font-size: 10.5pt;
        color: #333;
        margin-top: 8pt;
    }

    /* Parcours en version CV : compact, une colonne, sans effets */
    .hero { padding: 0 0 14pt; }
    .hero h1 { font-size: 22pt; }
    .hero-lede { font-size: 11pt; margin-bottom: 0; }
    .section { padding: 12pt 0; }
    .section-head { margin-bottom: 10pt; text-align: left; }
    .section-head h2 { font-size: 15pt; }
    .section-head p { font-size: 10.5pt; }
    .timeline-item { padding: 0 0 10pt 14pt; break-inside: avoid; }
    .timeline-item h3 { font-size: 12pt; }
    .card-grid { display: block; }
    .card {
        background: #fff !important;
        border: 1px solid #ddd;
        border-radius: 6pt;
        padding: 8pt 10pt;
        margin-bottom: 6pt;
        box-shadow: none !important;
        break-inside: avoid;
    }
    a { color: #000; }
}

/* ------------------------------------------------------------
   22. Accessibilité, passe du 8 septembre 2026 (audit axe-core 4.10),
   contrastes recalculés le 11 septembre 2026 pour la nouvelle palette
   ------------------------------------------------------------ */
/* Boutons en mode sombre : texte noir sur bleu acier (9,5:1), porté par le jeton --sur-accent
   défini dans les deux blocs sombres (attribut data-theme et prefers-color-scheme). */

/* Liens placés dans un texte : soulignés, la couleur seule ne suffit pas */
.text-link, .article-body a, .legal-section a, .legal-table a, .legal-page header a,
.card p a, .press-card-body a, .timeline-item p a, .footer-bottom a,
.hero-lede a, .panel-lede a, .section-head p a {
    text-decoration: underline;
    text-underline-offset: 0.15em;
    text-decoration-thickness: 1px;
}

/* Hiérarchie des titres : intertitres du pied de page en h2, premières fiches en h2 */
.footer-col .footer-heading {
    font-size: var(--text-sm);
    font-weight: 600;
    margin-bottom: var(--s-4);
    letter-spacing: -0.005em;
}

/* Blocs de code défilants atteignables au clavier */
pre[tabindex]:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------
   23. Vitrine, cadres et catalogue, passe du 11 septembre 2026
   Les images sont des captures des sites réellement livrés.
   ------------------------------------------------------------ */

/* Accueil : texte à gauche, portrait à droite (section 32) ; les cadres servent aux captures */
.hero-split {
    display: grid;
    grid-template-columns: 1.05fr 0.95fr;
    gap: clamp(2.5rem, 6vw, 5rem);
    align-items: center;
    max-width: var(--container);
    margin: 0 auto;
    text-align: left;
}
.hero-split .hero-lede { margin-left: 0; }
.hero-split .hero-cta { justify-content: flex-start; }
@media (max-width: 820px) {
    .hero-split { grid-template-columns: 1fr; text-align: center; }
    .hero-split .hero-lede { margin: 0 auto var(--s-10); }
    .hero-split .hero-cta { justify-content: center; }
}

/* Les captures des sites (galerie de l'étage 1, presse) : un seul traitement. L'image nue à bords francs, un filet d'un
   pixel, le nom de domaine en légende dessous (figure et figcaption). Ni fausse barre de navigateur, ni ombre, ni zoom, ni
   auréole ; une capture qui est un lien monte de 2 px au survol. Le lien enveloppe la figure : son nom est la légende. */
.capture { margin: 0; }
.capture img {
    display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; object-position: top;
    border: 1px solid var(--rule); border-radius: 0; background: var(--bg-alt);
}
.capture-domaine { display: block; margin-top: var(--s-3); font-size: var(--text-sm); line-height: 1.4; color: var(--mute); overflow-wrap: anywhere; }
a.capture-lien { display: block; color: inherit; text-decoration: none; }
a.capture-lien:focus-visible { outline: 3px solid var(--accent); outline-offset: 4px; }
a.capture-lien:hover .capture-domaine { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
a.capture-lien .capture img { transition: transform 0.3s var(--ease); }
a.capture-lien:hover .capture img { transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
    a.capture-lien .capture img { transition: none; }
    a.capture-lien:hover .capture img { transform: none; }
}
html.a11y-animations a.capture-lien .capture img { transition: none; }
html.a11y-animations a.capture-lien:hover .capture img { transform: none; }

/* Le cadre noir de la vidéo de la presse */
.cadre {
    border: 1px solid var(--rule);
    border-radius: var(--r);
    overflow: hidden;
    background: var(--card);
}


/* Presse : une carte par article, capture à gauche, texte à droite, empilées */
.presse-liste { display: grid; gap: var(--s-6); max-width: var(--container); margin: 0 auto; }
.press-card--visuel { align-items: start; }
.press-card--visuel .cadre, .press-card--visuel .capture img { border-color: rgba(255, 255, 255, 0.18); }
.press-card--visuel .capture-domaine { color: var(--panel-mute); }
.press-card--visuel .press-card-quote { font-size: clamp(1.25rem, 2.4vw, 1.6rem); }
.press-card--visuel .press-card-source { margin-top: var(--s-3); margin-bottom: var(--s-6); }
/* une fiche sans visuel (l'interview : ses liens seuls) prend toute la largeur ; ses gestes se rangent côte à côte */
.press-card > .press-card-body:only-child { grid-column: 1 / -1; }
.press-card-body .hero-cta { margin-top: var(--s-8); gap: var(--s-3); }
.press-card-body .hero-cta .btn { margin-top: 0; }
.cadre--video { background: #000; }
.cadre--video video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: #000; }
/* Chrome ne pose pas :focus-visible sur un lecteur vidéo atteint au clavier : la prise
   de focus resterait invisible (RGAA 10.7). On la dessine nous-mêmes. */
.cadre--video video:focus { outline: 3px solid var(--accent); outline-offset: 3px; }

/* Transcription d'un média : le texte est replié, le titre reste un bouton natif. */
.transcription { margin: var(--s-4) 0 0; }
.transcription > summary {
    cursor: pointer;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--accent);
    min-height: 44px;
    display: flex;
    align-items: center;
}
.transcription > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
.transcription-corps { font-size: var(--text-sm); color: var(--mute); }
.transcription-corps p + p { margin-top: var(--s-3); }
/* Dans une fiche de presse, le fond est noir : l'accent bleu profond n'y tient pas le contraste */
.press-card-body .transcription > summary { color: var(--accent-on-dark); }
.press-card-body .transcription > summary:focus-visible { outline-color: var(--accent-on-dark); }
.press-card-body .transcription-corps { color: var(--panel-mute); }

/* Catalogue des réalisations : une fiche par site, l'état à la place du panier */
.filtres {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-2);
    max-width: var(--container);
    margin: 0 auto var(--s-6);
}
.filtre {
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    padding: 8px 16px;
    min-height: 44px;            /* cible tactile 44 px minimum */
    border-radius: var(--r-pill);
    border: 1px solid var(--bord-controle);   /* RGAA 3.3 */
    background: var(--card);
    color: var(--ink);
    cursor: pointer;
    transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.filtre:hover { border-color: var(--accent); }
.filtre[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--sur-accent); }
.catalogue-compte {
    text-align: center;
    color: var(--mute);
    font-size: var(--text-sm);
    margin: 0 auto var(--s-10);
}

.catalogue-grid {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: var(--s-6);
    max-width: var(--container);
    margin: 0 auto;
}
.produit {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    overflow: hidden;
    background: var(--card);
}
.produit[hidden] { display: none; }
/* Les fiches du catalogue et des études sont composées d'emblée, sans content-visibility : une hauteur réservée d'avance
   (620 px) contre 610 à 970 px réels faisait grandir la page après la touche Fin (573 px sur les études à 390 px, 837 sur
   le catalogue), et le gain mesuré sur ces pages à scène est nul. L'image réserve sa place par ses dimensions et le
   rapport 16:10 du visuel. Les lignes du journal du blog gardent la leur (hauteur d'une ligne dans journal.css). */
.journal-liste .produit { content-visibility: auto; }
@media print { .journal-liste .produit { content-visibility: visible; } }
.produit-visuel {
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background: var(--bg-alt);
    border-bottom: 1px solid var(--rule);
}
.produit-visuel img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: top;
    display: block;
}
.produit-visuel--texte {
    display: flex;
    align-items: center;
    padding: var(--s-6);
    background: var(--navy);
    color: var(--panel-ink);
    font-weight: 700;
    font-size: var(--text-lg);
    letter-spacing: -0.018em;
    line-height: 1.25;
}
.produit-corps {
    padding: var(--s-6);
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    flex: 1;
}
.produit-etat {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--accent);
}
.produit-etat::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.produit-etat--fin { color: var(--mute); }
.produit h3 { font-size: var(--text-lg); letter-spacing: -0.018em; }
.produit-desc { color: var(--mute); font-size: var(--text-base); flex: 1; }
.produit-meta {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 12px;
    font-size: var(--text-sm);
    color: var(--mute);
    margin: 0;
}
.produit-meta dt { font-weight: 600; color: var(--ink); }
.produit-meta dd { margin: 0; }
.produit-action { margin-top: var(--s-2); justify-content: center; }
@media print { .filtres, .produit-action { display: none !important; } .produit { break-inside: avoid; } }

/* ------------------------------------------------------------
   24. Formulaire de contact : compose un courriel, ne stocke rien
   ------------------------------------------------------------ */
:root { --erreur: #9b1c1c; }
html[data-theme="dark"] { --erreur: #ffb4ab; }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) { --erreur: #ffb4ab; } }

.formulaire {
    max-width: 640px;
    margin: 0 auto;
    display: grid;
    gap: var(--s-5, 1.25rem);
}
.formulaire-note { color: var(--mute); font-size: var(--text-sm); margin-bottom: var(--s-2); }
.formulaire-rangee { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
@media (max-width: 640px) { .formulaire-rangee { grid-template-columns: 1fr; } }

.champ label { display: block; font-size: var(--text-sm); font-weight: 600; margin-bottom: 6px; }
.champ-opt { font-weight: 400; color: var(--mute); }
/* Mention du caractère obligatoire, dans l'étiquette elle-même : le critère RGAA 11.10
   demande une indication visible reliée au champ ; l'attribut required seul ne suffit pas. */
.champ-obl { font-weight: 400; color: var(--mute); }
.champ input, .champ select, .champ textarea {
    width: 100%;
    font: inherit;
    font-size: max(16px, var(--text-base));   /* 16 px minimum : pas de zoom forcé sur iOS */
    line-height: 1.4;
    color: var(--ink);
    background: var(--card);
    border: 1px solid var(--bord-controle);   /* RGAA 3.3 : la bordure est le seul contour du champ */
    border-radius: var(--r);
    padding: 12px 14px;
    min-height: 48px;
}
.champ textarea { min-height: 170px; resize: vertical; }
.champ input:focus-visible, .champ select:focus-visible, .champ textarea:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-color: var(--accent);
}
.champ [aria-invalid="true"] { border-color: var(--erreur); }
.champ-erreur { color: var(--erreur); font-size: var(--text-sm); margin-top: 6px; }
.formulaire-statut { color: var(--mute); font-size: var(--text-sm); min-height: 1.4em; margin: 0; }
.formulaire-mentions { color: var(--mute); font-size: var(--text-sm); margin: var(--s-3) 0 0; max-width: 62ch; }
.formulaire .btn { min-height: 48px; }
/* L'envoi en cours (main.js section 11 pose aria-busy) : le bouton le montre, un second appui ne renvoie rien */
.formulaire[aria-busy="true"] .btn-primary { cursor: progress; opacity: 0.7; }
/* Le piège à robots : hors de l'écran et du parcours au clavier, jamais rempli par un humain */
.champ-piege { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
/* Le retour du formulaire envoyé sans script : le Worker renvoie sur l'une de ces ancres, seule la visée se montre */
.formulaire-retour { display: none; max-width: 640px; margin: 0 auto var(--s-6); padding: var(--s-4) var(--s-5); border: 1px solid var(--accent); border-radius: var(--r); font-weight: 600; }
.formulaire-retour--echec { border-color: var(--erreur); }
.formulaire-retour:target { display: block; }
/* Le motif : quatre boutons radio, aucun coché d'avance (main.js coche celui du palier d'où l'on vient) */
fieldset.champ { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.champ legend { font-size: var(--text-sm); font-weight: 600; padding: 0; margin-bottom: 6px; }
.choix { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.champ .choix label { display: inline-flex; align-items: center; gap: var(--s-2); margin: 0; min-height: 48px; padding: 8px 16px; font-size: var(--text-base); font-weight: 400; border: 1px solid var(--bord-controle); border-radius: var(--r); background: var(--card); cursor: pointer; }
.champ .choix input { width: 18px; height: 18px; min-height: 0; padding: 0; margin: 0; accent-color: var(--accent); }
.champ .choix label:has(:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.formulaire-apercu {
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    background: var(--bg-alt);
    padding: var(--s-6);
    display: grid;
    gap: var(--s-4);
}
.formulaire-apercu[hidden] { display: none; }   /* display:grid ci-dessus battrait l'attribut hidden */
.formulaire-texte {
    font: inherit;
    font-size: var(--text-sm);
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--ink);
    margin: 0;
}
.formulaire-liens { margin-top: var(--s-12); }

/* ------------------------------------------------------------
   25. Fond de page : hairlines verticales et trois barres bleues fixes.
   Décoratif, derrière le contenu, masqué par les bandes et les cartes.
   Coupé sous prefers-reduced-motion (les barres restent, l'animation part).
   ------------------------------------------------------------ */
:root {
    --fond-ligne: rgba(20, 52, 95, 0.09);
    --fond-barre: rgba(20, 52, 95, 0.45);
}
html[data-theme="dark"] {
    --fond-ligne: rgba(143, 176, 232, 0.10);
    --fond-barre: rgba(143, 176, 232, 0.5);
}
@media (prefers-color-scheme: dark) {
    html:not([data-theme="light"]) {
        --fond-ligne: rgba(143, 176, 232, 0.10);
        --fond-barre: rgba(143, 176, 232, 0.5);
    }
}
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: repeating-linear-gradient(90deg, var(--fond-ligne) 0 1px, transparent 1px 120px);
    background-position: 60px 0;
}
/* Les trois barres s'allument l'une après l'autre, de gauche à droite, comme une rampe de LED qui
   monte puis s'éteint : une vague lente (14 s), une seule couleur, jamais un clignotement. */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        linear-gradient(180deg, transparent 0%, var(--fond-barre) 35%, var(--fond-barre) 65%, transparent 100%),
        linear-gradient(180deg, transparent 10%, var(--fond-barre) 50%, transparent 90%),
        linear-gradient(180deg, transparent 0%, var(--fond-barre) 40%, transparent 80%);
    background-repeat: no-repeat;
    background-size: 2px 100%, 2px 100%, 2px 100%;
    background-position: 14% 0, 51% 0, 87% 0;
    opacity: 0.85;
    /* Le masque est une bande claire posée sur un voile sombre, trois fois plus large que l'écran.
       Seule sa position bouge (la seule propriété animée, donc fluide) : la bande glisse de gauche
       à droite et allume chaque barre à son passage, puis l'écran reste éteint quelques secondes. */
    -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,0.28) 0%, rgba(0,0,0,0.28) 44%, #000 50%, rgba(0,0,0,0.28) 56%, rgba(0,0,0,0.28) 100%);
    mask-image: linear-gradient(90deg, rgba(0,0,0,0.28) 0%, rgba(0,0,0,0.28) 44%, #000 50%, rgba(0,0,0,0.28) 56%, rgba(0,0,0,0.28) 100%);
    -webkit-mask-size: 300% 100%;
    mask-size: 300% 100%;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: 100% 0;
    mask-position: 100% 0;
    animation: barres-led 12s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}
@keyframes barres-led {
    0%   { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
    70%  { -webkit-mask-position: 0% 0;   mask-position: 0% 0; }
    100% { -webkit-mask-position: 0% 0;   mask-position: 0% 0; }
}
@media (max-width: 640px) {
    body::before { background-image: repeating-linear-gradient(90deg, var(--fond-ligne) 0 1px, transparent 1px 72px); }
    body::after { background-size: 2px 100%, 2px 100%, 0 0; }
}
@media (prefers-reduced-motion: reduce) { body::after { animation: none; -webkit-mask-image: none; mask-image: none; opacity: 0.5; } }
html.a11y-animations body::after { animation: none; -webkit-mask-image: none; mask-image: none; opacity: 0.5; }
@media print { body::before, body::after { display: none; } }

/* Logo à la place d'une capture (LBO Journal : projet arrêté, site retiré de la publication).
   Le fichier porte son propre fond blanc : il s'affiche centré sur une case blanche, dans les
   deux thèmes, à la moitié de la largeur de la case (170 px au plus), sans étirement ni zoom
   au survol. Le fichier fait 100 px de côté : au-delà de 170 px il deviendrait flou. */
.produit-visuel.produit-visuel--logo {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 10;
    background: #ffffff;
}
.produit-visuel.produit-visuel--logo img {
    width: min(52%, 170px);
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    object-position: center;
}
.produit:hover .produit-visuel--logo img { transform: none; }

/* ------------------------------------------------------------
   26. Accessibilité : panneau glissant et réglages d'affichage.
   Le panneau est construit par main.js (section 12). Chaque réglage
   pose une classe a11y-* sur <html> ; tout se range dans localStorage.
   ------------------------------------------------------------ */
body.a11y-ouvert { overflow: hidden; }

.a11y-voile {
    position: fixed;
    inset: 0;
    z-index: 1100;
    background: rgba(0, 0, 0, 0);
    transition: background 0.36s var(--ease-out);
}
.a11y-voile.ouvert { background: rgba(0, 0, 0, 0.38); }
.a11y-voile[hidden] { display: none; }

.a11y-panneau {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 1101;
    width: min(400px, 100vw);
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--ink);
    border-left: 1px solid var(--rule);
    transform: translateX(100%);
    transition: transform 0.36s var(--ease-out);
    overscroll-behavior: contain;
}
.a11y-panneau.ouvert { transform: none; }
.a11y-panneau[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .a11y-panneau, .a11y-voile { transition: none; } }

.a11y-entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-6) var(--s-6) var(--s-4);
    border-bottom: 1px solid var(--rule);
}
.a11y-entete .overline { display: block; margin-bottom: var(--s-1); font-size: var(--text-sm); color: var(--mute); }
.a11y-entete h2 { font-size: var(--text-xl); line-height: 1.15; letter-spacing: -0.02em; margin: 0; }
.a11y-entete h2::after { content: none; }
.a11y-fermer {
    flex: none;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--card);
    color: var(--ink);
    border: 1px solid var(--bord-controle);   /* RGAA 3.3 */
    border-radius: 50%;
    cursor: pointer;
}
.a11y-fermer:hover { border-color: var(--accent); }

.a11y-corps { flex: 1; overflow-y: auto; padding: 0 var(--s-6) var(--s-4); }
.a11y-note { color: var(--mute); font-size: var(--text-sm); margin: var(--s-4) 0 0; }
.a11y-groupe { padding: var(--s-6) 0 var(--s-4); border-bottom: 1px solid var(--rule); }
.a11y-groupe:last-child { border-bottom: 0; }
.a11y-groupe h3 { font-size: var(--text-sm); font-weight: 600; color: var(--mute); margin: 0 0 var(--s-3); }

.a11y-segments {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    border: 1px solid var(--bord-controle);   /* RGAA 3.3 */
    border-radius: var(--r);
    overflow: hidden;
}
.a11y-segments button {
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    min-height: 44px;
    padding: 0 var(--s-2);
    background: var(--card);
    color: var(--ink);
    border: 0;
    border-right: 1px solid var(--bord-controle);   /* RGAA 3.3 : sépare deux états du groupe */
    cursor: pointer;
}
.a11y-segments button:last-child { border-right: 0; }
.a11y-segments button[aria-pressed="true"] { background: var(--accent); color: var(--sur-accent); }
.a11y-segments button:focus-visible { outline-offset: -3px; }
/* Groupe qui prend toute la ligne sous son libellé (interligne) : posé en classe, jamais en style en ligne */
.a11y-segments.a11y-segments--pleine { flex: 1 1 100%; }

.a11y-ligne {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    width: 100%;
    min-height: 52px;
    padding: var(--s-2) 0;
    background: none;
    border: 0;
    color: var(--ink);
    font: inherit;
    font-size: var(--text-base);
    text-align: left;
    cursor: pointer;
}
.a11y-ligne--statique { cursor: default; flex-wrap: wrap; }
.a11y-ligne + .a11y-ligne { border-top: 1px solid var(--rule); }
.a11y-libelle { flex: 1 1 auto; line-height: 1.35; }
.a11y-libelle small { display: block; color: var(--mute); font-size: var(--text-sm); margin-top: 2px; }
.a11y-switch {
    flex: none;
    position: relative;
    width: 46px;
    height: 28px;
    border-radius: 14px;
    /* État « éteint » : le rail doit se détacher du fond du panneau et laisser voir
       la pastille blanche, sinon l'état n'est pas lisible (RGAA 3.3). */
    background: var(--bord-controle);
    transition: background 0.2s var(--ease);
}
.a11y-switch::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    /* Éteinte, la pastille se pose sur le rail gris : elle prend le fond de la page,
       blanc en clair, noir en sombre, pour rester détachée du rail (RGAA 3.3). */
    background: var(--bg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    transition: transform 0.2s var(--ease);
}
[role="switch"][aria-checked="true"] .a11y-switch { background: var(--accent); }
[role="switch"][aria-checked="true"] .a11y-switch::after { transform: translateX(18px); }
/* Allumé, la pastille se pose sur l'accent : elle prend la couleur prévue pour cet usage.
   En sombre, une pastille presque blanche sur le bleu acier ne tenait que 2:1 (RGAA 3.3). */
[role="switch"][aria-checked="true"] .a11y-switch::after { background: var(--sur-accent); }

.a11y-pas { display: flex; align-items: center; gap: var(--s-2); }
.a11y-pas button {
    width: 44px;
    height: 44px;
    border-radius: var(--r);
    border: 1px solid var(--bord-controle);   /* RGAA 3.3 */
    background: var(--card);
    color: var(--ink);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.a11y-pas button:hover:not(:disabled) { border-color: var(--accent); }
.a11y-pas button:disabled { opacity: 0.4; cursor: default; }
.a11y-pas output { min-width: 5ch; text-align: center; font-variant-numeric: tabular-nums; font-size: var(--text-sm); color: var(--mute); }
.a11y-lire { margin-top: var(--s-3); }
.a11y-lire .btn { width: 100%; min-height: 48px; }
.a11y-lire p { color: var(--mute); font-size: var(--text-sm); margin-top: var(--s-2); }

.a11y-pied {
    padding: var(--s-4) var(--s-6) var(--s-6);
    border-top: 1px solid var(--rule);
    display: grid;
    gap: var(--s-3);
    font-size: var(--text-sm);
    color: var(--mute);
}
.a11y-pied .btn { min-height: 44px; justify-content: center; }
.a11y-pied a { color: var(--accent); text-decoration: underline; text-underline-offset: 0.15em; }
.a11y-statut { min-height: 1.3em; margin: 0; color: var(--ink); }

/* Guide de lecture : une bande fixe qui suit le pointeur */
.a11y-guide {
    position: fixed;
    left: 0;
    right: 0;
    height: 3.6em;
    z-index: 1099;
    pointer-events: none;
    border-top: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    background: rgba(20, 52, 95, 0.06);
    transform: translateY(-50%);
}
html[data-theme="dark"] .a11y-guide { background: rgba(143, 176, 232, 0.10); }

/* Réglages : classes posées sur <html> */
html.a11y-texte-112 { font-size: 112.5%; }
html.a11y-texte-125 { font-size: 125%; }
html.a11y-texte-137 { font-size: 137.5%; }
html.a11y-texte-150 { font-size: 150%; }

html.a11y-interligne-1 body,
html.a11y-interligne-1 p, html.a11y-interligne-1 li, html.a11y-interligne-1 dd,
html.a11y-interligne-1 td, html.a11y-interligne-1 th, html.a11y-interligne-1 label { line-height: 1.9 !important; }
html.a11y-interligne-2 body,
html.a11y-interligne-2 p, html.a11y-interligne-2 li, html.a11y-interligne-2 dd,
html.a11y-interligne-2 td, html.a11y-interligne-2 th, html.a11y-interligne-2 label { line-height: 2.2 !important; }

html.a11y-espacement body { letter-spacing: 0.1em !important; word-spacing: 0.16em !important; }
html.a11y-espacement h1, html.a11y-espacement h2, html.a11y-espacement h3 { letter-spacing: 0.04em !important; }

html.a11y-police-lisible body,
html.a11y-police-lisible button, html.a11y-police-lisible input,
html.a11y-police-lisible select, html.a11y-police-lisible textarea { font-family: "Atkinson Hyperlegible", var(--font) !important; }

html.a11y-gauche main, html.a11y-gauche main * { text-align: start !important; }   /* début de ligne : gauche en français, droite en arabe */

html.a11y-liens a:not(.btn):not(.nav-logo):not(.footer-logo):not(.filtre) {
    text-decoration: underline !important;
    text-underline-offset: 0.15em;
}

html.a11y-titres h1, html.a11y-titres h2, html.a11y-titres h3, html.a11y-titres h4 {
    text-decoration: underline;
    text-decoration-color: var(--accent);
    text-decoration-thickness: 0.12em;
    text-underline-offset: 0.14em;
}

html.a11y-gris body > *:not(.a11y-panneau):not(.a11y-voile):not(.a11y-guide):not(.a11y-bouton),
html.a11y-gris body::before, html.a11y-gris body::after { filter: grayscale(1); }

html.a11y-images img, html.a11y-images video, html.a11y-images .card-media,
html.a11y-images .produit-visuel, html.a11y-images .cadre { visibility: hidden !important; }

/* html lui-même compte : c'est lui qui porte scroll-behavior: smooth (section 2) */
html.a11y-animations, html.a11y-animations *, html.a11y-animations *::before, html.a11y-animations *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
}

html.a11y-sans-fond body::before, html.a11y-sans-fond body::after { display: none; }

html.a11y-curseur, html.a11y-curseur * {
    cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 24 24'><path d='M5 3l14 8-6 1.5L9 20z' fill='%23000' stroke='%23fff' stroke-width='1.6' stroke-linejoin='round'/></svg>") 5 3, auto !important;
}

/* Contraste renforcé : noir sur blanc (ou blanc sur noir), un seul accent très contrasté, filets pleins */
html.a11y-contraste {
    --bg: #ffffff;
    --bg-alt: #ffffff;
    --ink: #000000;
    --mute: #1a1a1a;
    --rule: #000000;
    --bord-controle: #000000;
    --card: #ffffff;
    --card-on-alt: #ffffff;
    --accent: #0000a8;
    --accent-hover: #000080;
    --nav-bg: rgba(255, 255, 255, 0.97);
    --panel: #000000;
    --panel-ink: #ffffff;
    --panel-mute: #e6e6e6;
    --fond-ligne: transparent;
    --fond-barre: transparent;
}
html.a11y-contraste[data-theme="dark"] {
    --bg: #000000;
    --bg-alt: #000000;
    --ink: #ffffff;
    --mute: #f0f0f0;
    --rule: #ffffff;
    --bord-controle: #ffffff;
    --card: #000000;
    --card-on-alt: #000000;
    --accent: #ffd60a;
    --accent-hover: #ffe45c;
    --accent-on-dark: #ffd60a;
    --nav-bg: rgba(0, 0, 0, 0.97);
    --panel: #000000;
    --panel-ink: #ffffff;
    --panel-mute: #f0f0f0;
}
/* Même palette renforcée sombre quand le thème vient du système, avant le script ou sans lui */
@media (prefers-color-scheme: dark) {
    html.a11y-contraste:not([data-theme="light"]) {
        --bg: #000000;
        --bg-alt: #000000;
        --ink: #ffffff;
        --mute: #f0f0f0;
        --rule: #ffffff;
        --bord-controle: #ffffff;
        --card: #000000;
        --card-on-alt: #000000;
        --accent: #ffd60a;
        --accent-hover: #ffe45c;
        --accent-on-dark: #ffd60a;
        --nav-bg: rgba(0, 0, 0, 0.97);
        --panel: #000000;
        --panel-ink: #ffffff;
        --panel-mute: #f0f0f0;
    }
}
html.a11y-contraste a:not(.btn):not(.nav-logo):not(.footer-logo):not(.filtre) { text-decoration: underline; }
html.a11y-contraste .card, html.a11y-contraste .produit, html.a11y-contraste .press-card,
html.a11y-contraste .cadre, html.a11y-contraste .capture img, html.a11y-contraste .formulaire-apercu { border-width: 2px; }
html.a11y-contraste .btn-primary, html.a11y-contraste .nav-cta,
html.a11y-contraste .filtre[aria-pressed="true"], html.a11y-contraste .a11y-bouton,
html.a11y-contraste .a11y-segments button[aria-pressed="true"] { color: #ffffff; }
html.a11y-contraste[data-theme="dark"] .btn-primary, html.a11y-contraste[data-theme="dark"] .nav-cta,
html.a11y-contraste[data-theme="dark"] .filtre[aria-pressed="true"], html.a11y-contraste[data-theme="dark"] .a11y-bouton,
html.a11y-contraste[data-theme="dark"] .a11y-segments button[aria-pressed="true"] { color: #000000; }

/* ------------------------------------------------------------
   27. Tests techniques : page publique des mesures du site.
   Aucune couleur nouvelle : noir, blanc, gris #f5f5f7, filet gris,
   le bleu d'accent #14345f et son relais #8fb0e8 sur fond sombre.
   Aucune ombre, aucun dégradé, aucun pictogramme.
   Trois règles de lecture : une ligne de texte ne dépasse pas 62
   caractères, les tableaux vivent dans un conteneur qui défile avec
   sa première colonne collante, et chaque bloc porte une phrase en
   clair qui dit ce que le chiffre veut dire.
   ------------------------------------------------------------ */

/* Longueur de ligne : la règle qui tient toute la page */
.tt-familles p, .tt-limites li, .tt-source, .tt-panel-note, .tt-scroll-hint {
    max-width: 62ch;
}

/* ---- Chiffres clés, sur la bande noire ---- */
.tt-chiffres {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: var(--s-8);
    max-width: var(--container);
    margin: var(--s-12) auto 0;
    text-align: left;
}
.tt-chiffres li {
    padding-top: var(--s-4);
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}
.tt-chiffre {
    display: block;
    font-size: clamp(2.4rem, 6vw, 3.4rem);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1;
    color: var(--accent-on-dark);
    font-variant-numeric: tabular-nums;
}
.tt-legende {
    display: block;
    margin-top: var(--s-3);
    font-size: var(--text-sm);
    color: var(--panel-mute);
}
.tt-panel-note {
    margin-top: var(--s-10);
    font-size: var(--text-sm);
    color: var(--panel-mute);
}

/* ---- La phrase en clair : ce que le résultat veut dire ---- */
.tt-en-clair {
    display: block;
    max-width: 62ch;
    margin-top: var(--s-4);
    padding-left: var(--s-4);
    border-left: 2px solid var(--accent);
    color: var(--accent);
    font-weight: 500;
    font-size: var(--text-lg);
    letter-spacing: -0.015em;
}
.tt-en-clair--bande {
    margin-top: var(--s-3);
    padding-left: var(--s-3);
    border-left-color: var(--accent-on-dark);
    color: var(--accent-on-dark);
    font-size: var(--text-base);
}

/* ---- Blocs de tableaux ---- */
.tt-bloc {
    max-width: var(--container);
    margin: 0 auto var(--s-8);
    background: var(--card-on-alt);
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    padding: clamp(1.25rem, 3vw, 2rem);
}
.tt-bloc:last-child { margin-bottom: 0; }
.tt-bloc h3 { margin-bottom: var(--s-3); }
.tt-bloc .tt-en-clair { margin-top: var(--s-4); }
/* Relevé automatique du jour : les tableaux remplis par mesures.js, séparés de la méthode qui suit. */
.tt-releve { margin-bottom: var(--s-8); }
.tt-table td.tt-texte { white-space: normal; min-width: 14ch; }

.tt-source {
    margin: 0 0 var(--s-4);
    font-size: var(--text-sm);
    color: var(--mute);
}
.tt-scroll-hint {
    margin: 0 0 var(--s-3);
    font-size: var(--text-sm);
    color: var(--mute);
}

/* ---- Tableaux ---- */
.tt-table {
    width: 100%;
    min-width: 620px;
    border-collapse: collapse;
    font-size: var(--text-sm);
}
.tt-table caption {
    caption-side: top;
    text-align: left;
    font-weight: 600;
    font-size: var(--text-base);
    color: var(--ink);
    padding-bottom: var(--s-3);
}
.tt-table th, .tt-table td {
    text-align: left;
    vertical-align: top;
    padding: var(--s-2) var(--s-4);
    border-bottom: 1px solid var(--rule);
}
.tt-table th:first-child, .tt-table td:first-child { padding-left: 0; }
.tt-table thead th {
    font-weight: 600;
    color: var(--ink);
    white-space: nowrap;
    border-bottom: 2px solid var(--accent);
}
.tt-table td { color: var(--mute); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tt-table tbody tr:last-child th, .tt-table tbody tr:last-child td { border-bottom: 0; }

/* Première colonne collante : le nom de la page reste lisible pendant le défilement */
.tt-table tbody th, .tt-table thead th:first-child {
    position: sticky;
    left: 0;
    background: var(--card-on-alt);
    border-right: 1px solid var(--rule);
    padding-right: var(--s-6);
    z-index: 1;
}
.tt-table thead th:first-child { z-index: 2; }
.tt-table tbody th { font-weight: 600; color: var(--ink); }
.tt-page-nom { display: block; }
.tt-table small {
    display: block;
    margin-top: 2px;
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--mute);
}

/* Les scores : au dessus de 90 en encre, en dessous en bleu, jamais de rouge ni de vert */
.tt-score { font-variant-numeric: tabular-nums; }
.tt-score--haut { color: var(--ink); font-weight: 600; }
.tt-score--bas { color: var(--accent); font-weight: 600; }

.tt-table code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
    overflow-wrap: anywhere;
}
.tt-table--corrections { min-width: 720px; }
.tt-table--corrections td { max-width: 28rem; white-space: normal; }
.tt-table--corrections tbody th { max-width: 15rem; white-space: normal; }

.table-scroll { overflow-x: auto; }
.table-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---- Fiches par famille de tests ---- */
.tt-familles {
    max-width: var(--container);
    margin: 0 auto;
    display: grid;
    gap: var(--s-4);
}
/* Quinze familles de tests sur une page : la fiche est dense, sinon la page
   devient un rouleau. Moins de marge intérieure que les cards du reste du site. */
.tt-famille { display: grid; gap: var(--s-6); padding: clamp(1.25rem, 3vw, 2rem); }
.tt-famille h3 { margin-bottom: var(--s-2); }
.tt-outil {
    font-size: var(--text-sm);
    color: var(--mute);
}
.tt-verdict {
    margin-top: var(--s-3);
    color: var(--ink);
    font-weight: 600;
}
.tt-famille .tt-resultat {
    margin-top: var(--s-4);
    font-size: var(--text-sm);
    color: var(--ink);
}
.tt-famille .tt-methode {
    margin-top: var(--s-3);
    font-size: var(--text-sm);
    color: var(--mute);
}
.tt-sous-titre {
    margin-top: var(--s-4);
    color: var(--ink);
    font-weight: 600;
    font-size: var(--text-base);
}
.tt-ecarts, .tt-notes {
    list-style: none;
    margin-top: var(--s-2);
    display: grid;
    gap: var(--s-2);
}
.tt-ecarts li, .tt-notes li {
    max-width: 62ch;
    font-size: var(--text-sm);
    color: var(--mute);
    padding-left: var(--s-4);
    border-left: 2px solid var(--rule);
}
.tt-ecart-phrase { color: var(--ink); }
.tt-ecart-portee { display: block; margin-top: 2px; }
.tt-ecarts code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.92em;
    color: var(--ink);
    overflow-wrap: anywhere;
}

/* ---- Replis natifs : la liste longue reste fermée ---- */
.tt-details { margin-top: var(--s-3); }
.tt-details--famille { margin-top: var(--s-4); border-top: 1px solid var(--rule); padding-top: var(--s-2); }
.tt-details--famille .tt-methode { margin-top: var(--s-2); }
.tt-details--famille .tt-sous-titre:first-of-type { margin-top: var(--s-4); }
.tt-details > summary {
    cursor: pointer;
    display: inline-block;
    padding: var(--s-2) 0;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--accent);
}
.tt-details > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
.tt-details[open] > summary { margin-bottom: var(--s-2); }

/* ---- Limites ---- */
.tt-limites { max-width: var(--container-text); margin: 0 auto; }
.tt-limites ul { list-style: none; display: grid; gap: var(--s-4); }
.tt-limites li {
    color: var(--mute);
    padding-left: var(--s-6);
    border-left: 2px solid var(--rule);
}

/* ---- Deux colonnes dans la fiche, à partir de 900 pixels ---- */
@media (min-width: 900px) {
    .tt-famille {
        grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
        gap: var(--s-10);
        align-items: start;
    }
    .tt-famille-tete { border-right: 1px solid var(--rule); padding-right: var(--s-8); }
    /* La colonne des résultats accepte un tableau plus large qu'elle sans agrandir la grille */
    .tt-famille-corps { min-width: 0; }
}

/* Le rappel de défilement ne sert qu'aux largeurs où le tableau déborde */
@media (min-width: 920px) {
    .tt-scroll-hint { display: none; }
}

@media (max-width: 640px) {
    .tt-chiffres { gap: var(--s-6); }
    .tt-en-clair { font-size: var(--text-base); }
}

@media print {
    .tt-table { min-width: 0; font-size: 9pt; }
    .tt-table tbody th, .tt-table thead th:first-child { position: static; }
    .table-scroll { overflow: visible; }
    .tt-scroll-hint { display: none; }
    .tt-details > summary { display: none; }
    .tt-bloc { border: 0; padding: 0; }
}

/* ------------------------------------------------------------
   28. Témoignages : retours clients reproduits mot pour mot.
   Cartes à filet, citation en grand, filet bleu d'ouverture,
   attribution en petit ; variante compacte dans une fiche du catalogue.
   ------------------------------------------------------------ */
.temoignages {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-6);
    max-width: var(--container);
    margin: 0 auto;
}
@media (max-width: 720px) { .temoignages { grid-template-columns: 1fr; } }
.temoignage {
    margin: 0;
    padding: var(--s-8);
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    background: var(--card);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--s-6);
}
.temoignage blockquote {
    margin: 0;
    font-size: var(--text-lg);
    line-height: 1.5;
    letter-spacing: -0.012em;
    color: var(--ink);
}
.temoignage blockquote::before {
    content: "";
    display: block;
    width: 44px;
    height: 2px;
    background: var(--accent);
    margin-bottom: var(--s-6);
}
.temoignage blockquote p + p { margin-top: var(--s-3); }
.temoignage figcaption {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--s-1) var(--s-4);
    font-size: var(--text-sm);
    color: var(--mute);
}
.temoignage figcaption strong { color: var(--ink); font-weight: 600; }
.temoignage-role { flex-basis: 100%; }
.temoignages-source {
    max-width: var(--container-text);
    margin: var(--s-8) auto 0;
    text-align: center;
    font-size: var(--text-sm);
    color: var(--mute);
}

/* Variante compacte, dans les fiches SAT Plus et Inage Créa du catalogue */
.produit-temoignage {
    margin: var(--s-4) 0 0;
    padding: var(--s-4) var(--s-4) var(--s-4) var(--s-6);
    border-left: 2px solid var(--accent);
    border-radius: 0 var(--r) var(--r) 0;
    background: var(--bg-alt);
    font-size: var(--text-sm);
    line-height: 1.55;
    color: var(--ink);
}
.produit-temoignage p { margin: 0; }
.produit-temoignage-auteur { margin-top: var(--s-2) !important; color: var(--mute); }   /* pas de <footer> ici : la règle globale footer lui donnerait 4 rem de padding */
.produit-temoignage-auteur strong { color: var(--ink); font-weight: 600; }
/* L'exemple livré sous les formats de l'étage 2 : SAT Plus, son avis, puis son étude */
.exemple-livre { max-width: var(--container); margin: var(--s-12) auto 0; padding-top: var(--s-12); border-top: 1px solid var(--rule); }
.exemple-livre h3 { font-size: clamp(1.25rem, 2.2vw, 1.75rem); line-height: 1.2; letter-spacing: -0.02em; max-width: 34ch; margin: var(--s-2) 0 0; }
.exemple-livre .produit-temoignage { max-width: 62ch; }

/* ------------------------------------------------------------
   29. Estimations de coût en agence : lien discret vers le document dans les
   fiches du catalogue (aucun montant sur le site, le chiffre vit dans le PDF),
   aperçu du PDF dans une boîte de dialogue native, tableau de la liste.
   Les documents eux-mêmes ont leur feuille, assets/css/estimation.css.
   ------------------------------------------------------------ */
.produit-estimation {
    margin: var(--s-3) 0 0;
    padding-top: var(--s-3);
    border-top: 1px solid var(--rule);
    font-size: var(--text-sm);
    color: var(--mute);
    line-height: 1.6;
}
.produit-estimation a { padding: 4px 0; }   /* cible tactile : 24 px de haut au moins sur une ligne de texte */

/* La boîte de dialogue est centrée à la main : la réinitialisation « margin: 0 » du début de la feuille
   annule le « margin: auto » que le navigateur donne aux <dialog>, qui se retrouvaient collés en haut à gauche.
   L'aperçu montre la VERSION WEB du document (toujours affichable), le bouton mène au PDF. */
dialog.apercu-pdf {
    position: fixed;
    inset: 0;
    margin: auto;
    width: min(960px, calc(100vw - 2 * var(--s-6)));
    height: min(calc(100vh - 2 * var(--s-6)), 1100px);
    max-width: none;
    max-height: none;
    padding: 0;
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    background: var(--bg);
    color: var(--ink);
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
dialog.apercu-pdf:not([open]) { display: none; }
dialog.apercu-pdf::backdrop { background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(4px); }
.apercu-pdf-barre {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-4);
    padding: var(--s-3) var(--s-4);
    border-bottom: 1px solid var(--rule);
    background: var(--bg-alt);
    flex: none;
}
.apercu-pdf-titre { font-size: var(--text-base); font-weight: 600; margin: 0; letter-spacing: -0.01em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apercu-pdf-actions { display: flex; gap: var(--s-2); flex: none; }
.apercu-pdf-actions .btn { min-height: 40px; padding: 8px 14px; font-size: var(--text-sm); }
.apercu-pdf-cadre { display: block; width: 100%; flex: 1 1 auto; min-height: 0; border: 0; background: var(--bg); }
@media (max-width: 640px) { .apercu-pdf-barre { flex-wrap: wrap; } .apercu-pdf-titre { white-space: normal; } }

/* Liste des documents (estimations.html) : cartes du catalogue, bouton puis lien centré */
.produit-actions { display: flex; flex-direction: column; align-items: stretch; gap: var(--s-2); margin-top: var(--s-2); }
.produit-actions .produit-action { margin-top: 0; }
.produit-actions .text-link { text-align: center; font-size: var(--text-sm); padding: 6px 0; }

/* ------------------------------------------------------------
   30. Langues : bandeau de suggestion (main.js section 14) posé en bas
   à gauche, à l'opposé du bouton d'accessibilité ; écriture de droite à
   gauche pour l'arabe (police Noto Sans Arabic chargée par la page).
   ------------------------------------------------------------ */
.langue-bandeau {
    position: fixed;
    bottom: var(--s-6);
    left: var(--s-6);
    z-index: 60;
    max-width: min(520px, calc(100vw - 2 * var(--s-6) - 72px));
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-2) var(--s-4);
    padding: var(--s-3) var(--s-4);
    background: var(--card);
    color: var(--ink);
    border: 1px solid var(--rule);
    border-radius: var(--r-lg);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
    font-size: var(--text-sm);
}
.langue-bandeau p { margin: 0; flex: 1 1 auto; }
.langue-bandeau a { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 0.15em; padding: 6px 0; }
.langue-bandeau-fermer {
    appearance: none;
    border: 1px solid var(--rule);
    background: transparent;
    color: var(--ink);
    width: 36px; height: 36px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
}
.langue-bandeau-fermer:hover { background: var(--bg-alt); }
@media (max-width: 640px) { .langue-bandeau { left: var(--s-4); right: var(--s-4); bottom: calc(var(--s-6) + 64px); max-width: none; } }
@media print { .langue-bandeau { display: none !important; } }

/* ------------------------------------------------------------
   31. Drapeaux : petits SVG inline (France, Union européenne) posés
   devant un mot qui dit déjà le pays ou le droit ; décoratifs, jamais
   dans le sélecteur de langue. Hauteur d'une lettre, coins à peine arrondis.
   ------------------------------------------------------------ */
.drapeau {
    display: inline-block;
    width: 1.3em;
    height: auto;
    vertical-align: -0.18em;
    margin-right: 0.4em;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
    flex: none;
}
.drapeau + .drapeau { margin-left: -0.15em; }
html[data-theme="dark"] .drapeau { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18); }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) .drapeau { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18); } }
html.a11y-gris .drapeau { filter: none; }
.insecable { white-space: nowrap; }   /* groupe de mots qui ne se coupe pas en fin de ligne (kicker de l'accueil) */

html[dir="rtl"] body { font-family: "Noto Sans Arabic", var(--font); }
html[dir="rtl"] .langue-bandeau { left: auto; right: var(--s-6); }
html[dir="rtl"] .a11y-bouton { right: auto; left: var(--s-6); }
@media (max-width: 640px) { html[dir="rtl"] .langue-bandeau { left: var(--s-4); right: var(--s-4); } }

/* ------------------------------------------------------------
   32. Vivant : portrait, galerie des sites, chiffres, auréoles, particules.
   Une seule lumière vive (#2997ff), posée par petites touches ; le reste
   garde les bleus du site. Tout s'arrête sous prefers-reduced-motion et
   avec le réglage « réduire les animations » du panneau (html.a11y-animations) ;
   le fond disparaît avec « masquer le fond » (html.a11y-sans-fond).
   ------------------------------------------------------------ */
:root { --lumiere: #2997ff; --lumiere-14: rgba(41, 151, 255, 0.14); --lumiere-35: rgba(41, 151, 255, 0.35); --halo: rgba(20, 52, 95, 0.45); }
html[data-theme="dark"] { --halo: rgba(0, 0, 0, 0.85); }
@media (prefers-color-scheme: dark) { html:not([data-theme="light"]) { --halo: rgba(0, 0, 0, 0.85); } }

/* Accueil : le texte à gauche, le portrait à droite dans un halo qui respire lentement.
   Le halo déborde du portrait : la section le rogne sur les côtés pour ne jamais créer de défilement horizontal
   (constaté à 1024 px par le banc du 12 septembre 2026). */
.hero { overflow-x: clip; }
/* Les colonnes ne valent qu'au-dessus du point de bascule de .hero-split (820 px) : en dessous, la grille
   passe en une colonne et le portrait, plus petit, précède le texte. */
@media (min-width: 821px) {
    .hero-split--portrait { grid-template-columns: 1.15fr 0.85fr; }
    .hero-split--portrait h1 { font-size: clamp(2.1rem, 4.4vw, 3.4rem); letter-spacing: -0.03em; line-height: 1.06; }
    .hero-split--portrait .hero-lede { font-size: clamp(1.0625rem, 1.7vw, 1.25rem); max-width: 560px; }
}
@media (max-width: 820px) {
    .hero-split--portrait h1 { font-size: clamp(1.9rem, 8vw, 2.6rem); letter-spacing: -0.03em; line-height: 1.08; }
}
.hero-portrait { position: relative; max-width: 380px; margin: 0 auto; }
.hero-portrait::before {
    content: "";
    position: absolute;
    inset: -12% -16% -8% -16%;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(41, 151, 255, 0.22), rgba(20, 52, 95, 0.10) 55%, transparent 100%);
    filter: blur(18px);
    animation: halo-respire 9s ease-in-out infinite alternate;
}
html[data-theme="dark"] .hero-portrait::before { background: radial-gradient(closest-side, rgba(41, 151, 255, 0.30), rgba(143, 176, 232, 0.12) 55%, transparent 100%); }
@keyframes halo-respire { from { opacity: 0.55; transform: scale(0.96); } to { opacity: 1; transform: scale(1.03); } }
.hero-portrait img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    border-radius: var(--r-lg);
    border: 1px solid var(--rule);
    box-shadow: 0 30px 80px -24px var(--halo);
}
.hero-portrait figcaption {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    margin-top: var(--s-4);
    font-size: var(--text-sm);
    color: var(--mute);
    text-align: left;
}
/* Le point bleu qui bat : le signe « joignable » */
.led {
    flex: 0 0 auto;
    display: inline-block;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--lumiere);
    box-shadow: 0 0 0 3px var(--lumiere-14);
    animation: led-bat 3.2s ease-in-out infinite;
}
@keyframes led-bat { 0%, 100% { box-shadow: 0 0 0 3px var(--lumiere-14); } 50% { box-shadow: 0 0 0 8px rgba(41, 151, 255, 0.05); } }
@media (max-width: 820px) {
    .hero-split--portrait .hero-portrait { order: -1; max-width: 240px; margin-bottom: var(--s-8); }
    .hero-portrait figcaption { justify-content: center; text-align: center; }
}

/* Portrait rond des pages secondaires (contact) */
.portrait-rond {
    display: block;
    width: 128px; height: 128px;
    margin: 0 auto var(--s-6);
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--rule);
    box-shadow: 0 16px 40px -16px var(--halo), 0 0 0 6px var(--lumiere-14);
}

/* Galerie : les captures des sites en ligne forment une bande à faire défiler à la main, à l'horizontale,
   que le navigateur sait amener au focus (page de l'étage « Le site » ; la scène en trois dimensions
   accroche les mêmes images au mur du hall d'exposition). Un seul axe : les titres, les grands formats, la première tuile
   et le lien du catalogue partent du bord gauche du conteneur, comme les autres sections à plat. */
.galerie { --galerie-marge: max(var(--gutter), calc((100% - var(--container)) / 2)); padding: 0 0 var(--s-16); }
.section.galerie-formats { padding-left: 0; padding-right: 0; }
.galerie-formats .formats-grille { max-width: calc(var(--container) + 2 * var(--gutter)); }
.galerie-scene { display: flex; flex-direction: column; justify-content: center; }
.galerie-tete { width: 100%; max-width: calc(var(--container) + 2 * var(--gutter)); margin: 0 auto var(--s-8); padding: 0 var(--gutter); }
.galerie-titre { font-size: var(--text-lg); font-weight: 600; letter-spacing: -0.018em; margin: 0; }
.galerie-colle { overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; scroll-snap-type: x proximity; scroll-padding-inline: var(--galerie-marge); }
.galerie-piste { list-style: none; margin: 0; padding: var(--s-2) var(--galerie-marge) var(--s-6); display: flex; gap: var(--s-6); width: max-content; }
/* Grandes tuiles : la hauteur libre sous le titre fixe leur taille (image 16:10 et sa légende), la largeur de la fenêtre la
   borne, et la source aussi : 720 px au plus, la moitié du fichier de 1440, pour rester nette sur un écran de densité 2 */
.galerie-item { flex: 0 0 auto; width: clamp(280px, min(64vw, calc((100vh - 300px) * 1.6)), 720px); scroll-snap-align: start; }
.galerie-lien { width: 100%; max-width: calc(var(--container) + 2 * var(--gutter)); margin: var(--s-4) auto 0; padding: 0 var(--gutter); }
/* Grands formats : le titre, la ligne, puis le domaine qui ferme la légende (les titres d'un rang restent alignés, même
   pour la boutique qui n'a pas d'adresse publique) */
.format .capture-domaine { margin-top: var(--s-1); }
@media (prefers-reduced-motion: reduce) {
    .hero-portrait::before, .led { animation: none; }
}
html.a11y-animations .hero-portrait::before, html.a11y-animations .led { animation: none; }
@media print { .galerie, .tuyau, .fond-particules { display: none !important; } }

/* Chiffres : quatre nombres qui se comptent à l'arrivée à l'écran, une lumière sous chacun */
.chiffres { padding: 0 var(--gutter) var(--section-pad); }
.chiffres-liste {
    list-style: none;
    margin: 0 auto;
    padding: var(--s-10) 0 0;
    max-width: var(--container);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-8) var(--s-6);
    border-top: 1px solid var(--rule);
}
.chiffres-liste li { display: flex; flex-direction: column; gap: var(--s-3); }
.chiffre {
    font-size: clamp(2.6rem, 6vw, 4.25rem);
    font-weight: 700;
    letter-spacing: -0.035em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}
.chiffre-trait { display: block; width: 44px; height: 2px; background: linear-gradient(90deg, var(--lumiere), var(--accent)); transform-origin: left; transform: scaleX(0); transition: transform 1.1s var(--ease-out) 0.2s; }
.chiffres-liste li.compte .chiffre-trait { transform: scaleX(1); }
.chiffre-label { font-size: var(--text-sm); color: var(--mute); line-height: 1.5; max-width: 22ch; }
@media (max-width: 820px) { .chiffres-liste { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .chiffres-liste { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .chiffre-trait { transition: none; transform: scaleX(1); } }
html.a11y-animations .chiffre-trait { transition: none; transform: scaleX(1); }

/* Auréoles : au survol et au focus, un halo bleu se pose sous les cartes, les fiches, les filtres,
   les boutons et les témoignages. La lumière vive reste en bord, jamais en aplat. */
.card, .produit, .temoignage, .press-card, .doc-fiche {
    transition: box-shadow 0.45s var(--ease), transform 0.45s var(--ease), border-color 0.45s var(--ease);
}
.card:hover, .produit:hover, .temoignage:hover, .card:focus-within, .produit:focus-within {
    border-color: rgba(20, 52, 95, 0.35);
    box-shadow: 0 0 0 1px rgba(20, 52, 95, 0.08), 0 20px 50px -24px var(--halo), 0 0 70px -22px var(--lumiere-35);
    transform: translateY(-2px);
}
html[data-theme="dark"] .card:hover, html[data-theme="dark"] .produit:hover, html[data-theme="dark"] .temoignage:hover,
html[data-theme="dark"] .card:focus-within, html[data-theme="dark"] .produit:focus-within {
    border-color: rgba(143, 176, 232, 0.4);
    box-shadow: 0 0 0 1px rgba(143, 176, 232, 0.10), 0 20px 50px -24px var(--halo), 0 0 70px -22px rgba(41, 151, 255, 0.5);
}
.btn { transition: background 0.2s var(--ease), color 0.2s var(--ease), transform var(--mv-t-relache) var(--mv-appui), box-shadow 0.35s var(--ease); }
.btn:focus-visible { box-shadow: 0 0 0 4px var(--lumiere-14), 0 12px 30px -14px var(--halo); }
@media (hover: hover) and (pointer: fine) { .btn:hover { box-shadow: 0 0 0 4px var(--lumiere-14), 0 12px 30px -14px var(--halo); } }
.filtre { transition: background 0.2s var(--ease), color 0.2s var(--ease), border-color 0.2s var(--ease), box-shadow 0.35s var(--ease); }
.filtre:hover, .filtre:focus-visible { box-shadow: 0 0 0 4px var(--lumiere-14), 0 0 30px -8px var(--lumiere-35); }
.a11y-bouton:focus-visible { box-shadow: 0 0 0 5px var(--lumiere-14), 0 12px 30px -12px var(--halo); }
@media (hover: hover) and (pointer: fine) { .a11y-bouton:hover { box-shadow: 0 0 0 5px var(--lumiere-14), 0 12px 30px -12px var(--halo); } }
@media (prefers-reduced-motion: reduce) {
    .card, .produit, .temoignage, .press-card, .doc-fiche, .btn, .filtre { transition: none; }
    .card:hover, .produit:hover, .temoignage:hover, .card:focus-within, .produit:focus-within { transform: none; }
}
html.a11y-animations .card, html.a11y-animations .produit, html.a11y-animations .temoignage, html.a11y-animations .btn, html.a11y-animations .filtre { transition: none; }
html.a11y-animations .card:hover, html.a11y-animations .produit:hover, html.a11y-animations .temoignage:hover { transform: none; }

/* Lien de suite sous une grille de cartes (accueil, études de cas) */
.section-suite { text-align: center; margin: var(--s-10) auto 0; }

/* Pages document : un paragraphe qui suit une liste reprend son souffle (page Comment je travaille, § 06) */
.legal-section ul + p, .legal-section ol + p { margin-top: var(--s-6); }

/* Texte réservé aux lecteurs d'écran */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Particules : un canevas fixe derrière la page, dessiné par main.js (section 16) ; quelques points
   bleus qui montent lentement, un éclat toutes les cinq à neuf secondes. Rien sans script. */
.fond-particules { position: fixed; inset: 0; z-index: -1; pointer-events: none; }
html.a11y-sans-fond .fond-particules { display: none; }

/* ------------------------------------------------------------
   33. Utilitaires de mise en page, passe du 13 septembre 2026 : remplacent les
   dix-huit attributs style posés dans les pages, pour une politique de sécurité
   du contenu sans styles en ligne. Une classe par intention, nommée par son rôle.
   ------------------------------------------------------------ */
/* Section qui suit directement un hero : pas de marge haute, le hero porte déjà la sienne */
.section.section--suite-hero { padding-top: 0; }
/* Groupe de boutons aligné à gauche (formulaires, fiches) au lieu du centrage par défaut */
.hero-cta.hero-cta--gauche { justify-content: flex-start; }
.hero-cta.hero-cta--espace { margin-top: var(--s-6); }
/* Note centrée sous un bloc : renvoi vers un autre site, flux RSS */
.section .note-centre { text-align: center; color: var(--mute); margin-top: var(--s-8); }
.section .note-centre--petite { margin-top: var(--s-12); font-size: var(--text-sm); }
/* Renvoi centré qui ne porte qu'un lien : couleur et taille du texte courant */
.section .note-centre--lien { margin-top: var(--s-12); color: inherit; }
/* Lien de sortie d'une bande sombre */
.panel-inner .panel-lien { margin-top: var(--s-16); }
/* La phrase-thèse de l'accueil et son lien */
.cta-final .manifeste {
    font-size: clamp(1.6rem, 4vw, 2.6rem);
    font-weight: 700;
    letter-spacing: -0.022em;
    line-height: 1.2;
    max-width: 720px;
    margin: 0 auto;
}
.cta-final .manifeste-lien { margin-top: var(--s-6); margin-bottom: 0; }

/* Les bandes des étages : une bande par carte, pleine largeur, empilées. Le mot du surtitre en très grand sur toute la
   largeur, puis la promesse (h3) en gros et le détail (p) en petit d'un côté, la vue de la scène de l'autre, à gauche puis à
   droite. Les cartes gardent .card-grid et .card (les scènes lisent ces classes, leur surtitre, leur h3, leur paragraphe) et
   reçoivent .bandes et .bande ; le texte est enveloppé dans .bande-texte, l'image porte .bande-image. Les couleurs viennent
   des jetons de la palette de la salle. Sur téléphone tout s'empile, le mot reste grand, le texte précède l'image. */
.section.section--bandes .section-head { max-width: var(--container); margin: 0 auto var(--s-12); text-align: left; }
.section.section--bandes .section-head p { max-width: var(--container-text); }
.card-grid.bandes { display: block; }
.bandes .bande {
    container-type: inline-size;
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-6) var(--s-12); align-items: center;
    padding: var(--s-12) 0; background: none; border: 0; border-top: 1px solid var(--rule); border-radius: 0; box-shadow: none; transform: none;
}
.bandes .bande:first-child { border-top: 0; padding-top: 0; }
.bandes .bande:hover, .bandes .bande:focus-within { border-color: var(--rule); box-shadow: none; transform: none; }
.bandes .bande > .overline {
    grid-column: 1 / -1; margin: 0; font-size: clamp(2.2rem, 7vw, 6rem); font-size: min(clamp(2.2rem, 7vw, 6rem), 11.5cqi); font-weight: 800; line-height: 0.95;
    letter-spacing: -0.035em; text-transform: uppercase; color: var(--ink); text-wrap: balance;
}
.bandes .bande > .overline .drapeau { width: 0.55em; height: 0.38em; vertical-align: 0.06em; margin-right: 0.18em; }
/* le premier segment du surtitre en grand, le reste (client, année) en petit sur la ligne du dessous */
.bandes .bande > .overline .bande-reste { display: block; margin-top: var(--s-3); font-size: var(--text-base); font-weight: 600; line-height: 1.3; letter-spacing: -0.01em; text-transform: none; color: var(--mute); }
.bandes .bande > .overline .bande-sep { display: none; }
.bandes .bande-texte h3 { font-size: clamp(1.5rem, 2.6vw, 2.125rem); line-height: 1.15; letter-spacing: -0.022em; margin-bottom: var(--s-4); }
.bandes .bande-texte p { color: var(--mute); font-size: var(--text-base); line-height: 1.55; max-width: 46ch; }
.bandes .bande-texte .link-more { margin-top: var(--s-5); }
.bandes .bande:nth-child(even) > .bande-texte { order: 2; }
.bandes .bande-image { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; border-radius: var(--r); border: 1px solid var(--rule); background: var(--bg-alt); }
.bandes--sans-image .bande { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 760px) {
    .bandes .bande { grid-template-columns: minmax(0, 1fr); gap: var(--s-6); padding: var(--s-10) 0; }
    .bandes .bande:nth-child(even) > .bande-texte { order: 0; }
    .bandes .bande-texte p { max-width: none; }
}

/* ------------------------------------------------------------
   34. Questions fréquentes : sous chaque réponse, la ligne « Vérifier »,
   qui renvoie aux pages du site qui prouvent la réponse. Une ligne de
   service, plus petite que la réponse et détachée par un filet.
   Aucune couleur nouvelle : les jetons de la section 12 suffisent.
   ------------------------------------------------------------ */
.legal-section .faq-preuve {
    margin-top: var(--s-6);
    padding-top: var(--s-3);
    border-top: 1px solid var(--rule);
    font-size: var(--text-sm);
    line-height: 1.55;
}

/* ------------------------------------------------------------
   35. La cabine : la phrase « Cinq pièces, un seul tuyau » et son aura, dans la station
   cabine de l'accueil (la scène elle-même vit dans assets/css/immeuble.css et
   assets/js/immeuble/).
   ------------------------------------------------------------ */
.tuyau { padding: 0 var(--gutter) var(--s-16); }
.tuyau-inner { max-width: var(--container); margin: 0 auto; }
.tuyau-titre { font-size: var(--text-lg); font-weight: 600; letter-spacing: -0.018em; margin: 0 0 var(--s-8); }
/* La ligne sous le tuyau : une phrase, posée comme un titre, l'encre du thème */
.tuyau-inner .tuyau-aura { margin: var(--s-8) 0 0; font-size: clamp(1.3rem, 2.4vw, 1.95rem); font-weight: 600; letter-spacing: -0.02em; line-height: 1.2; color: var(--ink); text-wrap: balance; }
.tuyau-inner .tuyau-texte { max-width: var(--container-text); color: var(--mute); font-size: var(--text-md, 1.125rem); line-height: 1.55; margin: 0; }

/* ------------------------------------------------------------
   37. Le manifeste s'écrit au défilement : la phrase passe du gris à l'encre pendant
   qu'elle traverse le milieu de l'écran (dégradé découpé par le texte, glissé par le
   défilement). Sans prise en charge, sous mouvement réduit ou sur demande du panneau :
   texte à l'encre, immobile.
   ------------------------------------------------------------ */
@supports (animation-timeline: view()) and (background-clip: text) {
    @media (prefers-reduced-motion: no-preference) {
        html:not(.a11y-animations) .cta-final .manifeste { view-timeline-name: --manifeste; view-timeline-axis: block; }
        html:not(.a11y-animations) .cta-final .manifeste,
        html:not(.a11y-animations) .cta-final .manifeste em {
            background-image: linear-gradient(90deg, var(--ink) 0 50%, var(--mute) 50% 100%);
            background-size: 200% 100%;
            background-position: 100% 0;
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            animation: manifeste-remplir linear both;
            animation-timeline: --manifeste;
            animation-range: entry 60% cover 55%;
        }
        html:not(.a11y-animations) .cta-final .manifeste em {
            background-image: linear-gradient(90deg, var(--accent) 0 50%, var(--mute) 50% 100%);
        }
    }
}
@keyframes manifeste-remplir { to { background-position: 0 0; } }

/* ------------------------------------------------------------
   38. Transitions de page natives : d'une page à l'autre, la barre reste en place, le
   titre glisse vers sa nouvelle position et le reste fond. Les deux pages doivent
   porter la règle, elles la portent toutes par cette feuille. Navigateur sans prise
   en charge, mouvement réduit : navigation ordinaire. Panneau « réduire les
   animations » : durées à zéro.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
}
/* Le nom est porté par le contenu de la barre (.nav-container), jamais par <header> ni par .nav : un élément nommé
   forme un contexte d'empilement et une racine de fond. Sur <header>, il enfermait le z-index de la barre sous la scène
   d'entrée collée ; sur .nav, le flou de .nav::before (section 3) ne voyait plus rien derrière la barre et le texte
   passait net sous le nom. Le logo et les liens restent en place pendant le changement de page, le fond de la barre
   suit le fondu de la page. */
.nav-container { view-transition-name: entete; }
main h1 { view-transition-name: titre; }
/* page à scène : le titre n'est pas photographié au-dessus du voile */
html[data-salle]:not([data-salle="imprimerie"]) main h1 { view-transition-name: none; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.28s; animation-timing-function: var(--ease); }
::view-transition-group(titre) { animation-duration: 0.36s; animation-timing-function: cubic-bezier(0.2, 0.7, 0.2, 1); }
html.a11y-animations::view-transition-old(root),
html.a11y-animations::view-transition-new(root),
html.a11y-animations::view-transition-group(*) { animation-duration: 0s; }

/* ------------------------------------------------------------
   39. Pied de page : le nom en très grand, décoratif (le lien du pied porte déjà le
   nom, la ligne est cachée aux lecteurs d'écran). Typographie : titres équilibrés,
   paragraphes sans mot orphelin, là où le navigateur le sait.
   ------------------------------------------------------------ */
/* La taille suit la largeur du pied (unité de conteneur) : le nom occupe toute la ligne sans jamais
   la dépasser, à 390 comme à 1440 pixels. Sans unités de conteneur, le clamp en vw prend le relais. */
.footer-inner { container-type: inline-size; }
.footer-nom {
    margin: 0 0 var(--s-10);
    font-size: clamp(2rem, 9vw, 7rem);
    font-size: 11.6cqi;
    font-weight: 600;
    letter-spacing: -0.045em;
    line-height: 0.95;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    user-select: none;
}
h1, h2, h3 { text-wrap: balance; }
p, li, dd, figcaption { text-wrap: pretty; }

/* ------------------------------------------------------------
   40. L'aveu : la phrase qui dit pourquoi les sites livrés ne ressemblent pas à
   celui-ci, posée après la liste des réalisations, en retrait, sans insister.
   ------------------------------------------------------------ */
.section .aveu { max-width: var(--container-text); margin: var(--s-12) auto 0; color: var(--mute); text-align: center; font-size: var(--text-base); }
.section .aveu strong { color: var(--ink); font-weight: 600; }

/* ------------------------------------------------------------
   41. Le contenu à plat des étages et des annexes, au niveau de la scène.
   Après la scène, la page se lit comme une page de site : un seul axe (le
   bord gauche du conteneur), une marge de section à l'échelle, la fiche
   Entreprise sur la grille de la fiche papier, les tableaux des articles
   lisibles dès la première colonne. Le journal du blog et les pages
   document (questions fréquentes, méthode) gardent leur mise en page.
   ------------------------------------------------------------ */
:root {
    --plat-pad: clamp(3rem, 5vw, 4.5rem);                              /* 48 à 72 px de chaque côté d'une section */
    --plat-bord: max(0px, calc((100% - var(--container)) / 2));       /* le bord du conteneur, pour un bloc plus étroit */
}
/* Le rythme, blog compris : entre deux sections, deux marges de section, jamais le double d'une marge de héros. Le premier
   bloc sous la scène garde la sienne, le dernier aussi : l'arrivée du contenu et sa fin avant le palier sont réglées avec
   la fin de la pièce (immeuble.css). */
main.etage:not(.legal-page--doc) > :is(.section, .panel, .chiffres, .hero.etage-contenu):not(:has(+ .retour-ascenseur)) { padding-bottom: var(--plat-pad); }
main.etage:not(.legal-page--doc) > :not([data-station]) + :is(.section:not(.section--suite-hero), .panel) { padding-top: var(--plat-pad); }
main.etage:not(.legal-page--doc) > .hero.etage-contenu .hero-inner > :last-child { margin-bottom: 0; }
main.etage:not(.legal-page--doc) .bandes .bande:last-child { padding-bottom: 0; }
main.legal-page--doc.etage .legal-update { margin-top: var(--s-10); }

/* Un seul axe : les têtes de section, le héros, les bandeaux, l'appel final, les notes et les blocs étroits partent du bord
   gauche du conteneur, là où partent les grilles de cartes, les bandes et la galerie. */
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) .section-head { max-width: var(--container); margin-left: auto; margin-right: auto; text-align: left; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) .section-head p { max-width: var(--container-text); }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) :is(.section-head, .panel) h2::after { margin-left: 0; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > :is(.hero.etage-contenu, .panel, .cta-final) { text-align: left; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .hero.etage-contenu .hero-inner { max-width: var(--container); }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .panel .panel-inner { max-width: var(--container); text-align: left; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > :is(.hero.etage-contenu, .panel) :is(.hero-lede, .panel-lede, .pillars, .portrait-rond) { margin-left: 0; margin-right: 0; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > :is(.hero.etage-contenu, .cta-final) .hero-cta { justify-content: flex-start; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .cta-final > * { margin-left: var(--plat-bord); margin-right: auto; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .cta-final > h2 { max-width: var(--container); }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .section > :is(.formulaire, .formulaire-retour, .contact-list, .temoignages-source, .aveu) { margin-left: var(--plat-bord); margin-right: auto; text-align: left; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .section > :is(.note-centre, .section-suite, .catalogue-compte) { max-width: var(--container); margin-left: auto; margin-right: auto; text-align: left; }
html:not([data-salle="imprimerie"]) main.etage:not(.legal-page--doc) > .section > .filtres { justify-content: flex-start; }

/* La fiche Entreprise : Identité puis Contact, l'une sous l'autre, comme la fiche papier que l'archiviste ouvre dans la
   scène ; libellé sur un tiers, valeur sur deux tiers, les deux cartes sur le même axe. Une valeur ne se coupe qu'au
   blanc (le courriel et l'adresse restent entiers) ; seul un mot plus long que sa colonne passe à la ligne. Sous 600 px,
   le libellé passe au-dessus de sa valeur, comme sur le papier. */
.card-grid--fiche { grid-template-columns: minmax(0, 1fr); }
.card-grid--fiche .legal-table td { overflow-wrap: break-word; }
@media (min-width: 601px) {
    .card-grid--fiche .legal-table { table-layout: fixed; }
    .card-grid--fiche .legal-table th { width: 33.333%; white-space: normal; padding-right: var(--s-6); }
}

/* Les tableaux des articles : la première colonne (une date, un nom, un seuil) garde une largeur de lecture ; sans elle,
   les colonnes de texte la réduisaient à une centaine de pixels et « 1er septembre 2026 » passait sur trois lignes.
   Le tableau reste dans la colonne de texte (journal.css, la fiche pratique : cartes au téléphone). Chaque cellule part du
   haut de sa ligne : on lit la ligne d'un seul regard. Sous 1 000 px, le tableau reste dans la colonne de texte et ses
   cellules se serrent (12 px de marge au lieu de 16, la première et la dernière colonne au bord du texte) : la place va
   au texte. Au téléphone (sous 700 px, tant que la colonne de texte n'a pas sa pleine largeur), la première colonne garde
   de quoi tenir une date sur deux lignes et les autres n'ont aucun minimum : un tableau qui tient dans l'écran sans la
   règle y tient encore. Un tableau plus large que l'écran défile dans son cadre (.table-scroll), une ombre au bord le
   montre, sa légende reste entière à l'écran, et la page ne déborde jamais (un courriel ou une adresse trop longs passent
   à la ligne). */
.article-body { overflow-wrap: break-word; }
.article-body :is(th, td) { vertical-align: top; }
@media (max-width: 699px) {
    .article-body table :is(th, td):first-child { min-width: 7.5em; }
    .article-body .table-scroll { container-type: inline-size; }
    .article-body .table-scroll caption { position: sticky; left: 0; max-width: 100cqi; text-align: left; }
}
/* Sous 1 000 px, les cellules serrées ; un tableau qui défile le montre : une ombre au bord où il reste des colonnes,
   effacée quand on arrive au bout. */
@media (max-width: 999px) {
    .article-body :is(th, td) { padding-left: var(--s-3); padding-right: var(--s-3); }
    .article-body :is(th, td):first-child { padding-left: 0; }
    .article-body :is(th, td):last-child { padding-right: 0; }
    .article-body .table-scroll {
        background:
            linear-gradient(to right, var(--bg) 40%, transparent) left center / 2rem 100% no-repeat local,
            linear-gradient(to left, var(--bg) 40%, transparent) right center / 2rem 100% no-repeat local,
            radial-gradient(farthest-side at 0 50%, color-mix(in srgb, var(--ink) 18%, transparent), transparent) left center / 0.75rem 100% no-repeat scroll,
            radial-gradient(farthest-side at 100% 50%, color-mix(in srgb, var(--ink) 18%, transparent), transparent) right center / 0.75rem 100% no-repeat scroll;
    }
}
@media (min-width: 700px) {
    .article-body table:not(:has(tr > :nth-child(5))) :is(th, td):first-child { min-width: 9em; }
    .article-body table:not(:has(tr > :nth-child(4))) :is(th, td):first-child { min-width: 11em; }
}

/* ------------------------------------------------------------
   42. Le mouvement des pages à scène (hors imprimerie). titres.js coupe les titres et pose titre-auto,
   titre-attend, titre-joue. Le style de base est l'état final : l'attente n'existe que sous le mouvement permis.
   Le titre de l'accueil ne monte pas : il se lit dès le premier affichage.
   ------------------------------------------------------------ */
.mot { display: inline-block; overflow: clip; padding-block: 0.2em; margin-block: -0.2em; }
.mot > span { display: inline-block; }
.plan-texte--hero h1 .titre-moitie { display: block; }
.plan-texte--arrivee h1 { --mv-duree: 560ms; }
.plan-texte--arrivee h1 .mot { --mv-retard: calc(420ms + var(--i, 0) * 60ms); }
.station--piece .plan-texte h2 { --mv-duree: 520ms; }
.station--piece .plan-texte h2 .mot { --mv-retard: calc(var(--i, 0) * 70ms); }
.etage-contenu .section-head h2, .bandes .bande-texte h3 { --mv-duree: 480ms; }
.etage-contenu .section-head h2 .mot { --mv-retard: calc(var(--i, 0) * 45ms); }
.bandes .bande > .overline { --mv-duree: 700ms; }
.bandes .bande-texte h3 .mot { --mv-retard: calc(140ms + var(--i, 0) * 45ms); }
.palier-titre { --mv-duree: 520ms; }
.palier-titre .mot { --mv-retard: calc(120ms + var(--i, 0) * 60ms); }
.plan-texte--arrivee .piece-numero .lettre { --mv-retard: calc(300ms + var(--i, 0) * 24ms); }
.palier .piece-numero .lettre { --mv-retard: calc(var(--i, 0) * 30ms); }
.indice-doigt { display: none; }
@media (hover: none) and (any-pointer: coarse) { .indice .indice-souris { display: none; } .indice .indice-doigt { display: inline; } }
@media (min-width: 821px) {
    .nav-menu a:not(.nav-cta) { position: relative; }
    .nav-menu a:not(.nav-cta)::after { content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 1.5px; background: currentColor; transform: scaleX(0); transform-origin: right; }
    .nav-menu a.active:not(.nav-cta)::after { transform: none; }
}
@media (hover: hover) and (pointer: fine) and (min-width: 821px) { .nav-menu a:not(.nav-cta):hover::after { transform: none; transform-origin: left; } }
html[data-salle]:not([data-salle="imprimerie"]) main .text-link { text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); }
html[data-salle]:not([data-salle="imprimerie"]) main .link-more { text-decoration: underline transparent; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
html[data-salle]:not([data-salle="imprimerie"]) main .text-link:focus-visible, html[data-salle]:not([data-salle="imprimerie"]) main .link-more:focus-visible { text-decoration-color: currentColor; }
@media (hover: hover) and (pointer: fine) {
    html[data-salle]:not([data-salle="imprimerie"]) main .text-link:hover, html[data-salle]:not([data-salle="imprimerie"]) main .link-more:hover { text-decoration-color: currentColor; }
    html[data-salle]:not([data-salle="imprimerie"]) main .link-more:hover::after { transform: translateX(3px); }
}
html[data-salle]:not([data-salle="imprimerie"]) main .link-more:active::after { transform: translateX(5px); }
.menu-toggle { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.hero-cta .btn, .palier-actions .btn { position: relative; }
/* « Visiter l'immeuble » pressé avant la scène attend le hall (main.js section 17) et le montre */
.hero-cta .hero-visite[aria-busy="true"] { cursor: progress; opacity: 0.7; }

@keyframes mv-attente { from { opacity: 1; } to { opacity: 0.55; } }
@keyframes mv-monte { from { transform: translateY(110%); opacity: 0; } 40% { opacity: 1; } to { transform: none; opacity: 1; } }
@keyframes mv-lettre { from { opacity: 0; } to { opacity: 1; } }
@keyframes mv-filet { from { transform: scaleX(0); } to { transform: none; } }
@keyframes mv-anneau { from { transform: scale(1); opacity: 0.55; } to { transform: scale(1.22); opacity: 0; } }
@keyframes mv-parti { from { transform: scale(1); opacity: 0.9; } to { transform: scale(1.35); opacity: 0; } }
@keyframes mv-cascade { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }

@media screen and (prefers-reduced-motion: no-preference) {
    html.accueil-3d:not(.a11y-animations) :is(.titre-auto, .titre-joue):not(.titre-pose) .mot > span { animation: mv-monte var(--mv-duree, 520ms) var(--mv-entree) var(--mv-retard, 0ms) 1 backwards; }
    html.accueil-3d:not(.a11y-animations) .titre-attend .mot > span { transform: translateY(110%); opacity: 0; }
    html.accueil-3d:not(.a11y-animations) :is(.titre-auto, .titre-joue):not(.titre-pose) .lettre { animation: mv-lettre 10ms step-end var(--mv-retard, 0ms) 1 backwards; }
    html.accueil-3d:not(.a11y-animations) .titre-attend .lettre { opacity: 0; }
    html.accueil-3d:not(.a11y-animations) .etage-contenu .section-head h2.titre-attend::after { transform: scaleX(0); }
    html.accueil-3d:not(.a11y-animations) .etage-contenu .section-head h2.titre-joue:not(.titre-pose)::after { transform-origin: left; animation: mv-filet var(--mv-long) var(--mv-entree) 300ms 1 backwards; }
    html.accueil-3d:not(.a11y-animations) .rue-entree:not(.rue-posee) .hero-cta .btn-primary:not(.est-parti)::after,
    html.accueil-3d:not(.a11y-animations) .hero-cta .est-parti::after,
    html.accueil-3d:not(.a11y-animations) footer.palier.titre-joue .palier-actions .btn::after {
        content: ""; position: absolute; inset: 0; border-radius: inherit; border: 2px solid var(--accent); opacity: 0; pointer-events: none;
    }
    html.accueil-3d:not(.a11y-animations) .rue-entree:not(.rue-posee) .hero-cta .btn-primary:not(.est-parti)::after { animation: mv-anneau 800ms var(--mv-entree) 1150ms 1 backwards; }
    html.accueil-3d:not(.a11y-animations) .hero-cta .est-parti::after { animation: mv-parti 360ms var(--mv-entree) 1 backwards; }
    html:not(.a11y-animations) .hero-cta .hero-visite[aria-busy="true"] { animation: mv-attente 700ms ease-in-out infinite alternate; }
    html.accueil-3d:not(.a11y-animations) footer.palier.titre-joue:not(.titre-pose) .palier-actions .btn::after { animation: mv-anneau 800ms var(--mv-entree) 700ms 1 backwards; }
    @media (max-width: 720px) { html.accueil-3d:not(.a11y-animations) .rue-entree:not(.rue-posee) .hero-cta .btn-primary:not(.est-parti)::after { animation-delay: 950ms; } }
    html:not(.a11y-animations) .btn:active, html:not(.a11y-animations) .menu-toggle:active, html:not(.a11y-animations) .a11y-bouton:active { transform: scale(0.97); transition: background var(--mv-t-appui) linear, color var(--mv-t-appui) linear, box-shadow 0.35s var(--ease), transform var(--mv-t-appui) var(--mv-appui); }
    html:not(.a11y-animations) .nav-menu a.nav-cta { transition: color 0.2s var(--ease), background var(--mv-court) var(--ease), transform var(--mv-t-relache) var(--mv-appui); }
    html:not(.a11y-animations) .nav-menu a.nav-cta:active { transform: scale(0.97); transition-duration: var(--mv-t-appui); }
    html:not(.a11y-animations) .retour-ascenseur:active { transform: scale(0.96); transition-duration: 0.3s, var(--mv-t-appui), 0.3s, 0.3s, 0.3s, 0.3s, 0.3s, 0.3s; }
    html:not(.a11y-animations) .retour-ascenseur::before { transition: box-shadow 120ms var(--mv-appui); }
    html:not(.a11y-animations) .nav-menu a:not(.nav-cta)::after { transition: transform 140ms var(--mv-sortie); }
    @media (hover: hover) and (pointer: fine) { html:not(.a11y-animations) .nav-menu a:not(.nav-cta):hover::after { transition: transform var(--mv-court) var(--mv-entree); } }
    html:not(.a11y-animations) .nav-menu.active li { animation: mv-cascade 200ms var(--mv-entree) calc(var(--rg, 0) * 35ms) 1 backwards; }
    .nav-menu li:nth-child(2) { --rg: 1; }
    .nav-menu li:nth-child(3) { --rg: 2; }
    .nav-menu li:nth-child(4) { --rg: 3; }
    html[data-salle]:not(.a11y-animations):not([data-salle="imprimerie"]) main .text-link, html[data-salle]:not(.a11y-animations):not([data-salle="imprimerie"]) main .link-more { transition: text-decoration-color var(--mv-t-survol) var(--mv-appui), color 0.2s var(--ease); }
    html[data-salle]:not(.a11y-animations):not([data-salle="imprimerie"]) main .link-more::after { transition: transform var(--mv-t-survol) var(--mv-appui); }
}
/* ailleurs, rien n'attend (la section 21 ne remet pas le délai à zéro) */
@media print, (prefers-reduced-motion: reduce) { .mot > span, .lettre { animation: none !important; transform: none !important; opacity: 1 !important; } }
html.a11y-animations .mot > span, html.a11y-animations .lettre { animation: none; transform: none; opacity: 1; }
.retour-ascenseur:active::before { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 45%, transparent); }
