/* ==========================================================================
   Bi Cloud — feuille de styles principale
   --------------------------------------------------------------------------
   Fondations : jetons de design, typographie, composants, états.
   Aucun script n'est requis pour lire le contenu ; le JavaScript n'ajoute que
   le menu à tiroir, la barre d'action collante et les apparitions au défilement.

   SOMMAIRE
     1.  Jetons — thème clair (:root nu)
     2.  Jetons — thème sombre (les deux blocs)
     3.  Réinitialisation et éléments de base
     4.  Utilitaires de mise en page
     5.  En-tête, marque, logo, navigation
     6.  Boutons et états
     7.  Bandes, héros, fil d'Ariane, corps de page
     8.  Contenu rédactionnel
     9.  Barre latérale
     10. Cartes, grilles, chiffres, bandeau de confiance
     11. FAQ, listes, glossaire
     12. Conversion : bloc CTA et barre collante mobile
     13. Formulaires
     14. Encarts, marqueurs, décor hexagonal
     15. Pied de page
     16. Animations d'apparition
     17. Réactif
     18. Impression
     19. Compatibilité (jetons hérités)

   RÈGLE D'OR — le vert (--cta) ne sert QU'aux appels à l'action : bouton de
   prise de rendez-vous, envoi de formulaire, bouton du diagnostic. Jamais un
   titre, un filet, une icône ou une carte. Le bleu porte l'identité (liens,
   symboles, structure), l'ardoise porte les aplats sombres, le reste est neutre.

   CONTRASTE — --ink-3 n'est validé AA que sur --bg et --surface. Sur
   --surface-2 et --surface-3, utiliser --ink-2.
   ========================================================================== */


/* =========================================================== 1. Jetons — clair
   Palette validée WCAG AA. Ne pas modifier sans revalider les contrastes.
   Toute couleur du fichier passe par ces variables : aucun littéral ailleurs.
   ========================================================================== */
:root{
  color-scheme:light;

  /* — fonds et surfaces — */
  --bg:#F7F9FA;
  --surface:#FFFFFF;
  --surface-2:#EDF2F5;
  --surface-3:#DFE8ED;

  /* — textes — */
  --ink:#16242E;
  --ink-2:#40586A;
  --ink-3:#5E7686;

  /* — filets — */
  --rule:#DCE5EA;
  --rule-strong:#B9C9D2;

  /* — marque, bleu : aplats, liens, symboles, structure — */
  --brand:#008FBA;        /* aplats et symboles, filets d'accent */
  --brand-ink:#00718F;    /* texte et liens sur fond clair */
  --brand-deep:#2F4858;   /* ardoise, bandeaux pleins */
  --brand-soft:#E1F1F7;   /* fond teinté discret */

  /* — action, vert : RÉSERVÉ aux appels à l'action — */
  --cta:#7BB928;
  --cta-hover:#6DA71F;
  --cta-ink:#12240A;
  --cta-soft:#EEF7E2;

  /* — sémantique — */
  --ok:#1C6640;    --ok-soft:#E0EFE6;
  --warn:#9A5B08;  --warn-soft:#F8EBD8;
  --alert:#A3231A; --alert-soft:#F8E3E1;

  /* — jetons dérivés —
     --brand sur texte blanc ne donne que 3,7:1 : insuffisant pour un aplat
     porteur de texte. --brand-solid est la déclinaison AA du bouton bleu. */
  --brand-solid:#00718F;
  --brand-solid-hover:#005B74;
  --brand-solid-ink:#FFFFFF;
  --on-deep:#FFFFFF;        /* texte posé sur --brand-deep, identique en sombre */

  /* — bascule des déclinaisons du logo, pilotée par jeton
       (les blocs de thème ne contiennent ainsi que des variables) — */
  --logo-light:block;
  --logo-dark:none;

  /* — ombres : teinte + facteur d'opacité, ajustés par thème — */
  --shadow-rgb:22 36 46;
  --shadow-k:1;
  --shadow-sm:0 1px 2px rgb(var(--shadow-rgb)/calc(.06 * var(--shadow-k)));
  --shadow:0 1px 2px rgb(var(--shadow-rgb)/calc(.05 * var(--shadow-k))),
           0 12px 28px -18px rgb(var(--shadow-rgb)/calc(.34 * var(--shadow-k)));
  --shadow-lg:0 4px 8px rgb(var(--shadow-rgb)/calc(.07 * var(--shadow-k))),
              0 24px 48px -24px rgb(var(--shadow-rgb)/calc(.42 * var(--shadow-k)));

  /* — impression (jamais redéfini par thème : le papier reste blanc) — */
  --paper:#FFFFFF;
  --paper-ink:#101010;

  /* — familles — */
  --f-display:"Sora","Helvetica Neue",Arial,sans-serif;
  --f-body:"Public Sans","Helvetica Neue",Arial,sans-serif;
  --f-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* — échelle typographique (1rem = 17px, voir html) — */
  --t-cap:.72rem;    /* étiquettes mono */
  --t-sm:.82rem;     /* mentions, méta */
  --t-md:.92rem;     /* texte secondaire, navigation */
  --t-base:1rem;     /* texte courant : 17px */
  --t-lg:1.13rem;
  --t-xl:1.3rem;
  --t-2xl:1.6rem;
  --t-3xl:2.05rem;
  --t-hero:clamp(2.05rem,1.35rem + 2.7vw,3.1rem);

  --lh-tight:1.14;   /* grands titres */
  --lh-snug:1.32;    /* titres courants */
  --lh-body:1.65;    /* texte courant */

  --ls-tighter:-.035em;  /* h1 uniquement */
  --ls-tight:-.022em;    /* h2, h3 */
  --ls-cap:.14em;        /* capitales mono */

  /* — espacement : une seule échelle, utilisée partout — */
  --s1:4px;
  --s2:8px;
  --s3:12px;
  --s4:18px;
  --s5:26px;
  --s6:40px;
  --s7:60px;
  --s8:88px;

  /* — rayons — */
  --r-sm:6px;
  --r:10px;
  --r-lg:16px;

  /* — gabarit — */
  --maxw:1180px;
  --prose:68ch;
  --header-h:72px;
  --tap:44px;          /* hauteur minimale d'une zone cliquable */
}


/* ==================================================== 2. Jetons — sombre (×2)
   Les deux blocs sont strictement identiques et ne contiennent QUE des
   variables. Toute variable y figurant est déjà définie sur :root nu.
   ========================================================================== */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;

    --bg:#0D1720;
    --surface:#13212C;
    --surface-2:#1B2C39;
    --surface-3:#253A49;

    --ink:#E8F0F4;
    --ink-2:#AFC3CF;
    --ink-3:#7F97A6;

    --rule:#223543;
    --rule-strong:#34505F;

    --brand:#4FC0E4;
    --brand-ink:#6FD0EE;
    --brand-deep:#0D3444;
    --brand-soft:#0D3444;

    --cta:#8FCF35;
    --cta-hover:#A0DC49;
    --cta-ink:#0B1705;
    --cta-soft:#16300A;

    --ok:#74CE99;    --ok-soft:#12281C;
    --warn:#E3A857;  --warn-soft:#2C2011;
    --alert:#EF9285; --alert-soft:#2E1614;

    --brand-solid:#4FC0E4;
    --brand-solid-hover:#6FD0EE;
    --brand-solid-ink:#06222C;

    --logo-light:none;
    --logo-dark:block;

    --shadow-rgb:0 0 0;
    --shadow-k:2.4;
  }
}

:root[data-theme="dark"]{
  color-scheme:dark;

  --bg:#0D1720;
  --surface:#13212C;
  --surface-2:#1B2C39;
  --surface-3:#253A49;

  --ink:#E8F0F4;
  --ink-2:#AFC3CF;
  --ink-3:#7F97A6;

  --rule:#223543;
  --rule-strong:#34505F;

  --brand:#4FC0E4;
  --brand-ink:#6FD0EE;
  --brand-deep:#0D3444;
  --brand-soft:#0D3444;

  --cta:#8FCF35;
  --cta-hover:#A0DC49;
  --cta-ink:#0B1705;
  --cta-soft:#16300A;

  --ok:#74CE99;    --ok-soft:#12281C;
  --warn:#E3A857;  --warn-soft:#2C2011;
  --alert:#EF9285; --alert-soft:#2E1614;

  --brand-solid:#4FC0E4;
  --brand-solid-hover:#6FD0EE;
  --brand-solid-ink:#06222C;

  --logo-light:none;
  --logo-dark:block;

  --shadow-rgb:0 0 0;
  --shadow-k:2.4;
}


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

html{
  font-size:106.25%;          /* 1rem = 17px, l'échelle suit le réglage du navigateur */
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--header-h) + var(--s4));
}

body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:var(--t-base);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

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

h1,h2,h3,h4,h5,h6{
  font-family:var(--f-display);
  font-weight:600;
  line-height:var(--lh-snug);
  letter-spacing:var(--ls-tight);
  margin:0;
  text-wrap:balance;
}
h1{font-size:var(--t-hero);font-weight:700;line-height:var(--lh-tight);letter-spacing:var(--ls-tighter);}
h2{font-size:var(--t-2xl);}
h3{font-size:var(--t-lg);}
h4,h5,h6{font-size:var(--t-base);}

p,ul,ol,dl,blockquote,table,figure,pre{margin:0;}
p{text-wrap:pretty;}
strong,b{font-weight:600;}
small{font-size:var(--t-sm);}

a{
  color:var(--brand-ink);
  text-underline-offset:3px;
  text-decoration-thickness:1px;
  transition:color .15s ease,text-decoration-color .15s ease;
}
a:hover{color:var(--brand);}
a:active{text-decoration-thickness:2px;}   /* lisible dans les deux thèmes */

/* Focus visible unique et systématique : 2px --brand, décalé de 3px.
   L'outline épouse déjà le rayon de l'élément : ne rien forcer ici. */
:focus-visible{outline:2px solid var(--brand);outline-offset:3px;}

::selection{background:var(--brand-soft);color:var(--ink);}

hr{border:none;border-top:1px solid var(--rule);margin:var(--s5) 0;}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  *,*::before,*::after{
    animation-duration:.01ms!important;
    animation-iteration-count:1!important;
    transition-duration:.01ms!important;
    scroll-behavior:auto!important;
  }
}


/* ================================================ 4. Utilitaires de gabarit */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--s5);}
.prose{max-width:var(--prose);}

/* Étiquette mono en capitales. --ink-3 n'étant validé AA que sur --bg et
   --surface, les contextes teintés repassent l'étiquette en --ink-2. */
.eyebrow{
  font-family:var(--f-mono);
  font-size:var(--t-cap);
  font-weight:500;
  letter-spacing:var(--ls-cap);
  text-transform:uppercase;
  color:var(--ink-3);
}

.lede{font-size:var(--t-xl);line-height:1.5;color:var(--ink-2);max-width:60ch;}

.sec-head{display:flex;flex-direction:column;gap:var(--s2);}
/* Ligne de sortie sous une grille de cartes : deux renvois discrets, jamais un
   troisième bouton. Elle évite le cul-de-sac sans concurrencer l'action. */
.sec-foot{font-size:var(--t-md);color:var(--ink-3);}
.sec-foot a{color:var(--brand-ink);font-weight:500;}

.actions{display:flex;flex-wrap:wrap;gap:var(--s3);padding-top:var(--s1);}

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

.skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--brand-deep);color:var(--on-deep);
  padding:var(--s3) var(--s4);border-radius:0 0 var(--r-sm) 0;
  font-weight:600;text-decoration:none;
}
.skip:focus{left:0;}


/* ======================================== 5. En-tête, marque, logo, navigation */
.site-header{
  position:sticky;top:0;z-index:50;
  background:color-mix(in srgb,var(--surface) 92%,transparent);
  backdrop-filter:saturate(180%) blur(12px);
  border-bottom:1px solid var(--rule);
}
.site-header .wrap{display:flex;align-items:center;flex-wrap:wrap;gap:var(--s4);min-height:var(--header-h);}

/* Verrou de marque empilé : la signature passe sous le nom plutôt qu'à côté.
   Posée en ligne, elle coûte 100px de large à l'en-tête et fait déborder la
   navigation complète hors du gabarit de 1180px. */
.brand{display:flex;flex-direction:column;justify-content:center;gap:1px;text-decoration:none;color:var(--ink);flex:0 0 auto;}
.brand .mark{font-family:var(--f-display);font-weight:700;font-size:var(--t-xl);line-height:1.15;letter-spacing:var(--ls-tighter);color:var(--brand-ink);}
.brand .sub{font-family:var(--f-mono);font-size:var(--t-cap);line-height:1.2;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);}

/* .site-logo — image du logo, jamais recolorée ni déformée.
   Hauteur d'en-tête : 34px (fourchette imposée 32–38px).
   Deux déclinaisons, la bascule clair/sombre se fait par jeton :
     <a class="brand" href="/">
       <img class="site-logo site-logo--light" src="/assets/logo-horizontal.png"
            alt="Bi Cloud" width="W" height="H">
       <img class="site-logo site-logo--dark" src="/assets/logo-horizontal-sombre.png"
            alt="" aria-hidden="true" width="W" height="H">
     </a>
   width/height explicites obligatoires ; pas de loading="lazy" en en-tête.
   .site-logo--white : version blanche, à poser sur aplat --brand-deep.
   .site-logo--lg : pied de page.
   Zone de respiration = hauteur ÷ 2, soit 17px : garantie par le gap --s4
   (18px) de .site-header .wrap. Ne pas la réduire. */
.site-logo{
  height:var(--logo-h,34px);
  width:auto;
  max-width:none;
  flex:0 0 auto;
}
.site-logo--light{display:var(--logo-light);}
.site-logo--dark{display:var(--logo-dark);}
.site-logo--white{display:block;}   /* visible quel que soit le thème */
.site-logo--lg{--logo-h:40px;}

.nav{margin-left:auto;display:flex;align-items:center;gap:2px;min-width:0;}
.nav > ul{list-style:none;display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:0;margin:0;}
.nav li{position:relative;}
.nav a{
  display:block;padding:var(--s2);border-radius:var(--r-sm);white-space:nowrap;
  color:var(--ink-2);text-decoration:none;font-size:var(--t-md);font-weight:500;
  transition:background .15s ease,color .15s ease;
}
.nav a:hover{background:var(--surface-2);color:var(--ink);}
.nav a[aria-current="page"]{background:var(--surface-2);color:var(--ink);font-weight:600;}
.nav .sub-menu{
  list-style:none;margin:0;padding:var(--s2);position:absolute;top:100%;left:0;min-width:280px;
  background:var(--surface);border:1px solid var(--rule);border-radius:var(--r);
  box-shadow:var(--shadow-lg);display:none;flex-direction:column;gap:1px;
}
.nav li:hover > .sub-menu,
.nav li:focus-within > .sub-menu{display:flex;}
.nav .sub-menu a{white-space:nowrap;font-weight:400;}

/* Bouton du menu à tiroir : masqué au-dessus de 1150px, dessiné par l'agent
   en-tête au-dessous. aria-expanded porte l'état. */
.nav-toggle{
  display:none;
  align-items:center;justify-content:center;gap:var(--s2);
  min-height:var(--tap);min-width:var(--tap);
  padding:var(--s2) var(--s3);
  background:transparent;border:1px solid var(--rule-strong);border-radius:var(--r-sm);
  color:var(--ink);font-family:var(--f-body);font-size:var(--t-md);font-weight:600;
  cursor:pointer;
}
.nav-toggle:hover{border-color:var(--brand);color:var(--brand-ink);}

/* Téléphone cliquable en en-tête, visible sur mobile (voir §17). */
.header-tel{
  display:none;align-items:center;gap:var(--s2);
  min-height:var(--tap);padding:0 var(--s3);
  color:var(--ink);font-weight:600;font-size:var(--t-md);text-decoration:none;
  border-radius:var(--r-sm);
}
.header-tel:hover{background:var(--surface-2);color:var(--brand-ink);}

.header-cta{flex:0 0 auto;margin-left:var(--s2);white-space:nowrap;}


/* ============================================== 6. Boutons et états
   .btn-primary = vert, appel à l'action principal (règle d'or).
   .btn-brand   = bleu plein, action secondaire importante.
   .btn-ghost   = contour neutre, survol bleu.
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  min-height:var(--tap);
  padding:var(--s3) var(--s5);
  border-radius:var(--r-sm);border:1px solid transparent;
  font-family:var(--f-body);font-weight:600;font-size:var(--t-md);line-height:1.25;
  text-decoration:none;cursor:pointer;text-align:center;
  transition:background .15s ease,border-color .15s ease,color .15s ease,transform .1s ease,box-shadow .15s ease;
}
.btn:active{transform:translateY(1px);}
.btn-lg{padding:var(--s4) var(--s6);font-size:var(--t-base);min-height:52px;}

.btn-primary{background:var(--cta);border-color:var(--cta);color:var(--cta-ink);}
.btn-primary:hover{background:var(--cta-hover);border-color:var(--cta-hover);color:var(--cta-ink);}

.btn-brand{background:var(--brand-solid);border-color:var(--brand-solid);color:var(--brand-solid-ink);}
.btn-brand:hover{background:var(--brand-solid-hover);border-color:var(--brand-solid-hover);color:var(--brand-solid-ink);}

.btn-ghost{background:transparent;border-color:var(--rule-strong);color:var(--ink);}
.btn-ghost:hover{background:var(--brand-soft);border-color:var(--brand);color:var(--brand-ink);}

/* Désactivé : neutre, sans effet de survol, curseur explicite.
   Le libellé reste lisible (--ink-2) : --ink-3 ne passe pas AA sur --surface-3. */
.btn[disabled],
.btn[aria-disabled="true"]{
  background:var(--surface-3);border-color:var(--rule);color:var(--ink-2);
  cursor:not-allowed;box-shadow:none;transform:none;
}

/* État de chargement : le libellé s'efface, un témoin tourne à sa place.
   Le libellé reste dans le DOM — la largeur du bouton ne bouge pas. */
.btn.is-loading{cursor:progress;color:transparent;position:relative;}
.btn.is-loading::after{
  content:"";position:absolute;width:16px;height:16px;border-radius:50%;
  border:2px solid var(--ink);border-top-color:transparent;
  animation:btn-spin .7s linear infinite;
}
.btn-primary.is-loading::after{border-color:var(--cta-ink);border-top-color:transparent;}
.btn-brand.is-loading::after{border-color:var(--brand-solid-ink);border-top-color:transparent;}
.btn-ghost.is-loading::after{border-color:var(--ink);border-top-color:transparent;}
@keyframes btn-spin{to{transform:rotate(360deg);}}


/* ================================ 7. Bandes, héros, fil d'Ariane, corps de page */
main{display:block;}

section.band{padding:var(--s7) 0;border-bottom:1px solid var(--rule);}
section.band.alt{background:var(--surface);}
section.band > .wrap{display:flex;flex-direction:column;gap:var(--s5);}

.breadcrumb{padding:var(--s4) 0 0;}
.breadcrumb ol{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s1);padding:0;margin:0;font-size:var(--t-sm);color:var(--ink-3);}
.breadcrumb li::after{content:"›";margin-left:var(--s1);color:var(--rule-strong);}
.breadcrumb li:last-child::after{content:"";}
.breadcrumb a{color:var(--ink-3);text-decoration:none;}
.breadcrumb a:hover{color:var(--brand-ink);text-decoration:underline;}

.hero{padding:var(--s6) 0 var(--s7);border-bottom:1px solid var(--rule);background:var(--surface);position:relative;}
.hero .wrap{display:flex;flex-direction:column;gap:var(--s6);position:relative;z-index:1;}
.hero-main{display:flex;flex-direction:column;min-width:0;}
.hero h1{max-width:19ch;}
.hero .actions{padding-top:var(--s2);}
.hero-home{padding-bottom:var(--s8);background:linear-gradient(180deg,var(--brand-soft) 0%,var(--surface) 70%);}

/* Ligne de réassurance courte sous le héros (métadonnées d'article incluses). */
.trust{
  display:flex;flex-wrap:wrap;gap:var(--s2) var(--s5);
  padding-top:var(--s5);margin-top:var(--s1);
  border-top:1px solid var(--rule);font-size:var(--t-sm);color:var(--ink-2);
}
.trust span{display:flex;align-items:center;gap:var(--s2);}
.trust span::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--brand);flex:0 0 auto;}

.page-body{padding:var(--s6) 0 var(--s7);}
.page-body .wrap{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:var(--s7);align-items:start;}
.page-body.full .wrap{grid-template-columns:minmax(0,1fr);}
.page-body.full article.content{max-width:none;}
.page-body.full article.content > p,
.page-body.full article.content > ul,
.page-body.full article.content > ol,
.page-body.full article.content > blockquote{max-width:var(--prose);}


/* ============================================== 8. Contenu rédactionnel */
article.content{max-width:var(--prose);display:flex;flex-direction:column;gap:var(--s5);}
article.content > h2{font-size:var(--t-2xl);margin-top:var(--s5);}
article.content > h2:first-child{margin-top:0;}
article.content > h3{font-size:var(--t-lg);margin-top:var(--s1);}
article.content p{color:var(--ink-2);}
article.content a{font-weight:500;}

article.content > ul,
article.content > ol{padding-left:1.3em;display:flex;flex-direction:column;gap:var(--s2);color:var(--ink-2);}
article.content li::marker{color:var(--brand);}
article.content li > ul,
article.content li > ol{margin-top:var(--s2);padding-left:1.2em;display:flex;flex-direction:column;gap:var(--s1);}

article.content blockquote{
  border-left:3px solid var(--brand);background:var(--surface-2);
  padding:var(--s4) var(--s5);border-radius:0 var(--r) var(--r) 0;color:var(--ink);
}
article.content blockquote p{color:var(--ink);}
article.content blockquote p + p{margin-top:var(--s2);}

article.content code{
  font-family:var(--f-mono);font-size:.86em;
  background:var(--surface-2);border:1px solid var(--rule);
  padding:1px 5px;border-radius:4px;color:var(--ink);
}
article.content pre{
  background:var(--surface-2);border:1px solid var(--rule);border-radius:var(--r);
  padding:var(--s4);overflow-x:auto;
  font-family:var(--f-mono);font-size:var(--t-sm);line-height:1.6;color:var(--ink);
}
article.content pre code{background:none;border:none;padding:0;font-size:inherit;}

article.content .table-scroll{overflow-x:auto;border:1px solid var(--rule);border-radius:var(--r);background:var(--surface);}
article.content table{border-collapse:collapse;width:100%;min-width:520px;font-size:var(--t-md);}
article.content th,
article.content td{text-align:left;padding:var(--s3) var(--s4);border-bottom:1px solid var(--rule);vertical-align:top;}
article.content thead th{
  font-family:var(--f-mono);font-size:var(--t-cap);letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-2);font-weight:500;background:var(--surface-2);white-space:nowrap;
}
article.content tbody tr:last-child td{border-bottom:none;}
article.content td{color:var(--ink-2);}
article.content td:first-child{color:var(--ink);}

/* Réponse directe placée en tête de page (référencement et lecture rapide). */
.lede-answer{
  background:var(--surface-2);border:1px solid var(--rule);border-left:3px solid var(--brand);
  padding:var(--s5);border-radius:0 var(--r) var(--r) 0;
  font-size:var(--t-lg);line-height:1.55;color:var(--ink);
}


/* ============================================================ 9. Barre latérale */
.sidebar{display:flex;flex-direction:column;gap:var(--s5);position:sticky;top:calc(var(--header-h) + var(--s5));}
.side-card{
  background:var(--surface);border:1px solid var(--rule);border-radius:var(--r);
  padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);box-shadow:var(--shadow-sm);
}
.side-card h2,.side-card h3{font-size:var(--t-lg);}
.side-card p{font-size:var(--t-md);color:var(--ink-2);}
.side-card ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--s2);}
.side-card ul a{font-size:var(--t-md);text-decoration:none;color:var(--ink-2);}
.side-card ul a:hover{color:var(--brand-ink);text-decoration:underline;}
.side-card .btn{width:100%;}

/* Carte latérale de conversion : teinte bleue (identité), bouton vert (action). */
.side-card.accent{background:var(--brand-soft);border-color:color-mix(in srgb,var(--brand) 32%,transparent);}
.side-card.accent .eyebrow{color:var(--ink-2);}
.side-card.accent p{color:var(--ink-2);}


/* ================ 10. Cartes, grilles, chiffres, bandeau de confiance */
.grid{display:grid;gap:var(--s5);}
.grid-2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));}
.grid-3{grid-template-columns:repeat(auto-fit,minmax(268px,1fr));}
.grid-4{grid-template-columns:repeat(auto-fit,minmax(214px,1fr));}

.card{
  background:var(--surface);border:1px solid var(--rule);border-radius:var(--r);
  padding:var(--s5);display:flex;flex-direction:column;gap:var(--s3);box-shadow:var(--shadow-sm);
  transition:border-color .15s ease,box-shadow .15s ease,transform .15s ease;
}
section.alt .card{background:var(--bg);}
.card h2,.card h3{font-size:var(--t-lg);}
.card p{font-size:var(--t-md);color:var(--ink-2);}

/* Carte cliquable : elle doit se signaler comme telle — curseur, filet bleu,
   élévation, flèche qui avance, anneau de focus visible. */
a.card{text-decoration:none;color:inherit;cursor:pointer;}
a.card:hover{border-color:var(--brand);box-shadow:var(--shadow);transform:translateY(-2px);}
a.card:active{transform:translateY(0);box-shadow:var(--shadow-sm);}
a.card:focus-visible{border-color:var(--brand);}
.card .more{
  margin-top:auto;padding-top:var(--s1);
  font-size:var(--t-md);font-weight:600;color:var(--brand-ink);
  display:flex;align-items:center;gap:var(--s2);
}
.card .more::after{content:"→";transition:transform .15s ease;}
a.card:hover .more{color:var(--brand);}
a.card:hover .more::after{transform:translateX(3px);}

.stat{display:flex;flex-direction:column;gap:var(--s1);}
.stat .v{
  font-family:var(--f-display);font-size:var(--t-3xl);font-weight:700;
  letter-spacing:var(--ls-tighter);line-height:1;color:var(--brand-ink);
  font-variant-numeric:tabular-nums;
}
.stat .l{font-size:var(--t-md);color:var(--ink-2);}

/* .trust-bar — bandeau de chiffres, placé sous le titre de page.
   Chiffres tabulaires, encadrés de deux filets, aucune couleur d'action : la
   confiance s'inspire, elle ne se crie pas.
     <ul class="trust-bar">
       <li><span class="trust-bar__n">278</span><span class="trust-bar__l">clients accompagnés</span></li>
       …
     </ul>                                                                     */
.trust-bar{
  list-style:none;margin:0;
  padding:var(--s4) 0;
  display:flex;flex-wrap:wrap;gap:var(--s4) var(--s7);
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
}
.trust-bar li{display:flex;flex-direction:column;gap:2px;}
.trust-bar__n{
  font-family:var(--f-display);font-size:var(--t-2xl);font-weight:700;
  letter-spacing:var(--ls-tight);line-height:1.05;color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.trust-bar__l{
  font-family:var(--f-mono);font-size:var(--t-cap);letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);line-height:1.4;
}


/* ================================================= 11. FAQ, listes, glossaire */
.faq{display:flex;flex-direction:column;border-top:1px solid var(--rule);}
.faq-item{border-bottom:1px solid var(--rule);padding:var(--s5) 0;display:flex;flex-direction:column;gap:var(--s2);}
.faq-item h3{font-size:var(--t-lg);color:var(--ink);}
.faq-item p{color:var(--ink-2);max-width:var(--prose);}

.list-rows{display:flex;flex-direction:column;border-top:1px solid var(--rule);margin:0 calc(var(--s3) * -1);}
.list-row{
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--s2) var(--s5);
  padding:var(--s5) var(--s3);border-bottom:1px solid var(--rule);align-items:baseline;
  text-decoration:none;color:inherit;
  transition:background .15s ease;
}
.list-row h3{font-size:var(--t-lg);grid-column:1;transition:color .15s ease;}
.list-row p{grid-column:1;font-size:var(--t-md);color:var(--ink-2);max-width:70ch;}
.list-row .meta{
  grid-column:2;grid-row:1;justify-self:end;
  font-family:var(--f-mono);font-size:var(--t-cap);color:var(--ink-3);
  white-space:nowrap;font-variant-numeric:tabular-nums;
}
/* Ligne cliquable : fond, titre coloré et souligné — même grammaire que les cartes. */
a.list-row:hover{background:var(--surface-2);}
a.list-row:hover h3{color:var(--brand-ink);text-decoration:underline;}

dl.glossary{display:flex;flex-direction:column;border-top:1px solid var(--rule);}
dl.glossary > div{padding:var(--s5) 0;border-bottom:1px solid var(--rule);display:flex;flex-direction:column;gap:var(--s2);}
dl.glossary dt{font-family:var(--f-display);font-weight:600;font-size:var(--t-lg);}
dl.glossary dt a{text-decoration:none;}
dl.glossary dt a:hover{text-decoration:underline;}
dl.glossary dd{margin:0;color:var(--ink-2);font-size:var(--t-md);}


/* ========================= 12. Conversion : bloc CTA et barre collante mobile
   Aplat ardoise (--brand-deep) dans les deux thèmes, texte --on-deep.
   Le bouton d'action reste vert : c'est le repère du visiteur sur tout le site.
   Les surcharges ci-dessous sont volontairement plus spécifiques que le §6.
   ========================================================================== */
.cta-block{
  background:var(--brand-deep);color:var(--on-deep);border-radius:var(--r-lg);
  padding:var(--s6);display:flex;flex-direction:column;gap:var(--s3);
  position:relative;overflow:hidden;
}
.cta-block > *:not(.hex-deco){position:relative;z-index:1;}
.cta-block h2{font-size:var(--t-2xl);color:inherit;max-width:22ch;}
.cta-block p{color:inherit;opacity:.9;max-width:56ch;}
.cta-block .eyebrow{color:inherit;opacity:.75;}
.cta-block .fine{font-size:var(--t-sm);opacity:.8;}
/* :not(.btn) est indispensable : sans lui cette règle repeindrait le libellé
   du bouton vert en blanc (2,4:1) — c'est le seul point de collision de
   spécificité du fichier avec les boutons. */
.cta-block a:not(.btn){color:inherit;}
.cta-block .actions{padding-top:var(--s2);}
.cta-block .btn-ghost{background:transparent;border-color:color-mix(in srgb,var(--on-deep) 45%,transparent);color:var(--on-deep);}
.cta-block .btn-ghost:hover{background:color-mix(in srgb,var(--on-deep) 14%,transparent);border-color:var(--on-deep);color:var(--on-deep);}
.cta-block :focus-visible{outline-color:var(--on-deep);}

/* .sticky-cta — barre d'action fixe, sous 700px uniquement.
   Masquée par défaut ; le JS ajoute .is-visible après 400px de défilement et
   la retire quand le bloc de conversion de bas de page entre dans l'écran.
   Sans JavaScript, elle ne s'affiche jamais : aucun contenu n'en dépend. */
.sticky-cta{display:none;}
.sticky-cta .btn{flex:1 1 0;min-width:0;}

/* ================================================================ 13. Formulaires
   .form-field — un champ = une étiquette VISIBLE au-dessus, un contrôle,
   une aide facultative, un message d'erreur sous le champ concerné.
     <div class="form-field">
       <label for="x">Votre email</label>
       <input id="x" type="email" aria-describedby="x-err" aria-invalid="true">
       <p class="form-field__hint">Nous répondons sous une heure ouvrée.</p>
       <p class="form-field__error" id="x-err">Indiquez une adresse valide.</p>
     </div>
   L'erreur se déclenche par aria-invalid="true" sur le contrôle, ou par
   .is-error sur le conteneur. Jamais de placeholder en guise d'étiquette.
   ========================================================================== */
.form{display:flex;flex-direction:column;gap:var(--s5);max-width:560px;}

.form-field{display:flex;flex-direction:column;gap:var(--s1);}
.form-field > label{font-size:var(--t-md);font-weight:600;color:var(--ink);}
.form-field__hint{font-size:var(--t-sm);color:var(--ink-3);}
.form-field__error{font-size:var(--t-sm);font-weight:600;color:var(--alert);}

.form-field input,
.form-field select,
.form-field textarea{
  font-family:var(--f-body);font-size:var(--t-base);line-height:1.4;color:var(--ink);
  background:var(--surface);border:1px solid var(--rule-strong);border-radius:var(--r-sm);
  padding:var(--s3);width:100%;min-height:var(--tap);
  transition:border-color .15s ease,background .15s ease;
}
.form-field textarea{min-height:120px;resize:vertical;}
.form-field input::placeholder,
.form-field textarea::placeholder{color:var(--ink-3);}
.form-field input:hover,
.form-field select:hover,
.form-field textarea:hover{border-color:var(--ink-3);}
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible{border-color:var(--brand);outline-offset:2px;}
.form-field input[disabled],
.form-field select[disabled],
.form-field textarea[disabled]{background:var(--surface-2);color:var(--ink-3);cursor:not-allowed;}

/* État d'erreur — spécificité égale à celle des règles ci-dessus, l'ordre
   source tranche : un champ en erreur reste rouge même pendant le focus,
   l'anneau bleu du focus restant visible par-dessus. */
.form-field.is-error > label{color:var(--alert);}
.form-field.is-error input,
.form-field.is-error select,
.form-field.is-error textarea,
.form-field input[aria-invalid="true"],
.form-field select[aria-invalid="true"],
.form-field textarea[aria-invalid="true"]{border-color:var(--alert);background:var(--alert-soft);}

/* .form-msg — écran de confirmation ou message global de formulaire :
   il dit ce qui se passe ensuite et sous quel délai. */
.form-msg{
  border:1px solid var(--rule);border-left:3px solid var(--brand);
  background:var(--surface-2);color:var(--ink);
  padding:var(--s4) var(--s5);border-radius:0 var(--r) var(--r) 0;
  display:flex;flex-direction:column;gap:var(--s2);
}
.form-msg--ok{border-left-color:var(--ok);background:var(--ok-soft);}
.form-msg--alert{border-left-color:var(--alert);background:var(--alert-soft);}
.form-msg p{color:var(--ink-2);font-size:var(--t-md);}

/* Case à cocher de consentement : zone cliquable généreuse. */
.form-consent{display:flex;gap:var(--s3);align-items:flex-start;font-size:var(--t-sm);color:var(--ink-2);}
.form-consent input{width:auto;min-height:0;margin:5px 0 0;accent-color:var(--brand);flex:0 0 auto;}


/* ============================== 14. Encarts, marqueurs, décor hexagonal */
.callout{
  border-left:3px solid var(--warn);background:var(--warn-soft);
  padding:var(--s4) var(--s5);border-radius:0 var(--r) var(--r) 0;
  display:flex;flex-direction:column;gap:var(--s2);
}
.callout .eyebrow{color:var(--warn);}
.callout p{font-size:var(--t-md);color:var(--ink-2);}

.todo{
  display:inline-block;background:var(--alert-soft);color:var(--alert);
  border:1px dashed color-mix(in srgb,var(--alert) 50%,transparent);
  padding:1px 7px;border-radius:4px;font-family:var(--f-mono);font-size:.8em;font-weight:500;
}

/* .hex-deco — motif hexagonal repris de la géométrie du symbole.
   Couche décorative, jamais porteuse d'information : à poser dans un parent
   en position:relative, avec un contenu en z-index supérieur.
     <div class="hero"><span class="hex-deco" aria-hidden="true"></span>…</div>
   Le motif est un masque (aucune couleur n'y est encodée) : la teinte vient
   de --hex-color, l'intensité de --hex-opacity. Jamais en vert. */
.hex-deco{
  --hex-pattern:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='56' height='100' viewBox='0 0 56 100'%3E%3Cpath d='M28 66L0 50L0 16L28 0L56 16L56 50L28 66L28 100' fill='none' stroke='%23000' stroke-width='2'/%3E%3Cpath d='M28 0L28 34L0 50L0 84L28 100L56 84L56 50L28 34' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background:var(--hex-color,var(--brand));
  opacity:var(--hex-opacity,.07);
  -webkit-mask-image:var(--hex-pattern);
  mask-image:var(--hex-pattern);
  -webkit-mask-size:56px 100px;
  mask-size:56px 100px;
}
.cta-block .hex-deco{--hex-color:var(--on-deep);--hex-opacity:.06;}


/* ============================================================ 15. Pied de page */
.site-footer{background:var(--surface);border-top:1px solid var(--rule);padding:var(--s7) 0 var(--s6);}
.site-footer .wrap{display:flex;flex-direction:column;gap:var(--s6);}
.foot-grid{display:grid;grid-template-columns:1.4fr repeat(auto-fit,minmax(150px,1fr));gap:var(--s6);}
.foot-col{display:flex;flex-direction:column;gap:var(--s3);}
.foot-col h2{
  font-family:var(--f-mono);font-size:var(--t-cap);font-weight:500;
  letter-spacing:var(--ls-cap);text-transform:uppercase;color:var(--ink-3);
}
.foot-col ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--s2);}
.foot-col a{font-size:var(--t-md);color:var(--ink-2);text-decoration:none;}
.foot-col a:hover{color:var(--brand-ink);text-decoration:underline;}
.foot-col p{font-size:var(--t-md);color:var(--ink-2);}
.foot-bottom{
  display:flex;flex-wrap:wrap;gap:var(--s2) var(--s5);justify-content:space-between;
  padding-top:var(--s5);border-top:1px solid var(--rule);font-size:var(--t-sm);color:var(--ink-3);
}
.foot-bottom ul{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s4);padding:0;margin:0;}
.foot-bottom a{color:var(--ink-3);text-decoration:none;}
.foot-bottom a:hover{color:var(--brand-ink);text-decoration:underline;}


/* ================================================ 16. Animations d'apparition
   .reveal et .reveal-group sont décrits d'un seul tenant en §22.7.
   Rien ici : l'état masqué ne doit être posé QUE sous .js-reveal, classe que le
   script d'apparition pose lui-même après s'être assuré qu'il peut la retirer.
   La classe .js générique ne suffirait pas — un script en échec laisserait des
   sections entières à opacité 0.
   ========================================================================== */


/* ================================================================ 17. Réactif */

@media (max-width:1080px){
  .page-body .wrap{grid-template-columns:minmax(0,1fr);gap:var(--s6);}
  .sidebar{position:static;flex-direction:row;flex-wrap:wrap;}
  .sidebar .side-card{flex:1 1 280px;}
}

/* Le comportement réactif de l'en-tête (bascule en menu à tiroir sous 1150px)
   est décrit d'un seul tenant en §20 — voir « en-tête et pied de page ». */

@media (max-width:760px){
  .trust-bar{gap:var(--s3) var(--s5);}
}

@media (max-width:640px){
  html{font-size:100%;}
  .wrap{padding:0 var(--s4);}
  section.band{padding:var(--s6) 0;}
  .hero{padding:var(--s5) 0 var(--s6);}
  .page-body{padding:var(--s5) 0 var(--s6);}
  .cta-block{padding:var(--s5) var(--s4);}
  .list-row{grid-template-columns:minmax(0,1fr);}
  .list-row .meta{grid-column:1;grid-row:auto;justify-self:start;}
  .foot-grid{grid-template-columns:1fr;gap:var(--s5);}
  .btn-lg{width:100%;}
  .hero .actions .btn,
  .cta-block .actions .btn{width:100%;}
}

/* Barre d'action collante : uniquement sous 700px. */
@media (max-width:700px){
  .sticky-cta{
    position:fixed;left:0;right:0;bottom:0;z-index:60;
    display:flex;gap:var(--s2);
    padding:var(--s2) var(--s3) calc(var(--s2) + env(safe-area-inset-bottom));
    background:var(--surface);border-top:1px solid var(--rule);
    box-shadow:var(--shadow-lg);
    transform:translateY(110%);
    transition:transform .25s ease;
  }
  .sticky-cta.is-visible{transform:none;}
  .sticky-cta .btn{padding-left:var(--s3);padding-right:var(--s3);}
  .site-footer{padding-bottom:calc(var(--s6) + 64px);}
}


/* ============================================================== 18. Impression */
@media print{
  .site-header,.site-footer,.sidebar,.cta-block,.sticky-cta,.skip,.breadcrumb,.hex-deco{display:none;}
  body{background:var(--paper);color:var(--paper-ink);font-size:11pt;}
  .wrap{max-width:none;padding:0;}
  a{color:var(--paper-ink);text-decoration:underline;}
  .reveal,.reveal-group > *{opacity:1!important;transform:none!important;}
}


/* ========================================================= 19. Compatibilité
   Le fragment du diagnostic (build/tools/) consomme encore les noms de
   l'ancienne palette. Ces alias les redirigent vers le système actuel : ils se
   résolvent sur :root, donc suivent automatiquement le thème. Aucune valeur
   littérale ici. À supprimer quand le fragment aura été repris.
   ========================================================================== */
:root{
  --accent:var(--brand-ink);
  --accent-2:var(--brand);
  --accent-soft:var(--brand-soft);
  --brand-2:var(--brand);
  --warm:var(--warn);
  --warm-soft:var(--warn-soft);
}


/* ========================================================= 20. === conversion ===
   Lot conversion. Ces règles viennent APRÈS le reste de la feuille : à
   spécificité égale, elles tranchent. Aucune valeur littérale, aucun vert
   ailleurs que sur un bouton d'action.

   Sommaire
     20.1  Hiérarchie des actions — un seul bouton vert par champ de vision
     20.2  Bandeau de confiance (.trust-bar)
     20.3  Bloc de conversion de bas de page (.cta-block)
     20.4  Barre latérale efficace (.sidebar)
     20.5  Barre d'action collante mobile (.sticky-cta)
   ========================================================================== */


/* --------------------------------------------------- 20.1 Hiérarchie des actions
   Deux boutons de même poids se neutralisent : le visiteur hésite, donc il
   ne clique pas. Le second appel à l'action garde la même hauteur que le
   premier — l'alignement optique compte — mais perd son contraste : filet
   léger, libellé en --ink-2, graisse réduite. Il ne redevient franc qu'au
   survol, quand l'intention est déjà là. */
.btn-quiet{
  background:transparent;
  border-color:var(--rule);
  color:var(--ink-2);
  font-weight:500;
}
.btn-quiet:hover{
  background:var(--brand-soft);
  border-color:var(--brand);
  color:var(--brand-ink);
}

/* Icône posée dans un bouton ou un lien d'action : elle suit la couleur du
   texte (fill="currentColor") et ne porte jamais d'information seule. */
.ico{flex:0 0 auto;}


/* --------------------------------------------------- 20.2 Bandeau de confiance
   Séparateurs : un filet fin dessiné dans la gouttière, jamais une bordure
   collée au chiffre. Trois paliers : rangée libre au-dessus de 560px, trois
   colonnes égales en dessous (les filets deviennent des bordures, les chiffres
   perdent deux points), puis trois lignes empilées sous 380px, où « UTILISATEURS »
   ne tient plus dans un tiers d'écran. Chiffres tabulaires aux trois paliers. */
.trust-bar li{position:relative;min-width:0;}
.trust-bar li + li::before{
  content:"";position:absolute;
  left:calc(var(--s7) / -2);
  top:.2em;bottom:.2em;width:1px;
  background:var(--rule-strong);
}
.trust-bar__n{white-space:nowrap;}

/* Ligne de méta d'article suivie du bandeau : un seul filet entre les deux. */
.trust + .trust-bar{border-top:0;padding-top:0;}

@media (max-width:760px){
  .trust-bar li + li::before{left:calc(var(--s5) / -2);}
}

@media (max-width:560px){
  .trust-bar{
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    gap:0;padding:var(--s3) 0;
  }
  .trust-bar li{padding:0 var(--s3);}
  .trust-bar li:first-child{padding-left:0;}
  .trust-bar li:last-child{padding-right:0;}
  .trust-bar li + li{border-left:1px solid var(--rule);}
  .trust-bar li + li::before{display:none;}
  .trust-bar__n{font-size:var(--t-xl);}
  .trust-bar__l{font-size:.74rem;letter-spacing:.05em;}
}

/* Sous 380px, trois colonnes ne tiennent plus sans couper « UTILISATEURS ».
   Le bandeau passe en trois lignes — chiffre et libellé côte à côte, filets
   horizontaux : c'est plus haut, mais rien n'est tronqué et tout se lit. */
@media (max-width:380px){
  .trust-bar{grid-template-columns:minmax(0,1fr);padding:var(--s2) 0;}
  .trust-bar li{flex-direction:row;align-items:baseline;gap:var(--s3);padding:var(--s2) 0;}
  .trust-bar li + li{border-left:0;border-top:1px solid var(--rule);}
  .trust-bar__n{font-size:var(--t-lg);min-width:4.4em;}
  .trust-bar__l{font-size:.74rem;}
}


/* ------------------------------------------- 20.3 Bloc de conversion (bas de page)
   Le titre promet un résultat, pas une réunion. Trois points de réassurance,
   un seul bouton vert, le téléphone traité comme une vraie seconde porte, et
   une sortie de secours vers le diagnostic pour qui n'est pas prêt à parler. */
.band-conv{border-bottom:0;}

/* Deux colonnes à partir de 900px : la promesse à gauche, l'action à droite,
   séparées par un filet. En dessous, une seule colonne — la promesse d'abord,
   le bouton ensuite : on ne demande jamais avant d'avoir dit pourquoi. */
.cta-say,
.cta-do{display:flex;flex-direction:column;gap:var(--s3);min-width:0;}
.cta-do{gap:var(--s4);}

@media (min-width:900px){
  .cta-block{flex-direction:row;gap:var(--s7);align-items:flex-start;padding:var(--s7) var(--s6);}
  .cta-say{flex:1 1 auto;}
  .cta-do{
    flex:0 0 clamp(318px,32%,380px);
    padding-left:var(--s6);
    border-left:1px solid color-mix(in srgb,var(--on-deep) 22%,transparent);
  }
  /* Le libellé complet du bouton ne doit pas se casser en deux lignes dans une
     colonne étroite : on rend les flancs au texte plutôt que de le tronquer. */
  .cta-do .btn{width:100%;padding-left:var(--s4);padding-right:var(--s4);}
}

.cta-logo{--logo-h:24px;opacity:.92;align-self:flex-start;margin-bottom:var(--s1);}

.cta-block h2{max-width:24ch;}
.cta-block .fine{line-height:1.5;}

/* Puces hexagonales : la géométrie du symbole, en blanc atténué. Jamais en
   vert — le vert reste le repère exclusif du bouton. */
.cta-points{
  list-style:none;margin:0;padding:0;
  display:flex;flex-wrap:wrap;gap:var(--s2) var(--s5);
  font-size:var(--t-md);
}
.cta-points li{display:flex;align-items:center;gap:var(--s2);opacity:.92;}
.cta-points li::before{
  content:"";width:7px;height:8px;flex:0 0 auto;
  background:var(--on-deep);opacity:.6;
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
}

/* Téléphone : deuxième porte de sortie, pas une mention légale. Aligné sur la
   hauteur du bouton (.btn-lg = 52px) pour que la ligne d'action reste droite. */
.cta-tel{
  display:inline-flex;flex-direction:column;justify-content:center;gap:1px;
  min-height:52px;padding:0 var(--s3);
  border-radius:var(--r-sm);text-decoration:none;
}
.cta-tel__l{
  font-family:var(--f-mono);font-size:var(--t-cap);letter-spacing:var(--ls-cap);
  text-transform:uppercase;opacity:.75;
}
.cta-tel__n{
  display:flex;align-items:center;gap:var(--s2);
  font-family:var(--f-display);font-size:var(--t-xl);font-weight:700;
  letter-spacing:var(--ls-tight);font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.cta-tel:hover .cta-tel__n{text-decoration:underline;text-underline-offset:3px;}

.cta-alt{font-size:var(--t-md);opacity:.92;}
.cta-alt a{text-decoration:underline;text-underline-offset:3px;}
.cta-alt a:hover{text-decoration-thickness:2px;}

@media (max-width:640px){
  .cta-block .actions{gap:var(--s3);}
  .cta-tel{padding:0;min-height:var(--tap);}
}


/* ------------------------------------------------------ 20.4 Barre latérale
   Colonne d'action, pas dépotoir de liens : l'audit d'abord, avec sa durée et
   sa promesse. Largeur fixée par la grille de .page-body (300px), min-width:0
   partout : un mot long ne peut donc pas élargir la colonne ni pousser le
   contenu rédactionnel. */
.sidebar,
.sidebar .side-card{min-width:0;}
.sidebar a{overflow-wrap:anywhere;}

.side-audit h2{max-width:18ch;}
.side-audit .eyebrow{font-variant-numeric:tabular-nums;}
.side-fine{font-size:var(--t-sm);color:var(--ink-2);}

.side-tel{
  display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap);margin-top:calc(var(--s2) * -1);
  font-family:var(--f-display);font-weight:700;font-size:var(--t-lg);
  letter-spacing:var(--ls-tight);font-variant-numeric:tabular-nums;
  color:var(--brand-ink);text-decoration:none;
}
.side-tel:hover{text-decoration:underline;text-underline-offset:3px;}

/* Écrans larges : la colonne reste collante. Si elle dépasse la hauteur de
   fenêtre, elle défile pour elle-même plutôt que de laisser ses dernières
   cartes hors d'atteinte. Le padding latéral compense l'écrêtage des ombres
   provoqué par overflow, la marge négative le reprend sur la gouttière. */
@media (min-width:1081px){
  .sidebar{
    max-height:calc(100vh - var(--header-h) - var(--s5) * 2);
    overflow-y:auto;overscroll-behavior:contain;
    padding:var(--s2);margin:calc(var(--s2) * -1);
    scrollbar-width:thin;
  }
}


/* ------------------------------------------- 20.5 Barre d'action collante mobile
   Enrichissement pur. Le script pose .js-sticky sur <html> ; sans lui la barre
   n'existe pas visuellement, n'occupe aucune place et ne masque rien — le
   contenu reste intégralement lisible sans JavaScript.
   Elle apparaît après 400px de défilement et se retire dès que le bloc de
   conversion de bas de page entre à l'écran : deux fois la même demande dans
   le même champ de vision, c'est une fois de trop. */
:root:not(.js-sticky) .sticky-cta{display:none;}

@media (max-width:700px){
  /* Réserve de place : la barre est fixe, le pied de page doit pouvoir
     défiler au-dessus d'elle. La réserve ne s'applique que si la barre existe,
     et remplace celle posée par défaut sur le pied de page. */
  .site-footer{padding-bottom:var(--s6);}
  .js-sticky body{padding-bottom:calc(60px + env(safe-area-inset-bottom));}

  /* Hors écran ET hors du parcours de tabulation visuel : visibility bascule
     à la fin de la transition de sortie, jamais pendant. */
  .js-sticky .sticky-cta{
    visibility:hidden;
    transition:transform .25s ease,visibility 0s linear .25s;
  }
  .js-sticky .sticky-cta.is-visible{
    visibility:visible;
    transition:transform .25s ease;
  }
  .sticky-cta .btn{font-size:var(--t-md);}
  .sticky-cta .btn-ghost{background:var(--surface);}
}

@media (prefers-reduced-motion:reduce){
  .js-sticky .sticky-cta,
  .js-sticky .sticky-cta.is-visible{transition:none;}
}


/* =================================================== 21. === en-tête et pied de page ===
   Identité visuelle (logo), en-tête collant, menu à tiroir sous 1150 px et
   pied de page. Aucune couleur littérale : tout passe par les jetons, donc
   par les trois blocs de thème du §1–2. Le vert reste réservé à l'action.
   ========================================================================== */

/* ---------------------------------------------------------- 21.1 Verrou de marque
   Le logo est posé tel quel : jamais recoloré, déformé, pivoté ni recadré.
   Seule la hauteur est pilotée (--logo-h), la largeur suit le ratio du fichier.
   Les deux déclinaisons clair/sombre sont dans le HTML ; le CSS en masque une
   via --logo-light / --logo-dark, définis dans les trois blocs de thème.
   Aucun JavaScript n'intervient dans la bascule. */
.brand{
  display:inline-flex;flex-direction:row;align-items:center;
  gap:var(--s3);flex:0 0 auto;
  text-decoration:none;color:var(--ink);
  border-radius:var(--r-sm);
}
.brand:focus-visible{outline-offset:4px;}
/* Zone de respiration = hauteur du logo ÷ 2, soit 17px en en-tête : garantie
   par le gap de .site-header .wrap (--s4, 18px). Ne pas la réduire. */
.site-header .wrap{gap:var(--s4);}

.brand--foot{align-self:flex-start;}

/* Le survol du verrou ne recolore rien : il ne fait qu'atténuer très légèrement
   l'image, pour signaler que c'est un lien. */
.brand:hover .site-logo{opacity:.86;}
.site-logo{transition:opacity .15s ease;}

/* ------------------------------------------------------------- 21.2 En-tête
   Ordre du DOM : logo, téléphone, bouton vert, bouton menu, tiroir. Le tiroir
   suit immédiatement le bouton qui l'ouvre — la tabulation épouse donc le sens
   de lecture, sur mobile comme au clavier.
   Ordre visuel au grand format : logo | navigation | téléphone | bouton vert.
   Les deux ordres divergent, `order` les réconcilie. */
.site-header .wrap{align-items:center;flex-wrap:nowrap;}
.site-header .brand{order:1;}
.site-header .nav{order:2;}
.site-header .header-tel{order:3;}
.site-header .header-cta{order:4;}
.site-header .nav-toggle{order:5;}

.header-tel{
  gap:var(--s2);
  margin-left:auto;                 /* pousse téléphone + bouton + menu à droite */
  font-variant-numeric:tabular-nums;
}
.header-tel .ico{flex:0 0 auto;color:var(--brand-ink);}
.header-tel:hover .ico{color:inherit;}

/* Deux libellés pour le bouton d'action, un seul affiché à la fois : le libellé
   masqué en display:none ne compte pas dans le nom accessible du lien. */
.header-cta__narrow{display:none;}

/* Bouton hamburger — visible uniquement quand le script a répondu (.js) et que
   la navigation horizontale ne tient plus. */
.nav-toggle__bars{
  position:relative;display:block;flex:0 0 auto;
  width:18px;height:12px;
}
.nav-toggle__bars span{
  position:absolute;left:0;right:0;height:2px;border-radius:2px;
  background:currentColor;
  transition:transform .2s ease,opacity .15s ease;
}
.nav-toggle__bars span:nth-child(1){top:0;}
.nav-toggle__bars span:nth-child(2){top:5px;}
.nav-toggle__bars span:nth-child(3){top:10px;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1){transform:translateY(5px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2){opacity:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3){transform:translateY(-5px) rotate(-45deg);}
.nav-toggle[aria-expanded="true"]{background:var(--surface-2);border-color:var(--rule-strong);}

/* Le conteneur du tiroir est transparent au-dessus de 1150px : ses enfants
   redeviennent des éléments de la barre d'en-tête. */
.nav-drawer{display:contents;}
.nav-drawer__actions{display:none;}

/* -------------------------------------------- 21.3 Sous 1150px : menu à tiroir
   Deux comportements, dans cet ordre :
     a) sans JavaScript — la navigation reste dans le flux, empilée sous la
        barre d'en-tête, sous-menus dépliés. Rien n'est masqué, rien ne défile
        horizontalement. Le bouton hamburger, lui, n'apparaît pas.
     b) avec JavaScript (.js) — la même navigation devient un tiroir, refermé
        par défaut, ouvert par le bouton hamburger.
   ========================================================================== */
@media (max-width:1150px){
  .site-header .wrap{
    flex-wrap:wrap;min-height:auto;
    padding-top:var(--s3);padding-bottom:var(--s3);
    gap:var(--s3);
    row-gap:var(--s4);
  }

  .site-header .nav-toggle{order:4;}
  /* Le téléphone entre en scène dès que la navigation quitte la barre : c'est
     la deuxième porte de sortie du site, et la plus utilisée sur mobile. */
  .header-tel{display:inline-flex;}
  .site-header .header-tel{order:2;}
  .site-header .header-cta{order:3;margin-left:0;}
  .site-header .nav-drawer{display:block;order:5;width:100%;}
  .nav-drawer__actions{display:none;}

  /* a) repli sans JavaScript : navigation en pile, sous-menus dépliés.
     Hiérarchie à deux niveaux : la rubrique porte le poids, ses pages sont
     décalées derrière un filet. Rien ne se replie, rien ne défile de côté. */
  .nav{width:100%;margin-left:0;display:block;}
  .nav > ul{flex-direction:column;align-items:stretch;flex-wrap:nowrap;gap:0;}
  .nav > ul > li + li{border-top:1px solid var(--rule);}
  .nav > ul > li > a{
    padding:var(--s3) var(--s2);border-radius:var(--r-sm);
    font-family:var(--f-display);font-size:var(--t-lg);font-weight:600;
    letter-spacing:var(--ls-tight);color:var(--ink);
  }
  .nav .sub-menu{
    position:static;display:flex;min-width:0;
    background:none;border:none;border-left:1px solid var(--rule-strong);border-radius:0;
    box-shadow:none;
    margin:0 0 var(--s3) var(--s3);padding:0 0 0 var(--s3);gap:0;
  }
  .nav .sub-menu a{
    white-space:normal;color:var(--ink-2);font-size:var(--t-md);
    padding:var(--s2) var(--s2);min-height:var(--tap);display:flex;align-items:center;
  }
  .nav li:hover > .sub-menu,
  .nav li:focus-within > .sub-menu{display:flex;}

  /* b) menu à tiroir dès que le script a répondu */
  .js .nav-toggle{display:inline-flex;}

  .js .site-header .nav-drawer{
    display:flex;flex-direction:column;gap:var(--s5);
    /* Positionné sur .site-header (sticky, donc bloc conteneur) : le tiroir se
       cale exactement sous la barre, à toute largeur, sans nombre magique. */
    position:absolute;top:100%;left:0;right:0;z-index:1;
    background:var(--surface);
    border-bottom:1px solid var(--rule);
    box-shadow:var(--shadow-lg);
    padding:var(--s5) var(--s5) var(--s6);
    max-height:calc(100vh - var(--header-h-m));
    max-height:calc(100dvh - var(--header-h-m));
    overflow-y:auto;overscroll-behavior:contain;
    visibility:hidden;opacity:0;transform:translateY(-6px);
    transition:opacity .18s ease,transform .18s ease,visibility 0s linear .18s;
  }
  .js .nav-drawer.is-open{
    visibility:visible;opacity:1;transform:none;
    transition-delay:0s;
  }
  .js .nav-drawer__actions{display:flex;flex-direction:column;gap:var(--s3);order:1;}
  .js .nav-drawer .nav{order:2;width:100%;}
  /* Le tiroir est un calque : on fige le défilement de la page derrière lui. */
  body.nav-est-ouvert{overflow:hidden;}
  body.nav-est-ouvert .sticky-cta{display:none;}
}

/* Hauteur réelle de la barre sous 1150px : padding (2 × --s3) + hauteur d'une
   zone cliquable. Elle sert à borner la hauteur du tiroir. */
.site-header{--header-h-m:calc(var(--tap) + 2 * var(--s3));}

/* Bloc d'action en tête du tiroir : le bouton vert d'abord, plein cadre, puis
   le téléphone, puis l'engagement de rappel. C'est la première chose que voit
   un visiteur qui ouvre le menu. */
.nav-drawer__actions{
  padding-bottom:var(--s5);
  border-bottom:1px solid var(--rule);
}
.nav-drawer__actions .btn{width:100%;}
.nav-drawer__tel{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s2);
  min-height:var(--tap);padding:0 var(--s3);
  color:var(--ink);font-weight:600;font-size:var(--t-lg);text-decoration:none;
  font-variant-numeric:tabular-nums;
  border:1px solid var(--rule-strong);border-radius:var(--r-sm);
}
.nav-drawer__tel .ico{color:var(--brand-ink);}
.nav-drawer__tel:hover{background:var(--brand-soft);border-color:var(--brand);color:var(--brand-ink);}
.nav-drawer__fine{font-size:var(--t-sm);color:var(--ink-3);text-align:center;}

/* Sous 700px, le libellé long du bouton d'action laisse la place au libellé
   court : logo, téléphone, bouton vert et menu tiennent alors sur une ligne
   jusqu'à 320px de large. Le bouton vert reste visible en permanence. */
@media (max-width:700px){
  .site-header .wrap{gap:var(--s2);}
  .header-cta__wide{display:none;}
  .header-cta__narrow{display:inline;}
  .header-cta{padding-left:var(--s3);padding-right:var(--s3);}
  .header-tel__num{display:none;}          /* l'icône seule, nom accessible via aria-label */
  .header-tel{padding:0;min-width:var(--tap);justify-content:center;}
  .js .nav-drawer{padding-left:var(--s4);padding-right:var(--s4);}
}

/* Entre 640 et 1150px, le tiroir dispose de toute la largeur d'une tablette :
   la navigation passe sur deux colonnes plutôt que d'étirer une liste unique
   sur 900px, et le bloc d'action garde une largeur de bouton lisible. */
@media (min-width:641px) and (max-width:1150px){
  .js .site-header .nav-drawer{padding-left:var(--s6);padding-right:var(--s6);}
  .js .nav-drawer__actions{max-width:460px;}
  /* Colonnes CSS plutôt qu'une grille : les rubriques s'écoulent d'une colonne
     à l'autre sans creuser les trous qu'une grille laisse dès que deux
     rubriques n'ont pas le même nombre de pages. */
  .js .nav-drawer .nav > ul{display:block;columns:2;column-gap:var(--s7);}
  .js .nav-drawer .nav > ul > li{break-inside:avoid;padding-bottom:var(--s4);}
  .js .nav-drawer .nav > ul > li + li{border-top:none;}
}

/* Très petits écrans : le mot « Menu » cède la place, les trois barres restent.
   Le nom accessible du bouton ne bouge pas, il vient de son aria-label. */
@media (max-width:380px){
  .nav-toggle__label{display:none;}
  .nav-toggle{padding-left:var(--s2);padding-right:var(--s2);}
}

/* Le tiroir n'existe qu'en dessous de 1150px : au-dessus, on s'assure qu'aucun
   état résiduel ne subsiste après un redimensionnement. */
@media (min-width:1151px){
  .nav-drawer.is-open{visibility:visible;opacity:1;}
  body.nav-est-ouvert{overflow:auto;}
}

/* ------------------------------------------------------- 21.4 Pied de page
   Trois niveaux de lecture : marque et coordonnées d'abord (ce dont on a
   besoin pour appeler), plan du site ensuite, mentions administratives en
   dernier, en corps réduit. */
.site-footer .wrap{gap:var(--s6);}

.foot-top{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--s6) var(--s7);align-items:start;
}

.foot-brand{display:flex;flex-direction:column;gap:var(--s4);align-items:flex-start;}
.foot-brand .brand--foot{order:0;}
.foot-baseline{
  font-family:var(--f-display);font-size:var(--t-xl);line-height:var(--lh-snug);
  letter-spacing:var(--ls-tight);color:var(--ink);max-width:26ch;text-wrap:balance;
}
.foot-social{
  display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap);padding:0 var(--s3) 0 0;
  color:var(--ink-2);font-size:var(--t-md);font-weight:600;text-decoration:none;
}
.foot-social .ico{color:var(--brand-ink);flex:0 0 auto;}
.foot-social:hover{color:var(--brand-ink);}
.foot-social:hover span{text-decoration:underline;}

.foot-contact{display:flex;flex-direction:column;gap:var(--s3);align-items:flex-start;}
.foot-contact h2{
  font-family:var(--f-mono);font-size:var(--t-cap);font-weight:500;
  letter-spacing:var(--ls-cap);text-transform:uppercase;color:var(--ink-3);
}
/* Le téléphone est la deuxième porte de sortie du site : il est traité comme
   tel — grand, tabulaire, avec une zone cliquable pleine. Il reste bleu :
   le vert appartient au bouton de prise de rendez-vous. */
.foot-phone{
  display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap);
  font-family:var(--f-display);font-size:var(--t-2xl);font-weight:700;
  letter-spacing:var(--ls-tight);font-variant-numeric:tabular-nums;
  color:var(--brand-ink);text-decoration:none;
}
.foot-phone .ico{width:22px;height:22px;flex:0 0 auto;}
.foot-phone:hover{color:var(--brand);text-decoration:underline;}
.foot-hours{font-size:var(--t-md);color:var(--ink-2);}
.foot-hours strong{color:var(--ink);}
.foot-mail{
  display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap);
  font-size:var(--t-md);font-weight:600;color:var(--ink-2);text-decoration:none;
}
.foot-mail .ico{color:var(--brand-ink);flex:0 0 auto;}
.foot-mail:hover{color:var(--brand-ink);}
.foot-mail:hover span{text-decoration:underline;}
.site-footer address{
  font-style:normal;font-size:var(--t-md);line-height:var(--lh-body);color:var(--ink-2);
}

/* Plan du site : cinq colonnes égales, titres de colonne cliquables. */
.foot-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  gap:var(--s5) var(--s4);
  padding-top:var(--s6);border-top:1px solid var(--rule);
}
/* font-size:inherit est nécessaire : la règle générique .foot-col a (§15) est
   plus spécifique que .foot-col h2 pour la taille et grossirait le titre. */
.foot-col h2 a{font-size:inherit;color:inherit;text-decoration:none;}
.foot-col h2 a:hover{color:var(--brand-ink);text-decoration:underline;}
.foot-col a{line-height:1.45;}

.foot-bottom{align-items:baseline;}
.foot-bottom p{color:inherit;}
.foot-ident{display:block;margin-top:var(--s1);}

@media (max-width:900px){
  .foot-top{grid-template-columns:minmax(0,1fr);gap:var(--s6);}
}

@media (max-width:640px){
  .site-footer .wrap{gap:var(--s6);}
  .foot-grid{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--s5) var(--s4);}
  .foot-baseline{font-size:var(--t-lg);}
  .foot-phone{font-size:var(--t-xl);}
}

@media print{
  .nav-drawer,.nav-toggle{display:none;}
}


/* ========================================================= 22. === formulaires ===
   Pages de conversion : formulaire de devis (/contact/) et bloc de
   réservation (/prendre-rendez-vous/). Ces règles complètent le §13, qui
   porte les fondations d'un champ (.form-field, .form-msg, .form-consent) ;
   on ne redéfinit ici que ce qui est propre aux deux blocs.

   Aucune valeur littérale : tout passe par les jetons du §1–2, donc par les
   trois blocs de thème. Le vert (--cta) reste réservé aux deux seuls boutons
   d'action de ces pages : « Demander un devis » et « Choisir un créneau ».

   Sommaire
     22.1  Zones cliquables et focus — le socle accessible
     22.2  Formulaire de devis : gabarit et carte
     22.3  Champs, erreurs, consentement
     22.4  Envoi, confirmation, repli sans JavaScript
     22.5  Colonne de réassurance
     22.6  Bloc de réservation Microsoft Bookings
   ========================================================================== */


/* ------------------------------------------- 22.1 Zones cliquables et focus
   44 px est un plancher, pas une cible : un doigt ne vise pas, il pose. Les
   contrôles héritent déjà de min-height:var(--tap) au §13 ; restent les cases
   à cocher et les liens en ligne, que les navigateurs dessinent à 13 px. */
.convform input[type="checkbox"]{
  width:22px;height:22px;min-height:0;flex:0 0 auto;
  accent-color:var(--brand);cursor:pointer;
}

/* Le focus est l'affordance principale au clavier : il ne doit jamais être
   rogné par le débordement d'un parent. Les cartes de ce lot laissent donc
   respirer l'anneau plutôt que de couper (pas d'overflow:hidden). */
.convform :focus-visible,
.rdv :focus-visible{outline:2px solid var(--brand);outline-offset:3px;}


/* -------------------------------------------- 22.2 Formulaire de devis
   Deux colonnes au-dessus de 900 px : le formulaire, puis une colonne de
   réassurance étroite qui porte le téléphone. En dessous, une seule colonne
   et la réassurance passe SOUS le formulaire — sur mobile, tout ce qui
   s'interpose entre le titre et le premier champ est du retard pris. */
.convform{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--s6);
  align-items:start;
  padding:var(--s6);
  background:var(--surface);
  border:1px solid var(--rule);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow);
  scroll-margin-top:calc(var(--header-h) + var(--s5));
}
@media (min-width:900px){
  .convform{grid-template-columns:minmax(0,1fr) 290px;gap:var(--s7);}
}

/* .form et .form-msg (§13) posent display:flex — une règle d'auteur bat la
   feuille du navigateur, et l'attribut `hidden` cesse alors de masquer quoi
   que ce soit. On lui rend son effet, explicitement, sur les deux blocs qui
   s'échangent la place : le formulaire et sa confirmation. */
.convform__form[hidden],
.convform__done[hidden]{display:none;}

.convform__main{display:flex;flex-direction:column;gap:var(--s5);min-width:0;}
.convform__head{display:flex;flex-direction:column;gap:var(--s2);}
.convform__head h2{font-size:var(--t-2xl);}
.convform__head p{color:var(--ink-2);max-width:52ch;}

/* .form impose max-width:560px au §13 : conservé, c'est la largeur au-delà de
   laquelle un champ devient pénible à parcourir de l'œil. */
.convform__form{gap:var(--s5);}

.convform__legend{font-size:var(--t-sm);color:var(--ink-3);}


/* --------------------------------------- 22.3 Champs, erreurs, consentement
   Le message d'erreur vit dans le DOM en permanence, vide, et disparaît par
   :empty. Rien n'est créé ni détruit à la validation : aria-describedby posé
   une fois dans le HTML reste valide, et le lecteur d'écran lit le texte dès
   qu'il est écrit. */
/* Le filet du §13 (--rule-strong) ne donne que 1,7:1 sur --surface : sous le
   seuil de 3:1 qu'un composant d'interface doit tenir (WCAG 1.4.11). Sur un
   formulaire, ce filet EST le champ — c'est lui qui dit où écrire. Il passe
   donc en --ink-3 : 4,8:1 en clair, 5,4:1 en sombre, sans toucher aux jetons.

   Le :not(.is-error) est nécessaire, pas cosmétique : à spécificité égale,
   une règle posée ici l'emporterait sur le filet rouge du §13, qui vient
   plus haut dans le fichier. Le champ fautif garde donc sa couleur d'alerte. */
.convform .form-field:not(.is-error) input,
.convform .form-field:not(.is-error) select,
.convform .form-field:not(.is-error) textarea{border-color:var(--ink-3);}
.convform .form-field:not(.is-error) input:hover,
.convform .form-field:not(.is-error) select:hover,
.convform .form-field:not(.is-error) textarea:hover{border-color:var(--brand);}

.convform .form-field__error:empty{display:none;}

/* Le message est précédé d'un signe : la couleur seule ne porte jamais une
   information (WCAG 1.4.1). */
.convform .form-field__error::before{content:"⚠ ";}

.form-field__opt{
  font-family:var(--f-mono);font-size:var(--t-cap);font-weight:400;
  letter-spacing:var(--ls-cap);text-transform:uppercase;color:var(--ink-3);
  margin-left:var(--s2);
}

/* Consentement : une boîte à part entière, cliquable sur toute sa surface,
   et non une ligne de petit texte qu'on coche à l'aveugle. */
.convform .form-consent{
  align-items:flex-start;gap:var(--s3);
  min-height:var(--tap);
  padding:var(--s3) var(--s4);
  border:1px solid var(--rule);border-radius:var(--r);
  background:var(--surface);
  transition:border-color .15s ease,background .15s ease;
}
.convform .form-consent:hover{border-color:var(--brand);background:var(--brand-soft);}
.convform .form-consent:focus-within{border-color:var(--brand);}
.convform .form-consent label{
  font-size:var(--t-sm);line-height:1.5;color:var(--ink-2);
  cursor:pointer;font-weight:400;
}
.convform .form-field--consent.is-error .form-consent{
  border-color:var(--alert);background:var(--alert-soft);
}
/* --ink-2 et non --ink-3 : sur --alert-soft, --ink-3 ne passe pas AA. */
.convform .form-field--consent.is-error .form-consent label{color:var(--ink-2);}

.convform__policy{font-size:var(--t-sm);}
.convform__policy a{font-weight:500;}


/* ------------------------- 22.4 Envoi, confirmation, repli sans JavaScript */
.convform__submit{display:flex;flex-direction:column;gap:var(--s3);align-items:flex-start;}
.convform__submit .btn{min-width:min(100%,240px);}

.convform__fine{font-size:var(--t-sm);line-height:1.5;color:var(--ink-2);}
.convform__fine strong{color:var(--ink);}

/* Bandeau d'annonce (aria-live). Neutre pendant l'envoi, rouge quand des
   champs restent à corriger : le visiteur sait d'un coup d'œil si sa demande
   est partie ou non, sans avoir à relire tout le formulaire. */
.convform__alert{
  font-size:var(--t-md);font-weight:600;color:var(--ink);
  border-left:3px solid var(--brand);background:var(--surface-2);
  padding:var(--s3) var(--s4);border-radius:0 var(--r-sm) var(--r-sm) 0;
}
.convform__alert:empty{display:none;}
.convform__alert--err{border-left-color:var(--alert);background:var(--alert-soft);}

/* Écran de confirmation : il dit ce qui se passe ensuite ET sous quel délai.
   Il reçoit le focus à l'envoi, d'où l'anneau explicite. */
.convform__done{gap:var(--s4);scroll-margin-top:calc(var(--header-h) + var(--s5));}
.convform__done .eyebrow{color:var(--ink-2);}
.convform__done h3{font-size:var(--t-xl);color:var(--ink);}
.convform__done p{color:var(--ink-2);}
.convform__done strong{color:var(--ink);}
.convform__done:focus-visible{outline:2px solid var(--brand);outline-offset:4px;}

.convform__next{
  display:flex;flex-direction:column;gap:var(--s3);
  margin:0;padding:0;list-style:none;counter-reset:etape;
}
.convform__next li{
  display:grid;grid-template-columns:26px minmax(0,1fr);gap:var(--s3);
  align-items:start;font-size:var(--t-md);color:var(--ink-2);
}
.convform__next li::before{
  counter-increment:etape;content:counter(etape);
  font-family:var(--f-mono);font-size:var(--t-cap);font-weight:500;
  width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  color:var(--brand-solid-ink);background:var(--brand-solid);
}
.convform__done-cta{padding-top:var(--s1);}

/* Repli sans JavaScript. Le formulaire ne poste nulle part : l'afficher sans
   script serait promettre une action qui n'arrivera pas. Il reste donc masqué
   tant que <html> ne porte pas .js (posée dans le <head>, avant le premier
   rendu : aucun clignotement), et le <noscript> prend le relais. */
:root:not(.js) .convform__form{display:none;}
.convform__noscript{gap:var(--s3);}
.convform__noscript-actions{margin-top:var(--s1);}


/* --------------------------------------------- 22.5 Colonne de réassurance
   Elle ne concurrence pas le formulaire : pas de vert, pas de bouton. Le
   téléphone y est traité en grand parce que c'est la seule voie utile pour
   un incident en cours — la seule situation où un formulaire est une erreur. */
.convform__side{display:flex;flex-direction:column;gap:var(--s5);min-width:0;}

.convform__side-card{
  display:flex;flex-direction:column;gap:var(--s2);
  padding:var(--s4) var(--s5);
  background:var(--surface-2);border:1px solid var(--rule);border-radius:var(--r);
}
/* Sur --surface-2, --ink-3 ne passe pas AA : l'étiquette repasse en --ink-2. */
.convform__side-card .eyebrow{color:var(--ink-2);}
.convform__side-card h3{font-size:var(--t-lg);}
.convform__side-card p{font-size:var(--t-sm);line-height:1.55;color:var(--ink-2);}

.convform__tel{
  display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap);margin-top:var(--s1);
  font-family:var(--f-display);font-size:var(--t-xl);font-weight:700;
  letter-spacing:var(--ls-tight);font-variant-numeric:tabular-nums;
  color:var(--brand-ink);text-decoration:none;
}
.convform__tel:hover{color:var(--brand);text-decoration:underline;}
.convform__side-card .convform__fine{font-size:var(--t-sm);color:var(--ink-2);}

.convform__promises{
  display:flex;flex-direction:column;gap:var(--s3);
  margin:0;padding:0;list-style:none;
}
.convform__promises li{
  display:grid;grid-template-columns:10px minmax(0,1fr);gap:var(--s3);
  align-items:start;font-size:var(--t-sm);line-height:1.55;color:var(--ink-2);
}
.convform__promises li::before{
  content:"";width:8px;height:8px;margin-top:7px;border-radius:50%;
  background:var(--brand);
}


/* ------------------------------- 22.6 Bloc de réservation Microsoft Bookings
   La page /prendre-rendez-vous/ a une seule fonction : ouvrir l'agenda. Le
   bloc dit d'abord ce que le visiteur obtient (trois points), puis lui donne
   le bouton. L'ordre compte : un bouton présenté avant sa promesse se fait
   ignorer. L'alternative « qu'on vous rappelle » vient sous un filet, en
   retrait — c'est une sortie de secours, pas un second choix de même poids. */
.rdv{
  position:relative;isolation:isolate;
  display:flex;flex-direction:column;gap:var(--s5);
  padding:var(--s6);
  background:var(--surface);
  border:1px solid var(--rule-strong);
  border-radius:var(--r-lg);
  box-shadow:var(--shadow);
  scroll-margin-top:calc(var(--header-h) + var(--s5));
}
.rdv > *:not(.hex-deco){position:relative;z-index:1;}
.rdv .hex-deco{--hex-opacity:.05;border-radius:var(--r-lg);}

.rdv__head{display:flex;flex-direction:column;gap:var(--s2);}
.rdv__head h2{font-size:var(--t-2xl);}

.rdv__points{
  display:flex;flex-direction:column;gap:var(--s4);
  margin:0;padding:0;list-style:none;
}
.rdv__points li{
  display:grid;grid-template-columns:32px minmax(0,1fr);gap:var(--s3);
  align-items:start;font-size:var(--t-md);line-height:1.6;color:var(--ink-2);
}
.rdv__points strong{color:var(--ink);}
/* Le pastillage est bleu : la géométrie du symbole porte l'identité, le vert
   ne sort que sur le bouton. */
.rdv__n{
  width:32px;height:32px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--f-mono);font-size:var(--t-sm);font-weight:500;
  color:var(--brand-ink);background:var(--brand-soft);
  border:1px solid var(--brand);
}

.rdv__do{
  display:flex;flex-direction:column;gap:var(--s3);align-items:stretch;
  padding-top:var(--s2);
}
/* « Bouton vert, large » : il occupe la largeur utile jusqu'à 480 px, seuil
   au-delà duquel un bouton pleine largeur cesse d'être lu comme un bouton. */
.rdv__cta{width:100%;max-width:480px;}
.rdv__fine{font-size:var(--t-sm);line-height:1.5;color:var(--ink-3);max-width:52ch;}

.rdv__alt{
  border-top:1px solid var(--rule);padding-top:var(--s5);
  font-size:var(--t-md);line-height:1.6;color:var(--ink-2);
}
.rdv__alt strong{color:var(--ink);}
.rdv__alt a{font-weight:600;}
.rdv__hours{display:block;margin-top:var(--s1);font-size:var(--t-sm);color:var(--ink-3);}


/* ------------------------------------------------------------ 22.7 Réactif */
@media (max-width:640px){
  .convform,
  .rdv{padding:var(--s5) var(--s4);border-radius:var(--r);}
  .convform__submit,
  .convform__submit .btn,
  .rdv__cta{width:100%;max-width:none;}
  .convform__submit{align-items:stretch;}
  .rdv__points li{grid-template-columns:28px minmax(0,1fr);gap:var(--s3);}
  .rdv__n{width:28px;height:28px;}
}

/* Le bloc de conversion est aussi la page la plus imprimée : un devis se
   prépare souvent sur papier. On garde les points et le téléphone, on retire
   ce qui n'a pas de sens hors écran. */
@media print{
  .convform__form,
  .convform__alert,
  .convform__done-cta,
  .rdv__cta,
  .rdv .hex-deco{display:none;}
  .convform,
  .rdv{border:1px solid var(--paper-ink);box-shadow:none;}
}


/* ============================================================ 22. === éditorial ===
   Mise en page du contenu : héros, chapeau de réponse directe, tableaux, FAQ,
   listings, schémas, apparitions au défilement. Ces règles viennent APRÈS le
   reste de la feuille : à spécificité égale, elles tranchent.

   Aucune valeur littérale de couleur, aucun vert ailleurs que sur un bouton
   d'action, aucune couleur définie uniquement dans un @media ou un
   [data-theme] : tout passe par les jetons des §1–2.

   Sommaire
     22.1  Héros — hiérarchie sur-titre / titre / chapeau / actions
     22.2  Chapeau de réponse directe (.lede-answer)
     22.3  Tableaux — en-têtes collants, zébrures, ombres de défilement
     22.4  Blocs FAQ
     22.5  Listings — cartes, lignes de blog, glossaire
     22.6  Schémas SVG (.schema, classes .sc-*)
     22.7  Apparitions au défilement (.reveal, .reveal-group)
   ========================================================================== */


/* ------------------------------------------------------------- 22.1 Héros
   Quatre niveaux, quatre écarts différents. Le gap uniforme du §7 les mettait
   tous à la même distance : le regard ne savait plus ce qui commandait quoi.
   L'écart se resserre là où le lien est fort (sur-titre → titre) et s'ouvre là
   où l'on change de registre (chapeau → actions → preuve). */
.hero-main{gap:0;}

/* Le sur-titre est un repère de rubrique, pas un titre : il reste petit, mais
   passe en bleu et reçoit la puce hexagonale du symbole. Jamais en vert. */
.hero .eyebrow{
  display:inline-flex;align-items:center;gap:var(--s2);
  align-self:flex-start;
  color:var(--brand-ink);
}
.hero .eyebrow::before{
  content:"";width:9px;height:10px;flex:0 0 auto;
  background:currentColor;
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
}

.hero h1{margin-top:var(--s3);max-width:20ch;}

/* Le chapeau descend d'un cran en taille et en couleur, et se cale sur une
   mesure plus courte que le corps de texte : c'est une entrée en matière, pas
   un paragraphe. */
.hero .lede{
  margin-top:var(--s4);
  font-size:var(--t-xl);line-height:1.5;
  color:var(--ink-2);max-width:56ch;
}

.hero .actions{margin-top:var(--s5);padding-top:0;}

/* La preuve chiffrée ferme le héros : elle est séparée par un vrai blanc, pas
   par le même écart que le reste. */
.hero-main > .trust,
.hero-main > .trust-bar{margin-top:var(--s6);}
.hero-main > .trust + .trust-bar{margin-top:0;}

@media (max-width:640px){
  .hero h1{max-width:none;}
  .hero .lede{font-size:var(--t-lg);margin-top:var(--s3);}
  .hero .actions{margin-top:var(--s4);}
  .hero-main > .trust,
  .hero-main > .trust-bar{margin-top:var(--s5);}
}


/* ------------------------------------------ 22.1b Panneau de preuve du héros
   Le héros tenait sur une colonne de 690 px dans un conteneur de 1128 : il
   restait 440 px de vide à droite du titre, sur chaque page, au-dessus de la
   ligne de flottaison. Ce panneau occupe ce vide avec ce qui manquait par
   ailleurs — les trois chiffres de l'entreprise (brief §5, jusqu'ici absents
   de toutes les pages commerciales) et le téléphone, invisible au grand format.

   Il ne porte AUCUN bouton : le seul appel à l'action du héros reste le bouton
   vert de gauche. Le panneau réassure, il ne réclame pas un deuxième clic.
   Sous 1040 px il se déplie sous le titre et redevient le bandeau horizontal
   d'origine — cadre, fond et texture disparaissent, seuls restent un filet et
   les chiffres.                                                              */
.hero-aside{
  position:relative;overflow:hidden;min-width:0;
  display:flex;flex-direction:column;gap:var(--s4);
}
.hero-aside > *:not(.hex-deco){position:relative;z-index:1;}
.hero-aside .hex-deco{--hex-opacity:.05;}

.hero-aside__label{
  font-family:var(--f-mono);font-size:var(--t-cap);letter-spacing:var(--ls-cap);
  text-transform:uppercase;color:var(--ink-3);
}
.hero-aside__tel{
  display:flex;flex-direction:column;gap:2px;
  text-decoration:none;color:var(--ink);
  min-height:var(--tap);justify-content:center;
  border-radius:var(--r-sm);
}
.hero-aside__tel-l{font-size:var(--t-sm);color:var(--ink-3);}
.hero-aside__tel-n{
  display:inline-flex;align-items:center;gap:var(--s2);
  font-family:var(--f-display);font-size:var(--t-xl);font-weight:600;
  letter-spacing:var(--ls-tight);color:var(--brand-ink);
  font-variant-numeric:tabular-nums;
}
.hero-aside__tel .ico{color:var(--brand-ink);}
.hero-aside__tel:hover .hero-aside__tel-n{text-decoration:underline;text-underline-offset:3px;}
.hero-aside__fine{font-size:var(--t-sm);color:var(--ink-3);}

/* Grand format : deux colonnes. Le panneau prend son cadre, sa texture et sa
   propre respiration ; les chiffres s'empilent, séparés par des filets.
   Le panneau prend le relais du téléphone : là où il s'affiche, la barre
   d'en-tête cesse de montrer le numéro (règle ci-dessous), et réciproquement.
   Jamais deux fois le même numéro dans le même écran. */
@media (min-width:1040px){
  .hero .wrap{
    display:grid;grid-template-columns:minmax(0,1fr) 306px;
    column-gap:var(--s7);align-items:start;
  }
  .hero-aside{
    border:1px solid var(--rule);border-radius:var(--r-lg);
    background:var(--surface-2);
    padding:var(--s5);gap:var(--s5);
    margin-top:var(--s2);
  }
  .hero-home .hero-aside{background:color-mix(in srgb,var(--surface) 72%,transparent);}
  .hero-aside .trust-bar{
    flex-direction:column;flex-wrap:nowrap;gap:0;
    border:0;padding:0;
  }
  .hero-aside .trust-bar li + li{
    margin-top:var(--s4);padding-top:var(--s4);
    border-top:1px solid var(--rule);
  }
  .hero-aside .trust-bar li + li::before{display:none;}
  .hero-aside__tel{
    border-top:1px solid var(--rule);padding-top:var(--s4);
  }
}

/* Format intermédiaire et mobile : le panneau redevient un bandeau. */
@media (max-width:1039px){
  .hero-aside{border-top:1px solid var(--rule);padding-top:var(--s5);gap:var(--s4);}
  .hero-aside .hex-deco,
  .hero-aside__label{display:none;}
  .hero-aside .trust-bar{border-top:0;padding-top:0;}
  .hero-aside__fine{display:none;}   /* déjà porté par le bandeau .trust */
  /* Le bas du héros d'accueil était calé (--s8) sur un héros SANS panneau.
     Le panneau replié ajoute une centaine de pixels : le même creux devient
     un trou entre le dernier chiffre et la section suivante. */
  .hero-home{padding-bottom:var(--s6);}
}
/* Le téléphone du panneau ne sert qu'au grand format. Dès 1150 px la barre
   d'en-tête affiche le numéro elle-même, et sous 700 px la barre d'action
   collante ajoute « Appeler » : le garder ici en ferait le deuxième, puis le
   troisième numéro du même écran. Il ne paraît donc que là où il manquait
   vraiment — au-dessus de 1040 px, dans le panneau. */
@media (max-width:1039px){
  .hero-aside__tel{display:none;}
}

/* Entre 1040 et 1150 px, la navigation est déjà repliée — donc la barre
   d'en-tête voudrait afficher le numéro — mais le panneau du héros le porte
   déjà. On le retire de la barre sur cette seule tranche : le numéro reste
   visible une fois, et une seule, au-dessus de la ligne de flottaison. */
@media (min-width:1040px) and (max-width:1150px){
  .header-tel{display:none;}
  /* C'est .header-tel qui portait le margin-left:auto poussant le groupe
     d'actions à droite. Il passe au bouton, qui devient le premier du groupe. */
  .site-header .header-cta{margin-left:auto;}
}
@media (max-width:640px){
  .hero .wrap{gap:var(--s5);}
  .hero-aside{padding-top:var(--s4);}
}


/* -------------------------------------- 22.2 Chapeau de réponse directe
   C'est le bloc que citent les moteurs de réponse : il doit se détacher sans
   crier. Il se détache donc par la matière (une surface pleine, une ombre
   courte, un filet bleu) et non par la couleur — aucun aplat teinté, aucun
   corps surdimensionné. L'étiquette est un vrai élément du document (voir
   build.py) : le contenu généré n'est ni citable ni sélectionnable.
     <div class="lede-answer">
       <p class="lede-answer__label">En bref</p>
       <div class="lede-answer__body">…</div>
     </div>                                                                   */
.lede-answer{
  display:flex;flex-direction:column;gap:var(--s2);
  background:var(--surface);
  border:1px solid var(--rule);
  border-left:3px solid var(--brand);
  border-radius:0 var(--r) var(--r) 0;
  padding:var(--s5);
  box-shadow:var(--shadow-sm);
}
.lede-answer__label{
  font-family:var(--f-mono);font-size:var(--t-cap);font-weight:500;
  letter-spacing:var(--ls-cap);text-transform:uppercase;
  color:var(--brand-ink);
}
.lede-answer__body{
  font-size:var(--t-lg);line-height:1.55;color:var(--ink);
  max-width:64ch;
}
.lede-answer__body p{color:inherit;}
.lede-answer__body p + p{margin-top:var(--s3);}
.lede-answer__body a{font-weight:600;}

/* Sur une bande claire (--surface), la surface pleine ne suffit plus à
   détacher le bloc : on repasse sur le fond de page. */
section.alt .lede-answer{background:var(--bg);}


/* --------------------------------------------- 22.2 bis Mesure de la colonne
   Le texte courant se lit à 68 caractères ; un tableau et un schéma, non. Le
   §7 appliquait déjà cette distinction aux pages sans barre latérale : elle
   vaut partout. La colonne prend donc toute sa largeur, et ce sont les blocs
   de TEXTE qui portent la mesure — un schéma ramené à 68 caractères de large
   voit sa typographie tomber sous le seuil de lisibilité. */
article.content{max-width:none;}
article.content > p,
article.content > ul,
article.content > ol,
article.content > dl:not(.glossary),
article.content > blockquote,
article.content > h2,
article.content > h3,
article.content > h4,
article.content > .lede-answer,
article.content > .callout{max-width:var(--prose);}


/* ------------------------------------------------------------ 22.3 Tableaux
   Trois problèmes, trois réponses :
     — on perd la tête de colonne au bas d'un long tableau → en-tête collant,
       posé par build.py (.table-scroll--long) au-delà de 8 lignes ;
     — on saute une ligne en lisant de gauche à droite → zébrure, très légère,
       obtenue par un voile d'encre et non par une couleur : elle fonctionne
       donc telle quelle dans les deux thèmes ;
     — on ne voit pas qu'un tableau défile → ombre portée sur le bord concerné,
       qui n'apparaît QUE s'il reste quelque chose à faire défiler de ce côté.
       Le mécanisme est celui des deux paires de dégradés : les voiles couleur
       de surface sont ancrés au contenu (local) et masquent l'ombre quand on
       est en butée, les ombres sont ancrées au conteneur (scroll). Aucun
       script n'intervient. */
article.content .table-scroll{
  background-color:var(--surface);
  background-image:
    linear-gradient(to right,var(--surface),color-mix(in srgb,var(--surface) 0%,transparent)),
    linear-gradient(to left, var(--surface),color-mix(in srgb,var(--surface) 0%,transparent)),
    linear-gradient(to right,rgb(var(--shadow-rgb)/calc(.22 * var(--shadow-k))),
                             color-mix(in srgb,var(--surface) 0%,transparent)),
    linear-gradient(to left, rgb(var(--shadow-rgb)/calc(.22 * var(--shadow-k))),
                             color-mix(in srgb,var(--surface) 0%,transparent));
  background-position:0 0,100% 0,0 0,100% 0;
  background-size:28px 100%,28px 100%,15px 100%,15px 100%;
  background-repeat:no-repeat;
  background-attachment:local,local,scroll,scroll;
}

/* Conteneur focusable (tabindex="0" posé par build.py) : sans cela, un tableau
   qui déborde est inatteignable au clavier. L'anneau de focus général suffit,
   on lui rend juste un peu d'air. */
article.content .table-scroll:focus-visible{outline-offset:2px;}

/* Zébrure : un voile d'encre à 3,5 %, appliqué aux cellules et non à la ligne,
   pour rester translucide — l'ombre de défilement doit passer au travers. */
article.content tbody tr:nth-child(even) td{
  background:color-mix(in srgb,var(--ink) 3.5%,transparent);
}

/* En-tête collant des tableaux longs. La bordure basse d'un thead collant
   décroche en border-collapse:collapse : c'est une ombre intérieure qui tient
   le filet. Le fond doit rester opaque, sinon les lignes défilent au travers. */
article.content .table-scroll--long{max-height:min(68vh,560px);}
article.content .table-scroll--long thead th{
  position:sticky;top:0;z-index:2;
  background:var(--surface-2);
  box-shadow:inset 0 -1px 0 var(--rule-strong);
}
article.content .table-scroll--long tbody tr:hover td{
  background:color-mix(in srgb,var(--brand) 9%,transparent);
}

/* Chiffres alignés : une colonne de prix ou de durées se compare à l'œil. */
article.content td,
article.content th{font-variant-numeric:tabular-nums;}


/* ------------------------------------------------------------ 22.4 Blocs FAQ
   Question en évidence : plus grande, en encre pleine, marquée d'une puce
   hexagonale. Réponse en retrait, sur une mesure de lecture. À partir de
   1000 px, question et réponse passent en deux colonnes — l'œil balaie alors
   la colonne de questions sans traverser les réponses. */
.faq{border-top:1px solid var(--rule);}
.faq-item{padding:var(--s6) 0;gap:var(--s3);}
.faq-item h3{
  position:relative;padding-left:var(--s5);
  font-size:var(--t-xl);color:var(--ink);
  letter-spacing:var(--ls-tight);text-wrap:balance;
}
.faq-item h3::before{
  content:"";position:absolute;left:0;top:.42em;
  width:10px;height:11px;
  background:var(--brand);
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
}
.faq-item p{font-size:var(--t-base);line-height:var(--lh-body);color:var(--ink-2);}

@media (min-width:1000px){
  .faq-item{
    display:grid;grid-template-columns:minmax(0,34%) minmax(0,1fr);
    gap:var(--s3) var(--s7);align-items:start;
  }
  .faq-item h3{grid-column:1;}
  .faq-item p{grid-column:2;max-width:64ch;}
}

@media (max-width:640px){
  .faq-item{padding:var(--s5) 0;}
  .faq-item h3{font-size:var(--t-lg);}
}


/* ------------------------------------------------------------- 22.5 Listings
   Une seule grammaire pour les trois listes : titre en tête, résumé en encre
   secondaire, métadonnées en mono, action explicite en bas. Ce qui change,
   c'est la densité — trois colonnes pour les expertises, une pile pour le
   blog, deux colonnes pour le glossaire. */

/* --- cartes (expertises, solutions, secteurs, pages liées) --- */
.card{padding:var(--s5);gap:var(--s2);}
.card .eyebrow{order:-1;}
.card h2,.card h3{font-size:var(--t-lg);letter-spacing:var(--ls-tight);text-wrap:balance;}
.card p{font-size:var(--t-md);line-height:1.6;}
/* L'action se décolle du résumé : un blanc, pas un filet — trois filets par
   rangée de cartes hacheraient la grille. */
.card .more{padding-top:var(--s3);}

/* --- lignes de blog --- */
.list-rows{border-top:1px solid var(--rule);margin:0;}
.list-row{
  grid-template-columns:minmax(0,1fr) auto;
  gap:var(--s2) var(--s5);
  padding:var(--s5) var(--s4);
  align-items:start;
  border-radius:var(--r);
}
.list-row h3{
  grid-column:1;grid-row:1;
  font-size:var(--t-xl);letter-spacing:var(--ls-tight);text-wrap:balance;
}
.list-row p{grid-column:1;grid-row:2;font-size:var(--t-base);max-width:68ch;}
.list-row .meta{
  grid-column:2;grid-row:1;justify-self:end;align-self:baseline;
  display:flex;flex-wrap:wrap;gap:var(--s2);align-items:baseline;
}
.list-row .meta-sep{color:var(--rule-strong);}
.list-row .more{
  grid-column:1;grid-row:3;
  display:inline-flex;align-items:center;gap:var(--s2);
  font-size:var(--t-md);font-weight:600;color:var(--brand-ink);
}
.list-row .more::after{content:"→";transition:transform .15s ease;}
a.list-row:hover .more::after{transform:translateX(3px);}
a.list-row:focus-visible{outline-offset:-2px;}

@media (max-width:640px){
  .list-row{padding:var(--s5) var(--s2);}
  .list-row h3{font-size:var(--t-lg);}
  .list-row .meta{grid-column:1;grid-row:2;justify-self:start;}
  .list-row p{grid-row:3;}
  .list-row .more{grid-row:4;}
}

/* --- glossaire ---
   Le terme et sa définition en deux colonnes : la colonne de gauche devient
   un index que l'œil descend sans lire les définitions. */
dl.glossary > div{padding:var(--s5) 0;gap:var(--s2);}
dl.glossary dt{font-size:var(--t-lg);letter-spacing:var(--ls-tight);}
dl.glossary dd{font-size:var(--t-base);color:var(--ink-2);max-width:70ch;}

@media (min-width:820px){
  dl.glossary > div{
    display:grid;grid-template-columns:minmax(0,28%) minmax(0,1fr);
    gap:var(--s2) var(--s6);align-items:baseline;
  }
}


/* --------------------------------------------------------- 22.6 Schémas SVG
   Deux schémas, dessinés à la géométrie hexagonale du symbole : le déroulé
   d'une mission et ce que Copilot peut voir. Ils expliquent un mécanisme —
   aucun n'est décoratif. Les fragments vivent dans build/tools/ et sont posés
   par le marqueur {{SCHEMA:nom}} (voir build.py).

   Chaque fragment porte DEUX tracés du même schéma : .schema__wide (frise
   horizontale) et .schema__tall (verticale). Un seul est affiché à la fois, en
   display:none — le tracé masqué sort donc aussi de l'arbre d'accessibilité, et
   un seul role="img" est exposé. La bascule se fait à 780 px : au-dessous, la
   colonne de texte ne fait plus assez de large pour que la frise horizontale
   reste lisible.

   Aucune couleur n'est écrite dans le SVG : les traits prennent currentColor
   (la couleur de l'élément, fixée ici à --brand), le reste passe par les
   classes .sc-*. Le schéma suit donc le thème sans une ligne de plus.        */
.schema{
  margin:0;
  display:flex;flex-direction:column;gap:var(--s4);
  padding:var(--s5);
  background:var(--surface);
  border:1px solid var(--rule);border-radius:var(--r);
}
section.alt .schema{background:var(--bg);}

.schema svg{width:100%;height:auto;color:var(--brand);}
/* Plafond de largeur : au-delà, la frise grossit sans rien gagner en clarté.
   La proportion vient du viewBox, il n'y a donc aucun saut de mise en page. */
.schema__wide{display:block;max-width:760px;margin-inline:auto;}
.schema__tall{display:none;max-width:400px;margin-inline:auto;}

@media (max-width:780px){
  .schema{padding:var(--s4);}
  .schema__wide{display:none;}
  .schema__tall{display:block;}
}

/* — vocabulaire graphique commun aux deux schémas —
   Chaque figure porte en plus son propre crochet (.schema--mission,
   .schema--copilot) : on peut donc régler un schéma sans toucher à l'autre,
   par exemple .schema--copilot .sc-desc{font-size:…}. Aucun n'en a besoin
   aujourd'hui — ils sont là pour que ce soit possible sans refonte. */
.sc-hex{fill:var(--brand-soft);stroke:currentColor;stroke-width:1.6;}
.sc-hex--strong{stroke-width:2.4;}
.sc-hex-alert{fill:var(--alert);}
.sc-box{fill:var(--surface-2);stroke:var(--rule);stroke-width:1;}
.sc-box--alert{fill:var(--alert-soft);stroke:color-mix(in srgb,var(--alert) 42%,transparent);}
.sc-line{fill:none;stroke:var(--rule-strong);stroke-width:1.5;}
.sc-hair{fill:none;stroke:var(--rule-strong);stroke-width:1;}
.sc-arrow{fill:var(--rule-strong);}

/* Textes. --ink-3 n'est validé AA que sur --bg et --surface : tout ce qui peut
   se retrouver dans un .sc-box (donc sur --surface-2) prend --ink-2. */
.sc-num{fill:var(--brand-ink);font-family:var(--f-mono);font-size:14px;font-weight:600;}
.sc-title{fill:var(--ink);font-family:var(--f-display);font-size:15px;font-weight:600;}
.sc-label{fill:var(--ink);font-family:var(--f-display);font-size:16px;font-weight:700;
          letter-spacing:var(--ls-tight);}
.sc-name{fill:var(--ink);font-family:var(--f-display);font-size:14px;font-weight:600;}
.sc-role{fill:var(--ink-2);font-family:var(--f-body);font-size:12px;}
.sc-desc{fill:var(--ink-2);font-family:var(--f-body);font-size:12.5px;}
.sc-fine{fill:var(--ink-2);font-family:var(--f-body);font-size:11.5px;}
.sc-note{fill:var(--ink-2);font-family:var(--f-body);font-size:11.5px;}
.sc-tag{fill:var(--ink-2);font-family:var(--f-mono);font-size:10.5px;letter-spacing:.07em;}
.sc-flag{fill:var(--ink-3);font-family:var(--f-mono);font-size:10.5px;letter-spacing:.03em;}
/* L'alerte n'est jamais portée par la seule couleur : le texte la dit aussi. */
.sc-alert{fill:var(--alert);font-family:var(--f-body);font-size:12.5px;font-weight:600;}
.sc-alert-fine{fill:var(--alert);font-family:var(--f-body);font-size:11.5px;}

.schema__cap{
  font-size:var(--t-sm);line-height:1.55;color:var(--ink-2);
  max-width:70ch;text-wrap:pretty;
}

/* Équivalent textuel. Un <details> : présent dans le document pour les moteurs
   et les lecteurs d'écran, ouvrable sans une ligne de JavaScript, et qui ne
   double pas visuellement le schéma pour qui le voit déjà. */
.schema-alt{
  border-top:1px solid var(--rule);
  padding-top:var(--s2);
  font-size:var(--t-md);color:var(--ink-2);
}
/* Le schéma a droit à toute la colonne, son équivalent textuel non : c'est du
   texte courant, il reprend la mesure de lecture. */
.schema-alt > *:not(summary){max-width:var(--prose);}
.schema-alt > summary{
  display:inline-flex;align-items:center;gap:var(--s2);
  min-height:var(--tap);
  list-style:none;cursor:pointer;
  font-family:var(--f-mono);font-size:var(--t-cap);font-weight:500;
  letter-spacing:var(--ls-cap);text-transform:uppercase;
  color:var(--brand-ink);
}
.schema-alt > summary::-webkit-details-marker{display:none;}
.schema-alt > summary::before{
  content:"";width:9px;height:10px;flex:0 0 auto;
  background:currentColor;
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
  transition:transform .15s ease;
}
.schema-alt[open] > summary::before{transform:rotate(90deg);}
.schema-alt > summary:hover{text-decoration:underline;text-underline-offset:3px;}
.schema-alt > *:not(summary){margin-top:var(--s3);}
.schema-alt ol,
.schema-alt ul{
  padding-left:1.4em;display:flex;flex-direction:column;gap:var(--s2);
}
.schema-alt li::marker{color:var(--brand);}
.schema-alt strong{color:var(--ink);}


/* ------------------------------------------ 22.7 Apparitions au défilement
   Fondu montant de 12 px, 450 ms, décalé de 60 ms d'un élément au suivant.

   RÈGLE INTANGIBLE : rien n'est masqué tant que le script d'apparition n'a pas
   posé LUI-MÊME .js-reveal sur <html> — pas .js, qui est posée dans le <head>
   avant tout rendu. Sans JavaScript, sans IntersectionObserver, ou sous
   prefers-reduced-motion, le script s'arrête avant de poser la classe et tout
   est visible d'emblée. Le §16 est vide pour cette raison.

   Deux marqueurs :
     .reveal         un bloc qui apparaît d'un seul tenant
     .reveal-group   chacun de ses enfants directs apparaît à son tour
   Jamais sur un appel à l'action : ni la barre latérale, ni la barre collante,
   ni le héros — masquer un bouton, même 450 ms, c'est perdre un clic.        */
.js-reveal .reveal,
.js-reveal .reveal-group > *{
  opacity:0;
  transform:translateY(12px);
  transition:opacity .45s ease,transform .45s ease;
  transition-delay:calc(var(--reveal-i,0) * 60ms);
}
.js-reveal .reveal.is-in,
.js-reveal .reveal-group > .is-in{opacity:1;transform:none;}

/* Décalage en cascade, plafonné à cinq crans (300 ms) : au-delà, la dernière
   carte d'une grille arriverait après que l'œil l'a déjà cherchée. */
.js-reveal .reveal-group > *:nth-child(2){--reveal-i:1;}
.js-reveal .reveal-group > *:nth-child(3){--reveal-i:2;}
.js-reveal .reveal-group > *:nth-child(4){--reveal-i:3;}
.js-reveal .reveal-group > *:nth-child(5){--reveal-i:4;}
.js-reveal .reveal-group > *:nth-child(n+6){--reveal-i:5;}

/* Double neutralisation : le script s'arrête déjà de lui-même sous mouvement
   réduit, mais un réglage changé en cours de session ne le relance pas. */
@media (prefers-reduced-motion:reduce){
  .js-reveal .reveal,
  .js-reveal .reveal-group > *{opacity:1;transform:none;transition:none;}
}


/* ==================================================== 23. === recette technique ===
   Lot de correction issu de la recette : contrastes réellement mesurés dans
   les deux thèmes, zones cliquables, filet de sécurité au clavier. Placé en
   fin de feuille pour trancher à spécificité égale. Aucune valeur littérale :
   tout passe par les jetons des §1–2, donc les deux thèmes suivent.

   Sommaire
     23.1  Boutons à contour : le filet EST le bouton (WCAG 1.4.11)
     23.2  Champs de formulaire hors .convform
     23.3  Séparateurs de méta
     23.4  Zones cliquables du pied de page
     23.5  Apparitions au défilement : filet de sécurité au focus
   ========================================================================== */


/* ------------------------------- 23.1 Boutons à contour : le filet EST le bouton
   Sur un bouton plein, la couleur de fond dessine la limite. Sur un bouton à
   contour, il n'y a que le filet : c'est lui, et lui seul, qui dit « ceci est
   un bouton ». WCAG 1.4.11 lui impose donc 3:1 sur le fond adjacent.

   Mesuré : --rule-strong donne 1,7:1 sur --surface et --rule 1,28:1 — le
   bouton secondaire était une zone de texte flottante. Le §22.3 avait déjà
   tiré cette conclusion pour les champs du formulaire de devis ; elle vaut
   pour les boutons. --ink-3 relève le filet à 4,6:1 en clair et 6,2:1 en
   sombre, sans toucher aux jetons ni à la hiérarchie : le bouton secondaire
   reste sans fond ni vert, il devient seulement visible.

   .cta-block .btn-ghost n'est pas concerné : sur l'aplat ardoise, son filet
   (--on-deep à 45 %) tient déjà 3,2:1. Sa règle du §20.3 reste en vigueur. */
.btn-ghost{border-color:var(--ink-3);}
.btn-quiet{border-color:var(--ink-3);}

/* Le survol ne perd rien : le filet bleu de --brand tient 3:1 sur --surface. */


/* ---------------------------------- 23.2 Champs de formulaire hors .convform
   Même raisonnement, même correction, mais généralisée : le §22.3 ne relevait
   le filet que sous .convform. Les champs du diagnostic et de toute page à
   venir gardaient 1,7:1. La règle passe au niveau de .form-field, et celle du
   §22.3 devient un doublon inoffensif. */
.form-field input,
.form-field select,
.form-field textarea{border-color:var(--ink-3);}
/* Le champ fautif garde sa couleur d'alerte : sa règle du §13 vient avant,
   on la rétablit ici à spécificité supérieure. */
.form-field input[aria-invalid="true"],
.form-field select[aria-invalid="true"],
.form-field textarea[aria-invalid="true"]{border-color:var(--alert);}


/* ------------------------------------------------- 23.3 Séparateurs de méta
   Le point médian des lignes de liste était posé en --rule-strong : 1,61:1 en
   clair, 2,12:1 en sombre. Il est marqué aria-hidden, donc hors du champ de
   1.4.3 — mais un séparateur qu'on ne voit pas ne sépare rien. --ink-3 le rend
   lisible (4,6:1) tout en le gardant secondaire par rapport aux méta. */
.list-row .meta-sep{color:var(--ink-3);}


/* ------------------------------------ 23.4 Zones cliquables du pied de page
   Les titres de colonne du plan de site sont des liens de 14 px de haut :
   sous les 24 px de la cible minimale (WCAG 2.5.8), et bien plus délicats
   encore au pouce. Le remplissage vertical élargit la cible sans déplacer
   quoi que ce soit — la marge négative rend au bloc la hauteur qu'il avait. */
.foot-col h2 a,
.foot-col ul a{
  display:inline-block;
  padding-block:5px;
  margin-block:-5px;
}


/* ----------------------- 23.5 Apparitions au défilement : filet de sécurité
   Un lien atteint au clavier dans un bloc pas encore entré dans le champ est
   à opacité 0 le temps que l'IntersectionObserver rende la main. Le navigateur
   le fait défiler, l'observateur suit, et tout rentre dans l'ordre — mais sur
   une frame ou deux le focus est posé sur du vide. :focus-within tranche
   avant l'observateur : ce qui reçoit le focus est visible, sans exception et
   sans attendre personne. */
.js-reveal .reveal:focus-within,
.js-reveal .reveal-group > *:focus-within{
  opacity:1;
  transform:none;
  transition:none;
}


/* ------------------------------------- 23.6 --ink-3 sur --surface-2 : 4,22:1
   Le §22.5 avait déjà relevé le cas pour la colonne de réassurance :
   --ink-3 tient AA sur --surface (4,8:1) et sur --bg (4,6:1), mais retombe à
   4,22:1 sur --surface-2 — sous le seuil. Le bandeau de confiance et le
   panneau latéral du héros sont posés sur --surface-2 : leurs étiquettes et
   leurs mentions y passent en --ink-2. Elles restent secondaires — c'est
   --ink-2, pas --ink — mais elles se lisent.

   Mesuré en sombre : --ink-3 (#7F97A6) sur --surface-2 (#1B2C39) donne 5,0:1,
   déjà conforme. La règle vaut donc surtout en clair, mais --ink-2 tient AA
   dans les deux thèmes : une seule règle, aucun bloc de thème supplémentaire. */
.hero-aside__label,
.hero-aside__tel-l,
.hero-aside__fine,
.trust-bar__l{color:var(--ink-2);}
