/*
   Charte de L'Atelier d'Olivier — feuille unique.

   Un seul fichier pour toutes les pages : deux copies finissent
   toujours par diverger, et la divergence ne se voit qu'une fois en
   ligne. Les gabarits l'appellent par un marqueur, et la
   construction l'insère telle quelle.
*/

  :root {
    /* Sans cette ligne, iOS et Safari considèrent la page comme claire et
       ajustent d'eux-mêmes ce qu'ils croient devoir corriger : champs, boutons,
       fonds. Le résultat est un noir qui vire au blanc par endroits — pas
       partout, ce qui est pire que partout. La déclarer sombre suffit à faire
       cesser ces retouches. */
    color-scheme: dark;
    --nuit: #101012;
    --bloc: #17171A;
    --creux: #1D1D21;
    --ivoire: #EAE5DA;
    --cendre: #8E897E;
    --ligne: #26262A;
    --ligne-2: #34343A;
    /* L'argent appartient à l'Atelier. L'or est réservé à Oscendence. */
    --argent: #C3C6CB;
    --or: #D4B97F;
    /* Le rose poudre du mariage. Le dore appartient a Oscendence — sa page en
       fait sa signature (#D5BC8B, #E7CE8A). Donner le dore aux deux entrees
       « qui sortent de la boutique » reviendrait a n'en distinguer aucune.

       CE QUI FAIT QU'UN ROSE EST POUDRE. Le premier essai, #E5C4C0, etait un
       rose franc : Olivier le voulait « beaucoup plus poudre, tres doux ». Un
       rose poudre se desature et s'eclaircit, mais surtout il garde
       R > B > G — le bleu au-dessus du vert. L'inverse, R > G > B, glisse vers
       la peche et la creme, et se confondrait avec l'ivoire des boutons. */
    --rose: #EFD9DD;
    /* Le vert d'eau des evenements. Ni dore ni rose : une troisieme
       porte doit se distinguer des deux autres, et le vegetal est le
       seul registre qui reste sans sortir du metier. */
    /* Le vert d'eau a ete retire : Olivier le trouvait discordant a cote
       du dore. Il ne reste que sur les intertitres de la page.
       --sauge: #D3DED0; */
    --sauge: #D3DED0;
    /* La pierre chaude des rayons, et l'ivoire des deux dernieres
       portes. Le menu etait FROID entre un dore et un rose qui sont
       chauds : ce n'etait pas un manque de contraste, c'etait un
       desaccord de temperature. Aucun reglage de gris n'y pouvait rien. */
    --pierre-h: #2E2721;
    --pierre-b: #1E1A16;
    --ivoire-h: #F5F1E7;
    --ivoire-b: #DCD5C6;
    --jost: Jost, "Century Gothic", Futura, system-ui, sans-serif;
    --ui: Archivo, system-ui, -apple-system, "Segoe UI", sans-serif;
  }
  * { box-sizing: border-box; }
  /* L'attribut « hidden » ne pose qu'un « display: none » de feuille par
     défaut : n'importe quel « display » déclaré ensuite le bat. La règle est
     limitée à nos propres éléments — appliquée partout, elle empêcherait
     Ecwid de révéler les siens. */
  .choix-lot[hidden] { display: none !important; }
  /* Safari gonfle le texte de lui-meme quand on tourne le telephone. */
  html { -webkit-text-size-adjust: 100%; }
  html { background: var(--nuit); }
  body { margin: 0; overflow-x: hidden; background: var(--nuit); color: var(--ivoire); font-family: var(--ui); -webkit-font-smoothing: antialiased; }
  img { display: block; max-width: 100%; }
  a { color: var(--ivoire); text-decoration: none; }
  a:hover { color: #fff; }
  a:focus-visible, button:focus-visible { outline: 2px solid var(--argent); outline-offset: 3px; }
  .page { max-width: 1440px; margin: 0 auto; }

  /* ---------- bandeau de service ---------- */
  .service {
    background: var(--bloc); border-bottom: 1px solid var(--ligne);
    display: flex; align-items: center; justify-content: center; gap: 24px;
    flex-wrap: wrap; padding: 10px 20px; font-size: 12px; color: var(--cendre);
  }
  .service strong { color: var(--ivoire); font-weight: 500; }
  .service .sep { color: #3A3A40; }
  /* Les étoiles d'avis sont une convention universelle : en argent elles ne se
     liraient plus comme une note. Seule dérogation à la règle « l'or est réservé
     à Oscendence ». */
  .avis { display: inline-flex; align-items: center; gap: 8px; }
  .etoiles { width: 78px; height: 15px; fill: #E0B04A; flex: 0 0 auto; }
  /* La cinquième étoile est à demi remplie : 4,3 arrondi au demi-point le
     plus proche donne 4,5. Le dégradé s'arrête net à la moitié, ce qui
     produit une vraie demi-étoile et non un fondu. La règle CSS est
     nécessaire : un attribut « fill » posé sur le tracé serait battu par
     le « fill » que cette même classe applique au SVG entier. */
  .etoiles .demi { fill: url(#demi-etoile); }

  /* ---------- en-tête ---------- */
  .entete { border-bottom: 1px solid var(--ligne); }

  /* LES OUTILS ONT QUITTE LA LIGNE DU LOGO. Panier, telephone et langue vivent
     maintenant sur leur propre rang, juste sous le bandeau de service — demande
     d'Olivier le 4 septembre 2026.

     Ce qu'on y gagne : le logo n'a plus a partager sa ligne, il se centre, et
     l'oeil rencontre la marque seule. Ce qu'on y perd : un rang de plus en
     hauteur sur ordinateur, la ou les deux tenaient cote a cote. Sur telephone
     ils s'empilaient deja — il n'y perd rien.

     Le rang reprend les marges du bandeau au-dessus de lui, pour que les deux
     lisieres tombent l'une sous l'autre.

     Les trois groupes se repartissent sur toute la largeur : le panier a
     gauche, le telephone au centre, la langue a droite. Groupes au centre, ils
     formaient un bloc unique de trois choses sans rapport — on lisait « panier
     telephone FR » comme une phrase. Ecartes, chacun redevient ce qu'il est.
     C'est aussi la place ou l'oeil va les chercher : le panier en haut a
     gauche et la langue en haut a droite sont des conventions, et une
     convention respectee ne coute rien a personne. */
  .rang-outils {
    display: flex; align-items: center;
    border-bottom: 1px solid var(--ligne);
    padding: 9px 20px;
  }
  .rang-outils .outils { width: 100%; justify-content: space-between; }
  .rang-marque { display: flex; align-items: center; justify-content: center;
                 gap: 26px; padding: 0 40px; height: 104px; }
  /* Sur une page produit, l'en-tête ne doit pas coûter la moitié de l'écran :
     le client vient voir le bouquet, pas la marque. */
  .produit .rang-marque { height: 82px; }
  .produit .rang-marque .mono { width: 190px; }
  .produit .nav { padding: 11px 40px; }
  /* LA RESERVE DE DROITE EST MORTE — 6 septembre 2026.
     Toutes les regles ci-dessous portaient un retrait droit bien plus grand
     que le gauche : 110, 78 ou 74 px contre 14, 16 ou 20. Ces pixels
     degageaient le coin ou se posait la bulle d'assistance. La bulle est en
     bas depuis le 5 septembre — verifie le 6 : 22 px du bas sur 800 comme sur
     1 440 px. La reserve est restee, sa raison d'etre avait disparu, et elle
     poussait tout le contenu vers la gauche.
     Olivier l'a vu sur une FICHE PRODUIT, la ou « .produit .service » (0,2,0)
     l'emportait sur la correction deja posee pour « .service » seul :
     « Note sur google ***** est decentre. IL faut qu'il soit justifie a
     droite ». Mesure avant correction, sur 412 px : la note s'arretait a
     104 px du bord quand le selecteur de langue s'arretait a 14. */
  /* QUARANTE, comme « .produit .nav » juste au-dessus : sur une fiche, le
     bandeau, le menu et le fil d'Ariane doivent partager le meme bord.
     Mesure avant correction sur 1 440 px : bandeau a 20, menu a 40. */
  .produit .service { padding: 8px 40px; font-size: 11.5px; }
  /* Le monogramme est un trait fin : sous 55 px de haut il devient une tache.
     Et le nom est composé en texte vivant, donc net à toute définition —
     un tracé réduit à cette taille bave. */
  /* Le symbole complet — rameaux compris — est large et bas : empilé avec le
     nom en dessous, comme dans le logo d'origine. Le nom reste en texte vivant,
     un tracé réduit à cette taille bave. */
  .entete .marque { display: flex; flex-direction: column; align-items: center; gap: 2px;
                    flex: 0 0 auto; width: 232px; }
  .entete .marque .mono { width: 232px; height: auto; }
  /* Argent métallique : dégradé sombre -> éclat -> sombre, découpé sur le
     texte. Un gris uni donnerait du gris ; c'est la variation qui fait le métal. */
  /* Le nom cede la vedette au metier, comme sur le site actuel : plus petit,
     plus sourd, place au-dessus. */
  .entete .marque .nom {
    font-family: var(--jost); font-weight: 400; font-size: 11px;
    letter-spacing: .2em; white-space: nowrap; padding-left: .2em;
    color: #8E949B;
  }
  /* ---------- le metier, en titre de page ---------- */
  /* Sorti du bloc de marque : il n'a plus a tenir dans les 232 px du symbole,
     donc il peut enfin avoir la taille d'un titre. Les filets l'encadrent
     sans le cerner, en s'effacant vers les bords. */
  .titre-page { display: flex; align-items: center; justify-content: center; gap: 17px;
                padding: 2px 40px 24px; }
  .titre-page .losange { width: 6px; height: 6px; flex: 0 0 auto;
                         transform: rotate(45deg);
                         background: linear-gradient(135deg, #FFFFFF 0%, #DDE2E8 38%, #9AA1A9 100%);
                         box-shadow: 0 0 7px rgba(216,221,227,.5); }
  .titre-page .filet { height: 1px; width: clamp(40px, 12vw, 170px);
                       background: linear-gradient(90deg, transparent 0%, #565C63 34%,
                                   #9BA2AA 70%, #E2E7ED 100%); }
  .titre-page .filet.droite { background: linear-gradient(270deg, transparent 0%, #565C63 34%,
                                          #9BA2AA 70%, #E2E7ED 100%); }
  .titre-page h1 {
    margin: 0; font-family: var(--jost); font-weight: 200; font-size: 33px;
    letter-spacing: .42em; text-transform: uppercase; white-space: nowrap;
    padding-left: .42em; line-height: 1.15;
    color: #E4E9EE;
  }
  .nav { display: flex; justify-content: center; gap: 30px; padding: 15px 40px;
         border-top: 1px solid var(--ligne);
         font-family: var(--jost); font-size: 14px; letter-spacing: .09em; }
  /* Les deux entrees qui menent AILLEURS que dans la boutique — vers une autre
     marque, vers un devis — portent un fond plutot qu'une simple couleur de
     texte. Olivier : « il faut que le bouton Oscendence ressorte encore plus,
     agir sur le fond ». Fond plein et texte sombre : c'est le traitement le
     plus fort dont dispose une barre de navigation, et il inverse le rapport
     figure/fond, ce qu'aucune nuance de gris ne fait.

     Chacune emprunte la couleur de SA page, pour qu'on retrouve au clic ce
     qu'on a vu au menu. */
  /* On ecrit « a.osc » et non « .osc ». Le bloc telephone pose
     « .entete .nav a », de specificite (0,2,1), qui l'emporte sur « .nav .osc »
     a (0,2,0) : la couleur passait, le fond disparaissait, et les pastilles
     redevenaient du texte ordinaire sous 620 px — la ou Olivier regarde.
     « .nav a.osc » vaut (0,2,1) et fait jeu egal, en arrivant apres. */
  /* Le filet de coupure. Il ne separe pas pour decorer : il dit qu'a sa droite
     on quitte la boutique. Un ecart plus large que le pas du menu suffirait a
     le faire comprendre, mais le filet le rend certain sans rien ecrire. */
  .nav-coupe {
    width: 1px; height: 17px; align-self: center; flex: 0 0 auto;
    /* MESURE, et non impression. Sur grand ecran le pas du menu est de 100 px
       d'un libelle au suivant. Avec 8 px de marge, la coupure valait 108 px :
       identique a l'oeil, donc invisible. Le regroupement ne se lit que si
       l'ecart de la coupure depasse nettement le pas courant.

       34 px → 12 px, le 4 septembre 2026. Olivier : « il y a un espace entre
       plantes et ultra luxe oscendence ». Le calcul d'origine oubliait que le
       menu est en « space-between » : l'espace libre de la barre s'ajoute aux
       marges de la coupure, des deux cotes. Mesure a 1600 px : 108 px entre
       deux entrees ordinaires, 142 px de part et d'autre du filet — soit un
       trou de deux entrees manquantes, la ou l'on voulait une respiration.
       A 12 px le filet vaut 120 px contre 108 : il se voit, il ne troue plus.
       Et le passage du menu a 15 px elargit les entrees, ce qui reduit encore
       l'espace libre a repartir. */
    margin: 0 12px;
    background: linear-gradient(180deg, transparent 0%, var(--ligne) 30%,
                var(--ligne) 70%, transparent 100%);
  }

  .nav a.osc, .nav a.mar, .nav a.eve {
    color: var(--nuit); padding: 5px 13px; border-radius: 2px;
    font-weight: 500;
  }

  /* DEUX POLICES POUR DEUX MOTS, et le cout est reel : deux familles de plus a
     telecharger. Il est tenu par le parametre « text= » de Google Fonts, qui ne
     sert que les glyphes demandes — ici les lettres d'« Oscendence » et de
     « Mariage ». Deux fichiers de quelques centaines d'octets au lieu de deux
     polices entieres.

     Italiana pour Oscendence : une romaine a tres fort contraste, haute et
     etroite, de la famille des titres de couture. Elle sort du reste sans etre
     manuscrite, ce qu'Olivier excluait. Elle n'existe qu'en une graisse, d'ou
     le font-weight ramene a 400 — demander du 500 la ferait grossir
     artificiellement au rendu.

     Pinyon Script pour Mariage : une anglaise gravee, plus dense que les
     scripts de faire-part et donc lisible a petite taille. Elle est portee a
     19 px parce qu'une calligraphie posee au corps du menu ne se lit plus ;
     l'oeil d'une script est bien plus petit que sa hauteur de casse. */
  /* LE CORPS FAIT LA LISIBILITE, PAS LA GRAISSE. Olivier : « les polices sont
     tres belles mais vraiment pas visibles ». Les deux n'existent qu'en une
     seule graisse — on ne peut pas les epaissir. Or ce sont precisement les
     deux familles qui supportent le moins la reduction : une didone perd ses
     delies, une anglaise perd ses pleins et delies tout entiers. L'oeil d'une
     script fait a peine la moitie de sa hauteur de casse.

     On les agrandit donc franchement, et on resserre l'interlettrage
     d'Italiana : espacer une capitale fine la fait disparaitre au lieu de la
     poser. */
  /* AGRANDIR LA POLICE, PAS LE BOUTON. Olivier, apres un premier essai :
     « ce ne sont pas les boutons qu'il faut agrandir mais les polices, et les
     rendre plus lisibles ». Le corps monte donc, mais le rembourrage vertical
     descend d'autant : la pastille garde la hauteur des autres entrees.

     ET PLUS D'ITALIQUE. Pinyon Script etait une anglaise — belle, et illisible
     d'un coup d'oeil : l'italique demande a l'oeil de reconstruire chaque
     lettre. Cormorant Garamond la remplace : droite, chaleureuse, avec assez
     de caractere pour ne pas se confondre avec le menu, et lisible a 17 px.
     En 600, parce que ses graisses legeres s'effacent sur un fond clair. */
  /* LA HAUTEUR ETAIT BONNE, C'ETAIT LA LARGEUR. Mesure : 139 px pour
     Oscendence et 99 px pour Mariage, contre 55 px par rayon. Ce n'est pas le
     corps de la police qui les faisait paraitre gros — c'etaient les 40 px de
     rembourrage lateral, plus un fond plein qui rend visible chaque pixel de
     marge. On resserre le rembourrage et on baisse d'un cran le corps ;
     l'ecart aux rayons tombe de 2,5 fois a 1,7 fois. */
  /* MEME LARGEUR POUR LES DEUX. « Oscendence » fait dix lettres, « Mariage »
     sept : au naturel, l'une est un tiers plus large que l'autre et la paire
     boite. Une largeur minimale commune les aligne — c'est la plus longue qui
     la fixe, et la plus courte se centre dedans. */
  /* La largeur commune des pastilles ne s'ecrit plus en dur. Le « 112px »
     qui vivait ici datait de l'epoque ou elles etaient deux ; a trois il
     debordait la ligne, et comme c'etait un nombre fixe aucun reglage de
     police ne le corrigeait. Elles se partagent la rangee. */
  .nav a.osc, .nav a.mar, .nav a.eve { box-sizing: border-box; }
  /* POURQUOI ITALIANA EST PARTIE. Olivier : « on n'arrive pas du tout a lire
     Oscendence ». Ce n'etait pas un reglage a corriger — c'etait la mauvaise
     fonte. Italiana est une didone de TITRAGE : son contraste entre pleins et
     delies est concu pour 40 px, et a 15 px les delies tombent sous le pixel
     et disparaissent. On ne rattrape pas cela en grossissant un peu.

     Cinzel la remplace : une capitale romaine, meme registre de luxe, mais des
     futs pleins qui tiennent a 14 px. Et Cormorant passe en 700 — sa 600
     s'effacait aussi sur un fond clair. */
  .nav a.osc {
    font-family: Cinzel, "Trajan Pro", Georgia, serif;
    font-weight: 600; font-size: 13px; letter-spacing: .05em;
    padding: 4px 11px;
  }
  .nav a.mar {
    font-family: "Cormorant Garamond", Garamond, Georgia, serif;
    font-weight: 700; font-size: 17px; letter-spacing: .02em;
    padding: 4px 11px;
  }
  /* EVENEMENTS GARDE LA POLICE DE LA MAISON, et c'est voulu. Cinzel dit
     « autre marque », Cormorant dit « mariage » ; Jost dit « une page de ce
     site ». Les evenements ne sont pas une marque, c'est un service — et une
     troisieme fonte d'apparat sur la meme rangee ferait un echantillonnier. */
  /* PAS DE CAPITALES. Elles coutaient 112 px de largeur minimale a
     « Evenements » — la flexbox ne peut pas descendre sous la largeur du
     contenu quand le texte ne se coupe pas, et les trois pastilles faisaient
     336 px pour 335 disponibles. Un pixel, et le mot tombait seul sur une
     quatrieme ligne. En bas de casse il en fait 86.

     La capitale etait de toute facon le mauvais registre : elle criait a cote
     d'une romaine et d'une garamond qui, elles, parlent bas. */
  .nav a.eve {
    font-family: var(--jost); font-weight: 500; font-size: 13.5px;
    letter-spacing: .04em;
    padding: 4px 11px;
  }
  /* Le russe, l'arabe et le chinois reprennent la police du menu : Pinyon
     Script n'a pas leurs caracteres, et « Свадьба » y tomberait sur une
     cursive systeme choisie par le navigateur — c'est-a-dire sur n'importe
     quoi. Italiana non plus, d'ou le meme rappel pour Oscendence. */
  .nav a.mar:lang(ru), .nav a.mar:lang(ar), .nav a.mar:lang(zh),
  .nav a.osc:lang(ru), .nav a.osc:lang(ar), .nav a.osc:lang(zh) {
    font-family: var(--jost); font-size: 14px; letter-spacing: .09em;
    font-weight: 500;
  }
  .nav a.osc { background: var(--or); }
  .nav a.mar { background: var(--rose); }
  .nav a.eve { background: var(--sauge); }
  .nav a.eve:hover { background: #E2EBDF; }
  .nav a.osc:hover { background: #E7CE8A; }
  .nav a.mar:hover { background: #F8ECEE; }

  .outils { display: flex; align-items: center; gap: 16px; font-size: 13px; }

  /* ---------- selecteur de langue ---------- */
  /* Ouverture au survol ET au focus : sans « focus-within », la liste serait
     inatteignable au clavier et sur ecran tactile. */
  .langue { position: relative; }
  .langue-actuelle { display: inline-flex; align-items: center; gap: 7px;
                     background: none; border: 0; padding: 6px 2px; cursor: pointer;
                     color: var(--cendre); font-family: var(--ui); font-size: 13px; }
  .langue-actuelle:hover, .langue:focus-within .langue-actuelle { color: var(--ivoire); }
  .langue .chevron { width: 9px; height: 6px; flex: 0 0 auto; }
  .drapeau { width: 19px; height: 13px; flex: 0 0 auto; border-radius: 1px;
             box-shadow: 0 0 0 1px rgba(255,255,255,.14); }
  .langue-liste { position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
                  z-index: 50; min-width: 178px; padding: 7px 0;
                  background: var(--bloc); border: 1px solid var(--ligne-2);
                  box-shadow: 0 10px 30px rgba(0,0,0,.55);
                  display: none; flex-direction: column; }
  .langue:hover .langue-liste, .langue:focus-within .langue-liste { display: flex; }
  .langue-liste a { display: flex; align-items: center; gap: 10px; padding: 8px 14px;
                    font-size: 13px; color: var(--cendre); }
  .langue-liste a:hover { background: var(--creux); color: var(--ivoire); }
  .langue-liste a.active { color: var(--ivoire); }
  .langue-liste .code { font-family: var(--jost); letter-spacing: .1em; width: 22px; }
  .langue-liste .langue-nom { font-size: 12.5px; }
  .wa { display: inline-flex; align-items: center; gap: 7px; color: var(--ivoire); white-space: nowrap; }
  .wa:hover { color: #9FD79F; }

  /* ---------- assistance ---------- */
  /* Fixe et non absolue : elle reste au meme endroit de l'ecran quel que
     soit le defilement, c'est ce qui en fait une assistance et non un lien
     qu'on depasse. */
  .assistance { position: fixed; right: 18px; top: 12px; z-index: 40;
                display: flex; flex-direction: column; align-items: center; gap: 7px; }
  /* L'or est réservé à Oscendence : la bulle se rend visible par la lumière et
     le halo, pas par la couleur. Le double anneau la détache aussi bien d'une
     photo claire que du fond nuit, ce qu'une simple ombre portée ne faisait
     pas. La respiration attire l'œil sans bouger la mise en page. */
  .assistance .bulle { width: 60px; height: 60px; border-radius: 50%;
                       display: flex; align-items: center; justify-content: center;
                       background: linear-gradient(140deg, #F4F6F9 10%, #C2C8D0 90%);
                       box-shadow: 0 0 0 1px rgba(255,255,255,.5),
                                   0 0 0 8px rgba(195,198,203,.14),
                                   0 0 26px rgba(195,198,203,.30),
                                   0 8px 26px rgba(0,0,0,.6);
                       animation: respire 3.4s ease-in-out infinite; }
  @keyframes respire {
    0%, 100% { box-shadow: 0 0 0 1px rgba(255,255,255,.5),
                           0 0 0 8px rgba(195,198,203,.14),
                           0 0 26px rgba(195,198,203,.30),
                           0 8px 26px rgba(0,0,0,.6); }
    50%      { box-shadow: 0 0 0 1px rgba(255,255,255,.7),
                           0 0 0 13px rgba(195,198,203,.07),
                           0 0 34px rgba(195,198,203,.46),
                           0 8px 26px rgba(0,0,0,.6); }
  }
  @media (prefers-reduced-motion: reduce) { .assistance .bulle { animation: none; } }
  .assistance:hover .bulle { background: linear-gradient(140deg, #FFFFFF, #D6DBE1); }
  /* La legende flotte au-dessus de la page : elle a besoin de son propre
     contraste, l'ombre portee la detache de ce qui defile dessous. */
  .assistance-mot { font-family: var(--jost); font-size: 10px; letter-spacing: .18em;
                    text-transform: uppercase; color: #D5D0C5; padding-left: .18em;
                    text-shadow: 0 1px 7px rgba(0,0,0,.9), 0 0 14px rgba(0,0,0,.7); }
  .assistance:hover .assistance-mot { color: #FFFFFF; }
  .panier { display: inline-flex; align-items: center; gap: 7px; border: 1px solid var(--ligne-2); padding: 9px 14px; }

  /* ---------- ouverture ---------- */
  .ouverture { position: relative; min-height: 560px; display: flex; align-items: center;
               background-size: cover; background-position: center; }
  .ouverture .voile { position: absolute; inset: 0;
    background: linear-gradient(90deg, rgba(16,16,18,.94) 0%, rgba(16,16,18,.74) 46%, rgba(16,16,18,.28) 100%); }
  .ouverture .mots { position: relative; display: flex; flex-direction: column; gap: 20px;
                     padding: 76px 40px; max-width: 640px; }
  .ouverture h1 { margin: 0; font-family: var(--jost); font-weight: 300; font-size: 52px;
                  line-height: 1.1; letter-spacing: -.005em; }
  .ouverture .promesse { margin: 0; font-size: 16px; line-height: 1.7; color: var(--cendre); }
  .bouton { align-self: flex-start; display: inline-flex; align-items: center; justify-content: center;
            height: 58px; padding: 0 40px; background: var(--ivoire); color: var(--nuit);
            font-size: 14px; font-weight: 600; }
  .bouton:hover { background: #fff; color: var(--nuit); }

  /* ---------- étiquette de mise en avant ---------- */
  /* Doré champagne, plus clair que l'or antique d'Oscendence : les deux
     maisons restent distinctes par le ton, et l'étiquette cesse d'être froide. */
  .etiq { position: absolute; top: 12px; left: 12px; color: #2A2010;
          background: linear-gradient(105deg, #C09B45 0%, #F0D68E 26%, #FFF8DC 50%, #E8CB77 74%, #BB9440 100%);
          font-size: 10px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
          padding: 6px 10px; box-shadow: 0 1px 6px rgba(0,0,0,.35); }
  .carte .vis { position: relative; }

  /* ---------- écran d'achat ---------- */
  .achat { display: grid; grid-template-columns: minmax(0, 330px) minmax(0, 1fr);
           gap: 30px; max-width: 1280px; margin: 0 auto; padding: 0 40px;
           align-items: start; }
  .visuel { position: relative; min-height: 880px; background-size: cover; background-position: center; }
  .visuel .marque-photo {
    position: absolute; left: 26px; bottom: 22px; font-size: 12px; color: #C9C4B8;
    background: rgba(16,16,18,.66); padding: 7px 12px;
  }

  .module { padding: 44px 52px 52px; border-left: 1px solid var(--ligne); display: flex; flex-direction: column; gap: 22px; }
  .fil { font-size: 12px; color: var(--cendre); }
  .fil a { color: var(--cendre); }
  .badge {
    align-self: flex-start; font-family: var(--ui); font-size: 10px; font-weight: 600;
    letter-spacing: .2em; text-transform: uppercase;
    background: var(--argent); color: var(--nuit); padding: 5px 10px;
  }
  h1 { margin: 0; font-family: var(--jost); font-weight: 300; font-size: 40px; line-height: 1.12; letter-spacing: -.005em; }
  .sensations { display: flex; flex-direction: column; gap: 9px; border-left: 1px solid var(--argent); padding-left: 16px; }
  .sensations p { margin: 0; font-family: var(--jost); font-weight: 300; font-size: 17px; line-height: 1.4; color: var(--ivoire); }
  .sensations span { display: block; font-family: var(--ui); font-size: 9px; font-weight: 600;
                     letter-spacing: .22em; text-transform: uppercase; color: var(--cendre); margin-bottom: 3px; }

  .lbl { font-size: 10px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--cendre); }

  /* ---------- l'échelle des roses ---------- */
  .echelle { display: flex; flex-direction: column; gap: 14px; }
  .groupe { display: flex; flex-direction: column; gap: 8px; }
  .groupe .titre { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
  .groupe .titre .nom { font-family: var(--jost); font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: var(--argent); }
  .groupe .titre .note { font-size: 13px; color: #A9A398; }
  /* Un nombre de colonnes par défaut : sans lui, une grille tombe à une
     seule colonne et les paliers s'étalent en bandeaux. La largeur minimale
     laisse tenir « 500 » et son prix sans rogner. */
  /* « auto-fit » plutôt que « auto-fill » : les colonnes vides se replient
     et les carreaux présents occupent toute la largeur. Avec auto-fill, cinq
     paliers dans une grille de huit laissaient trois trous à droite. */
  .paliers { display: grid; gap: 6px;
             grid-template-columns: repeat(auto-fit, minmax(86px, 1fr)); }
  .paliers.huit { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .paliers.cinq { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .palier {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    position: relative; padding: 9px 4px; cursor: pointer; font-family: var(--ui);
    background: transparent; color: var(--ivoire); border: 1px solid var(--ligne-2);
    transition: border-color .12s, background .12s;
  }
  .palier:hover { border-color: var(--argent); }
  .palier .n { font-family: var(--jost); font-size: 19px; font-weight: 400; line-height: 1; }
  .palier .p { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--cendre); }
  .palier[aria-pressed="true"] { background: var(--ivoire); color: var(--nuit); border-color: var(--ivoire); }
  .palier[aria-pressed="true"] .p { color: var(--nuit); }
  .palier.conseille { border-color: var(--argent); }
  .palier.conseille::after {
    content: ""; position: absolute; top: 6px; right: 6px;
    width: 5px; height: 5px; border-radius: 50%; background: var(--argent);
  }
  .palier[aria-pressed="true"].conseille::after { background: var(--nuit); }
  /* « Le Classique » est un autre produit Ecwid : c'est un lien, pas un choix.
     Il ouvre l'échelle à 100 € au lieu de la laisser buter sur 200 €. */
  .palier.ailleurs { border-style: dashed; }
  .palier.ailleurs .n, .palier.ailleurs .p { color: var(--argent); }
  .palier .fleche { position: absolute; top: 5px; right: 6px; font-size: 10px; color: var(--argent); line-height: 1; }
  .legende { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #A9A398;
             flex-wrap: wrap; margin-top: 2px; }

  /* ---------- Somptueux : un écrin, pas seulement un autre titre ----------
     Le client qui monte à cent roses doit sentir qu'il change de rayon. */
  .groupe.somptueux {
    margin-top: 8px; padding: 20px 20px 22px;
    border: 1px solid var(--ligne-2); border-top: 2px solid var(--argent);
    background:
      linear-gradient(180deg, rgba(195,198,203,.07) 0%, rgba(195,198,203,0) 62%),
      var(--creux);
  }
  .groupe.somptueux .titre .nom { font-size: 15px; letter-spacing: .26em; padding-left: .26em; }
  .groupe.somptueux .titre .note { font-style: italic; }
  .groupe.somptueux .palier { padding: 17px 4px; border-color: #43434A; }
  .groupe.somptueux .palier .n { font-size: 23px; }
  .groupe.somptueux .paliers { gap: 8px; }
  .somptueux-mot { margin: 14px 0 0; font-size: 14px; line-height: 1.7; color: #B0AA9E; }
  .libre { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
  .libre label { font-size: 14px; color: #A9A398; }
  .n-libre { width: 150px; }
  .libre-p { font-family: var(--jost); font-size: 17px; font-variant-numeric: tabular-nums; color: var(--argent); }
  .legende .pt { width: 6px; height: 6px; border-radius: 50%; background: var(--argent); flex: 0 0 auto; }
  .enveloppe { position: relative; display: flex; }
  .enveloppe > .palier { flex: 1 1 auto; width: 100%; }

  /* ---------- champs ---------- */
  /* Un champ transparent sur fond nuit ne se voyait qu'à son filet d'un pixel :
     rien ne disait qu'on pouvait écrire là. Il lui faut une surface à lui,
     creusée, et un filet assez clair pour se lire sur une photo comme sur le
     fond. Le liseré intérieur fait le creux sans ombre lourde. */
  .champ { border: 1px solid #4C4C58; background: #23232B; color: var(--ivoire);
           font-family: var(--ui); font-size: 14px; padding: 12px 14px; width: 100%;
           box-shadow: inset 0 2px 5px rgba(0,0,0,.45);
           transition: border-color .15s, box-shadow .15s, background .15s; }
  .champ:hover { border-color: #6A6A78; background: #282831; }
  .champ:focus { outline: none; border-color: var(--argent);
                 box-shadow: inset 0 1px 0 rgba(0,0,0,.6), 0 0 0 3px rgba(195,198,203,.16); }
  .champ::placeholder { color: #9B9689; }

  /* Obligatoire ou facultatif : la mention est portée par l'étiquette, pas par
     une astérisque seule — une astérisque n'est comprise que par ceux qui la
     connaissent déjà, et un lecteur d'écran ne la lit pas comme une consigne. */
  .mention-champ { font-family: var(--jost); font-size: 10px; letter-spacing: .16em;
                   text-transform: uppercase; margin-left: 10px; font-weight: 400;
                   white-space: nowrap; }
  .mention-champ.requis { color: var(--argent); }
  .mention-champ.facultatif { color: #6F6B62; }
  /* Un champ obligatoire laissé vide se signale de lui-même, sans attendre
     l'envoi : le filet passe à l'argent dès qu'il est rempli. */
  .champ[required] { border-left: 2px solid var(--argent); }
  .champ[required]:placeholder-shown { border-left-color: #6E7176; }
  select.champ { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--cendre) 50%), linear-gradient(135deg, var(--cendre) 50%, transparent 50%); background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
  .bloc-champ { display: flex; flex-direction: column; gap: 8px; }

  /* ---------- repère de proportion ---------- */
  .proportion { display: flex; align-items: center; gap: 20px; border: 1px solid var(--ligne); padding: 16px 18px; }
  /* La place est réservée d'avance, sur le plus grand disque que ce produit
     puisse afficher : le générateur écrit --disque dans la page. Sans cela le
     bloc changerait de taille à chaque clic et la page bougerait sous le doigt.
     Le repli à 96px sert aux pages écrites avant cette variable. */
  .disques { display: flex; align-items: flex-end; gap: 14px; flex: 0 0 auto;
             height: max(96px, var(--disque, 96px));
             width: calc(76px + max(62px, var(--disque, 96px))); }
  .disque { position: relative; display: block; border-radius: 50%;
            flex: 0 0 auto; transition: width .18s, height .18s; }
  .disque i { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
              font-style: normal; font-family: var(--jost); font-size: 12px; font-variant-numeric: tabular-nums; }
  .disque.ref { border: 1px dashed var(--ligne-2); width: 62px; height: 62px; }
  .disque.ref i { color: var(--cendre); }
  .disque.sel { background: var(--argent); }
  .disque.sel i { color: var(--nuit); font-weight: 500; }
  .prop-txt { margin: 0; font-size: 12px; line-height: 1.7; color: var(--cendre); }
  /* Le nombre de mains dit la taille mieux qu'un chiffre, et sans rien
     révéler du contenu du bouquet. */
  .porte { display: block; font-family: var(--jost); font-size: 15px; letter-spacing: .02em;
           color: var(--ivoire); margin-bottom: 5px; }
  .prop-txt strong { color: var(--ivoire); font-weight: 500; }
  .vase { display: flex; align-items: center; gap: 14px; border: 1px solid var(--ligne-2); padding: 14px 16px; cursor: pointer; }
  .vase:hover { border-color: var(--argent); }
  .vase input { width: 17px; height: 17px; accent-color: var(--ivoire); flex: 0 0 auto; }
  .vase-txt { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
  .vase-nom { font-size: 14px; }
  .vase-det { font-size: 12px; color: var(--cendre); }
  .vase-prix { font-family: var(--jost); font-size: 17px; font-variant-numeric: tabular-nums; }

  /* ---------- action ---------- */
  /* Pleine largeur, texte plaqué aux deux bords, à plat : le bouton se lisait
     comme un bandeau d'information et non comme la chose à toucher. Trois
     corrections, dans l'ordre de leur effet :

     1. Il se rétrécit et se centre. Un objet qui ne touche pas les deux bords
        se détache du fond et se lit comme un objet.
     2. Il prend du relief — dégradé, ombre portée, liseré clair en haut — et
        s'enfonce au clic. C'est l'affordance : ce qui a une épaisseur se presse.
     3. Le libellé et le prix se rapprochent, séparés par un point médian. Aux
        deux extrémités, ils formaient deux blocs de texte sans lien. */
  .ajouter {
    display: inline-flex; align-items: center; justify-content: center; gap: 16px;
    width: 100%; max-width: 430px; align-self: center;
    min-height: 62px; padding: 0 34px; border: 0; border-radius: 3px; cursor: pointer;
    background: linear-gradient(180deg, #FFFDF8 0%, var(--ivoire) 55%, #DAD4C7 100%);
    color: var(--nuit); font-family: var(--ui); font-size: 15px; font-weight: 600;
    letter-spacing: .01em;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 2px 0 #A8A294,
                0 10px 26px rgba(0,0,0,.55);
    transition: transform .09s, box-shadow .09s, background .15s;
  }
  /* Au survol le bouton se soulève et un reflet le traverse. Un objet qui
     réagit au passage de la souris se lit comme actionnable avant même d'être
     cliqué ; c'est le signal le plus économique dont on dispose. Le reflet est
     un pseudo-élément qui glisse : rien ne bouge dans la mise en page. */
  .ajouter { position: relative; overflow: hidden; }
  .ajouter > * { position: relative; z-index: 1; }
  .ajouter::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
    transform: skewX(-18deg); opacity: 0; pointer-events: none; }
  .ajouter:hover { background: linear-gradient(180deg, #FFFFFF 0%, #F5F1E7 55%, #E2DCCF 100%);
                   transform: translateY(-2px);
                   box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 4px 0 #A8A294,
                               0 14px 30px rgba(0,0,0,.6); }
  .ajouter:hover::after { animation: reflet .75s ease-out; }
  @keyframes reflet {
    0%   { left: -60%; opacity: 0; }
    18%  { opacity: 1; }
    100% { left: 115%; opacity: 0; }
  }
  .ajouter:active { transform: translateY(2px);
                    box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 0 0 #A8A294,
                                0 4px 12px rgba(0,0,0,.5); }
  @media (prefers-reduced-motion: reduce) {
    .ajouter, .ajouter:hover { transition: none; transform: none; }
    .ajouter:hover::after { animation: none; }
  }
  .ajouter .total { font-family: var(--jost); font-size: 21px; font-weight: 400; font-variant-numeric: tabular-nums; }
  /* Le point médian relie le geste à son prix : « commander · 336,90 € » se lit
     d'un trait, là où deux blocs écartés se lisaient séparément. */
  .ajouter .total::before { content: "·"; margin-right: 16px; color: #9B9587; }
  /* Les frais de port apparaissent ici, sous le bouton. Un cout revele au
     dernier ecran est la premiere cause d'abandon de panier ; annonce tot,
     il protege au lieu de couter. Il doit donc se lire. */
  .sous-bouton { display: flex; align-items: center; justify-content: center;
                 gap: 14px; flex-wrap: wrap; font-size: 13px; color: #A9A398; }

  .mention { font-size: 12px; line-height: 1.7; color: var(--cendre); border-top: 1px solid var(--ligne); padding-top: 16px; }

  /* ---------- adaptation ---------- */
  @media (max-width: 1180px) {
    .achat { grid-template-columns: 1fr; }
    .visuel { min-height: 420px; }
    .module { border-left: 0; border-top: 1px solid var(--ligne); padding: 30px 20px 40px; }
    .rang-marque { flex-wrap: wrap; height: auto; padding: 14px 20px; gap: 14px; }
    .service,
    .produit .service { padding: 9px 16px; }
    .nav { width: 100%; overflow-x: auto; gap: 22px; padding: 12px 20px; justify-content: flex-start; }
  }
  @media (max-width: 620px) {
    h1 { font-size: 30px; }
    .paliers { grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); }
    .paliers.huit { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .paliers.cinq { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .entete .marque { width: 208px; }
    .entete .marque .mono { width: 208px; }
    .entete .marque .nom { font-size: 9px; letter-spacing: .16em; padding-left: .16em; }
    .titre-page { gap: 12px; padding: 2px 20px 20px; }
    .titre-page h1 { font-size: 21px; letter-spacing: .3em; padding-left: .3em; }
  }

  .suite { display: flex; justify-content: center; padding: 26px 20px 0; }
  .suite a { display: inline-flex; align-items: center; gap: 11px; font-size: 13px; color: var(--cendre); }
  .suite a:hover { color: var(--argent); }
  .suite svg { width: 15px; height: 15px; stroke: var(--argent); animation: descend 2.4s ease-in-out infinite; }
  @keyframes descend { 0%,100% { transform: translateY(0); } 50% { transform: translateY(4px); } }
  @media (prefers-reduced-motion: reduce) { .suite svg { animation: none; } }

  /* ================= sections de la page ================= */
  .section { padding: 96px 40px 0; }
  .section.premiere { padding-top: 30px; }
  .intro-rayon { margin: 0 0 26px; max-width: 62ch; font-size: 16px;
                 line-height: 1.75; color: #B4AFA4; }
  .tete { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; padding-bottom: 22px; }
  .tete .gauche { display: flex; flex-direction: column; gap: 8px; }
  .h2 { margin: 0; font-family: var(--jost); font-weight: 300; font-size: 38px; line-height: 1; letter-spacing: .01em; }
  .lien-fin { font-size: 13px; border-bottom: 1px solid var(--argent); padding-bottom: 5px; }

  .grille { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; }
  .grille.cinq { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .grille.quatre { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .carte { display: flex; flex-direction: column; background: var(--bloc); border: 1px solid var(--ligne); }
  .carte:hover { border-color: var(--ligne-2); }
  /* Format portrait : la photo source est carrée, donc c'est la largeur qui
     est rognée et non la hauteur. Les vases et les pieds restent visibles.

     La photo est une vraie image et non un fond CSS : elle porte un texte
     alternatif, elle se charge en différé sous la ligne de flottaison, et
     Google Images la voit. Un fond CSS ne fait aucune de ces trois choses. */
  .carte .vis { aspect-ratio: 4 / 5; overflow: hidden; }
  .photo { width: 100%; height: 100%; object-fit: cover; display: block; }
  .carte .corps { padding: 18px 18px 20px; display: flex; flex-direction: column; align-items: center;
                  text-align: center; gap: 10px; flex: 1 1 auto; }
  /* Un titre sur une seule ligne : les cartes s'alignent au pixel pres.
     Et la description occupe une hauteur fixe, sinon les prix se decalent. */
  .carte .nom-p { font-family: var(--jost); font-weight: 300; font-size: 18px; line-height: 1.25;
                  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
  .carte .sens { font-size: 12.5px; line-height: 1.55; color: var(--cendre);
                 flex: 1 1 auto; min-height: 3.1em; }
  .carte .bas { display: flex; align-items: center; justify-content: space-between; width: 100%;
                border-top: 1px solid var(--ligne); padding-top: 13px; }
  /* « dès 59,90 » puis « € » seul à la ligne : un prix coupé se lit deux fois
     avant d'être compris, et l'unité isolée ressemble à une erreur. */
  .carte .p { font-family: var(--jost); font-size: 17px; font-variant-numeric: tabular-nums;
              white-space: nowrap; }
  .carte .cta { font-size: 11px; color: var(--nuit); background: var(--ivoire); padding: 8px 12px;
                font-weight: 600; white-space: nowrap; }
  .carte.texte { justify-content: center; align-items: center; text-align: center; gap: 14px; padding: 40px 24px; min-height: 400px; }
  .carte.texte .nom-p { font-size: 24px; }

  /* Vignettes de collection. Les photos disponibles sont celles du site
     actuel : cadrage et grille identiques pour que la rangée tienne malgré
     des prises de vue d'origines différentes. */
  .univers { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 14px; }
  .tuile { display: block; position: relative; border: 1px solid var(--ligne); background: var(--creux); }
  .tuile:hover { border-color: var(--argent); }
  .tuile .vis { position: relative; aspect-ratio: 1 / 1; overflow: hidden;
                background-color: #191920; }
  .tuile .vis.vide { display: flex; align-items: center; justify-content: center; }
  .tuile .vis.vide span { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: #55524B; }
  /* Voile en degrade plutot qu'un aplat : la photo reste lisible en haut et
     le texte garde son contraste en bas. */
  .tuile .t-corps { position: absolute; left: 0; right: 0; bottom: 0;
                    padding: 44px 14px 15px; display: flex; flex-direction: column;
                    align-items: center; text-align: center; gap: 5px;
                    background: linear-gradient(to top, rgba(9,9,11,.94) 0%,
                                rgba(9,9,11,.82) 42%, rgba(9,9,11,.42) 74%, rgba(9,9,11,0) 100%); }
  .tuile .t-nom { font-family: var(--jost); font-weight: 300; font-size: 21px;
                  color: #FFFFFF; text-shadow: 0 1px 10px rgba(0,0,0,.7); }
  .tuile .t-note { font-size: 12px; line-height: 1.5; color: #C8C3B8;
                   text-shadow: 0 1px 8px rgba(0,0,0,.8); }

  /* ---------- Oscendence ---------- */
  /* La photo passe au fond, et tout le contenu se centre sur l'axe de la page.
     En colonnes, le texte était centré dans sa propre colonne — donc décalé de
     tout ce qui l'entourait — et la photo, coincée dans 340 px, ne montrait
     rien de la démesure qu'elle est censée annoncer. */
  .oscendence { position: relative; overflow: hidden; isolation: isolate;
                margin: 96px 40px 0; border: 1px solid var(--ligne-2); }
  .oscendence .vis-osc { position: absolute; inset: 0; z-index: 0; }
  .oscendence .vis-osc img { display: block; width: 100%; height: 100%;
                             object-fit: cover; object-position: 50% 42%; }
  /* Le voile. Sans lui le texte passerait sur un salon clair et deviendrait
     illisible ; avec lui la photo reste une présence, pas un décor bruyant. */
  .oscendence .vis-osc::after {
    content: ""; position: absolute; inset: 0;
    background: radial-gradient(120% 90% at 50% 45%,
                rgba(9,8,7,.72) 0%, rgba(9,8,7,.88) 55%, rgba(9,8,7,.96) 100%); }
  .oscendence .bloc { position: relative; z-index: 1; display: flex;
                      flex-direction: column; align-items: center;
                      gap: 24px; padding: 72px 40px; }
  .oscendence .osc-logo { width: 104px; height: auto; }
  .oscendence .txt { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 13px; }
  .oscendence .o-nom { font-family: var(--jost); font-weight: 300; font-size: 26px; letter-spacing: .22em; color: #D5BC8B; padding-left: .22em; line-height: 1.1; }
  .oscendence .o-marque { display: inline-flex; flex-direction: column; align-items: center; }
  .oscendence .o-slogan { font-family: var(--jost); font-weight: 300; font-size: 16px;
                          font-style: italic; color: #E7CE8A; margin-top: 4px; }
  .oscendence .o-mot { font-size: 14px; line-height: 1.75; color: var(--cendre); max-width: 62ch; }
  .oscendence .o-bas { display: flex; flex-direction: column; align-items: center; gap: 13px; }
  .oscendence .o-prix { font-family: var(--jost); font-size: 14px; color: #A79E8B;
                        font-variant-numeric: tabular-nums; letter-spacing: .08em; }
  /* Un vrai bouton, filet d'or et lettres espacees : un lien souligne n'a pas
     le poids qu'appelle une piece a quatre chiffres. */
  .oscendence .o-lien { font-family: var(--jost); font-size: 12px; letter-spacing: .26em;
                        text-transform: uppercase; color: #D5BC8B; padding: 15px 36px 15px 40px;
                        border: 1px solid rgba(213,188,139,.5); white-space: nowrap; }
  .oscendence .o-lien:hover { color: #F2E6C8; border-color: #D5BC8B; background: rgba(213,188,139,.07); }


  /* ---------- pied de page ---------- */
  .pied { margin-top: 96px; border-top: 1px solid var(--ligne); padding: 46px 40px 54px; display: grid;
          grid-template-columns: 300px 1fr 1fr 1fr; gap: 40px; }
  .pied .col { display: flex; flex-direction: column; gap: 11px; }
  .pied .col-titre { font-size: 10px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--argent); margin-bottom: 3px; }
  .pied a, .pied span.l { font-size: 13px; color: var(--cendre); }
  .pied .marque-pied { display: flex; flex-direction: column; align-items: center;
                       text-align: center; gap: 9px; }
  /* Enfant direct seulement : sans le chevron, cette règle attrapait aussi les
     icônes des réseaux placées plus bas et leur donnait 240 px. */
  /* Le logo est un <svg> en ligne dans les maquettes et un <img> dans les
     pages generees, ou il est servi en fichier pour etre mis en cache une
     fois pour tout le site. La regle vise les deux. */
  .pied .marque-pied > svg,
  .pied .marque-pied > .pied-logo { width: 240px; height: auto; }
  /* 4,5:1 minimum sur le fond de nuit : en dessous, ce texte cessait d'etre
     lisible pour une partie des visiteurs. Mesure faite, pas estimee. */
  .pied .mention-pied { font-size: 12px; line-height: 1.7; color: #7F7B72; }
  .pied .reseaux { display: flex; gap: 17px; margin-top: 8px; }
  .pied .reseaux a { color: #6F6B62; display: inline-flex; }
  .pied .reseaux svg { width: 23px; height: 23px; }
  .pied .reseaux a:hover { color: var(--argent); }

  @media (max-width: 1180px) {
    .section { padding-left: 20px; padding-right: 20px; }
    .grille, .grille.cinq, .grille.quatre { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .univers { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .ouverture h1 { font-size: 38px; }
    .ouverture { min-height: 420px; }
    .oscendence { margin: 70px 20px 0; }
    .oscendence .bloc { padding: 52px 28px; gap: 20px; }
    .pied { grid-template-columns: 1fr 1fr; padding-left: 20px; padding-right: 20px; }
  }
  @media (max-width: 620px) {
    .grille, .grille.cinq, .grille.quatre { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
    .univers { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px; }
    .ouverture h1 { font-size: 31px; }
    .pied { grid-template-columns: 1fr; }
    .h2 { font-size: 29px; }

    /* Deux colonnes sur 390 px laissent 175 px par carte : tout le texte
       redescend d'un cran, sinon le titre n'est plus qu'un debut de mot
       suivi de points de suspension. */
    .carte .corps { padding: 13px 11px 15px; gap: 8px; }
    /* « Bouquet aux couleurs chaudes » demande 188 px et la carte en offre
       155 : sur une ligne, le nom serait tronqué. Il passe donc sur deux,
       bornées à une hauteur fixe pour que les cartes restent alignées. */
    .carte .nom-p { font-size: 15px; white-space: normal; line-height: 1.25;
                    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
                    overflow: hidden; min-height: 2.5em; }
    .carte .sens { font-size: 11.5px; min-height: 3.4em; }
    .carte .p { font-size: 15px; }
    .carte .cta { font-size: 10px; padding: 7px 9px; letter-spacing: 0; }
    .tuile .t-corps { padding: 34px 9px 11px; gap: 3px; }
    .tuile .t-nom { font-size: 18px; }
    .tuile .t-note { font-size: 11.5px; }

    /* Le bandeau de service occupe le haut de l'ecran : il se resserre et
       perd ses barres verticales, que le retour a la ligne remplace. */
    .service { font-size: 11px; gap: 7px 14px; padding: 9px 14px; }
    .service .sep { display: none; }

    /* Sur téléphone, la rangée s'empile. L'ordre voulu, de haut en bas :
       la marque, le métier, puis les moyens de nous joindre.

       Le logo et « Fleuriste haut de gamme » forment une seule unité de
       reconnaissance — les séparer par une ligne d'outils cassait l'identité en
       deux au moment précis où le visiteur cherche à savoir où il est arrivé.
       Les outils viennent après : le téléphone et WhatsApp rassurent, le panier
       agit, mais aucun des trois n'a de sens avant qu'on sache chez qui on est.

       « order » réordonne sans toucher au HTML, donc sans rien changer pour un
       lecteur d'écran ni pour un moteur, qui lisent l'ordre du document. */
    /* Sur téléphone, tout l'en-tête s'empile. L'ordre voulu, de haut en bas :
       la marque, le métier, puis les moyens de nous joindre.

       Le logo et « Fleuriste haut de gamme » forment une seule unité de
       reconnaissance — les séparer par une ligne d'outils cassait l'identité en
       deux au moment précis où le visiteur cherche à savoir où il est arrivé.
       Les outils viennent ensuite : le téléphone et WhatsApp rassurent, le
       panier agit, mais aucun des trois n'a de sens avant qu'on sache chez qui
       on est.

       Le titre est frère de la rangée de marque, pas son enfant : « order » ne
       pourrait pas les entrelacer. « display: contents » efface la boîte de la
       rangée et fait remonter ses deux enfants au niveau de l'en-tête, où ils
       peuvent enfin s'ordonner avec le titre. Le HTML ne bouge pas, donc ni les
       lecteurs d'écran ni les moteurs ne voient de différence : ils lisent
       l'ordre du document. */
    .entete { display: flex; flex-direction: column; padding: 14px 16px 0; }
    .rang-marque { display: contents; }
    .entete .marque { order: 1; margin-bottom: 2px; }
    .titre-page { order: 2; padding: 0 0 14px; }
    .outils { order: 3; gap: 13px; font-size: 12px; width: 100%;
              justify-content: center; padding-bottom: 12px; }
    .entete .nav { order: 4; margin: 0 -16px; }
    .panier { padding: 8px 12px; }
    .nav { gap: 20px; padding: 11px 16px; scrollbar-width: none; }
    .nav::-webkit-scrollbar { display: none; }

    .oscendence .bloc { gap: 18px; padding: 40px 20px; }
    .oscendence .osc-logo { width: 76px; }
    .oscendence .o-nom { font-size: 22px; }
    .oscendence .o-lien { padding: 13px 26px 13px 30px; letter-spacing: .2em; }
    /* En haut à droite, la bulle recouvrait le bandeau de service : sur un
       écran de téléphone il n'y a pas de marge où se poser. Elle descend donc
       dans le coin bas, à portée du pouce — c'est là qu'on l'attend sur mobile,
       et elle ne masque plus rien de ce qui se lit.

       Le mot « Assistance » disparaît : le casque se comprend seul, et deux
       lignes de texte flottantes prennent la place d'un produit.

       À la mise en ligne, penser à retirer la bulle Messenger bleue de
       Facebook, qui occupe déjà ce coin. */
    .assistance { right: 14px; top: auto; bottom: 16px; gap: 0;
                  transition: bottom .18s ease-out; }
    .assistance .bulle { width: 48px; height: 48px; }
    .assistance-mot { display: none; }
    /* Le bandeau d'achat prend toute cette bande — 68 px de haut, pleine
       largeur, z-index 60 contre 40. La bulle passait dessous et devenait
       incliquable exactement quand le client a le prix sous les yeux. Elle
       monte au-dessus : 68 px de bandeau plus les 16 px d'écart d'origine.
       La marque est posée sur le corps par `achat.js`, en même temps que
       « visible » sur le bandeau — les deux ne peuvent pas se désaccorder. */
    body.avec-barre-achat .assistance { bottom: 84px; }
    @media (prefers-reduced-motion: reduce) { .assistance { transition: none; } }
  }

  /* Sous 430 px, « FLEURISTE HAUT DE GAMME » ne tient plus sur une ligne
     meme resserre : il passe sur deux, et les filets s'effacent car ils
     n'encadrent plus rien. Les libelles des outils cedent la place aux
     icones, qui se comprennent seules. */
  @media (max-width: 430px) {
    .titre-page { gap: 0; padding: 0 16px 18px; }
    .titre-page .filet { display: none; }
    .titre-page h1 { font-size: 16px; letter-spacing: .26em; padding-left: .26em;
                     white-space: normal; text-align: center; line-height: 1.6; }
    .titre-page .losange { display: none; }
    .lbl-outil { display: none; }
    .outils { gap: 16px; }
    .grille, .grille.cinq, .grille.quatre, .univers { gap: 9px; }
    /* Quatre-vingt-seize pixels de blanc entre deux sections, c'est une
       respiration sur un grand écran et un trou sur un téléphone : la section
       suivante disparaît sous la ligne de flottaison sans que rien n'indique
       qu'elle existe. */
    .section { padding: 44px 14px 0; }
    .section.premiere { padding-top: 18px; }
    .h2 { font-size: 25px; }
  }

  @media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ---------- texte de fond, pour les moteurs et pour les hésitants ---------
   Il vient après le module d'achat : celui qui veut commander n'a pas à le
   traverser, celui qui hésite le trouve, et les robots le lisent.
   Une seule colonne étroite — un texte long en pleine largeur ne se lit pas. */
.texte-seo { border-top: 1px solid var(--ligne); padding: 62px 40px 20px; }
.texte-seo .dedans { max-width: 780px; margin: 0 auto;
                     display: flex; flex-direction: column; gap: 30px; }
.texte-seo h2 { margin: 0 0 14px; font-family: var(--jost); font-weight: 300;
                font-size: 27px; line-height: 1.2; letter-spacing: .01em; }
.texte-seo h3 { margin: 0 0 8px; font-family: var(--jost); font-weight: 400;
                font-size: 15px; letter-spacing: .13em; text-transform: uppercase;
                color: var(--argent); }
.texte-seo p { margin: 0 0 13px; font-size: 15px; line-height: 1.8; color: #B4AFA4; }
.texte-seo p:last-child { margin-bottom: 0; }
.texte-seo strong { color: var(--ivoire); font-weight: 500; }
.texte-seo a { color: var(--argent); border-bottom: 1px solid var(--ligne-2); }
.texte-seo a:hover { border-bottom-color: var(--argent); }
.texte-seo .part { border-left: 1px solid var(--ligne); padding-left: 24px; }

@media (max-width: 620px) {
  .texte-seo { padding: 42px 20px 10px; }
  .texte-seo .dedans { gap: 24px; }
  .texte-seo h2 { font-size: 23px; }
  .texte-seo p { font-size: 14.5px; line-height: 1.75; }
  .texte-seo .part { padding-left: 16px; }
}

/* ---------- texte de fond replié ----------------------------------------
   Google indexe parfaitement le contenu d'un accordéon. Le repli épargne huit
   écrans de texte au client venu commander, tout en donnant aux moteurs de
   quoi comprendre la maison. Écrit en HTML natif : sans script, il s'ouvre
   même si le JavaScript échoue, et le lecteur d'écran le gère seul. */
.fond { border-top: 1px solid var(--ligne); margin-top: 96px; padding: 0 40px 10px; }
.fond .dedans { max-width: 820px; margin: 0 auto; }
.fond details { border-bottom: 1px solid var(--ligne); }
.fond summary { list-style: none; cursor: pointer; padding: 26px 0;
                display: flex; align-items: center; justify-content: space-between; gap: 20px;
                font-family: var(--jost); font-weight: 300; font-size: 22px; }
.fond summary::-webkit-details-marker { display: none; }
.fond summary .chev { width: 11px; height: 11px; flex: 0 0 auto;
                      border-right: 1px solid var(--argent); border-bottom: 1px solid var(--argent);
                      transform: rotate(45deg); transition: transform .2s; margin-bottom: 4px; }
.fond details[open] summary .chev { transform: rotate(-135deg); margin-bottom: 0; }
.fond summary:hover { color: #fff; }
.fond .replie { padding: 0 0 30px; }
.fond h3 { margin: 26px 0 10px; font-family: var(--jost); font-weight: 400; font-size: 15px;
           letter-spacing: .13em; text-transform: uppercase; color: var(--argent); }
.fond h3:first-child { margin-top: 0; }
.fond p { margin: 0 0 13px; font-size: 15px; line-height: 1.8; color: #B4AFA4; }
.fond p:last-child { margin-bottom: 0; }
.fond strong { color: var(--ivoire); font-weight: 500; }

@media (max-width: 620px) {
  .fond { margin-top: 62px; padding: 0 20px 6px; }
  .fond summary { font-size: 19px; padding: 20px 0; }
  .fond p { font-size: 14.5px; line-height: 1.75; }
}

.fond ul { margin: 0 0 13px; padding-left: 20px; }
.fond li { font-size: 15px; line-height: 1.75; color: #B4AFA4; margin-bottom: 5px; }
.fond li strong { color: var(--ivoire); font-weight: 500; }
.fond .chapo { border-left: 1px solid var(--argent); padding-left: 20px; margin-bottom: 22px; }
.fond .chapo p { color: #CFC9BE; }
@media (max-width: 620px) {
  .fond li { font-size: 14.5px; }
  .fond .chapo { padding-left: 14px; }
}

/* ---------- page de réclamation ---------- */
.plainte { padding: 46px 40px 20px; }
.plainte .dedans { max-width: 720px; margin: 0 auto; }
.plainte h1 { margin: 0 0 8px; font-family: var(--jost); font-weight: 300;
              font-size: 40px; line-height: 1.12; letter-spacing: -.005em; }
.plainte .accroche { margin: 0 0 34px; font-size: 17px; line-height: 1.7; color: #CFC9BE; }
.plainte h2 { margin: 40px 0 14px; font-family: var(--jost); font-weight: 300;
              font-size: 25px; line-height: 1.2; }
.plainte p { margin: 0 0 13px; font-size: 15px; line-height: 1.8; color: #B4AFA4; }
.plainte strong { color: var(--ivoire); font-weight: 500; }
.plainte a { color: var(--argent); border-bottom: 1px solid var(--ligne-2); }
.plainte a:hover { border-bottom-color: var(--argent); }

/* Les trois étapes, numérotées : le chemin doit se lire d'un coup d'œil. */
.etapes { display: flex; flex-direction: column; gap: 2px; margin: 26px 0 8px; }
.etape { display: grid; grid-template-columns: 46px 1fr; gap: 18px;
         align-items: start; padding: 20px 0; border-top: 1px solid var(--ligne); }
.etape:last-child { border-bottom: 1px solid var(--ligne); }
.etape .rang { font-family: var(--jost); font-weight: 200; font-size: 30px;
               line-height: 1; color: var(--argent); }
.etape .quoi { display: flex; flex-direction: column; gap: 6px; }
.etape .quoi b { font-family: var(--jost); font-weight: 400; font-size: 17px; color: var(--ivoire); }
.etape .quoi span { font-size: 14.5px; line-height: 1.7; color: #B4AFA4; }

.plainte .bouton { margin-top: 8px; }
.encadre { border: 1px solid var(--ligne-2); padding: 24px 26px; margin: 34px 0 0; }
.encadre h3 { margin: 0 0 10px; font-family: var(--jost); font-weight: 400; font-size: 14px;
              letter-spacing: .13em; text-transform: uppercase; color: var(--argent); }
.encadre p { margin: 0 0 8px; font-size: 14px; line-height: 1.75; }
.encadre p:last-child { margin-bottom: 0; }

@media (max-width: 620px) {
  .plainte { padding: 30px 20px 10px; }
  .plainte h1 { font-size: 30px; }
  .plainte .accroche { font-size: 15.5px; }
  .plainte h2 { font-size: 22px; }
  .etape { grid-template-columns: 34px 1fr; gap: 12px; }
  .etape .rang { font-size: 25px; }
  .encadre { padding: 18px 18px; }
}

/* ---------- page produit generee ---------- */
/* La photo illustre, le module vend : elle garde une largeur fixe et un
   format portrait, pendant que le module prend tout le reste. En carré sur
   une demi-largeur, elle mesurait près de 700 px de côté et repoussait
   l'échelle des tailles hors de l'écran. */
.visuel-p { background: var(--bloc); aspect-ratio: 4 / 5; overflow: hidden;
            position: sticky; top: 18px; }
.visuel-p .photo { width: 100%; height: 100%; object-fit: cover; display: block; }
.prix-p { margin: 0; font-family: var(--jost); font-size: 26px; color: var(--ivoire);
          font-variant-numeric: tabular-nums; }
.texte-p { border-top: 1px solid var(--ligne); padding-top: 20px; }
.texte-p p { margin: 0 0 13px; font-size: 15px; line-height: 1.8; color: #B4AFA4; }
.texte-p p:last-child { margin-bottom: 0; }
.texte-p strong { color: var(--ivoire); font-weight: 500; }
.texte-p ul { margin: 0 0 13px; padding-left: 20px; }
.texte-p li { font-size: 15px; line-height: 1.75; color: #B4AFA4; }
.options { display: flex; flex-direction: column; gap: 16px;
           border-top: 1px solid var(--ligne); padding-top: 20px; }
.options .opt-nom { font-family: var(--jost); font-size: 15px; color: var(--ivoire);
                    display: block; margin-bottom: 7px; }
.options ul { margin: 0; padding-left: 18px; }
.options li { font-size: 14px; line-height: 1.7; color: #A9A398; }
.options .sup { color: var(--argent); font-variant-numeric: tabular-nums; }
@media (max-width: 620px) {
  .prix-p { font-size: 22px; }
  .texte-p p, .texte-p li { font-size: 14.5px; }
}

/* ---------- module d'achat des pages generees ---------- */
.options .opt { display: flex; flex-direction: column; gap: 7px; }
.produit .module { gap: 14px; padding: 0 0 34px; border-left: 0; }
/* Le menu s'appuyait sur le fil d'Ariane : deux zones de nature différente
   collées l'une à l'autre se lisent comme une seule, et la page paraît
   chargée. Un filet et de l'air les séparent. */
.produit .achat { padding-top: 40px; border-top: 1px solid var(--ligne); margin-top: 0; }
/* Sur une page produit, le menu n'est plus la vedette : il recule d'un ton et
   d'un corps pour laisser la fiche occuper le regard. Il reste là — c'est lui
   qui relie les 592 pages entre elles, et Google lit ces liens. */
.produit .nav { border-bottom: 0; padding: 9px 40px 14px; font-size: 13px; }
.produit .nav a { color: #9A958B; }
.produit .nav a:hover { color: var(--ivoire); }
.produit .nav a.osc, .produit .nav a.mar { padding: 4px 11px; }
/* Le ruban tient sur la ligne du fil d'Ariane : deux lignes pour deux mots,
   c'est une ligne de trop quand l'échelle attend en dessous. */
.produit .fil { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 0; }
.produit .fil + .badge { order: 2; margin: 0; }
.produit .module { display: flex; flex-direction: column; }
.produit .badge { align-self: flex-start; margin-top: -6px; }
.produit .options { gap: 14px; padding-top: 16px; }
.produit h1 { font-size: 27px; line-height: 1.12; margin: 0; }
.produit .champ { min-height: 44px; }
.produit .options label.opt-nom { margin-bottom: 0; }
.options label.opt-nom { cursor: pointer; }
/* Treize paliers, deux champs, un vase et un bouton doivent tenir sous les
   yeux : chaque carreau se resserre pour qu'on voie l'échelle entière sans
   défiler. C'est aussi ce que demande la recherche sur le choix — un palier
   supérieur qu'on ne voit pas est une omission possible. */
.choix-lot { display: grid; grid-template-columns: repeat(auto-fit, minmax(98px, 1fr)); gap: 6px; }
.choix { display: flex; flex-direction: column; align-items: center; justify-content: center;
         gap: 2px; min-height: 46px; padding: 7px 6px; cursor: pointer;
         background: var(--creux); border: 1px solid var(--ligne-2); color: var(--ivoire);
         font-family: var(--jost); transition: border-color .15s, background .15s; }
.choix:hover { border-color: var(--argent); }
.choix .choix-nom { font-size: 13px; line-height: 1.2; text-align: center; }
.choix .choix-sup { font-size: 11.5px; color: var(--argent); font-variant-numeric: tabular-nums; }
/* Le choix retenu doit se voir d'un coup d'oeil : c'est lui qui part au panier. */
.choix.actif { background: var(--ivoire); color: var(--nuit); border-color: var(--ivoire); }
.choix.actif .choix-sup { color: #4A4438; }
.alerte { margin: 0; padding: 13px 15px; border: 1px solid #6B4A4A; background: #241A1A;
          color: #E8D5D5; font-size: 14px; line-height: 1.6; }
.ajouter[disabled] { opacity: .55; cursor: progress; }
@media (max-width: 620px) {
  .choix-lot { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 6px; }
  .choix { min-height: 54px; padding: 8px 6px; }
  .choix .choix-nom { font-size: 13px; }
}

/* ---------- le tunnel Ecwid, rendu lisible ------------------------------
   Ces sélecteurs appartiennent à Ecwid, pas à nous : ils peuvent changer sans
   préavis lors d'une de leurs mises à jour. La règle est donc écrite pour
   qu'un changement dégrade l'apparence sans jamais casser le tunnel — aucune
   position, aucun affichage forcé, seulement de la couleur et du corps.

   À revérifier après chaque évolution de leur côté.
------------------------------------------------------------------------- */
#tunnel { --marge: 40px; padding: 0 var(--marge) 40px;
          color: var(--ivoire); }

/* Filet de sécurité. Si la feuille de style d'Ecwid n'arrive pas — coupure,
   bloqueur, panne de leur diffusion — le tunnel s'affichait en couleurs par
   défaut : texte sombre sur fond sombre, liens bleus, boutons gris. Illisible.
   Aucune de ces règles ne porte « !important » : dès que leur thème charge,
   il reprend la main. */
#tunnel a { color: var(--argent); }
#tunnel button:not(.retour-panier), #tunnel input[type="submit"]
  { color: var(--nuit); background: var(--ivoire); }
#tunnel label, #tunnel p, #tunnel span, #tunnel div { color: inherit; }

/* Le tunnel commence haut dans la page : chaque pixel repris au décor est un
   pixel de formulaire visible sans défiler. La rangée de marque se resserre,
   le bandeau, le menu et le pied disparaissent — ils n'offrent que des
   sorties au moment où l'on veut que le client aille au bout. */
body:has(#tunnel:not([style*="display: none"])) .rang-marque { height: 68px; }

/* Les intitulés de section se noyaient dans la masse : « Coordonnées de la
   personne à livrer » doit s'annoncer comme un cap, pas comme une ligne. */
#tunnel .ec-header-h2,
#tunnel .ec-page-title,
#tunnel h2 {
  font-family: var(--jost) !important;
  font-weight: 400 !important;
  letter-spacing: .04em;
  color: var(--argent) !important;
  border-bottom: 1px solid var(--ligne-2);
  padding-bottom: 10px;
}

/* Le tunnel occupe toute la largeur disponible : moins de défilement pour
   voir le formulaire d'adresse en entier. */
#tunnel .ec-size, #tunnel .ec-wrapper { max-width: none !important; }

/* Le rythme vertical d'Ecwid est généreux : neuf champs d'adresse ne tiennent
   pas dans un écran de portable. On resserre l'espacement entre les lignes,
   sans toucher à la taille des champs eux-mêmes — un champ trop petit se rate
   au doigt, et sous 16 px Safari zoome sans redézoomer. */
#tunnel .ec-form__row, #tunnel .ec-form__cell { margin-bottom: 6px !important; }
#tunnel .ec-form__title { margin-bottom: 4px !important; font-size: 15px !important; }

/* Les champs d'Ecwid mesurent près de 58 px de haut. On reprend sur le
   rembourrage, jamais sur le corps du texte : sous 16 px, Safari zoome
   l'écran entier au premier appui et ne redézoome jamais. Un champ de 46 px
   reste largement assez grand pour le doigt — la recommandation d'usage est
   de 44 px. */
#tunnel .ec-form__row input[type="text"],
#tunnel .ec-form__row input[type="tel"],
#tunnel .ec-form__row input[type="email"],
#tunnel .ec-form__row select,
#tunnel .ec-text-field input,
#tunnel .ec-text-field select {
  padding-top: 10px !important; padding-bottom: 10px !important;
  min-height: 46px !important; font-size: 16px !important;
}
#tunnel .ec-form__cell label, #tunnel .ec-text-field label { line-height: 1.3 !important; }

@media (max-width: 620px) { #tunnel { --marge: 16px; } }

/* ---------------------------------------------------------------------------
   Plancher tactile — à laisser en dernier

   Safari zoome tout l'écran dès qu'on touche un champ dont le corps est
   inférieur à 16 px, et ne redézoome jamais. Le plancher ne concerne donc que
   les appareils tactiles.

   Sa place en fin de feuille n'est pas cosmétique : « .champ » pèse autant que
   la règle qui fixe les champs à 14 px, et à poids égal c'est la dernière
   écrite qui l'emporte. Placée plus haut, elle était simplement ignorée.
--------------------------------------------------------------------------- */
@media (pointer: coarse) {
  input, select, textarea, .champ { font-size: 16px; }
}

/* ---------- l'or d'Ecwid, ramené dans la palette ----------
   Le thème de la boutique pose un beige doré (#D4B97F) sur ses liens et ses
   boutons. Sur nos pages, deux choses le rendent faux : il rompt la continuité
   au moment précis où le client engage son paiement — c'est là qu'un doute de
   « suis-je encore sur le même site ? » coûte le plus cher — et l'or appartient
   à Oscendence, pas à l'Atelier.

   La correction est ici plutôt que dans le réglage Ecwid : elle vit dans le
   dépôt, elle se relit, et elle ne dépend pas d'un réglage que personne ne
   retrouvera dans deux ans. Le « !important » est nécessaire, les styles
   d'Ecwid étant injectés après les nôtres. */
/* Sur fond sombre — les liens et titres posés sur notre page. */
#tunnel .ec-link,
#tunnel .ec-link--muted,
#tunnel .ec-link--hover,
#tunnel .ec-cart-item__title,
#tunnel .breadcrumbs__link { color: var(--argent) !important; }

/* Sur fond clair — l'intérieur des champs d'Ecwid, qui sont blancs. L'argent y
   serait illisible : c'est le piège de cette correction, et il valait mieux le
   voir avant de publier. Le gris est assez sombre pour se lire sur blanc, assez
   clair pour ne pas se confondre avec une valeur déjà saisie. */
#tunnel input::placeholder,
#tunnel textarea::placeholder { color: #56565E !important; opacity: 1 !important; }
/* LE GRIS RESTE, ET LE RETIRER A COUTE CINQUANTE ELEMENTS ILLISIBLES.
   J'ai sorti « .form-control__select-text » de ce groupe en le prenant pour un
   indice de saisie mal range. Mesure apres depot : « Trier par » est passe de
   2,6:1 a 1,3, et « Bouquets », « Creations », « Deuil » sont tombes a 1,7 —
   cinquante elements sous le seuil la ou il y en avait un.
   La raison est simple et je ne l'avais pas vue : sans cette regle, ces textes
   heritent de l'ivoire, et Ecwid les pose sur des fonds CLAIRS. Le gris
   n'etait pas une negligence, c'etait le compromis qui tient sur les deux
   fonds. « Trier par » a 2,6:1 est un defaut ; cinquante a 1,7 en est un
   cinquante fois pire.
   Ce qu'il faudrait, c'est distinguer les zones claires des sombres — ce qui
   demande de lire la structure d'Ecwid, pas d'ajouter une regle. A faire apres
   la mise en ligne, pas la veille. */
#tunnel .form-control__placeholder,
#tunnel .form-control__placeholder-inner,
#tunnel .form-control__select-text,
#tunnel .form-control__arrow { color: #56565E !important; }
#tunnel .ec-link:hover,
#tunnel .ec-cart-item__title:hover { color: #FFFFFF !important; }

/* Les boutons d'Ecwid reprennent exactement le nôtre : même ivoire, même
   relief, même enfoncement au clic. Le client ne change pas d'objet en
   changeant d'étape. */
#tunnel .form-control__button {
  background: linear-gradient(180deg, #FFFDF8 0%, var(--ivoire) 55%, #DAD4C7 100%) !important;
  color: var(--nuit) !important; border: 0 !important; border-radius: 3px !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 2px 0 #A8A294,
              0 8px 20px rgba(0,0,0,.5) !important;
  transition: transform .09s, box-shadow .09s, background .15s;
}
#tunnel .form-control__button:hover {
  background: linear-gradient(180deg, #FFFFFF 0%, #F5F1E7 55%, #E2DCCF 100%) !important;
  transform: translateY(-2px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 4px 0 #A8A294,
              0 12px 26px rgba(0,0,0,.55) !important;
}
#tunnel .form-control__button:active { transform: translateY(2px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 0 0 #A8A294,
              0 4px 12px rgba(0,0,0,.5) !important; }

/* La vignette du panier posait un fond beige en attendant sa photo. */
#tunnel .ec-cart-item__picture { background: var(--bloc) !important; }


/* Tous les boutons d'Ecwid, primaires comme secondaires. « Continuer » gardait
   le fond noir et le liseré doré du thème : au milieu d'un tunnel, deux boutons
   d'aspect différent pour la même action font hésiter. L'attribut partiel
   attrape les variantes que le nom exact laisserait passer. */
/* Le bouton, et lui seul. « form-control__button-text » contient la même
   chaîne : un sélecteur par sous-chaîne peignait aussi le libellé, ce qui
   dessinait un rectangle blanc au milieu du bouton. */
#tunnel button.form-control__button,
#tunnel .ec-cart__button button {
  background: linear-gradient(180deg, #FFFDF8 0%, var(--ivoire) 55%, #DAD4C7 100%) !important;
  color: var(--nuit) !important; border: 0 !important; border-radius: 3px !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 2px 0 #A8A294,
              0 8px 20px rgba(0,0,0,.5) !important;
}

/* Le libellé n'hérite de rien : il vit à l'intérieur du bouton. */
#tunnel .form-control__button-text,
#tunnel .form-control__button span {
  background: none !important; box-shadow: none !important;
  color: inherit !important; border: 0 !important; }

/* Ecwid annonce les étapes suivantes en quatre paragraphes administratifs —
   « Sélectionnez le mode d'expédition pour l'envoi de votre commande ». Le
   client n'a pas besoin qu'on lui décrive un formulaire : il a besoin de savoir
   qu'il pourra nommer la personne à livrer, choisir le jour, et payer sans
   risque. On remplace donc le bloc au lieu de le compléter. */
#tunnel .ec-cart-next { display: none !important; }

/* ---------- le bandeau rassurant ---------- */
.rassure { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;
           margin: 0 0 22px; padding: 0; list-style: none; }
.rassure li { display: flex; align-items: center; gap: 11px;
              border: 1px solid var(--ligne-2); background: var(--bloc);
              padding: 13px 18px; font-size: 13.5px; color: var(--ivoire);
              flex: 1 1 240px; max-width: 340px;
              /* Chacun paraît à son tour : l'œil suit la promesse dans l'ordre
                 où elle se déroulera. Le décalage est court — au-delà, on
                 attend le contenu au lieu de le lire. */
              opacity: 0; transform: translateY(7px);
              animation: parait .45s ease-out forwards; }
.rassure li:nth-child(1) { animation-delay: .05s; }
.rassure li:nth-child(2) { animation-delay: .19s; }
.rassure li:nth-child(3) { animation-delay: .33s; }
@keyframes parait { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .rassure li { animation: none; opacity: 1; transform: none; }
}
.rassure svg { width: 21px; height: 21px; flex: 0 0 auto; stroke: var(--argent);
               fill: none; stroke-width: 1.5; stroke-linecap: round;
               stroke-linejoin: round; }
@media (max-width: 620px) {
  .rassure { gap: 8px; margin-bottom: 16px; }
  .rassure li { flex: 1 1 100%; padding: 11px 14px; font-size: 13px; }
}


/* ---------- corrections mobiles, relevées sur téléphone ---------- */
@media (max-width: 620px) {

  /* La photo restait collée en haut pendant que le texte défilait dessous :
     en une seule colonne, « sticky » n'a plus rien à quoi s'accrocher, il ne
     fait que superposer. Sur grand écran il garde tout son sens — la photo
     accompagne la lecture des options. */
  .visuel-p { position: static; top: auto; }

  /* L'en-tête est une colonne, mais rien ne disait à ses enfants de se centrer :
     ils s'étiraient sur toute la largeur, et le bloc de marque — large de 208 px
     par la règle du dessus — se posait donc contre le bord gauche. */
  .entete { align-items: center; }
  .entete .marque { align-self: center; }

  /* Le menu débordait et se faisait défiler du doigt. Un menu qu'il faut
     découvrir en le poussant n'est pas un menu : ceux qui ignorent le geste ne
     voient jamais Mariage ni Oscendence, c'est-à-dire les deux entrées qui ne
     figurent nulle part ailleurs. Il passe donc sur deux lignes — plus haut de
     trente pixels, mais entièrement visible. */
  .entete .nav { flex-wrap: wrap; justify-content: center; overflow: visible;
                 gap: 14px 20px; padding: 12px 16px; }

  /* Les trois bandeaux occupent toute la largeur et se centrent. Justifiés à
     gauche sur un écran étroit, ils laissaient une marge droite vide qui
     donnait la page pour mal cadrée. */
  /* Le bandeau prend toute la largeur : la promesse sur sa ligne, puis la zone
     et la note réparties de part et d'autre. Groupées à gauche, elles laissaient
     une marge droite vide qui donnait la page pour mal cadrée. */
  .service { justify-content: space-between; text-align: center; padding: 9px 14px;
             gap: 6px 12px; }
  .service > span:first-child { width: 100%; }
  .outils { width: 100%; justify-content: space-between; padding: 0 4px 12px; }

  /* Le prix et le bouton se touchaient. Sur deux lignes, chacun retrouve sa
     place : on lit le prix, puis on décide. */
  .carte .bas { flex-direction: column; align-items: stretch; gap: 9px; }
  .carte .cta { text-align: center; padding: 10px 12px; }

  /* Les colonnes du pied sont des flex verticaux : « text-align » seul ne
     centre que le texte à l'intérieur de chaque lien, pas les liens entre eux. */
  .pied { text-align: center; }
  .pied .col { align-items: center; text-align: center; }
  .pied .l { justify-content: center; text-align: center; }
}

/* ---------- pages de texte ----------
   Livraison, conditions, mentions, questions fréquentes, journal, mariage.
   Une seule colonne, une largeur de lecture confortable : au-delà d'environ
   soixante-dix signes par ligne, l'œil perd le début de la ligne suivante. */
.page-texte .contenu { max-width: 760px; margin: 0 auto; padding: 40px 40px 90px; }
.page-texte .fil { font-size: 12px; color: var(--cendre); margin: 0 0 18px; }
.page-texte .fil a { color: var(--cendre); }
.page-texte h1 { font-family: var(--jost); font-weight: 200; font-size: 34px;
                 letter-spacing: .06em; line-height: 1.2; margin: 0 0 18px;
                 color: var(--ivoire); }
.page-texte .chapo-page { font-size: 17px; line-height: 1.75; color: var(--argent);
                          margin: 0 0 34px; }
.page-texte h2 { font-family: var(--jost); font-weight: 300; font-size: 22px;
                 letter-spacing: .03em; margin: 40px 0 12px; color: var(--ivoire);
                 border-top: 1px solid var(--ligne); padding-top: 30px; }
.page-texte h3 { font-family: var(--jost); font-weight: 400; font-size: 16px;
                 letter-spacing: .04em; margin: 26px 0 8px; color: var(--argent); }
.page-texte p, .page-texte li { font-size: 15px; line-height: 1.8; color: #B9B3A7; }
.page-texte ul, .page-texte ol { padding-left: 20px; }
.page-texte li { margin-bottom: 7px; }
.page-texte strong { color: var(--ivoire); font-weight: 500; }
/* LE SOULIGNEMENT NE VAUT QUE POUR LA PROSE.
   Cette règle visait « .page-texte a », et « .page-texte » enveloppe TOUTE la
   page — l'en-tête, le menu, le fil d'Ariane, le téléphone et le pied compris.
   Résultat : sur les quelque cent pages de texte du site, tous les boutons du
   menu étaient soulignés. Olivier l'a relevé sur Oscendence ; le défaut y était
   simplement le plus visible, il touchait toutes les pages de texte.

   Un lien souligné dans un paragraphe se lit comme un lien, c'est sa fonction.
   Le même trait sous un bouton de menu le fait ressembler à une faute de mise
   en page. On vise donc « .contenu », qui est le seul conteneur de la prose. */
.page-texte .contenu a { color: var(--argent); text-decoration: none; }
/* LE SURVOL RESTE COLLE APRES UN RETOUR EN ARRIERE, SUR TELEPHONE.
   Olivier, le 4 septembre 2026 : « j'ai cliqué sur un produit, revenu en
   arrière et tout est souligné ». Ce n'est pas un defaut de la page, c'est le
   comportement du tactile : faute de curseur qui s'en aille, le navigateur
   garde l'etat « :hover » sur le dernier element touche, et le restaure au
   retour. La page revient donc soulignee, sans que rien ne la survole.
   Le remede est de ne poser le survol que la ou il existe vraiment. Ce
   fichier le fait deja pour les fleches du carrousel ; il fallait le faire
   ici aussi. */
@media (hover: hover) {
  .page-texte .contenu a:hover { text-decoration: underline; text-underline-offset: 3px;
                                 text-decoration-thickness: 1px; }
}
/* Un bouton ne se souligne jamais : le soulignement traverse les capitales
   espacees du libelle et le rend illisible. Constate par Olivier sur
   « Estimer mon budget floral ». Idem pour un numero de telephone. */
.page-texte .contenu a.ajouter, .page-texte .contenu a[href^="tel:"],
.page-texte .contenu a.ajouter:hover, .page-texte .contenu a[href^="tel:"]:hover {
  text-decoration: none;
}
/* LA COULEUR, et pas seulement le soulignement.

   « .ajouter » pose color: var(--nuit) avec une specificite de (0,1,0) ;
   « .page-texte .contenu a » pose var(--argent) avec (0,2,0) et l'emporte. Un
   bouton place dans une page de texte affichait donc de l'argent clair sur un
   fond creme : CONTRASTE MESURE 1,68:1, illisible. Olivier l'a signale deux
   fois — la premiere fois j'ai retire le soulignement, qui n'etait que le
   symptome visible, et le vrai defaut est reste en ligne. */
.page-texte .contenu a.ajouter { color: var(--nuit); }
@media (hover: hover) { .page-texte a:hover { color: #fff; } }
/* UNE CARTE N'EST PAS UN LIEN DE TEXTE. Les pieces Oscendence sont des images
   avec leur nom et leur note dessous ; les souligner d'un trait de prose les
   fait passer pour une note de bas de page. */
.page-texte .contenu a.osc-carte,
.page-texte .contenu a.osc-carte:hover { text-decoration: none; }
/* Un encadré pour ce qui doit être vu même par qui survole. */
.page-texte .encadre { border: 1px solid var(--ligne-2); background: var(--bloc);
                       padding: 20px 24px; margin: 26px 0; }
.page-texte .encadre p:last-child { margin-bottom: 0; }
.page-texte .encadre p:first-child { margin-top: 0; }
.page-texte table { width: 100%; border-collapse: collapse; margin: 20px 0;
                    font-size: 14px; }
.page-texte th, .page-texte td { text-align: left; padding: 10px 12px;
                                 border-bottom: 1px solid var(--ligne); }
.page-texte th { color: var(--argent); font-weight: 500; }
.page-texte td { color: #B9B3A7; }
@media (max-width: 620px) {
  .page-texte .contenu { padding: 24px 16px 60px; }
  .page-texte h1 { font-size: 26px; }
  .page-texte .chapo-page { font-size: 16px; }
  .page-texte h2 { font-size: 19px; margin-top: 30px; padding-top: 22px; }
}

/* ---------- cibles tactiles ----------
   Un doigt vise mal : la recommandation d'usage est quarante-quatre pixels de
   côté, et plusieurs de nos commandes étaient nettement en dessous — sélecteur
   de langue, téléphone, WhatsApp, panier, entrées de menu, icônes sociales.

   On agrandit la ZONE, pas le dessin. Le trait reste fin, ce qui compte pour une
   maison qui vend du haut de gamme ; c'est la surface sensible qui grandit,
   invisible. Un client pressé ou âgé n'a pas à viser.

   « pointer: coarse » plutôt qu'une largeur d'écran : c'est le doigt qu'on vise,
   pas le téléphone. Une tablette large en a un aussi. */
@media (pointer: coarse) {
  .outils > a,
  .langue-actuelle,
  .panier { min-height: 44px; display: inline-flex; align-items: center; }
  .outils > a { padding: 0 6px; }
  .wa { padding: 0 8px; }

  .nav a { min-height: 44px; display: inline-flex; align-items: center;
           padding: 0 4px; }

  /* Les icônes sociales gardent leurs dix-neuf pixels de trait, dans une zone
     de quarante-quatre. */
  .pied .reseaux a { min-width: 44px; min-height: 44px;
                     display: inline-flex; align-items: center; justify-content: center; }
  .pied .reseaux { gap: 6px; }

  .pied .col a { min-height: 40px; display: flex; align-items: center; }

  /* Les paliers de taille et les choix d'options se touchent au doigt. */
  .palier, .choix { min-height: 44px; }
  .vase { min-height: 48px; }
}


/* ---------- la rangée d'outils, en trois colonnes ----------
   Le téléphone doit être au milieu de l'écran, pas au milieu de ce qui reste
   une fois les autres placés. Une grille de trois colonnes le garantit : les
   deux colonnes latérales prennent la même part, quoi qu'elles contiennent, et
   la colonne centrale se retrouve donc sur l'axe.

   Avec « space-between », le centre se déplaçait dès qu'un libellé changeait de
   longueur — « Panier », « Cart », « Warenkorb ». */
.outils { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
          width: 100%; gap: 10px; }
.outils-gauche { display: inline-flex; align-items: center; gap: 14px;
                 justify-self: start; }
.tel-entete { justify-self: center; white-space: nowrap; }
.panier { justify-self: end; }

@media (max-width: 620px) {
  /* Sur téléphone, le numéro est la commande la plus utile de la page : il
     passe seul sur sa ligne, au centre et en plus grand. Le panier et la langue
     se partagent la ligne du dessous, chacun à son bord.

     Ce bloc plaçait encore les éléments de l'ancienne rangée — une colonne de
     gauche depuis supprimée, un téléphone qui n'est plus un enfant direct de la
     grille. Le panier héritait donc d'une consigne « ligne 2, colonne 3 » qui
     l'expédiait seul en bas à droite, à l'exact opposé de sa place. Une règle
     de disposition qui nomme des éléments disparus ne provoque aucune erreur :
     elle place ce qui reste, au hasard de ce qui subsiste. */
  .outils { grid-template-columns: 1fr 1fr; row-gap: 12px; }
  .outils-centre { grid-row: 1; grid-column: 1 / -1; justify-self: center;
                   font-size: 15px; letter-spacing: .02em; }
  .outils .panier { grid-row: 2; grid-column: 1; justify-self: start; }
  .outils .langue { grid-row: 2; grid-column: 2; justify-self: end; }
}

/* ---------- le menu, deux rangées franches ----------
   Sept entrées ne tiennent pas sur une ligne de téléphone. Plutôt qu'un
   enroulement de hasard, on impose des cellules de même largeur : les deux
   rangées s'alignent, et l'ensemble se lit comme une grille voulue et non
   comme un débordement. */
@media (max-width: 620px) {
  /* CINQ RAYONS SUR UNE SEULE LIGNE. A 375 px il reste 355 px utiles : cinq
     libelles, quatre intervalles. « Creations » est le plus long — a 11 px
     sans interlettrage il tient en 52 px, et cinq boutons de 66 px rentrent.
     C'est serre, et c'est le prix a payer pour que la boutique se lise d'un
     seul regard comme un groupe. Les deux metiers vont sur la ligne du
     dessous, ou la place ne manque plus. */
  .entete .nav { display: flex; flex-wrap: wrap; justify-content: center;
                 gap: 4px; padding: 6px 6px 10px; }
  /* TOUTE LA LARGEUR. Centres, les cinq rayons laissaient une marge morte de
     chaque cote et la rangee flottait. « flex: 1 » les fait partager la ligne
     a parts egales, bord a bord — et la boutique se lit d'un bloc. */
  .entete .nav a { justify-content: center; text-align: center;
                   flex: 1 1 0; min-width: 0; white-space: nowrap; }
  /* Une barriere, pas un filet : sur telephone le separateur n'a pas besoin
     d'etre vu, il a besoin de pousser les deux marques sur leur propre ligne.
     Largeur pleine, hauteur nulle — il ne se voit pas et il fait tout. */
  .entete .nav .nav-coupe {
    flex: 0 0 100%; width: auto; height: 0; margin: 9px 0 0; background: none;
  }
  /* Les deux metiers ne se touchent pas. Colles, ils se lisent comme une
     paire ; espaces, chacun redevient une porte. */
  /* PAS DE MARGES. Les trois pastilles s'etirent a parts egales comme les
     cinq rayons du dessus — c'est ce que la mise en page faisait deja, et s'y
     opposer coutait les six pixels qui faisaient tomber « Evenements » seule
     sur une quatrieme ligne. Trois blocs egaux sous cinq blocs egaux se lisent
     mieux que trois blocs de largeurs differentes. L'intervalle de la rangee
     suffit a les separer. */
  .entete .nav a.osc, .entete .nav a.mar, .entete .nav a.eve {
    /* La borne explicite met l'arrondi hors d'etat de nuire : trois tiers ne
       peuvent plus faire plus d'un tout. */
    flex: 1 1 0; margin: 0; max-width: calc(33.33% - 3px);
  }
}

/* ---------- le pied, en blocs ----------
   Ce bloc posait deux colonnes alignées à gauche. Il a été retiré le
   2 septembre : la répartition en trois colonnes centrées vit plus bas, et
   deux règles qui décrivent la même chose finissent toujours par se
   contredire. Seule reste ici la hauteur de cible tactile. */
@media (max-width: 620px) {
  .pied .marque-pied { grid-column: 1 / -1; }
  .pied .col a { min-height: 34px; }
}

/* L'encadré des garanties légales est un texte imposé, plus dense que le reste.
   Il se lit comme un document dans le document : un peu plus petit, un peu plus
   serré, et clairement délimité. */
.page-texte .encadre-legal p { font-size: 13.5px; line-height: 1.65; }
.page-texte .encadre-legal ul { margin: 8px 0; }
.page-texte .encadre-legal li { font-size: 13.5px; margin-bottom: 4px; }
.page-texte .maj { margin-top: 40px; padding-top: 20px;
                   border-top: 1px solid var(--ligne); font-size: 13px;
                   color: var(--cendre); }

/* ---------- le journal ----------
   Une liste d'articles se parcourt en diagonale : le titre porte, la première
   phrase décide. Un filet sépare, sans encadrer — un encadré par article
   donnerait une grille de fiches, pas une table des matières. */
.page-texte .art { border-top: 1px solid var(--ligne); padding-top: 26px;
                   margin-bottom: 30px; }
.page-texte .art h2 { border-top: 0; padding-top: 0; margin: 0 0 10px;
                      font-size: 20px; line-height: 1.35; }
.page-texte .contenu .art h2 a { color: var(--ivoire); text-decoration: none; }
.page-texte .contenu .art h2 a:hover { color: #fff; text-decoration: underline;
                              text-underline-offset: 4px; }
.page-texte .art p { margin: 0 0 10px; }
.page-texte .art-lire a { font-family: var(--jost); font-size: 13px;
                          letter-spacing: .1em; color: var(--argent); }

/* ---------- la fiche produit sur téléphone ----------
   Mesuré : le nom du produit tombait à 910 px et le bouton d'achat à 1 600 px,
   pour un écran de 812. Un visiteur venu d'une publicité voyait une photo et
   rien d'autre — ni ce qu'on lui vend, ni combien.

   Trois corrections qui tiennent ensemble :

   1. Le fil d'Ariane, le nom et le prix passent AVANT la photo. Le HTML ne
      bouge pas : « order » suffit, et les moteurs continuent de lire l'ordre du
      document.
   2. La photo est plafonnée à 42 % de la hauteur d'écran. Elle reste le premier
      argument, elle cesse d'être un mur.
   3. Un bandeau collant porte le prix et le bouton dès que le vrai bouton sort
      de l'écran — voir achat.js. */
@media (max-width: 620px) {
  /* La photo et le module sont frères : « order » seul ne peut pas les
     entrelacer. « display: contents » efface la boîte du module et fait remonter
     ses enfants au niveau de la section, où tout peut enfin s'ordonner. Le HTML
     ne bouge pas, donc ni les lecteurs d'écran ni les moteurs ne voient de
     différence. */
  .produit .achat { display: flex; flex-direction: column; gap: 0; padding: 0 14px 30px; }
  .produit .module { display: contents; }

  /* DE L'AIR ENTRE LA MARQUE ET LE FIL D'ARIANE — 6 septembre 2026.
     Olivier, sur son telephone : « Il faudrait laisser un espace un peu plus
     important entre L'Atelier d'Olivier Fleuriste et le fil d'ariane, c'est
     trop condense ». Mesure a 412 px : le bloc de marque finissait a 177, le
     fil commencait a 179 — DEUX pixels. Les deux se lisaient comme un seul
     bloc, alors que l'un est l'identite de la maison et l'autre un reperage.

     LA MARGE VA ICI ET NON SUR « .produit .fil ». Posee la, elle etait
     ecrasee : cette regle-ci vaut (0,3,1) contre (0,2,0), et c'est elle qui
     gouverne des que la fiche se replie. Corrige une premiere fois au mauvais
     endroit, sans effet visible — la mesure l'a dit, pas l'oeil.

     Seize pixels, pas davantage : sur une fiche, chaque pixel d'en-tete est un
     pixel de moins pour le bouquet, et c'est le bouquet qu'on vient voir. */
  .produit .module > .fil       { order: 1; margin: 16px 0 6px; }
  .produit .module > .badge     { order: 2; }
  .produit .module > h1         { order: 3; margin: 0 0 12px; }
  .produit .visuel-p            { order: 4; aspect-ratio: auto; max-height: 38vh;
                                  margin: 0 0 16px; }
  .produit .visuel-p .photo     { height: 38vh; object-fit: cover; }
  .produit .module > .opt,
  .produit .module > .options   { order: 5; margin-bottom: 14px; }
  .produit .module > .proportion { order: 6; margin-bottom: 14px; }
  .produit .module > .alerte    { order: 7; }
  .produit .module > .ajouter   { order: 8; width: 100%; max-width: none; }
  .produit .module > .sous-bouton { order: 9; margin-top: 10px; }
  .produit .module > .texte-p   { order: 10; margin-top: 22px; }
  .produit .module > .mention   { order: 11; }
}

/* ---------- le bandeau d'achat collant ----------
   Il n'apparaît que lorsque le vrai bouton a quitté l'écran : tant qu'on le
   voit, en ajouter un second serait du bruit. */
.barre-achat { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
               display: none; align-items: center; justify-content: space-between;
               gap: 12px; padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
               background: rgba(16,16,18,.96);
  /* LE PREFIXE EST OBLIGATOIRE SUR SAFARI, et Safari est le navigateur de
     l'iPhone — donc d'une bonne part des visiteurs de ce site. Sans lui, la
     barre d'achat perd son flou : le fond reste opaque a 96 %, ce qui la rend
     lisible quand meme, mais elle cesse de laisser deviner la page dessous.
     Deux mots de plus, et le rendu est le meme partout. */
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
               border-top: 1px solid var(--ligne-2);
               box-shadow: 0 -8px 24px rgba(0,0,0,.5); }
.barre-achat.visible { display: flex; }
.barre-achat .bp { font-family: var(--jost); font-size: 19px; color: var(--ivoire);
                   white-space: nowrap; font-variant-numeric: tabular-nums; }
.barre-achat .bb { flex: 1 1 auto; max-width: 220px; min-height: 48px;
                   display: inline-flex; align-items: center; justify-content: center;
                   border: 0; border-radius: 3px; cursor: pointer;
                   background: linear-gradient(180deg, #FFFDF8 0%, var(--ivoire) 55%, #DAD4C7 100%);
                   color: var(--nuit); font-family: var(--ui); font-size: 14px;
                   font-weight: 600;
                   box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 2px 0 #A8A294; }
@media (min-width: 621px) { .barre-achat { display: none !important; } }

/* Les cibles tactiles étaient conditionnées au seul « pointer: coarse ». C'est
   juste, mais invérifiable en émulation : la largeur d'écran sert donc aussi de
   déclencheur. Deux portes valent mieux qu'une pour une règle qu'on ne peut pas
   mesurer autrement. */
@media (max-width: 620px) {
  .outils > a, .langue-actuelle, .panier,
  .nav a { min-height: 44px; display: inline-flex; align-items: center; }
  .pied .reseaux a { min-width: 44px; min-height: 44px; display: inline-flex;
                     align-items: center; justify-content: center; }
  .pied .col a { min-height: 40px; display: flex; align-items: center; }
  .palier, .choix { min-height: 44px; }
  .carte .cta { min-height: 44px; display: inline-flex; align-items: center;
                justify-content: center; }
}

/* ---------- l'en-tête, une seule colonne à toutes les largeurs ----------
   Le logo se tenait sur la même ligne que la langue, WhatsApp et le panier :
   il n'était donc jamais au centre de la page, seulement au centre de ce qui
   restait. Sur téléphone la colonne était déjà en place ; l'étendre au grand
   écran donne une mise en page unique, plus simple à tenir, et met la marque
   sur l'axe.

   Même mécanique que sur téléphone : « display: contents » efface la boîte de
   la rangée pour que ses enfants s'ordonnent avec le titre. Le HTML ne change
   pas. */
.entete { display: flex; flex-direction: column; align-items: center; }
.rang-marque { display: contents; }
.entete .marque { order: 1; align-self: center; }
.titre-page { order: 2; }
/* Bridée à 1 100 px et centrée, la rangée laissait quatre cents pixels de vide
   de chaque côté sur un écran large : le panier et la langue flottaient au
   milieu de nulle part au lieu de tenir les bords. Elle occupe maintenant toute
   la largeur, avec le même retrait de quarante pixels que le bandeau de service
   au-dessus — les trois rangées de l'en-tête s'alignent alors sur un même bord. */
.outils { order: 3; width: 100%; max-width: none;
          padding: 0 40px 16px; margin: 0; }
.entete .nav { order: 4; width: 100%; }
.produit .entete .marque { margin-top: 14px; }

/* Le bandeau de service respirait mal : trois informations collées au centre
   d'une ligne de mille pixels. Elles se répartissent maintenant sur toute la
   largeur, séparées par leurs barres.

   ELLES TIENNENT LE BORD, ELLES NE FLOTTENT PLUS. Olivier, le 6 septembre
   2026 : « Note sur Google n'est pas justifié à gauche ». Mesuré sur
   1 440 px avant correction : « Livraison aujourd'hui » commençait à 167 px
   quand la première entrée du menu, juste en dessous, commençait à 40 px ; et
   « Noté sur Google » s'arrêtait à 182 px du bord droit quand le sélecteur de
   langue s'arrête à 15. La bande entière flottait au milieu, décalée des deux
   rangées qu'elle surmonte.

   Deux causes, toutes deux réparées ici :

   1. « space-evenly » pose un intervalle AVANT le premier élément et APRÈS le
      dernier. Les extrémités ne touchent donc jamais le bord, quel que soit le
      retrait. « space-between » les y colle, et laisse le reste se répartir.
   2. Le retrait droit de cent dix pixels avait été posé pour dégager la bulle
      d'assistance, à l'époque où elle vivait en haut à droite. Olivier l'a
      fait descendre le 5 septembre : mesurée le 6, elle est à 22 px du BAS sur
      800 comme sur 1 440 px. Le retrait ne dégage donc plus rien — il ne fait
      que désaligner.

   Le retrait devient celui des autres rangées, au pixel près : c'est la même
   expression que « .entete .nav ». Sur un écran large, les trois rangées de
   l'en-tête partagent alors le bord du bloc de 1 360 px. */
.service {
  justify-content: space-between; gap: 10px 40px;
  padding-block: 11px;
  padding-inline: max(40px, calc((100% - 1360px) / 2));
}

@media (max-width: 900px) {
  .outils { padding: 0 20px 14px; }
  .service { padding: 10px 20px; gap: 8px 22px; }
}

/* ---------- la rangée d'outils, remise dans l'ordre de l'usage ----------
   Le panier à gauche, le téléphone et WhatsApp ensemble au centre, la langue à
   droite. Le téléphone et WhatsApp servent à la même chose — joindre un
   fleuriste — et les séparer obligeait l'œil à chercher deux fois. Le sélecteur
   de langue, lui, ne sert qu'une fois par visite : sa place est au bord. */
.outils-centre { display: inline-flex; align-items: center; gap: 14px;
                 justify-self: center; }
.outils .panier { justify-self: start; }
.outils .langue { justify-self: end; }
.outils-gauche { display: none; }

/* La marque était écrasée par le métier : trente-trois pixels pour « FLEURISTE
   HAUT DE GAMME » contre onze pour « L'ATELIER D'OLIVIER ». Le nom de la maison
   passait après sa description, ce qui est l'inverse de ce qu'on veut. */
.entete .marque { width: 300px; }
.entete .marque .mono { width: 300px; }
.entete .marque .nom { font-size: 15px; letter-spacing: .26em;
                       padding-left: .26em; color: #B9BEC5; }
.titre-page h1 { font-size: 29px; letter-spacing: .38em; padding-left: .38em; }

@media (max-width: 620px) {
  .entete .marque, .entete .marque .mono { width: 240px; }
  .entete .marque .nom { font-size: 12px; letter-spacing: .2em; padding-left: .2em; }
  .titre-page h1 { font-size: 19px; letter-spacing: .26em; padding-left: .26em; }
  .outils-centre { gap: 10px; }
}

/* ---------- l'en-tête tient les bords de l'écran ----------
   Le panier et le sélecteur de langue restaient loin des bords sur un grand
   écran, et ce n'était pas la faute de la rangée : `.page` plafonne tout le
   site à 1 440 px. Au-delà, le conteneur laissait deux cent cinquante pixels
   de vide de chaque côté, et les outils flottaient au milieu de nulle part.

   Le plafond a sa raison d'être pour le contenu — une ligne de texte de mille
   huit cents pixels ne se lit pas. Mais il n'a aucune raison de s'appliquer à
   l'habillage : bandeau de service, outils et menu sont la carrosserie du site,
   pas son contenu, et leur place est au bord.

   D'où ce renversement : le plafond quitte `.page` pour se poser sur chacun de
   ses enfants, sauf ces deux-là. Le contenu garde donc exactement la largeur
   qu'il avait — rien ne bouge dans les pages — et seul l'en-tête s'élargit.

   Aucun `vw` ici, volontairement : `100vw` compte la barre de défilement, et
   la marge négative qu'on en tire déborde de sa largeur. C'est ainsi qu'on
   fabrique un défilement horizontal sans le voir sur son propre écran.

   Et rien de tout cela en dessous de 1 441 px : à cette largeur le plafond ne
   mordait déjà pas. Les téléphones et les portables ne voient pas la
   différence, ce qui est la meilleure façon de ne rien casser chez eux. */
@media (min-width: 1441px) {
  .page { max-width: none; margin: 0; }
  .page > * { max-width: 1440px; margin-inline: auto; }
  .page > .service,
  .page > .entete { max-width: none; }
}

/* ---------- le bandeau de service, vraiment sur l'axe ----------
   « France et Monaco » tombait cinquante-cinq pixels à droite du logo. Deux
   causes se cumulaient, et aucune ne se voyait à l'œil sans mesurer.

   La première : une répartition automatique pose des intervalles égaux entre
   des éléments de longueurs inégales. « Livraison le jour même proposée pour
   toute commande avant 12 h » fait trois cent cinquante pixels, « Noté sur
   Google » beaucoup moins — l'élément du milieu se retrouve donc poussé du
   côté du plus court. Des intervalles égaux ne donnent un milieu centré que si
   les extrémités pèsent le même poids.

   La seconde : le retrait droit de cent dix pixels, posé pour dégager la bulle
   d'assistance, déplaçait le centre de la boîte de trente-cinq pixels vers la
   gauche sans que rien ne le rattrape.

   La grille corrige les deux. Cinq colonnes « 1fr auto 1fr auto 1fr » : les
   trois colonnes de texte prennent la même part, les deux barres la leur, et
   le centre de la colonne du milieu tombe exactement sur le centre de la
   boîte. Le retrait devient symétrique pour que ce centre soit aussi celui de
   l'écran.

   Réservé aux écrans larges : en dessous, une colonne au tiers ne contient
   plus la première phrase, et la répartition automatique reste préférable. */
@media (min-width: 1500px) {
  .service { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr;
             align-items: center; gap: 0;
             /* Même retrait que les deux rangées du dessous — les cent dix
                pixels dégageaient la bulle d'assistance, qui vit maintenant en
                bas. Voir la note sur « .service » plus haut. */
             padding-block: 11px;
             padding-inline: max(40px, calc((100% - 1360px) / 2)); }
  /* Le milieu reste centré — c'est toute la raison d'être de la grille — mais
     les extrémités tiennent le bord, comme le menu et la rangée d'outils.
     Centrer les trois faisait flotter les deux du bord sans rien y gagner. */
  .service > * { justify-self: center; }
  .service > *:first-child { justify-self: start; }
  .service > *:last-child { justify-self: end; }
}

/* La marque tenait sur deux lignes séparées par deux pixels : « L'ATELIER
   D'OLIVIER » et « FLEURISTE HAUT DE GAMME » se touchaient presque. Le nom de
   la maison et son métier sont deux énoncés, pas une phrase coupée en deux —
   il leur faut de quoi se distinguer. */
.titre-page { padding-top: 20px; }

/* ================= LES TEXTES GRANDISSENT AVEC L'ÉCRAN =================

   Tout l'en-tête était écrit en tailles fixes, choisies sur un écran de
   portable. Mesuré sur 1 835 pixels : bandeau du haut à douze pixels, panier
   et téléphone à treize, menu à quatorze dont les sept entrées n'occupaient
   que quatre cent douze pixels — vingt-deux pour cent de la largeur. Un
   numéro de téléphone à treize pixels sur un écran de vingt-sept pouces n'est
   pas discret, il est illisible.

   La règle : chaque taille s'exprime en trois valeurs — un plancher, une part
   de la largeur de l'écran, un plafond. En dessous du plancher le texte ne
   descend jamais, ce qui protège le téléphone ; au-dessus du plafond il cesse
   de grandir, ce qui évite qu'un grand écran ne donne des titres de journal.
   Entre les deux, il suit l'écran.

   Le plafond n'est pas une coquetterie : sans lui, un écran de deux mille cinq
   cents pixels afficherait un menu de trente-deux pixels, et l'en-tête
   mangerait la moitié de la page avant la première fleur.

   Les planchers reprennent exactement les tailles actuelles du téléphone :
   rien ne bouge en dessous de 620 px, et ce qui marche là ne se casse pas. */

.service            { font-size: clamp(12px, 0.85vw, 17px); }
.outils             { font-size: clamp(14px, 1.05vw, 21px); }
.outils-centre      { font-size: clamp(15px, 1.25vw, 25px); }
.entete .marque .nom{ font-size: clamp(12px, 1.00vw, 20px); }
.titre-page h1      { font-size: clamp(19px, 1.85vw, 36px); }
.entete .nav        { font-size: clamp(15px, 1.38vw, 27px); }

/* Le logo suit le même mouvement. Il restait à trois cents pixels quel que
   soit l'écran, ce qui le faisait rétrécir à mesure que la page s'élargissait
   — un effet d'optique, mais un effet réel. */
.entete .marque,
.entete .marque .mono { width: clamp(240px, 20vw, 380px); }

/* ---------- le menu prend toute la largeur ----------
   Sept entrées groupées au centre laissaient les quatre cinquièmes de la barre
   vides. Elles se répartissent maintenant d'un bord à l'autre. C'est aussi ce
   qui rend chaque entrée plus facile à viser : la cible ne grandit pas, mais
   la distance entre deux cibles voisines double, et c'est elle qui produit les
   clics manqués. */
@media (min-width: 621px) {
  .entete .nav { justify-content: space-between; gap: 10px;
                 padding-inline: clamp(20px, 3vw, 70px); }
}

/* ---------- sur téléphone, deux rangées franches ----------
   Sept entrées ne tiennent pas sur une ligne à une taille lisible : quatre
   puis trois, sur une grille de douze colonnes qui divise exactement les deux
   rangées — trois colonnes par entrée en haut, quatre en bas. Les deux lignes
   s'alignent au pixel au lieu de se centrer approximativement. */
@media (max-width: 620px) {
  .entete .nav { grid-template-columns: repeat(12, 1fr);
                 font-size: clamp(14.5px, 4.1vw, 18px); }
  .entete .nav a { grid-column: span 3; }
  .entete .nav a:nth-child(5) { grid-column: 1 / span 4; }
  .entete .nav a:nth-child(6) { grid-column: 5 / span 4; }
  .entete .nav a:nth-child(7) { grid-column: 9 / span 4; }
}

/* ---------- le téléphone et le menu sur l'écran d'un téléphone ----------
   Deux règles anciennes imposaient encore des tailles fixes que l'échelle
   ci-dessus ne pouvait pas atteindre : quinze pixels pour le numéro, treize
   pour les entrées de menu. Sur l'appareil qui fait l'essentiel des commandes,
   c'était le contraire de ce qu'il fallait — le numéro y est la deuxième façon
   de commander, après le bouton d'achat.

   Ce bloc vient en dernier pour les emporter, plutôt que d'aller les modifier
   là où elles sont : elles y sont écrites au milieu de la mise en page des
   deux rangées, et les défaire à distance revient à casser cette mise en page
   pour changer un chiffre. */
@media (max-width: 620px) {
  .outils-centre,
  .outils-centre .tel-entete,
  .outils-centre a           { font-size: 17px; }
  .entete .nav,
  .entete .nav a             { font-size: clamp(14.5px, 4.1vw, 18px); }
}

/* ================= LISIBILITÉ : LES PETITS TEXTES =================

   Relevé de Codex sur sept pages du dépôt de test, le 31 août 2026. Le fond
   sombre n'est pas en cause — les titres tiennent un contraste de 15:1, les
   paragraphes 9:1. Ce sont les tailles, et un contraste précis.

   La mention « facultatif » plafonnait à 3,58:1, en dessous du minimum de
   4,5:1 que les règles d'accessibilité posent pour du texte courant, et à dix
   pixels. Elle passe à quatorze et s'éclaircit. Le gris retenu, #9A9488, donne
   4,9:1 sur le fond de page : au-dessus du seuil, sans devenir aussi présente
   que l'étiquette qu'elle accompagne — une mention facultative qui crie serait
   un contresens.

   Les suppléments de prix étaient à 11,5 px. C'est une information d'achat :
   le client compare des paliers, et le chiffre qui les sépare était le plus
   petit texte de la page. Quatorze.

   Les champs de saisie montaient déjà à 16 px sur les appareils tactiles —
   Safari zoome l'écran en dessous et ne le rend jamais. Ils y passent partout,
   et leur contour se renforce : ils se distinguaient mal du fond.

   Ces valeurs sont un choix de confort, pas un seuil réglementaire — sauf le
   contraste de la mention, qui l'est. */

.mention-champ        { font-size: 14px; letter-spacing: .10em; }
.mention-champ.facultatif { color: #9A9488; }

/* LE COMPTE DE CARACTERES DU RUBAN.
   Il s'affiche avant la saisie, pas apres : « 40 caracteres maximum » annonce
   la contrainte, puis le script la remplace par ce qu'il reste. Une limite
   qu'on decouvre en butant dessus se lit comme une panne du champ.
   Il vire a l'ambre sous dix caracteres restants — le moment ou l'on cherche
   comment finir sa phrase — et au rouge a zero. */
.mention-champ.compte { color: #8E887C; margin-left: 10px; letter-spacing: .06em; }
.mention-champ.compte.serre { color: #C9A227; }
.mention-champ.compte.plein { color: #C97A6D; }
.choix .choix-sup     { font-size: 14px; }
.palier .p            { font-size: 14px; }
.prop-txt, .vase-det  { font-size: 14px; }
.mention              { font-size: 14px; }
.champ                { font-size: 16px; border-color: #6A6A78; }
.champ:hover          { border-color: #8A8A98; }
.page-texte p,
.page-texte li        { font-size: 16px; }

/* ================= L'ESPACE MARIAGE =================

   Le simulateur ne montre aucun prix ligne à ligne — c'est une règle du projet
   et elle vaut doublement ici. Un montant en face de chaque poste transforme
   une liste d'envies en une addition qu'on cherche à réduire : on décoche les
   boutonnières, puis les cônes de pétales, et l'on se retrouve avec un mariage
   moins beau pour avoir économisé le prix d'un plat.

   La mise en page suit cette intention. Les cases sont larges et faciles à
   cocher, le total est loin, en bas, et il est donné en fourchette : ce qu'il
   est réellement — un ordre de grandeur avant un rendez-vous. */

.simulateur { margin: 30px 0 40px; border: 1px solid var(--ligne);
              background: #16161A; padding: 24px 22px 26px; }

.m-cadre { display: flex; gap: 22px; flex-wrap: wrap; margin-bottom: 22px; }
.m-nb { display: flex; flex-direction: column; gap: 7px; flex: 1 1 190px; }
.m-nb span { font-family: var(--jost); font-size: 13px; letter-spacing: .14em;
             text-transform: uppercase; color: var(--cendre); }
.m-nb input { border: 1px solid #6A6A78; background: #23232B; color: var(--ivoire);
              font-family: var(--ui); font-size: 16px; padding: 11px 13px;
              box-shadow: inset 0 2px 5px rgba(0,0,0,.45); }

/* Les deux niveaux : deux propositions, pas un curseur. Un curseur suggère un
   compromis à trouver ; deux cartes présentent deux façons de faire. */
.m-gamme { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 26px; }
.m-niveau { display: flex; flex-direction: column; gap: 5px; text-align: left;
            border: 1px solid var(--ligne); background: #1B1B20; color: var(--ivoire);
            padding: 14px 16px; cursor: pointer;
            transition: border-color .15s, background .15s; }
.m-niveau:hover { border-color: #6A6A78; background: #202027; }
.m-niveau.actif { border-color: var(--argent); background: #24242C;
                  box-shadow: inset 0 0 0 1px rgba(195,198,203,.25); }
.m-niveau-nom { font-family: var(--jost); font-size: 16px; letter-spacing: .2em;
                text-transform: uppercase; }
.m-niveau-det { font-size: 14px; line-height: 1.5; color: var(--cendre); }

.m-groupe { border: 0; border-top: 1px solid var(--ligne); margin: 0; padding: 20px 0 4px; }
.m-groupe legend { font-family: var(--jost); font-size: 14px; letter-spacing: .2em;
                   text-transform: uppercase; color: #C9C4B8; padding: 0 12px 0 0; }
.m-postes { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 22px; }

/* Toute la ligne est cliquable, pas seulement le carré : viser un carré de
   seize pixels au pouce est le genre de détail qui fait abandonner. */
.m-poste { display: flex; align-items: center; gap: 12px; min-height: 44px;
           padding: 6px 8px; cursor: pointer; }
.m-poste:hover { background: #1C1C21; }
.m-poste input[type="checkbox"] { width: 19px; height: 19px; flex: 0 0 auto;
                                  accent-color: #C3C6CB; cursor: pointer; }
.m-nom { flex: 1 1 auto; font-size: 15px; line-height: 1.45; }
.m-qte { width: 62px; flex: 0 0 auto; border: 1px solid #4C4C58; background: #23232B;
         color: var(--ivoire); font-family: var(--ui); font-size: 15px;
         padding: 7px 8px; text-align: center; }
.m-qte:disabled { opacity: .3; }

.m-total { margin-top: 26px; border-top: 1px solid var(--ligne); padding-top: 22px;
           display: flex; flex-direction: column; gap: 8px; text-align: center; }
.m-total-lbl { font-family: var(--jost); font-size: 13px; letter-spacing: .18em;
               text-transform: uppercase; color: var(--cendre); }
.m-total-val { font-family: var(--jost); font-size: clamp(24px, 2.4vw, 38px);
               font-weight: 300; letter-spacing: .06em; color: #6A6A78; }
.m-total-val.chiffre { color: var(--ivoire); }
.m-total-note { font-size: 14px; line-height: 1.6; color: var(--cendre); }

/* Le piège à robots. « display: none » se repère : plusieurs automates lisent
   la feuille de style avant de remplir. On le sort de l'écran. */
.miel { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* La galerie de realisations.

   Elle est la preuve de la page. Un couple ne redoute pas la depense, il
   redoute de se tromper de prestataire : ce sont les photos qui repondent, pas
   les phrases. D'ou des vignettes GENEREUSES — trois colonnes seulement sur
   grand ecran, une seule sur telephone — plutot que la mosaique de timbres
   qu'on voit partout, ou rien ne se distingue.

   `aspect-ratio` fixe le cadre avant que l'image n'arrive : sans lui la page
   sursaute a chaque chargement, et un saut de mise en page coute la lecture. */
/* Le registre des deux pages de mariage.

   POURQUOI DU DORE, ET POURQUOI PAS UN FOND IVOIRE. Olivier demandait s'il
   fallait quitter le fond sombre. Le vrai risque du sombre n'est pas la
   lisibilite — les photos de fleurs claires y gagnent au contraire du
   contraste — c'est le REGISTRE : une maison qui vend aussi des compositions
   de deuil ne peut pas laisser sa page mariage sonner funebre.

   Changer le fond d'une seule page coute cher : un couple qui vient d'une fiche
   produit croit avoir change de site, et il faut tenir deux themes en huit
   langues. L'ecart de registre se joue moins sur le fond que sur l'ACCENT.
   L'argent est formel ; le dore est celebratoire. On garde donc la nuit, et on
   passe les intertitres et les filets au dore.

   Ce n'est pas un effet mesure : le trafic mariage ne permet aucun test. C'est
   un choix de registre, assume comme tel, et reversible en une ligne. */
.page-mariage .contenu h2,
.page-estimation-budget-mariage .contenu h2 { color: var(--rose); }
.page-mariage .contenu h2::after,
.page-estimation-budget-mariage .contenu h2::after {
  content: ""; display: block; width: 46px; height: 1px; margin-top: 10px;
  background: linear-gradient(90deg, var(--rose) 0%, transparent 100%);
}

/* LA COMPARAISON DES ROSES.

   Deux photos cote a cote sur grand ecran, l'une sous l'autre sur telephone —
   jamais reduites en vignettes : c'est la DIFFERENCE DE TAILLE qu'on doit voir,
   et on ne la voit pas sur un timbre. Pas de recadrage non plus : « object-fit:
   cover » couperait justement la tige longue qui fait l'argument. */
.r-comparaison { display: grid; grid-template-columns: repeat(2, 1fr);
                 gap: 14px; margin: 20px 0 6px; }
.r-vue { margin: 0; }
.r-vue img { width: 100%; height: auto; display: block; border-radius: 2px; }
@media (max-width: 620px) {
  .r-comparaison { grid-template-columns: 1fr; gap: 16px; }
}

/* La photo d'ouverture. « aspect-ratio » fixe le cadre AVANT que l'image
   n'arrive : sans lui la page sursaute au chargement, et un saut de mise en
   page coute la lecture. Le rapport se resserre sur telephone — 16/9 y
   donnerait une bande, 4/3 une image. */
.m-ouverture { margin: 0 0 26px; }
.m-ouverture img { width: 100%; height: auto; aspect-ratio: 16 / 9;
                   object-fit: cover; display: block; background: #1a1a1d; }
@media (max-width: 620px) {
  .m-ouverture { margin-bottom: 20px; }
  .m-ouverture img { aspect-ratio: 4 / 3; }
}

/* LE CARROUSEL DES REALISATIONS.

   Il defile en CSS seul : « scroll-snap » cale chaque photo en place, et le
   doigt, la molette et le clavier suffisent. Le JavaScript n'ajoute que les
   fleches et les pastilles — si rien ne s'execute, la bande reste parcourable.
   La fonction en CSS, le confort en JS.

   ON MONTRE UNE PHOTO ET DEMIE, jamais une seule. Une image qui remplit
   exactement la largeur ne dit pas qu'il y en a d'autres derriere, et
   personne ne fait glisser ce qu'il ne soupconne pas. Le bord de la suivante
   est l'affordance ; les pastilles ne font que la confirmer. */
.m-carrousel { position: relative; margin: 26px 0 34px; }

.m-piste {
  display: flex; gap: 12px;
  overflow-x: auto; scroll-snap-type: x mandatory;
  /* PAS DE « scroll-behavior: smooth » ICI. Pose sur le conteneur, il rend le
     defilement programme inoperant dans plusieurs contextes — verifie : avec
     lui, « piste.scrollLeft = 300 » ne bouge pas ; sans lui, la valeur passe a
     231, l'ancrage ayant fait son travail. Le glissement doux appartient au
     script, qui le demande a chaque appel et sait le retirer quand le systeme
     annonce preferer moins d'animation. */
  scrollbar-width: none;
  padding-bottom: 2px;
}
.m-piste::-webkit-scrollbar { display: none; }

/* DES VIGNETTES, PAS DES TABLEAUX. Olivier : « ne les affiche pas en gros,
   c'est anecdotique ». Il a raison sur la hierarchie : la photo d'ouverture
   porte la promesse, ces douze-la ne font que la documenter. Servies en grand
   elles prenaient le pas sur le texte, qui est ce qui vend.

   Cinq par ecran sur un bureau, trois sur une tablette, deux et demie sur un
   telephone — la demie reste, c'est elle qui dit qu'il y en a d'autres. */
.m-vue { margin: 0; flex: 0 0 calc((100% - 48px) / 5); scroll-snap-align: start; }
.m-vue img { width: 100%; height: auto; aspect-ratio: 3 / 4;
             object-fit: cover; display: block; background: #1a1a1d; }

/* Les fleches ne servent qu'a la souris : sur un ecran tactile on fait
   glisser, et deux boutons poses sur les photos les mangeraient. */
.m-fleche {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(198, 202, 208, .3);
  background: rgba(16, 16, 18, .82); color: var(--ivoire);
  font-size: 22px; line-height: 1; display: none;
  align-items: center; justify-content: center;
  transition: background .15s, border-color .15s;
}
.m-fleche:hover { background: rgba(16, 16, 18, .95); border-color: var(--rose); }
.m-fleche[disabled] { opacity: .3; cursor: default; }
.m-gauche { left: -18px; }
.m-droite { right: -18px; }
@media (hover: hover) and (min-width: 900px) { .m-fleche { display: flex; } }

.m-points { display: flex; justify-content: center; gap: 7px; margin-top: 14px; }
.m-points span {
  width: 6px; height: 6px; border-radius: 50%;
  background: rgba(198, 202, 208, .28); transition: background .2s, width .2s;
}
.m-points span.actif { background: var(--rose); width: 18px; border-radius: 3px; }

@media (max-width: 900px) { .m-vue { flex: 0 0 calc((100% - 24px) / 3); } }
@media (max-width: 560px) { .m-vue { flex: 0 0 40%; }
                            .m-vue img { aspect-ratio: 4 / 5; } }

/* LA BANDE DES EVENEMENTS COMPTE QUATRE VIGNETTES, PAS CINQ.

   La page mariage en aligne treize : la cinquieme est coupee par le bord, et
   c'est cette coupe qui dit qu'il y en a d'autres derriere. Les evenements
   n'en ont que cinq, dont la premiere s'affiche en grand — il en reste quatre.
   Calibrees pour cinq, elles laisseraient un vide a droite, qui se lit comme
   une image manquante et non comme une reserve.

   Quatre par ecran de bureau, deux sur telephone. */
.e-galerie .m-vue { flex: 0 0 calc((100% - 36px) / 4); }
@media (max-width: 900px) { .e-galerie .m-vue { flex: 0 0 calc((100% - 12px) / 2); } }
@media (max-width: 560px) { .e-galerie .m-vue { flex: 0 0 calc((100% - 12px) / 2); } }

.form-mariage { margin: 24px 0 10px; }
.m-champs { display: flex; flex-direction: column; gap: 4px; margin-bottom: 22px; }
.m-champs .opt-nom { margin-top: 16px; }
/* Le bouton d'envoi reprend l'apparence du bouton d'achat, explicitement.
   Il l'heritait, et il est arrive transparent avec un texte sombre : invisible
   sur une page noire — le defaut exact qu'on venait de corriger sur la
   boutique. Un bouton ne doit jamais dependre d'un heritage pour se voir. */
/* LE BOUTON EST CENTRE DANS LE FORMULAIRE.
   Olivier, le 5 septembre 2026 : « centre le bouton confier mon projet ».
   Mesure a 1440 px : le bouton occupait 373 a 793, le formulaire 373 a 1053 —
   cale a gauche, decale de 130 px du centre. Il est borne a 420 px de large
   quand le formulaire en fait 680 : la largeur maximale etait posee, la marge
   qui la centre ne l'etait pas.
   « margin-inline: auto » demande une boite de niveau bloc ; « inline-flex »
   ne se centre pas ainsi. On passe donc en « flex », ce qui ne change rien a
   l'interieur du bouton — les deux disposent leurs enfants de la meme facon. */
.form-mariage .ajouter {
    width: 100%; max-width: 420px; margin-inline: auto;
    display: flex; align-items: center; justify-content: center;
    min-height: 62px; padding: 0 34px; border: 0; border-radius: 3px;
    cursor: pointer;
    background: linear-gradient(180deg, #FFFDF8 0%, var(--ivoire) 55%, #DAD4C7 100%);
    color: var(--nuit); font-family: var(--ui); font-size: 15px; font-weight: 600;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.9), 0 3px 0 #A8A294,
                0 10px 24px rgba(0,0,0,.5);
}
.form-mariage .ajouter:hover {
    background: linear-gradient(180deg, #FFFFFF 0%, #F5F1E7 55%, #E2DCCF 100%);
}
.m-suite { font-size: 14px; line-height: 1.6; color: var(--cendre); margin-top: 14px; }

/* LE MESSAGE DE SUCCES SE VOIT, MAINTENANT.
   Olivier, le 5 septembre 2026 : « met le message de succès d'envoi de mail en
   plus visible (vert plus clair. Attention à la police qui doit rester
   visible) ».
   Il etait en vert tres sombre — #1E2420 — sur une page deja sombre : la seule
   chose qui le signalait etait un filet argent. Un message qu'on doit chercher
   ne confirme rien, et le visiteur renvoie sa demande.
   Le fond passe donc au vert clair et LE TEXTE AU VERT PRESQUE NOIR. C'est la
   seconde moitie de la consigne, et elle n'est pas facultative : eclaircir le
   fond en gardant l'ivoire aurait donne 1,2:1, exactement le defaut du bloc de
   consentement trouve hier. Mesure : #16301C sur #DCEFDC = 12,6:1.
   La variante d'echec, elle, reste sombre — voir plus bas. */
/* « p.m-reponse » ET « .page-texte p.m-reponse », et ce n'est pas de la
   ceinture-bretelles. Premiere pose : le fond est passe au vert clair et le
   TEXTE EST RESTE BEIGE — 1,7:1, illisible. « .page-texte p » vaut (0,2,0) et
   l'emportait sur « .m-reponse » a (0,1,0). C'est le meme piege que le bloc de
   consentement d'hier, et je venais de l'ecrire trois lignes plus haut.
   MESURE APRES CORRECTION : #16301C sur #DCEFDC, 12,6:1. */
p.m-reponse,
.page-texte p.m-reponse {
  border: 1px solid #6FA37E; background: #DCEFDC; color: #16301C;
  padding: 18px 20px; margin: 0 0 24px;
  font-size: 17px; line-height: 1.6; font-weight: 400;
}
/* Le filet ne suffisait pas a le faire remarquer : on lui donne du poids par
   le fond, pas par une animation. Un bandeau qui clignote sur une page de
   deuil serait indecent, et ce meme bloc sert les trois formulaires. */
.m-reponse strong, .m-reponse b { color: #0E220F; }

/* L'ECHEC RESTE SOMBRE, ET C'EST VOULU.
   Olivier n'a demande que le succes. Mais si les deux blocs devenaient clairs,
   ils se ressembleraient — or l'un dit « c'est parti » et l'autre « il manque
   quelque chose ». La difference doit se voir avant d'etre lue.
   Mesure du contraste conserve : ivoire #EAE5DA sur #241C1C, 12,1:1. */
p.m-reponse.rate,
.page-texte p.m-reponse.rate {
  background: #241C1C; border-color: #8A5A5A; color: var(--ivoire);
  font-size: 16px;
}

@media (max-width: 620px) {
  .simulateur { padding: 18px 14px 20px; margin: 22px -6px 32px; }
  .m-postes { grid-template-columns: 1fr; }
  .m-gamme { grid-template-columns: 1fr; }
}

/* La ligne dédiée aux mariages, dans le corps de la page — le 09, pas le 07 de
   l'en-tête. Un couple qui appelle depuis cette page tombe sur la bonne ligne,
   et l'origine de l'appel se lit sans avoir à la demander. */
.m-appel { border-left: 2px solid var(--argent); padding: 12px 16px;
           background: #16161A; margin: 18px 0 0; font-size: 16px; }
.m-appel a { font-family: var(--jost); font-size: 19px; letter-spacing: .06em;
             color: var(--ivoire); text-decoration: none; border-bottom: 1px solid var(--argent); }

/* Les pièces Oscendence : une liste, pas une grille de vignettes.
   La gamme compte cinq pièces. Une grille de photos les mettrait en
   concurrence les unes avec les autres et ramènerait le regard sur le prix ;
   une liste laisse chacune se lire pour ce qu'elle est. */
.osc-pieces { list-style: none; margin: 18px 0 0; padding: 0; }
.osc-pieces li { border-top: 1px solid var(--ligne); padding: 16px 0;
                 font-size: 16px; line-height: 1.6; color: var(--cendre); }
.osc-pieces li:last-child { border-bottom: 1px solid var(--ligne); }
.osc-pieces a { color: var(--ivoire); text-decoration: none; }
.osc-pieces a strong { font-family: var(--jost); font-size: 18px;
                       font-weight: 400; letter-spacing: .04em;
                       border-bottom: 1px solid var(--argent); padding-bottom: 2px; }
.osc-pieces a:hover strong { border-bottom-color: var(--ivoire); }

/* ---------- ce que ça fait : deux lignes sous le titre ----------
   Posées entre le nom du produit et la photo. Mesuré sur un écran de
   375 × 812 : le titre est à 427 px, la photo occupe ensuite trois cents
   pixels, et le prix ne paraît qu'à 1 400. C'est donc le seul endroit où
   ces deux lignes seront lues sans faire défiler.

   Elles ne crient pas : c'est le titre qui porte, elles accompagnent. D'où
   le corps plus petit que le texte courant et la couleur en retrait — un
   ton au-dessus du gris de service, un ton en dessous de l'ivoire. */
.sensation { display: flex; flex-direction: column; gap: 3px;
             margin: 10px 0 0; padding-left: 13px;
             border-left: 1px solid var(--ligne-2); }
.sensation span { font-family: var(--jost); font-size: 15px; line-height: 1.45;
                  font-weight: 300; letter-spacing: .012em; }
/* Celui qui envoie parle en premier : c'est lui qui lit la page. */
.s-envoi { color: var(--ivoire); }
.s-recu  { color: #A9A399; }
@media (max-width: 620px) {
  .sensation { margin-top: 9px; padding-left: 11px; }
  .sensation span { font-size: 14px; }
}

/* ==========================================================================
   Reprise mobile — 1er septembre 2026, sur relevé d'Olivier sur son Android
   ========================================================================== */

@media (max-width: 620px) {

  /* 1. LE BANDEAU DE SERVICE ÉTAIT DÉCENTRÉ.
     Il portait « padding: 10px 74px 10px 20px » : cinquante-quatre pixels de
     plus à droite qu'à gauche, donc tout son contenu poussé vers la gauche.
     Ces 74 px dégageaient le coin où la bulle d'assistance se posait — mais
     sur téléphone la bulle est passée en bas depuis. La réserve est restée,
     la raison d'être avait disparu.

     « .produit .service » EST NOMMÉE ICI AUSSI, et c'est tout le sujet du
     6 septembre : elle vaut (0,2,0) et l'emportait sur « .service » seul,
     si bien que la correction ci-dessous ne touchait pas les fiches produits
     — les seules pages où Olivier l'a vu. Une correction qui ne s'applique
     pas partout où le défaut existe laisse croire qu'elle a servi.

     QUATORZE ET NON VINGT : c'est le retrait des deux rangées du dessous, le
     menu et les outils. Mesuré : burger à 14, sélecteur de langue à 14. Un
     bandeau à 20 px se voit rentré de six pixels par rapport à ce qu'il
     surmonte — assez peu pour qu'on ne sache pas nommer ce qui cloche, assez
     pour qu'on le sente. */
  .service,
  .produit .service { padding-left: 14px; padding-right: 14px; }

  /* 3. PANIER, TÉLÉPHONE ET LANGUE TENAIENT SUR DEUX LIGNES, ET DE TRAVERS.
     La rangée faisait 88 px de haut : le téléphone seul sur la première, le
     panier collé à gauche et la langue collée à droite sur la seconde. On la
     force sur une seule ligne, centrée, en resserrant ce qui peut l'être. */
  .outils { flex-wrap: nowrap; justify-content: center; gap: 10px;
            padding: 0 8px 12px; }
  .outils-centre { gap: 9px; flex-wrap: nowrap; }
  .tel-entete { font-size: 13px; white-space: nowrap; letter-spacing: 0; }
  .panier { padding: 7px 10px; }
  .langue-actuelle { padding: 6px 0; }

  /* 4. LE MENU SUR DEUX LIGNES NE SE LISAIT PAS COMME UN MENU.
     Sept mots posés à plat sur deux rangées ressemblent à une phrase coupée.
     Chacun prend donc son cadre : un filet léger, pas un bouton plein — le
     plein appartient au bouton d'achat, et deux niveaux de plein sur le même
     écran se disputent le regard. La ligne se centre au lieu de défiler :
     un menu qui défile cache la moitié de ses entrées. */
  .entete .nav { overflow-x: visible; justify-content: center; flex-wrap: wrap;
                 gap: 8px; padding: 12px 14px 14px; }
  .entete .nav a { border: 1px solid var(--ligne-2); border-radius: 2px;
                   padding: 8px 13px; min-height: 0; font-size: 13px;
                   letter-spacing: .06em; line-height: 1.1; }
  .entete .nav a:hover, .entete .nav a:focus-visible { border-color: var(--argent); }

  /* 6. LE PIED DE PAGE RESPIRAIT TROP.
     Chaque lien portait 40 px de hauteur minimale — la règle de cible tactile,
     juste dans son principe — plus l'espacement de la colonne. Les rubriques
     se retrouvaient à plus de soixante pixels l'une de l'autre et la liste
     perdait sa cohérence. On garde une cible confortable (36 px, au-dessus du
     doigt moyen) et on rend l'espacement à la colonne. */
  .pied .col a { min-height: 36px; }
  .pied .col { gap: 0; }
  .pied { gap: 22px 18px; }
}

@media (max-width: 430px) {

  /* 2. « FLEURISTE HAUT DE GAMME » PASSAIT SUR DEUX LIGNES.
     Le calcul : vingt-trois caractères à 16 px avec .26em d'interlettrage font
     environ 324 px, pour 311 px disponibles une fois les marges retirées. Il
     manquait treize pixels. On les reprend sur l'interlettrage plutôt que sur
     le corps : c'est l'espacement qui donne le ton, mais c'est le corps qui
     donne la lisibilité, et l'un se resserre sans que l'autre souffre. */
  .titre-page h1 { font-size: 15px; letter-spacing: .15em; padding-left: .15em;
                   white-space: nowrap; }
}

/* ==========================================================================
   La fiche produit sur téléphone — reprise du 1er septembre 2026
   ========================================================================== */

@media (max-width: 620px) {

  /* L'ORDRE. Deux blocs n'avaient pas de rang et remontaient donc tout en
     haut, avant même le fil d'Ariane : les deux lignes de sensation, et la
     mention technique en italique. Un enfant de conteneur flexible sans
     « order » vaut zéro, et zéro passe avant un.

     Résultat à l'écran : le client tombait sur « photos non contractuelles,
     mises en scène en studio, vases vendus séparément » avant d'avoir vu le
     nom du produit. La première chose qu'on lui disait était une réserve.

     L'ordre demandé par Olivier, et celui-ci le tient : la photo et le titre,
     puis ce que ça fait, puis les options, puis la description, et la mention
     technique en dernier — elle est utile, elle n'est pas accueillante. */
  .produit .module > .fil        { order: 1; }
  .produit .module > .badge      { order: 2; }
  .produit .module > h1          { order: 3; }
  .produit .visuel-p             { order: 4; }
  .produit .module > .sensation  { order: 5; margin: 14px 0 4px; }
  .produit .module > .opt,
  .produit .module > .options    { order: 6; }
  .produit .module > .proportion { order: 7; }
  .produit .module > .alerte     { order: 8; }
  .produit .module > .ajouter    { order: 9; }
  .produit .module > .sous-bouton { order: 10; }
  .produit .module > .texte-p    { order: 11; }
  /* Sans classe dans le gabarit, la mention se désigne par sa balise. */
  .produit .module > em,
  .produit .module > .mention    { order: 12; margin-top: 20px; }

  /* CENTRÉ, ET NON ALIGNÉ À DROITE.
     Le fil d'Ariane, le badge et le titre se centrent sur la photo qu'ils
     surmontent : sur un écran étroit, une colonne unique centrée se lit d'un
     seul mouvement d'œil. Les deux lignes de sensation suivent, mais gardent
     leur filet à gauche — c'est lui qui les distingue du titre. */
  .produit .module > .fil,
  .produit .module > .badge,
  .produit .module > h1 { text-align: center; }
  .produit .module > .badge { align-self: center; }
  .produit .module > .sensation { text-align: center; border-left: 0;
                                  padding-left: 0; align-items: center; }

  /* « COMPOSEZ VOTRE BOUQUET » ÉTAIT INVISIBLE.
     Onze pixels de haut, en gris de service : le titre de la seule section où
     le client agit se lisait moins bien que la mention légale. Il devient ce
     qu'il est — l'invitation à choisir. */
  .options > .lbl { font-family: var(--jost); font-size: 13px; font-weight: 400;
                    letter-spacing: .18em; text-transform: uppercase;
                    color: var(--ivoire); text-align: center;
                    padding: 4px 0 12px; border-top: 1px solid var(--ligne-2);
                    margin-top: 6px; }

  /* LE SUPPLÉMENT DU VASE PASSAIT À LA LIGNE, séparant le nombre de son
     symbole : « + 90 » sur une ligne, « € » sur la suivante. Un montant ne se
     coupe jamais. */
  .opt .choix-sup, .opt .sup, .options .sup, .options .choix-sup {
    white-space: nowrap; }

  /* LE BANDEAU D'ACHAT ET LE MÉDAILLON DE CONSENTEMENT SE SUPERPOSAIENT.
     Axeptio pose son bouton en bas à gauche, exactement là où le bandeau
     affiche le prix : le montant devenait illisible. Comme pour la bulle
     d'assistance, c'est le médaillon qui monte — le prix, lui, n'a pas
     d'autre place.

     Plusieurs sélecteurs : Axeptio a changé de nommage au fil de ses
     versions, et viser large ne coûte rien quand aucun des candidats
     n'existe. */
  body.avec-barre-achat #axeptio_main_button,
  body.avec-barre-achat #axeptio_btn,
  body.avec-barre-achat .axeptio_mount,
  body.avec-barre-achat #axeptio_overlay > button,
  body.avec-barre-achat [class*="axeptio"][class*="button"] {
    bottom: 84px !important; transition: bottom .18s ease-out; }
}

/* ==========================================================================
   Ce qui se superposait, et ce qui faisait doublon — 1er septembre 2026
   ========================================================================== */

/* LA BULLE MESSENGER DE FACEBOOK RECOUVRAIT « CHOISIR ET COMMANDER ».
   Elle se pose en bas à droite, en position fixe, au-dessus de tout — et le
   bouton d'achat est au même endroit dès que le bandeau collant paraît. Une
   bulle de discussion qui masque le bouton d'achat coûte des commandes, pas
   des conversations.

   Elle est masquée ici, sur toutes les pages. **Ce n'est qu'un cache** : le
   script continue de se charger et de suivre le visiteur. Le vrai retrait se
   fait dans les réglages de la boutique, et il est inscrit dans
   ECWID-A-MODIFIER.md — Olivier l'avait déjà demandé. */
.fb_dialog, .fb_dialog_content, .fb-customerchat,
#fb-root > div[class*="fb_dialog"] { display: none !important; }

/* FAVORIS ET PANIER, EN DOUBLON.
   Ecwid affiche ses propres liens « Favoris » et « Panier (2) » en doré au
   milieu de la page. Le premier ne sert à personne — mesuré nulle part, mais
   Olivier est catégorique et c'est son catalogue. Le second répète le panier
   de l'en-tête, qui est visible en permanence alors que celui-là ne l'est que
   si l'on descend jusqu'à lui.

   Deux liens qui mènent au même endroit, dont un plus haut et toujours là :
   celui du bas ne fait qu'ajouter une décision. */
.ec-cart-widget, .ec-wishlist-widget,
.ec-store__cart-widget, [class*="ec-"][class*="wishlist"] { display: none !important; }

/* LE PANIER DE L'EN-TÊTE PREND LA PLACE QU'ILS LAISSENT.
   Il devient la seule voie vers le panier : il doit se voir. Quatorze pixels
   d'icône dans un cadre étroit se lisaient comme un ornement ; à vingt, dans
   un cadre qui respire, c'est un bouton. */
.panier svg { width: 20px; height: 20px; }
@media (max-width: 620px) {
  .panier { padding: 9px 13px; }
  .panier svg { width: 22px; height: 22px; }
}

/* ==========================================================================
   Le tunnel Ecwid — allègement du 1er septembre 2026
   --------------------------------------------------------------------------
   Ces règles portent sur du balisage qu'Ecwid injecte dans notre page. Sa
   feuille est portée par « html#ecwid_html body#ecwid_body », d'une
   spécificité que rien d'écrit ici ne peut atteindre : « !important » n'est
   pas une facilité, c'est le seul moyen. Les classes ont été relevées dans sa
   feuille servie, pas devinées.
   ========================================================================== */

/* « PAGES SUIVANTES… » — LES TITRES SUFFISENT.
   Chaque étape à venir portait son titre et une phrase d'explication :
   « Informations d'expédition / Précisez vos coordonnées pour choisir un mode
   d'expédition. » Le titre le dit déjà, et la phrase le redit plus longuement.

   Sur un téléphone, ce bloc occupait la moitié d'un écran pour annoncer des
   pages qu'on n'a pas encore atteintes — pendant que le bouton qui y mène est
   remonté hors de vue. On garde les titres, qui rassurent sur ce qui reste à
   faire ; on retire les phrases, qui n'ajoutent rien. */
.ec-cart-next .ec-cart-step__text,
.ec-cart-next .ec-cart-step__subtitle,
.ec-cart-next__step .ec-cart-step__section--description { display: none !important; }
.ec-cart-next__step { margin-bottom: 6px !important; }

/* LE COUPON — MA CORRECTION L'AVAIT CASSÉ, ELLE EST RETIRÉE.
   J'avais masqué « .ec-cart-coupon__text » en croyant supprimer un libellé
   redondant. Le résultat, relevé par Olivier : deux fois « Appliquer un coupon
   promotionnel », et **plus moyen de cliquer ni de saisir un code**.

   Une gêne de lecture réparée par une panne de fonction, c'est un mauvais
   échange, et sur un tunnel de commande c'est le pire de tous. La règle est
   retirée : Ecwid reprend son comportement d'origine.

   Le vrai remède n'est pas ici. Le libellé du coupon se change dans les
   réglages de langue de la boutique, là où Ecwid le lit — pas depuis une
   feuille de style extérieure qui ne peut que cacher, jamais renommer. Inscrit
   dans ECWID-A-MODIFIER.md. */

/* ==========================================================================
   Trois reprises, mesurées — 1er septembre 2026, seconde passe
   ========================================================================== */

@media (max-width: 620px) {

  /* LA RANGÉE D'OUTILS ÉTAIT UNE GRILLE, PAS UN FLEX.
     La correction précédente posait « flex-wrap: nowrap » sur un conteneur en
     « display: grid » : la propriété n'y veut rien dire, et la grille
     continuait de renvoyer le panier et la langue sous le téléphone.

     Le sujet n'était donc pas le retour à la ligne, c'était le mode de
     disposition — corriger l'un sans regarder l'autre ne pouvait rien donner.

     Les trois éléments mesurent 270 px en tout pour 343 disponibles : ils
     tiennent largement, il suffit de le leur permettre. */
  .outils { display: flex !important; flex-wrap: nowrap; align-items: center;
            justify-content: center; gap: 12px; }
  .outils-centre { flex: 0 1 auto; }

  /* « FLEURISTE HAUT DE GAMME » ÉTAIT DEVENU ILLISIBLE.
     Quinze pixels tenaient sur une ligne, mais n'occupaient que 235 px des 343
     disponibles : j'avais réduit bien au-delà du nécessaire. On reprend les
     cent pixels laissés vides — le texte remplit sa ligne au lieu de la
     subir. */
  .titre-page h1 { font-size: 19px; letter-spacing: .17em; padding-left: .17em;
                   white-space: nowrap; }

  /* LE BANDEAU DE SERVICE, RÉPARTI PLUTÔT QU'ÉTALÉ.
     « space-evenly » posait des intervalles égaux entre trois éléments de
     longueurs inégales, et les deux lignes flottaient au hasard de leur
     contenu. La livraison garde toute la première ligne, centrée ; la zone et
     l'avis Google se calent chacun sur son bord — deux ancrages fixes valent
     mieux qu'une répartition qui bouge avec le texte. */
  .service { justify-content: space-between; column-gap: 12px; }
  .service > span:first-child { flex: 1 0 100%; text-align: center; }
  .service > span:not(:first-child):not(.sep) { flex: 0 0 auto; }
  .service .avis { margin-left: auto; }
}

@media (max-width: 430px) {
  /* La règle des 430 px reprend la main sur celle des 620 : elle doit porter
     la même valeur, sans quoi le titre redeviendrait minuscule sur les écrans
     les plus étroits — ceux, précisément, où il est déjà le plus serré. */
  .titre-page h1 { font-size: 18px; letter-spacing: .15em; padding-left: .15em; }
}

/* ==========================================================================
   Le menu — de l'écart et de la matière, 1er septembre 2026
   --------------------------------------------------------------------------
   Deux défauts mesurés : huit pixels entre deux entrées, et trente-deux
   pixels de haut. Le second compte autant que le premier — les
   recommandations d'accessibilité posent quarante-quatre pixels comme cible
   tactile confortable, et un menu qu'on manque une fois sur cinq est un menu
   qu'on cesse d'utiliser.

   La matière, ensuite. Un simple filet gris se lit comme un tableau ; ce qu'on
   veut, c'est un objet qu'on touche. D'où un dégradé — mais **de l'argent, et
   très peu** : l'or est réservé à Oscendence, et un menu qui brille se
   disputerait le regard avec le bouton d'achat, qui est le seul endroit du
   site où l'on veut vraiment appuyer.

   Le relief tient en trois traits presque invisibles : un fond qui s'éclaircit
   d'un souffle vers le haut, un liseré clair sur l'arête supérieure, et une
   ombre portée courte. Séparément on ne les voit pas ; ensemble ils suffisent.
   ========================================================================== */

@media (max-width: 620px) {
  /* TOUTE LA LARGEUR, VRAIMENT. Il restait 14 px de marge de chaque cote
     et 10 px entre chaque bouton : 76 px perdus sur les 375 d'un
     telephone, soit un sixieme de la ligne. A 4 px de marge et 3 px
     d'intervalle, chaque rayon gagne 15 px de large — et le libelle
     respire au lieu de fleurter avec son bord. */
  /* DEUX PIXELS DE MARGE, ET LA RAISON VAUT D'ETRE ECRITE. Les trois
     pastilles sortaient a 112 px chacune, soit 336 px pour 335 disponibles :
     UN pixel de trop, et « Evenements » tombait seule sur une quatrieme
     ligne. Le chiffre 112 ne bougeait pas quand je changeais la police —
     c'est qu'il ne venait pas du contenu mais de l'arrondi du calcul flex.
     Chercher la bonne taille de texte etait donc perdu d'avance. */
  .entete .nav { gap: 3px; padding: 10px 2px 14px; }

  .entete .nav a {
    /* Assez petit pour que les CINQ rayons tiennent sur une seule ligne a
       375 px — c'est ce qui les fait lire comme un groupe — et assez grand
       pour rester confortable. Mesure : 12 px sans interlettrage, cinq
       libelles et quatre intervalles occupent 291 px des 355 disponibles. */
    padding: 9px 6px; font-size: 12px; letter-spacing: 0; min-height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid rgba(198, 202, 208, .22);
    border-radius: 3px;
    /* Olivier : « la ils sont noir sur noir, je trouve ca fade ». Il avait
       raison — le degradé precedent valait moins de 8 % d'opacite sur du noir,
       soit un ecart de luminance que l'oeil ne separe pas du fond. Un gris
       franc, pose et non calcule, donne des touches qu'on voit sans qu'elles
       crient : #23232A contre le #101012 du fond. */
    background: linear-gradient(180deg, #26262E 0%, #1E1E24 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .085),
                0 1px 2px rgba(0, 0, 0, .35);
    transition: background .16s ease-out, border-color .16s ease-out;
  }

  /* Les deux pastilles, en dernier et dans CE bloc.

     « .entete .nav a » ci-dessus vaut (0,2,1) — exactement comme « .nav a.osc »
     posee mille neuf cents lignes plus haut. A specificite egale, la derniere
     ecrite l'emporte : le relief argente recouvrait donc le dore et le rose,
     et sous 620 px les deux pastilles redevenaient des entrees ordinaires.
     C'est la ou Olivier regarde. On les repose ici, apres.

     Elles gardent le relief du bloc — c'est lui qui fait « objet qu'on
     touche » — mais leur liseré passe au transparent : un cadre gris autour
     d'un fond dore le salit. */
  .entete .nav a.osc, .entete .nav a.mar, .entete .nav a.eve {
    color: var(--nuit); border-color: transparent;
    /* Trois pastilles sur une ligne de 335 px : chaque pixel de rembourrage
       compte. A 20 px de cotes elles faisaient 341 et la troisieme tombait
       seule en dessous. */
    /* Elles ne s'etirent pas comme les rayons : deux pastilles bord a bord
       feraient deux pavés. Elles gardent leur largeur propre, et la meme
       hauteur que la ligne du dessus. */
    /* QUATRIEME FOIS QUE CE BLOC RECOUVRE UNE REGLE POSEE PLUS HAUT. Il
       porte « .entete .nav a » — (0,2,1), exactement comme « .nav a.osc » —
       et il arrive en fin de fichier : a specificite egale, le dernier ecrit
       gagne. Sa consigne « min-width: 0 », donnee aux rayons pour qu'ils se
       partagent la ligne, annulait la largeur commune des deux pastilles.
       Toute regle qui vise une entree du menu doit donc etre posee ICI. */
    /* « min-width: 112px » etait ecrit ici en dur, pour donner une largeur
       commune aux DEUX pastilles d'alors. A trois, 112 x 3 = 336 px pour 339
       disponibles une fois les intervalles comptes : « Evenements » tombait
       seule sur une quatrieme ligne. Et comme la contrainte etait un nombre
       fixe, aucun changement de police ne la bougeait — j'ai cherche du cote
       du texte pendant trois essais avant de la trouver.
       Elles se partagent maintenant la ligne en trois, comme les cinq rayons
       du dessus se la partagent en cinq. */
    flex: 1 1 0; padding: 4px 7px; min-width: 0;
    max-width: calc(33.33% - 2px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .38),
                0 1px 3px rgba(0, 0, 0, .42);
  }
  /* Les 11 px imposes ci-dessus aux rayons ne valent pas pour elles : elles
     ont leur ligne, et ces deux familles ont besoin de corps. */
  .entete .nav a.osc { font-size: 13px; letter-spacing: .05em; }
  .entete .nav a.mar { font-size: 16px; }
  .entete .nav a.eve { font-size: 13px; letter-spacing: .02em; }
  /* CINQUIEME FOIS QUE CE BLOC RECOUVRE UNE REGLE POSEE PLUS HAUT, et la
     derniere : toute regle qui vise une entree du menu s'ecrit ICI.

     L'arbitrage d'Olivier : le dore reste a Oscendence, le vert d'eau des
     evenements disparait — « ca jure », et c'est exact, un vert et un dore se
     disputent au lieu de s'accorder. Mariage et Evenements passent a l'ivoire
     inverse, et Mariage seul recoit une brindille de chaque cote : deux
     pastilles claires cote a cote se confondraient, l'ornement les separe
     sans ajouter une couleur de plus. */
  .entete .nav a.osc:active { background: var(--or); border-color: transparent; }
  .entete .nav a.mar:active { background: var(--rose); border-color: transparent; }

  /* Au doigt, la pression doit se voir : la lueur s'inverse, comme un objet
     qu'on enfonce. « :active » plutôt que « :hover », qui n'existe pas ici. */
  .entete .nav a:active {
    background: linear-gradient(180deg, #17171C 0%, #24242B 100%);
    border-color: rgba(198, 202, 208, .34);
  }

  /* Oscendence garde sa couleur propre : c'est la seconde marque, elle ne se
     fond pas dans le menu de la première. */
  .entete .nav a.osc { border-color: rgba(198, 202, 208, .30); }
}

/* ==========================================================================
   Les trois outils, à trois places fixes — 1er septembre 2026
   --------------------------------------------------------------------------
   Regroupés au centre, ils se touchaient : trois cibles tactiles côte à côte
   au milieu d'un écran, dont deux mènent ailleurs. Et le téléphone, qui est le
   seul des trois à devoir se voir tout de suite, n'était pas centré sur la
   page — il était centré dans un groupe, ce qui n'est pas la même chose.

   Une grille à trois colonnes règle les deux à la fois : les colonnes
   extérieures se partagent également ce qui reste, donc **la colonne du milieu
   tombe au centre exact de l'écran**, quelles que soient les largeurs du
   panier et du sélecteur. Le flex ne sait pas faire cela — il centre le
   groupe, pas l'élément.
   ========================================================================== */

@media (max-width: 620px) {
  .outils { display: grid !important; grid-template-columns: 1fr auto 1fr;
            align-items: center; column-gap: 10px;
            padding: 2px 4px 12px; }
  .outils > .panier { justify-self: start; }
  .outils > .outils-centre { justify-self: center; }
  .outils > .langue { justify-self: end; }
}

/* ==========================================================================
   Le bandeau de service sur une seule ligne — 1er septembre 2026
   --------------------------------------------------------------------------
   Olivier demandait s'il fallait retirer la ligne « livraison le jour même »
   pour gagner de la hauteur. **C'est l'autre qu'il faut retirer**, et voici
   pourquoi.

   Les trois informations ne tiennent pas sur une ligne à onze pixels : il faut
   en sacrifier une. La livraison le jour même est le seul argument d'achat des
   trois — c'est ce qui décide quelqu'un qui a besoin de fleurs aujourd'hui, et
   c'est la crainte qu'il faut lever chez un client qui achète pour autrui :
   arriver trop tard. La note Google est la preuve, elle reste.

   « France et Monaco, 7 j/7 » disparaît d'ici seulement : la zone est répétée
   dans le menu, dans le pied de page, dans « Où nous livrons » et sur les
   treize pages régionales. Elle se vérifie quand on la cherche ; la livraison
   du jour, elle, doit se voir sans la chercher.

   Gain : une ligne de bandeau, soit vingt-huit pixels rendus aux collections.
   Pour revenir en arrière, il suffit de retirer cette règle.
   ========================================================================== */

@media (max-width: 620px) {
  .service > span:nth-of-type(2) { display: none; }
  .service > span:first-child { flex: 0 1 auto; text-align: left; }
  .service { flex-wrap: nowrap; align-items: center; padding: 9px 14px; }
  .service .avis { flex: 0 0 auto; }
}

/* ==========================================================================
   Reprise des reprises — 1er septembre 2026, troisième passe
   ========================================================================== */

@media (max-width: 620px) {

  /* LE TÉLÉPHONE OCCUPAIT SA PROPRE RANGÉE, et je n'avais pas vu pourquoi.
     Une règle posée plus haut lui donne « grid-column: 1 / -1 » : toute la
     largeur de la première rangée. Ma grille à trois colonnes ne pouvait donc
     rien — elle décrivait des colonnes qu'un enfant refusait d'occuper.

     C'est la même erreur que pour le flex sur une grille : j'ai réglé la
     propriété visible sans chercher celle qui la contredisait. */
  .outils > .outils-centre { grid-column: auto; grid-row: auto;
                             justify-self: center; }
  /* Le numéro se resserre un peu, comme demandé : il reste le plus gros
     caractère de la rangée, il n'a pas besoin d'être le plus gros de l'écran. */
  .tel-entete { font-size: 12.5px; }

  /* LE BANDEAU : DEUX FAUTES DANS MA RÈGLE PRÉCÉDENTE.
     « span:nth-of-type(2) » désignait le séparateur, pas la zone — les
     séparateurs comptent comme des « span ». Et « flex-wrap: nowrap » a
     comprimé la livraison en une colonne de quatre lignes au lieu de la
     laisser tenir sur une ligne.

     On désigne donc par ce que l'élément EST, non par son rang : ni le
     premier, ni un séparateur, ni l'avis — il ne reste que la zone. */
  .service { flex-wrap: wrap; }
  .service > span:not(:first-child):not(.sep):not(.avis) { display: none; }
  .service > span:first-child { flex: 1 1 auto; text-align: left;
                                white-space: normal; }
}

/* ==========================================================================
   La photo centrée, et les deux sensations nommées — 1er septembre 2026
   ========================================================================== */

@media (max-width: 620px) {

  /* LA PHOTO SE CENTRE.
     Elle occupait toute la largeur en « object-fit: cover », donc elle rognait
     le sujet pour remplir. Sur une orchidée haute, cela coupait les hampes.
     Elle garde ses proportions et se pose au milieu : mieux vaut un peu de
     noir de part et d'autre qu'un bouquet amputé. */
  .produit .visuel-p { display: flex; align-items: center; justify-content: center;
                       max-height: 46vh; }
  .produit .visuel-p .photo { height: auto; max-height: 46vh; width: auto;
                              max-width: 100%; object-fit: contain;
                              margin: 0 auto; }

  /* LES DEUX LIGNES DE SENSATION PORTENT LEUR LIBELLÉ.
     Sans lui, on ne savait pas qui ressentait quoi. « Pour qui offre » et
     « pour qui reçoit » nomment la fonction, pas la personne : rien de
     masculin, rien de féminin, et pas de tournure inclusive qui alourdirait
     deux lignes dont toute la valeur est d'être brèves. */
  .produit .module > .sensation { text-align: left; align-items: stretch;
                                  gap: 8px; margin: 16px 0 6px; }
  .sensation .s-ligne { display: grid; grid-template-columns: auto 1fr;
                        column-gap: 10px; align-items: baseline; }
  .sensation .s-qui { font-family: var(--jost); font-size: 9.5px;
                      letter-spacing: .17em; text-transform: uppercase;
                      color: #8A857C; white-space: nowrap;
                      padding-top: 1px; }
}

/* Sur écran large, le libellé se place de la même façon — la colonne de
   gauche aligne les deux lignes l'une sous l'autre, ce qui les lie. */
.sensation .s-ligne { display: grid; grid-template-columns: auto 1fr;
                      column-gap: 12px; align-items: baseline; }
.sensation .s-qui { font-family: var(--jost); font-size: 10px;
                    letter-spacing: .17em; text-transform: uppercase;
                    color: #8A857C; white-space: nowrap; }

/* ==========================================================================
   Le pied de page, réparti — 1er septembre, puis refait le 2
   --------------------------------------------------------------------------
   La version du 1er septembre posait « Boutique » à gauche, « L'Atelier » à
   droite et « Nous joindre » sur toute la largeur en dessous. Olivier a demandé
   les trois côte à côte, sous-rubriques centrées : cette version-là a donc été
   **retirée** et non pas corrigée par-dessus.

   Il fallait la retirer, pas l'empiler : « .pied .col:nth-of-type(2) » compte
   trois sélecteurs et bat « .pied > .col » qui n'en compte que deux. La règle
   la plus récente aurait perdu, et le pied serait resté tel quel malgré la
   nouvelle règle — le genre de panne qu'on cherche longtemps parce que le code
   ajouté a l'air juste.

   La répartition en vigueur est plus bas, dans la passe du 2 septembre.
   ========================================================================== */

/* ==========================================================================
   Deux corrections de mes propres corrections — 2 septembre 2026
   ========================================================================== */

@media (max-width: 620px) {

  /* LA RANGÉE D'OUTILS, TROISIÈME TENTATIVE — et cette fois en lisant TOUTES
     les règles qui la gouvernent, au lieu d'une seule.

     Il n'y avait pas un obstacle mais trois, posés ensemble plus haut :
     « .outils-centre » prend toute la première rangée, « .panier » est cloué en
     « grid-row: 2 », « .langue » aussi. J'avais levé le premier et laissé les
     deux autres — d'où un panier et une langue toujours sur une seconde ligne.

     La leçon, deux fois de suite la même : quand un réglage ne prend pas, ce
     n'est pas qu'il est trop faible, c'est qu'on n'a pas cherché tout ce qui
     le contredit. */
  .outils > .panier,
  .outils > .langue,
  .outils > .outils-centre { grid-row: auto; grid-column: auto; }
  .outils > .panier { justify-self: start; }
  .outils > .outils-centre { justify-self: center; }
  .outils > .langue { justify-self: end; }

  /* LE PIED DE PAGE : TROIS COLONNES CÔTE À CÔTE, SOUS-RUBRIQUES CENTRÉES.
     Demandé par Olivier le 2 septembre, après deux versions intermédiaires.

     Ce qu'il y avait avant : Boutique à gauche, L'Atelier à droite, et Nous
     joindre seule sur toute la largeur en dessous. Trois blocs de tailles
     différentes, et une répartition qui se lisait mal.

     Ce qu'il faut : les trois côte à côte, chacun d'un tiers, chaque
     sous-rubrique centrée sous son titre. Une seule règle y suffit désormais,
     puisque les trois colonnes se comportent pareil.

     Le piège, payé deux fois : « nth-of-type » compte parmi les frères de même
     balise, et le bloc de marque est un « div » comme les colonnes. Les
     colonnes sont donc les rangs 2, 3 et 4 — pas 1, 2 et 3. Écrire « .col »
     sans rang, comme ici, retire le piège au lieu de le contourner. */
  .pied { grid-template-columns: repeat(3, 1fr); gap: 22px 10px; }
  .pied .marque-pied { grid-column: 1 / -1; }
  .pied > .col { text-align: center; align-items: center; min-width: 0; }
  .pied > .col .l,
  .pied > .col a { justify-content: center; text-align: center;
                   /* Trois colonnes sur un téléphone laissent environ cent
                      pixels chacune. « Livraison et paiement » ou « Questions
                      fréquentes » y passent sur deux lignes : il faut donc que
                      la coupure soit propre plutôt qu'un débordement. */
                   overflow-wrap: anywhere; hyphens: auto; line-height: 1.35; }
}

@media (max-width: 620px) {
  /* Ma première version posait « grid-column: 1 / -1 » sur une colonne, ce qui
     l'étalait sur toute la largeur pendant que ses voisines gardaient la leur.
     Une règle laissée derrière une correction agit encore, mais sur autre
     chose : elle est aussi nuisible que la faute qu'elle corrigeait. */
  .pied > .col:nth-of-type(3) { grid-column: auto; }

  /* À cette largeur, trois colonnes deviennent étroites : on resserre le texte
     plutôt que de casser la répartition demandée. */
  .pied { gap: 20px 8px; }
  .pied > .col a { font-size: 12.5px; min-height: 32px; }
  .pied .col-titre { font-size: 10px; letter-spacing: .12em; }
}

/* ==========================================================================
   Passe mobile sur les douze autres types de page — 2 septembre 2026
   --------------------------------------------------------------------------
   Olivier avait relevé beaucoup de défauts sur deux pages ; les autres
   n'avaient jamais été regardées sur téléphone. Mesuré sur rayon, mariage,
   conditions de vente, page régionale et Journal :

   **aucun débordement horizontal nulle part, aucun élément plus large que
   l'écran, menu à quarante pixels partout.** Le gros est donc sain.

   Deux fausses alertes écartées en chemin, notées parce qu'elles reviendront :
   les dix-huit cases à cocher du formulaire mariage font dix-neuf pixels, mais
   elles vivent dans un « label » de quarante-quatre pixels sur trois cent
   vingt-cinq — **toute la ligne est déjà la cible**, et mesurer la case au
   lieu de la cible réelle ne dit rien. Et le champ-piège à robots est bien
   hors écran, à moins neuf mille neuf cent quatre-vingt-dix-neuf pixels.

   Restent trois choses vraies.
   ========================================================================== */

@media (max-width: 620px) {

  /* 1. LE CHAMP DE QUANTITÉ DU FORMULAIRE MARIAGE faisait trente-deux pixels,
     quand les autres champs du même formulaire en font quarante-trois. C'est
     le seul qu'on manque, et c'est celui qu'on utilise dix-huit fois. */
  .m-qte { min-height: 40px; padding: 8px 10px; font-size: 16px; }

  /* 2. LE TÉLÉPHONE ET WHATSAPP DE L'EN-TÊTE offraient dix-neuf et dix-sept
     pixels de hauteur de clic. Pour un fleuriste dont un quart des commandes
     passe par le téléphone, c'est le lien qui doit être le plus facile à
     atteindre du site.

     On agrandit la zone sensible sans grossir le texte : la marge intérieure
     ne se voit pas, elle se touche. */
  .outils-centre > a { padding: 11px 4px; display: inline-flex;
                       align-items: center; }

  /* 3. LES PETITES CAPITALES à dix pixels — « Découvrir » sur les cartes, et
     les titres de colonne du pied. L'interlettrage large les rend lisibles,
     mais dix pixels reste sous ce qu'on lit sans effort à bout de bras, et
     Olivier a déjà signalé deux fois que le site écrivait trop petit. */
  .carte .cta { font-size: 11px; }
  .pied .col-titre { font-size: 11px; }
}


/* Le libellé des deux lignes de sensation était à 4,45 de contraste sur le
   fond nuit, pour un seuil de 4,5 à cette taille — mesuré le 2 septembre 2026,
   pas estimé à l'œil. Trente-cinq millièmes manquaient, ce qui ne se voit pas
   en regardant et se voit en calculant. Le gris passe de #7E7A72 à #8A857C,
   soit 5,18 : la nuance reste discrète, elle devient lisible.

   C'est le troisième réglage de couleur de ce site repris sur un calcul plutôt
   que sur une impression, et les trois fois l'œil disait « ça va ». */

/* ==========================================================================
   Trois défauts d'un seul tenant — 2 septembre 2026, après relevé d'Olivier
   --------------------------------------------------------------------------
   Il en a signalé trois : la promesse de livraison encore affichée à 12 h 56,
   « Noté sur Google » renvoyé à la ligne, et le panier, le téléphone et la
   langue redescendus sur deux lignes après avoir été réparés.

   **Les trois n'en font qu'un.** En retirant l'ancien bloc du pied de page,
   j'avais coupé juste après sa dernière règle et laissé la fermeture de la
   requête média. Un navigateur qui rencontre une accolade fermante là où il attend un sélecteur
   jette ce qui suit jusqu'à pouvoir se rattraper — et ce qui suivait était le
   bloc contenant à la fois la rangée d'outils et les trois colonnes du pied.
   Le code était juste, il n'était simplement jamais appliqué.

   La leçon : après une suppression dans une feuille de style, compter les
   accolades. Une seule en trop annule silencieusement tout ce qui la suit.
   ========================================================================== */

@media (max-width: 620px) {
  /* LE BANDEAU SUR UNE SEULE LIGNE.
     « flex: 1 0 100% » donnait toute la largeur au premier élément : c'était
     juste quand il disait « Livraison le jour même si commande avant 12 h »,
     ce l'est beaucoup moins depuis qu'il tient en deux mots. La promesse se
     cale à gauche, l'avis Google à droite, et rien ne revient à la ligne. */
  .service { flex-wrap: nowrap; justify-content: space-between; column-gap: 10px; }
  .service > span:first-child { flex: 0 1 auto; width: auto; text-align: left;
                                white-space: nowrap; }
  .service .avis { margin-left: auto; flex: 0 0 auto; white-space: nowrap; }

  /* Passé midi, la promesse disparaît et l'avis reste seul : il se cale alors
     à gauche si on ne lui dit rien. On le tient à droite dans les deux cas. */
  .service > span:only-of-type { margin-left: auto; }

  /* LE NUMÉRO DE TÉLÉPHONE, PLUS PETIT.
     Il occupait la moitié de la rangée et repoussait la langue à la ligne.
     Personne ne recopie un numéro depuis son téléphone : on le touche. Sa
     lisibilité n'a donc pas à être celle d'un texte qu'on lit, seulement celle
     d'une cible qu'on vise — et la cible, elle, garde ses 44 pixels de haut. */
  .outils .tel-entete { font-size: 15px; letter-spacing: .01em; }
  .outils { column-gap: 6px; }
}

@media (max-width: 430px) {
  .outils .tel-entete { font-size: 13.5px; }
  .service { font-size: 10.5px; }
}

/* ==========================================================================
   Une quatrième colonne pour le juridique — 2 septembre 2026
   --------------------------------------------------------------------------
   « Nous joindre » portait huit entrées quand ses voisines en portaient quatre
   ou cinq : le téléphone, les horaires, la livraison, la foire aux questions,
   la réclamation, et par-dessus les trois textes juridiques. Deux fois plus
   long que les autres, et le regard n'y trouvait plus la seule chose qu'on y
   cherche vraiment — comment joindre quelqu'un.

   Les trois textes juridiques partent dans leur propre bloc. Ils forment une
   famille, on les consulte pour une raison différente du reste, et les séparer
   rééquilibre les colonnes sans rien retirer.

   **Les trois blocs demandés restent côte à côte.** Le juridique prend la
   quatrième place sur les écrans qui l'ont, et passe en pleine largeur sous les
   trois autres sur un téléphone — quatre colonnes de quatre-vingt-dix pixels ne
   laisseraient pas passer « Conditions générales ».
   ========================================================================== */

@media (min-width: 621px) {
  .pied { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .pied .marque-pied { grid-column: 1 / -1; }
}

@media (max-width: 620px) {
  /* Les trois premières colonnes gardent leur tiers. La quatrième s'étend sous
     elles et dispose ses trois liens en ligne : trois entrées courtes n'ont pas
     besoin d'une colonne, elles tiennent sur un rang. */
  .pied > .col-legal { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap;
                       justify-content: center; align-items: baseline;
                       gap: 4px 18px; margin-top: 4px;
                       padding-top: 16px; border-top: 1px solid var(--ligne); }
  .pied > .col-legal .col-titre { flex: 1 0 100%; text-align: center;
                                  margin-bottom: 2px; }

  /* L'adresse de contact est le plus long mot d'une colonne de cent pixels.
     On la laisse se couper proprement plutôt que déborder, et on la garde
     lisible : c'est elle qu'on recopie quand on écrit depuis un ordinateur. */
  .pied > .col a[href^="mailto:"] { overflow-wrap: anywhere; line-height: 1.3; }
}

/* ==========================================================================
   Quatre défauts relevés sur la fiche produit — 2 septembre 2026, 13 h
   ========================================================================== */

@media (max-width: 620px) {

  /* 1. LA PHOTO ET LE TITRE SE CENTRENT VRAIMENT.
     Mesuré sur la capture d'Olivier : la photo commençait à 32 px du bord
     gauche et s'arrêtait à 88 px du bord droit. Elle n'était pas centrée, elle
     était décalée — un reste de la marge asymétrique posée pour l'ancien
     bandeau. On rend les marges égales, et le titre suit la photo. */
  .produit .visuel-p { padding-left: 0; padding-right: 0; margin-left: auto;
                       margin-right: auto; width: 100%; }
  .produit .module > h1,
  .produit .module > .fil { text-align: center; }
  .produit .module > .fil { justify-content: center; }

  /* 2. LES DEUX LIGNES DE SENSATION, LISIBLES.
     Le contraste passait la norme — 5,18 : 1 sur le fond nuit — et pourtant
     elles ne se lisaient pas. Le défaut n'était pas la couleur seule mais sa
     rencontre avec la taille : **9,5 px en capitales espacées de 0,17 em**.
     Une norme respectée sur un texte trop petit reste illisible ; l'inverse
     est vrai aussi, et c'est pourquoi on corrige les deux à la fois.
     #A8A296 monte le rapport à 7,49 : 1. */
  .sensation .s-qui { font-size: 11px; letter-spacing: .13em; color: #A8A296; }
  .sensation .s-envoi,
  .sensation .s-recu { font-size: 15px; }

  /* 3. LE CERCLE DE RÉFÉRENCE ÉTAIT INVISIBLE.
     Son trait pointillé était en --ligne-2, soit **1,54 : 1** — au-dessous du
     seuil de 3 : 1 exigé d'un simple trait, et cinq fois moins que ce qu'il
     faudrait. Le cercle porte pourtant toute la démonstration : sans lui, on
     ne compare rien. Trait et texte remontés ensemble. */
  .disque.ref { border-color: #6E6E78; border-width: 2px; }
  .disque.ref i { color: #B4AEA2; }
  .disque i { font-size: 13px; }
  .prop-txt { color: #B4AEA2; font-size: 13px; line-height: 1.55; }
  .proportion { border-color: #3E3E46; }

  /* 4. LE MÉDAILLON D'AXEPTIO NE MASQUE PLUS LE PRIX.
     Il se pose en bas à gauche, exactement là où la barre collante affiche le
     montant — Olivier ne lisait plus que « 0 € ». Le retirer serait le mauvais
     remède : c'est la seule porte de sortie du consentement, et beaucoup de
     visiteurs arrivent directement sur une fiche depuis une publicité. On
     décale donc le prix hors de son emprise. */
  .barre-achat { padding-left: 68px; }
  .barre-achat .bp { flex: 0 0 auto; }
}

/* ==========================================================================
   Le médaillon d'Axeptio s'efface une fois le consentement donné — 2 sept. 2026
   --------------------------------------------------------------------------
   Il se posait en bas à gauche, en position fixe, exactement là où la barre
   collante affiche le prix. Sur un téléphone, on ne lisait plus le montant.

   Le widget vit dans un « shadow root » : aucune règle d'ici n'atteint son
   intérieur, on ne peut donc pas viser le seul médaillon. On masque l'hôte
   entier — mais **seulement une fois le consentement donné**, car avant cela
   c'est le bandeau qu'il porte, et le bandeau doit rester. La classe est posée
   par le script du pied de page, d'après le témoin « axeptio_cookies ».

   Le lien « Préférences de cookies » du pied enlève la classe et rouvre le
   panneau : on retire une gêne, pas un droit.
   ========================================================================== */

html.consentement-donne #axeptio_overlay,
html.consentement-donne .axeptio_mount,
html.consentement-donne #axeptio_main_button,
html.consentement-donne #axeptio_btn { display: none !important; }

/* Le prix retrouve sa place : le décalage de 68 px n'avait de raison d'être
   que tant que le médaillon l'occupait. On le garde tant que le consentement
   n'est pas donné, on le rend dès qu'il l'est. */
@media (max-width: 620px) {
  html.consentement-donne .barre-achat { padding-left: 16px; }
}

/* ==========================================================================
   Corrections du 2 septembre, 15 h — relevé d'Olivier sur son téléphone
   ========================================================================== */

/* LES PIÈCES OSCENDENCE SE MONTRENT.
   Elles étaient listées en texte : un nom, une phrase, un lien. On ne vend pas
   une composition de mille roses à plusieurs milliers d'euros sur une
   description — c'est précisément le rayon où l'image fait tout le travail. */
.osc-pieces { list-style: none; margin: 0; padding: 0;
              display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
              gap: 26px 20px; }
.osc-pieces li { margin: 0; }
.osc-carte { display: flex; flex-direction: column; gap: 10px; }
.osc-carte img { width: 100%; height: auto; aspect-ratio: 1 / 1;
                 object-fit: cover; display: block; border: 1px solid var(--ligne); }
.osc-carte .osc-nom { font-family: var(--jost); font-size: 17px; font-weight: 300;
                      color: var(--ivoire); letter-spacing: .01em; }
.osc-carte .osc-note { font-size: 13.5px; line-height: 1.55; color: #B4AEA2; }
@media (hover: hover) { .osc-carte:hover img { border-color: var(--argent); } }
/* L'appel a l'action. En or, parce que c'est la couleur d'Oscendence et la
   seule derogation admise a la regle « l'or est reserve a la marque ». Le
   filet le pose comme un bouton sans en faire une boite : une boite pleine
   sous une piece a plusieurs milliers d'euros ferait catalogue. */
.osc-carte .osc-voir {
  align-self: flex-start; margin-top: 2px;
  font-family: var(--jost); font-size: 12px; font-weight: 400;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--or); padding-bottom: 3px;
  border-bottom: 1px solid rgba(212, 185, 127, .5);
  transition: border-color .16s, color .16s;
}
@media (hover: hover) {
  .osc-carte:hover .osc-voir { color: #E7CE8A; border-bottom-color: #E7CE8A; }
}

/* UN NUMÉRO DE TÉLÉPHONE NE SE COUPE PAS EN DEUX.
   Relevé sur la page mariage : « 09 70 » restait sur une ligne et « 98 89 81 »
   passait à la suivante. Un numéro coupé n'est plus un numéro — on ne le lit
   pas, on ne le retient pas, et sur un téléphone on hésite à le toucher. */
a[href^="tel:"], .tel-mariage, .osc-tel { white-space: nowrap; }

@media (max-width: 620px) {
  /* LE PIED DE PAGE : DE LA PLACE POUR L'ADRESSE.
     « contact@atelierdolivier.com » est le plus long mot du pied, et il tombait
     dans la colonne la plus étroite. Les deux colonnes de gauche portent des
     mots courts — Bouquets, Deuil, Mariage — et n'ont pas besoin d'un tiers
     chacune. On leur en prend pour la donner à celle qui en manque. */
  .pied { grid-template-columns: 0.82fr 0.82fr 1.36fr; column-gap: 8px; }
  .pied > .col a[href^="mailto:"] { font-size: 12px; }
}

/* ==========================================================================
   La signature d'Oscendence, et le pied réparti — 2 septembre 2026, 21 h
   ========================================================================== */

/* « CHOQUEZ AVEC STYLE » EST LA PHRASE DE LA MARQUE, PAS UN CHAPÔ.
   Elle sortait en blanc, à la taille du reste, séparée du titre par un blanc
   d'article : rien ne disait qu'on lisait une signature. Elle se rapproche du
   nom, prend l'or de la maison, et s'écrit en italique déliée — un registre que
   rien d'autre n'emploie sur le site, donc qui ne se confond avec rien. */
/* LE RAPPORT ETAIT INVERSE, ET C'EST MESURABLE. Sur telephone le titre
   « Oscendence » sortait a 26 px en gris pale, et la signature a 25 px en or
   et en italique. A taille quasi egale, c'est la COULEUR qui decide de la
   hierarchie : l'or sur fond noir attire l'oeil bien avant un gris clair. La
   signature passait donc devant le nom de la marque.

   Le nom prend le dessus — c'est lui qu'on doit retenir — et la signature
   revient a la taille d'une ligne qu'on lit une fois. Les deux se centrent :
   une marque de tres haut de gamme pose son nom sur l'axe, pas au fer a
   gauche comme un article. */
.page-oscendence .contenu > h1 {
  text-align: center;
  font-size: clamp(38px, 6.4vw, 60px); font-weight: 200;
  letter-spacing: .04em; line-height: 1.08;
  margin-bottom: 6px;
}
.page-oscendence .chapo-page {
  text-align: center;
  margin-top: 0; margin-bottom: 34px;
  font-family: var(--jost); font-style: italic; font-weight: 300;
  font-size: clamp(16px, 1.9vw, 19px); line-height: 1.4;
  letter-spacing: .05em; color: #D4B97F;
}
/* Le fil d'Ariane reste au fer a gauche : c'est un outil de reperage, pas un
   element de la marque, et le centrer brouillerait les deux. */

@media (max-width: 620px) {
  .page-oscendence .contenu > h1 { font-size: 34px; letter-spacing: .03em; }
  .page-oscendence .chapo-page { margin-bottom: 26px; font-size: 15.5px; }
}

/* LE PIED : BOUTIQUE À GAUCHE, LE MILIEU CENTRÉ, NOUS JOINDRE À DROITE.
   Trois blocs alignés au centre se ressemblaient trop pour qu'on distingue où
   l'un finissait et l'autre commençait. Chacun se cale maintenant sur son
   bord, et le regard a trois repères au lieu d'un. */
.pied > .col:nth-of-type(2) { text-align: left; align-items: flex-start; }
.pied > .col:nth-of-type(2) a,
.pied > .col:nth-of-type(2) .l { justify-content: flex-start; text-align: left; }

.pied > .col:nth-of-type(3) { text-align: center; align-items: center; }

.pied > .col:nth-of-type(4) { text-align: right; align-items: flex-end; }
.pied > .col:nth-of-type(4) a,
.pied > .col:nth-of-type(4) .l { justify-content: flex-end; text-align: right; }

/* La colonne juridique garde sa ligne centrée sous les trois autres. */
.pied > .col-legal { text-align: center; align-items: center; }
.pied > .col-legal a { justify-content: center; text-align: center; }

/* ==========================================================================
   Deux lignes qui doivent tenir sur une ligne — 2 septembre 2026, 21 h 30
   ========================================================================== */

@media (max-width: 620px) {
  /* LE LIBELLÉ PASSE AU-DESSUS.
     Il occupait une colonne d'environ 130 pixels. Sur un écran de 360, il
     restait donc **moins de 190 pixels** à la phrase, soit vingt-six caractères
     — alors que la médiane française est de trente-huit. Deux lignes sur trois
     revenaient à la ligne, et une formule qui se casse en deux perd le rythme
     qui faisait toute sa valeur.

     Le libellé au-dessus rend la largeur entière à la phrase. Il reste lisible
     parce qu'il est court et espacé : on ne le lit pas, on le reconnaît. */
  .sensation .s-ligne { grid-template-columns: 1fr; row-gap: 1px; }
  .sensation .s-qui { font-size: 10px; letter-spacing: .15em; }
  .sensation .s-envoi,
  .sensation .s-recu { font-size: 14.5px; line-height: 1.3; }
}

/* LE SUPPLÉMENT DE PRIX NE SE COUPE PAS DE SON EURO.
   « + 30 € » sortait en « + 30 » puis « € » à la ligne suivante. Un montant
   séparé de sa devise cesse d'être un montant : on le relit deux fois pour
   comprendre ce qu'on lit. Vaut pour le supplément du vase comme pour ceux des
   tailles, qui tiennent aujourd'hui par chance et non par règle. */
.opt .supplement, .vase-prix, .opt-prix, .echelle .prix,
[data-supplement], .prix-sup { white-space: nowrap; }

/* ==========================================================================
   L'espace mariage, refait — 2 septembre 2026
   --------------------------------------------------------------------------
   La page mêlait une liste à cocher, un paragraphe, puis un formulaire. Olivier
   l'a lue comme un lecteur : « une première partie du questionnaire, du blabla,
   et la suite du questionnaire ». Il avait raison — on ne coupe pas un
   formulaire en deux par de la prose.

   L'estimation vit maintenant sur sa propre page. Ici, la liste se **lit** :
   cocher demande de décider, lire demande seulement de se souvenir, et ce que
   cherche un couple à ce moment-là est de vérifier qu'il n'oublie rien.
   ========================================================================== */

.m-banniere { margin: 0 0 30px; }
.m-banniere img { width: 100%; height: auto; display: block;
                  aspect-ratio: 4 / 1; object-fit: cover; }

.m-listes { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
            gap: 24px 30px; margin: 26px 0 34px; }
.m-bloc h3 { font-family: var(--jost); font-size: 15px; font-weight: 400;
             letter-spacing: .06em; text-transform: uppercase;
             color: var(--argent); margin: 0 0 10px; }
.m-bloc ul { list-style: none; margin: 0; padding: 0; }
.m-bloc li { font-size: 14.5px; line-height: 1.7; color: #B4AEA2;
             padding-left: 14px; position: relative; }
.m-bloc li::before { content: "·"; position: absolute; left: 2px;
                     color: var(--argent); }

.m-photo { margin: 30px 0; }
.m-photo img { width: 100%; max-width: 458px; height: auto; display: block;
               margin: 0 auto; border: 1px solid var(--ligne); }

/* Le passage vers l'estimation. Il vient APRÈS la liste : on ne propose pas de
   chiffrer à quelqu'un qui n'a pas encore vu ce qu'il y a à chiffrer. */
.m-vers-budget { border: 1px solid var(--ligne); padding: 22px 24px;
                 margin: 32px 0; text-align: center; }
.m-vers-budget p { margin: 0 0 14px; }
.m-vers-budget p:last-child { margin: 0; }

/* ---------- la page d'estimation ---------- */

.b-gamme { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 26px 0 30px; }
.b-niveau { background: none; border: 1px solid var(--ligne); color: var(--cendre);
            padding: 14px 16px; cursor: pointer; text-align: left;
            display: flex; flex-direction: column; gap: 4px;
            font-family: inherit; transition: border-color .15s, color .15s; }
.b-niveau-nom { font-family: var(--jost); font-size: 16px; color: var(--ivoire); }
.b-niveau-det { font-size: 12.5px; line-height: 1.4; }
.b-niveau.actif { border-color: var(--argent); }
.b-niveau.actif .b-niveau-nom { color: #D4B97F; }

.b-groupe { border: 0; border-top: 1px solid var(--ligne); margin: 0 0 6px; padding: 18px 0 4px; }
.b-groupe legend { font-family: var(--jost); font-size: 13px; letter-spacing: .12em;
                   text-transform: uppercase; color: var(--argent); padding: 0 10px 0 0; }
.b-postes { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
            gap: 6px 24px; }
.b-poste { display: flex; align-items: center; gap: 10px; padding: 7px 0;
           font-size: 14.5px; color: var(--ivoire); cursor: pointer; }
.b-poste input[type="checkbox"] { width: 17px; height: 17px; flex: 0 0 auto;
                                  accent-color: #D4B97F; }
.b-nom { flex: 1 1 auto; }
.b-qte { width: 62px; flex: 0 0 auto; background: #15151A; color: var(--ivoire);
         border: 1px solid var(--ligne); padding: 5px 7px; font-family: inherit;
         font-size: 14px; text-align: center; }
.b-qte:disabled { opacity: .35; }

.b-total { border: 1px solid var(--argent); padding: 22px 24px; margin: 30px 0 18px;
           display: flex; flex-direction: column; align-items: center; gap: 6px;
           text-align: center; }
.b-total-lbl { font-family: var(--jost); font-size: 11px; letter-spacing: .18em;
               text-transform: uppercase; color: var(--cendre); }
.b-total-val { font-family: var(--jost); font-size: clamp(26px, 4vw, 38px);
               font-weight: 200; color: var(--rose); letter-spacing: .01em; }
.b-total-note { font-size: 13px; color: #B4AEA2; }

.b-suite { font-size: 14px; line-height: 1.7; color: #B4AEA2; }
.b-appel { margin-top: 14px; }
.b-lien { color: var(--argent); text-decoration: none; }
.b-lien:hover { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 620px) {
  .b-gamme { grid-template-columns: 1fr; }
  .b-postes { grid-template-columns: 1fr; }
  .b-poste { min-height: 44px; }
  .m-listes { grid-template-columns: 1fr; gap: 20px; }
  .m-banniere img { aspect-ratio: 16 / 9; }
}

/* LA COMPARAISON DES CALIBRES.

   Une affirmation de fait — « corolles larges » — appelle une preuve, et une
   photo en est une bien meilleure qu'un adjectif. Les deux cliches sont
   d'Olivier ; leurs orientations sont INVERSES l'une par rapport a l'autre,
   d'ou une legende qui nomme les roses au lieu de designer un cote. Une
   legende « a gauche » aurait ete juste sur une image et fausse sur l'autre.

   Deux colonnes sur large, l'une sous l'autre sur telephone. Hauteur commune
   et recadrage centre : sans cela un portrait de 1 400 px ecrase un paysage
   de 1 050 et la paire perd son propos. */
/* ELLES ILLUSTRENT, ELLES NE DEMONTRENT PAS. Olivier : « il faut que ces
   photos ne soient pas trop grosses dans la page, c'est juste pour illustrer
   des propos ». Une image qui prend toute la colonne devient le sujet du
   paragraphe ; a 420 px elle reste ce qu'elle est — une preuve rapide, qu'on
   regarde une seconde avant de revenir au texte.

   Et DEUX COLONNES MEME SUR TELEPHONE. Empilees, deux photos pleine largeur
   coupent la lecture en deux et pesent plus que le paragraphe qu'elles
   servent. Cote a cote et petites, elles restent une note en marge. */
.calibre { margin: 20px 0 24px; max-width: 420px;
           display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
/* CHAQUE PHOTO GARDE SES PROPORTIONS. Le carre coupait les tiges en haut et
   en bas : on voyait un troncon de tige sans la fleur, ce qui vide l'image de
   son propos. Olivier : « il faudrait voir les fleurs entieres, du bout des
   tiges jusqu'a la fleur ». Les deux images ont donc des hauteurs
   differentes — c'est le prix de les montrer entieres, et il est juste. */
.calibre { align-items: start; }
.calibre img { width: 100%; height: auto; display: block; border-radius: 2px; }
.calibre figcaption { grid-column: 1 / -1; font-size: 12.5px; line-height: 1.55;
                      color: #B4AEA2; padding-top: 2px; }

@media (max-width: 620px) {
  .calibre { max-width: none; gap: 7px; }
  .calibre img { border-radius: 1px; }
  .calibre figcaption { font-size: 12px; }
}

/* ==========================================================================
   L'espace evenements — 3 septembre 2026
   ========================================================================== */

/* Le vert d'eau signe la page comme le dore signe Oscendence : on retrouve au
   clic la couleur qu'on a vue au menu. Sans cela la pastille ne serait qu'une
   decoration de barre. */
.page-evenements .contenu h2 { color: var(--sauge); }
.page-evenements .contenu h2::after {
  content: ""; display: block; width: 46px; height: 1px; margin-top: 10px;
  background: linear-gradient(90deg, var(--sauge) 0%, transparent 100%);
}

/* Trois colonnes qui disent trois publics. Une entreprise et un particulier ne
   cherchent pas la meme chose : melanges dans une seule liste, chacun lirait
   celle de l'autre avant de trouver la sienne. */
.e-listes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px;
            margin: 22px 0 24px; }
.e-groupe h3 { font-family: var(--jost); font-weight: 400; font-size: 14px;
               letter-spacing: .11em; text-transform: uppercase;
               color: var(--ivoire); margin: 0 0 12px; }
.e-liste { list-style: none; margin: 0; padding: 0; }
.e-liste li { position: relative; padding: 0 0 9px 15px; font-size: 15px;
              line-height: 1.55; color: var(--cendre); }
.e-liste li::before { content: ""; position: absolute; left: 0; top: 10px;
                      width: 5px; height: 1px; background: var(--sauge); }

.e-etapes { margin: 20px 0 26px; padding-left: 20px; }
.e-etapes li { padding: 0 0 14px 4px; line-height: 1.7; }

/* LES DEUX VOIES A EGALITE, et c'est le point de la page. Partout ailleurs sur
   le site le telephone domine ; ici l'ecrit tient la meme place. Olivier :
   « souvent des etrangers qui sont plus a l'aise par ecrit ». Un dirigeant qui
   hesite sur son francais ne telephonera pas — il ecrira, ou il ira ailleurs.
   Deux colonnes de meme largeur, meme graisse, meme traitement : rien dans la
   mise en page ne suggere que l'une est le second choix. */
.e-voies { display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
           margin: 20px 0 30px; }
.e-voie { border: 1px solid var(--ligne); border-radius: 3px; padding: 18px 18px 16px;
          background: linear-gradient(180deg, rgba(211,222,208,.05) 0%, transparent 100%); }
.e-voie-quoi { display: block; font-family: var(--jost); font-size: 12px;
               letter-spacing: .13em; text-transform: uppercase;
               color: var(--sauge); margin-bottom: 8px; }
.e-voie-adr { margin: 0 0 8px; font-size: 17px; line-height: 1.4; }
.e-voie-adr a { color: var(--ivoire); text-decoration: none; }
.e-voie-adr a:hover { text-decoration: underline; text-underline-offset: 3px; }
.e-voie-note { margin: 0; font-size: 13px; line-height: 1.55; color: #8E877B; }

.e-form { margin-top: 8px; }
.e-form-note { margin: 0 0 18px; font-size: 14.5px; line-height: 1.7;
               color: var(--cendre); }

@media (max-width: 900px) {
  .e-listes { grid-template-columns: 1fr 1fr; gap: 20px; }
}
@media (max-width: 620px) {
  .e-listes { grid-template-columns: 1fr; gap: 22px; margin: 18px 0 20px; }
  .e-voies { grid-template-columns: 1fr; gap: 10px; }
  .e-voie { padding: 15px 15px 13px; }
  .e-voie-adr { font-size: 16px; word-break: break-word; }
  .e-etapes { padding-left: 18px; }
}


/* ==========================================================================
   La bande des sous-rayons — 4 septembre 2026
   ==========================================================================

   Le rayon Deuil sortait vingt-neuf produits dans une grille plate : gerbes,
   coeurs, couronnes, raquettes et coussins meles. Quelqu'un qui cherchait une
   couronne parcourait vingt-neuf vignettes pour trouver les six qui le
   concernaient.

   C'est le rayon ou ce defaut coute le plus cher. La regle du projet dit que
   la capacite de decision est alteree apres un deces ; une personne dans cet
   etat ne trie pas une grille, elle abandonne. Ces cinq portes ne sont pas une
   commodite, elles rendent le rayon utilisable.

   AUCUNE MISE EN AVANT. L'ordre suit les ventes, mais rien ne le dit : pas de
   pastille « le plus demande », pas de premiere case plus grande. Le rayon
   Deuil interdit toute montee en gamme, et un classement affiche en est une.
   ========================================================================== */

/* LA MEME GRILLE QUE LES PRODUITS. Olivier : « les sous-categories dans
   bouquet doivent etre de la meme taille que les produits ». Elles etaient a
   108 px de large quand une fiche en fait 169 : deux tailles de vignette sur
   une meme page font croire a deux natures de contenu, et l'oeil hesite. On
   reprend donc la grille a l'identique — quatre colonnes, puis trois, puis
   deux — et les sous-rayons se lisent comme ce qu'ils sont : des entrees de
   meme rang que les produits. */
.sous-cats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
             gap: 18px; margin: 4px 0 30px; }
/* UN SOUS-RAYON EST UNE PORTE, PAS UNE LEGENDE.
   Olivier, le 4 septembre 2026 : « écrites très petites, illisibles et en gris
   sur noir en plus ». Mesure : 12 px, #8E897E sur #101012, contraste 5,46:1.
   Le contraste passait le seuil — c'est bien la preuve qu'un seuil ne suffit
   pas. A douze pixels, un gris moyen se lit mal quoi qu'en dise le calcul, et
   ces mots-la ne sont pas des legendes sous une image : ce sont les entrees
   d'un rayon, du meme rang que les noms de produits juste en dessous, qui sont
   en ivoire et plus gros.
   Ivoire sur nuit : 13,4:1, soit trois fois le minimum exige. */
.sc-case { display: flex; flex-direction: column; gap: 8px;
           text-decoration: none; color: var(--ivoire); }
.sc-case img { width: 100%; height: auto; aspect-ratio: 1 / 1;
               object-fit: cover; display: block; border-radius: 2px;
               background: #1a1a1d; }
/* 15 px → 18 px, le 4 septembre 2026. La regle ci-dessus dit qu'un sous-rayon
   est du meme rang qu'un produit ; la taille disait le contraire. Mesure : les
   noms de produits, juste en dessous sur la meme page, sont a 18 px. On aligne
   — c'est la fin de la correction commencee sur la couleur, et Olivier avait
   signale les deux d'un seul coup : « écrites très petites, illisibles et en
   gris sur noir en plus ». */
.sc-nom { font-family: var(--jost); font-size: 18px; line-height: 1.4;
          letter-spacing: .02em; text-align: center; }
.sc-case:hover { color: var(--ivoire); }
.sc-case:hover img { outline: 1px solid rgba(198, 202, 208, .35);
                     outline-offset: -1px; }

/* Sur telephone la bande defile plutot que de s'empiler : cinq cases empilees
   repousseraient la grille des produits sous deux ecrans, et le visiteur
   croirait que le rayon ne contient que des sous-rayons. */
/* Aux memes ruptures que la grille des produits, et jamais ailleurs : deux
   grilles qui changent de colonnage a des largeurs differentes se decalent
   l'une par rapport a l'autre, et la page parait mal montee. */
@media (max-width: 1100px) {
  .sous-cats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .sous-cats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  /* Deux par ligne au lieu de quatre : la case est deux fois plus large, le
     mot a donc plus de place, pas moins. Le reduire ici etait un reflexe, pas
     une mesure. 14,5 px → 17 px pour la meme raison qu'au-dessus : c'est un
     nom de rayon, pas une legende. */
  .sc-nom { font-size: 17px; }
}
@media (max-width: 430px) {
  .sous-cats { gap: 9px; }
}

/* ==========================================================================
   LA ZONE DE CHOIX PRENAIT LES DEUX TIERS DE L'ECRAN, PAS TOUTE LA LARGEUR.
   Olivier, le 4 septembre 2026 : « il faudrait que les placeholder carte
   message et précision pour le fleuriste prennent toute la largeur ».

   Mesure sur 375 px : la zone d'options s'arretait a 264 px pour 347
   disponibles — quatre-vingt-trois pixels perdus a droite, sur toute la
   hauteur du bloc. Les deux champs de texte remplissaient bien leur parent a
   100 % ; c'est le parent qui etait etroit, et les boutons de couleur
   souffraient du meme mal sans qu'on le remarque.

   La cause : « .module » passe en « display: contents » sur telephone, ce qui
   fait remonter « .options » comme enfant direct d'une section dont la mise en
   page a change de nature en cours de route — elle porte encore un
   « grid-template-columns » alors qu'elle est en flex. Un enfant flex prend
   alors sa largeur de contenu, et le contenu le plus large etait une rangee de
   deux boutons.

   On ne demele pas cet heritage la veille d'une mise en ligne : on pose la
   largeur, qui est ce qui etait voulu dans les deux dispositions. */
.achat .options,
.achat .options .opt,
.achat .options .bloc-champ { width: 100%; }

/* ==========================================================================
   LE TEXTE DE FOND DES RAYONS, SOUS LES PRODUITS.

   Mesure du 4 septembre 2026 : le rayon Bouquets portait quinze mots avant sa
   grille, fil d'Ariane et compteur compris, et son introduction en faisait
   quatre. Une categorie sans texte ne se classe que sur son nom exact.

   Olivier : « genre en bas des produits, en accordeons pour ne pas charger ».
   C'est le bon endroit — celui qui vient acheter voit la grille tout de suite,
   le texte attend celui qui hesite — et Google lit ce que contient un
   « details », ce qui est tranche depuis l'indexation mobile.
   ========================================================================== */
.fond-rayon {
  margin: 46px 0 8px;
  border-top: 1px solid var(--ligne);
  padding-top: 8px;
}
.fond-rayon > summary {
  cursor: pointer; list-style: none;
  padding: 16px 0;
  font-family: var(--jost); font-size: 15px; font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ivoire);
  display: flex; align-items: center; gap: 12px;
}
.fond-rayon > summary::-webkit-details-marker { display: none; }
/* Le chevron tourne : c'est le seul signe qui dise qu'on peut ouvrir, et il
   doit rester lisible sans couleur ni fond. */
.fond-rayon > summary::after {
  content: ""; width: 8px; height: 8px; flex: 0 0 auto;
  border-right: 1px solid var(--argent); border-bottom: 1px solid var(--argent);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .18s ease-out;
}
.fond-rayon[open] > summary::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}
@media (hover: hover) { .fond-rayon > summary:hover { color: #FFFDF6; } }

.fond-corps { padding: 4px 0 26px; max-width: 74ch; }
.fond-corps p { font-size: 15px; line-height: 1.72; color: var(--cendre);
                margin: 0 0 14px; }
.fond-corps h3 { font-family: var(--jost); font-weight: 400; font-size: 16px;
                 letter-spacing: .02em; color: var(--ivoire);
                 margin: 22px 0 8px; }
.fond-corps strong { color: var(--ivoire); font-weight: 400; }

/* ==========================================================================
   LE TUNNEL ECWID : UN SEUL TEXTE SOUS LE SEUIL, PAS TROIS.

   Mesures prises le 4 septembre 2026 pendant la commande d'essai d'Olivier,
   sur un panier reel — puis REFAITES le meme jour, parce que deux des trois
   etaient fausses :

     « Quantité : 1 »            #56565E sur #101012   2,61:1   defaut reel
     « Entrez votre code promo » #56565E sur blanc     7,03:1   annonce 2,9
     « Votre adresse mail »      #56565E sur blanc     7,03:1   annonce 2,9

   L'erreur venait de l'outil, pas d'Ecwid : ce blanc est rendu en notation
   « color(srgb 0.9825 …) », que mon script lisait comme une valeur sur 255 —
   il prenait donc du blanc pour du noir. Voir le detail plus bas, a l'endroit
   ou le gris des indices de saisie est laisse tel quel.

   Ce qui reste vrai : Ecwid pose un gris unique pour les deux fonds. Sur le
   sien, clair, il passe largement. Sur le notre, sombre, il ne passe pas — et
   « Quantité » n'est pas un texte d'ambiance, c'est le nombre d'articles
   commandes. C'est celui-la, et lui seul, qu'on releve.
   ========================================================================== */

/* LES PASTILLES DE PRODUIT ETAIENT INVISIBLES : DORE SUR DORE.
   Trouve le 4 septembre 2026 en cherchant autre chose. Mesure : #D4B97F sur
   #D4B97F — contraste 1:1, c'est-a-dire du texte de la couleur exacte de son
   fond. « N°1 des ventes », « Selection Prestige », « Bouquet Signature »,
   « Hommage delicat » : huit pastilles posees par Olivier dans Ecwid, et pas
   une seule lisible.
   L'or vient de notre variable, appliquee au fond par notre feuille ; Ecwid,
   lui, ecrit le texte dans la meme couleur d'accent. Personne ne l'avait vu
   parce qu'une pastille invisible ressemble a une pastille absente. */
.label__text,
.ec-store [class*="label__text"] {
  color: var(--nuit) !important;
}

/* « TRIER PAR », QUATRIEME ESSAI : 2,6:1 → 15,1:1. CELUI-CI TIENT.
   Les trois premiers echouaient de la meme facon : ils changeaient la couleur
   partout, alors que ce texte vit tantot sur fond clair, tantot sur fond
   sombre. Le commentaire plus haut disait quoi faire — « distinguer les zones
   claires des sombres » — sans dire comment.

   Le comment, lu dans la structure d'Ecwid le 4 septembre 2026 : ce n'est pas
   la CLASSE qui dit le fond, c'est la PAGE. Releve element par element sur les
   trois pages du tunnel, avec le fond calcule de chacun :

     .form-control__select-text   categorie 3/3 sombre · panier 4/4 sombre ·
                                  commande 1/1 sombre        → ivoire partout
     .form-control__arrow         categorie 3/3 sombre · panier 3/3 sombre ·
                                  COMMANDE 1 SUR 2 SUR BLANC → pas la commande
     .form-control__placeholder…  panier 1 sombre / 3 blancs ·
                                  commande 6/6 blancs        → gris, mais plus
                                                               fonce (voir plus bas)

   D'ou trois regles au lieu d'une. La fleche est l'exemple meme du piege :
   une seule des deux est sur blanc a l'etape adresse, et une regle « toutes
   les fleches en ivoire » l'aurait effacee. Les regles portent en (1,2,0)
   contre (1,1,0) — le gris n'est pas retire, donc les cinquante elements
   casses par le troisieme essai ne sont pas touches.

   MESURE APRES DEPOT, sur la feuille reellement en ligne : les trois passent
   a l'ivoire. « Trier par » 15,1:1, zero texte sous le seuil sur la page du
   panier.

   ET UNE LECON DE METHODE, qui a failli me faire ecrire l'inverse. Essayee
   par injection dans la console — un <style> ajoute a la volee — la regle
   semblait ne corriger que deux des trois : « Trier par » resistait meme a un
   « color: lime !important » pose en ligne sur l'element, quand son voisin
   immediat l'acceptait. J'allais consigner un echec partiel.

   Pourquoi l'injection donnait ce resultat, JE NE LE SAIS PAS. J'ai soupconne
   la regle de survol d'Ecwid ; verifie, elle ne porte pas de !important et ne
   peut donc pas battre un inline. L'hypothese est fausse, je n'en mets pas une
   autre a la place. Ce qui est etabli tient en une phrase :
   UN ESSAI PAR INJECTION NE VAUT PAS UNE MESURE APRES DEPOT. */
/* Les libelles de selecteur : sombres sur les trois pages, sans exception
   mesuree. « Trier par », « Quantite : 2 », « 1 produit », « Afficher les
   prix en ». « Quantite » est celui qu'Olivier avait signale le 4 septembre —
   « Quantite est illisible (gris fonce sur noir) » — et il l'etait encore :
   la correction d'alors n'avait porte que sur la page de categorie. */
#tunnel .ec-store__category-page .form-control__select-text,
#tunnel .ec-store__cart-page .form-control__select-text,
#tunnel .ec-store__checkout-page .form-control__select-text,
/* Les fleches : sur la categorie et le panier seulement. PAS sur la page de
   commande, ou l'une des deux est sur fond blanc. */
#tunnel .ec-store__category-page .form-control__arrow,
#tunnel .ec-store__cart-page .form-control__arrow,
#tunnel .ec-store__category-page .form-control__placeholder,
#tunnel .ec-store__category-page .form-control__placeholder-inner {
  color: var(--ivoire) !important;
}

/* ==========================================================================
   LES LIBELLES DE CHAMP ETAIENT IVOIRE SUR BLANC A L'ETAPE ADRESSE.

   Trouve le 4 septembre 2026, et personne ne l'avait vu — moi le premier :
   mon script de mesure lisait le blanc d'Ecwid, note « color(srgb 0.9825 …) »,
   comme une valeur sur 255, donc comme du noir. De l'ivoire sur du noir passe
   le seuil haut la main. Le defaut etait la depuis le debut, cache par
   l'outil cense le trouver.

   Mesure, une fois l'outil repare : « Adresse postale, appartement, suite »,
   « Ville » et « Code postal » en #EAE5DA sur #FBFBFB — 1,2:1. Ce sont les
   libelles flottants qui remontent au-dessus du champ des qu'il est rempli :
   le client saisit son adresse et les intitules disparaissent au moment ou il
   voudrait relire ce qu'il a mis ou.

   La cause n'est pas une regle mais un heritage : « #tunnel » porte
   « color: var(--ivoire) », juste sur notre fond sombre, et les libelles
   d'Ecwid n'ont pas de couleur propre. Ils prennent donc l'ivoire ou qu'ils
   soient. Les trois mesures sont toutes sur fond blanc, aucune sur sombre :
   la regle porte sur les deux pages du tunnel, pas plus loin.
   ========================================================================== */
#tunnel .ec-store__checkout-page .form-control__label,
#tunnel .ec-store__cart-page .form-control__label {
  color: var(--nuit) !important;
}

/* ==========================================================================
   LE GRIS DES INDICES DE SAISIE : ON N'Y TOUCHE PAS, ET VOICI POURQUOI.

   J'ai failli l'eclaircir. Mon script de mesure donnait neuf libelles a 2,9:1
   sur le blanc d'Ecwid — « Votre adresse mail », « Entrez votre code promo »,
   « Adresse postale », « Ville », « Code postal », « Veuillez selectionner un
   pays » — et j'ai pose #6B6B73 pour les remonter.

   LE CHIFFRE ETAIT FAUX, ET MA CORRECTION AGGRAVAIT LES CHOSES.
   Ecwid rend ce blanc en notation « color(srgb 0.9825 0.9825 0.9825) ».
   Mon script lisait 0,9825 comme une valeur sur 255 et prenait donc ce blanc
   pour du noir. Mesure refaite en laissant le navigateur convertir la
   couleur — un canvas, pas une expression reguliere :

     #56565E sur ce blanc   7,03:1   (annonce a tort : 2,9)
     #6B6B73 sur ce blanc   5,10:1   ma « correction »

   Le gris d'origine passait largement le seuil ; ce que j'avais pose le
   faisait descendre de deux points. Retire. Les mesures sur fond sombre,
   elles, tenaient — la notation « rgb(16, 16, 18) » se lit sans piege, et
   « Quantite : 2 » etait bien a 2,61:1.

   LA LECON, plus utile que la regle : un chiffre produit par un outil qu'on
   a ecrit soi-meme n'est pas une mesure tant qu'on ne l'a pas confronte a un
   calcul independant. Celui-ci a failli faire degrader ce qu'il fallait
   laisser.
   ========================================================================== */

/* ==========================================================================
   LE CONSENTEMENT DEVENAIT INVISIBLE AU MOMENT OU IL BLOQUAIT LA COMMANDE.

   Trouve le 4 septembre 2026 en parcourant le tunnel avec un panier reel.
   Quand le client oublie de cocher « J'accepte les Conditions generales »,
   Ecwid surligne le bloc en jaune pale (#F1FFA6) pour attirer l'oeil. Notre
   texte y est ivoire et nos liens dores :

     « J'accepte »              #EAE5DA sur #F1FFA6   1,2:1
     « Conditions generales »   #D4B97F sur #F1FFA6   1,8:1
     « Declaration de confidentialite »               1,8:1

   1,2:1, c'est du texte de la couleur de son fond. Le client voit une case a
   cocher, un rectangle jaune vide, et un bouton qui refuse d'avancer : il ne
   peut meme pas lire ce qu'on lui demande d'accepter. C'est le pire endroit
   possible pour un texte invisible — celui ou la commande s'arrete.

   Le surlignage est un ETAT, pas un style permanent : Ecwid le pose sous
   « .ec-cart__checkout--highlight » et sous le survol de
   « --need-agreement ». On ne repeint donc que cet etat ; hors surlignage, le
   bloc reste ivoire sur notre fond sombre, ou il est juste. Les liens gardent
   leur soulignement pour rester reconnaissables sans la couleur.
   ========================================================================== */
#tunnel .ec-cart__checkout--highlight .form-control--required .form-control__inline-label,
#tunnel .ec-cart__checkout--highlight .form-control--required .form-control__inline-label *,
#tunnel .ec-cart__checkout--need-agreement:hover .ec-cart__agreement:not(:hover) .form-control--required .form-control__inline-label,
#tunnel .ec-cart__checkout--need-agreement:hover .ec-cart__agreement:not(:hover) .form-control--required .form-control__inline-label * {
  color: var(--nuit) !important;
}
/* LES DEUX LIENS RESISTAIENT, ET LA REGLE QUI GAGNAIT N'EST PAS DANS CE
   FICHIER. Le soulignement prenait, la couleur non — signe qu'une declaration
   plus specifique tenait l'or. Cherchee dans charte.css : rien. Trouvee dans
   « ecwid-css-complet.css », le CSS colle par Olivier dans la console Ecwid,
   servi par Ecwid donc APRES le notre :

     html#ecwid_html body#ecwid_body .ec-size .ec-store .ec-link,
     html#ecwid_html body#ecwid_body .ec-size .ec-store a { color: #d4b97f !important }

   Deux identifiants, soit (2,3,1) : aucune regle a un seul « #tunnel » ne peut
   passer devant, quel que soit le nombre de classes empilees. Ecwid pose bien
   ces identifiants sur html et body de notre page — verifie.

   On reprend donc les deux memes identifiants. La regle ne vaut que dans le
   bloc de consentement surligne : partout ailleurs l'or reste l'or. */
html#ecwid_html body#ecwid_body #tunnel .ec-cart__checkout--highlight .form-control--required .form-control__inline-label .ec-link,
html#ecwid_html body#ecwid_body #tunnel .ec-cart__checkout--need-agreement:hover .ec-cart__agreement:not(:hover) .form-control--required .form-control__inline-label .ec-link {
  color: var(--nuit) !important;
  text-decoration: underline !important;
}

/* ==========================================================================
   LE TUNNEL PREND LA LARGEUR DE LA PAGE, PAS CELLE D'UN ARTICLE.

   Olivier, apres sa commande d'essai reussie (n° AO26313) : « on peut faire
   le message de confirmation plus large ? ».

   Mesure : « main.contenu » porte un « max-width: 760px ». C'est la largeur de
   lecture des pages de texte, et elle est juste pour un article — au-dela
   d'une soixantaine de caracteres par ligne, l'oeil perd le debut de la
   suivante. Mais une confirmation de commande n'est pas un article : c'est un
   recapitulatif avec un plan, une adresse, une liste d'articles et leurs
   options. Serre a 760 px moins les marges, chaque ligne se casse en trois.

   Le tunnel ne s'affiche jamais en meme temps que le texte de la page : il le
   remplace. Rien ne se bouscule donc quand il s'elargit. */
.contenu:has(#tunnel) {
  max-width: 1180px;
}
/* La confirmation elle-meme respire : Ecwid y empile un plan et un
   recapitulatif dans une colonne unique. */
#tunnel .ec-confirmation,
#tunnel [class*="confirmation"] { max-width: none; }

@media (max-width: 1240px) {
  .contenu:has(#tunnel) { max-width: none; }
}

/* LE MESSAGE D'ECWID SUR LES OPTIONS MODIFIEES.
   Il s'affiche en haut a droite, en gris tres clair sur blanc, et il est
   illisible. Son contenu compte pourtant : il dit qu'une option du panier
   n'existe plus au catalogue — c'est le genre de chose qu'on veut lire. */
.ec-notice, .ec-notice__body, .ec-notice__text,
[class*="ec-notice"] .ec-text-muted,
[class*="notice"] [class*="text"] {
  color: #2A2A31 !important;
}

/* LE COUPON EXISTE, MAIS IL N'A PAS L'AIR D'EXISTER.
   Olivier, pendant sa commande d'essai : « aucun endroit pour mettre le coupon
   de réduction ». Mesure faite : « Appliquer un coupon promotionnel » est bien
   present et visible — mais c'est un TITRE. Le champ ne s'ouvre qu'au clic, et
   rien ne dit qu'on peut cliquer.
   Un client qui a un code et ne trouve pas ou le mettre ne cherche pas
   longtemps : il abandonne, ou il telephone. On donne donc a ce titre
   l'apparence de ce qu'il est — une commande. */
/* LE COUPON DE LA COLONNE DE GAUCHE EST MASQUE PAR ECWID LUI-MEME.
   Regle relevee dans sa feuille : « .ec-size:not(.ec-size--s) .ec-store
   .ec-cart__sidebar .ec-cart-coupon { display: none } ». Sur grand ecran, le
   champ vit dans la colonne principale ; le titre de gauche reste, sans son
   champ, et ne sert donc qu'a egarer. On le retire.
   Le vrai champ, lui, fonctionne : verifie le 4 septembre 2026. */
.ec-cart__sidebar .ec-cart__credits-and-coupons { display: none; }

/* LE COUPON REDEVIENT UTILISABLE SUR ORDINATEUR.
   Relevé le 6 septembre 2026 dans le tunnel réel : sur grand écran, Ecwid
   masque le déclencheur « Coupon promotionnel / Échanger » dans LES DEUX
   copies qu'il produit — celle de la colonne et celle du corps — ainsi que le
   formulaire qui devrait se déplier. Il ne restait que le titre, sans rien
   dessous. C'est ce qu'Olivier décrit depuis le 4 septembre : « aucun endroit
   pour mettre le coupon ».

   IL FAUT LES DEUX RÈGLES, ET C'EST TOUT L'ENJEU. Le déclencheur seul se
   replie au clic sans rien ouvrir — mesuré : le formulaire reste à zéro de
   haut, parce que son conteneur est masqué et que l'animation d'Ecwid n'a rien
   à révéler. Le formulaire seul s'affiche en permanence, ce qui rappelle à qui
   n'a pas de code qu'il existe des réductions et l'invite à quitter la page
   pour en chercher une. Ensemble, ils rendent le comportement d'origine :
   on clique, le champ s'ouvre.

   Vérifié après correction : le clic ouvre le champ à 565 × 39, la saisie fait
   473 × 32, et le bouton d'Ecwid porte déjà le mot « Appliquer ».

   J'avais d'abord écrit ici qu'aucune classe d'état ne permettait de viser
   l'état ouvert. C'était faux : Ecwid ne pose pas de classe, il bascule la
   « visibility » de « .ec-cart-coupon__wrap ». On n'a donc rien à viser — il
   suffit de ne plus masquer ce qu'il veut montrer. */
.ec-cart__step .ec-cart__discount > .ec-cart__coupon,
.ec-cart__step .ec-cart-discount-group > .ec-cart__coupon { display: block !important; }

/* « ÉCHANGER » DEVIENT « APPLIQUER » — Olivier, le 6 septembre 2026.
   Le mot ne se change pas depuis une feuille de style : on masque le sien et
   l'on écrit le nôtre à la place. Le lien reste le lien, donc le clic reste le
   clic — c'est ce qui distingue cette correction de celle du 4 septembre, qui
   avait masqué tout le libellé et cassé la fonction.
   Le remède durable est ailleurs : dans les réglages de langue d'Ecwid, là où
   le mot est lu. Inscrit dans ECWID-A-MODIFIER.md. Ceci tient d'ici là. */
/* LE COUPON TIENT LE BORD GAUCHE — Olivier, le 6 septembre 2026 :
   « "Coupon promotionnel appliquer" il faut le justifier à gauche ».
   « start » et non « left » : dans le tunnel arabe, le bord de départ est à
   droite, et forcer la gauche y mettrait la ligne à contresens du reste.
   Je n'ai PAS pu reproduire le décalage dans l'émulateur — sur la page panier
   le libellé commence déjà au bord, à 647 px comme ses voisins. La règle est
   donc défensive : elle nomme le comportement voulu partout où le bloc peut
   apparaître, plutôt que de corriger un endroit que je n'ai pas vu. À
   confirmer d'un coup d'œil sur l'écran où Olivier l'a vu. */
.ec-cart__discount,
.ec-cart__coupon,
.ec-cart-coupon__text {
  text-align: start !important;
  justify-content: flex-start !important;
}

.ec-cart-coupon__text .ec-link { font-size: 0 !important; }
.ec-cart-coupon__text .ec-link::after {
  content: "Appliquer"; font-size: 14px;
}

/* LE BOUTON « REVENIR AU PANIER » N'EST PAS UN BOUTON D'ACHAT.
   Olivier, le 6 septembre 2026 : « le bouton "revenir au panier" est
   grossier ». Mesuré : fond ivoire plein, texte sombre — l'apparence du bouton
   de paiement, pour un lien de retour. La cause n'était pas Ecwid mais NOUS :
   « #tunnel button » vaut (0,1,1) et écrasait « .retour-panier » (0,1,0). Ce
   filet de sécurité existe pour le cas où la feuille d'Ecwid n'arrive pas ; il
   exclut maintenant notre propre bouton.
   Deux niveaux de plein sur un même écran se disputent le regard, et celui
   qu'on veut voir gagner est « Continuer ». */
#tunnel .retour-panier, .ec-store .retour-panier {
  background: none; color: var(--argent);
  border: 0; border-bottom: 1px solid rgba(198, 202, 208, .3);
  border-radius: 0; box-shadow: none;
  padding: 10px 0; min-height: 0; width: auto;
  font-family: var(--jost); font-size: 13.5px; letter-spacing: .06em;
  text-transform: none;
}

/* LE TITRE ORPHELIN DISPARAIT — 6 septembre 2026.
   Olivier : « il y a une ligne "Appliquer un coupon promotionnel" soulignée où
   il ne se passe rien quand on clique dessus et qui est redondant avec "Coupon
   promotionnel Échanger" ». Il a raison sur les deux points, et la mesure le
   confirme : c'est un TITRE, pas une commande — lui donner un curseur de main,
   comme je l'avais fait le 4 septembre, ne faisait qu'aggraver la promesse.
   On le retire partout ; le contrôle qui suit porte déjà son propre libellé. */
.ec-cart__credits-and-coupons--title { display: none !important; }

/* LE RETOUR AU PANIER, pose par « mesure.js » en tete du tunnel. Il n'existe
   pas sur la page panier, ou il n'aurait pas de sens. */
.retour-panier {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0 0 22px; padding: 10px 0;
  background: none; border: 0; cursor: pointer;
  font-family: var(--jost); font-size: 13.5px; letter-spacing: .06em;
  color: var(--argent);
  border-bottom: 1px solid rgba(198, 202, 208, .3);
}
.retour-panier::before { content: "‹"; font-size: 17px; line-height: 1; }
@media (hover: hover) {
  .retour-panier:hover { color: var(--ivoire); border-bottom-color: var(--ivoire); }
}

/* ==========================================================================
   LE BANDEAU DEVIENT UN CHEMIN D'ETAPES.

   Olivier, pendant sa commande d'essai : « encore trop petites et il faut les
   numeroter comme des etapes, et meme les changer de couleur quand l'etape
   est faite. Du coup il manque l'etape actuelle, entrez votre adresse
   e-mail ».

   Trois choses, donc, et la troisieme etait la plus grave : l'etape qui
   manquait etait LA PREMIERE. Ecwid demande le courriel avant tout, et le
   bandeau commencait a l'adresse — le client voyait trois cases dont aucune ne
   decrivait ce qu'il faisait a l'instant.

   Le quatrieme element a fait passer le texte a 12,5 px sur telephone. Il
   remonte a 14, et le numero porte desormais le repere : on lit « 2 » avant de
   lire la phrase, ce qui est plus rapide que de compter les cases.
   ========================================================================== */
.rassure li { font-size: 14.5px; padding: 14px 16px; flex: 1 1 200px; }
.rassure li:nth-child(4) { animation-delay: .47s; }

.rassure .r-num {
  flex: 0 0 auto;
  width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--ligne-2);
  font-family: var(--jost); font-size: 12px; letter-spacing: 0;
  color: var(--cendre);
  transition: background .2s, color .2s, border-color .2s;
}

/* CE QUI EST DERRIERE SOI. Le numero cede la place a une coche : on n'a plus
   besoin de savoir que c'etait la deuxieme, seulement que c'est fait. */
.rassure li.faite { border-color: rgba(160, 200, 160, .32); }
.rassure li.faite .r-num {
  background: #7FBF7F; border-color: #7FBF7F; color: var(--nuit);
  font-size: 0;
}
.rassure li.faite .r-num::after { content: "✓"; font-size: 13px; }
.rassure li.faite .r-mot { color: var(--cendre); }
.rassure li.faite svg { opacity: .5; }

/* L'ETAPE EN COURS. Elle se distingue par le fond, pas par la couleur du
   texte : c'est le contraste le plus fort dont on dispose, et il se voit du
   coin de l'oeil pendant qu'on remplit un champ. */
.rassure li.ici {
  border-color: var(--argent);
  background: #1B1B21;
}
.rassure li.ici .r-num {
  background: var(--ivoire); border-color: var(--ivoire); color: var(--nuit);
}
.rassure li.ici .r-mot { color: #FFFDF6; }

@media (max-width: 620px) {
  /* Quatre etapes sur un telephone : deux par ligne, et le texte reste lisible
     — c'etait le premier reproche d'Olivier. */
  .rassure { gap: 8px; }
  .rassure li { flex: 1 1 calc(50% - 8px); font-size: 13px; padding: 11px 12px;
                gap: 8px; }
  .rassure li svg { display: none; }
}
.ec-cart__credits-and-coupons--title {
  color: var(--argent) !important;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
@media (hover: hover) {
  .ec-cart__credits-and-coupons--title:hover { color: var(--ivoire) !important; }
}

/* ==========================================================================
   LE MENU, SANS BOITE — 4 septembre 2026
   ==========================================================================

   Olivier : « oublie pour le bouton mariage, c'est moche. On va tester deux
   lignes de filet sans boite. » Puis, devant le resultat : « il manque encore
   un truc, je n'arrive pas a savoir quoi mais quelque chose me gene ».

   DEUX DEFAUTS, et tous deux se voient une fois nommes.

   1. LE FILET SOULIGNAIT LA CASE, PAS LE MOT. Les cases sont de largeur
      egale, les mots non : le trait depassait de six pixels sous « Deuil » et
      d'aucun sous « Créations ». On ne lisait plus cinq mots soulignes mais
      une ligne pointillee cassee en cinq segments inegaux. Le filet vit
      desormais sur un span, qui fait la largeur du texte et rien de plus.

   2. TROIS POLICES SUR LA SECONDE LIGNE. Cinzel pour Oscendence, Cormorant
      pour Mariage, Jost pour Evenements : trois caracteres pour trois mots
      voisins, ce qui donne trois sites cote a cote. Elles avaient un sens
      quand chaque entree etait une pastille coloree — un objet distinct porte
      sa propre typographie. Sans boite, elles n'ont plus rien pour les
      separer, et la difference devient du desordre.

      Tout le menu passe donc a la police de la maison. Oscendence garde sa
      distinction, mais par la COULEUR et l'interlettrage seulement : c'est
      assez pour dire « autre marque », et cela ne casse pas la ligne.

   Ce bloc est en fin de fichier A DESSEIN : le bloc telephone porte le meme
   selecteur « .entete .nav a » et recouvrait six fois de suite les regles
   posees plus haut. Ce qui concerne le menu s'ecrit ici, en dernier.
   ========================================================================== */

.entete .nav a,
.entete .nav a.osc,
.entete .nav a.mar,
.entete .nav a.eve {
  background: none;
  background-image: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 7px 2px 6px;
  min-height: 38px;
  /* UNE SEULE POLICE POUR TOUT LE MENU. */
  font-family: var(--jost);
  font-weight: 400;
  /* 13 px → 15 px, le 4 septembre 2026. Olivier : « sur ordinateur le texte du
     menu est très petit ». Mesure : 13 px pour le menu principal quand le
     texte courant de la page est à 16 px et les noms de produits à 18. Le
     menu se lisait donc comme une mention légale alors que c'est le premier
     chemin du site. Sur téléphone, le bloc plus bas garde 12,5 px : la ligne
     y défile et chaque pixel gagné en largeur coûte une entrée visible. */
  /* 15 px → 17 px, le 5 septembre 2026, sur la meme remarque d'Olivier :
     « c'est l'occasion pour augmenter la police (sur ordi au moins) ». Les
     noms de produits sont a 18 px ; le menu, qui est le premier chemin du
     site, n'a aucune raison d'etre plus discret qu'eux. Sous 620 px le bloc
     plus bas garde 12,5 px : la ligne y defile, et chaque pixel de largeur
     coute une entree visible. */
  font-size: 17px;
  letter-spacing: .07em;
  color: #DCD7CD;
}

/* Le filet : sur le mot, et lui seul. */
.entete .nav a > span {
  display: inline-block;
  padding-bottom: 5px;
  border-bottom: 1px solid rgba(198, 202, 208, .26);
  transition: border-color .16s ease-out, color .16s ease-out;
}
.entete .nav a:hover { color: #FFFDF6; }
.entete .nav a:hover > span { border-bottom-color: rgba(226, 231, 237, .75); }

/* Oscendence : l'or, et rien d'autre. Pas de police propre — la couleur suffit
   a dire qu'on quitte la maison pour une autre marque, et elle ne casse pas
   l'alignement de la ligne. */
.entete .nav a.osc { color: var(--or); letter-spacing: .12em; }
.entete .nav a.osc > span { border-bottom-color: rgba(212, 185, 127, .5); }
.entete .nav a.osc:hover { color: #E7CE8A; }
.entete .nav a.osc:hover > span { border-bottom-color: rgba(231, 206, 138, .9); }

/* Mariage et Evenements : la seconde ligne se distingue par un texte un rien
   plus clair, pas par une autre police. */
.entete .nav a.mar, .entete .nav a.eve { color: #EFEAE0; }
.entete .nav a.mar > span, .entete .nav a.eve > span {
  border-bottom-color: rgba(226, 231, 237, .38);
}

@media (max-width: 620px) {
  /* LA SECONDE LIGNE ETAIT TROP BASSE. Elle heritait de deux ecarts qui
     s'additionnaient : l'interligne de la rangee et la marge de la coupure.
     On garde la coupure — c'est elle qui separe la boutique des trois autres
     metiers — mais reduite a ce qu'il faut pour qu'on la voie, pas davantage. */
  .entete .nav { gap: 2px 4px; padding: 12px 8px 14px; }
  .entete .nav .nav-coupe { margin-top: 4px; }
  .entete .nav a { font-size: 12.5px; letter-spacing: .05em; padding: 7px 1px 6px; }
  .entete .nav a.osc { letter-spacing: .1em; }
  .entete .nav a > span { padding-bottom: 4px; }
}

/* ==========================================================================
   LE MENU GLISSANT — essai demande par Olivier le 4 septembre 2026, « pour
   gagner de la place ».

   Une seule ligne qui defile au doigt, au lieu de deux lignes empilees.

   CE QU'ON Y GAGNE : la hauteur d'une rangee sur telephone.

   CE QU'ON Y PERD, et qu'il faut avoir mesure avant de trancher : les huit
   entrees ne tiennent pas dans 375 px. Celles qui sortent du champ sont les
   dernieres — donc Oscendence, Mariage et Evenements, c'est-a-dire
   exactement les trois qu'Olivier veut faire ressortir.

   ET LE RISQUE QUI PRIME : personne ne fait glisser ce qu'il ne soupconne
   pas. C'est deja ecrit dans ce fichier, a propos du carrousel du mariage.
   D'ou les deux precautions ci-dessous, qui ne sont pas decoratives :

   - LE DERNIER LIBELLE VISIBLE EST COUPE PAR LE BORD. Un menu qui s'arrete
     pile au bord dit qu'il est fini ; un mot tranche dit qu'il continue.
   - UN VOILE SOMBRE sur le bord droit rend la coupe volontaire plutot
     qu'accidentelle, et il s'efface des qu'on est arrive au bout.

   Le defilement est en CSS seul. Sans JavaScript on fait glisser au doigt,
   a la molette et au clavier — la fonction en CSS, le confort en JS.
   ========================================================================== */
@media (max-width: 620px) {
  .entete .nav {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* MESURE, PAS IMPRESSION. A 20 px d'ecart et 18 px de marge, le menu
       s'arretait pile apres « Plantes » : rien ne debordait, donc rien ne
       disait qu'il y avait une suite, et les trois entrees suivantes
       n'existaient plus pour personne. Resserre, « Oscendence » entame le
       champ et sa coupe fait tout le travail. */
    gap: 0 15px;
    padding: 10px 10px 11px;
    /* Le voile du bord droit. « mask-image » n'agit que sur ce qui deborde :
       arrive au bout, le dernier mot est net. */
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 34px), transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 34px), transparent 100%);
  }
  .entete .nav::-webkit-scrollbar { display: none; }
  .entete .nav a {
    flex: 0 0 auto;
    max-width: none;
    scroll-snap-align: start;
    padding: 7px 0 6px;
  }
  /* LES TROIS DERNIERS SE CHEVAUCHAIENT, ET LE PIEGE EST TOUJOURS LE MEME.
     Le bloc telephone pose « .entete .nav a.osc », de specificite (0,3,1), et
     leur donne « flex: 1 1 0 » avec « max-width: 33.33% » — parfait pour une
     rangee qui se partage la largeur, ruineux pour une ligne qui defile : les
     trois libelles se compressaient a un tiers d'ecran chacun tout en refusant
     de se couper, et « Oscendence », « Mariage » et « Evenements » s'ecrivaient
     par-dessus les uns les autres.
     Ma regle ne portait que « .entete .nav a », a (0,2,1) : elle perdait.
     Constate par Olivier sur son telephone, capture a l'appui. C'est la
     septieme fois que ce bloc recouvre une regle posee ailleurs. */
  .entete .nav a.osc,
  .entete .nav a.mar,
  .entete .nav a.eve {
    flex: 0 0 auto;
    max-width: none;
    margin: 0;
  }
  /* La coupure redevient ce qu'elle etait sur grand ecran : un filet vertical.
     En pleine largeur elle cassait la ligne en deux, ce qui est precisement ce
     qu'on cherche a eviter ici. */
  .entete .nav .nav-coupe {
    flex: 0 0 1px; width: 1px; height: 15px; align-self: center;
    margin: 0 6px;
    background: linear-gradient(180deg, transparent 0%, var(--ligne) 30%,
                var(--ligne) 70%, transparent 100%);
  }
}

/* ==========================================================================
   L'EN-TETE SE RESSERRE — demande d'Olivier le 4 septembre 2026 : « gagner
   un peu d'affichage produit ».

   Ce qu'on reprend, et ou : ce sont des marges, jamais des tailles. Le logo
   garde sa dimension, le numero garde la sienne, les zones tactiles gardent
   leurs 44 px — c'est le VIDE ENTRE LES CHOSES qui se reduit, pas les choses.

   MESURE AVANT : sur un ecran de 375 px, la premiere carte produit commencait
   a 639 px. Plus des trois quarts de l'ecran occupes avant qu'on voie une
   fleur.

   Le detail est ecrit ligne a ligne : sans cela, la prochaine fois qu'on
   cherchera d'ou vient un tassement, il faudra relire tout le fichier.
   ========================================================================== */
@media (max-width: 620px) {
  /* Le numero et WhatsApp servent a la meme chose — joindre un fleuriste — et
     neuf pixels d'ecart les faisaient lire comme deux commandes distinctes.
     Ils se touchent presque maintenant ; leurs zones tactiles, elles, ne
     bougent pas : le padding de chaque lien les tient ecartees de huit pixels,
     au-dessus du seuil ou le doigt se trompe de cible. */
  .outils-centre { gap: 2px; }

  /* Douze pixels sous la rangee d'outils, deux au-dessus. Ce bas ne servait
     qu'a l'ancienne mise en page, ou les outils fermaient l'en-tete ; ils ont
     maintenant leur propre rang, avec son filet pour le clore. */
  .rang-outils .outils { padding: 1px 4px 3px; }

  /* Quatorze pixels au-dessus du logo — c'est le vide qu'Olivier voit entre le
     numero et la marque. Il n'a pas de raison d'etre : le filet du rang
     au-dessus separe deja les deux. */
  .entete { padding-top: 5px; }

  /* Le menu rend deux pixels en haut et en bas, pas davantage : sous 38 px de
     haut, une entree cesse d'etre une cible confortable au doigt. */
  .entete .nav { padding: 8px 10px 9px; }
}

/* LE NUMERO ETAIT UNE CIBLE TROP PETITE, ET IL L'ETAIT DEJA AVANT.
   Mesure au doigt emule : panier 44 px, langue 44 px, telephone 37, WhatsApp
   39. La regle qui garantit les 44 px vise « .outils > a » ; ces deux-la sont
   dans « .outils-centre », donc enfants au second degre — elle ne les
   atteignait pas.

   Ce n'etait pas urgent tant que neuf pixels les separaient. En les
   resserrant a deux, deux cibles trop petites deviennent voisines, et le
   doigt se trompe. Or c'est le NUMERO D'UN FLEURISTE sur un telephone : la
   commande la plus utile de la page, comme l'ecrit deja ce fichier plus haut.

   Mesure : cela ne coute AUCUN pixel de hauteur — le rang en fait deja 48 a
   cause du panier. La premiere carte produit reste a 616 px. */
@media (pointer: coarse) {
  .outils-centre > a { min-height: 44px; }
}

/* LE LOGO REMONTE ENCORE — second passage, 4 septembre 2026.
   Mesure : il ne restait que CINQ pixels entre la rangee d'outils et le haut
   du logo. Le vide etait epuise ; ce qui suit se prend donc sur le bloc de
   marque lui-meme, et c'est une decision d'identite, pas de mise en page.

   Le logo passe de 240 a 208 px de large sur telephone, sa hauteur suit
   (53 -> 46). C'est la taille qu'il avait deja sous 620 px avant qu'une regle
   posterieure ne le rende a 240. Il reste tres lisible : le monogramme est un
   trait fin, et c'est sous 40 px de haut qu'il devient une tache — on s'arrete
   bien au-dessus.

   Dire ce que cela rapporte, parce que c'est modeste : une douzaine de pixels.
   L'en-tete a rendu tout ce qu'elle pouvait sans toucher a ce qui se lit. */
@media (max-width: 620px) {
  /* CENT DIX PIXELS DE MARGE A DROITE, herites du bandeau de service : ils y
     reservent la place de la bulle d'assistance, qui se pose en haut a droite
     SUR ORDINATEUR. Sur telephone elle descend dans le coin bas, a portee du
     pouce — la marge ne protege donc plus rien et ne fait que comprimer la
     rangee vers la gauche. Le numero cessait d'etre centre sur le logo, et le
     bouton du menu passait sous lui. */
  .rang-outils { padding: 0 10px; }
  .rang-outils .outils { padding: 0 4px 2px; }
  .entete { padding-top: 3px; }
  .entete .marque,
  .entete .marque .mono { width: 208px; }
  .entete .marque { gap: 0; margin-bottom: 0; }
  .entete .marque .nom { font-size: 11px; letter-spacing: .18em;
                         padding-left: .18em; }
}

/* LE NUMERO SE CENTRE SUR LE LOGO, ET L'ICONE WHATSAPP NE COMPTE PAS.
   Demande d'Olivier le 4 septembre 2026.

   Le defaut, invisible tant qu'on ne le cherche pas : le bloc centre contenait
   le numero ET l'icone, et c'est ce BLOC qui etait centre. Le numero se
   trouvait donc decale vers la gauche de la moitie de l'icone plus l'ecart —
   une vingtaine de pixels — et ne tombait pas d'aplomb sur le monogramme
   juste en dessous. Deux elements presque alignes se lisent moins bien que
   deux elements franchement decales : l'oeil corrige tout seul un decalage
   assume, il bute sur un ratage.

   L'icone sort donc du flux et se pose a droite du numero. Elle ne pese plus
   rien dans le calcul, et sa zone tactile ne bouge pas.

   LE MILIEU SE CENTRE PAR POSITION ABSOLUE, et pas par une grille. La
   premiere version posait « grid-template-columns: 1fr auto 1fr », ce qui
   centre bien tant qu'il y a trois enfants — le bouton du menu replie en a
   fait un quatrieme, la case surnumeraire est passee a la ligne suivante, et
   la rangee a double de hauteur : 46 px devenus 102.

   En absolu, le centrage ne depend ni du nombre d'elements autour ni de leur
   largeur. C'est ce qu'il fallait ici, ou la gauche porte un bouton et la
   droite deux commandes. */
/* LE REPERE DU CENTRAGE EST LE RANG, PAS LA RANGEE D'OUTILS.
   La rangee porte 110 px de marge a droite et 20 a gauche — la place reservee
   a la bulle d'assistance, qui est en position fixe dans le coin haut droit et
   recouvre bien cette hauteur (mesure : elle occupe 12 a 94 px, le rang va de
   38 a 113). Centrer sur une boite aux marges inegales decalait le numero de
   quarante-cinq pixels vers la gauche sur ordinateur, et il ne tombait plus
   sur le logo. Le rang, lui, tient toute la largeur. */
.rang-outils { position: relative; }
.rang-outils .outils {
  display: flex !important;
  align-items: center;
  /* EXPLICITE, PARCE QU'UNE REGLE PLUS HAUT DIT « center ». Laissee en place,
     elle groupait le panier au milieu, ou il passait sous le numero centre :
     deux elements superposes, et aucun des deux lisible. */
  justify-content: flex-start;
  position: static;
  gap: 10px;
}
.rang-outils .outils > .outils-centre {
  position: absolute; left: 50%; transform: translateX(-50%);
  justify-self: auto;
}
/* Sur ordinateur, le panier reste a gauche et pousse la langue au bord. */
.rang-outils .outils > .panier { margin-right: auto; }
.rang-outils .outils-centre .wa {
  position: absolute;
  left: calc(100% + 6px);
  top: 50%;
  transform: translateY(-50%);
}

/* ==========================================================================
   LE MENU SE REPLIE SOUS 700 PX — decide avec Olivier le 4 septembre 2026.

   POURQUOI 700 ET PAS 620. Mesure faite : avec « Ultra Luxe Oscendence », la
   ligne tient sans defiler jusqu'a 700 px de large. En dessous, « Evenements »
   sort du champ. Le seuil suit donc ce que la mesure donne, pas un chiffre
   rond.

   POURQUOI ON PEUT SE PERMETTRE DE CACHER LE MENU, alors que la regle
   generale dit de ne pas cacher le chemin d'achat. Le chiffre qui tranche :
   sur 28 jours, 18 315 sessions mobiles, dont 16 569 entrent par l'accueil —
   NEUF SUR DIX. Or l'accueil affiche « Nos collections » en grand, juste sous
   l'en-tete. Sur telephone, le chemin d'achat n'est donc pas le menu : c'est
   cette grille. Le menu sert a la navigation d'un rayon a l'autre, ce qui
   vient apres.

   CE QUE LE REPLI FAIT GAGNER : la rangee entiere du menu, cinquante-six
   pixels, sur un ecran ou l'en-tete en occupait deux cents.

   SANS JAVASCRIPT, RIEN NE SE REPLIE. La feuille ne cache le menu que sous
   « .js », classe posee dans la tete du document. Personne ne se retrouve
   devant un bouton qui n'ouvre rien.
   ========================================================================== */

/* Au-dessus de 700 px le bouton n'existe pas. */
.burger { display: none; }

@media (max-width: 700px) {
  .burger {
    display: inline-flex; align-items: center; gap: 7px;
    min-height: 44px; padding: 0 4px 0 0;
    background: none; border: 0; cursor: pointer;
    font-family: var(--jost); font-size: 13px; letter-spacing: .08em;
    color: #DCD7CD;
  }
  .burger-mot { text-transform: uppercase; }
  .burger svg { flex: 0 0 auto; }
  /* Le bouton prend la gauche, le panier et la langue se rejoignent a droite.
     C'est la disposition que tout le monde connait, et elle libere la gauche
     pour la seule commande qui ouvre quelque chose. */
  .burger { margin-right: 0; }
  .rang-outils .outils > .panier { margin-right: 0; margin-left: auto; }

  /* WHATSAPP PASSE A GAUCHE DU NUMERO, et le calcul le commande.
     Sur 375 px : bouton 69, numero 117, WhatsApp 25, panier 36, langue 59 —
     306 px de contenu. Le numero devant rester centre sur le logo, il occupe
     129 a 246, ce qui ne laisse que 129 px a droite pour trois elements qui en
     demandent 140 : l'icone tombait sur le panier.
     A gauche, elle se loge dans les quarante-six pixels libres entre le bouton
     et le numero, et les deux restent aussi proches qu'Olivier les voulait. */
  .rang-outils .outils-centre .wa {
    left: auto;
    right: calc(100% + 6px);
  }

  /* LE MENU DEPLIE TOMBE SOUS L'EN-TETE, il ne la pousse pas vers le bas.
     Pousser ferait sauter la page entiere a chaque ouverture, et le pouce qui
     vient de toucher le bouton se retrouverait a viser autre chose. */
  .js .entete .nav { display: none; }
  .js[data-menu="ouvert"] .entete .nav {
    display: flex; flex-direction: column; align-items: stretch;
    gap: 0; padding: 4px 0 10px;
    mask-image: none; -webkit-mask-image: none;
    overflow: visible;
  }
  .js[data-menu="ouvert"] .entete .nav a {
    flex: 0 0 auto; max-width: none; text-align: left;
    padding: 11px 20px; min-height: 48px;
    justify-content: flex-start; align-items: baseline;
    border-bottom: 1px solid rgba(198, 202, 208, .1);
  }
  /* Le filet du menu en ligne soulignait le mot ; deplie, chaque entree a deja
     sa ligne de separation, et deux traits pour une seule entree font sale. */
  .js[data-menu="ouvert"] .entete .nav a > span { border-bottom: 0; padding-bottom: 0; }
  .js[data-menu="ouvert"] .entete .nav .nav-coupe {
    flex: 0 0 auto; width: auto; height: 1px; margin: 7px 20px;
    background: var(--ligne);
  }
  /* Les deux ou trois mots qui disent ce que le metier vend. Ils ne
     s'affichent QUE deplies : en ligne, ils n'auraient pas la place, et un
     libelle a deux etages dans une barre horizontale ne se lit pas. */
  .js[data-menu="ouvert"] .entete .nav .nav-quoi {
    display: inline; margin-left: 10px;
    font-size: 12px; letter-spacing: .02em; color: #8E887C;
  }
}

/* Partout ailleurs, la description ne s'affiche jamais. */
.nav-quoi { display: none; }

/* ==========================================================================
   UNE SEULE GOUTTIERE POUR TOUTES LES BANDES DE L'EN-TETE.

   Olivier, le 5 septembre 2026 : « il faut sur ordi que le panier, la langue
   et le bandeau de menu soient alignés sur les marges générales des catégories
   et autre. Il faut que tout soit aligné. »

   MESURE AVANT CORRECTION, a 1600 px — chaque bande commencait ailleurs :

       contenu (titres, cartes, pied)     113 px      <- la reference
       bandeau de service                 110 px
       bouton Panier                      133 px
       premier lien du menu                48 px
       selecteur de langue (a droite)     238 px

   Cinq bandes, cinq marges. Et la rangee d'outils n'etait meme pas centree :
   20 px a gauche, 110 a droite — l'ecart se voyait sans rien mesurer.

   D'OU VIENT LE 113. « .section » porte « max-width: 1440px », centre, plus
   40 px de remplissage : sa colonne de texte fait donc 1360 px de large. A
   1600 px de fenetre, elle commence a 113. Ce n'est pas un nombre a recopier —
   il change avec la fenetre — mais une COLONNE a partager.

   LA FORMULE. « max(40px, calc((100% - 1360px) / 2)) » donne exactement le
   bord de cette colonne, a toute largeur :

       fenetre large   (100% - 1360) / 2   la bande s'aligne sur le contenu
       fenetre etroite 40px                les deux tombent sur la meme marge

   On la pose sur le REMPLISSAGE et non sur une largeur maximale : les bandes
   gardent leur fond et leur filet sur toute la largeur de l'ecran — c'est ce
   qui fait tenir l'en-tete — et seul leur contenu s'aligne.

   Sous 621 px, rien de tout cela ne s'applique : le telephone a ses propres
   regles, ecrites plus haut, et elles sont justes.
   ========================================================================== */
@media (min-width: 621px) {
  .service,
  .entete .nav {
    padding-inline: max(40px, calc((100% - 1360px) / 2));
  }
  /* La rangee d'outils est deja bornee a 1440 px et centree : il lui suffit
     d'un remplissage symetrique de 40 px, comme « .section ». Les 110 px de
     droite qu'elle portait degageaient le bouton Assistance ; celui-ci vit
     desormais dans la gouttiere, hors de la colonne. */
  .rang-outils { padding-inline: 0; }
  .rang-outils .outils { padding-inline: 40px; }
}

/* ==========================================================================
   LA GALERIE DES FICHES PRODUIT.

   Olivier, le 5 septembre 2026 : « sur tous les produits il n'y a qu'une seule
   photo alors que sur ecwid il y en a plusieurs. Il faut pouvoir les faire
   defiler comme sur le site actuel ». Mesure : 55 fiches sur 63 portent une
   galerie dans Ecwid — 166 photos — et pas une n'etait rendue.

   Le carrousel est celui de la page mariage, repris tel quel : meme
   « data-carrousel », meme piste, meme pilote. Il n'a besoin ici que d'etre
   remis a la largeur de la colonne de gauche et d'oublier les marges laterales
   qu'il porte sur une page de texte pleine largeur.

   LA VUE OCCUPE TOUTE LA PISTE, une photo a la fois. Sur la page mariage on
   montre trois vignettes cote a cote — c'est une galerie de reference, on y
   compare. Sur une fiche produit, on regarde LA piece : trois vues d'un meme
   bouquet en petit ne valent pas une vue en grand.
   ========================================================================== */
.p-galerie { margin: 0; }
/* LE PAS DU PILOTE EST « largeur + 12 » — voir « pas() » dans mesure.js.
   Avec un ecart de zero, chaque coup de fleche se decalait de douze pixels,
   et l'erreur s'accumulait vue apres vue. On garde donc l'ecart que le pilote
   suppose plutot que de reecrire le pilote pour un seul carrousel. */
.p-galerie .m-piste { gap: 12px; scroll-snap-type: x mandatory; }
.p-galerie .m-vue { flex: 0 0 100%; margin: 0; scroll-snap-align: center; }
.p-galerie .m-vue img { width: 100%; height: auto; aspect-ratio: 1 / 1;
                        object-fit: cover; display: block; border-radius: 2px; }
/* Les pastilles sous la photo, pas par-dessus : sur une fiche, le bas de
   l'image porte souvent la composition elle-meme. */
.p-galerie .m-points { margin-top: 12px; }

/* ==========================================================================
   LE CHAMP DE MONTANT — les fiches vendues au prix libre.
   Olivier, le 5 septembre 2026 : « On a pas le choix du montant dans bouquet
   personnalisé ». Le champ n'existait pas ; toute commande partait au minimum.
   Il se presente comme une option parmi les autres, parce que c'en est une :
   le client choisit une couleur, une forme, puis ce qu'il souhaite offrir.
   ========================================================================== */
.montant-libre .champ { max-width: 220px; font-size: 20px; letter-spacing: .02em; }
.montant-note { margin: 8px 0 0; font-size: 14px; line-height: 1.5;
                color: #9A9488; }

/* Le bandeau de service, aligne lui aussi.
   Sa gouttiere tombe bien sur 113 px, mais ses trois informations restaient
   centrees dans leurs colonnes : la premiere commencait a 269. « Il faut que
   tout soit aligne » (Olivier, 5 septembre 2026) vaut aussi pour elle.
   La premiere se cale a gauche, la derniere a droite, celle du milieu reste
   centree — la barre encadre alors la page au lieu de flotter dedans. */
@media (min-width: 1500px) {
  .service > *:first-child { justify-self: start; }
  .service > *:last-child  { justify-self: end; }
}

/* ==========================================================================
   LE FILET DU MENU EST RETIRE.

   Olivier, le 5 septembre 2026 : « il y a toujours un espace dans le menu
   entre Plantes et ultra luxe oscendence. Il faut l'enlever ».

   Le resserrer ne suffisait pas, et c'etait previsible : le filet est un
   element de la ligne, et « space-between » lui distribue sa part d'espace
   libre comme a une entree de menu. Meme reduit a 12 px de marge, il ajoutait
   un cran de plus a un endroit ou l'on n'en veut aucun. Passe de 34 a 12 px, le
   trou est passe de 142 a 115 px la ou les autres ecarts valaient 103 : encore
   visible, encore signale.

   CE QU'IL DISAIT SE DIT AUTREMENT. Il annoncait qu'a sa droite on quitte la
   boutique. C'est deja porte par la couleur — « Ultra Luxe Oscendence » est en
   or, les deux dernieres entrees en blanc plus clair — et par le fait que ces
   trois-la ne sont pas des rayons. Une separation qui se voyait au prix d'un
   trou dans la ligne coutait plus qu'elle ne rapportait.
   ========================================================================== */
@media (min-width: 621px) {
  .entete .nav .nav-coupe { display: none; }
}

/* ==========================================================================
   WHATSAPP DEVIENT UN BOUTON.

   Olivier, le 5 septembre 2026 : « mets whatsapp sous forme de bouton whatsapp
   plutot ». Il etait en texte ivoire a cote du numero — meme couleur, meme
   graisse, meme taille : deux moyens de nous joindre qui se lisaient comme une
   seule phrase, « +33 7 66 51 28 82 WhatsApp ». Rien ne disait que le second
   etait cliquable, ni qu'il ouvrait autre chose qu'un appel.

   LE VERT EST CELUI DE WHATSAPP (#25D366), et c'est le seul endroit du site ou
   une couleur de marque etrangere est admise : c'est precisement ce qui la
   rend reconnaissable sans avoir a la lire. Le texte passe en sombre, sur un
   fond plein — mesure apres depot : #0B2E13 sur #25D366 donne 7,5:1.
   (J'avais ecrit 8,9 avant de mesurer ; le chiffre juste est celui-ci.)

   Le pictogramme herite de « currentColor » et suit donc le texte, sans regle
   de plus.
   ========================================================================== */
.wa {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 12px; border-radius: 999px;
  background: #25D366; color: #0B2E13;
  /* PLUS PETIT QUE LE NUMERO — Olivier, le 6 septembre 2026.
     Le libelle etait a 16px, exactement la taille du numero de telephone pose
     a cote : les deux se disputaient le meme rang, alors qu'ils ne jouent pas
     le meme role. Le numero est l'information, le bouton est l'action.
     A 13,5px le bouton se lit comme un bouton et cesse de concurrencer le
     numero. Le contraste ne bouge pas — 7,5:1, la couleur est inchangee. */
  font-size: 13.5px;
  font-weight: 500; letter-spacing: .02em;
  text-decoration: none; white-space: nowrap;
  transition: background .15s ease;
}
@media (hover: hover) {
  /* Le survol fonce au lieu d'eclaircir : sur un bouton plein, eclaircir
     donne l'impression que le bouton s'eteint. */
  .wa:hover { background: #1EBE5A; color: #0B2E13; }
}
.wa svg { width: 17px; height: 17px; }

/* LE LOGO NE SERT QUE QUAND LE MOT DISPARAIT.
   Sur un grand ecran, le logo pose a cote du mot « WhatsApp » dit deux fois la
   meme chose. On le garde donc dans le balisage — un `display:none` se leve,
   un element absent demanderait de regenerer — et on ne le montre qu'en
   dessous de 430 px, la ou « .lbl-outil » est masque. */
.wa .wa-logo { display: none; }
@media (max-width: 620px) {
  .wa { padding: 6px 11px; }
}
@media (max-width: 430px) {
  /* Sans cette regle, le bouton n'a plus rien a montrer : le mot est masque
     avec tous les libelles d'outils, et il ne reste qu'une barre verte de
     quelques pixels. Olivier l'a vue depuis son telephone le 6 septembre.
     Le logo prend la place du mot ; le bouton devient rond, parce qu'un
     pictogramme seul dans une pilule allongee flotte. */
  /* PLUS PETITE — Olivier, le 6 septembre 2026 : « la pastille whastapp prend
     bcp de place sur mobile (la reduire ?) ». Mesuree a 40 px de large contre
     36 pour le panier voisin : a peine plus grande, mais PLEINE la ou le
     panier est ajoure, donc bien plus lourde a l'oeil. On reduit le disque
     plutot que la couleur — c'est le vert qui nomme le bouton. */
  .wa .wa-logo { display: block; width: 16px; height: 16px; }
  /* « .outils-centre > .wa » et non « .wa » seul : la regle de zone tactile
     « .outils-centre > a » vaut (0,1,1) et l'emportait, ce qui ecrasait le
     bouton a vingt-six pixels de large. Mesure avant correction : 26 x 44.
     Ici (0,2,0) gagne, et l'on garde une cible de quarante pixels — un
     pictogramme seul doit rester aussi facile a toucher que le mot qu'il
     remplace. */
  /* UN DISQUE, PAS UNE PILULE. Olivier, le 6 septembre 2026 : « la pastille
     est ovale ». Elle l'etait parce que sa largeur venait de son contenu —
     16 px de logo plus la marge — tandis que sa HAUTEUR lui etait imposee par
     la rangee d'outils, haute de 44 px pour rester facile a toucher. Trente-
     deux de large sur quarante-quatre de haut, avec un rayon de 999 px : une
     pilule debout.
     On fixe donc les deux cotes au lieu de les laisser se negocier avec le
     contexte. Trente-six pixels : plus petit que le panier voisin (36 de large
     mais ajoure, donc plus leger a l'oeil), assez grand pour le pouce.
     « flex: 0 0 auto » l'empeche d'etre etire par la rangee, et c'etait bien
     l'etirement la cause. */
  .outils-centre > .wa {
    gap: 0; padding: 0;
    /* « min-height: 0 » N'EST PAS DECORATIF. « .outils-centre > a » impose
       44 px de haut a toute la rangee pour rester facile a toucher ; sans le
       lever ici, la pastille restait haute de 44 et large de 36 — une pilule
       debout, et c'est exactement ce qu'Olivier a vu : « la pastille est
       ovale ». Une hauteur ecrite qui ne s'applique pas se voit a l'oeil bien
       avant de se voir dans le code. */
    min-height: 0;
    width: 28px; height: 28px; flex: 0 0 auto;
    justify-content: center; border-radius: 50%;
  }
  /* « fais la taille du logo whatsapp ça suffira » — Olivier, meme jour. Le
     disque se resserre sur le pictogramme au lieu de l'entourer d'un halo :
     seize pixels de logo dans vingt-huit de vert. La cible passe sous les
     quarante pixels recommandes, et c'est un choix assume — il l'a demandee
     petite, le telephone reste a cote et lui garde toute sa hauteur. */
  .wa .wa-logo { width: 16px; height: 16px; }
}

/* ==========================================================================
   LE TELEPHONE ET WHATSAPP FORMENT UN BLOC, ET CE BLOC EST CENTRE.

   Olivier, le 5 septembre 2026 : « Espace le bouton whatsapp du numero de
   telephone et centre le bloc (les deux elements) au milieu de la page ».

   MESURE AVANT : le numero occupait 828→1011 sur une page de 1854, soit
   parfaitement centre ; et le bouton WhatsApp, lui, etait pose en
   « position: absolute; left: calc(100% + 6px) » — donc SUSPENDU A DROITE du
   numero, hors du flux. Le couple s'etendait de 828 a 1181, centre a 1004
   quand la page l'est a 927 : soixante-dix-sept pixels de decalage, que l'oeil
   voit sans les mesurer.

   L'absolu avait une raison : garder le numero au centre exact malgre le
   bouton. Mais ce n'est pas ce qu'on veut — on veut les DEUX au centre. Le
   bouton redevient donc un element ordinaire de la ligne, et la grille
   « 1fr auto 1fr » de la rangee centre l'ensemble toute seule.

   L'ecart passe a 22 px : a 14, le bouton touchait presque le dernier chiffre
   et se lisait comme la suite du numero.
   ========================================================================== */
.rang-outils .outils-centre {
  display: inline-flex; align-items: center; gap: 22px;
}
.rang-outils .outils-centre .wa {
  position: static;
  left: auto; right: auto; top: auto;
  transform: none;
}
@media (max-width: 620px) {
  /* Sur telephone la ligne est etroite : on resserre plutot que de passer a
     la ligne, une rangee d'outils sur deux etages mange l'ecran. */
  .rang-outils .outils-centre { gap: 12px; }
}

/* ==========================================================================
   LE SOULIGNEMENT DU MENU S'ANIME AU SURVOL.

   Olivier, le 5 septembre 2026 : « Quand on passe la souris sur les textes du
   menu j'aimerai un effet (comme sur les soulignements) ».

   Le filet existait deja sous chaque entree, et il changeait de couleur au
   survol — un changement si discret qu'il ne se remarquait pas. Il se DESSINE
   maintenant, de gauche a droite, en deux dixiemes de seconde.

   COMMENT, ET POURQUOI PAS AUTREMENT. On anime « transform: scaleX » d'un trait
   pose en « ::after », et non la largeur : une largeur animee fait recalculer
   la mise en page a chaque image, une transformation non. Sur une barre de huit
   entrees, la difference se voit sur une machine modeste.

   Le filet au repos reste : il dit que le mot est un lien avant qu'on le
   survole. C'est le trait CLAIR qui se dessine par-dessus.

   Sous « (hover: hover) » : sur un ecran tactile, un survol reste colle apres
   un retour en arriere, et l'entree paraitrait selectionnee sans l'etre.
   ========================================================================== */
@media (hover: hover) {
  .entete .nav a > span { position: relative; }
  .entete .nav a > span::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
    height: 1px; background: currentColor;
    transform: scaleX(0); transform-origin: left center;
    transition: transform .2s ease;
  }
  .entete .nav a:hover > span::after,
  .entete .nav a:focus-visible > span::after { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
  .entete .nav a > span::after { transition: none; }
}

/* ==========================================================================
   LA BULLE D'ASSISTANCE DESCEND EN BAS A DROITE, SUR ORDINATEUR AUSSI.

   Olivier, le 5 septembre 2026 : « Le selecteur de langue est gene par la
   bulle assistance ». Mesure, a cinq largeurs :

       1500 px   la langue finit a 1423, la bulle commence a 1391   -31 px
       1280 px                     1225                     1171    -54 px
       1100 px                     1045                      991    -54 px
        950 px                      895                      841    -54 px

   Ce n'est pas un cas limite : de 1500 px vers le bas, c'est-a-dire sur la
   quasi-totalite des ecrans, les deux se recouvrent. Au-dela de 1600 px seul,
   la colonne de contenu cesse de grandir et la gouttiere devient assez large
   pour les deux.

   ON NE REDUIT PAS LA COLONNE POUR LOGER LA BULLE. C'est ce que faisaient les
   110 px de remplissage asymetrique de la rangee d'outils, et c'est ce qui
   decalait tout l'en-tete — le defaut qu'Olivier a fait corriger une heure
   plus tot. Reserver la place reviendrait a defaire l'alignement pour un
   element flottant.

   LA REPONSE ETAIT DEJA DANS LE SITE. Sur telephone, la bulle est en bas a
   droite depuis toujours (« bottom: 16px », plus haut dans ce fichier). Le
   bureau etait la seule exception, et c'est la seule ou la collision se
   produit. On aligne donc le bureau sur le telephone plutot que d'inventer un
   troisieme comportement.

   Ce que cela preserve : elle reste fixe, donc toujours atteignable — c'est ce
   qui en fait une assistance et non un lien qu'on depasse. Ce que cela change :
   on la trouve la ou l'on cherche une aide, en bas a droite.
   ========================================================================== */
@media (min-width: 621px) {
  .assistance {
    top: auto;
    bottom: 22px;
    right: 22px;
  }
}

/* ==========================================================================
   ESSAYE PUIS RETIRE : LA REPARTITION PAR LES CENTRES.

   Olivier avait demande, le 5 septembre 2026, que le menu se reparte par les
   centres plutot que par les bords — les ecarts etaient tous a 92 px et la
   ligne paraissait pourtant irreguliere, parce que l'oeil lit le rythme des
   mots et non les intervalles.

   Fait, mesure, et repris devant lui : « pour le menu revient au centrage des
   mots comme avant ».

   CE QUE LA MESURE AVAIT MONTRE, et qui explique le verdict. Huit colonnes
   egales de 170 px donnaient bien des centres reguliers — 168 a 171 px — mais
   les ecarts entre les mots passaient de 92 px uniformes a une fourchette de
   48 a 107. « Ultra Luxe Oscendence » fait 212 px pour une part de 170 : elle
   debordait sur ses deux voisines, et les deux ecarts qui l'entourent se
   resserraient de moitie quand les autres s'ouvraient.

   Un rythme de centres regulier au prix d'ecarts du simple au double : le
   remede se voyait plus que le mal. On garde donc « space-between », qui donne
   des ecarts rigoureusement egaux, et l'on note ici pourquoi — pour ne pas
   refaire l'essai dans six mois.

   Si la question revient, le levier n'est pas dans cette regle : c'est la
   longueur du libelle « Ultra Luxe Oscendence » qui rend les deux repartitions
   inconciliables.
   ========================================================================== */

/* ==========================================================================
   LA LOUPE : une photo du carrousel, agrandie sans quitter la page.

   Olivier, le 5 septembre 2026 : « raisonnablement, pas en pleine page mais la
   faire un peu plus grande ». Les deux bornes ci-dessous sont cette phrase
   traduite en chiffres.

   900 PX, ET PAS PLUS. C'est la taille reelle des fichiers — au-dela on
   n'agrandit plus rien, on interpole, et une photo interpolee sur un site qui
   vend le detail d'une composition dessert exactement ce qu'elle montre.

   82 % DE LA HAUTEUR, ET PAS 100. Le bord de la page reste visible tout
   autour : le lecteur voit qu'il est toujours chez lui, et il sait ou cliquer
   pour revenir. Une image qui touche les quatre bords est une nouvelle page,
   et il faut alors lui apprendre a en sortir.

   Le voile est sombre mais pas noir — #0A0A0C a 88 % laisse deviner la page
   dessous, ce qui est precisement le but.
   ========================================================================== */
.loupe {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(10, 10, 12, .88);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  cursor: zoom-out;
}
.loupe[hidden] { display: none; }
.loupe-image {
  max-width: min(900px, 100%);
  max-height: 82vh;
  width: auto; height: auto;
  border-radius: 3px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .55);
  /* La photo elle-meme n'est pas une cible de fermeture : on clique a cote
     pour fermer, on clique dessus pour la regarder. */
  cursor: default;
}
.loupe-fermer {
  position: absolute; top: 14px; right: 16px;
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid rgba(226, 231, 237, .28);
  background: rgba(16, 16, 18, .7); color: var(--ivoire);
  font-size: 24px; line-height: 1; cursor: pointer;
}
@media (hover: hover) {
  .loupe-fermer:hover { background: rgba(16, 16, 18, .95);
                        border-color: var(--argent); }
}
/* Le curseur dit que la photo s'ouvre, avant meme qu'on l'essaie. */
@media (hover: hover) {
  [data-carrousel] .m-vue img { cursor: zoom-in; }
}
@media (max-width: 620px) {
  .loupe { padding: 12px; }
  .loupe-image { max-height: 76vh; }
  .loupe-fermer { top: 8px; right: 10px; }
}

/* ==========================================================================
   OÙ SUIS-JE — l'entrée de menu de la page courante — 6 septembre 2026

   Olivier : « quand on est dans un menu, par exemple bouquet, je voudrais que
   l'élément du menu soit mis en valeur par rapport aux autres (pour savoir où
   on est dans le menu) ».

   CE QUI LA DISTINGUE, ET POURQUOI CES TROIS CHOSES-LÀ.

   1. Le trait sous le mot, POSÉ et non survolé. C'est le même trait que celui
      du survol — même épaisseur, même place — ce qui fait qu'on le lit sans
      l'apprendre : on sait déjà ce qu'il veut dire. Il est simplement là tout
      le temps au lieu de venir avec la souris.
   2. La couleur pleine du texte. Les entrées au repos sont en gris clair ; la
      page courante passe en ivoire. C'est le signal qui se voit de loin, et le
      seul qui fonctionne sur un écran tactile, où il n'y a pas de survol.
   3. Rien d'autre. Pas de fond, pas de gras, pas de cadre : huit entrées dont
      une encadrée transforme le menu en formulaire, et le gras déplace les
      voisines d'un pixel — sur une barre, ce décalage se voit.

   On vise « [aria-current] » et non la classe : l'attribut est la source de
   vérité, il est posé par le générateur pour les lecteurs d'écran, et styler
   ce qu'on annonce évite qu'un jour l'un dise une chose et l'autre le
   contraire. La classe « ici » reste dans le HTML pour qui voudrait viser plus
   fin sans toucher à la sémantique.
   ========================================================================== */
/* PREMIERE VERSION INSUFFISANTE, ET DEUX RAISONS MESUREES.

   1. Le trait ne distinguait rien. CHAQUE entree porte deja un filet au repos
      — « 1px solid rgba(198,202,208,.26) » — pose la pour dire que le mot est
      un lien. Le trait de la page courante etait de meme epaisseur : par-
      dessus un filet existant, il ne se lisait pas comme un signal, mais comme
      le meme filet un peu plus net. Olivier : « l'element du menu selectionne
      n'est pas allume (juste le soulignement) ».
   2. La couleur ASSOMBRISSAIT au lieu d'eclairer. « --ivoire » vaut 234 ; or
      « Mariage » et « Evenements » sont ecrits en 239, et « Oscendence » en
      dore. Poser une couleur unique retirait donc de la lumiere a trois
      entrees sur huit, et effacait au passage l'identite doree d'Oscendence —
      la seule couleur du site qui ne lui soit pas partagee.

   D'ou la regle : ON N'IMPOSE PAS UNE COULEUR, ON ECLAIRE CELLE DE L'ENTREE.
   Chaque famille garde la sienne, en plus clair. Le dore reste dore. */
.entete .nav a[aria-current="page"] { color: var(--ivoire-h); }
.entete .nav a.osc[aria-current="page"] { color: #E7CE8A; }
.entete .nav a.mar[aria-current="page"],
.entete .nav a.eve[aria-current="page"] { color: #FFFFFF; }

/* LE TRAIT DOUBLE D'EPAISSEUR. Un pixel de plus est ce qui distingue « ce mot
   est un lien » de « vous etes ici », sans ajouter ni fond ni cadre a une
   barre de huit entrees. Il descend d'un pixel pour couvrir le filet du repos
   au lieu de s'empiler dessus : deux traits l'un sur l'autre font une bavure,
   pas un soulignement. */
.entete .nav a[aria-current="page"] > span::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 2px; background: currentColor;
  transform: none;                 /* posé, pas animé : il est déjà là */
}
/* « position: relative » n'est déclaré que sous « (hover: hover) », avec le
   soulignement animé. Sans cette ligne, le trait de la page courante se
   placerait par rapport à la barre entière sur un écran tactile — c'est-à-dire
   n'importe où. Le défaut ne se serait vu que sur téléphone. */
.entete .nav a[aria-current="page"] > span { position: relative; }

/* ==========================================================================
   LE MENU DÉPLIÉ DOIT SE VOIR COMME UN BLOC — 6 septembre 2026

   Olivier, depuis son téléphone : « Quand on déploie le menu buger sur mobile
   j'aimerai qu'on distingue le bloc du menu déployé (sinon ça fait noir sur
   noir, on voit difficilement qu'il y a un menu déployé) ».

   Il a raison, et la cause est mesurable : le menu déplié n'avait aucun fond
   propre. Il héritait donc du noir de la page — #101012 sur #101012 — et seuls
   ses filets de séparation, à 10 % d'opacité, disaient qu'il existait. Un
   panneau qui s'ouvre sans se distinguer du fond ne se lit pas comme un
   panneau : il se lit comme du contenu qui vient d'apparaître, et l'on ne sait
   plus si l'on a ouvert un menu ou changé de page.

   TROIS SIGNAUX, ET AUCUN DE PLUS.

   1. Un fond plus clair. **Aucun jeton de la palette ne convenait**, et c'est
      mesuré : « --bloc » sur « --nuit » donne 1,06 de contraste, « --creux »
      1,12. En dessous de 1,2 l'écart ne se voit pas sur un téléphone en plein
      jour — c'est précisément ce qu'Olivier décrit. On pose donc une valeur
      explicite, #25252B, qui donne 1,23 : l'écart le plus faible qui se voie
      encore. Au-delà, le panneau devient une boîte grise sur une page noire,
      et l'on abîme la sobriété de l'ensemble pour rien.
   2. Un trait sous le panneau, qui dit où il se termine. Sans lui, la dernière
      entrée se confond avec le début de la page.
   3. Une ombre portée. C'est elle, et non le fond, qui fait comprendre que le
      panneau est AU-DESSUS de la page et non dedans — donc qu'il se referme.

   Le fond est posé sur « .nav » et non sur un parent : le panneau tombe sous
   l'en-tête sans la pousser, et teinter l'en-tête entière ferait bouger sa
   couleur à chaque ouverture.
   ========================================================================== */
.js[data-menu="ouvert"] .entete .nav {
  background: #25252B;
  /* Les DEUX bords, pas seulement le bas : le haut sépare le panneau de la
     rangée d'outils, qui est noire elle aussi. Sans lui, le panneau paraît
     commencer nulle part. */
  border-top: 1px solid #3A3A42;
  border-bottom: 1px solid #3A3A42;
  /* L'ombre fait plus pour dire « ceci est au-dessus » que le fond lui-même.
     Elle est franche exprès — une ombre timide sur un fond noir ne se voit
     pas du tout. */
  box-shadow: 0 16px 30px rgba(0, 0, 0, .55);
}

/* ==========================================================================
   ET DANS CE PANNEAU, L'ENTRÉE COURANTE

   La couleur seule ne suffisait pas, et la mesure le disait : la page courante
   passait de #DCD7CD à #EAE5DA — quatorze points sur deux cent cinquante-cinq.
   Pire, « Mariage » et « Événements » sont écrits en #EFEAE0, donc PLUS CLAIRS
   que la page où l'on se trouve. Le signal était inversé.

   On lui donne donc ce qu'aucune autre entrée n'a : un fond, et un repère à
   gauche. Sur une liste verticale, la barre de gauche se lit avant le texte —
   c'est le bord que l'œil suit en descendant.

   Le fond reste très discret (« --bloc » sur « --creux ») : il ne s'agit pas
   de décorer une entrée, mais de répondre à une question — où suis-je.
   ========================================================================== */
.js[data-menu="ouvert"] .entete .nav a[aria-current="page"] {
  /* TROIS ÉTAGES, ET DANS CET ORDRE : la page (#101012), le panneau
     (#25252B), la ligne où l'on se trouve (#32323A). Chacun se détache du
     précédent, et la ligne courante est l'endroit le plus clair de l'écran.

     Deux erreurs faites avant d'arriver là, toutes deux vues à la mesure et
     non à l'œil. D'abord la ligne courante était plus SOMBRE que le panneau —
     une ligne creusée se lit comme désactivée, le contraire de ce qu'on veut
     dire. Ensuite les deux tenaient dans les jetons de la palette, trop
     rapprochés : 1,06 de contraste, invisible. */
  background: #32323A;
  box-shadow: inset 3px 0 0 var(--argent);
  color: var(--ivoire-h);
}
/* Déplié, chaque entrée a déjà sa ligne de séparation : le trait posé sous le
   mot ferait un second filet sur la même entrée, ce que la règle du menu
   déplié interdit déjà pour le filet de survol. Le fond et la barre suffisent. */
.js[data-menu="ouvert"] .entete .nav a[aria-current="page"] > span::after {
  content: none;
}

/* ==========================================================================
   « C'EST BIEN PARTI » — le panneau de confirmation de commande
   6 septembre 2026, une heure après la bascule

   POURQUOI IL EXISTE. Un client a payé DEUX FOIS la même orchidée à cinq
   minutes d'intervalle — 204,90 € débités deux fois. Les traces de paiement
   sont formelles : deux moyens de paiement Stripe distincts, cryptogramme
   vérifié les deux fois, et la même session. Il n'a pas quitté le site ; il a
   ressaisi sa carte entière, convaincu que la première fois n'avait pas
   marché.

   La page de confirmation d'Ecwid s'affiche pourtant. Mais elle ressemble à
   une page, pas à une réponse. Quelqu'un qui vient de donner deux cents euros
   cherche un signal, pas un récapitulatif.

   LE VERT EST CELUI DES FORMULAIRES, et ce n'est pas une facilité. Olivier
   l'a choisi lui-même le 5 septembre — « vert plus clair, attention à la
   police qui doit rester visible » — et son contraste est mesuré à 11,8:1.
   Une couleur de plus dans la palette serait une couleur de trop, et celle-ci
   dit déjà « c'est parti » ailleurs sur le site.

   IL BARRE LE PASSAGE, et c'est le point. Un bandeau se défile ; un panneau se
   ferme. Devant un doute qui coûte un double paiement, on veut le geste.
   ========================================================================== */
.confirme-fond {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(8, 8, 10, .72);
}
.confirme-boite {
  width: 100%; max-width: 460px;
  background: #DCEFDC; color: #16301C;
  border: 1px solid #6FA37E;
  padding: 32px 30px 28px;
  text-align: center;
  font-family: var(--ui);
  box-shadow: 0 20px 48px rgba(0, 0, 0, .5);
}
/* La coche vient avant le texte : elle se lit d'un regard, avant même qu'on
   ait commencé à lire. */
.confirme-coche {
  width: 52px; height: 52px; margin: 0 auto 16px;
  border-radius: 50%; background: #2E7D46; color: #FFFFFF;
  font-size: 28px; line-height: 52px; font-weight: 500;
}
.confirme-titre {
  margin: 0 0 12px; font-size: 21px; line-height: 1.35; font-weight: 500;
  color: #0E220F;
}
.confirme-corps { margin: 0 0 18px; font-size: 15.5px; line-height: 1.6; }
/* Le numéro transforme « ça a l'air d'avoir marché » en « j'ai une preuve ».
   Il se lit en chiffres tabulaires : on le recopie souvent. */
.confirme-num {
  margin: 0 0 22px; font-size: 15px; font-weight: 500;
  font-variant-numeric: tabular-nums; color: #0E220F;
}
.confirme-bouton {
  display: inline-block; border: 0; cursor: pointer;
  background: #16301C; color: #F2F7F2;
  padding: 13px 26px; font-family: var(--ui); font-size: 15px;
  letter-spacing: .02em;
}
@media (hover: hover) {
  .confirme-bouton:hover { background: #0E220F; }
}
@media (max-width: 430px) {
  .confirme-boite { padding: 26px 20px 22px; }
  .confirme-titre { font-size: 19px; }
}
