:root, [data-theme=light] {
  --bg: #ffffff;
  --bg-alt: #f6f7fb;
  --bg-deep: #0d1020;
  --card: #ffffff;
  --card-alt: #f9fafc;
  --border: rgba(15, 20, 40, .10);
  --border-strong: rgba(15, 20, 40, .18);
  --text: #12162a;
  --text-2: #4b5468;
  --muted: #666e82;
  --accent: #4f46e5;
  --accent-2: #06b6d4;
  --accent-soft: rgba(79, 70, 229, .10);
  --ok: #0d9488;
  --warn: #d97706;
  --err: #dc2626;
  /* --ok/--warn echouent en texte normal sur les 3 fonds clairs (3.74:1 /
     3.19:1 pour 4.5:1 requis) : ces variantes -text les cantonnent au texte
     (.chip--ok, .chip--wait, .cmp .yes), --ok/--warn restant reserves au
     decor (points, bordures, fonds de chip) ou le seuil AA ne s'applique pas. */
  --ok-text: #0b7d72;
  --warn-text: #a35e05;
  /* Mesure : sur un fond teinte a 10-12 % par la couleur d'etat (les blocs
     `.form-note`, WEB-16), --err rend 4.13:1 et --ok-text 4.34:1 — sous le
     seuil AA. Ces deux variantes sont calculees SUR CE FOND, pas sur --card. */
  --err-text: #b91c1c;
  --ok-text-soft: #0a6b62;
  --on-deep: #f2f4fb;
  --on-deep-2: #a6adc4;
  --shadow: 0 1px 2px rgba(15,20,40,.05), 0 8px 24px rgba(15,20,40,.06);
  --shadow-lg: 0 2px 4px rgba(15,20,40,.06), 0 24px 60px rgba(15,20,40,.12);
  --radius: 14px;
  --radius-sm: 9px;
  --maxw: 1160px;
}
[data-theme=dark] {
  --bg: #0a0c16;
  --bg-alt: #10131f;
  --bg-deep: #05060d;
  --card: #141826;
  --card-alt: #191d2c;
  --border: rgba(255,255,255,.08);
  --border-strong: rgba(255,255,255,.16);
  --text: #eef1f8;
  --text-2: #a3abc0;
  --muted: #7b849a;
  --accent: #7c73f0;
  --accent-2: #22d3ee;
  --accent-soft: rgba(124, 115, 240, .14);
  --err-text: #f87171;
  --ok-text-soft: #2dd4bf;
  --ok: #2dd4bf;
  --warn: #fbbf24;
  --err: #f87171;
  /* Deja conformes en texte sur les fonds sombres (9:1+) : les variantes
     -text reprennent --ok/--warn tels quels ici, seul le clair les corrige. */
  --ok-text: #2dd4bf;
  --warn-text: #fbbf24;
  --on-deep: #f2f4fb;
  --on-deep-2: #98a0b8;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
  --shadow-lg: 0 2px 4px rgba(0,0,0,.5), 0 24px 60px rgba(0,0,0,.5);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
/* Anneau de focus clavier explicite, absent des 0 occurrences precedentes du
   fichier : l'outline UA par defaut est quasi invisible sur .adm-sidebar et
   .ftr (fond --bg-deep). --accent conserve un contraste non-texte >= 3:1 sur
   les fonds clairs COMME sur --bg-deep (mesure : 3.0:1 en light, 4.68 a
   5.36:1 en dark) — un seul token suffit, pas de variante par fond. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { margin: 0; line-height: 1.15; letter-spacing: -.02em; font-weight: 640; }
p { margin: 0; }
img { max-width: 100%; display: block; }

.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.section { padding: 96px 0; }
.section--alt { background: var(--bg-alt); }
/* Section qui CONTINUE la precedente (meme sujet, pas de changement de fond) :
   ses 96px de haut feraient une rupture, mais `padding-top:0` pose en inline —
   le motif qu'on remplace ici — colle le titre au bloc du dessus. 48px = la
   moitie du pas normal : la suite se lit comme une suite, sans que le titre
   touche le bloc precedent. Une CLASSE et pas de l'inline, sinon corriger une
   section rend les autres incoherentes sur la meme page. */
.section--suite { padding-top: 48px; }

/* ---------- Header ---------- */
.hdr {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
}
.hdr__in { display: flex; align-items: center; gap: 28px; height: 68px; }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 680; letter-spacing: -.02em; font-size: 17px; }
.brand__mark {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  display: grid; place-items: center; color: #fff; font-size: 14px; font-weight: 800;
}
.nav { display: flex; gap: 4px; margin-left: auto; align-items: center; }
.nav a {
  padding: 8px 13px; border-radius: 8px; font-size: 14.5px; color: var(--text-2);
  font-weight: 500; transition: background .15s, color .15s;
}
.nav a:hover { background: var(--accent-soft); color: var(--text); }
.nav a.is-active { color: var(--accent); font-weight: 600; }
.hdr__cta { margin-left: 10px; }
/* Menu mobile — `<details>` natif, aucun script (WEB-18).
   `.mnav.is-open` attendait un JS qui n'a jamais ete porte : c'est
   `details[open]` qui ouvre desormais, et le navigateur tient `aria-expanded`,
   le clavier et Echap a notre place. */
.mnav-wrap { display: none; margin-left: auto; position: relative; }
.burger {
  display: grid; place-items: center;
  background: none; border: 1px solid var(--border-strong);
  border-radius: 9px; width: 40px; height: 38px; color: var(--text); font-size: 17px; cursor: pointer;
  /* Le marqueur natif du <summary> (triangle) n'a pas sa place dans un burger. */
  list-style: none;
}
.burger::-webkit-details-marker { display: none; }
.burger::marker { content: ""; }
.burger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Le tiroir sort du flux pour couvrir toute la largeur sous l'en-tete : dans
   le flux, il serait un troisieme element du `.hdr__in` en flex, coince entre
   le logo et le bord. `.hdr` etant `position: sticky`, il fait deja contexte
   de positionnement. */
.mnav {
  position: absolute; top: calc(100% + 11px); right: -24px; left: auto;
  min-width: 240px; z-index: 60;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); box-shadow: var(--shadow-lg);
  /* `overflow: hidden` seul (pour le `border-radius`) rendait le tiroir plus
     haut que certains viewports sans moyen d'y acceder : en paysage mobile, la
     derniere entree tombait hors ecran et le scroll de la page ne la ramenait
     pas. Borne + defilement interne sur l'axe vertical.
     `100dvh` et non `100vh` : sur mobile, `vh` ignore la barre d'URL. */
  max-height: calc(100dvh - 90px);
  overflow: hidden auto;
}
.mnav a { display: block; padding: 13px 20px; border-bottom: 1px solid var(--border); font-weight: 500; }
.mnav a:last-child { border-bottom: 0; }
.mnav a.is-active { color: var(--accent); font-weight: 640; }
/* `.mnav a.mnav__cta` et non `.mnav__cta` seul : `.mnav a` (0,1,1) pose
   `font-weight: 500` et gagnerait contre une classe seule (0,1,0), quel que
   soit l'ordre dans le fichier. Le voisin `.mnav a.is-active` obtenait bien ses
   640, ce qui rendait l'ecrasement invisible a la lecture. */
.mnav a.mnav__cta { color: var(--accent); font-weight: 640; background: var(--accent-soft); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 22px; border-radius: 10px; font-weight: 600; font-size: 15px;
  border: 1px solid transparent; cursor: pointer; transition: transform .12s, box-shadow .18s, background .15s;
  font-family: inherit; white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn--primary { background: var(--accent); color: #fff; box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 32%, transparent); }
.btn--primary:hover { background: color-mix(in srgb, var(--accent) 88%, #000); }
/* En theme sombre, blanc sur --accent (#7c73f0) ne fait que 3.77:1 pour 4.5:1
   requis : le bouton principal echouait AA. --bg dark (#0a0c16) sur le meme
   fond donne 5.17:1 — un token deja dans la palette, pas une couleur ajoutee. */
[data-theme=dark] .btn--primary { color: var(--bg); }
.btn--ghost { background: transparent; color: var(--text); border-color: var(--border-strong); }
.btn--ghost:hover { background: var(--accent-soft); border-color: var(--accent); }
.btn--light { background: #fff; color: #12162a; }
.btn--outline-light { background: transparent; color: var(--on-deep); border-color: rgba(255,255,255,.28); }
.btn--outline-light:hover { background: rgba(255,255,255,.08); }
.btn--sm { padding: 9px 16px; font-size: 14px; }
.btn--lg { padding: 15px 30px; font-size: 16px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; transform: none; }

/* ---------- Typo helpers ---------- */
.eyebrow {
  font-size: 12.5px; font-weight: 680; letter-spacing: .10em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 14px;
}
.h1 { font-size: clamp(36px, 5.2vw, 60px); font-weight: 700; letter-spacing: -.035em; }
.h2 { font-size: clamp(28px, 3.6vw, 42px); letter-spacing: -.03em; }
.h3 { font-size: 21px; }
.h4 { font-size: 17px; }
.lead { font-size: clamp(17px, 1.6vw, 19.5px); color: var(--text-2); line-height: 1.62; }
.small { font-size: 14px; color: var(--text-2); }
.tiny { font-size: 12.8px; color: var(--muted); }
.center { text-align: center; }
.mx-auto { margin-left: auto; margin-right: auto; }
.mw-720 { max-width: 720px; }
.mw-620 { max-width: 620px; }
.mt-8 { margin-top: 8px; } .mt-14 { margin-top: 14px; } .mt-20 { margin-top: 20px; }
.mb-20 { margin-bottom: 20px; }
.mt-28 { margin-top: 28px; } .mt-40 { margin-top: 40px; } .mt-56 { margin-top: 56px; }

/* ---------- Hero ---------- */
.hero { position: relative; overflow: hidden; padding: 92px 0 84px; }
.hero::before {
  content: ''; position: absolute; inset: -40% 50% auto -20%; height: 720px;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 22%, transparent), transparent);
  filter: blur(10px); pointer-events: none;
}
.hero::after {
  content: ''; position: absolute; inset: -30% -25% auto 45%; height: 640px;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent-2) 18%, transparent), transparent);
  pointer-events: none;
}
.hero__in { position: relative; z-index: 1; display: grid; grid-template-columns: 1.06fr .94fr; gap: 60px; align-items: center; }
.pill {
  display: inline-flex; align-items: center; gap: 9px; padding: 7px 15px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--border-strong); font-size: 13.5px;
  font-weight: 550; color: var(--text-2); box-shadow: var(--shadow); margin-bottom: 26px;
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 22%, transparent); }
.hero__cta { display: flex; gap: 13px; flex-wrap: wrap; margin-top: 34px; }
.hero__note { margin-top: 18px; font-size: 13.5px; color: var(--muted); }

/* ---------- Visual panel ---------- */
.panel {
  background: var(--card); border: 1px solid var(--border); border-radius: 18px;
  box-shadow: var(--shadow-lg); overflow: hidden;
}
.panel__bar {
  display: flex; align-items: center; gap: 8px; padding: 12px 16px;
  border-bottom: 1px solid var(--border); background: var(--card-alt);
}
.panel__dots { display: flex; gap: 6px; }
.panel__dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--border-strong); display: block; }
.panel__title { font-size: 13px; color: var(--muted); font-weight: 550; margin-left: 6px; }
.panel__body { padding: 18px; display: grid; gap: 11px; }

.tile {
  display: flex; align-items: center; gap: 13px; padding: 13px 15px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card-alt);
}
.tile__ico {
  width: 34px; height: 34px; border-radius: 9px; flex: none; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-size: 15px;
}
.tile__t { font-weight: 600; font-size: 14.5px; }
.tile__s { font-size: 12.8px; color: var(--muted); }
.tile__right { margin-left: auto; }

.chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 620; letter-spacing: .01em;
}
.chip--ok { background: color-mix(in srgb, var(--ok) 15%, transparent); color: var(--ok-text); }
.chip--run { background: var(--accent-soft); color: var(--accent); }
.chip--wait { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn-text); }
.chip--neutral { background: var(--bg-alt); color: var(--text-2); border: 1px solid var(--border); }

/* ---------- Grids & cards ---------- */
.grid { display: grid; gap: 22px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
/* Calendrier de /rendez-vous : sept jours, la ou la maquette figee n'en
   montrait que cinq. Les colonnes se resserrent avant de passer a la ligne. */
.grid--semaine { display: grid; gap: 12px; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 26px; box-shadow: var(--shadow); transition: transform .18s, box-shadow .18s, border-color .18s;
}

/* Boutons d'action alignes d'une carte a l'autre.
 *
 * Les cartes d'une meme grille ont des textes de longueurs differentes : sans
 * cette regle, chaque bouton se pose juste sous SON texte, et deux cartes
 * cote a cote presentent leurs actions a deux hauteurs differentes.
 *
 * `align-items: stretch` (defaut de la grille) donne deja aux cartes la meme
 * HAUTEUR ; ce qui manquait etait de pousser le dernier bloc vers le bas de
 * cette hauteur. Le blanc apparait alors entre le texte et le bouton, ce qui
 * est le compromis explicitement demande plutot que des actions decalees.
 *
 * `:last-child` plutot qu'une classe dediee : le bloc d'action est toujours le
 * dernier enfant de la carte, et une carte SANS bouton n'est pas affectee —
 * `margin-top: auto` sur un dernier bloc de texte ne le deplace pas
 * visuellement puisqu'il n'y a rien apres lui.
 *
 * `:not(.case)` exclut les vignettes de `/realisations`, qui portent un
 * `style="display:grid"` EN LIGNE : un style inline gagne sur la feuille, donc
 * `display:flex` y serait ignore pendant que `margin-top:auto` s'appliquerait
 * quand meme — la vignette serait etiree sans que la regle qui l'explique soit
 * active. Mieux vaut ne pas les viser du tout. */
.grid > .card--hover:not(.case) { display: flex; flex-direction: column; }
.grid > .card--hover:not(.case) > :last-child { margin-top: auto; }
.card--hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--border-strong); }
.card__ico {
  width: 42px; height: 42px; border-radius: 11px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-size: 19px; margin-bottom: 16px;
}
.card__t { font-size: 17.5px; font-weight: 640; margin-bottom: 8px; }
.card__d { font-size: 14.8px; color: var(--text-2); line-height: 1.6; }

/* ---------- En-tete de carte de formule (WEB-36) — variante retenue ----------
   Arbitrage humain : icone et titre en vis-a-vis. Le badge garde exactement sa
   place (premier element de la carte) mais repasse en neutre pour ne plus
   rivaliser en couleur avec le bouton d'action ; la pastille d'icone vient se
   mettre en vis-a-vis du titre, qui monte a 21px. Contrainte non negociable :
   le traitement est STRICTEMENT le meme pour les deux formules — deux
   besoins, jamais deux gammes. */
.fhead { display: grid; }
.fhead--duo {
  grid-template-columns: auto minmax(0, 1fr); gap: 16px; align-items: center;
  margin: 16px 0 20px;
}
.fhead--duo .fhead__tile {
  width: 48px; height: 48px; border-radius: 13px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-size: 21px;
}
.fhead--duo .fhead__t { font-size: 21px; font-weight: 660; letter-spacing: -.02em; line-height: 1.25; }

/* ---------- Steps ---------- */
.steps { display: grid; gap: 20px; grid-template-columns: repeat(3, 1fr); counter-reset: st; row-gap: 34px; }
.step { position: relative; padding-top: 20px; }
.step__n {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: #fff; font-weight: 700; font-size: 14.5px; margin-bottom: 15px;
}
.step__line { position: absolute; top: 37px; left: 42px; right: -20px; height: 2px; background: var(--border); }
/* Le trait relie deux etapes CONSECUTIVES d'une meme ligne : il s'arrete donc
   en fin de rangee (3n) autant qu'a la derniere etape. Sans la regle `3n`,
   l'etape 3 tendrait un trait vers une case vide a sa droite. */
.step:nth-child(3n) .step__line, .step:last-child .step__line { display: none; }

/* ---------- Compare table ---------- */
.cmp { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.cmp th, .cmp td { padding: 15px 20px; text-align: left; font-size: 14.8px; border-bottom: 1px solid var(--border); vertical-align: top; }
.cmp thead th { background: var(--card-alt); font-size: 13px; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); font-weight: 680; }
.cmp tbody tr:last-child td { border-bottom: none; }
.cmp .yes { color: var(--ok-text); font-weight: 640; }
.cmp .no { color: var(--muted); }
.cmp col.hl { background: var(--accent-soft); }

/* ---------- Pricing ---------- */
.price {
  background: var(--card); border: 2px solid var(--accent); border-radius: 18px; padding: 36px;
  box-shadow: var(--shadow-lg); position: relative;
}
.price__tag {
  position: absolute; top: -13px; left: 36px; background: var(--accent); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 5px 14px; border-radius: 999px;
}
.price__amount { font-size: 42px; font-weight: 700; letter-spacing: -.03em; }
.list { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
.list li { display: flex; gap: 11px; align-items: flex-start; font-size: 15px; color: var(--text-2); }
.list li::before { content: '✓'; color: var(--ok); font-weight: 800; flex: none; line-height: 1.55; }

/* ---------- Cases ---------- */
.case { display: grid; grid-template-columns: 1fr; overflow: hidden; padding: 0; }
.case__head { padding: 26px 26px 0; }
.case__logo {
  height: 40px; width: 40px; border-radius: 10px; display: grid; place-items: center;
  font-weight: 800; color: #fff; font-size: 15px; margin-bottom: 15px;
}
.case__body { padding: 18px 26px 26px; }
.case__metrics { display: flex; gap: 26px; flex-wrap: wrap; padding: 17px 26px; border-top: 1px solid var(--border); background: var(--card-alt); }
.metric__v { font-size: 20px; font-weight: 700; letter-spacing: -.02em; }
.metric__l { font-size: 12.5px; color: var(--muted); }
.tags { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 15px; }

/* ---------- FAQ ---------- */
.faq { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); overflow: hidden; }
.faq__item + .faq__item { border-top: 1px solid var(--border); }
/* `.faq__q` est un `<summary>` depuis WEB-18 : les `<button>` qui le
   precedaient etaient inertes faute du script jamais porte, et `+` ne devenait
   jamais `−`. Le marqueur natif est neutralise, l'etat ouvert vient de
   `[open]` et non d'une classe posee en JS. */
.faq__q {
  width: 100%; background: none; border: none; text-align: left; padding: 21px 24px; cursor: pointer;
  font-size: 16.5px; font-weight: 600; color: var(--text); display: flex; gap: 16px;
  align-items: center; justify-content: space-between; font-family: inherit;
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::marker { content: ""; }
.faq__q:hover { background: var(--card-alt); }
.faq__q:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.faq__sign { flex: none; color: var(--accent); font-size: 21px; font-weight: 400; transition: transform .2s; }
.faq__item[open] .faq__sign { transform: rotate(45deg); }
.faq__a { padding: 0 24px 22px; font-size: 15.2px; color: var(--text-2); line-height: 1.65; max-width: 800px; }

/* ---------- Form ---------- */
.field { display: grid; gap: 7px; margin-bottom: 17px; }
.field label { font-size: 13.8px; font-weight: 600; color: var(--text-2); }
/* .field est aussi pose sur <fieldset> (groupes de .radio-card, cf.
   contact.html) pour donner un nom accessible au groupe via <legend> plutot
   qu'un <label> orphelin sans `for` : neutralise le style natif du navigateur
   (bordure, padding) et aligne <legend> sur le rendu de .field label. */
fieldset.field { border: none; padding: 0; margin-left: 0; margin-right: 0; }
.field legend { font-size: 13.8px; font-weight: 600; color: var(--text-2); padding: 0; }
/* `:not([type=radio]):not([type=checkbox])` : ces deux-la ne sont pas des
   champs de saisie a habiller. Sans l'exclusion, un radio herite de
   `width: 100%` — et un radio masque hors ecran (`.radio-input`) prend alors
   toute la largeur du viewport, ce qui a fait deborder /contact de 435px. */
.field input:not([type="radio"]):not([type="checkbox"]),
.field select,
.field textarea {
  padding: 12px 14px; border-radius: 10px; border: 1px solid var(--border-strong);
  background: var(--bg); color: var(--text); font-size: 15px; font-family: inherit; width: 100%;
}
.field input:not([type="radio"]):not([type="checkbox"]):focus,
.field select:focus,
.field textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.field textarea { min-height: 118px; resize: vertical; }
.field .err { font-size: 12.8px; color: var(--err); }
.radio-grid { display: grid; gap: 10px; grid-template-columns: repeat(2, 1fr); }
/* L'input reste dans le flux (pas de `display:none`, qui le retirerait de la
   navigation clavier et du calcul de nom accessible) mais invisible : c'est le
   <label> adjacent qui porte tout le rendu. */
.radio-input {
  position: absolute; width: 1px; height: 1px; margin: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.radio-card {
  display: block;
  border: 1px solid var(--border-strong); border-radius: 10px; padding: 13px 15px; cursor: pointer;
  font-size: 14.5px; font-weight: 550; transition: border-color .15s, background .15s;
}
.radio-card:hover { border-color: var(--accent); }
/* Etat selectionne : porte par `:checked` et non par une classe posee en JS. */
.radio-input:checked + .radio-card {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 640;
}
/* Le focus doit se voir sur le label, l'input etant invisible. */
.radio-input:focus-visible + .radio-card {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.radio-card__d { display: block; font-size: 12.8px; font-weight: 450; color: var(--text-2); margin-top: 5px; }

/* ---------- Retour de formulaire (WEB-16) ---------- */
/* Le resultat d'une soumission est rendu par le SERVEUR, apres redirection
   (succes) ou re-rendu (erreurs) : aucun script n'affiche ces blocs. */
.form-note { border-radius: 10px; padding: 14px 16px; font-size: 14.5px; line-height: 1.55; }
.form-note--ok {
  border: 1px solid color-mix(in srgb, var(--ok) 45%, var(--border));
  background: color-mix(in srgb, var(--ok) 12%, var(--card));
  color: var(--ok-text-soft);
}
.form-note--err {
  border: 1px solid color-mix(in srgb, var(--err) 45%, var(--border));
  background: color-mix(in srgb, var(--err) 10%, var(--card));
  color: var(--err-text);
}
.form-note__list { margin: 8px 0 0; padding-left: 18px; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--err); }

/* ---------- Creneaux de rendez-vous (WEB-16) ---------- */
/* Un creneau est un radio dans le formulaire : c'est ce qui permet de choisir
   sans JS et de transmettre la valeur au submit. Un creneau pris ou hors plage
   n'a pas d'input du tout — il n'est pas selectionnable, donc pas focusable. */
.slot-input:checked + .slot {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 640;
}
.slot-input:focus-visible + .slot { outline: 2px solid var(--accent); outline-offset: 2px; }
.slot {
  display: block; text-align: center; cursor: pointer;
  padding: 8px 0; border-radius: 8px; border: 1px solid var(--border-strong);
  font-size: 13.5px; font-weight: 550; transition: border-color .15s, background .15s;
}
.slot:hover { border-color: var(--accent); }
.slot--taken {
  cursor: not-allowed; color: var(--muted); border-style: dashed;
  text-decoration: line-through; font-weight: 450;
}
.slot--off { border: 0; color: var(--muted); font-weight: 450; }

/* ---------- Footer ---------- */
.ftr { background: var(--bg-deep); color: var(--on-deep); padding: 62px 0 30px; }
.ftr a { color: var(--on-deep-2); font-size: 14.5px; }
.ftr a:hover { color: var(--on-deep); }
.ftr__cols { display: grid; grid-template-columns: 1.7fr 1fr 1fr 1fr; gap: 40px; }
.ftr__cols--legal { grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr; }
.ftr__col h5 { font-size: 12.5px; text-transform: uppercase; letter-spacing: .09em; color: var(--muted); margin: 0 0 15px; font-weight: 680; }
.ftr__links { display: grid; gap: 10px; }
.ftr__bottom {
  margin-top: 44px; padding-top: 24px; border-top: 1px solid rgba(255,255,255,.09);
  display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; font-size: 13.2px; color: var(--muted);
}

/* ---------- Banner CTA ---------- */
.cta-band {
  background: linear-gradient(120deg, var(--accent), var(--accent-2));
  border-radius: 20px; padding: 52px 46px; color: #fff; text-align: center;
}
.cta-band .h2 { color: #fff; }
.cta-band p { color: rgba(255,255,255,.9); }

/* ---------- Misc ---------- */
.divider { height: 1px; background: var(--border); border: none; margin: 0; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 10px 18px; font-size: 14.8px; }
.kv dt { color: var(--muted); }
.kv dd { margin: 0; color: var(--text); font-weight: 550; }
/* `.kv-libre` : un `dd` qui porte du TEXTE LIBRE, non maitrise — le message
   d'une demande, le sujet d'un rendez-vous, le corps d'une notification et sa
   derniere erreur. Une piste `1fr` de grid a `min-width: auto`, donc son
   minimum est le min-content du contenu : pour un texte, sa plus longue suite
   sans espace. Mesure, viewport 390 px, un `dd` de 800 caracteres sans
   espace : `scrollWidth` du document 8 679 px sans la regle, 390 px avec.
   `break-word` seul ne suffit pas — c'est bien le minimum automatique de la
   piste qui decide.

   SUR UNE CLASSE ET PAS SUR `.kv dd`, parce que cette feuille est PARTAGEE
   par la vitrine et le back-office : `.kv` est porte par douze `<dl>`, dont
   quatre sur la vitrine (`contact.html`, et trois fois `legal-mentions.html`).
   Mesure a 390 px sur `/mentions-legales` : la regle globale faisait passer la
   colonne des libelles de 159 a 182 px et celle des valeurs de 111 a 88, et
   `contact@creep-studio.com` y gagnait une ligne et demie. Pas un bug — un
   changement de mise en page sur la page qui porte l'identite legale, obtenu
   comme effet de bord d'un correctif de back-office. Releve en relecture. */
.kv dd.kv-libre { overflow-wrap: anywhere; }
.note {
  border-left: 3px solid var(--accent); background: var(--accent-soft);
  padding: 15px 19px; border-radius: 0 10px 10px 0; font-size: 14.8px; color: var(--text-2);
}
.toast {
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%);
  background: var(--bg-deep); color: #fff; padding: 13px 22px; border-radius: 11px;
  box-shadow: var(--shadow-lg); font-size: 14.5px; z-index: 100; font-weight: 550;
}

/* ---------- Dispositif (infra, staging, retours, suivi) ---------- */
.disp { display: grid; gap: 22px; grid-template-columns: repeat(2, 1fr); margin-top: 52px; }
.disp__card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 28px; box-shadow: var(--shadow); display: flex; flex-direction: column;
}
.disp__ico {
  width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent); font-size: 21px; margin-bottom: 17px;
}
.disp__t { font-size: 19px; font-weight: 640; margin-bottom: 9px; }
.disp__d { font-size: 15px; color: var(--text-2); line-height: 1.62; }
.disp__points { list-style: none; padding: 0; margin: 18px 0 0; display: grid; gap: 10px; }
.disp__points li { display: flex; gap: 10px; font-size: 14.4px; color: var(--text-2); line-height: 1.55; }
.disp__points li::before { content: '✓'; color: var(--ok); font-weight: 800; flex: none; }
.disp__note {
  margin-top: 18px; padding-top: 15px; border-top: 1px solid var(--border);
  font-size: 13.6px; color: var(--muted); line-height: 1.55; font-style: italic;
}

/* ---------- Roadmap (3 colonnes de suivi) ---------- */
.road { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 44px; }
.road__col { background: var(--card-alt); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; }
.road__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.road__label { font-size: 13px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-2); }
.road__count {
  font-size: 12px; font-weight: 700; color: var(--muted); background: var(--bg);
  border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px;
}
.road__items { display: grid; gap: 11px; }
.road__item { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 13px 15px; }
.road__item--done { opacity: .82; }
.road__t { font-size: 14.6px; font-weight: 600; line-height: 1.4; }
.road__meta { font-size: 12.6px; color: var(--muted); margin-top: 5px; }

/* ---------- Beta (programme de lancement) ---------- */
.beta {
  border: 2px solid var(--accent); border-radius: 18px; padding: 34px;
  background: var(--card); box-shadow: var(--shadow-lg); position: relative;
}
.beta__badge {
  position: absolute; top: -13px; left: 34px; background: var(--accent); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 5px 14px; border-radius: 999px;
}
.beta__cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; margin-top: 26px; }
.beta__col { background: var(--card-alt); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; }
.beta__colt { font-weight: 640; font-size: 15.5px; display: flex; gap: 9px; align-items: center; margin-bottom: 13px; }
.beta__items { list-style: none; padding: 0; margin: 0; display: grid; gap: 9px; }
.beta__items li { font-size: 14.2px; color: var(--text-2); line-height: 1.55; padding-left: 15px; position: relative; }
.beta__items li::before { content: '·'; position: absolute; left: 3px; font-weight: 800; color: var(--muted); }
.perks { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; margin-top: 26px; }
.perk { border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; background: var(--card-alt); }
.perk__ico { font-size: 21px; margin-bottom: 11px; }
.perk__t { font-weight: 640; font-size: 15.5px; margin-bottom: 7px; }
.perk__d { font-size: 14px; color: var(--text-2); line-height: 1.58; }
.beta__places {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border);
  font-size: 14.2px; color: var(--text-2);
  display: flex; gap: 10px 12px; align-items: center; flex-wrap: wrap;
}
.beta__places > span { flex: 1 1 auto; min-width: 0; }

/* Colonnes principal/secondaire. En classe et non en style inline : un inline
   n'est surchargeable par aucune media query, et la page deborde en mobile. */
.grid--aside { grid-template-columns: 1.1fr .9fr; gap: 40px; align-items: start; }
/* pages/contact.html : colonne principale plus large que le defaut. Meme
   piege corrige que .grid--aside — un ratio different reste une CLASSE,
   jamais un style="grid-template-columns:…" qui echapperait a la media query
   qui remet 1 colonne sous 760px (cf. .grid--2, .grid--3… plus bas). */
.grid--aside--wide { grid-template-columns: 1.55fr .85fr; }
/* pages/admin-template-detail.html : code MJML / apercu du rendu cote a cote.
   Meme piege : un grid-template-columns inline echappait a la media query et
   l'apercu e-mail (largeur fixe 380px, cf. commentaire de EmailPreview plus
   bas) debordait horizontalement a 375px. */
.tpl-split { display: grid; grid-template-columns: 1.2fr 1fr; gap: 0; }

/* ---------- Back-office : shell (sidebar DS + header + profil DS) ---------- */
/* La sidebar (.cs-sidebar, 230px) et le menu profil (.cs-profile-menu) sont le
   composant du design system creep-ds (assets/ds/creep-ds/*.js,
   tokens.css) : ce bloc ne pose plus que la mise en page LOCALE autour d'eux —
   le slot mobile, le header, la largeur consommee par .adm-actionbar. */
.adm-shell { display: flex; min-height: 100vh; }
.adm-sidebar-slot { flex: none; display: contents; }
.adm-main { flex: 1 1 auto; min-width: 0; }

/* Le back-office n'est pas une page de lecture : il n'a pas de raison d'etre
   plafonne a --maxw (1160px), une largeur choisie pour le confort de lecture du
   site public. La sidebar prend deja 220px ; sur un ecran large le contenu
   restait tasse au centre. Le .wrap des pages admin s'etend donc a toute la
   largeur disponible. Le site public n'est pas touche. */
.adm-main .wrap { max-width: none; }

/* Le back-office assume un aspect plus severe que la page commerciale : 14px
   d'arrondi y font decoratif sur des surfaces de travail denses. Les boutons et
   les champs gardent le rayon commun — seules les CARTES sont concernees. */
.adm-main .card { border-radius: 8px; }

/* Dans l'admin, la liste porte l'information et le panneau lateral n'est qu'un
   detail : 1.1fr/.9fr comprimait la liste presque a egalite. */
.adm-main .grid--aside { grid-template-columns: minmax(0, 1.9fr) minmax(0, .8fr); }

/* En dessous de 1100px les deux colonnes ne tiennent plus : la liste devenait
   illisible avant que le panneau ne cede. Empilement, liste d'abord. */
@media (max-width: 1100px) {
  .adm-main .grid--aside { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}

/* ---------- Back-office : barre d'actions fixe (pages de detail) ---------- */
/* `fixed`, PAS `sticky` : sticky ne colle que si la page defile, or sur un ecran
   haut le contenu tient en entier et la barre se retrouvait en fin de flux, au
   milieu du vide. Caler a gauche sur la sidebar DS (230px, .cs-sidebar) pour
   rester dans la zone de travail ; en mobile la sidebar sort du flux, la barre
   reprend toute la largeur. z-index 65 : sous .cs-sidebar mobile (70, doit
   passer devant une fois ouverte) ET sous .cs-profile-menu__panel (120, valeur
   du DS). Le site public ne consomme jamais cette classe — aucun conflit avec
   .toast (100) ni .consent-banner (200). */
.adm-actionbar {
  position: fixed; left: 230px; right: 0; bottom: 0; z-index: 65;
  display: flex; align-items: center; gap: 10px;
  padding: 16px 24px;
  background: var(--card); border-top: 1px solid var(--border); box-shadow: var(--shadow-lg);
}
/* Retrait sous le contenu de TOUTES les pages admin : sans lui, la barre fixe
   masquerait la fin d'un formulaire. Inoffensif sur les pages sans barre — c'est
   du vide en bas de page — et ca evite un selecteur conditionnel fragile. */
.adm-main .wrap { padding-bottom: 104px; }
@media (max-width: 560px) { .adm-actionbar { left: 0; } }

/* ---------- Back-office : barre de filtres sur une ligne ---------- */
/* Les filtres a selection multiple utilisent desormais `Select`/`MultiSelect`
   du DS (.cs-ms-*, tokens.css) — cette regle ne pose plus que l'alignement du
   conteneur qui les recoit. */
.adm-filterbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.adm-filterbar__search { flex: 1 1 220px; min-width: 180px; }

.adm-header {
  border-bottom: 1px solid var(--border); background: var(--card);
  display: flex; align-items: center; gap: 16px; height: 60px; padding: 0 24px;
}
.adm-header__toggle {
  display: none; background: none; border: 1px solid var(--border-strong); border-radius: 9px;
  width: 36px; height: 34px; color: var(--text); font-size: 16px; cursor: pointer; flex: none;
}
.adm-header__title { font-weight: 640; font-size: 15px; }
.adm-header__profile { margin-left: auto; }

/* Les ecrans d'admin composent leurs lignes en flex avec des colonnes de
   largeur fixe posees en INLINE. Un inline ne se surcharge pas ; ces regles
   agissent donc sur le CONTENEUR (wrap) plutot que sur les colonnes. */
.adm-row { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.adm-scroll { overflow-x: auto; max-width: 100%; min-width: 0; -webkit-overflow-scrolling: touch; }

/* Seuil BAS volontairement : la sidebar DS fait 230px et tient largement
   au-dessus. A 640px elle se repliait dans l'iframe etroite du viewer de
   maquettes, ou elle paraissait absente alors que la page etait correcte.
   `.adm-shell--nav-open` (posee par AdminShell) pilote le hors-ecran : la
   sidebar DS elle-meme n'a pas de mode off-canvas, seul `collapsed` (rail
   d'icones) existe et ne convient pas au mobile. */
@media (max-width: 560px) {
  .adm-shell { position: relative; }
  .adm-sidebar-slot .cs-sidebar {
    position: fixed; inset: 0 auto 0 0; z-index: 70; transform: translateX(-100%);
    transition: transform .2s ease; box-shadow: var(--cs-shadow-lg);
  }
  .adm-shell--nav-open .adm-sidebar-slot .cs-sidebar { transform: translateX(0); }
  .adm-header__toggle { display: block; }
}
/* Un enfant de grid/flex a `min-width:auto` par defaut : il adopte la largeur de
   son contenu et pousse la page, meme si son conteneur scrollable est contraint.
   Sans cette regle, le scroll horizontal des tableaux d'admin ne s'active jamais. */
.grid--aside > * { min-width: 0; }

@media (max-width: 980px) {
  .hero__in { grid-template-columns: 1fr; gap: 44px; }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--semaine { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .road { grid-template-columns: 1fr; }
  .perks { grid-template-columns: 1fr; }
  .steps { grid-template-columns: repeat(2, 1fr); }
  /* Aucune regle de trait ici : `.step__line { display: none }` ci-dessous
     masque TOUS les traits sous 980px, comportement d'origine du site. Y
     rallumer une fin de rangee `2n` demanderait de battre sa specificite
     (0,1,0 contre 0,3,0) et rallumerait un trait isole — pas de trait du
     tout est la regle, et elle se suffit. */
  .step__line { display: none; }
  .ftr__cols, .ftr__cols--legal { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  .section { padding: 66px 0; }
  /* Meme rapport qu'en large (la moitie du pas normal) : 33px n'est pas sur la
     grille de 4, 32 l'est. */
  .section--suite { padding-top: 32px; }
  .nav, .hdr__cta { display: none; }
  .mnav-wrap { display: block; }
  .grid--2, .grid--3, .grid--4, .steps, .radio-grid, .grid--aside, .tpl-split { grid-template-columns: 1fr; }
  /* Le calendrier garde DEUX colonnes en mobile : une seule empilerait
     sept jours de creneaux sur une page interminable. */
  .grid--semaine { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .disp, .road, .beta__cols, .perks { grid-template-columns: 1fr; }
  .ftr__cols, .ftr__cols--legal { grid-template-columns: 1fr; gap: 30px; }
  .cta-band { padding: 38px 24px; }
  .price { padding: 26px; }
  /* `display: block` seul ne suffit pas : le <colgroup> continue d'imposer sa
     largeur au conteneur. `max-width` le borne, et le scroll reste interne. */
  .cmp { display: block; overflow-x: auto; max-width: 100%; }
  /* Sous 400px, un libelle long sur une seule ligne (`white-space: nowrap`
     herite de `.btn`) depasse la colonne. On autorise le retour a la ligne
     plutot que de raccourcir le texte. */
  .btn--lg { white-space: normal; text-align: center; }
}

/* ---------- Interface (va-et-vient client <-> equipe) ---------- */
.flow { display: grid; gap: 0; margin-top: 48px; max-width: 940px; margin-left: auto; margin-right: auto; }
.flow__row {
  display: grid; grid-template-columns: minmax(0,1fr) 44px minmax(0,1fr);
  gap: 0 26px; align-items: start;
}
.flow__empty { min-height: 1px; }
.flow__spine { display: grid; justify-items: center; grid-template-rows: auto 1fr; }
.flow__node {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  font-size: 18px; flex: none; border: 2px solid var(--border-strong); background: var(--card);
  position: relative; z-index: 1;
}
.flow__node--nous { border-color: var(--accent); background: var(--accent-soft); }
.flow__rail { width: 2px; background: var(--border); min-height: 26px; }
.flow__row:last-child .flow__rail { background: transparent; }
.flow__card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 20px 23px; box-shadow: var(--shadow); margin-bottom: 22px;
}
.flow__card--nous { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.flow__who {
  font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 7px;
}
.flow__who--nous { color: var(--accent); }
.flow__t { font-weight: 640; font-size: 16.5px; margin-bottom: 7px; }
.flow__d { font-size: 14.6px; color: var(--text-2); line-height: 1.6; }

.rhythm { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 44px; }
.rhythm__item {
  text-align: center; padding: 24px 18px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--card-alt);
}
.rhythm__v { font-size: 19px; font-weight: 700; letter-spacing: -.02em; color: var(--accent); }
.rhythm__l { font-size: 14px; color: var(--text-2); margin-top: 6px; line-height: 1.5; }

@media (max-width: 860px) {
  .flow__row { grid-template-columns: auto 1fr; gap: 0 18px; }
  .flow__row > .flow__empty { display: none; }
  .flow__spine { order: -1; }
  .rhythm { grid-template-columns: 1fr; }
}

/* ---------- Cible d'ancre sous un en-tete collant ---------- */
/* L'en-tete public est `position: sticky` sur 69px de haut : un saut vers
   `#une-ancre` aligne le HAUT de l'element sur le haut de la fenetre, donc
   SOUS l'en-tete. Mesure sur /cookies#reglage avant correctif — le <h2> de la
   section arrivait a y = 0..24, entierement recouvert : le visiteur qui clique
   « Gerer mes cookies » atterrissait au milieu du contenu, sans voir le titre.

   `scroll-margin-top` decale le point d'arret du defilement sans rien changer
   a la mise en page, et sans JavaScript.

   UNE CLASSE et non `[id]` : cette feuille est PARTAGEE avec le back-office
   React (`/admin`), qui n'a pas cet en-tete et qui, lui, execute du JS —
   `scrollIntoView` y prendrait une marge qui n'a pas de raison d'etre. La
   classe se pose sur les ancres du site public uniquement. */
.scroll-anchor { scroll-margin-top: 90px; }

/* ---------- Consentement cookies (bandeau serveur, WEB-19) ---------- */
.consent-banner {
  position: fixed; left: 18px; right: 18px; bottom: 18px; z-index: 200;
  max-width: 720px; margin: 0 auto;
  background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 20px 22px;
  display: flex; flex-direction: column; gap: 16px;
}
.consent-banner__text { font-size: 14.2px; color: var(--text-2); line-height: 1.55; }
.consent-banner__actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }

.consent-overlay {
  position: fixed; inset: 0; z-index: 210;
  background: rgba(10, 12, 22, .5);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.consent-panel {
  width: 100%; max-width: 560px; max-height: 84vh; overflow-y: auto;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 28px;
}
.consent-panel__list { display: grid; gap: 16px; margin-top: 20px; }
.consent-cat {
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 15px 17px;
  background: var(--card-alt);
}
.consent-cat__head { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.consent-cat__label { font-size: 14.5px; font-weight: 620; color: var(--text); }
.consent-panel__actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; margin-top: 24px; }

@media (max-width: 760px) {
  .consent-banner { left: 12px; right: 12px; bottom: 12px; padding: 17px; }
  .consent-banner__actions { justify-content: stretch; }
  .consent-banner__actions .btn { flex: 1 1 auto; }
}

/* Ligne de liste selectionnable (maitre-detail Agenda / Demandes). Un <button>
   pour que le clavier l'atteigne ; les styles natifs du bouton sont annules,
   sans quoi la ligne heriterait bordure, fond et police du bouton. */
.adm-row--clickable {
  width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: 0; border-bottom: 1px solid var(--border);
  padding: 14px 4px; cursor: pointer;
}
.adm-row--clickable:hover { background: var(--card-alt); }
.adm-row--clickable[aria-current="true"] { background: var(--accent-soft); }

/* ── Leurre anti-robot : PAS DE CLASSE ICI, et c'est delibere ────────────────
   La classe `.hp` cachait le champ leurre de `/contact` et `/rendez-vous`.
   Elle a ete retiree (WEB-42) : une garde dont la dissimulation vit dans CE
   fichier depend d'une ressource qu'un deploiement peut supprimer — et WEB-31 a
   mesure le site public servi SANS AUCUNE feuille de style, les pages rendant
   toujours en 200. Dans cette fenetre, le leurre etait un champ ordinaire qu'un
   prospect remplissait de bonne foi.

   Le style est donc EN LIGNE dans les deux gabarits, et il y reste. Pour un
   nouveau formulaire : copier le champ ET son style inline depuis
   `pages/contact.html` ; l'explication, elle, vit une seule fois la-bas — la
   recopier la ferait diverger a la premiere correction.

   Cette note est en fin de fichier et non au milieu d'un groupe de regles : un
   pave de commentaire coince entre deux selecteurs sans rapport est ce qu'un
   nettoyage deplace ou supprime sans y penser. Cf. aussi `server/src/security.rs`,
   qui porte l'interdiction d'extraire ce style-la lors d'un durcissement CSP. */
