/* ==========================================================================
   mbarane.com — feuille de style
   --------------------------------------------------------------------------
   Direction visuelle : indigo et sable.
   L'indigo est un artisanat textile sénégalais ; c'est de là que vient la
   palette, plutôt que d'une charte générique. Le motif tissé du panneau
   d'authentification (.panneau) évoque la trame d'un tissu teint : c'est
   l'unique élément décoratif du site, tout le reste reste silencieux.

   Ton : calme, beaucoup d'air, aucune saturation agressive. Les personnes qui
   arrivent ici sont souvent en difficulté ; l'interface ne doit ni presser
   ni alarmer.

   Accessibilité : contrastes vérifiés WCAG AA, focus toujours visible,
   mouvement respectant prefers-reduced-motion, cibles tactiles ≥ 44 px.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Jetons
   -------------------------------------------------------------------------- */
:root {
    /* Encres */
    --encre:        #10233A;   /* texte principal — 15:1 sur --papier */
    --encre-douce:  #47586B;   /* texte secondaire — 7:1 sur --papier */
    --encre-tenue:  #6B7C8D;   /* légendes — 4.6:1 sur --papier */

    /* Indigo — le panneau signature */
    --indigo-nuit:  #0B1A2E;
    --indigo:       #1B3B6F;
    --indigo-clair: #2E5A9E;

    /* Lagune — accent d'action */
    --lagune:       #0B6E6D;   /* 5.2:1 sur --papier */
    --lagune-fonce: #085453;
    --lagune-voile: #E4F1F0;

    /* Sable — chaleur */
    --sable:        #E8DCC8;
    --ocre:         #A85A28;   /* 5.0:1 sur --papier */
    --ocre-voile:   #FAEFE4;

    /* Surfaces */
    --papier:       #FBFAF7;
    --carte:        #FFFFFF;
    --brume:        #EFF1F3;
    --trait:        #DCE1E6;

    /* États */
    --erreur:       #B3261E;
    --erreur-voile: #FCEDEC;
    --succes:       #1B5E3A;
    --succes-voile: #E9F4EE;
    --alerte:       #7A4A12;
    --alerte-voile: #FBF2E3;

    /* Typographie — deux rôles, une seule fonte téléchargée.

       Titres : Bricolage Grotesque, HÉBERGÉE ICI (assets/fonts/). La politique
       de sécurité de contenu impose font-src 'self' : aucun appel à Google
       Fonts n'aboutirait, et c'est voulu — une fonte distante révélerait la
       consultation du site à un tiers, ce qui est exactement ce qu'on refuse
       sur une plateforme où la discrétion est un enjeu de sécurité physique.

       Corps : la pile système. Elle est déjà sur l'appareil, donc gratuite en
       octets. Une part importante du public est en 3G ; on paie une fonte,
       pas deux, et on la paie pour les titres, là où le caractère se voit. */
    --titre: "Bricolage Grotesque", ui-sans-serif, system-ui, -apple-system,
             "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --texte: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, "Noto Sans", sans-serif;
    --mono:  ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

    /* Échelle typographique — ratio 1.25, fluide sur l'axe principal */
    --t-xs:  0.8125rem;
    --t-sm:  0.9375rem;
    --t-md:  1.0625rem;   /* corps : 17 px, plus confortable que 16 en lecture longue */
    --t-lg:  1.3125rem;
    --t-xl:  clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
    --t-2xl: clamp(2rem, 1.5rem + 2.4vw, 3.125rem);

    /* Rythme — échelle de 4 px */
    --e-1: 0.25rem;  --e-2: 0.5rem;   --e-3: 0.75rem;  --e-4: 1rem;
    --e-5: 1.5rem;   --e-6: 2rem;     --e-7: 3rem;     --e-8: 4rem;
    --e-9: 6rem;

    --rayon:    10px;
    --rayon-lg: 16px;

    --ombre-1: 0 1px 2px rgb(16 35 58 / 6%), 0 2px 8px rgb(16 35 58 / 4%);
    --ombre-2: 0 2px 4px rgb(16 35 58 / 6%), 0 12px 32px rgb(16 35 58 / 8%);

    --largeur-texte: 34rem;
    --largeur-page:  72rem;
}

/* Mode sombre : ces pages sont souvent consultées tard, dans des conditions
   peu confortables. On respecte la préférence du système. */
@media (prefers-color-scheme: dark) {
    :root {
        --encre:        #E8EDF2;
        --encre-douce:  #A9B7C4;
        --encre-tenue:  #8494A3;
        --papier:       #0E1A28;
        --carte:        #15263A;
        --brume:        #1B2E45;
        --trait:        #2A4058;
        --lagune:       #4FC9C6;
        --lagune-voile: #12333A;
        --ocre:         #E0A472;
        --ocre-voile:   #33261A;
        --erreur:       #F2A9A3;
        --erreur-voile: #3A1D1B;
        --succes:       #86D3A6;
        --succes-voile: #14301F;
        --alerte:       #E3BE7E;
        --alerte-voile: #33290F;
        --ombre-1: 0 1px 2px rgb(0 0 0 / 30%);
        --ombre-2: 0 12px 32px rgb(0 0 0 / 40%);
    }
}

/* --------------------------------------------------------------------------
   1 bis. La fonte des titres
   --------------------------------------------------------------------------
   Bricolage Grotesque — licence SIL Open Font, fichier variable, servi depuis
   ce domaine. Un seul fichier couvre 400 → 800 : demander quatre graisses
   statiques coûterait quatre requêtes et trois fois le poids.

   font-display: swap — le texte s'affiche immédiatement avec la fonte système
   et bascule à l'arrivée du fichier. Sur une connexion lente, mieux vaut un
   titre lisible tout de suite qu'un titre parfait dans deux secondes.

   Deux sous-ensembles : « latin » suffit au français courant (é à è ù ç œ),
   « latin-ext » n'est chargé que si un caractère de sa plage apparaît — le
   navigateur décide, grâce à unicode-range.
   -------------------------------------------------------------------------- */
@font-face {
    font-family: "Bricolage Grotesque";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/assets/fonts/bricolage-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: "Bricolage Grotesque";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/assets/fonts/bricolage-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;
}

/* --------------------------------------------------------------------------
   2. Réinitialisation
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

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

body {
    margin: 0;
    font-family: var(--texte);
    font-size: var(--t-md);
    line-height: 1.7;
    color: var(--encre);
    background: var(--papier);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

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

h1, h2, h3, h4 {
    margin: 0 0 var(--e-4);
    font-family: var(--titre);
    /* La fonte est variable sur l'axe « optical size » : les glyphes se
       resserrent d'eux-mêmes en gros corps et s'ouvrent en petit corps.
       C'est le navigateur qui règle l'axe, à partir de la taille demandée. */
    font-optical-sizing: auto;
    font-weight: 600;
    line-height: 1.14;
    letter-spacing: -0.018em;
    text-wrap: balance;
}

h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); }

p  { margin: 0 0 var(--e-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--lagune);
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}
a:hover { color: var(--lagune-fonce); }

/* Focus toujours visible — jamais supprimé, seulement mis en forme. */
:focus-visible {
    outline: 3px solid var(--lagune);
    outline-offset: 2px;
    border-radius: 4px;
}

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

/* Lien d'évitement — premier élément focusable de chaque page */
.saut-contenu {
    position: absolute;
    left: -9999px;
    top: var(--e-2);
    z-index: 100;
    padding: var(--e-3) var(--e-4);
    background: var(--carte);
    color: var(--encre);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-2);
}
.saut-contenu:focus { left: var(--e-4); }

/* Champ leurre anti-robot : masqué visuellement, retiré de l'arbre
   d'accessibilité par aria-hidden et tabindex="-1" côté HTML. */
.hp-field {
    position: absolute !important;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

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

/* --------------------------------------------------------------------------
   3. Structure
   -------------------------------------------------------------------------- */
.page       { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.page__corps{ flex: 1; }

.contenant  { width: 100%; max-width: var(--largeur-page); margin-inline: auto; padding-inline: var(--e-5); }
.contenant--etroit { max-width: 46rem; }

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

/* --------------------------------------------------------------------------
   4. En-tête et pied
   -------------------------------------------------------------------------- */
.entete {
    border-bottom: 1px solid var(--trait);
    background: var(--carte);
    position: sticky;
    top: 0;
    z-index: 20;
}

.entete__interieur {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-4);
    min-height: 68px;
}

/* En dessous de 32rem, la marque et la navigation ne tiennent plus côte à
   côte : les libellés de boutons se brisaient en trois lignes, ce qui est un
   bouton cassé, pas un bouton étroit. On passe sur deux rangs — marque au
   -dessus, navigation en dessous, alignée à droite. */
@media (max-width: 32rem) {
    .entete__interieur {
        flex-direction: column;
        align-items: stretch;
        gap: var(--e-3);
        padding-block: var(--e-3);
    }

    .entete__interieur .nav { justify-content: flex-end; }
}
/* La marque : le signe, puis le mot.
   align-items: center et non baseline — il n'y a plus deux textes à aligner
   sur une même ligne d'écriture, mais une image et un bloc de texte. */
.marque {
    display: inline-flex;
    align-items: center;
    gap: var(--e-3);
    color: var(--encre);
    text-decoration: none;
}

.marque:hover { color: var(--encre); }

.marque__mot {
    font-family: var(--titre);
    font-optical-sizing: auto;
    font-size: 1.375rem;
    font-weight: 620;
    letter-spacing: -0.03em;
    line-height: 1.1;
}

.marque__slogan {
    display: block;
    font-family: var(--texte);
    font-size: var(--t-xs);
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 1.3;
    color: var(--encre-tenue);
    margin-top: 1px;
}

/* Le logo ne se déforme jamais, quelle que soit la place restante : sans
   flex-shrink: 0, un slogan long l'écrase en ovale sur un écran étroit. */
.logo { flex: 0 0 auto; display: block; border-radius: 22%; }

/* Sous 26rem, le slogan disparaît plutôt que de passer à la ligne et de
   doubler la hauteur de l'en-tête. Le nom et le signe suffisent à identifier
   le site ; la promesse est répétée sur la page d'accueil. */
@media (max-width: 26rem) {
    .marque__slogan { display: none; }
}

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

/* Un libellé de bouton qui passe à la ligne est un bouton cassé : on préfère
   qu'il dépasse en largeur, ce que le passage sur deux rangs rend possible. */
.nav .bouton, .nav__lien { white-space: nowrap; }

.nav__lien {
    /* 44 px : le minimum retenu par les recommandations tactiles. On mesurait
       42 px — deux pixels qui ne se voient pas, mais qui se ratent avec le
       pouce, surtout en marchant ou d'une seule main. */
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: var(--e-2) var(--e-3);
    border-radius: var(--rayon);
    color: var(--encre-douce);
    font-size: var(--t-sm);
    font-weight: 500;
    text-decoration: none;
}
.nav__lien:hover { background: var(--brume); color: var(--encre); }
.nav__lien[aria-current="page"] { color: var(--encre); background: var(--brume); }

.pied {
    border-top: 1px solid var(--trait);
    padding-block: var(--e-6);
    font-size: var(--t-sm);
    color: var(--encre-tenue);
}
.pied__liens { display: flex; flex-wrap: wrap; gap: var(--e-4); margin-bottom: var(--e-3); }
.pied a { color: var(--encre-douce); }

/* --------------------------------------------------------------------------
   5. Le panneau — élément signature
   --------------------------------------------------------------------------
   Trame tissée en dégradés répétés, sans aucune image : évoque un tissu teint
   à l'indigo. Présent uniquement sur les écrans d'authentification, où il fait
   office de repère de confiance.
   -------------------------------------------------------------------------- */
.duo {
    display: grid;
    grid-template-columns: 1fr;
    min-height: 100vh;
    min-height: 100dvh;
}

@media (min-width: 62rem) {
    .duo { grid-template-columns: minmax(0, 27rem) minmax(0, 1fr); }
}

.panneau {
    position: relative;
    display: none;
    flex-direction: column;
    justify-content: space-between;
    padding: var(--e-7) var(--e-6);
    color: #EAF0F7;
    background:
        radial-gradient(120% 80% at 15% 0%, #2E5A9E 0%, transparent 55%),
        linear-gradient(165deg, var(--indigo) 0%, var(--indigo-nuit) 100%);
    overflow: hidden;
}

@media (min-width: 62rem) { .panneau { display: flex; } }

/* La trame */
.panneau::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        repeating-linear-gradient(90deg, rgb(255 255 255 / 5%) 0 1px, transparent 1px 8px),
        repeating-linear-gradient(0deg,  rgb(255 255 255 / 3.5%) 0 1px, transparent 1px 8px);
    mask-image: radial-gradient(130% 90% at 20% 15%, #000 0%, transparent 78%);
    pointer-events: none;
}

.panneau > * { position: relative; }

.panneau .marque,
.panneau .marque:hover { color: #FFF; }
.panneau .marque__slogan { color: rgb(234 240 247 / 72%); }

.panneau__phrase {
    font-size: 1.5rem;
    font-weight: 500;
    line-height: 1.4;
    letter-spacing: -0.02em;
    max-width: 20ch;
    margin: 0;
}

.panneau__note {
    font-size: var(--t-sm);
    line-height: 1.6;
    color: rgb(234 240 247 / 78%);
    max-width: 32ch;
    margin: var(--e-4) 0 0;
}

.panneau__pied {
    font-size: var(--t-xs);
    color: rgb(234 240 247 / 62%);
    display: flex;
    align-items: center;
    gap: var(--e-2);
}

.volet {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--e-6) var(--e-5) var(--e-8);
    background: var(--papier);
}

.volet__interieur { width: 100%; max-width: 26rem; margin-inline: auto; }

/* Marque affichée en tête du volet sur mobile, quand le panneau est masqué */
.volet__marque { margin-bottom: var(--e-6); }
@media (min-width: 62rem) { .volet__marque { display: none; } }

/* --------------------------------------------------------------------------
   6. Formulaires
   -------------------------------------------------------------------------- */
.champ { margin-bottom: var(--e-5); }

.champ__etiquette {
    display: block;
    margin-bottom: var(--e-2);
    font-size: var(--t-sm);
    font-weight: 600;
    letter-spacing: -0.005em;
    color: var(--encre);
}

.champ__aide {
    display: block;
    margin-top: var(--e-2);
    font-size: var(--t-sm);
    color: var(--encre-tenue);
    line-height: 1.55;
}

.champ__saisie {
    width: 100%;
    min-height: 48px;
    padding: var(--e-3) var(--e-4);
    font: inherit;
    font-size: var(--t-md);
    color: var(--encre);
    background: var(--carte);
    border: 1.5px solid var(--trait);
    border-radius: var(--rayon);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.champ__saisie::placeholder { color: var(--encre-tenue); opacity: .75; }
.champ__saisie:hover { border-color: var(--encre-tenue); }
.champ__saisie:focus {
    outline: none;
    border-color: var(--lagune);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--lagune) 22%, transparent);
}
.champ__saisie[aria-invalid="true"] { border-color: var(--erreur); }
.champ__saisie[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--erreur) 20%, transparent);
}

textarea.champ__saisie { min-height: 8rem; resize: vertical; line-height: 1.6; }

.champ__erreur {
    display: flex;
    gap: var(--e-2);
    margin-top: var(--e-2);
    font-size: var(--t-sm);
    font-weight: 500;
    color: var(--erreur);
}

/* Code à 6 chiffres — chiffres tabulaires, espacés, gros */
.champ__code {
    font-family: var(--mono);
    font-size: 1.5rem;
    letter-spacing: 0.35em;
    text-align: center;
    font-variant-numeric: tabular-nums;
    padding-inline: var(--e-3);
}

/* Bascule afficher / masquer le mot de passe. Ajoutée par JavaScript : elle
   n'apparaît donc jamais sans être fonctionnelle. */
.champ--avec-bascule { position: relative; }

.champ__bascule {
    position: absolute;
    right: var(--e-2);
    top: 50%;
    transform: translateY(-50%);
    /* Même seuil tactile que le reste : ce bouton est le plus utilisé du
       formulaire sur mobile, où l'on saisit un mot de passe long à l'aveugle. */
    min-height: 44px;
    padding-inline: var(--e-3);
    font: inherit;
    font-size: var(--t-sm);
    font-weight: 500;
    color: var(--encre-douce);
    background: transparent;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
}
.champ__bascule:hover { background: var(--brume); color: var(--encre); }

/* Le champ d'aide se place sous le champ : la bascule est centrée sur la
   hauteur de la seule zone de saisie, pas du bloc entier. */
.champ--avec-bascule .champ__bascule { top: 24px; transform: none; }

/* Emplacement du composant CAPTCHA. Hauteur réservée pour éviter que le
   contenu ne saute quand le composant du fournisseur se charge. */
.captcha { min-height: 68px; }
.captcha:empty { min-height: 0; }

.case {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--e-3);
    align-items: start;
    margin-bottom: var(--e-5);
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--encre-douce);
    cursor: pointer;
}
.case input[type="checkbox"] {
    width: 20px; height: 20px;
    margin: 2px 0 0;
    accent-color: var(--lagune);
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   7. Boutons
   -------------------------------------------------------------------------- */
.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--e-2);
    min-height: 48px;
    padding: var(--e-3) var(--e-5);
    font: inherit;
    font-size: var(--t-md);
    font-weight: 580;
    letter-spacing: -0.005em;
    color: #FFF;
    background: var(--lagune);
    border: 1.5px solid transparent;
    border-radius: var(--rayon);
    cursor: pointer;
    text-decoration: none;
    transition: background-color .15s ease, transform .08s ease;
}
.bouton:hover { background: var(--lagune-fonce); color: #FFF; }
.bouton:active { transform: translateY(1px); }
.bouton--large { width: 100%; }

.bouton--secondaire {
    color: var(--encre);
    background: var(--carte);
    border-color: var(--trait);
}
.bouton--secondaire:hover { background: var(--brume); color: var(--encre); border-color: var(--encre-tenue); }

.bouton--discret {
    color: var(--encre-douce);
    background: transparent;
    border-color: transparent;
    font-weight: 500;
    min-height: 44px;
    padding-inline: var(--e-3);
}
.bouton--discret:hover { background: var(--brume); color: var(--encre); }

.bouton--danger { background: var(--erreur); }
.bouton--danger:hover { background: #8E1E17; color: #FFF; }

/* --------------------------------------------------------------------------
   8. Messages
   -------------------------------------------------------------------------- */
/* flow-root, et non flex.
   En flex, les enfants se placent CÔTE À CÔTE : un bloc contenant un titre et
   deux paragraphes — comme sur les pages légales — partait en largeur et
   faisait défiler la page entière horizontalement sur téléphone. Le défaut
   était invisible tant qu'un message ne contenait qu'un seul paragraphe.
   flow-root donne un contexte de formatage propre sans cet effet de bord. */
.message {
    display: flow-root;
    padding: var(--e-4);
    margin-bottom: var(--e-5);
    border-radius: var(--rayon);
    border-left: 3px solid;
    font-size: var(--t-sm);
    line-height: 1.6;
    /* Une adresse ou un nom d'organisme sans espace casse plutôt que de
       pousser le bloc au-delà de l'écran. */
    overflow-wrap: anywhere;
}
.message p { margin: 0; }
.message > * + * { margin-top: var(--e-3); }
.message--succes { background: var(--succes-voile); border-color: var(--succes); color: var(--succes); }
.message--error,
.message--erreur { background: var(--erreur-voile); border-color: var(--erreur); color: var(--erreur); }
.message--warning,
.message--alerte { background: var(--alerte-voile); border-color: var(--alerte); color: var(--alerte); }
.message--info   { background: var(--lagune-voile); border-color: var(--lagune); color: var(--lagune-fonce); }

@media (prefers-color-scheme: dark) {
    .message--info { color: var(--lagune); }
}

/* --------------------------------------------------------------------------
   9. Cartes et blocs
   -------------------------------------------------------------------------- */
.carte {
    padding: var(--e-5);
    background: var(--carte);
    border: 1px solid var(--trait);
    border-radius: var(--rayon-lg);
    box-shadow: var(--ombre-1);
}

.carte__titre { font-size: var(--t-lg); margin-bottom: var(--e-2); }
.carte__texte { color: var(--encre-douce); font-size: var(--t-sm); margin-bottom: var(--e-4); }

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

/* Surtitre : la petite étiquette en capitales au-dessus d'un titre.
   À DOSER. Posée sur chaque section, elle donne à toutes les pages le même
   rythme mécanique et ne signale plus rien. Règle tenue ici : au plus une
   pour trois sections, et jamais deux sections de suite. */
.surtitre {
    display: block;
    margin-bottom: var(--e-3);
    font-family: var(--titre);
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ocre);
}

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

.texte-doux  { color: var(--encre-douce); }
.texte-tenu  { color: var(--encre-tenue); font-size: var(--t-sm); }
.centre      { text-align: center; }

.pile > * + * { margin-top: var(--e-4); }

/* Rappel « ceci n'est pas un avis professionnel » — présent partout où un
   résultat est affiché. Discret mais jamais absent. */
.avertissement {
    padding: var(--e-4);
    background: var(--ocre-voile);
    border-radius: var(--rayon);
    font-size: var(--t-sm);
    line-height: 1.6;
    color: var(--encre-douce);
}

/* Codes de secours */
.codes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--e-2);
    padding: var(--e-4);
    margin-bottom: var(--e-5);
    background: var(--brume);
    border-radius: var(--rayon);
    font-family: var(--mono);
    font-size: var(--t-md);
    letter-spacing: 0.06em;
}
.codes li { list-style: none; padding: var(--e-2); text-align: center; }

/* Secret TOTP affiché en repli du QR code */
.secret {
    display: block;
    padding: var(--e-3) var(--e-4);
    background: var(--brume);
    border-radius: var(--rayon);
    font-family: var(--mono);
    font-size: var(--t-sm);
    letter-spacing: 0.12em;
    word-break: break-all;
    text-align: center;
}

.qr {
    display: grid;
    place-items: center;
    padding: var(--e-4);
    background: #FFF;
    border: 1px solid var(--trait);
    border-radius: var(--rayon);
    margin-bottom: var(--e-4);
}

/* --------------------------------------------------------------------------
   10. Auto-évaluation
   --------------------------------------------------------------------------
   Parti pris : AUCUN code couleur rouge / orange / vert. Une pastille rouge
   posée sur la vie affective de quelqu'un se lit comme une sentence. Toutes
   les barres utilisent la même teinte ; l'information est portée par la
   longueur de remplissage et par le texte, jamais par un signal d'alarme.
   -------------------------------------------------------------------------- */

/* Progression --------------------------------------------------------------- */
.progression { margin-bottom: var(--e-6); }

.progression__texte {
    margin: 0 0 var(--e-2);
    font-size: var(--t-sm);
    font-weight: 600;
    color: var(--encre-douce);
    font-variant-numeric: tabular-nums;
}

.progression__barre {
    height: 5px;
    background: var(--brume);
    border-radius: 999px;
    overflow: hidden;
}

.progression__remplissage {
    display: block;
    height: 100%;
    background: var(--lagune);
    border-radius: 999px;
    transition: width .3s ease;
}

/* Questions ----------------------------------------------------------------- */
.question {
    margin: 0 0 var(--e-5);
    padding: var(--e-5) 0 0;
    border: 0;
    border-top: 1px solid var(--trait);
}
.question:first-of-type { border-top: 0; padding-top: var(--e-4); }

.question__intitule {
    display: block;
    width: 100%;
    padding: 0;
    margin-bottom: var(--e-4);
    font-size: var(--t-md);
    font-weight: 500;
    line-height: 1.55;
    color: var(--encre);
    text-wrap: pretty;
}

/* Numéro discret : repère de position, pas une hiérarchie. Les questions ne
   sont pas une séquence — leur ordre n'a pas de sens propre. */
.question__numero {
    color: var(--encre-tenue);
    font-variant-numeric: tabular-nums;
    margin-right: var(--e-1);
}

.question__aide {
    margin: calc(var(--e-4) * -1 + var(--e-1)) 0 var(--e-4);
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--encre-tenue);
}

/* Échelle de réponse --------------------------------------------------------
   De vrais boutons radio, masqués visuellement mais présents dans le DOM :
   la navigation au clavier (flèches) et l'annonce par lecteur d'écran restent
   celles, natives, d'un groupe de radios.

   VERTICALE, À TOUTES LES LARGEURS. Les réponses ne sont plus cinq adverbes
   interchangeables mais cinq phrases écrites pour la question. Cinq phrases
   côte à côte donnent cinq colonnes de trois mots de large : illisible sur un
   téléphone, et l'œil ne peut plus les comparer, ce qui est pourtant tout ce
   qu'on lui demande de faire ici. */
.echelle {
    display: flex;
    flex-direction: column;
    gap: var(--e-2);
}

.echelle__radio {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    pointer-events: none;
}

.echelle__option {
    display: flex;
    align-items: flex-start;
    gap: var(--e-3);
    min-height: 48px;
    padding: var(--e-3) var(--e-4);
    font-size: var(--t-sm);
    font-weight: 500;
    line-height: 1.45;
    text-align: left;
    color: var(--encre-douce);
    background: var(--carte);
    border: 1.5px solid var(--trait);
    border-radius: var(--rayon);
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease, color .12s ease;
}

/* Pastille de sélection dessinée en CSS.
   Le radio natif est masqué pour pouvoir styler la ligne entière ; sans repère
   visuel, rien ne dirait qu'un seul choix est possible. Une pastille ronde le
   dit — c'est la convention que tout le monde lit sans y penser, et elle
   distingue ce groupe d'une liste de cases à cocher. */
.echelle__option::before {
    content: "";
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.12rem;
    border: 2px solid var(--encre-tenue);
    border-radius: 50%;
    background: transparent;
    transition: border-color .12s ease, box-shadow .12s ease, background-color .12s ease;
}

.echelle__option:hover { border-color: var(--encre-tenue); color: var(--encre); }

.echelle__radio:checked + .echelle__option {
    color: #FFF;
    background: var(--lagune);
    border-color: var(--lagune);
    font-weight: 600;
}

.echelle__radio:checked + .echelle__option::before {
    border-color: #FFF;
    background: #FFF;
    /* Anneau intérieur : la couleur du fond réapparaît au centre. */
    box-shadow: inset 0 0 0 3.5px var(--lagune);
}

/* Le focus doit rester visible alors que le radio lui-même est masqué. */
.echelle__radio:focus-visible + .echelle__option {
    outline: 3px solid var(--lagune);
    outline-offset: 2px;
}

@media (prefers-color-scheme: dark) {
    .echelle__radio:checked + .echelle__option { color: var(--papier); }
    .echelle__radio:checked + .echelle__option::before {
        border-color: var(--papier);
        background: var(--papier);
        box-shadow: inset 0 0 0 3.5px var(--lagune);
    }
}

.etape__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--e-3);
    align-items: center;
    margin-top: var(--e-6);
}

/* Liste des étapes sur la page de présentation ------------------------------ */
.etapes-liste {
    list-style: none;
    counter-reset: etape;
    padding: 0;
    margin: 0;
}

.etapes-liste li {
    counter-increment: etape;
    position: relative;
    padding: var(--e-4) 0 var(--e-4) var(--e-6);
    border-top: 1px solid var(--trait);
}
.etapes-liste li:last-child { border-bottom: 1px solid var(--trait); }

/* Ici la numérotation encode une vraie information : les étapes se font dans
   l'ordre. Ailleurs sur le site, on s'en passe. */
.etapes-liste li::before {
    content: counter(etape);
    position: absolute;
    left: 0;
    top: var(--e-4);
    font-size: var(--t-sm);
    font-weight: 650;
    color: var(--ocre);
    font-variant-numeric: tabular-nums;
}

.etapes-liste strong { display: block; margin-bottom: var(--e-1); }

/* Scores par dimension ------------------------------------------------------ */
.scores { margin-top: var(--e-5); }

.score { padding: var(--e-5) 0; border-top: 1px solid var(--trait); }
.score:last-child { border-bottom: 1px solid var(--trait); }

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

.score__titre { margin: 0; font-size: var(--t-md); font-weight: 600; }

.score__valeur {
    font-size: var(--t-lg);
    font-variant-numeric: tabular-nums;
    color: var(--encre-douce);
    white-space: nowrap;
}

/* Le niveau se traduit par la GRAISSE, pas par la couleur. */
.score__valeur[data-niveau="marque"] { color: var(--encre); font-weight: 650; }
.score__valeur[data-niveau="modere"] { color: var(--encre); font-weight: 550; }

.score__barre {
    height: 8px;
    background: var(--brume);
    border-radius: 999px;
    overflow: hidden;
}

.score__remplissage {
    display: block;
    height: 100%;
    background: var(--lagune);
    border-radius: 999px;
}

.score__note {
    margin: var(--e-3) 0 0;
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--encre-tenue);
}

/* Historique ----------------------------------------------------------------- */
.historique { list-style: none; padding: 0; margin: var(--e-5) 0 0; }

.historique__ligne {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--e-3);
    padding: var(--e-4) 0;
    border-top: 1px solid var(--trait);
}
.historique__ligne:last-child { border-bottom: 1px solid var(--trait); }

@media (min-width: 44rem) {
    .historique__ligne {
        grid-template-columns: 1fr auto auto;
        align-items: center;
        gap: var(--e-5);
    }
}

.historique__date   { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.historique__bande  { margin: var(--e-1) 0 0; font-size: var(--t-sm); color: var(--encre-tenue); }

.historique__mesure { display: flex; align-items: baseline; gap: var(--e-3); }

.historique__valeur {
    font-size: var(--t-lg);
    font-variant-numeric: tabular-nums;
    color: var(--encre);
}

.historique__ecart {
    font-size: var(--t-sm);
    font-variant-numeric: tabular-nums;
    color: var(--encre-tenue);
}

.historique__actions { display: flex; gap: var(--e-2); align-items: center; }

/* --------------------------------------------------------------------------
   11. Journal
   --------------------------------------------------------------------------
   Même parti pris que l'auto-évaluation : aucun code couleur d'alerte sur les
   montants. Un total élevé n'est pas une alarme, c'est un fait — et la personne
   qui le consulte le sait déjà.
   -------------------------------------------------------------------------- */

.journal-entete {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--e-4);
    margin-bottom: var(--e-6);
}
.journal-entete h1 { margin: 0; }
.journal-entete__actions { display: flex; flex-wrap: wrap; gap: var(--e-3); }

/* Filtres ------------------------------------------------------------------- */
.filtres {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--e-3);
    padding: var(--e-4);
    margin-bottom: var(--e-5);
    background: var(--brume);
    border-radius: var(--rayon-lg);
}

@media (min-width: 48rem) {
    .filtres { grid-template-columns: 1.4fr 1fr 1fr auto; align-items: end; }
}

.filtres__champ { margin: 0; }
.filtres__champ .champ__saisie { min-height: 44px; }
.filtres__actions { display: flex; gap: var(--e-2); align-items: center; }

/* Frise --------------------------------------------------------------------- */
.frise-mois { margin-bottom: var(--e-7); }

.frise-mois__titre {
    position: sticky;
    top: 68px;                    /* hauteur de l'en-tête */
    z-index: 5;
    padding: var(--e-2) 0;
    margin: 0 0 var(--e-3);
    font-size: var(--t-sm);
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--encre-tenue);
    background: var(--papier);
    border-bottom: 1px solid var(--trait);
}

.frise { list-style: none; padding: 0; margin: 0; }

.frise__entree {
    display: grid;
    grid-template-columns: 3.25rem 1fr;
    gap: var(--e-4);
    padding: var(--e-4) 0;
    position: relative;
}

/* Le filet continu qui relie les entrées : c'est ce qui fait la « frise »
   plutôt qu'une liste. Il s'arrête à la dernière entrée du mois. */
.frise__entree::before {
    content: "";
    position: absolute;
    left: 1.5rem;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--trait);
}
.frise__entree:first-child::before { top: var(--e-4); }
.frise__entree:last-child::before  { bottom: calc(100% - var(--e-4)); }

.frise__date {
    position: relative;
    z-index: 1;
    display: grid;
    place-content: center;
    align-self: start;
    width: 3.25rem;
    height: 3.25rem;
    text-align: center;
    background: var(--carte);
    border: 1px solid var(--trait);
    border-radius: 50%;
}

.frise__jour {
    display: block;
    font-size: var(--t-md);
    font-weight: 650;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.frise__mois-court {
    display: block;
    font-size: 0.6875rem;
    color: var(--encre-tenue);
    line-height: 1.4;
}

.frise__contenu {
    padding: var(--e-4);
    background: var(--carte);
    border: 1px solid var(--trait);
    border-radius: var(--rayon-lg);
}

.frise__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--e-3);
    margin-bottom: var(--e-2);
}

.etiquette {
    display: inline-block;
    padding: 2px var(--e-2);
    font-size: var(--t-xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--encre-douce);
    background: var(--brume);
    border-radius: 999px;
}

.frise__montant {
    font-size: var(--t-sm);
    color: var(--encre-douce);
    font-variant-numeric: tabular-nums;
}
.frise__montant strong { color: var(--encre); }

.frise__titre  { margin: 0 0 var(--e-2); font-size: var(--t-md); font-weight: 600; }
.frise__texte  { margin: 0; color: var(--encre-douce); font-size: var(--t-sm); line-height: 1.6; }

.frise__illisible {
    margin: 0;
    padding: var(--e-3);
    font-size: var(--t-sm);
    color: var(--alerte);
    background: var(--alerte-voile);
    border-radius: var(--rayon);
}

.frise__actions {
    display: flex;
    gap: var(--e-1);
    margin-top: var(--e-3);
    padding-top: var(--e-3);
    border-top: 1px solid var(--trait);
}

.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-3);
    margin-top: var(--e-6);
}

/* Formulaire ---------------------------------------------------------------- */
.champ-groupe {
    padding: var(--e-4);
    margin-bottom: var(--e-5);
    background: var(--brume);
    border-radius: var(--rayon-lg);
}
.champ-groupe .champ:last-child { margin-bottom: 0; }

.montant { display: grid; grid-template-columns: 1fr; gap: var(--e-3); }
@media (min-width: 34rem) { .montant { grid-template-columns: 2fr 1fr; } }

/* Le rappel sur les tiers : présent, lisible, mais pas alarmant. C'est une
   invitation à formuler autrement, pas un avertissement de modération. */
.rappel-tiers {
    margin: 0 0 var(--e-3);
    padding: var(--e-3);
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--encre-douce);
    background: var(--lagune-voile);
    border-left: 2px solid var(--lagune);
    border-radius: 0 var(--rayon) var(--rayon) 0;
}

/* Cinq niveaux d'humeur.
   Celle-ci reste HORIZONTALE : ses libellés sont des mots (« Mal »,
   « Bien »), pas des phrases. C'est l'échelle du questionnaire qui est passée
   en liste verticale, parce que ses réponses y sont devenues des phrases
   entières. La forme suit le contenu, pas l'inverse. */
.echelle--humeur { flex-direction: row; flex-wrap: wrap; }

.echelle--humeur .echelle__option {
    flex: 1 1 7rem;
    justify-content: center;
    text-align: center;
}

/* Pas de pastille ici : cinq segments côte à côte se lisent comme un curseur,
   et la pastille les alourdirait sans rien apprendre. */
.echelle--humeur .echelle__option::before { display: none; }

/* Pièces jointes --------------------------------------------------------------
   Une ligne par pièce : aperçu, nom, poids, bouton de suppression. Pas une
   grille de vignettes — ces images sont des captures de conversation, pas une
   galerie. Une mosaïque en ferait un album qu'on parcourt ; une liste en fait
   un dossier qu'on consulte, ce qu'elle est. */
.pieces__liste {
    list-style: none;
    margin: 0 0 var(--e-5);
    padding: 0;
    border-top: 1px solid var(--trait);
}

.piece {
    display: flex;
    align-items: center;
    gap: var(--e-4);
    padding: var(--e-3) 0;
    border-bottom: 1px solid var(--trait);
}

.piece__apercu {
    flex: 0 0 auto;
    display: block;
    width: 4rem;
    height: 4rem;
    overflow: hidden;
    border-radius: var(--rayon);
    border: 1px solid var(--trait);
}

.piece__apercu img { width: 100%; height: 100%; object-fit: cover; }

.piece__type {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    font-family: var(--titre);
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.08em;
    color: var(--encre-tenue);
    background: var(--brume);
    border: 1px solid var(--trait);
    border-radius: var(--rayon);
}

.piece__infos { flex: 1 1 auto; min-width: 0; }

.piece__nom {
    display: block;
    font-weight: 550;
    color: var(--encre);
    /* Les noms de fichiers sont longs et sans espace : sans cela, un seul nom
       pousse le bouton de suppression hors de l'écran sur un téléphone. */
    overflow-wrap: anywhere;
}

.piece__meta {
    margin: var(--e-1) 0 0;
    font-size: var(--t-xs);
    color: var(--encre-tenue);
    font-variant-numeric: tabular-nums;
}

/* Compteur de pièces sur une note de la frise */
.piece-compte {
    display: inline-flex;
    align-items: center;
    gap: var(--e-1);
    padding: 2px var(--e-2);
    font-size: var(--t-xs);
    font-weight: 550;
    color: var(--encre-douce);
    background: var(--brume);
    border-radius: 999px;
}

/* Totaux -------------------------------------------------------------------- */
.totaux { margin-bottom: var(--e-6); }
.totaux__devise { font-size: var(--t-lg); margin-bottom: var(--e-4); }

/* Bilan versé / reçu ---------------------------------------------------------
   Deux colonnes face à face, séparées par un filet : la composition dit
   elle-même qu'il s'agit de deux sens opposés, avant même qu'on lise les
   libellés. La phrase de solde est posée dessous, en toutes lettres — un
   nombre précédé d'un signe moins se lit mal et s'interprète encore plus mal
   sur un sujet où l'on cherche justement à ne pas se tromper.

   AUCUN code couleur. Ni rouge sur le versé, ni vert sur le reçu. Un montant
   élevé n'est pas une alarme, c'est un fait ; la couleur porterait un jugement
   que ces chiffres ne permettent pas. */
.bilan {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--e-4);
    padding: var(--e-5);
    margin-bottom: var(--e-4);
    background: var(--carte);
    border: 1.5px solid var(--lagune);
    border-radius: var(--rayon-lg);
}

@media (min-width: 40rem) {
    .bilan { grid-template-columns: 1fr 1fr; column-gap: var(--e-6); }
    .bilan__cote + .bilan__cote {
        padding-left: var(--e-6);
        border-left: 1px solid var(--trait);
    }
    .bilan__solde { grid-column: 1 / -1; }
}

.bilan__libelle {
    margin: 0 0 var(--e-2);
    font-family: var(--titre);
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--encre-tenue);
}

.bilan__valeur {
    margin: 0;
    font-family: var(--titre);
    font-optical-sizing: auto;
    font-size: clamp(1.625rem, 1.3rem + 1.4vw, 2.25rem);
    font-weight: 620;
    line-height: 1.1;
    letter-spacing: -0.02em;
    /* Chiffres de largeur fixe : sans cela, deux montants superposés ne
       s'alignent pas et la comparaison visuelle devient fausse. */
    font-variant-numeric: tabular-nums;
    color: var(--encre);
}

.bilan__note {
    margin: var(--e-2) 0 0;
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--encre-tenue);
}

.bilan__solde {
    padding-top: var(--e-4);
    border-top: 1px solid var(--trait);
}

.bilan__phrase {
    margin: 0;
    font-size: var(--t-md);
    line-height: 1.5;
    color: var(--encre-douce);
}

.bilan__phrase strong {
    font-variant-numeric: tabular-nums;
    color: var(--encre);
}

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

.total {
    padding: var(--e-4);
    background: var(--carte);
    border: 1px solid var(--trait);
    border-radius: var(--rayon-lg);
}

/* Le seul accent de la page : la question à laquelle l'écran répond. */
.total--principal { border-color: var(--lagune); border-width: 1.5px; }

.total__libelle {
    margin: 0 0 var(--e-2);
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--encre-tenue);
}

.total__valeur {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    color: var(--encre);
    overflow-wrap: anywhere;
}

.total__note { margin: var(--e-2) 0 0; font-size: var(--t-xs); color: var(--encre-tenue); }

/* Tableau mensuel ------------------------------------------------------------ */
.tableau-mois {
    width: 100%;
    margin-top: var(--e-5);
    border-collapse: collapse;
    font-size: var(--t-sm);
}

.tableau-mois th,
.tableau-mois td {
    padding: var(--e-3) var(--e-2);
    text-align: left;
    border-bottom: 1px solid var(--trait);
    vertical-align: middle;
}

.tableau-mois thead th {
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--encre-tenue);
}

.tableau-mois .nombre { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tableau-mois__barre  { width: 40%; padding-left: var(--e-4); }

.barre {
    display: block;
    height: 7px;
    min-width: 2px;
    background: var(--lagune);
    border-radius: 999px;
}

/* Zone d'action irréversible ------------------------------------------------- */
.carte--danger { border-color: var(--erreur); }
.carte--danger .carte__titre { color: var(--erreur); }

/* --------------------------------------------------------------------------
   12. Offre
   --------------------------------------------------------------------------
   Aucune mise en avant agressive : pas de « recommandé », pas de prix barré,
   pas de compte à rebours. Le public de ce site prend déjà des décisions sous
   pression par ailleurs ; en ajouter ici serait indéfendable.
   -------------------------------------------------------------------------- */

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

.offre {
    display: flex;
    flex-direction: column;
    padding: var(--e-5);
    background: var(--carte);
    border: 1px solid var(--trait);
    border-radius: var(--rayon-lg);
}

.offre__nom { margin: 0 0 var(--e-3); font-size: var(--t-md); font-weight: 600; }

.offre__prix {
    margin: 0 0 var(--e-2);
    font-size: 1.875rem;
    font-weight: 620;
    line-height: 1.1;
    letter-spacing: -0.025em;
    font-variant-numeric: tabular-nums;
}

.offre__intervalle {
    display: block;
    margin-top: var(--e-1);
    font-size: var(--t-sm);
    font-weight: 500;
    letter-spacing: 0;
    color: var(--encre-tenue);
}

.offre__note {
    margin: 0 0 var(--e-5);
    font-size: var(--t-sm);
    line-height: 1.55;
    color: var(--encre-douce);
    flex: 1;
}

/* --------------------------------------------------------------------------
   13. Accueil
   -------------------------------------------------------------------------- */
.heros {
    padding-block: var(--e-9) var(--e-8);
    background:
        radial-gradient(80% 60% at 8% 0%, var(--lagune-voile) 0%, transparent 60%),
        var(--papier);
}

.heros__titre {
    font-size: var(--t-2xl);
    max-width: 16ch;
    margin-bottom: var(--e-5);
}

.heros__chapeau {
    font-size: var(--t-lg);
    line-height: 1.55;
    color: var(--encre-douce);
    max-width: 44ch;
    margin-bottom: var(--e-6);
}

.heros__actions { display: flex; flex-wrap: wrap; gap: var(--e-3); }

/* Engagement de confidentialité : liste à filet, pas de puces décoratives.
   Le filet encode une vraie idée — une limite, une frontière. */
.engagements { list-style: none; padding: 0; margin: 0; }
.engagements li {
    padding: var(--e-4) 0 var(--e-4) var(--e-5);
    border-left: 2px solid var(--sable);
    position: relative;
}
.engagements li + li { border-top: 1px solid var(--trait); }
.engagements strong { display: block; margin-bottom: var(--e-1); }

@media (prefers-color-scheme: dark) {
    .engagements li { border-left-color: var(--ocre); }
}

/* --------------------------------------------------------------------------
   14. Communauté
   --------------------------------------------------------------------------
   Aucun élément de gamification : pas de badge, pas de classement, pas de
   compteur de réputation. On ne récompense pas le volume de publication sur
   des récits de situations difficiles.
   -------------------------------------------------------------------------- */

.regles {
    padding: var(--e-5);
    background: var(--lagune-voile);
    border-radius: var(--rayon-lg);
}

.regles__titre { margin: 0 0 var(--e-4); font-size: var(--t-md); font-weight: 650; }

.regles__liste { margin: 0; padding-left: var(--e-5); }
.regles__liste li { margin-bottom: var(--e-3); font-size: var(--t-sm); line-height: 1.6; color: var(--encre-douce); }
.regles__liste li:last-child { margin-bottom: 0; }
.regles__liste strong { color: var(--encre); }

.discussions { list-style: none; padding: 0; margin: 0; }

.discussion {
    padding: var(--e-5) 0;
    border-top: 1px solid var(--trait);
}
.discussion:last-child { border-bottom: 1px solid var(--trait); }

.discussion__titre { margin: 0 0 var(--e-2); font-size: var(--t-md); font-weight: 600; line-height: 1.35; }
.discussion__titre a { color: var(--encre); text-decoration: none; }
.discussion__titre a:hover { color: var(--lagune); text-decoration: underline; }

.discussion__extrait {
    margin: 0 0 var(--e-3);
    font-size: var(--t-sm);
    line-height: 1.6;
    color: var(--encre-douce);
    max-width: 68ch;
}

.discussion__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--e-4);
    margin: 0;
    font-size: var(--t-xs);
    color: var(--encre-tenue);
}

.message-corps {
    font-size: var(--t-md);
    line-height: 1.7;
    color: var(--encre);
    max-width: 68ch;
    overflow-wrap: anywhere;
}

.actions-message {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--e-2);
    margin-top: var(--e-5);
    padding-top: var(--e-4);
    border-top: 1px solid var(--trait);
}

.signalement summary { cursor: pointer; list-style: none; }
.signalement summary::-webkit-details-marker { display: none; }

.signalement__form {
    margin-top: var(--e-3);
    padding: var(--e-4);
    background: var(--brume);
    border-radius: var(--rayon);
    min-width: min(100%, 22rem);
}

.reponses { list-style: none; padding: 0; margin: var(--e-4) 0 0; }

.reponse {
    padding: var(--e-4) 0 var(--e-4) var(--e-4);
    border-left: 2px solid var(--trait);
    margin-bottom: var(--e-3);
}
.reponse .message-corps { margin-top: var(--e-2); font-size: var(--t-sm); }

/* --------------------------------------------------------------------------
   15. Administration et modération
   --------------------------------------------------------------------------
   Volontairement distinct de l'espace membre : bandeau indigo sombre, densité
   plus forte. Quelqu'un qui gère plusieurs onglets doit savoir en un coup
   d'œil s'il agit comme membre ou comme modérateur.
   -------------------------------------------------------------------------- */

.entete-admin {
    background: linear-gradient(160deg, var(--indigo) 0%, var(--indigo-nuit) 100%);
    color: #EAF0F7;
    position: sticky;
    top: 0;
    z-index: 20;
}

.entete-admin__interieur {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--e-4);
    min-height: 60px;
    padding-block: var(--e-2);
}

/* center, et non baseline : un logo n'a pas de ligne d'écriture sur laquelle
   s'aligner, il se centrerait de travers. */
.entete-admin__marque { display: flex; align-items: center; gap: var(--e-3); }

.entete-admin__titre {
    font-family: var(--titre);
    font-optical-sizing: auto;
    font-size: 1.125rem;
    font-weight: 620;
    letter-spacing: -0.03em;
    color: #FFF;
}

.entete-admin__role {
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgb(234 240 247 / 70%);
}

.nav-admin { display: flex; flex-wrap: wrap; gap: var(--e-1); }

.nav-admin a {
    padding: var(--e-2) var(--e-3);
    font-size: var(--t-sm);
    font-weight: 500;
    color: rgb(234 240 247 / 82%);
    text-decoration: none;
    border-radius: var(--rayon);
}
.nav-admin a:hover { background: rgb(255 255 255 / 10%); color: #FFF; }
.nav-admin a[aria-current="page"] { background: rgb(255 255 255 / 16%); color: #FFF; }
.nav-admin__sortie { margin-left: var(--e-3); border-left: 1px solid rgb(255 255 255 / 20%); }

/* Statistiques ---------------------------------------------------------------- */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
    gap: var(--e-3);
    margin-block: var(--e-5);
}

.stat {
    padding: var(--e-4);
    background: var(--carte);
    border: 1px solid var(--trait);
    border-radius: var(--rayon);
}

.stat__libelle {
    margin: 0 0 var(--e-2);
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--encre-tenue);
}

.stat__valeur {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.stat__note { margin: var(--e-2) 0 0; font-size: var(--t-xs); color: var(--encre-tenue); }

/* Tableaux d'administration ----------------------------------------------------- */
.tableau-admin {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-sm);
    margin-block: var(--e-4);
}

.tableau-admin th,
.tableau-admin td {
    padding: var(--e-3);
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--trait);
}

.tableau-admin thead th {
    font-size: var(--t-xs);
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--encre-tenue);
    white-space: nowrap;
}

.tableau-admin tbody tr:hover { background: var(--brume); }
.tableau-admin code { font-size: var(--t-xs); word-break: break-all; }

/* Décisions de modération ---------------------------------------------------------- */
.decision { padding-top: var(--e-4); border-top: 1px solid var(--trait); }

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


/* ==========================================================================
   16. Mouvement
   --------------------------------------------------------------------------
   Le mouvement sert à faire APPARAÎTRE, jamais à attirer. Rien ne clignote,
   rien ne rebondit, rien ne boucle. Le public de ce site arrive souvent
   inquiet ; une interface qui s'agite ajoute à la charge au lieu de l'alléger.

   Tout est désactivé par prefers-reduced-motion, sans exception.
   ========================================================================== */

/* L'état masqué n'existe QUE si JavaScript a pris la main (classe posée sur
   <html> par init.js). Sans JavaScript, tout reste visible : une page dont le
   contenu ne s'affiche jamais faute de script serait un défaut, pas un effet. */
.js [data-revele] {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity .8s cubic-bezier(.2, .7, .3, 1),
                transform .8s cubic-bezier(.2, .7, .3, 1);
}

.js [data-revele].est-visible { opacity: 1; transform: none; }

.js [data-revele][data-delai="1"] { transition-delay: .1s; }
.js [data-revele][data-delai="2"] { transition-delay: .2s; }
.js [data-revele][data-delai="3"] { transition-delay: .3s; }
.js [data-revele][data-delai="4"] { transition-delay: .4s; }

@media (prefers-reduced-motion: reduce) {
    .js [data-revele] { opacity: 1; transform: none; transition: none; }
}

/* ==========================================================================
   17. Photographies
   --------------------------------------------------------------------------
   Chaque emplacement affiche un DÉGRADÉ tant qu'aucun fichier n'est déposé.

   Ce n'est pas un pis-aller : un dégradé profond, texturé et bien composé est
   une image à part entière. La page est présentable avant même la première
   photo, et déposer un fichier dans public/assets/img/photos/ le remplace sans
   toucher au code (voir la fonction photo() dans app/helpers.php).

   Les dégradés sont construits en couches — deux halos radiaux sur une base
   linéaire — ce qui produit une profondeur que n'a jamais un dégradé simple.
   Un grain fin par-dessus supprime les cassures de bandes.
   ========================================================================== */

.media {
    position: relative;
    overflow: hidden;
    border-radius: var(--rayon-lg);
    box-shadow: var(--ombre-2);
    background:
        radial-gradient(78% 60% at 18% 12%, #2E5A9E 0%, transparent 62%),
        radial-gradient(66% 52% at 88% 84%, #A85A28 0%, transparent 58%),
        linear-gradient(158deg, #1B3B6F 0%, #0B1A2E 100%);
}

/* Variantes : chaque bloc a sa lumière propre, sinon la page se répète. */
.media--aube {
    background:
        radial-gradient(72% 58% at 78% 16%, #E0A472 0%, transparent 58%),
        radial-gradient(80% 62% at 12% 88%, #0B6E6D 0%, transparent 60%),
        linear-gradient(168deg, #2E5A9E 0%, #10233A 100%);
}

.media--lagune {
    background:
        radial-gradient(74% 60% at 22% 82%, #0B6E6D 0%, transparent 62%),
        radial-gradient(64% 50% at 82% 18%, #E8DCC8 0%, transparent 52%),
        linear-gradient(150deg, #12294D 0%, #0B1A2E 100%);
}

.media--terre {
    background:
        radial-gradient(70% 56% at 24% 20%, #C8763C 0%, transparent 58%),
        radial-gradient(72% 58% at 84% 86%, #1B3B6F 0%, transparent 62%),
        linear-gradient(172deg, #8A5A33 0%, #10233A 100%);
}

/* Grain : un dégradé plat paraît toujours bon marché. Le bruit lui donne de la
   matière et supprime les cassures de bandes sur les écrans 8 bits. */
.media::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    opacity: .5;
    mix-blend-mode: overlay;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23b)' opacity='.42'/%3E%3C/svg%3E");
}

/* La trame indigo, très atténuée : le motif du site traverse jusqu'aux images. */
.media::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background-image:
        repeating-linear-gradient(90deg, rgb(255 255 255 / 5%) 0 1px, transparent 1px 11px),
        repeating-linear-gradient(0deg,  rgb(255 255 255 / 3.5%) 0 1px, transparent 1px 11px);
    mask-image: radial-gradient(120% 90% at 25% 15%, #000 0%, transparent 76%);
}

/* La photographie, une fois déposée, recouvre tout le dégradé. */
.media img {
    position: relative;
    z-index: 3;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media--paysage { aspect-ratio: 8 / 5; }
.media--carre   { aspect-ratio: 1 / 1; }
.media--haut    { aspect-ratio: 4 / 5; }

/* ==========================================================================
   18. Le héros, en pleine image
   ========================================================================== */

.heros {
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: clamp(30rem, 74vh, 46rem);
    padding-block: var(--e-9) var(--e-8);
    overflow: hidden;
    isolation: isolate;
    color: #FFF;
    background:
        radial-gradient(70% 55% at 76% 14%, #E0A472 0%, transparent 56%),
        radial-gradient(84% 66% at 10% 86%, #0B6E6D 0%, transparent 62%),
        linear-gradient(163deg, #2E5A9E 0%, #10233A 55%, #0B1A2E 100%);
}

.heros__photo {
    position: absolute;
    inset: 0;
    z-index: -3;
}
.heros__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Voile : garantit la lisibilité du texte quelle que soit la photo déposée,
   claire ou sombre. Sans lui, une image lumineuse rendrait le titre illisible. */
.heros::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -2;
    /* Deux voiles, pas un. Le premier monte du bas, là où se pose le texte ;
       le second traverse en diagonale et laisse respirer le coin haut droit
       de la photo. Un voile uniforme éteindrait l'image entière pour protéger
       trois lignes de titre. */
    background:
        linear-gradient(to top,
            rgb(8 20 36 / 94%) 0%,
            rgb(8 20 36 / 88%) 26%,
            rgb(8 20 36 / 58%) 52%,
            rgb(8 20 36 / 18%) 78%,
            rgb(8 20 36 / 6%) 100%),
        linear-gradient(102deg,
            rgb(11 26 46 / 58%) 0%,
            rgb(11 26 46 / 26%) 52%,
            rgb(11 26 46 / 0%) 100%);
}

/* Il n'y a PAS de trame SVG surimposée ici. Elle y était tant que le héros
   n'avait qu'un dégradé : il fallait bien lui donner de la matière. La
   photographie déposée est un mur de tissus teints à l'indigo — une trame
   réelle, à la main. Superposer un quadrillage dessiné par-dessus reviendrait
   à mettre un faux tissage sur un vrai. On retire. */

.heros__contenu { position: relative; max-width: 40rem; }

.heros .surtitre { color: var(--sable); }

.heros__titre {
    /* 3,5 lignes de titre sont une erreur de corps, jamais de texte : le
       plafond est calé pour que « Y voir clair, à votre rythme. » tienne en
       deux lignes du téléphone au grand écran. */
    font-size: clamp(2.375rem, 1.35rem + 4.2vw, 4.25rem);
    line-height: 1.04;
    letter-spacing: -0.032em;
    font-weight: 620;
    color: #FFF;
    margin-bottom: var(--e-5);
    text-shadow: 0 2px 30px rgb(11 26 46 / 45%);
}

.heros__chapeau {
    font-size: clamp(1.0625rem, 1rem + .5vw, 1.375rem);
    line-height: 1.55;
    color: rgb(255 255 255 / 86%);
    max-width: 34rem;
    margin-bottom: var(--e-6);
}

.heros__actions { display: flex; flex-wrap: wrap; gap: var(--e-3); }

.heros .bouton--secondaire {
    color: #FFF;
    background: rgb(255 255 255 / 12%);
    border-color: rgb(255 255 255 / 32%);
    backdrop-filter: blur(4px);
}
.heros .bouton--secondaire:hover {
    background: rgb(255 255 255 / 22%);
    border-color: rgb(255 255 255 / 55%);
    color: #FFF;
}

/* Bande d'engagements, immédiatement sous le héros.
   Elle y est parce qu'elle N'EST PAS dans le héros : « gratuit, chiffré,
   effaçable » est une promesse à tenir, pas un slogan à glisser sous un
   bouton. Le héros dit une chose ; cette bande en dit trois, à sa place. */
.bande-garanties {
    border-block: 1px solid var(--trait);
    background: var(--carte);
}

.bande-garanties ul {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: var(--e-4) var(--e-6);
    list-style: none;
    margin: 0;
    padding: var(--e-5) 0;
}

.bande-garanties li {
    display: flex;
    gap: var(--e-3);
    align-items: baseline;
    font-size: var(--t-sm);
    line-height: 1.5;
    color: var(--encre-douce);
}

/* Le trait ocre remplace la puce : il marque une limite, ce qui est
   exactement le sujet de la ligne qu'il précède. */
.bande-garanties li::before {
    content: "";
    flex: 0 0 1.25rem;
    height: 2px;
    background: var(--ocre);
    transform: translateY(-0.3em);
}

.bande-garanties strong {
    font-family: var(--titre);
    font-weight: 650;
    color: var(--encre);
}

/* Soulignement ocre du mot fort.
   text-decoration plutôt qu'un pseudo-élément positionné : le navigateur cale
   le trait sous la ligne de base et l'écarte des jambages. Un ::after posé à
   « bottom: .1em » traverse les lettres dès que le corps change, et le corps
   change ici à chaque largeur d'écran. */
.tisse {
    white-space: nowrap;
    text-decoration: underline;
    text-decoration-color: var(--ocre);
    text-decoration-thickness: .085em;
    text-underline-offset: .1em;
    text-decoration-skip-ink: none;
}

/* ==========================================================================
   19. Sections alternées texte / image
   ========================================================================== */

.bloc {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--e-6);
    align-items: center;
}

@media (min-width: 58rem) {
    .bloc { grid-template-columns: 1fr 1fr; gap: clamp(var(--e-6), 5vw, var(--e-8)); }
    .bloc--inverse .bloc__media { order: -1; }
}

.bloc__texte { max-width: 42ch; }
.bloc__texte h2 { font-size: clamp(1.625rem, 1.2rem + 1.6vw, 2.25rem); }

.section--matiere {
    background:
        repeating-linear-gradient(90deg, rgb(27 59 111 / 4%) 0 1px, transparent 1px 14px),
        repeating-linear-gradient(0deg,  rgb(27 59 111 / 3%) 0 1px, transparent 1px 14px),
        var(--brume);
}

/* Bandeau pleine largeur, texte en surimpression */
.bandeau {
    position: relative;
    min-height: clamp(18rem, 38vw, 28rem);
    display: flex;
    align-items: flex-end;
    padding: var(--e-6);
}

.bandeau__texte { position: relative; z-index: 4; max-width: 46ch; color: #FFF; }
.bandeau__texte h2 { color: #FFF; margin-bottom: var(--e-3); }
.bandeau__texte p  { margin: 0; color: rgb(255 255 255 / 88%); line-height: 1.6; }
/* Même spécificité que la règle p ci-dessus (0,2,0) et placée après :
   c'est ce qui la fait gagner, sans !important. */
.bandeau__texte .bandeau__action { margin-top: var(--e-5); }

.bandeau .media-fond {
    position: absolute;
    inset: 0;
    z-index: 0;
    border-radius: inherit;
}

.bandeau::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    border-radius: inherit;
    background: linear-gradient(to top, rgb(11 26 46 / 86%) 0%, rgb(11 26 46 / 30%) 55%, transparent 100%);
}

/* Lisière tissée entre deux sections — bordure de pagne, pas filet gris */
.lisiere {
    height: 12px;
    border: 0;
    margin: 0;
    background:
        linear-gradient(var(--ocre), var(--ocre)) 0 0 / 100% 2px no-repeat,
        linear-gradient(var(--ocre), var(--ocre)) 0 100% / 100% 2px no-repeat,
        repeating-linear-gradient(90deg, var(--indigo) 0 2px, transparent 2px 7px);
    opacity: .3;
}

/* Repères chiffrés */
.reperes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    gap: var(--e-6);
}

.repere { padding-left: var(--e-4); border-left: 2px solid var(--ocre); }

.repere__valeur {
    margin: 0 0 var(--e-2);
    font-family: var(--titre);
    font-optical-sizing: auto;
    font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
    font-weight: 620;
    line-height: 1.05;
    letter-spacing: -0.03em;
    color: var(--indigo);
}

@media (prefers-color-scheme: dark) { .repere__valeur { color: var(--lagune); } }

.repere__texte { margin: 0; font-size: var(--t-sm); line-height: 1.55; color: var(--encre-douce); }

/* Micro-interactions */
.carte {
    transition: transform .25s cubic-bezier(.2, .7, .3, 1), box-shadow .25s ease, border-color .25s ease;
}
.carte:hover {
    transform: translateY(-3px);
    box-shadow: var(--ombre-2);
    border-color: color-mix(in srgb, var(--lagune) 35%, var(--trait));
}

.media { transition: transform .5s cubic-bezier(.2, .7, .3, 1); }
.bloc__media:hover .media { transform: scale(1.012); }

@media (prefers-reduced-motion: reduce) {
    .carte, .carte:hover, .media, .bloc__media:hover .media { transform: none; transition: none; }
}

/* Pièces jointes vues par un modérateur ou un administrateur.
   Volontairement austère : des boutons, pas des vignettes. Ce qui s'affiche
   sans être demandé finit par être vu sans être décidé. */
.pieces-moderation {
    margin-top: var(--e-4);
    padding-top: var(--e-3);
    border-top: 1px dashed var(--trait);
}

.piece-moderation { display: inline-block; margin: var(--e-2) var(--e-2) 0 0; }

/* Paires libellé / valeur — état d'un service, dans l'administration.
   Une définition list plutôt qu'un tableau : ce sont des couples, pas des
   lignes comparables entre elles. */
.paires {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--e-2) var(--e-5);
    margin: 0;
    align-items: baseline;
}

.paires dt {
    font-size: var(--t-sm);
    color: var(--encre-tenue);
}

.paires dd {
    margin: 0;
    font-size: var(--t-sm);
}

/* --------------------------------------------------------------------------
   Audience — graphiques en CSS pur
   --------------------------------------------------------------------------
   La politique de sécurité de contenu interdit unsafe-inline et tout script
   distant : aucune bibliothèque de graphiques n'est chargeable. Des barres en
   CSS se lisent aussi bien, ne coûtent aucun octet de plus, et le tableau qui
   les accompagne les rend accessibles au lecteur d'écran.
   -------------------------------------------------------------------------- */
.histogramme {
    display: flex;
    align-items: flex-end;
    gap: 2px;
    height: 140px;
    padding-top: var(--e-3);
}

.histogramme__barre {
    flex: 1 1 0;
    min-width: 2px;
    background: var(--indigo);
    border-radius: 2px 2px 0 0;
    opacity: .85;
    transition: opacity .12s ease;
}

.histogramme__barre:hover { opacity: 1; }

@media (prefers-color-scheme: dark) {
    .histogramme__barre { background: var(--lagune); }
}

.repartition { width: 100%; border-collapse: collapse; }

.repartition th {
    text-align: left;
    font-weight: 500;
    font-size: var(--t-sm);
    padding: var(--e-2) var(--e-3) var(--e-2) 0;
    white-space: nowrap;
}

.repartition td { padding: var(--e-2) 0; font-size: var(--t-sm); }

.repartition .nombre {
    text-align: right;
    padding-left: var(--e-3);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* La jauge prend toute la place restante : c'est elle qui porte la comparaison
   visuelle, les colonnes chiffrées ne font que la confirmer. */
.repartition__jauge {
    width: 100%;
    padding-inline: var(--e-2);
}

.repartition__jauge span {
    display: block;
    height: 8px;
    min-width: 2px;
    border-radius: 999px;
    background: var(--lagune);
}

/* --------------------------------------------------------------------------
   Tableaux sur petit écran
   --------------------------------------------------------------------------
   Deux formes de tableaux coexistent sur le site, et elles n'ont pas le même
   problème en petite largeur :

    .tableau-fiches   des paires libellé / valeur (« Responsable de traitement
                      → Untel »). Sur un téléphone, elles S'EMPILENT : le
                      libellé au-dessus, la valeur en dessous. Un défilement
                      horizontal serait ici une régression — on lit ces lignes
                      une par une, pas en les comparant entre elles.

    .tableau-defilant un vrai tableau de données, dont les colonnes se
                      comparent. Empiler le rendrait illisible : il DÉFILE
                      dans son propre cadre, sans jamais faire défiler la page.

   Règle tenue dans les deux cas : le corps de la page ne défile jamais
   horizontalement. Une page qui glisse latéralement sous le pouce donne
   l'impression d'être cassée, et elle l'est.
   -------------------------------------------------------------------------- */
.tableau-fiches {
    width: 100%;
    margin-top: var(--e-5);
    border-collapse: collapse;
    font-size: var(--t-sm);
}

.tableau-fiches th,
.tableau-fiches td {
    padding: var(--e-3) var(--e-2);
    text-align: left;
    border-bottom: 1px solid var(--trait);
    vertical-align: top;
}

.tableau-fiches th {
    font-weight: 600;
    color: var(--encre-douce);
    width: 34%;
}

/* Les mots longs — adresses, noms d'organismes — cassent plutôt que de
   pousser la colonne au-delà de l'écran. */
.tableau-fiches td { overflow-wrap: anywhere; }

@media (max-width: 40rem) {
    .tableau-fiches,
    .tableau-fiches tbody,
    .tableau-fiches tr,
    .tableau-fiches th,
    .tableau-fiches td { display: block; width: auto; }

    .tableau-fiches tr {
        padding-block: var(--e-3);
        border-bottom: 1px solid var(--trait);
    }

    .tableau-fiches th {
        padding: 0 0 var(--e-1);
        border: 0;
        font-size: var(--t-xs);
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--encre-tenue);
    }

    .tableau-fiches td { padding: 0; border: 0; }
}

/* Cadre défilant pour les vrais tableaux de données. */
.tableau-defilant {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Indique qu'il y a quelque chose à faire glisser plutôt que de le laisser
       deviner : sans repère, on ne cherche pas à faire défiler un tableau. */
    background:
        linear-gradient(to right, var(--papier) 30%, rgb(255 255 255 / 0)) left / 40px 100% no-repeat,
        linear-gradient(to left,  var(--papier) 30%, rgb(255 255 255 / 0)) right / 40px 100% no-repeat;
}

.tableau-defilant > table { min-width: 32rem; }
