/* ==========================================================================
   POC Configurateur de cuisine IA — charte MAGENTA Home Design
   Fond blanc, magenta en accent seulement, beaucoup de blanc, peu de
   tailles de typo. Mobile d'abord : le parcours se joue au telephone.
   ========================================================================== */

:root {
  --mg-primary: #e6007e;
  --mg-ink: #323232;
  --mg-black: #000000;
  --mg-gray: #808080;
  --mg-gray-light: #b2b2b2;
  --mg-line: #e4e4e4;
  --mg-surface: #fafafa;

  /* Rouge Veneta Cucine, releve sur le logo fourni. Reserve a l'ecran
     des finitions : c'est le nuancier du fournisseur, et l'y signaler
     rassure le visiteur sur la provenance des matieres. Partout
     ailleurs, la couleur d'accent reste le magenta MAGENTA. */
  --veneta-red: #dc0714;

  /* Couleur d'accent de l'ecran courant. Bascule au rouge Veneta sur
     l'etape des finitions, sans dupliquer les regles de selection. */
  --accent: var(--mg-primary);

  --font: 'Futura PT', 'Futura', 'Helvetica Neue', 'Helvetica', 'Arial',
    ui-sans-serif, system-ui, sans-serif;

  --gap: 1.5rem;
  --radius: 4px;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font);
  color: var(--mg-ink);
  background: #ffffff;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* ---- En-tete ------------------------------------------------------------ */

header {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--mg-line);
}

header img {
  height: 24px;
  width: auto;
}

header .tag {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mg-gray);
}

/* Le bandeau labo doit etre impossible a confondre avec le parcours
   visiteur : c'est un outil interne, pas un ecran client. */
.labo-banner {
  background: var(--mg-ink);
  color: #fff;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.5rem 1.5rem;
}

/* ---- Structure ---------------------------------------------------------- */

main {
  max-width: 720px;
  margin: 0 auto;
  padding: 2rem 1.5rem 6rem;
}

.step {
  display: none;
}

.step.active {
  display: block;
  animation: fade 0.25s ease-out;
}

@keyframes fade {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.step-count {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mg-gray);
  margin-bottom: 0.5rem;
}

h1 {
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.25;
  margin: 0 0 0.5rem;
}

.lead {
  color: var(--mg-gray);
  margin: 0 0 var(--gap);
}

/* ---- Barre de progression ----------------------------------------------- */

.progress {
  display: flex;
  gap: 6px;
  margin-bottom: 2rem;
}

.progress span {
  flex: 1;
  height: 2px;
  background: var(--mg-line);
  transition: background 0.3s;
}

.progress span.done {
  background: var(--mg-primary);
}

/* ---- Choix en cartes ---------------------------------------------------- */

.choices {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

.choice {
  border: 1px solid var(--mg-line);
  border-radius: var(--radius);
  background: #fff;
  padding: 1.25rem 1rem;
  text-align: left;
  font-family: inherit;
  font-size: 1rem;
  color: var(--mg-ink);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.choice:hover {
  border-color: var(--mg-gray-light);
}

.choice[aria-pressed='true'] {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.choice .shape {
  display: block;
  margin-bottom: 0.75rem;
}

.choice .name {
  display: block;
  font-weight: 500;
}

.choice .hint {
  display: block;
  font-size: 0.8125rem;
  color: var(--mg-gray);
}

/* ---- Finitions ---------------------------------------------------------- */

/* L'ecran des finitions passe en accent Veneta. Une seule variable
   bascule, les regles de selection plus bas n'en savent rien. */
.step.veneta {
  --accent: var(--veneta-red);
}

.veneta-band {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.875rem 1rem;
  margin-bottom: 2rem;
  background: var(--mg-surface);
  border-left: 2px solid var(--veneta-red);
  border-radius: var(--radius);
}

.veneta-band img {
  height: 15px;
  width: auto;
}

.veneta-band span {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--mg-gray);
}

.finish-group {
  margin-bottom: 2rem;
}

.finish-group h2 {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mg-gray);
  font-weight: 500;
  margin: 0 0 0.75rem;
  padding-left: 0.5rem;
  border-left: 2px solid var(--veneta-red);
}

/* ---- Rail horizontal de finitions --------------------------------------- */

/* Six pastilles visibles, le reste au defilement lateral. Le rail
   remplace l'ancien bouton « Voir tout » : sur mobile le geste est
   naturel, et sur desktop les fleches le rendent explicite. */
.rail {
  position: relative;
  /* Referentiel de largeur pour les pastilles. Indispensable : dans une
     grille qui deborde horizontalement, `100%` designe la largeur du
     CONTENU (les 150 pastilles), pas la zone visible — chaque colonne
     faisait alors 1/6 du rail entier. `cqw` mesure bien le conteneur. */
  container-type: inline-size;
}

.swatches {
  display: grid;
  grid-auto-flow: column;
  /* Six pastilles dans la largeur visible. La 7e depasse juste assez
     pour se voir : c'est ce qui signale qu'il y a une suite. */
  grid-auto-columns: calc((100cqw - 5 * 0.75rem) / 6);
  gap: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  scrollbar-width: none;
}

.swatches::-webkit-scrollbar {
  display: none;
}

.swatches > * {
  scroll-snap-align: start;
}

/* « Garder mon sol » : sa propre ligne, avant les matieres. Ce n'est
   pas une matiere parmi d'autres, c'est le choix de ne rien changer. */
.keep-row {
  /* Six colonnes fixes, une seule occupee : la pastille a exactement la
     largeur de celles des rails. Pas de `cqw` ici — le referentiel
     serait l'element lui-meme, donc circulaire. */
  grid-auto-flow: row;
  grid-template-columns: repeat(6, 1fr);
  overflow: visible;
  margin-bottom: 1.25rem;
}

.sous-titre {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--mg-gray);
  margin: 0 0 0.5rem;
}

.sous-titre + .rail {
  margin-bottom: 1.25rem;
}

/* L'etiquette du groupe qu'on regarde. Elle suit le defilement plutot
   que de decouper le rail en onze blocs : le visiteur balaie une seule
   ligne et sait toujours dans quelle famille du nuancier il pioche. */
.groupe {
  display: inline-block;
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin: -0.25rem 0 0.625rem;
  transition: opacity 0.15s;
}

.groupe[hidden] {
  display: none;
}

/* Sur telephone, six pastilles font 50 px de cote : trop petit pour
   juger d'une matiere, et trop petit pour viser au doigt. Quatre
   laissent ~80 px, ce qui montre reellement le veinage d'un bois. */
@media (max-width: 560px) {
  .swatches {
    grid-auto-columns: calc((100cqw - 3 * 0.75rem) / 4);
  }

  .keep-row {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ---- Fleches de defilement ----------------------------------------------- */

.arrow {
  position: absolute;
  top: calc(50% - 0.9rem);
  transform: translateY(-50%);
  z-index: 2;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--mg-line);
  border-radius: 50%;
  background: #fff;
  color: var(--mg-ink);
  cursor: pointer;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12);
  display: grid;
  place-items: center;
}

.arrow svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.arrow.prev {
  left: -10px;
}

.arrow.next {
  right: -10px;
}

.arrow:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.arrow[hidden] {
  display: none;
}

.swatch {
  border: none;
  background: none;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
}

/* La pastille est une <img> quand elle a une vignette (lazy loading
   natif), un <span> colore sinon. Les deux partagent cette regle. */
.swatch .chip {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--radius);
  border: 1px solid var(--mg-line);
  object-fit: cover;
  background-size: cover;
  background-position: center;
  transition: box-shadow 0.15s;
}

.swatch[aria-pressed='true'] .chip {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 2px var(--accent);
}

.swatch .label {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.6875rem;
  color: var(--mg-ink);
  margin-top: 0.5rem;
  line-height: 1.25;
  min-height: 2.5em;
}

.swatch[aria-pressed='true'] .label {
  color: var(--accent);
}

/* ---- Animation « reculez-vous » ----------------------------------------- */

.recul {
  margin: 0 0 var(--gap);
  padding: 1.25rem 1rem 0.875rem;
  background: var(--mg-surface);
  border-radius: var(--radius);
  text-align: center;
}

.recul svg {
  width: 100%;
  max-width: 300px;
  height: auto;
}

.recul figcaption {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--mg-gray);
  margin-top: 0.5rem;
}

.recul .mur {
  fill: #fff;
  stroke: var(--mg-line);
  stroke-width: 2;
}

.recul .sol {
  stroke: var(--mg-gray-light);
  stroke-width: 2;
}

.recul .cuisine {
  fill: #fff;
  stroke: var(--mg-gray-light);
  stroke-width: 2;
}

/* Le cadre part serre sur la cuisine, puis s'ouvre sur toute la piece :
   c'est le geste qu'on demande au visiteur, montre plutot qu'ecrit.

   L'animation passe par `transform`, PAS par les attributs x/y/width/
   height : ceux-ci ne sont animables en CSS que depuis SVG2, et Safari
   ne les anime pas. Or le parcours se joue au telephone, souvent sur
   iPhone — l'animation y serait restee figee. Le rect porte donc sa
   taille FINALE (piece entiere) et on le retrecit au depart. */
.recul .cadre,
.recul .personne {
  transform-box: fill-box;
  transform-origin: center;
}

.recul .cadre {
  fill: none;
  stroke: var(--mg-primary);
  stroke-width: 2.5;
  animation: cadre-recul 4s ease-in-out infinite;
}

.recul .personne {
  fill: none;
  stroke: var(--mg-ink);
  stroke-width: 2.5;
  stroke-linecap: round;
  animation: personne-recul 4s ease-in-out infinite;
}

@keyframes cadre-recul {
  /* Depart : cadre trop serre, on ne voit qu'un bout du lineaire.
     Le translate recentre ce petit cadre sur la cuisine, qui n'est pas
     au milieu de la piece — sans lui, le cadre serre se centrerait sur
     le mur et ne montrerait pas l'erreur qu'on veut illustrer. */
  0%,
  15% {
    transform: translate(-34px, 6px) scale(0.5, 0.86);
  }
  /* Arrivee : toute la cuisine, plus un peu de mur de chaque cote. */
  55%,
  85% {
    transform: translate(0, 0) scale(1);
  }
  100% {
    transform: translate(-34px, 6px) scale(0.5, 0.86);
  }
}

/* La personne recule : elle s'eloigne de la cuisine, donc se rapproche
   de l'observateur — elle descend dans l'image et grandit. */
@keyframes personne-recul {
  0%,
  15% {
    transform: translateY(-12px) scale(0.85);
  }
  55%,
  85% {
    transform: translateY(0) scale(1.15);
  }
  100% {
    transform: translateY(-12px) scale(0.85);
  }
}

/* ---- Sol : produit MAGENTA au milieu des finitions Veneta --------------- */

/* L'etape des finitions est en accent Veneta ; le sol vient d'Odoo et
   n'a rien de Veneta. Ce bloc remet donc l'accent magenta pour lui
   seul — la marque du fournisseur ne doit pas couvrir un produit qui
   n'est pas le sien. */
.finish-group.hors-veneta {
  --accent: var(--mg-primary);
  padding-top: 1.5rem;
  border-top: 1px solid var(--mg-line);
}

.finish-group.hors-veneta h2 {
  border-left-color: var(--mg-primary);
}

.magenta-band {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  background: var(--mg-surface);
  border-left: 2px solid var(--mg-primary);
  border-radius: var(--radius);
}

.magenta-band img {
  height: 14px;
  width: auto;
}

.magenta-band span {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--mg-gray);
}

/* Le sous-titre carrelage / parquet sous la pastille de sol. */
.swatch .famille {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mg-gray-light);
}

/* « Garder mon sol » n'a pas de matiere a montrer : une pastille
   hachuree, qui se lit comme « rien ne change ». */
.swatch .chip.keep {
  background: repeating-linear-gradient(
    45deg,
    #fff,
    #fff 5px,
    var(--mg-line) 5px,
    var(--mg-line) 10px
  );
}

/* ---- Pictos de section --------------------------------------------------- */

/* Meme cuisine schematique que l'animation « reculez-vous » : le
   visiteur reconnait le dessin d'un ecran a l'autre. La zone concernee
   par la section est pleine, le reste en trait leger. */
.picto {
  width: 46px;
  height: auto;
  flex: none;
  vertical-align: -0.4em;
  margin-right: 0.625rem;
}

.picto .mur {
  fill: none;
  stroke: var(--mg-line);
  stroke-width: 1.5;
}

.picto .on {
  fill: var(--accent);
  stroke: none;
}

.picto .off {
  fill: #fff;
  stroke: var(--mg-gray-light);
  stroke-width: 1.5;
}

.finish-group h2 {
  display: flex;
  align-items: center;
}

#accueil {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
  border-radius: 2px;
}

#accueil:focus-visible {
  outline: 2px solid var(--mg-primary);
  outline-offset: 3px;
}

.encore {
  font-size: 1.0625rem;
  font-weight: 500;
  margin: 2.5rem 0 1rem;
}

/* ---- Choix de la categorie ----------------------------------------------- */

.categories {
  display: grid;
  gap: 0.75rem;
}

.categorie {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  width: 100%;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--mg-line);
  border-radius: var(--radius);
  background: var(--mg-surface);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s;
}

.categorie:hover,
.categorie:focus-visible {
  border-color: var(--mg-primary);
  outline: none;
}

.categorie svg {
  width: 72px;
  height: 40px;
  flex: 0 0 auto;
}

/* Meme langage que les schemas d'implantation : la piece en trait
   leger, ce qui change en plein magenta. */
.categorie svg .mur {
  fill: none;
  stroke: var(--mg-line);
  stroke-width: 1.5;
}
.categorie svg .on { fill: var(--mg-primary); }
.categorie svg .off { fill: var(--mg-gray-light); }

.categorie .titre {
  font-size: 1.0625rem;
  font-weight: 500;
}

/* ---- Choix de la photo --------------------------------------------------- */

/* Un bouton d'entree, pleine largeur ; les deux destinations
   apparaissent ensuite cote a cote sous lui. */
.sources {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
}

.choix-photo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

/* Le bouton d'entree est un <button> et non un <label> : il faut lui
   retirer ce que le navigateur pose sur les boutons. */
button.source {
  font: inherit;
  color: inherit;
  width: 100%;
}


/* Une fois la photo choisie, l'ecran se replie autour d'elle : le
   schema de cadrage s'efface, et le bouton se reduit a une ligne
   discrete qui ne sert plus qu'a changer d'avis. */
.photo-choisie .recul {
  display: none;
}

.photo-choisie .source {
  padding: 0.625rem 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}

.photo-choisie .source .icon {
  margin-bottom: 0;
}

.photo-choisie .source .icon svg {
  width: 18px;
  height: 18px;
}

.photo-choisie .source .title {
  font-size: 0.8125rem;
}

.source {
  display: block;
  border: 1px dashed var(--mg-gray-light);
  border-radius: var(--radius);
  background: var(--mg-surface);
  padding: 2.25rem 1rem;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s;
}

.source:hover {
  border-color: var(--mg-primary);
}

.source .icon {
  display: block;
  color: var(--mg-primary);
  margin-bottom: 0.625rem;
}

.source .icon svg {
  width: 30px;
  height: 30px;
}

.source .title {
  display: block;
  font-weight: 500;
  font-size: 0.9375rem;
  line-height: 1.3;
}

.source input {
  display: none;
}

/* `hidden` ne suffit PAS ici, et c'est un piege de specificite : le
   navigateur pose `[hidden] { display: none }` dans sa feuille par
   defaut, et n'importe quelle regle de CLASSE la bat — ici
   `.source { display: block }`. Le bouton d'entree gardait donc sa
   place apres avoir ete masque par le script, et les trois boutons
   s'affichaient ensemble. Vu sur un Pixel 11 le 2026-09-09.

   Le piege se double d'un piege de MESURE : `element.hidden` rendait
   bien `true`. Seul le `display` calcule dit la verite. */
.source[hidden],
.choix-photo[hidden] {
  display: none;
}

/* L'appareil photo n'existe pas sur un poste fixe : sur un pointeur
   fin, « Prendre une photo » ouvre au mieux une webcam, au pire rien.
   Un seul bouton alors, et il prend toute la largeur.

   Ce bloc DOIT rester le dernier des regles `.source` : a specificite
   egale c'est l'ordre qui tranche, et `.photo-choisie .source` remettait
   `display: flex` sur le bouton qu'on venait de masquer — le double
   bouton reapparaissait des que la photo etait choisie. */
@media (hover: hover) and (pointer: fine) {
  .sources {
    grid-template-columns: 1fr;
  }

  .source.appareil {
    display: none;
  }

  /* Une seule destination reste : il n'y a donc rien a demander. Le
     bouton d'entree s'efface et la galerie s'affiche d'emblee, ce qui
     rend sa tape unique au poste fixe. `[hidden]` se leve ici parce que
     c'est le script qui le pose, et il ne connait pas le pointeur. */
  #ajouter-photo {
    display: none;
  }

  #choix-photo[hidden] {
    display: grid;
  }

  .choix-photo {
    grid-template-columns: 1fr;
  }
}

.preview {
  position: relative;
  margin-top: 1rem;
}

.preview img {
  width: 100%;
  border-radius: var(--radius);
  display: block;
}

/* ---- Champ texte -------------------------------------------------------- */

textarea {
  width: 100%;
  min-height: 140px;
  border: 1px solid var(--mg-line);
  border-radius: var(--radius);
  padding: 0.875rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--mg-ink);
  resize: vertical;
}

textarea:focus {
  outline: none;
  border-color: var(--mg-primary);
}

/* ---- Boutons ------------------------------------------------------------ */

.actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 2rem;
}

.btn {
  font-family: inherit;
  font-size: 1rem;
  border-radius: var(--radius);
  padding: 0.875rem 2rem;
  cursor: pointer;
  border: 1px solid transparent;
  transition: opacity 0.15s;
}

.btn-primary {
  background: var(--mg-primary);
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  opacity: 0.88;
}

.btn-primary:disabled {
  background: var(--mg-line);
  color: var(--mg-gray-light);
  cursor: not-allowed;
}

.btn-ghost {
  background: none;
  color: var(--mg-gray);
  border-color: transparent;
  padding-left: 0;
}

.btn-ghost:hover {
  color: var(--mg-ink);
}

/* ---- Attente ------------------------------------------------------------ */

.waiting {
  text-align: center;
  padding: 4rem 0;
}

/* Les trois bandes de l'icone MAGENTA, qui s'etirent en cascade. Elles
   remplacent le disque tournant : c'est la marque qui travaille, pas un
   composant generique. */
.bandes {
  display: block;
  width: 76px;
  height: auto;
  margin: 0 auto 1.5rem;
}

.bandes rect {
  fill: var(--mg-primary);
  transform-origin: left center;
  animation: bande 1.4s ease-in-out infinite;
}

.bandes rect:nth-child(2) {
  animation-delay: 0.15s;
}

.bandes rect:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes bande {
  0%,
  100% {
    transform: scaleX(0.25);
    opacity: 0.35;
  }
  50% {
    transform: scaleX(1);
    opacity: 1;
  }
}

/* Version reduite du chat : meme animation, plus discrete. */
.bandes.small {
  width: 44px;
  margin: 0.25rem 0;
}

.waiting .elapsed {
  font-variant-numeric: tabular-nums;
  color: var(--mg-gray);
  font-size: 0.875rem;
}

/* ---- Comparateur avant / apres ------------------------------------------ */

/* `width: 100%` est INDISPENSABLE depuis que les deux images sont en
   position absolue : plus rien dans le flux ne donne sa largeur au
   cadre, et le comparateur du fil de retouches se reduisait a la
   largeur de sa bulle — une vignette de 160 px. */
.compare {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  user-select: none;
  line-height: 0;
}

/* Les DEUX images occupent le meme cadre, dont le ratio est celui du
   rendu (`--ratio`, pose par le JS). La photo du visiteur ne fait pas
   toujours exactement 4:3 ou 3:4 : le modele rend au ratio supporte le
   plus proche, et laisser la source fixer la hauteur superposait alors
   deux cadrages differents — l'un des deux etait etire. */
.compare {
  aspect-ratio: var(--ratio, 4 / 3);
}

.compare img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.compare .after {
  /* Pilote par --split, mis a jour par le curseur. */
  clip-path: inset(0 0 0 var(--split, 50%));
}

.compare .handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--split, 50%);
  width: 2px;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
  pointer-events: none;
}

.compare .handle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 36px;
  height: 36px;
  margin: -18px 0 0 -18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
}

.compare input[type='range'] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
}

.compare-legend {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mg-gray);
  margin-top: 0.75rem;
}

/* ---- Resultat ----------------------------------------------------------- */

.result-meta {
  font-size: 0.8125rem;
  color: var(--mg-gray);
  margin-top: 1rem;
}

.result-meta strong {
  color: var(--mg-ink);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.cta {
  border-top: 1px solid var(--mg-line);
  margin-top: 2.5rem;
  padding-top: 2rem;
}

.cta p {
  margin: 0 0 1.25rem;
}

/* ---- Grille du mode labo ------------------------------------------------ */

.labo-grid {
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 720px) {
  .labo-grid {
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
}

.labo-card {
  border: 1px solid var(--mg-line);
  border-radius: var(--radius);
  overflow: hidden;
}

.labo-card img {
  width: 100%;
  display: block;
}

.labo-card .body {
  padding: 0.875rem 1rem;
}

.labo-card .model {
  font-size: 0.8125rem;
  font-weight: 500;
}

.labo-card .time {
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
  color: var(--mg-primary);
}

.labo-card .failed {
  color: var(--mg-gray);
  font-size: 0.8125rem;
  padding: 1.5rem 1rem;
}

/* ---- Erreur ------------------------------------------------------------- */

.error {
  border-left: 2px solid var(--mg-primary);
  background: var(--mg-surface);
  padding: 1rem 1.25rem;
  font-size: 0.875rem;
  margin-top: 1.5rem;
}

.error code {
  display: block;
  color: var(--mg-gray);
  font-size: 0.8125rem;
  margin-top: 0.5rem;
  word-break: break-word;
}

/* ---- Mouvement réduit ---------------------------------------------------- */

/* Qui a désactivé les animations dans son système ne doit pas subir de
   mouvement. Les bandes restent lisibles comme indicateur d'activité
   (pulsation d'opacité, sans déplacement) ; le schéma « reculez-vous »
   se fige sur le cadre large, celui qu'on veut voir adopter. */
@media (prefers-reduced-motion: reduce) {
  .bandes rect {
    animation: bande-douce 1.8s ease-in-out infinite;
    transform: none;
  }

  @keyframes bande-douce {
    0%,
    100% {
      opacity: 0.3;
    }
    50% {
      opacity: 1;
    }
  }

  .recul .cadre,
  .recul .personne {
    animation: none;
  }

  .recul .cadre {
    transform: scale(1);
  }

  .step.active {
    animation: none;
  }
}

/* ---- Chat de retouche ---------------------------------------------------- */

.chat {
  border-top: 1px solid var(--mg-line);
  margin-top: 2rem;
  padding-top: 1.5rem;
}

.chat h2 {
  font-size: 1rem;
  font-weight: 500;
  margin: 0 0 1rem;
}

.fil {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.fil:empty {
  margin-bottom: 0;
}

/* Bulles facon messagerie : le visiteur a droite, nous a gauche. Le
   vocabulaire visuel est connu de tout le monde, il n'a rien a
   apprendre. */
.bulle {
  max-width: 82%;
  padding: 0.625rem 0.875rem;
  border-radius: 14px;
  font-size: 0.9375rem;
  line-height: 1.4;
  white-space: pre-wrap;
}

.bulle.moi {
  align-self: flex-end;
  background: var(--mg-primary);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.bulle.magenta {
  align-self: flex-start;
  background: var(--mg-surface);
  color: var(--mg-ink);
  border: 1px solid var(--mg-line);
  border-bottom-left-radius: 4px;
}

.bulle.echec {
  border-color: var(--mg-primary);
}

.suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

/* Sans amorce, un visiteur ne sait pas quoi ecrire a une IA. Ces quatre
   propositions sont la pour lancer le premier tour ; elles disparaissent
   ensuite. */
.suggestions button {
  font-family: inherit;
  font-size: 0.8125rem;
  padding: 0.4375rem 0.875rem;
  border: 1px solid var(--mg-line);
  border-radius: 999px;
  background: #fff;
  color: var(--mg-ink);
  cursor: pointer;
}

.suggestions button:hover {
  border-color: var(--mg-primary);
  color: var(--mg-primary);
}

.chat-saisie {
  display: flex;
  gap: 0.5rem;
}

.chat-saisie input {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--mg-line);
  border-radius: var(--radius);
  padding: 0.75rem 0.875rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--mg-ink);
}

.chat-saisie input:focus {
  outline: none;
  border-color: var(--mg-primary);
}

.chat-saisie .btn {
  padding: 0.75rem 1.25rem;
  flex: none;
}

/* ---- Formulaire de devis ------------------------------------------------- */

.champ {
  display: block;
  margin-bottom: 1rem;
}

.champ span {
  display: block;
  font-size: 0.8125rem;
  color: var(--mg-gray);
  margin-bottom: 0.375rem;
}

.champ input,
.champ textarea {
  width: 100%;
  border: 1px solid var(--mg-line);
  border-radius: var(--radius);
  padding: 0.75rem 0.875rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--mg-ink);
}

.champ input:focus,
.champ textarea:focus {
  outline: none;
  border-color: var(--mg-primary);
}

/* Le seul ecart avec un champ d'une ligne : il se redimensionne, et
   jamais en largeur — l'etirer casserait la colonne du formulaire. */
.champ textarea {
  resize: vertical;
  min-height: 5.5rem;
  line-height: 1.45;
}

.champ textarea::placeholder {
  color: var(--mg-gray-light);
}

.consent {
  display: flex;
  gap: 0.625rem;
  align-items: flex-start;
  font-size: 0.875rem;
  margin: 1.25rem 0 1rem;
  cursor: pointer;
}

.consent input {
  margin-top: 0.2em;
  accent-color: var(--mg-primary);
  flex: none;
}

/* La mention de traitement doit etre lisible, pas cachee en gris pale :
   c'est ce que le visiteur accepte en cochant la case au-dessus. */
/* L'asterisque des champs obligatoires, et la mention inverse pour les
   autres. Marquer les DEUX evite l'hesitation : sans le « facultatif »,
   un champ sans asterisque se lit comme un oubli de balisage. */
.champ .requis,
.consent .requis,
.mention .requis {
  color: var(--mg-primary);
  font-style: normal;
  font-weight: 600;
}

.champ .option {
  color: var(--mg-gray);
  font-style: normal;
  font-weight: 400;
  font-size: 0.8125rem;
}

.mention {
  font-size: 0.8125rem;
  color: var(--mg-gray);
  background: var(--mg-surface);
  border-left: 2px solid var(--mg-line);
  padding: 0.75rem 0.875rem;
  margin: 0 0 1.5rem;
}

/* Une bulle qui porte une image : la retouche s'affiche dans le fil,
   sous la demande qui l'a produite. Les versions precedentes restent
   au-dessus — le visiteur suit l'evolution de son projet. */
.bulle.avec-image {
  /* `width` et pas seulement `max-width` : une bulle se dimensionne sur
     son contenu, et le `width: 100%` du comparateur se resolvait alors
     contre une largeur elle-meme deduite du contenu — circulaire, d'ou
     une vignette de 160 px dans le fil. */
  width: 100%;
  max-width: 100%;
  padding: 0;
  background: none;
  border: none;
  overflow: hidden;
  border-radius: var(--radius);
}

/* Le comparateur du fil : meme composant qu'en haut de page, a la
   largeur de la bulle. */
.bulle.avec-image .compare {
  border: 1px solid var(--mg-line);
}

.bulle.avec-image .compare-legend {
  margin-bottom: 0.25rem;
}


/* ---- Interrupteur << meubles hauts >> ------------------------------- */
/*
   Actif par defaut : une cuisine EN A. Le visiteur desactive, il
   n'active pas. Un premier jet proposait une pastille << Sans meubles
   hauts >> en tete du rail, sur le modele de << Garder mon sol >> ;
   mais garder son sol est le cas frequent, alors que se passer de
   meubles hauts est l'exception, et la pastille se lisait comme une
   matiere de plus parmi cent cinquante.
*/
.bascule {
  /* `flex` et non `inline-flex` : l'etiquette de groupe qui suit
     (<< BOIS >>, << LAQUES >>…) se collait a la fin du texte. */
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  cursor: pointer;
  user-select: none;
}
.bascule input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.bascule .piste {
  flex: none;
  width: 28px;
  height: 16px;
  border-radius: 8px;
  background: var(--mg-gray-light);
  position: relative;
  transition: background 0.18s ease;
}
.bascule .piste::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.18s ease;
}
.bascule input:checked + .piste { background: var(--mg-primary); }
.bascule input:checked + .piste::after { transform: translateX(12px); }
.bascule input:focus-visible + .piste {
  outline: 2px solid var(--mg-primary);
  outline-offset: 2px;
}
/* Meme corps que le nom d'une finition : l'interrupteur est un
   reglage, pas un titre. */
.bascule .texte { font-size: 0.6875rem; color: var(--mg-ink); }
.bascule input:not(:checked) ~ .texte { color: var(--mg-gray); }

/* Le rail se replie quand les meubles hauts sont retires : laisser 150
   pastilles inertes sous un interrupteur eteint invite au clic. */
.finish-group.sans-hauts .rail,
.finish-group.sans-hauts .groupe { display: none; }

@media (prefers-reduced-motion: reduce) {
  .bascule .piste,
  .bascule .piste::after { transition: none; }
}


/* La douche a l'italienne n'est pas un detail de finition mais une
   facon de construire la piece : son interrupteur se lit donc au corps
   du texte courant, contrairement a celui des meubles hauts. */
.bascule-large { margin: 0 0 1.5rem; gap: 0.75rem; }
.bascule-large .piste { width: 42px; height: 24px; border-radius: 12px; }
.bascule-large .piste::after { top: 3px; left: 3px; width: 18px; height: 18px; }
.bascule-large input:checked + .piste::after { transform: translateX(18px); }
.bascule-large .texte { font-size: 0.9375rem; }

/* Deux interrupteurs de suite se lisent comme une paire : le premier
   se rapproche du second, et l'ecart d'avant reste celui du titre. */
.bascule-paire { margin-bottom: 0.625rem; }
