/* ==========================================================================
   SahelForge — feuille de style unique
   --------------------------------------------------------------------------
   Parti pris « Produit » (octobre 2026), qui remplace « Ardoise » : celui
   d'un éditeur de logiciels. Le site est clair de haut en bas, seul le pied
   reste sur l'ardoise ; l'accueil montre d'emblée une application réelle,
   parce que c'est ce qui tourne déjà qui convainc un dirigeant.

   Trois règles tiennent l'ensemble :
     1. La couleur ne structure pas — les surfaces, les filets et les blancs
        le font. Le bleu d'action porte ce qui se clique, bouton principal
        compris ; le laiton est l'identité, jamais du texte sur fond clair.
     2. Space Grotesk ne sert qu'aux titres. Employé pour du texte courant,
        il fatigue à l'écran.
     3. Le relief vient de deux ombres jetons (--ombre-1, --ombre-2), jamais
        d'une ombre écrite à la main. En thème sombre, où une ombre ne se
        voit pas, ces jetons deviennent des filets et la surface s'éclaircit
        d'un cran.

   Aucun style en ligne (attribut « style= ») n'est possible dans les vues :
   la politique de sécurité déclarée dans .htaccess est « style-src 'self' »,
   sans 'unsafe-inline'. Tout habillage passe donc par ce fichier.
   ========================================================================== */

/* --- Polices ------------------------------------------------------------
   Hébergées localement, dans www/assets/polices/. Deux raisons : la
   politique de sécurité interdit tout hôte externe, et un site vitrine n'a
   pas à signaler chacune de ses visites à un tiers.

   Fichiers variables : un seul par famille couvre les graisses 400 à 700, au
   lieu de quatre fichiers statiques. Le « unicode-range » fait le reste — un
   navigateur affichant du français ne télécharge jamais le latin étendu.
   « font-display: swap » affiche immédiatement la police de repli : sur une
   connexion lente, le texte est lisible avant que la police n'arrive. */

@font-face {
    font-family: 'Inter var';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/assets/polices/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: 'Inter var';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/assets/polices/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: 'Space Grotesk var';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/assets/polices/space-grotesk-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: 'Space Grotesk var';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/assets/polices/space-grotesk-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;
}

/* --- Jetons -------------------------------------------------------------- */

:root {
    color-scheme: light;

    /* Châssis repris de GoyPro, accent gardé de SahelForge.
       ----------------------------------------------------------------
       Le portail et l'application doivent se lire comme le même système :
       un prospect qui passe du site à une démonstration ne doit pas avoir
       l'impression de changer d'éditeur. Les gris, les fonds et la couleur
       d'action viennent donc de goypro-app/src/main/webapp/resources/css/
       (app.css, jetons « ardoise » et « action »).

         ardoise-900     #0F172A   titres, fond sombre
         ardoise-700     #334155   texte secondaire
         ardoise-300     #CBD5E1   filets
         ardoise-100     #F1F5F9   bande creuse
         action          #1264C8   LIENS, boutons d'action
         action-survol   #0F58AD   survol
         action-douce    #E8F0FC   état choisi, sélection
         fond-page       #F6F8FB   fond clair

       Ce qui NE vient pas de GoyPro, et ne doit pas en venir : l'accent.
       GoyPro emploie l'ambre #F59E0B pour ses alertes et ses retards —
       c'est une couleur sémantique chez lui, une identité chez nous. Le
       laiton d'Agadez reste donc l'accent du portail, et le logo n'est pas
       recoloré : la planche de marque continue de gouverner la marque,
       GoyPro gouverne le châssis.

       Le laiton ne porte JAMAIS de texte sur fond clair : 2,2:1, illisible.
       Le bleu d'action en porte, à 5,4:1. D'où deux jetons distincts —
       --lien colore le texte cliquable, --accent remplit les boutons et
       trace les filets d'accent. Les confondre remettrait du laiton sur du
       texte. En thème sombre les deux étaient auparavant confondus sur la
       braise ; ils ne le sont plus. */

    --fond: #F6F8FB;
    --fond-creux: #F1F5F9;
    --surface: #ffffff;
    --texte: #0F172A;
    --texte-doux: #334155;
    /* L'ardoise-500 de GoyPro (#64748B) tombe à 4,3:1 sur la bande creuse.
       Assombrie jusqu'à passer 4,5:1 : ce jeton porte des dates et des
       mentions de durée, du texte menu, celui qui souffre le plus. */
    --texte-tenu: #5B6B80;
    --filet: #CBD5E1;
    /* Assombri de la même façon, pour garder au filet fort le poids qu'il
       avait dans la palette chaude — la structure du site tient sur ses
       filets, un filet plus pâle, c'est une page qui se délite. */
    --filet-fort: #AEB9C7;

    --lien: #1264C8;
    --lien-fort: #0F58AD;
    --accent: #d99b2b;
    --accent-fort: #bf831d;
    --selection: #E8F0FC;
    --sur-accent: #0F172A;

    /* Le bouton principal, au bleu d'action de GoyPro : sur l'application
       comme ici, c'est la couleur de ce qu'on déclenche. Égal à --lien en
       valeur, distinct en rôle — un bouton n'est pas un lien de texte, et
       --sur-action change avec le thème, comme --sur-accent : le bleu clair
       du thème sombre ne tient pas un texte blanc. */
    --action: #1264C8;
    --action-fort: #0F58AD;
    --sur-action: #ffffff;

    --ombre-1: 0 1px 2px rgb(15 23 42 / 0.06), 0 1px 3px rgb(15 23 42 / 0.08);
    --ombre-2: 0 4px 12px rgb(15 23 42 / 0.08), 0 12px 32px rgb(15 23 42 / 0.10);

    /* Sémantiques, distinctes de l'accent : un état n'est pas une identité.
       Elles changent avec le thème, faute de quoi le rouge d'une erreur de
       formulaire tombe à 2,2:1 sur fond sombre — ce qui était le cas. */
    --erreur: #B91C1C;
    --succes: #047857;

    /* Coloris du logo, repris à l'identique de la planche. Le dessin est
       inliné et prend ces couleurs : cela reproduit exactement les deux
       versions officielles — on a vérifié que la version « fond sombre » du
       kit est, à l'octet près, la permutation de couleurs de la version
       claire. La marque n'est donc jamais recolorée arbitrairement. */
    --logo-corps: #0e2e4a;
    --logo-accent: #d99b2b;
    --logo-tenu: #1b4b73;

    /* Space Grotesk pour les titres, le logotype et les chiffres, comme
       l'impose la planche. C'est la police du logotype lui-même, vectorisée
       dans le SVG : un serif à côté jurerait avec la marque. */
    --titre: 'Space Grotesk var', ui-sans-serif, system-ui, 'Segoe UI',
             Roboto, 'Helvetica Neue', Arial, sans-serif;
    --sans: 'Inter var', ui-sans-serif, system-ui, -apple-system, 'Segoe UI',
            Roboto, 'Helvetica Neue', Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* Échelle fluide, sans palier à déclarer : la taille suit la largeur de
       la fenêtre. Les titres ont une amplitude bien plus large que le texte
       courant, dont la taille de lecture ne doit presque pas bouger. */
    --t-xs: 0.75rem;
    --t-s: 0.875rem;
    --t-base: clamp(1rem, 0.98rem + 0.1vw, 1.0625rem);
    --t-m: clamp(1.125rem, 1.07rem + 0.28vw, 1.3125rem);
    /* Taille du corps d'un article, distincte de --t-base : un texte
       long se lit plus gros qu'un libellé d'interface, mais moins gros
       qu'un chapeau. Couplée à --mesure, elle vise 60 à 70 signes par
       ligne — au-delà l'œil se perd, en deçà il saute trop souvent. */
    --t-lecture: clamp(1.0625rem, 1rem + 0.28vw, 1.1875rem);
    --t-l: clamp(1.5rem, 1.32rem + 0.9vw, 2.125rem);
    --t-xl: clamp(2rem, 1.6rem + 1.9vw, 3.25rem);
    --t-xxl: clamp(2.5rem, 1.75rem + 3.4vw, 4.75rem);
    /* Le titre de l'accroche, seul de sa taille sur le site. */
    --t-hero: clamp(2.75rem, 1.8rem + 4.2vw, 5.25rem);

    --e-1: 0.375rem;
    --e-2: 0.75rem;
    --e-3: 1.25rem;
    --e-4: 2rem;
    --e-5: 3.25rem;
    --e-6: 5.5rem;
    --e-7: 8rem;

    /* Deux rayons : le petit pour ce qui se manipule (bouton, champ), le
       grand pour ce qui contient (carte, capture, panneau). Le registre est
       celui des interfaces applicatives, celui de GoyPro. */
    --rayon: 8px;
    --rayon-carte: 14px;
    --largeur: 74rem;
    --mesure: 40rem;

    /* Mouvement. Trois durées seulement, pour que le site ait un tempo et
       non une collection d'effets. La courbe est une décélération : le
       mouvement part vite et s'arrête doucement, ce qui se lit comme un
       objet qui se pose. Une courbe symétrique (ease) donne au contraire
       l'impression d'un objet qui flotte.

       Les distances sont volontairement courtes — 10 px, jamais plus. Un
       grand déplacement attire l'œil sur l'animation ; un petit le ramène
       sur le contenu, ce qui est le but dans un registre éditorial. */
    --duree-rapide: 0.15s;
    --duree: 0.32s;
    --duree-lente: 0.55s;
    --courbe: cubic-bezier(0.22, 1, 0.36, 1);
    --montee: 10px;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="clair"]) {
        color-scheme: dark;

        --fond: #131C30;
        --fond-creux: #0F172A;
        --surface: #1B2642;
        --texte: #E2E8F0;
        --texte-doux: #94A3B8;
        --texte-tenu: #7D8FA6;
        --filet: #2B3A52;
        --filet-fort: #3A4B66;

        /* Le lien cesse d'être la braise : sur l'ardoise de GoyPro, c'est
           son bleu clair qui porte le texte cliquable, et l'accent redevient
           ce qu'il est en thème clair — un remplissage, pas un texte. */
        --lien: #7AB3F5;
        --lien-fort: #A5CBF7;
        --accent: #f2c14e;
        --accent-fort: #f7d585;
        --selection: #1E293B;
        --sur-accent: #0F172A;

        --action: #7AB3F5;
        --action-fort: #A5CBF7;
        --sur-action: #0F172A;
        --ombre-1: 0 0 0 1px var(--filet);
        --ombre-2: 0 0 0 1px var(--filet-fort);

        --erreur: #F87171;
        --succes: #34D399;

        --logo-corps: #f5f4f0;
        --logo-accent: #f2c14e;
        --logo-tenu: #9fb6c9;
    }
}

:root[data-theme="sombre"] {
    color-scheme: dark;

    --fond: #131C30;
    --fond-creux: #0F172A;
    --surface: #1B2642;
    --texte: #E2E8F0;
    --texte-doux: #94A3B8;
    --texte-tenu: #7D8FA6;
    --filet: #2B3A52;
    --filet-fort: #3A4B66;

    /* Le lien cesse d'être la braise : sur l'ardoise de GoyPro, c'est
       son bleu clair qui porte le texte cliquable, et l'accent redevient
       ce qu'il est en thème clair — un remplissage, pas un texte. */
    --lien: #7AB3F5;
    --lien-fort: #A5CBF7;
    --accent: #f2c14e;
    --accent-fort: #f7d585;
    --selection: #1E293B;
    --sur-accent: #0F172A;

    --action: #7AB3F5;
    --action-fort: #A5CBF7;
    --sur-action: #0F172A;
    --ombre-1: 0 0 0 1px var(--filet);
    --ombre-2: 0 0 0 1px var(--filet-fort);

    --erreur: #F87171;
    --succes: #34D399;

    --logo-corps: #f5f4f0;
    --logo-accent: #f2c14e;
    --logo-tenu: #9fb6c9;
}

/* --- Remise à zéro ------------------------------------------------------- */

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

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

/* Le respect de « mouvement réduit » n'est pas un supplément d'accessibilité :
   chez une personne sujette aux vertiges vestibulaires, une animation de
   défilement provoque un malaise réel. Tout ce qui bouge dans cette feuille
   est donc soit déclaré à l'intérieur d'un « no-preference », soit neutralisé
   ici.

   Le délai compte autant que la durée : une animation ramenée à 0,01 ms mais
   gardant ses 500 ms de retard laisserait l'élément invisible une demi-seconde
   — le défaut serait pire que l'animation. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        transition-delay: 0s !important;
    }

    /* Les transitions de page se font alors sans fondu, ce qui reste une
       navigation correcte : la page suivante s'affiche, simplement d'un coup. */
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) { animation: none !important; }
}

body {
    background: var(--fond);
    color: var(--texte);
    font-family: var(--sans);
    font-size: var(--t-base);
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
    font-synthesis-weight: none;
}

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

h1, h2, h3 {
    font-family: var(--titre);
    font-weight: 600;
    line-height: 1.1;
    /* Un grotesque à grande taille se resserre : à approche normale, les
       lettres d'un titre se lisent une à une au lieu d'un seul bloc. */
    letter-spacing: -0.03em;
    text-wrap: balance;
}

h1 { font-size: var(--t-xxl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-l); }

p, li { text-wrap: pretty; }

a {
    color: var(--lien);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
    text-decoration-color: color-mix(in srgb, var(--lien) 40%, transparent);
    transition: text-decoration-color var(--duree-rapide) var(--courbe), color var(--duree-rapide) var(--courbe);
}

a:hover { color: var(--lien-fort); text-decoration-color: currentcolor; }

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

::selection { background: var(--selection); color: var(--texte); }

/* --- Aides --------------------------------------------------------------- */

.conteneur {
    width: 100%;
    max-width: var(--largeur);
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 5vw, 3.5rem);
}

.mesure { max-width: var(--mesure); }

.visuellement-cache {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.lien-evitement {
    position: absolute;
    left: var(--e-2);
    top: -4rem;
    z-index: 100;
    background: var(--accent);
    color: var(--sur-accent);
    padding: var(--e-2) var(--e-3);
    border-radius: var(--rayon);
    transition: top var(--duree-rapide) var(--courbe);
}
.lien-evitement:focus { top: var(--e-2); color: var(--sur-accent); }

/* --- Libellés ------------------------------------------------------------
   La petite capitale espacée : elle appartient au registre imprimé, alors
   que la chasse fixe évoque le terminal — juste pour un studio technique, à
   contretemps pour une offre qui s'adresse à des dirigeants. En gris tenu et
   non en bleu : un libellé n'est pas cliquable, et le bleu est réservé à ce
   qui l'est. */

.surtitre {
    display: flex;
    align-items: center;
    gap: var(--e-2);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--texte-tenu);
    margin-bottom: var(--e-3);
}

/* Le losange du symbole, en laiton, devant le libellé de l'accroche : un
   pictogramme et non du texte, donc l'accent y est admis. */
.surtitre--losange::before {
    content: "";
    flex: none;
    width: 0.55rem;
    height: 0.55rem;
    background: var(--accent);
    transform: rotate(45deg);
}

.numero {
    font-variant-numeric: tabular-nums;
    color: var(--texte-tenu);
    font-weight: 500;
}

/* --- En-tête ------------------------------------------------------------- */

.entete {
    position: sticky;
    top: 0;
    z-index: 50;
    /* Opaque d'abord : un en-tête translucide sans flou laisserait le texte
       de la page se lire au travers. */
    background: var(--fond);
    border-bottom: 1px solid var(--filet);
}

@supports (backdrop-filter: blur(1px)) {
    .entete {
        background: color-mix(in srgb, var(--fond) 85%, transparent);
        backdrop-filter: blur(12px);
    }
}

.entete__interieur {
    display: flex;
    align-items: center;
    gap: var(--e-3);
    min-height: 4.5rem;
}

.logo {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    margin-inline-end: auto;
}

/* Le SVG est inliné et prend ses couleurs de la feuille de style : les deux
   coloris officiels de la planche, selon le thème. La hauteur est fixée ici,
   la largeur suit le viewBox — le dessin n'est donc jamais étiré, ce que la
   planche interdit. */
.logo__svg { display: block; width: auto; }

.logo__corps { fill: var(--logo-corps); }
.logo__accent { fill: var(--logo-accent); }
.logo__tenu { fill: var(--logo-tenu); }
.logo__anneau { stroke: var(--logo-accent); }

/* 34 px : au-dessus du minimum de 32 px fixé par la planche pour le logo
   sans slogan. En dessous, il faudrait passer au symbole seul. */
.logo--entete .logo__svg { height: 34px; }

/* Le pied a la place du logo complet, slogan compris. */
.logo--pied .logo__svg { height: 58px; }

/* Zone de protection : un vide égal au diamètre de l'anneau tout autour.
   Sur l'anneau du logo, ce diamètre vaut environ 27 % de la hauteur totale. */
.logo--entete { padding-inline-end: 0.27em; font-size: 34px; }
.logo--pied { margin-bottom: var(--e-3); }

.navigation__liste {
    display: flex;
    align-items: center;
    gap: var(--e-4);
    list-style: none;
    padding: 0;
}

.navigation a {
    color: var(--texte-doux);
    text-decoration: none;
    font-size: var(--t-s);
    font-weight: 500;
    position: relative;
    padding-block: 0.35rem;
}

.navigation a:hover { color: var(--texte); }

/* Le filet sous le lien courant, plutôt qu'un changement de couleur : il
   marque la position sans peser.

   Le même filet se déroule au survol, depuis la gauche — c'est-à-dire dans le
   sens de la lecture. Déroulé depuis le centre, il se lirait comme une
   décoration ; depuis le bord, comme un soulignement qu'on trace. */
.navigation a::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: -0.1rem;
    height: 1px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--duree) var(--courbe);
}
.navigation a:hover::after,
.navigation a:focus-visible::after { transform: scaleX(1); }

.navigation a[aria-current="page"] { color: var(--texte); }
.navigation a[aria-current="page"]::after { transform: scaleX(1); }

/* « .navigation a » l'emporte en spécificité sur « .bouton » : sans ces
   règles, le bouton d'appel à l'action hérite de la couleur atténuée des
   liens de menu, texte gris sur fond coloré. */
.navigation a.bouton,
.navigation a.bouton:hover { color: var(--sur-action); }
.navigation a.bouton::after { display: none; }

.entete__bascule { display: none; }

.bascule-theme {
    background: none;
    border: 1px solid var(--filet);
    border-radius: var(--rayon);
    color: var(--texte-doux);
    cursor: pointer;
    width: 2.25rem; height: 2.25rem;
    display: grid; place-items: center;
    font-size: 0.9rem;
    flex: none;
    transition: border-color var(--duree-rapide) var(--courbe),
                color var(--duree-rapide) var(--courbe),
                transform var(--duree-rapide) var(--courbe);
}
.bascule-theme:hover { color: var(--texte); border-color: var(--filet-fort); }

/* Le pictogramme est un disque à moitié plein : le faire tourner d'un
   demi-tour illustre exactement ce que le bouton fait — passer d'une moitié
   à l'autre. L'animation dit la fonction, elle ne l'orne pas. */
.bascule-theme span { transition: transform var(--duree-lente) var(--courbe); }
.bascule-theme:hover span { transform: rotate(180deg); }
.bascule-theme:active { transform: scale(0.94); }

/* --- Boutons ------------------------------------------------------------- */

.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    min-height: 44px;
    padding: 0.8rem 1.5rem;
    background: var(--action);
    color: var(--sur-action);
    border: 1px solid var(--action);
    border-radius: var(--rayon);
    font: inherit;
    font-size: var(--t-s);
    font-weight: 600;
    letter-spacing: 0.005em;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--duree-rapide) var(--courbe),
                border-color var(--duree-rapide) var(--courbe),
                color var(--duree-rapide) var(--courbe),
                transform var(--duree-rapide) var(--courbe);
}

.bouton:hover {
    background: var(--action-fort);
    border-color: var(--action-fort);
    color: var(--sur-action);
    /* Un pixel, pas trois : au-delà de deux pixels, un bouton qui monte se
       lit comme un défaut d'alignement plutôt que comme un relief. */
    transform: translateY(-1px);
}

/* L'enfoncement au clic est le seul retour immédiat dont dispose un bouton
   qui déclenche une navigation : le temps que la page suivante arrive, le
   visiteur sait déjà que son geste a porté. */
.bouton:active { transform: translateY(1px); }

.bouton--compact { padding: 0.5rem 1rem; }

.bouton--secondaire {
    background: var(--surface);
    color: var(--texte);
    border-color: var(--filet-fort);
}
.bouton--secondaire:hover {
    background: var(--surface);
    color: var(--lien);
    border-color: var(--lien);
}

/* Lien-flèche : la sortie discrète d'une carte ou d'une section. */
.lien-fleche {
    display: inline-flex;
    align-items: center;
    gap: 0.45em;
    font-size: var(--t-s);
    font-weight: 600;
    text-decoration: none;
    color: var(--lien);
}
.lien-fleche::after {
    content: "→";
    transition: transform var(--duree-rapide) var(--courbe);
}
a:hover > .lien-fleche::after,
.lien-fleche:hover::after { transform: translateX(0.2em); }

/* --- Sections ------------------------------------------------------------ */

.section { padding-block: var(--e-6); }

/* Un filet plutôt qu'un aplat : la page reste d'une seule teinte, et la
   structure se lit quand même. */
.section--filet { border-top: 1px solid var(--filet); }
.section--creux { background: var(--fond-creux); border-block: 1px solid var(--filet); }

.section__entete { max-width: 44rem; margin-bottom: var(--e-5); }

/* La sortie d'une section vient après la liste qu'elle prolonge, détachée
   d'elle mais dans le même souffle. */
.section__sortie { margin-top: var(--e-4); }
/* « :not(.surtitre) » : sans lui, cette règle, plus spécifique que
   « .surtitre », donnait au libellé la taille et la marge d'un chapeau. */
.section__entete p:not(.surtitre) {
    color: var(--texte-doux);
    font-size: var(--t-m);
    margin-top: var(--e-3);
    max-width: var(--mesure);
}

/* Une section sur la surface pleine, entre deux filets : elle se détache
   du fond de page sans recourir à un aplat de couleur. */
.section--surface { background: var(--surface); border-block: 1px solid var(--filet); }

/* --- Bande à l'encre -----------------------------------------------------
   Le pied de page, seul sur l'ardoise la plus sombre, dans les deux thèmes ;
   le reste du site est clair depuis le parti pris « Produit ». Les jetons y sont
   redéfinis plutôt que les couleurs écrites en dur : tout composant posé
   dans la bande — bouton, lien-flèche, logo — prend ainsi ses
   couleurs de fond sombre sans règle de plus. Les valeurs sont celles du
   thème sombre ; le laiton y devient braise, comme le veut la planche sur
   fond sombre. */

.bande-encre {
    --fond: #0F172A;
    --surface: #16203A;
    --fond-creux: #16203A;
    --texte: #F8FAFC;
    --texte-doux: #CBD5E1;
    --texte-tenu: #94A3B8;
    --filet: #2B3A52;
    --filet-fort: #3A4B66;
    --lien: #7AB3F5;
    --lien-fort: #A5CBF7;
    --accent: #f2c14e;
    --accent-fort: #f7d585;
    --sur-accent: #0F172A;
    --action: #7AB3F5;
    --action-fort: #A5CBF7;
    --sur-action: #0F172A;
    --ombre-1: 0 0 0 1px var(--filet);
    --ombre-2: 0 0 0 1px var(--filet-fort);
    --logo-corps: #f5f4f0;
    --logo-accent: #f2c14e;
    --logo-tenu: #9fb6c9;

    background: var(--fond);
    color: var(--texte);
}

/* --- Bandeau de page -----------------------------------------------------
   L'ouverture des pages intérieures : fil, libellé, titre et chapeau sur le
   fond creux, fermé par un filet. Le corps de la page commence sur le fond
   de page, juste dessous : un cran de teinte suffit à séparer les deux. */

.bandeau {
    padding-block: clamp(3rem, 7vw, 5.5rem);
    background: var(--fond-creux);
    border-bottom: 1px solid var(--filet);
}

.bandeau .section__entete,
.bandeau .article__entete,
.bandeau .statistiques__entete {
    max-width: 48rem;
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: 0;
}

.bandeau h1 { font-weight: 600; letter-spacing: -0.025em; }

/* Le bandeau a déjà ouvert la page : le corps n'a pas besoin du grand
   blanc d'une section qui en suivrait une autre. */
.bandeau + .section { padding-top: var(--e-5); }

/* --- Accroche ------------------------------------------------------------
   Le texte à gauche, une application réelle à droite, dans un cadre de
   navigateur : le dirigeant voit ce que nous livrons avant d'avoir lu ce
   que nous promettons. Les engagements suivent, en tuiles. */

.accroche { padding-top: clamp(3rem, 8vw, 6rem); }

.accroche__grille {
    display: grid;
    gap: var(--e-5);
    align-items: center;
    padding-bottom: clamp(3rem, 7vw, 5.5rem);
}
@media (min-width: 56.25rem) {
    .accroche__grille { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
}

.accroche__texte { max-width: 56rem; }

/* Le libellé en pastille : il se détache du titre sans prendre de couleur.
   Même règle à l'accroche et au bandeau des pages intérieures. */
.accroche .surtitre,
.bandeau .surtitre {
    display: inline-flex;
    padding: 0.35rem 0.8rem;
    background: var(--fond-creux);
    border: 1px solid var(--filet);
    border-radius: 999px;
}

.cadre-navigateur {
    margin: 0;
    background: var(--surface);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-2);
    overflow: hidden;
}

/* Les trois points d'une fenêtre, dessinés plutôt qu'ajoutés au balisage. */
.cadre-navigateur__barre {
    display: block;
    height: 2rem;
    background:
        radial-gradient(circle, var(--filet-fort) 0 4px, transparent 4.5px) 0.9rem 50% / 12px 12px no-repeat,
        radial-gradient(circle, var(--filet-fort) 0 4px, transparent 4.5px) 1.65rem 50% / 12px 12px no-repeat,
        radial-gradient(circle, var(--filet-fort) 0 4px, transparent 4.5px) 2.4rem 50% / 12px 12px no-repeat,
        var(--fond-creux);
    border-bottom: 1px solid var(--filet);
}

/* La capture est plus haute que large : on en montre le haut, là où sont
   le menu et les chiffres, plutôt que de la réduire jusqu'à l'illisible. */
.cadre-navigateur img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    object-position: top left;
}

.accroche h1 {
    font-size: var(--t-hero);
    line-height: 1.02;
    max-width: 16ch;
    margin-bottom: var(--e-4);
}

.accroche__resume {
    font-size: var(--t-m);
    line-height: 1.55;
    color: var(--texte-doux);
    max-width: 40rem;
    margin-bottom: var(--e-5);
}

.accroche__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e-3);
}

.accroche__preuves {
    display: grid;
    gap: var(--e-3);
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}

.preuve {
    padding: var(--e-4);
    background: var(--surface);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
}

/* Un pictogramme, donc le laiton y est admis : il ne porte aucun texte. */
.preuve__icone { color: var(--accent); margin-bottom: var(--e-2); }

.preuve strong {
    display: block;
    font-family: var(--titre);
    font-weight: 600;
    font-size: var(--t-m);
    letter-spacing: -0.01em;
    margin-bottom: 0.15rem;
}
.preuve span { color: var(--texte-tenu); font-size: var(--t-s); line-height: 1.5; display: block; }

/* --- Réalisation en vedette ----------------------------------------------
   La première réalisation, en grand, avec ses points saillants dans un
   panneau. Une seule : deux vedettes, et aucune ne le serait plus. */

.vedette {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    margin-bottom: var(--e-4);
    background: var(--surface);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: border-color var(--duree) var(--courbe),
                box-shadow var(--duree) var(--courbe),
                translate var(--duree-rapide) var(--courbe);
}

/* Deux pixels de montée et l'ombre qui s'élargit : la carte se soulève,
   comme partout ailleurs sur le site. */
a.vedette:hover {
    color: inherit;
    border-color: var(--filet-fort);
    box-shadow: var(--ombre-2);
    /* « translate » et non « transform » : la révélation au défilement tient
       « transform » jusqu'au bout de son animation, ce qui annulait la
       montée de toute carte révélée. Les deux propriétés se composent. */
    translate: 0 -2px;
}
a.vedette:hover .vedette__titre { color: var(--lien); }

.vedette__corps {
    display: flex;
    flex-direction: column;
    gap: var(--e-3);
    padding: var(--e-5);
}

.vedette__titre {
    font-family: var(--titre);
    font-size: var(--t-l);
    font-weight: 600;
    line-height: 1.12;
    letter-spacing: -0.015em;
    transition: color var(--duree-rapide) var(--courbe);
}

.vedette__resume { color: var(--texte-doux); font-size: var(--t-m); line-height: 1.6; }

.vedette__panneau {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--e-5);
    background: var(--fond-creux);
    border-inline-start: 1px solid var(--filet);
    list-style: none;
}

.vedette__point {
    display: flex;
    align-items: baseline;
    gap: var(--e-2);
    padding-block: var(--e-2);
    border-bottom: 1px solid var(--filet);
    font-size: var(--t-s);
    font-weight: 600;
}

/* Le losange de la marque comme puce : pictogramme, donc laiton admis. */
.vedette__point::before {
    content: "";
    flex: none;
    width: 0.45rem;
    height: 0.45rem;
    background: var(--accent);
    transform: rotate(45deg) translateY(-0.1em);
}

.vedette__pile {
    padding-top: var(--e-2);
    font-family: var(--mono);
    font-size: var(--t-xs);
    color: var(--texte-doux);
}

/* La carte encadrée : les réalisations qui suivent la vedette. Toute carte
   a désormais le cadre de la vedette ; celle-ci garde seulement un peu plus
   d'air. Le double sélecteur l'emporte sur « .carte », déclarée plus bas. */
.carte.carte--encadree { gap: var(--e-3); }

/* --- Colonnes ------------------------------------------------------------
   Les trois activités en tuiles, la première sur deux rangs : c'est le
   développement sur mesure, le cœur de l'offre, et la grille le dit sans un
   mot de plus. Le numéro est un repère d'ordre, pas une information : il est
   masqué aux lecteurs d'écran et peut donc rester discret. */

.colonnes {
    display: grid;
    gap: var(--e-3);
}
@media (min-width: 56.25rem) {
    .colonnes { grid-template-columns: 1.4fr 1fr; }
    .colonnes .colonne:first-child { grid-row: span 2; }
    .colonnes .colonne:first-child .colonne__titre { font-size: var(--t-l); }
}

.colonne {
    display: flex;
    flex-direction: column;
    gap: var(--e-3);
    padding: var(--e-4);
    background: var(--fond);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
    text-decoration: none;
    color: inherit;
}
.colonne:hover { color: inherit; }
.colonne:hover .colonne__titre { color: var(--lien); }

.colonne__numero {
    font-family: var(--titre);
    font-size: var(--t-s);
    font-weight: 600;
    line-height: 1;
    color: var(--texte-tenu);
}

.colonne__titre {
    font-family: var(--titre);
    font-size: var(--t-m);
    font-weight: 600;
    line-height: 1.2;
    transition: color var(--duree-rapide) var(--courbe);
}

.colonne__texte { color: var(--texte-doux); font-size: var(--t-s); line-height: 1.65; }
.colonne .lien-fleche { margin-top: auto; }

/* --- Rubriques (liste éditoriale numérotée) ------------------------------
   Employée pour les services et le blog. Une ligne pleine largeur par
   entrée, en carte : elles se lisent dans l'ordre, et cet ordre est un choix
   éditorial, mais chacune se survole comme n'importe quelle carte du site. */

.rubriques { display: grid; gap: var(--e-3); }

.rubrique {
    display: grid;
    grid-template-columns: 5.5rem minmax(0, 26rem) minmax(0, 1fr) auto;
    gap: var(--e-4);
    align-items: start;
    padding: var(--e-4);
    background: var(--surface);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
    text-decoration: none;
    color: inherit;
    transition: border-color var(--duree) var(--courbe),
                box-shadow var(--duree) var(--courbe),
                translate var(--duree-rapide) var(--courbe);
}

.rubrique:hover {
    color: inherit;
    border-color: var(--filet-fort);
    box-shadow: var(--ombre-2);
    translate: 0 -2px;
}
.rubrique:hover .rubrique__titre { color: var(--lien); }

/* La date ou le numéro en pastille, comme les libellés de bandeau. */
.rubrique__numero {
    justify-self: start;
    padding: 0.2rem 0.6rem;
    background: var(--fond-creux);
    border-radius: 999px;
    font-size: var(--t-xs);
    font-weight: 600;
    color: var(--texte-tenu);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.rubrique__titre {
    font-family: var(--titre);
    font-size: var(--t-l);
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: -0.015em;
    transition: color var(--duree-rapide) var(--courbe);
}

.rubrique__texte { color: var(--texte-doux); font-size: var(--t-s); line-height: 1.65; }

.rubrique__fleche {
    /* Pictogramme, non du texte : le laiton y est admis, le sens est déjà
       porté par le titre voisin. */
    color: var(--accent);
    font-size: var(--t-m);
    padding-top: 0.15rem;
    transition: transform var(--duree-rapide) var(--courbe);
}
.rubrique:hover .rubrique__fleche { transform: translateX(0.25em); }

/* --- Séries du blog ------------------------------------------------------
   Deux listes de rubriques dans une même page, chacune sous son titre. Le
   sous-titre reprend l'en-tête de section pour rester dans la même mesure et
   la même graisse, avec un dessous resserré : entre un h2 et la liste qu'il
   annonce, l'écart d'une vraie section ferait lire deux blocs séparés au lieu
   d'un titre et son contenu. */

.serie + .serie { margin-top: var(--e-6); }
.serie .section__entete { margin-bottom: var(--e-4); }

/* --- Grilles et cartes --------------------------------------------------- */

.grille {
    display: grid;
    gap: var(--e-3);
    /* « auto-fill » : une carte seule garde la largeur d'une colonne au lieu
       de s'étirer sur toute la ligne. */
    grid-template-columns: repeat(auto-fill, minmax(min(18rem, 100%), 1fr));
}

.grille--deux { grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr)); }

.carte {
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
    padding: var(--e-4);
    background: var(--surface);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
    transition: border-color var(--duree) var(--courbe),
                box-shadow var(--duree) var(--courbe),
                translate var(--duree-rapide) var(--courbe);
}

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

/* La carte se soulève de deux pixels et son ombre s'élargit : deux pixels
   suffisent à ce que la carte survolée se détache de ses voisines. */
a.carte:hover {
    color: inherit;
    border-color: var(--filet-fort);
    box-shadow: var(--ombre-2);
    translate: 0 -2px;
}
a.carte:hover .carte__titre { color: var(--lien); }

.carte__titre,
.carte h2, .carte h3 {
    font-family: var(--titre);
    font-size: var(--t-m);
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    transition: color var(--duree-rapide) var(--courbe);
}

.carte p { color: var(--texte-doux); font-size: var(--t-s); line-height: 1.65; }

.carte__lien { margin-top: auto; padding-top: var(--e-2); }

.carte__meta {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--texte-tenu);
}

.etiquettes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--e-1);
    list-style: none;
    padding: 0;
    margin-top: var(--e-1);
}

.etiquette {
    font-size: var(--t-xs);
    padding: 0.1rem 0.55rem;
    border: 1px solid var(--filet);
    border-radius: 999px;
    color: var(--texte-doux);
    transition: border-color var(--duree-rapide) var(--courbe),
                color var(--duree-rapide) var(--courbe);
}
.etiquette:hover { border-color: var(--filet-fort); color: var(--texte); }

.etiquettes--espacees { margin-top: var(--e-4); }

/* --- Barre d'action ------------------------------------------------------
   Fixée en bas de l'écran sur mobile seulement, où appuyer vaut mieux
   qu'ouvrir un menu. Sur ordinateur, l'en-tête porte déjà le bouton. Sous
   l'en-tête dans l'empilement : le menu déplié passe par-dessus elle. */

.barre-action { display: none; }

/* Le vert est celui de WhatsApp, et il est délibérément hors de la palette
   de marque : c'est un logo tiers, reconnu à sa couleur. Le repeindre en
   laiton le rendrait méconnaissable, ce qui coûterait exactement ce que le
   bouton est censé gagner. */
.barre-action__whatsapp {
    display: grid;
    place-items: center;
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: var(--rayon);
    background: #25d366;
    color: #fff;
}
.barre-action__whatsapp:hover { color: #fff; }

.action-whatsapp { white-space: nowrap; }

/* --- Sommaire ------------------------------------------------------------ */

.sommaire {
    max-width: var(--mesure);
    margin-bottom: var(--e-4);
    padding: var(--e-3) var(--e-4);
    background: var(--fond-creux);
    border-inline-start: 2px solid var(--accent);
}

.sommaire__titre {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--texte-tenu);
    margin-bottom: var(--e-2);
}

.sommaire__liste {
    display: grid;
    gap: var(--e-1);
    margin: 0;
    padding-inline-start: 1.2rem;
    font-size: var(--t-s);
}

.sommaire__liste li::marker { color: var(--texte-tenu); font-variant-numeric: tabular-nums; }
.sommaire__liste a { text-decoration: none; }
.sommaire__liste a:hover { text-decoration: underline; }

/* Le titre visé ne doit pas se retrouver sous l'en-tête collant. */
.prose h2 { scroll-margin-top: 5.5rem; }

/* --- Partage ------------------------------------------------------------- */

.partage {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e-2) var(--e-3);
    max-width: var(--mesure);
    margin-top: var(--e-5);
    padding-top: var(--e-3);
    border-top: 1px solid var(--filet);
    font-size: var(--t-s);
}

.partage__titre {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--texte-tenu);
}

.partage__lien { text-decoration: none; font-weight: 500; }
.partage__lien:hover { text-decoration: underline; }
.partage__lien[data-copie] { color: var(--texte-doux); }

.rubrique__note {
    display: block;
    margin-top: var(--e-1);
    font-size: var(--t-xs);
    color: var(--texte-tenu);
}

.contact__whatsapp { margin-bottom: var(--e-3); }
.contact__faq { margin-top: var(--e-3); }

/* --- Statistiques --------------------------------------------------------
   Page privée, mais elle utilise les mêmes composants que le reste : rien ne
   justifie une seconde feuille de style pour un écran d'administration. */

.statistiques__entete {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--e-3);
    margin-bottom: var(--e-4);
}

.statistiques__periodes {
    display: flex;
    flex-wrap: wrap;
    gap: var(--e-3);
    padding-bottom: var(--e-3);
    border-bottom: 1px solid var(--filet);
    font-size: var(--t-s);
}
.statistiques__periodes a { text-decoration: none; color: var(--texte-doux); }
.statistiques__periodes a:hover { color: var(--lien); }
.statistiques__periodes a[aria-current="page"] { color: var(--texte); font-weight: 600; }

.statistiques__chiffres {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
    margin-block: var(--e-4) var(--e-5);
    border-top: 1px solid var(--filet);
}

.chiffre {
    padding: var(--e-3) var(--e-3) 0 0;
    border-inline-start: 1px solid var(--filet);
    padding-inline-start: var(--e-3);
}
.chiffre:first-child { border-inline-start: 0; padding-inline-start: 0; }

.chiffre strong {
    display: block;
    font-family: var(--titre);
    font-size: var(--t-xl);
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.chiffre span { color: var(--texte-doux); font-size: var(--t-s); }
.chiffre abbr { cursor: help; text-decoration: none; color: var(--texte-tenu); }

.statistiques__titre {
    font-size: var(--t-m);
    font-weight: 600;
    margin-bottom: var(--e-3);
}

/* Le graphique : une colonne par jour, alignées en bas.
   Les hauteurs sont posées par paliers de 5 % (voir plus bas) et non par un
   attribut « style », que la politique de sécurité du site ignore. */
.graphique {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 9rem;
    padding: var(--e-2);
    background: var(--fond-creux);
    border: 1px solid var(--filet);
}

.graphique__jour { flex: 1; height: 100%; display: flex; align-items: flex-end; min-width: 2px; }

.graphique__barre {
    width: 100%;
    background: var(--accent);
    /* Un jour à zéro doit rester visible, sinon le graphique ment par
       omission : on ne distingue plus « aucune visite » de « pas de
       données ». */
    min-height: 2px;
    transition: background-color var(--duree-rapide) var(--courbe);
}
.graphique__jour:hover .graphique__barre { background: var(--lien); }

.graphique__barre[data-niveau="0"] { height: 0%; }
.graphique__barre[data-niveau="5"] { height: 5%; }
.graphique__barre[data-niveau="10"] { height: 10%; }
.graphique__barre[data-niveau="15"] { height: 15%; }
.graphique__barre[data-niveau="20"] { height: 20%; }
.graphique__barre[data-niveau="25"] { height: 25%; }
.graphique__barre[data-niveau="30"] { height: 30%; }
.graphique__barre[data-niveau="35"] { height: 35%; }
.graphique__barre[data-niveau="40"] { height: 40%; }
.graphique__barre[data-niveau="45"] { height: 45%; }
.graphique__barre[data-niveau="50"] { height: 50%; }
.graphique__barre[data-niveau="55"] { height: 55%; }
.graphique__barre[data-niveau="60"] { height: 60%; }
.graphique__barre[data-niveau="65"] { height: 65%; }
.graphique__barre[data-niveau="70"] { height: 70%; }
.graphique__barre[data-niveau="75"] { height: 75%; }
.graphique__barre[data-niveau="80"] { height: 80%; }
.graphique__barre[data-niveau="85"] { height: 85%; }
.graphique__barre[data-niveau="90"] { height: 90%; }
.graphique__barre[data-niveau="95"] { height: 95%; }
.graphique__barre[data-niveau="100"] { height: 100%; }

.graphique__legende {
    display: flex;
    justify-content: space-between;
    gap: var(--e-2);
    margin-top: var(--e-1);
    font-size: var(--t-xs);
    color: var(--texte-tenu);
}

.statistiques__tableaux {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--e-5);
    margin-top: var(--e-5);
}

.tableau { width: 100%; border-collapse: collapse; font-size: var(--t-s); }
.tableau th, .tableau td { text-align: start; padding: var(--e-2) 0; border-bottom: 1px solid var(--filet); }
.tableau th {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--texte-tenu);
    border-bottom-color: var(--filet-fort);
}
.tableau__nombre { text-align: end; font-variant-numeric: tabular-nums; }
.tableau a { text-decoration: none; }
.tableau a:hover { text-decoration: underline; }

/* Suivre une ligne du regard dans un tableau de chiffres demande un effort
   que le survol supprime. */
.tableau tbody tr { transition: background-color var(--duree-rapide) var(--courbe); }
.tableau tbody tr:hover { background: var(--fond-creux); }

/* --- Contenu rédigé ------------------------------------------------------ */

.prose { max-width: var(--mesure); font-size: var(--t-lecture); line-height: 1.75; }
.prose > * + * { margin-top: var(--e-3); }

/* La première ligne d'un article, un cran plus grande : elle fait entrer
   dans le texte. */
.prose > p:first-child { font-size: 1.12em; line-height: 1.6; color: var(--texte-doux); }

.prose h2 {
    font-size: var(--t-l);
    margin-top: var(--e-5);
    padding-top: var(--e-3);
    border-top: 1px solid var(--filet);
}
.prose h3 { font-size: var(--t-m); font-weight: 600; margin-top: var(--e-4); }
.prose ul, .prose ol { padding-inline-start: 1.4rem; }
.prose li + li { margin-top: var(--e-1); }
.prose li::marker { color: var(--texte-tenu); }
.prose strong { font-weight: 650; }

.prose blockquote {
    border-inline-start: 2px solid var(--accent);
    padding-inline-start: var(--e-3);
    color: var(--texte-doux);
    font-family: var(--titre);
    font-size: 1.05em;
}

.prose code {
    font-family: var(--mono);
    font-size: 0.85em;
    background: var(--fond-creux);
    border: 1px solid var(--filet);
    border-radius: var(--rayon);
    padding: 0.1em 0.35em;
}

.prose pre {
    background: var(--fond-creux);
    border: 1px solid var(--filet);
    border-radius: var(--rayon);
    padding: var(--e-3);
    /* Le code déborde en largeur : il défile dans son propre cadre, sinon
       c'est la page entière qui défile latéralement sur téléphone. */
    overflow-x: auto;
}
.prose pre code { background: none; border: 0; padding: 0; font-size: var(--t-s); }

/* Un tableau peut être plus large que la mesure du texte : il défile seul.
   Sans ce cadre, il pousserait la page entière. */
.prose table {
    /* Le cadre épouse les colonnes : en « display: block », un tableau à
       pleine largeur garde ses lignes à leur largeur propre, et le cadre
       les dépasserait d'un vide. */
    width: max-content;
    max-width: 100%;
    /* « separate » : un tableau en « collapse » ne prend pas d'arrondi. */
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--filet);
    border-radius: var(--rayon);
    font-family: var(--sans);
    font-size: var(--t-s);
    display: block;
    overflow-x: auto;
}
.prose th, .prose td {
    text-align: start;
    padding: var(--e-2) var(--e-3);
    border-bottom: 1px solid var(--filet);
    /* Le texte s'enroule dans la cellule. Un « nowrap » général rendait large
       tout tableau dont une cellule est une phrase, et le renvoyait au
       défilement horizontal ci-dessus alors qu'il tenait dans la mesure. Ce
       qui ne doit pas se couper — un nombre et son unité — se tient par une
       espace insécable dans le Markdown, ce que la typographie française
       demande de toute façon. */
    vertical-align: top;
}
.prose th {
    font-weight: 600;
    font-size: var(--t-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--texte-tenu);
    background: var(--fond-creux);
    border-bottom-color: var(--filet-fort);
}
.prose tr:last-child > td { border-bottom: 0; }
.prose img { border: 1px solid var(--filet); }

/* Une capture d'écran lue dans la seule mesure du texte, 40 rem, réduit une
   interface de 1 440 px de plus de moitié : ses libellés deviennent
   illisibles. La figure sort donc de la mesure vers la droite, jusqu'à la
   largeur du conteneur — mesurée en unités de conteneur, que la largeur de
   fenêtre ne remplace pas : « 100vw » compte la barre de défilement et ferait
   déborder la page. L'image garde sa taille propre si elle est plus étroite :
   une capture n'est jamais agrandie. Sans ces unités, la figure reste dans la
   mesure, ce qui est lisible, simplement plus petit. */
.conteneur:has(> .prose) { container-type: inline-size; }

.prose figure {
    width: 100%;
    width: 100cqi;
    margin-block: var(--e-5);
}

.prose figure img {
    display: block;
    max-width: 100%;
    height: auto;
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
}

.prose figcaption {
    max-width: var(--mesure);
    margin-top: var(--e-2);
    font-size: var(--t-s);
    color: var(--texte-tenu);
}

/* --- Articles et documents ----------------------------------------------- */

.article__entete {
    max-width: 44rem;
    margin-bottom: var(--e-5);
    padding-bottom: var(--e-4);
    border-bottom: 1px solid var(--filet);
}

.article__meta {
    color: var(--texte-doux);
    font-size: var(--t-s);
    margin-top: var(--e-3);
}

.article__chapeau {
    font-size: var(--t-m);
    color: var(--texte-doux);
    margin-top: var(--e-3);
    max-width: var(--mesure);
}

.fil {
    font-size: var(--t-s);
    color: var(--texte-tenu);
    margin-bottom: var(--e-4);
}
.fil a { color: var(--texte-tenu); text-decoration: none; }
.fil a:hover { color: var(--lien); }

/* --- Formulaire ---------------------------------------------------------- */

/* --- Contact : le formulaire en carte, les accès directs à côté ------------ */

.contact { display: grid; gap: var(--e-4); align-items: start; }
@media (min-width: 56.25rem) {
    .contact { grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr); }
}

.formulaire {
    display: grid;
    gap: var(--e-3);
    padding: var(--e-4);
    background: var(--surface);
    border: 1px solid var(--filet);
    border-radius: var(--rayon-carte);
    box-shadow: var(--ombre-1);
}

.champ { display: grid; gap: var(--e-1); }

.champ label {
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--texte-doux);
}

.champ__aide { font-size: var(--t-xs); color: var(--texte-tenu); line-height: 1.5; }

.champ input,
.champ select,
.champ textarea {
    width: 100%;
    min-height: 44px;
    padding: 0.7rem 0.85rem;
    font: inherit;
    font-size: var(--t-s);
    color: var(--texte);
    background: var(--surface);
    border: 1px solid var(--filet-fort);
    border-radius: var(--rayon);
    transition: border-color var(--duree-rapide) var(--courbe);
}

.champ textarea { min-height: 10rem; resize: vertical; line-height: 1.6; }
.champ input:hover, .champ select:hover, .champ textarea:hover { border-color: var(--texte-tenu); }
.champ input:focus-visible,
.champ select:focus-visible,
.champ textarea:focus-visible {
    border-color: var(--action);
    outline: 2px solid var(--action);
    outline-offset: 1px;
}

.champ--erreur input,
.champ--erreur select,
.champ--erreur textarea { border-color: var(--erreur); }

.champ__erreur { font-size: var(--t-xs); color: var(--erreur); font-weight: 500; }

.champ--paire { display: grid; gap: var(--e-3); grid-template-columns: 1fr 1fr; }

.formulaire__pied { margin-top: var(--e-2); display: grid; gap: var(--e-3); justify-items: start; }

/* Le champ leurre : hors de l'écran, retiré du parcours au clavier et masqué
   aux lecteurs d'écran, mais présent dans le document — donc rempli par un
   robot qui remplit tout. */
.leurre {
    position: absolute;
    left: -9999px;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
}

.alerte {
    padding: var(--e-3);
    border-inline-start: 2px solid var(--filet-fort);
    background: var(--fond-creux);
    font-size: var(--t-s);
    margin-bottom: var(--e-4);
}

.alerte--succes { border-inline-start-color: var(--succes); }
.alerte--echec { border-inline-start-color: var(--erreur); }

.contact__direct {
    padding: var(--e-4);
    background: var(--fond-creux);
    border-radius: var(--rayon-carte);
}
.contact__direct h2 { font-size: var(--t-m); font-weight: 600; margin-bottom: var(--e-2); }
.contact__direct h2 + p { color: var(--texte-doux); margin-bottom: var(--e-3); }

/* --- Bloc d'appel -------------------------------------------------------- */

/* Un panneau fermé par le filet de laiton : la seule fin de page qui
   demande quelque chose au lecteur, et la seule ainsi marquée. */
.appel {
    display: grid;
    gap: var(--e-3);
    max-width: 44rem;
    padding: var(--e-5);
    background: var(--fond-creux);
    border-top: 3px solid var(--accent);
    border-radius: var(--rayon-carte);
}

.appel h2 { font-size: var(--t-l); }
.appel p { color: var(--texte-doux); max-width: var(--mesure); }
.appel__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3); margin-top: var(--e-2); }

/* L'appel de l'accueil sur une ligne : l'argument à gauche, le geste à
   droite. Sous la largeur des deux, le bouton passe simplement dessous. */
.appel--ligne {
    max-width: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-4) var(--e-5);
}
.appel--ligne > div:first-child { flex: 1 1 30rem; }
.appel--ligne h2 { font-size: var(--t-xl); font-weight: 600; letter-spacing: -0.025em; margin-bottom: var(--e-3); }
.appel--ligne .appel__actions { margin: 0; }

.suite { margin-top: var(--e-6); }

/* --- Pied de page -------------------------------------------------------- */

.pied {
    /* Généreux, mais pas au point de creuser un trou sous une page courte
       comme la liste des réalisations, qui tient en deux cartes. */
    margin-top: var(--e-6);
    /* Le filet de la bande, et non celui de la page : en thème sombre, le
       fond de la bande et celui de la page sont trop proches pour que la
       limite se lise sans lui. */
    border-top: 1px solid var(--filet);
    font-size: var(--t-s);
}

.pied__interieur {
    display: grid;
    gap: var(--e-4);
    grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
    padding-block: var(--e-5) var(--e-4);
}

/* La marque prend plus de place dès que les trois colonnes tiennent. */
@media (min-width: 56.25rem) {
    .pied__interieur { grid-template-columns: 1.6fr 1fr 1fr; }
}

.pied__marque { font-family: var(--titre); font-weight: 600; font-size: var(--t-m); }
.pied__texte { color: var(--texte-doux); margin-top: var(--e-1); max-width: 20rem; }

.pied__titre {
    font-size: var(--t-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--texte-tenu);
    margin-bottom: var(--e-2);
}

.pied__liste { list-style: none; padding: 0; display: grid; gap: var(--e-1); }
.pied__liste a { color: var(--texte-doux); text-decoration: none; }
.pied__liste a:hover { color: var(--lien); }

.pied__bas {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--e-2);
    padding-block: var(--e-3);
    border-top: 1px solid var(--filet);
    color: var(--texte-tenu);
    font-size: var(--t-xs);
}
.pied__bas a { color: var(--texte-tenu); text-decoration: none; }
.pied__bas a:hover { color: var(--lien); }

/* --- Page d'erreur ------------------------------------------------------- */

.erreur { padding-block: var(--e-7); max-width: 34rem; }
.erreur__code {
    font-family: var(--titre);
    font-size: var(--t-xl);
    color: var(--texte-tenu);
    margin-bottom: var(--e-2);
}
.erreur__texte { color: var(--texte-doux); margin-top: var(--e-3); }
.erreur__actions { display: flex; flex-wrap: wrap; gap: var(--e-3); margin-top: var(--e-4); }

/* --- Adaptations --------------------------------------------------------- */

@media (max-width: 61.99rem) {
    .rubrique {
        grid-template-columns: 3rem minmax(0, 1fr) auto;
    }
    .rubrique__texte { grid-column: 2 / -1; }

    /* Le panneau de la vedette passe sous son texte ; son filet de gauche
       devient un filet de tête. */
    .vedette { grid-template-columns: 1fr; }
    .vedette__panneau { border-inline-start: 0; border-top: 1px solid var(--filet); }
}

@media (max-width: 47.99rem) {
    /* Le menu ne se replie que si le script a pris la main. Sans JavaScript,
       data-js est absent et la navigation reste dépliée sous l'en-tête : le
       site demeure entièrement parcourable. */
    html[data-js] .navigation {
        position: absolute;
        inset-inline: 0;
        top: 100%;
        background: var(--fond);
        border-bottom: 1px solid var(--filet);
        padding: var(--e-3) clamp(1.25rem, 5vw, 3.5rem) var(--e-4);
        /* Un tiroir qui couvre l'écran sous l'en-tête. « position: fixed »
           n'y suffirait pas : le flou de l'en-tête fait de lui le bloc
           conteneur de ses descendants fixes, d'où une hauteur explicite. */
        height: calc(100dvh - 4.5rem);
        overflow-y: auto;

        /* « visibility » plutôt que « display: none » : c'est la seule des
           deux propriétés qui se laisse animer, et elle retire tout autant
           le menu du parcours au clavier. Le délai la retarde jusqu'à la fin
           du fondu — sans lui, le menu disparaîtrait d'un coup au lieu de
           s'effacer. Le panneau étant en position absolue, il ne pousse
           rien : le rendre invisible plutôt qu'absent ne coûte aucune place. */
        opacity: 0;
        visibility: hidden;
        transform: translateY(calc(var(--montee) * -1));
        transition: opacity var(--duree) var(--courbe),
                    transform var(--duree) var(--courbe),
                    visibility 0s linear var(--duree);
    }

    html[data-js] .navigation[data-ouvert] {
        opacity: 1;
        visibility: visible;
        transform: none;
        transition: opacity var(--duree) var(--courbe),
                    transform var(--duree) var(--courbe),
                    visibility 0s;
    }

    /* Les liens entrent en cascade derrière le panneau. Le décalage est posé
       par nth-child : la politique de sécurité interdit l'attribut « style »,
       donc il n'y a pas de variable par élément à passer depuis le gabarit. */
    html[data-js] .navigation[data-ouvert] .navigation__liste > li {
        animation: apparition var(--duree) var(--courbe) both;
    }
    html[data-js] .navigation[data-ouvert] .navigation__liste > li:nth-child(2) { animation-delay: 0.04s; }
    html[data-js] .navigation[data-ouvert] .navigation__liste > li:nth-child(3) { animation-delay: 0.08s; }
    html[data-js] .navigation[data-ouvert] .navigation__liste > li:nth-child(4) { animation-delay: 0.12s; }
    html[data-js] .navigation[data-ouvert] .navigation__liste > li:nth-child(5) { animation-delay: 0.16s; }

    .navigation__liste { flex-direction: column; align-items: stretch; gap: var(--e-3); }
    /* Des cibles au format du pouce, dans le tiroir seulement : sans le
       script, la navigation dépliée garde sa taille ordinaire. */
    html[data-js] .navigation__liste a:not(.bouton) {
        display: flex;
        align-items: center;
        min-height: 44px;
        font-size: var(--t-l);
    }
    .navigation a[aria-current="page"]::after { display: none; }
    .navigation__liste .bouton { justify-content: center; }

    html[data-js] .entete__bascule {
        display: grid;
        place-items: center;
        width: 2.25rem; height: 2.25rem;
        background: none;
        border: 1px solid var(--filet);
        border-radius: var(--rayon);
        color: var(--texte);
        cursor: pointer;
    }

    .entete__interieur { position: relative; }
    /* Sous 32 px, la planche impose le symbole seul ; on reste donc à
       30 px, au-dessus du minimum de 24 px du symbole, sans descendre
       le logotype sous son propre seuil. */
    .logo--entete .logo__svg { height: 30px; }
    .logo--entete { font-size: 30px; }

    .entete__barres,
    .entete__barres::before,
    .entete__barres::after {
        content: "";
        display: block;
        width: 1rem; height: 1.5px;
        background: currentcolor;
    }
    .entete__barres { position: relative; transition: background-color var(--duree-rapide) var(--courbe); }
    .entete__barres::before { position: absolute; top: -5px; }
    .entete__barres::after { position: absolute; top: 5px; }

    .entete__barres::before,
    .entete__barres::after {
        transition: transform var(--duree) var(--courbe);
    }

    /* La croix se dessine à partir de aria-expanded, donc de l'état que lit
       un lecteur d'écran — et non d'une classe posée en parallèle. Il ne peut
       pas y avoir de désaccord entre ce qui est vu et ce qui est annoncé.
       La barre du milieu s'efface en devenant transparente : la retirer par
       « display » emporterait aussi ses deux pseudo-éléments. */
    .entete__bascule[aria-expanded="true"] .entete__barres { background: transparent; }
    .entete__bascule[aria-expanded="true"] .entete__barres::before { transform: translateY(5px) rotate(45deg); }
    .entete__bascule[aria-expanded="true"] .entete__barres::after { transform: translateY(-5px) rotate(-45deg); }

    .champ--paire { grid-template-columns: 1fr; }

    .barre-action {
        display: flex;
        gap: var(--e-2);
        position: fixed;
        inset: auto 0 0;
        z-index: 40;
        padding: var(--e-2) clamp(1.25rem, 5vw, 3.5rem);
        padding-bottom: max(var(--e-2), env(safe-area-inset-bottom));
        background: var(--surface);
        border-top: 1px solid var(--filet);
        box-shadow: var(--ombre-2);
    }
    .barre-action .bouton { flex: 1; }

    /* La hauteur de la barre, réservée sous le pied : sans elle, la barre
       couvrirait les dernières lignes de la page et le bouton d'envoi du
       formulaire de contact quand il est en bas. */
    body { padding-bottom: calc(5rem + env(safe-area-inset-bottom)); }

    /* Sur mobile, la barre fixe porte WhatsApp : garder aussi le bouton
       dans le flux proposerait deux fois la même chose. */
    .action-whatsapp { display: none; }

    .vedette__corps, .vedette__panneau { padding: var(--e-4); }

    .rubrique { grid-template-columns: 2.25rem minmax(0, 1fr); gap: var(--e-2) var(--e-3); }
    .rubrique__fleche { display: none; }
}

/* --- Impression ----------------------------------------------------------
   Un prospect qui imprime /services en PDF pour le faire circuler en interne
   est un prospect sérieux : ce qu'il obtient doit ressembler à un document,
   pas à une capture d'écran de site.

   Le logo est conservé — c'est ce qui identifie le document une fois
   détaché du navigateur. Tout ce qui n'a de sens qu'à l'écran disparaît. */

/* --- Mouvement -----------------------------------------------------------
   Le site est un document, pas une application : le mouvement y sert à faire
   entrer dans la lecture et à confirmer un geste, jamais à occuper l'œil. On
   s'en tient donc à trois usages, et à aucun quatrième :

     1. l'entrée en page — l'accroche se pose, ce qui donne un début au
        parcours au lieu de tout livrer d'un bloc ;
     2. la révélation au défilement — chaque section arrive quand on l'atteint ;
     3. le retour au geste — survol, clic, ouverture du menu, copie du lien.

   Deux règles de fabrication, imposées par les contraintes du site :

   « Aucun style en ligne » (politique de sécurité) interdit de passer un
   décalage par élément depuis le gabarit. Les cascades sont donc écrites en
   nth-child, ce qui les limite à des séries courtes et connues d'avance.

   « Rien ne doit disparaître » : un élément mis à opacité 0 par la feuille
   doit être ramené à 1 par un mécanisme qui existe forcément. Les entrées en
   page sont des animations CSS, qui s'exécutent toujours. Les révélations au
   défilement reposent sur une chronologie de défilement, déclarée dans un
   @supports : un navigateur qui ne la connaît pas n'applique aucune de ces
   règles, et affiche le contenu tel quel. À aucun moment un texte ne dépend
   de JavaScript pour être visible. */

@keyframes apparition {
    from { opacity: 0; transform: translateY(var(--montee)); }
    to   { opacity: 1; transform: none; }
}

@keyframes apparition-simple {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes croissance {
    from { transform: scaleY(0); }
    to   { transform: scaleY(1); }
}

/* Entrée de l'accroche. Le pas est de 60 ms : assez pour que l'ordre se
   perçoive — surtitre, titre, résumé, actions — sans que le dernier élément
   se fasse attendre. L'ensemble est posé en moins d'une seconde.

   « both » retient l'élément à l'état de départ pendant son délai ; sans
   cela, il apparaîtrait d'abord en clair avant de disparaître pour entrer. */
.accroche__texte > * {
    animation: apparition var(--duree-lente) var(--courbe) both;
}
.accroche__texte > *:nth-child(2) { animation-delay: 0.06s; }
.accroche__texte > *:nth-child(3) { animation-delay: 0.12s; }
.accroche__texte > *:nth-child(4) { animation-delay: 0.18s; }

/* Les trois repères arrivent après le texte : ils appuient l'argument, ils
   ne le portent pas. */
.accroche__preuves .preuve {
    animation: apparition var(--duree-lente) var(--courbe) both;
}
.accroche__preuves .preuve:nth-child(1) { animation-delay: 0.24s; }
.accroche__preuves .preuve:nth-child(2) { animation-delay: 0.30s; }
.accroche__preuves .preuve:nth-child(3) { animation-delay: 0.36s; }

/* Le message de suite d'un envoi de formulaire : il apparaît au chargement
   d'une page obtenue par redirection, donc à un moment où le visiteur
   cherche justement à savoir ce qui s'est passé. */
.alerte { animation: apparition var(--duree) var(--courbe) both; }


/* Le graphique se dessine en montant depuis la ligne de base — le sens dans
   lequel on lit une hauteur. Toutes les barres partent ensemble : la période
   affichée peut compter trente comme trois cent soixante-cinq jours, et une
   cascade en nth-child ne peut pas couvrir une série de longueur inconnue
   sans se désordonner au-delà de la dernière règle écrite. */
.graphique__barre {
    transform-origin: bottom;
    animation: croissance var(--duree-lente) var(--courbe) both;
}

/* Confirmation de copie : le lien change de texte, ce qui est le vrai
   message ; le fondu signale seulement que quelque chose vient de changer,
   pour l'œil qui était ailleurs au moment du clic. */
.partage__lien[data-copie] { animation: apparition-simple var(--duree) var(--courbe); }

/* --- Révélation au défilement --------------------------------------------
   Chronologie de défilement, sans une ligne de JavaScript : le navigateur
   fait avancer l'animation selon la position de l'élément dans la fenêtre.
   L'alternative — un IntersectionObserver — imposerait de masquer le contenu
   depuis la feuille et de compter sur un script pour le rendre visible. Un
   script qui échoue effacerait alors la page.

   La plage s'arrête dans « entry » : sur un élément plus haut que la fenêtre,
   cette plage est de longueur nulle et l'animation se place d'emblée à son
   terme, c'est-à-dire visible. La dégradation va donc toujours vers le
   contenu affiché. */
@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
        .section__entete,
        .rubriques .rubrique,
        .vedette,
        .colonnes .colonne,
        .grille .carte,
        .statistiques__chiffres .chiffre,
        .appel {
            animation: apparition linear both;
            animation-timeline: view();
            animation-range: entry 15% entry 75%;
        }

    }

    /* L'en-tête prend son ombre au premier défilement : il devient une barre
       d'outils au-dessus du document, au lieu de flotter dans la même teinte
       que lui. En haut de page, rien ne passe dessous, l'ombre n'a pas lieu. */
    @supports (animation-timeline: scroll()) {
        .entete {
            animation: entete-relief linear both;
            animation-timeline: scroll();
            animation-range: 0 64px;
        }
    }
}

@keyframes entete-relief {
    from { box-shadow: none; }
    to { box-shadow: var(--ombre-2); }
}

/* --- Transitions de page -------------------------------------------------
   Le site est rendu par le serveur : chaque lien recharge un document. Le
   fondu croisé entre les deux pages retire le blanc qui sépare l'ancienne de
   la nouvelle, et c'est ce blanc qui fait qu'un site en pages séparées paraît
   plus lent qu'une application, à temps de réponse égal.

   Les navigateurs qui ignorent la règle naviguent comme avant. L'en-tête
   reçoit un nom de transition : identique d'une page à l'autre, il est alors
   traité comme un élément qui persiste, et cesse de clignoter au passage. */
@view-transition { navigation: auto; }

.entete { view-transition-name: entete; }

@keyframes vt-sortie { to { opacity: 0; } }
@keyframes vt-entree { from { opacity: 0; } }

/* La durée par défaut du fondu est trop longue pour une navigation interne :
   elle ajoute à l'attente au lieu de la masquer. La sortie est plus courte
   que l'entrée, pour que la page qui arrive prenne le dessus rapidement. */
::view-transition-old(root) { animation: vt-sortie 0.09s linear both; }
::view-transition-new(root) { animation: vt-entree 0.22s var(--courbe) both; }

@media print {
    /* Rien ne s'anime sur papier, et surtout rien n'y reste à mi-course. Une
       chronologie de défilement n'a pas de fenêtre à laquelle se référer dans
       un contexte paginé : sans cette remise à zéro, un bloc pourrait
       s'imprimer à moitié transparent, ou pas du tout. */
    *, *::before, *::after {
        animation: none !important;
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
        translate: none !important;
        /* Une ombre s'imprime en gris sale, ou pas du tout selon le pilote. */
        box-shadow: none !important;
    }

    /* Navigation, appels à l'action, partage : sans objet sur papier. */
    .entete__bascule, .navigation, .bascule-theme, .lien-evitement,
    .appel, .suite, .barre-action, .partage, .sommaire,
    .pied__liste, .pied__titre, .statistiques__periodes { display: none; }

    /* La couleur d'impression coûte cher et la plupart des imprimantes de
       bureau rendent mal les aplats : tout passe en noir sur blanc, sauf le
       logo, qui garde son dessin. */
    /* La bande à l'encre redéfinit ses propres jetons : sans elle dans ce
       sélecteur, le pied s'imprimerait en texte clair sur papier blanc. */
    :root, .bande-encre {
        --fond: #fff;
        --fond-creux: #fff;
        --surface: #fff;
        --texte: #000;
        --texte-doux: #222;
        --texte-tenu: #555;
        --filet: #bbb;
        --filet-fort: #888;
        --lien: #000;
        /* Sans ces deux-là, une page imprimée depuis le thème sombre
           poserait le rouge clair du message d'erreur sur du papier
           blanc : 1,8:1, illisible. */
        --erreur: #8c1515;
        --succes: #14532d;
    }

    /* Le logo du pied reprend son coloris pour fond clair : la version
       fond sombre de la bande serait presque blanche sur le papier. */
    .bande-encre {
        background: none;
        color: #000;
        --logo-corps: #0e2e4a;
        --logo-accent: #d99b2b;
        --logo-tenu: #1b4b73;
    }

    body { background: #fff; color: #000; font-size: 10.5pt; line-height: 1.45; padding-bottom: 0; }

    .entete {
        position: static;
        border-bottom: 1px solid #888;
        background: none;
        backdrop-filter: none;
    }
    .entete__interieur { min-height: 0; padding-block: 0.4cm; }

    .conteneur { max-width: none; padding-inline: 0; }
    .section { padding-block: 0.6cm; }
    .prose, .mesure, .article__entete, .section__entete { max-width: none; }

    /* Un titre seul en bas de page, ou une carte coupée en deux, sont les
       deux défauts qui font qu'un document imprimé paraît bâclé. */
    h1, h2, h3 { break-after: avoid; page-break-after: avoid; }
    .carte, .rubrique, .vedette, .colonne, .preuve, figure, pre, table { break-inside: avoid; page-break-inside: avoid; }

    /* Sur papier, un lien n'est plus cliquable : son adresse doit être lue.
       Limité aux liens externes — imprimer l'URL de chaque lien interne
       rendrait le texte illisible. */
    .prose a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 0.85em;
        color: #555;
        word-break: break-all;
    }

    .pied { margin-top: 0.8cm; border-top: 1px solid #888; }
    .pied__interieur { display: block; padding-block: 0.4cm 0; }
    .pied__bas { border: 0; padding-block: 0.2cm; }

    @page { margin: 1.6cm 1.4cm; }
}
