@import url('https://fonts.googleapis.com/css2?family=Archivo+Black&family=Archivo:wght@300;400;500;600&family=Outfit:wght@200;300;400;500&display=swap');
@font-face{font-family:'Noken Bold';src:url('https://muons.fr/projets/assets/Noken-Bold.woff2') format('woff2');font-weight:bold;font-style:normal;font-display:swap}
html{font-size:clamp(16px,calc(12px + 0.25vw),20px);scroll-behavior:smooth}

/* ==========================================================================
   THEME — sombre par défaut, clair en option (bascule via data-theme sur
   <html>, gérée par site.js + persistée en localStorage). L'accent orange
   (#ff6400) est utilisé pour les actions primaires et les états
   sélectionnés/actifs, dans les deux thèmes.
   ========================================================================== */
:root{
  --bg:#000; --surface:#0d0d0d; --surface-2:#161616;
  --ink:#f4f4ef; --dim:#828282;
  --line:rgba(255,255,255,.14); --line2:rgba(255,255,255,.07);
  --glass:rgba(255,255,255,.045); --grid-line:rgba(255,255,255,.045);
  --header-bg:rgba(0,0,0,.92); --shadow:rgba(0,0,0,.5);
  --overlay-bg:rgba(0,0,0,.55); --modal-overlay:rgba(0,0,0,.82);
  --accent:#ff6400; --accent-ink:#fff; --accent-line:rgba(255,100,0,.4);
}
:root[data-theme="light"]{
  /* Miroir littéral du thème sombre (fond #000 / texte quasi blanc) : fond
     quasi blanc pur et texte quasi noir pur, pour un contraste équivalent —
     les surfaces de blocs (cartes, etc.) restent légèrement décalées du fond
     comme en sombre, sans devenir blanches à 100 % non plus. */
  --bg:#ffffff; --surface:#f5f4f0; --surface-2:#ebeae4;
  --ink:#0d0d0d; --dim:#5a5a56;
  --line:rgba(0,0,0,.18); --line2:rgba(0,0,0,.11);
  --glass:rgba(0,0,0,.035); --grid-line:rgba(0,0,0,.06);
  --header-bg:rgba(255,255,255,.92); --shadow:rgba(20,18,15,.16);
  --overlay-bg:rgba(255,255,255,.7); --modal-overlay:rgba(20,18,15,.55);
  --accent:#ff6400; --accent-ink:#fff; --accent-line:rgba(255,100,0,.4);
}
*{margin:0;padding:0;box-sizing:border-box}
/* Transition de thème coordonnée : sans règle par élément, seul <body> (via
   sa propre transition) s'estompait en douceur pendant que le reste de la
   page (cartes, header, modales…) basculait instantanément — d'où l'effet
   "violent" et désynchronisé au clic sur le bouton clair/sombre. Un fallback
   universel fait fondre tous les éléments ensemble, à la même vitesse ; les
   éléments qui déclarent déjà leur propre transition (boutons au survol…)
   restent prioritaires et ne sont pas affectés. */
@media(prefers-reduced-motion:no-preference){
  *,*::before,*::after{transition:background-color .35s ease,border-color .35s ease,color .35s ease,box-shadow .35s ease}
}
body{background:var(--bg);color:var(--ink);font-family:'Archivo',sans-serif;font-weight:300;-webkit-font-smoothing:antialiased;overflow-x:hidden;display:flex;flex-direction:column;min-height:100vh;min-height:100dvh}
/* body est un flex column : sans ceci, un enfant (header/#pp-root/#fp-root/
   #cart-root/footer) dont un descendant refuse de rétrécir sous son
   min-content (texte non-cassable, ligne flex sans wrap…) pousse toute la
   page plus large que le viewport — overflow-x:hidden ci-dessus masque alors
   silencieusement le débordement au lieu de laisser le contenu s'adapter.
   Même principe que minmax(0,1fr) plus bas pour les grilles. */
body>*{min-width:0}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
img,svg{display:block}
::selection{background:var(--accent);color:#fff}
.wrap{max-width:96rem;margin:0 auto;padding:0 clamp(1.2rem,3vw,2.4rem)}
.eyebrow{font-family:'Outfit',monospace;font-weight:300;font-size:.7rem;letter-spacing:.32em;text-transform:uppercase;color:color-mix(in srgb,var(--ink) 50%,transparent)}
.h2{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:clamp(1.6rem,3.2vw,2.5rem);line-height:1.05;letter-spacing:.01em}
.lead{font-family:'Outfit',sans-serif;font-weight:300;font-size:clamp(.9rem,1.2vw,1.05rem);line-height:1.6;color:color-mix(in srgb,var(--ink) 62%,transparent)}
.btn{display:inline-flex;align-items:center;gap:.6rem;font-family:'Outfit',monospace;font-weight:500;font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;padding:.85rem 1.6rem;border-radius:3rem;transition:background .2s,color .2s,border-color .2s,transform .2s;white-space:nowrap}
.btn-primary{background:transparent;color:var(--accent);border:0.05rem solid var(--accent)}
.btn-primary:hover{background:var(--accent);color:var(--accent-ink);transform:translateY(-0.125rem)}
.btn-solid{background:var(--accent);color:var(--accent-ink);border:0.05rem solid var(--accent)}
.btn-solid:hover{background:color-mix(in srgb,var(--accent) 85%,#000);border-color:color-mix(in srgb,var(--accent) 85%,#000);transform:translateY(-0.125rem)}
.btn-ghost{border:0.05rem solid var(--line);color:var(--ink)}
.btn-ghost:hover{border-color:var(--ink);transform:translateY(-0.125rem)}
.btn-sm{padding:.55rem 1.1rem;font-size:.62rem}

/* ── Bouton "shiny" (Échantillons, barre du haut) — porté depuis un composant
   React fourni par l'utilisateur (style jsx + @property), en CSS pur ici
   puisque le site n'a pas de framework. Couleur d'accroche remplacée par
   l'orange d'accent du site (--accent) ; les tons de fond/texte suivent les
   tokens de thème (--surface/--ink) pour s'adapter au clair comme au sombre,
   plutôt que le noir fixe du composant d'origine. ── */
@property --gradient-angle{syntax:"<angle>";initial-value:0deg;inherits:false}
@property --gradient-angle-offset{syntax:"<angle>";initial-value:0deg;inherits:false}
@property --gradient-percent{syntax:"<percentage>";initial-value:20%;inherits:false}
@property --gradient-shine{syntax:"<color>";initial-value:#fff;inherits:false}
@property --shiny-bg{syntax:"<color>";initial-value:#0d0d0d;inherits:false}
/* Version allégée : le composant d'origine ajoutait aussi un halo interne
   (span::before, un box-shadow qui "respire" en scale) qui se faisait mal
   découper par overflow:hidden selon le moteur de rendu — au survol, ça
   laissait échapper un bloc orange rectangulaire hors de la pilule. Ce
   halo est retiré, mais le motif de points est conservé (juste en dessous
   de 100% de large/haut avec un border-radius hérité, il reste bien dans
   les bords de la pilule). */
.shiny-cta{
  --shiny-bg:var(--surface-2);
  --shiny-fg:var(--ink);
  --shiny-hl:var(--accent);
  --shiny-hl-subtle:color-mix(in srgb,var(--accent) 55%,#fff);
  --duration:3s;
  isolation:isolate;position:relative;overflow:hidden;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:'Outfit',monospace;font-weight:500;font-size:.62rem;letter-spacing:.18em;
  text-transform:uppercase;line-height:1;white-space:nowrap;
  padding:.55rem 1.3rem;border:0.0625rem solid transparent;border-radius:3rem;
  color:var(--shiny-fg);
  background:linear-gradient(var(--shiny-bg),var(--shiny-bg)) padding-box,
    conic-gradient(from calc(var(--gradient-angle) - var(--gradient-angle-offset)),
      transparent,var(--shiny-hl) var(--gradient-percent),
      var(--gradient-shine) calc(var(--gradient-percent) * 2),
      var(--shiny-hl) calc(var(--gradient-percent) * 3),
      transparent calc(var(--gradient-percent) * 4)) border-box;
  transition:translate .15s,color .2s,--shiny-bg .2s,
    --gradient-angle-offset 800ms cubic-bezier(.25,1,.5,1),
    --gradient-percent 800ms cubic-bezier(.25,1,.5,1),
    --gradient-shine 800ms cubic-bezier(.25,1,.5,1);
  animation:gradient-angle var(--duration) linear infinite;
}
.shiny-cta:active{translate:0 0.0625rem}
.shiny-cta span{position:relative;z-index:1}
/* Motif de petits points, masqué en dégradé conique pour ne montrer qu'un
   arc qui tourne avec la bordure — reste en retrait de 3px des bords
   (--size) et hérite le border-radius, donc toujours contenu dans la pilule. */
.shiny-cta::before{
  content:"";pointer-events:none;position:absolute;inset-inline-start:50%;inset-block-start:50%;
  translate:-50% -50%;z-index:-1;border-radius:inherit;
  --size:calc(100% - 0.1875rem);--position:2px;--space:calc(var(--position) * 2);
  width:var(--size);height:var(--size);
  background:radial-gradient(circle at var(--position) var(--position),#fff calc(var(--position) / 4),transparent 0) padding-box;
  background-size:var(--space) var(--space);background-repeat:space;
  mask-image:conic-gradient(from calc(var(--gradient-angle) + 45deg),#000,transparent 10% 90%,#000);
  -webkit-mask-image:conic-gradient(from calc(var(--gradient-angle) + 45deg),#000,transparent 10% 90%,#000);
  opacity:.4;
  animation:gradient-angle var(--duration) linear infinite;
}
.shiny-cta:is(:hover,:focus-visible){--gradient-angle-offset:95deg;--gradient-shine:var(--shiny-hl-subtle);--shiny-bg:var(--accent);color:var(--accent-ink)}
@keyframes gradient-angle{to{--gradient-angle:360deg}}
@media(prefers-reduced-motion: reduce){.shiny-cta,.shiny-cta::before{animation:none}}
.reveal{opacity:0;transform:translateY(1.5rem);transition:opacity .6s cubic-bezier(.2,.7,.2,1),transform .6s cubic-bezier(.2,.7,.2,1)}
.reveal.on{opacity:1;transform:none}
.reveal2{transition-delay:.08s}.reveal3{transition-delay:.16s}.reveal4{transition-delay:.24s}

/* grille en fond — signature visuelle du site */
.gridbg{position:relative}
.gridbg::before{content:'';position:absolute;inset:0;z-index:0;pointer-events:none;background-image:linear-gradient(var(--grid-line) 0.0625rem,transparent 0.0625rem),linear-gradient(90deg,var(--grid-line) 0.0625rem,transparent 0.0625rem);background-size:3rem 3rem;-webkit-mask-image:radial-gradient(ellipse at 50% 20%,black 0%,transparent 68%);mask-image:radial-gradient(ellipse at 50% 20%,black 0%,transparent 68%)}
.gridbg>.wrap{position:relative;z-index:1}

/* emplacement photo — à remplacer */
.photo-slot{position:relative;aspect-ratio:4/3;background:var(--surface);border:0.0625rem dashed color-mix(in srgb,var(--ink) 16%,transparent);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;overflow:hidden}
.photo-slot img,.photo-slot video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.photo-slot svg{width:1.4rem;height:1.4rem;stroke:color-mix(in srgb,var(--ink) 28%,transparent);flex:none}
.photo-slot .ph-label{font-family:'Outfit',monospace;font-size:.58rem;letter-spacing:.08em;text-transform:uppercase;color:color-mix(in srgb,var(--ink) 32%,transparent);text-align:center;padding:0 .6rem;line-height:1.4}

/* bandeau promo — couleur de marque, en haut de chaque page */
#promo-strip{background:var(--accent);color:var(--accent-ink)}
.promo-row{display:flex;align-items:center;justify-content:center;gap:clamp(1rem,3vw,2.4rem);padding:.5rem 0;font-family:'Outfit',monospace;font-weight:500;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;flex-wrap:wrap;text-align:center}

/* header */
#site-header{position:sticky;top:0;z-index:60;background:var(--header-bg);backdrop-filter:blur(.6rem);border-bottom:0.0625rem solid var(--line2);flex:none}
.main-row{display:flex;align-items:center;gap:1.4rem;padding:.9rem 0}
.logo{font-family:'Noken Bold','Archivo Black',sans-serif;font-weight:bold;font-size:1.3rem;letter-spacing:0;text-transform:uppercase;flex:none}
/* Survol du logo header — flip vertical lettre par lettre, voir logoSwapHtml()
   dans site.js. Chaque .lg-char masque une boîte de hauteur 1em ; .lg-c2 est
   positionné juste sous .lg-c1 (top:100%) et invisible tant que rien ne bouge.
   Au survol, les deux calques translatent de -100% (délai décalé par lettre
   via --d) : .lg-c1 sort par le haut pendant que .lg-c2 vient prendre sa
   place — l'utilisateur ne voit jamais l'espace vide entre les deux. */
.logo-swap{display:inline-flex}
.lg-char{position:relative;display:inline-block;height:1em;overflow:hidden;vertical-align:top}
.lg-c{display:block;transition:transform .5s cubic-bezier(.65,0,.35,1);transition-delay:var(--d,0s)}
.lg-c2{position:absolute;left:0;top:100%}
.logo-swap:hover .lg-c1,.logo-swap:hover .lg-c2{transform:translateY(-100%)}
@media(prefers-reduced-motion:reduce){.lg-c{transition:none}}
.main-row .logo{font-size:2rem;margin-right:.9rem}
.mnav{display:flex;align-items:center;gap:.2rem;flex:1;min-width:0}
@media(min-width:68.01rem){.mnav{gap:.5rem}}
.nav-item{position:relative}
.nav-trig{display:flex;align-items:center;justify-content:center;gap:.3rem;padding:.5rem .8rem;font-family:'Outfit',sans-serif;font-weight:600;font-size:.7rem;letter-spacing:.04em;text-transform:uppercase;line-height:1;color:var(--accent-ink);background:var(--accent);border-radius:.4rem;transition:background .2s}
.nav-trig:hover{background:color-mix(in srgb,var(--accent) 82%,black)}
.nav-trig svg{width:.6rem;height:.6rem;stroke:currentColor;flex:none;transition:transform .2s;margin-top:0.0625rem}
.nav-item:hover .nav-trig svg,.nav-item.open .nav-trig svg{transform:rotate(180deg)}
.nav-drop{position:absolute;top:100%;left:0;margin-top:.4rem;width:max-content;max-width:min(92vw,58rem);background:var(--surface);border:0.0625rem solid var(--line);border-radius:.8rem;padding:.9rem;opacity:0;visibility:hidden;transform:translateY(.4rem);transition:opacity .18s,transform .18s,visibility .18s,background-color .35s ease,border-color .35s ease;box-shadow:0 1rem 2.5rem var(--shadow);display:grid;grid-auto-flow:column;grid-auto-columns:minmax(8.5rem,10.5rem);gap:.4rem 1rem}
.nav-item:hover .nav-drop,.nav-item.open .nav-drop{opacity:1;visibility:visible;transform:none}
.nav-drop-fam h5{font-family:'Outfit',monospace;font-weight:500;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);margin-bottom:.5rem;padding:0 .4rem .4rem;border-bottom:0.0625rem solid var(--accent-line)}
.nav-drop a{display:block;padding:.4rem .4rem;border-radius:.4rem;font-family:'Outfit',sans-serif;font-size:.78rem;font-weight:300;color:color-mix(in srgb,var(--ink) 68%,transparent);transition:background .15s,color .15s}
.nav-drop a:hover{background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent)}
.hd-actions{display:flex;align-items:center;gap:.6rem;flex:none}
.hd-social{display:flex;align-items:center;gap:.35rem}
.hd-ico{width:1.85rem;height:1.85rem;border-radius:50%;border:0.05rem solid var(--line2);display:flex;align-items:center;justify-content:center;flex:none;color:color-mix(in srgb,var(--ink) 60%,transparent);transition:border-color .2s,color .2s,transform .2s}
.hd-ico:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-0.1rem)}
.hd-ico svg{width:.72rem;height:.72rem;stroke:currentColor}
.hd-sep{width:0.0625rem;height:1.3rem;background:var(--line2);flex:none}
.hd-icon-btn{position:relative;width:1.85rem;height:1.85rem;border-radius:50%;border:0.05rem solid var(--line2);display:flex;align-items:center;justify-content:center;flex:none;color:color-mix(in srgb,var(--ink) 60%,transparent);transition:border-color .2s,color .2s,transform .2s}
.hd-icon-btn:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-0.1rem)}
.hd-icon-btn svg{width:.82rem;height:.82rem;stroke:currentColor}
.hd-cart-badge{position:absolute;top:-.3rem;right:-.3rem;min-width:1.05rem;height:1.05rem;padding:0 .25rem;border-radius:1rem;background:var(--accent);color:var(--accent-ink);font-family:'Outfit',monospace;font-size:.6rem;align-items:center;justify-content:center;line-height:1}
.hd-cart.bump{animation:cartBump .45s ease}
/* Aperçu panier au survol — même logique d'ouverture que .nav-drop, mais
   ancré à droite (right:0) puisque le panier est tout près du bord droit du
   header : un ancrage left:0 comme .nav-drop déborderait de l'écran. */
.hd-cart-wrap{position:relative;display:flex;align-items:center}
.cart-preview{position:absolute;top:100%;right:0;margin-top:.6rem;width:19rem;max-width:88vw;background:var(--surface);border:0.0625rem solid var(--line);border-radius:.9rem;padding:.7rem;opacity:0;visibility:hidden;transform:translateY(.4rem);transition:opacity .18s,transform .18s,visibility .18s,background-color .35s ease,border-color .35s ease;box-shadow:0 1rem 2.5rem var(--shadow);z-index:70}
/* (hover:hover) and (pointer:fine) — pas juste "mobile" : sur tactile, un
   :hover simple sur un élément qui révèle du contenu peut forcer certains
   navigateurs (iOS Safari) à consommer le premier tap pour "activer" le
   survol plutôt que suivre le lien — le panier doit toujours amener
   directement à panier.html en un seul tap sur mobile, jamais d'aperçu. */
@media(hover:hover) and (pointer:fine){
  .hd-cart-wrap:hover .cart-preview{opacity:1;visibility:visible;transform:none}
}
.cart-preview-empty{font-family:'Outfit',sans-serif;font-size:.8rem;color:var(--dim);padding:.6rem .3rem;text-align:center}
.cart-preview-item{display:flex;align-items:center;gap:.6rem;padding:.4rem .3rem;border-radius:.5rem}
.cart-preview-item+.cart-preview-item{border-top:0.0625rem solid var(--line2)}
.cart-preview-photo{width:2.7rem;height:2.7rem;border-radius:.4rem;overflow:hidden;flex:none;background:var(--bg);position:relative}
.cart-preview-photo img,.cart-preview-photo video{width:100%;height:100%;object-fit:cover}
.cart-preview-photo svg{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1rem;height:1rem;stroke:color-mix(in srgb,var(--ink) 28%,transparent)}
.cart-preview-text{min-width:0;display:flex;flex-direction:column;gap:.1rem}
.cart-preview-text b{font-family:'Outfit',sans-serif;font-weight:600;font-size:.78rem;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cart-preview-text span{font-family:'Outfit',monospace;font-size:.64rem;color:var(--dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cart-preview-remove{flex:none;width:1.5rem;height:1.5rem;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--dim);transition:background .15s,color .15s}
.cart-preview-remove svg{width:.7rem;height:.7rem;stroke:currentColor}
.cart-preview-remove:hover{background:var(--accent);color:var(--accent-ink)}
.cart-preview-more{font-family:'Outfit',monospace;font-size:.62rem;color:var(--dim);text-align:center;padding:.4rem 0 .1rem}
.cart-preview-btn{display:flex;justify-content:center;width:100%;margin-top:.6rem}
@keyframes cartBump{
  0%,100%{transform:rotate(0)}
  20%{transform:rotate(-16deg)}
  45%{transform:rotate(13deg)}
  70%{transform:rotate(-7deg)}
  90%{transform:rotate(3deg)}
}
.drawer-cta .hd-icon-btn{width:2.1rem;height:2.1rem}
.drawer-cta .hd-icon-btn svg{width:.9rem;height:.9rem}
.theme-toggle{width:1.85rem;height:1.85rem;border-radius:50%;border:0.05rem solid var(--line2);display:flex;align-items:center;justify-content:center;flex:none;transition:border-color .2s,background .2s,transform .25s}
.theme-toggle:hover{border-color:var(--accent);transform:rotate(18deg) scale(1.1)}
.theme-toggle:active{transform:scale(.85)}
.theme-toggle.spin{animation:themeSpin .5s ease}
@keyframes themeSpin{0%{transform:rotate(0)}100%{transform:rotate(1turn)}}
.theme-toggle svg{width:.82rem;height:.82rem;stroke:var(--ink);fill:none}
.theme-toggle .i-sun{display:none}
:root[data-theme="light"] .theme-toggle .i-moon{display:none}
:root[data-theme="light"] .theme-toggle .i-sun{display:block}
.burger{display:none;flex-direction:column;gap:.28rem;padding:.5rem}
.burger span{width:1.3rem;height:0.09rem;background:var(--ink)}
@media(max-width:68rem){
  /* Le menu déroulant complet (survol) laisse place au tiroir mobile pour le
     détail des familles/produits, mais les 2 boutons "Impression"/"Création"
     restent visibles, recentrés dans l'espace libre entre logo et actions —
     un raccourci direct sans ouvrir le tiroir. Leur sous-menu (.nav-drop,
     pensé pour un survol souris) est masqué : au tactile ça naviguerait
     directement vers print.html/creation.html, comme n'importe quel lien. */
  .mnav{display:flex;justify-content:center}
  .nav-drop{display:none}
  .burger{display:flex}
  /* Le thème vit désormais dans l'en-tête du tiroir (drawer-top-actions,
     site.js) — inutile de le dupliquer ici. La recherche, elle, reste dans
     cette barre (voir plus bas : réordonnée juste avant le burger). */
  #themeToggle{display:none}
  /* Recherche/panier/burger réordonnés (flex order) sans toucher au DOM —
     le panier garde sa position d'origine, la recherche vient se placer
     juste avant le burger, comme demandé, sans affecter l'ordre desktop. */
  .hd-cart-wrap{order:1}
  .js-search-btn{order:2}
  .burger{order:3}
  /* Les pastilles Impression/Création gardent leur style desktop mais doivent
     tenir, à deux, dans l'espace libre entre logo et actions sur un petit
     écran — nettement plus compactes, et sans le chevron (qui suggère un
     sous-menu au survol, inutilisable au tactile ; voir .nav-drop{display:none}
     juste au-dessus). */
  .main-row{gap:.6rem}
  .nav-trig{padding:.42rem .55rem;font-size:.6rem;letter-spacing:.01em;gap:0}
  .nav-trig svg{display:none}
  /* Logo resserré à la même taille que celui du tiroir (drawer-top) — 2rem
     (taille desktop) prenait trop de place à côté des pastilles Impression/
     Création maintenant visibles ici aussi. */
  .main-row .logo{font-size:1.3rem}
}
@media(max-width:40rem){.hd-social,.hd-sep{display:none}}
/* Sous 40rem, le bouton "Échantillons" du header (recherche+panier+CTA+thème+
   burger, tous côte à côte) fait déborder .main-row horizontalement — l'action
   reste accessible via le même bouton dans le tiroir mobile (#echBtnDrawer,
   voir drawerCtaHtml dans site.js), donc on le masque juste ici. */
@media(max-width:40rem){#echBtnTop{display:none}}
/* Le padding standard (.wrap) est le même partout ; sur mobile on resserre
   légèrement à droite pour que le burger se rapproche du bord (son padding
   interne sert déjà de zone tactile confortable), et on assure explicitement
   une marge nette à gauche du logo pour qu'il ne semble jamais collé au bord. */
@media(max-width:40rem){.main-row{padding-left:1.4rem;padding-right:.75rem}}
.drawer-social{gap:.6rem}
.drawer-social .hd-ico{width:2.1rem;height:2.1rem}
.drawer-social .hd-ico svg{width:.85rem;height:.85rem}

/* tiroir mobile — 3 zones en colonne : en-tête fixe (logo+thème+fermer),
   zone du milieu qui centre verticalement familles+bouton Échantillons dans
   l'espace disponible, pied de page fixe (contacts) séparé par un filet. */
/* Ouverture du tiroir : fondu lent (opacity, .55s) plutôt qu'un slide sec —
   le léger translateX résiduel reste, mais l'effet dominant est le fade.
   Chaque .drawer-fam fait un fondu + léger décalage vertical, en cascade
   (transition-delay croissant par ordre d'apparition) une fois .open posé. */
.drawer{position:fixed;inset:0;z-index:90;background:var(--bg);opacity:0;transform:translateX(2.5rem);transition:opacity .55s ease,transform .55s ease,background-color .35s ease;pointer-events:none;overflow-y:auto;display:flex;flex-direction:column}
.drawer.open{opacity:1;transform:none;pointer-events:auto}
.drawer-top{display:flex;justify-content:space-between;align-items:center;padding:1.1rem clamp(1.2rem,4vw,3rem);border-bottom:0.0625rem solid var(--line2);flex:none}
.drawer-top-actions{display:flex;align-items:center;gap:.6rem}
/* overflow-y:auto est ce qui empêche .drawer-mid de déborder sur le header
   (drawer-top) et le footer (drawer-footer, tous deux flex:none donc de
   taille fixe) quand une famille dépliée rend son contenu plus haut que
   l'espace disponible : un flex:1 sans overflow explicite ne clippe rien,
   le contenu débordait alors symétriquement au-dessus ET en dessous
   (conséquence du justify-content:center) par-dessus les zones fixes. */
.drawer-mid{flex:1;display:flex;flex-direction:column;justify-content:center;min-height:0;overflow-y:auto}
.drawer-mid nav{padding:1rem clamp(1.2rem,4vw,3rem) 1rem}
.drawer-footer{border-top:0.0625rem solid var(--line2);border-bottom:none;justify-content:center;flex:none}
/* Trait orange entre les familles Impression et les groupes Création. */
/* Titres de groupe (Impression / Création) — orange, avec un filet fin
   dessous plutôt qu'un simple trait plein pleine largeur entre les deux
   groupes (plus lisible, nomme explicitement chaque groupe). */
.drawer-group-title{font-family:'Outfit',monospace;font-size:.68rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);padding-bottom:.55rem;margin:.3rem 0 .2rem;border-bottom:0.05rem solid var(--accent-line)}
.drawer-group-title:first-child{margin-top:0}
.drawer-fam{padding:.9rem 0;border-bottom:0.0625rem solid var(--line2)}
/* Cascade au survol de tous les enfants directs de <nav> — titres de groupe
   ET familles ensemble, dans leur ordre d'apparition — plutôt que juste
   .drawer-fam, sinon les titres de groupe (ajoutés séparément) sautaient
   instantanément sans suivre le même fondu en cascade que le reste. */
.drawer-mid nav>*{opacity:0;transform:translateY(.6rem);transition:opacity .4s ease,transform .4s ease}
.drawer.open .drawer-mid nav>*{opacity:1;transform:none}
.drawer.open .drawer-mid nav>*:nth-child(1){transition-delay:.08s}
.drawer.open .drawer-mid nav>*:nth-child(2){transition-delay:.11s}
.drawer.open .drawer-mid nav>*:nth-child(3){transition-delay:.14s}
.drawer.open .drawer-mid nav>*:nth-child(4){transition-delay:.17s}
.drawer.open .drawer-mid nav>*:nth-child(5){transition-delay:.2s}
.drawer.open .drawer-mid nav>*:nth-child(6){transition-delay:.23s}
.drawer.open .drawer-mid nav>*:nth-child(7){transition-delay:.26s}
.drawer.open .drawer-mid nav>*:nth-child(8){transition-delay:.29s}
.drawer.open .drawer-mid nav>*:nth-child(9){transition-delay:.32s}
.df-summary{width:100%;font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:1rem;color:color-mix(in srgb,var(--ink) 90%,transparent);cursor:pointer;display:flex;justify-content:space-between;align-items:center;text-align:left}
.df-plus{transition:transform .3s ease;flex:none}
.drawer-fam.open .df-plus{transform:rotate(45deg)}
/* Ouverture lente de la liste de produits — grille 1 ligne 0fr → 1fr,
   overflow:hidden sur le contenu pour le masquer tant que la ligne est
   quasi nulle : la technique standard pour animer une hauteur "auto". */
/* minmax(0,Xfr), pas juste Xfr : une piste <flex> seule garde un minimum
   "auto" basé sur son contenu (même 0fr), donc sans le minmax(0,…) le
   panneau fermé gardait un reliquat de quelques px visible — même famille de
   piège que minmax(0,1fr) pour les débordements horizontaux plus haut. */
.df-panel{display:grid;grid-template-rows:minmax(0,0fr);transition:grid-template-rows .4s ease}
.drawer-fam.open .df-panel{grid-template-rows:minmax(0,1fr)}
.drawer-fam .df-links{display:flex;flex-direction:column;padding-top:.6rem;gap:.2rem;overflow:hidden;min-height:0}
.drawer-fam .df-links a{padding:.4rem 0;font-family:'Outfit',sans-serif;font-size:.85rem;color:color-mix(in srgb,var(--ink) 60%,transparent)}
.drawer-cta{padding:1rem clamp(1.2rem,4vw,3rem);display:flex;gap:.6rem;flex-wrap:wrap}
.drawer-cta-center{justify-content:center}

/* breadcrumb */
.breadcrumb{padding:1rem 0;font-family:'Outfit',monospace;font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);display:flex;gap:.5rem;flex-wrap:wrap}
.breadcrumb a{color:color-mix(in srgb,var(--ink) 55%,transparent);transition:color .15s}
.breadcrumb a:hover{color:var(--ink)}

/* hero produit (accueil) */
/* Fond gris foncé fixe (indépendant du thème) pour détacher visuellement le
   hero de la section "Produits phares" qui suit. On réassigne localement les
   tokens de thème : tous les composants enfants (badges, boutons, carrousel)
   restent lisibles sans dupliquer leurs règles. */
#hero{
  position:relative; overflow:hidden;
  display:flex; align-items:center;
  /* Le hero doit tenir entier à l'écran sans scroll, sur toutes les tailles :
     100dvh (hauteur réelle visible, fiable sur mobile où 100vh inclut la
     zone masquée par la barre d'adresse) moins la hauteur réelle du header
     (--header-h, mesurée en JS — voir initSite() dans site.js — puisqu'elle
     varie selon le contenu et le point de rupture). 45rem reste le filet de
     sécurité si dvh/var ne sont pas supportés. */
  min-height:45rem;
  min-height:calc(100dvh - var(--header-h, 4.5rem));
  padding:3rem 0;
  background:#000; color:var(--ink);
  --bg:#000; --ink:#f4f4ef; --dim:#9a9a95;
  --line:rgba(255,255,255,.16); --line2:rgba(255,255,255,.09);
  --glass:rgba(255,255,255,.05); --grid-line:rgba(255,255,255,.05);
  --surface:#242423; --surface-2:#2c2c2a; --overlay-bg:rgba(0,0,0,.55);
}
:root[data-theme="light"] #hero{
  background:#fff; color:#0d0d0d;
  --bg:#fff; --ink:#0d0d0d; --dim:#5a5a56;
  --line:rgba(0,0,0,.18); --line2:rgba(0,0,0,.11);
  --glass:rgba(0,0,0,.035); --grid-line:rgba(0,0,0,.06);
  --surface:#f5f4f0; --surface-2:#ebeae4; --overlay-bg:rgba(255,255,255,.7);
}
/* Desktop : on laisse la section suivante apparaître en bas d'écran (le hero
   ne doit pas occuper 100% de la hauteur visible, pour inciter au scroll). */
@media(min-width:64rem){
  #hero{ min-height:calc(100dvh - var(--header-h, 4.5rem) - 6rem); }
}
#heroGridBg{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none}
#hero>.wrap{position:relative;z-index:1}
.hero-copy{max-width:100rem;margin:0 auto;text-align:center}
.hero-copy h1{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:clamp(2.3rem,5vw,3.8rem);line-height:1.03;letter-spacing:.005em;margin:.6rem 0 1rem}
.hero-copy h1 .accent{color:var(--accent)}
.hero-copy .lead{max-width:40rem;margin:0 auto 1.6rem}
.hero-ctas{display:flex;gap:.8rem;flex-wrap:wrap;justify-content:center;margin-bottom:1.8rem}
/* Grille 1fr/auto/1fr plutôt que flex+justify-content:center : avec flex, le
   trait se retrouve au milieu du BLOC (les 2 textes + le trait) une fois ce
   bloc centré — donc décalé du vrai centre de la page dès que "En 15
   minutes" et "Sous 1H" n'ont pas la même largeur (ce qui est le cas). Deux
   colonnes 1fr symétriques encadrant le trait garantissent que lui reste au
   centre géométrique réel, quelle que soit la largeur de chaque texte. */
.hero-badges{display:grid;grid-template-columns:1fr auto 1fr;align-items:center}
.hero-badges div{display:flex;flex-direction:column;gap:.2rem;padding:0 1.2rem;text-align:center}
.hero-badges div:nth-child(1){justify-self:end}
.hero-badges div:nth-child(3){justify-self:start}
/* Séparateur dédié à hauteur fixe (comme le trait de l'indicateur de scroll)
   plutôt qu'un border-left calé sur la hauteur du bloc voisin : ce dernier
   dépendait du nombre de lignes de chaque côté (ex. "En 15 minutes" vs
   "Sous 1H"), donc pas toujours bien centré verticalement d'un bloc à
   l'autre. flex align-items:center sur .hero-badges le centre. */
/* align-self:stretch plutôt qu'une hauteur fixe en rem : une valeur devinée
   ne matchait pas exactement la hauteur réelle du bloc "k+v" une fois les
   vraies polices (Outfit/Archivo, ascent/descent différents) chargées en
   prod — visuellement pas centré malgré align-items:center sur la ligne. En
   s'étirant sur toute la hauteur de la ligne (donc du bloc le plus haut des
   deux), le trait colle exactement aux deux blocs, quelle que soit la
   police réellement rendue. */
.hero-badges-sep{width:0.0625rem;align-self:stretch;background:var(--accent);flex:none}
.hero-badges .k{font-family:'Outfit',monospace;font-size:.58rem;letter-spacing:.14em;text-transform:uppercase;color:var(--ink)}
.hero-badges .v{font-family:'Archivo',sans-serif;font-weight:500;font-size:.8rem;color:var(--ink)}
/* Indicateur de scroll — fine ligne verticale en bas du hero (piste discrète
   + un segment accent qui coule doucement du haut vers le bas en boucle),
   avec le mot "Scroll" centré dessous. */
.hero-scroll-cue{position:absolute;left:50%;bottom:1.2rem;transform:translateX(-50%);z-index:2;display:flex;flex-direction:column;align-items:center;gap:.5rem;opacity:.8;transition:opacity .2s}
.hero-scroll-cue:hover{opacity:1}
.hero-scroll-track{display:block;width:0.0625rem;height:2.6rem;background:var(--line2);overflow:hidden;position:relative}
.hero-scroll-line{position:absolute;left:0;top:-40%;width:100%;height:40%;background:var(--accent);animation:heroScrollFlow 2.1s ease-in-out infinite}
@keyframes heroScrollFlow{0%{top:-40%}100%{top:100%}}
@media(prefers-reduced-motion:reduce){.hero-scroll-line{animation:none;top:0;height:100%;background:var(--accent)}}
.hero-scroll-label{font-family:'Outfit',monospace;font-size:.6rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ink)}
/* Apparition cinématique du texte du hero — fondu + léger flou qui se
   résorbe, en cascade (chaque bloc démarre après le précédent), au lieu du
   .reveal générique (déclenché au scroll, inutile ici puisque le hero est
   déjà visible au chargement). */
.hero-cine{opacity:0;animation:heroCineIn 1.15s cubic-bezier(.16,.8,.24,1) both}
.hero-cine1{animation-delay:.05s}
.hero-cine2{animation-delay:.3s}
.hero-cine3{animation-delay:.52s}
.hero-cine4{animation-delay:.72s}
@keyframes heroCineIn{from{opacity:0;transform:translateY(1.4rem);filter:blur(0.375rem)}to{opacity:1;transform:none;filter:blur(0)}}
@media(prefers-reduced-motion:reduce){.hero-cine{animation:none;opacity:1}}
/* Le header est sticky (hauteur variable, mesurée en JS → --header-h,
   site.js) : sans ce scroll-margin, l'ancre #produits scrollait pile sous le
   bord du viewport, mais le header sticky venait ensuite recouvrir le haut
   de la section — d'où l'impression d'un scroll "un peu trop bas". */
#produits{position:relative;overflow:hidden;scroll-margin-top:var(--header-h,4.5rem)}
#popParticles{position:absolute;inset:0;z-index:0;pointer-events:none}
#produits>.wrap{position:relative;z-index:1}

/* grille produits phares */
.pgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin-top:1.6rem}
@media(max-width:64rem){.pgrid{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* 2 colonnes jusqu'en bas — évite le mur d'une seule carte par ligne (mega
   scroll) sur mobile, pour "produits phares" (accueil), "voir aussi" (fiche
   produit) et la grille produit d'une page famille, qui partagent .pgrid. */
@media(max-width:44rem){.pgrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem}}
.pgrid-more{display:flex;justify-content:center;margin-top:2rem}
.p-card{border:0.0625rem solid var(--line2);border-radius:.9rem;background:var(--glass);overflow:hidden;display:flex;flex-direction:column;text-align:left;transition:box-shadow .25s,transform .25s,background-color .35s ease,border-color .35s ease}
.p-card:hover{box-shadow:0 0 2.5rem color-mix(in srgb,var(--accent) 30%,transparent);transform:translateY(-0.1875rem)}
.p-card .photo-slot{border-radius:0;border:none}
.p-body{padding:.65rem .7rem .65rem .9rem;display:flex;align-items:center;justify-content:space-between;gap:.6rem}
.p-body-text{display:flex;flex-direction:column;gap:.25rem;min-width:0}
.p-body h3{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:.88rem;line-height:1.2}
/* Prix indicatif retiré partout (cards produits ET cards produits-création) —
   display:none plutôt que ne plus le générer côté JS : plus simple, et
   réversible d'un coup si besoin. */
.p-price{display:none;font-family:'Outfit',monospace;font-size:.64rem;letter-spacing:.03em;color:var(--accent)}
.creation-card .p-price{order:2;margin-top:-.3rem}
.p-go{width:1.9rem;height:1.9rem;border-radius:50%;border:0.05rem solid var(--line2);display:flex;align-items:center;justify-content:center;transition:background .2s,border-color .2s;flex:none}
.p-go svg{width:.8rem;height:.8rem;stroke:var(--ink)}
.p-card:hover .p-go,.creation-card:hover .p-go{background:var(--accent);border-color:var(--accent)}
.p-card:hover .p-go svg,.creation-card:hover .p-go svg{stroke:var(--accent-ink)}
/* Placé APRÈS les règles .p-go non-conditionnelles ci-dessus : à
   spécificité égale (un seul sélecteur de classe), c'est l'ordre dans la
   feuille qui tranche, pas le fait d'être dans un @media — une version
   précédente de ce bloc placée avant .p-go{display:flex} se faisait donc
   silencieusement écraser, y compris sur mobile. */
@media(max-width:44rem){
  /* Flèches retirées sur toutes les cards (produits phares, voir aussi,
     familles, produits création) — elles prenaient trop de place pour
     l'apport visuel sur un petit écran. */
  .p-go{display:none}
  /* Les familles ont désormais une vraie illustration éditable depuis le
     Studio (voir catalogue.html) — même traitement que les cards création
     ci-dessous : ne garder que photo + titre sur mobile, la description
     (texte plus long pour une famille que pour un produit) écrasait sinon
     la photo dans l'espace restant du carré au lieu de la laisser occuper
     tout le bloc. */
  #familyGrid .creation-card p,
  #creationGrid .creation-card p{display:none}
  /* Photo en plein cadre, bord à bord, comme les cards produits d'impression
     (.p-card) — le padding uniforme du desktop laissait un petit carré
     inséré avec beaucoup de vide noir autour au lieu de remplir le bloc. */
  #familyGrid .creation-card,
  #creationGrid .creation-card{padding:0;gap:0}
  #familyGrid .creation-card .photo-slot,
  #creationGrid .creation-card .photo-slot{border-radius:0}
  /* Même taille de titre que les cards produits d'impression (.p-body h3,
     .88rem) — la police par défaut (1.05rem) était plus grosse et détonnait
     visuellement entre les deux pages sur mobile. */
  #familyGrid .creation-card h3,
  #creationGrid .creation-card h3{padding:.65rem .8rem;font-size:.88rem}
}

/* bandeau réassurance — hauteur doublée : sert aussi de respiration statique
   entre creation-band (vidéo) et about-sec (fond animé du cube). */
#trust{position:relative;background:var(--glass);border-top:0.0625rem solid var(--line2);border-bottom:0.0625rem solid var(--line2);padding:clamp(3.2rem,7vh,4.4rem) 0}
/* Texture de fond — grille de petits points, en retrait derrière .trust-row
   (z-index) pour rester une simple respiration visuelle, pas un motif qui
   concurrence les pictos. */
#trust::before{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px,color-mix(in srgb,var(--ink) 18%,transparent) 1px,transparent 0);
  background-size:18px 18px;
  /* Fade du centre vers les bords — sans ça la grille de points est visible
     jusqu'au bord du bandeau, ce qui la rend trop présente. */
  mask-image:radial-gradient(ellipse at center,#000 0%,#000 35%,transparent 85%);
  -webkit-mask-image:radial-gradient(ellipse at center,#000 0%,#000 35%,transparent 85%);
}
.trust-row{position:relative;z-index:1}
.trust-row{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;text-align:center}
.trust-item{display:flex;flex-direction:column;align-items:center;gap:.5rem;position:relative}
/* Petites barres verticales oranges entre les points, desktop uniquement
   (voir media query ci-dessous pour leur retrait sur mobile, remplacées par
   un peu de padding entre les deux lignes de pictos). */
.trust-item:not(:first-child)::before{content:"";position:absolute;left:-.5rem;top:20%;bottom:20%;width:0.0625rem;background:var(--accent);opacity:.45}
@media(max-width:44rem){
  .trust-row{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:1.8rem}
  .trust-item:not(:first-child)::before{display:none}
}
.trust-item svg{width:1.6rem;height:1.6rem;stroke:var(--accent);fill:none;stroke-width:1.3;stroke-linecap:round;stroke-linejoin:round;overflow:visible}
.trust-item b{font-family:'Archivo',sans-serif;font-weight:500;font-size:.8rem}

/* Chaque picto a désormais sa propre animation (plus un pulse générique
   identique partout) — cohérente avec ce que l'icône représente. */

/* 1. Devis en 15 minutes — les aiguilles tournent, littéralement le temps
   qui file. */
.trust-clock-hands{transform-origin:12px 12px;animation:trustClockSpin 3s linear infinite}
@keyframes trustClockSpin{to{transform:rotate(360deg)}}

/* 2. BAT en 1 heure — l'éclair à l'intérieur du document clignote comme un
   flash, pour l'idée de rapidité/validation express. */
.trust-bat-bolt{transform-origin:12px 12px;animation:trustBoltFlash 1.8s ease-in-out infinite}
@keyframes trustBoltFlash{0%,60%,100%{opacity:1;transform:scale(1)}75%{opacity:.25;transform:scale(.85)}90%{opacity:1;transform:scale(1.08)}}

/* 3. Vérification & correction fichiers — la coche se dessine, comme un
   contrôle qui vient de passer. */
.trust-check-mark{stroke-dasharray:12;stroke-dashoffset:12;animation:trustCheckDraw 2.8s ease-in-out infinite}
@keyframes trustCheckDraw{0%,15%{stroke-dashoffset:12}55%,85%{stroke-dashoffset:0}100%{stroke-dashoffset:-12}}

/* 4. Suivi personnalisé — un anneau qui respire autour de la silhouette,
   comme une attention qui reste braquée sur le client. */
.trust-follow-ring{transform-origin:12px 9px;animation:trustFollowPulse 2.4s ease-in-out infinite}
@keyframes trustFollowPulse{0%,100%{transform:scale(1);opacity:.35}50%{transform:scale(1.12);opacity:.9}}

@media(prefers-reduced-motion: reduce){
  .trust-clock-hands,.trust-bat-bolt,.trust-check-mark,.trust-follow-ring{animation:none}
}

/* bandeau création (accueil) */
/* Vidéo en fond plein cadre, contenu en overlay — mêmes tokens forcés clairs
   que #hero (fond fixe, indépendant du thème). */
.creation-band{position:relative;overflow:hidden;min-height:50rem;display:flex;align-items:center;padding:clamp(3rem,8vh,5rem) 0;border-bottom:0.0625rem solid var(--line2);
  --ink:#f4f4ef; --dim:#c9c9c4; color:var(--ink)}
.cb-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.cb-scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(100deg,rgba(0,0,0,.55) 0%,rgba(0,0,0,.4) 40%,rgba(0,0,0,.15) 100%)}
.cb-content{position:relative;z-index:2;max-width:100rem;width:100%}
.cb-text .h2{line-height:1.08}
.cb-text .lead{margin-top:.6rem;max-width:46rem}
.cb-content .btn{margin-top:1.4rem;flex:none}
/* Bande vidéo moitié moins haute sur mobile : texte relevé en haut, bouton
   posé en bas et centré (au lieu du bloc unique centré verticalement), pour
   que la vidéo se voie encore malgré la hauteur réduite. */
@media(max-width:40rem){
  .creation-band{min-height:25rem;padding:1.6rem 0;align-items:stretch}
  .creation-band>.wrap{display:flex}
  .cb-content{height:100%;display:flex;flex-direction:column;justify-content:space-between;align-items:center;text-align:center}
  .cb-content .btn{margin-top:0}
}


/* section "qui sommes-nous" (accueil, avant le footer) */
/* Fond "Silk" toujours sombre (indépendant du thème du site, comme #hero et
   .creation-band) — le texte reste donc forcé en tons clairs ici, sinon il
   passerait en encre sombre (thème clair) sur un fond qui, lui, ne change
   pas de tonalité, et deviendrait illisible. */
.about-sec{position:relative;overflow:hidden;padding:clamp(2.8rem,6vh,4.2rem) 0;border-top:0.0625rem solid var(--line2);
  --ink:#f4f4ef; --dim:#c9c9c4; --line2:rgba(255,255,255,.14); color:var(--ink)}
/* +25% de hauteur sur desktop uniquement (mobile empile le bloc photo et le
   texte, donc la hauteur y suit déjà le contenu — pas concerné), puis +25%,
   +30%, puis +20% supplémentaires (soit +144% au total par rapport à
   l'originale). */
@media(min-width:56.01rem){.about-sec{padding:clamp(6.825rem,14.625vh,10.2375rem) 0}}
/* 3 blocs (cube, en-tête "Qui sommes-nous"+titre, paragraphe) placés via
   grid-template-areas plutôt que "order" — on ne veut réordonner QUE
   l'en-tête au-dessus du cube sur mobile, pas le paragraphe qui doit lui
   rester en dessous, et "order" seul ne peut pas viser un enfant en
   particulier de .about-text (il aurait fallu déplacer les 3 blocs ensemble). */
.about-grid{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);grid-template-areas:"media heading" "media text";gap:clamp(1.6rem,4vw,3rem);align-items:center}
.about-media{grid-area:media}
.about-heading{grid-area:heading}
.about-text{grid-area:text}
@media(max-width:56rem){
  .about-grid{grid-template-columns:minmax(0,1fr);grid-template-areas:"heading" "media" "text"}
}
.about-media .photo-slot{border-radius:.9rem}
/* Fond "Silk" (Three.js, porté depuis V2.html) sur TOUTE la section — un
   seul canvas/une seule scène, qui contient aussi le cube de verre
   (repositionné en JS pour rester visuellement dans .photo-slot). */
#aboutScene{position:absolute;inset:0;z-index:0}
#aboutScene canvas{position:absolute;inset:0;width:100%!important;height:100%!important}
.about-media .photo-slot{background:none;border:none}
/* Zone d'accroche du cube resserrée sur sa taille réelle (pas tout le bloc
   photo, largement vide) : sur mobile, un doigt qui touchait n'importe où
   dans .photo-slot en scrollant accrochait le cube au lieu de laisser
   défiler la page. */
#aboutCubeHit{position:absolute;left:50%;top:50%;width:42%;height:42%;transform:translate(-50%,-50%);cursor:grab;touch-action:none;z-index:2}
#aboutCubeHit:active{cursor:grabbing}
/* Fallback masqué par défaut : réaffiché en JS (classe .no-3d) si le rendu
   Three.js échoue (WebGL indisponible), pour ne jamais laisser un bloc vide. */
.about-media .photo-slot svg,.about-media .photo-slot .ph-label{opacity:0}
.about-media .photo-slot.no-3d{background:var(--surface);border:0.0625rem dashed color-mix(in srgb,var(--ink) 16%,transparent)}
.about-media .photo-slot.no-3d svg,.about-media .photo-slot.no-3d .ph-label{opacity:1}
.about-text h2{margin:.6rem 0 1rem}
.about-text .lead{max-width:34rem}

/* bande CTA finale (slim) */
.cta-slim{padding:2.2rem 0;border-bottom:0.0625rem solid var(--line2);background:var(--surface)}
.cta-slim-row{display:flex;align-items:center;justify-content:space-between;gap:1.4rem;flex-wrap:wrap}
.cta-slim-row p{font-family:'Outfit',sans-serif;font-weight:300;font-size:.85rem;color:color-mix(in srgb,var(--ink) 60%,transparent)}
.cta-slim-row .btns{display:flex;gap:.7rem;flex-wrap:wrap}

/* footer sitemap — simple séparation par un filet, pas de fond plein pour rester discret.
   2 zones : copyright à gauche, mentions légales à droite (canaux de contact → header). */
footer{border-top:0.0625rem solid var(--line2);margin-top:auto;flex:none}
.foot-row{padding:1.3rem 0;display:flex;align-items:center;justify-content:center;gap:.8rem}
/* Toujours sur une seule ligne, même mobile — plus de flex-direction:column
   qui les empilait sous 48rem. Le filet vertical entre les deux (border-left
   sur .foot-ml) fait office de séparateur, quel que soit l'alignement. */
.foot-ml{font-family:'Outfit',monospace;font-size:.76rem;color:color-mix(in srgb,var(--ink) 60%,transparent);transition:color .15s;white-space:nowrap;border-left:0.0625rem solid var(--line2);padding-left:.8rem}
.foot-ml:hover{color:var(--accent)}
.fcopy{font-family:'Outfit',sans-serif;font-weight:300;font-size:.7rem;color:var(--dim)}

/* page produit */
/* Sur mobile, le padding standard de .wrap (plancher 1.2rem) laisse le
   contenu de la fiche produit (galerie, configurateur, "voir aussi"…) trop
   proche des bords de l'écran — on l'aère un peu, ici seulement. */
@media(max-width:40rem){#pp-root .wrap{padding-left:1.7rem;padding-right:1.7rem}}
.pp-head{padding:1.2rem 0 clamp(1.4rem,3vh,2rem)}
.pp-head h1{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:clamp(1.9rem,4vw,3rem);line-height:1.05;margin:.5rem 0 .6rem}
.price-badge{display:inline-flex;align-items:center;gap:.4rem;font-family:'Outfit',monospace;font-size:.72rem;letter-spacing:.03em;color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);border:0.05rem solid var(--accent-line);border-radius:2rem;padding:.4rem .9rem;margin-bottom:.9rem}
.price-badge strong{font-weight:600;font-size:.85rem}
.price-badge-side{display:flex;width:100%;border-radius:.7rem;padding:.9rem 1.1rem;margin-bottom:1rem}
/* #cfgPriceBadge vit dans .pp-panel (grille), juste avant le bouton panier —
   grid-column:1/-1 pour occuper toute la largeur comme .cfg-full, et rester
   juste au-dessus du bouton "Ajouter au panier" quelle que soit la taille
   d'écran (ordre naturel du DOM, pas de réordonnancement desktop). */
#cfgPriceBadge{grid-column:1/-1}
.price-badge-side span{margin-left:auto;font-family:'Outfit',sans-serif;font-size:.62rem;letter-spacing:0;text-transform:none;color:var(--dim)}
.pp-tagline{font-family:'Outfit',sans-serif;font-weight:400;font-size:1.05rem;color:var(--ink);margin-bottom:.6rem;max-width:44rem}
.pp-about{font-family:'Outfit',sans-serif;font-weight:300;font-size:.9rem;line-height:1.65;color:color-mix(in srgb,var(--ink) 62%,transparent);max-width:50rem}
.pp-grid{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:clamp(1.6rem,4vw,3rem);padding:0 0 clamp(2.6rem,6vh,4rem)}
@media(max-width:56rem){.pp-grid{grid-template-columns:minmax(0,1fr)}}
.pp-gallery .photo-slot{border-radius:.9rem}
.pp-gallery-main{aspect-ratio:4/3;margin-bottom:.6rem}
.pp-thumbs{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.6rem}
.pp-thumbs .photo-slot{aspect-ratio:1/1;border-radius:.5rem}
.pp-thumbs .pp-thumb{cursor:pointer;padding:0;transition:border-color .2s,opacity .2s;opacity:.6}
.pp-thumbs .pp-thumb:hover{opacity:.9;border-color:var(--accent-line)}
.pp-thumbs .pp-thumb.active{opacity:1;border-style:solid;border-color:var(--accent)}
.pp-panel{display:grid;grid-template-columns:minmax(0,1fr);gap:.6rem .7rem}
@media(min-width:36rem){.pp-panel{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.pp-trust{margin-top:1.2rem;display:flex;align-items:center;flex-wrap:nowrap;overflow-x:auto}
.pp-trust li{list-style:none;display:flex;align-items:center;gap:.4rem;font-family:'Outfit',sans-serif;font-size:.74rem;color:color-mix(in srgb,var(--ink) 60%,transparent);padding:.2rem .8rem;white-space:nowrap;flex:none}
.pp-trust li:first-child{padding-left:0}
.pp-trust li+li{border-left:0.0625rem solid var(--line2)}
.pp-trust svg{width:.85rem;height:.85rem;stroke:var(--accent);flex:none}
/* Sur mobile, 3 items en scroll horizontal masquaient les deux derniers sans
   swiper — empilés verticalement (une ligne chacun), tout est visible d'un
   coup d'œil, plus de séparateurs verticaux (inutiles en colonne). */
@media(max-width:40rem){
  .pp-trust{flex-direction:column;align-items:flex-start;overflow-x:visible;gap:.5rem}
  .pp-trust li{padding:0;white-space:normal}
  .pp-trust li+li{border-left:none}
}
.pp-note{margin-top:.9rem;font-family:'Outfit',monospace;font-size:.6rem;letter-spacing:.04em;color:var(--dim);line-height:1.6}
.cfg-cart-note-ok{color:var(--accent)}
.cfg-cart-note-ok a{color:inherit;text-decoration:underline}
.cfg-cart-note-err{color:var(--accent)}
.pp-ctas{display:flex;flex-direction:column;gap:.6rem;margin-top:.4rem}
.pp-ctas .btn{justify-content:center;width:100%}
/* Envoi groupé du panier — ferré à droite, largeur réduite (le formulaire de
   coordonnées juste au-dessus fait déjà office de contexte, la CTA n'a pas
   besoin de courir sur toute la largeur). */
.cart-submit-row{display:flex;justify-content:flex-end;margin-top:.4rem}
.cart-submit-row .btn{width:25%;min-width:8.5rem;justify-content:center}

.cross-sec{padding:clamp(2.4rem,5vh,3.4rem) 0;border-top:0.0625rem solid var(--line2)}
/* ── configurateur embarqué (page produit) — grille 2 colonnes pour réduire
   le scroll : les groupes courts (choix simples) se placent côte à côte,
   les groupes plus longs (dimensions, quantité, fichier, coordonnées…)
   gardent toute la largeur. ── */
.cfg-step{grid-column:1/-1;border:0.0625rem solid var(--line2);border-radius:.6rem;background:var(--glass);padding:.65rem .8rem;transition:box-shadow .2s,border-color .2s,background-color .35s ease}
.cfg-step.cfg-step-half{grid-column:span 1}
.cfg-step.cfg-step-lastodd{grid-column:1/-1}
.cfg-full{grid-column:1/-1;border:none;background:none;padding:0}
.cfg-step.cfg-step-err{box-shadow:inset .1875rem 0 0 var(--accent);border-color:var(--accent-line)}
.cfg-title{display:flex;align-items:baseline;gap:.4rem;font-family:'Outfit',sans-serif;font-weight:700;font-size:.8rem;color:var(--accent);margin-bottom:.4rem}
.cfg-req{color:var(--accent);font-size:.85rem}
.cfg-pills{display:flex;flex-wrap:wrap;gap:.35rem}
.cfg-pill{font-family:'Outfit',sans-serif;font-size:.74rem;color:color-mix(in srgb,var(--ink) 78%,transparent);background:var(--surface);border:0.05rem solid var(--line2);border-radius:2rem;padding:.38rem .75rem;transition:border-color .15s,background .15s,color .15s}
.cfg-pill:hover{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}
.cfg-pill.sel{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.cfg-dims{display:flex;gap:.7rem;flex-wrap:wrap}
.cfg-field{display:flex;flex-direction:column;gap:.35rem}
.cfg-field label{font-family:'Outfit',monospace;font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;color:var(--dim)}
.cfg-input{background:var(--surface);border:0.0625rem solid var(--line2);border-radius:.5rem;padding:.45rem .7rem;font-family:'Outfit',sans-serif;font-size:.83rem;color:var(--ink);outline:none;transition:border-color .2s,background-color .35s ease,color .35s ease;width:8rem}
.cfg-input:focus{border-color:var(--accent)}
.cfg-qty-custom{display:flex;align-items:center;gap:.5rem;margin-top:.45rem;flex-wrap:wrap}
.cfg-qty-custom .cfg-input{width:9rem}
.cfg-qty-custom span{font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;color:var(--dim)}
.cfg-file{border-radius:.6rem}
.cfg-file-drop{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;width:100%;padding:2.2rem 1.2rem;border:0.09rem dashed var(--line);border-radius:.8rem;cursor:pointer;text-align:center;transition:border-color .2s,background .2s}
.cfg-file-drop:hover{border-color:var(--accent)}
.cfg-file.drag .cfg-file-drop{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent)}
.cfg-file-drop svg{width:2.1rem;height:2.1rem;stroke:var(--accent)}
.cfg-file-drop-title{font-family:'Outfit',sans-serif;font-weight:500;font-size:.88rem;color:var(--ink)}
.cfg-file-drop-sub{font-family:'Outfit',monospace;font-size:.64rem;letter-spacing:.03em;color:var(--dim)}
.cfg-file-list{display:flex;flex-direction:column;gap:.4rem;margin-top:.8rem}
.cfg-file-item{display:flex;align-items:center;gap:.55rem;background:var(--surface);border:0.0625rem solid var(--line2);border-radius:.5rem;padding:.4rem .5rem .4rem .65rem;font-family:'Outfit',sans-serif;font-size:.76rem}
.cfg-file-item svg{width:.9rem;height:.9rem;stroke:var(--accent);flex:none}
.cfg-file-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
.cfg-file-size{color:var(--dim);font-family:'Outfit',monospace;font-size:.64rem;flex:none}
.cfg-file-remove{flex:none;width:1.3rem;height:1.3rem;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--dim);transition:background .15s,color .15s}
.cfg-file-remove:hover{background:var(--accent);color:var(--accent-ink)}
.cfg-file-remove svg{width:.6rem;height:.6rem;stroke:currentColor}
.cfg-contact-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:.6rem;margin-bottom:.5rem}
@media(max-width:26rem){.cfg-contact-row{grid-template-columns:minmax(0,1fr)}}
.cfg-summary{background:var(--surface);border:0.0625rem solid var(--line2);border-radius:.6rem;padding:.65rem .85rem;margin-bottom:.9rem;font-family:'Outfit',sans-serif;font-size:.76rem;color:color-mix(in srgb,var(--ink) 70%,transparent);line-height:1.6}
.cfg-summary b{color:var(--ink);font-weight:500}
.cfg-summary .empty{color:var(--dim);font-style:italic}
.cfg-error{color:#fff;background:#a23a1f;border:0.0625rem solid #c24b2c;border-radius:.5rem;padding:.6rem .8rem;font-size:.78rem;margin-top:.9rem;font-family:'Outfit',sans-serif}
.cfg-success{text-align:center;padding:1rem 0}
.cfg-success .ring{width:3rem;height:3rem;margin:0 auto 1rem;border:0.0625rem solid var(--accent);color:var(--accent);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.2rem}
.cfg-success h3{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:1.2rem;margin-bottom:.5rem}
.cfg-success p{font-family:'Outfit',sans-serif;font-size:.85rem;color:color-mix(in srgb,var(--ink) 65%,transparent);line-height:1.6;margin-bottom:1rem}
.cfg-ref{font-family:'Archivo Black',sans-serif;font-size:1rem;letter-spacing:.02em;color:var(--accent);margin-bottom:1rem}
.pp-success-full{max-width:30rem;margin:0 auto}
.pp-success-ctas{display:flex;gap:.7rem;justify-content:center;flex-wrap:wrap;margin-top:.4rem}
.cart-item-summary{display:flex;flex-direction:column;gap:.25rem;font-family:'Outfit',sans-serif;font-size:.76rem;color:color-mix(in srgb,var(--ink) 70%,transparent);line-height:1.6}
.cart-item-summary b{color:var(--ink);font-weight:500}
.cart-item-summary .empty{color:var(--dim);font-style:italic}

/* ── Panier : #cart-root occupe l'espace restant entre header/footer (voir
   body flex-column sticky-footer) — le panier vide centre son .wrap dans
   cet espace au lieu de rester collé en haut. ── */
#cart-root{display:flex;flex-direction:column;flex:1}
.cart-empty-hero{flex:1;display:flex;align-items:center}
.cart-empty-hero>.wrap{width:100%;text-align:center}
.cart-empty-hero .lead{margin-left:auto;margin-right:auto}

/* ── Panier : cards carrées (photo + caractéristiques), 4 par ligne ── */
.cart-layout{display:flex;flex-direction:column;gap:2.4rem}
.cart-items{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1.2rem}
@media(max-width:64rem){.cart-items{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:44rem){.cart-items{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:28rem){.cart-items{grid-template-columns:minmax(0,1fr)}}
.cart-card{display:flex;flex-direction:column;border:0.0625rem solid var(--line2);border-radius:.9rem;background:var(--glass);overflow:hidden;transition:border-color .2s,background-color .35s ease}
/* 16/10 au lieu du carré d'origine (1/1) : environ -37% de hauteur sur la
   photo, qui domine la hauteur totale de la card. */
.cart-card-photo{aspect-ratio:16/10;border-radius:0;border:none}
.cart-card-body{flex:1;padding:.7rem .85rem .1rem}
.cart-card-body h3{font-family:'Outfit',sans-serif;font-weight:600;font-size:.86rem;color:var(--ink);margin-bottom:.35rem}
.cart-card-actions{display:flex;gap:.5rem;padding:.6rem .85rem .75rem}
.cart-edit-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:.35rem;font-family:'Outfit',monospace;font-size:.6rem;letter-spacing:.04em;text-transform:uppercase;padding:.5rem .5rem;border-radius:.5rem;border:0.05rem solid var(--line2);color:color-mix(in srgb,var(--ink) 75%,transparent);white-space:nowrap;transition:border-color .15s,background .15s,color .15s}
.cart-edit-btn svg{width:.75rem;height:.75rem;stroke:currentColor;flex:none}
.cart-edit-btn:hover{border-color:var(--accent);color:var(--accent)}
/* Croix de suppression — remplace l'ancien bouton "Supprimer" texte, posée
   directement sur la photo (coin haut-droit) pour gagner la hauteur qu'il
   prenait dans .cart-card-actions. */
.cart-remove-x{position:absolute;top:.5rem;right:.5rem;z-index:2;width:1.7rem;height:1.7rem;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--overlay-bg);backdrop-filter:blur(0.25rem);color:var(--accent);transition:background .15s,transform .15s}
.cart-remove-x svg{width:.7rem;height:.7rem;stroke:currentColor}
.cart-remove-x:hover{background:var(--accent);color:var(--accent-ink);transform:scale(1.08)}
.cart-file-contact{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:1.4rem;align-items:start}
@media(max-width:50rem){.cart-file-contact{grid-template-columns:minmax(0,1fr)}}
.cart-file-contact .cfg-step{height:100%}

/* page création */
.creation-hero{padding:clamp(2.4rem,5vh,3.6rem) 0}
.creation-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem;margin-top:1.6rem}
/* 2 colonnes jusqu'en bas (comme .pgrid) — print.html/creation.html listent
   les familles avec cette grille, pas de raison qu'elles retombent seules à
   une colonne unique sur mobile. */
@media(max-width:56rem){.creation-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:.7rem}}
/* aspect-ratio:1/1 sur la card entière (famille comme produit création) — la
   photo n'a plus de ratio fixe (elle prend le reste via flex:1) et le
   descriptif est tronqué à 2 lignes (line-clamp) : sans ça un descriptif
   long étirait la card bien au-delà d'un carré. */
.creation-card{width:100%;aspect-ratio:1/1;overflow:hidden;text-align:left;border:0.0625rem solid var(--line2);border-radius:.9rem;background:var(--glass);padding:1.4rem;display:flex;flex-direction:column;gap:.5rem;transition:box-shadow .25s,border-color .25s,transform .25s,background-color .35s ease}
.creation-card:hover{border-color:var(--accent-line);box-shadow:0 0 2.5rem color-mix(in srgb,var(--accent) 30%,transparent);transform:translateY(-0.1875rem)}
.creation-card .photo-slot{aspect-ratio:auto;flex:1;min-height:0}
.creation-card h3{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:1.05rem;flex:none}
.creation-card p{font-family:'Outfit',sans-serif;font-weight:300;font-size:.82rem;line-height:1.55;color:color-mix(in srgb,var(--ink) 55%,transparent);flex:none;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* outil "Comment préparer mes fichiers" — reprend prep.html (configurateur)
   dans une iframe, en overlay plein écran (adapté depuis configurateur/index.html). */
.vitro-tool-overlay{position:fixed;inset:0;z-index:150;background:var(--modal-overlay);display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .3s;backdrop-filter:blur(1.5rem) saturate(160%);-webkit-backdrop-filter:blur(1.5rem) saturate(160%);padding:1.4rem}
.vitro-tool-overlay.active{opacity:1;pointer-events:auto}
.vitro-tool-card{width:100%;max-width:68rem;height:min(82vh,48rem);background:var(--surface);border:0.0625rem solid var(--line);border-radius:1.1rem;box-shadow:0 1.5rem 3rem var(--shadow);display:flex;flex-direction:column;overflow:hidden;transform:translateY(1.4rem) scale(.97);transition:transform .4s}
.vitro-tool-overlay.active .vitro-tool-card{transform:translateY(0) scale(1)}
.vitro-tool-head{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:1rem;padding:.9rem 1.2rem;border-bottom:0.0625rem solid var(--line);flex:none}
.vitro-tool-head-side{min-width:0}
.vitro-tool-title{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:.9rem;letter-spacing:.01em;color:var(--ink);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vitro-tool-close{justify-self:end;background:transparent;border:0.05rem solid var(--line2);border-radius:6.25rem;color:var(--dim);font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.1em;font-weight:600;padding:.5rem 1rem;cursor:pointer;transition:all .2s;text-transform:uppercase}
.vitro-tool-close:hover{border-color:var(--accent);color:var(--accent)}
.vitro-tool-iframe{flex:1;width:100%;border:0;background:#0c0b0a}
@media(max-width:44rem){
  .vitro-tool-overlay{padding:0}
  .vitro-tool-card{max-width:100%;height:100dvh;border-radius:0}
}
.cfg-file-help{margin-top:.7rem;display:inline-flex;align-items:center;gap:.4rem;background:transparent;border:0.05rem solid var(--line2);border-radius:6.25rem;padding:.55rem 1.1rem;font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);cursor:pointer;transition:all .2s}
.cfg-file-help:hover{border-color:var(--accent);color:var(--accent)}

/* modals (échantillons / info) */
.modal-ov{position:fixed;inset:0;z-index:120;background:var(--modal-overlay);backdrop-filter:blur(.6rem);display:flex;align-items:center;justify-content:center;padding:1.2rem;opacity:0;pointer-events:none;transition:opacity .25s}
.modal-ov.open{opacity:1;pointer-events:auto}
.modal-card{position:relative;width:min(34rem,94vw);max-height:86vh;overflow-y:auto;border:0.0625rem solid var(--line);border-radius:1.1rem;background:var(--surface);padding:2rem;transform:translateY(0.625rem);transition:transform .3s,background-color .35s ease,border-color .35s ease}
.modal-card.modal-wide{width:min(42rem,94vw)}
.modal-ov.open .modal-card{transform:none}
.modal-close{position:absolute;top:.9rem;right:.9rem;z-index:2;width:2.2rem;height:2.2rem;border:0.05rem solid var(--line);border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--overlay-bg);backdrop-filter:blur(0.25rem);transition:transform .25s,border-color .2s}
.modal-close svg{width:.9rem;height:.9rem;stroke:var(--ink);stroke-width:1.5;fill:none;transition:stroke .2s}
.modal-close:hover{border-color:var(--accent);transform:rotate(90deg)}
.modal-close:hover svg{stroke:var(--accent)}
.modal-card h3{font-family:'Archivo Black',sans-serif;text-transform:uppercase;font-size:1.3rem;margin-bottom:.6rem}
.modal-card .kicker{font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.2em;color:var(--dim);text-transform:uppercase;margin-bottom:.5rem}
.modal-card p{font-family:'Outfit',sans-serif;font-weight:300;font-size:.85rem;line-height:1.6;color:color-mix(in srgb,var(--ink) 62%,transparent);margin-bottom:1rem}
/* Mentions légales / politique de confidentialité — même modale à onglets */
.modal-legal{width:min(38rem,94vw);padding-top:3.4rem}
.legal-tabs{display:flex;gap:1.4rem;border-bottom:0.0625rem solid var(--line2);margin-bottom:1.4rem}
.legal-tab{font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);background:none;border:none;padding:0 0 .7rem;cursor:pointer;border-bottom:0.125rem solid transparent;transition:color .2s,border-color .2s}
.legal-tab:hover{color:var(--ink)}
.legal-tab.active{color:var(--ink);border-bottom-color:var(--accent)}
.legal-panel{display:none}
.legal-panel.active{display:block}
.legal-placeholder{color:var(--accent)}
ul.legal-list{list-style:none;margin:0 0 1rem;padding:0}
ul.legal-list li{position:relative;padding:.2rem 0 .2rem 1rem;font-family:'Outfit',sans-serif;font-weight:300;font-size:.85rem;line-height:1.6;color:color-mix(in srgb,var(--ink) 62%,transparent)}
ul.legal-list li::before{content:'';position:absolute;left:0;top:.75rem;width:.25rem;height:.25rem;border-radius:50%;background:var(--dim)}
@media(max-width:40rem){
  .legal-tabs{gap:1rem;margin-bottom:.8rem}
  .legal-tab{font-size:.56rem;padding-bottom:.5rem}
  ul.legal-list li{font-size:.74rem;padding:.15rem 0 .15rem .8rem}
}
.ech-step{display:flex;align-items:center;gap:.7rem;margin:1.1rem 0 .7rem;font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.ech-step span{color:var(--accent);font-weight:500}
.ech-step::after{content:'';flex:1;height:0.0625rem;background:var(--line2)}
.ech-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:.7rem}
@media(max-width:26.25rem){.ech-row{grid-template-columns:minmax(0,1fr)}}
.modal-card label{display:flex;flex-direction:column;gap:.4rem;font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);margin-bottom:.7rem}
.modal-card label em{color:var(--accent);font-style:normal}
.ech-full{grid-column:1/-1}
.modal-card input[type=text],.modal-card input[type=email],.modal-card input[type=tel],.modal-card textarea{width:100%;background:var(--bg);border:0.0625rem solid var(--line2);border-radius:.5rem;padding:.65rem .8rem;font-family:'Outfit',sans-serif;font-weight:300;font-size:.85rem;text-transform:none;letter-spacing:0;color:var(--ink);outline:none;transition:border-color .2s}
.modal-card textarea{min-height:6rem;resize:vertical}
.modal-card input:focus,.modal-card textarea:focus{border-color:var(--accent)}
/* Échantillons (3 étapes) et Nous écrire sont denses — sur mobile on
   resserre padding/tailles/marges pour que tout tienne sans scroll interne
   (max-height:86vh + overflow-y:auto restent le filet de sécurité si un
   très petit écran ne suffit vraiment pas). */
@media(max-width:40rem){
  .modal-ov{padding:.6rem}
  .modal-card{padding:1.1rem .9rem;max-height:96dvh}
  .modal-card h3{font-size:1rem;margin-bottom:.3rem}
  .modal-card .kicker{font-size:.54rem;margin-bottom:.3rem}
  .modal-card p{font-size:.74rem;line-height:1.4;margin-bottom:.5rem}
  .ech-step{margin:.5rem 0 .35rem}
  .ech-row{gap:.4rem}
  .modal-card label{font-size:.56rem;gap:.25rem;margin-bottom:.4rem}
  .modal-card input[type=text],.modal-card input[type=email],.modal-card input[type=tel],.modal-card textarea{padding:.4rem .6rem;font-size:.78rem}
  .modal-card textarea{min-height:3.6rem}
  .ech-submit{margin-top:.5rem;gap:.5rem}
  .ech-rgpd{padding:.6rem;font-size:.62rem}
}

/* ── recherche produits — pas de gros modal-card ici (titre, croix de
   fermeture) : juste le champ, dans une carte compacte. Fermeture au clic en
   dehors (déjà géré par .modal-ov), donc pas besoin de bouton croix dédié. ── */
.search-card{position:relative;width:min(30rem,92vw);background:var(--surface);border:0.0625rem solid var(--line);border-radius:1rem;padding:.9rem;box-shadow:0 1rem 2.5rem var(--shadow);transform:translateY(0.625rem);transition:transform .3s,background-color .35s ease,border-color .35s ease}
.modal-ov.open .search-card{transform:none}
.search-input-row{display:flex;align-items:center;gap:.5rem;border:0.0625rem solid var(--line2);border-radius:.6rem;padding:.7rem 1rem;transition:border-color .2s}
.search-input-row:focus-within{border-color:var(--accent)}
.search-input-row input{flex:1;min-width:0;background:none;border:none;outline:none;font-family:'Outfit',sans-serif;font-size:.9rem;color:var(--ink);text-transform:none;letter-spacing:0}
.search-input-row input::placeholder{color:var(--dim)}
.search-clear{display:none;flex:none;width:1.5rem;height:1.5rem;border-radius:50%;align-items:center;justify-content:center;font-size:1.05rem;line-height:1;color:var(--dim);transition:background .15s,color .15s}
.search-clear:hover{background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent)}
.search-results{display:flex;flex-direction:column;gap:.25rem;max-height:22rem;overflow-y:auto;margin-top:.7rem}
.search-result{display:flex;align-items:baseline;justify-content:space-between;gap:.8rem;padding:.7rem .8rem;border-radius:.5rem;transition:background .15s}
.search-result:hover{background:color-mix(in srgb,var(--accent) 10%,transparent)}
.search-result-name{font-family:'Outfit',sans-serif;font-weight:500;font-size:.88rem;color:var(--ink)}
.search-result:hover .search-result-name{color:var(--accent)}
.search-result-fam{font-family:'Outfit',monospace;font-size:.6rem;letter-spacing:.04em;text-transform:uppercase;color:var(--dim);white-space:nowrap;flex:none}
.search-empty{font-family:'Outfit',sans-serif;font-size:.82rem;color:var(--dim);padding:1.2rem .2rem;text-align:center}
.ech-rgpd{flex-direction:row!important;align-items:flex-start;gap:.7rem;text-transform:none;letter-spacing:0;font-size:.68rem;line-height:1.5;color:var(--dim);border:0.05rem solid var(--line2);border-radius:.5rem;padding:.8rem;cursor:pointer;white-space:normal;min-width:0}
.ech-rgpd input{width:1rem;height:1rem;margin-top:.15rem;flex:none;accent-color:var(--accent)}
.ech-err{color:#fff;background:#a23a1f;border:0.0625rem solid #c24b2c;border-radius:.5rem;padding:.6rem .8rem;font-size:.75rem;margin-top:.8rem}
.ech-submit{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;margin-top:1.2rem}
.ech-note{font-family:'Outfit',monospace;font-size:.62rem;letter-spacing:.06em;color:var(--dim)}
.ech-ring{width:3rem;height:3rem;margin:0 auto 1rem;border:0.0625rem solid var(--accent);color:var(--accent);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:1.2rem}
.ech-submit .btn[disabled]{opacity:.5;pointer-events:none}
