/* ============================================================================================
   TickDoc · feuille unique
   ============================================================================================

   ── CE QUI A CHANGÉ PAR RAPPORT À LA PREMIÈRE VITRINE, ET POURQUOI ──────────────────────────

   La précédente a été abandonnée sur un verdict sans appel : « plus on modifie plus c'est nul ».
   Trois causes, identifiées avant de redessiner quoi que ce soit.

   1. DES CARTES VASTES ET VIDES. Six lignes de texte dans un cadre de quatre cents pixels de haut :
      le blanc ne faisait pas respirer le contenu, il signalait qu'il en manquait. Ici, une carte se
      dimensionne sur ce qu'elle contient, jamais l'inverse.

   2. DES ILLUSTRATIONS QUI N'ÉTAIENT PAS LE PRODUIT. Des schémas au trait, des flèches, des libellés
      à onze pixels. La seule que Pierrick trouvait bonne était la maquette de l'écran du destinataire.
      Le produit est donc devenu le matériau principal : la moitié des sections porte un fragment
      d'interface réel, en HTML, pas un dessin qui l'explique.

   3. UN TEXTE LONG ET PLAT. Vingt-deux blocs de même poids, où rien n'attirait l'œil sur ce qui
      distingue vraiment l'outil. L'échelle typographique est ici franche, et chaque section porte UNE
      idée.

   ── LES RÈGLES QUI NE SE NÉGOCIENT PAS ──────────────────────────────────────────────────────

   Aucune requête vers un service tiers : ni police, ni script, ni image. C'est ce qui permet de ne pas
   afficher de bandeau de consentement, et c'est ce que la page « Données personnelles » affirme.

   ⚠️ Le vert #12A06A donne 3,35:1 sur blanc : il n'est JAMAIS du texte. Fond de bouton, coche, pastille,
   très gros caractère. Les liens sont en #0C7C52, qui donne 5,22:1.

   ⚠️ Toute règle de conteneur visant un élément générique doit exclure les composants qu'elle peut
   contenir : `.nav a:not(.btn)`. Un sélecteur `classe + élément` pèse 0,1,1 et bat une `classe` seule à
   0,1,0. Cette collision a livré un bouton à 2:1 sur la vitrine précédente.

   ⚠️ L'apparition au défilement n'anime que la POSITION, jamais l'opacité : un fondu part de
   `opacity: 0`, et il suffit que la frise ne progresse pas pour qu'une section reste invisible.

   ── PRÉVU POUR DEUX LANGUES DÈS MAINTENANT ──────────────────────────────────────────────────

   Rien ici ne dépend du français. Les pages vivent sous `/fr/`, les futures sous `/en/` · aucune
   dimension n'est calée sur la longueur d'un mot français, et les composants qui portent du texte
   acceptent deux lignes sans casser.
   ============================================================================================ */

:root {
    --ink: #12232B;
    --ink-deep: #0A161C;
    --slate: #405A66;
    --slate-soft: #5A717C;

    --green: #12A06A;
    --green-deep: #0C7C52;
    --green-wash: #F1F8F4;

    --amber: #8A6100;
    --amber-wash: #FCF4E4;

    --page: #FBFCFC;
    --surface: #FFFFFF;
    --raised: #F3F6F5;
    --border: #E4EAE8;
    --border-firm: #C9D4D1;

    --measure: 62ch;

    --r-sm: 10px;
    --r-md: 14px;
    --r-lg: 22px;
    --r-xl: 30px;

    --sh-1: 0 1px 2px rgba(18, 35, 43, 0.05);
    --sh-2: 0 1px 2px rgba(18, 35, 43, 0.05), 0 12px 28px -16px rgba(18, 35, 43, 0.2);
    --sh-3: 0 2px 6px rgba(18, 35, 43, 0.06), 0 28px 60px -28px rgba(18, 35, 43, 0.32);

    /*
        Aucune police distante. Segoe UI Variable Display sous Windows, SF Pro Display sous macOS : deux
        géométriques déjà installées. On obtient le caractère voulu sans facturer un téléchargement au
        visiteur, ni ouvrir une requête vers un tiers.
    */
    --font: "Segoe UI Variable Display", "SF Pro Display", -apple-system, BlinkMacSystemFont,
        "Segoe UI", system-ui, sans-serif;
    --mono: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--page);
    color: var(--ink);
    font-family: var(--font);
    font-size: 17px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;
}

img,
svg {
    display: block;
    max-width: 100%;
}

/* ── Échelle typographique ──────────────────────────────────────────────────────────────────── */

/*
    Franche, exprès. Sur la vitrine précédente, un h1 et un h2 se distinguaient à peine, et une page
    entière se lisait donc comme un seul bloc gris. Ici, chaque niveau se voit de loin.
*/
h1,
h2,
h3 {
    margin: 0;
    letter-spacing: -0.028em;
    line-height: 1.12;
    font-weight: 700;
}

h1 {
    font-size: clamp(2.45rem, 1.4rem + 3.6vw, 4.1rem);
}

h2 {
    font-size: clamp(1.85rem, 1.2rem + 2.1vw, 2.7rem);
}

h3 {
    font-size: 1.12rem;
    line-height: 1.35;
    letter-spacing: -0.015em;
}

p {
    margin: 0 0 1.05rem;
    max-width: var(--measure);
}

a {
    color: var(--green-deep);
    text-underline-offset: 3px;
}

strong {
    font-weight: 650;
}

:focus-visible {
    outline: 3px solid var(--green-deep);
    outline-offset: 3px;
    border-radius: 8px;
}

/* ── Le lien d'évitement, premier élément focalisable de chaque page ────────────────────────── */

.skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 0.85rem 1.2rem;
    background: var(--ink);
    color: #fff;
    border-radius: 0 0 var(--r-md) 0;
    text-decoration: none;
    font-weight: 600;
}

.skip:focus {
    left: 0;
}

/* ── Trame ──────────────────────────────────────────────────────────────────────────────────── */

.wrap {
    width: min(100% - 2.5rem, 74rem);
    margin-inline: auto;
}

section {
    padding: clamp(3.6rem, 2rem + 5vw, 6.4rem) 0;
}

.tint {
    background: var(--raised);
}

.dark {
    background: var(--ink-deep);
    color: #DCE6E9;
}

.dark h1,
.dark h2,
.dark h3,
.dark strong {
    color: #fff;
}

/*
    ⚠️ Position seulement, jamais l'opacité : voir l'entête. Et sous `prefers-reduced-motion`, rien
    ne bouge du tout.
*/
@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
        .rise {
            animation: rise-in linear both;
            animation-timeline: view();
            animation-range: entry 8% cover 26%;
        }

        @keyframes rise-in {
            from {
                transform: translateY(22px);
            }
            to {
                transform: none;
            }
        }
    }
}

/* ── Entête ─────────────────────────────────────────────────────────────────────────────────── */

.masthead {
    position: sticky;
    top: 0;
    z-index: 40;
    background: rgba(251, 252, 252, 0.86);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border);
}

/*
    ⚠️ LA GOUTTIÈRE EST RESSERRÉE SOUS 48 rem, POUR UN PIXEL. Mesuré à 320 px avec la coquille
    refondue : logo 105 + gouttière 22,4 + bouton 159 = 286,4 px depuis x=20, soit un bord droit à
    306 pour 305 disponibles. Un pixel donne la même barre de défilement horizontale que cinquante.
    Sous 48 rem seuls le logo et le bouton s'affichent, les six liens étant masqués : la gouttière
    n'y sépare donc que deux éléments et peut être plus courte.
*/
.masthead .wrap {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-height: 76px;
}

@media (min-width: 48rem) {
    .masthead .wrap {
        gap: 1.4rem;
    }
}

/*
    ⚠️ Le signe et le mot ont été agrandis à la demande de Pierrick. Les deux ENSEMBLE : grossir l'image
    seule aurait déséquilibré le couple, le mot paraissant alors une légende du signe au lieu d'en être
    la moitié.
*/
.logo {
    display: flex;
    align-items: center;
    min-height: 48px;
    gap: 0.66rem;
    text-decoration: none;
    color: var(--ink);
    font-size: 1.62rem;
    letter-spacing: -0.03em;
    margin-right: auto;
}

.logo b {
    font-weight: 700;
}

.logo span {
    font-weight: 400;
}

.nav {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/*
    ⚠️ `:not(.btn)` : sans cette exclusion, cette règle de conteneur (0,1,1) écraserait `.btn-primary`
    (0,1,0) et le bouton d'appel s'afficherait en encre sur vert, soit 2:1. C'est exactement ce qui a
    été livré une fois sur la vitrine précédente.
*/
/*
    ⚠️ 44 px de haut, exigence du RGAA pour une cible tactile. Le rembourrage seul donnait 42 px : deux
    pixels qui ne se voient pas à l'œil et se ratent au doigt. Mesuré, pas estimé.
*/
/*
    ⚠️ `nowrap` OU LA MESURE MENT. Sans lui, un lien de menu est un élément flexible dont le
    `min-width: auto` vaut son mot le plus long : la barre trouve à tenir EN REPLIANT SES LIBELLÉS,
    ce qui n'est pas tenir. Constaté sur la maquette à 992 et à 1 024 px, où « Comment ça marche »
    s'affichait sur deux lignes pendant que le document ne débordait plus et que les cibles gardaient
    leurs 44 px : le contrôle était vert et la barre était cassée. Avec `nowrap`, un manque de place
    ne peut plus se résoudre en silence — il déborde, il se mesure, il se corrige.
*/
.nav a:not(.btn) {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.55rem 0.75rem;
    border-radius: var(--r-sm);
    color: var(--slate);
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 550;
    white-space: nowrap;
}

.nav a:not(.btn):hover,
.nav a:not(.btn)[aria-current] {
    color: var(--ink);
    background: var(--raised);
}

/*
    ⚠️ HUITIÈME OCCURRENCE DU PIÈGE `:not()`, ET LA PLUS VISIBLE DE TOUTES.

    Ces deux règles s'écrivaient `.nav-hide`, soit (0,1,0). La règle de conteneur juste au-dessus,
    `.nav a:not(.btn)`, pèse (0,2,1) — un `:not()` prend la spécificité de son argument le plus fort —
    et son `display: inline-flex` écrasait donc le `display: none`.

    Conséquence : LA NAVIGATION N'A JAMAIS ÉTÉ MASQUÉE SUR TÉLÉPHONE. Six liens et un bouton
    s'alignaient sur 719 px dans une fenêtre de 390, ce qui donnait une BARRE DE DÉFILEMENT
    HORIZONTALE sur les huit pages du site, à toute largeur inférieure à 62 rem. La media query en
    dessous n'a jamais rien changé non plus, pour la même raison : elle réaffirmait une valeur déjà
    appliquée.

    Invisible sur un écran d'ordinateur, où la media query est vraie et le rendu correct. Trouvé en
    mesurant `scrollWidth` contre `innerWidth` dans un cadre de 390 px · ni une capture, ni un contrôle
    de contraste, ni le balayage des classes ne pouvaient le voir. Même famille que l'`<input
    type="file">` masqué qui élargissait le document de 378 px dans l'espace client.

    `.nav a.nav-hide` pèse (0,2,1), à égalité avec la règle de conteneur, et vient APRÈS elle : c'est
    l'ordre qui départage, donc elle gagne. Monter la spécificité plutôt qu'ajouter un `!important`,
    pour que la prochaine règle de conteneur se heurte au même arbitrage lisible.
*/
.nav a.nav-hide {
    display: none;
}

@media (min-width: 62rem) {
    .nav a.nav-hide {
        display: inline-flex;
    }
}

/* ── Menu de téléphone ──────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ POURQUOI CE MENU EXISTE. Les six entrées portent `nav-hide` et disparaissent sous 62 rem · le
    pied ne reprend pas l'accès à l'espace client, son commentaire disant que « ses deux liens sont
    déjà dans l'entête de chaque page ». C'était vrai à toute largeur SAUF celles où l'entête les
    masque, c'est-à-dire tous les téléphones. « Connexion » n'était donc atteignable nulle part, et un
    client qui revenait depuis son téléphone ne pouvait pas ouvrir son espace. Neuvième occurrence de
    « un commentaire décrit un mécanisme qui n'existe pas dans le cas qui compte ».

    ⚠️ CACHÉ SUR ORDINATEUR, où la barre porte déjà les six entrées : deux navigations visibles en
    même temps seraient deux fois la même chose, et le lecteur d'écran les annoncerait toutes les deux.
*/
.nav-menu {
    position: relative;
}

@media (min-width: 62rem) {
    .nav-menu {
        display: none;
    }
}

/*
    La bascule. `list-style: none` retire le triangle par défaut, et la ligne `::-webkit-details-marker`
    fait la même chose pour les moteurs WebKit qui l'ignorent encore.
*/
/*
    ⚠️ 44 PAR 44, ET UNE ICÔNE SEULE. Avec le mot « Menu » visible, l'entête débordait de 27 px en
    français et de 36 px en anglais à 390 px, et de 40 et 49 px à 320 px : le logo, la bascule et
    « Créer un compte » ne tiennent pas ensemble, et le libellé anglais est plus long. Une barre de
    défilement horizontale sur toutes les pages est le défaut que ce site a déjà payé deux fois.

    Le nom accessible du bouton est porté par un `<span class="visually-hidden">` : une icône ne
    fournit aucun nom, et un bouton sans nom est inutilisable au lecteur d'écran.
*/
.nav-bascule {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    color: var(--slate);
    cursor: pointer;
    list-style: none;
}

.nav-bascule::-webkit-details-marker {
    display: none;
}

.nav-bascule:hover,
.nav-menu[open] .nav-bascule {
    color: var(--ink);
    border-color: var(--ink);
}

/*
    Le panneau. `position: absolute` le fait flotter au-dessus de la page plutôt que de pousser le
    contenu vers le bas · `right: 0` l'aligne sur le bord de l'entête, faute de quoi il déborderait
    à droite sur les écrans les plus étroits.
*/
.nav-panneau {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 40;
    display: flex;
    flex-direction: column;
    min-width: 14rem;
    padding: 0.4rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: 0 18px 40px rgb(18 35 43 / 0.14);
}

/*
    ⚠️ TROIS CLASSES ET UN ÉLÉMENT, SOIT (0,3,1), ET CE N'EST PAS DÉCORATIF.

    La règle de conteneur `.nav a:not(.btn)` pèse **(0,2,1)** — un `:not()` prend la spécificité de son
    argument — et impose `display: inline-flex` et `white-space: nowrap`. Écrit `.nav-panneau a`, soit
    (0,1,1), ce bloc PERDRAIT et les entrées s'aligneraient en une seule ligne qui déborde. Écrit
    `.nav .nav-panneau a`, il pèse (0,2,1) : à ÉGALITÉ, donc départagé par le seul ordre du fichier,
    ce qui casse au premier déplacement de bloc. `:not(.btn)` porte la troisième classe et tranche
    la question pour de bon.

    C'est la NEUVIÈME occurrence de ce piège dans ce fichier, et la huitième est documentée trente
    lignes plus haut : elle avait laissé la navigation visible sur tous les téléphones pendant des
    semaines. Le style calculé a été mesuré après coup, pas déduit.
*/
.nav .nav-panneau a:not(.btn) {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0.55rem 0.7rem;
    border-radius: var(--r-sm);
    color: var(--slate);
    text-decoration: none;
    font-size: 0.97rem;
    font-weight: 550;
    white-space: normal;
}

.nav .nav-panneau a:not(.btn):hover,
.nav .nav-panneau a:not(.btn)[aria-current] {
    color: var(--ink);
    background: var(--raised);
}

/*
    ⚠️ AUCUNE ANIMATION D'OUVERTURE, à dessein. La règle de la vitrine est que l'apparition n'anime
    jamais l'opacité · et un panneau qui glisse sur le seul chemin vers l'espace client ne gagne rien
    à retarder son propre affichage. Rien à protéger sous `prefers-reduced-motion`, donc.

    ⚠️ ET AUCUN JAVASCRIPT NON PLUS : le menu est un `<details>`, donc le navigateur seul l'ouvre et
    le ferme, au clic comme au clavier. Conséquence assumée · il ne se ferme ni à l'échappement, ni
    au clic à côté. `tickdoc.js` n'étant chargé que par les deux pages de contact, un module qui
    ajouterait ces deux gestes serait mort sur les quatorze autres pages.
*/

/*
    ⚠️ L'ENTÊTE DÉBORDAIT ENCORE, ET SEULEMENT EN ANGLAIS À 390 PX. Trois éléments s'y disputent la
    largeur : le logo à 1,62 rem, la bascule de 44 px et « Créer un compte ». Mesuré après le passage
    de la bascule en icône seule : le français tenait à 390, l'anglais débordait de 7 px, et les deux
    débordaient à 320 — de 10 et 19 px. `Create an account` est plus long que `Créer un compte`, donc
    un réglage validé en français ne dit rien de l'anglais.

    ⚠️ 26 REM ET NON LE POINT DE RUPTURE DU MENU. Entre 416 et 992 px la place est largement suffisante
    et resserrer le logo n'y aurait aucun motif · c'est une correction pour les écrans étroits, pas une
    seconde direction graphique.

    ⚠️ TROIS CLASSES POUR LE BOUTON, SOIT (0,3,0), parce que `.btn` pèse (0,1,0) et que la règle doit
    gagner sans dépendre de l'ordre du fichier. Neuvième et dixième occurrences de cet arbitrage dans
    cette feuille.

    ⚠️ LA MARQUE `<img>` N'EST PAS TOUCHÉE : ses attributs `width` et `height` sont confrontés aux
    dimensions réelles du fichier par la douzième passe de `_controles.py`. Seul le mot se resserre.
*/
@media (max-width: 26rem) {
    .masthead .logo {
        font-size: 1.3rem;
    }

    /*
        ⚠️ L'ENFANT DIRECT SEULEMENT (`>`), sinon cette règle masquerait AUSSI la copie du bouton
        placée dans le panneau, et l'appel à l'action disparaîtrait de la page entière à 320 px.
        C'est le genre de sélecteur trop large qui rend un contrôle vert — plus de débordement — sur
        une page où le geste principal n'existe plus.
    */
    .masthead .nav > .btn {
        display: none;
    }
}

/*
    La copie du bouton dans le panneau ne sert QUE sous 26 rem · au-dessus, l'entête porte l'original,
    et deux boutons identiques à deux endroits seraient annoncés deux fois par un lecteur d'écran.
*/
/*
    ⚠️ DEUX CLASSES, SOIT (0,2,0), ET MESURÉ PLUTÔT QUE DÉDUIT. Écrite `.nav-panneau-cta`, cette règle
    pesait (0,1,0) — exactement comme `.btn { display: inline-flex }`, qui est déclaré PLUS BAS dans
    ce fichier et gagnait donc par le seul ordre. Constaté à 768 px : les DEUX copies du bouton
    s'affichaient, donc un lecteur d'écran annonçait deux fois le même geste. Onzième occurrence de
    cet arbitrage dans cette feuille, et la troisième trouvée en mesurant après avoir écrit un
    commentaire qui prévenait du risque.
*/
@media (min-width: 26.01rem) {
    .nav .nav-panneau-cta {
        display: none;
    }
}

/*
    Le bouton du panneau occupe toute sa largeur et se détache des six liens par un filet : c'est un
    geste d'une autre nature, et rien ne doit laisser croire qu'il mène à une septième page du site.
*/
.nav .nav-panneau-cta {
    margin-top: 0.4rem;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
    border-top: 1px solid var(--border);
    border-radius: var(--r-sm);
}

/* ── Boutons ────────────────────────────────────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 46px;
    padding: 0.7rem 1.15rem;
    border: 1px solid transparent;
    border-radius: var(--r-md);
    font: inherit;
    font-size: 0.98rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
}

.btn-primary {
    background: var(--green-deep);
    color: #fff;
}

.btn-primary:hover {
    background: #0A6A46;
}

.btn-ghost {
    background: var(--surface);
    border-color: var(--border-firm);
    color: var(--ink);
}

.btn-ghost:hover {
    border-color: var(--slate);
}

.dark .btn-ghost {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.28);
    color: #fff;
}

.actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    margin-top: 1.6rem;
}

/* ── Étiquette de section ───────────────────────────────────────────────────────────────────── */

.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.9rem;
    padding: 0.3rem 0.7rem 0.3rem 0.55rem;
    border-radius: 999px;
    background: var(--green-wash);
    color: var(--green-deep);
    font-size: 0.78rem;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--green);
}

.dark .eyebrow {
    background: rgba(18, 160, 106, 0.16);
    color: #7FE0B4;
}

.lead {
    font-size: clamp(1.06rem, 1rem + 0.3vw, 1.24rem);
    color: var(--slate);
    max-width: 54ch;
}

.dark .lead {
    color: #B9CBD1;
}

/* ── Héros ──────────────────────────────────────────────────────────────────────────────────── */

.hero {
    padding-top: clamp(2.8rem, 1.5rem + 4vw, 5rem);
    padding-bottom: clamp(3rem, 2rem + 4vw, 5.4rem);
}

.hero .wrap {
    display: grid;
    gap: clamp(2.4rem, 1rem + 5vw, 4rem);
    align-items: center;
}

@media (min-width: 62rem) {
    .hero .wrap {
        grid-template-columns: 1fr 26.5rem;
    }
}

.hero h1 {
    margin-bottom: 1.2rem;
}

/* Les trois preuves sous l'appel : elles répondent à « et mes données ? » avant qu'on la pose. */
.assurances {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    margin: 2rem 0 0;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    list-style: none;
    font-size: 0.92rem;
    color: var(--slate);
}

.assurances li {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.assurances svg {
    flex: none;
    color: var(--green);
}

/* ── Duo texte + maquette ───────────────────────────────────────────────────────────────────── */

/*
    Le motif de base du site : une idée à gauche, le produit à droite. Répété, il donne un rythme, et
    il évite la page de texte qui a fait échouer la version précédente.
*/
.duo {
    display: grid;
    gap: clamp(2rem, 1rem + 4vw, 3.4rem);
    align-items: center;
}

@media (min-width: 62rem) {
    .duo {
        grid-template-columns: 1fr 1fr;
    }

    .duo-flip > *:first-child {
        order: 2;
    }
}

.duo h2 {
    margin-bottom: 1rem;
}

/* ── Maquettes du produit ───────────────────────────────────────────────────────────────────── */

/*
    ⚠️ EN HTML, PAS EN CAPTURE. Une image se périme au premier changement d'interface, pèse, et floute
    sur un écran dense. En balisage elle reste nette, s'adapte à la largeur, se traduit, et se corrige
    en même temps que le produit.

    ⚠️ Toutes sont DÉCORATIVES : `aria-hidden` au balisage, parce que le texte de la section dit déjà ce
    qu'elles montrent. Les faire lire imposerait vingt fragments sans intérêt entre un titre et un
    bouton.
*/
/*
    ⚠️ `min-width: 0` N'EST PAS UNE PRÉCAUTION, C'EST CE QUI EMPÊCHE LA MAQUETTE DE DÉBORDER L'ÉCRAN.

    Un élément de grille vaut `min-width: auto` par défaut, c'est-à-dire la largeur MINIMALE DE SON
    CONTENU : il refuse de se réduire en dessous, et pousse alors sa colonne. Mesuré le 12 août 2026 à
    320 px sur la maquette ajoutée à la page d'accueil · 353 px dans une colonne de 265, donc une barre
    de défilement horizontale sur toute la page.

    La maquette du premier écran ne le montrait pas, et c'est ce qui rend le piège vicieux : elle ne
    déborde que si l'une de ses lignes contient un texte un peu plus long. Le défaut dort jusqu'au jour
    où quelqu'un allonge une phrase, et il apparaît alors sur une page qu'il n'a pas touchée.
*/
.shot {
    min-width: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-3);
    padding: 1.2rem;
}

/*
    ⚠️ LA MAQUETTE REPREND L'ENCRE SUR FOND SOMBRE, et ce n'est pas cosmétique.

    `.dark` pose une couleur de texte claire sur toute la section. La maquette, elle, garde son fond
    blanc pour se détacher · sans cette remise à zéro, tout son contenu s'affichait en gris très clair
    sur blanc, soit un contraste de l'ordre de 1,3:1. Le défaut ne se voit pas en lisant la feuille :
    la règle fautive est à cent lignes de là, et elle ne parle pas des maquettes.
*/
.dark .shot,
.dark .shot strong,
.dark .shot b {
    color: var(--ink);
}

.dark .shot {
    border-color: rgba(255, 255, 255, 0.14);
}

.dark .shot .row em,
.dark .shot .shot-foot,
.dark .shot .quote,
.dark .shot-head small {
    color: var(--slate);
}

.shot-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.9rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--border);
    margin-bottom: 1rem;
}

.shot-head strong {
    display: block;
    font-size: 0.98rem;
    letter-spacing: -0.015em;
}

.shot-head small {
    display: block;
    font-size: 0.82rem;
    color: var(--slate-soft);
    font-weight: 400;
}

.badge {
    flex: none;
    padding: 0.24rem 0.62rem;
    border-radius: 999px;
    font-size: 0.76rem;
    font-weight: 650;
    white-space: nowrap;
    background: rgba(64, 90, 102, 0.1);
    color: var(--slate);
}

.badge-ok {
    background: var(--green-wash);
    color: var(--green-deep);
}

.badge-wait {
    background: var(--amber-wash);
    color: var(--amber);
}

/* La barre de progression, à sa place exacte : le vert mesure ce qui est acquis. */
.bar {
    height: 7px;
    border-radius: 999px;
    background: rgba(18, 35, 43, 0.08);
    overflow: hidden;
}

.bar i {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--green);
}

.bar-note {
    margin: 0.5rem 0 1rem;
    font-size: 0.83rem;
    color: var(--slate);
}

.rows {
    display: grid;
    gap: 0.5rem;
}

.row {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.68rem 0.8rem;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    font-size: 0.9rem;
}

.row > b {
    flex: 1;
    min-width: 0;
    font-weight: 600;
}

.row em {
    flex: none;
    font-style: normal;
    font-size: 0.83rem;
    color: var(--slate);
}

.row-ok {
    border-color: rgba(18, 160, 106, 0.38);
    background: var(--green-wash);
}

.row-said {
    border-color: var(--border-firm);
    background: rgba(64, 90, 102, 0.045);
}

.quote {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.83rem;
    font-style: italic;
    color: var(--slate);
    font-weight: 400;
}

/* La pastille d'état d'une ligne. */
.pip {
    width: 21px;
    height: 21px;
    border-radius: 50%;
    flex: none;
    display: grid;
    place-items: center;
    color: #fff;
}

.pip-ok {
    background: var(--green);
}

.pip-said {
    background: var(--slate);
}

.pip-todo {
    border: 2px dashed var(--border-firm);
}

/* Le bouton d'un écran, dans la maquette. */
.shot-cta {
    margin-top: 1rem;
    padding: 0.72rem 0.9rem;
    border-radius: var(--r-md);
    background: var(--ink);
    color: #fff;
    font-size: 0.9rem;
    font-weight: 600;
    text-align: center;
}

.shot-cta-off {
    background: rgba(64, 90, 102, 0.14);
    color: var(--slate);
}

.shot-foot {
    margin: 0.85rem 0 0;
    font-size: 0.85rem;
    color: var(--slate);
}

/* Ce qu'il y a réellement sur le disque. */
.cipher {
    padding: 0.7rem 0.8rem;
    border-radius: var(--r-sm);
    background: var(--ink-deep);
    color: #9FB4BC;
    font-family: var(--mono);
    font-size: 0.76rem;
    line-height: 1.75;
    word-break: break-all;
}

/* Les gestes offerts sur une ligne · leur ABSENCE illustre autant que leur présence. */
.acts {
    display: flex;
    gap: 0.7rem;
    flex: none;
    font-size: 0.83rem;
    font-weight: 600;
}

.acts span {
    color: var(--green-deep);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.acts span.off {
    color: var(--slate);
    text-decoration: line-through;
    font-weight: 500;
}

/* ── Grille de cartes ───────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ `align-items: start` : sans cela, une carte courte s'étire à la hauteur de la plus longue et son
    cadre décrit une zone vide. C'est précisément le défaut de la vitrine précédente.
*/
.cards {
    display: grid;
    gap: 1.1rem;
    align-items: start;
    margin-top: 2.6rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 1.4rem;
    box-shadow: var(--sh-1);
}

.card h3 {
    margin-bottom: 0.5rem;
}

.card p {
    margin: 0;
    font-size: 0.95rem;
    color: var(--slate);
}

.card p + p {
    margin-top: 0.7rem;
}

.card-icon {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    margin-bottom: 0.9rem;
    border-radius: 11px;
    background: var(--green-wash);
    color: var(--green-deep);
}

.dark .card {
    background: rgba(255, 255, 255, 0.05);
    border-color: rgba(255, 255, 255, 0.12);
    box-shadow: none;
}

.dark .card p {
    color: #B9CBD1;
}

.dark .card-icon {
    background: rgba(18, 160, 106, 0.18);
    color: #7FE0B4;
}

/* ── Liste à coches ─────────────────────────────────────────────────────────────────────────── */

.checks {
    margin: 1.4rem 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.7rem;
    max-width: var(--measure);
}

/*
    ⚠️ PAS DE GRILLE ICI, ET C'EST UN DÉFAUT VÉCU.

    La première version posait `display: grid` avec deux colonnes, 22 px pour la coche et le reste pour
    le texte. Or dans un conteneur de grille, CHAQUE ENFANT devient une case : le `::before` prenait la
    première, le `<strong>` la seconde, et le texte qui suivait le `<strong>` retombait à la ligne
    suivante DANS LA COLONNE DE 22 px. Résultat, un mot par ligne sur une colonne large de deux
    centimètres.

    Le symptôme n'apparaît que sur les puces dont le texte est coupé par une balise · celles d'une seule
    phrase s'affichaient parfaitement, ce qui rendait le défaut invisible tant qu'on ne regardait pas la
    bonne puce. Signalé par Pierrick, capture à l'appui.

    La coche est donc posée en absolu et le texte reste dans un flux normal : quel que soit le nombre de
    balises qu'il traverse, il coule.
*/
.checks li {
    position: relative;
    padding-left: 1.95rem;
    font-size: 0.97rem;
}

.checks li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.2rem;
    width: 21px;
    height: 21px;
    border-radius: 50%;
    background: var(--green-wash) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.6 6.3 4.9 8.6 9.5 3.7' stroke='%230C7C52' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 13px no-repeat;
}

.dark .checks li::before {
    background-color: rgba(18, 160, 106, 0.2);
}

/* ── Bandeau d'appel ────────────────────────────────────────────────────────────────────────── */

.cta {
    text-align: center;
}

.cta p,
.cta .lead {
    margin-inline: auto;
}

.cta .actions {
    justify-content: center;
}

/* ── Pied de page ───────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ LE REMBOURRAGE EST À ZÉRO, ET C'EST LE PIED REFONDU QUI LE PORTE. Il valait
    `3.4rem 0 2.4rem` quand le pied était celui de la première version · la refonte le confie à
    `.mq-foot`, en haut comme en bas, pour que les deux écarts soient égaux par construction et le
    restent si l'un des deux est ajusté.

    ⚠️ LA MAQUETTE L'ÉCRASAIT PAR UN SECOND BLOC `footer`, ET ELLE LE SIGNALAIT ELLE-MÊME :
    `footer` pèse (0,0,1) des deux côtés, donc seul l'ORDRE de chargement départageait. En un seul
    fichier ce serait un doublon que rien ne signale, et le rembourrage reviendrait le jour où les
    deux blocs changent de place. La valeur est donc posée ici, une seule fois.
*/
footer {
    padding: 0;
    background: var(--surface);
    border-top: 1px solid var(--border);
}

.foot {
    display: grid;
    gap: 2.2rem;
}

@media (min-width: 52rem) {
    .foot {
        grid-template-columns: 1.4fr repeat(3, 1fr);
    }
}

.foot h2 {
    font-size: 0.82rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--slate-soft);
    margin-bottom: 0.8rem;
}

.foot ul {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.95rem;
}

/*
    ⚠️ LES NEUF LIENS DU PIED MESURAIENT 21 px DE HAUT, sous la barre des 44 px que le projet s'est
    fixée. Constat de MESURE, sur les seize pages, pas une impression : ils tenaient dans leur seule
    hauteur de ligne.

    Ce ne sont pas des liens en ligne dans une phrase — ceux-là sont explicitement exemptés par le
    WCAG 2.5.8, et on ne peut de toute façon pas les grossir sans casser l'interligne. Ce sont des
    éléments d'une LISTE DE NAVIGATION, au même titre que le menu de l'entête, dont chaque entrée fait
    déjà 44 px. L'incohérence était là.

    `display: flex` et `align-items: center` sur le lien lui-même, plutôt qu'un `padding` sur le `li` :
    la cible doit être le lien, pas la case qui le contient · un rembourrage sur le `li` agrandit la
    zone visible sans agrandir la zone cliquable.

    Le `gap` de la liste tombe à zéro : les 44 px de chaque lien fournissent désormais l'espacement, et
    le conserver aurait étiré le pied de 27 px par lien.
*/
.foot li a {
    display: flex;
    align-items: center;
    min-height: 44px;
    color: var(--slate);
    text-decoration: none;
}

.foot a {
    color: var(--slate);
    text-decoration: none;
}

.foot a:hover {
    color: var(--ink);
    text-decoration: underline;
}

/*
    Le sélecteur de langue et le courriel du pied bas : ils vivent dans un `<p>`, mais ce sont des
    commandes autonomes et non des liens au fil d'une phrase. 44 px aussi.
*/
.foot-bottom a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
}

.foot p {
    font-size: 0.92rem;
    color: var(--slate);
    max-width: 34ch;
}

.foot-bottom {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.4rem;
    justify-content: space-between;
    align-items: center;
    margin-top: 2.6rem;
    padding-top: 1.4rem;
    border-top: 1px solid var(--border);
    font-size: 0.9rem;
    color: var(--slate);
}

.foot-bottom p {
    margin: 0;
}


/* ============================================================================================
   Contenu long : pages légales, données personnelles, formulaire
   ============================================================================================

   ⚠️ Ces pages sont du TEXTE, pas une démonstration. Elles n'ont ni maquette ni duo : leur qualité
   se mesure à la facilité de lecture, pas à l'envie qu'elles donnent. Le contenu légal est repris
   mot pour mot de la version précédente · le reformuler ferait courir un risque juridique pour un
   gain d'écriture nul.
*/

.prose {
    max-width: var(--measure);
}

.prose h2 {
    margin-top: 2.6rem;
    margin-bottom: 0.9rem;
    font-size: clamp(1.5rem, 1.1rem + 1.2vw, 1.95rem);
}

.prose h2:first-child {
    margin-top: 0;
}

.prose h3 {
    margin-top: 1.8rem;
    margin-bottom: 0.5rem;
}

.prose ul:not(.checks) {
    padding-left: 1.15rem;
    max-width: var(--measure);
}

.prose li {
    margin-bottom: 0.45rem;
}

.prose code {
    padding: 0.1rem 0.35rem;
    border-radius: 6px;
    background: var(--raised);
    font-family: var(--mono);
    font-size: 0.88em;
}

/* Un encadré qui appuie une phrase, sans crier. */
.callout {
    margin: 1.6rem 0;
    padding: 1.1rem 1.3rem;
    border-left: 3px solid var(--green);
    border-radius: 0 var(--r-md) var(--r-md) 0;
    background: var(--green-wash);
}

.callout p:last-child {
    margin-bottom: 0;
}

/* ⚠️ Un tableau large ne doit jamais élargir la PAGE : il défile dans sa propre boîte. */
.table-scroll {
    overflow-x: auto;
    margin: 1.6rem 0;
}

table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.95rem;
}

/*
    ⚠️ `overflow-x: auto` NE SUFFIT PAS, ET LE CROIRE A DONNÉ UN MOT PAR LIGNE SUR MOBILE.

    `width: 100%` demande au tableau la largeur de sa boîte. Sur un téléphone, quatre colonnes dans
    350 px se réduisent donc à leur `min-content` : « Second facteur obligatoire, passkeys » s'est
    affiché sur quatre lignes dans une colonne de 134 px. La boîte défilait bien · elle n'avait presque
    rien à faire défiler, puisque le tableau avait accepté de se tasser.

    Un plancher change la nature du calcul : le tableau garde une largeur lisible, dépasse la boîte, et
    c'est ALORS que le défilement sert à quelque chose. Posé sur `.table-scroll > table` et non sur
    `.compare`, parce que les deux tableaux de la page « Données personnelles » ont exactement le même
    besoin.

    Même famille que le défaut de `.checks li` : invisible sur les libellés courts, criant sur les
    longs, et introuvable sans mesurer les lignes rendues.
*/
.table-scroll > table {
    min-width: 33rem;
}

th,
td {
    text-align: left;
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

th {
    font-size: 0.8rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--slate-soft);
}

/* ── Formulaire ─────────────────────────────────────────────────────────────────────────────── */

.field {
    margin-bottom: 1.15rem;
    max-width: 34rem;
}

.field label {
    display: block;
    margin-bottom: 0.4rem;
    font-weight: 600;
    font-size: 0.95rem;
}

.field input,
.field textarea,
.field select {
    width: 100%;
    min-height: 46px;
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--border-firm);
    border-radius: var(--r-md);
    background: var(--surface);
    color: var(--ink);
    font: inherit;
    font-size: 1rem;
}

.field textarea {
    min-height: 8rem;
    resize: vertical;
}

.hint {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.87rem;
    color: var(--slate);
}

.form-note {
    font-size: 0.9rem;
    color: var(--slate);
}

.form-status {
    margin: 1.2rem 0;
    padding: 0.9rem 1.1rem;
    border-radius: var(--r-md);
    background: var(--green-wash);
    color: var(--ink);
    font-size: 0.95rem;
}

/*
    ⚠️ LE CHAMP PIÈGE, masqué de l'affichage ET des lecteurs d'écran.

    `display: none` suffirait à l'œil, mais certains robots le repèrent · et une personne au lecteur
    d'écran ne doit jamais tomber sur un champ qu'elle est censée laisser vide. D'où la sortie du flux
    par la position, plus `aria-hidden` et `tabindex="-1"` au balisage.
*/
.trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Le fil d'Ariane des pages secondaires. */
.breadcrumb {
    padding-top: 1.4rem;
    font-size: 0.9rem;
    color: var(--slate);
}

.breadcrumb ol {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.breadcrumb li + li::before {
    content: "·";
    margin-right: 0.5rem;
    color: var(--border-firm);
}

.breadcrumb a {
    color: var(--slate);
}


/* ── Panneau : un bloc de saisie posé sur la page ───────────────────────────────────────────── */

/*
    Le formulaire de contact vit dans un panneau blanc plutôt qu'à même le fond. Sur la version
    précédente il flottait dans la page, et un champ sans cadre au milieu d'un texte se lit comme une
    ligne de plus, pas comme un endroit où l'on agit.
*/
.panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-2);
    padding: clamp(1.4rem, 1rem + 1.4vw, 2.1rem);
}

.panel .field:last-of-type {
    margin-bottom: 1.5rem;
}

/*
    ⚠️ Une colonne de saisie plus large que la colonne d'accompagnement. À parts égales, les champs
    devenaient étroits et le formulaire avait l'air d'un aparté sur sa propre page.
*/
@media (min-width: 62rem) {
    .duo-form {
        grid-template-columns: 1.35fr 1fr;
        align-items: start;
    }
}

/* Une carte d'appoint, à côté du formulaire. */
.aside-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 1.3rem;
    box-shadow: var(--sh-1);
}

.aside-card + .aside-card {
    margin-top: 1rem;
}

.aside-card h2 {
    font-size: 1.05rem;
    letter-spacing: -0.015em;
    margin-bottom: 0.5rem;
}

.aside-card p {
    margin: 0;
    font-size: 0.95rem;
    color: var(--slate);
}

.aside-card p + p {
    margin-top: 0.7rem;
}

/*
    ⚠️ Le message d'état ne prend de place que lorsqu'il en a. Vide, il laissait un bandeau vert clair
    sous le bouton, qui se lisait comme une confirmation d'un envoi qui n'avait pas eu lieu.
*/
.form-status:empty {
    display: none;
}

/* ── Grille de tarifs ───────────────────────────────────────────────────────────────────────── */

/*
    Trois colonnes qui deviennent une seule sous 60 rem environ, par `auto-fit`, comme `.cards`.

    ⚠️ PAS de `align-items: start` ici, contrairement à `.cards`, et c'est le choix inverse pour la
    raison inverse : sur une grille de tarifs, trois cadres de hauteurs différentes empêchent de lire
    une ligne en travers, et le bouton de chaque palier se retrouve à une hauteur différente. Les
    listes sont donc étirées et le bouton poussé en bas par `margin-top: auto`.
*/
.tiers {
    display: grid;
    gap: 1.2rem;
    margin-top: 2.6rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.tier {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 1.6rem 1.5rem;
    box-shadow: var(--sh-1);
}

/*
    Le palier mis en avant. Un liséré vert et une ombre plus marquée · PAS un fond vert.

    ⚠️ Le vert de la charte plafonne à 3,35:1 sur blanc : il ne porte donc jamais de texte, et une carte
    au fond vert obligerait à écrire dessus. Il sert de liséré, de coche et de fond de bouton.
*/
.tier-featured {
    border-color: var(--green);
    box-shadow: var(--sh-2);
}

.tier-flag {
    align-self: start;
    margin-bottom: 0.9rem;
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    background: var(--green-wash);
    color: var(--green-deep);
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/*
    Réserve la hauteur de l'étiquette sur les paliers qui n'en portent pas, pour que les trois titres
    s'alignent. Sans cela, le palier vedette descend seul de 30 px et la grille paraît de guingois.
*/
.tier-flag-none {
    visibility: hidden;
}

.tier h2 {
    font-size: 1.35rem;
    letter-spacing: -0.02em;
    margin-bottom: 0.3rem;
}

.tier-for {
    margin: 0 0 1.1rem;
    font-size: 0.93rem;
    color: var(--slate);
}

.price {
    display: flex;
    align-items: baseline;
    gap: 0.35rem;
    margin-bottom: 0.35rem;
}

.price b {
    font-size: 2.9rem;
    line-height: 1;
    letter-spacing: -0.045em;
    color: var(--ink-deep);
}

.price span {
    font-size: 0.95rem;
    color: var(--slate);
}

/* Le « HT » et la périodicité, à part du chiffre : obligatoires, et jamais en tout petit gris illisible. */
.price-note {
    margin: 0 0 1.3rem;
    font-size: 0.86rem;
    color: var(--slate);
}

/*
    La liste des lignes d'un palier. Même construction que `.checks` — coche en absolu, texte dans un
    flux normal — parce que le même défaut y guettait : une ligne coupée par un `<b>` se serait
    répandue un mot par ligne dans la colonne de la coche.
*/
.tier ul {
    margin: 0 0 1.5rem;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.62rem;
    font-size: 0.94rem;
}

.tier li {
    position: relative;
    padding-left: 1.75rem;
    color: var(--ink);
}

.tier li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.15rem;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: var(--green-wash) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M2.6 6.3 4.9 8.6 9.5 3.7' stroke='%230C7C52' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px no-repeat;
}

/*
    Une ligne ABSENTE du palier.

    ⚠️ Elle reste lisible : `--slate` donne 7,2:1, pas un gris décoratif. Dire « ce n'est pas dans cette
    offre » est une information qu'on lit, pas une mention qu'on devine. Et le signe est une croix, pas
    une coche pâle · deux ronds verts de nuances voisines se confondent au premier coup d'œil.
*/
.tier li.off {
    color: var(--slate);
}

.tier li.off::before {
    background: var(--raised) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3.6 3.6 8.4 8.4M8.4 3.6 3.6 8.4' stroke='%23405A66' stroke-width='1.9' stroke-linecap='round'/%3E%3C/svg%3E") center / 12px no-repeat;
}

/* `auto` pousse le bouton en bas : les trois se retrouvent alignés quelles que soient les listes. */
.tier .btn {
    margin-top: auto;
    width: 100%;
    justify-content: center;
}

/* ── Le tableau comparatif ──────────────────────────────────────────────────────────────────── */

/*
    Les trois colonnes de valeurs sont centrées, la première reste à gauche : un « 5 » aligné à gauche
    dans une colonne large se lit mal en face de « sans limite ».
*/
.compare td + td,
.compare th + th {
    text-align: center;
}

.compare tbody th {
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--ink);
}

/* La colonne du palier vedette, teintée sur toute sa hauteur pour se suivre à l'œil. */
.compare td.spot,
.compare th.spot {
    background: var(--green-wash);
}

/* ══ MODIFICATEURS · CE QUI VIVAIT EN ATTRIBUT « style » ════════════════════════════════════════
   ⚠️ LA CSP DU SITE EST `style-src 'self'`, SANS `'unsafe-inline'` : UN ATTRIBUT `style` EST IGNORÉ.
   Servi en local par `python -m http.server` il n'y a aucune CSP, donc la page paraît juste et le
   défaut n'apparaît qu'en production — sans autre signal qu'un avertissement dans une console que
   personne n'ouvre. Quarante-trois attributs vivaient ainsi sur les seize pages.
   La huitième passe de `_controles.py` en refuse désormais l'apparition. */

/* La bannière de la page tarifs : une seule colonne, plus étroite que la grille par défaut.
   ⚠️ Sans cela, `.hero .wrap` reste la grille à deux colonnes et l'accroche part à droite. */
.hero .wrap-simple {
    display: block;
    max-width: 52rem;
}

/* Le logo du pied, qui se détache du paragraphe qui le suit. */
.foot .logo {
    margin-bottom: 0.9rem;
}

/* Une barre de progression partielle. ⚠️ La largeur PAR DÉFAUT est pleine — un bloc remplit son
   conteneur — donc seule la valeur partielle a besoin d'être écrite. Sans elle, la maquette de
   `cas-usage` annonçait « 7 sur 11 » sous une barre complète. */
.bar-part i {
    width: 64%;
}

/* Une légende de maquette collée à l'image qu'elle commente, sans l'espace habituel. */
.shot-foot-flush {
    margin-top: 0;
}

/* Ce qui suit immédiatement une légende de maquette. */
.after-shot {
    margin-top: 0.9rem;
}

/* Les deux encarts de la page tarifs, sous les cartes et sous le tableau. */
.callout-after-tiers {
    margin-top: 2rem;
}

.callout-after-table {
    margin-top: 2.2rem;
}

/* La page de redirection de langue à la racine · elle n'a ni entête ni pied, donc rien qui l'écarte
   du bord. ⚠️ Elle EST servie, contrairement aux outils préfixés d'un souligné. */
.wrap-choix-langue {
    padding: 3rem 0;
}


/* ══ LA PAGE D'ACCUEIL ══════════════════════════════════════════════════════════════════════════ */

/*
    Le prix, sous les deux boutons du premier écran.

    ⚠️ IL EST LÀ PARCE QU'UN VISITEUR QUI NE VOIT AUCUN PRIX SUPPOSE QU'IL FAUT DEMANDER UN DEVIS, et
    qu'il part. C'est l'objection la plus chère à lever, et elle se levait à deux clics de distance.
    ⚠️ Discret et non appuyé : il rassure, il ne vend pas · l'action principale reste le bouton.
*/
.hero-price {
    margin: 0.9rem 0 0;
    font-size: 0.92rem;
    color: var(--slate);
}

.hero-price a {
    white-space: nowrap;
}

/*
    Le tableau « aujourd'hui / avec TickDoc ».

    ⚠️ LES DEUX COLONNES SONT À GAUCHE, contrairement à `.compare` qui centre les siennes. Là il s'agit
    de chiffres courts qu'on compare ligne à ligne · ici de phrases, et une phrase centrée se lit mal.
    Réutiliser `.compare` aurait donné deux colonnes de texte centré, ce qui est exactement ce qu'il ne
    faut pas faire.

    ⚠️ La seconde colonne est teintée sur toute sa hauteur, comme la colonne vedette de la grille
    tarifaire : c'est ce qui permet de suivre « le nôtre » à l'œil sans relire l'entête.
*/
.versus th,
.versus td {
    text-align: left;
    vertical-align: top;
    width: 50%;
}

.versus td.spot,
.versus th.spot {
    background: var(--green-wash);
}

/*
    ⚠️ POUR LES LECTEURS D'ÉCRAN SEULEMENT, et le `clip-path` est ce qui le rend sûr. `display: none`
    retirerait l'élément de l'arbre d'accessibilité, donc du texte destiné à être lu ne le serait pas ·
    une position hors écran, elle, laisse la légende annoncée avec son tableau.

    ⚠️ Le couple `width: 1px` + `clip-path` est nécessaire : sans le second, le contenu déborde de sa
    boîte d'un pixel et élargit le document. C'est le mécanisme exact qui a donné une barre de
    défilement horizontale sur toutes les pages portant un dépôt de fichier, dans l'application.
*/
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ═════════════════════════════════════════════════════════════════════════════════════════════════
   LA REFONTE MARKETING · tout ce que la charte ci-dessus ne portait pas
   ═════════════════════════════════════════════════════════════════════════════════════════════════

   Ces règles viennent de la maquette des neuf pages, relevée sur les visuels au pixel et mesurée
   aux sept largeurs de 320 à 1 920 px. Elles COMPLÈTENT la charte, elles ne la remplacent pas :
   toutes les classes ajoutées sont préfixées `mq-`, ce qui rend la collision impossible avec les
   1 535 lignes au-dessus.

   ⚠️ DEUX RÈGLES DE LA MAQUETTE NE SONT PAS ICI, ET C'EST VOULU. Elle redéclarait `.masthead .wrap`
   pour sa gouttière et `.nav a:not(.btn)` pour son `white-space` · dans deux fichiers séparés
   l'ordre de chargement les départageait, dans un seul fichier ce serait un doublon que rien ne
   signale. Les deux sont donc fondues DANS la règle de la charte, à leur place, avec la mesure qui
   les motive.

   ⚠️ LE PRÉFIXE `mq-` VEUT DIRE « MAQUETTE », ET IL N'A PLUS DE SENS ICI. Il est conservé pendant
   la reprise des neuf pages, parce qu'il permet de comparer une page du dépôt à sa maquette ligne
   par ligne — c'est le garde-fou principal de ce portage. Un renommage mécanique est proposé en
   dernier commit, une fois les neuf pages en place et mesurées.
*/

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   0. JETONS LOCAUX · relevés sur le visuel, à la pipette
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

:root {
    /*
        ⚠️ LE CONTENEUR DU VISUEL EST BEAUCOUP PLUS LARGE QUE `.wrap` DE LA CHARTE.
        Mesuré : ses panneaux vont de x=25 à x=785 sur 812, soit 93,6 % de la largeur · `.wrap` en
        occupe 82 % (74 rem dans 1440). C'était la cause principale de mon décalage général : tout
        paraissait plus étroit et plus petit que le visuel. 84 rem donne 93,3 % à 1440 px.

        ⚠️ Conséquence à ne pas taire : cette home serait plus large que les quinze autres pages.
        Voir README.md, c'est un arbitrage à rendre avant toute reprise dans `site-v2/`.
    */
    --mq-max: 84rem;
    /*
        ⚠️ 1,25 rem SOUS 62 rem, ET C'EST MESURÉ. À 1,5 rem la coquille ne fait plus que 257 px à
        320 px de fenêtre · l'entête y réclame 283 px (logo 102 + gouttière 22 + bouton 159, dont
        le libellé ne se coupe pas), et la page débordait de 3 px. La vitrine actuelle emploie
        1,25 rem et tient, à 2 px près. Trois pixels ne se voient pas et donnent quand même une
        barre de défilement horizontale sur tout le site.
    */
    --mq-marge: 1.25rem;

    /* Fonds relevés à la pipette sur le visuel */
    --mq-secu: #012318;      /* panneau sécurité · vert très sombre, pas le noir de --ink-deep */
    --mq-cta: #007547;       /* bandeau final · blanc dessus à 5,78:1, mieux que --green-deep */
    /*
        ⚠️ #EAF4EE ET NON LE #F6FAF9 RELEVÉ SUR LE VISUEL, qui « manquait de tonalité » le
        8 septembre. C'est la teinte la plus soutenue qui garde tous les contrastes du panneau
        au-dessus de 4,5:1 · ardoise 6,50:1 et vert profond 4,64:1. La suivante essayée, #E4F1EA,
        fait tomber le vert profond à 4,49, donc sous le seuil du texte courant.
    */
    --mq-tint: #EAF4EE;      /* panneau teinté de la section « différenciation » */

    /*
        ⚠️ LE ROUGE DU VISUEL EST #FF614A, ET IL DONNE 2,97:1 SUR BLANC · sous les 3:1 qu'exige
        WCAG 1.4.11 pour une icône. Trois centièmes, donc invisible à l'œil et refusé par la mesure.
        #DC2626 donne 4,83:1 et reste le même rouge à la lecture.
    */
    --mq-refus: #DC2626;

    /*
        ⚠️ LA COLONNE DE LECTURE DES PAGES LÉGALES, EN REM ET NON EN `ch`, ET C'EST UNE MESURE QUI
        L'A IMPOSÉ. Elle valait `86ch` · or `ch` se calcule sur la taille de police de L'ÉLÉMENT,
        et le fil d'Ariane est à 0,9 rem. Les deux boîtes portaient donc la même déclaration et
        rendaient deux largeurs différentes : le texte commençait à 318 px, le fil à 379, et les
        aligner par la classe seule était impossible. 49,25 rem valent 788 px à la racine de 16 px,
        soit exactement ce que `86ch` rendait sur le corps de texte : la largeur ne change pas, sa
        définition cesse de dépendre de qui la porte.

        Dixième et onzième occurrence de « une valeur déclarée n'est pas une valeur appliquée » dans
        ce projet · les deux précédentes étaient des conflits de spécificité, celle-ci est une unité.
    */
    --mq-lecture: 49.25rem;
}

.mq-wrap {
    width: min(100% - 2 * var(--mq-marge), var(--mq-max));
    margin-inline: auto;
}

/*
    ⚠️ L'ENTÊTE PORTE LES DEUX CLASSES, ET CE N'EST PAS UNE MALADRESSE. `.masthead .wrap` lui
    donne sa boîte flexible et ses 76 px de haut : retirer `wrap` ferait s'effondrer la barre. Or
    `.wrap` et `.mq-wrap` pèsent tous deux (0,1,0) et se disputent `width` — seul l'ORDRE du fichier
    les départage, et il suffirait de déplacer un bloc pour que l'entête revienne à 74 rem quand le
    reste du site est à 84, sans qu'aucun contrôle ne le dise. `.wrap.mq-wrap` pèse (0,2,0) et gagne
    dans les deux sens.
*/
.wrap.mq-wrap {
    width: min(100% - 2 * var(--mq-marge), var(--mq-max));
}

/*
    ⚠️ LE RYTHME VERTICAL DE LA CHARTE EST DEUX FOIS PLUS AÉRÉ QUE CELUI DU VISUEL, et c'est ce
    qui donnait la différence d'allure la plus visible. Mesuré :

        `section` de la charte     102,4 px en haut ET en bas, soit 205 px entre deux sections
        le visuel                  de 28 à 117 px selon la couture, environ 65 en moyenne

    Sur six sections cela faisait 1 229 px de rembourrage, et ma page mesurait 5 564 px de haut
    pour 1 440 de large, soit un rapport de 3,86 contre 2,66 au visuel : 45 % trop haute.

    ⚠️ Ce n'est PAS une correction de confort. « La densité est ennemie de la confiance » est une
    règle écrite du projet, et la charte l'applique · le visuel, lui, est plus serré. Ce réglage
    suit le visuel, il ne le corrige pas · à confirmer.
*/
.mq-section {
    padding-block: clamp(1.2rem, 0.8rem + 1.2vw, 1.7rem);
}

/*
    ⚠️ Un cran d'air EN PLUS, sur les coutures qui le demandent. Deux sections la portent :

      · avant « quatre étapes », où la section 2 se termine par deux panneaux encadrés et la
        suivante commence par un titre centré · sans respiration les deux se touchaient ;
      · avant le bandeau vert final, demandé le 8 septembre · un panneau plein qui démarre à 27 px
        des cartes des métiers paraissait collé.

    « Pas beaucoup » était la consigne les deux fois, d'où 1,6 rem ajoutés et non le double.
*/
.mq-section-aere {
    padding-top: clamp(2rem, 1.4rem + 2vw, 3.3rem);
}

/*
    ⚠️ LA DERNIÈRE SECTION A BESOIN DE SON PROPRE REMBOURRAGE BAS.
    Mesuré : le bandeau vert s'arrêtait à 27 px du filet du pied, quand toutes les autres coutures
    de la page en font 54. Il paraissait donc collé, et c'est ce qui a été signalé le 8 septembre.

    ⚠️ Pourquoi une classe de plus, et non `.mq-section-aere` rendue symétrique : cette dernière
    est aussi posée sur la section des étapes, dont la couture avec le panneau teinté vaut 54 px et
    a été validée telle quelle. La rendre symétrique l'aurait poussée à 80 px sans que personne ne
    l'ait demandé.

    ⚠️ Et pourquoi pas un `padding-top` sur le `footer` : il est à zéro EXPRÈS, pour que les deux
    écarts du pied soient portés par `.mq-foot` seul et restent égaux par construction. Y remettre
    du rembourrage casserait cette garantie.
*/
.mq-section-fin {
    padding-bottom: clamp(2rem, 1.4rem + 2vw, 3.3rem);
}

/*
    ⚠️ De l'air DES DEUX CÔTÉS du titre des métiers, demandé le 8 septembre.
    Le titre y est pris en étau : au-dessus le panneau vert très sombre de la sécurité, au-dessous
    six cartes serrées. Le rembourrage de section double, ET la gouttière entre le titre et les
    cartes passe de 2,4 à 3,2 rem · le rembourrage seul aurait éloigné le titre du panneau sans le
    décoller de ses cartes.
*/
.mq-section-large {
    padding-block: clamp(2.2rem, 1.5rem + 2.2vw, 3.4rem);
}

.mq-section-large .mq-cards {
    margin-top: 3.2rem;
}

@media (min-width: 62rem) {
    :root {
        --mq-marge: 1.5rem;
    }
}

/*
    Le titre de section, CENTRÉ · c'est la forme du visuel sur les étapes, la différenciation et
    les métiers. La sécurité et le bandeau final gardent un titre aligné à gauche.

    ⚠️ IL EST PLUS PETIT QUE LE `h2` DE LA CHARTE, et c'est mesuré. La charte plafonne `h2` à
    2,7 rem, soit 43,2 px · à cette taille « Pour tous les métiers qui attendent des pièces avant
    de pouvoir avancer. » réclame environ 1 490 px pour 1 344 disponibles, donc DEUX lignes. Le
    visuel met ces titres sur UNE ligne : son `h2` fait environ 36 px à 1 440. D'où le plafond à
    2,3 rem, et un `max-width` qui ne bride plus rien à cette largeur.
*/
/*
    ⚠️ LA TAILLE EST DÉCLARÉE UNE SEULE FOIS, POUR LES DEUX SÉLECTEURS.
    Le titre de la section « Arrêtez de chercher les pièces dans les mails. » employait le `h2` de
    la charte, plafonné à 2,7 rem, soit 43,2 px · les titres centrés sont à 2,3 rem, soit 36,8. Deux
    tailles pour deux titres de même rang se voyaient au défilement. Demandé le 8 septembre.

    Les deux sélecteurs partagent la même déclaration : deux règles séparées finiraient par
    divergerau premier ajustement, et c'est exactement le genre d'écart que personne ne remarque.
*/
.mq-titre,
.mq-probleme h2 {
    font-size: clamp(1.62rem, 1.1rem + 1.6vw, 2.3rem);
    line-height: 1.15;
}

.mq-titre {
    text-align: center;
    margin-inline: auto;
    max-width: 62ch;
}

/*
    ⚠️ 40 REM ET NON 46 CH · LE SOUS-TITRE DOIT TENIR SUR UNE LIGNE. Demandé par Christophe le
    8 septembre 2026 sur trois sections de « Comment ça marche ». 46 ch valaient 405 px et coupaient
    en deux des phrases qui réclamaient 443, 425 et 543 px, pour 885 à 944 px offerts par le
    conteneur à 992 px de fenêtre : le plafond était le seul obstacle.

    ⚠️ LE PLAFOND EST PARTAGÉ PAR LES 21 SOUS-TITRES DES HUIT PAGES, et c'est pour cela qu'il est
    relevé ici plutôt que surchargé sur une page. Mesuré à 1 440 px : **19 des 21 tiennent sur une
    ligne à 640 px**. Les deux qui restent sur deux lignes sont de vraies phrases longues — 987 px
    sur « Données personnelles », 840 px sur une question de « Tarifs » — et c'est correct. Un
    plafond différent d'une page à l'autre aurait été la direction artistique par page que le §10 de
    la refonte interdit.

    ⚠️ EN REM, PAS EN CH, ET AVEC 18 % DE MARGE. Le site n'a AUCUN `@font-face` : la pile est
    système — Segoe UI Variable Display, SF Pro Display, puis les replis — donc la largeur d'une même
    phrase change d'une machine à l'autre, et `ch` change avec elle. Un plafond calé au pixel sur la
    plus longue phrase (543 px) se serait cassé ailleurs sans que rien ne le signale. 640 px laisse
    97 px, et `rem` rend le plafond lui-même indépendant de la police.

    ⚠️ SOUS ENVIRON 1 000 PX, LA PHRASE SE REPLIE, et c'est voulu : la largeur offerte devient
    inférieure au plafond. Une phrase forcée sur une ligne à 390 px déborderait.
*/
.mq-sous {
    text-align: center;
    margin: 0.7rem auto 0;
    max-width: 40rem;
    color: var(--slate);
    font-size: 1.02rem;
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   0 bis. LE LOGO · le lettrage du visuel
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ « Tick » ET « Doc » SONT TOUS DEUX EN GRAS, ET « Doc » EST VERT. La charte pose l'inverse :
    `.logo b { font-weight: 700 }` et `.logo span { font-weight: 400 }`, les deux en encre. Relevé
    sur le visuel à la pipette, le vert du lettrage vaut #026737, soit `--green-deep` à trois unités
    près.

    ⚠️ `--green-deep` et non `--green` : à 29 px le lettrage est du gros texte, donc 3:1 suffirait
    et `--green` passerait · mais le visuel emploie bien un vert sombre, et `--green-deep` donne
    5,22:1. Aucune raison de prendre le plus clair.

    ⚠️ Le sélecteur descend à `span span`, qui pèse (0,1,2), pour battre `.logo span` (0,1,1) de la
    charte.

    ⚠️ LE VISUEL N'A AUCUN SIGNE DANS L'ENTÊTE, seulement le lettrage · vérifié en balayant depuis
    x=0. Le signe est conservé ici : c'est « la case qui déborde », choisie par Pierrick à la
    conception, et son retrait n'a pas été demandé. À arbitrer.
*/
/*
    ⚠️ L'AGRANDISSEMENT EST RÉSERVÉ AUX ÉCRANS QUI ONT LA PLACE, et c'est mesuré : à 1,85 rem le
    lettrage plus le signe font 167 px au lieu de 102 · à 320 px de fenêtre l'entête réclamait alors
    348 px pour 285 disponibles, et la page débordait de 14 px. Le lettrage en gras et le vert sur
    « Doc », eux, s'appliquent à toutes les largeurs : c'est le dessin, pas la taille.
*/

/* ⚠️ Le signe descend à 38 px sous 48 rem : le « Doc » passé en gras élargit le lettrage de 3 px,
   et il manquait exactement 1 px à 320 px de fenêtre. Un pixel donne la même barre de défilement
   horizontale que cinquante. */
.mq-logo img {
    width: 38px;
    height: 38px;
}

@media (min-width: 48rem) {
    .mq-logo {
        font-size: 1.85rem;
    }

    .mq-logo img {
        width: 46px;
        height: 46px;
    }
}

.mq-logo span {
    font-weight: 700;
}

/* ── Le lettrage sous 24 rem ────────────────────────────────────────────────────────────────────
   ⚠️ À 320 px, LE LETTRAGE PASSAIT SOUS LE BOUTON, ET AUCUN CONTRÔLE NE POUVAIT LE VOIR.
   Le logo affichait « TickD » : le « oc » était recouvert par « Créer un compte ». Mesuré, puis
   regardé pour en être sûr. Le mécanisme est celui du piège nº 4 du README, et il est vicieux :

     · l'entête réclamait 105 + 16 + 159 = 280 px pour 265 disponibles ;
     · `.masthead .wrap` est une boîte flexible, donc le lien du logo a ÉTÉ COMPRIMÉ de 143 à
       105 px au lieu de pousser le bouton dehors ;
     · son `span` a débordé de 38 px, mais un débordement d'un enfant hors de son parent
       n'élargit pas le document · `scrollWidth` valait exactement `clientWidth` ;
     · le bouton vient après dans le balisage, donc il se peint PAR-DESSUS le lettrage.

   Résultat : contrôle vert, aucune barre de défilement, et un logo tronqué. La correction
   précédente avait bien supprimé le débordement du DOCUMENT sous 48 rem, ce qui était son objet ·
   elle n'avait pas de raison de regarder à l'intérieur de l'entête.

   ⚠️ NI LE LETTRAGE MASQUÉ, NI LE LIBELLÉ RACCOURCI À UN MOT. Masquer « TickDoc » sous 384 px
   retirerait le nom de la marque des plus petits téléphones ET viderait le lien de son nom
   accessible, l'`alt` du signe étant vide exprès. Les deux éléments rapetissent donc ensemble, ce
   qui suffit : 32 + 10,6 + 67 + 16 + 130 = 256 px pour 265 disponibles.

   ⚠️ `flex: none` SUR LE LOGO, ET C'EST LA VRAIE LEÇON. Sans lui, une entête trop large se
   corrige toute seule en écrasant le logo, donc EN SILENCE. Avec lui, elle pousse le bouton dehors
   et le document déborde : le défaut redevient mesurable. Un défaut bruyant vaut mieux qu'un
   défaut muet. */
.mq-logo {
    flex: none;
}

@media (max-width: 24rem) {
    .mq-logo {
        font-size: 1.15rem;
    }

    .mq-logo img {
        width: 32px;
        height: 32px;
    }

    .masthead .btn {
        padding: 0.6rem 0.8rem;
        font-size: 0.88rem;
    }
}

.mq-logo span span {
    color: var(--green-deep);
}

/* ── La barre comprimée entre 62 et 72 rem ──────────────────────────────────────────────────────
   ⚠️ AJOUTER « COMMENT ÇA MARCHE » AU MENU FAIT DÉBORDER L'ENTÊTE DE 992 À 1 078 PX, ET C'EST
   MESURÉ, PAS DÉDUIT. La barre du site actuel fait 748 px en français, celle-ci 818 : la nouvelle
   entrée en coûte 70. Or le menu apparaît à 62 rem, soit 992 px, où la coquille ne fait que
   929 px · avec un logo de 164, il en manquait 51. À 1 024 px, largeur d'écran très courante, il
   en manquait 19.

   ⚠️ CE DÉFAUT ÉTAIT MUET AVANT LE `flex: none` DU LOGO. La boîte flexible écrasait le logo pour
   absorber le dépassement, donc le document ne débordait pas et le contrôle restait vert · c'est
   le `flex: none` posé pour le lettrage tronqué qui l'a rendu bruyant. Une correction qui fait
   apparaître un second défaut n'en crée pas un : elle le révèle.

   ⚠️ ET LE SITE ACTUEL EST DÉJÀ À LA LIMITE : 144 + 748 + 22 = 914 px pour 929 disponibles, soit
   15 px de marge à 992 px. Toute entrée ajoutée au menu, dans n'importe quelle langue, casse
   l'entête. À savoir avant d'en ajouter une huitième.

   ⚠️ NI MENU MASQUÉ, NI LIBELLÉ RACCOURCI. Relever le seuil d'apparition à 68 rem laisserait les
   tablettes et les petits portables SANS AUCUNE NAVIGATION entre 992 et 1 088 px, et ce site n'a
   pas de menu déroulant — il n'a aucune dépendance JavaScript. Raccourcir « Comment ça marche »
   trahirait le libellé choisi. C'est donc l'espacement de la barre qui se resserre, dans la seule
   bande où la place manque, et la hauteur de 44 px des cibles est intacte : seul le rembourrage
   HORIZONTAL diminue.

   ⚠️ Au-delà de 72 rem la compression cesse, et c'est vérifié : à 1 152 px la coquille fait
   1 112 px pour un besoin de 1 004. */
/* ── Le rembourrage des liens resserré au-delà de 62 rem ────────────────────────────────────────
   ⚠️ IL RESTE NÉCESSAIRE, ET C'EST LE SEUL RÉGLAGE QUI RESTE. Mesuré le 8 septembre 2026 avec
   `nowrap`, donc sur la largeur VRAIE, à six entrées de menu, pour 929 px de coquille à 992 px de
   fenêtre — le logo et la gouttière en prenant 186 :

     · gouttière ET rembourrage resserrés : barre 695 px, besoin 881 px → 48 px de marge ;
     · **gouttière de la charte, rembourrage resserré : barre 714 px, besoin 900 px → 29 px de
       marge. C'EST L'ÉTAT ACTUEL** ;
     · les deux à la valeur de la charte : barre 772 px, besoin 958 px → **il manque 29 px**.

   ⚠️ LA GOUTTIÈRE EST À 0,5 REM, ET LE PLAFOND EST À 0,6. Christophe voulait plus d'air entre les
   liens, et a demandé 1 rem : **1 rem ne tient pas.** Mesuré à 992 px, coquille de 929 :

     | gouttière | barre | besoin | marge |
     |-----------|-------|--------|-------|
     | 0,15 rem  | 695   | 881    | +48   |
     | 0,35 rem  | 714   | 900    | +29   |
     | **0,5 rem · RETENU** | **728** | **914** | **+15** |
     | 0,6 rem   | 738   | 924    |  +5   |
     | 0,65 rem  | 743   | 929    |   0   |
     | 0,7 rem   | 747   | 933    |  −4   |
     | 1 rem     | 776   | 962    | **−33** |

   ⚠️ POURQUOI PAS 0,6 REM, QUI PASSE. Il ne laisse que 5 px, et la pile de polices est SYSTÈME :
   la même barre est plus large sur une autre machine, et aucun contrôle d'ici ne verrait la casse
   là-bas. Une valeur juste qui ne tient qu'à un cheveu se casse à la première correction de libellé.

   ⚠️ POUR OBTENIR 1 REM, IL FAUDRAIT RÉTABLIR LE REPLI SUR DEUX LIGNES entre 992 et 1 025 px, soit
   127 px d'entête au lieu de 77 dans cette bande. Écarté le 8 septembre 2026 · la bande serait
   étroite, 33 px, mais le coût est visible et 0,5 rem donne déjà 43 % d'air en plus qu'avant.

   ⚠️ ET LA MARGE PASSE DE 48 À 15 PX, ce qui est le prix à connaître. Toute entrée ajoutée au menu,
   tout libellé rallongé, se mesure désormais contre 15 px. Le repli sur deux lignes est recopié en
   clair un peu plus bas, dans le commentaire qui explique son retrait.

   ⚠️ LE REMBOURRAGE NE PEUT PAS SUIVRE : le rendre à la charte fait manquer 29 px et casse l'entête
   à 992 px. C'est la seule moitié du resserrement qui tienne.

   ⚠️ IL N'A PAS DE BORNE HAUTE, exprès. Le limiter obligerait à revenir au rembourrage large pile
   là où la coquille cesse de grandir : une valeur juste qui ne tient qu'à un cheveu se casse à la
   première correction de libellé. Un rembourrage uniformément un peu plus serré vaut mieux qu'un
   saut d'espacement au milieu du redimensionnement.

   ⚠️ LA BARRE SUR DEUX LIGNES ENTRE 62 ET 68 REM EST RETIRÉE, ET C'EST LA REFONTE QUI L'A RENDUE
   INUTILE. Elle existait parce que la barre à SEPT entrées réclamait 1 018 px pour 929 disponibles,
   soit 89 px manquants qu'aucun resserrement ne trouvait. Le §11 de `00_GLOBAL_REFONTE.md` retire
   « Fonctionnalités » du menu et raccourcit « Cas d'usage » en « Pour qui ? », ce qui rend 137 px —
   plus que les 89 qui manquaient. Le repli coûtait **50 px de hauteur d'entête**, 127 px au lieu de
   77, entre 992 et 1 088 px : un coût devenu gratuit.

   ⚠️ LE JOUR OÙ UNE ENTRÉE REVIENT AU MENU, LE MANQUE REVIENT AVEC ELLE et le repli est à
   rétablir. ⚠️ **IL N'EST PAS DANS UN HISTORIQUE GIT, CONTRAIREMENT À CE QUE CE COMMENTAIRE A
   AFFIRMÉ** : `moi/` n'est pas un dépôt, `git` y répond « not a git repository ». Le voici, à
   recoller tel quel :

       @media (min-width: 62rem) and (max-width: 68rem) {
           .masthead .wrap { flex-wrap: wrap; }
           .nav { width: 100%; justify-content: flex-end; padding-bottom: 0.35rem; }
       }

   Le README porte les trois solutions écartées avec leur prix mesuré. Ne pas ajouter une entrée
   sans remesurer l'entête à 992 px. */
@media (min-width: 62rem) {
    .nav {
        gap: 0.5rem;
    }

    .nav a:not(.btn) {
        padding-inline: 0.45rem;
    }
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   1. HERO
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ L'IMAGE EST EN RETRAIT DU BORD, alors que le visuel la fait filer jusqu'au bord droit de la
    fenêtre · mesuré, son dernier pixel non blanc y est à x=811 sur 812. Écart demandé le
    8 septembre 2026 : le hero emploie donc la même coquille symétrique que les autres sections.
*/
.mq-hero {
    padding-block: clamp(1.8rem, 1.2rem + 2.4vw, 3.2rem) clamp(2rem, 1.4rem + 3vw, 3.6rem);
    width: min(100% - 2 * var(--mq-marge), var(--mq-max));
    margin-inline: auto;
    display: grid;
    gap: 2.2rem;
    align-items: center;
}

/*
    ⚠️ SUR UNE COLONNE, L'IMAGE EST BRIDÉE, ET SANS CELA LE HERO DEVIENT MONSTRUEUX.
    Mesuré à 1 120 px de fenêtre, quand le hero restait sur une colonne jusqu'à 72 rem : l'image
    faisait 1 081 x 819 px et le hero 1 396 px de haut. C'est le « en moyenne taille ça merde » du
    8 septembre. Deux corrections, et il faut les deux : le plafond ci-dessous, ET le passage à deux
    colonnes dès 62 rem au lieu de 72.
*/
.mq-hero-visuel {
    display: block;
    width: 100%;
    max-width: 30rem;
    margin-inline: auto;
    height: auto;
}

/*
    ⚠️ DEUX COLONNES DÈS 62 rem, ET LE RAPPORT EST CALCULÉ, PAS CHOISI.
    Le titre demande 11,59 fois son corps. La colonne de texte vaut (coquille - 40) / 2,05, soit
    445 px à 992 px de fenêtre pour 426 demandés, et 636 à 1 440 px pour 575. Ça tient partout.

    ⚠️ 1,05 part et non 1,18 : « un tout petit peu plus petit », demandé le 8 septembre. L'image
    passe de 728 à 668 px à 1 440, soit 8 % de moins.
*/
@media (min-width: 62rem) {
    .mq-hero {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
        column-gap: 2.5rem;
    }

    .mq-hero-visuel {
        max-width: none;
        margin-inline: 0;
    }
}

/*
    ⚠️ L'ACCROCHE EST DU TEXTE VERT, PAS UNE PASTILLE. `.eyebrow` de la charte est une pastille à
    fond vert pâle avec une puce ronde · le visuel n'a que des capitales vertes espacées. Échantillon
    du visuel : #12653A, un vert sombre.
    ⚠️ `--green-deep` et NON `--green` : à 13 px c'est du texte courant, et le vert de la charte
    n'y donne que 3,26:1 pour 4,5 exigés. `--green-deep` donne 5,08:1.
*/
.mq-eyebrow {
    display: block;
    margin-bottom: 1.1rem;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--green-deep);
}

/*
    L'échelle du titre est CALCULÉE, pas choisie à vue. Mesurée dans la fonte réelle, la ligne la
    plus longue occupe 11,59 fois le corps employé. La colonne de texte vaut
    (min(fenêtre - 48, 1344) - 48) / 2. Il faut donc :

        corps ≤ (min(fenêtre - 48, 1344) - 48) / 2 / 11,59

    La colonne vaut (min(fenetre - 2 x marge, 1344) - 40) / 2,18, soit 488 px a 1 152 et 598 a 1 440.
    Il faut donc au plus 41 px de corps a 1 152 et 49,6 au plafond, atteint des 1 341 px.
    ⚠️ MA PREMIERE PENTE ETAIT CALCULEE SUR L'ANCIENNE GEOMETRIE, a colonnes egales et gouttiere de
    48 px · apres l'elargissement de la colonne de droite le titre repassait a QUATRE lignes a
    1 152 px, et seule la mesure le disait.
    D'où la pente : 45,6 = -3,84 + 4,29 × 11,52  et  52,8 = -3,84 + 4,29 × 13,20.

    ⚠️ Le plafond de la charte est 4,1 rem, soit 65,6 px : le titre tombait alors sur QUATRE lignes.
    Le plafond n'est abaissé que sur CE titre, jamais dans la charte, qui sert seize pages.
*/
.mq-h1 {
    margin: 0 0 1.2rem;
    font-size: clamp(2.3rem, -0.71rem + 4.55vw, 3.1rem);
    line-height: 1.08;
    letter-spacing: -0.03em;
    font-weight: 700;
    color: var(--ink);
}

/*
    ⚠️ SEUL LE MOT « TickDoc » EST VERT, et c'est vérifié au pixel : sur la seconde ligne du visuel,
    le vert court de x=19 à x=134 et l'encre reprend à x=145. Ma première version peignait toute la
    ligne en vert.
    ⚠️ `--green` est admis ICI parce que le titre fait 37 à 53 px : au-delà de 24 px en gras, WCAG
    demande 3:1 et le vert de la charte donne 3,26:1. Ne PAS recopier ce vert sur un texte courant.
*/
.mq-h1 b {
    font-weight: inherit;
    color: var(--green);
}

.mq-hero-lead {
    margin: 0;
    font-size: clamp(1.04rem, 1rem + 0.3vw, 1.18rem);
    color: var(--slate);
    max-width: 46ch;
}

.mq-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    margin-top: 1.8rem;
}

/* ⚠️ `.mq-actions` est aligné à GAUCHE, parce qu'il vit dans un hero ou un bandeau dont le texte
   l'est aussi. Sous un `.mq-titre`, qui est centré, un bouton à gauche déséquilibre la section : le
   résumé tarifaire de l'accueil est le premier bloc de ce genre. Une classe de plus plutôt qu'un
   `justify-content` posé sur `.mq-actions`, qui aurait recentré les boutons des six heros. */
.mq-actions-centre {
    justify-content: center;
}

/*
    ⚠️ LE BOUTON SECONDAIRE DU VISUEL EST VERT, PAS GRIS. `.btn-ghost` de la charte est blanc à
    liséré `--border-firm` (#C9D4D1) avec du texte en encre : sur un fond blanc il s'efface et
    c'est le « trop fade » du 8 septembre. Le visuel lui donne un liséré vert, du texte vert et un
    lettrage gras.

    Contrastes : texte `--green-deep` sur blanc 5,22:1 · liséré `--green` sur blanc 3,35:1, au-delà
    des 3:1 qu'exige WCAG 1.4.11 pour la bordure d'un composant.

    ⚠️ LA RÈGLE DE SURVOL EST REDONNÉE ICI. `.mq-hero .btn-ghost` pèse (0,2,0) et bat
    `.btn-ghost:hover` (0,1,1) de la charte : sans cette seconde règle le bouton n'aurait plus aucun
    état de survol. C'est exactement le piège déjà rencontré sur le bouton du bandeau final.
*/
.mq-hero .btn-ghost {
    background: var(--surface);
    border-color: var(--green);
    color: var(--green-deep);
    font-weight: 700;
}

.mq-hero .btn-ghost:hover {
    background: var(--green-wash);
    border-color: var(--green-deep);
}

/* La pastille de lecture du visuel est CERCLÉE, pas remplie. */
.mq-play {
    display: grid;
    place-items: center;
    width: 21px;
    height: 21px;
    border: 2px solid currentColor;
    border-radius: 50%;
    color: inherit;
    flex: none;
}

/*
    Les trois mentions de confiance : le visuel leur donne une icône plus grande et un libellé
    SUR DEUX LIGNES, alors que `.assurances` de la charte les met sur une seule ligne avec un
    filet au-dessus. Sans filet ici, comme dans le visuel.
*/
.mq-trust {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 2rem;
    margin: 2.2rem 0 0;
    padding: 0;
    list-style: none;
}

.mq-trust li {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    font-size: 0.88rem;
    line-height: 1.3;
    color: var(--slate);
}

.mq-trust svg {
    flex: none;
    color: var(--ink);
}

.mq-trust b {
    display: block;
    color: var(--ink);
    font-weight: 600;
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   2. LE PROBLÈME · photo portrait pleine hauteur à gauche
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

.mq-probleme {
    display: grid;
    gap: clamp(1.6rem, 1rem + 2.4vw, 2.8rem);
    align-items: stretch;
}

@media (min-width: 62rem) {
    .mq-probleme {
        grid-template-columns: minmax(0, 0.62fr) minmax(0, 1fr);
    }
}

/*
    ⚠️ LA PHOTO EST SORTIE DU FLUX, ET `height: 100 %` NE SUFFISAIT PAS.
    `11.png` fait 760 x 950 : posée à la largeur de sa colonne, 497 px, elle CONTRIBUE 621 px de
    hauteur intrinsèque à la rangée de la grille. La rangée valait donc 621 px là où le texte n'en
    demandait que 480, et la photo dépassait le bloc au lieu de le suivre · `height: 100 %` se
    résolvait contre une hauteur qu'elle avait elle-même imposée.

    Le cadre en `position: relative` et la photo en `absolute` retirent cette contribution : la
    rangée est alors dictée par la colonne de texte, et la photo s'étire exactement à sa hauteur,
    comme dans le visuel où elle est à ras du haut et du bas de la section.

    ⚠️ `11.png` ET NON `03.png` : le format PORTRAIT est ce qui permet ce recadrage sans étirer le
    sujet. Demandé le 7 septembre 2026.
*/
.mq-portrait-cadre {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: var(--r-lg);
    overflow: hidden;
}

@media (min-width: 62rem) {
    .mq-portrait-cadre {
        aspect-ratio: auto;
        min-height: 20rem;
    }
}

.mq-portrait {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 30%;
}

.mq-probleme h2 {
    margin-bottom: 0.8rem;
}

.mq-probleme-lead {
    margin: 0;
    color: var(--slate);
    font-size: 1.02rem;
    max-width: 52ch;
}

.mq-compare {
    display: grid;
    gap: 1.1rem;
    margin-top: 1.8rem;
}

@media (min-width: 46rem) {
    .mq-compare {
        grid-template-columns: 1fr 1fr;
    }
}

.mq-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 1.4rem 1.3rem;
}

/* Le panneau favorable du visuel porte un liséré VERT et son titre est vert. */
.mq-panel-good {
    border-color: var(--green);
}

.mq-panel h3 {
    margin: 0 0 1.1rem;
    font-size: 1.12rem;
}

/* Vert PROFOND : un `h3` à 18 px est du texte courant, et --green n'y donne que 3,26:1. */
.mq-panel-good h3 {
    color: var(--green-deep);
}

.mq-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 0.85rem;
}

.mq-list li {
    display: grid;
    grid-template-columns: 20px 1fr;
    gap: 0.7rem;
    align-items: start;
    font-size: 0.94rem;
    line-height: 1.35;
    color: var(--slate);
}

.mq-list svg {
    margin-top: 0.12rem;
}

/*
    ⚠️ LA PUCE NE PORTE PAS LE SENS À ELLE SEULE. Une croix rouge et une coche verte se distinguent
    par la couleur et par la forme, mais un lecteur d'écran ne voit ni l'une ni l'autre : les deux
    icônes sont `aria-hidden`, et c'est le TITRE du panneau, « Sans TickDoc » ou « Avec TickDoc »,
    qui porte l'information. C'est le défaut que j'ai relevé sur la page tarifs du site, où
    `.tier li.off` ne dit « non incluse » que par une croix en image de fond.
*/
.mq-list-no svg {
    color: var(--mq-refus);
}

.mq-list-yes svg {
    color: var(--green-deep);
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   3. CARTES · hauteur égale, et c'est le point qui manquait
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ `align-items: stretch` ET NON `start`. `.cards` de la charte pose `align-items: start`, ce
    qui laisse chaque carte à sa hauteur propre : dans le visuel elles sont TOUTES DE MÊME HAUTEUR,
    et c'est ce qui fait tenir la rangée. Le `flex` en colonne plus `margin-top: auto` sur
    l'illustration pousse celle-ci en bas de la carte quelle que soit la longueur du texte.
*/
.mq-cards {
    display: grid;
    gap: 1.2rem;
    align-items: stretch;
    margin-top: 2.4rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.mq-card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 1.15rem;
}

/* ⚠️ Corps AGRANDI le 8 septembre : 1,02 et 0,92 rem se lisaient petit dans des cartes de 300 px.
   La règle porte sur `.mq-card`, donc les trois sections de cartes en profitent ensemble. */
.mq-card h3 {
    margin: 0;
    font-size: 1.1rem;
}

.mq-card p {
    margin: 0.6rem 0 0;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--slate);
}

/* Le badge numéroté du visuel : un carré vert plein, le chiffre en blanc, sur la MÊME LIGNE
   que le titre de l'étape. */
.mq-etape-tete {
    display: flex;
    align-items: center;
    gap: 0.65rem;
}

.mq-num {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    flex: none;
    border-radius: 7px;
    background: var(--green-deep);
    color: #fff;
    font-size: 0.82rem;
    font-weight: 700;
}

/* L'illustration des ÉTAPES est en bas de la carte · celle de la différenciation est en haut. */
.mq-illus-bas {
    display: block;
    width: 100%;
    max-width: 11rem;
    height: auto;
    margin: 1.4rem auto 0;
}

.mq-illus-haut {
    display: block;
    width: 100%;
    max-width: 11rem;
    height: auto;
    margin: 0 auto 1.1rem;
}

/*
    Les flèches du visuel entre les étapes : un tiret pointillé vert et une pointe. Elles
    n'apparaissent qu'à quatre colonnes, et jamais après la dernière carte, où elles pointeraient
    dans le vide.
*/
.mq-steps {
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 34rem) {
    .mq-steps {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/*
    ⚠️ UN TRIANGLE FIN EN CONTOUR, PLEINE HAUTEUR, EN VERT CLAIR.
    Trois versions ont précédé celle-ci, et chacune disait quelque chose :

      1. un `border-top: dashed` plus un carré tourné de 45° pour la pointe · les tirets ne
         tombaient pas sur la pointe et le carré donnait deux bouts coupés en biais ;
      2. un petit SVG de 38 x 14 px au niveau du titre · « des flèches chelou en texte » ;
      3. un chevron pleine hauteur au rapport 12:80 · la bonne échelle, mais un tracé OUVERT que
         l'étirement rendait illisible : il se lisait comme un trait oblique, pas comme une flèche ;
      4. un chevron reproportionné 16:28 · lisible, mais on perdait la pleine hauteur.

    La version 3 était la bonne piste, il lui manquait le côté gauche. Le `Z` ferme le tracé : le
    chevron et le trait vertical qui joint ses deux extrémités ne font qu'un seul `path`, donc un
    triangle fin qui pointe vers la carte suivante. La forme se lit même très étirée, parce que
    c'est une forme et non plus une direction à deviner.

    ⚠️ `background-size: contain` FAIT TOUT LE TRAVAIL. Le rapport est conservé, donc le trait
    garde une épaisseur uniforme quand la forme s'étire avec la carte · un
    `preserveAspectRatio='none'` l'aurait épaissi d'un seul côté, et `vector-effect` n'est pas
    fiable dans une image de fond.

    ⚠️ 52 % DE LA HAUTEUR DE LA CARTE, ET NON 76 %. La première version allait de 12 % à 12 % et
    faisait « un peu haute », le 8 septembre. La hauteur et la LARGEUR sont liées par le rapport du
    tracé : raccourcir sans y toucher aurait aussi aminci la forme. Le rapport passe donc de 12:80
    à 12:60, ce qui rend environ 35 px de large pour 175 de haut · les 8 px de chaque côté dans une
    gouttière de 51 l'empêchent de toucher les cartes.

    ⚠️ LA FORME EST REMPLIE D'UN DÉGRADÉ, ET LE CÔTÉ GAUCHE N'A PLUS DE TRAIT.
    Demandé le 8 septembre : rempli de vert à droite vers blanc à gauche, et le trait de gauche
    très pâle voire blanc puisque la forme est pleine. Le SVG porte donc DEUX tracés superposés :

      1. le triangle FERMÉ, rempli du dégradé · il va de `stop-opacity: 0` à gauche à 0,9 à droite ;
      2. les deux DIAGONALES seules, ouvertes, sans le côté gauche · elles tiennent la pointe.

    ⚠️ LE DÉGRADÉ VA VERS LA TRANSPARENCE, PAS VERS UN BLANC EN DUR. Le fond de la section est
    `--page`, soit #FBFCFC, et non du blanc pur : un `#FFFFFF` en dur laisserait un liséré plus
    clair que la page, visible en dégradé sur un côté. La transparence s'adapte au fond quel qu'il
    soit, y compris si la section devient teintée un jour.

    ⚠️ LE CÔTÉ GAUCHE N'EST PAS PEINT EN BLANC, IL EST ABSENT du second tracé. Le peindre en blanc
    aurait posé une ligne claire sur un fond presque blanc, donc un trait invisible mais réel, qui
    se serait mis à se voir à la première section teintée.

    ⚠️ #6FC9A3 pour les diagonales, et non le vert de la charte, demandé le 8 septembre : « en
    couleur claire ». Il donne 1,93:1 sur le fond de page, ce qui est faible ET admissible ici,
    parce que le tracé est strictement DÉCORATIF · il est posé par un `::after`, donc absent pour un
    lecteur d'écran, et l'ordre des étapes est déjà porté par les badges numérotés.

    ⚠️ Jamais après la DERNIÈRE carte, où il pointerait dans le vide. Et jamais sous 62 rem, où les
    cartes sont sur un ou deux rangs : une forme horizontale y désignerait la carte du dessous.
*/
@media (min-width: 62rem) {
    .mq-steps {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        column-gap: 3.2rem;
    }

    .mq-steps .mq-card {
        position: relative;
    }

    .mq-steps .mq-card:not(:last-child)::after {
        content: "";
        position: absolute;
        right: -3.2rem;
        top: 24%;
        bottom: 24%;
        width: 3.2rem;
        background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='60' viewBox='0 0 12 60'%3E%3Cdefs%3E%3ClinearGradient id='d' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%2312A06A' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%2312A06A' stop-opacity='0.9'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M3.4 4 9.2 30 3.4 56 Z' fill='url(%23d)'/%3E%3Cpath d='M3.4 4 9.2 30 3.4 56' fill='none' stroke='%236FC9A3' stroke-width='0.62' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
    }
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   4. PANNEAU TEINTÉ · la différenciation
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ QUATRE COLONNES IMPOSÉES, ET NON `auto-fit`. Mesuré : à 992 px `auto-fit` n'en rendait que
    trois, la quatrième carte tombant seule sur un second rang. `auto-fit` calcule ce qui TIENT, pas
    ce qu'on veut, et la carte orpheline casse la lecture de la rangée. Une seule colonne sous
    34 rem, où une carte de deux colonnes ne fait que 123 px de large.

    ⚠️ CES RÈGLES ONT DÉJÀ ÉTÉ EFFACÉES UNE FOIS, le 8 septembre. Elles vivaient juste AVANT
    l'entête de section ci-dessus, et deux remplacements successifs de la règle de la flèche ont
    pris cet entête comme borne de fin · les cartes sont donc revenues à `auto-fit` en silence,
    sans que rien ne le montre à l'écran d'un poste large. C'est la première passe de
    `_controles-maquette.py` qui l'a dit, en signalant `.mq-diff` employée sans règle.
    Elles sont désormais DANS leur section, après l'entête.
*/
.mq-diff {
    grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 34rem) {
    .mq-diff {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 62rem) {
    .mq-diff {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/*
    ⚠️ UN PANNEAU ARRONDI EN RETRAIT, PAS UNE BANDE PLEINE LARGEUR. Mesuré sur le visuel : la
    bande de gauche, x 6 à 18, est blanche sur TOUTE la hauteur de la page · aucune section colorée
    ne touche le bord. Ma première version employait `.tint` de la charte, qui va d'un bord à
    l'autre.
*/
.mq-tintpanel {
    background: var(--mq-tint);
    border-radius: var(--r-xl);
    /*
        ⚠️ Le rembourrage HAUT de ce panneau s'ajoute à celui des deux sections voisines. Mesuré,
        l'écart entre les cartes des étapes et le titre « TickDoc sait ce qu'il manque » valait
        41,6 + 41,6 + 57,6 = 141 px. Il en fait 27 + 27 + 38 = 92.
    */
    padding: clamp(1.6rem, 1rem + 2vw, 2.4rem) clamp(1.2rem, 0.6rem + 2vw, 2.4rem);
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   5. SÉCURITÉ · panneau vert sombre, image à ras du bord
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

.mq-secu {
    background: var(--mq-secu);
    border-radius: var(--r-xl);
    overflow: hidden;
    display: grid;
    align-items: center;
}

@media (min-width: 62rem) {
    .mq-secu {
        grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    }
}

.mq-secu-texte {
    padding: clamp(1.8rem, 1.2rem + 2.4vw, 3rem);
}

.mq-secu h2 {
    margin: 0 0 0.8rem;
    color: #fff;
}

.mq-secu-lead {
    margin: 0;
    color: #B9CBD1;
    font-size: 0.99rem;
    max-width: 44ch;
}

/*
    ⚠️ L'IMAGE VA À RAS DU BORD DU PANNEAU, elle n'est pas encadrée. Le panneau porte
    `overflow: hidden` et son arrondi, donc l'image se coupe proprement dans les coins.
    ⚠️ `12.png` est CARRÉE, à la demande · le panneau est plus large que haut, donc l'image
    se recadre par `object-fit: cover` plutôt que de dicter la hauteur du bloc.
*/
/*
    ⚠️ UN COMPROMIS, ET IL FAUT LE SAVOIR. `12.png` est CARRÉE, à la demande · posée à ras du bord
    d'une demi-colonne de 611 px, elle imposait 611 px de hauteur au panneau, là où le visuel n'en
    donne que 390. Le plafond de 27 rem la recadre d'environ un cinquième par `object-fit: cover`.
    Le sujet (bouclier, carte, dossier) est centré, donc le recadrage ne coupe rien d'essentiel ·
    mais la proportion carrée n'est plus tenue à l'écran. À arbitrer : garder le carré strict
    obligerait à un panneau beaucoup plus haut que le visuel.
*/
.mq-secu-img {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 15rem;
    max-height: 27rem;
    object-fit: cover;
}

/* Les quatre points du visuel portent un LIBELLÉ SEUL, sans phrase d'explication. */
.mq-secu-list {
    margin: 1.6rem 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 1rem;
}

/* ⚠️ La colonne passe à 26 px : le drapeau hexagonal est presque aussi large que haut, et à 22 px
   il débordait de sa piste de 3 px. Le débordement restait dans la carte, donc invisible. */
.mq-secu-list li {
    display: grid;
    grid-template-columns: 26px 1fr;
    gap: 0.8rem;
    align-items: start;
    color: #fff;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.35;
}

.mq-secu-list svg {
    margin-top: 0.1rem;
    color: #7FE0B4;
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   6. LES SIX MÉTIERS
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ SIX COLONNES IMPOSÉES, ET NON `auto-fit`. Mesuré : à 992 px `auto-fit` rendait CINQ colonnes
    plus une carte seule sur un second rang, et à 768 px quatre plus deux. Le visuel les met toutes
    les six sur un rang. `auto-fit` calcule ce qui TIENT, pas ce qu'on veut · et la carte orpheline
    d'un second rang casse la lecture de la rangée.
*/
.mq-metiers {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 46rem) {
    .mq-metiers {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 62rem) {
    .mq-metiers {
        grid-template-columns: repeat(6, minmax(0, 1fr));
    }
}

.mq-metiers .mq-card {
    align-items: center;
    text-align: center;
    padding: 1.6rem 1rem;
}

/*
    ⚠️ CALÉE SUR LA HAUTEUR, JAMAIS SUR LA LARGEUR. Les six icônes sont rognées à leur glyphe, donc
    elles n'ont plus le même rapport : la balance est haute et étroite, les deux personnages larges
    et bas. À largeur égale elles paraîtraient de tailles très différentes.
*/
.mq-metier-ico {
    display: block;
    height: 46px;
    width: auto;
    margin-bottom: 1rem;
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   7. BANDEAU FINAL
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

.mq-band {
    background: var(--mq-cta);
    border-radius: var(--r-xl);
    overflow: hidden;
    display: grid;
    align-items: center;
    gap: 1.6rem;
}

@media (min-width: 62rem) {
    .mq-band {
        grid-template-columns: minmax(0, 0.92fr) minmax(0, 1fr);
        gap: 0;
    }
}

.mq-band-texte {
    padding: clamp(1.8rem, 1.2rem + 2.6vw, 3.2rem);
}

.mq-band h2 {
    margin: 0 0 0.9rem;
    color: #fff;
}

.mq-band-lead {
    margin: 0;
    color: #E3F3EB;
    font-size: 1.02rem;
    max-width: 40ch;
}

/* L'image du visuel remplit la moitié droite du bandeau et se coupe sur son arrondi. */
.mq-band-img {
    display: block;
    width: 100%;
    height: auto;
}

/*
    ⚠️ LE LIBELLÉ D'UN BOUTON DE LA CHARTE NE SE COUPE JAMAIS : `white-space: nowrap` est posé sur
    `.btn`, ligne 354 de `tickdoc.css`. « Créer un compte gratuitement » a donc une largeur
    MINIMALE de 257 px, et à 320 px de fenêtre le bandeau n'en offre que 205 · son `overflow: hidden`
    coupait alors le bouton, sans faire défiler la page. Défaut plus discret qu'une barre de
    défilement : rien ne bougeait, le bouton était simplement tronqué.

    ⚠️ J'AI D'ABORD CRU QUE LA CAUSE ÉTAIT L'`inline-flex` de `.btn`, et le passage en `display:
    block` n'a rien changé · mesuré, la largeur minimale restait à 257 px. Il fallait lire la règle.
*/
.mq-band .btn {
    display: block;
    width: 100%;
    white-space: normal;
    text-align: center;
    padding-block: 0.85rem;
}

@media (min-width: 40rem) {
    .mq-band .btn {
        display: inline-flex;
        width: auto;
        white-space: nowrap;
    }
}

.mq-band .btn-primary {
    background: #fff;
    border-color: #fff;
    color: var(--green-deep);
}

/*
    ⚠️ CE BOUTON N'AVAIT AUCUN ÉTAT DE SURVOL, et c'est la passe de survol de `_audit.js` qui l'a
    fait voir. Elle annonçait 1,27:1, ce qui est un FAUX POSITIF de sa méthode : elle remplace
    `:hover` par une classe, donc `.btn-primary:hover` (0,1,1) devient (0,2,0) et gagne en passant
    en dernier. Dans la vraie cascade c'est `.mq-band .btn-primary` (0,2,0) qui gagne, le fond reste
    blanc, et le contraste reste à 5,22:1. Mais le faux positif désignait un vrai manque :
    `.btn-primary:hover { background: #0A6A46 }` de la charte était écrasé, donc RIEN ne changeait
    sous le pointeur. Vert profond sur --green-wash : 4,84:1.
*/
.mq-band .btn-primary:hover {
    background: var(--green-wash);
}

/* Le second geste du visuel est un LIEN FLÉCHÉ, pas un bouton à liséré. */
.mq-lien-fleche {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    margin-top: 1rem;
    color: #fff;
    font-weight: 600;
    font-size: 0.98rem;
    text-decoration: none;
}

.mq-lien-fleche:hover {
    text-decoration: underline;
}

.mq-band-notes {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.5rem;
    margin: 1.8rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.88rem;
    color: #E3F3EB;
}

.mq-band-notes li {
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────────
   8. PIED DE PAGE
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/*
    ⚠️ LE REMBOURRAGE DU `footer` DE LA CHARTE EST REMIS À ZÉRO, ET SANS CELA L'ÉCART NE PEUT PAS
    S'ÉGALISER. Mesuré : le filet du haut est le `border-top` du `footer`, et l'écart jusqu'au
    premier texte valait 89 px — 54,4 du `footer` plus 33,6 de `.mq-foot` — contre 16 px seulement
    entre le dernier lien et le filet du bas. Demandé le 8 septembre : les deux à égalité.

    Les 28 px sont désormais portés par `.mq-foot` SEUL, en haut comme en bas, donc les deux écarts
    sont égaux par construction et le resteront si l'un des deux est ajusté.

    ⚠️ `footer` est un sélecteur d'élément (0,0,1), de même poids que celui de la charte : c'est
    l'ORDRE de chargement qui départage, et cette feuille vient après. Le jour où elle serait
    chargée avant, le rembourrage reviendrait sans qu'aucun contrôle ne le dise.
*/
/*
    ⚠️ Hauteur RESSERRÉE le 8 septembre : le pied mesurait 420 px pour 227 au visuel. Le
    rembourrage haut, la gouttière entre colonnes et la marge des titres descendent ensemble · un
    seul des trois n'aurait presque rien changé.
*/
/*
    ⚠️ 2,5 rem, ET DES DEUX CÔTÉS. « Plus d'espace entre le haut du texte du pied et le trait » a
    été demandé le 8 septembre · l'égalité haut/bas l'avait été la veille. Augmenter le seul
    rembourrage du haut aurait satisfait la seconde demande en défaisant la première : les 40 px
    sont donc portés en haut comme en bas, et les deux écarts restent égaux par construction.
*/
.mq-foot {
    display: grid;
    gap: 1.6rem;
    padding-block: 2.5rem;
}

@media (min-width: 62rem) {
    .mq-foot {
        grid-template-columns: 1.6fr 1fr 1fr 1fr 1.2fr;
    }
}

/* Le lettrage du pied garde le traitement de l'entête, à une taille moindre : « un peu plus grand »
   ne visait que l'entête. */
/* ⚠️ `min-height: 44px` et non `auto` : c'est un LIEN, et `_audit.js` le comptait à 39 px. */
.mq-foot-marque .mq-logo {
    font-size: 1.5rem;
    min-height: 44px;
}

.mq-foot-marque .mq-logo img {
    width: 38px;
    height: 38px;
}

.mq-foot-marque p {
    margin: 0.9rem 0 1rem;
    font-size: 0.92rem;
    line-height: 1.45;
    color: var(--slate);
    max-width: 30ch;
}

.mq-foot h2 {
    margin: 0 0 0.3rem;
    font-size: 0.92rem;
    font-weight: 700;
    letter-spacing: 0;
    color: var(--ink);
}

.mq-foot ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

/*
    La cible tactile se pose sur le LIEN, jamais sur le `li` : un rembourrage sur le conteneur
    agrandit la zone visible sans agrandir la zone cliquable.

    ⚠️ 32 px AU POINTEUR FIN, 44 AU DOIGT, ET C'EST UN ÉCART ASSUMÉ À LA RÈGLE DU PROJET.
    Le projet s'est fixé 44 px partout · à 0,92 rem de corps cela donnait des lignes très aérées, et
    « le footer a les liens trop espacés en hauteur » est le retour du 8 septembre. 32 px reste
    au-dessus des 24 px du critère AA (WCAG 2.5.8), et `pointer: coarse` rend les 44 px sur tout
    écran tactile, là où la cible compte vraiment.
    ⚠️ CONSÉQUENCE À NE PAS TAIRE : `_audit.js` signalera ces liens comme étant sous 44 px sur un
    poste de travail. C'est voulu, ce n'est pas un défaut oublié.

    ⚠️ Le soulignement était « trop bas » : son décalage automatique se calculait sur une boîte de
    44 px. Il est posé explicitement, près du texte.
*/
.mq-foot ul a {
    display: flex;
    align-items: center;
    min-height: 32px;
    font-size: 0.95rem;
    color: var(--slate);
    text-decoration: none;
    text-underline-offset: 0.14em;
    text-decoration-thickness: 1px;
}

@media (pointer: coarse) {
    .mq-foot ul a {
        min-height: 44px;
    }
}

.mq-foot ul a:hover {
    color: var(--green-deep);
    text-decoration: underline;
}

/* ⚠️ `.mq-social` A ÉTÉ RETIRÉE AVEC LE LIEN LINKEDIN, le 8 septembre 2026, sur décision de
   Christophe. Le lien pointait sur `#` faute d'adresse connue, et le pied du site en ligne n'en
   porte aucun. Une règle sans élément à viser n'est signalée par aucun contrôle : la première passe
   compare les classes employées aux règles déclarées, pas l'inverse.

   ⚠️ AUCUN HISTORIQUE GIT NE LA RENDRAIT — `moi/` n'est pas un dépôt. La voici :

       .mq-social       { display: grid; place-items: center; width: 44px; height: 44px;
                          border-radius: var(--r-sm); color: var(--slate); }
       .mq-social:hover { color: var(--green-deep); background: var(--raised); } */

/* Les deux lignes de confiance du visuel n'ont PAS de titre de colonne. */
.mq-foot-trust {
    display: grid;
    gap: 1rem;
    align-content: start;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.92rem;
    color: var(--slate);
}

.mq-foot-trust li {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.mq-foot-trust svg {
    flex: none;
    color: var(--green-deep);
}

/*
    ⚠️ 5 · LE DRAPEAU EST UNE IMAGE, PAS UN SVG DESSINÉ À LA MAIN.
    Mes trois rectangles empilés faisaient « moche et trop petit », le 8 septembre. `ico07.png` est
    le drapeau hexagonal de micrologiciel.fr, et il porte déjà son canal alpha.
    ⚠️ Il est calé sur la HAUTEUR : c'est un hexagone à peine plus large que haut, et le caler sur
    la largeur le ferait dépasser de la ligne de texte.
*/
.mq-drapeau {
    display: block;
    height: 26px;
    width: auto;
    flex: none;
}

.mq-trust .mq-drapeau {
    height: 30px;
}

/*
    ⚠️ 4 · LE CHOIX DE LA LANGUE EST ICI, sous « Conforme RGPD », et non plus dans la ligne du
    copyright. Demandé le 8 septembre · il laisse le copyright seul et vraiment centré.
    ⚠️ La cible reste à 44 px : c'est un lien de navigation, pas une mention en ligne dans une
    phrase, donc l'exemption des liens en ligne ne s'y applique pas.
*/
/*
    ⚠️ LE SÉLECTEUR EST `.mq-foot a.mq-foot-langue`, ET PAS `.mq-foot-langue` SEUL. La classe
    seule pèse (0,1,0) et `.mq-foot ul a` (0,1,2) : le `min-height: 44px` était donc écrasé par les
    32 px des liens de colonne, et `_audit.js` comptait ce lien parmi les cibles trop petites. C'est
    la collision « classe + élément contre classe seule » que la charte documente en tête de
    `tickdoc.css`, rencontrée une fois de plus.

    ⚠️ IL DISAIT `.mq-foot ul a.mq-foot-langue`, ET CE `ul` EST DEVENU UN PIÈGE le 8 septembre 2026 :
    le lien a été déplacé sous le logo, dans un `div`, donc la règle ne l'atteignait plus et il
    reperdait ses 44 px — le défaut même qu'elle existe pour empêcher, ressuscité par un
    déplacement. Le `ul` est retiré du sélecteur et la spécificité tient toute seule : deux classes
    (0,2,1) battent la classe unique de `.mq-foot ul a`, où qu'il soit posé.
*/
.mq-foot a.mq-foot-langue {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-height: 44px;
    margin-top: 0.2rem;
    color: var(--green-deep);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    text-underline-offset: 0.14em;
}

/* Même arbitrage de spécificité que ci-dessus : `.mq-foot ul a:hover` pèse (0,2,2). */
.mq-foot a.mq-foot-langue:hover {
    text-decoration: underline;
}

/* Le copyright du visuel est CENTRÉ, seul, sous un filet. */
/* Le `footer` n'ayant plus de rembourrage propre, c'est ce bloc qui ferme la page : 2 rem en bas,
   sinon le copyright se collerait au bord de la fenêtre. */
/*
    ⚠️ LE FILET DU BAS VA D'UN BORD À L'AUTRE, comme celui du haut du pied.
    Celui du haut est le `border-top` du `footer`, donc pleine largeur · celui du bas s'arrêtait à
    1 344 px quand il vivait DANS la coquille. Les deux filets n'avaient pas la même longueur, et
    cela se voyait. `.mq-foot-bas` est donc sorti de la coquille et porte la sienne à l'intérieur.

    ⚠️ LES DEUX DÉCLARATIONS DE CETTE CLASSE SONT FONDUES ICI. La maquette en portait deux, à
    deux endroits de la feuille : elles ne touchaient aucune propriété commune, donc le rendu était
    juste · mais à poids égal c'est l'ORDRE qui départage, et le jour où la première reçoit un
    `padding` la seconde le mange sans qu'aucun contrôle ne le dise. Le projet a déjà payé ce
    défaut : une seconde règle `.field-inline` avait décalé un bouton de 14 px sur trois écrans.
*/
.mq-foot-bas {
    border-top: 1px solid var(--border);
    padding: 1.25rem 0 2rem;
    text-align: center;
    font-size: 0.88rem;
    color: var(--slate-soft);
}

/*
    ⚠️ `max-width: none` EST NÉCESSAIRE, ET C'EST CE QUI DÉCENTRAIT LE COPYRIGHT.
    La charte pose `p { max-width: var(--measure) }`, soit 62 ch, à la ligne 142 de `tickdoc.css` :
    mesuré, le paragraphe faisait donc 471 px et se centrait DANS ces 471 px, alors que la coquille
    en fait 1 344. Le `text-align: center` du parent était bien appliqué · il centrait juste le
    texte dans une boîte qui n'était pas centrée elle-même.
*/
.mq-foot-bas p {
    margin: 0;
    max-width: none;
}

.mq-foot-bas a {
    color: var(--slate);
}

/*
    ⚠️ L'OUTILLAGE DE MAQUETTE A ÉTÉ RETIRÉ le 8 septembre : le bouton « Révéler les points à
    arbitrer » et les encadrements en pointillé qu'il posait sur `data-ecart`, `data-arbitrer` et
    `data-inexistant`.

    ⚠️ LES ATTRIBUTS `data-*`, EUX, RESTENT DANS LE BALISAGE. Ils ne produisent plus aucun rendu,
    et ils sont la seule trace de ce qui reste à trancher : les six liens sans page, les écarts
    assumés au visuel et les points fidèles mais discutables. `_controles-maquette.py` les compte à
    sa sixième passe, et le README les énumère. Les supprimer ferait perdre la liste.
*/

/* ═════════════════════════════════════════════════════════════════════════════════════════════════
   9. LES PAGES INTÉRIEURES · huit pages, la même géométrie que la home
   ═════════════════════════════════════════════════════════════════════════════════════════════════

   ⚠️ LA GÉOMÉTRIE VIENT DE LA HOME, PAS DES SIX MAQUETTES DE PAGE, et c'est un constat de mesure,
   pas un choix de confort. Les six visuels `moi/notes/01.png` à `06.png` donnent une coquille allant
   de 74,9 % à 87,6 % de leur largeur selon la page — mesuré sur l'entête, du bord du logo au bord
   du bouton. Un écart de treize points d'une page à l'autre n'est pas une spécification : leur
   structure et leur contenu sont exploitables, leur géométrie non. Le visuel de la home, lui, était
   cohérent, et il est déjà relevé au pixel. Toutes les pages emploient donc `--mq-max`.

   ⚠️ CONSÉQUENCE HEUREUSE : la home cesse d'être une exception de largeur. C'était le troisième des
   six points à trancher du README · il tombe de lui-même dès que les huit autres pages sont à
   84 rem.

   ⚠️ CE BLOC N'AJOUTE QUE CE QUE LA CHARTE N'A PAS. `.field`, `.hint`, `.trap`, `.form-status`,
   `.tiers`, `.tier`, `.tier-featured`, `.tier-flag`, `.tier-for`, `.table-scroll`, `.prose`,
   `.checks` et `.breadcrumb` existent dans `tickdoc.css` et sont employées telles quelles. Les
   redéclarer aurait été la faute que la passe 3 des contrôles cherche : deux règles de même poids,
   départagées par leur ordre, en silence.
   ───────────────────────────────────────────────────────────────────────────────────────────────── */

/* ── 9.1 · Le hero d'une page intérieure ────────────────────────────────────────────────────────
   Même colonne de texte que la home. La différence est l'image : celle de la home est une
   composition volontairement PLUS LARGE que sa colonne, celle-ci reste dans la sienne. */

.mq-hero-page {
    grid-template-columns: 1fr;
}

.mq-hero-img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--r-lg);
}

/* ⚠️ `.mq-hero-img-sombre` A ÉTÉ RETIRÉE LE 8 SEPTEMBRE 2026, ET SA CAUSE EST UNE IMAGE.
   Elle disait : « `hero-securite.webp` est une image SOMBRE, elle porte son propre fond, et une
   ombre claire ne s'y verrait pas · c'est un liséré sombre qui la détache du blanc de la page. »
   Le raisonnement était juste, et sa prémisse est tombée : la source est passée de `18.png` à
   `18-bis.png`, qui est CLAIRE — luminance de bord 249,7 contre 26,1. Un liséré sombre autour d'une
   image claire sur fond blanc se lit comme un cadre, pas comme un détachement.

   ⚠️ SON CONTENU EST RECOPIÉ ICI, PARCE QU'IL N'Y A AUCUN HISTORIQUE POUR LE RENDRE. `moi/` n'est
   pas un dépôt git : `git` y répond « not a git repository ». Pour la rétablir si une image sombre
   revient un jour :

       .mq-hero-img-sombre { border: 1px solid #0B3A2A; box-shadow: var(--sh-2); }

   ⚠️ Une règle sans élément à viser n'est signalée par aucun contrôle — la première passe compare
   les classes employées aux règles déclarées, pas l'inverse. Troisième retrait de ce genre
   aujourd'hui, après `.mq-social` et `.mq-avert`. */

/* Les trois repères numérotés sous les boutons du hero de « Comment ça marche ». */
.mq-hero-mini {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem 1.8rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.mq-hero-mini li {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.9rem;
    line-height: 1.3;
    color: var(--slate);
    max-width: 15rem;
}

/*
    ⚠️ 1,55 rem DE CÔTÉ, PAS 44 px. Ce n'est pas une cible tactile : c'est une pastille décorative
    à l'intérieur d'un élément de liste qui n'est pas cliquable. La règle des 44 px porte sur les
    liens et les boutons · l'appliquer ici gonflerait la ligne sans rien rendre atteignable.
*/
.mq-hero-mini b {
    flex: none;
    display: grid;
    place-items: center;
    width: 1.55rem;
    height: 1.55rem;
    border-radius: 50%;
    background: var(--green-wash);
    border: 1px solid var(--green);
    color: var(--green-deep);
    font-size: 0.8rem;
    font-weight: 700;
}

/* ── 9.2 · La pastille d'icône, présente dans toutes les grilles des six visuels ───────────────── */

.mq-ico {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: 1rem;
    border-radius: var(--r-md);
    background: var(--green-wash);
    color: var(--green-deep);
}

.mq-ico-rond {
    border-radius: 50%;
}

/*
    ⚠️ La pastille du bandeau SOMBRE ne peut pas garder `--green-wash` : sur `--mq-secu`, un fond
    presque blanc porterait une icône vert profond à 1,2:1 contre son entourage. Fond translucide
    clair et icône `#7FE0B4`, la même que `.mq-secu-list svg`, qui est mesurée.
*/
.mq-ico-sombre {
    background: rgba(127, 224, 180, 0.14);
    color: #7FE0B4;
}

/* ── 9.3 · Nombres de colonnes explicites ───────────────────────────────────────────────────────
   `.mq-cards` est en `auto-fit minmax(14rem, 1fr)`, ce qui convient à trois et six cartes. À
   quatre et à deux, l'auto-fit donne des lignes de trois puis une carte seule. */

.mq-cards-2 {
    grid-template-columns: 1fr;
}

.mq-cards-3 {
    grid-template-columns: 1fr;
}

.mq-cards-4 {
    grid-template-columns: 1fr;
}

/* ── 9.4 · Un titre de section aligné à gauche, dans un bloc à deux colonnes ─────────────────── */

.mq-h2 {
    margin: 0 0 0.9rem;
    font-size: clamp(1.5rem, 1.05rem + 1.4vw, 2.05rem);
    line-height: 1.16;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.mq-h2 b {
    font-weight: inherit;
    color: var(--green);
}

.mq-lead {
    margin: 0 0 1.4rem;
    font-size: 1.02rem;
    line-height: 1.55;
    color: var(--slate);
    max-width: 46ch;
}

/* ── 9.5 · Texte d'un côté, média de l'autre ──────────────────────────────────────────────────── */

.mq-split {
    display: grid;
    gap: 2rem;
    align-items: center;
}

/* Même bridage que `.mq-vue-img`, et pour la même raison. */
.mq-split-img {
    display: block;
    width: 100%;
    max-width: 27rem;
    height: auto;
    margin-inline: auto;
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
}

/* ── 9.6 · L'encart de rappel, sur fond teinté ─────────────────────────────────────────────────── */

.mq-encart {
    margin-top: 1.5rem;
    padding: 1rem 1.15rem;
    border-radius: var(--r-md);
    background: var(--mq-tint);
    border-left: 3px solid var(--green);
    font-size: 0.97rem;
    line-height: 1.5;
    color: var(--ink);
}

/* ── 9.7 · Les deux vues · « ce que voit le professionnel », « ce que voit le destinataire » ───── */

.mq-vues {
    display: grid;
    gap: 1.4rem;
    margin-top: 2.4rem;
}

.mq-vue {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    padding: clamp(1.2rem, 0.8rem + 1.4vw, 1.8rem);
}

.mq-vue-tete {
    display: grid;
    grid-template-columns: 2.75rem 1fr;
    gap: 0.9rem;
    align-items: center;
    margin-bottom: 1.4rem;
}

.mq-vue-tete .mq-ico {
    margin-bottom: 0;
}

/*
    ⚠️ `h2` ET `h3` ENSEMBLE, et ce n'est pas une hésitation. Le niveau dépend de la page : sur
    « Comment ça marche » et « Sécurité », le panneau suit un `h2` de section, donc son titre est un
    `h3` · sur « Données personnelles », il suit directement le `h1` de la page, donc c'est un `h2`,
    et sauter au `h3` casserait la hiérarchie que `_audit-seo-rgaa.py` contrôle. Le style est le
    même parce que le rôle visuel est le même.
*/
.mq-vue-tete h2,
.mq-vue-tete h3 {
    margin: 0;
    font-size: 1.16rem;
}

.mq-vue-tete p {
    margin: 0.2rem 0 0;
    font-size: 0.94rem;
    color: var(--slate);
}

/* Un paragraphe posé directement dans le panneau, hors de son entête et de son pied. */
.mq-vue > p {
    margin: 0 0 1rem;
    font-size: 0.99rem;
    line-height: 1.55;
    color: var(--slate);
}

/*
    ⚠️ BRIDÉE, ET SANS CELA L'ILLUSTRATION MANGE LE PANNEAU. Vu à l'écran, pas déduit : à 1 440 px
    une illustration de 440 px de large s'étirait à près de 500, soit 250 px de haut au-dessus de
    quatre lignes de texte. Le visuel `03.png` met là des captures de produit, plus petites et plus
    informatives · à défaut de les avoir en source, l'illustration reste décorative et doit donc
    passer après le texte, pas avant.
*/
.mq-vue-img {
    display: block;
    width: 100%;
    max-width: 19rem;
    height: auto;
    margin: 0 auto 1.3rem;
    border-radius: var(--r-md);
}

/*
    ⚠️ L'ESPACE AU-DESSUS VIENT DE LA LISTE, PAS D'ICI, ET C'EST `margin-top: auto` QUI L'IMPOSE.
    Demandé par Christophe le 8 septembre 2026 : les deux notes se collaient à la liste, alors que
    les trois `.mq-cite` de la section suivante ont 1,2 rem au-dessus. On ne peut pas le corriger sur
    cette règle — `auto` est ce qui aligne les deux notes sur le BAS de leurs panneaux, et une seule
    valeur ne peut pas être à la fois `auto` et un minimum. L'espace est donc posé en marge BASSE de
    la liste qui précède, ce qui garantit 1,2 rem au minimum et laisse `auto` absorber le reste.

    ⚠️ LE SÉLECTEUR EST `.mq-vue .checks`, JAMAIS `.checks` SEUL. `.checks` vient de `tickdoc.css` et
    la maquette ne la redéclare pas, exprès : deux règles de même poids départagées par leur ordre
    sont précisément ce que la passe 3 des contrôles cherche. Ici la portée est ajoutée, donc le poids
    diffère et l'arbitrage reste lisible.

    ⚠️ 0,6 REM, ET NON LES 1,2 REM QUE `.mq-cite` DÉCLARE · PARCE QUE `.mq-cite` N'OBTIENT PAS CE
    QU'ELLE DEMANDE. Mesuré : sa marge calculée vaut 9,6 px et non 19,2. `.mq-card p` pèse (0,1,1) et
    écrase `.mq-cite` (0,1,0) malgré sa position plus haut dans le fichier — la spécificité bat
    l'ordre. La consigne était « pareil que dans l'autre section », donc la valeur de référence est
    celle qui S'APPLIQUE, pas celle qui est écrite. Neuvième occurrence de ce piège dans le projet.
    ⚠️ À rouvrir avec Christophe : réparer `.mq-cite` porterait les deux sections à 19 px, ce qui
    était l'intention d'origine. Les deux valeurs sont défendables, celle-ci est fidèle au rendu.
*/
.mq-vue .checks {
    margin-bottom: 0.6rem;
}

.mq-vue-pied {
    margin-top: auto;
    padding: 0.9rem 1rem;
    border-radius: var(--r-md);
    background: var(--mq-tint);
    font-size: 0.93rem;
    line-height: 1.45;
    color: var(--ink);
}

/* ── 9.8 · Deux colonnes de garanties, dans un panneau teinté ──────────────────────────────────── */

.mq-duo {
    display: grid;
    gap: 2rem;
    margin-top: 2.2rem;
}

.mq-duo-tete {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin: 0 0 1.2rem;
    font-size: 1.14rem;
}

.mq-duo-tete svg {
    flex: none;
    color: var(--green-deep);
}

/* ── 9.9 · Les badges du bandeau sombre de la page Sécurité ────────────────────────────────────── */

.mq-badges {
    display: grid;
    gap: 0.8rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
    margin-top: 1.8rem;
}

.mq-badge {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.75rem 0.9rem;
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(127, 224, 180, 0.3);
    color: #fff;
    font-size: 0.88rem;
    font-weight: 600;
    line-height: 1.3;
}

.mq-badge svg {
    flex: none;
    color: #7FE0B4;
}

/* ── 9.9 bis · Le bouton DANS le panneau sombre ────────────────────────────────────────────────
   ⚠️ TROUVÉ EN MESURANT, ET INVISIBLE AUTREMENT · c'est le piège nº 4 du README, pris en flagrant
   délit. `.btn` porte `white-space: nowrap`, donc « Créer un compte gratuitement » mesure 257 px
   sans pouvoir se couper. À 320 px de fenêtre, le bloc de texte du panneau était donc forcé à
   314 px pour une largeur disponible de 265 · et `.mq-secu` porte `overflow: hidden`, donc
   RIEN NE DÉBORDAIT ET RIEN NE DÉFILAIT. Le document mesurait exactement la largeur de la
   fenêtre, le contrôle était vert, et le bouton était coupé.

   ⚠️ Le panneau sombre de la HOME n'avait pas ce défaut parce qu'il ne contient aucun bouton :
   c'est cette page qui en ajoute un. Un bloc partagé ne se valide pas une fois pour toutes, il se
   revalide avec ce qu'on met dedans.

   ⚠️ Traitement identique à `.mq-band .btn`, qui règle le même problème dans le bandeau final,
   et non une seconde déclaration de `.mq-band .btn` : deux règles de même poids se départagent
   par leur ordre, en silence. */
/* ⚠️ Plafonné, contrairement à celui du bandeau final : la colonne de texte du panneau sombre est
   plus large ici, et un bouton de 600 px se lit comme une barre, plus comme un bouton. */
.mq-secu .btn {
    display: block;
    width: 100%;
    max-width: 22rem;
    white-space: normal;
    text-align: center;
    padding-block: 0.85rem;
}

.mq-secu .btn-primary {
    background: #fff;
    border-color: #fff;
    color: var(--green-deep);
}

.mq-secu .btn-primary:hover {
    background: var(--green-wash);
}

/*
    ⚠️ LE PANNEAU SOMBRE REÇOIT UN SECOND BOUTON, ET `.btn-ghost` N'AVAIT AUCUNE RÈGLE ICI.
    Le §9 de la fiche Sécurité demande deux appels — « Nous contacter » et « Créer un compte
    gratuit ». Sans cette règle, `.btn-ghost` garde ses valeurs de fond clair : `background:
    var(--surface)`, soit un bouton PRESQUE BLANC posé à côté du bouton principal, lui aussi rendu
    blanc sur ce panneau. Deux barres blanches identiques, dont l'une est censée être secondaire.

    ⚠️ ET LA MESURE DE CONTRASTE NE L'AURAIT PAS SIGNALÉ : le texte serait resté de l'encre sur du
    clair, donc lisible. C'est un défaut de HIÉRARCHIE, pas de contraste, et il ne se voit qu'en
    ouvrant la page. Même famille que le bouton secondaire désactivé plus appuyé que l'actif.

    ⚠️ LE LISÉRÉ EST À 38 % ET NON À 28 % COMME `.dark .btn-ghost` DE LA CHARTE, et c'est calculé.
    Sur `--mq-secu` (#012318), du blanc composité à 28 % donne 2,48:1, sous les 3:1 qu'exige
    WCAG 1.4.11 pour la limite visuelle d'un composant. À 38 % il donne 3,48:1, et le texte 16,73:1.
    Les trois valeurs sont MESURÉES sur le style calculé, fond réellement peint compris : 0,34 est
    le premier palier qui passe, à 3,05:1, et 0,38 laisse de la marge.
    ⚠️ `.dark .btn-ghost` PORTE DONC LE MÊME DÉFAUT, à 28 %, sur les pages qui emploient encore la
    bande sombre du premier design. Il n'est pas corrigé ici : ce n'est pas le périmètre de cette
    reprise, et `.dark` disparaît quand la dernière page est refondue. Signalé, pas corrigé.
*/
.mq-secu .btn-ghost {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.38);
    color: #fff;
}

.mq-secu .btn-ghost:hover {
    border-color: rgba(255, 255, 255, 0.68);
}

/* ── 9.10 · Le bénéfice cité, sur la page « Comment ça marche » ────────────────────────────────── */

/*
    ⚠️ CE N'EST PAS UN TÉMOIGNAGE CLIENT, et le visuel `01.png` en portait trois, entre guillemets.
    Le produit est en ligne depuis le 12 août 2026 et aucun parcours complet n'y a encore été fait :
    aucun client n'a pu dire cela. Un avis inventé est un mensonge, et chez Google un motif de
    sanction manuelle · c'est déjà pour cette raison que la septième passe de `_controles.py` refuse
    tout `aggregateRating` et tout `review` dans les données structurées du site. Le bloc garde donc
    sa place et sa forme, et porte une phrase qui décrit ce que le produit FAIT. Voir README.md.
*/
.mq-cite {
    margin-top: 1.2rem;
    padding: 0.95rem 1.05rem;
    border-radius: var(--r-md);
    background: var(--green-wash);
    font-size: 0.94rem;
    line-height: 1.5;
    color: var(--ink);
}

/* ── 9.10 bis · LES SIX ANCRES DE MÉTIER ATTERRISSENT SOUS L'ENTÊTE COLLANTE ───────────────────
   ⚠️ SANS CELA, `cas-usage.html#immobilier` CACHE LE TITRE DE SA SECTION. Signalé par Christophe le
   8 septembre 2026. `.masthead` est en `position: sticky` et mesure 77 px : le navigateur amenait
   la cible tout en haut de la fenêtre, donc **sous** l'entête, et le haut du panneau vert
   « Des exemples concrets. » restait hors écran. Le visiteur arrivait au milieu d'un bloc sans
   savoir ce qu'il regardait.

   ⚠️ LES SIX CIBLES SONT À UN DÉCALAGE FIXE DU HAUT DE LEUR SECTION, ce qui rend une seule valeur
   possible par famille. Mesuré à 1 440 px : les trois `.mq-exemple` sont côte à côte dans une
   grille, donc **tous trois** à 157 px sous le haut du panneau · les trois `.mq-card` de « Et
   aussi. » à 132 px sous le haut de leur section. D'où deux valeurs et non six.

   ⚠️ LE CALCUL : décalage + hauteur d'entête + une respiration. 157 + 77 + 14 = 248 px, et
   132 + 77 + 15 = 224 px · le haut de la section se pose alors à environ 91 px du bord, soit 14 px
   sous l'entête. `scroll-margin-top` ne s'applique QUE lors d'un défilement vers la cible, il est
   donc sans effet le reste du temps.

   ⚠️ LA PAGE 04 DE LA REFONTE VA DÉPLACER CES SIX `id` sur un bloc unique (§14) · les deux
   décalages changeront, et ces valeurs sont à remesurer ce jour-là. Ne pas les recopier à l'aveugle. */
.mq-exemple[id] {
    scroll-margin-top: 15.5rem;
}

.mq-card[id] {
    scroll-margin-top: 14rem;
}

/* ── 9.11 · Les six métiers, en cartes cliquables ──────────────────────────────────────────────── */

.mq-metier-carte {
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.mq-metier-carte:hover {
    border-color: var(--green);
    box-shadow: var(--sh-2);
}

/*
    ⚠️ La cible tactile, c'est la CARTE ENTIÈRE, qui est le lien. Cette flèche n'est qu'un repère
    visuel à l'intérieur, et n'a donc pas à faire 44 px. Les neuf liens du pied de la vitrine
    actuelle font 21 px pour avoir posé le rembourrage sur le `li` plutôt que sur le lien.
*/
.mq-metier-fleche {
    display: grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    margin-top: 1.1rem;
    border-radius: 50%;
    background: var(--green-wash);
    color: var(--green-deep);
}

/* ── 9.12 · Les trois exemples concrets de la page Cas d'usage ─────────────────────────────────── */

.mq-exemples {
    display: grid;
    gap: 1.4rem;
    margin-top: 2.4rem;
}

.mq-exemple {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    overflow: hidden;
}

/*
    ⚠️ `contain` ET NON `cover`, ET UN FOND TEINTÉ. Le visuel `04.png` met ici trois PHOTOS en
    16:9, qui se recadrent sans dommage. Ce sont ici les tuiles découpées de `20.png`, qui portent
    une illustration détachée et sa pastille : `cover` en couperait la pastille, c'est-à-dire
    précisément le repère métier. Écart au visuel assumé, faute de photos en source.
*/
.mq-exemple-photo {
    display: block;
    width: 100%;
    height: 9.5rem;
    padding: 0.6rem;
    background: var(--mq-tint);
    object-fit: contain;
}

.mq-exemple-tag {
    position: relative;
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: 0.45rem;
    margin: -1.5rem 0 0 1.1rem;
    padding: 0.4rem 0.75rem;
    border-radius: var(--r-sm);
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--sh-1);
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--ink);
}

.mq-exemple-tag svg {
    color: var(--green-deep);
}

.mq-exemple-corps {
    display: flex;
    flex: 1;
    flex-direction: column;
    padding: 1rem 1.15rem 1.15rem;
}

.mq-exemple-corps h3 {
    margin: 0 0 0.5rem;
    font-size: 1.1rem;
}

.mq-exemple-corps p {
    margin: 0 0 1.1rem;
    font-size: 0.97rem;
    line-height: 1.5;
    color: var(--slate);
}

.mq-exemple-bas {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 1rem;
    align-items: center;
    margin-top: auto;
    padding-top: 0.4rem;
}

/*
    ⚠️ Une PHRASE, pas un libellé de jauge. La première version réemployait `.mq-jauge-txt`, qui
    fait 0,78 rem parce qu'il ne porte que « pièces reçues » sous l'anneau. Deux lignes de texte
    courant à cette taille tombent sous le seuil de lisibilité que le projet s'est fixé.
*/
.mq-exemple-note {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--slate);
}

.mq-jauge {
    display: grid;
    place-items: center;
    text-align: center;
}

.mq-jauge-txt {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.78rem;
    color: var(--slate);
}

/* ── 9.13 · La grille tarifaire ────────────────────────────────────────────────────────────────── */

/*
    ⚠️ LES VALEURS DE CETTE GRILLE VIENNENT DE `deploy/sql/03-commercial-plans.sql`, QUI FAIT FOI,
    et NON du visuel `05.png`. Le visuel nomme la troisième offre « Équipe » là où la base et tout
    le produit disent « Complet », et ses cartes ne portent AUCUN quota de dossiers — le
    différenciateur principal. La grille vit en cinq endroits, et la sixième passe de
    `_controles.py` confronte les deux pages de tarifs au script SQL. Une page qui promet ce que la
    base n'accorde pas ne se découvre qu'avec un client mécontent.
*/
.mq-tier-ico {
    display: grid;
    place-items: center;
    width: 3.4rem;
    height: 3.4rem;
    margin: 0 auto 1rem;
    border-radius: 50%;
    background: var(--green-wash);
    color: var(--green-deep);
}

/*
    ⚠️ LE HAUT DE LA CARTE EST CENTRÉ, ET LA LISTE RESTE À GAUCHE. Le visuel `05.png` centre le
    nom, la phrase d'usage et le prix · `.tier h2` et `.tier-for` de la charte sont alignés à
    gauche, ce qui donnait une carte à l'icône et au prix centrés et au titre à gauche. Centrer la
    carte ENTIÈRE serait pire : une liste de onze lignes centrée ne se lit pas, l'œil ne trouve
    plus le début des lignes.

    ⚠️ `.tiers .tier > h2` pèse (0,2,1) et bat `.tier h2` (0,1,1) de la charte · le `>` limite la
    portée au titre de la carte, sans toucher aux `h3` que d'autres blocs pourraient y placer.
*/
.tiers .tier > h2,
.tiers .tier > .tier-for {
    text-align: center;
}

.mq-tier-prix {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.35rem;
    margin: 0.6rem 0 0.3rem;
}

.mq-tier-prix strong {
    font-size: clamp(2.2rem, 1.6rem + 2vw, 2.9rem);
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--ink);
}

.mq-tier-prix span {
    font-size: 0.88rem;
    color: var(--slate);
}

/*
    ⚠️ NI `.mq-table` NI CLASSE DE COLONNE MISE EN AVANT : la charte les porte déjà.
    `.table-scroll > table` a son `min-width: 33rem`, avec la mise en garde qui explique pourquoi
    `overflow-x` seul donnait un mot par ligne · et `.compare th.spot` / `.compare td.spot` teintent
    la colonne de l'offre recommandée. Les redéclarer aurait été deux règles de même poids
    départagées par leur ordre, en silence, ce que la passe 3 des contrôles cherche.
*/

/* ── 9.14 · Les questions fréquentes, en `<details>` natifs ────────────────────────────────────── */

/* Aucune dépendance : `<details>` ouvre et ferme tout seul, et reste lisible sans JavaScript. */
.mq-faq {
    display: grid;
    gap: 0.8rem;
    margin-top: 2.2rem;
}

.mq-faq details {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
}

/*
    ⚠️ 44 px DE HAUTEUR UTILE : `summary` est le seul élément cliquable de ce bloc. Et
    `list-style: none` PLUS `::-webkit-details-marker` : le triangle par défaut ne se retire pas
    autrement selon le moteur, et il se superposait au chevron.
*/
.mq-faq summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 44px;
    padding: 0.75rem 1.1rem;
    list-style: none;
    cursor: pointer;
    font-size: 1.01rem;
    font-weight: 600;
    color: var(--ink);
}

.mq-faq summary::-webkit-details-marker {
    display: none;
}

.mq-faq summary:hover {
    color: var(--green-deep);
}

.mq-faq summary svg {
    flex: none;
    color: var(--slate);
    transition: transform 0.15s;
}

.mq-faq details[open] summary svg {
    transform: rotate(180deg);
}

.mq-faq-r {
    margin: 0;
    padding: 0 1.1rem 1.1rem;
    max-width: 74ch;
    font-size: 0.99rem;
    line-height: 1.6;
    color: var(--slate);
}

/* ── 9.15 · La page Contact · formulaire à gauche, trois portes à droite ───────────────────────── */

.mq-contact {
    display: grid;
    gap: 1.6rem;
    align-items: start;
    margin-top: 2.4rem;
}

.mq-form-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    padding: clamp(1.2rem, 0.8rem + 1.6vw, 2rem);
}

.mq-form-panel h2 {
    margin: 0 0 0.5rem;
    font-size: 1.3rem;
}

.mq-form-panel > p {
    margin: 0 0 1.6rem;
    font-size: 0.97rem;
    color: var(--slate);
}

.mq-form-panel .btn {
    width: 100%;
    white-space: normal;
}

/*
    ⚠️ LES CHAMPS DU FORMULAIRE VONT JUSQU'AU BORD DU PANNEAU. Signalé par Christophe le 8 septembre
    2026 : « Votre structure » et « Votre message » s'arrêtaient 92 px avant le bord droit, alors que
    la paire « nom + adresse » juste au-dessus le touche. Mesuré à 1 440 px : le formulaire fait
    636 px, ces deux champs 544 px. La cause est `.field { max-width: 34rem }` dans `tickdoc.css`,
    un plafond de LONGUEUR DE LIGNE parfaitement justifié pour un formulaire en pleine page · ici le
    formulaire est déjà dans une colonne de 636 px, donc le plafond ne protège plus rien et ne fait
    qu'un désalignement visible.

    ⚠️ LE SÉLECTEUR PORTE LA PORTÉE, `.field` N'EST PAS REDÉCLARÉE. Elle vient de la charte, et la
    maquette ne redéclare aucune de ses classes : deux règles de même poids départagées par leur
    ordre sont ce que la passe 3 des contrôles cherche.
    ⚠️ Sans effet sous 1 100 px environ, la colonne devenant alors plus étroite que 544 px.
*/
.mq-form-panel .field {
    max-width: none;
}

/*
    ⚠️ `margin-top` EST POSÉ SUR UN SÉLECTEUR PLUS FORT, ET C'EST LA CORRECTION D'UN DÉFAUT MUET.
    Cette règle déclarait `margin: 1.1rem 0 0` et n'en obtenait RIEN : `.mq-form-panel > p` pèse
    (0,1,1) et l'écrase (0,1,0), d'où un texte au cadenas collé au bouton d'envoi, à 0 px. Mesuré, pas
    supposé — et la marge BASSE de 1,6 rem que la note portait venait elle aussi de la règle qui
    l'écrasait. Signalé par Christophe le 8 septembre 2026, qui demandait « un espace plus important ».

    ⚠️ DIXIÈME OCCURRENCE DE CE PIÈGE DANS LE PROJET, et la seconde de la journée après `.mq-cite`.
    La forme est toujours la même : une classe seule contre une classe suivie d'un élément, et la
    spécificité qui bat l'ordre du fichier. Une valeur déclarée n'est pas une valeur appliquée.

    ⚠️ 1,6 REM ET NON 1,1 : le bouton fait 100 % de large et 50 px de haut · la valeur d'origine
    n'avait jamais été vue à l'écran, donc rien ne la recommande. 1,6 rem est le rythme que
    `.mq-form-panel > p` emploie déjà dans ce panneau.
*/
.mq-form-panel > .mq-form-note {
    margin-top: 1.6rem;
}

.mq-form-note {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin: 1.1rem 0 0;
    font-size: 0.87rem;
    line-height: 1.45;
    color: var(--slate);
}

.mq-form-note svg {
    flex: none;
    margin-top: 0.1rem;
    color: var(--green-deep);
}

.mq-portes {
    display: grid;
    gap: 0.9rem;
}

.mq-porte {
    display: grid;
    grid-template-columns: 2.75rem 1fr;
    gap: 1rem;
    padding: 1.1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
}

.mq-porte .mq-ico {
    margin-bottom: 0;
}

.mq-porte h3 {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
}

.mq-porte p {
    margin: 0;
    font-size: 0.94rem;
    line-height: 1.5;
    color: var(--slate);
}

.mq-porte-tint {
    background: var(--mq-tint);
    border-color: transparent;
}

/* Les trois qualités de la relation, dans le panneau teinté du bas de la page Contact. */
.mq-relation {
    display: grid;
    gap: 1.4rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.mq-relation li {
    display: grid;
    grid-template-columns: 3rem 1fr;
    gap: 1rem;
    align-items: center;
}

.mq-relation b {
    display: block;
    margin-bottom: 0.2rem;
    color: var(--ink);
}

.mq-relation span {
    font-size: 0.93rem;
    line-height: 1.45;
    color: var(--slate);
}

/* ── 9.16 · Les deux pages légales ─────────────────────────────────────────────────────────────── */

/* `.prose` et `.breadcrumb` viennent de la charte · seule la largeur de colonne change.

   ⚠️ 86 CH ET NON 74, demandé par Christophe le 8 septembre 2026 pour les DEUX pages légales, qui
   partagent cette règle. La charte plafonne `.prose` à `var(--measure)`, soit 62 ch · la maquette
   était déjà à 74 ch, ce qui rendait 678 px de texte dans une colonne qui en offre 1 344. La moitié
   de la largeur restait vide sur des pages qu'on parcourt plutôt qu'on ne lit en continu.

   ⚠️ 86 CH DÉPASSE LA FOURCHETTE DE CONFORT USUELLE, 45 à 75 caractères par ligne, et c'est assumé
   ici : ce sont des documents de référence, consultés par section. L'augmentation est restée modérée
   pour cette raison — dire si elle doit aller plus loin.

   ⚠️ EN CH ET NON EN REM, contrairement au plafond de `.mq-sous`, et la différence est voulue : ici
   la contrainte est une LONGUEUR DE LIGNE, qui se mesure en caractères et doit donc suivre la police
   de la machine · là-bas c'était un budget de pixels pour tenir sur une ligne, qui devait au
   contraire en être indépendant. */
.mq-prose {
    max-width: var(--mq-lecture);
}

/*
    ⚠️ MÊME ARBITRAGE QUE `.wrap.mq-wrap`, ET POUR LA MÊME RAISON. Les pages légales portent les deux
    classes : `.prose` pour sa typographie — marges des `h2`, interlignage, listes — et `.mq-prose`
    pour sa largeur. Or les deux pèsent (0,1,0) et se disputent `max-width` : seul l'ORDRE du fichier
    les départage, et il suffirait de déplacer un bloc pour que la colonne de texte revienne à
    `--measure` sans qu'aucun contrôle ne le dise. (0,2,0) gagne dans les deux sens.
*/
.prose.mq-prose {
    max-width: var(--mq-lecture);
}

/* ⚠️ `.mq-avert` A ÉTÉ RETIRÉE AVEC SES DEUX SEULS USAGES, le 8 septembre 2026, sur décision de
   Christophe : la note de maquette de `securite.html`, puis celle des mentions légales. Comme
   `.mq-social`, une règle sans élément à viser n'est signalée par aucun contrôle — la première passe
   compare les classes employées aux règles déclarées, pas l'inverse.

   ⚠️ SON MOTIF RESTE VALABLE SI UN ENCADRÉ REDEVIENT NÉCESSAIRE : le site en ligne porte
   « à compléter avant mise en ligne » en texte courant sur quatre pages, où la mention passe
   inaperçue · la maquette, elle, n'en a aucune, ses champs légaux ayant été remplis. Chercher les
   DEUX formes au moment de la reprise, la française et « to complete before going live ».

   ⚠️ LA RÈGLE N'EST PAS DANS UN HISTORIQUE GIT, contrairement à ce que ce commentaire a affirmé :
   `moi/` n'est pas un dépôt. La voici, à recoller tel quel :

       .mq-avert   { margin: 1.4rem 0; padding: 0.9rem 1.1rem; border-radius: var(--r-md);
                     background: var(--amber-wash); border-left: 3px solid var(--amber);
                     font-size: 0.96rem; line-height: 1.5; color: var(--ink); }
       .mq-avert b { color: var(--amber); } */

/* ── 9.17 · Points de rupture ──────────────────────────────────────────────────────────────────── */

@media (min-width: 48rem) {
    .mq-cards-2 {
        grid-template-columns: repeat(2, 1fr);
    }

    .mq-cards-4 {
        grid-template-columns: repeat(2, 1fr);
    }

    .mq-vues {
        grid-template-columns: repeat(2, 1fr);
    }

    .mq-duo {
        grid-template-columns: repeat(2, 1fr);
        gap: 2.6rem;
    }

    .mq-exemples {
        grid-template-columns: repeat(3, 1fr);
    }

    .mq-field-duo {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 0 1rem;
    }
}

@media (min-width: 62rem) {
    .mq-hero-page {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
        gap: 2.8rem;
    }

    .mq-cards-3 {
        grid-template-columns: repeat(3, 1fr);
    }

    .mq-cards-4 {
        grid-template-columns: repeat(4, 1fr);
    }

    .mq-split {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
        gap: 3rem;
    }

    /*
        ⚠️ L'ordre visuel s'inverse SANS toucher à l'ordre du document : le texte reste avant
        l'image dans le balisage, donc dans l'ordre de lecture d'un lecteur d'écran et dans
        l'ordre de tabulation. C'est `order` et non deux blocs dupliqués.
    */
    .mq-split-inverse > :first-child {
        order: 2;
    }

    .mq-contact {
        grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
        gap: 2rem;
    }
}
