/* ═══ APERÇU MODIFIABLE (panneau de gestion uniquement) ══════════════════
   Tout ce qui suit n'existe que sous `html[data-edition]`, posé par
   js/shop.js et js/product.js quand la boutique est ouverte DANS l'aperçu
   du panneau, avec `?edition=1` et un parent de même origine. Une boutique
   ouverte par un client ne porte jamais cet attribut : ces règles n'y
   changent rien, et les outils (pilules, nuancier, bande d'aide) n'y sont
   jamais créés. La feuille est à part d'app.css pour que le langage visuel
   de l'édition vive à un seul endroit, partagé par l'accueil et la fiche. */

/* Les textes qu'on peut retoucher se signalent au survol par un liseré
   pointillé — assez pour dire « ceci se modifie », assez discret pour ne
   pas déguiser l'aperçu en formulaire : le gérant doit continuer à voir
   sa boutique telle que ses clients la verront. */
html[data-edition] [data-modif]{outline:1px dashed transparent;outline-offset:3px;
  border-radius:4px;transition:outline-color .18s,background .18s;cursor:text}
html[data-edition] [data-modif]:hover{outline-color:var(--acc)}
html[data-edition] [data-modif]:focus{outline:2px solid var(--acc);outline-offset:3px;
  background:color-mix(in srgb,var(--acc) 10%,transparent)}
/* LE CRAYON EST HORS DU FLUX, et c'est tout l'enjeu de ces deux règles.
   Posé dans la boîte (::after inline, marge + glyphe à .68em), il ajoutait
   sa largeur à celle du texte : un titre de bannière borné à 17ch
   (app.css, `.hero.plein .hero-card h1`) repassait sur deux lignes AU
   SURVOL, avant le moindre clic, et la bannière sautait de 64 px sous la
   souris. En absolu il n'occupe plus aucune largeur, donc il ne décide
   plus d'aucun retour à la ligne. Sa taille est FIXE et non en `em` : à
   .68em d'un titre de 58 px, le crayon faisait 39 px de haut.
   Il se pose au coin haut-droit et déborde vers l'extérieur : à cheval sur
   le bord, il reste lisible sans recouvrir le texte, et il ne peut pas
   sortir de l'écran sur un bloc qui va d'un bord à l'autre (le bandeau
   d'annonce), là où un placement franchement à droite aurait été rogné
   par la coupe latérale de la page (app.css, overflow-x:clip).

   Un crayon discret au survol, en plus du liseré : le liseré dit « ceci
   bouge », le crayon dit « ceci s'écrit ». Il disparaît dès qu'on tape,
   pour ne pas se retrouver dans la sélection. Jamais sur un texte vidé
   ni sur un repère (`[data-vide]`, plus bas) : il le ferait passer pour
   rempli. Trois exclusions, le liseré suffit : le nom de carte, dont le
   ::after est déjà un ornement pour plusieurs cadres (perle, deco,
   feston dans app.css : le crayon s'y retrouvait tourné de 45° dans un
   carré ou collé dans un fil de perles) ; l'enseigne, rognée par une
   ellipse, qui perdait ses dernières lettres à chaque passage de la
   souris ; et l'étiquette « Nous trouver », traitée juste en dessous.

   SA POSITION PASSE PAR TROIS VARIABLES, et ce n'est pas une coquetterie :
   le sélecteur ci-dessous, avec ses six `:not()`, pèse si lourd qu'aucune
   exception raisonnable ne peut le battre. Une variable posée sur l'ÉLÉMENT
   (le pseudo-élément en hérite) contourne la cascade au lieu de lutter
   contre elle — voir la bande des rayons, juste après. */
html[data-edition] [data-modif]:not(.pcard .name):not(.mn-nom):not(.lm-badge):hover:not(:focus):not(:empty):not([data-vide])::after{
  content:'\270E';position:absolute;right:var(--crayon-x,0);top:var(--crayon-y,0);
  transform:var(--crayon-t,translate(60%,-60%));
  font:400 13px/1 var(--sans);opacity:.55;pointer-events:none}
/* SAUF DANS LA BANDE DES RAYONS, QUI ROGNE CE QUI DÉBORDE PAR LE HAUT. La
   piste des puces est `overflow-x:auto` (app.css, `.scroller`) : en CSS, un
   conteneur qui coupe en largeur calcule aussi son débordement VERTICAL en
   `auto`, et ce qui sort par le haut n'est même pas atteignable au
   défilement. Le crayon, remonté de 60 % de sa hauteur, y perdait la moitié
   de son glyphe — et dans l'en-tête, où la piste n'a plus de marge haute
   (app.css, `header.appbar .cats-bande .scroller`), il disparaissait
   entièrement. On le rentre donc DANS la puce, centré sur sa hauteur, et on
   lui réserve sa place par une gouttière à droite : rien ne dépasse, rien
   n'est coupé, et il ne vient pas mordre la puce suivante. La gouttière est
   posée en permanence et non au survol — apparue sous la souris, elle
   élargirait la puce et ferait sauter toute la rangée. */
html[data-edition] .cats-bande .chip[data-modif]{padding-right:27px;
  --crayon-x:10px;--crayon-y:50%;--crayon-t:translateY(-50%)}
/* LE REPÈRE DU CRAYON, ET RIEN D'AUTRE. Un élément en position absolue se
   place par rapport au premier ancêtre positionné : sans ce `relative`, le
   crayon irait se coller au coin d'une section entière. `relative` ne
   déplace rien et ne crée pas de contexte d'empilement, il ne fait
   qu'offrir ce repère.
   L'ÉTIQUETTE « NOUS TROUVER » EST EXCLUE : la seule mise en page qui
   l'affiche la pose elle-même en absolu (app.css, [data-lamaison="onglet"]),
   et cette règle-ci, plus spécifique, la ramènerait dans le flux : elle
   sauterait de place à l'entrée en retouche. Elle garde son liseré. */
html[data-edition] [data-modif]:not(.lm-badge){position:relative}
/* Ce qui s'ouvre d'un clic le dit par le curseur : la bannière, le bloc
   « La maison », l'enseigne à logo. L'enseigne TEXTE est exclue ici
   (même poids que la règle [data-modif], et celle-ci viendrait après) :
   elle garde son curseur texte ; les textes de la bannière et de La
   maison aussi, par leur propre règle [data-modif]. */
html[data-edition] .hero-card,html[data-edition] .lm-card,html[data-edition] .mn-nom:not([data-modif]){cursor:pointer}
/* Un texte vidé garde une prise : sans hauteur, on ne pourrait plus
   jamais cliquer dedans pour le réécrire.
   `.lm-badge` EN EST EXCLUE, pour la même raison que le repère plus bas ne
   force plus l'affichage : neuf modèles du bloc « La maison » sur dix la
   masquent par leur mise en page (app.css, `.lm-badge,.lm-mono,.lm-sub`), et
   ce sélecteur, bien plus spécifique, la ramenait à l'écran dès qu'elle était
   vide — un repère flottant là où le client ne verra jamais rien. Sous le
   modèle qui l'affiche, elle garde sa prise autrement : le texte du repère
   (`[data-vide]::before`) lui donne sa largeur et sa hauteur. */
html[data-edition] [data-modif]:empty:not(.lm-badge){min-width:90px;min-height:1.2em;
  outline-color:var(--line-2);display:inline-block}
/* ── LE REPÈRE D'UN CHAMP VIDÉ ───────────────────────────────────────
   La garde ci-dessus ne suffisait pas, et c'est le défaut qu'on répare :
   vider un texte est un USAGE (le bandeau d'annonce, la mention de la
   bannière), et la boutique masque alors le bloc avec `.hide`, qui vaut
   `display:none!important` (app.css). La prise de 90 px était donc
   annulée, le rectangle mesurait 0 × 0, plus aucun clic n'y entrait : le
   gérant qui vidait son bandeau depuis la vitrine ne pouvait plus JAMAIS
   le réécrire depuis la vitrine, aucun geste ne le ramenait.
   `data-vide` est posé par js/shop.js (marquerLesVides) et porte la
   phrase à afficher. Il faut `!important` pour battre `.hide`, et la
   spécificité fait le reste.
   ON REND VISIBLE TOUT CHAMP MASQUÉ PAR `.hide`, pas seulement les vides :
   dès que le gérant écrit dans un repère, js/shop.js retire `data-vide`, mais
   la boutique ne redessine pas pour autant (elle le fera au prochain
   chargement) et la classe `.hide` est toujours là. Sans la première
   ligne ci-dessous, le texte qu'il venait de taper disparaissait sous ses
   yeux au moment de valider.
   ET SEULEMENT `.hide`, JAMAIS `[data-vide]` SEUL : `display:inline-block`
   forcé bat tout masquage sans `!important`, y compris ceux de la MISE EN
   PAGE. L'étiquette « Nous trouver » est cachée par neuf modèles du bloc « La
   maison » sur dix (app.css, `.lm-badge,.lm-mono,.lm-sub{display:none}`) :
   vidée sous le seul modèle qui l'affiche puis regardée sous un autre, elle
   revenait en repère flottant dans un bloc où le client, lui, ne verra jamais
   rien. Un champ que sa mise en page cache reste donc caché ; `[data-vide]`
   ne porte que l'habillage du repère.
   RIEN DE TOUT CELA N'EXISTE POUR UN CLIENT : tout est sous
   html[data-edition], et il voit une boutique simplement sans bandeau.
   Fond et liseré sont tirés de `currentColor`, jamais d'une encre fixe :
   le titre de bannière est blanc sur la photo du gérant, l'annonce est à
   la couleur d'accent, un intitulé de rayon est sombre sur crème. Une
   teinte en dur aurait disparu dans la moitié des cas. */
html[data-edition] [data-modif].hide{display:inline-block!important}
html[data-edition] [data-modif][data-vide]{
  min-width:90px;padding:1px 8px;border-radius:6px;cursor:text;
  background:color-mix(in srgb,currentColor 8%,transparent);
  outline:1px dashed color-mix(in srgb,currentColor 40%,transparent);outline-offset:2px}
/* LE REPÈRE GARDE SON SURVOL ET SON LISERÉ DE FOCUS. La règle ci-dessus pèse
   exactement autant que `[data-modif]:hover` et `[data-modif]:focus` en tête
   de feuille (0,3,1 des deux côtés) : à poids égal c'est la dernière écrite
   qui gagne, et son `outline` pointillé écrasait les deux. Le champ le plus
   difficile à voir — une boîte de 90 px presque vide — était donc le SEUL à
   ne rien signaler quand on le survolait ni quand on cliquait dedans. On les
   redit ici, après, pour qu'ils reprennent la main. */
html[data-edition] [data-modif][data-vide]:hover{outline-color:var(--acc)}
html[data-edition] [data-modif][data-vide]:focus{outline:2px solid var(--acc);outline-offset:3px;
  background:color-mix(in srgb,var(--acc) 10%,transparent)}
/* Le bandeau d'annonce occupe toute la largeur de la page : ramené à un
   bloc en ligne, il se retrouverait collé au bord de l'écran. On lui rend
   la gouttière que sa règle d'origine (app.css, `.annonce`) obtient d'un
   `margin-inline:auto` sans effet une fois le bloc en ligne. */
html[data-edition] #annonce.hide{margin-inline:16px}
/* Le repère est un PSEUDO-ÉLÉMENT : il ne fait pas partie du texte
   modifiable, il ne peut donc pas partir à l'enregistrement à la place de
   ce que le gérant écrit. Taille et casse fixées ici : sans cela il
   héritait des 58 px du titre de bannière ou des capitales de la mention.
   IL RESTE TANT QUE RIEN N'EST TAPÉ. Il s'effaçait au FOCUS, c'est-à-dire
   à l'instant précis où le gérant en avait besoin : la consigne (« Écrire
   votre accroche ») disparaissait au clic, et il se retrouvait devant une
   boîte vide sans savoir ce qu'on lui demandait d'écrire. C'est js/shop.js
   qui retire `data-vide` à la première lettre frappée, et le remet si tout
   est effacé — le pseudo-élément suit l'attribut, sans règle de focus. */
html[data-edition] [data-modif][data-vide]::before{content:attr(data-vide);
  font:500 12.5px/1.4 var(--sans);letter-spacing:normal;text-transform:none;
  color:inherit;opacity:.7;pointer-events:none}

/* Le « + » de création de rayon, visible uniquement dans l'aperçu du
   panneau. Il se distingue des rayons : c'est une commande, pas une
   destination. */
html[data-edition] .cats-bande .chip-plus{color:var(--acc);font-weight:700;white-space:nowrap}
html[data-edition] .cats-bande .chip[data-modif]{cursor:text}
html:not([data-edition]) .cats-bande .chip-plus{display:none}

/* ── CE QUI EST VISÉ ─────────────────────────────────────────────────
   La carte, la bannière, le bloc « La maison » ou la grille qu'une pilule
   est en train de régler : un contour dans la couleur d'accent, pour
   qu'on sache à quoi les flèches se rapportent. */
html[data-edition] .pcard.vise{outline:2px solid var(--acc);outline-offset:4px;border-radius:inherit}
html[data-edition] .lm-card.vise{outline:2px solid var(--acc);outline-offset:4px}
html[data-edition] .hero-card.vise{outline:2px solid var(--acc);outline-offset:-3px}
html[data-edition] .grid.vise{outline:2px dashed var(--acc);outline-offset:8px;border-radius:12px}

/* ── LA PILULE D'OUTILS ──────────────────────────────────────────────
   Posée SUR la page (position absolue au fil du document) et replacée au
   défilement : ancrée au bord de l'écran, on ne saurait plus à quel
   élément elle se rapporte. Sombre quel que soit le thème : c'est un
   outil du panneau, pas un morceau de la boutique. */
.edit-cadres{position:absolute;z-index:9999;transform:translate(-50%,-100%);
  display:flex;align-items:center;gap:4px;padding:5px 6px;border-radius:99px;
  background:#14100c;color:#fff;box-shadow:0 8px 24px -10px rgba(0,0,0,.6);
  font:600 12.5px/1 var(--sans);white-space:nowrap;max-width:calc(100vw - 16px)}
.edit-cadres[hidden]{display:none}
.edit-cadres button{width:30px;height:30px;border:0;border-radius:50%;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font-size:17px;line-height:1;
  display:grid;place-items:center;transition:background .15s;flex:none}
.edit-cadres button:hover{background:rgba(255,255,255,.3)}
/* L'état retenu (nombre par rangée, carrousel ou grille) s'inverse : on
   voit d'un coup d'œil ce qui est en place. */
.edit-cadres button.on{background:#fff;color:#14100c}
.edit-cadres-nom{padding:0 8px;max-width:150px;overflow:hidden;text-overflow:ellipsis}
/* Le style de bannière et le fond portent une précision (« masqué par la
   photo ») qui explique pourquoi les flèches ne changent rien : coupée
   par l'ellipse, elle n'expliquait plus rien. */
.edit-cadres .edit-banniere-style,.edit-fond .edit-cadres-nom{max-width:260px}
.edit-cadres .edit-lib{padding:0 4px 0 8px;opacity:.7;font-weight:500}
.edit-cadres .edit-sep{width:1px;height:18px;background:rgba(255,255,255,.22);margin:0 3px;flex:none}
.edit-cadres .edit-ouvrir{width:auto;padding:0 12px;height:28px;border-radius:99px;
  font:600 12px/1 var(--sans);margin-left:2px}
.edit-cadres .edit-col{width:26px;height:26px;font-size:12.5px;font-weight:700}
/* Sur un petit écran, la pilule de la grille et celle de la bannière
   débordent : on les laisse passer à la ligne plutôt que de les couper. */
@media(max-width:560px){.edit-cadres{white-space:normal;flex-wrap:wrap;justify-content:center;border-radius:20px;row-gap:5px}}

/* ── LE NUANCIER ─────────────────────────────────────────────────────
   Ouvert depuis la pilule du menu : les teintes de la boutique, celle du
   menu, celles du nom, de l'accroche et des titres, puis les polices.
   Chaque pastille peint la boutique tout de suite ; le panneau, lui,
   enregistre. */
.edit-nuancier{position:absolute;z-index:9999;width:min(92vw,560px);padding:12px 14px 10px;
  border-radius:18px;background:#14100c;color:#fff;box-shadow:0 14px 34px -12px rgba(0,0,0,.7);
  font:500 12.5px/1.3 var(--sans)}
.edit-nuancier[hidden]{display:none}
.edit-nu-rang{display:flex;align-items:center;flex-wrap:wrap;gap:5px;margin:5px 0}
.edit-nu-lib{flex:0 0 66px;opacity:.65;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.edit-pastille{width:18px;height:18px;border-radius:50%;padding:0;cursor:pointer;flex:none;
  border:2px solid transparent;box-shadow:inset 0 0 0 1px rgba(255,255,255,.22);transition:transform .12s}
.edit-pastille:hover{transform:scale(1.18)}
.edit-pastille.on{border-color:#fff;transform:scale(1.18)}
.edit-nu-chip{height:24px;padding:0 10px;border:0;border-radius:99px;cursor:pointer;flex:none;
  background:rgba(255,255,255,.14);color:#fff;font:600 11.5px/1 var(--sans)}
.edit-nu-chip:hover{background:rgba(255,255,255,.28)}
.edit-nu-chip.on{background:#fff;color:#14100c}
.edit-nu-sel{display:inline-flex;align-items:center;gap:6px;margin-right:8px;font-weight:600;font-size:12px}
.edit-nuancier select{height:28px;max-width:170px;padding:0 8px;border-radius:8px;
  border:1px solid rgba(255,255,255,.25);background:#221c17;color:#fff;font-size:13px}
.edit-nuancier select option{background:#221c17;color:#fff}

/* ── « + ARTICLE », EN BOUT DE GRILLE ────────────────────────────────
   Une case en pointillé, à la place qu'aurait le prochain article. Ce
   n'est pas une carte (`.pcard`) : ni favori, ni ajout au panier, ni
   révélation au défilement. */
.edit-plus-article{display:grid;place-items:center;align-content:center;gap:4px;min-height:120px;
  border:2px dashed color-mix(in srgb,var(--acc) 55%,transparent);border-radius:18px;
  background:color-mix(in srgb,var(--acc) 6%,transparent);color:var(--acc);cursor:pointer;
  font:600 13px/1.2 var(--sans);transition:background .15s,border-color .15s}
.edit-plus-article:hover{background:color-mix(in srgb,var(--acc) 12%,transparent);border-color:var(--acc)}
.edit-plus-article b{font-size:30px;line-height:1;font-weight:500}
.grid.cascade .edit-plus-article{break-inside:avoid;width:100%;margin:0 0 13px}
html:not([data-edition]) .edit-plus-article{display:none}

/* ── LA BANDE D'AIDE ─────────────────────────────────────────────────
   Fixée en bas du cadre, refermable et mémorisée pour la session : elle
   dit les gestes une fois, puis se retire. */
.edit-aide{position:fixed;left:50%;bottom:14px;z-index:9998;transform:translateX(-50%);
  display:flex;align-items:center;gap:10px;max-width:min(94vw,760px);padding:8px 8px 8px 16px;
  border-radius:99px;background:#14100c;color:#fff;box-shadow:0 10px 28px -10px rgba(0,0,0,.6);
  font:500 12.5px/1.35 var(--sans)}
.edit-aide button{width:28px;height:28px;border:0;border-radius:50%;cursor:pointer;flex:none;
  background:rgba(255,255,255,.14);color:#fff;font-size:18px;line-height:1;display:grid;place-items:center}
.edit-aide button:hover{background:rgba(255,255,255,.3)}
@media(max-width:560px){.edit-aide{border-radius:16px;bottom:8px}}

/* ── LA FICHE ARTICLE ────────────────────────────────────────────────
   Sur produit.html, la bande du bas est le sélecteur de design ; la
   retouche y ajoute sa rangée d'outils (js/product.js, retoucherLaFiche) :
   le retour à la boutique, l'état du dernier enregistrement, « Photo » et
   « Modifier la fiche complète ». Même encre sombre que les pilules : ce
   sont des outils du panneau, pas un morceau de la boutique. */
.fiche-pick .fp-outils{display:flex;align-items:center;flex-wrap:wrap;gap:6px;
  padding:0 14px 9px;font:600 12px/1 var(--sans)}
.fiche-pick .fp-retour{color:rgba(255,255,255,.78);text-decoration:none;padding:7px 10px 7px 0;
  white-space:nowrap}
.fiche-pick .fp-retour:hover{color:#fff;text-decoration:underline}
/* L'état prend la place libre entre le retour et les boutons ; il s'efface
   de lui-même (js). Vert quand c'est enregistré, rouge quand c'est refusé. */
.fiche-pick .fp-etat{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:500;font-size:11.5px;color:rgba(255,255,255,.55)}
.fiche-pick .fp-etat.ok{color:#a8e6b4}
.fiche-pick .fp-etat.ko{color:#ffb3a7}
.fiche-pick .fp-outils button{height:28px;padding:0 12px;border:0;border-radius:99px;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font:600 12px/1 var(--sans);white-space:nowrap;flex:none;
  transition:background .15s}
.fiche-pick .fp-outils button:hover{background:rgba(255,255,255,.3)}
/* Le prix du site : seul le chiffre principal est enveloppé et retouchable,
   l'ancien prix barré reste hors de portée. Une boîte, pour que le liseré
   de [data-modif] se dessine autour du chiffre et non du bloc entier. */
html[data-edition] #pprice [data-modif]{display:inline-block}
/* Dans la maquette, le titre, le prix et la description du gabarit se
   réécrivent aussi, même réduits par l'échelle : le curseur le dit. */
html[data-edition] .fp-maq [data-modif]{cursor:text}
/* Sur un petit écran, l'état passe seul sur sa ligne plutôt que d'écraser
   les boutons. */
@media(max-width:560px){.fiche-pick .fp-etat{flex-basis:100%;order:9}}
