/* ============================================================================
   fleuriste.css — Module de commande de fleurs sur mesure.
   ----------------------------------------------------------------------------
   Une seule feuille pour les deux faces du module : l'espace du fleuriste
   (`body.espace`) et le formulaire public (`body.commande`). Elles partagent
   variables, boutons et champs — c'est le même produit.

   Indépendante des autres modules, par décision : ni tokens.css du calculateur,
   ni reservation.css. Un module doit pouvoir évoluer sans casser son voisin.

   --- LE PARTI PRIS VISUEL --------------------------------------------------
   Du papier, de l'encre, de l'espace. Un fleuriste travaille une matière
   vivante ; l'écran qui vend son travail ne doit pas ressembler à un tableur.
   D'où le fond crème plutôt que blanc, les angles généreux, et une seule
   couleur d'accent — la sienne, réglable — qui ne sert qu'à désigner ce qui est
   choisi.
   ============================================================================ */

:root{
  --fond:#fbf8f5;
  --fond-creux:#f4eee9;
  --carte:#ffffff;
  --texte:#241c22;          /* sur --carte : 15,9:1 */
  --gris:#5c5159;           /* sur --carte :  7,4:1 */
  --discret:#736670;        /* sur --carte :  5,1:1 */
  --trait:#e8dfe0;
  --trait-fort:#d3c5c8;

  /* L'accent est réécrit par la boutique. Ces valeurs sont le repli. */
  --accent:#b0407a;         /* blanc dessus : 5,44:1 */
  --accent-fonce:#8a2f5f;
  --accent-tres-clair:#fbeef4;
  --accent-clair:#f2d9e5;

  --ok:#0f6b45;
  --ok-fond:#e6f4ee;
  --attention:#8a5a00;
  --attention-fond:#fdf3e0;
  --alerte:#a8261f;
  --alerte-fond:#fceceb;
  /* Le ton « Premium » du guide : un ambre, distinct des trois autres. */
  --or:#8a5a00;
  --or-fond:#fdf6e3;

  --deuil:#3f4a54;          /* le parcours obsèques quitte le rose */
  --deuil-fond:#eef1f4;

  --r:14px;
  --r-grand:22px;
  --r-pilule:999px;
  --ombre:0 4px 16px -6px rgba(36,28,34,.14);
  --ombre-forte:0 18px 44px -18px rgba(36,28,34,.30);
  --duree:180ms;
  --courbe:cubic-bezier(.22,.61,.36,1);

  /* Le crochet de validation, dessiné une fois et découpé dans un masque : il
     prend alors la couleur de la boutique, quelle qu'elle soit. Une image
     coloriée d'avance obligerait à en produire une par accent. */
  --crochet:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round' d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");

  /* Le pendant CSS de la balise <meta>. Il couvre le cas ou la page est posee
     dans une iframe : c'est le document interne qui compte, et le site du
     fleuriste ne portera pas notre balise. Sans ca, les CHAMPS du formulaire
     embarque redeviennent noirs chez un visiteur en mode sombre, alors que
     tout le reste de la page est clair. */
  color-scheme:light;

  --serif:ui-serif, Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  --sans:ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial;
}

*{ box-sizing:border-box; }

/* --- POURQUOI CETTE RÈGLE EST LA PREMIÈRE DE LA FEUILLE --------------------
   L'attribut `hidden` n'est qu'un `display:none` posé par le navigateur. La
   moindre règle d'auteur qui donne un `display` à l'élément — `display:flex`
   sur un bandeau, `display:grid` sur une grille — l'emporte sur lui, et
   l'élément reste visible alors que le script le croit caché. Constaté ici :
   le conseil du fleuriste s'affichait vide au chargement.
   Une seule règle règle le cas pour toute la feuille, définitivement. */
[hidden]{ display:none !important; }

body{
  margin:0;
  min-height:100dvh;
  display:flex;
  flex-direction:column;
  background:var(--fond);
  color:var(--texte);
  font-family:var(--sans);
  font-size:15px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3{ margin:0; line-height:1.2; }
h1,h2{ font-family:var(--serif); font-weight:600; letter-spacing:-.01em; }
p{ margin:0 0 .8em; }
a{ color:var(--accent-fonce); }

/* Le parcours deuil bascule toute la page dans une tonalité sobre. Ce n'est pas
   une coquetterie : on ne choisit pas une gerbe d'obsèques dans la même
   ambiance qu'un bouquet d'anniversaire. */
body[data-ton="deuil"]{
  --accent:var(--deuil);
  --accent-fonce:#2c353d;
  --accent-tres-clair:#f3f5f7;
  --accent-clair:#dde3e8;
}

/* ---------------------------------------------------------------------------
   1. Ossature
--------------------------------------------------------------------------- */
.enveloppe{
  width:100%;
  max-width:840px;
  margin:0 auto;
  padding:20px 18px 56px;
  flex:1;
}

.entete{
  display:flex;
  align-items:center;
  gap:14px;
  padding:14px 0 20px;
  border-bottom:1px solid var(--trait);
  margin-bottom:22px;
}
.entete__logo{
  height:46px; width:auto; max-width:160px;
  object-fit:contain;
  flex:0 0 auto;
}
.entete__textes{ min-width:0; }
.entete__nom{ font-size:1.15rem; font-family:var(--serif); font-weight:600; }
.entete__mot{ color:var(--gris); font-size:.9rem; margin:2px 0 0; }

/* ---------------------------------------------------------------------------
   2. Le fil des étapes
   Il indique où l'on en est, pas où l'on peut aller : cliquer dessus ne saute
   pas une étape non remplie.
--------------------------------------------------------------------------- */
.fil{
  display:flex;
  gap:6px;
  margin:0 0 24px;
  padding:0;
  list-style:none;
}
.fil__pas{
  flex:1 1 0;
  min-width:0;
  height:5px;
  border-radius:var(--r-pilule);
  background:var(--trait);
  transition:background var(--duree) var(--courbe);
}
.fil__pas--faite{ background:var(--accent-clair); }
.fil__pas--ici{ background:var(--accent); }
.fil__legende{
  display:flex; justify-content:space-between;
  font-size:.78rem; color:var(--discret);
  margin:-16px 0 24px;
}

/* ---------------------------------------------------------------------------
   3. Étapes et titres
--------------------------------------------------------------------------- */
.etape{ display:none; animation:apparait var(--duree) var(--courbe); }
.etape--ici{ display:block; }
@keyframes apparait{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){
  .etape{ animation:none; }
  *{ transition-duration:1ms !important; }
}

.etape__titre{ font-size:1.5rem; margin:0 0 6px; }
.etape__sous{ color:var(--gris); margin:0 0 22px; }

fieldset{ border:0; margin:0 0 26px; padding:0; }
legend{ padding:0; font-weight:600; margin-bottom:10px; }

/* ---------------------------------------------------------------------------
   4. Les tuiles de choix (occasion, palette, palier, mode de remise)
--------------------------------------------------------------------------- */
.tuiles{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(min(100%, 180px), 1fr));
  gap:10px;
}
.tuiles--large{ grid-template-columns:repeat(auto-fill, minmax(min(100%, 250px), 1fr)); }

.tuile{
  position:relative;
  display:flex;
  flex-direction:column;
  gap:3px;
  text-align:left;
  padding:14px 16px;
  min-height:64px;
  background:var(--carte);
  border:1.5px solid var(--trait);
  border-radius:var(--r);
  color:var(--texte);
  font:inherit;
  cursor:pointer;
  transition:border-color var(--duree) var(--courbe),
             background var(--duree) var(--courbe),
             transform var(--duree) var(--courbe);
}
.tuile:hover{ border-color:var(--trait-fort); transform:translateY(-1px); }
.tuile[aria-pressed="true"]{
  border-color:var(--accent);
  background:var(--accent-tres-clair);
}
.tuile[aria-pressed="true"]::after{
  content:"";
  position:absolute; inset:-1.5px;
  border:1.5px solid var(--accent);
  border-radius:var(--r);
  pointer-events:none;
}
.tuile__nom{ font-weight:600; }
.tuile__note{ font-size:.86rem; color:var(--gris); }
.tuile__prix{ font-variant-numeric:tabular-nums; font-weight:600; color:var(--accent-fonce); }

/* Les pastilles d'une palette. */
.pastilles{ display:flex; gap:5px; margin-top:8px; }
.pastille{
  width:20px; height:20px; border-radius:50%;
  border:1px solid rgba(36,28,34,.16);
  flex:0 0 auto;
}

/* ---------------------------------------------------------------------------
   5. Le conseil du fleuriste
   Une phrase, celle qu'il aurait dite au comptoir. Elle apparaît sous
   l'occasion choisie et nulle part ailleurs.
--------------------------------------------------------------------------- */
.conseil{
  display:flex; gap:12px; align-items:flex-start;
  margin:18px 0 0;
  padding:14px 16px;
  background:var(--accent-tres-clair);
  border-left:3px solid var(--accent);
  border-radius:0 var(--r) var(--r) 0;
  font-size:.94rem;
}
.conseil__quoi{ font-weight:600; display:block; margin-bottom:2px; font-size:.8rem;
  text-transform:uppercase; letter-spacing:.05em; color:var(--accent-fonce); }

/* ---------------------------------------------------------------------------
   6. LA GRILLE DES FLEURS
   Le cœur du formulaire. Chaque vignette porte une fiche : symbolique,
   histoire, saison, parfum, tenue en vase, précaution. Elle s'ouvre au survol
   sur un écran à souris, et au toucher partout — un survol seul n'existe pas
   sur un téléphone, et la moitié des commandes viendront d'un téléphone.
--------------------------------------------------------------------------- */
.fleurs{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(min(100%, 116px), 1fr));
  gap:12px;
  margin:0;
  padding:0;
  list-style:none;
}
.fleur{ position:relative; }

.fleur__bouton{
  width:100%;
  display:flex; flex-direction:column; align-items:stretch; gap:8px;
  padding:8px 8px 10px;
  background:var(--carte);
  border:1.5px solid var(--trait);
  border-radius:var(--r);
  color:var(--texte);
  font:inherit;
  text-align:center;
  cursor:pointer;
  transition:border-color var(--duree) var(--courbe), transform var(--duree) var(--courbe);
}
.fleur__bouton:hover{ border-color:var(--trait-fort); transform:translateY(-2px); }
.fleur__bouton[aria-pressed="true"]{ border-color:var(--accent); background:var(--accent-tres-clair); }

.fleur__vignette{
  aspect-ratio:1;
  width:100%;
  border-radius:10px;
  background:var(--fond-creux);
  object-fit:cover;
  display:block;
}
.fleur__dessin{
  aspect-ratio:1; width:100%;
  border-radius:10px;
  background:var(--accent-tres-clair);
  display:grid; place-items:center;
  color:var(--accent);
}
.fleur__dessin svg{ width:52%; height:52%; opacity:.75; }

.fleur__nom{ font-size:.86rem; font-weight:600; line-height:1.25; }
.fleur__sym{ font-size:.75rem; color:var(--discret); line-height:1.3;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }

/* Le drapeau d'une précaution : visible sans ouvrir la fiche. */
.fleur__alerte{
  position:absolute; top:6px; right:6px;
  width:20px; height:20px; border-radius:50%;
  background:var(--attention-fond);
  color:var(--attention);
  display:grid; place-items:center;
  font-size:.7rem; font-weight:700;
  border:1px solid rgba(138,90,0,.28);
}

/* La fiche. */
.fiche{
  position:absolute;
  z-index:30;
  left:50%;
  top:calc(100% + 8px);
  transform:translateX(-50%);
  width:min(320px, calc(100vw - 32px));
  background:var(--carte);
  border:1px solid var(--trait-fort);
  border-radius:var(--r);
  box-shadow:var(--ombre-forte);
  padding:14px 16px;
  text-align:left;
  font-size:.86rem;
  line-height:1.5;
  /* Une fiche plus haute que l'ecran ne rentre nulle part : ni au-dessus de sa
     vignette, ni en dessous. On la plafonne, et elle defile a l'interieur. */
  max-height:min(62vh, 440px);
  overflow-y:auto;
  overscroll-behavior:contain;
}
.fiche--haut{ top:auto; bottom:calc(100% + 8px); }
.fiche__nom{ font-family:var(--serif); font-size:1.05rem; font-weight:600; margin:0 0 2px; }
.fiche__sym{ color:var(--accent-fonce); font-weight:600; margin:0 0 8px; }
.fiche__histoire{ color:var(--gris); margin:0 0 10px; }
.fiche__faits{ display:grid; grid-template-columns:auto 1fr; gap:3px 10px; margin:0; font-size:.82rem; }
.fiche__faits dt{ color:var(--discret); }
.fiche__faits dd{ margin:0; }
.fiche__precaution{
  margin:10px 0 0; padding:8px 10px;
  background:var(--attention-fond); color:var(--attention);
  border-radius:9px; font-size:.82rem;
}
.fiche__fermer{
  position:absolute; top:6px; right:6px;
  width:28px; height:28px; border:0; border-radius:50%;
  background:transparent; color:var(--discret);
  font-size:1.1rem; line-height:1; cursor:pointer;
}
.fiche__fermer:hover{ background:var(--fond-creux); }

/* ---------------------------------------------------------------------------
   6 bis. Les deux façons de commander
--------------------------------------------------------------------------- */

/* Bouquet composé : ce qui a été choisi, avec une quantité facultative.
   La liste apparaît sous la grille plutôt qu'en pastilles dans les vignettes :
   un champ de saisie dans une tuile de 116 px est illisible au doigt. */
.choisies{ list-style:none; margin:0; padding:0; display:grid; gap:8px; }
.choisie{
  display:flex; align-items:center; gap:12px;
  padding:10px 14px;
  background:var(--carte);
  border:1px solid var(--trait);
  border-radius:11px;
}
.choisie__nom{ flex:1 1 auto; min-width:0; font-weight:600; }
.choisie__qte{ width:88px; flex:0 0 auto; }
.choisie__qte input{ padding:7px 9px; text-align:center; }
.choisie__oter{
  flex:0 0 auto;
  width:30px; height:30px; padding:0;
  border:0; border-radius:50%;
  background:transparent; color:var(--discret);
  font-size:1.2rem; line-height:1; cursor:pointer;
}
.choisie__oter:hover{ background:var(--fond-creux); color:var(--alerte); }

/* Une seule variété : le compteur de tiges. Gros boutons, gros chiffre —
   c'est la seule saisie du formulaire qu'on fait à répétition. */
.compteur-tiges{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin-bottom:12px;
}
.compteur-tiges input[type="number"]{
  width:110px; flex:0 0 auto;
  text-align:center;
  font-family:var(--serif);
  font-size:1.6rem; font-weight:600;
  font-variant-numeric:tabular-nums;
  padding:8px 6px;
}
.btn--rond{
  width:46px; height:46px; padding:0; flex:0 0 auto;
  border-radius:50%;
  font-size:1.5rem; line-height:1;
}
.compteur-tiges__prix{
  font-family:var(--serif);
  font-size:1.5rem; font-weight:600;
  font-variant-numeric:tabular-nums;
  color:var(--accent-fonce);
  margin-left:auto;
}
@media (max-width:420px){
  .compteur-tiges__prix{ margin-left:0; width:100%; }
}

/* Le prix de la tige, sur la vignette, quand on commande à l'unité. */
.fleur__tige{
  font-size:.76rem; font-weight:600;
  color:var(--accent-fonce);
  font-variant-numeric:tabular-nums;
}

/* ---------------------------------------------------------------------------
   7. Le budget
--------------------------------------------------------------------------- */
.budget__montant{
  font-family:var(--serif);
  font-size:2.6rem;
  font-weight:600;
  font-variant-numeric:tabular-nums;
  color:var(--accent-fonce);
  line-height:1;
  margin:6px 0 4px;
}
.budget__bornes{ display:flex; justify-content:space-between; font-size:.8rem; color:var(--discret); }

input[type="range"]{
  width:100%; margin:10px 0 4px;
  accent-color:var(--accent);
  height:28px;
}

/* ---------------------------------------------------------------------------
   8. Champs
--------------------------------------------------------------------------- */
/* --- L'ALIGNEMENT DES CHAMPS ---------------------------------------------
   Un `.champ` est une colonne : l'etiquette en haut, le cadre de saisie
   POUSSE en bas par `margin-top:auto`. Les etiquettes d'une meme rangee font
   une, deux ou trois lignes selon qu'elles portent une aide ; sans cela, les
   cadres descendaient d'autant et se retrouvaient a trois hauteurs
   differentes. C'est le detail qui fait qu'un formulaire a l'air bricole.
   ------------------------------------------------------------------------ */
.champ{
  display:flex; flex-direction:column;
  min-width:0;                 /* sinon un champ long elargit toute la grille */
  margin:0 0 16px;
}
.champ__label{ display:block; font-weight:600; margin-bottom:5px; }
.champ__aide{ display:block; font-weight:400; color:var(--discret); font-size:.85rem; margin-top:1px; }

/* Ce qui se saisit vient en dernier, quoi qu'il y ait au-dessus. */
.champ > input,
.champ > select,
.champ > textarea,
.champ > .champ-couleur{ margin-top:auto; }

/* Le champ de fichier est habillé comme les autres : sans cela, c'est le seul
   contrôle de la page a garder l'allure brute du navigateur, et le seul à ne
   pas tomber à la même hauteur que ses voisins de rangée. */
input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
input[type="number"], input[type="time"], input[type="date"], input[type="file"],
input[type="search"], select, textarea{
  width:100%;
  padding:11px 13px;
  background:var(--carte);
  border:1.5px solid var(--trait-fort);
  border-radius:11px;
  color:var(--texte);
  font:inherit;
}
textarea{ min-height:96px; resize:vertical; }

/* Le bouton interne du champ de fichier : sans mise en forme, il garde le gris
   système au milieu d'une ligne dessinée. */
/* Une hauteur commune à TOUS les contrôles. Le champ de fichier porte un
   bouton interne dont la hauteur dépend du navigateur : il faisait 54 px là
   où une liste déroulante en fait 46, et les deux ne tombaient pas au même
   niveau dans une rangée. On fixe la hauteur plutôt que de courir après les
   remplissages. */
input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
input[type="number"], input[type="time"], input[type="date"], input[type="file"],
input[type="search"], select{ min-height:46px; }

input[type="file"]{
  display:flex; align-items:center;
  padding:0 10px; cursor:pointer;
}
input[type="file"]::file-selector-button{
  margin-right:10px; padding:6px 12px;
  border:1px solid var(--trait-fort); border-radius:8px;
  background:var(--fond-creux); color:var(--texte);
  font:inherit; font-size:.86rem; font-weight:600;
  cursor:pointer;
}
input[type="file"]::file-selector-button:hover{ border-color:var(--accent); }
input::placeholder, textarea::placeholder{ color:var(--discret); }

:where(button, a, input, select, textarea, [tabindex]):focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:6px;
}

.duo{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:0 14px; }
.duo--cp{ grid-template-columns:minmax(0,120px) minmax(0,1fr); }
@media (max-width:520px){ .duo, .duo--cp{ grid-template-columns:minmax(0,1fr); } }

.compteur{ font-size:.8rem; color:var(--discret); text-align:right; margin-top:-10px; }

/* ---------------------------------------------------------------------------
   9. Le calendrier
--------------------------------------------------------------------------- */
.jours{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(min(100%, 150px), 1fr));
  gap:8px;
  max-height:290px;
  overflow-y:auto;
  padding:2px;
}
.jour{
  padding:11px 12px;
  background:var(--carte);
  border:1.5px solid var(--trait);
  border-radius:11px;
  font:inherit; color:var(--texte);
  text-align:left; cursor:pointer;
}
.jour:hover{ border-color:var(--trait-fort); }
.jour[aria-pressed="true"]{ border-color:var(--accent); background:var(--accent-tres-clair); }
.jour__date{ display:block; font-weight:600; }
.jour__reste{ display:block; font-size:.78rem; color:var(--attention); font-weight:600; }

.creneaux{ display:flex; flex-wrap:wrap; gap:8px; margin-top:14px; }
.creneau{
  padding:9px 15px;
  border:1.5px solid var(--trait);
  border-radius:var(--r-pilule);
  background:var(--carte);
  font:inherit; color:var(--texte); cursor:pointer;
}
.creneau[aria-pressed="true"]{ border-color:var(--accent); background:var(--accent-tres-clair); font-weight:600; }

/* ---------------------------------------------------------------------------
   10. Récapitulatif
--------------------------------------------------------------------------- */
.recap{
  background:var(--carte);
  border:1px solid var(--trait);
  border-radius:var(--r-grand);
  padding:18px 20px;
  margin:0 0 22px;
  box-shadow:var(--ombre);
}
.recap__lignes{ display:grid; grid-template-columns:auto 1fr; gap:7px 16px; margin:0; }
.recap__lignes dt{ color:var(--discret); }
.recap__lignes dd{ margin:0; }
.recap__total{
  display:flex; justify-content:space-between; align-items:baseline;
  margin-top:16px; padding-top:14px;
  border-top:1px solid var(--trait);
  font-family:var(--serif); font-size:1.35rem; font-weight:600;
}
.recap__total span:last-child{ font-variant-numeric:tabular-nums; color:var(--accent-fonce); }

/* ---------------------------------------------------------------------------
   11. Boutons et messages
--------------------------------------------------------------------------- */
.barre{
  display:flex; gap:10px; align-items:center;
  margin-top:26px; padding-top:20px;
  border-top:1px solid var(--trait);
}
.barre__vide{ flex:1; }

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 22px;
  border:1.5px solid transparent;
  border-radius:var(--r-pilule);
  background:var(--accent); color:#fff;
  font:inherit; font-weight:600;
  cursor:pointer;
  transition:background var(--duree) var(--courbe), transform var(--duree) var(--courbe);
}
.btn:hover{ background:var(--accent-fonce); transform:translateY(-1px); }
.btn[disabled]{ opacity:.55; cursor:not-allowed; transform:none; }
.btn--fantome{ background:transparent; color:var(--gris); border-color:var(--trait-fort); }
.btn--fantome:hover{ background:var(--fond-creux); color:var(--texte); }

.note{
  padding:12px 15px;
  border-radius:11px;
  font-size:.9rem;
  margin:0 0 16px;
}
.note--info{ background:var(--accent-tres-clair); color:var(--texte); }
.note--ok{ background:var(--ok-fond); color:var(--ok); }
.note--attention{ background:var(--attention-fond); color:var(--attention); }
.note--ko{ background:var(--alerte-fond); color:var(--alerte); }

/* ---------------------------------------------------------------------------
   12. Écran de confirmation
--------------------------------------------------------------------------- */
.fini{ text-align:center; padding:40px 10px; }
.fini__rond{
  width:72px; height:72px; margin:0 auto 20px;
  border-radius:50%;
  background:var(--ok-fond); color:var(--ok);
  display:grid; place-items:center;
}
.fini__titre{ font-size:1.7rem; margin-bottom:10px; }
.fini__ref{
  display:inline-block;
  margin:14px 0 0;
  padding:9px 18px;
  background:var(--fond-creux);
  border-radius:var(--r-pilule);
  font-variant-numeric:tabular-nums;
  font-weight:700; letter-spacing:.06em;
}

.pied{
  text-align:center;
  padding:22px 16px 30px;
  color:var(--discret);
  font-size:.82rem;
}

/* ---------------------------------------------------------------------------
   12 ter. LE PANIER
   Les bouquets deja mis de cote. Le bloc n'apparait qu'a partir du deuxieme :
   un panier vide en haut de page ne fait que poser une question a quelqu'un
   qui n'en commande qu'un — et c'est la quasi-totalite des commandes.
--------------------------------------------------------------------------- */
.panierBloc{
  margin:0 0 18px;
  padding:12px 16px;
  background:var(--accent-tres-clair);
  border-radius:14px;
}
.panierBloc__titre{
  margin:0 0 8px;
  font-size:.78rem; font-weight:700; letter-spacing:.03em;
  text-transform:uppercase; color:var(--accent-fonce);
}
.panier{ list-style:none; margin:0; padding:0; }
.panier__ligne{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:7px 0;
  border-bottom:1px solid var(--trait);
  font-size:.9rem;
}
.panier__ligne:last-child{ border-bottom:0; }
.panier__ligne--encours{ color:var(--gris); font-style:italic; }
.panier__rang{ font-weight:700; min-width:82px; }
.panier__quoi{ flex:1 1 auto; min-width:0; }
.panier__prix{ font-weight:700; white-space:nowrap; }
.panier__oter{
  border:0; background:none; padding:0;
  color:var(--alerte); font:inherit; font-size:.82rem;
  text-decoration:underline; cursor:pointer;
}

/* La ligne qui invite a en ajouter un second. Discrete : la plupart des
   clients n'en veulent qu'un, et elle ne doit pas ressembler a une etape. */
.etape__multi{
  margin:10px 0 0;
  font-size:.86rem; color:var(--gris);
}
.barre--ajouter{ flex-wrap:wrap; }

/* ---------------------------------------------------------------------------
   13. Mode sombre
   La page est posée sur le site du fleuriste et lue partout ; on suit le
   réglage du visiteur. Seules les variables changent — aucune règle de mise
   en page n'est dupliquée.
--------------------------------------------------------------------------- */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --fond:#191317;
    --fond-creux:#241c22;
    --carte:#221a20;
    --texte:#f2eaee;        /* sur --carte : 14,3:1 */
    --gris:#c3b2bb;
    --discret:#a3919b;      /* sur --carte : 6,1:1 */
    --trait:#3a2e35;
    --trait-fort:#54434c;

    --accent:#e888b4;       /* fond sombre dessous : 7,0:1 */
    --accent-fonce:#f0a8c9;
    --accent-tres-clair:#33202a;
    --accent-clair:#4a2c3b;

    --ok:#6fd8a8;   --ok-fond:#17322a;
    --attention:#f0c070; --attention-fond:#332818;
    --alerte:#f09a94;    --alerte-fond:#3a1f1d;
    --or:#e8c169;        --or-fond:#332a16;
    --deuil:#a8bccd;     --deuil-fond:#222a31;

    --ombre:0 4px 16px -6px rgba(0,0,0,.5);
    --ombre-forte:0 18px 44px -18px rgba(0,0,0,.7);
  }
  /* Le texte sombre ne vaut que pour le bouton PLEIN, dont le fond est
     l'accent clair. Les variantes transparentes gardent leur propre couleur :
     sans cette exclusion, « Annuler » s'écrivait en #191317 sur une carte
     sombre — un bouton parfaitement invisible, constaté à l'écran. La
     spécificité de ce sélecteur (0-3-0) écrase celle de .btn--danger (0-1-0),
     et c'est exactement ce qu'il ne fallait pas. */
  :root:not([data-theme="light"]) .btn:not(.btn--fantome):not(.btn--danger){ color:#191317; }
  :root:not([data-theme="light"]) .cal__case[aria-pressed="true"]{ color:#191317; }
  :root:not([data-theme="light"]) .pastille{ border-color:rgba(255,255,255,.22); }
}

/* ---------------------------------------------------------------------------
   13 bis. LE MÊME SOMBRE, MAIS CHOISI

   Le bloc ci-dessus ne s'applique qu'à un visiteur dont le SYSTÈME est en
   sombre. Le fleuriste qui demande expressément un formulaire sombre n'avait
   donc aucun effet : `data-theme="dark"` ne déclenchait rien.

   CSS n'a pas de mixin, et une déclaration ne peut pas être à la fois dans
   une requête média et hors d'elle. On duplique. Le test `test-theme.php`
   compare les deux blocs jeton par jeton et échoue s'ils divergent : c'est ce
   qui empêche la copie de vieillir en silence.
--------------------------------------------------------------------------- */
:root[data-theme="dark"]{
  color-scheme:dark;
  --fond:#191317;
  --fond-creux:#241c22;
  --carte:#221a20;
  --texte:#f2eaee;        /* sur --carte : 14,3:1 */
  --gris:#c3b2bb;
  --discret:#a3919b;      /* sur --carte : 6,1:1 */
  --trait:#3a2e35;
  --trait-fort:#54434c;

  --accent:#e888b4;       /* fond sombre dessous : 7,0:1 */
  --accent-fonce:#f0a8c9;
  --accent-tres-clair:#33202a;
  --accent-clair:#4a2c3b;

  --ok:#6fd8a8;   --ok-fond:#17322a;
  --attention:#f0c070; --attention-fond:#332818;
  --alerte:#f09a94;    --alerte-fond:#3a1f1d;
  --or:#e8c169;        --or-fond:#332a16;
  --deuil:#a8bccd;     --deuil-fond:#222a31;

  --ombre:0 4px 16px -6px rgba(0,0,0,.5);
  --ombre-forte:0 18px 44px -18px rgba(0,0,0,.7);
}
/* Le texte sombre ne vaut que pour le bouton PLEIN, dont le fond est
   l'accent clair. Les variantes transparentes gardent leur propre couleur :
   sans cette exclusion, « Annuler » s'écrivait en #191317 sur une carte
   sombre — un bouton parfaitement invisible, constaté à l'écran. La
   spécificité de ce sélecteur (0-3-0) écrase celle de .btn--danger (0-1-0),
   et c'est exactement ce qu'il ne fallait pas. */
:root[data-theme="dark"] .btn:not(.btn--fantome):not(.btn--danger){ color:#191317; }
:root[data-theme="dark"] .cal__case[aria-pressed="true"]{ color:#191317; }
:root[data-theme="dark"] .pastille{ border-color:rgba(255,255,255,.22); }

/* ---------------------------------------------------------------------------
   13 ter. LE FILTRE DE LA GRILLE DE FLEURS
   Une barre discrète : elle sert à chercher, pas à se faire remarquer. Elle
   n'apparaît qu'au-dessus de dix vignettes — en filtrer six serait du bruit.
--------------------------------------------------------------------------- */
.filtres{
  display:grid; gap:10px;
  padding:14px 16px; margin:0 0 16px;
  background:var(--fond-creux);
  border-radius:14px;
}
.filtres__label{
  display:block;
  font-size:.78rem; font-weight:600; color:var(--gris);
  text-transform:uppercase; letter-spacing:.03em;
  margin-bottom:5px;
}
.filtres__champ input{
  width:100%; box-sizing:border-box;
  padding:10px 13px;
  border:1.5px solid var(--trait-fort); border-radius:11px;
  background:var(--carte); color:var(--texte);
  font:inherit;
}
.filtres__champ input:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
.filtres__ligne{ min-width:0; }
.filtres__chips{ display:flex; flex-wrap:wrap; gap:6px; }

.chip{
  padding:6px 13px;
  border:1.5px solid var(--trait-fort); border-radius:var(--r-pilule);
  background:var(--carte); color:var(--gris);
  font:inherit; font-size:.86rem; font-weight:600;
  cursor:pointer;
}
.chip:hover{ color:var(--texte); border-color:var(--accent); }
.chip[aria-pressed="true"]{
  background:var(--accent-tres-clair);
  border-color:var(--accent);
  color:var(--accent-fonce);
}

/* Le conseil du fleuriste, marque sur la vignette : il ouvre la grille sans
   l'enfermer. Un client qui veut des tournesols pour un anniversaire n'a pas
   tort — c'est la liste qui est courte. */
.fleur__conseil{
  display:block; margin-top:3px;
  font-size:.72rem; font-weight:700; line-height:1.3;
  color:var(--accent-fonce);
}

.filtres__pied{
  display:flex; align-items:center; gap:12px;
  font-size:.84rem; color:var(--gris);
}
.filtres__compte{ flex:1 1 auto; }
.filtres__reset{
  border:0; background:none; padding:0;
  color:var(--accent-fonce); font:inherit; font-size:.84rem; font-weight:600;
  text-decoration:underline; cursor:pointer;
}

/* ---------------------------------------------------------------------------
   13 quater. LE CALENDRIER
   Un mois en semaines. Les jours fermés restent visibles et désactivés : une
   case grise le mardi apprend que la boutique ferme ce jour-là ; une case
   absente fait croire à une panne.
--------------------------------------------------------------------------- */
.cal{
  background:var(--carte);
  border:1.5px solid var(--trait);
  border-radius:14px;
  padding:12px;
  max-width:380px;
}
.cal__tete{
  display:flex; align-items:center; justify-content:space-between;
  gap:8px; margin-bottom:8px;
}
.cal__mois{ font-weight:600; text-transform:capitalize; }
.cal__fleche{
  width:34px; height:34px;
  border:1.5px solid var(--trait); border-radius:10px;
  background:var(--carte); color:var(--texte);
  font-size:1.2rem; line-height:1; cursor:pointer;
}
.cal__fleche:hover:not(:disabled){ border-color:var(--accent); }
.cal__fleche:disabled{ opacity:.35; cursor:not-allowed; }

.cal__jours{
  display:grid; grid-template-columns:repeat(7, 1fr); gap:3px;
  margin-bottom:4px;
}
.cal__jours span{
  text-align:center; font-size:.74rem; font-weight:600;
  color:var(--discret);
}
.cal__grille{ display:grid; grid-template-columns:repeat(7, 1fr); gap:3px; }
.cal__case{
  position:relative;
  aspect-ratio:1 / 1; min-height:38px;
  display:grid; place-items:center;
  border:1.5px solid transparent; border-radius:9px;
  background:var(--fond-creux); color:var(--texte);
  font:inherit; font-size:.9rem; cursor:pointer;
}
.cal__case:hover:not(:disabled){ border-color:var(--accent); }
.cal__case--vide{ background:none; }
/* Un jour ferme reste LISIBLE. Ce n'est pas un bouton mort qu'on cache : la
   grille des lundis barres apprend au client que la boutique ferme le lundi.
   A .45 d'opacite il tombait a 2,22:1 sur fond sombre ; a .7 il remonte a
   3,48:1, et le barre porte l'information sans dependre de la couleur. */
.cal__case--ferme{
  background:none; color:var(--discret);
  cursor:not-allowed; opacity:.7;
  text-decoration:line-through;
}
.cal__case[aria-pressed="true"]{
  background:var(--accent); color:#fff; font-weight:700;
  border-color:var(--accent);
}
/* Le point dit « il reste peu de places ». Le title le dit en toutes lettres :
   une couleur seule n'informe personne qui ne la voit pas. */
.cal__point{
  position:absolute; bottom:5px; left:50%; transform:translateX(-50%);
  width:5px; height:5px; border-radius:50%;
  background:var(--attention);
}
.cal__case[aria-pressed="true"] .cal__point{ background:#fff; }
.cal__vide{ margin:10px 0 0; font-size:.86rem; color:var(--gris); }
.cal__choix{
  margin:10px 0 0; font-weight:600; color:var(--accent-fonce);
}

/* ---------------------------------------------------------------------------
   14. Écrans étroits
   Placé APRÈS les règles qu'il corrige : une requête média n'ajoute aucune
   spécificité, et une adaptation écrite trop tôt perd silencieusement contre
   la règle qu'elle prétend remplacer.
--------------------------------------------------------------------------- */
@media (max-width:560px){
  .enveloppe{ padding:14px 14px 44px; }
  .etape__titre{ font-size:1.3rem; }
  .budget__montant{ font-size:2.1rem; }
  .fleurs{ grid-template-columns:repeat(auto-fill, minmax(min(100%, 104px), 1fr)); }
  .barre{ flex-wrap:wrap; }
  .barre .btn{ flex:1 1 auto; min-width:0; }
  .barre__vide{ display:none; }
  /* La fiche cesse de flotter : sur un téléphone, une bulle positionnée finit
     toujours par sortir de l'écran. Elle se pose sous la vignette et pousse la
     grille — c'est plus honnête et ça ne se coupe jamais. */
  .fiche{
    position:static; transform:none; width:100%;
    margin-top:8px; box-shadow:none;
  }
}

/* ===========================================================================
   12. LE SOUFFLE — ce qui fait qu'on a envie de continuer
   ===========================================================================
   Un formulaire de commande de fleurs qui ressemble à une déclaration
   d'impôts fait fuir avant la deuxième étape. Ce bloc ne change aucune
   information : il change ce qu'on ressent en la parcourant.

   Trois principes, et rien d'autre :

     1. LA MATIÈRE PLUTÔT QUE LA COULEUR. On n'ajoute pas de teintes — la
        boutique choisit les siennes, et une palette imposée par-dessus la
        sienne serait sa palette abîmée. On travaille l'ombre, le rayon, la
        profondeur : ça marche avec n'importe quel accent.

     2. LA RÉPONSE AU GESTE. Ce qui rend une interface agréable n'est pas sa
        décoration, c'est qu'elle réponde. Survol, appui, choix : trois états
        distincts, immédiats. Un bouton qui s'enfonce sous le doigt vaut dix
        dégradés.

     3. TOUT S'ÉTEINT. Chaque animation de ce bloc est annulée sous
        `prefers-reduced-motion`. Ce n'est pas une option de confort : un
        mouvement non désiré peut déclencher un malaise réel.
   =========================================================================== */

/* --- LA BANDE DE PHOTOS SUR LA TUILE D'OCCASION ---------------------------
   Trois photographies cote a cote, a fleur de bord, en haut de la tuile.

   La premiere version les posait en pastilles rondes de 38 px qui se
   chevauchaient — joli avec des dessins, illisible avec des photos. Une
   photographie a besoin de place : a 38 px de diametre, un gros plan de
   petales devient une tache de couleur, et la tuile perd justement ce qu'on
   etait venu chercher. Trois bandes de 60 px de large sur 78 de haut, et la
   fleur redevient reconnaissable.

   Les marges negatives annulent le rembourrage de la tuile : l'image touche
   les bords, ce qui la fait lire comme une photo et non comme une vignette
   posee dans une case. */
.tuile--occasion{ padding-top:0; overflow:hidden; }
.tuile__bouquet{
  display:flex;
  gap:2px;
  margin:0 -16px 12px;
  height:78px;
  background:var(--fond-creux);
}
.tuile__fleur{
  flex:1 1 0;
  min-width:0;
  height:100%;
  object-fit:cover;
  display:block;
  transition:transform 320ms var(--courbe);
}
/* Au survol, la bande respire : un agrandissement de 4 % qu'on ne voit pas
   vraiment mais qu'on sent. Le debordement est masque par la tuile. */
.tuile--occasion:hover .tuile__fleur{ transform:scale(1.04); }
.tuile--occasion .tuile__nom{ padding-left:0; }

/* --- LES TROIS ÉTATS D'UNE TUILE ------------------------------------------
   Survol : elle se soulève. Appui : elle s'enfonce — c'est le retour tactile
   qui manque à presque toutes les interfaces web. Choisie : elle le reste
   visiblement, et une pastille le confirme sans dépendre de la couleur. */
.tuile{ box-shadow:0 1px 2px rgba(36,28,34,.04); }
.tuile:hover{ box-shadow:var(--ombre); }
.tuile:active{ transform:translateY(0) scale(.985); }
.tuile[aria-pressed="true"]{ box-shadow:var(--ombre); }

/* La pastille de choix. Elle surgit avec un petit rebond : « c'est pris » se
   lit mieux ainsi qu'avec un changement de bordure, que l'oeil rate. */
.tuile[aria-pressed="true"]::before{
  content:"";
  position:absolute;
  top:10px; right:10px;
  width:20px; height:20px;
  border-radius:var(--r-pilule);
  background:var(--accent);
  /* Le crochet est découpé dans le masque : pas d'image à charger, pas de
     police à attendre, et il prend la couleur de la boutique sans qu'on ait
     besoin de la connaître. */
  -webkit-mask:var(--crochet) center/13px no-repeat, linear-gradient(#000,#000);
  -webkit-mask-composite:xor;
  mask:var(--crochet) center/13px no-repeat, linear-gradient(#000,#000);
  mask-composite:exclude;
  animation:pastille 260ms var(--courbe);
  z-index:1;
}
/* Sur une bande de photos, la pastille tombait tantot sur un petale clair,
   tantot sur un feuillage sombre : elle disparaissait une fois sur deux. Le
   liseré la detache de n'importe quel fond. Il est pose ici plutot que dans
   la regle du dessus parce qu'un `box-shadow` sur un element masque doit
   venir APRES le masque, sinon il est decoupe avec lui. */
.tuile--occasion[aria-pressed="true"]::before{
  top:8px; right:8px;
  outline:2.5px solid var(--carte);
  outline-offset:0;
}
@keyframes pastille{
  0%{ transform:scale(.2); opacity:0; }
  60%{ transform:scale(1.12); opacity:1; }
  100%{ transform:scale(1); opacity:1; }
}

/* Le nom ne doit pas passer sous la pastille. */
.tuile[aria-pressed="true"] .tuile__nom{ padding-right:24px; }

/* --- LA PROGRESSION SE VOIT ------------------------------------------------
   Cinq traits gris et un rose ne disent pas « vous avancez ». Le trait
   courant s'épaissit et se remplit d'un dégradé : on voit où on en est du
   premier coup d'oeil, et on voit que ça a bougé. */
.fil{ gap:5px; }
.fil__pas{
  height:6px;
  transition:background var(--duree) var(--courbe), transform var(--duree) var(--courbe);
}
.fil__pas--faite{ background:var(--accent); opacity:.42; }
.fil__pas--ici{
  background:linear-gradient(90deg, var(--accent-fonce), var(--accent));
  transform:scaleY(1.25);
}
.fil__legende{ font-weight:600; }
.fil__legende span:last-child{ color:var(--accent-fonce); }

/* --- L'ARRIVÉE D'UNE ÉTAPE ------------------------------------------------
   Les tuiles entrent l'une après l'autre, très vite. L'effet dure moins d'un
   tiers de seconde en tout : il ne retarde rien, il donne le sentiment que la
   page se dépose au lieu d'apparaître. Au-delà de la huitième, plus de délai
   supplémentaire — personne n'attendra une seconde pour voir sa dernière
   case. */
.etape--ici .tuile{ animation:tuileArrive 300ms var(--courbe) backwards; }
.etape--ici .tuile:nth-child(1){ animation-delay:0ms; }
.etape--ici .tuile:nth-child(2){ animation-delay:35ms; }
.etape--ici .tuile:nth-child(3){ animation-delay:70ms; }
.etape--ici .tuile:nth-child(4){ animation-delay:105ms; }
.etape--ici .tuile:nth-child(5){ animation-delay:140ms; }
.etape--ici .tuile:nth-child(6){ animation-delay:175ms; }
.etape--ici .tuile:nth-child(7){ animation-delay:210ms; }
.etape--ici .tuile:nth-child(n+8){ animation-delay:240ms; }
@keyframes tuileArrive{
  from{ opacity:0; transform:translateY(9px) scale(.985); }
  to{ opacity:1; transform:none; }
}

/* --- LES BOUTONS RÉPONDENT ------------------------------------------------ */
.btn{ transition:transform var(--duree) var(--courbe), box-shadow var(--duree) var(--courbe),
                 background var(--duree) var(--courbe), border-color var(--duree) var(--courbe); }
.btn:hover{ transform:translateY(-1px); }
.btn:active{ transform:translateY(0) scale(.98); }

/* --- TOUT S'ÉTEINT --------------------------------------------------------
   Placé en dernier : une requête média n'ajoute aucune spécificité, c'est
   l'ordre qui tranche. Écrite plus haut, cette règle perdrait contre les
   animations qu'elle prétend annuler — le projet s'est déjà fait prendre. */
@media (prefers-reduced-motion:reduce){
  .tuile, .tuile__fleur, .btn, .fil__pas{ transition:none; }
  .etape--ici .tuile{ animation:none; }
  .tuile[aria-pressed="true"]::before{ animation:none; }
  .tuile:active, .btn:hover, .btn:active,
  .tuile--occasion:hover .tuile__fleur:first-child{ transform:none; }
  .fil__pas--ici{ transform:none; }
}

/* --- LES FLEURS D'OBSÈQUES NE CRIENT PAS ----------------------------------
   Les fleurs conseillées pour les obsèques sont les bonnes — rose, lys,
   oeillet, chrysanthème, glaïeul, ce sont celles du métier. Mais leurs
   illustrations sont dessinées en rose vif et en rouge, et une gerbe qui
   pétille au-dessus du mot « Obsèques » est une faute de ton qu'on remarque
   avant de lire.

   On désature plutôt que de les retirer : l'image reste, elle dit encore de
   quelles fleurs on parle, et le ton se tait. Le reste de la page bascule
   déjà en sobre une fois l'occasion choisie (`body[data-ton="deuil"]`) ;
   ceci couvre le seul écran où ce n'est pas encore décidé. */
#occasionsDeuil .tuile__fleur{ filter:saturate(.3); }
#occasionsDeuil .tuile[aria-pressed="true"] .tuile__fleur{ filter:saturate(.42); }
