/* ══════════════════════════════════════════════════════════════════════
   CoVœur — Composants de formulaire (brief § 5.8)
   Maquettes : formulaires-composants, formulaire-question-mobile

   CE FICHIER EXISTE POUR QU'IL N'Y EN AIT QU'UN. Treize formulaires du
   produit portaient chacun son propre bloc `<style>` — environ huit mille
   lignes, aucune ne partageant de jeton. Changer la couleur d'un champ en
   erreur demandait treize modifications, et rien ne disait laquelle avait
   été oubliée : un formulaire resté en arrière se lit comme un formulaire
   qu'on n'a simplement pas encore refait.

   TOUT PASSE PAR LES JETONS de `report-tokens.css`. Une valeur littérale
   ici serait une couleur que le thème QRush ne peut plus atteindre.

   LA VOIX, PARCE QU'ELLE EST DANS LE COMPOSANT :
   libellés à la voix de la personne (« Mon prénom »), aides et erreurs à la
   voix de CoVœur (« Il manque quelques chiffres. »). Le composant ne peut
   pas l'imposer, mais chaque exemple de ce fichier le montre.
   ══════════════════════════════════════════════════════════════════════ */

/* LES ENTRÉES NATIVES RESTENT DANS LE DOM, masquées à l'œil seulement : ce
   sont elles qui portent le clavier, l'envoi du formulaire et ce que dit un
   lecteur d'écran. Les remplacer par des `<div>` aurait coûté tout ça pour un
   rendu identique. C'est le `<label>` qui devient la cible — un clic sur
   l'entrée elle-même n'atteint rien, et c'est normal.

   `hidden` DOIT GAGNER, PARTOUT. Toute classe qui pose un `display` écrase le
   `display:none` que le navigateur attache à l'attribut — et l'élément reste
   à l'écran alors que le code le croit retiré, sans rien dans le journal.

   LA RÈGLE EST GÉNÉRALE, ET C'EST LE POINT. La première version énumérait les
   composants concernés. Deux heures plus tard, `.cv-textarea { display: block }`
   n'y était pas : sur la météo, la zone « Un rêve cette nuit ? » restait
   ouverte alors que l'interrupteur la disait fermée. Corriger l'instance
   laisse la classe de bug en place — tout composant ajouté ici la ramènerait.

   `!important` est légitime ici et nulle part ailleurs dans ce fichier :
   `hidden` veut dire « cet élément n'est pas pertinent », et une règle de
   présentation n'a pas à en décider autrement. */
[hidden] { display: none !important; }

/* ── Le champ, et ses cinq états ────────────────────────────────────────
   Cibles tactiles de 44 px minimum, et POLICE À 16 px SUR MOBILE : en
   dessous, iOS zoome sur le champ au premier tap et ne dézoome jamais — la
   maquette est à 15,5, on monte à 16. */
/* Un libellé LU MAIS PAS VU : quand la question juste au-dessus le porte
   déjà à l'écran, le répéter alourdit — mais le retirer laisserait le champ
   muet pour un lecteur d'écran. */
.cv-sr {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0;
}
.cv-field { margin-bottom: 20px; }
.cv-field__label {
    display: block; margin-bottom: 7px;
    font-family: var(--cv-sans); font-size: 14px; font-weight: 500;
    color: var(--cv-encre-forte);
}
/* « Facultatif » en gris après le libellé, jamais d'astérisque : un
   astérisque demande d'aller chercher sa légende ailleurs sur la page. */
.cv-field__opt { font-weight: 400; color: var(--cv-encre-faint); }
.cv-field__opt::before { content: " · "; }

.cv-input, .cv-textarea, .cv-select {
    display: block; width: 100%; box-sizing: border-box;
    min-height: 50px; padding: 13px 16px;
    border-radius: var(--cv-radius); border: 1px solid var(--cv-bordure);
    background: var(--cv-creme-raised); color: var(--cv-encre-forte);
    font-family: var(--cv-sans); font-size: 16px; line-height: 1.45;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.cv-input::placeholder, .cv-textarea::placeholder { color: var(--cv-encre-faint); }
.cv-input:focus, .cv-textarea:focus, .cv-select:focus {
    outline: none; border: 1.5px solid var(--cv-sauge);
    box-shadow: 0 0 0 4px rgba(127, 161, 147, .18);
}
.cv-input[aria-invalid="true"], .cv-textarea[aria-invalid="true"] {
    border: 1.5px solid var(--cv-danger);
}
.cv-input[aria-invalid="true"]:focus, .cv-textarea[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 4px var(--cv-danger-tint);
}
.cv-field--ok .cv-input { border-color: var(--cv-sauge-rule); }
.cv-input:disabled, .cv-textarea:disabled {
    background: var(--cv-desactive); border-style: dashed;
    color: var(--cv-encre-faint); cursor: not-allowed;
}
/* La coche d'un champ validé, posée DANS le champ. */
.cv-field__wrap { position: relative; }
.cv-field__ok {
    position: absolute; right: 15px; top: 50%; transform: translateY(-50%);
    color: var(--cv-sauge); pointer-events: none;
}
.cv-field__wrap:has(.cv-field__ok) .cv-input { padding-right: 44px; }

.cv-aide {
    display: block; margin-top: 7px;
    font-size: 13px; line-height: 1.5; color: var(--cv-encre);
}
/* L'erreur PORTE SON ICÔNE : la couleur seule ne suffit pas — un daltonien
   voit un champ identique aux autres, et un lecteur d'écran ne voit rien du
   tout. `aria-describedby` sur le champ fait le reste. */
.cv-erreur {
    display: flex; align-items: flex-start; gap: 6px; margin-top: 7px;
    font-size: 13px; line-height: 1.5; color: var(--cv-danger);
}
.cv-erreur svg { flex-shrink: 0; margin-top: 2px; }

/* ── Réponse libre ──────────────────────────────────────────────────────
   Ce qu'elle écrit est en Fraunces : ce sont ses mots, pas une saisie de
   formulaire. Le compteur et « Dicter » vivent dans le cadre. */
.cv-textarea {
    min-height: 120px; resize: vertical;
    font-family: var(--cv-serif); font-size: 17px; line-height: 1.55;
}
.cv-libre { position: relative; }
.cv-libre .cv-textarea { padding-bottom: 46px; }
.cv-libre__pied {
    position: absolute; left: 14px; right: 14px; bottom: 12px;
    display: flex; align-items: center; justify-content: space-between;
    pointer-events: none;
}
.cv-dicter {
    display: inline-flex; align-items: center; gap: 6px; pointer-events: auto;
    padding: 5px 11px; border-radius: 999px; cursor: pointer;
    background: var(--cv-creme); border: 1px solid var(--cv-bordure);
    font-family: var(--cv-sans); font-size: 12.5px; color: var(--cv-encre);
}
.cv-dicter:hover { border-color: var(--cv-sauge); color: var(--cv-sauge-dark); }
.cv-dicter.est-actif { background: var(--cv-sauge); color: var(--cv-creme-raised); border-color: var(--cv-sauge); }
.cv-compteur {
    font-family: var(--cv-mono); font-size: 11px; color: var(--cv-encre-faint);
}
.cv-compteur.est-pleine { color: var(--cv-danger); }

/* ── Choix unique : des cartes, pas des ronds ───────────────────────────
   Le radio natif reste dans le DOM (clavier, formulaire, lecteur d'écran) ;
   c'est le `<label>` qui devient la cible. Le remplacer par un `<div>` aurait
   coûté la navigation au clavier pour un rendu identique. */
.cv-choices { display: flex; flex-direction: column; gap: 10px; }
.cv-choice {
    display: flex; align-items: flex-start; gap: 13px; cursor: pointer;
    padding: 14px 16px; border-radius: 16px;
    background: var(--cv-creme-raised); border: 1px solid var(--cv-bordure);
    transition: border-color .15s ease, background .15s ease;
}
.cv-choice:hover { border-color: var(--cv-hover-border); }
.cv-choice input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0; }
.cv-choice__puce {
    width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; margin-top: 1px;
    border: 1.5px solid var(--cv-bordure); background: var(--cv-creme-raised);
    display: inline-flex; align-items: center; justify-content: center;
}
.cv-choice__puce::after {
    content: ""; width: 10px; height: 10px; border-radius: 50%;
    background: var(--cv-sauge); transform: scale(0); transition: transform .15s ease;
}
.cv-choice__titre {
    display: block; font-family: var(--cv-sans); font-size: 15px;
    color: var(--cv-encre-forte); line-height: 1.4;
}
.cv-choice__precision {
    display: block; margin-top: 2px;
    font-family: var(--cv-serif-italic); font-style: italic; font-size: 14px;
    color: var(--cv-encre); line-height: 1.4;
}
.cv-choice:has(input:checked) {
    background: var(--cv-sauge-tint); border: 1.5px solid var(--cv-sauge);
}
.cv-choice:has(input:checked) .cv-choice__puce {
    border-color: var(--cv-sauge); background: var(--cv-creme-raised);
}
.cv-choice:has(input:checked) .cv-choice__puce::after { transform: scale(1); }
.cv-choice:has(input:focus-visible) { box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }

/* ── Choix multiples : des pastilles ────────────────────────────────────
   La limite est DITE dans l'aide et APPLIQUÉE : une limite annoncée qu'on
   peut dépasser ne vaut rien, une limite appliquée sans être dite se lit
   comme un bug. */
.cv-chips-choix { display: flex; flex-wrap: wrap; gap: 10px; }
.cv-chip {
    display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
    min-height: 40px; padding: 0 16px; border-radius: 999px;
    background: var(--cv-creme-raised); border: 1px solid var(--cv-bordure);
    font-family: var(--cv-sans); font-size: 14.5px; color: var(--cv-encre-forte);
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.cv-chip:hover { border-color: var(--cv-hover-border); }
.cv-chip input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0; }
.cv-chip__coche { display: none; }
.cv-chip:has(input:checked) {
    background: var(--cv-sauge); border-color: var(--cv-sauge); color: var(--cv-creme-raised);
}
.cv-chip:has(input:checked) .cv-chip__coche { display: inline-flex; }
.cv-chip:has(input:focus-visible) { box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }
/* Au plafond, ce qui n'est pas coché s'éteint — on VOIT que la limite est
   atteinte au lieu de découvrir qu'un clic ne fait rien. */
.cv-chips-choix.est-pleine .cv-chip:not(:has(input:checked)) {
    opacity: .45; cursor: not-allowed;
}

/* ── Échelle 1–5 ───────────────────────────────────────────────────────── */
.cv-scale { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.cv-scale__case {
    /* `line-height: 1` avec le centrage flex : sans lui, la hauteur de ligne
       de la police décale le chiffre de un ou deux pixels vers le bas. */
    display: inline-flex; align-items: center; justify-content: center;
    line-height: 1;
    min-height: 48px; border-radius: var(--cv-radius); cursor: pointer;
    background: var(--cv-creme-raised); border: 1px solid var(--cv-bordure);
    font-family: var(--cv-serif); font-size: 18px; color: var(--cv-encre-forte);
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.cv-scale__case:hover { border-color: var(--cv-hover-border); }
.cv-scale__case input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0; }
.cv-scale__case:has(input:checked) {
    background: var(--cv-encre-forte); border-color: var(--cv-encre-forte);
    color: var(--cv-creme);
}
.cv-scale__case:has(input:focus-visible) { box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }
.cv-bornes {
    display: flex; justify-content: space-between; margin-top: 9px;
    font-family: var(--cv-serif-italic); font-style: italic; font-size: 13px;
    color: var(--cv-encre);
}

/* ── Curseur ────────────────────────────────────────────────────────────
   Le remplissage est peint par une variable posée en JS (`--cv-pct`) : un
   `<input type=range>` ne sait pas colorer sa piste à gauche de la poignée. */
.cv-slider {
    -webkit-appearance: none; appearance: none; width: 100%; height: 6px;
    border-radius: 3px; background: var(--cv-bordure); cursor: pointer;
    background-image: linear-gradient(var(--cv-sauge), var(--cv-sauge));
    background-size: var(--cv-pct, 50%) 100%; background-repeat: no-repeat;
}
.cv-slider::-webkit-slider-thumb {
    -webkit-appearance: none; width: 28px; height: 28px; border-radius: 50%;
    background: var(--cv-creme-raised); border: 2px solid var(--cv-sauge);
    box-shadow: 0 2px 6px rgba(42, 33, 64, .18); cursor: pointer;
}
.cv-slider::-moz-range-thumb {
    width: 28px; height: 28px; border-radius: 50%;
    background: var(--cv-creme-raised); border: 2px solid var(--cv-sauge);
    box-shadow: 0 2px 6px rgba(42, 33, 64, .18); cursor: pointer;
}
.cv-slider:focus-visible { outline: none; box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }

/* ── Interrupteur ───────────────────────────────────────────────────────
   LA LIGNE ENTIÈRE est cliquable : viser un rail de 48 px au pouce rate une
   fois sur trois, et le libellé porte déjà l'intention. */
.cv-toggle {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; cursor: pointer; padding: 14px 0;
}
.cv-toggle + .cv-toggle { border-top: 1px solid var(--cv-bordure); }
.cv-toggle__txt { flex: 1 1 auto; min-width: 0; }
.cv-toggle__titre {
    display: block; font-family: var(--cv-sans); font-size: 15px;
    color: var(--cv-encre-forte); line-height: 1.4;
}
.cv-toggle__aide {
    display: block; margin-top: 3px; font-size: 13px;
    color: var(--cv-encre); line-height: 1.45;
}
.cv-toggle input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0; }
.cv-toggle__rail {
    position: relative; flex-shrink: 0; width: 48px; height: 28px;
    border-radius: 999px; background: var(--cv-bordure); margin-top: 2px;
    transition: background .18s ease;
}
.cv-toggle__rail::after {
    content: ""; position: absolute; top: 3px; left: 3px;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--cv-creme-raised); box-shadow: 0 1px 3px rgba(42, 33, 64, .2);
    transition: transform .18s ease;
}
.cv-toggle:has(input:checked) .cv-toggle__rail { background: var(--cv-sauge); }
.cv-toggle:has(input:checked) .cv-toggle__rail::after { transform: translateX(20px); }
.cv-toggle:has(input:focus-visible) .cv-toggle__rail { box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }

/* ── Consentement ───────────────────────────────────────────────────────
   JAMAIS PRÉ-COCHÉ. Ce n'est pas une règle de style : un consentement
   pré-coché n'est pas un consentement. */
.cv-consent { display: flex; align-items: flex-start; gap: 11px; cursor: pointer; }
.cv-consent input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0; }
.cv-consent__case {
    width: 20px; height: 20px; border-radius: 7px; flex-shrink: 0; margin-top: 1px;
    border: 1.5px solid var(--cv-bordure); background: var(--cv-creme-raised);
    display: inline-flex; align-items: center; justify-content: center;
    color: transparent; transition: background .15s ease, border-color .15s ease;
}
.cv-consent:has(input:checked) .cv-consent__case {
    background: var(--cv-sauge); border-color: var(--cv-sauge); color: var(--cv-creme-raised);
}
.cv-consent:has(input:focus-visible) .cv-consent__case { box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }
.cv-consent__txt { font-size: 14px; line-height: 1.5; color: var(--cv-encre); }
.cv-consent__txt a { color: var(--cv-sauge-dark); }

/* ── Le fil des trois entrées : formalités → situation → profil ─────────
   Copié à l'identique dans les trois fichiers, avec ses couleurs en dur.
   Sans lui, chaque formulaire se présente comme s'il était le dernier : on
   ne sait ni combien il en reste, ni où l'on en est. */
.cv-steps { margin: 0 0 24px; }
.cv-steps ol { display: flex; list-style: none; margin: 0; padding: 0; }
.cv-steps li {
    flex: 1 1 0; position: relative; text-align: center;
    font-size: 11.5px; line-height: 1.3; color: var(--cv-encre-faint);
}
.cv-steps li + li::before {
    content: ""; position: absolute; top: 13px; right: 50%;
    width: 100%; height: 2px; background: var(--cv-bordure);
}
.cv-steps li.done + li::before, .cv-steps li.now::before { background: var(--cv-sauge); }
.cv-steps .dot {
    position: relative; z-index: 1; display: flex; align-items: center;
    justify-content: center; width: 26px; height: 26px; margin: 0 auto 6px;
    border-radius: 50%; background: var(--cv-creme-raised);
    border: 2px solid var(--cv-bordure);
    font-family: var(--cv-mono); font-size: 12px; color: var(--cv-encre-faint);
}
.cv-steps li.done .dot { background: var(--cv-sauge); border-color: var(--cv-sauge); color: var(--cv-creme-raised); }
.cv-steps li.now .dot {
    border-color: var(--cv-sauge); color: var(--cv-encre-forte);
    box-shadow: 0 0 0 3px var(--cv-sauge-tint);
}
.cv-steps li.now .lbl { color: var(--cv-encre-forte); font-weight: 500; }
.cv-steps li.done .lbl { color: var(--cv-sauge-dark); }
@media (max-width: 360px) { .cv-steps li { font-size: 10.5px; } }

/* ── L'enveloppe d'un formulaire en une page ───────────────────────────── */
.cv-page { max-width: 560px; margin: 0 auto; padding: 28px 20px 60px; }
.cv-page__kicker {
    font-family: var(--cv-mono); font-size: 10.5px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--cv-sauge); margin-bottom: 9px;
}
.cv-page__titre {
    font-family: var(--cv-serif); font-weight: 400; font-size: 27px;
    line-height: 1.2; color: var(--cv-encre-forte); margin: 0 0 10px;
    text-wrap: balance;
}
.cv-page__lede {
    font-family: var(--cv-serif-italic); font-style: italic; font-size: 15px;
    line-height: 1.5; color: var(--cv-encre); margin: 0 0 24px;
}

/* ── Progression ────────────────────────────────────────────────────────
   Des segments, pas une barre : on voit combien il reste de questions, pas
   un pourcentage qu'il faut convertir mentalement. */
.cv-stepper__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 8px;
    font-family: var(--cv-mono); font-size: 10.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--cv-encre-faint);
}
/* De l'air sous la barre : la question venait se coller dessus, et les deux
   se lisaient comme un seul bloc. */
.cv-stepper__segs { display: flex; gap: 5px; margin-bottom: 28px; }
.cv-stepper__seg {
    flex: 1 1 0; height: 4px; border-radius: 2px; background: var(--cv-bordure);
}
.cv-stepper__seg.est-fait { background: var(--cv-sauge); }
.cv-stepper__seg.est-courant { background: var(--cv-encre-forte); }

/* ── Boutons ────────────────────────────────────────────────────────────
   Sauge pour avancer, prune pour l'envoi final : le dernier geste ne
   ressemble pas aux quinze qui l'ont précédé. */
.cv-btn-f {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    min-height: 48px; padding: 0 24px; border-radius: 999px; cursor: pointer;
    border: 1px solid transparent; font-family: var(--cv-sans); font-size: 15px;
    text-decoration: none; transition: background .15s ease, border-color .15s ease;
}
.cv-btn-f--principal { background: var(--cv-sauge); color: var(--cv-creme-raised); }
.cv-btn-f--principal:hover:not(:disabled) { background: var(--cv-sauge-dark); }
.cv-btn-f--final { background: var(--cv-encre-forte); color: var(--cv-creme); }
.cv-btn-f--final:hover:not(:disabled) { background: #1f1830; }
.cv-btn-f--second {
    background: var(--cv-creme-raised); border-color: var(--cv-bordure);
    color: var(--cv-encre-forte);
}
.cv-btn-f--second:hover:not(:disabled) { border-color: var(--cv-sauge); }
.cv-btn-f:disabled { background: var(--cv-desactive); color: var(--cv-encre-faint); cursor: not-allowed; }
.cv-btn-f:focus-visible { outline: none; box-shadow: 0 0 0 4px rgba(127, 161, 147, .18); }
.cv-passer {
    display: inline-block; background: none; border: 0; padding: 4px 0; cursor: pointer;
    font-family: var(--cv-sans); font-size: 14px; color: var(--cv-encre);
    text-decoration: underline; text-underline-offset: 3px;
}
.cv-passer:hover { color: var(--cv-sauge-dark); }

/* ══════════════════════════════════════════════════════════════════════
   L'ÉCRAN « UNE QUESTION » (mini-profil, questionnaires de programme)
   Une question par écran sur mobile ; sur desktop, le même écran centré.
   ══════════════════════════════════════════════════════════════════════ */
.cv-q-page {
    max-width: 640px; margin: 0 auto; padding: 0 20px 140px;
    font-family: var(--cv-sans); color: var(--cv-encre-forte);
}
.cv-q-top {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; padding: 14px 0 18px;
}
.cv-q-top__nom { font-size: 15px; color: var(--cv-encre-forte); }
.cv-q-top__retour, .cv-q-top__plus-tard {
    display: inline-flex; align-items: center; gap: 5px;
    background: none; border: 0; padding: 6px; cursor: pointer;
    font-family: var(--cv-sans); font-size: 14px; color: var(--cv-encre);
    text-decoration: none;
}
.cv-q-top__plus-tard { color: var(--cv-sauge-dark); }

/* La bulle de conseil : c'est CoVœur qui parle, et la mascotte le dit avant
   qu'on ait lu. */
.cv-q-conseil { display: flex; align-items: flex-start; gap: 12px; margin: 22px 0 26px; }
.cv-q-conseil img { width: 62px; height: auto; flex-shrink: 0; }
.cv-q-conseil__bulle {
    flex: 1 1 auto; padding: 14px 18px; border-radius: 6px 18px 18px 18px;
    background: var(--cv-creme-raised); border: 1px solid var(--cv-bordure);
    font-family: var(--cv-serif-italic); font-style: italic; font-size: 15px;
    line-height: 1.5; color: var(--cv-encre);
}
.cv-q-titre {
    font-family: var(--cv-serif); font-weight: 400; font-size: 28px;
    line-height: 1.22; color: var(--cv-encre-forte); margin: 0 0 22px;
    text-wrap: balance;
}
.cv-q-echapper { display: block; text-align: center; margin: 18px auto 0; }

/* La barre d'actions COLLE EN BAS : sur un écran de téléphone, « Continuer »
   posé après quatre réponses tombe sous la ligne de flottaison, et on croit
   la page finie. */
.cv-q-actions {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
    display: flex; align-items: center; gap: 12px;
    padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
    background: var(--cv-creme); border-top: 1px solid var(--cv-bordure);
}
.cv-q-actions > * { flex: 1 1 0; }
.cv-q-actions > .cv-btn-f--second { flex: 0 0 auto; padding: 0 22px; }
@media (min-width: 700px) {
    .cv-q-actions {
        position: static; border: 0; background: none;
        padding: 26px 0 0; justify-content: flex-end;
    }
    .cv-q-actions > * { flex: 0 0 auto; }
    .cv-q-page { padding-bottom: 60px; }
}

/* ── Une carte de bloc, pour les formulaires en une page ───────────────── */
.cv-form-carte {
    background: var(--cv-creme-raised); border: 1px solid var(--cv-bordure);
    border-radius: var(--cv-radius-lg); padding: 22px 20px; margin-bottom: 20px;
}
.cv-form-carte__kick {
    font-family: var(--cv-mono); font-size: 10px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--cv-encre-faint); margin: 0 0 6px;
}
.cv-form-carte__titre {
    font-family: var(--cv-serif); font-weight: 400; font-size: 21px;
    color: var(--cv-encre-forte); margin: 0 0 18px;
}

/* ── Carte repliable ────────────────────────────────────────────────────
   Une carte facultative qui s'ouvre au clic. Le `<details>` natif porte
   l'état : pas de JS, et le clavier comme la synthèse vocale savent déjà
   s'en servir. Replié, il annonce ce qu'on gagne à l'ouvrir — pas « voir
   plus ». */
.cv-repli { padding: 0; overflow: hidden; }
.cv-repli__tete {
    display: flex; align-items: center; gap: 10px;
    padding: 18px 20px; cursor: pointer; list-style: none;
    font-family: var(--cv-sans); font-size: 15px; font-weight: 500;
    color: var(--cv-sauge);
}
.cv-repli__tete::-webkit-details-marker { display: none; }
.cv-repli__tete::after {
    content: ""; width: 8px; height: 8px; margin-left: auto; flex: 0 0 auto;
    border-right: 1.6px solid var(--cv-sauge); border-bottom: 1.6px solid var(--cv-sauge);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .18s ease;
}
.cv-repli[open] .cv-repli__tete::after { transform: rotate(-135deg) translate(-2px, -2px); }
.cv-repli__tete:hover { background: var(--cv-sauge-tint); }
.cv-repli__signe {
    width: 22px; height: 22px; flex: 0 0 auto; border-radius: 50%;
    background: var(--cv-sauge-tint); color: var(--cv-sauge);
    display: grid; place-items: center; font-size: 15px; line-height: 1;
}
.cv-repli__corps { padding: 2px 20px 22px; }
@media (prefers-reduced-motion: reduce) {
    .cv-repli__tete::after { transition: none; }
}

/* Les navigateurs sans `:has()` (Firefox < 121, Safari < 15.4) ne peignent
   pas l'état sélectionné. Le JS pose alors la classe à la main — sans quoi
   on coche sans que rien ne change à l'écran. */
.cv-choice.est-choisi { background: var(--cv-sauge-tint); border: 1.5px solid var(--cv-sauge); }
.cv-choice.est-choisi .cv-choice__puce { border-color: var(--cv-sauge); }
.cv-choice.est-choisi .cv-choice__puce::after { transform: scale(1); }
.cv-chip.est-choisi {
    background: var(--cv-sauge); border-color: var(--cv-sauge); color: var(--cv-creme-raised);
}
.cv-chip.est-choisi .cv-chip__coche { display: inline-flex; }
.cv-scale__case.est-choisi {
    background: var(--cv-encre-forte); border-color: var(--cv-encre-forte); color: var(--cv-creme);
}
.cv-toggle.est-choisi .cv-toggle__rail { background: var(--cv-sauge); }
.cv-toggle.est-choisi .cv-toggle__rail::after { transform: translateX(20px); }
.cv-consent.est-choisi .cv-consent__case {
    background: var(--cv-sauge); border-color: var(--cv-sauge); color: var(--cv-creme-raised);
}
