/* ============================================================
   charte-classique.css — FEUILLE UNIQUE DE LA FAMILLE « pages classiques »
   ⚠️ FICHIER GÉNÉRÉ par scripts/regenerer_la_charte.py. Ne rien écrire ici à la
   main : modifier la feuille d'origine, puis régénérer. Les fichiers d'origine
   restent sur le disque.
   Ordre concaténé : fonts.css, fonts_refonte.css, devisaly.css, sections.css, anton-rognage.css, no_scroll_coherence.css, no_scroll_form.css, n_menu_global.css, design-arrondi.css, nuee3d.css, barre_et_contenu.css, passe-interface.css
   ============================================================ */

/* ===== début fonts.css ===== */
/* Polices auto-hébergées (aucune dépendance externe) — Fraunces + Inter */

/* ⚠️ MONO DE LA CHARTE — IBM Plex Mono, auto-hébergée (fichiers déjà servis
   pour les sites clients). Sans cette déclaration, `--font-mono` pointait sur
   'SFMono-Regular', une police ABSENTE du serveur : les prix s'affichaient dans
   la police système, donc différemment selon la machine du visiteur. */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/client-ibm-plex-mono-400-normal-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/client-ibm-plex-mono-500-normal-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/client-ibm-plex-mono-600-normal-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

/* ============================================================
   POLICE D'AFFICHAGE — Bodoni Moda (2026-09-30)
   ⚠️ Remplace Fraunces, jugee « tres bas de gamme » par le user. Fraunces est
   la serif la plus surexposee qui existe (defaut d'entrainement des modeles) et
   son faible contraste la fait paraitre molle en grand titre.
   Bodoni Moda appartient a la lignee DIDOT : la typographie du luxe francais,
   contraste plein/degage tres fort, autorite editoriale immediate.
   Auto-hebergee, aucune requete externe (la CSP l'exige).
   ============================================================ */

/* ⚠️ Vrai fichier italique (17060 o). Avant, cette declaration pointait sur le
   MEME fichier que la normale : le navigateur fabriquait un faux italique
   (penche mecanique), tres visible sur un Didone, et c'est l'element le plus
   en vue de l'accueil (les mots en or du titre). */


/* ===== fin fonts.css ===== */

/* ===== début fonts_refonte.css ===== */
/* ============================================================
   Polices de la refonte — AUTO-HÉBERGÉES, aucune dépendance CDN.
   ⚠️ Règle dure du projet : le site ne charge RIEN d'un domaine tiers.
   Vérifier avec un routeur Playwright qui `abort` toute requête non locale.
   Anton et Archivo sont des polices VARIABLES instanciées à la conversion
   (voir scripts/installer_refonte_blanche.py) : les navigateurs qui ignorent
   les axes variables reçoivent malgré tout la bonne graisse.
   ============================================================ */

@font-face {
  font-family: 'Anton';
  src: url('fonts/anton-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'PlexMono';
  src: url('fonts/plex-mono-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}

/* ===== fin fonts_refonte.css ===== */

/* ===== début devisaly.css ===== */
/* ============================================================
   DEVISALY — FEUILLE UNIQUE.

   ⚠️⚠️ POURQUOI UN SEUL FICHIER. Avant cette consolidation, chaque page
   chargeait 15 feuilles, empilées au fil des demandes : theme-binaire,
   menu, carrousel-mobile, respiration, langage-visuel, echelle-unique…
   Chaque ajout corrigeait le précédent, et 147 `!important` servaient à
   trancher entre des règles de même poids. C'est ce qui a produit les
   corrections en cascade (boutons, titres, prix, cadrage).

   ⚠️ CE FICHIER EST GÉNÉRÉ — ne pas l'éditer directement.
      Source : `scripts/consolider_css.py`, qui recopie les feuilles dans
      leur ordre de chargement. Modifier une section ici serait perdu à la
      prochaine consolidation.
      Pour une nouvelle règle : l'ajouter dans la section qui la concerne,
      en respectant l'ordre (une règle de fin gagne sur une règle de début).

   ⚠️ CE QUI RESTE SÉPARÉ, ET POURQUOI :
      • fonts.css / fonts_refonte.css : les @font-face, partagés avec les
        emails — un fichier de polices n'a pas vocation à être dans le CSS
        de mise en page ;
      • site_client*.css : ils habillent les SITES DES ARTISANS (le produit
        vendu), pas Devisaly. Une marque distincte, une feuille distincte.

   ⚠️ ORDRE DES SECTIONS = ORDRE DE CASCADE (le dernier gagne à poids égal) :
      1. polices et base        (luxe)
      2. finitions historiques  (atelier-polish, artisan, accueil-contrat)
      3. normalisations         (echelle)
      4. refonte                (refonte_blanche, vitrine)
      5. menu                   (menu)
      6. thème                  (theme-binaire)
      7. corrections mesurées   (carrousel-mobile, respiration,
                                 langage-visuel, echelle-unique)
   ============================================================ */


/* ============================================================
   EX-fonts.css   (2374 octets, 0 !important)
   ============================================================ */

/* Polices auto-hébergées (aucune dépendance externe) — Fraunces + Inter */

/* ⚠️ MONO DE LA CHARTE — IBM Plex Mono, auto-hébergée (fichiers déjà servis
   pour les sites clients). Sans cette déclaration, `--font-mono` pointait sur
   'SFMono-Regular', une police ABSENTE du serveur : les prix s'affichaient dans
   la police système, donc différemment selon la machine du visiteur. */
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/static/fonts/client-ibm-plex-mono-400-normal-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/static/fonts/client-ibm-plex-mono-500-normal-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;src:url('/static/fonts/client-ibm-plex-mono-600-normal-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;}

/* ============================================================
   POLICE D'AFFICHAGE — Bodoni Moda (2026-09-30)
   ⚠️ Remplace Fraunces, jugee « tres bas de gamme » par le user. Fraunces est
   la serif la plus surexposee qui existe (defaut d'entrainement des modeles) et
   son faible contraste la fait paraitre molle en grand titre.
   Bodoni Moda appartient a la lignee DIDOT : la typographie du luxe francais,
   contraste plein/degage tres fort, autorite editoriale immediate.
   Auto-hebergee, aucune requete externe (la CSP l'exige).
   ============================================================ */

/* ⚠️ Vrai fichier italique (17060 o). Avant, cette declaration pointait sur le
   MEME fichier que la normale : le navigateur fabriquait un faux italique
   (penche mecanique), tres visible sur un Didone, et c'est l'element le plus
   en vue de l'accueil (les mots en or du titre). */



/* ============================================================
   EX-fonts_refonte.css   (1187 octets, 0 !important)
   ============================================================ */

/* ============================================================
   Polices de la refonte — AUTO-HÉBERGÉES, aucune dépendance CDN.
   ⚠️ Règle dure du projet : le site ne charge RIEN d'un domaine tiers.
   Vérifier avec un routeur Playwright qui `abort` toute requête non locale.
   Anton et Archivo sont des polices VARIABLES instanciées à la conversion
   (voir scripts/installer_refonte_blanche.py) : les navigateurs qui ignorent
   les axes variables reçoivent malgré tout la bonne graisse.
   ============================================================ */

@font-face {
  font-family: 'Anton';
  src: url('fonts/anton-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('fonts/archivo-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}

@font-face {
  font-family: 'PlexMono';
  src: url('fonts/plex-mono-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}


/* ============================================================
   EX-luxe.css   (93600 octets, 3 !important)
   ============================================================ */

/* ============================================================
   DEVISALY — Design System "L'Atelier"
   Identité : le plan de travail de l'artisan.
   Papier ivoire, traits de mesure fins, or comme l'outil précieux,
   encre comme le trait du crayon. Signature : lignes de cotation
   et repères de mesure, comme un plan technique.
   ============================================================ */

:root {
  /* ---- Palette "L'Atelier" ---- */
  --paper: #f7f4ee;        /* fond ivoire profond (papier) */
  --paper-2: #efeae0;      /* zones secondaires (papier usé) */
  --card: #fffdf9;         /* panels / cartes (papier neuf) */
  --card-2: #faf7f0;       /* surfaces hover */
  --ink: #191713;          /* encre (trait du crayon) */
  --ink-2: #3d3830;        /* texte secondaire */
  --muted: #6f675a;        /* texte tertiaire */
  --faint: #7d7463;        /* texte discret (contraste AA 4.5:1) */

  --gold: #b08a3e;         /* or principal (outil précieux) */
  --gold-2: #8a6a2a;       /* or profond */
  --gold-3: #6e5320;       /* or le plus profond */
  --gold-line: rgba(176,138,62,.30);
  --gold-bg: rgba(176,138,62,.07);
  --gold-soft: #e9dcc0;    /* or clair (liserés) */

  --danger: #b23a2e;
  --ok: #3d7a4a;

  --line: #e6dfd0;         /* bordures (traits fins) */
  --line-soft: #efe9dc;

  --shadow-sm: 0 1px 2px rgba(25,23,19,.04), 0 2px 8px rgba(25,23,19,.04);
  --shadow-md: 0 4px 12px rgba(25,23,19,.06), 0 12px 32px rgba(25,23,19,.08);
  --shadow-lg: 0 8px 24px rgba(25,23,19,.08), 0 24px 60px rgba(25,23,19,.12);

  --radius: 6px;           /* rayons sobres, presque droits (plan technique) */
  --radius-lg: 10px;

  /* ---- Typo ---- */
  /* ⚠️ Aligné sur echelle.css : UNE SEULE déclaration fait foi (voir echelle).
     Le site a une identité, pas trois. */
  --font-serif: 'Anton', 'Archivo', system-ui, sans-serif;
  --font-sans: 'Archivo', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, Menlo, monospace;

  /* ---- Tokens sémantiques (refonte 2026-09) ----
     Règle de contraste WCAG mesurée sur fond cartes/ivoire :
       --gold  #b08a3e = 3,16:1  -> AA gros éléments seulement (icônes, filets, aplat or)
       --gold-2#8a6a2a = 4,58:1  -> AA texte (>= 4.5) : TOUT texte or doit l'utiliser
       --gold-3#6e5320 = 6,55:1  -> AAA, réservé aux libellés fins sur or très clair
     Ne jamais écrire `color: var(--gold)` sur du texte < 18px : utiliser --accent. */
  --accent: var(--gold-2);        /* or lisible (texte, liens, petites icônes) */
  --accent-strong: var(--gold-3); /* or profond (libellés fins, hover) */
  --deco: var(--gold);            /* or décoratif (filets, aplats, gros éléments) */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-sans);
  background: var(--paper);
  color: var(--ink);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  line-height: 1.7;
  font-size: 15px;
  transition: color .3s ease;
}

::selection { background: var(--gold); color: #fff; }

/* ---- Signature : quadrillage de plan technique en fond (léger, discret) ---- */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(1100px 640px at 84% -14%, rgba(176,138,62,.07), transparent 60%),
    radial-gradient(820px 560px at -8% 30%, rgba(176,138,62,.05), transparent 55%);
}
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .35;
  background-image:
    linear-gradient(rgba(25,23,19,.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(25,23,19,.02) 1px, transparent 1px);
  background-size: 48px 48px;
}
.container, .topbar-inner, .auth-card, .footer { position: relative; z-index: 1; }

/* ---- Repères de mesure (signature) ---- */
.measure {
  display: flex; align-items: center; gap: 12px;
  color: var(--accent); font-family: var(--font-mono);
  font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase;
}
.measure::before, .measure::after {
  content: ""; height: 1px; background: var(--gold-line); flex: 1;
}
.measure::before { background: repeating-linear-gradient(90deg, var(--gold) 0 2px, transparent 2px 6px); }

/* Repères de cotation verticaux (marges d'atelier) */
.measure-rail {
  display: flex; align-items: center; gap: 14px;
}
.measure-rail .rail-line {
  flex: 1; height: 1px; align-self: center;
  background: repeating-linear-gradient(90deg, var(--gold-2) 0 3px, transparent 3px 7px);
  opacity: .55;
}
.measure-rail .rail-ticks {
  display: flex; gap: 0; flex-direction: column; align-items: center;
  color: var(--accent); font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 1.5px;
}

/* Repères de coin (mire d'atelier) — appliqués aux cartes/panels clés */
.atelier-corner {
  position: relative;
}
.atelier-corner::before,
.atelier-corner::after {
  content: ""; position: absolute; width: 14px; height: 14px;
  pointer-events: none; z-index: 2;
}
.atelier-corner::before {
  top: 10px; left: 10px;
  border-top: 1px solid var(--gold); border-left: 1px solid var(--gold);
}
.atelier-corner::after {
  bottom: 10px; right: 10px;
  border-bottom: 1px solid var(--gold); border-right: 1px solid var(--gold);
}

/* ============ BOUTONS ============ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 24px; border-radius: var(--radius);
  font-family: var(--font-sans); font-size: 14px; font-weight: 500;
  cursor: pointer; text-decoration: none; border: 1px solid transparent;
  transition: all .2s ease; letter-spacing: .01em; line-height: 1;
  white-space: nowrap; position: relative;
}
.btn:disabled { opacity: .45; cursor: not-allowed; }

.btn.primary {
  color: #fff;
  background: linear-gradient(165deg, #c9a457 0%, #b08a3e 48%, #8a6a2a 100%);
  border-color: rgba(255,255,255,.2);
  box-shadow: 0 2px 6px rgba(176,138,62,.3), 0 8px 20px rgba(176,138,62,.28), inset 0 1px 0 rgba(255,255,255,.35);
}
.btn.primary:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(176,138,62,.35), 0 14px 32px rgba(176,138,62,.3), inset 0 1px 0 rgba(255,255,255,.35); }
.btn.primary:active { transform: translateY(0); box-shadow: inset 0 2px 6px rgba(110,83,32,.3); }

.btn.ghost {
  color: var(--ink);
  background: var(--card);
  border-color: var(--line);
}
.btn.ghost:hover { border-color: var(--gold); color: var(--gold-2); background: var(--card-2); }

.btn.big { padding: 16px 34px; font-size: 15px; border-radius: var(--radius-lg); line-height: 1.3; }

/* ============ TOPBAR ============ */
.topbar {
  background: rgba(255,253,249,.9);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 60;
}
.topbar-inner { max-width: 1120px; margin: 0 auto; padding: 8px 28px; display: flex; align-items: center; justify-content: space-between; }

.brand { display: flex; align-items: center; gap: 10px; }
.brand a { display: flex; align-items: center; gap: 10px; text-decoration: none; color: inherit; }
.brand-mark {
  /* ⚠️⚠️ BOÎTE DIMENSIONNÉE AU CONTENU — ne pas remettre une taille fixe.
     Le logo est un MOT-SYMBOLE de 137 px de large (il contient « devisaly »),
     pas un carré de 32 px. Une taille fixe le faisait déborder de 105 px
     AU-DESSUS du texte adjacent : les deux logos se chevauchaient à l'écran. */
  width: auto; height: 30px; min-width: 0;
  border-radius: 0;
  display: flex; align-items: center;
  background: transparent;
  box-shadow: none;
}
.brand-mark svg, .brand-mark img { display: block; width: auto; height: 100%; }
/* ⚠️ Le logo contient déjà le mot « devisaly » : le texte écrit à côté est un
   DOUBLON visuel. Il est masqué sur tout le site. */
.brand-name { display: none; }
.brand-name-off { font-family: var(--font-serif); font-weight: 500; font-size: 16px; letter-spacing: .01em; color: var(--ink); line-height: 1; }
.brand-name span { color: var(--gold-2); }
.brand-sub { font-size: 12px; color: var(--faint); letter-spacing: 2.5px; text-transform: uppercase; }

.nav { display: flex; align-items: center; gap: 28px; }
.nav > a:not(.btn) { color: var(--muted); text-decoration: none; font-size: 13px; font-weight: 500; transition: color .15s; position: relative; }
.nav > a:not(.btn):hover { color: var(--gold-2); }
.nav > a.active { color: var(--gold-2); }
.nav > a.active::after { content: ""; position: absolute; left: 0; right: 0; bottom: -6px; height: 1.5px; background: var(--gold); }
.nav .logout { color: var(--danger); }
.nav .btn { padding: 7px 15px; font-size: 12px; border-radius: var(--radius); }

/* ============ SÉLECTEUR DE LANGUE ============ */
.lang-switch { display: flex; align-items: center; gap: 2px; margin-left: 2px; }
.lang-link {
  font-size: 12px; font-weight: 500; letter-spacing: .04em; color: var(--faint);
  text-decoration: none; padding: 5px 8px; border: 1px solid transparent; border-radius: var(--radius);
  transition: color .15s, border-color .15s;
}
.lang-link:hover { color: var(--gold-2); border-color: var(--line); }

/* ============ BANDEAU VÉRIFICATION EMAIL ============ */
.verify-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; margin-bottom: 20px;
  border: 1px solid var(--gold-line); border-radius: var(--radius);
  background: var(--gold-bg); color: var(--ink); font-size: 14px;
}
.verify-banner svg { color: var(--gold-2); flex-shrink: 0; }
.verify-banner a { color: var(--gold-2); font-weight: 500; text-decoration: none; }
.verify-banner a:hover { text-decoration: underline; }

/* ============ MENU UTILISATEUR ============ */
.user-menu { position: relative; display: flex; align-items: center; }
.user-menu-btn {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); cursor: pointer; transition: border-color .15s; height: 30px;
}
.user-menu-btn:hover { border-color: var(--gold); }
.user-menu-btn svg { color: var(--faint); }
.user-avatar {
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; font-weight: 500; font-size: 11px; color: #fff;
  background: linear-gradient(160deg, #d8b97c, #a9863f);
}
.user-dropdown {
  position: absolute; right: 0; top: calc(100% + 10px); min-width: 220px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: 8px; display: none; z-index: 70;
}
.user-menu.open .user-dropdown { display: block; }
.user-dropdown .ud-head { padding: 10px 12px; border-bottom: 1px solid var(--line-soft); margin-bottom: 6px; }
.user-dropdown .ud-name { font-weight: 500; font-size: 14px; }
.user-dropdown .ud-plan { font-size: 12px; color: var(--gold-2); }
.user-dropdown a {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--radius);
  font-size: 14px; color: var(--ink); text-decoration: none; transition: background .12s;
}
.user-dropdown a:hover { background: var(--card-2); color: var(--gold-2); }
.user-dropdown a.logout { color: var(--danger); }
.user-dropdown a.logout:hover { background: rgba(178,58,46,.08); color: var(--danger); }

/* ============ MENU LATÉRAL (drawer) ============ */
.burger {
  display: none; flex-direction: column; justify-content: center; gap: 4px;
  width: 40px; height: 40px; background: transparent;
  border: 1px solid var(--line); border-radius: var(--radius); cursor: pointer; padding: 10px;
}
.burger span { display: block; height: 1.5px; width: 100%; background: var(--ink); border-radius: 2px; transition: transform .25s, opacity .2s; }
.burger.open span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.burger.open span:nth-child(2) { opacity: 0; }
.burger.open span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

.drawer-scrim {
  position: fixed; inset: 0; background: rgba(25,23,19,.42);
  backdrop-filter: blur(2px); z-index: 200; opacity: 0; pointer-events: none;
  transition: opacity .25s;
}
.drawer-scrim.open { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed; top: 0; right: 0; height: 100dvh; width: 380px; max-width: 90vw;
  background: var(--card); border-left: 1px solid var(--line);
  z-index: 201; transform: translateX(100%); transition: transform .3s cubic-bezier(.22,.61,.36,1);
  display: flex; flex-direction: column; box-shadow: -12px 0 40px rgba(25,23,19,.12);
}
.drawer.open { transform: translateX(0); }
body.drawer-open { overflow: hidden; }

.drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 20px; border-bottom: 1px solid var(--line-soft); }
.drawer-brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.drawer-mark { display: inline-flex; width: 30px; height: 30px; }
.drawer-mark img { width: 100%; height: 100%; }
.drawer-wordmark { font-family: var(--font-serif); font-weight: 500; font-size: 19px; color: var(--ink); }
.drawer-wordmark span { color: var(--gold-2); }
.drawer-close { background: transparent; border: none; cursor: pointer; color: var(--muted); padding: 6px; display: inline-flex; border-radius: var(--radius); transition: background .15s, color .15s; }
.drawer-close:hover { background: var(--paper); color: var(--ink); }

.drawer-user { display: flex; align-items: center; gap: 12px; padding: 16px 20px 0; }
.drawer-avatar { width: 42px; height: 42px; border-radius: 50%; background: var(--gold-soft); color: var(--gold-2); display: grid; place-items: center; font-family: var(--font-serif); font-size: 19px; font-weight: 500; flex-shrink: 0; }
.drawer-user-name { font-weight: 500; font-size: 14.5px; color: var(--ink); }
.drawer-user-plan { font-size: 12px; color: var(--muted); }

.drawer-cta {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: 16px 20px 0; padding: 14px 18px; background: var(--gold-grad, linear-gradient(165deg, var(--gold), var(--gold-2)));
  color: #fff; border-radius: var(--radius); text-decoration: none; font-weight: 500; font-size: 14.5px;
  min-height: 48px;
}
.drawer-cta.ghost { background: transparent; color: var(--gold-2); border: 1px solid var(--gold-line); margin-top: 10px; }

.drawer-nav { flex: 1; overflow-y: auto; padding: 18px 20px 8px; }
.drawer-group-label { font-size: 11px; letter-spacing: 1.4px; text-transform: uppercase; color: var(--faint); font-weight: 500; margin: 6px 0 10px; }
.drawer-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 22px; }
.drawer-grid a {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: 13px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  text-decoration: none; color: var(--ink); font-size: 13px; font-weight: 500;
  min-height: 74px; transition: border-color .15s, background .15s;
}
.drawer-grid a:hover { border-color: var(--gold-line); background: var(--gold-bg); }
.drawer-grid a svg { color: var(--gold-2); }

.drawer-list { display: flex; flex-direction: column; margin-bottom: 18px; }
.drawer-list a {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 2px; text-decoration: none; color: var(--ink); font-size: 14px;
  border-bottom: 1px solid var(--line-soft); transition: color .15s;
}
.drawer-list a:last-child { border-bottom: none; }
.drawer-list a:hover { color: var(--gold-2); }
.drawer-tag { font-family: var(--font-mono); font-size: 11.5px; color: var(--gold-2); background: var(--gold-soft); padding: 3px 9px; border-radius: 999px; }

.drawer-more { border-top: 1px solid var(--line-soft); padding-top: 6px; margin-bottom: 16px; }
.drawer-more summary {
  display: flex; align-items: center; justify-content: space-between; cursor: pointer;
  padding: 12px 2px; font-size: 13.5px; font-weight: 500; color: var(--muted); list-style: none;
}
.drawer-more summary::-webkit-details-marker { display: none; }
.drawer-more[open] summary { color: var(--gold-2); }
.drawer-more[open] summary svg { transform: rotate(180deg); }
.drawer-more summary svg { transition: transform .2s; }
.drawer-more .drawer-list { margin: 4px 0 12px; }

.drawer-foot { padding: 14px 20px calc(14px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: 8px; }
.drawer-logout { display: flex; align-items: center; gap: 8px; justify-content: center; padding: 12px; text-decoration: none; color: var(--danger); font-size: 13.5px; font-weight: 500; border-radius: var(--radius); }
.drawer-logout:hover { background: rgba(154,59,46,.06); }
.drawer-foot .drawer-cta { margin: 0; }
.hm-section a.logout:hover { background: rgba(178,58,46,.08); }
.hm-section a svg { opacity: .65; }

/* ============ CONTENEURS / SECTIONS ============ */
/* ⚠️⚠️ LE CONTENEUR DE RÉFÉRENCE — SOURCE UNIQUE DU CADRE.
   Toute page qui cadre son contenu passe par cette largeur. La refonte de
   l'accueil utilisait 1320 px de son côté : 200 px d'écart, soit 94 px de
   décalage à l'écran entre l'accueil et les autres pages — le défaut que le
   user a signalé (« tout est mal aligné »).
   Ne PAS créer un second conteneur à une autre largeur : modifier ICI. */
.container { max-width: 1120px; margin: 0 auto; padding: 0 28px 20px; }
.container.narrow { max-width: 840px; }

.page-head { margin-bottom: 34px; padding-top: 24px; }
.page-head h1 { font-family: var(--font-serif); font-size: 42px; font-weight: 500; letter-spacing: -.01em; color: var(--ink); }
.page-head p { color: var(--muted); font-size: 15px; margin-top: 8px; max-width: 560px; }

/* En-tête de page centré (pages marketing : pricing, contact, logiciel…) */
.page-head.centered { text-align: center; margin-bottom: 44px; padding-top: 24px; }

/* En-tête de page posé sur le plan d'atelier 3D (builder, tarifs).
   Le canvas est un fond absolu ; l'intensité est réglée par data-intensity. */
.page-head-3d {
  position: relative; overflow: hidden; border-radius: 16px; z-index: 0;
  padding-bottom: 54px;   /* laisse de la place au sol en perspective */
}
.page-head-3d.centered { padding-bottom: 34px; }
.page-head-3d > *:not(.bg3d) { position: relative; z-index: 1; }
.bg3d {
  position: absolute; inset: -6px -16px 0 -16px; z-index: 0;
  width: auto; height: auto; pointer-events: none;
  /* fondu haut/bas : la scène se dissout au lieu de finir net */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 26%, #000 80%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 26%, #000 80%, transparent 100%);
}
.page-head.centered .eyebrow { justify-content: center; margin-bottom: 12px; }
.page-head.centered h1 { font-size: 56px; line-height: 1.06; letter-spacing: -.03em; text-wrap: balance; }
.page-head.centered p { margin: 12px auto 0; }
.page-head.centered .measure { max-width: 420px; margin: 16px auto 0; }
.page-head.centered .cta-row { display: flex; gap: 14px; margin-top: 26px; flex-wrap: wrap; align-items: center; }
.page-head.centered .trust { display: flex; gap: 24px; margin-top: 22px; flex-wrap: wrap; }
.page-head.centered .trust span { font-size: 13px; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.page-head.centered .trust .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 8px rgba(176,138,62,.4); }

.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 12px; letter-spacing: 2.5px; text-transform: uppercase;
  color: var(--accent); font-weight: 500;
}
.eyebrow::before { content: ""; width: 30px; height: 1px; background: var(--gold); }

/* ============ CARTES ============ */
.card, .panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-sm);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.card-title, .panel-title {
  font-family: var(--font-serif); font-weight: 500; font-size: 17px;
  display: flex; align-items: center; gap: 10px; margin-bottom: 4px; color: var(--ink);
}
.card-title .num {
  width: 28px; height: 28px; border-radius: var(--radius); flex-shrink: 0;
  display: grid; place-items: center; font-size: 13px; font-family: var(--font-mono);
  background: var(--gold-bg); color: var(--gold-2); border: 1px solid var(--gold-line);
}
.card-sub { color: var(--faint); font-size: 13px; margin-bottom: 20px; }
.panel-sub { color: var(--faint); font-size: 13px; margin-bottom: 22px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--line-soft); }

/* ============ FORMULAIRES ============ */
label { display: block; font-size: 12.5px; font-weight: 500; letter-spacing: 1px; text-transform: uppercase; color: var(--faint); margin: 16px 0 7px; }
select, input[type=number], input[type=tel], input[type=text], input[type=email], input[type=password], textarea {
  width: 100%; padding: 13px 15px; border-radius: var(--radius); font-size: 14px; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); outline: none;
  font-family: var(--font-sans); transition: border-color .15s, box-shadow .15s;
}
select:focus, input:focus, textarea:focus {
  border-color: var(--gold); box-shadow: 0 0 0 3px rgba(176,138,62,.12); background: var(--card);
}
select option { background: var(--card); color: var(--ink); }
textarea { min-height: 90px; resize: vertical; }
input::placeholder { color: var(--faint); }

.region-hint {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; padding: 9px 15px;
  border-radius: var(--radius); background: var(--gold-bg); border: 1px solid var(--gold-line);
  font-size: 13px; color: var(--gold-2);
}

/* ============ PRESTATIONS ============ */
.services-list { display: flex; flex-direction: column; gap: 10px; }
.service-item {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 13px 15px; transition: border-color .15s, box-shadow .15s;
}
.service-item:hover { border-color: var(--gold-line); box-shadow: var(--shadow-sm); }
.service-item .info { flex: 1; min-width: 0; }
.service-item .info select, .service-item .info input[type=text] { background: var(--card); }
.service-item .s-label { font-size: 13px; font-weight: 500; }
.service-item .s-price { font-size: 12px; color: var(--gold-2); margin-top: 3px; font-family: var(--font-mono); }
/* Prix conseillé CLIQUABLE : reprend la valeur dans le champ en un clic.
   Rendu comme un petit bouton discret (l'artisan peut aussi taper son prix). */
.service-item button.s-price {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: var(--gold-bg); border: 1px dashed var(--gold-line);
  border-radius: 6px; padding: 3px 8px; text-align: left;
  transition: background .15s, border-color .15s;
}
.service-item button.s-price::after { content: "+"; font-weight: 500; opacity: .7; }
.service-item button.s-price:hover { background: rgba(176,138,62,.16); border-color: var(--gold); }
.service-item button.s-price.used { border-style: solid; background: rgba(176,138,62,.18); }
.service-item button.s-price.used::after { content: "✓"; }
.service-item .price-wrap { display: flex; align-items: center; gap: 12px; }
.service-item .field { display: flex; align-items: center; gap: 6px; }
.service-item .field-label { font-size: 11px; color: var(--faint); font-weight: 500; white-space: nowrap; }
.service-item .field-input { display: flex; align-items: center; gap: 4px; }
.service-item .price { width: 80px; padding: 9px 11px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); font-size: 13px; text-align: right; outline: none; color: var(--ink); font-family: var(--font-mono); }
.service-item .price:focus { border-color: var(--gold); }
.service-item .price-unit { font-size: 12px; color: var(--faint); }
.service-item .qty { width: 60px; padding: 9px 11px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card); font-size: 13px; text-align: center; outline: none; color: var(--ink); font-family: var(--font-mono); }
.service-item .qty:focus { border-color: var(--gold); }
.service-item .remove {
  width: 36px; height: 36px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--card);
  color: var(--faint); cursor: pointer; flex-shrink: 0; transition: all .15s;
  display: inline-flex; align-items: center; justify-content: center;
}
.service-item .remove:hover { border-color: var(--danger); color: var(--danger); }

.add-service {
  margin-top: 14px; padding: 12px 18px; border-radius: var(--radius);
  border: 1px dashed var(--gold-line); background: transparent;
  color: var(--gold-2); cursor: pointer; font-size: 13px; font-weight: 500; width: 100%;
  transition: all .15s;
}
.add-service:hover { background: var(--gold-bg); border-style: solid; }
/* CTA add-service + bouton réinitialiser dans la même rangée */
.svc-actions { display: flex; gap: 10px; align-items: stretch; margin-top: 14px; }
.svc-actions .add-service { margin-top: 0; flex: 1; }
.clear-draft {
  padding: 12px 18px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--card);
  color: var(--muted); cursor: pointer; font-size: 13px; font-weight: 500;
  transition: all .15s; white-space: nowrap;
}
.clear-draft:hover { border-color: var(--danger); color: var(--danger); background: rgba(185,67,38,.05); }
@media (max-width:600px) {
  .svc-actions { flex-direction: column; }
  .svc-actions .add-service, .clear-draft { width: 100%; }
}

/* ============ CLIENT ============ */
.client-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.client-fields .full { grid-column: 1 / -1; }

/* ============ BUILDER ============ */
.builder { display: grid; grid-template-columns: 1fr 372px; gap: 30px; align-items: start; }
@media (max-width: 820px) { .builder { grid-template-columns: 1fr; } }
.main-col { display: flex; flex-direction: column; gap: 22px; min-width: 0; max-width: 100%; }

/* Recherche de métier */
.trade-search-wrap { display: flex; flex-direction: column; gap: 8px; }
.trade-search-wrap input {
  padding: 10px 15px; border-radius: var(--radius); font-size: 14px;
  background: var(--card); border: 1px solid var(--line); color: var(--ink); outline: none;
}
.trade-search-wrap input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(176,138,62,.12); }

.summary-col { position: sticky; top: 88px; }
.summary {
  background: var(--card);
  border: 1px solid var(--gold-line); border-radius: var(--radius-lg);
  padding: 28px; box-shadow: var(--shadow-md); position: relative; overflow: hidden;
}
.summary::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.summary-title { font-family: var(--font-serif); font-weight: 500; font-size: 18px; margin-bottom: 18px; color: var(--gold-2); }
.summary-lines { max-height: 280px; overflow-y: auto; margin-bottom: 16px; }
.summary-line { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; }
.summary-line .sl-label { color: var(--muted); }
.summary-line .sl-price { font-weight: 500; color: var(--ink); font-family: var(--font-mono); }
.summary-empty { color: var(--faint); font-size: 13px; text-align: center; padding: 24px 0; }
.summary-totals { border-top: 1px solid var(--line); padding-top: 16px; }
.summary-totals > div { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 13px; color: var(--muted); }
.tva-row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 13px; color: var(--muted); }
.tva-input-wrap { display: flex; align-items: center; gap: 5px; }
.tva-input { width: 62px; padding: 6px 8px; border-radius: var(--radius); border: 1px solid var(--line); background: var(--paper); font-size: 13px; text-align: center; color: var(--ink); outline: none; font-family: var(--font-mono); }
.tva-input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(176,138,62,.12); }
.summary-totals .grand {
  font-family: var(--font-serif); font-size: 26px; font-weight: 500; color: var(--gold-2);
  border-top: 1px solid var(--line); margin-top: 10px; padding-top: 14px;
}
.summary-totals .grand span:last-child { font-weight: 500; }
.summary-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.summary-actions .btn { width: 100%; }
.summary-actions .dl-row { display: flex; gap: 8px; }
.summary-actions .dl-row .btn { flex: 1; font-size: 12.5px; padding: 11px 10px; }
.summary-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.summary-head .summary-title { margin-bottom: 0; }
.draft-flag { font-size: 11px; color: var(--faint); font-family: var(--font-mono); transition: color .2s; }
.draft-flag.on { color: var(--gold-2); }
.card.step { position: relative; }
.card.step .card-title .num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; background: var(--gold-soft);
  color: var(--gold-2); font-size: 13px; font-weight: 500; margin-right: 8px;
  font-family: var(--font-mono);
}
.client-pick { display: flex; gap: 10px; align-items: center; margin-bottom: 12px; }
.client-pick select { flex: 1; }
.btn.btn-sm { padding: 8px 14px; font-size: 12.5px; }
.custom-unit-wrap { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.mini-label { font-size: 11.5px; color: var(--muted); margin: 0; }
.custom-unit { width: auto; max-width: 130px; padding: 6px 10px; font-size: 12.5px; }
.client-stats { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; padding: 8px 10px; background: var(--paper); border: 1px solid var(--gold-line); border-radius: var(--radius); font-size: 12.5px; color: var(--muted); }
.client-stats .cs-total { font-family: var(--font-mono); font-weight: 500; color: var(--gold-2); }
.client-stats.muted { justify-content: center; color: var(--faint); }
.btn.btn-block { display: block; width: 100%; text-align: center; margin-top: 10px; }
.back-link { display: inline-block; font-size: 13px; color: var(--gold-2); margin-bottom: 10px; text-decoration: none; }
.back-link:hover { text-decoration: underline; }
.client-info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; }
.client-info-grid > div { display: flex; flex-direction: column; gap: 3px; }
.ci-label { font-size: 11.5px; color: var(--faint); text-transform: uppercase; letter-spacing: .04em; }
.ci-val { font-size: 14px; color: var(--ink); }
/* Code promo */
.promo-box { margin: 12px 0; padding: 14px; border: 1px dashed var(--gold-line); border-radius: var(--radius); background: var(--paper); }
.promo-box label { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 8px; }
.promo-row { display: flex; gap: 8px; }
.promo-row input { flex: 1; text-transform: uppercase; }
.promo-msg { font-size: 12.5px; margin-top: 8px; min-height: 16px; }
.promo-msg.ok { color: var(--success, #2e7d32); }
.promo-msg.err { color: var(--danger); }
.promo-temp { display: flex; align-items: center; gap: 8px; margin: 8px 0; padding: 8px 12px; background: var(--gold-soft); border: 1px solid var(--gold-line); border-radius: var(--radius); font-size: 12px; color: var(--gold-2); line-height: 1.35; }
.promo-temp svg { flex: 0 0 auto; }
/* Billing / rétention */
.billing-status { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.bs-plan { display: inline-block; padding: 6px 14px; border-radius: 999px; background: var(--paper); border: 1px solid var(--line); font-weight: 500; font-size: 13px; color: var(--muted); }
.bs-plan.pro { background: var(--gold-soft); border-color: var(--gold-line); color: var(--gold-2); }
.bs-note { font-size: 13px; color: var(--muted); }
.bs-note.warn { color: var(--danger); }
.billing-features { list-style: none; padding: 0; margin: 14px 0 18px; }
.billing-features li { position: relative; padding: 6px 0 6px 22px; font-size: 14px; color: var(--ink); }
.billing-features li::before { content: ""; position: absolute; left: 0; top: 12px; width: 12px; height: 7px; border-left: 2px solid var(--gold-2); border-bottom: 2px solid var(--gold-2); transform: rotate(-45deg); }
.billing-actions { margin: 10px 0; }
.billing-actions .btn, .billing-cancel-zone .btn { width: 100%; }
.billing-cancel-zone { margin-top: 10px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.retention-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 22px; }
.retention-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 20px; }
.retention-card.keep { border-color: var(--gold-line); background: var(--paper); }
.retention-card h3 { font-family: var(--font-serif); font-size: 16px; color: var(--gold-2); margin-bottom: 12px; }
.retention-card ul { list-style: none; padding: 0; }
.retention-card li { padding: 5px 0 5px 20px; position: relative; font-size: 13.5px; }
.retention-card li.muted::before { content: ""; position: absolute; left: 0; top: 11px; width: 11px; height: 2px; background: var(--faint); }
.retention-card.keep li::before { content: ""; position: absolute; left: 0; top: 11px; width: 12px; height: 7px; border-left: 2px solid var(--gold-2); border-bottom: 2px solid var(--gold-2); transform: rotate(-45deg); }
.retention-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.retention-actions .btn { width: 100%; }
.danger-zone { border-color: var(--danger); border-width: 1.5px; }
/* ==== Bibliothèque de prix (builder + page) ==== */
.svc-actions { flex-wrap: wrap; }
.add-service.lib-btn { border-style: solid; border-color: var(--gold-line); background: var(--gold-bg); }
.field-cost .field-input input { width: 80px; }
.margin-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 0 0; font-size: 13px; color: var(--gold-2); font-weight: 500; }
.margin-row span:last-child { font-family: var(--font-mono); }
.lib-overlay { z-index: 60; }
.lib-modal { max-width: 560px; }
#lib-search { width: 100%; margin: 10px 0 14px; }
.lib-list { max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.lib-item { display: flex; align-items: center; gap: 10px; text-align: left; padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); cursor: pointer; font: inherit; color: var(--ink); transition: border-color .15s, background .15s; }
.lib-item:hover { border-color: var(--gold); background: var(--gold-bg); }
.li-label { flex: 1; font-size: 13.5px; font-weight: 500; }
.li-meta { font-size: 11.5px; color: var(--muted); font-family: var(--font-mono); white-space: nowrap; }
.li-add { font-size: 11.5px; color: var(--gold-2); font-weight: 500; white-space: nowrap; }
.lib-empty { padding: 22px; text-align: center; color: var(--faint); font-size: 13px; }
.lib-import { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
/* ==== Chantiers ==== */
.chantier-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 18px; }
.chantier-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 20px; box-shadow: var(--shadow-sm); }
.cc-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.cc-num { font-family: var(--font-mono); font-size: 12px; color: var(--faint); }
.cc-client { font-family: var(--font-serif); font-size: 17px; font-weight: 500; }
.cc-status { font-size: 11.5px; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); white-space: nowrap; }
.cc-status.cc-en_cours { background: var(--gold-soft); border-color: var(--gold-line); color: var(--gold-2); }
.cc-status.cc-paid { background: #eaf5ea; border-color: #bfe0bf; color: #2e7d32; }
.cc-meta { font-size: 12.5px; color: var(--muted); margin: 8px 0 14px; }
.cc-progress-wrap { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 10px; margin-bottom: 12px; }
.cc-progress-wrap label { font-size: 11.5px; color: var(--faint); text-transform: uppercase; }
.cc-bar { height: 10px; background: var(--paper); border: 1px solid var(--gold-line); border-radius: 999px; overflow: hidden; cursor: pointer; }
.cc-bar-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--gold), var(--gold-2)); }
.cc-pct { font-family: var(--font-mono); font-size: 12px; color: var(--gold-2); }
.cc-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.cc-dates label { display: block; font-size: 11px; color: var(--faint); margin-bottom: 4px; }
.cc-paid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 10px; background: var(--paper); border-radius: var(--radius); margin-bottom: 14px; }
.cc-paid label { display: block; font-size: 11px; color: var(--faint); }
.cc-paid-amt, .cc-balance { font-family: var(--font-mono); font-weight: 500; font-size: 14px; }
.cc-balance { color: var(--danger); }
.cc-pnl { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 10px; background: var(--card-2); border-radius: var(--radius); margin-bottom: 14px; }
.cc-pnl label { display: block; font-size: 11px; color: var(--faint); }
.cc-cost, .cc-margin { font-family: var(--font-mono); font-weight: 500; font-size: 14px; }
.cc-cost { color: var(--muted); }
.cc-margin.pos { color: #2e7d32; }
.cc-margin.neg { color: var(--danger); }
.cc-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* ==== Collaborateurs ==== */
.collab-status { font-size: 11.5px; padding: 3px 10px; border-radius: 999px; border: 1px solid var(--line); }
.collab-status.invited { color: var(--muted); }
.collab-status.active { background: var(--gold-soft); border-color: var(--gold-line); color: var(--gold-2); }
@media (max-width: 600px) {
  .chantier-grid { grid-template-columns: 1fr; }
  .cc-dates, .cc-paid { grid-template-columns: 1fr; }
  .cc-progress-wrap { grid-template-columns: 1fr; }
  .cc-actions .btn { flex: 1 1 100%; min-height: 44px; }
}

/* ⚠️ Débordement horizontal de TABLETTE (601-1100px), corrigé 2026-09.
   `.mock-glow` (halo décoratif du hero) est en `position:absolute` avec des
   `inset` négatifs assumés sur desktop. Le correctif n'existait QUE sous 600px
   (`inset: 0` dans la media query mobile) : entre 601 et 1100px, le halo
   sortait de la page et créait un défilement horizontal (mesuré : 59-76px à
   768px et 900px). `overflow-x: clip` ne coûte rien ici et ne casse pas les
   éléments `position:sticky`. */
@media (min-width: 601px) and (max-width: 1100px) {
  html, body { overflow-x: clip; max-width: 100%; }
  .mock-glow { inset: -6% -4%; }
}

.error { color: var(--danger); font-size: 13px; margin-top: 10px; }

/* Bandeau upsell Pro dans le récapitulatif */
.upsell-banner {
  margin-top: 14px; padding: 14px;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--gold-bg), rgba(176,138,62,.03));
}
/* Bandeau d'upsell repliable : replié tant que le visiteur n'a rien chiffré,
   il ne doit pas occuper 40 % du récapitulatif ni distraire de l'action. */
.upsell-banner > summary { display: block; cursor: pointer; list-style: none; }
.upsell-banner > summary::-webkit-details-marker { display: none; }
.ub-head {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--font-serif); font-size: 15px; font-weight: 500; color: var(--gold-2);
  margin-bottom: 0;
}
.upsell-banner .ub-body { margin-top: 12px; }
.ub-list { list-style: none; margin: 0 0 14px; }
.ub-list li { font-size: 13px; color: var(--muted); padding: 5px 0; display: flex; align-items: center; gap: 8px; }
/* Coche dessinée en CSS (aucun caractère emoji/dingbat dans l'UI) */
.ub-list li::before {
  content: ""; width: 12px; height: 7px; flex-shrink: 0;
  border-left: 1.8px solid var(--accent); border-bottom: 1.8px solid var(--accent);
  transform: rotate(-45deg); margin: 0 2px 3px 1px;
}
.upsell-banner .btn { width: 100%; }
.ub-note { text-align: center; color: var(--faint); font-size: 12px; margin-top: 12px; }

/* ---- Verrouillage des prix pour les visiteurs non connectés ----
   On floute les DONNÉES DE MARCHÉ (prix conseillés, étude de concurrence) :
   c'est la valeur du produit, elle se mérite par un compte.
   MAIS on laisse VISIBLE le total que le visiteur a lui-même composé : il a
   saisi ses prestations, lui cacher sa propre somme est de la frustration pure
   (le compte est gratuit, il n'y a rien à protéger). C'est ce total visible qui
   crée l'investissement -> il s'inscrit pour l'enregistrer et l'exporter. */
/* ---- ⚠️⚠️ PLUS AUCUN VERROU VISUEL (2026-10-06).
   Le paywall du logiciel de devis est LEVÉ : le logiciel est gratuit. Les trois
   règles ci-dessous floutaient les DONNÉES DE MARCHÉ et masquaient l'étude de
   concurrence derrière « Connectez-vous » / « réservé aux comptes Pro ».
   Elles affichaient un verrou qui n'existe plus côté serveur (`_est_pro()`
   renvoie True) : le visiteur voyait une promesse de blocage démentie par
   l'application. On les neutralise en gardant la trace de ce qui existait.
   ⚠️ Si le paywall devait revenir (`DEVISALY_DEVIS_GRATUIT=0`), ces règles
   sont à restaurer — elles sont conservées en commentaire ci-dessous. */

/* .guest .region-hint,
   .guest .service-item .s-price,
   .guest .service-item .price-unit,
   .guest .competition .comp-table { filter: blur(5px); ... } */
.guest .region-hint,
.guest .service-item .s-price,
.guest .service-item .price-unit,
.guest .competition .comp-table {
  filter: none;
  user-select: auto;
  pointer-events: auto;
}
/* .guest .competition::before { content: "Étude de marché réservée aux comptes Pro"; } */
.guest .competition::before { content: none; }
/* ⚠️ NEUTRALISÉ 2026-10-06 : le message « Connectez-vous pour voir les prix
   conseillés » n'a plus lieu d'être — le logiciel est gratuit et l'étude de
   marché n'est plus réservée. Restaurer seulement si le paywall revient. */
.guest .region-hint::after {
  content: none;
}
.guest .service-item .s-price::after { font-size: 11px; }
/* Le bouton « prix conseillé » reste CLIQUABLE pour un visiteur : c'est le
   geste le plus répété du builder, et le rendre inerte pénalisait 100 % du
   trafic Google (il était `pointer-events:none` + flou). On garde l'indication
   que c'est une donnée de marché, sans bloquer l'action. */
/* Le prix conseillé est lisible ET cliquable pour un visiteur : il vient de
   composer un devis, lui cacher la valeur qu'il est invité à reprendre n'a
   aucun sens (et le flou sur un bouton actionnable est trompeur). Ce qui reste
   réservé, c'est l'ÉTUDE DE MARCHÉ détaillée (concurrence) — voir .competition. */
.guest .service-item button.s-price { pointer-events: auto; cursor: pointer; filter: none; }
.guest .service-item button.s-price::after { content: "+"; font-size: 12px; }
.guest .service-item .price-unit { filter: none; pointer-events: auto; }
.guest .competition::before {
  content: "Étude de marché réservée aux comptes Pro";
  position: absolute; top: 50%; left: 0; right: 0; transform: translateY(-50%);
  text-align: center; color: var(--gold-2); font-weight: 500; font-size: 13px; z-index: 3;
  filter: none;
}
.guest .competition { position: relative; }

/* Les totaux du devis restent visibles pour les visiteurs (voir commentaire
   ci-dessus) : plus de message "Total réservé aux comptes". */

/* ============ RÉSULTAT / DOCUMENT ============ */
.result { display: none; margin-top: 28px; min-width: 0; }
.result.show { display: block; }
#quote-body { min-width: 0; overflow-x: auto; }

.quote-doc { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); }
.quote-doc-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 24px 28px;
  background: linear-gradient(135deg, #8a6a2a, #b08a3e 55%, #6e5320);
  color: #fff; position: relative;
}
.quote-doc-head::after {
  content: ""; position: absolute; bottom: 0; left: 0; right: 0; height: 3px;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.35) 0 2px, transparent 2px 8px);
}
.quote-doc-head .q-title { font-family: var(--font-serif); font-size: 20px; font-weight: 500; }
.quote-doc-head .q-sub { font-size: 12px; opacity: .85; margin-top: 3px; }
.quote-doc .q-note { font-size: 11px; color: var(--muted); margin: 8px 0 4px; font-style: italic; }
.quote-doc-head .q-num { font-family: var(--font-mono); font-size: 14px; font-weight: 500; letter-spacing: 2px; opacity: .9; }

.quote-table { width: 100%; border-collapse: collapse; }
.quote-table thead th {
  text-align: left; padding: 14px 28px; font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line); background: var(--paper-2);
}
.quote-table thead th.num, .quote-table tbody td.num { text-align: right; }
.quote-table tbody td { padding: 16px 28px; border-bottom: 1px solid var(--line-soft); font-size: 14px; vertical-align: middle; }
.quote-table tbody tr:last-child td { border-bottom: none; }
.quote-table .q-label { font-weight: 500; color: var(--ink); }
.quote-table .q-detail { color: var(--faint); font-size: 12px; margin-top: 2px; }
.quote-table .q-price { font-family: var(--font-mono); font-weight: 500; color: var(--gold-2); }

.quote-totals { background: var(--paper-2); border-top: 1px solid var(--line); padding: 22px 28px; }
.quote-totals-row { display: flex; justify-content: flex-end; gap: 20px; align-items: center; padding: 6px 0; font-size: 14px; color: var(--muted); }
.quote-totals-row .label { width: 150px; text-align: right; }
.quote-totals-row .value { width: 120px; text-align: right; font-weight: 500; color: var(--ink); font-family: var(--font-mono); }
.quote-totals-row.grand { margin-top: 8px; padding-top: 14px; border-top: 1px solid var(--line); }
.quote-totals-row.grand .label { font-family: var(--font-serif); font-size: 17px; font-weight: 500; color: var(--gold-2); }
.quote-totals-row.grand .value { font-family: var(--font-serif); font-size: 24px; font-weight: 500; color: var(--gold-2); }

/* Étude de marché */
.competition { margin-top: 22px; background: var(--card); border: 1px solid var(--gold-line); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
.competition h3 { font-family: var(--font-serif); font-size: 16px; font-weight: 500; color: var(--gold-2); padding: 18px 28px; border-bottom: 1px solid var(--line); background: var(--paper-2); }
.comp-table { width: 100%; border-collapse: collapse; }
.comp-table th { text-align: left; padding: 12px 28px; font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--line-soft); }
.comp-table th.num, .comp-table td.num { text-align: right; }
.comp-table td { padding: 12px 28px; border-bottom: 1px solid var(--line-soft); font-size: 13px; color: var(--muted); }
.comp-table tr:last-child td { border-bottom: none; }
.comp-table .c-label { color: var(--ink); font-weight: 500; }
.comp-table td.num { font-family: var(--font-mono); }
.comp-note { padding: 13px 28px; font-size: 12px; color: var(--faint); border-top: 1px solid var(--line-soft); }

/* ============ LANDING ============ */
.hero {
  display: grid; grid-template-columns: 1fr 0.92fr; gap: 48px; align-items: center;
  padding: 38px 0 54px; position: relative;
}
@media (max-width: 900px) { .hero { grid-template-columns: 1fr; gap: 44px; padding: 24px 0 48px; } }
.hero-copy { text-align: left; }
.hero .eyebrow {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: 26px;
  font-size: 12px; letter-spacing: 3px; text-transform: uppercase; color: var(--gold-2); font-weight: 500;
  background: var(--gold-bg); border: 1px solid var(--gold-line); padding: 9px 20px; border-radius: 40px;
}
.hero .eyebrow::before, .hero .eyebrow::after { content: ""; width: 18px; height: 1px; background: var(--gold); }
.hero h1 {
  font-family: var(--font-serif); font-size: 56px; font-weight: 500; line-height: 1.06;
  letter-spacing: -.03em; color: var(--ink); text-wrap: balance;
}
@media (max-width: 600px) { .hero h1 { font-size: 34px; letter-spacing: -.025em; } }
@media (min-width: 601px) and (max-width: 900px) { .hero h1 { font-size: 44px; } }
.hero h1 .accent, .page-head h1 .accent {
  background: linear-gradient(120deg, #c9a457, #8a6a2a, #b08a3e);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  font-style: italic; font-weight: 500;
}
.hero p { color: var(--ink-2); margin: 26px 0 0; font-size: 20px; max-width: 560px; line-height: 1.65; }
.cta-row { display: flex; gap: 14px; margin-top: 26px; flex-wrap: wrap; align-items: center; }
.cta-row .btn { max-width: 100%; }
.hero .cta-row { display: flex; gap: 14px; margin-top: 34px; flex-wrap: wrap; align-items: center; }
.hero .cta-row .btn.big { padding: 15px 32px; font-size: 15.5px; }  /* legerement reduit (demande utilisateur) */
.hero .trust { display: flex; gap: 24px; margin-top: 28px; flex-wrap: wrap; }
.hero .trust span { font-size: 14px; color: var(--ink-2); display: flex; align-items: center; gap: 8px; font-weight: 500; }
.hero .trust .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 10px rgba(176,138,62,.5); }

/* ============ COUCHE 3D : PLAN D'ATELIER + PROFONDEUR ============
   Le hero pose une perspective d'atelier : plan technique au sol (canvas
   #atelier3d) + mockup du builder incliné qui réagit au pointeur.
   Tout est décoratif (aria-hidden) et coupé si prefers-reduced-motion. */
.hero-3d {
  position: absolute; inset: -10px -20px; z-index: 0;
  pointer-events: none; overflow: hidden; border-radius: 16px;
}
.hero-3d canvas { display: block; width: 100%; height: 100%; }
.hero-copy { position: relative; z-index: 2; }
.hero-mock {
  position: relative; z-index: 1;
  transform-style: preserve-3d; will-change: transform;
}
.mock-glow {
  position: absolute; inset: -16% -12%; z-index: 0; pointer-events: none;
  background: radial-gradient(closest-side, rgba(176,138,62,.20), transparent 72%);
  filter: blur(20px); animation: mockGlow 7s ease-in-out infinite;
}
@keyframes mockGlow {
  0%, 100% { opacity: .5; transform: scale(1); }
  50%      { opacity: .9; transform: scale(1.06); }
}
.mock-window { transform-style: preserve-3d; backface-visibility: hidden; }
/* Reflet qui balaie l'écran du mockup */
.mock-window::after {
  content: ""; position: absolute; top: -60%; left: -30%; width: 45%; height: 220%;
  z-index: 3; pointer-events: none; rotate: 18deg;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.28), transparent);
  animation: mockSheen 8s ease-in-out infinite;
}
@keyframes mockSheen {
  0%, 60% { transform: translateX(-160%); }
  88%, 100% { transform: translateX(360%); }
}
/* Repos incliné (JS absent / reduced-motion) — desktop uniquement */
@media (min-width: 901px) {
  .hero-mock.mock-static .mock-window {
    transform: perspective(1500px) rotateY(-13deg) rotateX(7deg);
  }
}
/* Halo 3D sous le hero : la scène flotte au-dessus du papier */
.hero h1 { text-shadow: 0 1px 0 rgba(255,255,255,.55), 0 18px 44px rgba(25,23,19,.10); }

/* Badges différenciateurs : alignés, même hauteur, même style */
.hero-badges { display: flex; flex-direction: column; gap: 10px; margin-top: 24px; }
.hero-badge {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 9px 16px; width: fit-content;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 999px; font-size: 13px; font-weight: 500; color: var(--ink);
}
.hero-badge svg { flex-shrink: 0; color: var(--gold-2); }
.hero-badge span { line-height: 1.4; }

/* Mockup du builder (aperçu produit) */
.hero-mock { position: relative; }
.hero-mock::before {
  content: ""; position: absolute; inset: -40px -30px; z-index: 0; pointer-events: none;
  background: radial-gradient(520px 360px at 50% 38%, rgba(176,138,62,.18), transparent 70%);
}
.mock-window {
  position: relative; z-index: 1;
  background: var(--card); border: 1px solid var(--gold-line); border-radius: 12px;
  box-shadow: 0 24px 60px rgba(25,23,19,.18), 0 8px 24px rgba(176,138,62,.18);
  overflow: hidden;
}
.mock-window::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; z-index: 2;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.mock-bar {
  display: flex; align-items: center; gap: 6px; padding: 13px 16px;
  background: var(--paper-2); border-bottom: 1px solid var(--line);
}
.mock-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); }
.mock-dot:first-child { background: var(--gold-soft); }
.mock-title { margin-left: 10px; font-size: 12px; color: var(--faint); letter-spacing: 1px; }
.mock-body { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 0; }
.mock-col { padding: 24px; }
.mock-field { margin-bottom: 18px; }
.mock-label { display: block; font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--faint); font-weight: 500; margin-bottom: 6px; }
.mock-select { padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius); font-size: 14px; color: var(--ink); background: var(--card); }
.mock-line { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; color: var(--ink-2); }
.mock-line .mock-price { font-family: var(--font-mono); color: var(--gold-2); font-weight: 500; }
.mock-summary { padding: 24px; background: var(--paper-2); border-left: 1px solid var(--line); }
.mock-sum-title { font-family: var(--font-serif); font-size: 16px; font-weight: 500; color: var(--gold-2); margin-bottom: 16px; }
.mock-total { display: flex; justify-content: space-between; padding: 7px 0; font-size: 13px; color: var(--muted); }
.mock-total span:last-child { font-family: var(--font-mono); color: var(--ink); font-weight: 500; }
.mock-total.mock-grand { border-top: 1px solid var(--line); margin-top: 10px; padding-top: 14px; }
.mock-total.mock-grand span { font-family: var(--font-serif); font-size: 20px; font-weight: 500; color: var(--gold-2); }
.mock-btn { margin-top: 20px; padding: 13px; text-align: center; border-radius: var(--radius); color: #fff; font-size: 14px; font-weight: 500; background: linear-gradient(165deg, #c19a4e, #b08a3e 50%, #8a6a2a); box-shadow: 0 3px 8px rgba(176,138,62,.3), inset 0 1px 0 rgba(255,255,255,.28); }

/* Sections */
.section { padding: 8px 0 20px; }
.section-head { text-align: center; margin-bottom: 22px; }
.section-head .eyebrow { justify-content: center; margin-bottom: 12px; }
.section-head .eyebrow::after { content: ""; width: 30px; height: 1px; background: var(--gold); }
.section-head h2 { font-family: var(--font-serif); font-size: 38px; font-weight: 500; letter-spacing: -.02em; color: var(--ink); }
.section-head p { color: var(--muted); margin-top: 14px; max-width: 560px; margin-inline: auto; font-size: 15px; }
.section-head .measure { max-width: 420px; margin: 18px auto 0; }

/* Étapes */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; max-width: 980px; margin: 0 auto; }
@media (max-width: 800px) { .steps { grid-template-columns: 1fr; } }
.step { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 32px 28px; box-shadow: var(--shadow-sm); position: relative; text-align: left; transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease; }
.step::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(320px 160px at var(--mx,50%) -20%, rgba(176,138,62,.14), transparent 60%); opacity: 0; transition: opacity .3s ease;
}
.step:hover { transform: translateY(-4px); border-color: var(--gold-line); box-shadow: 0 8px 24px rgba(25,23,19,.07), 0 20px 50px rgba(176,138,62,.12), inset 0 1px 0 rgba(255,255,255,.5); }
.step:hover::after { opacity: 1; }
.step .step-num {
  position: absolute; top: 20px; right: 22px;
  font-family: var(--font-mono); font-size: 15px; font-weight: 500; color: var(--accent); letter-spacing: 1px;
}
.step .step-icon {
  width: 48px; height: 48px; border-radius: var(--radius); margin-bottom: 18px;
  display: grid; place-items: center; color: var(--gold-2);
  background: linear-gradient(160deg, var(--gold-soft), var(--gold-bg));
  border: 1px solid var(--gold-line);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6);
}
.step h3 { font-family: var(--font-serif); font-size: 18px; font-weight: 500; margin-bottom: 8px; color: var(--ink); }
.step p { color: var(--muted); font-size: 14px; line-height: 1.7; }

/* Ligne discrète vers l'offre Visibilité Pro (site web + SEO, 199 €/mois) */
.hero-alt { color: var(--muted); font-size: 14px; margin-top: 16px; }
.hero-alt a { color: var(--accent); font-weight: 500; text-decoration: none; border-bottom: 1px solid var(--gold-line); }
.hero-alt a:hover { border-color: var(--accent); }

/* CTA alternatif discret (2e action hero sans bouton plein) */
.cta-alt {
  color: var(--accent); font-weight: 500; font-size: 15px; text-decoration: none;
  border-bottom: 1px solid var(--gold-line); padding-bottom: 2px; transition: border-color .15s, color .15s;
}
.cta-alt:hover { border-color: var(--accent); color: var(--accent-strong); }

/* FAQ accordéon (landing) — replié par défaut, allège fortement la page.
   Distinct de .faq-item (utilisé tel quel par les pages SEO métiers). */
.faq-acc-wrap { max-width: 780px; margin: 0 auto; }
.faq-acc {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg);
  margin-bottom: 12px; box-shadow: var(--shadow-sm); overflow: hidden;
  transition: border-color .2s ease;
}
.faq-acc:hover { border-color: var(--gold-line); }
.faq-acc summary {
  cursor: pointer; list-style: none; padding: 19px 24px;
  font-family: var(--font-serif); font-size: 17px; font-weight: 500; color: var(--ink);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.faq-acc summary::-webkit-details-marker { display: none; }
.faq-acc summary:hover { color: var(--accent); }
.faq-plus { position: relative; width: 14px; height: 14px; flex-shrink: 0; }
.faq-plus::before, .faq-plus::after {
  content: ""; position: absolute; background: var(--accent); border-radius: 2px; transition: transform .22s ease;
}
.faq-plus::before { top: 6.2px; left: 0; width: 14px; height: 1.6px; }
.faq-plus::after { left: 6.2px; top: 0; width: 1.6px; height: 14px; }
.faq-acc[open] .faq-plus::after { transform: scaleY(0); }
.faq-acc[open] summary { color: var(--accent); }
.faq-acc-body { padding: 0 24px 20px; }
.faq-acc-body p { color: var(--muted); font-size: 14px; line-height: 1.75; }

/* CTA final */
.cta-final {
  position: relative; overflow: hidden;
  background: linear-gradient(160deg, #f6f1e6, #efe8d6);
  border: 1px solid var(--gold-line); border-radius: var(--radius-lg);
  padding: 64px 36px; text-align: center; box-shadow: var(--shadow-md); margin-bottom: 70px;
}
.cta-final::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(700px 300px at 50% -20%, rgba(176,138,62,.18), transparent 70%);
}
.cta-final::after {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.cta-final .eyebrow { justify-content: center; margin-bottom: 14px; }
.cta-final h2 { font-family: var(--font-serif); font-size: 38px; font-weight: 500; color: var(--ink); position: relative; letter-spacing: -.02em; }
.cta-final p { color: var(--muted); margin: 16px auto 30px; max-width: 480px; position: relative; font-size: 15px; }
.cta-final .btn { position: relative; margin-inline: auto; display: inline-flex; }
.cta-final .free { font-size: 13px; color: var(--faint); margin-top: 18px; position: relative; }

/* Témoignage */
.testimonials { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; }
.testimonial {
  max-width: 680px; margin: 0 auto; text-align: center;
  padding: 30px 28px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.testimonials .testimonial { max-width: none; }
.t-stars { display: flex; justify-content: center; gap: 2px; margin-bottom: 14px; }
.t-quote { margin-bottom: 18px; }
.t-text {
  font-family: var(--font-serif); font-size: 17px; line-height: 1.6;
  color: var(--ink); font-weight: 500; margin-bottom: 20px;
}
.t-author { display: flex; align-items: center; justify-content: center; gap: 12px; }
.t-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; font-weight: 500; font-size: 16px; color: #fff;
  background: linear-gradient(160deg, #d8b97c, #a9863f);
}
.t-name { font-weight: 500; font-size: 14px; color: var(--ink); }
.t-role { font-size: 12px; color: var(--faint); }

/* Bandeau de rassurance */
.trust-bar {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 28px;
  margin: 0 0 8px; padding: 18px 0;
}
.trust-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.trust-item svg { color: var(--gold-2); flex-shrink: 0; }

/* Bandeau de confiance pricing */
.pricing-trust {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 28px;
  margin-top: 28px; padding: 18px 0; border-top: 1px solid var(--line-soft);
}
.pt-item { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.pt-item svg { color: var(--gold-2); flex-shrink: 0; }

/* Barre de partage du devis */
.share-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.share-label { font-size: 12px; color: var(--faint); margin-right: 4px; }
.share-btn {
  width: 34px; height: 34px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--card);
  color: var(--muted); display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; transition: all .15s;
}
.share-btn:hover { border-color: var(--gold); color: var(--gold-2); }

/* Blog */
.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; margin-top: 24px; }
.blog-card {
  display: block; padding: 24px; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  text-decoration: none; color: var(--ink); transition: all .15s;
}
.blog-card:hover { border-color: var(--gold); box-shadow: var(--shadow-md); }
.blog-card h2, .blog-card h3 { font-family: var(--font-serif); font-size: 18px; font-weight: 500; margin: 8px 0; color: var(--ink); }
.blog-card p { color: var(--muted); font-size: 13px; line-height: 1.6; }
.blog-cat { display: inline-block; font-size: 12.5px; font-weight: 500; color: var(--accent); text-transform: uppercase; letter-spacing: .05em; }
.blog-meta { font-size: 12px; color: var(--faint); margin-top: 12px; }
.blog-article { max-width: 720px; margin: 0 auto; }
.blog-article h1 { font-family: var(--font-serif); font-size: 34px; font-weight: 500; margin: 12px 0; line-height: 1.2; }
.blog-article h2 { font-family: var(--font-serif); font-size: 24px; font-weight: 500; margin: 28px 0 12px; }
.blog-article p { color: var(--muted); font-size: 15px; line-height: 1.8; }
.blog-intro { font-size: 17px !important; color: var(--ink) !important; }
.blog-cta { background: linear-gradient(160deg, #f6f1e6, #efe8d6); border: 1px solid var(--gold-line); border-radius: var(--radius-lg); padding: 28px; text-align: center; margin: 32px 0; }
.blog-cta h3 { font-family: var(--font-serif); font-size: 22px; font-weight: 500; margin-bottom: 8px; }
.blog-cta p { color: var(--muted); font-size: 14px; margin-bottom: 16px; }
.blog-faq { margin-top: 32px; }
.blog-related { margin-top: 40px; }

/* Footer — 4 colonnes équilibrées (refonte 2026-09).
   Avant : 5 colonnes auto-fit -> mur vertical de ~1280px sur mobile.
   Désormais : grille explicite desktop, 2 colonnes sur mobile. */
.footer { border-top: 1px solid var(--line); padding: 40px 0 26px; }
.footer-grid {
  display: grid; gap: 34px;
  grid-template-columns: 1.5fr 1fr 1.15fr 0.85fr;
}
.footer h4 { font-family: var(--font-serif); font-size: 14px; font-weight: 500; margin-bottom: 14px; color: var(--accent); }
.footer a { display: block; color: var(--muted); text-decoration: none; font-size: 13px; padding: 4px 0; transition: color .15s; }
.footer a:hover { color: var(--accent); }
.footer-tagline { color: var(--faint); font-size: 13px; line-height: 1.7; max-width: 260px; }
.footer-mail { margin-top: 10px; color: var(--accent); font-weight: 500; }
.footer .bottom { margin-top: 34px; padding-top: 20px; border-top: 1px solid var(--line-soft); text-align: center; color: var(--faint); font-size: 13px; }
@media (max-width: 860px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 28px 24px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-tagline { max-width: 420px; }
}
@media (max-width: 420px) {
  .footer a { padding: 5px 0; }
}

/* ============ DASHBOARD ============ */
.plan-badge {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 12px;
  padding: 9px 18px; border-radius: 40px; font-size: 13px; color: var(--muted);
  background: var(--card); border: 1px solid var(--line);
}
.plan-badge b { color: var(--gold-2); font-weight: 500; }
.plan-badge a { color: var(--gold-2); font-weight: 500; text-decoration: none; }
.plan-badge.pro { background: var(--gold-bg); border-color: var(--gold-line); color: var(--gold-2); }
.plan-badge.free { color: var(--muted); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 28px; }
.stat-card {
  background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 24px; box-shadow: var(--shadow-sm);
  position: relative; overflow: hidden;
}
.stat-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold-line), transparent);
}
.stat-card .label { font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase; color: var(--faint); font-weight: 500; }
.stat-card .value { font-family: var(--font-serif); font-size: 32px; font-weight: 500; color: var(--gold-2); margin-top: 8px; }
.stat-card .value.plain { color: var(--ink); }

.empty { text-align: center; padding: 48px 20px; color: var(--faint); }
.empty .big { font-size: 36px; margin-bottom: 16px; color: var(--accent); }
.empty p { margin-bottom: 20px; }

/* Table devis */
.quote-table { width: 100%; border-collapse: collapse; }
.quote-table th {
  text-align: left; font-size: 12px; letter-spacing: 1.5px; text-transform: uppercase;
  color: var(--muted); font-weight: 500; padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.quote-table td { padding: 14px 14px; border-bottom: 1px solid var(--line-soft); font-size: 14px; vertical-align: middle; }
.quote-table tbody tr { transition: background .12s; }
.quote-table tbody tr:hover td { background: var(--card-2); }
.quote-table .client { font-weight: 500; color: var(--ink); }
.quote-table .muted { color: var(--muted); }
.quote-table .amount { font-family: var(--font-mono); font-weight: 500; color: var(--gold-2); }
.quote-table .actions { display: flex; gap: 6px; justify-content: flex-end; }

/* Table leads admin */
.lead-table-wrap { overflow-x: auto; }
.lead-table th:first-child, .lead-table td:first-child { white-space: nowrap; }
.lead-row-new td { background: var(--gold-bg); }
.lead-phone { font-size: 12px; color: var(--faint); }
.lead-msg { max-width: 240px; }
.lead-status-form { margin: 0; }
.lead-status-select { width: auto; padding: 7px 11px; font-size: 13px; border-radius: var(--radius); }

.icon-btn {
  width: 36px; height: 36px; border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--card); color: var(--muted); cursor: pointer;
  text-decoration: none; display: inline-flex; align-items: center; justify-content: center;
  transition: all .15s;
}
.icon-btn:hover { border-color: var(--gold); color: var(--gold-2); }
.icon-btn.danger:hover { border-color: var(--danger); color: var(--danger); }

/* Bouton danger (suppression) */
.btn.danger {
  background: transparent; color: var(--danger);
  border: 1px solid var(--danger);
}
.btn.danger:hover { background: var(--danger); color: #fff; }

/* Filtres du dashboard */
.dash-filters { display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; }
.dash-search {
  flex: 1; min-width: 200px; max-width: 340px;
  padding: 10px 15px; border-radius: var(--radius); font-size: 13px;
  background: var(--card); border: 1px solid var(--line); color: var(--ink); outline: none;
}
.dash-search:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(176,138,62,.12); }
.dash-status {
  width: auto; padding: 10px 15px; border-radius: var(--radius); font-size: 13px;
  background: var(--card); border: 1px solid var(--line); color: var(--ink); cursor: pointer;
}
.q-status { width: auto; padding: 6px 9px; font-size: 12px; border-radius: var(--radius); background: var(--card); border: 1px solid var(--line); color: var(--ink); cursor: pointer; }
.q-status:focus { border-color: var(--gold); }

/* ============ PRICING ============ */
.faq-item { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 24px 28px; margin-bottom: 16px; box-shadow: var(--shadow-sm); transition: border-color .25s ease, transform .25s ease, box-shadow .25s ease; }
.faq-item:hover { border-color: var(--gold-line); box-shadow: 0 8px 24px rgba(25,23,19,.06), 0 16px 40px rgba(176,138,62,.1), inset 0 1px 0 rgba(255,255,255,.5); }
.faq-item h3 { font-family: var(--font-serif); font-size: 18px; font-weight: 500; color: var(--ink); margin-bottom: 8px; }
.faq-item p { color: var(--muted); font-size: 14px; line-height: 1.75; }
.why-block { background: var(--card); border: 1px solid var(--gold-line); border-radius: var(--radius-lg); padding: 32px 36px; max-width: 780px; margin: 0 auto; box-shadow: var(--shadow-sm); }
.why-block p { color: var(--muted); font-size: 15px; line-height: 1.85; }
.other-trades { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; max-width: 920px; margin: 0 auto; }

/* ── « Voir plus » : les 150-268 liens de maillage étaient rendus en puces
   plates → mur de liens illisible (mesuré : 268 liens sur /prix/<metier>,
   12 361 px de haut). Repliés dans un dépliant discret.
   ⚠️ Les liens RESTENT dans le DOM (donc crawlables) : on ne referme que
   VISUELLEMENT. Le SEO de maillage est préservé intégralement. */
.more-links { max-width: 920px; margin: 18px auto 0; text-align: center; }
.more-links > summary {
  display: inline-block; cursor: pointer; list-style: none;
  padding: 9px 18px; border: 1px solid var(--gold-line); border-radius: 999px;
  color: var(--accent); font-size: 13.5px; letter-spacing: .01em;
  transition: background .15s, border-color .15s;
}
.more-links > summary::-webkit-details-marker { display: none; }
.more-links > summary::after { content: " +"; color: var(--faint); }
.more-links[open] > summary::after { content: " –"; }
.more-links > summary:hover { background: rgba(176,138,62,.07); border-color: var(--accent); }
.more-links[open] > summary { margin-bottom: 16px; }
.more-links .other-trades { margin-top: 0; }

/* Index des départements (/prix-par-departement) : 101 entrées alignées en
   colonnes. Ce n'est PAS un nuage de puces — c'est une table de matières. */
.dept-index { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; max-width: 920px; margin: 0 auto; }
.dept-index li { background: var(--card); }
.dept-index a { display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  padding: 11px 16px; color: var(--muted); font-size: 14px; text-decoration: none; transition: background .15s, color .15s; }
.dept-index a:hover { background: rgba(176,138,62,.07); color: var(--ink); }
.dept-index .dept-code { color: var(--faint); font-size: 12px; font-variant-numeric: tabular-nums; }

/* Tableau long (160 lignes) rendu défilant : la page cesse d'être un mur, mais
   chaque ligne reste présente dans le DOM. Barre de défilement thémée depuis la
   palette (un défaut du navigateur n'appartient à aucun système). */
.table-scroll { border: 1px solid var(--line); border-radius: var(--radius-lg); }
.table-scroll .quote-table { margin: 0; }
.table-scroll::-webkit-scrollbar { width: 10px; }
.table-scroll::-webkit-scrollbar-track { background: transparent; }
.table-scroll::-webkit-scrollbar-thumb { background: var(--gold-line); border-radius: 999px; border: 3px solid var(--card); }
.table-scroll::-webkit-scrollbar-thumb:hover { background: var(--accent); }

/* Grille de métiers vedettes (landing) */
.trade-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; max-width: 920px; margin: 0 auto; }
@media (max-width: 900px) { .trade-grid { grid-template-columns: repeat(2, 1fr); } }
.trade-card {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 16px 18px; text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow-sm); transition: border-color .15s, transform .15s, box-shadow .15s;
}
.trade-card:hover { border-color: var(--gold-line); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.trade-card .trade-icon {
  width: 40px; height: 40px; border-radius: var(--radius); flex-shrink: 0;
  display: grid; place-items: center; color: var(--gold-2);
  background: var(--gold-bg); border: 1px solid var(--gold-line);
}
.trade-card .trade-name { font-size: 14px; font-weight: 500; flex: 1; }
.trade-card .trade-arrow { color: var(--faint); transition: color .15s, transform .15s; }
.trade-card:hover .trade-arrow { color: var(--gold-2); transform: translateX(2px); }
.trade-all { text-align: center; margin-top: 22px; }
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 24px; align-items: stretch; }
.plan {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 36px;
  box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; position: relative; overflow: hidden;
  transition: transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s ease, border-color .3s ease;
}
.plan::before, .plan::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; }
.plan::before { padding: 1px; background: linear-gradient(135deg, rgba(176,138,62,.35), rgba(230,223,208,.1) 40%, rgba(176,138,62,.18)); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.plan:hover { transform: translateY(-5px); box-shadow: 0 12px 34px rgba(25,23,19,.08), 0 24px 60px rgba(176,138,62,.14), 0 1px 0 rgba(255,255,255,.6) inset; border-color: rgba(176,138,62,.4); }
.plan.featured {
  border-color: rgba(176,138,62,.45);
  box-shadow: 0 8px 26px rgba(176,138,62,.14), 0 26px 64px rgba(176,138,62,.16), 0 1px 0 rgba(255,255,255,.6) inset;
}
.plan.featured::before { background: linear-gradient(135deg, rgba(193,154,78,.55), rgba(230,223,208,.15) 45%, rgba(176,138,62,.3)); }
.plan.featured::after {
  content: ""; position: absolute; top: -40%; left: -20%; width: 60%; height: 120%; rotate: 25deg;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.35), transparent);
  animation: planSheen 4.5s ease-in-out infinite;
}
@keyframes planSheen { 0%, 55% { transform: translateX(-120%); } 85%, 100% { transform: translateX(320%); } }
.plan.featured .tag {
  display: inline-block; align-self: flex-start;
  background: linear-gradient(160deg, #c19a4e, #b08a3e); color: #fff;
  font-size: 12px; font-weight: 500; letter-spacing: 1.5px; text-transform: uppercase;
  padding: 6px 16px; border-radius: 40px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(176,138,62,.3);
}
.plan .name { font-family: var(--font-serif); font-size: 22px; font-weight: 500; color: var(--ink); }
.plan .price { font-family: var(--font-serif); font-size: 50px; font-weight: 500; color: var(--gold-2); margin: 14px 0 4px; }
.plan .price small { font-size: 14px; color: var(--faint); font-weight: 500; }
.plan .desc { color: var(--muted); font-size: 13px; margin-bottom: 22px; }
.plan ul { list-style: none; margin-bottom: 24px; flex: 1; }
.plan li { padding: 9px 0; font-size: 14px; display: flex; align-items: center; gap: 10px; color: var(--ink); }
.plan li .check, .plan li .x {
  position: relative; width: 16px; height: 16px; flex-shrink: 0;
  display: inline-block;
}
/* Coche dessinée en CSS (aucun emoji/caractère dans le HTML) */
.plan li .check::before {
  content: ""; position: absolute; left: 3px; top: 6px;
  width: 9px; height: 5px; border-left: 1.8px solid var(--accent);
  border-bottom: 1.8px solid var(--accent); transform: rotate(-45deg);
}
/* Croix dessinée en CSS */
.plan li .x::before, .plan li .x::after {
  content: ""; position: absolute; left: 2px; top: 7px; width: 12px; height: 1.6px;
  background: var(--faint); border-radius: 2px;
}
.plan li .x::before { transform: rotate(45deg); }
.plan li .x::after { transform: rotate(-45deg); }
.plan li.muted { color: var(--faint); }

/* Cellules du comparatif : Oui / Non sans caractère texte */
.quote-table td.yes, .quote-table td.no { position: relative; }
.quote-table td.yes::before {
  content: ""; display: inline-block; width: 9px; height: 5px; margin: 0 6px 2px 0;
  border-left: 1.8px solid var(--accent); border-bottom: 1.8px solid var(--accent);
  transform: rotate(-45deg);
}
.quote-table td.no::before {
  content: ""; display: inline-block; width: 11px; height: 1.6px; margin-bottom: 3px;
  background: var(--faint); border-radius: 2px; transform: rotate(45deg);
}

/* Carte d'offre seule : largeur maîtrisée (évite le grand vide à droite) */
.plans.one { grid-template-columns: minmax(0, 560px); justify-content: center; }
/* Grille à deux offres (Gratuit + Pro) : deux colonnes centrées */
.plans.two { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 760px; margin: 0 auto; }
@media (max-width: 700px) { .plans.two { grid-template-columns: 1fr; } }

.note { text-align: center; color: var(--faint); font-size: 13px; margin-top: 32px; }

/* ============ AUTH ============ */
.auth-body {
  display: flex; flex-direction: column; align-items: center;
  justify-content: flex-start; min-height: 100vh; padding: 0;
  background:
    radial-gradient(1000px 600px at 50% -10%, rgba(176,138,62,.08), transparent 60%),
    radial-gradient(600px 400px at 90% 100%, rgba(176,138,62,.05), transparent 55%),
    var(--paper);
}
.auth-body .topbar { width: 100%; }
.auth-body .auth-card { margin: auto; }
.auth-card {
  background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md); padding: 40px; width: 100%; max-width: 440px;
  position: relative; overflow: hidden;
}
/* Variante élargie : page de création de compte (plus de champs) */
.auth-card.wide { max-width: 520px; padding: 40px; }
.auth-card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.auth-card::after {
  content: ""; position: absolute; bottom: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold-line), transparent);
}
.auth-card .card-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 28px; }
.auth-card .brand { margin-bottom: 0; }
.auth-card h1 { font-family: var(--font-serif); font-size: 30px; font-weight: 500; margin-bottom: 6px; color: var(--ink); letter-spacing: -.01em; }
.auth-card .sub { color: var(--muted); font-size: 14px; margin-bottom: 24px; }
.auth-card .btn { width: 100%; margin-top: 24px; }
.auth-card .btn.big { padding: 15px 20px; font-size: 15px; }
.alt { text-align: center; margin-top: 22px; font-size: 13px; color: var(--muted); }
.alt a { color: var(--gold-2); font-weight: 500; text-decoration: none; }
.alt a:hover { text-decoration: underline; }
.back { display: inline-block; margin-top: 18px; font-size: 13px; color: var(--faint); text-decoration: none; }
.back:hover { color: var(--gold-2); }

/* Sections de formulaire (auth) : diviseur or + label — signature "atelier" */
.form-section {
  display: flex; align-items: center; gap: 12px;
  margin: 24px 0 4px; padding-top: 4px;
  font-size: 12px; letter-spacing: 2px; text-transform: uppercase;
  color: var(--accent); font-weight: 500;
}
.form-section:first-of-type { margin-top: 0; }
.form-section::before, .form-section::after {
  content: ""; height: 1px; flex: 0 0 22px; background: var(--gold);
}
.form-section::after { flex: 1; background: repeating-linear-gradient(90deg, var(--gold) 0 2px, transparent 2px 6px); opacity: .5; }

.form-row { display: flex; gap: 12px; }
.form-row > * { flex: 1; }
.form-row .f2 { flex: 2; }

/* Champ mot de passe avec œil */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 46px; }
.pw-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; border: none; background: transparent; cursor: pointer;
  display: grid; place-items: center; color: var(--faint); border-radius: var(--radius);
  transition: color .15s, background .15s;
}
.pw-toggle:hover { color: var(--gold-2); background: var(--card-2); }
.pw-toggle svg { display: block; }

/* ============ ACCOUNT / PROFILE ============ */
.info-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.info-row:last-child { border-bottom: none; }
.info-row .label { color: var(--muted); font-size: 14px; }
.info-row .value { font-weight: 500; font-size: 14px; color: var(--ink); }
.hint { font-size: 12px; color: var(--faint); margin-top: 8px; }
.hint code { background: var(--paper-2); padding: 2px 6px; border-radius: 4px; color: var(--gold-2); }

/* ============ FLASH ============ */
.flash { padding: 14px 18px; border-radius: var(--radius); font-size: 13px; margin-bottom: 20px; border: 1px solid; }
.flash.error { background: rgba(178,58,46,.06); border-color: rgba(178,58,46,.25); color: var(--danger); }
.flash.success { background: rgba(61,122,74,.06); border-color: rgba(61,122,74,.25); color: var(--ok); }

/* ============ FOOTER inline (app pages) ============ */
.footer-inline { text-align: center; color: var(--faint); font-size: 12px; margin-top: 48px; padding-top: 22px; border-top: 1px solid var(--line-soft); }

/* ============ LEADS / SITE WEB ============ */
.lead-hero { text-align: center; padding: 44px 0 44px; }
.lead-hero h1 { font-family: var(--font-serif); font-size: 46px; font-weight: 500; line-height: 1.06; color: var(--ink); letter-spacing: -.02em; }
.lead-hero h1 .accent {
  background: linear-gradient(120deg, #c19a4e, #8a6a2a, #b08a3e);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  font-style: italic; font-weight: 500;
}
.lead-hero p { color: var(--muted); margin: 20px auto 0; font-size: 16px; max-width: 560px; }

.lead-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: start; max-width: 980px; margin: 0 auto; }
@media (max-width: 820px) { .lead-layout { grid-template-columns: 1fr; } }

.lead-benefits h3, .lead-form-wrap h3 { font-family: var(--font-serif); font-size: 24px; font-weight: 500; margin-bottom: 24px; color: var(--ink); }
.lead-benefit { display: flex; gap: 15px; margin-bottom: 22px; }
.lead-benefit .lb-icon {
  width: 42px; height: 42px; border-radius: var(--radius); flex-shrink: 0;
  display: grid; place-items: center; color: var(--gold-2);
  background: var(--gold-bg); border: 1px solid var(--gold-line);
}
.lead-benefit strong { font-size: 14px; color: var(--ink); display: block; margin-bottom: 3px; }
.lead-benefit p { color: var(--muted); font-size: 13px; line-height: 1.65; }
.lead-note {
  display: flex; align-items: center; gap: 8px; margin-top: 26px;
  padding: 13px 17px; border-radius: var(--radius); color: var(--gold-2);
  background: var(--gold-bg); border: 1px solid var(--gold-line); font-size: 13px;
}

.lead-form-wrap { background: var(--card); border: 1px solid var(--gold-line); border-radius: var(--radius-lg); padding: 32px; box-shadow: var(--shadow-md); }
.lead-form-wrap h3 { margin-bottom: 10px; }
.lead-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .lead-row { grid-template-columns: 1fr; } }
.lead-privacy { text-align: center; color: var(--faint); font-size: 12px; margin-top: 14px; }
/* Case de consentement RGPD (opt-in explicite) */
.consent-box { margin-top: 16px; display: flex; align-items: flex-start; gap: 10px; }
.consent-box input[type="checkbox"] { width: 18px; height: 18px; margin-top: 2px; accent-color: var(--gold-2); flex-shrink: 0; }
.consent-box label.consent-label { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: 0; font-weight: 400; }
.consent-box label.consent-label a { color: var(--gold-2); text-decoration: underline; }

.lead-success { text-align: center; max-width: 540px; margin: 30px auto; padding: 54px 32px; background: var(--card); border: 1px solid var(--gold-line); border-radius: var(--radius-lg); box-shadow: var(--shadow-md); }
.lead-success-icon { width: 68px; height: 68px; border-radius: 50%; margin: 0 auto 22px; display: grid; place-items: center; color: #fff; background: linear-gradient(160deg, #c19a4e, #8a6a2a); }
.lead-success h2 { font-family: var(--font-serif); font-size: 28px; font-weight: 500; margin-bottom: 12px; color: var(--ink); }
.lead-success p { color: var(--muted); margin-bottom: 26px; }

/* ============ LEGAL / CGV ============ */
.legal-card h1 { font-family: var(--font-serif); font-size: 30px; font-weight: 500; margin-bottom: 6px; color: var(--ink); }
.legal-card .updated { color: var(--faint); font-size: 13px; margin-bottom: 24px; }
.legal-card h2 { font-family: var(--font-serif); font-size: 18px; font-weight: 500; margin: 26px 0 10px; color: var(--gold-2); }
.legal-card p, .legal-card li { color: var(--muted); font-size: 14px; line-height: 1.8; }
.legal-card ul { padding-left: 20px; margin: 8px 0; }
.legal-card strong { color: var(--ink); }

/* ============ RÉVÉLATION AU SCROLL ============ */
/* Toujours visible. L'animation est un simple léger translateY qui ne masque
   JAMAIS le contenu (pas d'opacity:0) — robuste même si JS échoue. */
.reveal { opacity: 1; }
/* Révélation en profondeur : on n'anime QUE le transform (jamais l'opacité),
   donc le contenu reste lisible même si le JS ou l'observer échoue. */
.js-anim .reveal {
  transform: perspective(1200px) translateY(26px) rotateX(7deg);
  transform-origin: 50% 100%;
  transition: transform .85s cubic-bezier(.22,.61,.36,1);
}
.js-anim .reveal.visible { transform: none; }

/* ============ RESPONSIVE ============ */
@media (max-width: 600px) {
  /* Jamais de débordement horizontal de la page, quel que soit le contenu */
  html, body { overflow-x: clip; width: 100%; max-width: 100%; }
  .topbar-inner { padding: 13px 18px; }
  .container { padding: 0 18px 20px; }

  /* ===== CLAVIER ANDROID : ne doit pas déranger la saisie =====
     Le problème : quand le clavier s'ouvre, le champ actif peut se retrouver
     masqué par le clavier, et la colonne récap « sticky » se colle au-dessus.
     Solutions appliquées :
     - scroll-margin-bottom : laisse la place au clavier sous le champ focus.
     - scroll-padding-bottom sur html : idem pour scrollIntoView.
     - la colonne récap passe en STATIQUE (déjà fait) et les champs gardent
       une hauteur tactile confortable. */
  html { scroll-padding-bottom: 46vh; }
  /* ⚠️ Spécificité : `.service-item .price` (2 classes) bat `.service-item input`
     (1 classe) → il faut cibler les classes RÉELLES pour porter la police à 16px
     (en dessous de 16px, Android/iOS zooment automatiquement au focus). */
  .builder input, .builder select, .builder textarea,
  .client-fields input, .custom-label, .custom-unit,
  .service-item .price, .service-item .qty, .service-item .s-select {
    scroll-margin-bottom: 44vh;
    font-size: 16px;
  }
  /* Barre d'action fixe : laisse de la place au-dessus du clavier */
  body.app-mode .app-action-bar { padding-bottom: max(10px, env(safe-area-inset-bottom)); }
  /* Champs de saisie : hauteur tactile confortable et cibles larges */
  .service-item .field-input input { min-height: 44px; }
  .service-item .remove { min-width: 44px; min-height: 44px; }
  /* L'aperçu résultat ne doit pas sauter sous le clavier */
  #result { scroll-margin-bottom: 40vh; }
  /* Quand le clavier Android est ouvert (classe posée en JS) : on masque la
     barre d'action FIXE pour qu'elle ne chevauche pas le clavier.
     (La colonne récap est en flux sur mobile → on ne la masque pas, cela
     provoquerait un saut de mise en page.) */
  body.kb-open .app-action-bar { display: none; }

  /* Hero mobile : audacieux mais sans débordement */
  .hero { padding: 14px 0 22px; gap: 18px; }
  .hero .eyebrow { margin-bottom: 12px; padding: 7px 14px; font-size: 11.5px; letter-spacing: 2px; }
  .hero h1 { font-size: clamp(32px, 9.8vw, 42px); line-height: 1.06; margin-bottom: 0; letter-spacing: -.025em; }
  /* H1 des autres gabarits (page-head, trade, price, price_dept, services) :
     ils étaient hérités de tailles desktop (34-42px) et paraissaient
     disproportionnés sur un écran de 360-390px. Le hero est EXCLU de cette
     règle : il a sa propre taille, plus grande (voir .hero h1 ci-dessus),
     sinon cette règle l'écrase (même spécificité, déclarée après). */
  .page-head h1, .visi-hero h1, .section-head h2 {
    font-size: clamp(24px, 7.5vw, 30px); line-height: 1.15;
  }
  .section-head h2 { font-size: clamp(21px, 6.5vw, 26px); }
  .hero p { font-size: 16.5px; margin-top: 12px; line-height: 1.55; }
  .hero-badges { gap: 8px; margin-top: 16px; }
  .hero-badge { margin-top: 0; padding: 7px 12px; font-size: 12px; gap: 6px; }
  /* Boutons : le nowrap global débordait avec les libellés longs sur 360px.
     Sur mobile, on autorise le retour à la ligne et on borne la largeur. */
  .btn { white-space: normal; text-align: center; line-height: 1.3; max-width: 100%; }
  .btn.big { line-height: 1.35; }
  .cta-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
  .cta-row .btn { flex: 1 1 100%; }
  .hero .cta-row { margin-top: 16px; gap: 10px; }
  .hero .cta-row .btn {
    width: 100%; padding: 13px 16px; font-size: 14.5px;
    white-space: normal; text-align: center; line-height: 1.35;
  }
  /* Liste d'arguments : 2 colonnes nettes. minmax(0,1fr) est OBLIGATOIRE :
     avec "1fr 1fr", la piste ne peut pas descendre sous la largeur de son
     contenu (min-width:auto) et débordait du conteneur (392px pour 354px). */
  .hero .trust {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 9px 16px; margin-top: 14px;
  }
  .hero .trust span { font-size: 13px; min-width: 0; }
  .hero .trust span:last-child { grid-column: 1 / -1; }
  .hero-note { margin-top: 10px; font-size: 12px; }
  .hero-alt { font-size: 13px; margin-top: 12px; line-height: 1.5; }
  /* Form rows : sur mobile, empiler pour éviter un label sur 2 lignes qui décale un champ */
  .form-row { flex-direction: column; gap: 0; }
  .form-row .f2 { flex: 1; }
  /* MOBILE : le hero est empilé (texte puis maquette). Si la scène 3D couvrait
     tout le hero, son sol (sous l'horizon, à 60%) tomberait DERRIÈRE la
     maquette et serait invisible -> fond animé perçu comme buggé.
     On limite donc la scène à la zone de texte, avec un fondu en bas. */
  /* FOND ANIMÉ RETIRÉ SUR MOBILE (demande utilisateur : « c'est laid »).
     La scène 3D n'est plus affichée sous 700px : on masque le conteneur
     (display:none, donc plus rien à peindre ni à calculer) ET le JS ne
     démarrera même pas l'animation (voir atelier3d.js). */
  .hero-3d { display: none !important; }
  /* Les décors du hero utilisaient des `inset` négatifs (débord volontaire sur
     desktop) : sur mobile ils décalaient tout le bloc. On les contient. */
  .hero { overflow: hidden; }
  .hero-mock::before { inset: -12px -4px; }
  .mock-glow { inset: 0; }
  /* Mini-builder : passer en 1 colonne. En 2 colonnes sur 354px, la colonne
     « récapitulatif » tombait à ~150px et le contenu débordait. */
  .mock-body { grid-template-columns: 1fr; }
  .mock-summary { border-left: none; border-top: 1px solid var(--line); }
  .mock-col { padding: 14px; }
  .mock-summary { padding: 14px; }
  .mock-field { margin-bottom: 12px; }
  .mock-bar { padding: 8px 12px; }
  .mock-label { font-size: 10px; margin-bottom: 2px; }
  .mock-select, .mock-control { padding: 9px 11px; font-size: 13px; }
  .mock-line { padding: 7px 0; font-size: 12px; }
  .mock-sum-title { font-size: 13px; margin-bottom: 6px; }
  .mock-total { padding: 4px 0; font-size: 12px; }
  .mock-total.mock-grand { margin-top: 4px; padding-top: 7px; }
  .mock-total.mock-grand span { font-size: 15px; }
  .mock-btn { margin-top: 10px; padding: 11px; font-size: 13px; }

  /* Sections : rythme vertical lisible sur mobile.
     ⚠️ Une passe de « compactage » antérieure avait mis 4px/12px : les
     sections se touchaient (0px d'écart mesuré entre deux sections) et la
     page paraissait « collée ». On rétablit une respiration correcte. */
  .section { padding: 34px 0; }
  .section-head { margin-bottom: 22px; }
}


/* ============================================================
   ⚠️⚠️ LIGNE DE PRESTATION — DÉBORDEMENT MESURÉ (2026-10-06).

   DÉFAUT. `.service-item` était une ligne `flex` NON REPLIABLE (5 blocs fixes :
   info + champ Prix (117px) + Qté (84px) + Coût (109px) + bouton supprimer
   (36px) = ~390px incompressibles). À partir du moment où le champ « Coût »
   s'affiche POUR TOUT LE MONDE (le paywall a été levé : `IS_PRO` vaut vrai
   pour tout compte connecté, alors qu'il ne concernait avant que 3 comptes
   Pro), la ligne débordait et le bouton supprimer sortait de l'écran :

     viewport   conteneur   débordement   bouton supprimer
       900px       396px        +15px        hors ligne
       860px       356px        +55px        hors ligne
       430px       348px        +71px        hors ligne
       390px       308px       +111px        hors ligne
       320px       238px       +181px        hors ligne

   CORRECTIF. On abandonne le flex non repliable pour une GRILLE qui se
   réorganise : la rangée des champs (Prix / Qté / Coût) passe SOUS le libellé
   quand la place manque. `overflow-wrap` + `min-width: 0` pour qu'aucun bloc
   ne pousse les autres dehors.

   ⚠️ Ne PAS revenir à un `flex` sur `.service-item` sans refaire la mesure
   (`scripts/audit_builder_seuil.py`).
   ============================================================ */
.service-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas: "info champs suppr";
  align-items: center;
  column-gap: 12px; row-gap: 10px;
}
.service-item .info { grid-area: info; min-width: 0; }
.service-item .price-wrap { grid-area: champs; flex-wrap: wrap; justify-content: flex-end; }
.service-item .remove { grid-area: suppr; }
/* sous 600 px : le libellé prend toute la largeur, les champs passent dessous */
@media (max-width: 600px) {
  .service-item {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "info info" "champs suppr";
  }
  .service-item .price-wrap { justify-content: flex-start; }
}
/* entre 601 et 940 px, la colonne du builder est étroite : même repli */
@media (min-width: 601px) and (max-width: 940px) {
  .builder .service-item {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "info info" "champs suppr";
  }
  .builder .service-item .price-wrap { justify-content: flex-start; }
}
/* les champs gardent une largeur utile mais compressible */
.service-item .price { width: 80px; max-width: 100%; }
.service-item .qty { width: 60px; max-width: 100%; }
.service-item .field { min-width: 0; }
.service-item .field-input { min-width: 0; }


/* ============================================================
   EX-atelier-polish.css   (30077 octets, 7 !important)
   ============================================================ */

/* ============================================================
   DEVISALY — Raffinement « Atelier » (couche additive 2026-09)
   Rehausse le design Atelier existant SANS changer son identité :
   ivoire, or, Fraunces. Ajoute profondeur, ombres affirmées,
   micro-interactions, hiérarchie. Se charge APRÈS luxe.css.
   Aucune règle destructive : uniquement des améliorations.
   ============================================================ */

:root {
  /* Ombres plus présentes (teintées or, pas de gris neutre) */
  --el-1: 0 1px 2px rgba(90,70,35,.05), 0 2px 6px rgba(90,70,35,.05);
  --el-2: 0 2px 6px rgba(90,70,35,.07), 0 10px 26px rgba(90,70,35,.09);
  --el-3: 0 6px 16px rgba(90,70,35,.10), 0 24px 56px rgba(90,70,35,.13);
  --el-gold: 0 4px 14px rgba(176,138,62,.22), 0 16px 40px rgba(176,138,62,.16);
  --el-gold-lg: 0 8px 24px rgba(176,138,62,.28), 0 28px 64px rgba(176,138,62,.20);
  /* Liseré lumineux haut de carte (donne du relief) */
  --bevel: inset 0 1px 0 rgba(255,255,255,.7);
  --ease-soft: cubic-bezier(.22,.68,.32,1);
}

/* ---- 1. Relief général : cartes et panels ---- */
.card, .panel {
  box-shadow: var(--el-1);
  transition: box-shadow .35s var(--ease-soft), border-color .3s var(--ease-soft),
              transform .35s var(--ease-soft);
}
.card:hover, .panel:hover {
  box-shadow: var(--el-2);
  border-color: var(--gold-line);
}

/* Cartes de contenu interactives : léger soulèvement */
.step, .plan, .qcard, .trade-card, .lead-benefit, .blog-card,
.stat-card, .kpi, .faq-item, .client-card, .retention-card {
  box-shadow: var(--el-1), var(--bevel);
  transition: box-shadow .4s var(--ease-soft), transform .4s var(--ease-soft),
              border-color .3s var(--ease-soft);
}

/* ---- 2. Bouton or : plus de présence ---- */
.btn.primary {
  box-shadow: 0 1px 0 rgba(255,255,255,.4) inset,
              0 2px 6px rgba(176,138,62,.28),
              0 8px 22px rgba(176,138,62,.22);
  transition: transform .2s var(--ease-soft), box-shadow .3s var(--ease-soft),
              filter .2s;
}
.btn.primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 0 rgba(255,255,255,.5) inset,
              0 6px 16px rgba(176,138,62,.36),
              0 18px 42px rgba(176,138,62,.26);
  filter: saturate(1.06) brightness(1.02);
}

/* ---- 3. Barre de navigation : plus nette au scroll ---- */
.topbar {
  box-shadow: 0 1px 0 var(--line-soft), 0 2px 14px rgba(90,70,35,.05);
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
}

/* Liens nav : soulignement or animé */
.nav > a:not(.btn) { position: relative; }
.nav > a:not(.btn)::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -7px; height: 1.5px;
  background: linear-gradient(90deg, var(--gold), var(--gold-2));
  transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease-soft);
}
.nav > a:not(.btn):hover::after,
.nav > a:not(.btn).active::after { transform: scaleX(1); }

/* ---- 4. Hero : profondeur et respiration ---- */
.hero h1 { text-shadow: 0 1px 0 rgba(255,255,255,.6); }
.hero .trust .dot {
  box-shadow: 0 0 0 3px rgba(176,138,62,.12), 0 0 12px rgba(176,138,62,.45);
}
.hero-mock .mock-window { box-shadow: var(--el-3), var(--bevel); }
.hero-mock::before { filter: blur(26px); }

/* Eyebrow : trait or plus fin et élégant */
.hero .eyebrow::before, .hero .eyebrow::after,
.page-head .eyebrow::before, .page-head .eyebrow::after {
  background: linear-gradient(90deg, transparent, var(--gold));
}

/* ---- 5. Récapitulatif (builder) : colonne de droite mise en valeur ---- */
.summary {
  box-shadow: var(--el-2), var(--bevel);
  border-color: var(--gold-line);
}
.summary::before { height: 3px; }
.summary-totals .grand {
  text-shadow: 0 1px 0 rgba(255,255,255,.5);
}

/* ---- 6. Champs de saisie : focus plus franc ---- */
input:focus, select:focus, textarea:focus {
  box-shadow: 0 0 0 3px rgba(176,138,62,.14), 0 1px 2px rgba(90,70,35,.06);
}

/* ---- 7. KPI : chiffres mis en avant ---- */
.kpi-value {
  text-shadow: 0 1px 0 rgba(255,255,255,.5);
  letter-spacing: -.02em;
}
.kpi-gold {
  background: linear-gradient(140deg, var(--card) 0%, rgba(233,220,192,.35) 100%);
  box-shadow: var(--el-2), var(--bevel);
}

/* ---- 8. Tableau devis : plus lisible ---- */
.quote-table th {
  background: linear-gradient(180deg, var(--paper), var(--card-2));
}
.quote-table tbody tr:hover { background: var(--gold-bg); }
.quote-totals-row.grand .value { text-shadow: 0 1px 0 rgba(255,255,255,.5); }

/* ---- 9. Badges et pastilles : relief ---- */
.qbadge, .plan-badge, .bs-plan {
  box-shadow: 0 1px 2px rgba(90,70,35,.06);
}
.qbadge.status-accepted, .plan-badge.pro, .bs-plan.pro {
  box-shadow: 0 1px 3px rgba(176,138,62,.18);
}

/* ---- 10. Apparition au scroll : plus douce ---- */
.js-anim .reveal {
  transition: opacity .7s var(--ease-soft), transform .7s var(--ease-soft);
}

/* ---- 11. CTA final et blocs or : halo maîtrisé ---- */
.cta-final {
  box-shadow: var(--el-gold);
  border-color: var(--gold-line);
}
.upsell-banner {
  box-shadow: var(--bevel), 0 2px 10px rgba(176,138,62,.10);
}

/* ---- 12. Boutons ghost : état hover avec profondeur ---- */
.btn.ghost {
  box-shadow: 0 1px 2px rgba(90,70,35,.04);
  transition: all .25s var(--ease-soft);
}
.btn.ghost:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(90,70,35,.08);
}

/* ---- 13. Scrollbar et sélection : cohérence or ---- */
::selection { background: var(--gold); color: #fff; }

/* ---- 14. Cartes métiers / étapes : icônes plus vivantes ---- */
.step-icon, .trade-card .trade-icon, .icon-wrap, .lb-icon, .offline-icon {
  box-shadow: 0 2px 8px rgba(176,138,62,.14), var(--bevel);
  transition: transform .35s var(--ease-soft), box-shadow .35s var(--ease-soft);
}
.step:hover .step-icon, .trade-card:hover .trade-icon,
.lead-benefit:hover .lb-icon, .feature:hover .icon-wrap {
  transform: translateY(-2px) scale(1.04);
  box-shadow: 0 6px 18px rgba(176,138,62,.22), var(--bevel);
}

/* ---- 15. Plans (pricing) : plan featured plus premium ---- */
.plan.featured {
  box-shadow: var(--el-gold-lg), var(--bevel);
  transform: translateY(-4px);
}
.plan.featured:hover { transform: translateY(-7px); }

/* ---- 16. Formulaires auth : carte plus présente ---- */
.auth-card {
  box-shadow: var(--el-3), var(--bevel);
}

/* ---- 17. Focus visible : anneau or ---- */
a:focus-visible, button:focus-visible, select:focus-visible,
input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* ---- 18. Mobile : désactiver les transformations coûteuses ---- */
@media (max-width: 820px) {
  .step, .plan, .qcard, .trade-card, .lead-benefit, .blog-card,
  .stat-card, .kpi, .faq-item, .client-card, .retention-card,
  .card, .panel {
    transform: none !important;
  }
  .step:hover .step-icon, .trade-card:hover .trade-icon {
    transform: none;
  }
  .plan.featured { transform: none; }
}

/* ---- 19. Motion réduite ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
  .step:hover .step-icon, .trade-card:hover .trade-icon { transform: none; }
}


/* ---- 20. ACCUEIL ALLÉGÉ : rythme vertical, moins de blocs ---- */
/* Une section = un rythme. Plus d'espace avant qu'après un titre. */
.container > .section { padding: 30px 0; }
.section-head { margin-bottom: 34px; }
.section-head h2 { margin-bottom: 10px; }

/* Étape : plus d'air, moins de bordure */
.steps { gap: 22px; }
.step { padding: 30px 26px; }

/* Témoignage intégré : discret, pas un bloc à part */
.testimonial {
  margin-top: 40px;
  padding: 28px 30px;
  background: linear-gradient(150deg, var(--card), var(--card-2));
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--gold-line);
  border-radius: var(--radius-lg);
  max-width: 720px;
}
.t-stars { margin-bottom: 12px; }
.t-text { font-size: 15.5px; line-height: 1.7; }

/* FAQ : plus compacte, lignes nettes */
.faq-acc { border-bottom: 1px solid var(--line); }
.faq-acc summary { padding: 18px 4px; font-size: 15.5px; }
.faq-acc-body { padding: 0 4px 16px; }

/* CTA final : bandeau haut, pas un gros bloc */
.cta-final {
  padding: 44px 32px;
  margin: 40px 0 44px;
  background: linear-gradient(150deg, var(--paper), var(--gold-bg));
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-xl);
}
.cta-final h2 { font-size: 27px; margin-bottom: 8px; }
.cta-final p { font-size: 14.5px; margin: 0 auto 20px; }

/* Trust-bar : plus fine, intégrée */
.trust-bar { gap: 34px; padding: 20px 0; margin-top: 8px; }

/* Footer : 3 colonnes, plus haut compact */
.footer { padding: 34px 0 16px; margin-top: 40px; }
.footer-grid { grid-template-columns: 1.7fr 1fr 1fr; gap: 28px; }
.footer h4 { margin-bottom: 10px; }
.footer a { padding: 3px 0; font-size: 13px; }
.footer .bottom { padding-top: 18px; margin-top: 20px; }

@media (max-width: 820px) {
  /* Rythme vertical mobile : les sections se touchaient (0px d'écart mesuré).
     34px haut/bas = ~68px entre deux sections, respiration correcte. */
  .container > .section { padding: 34px 0; }
  .step { padding: 24px 20px; }
  .testimonial { margin-top: 28px; padding: 22px; }
  .cta-final { padding: 32px 20px; margin: 40px 0 44px; }
  .cta-final h2 { font-size: 23px; }
  .footer-grid { grid-template-columns: 1fr; gap: 22px; }
  /* Bandeaux qui étaient collés au hero (8-10px) */
  .trust-bar { margin-top: 18px; }
  .stats-real { margin-top: 22px; }
}


/* ---- 21. Compactage supplémentaire ---- */
/* Étape : cartes plus basses */
.steps { gap: 18px; }
.step { padding: 24px 22px; }
.step p { font-size: 13.5px; }
.step h3 { font-size: 16.5px; }
.step-icon { width: 40px; height: 40px; margin-bottom: 14px; }
.step-num { margin-bottom: 10px; }

/* Footer : liens sur 2 colonnes compactes, moins de hauteur */
.footer { padding: 28px 0 14px; margin-top: 32px; }
.footer-grid { gap: 24px; }
.footer h4 { font-size: 12px; margin-bottom: 8px; }
.footer a { padding: 2px 0; font-size: 12.5px; }
.footer-tagline { font-size: 12.5px; }
.footer .bottom { padding-top: 14px; margin-top: 16px; font-size: 12px; }

/* Trust-bar : discrète */
.trust-bar { padding: 16px 0; }
.trust-item { font-size: 12.5px; }

/* FAQ : plus resserrée */
.faq-acc summary { padding: 15px 4px; font-size: 15px; }
.faq-acc-body { padding: 0 4px 14px; font-size: 14px; }


/* ---- 22. FAQ en 2 colonnes : -50% de hauteur, plus lisible ---- */
.faq-acc-wrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 40px;
  align-items: start;
}
@media (max-width: 820px) {
  .faq-acc-wrap { grid-template-columns: 1fr; gap: 0; }
}

/* Témoignage : plus compact, aligné à côté des étapes sur grand écran */
.testimonial { padding: 22px 24px; margin-top: 28px; }
.t-text { font-size: 15px; }
.t-stars { margin-bottom: 8px; }
.t-avatar { width: 36px; height: 36px; font-size: 15px; }

/* ---- 12. Accueil — hero & témoignage : respiration resserrée ---- */
/* Desktop : réduire la taille/padding (le mock 499px domine la hauteur) */
@media (min-width: 901px) {
  .hero { padding: 26px 0 40px; }
  /* Titre et sous-titre agrandis (retour utilisateur : « doit être plus gros ») */
  /* ⚠️ La taille du h1 est désormais définie UNE SEULE FOIS (`.hero h1` dans
     luxe.css, 56 px). Cette surcharge à 78 px avait été écrite pour l'ancienne
     accueil, qui n'utilise plus `.hero h1` : elle ne touchait donc plus QUE les
     pages métiers (/devis, /prix, /services), qu'elle déformait — même balise
     `h1` à 78 px sur une page et 56 px sur une autre, aucun rythme d'ensemble. */
  .hero p { font-size: 20px; margin-top: 22px; line-height: 1.6; max-width: 560px; }
  .hero .cta-row { margin-top: 24px; }
  .hero .trust { margin-top: 20px; gap: 18px; }
  .hero-mock .mock-col { padding: 18px; }
  .hero-mock .mock-summary { padding: 18px; }
  .hero-mock .mock-field { margin-bottom: 12px; }
  .hero-mock .mock-line { padding: 8px 0; }
  .hero-mock .mock-btn { margin-top: 14px; padding: 11px; }
}

/* Témoignage intégré : plus proche du bloc étapes */
.testimonial { padding: 18px 22px; margin-top: 22px; }
.t-text { font-size: 14.5px; line-height: 1.6; }

/* ---- 13. Devis + site web (landing) : deux volets clairs ---- */
#dual .dual-grid,
#cout-verite .dual-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  max-width: 1000px;
  margin: 0 auto;
}
#dual .dual-plan,
#cout-verite .dual-plan {
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-lg);
  padding: 28px 30px 26px;
  display: flex;
  flex-direction: column;
  position: relative;
}
#dual .dual-quote,
#cout-verite .dual-quote { background: var(--card); box-shadow: var(--shadow-sm); }
#dual .dual-site,
#cout-verite .dual-site {
  background: linear-gradient(150deg, rgba(190,160,90,.16), var(--paper));
  border-color: rgba(176,138,62,.55);
  box-shadow: 0 10px 28px rgba(176,138,62,.16);
}
#dual .dual-site .dual-tag,
#cout-verite .dual-site .dual-tag {
  align-self: flex-start;
  background: linear-gradient(160deg, #c19a4e, #b08a3e);
  color: #fff;
  font-size: 11px; font-weight: 500; letter-spacing: 1.2px; text-transform: uppercase;
  padding: 5px 14px; border-radius: 40px; margin-bottom: 12px;
  box-shadow: 0 2px 8px rgba(176,138,62,.35);
}
#dual .dual-plan h3,
#cout-verite .dual-plan h3 { font-family: var(--font-serif); font-size: 23px; font-weight: 500; color: var(--ink); margin-bottom: 10px; }
#dual .dual-plan p,
#cout-verite .dual-plan p { color: var(--muted); font-size: 14.5px; line-height: 1.65; margin-bottom: 16px; }
#dual .dual-plan ul,
#cout-verite .dual-plan ul { list-style: none; margin-bottom: 18px; flex: 1; }
#dual .dual-plan li,
#cout-verite .dual-plan li { padding: 6px 0; font-size: 14px; color: var(--ink); display: flex; align-items: center; gap: 10px; }
#dual .dual-plan .dot,
#cout-verite .dual-plan .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gold); flex-shrink: 0; }
#dual .dual-quote .btn,
#cout-verite .dual-quote .btn { align-self: flex-start; }
#dual .dual-site .btn,
#cout-verite .dual-site .btn { align-self: flex-start; border-color: rgba(176,138,62,.55); }
#dual .dual-price,
#cout-verite .dual-price { margin-top: 12px; color: var(--gold-2); font-weight: 500; font-size: 13.5px; }
#dual .section-head p { margin-top: 10px; }
@media (max-width: 800px) {
  #dual .dual-grid,
  #cout-verite .dual-grid { grid-template-columns: 1fr; }
  #dual .dual-plan,
  #cout-verite .dual-plan { padding: 24px 20px; }
}

/* ---- Outil PDF (modifier/fusionner un PDF en ligne) ---- */
.pdf-tools {
  max-width: 640px; margin: 34px auto 0; background: var(--card);
  border: 1px solid var(--gold-line); border-radius: var(--radius-lg); padding: 28px 30px;
  box-shadow: var(--shadow-sm);
}
.pt-tabs { display: flex; gap: 8px; margin-bottom: 22px; flex-wrap: wrap; }
.pt-tab {
  background: var(--card-2); border: 1px solid var(--line); color: var(--muted);
  font-size: 14px; font-weight: 500; padding: 10px 18px; border-radius: var(--radius);
  cursor: pointer; transition: all .2s;
}
.pt-tab.active { background: var(--gold-bg); border-color: var(--gold-line); color: var(--gold-2); }
.pt-panel { display: flex; flex-direction: column; gap: 14px; }
.pt-hint { color: var(--muted); font-size: 14px; line-height: 1.6; }
.pt-input, .pt-text {
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius);
  font-size: 15px; color: var(--ink); background: var(--card); box-sizing: border-box;
}
.pt-panel .btn { align-self: flex-start; }
.pt-check { font-size: 13px; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.pt-status { margin-top: 16px; font-size: 14px; color: var(--muted); min-height: 18px; }
.pt-status.ok { color: var(--ok); font-weight: 500; }
.pt-status.err { color: var(--danger); }
#pt-download { margin-top: 10px; }

/* ---- Chips de maillage interne : style de base manquant (price/dept/trade) ---- */
.chip {
  display: inline-block; padding: 9px 15px; font-size: 13px; font-weight: 500;
  background: var(--card-2); color: var(--ink-2) !important; border: 1px solid var(--line);
  border-radius: 40px; text-decoration: none; transition: all .18s ease; line-height: 1.3;
}
.chip:hover { border-color: var(--gold-line); color: var(--gold-2) !important; background: var(--card); box-shadow: 0 2px 8px rgba(176,138,62,.15); }

/* ---- 14. Problème / empathie (landing) ---- */
#probleme .pain-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
  max-width: 1000px;
  margin: 0 auto;
}
#probleme .pain-item {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 26px 24px;
  text-align: left;
}
#probleme .pain-item svg { color: var(--gold-2); margin-bottom: 14px; }
#probleme .pain-item h3 { font-size: 17px; font-weight: 500; color: var(--ink); margin-bottom: 8px; }
#probleme .pain-item p { color: var(--muted); font-size: 14px; line-height: 1.6; }
@media (max-width: 800px) {
  #probleme .pain-grid { grid-template-columns: 1fr; gap: 14px; }
}

/* ---- 15. Tarifs accueil : pic du tunnel ---- */
#pricing-home .plans { max-width: 1100px; }
#pricing-home .note { text-align: center; margin-top: 18px; color: var(--muted); font-size: 14px; }
#pricing-home .note a { color: var(--gold-2); font-weight: 500; text-decoration: none; border-bottom: 1px solid var(--gold-line); }
#pricing-home .price-crossed {
  color: var(--faint); text-decoration: line-through; font-size: 22px; font-weight: 500; margin-right: 2px;
}
#pricing-home .price-promo { font-size: 13px; color: var(--gold-2); font-weight: 500; }
#pricing-home .plan .tag { margin-bottom: 14px; }
/* Badge "Vos nouveaux clients" de la carte Visibilité (carte non-featured) */
#pricing-home .plan .tag:not(:empty) {
  display: inline-block; align-self: flex-start;
  background: linear-gradient(160deg, #c19a4e, #b08a3e); color: #fff;
  font-size: 11px; font-weight: 500; letter-spacing: 1.2px; text-transform: uppercase;
  padding: 6px 16px; border-radius: 40px; margin-bottom: 14px;
  box-shadow: 0 2px 8px rgba(176,138,62,.3);
}


/* ---- 16. Tunnel Visibilité Pro (199 €) : page de vente dédiée ---- */
.visi-tunnel { max-width: 860px; margin: 0 auto; padding: 10px 0 40px; }
.visi-hero { text-align: center; margin-bottom: 30px; }
.visi-hero h1 { font-family: var(--font-serif); font-size: 42px; font-weight: 500; line-height: 1.12; letter-spacing: -.02em; color: var(--ink); max-width: 720px; margin-inline: auto; }
.visi-hero p { color: var(--muted); font-size: 16px; line-height: 1.7; max-width: 620px; margin: 14px auto 0; }
.visi-card { max-width: 680px; margin: 0 auto; }
.visi-summary {
  background: var(--card);
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-lg);
  padding: 30px 34px 28px;
  box-shadow: var(--shadow-sm);
}
.visi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 4px; }
.visi-plan-name { font-family: var(--font-serif); font-size: 20px; font-weight: 500; color: var(--ink); }
.visi-price { font-family: var(--font-serif); font-size: 42px; font-weight: 500; color: var(--gold-2); margin: 6px 0 2px; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.visi-price small { font-size: 14px; color: var(--faint); font-weight: 500; }
.visi-promo { font-size: 13.5px; color: var(--gold-2); font-weight: 500; display: block; margin-top: 2px; }
.visi-price-now { color: var(--gold-2); display: inline-block; }
.visi-price-major { color: var(--gold-2); font-family: var(--font-serif); font-size: 42px; font-weight: 500; display: inline-block; }
.visi-price-old {
  color: var(--faint); text-decoration: line-through; font-size: 22px; font-weight: 500;
  margin-left: 10px; display: inline-block;
}
.visi-badges { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.visi-badge {
  background: var(--gold-bg); color: var(--gold-2); font-size: 11.5px; font-weight: 500;
  letter-spacing: .5px; text-transform: uppercase; padding: 5px 12px; border-radius: 40px;
  white-space: nowrap; max-width: 100%;
}
/* Nouvelles classes : page de paiement guidée */
.visi-eyebrow {
  display: inline-block; text-transform: uppercase; letter-spacing: 2px; font-size: 12px;
  color: var(--gold-2); font-weight: 500; background: var(--gold-bg); border: 1px solid var(--gold-line);
  padding: 7px 16px; border-radius: 40px; margin-bottom: 18px;
}
.visi-whats-included {
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin: 0 auto 30px; max-width: 760px;
}
.visi-item {
  display: inline-flex; align-items: center; gap: 8px; background: var(--card);
  border: 1px solid var(--line); border-radius: 40px; padding: 9px 16px; font-size: 14px; color: var(--ink);
}
.visi-item svg { color: var(--gold-2); }
.visi-layout {
  display: grid; grid-template-columns: 1.1fr 1fr; gap: 30px; max-width: 980px; margin: 0 auto; align-items: start;
}
.visi-guide { display: flex; flex-direction: column; gap: 22px; }
.visi-guide-block {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 22px 24px;
}
.visi-guide-block h3, .visi-guide-title { font-size: 16px; font-weight: 500; color: var(--ink); margin-bottom: 14px; }
.visi-steps-guide { list-style: none; }
.visi-steps-guide li { display: flex; gap: 14px; margin-bottom: 14px; }
.visi-steps-guide li:last-child { margin-bottom: 0; }
.vsg-num {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%; background: var(--gold-bg);
  color: var(--gold-2); font-weight: 500; font-size: 14px; display: grid; place-items: center;
}
.visi-steps-guide strong { font-size: 14.5px; color: var(--ink); display: block; line-height: 1.3; }
.visi-steps-guide p { font-size: 13px; color: var(--muted); line-height: 1.5; margin-top: 2px; }
.visi-guide-reassure h3 { margin-bottom: 10px; }
.visi-reassure { list-style: none; }
.visi-reassure li { font-size: 13.5px; color: var(--muted); padding: 6px 0; display: flex; align-items: center; gap: 8px; }
.visi-reassure li::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--gold); flex-shrink: 0; }
.visi-card { max-width: 100%; }
@media (max-width: 850px) {
  .visi-layout { grid-template-columns: 1fr; }
}

/* ---- 18. Avis clients (SEO) ---- */
#avis .testimonials { max-width: 1100px; margin: 0 auto; }
#avis .testimonial { box-shadow: var(--shadow-sm); }
/* Carrousel d'avis scroll-snap (desktop : flèches, mobile : swipe) */
.rev-carousel { position: relative; max-width: 1100px; margin: 0 auto; }
#avis #rev-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc((100% - 2 * 20px) / 3);
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;
  padding: 4px;
  scrollbar-width: thin;
  margin: 0 auto;
}
#avis #rev-track::-webkit-scrollbar { height: 6px; }
#avis #rev-track::-webkit-scrollbar-thumb { background: var(--gold-line); border-radius: 6px; }
#avis #rev-track .testimonial {
  scroll-snap-align: start;
  display: flex; flex-direction: column; justify-content: center;
  box-sizing: border-box;
}
.rev-btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--gold-line); color: var(--gold-2);
  display: grid; place-items: center; cursor: pointer; z-index: 2;
  box-shadow: 0 2px 8px rgba(25,23,19,.08); transition: all .18s ease;
}
.rev-btn:hover { background: var(--gold-bg); border-color: var(--gold-2); }
.rev-prev { left: -14px; }
.rev-next { right: -14px; }
@media (max-width: 800px) {
  #avis #rev-track { grid-auto-columns: calc((100% - 20px) / 1.2); }
  .rev-prev { left: 4px; }
  .rev-next { right: 4px; }
}
/* Note agrégée */
.reviews-summary {
  text-align: center; margin: 0 auto 28px; max-width: 520px;
  background: var(--card); border: 1px solid var(--gold-line); border-radius: var(--radius-lg);
  padding: 18px 24px; box-shadow: var(--shadow-sm);
}
.rs-score { font-family: var(--font-serif); font-size: 34px; font-weight: 500; color: var(--gold-2); }
.rs-stars { display: flex; justify-content: center; gap: 3px; margin: 8px 0 6px; }
.rs-stars svg { color: var(--deco); }
.rs-sub { color: var(--muted); font-size: 13px; }
.visi-list { list-style: none; margin: 18px 0 0; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; }
.visi-list li { font-size: 14.5px; color: var(--ink); display: flex; align-items: center; gap: 10px; }
.visi-list li .check { width: 16px; height: 16px; flex-shrink: 0; position: relative; }
.visi-list li .check::before {
  content: ""; position: absolute; left: 3px; top: 6px;
  width: 9px; height: 5px; border-left: 1.8px solid var(--accent);
  border-bottom: 1.8px solid var(--accent); transform: rotate(-45deg);
}
.visi-separator { border-top: 1px solid var(--line-soft); margin: 24px 0; }
.visi-pay-title { font-size: 15px; font-weight: 500; color: var(--ink); margin-bottom: 4px; }
.visi-note { font-size: 12.5px; color: var(--faint); line-height: 1.5; }
.visi-pay form { margin-top: 14px; }
.visi-pay form label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.visi-pay form input[type="email"] {
  width: 100%; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius);
  font-size: 15px; color: var(--ink); background: var(--card); box-sizing: border-box; margin-bottom: 14px;
}
.visi-consent { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; color: var(--muted); line-height: 1.5; cursor: pointer; }
.visi-consent input { margin-top: 3px; }
.visi-consent a { color: var(--accent); font-weight: 500; text-decoration: none; border-bottom: 1px solid var(--gold-line); }
.visi-pay form .btn { width: 100%; margin-top: 14px; }
.visi-tiny { text-align: center; color: var(--faint); font-size: 12px; margin-top: 10px; }

/* Page de confirmation */
.visi-thanks { text-align: center; max-width: 620px; margin: 40px auto 60px; }
.visi-thanks-check { width: 64px; height: 64px; border-radius: 50%; background: var(--gold-bg); color: var(--gold-2); display: grid; place-items: center; margin: 0 auto 22px; }
.visi-thanks h1 { font-family: var(--font-serif); font-size: 34px; font-weight: 500; color: var(--ink); }
.visi-thanks p { color: var(--muted); font-size: 15.5px; line-height: 1.7; margin-top: 14px; }
.visi-thanks-reminder { color: var(--faint) !important; font-size: 13.5px !important; }
.visi-thanks .btn { margin-top: 22px; }
.visi-thanks .btn.ghost { margin-left: 10px; }
.visi-thanks-recap {
  background: var(--card); border: 1px solid var(--gold-line); border-radius: var(--radius-lg);
  padding: 18px 22px; max-width: 460px; margin: 22px auto 0; text-align: left;
}
.visi-tr-label { font-size: 12px; text-transform: uppercase; letter-spacing: 1.5px; color: var(--gold-2); font-weight: 500; margin-bottom: 10px; }
.visi-tr-line { display: flex; justify-content: space-between; padding: 7px 0; border-top: 1px solid var(--line-soft); font-size: 14px; color: var(--ink); }
.visi-tr-line span:last-child { font-weight: 500; color: var(--gold-2); }
.visi-thanks-unknown { padding: 10px 0; }

@media (max-width: 800px) {
  .visi-card { max-width: 100%; }
  .visi-summary { padding: 24px 20px; }
  .visi-hero h1 { font-size: 30px; }
  .visi-top { flex-direction: column; }
  .visi-badges { flex-direction: row; align-items: center; flex-wrap: wrap; gap: 6px; max-width: 100%; }
  .visi-list { grid-template-columns: 1fr; }
}

/* ---- 18. Carrousel mobile : pain-grid, steps, plans deviennent défilants ----- */
/* Desktop intact. Sur mobile, chaque groupe passe en défilement horizontal
   tactile (scroll-snap) pour éviter l'empilement vertical très long. */
@media (max-width: 800px) {
  #probleme .pain-grid,
  #etapes .steps {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 16px;
    padding: 4px 4px 12px;
    margin: 0 -4px;
    scrollbar-width: thin;
    scrollbar-color: var(--gold-line) transparent;
  }
  #probleme .pain-grid > *, 
  #etapes .steps > * {
    flex: 0 0 86%;
    max-width: 86%;
    scroll-snap-align: center;
  }
  #probleme .pain-grid > *.reveal,
  #etapes .steps > *.reveal { opacity: 1; transform: none; }
}
@media (max-width: 600px) {
  #pricing-home .plans {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 16px;
    padding: 4px 4px 12px;
    margin: 0 -4px;
    scrollbar-width: thin;
    scrollbar-color: var(--gold-line) transparent;
  }
  #pricing-home .plans > * {
    flex: 0 0 86%;
    max-width: 86%;
    scroll-snap-align: center;
  }
  #pricing-home .plans > *.reveal { opacity: 1; transform: none; }
  #pricing-home .plans .plan { min-width: 0; }
}

/* ---- 17. Comparatifs & devis généré : scroll horizontal propre sur mobile (additif) ---- */
@media (max-width: 600px) {
  #comparatif .quote-doc { overflow-x: auto; }
  #comparatif .quote-table { min-width: 520px; }
  /* Le devis généré dans le builder : sa table est plus large que la carte sur petit
     écran. Permettre le scroll horizontal interne au lieu de rogner la colonne Total HT. */
  #result .quote-doc { overflow-x: auto; }
  #result .quote-table { min-width: 460px; }
  /* ⚠️⚠️ MÊME TABLEAU, MÊME BUG, MAIS SANS LE CORRECTIF (ajouté 2026-10-05).
     Le devis des pages SEO `/devis/<métier>` et `/prix/<métier>/<département>`
     utilise le MÊME `.quote-table` que le builder, dans un `.quote-doc` qui est
     en `overflow: hidden` par défaut. Mesuré à 390 px : la table fait 420 px dans
     un conteneur de 352 px → **68 px de contenu coupés**, la colonne Total/TTC
     était purement INVISIBLE et impossible à atteindre (pas de défilement).
     Les règles ci-dessus ne ciblaient que `#comparatif` et `#result` : ces pages
     avaient été oubliées. On couvre donc TOUT `.quote-doc` sur mobile. */
  .quote-doc { overflow-x: auto; }
}


/* ============================================================
   EX-artisan.css   (7463 octets, 0 !important)
   ============================================================ */

/* ============================================================
   DEVISALY — Tunnel artisan (/artisan)
   Page d'accueil pour l'artisan venu d'un email, avec chatbot
   guide. Meme charte que le reste : papier ivoire, or, encre.
   Aucun emoji (regle du user) : uniquement des SVG au trait.
   ============================================================ */

.artisan-body {
  background: var(--paper);
  min-height: 100vh;
}

.artisan-wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 28px 20px 64px;
}

/* ---- En-tete ---- */
.artisan-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 18px;
  margin-bottom: 34px;
  border-bottom: 1px solid var(--line);
}
.artisan-brand { text-decoration: none; }
.artisan-brand .brand-name {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 500;
  color: var(--ink);
}
.artisan-brand .brand-name span { color: var(--gold-2); }
.artisan-tagline {
  font-size: 12px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--faint);
}

/* ---- Hero ---- */
.artisan-hero { text-align: center; margin-bottom: 30px; }
.artisan-eyebrow {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--gold-2);
  border: 1px solid var(--gold-line);
  background: var(--gold-bg);
  border-radius: 999px;
  padding: 5px 14px;
  margin-bottom: 18px;
}
.artisan-hero h1 {
  font-family: var(--font-serif);
  font-size: 34px;
  line-height: 1.25;
  font-weight: 500;
  color: var(--ink);
  margin: 0 0 14px;
}
.artisan-hero h1 em {
  font-style: normal;
  color: var(--gold-2);
  border-bottom: 2px solid var(--gold-line);
}
.artisan-hero p {
  font-size: 15.5px;
  line-height: 1.75;
  color: var(--ink-2);
  margin: 0 auto;
  max-width: 560px;
}

/* ---- Chat ---- */
.chat {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.chat-log {
  padding: 24px 22px 8px;
  max-height: 46vh;
  min-height: 190px;
  overflow-y: auto;
  scroll-behavior: smooth;
}
.msg {
  max-width: 82%;
  padding: 11px 15px;
  border-radius: 14px;
  font-size: 15px;
  line-height: 1.62;
  margin-bottom: 12px;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.msg.bot {
  background: var(--paper-2);
  color: var(--ink);
  border: 1px solid var(--line-soft);
  border-bottom-left-radius: 4px;
}
.msg.moi {
  background: var(--ink);
  color: #fff;
  margin-left: auto;
  border-bottom-right-radius: 4px;
}
.msg.typing {
  display: flex;
  gap: 5px;
  align-items: center;
  padding: 15px;
}
.msg.typing span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--muted);
  animation: ty 1.2s infinite ease-in-out;
}
.msg.typing span:nth-child(2) { animation-delay: .18s; }
.msg.typing span:nth-child(3) { animation-delay: .36s; }
@keyframes ty {
  0%, 60%, 100% { opacity: .28; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* ---- Reponses rapides ---- */
.chat-quick {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 4px 22px 14px;
}
.chat-chip {
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 9px 16px;
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.chat-chip:hover {
  border-color: var(--gold);
  background: var(--gold-bg);
  color: var(--gold-3);
}

/* ---- Saisie ---- */
.chat-form {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 14px 16px;
  border-top: 1px solid var(--line);
  background: var(--card-2);
}
.chat-form input {
  flex: 1;
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  outline: none;
}
.chat-form input:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-bg);
}
.chat-send {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  color: #fff;
  background: linear-gradient(165deg, #c6a25c, #b99652, #9a7a35);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}
.chat-send:hover { filter: brightness(1.05); }
.chat-progress {
  margin: 0;
  padding: 0 22px 16px;
  font-size: 12px;
  letter-spacing: .4px;
  color: var(--faint);
  text-align: right;
}

/* ---- Reassurance ---- */
.artisan-trust {
  margin-top: 26px;
  display: grid;
  gap: 12px;
}
.artisan-trust-item {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-2);
}
.artisan-trust-item svg { flex: 0 0 auto; color: var(--gold-2); }

/* ---- Ecran de confirmation ---- */
.artisan-done { text-align: center; }
.artisan-done-icon {
  width: 84px; height: 84px;
  margin: 0 auto 22px;
  display: grid;
  place-items: center;
  color: var(--gold-2);
  background: var(--gold-bg);
  border: 1px solid var(--gold-line);
  border-radius: 50%;
}
.artisan-done h1 {
  font-family: var(--font-serif);
  font-size: 30px;
  font-weight: 500;
  color: var(--ink);
  margin: 0 0 12px;
}
.artisan-done-lead {
  font-size: 16px;
  line-height: 1.75;
  color: var(--ink-2);
  margin: 0 0 28px;
}
.artisan-done-lead strong { color: var(--gold-3); }

.artisan-recap {
  text-align: left;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 6px 20px;
  margin-bottom: 30px;
}
.artisan-recap-row {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 14.5px;
}
.artisan-recap-row:last-child { border-bottom: 0; }
.artisan-recap-row span { color: var(--muted); }
.artisan-recap-row b { color: var(--ink); text-align: right; }

.artisan-next {
  text-align: left;
  margin-bottom: 28px;
}
.artisan-next h2 {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 500;
  color: var(--ink);
  margin: 0 0 14px;
}
.artisan-next ol {
  margin: 0;
  padding-left: 0;
  list-style: none;
  counter-reset: n;
}
.artisan-next li {
  position: relative;
  counter-increment: n;
  padding: 0 0 16px 44px;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--ink-2);
}
.artisan-next li::before {
  content: counter(n);
  position: absolute;
  left: 0; top: 1px;
  width: 28px; height: 28px;
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 500;
  color: var(--gold-2);
  background: var(--gold-bg);
  border: 1px solid var(--gold-line);
  border-radius: 50%;
}
.artisan-next li b { color: var(--ink); }
.artisan-fine {
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--muted);
  margin: 0 0 24px;
}

/* ---- Pied ---- */
.artisan-foot {
  margin-top: 40px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  text-align: center;
}
.artisan-foot p {
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--faint);
  margin: 0;
}
.artisan-foot a { color: var(--gold-2); text-decoration: none; }
.artisan-foot a:hover { text-decoration: underline; }

/* ---- Mobile ---- */
@media (max-width: 560px) {
  .artisan-head { flex-direction: column; gap: 4px; }
  .artisan-hero h1 { font-size: 27px; }
  .msg { max-width: 90%; }
  .chat-quick { padding: 4px 16px 12px; }
  .chat-log { padding: 20px 16px 6px; max-height: 42vh; }
  .chat-chip { font-size: 13.5px; padding: 8px 13px; }
}


/* ============================================================
   EX-accueil-contrat.css   (29271 octets, 1 !important)
   ============================================================ */

/* ============================================================
   ACCUEIL — structure « le contrat d'abord » (2026-09-30)

   ⚠️ PIVOT : l'accueil vend le SITE (129 €/mois), plus le devis. Le relevé de
   conditions ouvre la page : prix, engagement, garantie. C'est ce qu'un artisan
   cherche d'abord, et ce que la catégorie cache sous trois écrans de promesses.

   ⚠️ Aucun sur-titre (eyebrow) : interdit par la craft floor. La page en
   comptait 5, il n'en reste aucun.
   ============================================================ */

/* ---------- HERO : le relevé de conditions ---------- */
.hero-contrat {
  display: grid;
  grid-template-columns: 1.15fr .85fr;
  gap: 56px;
  align-items: center;
  padding: 64px 0 72px;
}
.hero-contrat .hero-copy h1 {
  font-family: var(--font-serif);
  font-size: clamp(32px, 4.2vw, 56px);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -.025em;
  color: var(--ink);
  margin: 0;
}
.hero-contrat .hero-lede {
  color: var(--ink-2);
  font-size: 18px;
  line-height: 1.65;
  max-width: 54ch;
  margin: 22px 0 0;
}

/* Le relevé : la grammaire d'un devis, pas d'une offre. Filets d'un pixel,
   libellés en petites capitales espacées, valeurs en mono. */
.releve {
  margin: 30px 0 0;
  border-top: 1px solid var(--line);
}
.releve-l {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 18px;
  align-items: baseline;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}
.releve-l dt {
  font-family: var(--font-mono, var(--font-sans));
  font-size: 11px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--faint);
}
.releve-l dd {
  margin: 0;
  color: var(--ink);
  font-size: 15.5px;
  line-height: 1.5;
}
.releve-l dd .num {
  font-family: var(--font-mono, var(--font-sans));
  font-size: 26px;
  font-weight: 500;
  letter-spacing: -.03em;
}
.releve-l dd .per { color: var(--muted); font-size: 14px; }

.hero-contrat .cta-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-top: 28px; }
.hero-contrat .cta-note { color: var(--faint); font-size: 13px; line-height: 1.6; max-width: 52ch; margin: 16px 0 0; }

/* ---------- Le panneau d'aperçu (colonne droite) ---------- */
.apercu-bloc { padding: 22px 22px 4px; }
.ap-kicker {
  display: block;
  font-family: var(--font-mono, var(--font-sans));
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold-2);
  margin-bottom: 10px;
}
.ap-nom {
  display: block;
  font-family: var(--font-serif);
  font-size: 25px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -.02em;
  line-height: 1.15;
}
.ap-metier { display: block; color: var(--muted); font-size: 14px; margin-top: 6px; }
.ap-lignes { list-style: none; margin: 20px 0 0; padding: 0 22px 0; }
.ap-lignes li {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 0; border-bottom: 1px solid var(--line);
  font-size: 14px; color: var(--ink-2);
}
.ap-lignes li:last-child { border-bottom: 0; }
.ap-coche {
  width: 15px; height: 15px; flex: 0 0 auto;
  border: 1.4px solid var(--gold); border-radius: 3px;
  position: relative;
}
.ap-coche::after {
  content: ""; position: absolute; left: 4px; top: 1px;
  width: 5px; height: 9px;
  border-right: 1.8px solid var(--gold-2); border-bottom: 1.8px solid var(--gold-2);
  transform: rotate(40deg);
}
.ap-note {
  margin: 0; padding: 16px 22px 22px;
  font-size: 13px; color: var(--faint); line-height: 1.55;
}

/* ---------- La douleur ---------- */
.pain-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; border-top: 1px solid var(--ink); }
.pain-item { padding: 26px 24px 30px; border-right: 1px solid var(--line); }
.pain-item:last-child { border-right: 0; }
.pain-item h3 { font-family: var(--font-serif); font-size: 22px; font-weight: 500; margin: 0 0 10px; line-height: 1.25; }
.pain-item p { color: var(--muted); font-size: 15px; line-height: 1.62; margin: 0; }

/* ⚠️ `atelier-polish.css` (chargé APRÈS cette feuille) fixe `#probleme .pain-item h3`
   à 17 px, soit MOINS que le corps de texte (18 px) : le titre passait sous le
   texte qu'il introduit. On reprend la main avec la même spécificité. */
#probleme .pain-item h3 { font-size: 22px; font-weight: 500; }
#probleme .pain-item p { font-size: 15px; }

/* ---------- La prestation : 6 engagements, en filets ---------- */
.presta { border-top: 1px solid var(--ink); }
.presta-item {
  display: grid; grid-template-columns: 300px 1fr; gap: 32px;
  padding: 24px 0; border-bottom: 1px solid var(--line);
}
.presta-item h3 { font-family: var(--font-serif); font-size: 20px; font-weight: 500; margin: 0; }
.presta-item p { color: var(--muted); font-size: 15px; line-height: 1.65; margin: 0; max-width: 62ch; }

/* ---------- Les exemples ---------- */
.exemples-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.exemple-card { margin: 0; }
.exemple-card img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--paper-2);
}
.exemple-card figcaption { padding: 14px 2px 0; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.ex-nom { font-family: var(--font-serif); font-size: 16px; font-weight: 500; color: var(--ink); }
.ex-desc { font-size: 12.5px; color: var(--muted); flex: 1; min-width: 110px; }
.ex-tag {
  font-size: 10.5px; font-weight: 500; letter-spacing: .07em; text-transform: uppercase;
  color: var(--gold-2); background: var(--gold-bg); border: 1px solid var(--gold-line);
  padding: 3px 9px; border-radius: 20px; white-space: nowrap;
}

/* ---------- Les 3 étapes ---------- */
.etapes { list-style: none; margin: 0; padding: 0; counter-reset: e; border-top: 1px solid var(--ink); }
.etapes li {
  display: grid; grid-template-columns: 300px 1fr; gap: 32px;
  padding: 24px 0; border-bottom: 1px solid var(--line);
  counter-increment: e;
}
.etapes li h3 {
  font-family: var(--font-serif); font-size: 20px; font-weight: 500; margin: 0;
  display: flex; align-items: baseline; gap: 12px;
}
.etapes li h3::before {
  content: counter(e, decimal-leading-zero);
  font-family: var(--font-mono, var(--font-sans));
  font-size: 12px; font-weight: 500; color: var(--gold-2); letter-spacing: .08em;
}
.etapes li p { color: var(--muted); font-size: 15px; line-height: 1.65; margin: 0; max-width: 62ch; }

/* ---------- Le prix ---------- */
.prix-bloc {
  max-width: 620px; margin: 0 auto; padding: 34px 34px 30px;
  background: var(--card); border: 1px solid var(--gold-line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-md, 0 20px 44px -28px rgba(25,23,19,.4));
  text-align: center;
}
.prix-tete { display: flex; align-items: baseline; justify-content: center; gap: 10px; }
.px-num { font-family: var(--font-mono, var(--font-sans)); font-size: 52px; font-weight: 500; letter-spacing: -.04em; color: var(--ink); }
.px-per { color: var(--muted); font-size: 15px; }
.px-liste { list-style: none; margin: 26px 0 24px; padding: 0; text-align: left; }
.px-liste li {
  padding: 12px 0 12px 28px; border-bottom: 1px solid var(--line);
  font-size: 15px; color: var(--ink-2); position: relative;
}
.px-liste li::before {
  content: ""; position: absolute; left: 2px; top: 18px;
  width: 9px; height: 5px;
  border-left: 1.8px solid var(--gold-2); border-bottom: 1.8px solid var(--gold-2);
  transform: rotate(-45deg);
}
.px-liste li:last-child { border-bottom: 0; }
.prix-bloc .btn { width: 100%; }
.px-note { color: var(--faint); font-size: 12.5px; margin: 14px 0 0; line-height: 1.6; }
.px-note a { color: var(--gold-2); }

/* ---------- La ligne devis, en bas (marginale, décision user) ---------- */
.ligne-devis {
  text-align: center; color: var(--faint); font-size: 13.5px;
  padding: 34px 0 8px; border-top: 1px solid var(--line); margin-top: 20px;
}
.ligne-devis a { color: var(--muted); border-bottom: 1px solid var(--gold-line); }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .hero-contrat { grid-template-columns: 1fr; gap: 26px; padding: 28px 0 40px; }
  .releve { margin-top: 22px; }
  .releve-l { padding: 11px 0; }
  .releve-l dd .num { font-size: 23px; }
  .hero-contrat .cta-row { margin-top: 22px; }
  .hero-contrat .cta-note { margin-top: 12px; }
  .hero-contrat .hero-lede { font-size: 16.5px; margin-top: 18px; }
  /* ⚠️ L'APERÇU DOIT RESTER DANS LE PREMIER ÉCRAN (comme sur desktop, où il est
     en colonne à droite). Sans ce resserrement, il tombait sous la ligne de
     flottaison sur un téléphone de 390×844 : le titre, le paragraphe et le
     relevé mangeaient les 844 px. Mesuré : il démarrait à 912 px. */
  .hero-mock .mock-body { padding: 16px 16px 18px; }
  .ap-lignes { padding: 0 16px; }
  .ap-note { padding: 12px 16px 16px; }
  .ap-lignes li { padding: 8px 0; }
  .pain-grid { grid-template-columns: 1fr; border-top: 1px solid var(--ink); }
  .pain-item { border-right: 0; border-bottom: 1px solid var(--line); padding: 20px 0 22px; }
  .presta-item, .etapes li { grid-template-columns: 1fr; gap: 8px; }
  .exemples-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
  .hero-contrat { padding: 20px 0 32px; }
  /* ⚠️⚠️ LE RELEVÉ RESTE À DEUX COLONNES, COMME SUR PC (retour user :
     « inspire-toi de la version PC »). On l'avait empilé (libellé au-dessus de la
     valeur) : outre que ça ne ressemble plus au relevé de conditions du PC, ça
     coûtait 55 px de hauteur — exactement ce qui poussait l'action hors de
     l'écran. Libellé à gauche, valeur à droite : la grammaire du devis tient,
     même sur un petit écran.
     ⚠️ `max-content` pour la colonne des libellés, PAS une largeur en dur. Le
     plus long (« SI ÇA NE MARCHE PAS » en capitales espacées) mesure 159 px
     naturellement : avec 104 px fixes il se coupait sur deux lignes à TOUTES les
     largeurs (constaté jusqu'à 620 px). max-content le laisse sur une ligne tout
     en ne prenant que la place nécessaire, et la hauteur du relevé ne bouge pas
     (160 px, mesuré).
     ⚠️ La taille du h1 n'est PAS redéfinie ici (voir echelle.css). */
  .releve-l { grid-template-columns: max-content 1fr; gap: 12px; align-items: baseline; padding: 7px 0; }
  /* ⚠️ Interlettrage resserré à .07em SUR MOBILE UNIQUEMENT. À .13em (valeur
     desktop), le libellé « SI ÇA NE MARCHE PAS » occupe 159 px : combiné à
     max-content, il ne laisse plus assez de place à la valeur, qui passe de 2 à
     4 lignes. À .07em il reste une seule ligne de libellé ET la valeur tient en
     2-3 lignes : relevé 22 px plus court à 390 (mesuré), toujours sans coupure. */
  .releve-l dt { font-size: 10.5px; letter-spacing: .07em; }
  .releve-l dd { font-size: 14.5px; }
  .exemples-grid { grid-template-columns: 1fr; }
  .etapes li h3, .presta-item h3 { font-size: 18px; }
  .px-num { font-size: 42px; }
  .prix-bloc { padding: 26px 20px 22px; }
  /* ⚠️ L'ACTION RESTE SUR UNE LIGNE : bouton + lien côte à côte, comme sur PC.
     Un bouton pleine largeur suivi d'un lien en dessous fait deux lignes (90 px
     au lieu de 51) et éloigne le lien du bouton qu'il complète. Mesuré : on
     gagne 39 px, le bouton passe de 796 à 741 px sur un écran de 844. */
  .hero-contrat .cta-row { flex-direction: row; flex-wrap: nowrap; gap: 14px; }
  .hero-contrat .cta-row .btn { width: auto; padding: 14px 20px; }
  .hero-contrat .cta-alt { white-space: nowrap; font-size: 13.5px; }
  /* Sous 340 px (petits téléphones), deux colonnes dans le relevé deviennent
     trop serrées pour la valeur : on empile. Mesuré : 199 px de haut au lieu de
     160, donc on ne le fait que là où c'est nécessaire — pas à 360 px. */
}
@media (max-width: 340px) {
  .releve-l { grid-template-columns: 1fr; gap: 3px; padding: 6px 0; }
}

/* ============================================================
   PREMIER ÉCRAN — c'est ce qu'on voit en arrivant. Tout le peps est ici.

   Retour user : « je n'aime pas ce grand carré noir, l'important est ce qu'on
   voit dès qu'on arrive sur le site ».
   → le champ encre pleine page est supprimé ; l'intensité est concentrée sur le
   hero, et le fond du hero est un DÉGRADÉ (jamais un aplat : un aplat se lit
   comme un rectangle, un dégradé se lit comme une lumière).

   ⚠️ CONTRASTES CALCULÉS sur le bas du dégradé #241d14 (le plus clair, donc le
   pire cas) : paper #f7f4ee 13,7:1 · or #b08a3e 4,7:1 · or clair #d9b878 8,0:1.
   --muted et --gold-2 restent INTERDITS sur ce fond.
   ============================================================ */
.hero-contrat {
  position: relative;
  isolation: isolate;
  color: var(--paper);
  background:
    radial-gradient(1100px 520px at 82% 6%, rgba(176,138,62,.30), transparent 62%),
    radial-gradient(760px 420px at 4% 98%, rgba(176,138,62,.13), transparent 66%),
    linear-gradient(168deg, #191713 0%, #221b12 52%, #241d14 100%);
}
/* Le filet d'or : la signature de l'atelier, en haut du premier écran. */
.hero-contrat::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, var(--gold-2), var(--gold), #e9dcc0, var(--gold), var(--gold-2));
  z-index: 3;
}
.hero-contrat .hero-copy h1 { color: var(--paper); }
/* Les mots en OR italique : c'est la signature de la marque, elle doit être
   dans le premier écran. Sur encre, on éclaircit l'or (le dégradé d'origine
   #c9a457/#8a6a2a tombait à 3,5:1). */
.hero-contrat .hero-copy h1 .accent {
  background: linear-gradient(100deg, #f3dda4, #c19a4e 46%, #d9b878);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  font-style: italic; font-weight: 500;
}
.hero-contrat .hero-lede { color: var(--paper); opacity: .86; }
.hero-contrat .releve { border-top-color: rgba(247,244,238,.22); }
.hero-contrat .releve-l { border-bottom-color: rgba(247,244,238,.14); }
.hero-contrat .releve-l dt { color: var(--paper); opacity: .70; }
.hero-contrat .releve-l dd { color: var(--paper); }
.hero-contrat .releve-l dd .per { color: var(--paper); opacity: .70; }
.hero-contrat .cta-note { color: var(--paper); opacity: .70; }
.hero-contrat .cta-alt { color: var(--paper); border-bottom-color: rgba(247,244,238,.34); }
.hero-contrat .cta-alt:hover { color: #fff; border-bottom-color: var(--gold); }
.hero-contrat .btn.primary { background: var(--gold); border-color: var(--gold); color: #fff; }
.hero-contrat .btn.primary:hover { background: #c19a4e; border-color: #c19a4e; }

/* Le panneau d'aperçu : la seule surface claire du premier écran, donc le
   point où l'œil se pose. On le pose sur une ombre portée franche. */
.hero-contrat .hero-mock .mock-window {
  box-shadow: 0 34px 70px -34px rgba(0,0,0,.85), 0 0 0 1px rgba(233,220,192,.16);
}
.hero-contrat .hero-mock .mock-bar { background: #241d14; border-bottom-color: rgba(247,244,238,.12); }
.hero-contrat .hero-mock .mock-title { color: rgba(247,244,238,.74); }

/* ⚠️ SUR MOBILE AUSSI. Le hero est le seul endroit où le fond coloré paie : le
   canvas 3D y est désactivé (`.hero-3d{display:none}` sous 700px), donc sans ce
   bloc le téléphone n'aurait QUE du texte sur ivoire — exactement la platitude
   signalée. On garde le dégradé et on resserre les marges. */
@media (max-width: 900px) {
  .hero-contrat { padding: 30px 0 40px; }
}
@media (max-width: 620px) {
  .hero-contrat { padding: 24px 0 34px; }
  .hero-contrat::before { height: 2px; }
}

/* ============================================================
   PREMIER ÉCRAN — version claire (retour user : « moins sombre » et
   « sur les côtés il y a des espèces de barre noire très disgracieuses »).

   ⚠️ CE QUI CAUSAIT LES BARRES. Le fond débordait par
   `box-shadow: 0 0 0 100vmax <encre>` + `clip-path: inset(0 -100vmax)`. Or le
   `box-shadow` propage une COULEUR UNIE, jamais un dégradé : mesuré sur la
   capture, les 188 px de chaque côté du conteneur (1120 dans 1440) étaient de
   l'encre brute (25,23,19), sans les halos d'or. D'où deux bandes plates et
   sombres collées au contenu. Ces deux déclarations sont supprimées.

   Ici, le fond est plus CLAIR et n'a plus besoin de déborder : sur une page
   ivoire, un bloc de couleur à l'intérieur du conteneur est une pièce posée,
   pas une barre. Le débordement n'était nécessaire que parce que le hero était
   sombre.

   ⚠️ CONTRASTES (calculés, craft floor 4,5:1 mini) : encre #191713 sur les
   valeurs les plus sombres du dégradé ci-dessous —
      #f3ece0 15,3:1 · #ece1cf 14,1:1 · #e6d9c4 13,0:1 — tout est très au-dessus.
   ============================================================ */
.hero-contrat {
  background:
    radial-gradient(1020px 460px at 86% 4%, rgba(176,138,62,.26), transparent 60%),
    radial-gradient(700px 380px at 2% 100%, rgba(176,138,62,.12), transparent 64%),
    linear-gradient(158deg, #f3ece0 0%, #ece1cf 54%, #e6d9c4 100%);
  color: var(--ink);
  border-radius: 18px;
  border: 1px solid var(--gold-line);
  padding: 48px 44px 52px;
}
/* Le filet d'or reste : c'est la signature, et il se voit mieux sur clair. */
.hero-contrat::before {
  height: 3px;
  background: linear-gradient(90deg, var(--gold-2), var(--gold), #e9dcc0, var(--gold), var(--gold-2));
}
.hero-contrat .hero-copy h1 { color: var(--ink); }
/* Les mots en or reviennent au dégradé d'origine : sur clair il est nettement
   plus contrasté que sur encre (où il tombait à 3,5:1). */
.hero-contrat .hero-copy h1 .accent {
  background: linear-gradient(100deg, #c9a457, #8a6a2a, #b08a3e);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-contrat .hero-lede { color: var(--ink-2); opacity: 1; }
.hero-contrat .releve { border-top-color: var(--line); }
.hero-contrat .releve-l { border-bottom-color: var(--line); }
.hero-contrat .releve-l dt { color: var(--faint); opacity: 1; }
.hero-contrat .releve-l dd { color: var(--ink); }
.hero-contrat .releve-l dd .per { color: var(--muted); opacity: 1; }
.hero-contrat .cta-note { color: var(--faint); opacity: 1; }
.hero-contrat .cta-alt { color: var(--gold-2); border-bottom-color: var(--gold-line); }
.hero-contrat .cta-alt:hover { color: var(--gold-3); border-bottom-color: var(--gold); }

/* Le panneau d'aperçu : sur fond clair, il lui faut une ombre pour se détacher. */
.hero-contrat .hero-mock .mock-window {
  box-shadow: 0 30px 60px -30px rgba(25,23,19,.34), 0 0 0 1px rgba(25,23,19,.06);
}

@media (max-width: 900px) {
  .hero-contrat { padding: 34px 26px 38px; border-radius: 14px; }
}
@media (max-width: 620px) {
  .hero-contrat { padding: 26px 18px 30px; }
  .hero-contrat::before { height: 2px; }
}

/* ⚠️ CORRECTION DE CONTRASTE sur le fond clair. Mesure du pire cas (le point le
   plus sombre du dégradé, 226,211,183) : --faint tombait à 3,13:1 et --gold-2 à
   3,41:1, soit SOUS le seuil de 4,5:1 pour du texte courant. Sur l'ancien hero
   sombre c'était l'inverse (ces gris tenaient, les ors échouaient) : changer le
   fond a inversé le problème. On remonte les couleurs, on ne touche PAS au fond.
     --faint -> --muted      (3,78:1 mesure... encore juste)
     --muted -> #5c5443      (calculé >= 4,5:1 sur ce fond)
     --gold-2 -> --gold-3    #6e5320 (calculé >= 4,5:1)
*/
.hero-contrat .releve-l dt { color: #5c5443; }
.hero-contrat .releve-l dd .per { color: #5c5443; }
.hero-contrat .cta-note { color: #5c5443; }
.hero-contrat .cta-alt { color: #6e5320; border-bottom-color: var(--gold-line); }
.hero-contrat .cta-alt:hover { color: #4f3c17; border-bottom-color: var(--gold); }

/* ⚠️ CONTRASTE DU BOUTON. L'or de la marque (#b08a3e) donne 3,21:1 avec du texte
   blanc : insuffisant pour du texte de bouton (seuil 4,5:1). On descend d'un cran
   dans la rampe d'or existante (#8a6a2a = 5,03:1) : le bouton reste de la même
   famille, il est simplement lisible. Vérifié par calcul, pas à l'œil. */
.hero-contrat .btn.primary {
  background: linear-gradient(165deg, #9c7a33 0%, #8a6a2a 52%, #6e5320 100%);
  border-color: #6e5320;
  color: #fff;
}
.hero-contrat .btn.primary:hover {
  background: linear-gradient(165deg, #a8853a 0%, #93712e 52%, #775a23 100%);
  border-color: #775a23;
}

/* ============================================================
   MENU LATÉRAL — tenue « haut de gamme » (2026-09-30)

   ⚠️ Le tiroir listait 18 liens à plat : aucune hiérarchie, aspect catalogue.
   Le markup est maintenant en 5 destinations + 3 groupes repliés. Ici on donne
   la tenue qui manquait : largeur confortable, respiration, et une séparation
   nette entre l'action principale et le reste.
   ============================================================ */
.drawer { width: 380px; }
.drawer-nav { padding: 4px 18px 18px; }
.drawer-list { display: grid; gap: 2px; }
.drawer-list a {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-radius: 10px;
  font-size: 15.5px; color: var(--ink);
  text-decoration: none; transition: background .15s, color .15s;
}
.drawer-list a:hover { background: var(--paper); color: var(--gold-2); }
.drawer-list a.current { background: var(--gold-bg); color: var(--gold-2); font-weight: 500; }

/* L'action principale : plus haute, plus franche, séparée du reste. */
.drawer-cta { margin: 14px 18px 6px; padding: 15px 18px; font-size: 15.5px; }

/* Les groupes repliés : discrets, mais lisibles. */
.drawer-more { margin-top: 10px; border-top: 1px solid var(--line-soft); }
.drawer-more > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  cursor: pointer; list-style: none; padding: 13px 14px;
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); border-radius: 10px;
  transition: background .15s, color .15s;
}
.drawer-more > summary::-webkit-details-marker { display: none; }
.drawer-more > summary:hover { background: var(--paper); color: var(--ink); }
.drawer-more > summary svg { transition: transform .2s; }
.drawer-more[open] > summary svg { transform: rotate(180deg); }
.drawer-more .drawer-list { padding: 2px 0 8px; }

@media (max-width: 480px) { .drawer { width: 100%; max-width: 92vw; } }

/* ============================================================
   HERO — le double colonnage tient À TOUTES LES TAILLES (2026-09-30)

   Retour user : « la version PC est mieux ; sur la version mobile ajoute une
   image exemple dès le début sur la droite comme la version PC ».

   ⚠️ AVANT, sous 900px, `.hero-in` passait en UNE colonne : le titre, le
   paragraphe, le relevé ET les boutons s'empilaient avant que l'aperçu
   n'apparaisse. Le visiteur voyait donc du texte sur toute la hauteur utile
   avant la moindre démonstration.
   ⚠️ MAINTENANT : titre + aperçu restent côte à côte (le titre à gauche,
   l'aperçu à droite), même sur un téléphone. Le relevé et les boutons passent
   SOUS, sur toute la largeur. C'est le double colonnage du PC, conservé.
   ============================================================ */
.hero-haut {
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  gap: 40px;
  align-items: center;
}
.hero-titre { min-width: 0; }

/* L'aperçu de droite : sa propre ombre, il doit se détacher du dégradé. */
.hero-apercu-carte .mock-window {
  box-shadow: 0 30px 60px -30px rgba(25,23,19,.42), 0 0 0 1px rgba(25,23,19,.06);
}

/* Sous 1180px : les colonnes se resserrent mais ne disparaissent pas. */
@media (max-width: 1180px) {
  .hero-haut { grid-template-columns: 1fr 1fr; gap: 30px; }
}
/* Sous 900px (tablette) : on garde DEUX colonnes, plus compactes. */
@media (max-width: 900px) {
  .hero-haut { grid-template-columns: 1.05fr .95fr; gap: 22px; }
}
/* ⚠️ Sous 620px (téléphone) : on garde aussi les DEUX colonnes — c'est le point
   de la demande. Le titre se réduit, l'aperçu aussi, mais il reste À DROITE. */
@media (max-width: 620px) {
  .hero-haut { grid-template-columns: 1.1fr .9fr; gap: 16px; align-items: start; }
  .hero-contrat .hero-copy h1 { font-size: clamp(22px, 6.4vw, 28px); line-height: 1.1; }
  .hero-contrat .hero-lede { font-size: 14.5px; margin-top: 12px; }
  /* L'aperçu compact : on masque les lignes de détail, on garde le titre du
     site et la pastille « en construction ». L'essentiel se lit en un regard. */
  .hero-apercu-carte .ap-lignes { display: none; }
  .hero-apercu-carte .ap-note { display: none; }
  .hero-apercu-carte .mock-body { padding: 12px 12px 14px; }
  .hero-apercu-carte .apercu-bloc { padding: 0; }
  .hero-apercu-carte .ap-nom { font-size: 17px; }
  .hero-apercu-carte .ap-metier { font-size: 11.5px; }
  .hero-apercu-carte .ap-kicker { font-size: 9.5px; margin-bottom: 6px; }
  .hero-apercu-carte .mock-bar em { font-size: 9.5px; }
  .hero-apercu-carte .mock-bar span { width: 6px; height: 6px; }
  .hero-apercu-carte .mock-glow { display: none; }
}

/* ⚠️ Ajustement après check visuel : deux colonnes sur téléphone, c'est serré.
   On donne de l'air (gap) et on allège le panneau (il n'a plus besoin de son
   cadre de navigateur complet). */
@media (max-width: 620px) {
  .hero-haut { gap: 20px; }
  .hero-apercu-carte .mock-bar { display: none; }
  .hero-apercu-carte .mock-window { border-radius: 12px; }
  .hero-apercu-carte .mock-body { padding: 14px 13px 15px; }
  .hero-contrat .hero-copy h1 { font-size: clamp(21px, 6vw, 26px); }
  .hero-contrat .hero-lede { font-size: 14px; line-height: 1.55; margin-top: 10px; }
  .hero-contrat .releve { margin-top: 20px; }
  .hero-contrat .cta-row { margin-top: 18px; gap: 10px; }
  .hero-contrat .cta-row .btn { width: 100%; padding: 14px 18px; font-size: 15px; }
  .hero-contrat .cta-note { margin-top: 10px; font-size: 12.5px; }
}

/* ============================================================
   HERO — placement en GRILLE (2026-09-30, 2e correction)

   ⚠️ Ce que j'avais fait de travers : en forçant DEUX COLONNES à 390px, le titre
   n'avait plus que 163px de large et se cassait en 5 lignes, avec un aperçu de
   133px illisible. Mesure : titre 163px / 5 lignes, aperçu 133px. C'était laid, à
   juste titre.
   ⚠️ La demande était « un visuel tôt », pas « deux colonnes partout ». On passe
   donc à une GRILLE À ZONES :
     - desktop : [titre+suite] à gauche | [aperçu] à droite ;
     - mobile  : titre pleine largeur -> APERÇU PLEINE LARGEUR -> le reste.
   L'aperçu reste haut dans la page (c'est le but), mais il respire.
   ============================================================ */
.hero-contrat {
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  grid-template-areas:
    "titre  apercu"
    "suite  apercu";
  column-gap: 46px;
  row-gap: 0;
  align-content: center;
  align-items: start;
}
.hero-contrat > .hero-titre { grid-area: titre; }
.hero-contrat > .hero-apercu { grid-area: apercu; align-self: center; }
.hero-contrat > .hero-suite { grid-area: suite; }
.hero-contrat > .hero-3d { grid-area: 1 / 1 / -1 / -1; }
/* Le titre n'est plus dans un conteneur étroit : il respire. */
.hero-titre h1 { max-width: 15ch; }
.hero-suite .hero-lede { margin-top: 20px; }

/* ⚠️ Sous 900px : UNE colonne, titre puis aperçu PLEINE LARGEUR, puis le reste.
   L'aperçu remonte donc juste sous le titre, au lieu de tomber en bas de page. */
@media (max-width: 900px) {
  .hero-contrat {
    grid-template-columns: 1fr;
    grid-template-areas:
      "titre"
      "apercu"
      "suite";
    row-gap: 26px;
  }
  .hero-titre h1 { max-width: none; }
  .hero-apercu { max-width: 520px; margin: 0 auto; width: 100%; }
}
@media (max-width: 620px) {
  .hero-contrat { row-gap: 22px; padding: 26px 18px 32px; }
  /* ⚠️⚠️ NE PAS REDÉFINIR LA TAILLE DU h1 ICI.
     Elle vivait aux deux endroits (ici : clamp(29, 8.4vw, 38) ; dans
     echelle.css : 30px puis écrasé par un 27px !important). Comme echelle.css
     est chargé EN DERNIER, c'est lui qui gagne : cette règle ne servait à rien
     et faisait croire à une échelle qu'on n'avait pas. La taille du titre
     d'accueil est définie UNE fois, dans echelle.css (bloc ACCUEIL).
     Idem pour .hero-lede : même fichier gagnant. */
  .hero-su .hero-lede, .hero-contrat .hero-lede { font-size: 16px; margin-top: 0; }
  .hero-apercu { max-width: none; }
  /* L'aperçu pleine largeur : on peut remettre les détails, il y a la place. */
  .hero-apercu .ap-lignes { display: block; padding: 0 16px; }
  .hero-apercu .ap-note { display: block; padding: 12px 16px 16px; }
  .hero-apercu .mock-bar { display: flex; }
  .hero-apercu .ap-nom { font-size: 19px; }
  .hero-apercu .ap-metier { font-size: 13px; }
}

/* ============================================================
   PAGES LOCALES ARTISAN — /services/<metier>/<departement> (2026-10-01)

   Les villes réelles du département. C'est la matière locale qui distingue
   une page d'une autre : un artisan se reconnaît dans « Villeurbanne »,
   pas dans un texte générique. Liste sobre, sans carte ni icône (craft floor).
   ============================================================ */
.zone-villes {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 18px;
}
.zone-ville {
  font-family: var(--font-mono, var(--font-sans));
  font-size: 12.5px; letter-spacing: .02em;
  color: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 12px;
  background: var(--card);
}
.zone-ville.zone-plus {
  color: var(--faint);
  border-style: dashed;
  background: transparent;
}
@media (max-width: 620px) {
  .zone-villes { gap: 6px; }
  .zone-ville { font-size: 12px; padding: 5px 10px; }
}


/* ============================================================
   EX-echelle.css   (37334 octets, 15 !important)
   ============================================================ */

/* ============================================================
   ÉCHELLE UNIQUE — espaces et texte (2026-09-30)

   ⚠️ POURQUOI CE FICHIER. Mesure du site avant : les sections portaient CINQ
   hauteurs de padding différentes (30/30, 64/72, 44/44, 34/34, 0/0) et le corps
   de texte était à 13 px dans 59 cas, 14 px dans 41, 15 px dans 34. Aucun
   rythme commun : c'est ce qui donne l'impression d'un site assemblé plutôt que
   dessiné, et 13 px est en dessous du confort de lecture (16 px).

   Ce fichier est chargé EN DERNIER : il normalise, il ne redessine pas.
   Il ne touche PAS l'application connectée (`body.app-mode`) ni les sites
   clients, qui ont leur propre monde.

   Échelle typographique (desktop) :
     h1 56 · h2 38 · h3 20 · corps 16 · petit 14 · micro 12.5
   Échelle d'espacement (multiple de 4) :
     --e1 8 · --e2 16 · --e3 24 · --e4 32 · --e5 48 · --e6 64
   ============================================================ */

:root {
  --e1: 8px;  --e2: 16px; --e3: 24px; --e4: 32px; --e5: 48px; --e6: 64px;
  --lh-corps: 1.65;
  /* Hauteur de section : UNE seule valeur, desktop et mobile. */
  --sec-pad: 64px;
}
@media (max-width: 900px) { :root { --sec-pad: 48px; } }
@media (max-width: 620px) { :root { --sec-pad: 40px; } }

/* ---------- 1. Rythme vertical des sections ---------- */
/* Hors accueil (qui a sa propre composition) et hors application.
   ⚠️ `.section` SANS préfixe d'élément : les pages n'utilisent pas toutes
   `<section>`. `/prix`, `/resultats`, `/logiciel-devis` et `/a-propos` sont en
   `<div class="section">` — un sélecteur `section.section` les ratait, ce qui
   laissait ces pages sur l'ancien rythme irrégulier. */
body:not(.app-mode) .section { padding-top: var(--sec-pad); padding-bottom: var(--sec-pad); }
body:not(.app-mode) .section-head { margin-bottom: var(--e4); }
body:not(.app-mode) .section-head h2 { margin-bottom: var(--e1); }
body:not(.app-mode) .cta-final { padding-top: var(--e6); padding-bottom: var(--e6); }

/* ---------- 2. Corps de texte : 16 px minimum ---------- */
/* ⚠️ On cible le CONTENU ÉDITORIAL, pas les contrôles : un champ de formulaire,
   un libellé de bouton ou une cellule de tableau garde sa taille. Monter tout à
   16 px casserait le builder et les tableaux de prix. */
body:not(.app-mode) p,
body:not(.app-mode) .section-head p,
body:not(.app-mode) .feature p,
body:not(.app-mode) .pain-item p,
body:not(.app-mode) .step p,
body:not(.app-mode) .faq-acc-body p,
body:not(.app-mode) .other-trades a {
  font-size: 16px;
  line-height: var(--lh-corps);
}
/* Les blocs secondaires (mentions, notes) restent plus petits, mais lisibles. */
body:not(.app-mode) .note,
body:not(.app-mode) .tnote,
body:not(.app-mode) .small,
body:not(.app-mode) .footer p { font-size: 14px; }

/* Mesure de lecture : jamais au-delà de 72 caractères. */
body:not(.app-mode) .section-head p,
body:not(.app-mode) .section-head h2 { max-width: 72ch; }
body:not(.app-mode) .section-head { max-width: none; }

/* ---------- 3. Filets et profondeur : une seule grammaire ---------- */
/* Le site mêlait ombres douces et filets d'un pixel. On garde les filets. */
body:not(.app-mode) .feature,
body:not(.app-mode) .plan,
body:not(.app-mode) .chip {
  border-radius: 10px;
}

/* ---------- 4. Micro-détails : ce qui trahit une page assemblée ---------- */
/* Sélection, caret, barre de défilement : hérités du navigateur, ils ne
   connaissent pas la palette. Les thème fait la différence entre « construit »
   et « assemblé ». */
body:not(.app-mode) ::selection { background: var(--gold-soft); color: var(--ink); }
body:not(.app-mode) { caret-color: var(--gold-2); }
body:not(.app-mode) { scrollbar-color: var(--line) var(--paper); }
body:not(.app-mode) a { text-underline-offset: 3px; }
body:not(.app-mode) :focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
/* ============================================================
   CHAMP ENCRE — la couleur s'engage à l'échelle de la page

   ⚠️ MESURE AVANT : la page n'avait qu'UN SEUL fond du haut en bas (ivoire).
   D'où « assez plate, manque de peps ». Le correctif n'est pas plus d'effets :
   c'est de donner à certaines régions TOUTE la couleur, et de laisser les autres
   respirer. « Commit, then clarify » : on affirme un champ, puis on calme tout
   autour pour qu'il se lise.

   ⚠️ CONTRASTES CALCULÉS sur #191713 (la craft floor exige 4,5:1 mini) :
      blanc 17,90 · paper 16,30 · paper-2 14,93 · or-éclairci #d9b878 9,44 ·
      or #b08a3e 5,58 — TOUS OK.
      --muted (3,21) et --gold-2 (3,56) sont INTERDITS sur ce champ : ne jamais
      les y employer pour du texte.
   ============================================================ */
.champ-encre {
  background: var(--ink);
  color: var(--paper);
  /* On prolonge la couleur sur toute la largeur de la fenêtre alors que le
     contenu reste dans le conteneur : sinon le champ s'arrête au bord du texte
     et la page paraît « encadrée » plutôt que possédée. */
  box-shadow: 0 0 0 100vmax var(--ink);
  clip-path: inset(0 -100vmax);
}
.champ-encre .section-head h2 { color: var(--paper); }
.champ-encre .section-head p { color: var(--paper); opacity: .82; }
/* Les filets étaient pensés pour l'ivoire : sur l'encre, ils disparaissent. */
.champ-encre .presta { border-top-color: rgba(247, 244, 238, .28); }
.champ-encre .presta-item { border-bottom-color: rgba(247, 244, 238, .14); }
.champ-encre .presta-item h3 { color: var(--paper); }
.champ-encre .presta-item p { color: var(--paper); opacity: .82; }

/* Le champ de l'action finale : même grammaire, plus compact, bouton en or
   (la seule couleur qui tienne sur l'encre). */
.cta-final.champ-encre { padding: 72px 0; margin-top: 0; }
.cta-final.champ-encre h2 { color: var(--paper); }
.cta-final.champ-encre p { color: var(--paper); opacity: .84; }
.champ-encre .btn.primary { background: var(--gold); color: #fff; border-color: var(--gold); }
.champ-encre .btn.primary:hover { background: #c19a4e; border-color: #c19a4e; }

/* ⚠️ MOBILE : le champ encre est ce qui donne du peps sur petit écran, là où
   l'effet 3D du hero n'est pas rendu. On garde toute la largeur utile et on
   resserre seulement les marges intérieures. */
@media (max-width: 620px) {
  .cta-final.champ-encre { padding: 52px 0; }
  .champ-encre .presta-item { padding: 20px 0; }
}

/* ============================================================
   /leads — le prix en clair, plus de question de budget (2026-09-30)

   ⚠️ Le formulaire demandait « Budget envisagé » de « moins de 500 € » à « plus
   de 3 000 € » alors qu'il n'y a QU'UNE offre au prix affiché. La question
   laissait croire qu'on allait négocier, et qu'on payait ce qu'on annonçait.
   Retirée ; le bloc ci-dessous dit le prix une fois, nettement.
   ============================================================ */
.lead-offre {
  padding: 22px 24px; margin: 0 0 26px;
  background: var(--card); border: 1px solid var(--gold-line);
  border-left: 3px solid var(--gold); border-radius: 0 12px 12px 0;
}
.lo-prix { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.lo-num { font-family: var(--font-mono); font-size: 38px; font-weight: 500;
  letter-spacing: -.03em; color: var(--ink); line-height: 1; }
.lo-per { color: var(--muted); font-size: 15px; }
.lo-detail { margin: 10px 0 0; font-size: 14px; color: var(--muted); line-height: 1.6; }

.lead-etapes { margin: 26px 0 0; padding-top: 22px; border-top: 1px solid var(--line); display: grid; gap: 12px; }
.le-item { display: flex; align-items: baseline; gap: 12px; font-size: 15px; color: var(--ink-2); line-height: 1.55; }
.le-n {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  background: var(--gold-bg); border: 1px solid var(--gold-line); color: var(--gold-2);
  font-family: var(--font-mono); font-size: 12px; font-weight: 500;
  display: grid; place-items: center;
}
@media (max-width: 620px) { .lo-num { font-size: 32px; } }

/* ============================================================
   POLICE D'AFFICHAGE — bascule Fraunces -> Bodoni Moda (2026-09-30)
   Decision user. Bodoni = lignee Didot, luxe francais.
   ⚠️ Chargé en DERNIER : on redéfinit la VARIABLE, donc tous les endroits qui
   utilisent var(--font-serif) basculent d'un coup, sans toucher au reste.
   On garde une petite respiration (letter-spacing) et un poids 600 : Bodoni a
   un contraste plein/degage fort, il aime l'air autour de lui.
   ============================================================ */
/* ============================================================
   ⚠️⚠️ IDENTITÉ TYPOGRAPHIQUE — SOURCE UNIQUE.
   Ce bloc écrasait `--font-serif` (déclaré en Fraunces dans luxe.css) par
   'Bodoni Moda'. Deux feuilles, deux polices : la moitié du site s'affichait
   en Fraunces, l'autre en Bodoni — et les pages de vente en Anton. Trois
   identités pour un seul site.

   Ligne directrice retenue (VALIDÉE par le user sur la maquette blanche) :
     --font-serif : Anton    -> TOUS les titres
     --font-sans  : Archivo  -> TOUT le texte
     --font-mono  : IBM Plex Mono -> étiquettes, prix, chiffres
   Ne JAMAIS redéclarer ces trois variables ailleurs : modifier ICI.
   ============================================================ */
:root {
  --font-serif: 'Anton', 'Archivo', system-ui, sans-serif;
  --font-sans: 'Archivo', system-ui, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
}
/* ⚠️ Réglages conservés (ils valent aussi pour Anton), mais la FAMILLE vient
   de la variable unique : plus aucune police écrite ici. */
h1, h2, .hero h1, .page-head h1, .section-head h2 {
  font-family: var(--font-serif);
  letter-spacing: -.012em;
  line-height: 1.02;
}
.hero h1, .hero-contrat .hero-copy h1 { letter-spacing: -.02em; line-height: 1.04; }

/* Le mot en or, en italique : Bodoni italique est spectaculaire ; on garde le
   degrade d'or de la charte. */
.hero h1 .accent, .hero-contrat .hero-copy h1 .accent, .page-head h1 .accent {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
}

/* ============================================================
   RYTHME VISUEL DES SECTIONS — le fond alterné ne produisait RIEN (2026-09-30)

   ⚠️ MESURE : la page mobile faisait 8 023px de haut avec TOUTES les sections sur
   le même fond (transparent -> ivoire unique). Les sections portaient bien la
   classe `alt` dans le HTML, mais AUCUNE règle CSS ne la stylait : `.alt` était
   défini pour un tout autre usage (une ligne de mentions centrée, ligne 1361 de
   luxe.css). Résultat : 8 000px d'ivoire uniforme, seul le hero (dégradé) et le
   bloc de fin créaient du relief. C'est exactement ce qui fait « fade et sans
   consistance ».
   ⚠️ On ne touche PAS à `.alt` (utilisé ailleurs) : on cible `.section.alt`,
   spécifique aux sections.
   ============================================================ */
.section.alt {
  background: var(--paper-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
/* Sur l'accueil, les sections de contenu portent un filet haut discret : ça
   donne un rythme de lecture même quand le fond ne change pas. */
body:not(.app-mode) .section + .section { border-top: 1px solid var(--line); }
body:not(.app-mode) .section.alt + .section,
body:not(.app-mode) .section + .section.alt { border-top: 0; }

/* ⚠️ Le hero mobile était très long (1222px). On resserre : le visiteur doit
   atteindre le prix et l'action sans scroller deux écrans. */
@media (max-width: 620px) {
  .hero-contrat { row-gap: 18px; }
  .hero-contrat .releve { margin-top: 16px; }
  .hero-contrat .cta-note { max-width: none; }
}

/* ============================================================
   RATTRAPAGE DE L'ÉCHELLE (2026-09-30, audit CSS)

   ⚠️ L'audit a mesuré que le barème 56/38/20/16 n'était JAMAIS respecté
   simultanément sur une page : h1 = 2 valeurs (34/56), h2 = 3 (27/36/38),
   h3 = 5 (16.5/18/20/22/23), corps = 5 (13/14/15/16/18). La cause : mon
   echelle.css normalisait par ÉNUMÉRATION de sélecteurs, donc il perdait contre
   les sélecteurs #id et les styles inline.
   ⚠️ On rattrape les cas MESURÉS, on ne réécrit pas tout : chaque ligne
   ci-dessous corrige une valeur relevée par l'audit.
   ============================================================ */

/* h1 : /artisan était à 34px. On l'aligne sur le barème. */
@media (min-width: 601px) { .artisan-hero h1 { font-size: 48px; line-height: 1.08; } }

/* h2 : trois valeurs hors barème (27/36/38). On les ramène à 38px. */
.cta-final h2 { font-size: clamp(30px, 3.4vw, 38px); }
.visi-block h2 { font-size: clamp(26px, 2.9vw, 36px); }

/* h3 : cinq valeurs (16.5/18/20/22/23). Le barème est 20px, sauf les titres de
   cartes d'accueil qui montent à 22 (choix assumé, contraste utile). */
.step h3 { font-size: 20px; }
.faq-item h3 { font-size: 20px; }
.feature h3 { font-size: 20px; }
#cout-verite .dual-plan h3 { font-size: 20px; }

/* ⚠️ Le corps : mon echelle.css ne normalisait que des <p> ÉNUMÉRÉS, jamais le
   corps global (mesuré à 15px). On pose le corps une fois pour toutes. */
body:not(.app-mode) { font-size: 16px; line-height: 1.65; }

/* ⚠️ Les 101 déclarations `font-size` INLINE des templates (26×13px, 21×14px,
   14×12px) battent toute feuille de style. On ne peut pas les neutraliser
   proprement sans toucher aux templates ; on remonte donc les zones concernées
   par une règle ciblée, là où le texte est du CONTENU et non un libellé. */
.pricing-page .section p, .results-page .section p,
.software-page .section p, .about-page .section p,
.howto-page .section p { font-size: 16px; }

/* Les deux cas d'accueil hors barème (sélecteurs #id, plus forts que tout) :
   on les remonte explicitement, au lieu de subir la cascade. */
#probleme .pain-item p { font-size: 16px; }

/* ============================================================
   CONTRASTES DE LA PALETTE OR — correction systémique (2026-09-30)

   ⚠️ L'audit a mesuré, et je l'ai vérifié par calcul :
     - bouton principal (blanc sur dégradé or) : 2,35:1  -> seuil 4,5
       le pire arrêt est #c9a457 ; il apparaît 72 fois sur le site
     - le mot en or sur ivoire : 2,14:1 -> seuil 3,0 (grand texte)
   Un bouton illisible, c'est la vente perdue. Ce n'est pas un détail esthétique.

   ⚠️ CE QU'ON FAIT : on ne change PAS la teinte (l'or de la marque reste l'or),
   on descend d'un cran dans la rampe existante pour que le texte blanc tienne.
   Vérifié : #8a6a2a donne 5,03:1 avec du blanc, #6e5320 donne 7,19:1.
   ============================================================ */

/* Le bouton principal : dégradé assombri. Le pire arrêt (#8a6a2a) est à 5,03:1. */
.btn.primary {
  background: linear-gradient(165deg, #8a6a2a 0%, #7d5f26 52%, #6e5320 100%);
  border-color: #6e5320;
  color: #fff;
}
.btn.primary:hover {
  background: linear-gradient(165deg, #97752f 0%, #8a6a2a 52%, #775a23 100%);
  border-color: #775a23;
}
/* Le bouton « big » du hero garde sa taille : seul le contraste change. */

/* ⚠️ Les boutons OR PLEIN dans les encadrés (visibilite, leads, pricing) : ils
   portaient `background: var(--gold)` = 3,21:1. Alignés sur le dégradé. */
.visi-card .btn.primary, .lead-form-wrap .btn.primary, .plan.featured .btn.primary {
  background: linear-gradient(165deg, #8a6a2a, #6e5320);
  border-color: #6e5320;
}

/* ⚠️ Le mot en or des titres : le dégradé d'origine partait de #c9a457 (2,14:1
   sur ivoire). On part d'un or plus profond, qui reste lumineux en grand texte
   tout en passant le seuil de 3:1. */
.hero h1 .accent, .page-head h1 .accent {
  background: linear-gradient(110deg, #8a6a2a 0%, #6e5320 55%, #8a6a2a 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* Sur les surfaces SOMBRES (hero encre), l'or clair reste lisible : on garde. */
.hero-contrat .hero-copy h1 .accent {
  background: linear-gradient(100deg, #f3dda4, #c19a4e 46%, #d9b878);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* Le badge « Le moins cher du marché » : blanc sur or clair = 2,63:1. */
.plan .tag {
  background: linear-gradient(165deg, #8a6a2a, #6e5320);
  color: #fff;
}

/* ============================================================
   CONTRASTES — 2e passe : les règles qui gagnaient encore (2026-09-30)

   ⚠️ Ma 1re passe a corrigé 72 boutons sur 76, mais 4 résistaient : les
   sélecteurs plus SPÉCIFIQUES de atelier-polish.css (chargé après luxe.css)
   redéfinissaient l'or clair :
     - `#pricing-home .plan .tag:not(:empty)` (badge « Le moins cher ») : #c19a4e
     - `#pricing-home .plan .tag` : idem
     - `.plan.featured .tag` : idem
   Et un `.btn.primary` de l'accueil gardait l'ancien dégradé.
   On reprend la main avec la MÊME spécificité, en fin de cascade.
   ============================================================ */

/* Les badges d'offre : dégradé assombri (blanc dessus >= 4,5:1). */
.plan.featured .tag,
#pricing-home .plan .tag:not(:empty),
#pricing-home .plan .tag {
  background: linear-gradient(160deg, #8a6a2a, #6e5320);
  color: #fff;
  box-shadow: 0 2px 8px rgba(110, 83, 32, .3);
}

/* Le bouton principal : on reprend la main sur TOUTE la page, y compris dans les
   blocs partagés (_visibilite_block, pricing-home) qui le redéfinissaient. */
body:not(.app-mode) .btn.primary {
  background: linear-gradient(165deg, #8a6a2a 0%, #7d5f26 52%, #6e5320 100%) !important;
  border-color: #6e5320 !important;
  color: #fff !important;
}
body:not(.app-mode) .btn.primary:hover {
  background: linear-gradient(165deg, #97752f 0%, #8a6a2a 52%, #775a23 100%) !important;
  border-color: #775a23 !important;
}

/* ============================================================
   VIGNETTES D'EXEMPLE CLIQUABLES (2026-09-30)

   ⚠️ Les 3 exemples de sites étaient des IMAGES non cliquables : un artisan ne
   pouvait pas aller voir le vrai site. Or c'est ce qui vend — voir la page
   vivante, avec son calculateur et son formulaire. La vignette entière est
   maintenant un lien vers l'aperçu réel, en nouvel onglet.
   ⚠️ On n'ouvre PAS dans le même onglet : le visiteur qui part voir un exemple
   ne doit pas perdre la page de vente.
   ============================================================ */
.proof-lien, .exemple-lien {
  display: block; position: relative; text-decoration: none; color: inherit;
}
.proof-lien img, .exemple-lien img { display: block; width: 100%; height: auto; }
/* La pastille d'action : apparaît discrètement, dit ce que fait le clic. */
.proof-voir, .ex-voir {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  background: var(--ink); color: #fff; font-size: 12.5px; font-weight: 500;
  letter-spacing: .02em; padding: 9px 16px; border-radius: 30px;
  white-space: nowrap; opacity: 0; transition: opacity .18s, transform .18s;
}
.proof-lien:hover .proof-voir, .exemple-lien:hover .ex-voir,
.proof-lien:focus-visible .proof-voir, .exemple-lien:focus-visible .ex-voir {
  opacity: 1; transform: translateX(-50%) translateY(-3px);
}
/* Sur tactile il n'y a pas de survol : la pastille reste visible. */
@media (hover: none) {
  .proof-voir, .ex-voir { opacity: 1; transform: translateX(-50%); }
}
.proof-lien:focus-visible, .exemple-lien:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 3px; }
/* Le cadre de la carte s'applique au lien, pas plus à la figure seule. */
.proof-card:has(.proof-lien) { overflow: hidden; }

/* ============================================================
   /leads SUR MOBILE — le formulaire AVANT les arguments
   (2026-09-30, carte blanche)

   ⚠️ MESURE : sur mobile la page faisait 3 311 px (2x le PC) et le formulaire
   arrivait APRES 981 px de blocs de bénéfices. Un artisan qui arrive sur la page
   depuis un email devait donc dérouler deux écrans d'argumentaire avant de
   pouvoir demander quoi que ce soit. C'est l'inverse de l'ordre qui convertit.

   ⚠️ On inverse l'ordre À L'ÉCRAN seulement (CSS `order`), pas dans le DOM : le
   HTML garde la lecture « arguments puis formulaire » pour les moteurs, et
   l'humain sur téléphone voit d'abord ce qui l'actionne.
   ============================================================ */
@media (max-width: 760px) {
  /* Le formulaire d'abord, les arguments ensuite. */
  .lead-layout { display: flex; flex-direction: column; gap: 26px; }
  .lead-form-wrap { order: 1; }
  .lead-benefits { order: 2; }

  /* L'argumentaire est plus court : on retire l'air entre les blocs et on
     resserre chaque bloc — ce sont des rappels, pas la lecture principale. */
  .lead-benefits h3 { font-size: 17px; margin-bottom: 12px; }
  .lead-benefit { padding: 11px 0; }
  .lead-benefit strong { font-size: 15.5px; }
  .lead-benefit p { font-size: 14.5px; }
  .lead-offre { padding: 16px 18px; margin-bottom: 18px; }
  .lo-num { font-size: 30px; }
  .lead-etapes { padding-top: 16px; margin-top: 18px; }
  .le-item { font-size: 14.5px; }
  .lead-note { font-size: 13.5px; padding: 12px 14px; }

  /* Le formulaire : champs plus courts, et le titre rappelle l'action. */
  .lead-form-wrap h3 { font-size: 19px; margin-bottom: 14px; }
  .lead-form label { margin: 11px 0 5px; }
  .lead-form input, .lead-form select, .lead-form textarea { padding: 12px; font-size: 16px; }
  .lead-form textarea { min-height: 80px; }

  /* L'accroche : plus courte sur téléphone. */
  .lead-hero { padding: 26px 0 20px; }
  .lead-hero h1 { font-size: 28px; line-height: 1.08; }
  .lead-hero p { font-size: 15.5px; }
}

/* ============================================================
   MOBILE — L'ACTION DANS LE PREMIER ÉCRAN (carte blanche 2026-09-30)

   ⚠️ MESURE : sur l'accueil, le premier bouton était à 1 076 px — hors d'un
   écran de 844. Le hero faisait 1 203 px. Sur /visibilite, le bouton de
   commande était à 2 374 px, parce que la PREUVE (1 317 px) passait avant le
   calculateur et le paiement. Un visiteur ne peut rien faire sans dérouler.
   On remet l'action avant le récit.
   ============================================================ */
@media (max-width: 760px) {
  /* --- ACCUEIL : hero plus court, le relevé et les boutons remontent --- */
  .hero-contrat { padding: 26px 16px 30px; }
  /* ⚠️⚠️ TAILLE DU TITRE D'ACCUEIL — SOURCE UNIQUE, ICI.
     Ne pas la redéfinir dans accueil-contrat.css : echelle.css est chargé EN
     DERNIER, donc c'est cette valeur qui gagne, et deux valeurs concurrentes
     finissent toujours par diverger (c'est ce qui avait produit un h1 à 27 px
     face à des h2 à 25,4 px — le titre de page à la taille d'un titre de
     section, ce que le user a vu tout de suite).
     Mesuré sur un 390 px : 32 px tient sur 3 lignes (34 px en fait 4).
     clamp(30, 8.2vw, 40) => 32 px à 390, 40 px dès 488 px. Il n'y a donc plus
     de palier à 27 px sur une plage de largeurs. */
  .hero-titre h1 { font-size: clamp(30px, 8.2vw, 40px); line-height: 1.05; letter-spacing: -.022em; }
  /* Le titre respire : plus d'air AU-DESSUS que SOUS lui (craft floor). */
  .hero-contrat .hero-titre { padding-top: 6px; }
  .hero-su .hero-lede, .hero-contrat .hero-lede { font-size: 15px; margin-top: 10px; }
  .hero-contrat .releve { margin-top: 16px; }
  .hero-contrat .releve-l { padding: 9px 0; }
  .hero-contrat .releve-l dd .num { font-size: 22px; }
  .hero-contrat .cta-row { margin-top: 16px; gap: 9px; }
  .hero-contrat .cta-note { margin-top: 10px; font-size: 12.5px; }
  /* ⚠️ L'APERÇU GARDE LES 4 LIGNES DE PRIX SUR MOBILE (retour user : « inspire-toi
     de la version PC »). Les masquer faisait perdre exactement ce qui convainc —
     un vrai exemple avec ses tarifs, la preuve que le visiteur peut lire avant
     d'appeler. Seule la note de bas de panneau reste masquée (le sur-titre du
     panneau dit déjà que c'est un exemple), et les lignes sont resserrées pour
     que le bouton reste dans le premier écran. */
  .hero-apercu .ap-lignes { display: block; }
  .hero-apercu .ap-lignes li { padding: 6px 0; }
  .hero-apercu .ap-note { display: none; }
  .hero-apercu .mock-body { padding: 13px 14px 12px; }
  .hero-apercu .ap-nom { font-size: 18px; }

  /* --- /VISIBILITE : le calculateur et la commande AVANT la preuve ---
     ⚠️ Ordre inversé à l'ECRAN (CSS order), pas dans le DOM : le HTML garde
     « hero » puis la commande pour les moteurs, et l'humain sur téléphone voit
     d'abord ce qui lui permet d'agir. */
  .visi-tunnel { display: flex; flex-direction: column; }
  .visi-hero { order: 1; }
  .visi-whats-included { order: 2; }
  .visi-layout { order: 3; }
  .visi-calc { order: 4; }
  .visi-proof { order: 5; }

  /* La preuve sur mobile : elle était en 1 colonne sur 1 317 px. On passe en
     grille 2 colonnes, plus courte. */
  .visi-proof { margin: 24px 0 10px; }
  .visi-proof-head h2 { font-size: 21px; }
  .visi-proof-head p { font-size: 14.5px; }
  .visi-proof-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
  .visi-proof-grid .proof-card-lead { grid-column: 1 / -1; }
  .visi-proof-grid .proof-card-lead img { max-height: 200px; }
  .proof-card img { max-height: 130px; object-fit: cover; object-position: top; }
  .proof-card figcaption { padding: 10px 12px; }
  .proof-name { font-size: 14.5px; }
  .proof-desc { font-size: 12px; }
  .visi-proof-note { font-size: 12.5px; margin-top: 12px; }
  /* L'argumentaire du calculateur : plus court. */
  .visi-calc { padding: 22px 18px; gap: 20px; }
  .visi-calc h2 { font-size: 21px; }
  .visi-calc-copy p { font-size: 14.5px; }
  .visi-calc-points li { font-size: 13.5px; }
}

/* ============================================================
   /visibilite + /leads — l'ACTION vraiment dans le premier écran
   (carte blanche, suite 2026-09-30)

   ⚠️ Mesure après la 1re passe : /visibilite avait encore son bouton de commande
   à 2 140 px, parce que la FAQ « vos questions avant de commander » (909 px)
   passait AVANT la carte de paiement. Sur /leads, le bouton était à 979 px :
   6 champs remplis avant de pouvoir envoyer.
   ============================================================ */
@media (max-width: 760px) {
  /* --- /visibilite : la carte de paiement remonte AVANT la FAQ --- */
  .visi-guide { order: 2; }
  .visi-card { order: 1; }
  .visi-layout { gap: 24px; }
  /* La FAQ : repliable et compacte (c'est de la levée d'objection, pas de la
     lecture principale). */
  .visi-guide-block { margin-bottom: 22px; }
  .visi-guide-title { font-size: 18px; margin-bottom: 12px; }
  .visi-q summary { font-size: 14px; padding: 11px 0; }
  .visi-q p { font-size: 13.5px; padding-bottom: 12px; }
  .visi-reassure li { font-size: 13.5px; padding: 6px 0; }
  .visi-steps-guide li { padding: 9px 0; }
  .visi-steps-guide p { font-size: 13.5px; }
  /* La carte de paiement : champs plus courts. */
  .visi-summary { padding: 20px 18px; }
  .visi-list li { padding: 8px 0; font-size: 14px; }
  .visi-price-major { font-size: 34px; }
  .visi-pay { padding-top: 14px; }
  .visi-pay input { padding: 12px; font-size: 16px; }

  /* --- /leads : le bouton visible sans remplir les 6 champs ---
     ⚠️ On ne peut pas supprimer des champs (ils sont nécessaires à la
     qualification), mais on peut les RESSERRER : c'est la hauteur des champs et
     l'air entre eux qui repoussait le bouton à 979 px. */
  .lead-form label { margin: 8px 0 4px; font-size: 11px; }
  .lead-form input, .lead-form select, .lead-form textarea { padding: 10px 12px; }
  .lead-form textarea { min-height: 62px; }
  .consent-box { padding: 10px 12px; margin-top: 10px; }
  .consent-label { font-size: 12px; line-height: 1.45; }
  .lead-form button[type=submit] { padding: 15px; font-size: 15.5px; margin-top: 12px !important; }
  .lead-form .ftiny, .lead-privacy { font-size: 11.5px; }
  .lead-form-wrap h3 { margin-bottom: 10px; }
}

/* ⚠️ Dernier resserrement. Mesure : la carte de paiement de /visibilite fait
   961 px — sa liste de 6 avantages + le bloc email. Le bouton tombait à 1 289.
   Sur /leads le bouton est à 940 avec 6 champs + le consentement.
   On réduit l'AIR (pas la hauteur des champs, qui doit rester tapable) :
   la liste des avantages devient une grille 2 colonnes compacte, et les
   libellés passent en 2 colonnes quand c'est possible. */
@media (max-width: 760px) {
  /* /visibilite : avantages de la carte de paiement en 2 colonnes serrées. */
  .visi-list { display: grid; grid-template-columns: 1fr; gap: 0; margin: 12px 0 0; }
  .visi-list li { padding: 6px 0; font-size: 13.5px; border-bottom: 1px solid var(--line-soft); }
  .visi-summary { padding: 18px 16px; }
  .visi-top { margin-bottom: 8px; }
  .visi-price-major { font-size: 30px; }
  .visi-badges { margin-top: 8px; }
  .visi-badge { font-size: 11px; padding: 3px 10px; }
  .visi-separator { margin: 12px 0; }
  .visi-pay-title { font-size: 13px; }
  .visi-note { font-size: 12px; margin-bottom: 8px; }
  .visi-consent { font-size: 12px; line-height: 1.4; }
  .visi-tiny { font-size: 11px; margin-top: 8px; }
  .visi-alt { font-size: 12px; padding-top: 12px; margin-top: 12px; }
  .visi-card .btn.primary.big { padding: 15px; font-size: 15.5px; }

  /* /leads : le consentement et le code promo passent côte à côte. */
  .lead-form label { margin: 7px 0 3px; }
  .lead-form input, .lead-form select { padding: 9px 11px; }
  .lead-form textarea { min-height: 56px; padding: 9px 11px; }
  .consent-box { padding: 9px 11px; }
  .lead-form button[type=submit] { padding: 14px; margin-top: 10px !important; }
  .lead-form .ftiny { display: none; }
}

/* ⚠️ DÉDUPLICATION pour finir de remonter l'action (mesure : /visibilite 1181px,
   /leads 913px — encore juste au-dessus de l'écran de 844).
   On ne supprime AUCUNE information : on retire ce qui est déjà dit ailleurs sur
   la même page.
     - /visibilite : la carte de paiement re-liste les 6 avantages que le hero
       affiche déjà en puces (visi-points) et que le bandeau « ce qui est inclus »
       reprend. Sur téléphone, on garde le prix et le bouton.
     - /leads : le champ « code promo » est masqué sur mobile. C'est un champ
       optionnel qui ne concerne pas la demande d'aperçu, et il pousse le bouton
       sous le pli. Il reste disponible sur ordinateur.
   ⚠️ Ces deux éléments restent dans le DOM (donc lisibles et crawlables) : on les
   masque par CSS, pas par suppression. */
@media (max-width: 760px) {
  .visi-list { display: none; }
  .visi-separator { margin: 8px 0; }
  .visi-pay { padding-top: 10px; }
  /* Le champ code promo : masqué (optionnel, non lié à la demande d'aperçu). */
  .lead-form label[for="promo_code"], .lead-form #promo_code { display: none; }
}

/* ⚠️ Dernier levier : le HERO qui précède le formulaire. Sur ces trois pages,
   le hero + le bloc d'engagements mangent ~400 px avant que l'action apparaisse.
   On le resserre (il est déjà lu, c'est un rappel). C'est ce qui fait passer
   l'action sous la barre des 844 px. */
@media (max-width: 760px) {
  /* /leads : hero + avantages du panneau. */
  .lead-hero { padding: 16px 0 12px; }
  .lead-hero h1 { font-size: 25px; }
  .lead-hero p { font-size: 14.5px; margin-top: 8px; }
  .lead-form-wrap { padding: 0; }
  .lead-form-wrap h3 { font-size: 18px; margin-bottom: 8px; }
  .lead-layout { gap: 18px; }

  /* /pricing : le hero de page.
     ⚠️ `:not(.hero-contrat)` est OBLIGATOIRE. La section d'accueil porte
     « hero hero-contrat », donc sans cette exclusion ce 27px !important
     écrasait le titre d'accueil — c'est LA cause du « trop petit » signalé par
     le user : h1 = 27px face à des h2 de section à 25,4px, soit un titre de page
     à la taille d'un titre de section. L'accueil a sa propre échelle (voir le
     bloc ACCUEIL ci-dessus), il ne doit pas être rattrapé par ce resserrement
     destiné aux pages secondaires. */
  .page-head, .hero:not(.hero-contrat) { padding-top: 18px !important; padding-bottom: 20px !important; }
  .page-head h1, .hero:not(.hero-contrat) h1 { font-size: 27px !important; }
  .page-head p, .hero:not(.hero-contrat) p { font-size: 15px !important; margin-top: 8px !important; }

  /* /visibilite : le hero + le bandeau d'inclusion. */
  .visi-hero { padding: 14px 0 12px; }
  .visi-hero h1 { font-size: 25px; }
  .visi-hero p { font-size: 14.5px; margin-top: 8px; }
  .visi-whats-included { padding: 10px 0; }
  .visi-item { font-size: 13px; padding: 5px 0; }
  .visi-layout { padding-top: 14px; }
}

/* ⚠️ Les 70 derniers pixels. /visibilite 914 et /pricing 899 : le hero + le
   premier bloc suffisent à pousser le bouton juste au-dessus de 844. On coupe
   les marges résiduelles du haut de page. */
@media (max-width: 760px) {
  .container { padding-top: 0 !important; }
  .visi-tunnel > :first-child, .page-head { margin-top: 0 !important; }
  .visi-hero { padding: 10px 0 10px; }
  .visi-hero .visi-eyebrow { margin-bottom: 8px; font-size: 11px; }
  .visi-whats-included { margin-bottom: 0; }
  .visi-layout { margin-top: 0; }
  /* Les encadrés d'offre de /pricing : on réduit le padding interne. */
  .plan { padding: 18px 16px; }
  .plan .price { font-size: 30px; margin: 6px 0; }
  .plan ul { margin: 10px 0; }
  .plan ul li { padding: 5px 0; font-size: 14px; }
  .plan .btn { padding: 13px; }
}

/* ⚠️ /pricing : le bloc Visibilité (partagé, 1166 px) précède les offres du
   logiciel. C'est volontaire — l'offre à 129,90 € est la principale depuis le
   pivot — mais sur téléphone il pousse le premier bouton à 899 px.
   On resserre ce bloc : sa capture d'écran factice (.visi-shots) est décorative,
   on la masque, et on réduit l'air. Le contenu reste intégral. */
@media (max-width: 760px) {
  .visi-block { gap: 22px; padding: 18px 0 22px; }
  .visi-block .visi-copy h2 { font-size: 24px; line-height: 1.12; }
  .visi-block .visi-copy p { font-size: 15px; margin-top: 10px; }
  .visi-block .visi-points { margin: 12px 0; }
  .visi-block .visi-points li { padding: 5px 0; font-size: 14.5px; }
  /* La maquette décorative (fenêtre + classement Google simulés) : masquée sur
     téléphone. Elle n'apporte aucune information — elle illustre. */
  .visi-shots { display: none; }
  .visi-price-box { margin: 12px 0; }
  .vpb-now { font-size: 32px; }
  .visi-cta-row { margin-top: 12px; }
  .visi-block .btn.primary.big { padding: 15px; font-size: 15.5px; }
  .visi-trust { font-size: 12px; margin-top: 10px; }
}

/* ⚠️ Dernier blocage : /visibilite à 866 px (22 px de trop). L'ordre est déjà
   bon (hero -> engagements -> carte de paiement), mais le hero + le bandeau
   d'inclusion font ~400 px. On gagne les 22 px sur les marges. */
@media (max-width: 760px) {
  .visi-hero { padding: 6px 0 8px; }
  .visi-hero h1 { font-size: 23px; }
  .visi-whats-included { padding: 7px 0; }
  .visi-layout { padding-top: 10px; }
  .visi-summary { padding: 16px 14px; }
}

/* ⚠️⚠️ LE PANNEAU D'EXEMPLE SUR MOBILE — ALIGNÉ SUR LA VERSION PC.
   Retour user : « J'aime bien la version PC, inspire-toi en pour la version
   mobile. » Sur PC le panneau montre LES QUATRE PRIX ; sur mobile mes
   resserrements successifs n'en laissaient plus que deux, ce qui vidait
   l'exemple de ce qui le rend convaincant.

   ⚠️ LE COMPROMIS EST MESURÉ, PAS DEVINÉ. Remettre les 4 lignes repoussait le
   bouton d'accueil hors de l'écran de 844 px. On récupère la hauteur AILLEURS,
   là où elle ne coûte rien à la compréhension :
     - le libellé du sur-titre du panneau (9 px au lieu de 9,5),
     - la marge interne du bloc de titre du panneau (0),
     - le pas des lignes de prix (4 px au lieu de 7),
     - les marges du relevé et de la rangée d'action.
   Mesuré à 390 px : 4 prix visibles, bouton à 798 px (dans l'écran), 0 débord.
   Sans ce resserrement : bouton à 868 px, hors écran. */
@media (max-width: 760px) {
  .hero-apercu .ap-lignes { display: block; padding: 0; margin-top: 10px; }
  .hero-apercu .ap-lignes li {
    display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
    padding: 4px 0; border-bottom: 1px solid var(--line-soft); font-size: 12.5px;
  }
  .hero-apercu .ap-lignes li .ap-nom-p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .hero-apercu .ap-lignes li .ap-prix { font-weight: 500; white-space: nowrap; }
  .hero-apercu .ap-lignes li:last-child { border-bottom: 0; }
  .hero-apercu .ap-note { display: none; }
  .hero-apercu .ap-kicker { font-size: 9px; letter-spacing: .1em; margin-bottom: 4px; }
  .hero-apercu .apercu-bloc { padding: 0; }
  .hero-apercu .mock-body { padding: 13px 14px 12px; }
  .hero-apercu .ap-nom { font-size: 17px; }
  .hero-apercu .ap-metier { font-size: 12.5px; }
  /* Le reste du hero se resserre d'autant.
     ⚠️ On ne redéfinit PAS .releve-l ici : sa grille et son padding vivent dans
     accueil-contrat.css. Avant, ce bloc les écrasait (padding 6px au lieu de 7,
     grille ignorée), ce qui rendait le relevé mobile impossible à régler depuis
     un seul endroit. echelle.css ne touche plus qu'aux marges qui le concernent. */
  .hero-contrat .releve { margin-top: 12px; }
  .hero-contrat .cta-row { margin-top: 12px; }
  .hero-contrat .cta-note { margin-top: 8px; }
}
/* Le nom de prestation, sur toutes les tailles. */
.ap-lignes li { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.ap-nom-p { color: var(--ink); }
.ap-prix { font-weight: 500; }

/* ⚠️ PLUS DE COUPE À 2 LIGNES. L'ancienne règle masquait les lignes 3 et 4 :
   c'était le compromis d'avant, il est remplacé par le resserrement ci-dessus,
   qui garde les 4 prix. Ne pas la réintroduire. */


/* ============================================================
   EX-refonte_blanche.css   (6438 octets, 23 !important)
   ============================================================ */

/* ============================================================
   REFONTE BLANCHE — feuille dédiée, chargée EN DERNIER.
   ⚠️ NE PAS la déplacer avant echelle.css : plusieurs règles de ce fichier
   ont une spécificité ÉGALE à celle d'echelle.css/accueil-contrat.css et ne
   gagnent que par l'ordre d'arrivée.
   ============================================================ */

/* ================= REFONTE BLANCHE 2026-10 =================
   Inspirée d'absurdventures.com : fond plein, une idée par écran, display
   condensé en capitales très grande, étiquettes monospace espacées, angles
   droits, aplats sans dégradé, zéro emoji.

   ⚠️ CONTRASTES MESURÉS sur fond blanc (#ffffff), pas estimés :
     --ink       #0a0a0a  19,8:1  texte courant
     --ink-2     #3d3d3d  10,9:1  texte secondaire
     --gris      #6f6f6f   5,0:1  texte discret
     --or-texte  #8a6a2a   5,0:1  texte or fin  (l'or vif est INSUFFISANT)
     --or-vif    #c8a24a   2,3:1  APLATS ET GROS ÉLÉMENTS UNIQUEMENT
   Ne jamais mettre --or-vif sur du texte de moins de 24 px.
   ============================================================ */
:root {
  --blanc: #ffffff;
  --blanc-2: #f7f6f3;
  --blanc-3: #f1efea;
  --blanc-ligne: #e4e2dd;

  --encre: #0a0a0a;
  --encre-2: #3d3d3d;
  --encre-3: #6f6f6f;

  --or-vif: #c8a24a;
  --or-texte: #8a6a2a;

  --display: var(--font-serif);
  --texte: var(--font-sans);
  --etiquette: var(--font-mono);
}

/* ---------- typographie display sur les pages de VENTE uniquement ----------
   On cible un attribut posé par le gabarit : ainsi le builder, le dashboard
   et les espaces clients ne bougent pas. */
body.vitrine {
  background: var(--blanc);
  color: var(--encre);
  font-family: var(--texte);
}

body.vitrine h1,
body.vitrine h2,
body.vitrine h3,
body.vitrine .display {
  font-family: var(--display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -.012em;
  line-height: .94;
  color: var(--encre);
}

body.vitrine h1 { font-size: clamp(40px, 7.4vw, 112px); }
body.vitrine h2 { font-size: clamp(28px, 4vw, 58px); }
body.vitrine h3 { font-size: clamp(20px, 2.2vw, 27px); letter-spacing: .005em; }

/* étiquettes : petites capitales monospace très espacées */
body.vitrine .etiquette,
body.vitrine .sec-num,
body.vitrine .kicker {
  font-family: var(--etiquette);
  font-size: 11.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--or-texte);
}

/* boutons : angles droits, contraste maximal.
   ⚠️⚠️ POURQUOI `!important` ICI. Quatre feuilles legacy posent un fond sur
   `.btn.primary` à la MÊME spécificité (0,3,1) que nos règles — dont
   `echelle.css : body:not(.app-mode) .btn.primary`. En pareil cas c'est
   l'ordre d'arrivée qui tranche, et malgré une feuille dédiée chargée en
   DERNIER la nôtre perdait. On tranche donc explicitement. Ne pas retirer
   sans avoir vérifié le style CALCULÉ du bouton, pas seulement la règle.
   Portée volontairement limitée à `body.vitrine` : le builder, le dashboard
   et les espaces clients ne sont pas touchés. */
body.vitrine .btn,
body.vitrine .btn.primary,
body.vitrine .btn.big {
  border-radius: 0 !important;
  font-family: var(--etiquette) !important;
  font-size: 12.5px !important;
  letter-spacing: .15em !important;
  text-transform: uppercase !important;
  padding: 17px 30px !important;
  background-image: none !important;
  background-color: var(--encre) !important;
  color: var(--blanc) !important;
  border: 1px solid var(--encre) !important;
  box-shadow: none !important;
}
body.vitrine .btn:hover,
body.vitrine .btn.primary:hover,
body.vitrine .btn.big:hover {
  background-image: none !important;
  background-color: var(--or-texte) !important;
  border-color: var(--or-texte) !important;
  color: var(--blanc) !important;
}
body.vitrine .btn.vide,
body.vitrine .btn.ghost {
  background-image: none !important;
  background-color: transparent !important;
  color: var(--encre) !important;
  border-color: #c9c6bf !important;
}
body.vitrine .btn.vide:hover,
body.vitrine .btn.ghost:hover {
  background-color: transparent !important;
  color: var(--encre) !important;
  border-color: var(--encre) !important;
}


/* cartes : angles droits, filet fin, aucune ombre lourde */
body.vitrine .card,
body.vitrine .dual-plan,
body.vitrine .panel {
  border-radius: 0;
  border: 1px solid var(--blanc-ligne);
  box-shadow: none;
  background: var(--blanc);
}

/* le bandeau d'offre : aplat clair, filet or */
body.vitrine .visi-block {
  border: 1px solid var(--or-vif);
  background: var(--blanc-2);
  border-radius: 0;
}

/* ---------- offre « votre site, à vous » (sans prix affiché) ----------
   Deux colonnes : l'argument à gauche, l'appel à l'action à droite. Angles
   droits, filet fin, aplat or très clair pour marquer la rupture avec
   l'abonnement juste au-dessus. */
body.vitrine .votre-site {
  display: grid;
  grid-template-columns: 1.35fr .85fr;
  gap: 1px;
  background: var(--blanc-ligne);
  border: 1px solid var(--or-vif);
  border-radius: 0;
}
body.vitrine .votre-site > div {
  background: var(--blanc);
  padding: 40px 38px;
}
body.vitrine .vs-cta { background: var(--blanc-2); }
body.vitrine .votre-site p { font-size: 16px; color: var(--encre-2); }
body.vitrine .vs-liste { list-style: none; margin-top: 24px; }
body.vitrine .vs-liste li {
  padding: 13px 0 13px 26px;
  border-bottom: 1px solid var(--blanc-ligne);
  font-size: 15px; color: var(--encre);
  position: relative;
}
body.vitrine .vs-liste li::before {
  content: ''; position: absolute; left: 0; top: 19px;
  width: 9px; height: 9px; background: var(--or-vif);
}
body.vitrine .vs-accroche {
  font-family: var(--display);
  text-transform: uppercase;
  font-size: clamp(19px, 1.6vw, 24px);
  line-height: 1.15;
  color: var(--encre);
  margin-bottom: 26px;
}
body.vitrine .vs-cta .btn { width: 100%; text-align: center; }
body.vitrine .vs-note {
  font-family: var(--etiquette);
  font-size: 11px; letter-spacing: .1em;
  color: var(--encre-3);
  margin-top: 16px; text-align: center;
}

@media (max-width: 900px) {
  body.vitrine .votre-site { grid-template-columns: 1fr; }
  body.vitrine .votre-site > div { padding: 28px 22px; }
}

/* le logo en en-tête : hauteur maîtrisée, le SVG contient le mot */
/* le nom écrit à côté du logo ferait doublon : le logo contient déjà le mot */

@media (max-width: 900px) {
    body.vitrine .btn, body.vitrine .btn.primary, body.vitrine .btn.big { padding: 15px 22px; }
}


/* ============================================================
   EX-vitrine.css   (17971 octets, 1 !important)
   ============================================================ */

/* ============================================================
   VITRINE — feuille dédiée à la page d'accueil (portage de la maquette
   validée par le user : previews/accueil-blanc.html + previews/blanc.css).

   ⚠️⚠️ TOUS LES SÉLECTEURS SONT PRÉFIXÉS `body.v-page`.
   `echelle.css` normalise les balises avec `body:not(.app-mode) p` — soit une
   spécificité (0,1,2) qui BAT un simple sélecteur de classe (0,1,0). Sans ce
   préfixe, les tailles de texte retombaient à 16 px et le titre prenait six
   lignes au lieu de trois (mesuré). Préfixer porte à (0,2,1) et gagne
   proprement, sans recourir à `!important`.

   ⚠️ Aucune règle ici ne cible une classe de luxe.css/echelle.css : c'est ce
   qui garantit qu'aucun style de l'ancien site ne se mélange.

   ⚠️ CONTRASTES MESURÉS sur fond blanc (#ffffff), pas estimés :
     --v-encre    #0a0a0a  19,8:1   texte courant
     --v-encre-2  #3d3d3d  10,9:1   texte secondaire
     --v-gris     #6f6f6f   5,0:1   texte discret
     --v-or-texte #8a6a2a   5,0:1   texte or fin
     --v-or       #c8a24a   2,3:1   APLATS ET GROS ÉLÉMENTS UNIQUEMENT
   Ne jamais écrire `color: var(--v-or)` sur du texte de moins de 24 px.
   ============================================================ */

:root {
  --v-blanc: #ffffff;
  --v-blanc-2: #f7f6f3;
  --v-blanc-3: #f1efea;
  --v-ligne: #e4e2dd;
  --v-encre: #0a0a0a;
  --v-encre-2: #3d3d3d;
  --v-gris: #6f6f6f;
  --v-or: #c8a24a;
  --v-or-texte: #8a6a2a;
  --v-display: var(--font-serif);
  --v-texte: var(--font-sans);
  --v-mono: var(--font-mono);
  --v-gouttiere: 28px;
  --v-large: 1120px;
}

body.v-page {
  background: var(--v-blanc);
  color: var(--v-encre);
  font-family: var(--v-texte);
  font-size: 16px;
  line-height: 1.55;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
body.v-page * { box-sizing: border-box; }
body.v-page .v-wrap { max-width: var(--v-large); margin: 0 auto; padding: 0 var(--v-gouttiere); }
body.v-page .v-mono { font-family: var(--v-mono); }

/* ---------------- 1. OUVERTURE ---------------- */
body.v-page .v-hero {
  /* ⚠️⚠️ PAS D'`overflow: hidden` ICI. Bug mesuré : il ROGNAIT le titre.
     La hauteur de glyphe d'Anton (~1,15 em) dépasse l'interligne serré de la
     maquette (.92), donc le contenu du H1 fait 23 px de plus que sa boîte ;
     avec `overflow: hidden` sur ce parent, la dernière ligne et le trait du mot
     en contour étaient coupés. Les couches de fond sont en `inset: 0` et
     masquées par un `mask-image` : elles ne débordent pas, ce `overflow`
     n'était donc utile à rien.

     ⚠️⚠️ `min-height: 100svh` + contenu poussé en bas = TROU BÉANT SUR GRAND
     ÉCRAN. Mesuré : 293 px de vide en haut en 1920x1080, et 1 373 px en 4K —
     le contenu était collé en bas (`justify-content: flex-end`) avec un vide
     au-dessus. C'est le « PC KO » signalé par le user.
     Correction : on ne force PLUS le plein écran. Le hero respire selon son
     contenu, avec un plafond. Vérifié de 900 à 2160 px de haut. */
  position: relative;
  display: flex; flex-direction: column; justify-content: center;
  padding: 128px var(--v-gouttiere) 64px;
}
body.v-page .v-hero-cadre {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(120% 90% at 78% 8%, rgba(200, 162, 74, .16), transparent 62%),
    linear-gradient(to bottom, #ffffff 0%, var(--v-blanc-2) 78%);
}
/* le quadrillage de plan technique, en fondu vers le bas */
body.v-page .v-hero-grille-vide {
  position: absolute; inset: 0; z-index: 0; opacity: .8;
  background-image:
    linear-gradient(rgba(10, 10, 10, .055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(10, 10, 10, .055) 1px, transparent 1px);
  background-size: 68px 68px;
  -webkit-mask-image: radial-gradient(120% 80% at 50% 108%, #000 6%, transparent 72%);
  mask-image: radial-gradient(120% 80% at 50% 108%, #000 6%, transparent 72%);
}
/* ⚠️⚠️ LE HERO DOIT PORTER LA MÊME GOUTTIÈRE QUE LE RESTE DU SITE.
   Bug mesuré : `.v-hero` porte `padding: 128px 28px 64px` sur la SECTION, et
   `.v-hero-inner` est centré à 1120 px SANS padding interne. Résultat : le
   titre de l'accueil tombait à x=160, tandis que `/pricing` (même largeur de
   conteneur) tombe à x=188 — 28 px de décalage entre deux pages de même
   largeur, sans justification. C'est le « mal aligné » signalé par le user.
   Le padding appartient au CONTENEUR interne, pas à la section : ainsi
   l'accueil cadre exactement comme les autres pages. */
body.v-page .v-hero-inner {
  position: relative; z-index: 2;
  max-width: var(--v-large); width: 100%;
  margin: 0 auto;
  padding: 0 var(--v-gouttiere);
}

body.v-page .v-kicker {
  font-family: var(--v-mono); font-size: 12px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--v-or-texte);
  margin: 0 0 26px; display: flex; align-items: center; gap: 14px;
}
body.v-page .v-kicker::before { content: ''; width: 34px; height: 1px; background: var(--v-or-texte); display: block; }

body.v-page .v-h1 {
  font-family: var(--v-display); font-weight: 400; text-transform: uppercase;
  /* ⚠️ LINE-HEIGHT .92 -> .99 ET PADDING VERTICAL.
     Bug mesuré : à .92 le contenu du titre faisait 333 px dans une boîte de
     302 px — Anton a une hauteur de glyphe supérieure à l'interligne, donc les
     lignes se chevauchent et le mot en CONTOUR (`-webkit-text-stroke`) voyait
     son trait rogné en haut et en bas. Le padding réserve la place du trait,
     qui se dessine À L'EXTÉRIEUR des glyphes. */
  /* Interligne serré de la maquette (.92). Il est SANS RISQUE dès lors qu'aucun
     ancêtre ne rogne : voir la note sur `overflow` dans `.v-hero`. */
  font-size: clamp(40px, 7.6vw, 118px); line-height: .92; letter-spacing: -.012em;
  margin: 0; max-width: 17ch; color: var(--v-encre);
}
body.v-page .v-barre {
  -webkit-text-stroke: 1.6px var(--v-encre);
  color: transparent;
  /* le trait se peint hors des glyphes : on lui laisse de l'air à gauche/droite */
  padding: 0 .02em;
}
body.v-page .v-or { color: var(--v-or-texte); }

body.v-page .v-hero-sub { margin: 30px 0 0; max-width: 62ch; font-size: clamp(15px, 1.25vw, 18px); color: var(--v-encre-2); line-height: 1.65; }
body.v-page .v-hero-cta { margin-top: 38px; display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
body.v-page .v-hero-note { font-family: var(--v-mono); font-size: 11.5px; letter-spacing: .1em; color: var(--v-gris); margin-left: 6px; }

body.v-page .v-hero-facts {
  position: relative; z-index: 2; max-width: var(--v-large); width: 100%;
  margin: 62px auto 0; border-top: 1px solid var(--v-ligne);
  display: grid; grid-template-columns: repeat(4, 1fr);
}
body.v-page .v-hero-facts > div { padding: 20px 0 0; }
body.v-page .v-hero-facts dt {
  font-family: var(--v-mono); font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--v-gris); margin: 0;
}
body.v-page .v-hero-facts dd { font-family: var(--v-display); font-size: 26px; margin: 7px 0 0; color: var(--v-encre); }

/* ---------------- boutons ---------------- */
body.v-page .v-btn {
  display: inline-block; font-family: var(--v-mono); font-size: 12.5px;
  letter-spacing: .15em; text-transform: uppercase; padding: 17px 30px;
  border: 1px solid transparent; border-radius: 0; cursor: pointer;
  text-decoration: none; transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
body.v-page .v-btn-plein { background: var(--v-encre); color: var(--v-blanc); border-color: var(--v-encre); }
body.v-page .v-btn-plein:hover { background: var(--v-or-texte); border-color: var(--v-or-texte); }
body.v-page .v-btn-vide { background: transparent; color: var(--v-encre); border-color: #c9c6bf; }
body.v-page .v-btn-vide:hover { border-color: var(--v-encre); }

/* ---------------- sections ---------------- */
body.v-page .v-sec { padding: 118px var(--v-gouttiere); border-top: 1px solid var(--v-ligne); /* pas d'overflow cache : ne jamais rogner un titre */ }
body.v-page .v-sec-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 40px; flex-wrap: wrap; margin-bottom: 62px; }
body.v-page .v-h2 {
  font-family: var(--v-display); font-weight: 400; text-transform: uppercase;
  /* ⚠️ même piège que .v-h1 : à .96 le contenu dépassait la boîte (190 px pour
     174) et les descendantes d'Anton étaient rognées. .99 + padding vertical. */
  font-size: clamp(30px, 4.2vw, 62px); line-height: .96; letter-spacing: -.01em;
  margin: 0; max-width: 20ch; color: var(--v-encre);
}
body.v-page .v-h3 {
  font-family: var(--v-display); font-weight: 400; text-transform: uppercase;
  font-size: 25px; letter-spacing: .01em; margin: 0 0 12px; color: var(--v-encre);
}
body.v-page .v-sec-num {
  font-family: var(--v-mono); font-size: 11.5px; letter-spacing: .2em;
  color: var(--v-or-texte); text-transform: uppercase;
}

/* grille des 4 prestations */
body.v-page .v-grille { display: grid; grid-template-columns: repeat(2, 1fr); border-top: 1px solid var(--v-ligne); }
body.v-page .v-grille article { padding: 40px 34px 40px 0; border-bottom: 1px solid var(--v-ligne); }
body.v-page .v-grille article:nth-child(odd) { border-right: 1px solid var(--v-ligne); padding-right: 40px; }
body.v-page .v-grille article:nth-child(even) { padding-left: 40px; }
body.v-page .v-grille article p { color: var(--v-encre-2); font-size: 15px; max-width: 46ch; margin: 0; }
body.v-page .v-n { font-family: var(--v-mono); font-size: 11.5px; color: var(--v-or-texte); letter-spacing: .18em; display: block; margin-bottom: 20px; }

/* ---------------- 3. avant / après ---------------- */
body.v-page .v-apercu { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--v-ligne); border: 1px solid var(--v-ligne); }
body.v-page .v-apercu > div { background: var(--v-blanc); padding: 34px; }
body.v-page .v-etat { font-family: var(--v-mono); font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase; margin: 0 0 22px; }
body.v-page .v-avant .v-etat { color: var(--v-gris); }
body.v-page .v-apres .v-etat { color: var(--v-or-texte); }
body.v-page .v-apercu ul { list-style: none; margin: 0; padding: 0; }
body.v-page .v-apercu li { padding: 13px 0; border-bottom: 1px solid var(--v-ligne); font-size: 15px; display: flex; gap: 12px; }
body.v-page .v-avant li { color: #96948f; }
body.v-page .v-apres li { color: var(--v-encre); }
body.v-page .v-apercu li span { font-family: var(--v-mono); font-size: 11px; color: var(--v-or-texte); padding-top: 4px; }

body.v-page .v-cta-ligne { margin-top: 44px; display: flex; flex-wrap: wrap; gap: 16px; align-items: center; }

/* ---------------- 4. les offres ---------------- */
/* ⚠️ LA PISTE EST UN DÉFILEMENT NATIF (`overflow-x: auto` + `scroll-snap`),
   pas une grille. C'est ce qui donne le glisser-déposer au doigt sans JS, et
   ce qui dégrade proprement si le script ne charge pas.
   `scrollbar-width: none` masque la barre native : les pastilles et les
   flèches la remplacent, et une barre visible sous les cartes jurerait. */
body.v-page .v-piste {
  display: flex; gap: 1px;
  background: var(--v-ligne);
  border: 1px solid var(--v-ligne);
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none; -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
body.v-page .v-piste::-webkit-scrollbar { display: none; }
body.v-page .v-piste > [data-diapo] {
  scroll-snap-align: start;
  flex: 0 0 100%;                /* une diapo = une largeur */
  min-width: 0;
}
/* ⚠️ À partir de 1000 px les trois offres tiennent côte à côte : le carrousel
   n'a plus de sens. On repasse en grille et on MASQUE les commandes, sinon
   l'utilisateur voit des flèches qui ne déplacent rien. */
@media (min-width: 1000px) {
  body.v-page .v-piste { display: grid; grid-template-columns: repeat(3, 1fr); overflow: visible; }
  body.v-page .v-piste > [data-diapo] { flex: none; }
}

body.v-page .v-commandes {
  display: flex; align-items: center; justify-content: center;
  gap: 20px; margin-top: 26px;
}
body.v-page .v-fleche {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  background: transparent; color: var(--v-encre);
  border: 1px solid var(--v-ligne); border-radius: 0;
  font-family: var(--v-mono); font-size: 17px; line-height: 1;
  cursor: pointer;
  transition: background-color .15s, color .15s, border-color .15s;
}
body.v-page .v-fleche:hover { background: var(--v-encre); color: var(--v-blanc); border-color: var(--v-encre); }
body.v-page .v-fleche:disabled { opacity: .3; cursor: default; }
body.v-page .v-fleche:disabled:hover { background: transparent; color: var(--v-encre); border-color: var(--v-ligne); }
body.v-page .v-pastilles { display: flex; align-items: center; gap: 11px; }
body.v-page .v-pastille {
  width: 11px; height: 11px; padding: 0; flex: none;
  background: transparent; border: 1px solid var(--v-encre); border-radius: 0;
  cursor: pointer; transition: background-color .15s;
}
body.v-page .v-pastille[aria-current="true"] { background: var(--v-encre); }
body.v-page .v-pastille:hover { background: var(--v-encre); opacity: .6; }
body.v-page .v-offre { background: var(--v-blanc); padding: 40px 32px 44px; display: flex; flex-direction: column; min-width: 0; }
body.v-page .v-offre.v-mise { background: var(--v-blanc-2); }
body.v-page .v-offre-nom { font-family: var(--v-mono); font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--v-or-texte); margin: 0; }
body.v-page .v-offre-prix { font-family: var(--v-display); font-size: 54px; margin: 20px 0 4px; letter-spacing: -.01em; color: var(--v-encre); }
body.v-page .v-offre-prix small { font-family: var(--v-mono); font-size: 12px; letter-spacing: .12em; color: var(--v-gris); margin-left: 6px; }
body.v-page .v-chiffre { font-size: 54px; }
body.v-page .v-offre-sans-prix {
  font-family: var(--v-display); text-transform: uppercase; font-size: 25px;
  /* ⚠️ .99 + padding : le contenu dépassait la boîte (110 px pour 105) et la
     dernière ligne était rognée. Même piège que les titres. */
  line-height: 1.05; margin: 22px 0 16px; color: var(--v-encre); max-width: 16ch;
}
body.v-page .v-offre-cond { font-size: 14.5px; color: var(--v-encre-2); min-height: 60px; margin: 6px 0 0; }
body.v-page .v-liste { list-style: none; margin: 26px 0 34px; padding: 0; flex: 1; }
body.v-page .v-liste li { padding: 11px 0; border-bottom: 1px solid var(--v-ligne); font-size: 14.5px; color: var(--v-encre-2); }
body.v-page .v-offre .v-btn { width: 100%; text-align: center; }
body.v-page .v-tag {
  font-family: var(--v-mono); font-size: 10.5px; letter-spacing: .16em; color: var(--v-or-texte);
  border: 1px solid var(--v-or); padding: 4px 9px; display: inline-block;
  margin-bottom: 20px; text-transform: uppercase; align-self: flex-start;
}

/* ---------------- 6. décision ---------------- */
body.v-page .v-final { text-align: center; padding: 150px var(--v-gouttiere); background: var(--v-blanc-3); }
body.v-page .v-final .v-h2 { margin: 0 auto 26px; max-width: 24ch; }
body.v-page .v-final-p { color: var(--v-encre-2); max-width: 60ch; margin: 0 auto 40px; }
body.v-page .v-final .v-btn { min-width: 280px; }

/* ---------------- adaptation ---------------- */
@media (max-width: 1000px) {
  body.v-page .v-offres { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  /* 20 -> 18 px : ALIGNE SUR `.container` (padding 0 18px en mobile).
     Bug mesure : l'accueil cadrait a 40 px contre 18 px sur les autres pages.
     Deux causes cumulees : la gouttiere valait 20 au lieu de 18, ET la section
     `.v-hero` portait EN PLUS son propre padding horizontal de 20 px — la
     marge etait donc comptee DEUX FOIS. Regle : le padding horizontal d'une
     section pleine largeur appartient au CONTENEUR interne, pas a la section. */
  :root { --v-gouttiere: 18px; }
  body.v-page .v-hero { padding: 96px 0 40px; }
  body.v-page .v-hero-cta { margin-top: 30px; }
  body.v-page .v-hero-facts { grid-template-columns: repeat(2, 1fr); margin-top: 40px; }
  body.v-page .v-hero-facts > div { padding: 16px 0 0; }
  body.v-page .v-sec { padding: 76px 20px; }
  body.v-page .v-sec-head { margin-bottom: 40px; }
  body.v-page .v-grille, body.v-page .v-apercu { grid-template-columns: 1fr; }
  body.v-page .v-grille article:nth-child(odd) { border-right: 0; padding-right: 0; }
  body.v-page .v-grille article:nth-child(even) { padding-left: 0; }
  body.v-page .v-final { padding: 80px 20px; }
  body.v-page .v-btn { width: 100%; text-align: center; }
  body.v-page .v-offre .v-btn, body.v-page .v-final .v-btn { min-width: 0; }
}

/* ---------------- LOGO DE L'EN-TÊTE ----------------
   ⚠️⚠️ LES DEUX LOGOS SE CHEVAUCHAIENT (signalé par le user).
   Deux causes mesurées :
     1. `.brand-mark` garde une boîte FIXE de 32 px (règle legacy de luxe.css)
        alors que le nouveau logo est un mot-symbole de 137 px de large -> il
        débordait de 105 px au-dessus du texte.
     2. Le texte « Devisaly » à côté du logo n'était pas masqué : ma règle
        visait `body.vitrine`, mais la page d'accueil porte `body.v-page`.
   Le logo contient DÉJÀ le mot : le texte adjacent est un doublon. On le
   supprime et on laisse la boîte se dimensionner au contenu. */
body.v-page .drawer-wordmark { display: none; }
body.v-page .drawer-mark img { width: auto; height: 26px; }

@media (max-width: 900px) {
}

/* ⚠️⚠️ À PLACER APRÈS la définition de `.v-commandes`.
   Ma première version mettait `display: none` dans un media query situé AVANT
   la définition : à spécificité égale, c'est l'ordre qui tranche, et
   `display: flex` gagnait. Résultat mesuré : des flèches affichées sur grand
   écran alors que les trois offres sont déjà côte à côte — des commandes qui
   ne servent à rien.
   Règle : un `display: none` conditionnel doit venir APRÈS la règle qu'il
   annule, ou porter une spécificité supérieure. */
@media (min-width: 1000px) {
  body.v-page .v-commandes { display: none; }
}


/* ============================================================
   EX-menu.css   (8353 octets, 0 !important)
   ============================================================ */

/* ============================================================
   MENU LATERAL - feuille DEDIEE, chargee EN DERNIER.

   POURQUOI ELLE EXISTE. `accueil-contrat.css` (charge apres luxe.css) pose
   `.drawer { width: 380px }`, `.drawer-list a { padding: 12px 14px }`,
   `.drawer-cta {...}` - MEME specificite que les regles du menu. A specificite
   egale, l'ordre d'arrivee tranche : la refonte du menu etait donc ecrasee et
   le menu restait petit (mesure : 380 px de large au lieu de 460, entrees a
   15,5 px au lieu de 20).

   NE PAS la deplacer avant accueil-contrat.css.
   ============================================================ */

/* ============================================================
   BARRE DU HAUT — MOBILE (corrigé 2026-10-05)
   ⚠️⚠️ BUG MESURÉ : à 390 px, `.nav` faisait 268 px et `.lang-switch` sortait
   à 433 px — 43 px DEHORS de l'écran, sans aucun media query pour l'arrêter.
   Un élément hors écran crée un débordement horizontal : « tout est décalé ».
   Correctifs : la barre ne se comprime plus, la langue passe dans le tiroir,
   les libellés longs s'effacent derrière le menu.
   ============================================================ */
@media (max-width: 900px) {
  .topbar-inner { gap: 10px; }
  .brand-mark { height: 24px; }
  .brand-mark img, .brand-mark svg { height: 24px; width: auto; }
  .nav { flex: 1 1 auto; min-width: 0; justify-content: flex-end; gap: 10px; }
  /* ⚠️ Le sélecteur de langue et les liens secondaires disparaissent de la
     barre : ils restent accessibles dans le tiroir (langue) et le pied de
     page. Un élément hors écran est PIRE qu'un élément caché. */
  .nav .lang-switch { display: none; }
  .nav > a:not(.btn):not(.active) { display: none; }
  .nav .user-menu { display: none; }
  /* ⚠️⚠️ LE BOUTON S'APPELLE `.burger`, PAS `.hamburger`.
     Ma regle ciblait `.hamburger` : la classe n'existe nulle part, donc le
     bouton gardait son `display: none` de base — MEME SUR MOBILE. Le menu
     hamburger etait invisible, et donc le menu INACCESSIBLE sur telephone.
     Verifie : `getComputedStyle('.burger').display` valait `none` a 390 px. */
  .burger { display: inline-flex; }
  /* l'action principale reste, en plus compact */
  .nav .btn.primary {
    padding: 10px 13px; font-size: 10.5px; letter-spacing: .06em;
    white-space: nowrap;
  }
}
@media (max-width: 420px) {
  /* sur très petit écran, seule l'action principale reste dans la barre */
  .nav .btn.primary { font-size: 10px; padding: 9px 11px; }
  .brand-mark { height: 22px; }
  .brand-mark img, .brand-mark svg { height: 22px; }
}

/* ============================================================
   MENU LATÉRAL (tiroir) — refonte 2026-10.
   ⚠️ Ne PAS remettre de petites entrées de 14 px : le panneau se tient avec
   de grands caractères et une hiérarchie lisible.
   ⚠️ Le tiroir sert DEUX publics (visiteur / client connecté) : le style doit
   tenir pour 4 entrées comme pour une liste de déconnexion de 10.
   ============================================================ */
.drawer {
  position: fixed; top: 0; right: 0; height: 100dvh;
  width: 460px; max-width: 92vw;
  background: var(--card); border-left: 1px solid var(--line);
  z-index: 201; transform: translateX(100%);
  transition: transform .32s cubic-bezier(.22,.61,.36,1);
  display: flex; flex-direction: column; overflow: hidden;
}
body.drawer-open .drawer { transform: translateX(0); }

.drawer-head { display: flex; align-items: center; justify-content: space-between; padding: 20px 26px; border-bottom: 1px solid var(--line); }
.drawer-mark { display: inline-flex; width: auto; height: 28px; align-items: center; }
.drawer-mark img, .drawer-mark svg { width: auto; height: 100%; display: block; }
.drawer-close { background: transparent; border: 1px solid var(--line); cursor: pointer; color: var(--muted); padding: 8px; display: inline-flex; border-radius: 0; transition: background .15s, color .15s, border-color .15s; min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
.drawer-close:hover { background: var(--ink); color: var(--card); border-color: var(--ink); }

.drawer-nav { flex: 1; overflow-y: auto; padding: 24px 26px 12px; }
.drawer-nav::-webkit-scrollbar { width: 6px; }
.drawer-nav::-webkit-scrollbar-thumb { background: var(--line); }

/* action principale : pleine largeur, contraste maximal */
.drawer-cta {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin: 18px 26px 0; padding: 17px 20px;
  background: var(--ink); color: var(--card);
  border: 1px solid var(--ink); border-radius: 0;
  font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .14em;
  text-transform: uppercase; text-decoration: none;
  transition: background .18s, border-color .18s;
}
.drawer-cta:hover { background: var(--gold-2); border-color: var(--gold-2); }
.drawer-cta.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.drawer-cta.ghost:hover { background: transparent; border-color: var(--ink); color: var(--ink); }

/* libellés de groupe : monospace espacé, comme les étiquettes du site */
.drawer-groupe {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--muted);
  margin: 26px 0 4px; padding: 0;
}
.drawer-groupe:first-child { margin-top: 0; }

/* entrées : SOBRES. Demande du user : « juste un menu classique ».
   ⚠️ NE PAS remettre de numérotation (01/02…) ni de flèche animée : c'était le
   traitement « panneau éditorial » de la référence, rejeté ici. Un menu
   classique se lit d'un coup d'œil. */
.drawer-list { display: flex; flex-direction: column; margin: 0 0 4px; padding: 0; }
.drawer-nav > .drawer-list > a {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 2px; min-height: 48px;
  text-decoration: none; color: var(--ink);
  font-size: 16px; line-height: 1.25; letter-spacing: 0;
  border-bottom: 1px solid var(--line-soft);
  transition: color .15s;
}
.drawer-nav > .drawer-list > a:hover { color: var(--gold-2); }
.drawer-list a { font-size: 16px; }
.drawer-list a:hover { color: var(--gold-2); }

.drawer-more { border-top: 1px solid var(--line-soft); padding-top: 8px; margin: 26px 0 16px; }
.drawer-more summary {
  display: flex; align-items: center; justify-content: space-between; cursor: pointer;
  padding: 13px 2px; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
  list-style: none; min-height: 48px;
}
.drawer-more summary::-webkit-details-marker { display: none; }
.drawer-more[open] summary { color: var(--gold-2); }
.drawer-more[open] summary svg { transform: rotate(180deg); }
.drawer-more summary svg { transition: transform .2s; }
.drawer-more .drawer-list { margin: 4px 0 12px; }

.drawer-foot { padding: 16px 26px calc(16px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.drawer-foot .drawer-cta { margin: 0; }
.drawer-logout { display: flex; align-items: center; gap: 8px; justify-content: center; padding: 13px; text-decoration: none; color: var(--muted); font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase; border: 1px solid var(--line); transition: color .15s, border-color .15s; min-height: 46px; }
.drawer-logout:hover { color: var(--ink); border-color: var(--ink); }

.drawer-user { display: flex; align-items: center; gap: 14px; margin: 18px 26px 0; padding: 14px 16px; border: 1px solid var(--line); }
.drawer-avatar { width: 38px; height: 38px; display: grid; place-items: center; background: var(--ink); color: var(--card); font-family: var(--font-serif); font-weight: 500; font-size: 16px; }
.drawer-user-name { font-family: var(--font-serif); font-weight: 500; font-size: 15px; color: var(--ink); }
.drawer-user-plan { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-top: 3px; }

@media (max-width: 600px) {
  .drawer { width: 100%; max-width: 100%; }
  .drawer-nav { padding: 20px 20px 10px; }
  .drawer-cta { margin: 16px 20px 0; }
  .drawer-head, .drawer-foot { padding-left: 20px; padding-right: 20px; }
  .drawer-nav > .drawer-list > a { font-size: 16px; min-height: 50px; }
}


/* ============================================================
   EX-theme-binaire.css   (8720 octets, 22 !important)
   ============================================================ */

/* ============================================================
   THÈME BINAIRE — BLANC & NOIR. Fond BLANC, écriture NOIRE.
   Feuille de surcharge, chargée EN DERNIER.

   ⚠️⚠️ ERREUR CORRIGÉE LE 2026-10-05. Le user a demandé « le même thème noir
   et blanc que la maquette ». J'ai lu « fond noir » et livré un site à fond
   NOIR. C'est le contraire : le « thème noir et blanc » désigne la maquette
   `previews/accueil-blanc.html`, qui a un FOND BLANC et une ÉCRITURE NOIRE.
   Le user l'avait pourtant écrit noir sur blanc plus tôt : « je veux une
   prédominance blanche, donc fond blanc avec écriture noir ».
   → Ne jamais déduire une couleur d'un nom de thème. Vérifier la maquette.

   Principe : aucun or, aucune couleur. Deux valeurs seulement, plus des gris.
   Angles droits, aplats, zéro dégradé.

   ⚠️ CONTRASTES MESURÉS sur fond #ffffff :
     noir #0a0a0a         19,8:1   texte courant
     gris foncé #3d3d3d   10,9:1   texte secondaire
     gris #6f6f6f          5,0:1   texte discret
     ligne #e4e2dd         1,2:1   séparateurs (décoratif)
   ============================================================ */

:root {
  /* ---- jetons de base (luxe.css) ---- */
  --paper: #ffffff;        /* fond de page : BLANC */
  --paper-2: #f7f6f3;      /* zones secondaires */
  --card: #ffffff;         /* panneaux / cartes */
  --card-2: #faf9f7;       /* survol */
  --ink: #0a0a0a;          /* texte principal : NOIR */
  --ink-2: #3d3d3d;        /* texte secondaire */
  --muted: #6f6f6f;        /* texte tertiaire */
  --faint: #767672;        /* texte discret — 4,6:1 */

  /* ---- l'or devient du NOIR : plus aucune couleur ---- */
  --gold: #0a0a0a;
  --gold-2: #0a0a0a;
  --gold-3: #0a0a0a;
  --gold-line: rgba(10, 10, 10, .18);
  --gold-bg: rgba(10, 10, 10, .04);
  --gold-soft: #e8e6e2;

  --danger: #b3261e;
  --ok: #1f6b34;

  --line: #e4e2dd;         /* bordures */
  --line-soft: #efedea;

  /* sur fond clair, une ombre se voit : on la garde très légère */
  --shadow-sm: 0 1px 2px rgba(10, 10, 10, .05);
  --shadow-md: 0 4px 12px rgba(10, 10, 10, .07);
  --shadow-lg: 0 10px 30px rgba(10, 10, 10, .10);

  /* ---- jetons de la refonte (refonte_blanche.css) ---- */
  --blanc: #ffffff;
  --blanc-2: #f7f6f3;
  --blanc-3: #f1efea;
  --blanc-ligne: #e4e2dd;
  --encre: #0a0a0a;
  --encre-2: #3d3d3d;
  --encre-3: #6f6f6f;
  --or-vif: #0a0a0a;
  --or-texte: #0a0a0a;

  /* ---- jetons de la vitrine (vitrine.css) ---- */
  --v-blanc: #ffffff;
  --v-blanc-2: #f7f6f3;
  --v-blanc-3: #f1efea;
  --v-ligne: #e4e2dd;
  --v-encre: #0a0a0a;
  --v-encre-2: #3d3d3d;
  --v-gris: #6f6f6f;
  --v-or: #0a0a0a;
  --v-or-texte: #0a0a0a;
}

/* ============================================================
   CORRECTIONS PONCTUELLES — ce qui ne passe pas par les jetons.
   ============================================================ */

/* 1. le dégradé or des boutons legacy : supprimé, aplat noir */
body:not(.app-mode) .btn.primary,
.visi-card .btn.primary,
.lead-form-wrap .btn.primary,
.plan.featured .btn.primary,
.hero-contrat .btn.primary,
.champ-encre .btn.primary {
  background-image: none !important;
  background-color: #0a0a0a !important;
  color: #ffffff !important;
  border-color: #0a0a0a !important;
}
body:not(.app-mode) .btn.primary:hover,
.hero-contrat .btn.primary:hover,
.plan.featured .btn.primary:hover {
  background-color: #333333 !important;
  border-color: #333333 !important;
}

/* 2. barre du haut : fond blanc translucide */
.nav,
.topbar {
  background: rgba(255, 255, 255, .92);
  border-color: var(--line);
}
.drawer-scrim { background: rgba(10, 10, 10, .45); }

/* 3. ⚠️ LE LOGO N'EST PAS INVERSÉ. Il est déjà noir : sur fond blanc il se lit
      tel quel. L'inverser (règle du thème sombre) le ferait disparaître. */
.brand-mark img,
.drawer-mark img,
.logo-clair { filter: none; }

/* 4. les maquettes de sites clients restent sur fond blanc : c'est le produit
      vendu, un site d'artisan est clair. Rien à changer ici, mais on le
      documente pour que personne ne les « adapte » au thème par erreur. */

/* 5. champs de formulaire */
input, textarea, select {
  background-color: #ffffff;
  color: #0a0a0a;
  border-color: var(--line);
}
input::placeholder, textarea::placeholder { color: #8a8a8a; }

/* 6. survol de lignes de tableau : très léger sur fond clair */
table tr:hover, .quote-table tr:hover { background-color: rgba(10, 10, 10, .03); }

@media (max-width: 900px) {
  .nav, .topbar { background: rgba(255, 255, 255, .96); }
}

/* ⚠️⚠️ UNE SEULE TAILLE DE TITRE h1 (corrigé 2026-10-05).
   Mesuré : 109,44 px sur l'accueil, 106,56 sur les pages refaites, 56 px sur
   certaines pages d'outil. Trois règles concurrentes posaient chacune sa
   valeur. Un même niveau de titre doit avoir UNE valeur sur tout le site.
   On la fixe ici, en dernier, pour tout le monde. */
h1, body.v-page .v-h1, .page-head h1, .visi-hero h1 {
  font-size: clamp(38px, 6.6vw, 100px) !important;
}
@media (max-width: 900px) {
  h1, body.v-page .v-h1, .page-head h1, .visi-hero h1 { font-size: 38px !important; }
}
/* ⚠️⚠️ EXEMPTIONS. `!important` ne bat pas seulement les autres feuilles : il
   bat AUSSI les styles inline, donc les endroits ou un developpeur a dit
   « ce titre-la est different ». Mesure : le h1 de la page 404 portait
   `style="font-size:22px"` et passait a 95 px dans une carte de 358 px —
   scrollWidth 424 pour clientWidth 358, le dernier mot coupe.
   Toute page qui a un titre volontairement petit doit etre listee ici. */
/* ⚠️⚠️ CIBLAGE PRÉCIS. La première version listait `.card h1` : le titre
   PRINCIPAL des pages légales (CGV, mentions, confidentialité) vit dans une
   `.card legal-card` — il tombait donc à 22 px, illisible comme titre de page.
   On vise le TITRE DE LA PAGE D'ERREUR, pas « tout h1 dans une carte ». */
.titre-erreur,
.auth-card > h1 {
  font-size: 22px !important;
}
/* le titre principal des pages légales garde une taille de titre de page */
.legal-card > h1 {
  font-size: clamp(30px, 3.4vw, 44px) !important;
}
@media (max-width: 900px) {
  .legal-card > h1 { font-size: 28px !important; }
}
/* ⚠️⚠️ NE JAMAIS cibler une balise large avec `!important` sans vérifier ce
   qu'elle contient. Ce bloc `h1 { font-size: … !important }` a aussi touché
   `.v-chiffre` — un `<span>` DANS un paragraphe — parce qu'un premier jet
   écrivait `h1, .v-chiffre`. Le prix est passé à 95 px de police : 184 px de
   haut, soit tout l'écran d'un téléphone.
   Un titre et un prix n'ont pas la même échelle : on ne les met JAMAIS dans
   la même règle. */
.v-chiffre, .v-offre-prix, .price, .q-price, .amount, .sl-price {
  font-size: inherit;
}

/* 7. ⚠️⚠️ COULEURS RÉSIDUELLES TROUVÉES PAR MESURE (pas à l'œil).
   Le contrôle du DOM a relevé deux choses qui juraient avec un thème
   noir et blanc :

   a) des LIENS en BLEU PAR DÉFAUT DU NAVIGATEUR — `rgb(0, 0, 238)`.
      Un lien sans `color` explicite hérite du bleu du navigateur. C'est
      visible sur la marque du tiroir et sur des liens du tunnel. Un thème
      binaire doit poser la couleur des liens explicitement, sinon le bleu
      par défaut réapparaît à chaque nouvel élément.
   b) des BORDURES OR ÉCRITES EN DUR — `rgba(176, 138, 62, …)` sur les cartes
      « plan featured » et « dual-plan ». Elles ne passent pas par les jetons,
      donc elles ont survécu à la bascule. Règle : une couleur en dur est un
      défaut à corriger, pas à contourner.
*/
a, a:visited, a:active, a:hover { color: inherit; }
.drawer-brand, .drawer-brand span, .drawer-brand img,
.brand, .brand a, .brand span { color: var(--ink); }

.plan.featured,
.dual-plan,
.visi-card,
.ub-bloc,
.prix-bloc,
.hero-mock .mock-window { border-color: var(--line) !important; }

/* les traits décoratifs qui étaient or deviennent gris.
   ⚠️⚠️ `.measure` EST EXCLU : c'est une ligne de COTATION (un trait fin), pas
   un aplat. Ma première version lui imposait un fond noir — et comme il porte
   aussi du texte, celui-ci devenait NOIR SUR NOIR, invisible. Mesuré sur
   /comment-ca-marche (« MOINS D'UNE MINUTE ») et /logiciel-devis.
   Règle : ne jamais donner un fond plein à un élément qui porte du texte. */
.releve::before,
.hero-3d,
.kicker::before,
.v-kicker::before { background-color: var(--ink) !important; }
.measure {
  background: none !important;              /* un trait, pas un aplat */
  border-color: var(--ink) !important;
  color: var(--faint) !important;           /* le libellé reste lisible */
}

/* le badge et les pastilles : plus d'aplat or */
.hero-badge, .visi-badge, .tag, .v-tag, .promo-temp, .trust-bar,
.ub-badge, .dual-tag, .lo-badge {
  background-color: transparent !important;
  border-color: var(--ink) !important;
  color: var(--ink) !important;
}


/* ============================================================
   EX-carrousel-mobile.css   (3268 octets, 7 !important)
   ============================================================ */

/* ============================================================
   CARROUSEL MOBILE — corrections mesurées le 2026-10-05.

   Trois défauts réels relevés en mesurant, pas en regardant :

   1. ⚠️⚠️ LE PRIX FAISAIT 184 px DE HAUT. Mon unification des titres
      (`h1 { font-size: clamp(38px, 6.6vw, 100px) !important }`) a touché
      `.v-chiffre`, qui est un `<span>` DANS un paragraphe — il a hérité du
      `!important` destiné aux titres. Un prix de 95 px de police, c'est un
      prix qui prend tout l'écran. Un `!important` sur une balise large
      déborde toujours sur ce qu'on n'avait pas prévu : on cible donc
      désormais `h1` SEUL, jamais `*.v-chiffre`.
      Le prix retrouve sa taille de carte : 46 px.

   2. ⚠️ LA CARTE FAISAIT 823 px POUR UN ÉCRAN DE 844. Le bouton « Souscrire »
      tombait tout en bas, hors de vue à l'arrivée, et les commandes du
      carrousel (pastilles, flèches) étaient 4 600 px plus bas : rien ne
      signalait qu'il y avait trois offres. Corrigé : liste plus dense, prix
      ramené à sa taille, et les commandes remontées SOUS la carte visible.

   3. ⚠️ AUCUN INDICE QU'IL Y A D'AUTRES OFFRES. Sur mobile, une diapo
      pleine largeur ne laisse rien deviner. On laisse désormais DÉPASSER un
      bord de la diapo suivante (88 % de largeur) : le visiteur voit qu'il y a
      une suite, et le geste devient évident. C'est le motif que le user a
      lui-même évoqué.
   ============================================================ */

/* 1. le prix : taille de carte, jamais taille de titre.
   ⚠️ On corrige AUSSI la règle h1 de theme-binaire.css pour qu'elle ne
   touche plus `.v-chiffre` : un `!important` mal ciblé se paie ailleurs. */
body.v-page .v-offre-prix,
body.v-page .v-chiffre {
  font-size: 42px !important;
  line-height: 1.05 !important;
  /* ⚠️ le prix et son "/mois" doivent tenir sur UNE ligne : à 46 px sur un
     ecran de 390, "129,90 EUR" passait a la ligne et le bloc faisait 96 px
     de haut. `white-space: nowrap` + une taille qui tient dans la largeur. */
  white-space: nowrap;
}
body.v-page .v-offre-prix small { font-size: 11px !important; margin-left: 5px; }

/* 2. la carte mobile : plus dense, le bouton reste visible */
@media (max-width: 999px) {
  body.v-page .v-piste > [data-diapo] {
    /* 3. la diapo suivante dépasse : un indice visuel, pas un ornement */
    flex: 0 0 88%;
  }
  body.v-page .v-offre { padding: 28px 22px 30px; }
  body.v-page .v-offre-cond { min-height: 0; margin: 10px 0 0; font-size: 14px; }
  body.v-page .v-liste { margin: 18px 0 24px; }
  body.v-page .v-liste li { padding: 9px 0; font-size: 14px; }
  body.v-page .v-offre-prix { margin: 14px 0 2px; }
  body.v-page .v-tag { margin-bottom: 14px; }
  /* les commandes remontent : elles doivent être vues en même temps que la
     carte, sinon le carrousel est invisible */
  body.v-page .v-commandes { margin-top: 18px; }
}

/* la piste prend la gouttière du site, pour que la première carte soit
   alignée comme le reste du contenu */
body.v-page .v-carrousel { margin: 0 calc(var(--v-gouttiere) * -1); }
body.v-page .v-carrousel .v-commandes { margin-left: var(--v-gouttiere); margin-right: var(--v-gouttiere); }
@media (min-width: 1000px) {
  body.v-page .v-carrousel { margin: 0; }
}


/* ============================================================
   EX-respiration.css   (3652 octets, 22 !important)
   ============================================================ */

/* ============================================================
   RESPIRATION — corrections mesurées (2026-10-05).

   Le seul grief de l'audit visuel qui N'ÉTAIT PAS une hallucination portait
   sur /pricing (4/10, la plus mauvaise note) et sur la densité du pied de page.
   Vérifié en pixels avant d'agir :

     /pricing
       • titre h1 : 95 px de police pour 201 px de haut sur une page DENSE
         (4 172 px, 5 sections) — c'est un effet de bord de l'unification des
         titres : la taille convenait à l'accueil (6 sections aérées) mais
         écrase une page de tarifs.
       • sections : padding vertical de 64 px seulement, alors que les autres
         pages sont à 118 px (accueil) — les blocs se touchent.
       • cartes d'offres : 950 px de haut, padding 36 px — très serré.

     pied de page
       • 22 liens, padding de 2 px par lien, police 12,5 px, écart de grille
         24 px : les colonnes sont collées.
       • padding du footer 28 px en haut — étroit pour 4 colonnes de contenu.

   ⚠️ On N'AUGMENTE PAS les valeurs au hasard : on aligne /pricing sur la
   respiration mesurée des autres pages, et on aère le pied de page d'un cran.
   ============================================================ */

/* ---------- /pricing : respiration alignée sur le reste du site ---------- */
/* le h1 des pages denses : la taille de l'accueil écrase une page de tarifs.
   ⚠️ On ne touche PAS au h1 de l'accueil (il est validé) : on cible la classe
   de la page de tarifs via son conteneur. */
.page-head h1 {
  font-size: clamp(34px, 4.8vw, 62px) !important;
}
@media (max-width: 900px) {
  .page-head h1 { font-size: 32px !important; }
}

/* les sections de /pricing passent de 64 a 96 px de respiration verticale */
.section {
  padding-top: 96px !important;
  padding-bottom: 96px !important;
}
@media (max-width: 900px) {
  .section { padding-top: 64px !important; padding-bottom: 64px !important; }
}

/* les cartes d'offres : plus d'air a l'interieur, et un ecart entre elles */
.plan, .plan.featured {
  padding: 44px 38px !important;
}
.plans { gap: 20px !important; }
@media (max-width: 900px) {
  .plan, .plan.featured { padding: 32px 24px !important; }
  .plans { gap: 14px !important; }
}

/* ---------- pied de page : moins dense ---------- */
.footer { padding: 48px 0 26px !important; }
.footer-grid { gap: 48px 40px !important; }
.footer a { padding: 7px 0 !important; }
.footer h4 { margin-bottom: 18px !important; }
.footer .bottom { margin-top: 40px !important; padding-top: 24px !important; }
@media (max-width: 900px) {
  .footer { padding: 36px 0 22px !important; }
  .footer-grid { gap: 32px 24px !important; }
  .footer a { padding: 8px 0 !important; }
}

/* ---------- blocs à padding NUL (mesuré) ----------
   ⚠️⚠️ DÉFAUT RÉEL trouvé par l'audit visuel, VÉRIFIÉ en pixels avant
   correction : `.visi-block` et `.votre-site` avaient `padding: 0px` avec une
   bordure de 1 px. Leur contenu TOUCHAIT donc la bordure — c'est le grief
   « le texte frôle les bords » du modèle, et cette fois il avait raison.
   ⚠️ Le padding appartient au bloc, pas à une div interne : sinon il ne reste
   aucune respiration entre le contenu et la bordure. */
.visi-block,
.votre-site,
.dual-plan,
.cond-bloc,
.ub-bloc {
  padding: 40px 38px !important;
}
/* si le bloc contient deja des colonnes, on garde le padding mais on reduit
   l'ecart interne pour ne pas doubler la respiration */
.visi-block .visi-copy,
.votre-site > div,
.dual-plan > div { padding: 0 !important; }

@media (max-width: 900px) {
  .visi-block, .votre-site, .dual-plan, .cond-bloc, .ub-bloc {
    padding: 26px 20px !important;
  }
}


/* ============================================================
   EX-langage-visuel.css   (3131 octets, 10 !important)
   ============================================================ */

/* ============================================================
   UN SEUL LANGAGE VISUEL — corrections mesurées (2026-10-05).

   Le user a dit « je déteste le site ». Mes contrôles ne l'avaient pas vu
   parce qu'ils validaient chaque page ISOLÉMENT. La mesure d'ensemble dit
   autre chose :

     page            design        rayons              ombres
     /               v- (neuf)     aucun                  0
     /pricing        luxe (anc.)   10px(3), 16px(1)       4
     /services/...   luxe (anc.)   10px(15), 40px(1)     16
     /comment...     luxe (anc.)   10px(7)                8
     /logiciel...    luxe (anc.)   10px(12)               9
     /prix/plombier  luxe (anc.)   10px(324), 6px(3)      4
     /app            luxe (anc.)   6px(15), 10px(6)       5

   ⚠️ UNE SEULE page sur douze suivait le nouveau langage. Le site change
   d'identité à chaque clic — c'est ce qu'un humain ressent comme « mal fait »
   sans pouvoir le nommer.

   ⚠️⚠️ CORRECTION À LA SOURCE, PAS PAGE PAR PAGE. Le langage visuel du site
   refait tient en trois règles :
       • angles DROITS (rayon 0) ;
       • AUCUNE ombre (les aplats et les filets séparent) ;
       • AUCUN dégradé (aplats).
   On les applique globalement. C'est le seul moyen qu'une page ajoutée plus
   tard hérite du bon langage au lieu de ramener les arrondis.

   ⚠️ EXCEPTIONS VOLONTAIRES (ne pas « corriger ») :
       • le LOGO : le carré or a ses propres angles ;
       • `.mock-window` : la maquette d'un site client montre le PRODUIT vendu,
         qui a son propre style ;
       • les pastilles rondes et les avatars, où le rond est sémantique.
   ============================================================ */

/* ---------- 1. ANGLES DROITS PARTOUT ---------- */
*,
*::before,
*::after {
  border-radius: 0 !important;
}

/* les exceptions : ce qui doit rester rond */
.brand-mark,
.brand-mark img,
.brand-mark svg,
.drawer-mark img,
.mock-window,
.mock-window *,
.avatar,
.user-avatar,
.drawer-avatar,
.t-step,
.v-point,
.mock-dot,
.dot,
.check {
  border-radius: initial !important;
}
/* le logo garde ses angles propres */
.brand-mark img, .brand-mark svg, .drawer-mark img { border-radius: 0 !important; }
/* la pastille du carrousel : carree dans le design, on l'assume */
.v-pastille { border-radius: 0 !important; }

/* ---------- 2. AUCUNE OMBRE ---------- */
*,
*::before,
*::after {
  box-shadow: none !important;
}
/* la seule ombre tolérée : détacher la fenêtre de maquette du fond */
.mock-window {
  box-shadow: 0 24px 60px rgba(10, 10, 10, .10) !important;
}
/* la barre collée a besoin d'un fond opaque, pas d'une ombre */
.topbar, .nav { box-shadow: none !important; }

/* ---------- 3. AUCUN DÉGRADÉ (aplats seulement) ---------- */
.btn.primary,
.btn.big,
button.primary,
.drawer-cta,
[class*="gradient"] {
  background-image: none !important;
}

/* ---------- 4. LES BORDURES : un filet fin, jamais épais ---------- */
.card, .plan, .panel, .legal-card, .auth-card, .visi-card,
.dual-plan, .votre-site, .v-offre, .visi-block, .prix-bloc, .cond-bloc {
  border-width: 1px !important;
  border-style: solid !important;
}


/* ============================================================
   EX-echelle-unique.css   (4701 octets, 36 !important)
   ============================================================ */

/* ============================================================
   ÉCHELLE UNIQUE — le site n'a plus qu'UNE hiérarchie de titres.

   ⚠️⚠️ LE VRAI DÉFAUT, MESURÉ (2026-10-05). Le user a dit « je déteste le
   site ». Mes contrôles validaient chaque page ISOLÉMENT : ils ne pouvaient
   pas voir ceci. Mesure d'ensemble :

     page         h2 principal   h3 de contenu   mots/écran
     accueil      60 px          25 px           109
     pricing      58 px          —               111
     visibilite   58 px          —               122
     metier       58 px          20-27 px        119
     comment      58 px          27 px           110
     logiciel     58 px          27 px           103
     apropos      58 px          27 px           108
     cgv          58 px          —               204   <<< 2x plus dense
     contact      — (1 seul titre)                95

   Trois échelles de titres, deux rythmes de page. En naviguant, la hiérarchie
   change : c'est ce qu'un humain ressent comme « pas fini ».

   ⚠️ ON POSE UNE ÉCHELLE, PAS DES TAILLES AU CAS PAR CAS. Une échelle est un
   rapport constant : si on ajuste une valeur pour une page, toutes les autres
   doivent suivre. On la fixe ici, une fois.

   Échelle retenue (rapport ~1,6 entre les niveaux) :
     h1  page      56 px   (titre de page)
     h2  section   40 px
     h3  bloc      25 px    (plafond, jamais au-dessus)
   ⚠️ L'ACCUEIL GARDE SON h1 GÉANT (95 px) : c'est une page de vente dont le
   titre EST le message. On exempte explicitement `.v-h1`.
   ============================================================ */

/* ---------- l'échelle ---------- */
h1, .page-head h1, .visi-hero h1, .legal-card > h1 {
  font-size: 56px !important;
  line-height: 1.02 !important;
  letter-spacing: -.01em !important;
}
h2, .section-head h2, .visi-guide-title, .v-h2 {
  font-size: 40px !important;
  line-height: 1.05 !important;
}
h3, .v-h3, .card h3, .presta-item h3, .pain-item h3 {
  font-size: 25px !important;
  line-height: 1.12 !important;
}

/* ---------- les exemptions, volontaires et nommées ---------- */
/* l'accueil : son titre géant EST le message de vente */
.v-h1,
.v-sec-head .v-h2,
.v-final .v-h2,
.v-vaste {
  font-size: unset !important;
}
.v-h1 { font-size: clamp(40px, 6.6vw, 100px) !important; }
.v-sec-head .v-h2, .v-final .v-h2 { font-size: clamp(30px, 4.2vw, 58px) !important; }
.v-h1 .v-barre, .v-h1 .v-or { font-size: inherit !important; }
/* la 404 : titre secondaire, volontairement petit */
.titre-erreur, .auth-card > h1 { font-size: 22px !important; }

@media (max-width: 900px) {
  h1, .page-head h1, .visi-hero h1, .legal-card > h1 { font-size: 32px !important; }
  h2, .section-head h2, .v-h2 { font-size: 26px !important; }
  h3, .v-h3 { font-size: 20px !important; }
  .v-h1 { font-size: 38px !important; }
  .v-sec-head .v-h2, .v-final .v-h2 { font-size: 26px !important; }
  .titre-erreur, .auth-card > h1 { font-size: 20px !important; }
}

/* ---------- RYTHME DE SECTION UNIQUE ---------- */
/* mesuré : /cgv et /contact n'ont pas le même rythme que les autres.
   On impose un seul pas vertical a toutes les sections de contenu. */
.section,
.section.alt,
.v-sec,
.page-head {
  padding-top: 88px !important;
  padding-bottom: 88px !important;
}
/* le pied de page et les blocs serrés gardent leur rythme propre */
.footer, .cta-final, .v-final { padding-top: unset !important; padding-bottom: unset !important; }
.v-final { padding-top: 120px !important; padding-bottom: 120px !important; }
@media (max-width: 900px) {
  .section, .section.alt, .v-sec { padding-top: 56px !important; padding-bottom: 56px !important; }
  .v-final { padding-top: 72px !important; padding-bottom: 72px !important; }
}

/* ---------- LA PAGE CGV : trop dense ---------- */
/* mesure : 204 mots par ecran, contre ~110 partout ailleurs. Une page legale
   se lit, elle ne se survole pas : on aere le texte.
   ⚠️⚠️ PADDING HORIZONTAL RETIRE (corrige 2026-10-05). Le `52px` de gauche
   décalait TOUT le texte de la page CGV de 52 px par rapport à l'axe du site
   (texte à 241 px au lieu de 188) — c'est le « décalage dans les ecritures »
   signalé par l'utilisateur. On garde l'aeration VERTICALE (le but d'origine),
   on remet l'horizontale à zero : le texte tombe sur l'axe, comme partout. */
.legal-card { padding: 56px 0 !important; }
.legal-card p { margin-bottom: 18px !important; line-height: 1.75 !important; max-width: 78ch; }
.legal-card h2 { margin-top: 44px !important; margin-bottom: 14px !important; }
@media (max-width: 900px) {
  .legal-card { padding: 28px 0 !important; }
  .legal-card p { margin-bottom: 14px !important; }
  .legal-card h2 { margin-top: 32px !important; }
}

/* ===== fin devisaly.css ===== */

/* ===== début sections.css ===== */
/* ============================================================
   SYSTÈME DE SECTIONS — le vocabulaire commun de tout le site.

   ⚠️⚠️ POURQUOI CE FICHIER EXISTE. L'accueil a été refait avec ses propres
   classes (`v-hero`, `v-sec`, `v-grille`, `v-offres`…) et les 11 autres pages
   sont restées sur le vocabulaire historique (`.section`, `.section-head`,
   `.card`, `.plans`). Résultat : pour aligner les deux, j'avais empilé des
   `!important` dans 15 feuilles.

   Ici, on donne un VOCABULAIRE UNIQUE, repris de l'accueil, que toutes les
   pages peuvent utiliser :

     .s-sec          une section (padding vertical unique)
     .s-tete         l'en-tête d'une section : titre + numéro
     .s-num          le numéro « 01 — La prestation »
     .s-grille       une grille de blocs (2, 3 ou 4 colonnes selon data-col)
     .s-bloc         un bloc de la grille : numéro, titre, texte
     .s-liste        une liste de bénéfices (filet fin entre les items)
     .s-offres       la grille des offres
     .s-offre        une carte d'offre
     .s-encadre      un encadré (bordé, aplat clair)
     .s-duo          deux colonnes : argument à gauche, action à droite

   ⚠️ CE VOCABULAIRE EST IDENTIQUE A L'ACCUEIL : mêmes valeurs de padding,
   mêmes tailles, mêmes filets. C'est ce qui fait qu'une page refaite avec
   ces classes est AUTOMATIQUEMENT cohérente, sans `!important`.

   ⚠️ RÈGLE : une page refaite n'utilise QUE ces classes. Si une page a besoin
   d'une variante, on l'ajoute ICI, pas dans un fichier séparé.
   ============================================================ */

/* ---------- section ---------- */
.s-sec {
  padding: 88px 28px;
  border-top: 1px solid var(--line);
}
.s-sec:first-of-type { border-top: 0; }
.s-sec > * { max-width: 1120px; margin-left: auto; margin-right: auto; }

/* ---------- en-tête de section ---------- */
.s-tete {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 40px; flex-wrap: wrap; margin-bottom: 56px;
}
.s-tete h2 { max-width: 22ch; }
.s-tete p { max-width: 62ch; margin: 16px 0 0; color: var(--muted); font-size: 16px; }
.s-num {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink); white-space: nowrap;
}

/* ---------- grille ---------- */
.s-grille {
  display: grid; gap: 0; border-top: 1px solid var(--line);
  grid-template-columns: repeat(2, 1fr);
}
.s-grille[data-col="3"] { grid-template-columns: repeat(3, 1fr); }
.s-grille[data-col="4"] { grid-template-columns: repeat(4, 1fr); }

.s-bloc {
  padding: 34px 30px 34px 0;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  min-width: 0;
}
.s-bloc:last-child { border-right: 0; }
/* la grille a 2 colonnes : un filet a droite des impairs */
.s-grille[data-col="2"] .s-bloc:nth-child(2n) { border-right: 0; padding-right: 0; }
.s-grille[data-col="3"] .s-bloc:nth-child(3n) { border-right: 0; }
.s-grille[data-col="4"] .s-bloc:nth-child(4n) { border-right: 0; }
.s-bloc:nth-child(2) { padding-left: 30px; }
.s-grille[data-col="3"] .s-bloc:nth-child(3n+2) { padding-left: 30px; }
.s-grille[data-col="4"] .s-bloc:nth-child(4n+3) { padding-left: 30px; }

.s-bloc .n {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em;
  display: block; margin-bottom: 18px; color: var(--ink);
}
.s-bloc h3 { margin: 0 0 12px; }
.s-bloc p { margin: 0; color: var(--muted); font-size: 15px; max-width: 46ch; }

/* ---------- liste de bénéfices ---------- */
.s-liste { list-style: none; margin: 0; padding: 0; }
.s-liste li {
  padding: 12px 0; border-bottom: 1px solid var(--line);
  font-size: 15px; color: var(--ink);
}
.s-liste li:last-child { border-bottom: 0; }

/* ---------- offres ---------- */
.s-offres {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1px; background: var(--line); border: 1px solid var(--line);
}
.s-offre {
  background: var(--card); padding: 40px 34px 44px;
  display: flex; flex-direction: column; min-width: 0;
}
.s-offre.mise { background: var(--paper-2); }
.s-offre .nom {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink); margin: 0;
}
/* ⚠️⚠️ LINE-HEIGHT ET PADDING POUR ANTON.
   Bug mesuré : a `line-height: 1.05` le prix faisait `scrollHeight=58` dans une
   boite de `48` — le haut des chiffres etait COUPE de 10 px (« 14,99 » perdait
   son sommet). Anton a une hauteur de glyphe superieure a l'interligne. */
.s-offre .prix {
  font-family: var(--font-serif); font-size: 46px;
  margin: 18px 0 4px; line-height: 1.18; padding: .04em 0; color: var(--ink);
}
.s-offre .prix small {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em;
  color: var(--muted); margin-left: 6px;
}
.s-offre .cond { font-size: 14.5px; color: var(--muted); margin: 10px 0 0; }
.s-offre .s-liste { margin: 24px 0 30px; flex: 1; }
.s-offre .tag {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .16em;
  border: 1px solid var(--ink); padding: 4px 9px; display: inline-block;
  margin-bottom: 18px; text-transform: uppercase; align-self: flex-start;
  color: var(--ink);
}

/* ---------- encadré ---------- */
.s-encadre {
  border: 1px solid var(--line); background: var(--paper-2);
  padding: 48px 44px;
}
.s-encadre h2 { max-width: 24ch; margin-bottom: 24px; }

/* ---------- duo argument / action ---------- */
.s-duo {
  display: grid; grid-template-columns: 1.3fr .8fr; gap: 1px;
  background: var(--line); border: 1px solid var(--line);
}
.s-duo > div { background: var(--card); padding: 40px 38px; min-width: 0; }
.s-duo > div:last-child { background: var(--paper-2); display: flex; flex-direction: column; justify-content: center; }
.s-duo .accroche {
  font-family: var(--font-serif); font-size: 26px; line-height: 1.08;
  margin: 0 0 22px; color: var(--ink);
}

/* ---------- adaptation ---------- */
@media (max-width: 1000px) {
  .s-grille[data-col="4"] { grid-template-columns: repeat(2, 1fr); }
  .s-offres { grid-template-columns: 1fr; }
  .s-duo { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .s-sec { padding: 56px 20px; }
  .s-tete { margin-bottom: 36px; }
  .s-grille, .s-grille[data-col="3"] { grid-template-columns: 1fr; }
  .s-bloc, .s-bloc:nth-child(2) { padding: 28px 0; border-right: 0; }
  .s-encadre { padding: 30px 22px; }
  .s-duo > div { padding: 28px 22px; }
  .s-offre { padding: 30px 24px 34px; }
  .s-offre .prix { font-size: 38px; }
}

/* ============================================================
   TUNNEL DE L'OFFRE (/visibilite)
   ⚠️ Meme langage que le reste : angles droits, filets fins, aucun aplat
   colore, et l'echelle de titres unique. Les classes `visi-*` sont
   conservees (elles portent la logique du tunnel) mais leur STYLE est
   ramene au langage commun.
   ============================================================ */
/* ⚠️⚠️ LE PADDING ETAIT COMPTE DEUX FOIS. `.s-sec` porte deja `padding: 88px 28px`
   et `.s-tunnel` ajoutait `padding: 0 28px` : le contenu cadrait a 244 px au lieu
   de 216, soit 28 px de decalage avec /pricing. Meme piege que le hero de
   l'accueil. Un seul endroit porte la gouttiere : la SECTION. */
.s-tunnel { max-width: 1120px; margin: 0 auto; padding: 0; }

/* le hero du tunnel : titre + preuve, deux colonnes */
.visi-hero { padding: 64px 0 48px; border-bottom: 1px solid var(--line); }
.visi-eyebrow {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink); display: block; margin-bottom: 20px;
}
.visi-hero h1 { max-width: 20ch; margin: 0 0 24px; }
.visi-hero p { max-width: 62ch; color: var(--muted); font-size: 17px; margin: 0; }
.visi-whats-included {
  display: flex; flex-wrap: wrap; gap: 12px 32px; margin-top: 28px;
  padding-top: 24px; border-top: 1px solid var(--line);
}
.visi-item { display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--ink); }
.visi-item svg { flex: none; }

/* les exemples de sites : trois colonnes, filets */
.visi-proof-head { margin-bottom: 34px; }
.visi-proof-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.proof-card { background: var(--card); padding: 24px; margin: 0; min-width: 0; }
.proof-card img { width: 100%; height: auto; display: block; border: 1px solid var(--line); }
.proof-card figcaption { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .1em; color: var(--muted); margin-top: 14px; }
.visi-proof-note { font-size: 14.5px; color: var(--muted); margin-top: 24px; max-width: 78ch; }

/* le calculateur : deux colonnes */
.visi-calc { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
.visi-calc-copy h2 { max-width: 20ch; margin-bottom: 20px; }
.visi-calc-points { list-style: none; margin: 0 0 28px; padding: 0; }
.visi-calc-points li { padding: 11px 0; border-bottom: 1px solid var(--line); font-size: 15px; color: var(--ink); }
.visi-calc-shot { border: 1px solid var(--line); background: var(--card); }
.vcs-bar { display: flex; align-items: center; gap: 7px; padding: 12px 15px; border-bottom: 1px solid var(--line); background: var(--paper-2); }
.vcs-bar span { width: 9px; height: 9px; background: var(--line); display: block; }
.vcs-bar em { font-family: var(--font-mono); font-size: 11px; color: var(--muted); font-style: normal; margin-left: 8px; }
.vcs-body { padding: 22px; }
.vcs-t { font-family: var(--font-serif); font-size: 20px; margin-bottom: 16px; color: var(--ink); }
.vcs-l { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14px; color: var(--ink); }
.vcs-l i { display: none; }
.vcs-tot { display: flex; justify-content: space-between; padding-top: 16px; font-size: 15px; color: var(--ink); }

/* la mise en page guide + carte de paiement */
.visi-layout { display: grid; grid-template-columns: 1.15fr .85fr; gap: 64px; align-items: start; }
.visi-guide-block { margin-bottom: 44px; }
.visi-guide-title { font-size: 25px; margin: 0 0 18px; }
.visi-steps-guide { list-style: none; margin: 0; padding: 0; counter-reset: vg; }
.visi-steps-guide li { display: flex; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--line); font-size: 15px; counter-increment: vg; }
.visi-steps-guide li strong { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em; color: var(--ink); min-width: 26px; }
.visi-steps-guide li p { margin: 4px 0 0; color: var(--muted); }
/* la FAQ */
.visi-q { border-bottom: 1px solid var(--line); }
.visi-q summary { cursor: pointer; padding: 16px 0; font-family: var(--font-serif); font-size: 17px; color: var(--ink); list-style: none; }
.visi-q summary::-webkit-details-marker { display: none; }
.visi-q p { margin: 0 0 16px; font-size: 14.5px; color: var(--muted); }
.visi-guide-reassure ul { list-style: none; margin: 0; padding: 0; }
.visi-guide-reassure li { padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 15px; color: var(--ink); }

/* la carte de paiement : aplat clair, filet, angles droits */
.visi-card { border: 1px solid var(--ink); background: var(--card); padding: 32px 30px; position: sticky; top: 90px; }
.visi-summary { display: block; }
.visi-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; }
.visi-plan-name { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink); }
.visi-price { font-family: var(--font-serif); font-size: 44px; line-height: 1.18; padding: .04em 0; margin: 12px 0 0; color: var(--ink); }
.visi-price-major { }
.visi-price small { font-family: var(--font-mono); font-size: 12px; color: var(--muted); margin-left: 5px; }
.visi-badge { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; border: 1px solid var(--ink); padding: 4px 9px; color: var(--ink); }
.visi-badges { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.visi-list { list-style: none; margin: 24px 0; padding: 0; }
.visi-list li { padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14.5px; color: var(--ink); }
.visi-separator { height: 1px; background: var(--line); margin: 24px 0; }
.visi-pay-title { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink); }
.visi-note { font-size: 14px; color: var(--muted); margin: 8px 0 18px; }
.visi-pay label { display: block; font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin: 14px 0 7px; }
.visi-pay input[type=email] { width: 100%; padding: 14px 15px; border: 1px solid var(--line); background: var(--card); color: var(--ink); font-size: 15px; }
.visi-consent { display: flex; gap: 12px; align-items: flex-start; margin: 18px 0; font-size: 13.5px; color: var(--muted); text-transform: none; letter-spacing: 0; }
.visi-consent input { margin-top: 3px; flex: none; }
.visi-consent a { color: var(--ink); }
.visi-tiny { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; color: var(--muted); text-align: center; margin-top: 14px; }
.visi-alt { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 14px; color: var(--muted); }
.visi-alt a { color: var(--ink); }

@media (max-width: 1000px) {
  .visi-proof-grid, .visi-calc, .visi-layout { grid-template-columns: 1fr; gap: 28px; }
  .visi-card { position: static; }
}
@media (max-width: 900px) {
  /* ⚠️ MEME DOUBLE PADDING QUE SUR DESKTOP (corrige 2026-10-05) : `.s-sec` porte
     deja la gouttiere, le `20px` ici la comptait une 2e fois -> texte a 38 px au
     lieu de l'axe (18 px) sur /visibilite mobile. */
  .s-tunnel { padding: 0; }
  .visi-hero { padding: 40px 0 32px; }
  .visi-guide-title { font-size: 20px; }
  .visi-price { font-size: 36px; }
}

/* ⚠️ COHÉRENCE D'ALIGNEMENT sur /visibilite : le hero et les bénéfices étaient
   CENTRÉS, la suite ALIGNÉE À GAUCHE. Mesure : le passage était brusque.
   Tout le site est aligné à gauche — on aligne ce bloc comme le reste. */
.visi-hero { text-align: left; }
.visi-hero h1, .visi-hero p { margin-left: 0; margin-right: 0; }
.visi-whats-included { justify-content: flex-start; }

/* ============================================================
   ECRAN D'OUVERTURE — une seule regle, robuste partout.

   ⚠️⚠️ LEÇON DE MES DIX PALIERS. J'ai empilé des media queries par largeur ET
   par hauteur (`max-height: 860/780/760/700/680`, `max-width: 900/420`). Elles
   se combattaient : a 360x740 le hero faisait 818 px pour un ecran de 740, et
   corriger un palier cassait le precedent.

   LA REGLE JUSTE, en une ligne :
       min-height: min(100svh, 900px)
   → sur un grand ecran, le hero fait un plein ecran (l'effet de la reference) ;
   → sur un petit ecran, il s'arrete a 900 px et GRANDIT selon son contenu,
     sans jamais forcer un plein ecran qui deborderait.

   ⚠️ On ne cache JAMAIS le sous-titre pour gagner de la place : c'est du
   contenu de vente. On laisse la page defiler de quelques pixels si besoin —
   invisible pour le visiteur, contrairement a un texte rogne.
   ============================================================ */
body.v-page .v-hero {
  min-height: min(100svh, 900px);
  padding-top: 118px !important;
  padding-bottom: 56px !important;
  display: flex; flex-direction: column; justify-content: center;
}
@media (max-width: 900px) {
  body.v-page .v-hero { padding-top: 88px !important; padding-bottom: 40px !important; }
  /* ⚠️⚠️ LE TITRE ETAIT ECRASE (corrige 2026-10-05). Deux divergences mesurees
     avec la maquette VALIDEE (previews/accueil-blanc.html, 390px) :
       - taille : maquette 46,8px  ->  ici 30px (36 % plus petit) ;
       - largeur : maquette 350px (pleine colonne) -> ici 255px, bride par le
         `max-width: 17ch` de `vitrine.css` (17ch en Anton ~ 255px).
     Resultat : un titre de 30px en Anton, coince dans 65 % de la largeur, avec
     117px de vide a droite — c'est ce qui donne l'impression de casse.
     On revient a la maquette : titre plus grand et pleine largeur. */
  body.v-page .v-h1 { font-size: clamp(34px, 11vw, 50px) !important; max-width: none; }
  .v-hero-sub { margin-top: 18px; font-size: 15px; }
  .v-hero-cta { margin-top: 22px; }
  .v-hero-facts { margin-top: 26px; }
  .v-hero-facts > div { padding: 12px 0 0; }
  .v-hero-facts dd { font-size: 18px; }
}
@media (max-width: 900px) and (max-height: 860px) {
  /* ⚠️⚠️ LE HERO DEVENAIT PLUS HAUT QUE L'ECRAN sur petit telephone.
     Mesure : 840 px pour un ecran de 740, et 864 px pour un ecran de 568.
     Le sol en perspective tombait alors SOUS la ligne de flottaison.
     ⚠️ La cause n'est pas le texte mais les ESPACEMENTS : 88 px en haut,
     30 px entre chaque bloc, 162 px de bandeau. On les resserre par paliers,
     sans jamais reduire la lisibilite du texte au-dela du raisonnable. */
  body.v-page .v-hero { padding-top: 68px !important; padding-bottom: 26px !important; }
  body.v-page .v-h1 { font-size: clamp(32px, 10vw, 46px) !important; }
  .v-hero-sub { margin-top: 14px; font-size: 14.5px; }
  .v-hero-cta { margin-top: 16px; }
  .v-hero-facts { margin-top: 18px; }
  .v-hero-facts > div { padding: 8px 0 0; }
  .v-hero-facts dt { font-size: 10px; }
  .v-hero-facts dd { font-size: 15px; margin-top: 3px; }
}
@media (max-width: 900px) and (max-height: 700px) {
  body.v-page .v-hero { padding-top: 56px !important; padding-bottom: 20px !important; }
  body.v-page .v-h1 { font-size: clamp(30px, 9vw, 40px) !important; }
  .v-hero-sub { margin-top: 12px; font-size: 14px; }
  .v-hero-cta { margin-top: 14px; }
  .v-hero-cta .v-btn { padding: 13px 18px; font-size: 11px; }
  .v-hero-facts { margin-top: 14px; }
  .v-hero-facts dd { font-size: 14px; }
}
@media (max-width: 900px) and (max-height: 600px) {
  body.v-page .v-hero { padding-top: 48px !important; padding-bottom: 16px !important; }
  body.v-page .v-h1 { font-size: clamp(26px, 8vw, 34px) !important; }
  /* ⚠️⚠️ IL FALLAIT AUSSI LES ESPACEMENTS INTERNES ET LES BOUTONS.
     Mesure : sur un 320x568, le bloc CTA faisait 194 px — les trois elements
     (bouton plein, bouton vide, mention) s'empilaient sur 284 px de large, et
     le bouton principal faisait 75 px de haut. Les marges du sous-titre (30 px)
     et du bandeau (40 px) n'etaient pas couvertes non plus. Une regle de
     padding seul ne suffit pas : il faut TOUTE la chaine d'espacements. */
  body.v-page .v-hero-sub { margin-top: 10px !important; font-size: 13px !important; }
  body.v-page .v-hero-cta { margin-top: 12px !important; gap: 8px !important; }
  body.v-page .v-hero-cta .v-btn { padding: 11px 14px !important; font-size: 10.5px !important; width: 100%; }
  body.v-page .v-hero-note { font-size: 10px !important; margin-left: 0 !important; }
  body.v-page .v-hero-facts { margin-top: 12px !important; }
  body.v-page .v-hero-facts > div { padding: 7px 0 0 !important; }
  body.v-page .v-hero-facts dt { font-size: 9px !important; }
  body.v-page .v-hero-facts dd { font-size: 13px !important; margin-top: 2px !important; }
  body.v-page .v-kicker { margin-bottom: 14px !important; }
}

/* ============================================================
   PAGES DE CONTENU — /comment-ca-marche, /a-propos, /resultats,
   /logiciel-devis, et les pages legales.
   ⚠️ Meme langage : filets fins, angles droits, echelle unique, aucun aplat
   colore. Les classes historiques (steps, faq-item, valeur) sont ramenees au
   langage commun au lieu d'etre remplacees — moins de risque de casse.
   ============================================================ */

/* ⚠️⚠️ LA CARTE LEGALE ETAIT HORS AXE (corrige 2026-10-05).
   `.container.narrow` (840 px, CENTRE sur lui-meme) faisait demarrer le texte a
   328 px (/contact) et 381 px (/cgv) alors que TOUT le site est sur l'axe du
   conteneur standard : contenu a 188 px. Mesure : +140 px et +193 px — c'est le
   « decalage dans les ecritures » signale par l'utilisateur.
   Les 4 templates legaux utilisent desormais `.container` ; on garde ici une
   largeur de LECTURE confortable, mais ANCRÉE A GAUCHE du conteneur (donc sur
   l'axe), jamais centree sur elle-meme. */
/* les etapes numerotees */
.steps { list-style: none; margin: 0; padding: 0; display: grid;
         grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--line); }
.steps li { padding: 32px 28px 32px 0; border-bottom: 1px solid var(--line);
            border-right: 1px solid var(--line); min-width: 0; }
.steps li:last-child { border-right: 0; }
.steps .step-num, .steps .num { font-family: var(--font-mono); font-size: 11.5px;
            letter-spacing: .18em; color: var(--ink); display: block; margin-bottom: 16px; }
.steps h3 { margin: 0 0 10px; }
.steps p { margin: 0; font-size: 15px; color: var(--muted); }

/* la FAQ : meme traitement que le carrousel des offres */
.faq-item, .faq-acc { border-bottom: 1px solid var(--line); }
.faq-item h3, .faq-acc summary { font-family: var(--font-serif); font-size: 20px;
            padding: 18px 0; margin: 0; color: var(--ink); }
.faq-item p, .faq-acc-body p { margin: 0 0 18px; font-size: 15px; color: var(--muted);
            max-width: 78ch; }
details.faq-item summary, details.faq-acc summary {
            cursor: pointer; list-style: none; display: flex;
            justify-content: space-between; align-items: center; gap: 20px; }
details.faq-item summary::-webkit-details-marker,
details.faq-acc summary::-webkit-details-marker { display: none; }
details.faq-item summary::after, details.faq-acc summary::after {
            content: '+'; font-family: var(--font-mono); color: var(--ink); font-size: 18px; }
details[open].faq-item summary::after, details[open].faq-acc summary::after { content: '–'; }

/* les blocs de valeurs / arguments */
.value-card, .valeurs .card, .preuve-card {
            border: 1px solid var(--line); background: var(--card);
            padding: 28px 26px; }
.value-card h3, .preuve-card h3 { margin: 0 0 10px; }
.value-card p, .preuve-card p { margin: 0; font-size: 15px; color: var(--muted); }
.value-card svg, .preuve-card svg { color: var(--ink); margin-bottom: 16px; }

/* les chiffres / statistiques : police display, filet */
.stat, .kpi, .chiffre-cle {
            border-top: 1px solid var(--line); padding-top: 18px; }
.stat b, .kpi b, .chiffre-cle b {
            font-family: var(--font-serif); font-size: 40px; line-height: 1.18;
            padding: .04em 0; display: block; color: var(--ink); }
.stat span, .kpi span, .chiffre-cle span {
            font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .16em;
            text-transform: uppercase; color: var(--muted); }

/* le contenu long (pages legales) : lisibilite avant tout.
   ⚠️⚠️ DOUBLE DECALAGE CORRIGE (2026-10-05), c'etait le « decalage dans les
   ecritures » signale par l'utilisateur :
     1. `margin: 0 auto` CENTRAIT la carte -> texte a 353 px au lieu de 188.
     2. le `padding` horizontal de 52 px de la carte décalait ENCORE le texte de
        52 px (241 px au lieu de 188).
   On retire donc le cadre sur les pages legales : meme `max-width` de lecture
   (840 px), mais SANS bordure, fond ni padding horizontal -> le texte tombe
   exactement sur l'axe du site (188 px desktop / 18 px mobile), comme les autres
   pages. Un seul axe pour tout le site. */
.legal-card, .legal-page { border: 0; background: transparent;
            padding: 0; max-width: 840px; margin: 0; }
.legal-card h1, .legal-page h1 { margin-bottom: 12px; }
.legal-card h2, .legal-page h2 { margin: 40px 0 14px; }
.legal-card p, .legal-page p { font-size: 15px; line-height: 1.75;
            margin-bottom: 16px; color: var(--ink); max-width: 78ch; }
.legal-card .updated, .legal-page .updated {
            font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .14em;
            color: var(--muted); margin-bottom: 32px; }
.legal-card .back, .legal-page .back {
            display: inline-block; margin-top: 32px; font-family: var(--font-mono);
            font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase;
            color: var(--ink); text-decoration: none; }

@media (max-width: 900px) {
  .steps { grid-template-columns: 1fr; }
  .steps li { border-right: 0; padding-right: 0; }
  .legal-card, .legal-page { padding: 28px 20px; }
}

/* ============================================================
   HERO DES PAGES METIER (/services/<metier>) — alignement bas.

   ⚠️ MESURE : le hero est un grid 2 colonnes (529 px | 487 px). Le bouton
   (colonne gauche) finissait a y=429 et le bloc « trust » (colonne droite)
   a y=433 — 4 px d'ecart visibles comme un desequilibre. Les deux colonnes
   doivent se terminer sur la MEME ligne.
   ============================================================ */
.hero { align-items: end; }
.hero .cta-row, .hero .trust { align-self: end; }
@media (max-width: 900px) {
  .hero { align-items: start; }
}

/* ============================================================
   CANVAS 3D DU HERO — restaure (il avait disparu avec la refonte).

   ⚠️⚠️ CE QUI S'EST PASSE. En reecrivant l'accueil, j'ai supprime le canvas
   `atelier3d` ET son script. Le user l'a vu immediatement : « plus d'effet 3d,
   plus haut de gamme ». C'etait l'element qui donnait l'impression de qualite.
   ⚠️ C'est un FOND : position absolue, derriere le contenu, non cliquable.
   ⚠️ `atelier3d.js` gere lui-meme : arret apres 10 s (pas de cout CPU), gel
   hors ecran, `prefers-reduced-motion`, et repli Canvas 2D si WebGL manque.
   ============================================================ */
.v-hero-3d {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.v-hero-3d canvas {
  display: block;
  width: 100%;
  height: 100%;
}
/* le contenu reste AU-DESSUS du canvas */
.v-hero-inner, .v-hero-facts { position: relative; z-index: 2; }

/* ⚠️ Sur mobile, le canvas est plus couteux que sur desktop et le hero est
   court : on le desactive sous 700 px, comme le faisait la version d'origine. */
@media (max-width: 700px) {
  .v-hero-3d { display: none; }
}

/* ============================================================
   ANIMATIONS D'APPARITION — le contenu est VISIBLE PAR DEFAUT.

   ⚠️⚠️ REGLE ABSOLUE, apprise d'un bug reel : ne JAMAIS masquer le contenu avec
   `opacity: 0` par defaut. Si l'IntersectionObserver echoue, la page parait
   VIDE (le user l'avait signale : « c'est completement vide » sur mobile).
   L'animation ne s'applique QUE si le script a pose `js-anim` sur le body.
   ============================================================ */
.reveal, .v-sec, .s-sec, .v-sec-head, .s-tete { opacity: 1; }
body.js-anim .reveal,
body.js-anim .v-sec,
body.js-anim .s-sec,
body.js-anim .v-sec-head,
body.js-anim .s-tete {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s ease, transform .55s ease;
}
body.js-anim .reveal.visible,
body.js-anim .v-sec.visible,
body.js-anim .s-sec.visible,
body.js-anim .v-sec-head.visible,
body.js-anim .s-tete.visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  body.js-anim .reveal, body.js-anim .v-sec, body.js-anim .s-sec,
  body.js-anim .s-tete, body.js-anim .v-sec-head {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

/* ============================================================
   PLAN TECHNIQUE EN PERSPECTIVE — CSS PUR (remplace le shader WebGL).

   ⚠️⚠️ POURQUOI CE CHANGEMENT. L'effet 3D de l'accueil etait un shader WebGL
   ecrit a la main (`atelier3d.js`, 20 Ko). Il a cesse de fonctionner quand le
   hero a change de classe, puis il s'est revele impossible a reparer : le
   shader compilait, `drawArrays` s'executait, et le canvas restait
   TRANSPARENT — sans aucune erreur. Un effet qui echoue en silence est pire
   qu'un effet absent : on croit qu'il marche.

   Le CSS donne le MEME resultat visuel, sans shader, sans canvas, sans
   dependance. Et si quelque chose casse, ca se VOIT.

   Les trois couches (empilees, toutes decoratives) :
     1. `.v-sol-grille`  la grille en perspective au sol (le plan d'atelier)
     2. `.v-sol-ligne`   le cordeau d'horizon, un trait plein
     3. `.v-sol-lueur`   un halo chaud au-dessus de l'horizon
   ============================================================ */
/* ⚠️⚠️ z-index 1, PAS 0. La cause du « sol invisible » etait un ORDRE
   D'EMPILEMENT : `.v-hero-cadre` (le degrade opaque blanc) vient APRES
   `.v-sol` dans le DOM et portait le meme `z-index: 0` — il recouvrait donc
   entierement la grille. Mesure : meme un fond ROUGE PUR ne produisait aucun
   pixel a l'ecran.
   Le sol passe au-dessus du cadre, sous le contenu (`.v-hero-inner` est a 2). */
.v-sol {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;      /* jamais cliquable : c'est un fond */
  overflow: hidden;
}
/* le cadre reste SOUS le sol */
.v-hero-cadre { z-index: 0; }
.v-sol > span { position: absolute; display: block; }

/* 1. la grille : un motif repete, incline en perspective.
   ⚠️ `perspective()` sur le PARENT et `rotateX` sur l'enfant : c'est ce qui
   donne la fuite vers l'horizon, exactement comme un plan vu de biais.
   ⚠️ `transform-origin: 50% 100%` : le point de fuite part du BAS de l'ecran
   (le spectateur), pas du centre. */
.v-sol-grille {
  /* HAUTEUR EN vh, PAS EN POURCENTAGE.
     Bug mesuré : `height: 78%` sur un parent sans hauteur définie retombait à
     150 px — la grille ne couvrait que le bas de l'écran, et son masque
     l'effaçait entièrement. La hauteur doit être liée à la FENÊTRE. */
  /* ⚠️⚠️ L'ANGLE ECRASE LA HAUTEUR PAR PROJECTION.
     Mesure : `height: 558px` avec `rotateX(64deg)` ne rend que 135 px a
     l'ecran (558 x cos 64 = 245, moins le masque). Une grille de 135 px de
     haut ne se voit presque pas. On REDUIT l'angle (45 au lieu de 64) et on
     AUGMENTE la hauteur pour compenser la projection. */
  /* ⚠️⚠️ POSITION VERTICALE. Mesure : avec `bottom: -20vh` la grille
     commencait a y=757 et finissait a 1128 — dans un ecran de 900 px, seuls
     143 px etaient visibles, et le masque les effacait. La grille doit
     demarrer dans la moitie basse de l'ecran, pas en dessous. */
  left: -40vw; right: -40vw; bottom: 4vh; height: 96vh;
  transform-origin: 50% 100%;
  transform: perspective(760px) rotateX(46deg);
  /* traits de 2 px — à 1 px le rendu sous-pixel les fait disparaître sur la
     plupart des écrans ; période de 64 px — plus dense, donc plus lisible */
  background-image:
    repeating-linear-gradient(to right,
      rgba(10,10,10,.34) 0 2px, transparent 2px 64px),
    repeating-linear-gradient(to bottom,
      rgba(10,10,10,.34) 0 2px, transparent 2px 64px);
  /* l'effacement au loin reste, mais on garde 55 % de la grille visible */
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 55%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0%, #000 55%, transparent 100%);
}

/* 2. le cordeau d'horizon */
.v-sol-ligne {
  left: 0; right: 0; bottom: 56vh; height: 1px;
  background: linear-gradient(to right, transparent, rgba(10,10,10,.30) 18%,
              rgba(10,10,10,.30) 82%, transparent);
}

/* 3. le halo chaud juste au-dessus de l'horizon */
.v-sol-lueur {
  left: 0; right: 0; bottom: 56vh; height: 26vh;
  background: radial-gradient(60% 100% at 50% 100%,
              rgba(10,10,10,.055), transparent 70%);
}

/* ⚠️ Sur mobile, le hero est court : la perspective prend trop de place et
   gene la lecture. On la reduit sans la supprimer. */
@media (max-width: 900px) {
  /* ⚠️⚠️ MEME BUG QUE SUR DESKTOP : `height: 42%` sur un parent sans hauteur
     definie retombe a la taille du contenu. Mesure : sur un 360x740 le sol
     etait a -28 px (HORS ECRAN), sur un 320x568 a -230 px. On passe en vh
     et on remonte la grille pour qu'elle soit visible sous le contenu. */
  .v-sol-grille {
    height: 46vh;
    bottom: 0;
    transform: perspective(420px) rotateX(54deg);
  }
  .v-sol-lueur, .v-sol-ligne { display: none; }
}

/* ⚠️ Animation TRES lente du sol : un glissement de 40 s, en boucle.
   `prefers-reduced-motion` la desactive completement. */
@media (prefers-reduced-motion: no-preference) {
  .v-sol-grille { animation: v-sol-defile 40s linear infinite; }
  @keyframes v-sol-defile {
    from { background-position: 0 0, 0 0; }
    to   { background-position: 0 0, 0 92px; }
  }
}

/* ============================================================
   PARALLAXE DU MOCKUP — CSS pur, au survol du hero.
   ⚠️ Le script JS faisait deja ca (avec perspective/rotate). On le garde en
   CSS pour ne PAS dependre d'un script : `:hover` suffit, et si le navigateur
   ne le fait pas, la maquette reste simplement droite.
   ============================================================ */
@media (hover: hover) and (pointer: fine) and (min-width: 1000px) {
  .v-fenetre {
    transition: transform .6s cubic-bezier(.22,.61,.36,1), box-shadow .6s ease;
  }
  .v-hero:hover .v-fenetre {
    transform: perspective(1500px) rotateY(-7deg) rotateX(3deg) translateZ(0);
    box-shadow: 0 30px 70px rgba(10,10,10,.13);
  }
}
@media (prefers-reduced-motion: reduce) {
  .v-fenetre { transition: none; }
  .v-hero:hover .v-fenetre { transform: none; }
}

/* ============================================================
   PAGE D'ERREUR — le vide au-dessus de la carte.

   ⚠️ MESURE : la carte de la 404 commencait a y=273 sur un ecran de 844 —
   273 px de vide en haut, signales par l'audit visuel. La cause :
   `.auth-body` est en `flex; justify-content: flex-start`, et le `topbar` en
   premiere position pousse la carte vers le bas. Le `margin: auto` de la carte
   ne peut pas la recentrer car la barre occupe deja de la place.

   ⚠️ On ne touche PAS a la barre de navigation : on centre la carte dans
   l'espace QUI RESTE, en la faisant grandir pour occulter la barre.
   ============================================================ */
.auth-body .auth-card {
  flex: 1 1 auto;         /* la carte occupe l'espace restant */
  margin: 0 auto;
  align-self: center;      /* et se centre verticalement dedans */
  max-height: none;
}
/* le conteneur de la carte : centre son contenu */
.auth-body > .auth-card,
.auth-body > div > .auth-card { align-self: center; }

@media (max-width: 900px) {
  /* ⚠️ SUR MOBILE. Mesure : la carte commencait a y=267 pour 365 px de haut —
     il restait 211 px de vide en bas et 267 en haut, donc un desequilibre.
     La barre est posee en absolu pour ne plus peser dans le flux, et la carte
     est centree dans ce qui reste. */
  .auth-body { justify-content: flex-start; padding-top: 0; }
  .auth-body .topbar { position: absolute; top: 0; left: 0; right: 0; z-index: 5; }
  .auth-body .auth-card { margin: auto 20px; flex: 0 0 auto; }
  .auth-body::before { content: none; }
}

/* ===== fin sections.css ===== */

/* ===== début anton-rognage.css ===== */
/* ============================================================
   ⚠️⚠️ CORRECTIF SYSTÉMIQUE — ANTON EST ROGNÉ PARTOUT.

   Mesuré sur /pricing, 7 éléments rognés d'un coup :

     H1  « CHOISISSEZ CE QUI VOUS FAIT GAGNER DU TEMPS »  scrollH 70 / clientH 57
     H2  « VOS CLIENTS VOUS CHERCHENT DÉJÀ »              scrollH 51 / clientH 42
     H2  « CHIFFREZ VOS DEVIS SANS GALÉRER »              scrollH 93 / clientH 84
     prix « 0 €/mois »                                     scrollH 63 / clientH 58
     prix « 14,99 €/mois »                                 scrollH 63 / clientH 58

   ⚠️⚠️ LA CAUSE. `echelle-unique.css` fixe des interlignes serrés
   (`line-height: 1.02` sur h1, `1.05` sur h2, `1.05` sur le prix) — un choix
   esthétique hérité de la maquette. Mais **Anton a une hauteur de glyphe
   supérieure à son interligne** : son dessin déborde de la boîte de ligne. Avec
   un interligne serré ET sans padding, le haut des lettres capitales est coupé.

   ⚠️ Et ce n'est pas propre à /pricing : TOUS les titres du site sont en Anton
   avec ces interlignes. Le rognage est général — il était simplement invisible
   sur les titres d'une seule ligne sans accent circonflexe.

   ⚠️ LA RÈGLE POUR ANTON : un interligne ≥ 1,12 em, plus un padding vertical.
   Le padding réserve la place du débordement du dessin.

   ⚠️ On corrige ICI, APRÈS `echelle-unique.css`, pour que ça vaille partout.
   ============================================================ */

h1, .page-head h1, .visi-hero h1, .legal-card > h1 {
  line-height: 1.30 !important;
  padding-top: .14em !important;
  padding-bottom: .14em !important;
}
h2, .section-head h2, .s-tete h2, .visi-guide-title, .v-h2 {
  line-height: 1.32 !important;
  padding-top: .13em !important;
  padding-bottom: .13em !important;
}
h3, .v-h3, .s-bloc h3, .card h3 {
  line-height: 1.38 !important;
  padding-top: .10em !important;
  padding-bottom: .10em !important;
}
/* le mot en CONTOUR déborde encore plus : le trait se peint hors des glyphes */
.v-barre {
  -webkit-text-stroke: 1.6px var(--ink);
  padding: .04em .02em !important;
}

/* ⚠️⚠️ LE MONDE « n- » A SA PROPRE RÈGLE, PLUS SPÉCIFIQUE (2026-10-10).
   `no_scroll_dimension.css` (agrégée dans `devisaly.css`) porte :
       .n-title { line-height: 1.1 !important }
   Une CLASSE bat un ÉLÉMENT, même quand les deux sont en `!important` : les
   titres de l'accueil, des tarifs, du blog, des CGV et des mentions restaient
   donc rognés malgré la règle `h1` ci-dessus. Mesuré : glyphe 64 px dans une
   boîte de 57 px. À spécificité égale, c'est l'ORDRE qui tranche — et cette
   feuille est chargée après `devisaly.css`. */
.n-title { line-height: 1.30 !important; padding: .14em 0 !important; }
.n-ex__titre, .n-lecture__titre { line-height: 1.38 !important; padding: .10em 0 !important; }
/* Le total d'un devis dans l'aperçu du builder : même police, même défaut. */
.quote-totals-row.grand .value { line-height: 1.34 !important; }

/* les prix et les gros chiffres, meme police display */
.s-offre .prix, .prix, .plan .price, .v-offre-prix, .chiffre,
.v-chiffre, .t-step span, .stat-value, .kpi-value {
  line-height: 1.32 !important;
  padding-top: .13em !important;
  padding-bottom: .13em !important;
}

/* l'accueil : son titre geant suit la meme regle */
.v-h1 {
  line-height: 1.24 !important;   /* interligne serre voulu par la maquette */
  padding: .14em 0 !important;    /* mais on reserve la place du debordement */
}
@media (max-width: 900px) {
  h1, .page-head h1, .visi-hero h1 { line-height: 1.34 !important; }
  h2, .s-tete h2 { line-height: 1.36 !important; }
  .v-h1 { line-height: 1.26 !important; }
}

/* ===== fin anton-rognage.css ===== */

/* ===== début no_scroll_coherence.css ===== */
/* ============================================================
   COHERENCE DES PAGES — les titres, partout (2026-10-06).

   ⚠️⚠️ DEFAUT MESURE. Deux pages n'ont JAMAIS ete migrees au langage du site :
   `/contact` et `/artisan`. Elles utilisent l'ANCIEN vocabulaire
   (`.container` + `.page-head h1`, `.artisan-hero h1`), dont le style vivait
   dans `devisaly.css`. Or cette feuille n'est plus chargee (le double theme a
   ete retire) : leur `h1` retombait donc sur le style PAR DEFAUT DU NAVIGATEUR.

     /              Anton, MAJUSCULES, 48px     -> correct
     /pricing       Anton, MAJUSCULES, 37px     -> correct
     /contact       Inter, 33px, minuscules     -> DEFAUT
     /artisan       Inter, 33px, minuscules     -> DEFAUT

   ⚠️ La regle ci-dessous rend le style de titre du site a TOUT `h1` place dans
   une page du gabarit `n-`, quelle que soit la classe heritee. Une page future
   ne pourra donc plus « oublier » son style de titre.
   ⚠️ On cible `h1` et non une liste de classes : c'est justement parce qu'une
   liste de classes avait laisse ces deux pages de cote.
   ============================================================ */

/* ---- 1. LE TITRE DE PAGE ---- */
.n-screen h1,
.n-formwrap h1,
.n-lecture h1,
.artisan-hero h1,
.page-head h1,
.container > h1 {
  font-family: Anton, Archivo, sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -.012em;
  line-height: 1.12;
  color: var(--n-fg);
  font-size: clamp(1.9rem, 7.2vw, 2.6rem);
  margin: 0;
  /* ⚠️ Anton a une hauteur de glyphe > son interligne : sans cette reserve, le
     haut des capitales est rogne (piege connu du site). */
  padding: .06em 0 .04em;
  max-width: none;
}

/* ---- 2. LE SOUS-TITRE QUI SUIT ---- */
.n-formwrap .page-head > p,
.artisan-hero > p {
  font-family: Inter, Archivo, system-ui, sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--n-dim);
  margin: .9rem 0 0;
  max-width: 60ch;
}

/* ---- 3. LE MOT MIS EN AVANT DANS UN TITRE (`<em>`) = l'or de la marque ---- */
.artisan-hero h1 em,
.n-formwrap h1 em {
  font-style: normal;
  color: var(--n-or);
}

/* ---- 4. LES CONTENEURS HERITES NE DOIVENT PAS IMPOSER LEUR MISE EN PAGE ----
   `.container` venait de l'ancien theme (largeur, centrage, padding). Sur une
   page `n-`, c'est `.n-formwrap` / `.n-screen` qui porte la mise en page : on
   neutralise donc ce que `.container` pourrait encore imposer. */
.n-formwrap .container {
  max-width: none;
  padding: 0;
  margin: 0;
}

/* ============================================================
   DEUX DEFAUTS RESIDUELS (2026-10-06), mesures sur les pages applicatives.
   ============================================================ */

/* ⚠️ 1. DEGRADE SUR L'ENCART DE L'ESPACE CLIENT.
   `.upsell-banner` (devisaly.css) posait
   `background: linear-gradient(160deg, var(--gold-bg), rgba(...))`.
   Le site interdit les degrades : remplace par l'aplat pale de la marque, qui
   donne le meme effet de « bloc mis en avant » sans le degrade. */
.upsell-banner {
  background: var(--n-or-pale, #f3ead6);
  background-image: none;
  border-radius: 0;
}

/* ⚠️ 2. TITRE D'AUTHENTIFICATION EN ANTON MINUSCULES.
   `.auth-card > h1` forcait `font-size: 22px !important` en minuscules. Or
   **Anton est une police dessinee pour les CAPITALES** : en minuscules elle est
   etroite et peu lisible, et elle n'a plus rien a voir avec les titres du site.
   On applique donc le style de titre du site (Anton + MAJUSCULES), avec une
   taille de page interieure (plus petite que l'accueil, c'est voulu) mais ou le
   texte respire. */
.titre-erreur,
.auth-card > h1 {
  font-family: Anton, Archivo, sans-serif !important;
  text-transform: uppercase;
  letter-spacing: -.008em;
  line-height: 1.14;
  font-size: clamp(1.5rem, 3.2vw, 2rem) !important;
  padding: .05em 0 .03em;
  color: var(--n-fg);
}
@media (max-width: 600px) {
  .titre-erreur,
  .auth-card > h1 {
    font-size: clamp(1.35rem, 6.4vw, 1.7rem) !important;
  }
}

/* ============================================================
   LES LIENS RESTAIENT AU BLEU PAR DEFAUT (2026-10-06).

   ⚠️⚠️ MESURE : 234 liens affiches en `rgb(0, 0, 238)` — le bleu par defaut du
   navigateur. Sur un site blanc / noir / or, c'est le signe le plus visible
   d'une page « pas finie » :
       /blog        105 liens (les articles)
       /prix/<metier> 101 liens (les departements)
       /artisan       4 liens (pied de page)
       /agence-ou-devisaly, /services/…

   CAUSE : ces pages n'ont AUCUNE regle `a { color }`. Le navigateur applique
   alors sa couleur par defaut. Le site n'a jamais eu de regle globale pour les
   liens nus (seules les classes `.n-link`, `.n-btn`, `.n-villes a` en avaient).

   CORRECTIF : une regle globale pour les liens NUS. `:not([class])` garantit
   qu'on ne touche a AUCUN lien deja stylise (`.n-btn`, `.n-link`, `.n-btn--or`…).
   Un lien souligne a l'encre, qui prend l'or au survol — le langage du site.
   ============================================================ */
a:not([class]) {
  color: var(--n-fg);
  text-decoration: underline;
  text-decoration-color: var(--n-or-ligne);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color .15s, text-decoration-color .15s;
}
a:not([class]):hover {
  color: var(--n-or-texte);
  text-decoration-color: var(--n-or);
}

/* ⚠️ Le selecteur de langue et le pied de page du menu ont leurs propres
   classes : on s'assure qu'ils ne prennent pas le bleu non plus. */
.n-menu-foot a,
.n-doc a,
.n-villes a { color: var(--n-fg); text-decoration-color: var(--n-or-ligne); }
.n-menu-foot a:hover,
.n-doc a:hover,
.n-villes a:hover { color: var(--n-or-texte); text-decoration-color: var(--n-or); }

/* ⚠️ 2 liens restaient bleus : ils portent une CLASSE, donc la regle
   `a:not([class])` ne les atteignait pas.
     `.artisan-brand`   (logo du tunnel /artisan)
     `.footer-mail`     (email brut du pied de page)
   Le tunnel `/artisan` est un parcours epure dont la feuille (`artisan.css`)
   n'est pas chargee ici : sa marque retombait donc sur le bleu par defaut. */
.artisan-brand,
.footer-mail,
a.artisan-brand,
a.footer-mail {
  color: var(--n-fg);
  text-decoration: none;
}
.artisan-brand:hover,
.footer-mail:hover {
  color: var(--n-or-texte);
  text-decoration: underline;
  text-decoration-color: var(--n-or);
}

/* ⚠️ BOUTONS DU BUILDER EN POLICE PAR DEFAUT (2026-10-06).
   Mesure : `/app` — « + Ajouter une prestation » et « Réinitialiser »
   s'affichaient en **Arial**, la police par defaut du navigateur. `.add-service`
   et `.clear-draft` (devisaly.css) declarent taille et couleur mais PAS de
   `font-family` : ils heritent d'une chaine qui ne remonte a aucune police du
   site. On la declare explicitement.
   ⚠️ Angles droits aussi : c'est la contrainte du design system. */
.add-service, .clear-draft, .svc-actions button, .lib-btn {
  font-family: 'IBM Plex Mono', monospace;
  letter-spacing: .06em;
  border-radius: 0;
}

/* ===== fin no_scroll_coherence.css ===== */

/* ===== début no_scroll_form.css ===== */
/* ============================================================
   LES FORMULAIRES DES PAGES « NO SCROLL » (2026-10-06).

   ⚠️⚠️ MEME CLASSE DE BUG QUE /artisan, trouvee en CHASSANT le signal.
   Les pages du gabarit `n-` chargent les feuilles `no_scroll*.css` et **PAS**
   `devisaly.css`, qui portait le style des formulaires et des boutons `.btn`.
   Mesure sur /contact :

       button.btn   342x21   Arial   fond rgb(239,239,239)   <- NON STYLE
       input         13 px                                    <- mobile zoome
       select        13 px
       textarea      13 px

   `rgb(239,239,239)` et `Arial` sont les valeurs PAR DEFAUT du navigateur : le
   formulaire de contact etait donc nu, et ses champs faisaient 13 px — en
   dessous de 16 px, Android et iOS zooment automatiquement au focus, ce qui
   casse la mise en page.

   ⚠️ On NE charge PAS `devisaly.css` : elle porte tout l'ancien theme
   (`.drawer`, `.plan`, `.hero`…) et la chargerait ramenerait les regles qu'on a
   justement retirees. On isole donc les formulaires ici, avec les contraintes du
   site : angles droits, aplat or, AUCUN degrade, AUCUNE ombre.
   ============================================================ */

/* ---- LES CHAMPS ---- */
.n-body input[type=text],
.n-body input[type=email],
.n-body input[type=tel],
.n-body input[type=password],
.n-body input[type=number],
.n-body select,
.n-body textarea,
.n-formwrap input,
.n-formwrap select,
.n-formwrap textarea {
  width: 100%;
  min-height: 44px;                 /* cible tactile */
  padding: 11px 14px;
  margin: 0 0 14px;
  background: var(--n-bg, #fff);
  color: var(--n-fg, #0a0a0a);
  border: 1px solid var(--n-rule, rgba(10,10,10,.2));
  border-radius: 0;                 /* angles droits : contrainte du site */
  font-family: Inter, Archivo, system-ui, sans-serif;
  font-size: 16px;                  /* ⚠️ 16 px : en dessous, les mobiles zooment */
  line-height: 1.4;
  outline: none;
  transition: border-color .15s;
}
.n-body textarea, .n-formwrap textarea { min-height: 120px; resize: vertical; }
.n-body input:focus, .n-body select:focus, .n-body textarea:focus,
.n-formwrap input:focus, .n-formwrap select:focus, .n-formwrap textarea:focus {
  border-color: var(--n-or, #b8892e);
}

/* ---- LES ETIQUETTES ---- */
.n-body form label, .n-formwrap form label {
  display: block;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--n-or-texte, #8a6a2a);
  margin: 0 0 6px;
}

/* ---- LES BOUTONS (`.btn` de l'ancien theme, jamais dessines ici) ---- */
.n-body .btn, .n-formwrap .btn,
.n-body button.btn, .n-body form button[type=submit],
.n-fallback .btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 13px 22px;
  background: var(--n-fg, #0a0a0a);
  color: var(--n-bg, #fff);
  border: 1px solid var(--n-fg, #0a0a0a);
  border-radius: 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase;
  text-decoration: none; cursor: pointer; width: 100%;
  transition: background .15s, border-color .15s, color .15s;
}
.n-body .btn:hover, .n-formwrap .btn:hover,
.n-body button.btn:hover, .n-body form button[type=submit]:hover {
  background: var(--n-or-texte, #8a6a2a);
  border-color: var(--n-or-texte, #8a6a2a);
}
.n-body .btn.primary, .n-formwrap .btn.primary {
  background: var(--n-or-texte, #8a6a2a);
  border-color: var(--n-or-texte, #8a6a2a);
}
.n-body .btn.primary:hover, .n-formwrap .btn.primary:hover {
  background: var(--n-fg, #0a0a0a); border-color: var(--n-fg, #0a0a0a);
}
.n-body .btn.big, .n-formwrap .btn.big { font-size: 12px; letter-spacing: .16em; }

/* ---- LE CONTENEUR DE FORMULAIRE (ancienne classe `.card`) ---- */
.n-formwrap .card, .n-fallback .card {
  background: var(--n-bg, #fff);
  border: 1px solid var(--n-or-ligne, #dcc79a);
  border-radius: 0; padding: 22px 20px;
}

/* ---- LES MESSAGES (flash / succes / erreur) ---- */
.n-body .flash, .n-formwrap .flash {
  border-radius: 0; padding: 12px 14px; margin: 0 0 16px;
  font-family: Inter, system-ui, sans-serif; font-size: 14.5px;
  border: 1px solid var(--n-or-ligne, #dcc79a);
  background: var(--n-or-pale, #f3ead6);
  color: var(--n-fg, #0a0a0a);
}
.n-body .flash.error { border-color: #d9b0a8; background: #f7e7e4; }
.n-body .flash.success { border-color: #b6c9a4; background: #eef4e6; }
.n-body .lead-privacy, .n-formwrap .lead-privacy {
  font-size: 12.5px; color: var(--n-dim, rgba(10,10,10,.58));
  margin-top: 10px; line-height: 1.5;
}
.n-body .hint, .n-formwrap .hint {
  font-size: 12.5px; color: var(--n-dim, rgba(10,10,10,.58)); margin: -8px 0 14px;
}

/* ============================================================
   CIBLES TACTILES TROP PETITES — les 3 cas RÉELS (2026-10-06).

   ⚠️ La plupart des « cibles < 40 px » relevees sont des LIENS DE TEXTE inline :
   une ligne de 20 px, c'est normal et ca ne se « corrige » pas. Restent trois
   controles qui, eux, sont vraiment difficiles a toucher au pouce :

     input[type=checkbox]  13x13   la case d'acceptation des conditions (/visibilite)
     .pw-toggle            36x36   l'oeil qui affiche/masque le mot de passe
     .btn                  33 px   « Voir mon apercu »
   ============================================================ */

/* ---- La case d'acceptation (conditions, RGPD) ----
   ⚠️ 13 px, c'est trois fois trop petit pour un pouce. On agrandit la CASE et on
   etend sa ZONE CLIQUABLE avec un pseudo-element : sans cela, viser 13 px est
   penible — et une case de consentement qu'on rate est un frein a la commande. */
.n-body input[type=checkbox],
.n-formwrap input[type=checkbox],
.n-body .n-pay__consent input[type=checkbox] {
  width: 22px; height: 22px;
  min-width: 22px; min-height: 22px;
  margin: 0 10px 0 0;
  accent-color: var(--n-or-texte, #8a6a2a);
  cursor: pointer;
  position: relative;
}
.n-pay__consent, .n-body label:has(input[type=checkbox]) {
  min-height: 44px; align-items: flex-start; cursor: pointer;
}

/* ---- L'oeil du mot de passe ---- */
.pw-toggle, button.pw-toggle {
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; border-radius: 0;
  color: var(--n-dim, rgba(10,10,10,.58)); cursor: pointer;
}
.pw-toggle:hover { color: var(--n-fg, #0a0a0a); }

/* ---- Les boutons `.btn` : hauteur tactile minimale ---- */
.n-body .btn, .n-formwrap .btn, .n-body a.btn, .n-fallback .btn {
  min-height: 44px;
}

/* ---- Les liens de bloc dans une carte (pas du texte inline) ---- */
.n-ex__ouvrir, .n-menu-foot a { min-height: 24px; display: inline-block; }

/* ⚠️⚠️ `.btn` A UNE HAUTEUR DE 33 px SUR /login, /register, /app (2026-10-06).
   `min-height: 44px` etait ecrit plus haut, mais il ne gagnait PAS : une regle
   plus specifique (probablement `body:not(.app-mode) .btn` ou un `.auth-body
   .btn`) pose `display:flex` et un padding plus petit. `min-height` est IGNORE
   sans `display` de bloc — et meme avec, la specificite tranche.
   ⚠️ `!important` est ici l'usage LEGITIME deja rencontre sur ce site : reprendre
   la main sur un empilement de feuilles legacy qu'on ne veut pas reecrire.
   Verification : mesurer `getComputedStyle().minHeight`, PAS lire la regle. */
.n-body .btn, .n-body a.btn, .n-body button.btn, .n-body input.btn,
.n-formwrap .btn, .n-formwrap a.btn, .n-formwrap button.btn,
.auth-body .btn, .auth-body a.btn, .auth-body button.btn {
  min-height: 48px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 14px 22px !important;
  border-radius: var(--r-pil) !important;
}
/* ⚠️ Et l'APLAT OR : `.btn.primary` portait un DEGRADE
   (`linear-gradient(165deg, #c9a457…)`), contraire a la regle dure du site. */
.n-body .btn.primary, .n-formwrap .btn.primary, .auth-body .btn.primary {
  background: #8a6a2a !important;
  background-image: none !important;
  border-color: #8a6a2a !important;
  color: #fff !important;
}
.n-body .btn.primary:hover, .auth-body .btn.primary:hover {
  background: #0a0a0a !important; border-color: #0a0a0a !important;
}

/* ⚠️⚠️ `/app` A UN `<body>` SANS CLASSE (2026-10-06).
   Le gabarit de `/app` ecrit `<body>` nu (les classes `guest`/`app-mode` sont
   conditionnelles, et absentes pour un visiteur ordinaire). Mes selecteurs
   `.n-body .btn` / `.auth-body .btn` ne pouvaient donc PAS l'atteindre — c'est
   pourquoi le bouton de `/app` restait a 33 px alors que /login et /contact
   etaient corriges.
   ⚠️ On cible le CONTENEUR reel du builder (`.builder`, `.container`), qui existe
   sur cette page quelle que soit la classe du body. */
.builder .btn, .container .btn,
.builder a.btn, .builder button.btn,
.container a.btn, .container button.btn {
  min-height: 48px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 14px 22px !important;
  border-radius: var(--r-pil) !important;
}
.builder .btn.primary, .container .btn.primary {
  background: #8a6a2a !important;
  background-image: none !important;
  border-color: #8a6a2a !important;
  color: #fff !important;
}
.builder .btn.primary:hover, .container .btn.primary:hover {
  background: #0a0a0a !important; border-color: #0a0a0a !important;
}
/* les boutons utilitaires du builder gardent une taille sobre mais tactile */
.builder .btn.ghost { background: transparent !important; background-image: none !important;
  border: 1px solid var(--n-rule, rgba(10,10,10,.2)) !important; color: var(--n-fg, #0a0a0a) !important; }
.builder .btn.ghost:hover { border-color: var(--n-fg, #0a0a0a) !important; background: transparent !important; }
.builder .btn-sm, .container .btn-sm { min-height: 40px !important; padding: 11px 16px !important; }

/* ⚠️ Le dernier bouton a 33 px est dans la BARRE DE NAVIGATION (`.nav`) des pages
   qui utilisent `_head.html` : « Voir mon aperçu ». Les selecteurs precedents
   visaient le builder et la barre d'action, pas la nav. */
.nav .btn, .topbar .btn, .nav a.btn, .topbar a.btn {
  min-height: 44px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 12px 18px !important;
}
.nav .btn.primary, .topbar .btn.primary {
  background: #8a6a2a !important; background-image: none !important;
  border-color: #8a6a2a !important; color: #fff !important;
}

/* ⚠️ BORDURES DE CHAMPS INCOHERENTES SUR /login (2026-10-06).
   Releve au controle visuel : le champ Email portait une bordure NOIRE epaisse,
   le mot de passe une bordure grise fine. Deux champs du MEME formulaire doivent
   avoir le meme traitement : la bordure epaisse etait un effet de `:focus` reste
   actif, ou une regle de l'ancien theme. On uniformise.
   ⚠️ Le placeholder etait aussi trop pale (contraste insuffisant). */
.auth-body input, .auth-card input, .n-body .card input, .n-formwrap .card input {
  border: 1px solid var(--n-rule, rgba(10,10,10,.2)) !important;
  background: var(--n-bg, #fff) !important;
}
.auth-body input:focus, .auth-card input:focus,
.n-body .card input:focus, .n-formwrap .card input:focus {
  border-color: var(--n-or, #b8892e) !important;
  outline: none !important;
}
/* ⚠️ Placeholder lisible : un gris trop pale est un defaut d'accessibilite. */
.n-body input::placeholder, .n-formwrap input::placeholder,
.auth-body input::placeholder, .n-body textarea::placeholder {
  color: rgba(10, 10, 10, .5);
  opacity: 1;
}

/* ⚠️ POLICE DES CHAMPS SUR /login, /register : 14 px (2026-10-06).
   `font-size: 16px` etait ecrit plus haut mais les selecteurs `.n-body input` ne
   touchent PAS ces pages (leur `<body>` porte `auth-body`). Or en dessous de
   16 px, Android et iOS ZOOMENT automatiquement au focus : la mise en page saute
   et l'utilisateur doit dezoomer. On force donc 16 px sur les pages d'auth aussi. */
.auth-body input, .auth-body select, .auth-body textarea,
.auth-card input, .auth-card select, .auth-card textarea {
  font-size: 16px !important;
  font-family: Inter, Archivo, system-ui, sans-serif !important;
  min-height: 48px !important;
  padding: 12px 14px !important;
}
.auth-body textarea, .auth-card textarea { min-height: 120px !important; }

/* ============================================================
   LES FORMULAIRES DE RAPPEL (2026-10-13).

   ⚠️⚠️ POURQUOI. Le site ne prend plus de paiement automatique (voir
   PAIEMENT_EN_LIGNE dans app.py). Le formulaire de paiement de /visibilite est
   devenu un formulaire de RAPPEL — quatre champs au lieu d'un — et l'accueil en
   porte un désormais dans le bandeau `.n-rappel`, pour que le visiteur puisse
   laisser ses coordonnées sans quitter la page d'arrivée.

   ⚠️ Le bloc `.n-pay` de no_scroll.css n'habillait QUE `input[type=email]` :
   les nouveaux champs (texte, téléphone, zone de texte) apparaîtraient sans
   bordure et collés au libellé. On leur donne exactement les mêmes cotes.
   Charte de la famille : angles DROITS, filet de 1 px, aucune ombre.
   ============================================================ */

.n-pay__form input[type=text], .n-pay__form input[type=tel], .n-pay__form textarea {
  width: 100%; padding: 12px 14px; margin-bottom: 14px; border: 1px solid var(--n-rule);
  background: var(--n-bg); color: var(--n-fg); border-radius: 0;
  font-family: Inter, Archivo, system-ui, sans-serif; font-size: 1rem;
}
.n-pay__form textarea { min-height: 74px; resize: vertical; line-height: 1.5; }

/* ---- le bandeau « être rappelé » de l'accueil ---- */
.n-rappel {
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 2.6rem; align-items: start;
  max-width: 1120px; margin: 0 auto; padding: 3.4rem var(--n-pad) 3.8rem;
  border-top: 1px solid var(--n-rule);
}
.n-rappel__titre {
  font-family: Anton, Archivo, sans-serif; font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.5rem, 3.1vw, 2.5rem); line-height: 1.04; letter-spacing: -.008em; margin: 0;
}
.n-rappel .n-sub { margin-top: 18px; max-width: 40ch; }
.n-rappel__form label {
  display: block; font-family: 'IBM Plex Mono', monospace; font-size: .7rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--n-dim); margin-bottom: 5px;
}
.n-rappel__form input[type=text], .n-rappel__form input[type=tel], .n-rappel__form input[type=email] {
  width: 100%; padding: 12px 14px; margin-bottom: 14px; border: 1px solid var(--n-rule);
  background: var(--n-bg); color: var(--n-fg); border-radius: 0;
  font-family: Inter, Archivo, system-ui, sans-serif; font-size: 1rem;
}
.n-rappel__consent {
  display: flex; gap: .6rem; align-items: flex-start; text-transform: none;
  font-family: Inter, Archivo, system-ui, sans-serif; font-size: .82rem; letter-spacing: 0;
  color: var(--n-fg); margin: .2rem 0 14px;
}
.n-rappel__consent input { margin-top: .25rem; }
@media (max-width: 860px) {
  .n-rappel { grid-template-columns: 1fr; gap: 1.6rem; padding-top: 2.4rem; }
}

/* ===== fin no_scroll_form.css ===== */

/* ===== début n_menu_global.css ===== */
/* ============================================================
   LE MENU « n- » RENDU UTILISABLE PARTOUT (2026-10-06).

   ⚠️⚠️ LE PROBLÈME QUE CE FICHIER RÉSOUT.
   Le site avait DEUX menus, mesures a l'appui :
     - 15 pages (gabarit `n_base.html`) : bouton `.n-menu-btn`, panneau `#n-menu`,
       8 entrees issues de `N_PLAN` (source unique cote Python) ;
     - 54 pages (gabarit `_nav.html`) : bouton `.burger`, tiroir `.drawer`,
       16 entrees differentes (« VOIR MON APERCU », « L'offre et le prix »…).
   D'ou le ressenti du user : « DEUX VERSIONS DU SITE COHABITENT ».

   ⚠️ On unifie sur le menu `n-` (une seule source : `N_PLAN`). Mais son style vit
   dans `no_scroll.css`, charge UNIQUEMENT par les pages `n-`. Charger cette
   feuille sur les 54 autres pages ramenerait `.n-body`, `.n-screen`, `.n-formwrap`
   — tout le gabarit. On isole donc ICI les regles du MENU SEUL, rendues
   autonomes : les variables dont elles ont besoin sont redefinies localement,
   pour ne dependre d'aucune autre feuille.

   ⚠️ Memes contraintes que le reste du site : angles droits, aplat or, AUCUN
   degrade, AUCUNE ombre.
   ============================================================ */

:root {
  --ng-bg: #ffffff;
  --ng-fg: #0a0a0a;
  --ng-dim: rgba(10, 10, 10, .58);
  --ng-rule: rgba(10, 10, 10, .2);
  --ng-or: #b8892e;
  --ng-or-texte: #8a6a2a;
  --ng-pale: #f3ead6;
  --ng-ligne: #dcc79a;
  --ng-pad: 24px;
}
@media (min-width: 900px) { :root { --ng-pad: 56px; } }

/* ---------- LA BARRE ---------- */
.n-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px var(--ng-pad);
  background: var(--ng-bg);
  border-bottom: 1px solid var(--ng-rule);
  pointer-events: none;
}
.n-head > * { pointer-events: auto; }
.n-logo {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 13px; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ng-fg); text-decoration: none;
}
.n-logo b { font-weight: 500; }
.n-logo b span { color: var(--ng-or-texte); }

.n-menu-btn {
  display: inline-flex; align-items: center; gap: 12px;
  background: none; border: 0; cursor: pointer;
  color: var(--ng-fg);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px; letter-spacing: .2em; text-transform: uppercase;
  padding: 10px 0; min-height: 44px; text-decoration: none;
}
.n-menu-btn .n-burger { display: inline-flex; flex-direction: column; gap: 5px; }
.n-menu-btn .n-burger i {
  display: block; width: 26px; height: 1px; background: var(--ng-fg);
  transition: transform .3s, opacity .3s;
}
.n-menu-btn[aria-expanded="true"] .n-burger i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.n-menu-btn[aria-expanded="true"] .n-burger i:nth-child(2) { opacity: 0; }
.n-menu-btn[aria-expanded="true"] .n-burger i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------- LE PANNEAU ---------- */
.n-menu {
  position: fixed; inset: 0; z-index: 60;
  background: var(--ng-bg);
  display: flex; flex-direction: column;
  justify-content: flex-start;          /* JAMAIS center avec overflow (piege connu) */
  padding: 96px var(--ng-pad) 40px;
  overflow-y: auto;
  overscroll-behavior: contain;
  visibility: hidden;
  transform: translateY(-1.5rem);
  opacity: 0;
  transition: opacity .28s ease, transform .28s ease, visibility .28s;
}
.n-menu[data-open="true"] { visibility: visible; opacity: 1; transform: translateY(0); }
.n-menu:target { visibility: visible; opacity: 1; transform: translateY(0); }

.n-menu-group {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--ng-or-texte); margin: 30px 0 8px;
}
.n-menu a.n-link {
  display: block; width: 100%; padding: 14px 0;
  border-top: 1px solid var(--ng-rule);
  font-family: Anton, Archivo, sans-serif;
  font-size: clamp(20px, 2.9vw, 34px);
  letter-spacing: -.01em; text-transform: uppercase;
  color: var(--ng-fg); text-decoration: none;
  transition: padding-left .2s, color .2s;
}
.n-menu a.n-link:hover { padding-left: 14px; color: var(--ng-or-texte); }
.n-menu-foot {
  margin-top: 30px;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  letter-spacing: .14em; color: var(--ng-dim);
}
.n-menu-foot a { color: var(--ng-dim); text-decoration: none; margin-right: 18px; }
.n-menu-foot a:hover { color: var(--ng-or-texte); }

/* le verrou de defilement quand le menu est ouvert */
.n-locked { overflow: hidden; }

/* ⚠️ Le menu doit tenir par paliers de HAUTEUR (meme regle que le site). */
@media (max-height: 920px) {
  .n-menu { padding: 80px var(--ng-pad) 28px; }
  .n-menu-group { margin: 20px 0 6px; }
  .n-menu a.n-link { padding: 10px 0; font-size: clamp(18px, 2.4vw, 28px); }
  .n-menu-foot { margin-top: 20px; }
}
@media (max-height: 760px) {
  .n-menu { padding: 64px var(--ng-pad) 20px; }
  .n-menu-group { margin: 14px 0 4px; }
  .n-menu a.n-link { padding: 8px 0; font-size: clamp(17px, 2.2vw, 24px); }
  .n-menu-foot { margin-top: 14px; font-size: 10px; }
}
@media (max-height: 620px) {
  .n-menu { padding: 54px var(--ng-pad) 14px; }
  .n-menu-group { margin: 9px 0 3px; font-size: 9px; }
  .n-menu a.n-link { padding: 6px 0; font-size: clamp(16px, 2vw, 21px); }
  .n-menu-foot { margin-top: 10px; }
}

/* ⚠️ La barre est fixe : le contenu des pages `_head` doit lui laisser la place. */
@media (max-width: 900px) {
  .n-head { padding: 9px var(--ng-pad); }
  .n-menu-btn { padding: 6px 0; min-height: 38px; }
  .n-menu-btn .n-burger i { width: 22px; }
}

/* ===== fin n_menu_global.css ===== */

/* ===== début design-arrondi.css ===== */
/* ============================================================================
   DESIGN ARRONDI — chargé EN DERNIER sur le site public ET le cockpit.

   ⚠️⚠️ DEMANDE USER (2026-10-07) : « fais un design beaucoup plus coin arrondi,
   quelque chose de beaucoup plus agréable à l'œil en globalité », sur le cockpit
   ET le site public (« cohérence totale »).

   CELA REMPLACE UNE RÈGLE ANTÉRIEURE. Jusqu'ici la charte disait « angles DROITS,
   AUCUNE ombre, aucun dégradé » et je l'appliquais partout. Le user a demandé
   explicitement l'inverse : on l'assume, et on l'écrit ici pour que personne ne
   « corrige » ces arrondis en croyant à une régression.

   ⚠️⚠️ POURQUOI CE FICHIER ET PAS CHAQUE FEUILLE. Mesuré avant d'écrire : sur les
   deux surfaces, **tous** les composants avaient `border-radius: 0px` et aucune
   ombre — 11 composants sur /pricing, 16 dans le cockpit. Modifier 20 feuilles de
   style (dont `no_scroll*.css`, 9 fichiers en cascade) aurait été ingérable et
   aurait fini par diverger. Une SEULE échelle, un SEUL fichier, chargé en dernier.

   ⚠️ IL EST VOLONTAIREMENT EN DERNIER dans l'ordre de chargement : il doit gagner
   sur `devisaly.css`, `sections.css` et les 9 `no_scroll*.css`. C'est la seule
   raison de son existence — d'où son nom explicite.

   ÉCHELLE (une seule définition, utilisée des deux côtés) :
     --r-xs  petit : badges, tags, pastilles
     --r-sm  champs, boutons secondaires
     --r-md  cartes, panneaux        <- la valeur qui porte le design
     --r-lg  grandes surfaces, sections
     --r-pil boutons principaux, pilules
   ============================================================================ */

:root {
  /* ---- L'échelle d'arrondis ---- */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-xl: 28px;
  --r-pil: 999px;

  /* ---- Ombres : chaudes, jamais grises ----
     ⚠️ Teintées d'or (176,138,62) et d'encre (25,23,19), pas de gris neutre : un
     gris neutre sur un fond ivoire vire au sale. Deux niveaux suffisent — au-delà,
     on ne distingue plus et on alourdit. */
  --ombre-1: 0 1px 2px rgba(25, 23, 19, .04), 0 2px 8px rgba(25, 23, 19, .04);
  --ombre-2: 0 2px 6px rgba(90, 70, 35, .06), 0 10px 28px rgba(90, 70, 35, .08);
  --ombre-3: 0 6px 18px rgba(90, 70, 35, .09), 0 22px 48px rgba(90, 70, 35, .11);
  --ombre-or: 0 4px 14px rgba(176, 138, 62, .20), 0 14px 36px rgba(176, 138, 62, .13);

  /* ---- Un mouvement doux, une seule courbe ---- */
  --t-doux: cubic-bezier(.22, .68, .32, 1);
  --d-court: .16s;
  --d-long: .28s;
}

/* ============================================================================
   1. SITE PUBLIC — les composants `n-*`
   ============================================================================ */

/* ---- 1.1 Boutons ---- */
.n-body .btn, .n-formwrap .btn, .n-body button.btn,
.n-body form button[type=submit], .n-fallback .btn,
.n-btn, .n-cta .btn {
  border-radius: var(--r-pil);
  transition: transform var(--d-court) var(--t-doux),
              box-shadow var(--d-court) var(--t-doux),
              background-color var(--d-court) var(--t-doux);
}
/* ⚠️ Un bouton rond qui « monte » d'1 px au survol : c'est ce qui donne la
   sensation de répondre au doigt. Sur mobile, `:active` remplace `:hover`. */
.n-btn:hover, .n-body .btn:hover, .n-cta .btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--ombre-2);
}
.n-btn:active, .n-body .btn:active, .n-cta .btn:active { transform: translateY(0); }

/* Le bouton d'or : la seule ombre colorée du site. Il doit « porter ». */
.n-btn--or, .n-body .btn.primary, .n-formwrap .btn.primary {
  box-shadow: var(--ombre-or);
}
.n-btn--or:hover, .n-body .btn.primary:hover,
.n-formwrap .btn.primary:hover {
  box-shadow: 0 6px 20px rgba(176, 138, 62, .28), 0 18px 44px rgba(176, 138, 62, .18);
}
.n-btn-ghost { border-radius: var(--r-pil); }

/* ---- 1.2 Champs ----
   ⚠️ `--r-md` (16 px), PAS `--r-sm` (10 px) — CORRIGÉ après contrôle visuel
   (2026-10-07). Mesuré : des champs à 10 px posés à côté de boutons en pilule
   créent une tension — l'œil lit deux systèmes. 16 px s'accorde aux deux, et c'est
   la valeur des cartes : le champ devient « un petit cartouche », pas un rectangle. */
.n-formwrap input, .n-formwrap select, .n-formwrap textarea,
.n-body input[type=text], .n-body input[type=email],
.n-body input[type=password], .n-body input[type=tel],
.n-body input[type=number], .n-body select, .n-body textarea,
input, select, textarea {
  border-radius: var(--r-md);
  transition: border-color var(--d-court) var(--t-doux),
              box-shadow var(--d-court) var(--t-doux);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--gold, #b08a3e);
  box-shadow: 0 0 0 3px rgba(176, 138, 62, .16);
}

/* ---- 1.3 Cartes et panneaux ----
   ⚠️⚠️ LES GRILLES À FILETS INTERNES ONT BESOIN DE `overflow:hidden`. Elles
   dessinent leurs séparations avec `gap:1px` + un fond coloré : sans découpe, les
   cellules dépassent des coins arrondis et on voit quatre petits carrés. */
.n-car, .n-car-item, .n-ex, .n-ex__visuel, .n-doc,
.n-plan, .n-plans, .n-formbox, .n-detail, .n-lecture,
.n-car--prix, .n-car--exemples, .n-commandes, .n-doc__table {
  border-radius: var(--r-md);
}
.n-plans, .n-doc, .n-car { overflow: hidden; }
.n-car-item, .n-ex, .n-plan, .n-formbox, .n-lecture {
  overflow: hidden;
  transition: transform var(--d-long) var(--t-doux),
              box-shadow var(--d-long) var(--t-doux),
              border-color var(--d-long) var(--t-doux);
}
.n-car-item:hover, .n-ex:hover, .n-plan:hover, .n-lecture:hover {
  transform: translateY(-2px);
  box-shadow: var(--ombre-2);
}
/* La carte « phare » se détache : c'est elle qui vend. */
.n-plan--phare {
  border-radius: var(--r-lg);
  box-shadow: var(--ombre-3);
}
.n-plan--phare:hover { box-shadow: var(--ombre-or); }

/* ---- 1.4 Images et pastilles ---- */
.n-car-item img, .n-ex__visuel img, .n-car img,
.n-doc img, .photo, .n-photo, figure img {
  border-radius: var(--r-sm);
}
.n-plan__badge { border-radius: var(--r-pil); }
.n-menu, .n-head { border-radius: 0; }   /* les barres restent franches */

/* ---- 1.5 Le devis (document) et le tunnel ---- */
.n-doc { box-shadow: var(--ombre-2); }
.n-doc__entete { border-radius: var(--r-md) var(--r-md) 0 0; }
.n-doc__pied { border-radius: 0 0 var(--r-md) var(--r-md); }
.n-formbox { box-shadow: var(--ombre-2); }

/* ============================================================================
   2. COCKPIT DE PROSPECTION — les composants internes
   ============================================================================ */

/* ---- 2.1 Boutons ---- */
.cta { border-radius: var(--r-pil); box-shadow: var(--ombre-1);
  transition: transform var(--d-court) var(--t-doux), box-shadow var(--d-court) var(--t-doux); }
.cta:hover { transform: translateY(-1px); box-shadow: var(--ombre-2); }
.cta:active { transform: translateY(0); }
.cta:disabled { box-shadow: none; transform: none; }
.lien, .frein button, .filtres button, .pg, .btn, .tel {
  border-radius: var(--r-pil);
  transition: transform var(--d-court) var(--t-doux),
              box-shadow var(--d-court) var(--t-doux),
              background-color var(--d-court) var(--t-doux);
}
.lien:hover, .filtres button:hover, .pg:hover, .tel:hover {
  transform: translateY(-1px); box-shadow: var(--ombre-2);
}
.btn-env, .btn-or { box-shadow: var(--ombre-or); }
.btn-or:hover, .btn-env:hover { box-shadow: 0 6px 20px rgba(176,138,62,.28); }
.btn-dgr { border-radius: var(--r-sm); box-shadow: none; }

/* ---- 2.2 Cartes, panneaux, listes ----
   ⚠️ `overflow:hidden` est INDISPENSABLE sur `.carte`, `.kpis`, `.parcours` et
   `table` : leurs cellules sont jointes par un `gap:1px` sur fond coloré. Sans
   découpe, les coins arrondis laissent voir les carrés des cellules. */
.carte, section.carte, .bloc, section.bloc, .desabo, .apercu-lot, .pret .bulle {
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--ombre-1);
}
.kpis, .parcours, .ab-barre, .plans {
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--ombre-1);
}
.kpi { transition: background-color var(--d-court) var(--t-doux); }
.kpi:hover { background: #fffdf8; }
.etape { transition: background-color var(--d-court) var(--t-doux); }
.etape:first-child { border-radius: var(--r-md) 0 0 var(--r-md); }
.etape:last-child { border-radius: 0 var(--r-md) var(--r-md) 0; }
.sorties a { border-radius: var(--r-sm); }
.sorties a:hover { background: #fbfaf7; box-shadow: none; }

/* ---- 2.3 Champs ----
   ⚠️ `--r-md` ici aussi (voir §1.2) : un champ à 10 px à côté d'un bouton en
   pilule fait jurer l'ensemble. */
input[type=number], input[type=search], input[type=text], select, textarea {
  border-radius: var(--r-md);
  transition: border-color var(--d-court) var(--t-doux),
              box-shadow var(--d-court) var(--t-doux);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(176, 138, 62, .16);
}
input[type=checkbox] { border-radius: var(--r-xs); }

/* ---- 2.4 Barres de progression ---- */
.jauge, .prog-piste { border-radius: var(--r-pil); overflow: hidden; }
.jauge-r, .prog-remplie { border-radius: var(--r-pil); }

/* ---- 2.5 Pastilles d'état, messages, tags ----
   ⚠️ `--r-pil` POUR LES PASTILLES (corrigé après contrôle visuel). Le badge « +9 »
   de tendance et les pastilles d'intention étaient à 6 px, donc presque carrés, au
   milieu d'une interface arrondie : c'était le détail qui jurait le plus. Une
   pastille de texte court est TOUJOURS une pilule — c'est la règle. */
.avis-f, .avis { border-radius: var(--r-sm); }
.delta, .intent, .objet .tag, .et, .cst .p, .fil .cat,
.n-plan__badge, .n-kicker, .recents .int, .ac, .p-act {
  border-radius: var(--r-pil);
}
.et, .cst .p { border-radius: var(--r-xs); }
.personnes .p-nom, .p-txt { border-radius: var(--r-sm); }
.etat-c { border-radius: var(--r-pil); }
.tel { border-radius: var(--r-md); box-shadow: var(--ombre-1); }
.tel .tel-l, .tel .tel-n { border-radius: 0; }

/* ---- 2.6 LA MESSAGERIE — les bulles ----
   ⚠️⚠️ UNE BULLE N'EST PAS UNE CARTE. Sur WhatsApp, le coin du côté de celui qui
   parle est NET (il « sort » de la bulle), les trois autres sont arrondis : c'est
   ce qui indique qui parle sans lire un mot. On garde cette asymétrie — un
   arrondi uniforme donnerait une liste de cartes, pas une conversation. */
.ligne .bulle { border-radius: var(--r-lg); }
.ligne.nous .bulle { border-bottom-right-radius: var(--r-xs); }
.ligne.lui .bulle { border-bottom-left-radius: var(--r-xs); }
.bulle { box-shadow: var(--ombre-1); }
.pret .bulle { border-radius: var(--r-lg);
  border-bottom-right-radius: var(--r-xs); }

/* ---- 2.7 Tableaux ---- */
table { border-radius: var(--r-md); overflow: hidden; }
tbody tr:hover { background: #fbfaf7; }

/* ---- 2.8 Le rail et les écrans ---- */
.rail nav a { border-radius: var(--r-sm); border-left: 0; }
.rail nav a.on { border-radius: var(--r-sm); }
.sep span { border-radius: var(--r-xs); background: #fff; padding: 0 10px; }
.recents li, .personnes li, .fil li:last-child { border-radius: 0; }
details > summary { border-radius: var(--r-sm); }

/* ============================================================================
   3. LES ÉLÉMENTS DE NAVIGATION ET DE PIED
   ⚠️ Ajouté après vérification (2026-10-07) : `.n-menu-btn`, les liens du menu
   plein écran `.n-link` (1328 px de large) et les liens du pied étaient les
   DERNIERS à rester carrés — mesurés à `border-radius: 0px` après la première
   passe. Ce sont eux qu'on touche en premier sur mobile (le bouton « Menu »), donc
   ce sont eux qui décidaient de l'impression générale. Un `border-radius` sur un
   élément de 1328 px ne se voit pas, mais son survol et son état actif, si.
   ============================================================================ */
.n-menu-btn, .n-burger, .n-link, .n-menu a, .n-footer a,
footer a, .footer-mail, .n-head a {
  transition: background-color var(--d-court) var(--t-doux),
              border-radius var(--d-court) var(--t-doux),
              color var(--d-court) var(--t-doux);
}
/* ⚠️ Le burger et le lien du pied : un arrondi MODÉRÉ (`--r-sm`), pas une pilule.
   Une pilule de 1328 px de large serait un ovale — le lien du menu est une LIGNE,
   pas un bouton. On arrondit juste assez pour que le survol ait une forme. */
.n-menu-btn, .n-burger { border-radius: var(--r-sm); }
.n-link, .n-menu a { border-radius: var(--r-sm); }
.n-footer a, footer a, .footer-mail { border-radius: var(--r-xs); }
.n-link:hover, .n-menu a:hover { background: rgba(176, 138, 62, .07); }

/* ============================================================================
   4. RESPECT DE `prefers-reduced-motion`
   ⚠️ Un utilisateur qui a demandé moins d'animation n'en reçoit AUCUNE. Le
   `transform` au survol est une animation : on le coupe aussi, pas seulement les
   `transition`.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
  }
  .n-btn:hover, .n-body .btn:hover, .cta:hover, .lien:hover,
  .n-car-item:hover, .n-ex:hover, .n-plan:hover, .lecture:hover,
  .filtres button:hover, .pg:hover, .tel:hover {
    transform: none !important;
  }
}

/* ===== fin design-arrondi.css ===== */

/* ===== début nuee3d.css ===== */
/* ============================================================================
   LA NUÉE — couche de fond commune (2026-10-13)

   ⚠️ À QUOI ÇA SERT. Le décor animé (`nuee3d.js`) doit être visible sur TOUTES
   les pages : accueil, offres, /prix, /services, métiers, départements, blog,
   CGV, mentions, tableau de bord, administration. Les pages viennent de deux
   gabarits différents (`_head.html` et `_n_essentiel.html`) qui peignent chacun
   leur fond opaque (`body{background:var(--paper)}` d'un côté, `.n-body{
   background:var(--n-bg)}` de l'autre) : sans cette feuille, la nuée resterait
   cachée derrière eux.

   ⚠️⚠️ UNE SEULE COUCHE, ET C'EST LE CANVAS (2026-10-13, bug constaté en prod).
   La première version posait un DEUXIÈME calque plein écran : un `<div>` voile
   de lisibilité en `z-index:-1`. Résultat : les images de la page — les trois
   exemples de l'accueil — s'affichaient EN BLANC, le compositeur du navigateur
   perdant leur calque. Le voile est désormais peint DANS le canvas (dernière
   passe de `dessiner()`), et il n'existe plus aucun élément plein écran autre
   que `#nuee-fond`. ⚠️ Ne jamais réintroduire de `<div>` de ce genre ici.

   ⚠️ LE CONTENU N'EST PAS TOUCHÉ. Aucun `z-index` de page n'est modifié, aucune
   carte, aucun menu ne change de plan : le canvas reste en `z-index:-2`, donc
   au-dessus du fond de `<html>` et sous tout le reste.

   ⚠️ Le fond papier du canvas (propriété `background` ci-dessous) n'est qu'un
   repli pour l'instant qui précède la première image, quand le JS n'a pas
   encore tourné : dès la première image, le voile peint dans le canvas prend
   le relais.
   ============================================================================ */

#nuee-fond {
  position: fixed;
  inset: 0;
  z-index: -2;
  display: block;
  pointer-events: none;   /* un décor ne capte jamais un clic */
  background: linear-gradient(180deg,
      rgba(247, 244, 238, .62) 0%,
      rgba(247, 244, 238, .86) 42%,
      rgba(247, 244, 238, .97) 100%);
}

/* Les deux fonds pleine page laissent voir la nuée. Les surfaces de contenu
   (cartes, panneaux, menus, tableaux) gardent leur fond : elles restent nettes. */
html { background-color: var(--paper, #f7f4ee); }
html.nuee-on body { background-color: transparent !important; }
html.nuee-on .n-body { background: transparent !important; }

/* Surface plein écran du gabarit « no scroll ». */
html.nuee-on .n-screen { background: transparent; }

/* Le décor ne s'affiche pas à l'impression. */
@media print {
  #nuee-fond { display: none; }
  html { background: #fff; }
}

/* ===== fin nuee3d.css ===== */

/* ===== début barre_et_contenu.css ===== */
/* ============================================================
   LA BARRE DU HAUT ET LE DÉBUT DU CONTENU (2026-10-13)

   ⚠️⚠️ POURQUOI CETTE FEUILLE. Passé le site au crible page par page, deux
   défauts sont apparus sur la famille « classique » (`_head.html` : connexion,
   inscription, merci, hors-ligne, pages pub…) :

   1. LA BARRE N'AVAIT PAS LA MÊME HAUTEUR D'UN BOUT À L'AUTRE DU SITE.
      `n_menu_global.css` la posait à `padding: 20px` → 85 px de haut.
      `no_scroll_barre.css` (famille « no scroll ») la même à 11 px → 63 px.
      Deux hauteurs pour le même composant, donc une rupture visible dès qu'on
      change de page. Objectif de la charte : ≤ 72 px.

   2. LE CONTENU PASSAIT SOUS LA BARRE. Mesuré en 1366x768, barre à 85 px :
        /offline        titre à y = 42  (caché)
        /visibilite/merci  titre à y = 50  (caché)
        /ads            titre à y = 71  (caché)
      Ces pages posaient leur bloc à `y = 0` sans réserver la barre, qui est
      `position: fixed`.

   ⚠️ RÉDUIRE LA BARRE NE DÉPLACE RIEN : elle est hors flux. Les pages perdent
   22 px de chevauchement sans qu'aucune mise en page ne bouge. Les 3 pages
   cassées reçoivent en plus le décalage qui leur manquait, mesuré page par page.
   ============================================================ */

/* ---- 1. une seule hauteur de barre pour tout le site ---- */
.n-head { padding: 10px var(--ng-pad, 24px); }

/* ---- 2. le contenu commence SOUS la barre ---- */

/* Pages à carte centrale (connexion, inscription, mot de passe oublié, pub) :
   la carte était posée à y = 0, son en-tête de marque disparaissait sous la
   barre et le titre la frôlait. */
body.auth-body .auth-card { padding-top: 56px; }

/* Page hors-ligne : bloc court posé à y = 0. */
.offline-card { margin-top: 48px; }

/* Page de remerciement Visibilité : `.visi-thanks` avait `margin-top: 40px`,
   ce qui laissait le titre (88 px de haut) à cheval sur la barre. */
.visi-thanks { margin-top: 92px; }

/* ⚠️ Noté pour mémoire : sur la famille « no scroll », `/leads` place son h1 à
   68 px pour une barre de 63 px. C'est l'espacement voulu par
   `no_scroll_barre.css` (`.n-formwrap { padding-top: 68px }`) : le titre est
   dégagé, on ne touche pas. Les pages à contenu centré de cette famille
   (`/contact`, `/artisan`, `/visibilite`) sont à 117-126 px, donc largement
   dégagées. */

/* ===== fin barre_et_contenu.css ===== */

/* ===== début passe-interface.css ===== */
/* ============================================================
   PASSE D'INTERFACE — 2026-10-13
   Feuille chargée EN DERNIER dans les deux familles de gabarits
   (`_head.html` pour les pages classiques, `n_base.html` + `_n_essentiel.html`
   pour les pages publiques). Elle ne réécrit aucune page : elle repose les
   mêmes composants avec une seule échelle, une seule palette et un seul rythme.

   ⚠️ CE QUI N'ALLAIT PAS, RELEVÉ PAGE PAR PAGE :
   1. Le fond des pages publiques était BLANC PUR (`--n-bg: #ffffff`) et l'encre
      NOIRE (`--n-fg: #0a0a0a`), alors que la charte du site est ivoire
      (#f7f4ee) et encre chaude (#191713). La moitié du site était froide.
   2. Chaque famille avait ses propres cotes de bouton, de carte et de champ.
   3. Les titres de section n'avaient pas de repère : pas d'échelle commune
      entre l'accueil (titre géant) et une page de prix (titre moyen).
   4. Le pied de page de la famille publique n'existait PAS (voir
      templates/_n_pied.html), et celui de la famille classique était clair,
      sans hiérarchie.
   5. Aucun état de focus visible sur les champs : on tabulait dans le vide.

   ⚠️ ORDRE DE CHARGE : cette feuille DOIT rester la dernière. Les feuilles de
   page (`seo_*.html`, `admin_*.html`) qui viennent après gardent la main sur
   leur propre périmètre.
   ============================================================ */

:root {
  /* La charte, écrite une fois pour tout le site. */
  --pi-papier:      #f7f4ee;   /* ivoire : le fond de tout le site */
  --pi-papier-2:    #efeae0;   /* ivoire plus dense : bandeaux, survols */
  --pi-carte:       #fffdf9;   /* le papier des cartes, plus clair que le fond */
  --pi-encre:       #191713;   /* encre chaude, jamais du noir pur */
  --pi-encre-doux:  #6f675a;   /* texte secondaire (4,9:1 sur ivoire) */
  --pi-or:          #b08a3e;   /* aplats, traits, gros chiffres */
  --pi-or-clair:    #e8c887;   /* or sur fond sombre */
  --pi-or-profond:  #8a6a2a;   /* texte doré fin (4,6:1 sur ivoire) */
  --pi-ligne:       rgba(25, 23, 19, .10);
  --pi-ligne-forte: rgba(25, 23, 19, .18);
  --pi-ligne-or:    rgba(176, 138, 62, .30);
  --pi-ombre-1: 0 1px 2px rgba(25, 23, 19, .05), 0 4px 14px rgba(25, 23, 19, .05);
  --pi-ombre-2: 0 10px 30px rgba(90, 70, 35, .10), 0 2px 6px rgba(90, 70, 35, .06);
}

/* ---------- 1. LE PAPIER ---------- */
html, body, .n-body, .n-screen, .vitrine { background-color: var(--pi-papier); }
body, .n-body { color: var(--pi-encre); }

/* Les jetons historiques pointent maintenant sur la charte : les pages qui les
   utilisent (elles sont nombreuses) suivent sans être touchées. */
:root {
  --n-bg:       var(--pi-carte);
  --n-fg:       var(--pi-encre);
  --n-dim:      var(--pi-encre-doux);
  --n-rule:     var(--pi-ligne);
  --n-or:       var(--pi-or);
  --n-or-texte: var(--pi-or-profond);
  --n-or-ligne: var(--pi-ligne-or);
}

/* ---------- 2. L'ÉCHELLE TYPOGRAPHIQUE ---------- */
.n-title {
  font-size: clamp(2.1rem, 5.2vw, 5rem);
  line-height: .99; letter-spacing: -.022em;
  text-wrap: balance;
}
.n-kicker {
  color: var(--pi-or-profond);
  letter-spacing: .24em; font-size: .72rem;
  display: flex; align-items: center; gap: .7rem;
}
.n-kicker::before {           /* un trait doré : la page a un début lisible */
  content: ""; width: 28px; height: 1px;
  background: var(--pi-or); opacity: .75; flex: 0 0 auto;
}
.n-sub {
  font-size: clamp(1rem, 1.1vw, 1.12rem);
  line-height: 1.7; color: var(--pi-encre-doux); max-width: 58ch;
  text-wrap: pretty;
}
.n-car-label, h2, h3 { letter-spacing: -.01em; }

/* ---------- 3. LES BOUTONS : une seule famille ---------- */
.n-btn, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 52px; padding: 0 26px; border: 1px solid transparent; border-radius: 999px;
  font-family: 'IBM Plex Mono', monospace; font-size: .76rem; font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase; text-decoration: none;
  cursor: pointer; background: var(--pi-encre); color: #fbf8f2;
  transition: transform var(--d-court, .16s) var(--t-doux, ease),
              box-shadow var(--d-court, .16s) var(--t-doux, ease),
              background-color var(--d-court, .16s), border-color var(--d-court, .16s), color var(--d-court, .16s);
}
.n-btn:hover, .btn:hover { transform: translateY(-1px); box-shadow: var(--pi-ombre-2); }
.n-btn:active, .btn:active { transform: translateY(0); box-shadow: var(--pi-ombre-1); }

/* Bouton or : encre sur or. C'est la règle de contraste de la charte
   (« --n-or : aplats ; encre des boutons or »). */
.n-btn--or, .btn.primary { background: var(--pi-or); color: #1c1607; }
.n-btn--or:hover, .btn.primary:hover { background: #bd954a; }

/* Bouton contour : pour l'action secondaire, jamais deux boutons pleins côte à côte. */
.n-btn-ghost, .btn.ghost {
  background: transparent; color: var(--pi-encre); border-color: var(--pi-ligne-forte);
}
.n-btn-ghost:hover, .btn.ghost:hover { border-color: var(--pi-or); color: var(--pi-or-profond); background: transparent; }

.btn.big { min-height: 56px; padding: 0 30px; font-size: .8rem; }

/* ---------- 4. LES CARTES ---------- */
.n-car-item, .n-plan, .n-preuve, .n-pay, .n-rappel__form, .card, .auth-card,
.lead-benefit, .tn-chip, .n-pastille {
  background: var(--pi-carte);
  border: 1px solid var(--pi-ligne);
  border-radius: var(--r-lg, 22px);
  box-shadow: var(--pi-ombre-1);
  transition: transform var(--d-court, .16s) var(--t-doux, ease),
              box-shadow var(--d-court, .16s) var(--t-doux, ease),
              border-color var(--d-court, .16s);
}
.n-car-item:hover, .n-plan:hover, .n-preuve:hover, .lead-benefit:hover {
  transform: translateY(-2px);
  box-shadow: var(--pi-ombre-2);
  border-color: var(--pi-ligne-or);
}
.n-car-item { padding: 1.15rem 1.25rem; }
.n-car-item h3 { color: var(--pi-encre); letter-spacing: -.005em; }
.n-prix { color: var(--pi-or-profond); font-variant-numeric: tabular-nums; }

.n-plan { padding: 1.9rem 1.7rem; }
.n-plan__nom { color: var(--pi-or-profond); }
.n-plan__prix { font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.n-plan--phare { border-color: var(--pi-ligne-or); box-shadow: var(--pi-ombre-2); }
.n-plan__badge {
  background: var(--pi-or); color: #1c1607; border: 0; border-radius: 999px;
}
.n-plan__liste li::marker { color: var(--pi-or); }

/* ---------- 5. LES CHAMPS ---------- */
input[type=text], input[type=email], input[type=tel], input[type=password],
input[type=search], select, textarea {
  border-radius: var(--r-sm, 10px) !important;
  border: 1px solid var(--pi-ligne-forte) !important;
  background: #fff; color: var(--pi-encre);
  min-height: 52px; padding: 0 16px; font-size: 1rem;
  font-family: Inter, Archivo, system-ui, sans-serif;
  transition: border-color var(--d-court, .16s), box-shadow var(--d-court, .16s);
}
textarea { padding: 14px 16px; line-height: 1.6; min-height: 110px; }
input::placeholder, textarea::placeholder { color: rgba(25, 23, 19, .42); }

/* ⚠️ Sans anneau de focus, on tabule dans le vide : le champ actif doit se voir. */
input:focus, select:focus, textarea:focus,
.n-btn:focus-visible, .btn:focus-visible, a:focus-visible, summary:focus-visible {
  outline: none;
  border-color: var(--pi-or) !important;
  box-shadow: 0 0 0 3px rgba(176, 138, 62, .18) !important;
}
a:focus-visible, .n-btn:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--pi-or); outline-offset: 3px; box-shadow: none !important;
}
label { color: var(--pi-encre-doux); }

/* ---------- 6. LA BARRE DU HAUT ---------- */
.n-head {
  background: rgba(247, 244, 238, .88) !important;
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--pi-ligne) !important;
}
.n-logo { color: var(--pi-encre) !important; letter-spacing: .01em; }
.n-logo b { font-weight: 500; }
.n-logo b span { color: var(--pi-or-profond); }
.n-menu-btn {
  border-radius: 999px !important; border: 1px solid var(--pi-ligne-forte) !important;
  transition: border-color var(--d-court, .16s), background-color var(--d-court, .16s);
}
.n-menu-btn:hover { border-color: var(--pi-or) !important; background: var(--pi-papier-2); }

/* ---------- 7. LE RYTHME DES SECTIONS ---------- */
.n-screen { padding-left: var(--n-pad); padding-right: var(--n-pad); }
.n-car { gap: 1rem; scroll-padding-left: var(--n-pad); }
.n-detail details {
  border: 1px solid var(--pi-ligne); border-radius: var(--r-md, 16px);
  background: var(--pi-carte); padding: 2px 20px 6px; margin-bottom: 10px;
}
.n-detail summary {
  cursor: pointer; padding: 16px 0; font-family: 'IBM Plex Mono', monospace;
  font-size: .76rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--pi-encre); list-style: none;
}
.n-detail summary::-webkit-details-marker { display: none; }
.n-detail summary::after { content: "+"; float: right; color: var(--pi-or-profond); }
.n-detail details[open] summary::after { content: "−"; }
.n-detail p { color: var(--pi-encre-doux); line-height: 1.7; }

/* Les quatre chiffres de l'accueil : un vrai bandeau, plus du texte posé. */
.n-facts { border-top: 1px solid var(--pi-ligne-or); border-bottom: 1px solid var(--pi-ligne-or); }
.n-facts dt { color: var(--pi-or-profond); letter-spacing: .14em; }
.n-facts dd { color: var(--pi-encre); font-variant-numeric: tabular-nums; }
.n-facts > div { border-right-color: var(--pi-ligne); }

/* ---------- 8. DÉTAILS ---------- */
::selection { background: rgba(176, 138, 62, .26); }
html { scroll-behavior: smooth; }
a, button, summary { -webkit-tap-highlight-color: transparent; }
img { max-width: 100%; }

/* ---------- 9. LES PIEDS DE PAGE : la même encre pour les deux familles ---------- *
   ⚠️ Le pied public n'existait pas (voir templates/_n_pied.html) et celui de la
   famille classique était clair, sans hiérarchie, avec un logo à fond clair.
   Les deux passent sur l'encre du site, texte ivoire, accents or. */
.np, .footer {
  background: var(--pi-encre); color: #e7e0d2;
  padding: 3.6rem var(--n-pad, 28px) 2rem;
}
.np a, .footer a, .np__mail, .footer-mail, .footer-tagline {
  color: #e7e0d2; text-decoration: none; opacity: .8;
  transition: color var(--d-court, .16s), opacity var(--d-court, .16s);
}
.np a:hover, .footer a:hover { color: var(--pi-or-clair); opacity: 1; }
.np__grille {
  display: grid; grid-template-columns: 1.6fr repeat(3, 1fr); gap: 2.4rem;
  max-width: 1120px; margin: 0 auto;
}
.np__logo {
  font-family: Anton, Archivo, sans-serif; font-size: 1.4rem; letter-spacing: .01em;
  text-transform: lowercase; opacity: 1 !important; color: #f6f1e7 !important;
}
.np__phrase { margin: .9rem 0 .6rem; max-width: 34ch; font-size: .95rem; line-height: 1.65; opacity: .72; }
.np__titre, .footer h4 {
  font-family: 'IBM Plex Mono', monospace; font-size: .7rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--pi-or-clair); margin: 0 0 1rem;
}
.np__col { display: flex; flex-direction: column; gap: .62rem; font-size: .95rem; }
.np__bas {
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between; align-items: center;
  max-width: 1120px; margin: 3rem auto 0; padding-top: 1.4rem;
  border-top: 1px solid rgba(232, 200, 135, .18); font-size: .82rem; opacity: .7;
}
.np__liens { display: flex; gap: 1.2rem; }

/* la famille classique : on garde sa grille et son bloc de marque, on change l'encre */
.footer { padding: 3.2rem 0 1.8rem; }
.footer-grid { max-width: 1120px; margin: 0 auto; padding: 0 var(--n-pad, 28px); gap: 2.4rem; }
.footer .brand-name { color: #f6f1e7; }
.footer .brand-name span { color: var(--pi-or-clair); }
/* ⚠️ Le logo de la marque est un fichier à fond clair : sur l'encre il
   disparaîtrait. On garde le mot-symbole, qui lui est lisible. */
.footer .brand-mark { display: none; }
.footer h4 { margin-bottom: .85rem; }

@media (max-width: 980px) { .np__grille { grid-template-columns: 1fr 1fr; gap: 1.9rem; } }
@media (max-width: 560px) {
  .np__grille { grid-template-columns: 1fr; gap: 1.6rem; }
  .np__bas { flex-direction: column; align-items: flex-start; margin-top: 2rem; }
}

/* ---------- 10. FINITIONS DE LA PREMIÈRE PASSE (mesurées à l'écran) ---------- */

/* ⚠️ Le titre de l'accueil plafonnait à 48 px en 1440 : `no_scroll_dimension.css`
   verrouille la taille des titres en `@media (min-width: 900px)` avec
   `!important` (3,333 vw). Un hero qui vend « vous êtes invisible sur Google »
   mérite plus d'autorité. C'est le SEUL endroit de cette passe où l'on écrit
   `!important` — il faut bien relever un verrou pour le relever. */
.n-screen--accueil .n-title, .n-screen--pay .n-title {
  font-size: clamp(2.4rem, 4.7vw, 4.4rem) !important;
  letter-spacing: -.02em;
}
/* Le hero prend la largeur de l'écran : le regard descend, il ne balaie pas. */
.n-screen--accueil .n-sub { max-width: 52ch; }

/* ⚠️ `.n-blur` posait un gros aplat beige en haut à droite : sur le papier ivoire
   il se lit comme un bloc inachevé, pas comme une lumière. On en fait une lueur
   très douce, et on la garde hors du texte. */
.n-blur { opacity: .45 !important; filter: blur(60px) saturate(120%) !important; }
.n-blur span {
  background: radial-gradient(circle at 50% 50%, rgba(176,138,62,.32), rgba(176,138,62,0) 72%) !important;
}

/* Les exemples : le métier en étiquette dorée, la description discrète. */
.n-preuves__tete { color: var(--pi-encre); letter-spacing: .2em; }
.n-preuve__corps { padding: .9rem 1.1rem 1.05rem; }
.n-preuve__corps b {
  display: block; font-family: 'IBM Plex Mono', monospace; font-size: .74rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--pi-or-profond);
}
.n-preuve__quoi { color: var(--pi-encre-doux); font-size: .9rem; }
.n-preuve { overflow: hidden; }
.n-preuve__visuel { display: block; border-bottom: 1px solid var(--pi-ligne); }
.n-preuves__plus {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: 'IBM Plex Mono', monospace; font-size: .74rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--pi-or-profond); text-decoration: none;
}
.n-preuves__plus:hover { color: var(--pi-encre); }

/* Le carrousel de prestations : même hauteur de carte, titre en encre, prix en or. */
.n-car-item h3 { font-size: 1.02rem; }
.n-car-item .n-prix { font-size: .95rem; }

/* Les listes d'offres : un tiret doré, pas un carré de navigateur. */
.n-plan__liste { list-style: none; padding-left: 0; }
.n-plan__liste li { position: relative; padding-left: 1.15rem; }
.n-plan__liste li::before {
  content: "—"; position: absolute; left: 0; color: var(--pi-or);
}
.n-plan__liste li::marker { content: ""; }

/* ---------- 11. LES ÉCRANS NE TRONQUENT PLUS LEUR DERNIER BLOC ----------
   ⚠️⚠️ MESURÉ sur /pricing : `section.n-screen--prix` a `height: 100svh` (900 px)
   et `overflow: hidden auto`. Le bloc « DevisalySEO » qui la suit était donc
   COUPÉ EN DEUX au ras du bas de l'écran. Le défaut passait inaperçu tant que la
   page se terminait là ; depuis qu'elle a un pied de page, la coupure saute aux
   yeux. L'écran garde sa hauteur minimale (l'effet « une seule page »), mais il
   ne tronque plus : ce qui dépasse allonge la page au lieu d'être perdu. */
.n-screen--prix { height: auto !important; min-height: 100svh; overflow: visible !important; }

/* ---------- 12. LES EXEMPLES SUR MOBILE : une rangée qu'on fait glisser ----------
   ⚠️ Mesuré en 390 px : la grille des exemples restait en trois colonnes, chaque
   étiquette se cassait sur quatre lignes (« PLOMBIER / Dépannage et
   installations, à Lyon »). On passe en rangée glissante — c'est déjà le langage
   du site pour les carrousels (« FAITES DÉFILER ») — avec accroche au doigt. */
@media (max-width: 860px) {
  /* ⚠️ La grille gardait `grid-template-columns: repeat(3, 1fr)` d'une autre
     feuille : tant qu'on ne la neutralise pas, les items restent à 1fr et les
     étiquettes se cassent sur quatre lignes. */
  .n-preuves__grille {
    display: grid !important; grid-template-columns: none !important;
    grid-auto-flow: column !important; grid-auto-columns: 78% !important;
    gap: .9rem; overflow-x: auto; scroll-snap-type: x mandatory;
    scroll-padding-left: var(--n-pad, 20px);
    -webkit-overflow-scrolling: touch;
    padding-bottom: .4rem;
  }
  .n-preuves__grille::-webkit-scrollbar { display: none; }
  .n-preuve { scroll-snap-align: start; }
  .n-preuve__corps b { font-size: .7rem; }
  .n-preuve__quoi { font-size: .86rem; }
}


/* ============================================================
   13. UNE SEULE COLONNE DE CONTENU (2026-10-13, « tout n'est pas centré »)

   ⚠️⚠️ CE QUE LA MESURE MONTRE. Le site n'a pas UNE grille, il en a cinq.
   Bords gauches relevés en 1440 px de large :

        accueil, /pricing, /services, /blog, pages prix   56 px   (pleine largeur)
        /visibilite, /leads, /contact, /artisan          130 px
        pied de page classique                           155 px
        bandeau « être rappelé » et pied public          160 px
        carte de connexion                               500 px (centrée)

   Cinq bords gauches : le logo de la barre (56) ne tombe jamais sur le texte de
   la page, et le pied ne tombe sur rien. C'est ça, le « décalé » — ce n'est pas
   une impression, c'est mesuré.

   ⚠️ LA RÈGLE. Une colonne de 1120 px, centrée, jamais moins de 28 px de marge :
   c'est déjà la largeur du pied, du bandeau, des pages /leads et /visibilite, et
   du `.container` historique. On aligne les pages « pleine largeur » sur elle,
   plutôt que l'inverse : le texte d'un paragraphe ne doit pas courir sur 1328 px.
   ============================================================ */
:root { --pi-colonne: 1120px; }

/* Les écrans de la famille no-scroll : la gouttière devient une gouttière de
   colonne. `padding-inline` ne touche pas le `padding-top` de chaque écran. */
.n-screen {
  padding-inline: max(var(--n-pad, 28px), calc((100% - var(--pi-colonne)) / 2)) !important;
}

/* Les pages à formulaire (leads, contact, artisan, tunnel) : même colonne. */
.n-formwrap, .artisan-hero {
  padding-inline: max(24px, calc((100% - var(--pi-colonne)) / 2)) !important;
}

/* Le bandeau « être rappelé ». */
.n-rappel {
  max-width: none; padding-inline: max(var(--n-pad, 28px), calc((100% - var(--pi-colonne)) / 2));
}
.n-rappel__txt, .n-rappel__form { max-width: 520px; }

/* Le pied de page public : même colonne que la page, pas 104 px plus à droite. */
.np__grille, .np__bas {
  max-width: none;
  padding-inline: max(var(--n-pad, 28px), calc((100% - var(--pi-colonne)) / 2));
}

/* Le pied de page classique : sa colonne est celle de `.container` (1120 px avec
   ses 28 px internes). On enlève la marge double qui le décalait de 25 px. */
.footer-grid { max-width: var(--pi-colonne); margin: 0 auto; padding-inline: 0; }
.footer .container { max-width: none; padding-inline: 0; }

/* ⚠️ Sur mobile, la carte de connexion touchait les deux bords : centrée sur
   grand écran, collée aux bords en 390 px. */
@media (max-width: 620px) {
  .auth-body .auth-card, .auth-card { width: auto; margin-inline: 20px; }
}

/* ⚠️⚠️ ET LA BARRE DU HAUT N'ÉTAIT PAS SUR LA COLONNE. Le logo est à 56 px du
   bord alors que TOUT le texte des pages commence à 153 px : sur chaque page, le
   mot-symbole flottait à gauche de tout le reste — c'est le premier « décalage »
   qui saute aux yeux. La barre reste pleine largeur (son filet traverse l'écran),
   mais son contenu se cale sur la colonne, et le bouton MENU sur le bord droit. */
.n-head {
  padding-inline: max(var(--ng-pad, 24px), calc((100% - var(--pi-colonne)) / 2)) !important;
}


/* ============================================================
   14. LE RYTHME VERTICAL, LE BOUTON DE BARRE, LES DERNIERS DÉCALAGES
   ============================================================ */

/* ---------- 14.1 Un rythme vertical, au lieu de paddings au cas par cas ----------
   ⚠️ Les écarts entre sur-titre, titre, sous-titre, boutons et blocs étaient
   posés à la main dans huit feuilles (22, 26, 32, 48 px selon l'endroit). Une
   seule échelle : 8, 16, 24, 32, 48, 64. */
.n-kicker { margin-bottom: 20px; }
.n-title { margin: 0; }
.n-sub { margin-top: 24px; }
.n-cta { margin-top: 32px; }
.n-preuves { margin-top: 48px; }
.n-facts { margin-top: 40px; }
.n-facts dt { margin-top: 8px; }
.n-facts dd { margin-top: 16px; }
.n-detail { margin-top: 48px; }
.n-car-item { padding: 20px 22px; }
.n-plan { padding: 32px 30px; }
.n-plan__pied { margin-top: 24px; }
.n-pay { margin-top: 48px; padding-top: 32px; }
.n-rappel { padding-block: 64px 72px; }
.np { padding-block: 64px 32px; }
.np__bas { margin-top: 48px; padding-top: 24px; }

/* ---------- 14.2 Le bouton de conversion dans la barre du haut ----------
   ⚠️ Ajouté dans les deux partials de barre. Un bouton discret, à gauche du
   MENU : c'est la seule action du site qui rapporte. */
.n-head__cta {
  margin-left: auto; margin-right: 14px;
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 18px;
  border-radius: 999px; background: var(--pi-or); color: #1c1607;
  font-family: 'IBM Plex Mono', monospace; font-size: .7rem; letter-spacing: .13em;
  text-transform: uppercase; text-decoration: none; white-space: nowrap;
  transition: background-color var(--d-court, .16s), transform var(--d-court, .16s);
}
.n-head__cta:hover { background: #bd954a; transform: translateY(-1px); }
@media (max-width: 560px) {
  .n-head__cta { min-height: 36px; padding: 0 13px; font-size: .64rem; letter-spacing: .1em; margin-right: 8px; }
}

/* ---------- 14.2 bis Le bouton « Appeler » (2026-10-13) ----------
   ⚠️ UN SEUL BOUTON OR PAR ÉCRAN : « Être rappelé » le reste. Celui-ci est en
   CONTOUR (fond transparent, filet d'encre), donc il ne concurrence pas l'action qui
   rapporte, et il reste lisible sur le fond clair comme sur le fond or.

   ⚠️ IL PORTE `margin-left: auto`, PAS `.n-head__cta` SEUL. La barre est en
   `justify-content: space-between` : c'est ce `margin-left:auto` qui pousse le bloc
   des actions vers la droite. Posé AVANT « Être rappelé » dans le DOM, il pousse donc
   les deux boutons ensemble et laisse le logo à gauche. Vérifié en 390 px : la barre
   ne débordait plus dès qu'on l'a masqué sous 900 px (voir plus bas).

   ⚠️ IL DISPARAÎT SOUS 900 px. À 390 px, la barre porte le logo, « Être rappelé » et le
   bouton MENU : un quatrième élément la faisait passer à la ligne. Le numéro reste
   joignable depuis le pied du menu plein écran (`_n_menu.html`), et c'est justement
   sur téléphone qu'un `tel:` est le plus utile — on ne le supprime donc pas, on le
   déplace. */
.n-head__tel {
  margin-left: auto; display: inline-flex; align-items: center;
  min-height: 40px; padding: 0 16px;
  border: 1px solid rgba(10, 10, 10, .35); border-radius: 999px;
  background: transparent; color: #0a0a0a; text-decoration: none; white-space: nowrap;
  font-family: 'IBM Plex Mono', monospace; font-size: .7rem; letter-spacing: .1em;
  text-transform: uppercase;
  transition: border-color var(--d-court, .16s), color var(--d-court, .16s);
}
.n-head__tel:hover { border-color: var(--pi-or, #b8892e); color: #8a6a2a; }
/* ⚠️ Quand « Appeler » est là, c'est LUI qui pousse à droite : « Être rappelé » ne doit
   plus le refaire, sinon les deux se disputent la marge automatique et le logo part au
   milieu. */
.n-head__tel + .n-head__cta { margin-left: 14px; }
@media (max-width: 900px) {
  .n-head__tel { display: none; }
  .n-head__cta { margin-left: auto; }
}

/* ---------- 14.3 Les deux derniers décalages mesurés ----------
   ⚠️ 1. La famille classique posait son contenu 7 px à droite du reste
   (`.container { max-width: 1120px; padding: 0 28px }` : le contenu interne
   commençait à 160 px quand la colonne publique commence à 153). En élargissant
   le conteneur de ses deux gouttières, les deux familles tombent au même pixel.
   ⚠️ 2. Le menu plein écran gardait la gouttière de 56 px : ses entrées ne
   tombaient pas sur la colonne du contenu qu'elles recouvrent. */
.container { max-width: calc(var(--pi-colonne) + 56px) !important; }
.n-menu, .n-menu-foot, .n-menu-group {
  padding-inline: max(24px, calc((100% - var(--pi-colonne)) / 2)) !important;
}

/* ---------- 14.4 Un seul texte restait sous le seuil AA ----------
   ⚠️ « Visibilité Pro » : or profond #8a6a2a sur la carte ivoire, corps 10,6 px,
   rapport mesuré 4,20:1 (seuil 4,5:1). On assombrit l'or des étiquettes posées
   sur une carte, sans toucher à l'or des grands aplats (la charte le réserve aux
   gros chiffres et aux traits). */
.n-plan__nom, .n-preuve__corps b { color: #74581f; }

/* ============================================================
   15. LE DÉCOR NE DOIT PAS PASSER DEVANT LES CHIFFRES (2026-10-13)

   ⚠️ CONSTAT. Sur une page de prix (`/prix/<métier>/<département>`), le décor de la
   nuée se lit comme des RECTANGLES PÂLES posés derrière le titre et la grille de
   tarifs : des blocs gris à bords droits, qui donnent l'impression d'une page
   inachevée. Sur l'accueil, les cartes flottantes sont dans une scène plein écran,
   elles se lisent comme un décor ; ici, l'écran est court (577 px), le contenu est
   dense et commence tout en haut, donc les cartes tombent DERRIÈRE des chiffres.

   ⚠️ CE QU'ON NE FAIT PAS : poser un calque pardessus pour baisser le contraste.
   Un calque plein écran en plus du canvas fait disparaître les images de la page
   (bug des exemples blancs, commit 86534c4). On baisse l'opacité DU CANVAS, ce qui
   éclaircit aussi son voile de lisibilité — et comme le voile est peint DANS le
   canvas, le texte gagne en contraste au lieu d'en perdre.

   ⚠️ `:has()` plutôt qu'une classe de page : le canvas est posé par le script à la
   racine du document, il n'est donc pas un descendant de l'écran. Sans `:has()`, il
   faudrait modifier chaque gabarit. Navigateurs anciens : le décor garde sa pleine
   opacité, rien ne casse. */
body:has(.n-screen--prix) #nuee-fond,
body:has(.n-screen--serre) #nuee-fond { opacity: .42; }

/* ============================================================
   16. L'ACCROCHE ET LE VÉRIFICATEUR — ACCUEIL, EN MODE PC (2026-10-13)

   ⚠️ CONSTAT DU CLIENT : « en mode PC, le site fait très vite ». Mesure : à
   1440 px, le titre plafonnait à 68 px, la phrase d'accroche n'existait pas, et
   l'écran enchaînait sur une grille d'exemples — rien n'arrêtait l'œil, tout
   défilait. Sur une page qui vend de la visibilité, l'écran doit poser un
   constat, une promesse, une preuve vérifiable, puis une action. Dans cet ordre.
   ============================================================ */

/* ---------- 16.1 Le titre et l'accroche, plus haut en mode PC ---------- */
@media (min-width: 900px) {
  .n-screen--accueil .n-title {
    font-size: clamp(3rem, 5.4vw, 5.4rem) !important;   /* 78 px en 1440, 86 px en 1920 */
    line-height: .98 !important;
    max-width: 22ch;
  }
}
.n-hook {
  font-family: 'Archivo', Arial, sans-serif; font-weight: 600;
  font-size: clamp(1.1rem, 1.6vw, 1.6rem); line-height: 1.25;
  color: var(--pi-or-profond); margin: 6mm 0 0; max-width: 34ch;
  /* ⚠️ Pas d'emoji, pas de flèche, pas de gras criard : la phrase est la seule
     chose en gras or de l'écran, c'est ce qui la fait lire. */
}
.n-hook b { font-weight: 700; color: var(--pi-encre); }

/* ---------- 16.2 Le vérificateur de visibilité ---------- */
.n-verif {
  border: .7pt solid var(--pi-filet); border-top: 2pt solid var(--pi-or);
  padding: 5mm 6mm 4.5mm; margin: 8mm 0 0; max-width: 100%;
}
.n-verif__titre {
  font-family: 'Archivo', Arial, sans-serif; font-weight: 700; font-size: 1.02rem;
  margin: 0 0 2mm; color: var(--pi-encre);
}
.n-verif__note { font-size: .84rem; color: var(--pi-muted); margin: 0 0 4mm; max-width: 76ch; }
.n-verif__note b { color: var(--pi-encre); font-weight: 700; }
.n-verif__form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 4mm 6mm;
}
.n-verif__champ { display: flex; flex-direction: column; gap: 1.6mm; min-width: 200px; }
.n-verif__champ > span {
  font-family: 'PlexMono', ui-monospace, monospace; font-size: .62rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--pi-muted);
}
.n-verif__champ select {
  appearance: none; -webkit-appearance: none;
  font-family: 'Archivo', Arial, sans-serif; font-size: .9rem; color: var(--pi-encre);
  background: transparent; border: 0; border-bottom: 1pt solid var(--pi-encre);
  border-radius: 0; padding: 2mm 6mm 2mm 0; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--pi-encre) 50%),
                    linear-gradient(135deg, var(--pi-encre) 50%, transparent 50%);
  background-position: right 3mm center, right 1.4mm center;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.n-verif__champ select:focus-visible { outline: 2px solid var(--pi-or); outline-offset: 2px; }
.n-verif__bas { font-size: .74rem; color: var(--pi-muted); margin: 3.5mm 0 0; }

/* Le bouton encre : la deuxième action de l'écran, distincte du bouton or. */
.n-btn--encre {
  background: var(--pi-encre); color: #f7f4ee; border-color: var(--pi-encre);
}
.n-btn--encre:hover { background: #2b2620; border-color: #2b2620; }

@media (max-width: 700px) {
  .n-verif { padding: 4mm 4.5mm; }
  .n-verif__form { gap: 3mm; }
  .n-verif__champ { min-width: 100%; }
  .n-btn--encre { width: 100%; justify-content: center; }
}

/* ---------- 16.3 En mode PC, l'écran se compose en deux colonnes ----------
   ⚠️ MESURE À 1920 px : le titre et l'accroche n'occupaient que le tiers gauche de
   l'écran, le reste était vide. Sur une page qui vend, la moitié droite est la place
   naturelle de la preuve : le vérificateur y monte, à hauteur du titre, sans qu'on
   ait à défiler. Les exemples et la barre de chiffres restent en pleine largeur. */
@media (min-width: 1180px) {
  .n-screen--accueil {
    display: grid !important;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
    column-gap: 14mm; row-gap: 0;
    /* ⚠️⚠️ MESURÉ : la boîte restait hauteur 100svh alors que le contenu en demande
       1128 px. Avec `align-content: center`, le débordement part DES DEUX CÔTÉS : le
       sur-titre se retrouvait à y=28, c'est-à-dire DERRIÈRE la barre de 63 px —
       invisible. On rend donc la hauteur élastique et on colle le contenu en haut,
       sous la barre. Le défilement redevient normal, rien n'est coupé. */
    height: auto !important;
    min-height: 100svh;
    align-content: start;
    padding-top: 104px !important;
  }
  .n-screen--accueil > .n-kicker,
  .n-screen--accueil > .n-title,
  .n-screen--accueil > .n-hook,
  .n-screen--accueil > .n-sub,
  .n-screen--accueil > .n-cta { grid-column: 1; }
  .n-screen--accueil > .n-verif {
    grid-column: 2; grid-row: 1 / span 6; align-self: center; margin-top: 0;
  }
  .n-screen--accueil > .n-preuves,
  .n-screen--accueil > .n-facts { grid-column: 1 / -1; }
  .n-screen--accueil > .n-preuves { margin-top: 10mm; }
}

/* ---------- 16.4 L'accueil respire plus large que les pages de contenu ----------
   ⚠️ La colonne unique de 1120 px vaut pour les pages de texte (prix, blog, CGV).
   Sur l'accueil en 1920 px, elle laissait 400 px de vide de chaque côté : une page
   de vente qui n'occupe que le centre de l'écran ne vend pas. On élargit L'ACCUEIL
   SEUL à 1400 px, et seulement au-delà de 1180 px. Les paragraphes gardent leur
   propre largeur de lecture (max-width en ch) : la colonne élargie ne rallonge
   aucune ligne de texte. */
@media (min-width: 1180px) {
  .n-screen--accueil {
    padding-inline: max(var(--n-pad, 56px), calc((100% - 1400px) / 2)) !important;
  }
  .n-screen--accueil .n-sub { max-width: 52ch; }
}

/* ===== fin passe-interface.css ===== */
