/* ==========================================================================
   ESPACE CLIENT · https://odratta.fr/espace/ (servi par le VPS)

   Feuille autonome : l'espace est du PHP rendu côté serveur, Tailwind
   n'est pas là. Refonte du 05/09/2026 : le design de Numeri (blanc,
   Poppins, pilules noires), transposé de mon-hebergement/src/index.css
   sélecteur par sélecteur. index.php et _devis.php appellent chacune de
   ces classes : aucune n'est retirée, renommée ni déplacée. Les jetons
   --o-* sont recopiés du bloc 02 d'index.css : les deux feuilles doivent
   dire la même chose.

   ⚠️ AUCUN attribut style="" ni bloc <style> ailleurs : la CSP vaut
   `style-src 'self'` sans 'unsafe-inline'. Toute règle en ligne serait
   ignorée, la page s'afficherait cassée, et seule la console du
   navigateur le dirait.

   ⚠️ CACHE : le serveur met un an sur le CSS, ce qui ne vaut que pour un
   fichier empreinté par un build. Celui-ci ne l'est pas : à chaque
   modification, INCRÉMENTER le ?v= dans mh_head() (index.php).

   ⚠️ BLANC SEULEMENT : aucun prefers-color-scheme. Ce que mh_head() doit
   dire avec cette feuille : color-scheme light, theme-color #FAFAFA, et
   le logo en encre (l'image vient du PHP, la règle .mh-brand img ne fixe
   que la hauteur, 32 px).
   ⚠️ Polices auto-hébergées (CNIL) : jamais de Google Fonts en CDN. Les
   trois woff2 doivent exister sous /assets/fonts/ sur CE domaine, sinon
   la page tombe sans bruit sur « Poppins secours » (Helvetica / Arial).

   Trois @media sont IMBRIQUÉS dans leur règle (CSS Nesting, tous les
   navigateurs depuis fin 2023) : la réduction de mouvement dans :root, la
   hauteur de bureau dans .mh-btn et .mh-lien-bouton. C'est pour ne pas
   répéter un sélecteur : la liste des sélecteurs est celle de la feuille
   d'origine, dans le même ordre. Un vieux moteur ignore le bloc imbriqué
   et rien ne casse (48 px au lieu de 44, une transition de 180 ms).

   Sommaire
     01  Polices
     02  Jetons
     03  Base
     04  En-tête et navigation
     05  Corps, titres
     06  Cartes, montant, listes, faits
     07  Pastille d'état
     08  Formulaires et boutons
     09  Messages
     10  Demandes
     11  Pied
     12  Voie « Mon site par Odratta »
   ========================================================================== */

/* == 01 · POLICES ==========================================================
   Poppins 400 / 500 / 600, latin (SIL OFL), dans /assets/fonts/. Les
   mêmes fichiers et les mêmes déclarations que le site. Plus aucune
   Bricolage, Hanken ni JetBrains : le code (chemins, identifiants) reste
   en monospace SYSTÈME, qui ne charge rien.
   ========================================================================== */
@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/assets/fonts/poppins-400-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: 'Poppins'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/assets/fonts/poppins-500-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: 'Poppins'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/assets/fonts/poppins-600-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; }
/* Secours calé sur les métriques de Poppins : pendant le swap la ligne a
   déjà la bonne largeur, rien ne saute (CLS 0). */
@font-face {
  font-family: 'Poppins secours';
  src: local('Helvetica Neue'), local('Arial'), local('Segoe UI'), local('Roboto');
  size-adjust: 112%; ascent-override: 93.75%; descent-override: 31.25%; line-gap-override: 0%;
}

/* == 02 · JETONS ===========================================================
   Copie du bloc 02 de src/index.css. Chaque encre porte son contraste
   mesuré sur #FAFAFA. Seules les deux rampes de dégradé (--o-grad,
   --o-grad-soft) ne sont pas recopiées : le mot en dégradé du h1
   d'accueil n'a pas de place dans l'espace client, et rien ici ne doit
   pouvoir en poser un.
   ========================================================================== */
:root {
  color-scheme: light;

  --o-bg: #fafafa;
  --o-surface: #ffffff;
  --o-surface-2: #f2f2f3;
  --o-surface-3: #e9e9eb;
  --o-ink: #000000;
  --o-well: #050505;
  --o-veil: rgba(250, 250, 250, 0.88);

  --o-text: #111113; /* 18,6:1 */
  --o-text-2: #55555b; /* 7,2:1 */
  --o-text-3: #6b6b72; /* 5,1:1 */
  --o-text-disabled: #a6a6ac;
  --o-text-inverse: #ffffff;
  --o-text-inverse-2: rgba(255, 255, 255, 0.72);

  --o-accent: #5f55c9; /* 5,6:1 : liens, focus, coché */
  --o-accent-hi: #4c43b4; /* 7,5:1 */
  --o-accent-soft: rgba(95, 85, 201, 0.1);

  --o-ok: #167a4b; --o-ok-soft: rgba(22, 122, 75, 0.1);
  --o-warn: #8a5a00; --o-warn-soft: rgba(138, 90, 0, 0.1);
  --o-danger: #c0203c; --o-danger-soft: rgba(192, 32, 60, 0.09);
  --o-info: #2f5fc4; --o-info-soft: rgba(47, 95, 196, 0.09);

  --o-line: rgba(0, 0, 0, 0.08);
  --o-line-2: rgba(0, 0, 0, 0.14);
  --o-line-strong: #767680; /* 3,2:1 */
  --o-line-inverse: rgba(255, 255, 255, 0.16);

  --o-focus: #5f55c9;

  --o-r-sm: 8px; --o-r-md: 12px; --o-r-lg: 16px; --o-r-xl: 24px; --o-r-2xl: 32px; --o-r-pill: 999px;

  --o-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.05);
  --o-shadow-2: 0 8px 24px -12px rgba(0, 0, 0, 0.18);
  --o-shadow-3: 0 24px 64px -28px rgba(0, 0, 0, 0.3);

  --o-dur-1: 120ms; --o-dur-2: 180ms; --o-dur-3: 280ms; --o-dur-4: 480ms;
  --o-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --o-ease-io: cubic-bezier(0.65, 0, 0.35, 1);

  --o-sp-1: 4px; --o-sp-2: 8px; --o-sp-3: 12px; --o-sp-4: 16px; --o-sp-5: 24px;
  --o-sp-6: 32px; --o-sp-7: 48px; --o-sp-8: 64px; --o-sp-9: 96px; --o-sp-10: 128px;
  --o-sp-section: clamp(4rem, 2.5rem + 6vw, 8rem); /* 64 → 128 */
  --o-sp-block: clamp(2.5rem, 1.6rem + 3.6vw, 4rem); /* 40 → 64 : entre un titre et son contenu */
  --o-sp-gutter: clamp(1.25rem, 0.5rem + 3.6vw, 2.5rem); /* 20 → 40 */

  --o-fs-display: clamp(2.5rem, 1.55rem + 4.2vw, 4.75rem); /* 40 → 76 */
  --o-fs-h1: clamp(2rem, 1.35rem + 2.9vw, 3.5rem); /* 32 → 56 */
  --o-fs-h2: clamp(1.625rem, 1.2rem + 1.9vw, 2.625rem); /* 26 → 42 */
  --o-fs-h3: clamp(1.25rem, 1.1rem + 0.65vw, 1.5rem); /* 20 → 24 */
  --o-fs-h4: 1.0625rem; /* 17 */
  --o-fs-lead: clamp(1.0625rem, 1rem + 0.45vw, 1.25rem); /* 17 → 20 */
  --o-fs-body: 1rem; /* 16, jamais moins sur téléphone */
  --o-fs-sm: 0.875rem; /* 14 */
  --o-fs-xs: 0.8125rem; /* 13 */
  --o-fs-eyebrow: 0.75rem; /* 12 */
  --o-fs-kpi: clamp(2rem, 1.5rem + 2.2vw, 3rem); /* 32 → 48 */

  --o-container: 1200px;
  --o-measure: 62ch;
  --nav-h: 64px;

  /* Rien ne bouge ici hormis des couleurs qui glissent en 180 ms. Sous
     prefers-reduced-motion, la durée tombe à zéro pour toutes : chaque
     transition de la feuille lit --o-dur-2. */
  @media (prefers-reduced-motion: reduce) {
    --o-dur-2: 0.01ms;
  }
}

/* == 03 · BASE ============================================================= */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Le filet d'ancrage du lien d'évitement (#contenu) tient compte de la
   barre collante : sans scroll-padding, la cible passerait dessous. */
html {
  -webkit-text-size-adjust: 100%;
  max-width: 100%;
  overflow-x: clip;
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  margin: 0;
  max-width: 100%;
  overflow-x: clip;
  background: var(--o-bg);
  color: var(--o-text);
  font-family: 'Poppins', 'Poppins secours', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-weight: 400;
  font-size: var(--o-fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Le lien courant : encre, souligné fin, l'accent au survol seulement.
   Les liens qui ont leur propre dessin (marque, onglets, pilules, pied)
   le redisent plus bas. */
a {
  color: var(--o-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--o-line-2);
  transition: color var(--o-dur-2) var(--o-ease), text-decoration-color var(--o-dur-2) var(--o-ease);
}
a:hover {
  color: var(--o-accent-hi);
  text-decoration-color: currentColor;
}

/* Le focus clavier : l'anneau violet du système. Aucun border-radius ici :
   l'anneau épouse celui de l'élément (une pilule reste une pilule). */
:focus-visible {
  outline: 2px solid var(--o-focus);
  outline-offset: 2px;
}

/* Lien d'évitement : hors écran, une pilule noire dès qu'il prend le focus. */
.mh-evitement {
  position: absolute;
  left: -9999px;
}
.mh-evitement:focus {
  left: 16px;
  top: 16px;
  z-index: 100;
  background: var(--o-ink);
  color: #fff;
  padding: 12px 24px;
  border-radius: 999px;
  font-size: var(--o-fs-sm);
  font-weight: 500;
  text-decoration: none;
}

.mh-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* L'enveloppe est pleine largeur : la barre du haut et le pied portent
   leur filet d'un bord à l'autre de l'écran, comme sur Numeri. La colonne
   de 760 px se retrouve dans la gouttière calculée ici, posée par chaque
   bande (en-tête, navigation, corps, pied) : au-delà de 760 px la marge
   grandit avec l'écran, en dessous c'est la gouttière du système. Le %
   se mesure sur l'enveloppe, donc sans l'ascenseur : la colonne est
   exacte au pixel. */
.mh-wrap {
  --mh-gouttiere: max(var(--o-sp-gutter), calc(50% - 380px + var(--o-sp-gutter)));
  margin: 0 auto;
  width: 100%;
  padding: 0 0 var(--o-sp-8);
}

/* == 04 · EN-TÊTE ET NAVIGATION ============================================
   La barre de Numeri : 64 px, collante, un voile blanc flouté, un filet
   dessous. La marque en encre à gauche, la sortie en pilule à droite.
   ========================================================================== */
.mh-top {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--nav-h);
  padding: 0 var(--mh-gouttiere);
  background: var(--o-veil);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--o-line);
}
.mh-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  min-width: 0;
  text-decoration: none;
  color: var(--o-ink);
}
/* Le logo en encre vient du PHP ; ici seulement sa hauteur. */
.mh-brand img {
  display: block;
  height: 32px;
  width: auto;
}
/* « Espace client » : le surtitre du système, à côté de la marque. Sur un
   écran de 320 px il passe sur deux lignes et tient dans les 64 px. */
.mh-brand span {
  font-size: var(--o-fs-eyebrow);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--o-text-3);
}
/* « Se déconnecter » / « Retour au site » : la pilule secondaire compacte
   (btn-sm), blanche avec un filet. Jamais noire : ce n'est pas l'action
   principale de l'écran. */
.mh-lien-bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--o-line-2);
  border-radius: 999px;
  background: var(--o-surface);
  color: var(--o-ink);
  font: inherit;
  font-size: var(--o-fs-sm);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color var(--o-dur-2) var(--o-ease), border-color var(--o-dur-2) var(--o-ease), color var(--o-dur-2) var(--o-ease);

  @media (min-width: 720px) and (hover: hover) and (pointer: fine) {
    min-height: 40px;
  }
}
@media (hover: hover) {
  .mh-lien-bouton:hover {
    background: var(--o-surface-2);
    border-color: var(--o-line-2);
    color: var(--o-ink);
  }
}
.mh-top form {
  margin: 0;
}

/* Les sections de l'espace : des pilules, comme les entrées de la barre
   de Numeri. L'entrée courante se lit à la forme (un cerne d'encre), pas
   seulement à la couleur. Plus de filet sous la rangée : le blanc et
   l'espace séparent. */
.mh-nav {
  padding: 8px var(--mh-gouttiere) 0;
}
/* Le -12px rend le rembourrage de la première pilule : son texte s'aligne
   sur la colonne. La gouttière (20 px et plus) absorbe le débord. */
.mh-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 -12px;
  padding: 0;
  list-style: none;
}
.mh-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 999px;
  font-size: var(--o-fs-sm);
  font-weight: 500;
  color: var(--o-text-2);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--o-dur-2) var(--o-ease), background-color var(--o-dur-2) var(--o-ease);
}
@media (hover: hover) {
  .mh-nav a:hover {
    color: var(--o-ink);
    background: var(--o-surface-2);
  }
}
.mh-nav a[aria-current='page'] {
  color: var(--o-ink);
  background: var(--o-surface);
  box-shadow: inset 0 0 0 1.5px var(--o-ink);
}

/* == 05 · CORPS, TITRES ==================================================== */
.mh-main {
  padding: 40px var(--mh-gouttiere) 0;
}
/* Le surtitre : 12 px, capitales, gris. Plus de mono, plus d'accent. */
.mh-kicker {
  margin: 0;
  font-size: var(--o-fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--o-text-3);
}
/* Les titres : encre pleine, graisse 500 (Poppins 500 n'est pas « gras »),
   jamais 600 ni 700. Le h1 d'une page intérieure est le t-h1 du système. */
h1 {
  font-size: var(--o-fs-h1);
  line-height: 1.15;
  letter-spacing: -0.03em;
  font-weight: 500;
  color: var(--o-ink);
  margin: 16px 0 0;
  text-wrap: balance;
  font-synthesis-weight: none;
}
/* Le titre d'une carte : le t-h3. */
h2 {
  font-size: var(--o-fs-h3);
  line-height: 1.25;
  letter-spacing: -0.01em;
  font-weight: 500;
  color: var(--o-ink);
  margin: 0 0 16px;
  text-wrap: balance;
  font-synthesis-weight: none;
}
.mh-lead {
  color: var(--o-text-2);
  font-size: var(--o-fs-lead);
  line-height: 1.55;
  margin: 20px 0 0;
  max-width: 52ch;
  text-wrap: pretty;
}
.mh-aide {
  color: var(--o-text-2);
  font-size: var(--o-fs-sm);
  line-height: 1.55;
  margin: 16px 0 0;
  max-width: 60ch;
}
/* « Ce qui est compris » : un surtitre dans la carte. Le padding s'ajoute
   aux 12 px que .mh-carte p impose à tout paragraphe de carte : 24 px
   d'air au total. */
.mh-sous {
  font-size: var(--o-fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--o-text-3);
  margin: 12px 0 0;
  padding-top: 12px;
}
.mh-fac {
  color: var(--o-text-3);
  font-weight: 400;
}

/* == 06 · CARTES, MONTANT, LISTES, FAITS ===================================
   Une carte : surface blanche, filet d'un pixel, rayon 24, 24 px de
   rembourrage, aucune ombre. Jamais une carte dans une carte.
   ========================================================================== */
.mh-carte {
  margin-top: 24px;
  border: 1px solid var(--o-line);
  border-radius: 24px;
  background: var(--o-surface);
  padding: 24px;
}
.mh-carte p {
  margin: 12px 0 0;
  max-width: var(--o-measure);
}
.mh-carte p:first-of-type {
  margin-top: 0;
}

/* Le prix : le chiffre qui compte (t-kpi), en encre, chiffres tabulaires. */
.mh-montant {
  font-size: var(--o-fs-kpi);
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 500;
  color: var(--o-ink);
  font-variant-numeric: tabular-nums;
  text-wrap: balance;
  margin: 0;
}
/* « soit … € TTC » : une petite ligne calme, plus de capitales. */
.mh-montant__ttc {
  display: block;
  font-size: var(--o-fs-sm);
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
  color: var(--o-text-2);
  margin-top: 8px;
}

.mh-liste {
  margin: 12px 0 0;
  padding-left: 1.2em;
  color: var(--o-text);
  line-height: 1.6;
}
.mh-liste li {
  margin-bottom: 4px;
}
/* Les adresses e-mail : une par ligne, à filets. Une adresse longue se
   coupe plutôt que de déborder de la carte sur téléphone. */
.mh-liste--mail {
  list-style: none;
  padding-left: 0;
  font-size: var(--o-fs-body);
  overflow-wrap: anywhere;
}
.mh-liste--mail li {
  margin-bottom: 0;
  padding: 10px 0;
  border-bottom: 1px solid var(--o-line);
}
.mh-liste--mail li:last-child {
  border-bottom: 0;
}

/* Les faits clé → valeur : deux colonnes à filets, lisibles en 320 px. */
.mh-dl {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(140px, 12em) 1fr;
  gap: 0 20px;
  border-top: 1px solid var(--o-line);
}
.mh-dl dt {
  padding: 12px 0;
  font-size: var(--o-fs-sm);
  color: var(--o-text-3);
  border-bottom: 1px solid var(--o-line);
}
.mh-dl dd {
  margin: 0;
  padding: 12px 0;
  font-size: var(--o-fs-body);
  color: var(--o-ink);
  font-weight: 500;
  border-bottom: 1px solid var(--o-line);
  overflow-wrap: anywhere;
}
@media (max-width: 560px) {
  .mh-dl {
    grid-template-columns: 1fr;
  }
  .mh-dl dt {
    padding-bottom: 0;
    border-bottom: 0;
  }
  .mh-dl dd {
    padding-top: 2px;
  }
}

/* == 07 · PASTILLE D'ÉTAT ==================================================
   Un point de 8 px devant la phrase d'état. Les encres d'état du système,
   jamais un vert d'identité : ok pour « en ligne », warn pour « il manque
   quelque chose », danger pour « suspendu / arrêté », gris pour le reste.
   ========================================================================== */
.mh-pastille {
  display: inline-block;
  position: relative;
  top: -1px;
  height: 8px;
  width: 8px;
  border-radius: 999px;
  background: var(--o-text-3);
  vertical-align: middle;
  margin-right: 6px;
}
.mh-pastille--verte {
  background: var(--o-ok);
}
.mh-pastille--orange {
  background: var(--o-warn);
}
.mh-pastille--rouge {
  background: var(--o-danger);
}
.mh-pastille--neutre {
  background: var(--o-text-3);
}
.mh-etat {
  font-size: var(--o-fs-body);
  color: var(--o-text);
}

/* == 08 · FORMULAIRES ET BOUTONS ===========================================
   Un libellé visible au-dessus, un champ blanc de 48 px, un seul rayon
   (12), 16 px pour qu'iOS ne zoome pas. Le focus : bordure encre et un
   halo violet de 3 px.
   ========================================================================== */
.mh-form {
  margin-top: 8px;
}
.mh-label {
  display: block;
  margin: 16px 0 8px;
  font-size: var(--o-fs-sm);
  font-weight: 500;
  color: var(--o-ink);
}
.mh-input {
  display: block;
  width: 100%;
  min-height: 48px;
  border: 1px solid var(--o-line-2);
  border-radius: 12px;
  background: var(--o-surface);
  color: var(--o-text);
  font: inherit;
  font-size: var(--o-fs-body);
  line-height: 1.4;
  padding: 12px 16px;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--o-dur-2) var(--o-ease), box-shadow var(--o-dur-2) var(--o-ease);
}
.mh-input:focus {
  border-color: var(--o-ink);
  box-shadow: 0 0 0 3px var(--o-accent-soft);
  outline: none;
}
.mh-textarea {
  resize: vertical;
  min-height: 128px;
}
/* Le code d'accès : centré, grand, espacé, chiffres tabulaires. Le
   text-indent rend l'espace que letter-spacing laisse après le dernier
   caractère : le code est centré à l'œil. Le rembourrage est resserré
   pour que « XXXX-XXXX » tienne dans 280 px (un écran de 320). */
.mh-input--code {
  font-size: 1.75rem;
  letter-spacing: 0.35em;
  text-indent: 0.35em;
  text-align: center;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  padding: 12px 8px;
  max-width: 20ch;
}
.mh-form--code {
  margin-top: 24px;
}

/* Le bouton : une pilule, 48 px au doigt, 44 sur bureau. Le survol
   change la COULEUR, jamais la taille. Le secondaire (celui-ci) est blanc
   avec un filet ; le principal, plus bas, est NOIR. Un seul noir par
   écran. */
.mh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 16px;
  min-height: 48px;
  padding: 0 24px;
  border: 1px solid var(--o-line-2);
  border-radius: 999px;
  background: var(--o-surface);
  color: var(--o-ink);
  font: inherit;
  font-size: var(--o-fs-body);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0;
  text-align: center;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color var(--o-dur-2) var(--o-ease), border-color var(--o-dur-2) var(--o-ease),
    color var(--o-dur-2) var(--o-ease), box-shadow var(--o-dur-2) var(--o-ease);

  @media (min-width: 720px) and (hover: hover) and (pointer: fine) {
    min-height: 44px;
  }
}
@media (hover: hover) {
  .mh-btn:hover {
    border-color: var(--o-line-2);
    background: var(--o-surface-2);
    color: var(--o-ink);
  }
}
/* Le principal : noir, texte blanc, une ombre grise courte. Jamais un
   dégradé, jamais du bleu. */
.mh-btn--primaire {
  background: var(--o-ink);
  border-color: var(--o-ink);
  color: #fff;
  box-shadow: 0 6px 20px -10px rgba(0, 0, 0, 0.45);
}
@media (hover: hover) {
  .mh-btn--primaire:hover {
    background: #222226;
    border-color: #222226;
    color: #fff;
    box-shadow: 0 10px 26px -10px rgba(0, 0, 0, 0.5);
  }
}
/* WhatsApp : le vert disparaît, un bouton n'est jamais vert. C'est le
   secondaire blanc, redit ici pour que la classe garde un sens et que le
   PHP n'ait rien à changer. */
.mh-btn--wa {
  background: var(--o-surface);
  border-color: var(--o-line-2);
  color: var(--o-ink);
  font-weight: 500;
}
@media (hover: hover) {
  .mh-btn--wa:hover {
    background: var(--o-surface-2);
    border-color: var(--o-line-2);
    color: var(--o-ink);
  }
}

/* == 09 · MESSAGES =========================================================
   Une note : fond teinté, rayon 16, aucun filet coloré. Le rouge du
   système pour un refus, le vert d'état pour une bonne nouvelle.
   ========================================================================== */
.mh-erreur,
.mh-info {
  margin: 16px 0 24px;
  border-radius: 16px;
  padding: 16px 24px;
  font-size: var(--o-fs-sm);
  font-weight: 500;
  line-height: 1.5;
  max-width: var(--o-measure);
}
.mh-erreur {
  background: var(--o-danger-soft);
  color: var(--o-danger);
}
.mh-info {
  background: var(--o-ok-soft);
  color: var(--o-ok);
}

/* == 10 · DEMANDES =========================================================
   Une demande par ligne à filets, l'étiquette d'état en pastille, les
   messages en fil avec un trait à gauche (encre quand c'est nous).
   ========================================================================== */
.mh-demande {
  border-top: 1px solid var(--o-line);
  padding: 4px 0;
}
.mh-demande:first-of-type {
  border-top: 0;
}
.mh-demande summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 48px;
  padding: 12px 0;
  cursor: pointer;
  list-style: none;
  color: var(--o-ink);
}
.mh-demande summary::-webkit-details-marker {
  display: none;
}
.mh-demande__sujet {
  font-weight: 500;
  font-size: var(--o-fs-body);
  color: var(--o-ink);
}
/* L'étiquette : la pastille grise du système (badge), 13 px, plus de
   capitales ni de mono. */
.mh-tag {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: var(--o-surface-2);
  color: var(--o-text-2);
  font-size: var(--o-fs-xs);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}
/* Ouverte : on vous doit une réponse (warn). En cours / répondu : l'encre
   d'information du système, la seule teinte qui n'est ni un verdict ni
   une alerte. Traitée : ok. */
.mh-tag--ouverte {
  background: var(--o-warn-soft);
  color: var(--o-warn);
}
.mh-tag--en_cours {
  background: var(--o-info-soft);
  color: var(--o-info);
}
.mh-tag--traitee {
  background: var(--o-ok-soft);
  color: var(--o-ok);
}

.mh-msg {
  border-left: 2px solid var(--o-line-2);
  padding: 2px 0 2px 16px;
  margin: 12px 0 0;
}
.mh-msg--nous {
  border-left-color: var(--o-ink);
}
.mh-msg__qui {
  margin: 0;
  font-size: var(--o-fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--o-text-3);
}
.mh-msg__texte {
  margin: 6px 0 0;
  font-size: var(--o-fs-body);
  color: var(--o-text);
}
.mh-form--reponse {
  margin-top: 16px;
  padding-bottom: 8px;
}

/* == 11 · PIED =============================================================
   Un filet, une ligne de 14 px en gris. Les liens sont soulignés fin : dans
   une phrase, la couleur seule ne les distingue pas du texte (WCAG 1.4.1).
   ========================================================================== */
.mh-foot {
  margin-top: var(--o-sp-8);
  border-top: 1px solid var(--o-line);
  padding: 32px var(--mh-gouttiere) 0;
  font-size: var(--o-fs-sm);
  line-height: 1.7;
  color: var(--o-text-3);
}
.mh-foot p {
  margin: 0;
  max-width: 70ch;
}
.mh-foot a {
  color: var(--o-text-2);
  white-space: nowrap;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--o-line-2);
}
@media (hover: hover) {
  .mh-foot a:hover {
    color: var(--o-ink);
    text-decoration-color: currentColor;
  }
}

/* == 12 · VOIE « MON SITE PAR ODRATTA » (24/08/2026) =======================
   Les écrans d'un client venu d'un devis réutilisent tout ce qui
   précède (cartes, listes de définitions, demandes, étiquettes).
   Ne restaient que la frise des jalons et la ligne à trois zones.
   ========================================================================== */

/* Frise d'avancement. Aucun pourcentage en ligne : la CSP interdit
   style="width:60%", et l'état est un JALON, pas une proportion.
   Fait : le point vert d'état. En cours : encre, en 500. À venir : gris. */
.mh-jalons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  font-size: var(--o-fs-sm);
  color: var(--o-text-3);
}
.mh-jalons li {
  position: relative;
  padding-left: 18px;
}
.mh-jalons li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  height: 8px;
  width: 8px;
  border-radius: 999px;
  background: var(--o-line-2);
}
.mh-jalons li.fait {
  color: var(--o-text-2);
}
.mh-jalons li.fait::before {
  background: var(--o-ok);
}
.mh-jalons li.cours {
  color: var(--o-ink);
  font-weight: 500;
}
.mh-jalons li.cours::before {
  background: var(--o-ink);
}

/* Ligne « libellé · montant · lien » : factures et documents. Le montant
   en encre, chiffres tabulaires ; la date et l'état en petit, en gris. */
.mh-ligne {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 4px 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--o-line);
  font-size: var(--o-fs-body);
}
.mh-ligne:first-of-type {
  border-top: 1px solid var(--o-line);
}
.mh-ligne__lib {
  color: var(--o-text);
}
.mh-ligne__lib em {
  font-style: normal;
  font-size: var(--o-fs-sm);
  color: var(--o-text-2);
}
.mh-ligne__val {
  font-size: var(--o-fs-body);
  font-weight: 500;
  color: var(--o-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mh-carte .mh-ligne + p {
  margin-top: 16px;
}

/* Une bonne nouvelle : règlement en place, facture réglée. Le vert d'état,
   jamais un vert d'identité. */
.mh-bon,
em.mh-bon {
  color: var(--o-ok);
  font-weight: 500;
}
