/* =========================================================
   Maison Praline — design system boutique (mobile first)
   ========================================================= */
:root{
  --cream:#FFF6EF; --cream-2:#FFEDE1; --card:#FFFFFF; --card-2:#FFFAF6;
  --ink:#2B1A12; --ink-2:#6E5648; --ink-3:#77614C;
  --line:#F2E0D2; --line-2:#E9D3C1;
  /* LES MÊMES, GARDÉES À PART, COMME REPLI. Un design à socle réécrit la
     palette de la fiche à partir de ses propres `--d-*` ; s'il n'en
     déclare aucune, `var(--d-fond)` est invalide et emporte avec elle
     TOUT ce qui la cite, jusqu'au fond de la page. js/ui.js réécrit ces
     doublures aux couleurs du thème du commerçant. */
  --cream-base:#FFF6EF; --cream-2-base:#FFEDE1; --card-base:#FFFFFF; --card-2-base:#FFFAF6;
  --ink-base:#2B1A12; --ink-2-base:#6E5648; --ink-3-base:#77614C;
  --line-base:#F2E0D2; --line-2-base:#E9D3C1;
  --rose:#FF5F8F; --rose-d:#E4457A; --rose-l:#FFE4EC;
  --caramel:#E9A657; --caramel-l:#FDF0DC;
  --pist:#7CC9A4; --pist-l:#E3F6EC;
  --choco:#4A2C1D; --myrt:#8E7CE8; --myrt-l:#EDE9FD;
  /* La couleur pleine des éléments d'action de la BOUTIQUE (bouton
     « ajouter », catégorie active, bandeau…). UI.applyTheme() la remplace
     par l'accent sombre du thème choisi ; sans ça ces éléments restaient
     chocolat sur toutes les palettes, et le commerçant avait l'impression que
     sa couleur n'était pas prise en compte. Repli sur --choco pour la
     vitrine SHOPZY, qui garde SA propre identité (voir css/shopzy.css). */
  --fort:var(--choco);
  --ok:#2FA36B; --warn:#D98A1F; --err:#E24C4C;
  --r-s:12px; --r-m:18px; --r-l:26px; --r-xl:34px;
  --sh-s:0 2px 8px rgba(74,44,29,.06);
  --sh-m:0 10px 26px -10px rgba(74,44,29,.18), 0 2px 6px rgba(74,44,29,.05);
  --sh-l:0 26px 60px -22px rgba(74,44,29,.34), 0 6px 16px rgba(74,44,29,.07);
  /* Repli AVANT que UI.applyTheme() n'ait pu poser la vraie couleur de la
     boutique (JS pas encore chargé, ou hydrate() encore en vol — voir
     js/shop.js: await DB.ensure() précède tout rendu). Posé sur --rose
     (rose vif), ce repli teintait de rose le dégradé de la bannière
     (.hero-card, --acc-l en fond) au premier affichage et à chaque
     rafraîchissement, sur UNE BOUTIQUE DE N'IMPORTE QUELLE COULEUR —
     signalé en confondant ce flash avec un résidu de la démo. Neutre
     (brun/crème, déjà utilisé ailleurs comme couleur d'attente) au lieu
     d'une teinte de marque : le flash reste bref, mais il ne ment plus. */
  --acc:var(--choco); --acc-d:var(--choco); --acc-l:var(--cream-2);
  /* ── L'EN-TÊTE DE LA BOUTIQUE ──────────────────────────────────────
     Le thème shopzy (DESIGN.md, shopzy-theme.css) : fond blanc, filet
     fin, encre sombre. C'est la base de TOUTES les boutiques. Un design
     qui voudrait un autre en-tête n'a que ces quatre variables à
     redéclarer. */
  --sz-header-bg:#ffffff; --sz-header-ink:#1a1a18;
  --sz-header-line:#e5e3dc; --sz-header-survol:#f6f5f2;
  --serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,"Helvetica Neue",sans-serif;
  --nav-h:72px;
}
/* prefers-reduced-motion : neutralise TOUT (animations en boucle des blobs
   décoratifs, de la scène 3D produit, transitions de survol…) plutôt que de
   traquer chaque règle une à une — plus sûr, et n'oublie rien d'ajouté plus
   tard. Ne masque aucun contenu : seule la durée du mouvement change. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
/* Lien d'évitement : hors écran tant qu'il n'a pas le focus (jamais
   display:none, qui le rendrait aussi inatteignable au clavier que
   invisible) — premier élément tabulable de chaque page, avant la nav. */
.skip-link{position:absolute;left:8px;top:-100px;z-index:200;background:var(--ink);color:#fff;
  padding:10px 16px;border-radius:10px;font-weight:700;font-size:14px;transition:top .15s}
.skip-link:focus{top:8px}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{
  font-family:var(--sans); color:var(--ink); background:var(--cream);
  -webkit-font-smoothing:antialiased; line-height:1.45; overflow-x:hidden;
  padding-bottom:calc(var(--nav-h) + env(safe-area-inset-bottom,0px) + 8px);
}
body.no-nav{padding-bottom:0}
img{max-width:100%;display:block}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;border:0;background:none}
a{color:inherit;text-decoration:none}
h1,h2,h3{margin:0;font-family:var(--serif);font-weight:600;letter-spacing:-.01em}
h1{font-size:26px} h2{font-size:20px} h3{font-size:16px}
.muted{color:var(--ink-2)} .tiny{font-size:12px} .small{font-size:13px}
.wrap{max-width:1120px;margin:0 auto;padding:0 16px}
.row{display:flex;align-items:center;gap:10px}
.row.between{justify-content:space-between}
.spacer{flex:1}
.hide{display:none!important}

/* ---------- décor : blobs ---------- */
.bg-blobs{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
.blob{position:absolute;border-radius:50%;filter:blur(46px);opacity:.5;animation:drift 18s ease-in-out infinite}
.blob.b1{width:280px;height:280px;background:var(--rose-l);top:-70px;left:-60px}
.blob.b2{width:240px;height:240px;background:var(--caramel-l);top:32%;right:-90px;animation-delay:-6s}
.blob.b3{width:300px;height:300px;background:var(--pist-l);bottom:-120px;left:20%;animation-delay:-11s}
@keyframes drift{0%,100%{transform:translate(0,0) scale(1)}33%{transform:translate(18px,-22px) scale(1.06)}66%{transform:translate(-14px,16px) scale(.96)}}

/* ---------- header ---------- */
.appbar{position:sticky;top:0;z-index:40;backdrop-filter:saturate(180%) blur(14px);
  background:color-mix(in srgb,var(--cream) 82%,transparent);border-bottom:1px solid transparent;transition:border-color .2s}
.appbar.scrolled{border-color:var(--line)}
.appbar-in{display:flex;align-items:center;gap:12px;padding:12px 16px;max-width:1120px;margin:0 auto}
.brand{display:flex;align-items:center;gap:9px;font-family:var(--serif);font-size:19px;font-weight:600}
.brand .dot{width:30px;height:30px;border-radius:11px;background:linear-gradient(140deg,var(--acc),var(--caramel));
  display:grid;place-items:center;color:#fff;font-size:15px;box-shadow:var(--sh-s);overflow:hidden;flex:none}
.brand .dot img{width:100%;height:100%;object-fit:cover;display:block}
.iconbtn{width:44px;height:44px;border-radius:14px;display:grid;place-items:center;background:var(--card);
  box-shadow:var(--sh-s);border:1px solid var(--line);position:relative;transition:transform .12s}
.iconbtn:active{transform:scale(.93)}
.badge{position:absolute;top:-5px;right:-5px;min-width:19px;height:19px;padding:0 5px;border-radius:99px;
  background:var(--acc);color:var(--sur-acc,#fff);font-size:11px;font-weight:700;display:grid;place-items:center;border:2px solid var(--cream)}

/* ---------- bottom nav ---------- */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:50;padding:8px 12px calc(8px + env(safe-area-inset-bottom,0px));
  background:color-mix(in srgb,var(--cream) 86%,transparent);backdrop-filter:blur(16px) saturate(180%);border-top:1px solid var(--line)}
.tabbar-in{display:flex;justify-content:space-around;max-width:480px;margin:0 auto}
.tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 2px;border-radius:14px;
  color:var(--ink-3);font-size:10.5px;font-weight:600;position:relative;transition:color .18s}
.tab svg{width:23px;height:23px;stroke-width:1.7}
.tab.active{color:var(--acc)}
.tab.active svg{stroke-width:2.2}
.tab .badge{top:0;right:22%}
@media(min-width:900px){
  .tabbar{left:50%;right:auto;transform:translateX(-50%);bottom:16px;border:1px solid var(--line);
    border-radius:24px;box-shadow:var(--sh-l);width:430px;padding:8px 10px}
}

/* ---------- boutons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:13px 20px;border-radius:16px;
  font-weight:650;font-size:15px;background:var(--card);border:1px solid var(--line);box-shadow:var(--sh-s);transition:transform .12s,box-shadow .2s}
.btn:active{transform:scale(.97)}
/* L'encre du bouton principal n'est plus blanche en dur : js/ui.js
   (encreSurAccent) mesure la clarté de l'accent et pose --sur-acc. Sur un
   accent vif — jaune acide, cyan, menthe — le blanc tombait entre 1,1 et
   3,3 de contraste. Le repli reste le blanc : rien ne change tant que la
   mesure n'a pas eu lieu. */
.btn.primary{background:linear-gradient(135deg,var(--acc),var(--acc-d));
  color:var(--d-btn-encre, var(--sur-acc, #fff));border-color:transparent;
  box-shadow:0 12px 24px -10px color-mix(in srgb,var(--acc) 70%,transparent)}
.btn.dark{background:var(--fort);color:var(--sur-fort,#fff);border-color:transparent}
.btn.ghost{background:transparent;box-shadow:none}
.btn.block{width:100%}
.btn.sm{padding:9px 14px;font-size:13.5px;border-radius:13px}
.btn[disabled]{opacity:.45;pointer-events:none}
.chip{padding:9px 15px;border-radius:99px;background:var(--card);border:1px solid var(--line);
  font-size:13.5px;font-weight:600;white-space:nowrap;color:var(--ink-2);transition:all .18s}
.chip.on{background:var(--fort);color:var(--sur-fort,#fff);border-color:var(--fort)}
.scroller{display:flex;gap:9px;overflow-x:auto;padding:4px 16px 10px;scrollbar-width:none;scroll-snap-type:x proximity;max-width:1120px;margin:0 auto}
.scroller::-webkit-scrollbar{display:none}

/* ---------- champs ---------- */
.field{display:block;margin-bottom:14px}
.field>span{display:block;font-size:12.5px;font-weight:650;color:var(--ink-2);margin-bottom:6px}
.input,select.input,textarea.input{width:100%;padding:13px 14px;border-radius:15px;border:1px solid var(--line-2);
  background:var(--card);font-size:15px;transition:border-color .18s,box-shadow .18s}
.input:focus{outline:none;border-color:var(--acc);box-shadow:0 0 0 4px color-mix(in srgb,var(--acc) 16%,transparent)}
textarea.input{min-height:84px;resize:vertical}
select.input{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236E5648' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center}

/* ---------- autocomplétion d'adresse (Base Adresse Nationale) — panier.html ---------- */
.addr-wrap{position:relative;display:block}
.addr-sug{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:40;background:var(--card);
  border:1px solid var(--line-2);border-radius:14px;box-shadow:var(--sh-m);overflow:hidden auto;max-height:270px}
.addr-opt{display:block;width:100%;text-align:left;padding:11px 14px;border:0;background:none;cursor:pointer;
  font-size:14px;color:var(--ink);border-bottom:1px solid var(--line);line-height:1.3}
.addr-opt:last-child{border-bottom:0}
.addr-opt small{display:block;color:var(--ink-3);font-size:11.5px;margin-top:2px}
.addr-opt.on,.addr-opt:hover{background:var(--cream-2)}

/* ---------- hero ---------- */
/* max-width+margin:auto, comme .wrap/.appbar-in : sans ça, hero/recherche/
   catégories/grille restent bord à bord sur un écran large (juste 16px de
   marge plate) pendant que l'en-tête et les cartes du bas (déjà en .wrap)
   se centrent dans une colonne de 1120px — tout finit désaligné. */
.hero{padding:6px 16px 18px;max-width:1120px;margin:0 auto}
/* En tête de page, la bannière n'a plus le header au-dessus d'elle : elle
   respire un peu, sinon elle touche le bord de l'écran. */
.hero.tete{padding-top:14px}
/* Dégradé construit à partir des jetons du thème actif (--cream-2, --acc-l…)
   plutôt que de teintes fixes : sans ça, la carte d'accueil restait rose-
   violet pour absolument toutes les boutiques, quel que soit le thème
   choisi dans Réglages — thèmes sobres compris. */
.hero-card{position:relative;border-radius:var(--r-xl);padding:22px;overflow:hidden;
  background:linear-gradient(135deg,var(--cream-2),var(--acc-l) 60%,var(--cream));box-shadow:var(--sh-m)}
.hero-card h1{font-size:29px;line-height:1.1;max-width:70%}
.hero-card p{margin:8px 0 16px;font-size:14px;color:var(--ink-2);max-width:66%}
.hero-deco{position:absolute;right:-14px;bottom:-16px;width:150px;opacity:.96;pointer-events:none;filter:drop-shadow(0 12px 20px rgba(120,70,40,.22))}
.hero-tag{display:inline-flex;align-items:center;gap:6px;background:rgba(255,255,255,.72);padding:6px 12px;
  border-radius:99px;font-size:11.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#8A5A3E;margin-bottom:10px}

/* ════════════════════════════════════════════════════════════════════
   BANNIÈRE D'ACCUEIL — onze mises en page du même bloc
   Choisie par le gérant dans Réglages (catalogue : js/themes.js,
   HERO_STYLES), posée en attribut `data-hero` sur <html> par
   UI.applyTheme(). Comme pour les cadres d'articles, le sélecteur
   reste `[data-hero=…]` sans `html` devant, pour que le panneau
   Réglages puisse montrer onze aperçus réels côte à côte.

   BALISAGE COMMUN, JAMAIS MODIFIÉ (voir boutique.html) :
     .hero > .hero-card > .hero-tag  (la mention « ✦ … »)
                        > h1         (le titre)
                        > p          (l'accroche)
                        > .btn.dark  (le bouton)
                        > .hero-deco (l'ornement, vide hors pâtisserie)

   Les max-width de h1 et p ne servent qu'à réserver la place du gâteau
   en pâtisserie : chaque variante les remet à 100 % dès qu'elle range
   le contenu autrement, sinon le titre se coupe au tiers sans raison.

   PARTI PRIS MOBILE : les maquettes d'origine sont dessinées pour
   1120 px. Les transposer en empilant bêtement le contenu donnait onze
   bannières identiques sur un téléphone — même colonne, seule la
   couleur changeait — alors que c'est là qu'arrive la majorité des
   clients. Chaque bannière a donc sa propre traduction mobile, qui
   garde son signe distinctif : le filet vertical de « Colonne » devient
   horizontal, l'arche de « Voûte » passe au-dessus du texte, les deux
   panneaux de « Diptyque » s'empilent au lieu de se juxtaposer, et
   « Table » file d'un bord à l'autre de l'écran. Le CSS est donc écrit
   mobile d'abord : le bloc de base EST la version téléphone, la requête
   @media(min-width:720px) rétablit la maquette d'origine.
   ════════════════════════════════════════════════════════════════════ */

/* L'ornement (le gâteau des pâtisseries) appartient à la bannière d'origine :
   dans toutes les autres, il viendrait buter sur un bouton ou une colonne
   placés justement à droite. Seule « Voûte » le reprend, et pour y dessiner
   son arche — d'où le masquage de son contenu éventuel.
   « Voûte » est exclue de la sélection plutôt que rattrapée plus bas : un
   :not() compte dans la spécificité, et la règle de masquage l'emportait
   sinon sur celle qui rallume l'arche, quel que soit l'ordre des blocs. */
[data-hero]:not([data-hero="classique"]):not([data-hero="voute"]) .hero-deco{display:none}
[data-hero="voute"] .hero-deco>*{display:none}

/* ── Table : deux filets horizontaux, bouton à droite ── */
/* Mobile : les deux filets courent d'un bord à l'autre de l'écran — c'est
   ce qui distingue « Table » d'un simple bloc, et un bandeau pleine
   largeur est justement plus franc sur un téléphone que sur un grand
   écran. Le bouton prend toute la largeur : c'est l'action de la page. */
[data-hero="table"] .hero{padding-left:0;padding-right:0}
[data-hero="table"] .hero-card{background:var(--cream-2);border-radius:0;box-shadow:none;
  border-top:1px solid var(--acc);border-bottom:1px solid var(--acc);padding:22px 16px}
[data-hero="table"] .hero-card h1,[data-hero="table"] .hero-card p{max-width:100%}
[data-hero="table"] .hero-card h1{font-size:26px}
[data-hero="table"] .hero-card p{margin:8px 0 0}
[data-hero="table"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.16em}
[data-hero="table"] .hero-card .btn{border-radius:0;margin-top:16px;width:100%}
@media(min-width:720px){
  [data-hero="table"] .hero{padding-left:16px;padding-right:16px}
  [data-hero="table"] .hero-card .btn{width:auto}
  [data-hero="table"] .hero-card{display:grid;grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto auto auto;align-items:center;column-gap:40px;padding:30px 40px}
  [data-hero="table"] .hero-tag{grid-area:1/1/2/2}
  [data-hero="table"] .hero-card h1{grid-area:2/1/3/2;font-size:40px}
  [data-hero="table"] .hero-card p{grid-area:3/1/4/2}
  [data-hero="table"] .hero-card .btn{grid-area:1/2/4/3;margin:0;justify-self:end}
}

/* ── Centré : tout au milieu, bouton réduit à un lien souligné ── */
[data-hero="centre"] .hero-card{background:var(--card-2);border:1px solid var(--acc);border-radius:var(--r-m);
  box-shadow:none;display:flex;flex-direction:column;align-items:center;text-align:center;padding:30px 22px}
[data-hero="centre"] .hero-card h1,[data-hero="centre"] .hero-card p{max-width:100%}
[data-hero="centre"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.2em}
[data-hero="centre"] .hero-card p{margin:10px 0 14px}
[data-hero="centre"] .hero-card .btn{background:none;color:var(--acc-d);border:0;border-bottom:1px solid var(--acc);
  border-radius:0;box-shadow:none;padding:0 0 4px;font-size:12px;letter-spacing:.12em;text-transform:uppercase}
@media(min-width:720px){[data-hero="centre"] .hero-card h1{font-size:40px}}

/* ── Colonne : titre à gauche, accroche et bouton dans une colonne
      détachée par un filet vertical ── */
/* Mobile : le filet qui sépare le titre des détails ne peut plus être
   vertical à 343 px — il devient horizontal, et les deux zones restent
   bien deux zones. C'est le signe distinctif de cette bannière, sans lui
   elle se confond avec toutes les autres sur un téléphone. */
[data-hero="colonne"] .hero-card{background:var(--cream-2);border-radius:var(--r-m);box-shadow:none;padding:22px 18px}
[data-hero="colonne"] .hero-card h1,[data-hero="colonne"] .hero-card p{max-width:100%}
[data-hero="colonne"] .hero-card h1{font-size:26px}
[data-hero="colonne"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.16em}
[data-hero="colonne"] .hero-card p{margin:16px 0 12px;padding-top:14px;border-top:1px solid var(--line-2)}
@media(min-width:720px){
  [data-hero="colonne"] .hero-card{display:grid;grid-template-columns:minmax(0,1fr) 300px;
    grid-template-rows:auto auto;align-items:center;column-gap:40px;padding:30px 40px}
  [data-hero="colonne"] .hero-tag{grid-area:1/1/2/2}
  [data-hero="colonne"] .hero-card h1{grid-area:2/1/3/2;font-size:40px}
  [data-hero="colonne"] .hero-card p{grid-area:1/2/2/3;align-self:end;margin:0 0 0 30px;
    padding:0 0 0 30px;border-top:0;border-left:1px solid var(--line-2)}
  [data-hero="colonne"] .hero-card .btn{grid-area:2/2/3/3;justify-self:start;align-self:start;
    margin:14px 0 0 60px;border-radius:0}
}

/* ── Voûte : ornement en arche à droite. L'arche est dessinée sur
      .hero-deco, resté vide hors pâtisserie (voir js/shop.js) : c'est
      la seule variante qui s'en sert, les autres le laissent invisible. ── */
/* Mobile : l'arche ne peut pas rester à droite (elle prendrait la moitié
   de l'écran), elle passe AU-DESSUS du texte, centrée et réduite — la
   bannière garde son ornement, qui est toute son identité. */
[data-hero="voute"] .hero-card{background:var(--cream-2);border-radius:var(--r-m);box-shadow:none;
  padding:22px 18px;display:flex;flex-direction:column;align-items:center;text-align:center}
[data-hero="voute"] .hero-card h1,[data-hero="voute"] .hero-card p{max-width:100%}
[data-hero="voute"] .hero-card h1{font-size:26px}
[data-hero="voute"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.16em}
[data-hero="voute"] .hero-card p{margin:10px 0 16px}
[data-hero="voute"] .hero-deco{order:-1;position:static;display:grid;place-items:center;
  width:84px;height:98px;margin:0 0 14px;filter:none;
  border:1px solid var(--acc);border-radius:42px 42px 3px 3px}
[data-hero="voute"] .hero-deco::before{content:'✦';font-family:var(--serif);font-size:30px;color:var(--acc)}
@media(min-width:720px){
  [data-hero="voute"] .hero-card{display:block;text-align:left;padding:30px 40px;padding-right:230px}
  [data-hero="voute"] .hero-card h1{font-size:40px}
  [data-hero="voute"] .hero-deco{position:absolute;right:44px;bottom:auto;margin:0;
    top:50%;transform:translateY(-50%);width:150px;height:175px;border-radius:75px 75px 3px 3px}
  [data-hero="voute"] .hero-deco::before{font-size:46px}
}

/* ── Filigrane : le nom de la boutique en très grand, en fond.
      Le texte vient de --hero-mot, posé par UI.applyTheme() — le CSS
      ne peut pas lire le nom du commerce tout seul. ── */
[data-hero="filigrane"] .hero-card{background:var(--card-2);border-radius:var(--r-m);box-shadow:none;padding:22px 18px}
/* Mobile : filigrane nettement plus petit. À 110 px sur un écran de
   375 px, une seule syllabe du nom restait visible — ça ne se lisait plus
   comme un filigrane, juste comme une tache. */
[data-hero="filigrane"] .hero-card::after{content:var(--hero-mot,'');position:absolute;right:14px;bottom:-.18em;
  font-family:var(--serif);font-size:58px;line-height:1;color:var(--acc);opacity:.13;
  letter-spacing:-.02em;white-space:nowrap;pointer-events:none}
[data-hero="filigrane"] .hero-card h1{font-size:26px}
[data-hero="filigrane"] .hero-card>*{position:relative;z-index:1}
[data-hero="filigrane"] .hero-card h1,[data-hero="filigrane"] .hero-card p{max-width:100%}
[data-hero="filigrane"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.16em}
[data-hero="filigrane"] .hero-card p{margin:10px 0 16px}
[data-hero="filigrane"] .hero-card .btn{border-radius:0}
@media(min-width:720px){[data-hero="filigrane"] .hero-card{padding:30px 40px}
  [data-hero="filigrane"] .hero-card h1{font-size:40px}
  [data-hero="filigrane"] .hero-card::after{font-size:130px;right:24px;bottom:-.22em}}

/* ── Écrin : fond sombre, mention et bouton dans l'accent du thème ── */
[data-hero="ecrin"] .hero-card{background:#1c1618;border-radius:var(--r-m);box-shadow:none;padding:22px 18px}
[data-hero="ecrin"] .hero-card h1{color:#f4eae2;max-width:100%;font-size:26px}
[data-hero="ecrin"] .hero-card p{color:#a6938b;max-width:100%;margin:10px 0 16px}
[data-hero="ecrin"] .hero-tag{background:none;padding:0;color:var(--acc-l);letter-spacing:.2em}
/* Mobile : bouton pleine largeur — sur fond sombre, un petit bouton clair
   perdu à gauche se lit mal ; en bandeau il devient le point d'appui. */
[data-hero="ecrin"] .hero-card .btn{background:var(--acc-l);color:#1c1618;border-radius:0;width:100%}
@media(min-width:720px){
  [data-hero="ecrin"] .hero-card .btn{width:auto}
  [data-hero="ecrin"] .hero-card{display:grid;grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto auto auto;align-items:center;column-gap:40px;padding:30px 40px}
  [data-hero="ecrin"] .hero-tag{grid-area:1/1/2/2}
  [data-hero="ecrin"] .hero-card h1{grid-area:2/1/3/2;font-size:40px}
  [data-hero="ecrin"] .hero-card p{grid-area:3/1/4/2}
  [data-hero="ecrin"] .hero-card .btn{grid-area:1/2/4/3;margin:0;justify-self:end}
}

/* ── Trait : la mention à gauche, détachée du titre par un filet ── */
[data-hero="trait"] .hero-card{background:var(--cream-2);border-radius:var(--r-m);box-shadow:none;padding:22px 18px}
[data-hero="trait"] .hero-card h1,[data-hero="trait"] .hero-card p{max-width:100%}
[data-hero="trait"] .hero-card h1{font-size:26px}
/* Mobile : le filet passe à gauche de la mention. Il ne sépare plus deux
   colonnes, mais il reste là — c'est le trait qui donne son nom et sa
   silhouette à cette bannière. */
[data-hero="trait"] .hero-tag{background:none;padding:0 0 0 12px;color:var(--acc-d);letter-spacing:.16em;
  border-left:2px solid var(--acc);margin-bottom:12px}
[data-hero="trait"] .hero-card p{margin:8px 0 16px}
@media(min-width:720px){
  [data-hero="trait"] .hero-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-rows:auto auto;align-items:center;column-gap:24px;padding:30px 40px}
  /* max-width + retour à la ligne autorisé : une mention un peu longue
     (« ✦ Sélection de créateurs ») gardée sur une seule ligne mange la
     moitié de la bannière et écrase le titre sur trois lignes. */
  [data-hero="trait"] .hero-tag{grid-area:1/1/3/2;margin:0;padding:0 24px 0 0;max-width:190px;
    white-space:normal;line-height:1.5;border-left:0;
    border-right:1px solid var(--line-2);align-self:stretch;display:flex;align-items:center}
  [data-hero="trait"] .hero-card h1{grid-area:1/2/2/3;font-size:34px}
  [data-hero="trait"] .hero-card p{grid-area:2/2/3/3;margin:8px 0 0}
  [data-hero="trait"] .hero-card .btn{grid-area:1/3/3/4;justify-self:end;border-radius:0}
}

/* ── Socle : bandeau de repères en bas, séparé par un filet.
      L'accroche descend dans ce socle : c'est le seul contenu dont on
      dispose, le balisage n'ayant pas de troisième ligne de texte. ── */
[data-hero="socle"] .hero-card{background:var(--cream-2);border-radius:var(--r-m);box-shadow:none;
  display:flex;flex-direction:column;padding:22px 18px}
[data-hero="socle"] .hero-card h1{max-width:100%;order:2;font-size:26px}
[data-hero="socle"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.16em;order:1}
[data-hero="socle"] .hero-card .btn{order:3;margin-top:16px;align-self:flex-start;border-radius:0}
[data-hero="socle"] .hero-card p{order:4;max-width:100%;margin:16px 0 0;padding-top:14px;
  border-top:1px solid var(--line-2);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase}
@media(min-width:720px){
  [data-hero="socle"] .hero-card{display:grid;grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto auto auto;align-items:end;column-gap:40px;padding:30px 40px}
  [data-hero="socle"] .hero-tag{grid-area:1/1/2/2}
  [data-hero="socle"] .hero-card h1{grid-area:2/1/3/2;font-size:38px}
  [data-hero="socle"] .hero-card .btn{grid-area:1/2/3/3;justify-self:end;align-self:center;margin:0}
  [data-hero="socle"] .hero-card p{grid-area:3/1/4/3;margin-top:18px}
}

/* ── Cadre : double filet tout autour, bouton en contour ── */
/* Mobile : filets resserrés (6 px au lieu de 8) et padding réduit, sinon
   les deux traits mangent la moitié de la largeur utile du téléphone. */
[data-hero="cadre"] .hero-card{background:var(--card-2);border:1px solid var(--acc);border-radius:var(--r-s);
  box-shadow:none;padding:22px}
[data-hero="cadre"] .hero-card::before{content:'';position:absolute;inset:6px;
  border:1px solid var(--line-2);border-radius:4px;pointer-events:none}
[data-hero="cadre"] .hero-card>*{position:relative}
[data-hero="cadre"] .hero-card h1,[data-hero="cadre"] .hero-card p{max-width:100%}
[data-hero="cadre"] .hero-card h1{font-size:25px}
[data-hero="cadre"] .hero-tag{background:none;padding:0;color:var(--acc-d);letter-spacing:.2em}
[data-hero="cadre"] .hero-card p{margin:10px 0 16px}
[data-hero="cadre"] .hero-card .btn{background:none;color:var(--acc-d);border:1px solid var(--acc);
  border-radius:0;box-shadow:none}
@media(min-width:720px){
  [data-hero="cadre"] .hero-card{display:grid;grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto auto auto;align-items:center;column-gap:40px;padding:38px 44px}
  [data-hero="cadre"] .hero-card::before{inset:8px}
  [data-hero="cadre"] .hero-tag{grid-area:1/1/2/2}
  [data-hero="cadre"] .hero-card h1{grid-area:2/1/3/2;font-size:38px}
  [data-hero="cadre"] .hero-card p{grid-area:3/1/4/2}
  [data-hero="cadre"] .hero-card .btn{grid-area:1/2/4/3;margin:0;justify-self:end}
}

/* ── Diptyque : deux panneaux, le second sombre. Le fond sombre est un
      pseudo-élément placé dans la grille (pas un fond de colonne, qui
      n'existe pas en CSS) et débordé jusqu'aux bords par des marges
      négatives égales au padding de la carte. ── */
/* Mobile : les deux panneaux ne se juxtaposent plus, ils s'EMPILENT —
   clair en haut, sombre en bas, chacun pleine largeur. Un diptyque
   vertical reste un diptyque ; rabattre le panneau sombre en simple
   fond de bouton aurait fait disparaître la bannière. */
[data-hero="diptyque"] .hero-card{background:var(--cream-2);border-radius:var(--r-m);box-shadow:none;padding:0;
  display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto auto auto}
[data-hero="diptyque"] .hero-card::before{content:'';grid-area:3/1/5/2;background:#232620}
[data-hero="diptyque"] .hero-card h1,[data-hero="diptyque"] .hero-card p{max-width:100%}
[data-hero="diptyque"] .hero-tag{grid-area:1/1/2/2;background:none;padding:0;color:var(--acc-d);
  letter-spacing:.16em;margin:22px 18px 0}
[data-hero="diptyque"] .hero-card h1{grid-area:2/1/3/2;font-size:26px;margin:10px 18px 22px}
[data-hero="diptyque"] .hero-card p{grid-area:3/1/4/2;z-index:1;color:#e6e3db;margin:20px 18px 0}
[data-hero="diptyque"] .hero-card .btn{grid-area:4/1/5/2;z-index:1;border-radius:0;
  margin:14px 18px 22px;background:var(--acc-l);color:#232620}
@media(min-width:720px){
  [data-hero="diptyque"] .hero-card{grid-template-columns:1.35fr 1fr;
    grid-template-rows:auto auto;align-items:center;padding:0}
  [data-hero="diptyque"] .hero-card::before{content:'';grid-area:1/2/3/3;background:#232620;align-self:stretch;
    margin:0;height:100%}
  [data-hero="diptyque"] .hero-tag{grid-area:1/1/2/2;margin:30px 44px 0;align-self:end}
  [data-hero="diptyque"] .hero-card h1{grid-area:2/1/3/2;font-size:38px;margin:10px 44px 30px;align-self:start}
  [data-hero="diptyque"] .hero-card p{grid-area:1/2/2/3;z-index:1;color:#e6e3db;margin:30px 36px 0;align-self:end}
  [data-hero="diptyque"] .hero-card .btn{grid-area:2/2/3/3;z-index:1;justify-self:start;align-self:start;
    margin:14px 36px 30px;background:var(--acc-l);color:#232620}
}

/* ---------- recherche ---------- */
/* width explicite (pas seulement margin:auto) : sans valeur définie, une
   boîte flex en largeur "auto" occupe tout l'espace disponible et un
   margin:auto ne centre alors plus rien — voir le commentaire sur .hero. */
.searchbar{display:flex;align-items:center;gap:10px;padding:12px 15px;border-radius:18px;background:var(--card);
  border:1px solid var(--line);box-shadow:var(--sh-s);width:calc(100% - 32px);max-width:1088px;margin:0 auto 14px}
.searchbar input{border:0;outline:none;background:none;flex:1;font-size:15px}

/* ---------- grille produits ---------- */
/* Les deux respirations sont nommées : le bandeau s'en sert pour se caler
   au plus près du texte (voir plus bas). */
/* Les deux respirations à zéro : le bandeau d'un rayon épouse sa ligne de
   texte, colle à ce qui le précède — les cartes du rayon du dessus — et
   aux articles qu'il annonce. Les bandes noires s'enchaînent alors sans
   blanc entre elles, comme les rayons d'une même page. */
.sec-head{--sh-haut:0px;--sh-bas:0px;
  display:flex;align-items:baseline;justify-content:space-between;
  padding:var(--sh-haut) 16px var(--sh-bas);max-width:1120px;margin:0 auto}
/* Sur bande noire, l'accent du thème (souvent sombre) disparaissait : les
   liens et le tri passent au blanc. */
.sec-head a{font-size:13px;font-weight:650;color:var(--acc-d)}
.sec-head a:hover{color:var(--ink)}
.sec-head select{color:var(--ink-2)!important}
.sec-head select option{color:var(--ink);background:var(--card)}
/* La couleur des intitulés de rayon, au choix du commerçant. Le repli est
   `inherit` et non une teinte en dur : sans réglage, le titre garde
   exactement l'encre qu'il avait, sur toutes les pages. Le sélecteur vise
   `.sec-head h2` et rien d'autre — ni les noms d'articles, ni les titres
   de page comme « Mon panier », ni quoi que ce soit du panneau de
   gestion, qui n'utilise pas cette classe. */
/* h1 ET h2 : sur la page Favoris, l'intitulé de rayon est un h1 (« Mes
   favoris ») — il restait le seul à ne pas suivre la couleur choisie. */
/* Blanc par défaut, puisque le bandeau est noir. Le réglage « couleur des
   titres » du commerçant reste prioritaire s'il en a choisi une. */
/* L'intitulé prend l'encre de la page, plus le blanc du bandeau disparu. */
.sec-head h1,.sec-head h2{color:var(--titre-color,var(--ink))}

/* UN BANDEAU BLANC COURT DERRIÈRE CHAQUE INTITULÉ DE RAYON. Sur un fond
   photographique ou animé, un titre posé à même le décor devient
   illisible dès qu'une zone claire passe dessous ; le bandeau lui donne
   un sol franc, quoi qu'il se passe derrière.

   Il est peint par un pseudo-élément qui DÉBORDE jusqu'aux bords de
   l'écran (`width:100vw` recentré), au lieu d'un fond posé sur
   `.sec-head` : cette barre est bornée à 1120 px et centrée, son fond se
   serait donc arrêté au milieu de l'écran sur un grand moniteur — une
   bande blanche flottante au lieu d'un bandeau. */
/* Même bandeau derrière la bande des CATÉGORIES. Il couvre toute sa
   hauteur : les pastilles ont leur propre fond, mais l'espace entre elles
   laissait passer le décor, et la rangée se lisait comme une suite de
   jetons flottants plutôt que comme un rayon. */
/* LES CATÉGORIES SONT DU TEXTE, PAS DES BOUTONS. Une rangée de pastilles
   se lisait comme une barre d'outils ; une ligne de mots séparés par un
   trait se lit comme les rayons d'une maison. La zone cliquable reste
   généreuse — le trait sépare, il ne rétrécit pas la cible. */
.cats-bande .chip{background:none;border:0;border-radius:0;padding:4px 0;
  color:var(--ink-3);font-weight:600;font-size:14px}
.cats-bande .chip.on{color:var(--ink);font-weight:700}
.cats-bande .chip:hover{color:var(--ink-2)}
/* Le trait vit sur le VOISIN DE GAUCHE, jamais sur le dernier élément :
   un trait après le dernier mot flotterait dans le vide en bout de
   rangée. */
.cats-bande .chip + .chip{border-left:1px solid var(--ink);
  padding-left:15px;margin-left:6px;line-height:1.1}
/* Le « + » de création de rayon (aperçu du panneau) : voir css/edition.css. */

/* LA BANDE DES RAYONS PROLONGE LE MENU. Même noir, aucune couture entre
   les deux : c'est un seul bloc qui tient le haut de l'écran. Le fond est
   posé directement, sans le calque débordant qu'il fallait tant qu'elle
   vivait au milieu de la page — dans l'en-tête, elle occupe déjà toute la
   largeur. */
/* La rangée des rayons suit l'en-tête : blanche, filet fin, texte
   sombre. Dans le thème de la boutique ce sont des liens de navigation,
   pas une bande de contraste. */
.cats-bande{position:relative;background:var(--sz-header-bg);
  border-bottom:1px solid var(--sz-header-line)}
.cats-bande .chip{color:#5f5e5a}
.cats-bande .chip.on{color:var(--sz-header-ink)}
.cats-bande .chip:hover{color:var(--sz-header-ink)}
/* Le séparateur suit le filet de l'en-tête. */
.cats-bande .chip + .chip{border-left-color:var(--sz-header-line)}
/* La rangée se resserre contre le menu — sans cela, un blanc les séparait
   et le bloc se lisait en deux morceaux — et la bande épouse la hauteur du
   texte : 49 px pour une ligne de 20 en faisait un second bandeau sous le
   menu, là où il ne faut qu'un ourlet. Mesuré après : 30 px. */
header.appbar .cats-bande .scroller{padding-top:0;padding-bottom:3px}

/* SUR LA FICHE ARTICLE, LE BANDEAU NE DÉBORDE PAS. Il est fait pour une
   page en UNE colonne, où traverser l'écran de bord à bord a un sens. La
   fiche peut être en deux colonnes (toute mise en page qui en déclare
   deux, et tout écran large) : une bande de la largeur de la fenêtre
   partait alors sous le
   visuel et le barrait de blanc — constaté sur l'aperçu en mode
   Ordinateur. Ici, elle s'arrête à son propre conteneur. */
.pwrap .sec-head::before{left:0;width:100%;margin-left:0}

/* Un bandeau d'annonce VIDE n'occupe plus rien. Il gardait sa marge basse
   même sans texte, et ces 12 px séparaient la bande des rayons du premier
   titre — un vide que rien ne justifiait. */
/* Tant que les données ne sont pas là, on ne montre RIEN plutôt qu'un
   contenu faux : les sections gardent leur place (aucun saut à
   l'arrivée), mais restent invisibles. Le fond et la bannière, eux,
   s'affichent tout de suite — ils ne dépendent d'aucune donnée. */
/* `[role=main]` autant que `main` : la fiche produit n'a pas de balise
   <main>, son conteneur est un div `.pwrap[role=main]`. Le masque ne s'y
   appliquait donc PAS, et le squelette de la page s'affichait en clair
   pendant une seconde ou deux avant que les données n'arrivent : photo
   vide, prix à « — », et des intitulés de pâtisserie sur une boutique qui
   n'en est pas une. La barre d'achat vit hors du conteneur, elle se masque
   à part. */
html.chargement main,
html.chargement [role="main"],
html.chargement .stickybar{visibility:hidden}
main,[role="main"],.stickybar{transition:opacity .25s ease}
html.chargement main,
html.chargement [role="main"],
html.chargement .stickybar{opacity:0}

#banner:empty{display:none}

.sec-head{position:relative}
.sec-head::before{content:'';position:absolute;z-index:-1;
  /* Serré sur la LIGNE DE TEXTE, pas sur la barre : celle-ci porte ses
     respirations (14 px au-dessus, 10 en dessous), et les inclure donnait
     un pavé blanc de 53 px là où le titre n'en occupe que 29. Le bandeau
     s'arrête donc là où le texte s'arrête. */
  top:var(--sh-haut);bottom:var(--sh-bas);
  left:50%;width:100vw;margin-left:-50vw;
  /* PLUS DE BANDE NOIRE derrière les intitulés de rayon. Elle servait de
     sol franc sur un fond photographique ; le thème de la boutique
     (DESIGN.md) n'en a pas — ses titres de section sont du texte sombre
     sur blanc, avec « Tout voir » en accent. Le bandeau reste déclaré :
     un design peut le rallumer en posant --bandeau-titre. */
  background:var(--bandeau-titre,transparent)}
/* minmax(0,1fr), pas 1fr tout court : un `1fr` seul équivaut à
   minmax(auto,1fr) — la piste refuse de descendre sous la largeur de son
   contenu (ex. un nom de produit long) et pousse toute la grille en dehors
   de l'écran (masqué par overflow-x:hidden sur body, d'où l'impression que
   les cartes ne sont plus centrées — en réalité la grille déborde à droite). */
.grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:13px;padding:0 16px;max-width:1120px;margin:0 auto}
@media(min-width:640px){.grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}}
@media(min-width:960px){.grid{grid-template-columns:repeat(4,minmax(0,1fr))}}
/* --cadre-ratio : la proportion commune à tous les cadres, lue par la règle
   juste en dessous. Resserrée sur téléphone, où la carte ne fait que
   165 px de large.
   --cadre-pad était la marge intérieure commune à tous les cadres : ses
   trente-sept lecteurs étaient les règles propres à chaque cadre, parties
   avec le catalogue. PLUS AUCUNE RÈGLE NE LA LIT
   aujourd'hui ; on la garde parce que c'est elle qui donnera aux prochains
   cadres la même respiration, et on l'écrit ici pour que la prochaine
   lecture ne reparte pas en chasse. */
:root{--cadre-pad:10px;--cadre-ratio:165/286}
@media(min-width:640px){:root{--cadre-pad:14px;--cadre-ratio:255/378}}

/* LA règle qui donne la même taille à tous les cadres. La hauteur de la
   carte est fixée par une proportion commune, et c'est le VISUEL qui absorbe
   l'écart : un cadre dont le pied est plus haut (un bouton pleine largeur,
   un cartouche) montre un visuel un peu plus court, jamais une carte plus
   grande. Sans ça, changer de cadre redimensionnait toute la boutique.
   Elle reste ici alors qu'il ne subsiste qu'un cadre : c'est elle qui tient
   l'alignement des rangées, et les prochains cadres s'y accrocheront.
   `margin-top:0` sur le pied est indispensable ici : une marge auto absorbe
   l'espace libre AVANT flex-grow, le visuel ne grandissait donc jamais et
   tout l'écart repartait en trou au-dessus du prix. */
[data-card] .pcard{aspect-ratio:var(--cadre-ratio);min-height:0}
[data-card] .pcard .thumb{flex:1 1 auto;min-height:0}
[data-card] .pcard .foot{margin-top:0}


/* GARDE-FOU DES APERÇUS DU PANNEAU RÉGLAGES — à laisser dans CE fichier.
   Les aperçus de cadres et de bannières contiennent de vraies cartes, et
   c'est css/admin.css qui leur donne leur largeur. Si ce fichier-là arrive
   en retard ou reste en cache après une mise à jour, la proportion définie
   juste au-dessus étire chaque aperçu sur toute la largeur de l'écran :
   mesuré à 5223 px de haut sur un téléphone, soit une page de Réglages
   interminable. La proportion est déclarée ici, sa limite aussi — pour
   qu'aucun des deux ne puisse voyager sans l'autre. */
/* La bande reste une LIGNE qui défile même sans admin.css : empilés, les
   aperçus font des milliers de pixels de haut, soit une page à rallonge.
   admin.css garde tout le reste (marges, accroche au défilement, cadre de
   sélection) — ici, seulement de quoi que la page reste utilisable. */
.card-pick{display:flex;gap:12px;overflow-x:auto}
.card-pick>*{flex:0 0 auto}
.cp-stage{display:block;max-width:200px}
.cp-stage .pcard{max-width:100%}

.hp-frame{display:block;max-width:276px;max-height:97px;overflow:hidden}
.pcard{position:relative;background:var(--card);border-radius:var(--r-l);padding:10px;border:1px solid var(--line);
  box-shadow:var(--sh-s);transition:transform .18s,box-shadow .25s;display:flex;flex-direction:column}
/* Filet de sécurité pour tout contexte SANS règle .photo-frame dédiée (ex.
   l'aperçu du formulaire admin, #prev) : aspect-ratio donne d'office une
   hauteur, sans dépendre d'un parent qui en aurait une explicite. Les
   contextes qui ont leur propre règle (carte produit, panier, mini-vignettes
   admin) fixent width/height eux-mêmes et prennent le dessus normalement. */
.photo-frame{aspect-ratio:1/1;overflow:hidden;border-radius:inherit}
.pcard:active{transform:scale(.975)}
@media(hover:hover){.pcard:hover{transform:translateY(-4px);box-shadow:var(--sh-m)}}
.pcard .thumb{position:relative;aspect-ratio:1/1;border-radius:20px;overflow:hidden;
  background:transparent;display:grid;place-items:center}
.pcard .thumb svg{width:82%;height:82%;filter:drop-shadow(0 10px 14px rgba(120,70,40,.18))}
/* Même respiration que les visuels dessinés/émoji ci-dessus — .photo-frame
   est un vrai <div> (voir js/visuals.js), pas de souci de pourcentage sur
   balise remplacée comme avec un <img> directement. */
.pcard .thumb .photo-frame{width:82%;height:82%;filter:drop-shadow(0 10px 14px rgba(120,70,40,.18))}
/* DEUX LIGNES, PAS UNE DE PLUS. Les noms venus d'un import (« Couverture
   d'été rafraîchissante de classe A pour la mère et le nourrisson »)
   couraient sur cinq lignes et repoussaient le prix hors de la carte,
   déformant toute la rangée. Coupé net à deux lignes, avec des points de
   suspension : le nom entier reste sur la fiche article.

   `min-height` en plus du plafond : sans elle, une carte au nom court se
   tasserait et les prix de la rangée ne s'aligneraient plus. */
.pcard .name{font-weight:650;font-size:14px;margin:9px 2px 2px;line-height:1.25;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;
  overflow:hidden;min-height:calc(2 * 1.25em)}
.pcard .cat{font-size:11.5px;color:var(--ink-3);margin:0 2px}
.pcard .foot{display:flex;align-items:center;justify-content:space-between;margin-top:auto;padding:8px 2px 2px}
/* Le prix ne se coupe JAMAIS. Dans une carte étroite — quatre
   suggestions de front sur la fiche article — « 45,90 € » passait à la
   ligne et le symbole se retrouvait seul sous le chiffre. */
.price{font-weight:750;font-size:15.5px;white-space:nowrap}
.pcard .foot{gap:8px}
.pcard .foot .price{min-width:0;overflow:hidden;text-overflow:ellipsis}
.price .old{font-size:12px;color:var(--ink-3);text-decoration:line-through;font-weight:500;margin-left:5px}
/* Zone cliquable élargie à 44px (repère d'accessibilité tactile) SANS
   agrandir le bouton visuellement — la carte est trop dense pour ça,
   dans un cadre en ligne. Un pseudo-élément débordant fait l'affaire :
   il reste dans la boîte du bouton pour la détection de clic, sans peser
   sur la mise en page (position:absolute n'affecte jamais le flux). */
.add{width:34px;height:34px;border-radius:12px;background:var(--fort);color:#fff;display:grid;place-items:center;transition:transform .14s;position:relative}
.add::after{content:'';position:absolute;inset:-5px}
.add:active{transform:scale(.85)}
.flag{position:absolute;top:16px;left:16px;padding:4px 9px;border-radius:99px;background:var(--acc);color:var(--sur-acc,#fff);
  font-size:10.5px;font-weight:750;letter-spacing:.02em;z-index:2}
.flag.soft{background:var(--fort);color:var(--sur-fort,var(--sur-acc,#fff))}
.flag.out{background:var(--ink-3)}
.fav{position:absolute;top:14px;right:14px;width:31px;height:31px;border-radius:50%;background:rgba(255,255,255,.9);
  display:grid;place-items:center;z-index:2;box-shadow:var(--sh-s)}
.fav::after{content:'';position:absolute;inset:-6px}
.fav svg{width:16px;height:16px;stroke:var(--ink-2);fill:none}
.fav.on svg{fill:var(--rose);stroke:var(--rose)}
/* La note suit le thème plutôt que de rester dorée : var(--caramel)
   (#E9A657) sur fond blanc ne donne que 2,0:1, très en dessous du seuil
   lisible — et c'est un vrai texte (« 4,8 »), pas une décoration.
   --acc-d est la teinte du thème déjà vérifiée sur blanc ET sur les deux
   crèmes pour les 23 palettes. Un cadre à fond sombre qui voudrait garder
   son or devra, comme avant, le déclarer dans sa propre règle. */
.stars{display:flex;gap:1px;align-items:center;font-size:11px;color:var(--acc-d);font-weight:700}


/* =========================================================
   BLOC « LA MAISON » — mise en page du bloc adresse/horaires/contact
   (Réglages → Bloc « La maison » ; catalogue dans js/themes.js,
   LAMAISON_STYLES). Balisage commun à tous les styles (voir boutique.html) :
   .lm-badge (étiquette, une seule variante l'utilise), .lm-id (mention +
   monogramme), .lm-info (adresse/horaires/téléphone, un <p> par ligne,
   déjà rempli d'icônes par js/shop.js), .lm-actions (les 2 boutons).
   Par défaut (aucun `data-lamaison` ou 'classique') : la carte d'origine,
   inchangée pour toute boutique déjà réglée. */
.lm-card{position:relative}
.lm-badge,.lm-mono,.lm-sub{display:none}
.lm-id{display:flex;align-items:center;gap:12px}
.lm-id-txt h3{margin:0 0 10px}
.lm-info{display:flex;flex-direction:column}
.lm-info p{margin:0 0 10px}
.lm-info p:last-child{margin-bottom:0}
.lm-actions{display:flex;align-items:center;gap:8px;margin-top:14px}

/* ── Trois colonnes : identité, informations, actions côte à côte ── */
[data-lamaison="colonnes"] .lm-card{padding:26px}
@media(min-width:720px){
  [data-lamaison="colonnes"] .lm-card{display:grid;grid-template-columns:1fr 1fr auto;align-items:center;gap:28px}
  [data-lamaison="colonnes"] .lm-info{padding-left:28px;border-left:1px solid var(--line-2)}
  [data-lamaison="colonnes"] .lm-info p{margin:0 0 8px}
  [data-lamaison="colonnes"] .lm-actions{margin-top:0;flex-direction:column;align-items:flex-end}
}

/* ── Bandeau centré : tout au milieu, informations en ligne ── */
[data-lamaison="bandeau"] .lm-card{background:var(--cream-2);text-align:center;padding:28px 24px}
[data-lamaison="bandeau"] .lm-id{justify-content:center}
[data-lamaison="bandeau"] .lm-info{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:8px 22px;margin-top:6px}
[data-lamaison="bandeau"] .lm-info p{margin:0}
[data-lamaison="bandeau"] .lm-actions{justify-content:center}

/* ── Bloc contrasté : bandeau d'identité sombre à gauche, sous-titre visible ── */
[data-lamaison="contraste"] .lm-card{padding:0;overflow:hidden}
[data-lamaison="contraste"] .lm-sub{display:block;font-family:var(--serif);font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--acc-l);margin-top:6px}
@media(min-width:640px){
  [data-lamaison="contraste"] .lm-card{display:grid;grid-template-columns:230px 1fr}
  [data-lamaison="contraste"] .lm-id{background:var(--choco,#2b1a12);padding:26px;flex-direction:column;
    align-items:flex-start;justify-content:center;gap:0}
  [data-lamaison="contraste"] .lm-id-txt h3{color:#fff}
  [data-lamaison="contraste"] .lm-mono{display:none}
  [data-lamaison="contraste"] .lm-info{padding:24px 26px 0}
  [data-lamaison="contraste"] .lm-actions{padding:0 26px 24px;margin-top:14px}
}
@media(max-width:639px){
  [data-lamaison="contraste"] .lm-id{background:var(--choco,#2b1a12);padding:22px}
  [data-lamaison="contraste"] .lm-id-txt h3{color:#fff}
  [data-lamaison="contraste"] .lm-info{padding:18px 22px 0}
  [data-lamaison="contraste"] .lm-actions{padding:0 22px 22px}
}

/* ── Sombre : fond sombre, accents clairs (même palette que la
   bannière « Écrin », déjà vérifiée) ── */
[data-lamaison="sombre"] .lm-card{background:#1c1618;padding:26px}
[data-lamaison="sombre"] .lm-id-txt h3{color:#f4eae2}
[data-lamaison="sombre"] .lm-info p{color:#a6938b}
[data-lamaison="sombre"] .lm-actions .btn{background:none;border:1px solid rgba(255,255,255,.22);color:#f4eae2}
[data-lamaison="sombre"] .lm-actions .btn:first-child{background:var(--acc-l);color:#1c1618;border-color:transparent}
@media(min-width:640px){
  [data-lamaison="sombre"] .lm-card{display:flex;align-items:center;justify-content:space-between;gap:28px}
  [data-lamaison="sombre"] .lm-info{flex-direction:row;flex-wrap:wrap;gap:6px 22px}
  [data-lamaison="sombre"] .lm-info p{margin:0}
  [data-lamaison="sombre"] .lm-actions{margin-top:0;flex-direction:column;flex:none}
}

/* ── Filet or : double bordure fine tout autour ── */
[data-lamaison="filetor"] .lm-card{background:var(--card-2);border:1px solid var(--acc);padding:6px}
[data-lamaison="filetor"] .lm-card::before{content:'';display:block;position:absolute;inset:6px;
  border:1px solid var(--line-2);border-radius:calc(var(--r-l) - 6px);pointer-events:none}
[data-lamaison="filetor"] .lm-card{padding:22px}
[data-lamaison="filetor"] .lm-actions{margin-top:16px}

/* ── Une ligne : tout sur une seule bande, filets haut/bas ── */
[data-lamaison="ligne"] .lm-card{background:none;border:0;box-shadow:none;border-top:1px solid var(--line-2);
  border-bottom:1px solid var(--line-2);border-radius:0;padding:20px 4px}
@media(min-width:860px){
  [data-lamaison="ligne"] .lm-card{display:flex;align-items:center;gap:24px}
  [data-lamaison="ligne"] .lm-id{flex:none}
  [data-lamaison="ligne"] .lm-info{flex-direction:row;flex-wrap:wrap;gap:6px 22px;flex:1}
  [data-lamaison="ligne"] .lm-info p{margin:0}
  [data-lamaison="ligne"] .lm-actions{margin-top:0;flex:none}
}

/* ── Carte à onglet : une étiquette qui dépasse en haut ── */
[data-lamaison="onglet"] .lm-card{padding:30px 24px 24px;margin-top:12px}
[data-lamaison="onglet"] .lm-badge{display:inline-block;position:absolute;top:0;left:24px;transform:translateY(-50%);
  font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#fff;
  background:var(--acc-d);padding:6px 14px;border-radius:99px}
@media(min-width:640px){
  [data-lamaison="onglet"] .lm-card{display:flex;align-items:center;justify-content:space-between;gap:24px}
  [data-lamaison="onglet"] .lm-info{flex-direction:row;flex-wrap:wrap;gap:6px 20px}
  [data-lamaison="onglet"] .lm-info p{margin:0}
  [data-lamaison="onglet"] .lm-actions{margin-top:0;flex:none}
}

/* ── Colonne enseigne : un bandeau d'initiales sur le côté ── */
[data-lamaison="enseigne"] .lm-card{padding:0;overflow:hidden}
[data-lamaison="enseigne"] .lm-mono{display:flex;align-items:center;justify-content:center;font-family:var(--serif);
  font-size:26px;color:#fff;background:var(--acc-d);flex:none}
[data-lamaison="enseigne"] .lm-id{gap:0}
[data-lamaison="enseigne"] .lm-id-txt{padding:22px 24px}
@media(min-width:640px){
  [data-lamaison="enseigne"] .lm-card{display:grid;grid-template-columns:110px 1fr auto}
  [data-lamaison="enseigne"] .lm-mono{width:110px;height:100%}
  [data-lamaison="enseigne"] .lm-info{padding:22px 24px;border-left:1px solid var(--line-2)}
  [data-lamaison="enseigne"] .lm-actions{padding:22px 24px 22px 0;margin-top:0;flex-direction:column}
}
@media(max-width:639px){
  [data-lamaison="enseigne"] .lm-mono{height:64px;width:100%}
  [data-lamaison="enseigne"] .lm-info{padding:0 22px 18px}
  [data-lamaison="enseigne"] .lm-actions{padding:0 22px 22px;margin-top:0}
}

/* ── Deux volets : informations et actions séparées, second volet sombre ── */
[data-lamaison="volets"] .lm-card{background:none;border:0;box-shadow:none;padding:0}
@media(min-width:640px){[data-lamaison="volets"] .lm-card{display:grid;grid-template-columns:1fr 1fr;gap:14px}}
[data-lamaison="volets"] .lm-id{padding:22px 24px 0}
[data-lamaison="volets"] .lm-info{padding:10px 24px 22px}
[data-lamaison="volets"] .lm-actions{background:var(--choco,#2b1a12);padding:22px 24px;margin:14px -0px -0px;
  border-radius:var(--r-l);flex-direction:column;align-items:flex-end}
@media(min-width:640px){[data-lamaison="volets"] .lm-actions{margin:0;flex-direction:row;align-items:center;justify-content:flex-end}}
[data-lamaison="volets"] .lm-actions .btn{background:none;border:1px solid rgba(255,255,255,.28);color:#fff}
[data-lamaison="volets"] .lm-actions .btn:first-child{background:#fff;color:var(--choco,#2b1a12);border-color:transparent}

/* ── Minimal : nom et téléphone en haut, reste en bas, un seul filet ── */
[data-lamaison="minimal"] .lm-card{background:var(--card-2);padding:24px}
[data-lamaison="minimal"] .lm-card{display:flex;flex-direction:column;gap:14px}
[data-lamaison="minimal"] .lm-id{justify-content:space-between}
[data-lamaison="minimal"] .lm-mono{display:none}
[data-lamaison="minimal"] .lm-info{border-top:1px solid var(--line-2);padding-top:14px;flex-direction:row;
  flex-wrap:wrap;justify-content:space-between;gap:8px}
[data-lamaison="minimal"] .lm-info p{margin:0}
[data-lamaison="minimal"] .lm-actions{margin-top:0}
@media(min-width:640px){[data-lamaison="minimal"] .lm-info{flex-wrap:nowrap}}

/* ---------- sheets / modales ---------- */
.sheet-bg{position:fixed;inset:0;background:rgba(43,26,18,.42);backdrop-filter:blur(3px);z-index:80;opacity:0;
  pointer-events:none;transition:opacity .24s}
.sheet-bg.on{opacity:1;pointer-events:auto}
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:90;background:var(--cream);border-radius:28px 28px 0 0;
  padding:10px 18px calc(20px + env(safe-area-inset-bottom,0px));transform:translateY(102%);transition:transform .3s cubic-bezier(.2,.9,.3,1);
  max-height:88vh;overflow-y:auto;box-shadow:0 -18px 50px rgba(74,44,29,.22)}
.sheet.on{transform:translateY(0)}
.sheet .grip{width:42px;height:5px;border-radius:99px;background:var(--line-2);margin:6px auto 14px}
@media(min-width:720px){
  .sheet{max-width:520px;margin:0 auto;border-radius:28px;bottom:auto;top:50%;transform:translateY(-40%) scale(.94);opacity:0}
  .sheet.on{transform:translate(0,-50%) scale(1);opacity:1;left:50%;margin-left:-260px}
}

/* ---------- toast ---------- */
/* Le message suit la même règle : plus de barre en bas, plus de réserve. */
body.no-nav .toast{bottom:calc(20px + env(safe-area-inset-bottom,0px))}
.toast{position:fixed;left:50%;bottom:calc(var(--nav-h) + 20px);transform:translate(-50%,20px);z-index:120;
  background:var(--fort);color:#fff;padding:12px 18px;border-radius:16px;font-size:14px;font-weight:600;
  box-shadow:var(--sh-l);opacity:0;pointer-events:none;transition:all .26s;display:flex;gap:9px;align-items:center;max-width:88vw}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* ---------- panier ---------- */
.citem{display:flex;gap:12px;padding:12px;background:var(--card);border:1px solid var(--line);border-radius:22px;margin-bottom:11px}
.citem .th{width:76px;height:76px;border-radius:16px;background:var(--cream-2);display:grid;place-items:center;flex:none}
.citem .th svg{width:80%;height:80%}
.citem .th .photo-frame{width:80%;height:80%}
.qty{display:flex;align-items:center;gap:4px;background:var(--cream-2);border-radius:99px;padding:3px}
/* Zone cliquable élargie (voir .add ci-dessus) — mais bornée côté intérieur
   (-2px, la moitié du .qty{gap:4px}) pour ne jamais empiéter sur le bouton
   voisin : un débordement symétrique de -8px sur les deux ferait chevaucher
   les deux zones et voler des clics au bouton d'à côté. */
.qty button{width:28px;height:28px;border-radius:50%;background:var(--card);display:grid;place-items:center;font-size:17px;font-weight:600;box-shadow:var(--sh-s);position:relative}
.qty button::after{content:'';position:absolute;inset:-8px}
.qty button:not(:last-child)::after{right:-2px}
.qty button:not(:first-child)::after{left:-2px}
.qty span{min-width:22px;text-align:center;font-weight:700;font-size:14px}
.summary{background:var(--card);border:1px solid var(--line);border-radius:24px;padding:16px;box-shadow:var(--sh-s)}
.summary .l{display:flex;justify-content:space-between;padding:6px 0;font-size:14.5px;color:var(--ink-2)}
.summary .l.total{border-top:1px dashed var(--line-2);margin-top:8px;padding-top:12px;font-size:19px;font-weight:750;color:var(--ink)}
.stickybar{position:fixed;left:0;right:0;bottom:calc(var(--nav-h) + env(safe-area-inset-bottom,0px));z-index:45;padding:12px 16px;
  background:color-mix(in srgb,var(--cream) 92%,transparent);backdrop-filter:blur(14px);border-top:1px solid var(--line)}
@media(min-width:900px){.stickybar{bottom:0;padding-bottom:96px;background:linear-gradient(to top,var(--cream) 70%,transparent)}}
/* LA BARRE D'ACHAT TOUCHE LE BAS DE L'ÉCRAN. Elle réservait 72 px pour la
   barre de navigation — celle qui flottait en bas de l'écran. Depuis que
   le menu est passé en HAUT, ces 72 px ne protégeaient plus rien : la
   barre « Ajouter au panier » flottait au-dessus du vide, à distance du
   bord, et venait recouvrir le nom de l'article.

   `no-nav` est posé par js/ui.js au moment même où le menu rejoint
   l'en-tête : les deux décisions ne peuvent pas se désaccorder.

   Seul l'espace du système est conservé (barre d'accueil de l'iPhone,
   gestes Android) — sans lui, le bouton passerait sous la barre du
   téléphone et deviendrait impossible à toucher. */
body.no-nav .stickybar{bottom:0;padding-bottom:calc(12px + env(safe-area-inset-bottom,0px))}
@media(min-width:900px){
  body.no-nav .stickybar{padding-bottom:calc(20px + env(safe-area-inset-bottom,0px))}
}
.empty{text-align:center;padding:60px 24px;color:var(--ink-2)}
.empty .big{font-size:54px;margin-bottom:10px}

/* ---------- étapes / steps ---------- */
.steps{display:flex;gap:6px;margin:4px 0 18px}
.steps i{flex:1;height:4px;border-radius:99px;background:var(--line-2)}
.steps i.on{background:var(--acc)}
.radio-card{display:flex;gap:12px;align-items:center;padding:14px;border-radius:18px;border:1.5px solid var(--line-2);
  background:var(--card);margin-bottom:10px;cursor:pointer;transition:all .18s}
.radio-card.on{border-color:var(--acc);background:var(--acc-l)}
.radio-card .k{width:22px;height:22px;border-radius:50%;border:2px solid var(--line-2);flex:none;display:grid;place-items:center}
.radio-card.on .k{border-color:var(--acc)}
.radio-card.on .k::after{content:"";width:11px;height:11px;border-radius:50%;background:var(--acc)}

/* Notice RGPD sous un formulaire de collecte : même disposition que les
   blocs d'info de la vitrine (icône carrée + texte, bordure pointillée),
   repris avec les couleurs de la boutique plutôt que le thème sombre. */
.rgpd-note{display:flex;gap:10px;align-items:flex-start;background:var(--card-2);
  border:1px dashed var(--line-2);border-radius:var(--r-m);padding:11px 13px;margin-top:10px}
.rgpd-note .ic{font-size:14px;flex:none;width:28px;height:28px;border-radius:9px;background:var(--acc-l);display:grid;place-items:center}
.rgpd-note p{margin:0;font-size:12.5px;line-height:1.5;color:var(--ink-2)}
.rgpd-note a{color:var(--acc-d);font-weight:650}

/* ---------- suivi commande ---------- */
.track{position:relative;padding-left:30px}
.track .st{position:relative;padding-bottom:22px}
.track .st::before{content:"";position:absolute;left:-30px;top:2px;width:16px;height:16px;border-radius:50%;
  background:var(--card);border:2px solid var(--line-2)}
.track .st::after{content:"";position:absolute;left:-23px;top:20px;bottom:0;width:2px;background:var(--line-2)}
.track .st:last-child::after{display:none}
.track .st.done::before{background:var(--ok);border-color:var(--ok)}
.track .st.done::after{background:var(--ok)}
.track .st.now::before{background:var(--acc);border-color:var(--acc);box-shadow:0 0 0 5px color-mix(in srgb,var(--acc) 22%,transparent)}

/* =========================================================
   PAGE PRODUIT — scène 3D « studio » (esprit Spline)
   ========================================================= */
.stage{position:relative;height:56vh;min-height:330px;max-height:460px;overflow:hidden;
  background:radial-gradient(120% 80% at 50% 8%,#FFFFFF 0%,var(--stage-a,#FFE9F0) 42%,var(--stage-b,#FFD9C9) 100%);
  border-radius:0 0 40px 40px;touch-action:pan-y;user-select:none}
.stage .halo{position:absolute;left:50%;top:52%;width:74vw;max-width:360px;aspect-ratio:1;transform:translate(-50%,-50%);
  border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,.92),rgba(255,255,255,0) 68%);filter:blur(2px)}
.stage .ring{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);border-radius:50%;
  border:1.5px dashed rgba(255,255,255,.75);animation:spin 26s linear infinite}
.stage .ring.r1{width:78vw;max-width:380px;aspect-ratio:1}
.stage .ring.r2{width:60vw;max-width:290px;aspect-ratio:1;animation-duration:18s;animation-direction:reverse;opacity:.6}
@keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}}
.stage .spark{position:absolute;border-radius:50%;background:#fff;opacity:.85;animation:float 7s ease-in-out infinite}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-16px)}}

/* ── Page produit : article FIGÉ et à plat (comme la carte du catalogue) —
   plus de rotation, de flottement, ni de relief 3D. Demande utilisateur.
   Le JS ne pose plus de transform (voir « article figé » dans product.js) ;
   ici on neutralise le relief CSS (perspective + translateZ des calques) et
   on retire les décors animés (anneaux, étincelles). !important pour primer
   sur un éventuel style inline résiduel. */
.stage .ring,.stage .spark{display:none}
.stage .scene{perspective:none}
.stage .obj{transform:none!important;transform-style:flat;animation:none!important}
.stage .obj .lay{transform:none!important}

/* Le visuel produit adopte le CADRE choisi (Réglages → Vitrine) : .prodhero est
   une VRAIE .pcard, donc les décors du cadre (bordures, ornements ::before/
   ::after) l'entourent exactement comme sur la carte du catalogue. Le visuel
   reste figé, centré. On dimensionne juste la carte en « héros » ; le cadre,
   lui, garde la main sur padding/bordure/fond/ornements (blocs plus bas). */
/* Le visuel produit adopte le CADRE choisi et REMPLIT toute la scène : le
   cadre recouvre entièrement le fond (plus de marge beige autour), et le
   visuel est agrandi. Mobile ET grand écran. La scène a overflow:hidden +
   border-radius : le cadre est donc rogné proprement à la forme de la scène.
   .prodhero-vis en z-index:2 + overflow:hidden : le visuel reste au-dessus des
   remplissages/ornements du cadre et ne peut jamais déborder. */
.stage .scene{display:grid;place-items:stretch;padding:0}
.stage .prodhero{aspect-ratio:auto;width:100%;height:100%;max-width:none;margin:0;display:flex;flex-direction:column}
.stage .prodhero:hover{transform:none}
.stage .prodhero .prodhero-vis{flex:1;min-height:0;width:100%;display:grid;place-items:center;position:relative;z-index:2;overflow:hidden}
/* LE VISUEL OCCUPE TOUT L'EMPLACEMENT. Il était borné à 72 % de la
   largeur dans un carré : sur une photo en pied, l'article se retrouvait
   petit au milieu d'une grande zone vide. Il prend maintenant toute la
   place disponible, et garde ses proportions — une robe touche le haut et
   le bas du cadre sans être rognée à la taille. */
.stage .prodhero .obj{width:100%;height:100%;aspect-ratio:auto;max-width:none;max-height:100%}
/* Plus d'arrondi sur la photo elle-même : elle épouse désormais le cadre,
   qui porte déjà le sien. Deux arrondis emboîtés se voyaient. */
.stage .prodhero .obj img{border-radius:0!important}
/* Pas de vignette crème derrière le visuel sur la page produit : l'emoji (ou
   le dessin) repose directement sur le fond du cadre. Le fond crème de la
   « carte emoji » (rect de emojiCard) et le fond de scène sont neutralisés. */
.stage .prodhero .obj svg rect{fill:transparent}
.stage{background:var(--card)}
.stage .shadow-floor{display:none}

.scene{position:absolute;inset:0;display:grid;place-items:center;perspective:1100px;perspective-origin:50% 45%}
.obj{position:relative;width:min(74vw,330px);aspect-ratio:1;transform-style:preserve-3d;
  transition:transform .12s ease-out;will-change:transform}
.obj.idle{animation:hover3d 5.5s ease-in-out infinite}
@keyframes hover3d{0%,100%{translate:0 0}50%{translate:0 -14px}}
.obj .lay{position:absolute;inset:0;transform-style:preserve-3d;backface-visibility:visible}
.obj .lay svg{width:100%;height:100%;display:block}
/* Paire face/dos (deux photos) uniquement : backface-visibility:hidden pour
   que chaque face disparaisse quand elle regarde loin de l'écran, sinon on
   verrait les deux photos superposées, ou une version inversée de la face
   avant en tournant. Volontairement PAS sur .lay directement : les calques
   du dessert illustré, eux, doivent rester visibles à 360° (ce sont de
   simples tranches empilées, pas une paire face/dos). */
.obj .lay.flip-face{backface-visibility:hidden}
.shadow-floor{position:absolute;left:50%;bottom:14%;width:52%;height:8%;transform:translateX(-50%);
  background:radial-gradient(ellipse,rgba(120,70,40,.34),rgba(120,70,40,0) 70%);filter:blur(6px)}
.hint{position:absolute;left:50%;bottom:14px;transform:translateX(-50%);display:flex;align-items:center;gap:7px;
  padding:7px 14px;border-radius:99px;background:rgba(255,255,255,.72);backdrop-filter:blur(8px);
  font-size:11.5px;font-weight:650;color:#8A5A3E;letter-spacing:.02em;pointer-events:none;transition:opacity .4s}
.hint.gone{opacity:0}
.stage-top{position:absolute;top:0;left:0;right:0;display:flex;justify-content:space-between;padding:14px 16px;z-index:5}

/* LA DESCRIPTION EN ENCRE PLEINE. Elle héritait du gris des textes
   secondaires — celui des mentions et des étiquettes — alors que c'est le
   texte qu'on vient LIRE sur une fiche article : matière, coupe, tailles.
   Sur un fond photographique, ce gris s'y noyait. */
#pdesc{color:var(--ink);
  /* FILET : aucun mot ne peut déborder de sa colonne, quoi qu'il arrive.
     Les descriptions d'import contiennent parfois des blocs insécables —
     références, adresses, entités HTML mal décodées — que le navigateur
     traite comme un seul mot : il débordait alors sur la colonne voisine
     et passait par-dessus la photo de l'article. La correction de fond est
     côté serveur ; celle-ci protège de tout ce qu'on n'a pas prévu. */
  overflow-wrap:anywhere}
/* Même filet pour les caractéristiques et le récit, nourris des mêmes
   sources. */
.pdetail p,.pdetail li,.pdetail dd,.pdetail h1{overflow-wrap:anywhere}

.pdetail{background:var(--cream);border-radius:34px 34px 0 0;margin-top:-26px;position:relative;z-index:6;
  padding:22px 16px 0;box-shadow:0 -14px 34px -18px rgba(74,44,29,.28)}
/* Espace bas de la fiche produit : dégage la barre fixe « Ajouter au panier »
   (+ le menu). Sur ordinateur la barre monte à ~159px (fondu de 96px), il faut
   donc plus de marge — sinon « Vous aimerez aussi » reste sous la barre. */
.prod-bottom-space{height:120px}
@media(min-width:900px){.prod-bottom-space{height:190px}}
.pdetail h1{font-size:27px;line-height:1.12;margin-bottom:4px}
.ptags{display:flex;gap:7px;flex-wrap:wrap;margin:10px 0 14px}
.ptag{padding:6px 11px;border-radius:99px;background:var(--card);border:1px solid var(--line);font-size:12px;font-weight:600;color:var(--ink-2)}
.pprice{font-family:var(--serif);font-size:30px;font-weight:650}
.pprice .old{font-size:16px;color:var(--ink-3);text-decoration:line-through;margin-left:8px;font-family:var(--sans)}

.swatches{display:flex;gap:10px;flex-wrap:wrap}
.sw{width:42px;height:42px;border-radius:15px;border:2px solid transparent;box-shadow:var(--sh-s);position:relative;transition:transform .16s}
.sw::after{content:'';position:absolute;inset:-4px}
.sw.on{border-color:var(--ink);transform:scale(1.06)}
.sw:active{transform:scale(.92)}
.opt{display:flex;gap:9px;flex-wrap:wrap}
/* `white-space:nowrap` n'est pas cosmétique : les tailles d'un fournisseur
   de mode arrivent en « EU 36 | FR 36,5 », que le retour à la ligne pliait en
   cinq lignes dans une case de 65 px de large et 122 de haut. Mesuré : la même
   case redevient 136 × 61, et rien ne déborde, pas même sur un écran de
   375 px. `flex:0 0 auto` empêche la case de rétrécir sous son texte. */
.opt button{white-space:nowrap;flex:0 0 auto;
  padding:11px 15px;border-radius:15px;border:1.5px solid var(--line-2);background:var(--card);
  font-size:14px;font-weight:600;transition:all .16s;text-align:left}
.opt button.on{border-color:var(--ink);background:var(--ink);color:#fff}
.opt button small{display:block;font-weight:500;opacity:.7;font-size:11px}
.accordion{border-top:1px solid var(--line);padding:15px 2px}
.accordion summary{list-style:none;display:flex;justify-content:space-between;align-items:center;font-weight:650;cursor:pointer}
.accordion summary::-webkit-details-marker{display:none}
.accordion summary::after{content:"+";font-size:20px;color:var(--ink-3);font-weight:400}
.accordion[open] summary::after{content:"–"}
.accordion p{margin:10px 0 0;color:var(--ink-2);font-size:14.5px}
.nutri{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:8px;margin-top:12px}
.nutri div{background:var(--card);border:1px solid var(--line);border-radius:15px;padding:10px 6px;text-align:center}
.nutri b{display:block;font-size:15px} .nutri span{font-size:10.5px;color:var(--ink-3)}
@media(min-width:900px){
  .pwrap{display:grid;grid-template-columns:1.05fr .95fr;gap:34px;max-width:1120px;margin:0 auto;padding:0 16px;align-items:start}
  .stage{height:62vh;max-height:620px;border-radius:40px;margin-top:14px;position:sticky;top:80px}
  .pdetail{margin-top:14px;border-radius:34px;box-shadow:none;padding-top:8px;background:transparent}
}


/* ---------- calibrage des icônes SVG ---------- */
.iconbtn svg,.searchbar svg,.btn svg,.add svg,.toast svg{width:20px;height:20px;flex:none}
.btn.sm svg{width:16px;height:16px}
.stars svg{width:12px;height:12px;fill:currentColor;stroke:none;flex:none}
.stars{gap:3px}
.fav.on svg{fill:var(--rose)}
.iconbtn.heart-on svg{fill:var(--rose);stroke:var(--rose)}
.pprice{white-space:nowrap}
.hint{white-space:nowrap}
.pdetail .row.between>div:first-child{min-width:0;flex:1}
.ptag{display:inline-flex;align-items:center;gap:5px;line-height:1.3}
.ptag svg{width:13px;height:13px;fill:var(--caramel);stroke:none;flex:none}
.hint{bottom:46px}
.stars{display:inline-flex;vertical-align:-2px}
.pcard .cat{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---------- composeur de boîte ---------- */
.cpslots{display:flex;gap:9px;flex-wrap:wrap;margin:4px 0 12px}
.cpslot{width:46px;height:46px;border-radius:16px;border:2px dashed var(--line-2);background:var(--card);
  display:grid;place-items:center;font-size:12px;color:var(--ink-3);transition:transform .14s}
.cpslot.on{border:2px solid rgba(255,255,255,.7);box-shadow:var(--sh-s);color:transparent}
.cpslot:active{transform:scale(.9)}

/* ---------- avis ---------- */
.avis-head{display:flex;gap:16px;align-items:center;margin-bottom:14px}
.avis-note{font-family:var(--serif);font-size:38px;font-weight:650;line-height:1}
.avis{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:14px;margin-bottom:10px}
.avis .top{display:flex;justify-content:space-between;align-items:center;margin-bottom:5px}
.avis p{margin:0;font-size:14.5px;color:var(--ink-2)}
.rate-pick{display:flex;gap:8px}
.rate-pick button{font-size:30px;line-height:1;color:var(--line-2);padding:0}
.rate-pick button.on{color:var(--caramel)}
.bar-note{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--ink-3)}
.bar-note i{flex:1;height:6px;border-radius:99px;background:#F3E5D9;overflow:hidden}
.bar-note i b{display:block;height:100%;background:var(--caramel);border-radius:99px}
.alert-ok{background:var(--acc-l);border:1px solid var(--line);border-radius:16px;padding:11px 13px;font-size:13.5px;color:var(--ink-2)}
.alert-ok b{color:var(--ink)}

/* ---------- carte cadeau ---------- */
.gcard{border-radius:26px;padding:3px;background:linear-gradient(135deg,var(--acc),var(--caramel),var(--myrt));box-shadow:var(--sh-m)}
.gc-in{border-radius:23px;background:linear-gradient(150deg,#FFF6EF,#FFE9DF);padding:22px 20px;position:relative;overflow:hidden}
.gc-in::after{content:"";position:absolute;right:-30px;bottom:-40px;width:150px;height:150px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,255,255,.85),transparent 70%)}
.gc-amount{font-family:var(--serif);font-size:42px;font-weight:650;margin:10px 0 2px;letter-spacing:-.02em}
.gc-to{font-size:14px;color:var(--ink-2)}
.gc-code{margin-top:14px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:17px;font-weight:700;
  background:rgba(255,255,255,.72);border:1px dashed var(--line-2);border-radius:14px;padding:10px 12px;text-align:center;letter-spacing:.04em}
.gc-shop{margin-top:14px;font-family:var(--serif);font-size:15px;color:var(--ink-2)}
@media print{body{padding:0}.appbar,.tabbar,.btn,.muted{display:none!important}.gcard{box-shadow:none}
  /* Un « sheet » (modale, voir js/ui.js) est en position:fixed — sans ce
     correctif, l'imprimer (Ticket, Facture…) le laisse hors-flux et coupé
     à la hauteur d'un écran au lieu de suivre le contenu réel. Valable sur
     TOUTE page chargeant app.css (compte.html n'a pas css/admin.css, qui
     porte déjà ce correctif pour le panel gérant). */
  .sheet-bg{display:none!important}
  .sheet{position:static!important;transform:none!important;max-height:none;box-shadow:none;border-radius:0;opacity:1!important;margin:0!important;max-width:none!important}}

/* ---------- ① allergènes (js/product.js) ---------- */
.al-bloc{background:var(--cream-2);border-radius:14px;padding:11px 13px}
.al-bloc>b{font-size:13px;display:block;margin-bottom:7px}
.al-chips{display:flex;flex-wrap:wrap;gap:6px}
.al-chip{background:#fff;border:1px solid var(--line-2);border-radius:99px;padding:4px 10px;font-size:12px;font-weight:600;color:var(--ink-2)}

/* ---------- ① planche d'étiquettes (js/admin.js etiquettesSheet) ----------
   Deux colonnes à l'écran, trois à l'impression — une planche A4 tient
   confortablement 3 étiquettes de large. `break-inside:avoid` empêche une
   étiquette d'être coupée en deux par un saut de page. */
.etq-planche{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
.etq{border:1px dashed var(--line-2);border-radius:10px;padding:10px;background:#fff;break-inside:avoid;page-break-inside:avoid}
.etq-nom{font-size:13px;display:block;line-height:1.25}
.etq-prix{font-size:15px;font-weight:750;margin:3px 0 5px}
.etq-al{font-size:10.5px;line-height:1.35;color:var(--ink-2)}
.etq-info{font-size:10px;color:var(--ink-3);line-height:1.35}
.etq-shop{font-size:9.5px;color:var(--ink-3);margin-top:5px;text-transform:uppercase;letter-spacing:.04em}
@media print{.etq-planche{grid-template-columns:repeat(3,1fr)}}

/* ---------- facture (js/ui.js renderFacture, supabase/19-facture.sql) ----------
   Partagée entre le panel gérant et l'espace client (voir le commentaire
   dans ui.js) : volontairement PAS le style monospace du Ticket existant —
   un document qu'un client peut recevoir mérite une mise en page normale. */
.facture-doc{font-size:13.5px;line-height:1.55;color:var(--ink)}
.facture-doc .fd-head{display:flex;justify-content:space-between;gap:16px;margin-bottom:18px;padding-bottom:14px;border-bottom:2px solid var(--ink)}
.facture-doc .fd-shop{font-family:var(--serif);font-size:17px;display:block;margin-bottom:2px}
.facture-doc .fd-num{text-align:right;flex:none}
.facture-doc .fd-bill{margin-bottom:16px}
.facture-doc .fd-tbl{width:100%;border-collapse:collapse;margin-bottom:14px}
.facture-doc .fd-tbl th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-3);padding:6px 4px;border-bottom:1px solid var(--line)}
.facture-doc .fd-tbl td{padding:8px 4px;border-bottom:1px solid var(--line)}
.facture-doc .fd-tbl th:nth-child(n+2),.facture-doc .fd-tbl td:nth-child(n+2){text-align:right}
.facture-doc .fd-totaux{margin-left:auto;max-width:280px}
.facture-doc .fd-totaux>div{display:flex;justify-content:space-between;padding:4px 0}
.facture-doc .fd-net{font-size:16px;font-weight:750;border-top:1px solid var(--ink);margin-top:4px;padding-top:8px!important}
.facture-doc .fd-note{font-size:12.5px;color:var(--ink-3);margin:6px 0}

/* ---------- services (sur mesure, carte cadeau) ---------- */
.services{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.svc{background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);padding:14px;display:flex;
  flex-direction:column;gap:3px;box-shadow:var(--sh-s);transition:transform .16s}
.svc:active{transform:scale(.97)}
.svc b{font-size:14.5px}
.svc-ic{width:64px;height:64px;margin-bottom:4px}
.svc-ic svg{width:100%;height:100%}
.cpslot{border-radius:50%;width:44px;height:44px}
.swatches .sw{position:relative}

/* =========================================================
   DISPOSITIONS DE VITRINE (Réglages → Vitrine)
   Le balisage des cartes produit ne change JAMAIS : seule la grille qui les
   contient est habillée autrement. Panier, favoris et fiche produit restent
   donc câblés à l'identique quelle que soit la disposition choisie.
   ========================================================= */

/* ── Catalogue en liste : une ligne par article, vignette à gauche ──
   La carte produit a six enfants (drapeau, favori, vignette, titre, rayon,
   pied). Sans placement EXPLICITE, la grille leur donne à chacun une cellule
   et la « ligne » devient une colonne de 1400 px de haut. On fixe donc la
   vignette sur toute la hauteur à gauche, et on empile le reste à droite. */
.grid.liste{grid-template-columns:1fr; gap:10px}
.grid.liste .pcard{
  display:grid; grid-template-columns:96px 1fr;
  grid-template-rows:auto auto auto; column-gap:14px; row-gap:2px;
  align-content:center; padding:10px 12px;
  /* La carte porte un `aspect-ratio: 255/378` pour rester carrée en grille.
     Sur une ligne pleine largeur, ce ratio imposait 1435 px de haut. En
     liste, la hauteur doit suivre le contenu. */
  aspect-ratio:auto; height:auto;
}
.grid.liste .pcard .thumb{
  grid-column:1; grid-row:1 / -1; align-self:center;
  width:96px; height:96px; margin:0; border-radius:12px;
}
.grid.liste .pcard .ptitle{grid-column:2; grid-row:1; align-self:end}
.grid.liste .pcard .cat{grid-column:2; grid-row:2}
.grid.liste .pcard .foot{grid-column:2; grid-row:3; width:auto; align-self:start}
.grid.liste .pcard .fav{top:10px; right:10px}
/* Le badge est positionné pour la grille (centré au-dessus du titre) : sur
   une ligne il chevauchait le nom de l'article. On le pose sur la vignette. */
.grid.liste .pcard .flag{left:10px; top:10px; right:auto; transform:none}
/* Une ligne se lit à gauche : le centrage hérité de la grille rendait le
   parcours du regard inutilement fatigant. */
.grid.liste .pcard .ptitle,
.grid.liste .pcard .cat{text-align:left}
/* Prix à gauche, bouton compact à droite — au lieu d'un bouton qui barre
   toute la largeur de la ligne. */
.grid.liste .pcard .foot{
  display:flex; flex-direction:row; flex-wrap:nowrap;
  align-items:center; justify-content:flex-start; gap:14px;
  padding-right:44px;   /* place pour le cœur des favoris, en haut à droite */
}
/* Le prix est centré et pleine largeur dans la grille : sur une ligne, il
   doit se coller au texte qu'il accompagne. */
.grid.liste .pcard .foot .price{width:auto; margin:0; text-align:left; flex:0 0 auto}
.grid.liste .pcard .foot .add{margin-left:auto; width:auto; min-width:64px; flex:0 0 auto}
@media(min-width:760px){
  .grid.liste .pcard{grid-template-columns:120px 1fr}
  .grid.liste .pcard .thumb{width:120px; height:120px}
}

/* ── Mosaïque : tailles alternées, rythme irrégulier ──
   Une carte sur cinq occupe deux colonnes. `grid-auto-flow:dense` comble les
   trous laissés par ces cartes larges — sans lui, la mosaïque se troue. */
.grid.mosaique{grid-auto-flow:dense}
.grid.mosaique .pcard:nth-child(5n+1){grid-column:span 2}
.grid.mosaique .pcard:nth-child(5n+1) .thumb{aspect-ratio:16/10}
@media(min-width:960px){
  .grid.mosaique .pcard:nth-child(7n+4){grid-column:span 2}
}

/* ── Vedette : le PREMIER article s'affiche en grand (vignette panoramique
   sur toute la largeur), les suivants en grille normale. ── */
.grid.vedette{grid-auto-flow:dense}
.grid.vedette .pcard:first-child{grid-column:1 / -1;aspect-ratio:auto}
.grid.vedette .pcard:first-child .thumb{aspect-ratio:16/9;flex:none}
@media(min-width:640px){
  .grid.vedette .pcard:first-child{grid-column:span 2}
  .grid.vedette .pcard:first-child .thumb{aspect-ratio:21/9}
}

/* ── Cascade : colonnes façon Pinterest, hauteurs alternées — les articles
   s'empilent sans s'aligner, pour un rythme vivant (le look « Sukin »).
   CSS multi-colonnes : le flux remplit une colonne puis la suivante. ── */
.grid.cascade{display:block;column-count:2;column-gap:13px}
@media(min-width:640px){.grid.cascade{column-count:3;column-gap:16px}}
@media(min-width:960px){.grid.cascade{column-count:4}}
.grid.cascade .pcard{break-inside:avoid;width:100%;margin:0 0 13px;aspect-ratio:auto}
.grid.cascade .pcard .thumb{aspect-ratio:1/1}
.grid.cascade .pcard:nth-child(3n) .thumb{aspect-ratio:3/4}
.grid.cascade .pcard:nth-child(4n+1) .thumb{aspect-ratio:4/5}

/* ── Grille fine : 3 colonnes serrées (mobile) → 4/5 sur grand écran, pour un
   catalogue fourni. Cartes en hauteur libre + contenu compacté pour tenir sans
   déborder à cette largeur réduite (le piège de la 1re version). ── */
.grid.fine{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
@media(min-width:640px){.grid.fine{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}}
@media(min-width:960px){.grid.fine{grid-template-columns:repeat(5,minmax(0,1fr))}}
.grid.fine .pcard{aspect-ratio:auto;padding:8px}
.grid.fine .pcard .name{font-size:12.5px;line-height:1.2;margin-top:7px}
.grid.fine .pcard .cat{font-size:10.5px}
.grid.fine .pcard .price{font-size:13px}
.grid.fine .pcard .old{display:none}          /* pas la place pour l'ancien prix */
.grid.fine .pcard .foot{padding-top:6px}
.grid.fine .pcard .add{width:30px;height:30px}

/* ── Magazine : rythme éditorial — un article sur trois s'affiche en grand
   (pleine largeur, vignette panoramique), les deux suivants côte à côte. ── */
.grid.magazine{grid-auto-flow:dense}
.grid.magazine .pcard:nth-child(3n+1){grid-column:1 / -1;aspect-ratio:auto}
.grid.magazine .pcard:nth-child(3n+1) .thumb{aspect-ratio:16/9;flex:none}
@media(min-width:640px){
  .grid.magazine .pcard:nth-child(3n+1){grid-column:span 2}
  .grid.magazine .pcard:nth-child(3n+1) .thumb{aspect-ratio:21/9}
}

/* ── Duo : deux grandes cartes par ligne à vignette panoramique — présentation
   immersive, met les visuels en valeur (mode, déco, produits soignés). ── */
.grid.duo{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.grid.duo .pcard{aspect-ratio:auto}
.grid.duo .pcard .thumb{aspect-ratio:4/3}
@media(min-width:900px){.grid.duo{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* ── Mise en avant en carrousel : une seule ligne qui défile ──
   Défilement natif avec points d'accroche : pas de bibliothèque, pas de
   boutons à câbler, et le geste tactile fonctionne déjà partout. */
.grid.carrousel{
  display:flex; overflow-x:auto; scroll-snap-type:x mandatory;
  /* Plus de marge basse : elle séparait la dernière carte du bandeau du
     rayon suivant. L'ombre des cartes déborde d'elle-même, sans réserve. */
  gap:13px; padding-bottom:0; -webkit-overflow-scrolling:touch;
  scrollbar-width:thin;
}
.grid.carrousel .pcard{
  flex:0 0 72%; max-width:260px; scroll-snap-align:start;
}
@media(min-width:640px){ .grid.carrousel .pcard{flex:0 0 240px} }

/* ── Bandeau d'annonce ── */
.annonce{
  margin:0 16px 14px; padding:11px 16px; border-radius:12px;
  background:var(--acc-l); border:1px solid var(--acc);
  color:var(--acc-d); font-size:13.5px; font-weight:600; text-align:center;
  max-width:1120px; margin-inline:auto;
}

/* =========================================================
   PAS DE DÉPLACEMENT LATÉRAL
   `overflow-x:hidden` posé sur `body` seul ne suffit pas : si c'est `html`
   qui défile, la page se déplace quand même du doigt. On coupe donc aux DEUX
   niveaux.
   `clip` plutôt que `hidden` : `hidden` fait de l'élément une boîte de
   défilement, ce qui casserait l'en-tête collant (position:sticky). `clip`
   rogne sans rien rendre défilable — l'en-tête continue de suivre.
   Les défilements horizontaux VOLONTAIRES (rayons, choix de styles,
   carrousel) sont dans des conteneurs internes : ils ne sont pas touchés.
   Le zoom à deux doigts reste possible : le désactiver rendrait le site
   inutilisable pour qui a besoin d'agrandir.
   ========================================================= */
html{overflow-x:clip}
body{overflow-x:clip; max-width:100%}


/* ════════════════════════════════════════════════════════════════════
   PERSONNALISATION PAR ÉLÉMENT — nom / accroche / bannière
   Variables posées par applyTheme (js/ui.js) depuis les réglages du gérant.
   '' / null = variable absente → le fallback (police/couleur du thème) reste.
   Bloc en fin de fichier : passe APRÈS les 11 variantes [data-hero] pour que
   le choix du gérant l'emporte (sauf « ecrin », volontairement sombre).
   POUR L'ACCROCHE, CE N'EST PLUS ICI QUE ÇA SE JOUE. Tant que boutique.html
   écrit `class="hero tete plein"` en dur, `html .hero.plein .hero-card
   #heroTag` (section « BANNIÈRE PLEIN ÉCRAN », plus bas) est plus spécifique
   et postérieure : elle gagne dans tous les cas, ici comme sous
   `html[data-herotexte]`. Le comportement utile est conservé — la couleur
   choisie par le gérant (`--tag-color`) est reprise à l'identique là-bas et
   continue de l'emporter — mais changer la ligne ci-dessous ne se verra
   nulle part. Ne la retirer qu'après avoir vérifié qu'aucun balisage ne
   réutilise #heroTag hors bannière pleine. */
.brand{font-family:var(--nom-police,var(--serif))}
.brand [data-shopname]{color:var(--nom-color,inherit)}
#heroTag{color:var(--tag-color,var(--ink-2))}
.hero-card h1{font-family:var(--hero-police,inherit);color:var(--hero-color,inherit)}
/* Image de fond de la bannière : !important pour battre le `background` des
   variantes [data-hero]. Voile sombre + texte clair par défaut = lisibilité. */
/* Image montrée TELLE QUELLE (aucun filtre). Sans texte par-dessus, la carte
   prend le format naturel de l'image (--hero-ar posé par js/shop.js) : l'image
   entière s'affiche, ni assombrie ni rognée. */
html[data-heroimg] .hero-card{
  background-image:var(--hero-image)!important;
  /* `contain` sur fond sombre, jamais `cover` : l'image du gérant s'affiche
     entière. Si le plafond de hauteur borne la carte, des marges sombres
     apparaissent au lieu d'un recadrage sauvage dans le visuel. */
  background-size:contain!important;background-position:center!important;background-repeat:no-repeat!important;
  background-color:#14100c;
  /* Hauteur CALCULÉE (largeur utile × ratio numérique --hero-hw, plafonnée) :
     surtout pas `aspect-ratio` + `max-height` — quand le plafond mordait,
     le navigateur reportait la contrainte sur la LARGEUR et la bannière
     rétrécissait au milieu de la page sur PC. La largeur, elle, ne bouge
     jamais. 1088px = 1120 (max de .hero) moins ses gouttières de 16px. */
  width:100%;
  height:min(calc(min(100vw - 32px,1088px) * var(--hero-hw,.56)),52vh)}
html[data-heroimg]:not([data-herotexte]) .hero-card{padding:0}
html[data-heroimg] .hero-deco{display:none}
/* Texte par-dessus l'image : léger voile bas + ombre pour la lisibilité, hauteur
   mini. Le voile n'apparaît QUE s'il y a du texte (jamais sur une image nue). */
html[data-herotexte] .hero-card{
  background-image:linear-gradient(rgba(20,12,8,.05),rgba(20,12,8,.42)),var(--hero-image)!important;
  min-height:clamp(150px,42vw,260px)}
html[data-herotexte] .hero-card h1{color:var(--hero-color,#fff);text-shadow:0 1px 5px rgba(0,0,0,.55)}
html[data-herotexte] #heroTag{color:var(--tag-color,#fff);text-shadow:0 1px 4px rgba(0,0,0,.6)}
html[data-herotexte] .hero-tag{background:rgba(255,255,255,.9);color:#2b1a12;text-shadow:none}
/* Sur mobile, la bannière IMAGE file bord à bord : aucune marge claire
   autour d'un visuel plein cadre sur un écran déjà étroit. Les coins ronds
   partent avec les marges — un rectangle net, façon affiche (même geste
   que [data-hero="table"] plus haut). */
@media(max-width:640px){
  html[data-heroimg] .hero{padding-left:0;padding-right:0}
  /* Plus de gouttières → la hauteur se recale sur la pleine largeur, et le
     plancher de 260px saute : au format de l'image, ni bande ni rognage. */
  html[data-heroimg] .hero-card{border-radius:0;min-height:0;
    height:min(calc(100vw * var(--hero-hw,.56)),52vh)}
}

/* Informations légales repliables : titre cliquable, contenu déplié au clic
   seulement (le CGV complet n'inonde plus le pied de page de la boutique). */
.legal-det>summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:10px}
.legal-det>summary::-webkit-details-marker{display:none}
.legal-det>summary>span{font-family:var(--serif);font-weight:700;font-size:1.05rem;color:var(--ink)}
.legal-det>summary::after{content:"⌄";font-size:1.15rem;line-height:1;color:var(--ink-3,#77614c);transition:transform .2s}
.legal-det[open]>summary::after{transform:rotate(180deg)}
.legal-det .legal-body{padding-top:2px}

/* ---- Nuancier photo des options produit (variantes couleur importées) ---- */
.opt-photos{display:flex;flex-wrap:wrap;gap:9px}
.opt-photos .opt-photo{width:76px;padding:4px 4px 6px;border:2px solid var(--line-2,#eee);border-radius:12px;
  background:#fff;cursor:pointer;display:flex;flex-direction:column;gap:4px;align-items:center;transition:border-color .12s}
.opt-photos .opt-photo img{width:100%;aspect-ratio:3/4;object-fit:cover;border-radius:8px}
.opt-photos .opt-photo-vide{width:100%;aspect-ratio:3/4;display:grid;place-items:center;font-size:24px;background:var(--cream-2,#f5f0ea);border-radius:8px}
.opt-photos .opt-photo small{font-size:10.5px;line-height:1.2;color:var(--ink-2,#555);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* La sélection se marque à la BORDURE, jamais au fond : la règle générale
   `.opt button.on` (fond sombre) rendait le libellé illisible sous la photo. */
.opt-photos .opt-photo.on{background:#fff;border-color:var(--acc,#c2528b);box-shadow:0 0 0 3px color-mix(in srgb,var(--acc,#c2528b) 18%,transparent)}
.opt-photos .opt-photo.on small{color:var(--ink,#222);font-weight:700}

/* ---- Galerie de la fiche produit (import CJ : plusieurs photos) ----
   Rangée de vignettes carrées sous la photo — la vue affichée est marquée
   d'une bordure accent, comme sur les fiches des grands catalogues. */
/* Les flèches de la galerie photo, posées sur les côtés du visuel. Assez
   contrastées pour se voir sur une photo claire comme sur une sombre, et
   assez discrètes pour ne pas disputer la vedette à l'article. */
.pgal-fleche{position:absolute;top:50%;z-index:8;transform:translateY(-50%);
  width:38px;height:38px;border:0;border-radius:50%;cursor:pointer;
  background:rgba(20,16,12,.42);color:#fff;font-size:21px;line-height:1;
  display:grid;place-items:center;backdrop-filter:blur(3px);
  transition:background .18s,transform .12s}
.pgal-fleche:hover{background:rgba(20,16,12,.62)}
.pgal-fleche:active{transform:translateY(-50%) scale(.9)}
.pgal-fleche.g{left:10px}
.pgal-fleche.d{right:10px}
@media print{.pgal-fleche{display:none}}

.pgal{display:flex;gap:10px;padding:12px 18px 2px;margin-bottom:36px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}

/* SUR ORDINATEUR, LES VUES SE RANGENT EN COLONNE À GAUCHE DU VISUEL.
   Alignées en ligne, elles débordaient hors du cadre dès la cinquième et
   il fallait les faire défiler pour voir qu'il y en avait d'autres — sur
   un écran qui a de la place à revendre.

   La colonne est posée EN ABSOLU par-dessus la scène plutôt que dans le
   flux : la scène occupe déjà toute la largeur, et lui prendre une bande
   à gauche aurait rétréci la photo de l'article, qu'on vient justement
   regarder.

   Le téléphone garde la rangée sous l'image : en colonne, elle y
   mangerait un cinquième de la largeur pour des vignettes qu'on peut
   déjà atteindre d'un balayage. */
@media(min-width:900px){
  /* La colonne de vues prend SA PROPRE COLONNE, à gauche du cadre de
     l'article. Posée en absolu par-dessus la scène, elle mordait sur le
     visuel : on lisait les vignettes SUR la photo, et le bord gauche de
     l'article disparaissait dessous.

     Une troisième piste de grille les sort du cadre. L'ordre du document
     reste inchangé — les vignettes y suivent la scène, ce qui est juste
     pour un lecteur d'écran — c'est la grille qui les place à gauche. */
  /* LE NOM ET LE PRIX RESTENT VISIBLES. Ils passaient sous le menu dès
     cent cinquante pixels de défilement — or ce sont les deux seules
     informations qu'un client garde sous les yeux en parcourant une fiche :
     ce qu'il regarde, et combien ça coûte. Le visuel est déjà collant à
     80 px ; son pendant textuel l'est maintenant aussi, juste sous le
     menu.

     Un fond opaque est indispensable : sans lui, le reste de la
     description défilerait en transparence derrière le titre. */
  .ptete{position:sticky;top:58px;z-index:7;
    background:var(--cream);padding-top:10px;padding-bottom:8px;
    margin-left:-4px;margin-right:-4px;padding-left:4px;padding-right:4px}

  .pwrap{grid-template-columns:auto minmax(0,1.05fr) minmax(0,.95fr);gap:18px}
  .pgal{grid-column:1;grid-row:1;position:static;align-self:start;
    flex-direction:column;width:78px;max-height:62vh;margin-top:14px;
    padding:0;overflow-y:auto;overflow-x:visible}
  .stage{grid-column:2;grid-row:1}
  .pdetail{grid-column:3;grid-row:1}
  .pgal .pgal-th{width:70px;height:70px}
}
.pgal::-webkit-scrollbar{display:none}
.pgal .pgal-th{flex:0 0 auto;width:64px;height:64px;padding:0;border:2px solid var(--line-2,#eee);border-radius:10px;
  background:#fff;cursor:pointer;overflow:hidden;transition:border-color .12s}
.pgal .pgal-th img{width:100%;height:100%;object-fit:cover;display:block}
.pgal .pgal-th.on{border-color:var(--acc,#c2528b);box-shadow:0 0 0 3px color-mix(in srgb,var(--acc,#c2528b) 18%,transparent)}
/* Le geste horizontal sur la photo appartient à la galerie (pan-y : le
   défilement vertical de la page reste natif) ; on neutralise aussi le
   « drag » d'image du bureau qui avalerait le pointerup. */
.stage .scene img{-webkit-user-drag:none;user-select:none}


/* ═══ CATALOGUE SUR FOND FIXE ═══════════════════════════════════════════
   Le décor de la boutique reste immobile pendant que les cartes montent
   devant lui. Aucune acrobatie : le décor est un calque `fixed` derrière
   tout, et ce sont les cartes qui défilent normalement — c'est ce qui
   rend l'effet fluide y compris sur téléphone, là où un `background-
   attachment:fixed` saccade et saute avec la barre d'adresse d'iOS. */
html.a-fond .cat-decor{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:linear-gradient(170deg,var(--cream) 0%,var(--acc-l) 58%,var(--cream-2) 100%);
  background-size:cover;background-position:center}
/* Un voile clair sépare le décor des cartes : sans lui, un fond
   photographique rendrait les prix illisibles. */
html.a-fond .cat-decor::after{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,color-mix(in srgb,var(--cream) 62%,transparent),
    color-mix(in srgb,var(--cream) 82%,transparent))}
/* Le fond du <body> masquait le décor : en mode fixe, c'est le décor qui
   fait office de fond, le corps devient transparent. */
html.a-fond body{background:transparent}
/* Le décor passe DERRIÈRE le contenu par son seul z-index négatif — le
   corps de page est transparent en mode fixe, rien ne le masque. On a
   longtemps forcé `position:relative` sur tous les enfants du <body> à la
   place : ça repoussait le décor au fond, mais ça écrasait aussi le
   `position` de tout le reste — le header perdait son adhérence (sticky →
   relative) et le lien « Aller au contenu », censé rester hors champ,
   rentrait dans le flux et décalait la page de 23 px. */
html.a-fond .cat-decor{z-index:-1}
html.cat-fixe .grid.defile{grid-template-columns:repeat(var(--defile-cols,2),minmax(0,1fr));gap:20px}
/* Une seule carte par rangée : format « magazine » — largeur bornée et
   posée au centre, avec une respiration verticale plus généreuse.
   Sélecteur par CLASSE et non par attribut style : le navigateur écrit
   « --defile-cols: 1 » avec une espace, qu'un [style*="…:1"] rate. */
html.cat-fixe .grid.defile.cols1{max-width:640px;margin-inline:auto;gap:34px}

/* PLUS L'ÉCRAN EST LARGE, PLUS IL Y A DE COLONNES. Le réglage « 1 à 4 par
   rangée » a été pensé pour le TÉLÉPHONE : il y dit la TAILLE des cartes.
   Appliqué tel quel sur un ordinateur trois fois plus large, il donnait
   des cartes de la taille d'une affiche — une robe occupait la moitié de
   l'écran. On ajoute donc des colonnes à mesure que la place vient : la
   carte garde la taille voulue, on en voit simplement plus.

   « Une seule par rangée » ne bouge pas : c'est un format magazine
   délibéré, déjà borné à 640 px et centré. */
@media(min-width:700px){
  html.cat-fixe .grid.defile.cols2{grid-template-columns:repeat(3,minmax(0,1fr))}
  html.cat-fixe .grid.defile.cols3{grid-template-columns:repeat(4,minmax(0,1fr))}
  html.cat-fixe .grid.defile.cols4{grid-template-columns:repeat(5,minmax(0,1fr))}
}
@media(min-width:1100px){
  html.cat-fixe .grid.defile.cols2{grid-template-columns:repeat(4,minmax(0,1fr))}
  html.cat-fixe .grid.defile.cols3{grid-template-columns:repeat(5,minmax(0,1fr))}
  html.cat-fixe .grid.defile.cols4{grid-template-columns:repeat(6,minmax(0,1fr))}
}
/* La révélation : opacité et position sont écrites image par image par
   js/shop.js d'après la place de la carte à l'écran. Pas de `transition`
   ici — elle lutterait contre le défilement et ajouterait un retard
   caoutchouteux. L'état de départ évite juste que les cartes clignotent
   avant la première peinture. */
/* Pas de `will-change` ici : voir peindreRevelation() dans js/shop.js. La
   couche GPU qu'il réservait à chaque carte laissait, sur Safari, un
   rectangle blanc derrière les coins arrondis et à l'ancienne position. */
.grid .pcard.arevele{opacity:0}
@media(prefers-reduced-motion:reduce){
  .grid .pcard.arevele{opacity:1;transform:none}
}
/* « Voir la suite » : discret, centré, dans le langage des boutons du site */
.defile-suite{display:flex;flex-direction:column;align-items:center;gap:3px;margin:30px auto 8px;
  padding:14px 30px;border-radius:99px;border:1px solid var(--line);background:var(--card);
  cursor:pointer;box-shadow:var(--sh-s);transition:transform .16s,box-shadow .2s}
.defile-suite b{font-size:14.5px;font-weight:700;color:var(--ink)}
.defile-suite span{font-size:11.5px;color:var(--ink-3)}
.defile-suite:hover{transform:translateY(-2px);box-shadow:var(--sh-m)}
.defile-suite:active{transform:scale(.98)}

/* ═══ Recherche dans l'en-tête ═══════════════════════════════════════════
   Elle a pris la place du nom de la boutique : sur un téléphone, chercher
   est le geste le plus utile d'une boutique, et le nom reste présent
   partout ailleurs (onglet, bannière, bloc « La maison »).
   Elle occupe toute la largeur disponible, les deux icônes gardant la
   leur — d'où le `min-width:0`, sans lequel un champ de formulaire refuse
   de se réduire et pousse le panier hors de l'écran. */
.searchbar.entete{flex:1;min-width:0;width:auto;max-width:none;margin:0;
  padding:9px 13px;border-radius:14px}
.searchbar.entete input{font-size:15px;min-width:0}
/* Le champ natif « search » ajoute sa propre croix sur iOS : on garde la
   nôtre, qui efface AUSSI le filtre, pas seulement le texte. */
.searchbar.entete input::-webkit-search-decoration,
.searchbar.entete input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
@media (max-width:400px){
  .searchbar.entete{padding:8px 11px;border-radius:12px}
  .searchbar.entete input{font-size:14px}
}

/* Carrousel piloté par le défilement de la page : les points d'accroche
   sont suspendus (ils feraient sauter la bande de carte en carte) et la
   barre de défilement masquée — le mouvement vient de la page, pas d'un
   geste sur la bande. Tout revient dès que le visiteur y pose le doigt. */
.grid.carrousel.pilote{scroll-snap-type:none;scrollbar-width:none}
.grid.carrousel.pilote::-webkit-scrollbar{display:none}

/* ═══ BANNIÈRE PLEIN ÉCRAN ══════════════════════════════════════════════
   La bannière ouvre la boutique sur toute la hauteur de l'écran, et les
   visuels du métier s'y relaient en fondu. `svh` et pas `vh` : sur
   téléphone, `vh` compte la barre d'adresse qui n'est pas encore
   rétractée — la bannière dépassait de l'écran au premier coup d'œil. */
.hero.plein{padding:0;max-width:none}
html .hero.plein .hero-card{border-radius:0!important;padding:26px 20px;
  height:100svh!important;min-height:100svh!important;max-height:none!important;
  display:flex;flex-direction:column;justify-content:flex-end;align-items:flex-start}
/* L'APLAT SOMBRE N'EST POSÉ QUE SI UNE PHOTO VA LE COUVRIR.
   Il était inconditionnel : plus spécifique (0,3,1) que la règle qui peint
   l'image du gérant (0,2,1), il gagnait des deux côtés — l'image n'était
   plus jamais peinte comme fond, et le dégradé du thème était remplacé par
   un noir fixe sur les deux tiers de l'écran. C'est là que le commerçant
   cherche sa couleur de site, et c'est là qu'il ne la voyait pas.
   `hero-visuel` est posée par js/shop.js quand il y a vraiment une photo. */
html .hero.plein.hero-visuel .hero-card{background-image:none!important;background-color:#14100c}
/* Le texte repasse devant les diapositives. */
html .hero.plein .hero-card>:not(.hero-diapos){position:relative;z-index:1}
html .hero.plein .hero-card h1{max-width:min(100%,17ch);font-size:clamp(30px,7.2vw,58px);
  color:var(--hero-color,#fff);text-shadow:0 2px 14px rgba(0,0,0,.5)}
/* L'ACCROCHE EST NOMMÉE PAR SON IDENTIFIANT, EXPRÈS. La règle de
   personnalisation `#heroTag{color:var(--tag-color,var(--ink-2))}` (plus
   haut dans ce fichier) porte un identifiant : elle l'emportait sur ce
   sélecteur de classes quel qu'en soit le nombre. Le titre passait bien au
   blanc et l'accroche restait brun foncé, ombrée de noir, sur un fond
   sombre : illisible, et vu par les clients autant que par le commerçant.
   Ajouter le `#heroTag` ici suffit à faire pencher la cascade du bon côté,
   sans `!important`.
   SEUL LE REPLI CHANGE : `var(--tag-color)` reste en tête, la couleur
   d'accroche choisie par le commerçant continue donc de gagner.
   CETTE RÈGLE VAUT POUR TOUTES LES BOUTIQUES, avec photo ou sans : la classe
   `.plein` est écrite en dur dans boutique.html et rien ne la retire. Le
   repli blanc n'est donc pas réservé au cas « photo », et c'est assumé — le
   titre, lui, est déjà blanc dans exactement la même situation (règle
   ci-dessus). Ce qui rend les deux lisibles sans photo, c'est le voile bas
   des diapositives, dont le dernier arrêt a été assombri pour ça (voir
   `.hero.plein .hero-diapos::after`, plus bas). */
html .hero.plein .hero-card p,
html .hero.plein .hero-card #heroTag{max-width:min(100%,42ch);color:var(--tag-color,rgba(255,255,255,.9));
  text-shadow:0 1px 8px rgba(0,0,0,.55);margin-bottom:34px}
/* La mention retrouve sa gouttière EN MÊME TEMPS que sa pastille blanche :
   `.hero-tag{padding:6px 12px}` (début de fichier, 0-1-0) est battu par les
   dix variantes [data-hero] qui posent `padding:0`, et cette règle-ci ne
   rendait que le fond. Sans photo et hors modèle « Classique », la mention
   s'affichait donc en pavé blanc collé au texte, sans la moindre respiration,
   avec le coin arrondi de 99 px par-dessus. */
html .hero.plein .hero-tag{background:rgba(255,255,255,.9);color:#2b1a12;text-shadow:none;padding:6px 12px}
html .hero.plein .hero-deco{display:none}

/* Les diapositives : empilées, une seule visible, fondu long. Elles
   remplissent le cadre (`cover`) — en plein écran, une image « entière »
   laisserait deux bandes noires sur les côtés. */
.hero-diapos{position:absolute;inset:0;z-index:0;overflow:hidden}
.hero-diapo{position:absolute;inset:0;background-size:cover;background-position:center;
  opacity:0;transition:opacity 1.5s ease;will-change:opacity}
.hero-diapo.on{opacity:1}
/* Voile bas : sans lui, un titre blanc sur un visuel clair devient illisible.
   Il ne couvre que le tiers inférieur, là où le texte est posé.
   DERNIER ARRÊT À .72 ET NON .62, POUR LA BOUTIQUE SANS PHOTO — c'est-à-dire
   la majorité : quinze métiers sur dix-neuf n'ont ni image du gérant ni
   visuel livré (voir js/shop.js), la carte garde alors son dégradé crème et
   l'aplat sombre de `.hero-visuel` ne s'applique pas. Le voile restait le
   seul assombrissement, et à .62 l'accroche blanche tombait à 4,3:1 sur ce
   crème composité : sous le seuil AA de 4,5 pour un texte de 14 px. À .72
   elle passe à 5,5:1, et le titre — blanc dans la même situation, mais assez
   grand pour n'exiger que 3:1 — reste largement au-dessus. Avec photo, le
   bas est simplement un peu plus profond. */
.hero.plein .hero-diapos::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(rgba(20,12,8,.06) 46%,rgba(20,12,8,.72) 100%)}

/* Le chevron d'invitation, en bas, qui respire. */
.hero-suite{position:absolute;left:50%;bottom:16px;z-index:2;width:15px;height:15px;
  margin-left:-7px;border-right:2px solid rgba(255,255,255,.85);
  border-bottom:2px solid rgba(255,255,255,.85);transform:rotate(45deg);
  animation:heroSuite 2.1s ease-in-out infinite;pointer-events:none}
@keyframes heroSuite{0%,100%{transform:rotate(45deg) translate(0,0);opacity:.45}
  50%{transform:rotate(45deg) translate(4px,4px);opacity:1}}
.hero:not(.plein) .hero-suite{display:none}
@media(prefers-reduced-motion:reduce){
  .hero-suite{animation:none}
  .hero-diapo{transition:none}
}
/* SUR ORDINATEUR, LA BANNIÈRE REND LE BAS DE L'ÉCRAN. En plein écran sur
   950 px de haut, le visiteur découvrait une photographie et rien d'autre
   — ni menu, ni le moindre article — et devait défiler presque tout un
   écran avant de trouver la navigation. La bannière s'arrête donc aux
   deux tiers : le menu et le haut des premières cartes tiennent dessous,
   et il se colle en haut dès le premier défilement.

   Le téléphone garde le plein écran : l'écran y est étroit et haut, la
   bannière y fait une vraie devanture, et le pouce défile sans effort. */
@media(min-width:900px){
  html .hero.plein .hero-card{height:68svh!important;min-height:68svh!important}
}
/* Entre les deux (tablette, portable posé à plat) : un compromis. */
@media(min-width:760px) and (max-width:899px){
  html .hero.plein .hero-card{height:84svh!important;min-height:84svh!important}
}

/* ═══ LE MENU DANS L'EN-TÊTE ════════════════════════════════════════════
   Sur la boutique, la navigation ne flotte plus en bas de l'écran : elle
   occupe l'en-tête, qui se colle en haut au défilement. La bannière
   d'accueil reste donc SEULE à l'arrivée — le menu est sous elle, pas
   par-dessus.

   `position:static` est indispensable : la barre est `fixed` par défaut
   pour flotter au-dessus de la page, et elle serait restée collée au bas
   de l'écran en dépit de sa nouvelle place dans le document. */
/* L'EN-TÊTE EST BLANC, sur toutes les boutiques. C'était une bande noire,
   qui posait des icônes claires sur un fond franc quoi qu'il défile
   dessous. Le thème de la boutique (DESIGN.md) demande l'inverse : fond
   blanc, filet fin, encre sombre — « bordures fines, beaucoup d'espace
   blanc ».

   Le filet du bas remplace le contraste que donnait le noir : sans lui,
   l'en-tête se confondrait avec une page claire. */
#menuHaut{width:100%;background:var(--sz-header-bg);
  border-bottom:1px solid var(--sz-header-line)}

/* ═══ LA BARRE DE MENU ══════════════════════════════════════════════════
   Trois zones sur une bande noire : deux commandes à gauche (le sommaire
   et la recherche), l'enseigne au centre, trois destinations à droite.
   Des icônes blanches, sans libellé — c'est la grammaire des grandes
   maisons, et elle tient sur un téléphone sans rien sacrifier.

   La grille est en `1fr auto 1fr` : le nom reste EXACTEMENT au centre de
   l'écran quel que soit le nombre d'icônes de part et d'autre. Avec un
   simple `space-between`, il aurait glissé vers la gauche dès qu'un côté
   compte une icône de plus. */
.tabbar.en-tete{position:static;z-index:auto;width:100%;padding:0;margin:0;
  background:none;backdrop-filter:none;border:0;box-shadow:none;transform:none;border-radius:0}
/* LES ICÔNES S'ALIGNENT SUR LES CARTES. La bande noire, elle, reste bord
   à bord : c'est le fond, il n'a pas à se borner. Mais son CONTENU suit la
   même grille que le catalogue — 1120 px centrés, 16 px de gouttière —
   sinon les trois traits collaient au bord de l'écran pendant que le
   premier article commençait bien plus loin, et rien ne s'alignait
   verticalement. */
/* `auto minmax(0,1fr) auto` et non plus `1fr auto 1fr` : deux colonnes
   égales encadraient l'enseigne et la maintenaient au CENTRE quoi qu'on
   fasse — `justify-self` n'y pouvait rien, la colonne elle-même étant
   centrée. Désormais la colonne du milieu prend toute la place restante et
   l'enseigne s'y cale à gauche, juste après le sommaire et la loupe.
   `minmax(0,…)` est indispensable : sans lui une enseigne longue refuse de
   rétrécir et pousse le panier hors de l'écran — c'est le cas mesuré à
   390 px avec « Au Bouquet Joli ». Avec, elle se coupe proprement grâce à
   l'ellipse posée plus bas. */
.tabbar.en-tete .tabbar-in{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;
  max-width:1120px;width:100%;margin-inline:auto;gap:8px;padding:4px 16px}
.mn-cote{display:flex;align-items:center;gap:6px}
/* `grid-row:1` n'est pas décoratif. Dans le balisage, le bloc burger+loupe
   vient AVANT le logo ; en lui donnant la colonne 2 sans fixer la rangée, la
   grille place le logo — qui réclame la colonne 1, déjà dépassée — sur la
   RANGÉE SUIVANTE. D'où une barre sur deux étages, burger en haut, logo et
   icônes en dessous. Fixer la rangée remet tout le monde sur la même ligne. */
.tabbar.en-tete .mn-cote:not(.mn-fin){grid-column:2;grid-row:1;justify-self:start}
.tabbar.en-tete .mn-fin{grid-column:3;grid-row:1}
.mn-fin{justify-content:flex-end}
.mn-i{--rx:0;--ry:0;
  position:relative;display:grid;place-items:center;width:38px;height:38px;
  border:0;background:none;padding:0;cursor:pointer;color:var(--sz-header-ink);border-radius:12px;
  transform:perspective(460px) rotateX(calc(var(--rx)*1deg)) rotateY(calc(var(--ry)*1deg));
  transition:transform .16s ease-out,opacity .2s,background .2s}
.mn-i svg{width:23px;height:23px;stroke-width:1.7}
.mn-i:hover{background:var(--sz-header-survol)}
.mn-i:active{transform:perspective(460px) scale(.92)}
/* La page où l'on se trouve : un point sous l'icône. Un aplat de couleur
   sur fond noir serait bien plus lourd que ce simple repère. */
.mn-i.actif::after{content:'';position:absolute;left:50%;bottom:5px;width:4px;height:4px;
  margin-left:-2px;border-radius:50%;background:var(--sz-header-ink)}
.mn-i .badge{position:absolute;top:3px;right:3px;min-width:17px;height:17px;padding:0 4px;
  border-radius:99px;background:var(--acc);color:var(--sur-acc,#fff);font-size:10.5px;font-weight:700;
  display:grid;place-items:center;border:1.5px solid var(--sz-header-bg)}
/* L'enseigne, au centre. Elle porte la police choisie par le commerçant —
   c'est son nom, pas une étiquette de gabarit. */
/* À GAUCHE, et non plus au centre — demande du 2026-09-01, et c'est aussi
   ce que dit le thème du projet : « logo à gauche, navigation au centre,
   icônes à droite ». `justify-self:start` suffit : l'enseigne reste dans sa
   colonne, elle se cale simplement contre son bord gauche, juste après le
   sommaire et la loupe. La grille n'est pas touchée. */
/* L'ENSEIGNE EN PREMIER, même sur écran étroit — demande du 2026-09-01.
   Elle était en colonne 2, donc APRÈS le sommaire et la loupe : le logo
   commençait à 96 px du bord. Elle passe en colonne 1 ; les deux commandes
   de gauche prennent la colonne 2 et se calent contre elle. L'ordre du
   document, lui, ne bouge pas : le sommaire reste la première chose
   atteinte au clavier, ce qui est juste — c'est une commande, pas une
   décoration.
   (Sur grand écran, les règles `html[data-entete-large]` plus bas prennent
   le relais : elles placent déjà l'enseigne en 1 et masquent le sommaire.) */
.mn-nom{grid-column:1;grid-row:1;justify-self:start;color:var(--sz-header-ink);text-decoration:none;
  font-family:var(--nom-police,var(--serif));font-size:16px;font-weight:600;
  letter-spacing:.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  max-width:100%;padding:0 4px}
/* Le logo prend la hauteur de la barre, jamais plus : une image haute
   ferait grandir l'en-tête de toute la boutique. `object-fit:contain` pour
   qu'un logo carré comme un logo panoramique tiennent sans se déformer. */
.mn-logo{display:block;height:30px;width:auto;max-width:min(46vw,220px);
  object-fit:contain;object-position:left center}
@media(max-width:430px){.mn-logo{height:26px;max-width:40vw}}
/* Écran étroit : cinq icônes et un nom ne tiennent pas de front. Les
   icônes se resserrent et le nom rapetisse — mesuré sur 390 px, où le nom
   « Au Bouquet Joli » venait buter contre la loupe et le cœur. Le nom est
   tronqué avec des points de suspension plutôt que de pousser les icônes
   hors de l'écran : mieux vaut une enseigne abrégée qu'un panier
   inaccessible. */
@media(max-width:430px){
  /* Écran étroit : on garde la gouttière du catalogue (16 px), sans quoi
     les icônes et les cartes ne s'aligneraient plus. */
  .tabbar.en-tete .tabbar-in{padding:8px 16px;gap:4px}
  .mn-i{width:38px;height:38px;border-radius:10px}
  .mn-i svg{width:21px;height:21px}
  .mn-cote{gap:0}
  .mn-nom{font-size:14.5px;padding:0 2px}
}
@media(max-width:360px){
  .mn-nom{font-size:13px}
  .mn-i{width:34px;height:34px}
  .mn-i svg{width:19px;height:19px}
}
@media(min-width:760px){
  .tabbar.en-tete .tabbar-in{padding:5px 16px;gap:14px}
  .mn-cote{gap:10px}
  .mn-i{width:40px;height:40px}
  .mn-i svg{width:23px;height:23px}
  .mn-nom{font-size:19px;max-width:min(40vw,460px)}
}
@media(prefers-reduced-motion:reduce){.mn-i{transform:none}}

/* Le sommaire ouvert par les trois traits. */
.mn-liste{display:flex;flex-direction:column;gap:2px}
.mn-ligne{display:flex;align-items:center;gap:13px;padding:14px 12px;border-radius:14px;
  color:var(--ink);font-weight:600;text-decoration:none;position:relative}
.mn-ligne svg{width:22px;height:22px;color:var(--ink-3);flex:none}
.mn-ligne:hover{background:var(--cream-2)}
.mn-ligne.actif{background:var(--acc-l);color:var(--acc-d)}
.mn-ligne.actif svg{color:var(--acc-d)}
.mn-ligne .badge{position:static;margin-left:auto;min-width:21px;height:21px;padding:0 6px;
  border-radius:99px;background:var(--acc);color:var(--sur-acc,#fff);font-size:11.5px;font-weight:700;
  display:grid;place-items:center}
.mn-pt{margin-left:auto;width:9px;height:9px;border-radius:50%;background:var(--ok)}

/* (seconde déclaration, plus bas dans la feuille : c'est elle qui
   l'emportait) */
#menuHaut{width:100%;background:var(--sz-header-bg);
  border-bottom:1px solid var(--sz-header-line)}

/* ═══ LE MENU : DES BOUTONS, PLUS DE BARRE ══════════════════════════════
   La bande translucide disparaît ; il ne reste que cinq pastilles posées
   sur la page. Chacune porte son propre fond, sinon les libellés
   deviendraient illisibles dès qu'une carte sombre passe dessous au
   défilement.

   Sur l'inclinaison au survol (--rx/--ry écrits par js/ui.js d'après la
   position du curseur) : la pastille bascule vers le doigt, comme une
   touche qu'on effleure. `perspective` doit être DANS le transform de
   l'élément lui-même — posée sur le parent, elle aurait donné un point de
   fuite commun aux cinq pastilles, et celles des bords auraient penché de
   travers. */
/* Plus de `:only-child` : l'en-tête de la boutique porte désormais DEUX
   rangées — le menu et les rayons — et la règle ne s'appliquait plus. */
header.appbar:has(>#menuHaut){background:none;backdrop-filter:none;border-bottom:0}
/* MAIS la rangée du TITRE garde son fond. Cinq pages en portent une en
   plus de la bande noire — panier, favoris, compte, carte cadeau, sur
   mesure : « Mon panier » et le bouton « Vider » s'y trouvaient peints
   sur RIEN, et le contenu défilait visiblement à travers. Sur le panier,
   le titre et une ligne d'article se superposaient lettre sur lettre.

   Fond PLEIN et non translucide : c'est un bandeau collé en haut sous
   lequel passe tout le contenu de la page ; 82 % de transparence y
   laissait encore lire ce qui glissait dessous. */
header.appbar:has(>#menuHaut) .appbar-in{
  background:var(--cream);position:relative;z-index:1}

/* LE NOM DE LA BOUTIQUE N'EST PAS ÉCRIT DEUX FOIS. Il figure déjà dans
   la bande noire, juste en dessous. Au-dessus, il était répété — et
   peint avec la couleur de marque, prévue pour le fond noir : blanc sur
   une surface claire, contraste mesuré à 1,07. Illisible, et en double.

   Défaut antérieur à la reprise des couleurs du design : il existait
   déjà quand la rangée n'avait pas de fond du tout. */
header.appbar:has(>#menuHaut) .appbar-in .brand{display:none}

/* Et si la rangée ne portait QUE ce nom — c'est le cas de la page des
   favoris — elle n'a plus de raison d'être : sans cela, il resterait
   une bande claire vide au-dessus du menu. Les pages qui portent un
   vrai titre (« Mon panier », « Carte cadeau », « Sur mesure ») ou un
   bouton la gardent. */
header.appbar:has(>#menuHaut) .appbar-in:not(:has(h1)):not(:has(button)){display:none}
/* Plus de filet entre le titre et le menu : la bande noire fait elle-même
   la séparation, bien mieux qu'un trait. */
header.appbar>#menuHaut{border-top:0}
.tabbar.en-tete{background:none;backdrop-filter:none;border:0}
.tabbar.en-tete .tab{
  --rx:0;--ry:0;
  border-radius:99px;background:var(--card);color:var(--ink-2);
  border:1px solid var(--line);
  box-shadow:0 3px 10px -6px rgba(0,0,0,.4);
  transform:perspective(560px) rotateX(calc(var(--rx)*1deg)) rotateY(calc(var(--ry)*1deg));
  transition:transform .16s ease-out,box-shadow .22s,background .22s,color .22s}
.tabbar.en-tete .tab:hover{box-shadow:0 10px 22px -12px rgba(0,0,0,.55)}
.tabbar.en-tete .tab:active{transform:perspective(560px) scale(.96)}
/* L'onglet courant prend la couleur de la boutique : sur des pastilles
   toutes pareilles, un simple changement de teinte du texte ne suffisait
   plus à dire où l'on se trouve. */
.tabbar.en-tete .tab.active{background:var(--acc);color:var(--sur-acc,#fff);border-color:transparent;
  box-shadow:0 6px 16px -8px var(--acc)}
.tabbar.en-tete .tab.active svg{stroke-width:2}
.tabbar.en-tete .tab .badge{top:-2px;right:8%}
@media(prefers-reduced-motion:reduce){
  .tabbar.en-tete .tab{transform:none;transition:background .2s,color .2s}
}
/* Reste de l'ANCIEN menu à onglets libellés, remplacé par la barre à
   icônes : ses règles visaient `.tab`, qui n'existe plus ici, et l'une
   d'elles imposait encore `max-width:none` au contenu du menu — c'est
   elle qui empêchait les icônes de s'aligner sur le catalogue. Supprimé.
   Le positionnement du menu vit désormais dans un seul bloc, plus haut. */

/* L'onglet « Rechercher » pointe sur #recherche. Sans cette réserve, le
   navigateur pose le champ pile au bord haut de la fenêtre — c'est-à-dire
   DERRIÈRE l'en-tête collant, qui le masque entièrement. */
/* La carte s'enfonce dès l'appui, le temps que sa fiche arrive. Sans ce
   retour immédiat, l'attente — même brève — passerait pour un clic qui
   n'a pas pris. */
.pcard.part{transform:scale(.975);opacity:.72;transition:transform .18s ease,opacity .18s ease}

/* ═══ APERÇU MODIFIABLE (panneau de gestion uniquement) ══════════════════
   Textes retouchables, pilules d'outils, nuancier, bande d'aide : tout vit
   dans css/edition.css, liée après cette feuille par boutique.html et
   produit.html. */

#recherche{scroll-margin-top:96px}

/* LA RECHERCHE EST REPLIÉE AU DÉPART, et s'ouvre sur la loupe du menu.
   `visibility:hidden` en plus de la hauteur nulle : un champ replié mais
   toujours tabulable enverrait le clavier dans un formulaire que
   personne ne voit. Elle redevient atteignable en s'ouvrant. */
.zone-recherche{padding:0 16px;max-height:0;opacity:0;visibility:hidden;overflow:hidden;
  transition:max-height .3s ease,opacity .24s ease,padding-bottom .3s ease,visibility .3s}
.zone-recherche.ouverte{max-height:110px;opacity:1;visibility:visible;padding-bottom:12px}
@media(prefers-reduced-motion:reduce){.zone-recherche{transition:opacity .2s,visibility .2s}}

/* ═══ FOND FIXE CHOISI PAR LE COMMERÇANT ════════════════════════════════
   Le décor du catalogue accepte une photo à la place du dégradé du
   thème. `background-image` et non le raccourci `background` : le
   dégradé de base est écrit en raccourci, et le réécrire ici effacerait
   la couleur de repli pendant que la photo charge. */
html[data-fondimg].a-fond .cat-decor{
  background-image:var(--fond-image);
  background-size:cover;background-position:center;background-repeat:no-repeat;
  background-attachment:scroll}
/* Le voile s'épaissit sur une PHOTO. Celui du dégradé (62 → 82 %) suffit
   à séparer deux aplats de la même palette ; sur une photographie
   contrastée, les prix et les catégories deviendraient illisibles. */
/* Les bulles décoratives partagent le même plan que le décor et, venant
   après lui dans la page, se peignent PAR-DESSUS. Sur un dégradé elles
   ajoutent une nuance ; sur une photographie, ce sont des taches. */
html[data-fondimg] .bg-blobs,html[data-fondanime] .bg-blobs{display:none}

/* La toile du fond animé remplit le décor et se place SOUS le voile —
   le ::after du décor, qui garde les titres lisibles. */
/* La toile déborde du décor par le bas ; c'est lui qui la découpe. */
.cat-toile{position:absolute;top:0;left:0;display:block}
html[data-fondanime] .cat-decor{overflow:hidden}
html[data-fondanime].a-fond .cat-decor{background-image:none}
html[data-fondanime].a-fond .cat-decor::after{
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--cream) var(--voile-haut,14%),transparent),
    color-mix(in srgb,var(--cream) var(--voile-bas,24%),transparent))}
/* LE VOILE SUR UNE PHOTO EST RÉGLABLE, et bien plus discret qu'avant.
   Il était fixé à 76 → 89 % : assez pour protéger les titres, mais il
   effaçait la photo que le commerçant venait de choisir — il n'en restait
   qu'un gris pâle. Il descend à 14 → 24 % par défaut, et chacun l'ajuste
   à son image (Réglages → Fond de la boutique).

   Les cartes du catalogue n'en dépendent pas : elles ont leur propre
   fond. Il ne protège que le texte posé À MÊME le décor — les titres de
   rayon, « Tout voir », le tri. */
html[data-fondimg].a-fond .cat-decor::after{
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--cream) var(--voile-haut,14%),transparent),
    color-mix(in srgb,var(--cream) var(--voile-bas,24%),transparent))}


/* ══════════════════════════════════════════════════════════════════════
   LE FOND DU CATALOGUE EN DÉGRADÉ
   ----------------------------------------------------------------------
   Six dégradés tirés des deux mises en page à parti pris (js/themes.js,
   FONDS_DEGRADES). Le réglage vaut « auto » par défaut : la toile suit
   alors la fiche article choisie, pour que la boutique et l'article ne
   parlent pas deux langues.

   `:not([data-fondimg])` est une ceinture : js/ui.js ne résout déjà aucun
   dégradé quand une photo est posée, mais si cette précaution sautait un
   jour, un dégradé recouvrirait en silence la photo que le commerçant
   vient de choisir. La règle refuse de s'appliquer plutôt que de gagner.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fonddeg]:not([data-fondimg]).a-fond .cat-decor{
  background-image:var(--fond-degrade);
  background-size:cover;background-position:center}
/* Le voile crème du thème (62 → 82 %) n'a plus lieu d'être : il est calibré
   pour séparer deux aplats de la MÊME palette. Posé sur un dégradé choisi,
   il le lave de sa couleur — et sur une nuit ambrée, il l'efface. Les
   titres de rayon n'en dépendent pas : ils ont leur propre bandeau noir. */
html[data-fonddeg]:not([data-fondimg]).a-fond .cat-decor::after{background:none}
/* Les bulles décoratives portent l'accent du thème : sur une menthe ou une
   nuit ambrée, ce sont des taches. Même traitement que sur une photo. */
html[data-fonddeg] .bg-blobs{display:none}

/* ══ ENCRE CLAIRE SUR FOND SOMBRE ═══════════════════════════════════════
   `data-fondsombre` est posé par js/ui.js quand le dégradé choisi est
   marqué `sombre`. Ce n'est pas une coquetterie : sans ces règles, tout
   texte posé À MÊME le décor reste en brun #2B1A12, soit un contraste de
   1,2:1 sur la nuit — invisible.

   Les titres de rayon, la bande des catégories, le menu, les cartes et les
   encadrés ont déjà leur propre fond opaque et n'ont besoin de rien. Ne
   sont listés ici que les éléments réellement nus. */
html[data-fondsombre] .empty{color:rgba(255,255,255,.78)}
html[data-fondsombre] .empty b{color:#fff}
/* Mention sanitaire obligatoire (art. L3323-4 CSP) et bandeau de
   démonstration : posés nus en bas de page, ils doivent rester lisibles —
   pour l'un c'est une obligation légale, pas une question de goût. */
html[data-fondsombre] #alcoolNotice,
html[data-fondsombre] #demoNotice{color:rgba(255,255,255,.72)}
/* « La maison » dans ses deux modèles sans cadre : la carte est alors
   transparente et son texte tombe directement sur le décor. */
html[data-fondsombre][data-lamaison="ligne"] .lm-card,
html[data-fondsombre][data-lamaison="volets"] .lm-card{color:rgba(255,255,255,.86)}
html[data-fondsombre][data-lamaison="ligne"] .lm-card h3,
html[data-fondsombre][data-lamaison="volets"] .lm-card .lm-id{color:#fff}
html[data-fondsombre][data-lamaison="ligne"] .lm-card .muted,
html[data-fondsombre][data-lamaison="volets"] .lm-card .muted{color:rgba(255,255,255,.70)}
html[data-fondsombre][data-lamaison="ligne"] .lm-card{border-color:rgba(255,255,255,.18)}


/* ── LE SYMÉTRIQUE : TOILE CLAIRE SOUS UN DESIGN SOMBRE ────────────────
   Le commerçant peut garder sa toile claire même avec un design de fiche à
   ambiance sombre. La palette du design reste en place — elle est cohérente
   sur ses propres cartes — mais le texte posé À MÊME la toile, lui, hérite
   d'une encre claire qui disparaît sur le clair. Ces règles lui rendent
   l'encre du thème. Elles ne visent QUE les endroits sans carte dessous ;
   posé sur une carte du design, le texte garde ses couleurs. */
html[data-fond-discordant] body.page-produit .empty,
html[data-fond-discordant] body.page-produit #pallerg,
html[data-fond-discordant] body.page-produit #pretract,
html[data-fond-discordant] body.page-produit .stickybar{color:var(--ink-2,#6E5648)}


/* Défaut préexistant, corrigé au passage : la date de fin de « Dernière
   chance » est un .tiny.muted (#6E5648) posé sur le bandeau NOIR du titre
   de rayon — illisible depuis que ce bandeau existe, quel que soit le
   fond. Les règles voisines (app.css:450-453) ne couvraient que `a` et
   `select`, jamais ce cas. */
.sec-head .muted,.sec-head .tiny.muted{color:rgba(255,255,255,.72)}


/* ══════════════════════════════════════════════════════════════════════
   LE SÉLECTEUR DE MISE EN PAGE (aperçu en direct)
   ----------------------------------------------------------------------
   Il remplace les deux flèches. Elles obligeaient à faire défiler les
   mises en page une par une pour retrouver celle qu'on cherchait, sans
   jamais montrer ce qui existe. Ici tout le choix est visible, et se fait
   glisser du doigt.
   ══════════════════════════════════════════════════════════════════════ */
.fiche-pick{position:fixed;left:0;right:0;bottom:0;z-index:9998;
  background:#14100c;color:#fff;padding:10px 0 calc(10px + env(safe-area-inset-bottom,0px));
  box-shadow:0 -10px 30px -14px rgba(0,0,0,.7)}
.fiche-pick .fp-tete{display:flex;align-items:baseline;gap:10px;padding:0 14px 8px;
  font:650 12.5px/1.2 var(--sans)}
.fiche-pick .fp-astuce{font-weight:400;font-size:11px;color:rgba(255,255,255,.5);margin-left:auto}
/* Le rail : défilement horizontal natif — donc glissement au doigt sur
   téléphone, deux doigts sur pavé tactile, molette inclinée à la souris.
   `scroll-snap` cale chaque vignette : on ne s'arrête jamais entre deux. */
.fiche-pick .fp-rail{display:flex;gap:10px;overflow-x:auto;overflow-y:hidden;
  padding:2px 14px 2px;scroll-snap-type:x mandatory;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
.fiche-pick .fp-rail::-webkit-scrollbar{display:none}
.fiche-pick .fp-item{flex:0 0 auto;scroll-snap-align:center;width:74px;padding:0;border:0;
  background:none;cursor:pointer;display:flex;flex-direction:column;gap:5px;align-items:center;
  font:inherit;color:inherit;-webkit-tap-highlight-color:transparent}
.fiche-pick .fp-nom{font-size:10.5px;line-height:1.2;text-align:center;
  color:rgba(255,255,255,.62);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:74px}
.fiche-pick .fp-item.on .fp-nom{color:#fff;font-weight:650}
/* La vignette : un petit plan de la page, pas une capture. Trois aplats
   suffisent à reconnaître une mise en page qu'on a déjà vue. */
.fiche-pick .fp-vue{position:relative;display:block;width:74px;height:92px;border-radius:9px;
  overflow:hidden;border:2px solid transparent;transition:border-color .14s,transform .14s}
.fiche-pick .fp-item.on .fp-vue{border-color:#fff}
.fiche-pick .fp-item:active .fp-vue{transform:scale(.95)}
.fiche-pick .fp-item:focus-visible .fp-vue{outline:2px solid var(--acc);outline-offset:2px}
.fiche-pick .fp-vue>*{position:absolute;border-radius:2px}
/* Disposition par défaut de la vignette : le visuel en haut, le texte
   dessous. Un design qui compose autrement la redresse par une règle
   `[data-apercu="<sa clé>"]`, comme le faisaient les anciens. */
.fiche-pick .fp-img{left:6px;right:6px;top:6px;height:46px;border-radius:5px}
.fiche-pick .fp-l1{left:8px;right:22px;top:60px;height:5px;opacity:.85}
.fiche-pick .fp-l2{left:8px;right:34px;top:70px;height:5px;opacity:.5}
.fiche-pick .fp-prix{left:8px;top:81px;width:22px;height:6px;border-radius:3px}


/* La barre d'achat monte au-dessus du sélecteur : sans ça les deux se
   superposent et « Ajouter au panier » devient inatteignable pendant
   qu'on essaie les mises en page. */
/* `--fp-h` est posée par js/product.js à partir de la hauteur RÉELLE du
   sélecteur. Le repli de 160px ne sert que le temps d'une image, avant la
   première mesure. */
html[data-edition] .stickybar{bottom:var(--fp-h,160px)}
@media(min-width:900px){
  html[data-edition] .stickybar{bottom:var(--fp-h,160px);padding-bottom:14px}}
/* Et le bas de page se dégage des deux barres empilées, sinon « Vous
   aimerez aussi » reste dessous. */
html[data-edition] .prod-bottom-space{height:calc(var(--fp-h,160px) + 150px)}

@media (prefers-reduced-motion: reduce){
  .fiche-pick .fp-vue{transition:none}
}


/* ── ESSAYER, PUIS CHOISIR ────────────────────────────────────────────
   Le clic ne fait que montrer ; l'enregistrement est un geste à part. Ces
   deux boutons n'apparaissent donc que lorsqu'il y a quelque chose à
   décider — sinon ils encombreraient en permanence une barre déjà dense. */
.fiche-pick .fp-actions{display:flex;gap:8px;align-items:center;margin-left:10px}
.fiche-pick .fp-actions[hidden]{display:none}
.fiche-pick .fp-annuler,.fiche-pick .fp-ok{
  border:0;border-radius:99px;cursor:pointer;font:650 12px/1 var(--sans);
  padding:8px 14px;-webkit-tap-highlight-color:transparent;transition:transform .12s,opacity .14s}
.fiche-pick .fp-annuler{background:rgba(255,255,255,.14);color:#fff}
.fiche-pick .fp-annuler:hover{background:rgba(255,255,255,.24)}
.fiche-pick .fp-ok{background:#fff;color:#14100c;font-weight:750}
.fiche-pick .fp-ok:hover{opacity:.88}
.fiche-pick .fp-annuler:active,.fiche-pick .fp-ok:active{transform:translateY(1px)}
.fiche-pick .fp-ok:focus-visible,.fiche-pick .fp-annuler:focus-visible{
  outline:2px solid var(--acc);outline-offset:2px}
/* Pendant qu'on essaie, la mention change de ton : elle ne dit plus comment
   se déplacer mais RASSURE sur le fait que rien n'est encore engagé. */
.fiche-pick .fp-astuce{transition:color .16s}

/* Le design réellement en ligne porte une pastille « actuel ». Sans elle,
   après trois essais, on ne sait plus lequel était le sien — et la seule
   façon de revenir en arrière serait de se souvenir de son nom. */
.fiche-pick .fp-actuel{
  display:none;position:absolute;left:50%;bottom:5px;transform:translateX(-50%);
  padding:2px 7px;border-radius:99px;background:rgba(20,16,12,.82);color:#fff;
  font:650 9px/1.4 var(--sans);letter-spacing:.04em;white-space:nowrap;
  border:1px solid rgba(255,255,255,.28)}
.fiche-pick .fp-item.actuel .fp-actuel{display:block}
/* Quand on regarde justement le design en ligne, la pastille n'apprend
   rien de plus que le cerclage : on l'efface. */
.fiche-pick .fp-item.actuel.on .fp-actuel{display:none}

/* Sur téléphone, l'entête passe sur deux lignes plutôt que d'écraser les
   boutons : « Enregistrer » ne doit jamais devenir illisible ou minuscule. */
@media(max-width:520px){
  .fiche-pick .fp-tete{flex-wrap:wrap;row-gap:6px}
  .fiche-pick .fp-actions{margin-left:auto}
}


/* Intertitre de groupe dans la rangée de designs. Écrit à la verticale : il
   sépare sans voler la largeur d'une vignette, ce qui comptera de nouveau
   dès que la rangée en fera défiler plusieurs. */
.fiche-pick .fp-sep{
  flex:0 0 auto;align-self:stretch;display:flex;align-items:center;
  writing-mode:vertical-rl;transform:rotate(180deg);
  padding:0 2px;margin-right:2px;
  font:650 9px/1 var(--sans);letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.42);white-space:nowrap;
  border-right:1px solid rgba(255,255,255,.14)}
.fiche-pick .fp-sep:first-child{border-right:0;padding-left:0}

/* ══════════════════════════════════════════════════════════════════════
   LE SOCLE DES DESIGNS
   ----------------------------------------------------------------------
   Un design dont la signature tient dans un dessin — un sol en perspective,
   une dalle extrudée, des panneaux de verre — s'écrit règle par règle.

   Un design qui se distingue surtout par sa PALETTE, ses arrondis, sa police
   de titre et son bouton, non : l'écrire à la main demanderait une
   quarantaine de lignes, qui se désaccorderaient au premier ajustement.

   Alors chaque design ne déclare que ses variables `--d-*` sur <html> —
   déclaration inerte, qui ne repeint rien par elle-même — et les deux
   blocs ci-dessous les distribuent : l'un à la fiche article, l'autre aux
   cartes du catalogue. Ajouter un design devient une déclaration, pas un
   chapitre.

   `data-socle` est posé par js/ui.js d'après FICHE_STYLES[…].socle.
   ══════════════════════════════════════════════════════════════════════ */

/* ── La fiche article, ET LES PAGES DE LA BOUTIQUE ──
   Panier, favoris, compte, carte cadeau, sur mesure prennent les mêmes
   couleurs et la même police que le design choisi : on ne change plus
   d'univers en passant d'une page à l'autre. Ce sont les mêmes variables,
   distribuées aux mêmes surfaces — rien à tenir à jour en double quand un
   design change.

   UNE seule classe pour les cinq, `page-boutique` : une liste de
   sélecteurs s'allongerait à chaque page ajoutée, et la prochaine serait
   oubliée. */
html[data-socle] body.page-boutique{
  /* LA POLICE DU DESIGN, AUSSI. Le panier portait la police du thème
     alors qu'il portait déjà ses couleurs : on passait d'une fiche en
     Archivo à un panier en serif. Tous les designs ne déclarent pas
     `--d-titre` ; le repli garde la police d'origine pour les autres,
     plutôt qu'une police vide. */
  --serif:var(--d-titre, "Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif)}
html[data-socle] body.page-boutique h1,
html[data-socle] body.page-boutique h2,
html[data-socle] body.page-boutique h3,
html[data-socle] body.page-boutique .total,
html[data-socle] body.page-boutique #next{
  font-weight:var(--d-titre-gras, 600);
  letter-spacing:var(--d-titre-chasse, -.01em)}
html[data-socle] body.page-boutique #ptitle{
  text-transform:var(--d-titre-casse, none)}

html[data-socle] body.page-produit,
html[data-socle] body.page-boutique{
  /* CHAQUE VARIABLE A SON REPLI, comme `--acc` juste en dessous. Sans
     eux, un design à socle SANS palette (c'est le cas de tous ceux du
     nouveau catalogue tant qu'ils n'en déclarent pas) rendait `--cream`
     invalide, et le dégradé du décor qui la cite tombait à `none` : plus
     aucun fond de page, donc du noir sur un navigateur en thème sombre. */
  --cream:var(--d-fond, var(--cream-base)); --cream-2:var(--d-fond2, var(--d-fond, var(--cream-2-base)));
  --card:var(--d-carte, var(--card-base)); --card-2:var(--d-carte2, var(--d-carte, var(--card-2-base)));
  --ink:var(--d-encre, var(--ink-base)); --ink-2:var(--d-encre2, var(--d-encre, var(--ink-2-base)));
  --ink-3:var(--d-encre3, var(--ink-3-base));
  --line:var(--d-filet, var(--line-base)); --line-2:var(--d-filet2, var(--d-filet, var(--line-2-base)));
  /* Repli sur la valeur du thème : un design sans `--d-acc` ne doit pas
     rendre `--acc` invalide et effacer le fond de toutes les pastilles. */
  --acc:var(--d-acc, var(--acc-base));
  --acc-d:var(--d-acc-d, var(--d-acc, var(--acc-d-base)));
  --acc-l:var(--d-acc-l, var(--d-filet, var(--acc-l-base)));
  --fort:var(--d-fort, var(--d-acc));
  color:var(--ink)}
/* ── UNE SECONDE SURFACE, PAS UNE COULEUR DE CONTRASTE ──
   `--d-fond2` est, chez plusieurs designs, la teinte OPPOSÉE au fond :
   le panneau sombre de la 5a, la bande noire de la 4c. Sur la fiche elle
   habille la scène, et c'est juste. Sur le panier elle sert de fond aux
   pastilles — celle de la quantité, les puces — dont l'encre reste celle
   du texte : le chiffre devenait sombre sur sombre, illisible sur huit
   designs.

   On la remplace par une nuance du fond lui-même, obtenue en y mêlant un
   peu d'encre. Elle se détache toujours du fond, et jamais du texte —
   que le design soit clair ou sombre. */
html[data-socle] body.page-boutique{
  --cream-2:color-mix(in srgb, var(--d-fond) 92%, var(--d-encre));
  --card-2:color-mix(in srgb, var(--d-carte, var(--d-fond)) 94%, var(--d-encre));

  /* ── LES ENCRES SECONDAIRES SORTENT DU DESIGN, PAS D'À CÔTÉ ──
     `--d-encre2` est une teinte déclarée à part. Sur un fond franc elle
     tombe juste ; sur un TON MOYEN elle se noie. La 4j (Valise) a un fond
     terracotta #c9603f et une encre secondaire grise #665750 : mesuré à
     1,7 — le texte d'aide y était illisible.

     On ne change pas le fond, ce serait trahir le design. On dérive les
     encres secondaires de sa PROPRE paire encre/fond : une teinte
     adoucie de son encre, sur son fond. Elle ne peut alors jamais être
     une couleur étrangère qui s'y perd. */
  --ink-2:color-mix(in srgb, var(--d-encre) 85%, var(--d-fond));
  --ink-3:color-mix(in srgb, var(--d-encre) 68%, var(--d-fond))}

html[data-socle] .stage{
  background:var(--d-scene, var(--d-fond2, var(--d-fond)));
  border-radius:var(--d-r, 0);overflow:visible}
html[data-socle] .stage .halo{display:none}
html[data-socle] .stage .scene{transform:var(--d-inclinaison, none)}
html[data-socle] .stage .prodhero{
  background:var(--d-socle-carte, var(--d-carte));
  border:var(--d-cadre, 0);border-radius:var(--d-r, 0);
  box-shadow:var(--d-ombre, none)}
html[data-socle] .stage .prodhero .prodhero-vis{
  padding:var(--d-marge, 0);border-radius:var(--d-r, 0);overflow:hidden}
/* Un fond opaque est OBLIGATOIRE : au-dessus de 900 px la règle de base
   passe .pdetail en transparent, pensée pour une encre sombre sur fond
   clair. Un design qui inverse l'encre y verrait son texte tomber à même
   le décor du catalogue. */
html[data-socle] .pdetail{
  background:var(--cream);border-radius:0;margin-top:0;box-shadow:none;
  border-top:1px solid var(--line)}
html[data-socle] #pname{
  font-family:var(--d-titre, var(--serif));
  font-weight:var(--d-titre-gras, 600);
  letter-spacing:var(--d-titre-chasse, -.01em);
  text-transform:var(--d-titre-casse, none);line-height:1.06}
html[data-socle] .pprice{
  font-family:var(--d-prix, var(--d-titre, var(--serif)));
  font-weight:var(--d-prix-gras, 700);letter-spacing:-.02em}
html[data-socle] .ptag{
  background:var(--d-puce, var(--card));border-color:var(--line-2);
  border-radius:var(--d-r-puce, 99px)}
html[data-socle] #addBtn{
  background:var(--d-btn, var(--fort));color:var(--d-btn-encre, #fff);
  border-radius:var(--d-r-btn, 999px);font-weight:750;
  box-shadow:var(--d-btn-ombre, none)}
html[data-socle] .pgal .pgal-th{
  border-radius:var(--d-r-min, 10px);border-color:var(--line-2)}
html[data-socle] .pgal .pgal-th.on{border-color:var(--d-acc)}
html[data-socle] .opt button.on{
  background:var(--d-acc);color:var(--d-btn-encre, #fff);
  border-color:var(--d-acc)}

/* ── Les cartes du catalogue ──
   Mêmes couleurs, pour que la boutique et la fiche ne se contredisent pas.
   Les variables sont redéfinies SUR la carte : son nom, son rayon, son
   prix et ses boutons les lisent tous, ils suivent donc sans qu'on ait à
   les énumérer. Le reste de la page n'est pas touché. */
html[data-socle] .pcard:not(.prodhero){
  --card:var(--d-carte); --ink:var(--d-encre);
  --ink-2:var(--d-encre2, var(--d-encre)); --ink-3:var(--d-encre3);
  --line:var(--d-filet); --line-2:var(--d-filet2, var(--d-filet));
  /* --acc sert de couleur de TEXTE dans plusieurs modèles de carte : le
     un cadre qui peint son prix à l'accent, par exemple. Un accent vif — cyan,
     jaune acide, orange — devient alors illisible sur une carte claire. On
     y met donc une variante densifiée jusqu'au seuil de lisibilité, en
     gardant l'accent d'origine pour --fort, qui ne sert qu'à des aplats
     pleins où le texte est posé par-dessus. */
  --acc:var(--d-acc-texte, var(--d-acc)); --acc-d:var(--d-acc-texte, var(--d-acc));
  /* L'encre lisible sur CET accent-là. `--sur-acc` est calculé pour la
     page ; à l'intérieur d'une carte l'accent est celui du design, et il
     peut être clair là où celui de la page est sombre. La valeur est
     calculée une fois pour toutes dans le bloc du design. */
  --sur-acc:var(--d-sur-acc, #fff);
  --sur-fort:var(--d-sur-fort, var(--d-sur-acc, #fff));
  --fort:var(--d-fort, var(--d-acc));
  background:var(--d-carte-fond, var(--d-carte));color:var(--d-encre);
  border:var(--d-carte-bordure, 1px solid var(--d-filet));
  border-radius:var(--d-r-carte, var(--r-l));
  box-shadow:var(--d-carte-ombre, var(--sh-s));
  /* Une ombre pleine ou une extrusion déborde de la boîte : sans cette
     respiration, la grille du catalogue la tranche net. */
  margin:var(--d-carte-marge, 0)}
html[data-socle] .pcard:not(.prodhero) .add{
  background:var(--d-btn-carte, var(--d-fort, var(--d-acc)));
  color:var(--d-btn-encre, #fff);
  border-radius:var(--d-r-btn-carte, var(--r-s));
  box-shadow:var(--d-btn-carte-ombre, none)}
/* La vignette : c'est là que se joue la moitié du caractère — un caisson
   creusé, un motif, un fond teinté. */
html[data-socle] .pcard:not(.prodhero) .thumb{
  background:var(--d-vignette, var(--card-2, var(--d-carte)));
  /* Une trame faite de traits de 1 px n'existe pas sans pas de répétition :
     sans `background-size`, le dégradé peint UNE ligne en haut et du vide en
     dessous. Le repli `auto` laisse intacts les fonds qui n'en ont pas
     besoin. */
  background-size:var(--d-vignette-taille, auto);
  border-radius:var(--d-r-min, 20px);
  box-shadow:var(--d-vignette-ombre, none)}
html[data-socle] .pcard:not(.prodhero) .name{
  font-family:var(--d-nom-police, inherit);
  font-weight:var(--d-nom-gras, 650);
  text-transform:var(--d-nom-casse, none)}
html[data-socle] .pcard:not(.prodhero) .fav{
  border-radius:var(--d-r-fav, 50%);
  background:var(--d-fav, rgba(255,255,255,.9))}
html[data-socle] .defile-suite{
  --ink:var(--d-encre); --ink-3:var(--d-encre3); --line:var(--d-filet);
  background:var(--d-carte);border-color:var(--d-filet)}
/* Sur les designs sombres, le cœur des favoris garde un fond clair : il
   disparaîtrait sinon dans la carte. */
html[data-socle][data-fondsombre] .pcard:not(.prodhero) .fav{background:rgba(255,255,255,.14)}
html[data-socle][data-fondsombre] .pcard:not(.prodhero) .fav svg{stroke:var(--d-encre)}


/* La même bande de designs, mais posée DANS le panneau plutôt que fixée en
   bas de l'écran : on choisit alors le design sans avoir à ouvrir un
   article dans l'aperçu. */
.fiche-pick.en-panneau{
  position:static;border-radius:16px;margin:0 0 12px;
  padding:10px 0;box-shadow:none}
.fiche-pick.en-panneau .fp-tete{padding:0 12px 8px}
.fiche-pick.en-panneau .fp-rail{padding:2px 12px}


/* Raccourcis de groupe — ils n'apparaissent qu'au-delà d'une douzaine de
   designs, quand la rangée devient trop longue pour être parcourue. */
.fiche-pick .fp-groupes{display:flex;gap:6px;overflow-x:auto;padding:0 14px 8px;
  scrollbar-width:none}
.fiche-pick .fp-groupes::-webkit-scrollbar{display:none}
.fiche-pick .fp-groupe{flex:0 0 auto;border:0;cursor:pointer;
  padding:5px 11px;border-radius:99px;background:rgba(255,255,255,.10);color:rgba(255,255,255,.72);
  font:650 11px/1 var(--sans);white-space:nowrap;transition:background .14s,color .14s}
.fiche-pick .fp-groupe:hover{background:rgba(255,255,255,.18);color:#fff}
.fiche-pick .fp-groupe.on{background:#fff;color:#14100c}
.fiche-pick.en-panneau .fp-groupes{padding:0 12px 8px}


/* ═════════════════════════════════════════════════════════════════════
   VOCABULAIRE DE DISPOSITION — la mise en page propre à chaque design
   ---------------------------------------------------------------------
   Un design ne réinvente pas sa mise en page : il prend l'une des six
   nommées ici. js/ui.js pose la bonne sur <html> via `data-dispo`, avec
   les proportions exactes de la maquette dans --l-cols (déclarées design
   par design dans js/themes.js).

     deux ......... le visuel, puis les informations
     deux-inverse . les informations d'abord
     trois ........ rail de vues élargi + deux colonnes
     douze ........ grille éditoriale décalée
     centre ....... tout sur un axe vertical
     plein ........ visuel pleine largeur

   CE VOCABULAIRE SURVIT À LA REMISE À ZÉRO DU CATALOGUE, et c'est
   volontaire : shopzy, seul design restant, n'utilise que `deux-inverse`,
   donc cinq de ces familles ne sont atteintes par personne aujourd'hui.
   Elles ne sont pas mortes pour autant — chacune a été mesurée sur une
   vraie fiche, sur les deux tailles d'écran, et les redessiner coûterait
   plus cher que de les garder. Les prochains designs s'y accrochent en
   déclarant `dispo`.

   ── CE QU'ON NE REPREND PAS DES MAQUETTES ──────────────────────────
   Leurs blocs sont posés en absolu dans un cadre de 760 px de haut, et
   calibrés sur un titre court (« T-shirt de sport »). Un vrai titre
   importé du fournisseur fait trois lignes : en absolu, il passerait
   sous le bouton d'achat — c'est exactement ce qui avait rendu une page
   illisible. On reprend donc la RÉPARTITION de chaque maquette (qui est
   à gauche, qui est à droite, dans quelles proportions) et jamais ses
   coordonnées. Tout reste en flux, aucune hauteur figée.
   ═════════════════════════════════════════════════════════════════════ */

/* ---------- ORDINATEUR ---------- */
@media(min-width:900px){

  html[data-dispo] .pwrap{
    gap:var(--l-gap,30px); max-width:var(--l-large,1180px);
    grid-template-columns:var(--l-rail,auto) var(--l-cols,minmax(0,1.05fr) minmax(0,.95fr))}
  html[data-dispo] .stage{grid-column:2;grid-row:1}
  html[data-dispo] .pdetail{grid-column:3;grid-row:1}
  html[data-dispo] .pgal{grid-column:1;grid-row:1}

  /* trois — le rail de vues n'est plus un liseré mais une vraie colonne :
     c'est ce qui fait lire la page en trois bandes, comme la maquette. */
  html[data-dispo="trois"]{--l-gap:26px}
  html[data-dispo="trois"] .pgal{width:var(--l-rail,110px)}
  html[data-dispo="trois"] .pgal .pgal-th{width:100%;height:auto;aspect-ratio:1}

  /* deux-inverse — le texte tient la gauche, le visuel arrive en réponse.
     Le rail de vues passe donc à droite, sous le visuel. */
  html[data-dispo="deux-inverse"] .pwrap{
    grid-template-columns:var(--l-cols,minmax(0,1fr) minmax(0,1.1fr)) var(--l-rail,auto)}
  html[data-dispo="deux-inverse"] .pgal{width:var(--l-rail,78px)}
  html[data-dispo="deux-inverse"] .pgal .pgal-th{width:100%;height:auto;aspect-ratio:1}
  html[data-dispo="deux-inverse"] .pdetail{grid-column:1}
  html[data-dispo="deux-inverse"] .stage{grid-column:2}
  html[data-dispo="deux-inverse"] .pgal{grid-column:3}
  html[data-dispo="deux-inverse"] .pdetail h1{font-size:40px;line-height:1.04;letter-spacing:-.02em}

  /* douze — grille éditoriale : les deux blocs ne se touchent pas, une
     colonne vide les sépare et décale la lecture. */
  html[data-dispo="douze"] .pwrap{
    grid-template-columns:auto repeat(12,minmax(0,1fr));gap:16px;max-width:1240px}
  html[data-dispo="douze"] .pdetail{grid-column:2 / 7}
  html[data-dispo="douze"] .stage{grid-column:8 / 14}

  /* centre — un seul axe, tout aligné dessus, mesure resserrée. */
  html[data-dispo="centre"] .pwrap{
    grid-template-columns:minmax(0,1fr);max-width:760px;gap:0}
  html[data-dispo="centre"] .stage{grid-column:1;grid-row:1;position:relative;top:auto;height:56vh;max-height:520px}
  html[data-dispo="centre"] .pgal{grid-column:1;grid-row:2;flex-direction:row;width:auto;max-height:none;
    justify-content:center;margin:14px 0 0;padding:0;overflow-x:auto}
  html[data-dispo="centre"] .pdetail{grid-column:1;grid-row:3;text-align:center;margin-top:18px}
  html[data-dispo="centre"] .ptete{justify-content:center;text-align:center;
    flex-direction:column;gap:6px;align-items:center!important}
  html[data-dispo="centre"] .ptete>div{text-align:center!important;width:100%}
  html[data-dispo="centre"] .ptags,
  html[data-dispo="centre"] .prow{justify-content:center}

  /* plein — le visuel prend toute la largeur, les informations viennent
     dessous en colonne étroite, décalées. */
  html[data-dispo="plein"] .pwrap{
    grid-template-columns:minmax(0,1fr);max-width:none;padding:0;gap:0}
  html[data-dispo="plein"] .stage{grid-column:1;grid-row:1;position:relative;top:auto;
    height:74vh;max-height:760px;border-radius:0;margin-top:0}
  /* L'en-tete de la boutique reste collee en haut : sans ce decalage, les
     boutons retour / partager / favori passent dessous. */
  html[data-dispo="plein"] .stage-top,
  html[data-dispo="centre"] .stage-top{padding-top:52px}
  html[data-dispo="plein"] .pgal{grid-column:1;grid-row:2;flex-direction:row;width:auto;max-height:none;
    max-width:1080px;margin:16px auto 0;padding:0 16px;overflow-x:auto}
  html[data-dispo="plein"] .pdetail{grid-column:1;grid-row:3;
    max-width:1080px;width:100%;margin:26px auto 0;padding-left:16px;padding-right:16px}
}

/* ---------- TÉLÉPHONE ----------
   Une colonne pour tout le monde — mais pas la même colonne. Ce qui
   distingue une maquette se traduit ici par ce qui domine l'écran. */
@media(max-width:899px){

  /* deux-inverse : quand les informations passent devant, c'est le TITRE
     qui est le sujet et le produit l'illustre. On rend donc le visuel plus
     court et le
     titre beaucoup plus grand, plutôt que de descendre la photo sous la
     description — une photo hors de l'écran d'accueil rendrait la fiche
     inutilisable. */
  html[data-dispo="deux-inverse"] .stage{height:38vh;min-height:250px}
  html[data-dispo="deux-inverse"] .pdetail h1{font-size:34px;line-height:1.05;letter-spacing:-.02em}
  html[data-dispo="deux-inverse"] .ptete{flex-direction:column;align-items:stretch!important;gap:8px}
  html[data-dispo="deux-inverse"] .ptete>div:last-child{text-align:left!important;
    display:flex;align-items:baseline;gap:10px}

  /* douze : rien de spectaculaire à empiler, mais l'esprit éditorial se
     garde par un titre large et un chapô détaché. */
  html[data-dispo="douze"] .pdetail h1{font-size:32px;line-height:1.08}
  html[data-dispo="douze"] #pdesc{font-size:16px}

  /* centre : l'axe vertical, c'est justement ce qui survit le mieux au
     téléphone. On le garde intégralement. */
  html[data-dispo="centre"] .pdetail{text-align:center}
  html[data-dispo="centre"] .ptete{flex-direction:column;gap:6px;align-items:center!important}
  html[data-dispo="centre"] .ptete>div{text-align:center!important;width:100%}
  html[data-dispo="centre"] .ptags,
  html[data-dispo="centre"] .prow{justify-content:center}
  html[data-dispo="centre"] .pgal{justify-content:center}

  /* plein : le visuel mange l'écran, bord à bord, et la feuille
     d'informations remonte dessus plus franchement. */
  html[data-dispo="plein"] .stage{height:66vh;max-height:none;border-radius:0}
  html[data-dispo="plein"] .pdetail{margin-top:-34px;border-radius:26px 26px 0 0}

  /* trois : le rail de vues devient une bande horizontale large, seule
     trace lisible d'une troisième colonne sur un écran de téléphone. */
  html[data-dispo="trois"] .pgal .pgal-th{width:84px;height:84px}
}


/* ══════════════════════════════════════════════════════════════════════
   LES COUCHES DE DÉCOR DANS LE CALQUE FIXE
   ----------------------------------------------------------------------
   js/ui.js (poserDecor) monte ici les couches relevées dans la maquette.
   Le calque est déjà `position:fixed; inset:0` : le décor reste immobile
   et la fiche défile par-dessus.

   Le voile clair du catalogue est retiré quand un décor est posé : il
   avait été mis pour qu'une PHOTO de fond n'avale pas les prix ; la
   maquette, elle, a déjà réglé ses contrastes.
   ══════════════════════════════════════════════════════════════════════ */
html.a-fond .cat-decor{overflow:hidden}
/* Un décor ne sert à rien s'il est couvert. La feuille d'informations et
   la scène sont opaques par défaut (elles portent la couleur du thème) :
   dès qu'un décor est posé, elles s'effacent pour le laisser voir. C'est
   ce que fait la maquette, où le décor traverse toute la page. */
html[data-decor] .pdetail{background:transparent;box-shadow:none;border-top:0}
html[data-decor] .stage{background:transparent;box-shadow:none}
html[data-decor] .stage .halo,
html[data-decor] .stage .ring,
html[data-decor] .stage .spark,
html[data-decor] .stage .shadow-floor{display:none}
html[data-decor].a-fond .cat-decor::after{display:none}
/* Le dégradé du catalogue est ÉTEINT sous un décor : la maquette part de
   sa propre couleur de cadre (5a : #f0efec), et c'est sur elle que sont
   calibrés ses contrastes. Laisser le dégradé par-dessous noyait la
   découpe sombre dans un fond déjà sombre — le titre blanc devenait
   invisible. */
html[data-decor].a-fond .cat-decor{
  background-color:var(--d-fond, var(--cream));background-image:none}
.cat-decor .d-couche{display:block;pointer-events:none}

/* Sur téléphone, le décor est calé sur un cadre bien plus large que haut
   (1040 × 760). Étiré sur un écran deux fois plus haut que large, un bloc
   de couleur devient une bande absurde. On le ramène donc sur la hauteur
   du premier écran, là où il compte, et on prolonge le fond en dessous. */
@media(max-width:899px){
  html[data-decor].a-fond .cat-decor .d-couche{
    transform-origin:top center}
  html[data-decor].a-fond .cat-decor{
    background:var(--d-fond, var(--cream))}
}

/* Décor solidaire du titre : il n'est plus fixé à la fenêtre mais posé en
   haut de la page, et défile avec elle. C'est la seule façon qu'une arête
   franche reste sous le titre quel que soit le nom de l'article. */
html[data-decor-ancre].a-fond .cat-decor{position:absolute;top:0;left:0;right:0;bottom:auto}

/* ══════════════════════════════════════════════════════════════════════
   LA PHOTO DE L'ARTICLE, DANS SON EMPLACEMENT RÉSERVÉ
   ----------------------------------------------------------------------
   Chaque maquette réserve un cadre au visuel (js/themes.js → PHOTOS) :
   des proportions, une place, un rayon, une inclinaison, une ombre. Ces
   deux règles y ENFERMENT la photo de l'article.

   Sans cet enfermement, la photo reprend sa taille naturelle : mesurée
   à 1013 × 894 dans une scène de 450 × 420, elle recouvrait le titre.
   ══════════════════════════════════════════════════════════════════════ */
html[data-photo] .stage .scene{
  position:absolute;inset:0;padding:0;display:block;perspective:none}
/* Aucun habillage : pas de cadre, pas de bordure, pas d'ombre. Les photos
   d'articles sont détourées ; un support derrière les encadrerait comme
   une vignette au lieu de les poser dans le décor. */
html[data-photo] .stage .prodhero{
  position:absolute;inset:0;width:100%;height:100%;margin:0;
  max-width:none;max-height:none;aspect-ratio:auto;display:block;
  background:transparent;border:0;border-radius:0;box-shadow:none;overflow:visible}
html[data-photo] .stage .prodhero-vis{
  position:absolute;inset:0;width:100%;height:100%;display:block;overflow:hidden}
html[data-photo] .stage .obj{
  position:absolute;inset:0;width:100%;height:100%;
  max-width:none;max-height:none;aspect-ratio:auto;transform:none}
html[data-photo] .stage .obj img,
html[data-photo] .stage .obj .lay{
  width:100%;height:100%;object-fit:contain;border-radius:0;background:transparent}
/* Une maquette « libre » ne réserve pas de cadre : sa photo détourée flotte
   dans la scène et garde son ombre portée (js/themes.js, PHOTOS). */
html:not([data-photo]) .stage .obj img{filter:var(--ph-fl,none)}

@media(min-width:900px){
  /* Les proportions et la place viennent de la maquette. L'inclinaison
     n'est appliquée qu'ici : sur téléphone, une carte tournée de 13° dans
     une colonne unique sort de l'écran. */
  html[data-photo] .stage{
    position:relative;top:auto;overflow:visible;
    height:auto;max-height:none;
    aspect-ratio:var(--ph-ratio,1);
    margin-top:calc(var(--ph-y,0) * 1vh)}
  html[data-photo] .stage .prodhero,
  html[data-photo] .stage .prodhero:hover{transform:none}
}
@media(max-width:899px){
  html[data-photo] .stage{overflow:hidden}
}

/* ══════════════════════════════════════════════════════════════════════
   PAS DE BANDE NOIRE SUR LA FICHE
   ----------------------------------------------------------------------
   « Avis des clients » et « Vous aimerez aussi » sont posés sur un
   bandeau plein, hérité du catalogue : il y sépare les rayons d'un fond
   photographique. Sur une fiche qui porte déjà le décor de sa maquette,
   ce pavé noir est une pièce rapportée. L'intitulé prend l'encre du
   design — noire sur un fond clair, claire sur un fond sombre.
   ══════════════════════════════════════════════════════════════════════ */
html[data-decor] .pwrap .sec-head::before{display:none}
html[data-decor] .pwrap .sec-head h1,
html[data-decor] .pwrap .sec-head h2{color:var(--d-encre,var(--ink))}
html[data-decor] .pwrap .sec-head a{color:var(--d-encre2,var(--ink-2))}
html[data-decor] .pwrap .sec-head a:hover{color:var(--d-encre,var(--ink))}
html[data-decor] .pwrap .sec-head select{color:var(--d-encre2,var(--ink-2))!important}

/* ══════════════════════════════════════════════════════════════════════
   LA MAQUETTE POSÉE TELLE QUELLE
   ----------------------------------------------------------------------
   Le gabarit est rendu à sa taille NATIVE (1040 × 760) puis mis à
   l'échelle. On obtient le dessin exact de la maquette, réduit — jamais
   un dessin recomposé, qui redistribuerait les blancs et changerait tout.

   Le reste de la fiche — quantité, retrait & livraison, avis,
   suggestions — défile en dessous, intact. Ce qui a été versé DANS la
   maquette (nom, prix, rayon, description, photo) est masqué plus bas :
   sans cela, le visiteur lirait deux fois le même nom et deux prix.
   ══════════════════════════════════════════════════════════════════════ */
.fp-maq{position:relative;width:100%;max-width:1040px;margin:0 auto;overflow:hidden}
/* Le groupe d'options que la maquette reprend déjà à son compte. Masqué à
   l'œil, PAS retiré : c'est lui qui porte l'état de la sélection, et les
   pastilles de la maquette le pilotent par un clic. `display:none` le rendrait
   inopérant. `clip-path` le laisse cliquable par programme. */
#opts > div.opt-repris{position:absolute;width:1px;height:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;pointer-events:none}
.fp-maq-cadre{width:1040px;height:auto;transform-origin:top left}
/* ── LA MAQUETTE EST ISOLÉE DU RESTE DU SITE ────────────────────────
   Les règles générales (`*`, `h1, h2, h3`, `h1`) imposaient la police
   du thème au titre de la maquette : « PARFUM BOIS » sortait en serif
   là où le modèle demande Archivo. Les tailles et graisses, elles, sont
   en style EN LIGNE dans le gabarit et gagnent déjà.

   On ne remet donc que ce que le site avait pris : la famille, et les
   marges par défaut des titres. */
.fp-maq-cadre h1,.fp-maq-cadre h2,.fp-maq-cadre h3,
.fp-maq-cadre p,.fp-maq-cadre div,.fp-maq-cadre span,
.fp-maq-cadre b,.fp-maq-cadre strong,.fp-maq-cadre small{font-family:inherit}
.fp-maq-cadre h1,.fp-maq-cadre h2,.fp-maq-cadre h3,.fp-maq-cadre p{margin:0}
.fp-maq-cadre h1{max-width:none;overflow-wrap:normal}

/* La maquette porte SA barre d'achat. Tant qu'elle est à l'écran, celle
   du site ferait doublon et la recouvrirait — deux boutons « Ajouter au
   panier » l'un sur l'autre. Elle reparaît dès qu'on a défilé. */
/* `visibility:hidden` et pas seulement `opacity:0` : une barre restée
   « visible » au sens du moteur continue de se placer au-dessus du prix
   de la maquette et de le recouvrir. */
html.maq-en-vue .stickybar{opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .18s, visibility 0s linear .18s}

html[data-maquette] .stage,
html[data-maquette] .pdetail .ptete,
html[data-maquette] .pdetail .ptags,
html[data-maquette] .pdetail #pdesc{display:none}
/* Le décor du calque de fond n'a plus lieu d'être : la maquette porte le
   sien, entier, dans son propre cadre. */
html[data-maquette] .cat-decor .d-couche{display:none}
html[data-maquette] .pwrap{display:block;max-width:1040px;margin:0 auto;padding:0 16px}
/* LE BANDEAU D'ACHAT DESCEND DANS LE FLUX. Il est normalement en position
   fixe, collé en bas de l'écran — utile sur une fiche ordinaire, néfaste
   sous une maquette : il recouvrait la description et les tailles, et la
   maquette porte déjà son propre bouton dans son dessin. Rendu au flux, il
   se pose SOUS le contenu, sans plus rien masquer. L'espace réservé sous la
   page n'a alors plus de raison d'être. */
html[data-maquette] .stickybar{position:static;bottom:auto;z-index:auto;
  background:none;padding:8px 16px 40px;margin:0 auto;max-width:1040px}
html[data-maquette] .prod-bottom-space{display:none}
/* Rendu au flux, le bandeau ne recouvre plus rien : le faire disparaître
   quand la maquette est à l'écran n'aurait plus de sens, et laisserait un
   trou clignotant au défilement. On annule donc l'escamotage ici — et
   seulement ici, la fiche sans maquette gardant son bandeau flottant. */
html[data-maquette].maq-en-vue .stickybar{opacity:1;visibility:visible;pointer-events:auto}
/* LA GALERIE RESTE, ELLE. Elle était masquée avec le reste de ce que la
   maquette reprend à son compte — sauf que la maquette ne réserve qu'UNE
   place à la photo : les autres vues d'un article importé devenaient
   inatteignables, et le commerçant croyait n'en avoir importé qu'une. Les
   vignettes reviennent donc sous le cadre, centrées, et pilotent la photo
   de la maquette. */
html[data-maquette] .pgal{display:flex;flex-direction:row;justify-content:center;
  flex-wrap:wrap;gap:10px;width:100%;max-width:1040px;margin:14px auto 30px;padding:0 16px;
  /* Sur grand écran, la galerie ordinaire est une colonne de 78 px posée à
     gauche de la photo. Sous une maquette il n'y a pas de colonne : les
     vignettes forment un bandeau horizontal centré. Sans ce redressement,
     elles restaient empilées les unes sous les autres. */
  max-height:none;overflow:visible}
html[data-maquette] .pdetail{margin-top:26px;border-radius:0;box-shadow:none;
  padding-left:0;padding-right:0;background:transparent}

/* ── LES FLÈCHES DE GALERIE DANS UN GABARIT, TOUS DESIGNS CONFONDUS ──
   Ces trois règles n'ont VOLONTAIREMENT aucun préfixe html[data-fiche] :
   elles valent pour les vingt-et-un gabarits, comme le veut js/product.js
   qui pose les flèches dans l'emplacement photo sans regarder le design.
   Elles vivaient à la fin du bloc PISTE, où l'on croyait ne retoucher que
   la piste : les déplacer ici, avec le reste du générique, évite qu'une
   retouche d'un seul design déplace les flèches des vingt autres.
   Mêmes pastilles que sur la scène classique, mais collées au bord de la
   photo plutôt qu'à celui de la scène. */
.fp-maq .fp-fleche{width:34px;height:34px;font-size:19px}
.fp-maq .fp-fleche.g{left:-6px}
.fp-maq .fp-fleche.d{right:-6px}

/* ── L'ARTICLE EST POSÉ SUR LE DÉCOR, PAS SUSPENDU DEVANT ───────────
   js/product.js pose la photo en `contain` sur toute la hauteur de son
   emplacement (`width:100%;height:100%`). Sans `object-position`, la
   valeur initiale `50% 50%` s'applique et l'article se CENTRE dans le
   cadre : une photo carrée ou en paysage laisse alors du vide sous
   elle, et l'article flotte au-dessus de la planche, de la pierre ou du
   plan de travail que le gabarit lui a dessinés. L'ombre, qui est un
   drop-shadow épousant la silhouette réelle, flotte avec lui.
   Les `align-items:flex-end` des gabarits n'y peuvent rien : l'image
   occupe TOUT le cadre, c'est `object-fit` qui décide où le sujet se
   pose dedans.
   La règle est générique parce que les vingt gabarits à décor posent
   tous l'article au sol ; elle est placée AVANT les blocs de design pour
   qu'un design puisse encore la contredire à spécificité égale, ce que
   fait le seul gabarit SANS décor, `shopzy`, dont l'emplacement est un
   carré gris où l'article se centre. La déclaration passe devant le
   cssText en ligne de product.js, qui ne déclare pas `object-position`. */
html[data-maquette] [data-fp="photo"] img{object-position:center bottom}

@media(max-width:899px){
  .fp-maq{max-width:none}
}

/* Le gabarit téléphone est écrit à la largeur de l'écran : il ne subit
   aucune réduction, sinon il serait rapetissé une seconde fois. */
.fp-maq-cadre.fp-maq-fluide{width:100%;height:auto;transform:none}

/* ══════════════════════════════════════════════════════════════════════
   SHOPZY — LE THÈME DE LA BOUTIQUE
   ----------------------------------------------------------------------
   Repris de shopzy-theme.css et de DESIGN.md, à la valeur près. Aucune
   couleur inventée : chaque teinte ci-dessous figure dans le fichier de
   thème d'origine.

   Deux règles de ce guide demandent une reprise explicite, parce que le
   site les enfreint par défaut :

   · « deux graisses seulement, 400 et 500 — jamais de 600/700 ». Le
     socle écrit le bouton d'achat en 750 et les titres en 600.
   · le bouton principal est NOIR (#1a1a18), pas de la couleur d'accent.
     Le bleu #185fa5 est réservé aux liens, à « Tout voir » et au bandeau
     de livraison.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="shopzy"]{
  --d-fond:#ffffff; --d-fond2:#f6f5f2;
  --d-carte:#ffffff; --d-carte2:#f6f5f2;
  --d-encre:#1a1a18; --d-encre2:#5f5e5a; --d-encre3:#9a988f;
  --d-filet:#e5e3dc; --d-filet2:#e5e3dc;
  --d-acc:#185fa5; --d-acc-d:#124a80; --d-acc-l:#e6f1fb; --d-acc-texte:#185fa5;
  /* le bouton d'achat : noir, comme .sz-btn-primary */
  --d-fort:#1a1a18; --d-btn:#1a1a18; --d-btn-encre:#ffffff;
  --d-titre:system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --d-titre-gras:500; --d-titre-casse:none; --d-titre-chasse:-.02em;
  --d-prix:system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --d-prix-gras:500;
  --d-r:8px; --d-r-min:6px; --d-r-btn:8px; --d-r-carte:12px; --d-r-puce:6px; --d-sur-acc:#fff; --d-sur-fort:#fff}

/* « jamais de 600/700 » : le socle écrit le bouton en 750 et les titres
   en 600. On rétablit les deux graisses du guide. */
html[data-fiche="shopzy"] #addBtn,
html[data-fiche="shopzy"] .btn,
html[data-fiche="shopzy"] #next{font-weight:500}
html[data-fiche="shopzy"] #pname,
html[data-fiche="shopzy"] h1,
html[data-fiche="shopzy"] h2,
html[data-fiche="shopzy"] h3{font-weight:500;letter-spacing:-.02em}
/* Le bouton principal est noir, pas bleu : l'accent reste aux liens. */
html[data-fiche="shopzy"] .btn.primary{
  background:#1a1a18;color:#ffffff;box-shadow:none}
/* « bordures fines, jamais d'ombre décorative ». */
html[data-fiche="shopzy"] .summary,
html[data-fiche="shopzy"] .citem{box-shadow:none;border:1px solid #e5e3dc}
/* La carte du catalogue est séparée des deux autres pour son
   `:not(.prodhero)`, et ce n'est pas un ornement : le bloc générique
   `html[data-socle] .pcard:not(.prodhero)` pèse (0,3,1) et repose une
   `box-shadow` dès que le design ne déclare pas `--d-carte-ombre`, ce qui
   est le cas ici. Sans ce filet, la carte de la boutique par défaut
   portait l'ombre que le guide interdit. Même spécificité que le
   générique, et ce bloc arrive après : c'est l'ordre qui tranche. */
html[data-fiche="shopzy"] .pcard:not(.prodhero){
  box-shadow:none;border:1px solid #e5e3dc}

/* « Texte en MAJUSCULES : interdit (sauf sigles) ». Le remplisseur commun
   écrit les repères chiffrés en capitales espacées, avec une valeur en
   graisse 800 — deux règles du guide enfreintes d'un coup. Le style est
   posé EN LIGNE par js/product.js : seul un !important peut le reprendre. */
html[data-fiche="shopzy"] [data-fp="reperes"] div{
  text-transform:none!important;letter-spacing:-.02em!important}
html[data-fiche="shopzy"] [data-fp="reperes"] div>div:first-child{
  font-size:13px!important;color:#5f5e5a!important;opacity:1!important}
html[data-fiche="shopzy"] [data-fp="reperes"] div>div:last-child{
  font-size:16px!important;font-weight:500!important}
/* Les choix d'options suivent la même sobriété : filet fin, coin 8 px. */
html[data-fiche="shopzy"] [data-fp="options"] span{
  border-radius:8px;font-weight:500!important;padding:10px 16px!important}
/* L'ARTICLE RESTE CENTRÉ ICI, contrairement aux vingt gabarits à décor.
   La règle générique `html[data-maquette] [data-fp="photo"] img` plaque
   l'article au bas de son emplacement pour qu'il se pose sur la planche,
   la pierre ou le plan de travail que le décor lui dessine. Shopzy n'a
   pas de décor : son emplacement est un carré gris à coins ronds, et un
   article collé au bord inférieur y donnerait un vide en haut au lieu
   d'une pose. Même spécificité que la règle générique (0,2,2) ; c'est
   l'ordre qui tranche, et ce bloc arrive après. */
html[data-fiche="shopzy"] [data-fp="photo"] img{object-position:center center}

/* ══════════════════════════════════════════════════════════════════════
   L'EN-TÊTE SUR UN ÉCRAN LARGE : ENSEIGNE · RAYONS · ICÔNES
   ----------------------------------------------------------------------
   La disposition du thème de la boutique (DESIGN.md) : « logo à gauche,
   navigation au centre, icônes recherche / compte / panier à droite ».

   js/ui.js (rangerLesRayons) déplace la rangée des rayons DANS la barre
   au-delà de 900 px, et la redescend en dessous en deçà — cinq rayons ne
   tiennent pas à côté d'une enseigne et de trois icônes sur un téléphone.

   Les trois traits disparaissent sur écran large : ils ouvraient un
   sommaire qui listait des rayons désormais visibles.
   ══════════════════════════════════════════════════════════════════════ */
@media(min-width:900px){
  html[data-entete-large] .tabbar.en-tete .tabbar-in{
    grid-template-columns:auto minmax(0,1fr) auto auto;gap:24px}
  /* `grid-row:1` sur les quatre : sans cela, un élément trop large crée
     une ligne implicite et la rangée des rayons passait AU-DESSUS de
     l'enseigne au lieu d'être à côté. */
  html[data-entete-large] .tabbar.en-tete .mn-nom{
    grid-column:1;grid-row:1;justify-self:start;text-align:left}
  html[data-entete-large] .tabbar-in>.cats-bande{
    grid-column:2;grid-row:1;
    background:none;border:0;justify-self:stretch;
    /* la rangée gardait sa largeur de page (1120 px) et débordait de la
       colonne : elle s'ajuste maintenant à la place disponible. */
    width:auto;max-width:100%;min-width:0;margin:0;overflow:hidden}
  html[data-entete-large] .tabbar-in>.cats-bande .scroller{
    justify-content:center;padding:0;overflow-x:auto;scrollbar-width:none}
  html[data-entete-large] .tabbar-in>.cats-bande .scroller::-webkit-scrollbar{display:none}
  html[data-entete-large] .tabbar.en-tete .mn-cote:not(.mn-fin){grid-column:3;grid-row:1}
  html[data-entete-large] .tabbar.en-tete .mn-fin{grid-column:4;grid-row:1}
  /* Le sommaire n'a plus d'objet : ses rayons sont sous les yeux. */
  html[data-entete-large] .tabbar.en-tete #mnSommaire{display:none}
}

/* ══════════════════════════════════════════════════════════════════════
   PISTE — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/piste.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous — quantité, accordéons, avis, « vous aimerez
   aussi » — appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux
   au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   béton devient la surface, le rouge de tartan devient l'accent.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="piste"]{
  --d-fond:#f0ece6; --d-fond2:#e3ded6;
  --d-carte:#ffffff; --d-carte2:#faf8f5;
  --d-encre:#1e1b19; --d-encre2:#4c4540; --d-encre3:#6b6259;
  --d-filet:#ded7cd; --d-filet2:#cfc7ba;
  --d-acc:#b8442c; --d-acc-d:#94341f; --d-acc-l:#f6e5e0;
  --d-fort:#b8442c}
/* Les lignes de la piste, reprises en filet sous les titres de section :
   c'est ce qui raccorde le bas de la page au décor du haut. */
html[data-fiche="piste"] body.page-produit .acc-t{letter-spacing:.01em}
html[data-fiche="piste"] body.page-produit .acc-t::after{content:'';display:block;
  width:54px;height:2px;margin-top:8px;background:var(--d-acc)}
/* Les barres de notation gardaient l'or du thème alors que tout le reste
   de la page a pris les couleurs du design : deux teintes chaudes
   voisines mais différentes, juste à côté des étoiles déjà passées au
   rouge. Elles suivent désormais l'accent du design. */
html[data-fiche="piste"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="piste"] .rate-pick button.on{color:var(--d-acc)}
/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit. */
html[data-fiche="piste"] [data-fp="photo"] img{
  filter:drop-shadow(0 22px 22px rgba(74,26,16,.42))}
/* ══════════════════════════════════════════════════════════════════════
   ÉDITORIAL CRÈME — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/editorial.html) ne couvre que le haut de la
   fiche. Tout ce qui vient dessous — quantité, accordéons, avis, « vous
   aimerez aussi » — appartient à la page, pas à la maquette. Sans
   palette, ces blocs gardaient les couleurs du thème et la fiche se
   coupait en deux au millimètre où le gabarit s'arrête.

   Les teintes sont RELEVÉES SUR LE DÉCOR, pas inventées : le plâtre du
   mur donne le fond (#f3ead9), la cimaise donne l'accent (#6e1226), la
   pierre du sol donne la seconde surface (#e7dcc8). C'est ce qui fait
   que la page et la photo ne se contredisent pas.

   Aucune variable de POLICE n'est déclarée, et c'est voulu : le repli de
   `--d-titre` est déjà la pile serif du thème, exactement celle du
   gabarit. En déclarer une ne changerait rien, sinon un endroit de plus
   à tenir à jour le jour où la pile bouge.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="editorial"]{
  --d-fond:#f3ead9; --d-fond2:#e7dcc8;
  --d-carte:#fffaf0; --d-carte2:#f7efe0;
  --d-encre:#1c1614; --d-encre2:#5a5049; --d-encre3:#6f6357;
  --d-filet:#ded2bf; --d-filet2:#c8b9a2;
  --d-acc:#6e1226; --d-acc-d:#4e0817; --d-acc-l:#f2e2de;
  --d-fort:#6e1226}
/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit.
   Basse et large, comme celle d'un objet posé sur une pierre pâle dans
   une pièce éclairée par le haut — pas le contact net d'un studio. */
html[data-fiche="editorial"] [data-fp="photo"] img{
  filter:drop-shadow(0 20px 20px rgba(74,50,36,.26))}

/* ── LA CARTE DU CATALOGUE ──
   Même monde que la fiche : une feuille crème posée sur le fond, un
   panneau de pierre pour le visuel, le nom en serif et tout le reste en
   sans. Les angles sont à peine adoucis (6 px pour 220 px de large, la
   proportion relevée sur la carte de référence) : une carte trop ronde
   ferait « application », pas « page imprimée ». */
html[data-fiche="editorial"] .pcard:not(.prodhero){
  background:var(--d-carte); border:1px solid var(--d-filet);
  border-radius:6px; padding:12px;
  box-shadow:0 1px 2px rgba(58,38,26,.05), 0 10px 22px -14px rgba(58,38,26,.30)}
/* Le visuel est posé sur un panneau de pierre, pas sur la feuille : sans
   lui, un article photographié sur fond blanc se dissolvait dans la
   carte et la rangée n'était plus qu'une suite de rectangles crème. */
html[data-fiche="editorial"] .pcard:not(.prodhero) .thumb{
  background:var(--d-fond2); border-radius:4px}
/* Le nom est la seule chose en serif sur la carte — c'est ce qui la
   rattache au titre de la fiche. `min-height` est reprise parce qu'elle
   suit l'interligne : la règle de base la calcule sur 1,25 em, et la
   rangée se désalignait de trois pixels sur les noms courts. */
html[data-fiche="editorial"] .pcard:not(.prodhero) .name{
  font-family:var(--serif); font-size:17px; font-weight:500;
  line-height:1.22; letter-spacing:-.01em; margin:11px 2px 3px;
  min-height:calc(2 * 1.22em)}
html[data-fiche="editorial"] .pcard:not(.prodhero) .cat{
  font-size:11px; letter-spacing:.01em; color:var(--d-encre3)}
/* Le prix reste en serif, lui aussi : nom et prix sont les deux seules
   choses qu'on retient d'une carte, ils parlent donc la même langue. Le
   reste — rayon, badge, bouton — est en sans, ce sont des repères. */
html[data-fiche="editorial"] .pcard:not(.prodhero) .price{
  font-family:var(--serif); font-size:16px; font-weight:600;
  letter-spacing:-.01em; color:var(--d-encre)}
/* Le bouton d'ajout redevient un disque plein : c'est le seul aplat de
   bordeaux de la carte, et le seul geste qu'elle propose. */
html[data-fiche="editorial"] .pcard:not(.prodhero) .add{
  background:var(--d-acc); color:#fffaf0; border-radius:50%}
/* Trois badges, trois rôles. La promotion DOIT se voir : elle garde
   l'aplat bordeaux. « Nouveau » et « Best-seller » ne sont pas des
   urgences : cartouche crème et filet fin, comme sur la carte de
   référence. L'épuisé s'efface dans l'encre tertiaire. Angles à 2 px
   pour tous : une pastille ronde jurerait avec le reste. */
html[data-fiche="editorial"] .pcard:not(.prodhero) .flag{
  top:18px; left:18px; border-radius:2px; padding:5px 9px;
  font-size:10.5px; font-weight:600; letter-spacing:.04em;
  background:var(--d-acc); color:#fffaf0}
html[data-fiche="editorial"] .pcard:not(.prodhero) .flag.soft{
  background:var(--d-carte); color:var(--d-acc);
  border:1px solid var(--d-filet2)}
html[data-fiche="editorial"] .pcard:not(.prodhero) .flag.out{
  background:var(--d-encre3); color:#fffaf0; border:0}
/* Le favori perd sa pastille blanche : sur une carte déjà crème, elle
   posait un deuxième blanc à côté du premier. Il ne reste que le tracé,
   au bordeaux du design, comme sur la carte de référence. */
html[data-fiche="editorial"] .pcard:not(.prodhero) .fav{
  background:transparent; box-shadow:none}
html[data-fiche="editorial"] .pcard:not(.prodhero) .fav svg{stroke:var(--d-acc)}
html[data-fiche="editorial"] .pcard:not(.prodhero) .fav.on svg{fill:var(--d-acc); stroke:var(--d-acc)}

/* ══════════════════════════════════════════════════════════════════════
   NOCTURNE DORÉ : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/nocturne.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous (quantité, accordéons, avis, « vous aimerez
   aussi ») appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème : on passait d'une nuit au
   charbon à du blanc, au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   charbon devient la surface, l'or devient l'accent.

   LE DESIGN EST SOMBRE, DONC L'ENCRE EST CLAIRE. Deux inversions à ne pas
   défaire par réflexe :
   · --d-acc-d est PLUS CLAIR que --d-acc. Sur du charbon c'est l'or
     éclairci qui porte le texte (.stars, .annonce, .mn-ligne.actif) ; un
     or foncé s'y noierait.
   · --d-acc-l n'est pas une teinte pâle mais un pan d'or ÉTEINT. Il sert
     de fond sous l'encre courante (.radio-card.on, .alert-ok, .annonce) :
     pâle, il aurait reçu du crème sur du crème.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="nocturne"]{
  --d-fond:#1b1b1f; --d-fond2:#141417;
  --d-carte:#212127; --d-carte2:#26262d;
  --d-encre:#f4efe4; --d-encre2:#c2beb6; --d-encre3:#8e8b92;
  --d-filet:#3a342c; --d-filet2:#4e4536;
  --d-acc:#cdac6e; --d-acc-d:#e2c78e; --d-acc-l:#2a2318;
  --d-fort:#cdac6e;
  /* L'encre lisible SUR l'or : 8,3 pour 1. Posée explicitement plutôt que
     laissée au repli #fff, qui ne donne que 1,9 sur cet or et effaçait le
     libellé du bouton. */
  --d-sur-acc:#17171a; --d-sur-fort:#17171a;
  --d-acc-texte:#dfc189;
  /* Le titre en serif, comme sur la maquette : la fiche et son gabarit ne
     doivent pas changer de voix à la jointure. Le prix, lui, reste en
     sans : un chiffre en Didone se lit moins vite. */
  --d-titre:'Playfair Display','Instrument Serif',Georgia,'Times New Roman',serif;
  --d-titre-gras:600;
  --d-prix:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif; --d-prix-gras:600;
  --d-nom-police:'Playfair Display','Instrument Serif',Georgia,'Times New Roman',serif;
  --d-nom-gras:500;
  /* Le bouton d'achat de la page reprend celui du gabarit : crème sur
     charbon, seul point clair de toute la fiche. --d-btn-encre sert aussi
     au « + » des cartes et à la taille retenue, tous deux sur or. */
  --d-btn:#f6f1e6; --d-btn-encre:#17171a; --d-r-btn:4px;
  /* Un seul jeton de forme pour la carte, sa vignette et les vignettes de
     galerie : ils se répondent au lieu de dériver chacun de son côté. */
  --d-r-carte:18px; --d-r-min:14px}

/* L'ombre de l'article, portée par la PHOTO et non par son cadre : un
   filtre posé sur le cadre s'appliquerait aussi aux deux flèches de
   galerie que product.js vient y accrocher.
   Deux couches, parce qu'une ombre noire ne se voit pas sur du noir : la
   première ancre l'article au sol, la seconde lui rend la lueur ambrée de
   la flaque dans laquelle il est posé. */
html[data-fiche="nocturne"] [data-fp="photo"] img{
  filter:drop-shadow(0 24px 26px rgba(0,0,0,.70)) drop-shadow(0 0 30px rgba(205,172,110,.22))}

/* ── LA CARTE DU CATALOGUE ─────────────────────────────────────────────
   Même monde que la fiche : un charbon à peine détaché du fond, tenu par
   un seul liseré d'or, et deux choses qui brillent, le prix et le « + ».

   Le sélecteur double le `:not(.prodhero)` du bloc générique
   `html[data-socle] .pcard:not(.prodhero)` écrit plus haut. Ce n'est pas
   une coquetterie : sans lui la règle générique reste la plus forte et
   rien de ce qui suit ne s'applique. À spécificité égale c'est l'ordre
   qui tranche, et ce bloc arrive après. */
html[data-fiche="nocturne"] .pcard:not(.prodhero){
  background:#212127;
  border:1px solid rgba(205,172,110,.34);
  box-shadow:0 12px 30px rgba(0,0,0,.42)}
/* La vignette : un pan à peine éclairci, pour que les articles sans photo
   (émoji, dessin) ne flottent pas dans le vide. */
html[data-fiche="nocturne"] .pcard:not(.prodhero) .thumb{
  background:rgba(244,239,228,.045)}
/* La photo REMPLIT sa vignette, le dessin respire. Ce n'est pas une
   inattention : une photo détourée sur fond noir prolonge la carte, alors
   qu'un émoji porté à la même taille devient une enseigne. Et l'ombre
   brune d'origine (rgba(120,70,40,.18)) n'existe pas sur du charbon : on
   la remplace par du noir franc plus une lueur d'or. */
html[data-fiche="nocturne"] .pcard:not(.prodhero) .thumb .photo-frame{
  width:100%;height:100%;
  filter:drop-shadow(0 10px 18px rgba(0,0,0,.55))}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .thumb svg{
  width:86%;height:86%;
  filter:drop-shadow(0 10px 16px rgba(0,0,0,.50)) drop-shadow(0 0 18px rgba(205,172,110,.18))}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .name{
  font-size:17px;letter-spacing:-.005em;color:#f4efe4;margin-top:12px}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .cat{
  font-size:11.5px;letter-spacing:.01em;color:#8e8b92}
/* Le filet qui sépare le nom du prix : le liseré d'or de l'horizon,
   redescendu dans la carte. C'est lui qui fait reconnaître le design
   avant même d'avoir lu le nom de la boutique. */
html[data-fiche="nocturne"] .pcard:not(.prodhero) .foot{
  border-top:1px solid rgba(205,172,110,.16);margin-top:auto;padding-top:12px}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .price{
  color:#dfc189;font-weight:600}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .price .old{color:#8e8b92}
/* Le « + » : un disque d'or plein, encre charbon. Rond et non arrondi,
   c'est la seule forme pleine de la carte, donc la seule à cliquer. */
html[data-fiche="nocturne"] .pcard:not(.prodhero) .add{
  width:36px;height:36px;border-radius:50%;
  background:#cdac6e;color:#17171a;
  box-shadow:0 2px 12px rgba(205,172,110,.26)}
/* L'étiquette ne prend PAS l'or : elle le disputerait au prix et au
   bouton, les deux seules choses qui doivent briller. Un pan translucide
   cerné d'un filet suffit à la faire lire. */
html[data-fiche="nocturne"] .pcard:not(.prodhero) .flag{
  background:rgba(244,239,228,.09);color:#ece7dc;
  border:1px solid rgba(205,172,110,.26);border-radius:9px;
  font-weight:600;letter-spacing:.01em}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .flag.soft{
  background:#cdac6e;color:#17171a;border-color:transparent}
html[data-fiche="nocturne"] .pcard:not(.prodhero) .flag.out{
  background:rgba(244,239,228,.06);color:#8e8b92;border-color:rgba(244,239,228,.12)}

/* ── LE RACCORD AVEC LE BAS DE LA PAGE ────────────────────────────────
   Le liseré d'or de l'horizon, repris sous les titres de section : c'est
   lui qui rattache la page défilée au décor resté en haut. Un filet de
   1 px, dégradé, jamais une barre : le design tient à ce que rien ne soit
   franc sauf la lumière. */
html[data-fiche="nocturne"] body.page-produit .acc-t::after{content:'';display:block;
  width:54px;height:1px;margin-top:8px;
  background:linear-gradient(90deg,#cdac6e,rgba(205,172,110,0))}
/* Les barres de notation gardaient l'or du thème alors que tout le reste
   de la page a pris celui du design : deux ors voisins côte à côte se
   voient. Elles suivent désormais l'accent, et les étoiles sa variante
   claire, seule lisible sur le charbon. */
html[data-fiche="nocturne"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="nocturne"] .rate-pick button.on{color:var(--d-acc-d)}
/* Les pastilles de taille du gabarit : product.js les dessine sans rayon,
   et un angle vif jure avec tout le reste. Le rayon est posé ici, la
   couleur reste celle que le gabarit a mise sous elles (currentColor). */
html[data-fiche="nocturne"] .fp-maq [data-fp="options"]>span{border-radius:99px}

/* ══════════════════════════════════════════════════════════════════════
   KRAFT ARTISAN : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/kraft.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous, quantité, accordéons, avis, « vous aimerez
   aussi », appartient à la page et pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   AUCUNE TEINTE N'EST INVENTÉE : #d4b998 (le papier) et #b9946e (la
   planche) sont relevées au pixel sur la photo du décor, puis éclaircies
   jusqu'à ce que l'encre brune y passe le seuil de lisibilité. Mesuré sur
   --d-fond : encre 12,2:1, encre secondaire 7,2:1, encre discrète 4,6:1,
   accent 4,8:1. Un kraft plus fidèle serait plus joli et illisible.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   papier devient la surface, le cuivre de l'encre devient l'accent.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="kraft"]{
  --d-fond:#f4e9d2; --d-fond2:#e9dcbe;
  --d-carte:#faf3e5; --d-carte2:#f4ead6;
  --d-encre:#33241a; --d-encre2:#5c4634; --d-encre3:#7a634c;
  --d-filet:#ddc9a6; --d-filet2:#c9ac7c;
  --d-acc:#8a5a2b; --d-acc-d:#6d4520; --d-acc-l:#f0e1c7;
  --d-fort:#3d2b1d;
  /* LA POLICE FAIT AUTANT QUE LA COULEUR ICI. Sans `--d-titre`, le panier
     et le compte repassaient en Palatino alors que la fiche est en
     empattements carrés : on changeait d'atelier en changeant de page.
     Rockwell est là partout où Office est installé, Roboto Slab sur
     Android, et Georgia tient la ligne en dernier recours (ses
     empattements s'épaississent en gras). Aucune police à télécharger. */
  --d-titre:Rockwell,"Rockwell Nova","Roboto Slab","Bitstream Vera Serif","Noto Serif",Georgia,serif;
  --d-titre-gras:700; --d-titre-chasse:-.012em;
  --d-prix:Rockwell,"Rockwell Nova","Roboto Slab","Bitstream Vera Serif","Noto Serif",Georgia,serif;
  --d-prix-gras:700;
  /* Le bouton de la page reprend la plaque encrée du gabarit : coins
     presque droits et décalage d'ombre, comme un tampon qu'on appuie. */
  --d-btn:#3d2b1d; --d-btn-encre:#f6edda; --d-r-btn:5px;
  --d-btn-ombre:0 3px 0 rgba(61,43,29,.32);
  --d-puce:#f4ead6; --d-r-puce:4px}

/* Le bord perforé d'une étiquette de papier, repris en filet sous les
   titres de section : c'est ce qui raccorde le bas de la page au décor. */
html[data-fiche="kraft"] body.page-produit .acc-t{letter-spacing:.01em}
html[data-fiche="kraft"] body.page-produit .acc-t::after{content:'';display:block;
  width:58px;height:0;margin-top:9px;border-top:2px dashed var(--d-acc)}
/* Les barres de notation et les étoiles gardaient l'or du thème alors que
   toute la page est passée au brun : deux chaudes voisines mais
   étrangères, juste à côté l'une de l'autre. */
html[data-fiche="kraft"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="kraft"] .rate-pick button.on{color:var(--d-acc)}

/* L'ombre de l'article, portée par la photo elle-même : posée sur le
   cadre, elle aurait bavé sur les deux flèches de galerie que product.js
   accroche au même endroit. Elle est brun-bois et pas grise, parce
   qu'elle tombe sur du chêne et pas sur du béton. */
html[data-fiche="kraft"] [data-fp="photo"] img{
  filter:drop-shadow(0 20px 20px rgba(56,34,14,.46))}

/* ── LA CARTE DU CATALOGUE : UNE ÉTIQUETTE DE KRAFT ────────────────────
   Elle doit appartenir au même monde que la fiche, donc elle est EN
   PAPIER et pas sur du papier : fond kraft plus dense que la page,
   fibres, grain, un bord net et une ligne perforée au-dessus du prix,
   comme un talon qu'on détache.

   Le grain est un SVG en `data:` (feTurbulence désaturée) et pas la photo
   du décor : la photo aurait amené la planche de bois, la ficelle et le
   tampon anglais dans chaque vignette, et la même image recadrée trente
   fois de suite. Une seule URL, donc un seul décodage pour tout le
   catalogue, et il se répète proprement à n'importe quelle taille.

   Le kraft de la carte (#d8c199) est volontairement plus SOMBRE que la
   toile : c'est ce qui la détache. Il est aussi le plancher de lisibilité
   du nom en cuivre foncé, mesuré à 4,8:1 ; l'assombrir davantage pour
   mieux la détacher ferait passer le nom sous le seuil. */
html[data-fiche="kraft"] .pcard:not(.prodhero){
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='kg'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23kg)' opacity='.17'/%3E%3C/svg%3E") 0 0/140px 140px repeat,
    repeating-linear-gradient(96deg, rgba(116,84,46,.055) 0 1px, rgba(0,0,0,0) 1px 5px),
    #d8c199;
  border:1px solid #b5945f; border-radius:14px; padding:12px;
  color:var(--d-encre);
  box-shadow:0 2px 0 rgba(74,53,36,.10), 0 12px 22px -16px rgba(52,35,18,.55)}
/* Le visuel est posé dans une FENÊTRE de papier clair, comme l'étiquette
   collée sur un sachet : c'est elle qui sépare l'article du kraft, sinon
   un produit brun disparaissait dans son propre fond. */
html[data-fiche="kraft"] .pcard:not(.prodhero) .thumb{
  background:#f6eeda; border-radius:10px;
  box-shadow:inset 0 0 0 1px rgba(120,90,55,.24)}
html[data-fiche="kraft"] .pcard:not(.prodhero) .name{
  font-family:var(--d-titre); font-size:16px; font-weight:700;
  letter-spacing:-.012em; color:var(--d-acc-d);
  /* line-height ET min-height ensemble : la règle de base réserve deux
     lignes à 1.25em, changer l'une sans l'autre décalait les prix d'une
     carte à l'autre dans la même rangée. */
  line-height:1.22; min-height:calc(2 * 1.22em)}
html[data-fiche="kraft"] .pcard:not(.prodhero) .cat{color:#5d4a37; font-size:11.5px}
/* La ligne perforée du talon à détacher : elle sépare le prix du reste
   sans ajouter un élément, et c'est le même geste que l'étiquette des
   repères sur la fiche. */
html[data-fiche="kraft"] .pcard:not(.prodhero) .foot{
  border-top:1px dashed rgba(109,69,32,.42); padding-top:9px; margin-top:auto}
html[data-fiche="kraft"] .pcard:not(.prodhero) .price{
  font-family:var(--d-prix); font-size:16px; font-weight:700; color:#2e2015}
/* Le bouton d'ajout redevient un vrai jeton rond d'encre brune : le carré
   arrondi du thème se confondait avec l'étiquette du haut. */
html[data-fiche="kraft"] .pcard:not(.prodhero) .add{
  width:38px; height:38px; border-radius:50%;
  background:#3d2b1d; color:#f6edda}
html[data-fiche="kraft"] .pcard:not(.prodhero) .flag{
  top:14px; left:14px; padding:5px 11px; border-radius:7px;
  font-family:var(--d-titre); font-size:11px; font-weight:700;
  letter-spacing:.02em; background:#3d2b1d; color:#f6edda}
/* « Épuisé » ne doit PAS porter la même encre franche que « Nouveau » :
   la règle ci-dessus est plus spécifique que `.flag.out` du thème et le
   repeignait en brun plein, donnant à un article indisponible l'air d'une
   nouveauté. Mesuré à 4,6:1, donc lisible tout en restant en retrait. */
html[data-fiche="kraft"] .pcard:not(.prodhero) .flag.out{background:#7a634c; color:#f3e7d3}
/* Le cœur perd sa pastille blanche : un disque blanc sur du kraft est la
   seule chose de la carte qui ne soit pas du papier. Le trait d'encre
   suffit, et l'état « aimé » reste peint en rose par la règle de base. */
html[data-fiche="kraft"] .pcard:not(.prodhero) .fav{background:transparent; box-shadow:none}
html[data-fiche="kraft"] .pcard:not(.prodhero) .fav svg{stroke:#4a3524}

/* ══════════════════════════════════════════════════════════════════════
   JOAILLERIE IVOIRE ·  LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/joaillerie.html) ne couvre que le haut de la
   fiche. Tout ce qui vient dessous, quantité, accordéons, avis, « vous
   aimerez aussi », appartient à la page et pas à la maquette. Sans
   palette, ces blocs gardaient les couleurs du thème et la fiche se
   coupait en deux au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line.

   LES TEINTES SONT RELEVÉES SUR LE DÉCOR, pas inventées : l'ivoire de la
   tablette (#faf4ec), le champagne du mur (#efe3ce), l'or du filet
   (#b08d4e). Le décor est clair, donc l'encre est un brun presque noir.
   L'accent est un or MOYEN : encreSurAccent() compare les deux encres
   possibles et pose d'elle-même le brun sur les aplats dorés, où le
   blanc ne donnerait que 3,4 de contraste.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="joaillerie"]{
  --d-fond:#faf4ec; --d-fond2:#efe3ce;
  --d-carte:#fdfaf3; --d-carte2:#f7eee0;
  --d-encre:#211b14; --d-encre2:#5b4f41;
  /* Tertiaire assombrie de #8a7b66, qui ne donnait que 4,0:1 sur
     l'ivoire de la carte pour un texte de 11 px. #786b59 tient 5,0:1
     sur --d-carte, 4,8:1 sur --d-fond et 4,5:1 sur --d-carte2. */
  --d-encre3:#786b59;
  --d-filet:#e6d9c2; --d-filet2:#d6c29f;
  --d-acc:#a8854a; --d-acc-d:#806230; --d-acc-l:#f5eada;
  --d-fort:#806230;
  /* La POLICE DU NOM voyage avec la palette : le bloc
     `html[data-socle] body.page-boutique` la distribue au panier, aux
     favoris et au compte. Sans elle on passait d'une fiche en serif à un
     panier en sans-serif, au milieu du même achat. */
  --d-titre:'Cormorant Garamond', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  /* L'or moyen sert aussi de couleur de TEXTE dans les cartes du
     catalogue (`--acc:var(--d-acc-texte, var(--d-acc))`). Sur l'ivoire
     d'une carte il ne donne que 3,3 : on y substitue l'or foncé, à 5,2,
     et l'accent d'origine reste pour les aplats. */
  --d-acc-texte:#806230;
  /* L'encre lisible SUR l'or à l'intérieur d'une carte : là, --sur-acc
     n'est pas celui que encreSurAccent() a calculé pour la page. */
  --d-sur-acc:#211b14}

/* L'ombre de l'article, portée par la PHOTO elle-même : sur le cadre,
   elle aurait bavé sur les deux flèches de galerie que product.js
   accroche au même endroit. Deux ombres et non une : la large fait la
   lumière de la vitrine, la courte fait le point de contact avec la
   tablette. Chaudes et discrètes, jamais noires : une bague de trois
   grammes ne porte pas l'ombre d'un ballon. */
html[data-fiche="joaillerie"] [data-fp="photo"] img{
  filter:drop-shadow(0 16px 18px rgba(120,92,48,.26)) drop-shadow(0 3px 5px rgba(90,68,34,.18))}

/* ══ LA CARTE DU CATALOGUE ═════════════════════════════════════════════
   Elle appartient au même monde que la fiche : ivoire, angles francs,
   filet d'or sous la vignette, nom en serif centré.

   `:not(.prodhero)` n'est pas un ornement. Le bloc générique
   `html[data-socle] .pcard:not(.prodhero)` pèse (0,3,1) ; un simple
   `html[data-fiche="joaillerie"] .pcard` ne pèse que (0,2,1) et se
   ferait écraser. Il écarte au passage la carte-héros de la fiche
   article, qui n'est pas une vignette de catalogue.
   ═════════════════════════════════════════════════════════════════════ */
html[data-fiche="joaillerie"] .pcard:not(.prodhero){
  background:#fdfaf3;
  border:1px solid #efe4d0;
  /* Trois pixels et non vingt : une maison de joaillerie encadre, elle
     n'arrondit pas. C'est ce qui fait lire la carte comme un écrin. */
  border-radius:3px;
  box-shadow:0 10px 26px rgba(120,92,48,.10), 0 1px 2px rgba(120,92,48,.07);
  padding:12px 12px 10px;
  text-align:center}
@media(hover:hover){
  html[data-fiche="joaillerie"] .pcard:not(.prodhero):hover{
    border-color:#dcc9a5;
    box-shadow:0 16px 34px rgba(120,92,48,.16)}
}
/* LE FILET D'OR SOUS LA VIGNETTE : la citation exacte du décor, le même
   trait que celui qui sépare le mur de la tablette. Il tient lieu de
   séparateur, d'où l'absence de tout autre trait au-dessus du nom. */
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .thumb{
  background:#f6f2ea;
  border-radius:2px;
  border-bottom:3px solid #c9a87f;
  box-shadow:none}
/* Le nom dans la police de la fiche : c'est lui qui raccorde le
   catalogue au décor, avant même la couleur. Le petit œil du Cormorant
   impose 19 px là où le sans-serif se contentait de 14. */
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .name{
  font-family:'Cormorant Garamond', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  font-size:19px; font-weight:600; letter-spacing:.005em; line-height:1.22;
  margin:12px 2px 3px;
  /* Le plancher suit le nouveau corps : gardé sur l'ancien, une carte au
     nom court se tassait et les prix de la rangée ne s'alignaient plus. */
  min-height:calc(2 * 1.22em)}
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .cat{
  font-size:11px; letter-spacing:.06em; color:#786b59}
/* Un second filet, plus pâle, pour détacher le prix : sans lui, le pied
   de carte flottait au milieu de l'ivoire. */
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .foot{
  border-top:1px solid #ece0ca; padding:10px 2px 0; margin-top:auto}
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .price{
  font-size:15px; font-weight:600; letter-spacing:.005em; color:#211b14}
/* Le « + » est un CERCLE VIDE cerné d'or, pas une pastille pleine : sur
   une carte aussi claire, un aplat doré devient la seule tache de la
   rangée et attire l'œil avant l'article. Il ne s'emplit qu'au survol,
   quand le geste est déjà engagé. */
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .add{
  background:transparent; color:#806230;
  border:1px solid #c0a071; border-radius:50%;
  box-shadow:none}
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .add:hover{
  background:#806230; color:#fdfaf3; border-color:#806230}
/* Le cœur des favoris perd sa pastille blanche, qui faisait un rond de
   papier collé sur l'écrin, et prend l'or du reste. */
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .fav{
  background:transparent; box-shadow:none}
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .fav svg{stroke:#a8854a}
/* LE BANDEAU D'ÉTAT en cartouche champagne à encre brune. En aplat doré
   à encre blanche, « Nouveau » ne donnait que 3,4 de contraste et se
   lisait comme une tache. Petites capitales, comme le rayon de la
   fiche : c'est la même voix. */
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .flag{
  background:#e6d3b5; color:#3a2e1d;
  border-radius:2px; font-size:9.5px; font-weight:700;
  letter-spacing:.1em; text-transform:uppercase}
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .flag.soft{background:#efe4d0; color:#3a2e1d}
html[data-fiche="joaillerie"] .pcard:not(.prodhero) .flag.out{background:#d8cdbc; color:#3a2e1d}

/* ══════════════════════════════════════════════════════════════════════
   GRILLE TECHNIQUE : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/technique.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous (quantité, accordéons, avis, « vous aimerez
   aussi ») appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   blanc d'atelier devient la surface, le bleu électrique devient l'accent,
   et TOUT perd son arrondi : un plan coté n'a pas de coins ronds.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="technique"]{
  --d-fond:#f1f2f4; --d-fond2:#e4e6ea;
  --d-carte:#ffffff; --d-carte2:#f4f6f8;
  --d-encre:#0e1116; --d-encre2:#474d57;
  /* Tertiaire assombrie de #7a818c : le rayon de la carte l'écrit en
     10,5 px capitales espacées, et #7a818c ne donnait que 3,9:1 sur la
     carte blanche, 3,5:1 sur la page. #696f79 tient 5,1:1 sur le blanc,
     4,7:1 sur --d-carte2 et 4,5:1 sur --d-fond, les trois surfaces où
     le socle reporte cette encre en --ink-3. */
  --d-encre3:#696f79;
  --d-filet:#dcdfe4; --d-filet2:#c2c7d0;
  --d-acc:#1430ee; --d-acc-d:#0d1fa8; --d-acc-l:#e7eaff;
  /* Le bleu sert AUSSI d'aplat : bouton d'achat, pastille « + » des
     cartes. 7,8:1 sous du blanc, il porte du texte sans réserve. */
  --d-fort:#1430ee;
  --d-acc-texte:#1430ee; --d-sur-acc:#ffffff; --d-sur-fort:#ffffff; --d-btn-encre:#ffffff;

  /* L'ANGLE DROIT PARTOUT. Le socle arrondit tout par défaut (12 à 999 px) ;
     ici chaque coin coupé net est ce qui fait lire « plan » plutôt que
     « application ». Seule la pastille « + » de la carte reste un cercle :
     c'est le signe de l'ajout, pas un ornement. */
  --d-r:2px; --d-r-min:0; --d-r-btn:0; --d-r-puce:0; --d-r-carte:2px;
  --d-r-btn-carte:50%; --d-r-fav:0;

  /* Deux familles, deux emplois. Le grotesque du système porte les titres,
     très gras et serré ; les CHIFFRES passent en condensé : c'est la
     colonne de cotes d'un plan, et un prix y tient en moitié moins de
     place à corps égal. « Arial Narrow » est présent sur pratiquement tous
     les macOS et Windows : le repli n'est là que pour les autres. */
  --d-titre:system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --d-titre-gras:800; --d-titre-chasse:-.035em; --d-titre-casse:none;
  --d-prix:"Archivo Narrow","Roboto Condensed","Helvetica Neue Condensed","Liberation Sans Narrow","Arial Narrow",system-ui,sans-serif;
  --d-prix-gras:700;

  /* La carte du catalogue, réglée par les crochets du socle plutôt que par
     des `!important` : `html[data-socle] .pcard:not(.prodhero)` est plus
     spécifique que `html[data-fiche="…"] .pcard`, une règle écrite ici
     n'aurait pas repris son fond ni sa bordure. */
  --d-nom-police:"Archivo Narrow","Roboto Condensed","Helvetica Neue Condensed","Liberation Sans Narrow","Arial Narrow",system-ui,sans-serif;
  --d-nom-gras:700; --d-nom-casse:uppercase;
  --d-carte-bordure:1px solid #c9ced6; --d-carte-ombre:none;
  --d-vignette:#f4f6f8; --d-fav:transparent;
  /* La grille du décor, poursuivie À TRAVERS la carte : c'est ce qui
     raccorde le catalogue à la fiche. Pas de `background-size` à prévoir,
     les arrêts sont en pixels. */
  --d-carte-fond:
    repeating-linear-gradient(90deg, rgba(14,17,22,.055) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(180deg, rgba(14,17,22,.055) 0 1px, transparent 1px 34px),
    #ffffff}

/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit. Deux
   passes (une ombre large pour le volume, une serrée pour le contact au
   sol) et un gris BLEUTÉ. Sur un plan blanc, une ombre neutre paraît
   sale, celle-ci paraît éclairée. */
html[data-fiche="technique"] [data-fp="photo"] img{
  filter:drop-shadow(0 18px 18px rgba(14,22,48,.20)) drop-shadow(0 2px 3px rgba(14,22,48,.16))}

/* ── LA CARTE DU CATALOGUE ─────────────────────────────────────────────
   Même monde que la fiche : un feuillet quadrillé, un titre condensé en
   capitales, un prix bleu, et pas une ombre. Ce que les variables
   ci-dessus ne savent pas dire est écrit ici. */
/* Le nom : deux lignes maximum, comme partout, mais recalées sur
   l'interligne serré du condensé. Sans ce `min-height`, les prix d'une
   rangée ne s'alignaient plus d'une carte à l'autre. */
html[data-fiche="technique"] .pcard .name{
  font-size:17px;line-height:1.15;letter-spacing:.005em;min-height:calc(2 * 1.15em)}
/* Le rayon reprend la légende du cartouche : chasse fixe, capitales
   espacées. C'est le même mot, écrit de la même main que sur la fiche. */
html[data-fiche="technique"] .pcard .cat{
  font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--d-encre3)}
/* Le prix est la cote de la pièce : condensé, bleu, plus gros que le nom. */
html[data-fiche="technique"] .pcard .price{
  font-family:"Archivo Narrow","Roboto Condensed","Helvetica Neue Condensed","Liberation Sans Narrow","Arial Narrow",system-ui,sans-serif;
  font-size:20px;font-weight:700;letter-spacing:0;color:var(--d-acc)}
/* La vignette : un caisson plein, à l'angle droit, et une ombre d'objet
   GRISE. Celle du socle est brune (rgba(120,70,40,…)) et, sur un plan blanc,
   elle jaunit tout. `:not(.prodhero)` n'est pas une coquetterie : sans lui
   la règle du socle, plus spécifique, reprend la main. */
html[data-fiche="technique"] .pcard:not(.prodhero) .thumb{
  border:1px solid var(--d-filet)}
html[data-fiche="technique"] .pcard .thumb svg,
html[data-fiche="technique"] .pcard .thumb .photo-frame{
  filter:drop-shadow(0 10px 12px rgba(14,22,48,.16))}
/* La pastille d'ajout : le seul cercle de la carte, en aplat bleu. */
html[data-fiche="technique"] .pcard:not(.prodhero) .add{
  background:var(--d-acc);border-radius:50%;box-shadow:none}
/* Le cœur des favoris perd son jeton blanc et son ombre : sur un feuillet,
   il n'y a rien à détourer. */
html[data-fiche="technique"] .pcard:not(.prodhero) .fav{
  background:transparent;box-shadow:none;border-radius:0}
/* L'étiquette n'est pas une gommette : c'est un tampon. Rectangle à filet
   fin, encre noire, capitales espacées, jamais une pastille de couleur. */
html[data-fiche="technique"] .pcard .flag{
  top:14px;left:14px;padding:5px 10px;border-radius:0;
  background:var(--d-carte);color:var(--d-encre);border:1px solid var(--d-encre);
  font-family:ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size:10px;font-weight:500;letter-spacing:.08em;text-transform:uppercase}
html[data-fiche="technique"] .pcard .flag.out{
  color:var(--d-encre3);border-color:var(--d-filet2)}
/* Au survol, la carte ne saute pas et ne prend pas d'ombre : son filet
   passe au bleu, comme une pièce sélectionnée dans un plan. */
@media(hover:hover){
  html[data-fiche="technique"] .pcard:not(.prodhero):hover{
    transform:none;box-shadow:none;border-color:var(--d-acc)}
}

/* ── LES REPÈRES CHIFFRÉS, EN CELLULES DE CARTOUCHE ────────────────────
   Ces cellules sont créées par product.js : le gabarit ne peut pas les
   styler en ligne, il n'y a que cette règle pour poser les séparateurs.
   `min-width:0` en plus de `flex:1` : sans lui, une valeur longue élargit
   sa cellule et le cartouche déborde de la carte sur un téléphone. */
html[data-fiche="technique"] [data-fp="reperes"]>div{
  flex:1 1 0;min-width:0;padding:11px 14px;border-left:1.5px solid var(--d-filet2)}
html[data-fiche="technique"] [data-fp="reperes"]>div:first-child{border-left:0}
html[data-fiche="technique"] [data-fp="reperes"]>div>div:last-child{
  font-family:"Archivo Narrow","Roboto Condensed","Helvetica Neue Condensed","Liberation Sans Narrow","Arial Narrow",system-ui,sans-serif;
  line-height:1.1}

/* ══════════════════════════════════════════════════════════════════════
   PASTEL DOUX : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/pastel.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous, quantité, accordéons, avis, « vous aimerez
   aussi », appartient à la page et pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. La
   crème du décor devient la surface, le rose poudré densifié devient
   l'accent ; la sauge reste réservée aux coussins du gabarit, elle est
   trop claire pour porter quoi que ce soit qui se lit.

   Un pastel n'excuse pas un texte pâle : chaque encre est mesurée sur les
   deux surfaces du design. #3b2a27 donne 12,9:1 sur la carte crème et
   10,8:1 sur la carte rose du catalogue, #b8506f porte du blanc à 4,8:1,
   #ad4162 à 5,7:1, et la sauge du rayon a été descendue à #54704f pour
   tenir 5,2:1 au lieu des 3:1 de la sauge du décor.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="pastel"]{
  --d-fond:#f8ece6; --d-fond2:#f1ddd7;
  --d-carte:#fdf8f3; --d-carte2:#f8ece6;
  --d-encre:#3b2a27; --d-encre2:#6d5551; --d-encre3:#7d6360;
  --d-filet:#efdcd5; --d-filet2:#e0c6be;
  --d-acc:#b8506f; --d-acc-d:#984055; --d-acc-l:#fbe7ea;
  --d-fort:#ad4162}
/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit. Rose
   et très étalée, jamais grise : une ombre neutre suffisait à salir le
   coussin sauge sur lequel l'article est posé. */
html[data-fiche="pastel"] [data-fp="photo"] img{
  filter:drop-shadow(0 20px 26px rgba(150,104,104,.34))}
/* Les pastilles de taille sont dessinées par product.js sans arrondi : des
   rectangles au milieu d'une composition qui n'a que des cercles. Elles ne
   portent pas de `border-radius` en style en ligne, une règle suffit donc
   à les arrondir sans rien changer au script. */
html[data-fiche="pastel"] [data-fp="options"] span{border-radius:999px}

/* ── LA CARTE DU CATALOGUE ──
   Elle appartient au même monde que la fiche, mais elle en inverse les
   deux surfaces : la fiche pose du crème sur du rose, la carte pose du
   rose sur la toile crème. C'est ce qui la détache du fond de page sans
   lui ajouter ni bordure ni filet, que le design ne supporte pas.

   `:not(.prodhero)` n'est pas décoratif : la règle générique
   `html[data-socle] .pcard:not(.prodhero)` a exactement la même
   spécificité. Sans lui, la nôtre passerait dessous et la carte
   reprendrait le fond crème de `--d-carte`. */
html[data-fiche="pastel"] .pcard:not(.prodhero){
  /* Le rose de la carte est plus foncé que la crème : l'accent servi en
     TEXTE (la note en étoiles) y tombait à 3,8:1. On sert donc la variante
     densifiée aux deux, l'accent d'origine restant pour les aplats. */
  --acc:#984055; --acc-d:#984055;
  background:#fadfe0;
  border:1px solid rgba(255,255,255,.62);
  border-radius:34px;
  padding:12px;
  box-shadow:0 18px 34px -20px rgba(150,88,96,.50)}
@media(hover:hover){
  html[data-fiche="pastel"] .pcard:not(.prodhero):hover{
    box-shadow:0 26px 44px -22px rgba(150,88,96,.58)}}
/* La vignette est un rose à peine plus soutenu que la carte : un creux, pas
   un cadre. Un aplat blanc y aurait fait un trou au milieu du pastel. */
html[data-fiche="pastel"] .pcard:not(.prodhero) .thumb{
  background:#f6d5d8;border-radius:26px}
html[data-fiche="pastel"] .pcard:not(.prodhero) .name{
  font-weight:750;letter-spacing:-.01em;color:#3b2a27}
/* Le rayon prend l'encre SECONDAIRE et non la tertiaire : sur le rose de la
   carte, #7d6360 ne donne que 4,4:1 pour un texte de 11,5 px. */
html[data-fiche="pastel"] .pcard:not(.prodhero) .cat{color:#6d5551}
html[data-fiche="pastel"] .pcard:not(.prodhero) .price{
  font-weight:800;color:#3b2a27}
/* L'ancien prix barré, oublié dans la passe qui a corrigé .cat juste
   au-dessus : #8a6f6b ne donnait que 3,7:1 sur le rose de la carte pour
   un texte de 12 px. #79615e tient 4,5:1. */
html[data-fiche="pastel"] .pcard:not(.prodhero) .price .old{color:#79615e}
/* Un vrai cercle, plus grand que le bouton carré d'origine : c'est la seule
   forme pleine de la carte, elle tient lieu de signature. */
html[data-fiche="pastel"] .pcard:not(.prodhero) .add{
  width:38px;height:38px;border-radius:50%;
  background:#ad4162;color:#ffffff;
  box-shadow:0 10px 18px -8px rgba(173,65,98,.66)}
/* L'étiquette est blanche et non teintée : posée sur le rose de la carte,
   une pastille rose sur rose ne se voyait plus. */
html[data-fiche="pastel"] .pcard:not(.prodhero) .flag{
  top:14px;left:14px;padding:5px 12px;border-radius:999px;
  background:#ffffff;color:#3b2a27;font-weight:750;
  box-shadow:0 6px 12px -6px rgba(150,88,96,.45)}
html[data-fiche="pastel"] .pcard:not(.prodhero) .flag.soft{
  background:#ffffff;color:#3b2a27}
/* « Épuisé » garde un fond plein : c'est la seule étiquette qui doit
   arrêter l'œil, et l'encre tertiaire porte du blanc à 5,5:1. */
html[data-fiche="pastel"] .pcard:not(.prodhero) .flag.out{
  background:#7d6360;color:#ffffff}
html[data-fiche="pastel"] .pcard:not(.prodhero) .fav{
  background:rgba(255,255,255,.62)}
html[data-fiche="pastel"] .pcard:not(.prodhero) .fav svg{stroke:#ad4162}

/* ══════════════════════════════════════════════════════════════════════
   MONOCHROME — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/mode.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous — quantité, accordéons, avis, « vous aimerez
   aussi » — appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux
   au millimètre où le gabarit s'arrête.

   Ici la difficulté n'est pas la couleur mais son ABSENCE : il n'y a
   qu'un gris de studio et un noir. L'accent EST le noir — un design
   monochrome qui garderait le bleu du thème sur ses boutons ne serait
   plus monochrome. Les gris sont strictement neutres, relevés sur le
   décor lui-même : mur #efefef, sol #f8f9f8, ombre portée #e1e1e1.
   Aucune teinte chaude ne doit s'y glisser, elle se verrait aussitôt.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="mode"]{
  --d-fond:#f0f0f0; --d-fond2:#e2e2e2;
  --d-carte:#ffffff; --d-carte2:#f7f7f7;
  /* #6a6a6a et pas plus pâle : c'est le gris le plus clair qui tienne
     encore 4,5:1 sur le fond du design, seuil des textes secondaires. */
  --d-encre:#0b0b0b; --d-encre2:#3b3b3b; --d-encre3:#6a6a6a;
  --d-filet:#dcdcdc; --d-filet2:#c4c4c4;
  --d-acc:#0b0b0b; --d-acc-d:#000000; --d-acc-l:#e8e8e8;
  --d-fort:#0b0b0b}

/* L'ombre de l'article, portée par la photo elle-même : posée sur le
   cadre, elle aurait bavé sur les deux flèches de galerie que product.js
   accroche au même endroit. Décalée vers la droite parce que le décor
   est éclairé de haut à gauche — une ombre centrée sous un article posé
   sur CE sol-là sonnerait faux à côté de l'ombre dure de l'image. */
html[data-fiche="mode"] [data-fp="photo"] img{
  filter:drop-shadow(16px 18px 16px rgba(11,11,11,.20))}

/* ── LA CARTE DU CATALOGUE, DANS LE MÊME MONDE QUE LA FICHE ───────────
   Même vocabulaire que le gabarit : angles vifs, un trait noir, un nom
   en condensée géante. Rien n'est arrondi sauf le bouton d'ajout, seule
   forme ronde du design — et c'est pour ça qu'on le voit. */
html[data-fiche="mode"] .pcard:not(.prodhero){
  background:var(--d-carte); border:0; border-radius:0;
  box-shadow:0 1px 2px rgba(11,11,11,.06); padding:10px 10px 14px}
html[data-fiche="mode"] .pcard:not(.prodhero) .thumb{
  background:#f1f1f1; border-radius:0}
/* L'ombre des visuels était teintée de brun (rgba(120,70,40,.18)) : une
   COULEUR, dans un design qui n'en a aucune. Repassée en gris neutre. */
html[data-fiche="mode"] .pcard:not(.prodhero) .thumb svg,
html[data-fiche="mode"] .pcard:not(.prodhero) .thumb .photo-frame{
  filter:drop-shadow(0 12px 16px rgba(11,11,11,.14))}
/* LE NOM EST L'IMAGE DE LA CARTE : condensé, capitales, presque aussi
   haut que la vignette. Le plafond de deux lignes vient de la règle de
   base ; on ne redescend que le PLANCHER, sinon une interligne de 0,9
   laissait un trou sous les noms courts et les prix de la rangée ne
   s'alignaient plus. Aucune police n'est téléchargée : on empile les
   condensées déjà présentes sur les systèmes, et `font-stretch` rattrape
   celles qui rangent leur condensée en variante plutôt qu'en famille. */
html[data-fiche="mode"] .pcard:not(.prodhero) .name{
  font-family:'Archivo Narrow','Roboto Condensed','Helvetica Neue Condensed','Liberation Sans Narrow','Arial Narrow','Helvetica Neue',system-ui,sans-serif;
  font-stretch:condensed; font-size:27px; font-weight:800; line-height:.9;
  letter-spacing:-.01em; text-transform:uppercase; color:var(--d-encre);
  margin:11px 2px 3px; min-height:calc(2 * .9em)}
html[data-fiche="mode"] .pcard:not(.prodhero) .cat{
  font-size:12px; color:var(--d-encre3); margin:0 2px 2px}
/* Le trait noir du décor, repris pour séparer le pied : c'est le seul
   ornement de la carte, et il la raccorde à la fiche. */
html[data-fiche="mode"] .pcard:not(.prodhero) .foot{
  border-top:1px solid var(--d-encre); padding:12px 2px 0}
/* Le prix reste dans la police du système, en graisse moyenne : deux
   condensées géantes l'une sous l'autre se disputeraient la carte. */
html[data-fiche="mode"] .pcard:not(.prodhero) .foot .price{
  font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  font-size:17px; font-weight:500; letter-spacing:-.005em; color:var(--d-encre)}
html[data-fiche="mode"] .pcard:not(.prodhero) .add{
  width:40px; height:40px; border-radius:50%;
  background:var(--d-encre); color:#ffffff}
/* Les étiquettes perdent leur pastille arrondie. « Nouveau » et
   « Best-seller » passent en blanc sur le visuel — avec un filet, sinon
   elles disparaissent sur la photo d'un article blanc, ce qui arrive
   sans arrêt en mode. La promotion garde le noir plein : c'est
   l'information la plus forte de la carte. */
html[data-fiche="mode"] .pcard:not(.prodhero) .flag{
  top:18px; left:18px; border-radius:0; padding:5px 10px;
  font-size:11px; font-weight:600; letter-spacing:0;
  background:var(--d-encre); color:#ffffff; border:1px solid var(--d-encre)}
html[data-fiche="mode"] .pcard:not(.prodhero) .flag.soft{
  background:#ffffff; color:var(--d-encre); border-color:var(--d-filet2)}
html[data-fiche="mode"] .pcard:not(.prodhero) .flag.out{
  background:var(--d-encre3); color:#ffffff; border-color:var(--d-encre3)}
/* Le cœur perd sa pastille blanche (la carte de référence n'en a pas)
   mais garde un halo : posé nu sur la photo d'un article sombre, il
   s'effaçait purement et simplement. Et il ne devient pas rose quand il
   est retenu — une couleur, encore, dans un design qui n'en a aucune. */
html[data-fiche="mode"] .pcard:not(.prodhero) .fav{
  background:transparent; box-shadow:none}
html[data-fiche="mode"] .pcard:not(.prodhero) .fav svg{
  stroke:var(--d-encre); filter:drop-shadow(0 0 2px rgba(255,255,255,.95))}
html[data-fiche="mode"] .pcard:not(.prodhero) .fav.on svg{
  fill:var(--d-encre); stroke:var(--d-encre)}

/* Les barres et les étoiles de notation gardaient l'or du thème, juste
   à côté de blocs devenus entièrement noirs : la seule tache de couleur
   de la page. Elles suivent l'accent, c'est-à-dire le noir. */
html[data-fiche="mode"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="mode"] .rate-pick button.on{color:var(--d-acc)}

/* ══════════════════════════════════════════════════════════════════════
   MARCHÉ COLORÉ - LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/marche.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous (quantité, accordéons, avis, « vous aimerez
   aussi ») appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   crème du mur devient la surface, la terracotta devient l'accent.

   La terracotta est descendue de #c6593d (la teinte du modèle) à #b94d33 :
   l'ivoire du bouton « Ajouter au panier » n'y tenait que 4,1:1, sous le
   seuil lisible pour un texte de 15 px. Cinq pour cent plus sombre, elle
   est la même à l'oeil et passe à 4,8:1.

   `--d-jaune` ne fait pas partie du contrat des designs à socle : c'est la
   moutarde des aplats, qui n'est JAMAIS une surface de texte et ne peut
   donc se loger ni dans --d-fond ni dans --d-acc sans devenir illisible
   quelque part. Elle est déclarée ici pour que l'étal, la vignette du
   catalogue et le filet des titres citent tous la même valeur.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="marche"]{
  --d-fond:#fdf9f0; --d-fond2:#f6eedb;
  --d-carte:#fffaf4; --d-carte2:#fdf4e6;
  --d-encre:#17130d; --d-encre2:#4a423a; --d-encre3:#7a6f62;
  --d-filet:#e8ddc7; --d-filet2:#d8c9ab;
  --d-acc:#b94d33; --d-acc-d:#9c3e28; --d-acc-l:#f7e2da;
  --d-fort:#b94d33;
  --d-jaune:#d8a512}
/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les deux flèches de galerie que product.js accroche au
   même endroit. Elle est brune et non grise parce qu'elle tombe sur l'étal
   jaune, où un gris neutre vire au vert. */
html[data-fiche="marche"] [data-fp="photo"] img{
  filter:drop-shadow(0 20px 20px rgba(96,54,6,.34))}
/* Les aplats du gabarit, repris sous les titres de section : c'est ce qui
   raccorde le bas de la page au décor du haut. Un bloc trapu et non un
   filet, sinon le design perd sa grammaire dès qu'on quitte la maquette. */
html[data-fiche="marche"] body.page-produit .acc-t{letter-spacing:-.005em}
html[data-fiche="marche"] body.page-produit .acc-t::after{content:'';display:block;
  width:48px;height:9px;margin-top:9px;background:var(--d-jaune)}
/* Les pastilles d'option sont peintes en ligne par product.js, qui ne sait
   poser ni rayon ni respiration : le gabarit leur donne l'encre, cette
   règle leur donne la pilule du modèle. */
html[data-fiche="marche"] [data-fp="options"] span{border-radius:999px;padding:9px 16px}
/* Les barres de notation gardaient l'or du thème alors que tout le reste de
   la page a pris les couleurs du design : deux jaunes voisins mais
   différents, juste à côté d'étoiles déjà passées en terracotta. */
html[data-fiche="marche"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="marche"] .rate-pick button.on{color:var(--d-acc)}

/* ── LA CARTE DU CATALOGUE ─────────────────────────────────────────────
   Même monde que la fiche : un carton ivoire sans bordure, une vignette
   moutarde pleine où l'article est POSÉ (même ombre brune, en plus petit),
   et le prix séparé du nom par un filet, comme la mention du bas de fiche.
   Les étiquettes redeviennent des BLOCS, rayon 8 px au lieu de 99 : le
   design est fait d'aplats francs, pas de bulles. */
html[data-fiche="marche"] .pcard:not(.prodhero){
  background:var(--d-carte);border:0;border-radius:16px;padding:10px 10px 4px;
  box-shadow:0 10px 26px rgba(92,52,6,.10)}
@media(hover:hover){html[data-fiche="marche"] .pcard:not(.prodhero):hover{
  box-shadow:0 16px 34px rgba(92,52,6,.16)}}
html[data-fiche="marche"] .pcard:not(.prodhero) .thumb{
  background:var(--d-jaune);border-radius:12px}
html[data-fiche="marche"] .pcard:not(.prodhero) .thumb svg,
html[data-fiche="marche"] .pcard:not(.prodhero) .thumb .photo-frame{
  filter:drop-shadow(0 12px 16px rgba(92,52,6,.30))}
html[data-fiche="marche"] .pcard:not(.prodhero) .name{
  font-weight:800;font-size:15px;letter-spacing:-.015em;color:var(--d-encre)}
html[data-fiche="marche"] .pcard:not(.prodhero) .cat{color:var(--d-encre3)}
/* `margin-top:auto` n'est PAS redit ici, et c'est voulu : la règle de base
   le pose pour plaquer le pied au bas de la carte, et c'est lui qui aligne
   les prix d'une rangée dont les noms font une ou deux lignes. Le redire en
   valeur fixe décrochait une carte sur deux. */
html[data-fiche="marche"] .pcard:not(.prodhero) .foot{
  border-top:1px solid var(--d-filet);padding:10px 2px 2px}
html[data-fiche="marche"] .pcard:not(.prodhero) .price{
  font-weight:800;font-size:17px;letter-spacing:-.02em;color:var(--d-encre)}
/* Le seul rond du design, comme sur le modèle : il rassemble en un point
   tout ce que la carte a de terracotta. */
html[data-fiche="marche"] .pcard:not(.prodhero) .add{
  width:38px;height:38px;border-radius:50%;background:var(--d-acc);color:#fffaf4}
/* LES TROIS ÉTIQUETTES, redites une par une. La première règle porte sur
   `.flag` tout court et l'emporte sur `.flag.soft` et `.flag.out` de la
   feuille de base : sans les deux suivantes, « Épuisé » et « Nouveau »
   héritaient du fond terracotta de la promo et ne se distinguaient plus. */
html[data-fiche="marche"] .pcard:not(.prodhero) .flag{
  border-radius:8px;padding:5px 10px;font-weight:800;letter-spacing:.01em;
  background:var(--d-acc);color:#fffaf4}
html[data-fiche="marche"] .pcard:not(.prodhero) .flag.soft{
  background:var(--d-carte);color:var(--d-encre);box-shadow:0 2px 8px rgba(92,52,6,.18)}
html[data-fiche="marche"] .pcard:not(.prodhero) .flag.out{
  background:var(--d-encre);color:var(--d-carte)}

/* ══════════════════════════════════════════════════════════════════════
   GOURMAND : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/gourmand.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous, quantité, accordéons, avis, « vous aimerez
   aussi », appartient à la page et non à la maquette. Sans palette, ces
   blocs gardent les couleurs du thème et la fiche se coupe en deux au
   millimètre où le gabarit s'arrête.

   Le parti pris tient en une phrase : le marbre est la surface, un noir
   chaud est l'encre, et l'or n'est qu'un FILET. Il ne devient un aplat
   que sur ce qui se touche, le bouton d'achat et l'étiquette de la carte,
   et c'est alors un or FONCÉ (#856428) : l'or clair du décor ne donne que
   3,6:1 sous du blanc, joli et illisible.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="gourmand"]{
  --d-fond:#f4f1eb; --d-fond2:#e8e3d9;
  --d-carte:#ffffff; --d-carte2:#fbf9f5;
  --d-encre:#1b1815; --d-encre2:#4a433b; --d-encre3:#736a5f;
  --d-filet:#e3ddd0; --d-filet2:#c9ae76;
  --d-acc:#856428; --d-acc-d:#5f4518; --d-acc-l:#f3ead6;
  --d-fort:#856428}

/* L'ombre de l'article est portée par la PHOTO et non par son cadre : un
   filtre posé sur le cadre s'appliquerait aussi aux deux flèches de
   galerie que product.js vient y accrocher. Courte et chaude, celle d'un
   objet posé sur un plan de marbre sous une lumière de vitrine, pas celle
   d'un objet en lévitation. */
html[data-fiche="gourmand"] [data-fp="photo"] img{
  filter:drop-shadow(0 16px 18px rgba(74,56,24,.28))}

/* ── LA CARTE DU CATALOGUE, DU MÊME MONDE QUE LA FICHE ────────────────
   Même grammaire que le gabarit, en plus petit : une surface blanche
   cernée d'un filet d'or, un nom en serif à fort contraste, un filet qui
   sépare le pied, et l'or réservé à l'étiquette et au bouton. Sans elle,
   le client passe d'un catalogue au thème de la boutique à une fiche en
   marbre : deux boutiques pour un seul commerçant. */
html[data-fiche="gourmand"] .pcard:not(.prodhero){
  background:var(--d-carte);
  border:1px solid rgba(133,100,40,.32);
  border-radius:18px; padding:12px;
  box-shadow:0 10px 26px rgba(74,56,24,.10)}
@media(hover:hover){
  html[data-fiche="gourmand"] .pcard:not(.prodhero):hover{box-shadow:0 16px 34px rgba(74,56,24,.16)}}
html[data-fiche="gourmand"] .pcard:not(.prodhero) .thumb{
  border-radius:12px; background:var(--d-carte2)}
/* Le serif ne descend pas en dessous de sa coupe grasse ici : à 16 px, un
   Didot en 400 devient un trait de crayon sur fond blanc. `min-height`
   est redonnée parce que la règle d'origine réserve deux lignes en `em`
   et que l'interligne change juste au-dessus. */
html[data-fiche="gourmand"] .pcard:not(.prodhero) .name{
  font-family:Didot, 'Bodoni 72', 'Bodoni MT', 'Playfair Display', 'Hoefler Text', Garamond, Georgia, serif;
  font-size:16.5px; font-weight:600; line-height:1.2; letter-spacing:.004em;
  color:var(--d-encre); margin:12px 2px 3px; min-height:calc(2 * 1.2em)}
html[data-fiche="gourmand"] .pcard:not(.prodhero) .cat{
  font-size:11.5px; letter-spacing:.01em; color:var(--d-encre3)}
/* Le filet d'or du décor, repris pour séparer le pied. Pas de
   `margin-top` ici : la règle d'origine le pousse en bas avec `auto`, et
   les cadres à proportion fixe le remettent à zéro. Le redéclarer, même à
   la même valeur, gagnerait sur les deux et déréglerait les rangées. */
html[data-fiche="gourmand"] .pcard:not(.prodhero) .foot{
  border-top:1px solid rgba(133,100,40,.30); padding:13px 2px 2px}
html[data-fiche="gourmand"] .pcard:not(.prodhero) .price{
  font-family:Didot, 'Bodoni 72', 'Bodoni MT', 'Playfair Display', 'Hoefler Text', Garamond, Georgia, serif;
  font-size:17px; font-weight:600; letter-spacing:.01em; color:var(--d-encre)}
/* Le bouton d'ajout en cercle ÉVIDÉ : un aplat d'or de plus, à côté de
   l'étiquette dorée et du filet doré, faisait trois ors dans 200 px. */
html[data-fiche="gourmand"] .pcard:not(.prodhero) .add{
  background:transparent; border:1px solid var(--d-acc);
  color:var(--d-acc); border-radius:50%}
/* L'étiquette : petit rectangle, presque pas arrondi, et le même serif
   que le nom. Le fond doré est refusé à `.out` (« Épuisé ») : cette
   règle-ci est plus spécifique que `.flag.out`, et sans le `:not()` une
   rupture de stock s'annoncerait dans l'or des nouveautés. */
html[data-fiche="gourmand"] .pcard:not(.prodhero) .flag{
  border-radius:4px; padding:5px 11px; font-size:11px; font-weight:600; letter-spacing:.02em;
  font-family:Didot, 'Bodoni 72', 'Bodoni MT', 'Playfair Display', 'Hoefler Text', Garamond, Georgia, serif}
html[data-fiche="gourmand"] .pcard:not(.prodhero) .flag:not(.out){
  background:var(--d-acc); color:#ffffff}

/* ══════════════════════════════════════════════════════════════════════
   CAVE : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/cave.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous, quantité, accordéons, avis, « vous aimerez
   aussi », appartient à la page et non à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   Deux couleurs, pas trois : la craie du mur passé au lait de chaux et le
   bordeaux du soubassement peint. Le bordeaux ne sert JAMAIS de fond de
   lecture, seulement d'encre de titre, de filet et d'aplat de bouton :
   le décor l'emploie déjà comme socle, et le répéter en grand aurait
   refermé la page au lieu de l'éclairer.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="cave"]{
  --d-fond:#f4f1ea; --d-fond2:#e9e2d7;
  --d-carte:#fbf9f5; --d-carte2:#f3efe7;
  --d-encre:#2b1d1f; --d-encre2:#4e3b3d; --d-encre3:#7a6668;
  --d-filet:#e2d7d2; --d-filet2:#cdbbb6;
  --d-acc:#5c1b2a; --d-acc-d:#3f0f1b; --d-acc-l:#f3e4e4;
  --d-fort:#5c1b2a;
  /* La police du design suit jusque dans le panier, les favoris et le
     compte : `--serif` y est redéfini à partir de `--d-titre`. Sans cette
     ligne, on passait d'une fiche gravée en capitales à un panier en
     Iowan Old Style, comme si on changeait de boutique en route. */
  --d-titre:'Playfair Display','Iowan Old Style',Palatino,Georgia,serif}

/* L'OMBRE EST PORTÉE PAR LA PHOTO, PAS PAR SON CADRE : sur le cadre, un
   filtre se serait appliqué aussi aux deux flèches de galerie que
   product.js vient accrocher au même endroit. Elle part vers la droite
   parce que la lampe du cellier éclaire d'en haut à gauche ; c'est elle
   qui fait tenir l'article sur la pierre au lieu de flotter devant.
   L'ancrage en bas de l'article n'est plus déclaré ici : il vaut pour
   tous les gabarits et vit désormais dans la règle générique
   `html[data-maquette] [data-fp="photo"] img`, plus haut. */
html[data-fiche="cave"] [data-fp="photo"] img{
  filter:drop-shadow(9px 20px 20px rgba(46,11,18,.42))}

/* ── LA CARTE DU CATALOGUE ────────────────────────────────────────────
   Le même monde que la fiche : une étiquette de craie serrée dans un
   cadre bordeaux épais, comme une contre-étiquette collée sur le casier.
   Angles presque vifs, serif gravé, un seul filet avant le prix.

   `:not(.prodhero)` n'est pas un ornement de sélecteur : c'est la portée
   EXACTE des règles génériques `html[data-socle] .pcard:not(.prodhero)`
   écrites plus haut dans ce fichier. Avec un sélecteur plus court, elles
   nous passaient devant en spécificité et rien de ce qui suit n'aurait
   pris effet. */
html[data-fiche="cave"] .pcard:not(.prodhero){
  background:var(--d-carte);
  border:6px solid var(--d-acc);
  border-radius:4px;
  padding:9px;
  box-shadow:0 16px 28px -16px rgba(46,11,18,.38)}
/* La vignette garde la lumière rasante du décor : claire en haut à
   gauche, qui s'épaissit vers le bas à droite, là où tombe l'ombre de
   l'article. Le liseré intérieur évite qu'une photo à fond blanc ne se
   confonde avec la craie de la carte. */
html[data-fiche="cave"] .pcard:not(.prodhero) .thumb{
  background:linear-gradient(142deg,#f4f0ea 0%,#ece5de 56%,#e1d8d0 100%);
  border-radius:2px;
  box-shadow:inset 0 0 0 1px rgba(92,27,42,.07)}
html[data-fiche="cave"] .pcard:not(.prodhero) .name{
  font-family:'Playfair Display','Iowan Old Style',Palatino,Georgia,serif;
  font-weight:600; font-size:16px; letter-spacing:.002em;
  color:var(--d-acc); margin-top:11px}
/* Le rayon passe en pastille grise, comme sur l'étiquette de référence :
   posé en encre nue sous un nom bordeaux, il se lisait comme une
   deuxième ligne de titre. `max-width` parce qu'un rayon importé
   (« Vêtements d'extérieur et accessoires ») débordait de la carte. */
html[data-fiche="cave"] .pcard:not(.prodhero) .cat{
  display:inline-block; box-sizing:border-box; max-width:calc(100% - 4px);
  margin:5px 2px 0; padding:3px 10px; border-radius:99px;
  background:rgba(43,29,31,.07); color:var(--d-encre3); font-size:11px}
/* Le filet gravé de la fiche, repris ici : c'est lui qui raccorde la
   carte du catalogue à la maquette de l'article. */
html[data-fiche="cave"] .pcard:not(.prodhero) .foot{
  border-top:1px solid var(--d-filet); margin-top:auto; padding-top:11px}
html[data-fiche="cave"] .pcard:not(.prodhero) .price{
  font-family:'Playfair Display','Iowan Old Style',Palatino,Georgia,serif;
  font-weight:600; font-size:17px; letter-spacing:.01em; color:var(--d-acc)}
html[data-fiche="cave"] .pcard:not(.prodhero) .add{
  background:var(--d-acc); color:#f7f4ee; border-radius:50%;
  width:36px; height:36px}
html[data-fiche="cave"] .pcard:not(.prodhero) .flag{
  top:17px; left:17px; padding:4px 10px; border-radius:3px;
  font-family:'Playfair Display','Iowan Old Style',Palatino,Georgia,serif;
  font-weight:600; font-size:11px; letter-spacing:.03em}
/* « Nouveau » et « Best-seller » ne sont pas des urgences : ils passent en
   contre-étiquette de craie, bordeaux sur craie. L'aplat bordeaux plein
   reste réservé à la remise, seul endroit de la carte qui doit crier ;
   « Épuisé » garde le gris du thème, qui dit l'arrêt et pas la promesse. */
html[data-fiche="cave"] .pcard:not(.prodhero) .flag.soft{
  background:#faf7f1; color:var(--d-acc);
  box-shadow:inset 0 0 0 1px rgba(92,27,42,.22)}

/* ══════════════════════════════════════════════════════════════════════
   BOTANIQUE — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/botanique.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous — quantité, accordéons, avis, « vous aimerez
   aussi » — appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   LE PARTI PRIS, ET IL EST DÉLIBÉRÉ : le décor est SOMBRE, la palette est
   CLAIRE. Ce n'est pas une contradiction, c'est le sujet du design — une
   planche gravée vert forêt posée sur du papier crème. La toile du
   catalogue prolonge le vert du mur ; la feuille d'informations, les
   cartes et les encadrés sont le papier.

   Pourquoi pas une palette sombre : `--d-encre` sert d'encre à la PAGE et
   à la CARTE du catalogue (html[data-socle] .pcard y lit --ink). La faire
   crème pour coller au décor rendait le nom de l'article crème sur la
   carte crème de la référence — invisible. Une seule encre, donc une
   seule polarité, et c'est celle du papier.

   Le crème-sur-vert du haut de fiche n'en souffre pas : il est écrit en
   dur dans le gabarit, qui ne lit aucune de ces variables.
   ══════════════════════════════════════════════════════════════════════ */
/* PALETTE SOMBRE, ET C'EST VOULU. Elle était ivoire alors que sa toile et
   son décor sont un mur vert profond : sous la maquette, les titres de
   rayon sortaient à 1,4 contre 1 sur le vert, donc invisibles. Le décor
   décide, la palette suit. Les valeurs sont reprises de la carte du
   gabarit lui-même (fond #2b4534, encre #f8f1e3), qui était déjà juste. */
html[data-fiche="botanique"]{
  --d-fond:#26402f; --d-fond2:#1e3325;
  --d-carte:#2b4534; --d-carte2:#325040;
  --d-encre:#f8f1e3; --d-encre2:#ded4c0; --d-encre3:#bfb5a1;
  --d-filet:#3c5a49; --d-filet2:#4a6a56;
  --d-acc:#d9c48f; --d-acc-d:#c2ab74; --d-acc-l:#33513f;
  --d-fort:#d9c48f;
  /* Au-delà des treize obligatoires : le caractère du design ne tient pas
     qu'aux couleurs. Le serif est la moitié du sujet — une planche de
     botanique est gravée, pas imprimée en linéale — et les rayons larges
     tiennent la carte du catalogue dans le même monde que la fiche. */
  /* L'accent est désormais un or clair : l'encre qui se pose DESSUS doit
     redevenir sombre, sinon un bouton plein porte du crème sur du doré. */
  --d-sur-acc:#1e3325; --d-sur-fort:#1e3325;
  --d-titre:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,"Times New Roman",serif;
  --d-titre-gras:500; --d-titre-chasse:-.015em;
  --d-nom-police:var(--d-titre); --d-nom-gras:500;
  --d-vignette:#f2ecdf; --d-puce:#fbf7ec; --d-r-puce:99px;
  --d-r-carte:20px; --d-r-min:14px; --d-r-btn:5px; --d-r-btn-carte:50%}

/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les deux flèches de galerie que product.js accroche au
   même endroit. Deux passes, parce qu'une seule ne racontait rien de bon :
   une ombre courte et dense qui POSE l'article sur le plancher, et une
   longue et diffuse qui donne sa profondeur à la pièce. Avec la première
   seule on obtenait un autocollant, avec la seconde seule un objet en
   lévitation à dix centimètres du sol. */
html[data-fiche="botanique"] [data-fp="photo"] img{
  filter:drop-shadow(0 9px 9px rgba(10,20,13,.46)) drop-shadow(0 30px 34px rgba(8,16,11,.38))}

/* ══ LA CARTE DU CATALOGUE ═════════════════════════════════════════════
   Reprise de la carte de référence : une carte de papier crème largement
   arrondie qui flotte sur le vert de la toile. Le nom gravé en serif, le
   rayon en linéale grise — c'est le seul texte de la carte qui n'est pas
   gravé, et c'est ce qui l'empêche de virer au faire-part —, un filet
   avant la ligne du prix, et le « + » en pastille de lin plutôt qu'en
   aplat d'accent : rien ne crie, la carte y gagne son calme.

   `:not(.prodhero)` n'est pas décoratif. Les règles génériques de
   html[data-socle] .pcard:not(.prodhero) portent exactement cette
   spécificité ; sans le `:not()` ce bloc passerait dessous et le « + »
   resterait blanc sur lin. À égalité, c'est l'ordre du fichier qui
   tranche — ce bloc est en fin de feuille, après elles.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="botanique"] .pcard:not(.prodhero){
  background:#fcf9f1;border:1px solid #ece3cf;border-radius:20px;padding:11px;
  box-shadow:0 12px 26px -12px rgba(16,30,20,.30)}
html[data-fiche="botanique"] .pcard:not(.prodhero) .thumb{
  background:#f2ecdf;border-radius:14px}
html[data-fiche="botanique"] .pcard:not(.prodhero) .name{
  font-family:var(--d-titre);font-weight:500;font-size:16px;letter-spacing:-.01em;
  color:#2a2418;margin:11px 3px 3px}
html[data-fiche="botanique"] .pcard:not(.prodhero) .cat{
  font-family:var(--sans);font-size:11.5px;color:#6d6755;margin:0 3px}
/* Le filet qui sépare l'identité du prix. On ne touche PAS au `margin-top`
   du pied : [data-card] .pcard .foot{margin-top:0} compte dessus pour faire
   grandir la vignette dans les cadres, et le forcer ici rouvrirait le trou
   au-dessus du prix que cette règle-là a justement fermé. */
html[data-fiche="botanique"] .pcard:not(.prodhero) .foot{
  border-top:1px solid #ece3cf;padding:11px 3px 2px}
html[data-fiche="botanique"] .pcard:not(.prodhero) .price{
  font-family:var(--d-titre);font-weight:500;font-size:17px;color:#2a2418}
html[data-fiche="botanique"] .pcard:not(.prodhero) .add{
  background:#e7dfcd;color:#2a2418;border-radius:50%;box-shadow:none}
/* L'étiquette est un morceau du même papier que la carte, pas une pastille
   d'accent : posé sur la photo, un aplat vert forêt faisait une tache là où
   la référence pose une petite étiquette de jardinier. Les deux variantes
   gardent leur sens — la promotion passe au vert plein, l'épuisé au gris
   d'encre — sinon les trois états devenaient le même. */
html[data-fiche="botanique"] .pcard:not(.prodhero) .flag{
  top:14px;left:14px;background:#fbf7ec;color:#2a2418;
  font-family:var(--sans);font-weight:600;font-size:11px;letter-spacing:0;
  border-radius:9px;padding:5px 11px;box-shadow:0 2px 6px rgba(16,30,20,.14)}
html[data-fiche="botanique"] .pcard:not(.prodhero) .flag.soft{background:#2f5040;color:#fbf7ec}
html[data-fiche="botanique"] .pcard:not(.prodhero) .flag.out{background:#6d6755;color:#fbf7ec}

/* La toile de ce design est sombre, donc `data-fondsombre` est posé — et
   avec lui .fav{background:rgba(255,255,255,.14)}, écrit pour une carte
   sombre. Sur une carte de papier crème cette pastille s'évanouit et le
   cœur flotte sans support. On la lui rend, et son trait passe à la terre
   cuite du pot de la référence. [data-socle] est ajouté au sélecteur pour
   passer devant la règle générique sans dépendre de l'ordre du fichier. */
html[data-socle][data-fiche="botanique"][data-fondsombre] .pcard:not(.prodhero) .fav{
  background:#fbf7ec;box-shadow:0 2px 6px rgba(16,30,20,.14)}
html[data-socle][data-fiche="botanique"][data-fondsombre] .pcard:not(.prodhero) .fav svg{stroke:#b06a49}

/* Les pastilles de taille du gabarit sont peintes en ligne par product.js,
   qui ne pose aucun rayon : elles sortaient à angle vif au milieu d'un
   design qui n'a que des arrondis. Seul le rayon est ajouté ici ; les
   couleurs restent calculées par product.js sur l'encre héritée et sur la
   surface trouvée au-dessus, et il ne faut surtout pas les figer. */
html[data-fiche="botanique"] .fp-maq [data-fp="options"] [role="button"]{border-radius:99px}

/* ══════════════════════════════════════════════════════════════════════
   LIBRAIRIE : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/librairie.html) ne couvre que le haut de la
   fiche. Tout ce qui vient dessous (quantité, accordéons, avis, « vous
   aimerez aussi ») appartient à la page, pas à la maquette. Sans palette,
   ces blocs gardaient les couleurs du thème et la fiche se coupait en
   deux au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   papier ivoire devient la surface, le taupe du bouton devient l'accent.

   DEUX POLICES, PAS UNE : le design tient sur le contraste entre le
   serif (l'ouvrage : titre, prix, description, bouton) et les petites
   capitales sans (la librairie : rayon, repères, métadonnées). C'est
   pour cela que `--d-titre` et `--d-prix` sont déclarés ici et que la
   carte du catalogue les reprend rayon par rayon plus bas.

   CONTRASTES VÉRIFIÉS sur #f9f5ea : encre 16,7:1, encre2 7,9:1,
   encre3 4,8:1, texte du bouton sur l'accent 4,9:1.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="librairie"]{
  --d-fond:#f9f5ea; --d-fond2:#f1ebdc;
  --d-carte:#fbf7ed; --d-carte2:#f3eee0;
  --d-encre:#17150f; --d-encre2:#514b40; --d-encre3:#766e5d;
  --d-filet:#e2dbc9; --d-filet2:#cec5ae;
  --d-acc:#746c5d; --d-acc-d:#565042; --d-acc-l:#ebe6d8;
  --d-fort:#746c5d;
  /* L'accent sert aussi de couleur de TEXTE dans les cartes : à 4,5:1
     tout juste, un libellé de 11 px passait sous le seuil. On garde donc
     une version densifiée pour l'encre, l'accent d'origine restant aux
     aplats pleins où le texte est posé par dessus. */
  --d-acc-texte:#5b5446;
  /* La voix de l'ouvrage. Même pile que `--serif` du site : c'est déjà
     une serif de livre, inutile d'en charger une autre pour ça. */
  --d-titre:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
  --d-titre-gras:500; --d-titre-casse:none; --d-titre-chasse:-.012em;
  --d-prix:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
  --d-prix-gras:500;
  --d-btn:#746c5d; --d-btn-encre:#fbf8f1; --d-sur-acc:#fbf8f1; --d-sur-fort:#fbf8f1;
  /* Presque pas d'arrondi : une page imprimée n'a pas de coins ronds.
     Seules les pastilles d'options restent des ovales, comme sur la
     maquette de référence. */
  --d-r:2px; --d-r-min:0; --d-r-btn:3px; --d-r-puce:999px}

/* L'ombre de l'article, portée par la photo elle-même : sur le cadre,
   elle aurait bavé sur les flèches de galerie accrochées au même endroit.
   Deux ombres et pas une : la large pose l'objet dans la pièce, la serrée
   le colle au plateau. Sans la seconde, un livre debout sur une tablette
   claire a l'air de flotter à deux centimètres du bois. Teinte brun bois
   et non noire : une ombre neutre sur du chêne se voit comme une tache. */
html[data-fiche="librairie"] [data-fp="photo"] img{
  filter:drop-shadow(0 18px 20px rgba(74,58,36,.26)) drop-shadow(0 3px 3px rgba(74,58,36,.20))}
/* Les pastilles de taille sont peintes en style EN LIGNE par product.js,
   qui ne pose aucun rayon. Rectangulaires, elles juraient avec tout le
   reste ; le rayon, lui, n'est pas en ligne, une simple règle suffit à le
   poser (ne pas toucher à la bordure : elle porte l'état retenu). */
html[data-fiche="librairie"] [data-fp="options"] span{border-radius:999px}
/* Le filet de tête du gabarit, repris sous les titres de section : c'est
   ce qui raccorde le bas de la page au haut de la fiche. Pleine largeur,
   pas un tiret de 54 px : ici le filet est une règle de composition, pas
   un ornement. */
html[data-fiche="librairie"] body.page-produit .acc-t{letter-spacing:.01em}
html[data-fiche="librairie"] body.page-produit .acc-t::after{content:'';display:block;
  height:1px;margin-top:9px;background:var(--d-encre);opacity:.72}
/* Les barres de notation et les étoiles suivent l'accent du design,
   sinon elles gardent l'or du thème juste à côté d'un taupe. */
html[data-fiche="librairie"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="librairie"] .rate-pick button.on{color:var(--d-acc)}

/* ── LA CARTE DU CATALOGUE ─────────────────────────────────────────────
   Le même monde que la fiche, en petit : un rectangle d'encre posé sur le
   papier, le visuel dans un caisson greige, le nom en serif, le reste de
   l'appareil (rayon, prix, étiquettes) en sans. Aucun arrondi sauf le
   bouton d'ajout, aucune ombre : une carte imprimée ne décolle pas.

   `:not(.prodhero)` n'est pas décoratif, il sert DEUX fois : il épargne
   le visuel de la fiche article (qui est une vraie .pcard), et il met ces
   règles à la même spécificité que le bloc `html[data-socle] .pcard:
   not(.prodhero)` plus haut. Étant écrites APRÈS lui dans le fichier,
   elles l'emportent. Retirer le `:not()` ferait perdre l'égalité et rien
   de ce qui suit ne s'appliquerait plus. */
html[data-fiche="librairie"] .pcard:not(.prodhero){
  background:var(--d-carte);border:1px solid #1e1b12;border-radius:0;
  box-shadow:none;padding:12px}
html[data-fiche="librairie"] .pcard:not(.prodhero) .thumb{
  background:#ebe5d7;border-radius:0}
/* Même ombre que sur la fiche, en plus discrète : le visuel est posé au
   fond du caisson, pas collé dessus. */
html[data-fiche="librairie"] .pcard:not(.prodhero) .thumb svg,
html[data-fiche="librairie"] .pcard:not(.prodhero) .thumb .photo-frame{
  filter:drop-shadow(0 12px 14px rgba(74,58,36,.20))}
html[data-fiche="librairie"] .pcard:not(.prodhero) .name{
  font-family:var(--d-titre);font-weight:500;font-size:16px;line-height:1.2;
  letter-spacing:-.005em;margin:12px 2px 3px}
html[data-fiche="librairie"] .pcard:not(.prodhero) .cat{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,sans-serif;
  font-size:11.5px;color:var(--d-encre3)}
/* Le filet qui sépare l'ouvrage de son prix, exactement comme celui qui
   ouvre la colonne de la fiche. `margin-top` n'est PAS touché : c'est le
   `auto` du socle qui aligne les prix d'une rangée à l'autre, et le
   `[data-card] .pcard .foot{margin-top:0}` plus haut qui laisse le visuel
   prendre l'espace libre. Y toucher déforme toute la grille. */
html[data-fiche="librairie"] .pcard:not(.prodhero) .foot{
  border-top:1px solid var(--d-filet);padding-top:11px}
html[data-fiche="librairie"] .pcard:not(.prodhero) .price{
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,sans-serif;
  font-weight:500;font-size:16px;letter-spacing:0}
/* Le bouton d'ajout est un jeton clair à signe sombre, pas un aplat de
   couleur : sur une carte aussi calme, un rond taupe plein tirait l'œil
   avant le titre. L'encre est écrite ici et pas prise dans
   `--d-btn-encre`, qui est l'ivoire du bouton d'achat de la fiche. */
html[data-fiche="librairie"] .pcard:not(.prodhero) .add{
  background:#ded7c7;color:var(--d-encre);border-radius:999px;
  width:36px;height:36px;box-shadow:none}
/* L'étiquette n'est pas une pastille de couleur mais un cartouche tracé,
   comme un cachet de libraire. En sans : c'est la librairie qui parle. */
html[data-fiche="librairie"] .pcard:not(.prodhero) .flag{
  top:12px;left:12px;background:transparent;color:var(--d-encre);
  border:1px solid var(--d-encre);border-radius:4px;padding:4px 10px;
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,sans-serif;
  font-weight:500;font-size:11px;letter-spacing:.02em}
html[data-fiche="librairie"] .pcard:not(.prodhero) .flag.soft{
  background:transparent;color:var(--d-encre)}
html[data-fiche="librairie"] .pcard:not(.prodhero) .flag.out{
  color:var(--d-encre3);border-color:var(--d-encre3)}
/* Le cœur perd sa pastille blanche et son ombre : sur du papier, il ne
   reste que le trait. */
html[data-fiche="librairie"] .pcard:not(.prodhero) .fav{
  top:12px;right:12px;background:transparent;box-shadow:none}

/* ══════════════════════════════════════════════════════════════════════
   BOIS — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/bois.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous — quantité, accordéons, avis, « vous aimerez
   aussi » — appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   Trois teintes relevées dans la photo, et rien d'autre : le chêne clair
   devient la surface, la sauge l'accent (aplats, filets, bouton), l'argile
   ne sert qu'au bouton d'ajout des cartes — un point chaud par carte, pas
   une seconde couleur d'interface.

   Les valeurs ne sont pas prises à l'œil : la sauge d'accent a été
   assombrie jusqu'à ce que du blanc passe dessus à 4,6:1, et l'encre
   tertiaire jusqu'à 4,7:1 sur le fond. Une fiche illisible n'est pas un
   parti pris.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="bois"]{
  --d-fond:#f5ede2; --d-fond2:#ebdfcd;
  --d-carte:#fffdf9; --d-carte2:#f8f1e6;
  --d-encre:#2a2521; --d-encre2:#5b5148; --d-encre3:#736558;
  --d-filet:#e4d7c3; --d-filet2:#d3c3aa;
  --d-acc:#667a5f; --d-acc-d:#4e6048; --d-acc-l:#e9eee4;
  --d-fort:#667a5f;

  /* ── Les réglages de forme, lus par le bloc html[data-socle] ──
     Sans `--d-titre`, le panier et le compte repassaient en serif alors
     que la fiche est en sans : on changeait d'univers d'une page à
     l'autre. Les rayons sont ceux du gabarit — rien n'est coupé au carré
     dans un atelier de menuisier. */
  --d-titre:system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --d-titre-gras:700; --d-titre-chasse:-.03em;
  --d-r:18px; --d-r-btn:14px; --d-r-puce:10px; --d-r-min:16px;
  --d-btn-ombre:0 10px 20px rgba(70,86,63,.22);
  --d-sur-acc:#ffffff;
  /* La sauge d'aplat ne tient que 1,9:1 en TEXTE sur le bois d'une carte
     (étoiles de notation, prix mis à l'accent par certains cadres) : les
     cartes en reprennent une version densifiée, l'aplat garde la sienne. */
  --d-acc-texte:#4e6048}

/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit.
   Deux passes — une longue vers la droite, du côté opposé à la fenêtre du
   décor, et une courte au contact du plan de travail. Sans la seconde,
   l'article a l'air décollé de la table. */
html[data-fiche="bois"] [data-fp="photo"] img{
  filter:drop-shadow(30px 18px 20px rgba(96,60,34,.26))
         drop-shadow(0 8px 10px rgba(96,60,34,.22))}

/* Les pastilles de taille sont peintes en ligne par product.js, qui ne
   leur donne aucun rayon : carrées, elles juraient avec le bouton et
   l'étiquette de rayon du gabarit, arrondis tous les deux. */
html[data-fiche="bois"] [data-fp="options"] span{border-radius:10px}
/* Le filet de sauge du gabarit, repris sous les titres de section : c'est
   ce qui raccorde le bas de la page au décor du haut. */
html[data-fiche="bois"] body.page-produit .acc-t::after{content:'';display:block;
  width:46px;height:3px;border-radius:2px;margin-top:8px;background:var(--d-acc)}
/* Les barres de notation et les étoiles gardaient l'or du thème à côté
   d'une page entièrement passée au chêne et à la sauge. */
html[data-fiche="bois"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="bois"] .rate-pick button.on{color:var(--d-acc-d)}

/* ══════════════════════════════════════════════════════════════════════
   LA CARTE DU CATALOGUE — LE MÊME MONDE QUE LA FICHE
   ----------------------------------------------------------------------
   La carte de référence n'est pas une boîte blanche : c'est une PLANCHE de
   chêne clair, veinée, à coins ronds, posée sur la page avec une ombre
   longue — et le prix vit dans une bande blanche qui court d'un bord à
   l'autre du bas, comme une étiquette collée sur le bois.

   Les veines sont deux trames verticales aux pas premiers entre eux (7 et
   23 px) : alignées, elles auraient fait des rayures régulières de papier
   peint au lieu d'un fil de bois.

   `:not(.prodhero)` n'est pas un ornement : le bloc de distribution
   html[data-socle] cible exactement ce sélecteur, et une règle moins
   spécifique se serait fait écraser par lui. C'est aussi ce qui laisse la
   carte de la fiche article (.prodhero) à la maquette.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="bois"] .pcard:not(.prodhero){
  background:
    repeating-linear-gradient(90deg, rgba(157,114,66,.10) 0 1px, rgba(157,114,66,0) 1px 7px),
    repeating-linear-gradient(90deg, rgba(120,84,46,.07) 0 1px, rgba(120,84,46,0) 1px 23px),
    linear-gradient(97deg, #f0dcbe 0%, #e8cfab 46%, #eedcbf 100%);
  color:#332d26;
  border:0;
  border-radius:22px;
  /* Décalée vers la droite et le bas : la même lumière que dans le décor,
     et le « ombres longues » du design. */
  box-shadow:14px 18px 30px rgba(96,62,32,.20), 0 2px 5px rgba(96,62,32,.12);
  /* Bas à zéro : la bande du pied doit toucher le bord de la planche. */
  padding:12px 12px 0}
@media(hover:hover){
  /* Sans cette règle, le survol rendait à la carte l'ombre grise du thème
     et la planche redevenait une boîte blanche le temps du survol. */
  html[data-fiche="bois"] .pcard:not(.prodhero):hover{
    box-shadow:20px 26px 40px rgba(96,62,32,.26), 0 2px 5px rgba(96,62,32,.12)}}

/* La vignette : un sable très pâle, plus clair que la planche, avec un
   liseré de lumière en haut — l'article a l'air posé dedans, pas collé
   dessus. L'ombre du visuel part du même côté que celle de la fiche. */
html[data-fiche="bois"] .pcard:not(.prodhero) .thumb{
  background:linear-gradient(168deg, #f8eeda 0%, #eedfc6 100%);
  border-radius:16px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.70)}
html[data-fiche="bois"] .pcard:not(.prodhero) .thumb svg,
html[data-fiche="bois"] .pcard:not(.prodhero) .thumb .photo-frame{
  filter:drop-shadow(12px 10px 12px rgba(96,62,32,.28))}

html[data-fiche="bois"] .pcard:not(.prodhero) .name{
  font-weight:600; font-size:15px; letter-spacing:-.015em; color:#332d26;
  margin:12px 2px 2px}
/* Le petit trait sous le nom appartient au ::before du RAYON et non au
   ::after du nom : `.name` est un -webkit-box tronqué à deux lignes, un
   pseudo-élément y compte comme une ligne et mangeait la seconde. */
html[data-fiche="bois"] .pcard:not(.prodhero) .cat{
  color:#5c5044; font-size:11.5px; margin:0 2px 12px}
html[data-fiche="bois"] .pcard:not(.prodhero) .cat::before{
  content:''; display:block; width:34px; height:2px; border-radius:1px;
  margin:0 0 9px; background:rgba(51,45,38,.28)}

/* L'ÉTIQUETTE COLLÉE SUR LA PLANCHE. Marges négatives pour rejoindre les
   deux bords, et les deux coins du bas repris à l'identique de la carte :
   `overflow:hidden` aurait fait le même effet mais rogné le prix dans les
   cadres à proportion imposée. */
html[data-fiche="bois"] .pcard:not(.prodhero) .foot{
  margin:auto -12px 0; padding:12px 14px;
  background:#fffdf9;
  border-radius:0 0 22px 22px;
  box-shadow:0 -1px 0 rgba(96,62,32,.08)}
/* Dans un CADRE à proportion imposée, une marge auto absorbe la place
   libre avant que la vignette ne grandisse : le visuel restait petit et
   l'écart repartait en trou au-dessus du prix (voir [data-card] plus
   haut, que cette règle-ci écrasait). */
html[data-fiche="bois"] [data-card] .pcard:not(.prodhero) .foot{margin-top:0}
html[data-fiche="bois"] .pcard:not(.prodhero) .price{
  font-weight:700; font-size:16px; letter-spacing:-.02em; color:#2a2521}
html[data-fiche="bois"] .pcard:not(.prodhero) .price .old{color:#8a7c6d}

/* Le seul point d'argile de l'interface, et il est rond : c'est le geste
   qui vend. La sauge est déjà prise par le bouton de la fiche — deux
   boutons verts à deux échelles différentes se seraient confondus. */
html[data-fiche="bois"] .pcard:not(.prodhero) .add{
  width:38px; height:38px; border-radius:50%;
  background:#a9684a; color:#ffffff;
  box-shadow:0 6px 12px rgba(120,70,40,.28)}

/* Le cartouche du décor de référence : sauge cerclée d'argile. Le liseré
   n'est pas décoratif — sur une planche claire, un aplat sauge sans bord
   se fondait dans le bois au premier coup d'œil. */
html[data-fiche="bois"] .pcard:not(.prodhero) .flag,
html[data-fiche="bois"] .pcard:not(.prodhero) .flag.soft{
  top:14px; left:14px;
  background:#667a5f; color:#ffffff;
  border:2px solid rgba(169,104,74,.85);
  border-radius:8px; padding:4px 11px;
  font-size:10.5px; font-weight:650; letter-spacing:.015em;
  box-shadow:0 3px 7px rgba(96,62,32,.18)}
html[data-fiche="bois"] .pcard:not(.prodhero) .flag.out{
  background:#6b6054; border-color:rgba(107,96,84,.55)}
/* Le cœur est dessiné À MÊME le bois, comme sur la carte de référence :
   la pastille blanche pleine y faisait une tache. Un voile suffit à
   détacher son trait des veines. */
html[data-fiche="bois"] .pcard:not(.prodhero) .fav{
  background:rgba(255,253,249,.55); box-shadow:none}

/* EN LISTE, la carte n'est plus une planche mais une ligne : la bande
   blanche pleine largeur et le filet sous le nom n'y ont plus de sens, et
   le pied redevient une simple cellule de la grille. */
html[data-fiche="bois"] .grid.liste .pcard:not(.prodhero){padding:12px 14px}
html[data-fiche="bois"] .grid.liste .pcard .foot{
  margin:0; padding:6px 0 0; background:none; border-radius:0; box-shadow:none}
html[data-fiche="bois"] .grid.liste .pcard .cat{margin-bottom:0}
html[data-fiche="bois"] .grid.liste .pcard .cat::before{display:none}

/* ══════════════════════════════════════════════════════════════════════
   NÉON NUIT ─ LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/neon.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous ─ quantité, accordéons, avis, « vous aimerez
   aussi » ─ appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux
   au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   noir de studio devient la surface, le cyan devient l'accent.

   DEUX NÉONS, DEUX RÔLES, JAMAIS MÉLANGÉS : le violet étiquette (rayon,
   « Nouveau », favori), le cyan agit (prix, bouton, ajout au panier). Un
   visiteur qui cherche où acheter doit trouver la seule tache cyan de
   l'écran.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="neon"]{
  --d-fond:#05070e; --d-fond2:#0a0d18;
  --d-carte:#0d0f1c; --d-carte2:#14172a;
  --d-encre:#f2f1f8; --d-encre2:#b9b6cc; --d-encre3:#837f99;
  --d-filet:#23243a; --d-filet2:#35365a;
  --d-acc:#56e5fa; --d-acc-d:#22c9e6; --d-acc-l:#102c38;
  --d-fort:#56e5fa;
  /* LE VIOLET EXISTE EN DEUX VERSIONS, ET CE N'EST PAS UN CAPRICE : celui
     du décor (#8c4ad2) ne donne que 3,6:1 sur la carte, en dessous du
     seuil lisible. Il reste donc un LISERÉ, jamais un texte ; sa version
     claire (9,2:1) prend les mots. */
  --d-violet:#8c4ad2; --d-violet-l:#c79bff;
  /* Le prolongement de la palette au reste de la page, via les variables
     que le pont `html[data-socle]` lit déjà. Bebas Neue est chargée par
     produit.html et boutique.html : aucune police en plus. Graisse 400
     imposée, car Bebas n'en a qu'une et un 650 ferait fabriquer au
     navigateur un faux gras baveux. */
  --d-titre:'Bebas Neue', Haettenschweiler, 'Arial Narrow', Impact, sans-serif;
  --d-titre-gras:400; --d-titre-chasse:.012em; --d-titre-casse:uppercase;
  --d-prix:'Bebas Neue', Haettenschweiler, 'Arial Narrow', Impact, sans-serif;
  --d-prix-gras:400;
  --d-nom-police:'Bebas Neue', Haettenschweiler, 'Arial Narrow', Impact, sans-serif;
  --d-nom-gras:400; --d-nom-casse:uppercase;
  /* L'ENCRE POSÉE SUR LE CYAN. Sans ces trois-là, le pont garde son repli
     `#fff` : du blanc sur #56e5fa, mesuré à 1,5:1, soit un bouton
     « Ajouter au panier » dont on ne lit plus le texte. */
  --d-btn:#56e5fa; --d-btn-encre:#05070e;
  --d-sur-acc:#05070e; --d-sur-fort:#05070e;
  --d-r-btn:10px; --d-btn-ombre:0 0 28px rgba(86,229,250,.36)}

/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit.
   Deux ombres et non une : la noire pose l'article sur le sol laqué, la
   violette lui rend le halo que le décor projette sur tout ce qui s'y
   trouve. Une ombre noire seule, sur un fond noir, ne se voit pas. */
html[data-fiche="neon"] [data-fp="photo"] img{
  filter:drop-shadow(0 18px 20px rgba(0,0,0,.72)) drop-shadow(0 0 34px rgba(124,92,232,.32))}

/* Les pastilles de taille sont peintes en style EN LIGNE par product.js,
   qui ne pose aucun arrondi : c'est au design de le donner. Sans cette
   règle, des cases à angle droit au milieu d'une composition qui n'en a
   aucun autre. */
html[data-fiche="neon"] [data-fp="options"]>*{
  border-radius:999px; letter-spacing:.06em; text-transform:uppercase}

/* Le liseré violet-cyan, repris sous les titres de section : c'est ce qui
   raccorde le bas de la page au décor du haut. Les capitales suffisent à
   les rattacher au design ; leur imposer Bebas en plus les rétrécirait
   d'un tiers (une capitale de 15 px y fait 11 px de haut) et un titre
   d'accordéon n'a pas la place de grandir pour compenser. */
html[data-fiche="neon"] body.page-produit .acc-t{
  letter-spacing:.06em; text-transform:uppercase}
html[data-fiche="neon"] body.page-produit .acc-t::after{content:'';display:block;
  width:54px;height:2px;margin-top:8px;
  background:linear-gradient(90deg, var(--d-violet), var(--d-acc))}
/* Les barres de notation et les étoiles cliquables gardaient l'or du
   thème alors que tout le reste de la page a pris les couleurs du
   design. Elles suivent désormais l'accent. */
html[data-fiche="neon"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="neon"] .rate-pick button.on{color:var(--d-acc)}

/* ══════════════════════════════════════════════════════════════════════
   LA CARTE DU CATALOGUE
   ----------------------------------------------------------------------
   Relevée sur la carte de référence : un pavé de verre presque noir,
   cerclé d'un liseré qui passe du violet au cyan et qui irradie. La
   boutique et la fiche doivent appartenir au même monde, sinon le décor
   de la fiche a l'air d'une pièce rapportée.

   POURQUOI `:not(.prodhero)` PARTOUT : le pont `html[data-socle]
   .pcard:not(.prodhero)` peint déjà ces cartes, avec une spécificité de
   (0,3,1). Un sélecteur plus court ici serait battu et ces règles ne
   feraient rien du tout. On reprend donc sa forme exacte, et c'est
   l'ordre du fichier qui tranche.

   LE LISERÉ EN DÉGRADÉ se fait en deux couches de fond, la carte en
   `padding-box` et le liseré en `border-box` : c'est le seul moyen
   d'avoir une bordure dégradée qui suive un angle arrondi, `border-image`
   ignorant le rayon.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="neon"] .pcard:not(.prodhero){
  border:1px solid transparent; border-radius:18px;
  background:
    linear-gradient(var(--d-carte), var(--d-carte)) padding-box,
    linear-gradient(142deg, #8c4ad2 0%, #5a4bc8 40%, #56e5fa 100%) border-box;
  box-shadow:0 14px 34px rgba(0,0,0,.62), 0 0 22px rgba(124,92,232,.16)}
@media(hover:hover){
  html[data-fiche="neon"] .pcard:not(.prodhero):hover{
    box-shadow:0 18px 40px rgba(0,0,0,.70), 0 0 34px rgba(86,229,250,.30)}}

/* Le caisson de la vignette : un creux plus clair que la carte, cerclé
   d'un mince liseré violet. C'est là que se joue la moitié du caractère. */
html[data-fiche="neon"] .pcard:not(.prodhero) .thumb{
  background:linear-gradient(158deg, #1b1e33 0%, #0a0c16 72%);
  border-radius:14px;
  box-shadow:inset 0 0 0 1px rgba(140,74,210,.22), inset 0 1px 0 rgba(255,255,255,.06)}

/* La famille, la casse et la graisse viennent des `--d-nom-*` déclarés
   plus haut : le pont les applique déjà, inutile de les répéter. Ne
   restent ici que la taille et l'espacement.
   `min-height` SUIT l'interligne : la règle de base réserve deux lignes
   à 1,25 ; avec un interligne de 1,18 non suivi, la carte garde un blanc
   sous les noms courts et la rangée cesse d'être alignée. */
html[data-fiche="neon"] .pcard:not(.prodhero) .name{
  font-size:16px; line-height:1.18; min-height:calc(2 * 1.18em);
  letter-spacing:.03em; color:var(--d-encre)}

html[data-fiche="neon"] .pcard:not(.prodhero) .cat{
  margin-top:4px; font-size:10.5px; font-weight:600; letter-spacing:.2em;
  text-transform:uppercase; color:var(--d-encre3)}

/* Le filet qui sépare le pied du reste, comme sur la carte de référence.
   AUCUN `margin-top` ici : `[data-card] .pcard .foot` en pose un à zéro
   pour que la vignette puisse grandir dans les cadres en ligne, et le
   redéclarer ferait retomber tout l'écart au-dessus du prix. */
html[data-fiche="neon"] .pcard:not(.prodhero) .foot{
  border-top:1px solid var(--d-filet); padding:11px 2px 2px}

html[data-fiche="neon"] .pcard:not(.prodhero) .price{
  font-family:var(--d-prix); font-weight:400; font-size:20px;
  letter-spacing:.02em; color:var(--d-encre)}
/* L'ancien prix revient à la police du site : barré, en capitales
   condensées, il se lisait comme un code-barres. */
html[data-fiche="neon"] .pcard:not(.prodhero) .price .old{
  font-family:var(--sans); font-size:12px; color:var(--d-encre3)}

/* Le bouton d'ajout n'est plus un aplat mais un anneau de néon, comme sur
   la carte de référence : sur une carte presque noire, un carré cyan
   plein pèse plus lourd que la photo de l'article. */
html[data-fiche="neon"] .pcard:not(.prodhero) .add{
  width:36px; height:36px; border-radius:50%;
  border:1px solid transparent; color:#d8f7ff;
  background:
    linear-gradient(var(--d-carte), var(--d-carte)) padding-box,
    linear-gradient(150deg, #8c4ad2, #56e5fa) border-box;
  box-shadow:0 0 16px rgba(86,229,250,.32)}

/* LES TROIS ÉTIQUETTES NE DISENT PAS LA MÊME CHOSE, elles ne portent donc
   pas le même néon : cyan pour une promotion (c'est une action), violet
   pour « Nouveau » et « Best-seller » (c'est une mention), gris éteint
   pour « Épuisé » (il n'y a rien à faire). */
html[data-fiche="neon"] .pcard .flag{
  background:rgba(8,10,20,.88); color:#d8f7ff;
  border:1px solid rgba(86,229,250,.85); border-radius:8px;
  padding:4px 10px; font-weight:600; letter-spacing:.06em;
  box-shadow:0 0 14px rgba(86,229,250,.28)}
html[data-fiche="neon"] .pcard .flag.soft{
  color:var(--d-violet-l); border-color:rgba(140,74,210,.85);
  box-shadow:0 0 14px rgba(140,74,210,.30)}
html[data-fiche="neon"] .pcard .flag.out{
  color:var(--d-encre3); border-color:var(--d-filet2); box-shadow:none}

/* LE CŒUR DES FAVORIS. `html[data-socle][data-fondsombre] … .fav` lui
   donne un fond blanc à 14 % : une pastille laiteuse posée sur du verre
   noir. Il faut la même spécificité (0,5,1) pour la reprendre, d'où le
   `[data-socle]` accolé ─ il est toujours là, ce design déclare
   `socle: true`. */
html[data-fiche="neon"][data-socle] .pcard:not(.prodhero) .fav{
  background:rgba(8,10,20,.82); border:1px solid rgba(140,74,210,.70);
  box-shadow:0 0 14px rgba(140,74,210,.26)}
html[data-fiche="neon"][data-socle] .pcard:not(.prodhero) .fav svg{stroke:var(--d-violet-l)}
html[data-fiche="neon"][data-socle] .pcard:not(.prodhero) .fav.on svg{
  fill:var(--d-violet-l); stroke:var(--d-violet-l)}

/* ══════════════════════════════════════════════════════════════════════
   BORD DE MER - LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/marin.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous (quantité, accordéons, avis, « vous aimerez
   aussi ») appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le mur
   devient la surface, le bleu de mer devient l'accent, et le sable garde
   le second rôle : la barre d'horizon, le galet d'ajout des cartes.

   Les encres sont mesurées sur les DEUX surfaces du design, la carte
   blanche et le fond bleu pâle : --d-encre3 y donne 5,2 et 4,7 pour 1, et
   le blanc du bouton 4,5 pour 1 sur --d-acc. Le bleu de la référence
   (#679dbc) tombait à 3,0 : il est ici foncé d'un cran, c'est le prix de
   la lisibilité. Seul --d-acc posé en TEXTE sur le fond de page descend à
   4,0 ; c'est --d-acc-d (5,9) qui sert dans ce cas, --d-acc ne servant
   que de surface.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="marin"]{
  --d-fond:#eaf3f8; --d-fond2:#dcebf3;
  --d-carte:#ffffff; --d-carte2:#f5fafd;
  --d-encre:#1f2c36; --d-encre2:#4c6272; --d-encre3:#55707f;
  --d-filet:#d9e8f1; --d-filet2:#c3d9e6;
  --d-acc:#3f7d9e; --d-acc-d:#2f6280; --d-acc-l:#e3eff6;
  --d-fort:#3f7d9e}
/* L'horizon du gabarit, repris en filet sous les titres de section : la mer
   puis le sable, dans une seule barre arrondie. C'est ce qui raccorde le bas
   de la page au décor du haut. */
html[data-fiche="marin"] body.page-produit .acc-t{letter-spacing:.005em}
html[data-fiche="marin"] body.page-produit .acc-t::after{content:'';display:block;
  width:66px;height:4px;margin-top:8px;border-radius:99px;
  background:linear-gradient(90deg,var(--d-acc) 0 58%,#dcbf97 58% 100%)}
/* Les barres de notation et les étoiles cliquables gardaient l'or du thème
   alors que toute la page est passée au bleu : deux accents concurrents
   côte à côte. Elles suivent désormais celui du design. */
html[data-fiche="marin"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="marin"] .rate-pick button.on{color:var(--d-acc)}
/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit. Teinte
   froide, parce qu'elle tombe sur du sable sous une lumière de bord de mer,
   et qu'une ombre chaude y sonnerait faux. */
html[data-fiche="marin"] [data-fp="photo"] img{
  filter:drop-shadow(0 20px 20px rgba(38,72,96,.30))}

/* ── LA CARTE DU CATALOGUE, DANS LE MÊME MONDE QUE LA FICHE ────────────
   Relevée sur la carte de référence : coins très arrondis, pas de bordure
   marquée, une ombre bleutée basse et large, et un seul point chaud, le
   galet de sable qui ajoute au panier. La carte doit tenir à côté de la
   fiche sans qu'on doute qu'il s'agit du même magasin. */
html[data-fiche="marin"] .pcard:not(.prodhero){
  font-family:ui-rounded,'SF Pro Rounded','Varela Round','Nunito','Hiragino Maru Gothic ProN',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  border-radius:26px;padding:12px;border:1px solid #eaf1f6;
  box-shadow:0 10px 26px rgba(47,98,128,.10)}
@media(hover:hover){html[data-fiche="marin"] .pcard:not(.prodhero):hover{box-shadow:0 16px 34px rgba(47,98,128,.16)}}
html[data-fiche="marin"] .pcard:not(.prodhero) .thumb{border-radius:18px;background:#f3f8fb}
/* Le thème porte une ombre de vignette CHAUDE (rgba(120,70,40,.18)) : sur ce
   fond bleuté elle virait au brun. Même geste, teinte de mer. */
html[data-fiche="marin"] .pcard:not(.prodhero) .thumb svg,
html[data-fiche="marin"] .pcard:not(.prodhero) .thumb .photo-frame{
  filter:drop-shadow(0 10px 14px rgba(47,98,128,.16))}
html[data-fiche="marin"] .pcard:not(.prodhero) .name{color:#3c4a57;font-weight:700;letter-spacing:-.005em}
html[data-fiche="marin"] .pcard:not(.prodhero) .cat{color:var(--d-encre3)}
html[data-fiche="marin"] .pcard:not(.prodhero) .price{color:var(--d-encre);font-weight:750;letter-spacing:-.01em}
/* Le galet de sable, rond : la seule touche chaude de la carte, et elle
   répond au sol du décor. Le sable de la référence (#d9b184) ne donnait au
   « + » blanc que 1,1 pour 1 ; foncé à #b9884e il passe à 3,1, le seuil des
   éléments d'interface. */
html[data-fiche="marin"] .pcard:not(.prodhero) .add{border-radius:50%;background:#b9884e}
/* La pastille reprend le bleu du mur avec une encre marine dessus : du blanc
   sur ce bleu pâle ne donnait que 1,8 pour 1. Les deux variantes (promotion,
   épuisé) suivent la même règle, chacune sur son propre fond. */
html[data-fiche="marin"] .pcard:not(.prodhero) .flag{border-radius:11px;padding:5px 11px;background:#cfe4f2;color:#24536e}
html[data-fiche="marin"] .pcard:not(.prodhero) .flag.soft{background:#f0e2cd;color:#6d4e26}
html[data-fiche="marin"] .pcard:not(.prodhero) .flag.out{background:#dfe7ec;color:#3f5361}
/* Le cœur de la référence flotte sans disque sous lui. Posé sur une vraie
   photo de produit il y deviendrait invisible : on garde le disque, mais
   plat et sans ombre, pour ne pas alourdir une carte qui vit de son air. */
html[data-fiche="marin"] .pcard:not(.prodhero) .fav{background:rgba(255,255,255,.88);box-shadow:none}

/* ══════════════════════════════════════════════════════════════════════
   ENFANCE — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/enfance.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous — quantité, accordéons, avis, « vous aimerez
   aussi » — appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux
   au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   crème du mur devient la surface, le bleu des galets devient l'accent.

   Deux partis pris propres à ce design, tenus jusqu'au bas de la page :
   · TOUT EST ROND. Les rayons sont déclarés en variables (--d-r*) parce
     que le socle les lit déjà : bouton en pastille pleine, carte à 26 px,
     vignette à 18 px. Aucun angle vif nulle part.
   · DEUX TEINTES D'ACTION, ET C'EST VOULU. Le bleu mène l'achat (bouton,
     étiquette « Nouveau », liens) ; l'orange ne sert qu'au « + » des
     cartes, où un bleu de plus se perdrait dans l'étiquette bleue posée
     juste au-dessus. Les deux sont densifiés par rapport aux teintes du
     décor : #588ece sur blanc ne donne que 3,4:1, sous le seuil lisible.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="enfance"]{
  --d-fond:#faf5ea; --d-fond2:#f4ead8;
  --d-carte:#fffcf6; --d-carte2:#f7ecdd;
  --d-encre:#241f2e; --d-encre2:#544d63; --d-encre3:#736c86;
  --d-filet:#f0e6d6; --d-filet2:#e4d5bd;
  --d-acc:#3a72b4; --d-acc-d:#2b5a93; --d-acc-l:#e4eef9;
  --d-fort:#3a72b4;

  /* Les rondeurs. Le socle les lit pour la scène, le bouton d'achat, les
     puces, les vignettes de galerie et les cartes du catalogue. */
  --d-r:20px; --d-r-min:18px; --d-r-btn:999px; --d-r-puce:999px;
  --d-r-carte:26px; --d-r-fav:50%;

  /* Les fontes. Poppins 700 est déjà chargée par produit.html et par
     boutique.html : le titre, le prix et le nom des cartes la prennent,
     le texte courant garde la police système — Poppins n'est chargée
     qu'en 600 et 700, une description y serait écrite en demi-gras. */
  --d-titre:Poppins,'SF Pro Rounded','Trebuchet MS',system-ui,sans-serif;
  --d-titre-gras:700; --d-titre-chasse:-.025em; --d-titre-casse:none;
  --d-prix:Poppins,'SF Pro Rounded','Trebuchet MS',system-ui,sans-serif;
  --d-prix-gras:700;
  --d-nom-police:Poppins,'SF Pro Rounded','Trebuchet MS',system-ui,sans-serif;
  --d-nom-gras:700; --d-nom-casse:none;

  /* Les boutons. --d-btn tient l'achat en bleu ; --d-btn-carte donne au
     « + » des cartes l'orange de la maquette de référence. */
  --d-btn:#3a72b4; --d-btn-encre:#ffffff;
  --d-btn-ombre:0 10px 22px rgba(58,114,180,.26);
  --d-btn-carte:#e2621f; --d-r-btn-carte:50%;
  --d-btn-carte-ombre:0 5px 12px rgba(226,98,31,.30);
  --d-sur-acc:#ffffff; --d-sur-fort:#ffffff; --d-acc-texte:#2b5a93;

  /* La carte et sa vignette : un papier crème posé sur le mur, et un
     caisson de sable clair pour l'article. */
  --d-carte-fond:#fffcf6; --d-carte-bordure:1px solid #f2e7d6;
  --d-carte-ombre:0 10px 24px rgba(94,74,48,.10);
  --d-vignette:#f7ecdd;
  --d-vignette-ombre:inset 0 0 0 1px rgba(190,163,124,.22);
  --d-fav:rgba(255,255,255,.94)}

/* L'ombre de l'article, portée par la PHOTO et non par son cadre : un
   filtre posé sur le cadre s'appliquerait aussi aux deux flèches de
   galerie que product.js vient y accrocher. Chaude et très floue — sur
   un sol crème, une ombre grise et nette ferait un trou. */
html[data-fiche="enfance"] [data-fp="photo"] img{
  filter:drop-shadow(0 20px 20px rgba(112,86,58,.30))}

/* Les choix d'options sont peints EN LIGNE par js/product.js, sans rayon :
   des rectangles à angles vifs au milieu d'une fiche où tout est rond.
   Seule une règle de feuille de style peut les arrondir. */
html[data-fiche="enfance"] [data-fp="options"] span{
  border-radius:999px;padding:9px 16px!important}

/* ── LA CARTE DU CATALOGUE ─────────────────────────────────────────────
   Le fond, la bordure, les rayons, la vignette et le « + » viennent des
   variables ci-dessus (le socle les lit déjà). Ne restent ici que les
   choses qu'aucune variable n'exprime : la typographie du nom, le vert
   du prix, le filet du pied, et la taille des deux pastilles.

   `:not(.prodhero)` et pas autre chose : c'est la forme qu'emploient les
   règles du socle, et sans elle ces règles-ci seraient moins spécifiques
   que celles qu'elles doivent reprendre. */
html[data-fiche="enfance"] .pcard:not(.prodhero){padding:12px}

/* La vignette : l'article un peu plus grand que d'ordinaire (86 % au lieu
   de 82 %) et posé sur une ombre chaude — un jouet occupe sa boîte. */
html[data-fiche="enfance"] .pcard:not(.prodhero) .thumb .photo-frame,
html[data-fiche="enfance"] .pcard:not(.prodhero) .thumb svg{
  width:86%;height:86%;
  filter:drop-shadow(0 12px 14px rgba(112,86,58,.24))}

html[data-fiche="enfance"] .pcard:not(.prodhero) .name{
  font-size:15px;letter-spacing:-.015em;margin-top:11px}

html[data-fiche="enfance"] .pcard:not(.prodhero) .cat{
  font-size:11.5px;color:var(--d-encre3)}

/* Le vert du prix vient de la carte de référence. Densifié jusqu'à 5:1
   sur le crème de la carte : le vert d'origine n'y donnait que 4,0, et
   un prix se lit, il ne se devine pas. */
html[data-fiche="enfance"] .pcard:not(.prodhero) .price{
  font-family:var(--d-prix);font-weight:700;font-size:16px;color:#2c7d40}

/* Un filet sépare le pied du nom, comme sur la carte de référence : sans
   lui, prix et nom se collent dès que le nom tient sur une seule ligne. */
html[data-fiche="enfance"] .pcard:not(.prodhero) .foot{
  border-top:1px solid #f2e7d6;padding-top:10px;margin-top:auto}

html[data-fiche="enfance"] .pcard:not(.prodhero) .add{width:36px;height:36px}

/* L'étiquette reprend le bleu PLEIN du bouton d'achat, pas l'accent
   densifié que les cartes utilisent pour leur texte : c'est un aplat, le
   blanc se pose dessus et non à côté. */
html[data-fiche="enfance"] .pcard:not(.prodhero) .flag{
  background:#3a72b4;color:#ffffff;
  padding:5px 12px;font-size:11px;font-weight:700;letter-spacing:0;
  box-shadow:0 4px 10px rgba(58,114,180,.26)}
html[data-fiche="enfance"] .pcard:not(.prodhero) .flag.soft{background:#3a72b4}
html[data-fiche="enfance"] .pcard:not(.prodhero) .flag.out{background:var(--d-encre3)}

/* Le cœur des favoris passe à l'orange des cartes : en gris, il était la
   seule pièce neutre d'une vignette entièrement colorée. */
html[data-fiche="enfance"] .pcard:not(.prodhero) .fav svg{stroke:#e2621f}
html[data-fiche="enfance"] .pcard:not(.prodhero) .fav.on svg{fill:#e2621f;stroke:#e2621f}

/* ══════════════════════════════════════════════════════════════════════
   OUTILLAGE — LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/outillage.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous — quantité, accordéons, avis, « vous aimerez
   aussi » — appartient à la page, pas à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux au
   millimètre où le gabarit s'arrête.

   LE JAUNE N'EST PAS L'ACCENT, ET C'EST LA DÉCISION QUI TIENT TOUT LE
   RESTE. Le système peint plusieurs aplats avec `--acc` ou `--fort` en y
   posant une encre BLANCHE calculée ailleurs (.btn.dark, .chip.on, .flag,
   #addBtn, .opt button.on). Un jaune de sécurité y aurait donné du blanc
   sur jaune, mesuré à 1,9:1 — illisible. On met donc le graphite de
   l'atelier dans l'accent : il porte le blanc à 11,7:1. Le jaune reste ce
   qu'il est sur une machine — un bord, un liseré, un avertissement — et
   il est nommé `--d-jaune`, lu seulement par les règles écrites ici.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="outillage"]{
  --d-fond:#e3e6ea; --d-fond2:#ccd3d9;
  --d-carte:#edf0f2; --d-carte2:#dfe4e8;
  --d-encre:#16181a; --d-encre2:#3f474e; --d-encre3:#636c74;
  --d-filet:#c2c9cf; --d-filet2:#a7b0b7;
  --d-acc:#2f3945; --d-acc-d:#1d242c; --d-acc-l:#dde3e7;
  --d-fort:#2f3945;
  /* Le jaune de sécurité. Jamais une encre, seulement un bord. */
  --d-jaune:#edc10a;
  /* L'encre posée SUR le graphite, dans la fiche comme dans la carte. */
  --d-btn-encre:#ffffff; --d-sur-acc:#ffffff; --d-sur-fort:#ffffff;
  /* Le titre et le prix de la page reprennent ceux du gabarit : sans eux,
     le nom repassait en serif deux centimètres sous le même nom en
     Archivo noir, et la fiche avouait sa couture. */
  --d-titre:'Archivo','Helvetica Neue',system-ui,sans-serif;
  --d-titre-gras:800; --d-titre-chasse:-.035em; --d-titre-casse:uppercase;
  --d-prix:'Archivo','Helvetica Neue',system-ui,sans-serif; --d-prix-gras:800;
  /* Rien n'est arrondi dans un atelier : de la tôle découpée. */
  --d-r:2px; --d-r-min:4px; --d-r-btn:3px; --d-r-puce:3px}

/* L'ombre de l'article, portée par la PHOTO elle-même : posée sur son
   cadre, elle aurait bavé sur les deux flèches de galerie que product.js
   y accroche, et sur les quatre équerres du gabarit téléphone. Froide et
   courte — l'article est posé sur du métal, pas sur du sable. */
html[data-fiche="outillage"] [data-fp="photo"] img{
  filter:drop-shadow(0 16px 16px rgba(16,22,28,.45))}

/* ── LA CARTE DU CATALOGUE ────────────────────────────────────────────
   Le même monde que la fiche : une plaque d'acier brossé bordée de jaune
   de sécurité, une fenêtre de visée avec ses équerres de mesure, un nom
   en capitales noires, un filet de cote au-dessus du prix.

   `:not(.prodhero)` sur CHAQUE sélecteur, y compris les enfants : les
   règles génériques de `html[data-socle] .pcard:not(.prodhero)` ont
   exactement cette spécificité-là. Sans le `:not`, c'est elles qui
   gagnent ; avec lui, c'est l'ordre dans le fichier qui tranche, et ce
   bloc est le dernier. */
html[data-fiche="outillage"] .pcard:not(.prodhero){
  background:linear-gradient(102deg, #f2f4f6 0%, #e2e6ea 46%, #ccd2d8 100%);
  border:3px solid var(--d-jaune);
  border-radius:9px;
  box-shadow:0 2px 0 rgba(22,24,26,.16)}
@media(hover:hover){
  html[data-fiche="outillage"] .pcard:not(.prodhero):hover{
    box-shadow:0 10px 18px rgba(22,24,26,.24)}}

/* La vignette : une fenêtre de visée creusée dans la plaque. Les deux
   équerres sont des pseudo-éléments, placés en BAS et non en haut : les
   deux coins hauts sont déjà pris par l'étiquette et par le cœur des
   favoris, et une équerre passée dessous ne se lirait plus. Elles tombent
   dans la marge de 9 % que .thumb laisse autour du visuel. */
html[data-fiche="outillage"] .pcard:not(.prodhero) .thumb{
  background:linear-gradient(168deg, #dfe4e8 0%, #cdd4da 100%);
  border:1px solid var(--d-filet2);
  border-radius:4px}
html[data-fiche="outillage"] .pcard:not(.prodhero) .thumb::before,
html[data-fiche="outillage"] .pcard:not(.prodhero) .thumb::after{
  content:'';position:absolute;bottom:5px;width:12px;height:12px;opacity:.5}
html[data-fiche="outillage"] .pcard:not(.prodhero) .thumb::before{
  left:5px;border-left:1.5px solid var(--d-encre);border-bottom:1.5px solid var(--d-encre)}
html[data-fiche="outillage"] .pcard:not(.prodhero) .thumb::after{
  right:5px;border-right:1.5px solid var(--d-encre);border-bottom:1.5px solid var(--d-encre)}

/* Le nom en capitales : la même plaque gravée que le titre de la fiche.
   `min-height` suit la nouvelle interligne — la règle de base la calcule
   sur 1,25 em, et sans ce rappel les prix d'une rangée se décalaient. */
html[data-fiche="outillage"] .pcard:not(.prodhero) .name{
  font-family:'Archivo','Helvetica Neue',system-ui,sans-serif;
  font-weight:800;font-size:13px;line-height:1.22;
  text-transform:uppercase;letter-spacing:-.005em;
  min-height:calc(2 * 1.22em)}

/* Le rayon en chasse fixe : la légende d'un plan, pas une phrase. */
html[data-fiche="outillage"] .pcard:not(.prodhero) .cat{
  font-family:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:10px;font-weight:500;letter-spacing:.16em;text-transform:uppercase;
  color:var(--d-encre3)}

/* Le filet de cote au-dessus du pied : il sépare l'identité du prix et
   rappelle les traits de cote de la fiche. AUCUN `margin-top` ici : les
   cadres du catalogue posent `margin-top:0` sur ce pied pour que le
   visuel puisse grandir, et une marge automatique rouvrirait le trou
   au-dessus du prix que cette règle-là est venue fermer. */
html[data-fiche="outillage"] .pcard:not(.prodhero) .foot{
  border-top:1.5px solid var(--d-filet2);padding:9px 2px 2px}
html[data-fiche="outillage"] .pcard:not(.prodhero) .price{
  font-family:'Archivo','Helvetica Neue',system-ui,sans-serif;
  font-weight:800;font-size:16px;letter-spacing:-.02em;color:var(--d-encre)}

/* Le bouton d'ajout : un poussoir de machine, acier cerclé de noir, et
   non l'aplat de couleur du thème. L'encre doit être redite ici : la
   règle générique du socle y pose `--d-btn-encre`, qui vaut blanc pour
   le graphite du gros bouton et disparaîtrait sur cet acier-là. */
html[data-fiche="outillage"] .pcard:not(.prodhero) .add{
  background:radial-gradient(120% 120% at 30% 20%, #cfd5da, #aeb6bd);
  color:var(--d-encre);
  border:1.5px solid var(--d-encre);
  border-radius:50%;
  box-shadow:none}

/* L'étiquette : une plaquette vissée, encadrée, à encre noire. Trois
   états qui se distinguent sans changer de forme — le neuf en acier, la
   promotion en jaune de sécurité, l'épuisé en noir. Aucun ne descend
   sous 8:1, là où la pastille d'origine peignait du blanc sur l'accent. */
html[data-fiche="outillage"] .pcard:not(.prodhero) .flag{
  background:rgba(243,246,248,.92);color:var(--d-encre);
  border:1.5px solid var(--d-encre);border-radius:4px;
  font-family:'Archivo','Helvetica Neue',system-ui,sans-serif;
  font-weight:800;font-size:10px;letter-spacing:.06em;text-transform:uppercase;
  padding:4px 8px}
html[data-fiche="outillage"] .pcard:not(.prodhero) .flag.soft{
  background:var(--d-jaune);color:var(--d-encre)}
html[data-fiche="outillage"] .pcard:not(.prodhero) .flag.out{
  background:var(--d-encre);color:var(--d-fond)}

/* ── LE RACCORD AVEC LE BAS DE LA PAGE ──
   La bande de sécurité, reprise en filet sous les titres de section :
   c'est ce qui raccorde la page au décor du haut. */
html[data-fiche="outillage"] body.page-produit .acc-t{letter-spacing:.01em}
html[data-fiche="outillage"] body.page-produit .acc-t::after{content:'';display:block;
  width:54px;height:4px;margin-top:8px;background:var(--d-jaune)}
/* Les barres de notation gardaient l'or du thème : deux jaunes voisins
   mais différents, à trois centimètres l'un de l'autre. Elles prennent
   celui du design — c'est un aplat, jamais un texte. */
html[data-fiche="outillage"] .bar-note i b{background:var(--d-jaune)}
/* Les étoiles, elles, SONT du texte : le jaune y tomberait à 1,8:1. */
html[data-fiche="outillage"] .rate-pick button.on{color:var(--d-acc-d)}

/* ══════════════════════════════════════════════════════════════════════
   ANIMALERIE : LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/animalerie.html) ne couvre que le haut de la
   fiche. Tout ce qui vient dessous (quantité, accordéons, avis, « vous
   aimerez aussi ») appartient à la page et non à la maquette : sans
   palette, ces blocs gardaient les couleurs du thème et la fiche se
   coupait en deux au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   plâtre beige devient la surface, le cacao de la tenture devient l'encre,
   le moka du lin devient l'accent. Décor CLAIR, donc encre sombre.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="animalerie"]{
  --d-fond:#f6efe5; --d-fond2:#eadcc9;
  --d-carte:#fffbf6; --d-carte2:#fdf4e9;
  --d-encre:#3e271d; --d-encre2:#6b5044; --d-encre3:#7f6a5c;
  --d-filet:#ecdfcd; --d-filet2:#dcc9b3;
  --d-acc:#97675a; --d-acc-d:#7a4e42; --d-acc-l:#f4e4d4;
  --d-fort:#97675a}
/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les deux flèches de galerie accrochées au même endroit.
   Décalée vers la droite parce que la lumière du décor entre par la
   fenêtre de gauche : une ombre centrée aurait sonné faux sur le jute. */
html[data-fiche="animalerie"] [data-fp="photo"] img{
  filter:drop-shadow(6px 20px 20px rgba(74,44,28,.32))}
/* Les pastilles de taille sont peintes en ligne par product.js, qui ne
   pose aucun rayon : sans cette règle, le seul angle droit du design se
   trouverait au milieu du panneau crème. */
html[data-fiche="animalerie"] [data-fp="options"]>*{border-radius:99px}
/* Les trois galets du gabarit, repris sous les titres de section : c'est
   ce qui raccorde le bas de la page au panneau du haut. Un filet droit
   jurerait dans un design où rien n'a d'angle. */
html[data-fiche="animalerie"] body.page-produit .acc-t::after{content:'';display:block;
  width:26px;height:5px;border-radius:99px;margin-top:9px;background:var(--d-acc)}
/* Les barres de notation et les étoiles gardaient l'or du thème à côté
   d'un moka chaud : deux teintes voisines mais différentes. Elles suivent
   l'accent du design, comme tout le reste de la page. */
html[data-fiche="animalerie"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="animalerie"] .rate-pick button.on{color:var(--d-acc)}

/* ── LA CARTE DU CATALOGUE ────────────────────────────────────────────
   Relevée sur la carte de référence : crème rosé, coins très arrondis,
   aucune bordure, et surtout un PIED EN PASTILLE, le prix et le bouton
   rond réunis dans un même galet sable. C'est ce galet qui fait
   appartenir la carte au même monde que la fiche. */
html[data-fiche="animalerie"] .pcard:not(.prodhero){
  background:#fdf3e8; border:0; border-radius:26px; padding:12px;
  box-shadow:0 10px 26px rgba(90,58,42,.13)}
@media(hover:hover){
  html[data-fiche="animalerie"] .pcard:not(.prodhero):hover{box-shadow:0 18px 34px rgba(90,58,42,.20)}}
/* La vignette porte son propre fond sable : sur le crème de la carte, une
   photo détourée sur fond blanc n'avait plus aucune limite visible. */
html[data-fiche="animalerie"] .pcard:not(.prodhero) .thumb{
  background:#f1e6d8; border-radius:20px}
html[data-fiche="animalerie"] .pcard:not(.prodhero) .name{
  font-weight:650; letter-spacing:-.005em; color:var(--d-encre)}
/* La marge basse du rayon remplace l'écart que donnait le pied : celui-ci
   est devenu une pastille, et son `margin-top:auto` doit rester intact,
   sinon les prix d'une même rangée cessent de s'aligner. */
html[data-fiche="animalerie"] .pcard:not(.prodhero) .cat{
  margin:0 4px 10px; color:var(--d-encre3)}
html[data-fiche="animalerie"] .pcard:not(.prodhero) .foot{
  background:var(--d-acc-l); border-radius:99px; padding:7px 7px 7px 15px}
/* En vue liste, le pied réserve 44 px à droite pour le cœur des favoris.
   La règle ci-dessus est plus spécifique que `.grid.liste .pcard .foot` :
   elle doit lui rendre cette réserve, sinon le cœur mange le bouton. */
html[data-fiche="animalerie"] .grid.liste .pcard:not(.prodhero) .foot{padding-right:44px}
html[data-fiche="animalerie"] .pcard:not(.prodhero) .price{
  font-weight:700; color:var(--d-encre)}
html[data-fiche="animalerie"] .pcard:not(.prodhero) .add{
  width:36px; height:36px; border-radius:50%; background:var(--d-acc); color:#fff}
html[data-fiche="animalerie"] .pcard:not(.prodhero) .flag{
  top:18px; left:18px; border-radius:99px; padding:5px 13px;
  background:var(--d-acc); color:#fff; font-weight:700; letter-spacing:.01em}

/* ══════════════════════════════════════════════════════════════════════
   TABLE DRESSÉE, LA PALETTE DU DESIGN, POUR TOUTE LA PAGE
   ----------------------------------------------------------------------
   Le gabarit (maquettes/table.html) ne couvre que le haut de la fiche.
   Tout ce qui vient dessous, quantité, accordéons, avis, « vous aimerez
   aussi », appartient à la page et non à la maquette. Sans palette, ces
   blocs gardaient les couleurs du thème et la fiche se coupait en deux
   au millimètre où le gabarit s'arrête.

   Ces `--d-*` sont lues par le bloc `html[data-socle] body.page-produit`
   plus haut, qui les recopie dans --cream, --card, --ink et --line. Le
   noyer devient la surface, la lumière de bougie devient l'accent.

   DESIGN SOMBRE : le fond est le bois du décor, l'encre est la crème du
   lin. Toutes les paires sont mesurées au dessus de 5:1, la plus basse
   étant le rayon gris sur la carte (5,2).
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="table"]{
  --d-fond:#20140e; --d-fond2:#2b1c14;
  --d-carte:#2f211a; --d-carte2:#3a2920;
  --d-encre:#f4ecdb; --d-encre2:#cbbca6; --d-encre3:#a2938a;
  --d-filet:#433126; --d-filet2:#57412f;
  /* L'accent EST la flamme. Sur un design sombre la variante « foncée »
     doit être plus CLAIRE que l'accent, pas plus sombre : --d-acc-d sert
     de couleur de texte (étoiles, prix des cartes) sur des surfaces
     noires, où un or assombri disparaissait. Et --d-acc-l, la surface
     douce de l'accent (.alert-ok, .radio-card.on, le rayon actif du
     menu), est un brun doré SOMBRE : posée en clair, elle recevait de
     l'encre crème et devenait illisible. */
  --d-acc:#d4a768; --d-acc-d:#e8c58a; --d-acc-l:#3a2a1a;
  --d-fort:#d4a768;
  /* L'ENCRE POSÉE SUR L'OR. Sans ces trois là, #addBtn, .add et .flag
     retombent sur leur repli en dur (#fff) : du blanc sur #d4a768 ne
     donne que 2:1. Le noyer par dessus l'or en donne 7,9. */
  --d-btn-encre:#241711; --d-sur-acc:#241711; --d-sur-fort:#241711}

/* L'ombre de l'article, portée par la photo elle-même : sur le cadre, elle
   aurait bavé sur les flèches de galerie accrochées au même endroit. Deux
   ombres, parce que la bougie du décor est à GAUCHE : une ombre projetée
   qui part vers la droite, et une ombre de contact serrée sous le pied,
   sans laquelle l'article flotte au dessus du plateau. */
html[data-fiche="table"] [data-fp="photo"] img{
  filter:drop-shadow(26px 16px 24px rgba(8,4,2,.62)) drop-shadow(0 10px 10px rgba(10,5,2,.55))}

/* Le filet d'or du gabarit, repris sous les titres de section : c'est ce
   qui raccorde le bas de la page au décor du haut. */
html[data-fiche="table"] body.page-produit .acc-t::after{content:'';display:block;
  width:108px;height:1px;margin-top:9px;
  background:linear-gradient(90deg, rgba(232,197,138,.92), rgba(232,197,138,.08))}
/* Les barres de notation et les étoiles gardaient l'or du thème, une
   teinte chaude voisine mais différente, juste à côté de l'or du design. */
html[data-fiche="table"] .bar-note i b{background:var(--d-acc)}
html[data-fiche="table"] .rate-pick button.on{color:var(--d-acc-d)}

/* ══ LA CARTE DU CATALOGUE ═════════════════════════════════════════════
   La carte est une planche de noyer, comme la table de la fiche : même
   bois, même filet d'or, même pastille de chandelier. Le visiteur passe
   du rayon à l'article sans changer de salle.

   `:not(.prodhero)` n'est pas décoratif : la règle générique
   `html[data-socle] .pcard:not(.prodhero)` compte une classe de plus que
   `html[data-fiche="table"] .pcard`, et gagnerait sur fond, bordure et
   rayon. À poids égal, c'est la dernière écrite qui l'emporte, et ce bloc
   est en fin de feuille.
   ══════════════════════════════════════════════════════════════════════ */
html[data-fiche="table"] .pcard:not(.prodhero){
  /* Le bois n'est pas un aplat : il s'éclaire vers le coin haut gauche,
     du côté d'où vient la bougie sur la fiche. */
  background:linear-gradient(152deg, #3d2b21 0%, #30211a 44%, #241811 100%);
  border:1px solid #43312a; border-radius:22px; padding:12px;
  box-shadow:0 18px 34px rgba(0,0,0,.44), inset 0 1px 0 rgba(238,201,141,.10)}
/* La vignette : un caisson creusé dans la planche, pas un cadre blanc. */
html[data-fiche="table"] .pcard:not(.prodhero) .thumb{
  background:radial-gradient(120% 96% at 22% 6%, rgba(232,176,96,.12), transparent 62%), #241812;
  border-radius:14px; box-shadow:inset 0 0 0 1px rgba(232,197,138,.13)}
/* L'ombre d'origine, un brun à 18 %, n'existait plus sur ce bois sombre :
   l'article était découpé à plat sur la vignette. */
html[data-fiche="table"] .pcard:not(.prodhero) .thumb svg,
html[data-fiche="table"] .pcard:not(.prodhero) .thumb .photo-frame{
  filter:drop-shadow(0 12px 16px rgba(0,0,0,.55))}
/* Le nom en serif crème, comme le titre de la fiche. */
html[data-fiche="table"] .pcard:not(.prodhero) .name{
  font-family:'Iowan Old Style','Palatino Linotype',Palatino,Georgia,'Times New Roman',serif;
  font-weight:500; font-size:15.5px; letter-spacing:.004em; color:#f7f0e0}
html[data-fiche="table"] .pcard:not(.prodhero) .cat{
  font-size:11.5px; color:#a2938a; letter-spacing:.01em}
/* Le filet d'or sépare le rayon du prix, exactement comme sur la fiche il
   sépare le titre du prix. `margin-top:auto` reste : c'est lui qui colle
   le pied en bas quand les noms de la rangée n'ont pas la même longueur. */
html[data-fiche="table"] .pcard:not(.prodhero) .foot{
  border-top:1px solid rgba(232,197,138,.30); padding-top:11px; margin-top:auto}
html[data-fiche="table"] .pcard:not(.prodhero) .price{
  font-family:'Iowan Old Style','Palatino Linotype',Palatino,Georgia,'Times New Roman',serif;
  font-weight:500; font-size:17px; color:#f7f0e0}
html[data-fiche="table"] .pcard:not(.prodhero) .price .old{color:#9d8e84}
/* La pastille du chandelier : ronde, dorée, encre noyer. */
html[data-fiche="table"] .pcard:not(.prodhero) .add{
  background:radial-gradient(120% 120% at 30% 22%, #f2cf96 0%, #d0a263 58%, #ac8346 100%);
  color:#241711; border-radius:50%;
  box-shadow:0 6px 14px rgba(0,0,0,.44), inset 0 1px 0 rgba(255,240,215,.55)}
/* L'étiquette n'est pas dorée : l'or est déjà pris par la pastille, deux
   taches d'or dans une carte de 200 px se disputaient l'œil. Un galet
   sombre à filet d'or, posé sur le bois. */
html[data-fiche="table"] .pcard:not(.prodhero) .flag{
  background:rgba(20,12,7,.78); color:#f2e7d2; border:1px solid rgba(232,197,138,.34);
  font-weight:600; letter-spacing:.06em}
html[data-fiche="table"] .pcard:not(.prodhero) .flag.soft{
  background:rgba(20,12,7,.78); color:#e8c58a}
html[data-fiche="table"] .pcard:not(.prodhero) .flag.out{
  background:rgba(20,12,7,.78); color:#a2938a}
/* Le cœur des favoris : un trait d'or, sans pastille. Le sélecteur est
   doublé du `[data-fondsombre]` parce que la règle générique des designs
   sombres, plus haut, lui repose un disque blanc à 14 % et compte une
   classe de plus que la nôtre. */
html[data-fiche="table"] .pcard:not(.prodhero) .fav,
html[data-fiche="table"][data-fondsombre] .pcard:not(.prodhero) .fav{
  background:none; box-shadow:none}
html[data-fiche="table"] .pcard:not(.prodhero) .fav svg,
html[data-fiche="table"][data-fondsombre] .pcard:not(.prodhero) .fav svg{stroke:#e6c58e}
