/*
 * KSI Logiciels — feuille de style du site commercial.
 *
 * Palette et typographie propres a cette ligne : aucune classe, aucune valeur, aucune police
 * reprise de commercial.css (marque historique, theme sombre bleu-cyan a coins 28px).
 *
 * Direction 20/09/2026, affinee le meme jour apres retour client (palette terracotta jugee
 * pas adaptee a un logiciel de gestion) : ton petrole/teal deja valide avant cette session
 * (coherent avec la page d'attente historique), avec la nouvelle structure conservee (hero
 * plein cadre sur fond sombre, display condense en majuscules, grille metiers avec
 * pictogrammes). Photos a venir : les cartes de la grille metiers sont deja prevues pour
 * recevoir une image plus tard.
 */

/* ── Polices HEBERGEES SUR LE SITE (10/10/2026) ──────────────────────────────────────────
 * Avant : @import vers Google Fonts, decouvert seulement apres le chargement de cette feuille
 * (deux allers-retours en serie, ~700 ms mesures), et un appel vers Google a CHAQUE visite —
 * ce que le RGPD n'aime pas (adresse IP transmise a un tiers sans necessite).
 * Maintenant : les deux polices VARIABLES (Oswald 400-700, Work Sans 100-900, sous-ensemble
 * latin, 21 + 50 Ko) vivent sous /assets/fonts/ (source : serveur/fonts/), prechargees par
 * l'en-tete du gabarit. `font-display: swap` : le texte s'affiche tout de suite en police de
 * repli, puis bascule.
 * ★ Les deux faces « Fallback » donnent a la police de repli (Arial / Roboto / Helvetica) les
 *   memes hauteurs de ligne et une largeur moyenne equivalente (metriques relevees dans les
 *   fichiers : Oswald asc 1,193 desc 0,289 largeur 0,377 em ; Work Sans asc 0,93 desc 0,243
 *   largeur 0,518 em ; Arial largeur 0,478 em) : la bascule ne deplace presque plus rien —
 *   c'etait la source du decalage de mise en page releve par Lighthouse (CLS 0,85 sur une
 *   page produit, 0,05 sur l'autre passage : tout dependait de l'arrivee de la police). */
@font-face {
    font-family: "Oswald";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/fonts/oswald.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Work Sans";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/assets/fonts/worksans.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Oswald Fallback";
    src: local("Arial Narrow"), local("Roboto Condensed"), local("Arial"), local("Roboto"), local("Helvetica Neue"), local("Liberation Sans");
    size-adjust: 78.7%;
    ascent-override: 151.6%;
    descent-override: 36.7%;
    line-gap-override: 0%;
}
@font-face {
    font-family: "Work Sans Fallback";
    src: local("Arial"), local("Roboto"), local("Helvetica Neue"), local("Liberation Sans");
    size-adjust: 108.2%;
    ascent-override: 85.9%;
    descent-override: 22.5%;
    line-gap-override: 0%;
}

:root {
    --paper: #f2f0e9;
    --panel: #ffffff;
    --ink: #16211f;
    --muted: #5b6b63;
    --line: #dbd6c6;
    --accent: #0c6b70;
    --accent-deep: #084c50;
    /* Accroche sur le bandeau sombre (hero) : --accent-deep y faisait 1,7:1 de contraste (audit du
       10/10/2026). Un teal clair sur l'encre, et l'inverse en theme sombre ou le bandeau est clair. */
    --hero-eyebrow: #86d6d6;
    --accent-ink: #ffffff;
    --accent-soft: rgba(12, 107, 112, 0.1);
    --accent-2: #5b6b63;
    --accent-2-soft: rgba(91, 107, 99, 0.12);
    --radius-s: 4px;
    --radius-m: 8px;
    --shadow: 0 12px 32px rgba(22, 33, 31, 0.08);
    --font-display: "Oswald", "Oswald Fallback", "Arial Narrow", sans-serif;
    --font-body: "Work Sans", "Work Sans Fallback", "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
    :root {
        --paper: #191510;
        --panel: #221d16;
        --ink: #f1ede2;
        --muted: #b3a999;
        --line: #3a3226;
        --accent: #5fc4c4;
        --accent-deep: #86d6d6;
        --hero-eyebrow: #084c50;
        --accent-ink: #10201f;
        --accent-soft: rgba(95, 196, 196, 0.14);
        --accent-2: #b3a999;
        --accent-2-soft: rgba(179, 169, 153, 0.14);
        --shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
    }
}

* {
    box-sizing: border-box;
}

/* Sans ce rappel, l'attribut [hidden] perd face a n'importe quelle regle qui pose son propre
 * display (ex. .commercial-field { display: flex }) : meme specificite, notre feuille passe
 * apres celle du navigateur dans la cascade. Constate le 21/09/2026 sur le formulaire de
 * commande (bascule Societe/Particulier). Meme regle que public/assets/commercial.css. */
[hidden] {
    display: none !important;
}

html {
    text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 17px;
    line-height: 1.6;
}

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

a {
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    a {
        color: var(--accent);
    }
}

h1, h2, h3 {
    font-family: var(--font-display);
    line-height: 1.1;
    text-wrap: balance;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    margin: 0 0 0.5em;
}

h1 {
    font-size: clamp(2.2rem, 4.4vw, 3.6rem);
    font-weight: 700;
}

h2 {
    font-size: clamp(1.5rem, 2.6vw, 2.1rem);
    font-weight: 600;
}

h3 {
    font-size: 1.05rem;
    font-weight: 600;
}

p {
    max-width: 62ch;
}

.eyebrow {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .eyebrow {
        color: var(--accent);
    }
}

.wrap {
    max-width: 1080px;
    margin: 0 auto;
    padding: 0 24px;
}

/* ── En-tete ─────────────────────────────────────────────────────────── */

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 2px solid var(--ink);
    background: var(--paper);
}

/* ⚠️ En-tete en PLEINE LARGEUR (22/09/2026, demande editeur) : contrairement au corps des
 *    pages, il n'est plus contraint a la gouttiere de 1080px — il suit la largeur de l'ecran,
 *    avec une marge laterale qui grandit avec le viewport (clamp). Le CONTENU des pages, lui,
 *    garde son .wrap a 1080px : seules les regles ci-dessous surchargent .wrap dans l'en-tete. */
.site-header .wrap {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 24px;
    max-width: none;
    padding-top: 14px;
    padding-bottom: 14px;
    padding-left: clamp(16px, 3vw, 56px);
    padding-right: clamp(16px, 3vw, 56px);
}

.header-left {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: var(--ink);
}

.brand img {
    height: 64px;
    width: auto;
}

.header-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 16px;
}

/* ── Compte / panier ──────────────────────────────────────────────────── */

.icon-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    color: var(--ink);
    text-decoration: none;
}

.icon-link:hover {
    background: var(--panel);
}

.icon-link svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.icon-badge {
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
}

/* ── Selecteur de langue ─────────────────────────────────────────────── */

.language-switcher {
    display: flex;
    gap: 6px;
}

.language-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    border: 2px solid transparent;
    text-decoration: none;
    font-size: 1.05rem;
    line-height: 1;
    background: var(--panel);
}

.language-pill:hover {
    border-color: var(--line);
}

.language-pill.is-active {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.header-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--accent-deep);
    background: var(--accent-soft);
    border-radius: 999px;
    padding: 6px 14px;
    white-space: nowrap;
}

@media (prefers-color-scheme: dark) {
    .header-badge {
        color: var(--accent);
    }
}

.site-nav ul {
    list-style: none;
    display: flex;
    gap: 28px;
    margin: 0;
    padding: 0;
}

.site-nav a {
    color: var(--ink);
    text-decoration: none;
    white-space: nowrap;
    font-family: var(--font-display);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.92rem;
    padding-bottom: 4px;
    border-bottom: 2px solid transparent;
}

.site-nav a:hover,
.site-nav a.is-active {
    border-bottom-color: var(--accent);
}

/* ── Pictogrammes ─────────────────────────────────────────────────────────
   ⚠️ `currentColor` : le picto prend la couleur du texte, donc il suit le thème clair ou
   sombre et l'état actif sans une seule règle de plus.
   ⚠️ `vertical-align` plutôt que flex sur le lien : le soulignement de la navigation active
   doit courir sous le picto ET sous le mot, pas sous le mot seul. */
.ksi-picto {
    display: inline-block;
    vertical-align: -0.16em;
    margin-right: 7px;
    flex: none;
}

.eyebrow-picto {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.eyebrow-picto .ksi-picto {
    margin-right: 6px;
}

/* ── Navigation à deux niveaux ────────────────────────────────────────────
   Une rubrique regroupe les produits (Nos logiciels, Démonstrations, Tarifs, Notices).
   ⚠️ OUVERTURE AU SURVOL *ET* AU CLAVIER (:focus-within) : un menu qui ne s'ouvre qu'à la
   souris est inaccessible à qui navigue à la tabulation — et sur mobile, un premier appui
   déclenche le survol, le second suit le lien.
   ⚠️ Le sous-menu reste dans le flux au-dessus de tout : z-index explicite, sinon le héros
   de la page passe devant. */

.site-nav .nav-rubrique {
    position: relative;
}

.site-nav .nav-chevron {
    display: inline-block;
    margin-left: 5px;
    font-size: 0.72em;
    line-height: 1;
    opacity: .65;
}

.site-nav .nav-sous {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 60;
    min-width: 210px;
    margin-top: 10px;
    padding: 8px;
    flex-direction: column;
    gap: 2px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(16, 24, 40, .13);
}

/* La zone tampon évite que le menu se referme dans l'espace entre le libellé et la liste. */
.site-nav .nav-rubrique::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    height: 14px;
}

.site-nav .nav-rubrique:hover .nav-sous,
.site-nav .nav-rubrique:focus-within .nav-sous {
    display: flex;
}

.site-nav .nav-sous a {
    display: block;
    padding: 7px 10px;
    border-bottom: none;
    border-radius: 7px;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 500;
    font-size: 0.93rem;
    white-space: nowrap;
}

.site-nav .nav-sous a:hover,
.site-nav .nav-sous a.is-active {
    background: var(--accent-soft, rgba(0, 0, 0, .06));
    border-bottom: none;
}

/* Pied de page : les sous-entrées sont dépliées, simplement décalées. */
/* ── Hero ─────────────────────────────────────────────────────────────── */

.hero {
    padding-top: 76px;
    padding-bottom: 76px;
    background: var(--ink);
    color: var(--paper);
}

.hero .eyebrow {
    display: block;
    margin-bottom: 18px;
    color: var(--hero-eyebrow);
}

@media (prefers-color-scheme: dark) {
    .hero .eyebrow {
        color: var(--accent);
    }
}

.hero h1 {
    color: var(--paper);
}

.hero p.lead {
    font-size: 1.15rem;
    color: var(--line);
    max-width: 60ch;
}

.hero-actions {
    display: flex;
    gap: 14px;
    margin-top: 28px;
    flex-wrap: wrap;
}

.button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 13px 24px;
    border-radius: var(--radius-s);
    font-family: var(--font-display);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: none;
    font-size: 0.92rem;
}

/* ★ Variante compacte (26/09/2026) : un bouton de section fait 13 px de haut de rembourrage et
   des majuscules espacées — juste pour un appel à l'action pleine largeur. Dans une cellule de
   tableau ou au fil d'un paragraphe, c'est trop. Même identité visuelle, moins d'encombrement. */
/* ★ La ligne du forfait d'ouverture se distingue des fonctions incluses : ce n'est pas une
   case à cocher, c'est un montant qui s'ajoute. Un filet et un fond discret suffisent —
   la surligner davantage la ferait passer pour une promotion. */
.pricing-row-setup td,
.pricing-row-setup th {
    border-bottom: 2px solid var(--line);
    font-weight: 600;
}

.button-compact {
    padding: 8px 14px;
    font-size: 0.78rem;
    letter-spacing: 0.03em;
}

.button-primary {
    background: var(--accent);
    color: var(--accent-ink);
}

.button-primary:hover {
    background: var(--accent-deep);
}

/* 🚨 UN BOUTON SECONDAIRE SUR FOND SOMBRE DOIT PASSER EN CLAIR (26/09/2026).
   `.button-secondary` est transparent avec un texte `--ink` : parfait sur le papier du site,
   INVISIBLE sur un panneau sombre — mesuré à **1:1** de contraste, c'est-à-dire du noir sur du
   noir. Le cas existait déjà pour le hero ; il s'est reproduit dès qu'un lien a été converti en
   bouton dans `.status-panel`.
   ⛔ LA LISTE DES FONDS SOMBRES EST ICI, À UN SEUL ENDROIT : tout nouveau conteneur sombre doit
      s'y ajouter, sinon il refabriquera le même défaut. Un contrôle de contraste automatisé
      (`tests/contraste_boutons.php`) mesure les pages servies pour que l'oubli se voie. */
.hero .button-secondary,
.status-panel .button-secondary,
.bandeau-preuve .button-secondary,
.bandeau-final .button-secondary {
    background: transparent;
    color: var(--paper);
    border: 1px solid var(--line);
}

.hero .button-secondary:hover,
.status-panel .button-secondary:hover,
.bandeau-preuve .button-secondary:hover,
.bandeau-final .button-secondary:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.button-secondary {
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--line);
}

.button-secondary:hover {
    border-color: var(--accent);
}

/* ── Sections generiques ─────────────────────────────────────────────── */

.section {
    padding-top: 60px;
    padding-bottom: 60px;
    border-top: 1px solid var(--line);
}

.section-head {
    max-width: 60ch;
    margin-bottom: 36px;
}

.section-head p {
    color: var(--muted);
}

.grid {
    display: grid;
    gap: 20px;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    padding: 26px;
}

.card h3 {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    margin-bottom: 8px;
}

.card p {
    color: var(--muted);
    margin: 0;
    font-size: 0.96rem;
}

/* ── Grille metiers ───────────────────────────────────────────────────── */

.jobs-grid {
    display: grid;
    gap: 20px;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.job-card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    padding: 26px 24px;
    position: relative;
}

.job-card--available {
    border-color: var(--accent);
    border-width: 2px;
}

.job-icon {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--accent-2-soft);
    color: var(--accent-2);
    margin-bottom: 18px;
}

.job-card--available .job-icon {
    background: var(--accent-soft);
    color: var(--accent);
}

.job-icon svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.job-card h3 {
    margin-bottom: 6px;
}

.job-card p {
    color: var(--muted);
    font-size: 0.94rem;
    margin: 0 0 16px;
}

.status-badge {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--accent-2-soft);
    color: var(--accent-2);
}

.status-badge--available {
    background: var(--accent-soft);
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .status-badge--available {
        color: var(--accent);
    }
}

/* 🚨 DE VRAIS BOUTONS DANS LES VIGNETTES (26/09/2026, demande de l'éditeur).
   Ces trois actions étaient des liens soulignés de 0,84 rem : le visiteur devait deviner
   qu'« ajouter au panier », « la démonstration » et « le logiciel » étaient des actions.
   ⚠️ `align-items: stretch` et `flex: 1 1 auto` : sans cela le bouton d'achat, plus haut
      parce qu'il porte son prix sur deux lignes, laisse les deux autres flotter en haut. */
.job-card-links {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 10px;
    margin-top: 18px;
}

.job-card-links .button,
.job-card-links .job-card-achat {
    flex: 1 1 auto;
    /* ⛔ `min-width: 0` sur chaque niveau : sans lui, un libellé long (allemand, italien)
       refuse de rétrécir et fait déborder la vignette. Piège déjà payé sur ce site. */
    min-width: 0;
}

.job-card-achat {
    display: flex;
    margin: 0;
}

.job-card-achat .button {
    width: 100%;
    /* ★ Le libellé au-dessus, le prix en dessous : un bouton reste lisible même quand il
       porte deux informations, à condition de ne pas les mettre sur la même ligne. */
    flex-direction: column;
    gap: 2px;
    text-align: center;
    justify-content: center;
}

.job-card-links .button {
    /* ⚠️ Plus compact que les boutons de section : trois actions dans une vignette de grille
       n'ont pas la place d'un appel à l'action pleine largeur. */
    padding: 11px 16px;
    font-size: 0.82rem;
    justify-content: center;
    text-align: center;
}

.button-prix {
    display: block;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-transform: none;
    opacity: 0.85;
}

@media (max-width: 560px) {
    /* ★ Sous 560 px, un bouton par ligne : trois cibles côte à côte deviennent trop étroites
       pour le doigt, et c'est là que la vignette est le plus souvent lue. */
    .job-card-links .button,
    .job-card-links .job-card-achat {
        flex: 1 1 100%;
    }
}

/* ── Panneau d'avancement honnete ────────────────────────────────────── */

.status-panel {
    background: var(--ink);
    color: var(--paper);
    border: none;
    border-radius: var(--radius-m);
    padding: 30px 32px;
    display: flex;
    gap: 20px;
    align-items: flex-start;
}

.status-panel .dot {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--accent);
    margin-top: 8px;
}

.status-panel p {
    margin: 0;
    color: var(--paper);
}

.status-panel p + p {
    margin-top: 8px;
    color: var(--line);
}

/* Messages flash (connexion, panier...) : bandeau sous l'en-tete, variante erreur. */
.flash-wrap {
    margin-top: 20px;
}

.flash-wrap .status-panel {
    padding: 16px 22px;
}

.flash-wrap .status-panel .dot {
    margin-top: 6px;
}

.status-panel--erreur {
    background: #7a2e1d;
}

.status-panel--erreur .dot {
    background: #f6c9b8;
}

/* ── Page contact : hero 2 colonnes + chips + etapes ─────────────────────── */
.hero-contact {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: 40px;
    align-items: center;
}

.contact-chips {
    display: grid;
    gap: 12px;
}

.contact-chip {
    display: block;
    padding: 14px 18px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: var(--radius-m);
    background: rgba(255, 255, 255, 0.06);
    color: var(--paper);
    text-decoration: none;
}

.contact-chip:hover {
    background: rgba(255, 255, 255, 0.12);
}

.contact-chip strong {
    display: block;
    font-family: var(--font-display);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 2px;
    color: var(--paper);
    opacity: 0.75;
}

.contact-chip span {
    font-size: 1.02rem;
}

.etapes-suite {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: grid;
    gap: 14px;
    counter-reset: etape;
}

.etapes-suite li {
    position: relative;
    padding-left: 44px;
    counter-increment: etape;
}

.etapes-suite li::before {
    content: counter(etape);
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent-deep);
    font-family: var(--font-display);
    font-weight: 600;
}

/* Variante pleine largeur : les etapes s'alignent en 3 colonnes sous le formulaire. */
.etapes-suite--large {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px 28px;
    margin-top: 16px;
}

@media (max-width: 900px) {
    .hero-contact {
        grid-template-columns: 1fr;
        gap: 24px;
    }

    .etapes-suite--large {
        grid-template-columns: 1fr;
    }

}

/* Galerie de captures produit : deux colonnes, image cadree, legende sous l'image. */
.captures-produit {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.capture {
    margin: 0;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    overflow: hidden;
}

.capture img {
    width: 100%;
    height: auto;
    display: block;
    border-bottom: 1px solid var(--line);
}

.capture figcaption {
    padding: 14px 18px;
    font-size: 0.9rem;
    color: var(--muted);
}

@media (max-width: 860px) {
    .captures-produit {
        grid-template-columns: 1fr;
    }
}

/* ══════════════════════════════════════════════════════════════════════════════════════
   ACCUEIL — BANDEAU DE PREUVE, SECTIONS ALTERNEES, FAQ DEPLIABLE (01/10/2026)

   🚨 CE QUE CES CLASSES VIENNENT COMBLER. L'accueil n'avait que des sections empilees sur
      une seule colonne et aucune capture : rien ne distinguait le haut de la page du bas, et
      le visiteur n'y voyait jamais le logiciel. Le rythme qui fonctionne — un benefice, des
      points, une capture en regard, et on recommence de l'autre cote — n'existait nulle part
      dans cette feuille.
   ★ TOUT PASSE PAR LES VARIABLES DE THEME, SANS EXCEPTION. Le site a un mode sombre : une
     seule couleur ecrite en dur rend sa section illisible la nuit. Les bandeaux reprennent le
     couple deja utilise par le hero et le panneau d'avancement (fond `--ink`, texte `--paper`,
     texte secondaire `--line`) : il s'inverse de lui-meme au changement de theme.
   ⚠️ SEUIL DE BASCULE : 900 px, celui que la feuille utilise DEJA (navigation repliable,
      `.hero-contact`, `.etapes-suite--large`). Les regles mobiles de ce bloc sont posees dans
      la requete de media existante, plus bas, et pas dans une nouvelle : deux seuils voisins
      produisent une plage ou la page n'est ni l'une ni l'autre.
   ══════════════════════════════════════════════════════════════════════════════════════ */

/* ── Bandeau de preuve ───────────────────────────────────────────────── */

/* ⚠️ IL PROLONGE LE HERO, IL NE LE SUIT PAS. Meme fond, aucun filet de separation entre les
      deux : les chiffres doivent appartenir au premier ecran, c'est la seule raison de leur
      presence. Pose apres une rupture de couleur, le bandeau redevient une section ordinaire
      et perd son role de preuve d'entree. */
.bandeau-preuve {
    background: var(--ink);
    color: var(--paper);
    padding-bottom: 46px;
}

/* ★ `grid-auto-flow: column` plutot qu'un nombre de colonnes fixe : le bandeau porte TROIS
     faits si l'un d'eux n'est pas traduit, et quatre sinon. Les colonnes se partagent la
     largeur quel qu'en soit le nombre, sans case vide ni colonne a rallonge.
   ⛔ `minmax(0, 1fr)` et non `1fr` : sans le minimum a zero, un libelle long (allemand,
      italien) refuse de rentrer et fait deborder la ligne. Piege deja paye sur ce site. */
.preuve-liste {
    list-style: none;
    margin: 0;
    padding: 26px 0 0;
    border-top: 1px solid var(--line);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0 26px;
}

.preuve-item {
    min-width: 0;
}

/* Un filet vertical entre deux faits, jamais avant le premier. */
.preuve-item + .preuve-item {
    border-left: 1px solid var(--line);
    padding-left: 26px;
}

.preuve-valeur {
    display: block;
    font-family: var(--font-display);
    font-size: clamp(2rem, 4vw, 2.9rem);
    font-weight: 700;
    line-height: 1;
    color: var(--paper);
}

/* ⚠️ PAS DE MAJUSCULES SUR LE LIBELLE. Le reste du site capitalise ses intertitres, mais ici
      le libelle est une phrase courte a lire en diagonale : en capitales, elle se dechiffre
      au lieu de se lire, et le probleme s'aggrave dans les quatre autres langues. */
.preuve-libelle {
    display: block;
    margin-top: 10px;
    font-size: 0.88rem;
    line-height: 1.35;
    color: var(--line);
}

.preuve-note {
    margin: 26px 0 0;
    font-size: 0.88rem;
    color: var(--line);
}

/* ── Section alternee : le texte d'un cote, la capture de l'autre ────── */

/* ★ C'EST LA PIECE MAITRESSE DE LA PAGE. Repetee quatre fois en s'inversant, elle donne au
     visiteur une raison de continuer a descendre : chaque ecran lui montre un logiciel
     different sous la meme forme, donc il sait deja comment le lire.
   ⛔ Le sens n'est PAS ecrit dans chaque section : le gabarit pose `.alterne--inverse` sur
      les rangs pairs. Un cote recopie a la main dans chaque bloc finit toujours par se
      repeter deux fois de suite le jour ou un logiciel s'ajoute au milieu. */
.alterne {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 44px;
    align-items: center;
}

.alterne-texte {
    min-width: 0;
}

.alterne-texte .eyebrow {
    display: block;
    margin-bottom: 14px;
}

.alterne-texte > p {
    color: var(--muted);
}

.alterne-visuel {
    min-width: 0;
}

.alterne--inverse .alterne-texte {
    order: 2;
}

.alterne--inverse .alterne-visuel {
    order: 1;
}

/* Le prix d'entree, lu dans la grille en base : la seule ligne chiffree de la section, donc
   elle se detache du texte courant sans pour autant devenir un titre. */
.alterne-tarif {
    margin: 20px 0 0;
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .alterne-tarif {
        color: var(--accent);
    }
}

/* ── Points de benefice ──────────────────────────────────────────────── */

/* ★ La marque de validation est DESSINEE avec deux bordures tournees : ni glyphe (qui change
     d'un systeme a l'autre et s'affiche parfois en couleur d'emoji), ni police d'icones, ni
     image. Elle prend la couleur d'accent, donc elle suit le theme toute seule. */
.points-benefice {
    list-style: none;
    margin: 20px 0 0;
    padding: 0;
    display: grid;
    gap: 13px;
}

.points-benefice li {
    position: relative;
    padding-left: 30px;
    font-size: 0.98rem;
}

.points-benefice li::before {
    content: "";
    position: absolute;
    left: 1px;
    top: 0.34em;
    width: 12px;
    height: 7px;
    border-left: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: rotate(-45deg);
}

/* ── FAQ depliable ───────────────────────────────────────────────────── */

/* ⛔ `<details>`/`<summary>` NATIFS, AUCUN SCRIPT. Les questions se deplient sans
      JavaScript, se parcourent au clavier sans rien ajouter, et leurs reponses restent dans
      le document — donc lisibles par un moteur de recherche. Une FAQ repliee par du script
      disparait le jour ou le script ne se charge pas, et elle disparait d'abord pour le
      lecteur qui en avait le plus besoin. */
.faq-liste {
    display: grid;
    gap: 12px;
}

.faq-item {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    padding: 0 22px;
}

/* ⚠️ PAS DE MAJUSCULES NON PLUS ICI, alors que `h3` en porte partout ailleurs : une question
      est une phrase entiere, avec un point d'interrogation. En capitales, elle cesse d'etre
      une question et devient une etiquette. */
.faq-item summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 0;
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.04rem;
    line-height: 1.3;
    /* Les deux lignes suivantes retirent le triangle du navigateur : on en dessine un. */
    list-style: none;
}

.faq-item summary::-webkit-details-marker {
    display: none;
}

/* Le chevron : meme technique que la marque de validation, deux bordures tournees. */
.faq-item summary::after {
    content: "";
    flex: 0 0 auto;
    width: 9px;
    height: 9px;
    border-right: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: rotate(45deg) translateY(-3px);
}

.faq-item[open] summary::after {
    transform: rotate(-135deg) translateY(-3px);
}

/* ⚠️ Un contour de focus VISIBLE : `summary` est l'element que l'on atteint a la tabulation,
      et c'est le seul moyen de savoir ou l'on en est sans souris. */
.faq-item summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

.faq-item[open] summary {
    border-bottom: 1px solid var(--line);
    margin-bottom: 18px;
}

.faq-item > p {
    margin: 0 0 22px;
    color: var(--muted);
    font-size: 0.96rem;
    max-width: 72ch;
}

/* ── Rappel final ────────────────────────────────────────────────────── */

/* ★ La page se ferme comme elle s'est ouverte : meme fond sombre que l'accroche. C'est le
     seul endroit ou l'on peut demander un contact, parce que c'est le seul ou le visiteur a
     deja tout vu.
   ⛔ Les boutons secondaires de ce bandeau sont declares plus haut, dans la liste UNIQUE des
      fonds sombres (`.hero`, `.status-panel`, `.bandeau-preuve`, `.bandeau-final`) : un
      bouton transparent a texte `--ink` y serait du noir sur du noir. */
.bandeau-final {
    background: var(--ink);
    color: var(--paper);
    padding-top: 58px;
    padding-bottom: 58px;
}

.bandeau-final h2 {
    color: var(--paper);
}

.bandeau-final p.lead {
    font-size: 1.1rem;
    color: var(--line);
    max-width: 60ch;
}

/* Page « À propos » : phrases d'identite, une par ligne, sans puce decorative. */
.liste-identite {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 14px;
}

.liste-identite li {
    padding-left: 18px;
    border-left: 3px solid var(--accent-soft);
    line-height: 1.7;
}

/* Bandeau de consentement (mesure d'audience). */
.cookie-banner {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: 16px;
    z-index: 60;
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
    max-width: 720px;
    margin: 0 auto;
    padding: 18px 22px;
    background: var(--ink);
    color: var(--paper);
    border-radius: var(--radius-m);
    box-shadow: 0 18px 38px rgba(0, 0, 0, 0.25);
}

.cookie-banner p {
    margin: 4px 0 0;
    color: var(--line);
    font-size: 0.92rem;
}

.cookie-banner a {
    color: var(--paper);
}

.cookie-banner .cookie-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

/* Le bandeau est sur fond sombre (--ink) : la variante secondaire, pensee pour fond clair,
   y devenait illisible (texte sombre sur sombre). */
.cookie-banner .button-secondary {
    color: var(--paper);
    border-color: var(--paper);
    background: transparent;
}

.cookie-banner .button-secondary:hover {
    color: var(--ink);
    background: var(--paper);
}

/* ── Contact ──────────────────────────────────────────────────────────── */

.contact-block {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.contact-block .card a {
    font-weight: 600;
    text-decoration: none;
}

/* ── Pied de page ─────────────────────────────────────────────────────── */

.site-footer {
    border-top: 2px solid var(--ink);
    padding: 40px 0 28px;
    color: var(--muted);
    font-size: 0.9rem;
}

.site-footer .wrap {
    display: block;
}

/* Pied de page 4 colonnes (22/09/2026) : marque + navigation + espace client + informations,
   puis une barre basse avec les mentions (copyright, adresse, SIRET, TVA). */
/*
 * ⚠️ LE NOMBRE DE COLONNES N'EST PLUS ECRIT EN DUR (23/09/2026). Le pied de page porte
 *    desormais UNE COLONNE PAR LOGICIEL, engendree depuis la gamme : figer « quatre colonnes »
 *    obligeait a revenir ici a chaque produit ajoute — et un oubli se voyait tout de suite,
 *    en production, sous la forme d'une colonne ecrasee.
 * ★ `auto-fit` compte les colonnes selon la place disponible ; la colonne de marque en occupe
 *   deux, ce qui lui laisse la largeur de son paragraphe sans elargir les autres.
 */
.site-footer-grille {
    display: grid;
    /* ⚠️ 140px, pas 160 : mesure faite au navigateur le 23/09/2026. A 160, la gouttiere de
       1080px ne laissait place qu'a CINQ pistes — la colonne de marque en prenant deux, la
       derniere rubrique passait a la ligne et laissait un trou a cote d'elle. A 140, il y en
       a six : marque, les deux logiciels, le site, les informations, sur une seule rangee. */
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 28px 32px;
    padding-bottom: 28px;
}

.site-footer-marque {
    grid-column: span 2;
}

.site-footer-marque strong {
    display: block;
    color: var(--ink);
    font-size: 1.05rem;
    margin-bottom: 6px;
}

.site-footer-marque p {
    margin: 0 0 10px;
    max-width: 32ch;
}

.site-footer-grille h3 {
    margin: 0 0 12px;
    font-family: var(--font-display);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink);
}

.site-footer-grille ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 8px;
}

.site-footer-bas {
    border-top: 1px solid var(--line);
    padding-top: 16px;
}

.site-footer-bas p {
    margin: 0;
    max-width: none;
    font-size: 0.82rem;
    text-align: center;
}

@media (max-width: 860px) {
    .site-footer-grille {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .site-footer-marque {
        grid-column: 1 / -1;
    }
}

@media (max-width: 480px) {
    .site-footer-grille {
        grid-template-columns: 1fr;
    }
}

.site-footer-aussi a {
    margin-left: 8px;
    color: var(--muted);
    text-decoration: underline;
}

.site-footer-aussi a:hover {
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .site-footer-aussi a:hover {
        color: var(--accent);
    }
}

.site-footer a {
    color: var(--muted);
    text-decoration: none;
}

.site-footer a:hover {
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .site-footer a:hover {
        color: var(--accent);
    }
}

/* ── Document legal (CGV / RGPD) ─────────────────────────────────────── */

.page-hero {
    padding: 56px 0 8px;
}

.page-hero .wrap,
.info-grid,
.legal-toc,
.legal-document,
.legal-translation-notice {
    max-width: 1080px;
    margin: 0 auto;
    padding-left: 24px;
    padding-right: 24px;
}

.badge-row span {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent-deep);
    margin-right: 14px;
}

@media (prefers-color-scheme: dark) {
    .badge-row span {
        color: var(--accent);
    }
}

.info-grid {
    display: grid;
    gap: 20px;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    padding-top: 24px;
    padding-bottom: 24px;
}

.info-card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    padding: 24px;
}

.compact-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}

.compact-table th {
    text-align: left;
    color: var(--muted);
    font-weight: 500;
    padding: 6px 12px 6px 0;
    white-space: nowrap;
}

.compact-table td {
    padding: 6px 0;
    overflow-wrap: anywhere;
}

/* Pastilles de statut (espace client) — meme famille visuelle que .status-badge. */
.status-pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    background: var(--accent-2-soft);
    color: var(--ink);
    white-space: nowrap;
}

.status-pill.status-success {
    background: var(--accent-soft);
    color: var(--accent-deep);
}

.status-pill.status-warning {
    background: var(--accent-2-soft);
    color: var(--muted);
}

.legal-toc, .legal-document {
    padding-top: 8px;
    padding-bottom: 8px;
}

.legal-toc ol {
    columns: 2;
    gap: 24px;
    padding-left: 20px;
}

.legal-section {
    padding: 20px 0;
    border-top: 1px solid var(--line);
}

.legal-section:first-child {
    border-top: none;
}

.muted {
    color: var(--muted);
}

/* ── Formulaire de commande ───────────────────────────────────────────── */

.commercial-form {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.form-section-title {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-size: 0.85rem;
    color: var(--accent-deep);
    border-bottom: 1px solid var(--line);
    padding-bottom: 8px;
    margin-top: 6px;
}

@media (prefers-color-scheme: dark) {
    .form-section-title {
        color: var(--accent);
    }
}

.commercial-form-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px;
}

/* ── Colonnes des pages panier/commande ──────────────────────────────────
 * Distinct de .grid (utilise ailleurs pour 3-6 cartes en auto-fit) : ici
 * TOUJOURS exactement 2 colonnes de forme differente (resume court a
 * gauche, formulaire dense a droite) — auto-fit les stabiliserait a 2
 * colonnes egales jusqu'a des largeurs trop etroites pour un formulaire a
 * 2 colonnes internes, d'ou la bascule anticipee en 960px ci-dessous
 * (constate en reel le 21/09/2026 : champs coupes/ecrases entre 640 et
 * ~950px de large, largeur non testee au premier passage). */
.checkout-columns {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: 28px;
}

/* Conteneur des 2 pages panier/commande : un peu plus large que .wrap (1080px)
 * pour que chaque colonne respire, sans toucher au reste du site (accueil, tarifs
 * restent a 1080px, largeur pensee pour la lecture, pas pour un formulaire dense). */
.wrap-wide {
    max-width: 1240px;
}

/* Formulaire code promo : flex qui s'enroule tout seul, container-width, pas
 * viewport-width — evite de rejouer le meme rattrapage de seuil que
 * .commercial-form-grid pour une simple paire champ+bouton. */
.promo-form {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.promo-form input {
    flex: 1 1 200px;
    font: inherit;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-s);
    background: var(--panel);
    color: var(--ink);
}

.promo-form input:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

@media (max-width: 1200px) {
    .checkout-columns {
        grid-template-columns: 1fr;
    }

    .commercial-form-grid {
        grid-template-columns: 1fr;
    }
}

/*
 * 🚨 L'EN-TETE DEBORDAIT A NOUVEAU (23/09/2026, mesure au navigateur).
 *    Le meme defaut qu'au 21/09 — la page entiere partait en defilement lateral — etait
 *    revenu, pour une raison simple : la navigation a grossi le jour meme (sept rubriques,
 *    des pictogrammes, des sous-menus). Le seuil de 1200 px etait juste quand elle comptait
 *    quatre liens ; il ne l'etait plus.
 *
 *    Mesure reelle AVANT correction, sur la page servie :
 *       1200 px  contenu 1200  ✅        1440 px  contenu 1454  ⛔ deborde de 14
 *       1280 px  contenu 1450  ⛔ 170     1536 px  contenu 1536  ✅
 *       1366 px  contenu 1452  ⛔ 86
 *    La plage cassee, 1201 a ~1455 px, est exactement celle des portables 13 et 14 pouces.
 *
 * ★ LE SEUIL EST DONC MESURE, PAS DEVINE : 1480 px couvre le pire cas releve (1454) avec
 *   une marge. ⚠️ Et il est SEPARE du bloc 1200 ci-dessus a dessein : y remonter le tunnel
 *   de commande le ferait passer en une colonne bien trop tot.
 * ⚠️ A REVERIFIER A CHAQUE AJOUT DANS LA NAVIGATION : une rubrique de plus, et ce seuil
 *    redevient faux. La mesure ci-dessus se rejoue en une minute au navigateur.
 */
@media (max-width: 1480px) {

    /* ⚠️ Constate en reel le 21/09/2026 : logo + nav (4 liens) + icones compte/panier
     * (ajoutees le meme jour) + 5 drapeaux ne tiennent plus sur une ligne des que la
     * grille 3 colonnes (.site-header .wrap) n'a plus assez de place — ELLE NE
     * S'ADAPTAIT PAS, elle debordait, entrainant TOUTE la page en scroll horizontal
     * (texte tronque a gauche, signale par capture d'ecran). Passe en flex qui
     * enroule : logo+actions restent sur une ligne, la nav bascule dessous.
     */
    .site-header .wrap {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        align-items: center;
    }

    .site-nav {
        order: 3;
        width: 100%;
    }

    .site-nav ul {
        justify-content: center;
        flex-wrap: wrap;
        gap: 14px 20px;
    }
}

/*
 * ⚠️ LE DEPLIAGE DES SOUS-MENUS RESTE A 1200 px, PAS A 1480 (23/09/2026).
 *    Remonter TOUT le bloc a 1480 corrigeait bien le debordement, mais depliait aussi les
 *    sous-menus sur les portables 13 et 14 pouces : « Logiciel Garage · Logiciel camping »
 *    repete sous chacune des quatre rubriques, en permanence. Verifie par capture avant de
 *    le scinder — c'etait laid, et inutile : a la souris, le survol fonctionne tres bien.
 * ★ Deux problemes distincts, deux seuils distincts : l'en-tete manque de PLACE des
 *   1480 px ; le survol ne manque de rien tant qu'il y a une souris.
 */
@media (max-width: 1200px) {
    /* ⚠️ SUR ÉCRAN ÉTROIT, ON DÉPLIE PLUTÔT QUE DE DÉROULER. Un menu au survol n'existe pas
       au doigt : le premier appui l'ouvre, le second suit le lien — et la moitié des
       visiteurs pensent que le lien ne marche pas. Les rubriques s'affichent donc en pile,
       leurs produits en dessous, toujours visibles. */
    .site-nav .nav-chevron {
        display: none;
    }

    .site-nav .nav-rubrique {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
    }

    .site-nav .nav-sous {
        display: flex;
        position: static;
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        min-width: 0;
        margin-top: 0;
        padding: 0;
        gap: 4px 14px;
        background: none;
        border: none;
        box-shadow: none;
    }

    .site-nav .nav-sous a {
        padding: 2px 6px;
        font-size: 0.86rem;
        opacity: .85;
    }
}

.commercial-field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.commercial-field-span {
    grid-column: 1 / -1;
}

.commercial-field label {
    font-weight: 600;
    font-size: 0.9rem;
}

.champ-requis {
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .champ-requis {
        color: var(--accent);
    }
}

.commercial-field input,
.commercial-field select,
.commercial-field textarea {
    font: inherit;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-s);
    background: var(--panel);
    color: var(--ink);
}

.commercial-field input:focus,
.commercial-field select:focus,
.commercial-field textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.commercial-field textarea {
    min-height: 72px;
    resize: vertical;
}

.legende-champs-requis {
    font-size: 0.85rem;
    color: var(--muted);
}

.consent-card {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    padding: 16px;
    background: var(--panel);
}

.consent-card input {
    margin-top: 3px;
}

/* ── Tarifs ───────────────────────────────────────────────────────────── */

.pricing-table-wrap {
    overflow-x: auto;
}

.pricing-table {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-m);
    overflow: hidden;
}

.pricing-table th,
.pricing-table td {
    padding: 14px 16px;
    text-align: center;
    border-bottom: 1px solid var(--line);
    font-size: 0.94rem;
}

.pricing-table thead th {
    vertical-align: top;
    padding-top: 20px;
    padding-bottom: 20px;
    background: var(--paper);
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.pricing-table thead th.is-vedette {
    background: var(--accent-soft);
    color: var(--accent-deep);
}

@media (prefers-color-scheme: dark) {
    .pricing-table thead th.is-vedette {
        color: var(--accent);
    }
}

.pricing-table td.is-vedette {
    background: var(--accent-soft);
}

.pricing-star {
    color: var(--accent);
}

.pricing-price {
    display: block;
    margin-top: 8px;
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    text-transform: none;
    letter-spacing: normal;
    color: var(--ink);
}

.pricing-period {
    display: block;
    font-size: 0.62rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
}

.pricing-table-label {
    text-align: left;
    font-weight: 500;
    color: var(--ink);
    white-space: nowrap;
}

.pricing-table tbody tr:last-child th,
.pricing-table tbody tr:last-child td {
    border-bottom: none;
}

.pricing-yes {
    color: var(--accent-deep);
    font-weight: 700;
}

@media (prefers-color-scheme: dark) {
    .pricing-yes {
        color: var(--accent);
    }
}

.pricing-no {
    color: var(--line);
}

.pricing-table-simple td {
    text-align: right;
    font-weight: 600;
}

.pricing-note {
    margin-top: 12px;
    font-size: 0.86rem;
    color: var(--muted);
}

code {
    background: var(--accent-soft);
    color: var(--accent-deep);
    padding: 3px 8px;
    border-radius: var(--radius-s);
    font-size: 0.95em;
}

@media (prefers-color-scheme: dark) {
    code {
        color: var(--accent);
    }
}

@media (max-width: 640px) {
    .header-badge {
        display: none;
    }

    .brand img {
        height: 48px;
    }

    .site-nav ul {
        gap: 16px;
        flex-wrap: wrap;
    }

    .language-pill {
        width: 30px;
        height: 30px;
        font-size: 0.95rem;
    }

    .hero {
        padding-top: 48px;
        padding-bottom: 48px;
    }

    .legal-toc ol {
        columns: 1;
    }
}

/* ── Galerie des captures (23/09/2026) ────────────────────────────────────
 * ★ Le defilement est NATIF (`scroll-snap`) : le navigateur s'en charge mieux qu'un script,
 *   et le geste fonctionne au doigt sans qu'on ecrive une ligne. Les fleches ne font que
 *   commander ce meme defilement.
 * ⛔ Rien ne bouge tout seul : pas de rotation automatique. Une image qui change pendant
 *   qu'on la regarde est une nuisance, pas une animation.
 */
.galerie {
    position: relative;
}

.galerie-piste {
    display: grid;
    grid-auto-flow: column;
    /* ⚠️ PAS `minmax(0, 68%)` — mesure au navigateur le 23/09/2026 : c'est une FOURCHETTE,
       dont le moteur prend le minimum des lors que tout tient dans la largeur. Les quatre
       captures se rangeaient donc a 283 px chacune, exactement la grille qu'on voulait
       remplacer, avec une piste qui ne defilait meme pas. Une taille IMPOSEE, bornee aux
       deux bouts, est le seul moyen de forcer le debordement voulu. */
    grid-auto-columns: clamp(260px, 68%, 820px);
    gap: 20px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding: 0;
    padding-bottom: 6px;
    /* La barre de defilement reste discrete mais PRESENTE : elle dit qu'il y a une suite. */
    scrollbar-width: thin;
}

.galerie-piste:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
}

.galerie-vue {
    margin: 0;
    scroll-snap-align: center;
}

.galerie-lien {
    position: relative;
    display: block;
    border: 1px solid var(--line);
    background: var(--panel);
    overflow: hidden;
    text-decoration: none;
}

.galerie-lien img {
    display: block;
    width: 100%;
    height: auto;
}

.galerie-lien:hover,
.galerie-lien:focus-visible {
    border-color: var(--accent);
    outline: none;
}

/* La loupe dit que l'image s'agrandit — sans elle, personne ne pense a cliquer. */
.galerie-loupe {
    position: absolute;
    right: 10px;
    bottom: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    background: var(--ink);
    color: var(--paper);
    opacity: .78;
    transition: opacity .15s ease;
}

.galerie-lien:hover .galerie-loupe,
.galerie-lien:focus-visible .galerie-loupe {
    opacity: 1;
}

.galerie-vue figcaption {
    margin-top: 10px;
    font-size: .92rem;
    color: var(--muted);
}

.galerie-fleche {
    position: absolute;
    top: 38%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--panel);
    color: var(--ink);
    cursor: pointer;
}

.galerie-precedent { left: -12px; }
.galerie-suivant { right: -12px; }

.galerie-fleche:hover:not(:disabled) {
    border-color: var(--accent);
    color: var(--accent);
}

.galerie-fleche:disabled {
    opacity: .3;
    cursor: default;
}

.galerie-pastilles {
    display: flex;
    justify-content: center;
    gap: 0;
    margin-top: 16px;
}

/* ★ Cible de 24 px, point de 9 px (10/10/2026) : un bouton de 9 px est injouable au doigt
   (audit : « target-size »). Le point est dessine dans un pseudo-element, la zone cliquable
   reste invisible. */
.galerie-pastille {
    position: relative;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
}
.galerie-pastille::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    border-radius: 999px;
    background: var(--line);
}

.galerie-pastille[aria-current="true"]::before {
    background: var(--accent);
    transform: scale(1.25);
}

/* ── Agrandissement ─────────────────────────────────────────────────────── */

.galerie-agrandissement {
    width: min(96vw, 1400px);
    max-width: 96vw;
    max-height: 94vh;
    padding: 0;
    border: 0;
    background: transparent;
    overflow: visible;
}

.galerie-agrandissement::backdrop {
    /* ⚠️ Un fond vraiment opaque : sur une capture d'ecran claire, un voile trop leger laisse
       la page transparaitre et on ne sait plus ce qu'on regarde. */
    background: rgba(12, 10, 8, .88);
}

.galerie-agrandissement figure {
    margin: 0;
}

.galerie-agrandissement img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 80vh;
    object-fit: contain;
    background: var(--panel);
    border: 1px solid rgba(255, 255, 255, .12);
}

.galerie-agrandissement figcaption {
    margin-top: 12px;
    text-align: center;
    color: #f2ece2;
    font-size: .95rem;
}

.galerie-fermer {
    position: absolute;
    top: -46px;
    right: 0;
    display: inline-flex;
    padding: 6px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: #f2ece2;
    cursor: pointer;
}

.galerie-agrandissement-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
    margin-top: 14px;
    color: #f2ece2;
    font-variant-numeric: tabular-nums;
}

.galerie-agrandissement-nav button {
    display: inline-flex;
    padding: 8px;
    border: 1px solid rgba(255, 255, 255, .28);
    border-radius: 999px;
    background: transparent;
    color: inherit;
    cursor: pointer;
}

.galerie-agrandissement-nav button:disabled {
    opacity: .3;
    cursor: default;
}

@media (max-width: 720px) {
    .galerie-piste { grid-auto-columns: clamp(240px, 88%, 640px); }
    /* Les fleches empietent sur l'image sur un ecran etroit : le glissement suffit. */
    .galerie-fleche { display: none; }
    .galerie-fermer { top: -40px; }
}

@media (prefers-reduced-motion: reduce) {
    .galerie-piste { scroll-behavior: auto; }
    .galerie-pastille[aria-current="true"]::before { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════
   NAVIGATION SUR PETIT ÉCRAN (24/09/2026)

   🚨 LE DÉFAUT CORRIGÉ ICI. La navigation à deux niveaux, posée le 23/09, n'avait aucune
      version mobile : à 390 px, les 41 liens du menu et de ses sous-menus se dépliaient
      verticalement et occupaient TOUT le premier écran. Le visiteur arrivait sur un sommaire,
      pas sur une offre — ni titre, ni argument, ni bouton visible sans faire défiler.

   ★ On ne touche à rien au-delà de 900 px : la barre de bureau reste exactement ce qu'elle
     était. Tout ce qui suit vit dans une requête de média, et le bouton n'existe que là.
   ══════════════════════════════════════════════════════════════════════════════════════ */

.nav-bascule {
    display: none;                 /* n'apparaît que sous 900 px, voir plus bas */
    align-items: center;
    justify-content: center;
    width: 44px;                   /* ⚠️ 44 px : la cible tactile minimale recommandée. */
    height: 44px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--radius-s, 10px);
    cursor: pointer;
    color: var(--ink);
}

.nav-bascule:hover { border-color: var(--accent); color: var(--accent); }
.nav-bascule:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.nav-bascule-barres { display: block; width: 20px; }

.nav-bascule-barres span {
    display: block;
    height: 2px;
    background: currentColor;      /* suit la couleur du texte, donc le thème */
    border-radius: 2px;
}

.nav-bascule-barres span + span { margin-top: 4px; }

@media (max-width: 900px) {

    /* ⛔⛔ CE BLOC A ETE DEPLACE ICI LE 01/10/2026, ET LE MOTIF COMPTE.
       Il etait dans la PREMIERE requete de media du fichier, AVANT les regles de bureau de
       `.alterne` (qui vivent plus bas, pres du reste de la section). A specificite egale,
       c'est la DERNIERE regle qui gagne : les regles de bureau ecrasaient donc les regles
       mobiles, et les sections alternees restaient sur DEUX COLONNES a 390 px — le texte se
       repliait a trois mots par ligne, l'image etait ecrasee. Mesure a l'ecran, pas deduite.
       ⚠️ Le commentaire d'origine annoncait avoir evite le piege de specificite : il l'avait
          evite SUR LES SELECTEURS (`.alterne--inverse .alterne-visuel` compte deux classes,
          les deux sens sont donc repris a specificite egale) mais pas SUR L'ORDRE. Les deux
          se verifient separement.
       ★ Place dans la requete de FIN DE FICHIER, le mobile passe toujours apres le bureau.
          Toute nouvelle regle mobile se range ici, pas en haut. */
    /* ── Accueil : bandeau de preuve et sections alternees ───────────────────────────
       ⛔⛔ LE TEXTE PASSE AVANT L'IMAGE, DES DEUX COTES. Sur un telephone, une capture
            large posee en tete de section repousse le titre et les points hors de l'ecran :
            le visiteur voit une image qu'il ne sait pas encore lire, et doit faire defiler
            pour apprendre de quoi elle parle. Une section sur deux faisait exactement ca.
       ⚠️ SPECIFICITE — LE PIEGE DE CE FICHIER. `.alterne--inverse .alterne-visuel` compte
          DEUX classes : une regle a une seule classe ecrite ici perdrait la bataille sans
          rien signaler, et la section paire garderait son image en premier. C'est le meme
          defaut qui a ete constate, deploye et servi sans effet sur la navigation mobile le
          24/09/2026. Les deux selecteurs sont donc repris nommement, a specificite egale et
          plus loin dans la cascade. */
    .alterne {
        grid-template-columns: minmax(0, 1fr);
        gap: 26px;
    }

    .alterne-texte,
    .alterne--inverse .alterne-texte {
        order: 1;
    }

    .alterne-visuel,
    .alterne--inverse .alterne-visuel {
        order: 2;
    }

    /* Deux faits par ligne : quatre colonnes sur un telephone donnent un chiffre par
       colonne de 80 px et un libelle coupe a chaque mot.
       ⚠️ Les filets verticaux disparaissent : sur deux lignes, le filet du troisieme fait
          se retrouve contre le bord gauche et ne separe plus rien. */
    .preuve-liste {
        grid-auto-flow: row;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 24px 22px;
    }

    .preuve-item + .preuve-item {
        border-left: 0;
        padding-left: 0;
    }
    /* L'en-tête passe en deux colonnes : la marque, et le bouton. Le menu sort du flux
       et se place dessous quand il est ouvert. */
    .site-header .wrap {
        grid-template-columns: 1fr auto;
        gap: 12px;
    }

    .nav-bascule { display: inline-flex; }

    /*
     * ⛔ LE MENU N'EST MASQUÉ QUE SI LE SCRIPT A PU S'EXÉCUTER (`.js-menu` sur <html>).
     *    Sans JavaScript, le bouton ne servirait à rien : masquer le menu le rendrait alors
     *    définitivement inatteignable. On préfère l'ancien comportement — long mais
     *    fonctionnel — à une navigation invisible.
     */
    .js-menu .site-nav {
        display: none;
        grid-column: 1 / -1;
        order: 3;
    }

    .js-menu .site-nav.est-ouvert { display: block; }

    /* Les rubriques s'empilent, et les sous-menus restent DÉPLIÉS une fois le menu ouvert :
       sur un écran tactile, un survol n'existe pas — un sous-menu qui ne s'ouvre qu'au
       survol ne s'ouvrirait jamais.
       ⚠️ SPÉCIFICITÉ : les blocs 1480 px et 1200 px plus haut CENTRENT déjà la navigation
          (`justify-content: center`, `align-items: center`) avec deux classes. Des sélecteurs
          moins spécifiques ici perdraient la bataille sans rien signaler — c'est exactement ce
          qui s'est passé au premier essai : règle écrite, déployée, servie, et sans effet. */
    .site-nav ul {
        flex-direction: column;
        align-items: stretch;
        justify-content: flex-start;
        gap: 2px;
    }

    .site-nav .nav-rubrique {
        align-items: stretch;      /* annule le centrage du bloc 1200 px */
        gap: 0;
    }

    .site-nav a {
        display: flex;
        align-items: center;
        /* ⚠️ `justify-content` ET `text-align` explicites : sans eux, les rubriques héritent
           du centrage de la barre de bureau et s'affichent au milieu, tandis que les entrées
           sans sous-menu restent à gauche — une colonne visiblement bancale. */
        justify-content: flex-start;
        text-align: left;
        gap: 10px;
        padding: 12px 8px;         /* hauteur de cible confortable au doigt */
    }

    /* Les rubriques sont des blocs pleine largeur : sans cela, l'élément de liste se
       dimensionne sur son contenu et le centrage revient par la bande. */
    .site-nav > ul > li { width: 100%; }

    .site-nav .nav-sous {
        position: static;          /* ⚠️ sortir du positionnement absolu du bureau, sinon le
                                      sous-menu se superpose au reste au lieu de s'insérer */
        display: flex;
        flex-direction: column;    /* le bloc 1200 px les met en RANGÉE : on repasse en pile */
        justify-content: flex-start;
        opacity: 1;
        visibility: visible;
        transform: none;
        box-shadow: none;
        border: 0;
        background: transparent;
        padding: 0 0 6px 26px;     /* retrait : la hiérarchie se lit sans chevron */
        gap: 0;
        min-width: 0;
    }

    .site-nav .nav-chevron,
    .site-nav .nav-rubrique::after { display: none; }

    /* Le bloc 1200 px les réduit à 0.86rem et les rend translucides : sur un téléphone,
       une cible tactile ne se réduit pas — on revient à une taille et un contraste normaux. */
    .site-nav .nav-sous a {
        padding: 10px 8px;
        font-size: 1rem;
        opacity: 1;
    }
}


/* ─── Accueil : hero et bandeau de preuve en PLEINE LARGEUR ────────────────────────────
 * 🚨 POURQUOI DES MODIFICATEURS, ET PAS UNE CORRECTION DE « .hero ». Le fond sombre du hero
 *    etait peint sur un element qui porte AUSSI « .wrap » (max-width: 1080px) : il s'arretait
 *    donc a 1080px, laissant la couleur de la page de part et d'autre. Sur la reference que
 *    l'editeur a designee, ce bandeau va d'un bord a l'autre, et c'est ce qui lui donne son
 *    assise.
 * ⛔ MAIS « .hero wrap » EST UTILISE PAR 22 PAGES. Corriger « .hero » lui-meme changerait
 *    l'allure de tout le site d'un coup, y compris des pages qu'on n'a pas regardees — le
 *    panier, les mentions legales, l'espace client. On ajoute donc un modificateur porte par
 *    l'accueil SEUL. L'etendre a une autre page tiendra en une classe.
 * ⚠️ Le contenu, lui, reste dans un « .wrap » INTERIEUR : c'est le fond qui s'etend, jamais
 *    le texte — une ligne de texte de 1600px ne se lit pas.
 */
.hero--pleine-largeur,
.bandeau-preuve--pleine-largeur {
    max-width: none;
    padding-left: 0;
    padding-right: 0;
}

/* Le bandeau de preuve prolonge le hero : aucune couture visible entre les deux. */
.bandeau-preuve--pleine-largeur {
    margin-top: 0;
}

/* ── Recherche dans le site (10/10/2026) ───────────────────────────────────
 * Un champ compact dans l'en-tete, une page de resultats sobre. Les couleurs viennent des
 * jetons existants : aucune valeur nouvelle, les deux themes restent coherents. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.header-search {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 2px 4px 2px 12px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--panel);
}
.header-search input {
    width: 150px;
    border: 0;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: 0.92rem;
    outline: none;
}
.header-search input::placeholder {
    color: var(--muted);
}
.header-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.header-search button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
}
.header-search button:hover,
.header-search button:focus-visible {
    background: var(--accent-soft);
    color: var(--accent);
}
.header-search svg,
.header-search-link svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.header-search-link {
    display: none;
}
@media (max-width: 900px) {
    .header-search input {
        width: 110px;
    }
}
@media (max-width: 560px) {
    .header-search {
        display: none;
    }
    .header-search-link {
        display: inline-flex;
    }
}
.recherche-form {
    display: flex;
    gap: 10px;
    max-width: 640px;
    margin-top: 18px;
}
.recherche-form input {
    flex: 1;
    min-width: 0;
    padding: 12px 16px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel);
    color: var(--ink);
    font: inherit;
}
.recherche-form input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.recherche-resultats {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 22px;
}
.recherche-resultat {
    padding-bottom: 22px;
    border-bottom: 1px solid var(--line);
}
.recherche-resultat h2 {
    margin: 4px 0 6px;
    font-size: 1.25rem;
}
.recherche-type {
    display: inline-block;
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}
.recherche-extrait {
    margin: 0;
    color: var(--muted);
}
.recherche-extrait mark {
    background: var(--accent-soft);
    color: var(--ink);
    border-radius: 3px;
    padding: 0 2px;
}
.recherche-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 18px;
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
}
@media (max-width: 560px) {
    .recherche-form {
        flex-direction: column;
    }
}

/* ── Grilles tarifaires sur téléphone (16/10/2026, audit) ──────────────────────────────
 * À 390 px, la colonne des libellés mangeait l'écran : l'en-tête des offres, tous les prix
 * et les boutons « Commander » vivaient hors champ à droite, sans que rien ne dise qu'il
 * fallait faire défiler. Trois gestes, aucun sur bureau :
 *   1. la colonne des libellés rétrécit et SE FIGE à gauche (sticky) — les valeurs défilent
 *      sous elle, le lecteur sait toujours de quelle ligne il s'agit ;
 *   2. un voile dégradé sur le bord droit dit « ça continue » tant que ça continue ;
 *   3. une consigne de défilement au-dessus de la grille, masquée aux grands écrans. */
@media (max-width: 640px) {
    .pricing-table-wrap {
        position: relative;
    }
    .pricing-table-wrap::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 28px;
        pointer-events: none;
        background: linear-gradient(to left, var(--paper), transparent);
    }
    .pricing-table th,
    .pricing-table td {
        padding: 10px 10px;
        font-size: 0.88rem;
    }
    .pricing-table .pricing-table-label,
    .pricing-table tbody th[scope="row"],
    .pricing-table tbody td:first-child,
    .pricing-table thead th:first-child {
        position: sticky;
        left: 0;
        z-index: 1;
        background: var(--panel);
        max-width: 46vw;
        min-width: 0;
        text-align: left;
        box-shadow: 2px 0 0 var(--line);
    }
}
.pricing-scroll-hint {
    display: none;
}
@media (max-width: 640px) {
    .pricing-scroll-hint {
        display: block;
        margin: 0 0 8px;
        font-size: 0.85rem;
        color: var(--muted);
    }
}
