/* =========================================================
   SB SMASH — Design System Premium (Violet graffiti + Gold)
   Palette inspirée du logo officiel : violet street-art sur fond or/ambre.
   ========================================================= */

:root {
  --violet-900: #2E0854;
  --violet-800: #3B0764;
  --violet-700: #4C1D95;
  --violet-600: #5B0FA8;
  --violet: #6A0DAD;
  --violet-500: #7C1FA2;
  --violet-light: #A855F7;
  --violet-lighter: #C084FC;
  --violet-pale: #F3E8FF;
  --violet-pale-2: #FAF5FF;
  --black: #0B0710;
  --ink: #17121F;
  --gray-900: #1F1B2A;
  --gray-700: #4A4459;
  --gray-500: #766F86;
  --gray-300: #C9C2D6;
  --gray-100: #EFEAF7;
  --white: #FFFFFF;
  --gold-dark: #C97B12;
  --gold: #F5A623;
  --gold-light: #FBC969;
  --gold-pale: #FEF3E0;
  --success: #22C55E;
  --danger: #EF4444;
  --info: #38BDF8;

  --radius-sm: 10px;
  --radius: 18px;
  --radius-lg: 28px;
  --radius-full: 999px;

  --shadow-sm: 0 2px 10px rgba(90, 15, 168, 0.08);
  --shadow: 0 10px 30px rgba(90, 15, 168, 0.14);
  --shadow-lg: 0 20px 60px rgba(46, 8, 84, 0.25);
  --shadow-glow: 0 0 0 1px rgba(168, 85, 247, 0.25), 0 20px 45px rgba(106, 13, 173, 0.28);
  --shadow-gold: 0 10px 25px rgba(245, 166, 35, 0.35);

  --grad-violet: linear-gradient(135deg, var(--violet-800) 0%, var(--violet) 45%, var(--violet-light) 100%);
  /* Réservé aux badges/pastilles PARFAITEMENT ronds (border-radius:50%) :
     un dégradé linéaire diagonal, une fois recadré en cercle, laisse deviner
     les angles du carré d'origine (effet "carré incrusté dans le rond").
     Un dégradé radial centré épouse la forme circulaire sans cet artefact. */
  --grad-violet-round: radial-gradient(circle at 35% 30%, var(--violet-light) 0%, var(--violet) 55%, var(--violet-800) 100%);
  --grad-violet-soft: linear-gradient(135deg, var(--violet-light) 0%, var(--violet-lighter) 100%);
  --grad-text: linear-gradient(90deg, var(--violet) 0%, var(--violet-light) 60%, var(--violet-lighter) 100%);
  --grad-gold: linear-gradient(135deg, var(--gold-dark) 0%, var(--gold) 55%, var(--gold-light) 100%);
  --grad-brand: linear-gradient(135deg, var(--violet) 0%, var(--violet-500) 55%, var(--gold) 130%);

  /* Sedgwick Ave (graffiti) pour les titres/affichage uniquement ; le texte
     courant, la navbar et les boutons restent en Inter pour la lisibilité. */
  --font-display: 'Sedgwick Ave', 'Poppins', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Inter', 'Segoe UI', system-ui, sans-serif;

  --header-h: 70px;
  --container: 1280px;
  --transition: all .35s cubic-bezier(.22,1,.36,1);

  --bg: var(--white);
  --bg-alt: #FBF9FE;
  --surface: #FFFFFF;
  --text: var(--ink);
  --text-muted: var(--gray-500);
  --border: rgba(106,13,173,0.12);
  --glass-bg: rgba(255,255,255,0.65);
  --glass-border: rgba(255,255,255,0.4);
}

[data-theme="dark"] {
  --bg: #120A1D;
  --bg-alt: #170D26;
  --surface: #1D1230;
  --text: #FFFFFF;
  --text-muted: #FFFFFF;
  --border: rgba(168,85,247,0.25);
  --glass-bg: rgba(29,18,48,0.6);
  --glass-border: rgba(168,85,247,0.25);
  --gray-100: #241934;
  --violet-pale: #241934;
  --violet-pale-2: #1D1230;
}

/* ---------------------------------------------------------------------
   Mode sombre : tout le texte et toutes les icônes en blanc (mobile + PC),
   pour rester bien lisibles sur les fonds sombres — quelle que soit la
   couleur de marque (violet/or) utilisée en mode clair. Le sélecteur
   :where(...) garde une spécificité nulle sur la liste de balises, pour
   que les exceptions ci-dessous (badges/boutons qui gardent un fond clair
   même en mode sombre) restent faciles à surcharger juste après.
   --------------------------------------------------------------------- */
[data-theme="dark"] :where(
  body, h1, h2, h3, h4, h5, h6, p, span, a, li, label, strong, em, small,
  button, select, textarea, input, td, th, dt, dd, blockquote, figcaption, div
) {
  color: #FFFFFF !important;
}
/* Pas de règle directement sur "svg" : les icônes suivent currentColor et
   héritent donc déjà du blanc via leur conteneur (button/div/a/span
   ci-dessus). Cibler le <svg> lui-même casserait les quelques exceptions
   ci-dessous (l'icône resterait blanche même si son bouton doit garder une
   couleur foncée sur un fond clair). */
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
  color: rgba(255,255,255,.55) !important;
  opacity: 1;
}

/* Couleurs de marque (violet/or) utilisées explicitement sur du texte ou
   des icônes — sans ça elles resteraient foncées malgré le blanc ci-dessus,
   car une couleur posée directement sur l'élément prime sur l'héritage. */
[data-theme="dark"] .eyebrow,
[data-theme="dark"] .btn-secondary,
[data-theme="dark"] .icon-btn:hover,
[data-theme="dark"] .prod-cat-tag,
[data-theme="dark"] .prod-rating .stars,
[data-theme="dark"] .price,
[data-theme="dark"] .info-row .ico,
[data-theme="dark"] .hours-table tr.today td,
[data-theme="dark"] .site-footer a:hover,
[data-theme="dark"] .main-nav a.indicator-target,
[data-theme="dark"] .cart-item-price,
[data-theme="dark"] .testi-stars,
[data-theme="dark"] .add-review-link,
[data-theme="dark"] .add-review-link:hover,
[data-theme="dark"] .review-login-prompt a,
[data-theme="dark"] .step.active .step-label,
[data-theme="dark"] .track-step.done .lbl,
[data-theme="dark"] .track-step.current .lbl {
  color: #FFFFFF !important;
}

/* Exceptions : composants qui gardent volontairement un fond clair même en
   mode sombre (badge, bouton, chip) — le texte (et son icône, héritée via
   currentColor) y reste foncé pour rester lisible sur ce fond clair précis. */
[data-theme="dark"] .fav-btn:not(.active),
[data-theme="dark"] .auth-tabs a.active,
[data-theme="dark"] .modal-gallery-nav {
  color: var(--violet) !important;
}
[data-theme="dark"] .badge-new {
  color: #4A2E00 !important;
}
[data-theme="dark"] .chip-danger {
  color: #B91C1C !important;
}
/* Étoiles du formulaire "Laisser un avis" : le blanc forcé ci-dessus rendait
   les étoiles sélectionnées et non sélectionnées identiques (toutes
   blanches), donc impossible de voir/choisir sa note. On leur redonne leurs
   deux couleurs distinctes (gris-violet clair = non choisie, or = choisie). */
[data-theme="dark"] .star-pick-btn {
  color: var(--border) !important;
}
[data-theme="dark"] .star-pick-btn.active {
  color: #f5a623 !important;
}
/* Cette exception ne doit s'appliquer QUE dans le menu déroulant mobile
   (fond violet pâle au survol/actif, voir plus bas @media max-width:980px)
   — sans la limiter à cette largeur d'écran, elle écrasait aussi le lien
   actif du menu PC (ex : "Accueil"), le rendant quasi invisible sur le fond
   violet foncé du header.
   En mode sombre, --violet-pale devient un violet TRÈS foncé (#241934, voir
   plus haut) : un texte violet--900 (aussi foncé) dessus était quasi
   illisible (violet sur violet). On le remplace par un violet clair, bien
   contrasté sur ce fond sombre. */
@media (max-width: 980px) {
  [data-theme="dark"] .main-nav a:hover,
  [data-theme="dark"] .main-nav a.active {
    color: var(--violet-lighter) !important;
  }
}

/* Supprime le halo/carré bleu que certains navigateurs mobiles (Chrome
   Android notamment) affichent brièvement au clic/tap sur un lien ou un
   bouton — purement cosmétique, la navigation au clavier garde son focus
   visible via :focus-visible plus bas. */
* { -webkit-tap-highlight-color: transparent; box-sizing: border-box; }
:focus:not(:focus-visible) { outline: none; }
html { scroll-behavior: smooth; }
/* Les ancres (#populaires, #localisation…) s'arrêtent sous le header fixe */
section[id] { scroll-margin-top: calc(var(--header-h) + 10px); }
body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  transition: background .4s ease, color .4s ease, opacity .32s ease, transform .32s ease;
  overflow-x: hidden;
}

/* ---------- Transitions de page (façon AnimatePresence, sans React) ----------
   html.page-transitioning est posé par un script bloquant dans <head>, avant
   le premier paint (donc aucun flash) : le body démarre invisible, décalé de
   quelques px, puis app.js retire la classe une fois le DOM prêt -> fondu
   d'entrée. Au clic sur un lien interne, app.js pose html.page-leaving et
   laisse le fondu de sortie jouer avant de naviguer réellement. */
html.page-transitioning body { opacity: 0; transform: translateY(10px); }
html.page-leaving body { opacity: 0; transform: translateY(-10px); transition: opacity .26s ease, transform .26s ease; }
@media (prefers-reduced-motion: reduce) {
  html.page-transitioning body, html.page-leaving body { opacity: 1 !important; transform: none !important; transition: none !important; }
}
h1, h2, h3, h4, h5 { font-family: var(--font-display); margin: 0 0 .5em; line-height: 1.15; font-weight: 700; letter-spacing: -0.01em; }
p { line-height: 1.7; color: var(--text-muted); margin: 0 0 1em; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
/* appearance:none retire le rendu natif du système (certains mobiles/navigateurs
   affichent un bouton non stylé en gris/noir foncé quand le mode sombre du
   système est actif, quelle que soit la couleur CSS demandée) : sans ça, un
   bouton sans fond/couleur explicites — comme "Mode sombre" dans le menu
   mobile — pouvait apparaître comme un pavé noir illisible. */
button { font-family: inherit; cursor: pointer; appearance: none; -webkit-appearance: none; background: none; border: none; color: inherit; }
/* Curseur main sur tout ce qui est cliquable mais n'est ni un <button> (déjà
   couvert ci-dessus) ni un <a> (pointer par défaut du navigateur) — surtout
   des éléments cliqués via JS (delegation sur data-attributes, cartes, etc.). */
[data-open-modal], [role="button"], [onclick] { cursor: pointer; }
ul { list-style: none; margin: 0; padding: 0; }
::selection { background: var(--violet-light); color: white; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.section { padding: 96px 0; }
.section-sm { padding: 56px 0; }
@media (max-width: 900px) { .section { padding: 64px 0; } }

.gradient-text {
  background: var(--grad-text);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--violet); background: var(--violet-pale); padding: 8px 16px; border-radius: var(--radius-full);
  margin-bottom: 16px;
}
[data-theme="dark"] .eyebrow { color: #FFFFFF; }

.section-head { max-width: 640px; margin: 0 auto 56px; text-align: center; }
.section-head h2 { font-size: clamp(28px, 4vw, 42px); }
.section-head.left { margin-left: 0; text-align: left; }

/* ---------- Boutons ----------
   Le texte des boutons reprend la police graffiti utilisée pour le logo
   (Sedgwick Ave) afin de garder le thème "tag à la bombe" jusque dans les
   CTA — taille et espacement légèrement augmentés pour rester lisibles
   malgré le tracé fin et penché du style graffiti. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 30px; border-radius: var(--radius-full); border: none;
  font-family: var(--font-display); font-weight: 400; font-size: 19px; letter-spacing: .015em;
  cursor: pointer; transition: var(--transition);
  white-space: nowrap; position: relative; overflow: hidden;
  /* Retire le rectangle de surbrillance bleu/gris que certains navigateurs
     mobiles (Chrome/Safari Android notamment) affichent par défaut au tap :
     il est carré et ignore le border-radius du bouton, ce qui casse le
     style "pilule". Remplacé juste en dessous par un état :active propre. */
  -webkit-tap-highlight-color: transparent;
}
/* Tous les boutons du site (pas seulement ceux du hero/home) : un léger
   "enfoncement" fluide au clic/tap, cohérent avec le survol déjà en place
   sur chaque variante (.btn-primary, .btn-secondary, etc.). !important pour
   garantir que cet état de clic prenne toujours le dessus, y compris sur
   les boutons du hero qui ont un survol 3D plus complexe et prioritaire. */
.btn:active {
  transform: scale(.96) !important;
  transition: transform .15s cubic-bezier(.4,0,.2,1) !important;
}
/* Anneau de focus rond, jamais en rectangle qui déborde : l'outline générique
   (voir plus bas, a/button/input:focus-visible) n'épouse pas toujours les
   coins arrondis d'une pilule sur tous les navigateurs (surtout Android en
   mode sombre) — on voit alors une "plaque" carrée dépasser du bouton. Le
   box-shadow, lui, suit toujours nativement le border-radius de l'élément,
   donc ne déborde jamais, quel que soit le navigateur. --focus-ring est
   injecté dans le box-shadow de chaque variante (.btn-primary, .btn-secondary…)
   ci-dessous et plus bas dans la version "home-cinematic". */
.btn:focus-visible {
  outline: none;
  --focus-ring: 0 0 0 3px var(--gold), 0 0 0 6px rgba(245,166,35,.35);
}
.btn-primary { background: var(--grad-violet); color: white; box-shadow: 0 10px 25px rgba(106,13,173,.35), var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-primary:hover { transform: translateY(-3px); box-shadow: 0 16px 34px rgba(106,13,173,.45), var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-secondary { background: white; color: var(--violet); border: 1.5px solid var(--violet-light); box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-secondary:hover { background: var(--violet-pale); transform: translateY(-3px); box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
[data-theme="dark"] .btn-secondary { background: transparent; color: #FFFFFF; }
.btn-ghost { background: transparent; color: var(--text); box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-ghost:hover { background: var(--gray-100); box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-dark { background: var(--black); color: white; box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-dark:hover { background: var(--violet-900); transform: translateY(-3px); box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
.btn-sm { padding: 9px 18px; font-size: 16px; }
.btn-lg { padding: 18px 38px; font-size: 21px; }
.btn-block { width: 100%; }
.btn-icon { padding: 12px; border-radius: 50%; }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none !important; }
.btn-outline-white { background: transparent; border: 1.5px solid rgba(255,255,255,.6); color: white; box-shadow: var(--focus-ring, 0 0 0 0 rgba(0,0,0,0)); }
/* Tableau de bord admin : on garde une police lisible et standard sur les
   boutons, la police graffiti est réservée au site public. */
body.admin-body .btn { font-family: var(--font-body); font-weight: 600; font-size: 15px; letter-spacing: normal; }
body.admin-body .btn-sm { font-size: 13px; }
body.admin-body .btn-lg { font-size: 16px; }
.btn-outline-white:hover { background: rgba(255,255,255,.15); }

/* ---------- Glassmorphism ---------- */
.glass {
  background: var(--glass-bg);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid var(--glass-border);
}

/* ---------- Header ---------- */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 500;
  height: var(--header-h); display: flex; align-items: center;
  background: var(--glass-bg); backdrop-filter: blur(16px) saturate(160%); -webkit-backdrop-filter: blur(16px) saturate(160%);
  border-bottom: 1px solid var(--glass-border);
  /* N.B. : on n'anime QUE l'ombre ici (pas background/backdrop-filter/border-color) —
     animer un backdrop-filter sur un header fixed provoque un liseré de rendu
     (bug de compositing Chromium, surtout sous Windows à l'échelle d'affichage
     non-100%). Le passage over-hero <-> solid doit rester un changement net. */
  transition: box-shadow .35s cubic-bezier(.22,1,.36,1);
}
/* Au-dessus du hero (haut de page d'accueil) : header transparent, fondu dans le visuel.
   Détecté en PUR CSS via :has() (":not(.solid)" laisse le scroll reprendre la
   main proprement, sans !important) — aucune dépendance au JS ni au rendu
   serveur pour l'état initial, donc aucun délai/flash possible : c'est vrai
   dès la toute première peinture, avant même que le JS ne s'exécute.
   .over-hero reste en filet de sécurité pour les navigateurs sans :has(). */
.site-header:has(+ .hero):not(.solid),
.site-header.over-hero:not(.solid) {
  background: transparent; border-bottom: none;
  backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none;
}
.site-header:has(+ .hero):not(.solid) .logo .txt,
.site-header.over-hero:not(.solid) .logo .txt { color: white; }
.site-header:has(+ .hero):not(.solid) .icon-btn,
.site-header.over-hero:not(.solid) .icon-btn { background: rgba(255,255,255,.14); color: white; }
.site-header:has(+ .hero):not(.solid) .icon-btn:hover,
.site-header.over-hero:not(.solid) .icon-btn:hover { background: rgba(255,255,255,.26); color: white; }
@media (min-width: 981px) {
  .site-header:has(+ .hero):not(.solid) .main-nav a,
  .site-header.over-hero:not(.solid) .main-nav a { color: rgba(255,255,255,.92); }
  /* Sur le hero transparent, le lien souligné (actif ou survolé) reste en
     blanc plein comme les autres liens : le doré clair utilisé avant se
     fondait dans les tons orangés de l'image de fond et devenait illisible. */
  .site-header:has(+ .hero):not(.solid) .main-nav a.indicator-target,
  .site-header.over-hero:not(.solid) .main-nav a.indicator-target { color: #fff; }
}
.site-header.solid { box-shadow: var(--shadow-sm); }
.header-inner { display: flex; align-items: center; justify-content: space-between; width: 100%; gap: 24px; }
.logo { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-weight: 800; font-size: 28px; }
/* Texte du logo en Sedgwick Ave (style graffiti, comme le logo peint) */
.logo .txt { font-family: 'Sedgwick Ave', var(--font-display), cursive; font-weight: 400; font-size: 30px; letter-spacing: .01em; }
.logo .mark {
  width: 50px; height: 50px; border-radius: 16px;
  /* Finition "or brossé" premium : dégradé plus profond que le simple
     grad-gold, liseré clair en haut, ombre interne chaude en bas. */
  background: linear-gradient(150deg, #FFD95E 0%, #F5A623 52%, #DE8A00 100%);
  border: 1px solid rgba(255, 236, 180, .55);
  display: flex; align-items: center; justify-content: center; color: var(--violet-900); font-size: 23px;
  box-shadow:
    inset 0 1.5px 0 rgba(255,255,255,.55),
    inset 0 -3px 6px rgba(140,70,0,.28),
    var(--shadow-gold);
  transition: transform .35s cubic-bezier(.22,1,.36,1); flex-shrink: 0;
  position: relative; overflow: hidden;
}
/* Variante image (badge rond officiel) : on annule le fond doré/carré, le
   badge se suffit à lui-même. Ombre douce + même rotation au survol. */
.logo .mark.mark-img {
  background: none; border: none; box-shadow: none; border-radius: 50%;
  overflow: visible;
}
.logo .mark.mark-img img {
  width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.35));
}
.logo .mark.mark-img::after { display: none; }
/* Reflet diagonal discret qui traverse le badge au survol */
.logo .mark::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.5) 50%, transparent 70%);
  transform: translateX(-120%); transition: transform .6s cubic-bezier(.22,1,.36,1);
}
.logo:hover .mark::after { transform: translateX(120%); }
@media (prefers-reduced-motion: reduce) { .logo .mark::after { display: none; } }
.logo:hover .mark { transform: rotate(-6deg) scale(1.06); }
/* "SB" (1er span) en doré, "Smash" (2e span) en blanc — demande explicite du
   client sur le texte du logo (header/footer/connexion...), pas sur l'image
   du badge rond qui reste inchangée. Un léger text-shadow sombre garde
   "Smash" lisible même sur le fond clair du header en thème jour (où un
   blanc pur serait invisible sur le fond translucide presque blanc). */
.logo .txt span:first-child { background: var(--grad-gold); -webkit-background-clip: text; background-clip: text; color: transparent; }
.logo .txt span:last-child { color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.4), 0 0 1px rgba(0,0,0,.3); }

/* ---------- Nav (soulignement doré coulissant) ----------
   L'indicateur n'est plus une pastille pleine mais un trait de soulignement
   fin et dégradé qui glisse sous le lien survolé/actif (même JS qu'avant :
   il pilote toujours transform + width, seul le style a changé). */
.main-nav { display: flex; align-items: center; gap: 6px; position: relative; }
.nav-indicator {
  position: absolute; top: auto; bottom: 2px; left: 0; height: 3px; width: 0;
  border-radius: 2px; background: var(--grad-gold);
  box-shadow: 0 1px 8px rgba(245,166,35,.55);
  opacity: 0; z-index: 0; pointer-events: none; will-change: transform, width;
  transition: transform .45s cubic-bezier(.22,1,.36,1), width .45s cubic-bezier(.22,1,.36,1), opacity .3s ease;
}
.nav-indicator.visible { opacity: 1; }
.main-nav a, .main-nav button.nav-only-mobile {
  padding: 8px 14px; border-radius: var(--radius-full); font-weight: 600; font-size: 14px; color: var(--text);
  position: relative; z-index: 1; text-align: left;
  transition: color .4s cubic-bezier(.22,1,.36,1), transform .4s cubic-bezier(.22,1,.36,1);
}
.main-nav a:hover { transform: translateY(-1px); }
/* .indicator-target = lien sous lequel le soulignement est posé (survolé, ou
   actif au repos) : on le teinte en doré pour rappeler le trait. */
.main-nav a.indicator-target { color: var(--gold-dark, #C77800); }
/* Icône devant chaque lien du menu : masquée en version PC (le soulignement
   doré suffit à repérer la page active), affichée en version mobile où le
   menu est une liste verticale — l'icône aide à scanner rapidement. */
.nav-link-ico { display: none; }
@media (max-width: 980px) {
  .nav-indicator { display: none; }
  .nav-link-ico { display: inline-flex; align-items: center; justify-content: center; margin-right: 10px; vertical-align: middle; flex-shrink: 0; }
  .main-nav a, .main-nav button.nav-only-mobile { display: flex; align-items: center; width: 100%; }
}

.header-actions { display: flex; align-items: center; gap: 8px; }
.icon-btn {
  width: 40px; height: 40px; border-radius: 50%; border: none; background: var(--gray-100);
  display: flex; align-items: center; justify-content: center; font-size: 17px; color: var(--text);
  position: relative; transition: var(--transition);
}
.icon-btn:hover { background: var(--violet-pale); color: var(--violet); transform: translateY(-2px); }
.icon-btn .badge {
  position: absolute; top: -4px; right: -4px; background: var(--grad-violet-round); color: white;
  font-size: 10.5px; font-weight: 700; min-width: 19px; height: 19px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; padding: 0 4px; box-shadow: 0 2px 6px rgba(106,13,173,.5);
}
/* #cartBadge / #notifBadge partagent la classe .badge avec les étiquettes
   produit ("Nouveau", "-20%"...), qui elles sont volontairement stylées en
   sticker penché plus bas dans ce fichier (body.home-cinematic .badge :
   position:relative, inclinaison, bordure, animation). Ce compteur-ci n'a
   rien d'une étiquette : on le protège explicitement de ce style pour qu'il
   reste un simple rond de comptage bien calé en haut à droite du bouton,
   quel que soit l'ordre des règles dans le fichier (sélecteur par id, donc
   spécificité maximale). */
#cartBadge, #notifBadge {
  position: absolute !important; rotate: 0deg !important; scale: 1 !important;
  border: none !important; animation: none !important;
}
.burger { display: none; }

/* Search dropdown */
.search-wrap { position: relative; }
.search-panel {
  position: absolute; top: 56px; right: 0; width: 380px; background: var(--surface); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); border: 1px solid var(--border); padding: 18px; opacity: 0; visibility: hidden; transform: translateY(-10px);
  transition: var(--transition); max-height: 70vh; overflow-y: auto;
}
.search-panel.open { opacity: 1; visibility: visible; transform: translateY(0); }
.search-panel input { width: 100%; padding: 13px 16px; border-radius: var(--radius-full); border: 1.5px solid var(--border); background: var(--bg-alt); color: var(--text); font-size: 14px; }
.search-results { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.search-result-item { display: flex; align-items: center; gap: 12px; padding: 8px; border-radius: var(--radius-sm); transition: var(--transition); }
.search-result-item:hover { background: var(--violet-pale); }
.search-result-item img { width: 46px; height: 46px; border-radius: 10px; object-fit: cover; }

/* =====================================================================
   FOND AMBIANT — page d'accueil uniquement (body.home-cinematic)
   ---------------------------------------------------------------------
   Objectif : donner l'impression d'une fine membrane métallique qui
   ondule très lentement derrière tout le contenu, du hero jusqu'au pied
   de page, sans jamais toucher au texte/boutons/cartes (lisibilité et
   clics toujours garantis). Trois idées superposées :
     1. .ambient-gradient (x3) — de grands halos flous qui dérivent très
        lentement (translate + scale, jamais top/left) : le "relief" et
        la "profondeur" de la plaque.
     2. .ambient-sheen — une bande de lumière diagonale, façon reflet
        d'acier brossé, qui balaie doucement l'écran en boucle.
     3. .ambient-noise — un grain SVG (feTurbulence) très subtil et
        semi-transparent qui dérive lentement : la texture "aluminium".
   Tout est position:fixed (donc gratuit au scroll, pas de repaint par
   section) et n'anime que transform/opacity → 100% GPU, aucun jank même
   sur une page longue. C'est ce choix (plutôt qu'une vraie distorsion
   SVG du contenu réel, coûteuse et nuisible à la lisibilité) qui tient
   la promesse "jamais gênant" tout en restant premium.
   ===================================================================== */
.ambient-bg {
  position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  opacity: 0; animation: ambientIn 1.4s cubic-bezier(.16,1,.3,1) forwards;
}
/* Le contenu réel doit toujours passer au-dessus du fond ambiant (scopé à
   la home : sur les autres pages il n'y a pas de .ambient-bg, donc pas
   besoin d'y toucher au stacking context existant). */
/* .site-header, .cart-drawer, .overlay-bg et .modal-bg sont volontairement
   exclus ici : ce sont des éléments position:fixed avec un z-index déjà bien
   au-dessus de l'ambient-bg (z-index:0), et leur appliquer position:relative
   écrasait leur position:fixed — c'est ce qui empêchait le tiroir du panier
   de s'ouvrir sur la page d'accueil. */
body.home-cinematic .section,
body.home-cinematic .section-sm,
body.home-cinematic footer { position: relative; z-index: 1; }

/* Fond graffiti fourni par le client : affiché en filigrane (opacité réduite
   + fusion soft-light) pour garder les textes lisibles par-dessus. */
.ambient-graffiti {
  position: absolute; inset: 0;
  background: url('/img/font.png') center / cover no-repeat;
  opacity: .16; mix-blend-mode: soft-light;
}
.ambient-gradient {
  position: absolute; border-radius: 50%; filter: blur(70px); will-change: transform, opacity;
}
.ambient-gradient.g1 {
  width: 60vw; height: 60vw; top: -15vw; left: -10vw;
  background: radial-gradient(circle, rgba(168,85,247,.30) 0%, transparent 70%);
  animation: ambientDriftA 26s ease-in-out infinite;
}
.ambient-gradient.g2 {
  width: 50vw; height: 50vw; top: 30vh; right: -15vw;
  background: radial-gradient(circle, rgba(245,166,35,.22) 0%, transparent 70%);
  animation: ambientDriftB 32s ease-in-out infinite;
}
.ambient-gradient.g3 {
  width: 45vw; height: 45vw; bottom: -10vw; left: 20vw;
  background: radial-gradient(circle, rgba(106,13,173,.24) 0%, transparent 70%);
  animation: ambientDriftC 38s ease-in-out infinite;
}
@keyframes ambientDriftA {
  0%, 100% { transform: translate3d(0,0,0) scale(1); }
  33%      { transform: translate3d(4vw, 3vh, 0) scale(1.08); }
  66%      { transform: translate3d(-3vw, 5vh, 0) scale(.96); }
}
@keyframes ambientDriftB {
  0%, 100% { transform: translate3d(0,0,0) scale(1); }
  50%      { transform: translate3d(-5vw, -4vh, 0) scale(1.1); }
}
@keyframes ambientDriftC {
  0%, 100% { transform: translate3d(0,0,0) scale(1); }
  50%      { transform: translate3d(4vw, -3vh, 0) scale(1.05); }
}

/* Reflet façon acier brossé : une bande diagonale qui traverse lentement */
.ambient-sheen {
  position: absolute; top: -50%; left: -60%; width: 60%; height: 200%;
  background: linear-gradient(100deg, transparent 40%, rgba(255,255,255,.05) 50%, transparent 60%);
  mix-blend-mode: overlay; will-change: transform;
  animation: ambientSheenSweep 14s ease-in-out infinite;
}
@keyframes ambientSheenSweep {
  0%   { transform: translate3d(-20%, 0, 0); }
  50%  { transform: translate3d(160%, 0, 0); }
  100% { transform: translate3d(-20%, 0, 0); }
}

/* Grain "aluminium" très subtil (SVG feTurbulence en data-URI) */
.ambient-noise {
  position: absolute; inset: -10%; opacity: .035; mix-blend-mode: overlay; will-change: transform;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
  animation: ambientNoiseDrift 22s linear infinite;
}
@keyframes ambientNoiseDrift {
  0%   { transform: translate3d(0,0,0); }
  100% { transform: translate3d(-220px,-220px,0); }
}
@keyframes ambientIn { to { opacity: 1; } }

/* Plaque métallique fine qui ondule vraiment (feTurbulence + feDisplacementMap,
   défini dans index.ejs). C'est la seule couche qui se déforme réellement —
   le reste du fond (dégradés, reflet, grain) ne fait que dériver en transform.
   Toujours purement décoratif : jamais appliqué au texte ni aux cartes. */
.ambient-wave-plate {
  position: absolute; inset: -10%; opacity: .07; mix-blend-mode: soft-light; will-change: filter;
  background: linear-gradient(115deg,
    rgba(255,255,255,.55) 0%, rgba(200,190,255,.25) 18%, rgba(120,60,180,.35) 36%,
    rgba(245,166,35,.3) 54%, rgba(200,190,255,.25) 72%, rgba(255,255,255,.5) 100%);
  filter: url(#metalWaveFilter);
  transform: translateZ(0);
}
@media (max-width: 900px) {
  /* Le filtre SVG animé coûte plus cher qu'un simple dégradé qui dérive :
     on le réserve au desktop et on garde le reste du fond ambiant partout. */
  .ambient-wave-plate { display: none; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative; height: 100vh; min-height: 620px; overflow: hidden; display: flex; align-items: center; padding-top: var(--header-h);
  /* Fond graffiti fourni par le client, en arrière-plan du hero */
  background: url('/img/font.png') center / cover no-repeat;
}
/* Les photos des slides sont masquées (le fond graffiti les remplace) ; on
   garde les slides pour la rotation des textes + leur voile de lisibilité. */
.hero-slide img { display: none; }
.hero-slide { position: absolute; inset: 0; opacity: 0; transition: opacity 1.2s ease; }
.hero-slide.active { opacity: 1; z-index: 2; }
.hero-slide img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.1); }
.hero-slide .overlay { position: absolute; inset: 0; background: linear-gradient(100deg, rgba(20,4,40,.88) 10%, rgba(59,7,100,.55) 55%, rgba(106,13,173,.25) 100%); }
.hero-inner { position: relative; z-index: 5; display: flex; align-items: center; justify-content: space-between; gap: 40px; }
.hero-content { position: relative; z-index: 5; color: white; max-width: 680px; flex: 1 1 auto; }
/* ---------- Entrée cinématographique du hero (3.8s, stagger) ----------
   Un seul rythme visuel pour toute la séquence : fondu + léger déplacement
   vers le haut + scale très subtile + flou qui se dissipe, sur la même
   courbe premium (cubic-bezier(.16,1,.3,1), "expo-out" façon Apple/Linear).
   Ordre : fond (déjà lancé) → formes décoratives → logo → badge → titre →
   sous-titre → boutons → pagination/scroll. Les étapes se chevauchent
   légèrement (comme un vrai stagger, pas une file d'attente) pour rester
   fluide plutôt que mécanique. */
.hero-badge {
  display: inline-flex; align-items: center; gap: 8px; background: rgba(245,166,35,.16); border: 1px solid rgba(245,166,35,.5); color: var(--gold-light); padding: 8px 18px; border-radius: var(--radius-full); font-size: 13px; font-weight: 600; letter-spacing: .05em; margin-bottom: 22px;
  opacity: 0; animation: heroLogoIn .9s cubic-bezier(.16,1,.3,1) 1.1s forwards;
}
.hero-content h1 {
  font-size: clamp(38px, 6vw, 70px); color: white; margin-bottom: 20px;
  opacity: 0; animation: heroLogoIn 1s cubic-bezier(.16,1,.3,1) 1.5s forwards;
}
.hero-content h1 em { font-style: normal; background: linear-gradient(90deg,#F0ABFC,#C084FC); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero-content p {
  color: rgba(255,255,255,.85); font-size: 18px; max-width: 520px; margin-bottom: 34px;
  opacity: 0; animation: heroLogoIn 1s cubic-bezier(.16,1,.3,1) 1.9s forwards;
}
.hero-cta { display: flex; gap: 16px; flex-wrap: wrap; }
/* Flottement bien "funk" une fois posés : bond vertical marqué + léger
   balancement de rotation, chaque bouton avec son propre tempo et déphasé
   (reverse sur le 2e) pour un mouvement organique plutôt qu'un ballet
   synchronisé au carré. Toujours sur "translate"/"rotate" (séparées de
   "transform"), donc aucun conflit avec l'entrée (heroLogoIn) ni le survol
   3D déjà posé sur .btn ailleurs dans ce fichier. */
.hero-cta .btn { opacity: 0; }
.hero-cta .btn:nth-child(1) { animation: heroLogoIn .9s cubic-bezier(.16,1,.3,1) 2.3s forwards, ctaFloat 3.2s ease-in-out 2.3s infinite; }
.hero-cta .btn:nth-child(2) { animation: heroLogoIn .9s cubic-bezier(.16,1,.3,1) 2.45s forwards, ctaFloat 3.7s ease-in-out 2.75s infinite reverse; }
@keyframes ctaFloat {
  0%, 100% { translate: 0 0; rotate: -2deg; }
  50%      { translate: 0 -10px; rotate: 2deg; }
}
.hero-dots {
  position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%); z-index: 6; display: flex; gap: 10px;
  opacity: 0; animation: heroDotsIn .8s cubic-bezier(.16,1,.3,1) 2.7s forwards;
}
.hero-dots button { width: 34px; height: 5px; border-radius: 4px; border: none; background: rgba(255,255,255,.35); transition: var(--transition); }
.hero-dots button.active { background: white; width: 50px; }
@keyframes heroDotsIn { from { opacity: 0; transform: translateX(-50%) translateY(14px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
.hero-scroll {
  position: absolute; bottom: 40px; right: 48px; z-index: 6; color: white; display: flex; flex-direction: column; align-items: center; gap: 10px; font-size: 12px; letter-spacing: .1em;
  opacity: 0; animation: heroScrollIn .8s cubic-bezier(.16,1,.3,1) 3s forwards;
}
@keyframes heroScrollIn { to { opacity: .8; } }
.hero-scroll .line { width: 1.5px; height: 40px; background: rgba(255,255,255,.5); position: relative; overflow: hidden; }
.hero-scroll .line::after { content: ''; position: absolute; top: -100%; left: 0; width: 100%; height: 100%; background: white; animation: scrollLine 2s infinite; }
@keyframes scrollLine { to { top: 100%; } }
@media (max-width: 720px) { .hero-scroll { display: none; } }

/* Formes décoratives du hero (2e étape de la séquence, avant le logo) */
.hero-deco-blob {
  position: absolute; z-index: 0; border-radius: 50%; filter: blur(50px); pointer-events: none;
  opacity: 0;
  animation: heroBlobIn 1s cubic-bezier(.16,1,.3,1) .2s forwards, heroBlobDrift 18s ease-in-out 1.2s infinite;
}
.hero-deco-blob.blob-a { width: 340px; height: 340px; top: 8%; left: 4%; background: radial-gradient(circle, rgba(245,166,35,.28) 0%, transparent 70%); }
.hero-deco-blob.blob-b { width: 280px; height: 280px; bottom: 10%; left: 42%; background: radial-gradient(circle, rgba(240,171,252,.22) 0%, transparent 70%); }
@keyframes heroBlobIn { from { opacity: 0; transform: scale(.7); } to { opacity: 1; transform: scale(1); } }
@keyframes heroBlobDrift { 0%, 100% { transform: translate3d(0,0,0) scale(1); } 50% { transform: translate3d(3vw, -2vh, 0) scale(1.06); } }
@media (max-width: 720px) { .hero-deco-blob { display: none; } }

/* ---------- Hero logo (grand format) ----------
   Entrée + flottement en cubic-bezier(.16,1,.3,1) ("expo-out" premium, la
   courbe utilisée par Linear/Framer pour un rendu très lisse — sans overshoot
   ni rebond mécanique). Le tilt qui suit la souris (hero-logo-tilt) est piloté
   par home.js via un lerp sur requestAnimationFrame : c'est ce qui donne la
   sensation "spring" d'une lib comme framer-motion, en vanilla JS pur. */
.hero-logo-wrap {
  position: relative; flex: 0 0 auto; width: min(58vw, 740px); max-width: 740px;
  display: flex; align-items: center; justify-content: center;
  perspective: 1400px;
  opacity: 0; transform: translateY(34px) scale(.85) rotate(-32deg);
  filter: blur(6px);
  /* Entrée dédiée (pas heroLogoIn, partagée avec le badge/titre/etc.) : le
     logo arrive en tournant sur lui-même avant de se stabiliser à plat. */
  animation: heroLogoSpinIn 1.4s cubic-bezier(.16,1,.3,1) .7s forwards;
}
.hero-logo-glow {
  position: absolute; inset: -10%; z-index: 0;
  background: radial-gradient(circle, rgba(245,166,35,.35) 0%, rgba(168,85,247,.22) 45%, transparent 72%);
  filter: blur(30px); border-radius: 50%;
  opacity: 0;
  animation: heroGlowIn .9s cubic-bezier(.16,1,.3,1) .45s forwards, heroGlowPulse 6s cubic-bezier(.45,0,.55,1) 1.35s infinite;
}
.hero-logo-tilt {
  position: relative; z-index: 1; width: 100%; transform-style: preserve-3d;
  /* Flottement + léger balancement rotatif continu une fois posé, comme une
     enseigne métallique suspendue qui bouge doucement — amplitude et durée
     réglées pour rester perceptible sans devenir agité ("fluide"). */
  animation: heroLogoFloat 6s cubic-bezier(.45,0,.55,1) 2.1s infinite;
  transition: transform .12s linear;
  will-change: transform;
}
.hero-logo-img {
  position: relative; width: 100%; height: auto; display: block;
  filter: drop-shadow(0 25px 45px rgba(0,0,0,.45)) drop-shadow(0 0 30px rgba(245,166,35,.2));
}
@keyframes heroLogoIn {
  0% { opacity: 0; transform: translateY(34px) scale(.94); filter: blur(6px); }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}
@keyframes heroLogoSpinIn {
  0% { opacity: 0; transform: translateY(34px) scale(.85) rotate(-32deg); filter: blur(6px); }
  65% { opacity: 1; }
  100% { opacity: 1; transform: translateY(0) scale(1) rotate(0deg); filter: blur(0); }
}
@keyframes heroLogoFloat {
  0%, 100% { transform: translateY(0) translateX(0) rotate(0deg); }
  25% { transform: translateY(-11px) translateX(4px) rotate(-1.4deg); }
  50% { transform: translateY(-20px) translateX(0) rotate(2.2deg); }
  75% { transform: translateY(-9px) translateX(-4px) rotate(-1deg); }
}
@keyframes heroGlowIn { from { opacity: 0; transform: scale(.85); } to { opacity: .8; transform: scale(1); } }
@keyframes heroGlowPulse { 0%,100% { opacity: .8; transform: scale(1); } 50% { opacity: 1; transform: scale(1.08); } }

/* Petit burger animé façon "clin d'œil" à côté de l'eyebrow Nouveautés */
.eyebrow-burger {
  display: inline-block; margin-left: 2px; transform-origin: 50% 70%;
  animation: burgerWink 3.2s ease-in-out infinite;
}
@keyframes burgerWink {
  0%, 60%, 100% { transform: rotate(0deg) translateY(0); }
  15% { transform: rotate(-14deg) translateY(-2px); }
  30% { transform: rotate(10deg) translateY(-3px); }
  45% { transform: rotate(-5deg) translateY(-1px); }
}

@media (max-width: 980px) {
  .hero { height: auto; min-height: min(100vh, 780px); flex-direction: column; padding: calc(var(--header-h) + 40px) 0 60px; }
  .hero-scroll { display: none; }
  .hero-inner { flex-direction: column; text-align: center; gap: 12px; }
  .hero-content { max-width: 100%; }
  .hero-content p { margin-left: auto; margin-right: auto; }
  .hero-cta { justify-content: center; }
  .hero-logo-wrap { width: min(90vw, 480px); margin-top: 8px; }
  .hero-dots { position: static; transform: none; margin-top: 28px; justify-content: center; }
}
/* Sur téléphone étroit (< ~480px), le badge du hero ("100% fait maison...")
   et le bouton "Commander maintenant" débordaient horizontalement du viewport :
   .hero-badge n'avait aucune contrainte de largeur/retour à la ligne, et .btn
   a "white-space: nowrap" (utile ailleurs sur le site pour les petits boutons)
   ce qui l'empêchait de rétrécir sous la largeur de son texte. On corrige ici
   en autorisant le retour à la ligne + une largeur max, sans toucher à la
   règle globale .btn utilisée par les autres boutons du site. */
@media (max-width: 480px) {
  .hero-badge {
    max-width: 100%;
    white-space: normal;
    text-align: center;
    box-sizing: border-box;
  }
  .hero-cta { width: 100%; }
  .hero-cta .btn {
    white-space: normal;
    text-align: center;
    max-width: 100%;
    padding-left: 20px;
    padding-right: 20px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero-logo-wrap, .hero-logo-glow, .hero-logo-tilt { animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
  .eyebrow-burger { animation: none !important; }
  /* Entrée cinématographique : tout apparaît directement, sans stagger ni fondu */
  .hero-badge, .hero-content h1, .hero-content p, .hero-cta .btn, .hero-scroll, .hero-deco-blob {
    animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important;
  }
  .hero-scroll { opacity: .8 !important; }
  /* .hero-dots garde son transform: translateX(-50%) de centrage, on ne coupe que l'animation */
  .hero-dots { animation: none !important; opacity: 1 !important; }
  /* Fond ambiant : on garde les halos statiques (aucune dérive, aucun grain animé) */
  .ambient-bg { animation: none !important; opacity: 1 !important; }
  .ambient-gradient, .ambient-sheen, .ambient-noise { animation: none !important; }
  /* La plaque ondulante est purement une animation : on la masque plutôt que
     de la figer (le filtre SVG resterait actif sans bouger, coût pour rien) */
  .ambient-wave-plate { display: none !important; }
}

/* ---------- Categories ---------- */
.cat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 18px; }
.cat-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 28px 16px;
  text-align: center; transition: var(--transition); cursor: pointer; position: relative; overflow: hidden;
}
.cat-card::before { content:''; position:absolute; inset:0; background: var(--grad-brand); opacity:0; transition: var(--transition); }
.cat-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-glow); border-color: transparent; }
.cat-card:hover::before { opacity: 1; }
.cat-card .icon { font-size: 38px; margin-bottom: 12px; position: relative; z-index: 2; transition: var(--transition); }
.cat-card .name { font-weight: 700; font-size: 14.5px; position: relative; z-index: 2; transition: var(--transition); }
.cat-card:hover .name, .cat-card:hover .icon { color: white; }

/* ---------- Product Cards ---------- */
.prod-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 26px; }
.prod-card {
  background: var(--surface); border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border);
  transition: var(--transition); position: relative; display: flex; flex-direction: column; box-shadow: var(--shadow-sm);
}
.prod-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-lg); }
.prod-media { position: relative; aspect-ratio: 4/3; overflow: hidden; background: var(--grad-violet-soft); }
/* object-position remonte le cadrage : recentré (50% 50%) le produit
   paraissait trop bas dans la carte (trop d'assiette/table visible en haut,
   pas assez du burger/plat lui-même). */
.prod-media img { width: 100%; height: 100%; object-fit: cover; object-position: center 25%; transition: transform .6s cubic-bezier(.22,1,.36,1); }
.prod-card:hover .prod-media img { transform: scale(1.08); }
.prod-media .emoji-badge { position: absolute; bottom: 10px; right: 10px; font-size: 34px; filter: drop-shadow(0 4px 10px rgba(0,0,0,.35)); opacity: .95; }
.prod-badges { position: absolute; top: 12px; left: 12px; display: flex; flex-direction: column; gap: 6px; z-index: 3; }
.badge { padding: 6px 12px; border-radius: var(--radius-full); font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.badge-new { background: var(--gold); color: #4A2E00; }
.badge-promo { background: var(--danger); color: white; }
.badge-popular { background: var(--violet); color: white; }
.fav-btn {
  position: absolute; top: 12px; right: 12px; z-index: 3; width: 38px; height: 38px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.85); backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center;
  font-size: 17px; color: var(--violet); transition: var(--transition);
}
.fav-btn:hover { transform: scale(1.15); }
.fav-btn.active { background: var(--violet); color: white; }
.prod-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.prod-cat-tag { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--violet-light); }
.prod-body h3 { font-size: 18px; margin: 0; }
.prod-desc { font-size: 13.5px; margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.prod-rating { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-muted); }
.prod-rating .stars { color: var(--gold); letter-spacing: 1px; }
.prod-footer { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 10px; }
.price-block { display: flex; align-items: baseline; gap: 8px; }
/* Les prix restent en Poppins (chiffres nets et lisibles, pas en graffiti) */
.price { font-family: 'Poppins', 'Segoe UI', system-ui, sans-serif; font-weight: 800; font-size: 19px; color: var(--violet); }
[data-theme="dark"] .price { color: #FFFFFF; }
.price-old { font-size: 13px; text-decoration: line-through; color: var(--text-muted); }
.price-from { font-size: 11px; color: var(--text-muted); display: block; }
.add-btn {
  width: 46px; height: 46px; border-radius: 50%; border: none; background: var(--grad-violet-round); color: white; font-size: 20px;
  display: flex; align-items: center; justify-content: center; transition: var(--transition); box-shadow: 0 8px 18px rgba(106,13,173,.35);
  flex-shrink: 0;
}
.add-btn:hover { transform: scale(1.1) rotate(90deg); }
.add-btn.added { background: var(--success); }

/* ---------- Why us ---------- */
.why-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap: 24px; }
.why-card { text-align: center; padding: 34px 20px; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--border); transition: var(--transition); }
.why-card:hover { transform: translateY(-6px); box-shadow: var(--shadow); }
.why-icon { width: 74px; height: 74px; border-radius: 50%; background: var(--grad-violet-round); color: white; display: flex; align-items: center; justify-content: center; font-size: 32px; margin: 0 auto 18px; box-shadow: 0 12px 24px rgba(106,13,173,.3), 0 0 0 4px rgba(245,166,35,.28); animation: floaty 4s ease-in-out infinite; }
@keyframes floaty { 0%,100%{ transform: translateY(0);} 50%{ transform: translateY(-8px);} }
.why-card h3 { font-size: 17px; }
.why-card p { font-size: 13.5px; margin: 0; }

/* ---------- Nouveautés (grande vitrine sombre façon showcase produit) ---------- */
.new-showcase {
  position: relative; margin-top: 8px; min-height: 460px; border-radius: var(--radius-lg);
  overflow: hidden; box-shadow: var(--shadow-lg);
  /* Permet le swipe tactile horizontal (voir home.js) sans bloquer le
     scroll vertical de la page sur mobile. */
  touch-action: pan-y;
  background:
    radial-gradient(120% 140% at 82% 20%, rgba(240,171,252,.16) 0%, transparent 55%),
    radial-gradient(90% 110% at 12% 85%, rgba(106,13,173,.35) 0%, transparent 60%),
    linear-gradient(135deg, #1B0730 0%, #0F0619 60%, #0A0412 100%);
}
/* Les cartes sont posées côte à côte comme les vignettes d'un bandeau de
   film (une bobine) : elles restent "collées" les unes aux autres et c'est
   tout le bandeau qui glisse d'un cran à chaque changement de produit,
   plutôt que chaque carte qui apparaît/disparaît indépendamment. */
.new-showcase-track { position: relative; min-height: 460px; display: flex; width: 100%; transition: transform .85s cubic-bezier(.65,0,.35,1); }
.new-showcase-slide {
  flex: 0 0 100%; width: 100%; min-width: 100%; display: flex; align-items: center;
}
.new-showcase-info { position: relative; z-index: 3; flex: 0 0 auto; width: min(420px, 46%); padding: 56px 24px 56px 56px; color: white; }
.new-showcase-badges { display: flex; gap: 8px; margin-bottom: 16px; }
.new-showcase-price {
  display: inline-flex; align-items: center; background: rgba(255,255,255,.12); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.14); color: white; font-size: 14px; font-weight: 700;
  padding: 8px 16px; border-radius: var(--radius-full); margin-bottom: 22px;
}
.new-showcase-price .old { text-decoration: line-through; color: rgba(255,255,255,.5); font-weight: 500; margin-left: 8px; font-size: 12.5px; }
.new-showcase-info h3 { font-size: clamp(24px, 2.6vw, 32px); color: white; margin-bottom: 12px; }
.new-showcase-info p { font-size: 15px; color: rgba(255,255,255,.72); max-width: 380px; margin-bottom: 30px; }
.new-showcase-actions { display: flex; align-items: center; gap: 14px; }
.new-showcase-cta {
  display: inline-flex; align-items: center; gap: 8px; background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.18); color: white; font-weight: 600; font-size: 14.5px;
  padding: 13px 24px; border-radius: var(--radius-full); transition: var(--transition);
}
.new-showcase-cta:hover { background: rgba(255,255,255,.2); transform: translateY(-2px); }
.new-showcase-add {
  width: 46px; height: 46px; border-radius: 50%; border: 1px solid rgba(255,255,255,.18);
  background: var(--grad-gold); color: var(--violet-900); display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: var(--transition); box-shadow: var(--shadow-gold);
}
.new-showcase-add:hover { transform: translateY(-2px) scale(1.05); }
.new-showcase-add.added { background: var(--success); color: white; }
.new-showcase-media { position: relative; z-index: 2; flex: 1 1 auto; height: 100%; min-height: 460px; display: flex; align-items: center; justify-content: center; padding: 30px; }
.new-showcase-photo { position: relative; display: inline-block; max-width: 92%; max-height: 78%; }
.new-showcase-photo img {
  display: block; max-width: 100%; max-height: 100%; width: auto; object-fit: contain;
  border-radius: 10px; box-shadow: 0 30px 70px rgba(0,0,0,.55); border: 3px solid rgba(255,255,255,.08);
}
.new-showcase-arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255,255,255,.16);
  background: rgba(255,255,255,.08); backdrop-filter: blur(6px); color: white;
  display: flex; align-items: center; justify-content: center; opacity: .75; transition: var(--transition);
}
.new-showcase-arrow:hover { opacity: 1; background: rgba(255,255,255,.18); }
.new-showcase-arrow.prev { left: 20px; }
.new-showcase-arrow.next { right: 20px; }
.new-showcase-dots { position: absolute; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 5; display: flex; gap: 8px; }
.new-showcase-dots button { width: 8px; height: 8px; border-radius: 50%; border: none; background: rgba(255,255,255,.35); transition: var(--transition); }
.new-showcase-dots button.active { width: 26px; border-radius: var(--radius-full); background: var(--grad-gold); }
@media (max-width: 900px) {
  .new-showcase-slide { flex-direction: column-reverse; padding-top: 20px; }
  .new-showcase-info { width: auto; padding: 8px 24px 100px; text-align: center; align-items: center; }
  .new-showcase-info p { margin-left: auto; margin-right: auto; }
  .new-showcase-actions { justify-content: center; }
  .new-showcase-media { min-height: 220px; padding: 20px; }
  .new-showcase-photo img { max-height: 210px; }
  .new-showcase-arrow { display: none; }
}

/* ---------- Testimonials ---------- */
.testi-slider { position: relative; overflow: hidden; }
.testi-track { display: flex; transition: transform .6s cubic-bezier(.22,1,.36,1); }
.testi-card { min-width: 100%; padding: 8px; }
@media (min-width: 780px) { .testi-card { min-width: 50%; } }
@media (min-width: 1100px) { .testi-card { min-width: 33.333%; } }
.testi-inner { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 30px; height: 100%; }
.testi-stars { color: var(--gold); margin-bottom: 14px; letter-spacing: 2px; }
.testi-inner p { font-style: italic; color: var(--text); font-size: 15px; }
.testi-person { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
.avatar-initials { width: 46px; height: 46px; border-radius: 50%; background: var(--grad-violet-round); color: white; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 15px; }
.testi-name { font-weight: 700; font-size: 14px; }
.testi-nav { display: flex; justify-content: center; gap: 14px; margin-top: 30px; }
/* Lien "Ajouter votre avis" sous le titre des témoignages */
.add-review-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--violet); font-weight: 700; font-size: 14.5px; text-decoration: none;
  padding: 8px 18px; border: 1.5px solid var(--violet-light); border-radius: var(--radius-full);
  transition: var(--transition);
}
.add-review-link:hover { background: var(--violet); color: #fff; }
.add-review-link:hover span { color: #fff !important; }
/* Le modal d'avis n'utilise pas .modal-box-scroll (qui porte le fond) : on
   donne donc un fond opaque directement à sa boîte, sinon le contenu de la
   page transparaît derrière et le formulaire devient illisible. */
#testiModal .modal-box { background: var(--surface); }
/* Bouton de fermeture du modal d'avis (fond clair, distinct du modal produit) */
.testi-modal-close {
  position: absolute; top: 14px; right: 14px; width: 34px; height: 34px;
  border-radius: 50%; border: none; background: var(--bg-alt); color: var(--text-muted);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: var(--transition); z-index: 2;
}
.testi-modal-close:hover { background: var(--gray-100); color: var(--text); }

/* ---------- Location / Hours ---------- */
.location-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 40px; align-items: stretch; }
@media (max-width: 900px) { .location-grid { grid-template-columns: 1fr; } }
.map-wrap { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow); border: 1px solid var(--border); min-height: 380px; }
.map-wrap iframe { width: 100%; height: 100%; min-height: 380px; border: 0; }
.info-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 34px; box-shadow: var(--shadow-sm); }
.info-row { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 20px; }
.info-row .ico { width: 46px; height: 46px; border-radius: 14px; background: var(--violet-pale); color: var(--violet); display: flex; align-items: center; justify-content: center; font-size: 19px; flex-shrink: 0; }
[data-theme="dark"] .info-row .ico { color: #FFFFFF; }
.status-pill { display: inline-flex; align-items: center; gap: 8px; padding: 8px 16px; border-radius: var(--radius-full); font-weight: 700; font-size: 13px; }
.status-open { background: rgba(34,197,94,.12); color: #16A34A; }
.status-closed { background: rgba(239,68,68,.12); color: #DC2626; }
.status-pill .dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 4px currentColor; opacity: .9; }

.hours-table { width: 100%; border-collapse: collapse; margin-top: 14px; }
.hours-table td { padding: 10px 0; border-bottom: 1px dashed var(--border); font-size: 14px; }
.hours-table tr:last-child td { border-bottom: none; }
.hours-table .day { font-weight: 600; }
.hours-table tr.today td { color: var(--violet); font-weight: 700; }
[data-theme="dark"] .hours-table tr.today td { color: #FFFFFF; }

/* ---------- Footer ---------- */
.site-footer { background: var(--black); color: rgba(255,255,255,.75); padding: 76px 0 26px; margin-top: 60px; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.3fr; gap: 40px; }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer h4 { color: white; font-size: 15px; margin-bottom: 18px; }
.site-footer a { color: rgba(255,255,255,.65); font-size: 14px; display: block; margin-bottom: 10px; transition: var(--transition); }
.site-footer a:hover { color: var(--violet-lighter); transform: translateX(4px); }
.footer-social { display: flex; gap: 10px; margin-top: 18px; }
.footer-social a { width: 40px; height: 40px; border-radius: 50%; background: rgba(255,255,255,.08); display: flex; align-items: center; justify-content: center; margin: 0; }
.footer-social a:hover { background: var(--grad-violet-round); }
.newsletter-form { display: flex; gap: 8px; margin-top: 8px; }
.newsletter-form input { flex: 1; padding: 12px 16px; border-radius: var(--radius-full); border: none; background: rgba(255,255,255,.1); color: white; font-size: 13px; }
.newsletter-form input::placeholder { color: rgba(255,255,255,.5); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.1); margin-top: 50px; padding-top: 24px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; font-size: 13px; color: rgba(255,255,255,.5); }

/* ---------- Forms ---------- */
.form-group { margin-bottom: 20px; }
.form-group label { display: block; font-size: 13.5px; font-weight: 600; margin-bottom: 8px; }
.form-control {
  width: 100%; padding: 14px 18px; border-radius: var(--radius-sm); border: 1.5px solid var(--border);
  background: var(--bg-alt); color: var(--text); font-size: 14.5px; transition: var(--transition); font-family: inherit;
}
.form-control:focus { outline: none; border-color: var(--violet-light); box-shadow: 0 0 0 4px var(--violet-pale); }
textarea.form-control { resize: vertical; min-height: 110px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 560px) { .form-row { grid-template-columns: 1fr; } }
.form-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 40px; box-shadow: var(--shadow-sm); }
.form-hint { font-size: 12.5px; color: var(--text-muted); margin-top: 6px; }
.form-error { color: var(--danger); font-size: 12.5px; margin-top: 6px; display: none; }
.form-check { display: flex; align-items: center; gap: 10px; font-size: 14px; }

/* ---------- Auth pages ---------- */
.auth-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 140px 20px 60px; background: var(--bg-alt); }
.auth-card { width: 100%; max-width: 440px; }
.auth-card .logo { justify-content: center; margin-bottom: 26px; }
.auth-tabs { display: flex; gap: 8px; margin-bottom: 30px; background: var(--gray-100); padding: 6px; border-radius: var(--radius-full); }
.auth-tabs a { flex: 1; text-align: center; padding: 10px; border-radius: var(--radius-full); font-weight: 700; font-size: 14px; }
.auth-tabs a.active { background: white; box-shadow: var(--shadow-sm); color: var(--violet); }

/* ---------- Toasts ---------- */
#toast-region { position: fixed; bottom: 24px; right: 24px; z-index: 3000; display: flex; flex-direction: column; gap: 10px; }
.toast { background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-lg); border-radius: var(--radius-sm); padding: 14px 20px; display: flex; align-items: center; gap: 12px; min-width: 260px; animation: toastIn .35s cubic-bezier(.22,1,.36,1); }
.toast.success { border-left: 4px solid var(--success); }
.toast.error { border-left: 4px solid var(--danger); }
.toast.info { border-left: 4px solid var(--info); }
@keyframes toastIn { from { opacity: 0; transform: translateX(40px);} to { opacity:1; transform: translateX(0);} }

/* ---------- Empty cart modal (checkout) ---------- */
.empty-cart-modal { position: fixed; inset: 0; z-index: 4000; display: none; align-items: center; justify-content: center; padding: 20px; }
.empty-cart-modal.open { display: flex; }
.empty-cart-modal-overlay { position: absolute; inset: 0; background: rgba(11,7,16,.6); backdrop-filter: blur(3px); animation: fadeIn .25s ease; }
.empty-cart-modal-box {
  position: relative; z-index: 1; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: 36px 32px; max-width: 380px; width: 100%; text-align: center;
  animation: emptyCartIn .3s cubic-bezier(.22,1,.36,1);
}
.empty-cart-modal-icon {
  width: 60px; height: 60px; border-radius: 50%; background: var(--violet-pale); color: var(--violet);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 18px;
}
.empty-cart-modal-box h3 { margin: 0 0 10px; }
.empty-cart-modal-box p { color: var(--text-muted); font-size: 14px; margin: 0 0 24px; }
.empty-cart-modal-box .btn { width: 100%; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes emptyCartIn { from { opacity: 0; transform: translateY(16px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }

/* ---------- Cart Drawer ---------- */
.overlay-bg { position: fixed; inset: 0; background: rgba(11,7,16,.55); backdrop-filter: blur(3px); z-index: 900; opacity: 0; visibility: hidden; transition: var(--transition); }
.overlay-bg.open { opacity: 1; visibility: visible; }
.cart-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 420px; max-width: 92vw; background: var(--surface); z-index: 950;
  transform: translateX(100%); transition: transform .4s cubic-bezier(.22,1,.36,1); display: flex; flex-direction: column; box-shadow: -20px 0 60px rgba(0,0,0,.25);
}
.cart-drawer.open { transform: translateX(0); }
.cart-drawer-head { padding: 24px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--border); }
.cart-items { flex: 1; overflow-y: auto; padding: 10px 24px; }
.cart-item { display: flex; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--border); animation: itemIn .3s ease; }
@keyframes itemIn { from { opacity:0; transform: translateY(10px);} to {opacity:1; transform: translateY(0);} }
/* Sortie animée avant suppression réelle du DOM (voir removeLine dans app.js) */
.cart-item.removing { animation: itemOut .24s ease forwards; pointer-events: none; }
@keyframes itemOut { to { opacity: 0; transform: translateX(30px) scale(.95); } }
@media (prefers-reduced-motion: reduce) {
  .cart-item, .cart-item.removing { animation: none !important; opacity: 1 !important; transform: none !important; }
}
.cart-item img { width: 64px; height: 64px; border-radius: 12px; object-fit: cover; flex-shrink: 0; }
.cart-item-info { flex: 1; min-width: 0; }
.cart-item-info h4 { font-size: 14.5px; margin: 0 0 3px; }
.cart-item-variant { font-size: 12px; color: var(--text-muted); }
.qty-control { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.qty-control button { width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--border); background: var(--bg-alt); font-size: 14px; }
.qty-control span { font-weight: 700; font-size: 13.5px; min-width: 16px; text-align: center; }
.cart-item-remove { background: none; border: none; color: var(--text-muted); font-size: 12px; cursor: pointer; }
.cart-item-remove:hover { color: var(--danger); }
.cart-item-price { font-weight: 700; color: var(--violet); font-size: 14px; white-space: nowrap; }
.cart-drawer-foot { padding: 22px 24px; border-top: 1px solid var(--border); }
.cart-empty { text-align: center; padding: 60px 20px; color: var(--text-muted); }
.cart-empty .icon { font-size: 54px; margin-bottom: 16px; }
.summary-row { display: flex; justify-content: space-between; font-size: 14px; margin-bottom: 10px; color: var(--text-muted); }
.summary-row.total { font-size: 18px; font-weight: 800; color: var(--text); margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border); }
.promo-row { display: flex; gap: 8px; margin: 14px 0; }
.promo-row input { flex: 1; }

/* ---------- Menu page ---------- */
.menu-toolbar { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; justify-content: space-between; margin-bottom: 34px; position: sticky; top: calc(var(--header-h) + 12px); z-index: 60; background: var(--bg); padding: 14px 0; }
.menu-search { position: relative; flex: 1; min-width: 220px; max-width: 420px; }
.menu-search input { width: 100%; padding: 13px 16px 13px 44px; border-radius: var(--radius-full); border: 1.5px solid var(--border); background: var(--surface); }
.menu-search .ico { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--text-muted); }
.chip-row { display: flex; gap: 10px; flex-wrap: wrap; }
.chip { padding: 9px 18px; border-radius: var(--radius-full); border: 1.5px solid var(--border); background: var(--surface); font-size: 13.5px; font-weight: 600; transition: var(--transition); }
.chip.active, .chip:hover { background: var(--grad-violet); color: white; border-color: transparent; }
.chip-danger { background: #FEE2E2; color: #B91C1C; border-color: #FEE2E2; }
.sort-select { padding: 11px 16px; border-radius: var(--radius-full); border: 1.5px solid var(--border); background: var(--surface); font-size: 13.5px; font-weight: 600; }

/* ---------- Product Modal ---------- */
.modal-bg { position: fixed; inset: 0; background: rgba(11,7,16,.6); backdrop-filter: blur(4px); z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 20px; opacity: 0; visibility: hidden; transition: var(--transition); }
.modal-bg.open { opacity: 1; visibility: visible; }
.modal-box { position: relative; border-radius: var(--radius-lg); max-width: 920px; width: 100%; max-height: 88vh; overflow: hidden; transform: scale(.92); transition: var(--transition); box-shadow: var(--shadow-lg); }
.modal-bg.open .modal-box { transform: scale(1); }
/* Le scroll (et sa scrollbar) vit dans ce wrapper interne, lui-même sans
   arrondi : c'est .modal-box (overflow:hidden + radius) qui le découpe
   proprement, pour que la scrollbar ne déborde jamais du coin arrondi. */
.modal-box-scroll { background: var(--surface); max-height: 88vh; overflow-y: auto; overflow-x: hidden; display: grid; grid-template-columns: minmax(0,1.15fr) minmax(0,1fr); }
.modal-gallery, .modal-body { min-width: 0; }
@media (max-width: 760px) { .modal-box-scroll { grid-template-columns: minmax(0,1fr); } }
.modal-box-scroll { scrollbar-width: thin; scrollbar-color: var(--violet-light) transparent; }
.modal-box-scroll::-webkit-scrollbar { width: 9px; }
.modal-box-scroll::-webkit-scrollbar-track { background: transparent; margin: 8px 0; border-radius: 10px; }
.modal-box-scroll::-webkit-scrollbar-thumb { background: var(--violet-light); border-radius: 10px; border: 2px solid var(--surface); background-clip: padding-box; min-height: 48px; }
.modal-box-scroll::-webkit-scrollbar-thumb:hover { background: var(--violet); background-clip: padding-box; }

/* ---- Galerie produit : photo mise en avant, navigation, miniatures ---- */
.modal-gallery { position: relative; display: flex; flex-direction: column; background: linear-gradient(160deg, var(--violet-pale-2), var(--bg-alt)); }
/* Format fixe (plutôt que flex:1, qui étirait le cadre à la hauteur de toute
   la fiche produit et laissait un grand vide flou sous la photo) : la photo
   garde une taille normale et les vignettes des photos suivantes prennent
   directement la place juste en dessous, sans zone de remplissage. */
.modal-gallery-stage { position: relative; flex: none; aspect-ratio: 4 / 3; overflow: hidden; }
/* Fond flou désactivé : demandé de ne plus l'afficher — la photo garde
   maintenant sa taille normale sans laisser de zone à combler derrière. */
.modal-gallery-backdrop { display: none; }
/* object-fit:contain (photo à sa taille normale, pas zoomée/recadrée) +
   object-position "top" : la photo reste entière et à la même taille,
   seulement décalée vers le haut du cadre au lieu d'être centrée (ce qui
   laissait un espace vide au-dessus et la faisait paraître "trop basse"). */
.modal-gallery-stage img#modalMainImg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: center top; display: block; opacity: 1; z-index: 1; transition: opacity .28s ease, transform .5s cubic-bezier(.2,.8,.2,1); }
.modal-gallery-stage:hover img#modalMainImg { transform: scale(1.03); }
.modal-gallery-shade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0) 68%, rgba(11,7,16,.45) 100%); pointer-events: none; z-index: 2; }
.modal-gallery-badges { position: absolute; top: 16px; left: 16px; display: flex; flex-direction: column; gap: 6px; z-index: 3; }
/* Boutons flèches directement visibles (pas seulement au survol) sur PC. */
.modal-gallery-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; border-radius: 50%; border: none; background: rgba(255,255,255,.9); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; cursor: pointer; opacity: 1; transition: var(--transition); box-shadow: var(--shadow-sm); color: var(--violet-900); z-index: 3; }
.modal-gallery-nav.prev { left: 14px; }
.modal-gallery-nav.next { right: 14px; }
.modal-gallery-nav:hover { background: #fff; transform: translateY(-50%) scale(1.08); }
/* Sur mobile, on retire les flèches gauche/droite : la galerie se manipule
   au doigt (swipe, voir product-modal.js) — le compteur "1 / 3" suffit à
   indiquer qu'il y a plusieurs photos. */
@media (max-width: 760px) { .modal-gallery-nav { display: none !important; } }
.modal-gallery-stage { touch-action: pan-y; }
.modal-gallery-counter { position: absolute; bottom: 14px; right: 14px; background: rgba(11,7,16,.55); color: #fff; font-size: 11.5px; font-weight: 700; letter-spacing: .02em; padding: 5px 12px; border-radius: var(--radius-full); backdrop-filter: blur(4px); z-index: 3; }
/* flex-wrap:wrap : toutes les photos secondaires apparaissent d'un coup,
   sur plusieurs lignes si besoin, plutôt que de déborder hors du cadre en
   nécessitant un geste de glissement pour les voir. */
.modal-thumbs { display: flex; flex-wrap: wrap; gap: 10px; padding: 14px 16px; background: var(--surface); }
.modal-thumbs img { height: 66px; width: 66px; object-fit: cover; border-radius: 14px; cursor: pointer; opacity: .55; border: 2px solid transparent; transition: var(--transition); }
.modal-thumbs img:hover { opacity: .85; transform: translateY(-2px); }
.modal-thumbs img.active { opacity: 1; border-color: var(--violet-light); box-shadow: 0 6px 16px rgba(106,13,173,.28); transform: translateY(-2px); }
.modal-body { padding: 30px; position: relative; }
/* Croix de fermeture : posée directement sur .modal-bg (pas dans .modal-box,
   ni dans la zone qui défile), en position:fixed par rapport à l'écran —
   donc toujours au même endroit, en haut à droite, quoi qu'il se passe dans
   le popup (scroll, changement de photo, etc.). Pas de cercle ni de fond :
   juste l'icône, avec une légère ombre pour rester lisible sur une photo
   sombre comme sur le fond blanc de la fiche produit. */
.modal-close {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 1001;
  width: 38px;
  height: 38px;
  background: transparent;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.7)) drop-shadow(0 0 6px rgba(0,0,0,.35));
  cursor: pointer;
  transition: var(--transition);
}
.modal-close:hover { transform: scale(1.12); }
.variant-options { display: flex; flex-direction: column; gap: 10px; margin: 18px 0; }
.variant-opt { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border: 1.5px solid var(--border); border-radius: var(--radius-sm); cursor: pointer; transition: var(--transition); }
.variant-opt.selected, .variant-opt:hover { border-color: var(--violet-light); background: var(--violet-pale); }
.extras-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0; }
.extra-chip { padding: 7px 14px; border-radius: var(--radius-full); border: 1.5px solid var(--border); font-size: 12.5px; font-weight: 600; }
.extra-chip.selected { background: var(--violet); color: white; border-color: var(--violet); }
.qty-stepper { display: flex; align-items: center; gap: 16px; margin: 18px 0; }
.qty-stepper button { width: 40px; height: 40px; border-radius: 50%; border: 1.5px solid var(--border); background: var(--bg-alt); font-size: 18px; }

/* ---------- Avis clients (modal produit) ---------- */
.modal-reviews { margin-top: 26px; padding-top: 20px; border-top: 1.5px solid var(--border); }
.modal-reviews-title { font-size: 15.5px; margin: 0 0 14px; }
.review-form { background: var(--bg-alt); border-radius: var(--radius-sm); padding: 14px 16px; margin-bottom: 16px; }
.review-form-title { display: block; font-size: 13px; margin-bottom: 8px; }
.review-login-prompt { font-size: 13px; color: var(--text-muted); margin: 0; }
.review-login-prompt a { color: var(--violet); font-weight: 700; }
.star-picker { display: flex; gap: 4px; margin-bottom: 10px; }
.star-pick-btn { background: none; border: none; font-size: 24px; line-height: 1; color: var(--border); padding: 2px; cursor: pointer; transition: var(--transition); }
.star-pick-btn.active { color: #f5a623; }
.review-textarea {
  width: 100%; min-height: 70px; resize: vertical; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  padding: 10px 12px; font-family: inherit; font-size: 13.5px; background: var(--surface); color: var(--text); margin-bottom: 10px;
}
.review-form-actions { display: flex; gap: 10px; }
.review-list { display: flex; flex-direction: column; gap: 14px; }
.review-empty { font-size: 13px; color: var(--text-muted); }
.review-item { padding-bottom: 14px; border-bottom: 1px solid var(--border); }
.review-item:last-child { border-bottom: none; padding-bottom: 0; }
.review-item.mine { background: var(--violet-pale); border-radius: var(--radius-sm); padding: 10px 12px; border-bottom: none; }
.review-item-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 3px; }
.review-author { font-weight: 700; font-size: 13.5px; }
.review-mine-tag { font-weight: 500; color: var(--text-muted); }
.review-date { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.review-stars { color: #f5a623; font-size: 14px; letter-spacing: 1px; }
.review-comment { font-size: 13.5px; margin: 4px 0 0; color: var(--text); }
.qty-stepper .val { font-size: 20px; font-weight: 800; min-width: 24px; text-align: center; }

/* ---------- Checkout stepper ---------- */
.stepper { display: flex; justify-content: center; gap: 0; margin-bottom: 50px; max-width: 640px; margin-left: auto; margin-right: auto; }
.step { flex: 1; text-align: center; position: relative; }
.step::before { content: ''; position: absolute; top: 20px; left: -50%; width: 100%; height: 2px; background: var(--border); z-index: 0; }
.step:first-child::before { display: none; }
.step.done::before { background: var(--violet); }
.step-circle { width: 42px; height: 42px; border-radius: 50%; background: var(--surface); border: 2px solid var(--border); display: flex; align-items: center; justify-content: center; font-weight: 800; margin: 0 auto 10px; position: relative; z-index: 1; transition: var(--transition); }
.step.active .step-circle { background: var(--grad-violet-round); border-color: transparent; color: white; box-shadow: 0 6px 16px rgba(106,13,173,.4); }
.step.done .step-circle { background: var(--success); border-color: transparent; color: white; }
.step-label { font-size: 12.5px; font-weight: 700; color: var(--text-muted); }
.step.active .step-label { color: var(--violet); }

.pay-options, .type-options { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.opt-card { border: 2px solid var(--border); border-radius: var(--radius); padding: 24px; text-align: center; cursor: pointer; transition: var(--transition); }
.opt-card:hover { border-color: var(--violet-light); }
.opt-card.selected { border-color: var(--violet); background: var(--violet-pale); }
.opt-card .ico { font-size: 30px; margin-bottom: 10px; }

.summary-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 30px; position: sticky; top: 110px; }

/* ---------- Page Panier (grille articles / résumé) ---------- */
.cart-page-grid { display: grid; grid-template-columns: minmax(0,1.6fr) minmax(0,1fr); gap: 40px; align-items: flex-start; }
#cartPageItems { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 30px; }
@media (max-width: 900px) {
  .cart-page-grid { grid-template-columns: minmax(0,1fr); }
  .summary-card { position: static; }
}
@media (max-width: 600px) {
  #cartPageItems, .summary-card { padding: 20px; }
}

/* ---------- Order Success / Tracking ---------- */
.success-wrap { min-height: 90vh; display: flex; align-items: center; justify-content: center; padding: 140px 20px 60px; text-align: center; }
.check-circle { width: 120px; height: 120px; border-radius: 50%; background: rgba(34,197,94,.12); display: flex; align-items: center; justify-content: center; margin: 0 auto 30px; }
.check-circle svg { width: 60px; height: 60px; }
.check-circle circle { stroke: var(--success); stroke-width: 3; fill: none; stroke-dasharray: 166; stroke-dashoffset: 166; animation: circleDraw 0.8s ease forwards; }
.check-circle path { stroke: var(--success); stroke-width: 4; fill: none; stroke-dasharray: 48; stroke-dashoffset: 48; animation: checkDraw .5s .7s ease forwards; }
@keyframes circleDraw { to { stroke-dashoffset: 0; } }
@keyframes checkDraw { to { stroke-dashoffset: 0; } }

.track-steps { display: flex; justify-content: space-between; position: relative; max-width: 780px; margin: 60px auto; }
.track-line-bg { position: absolute; top: 24px; left: 5%; right: 5%; height: 4px; background: var(--border); border-radius: 4px; z-index: 0; }
.track-line-fill { position: absolute; top: 24px; left: 5%; height: 4px; background: var(--grad-violet); border-radius: 4px; z-index: 1; transition: width 1s cubic-bezier(.22,1,.36,1); }
.track-step { position: relative; z-index: 2; text-align: center; flex: 1; }
.track-step .circle { width: 50px; height: 50px; border-radius: 50%; background: var(--surface); border: 3px solid var(--border); display: flex; align-items: center; justify-content: center; margin: 0 auto 12px; font-size: 20px; transition: var(--transition); }
.track-step.done .circle { background: var(--grad-violet-round); border-color: transparent; color: white; }
.track-step.current .circle { background: var(--grad-violet-round); border-color: transparent; color: white; animation: pulse-ring 1.6s infinite; }
@keyframes pulse-ring { 0%{ box-shadow: 0 0 0 0 rgba(106,13,173,.5);} 70%{ box-shadow: 0 0 0 14px rgba(106,13,173,0);} 100%{ box-shadow:0 0 0 0 rgba(106,13,173,0);} }
.track-step .lbl { font-size: 12px; font-weight: 700; color: var(--text-muted); max-width: 90px; margin: 0 auto; }
.track-step.done .lbl, .track-step.current .lbl { color: var(--violet); }

/* ---------- Stats ---------- */
.stats-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 30px; text-align: center; }
@media (max-width: 700px) { .stats-grid { grid-template-columns: 1fr; } }
.stat-num { font-family: var(--font-display); font-size: clamp(36px,5vw,54px); font-weight: 800; }

/* ---------- Utility ---------- */
.reveal { opacity: 0; transform: translateY(40px); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 50px; align-items: center; }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }
.tag-list { display: flex; flex-wrap: wrap; gap: 8px; }
.mt-0{margin-top:0} .mb-0{margin-bottom:0} .text-center{text-align:center}
.dark-toggle .sun { display: none; } .dark-toggle .moon { display: block; }
[data-theme="dark"] .dark-toggle .sun { display: block; } [data-theme="dark"] .dark-toggle .moon { display: none; }
.empty-state { text-align: center; padding: 90px 20px; color: var(--text-muted); }
.empty-state .icon { font-size: 60px; margin-bottom: 20px; }
.skeleton { background: linear-gradient(90deg, var(--gray-100) 20%, var(--violet-pale) 45%, var(--gold-pale) 60%, var(--gray-100) 80%); background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: var(--radius); }
@keyframes shimmer { to { background-position: -200% 0; } }

/* ---------- Entrée/sortie des cartes produit (grille filtrable, façon AnimatePresence) ----------
   Contrairement à .reveal (qui ne joue qu'une fois, au scroll), .card-pop
   sert aux grilles re-rendues dynamiquement (filtres du menu) : chaque
   carte apparaît avec un léger décalage (--i) façon "stagger children". */
.card-pop { animation: cardPop .5s cubic-bezier(.22,1,.36,1) both; animation-delay: calc(min(var(--i, 0), 9) * 50ms); }
@keyframes cardPop { from { opacity: 0; transform: translateY(22px) scale(.96); } to { opacity: 1; transform: none; } }
.prod-grid.grid-swapping > *, .cat-grid.grid-swapping > * { animation: cardOut .18s ease forwards; }
@keyframes cardOut { to { opacity: 0; transform: translateY(-10px) scale(.97); } }
@media (prefers-reduced-motion: reduce) {
  .card-pop, .prod-grid.grid-swapping > *, .cat-grid.grid-swapping > * { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* ---------- Mobile Nav ---------- */
.nav-only-mobile { display: none; }
@media (max-width: 980px) {
  /* Menu déroulant depuis le haut (sous le header), pas un tiroir plein
     écran : sa hauteur suit son contenu (flex + hauteur naturelle), avec
     juste un max-height + scroll en filet de sécurité si jamais l'écran est
     très petit ou qu'on ajoute beaucoup de liens plus tard. */
  .main-nav {
    position: fixed; top: var(--header-h); left: 0; right: 0; max-height: calc(100dvh - var(--header-h));
    background: var(--surface); flex-direction: column; align-items: stretch; padding: 14px 20px 20px; gap: 6px;
    overflow-y: auto; box-shadow: 0 20px 40px rgba(0,0,0,.18);
    border-bottom-left-radius: var(--radius-lg); border-bottom-right-radius: var(--radius-lg);
    transform: translateY(-12px); opacity: 0; visibility: hidden; pointer-events: none;
    transition: transform .3s cubic-bezier(.22,1,.36,1), opacity .25s ease, visibility 0s linear .3s;
  }
  .main-nav.open {
    transform: translateY(0); opacity: 1; visibility: visible; pointer-events: auto;
    transition: transform .3s cubic-bezier(.22,1,.36,1), opacity .25s ease, visibility 0s;
  }
  /* Liste sobre façon "app" : texte seul (pas d'icône), beaucoup d'air entre
     les lignes, et seule la page active se détache avec un fond doux +
     texte en gras dans la couleur de la marque — inspiré d'une référence
     donnée par le client. */
  .nav-link-ico { display: none !important; }
  .main-nav a, .main-nav button.nav-only-mobile {
    padding: 18px 16px; font-size: 16.5px; font-weight: 500; border-radius: var(--radius);
    color: var(--text); background: none;
  }
  .main-nav a:hover { background: var(--violet-pale); color: var(--violet); transform: none; }
  .main-nav a.active { background: var(--violet-pale); color: var(--violet); font-weight: 700; }
  .nav-only-mobile { display: block; width: 100%; font-family: inherit; text-align: left; }
  .burger { display: flex; }
  .search-panel { width: 92vw; right: -60px; }
}
@media (max-width: 560px) {
  .hide-on-small { display: none !important; }
  /* Un peu plus d'air entre les boutons (au lieu de 2px, quasi collés) :
     nécessaire pour que le badge du panier (qui déborde du bouton, voir
     plus bas) ne touche jamais le bouton suivant, mais aussi tout simplement
     plus propre visuellement qu'une rangée de boutons collés. */
  .header-actions { gap: 7px; }
  .logo { gap: 6px; }
  .logo .txt { font-size: 17px; }
  .logo .mark { width: 34px; height: 34px; font-size: 16px; border-radius: 10px; }
  .icon-btn { width: 38px; height: 38px; font-size: 16px; }
  .container { padding: 0 14px; }
  /* Le badge rond (panier/notifications) est un peu plus petit et moins en
     saillie sur mobile, pour rester bien "posé" sur son bouton plutôt que
     de déborder vers le suivant même avec l'espacement ci-dessus. */
  .icon-btn .badge { top: -2px; right: -2px; min-width: 17px; height: 17px; font-size: 10px; }
}
.burger { width: 44px; height: 44px; border-radius: 50%; background: var(--gray-100); border: none; align-items: center; justify-content: center; font-size: 20px; }

/* ---------- Icônes SVG (remplacent les emojis pour un rendu premium cohérent) ---------- */
.icon-svg { display: block; flex-shrink: 0; }
.icon-btn svg { width: 19px; height: 19px; }
.btn svg { width: 17px; height: 17px; }
.why-icon svg, .check-circle svg { width: 30px; height: 30px; }
.info-row .ico svg { width: 20px; height: 20px; }
.footer-social a svg { width: 17px; height: 17px; }
.opt-card .ico svg { width: 26px; height: 26px; }
.track-step .circle svg { width: 20px; height: 20px; }
.fav-btn svg { width: 16px; height: 16px; }
.admin-nav .ico svg, .kpi-card .ico svg { width: 18px; height: 18px; }
.icon-action svg { width: 15px; height: 15px; }
.cart-empty .icon svg, .empty-state .icon svg { width: 52px; height: 52px; color: var(--violet-light); }

/* ---------- Accessibilité ---------- */
.skip-link {
  position: fixed; top: -60px; left: 12px; z-index: 3000; background: var(--violet); color: white;
  padding: 12px 20px; border-radius: var(--radius-sm); font-weight: 700; transition: top .2s ease;
}
.skip-link:focus { top: 12px; }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 3px solid var(--gold); outline-offset: 2px;
}

/* ---------- Accent doré (identité du logo) ---------- */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--bg-alt); }
::-webkit-scrollbar-thumb { background: var(--grad-gold); border-radius: var(--radius-full); border: 2px solid var(--bg-alt); }
::-webkit-scrollbar-thumb:hover { background: var(--gold); }

/* Print (facture) */
@media print {
  .site-header, .site-footer, .no-print { display: none !important; }
}

/* =====================================================================
   MICRO-INTERACTIONS PREMIUM — page d'accueil uniquement
   ---------------------------------------------------------------------
   Scopé sous body.home-cinematic pour ne jamais affecter le Menu, le
   Panier, le Compte ou l'Admin (qui partagent les mêmes classes .btn /
   .prod-card dans ce fichier). Sur chaque bouton, carte, icône et image
   de la home : légère rotation 3D au survol, ombre dynamique, reflet
   métallique qui balaie la surface, et une touche de glassmorphism —
   uniquement transform/opacity/box-shadow (jamais top/left/width),
   pour rester fluide à 60 FPS. */
/* .btn n'est plus scopé à body.home-cinematic : demande explicite du client,
   le style "premium" (relief 3D, ombre dynamique, reflet) doit s'appliquer à
   TOUS les boutons du site (menu, panier, compte, admin inclus), pas
   seulement ceux de la page d'accueil — seul l'effet de flottement continu
   (ctaFloat, .hero-cta uniquement) reste exclusif au hero. Les cartes
   (cat-card/prod-card/why-card/testi-inner/new-showcase-*) restent scopées
   à la home comme avant. */
.btn,
body.home-cinematic .cat-card,
body.home-cinematic .prod-card,
body.home-cinematic .why-card,
body.home-cinematic .testi-inner,
body.home-cinematic .new-showcase-cta,
body.home-cinematic .new-showcase-add {
  position: relative; overflow: hidden;
  transition: transform .45s cubic-bezier(.16,1,.3,1), box-shadow .45s cubic-bezier(.16,1,.3,1);
  transform: perspective(900px) rotateX(0) rotateY(0) translateY(0) scale(1);
  will-change: transform;
}
/* Reflet métallique : une bande de lumière qui balaie la surface au survol */
.btn::after,
body.home-cinematic .prod-card::after,
body.home-cinematic .why-card::after,
body.home-cinematic .testi-inner::after,
body.home-cinematic .cat-card::after {
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.35) 48%, transparent 66%);
  transform: translateX(-120%); mix-blend-mode: overlay;
  transition: transform .75s cubic-bezier(.16,1,.3,1);
}
.btn:hover::after,
body.home-cinematic .prod-card:hover::after,
body.home-cinematic .why-card:hover::after,
body.home-cinematic .testi-inner:hover::after,
body.home-cinematic .cat-card:hover::after {
  transform: translateX(120%);
}
/* Léger voile glassmorphism qui apparaît au survol des cartes */
body.home-cinematic .prod-card, body.home-cinematic .why-card, body.home-cinematic .testi-inner {
  backdrop-filter: blur(0px); transition: transform .45s cubic-bezier(.16,1,.3,1), box-shadow .45s cubic-bezier(.16,1,.3,1), backdrop-filter .45s ease;
}
body.home-cinematic .prod-card:hover, body.home-cinematic .why-card:hover, body.home-cinematic .testi-inner:hover {
  backdrop-filter: blur(2px) saturate(1.1);
}

/* Boutons : effet "extrudé" — empilement d'ombres (portée + contact +
   biseau intérieur) pour un vrai relief physique, comme un bouton qui
   dépasse de la page, plus marqué encore au survol. Appliqué à TOUS les
   boutons du site (plus seulement la home). */
.btn::before {
  content: '';
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,.4) 0%, rgba(255,255,255,0) 42%, rgba(0,0,0,.1) 100%);
  opacity: .85;
  transition: opacity .45s cubic-bezier(.16,1,.3,1);
}
.btn:hover::before { opacity: 1; }

/* IMPORTANT : le nombre de couches de box-shadow doit être IDENTIQUE (et
   dans le même ordre inset/normal) entre l'état repos et l'état :hover
   ci-dessous. Si le nombre de couches diffère, le navigateur ne peut pas
   interpoler la transition en douceur : il "saute" d'un état à l'autre en
   un instant, ce qui se voit comme un artefact rectangulaire qui dépasse
   brièvement du bouton au survol (bug rapporté par vidéo). D'où la couche
   supplémentaire invisible ci-dessous (3ᵉ ligne), qui n'a aucun effet visuel
   au repos mais existe pour matcher la 3ᵉ couche du survol. */
.btn-primary {
  box-shadow:
    0 1px 0 rgba(255,255,255,.3) inset,
    0 -4px 8px rgba(0,0,0,.18) inset,
    0 0 0 1px rgba(255,255,255,0) inset,
    0 3px 8px rgba(0,0,0,.22),
    0 14px 26px rgba(106,13,173,.4),
    var(--focus-ring, 0 0 0 0 rgba(0,0,0,0));
}
.btn-secondary,
.btn-outline-white {
  box-shadow:
    0 1px 0 rgba(255,255,255,.55) inset,
    0 -3px 6px rgba(0,0,0,.07) inset,
    0 2px 6px rgba(0,0,0,.08),
    0 10px 20px rgba(0,0,0,.12),
    var(--focus-ring, 0 0 0 0 rgba(0,0,0,0));
}

.btn:hover {
  transform: perspective(900px) rotateX(6deg) rotateY(-5deg) translateY(-4px) scale(1.02);
}
.btn-primary:hover {
  box-shadow:
    0 1px 0 rgba(255,255,255,.4) inset,
    0 -6px 12px rgba(0,0,0,.24) inset,
    0 0 0 1px rgba(255,255,255,.1) inset,
    0 8px 16px rgba(0,0,0,.3),
    0 28px 50px rgba(106,13,173,.55),
    var(--focus-ring, 0 0 0 0 rgba(0,0,0,0));
}
.btn-secondary:hover, .btn-outline-white:hover {
  box-shadow:
    0 1px 0 rgba(255,255,255,.7) inset,
    0 -4px 9px rgba(0,0,0,.1) inset,
    0 6px 14px rgba(0,0,0,.14),
    0 20px 36px rgba(0,0,0,.2),
    var(--focus-ring, 0 0 0 0 rgba(0,0,0,0));
}

/* Catégories */
body.home-cinematic .cat-card:hover {
  transform: perspective(900px) rotateX(5deg) rotateY(-4deg) translateY(-10px) scale(1.03);
  box-shadow: var(--shadow-glow), 0 22px 40px rgba(0,0,0,.22);
}
body.home-cinematic .cat-card:hover .icon { transform: scale(1.12) rotate(-4deg); }

/* Produits */
body.home-cinematic .prod-card:hover {
  transform: perspective(900px) rotateX(4deg) rotateY(-3deg) translateY(-10px) scale(1.015);
  box-shadow: var(--shadow-lg), 0 24px 46px rgba(106,13,173,.18);
}
body.home-cinematic .prod-media { overflow: hidden; }
body.home-cinematic .prod-media img { transition: transform .6s cubic-bezier(.16,1,.3,1), filter .6s ease; }
body.home-cinematic .prod-card:hover .prod-media img { transform: scale(1.1); filter: brightness(1.04); }

/* "Pourquoi nous" */
body.home-cinematic .why-card:hover {
  transform: perspective(900px) rotateX(4deg) rotateY(0) translateY(-8px) scale(1.02);
  box-shadow: var(--shadow), 0 20px 36px rgba(106,13,173,.14);
}
body.home-cinematic .why-icon { transition: transform .45s cubic-bezier(.16,1,.3,1); }
body.home-cinematic .why-card:hover .why-icon { transform: scale(1.12) rotate(6deg); }

/* Témoignages */
body.home-cinematic .testi-inner:hover {
  transform: perspective(900px) rotateX(3deg) translateY(-6px) scale(1.015);
  box-shadow: var(--shadow);
}

/* Vitrine Nouveautés : reflet léger sur les boutons uniquement (le carrousel
   garde son comportement existant, on ne fait qu'ajouter un reflet discret) */
body.home-cinematic .new-showcase-cta, body.home-cinematic .new-showcase-add { overflow: hidden; }
body.home-cinematic .new-showcase-cta::after, body.home-cinematic .new-showcase-add::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,.3) 48%, transparent 66%);
  transform: translateX(-120%); transition: transform .7s cubic-bezier(.16,1,.3,1);
}
body.home-cinematic .new-showcase-cta:hover::after, body.home-cinematic .new-showcase-add:hover::after { transform: translateX(120%); }

/* =====================================================================
   FINITION "FUNK" — étiquettes autocollantes + mouvement, home only
   ---------------------------------------------------------------------
   Ici on utilise les propriétés CSS "rotate" / "scale" / "translate"
   séparées de "transform" (supporté par tous les navigateurs modernes) :
   ça permet de faire vivre un badge ou une icône en continu (rotation,
   micro-flottement) SANS jamais entrer en conflit avec les transform:
   déjà posés ailleurs (survol des cartes, etc.) puisque ce sont des
   propriétés indépendantes qui se combinent au rendu final. Tout est en
   rotate/scale/translate/opacity uniquement → reste fluide à 60 FPS et
   coupé net par prefers-reduced-motion plus bas. */

/* Badges "étiquette" (Nouveau / -X% / Populaire) : posés de travers comme
   un vrai sticker collé à la main, avec un petit "pop" d'arrivée et une
   respiration lente en continu. Comme .badge est utilisé partout sur le
   site, on scope strictement à la home pour ne pas toucher le Menu. */
body.home-cinematic .badge {
  --tilt: -6deg;
  position: relative;
  border: 2px solid rgba(255,255,255,.55);
  box-shadow: 0 3px 0 rgba(0,0,0,.16), 0 6px 14px rgba(0,0,0,.22);
  rotate: var(--tilt);
  animation: stickerPop .55s cubic-bezier(.34,1.56,.64,1) backwards, stickerWiggle 4.5s ease-in-out 1s infinite;
}
body.home-cinematic .badge-promo { --tilt: 5deg; }
body.home-cinematic .badge-popular { --tilt: -4deg; }
body.home-cinematic .prod-badges .badge:nth-child(2),
body.home-cinematic .new-showcase-badges .badge:nth-child(2) { animation-delay: .08s, 1.8s; }
@keyframes stickerPop {
  0% { opacity: 0; scale: .3; rotate: calc(var(--tilt) - 22deg); }
  65% { opacity: 1; scale: 1.18; }
  100% { opacity: 1; scale: 1; rotate: var(--tilt); }
}
@keyframes stickerWiggle {
  0%, 100% { rotate: var(--tilt); }
  50% { rotate: calc(var(--tilt) + 4deg); }
}

/* Étiquettes "eyebrow" (petit label au-dessus de chaque titre de section) :
   même esprit sticker, en plus discret, avec une micro-oscillation lente. */
body.home-cinematic .eyebrow {
  --tilt: -2.5deg;
  border: 1.5px solid rgba(255,255,255,.4);
  rotate: var(--tilt);
  animation: stickerWiggle 6s ease-in-out infinite;
}

/* Badge du hero ("100% fait maison") : garde son entrée existante
   (transform: translateY + scale), et gagne juste un léger balancement
   une fois posé, sur la propriété rotate (indépendante) — pas de conflit. */
.hero-badge { animation: heroLogoIn .9s cubic-bezier(.16,1,.3,1) 1.1s forwards, badgeSwing 4.4s ease-in-out 2.6s infinite; }
@keyframes badgeSwing { 0%,100% { rotate: -2.5deg; } 50% { rotate: 2.5deg; } }

/* Catégories : l'icône (emoji) flotte légèrement en continu, en plus du
   scale+rotate déjà posé au survol (sur transform, donc aucun conflit
   puisqu'on anime "translate" ici, pas "transform"). */
body.home-cinematic .cat-card .icon { animation: iconFloat 3.4s ease-in-out infinite; animation-delay: calc(var(--i, 0) * .12s); }
@keyframes iconFloat { 0%,100% { translate: 0 0; } 50% { translate: 0 -5px; } }

/* "Pourquoi nous" : en plus du flottement vertical existant (floaty, sur
   transform), un léger balancement continu sur rotate (propriété séparée). */
body.home-cinematic .why-icon { rotate: 0deg; animation: floaty 4s ease-in-out infinite, iconSway 5s ease-in-out .4s infinite; }
@keyframes iconSway { 0%,100% { rotate: -3deg; } 50% { rotate: 3deg; } }

/* Témoignages : chaque étoile scintille l'une après l'autre (voir le
   <span class="star-ch"> ajouté dans index.ejs pour animer étoile par
   étoile plutôt que le bloc entier d'un coup). */
body.home-cinematic .testi-stars .star-ch {
  display: inline-block; animation: starTwinkle 2.6s ease-in-out infinite;
}
@keyframes starTwinkle { 0%, 100% { scale: 1; } 50% { scale: 1.3; } }

@media (prefers-reduced-motion: reduce) {
  .btn, body.home-cinematic .cat-card, body.home-cinematic .prod-card,
  body.home-cinematic .why-card, body.home-cinematic .testi-inner,
  body.home-cinematic .new-showcase-cta, body.home-cinematic .new-showcase-add {
    transition: box-shadow .3s ease !important;
  }
  .btn:hover, body.home-cinematic .cat-card:hover, body.home-cinematic .prod-card:hover,
  body.home-cinematic .why-card:hover, body.home-cinematic .testi-inner:hover {
    transform: none !important; backdrop-filter: none !important;
  }
  .btn::after, body.home-cinematic .prod-card::after, body.home-cinematic .why-card::after,
  body.home-cinematic .testi-inner::after, body.home-cinematic .cat-card::after,
  body.home-cinematic .new-showcase-cta::after, body.home-cinematic .new-showcase-add::after { display: none !important; }
  body.home-cinematic .cat-card:hover .icon, body.home-cinematic .why-card:hover .why-icon,
  body.home-cinematic .prod-card:hover .prod-media img { transform: none !important; }
  body.home-cinematic .badge, .hero-badge, body.home-cinematic .eyebrow,
  body.home-cinematic .cat-card .icon, body.home-cinematic .why-icon,
  body.home-cinematic .testi-stars .star-ch {
    animation: none !important; rotate: 0deg !important; translate: 0 !important;
  }
}

/* Les halos ambiants et l'entrée cinématique n'ont pas leur place sur petit
   écran (coût de calcul relatif plus élevé, et l'attention doit aller au
   contenu) : on garde une entrée simple et un fond léger, sans dérive. */
@media (max-width: 600px) {
  .ambient-noise, .ambient-sheen { display: none; }
  body.home-cinematic .prod-card:hover, body.home-cinematic .why-card:hover, body.home-cinematic .testi-inner:hover {
    backdrop-filter: none;
  }
}

/* =====================================================================
   TAGS PEINTURE — éclaboussures graffiti dans chaque section (home only)
   ---------------------------------------------------------------------
   Un "blob" à la forme organique (astuce border-radius asymétrique, donc
   aucune image ni SVG à charger) + 3 petites gouttes qui semblent avoir
   giclé autour, comme un vrai coup de bombe de peinture. Toujours en
   z-index:-1 : la section est déjà position:relative (règle plus haut),
   donc la tache reste sous le contenu en flux normal sans qu'on ait à
   toucher au z-index du reste. Couleurs de la marque, opacité faible,
   léger mouvement continu (translate/rotate séparés de transform). */
.paint-splash {
  position: absolute; z-index: -1; pointer-events: none;
  animation: paintDrift 22s ease-in-out infinite;
  --psc: rgba(106,13,173,.14);
}
.paint-splash .ps-blob {
  position: absolute; inset: 0;
  border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%;
  background: var(--psc);
}
.paint-splash.psv2 .ps-blob { border-radius: 63% 37% 40% 60% / 55% 40% 60% 45%; }
.paint-splash.psv3 .ps-blob { border-radius: 34% 66% 57% 43% / 60% 35% 65% 40%; }
.paint-splash .ps-drop { position: absolute; border-radius: 50%; background: var(--psc); }
.paint-splash .d1 { width: 24%; height: 24%; top: -10%; right: 6%; }
.paint-splash .d2 { width: 13%; height: 13%; bottom: 2%; right: -10%; }
.paint-splash .d3 { width: 9%; height: 9%; top: 34%; left: -12%; }
@keyframes paintDrift {
  0%, 100% { translate: 0 0; rotate: 0deg; }
  50%      { translate: 1.4% -2.2%; rotate: 3deg; }
}
.paint-splash.psc-gold   { --psc: rgba(245,166,35,.17); }
.paint-splash.psc-pink   { --psc: rgba(240,171,252,.18); }
.paint-splash.psc-white  { --psc: rgba(255,255,255,.10); }
.paint-splash.psc-violet { --psc: rgba(106,13,173,.14); }
@media (max-width: 700px) { .paint-splash { display: none; } }
@media (prefers-reduced-motion: reduce) { .paint-splash { animation: none !important; } }

/* =====================================================================
   MOBILE — on coupe les animations en boucle infinie (funk + tags peinture)
   ---------------------------------------------------------------------
   Sur téléphone, ces petites animations continues (badges, eyebrow,
   icônes, étoiles) s'ajoutent au fond ambiant déjà animé et au carrousel
   Nouveautés, ce qui charge le processeur graphique et rend le scroll/le
   panier moins fluides sur du matériel plus modeste. On garde uniquement
   l'entrée "pop" ponctuelle des badges (bon marché, joue une fois), et on
   coupe tout ce qui tourne en continu — le style reste identique, juste
   figé au repos plutôt qu'animé sans arrêt. */
@media (max-width: 760px) {
  body.home-cinematic .badge { animation: stickerPop .55s cubic-bezier(.34,1.56,.64,1) backwards; }
  body.home-cinematic .eyebrow,
  body.home-cinematic .cat-card .icon,
  body.home-cinematic .testi-stars .star-ch {
    animation: none !important; rotate: 0deg !important; translate: 0 !important; scale: 1 !important;
  }
  /* .hero-badge garde son entrée (heroLogoIn, forwards) : on retire juste
     le balancement continu ajouté par-dessus (badgeSwing). */
  .hero-badge { animation: heroLogoIn .9s cubic-bezier(.16,1,.3,1) 1.1s forwards !important; rotate: 0deg !important; }
  /* .why-icon garde son flottement existant (floaty, sur transform) : on ne
     coupe ici que le balancement ajouté par-dessus (iconSway). */
  body.home-cinematic .why-icon { animation: floaty 4s ease-in-out infinite !important; rotate: 0deg !important; }
  /* Boutons du hero : demande explicite du client, le flottement "funk"
     (ctaFloat) doit rester actif sur téléphone/tablette aussi, pas seulement
     sur desktop. On ne touche donc plus à leur animation ici — la règle de
     base (.hero-cta .btn:nth-child) s'applique telle quelle. */
}
