/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   atelier.css — « La cote » sur /start, le tunnel d'achat (lot `the-workbench`, lot 5a du redesign).
   @registre /css/la-cote.css

   Source de vérité : « Kamba - specification La cote.html » (racine du dépôt, 15 septembre 2026),
   dont le pied de page dit la règle : « toute valeur absente de ce document est une décision non
   prise ». Cette feuille n'invente donc AUCUNE valeur : chaque couleur, taille, espacement, rayon
   et trait est un jeton de public/css/la-cote.css (§2), et tests/one-set-of-values.test.js le
   vérifie — /start est désormais une page GOUVERNÉE, elle tient zéro littéral hors du registre.

   ── CE LOT EST LE CHÂSSIS, PAS LE CONTENU ───────────────────────────────────────────────────────
   `builder.js` fait 7 000 lignes et start.html 1 078 : le configurateur ne tient pas dans un lot.
   Celui-ci prend le BALISAGE ET LES VALEURS — classes, cibles, anneaux, contrastes, grille,
   espacements, échelle typographique, paliers — et rien du fond. Le gabarit de question de
   l'étape 2, les trois rangs de l'écran Review, l'attente longue et l'amorce viennent en 5b / 5c.

   ── LA LIGNE QUI DÉCIDE D'UN NOM DE CLASSE ──────────────────────────────────────────────────────
   🔴 UNE CLASSE QUE QUELQUE CHOSE SÉLECTIONNE GARDE SON NOM ; UNE CLASSE QUE RIEN NE SÉLECTIONNE
   PASSE AU VOCABULAIRE DE LA DIRECTION. C'est la règle qu'`accueil.css` énonce (« les crochets de
   mise en page gardent leur nom parce que du JS, des tests et le rendu SSR s'y accrochent ») et
   elle se mesure, elle ne se suppose pas :
     · `.btn` / `.btn--primary` / `.btn--secondary` — mesuré : AUCUN sélecteur, dans aucun script,
       aucun test unitaire, aucun e2e. Ils deviennent `.bouton` / `.bouton--primaire` /
       `.bouton--secondaire` du registre, y compris aux 14 sites que `builder.js` écrit. Le
       précédent est `the-front-door`, qui a fait exactement cela sur l'accueil (tests/e2e/
       landing.spec.ts le dit en commentaire).
     · `.seg` / `.seg-group` / `.stepper-btn` / `.number-control*` / `.field-label` /
       `.control-row*` — mesuré : `pinMetric()` et neuf spécifications e2e sélectionnent
       `.seg[data-value=…]`, et tests/control-renderer.test.js épingle le balisage au caractère.
       Ils GARDENT leur nom et reçoivent ici les valeurs du registre. Renommer coûterait une
       réécriture de quarante chaînes épinglées pour zéro gain de rendu.

   ── CE QUE LA SPÉCIFICATION NE COUVRE PAS, ET QUI N'EST DONC PAS RESTYLÉ ICI ─────────────────────
   §1 marque « Paiement (Paddle) » comme une DÉCISION : la fenêtre d'achat n'a pas de valeurs dans
   ce document. Elle garde donc sa propre feuille (/css/purchase-modal.css), déclarée dans le
   registre d'exemptions avec cette raison — plutôt que de lui inventer un scrim, une ombre et un
   rayon que rien n'autorise. Idem pour le bandeau d'entrée et le panneau de liste d'attente
   (/css/waitlist-modal.css), qui sont la surface d'un autre lot.

   🔴 LES RESETS S'ÉCRIVENT EN :where(), SANS EXCEPTION. Un reset de base à spécificité (0,1,1) a
   mangé la couleur du bouton primaire au lot 1 — contraste tombé à 1,67:1, invisible pour un gate
   unitaire, attrapé seulement en e2e sur la page SERVIE.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── Les dimensions de composant que la spécification ne donne pas ─────────────────────────────
   §2.3 ferme la rampe d'espacement, les rayons, les traits, l'échelle typographique et la palette.
   Il ne donne PAS la largeur d'un champ de stepper ni celle d'un dessin de vignette. Précédent
   `--frame-w` de l'accueil : « la spécification n'en donne pas, donc on garde celle qui est
   publiée plutôt que d'en inventer une ». La différence ici est qu'elles sont NOMMÉES, en un seul
   endroit, au lieu d'être cachées dans un style="" — un lot qui voudra les trancher les trouve.
   Celles qui tombaient déjà sur la rampe y sont ramenées, et le disent. */
:root {
  --largeur-menu: 180px;                 /* menu de compte — la largeur publiée */
  /* --largeur-valeur est parti avec le châssis des contrôles, dans /css/controles.css : il ne
     dimensionne QUE .number-control__input, et un jeton doit vivre avec la règle qui le lit. */
  --largeur-vignette: 200px;             /* dessin d'une carte de catalogue — la largeur publiée */
  --largeur-dessin: 320px;               /* aperçu coté — la largeur publiée */
  --largeur-champ-court: 180px;          /* champ e-mail de la boîte de demande — la largeur publiée */
  --hauteur-textarea: var(--espace-80);  /* brief : 132 publié → 80, deux lignes, sur la rampe */
}

/* 🔴 LE SEUL RESET DE CETTE FEUILLE, ET IL EST EN :where(). Les panneaux du tunnel restent dans le
   DOM et sont masqués par l'attribut `hidden` ; beaucoup portent un `display: flex` de composant,
   qu'un `[hidden]` sans !important ne battrait pas. Le !important est donc délibéré — et
   :where() garde la règle à spécificité ZÉRO, pour qu'elle ne puisse jamais gagner autre chose
   que ce qu'elle déclare (la leçon du bouton primaire tombé à 1,67:1). */
:where([hidden]) { display: none !important; }

/* ── La colonne de page ────────────────────────────────────────────────────────────────────────
   `.container` est le crochet historique de la colonne ; il reçoit la largeur de contenu et la
   marge du palier du §2.3, exactement comme `.page-la-cote` du registre. */
.container { width: 100%; max-width: var(--largeur-contenu); margin: 0 auto; padding: 0 var(--marge-page); }

/* Lien d'évitement — hors écran jusqu'au focus, où il redevient une cible de 48 px. */
.skip-link { position: absolute; left: 0; top: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip-link:focus-visible { position: static; overflow: visible; clip-path: none; margin: var(--espace-8); }
/* ── Les niveaux typographiques des crochets historiques (§2.2) ────────────────────────────────
   `.display` est le crochet de « ce qui se lit » : il ne porte QUE la famille, chaque site portant
   son niveau. Trois familles, trois emplois disjoints — aucun niveau n'emprunte la famille d'un
   autre. */
.display { font-family: var(--police-lecture); font-weight: 400; }
/* Le titre d'un écran du configurateur est un TITRE DE SECTION, pas un hero : D1 est réservé au
   premier écran d'une page (§2.2), et 58 px sur un formulaire de quatre étapes écraserait la
   question qu'il annonce. */
.builder__title, .result__title { font-family: var(--police-lecture); font-weight: 300; font-size: var(--taille-h2); line-height: var(--interligne-h2); letter-spacing: var(--lettrage-h2); text-wrap: balance; }
.cat-card__title, .cat-other__title, .preview-empty__title, .hw-panel__title { font-family: var(--police-lecture); font-weight: 500; font-size: var(--taille-h3); line-height: var(--interligne-h3); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ── En-tête de page ───────────────────────────────────────────────────────────────────────────
   Un filet de section sous la barre, pas une ombre : la page n'a aucun calque (§2.1). */
.site-header { background: var(--papier); border-bottom: var(--trait-filet) solid var(--filet-section); }
.site-header__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-16); flex-wrap: wrap; row-gap: var(--espace-8); padding: var(--espace-8) var(--marge-page); width: 100%; max-width: var(--largeur-contenu); margin: 0 auto; }
.site-header__group { display: flex; align-items: center; gap: var(--espace-12); flex-wrap: wrap; }
/* 🔴 48 px DANS LES DEUX SENS. Le registre ne déclare que min-height sur .lien--bloc, ce qui
   suffit à un formulaire (des liens longs). Dans un en-tête, « Kamba » et la flèche de retour
   mesurent moins de 48 px de LARGE : la cible est de 48 px « sans exception » (§3), pas 48 px de
   haut seulement. Portée à cette page, pas au registre — élargir .lien--bloc partout est une
   décision du lot qui possède le registre (même arbitrage qu'`accueil.css`). */
.lien--bloc { min-width: var(--cible-tactile); justify-content: center; }
.logo { display: inline-flex; align-items: center; }
.logo img { height: var(--espace-24); width: auto; }
/* « Builder » et « Step N of 4 » : des étiquettes, pas des titres. Le registre a déjà leur niveau. */
.header-sep, .header-step { color: var(--encre-etiquette); }

/* Le sélecteur de langue est un CHAMP (§3) : même contour, même cible, même anneau. Pas de
   chevron en image de fond — le §2.1 n'autorise aucun dégradé ni calque, et le glyphe natif du
   navigateur est déjà là. */
.lang-select { width: auto; padding: 0 var(--espace-12); }

/* Le menu de compte. Il flotte, ce que la page ne fait nulle part ailleurs ; il reste donc le plus
   plat possible — filet fort, aucun rayon, aucune ombre (§2.1, §2.3) — et c'est le filet, pas une
   élévation, qui le détache. */
.acct { position: relative; }
.acct__menu { position: absolute; right: 0; top: 100%; z-index: 2; min-width: var(--largeur-menu); background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); padding: var(--espace-4); display: flex; flex-direction: column; }
/* L'avatar est une pastille — l'une des deux seules exceptions au rayon 0 (§2.3) — et non un
   bouton à libellé : il perd le padding horizontal de .bouton et garde sa cible carrée. */
.acct__btn { min-width: var(--cible-tactile); padding: 0; border-radius: var(--rayon-pastille); background: var(--surface-donnee); color: var(--encre); border: var(--trait-filet) solid var(--filet-fort); }
.acct__btn:hover { background: var(--encre-06); }
/* §1, « Sélecteur de langue et d'unités » : « Menu = liste à filets, même gabarit que les lignes
   de réglage ». Les deux rangs portent donc .ligne-reglage du registre — d'où leur cible et leur
   filet — et n'ajoutent ici que ce qu'un menu change : le padding horizontal et le dernier filet. */
.acct__item { justify-content: flex-start; width: 100%; text-align: left; background: transparent; color: var(--encre); border-top: 0; border-left: 0; border-right: 0; border-radius: 0; text-decoration: none; padding: var(--espace-8) var(--espace-12); font-family: var(--police-interface); font-weight: 400; font-size: var(--taille-interface); line-height: var(--interligne-interface); cursor: pointer; transition: background-color var(--duree); }
.acct__item:hover { background: var(--encre-06); }
.acct__item:last-child { border-bottom: 0; }
/* Une action destructive se dit en TEXTE, pas dans une couleur nouvelle (§1, « Réglages ·
   suppression de compte »). Elle garde donc l'encre et se distingue par le mot. */
.acct__item--danger { color: var(--encre); }

/* ── La grille du configurateur (§4) ───────────────────────────────────────────────────────────
   « Configurateur et amorce : les champs restent en haut, l'aperçu coté passe dessous, pleine
   largeur » jusqu'à 1080, « les deux colonnes apparaissent » au-delà. Une colonne par défaut :
   sur téléphone on saisit d'abord, on vérifie ensuite — c'est l'ordre du geste réel, et l'aperçu
   ne passe JAMAIS au-dessus des champs. */
.builder { display: grid; grid-template-columns: 1fr; gap: var(--espace-32); align-items: start; padding-top: var(--espace-44); padding-bottom: var(--espace-44); }
.builder__flow { min-width: 0; }
.builder__aside { min-width: 0; }
.builder--catalog .builder__aside { display: none; }
.builder__title { margin-bottom: var(--espace-24); }
.builder__nav { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-16); margin-top: var(--espace-24); }
/* Back est masqué à la première étape ; le vide garde Continue à droite sans que la rangée
   change de justification selon l'étape. */
.builder__nav-espace { flex: 1 1 0; }
.eyebrow { display: block; margin-bottom: var(--espace-8); }

/* ── Le fil des étapes ─────────────────────────────────────────────────────────────────────────
   Quatre nœuds. Le numéro d'étape est une PASTILLE — l'une des deux seules exceptions au rayon 0
   (§2.3) — et il porte --cote, « numéros d'étape », son rôle exact au §2.1. */
.stepper { list-style: none; margin: 0 0 var(--espace-24); padding: 0; display: flex; align-items: center; min-width: 0; }
.stepper__item { display: flex; align-items: center; flex: 1 1 auto; min-width: 0; }
.stepper__item:last-child { flex: 0 0 auto; }
.stepper__btn { display: flex; align-items: center; gap: var(--espace-8); min-height: var(--cible-tactile); min-width: var(--cible-tactile); justify-content: center; background: transparent; border: 0; border-radius: 0; padding: 0; cursor: pointer; flex: 0 0 auto; }
.stepper__mark { flex: none; width: var(--espace-32); height: var(--espace-32); border-radius: var(--rayon-pastille); display: flex; align-items: center; justify-content: center; font-family: var(--police-mesure); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); font-variant-numeric: tabular-nums; border: var(--trait-filet) solid var(--filet-fort); background: var(--surface-donnee); color: var(--cote); transition: background-color var(--duree), border-color var(--duree); }
.stepper__label { font-family: var(--police-interface); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); white-space: nowrap; }
.stepper__line { flex: 1 1 0; height: var(--trait-filet); background: var(--filet-liste); margin: 0 var(--espace-8); min-width: var(--espace-8); }
.stepper__line.is-filled { background: var(--action); }
.stepper__item.is-active .stepper__mark { background: var(--action); color: var(--papier); border-color: var(--action); }
.stepper__item.is-active .stepper__label { color: var(--encre); }
.stepper__item.is-done .stepper__mark { background: var(--action); color: var(--papier); border-color: var(--action); }
.stepper__item.is-locked .stepper__btn { cursor: default; }
.stepper__item.is-locked .stepper__mark { color: var(--encre-40); border-color: var(--encre-15); }
.stepper__item.is-locked .stepper__label { color: var(--encre-40); }

/* ── Les panneaux d'étape ──────────────────────────────────────────────────────────────────────
   `.card` est le crochet historique du bloc à données : fond --surface-donnee, « ici il y a une
   donnée » (§2.1), un filet fort, aucun rayon, aucune ombre. Rythme du §2.3 : 44 de padding pour
   une section, 24 sous un titre, 16 entre blocs frères, 8 dans un bloc. */
.card { background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); border-radius: 0; }
.card--pad { padding: var(--espace-24); }
.step-panel__intro { font-family: var(--police-lecture); font-size: var(--taille-prose); line-height: var(--interligne-prose); max-width: var(--mesure-prose); color: var(--encre-secondaire); margin: 0 0 var(--espace-16); text-wrap: pretty; }
.step-panel__hint { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-etiquette); margin: var(--espace-16) 0 var(--espace-8); }
.step-panel__hint--fin { margin-bottom: 0; text-align: right; }
/* `launch-code` (R16) — the sentence under a launch price (applied, or why it is not). The ink of
   running text, not of a label: it is something the buyer must read before paying. */
.prix-lancement { color: var(--encre); margin: var(--espace-8) 0 0; }
.prix-lancement[hidden] { display: none; }
.info-note { margin-top: var(--espace-16); padding: var(--espace-12) var(--espace-16); background: var(--bande); font-size: var(--taille-interface); line-height: var(--interligne-interface); color: var(--encre-secondaire); }

/* ── Les contrôles émis par shared/control-renderer.js ─────────────────────────────────────────
   🔴 SORTIS D'ICI VERS /css/controles.css (`the-first-move`, 2026-09-17), parce qu'ils sont
   désormais montés à deux endroits : ici et dans l'amorce de l'accueil. Ce fichier charge la
   feuille extraite AVANT la sienne (public/start.html), donc tout ce qui suit peut encore les
   surcharger exactement comme avant — l'extraction est neutre, et le gate la mesure plutôt que
   de la supposer. Le bloc parti contenait : .field-label(+--detache) · .seg-group · .seg(+:hover,
   [aria-pressed], [aria-disabled], --stacked, __sub) · .control-row(+--last, __name, __hint,
   __clamp) · .number-control(+__value, __input) · .stepper-btn(+3 états) · .unit ·
   .control-row--derived. */

/* La ligne « qui a décidé cette valeur, et pourquoi » (`decided-not-asked`). */
.decided-note { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); margin: var(--espace-4) 0 var(--espace-8); }
.decided-note__tag { font-weight: 600; color: var(--encre); }
.decided-note--yours { color: var(--encre-etiquette); }

/* Le lien de référence d'une question de pose (« Pas sûr ? … ») — le registre a déjà sa cible. */
.wall-type-help { margin-top: var(--espace-8); }

/* Champs libres : le brief du catalogue et le nom de projet. Le registre a le champ (§3) ; ici,
   seulement ce que le gabarit ajoute. */
.textarea { width: 100%; min-height: var(--hauteur-textarea); resize: vertical; padding: var(--espace-12); line-height: var(--interligne-interface); }
.review-name { margin-bottom: var(--espace-16); }
.prefs-cluster { margin-top: var(--espace-24); padding-top: var(--espace-16); border-top: var(--trait-filet) solid var(--filet-liste); }
/* Les enveloppes que shared/step-renderer.js émet autour d'un contrôle. */
.strength-control, .divider-control { margin: var(--espace-4) 0 var(--espace-16); }
/* Le corps d'un bloc à icône : il prend la place restante et ne déborde pas d'une grille. */
.val-card__body, .pdf-value__body { flex: 1 1 0; min-width: 0; }

/* ── Le catalogue (étape 0) ────────────────────────────────────────────────────────────────────
   Les types LIVRÉS ont un poids ÉGAL — aucun héros permanent, la règle est permanente. */
.catalog { margin-bottom: var(--espace-8); }
.cat-live { display: flex; flex-direction: column; gap: var(--espace-16); margin-bottom: var(--espace-16); }
.cat-live:empty { display: none; }
.cat-grid { display: grid; grid-template-columns: 1fr; gap: var(--espace-16); }
.cat-card { position: relative; display: flex; flex-direction: column; background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); border-radius: 0; }
.cat-card__media { display: flex; align-items: center; justify-content: center; padding: var(--espace-16); border-bottom: var(--trait-filet) solid var(--filet-liste); }
/* Le fond d'un dessin est --surface-donnee : « fond des dessins », son rôle au §2.1. */
.cat-card__media--render { background: var(--surface-donnee); }
.cat-card__media--soon { background: var(--bande); }
.cat-card__render { display: block; width: 100%; max-width: var(--largeur-vignette); }
.cat-card__icon svg { width: var(--espace-44); height: var(--espace-44); display: block; }
.cat-card__flag { position: absolute; top: var(--espace-8); left: var(--espace-8); z-index: 1; }
.cat-card__body { padding: var(--espace-16); display: flex; flex-direction: column; }
.cat-card__title { margin: 0; }
.cat-card__text { margin: var(--espace-8) 0 0; color: var(--encre-secondaire); }
.cat-card__choose { margin-top: var(--espace-16); align-self: flex-start; }
.cat-card--soon .cat-card__title, .cat-card--soon .cat-card__text { color: var(--encre-secondaire); }

/* « Notify me » et « Something else? » — une demande, pas une vente. */
.type-notify { margin-top: var(--espace-16); }
.type-notify__form { margin-top: var(--espace-12); display: flex; flex-direction: column; gap: var(--espace-8); }
/* `launch-code` (R17) — the second face of a « notify me » card: once the sale is open, a sentence and a
   link to the news. Shown by /js/sale-legal-gate.js (it clears the inline display:none). */
.type-notify__news { display: flex; flex-direction: column; align-items: flex-start; gap: var(--espace-8); }
.type-notify__feedback { margin-top: var(--espace-8); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); }
.cat-other { margin-top: var(--espace-24); padding-top: var(--espace-24); border-top: var(--trait-filet) solid var(--filet-section); }
.cat-other__title { margin: 0 0 var(--espace-8); }
.cat-other__text { margin: 0 0 var(--espace-8); color: var(--encre-secondaire); }
/* domain-bounds — la borne du périmètre : elle borne la boîte, elle ne la vend pas. */
.cat-other__scope { margin: 0 0 var(--espace-16); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-etiquette); }
.cat-other__row { display: flex; gap: var(--espace-8); margin-top: var(--espace-12); flex-wrap: wrap; }
.cat-other__email { flex: 1 1 var(--largeur-champ-court); }
.cat-other__submit { flex: 0 0 auto; }

/* ── Les badges ────────────────────────────────────────────────────────────────────────────────
   Une étiquette mono, pas une gélule : les rayons sont à 0 (§2.3). Le vert est réservé à
   --action, « marque validé » ; un badge neutre est un filet et de l'encre. */
.badge { display: inline-flex; align-items: center; gap: var(--espace-4); padding: var(--espace-4) var(--espace-8); border: var(--trait-filet) solid var(--filet-liste); border-radius: 0; background: var(--surface-donnee); font-family: var(--police-mesure); font-size: var(--taille-etiquette); line-height: var(--interligne-etiquette); letter-spacing: var(--lettrage-etiquette); text-transform: uppercase; color: var(--encre); font-variant-numeric: tabular-nums; }
.badge--green { color: var(--action); border-color: var(--action); }
.badge--muted { color: var(--encre-secondaire); }
/* Un avertissement ne devient JAMAIS discret (§1, contrainte produit) : il prend le registre
   d'alerte du §2.1, à pleine opacité. */
.badge--amber { color: var(--alerte-encre); background: var(--alerte-fond); border-color: var(--alerte-trait); }
.chip-row { display: flex; gap: var(--espace-8); flex-wrap: wrap; }
/* La pastille « en direct » de la tête d'aperçu — une marque « validé ». */
.dot-sage { width: var(--espace-8); height: var(--espace-8); border-radius: var(--rayon-pastille); background: var(--action); display: inline-block; flex: none; }

/* ── L'aperçu coté ─────────────────────────────────────────────────────────────────────────────
   Fond --surface-donnee, filet fort, sans rayon ni ombre. Le dessin est dimensionné en % de son
   conteneur (§4) — jamais en unités de fenêtre. */
.preview__head { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-12); flex-wrap: wrap; padding: var(--espace-12) var(--espace-16); border-bottom: var(--trait-filet) solid var(--filet-fort); }
.preview__title { display: flex; align-items: center; gap: var(--espace-8); font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); }
.preview__stage { padding: var(--espace-32) var(--espace-16); background: var(--surface-donnee); border-bottom: var(--trait-filet) solid var(--filet-liste); display: flex; flex-direction: column; align-items: center; justify-content: center; }
.preview__svg { width: 100%; max-width: var(--largeur-dessin); }
.preview__svg svg { width: 100%; height: auto; display: block; }
/* La légende sous le dessin est une COTE : Mono, --cote, et jamais sous 11 pt (§2.1, §2.2). */
.elevation__caption { margin-top: var(--espace-12); font-family: var(--police-mesure); font-size: var(--taille-cote-dessin); line-height: var(--interligne-cote-dessin); letter-spacing: var(--lettrage-cote-dessin); color: var(--cote); text-align: center; font-variant-numeric: tabular-nums; }
.preview__foot { padding: var(--espace-16); }
.pdf-note { margin: var(--espace-12) 0 0; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-etiquette); }
.preview-empty { padding: var(--espace-44) var(--espace-24); text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--espace-12); }
.preview-empty__icon { width: var(--espace-56); height: var(--espace-56); border-radius: var(--rayon-pastille); background: var(--bande); display: flex; align-items: center; justify-content: center; }
.preview-empty__frame { width: var(--espace-24); height: var(--espace-32); border: var(--trait-dessin) solid var(--encre); }
.preview-empty__title { color: var(--encre-secondaire); }
.preview-empty__text { color: var(--encre-secondaire); margin: 0; }

/* ── L'écran Review : le récapitulatif ─────────────────────────────────────────────────────────
   Le lot 5c tranche l'ORDRE et le POIDS des cartes ; ce lot n'en change ni l'un ni l'autre, il
   leur donne les valeurs de la direction. */
.review-grid { display: grid; grid-template-columns: 1fr; gap: var(--espace-8); margin-bottom: var(--espace-16); }
.review-cell { background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-liste); padding: var(--espace-12); }
.review-cell__label { font-family: var(--police-mesure); font-size: var(--taille-etiquette); line-height: var(--interligne-etiquette); letter-spacing: var(--lettrage-etiquette); text-transform: uppercase; color: var(--encre-etiquette); }
.review-cell__val { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); margin-top: var(--espace-4); }
.review-validation { display: flex; flex-direction: column; gap: var(--espace-12); margin: var(--espace-8) 0; }
.review-validation:empty { display: none; }
.val-section { display: flex; flex-direction: column; gap: var(--espace-12); }

/* Le bloc de transparence (cloison automatique, charge maximale) — une information, pas une
   alerte : il reste sur le fond des données, avec son filet. */
.val-notice { display: flex; align-items: flex-start; gap: var(--espace-8); padding: var(--espace-12); background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); }
.val-notice--warn { background: var(--alerte-fond); border: var(--trait-dessin) solid var(--alerte-trait); color: var(--alerte-encre); }
.val-notice__icon { flex: none; line-height: var(--interligne-interface); }
.val-notice__msg { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); }
.val-notice__lever { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); margin-top: var(--espace-4); }
.val-notice--warn .val-notice__lever { color: var(--alerte-encre); }

/* Les cartes d'avertissement et de refus — le bloc du §2.1 : contour 1,5 px alerte-trait, fond
   alerte-fond, texte alerte-encre à PLEINE opacité. « Un avertissement ne devient jamais
   discret : il reste l'élément de plus fort contraste de l'écran » (§1). */
.val-card { display: flex; align-items: flex-start; gap: var(--espace-8); padding: var(--espace-12) var(--espace-16); border: var(--trait-dessin) solid var(--alerte-trait); background: var(--alerte-fond); color: var(--alerte-encre); }
/* 🔴 LA DIRECTION NE DÉCLARE QU'UN SEUL REGISTRE D'ALERTE, et c'est une conséquence, pas un
   oubli. `--warning` peignait un ambre et `--blocking` un rouge (#FBEDEC / #E7C3BF), deux
   couleurs qui ne sont nulle part dans la palette du §2.1 — laquelle donne exactement un trio
   (alerte-trait / alerte-fond / alerte-encre). Les deux modificateurs prennent donc le même
   registre, à pleine opacité, ce qui respecte la contrainte produit du §1 (« un avertissement ne
   devient jamais discret »). CE QUI SE PERD est la DISTINCTION entre « on refuse » et « on
   avertit », qui est précisément l'arbitrage du lot 5c (« Ordre et poids des cartes
   d'avertissement ») : elle ne s'invente pas ici. Décision consignée dans RESULT.md. */
.val-card--warning, .val-card--blocking { border-color: var(--alerte-trait); background: var(--alerte-fond); }
.val-card--tip-grave { border-color: var(--danger-trait); background: var(--danger-fond); color: var(--danger-encre); }
.val-card--tip-grave :focus-visible { outline-color: var(--danger-encre); }
/* `fix-to-the-wall` (partie C) — l'avertissement de basculement : rouge pour les niveaux 2 à 4 (ci-dessus), le
   registre ambre ordinaire pour le niveau 1, tracé d'un filet plutôt que d'un trait : plus discret, jamais muet. */
.val-card--tip-conseil { border-width: var(--trait-filet); }
.val-card__guide { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); margin-top: var(--espace-8); }
.val-card__guide .lien { color: inherit; }
.val-card__icon { flex: none; line-height: var(--interligne-interface); }
.val-card__msg { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); }
.val-card__impact { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); margin-top: var(--espace-4); }
/* `remedy-reaches-screen` — la ligne du REMÈDE : elle porte le poids du message, pas le gris de
   la conséquence, parce que le lecteur d'un plan refusé doit trouver le geste. */
.val-card__fix { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); margin-top: var(--espace-8); }
.val-card__cta { margin-top: var(--espace-12); display: flex; flex-wrap: wrap; gap: var(--espace-8); align-items: center; }
/* Le bouton de remède (`migrate-the-remedies`) — `builder.js` le sélectionne par son nom
   (`$$('.val-card__apply', wrap)`), donc le nom reste et ce sont les valeurs qui passent au
   registre : c'est le bouton primaire du §3. Une carte peut offrir DEUX sorties exclusives (la
   hauteur OU la profondeur) : la première est le geste, l'autre est dessinée en contour, pour
   qu'un seul clic se lise comme la réponse. */
.val-card__apply { display: inline-flex; align-items: center; justify-content: center; min-height: var(--cible-tactile); padding: 0 var(--espace-16); background: var(--action); color: var(--papier); border: var(--trait-filet) solid var(--action); border-radius: var(--rayon-bouton); font-family: var(--police-interface); font-weight: 500; font-size: var(--taille-bouton); line-height: var(--interligne-bouton); cursor: pointer; transition: background-color var(--duree), border-color var(--duree); }
.val-card__apply:hover { background: var(--action-survol); border-color: var(--action-survol); }
.val-card__apply--alt { background: var(--surface-donnee); color: var(--action); }
.val-card__apply--alt:hover { background: var(--bande); }
.val-card__apply:disabled { background: var(--encre-12); color: var(--encre-45); border-color: var(--encre-15); cursor: default; }
/* Sur fond d'alerte, l'anneau passe à --alerte-encre pour rester visible (§3). */
.val-card :focus-visible, .val-notice--warn :focus-visible { outline-color: var(--alerte-encre); }
/* Le consentement de sécurité : cocher est ce qui débloque, donc c'est une action, et la ligne
   entière est la cible. */
.val-card__consent { display: flex; align-items: center; gap: var(--espace-8); min-height: var(--cible-tactile); margin-top: var(--espace-8); cursor: pointer; font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); }
.val-card__consent input { flex: none; width: var(--espace-24); height: var(--espace-24); margin: 0; cursor: pointer; accent-color: var(--action); }
.val-clear { display: flex; align-items: center; gap: var(--espace-8); padding: var(--espace-12); background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); }

/* ── `the-last-look` — LE VERDICT, EN TROIS RANGS, ET LA HIÉRARCHIE EST STRUCTURELLE ─────────────
   Arbitrage PO du 2026-09-16 : le rang se lit à la PLACE (le rang 1 en tête), au CONTOUR et au fait
   de n'être jamais replié — jamais à une teinte neuve : la direction n'a qu'un trio d'alerte, et
   WCAG 1.4.1 exige que la distinction ne repose pas sur la couleur seule. Le rang est DÉRIVÉ par
   builder.js depuis la conséquence déclarée par la règle (shared/card-rank.js), jamais écrit ici.
     rang 1 · sécurité     — les cartes gardent leur contour d'alerte (§2.1), le groupe s'ouvre sur
                             son intitulé ; rien n'est repliable, rien n'a de hauteur bornée ;
     rang 2 · validité     — bloc encadré d'un filet, sur le fond des données (le .val-notice) ;
     rang 3 · information  — une ligne simple sous un filet de liste : la boîte et le fond partent,
                             l'encre reste à pleine opacité, l'icône reste. */
.verdict { display: flex; flex-direction: column; gap: var(--espace-8); }
.verdict__intitule { margin: 0; font-family: var(--police-mesure); font-size: var(--taille-etiquette); line-height: var(--interligne-etiquette); letter-spacing: var(--lettrage-etiquette); text-transform: uppercase; color: var(--encre-etiquette); }
.verdict--rang-1 .verdict__intitule { color: var(--alerte-encre); }
.verdict--rang-3 .verdict__liste { gap: 0; }
.verdict--rang-3 .val-notice, .verdict--rang-3 .val-card { background: transparent; border: 0; border-bottom: var(--trait-filet) solid var(--filet-liste); padding: var(--espace-8) 0; color: var(--encre); }
.verdict--rang-3 .val-notice__lever, .verdict--rang-3 .val-card__impact { color: var(--encre-secondaire); }
/* L'ACTION d'une carte qui refuse (§2 : bloquant et avertissement se distinguent à l'action, pas à
   la teinte) — la carte dit que Générer reste éteint tant qu'on ne change pas ce qu'elle nomme. */
.val-card__action { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); margin-top: var(--espace-8); }

/* L'explication du plafond de panneau (`val-widthcap`) — une carte à données, avec le bloc
   d'alerte pour la raison et le fond des données pour le remède. */
.val-widthcap { display: block; background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); padding: var(--espace-16); }
.val-widthcap__head { display: flex; align-items: flex-start; gap: var(--espace-12); }
.val-widthcap__icon { width: var(--espace-32); height: var(--espace-32); background: var(--alerte-fond); border: var(--trait-dessin) solid var(--alerte-trait); color: var(--alerte-encre); display: flex; align-items: center; justify-content: center; flex: none; }
.val-widthcap__title { font-family: var(--police-lecture); font-weight: 500; font-size: var(--taille-h3); line-height: var(--interligne-h3); }
.val-widthcap__why { font-size: var(--taille-interface); line-height: var(--interligne-interface); color: var(--encre-secondaire); margin-top: var(--espace-4); }
.val-widthcap__why strong { color: var(--encre); font-weight: 600; }
.val-widthcap__fix { background: var(--bande); padding: var(--espace-16); margin-top: var(--espace-16); display: flex; flex-direction: column; gap: var(--espace-12); }
.val-widthcap__fixhead { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); color: var(--encre); }
.val-widthcap__units { display: flex; align-items: flex-end; justify-content: center; gap: var(--espace-12); flex-wrap: wrap; }
.val-widthcap__unit { display: flex; flex-direction: column; align-items: center; gap: var(--espace-4); }
.val-widthcap__unit svg { display: block; }
.val-widthcap__unitlabel, .val-widthcap__wall { font-family: var(--police-mesure); font-size: var(--taille-cote-dessin); line-height: var(--interligne-cote-dessin); color: var(--cote); text-align: center; }
.val-widthcap__plus { font-family: var(--police-mesure); font-size: var(--taille-h3); color: var(--cote); padding-bottom: var(--espace-24); }
.val-widthcap__reassure, .val-widthcap__adjust { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); text-align: center; }
.val-widthcap__placement { font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre); text-align: center; margin-top: var(--espace-4); }
.val-widthcap__cta { display: flex; align-items: center; gap: var(--espace-12); flex-wrap: wrap; margin-top: var(--espace-16); }
.val-widthcap__cta .val-card__cta { margin-top: 0; }

/* ── L'écran Review : la boîte d'achat ─────────────────────────────────────────────────────────
   Le lot 5c tranche son gabarit ; ici, les valeurs. */
.review-buybox { margin-top: var(--espace-16); }
.pdf-value { display: flex; align-items: flex-start; gap: var(--espace-12); padding: var(--espace-12) var(--espace-16); background: var(--bande); }
.pdf-value__icon { flex: none; line-height: var(--interligne-interface); }
.pdf-value__title { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); }
.pdf-value__text { margin: var(--espace-4) 0 0; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); }
.pdf-value__text strong { color: var(--encre); font-weight: 600; }
.generate-row { display: flex; align-items: center; justify-content: space-between; gap: var(--espace-16); flex-wrap: wrap; margin-top: var(--espace-16); }
.generate-row__caption { font-family: var(--police-mesure); font-size: var(--taille-etiquette); line-height: var(--interligne-etiquette); letter-spacing: var(--lettrage-etiquette); text-transform: uppercase; color: var(--encre-etiquette); }
/* Le prix est une VALEUR CHIFFRÉE (§2.2) : Newsreader 400, et son unité en Mono. */
.generate-row__price { font-family: var(--police-lecture); font-weight: 400; font-size: var(--taille-valeur); line-height: var(--interligne-valeur); font-variant-numeric: tabular-nums; }
/* `post-purchase-screen` — la face « possédé » occupe le même créneau focal que le prix, dans le
   vert qui CONFIRME (« marque validé », §2.1) plutôt que dans l'encre d'un montant à payer. */
.generate-row__owned { font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-h3); line-height: var(--interligne-h3); color: var(--action); }
/* `the-last-look` — la raison d'un Générer éteint, VISIBLE sous le bouton (elle était sr-only) :
   §2 dit que le refus se lit dans l'action. Même id, même aria-describedby. */
.generate-row__raison { flex: 1 0 100%; margin: 0; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--alerte-encre); }
.generate-row__raison[hidden] { display: none; }

/* ── L'écran de résultat ───────────────────────────────────────────────────────────────────────
   §1 : « Succès et téléchargement — Couverte — Gabarit « message étroit » + bouton primaire. » */
.result__title { margin: 0 0 var(--espace-8); }
.step7-unlock-msg { display: none; margin: 0 0 var(--espace-16); padding: var(--espace-12); background: var(--surface-donnee); border: var(--trait-filet) solid var(--action); font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); color: var(--action); text-align: center; }
.step7-unlock-msg.show { display: block; }
/* `sell-in-france` (R12) — le plan n'est pas en vente pour le pays du meuble : le bloc prend la place de
   tout le reste du panneau (bouton payant, conseil d'impression, mentions de paiement). Une classe sur le
   panneau, posée par builder.js renderSaleCountryBlock : le pays peut changer, et le bouton revenir. */
#step7CtaBlock.vente-pays-ferme > :not([data-sale-country-block]) { display: none !important; }
/* `finishing-touches` (STG-11) — le bloc ci-dessus est à l'écran : la carte sous l'aperçu ne montre plus
   ni le prix ni « Générer le plan » (ni la phrase du prix de lancement), elle renvoie au bloc. */
.review-buybox.vente-pays-ferme .generate-row,
.review-buybox.vente-pays-ferme [data-launch-note] { display: none !important; }
/* `ready-for-counsel` (FT-1) — vente ouverte, meuble pour un pays hors de la liste : dès la vérification,
   la carte ne cite aucun prix. « Générer le plan » reste (gratuit, seul chemin vers le bloc). */
/* `no-secure-promise` — le libellé « Votre plan de construction » annonçait ce prix : sans lui il restait seul
   au-dessus de rien. Il part avec le prix, et revient avec lui (même classe). */
.review-buybox.vente-pays-sans-prix .generate-row__price,
.review-buybox.vente-pays-sans-prix .generate-row__caption { display: none !important; }
.vente-pays { display: flex; flex-direction: column; align-items: flex-start; gap: var(--espace-12); }
.vente-pays[hidden] { display: none; }
.step7-cta-subtext, .trust-copy { margin: var(--espace-8) 0 0; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-etiquette); text-align: center; }
/* `the-last-look` — l'attente narrée sous le bouton de téléchargement : une phrase, pas une barre.
   L'échec reste à l'écran, dans l'encre d'alerte, jusqu'au prochain essai. */
.attente { margin: var(--espace-12) 0 0; padding: var(--espace-12); background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-fort); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre); text-align: left; }
.attente[hidden] { display: none; }
.attente--failed { border: var(--trait-dessin) solid var(--alerte-trait); background: var(--alerte-fond); color: var(--alerte-encre); }
/* `bought-stays-bought` — the warning of a purchased plan that today's calculation refuses
   (purchase-notice.js): the alert register of this page, set as a block that stays. */
.avis-achat { margin: var(--espace-12) 0 0; padding: var(--espace-12); border: var(--trait-dessin) solid var(--alerte-trait); background: var(--alerte-fond); color: var(--alerte-encre); font-size: var(--taille-interface); line-height: var(--interligne-interface); text-align: left; }
.avis-achat[hidden] { display: none; }
.avis-achat p { margin: 0; }
.avis-achat__surtitre, .avis-achat__etiquette { font-family: var(--police-mesure); font-size: var(--taille-etiquette); line-height: var(--interligne-etiquette); letter-spacing: var(--lettrage-etiquette); text-transform: uppercase; }
.avis-achat__titre { font-family: var(--police-lecture); font-weight: 500; font-size: var(--taille-h4); line-height: var(--interligne-h4); }
.avis-achat .avis-achat__titre + .avis-achat__texte { margin-top: var(--espace-8); }
.avis-achat__raison { margin-top: var(--espace-12); padding-top: var(--espace-12); border-top: var(--trait-filet) solid var(--alerte-trait); }
.avis-achat .avis-achat__texte + .avis-achat__etiquette { margin-top: var(--espace-12); }
.avis-achat__accroche { font-weight: 600; }
.avis-achat .avis-achat__fin { margin-top: var(--espace-12); padding-top: var(--espace-12); border-top: var(--trait-filet) solid var(--alerte-trait); font-weight: 600; }
.avis-achat__lien { color: inherit; text-decoration: underline; }
.activate-back-row { margin-top: var(--espace-16); text-align: center; }
/* Les deux liens « revenir en arrière » : des liens, donc soulignés (le lien ne peut pas tenir à
   la couleur seule — WCAG 1.4.1), et des cibles de 48 px. */
.activate-back-link { display: inline-flex; align-items: center; min-height: var(--cible-tactile); color: var(--action); text-decoration: underline; text-decoration-thickness: var(--trait-filet); text-underline-offset: var(--anneau-decalage); cursor: pointer; }
.activate-back-link:hover { color: var(--action-survol); }

/* La checklist de quincaillerie — un tableau dense, gabarit de la liste de découpe (§1). Son
   dessin à taille réelle est du contenu NOUVEAU (§6) et vient avec la bande des cinq gestes. */
.hw-panel { margin-top: var(--espace-24); padding: var(--espace-16); border: var(--trait-filet) solid var(--filet-fort); background: var(--surface-donnee); }
.hw-panel__title { margin: 0 0 var(--espace-4); font-family: var(--police-interface); font-weight: 600; font-size: var(--taille-intitule); line-height: var(--interligne-intitule); }
.hw-panel__intro { margin: 0 0 var(--espace-8); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); }
.hw-panel__list { list-style: none; margin: 0; padding: 0; }
.hw-panel__list li { display: flex; justify-content: space-between; align-items: baseline; gap: var(--espace-12); padding: var(--espace-8) 0; border-bottom: var(--trait-filet) solid var(--filet-liste); font-family: var(--police-mesure); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); font-variant-numeric: tabular-nums; }
.hw-panel__list li:last-child { border-bottom: 0; }
/* `five-moves` — la mention « à taille réelle » sous la liste, et le conseil d'impression sur l'écran de téléchargement. */
.hw-panel__note { margin: var(--espace-8) 0 0; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); }
.conseil-impression { margin: var(--espace-12) 0 0; padding: var(--espace-12); background: var(--surface-donnee); border: var(--trait-filet) solid var(--filet-liste); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); }
/* `store-link` (lot 47, point 7) — where to buy, once the plan is in hand: one sentence, then the link (a new tab). */
.lien-magasin { margin: var(--espace-12) 0 0; font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--encre-secondaire); }
.hw-panel__name { color: var(--encre); }
.hw-panel__qty { font-weight: 500; color: var(--encre); white-space: nowrap; }

/* ── États de page pilotés par les scripts ─────────────────────────────────────────────────────
   Le registre a déjà .hidden / .panel / .alerte-page ; ceux-ci sont propres au tunnel. */
.step-error { margin-top: var(--espace-12); font-size: var(--taille-donnee); line-height: var(--interligne-donnee); color: var(--alerte-encre); }
/* Le verbe d'attente, pas un voile : le §3 dit « libellé remplacé par le verbe d'attente, largeur
   figée, aria-busy ». Une opacité sur un bouton mangerait son contraste. */
.is-busy { pointer-events: none; }

/* ── §4 Paliers — quatre, en min-width, sur une base mobile ──────────────────────────────────── */
@media (min-width: 600px) {
  /* « Tableaux : 2 colonnes réelles » · « Quincaillerie en 2 colonnes » */
  .cat-grid { grid-template-columns: 1fr 1fr; }
  .cat-live { flex-direction: row; align-items: stretch; }
  .cat-live .cat-card { flex: 1 1 0; min-width: 0; }
  .review-grid { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 880px) {
  /* « Configurateur : les champs restent en haut, l'aperçu coté passe dessous, pleine largeur, et
     les valeurs calculées se placent en ligne sous l'aperçu. » La colonne reste unique ici. */
  .cat-grid { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 1080px) {
  /* « Les deux colonnes apparaissent » : champs 1fr / aperçu + cotes 1fr. */
  .builder { grid-template-columns: 1fr 1fr; gap: var(--gouttiere); }
  .builder--catalog { grid-template-columns: 1fr; }
  /* L'aperçu SUIT les champs quand on descend la page. C'est une décision produit existante
     (MOB-1), épinglée par tests/e2e/builder.spec.ts, que la direction ne donne ni ne retire — le
     §4 dit seulement QUAND la seconde colonne apparaît. Elle ne revient donc qu'au palier de deux
     colonnes : en dessous, l'aperçu est SOUS les champs, et l'y coller mettrait le dessin par
     dessus la question qu'on est en train de lire. (Retirée par erreur au premier jet de ce lot ;
     l'e2e l'a rattrapée, ce que les 65 écrans du relevé ne pouvaient pas voir.) */
  .builder__aside { position: sticky; top: var(--espace-16); }
}
/* Les libellés du fil d'étapes ne tiennent à côté des quatre nœuds qu'en deux colonnes larges ;
   en dessous, les pastilles numérotées et la ligne « Étape N sur 4 » portent la progression. */
@media (max-width: 1079px) {
  .stepper__label { display: none; }
}
