/*
 * Vitrine publique Clario — feuille de style autonome.
 *
 * Volontairement SANS Bootstrap ni jQuery, contrairement au panneau marchand.
 * Ces pages seront ouvertes en majorite depuis les navigateurs embarques de
 * WhatsApp, Facebook, Instagram et TikTok, sur des forfaits data comptes :
 * charger 200 ko de framework pour afficher une grille de produits serait
 * payer, a chaque visite, pour du code inutilise.
 *
 * Mobile first : toutes les regles de base visent le telephone, les media
 * queries n'ajoutent que ce dont un ecran large a besoin.
 *
 * Trois niveaux de personnalisation, du plus general au plus precis :
 *   1. les variables ci-dessous, communes a toutes les vitrines ;
 *   2. l'ambiance choisie par le commercant, via [data-ambiance] ;
 *   3. sa couleur d'accent, injectee en ligne dans la page (calculee cote
 *      serveur par StorefrontThemeService, en clair ET en sombre).
 *
 * Les variables d'accent presentes ici ne sont que des valeurs de repli : le
 * bloc inline de la page vient apres et l'emporte.
 */

:root {
  /* Accent — remplace en ligne par la couleur de la boutique. */
  --accent: #0E8C4F;
  --accent-dark: #0A6E3E;
  --accent-soft: #E4F2EA;
  --accent-ink: #FFFFFF;

  /* Neutres — l'ambiance "sobre", par defaut. */
  --ink: #1A2B4C;
  --ink-2: #55637A;
  --ink-3: #8A9099;
  --bg: #FAF8F4;
  --surface: #FFFFFF;
  --surface-2: #F2EFE8;
  --border: #E7E2D8;
  --danger: #A8332A;
  --danger-soft: #FAE7E4;
  --warm: #C2620F;

  /* Formes et densite — pilotees par l'ambiance. */
  --radius: 12px;
  --radius-sm: 9px;
  --border-w: 1px;
  --title-weight: 700;
  --card-pad: 10px 11px 12px;
  --section-gap: 20px;

  --shadow: 0 1px 2px rgba(26, 43, 76, .05), 0 8px 24px -16px rgba(26, 43, 76, .25);
  --header-h: 56px;
  --bn-h: 58px; /* hauteur de la barre de navigation basse */
}

/* ---------- Mode sombre ----------
   Beaucoup de telephones sont regles en sombre en permanence, souvent pour
   economiser la batterie. Ouvrir un lien qui eblouit, le soir, ferme la page.
   Seuls les neutres sont redefinis ici : l'accent est recalcule cote serveur,
   car lui seul connait la couleur choisie par le commercant. */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #E8E6E0;
    --ink-2: #A7AEB9;
    --ink-3: #79808C;
    --bg: #12151A;
    --surface: #1A1E25;
    --surface-2: #22262E;
    --border: #2C313A;
    --danger: #E88A7E;
    --danger-soft: #331816;
    --warm: #F0A05A;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px -16px rgba(0, 0, 0, .8);
  }
}

/* ---------- Ambiances ----------
   Un choix encadre plutot qu'un editeur libre : quatre jeux coherents donnent
   toujours un resultat presentable, la ou un panneau ouvert produit vite
   quelque chose d'illisible. Chaque ambiance est declaree deux fois, en clair
   et en sombre : une regle [data-ambiance] est plus specifique que :root, elle
   ecraserait sinon les neutres sombres. */
:root[data-ambiance="chaleureuse"] {
  --bg: #FDF6EC;
  --surface: #FFFDF8;
  --surface-2: #F5EADA;
  --border: #EBDCC5;
  --ink: #3B2E22;
  --ink-2: #6E5C4A;
  --ink-3: #9C8B79;
  --radius: 18px;
  --radius-sm: 13px;
  --card-pad: 12px 13px 14px;
  --section-gap: 24px;
}

:root[data-ambiance="contrastee"] {
  --bg: #FFFFFF;
  --surface: #FFFFFF;
  --surface-2: #F4F4F4;
  --border: #111111;
  --ink: #0A0A0A;
  --ink-2: #454545;
  --ink-3: #767676;
  --radius: 2px;
  --radius-sm: 2px;
  --border-w: 1.5px;
  --title-weight: 800;
  --shadow: none;
}

:root[data-ambiance="minimale"] {
  --bg: #FFFFFF;
  --surface: #FFFFFF;
  --surface-2: #FAFAFA;
  --border: #ECECEC;
  --ink: #202020;
  --ink-2: #6B6B6B;
  --ink-3: #A0A0A0;
  --radius: 6px;
  --radius-sm: 5px;
  --title-weight: 600;
  --card-pad: 12px 4px 16px;
  --section-gap: 32px;
  --shadow: none;
}

@media (prefers-color-scheme: dark) {
  :root[data-ambiance="chaleureuse"] {
    --bg: #16120D;
    --surface: #1F1913;
    --surface-2: #2A2219;
    --border: #372C20;
    --ink: #F0E7DA;
    --ink-2: #B6A692;
    --ink-3: #857766;
  }

  :root[data-ambiance="contrastee"] {
    --bg: #000000;
    --surface: #0B0B0B;
    --surface-2: #171717;
    --border: #F0F0F0;
    --ink: #FAFAFA;
    --ink-2: #C4C4C4;
    --ink-3: #8E8E8E;
  }

  :root[data-ambiance="minimale"] {
    --bg: #0E0E0E;
    --surface: #151515;
    --surface-2: #1C1C1C;
    --border: #262626;
    --ink: #EDEDED;
    --ink-2: #A5A5A5;
    --ink-3: #757575;
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* La barre de navigation basse est fixe : le contenu doit pouvoir defiler
   jusqu'au bout sans passer dessous. */
body.has-bottom-nav {
  padding-bottom: calc(var(--bn-h) + env(safe-area-inset-bottom));
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }

.wrap { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 14px; }

/* ---------- En-tete ---------- */
.sf-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--surface);
  border-bottom: var(--border-w) solid var(--border);
}
.sf-header-in { display: flex; align-items: center; gap: 10px; min-height: var(--header-h); }
.sf-brand { display: flex; align-items: center; gap: 9px; min-width: 0; flex: 1; }
.sf-brand img { width: 34px; height: 34px; border-radius: var(--radius-sm); object-fit: cover; flex: 0 0 auto; }
.sf-brand-mark {
  width: 34px; height: 34px; border-radius: var(--radius-sm); flex: 0 0 auto;
  background: var(--accent); color: var(--accent-ink);
  display: grid; place-items: center; font-weight: 700; font-size: .95rem;
}
.sf-brand-name {
  font-weight: var(--title-weight); font-size: 1rem; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sf-brand-sub { font-size: .72rem; color: var(--ink-3); }

.sf-cart-btn {
  position: relative;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-dark);
  font-weight: 600; font-size: .85rem;
  border: 0;
  flex: 0 0 auto;
}
.sf-cart-count {
  min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 999px; background: var(--accent); color: var(--accent-ink);
  font-size: .7rem; font-weight: 700;
  display: inline-grid; place-items: center;
}

/* ---------- Barre de navigation basse ----------
   Les destinations principales a portee de pouce, comme dans toutes les
   applications que le client utilise deja. S'en ecarter fait « site web » la
   ou on veut faire « boutique ». */
.sf-bottom-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: var(--surface);
  border-top: var(--border-w) solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.sf-bn-item {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  height: var(--bn-h);
  color: var(--ink-3);
  font-size: .68rem; font-weight: 500;
  /* La cible doit rester confortable au pouce, meme sur un ecran de 360 px. */
  min-width: 0;
}
.sf-bn-item.is-active { color: var(--accent-dark); font-weight: 600; }
.sf-bn-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.sf-bn-icon { position: relative; display: block; width: 22px; height: 22px; }
.sf-bn-icon svg { width: 22px; height: 22px; }
.sf-bn-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-bn-badge {
  position: absolute; top: -5px; right: -9px;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px;
  background: var(--accent); color: var(--accent-ink);
  font-size: .62rem; font-weight: 700; line-height: 17px; text-align: center;
}

/* Sur grand ecran la barre basse n'a plus de sens : l'en-tete suffit. */
@media (min-width: 860px) {
  .sf-bottom-nav { display: none; }
  body.has-bottom-nav { padding-bottom: 0; }
}

/* ---------- Recherche ---------- */
.sf-search { padding: 10px 0 12px; }
.sf-search form { display: flex; gap: 8px; }
.sf-input {
  width: 100%; padding: 11px 13px;
  border: var(--border-w) solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink);
  font-size: 16px; /* 16px : evite le zoom automatique sur iOS a la mise au point */
}
.sf-input:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }

/* ---------- Bandeau ---------- */
.sf-hero {
  background: var(--surface);
  border-bottom: var(--border-w) solid var(--border);
  padding: 16px 0 18px;
}
.sf-hero-banner {
  width: 100%; aspect-ratio: 16 / 7; object-fit: cover;
  border-radius: var(--radius); margin-bottom: 14px;
  background: var(--surface-2);
}
.sf-hero h1 { margin: 0 0 5px; font-size: 1.3rem; letter-spacing: -.02em; font-weight: var(--title-weight); }
.sf-hero p { margin: 0; color: var(--ink-2); font-size: .92rem; }

/* ---------- Puces de categorie ---------- */
.sf-chips {
  display: flex; gap: 8px; overflow-x: auto;
  padding: 12px 14px 4px; margin: 0 -14px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.sf-chips::-webkit-scrollbar { display: none; }
.sf-chip {
  flex: 0 0 auto;
  padding: 7px 13px; border-radius: 999px;
  border: var(--border-w) solid var(--border); background: var(--surface);
  font-size: .84rem; font-weight: 500; white-space: nowrap;
}
.sf-chip.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ---------- Sections ---------- */
.sf-section { padding: var(--section-gap) 0 4px; }
.sf-section-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-bottom: 12px;
}
.sf-section-head h2 { margin: 0; font-size: 1.05rem; letter-spacing: -.015em; font-weight: var(--title-weight); }
.sf-section-head a { font-size: .82rem; color: var(--accent-dark); font-weight: 600; }

/* ---------- Reserve d'image ----------
   Une teinte stable par produit, posee sous l'image. La carte est remplie
   avant que l'image n'arrive : plus de flash blanc, et le regard ne saute pas.
   Aucune extraction de couleur dominante n'est possible sans GD ni Imagick,
   dont la presence n'est pas garantie — une teinte constante atteint le meme
   but perceptif, et deux visites donnent la meme couleur. */
/* ---------- Grille produits ---------- */
.sf-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 560px) { .sf-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 860px) { .sf-grid { grid-template-columns: repeat(4, 1fr); gap: 16px; } }

.sf-card {
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
}
.sf-card-media {
  position: relative; aspect-ratio: 1 / 1;
  background-color: hsl(var(--tint, 200) 26% 91%);
}
.sf-card-media img { width: 100%; height: 100%; object-fit: cover; }
.sf-card-media .ph {
  width: 100%; height: 100%; display: grid; place-items: center;
  color: var(--ink-3); font-size: 1.6rem;
}
@media (prefers-color-scheme: dark) {
  .sf-card-media { background-color: hsl(var(--tint, 200) 14% 18%); }
}

.sf-badge {
  position: absolute; top: 8px; left: 8px;
  padding: 3px 8px; border-radius: 999px;
  font-size: .66rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  background: var(--accent); color: var(--accent-ink);
}
.sf-badge.out { background: var(--ink-3); color: var(--surface); }
.sf-badge.low { background: var(--warm); color: #FFFFFF; }

.sf-card-body { padding: var(--card-pad); display: flex; flex-direction: column; gap: 4px; flex: 1; }
.sf-card-cat { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
.sf-card-name {
  font-size: .88rem; font-weight: 600; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.sf-card-price { margin-top: auto; padding-top: 6px; font-size: 1rem; font-weight: 700; color: var(--accent-dark); }

/* ---------- Tuiles de categorie ----------
   Une photo dit ce que vend la boutique plus vite qu'un mot, et sans demander
   de savoir lire. L'image se deduit des produits publies : rien a saisir. */
.sf-tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
@media (min-width: 640px) { .sf-tiles { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px) { .sf-tiles { grid-template-columns: repeat(4, 1fr); gap: 16px; } }

.sf-tile {
  display: flex; flex-direction: column;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.sf-tile-media {
  aspect-ratio: 4 / 3;
  background-color: hsl(var(--tint, 200) 26% 91%);
}
.sf-tile-media img { width: 100%; height: 100%; object-fit: cover; }
@media (prefers-color-scheme: dark) {
  .sf-tile-media { background-color: hsl(var(--tint, 200) 14% 18%); }
}
.sf-tile-body { padding: 10px 12px 12px; }
.sf-tile-name { display: block; font-weight: 600; font-size: .92rem; line-height: 1.3; }
.sf-tile-count { display: block; font-size: .76rem; color: var(--ink-3); margin-top: 2px; }

/* ---------- Boutons ---------- */
.sf-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 12px 16px; border-radius: var(--radius-sm);
  border: var(--border-w) solid transparent;
  font-weight: 600; font-size: .92rem; cursor: pointer;
  background: var(--accent); color: var(--accent-ink);
  width: 100%;
}
.sf-btn:disabled { background: var(--ink-3); cursor: not-allowed; }
.sf-btn-ghost { background: var(--surface); border-color: var(--border); color: var(--ink); }
.sf-btn-sm { padding: 8px 12px; font-size: .84rem; width: auto; }
.sf-btn-link { background: none; border: 0; color: var(--danger); font-size: .8rem; padding: 4px 0; width: auto; cursor: pointer; }

/* ---------- Fiche produit ---------- */
.sf-product { padding: 16px 0 28px; }
.sf-product-media {
  display: block; position: relative;
  background-color: hsl(var(--tint, 200) 26% 91%);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  aspect-ratio: 1 / 1; margin-bottom: 16px;
}
@media (prefers-color-scheme: dark) {
  .sf-product-media { background-color: hsl(var(--tint, 200) 14% 18%); }
}
.sf-product-media img { width: 100%; height: 100%; object-fit: cover; }
.sf-zoom-hint {
  position: absolute; right: 10px; bottom: 10px;
  width: 32px; height: 32px; border-radius: 999px;
  background: rgba(0, 0, 0, .55); color: #FFFFFF;
  display: grid; place-items: center;
}
.sf-product h1 { margin: 0 0 6px; font-size: 1.35rem; letter-spacing: -.02em; font-weight: var(--title-weight); }
.sf-product-price { font-size: 1.5rem; font-weight: 800; color: var(--accent-dark); margin: 4px 0 12px; }
.sf-product-desc { color: var(--ink-2); white-space: pre-line; margin: 14px 0; }
.sf-meta { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: .82rem; color: var(--ink-2); }
@media (min-width: 760px) {
  .sf-product-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; align-items: start; }
  .sf-product-media { margin-bottom: 0; }
}

/* ---------- Barre d'achat permanente ----------
   Sur un telephone, « Ajouter au panier » disparait des qu'on lit la
   description. Fixee au-dessus de la barre de navigation, elle reste
   atteignable a tout moment. */
.sf-buybar {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--bn-h) + env(safe-area-inset-bottom));
  z-index: 35;
  background: var(--surface);
  border-top: var(--border-w) solid var(--border);
  box-shadow: 0 -6px 20px -18px rgba(0, 0, 0, .6);
}
.sf-buybar-in { display: flex; align-items: center; gap: 12px; padding: 9px 14px; }
.sf-buybar-price { flex: 1; min-width: 0; font-weight: 800; font-size: 1.05rem; color: var(--accent-dark); line-height: 1.2; }
.sf-buybar-price small { display: block; font-size: .7rem; font-weight: 500; color: var(--ink-3); }
.sf-btn-buy { width: auto; flex: 0 0 auto; padding: 11px 20px; }
/* Le contenu doit pouvoir defiler au-dela des deux barres empilees. La classe
   est posee par la vue plutot que deduite par :has(), dont le support n'est pas
   acquis sur les WebView Android anciennes — precisement celles des navigateurs
   embarques de WhatsApp et Facebook. */
body.has-buybar { padding-bottom: calc(var(--bn-h) + 62px + env(safe-area-inset-bottom)); }
@media (min-width: 860px) {
  .sf-buybar { bottom: 0; }
  body.has-buybar { padding-bottom: 62px; }
}

/* ---------- Agrandissement d'image ----------
   Realise avec :target — un lien et un fragment, aucun JavaScript. Fonctionne
   dans les navigateurs embarques les plus anciens. */
.sf-lightbox {
  display: none;
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0, 0, 0, .92);
  place-items: center;
  padding: 20px;
}
.sf-lightbox:target { display: grid; }
.sf-lightbox img { max-width: 100%; max-height: 92vh; object-fit: contain; }
.sf-lightbox-backdrop { position: absolute; inset: 0; }
.sf-lightbox-close {
  position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 16px;
  width: 40px; height: 40px; border-radius: 999px;
  background: rgba(255, 255, 255, .16); color: #FFFFFF;
  display: grid; place-items: center; font-size: 1.6rem; line-height: 1;
}

/* ---------- Variantes ---------- */
/* Boutons radio deguises en pastilles : la variante fait partie du formulaire
   d'ajout au panier, donc le choix fonctionne sans une ligne de JavaScript. */
.sf-variants { border: 0; padding: 0; margin: 0 0 14px; }
.sf-variants legend { padding: 0; margin-bottom: 7px; font-size: .82rem; font-weight: 600; }
.sf-variant { display: inline-flex; align-items: center; margin: 0 7px 7px 0; cursor: pointer; }
.sf-variant input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.sf-variant span {
  display: inline-block;
  padding: 9px 15px;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: .88rem; font-weight: 500;
  min-width: 46px; text-align: center;
}
.sf-variant input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-dark);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--accent);
}
/* Le focus clavier doit rester visible : l'input reel est masque. */
.sf-variant input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Une variante epuisee reste lisible plutot que masquee : le client doit voir
   que sa taille existe, sinon il la cherche ailleurs au lieu de revenir. */
.sf-variant.is-out { cursor: not-allowed; }
.sf-variant.is-out span {
  color: var(--ink-3);
  background: var(--bg);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.sf-line-variant {
  display: inline-block; margin-top: 3px;
  padding: 1px 7px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-dark);
  font-size: .74rem; font-weight: 600;
}

/* ---------- Panier et commande ---------- */
.sf-panel {
  background: var(--surface); border: var(--border-w) solid var(--border);
  border-radius: var(--radius); padding: 14px; margin-bottom: 14px;
}
.sf-line { display: flex; gap: 11px; padding: 12px 0; border-bottom: var(--border-w) solid var(--border); }
.sf-line:last-child { border-bottom: 0; }
.sf-line-img {
  width: 62px; height: 62px; border-radius: var(--radius-sm);
  object-fit: cover; background: var(--surface-2); flex: 0 0 auto;
}
.sf-line-body { flex: 1; min-width: 0; }
.sf-line-name { font-weight: 600; font-size: .9rem; }
.sf-line-price { color: var(--ink-2); font-size: .84rem; }
.sf-qty { display: inline-flex; align-items: center; gap: 6px; margin-top: 6px; }
.sf-qty input {
  width: 62px; padding: 6px 8px; text-align: center;
  border: var(--border-w) solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-size: 15px;
}
.sf-line-total { font-weight: 700; white-space: nowrap; align-self: center; }

.sf-totals { display: flex; flex-direction: column; gap: 8px; }
.sf-total-row { display: flex; justify-content: space-between; font-size: .92rem; }
.sf-total-row.grand { font-size: 1.15rem; font-weight: 800; padding-top: 8px; border-top: var(--border-w) solid var(--border); }

.sf-field { margin-bottom: 13px; }
.sf-field label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: 5px; }
.sf-field .hint { font-size: .76rem; color: var(--ink-3); margin-top: 4px; }
.sf-field textarea { min-height: 80px; resize: vertical; }
.sf-required { color: var(--danger); }

.sf-radio {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 12px; border: var(--border-w) solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); margin-bottom: 9px; cursor: pointer;
}
.sf-radio input { margin-top: 3px; flex: 0 0 auto; width: 18px; height: 18px; accent-color: var(--accent); }
.sf-radio-title { font-weight: 600; font-size: .9rem; }
.sf-radio-sub { font-size: .8rem; color: var(--ink-2); }
.sf-radio:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }

/* Champ pot de miel : invisible pour un humain, rempli par les robots. */
.sf-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- Bouton WhatsApp ---------- */
/* Le vert de WhatsApp, pas la couleur d'accent de la boutique : c'est la
   reconnaissance instantanee du service qui fait cliquer, et la teindre aux
   couleurs du magasin ferait perdre exactement ce qu'on cherche. Elle reste
   secondaire par la position, jamais par le contraste. */
.sf-btn-wa {
  background: #25D366;
  color: #FFFFFF;
  border-color: #25D366;
  margin-top: 8px;
}
.sf-btn-wa:hover { background: #1EBE5B; border-color: #1EBE5B; }
.sf-btn-wa:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.sf-wa-icon { flex: 0 0 auto; }
@media (prefers-color-scheme: dark) {
  .sf-btn-wa { box-shadow: 0 0 0 1px rgba(255, 255, 255, .12); }
}

/* ---------- Messages ---------- */
.sf-alert {
  border-radius: var(--radius-sm); padding: 11px 13px; margin: 12px 0;
  font-size: .88rem; border: var(--border-w) solid transparent;
}
.sf-alert-ok { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-dark); }
.sf-alert-err { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.sf-alert ul { margin: 6px 0 0; padding-left: 18px; }

.sf-empty { text-align: center; padding: 48px 16px; color: var(--ink-2); }
.sf-empty h2 { font-size: 1.05rem; color: var(--ink); margin: 0 0 6px; font-weight: var(--title-weight); }

/* ---------- Barre d'action collante ----------
   Utilisee par le panier et le formulaire de commande. Elle se cale au-dessus
   de la barre de navigation, sinon les deux se superposeraient. */
.sf-sticky {
  position: sticky;
  bottom: calc(var(--bn-h) + env(safe-area-inset-bottom));
  z-index: 20;
  background: var(--surface);
  border-top: var(--border-w) solid var(--border);
  padding: 11px 14px;
  margin: 18px -14px 0;
}
@media (min-width: 860px) {
  .sf-sticky { bottom: 0; }
}

/* ---------- Pagination ---------- */
.sf-pagination { display: flex; justify-content: center; gap: 6px; padding: 22px 0; flex-wrap: wrap; }
.sf-pagination a, .sf-pagination span {
  padding: 7px 12px; border-radius: var(--radius-sm);
  border: var(--border-w) solid var(--border);
  background: var(--surface); font-size: .86rem;
}
.sf-pagination .active span { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.sf-pagination .disabled span { color: var(--ink-3); }

/* ---------- Pied de page ---------- */
.sf-footer {
  margin-top: 32px; padding: 22px 0 34px;
  border-top: var(--border-w) solid var(--border); background: var(--surface);
  font-size: .84rem; color: var(--ink-2);
}
.sf-footer h3 { font-size: .9rem; margin: 0 0 7px; color: var(--ink); font-weight: var(--title-weight); }
.sf-footer-cols { display: grid; gap: 18px; }
@media (min-width: 640px) { .sf-footer-cols { grid-template-columns: repeat(3, 1fr); } }
.sf-social { display: flex; gap: 10px; margin-top: 8px; }
.sf-social a {
  padding: 6px 11px; border: var(--border-w) solid var(--border); border-radius: var(--radius-sm);
  font-size: .8rem; font-weight: 600;
}
.sf-credit { margin-top: 20px; font-size: .76rem; color: var(--ink-3); }


/* ---------- Promotions ----------
   Le prix barre n'est montre que s'il depasse le prix reel : c'est verifie
   cote serveur, jamais laisse au hasard de la saisie. */
.sf-badge.sale { background: var(--danger); color: #FFFFFF; }
.sf-price-was {
  color: var(--ink-3);
  font-weight: 500;
  font-size: .82em;
  margin-left: 6px;
  text-decoration-thickness: 1px;
}
.sf-discount {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--danger);
  color: #FFFFFF;
  font-size: .72rem;
  font-weight: 700;
  vertical-align: middle;
}

/* ---------- Galerie produit ----------
   Defilement natif avec accrochage, en CSS pur. Un carrousel en JavaScript
   aurait demande une bibliotheque et se serait fige sur les navigateurs
   embarques les plus anciens ; le defilement du systeme ne casse jamais. */
.sf-gallery {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  border-radius: var(--radius);
}
.sf-gallery::-webkit-scrollbar { display: none; }
.sf-gallery-slide {
  position: relative;
  flex: 0 0 100%;
  scroll-snap-align: center;
  aspect-ratio: 1 / 1;
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background-color: hsl(var(--tint, 200) 26% 91%);
}
.sf-gallery-slide img { width: 100%; height: 100%; object-fit: cover; }
.sf-gallery-hint {
  margin: 8px 0 0;
  font-size: .78rem;
  color: var(--ink-3);
  text-align: center;
}
@media (prefers-color-scheme: dark) {
  .sf-gallery-slide { background-color: hsl(var(--tint, 200) 14% 18%); }
}
@media (min-width: 760px) {
  .sf-gallery-slide { flex-basis: calc(50% - 4px); }
}

/* ---------- Actions secondaires de la fiche ---------- */
.sf-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.sf-actions .sf-btn { margin-top: 0; }

/* Combinaison inexistante : on le dit, plutot que de laisser un bouton
   qui ne repond pas. */
.sf-attr-note {
  margin: 0 0 12px;
  padding: 8px 11px;
  border-radius: var(--radius-sm);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: .84rem;
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }

  /* CE BLOC EST OBLIGATOIRE, PAS UN CONFORT.

     `.sf-animate-fade` pose `opacity: 0` et compte sur l'animation pour
     ramener a 1. Couper l'animation sans rendre l'opacite laissait les
     elements a zero : pour tout visiteur ayant active la reduction des
     animations — un reglage d'accessibilite courant, et le defaut de
     certains modes economie d'energie — la GRILLE DE PRODUITS ENTIERE etait
     invisible. La boutique paraissait vide.

     On coupe le mouvement, mais on atterrit sur l'etat final. C'est la seule
     facon correcte de neutraliser une animation d'apparition. */
  .sf-animate-fade,
  [class*="sf-animate"] {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ---------------------------------------------------------------- filtres */
/* Le panneau de filtres est un <details> : il s'ouvre sans une ligne de
   JavaScript, garde son etat au clavier, et reste utilisable si les scripts
   ne se chargent pas — ce qui arrive sur les connexions dont depend cette
   vitrine. On lui retire seulement le triangle par defaut, remplace par un
   chevron dessine en CSS. */
.sf-filters > summary { list-style: none; position: relative; padding-right: 34px; }
.sf-filters > summary::-webkit-details-marker { display: none; }
.sf-filters > summary::after {
  content: '';
  position: absolute;
  right: 16px;
  top: 50%;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--ink-2);
  border-bottom: 2px solid var(--ink-2);
  transform: translateY(-70%) rotate(45deg);
  transition: transform .18s ease;
}
.sf-filters[open] > summary::after { transform: translateY(-30%) rotate(-135deg); }
.sf-filters > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ==========================================================================
   FUTURISTIC & GLASSMORPHIC STOREFRONT EXTENSIONS (LIGHT & DARK)
   ========================================================================== */

/* Glassmorphism Header & Sticky Bars */
.sf-header {
  background: rgba(255, 255, 255, 0.82) !important;
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  border-bottom: 1px solid var(--border) !important;
}

.sf-bottom-nav, .sf-buybar, .sf-sticky {
  background: rgba(255, 255, 255, 0.85) !important;
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border-top: 1px solid var(--border) !important;
}

@media (prefers-color-scheme: dark) {
  .sf-header {
    background: rgba(26, 30, 37, 0.82) !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
  }
  .sf-bottom-nav, .sf-buybar, .sf-sticky {
    background: rgba(26, 30, 37, 0.85) !important;
    border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
  }
}

/* Card Futuristic Hover & Glass Effects */
.sf-card, .sf-tile, .sf-panel {
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s ease, border-color 0.35s ease;
  position: relative;
}

.sf-card:hover, .sf-tile:hover {
  transform: translateY(-4px) scale(1.01);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.08), 0 0 15px var(--accent-soft);
  border-color: var(--accent) !important;
}

@media (prefers-color-scheme: dark) {
  .sf-card:hover, .sf-tile:hover {
    box-shadow: 0 14px 35px rgba(0, 0, 0, 0.5), 0 0 20px rgba(14, 140, 79, 0.25);
  }
}

/* Neon Badges with Pulse */
.sf-badge {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  letter-spacing: 0.04em;
  backdrop-filter: blur(4px);
}

.sf-badge.sale {
  background: linear-gradient(135deg, #FF6B00 0%, #E02424 100%) !important;
  box-shadow: 0 0 10px rgba(255, 107, 0, 0.4);
}

/* Stagger Animations */
@keyframes sfFadeInUp {
  0% {
    opacity: 0;
    transform: translateY(24px) scale(0.98);
    filter: blur(4px);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

.sf-animate-fade {
  animation: sfFadeInUp 0.55s cubic-bezier(0.16, 1, 0.3, 1) forwards;
  opacity: 0;
}

.sf-stagger-1 { animation-delay: 0.05s; }
.sf-stagger-2 { animation-delay: 0.10s; }
.sf-stagger-3 { animation-delay: 0.15s; }
.sf-stagger-4 { animation-delay: 0.20s; }
.sf-stagger-5 { animation-delay: 0.25s; }
.sf-stagger-6 { animation-delay: 0.30s; }
.sf-stagger-7 { animation-delay: 0.35s; }
.sf-stagger-8 { animation-delay: 0.40s; }

/* Enhanced Form Inputs */
.sf-input {
  transition: all 0.25s ease;
}

.sf-input:focus {
  box-shadow: 0 0 0 3px var(--accent-soft), 0 0 15px rgba(14, 140, 79, 0.15);
}



/* =========================================================================
   IDENTITE, PARTAGE, ET CADRES ARRONDIS
   ========================================================================= */

/* ---------- Banniere ----------
   Le rapport 16/7 est celui annonce au commercant dans ses reglages. Il est
   declare ici et la : changer l'un sans l'autre livrerait une image recadree
   autrement que sur l'apercu. */
.sf-hero-banner {
  aspect-ratio: 16 / 7;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* Sans banniere, le nom de la boutique porte le hero seul. Il a donc besoin
   d'air et de taille — sinon la page commence par un vide. */
.sf-hero h1 {
  font-size: clamp(1.6rem, 5vw, 2.4rem);
  letter-spacing: -0.02em;
  margin-bottom: 6px;
}
.sf-hero > .wrap { text-align: center; }
.sf-hero p { color: var(--ink-2); margin-bottom: 14px; }

/* ---------- Partage ---------- */
.sf-share { position: relative; display: inline-block; }

.sf-share-panel {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: calc(100% + 8px);
  z-index: 40;
  width: min(320px, calc(100vw - 32px));
  padding: 12px;
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, .28);
  text-align: left;
}

.sf-share-links { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; margin-bottom: 10px; }

.sf-share-link {
  display: block;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  font-size: .82rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  color: var(--accent-ink);
  /* Les couleurs de marque des reseaux, pas l'accent de la boutique : on les
     reconnait a la couleur avant de lire le nom. */
  background: #25D366;
}
.sf-share-link.is-facebook { background: #1877F2; }
.sf-share-link.is-x        { background: #14171A; }
.sf-share-link.is-telegram { background: #229ED9; }
.sf-share-link:hover { filter: brightness(1.08); }

.sf-share-copy { display: flex; gap: 6px; }
.sf-share-copy input { flex: 1; min-width: 0; font-size: .78rem; }
.sf-share-copy-btn { white-space: nowrap; }

/* ---------- Cadre arrondi de la vignette ----------
   Sur le modele, l'image n'est pas collee au bord de la carte : elle vit dans
   un cadre arrondi, avec une marge tout autour. C'est cette marge qui donne a
   la grille son air soigne, et qui laisse la carte respirer. */
.sf-card {
  padding: 8px;
  border-radius: calc(var(--radius) + 6px);
  overflow: visible;
}
.sf-card-media {
  border-radius: var(--radius);
  overflow: hidden;
}
.sf-card-body { padding: 10px 4px 4px; }

/* La pastille de remise se pose sur le cadre, pas sur le bord de la carte. */
.sf-card .sf-badge { top: 10px; left: 10px; }

/* ---------- Coherence clair / sombre ----------
   La carte etait detachee par une bordure en clair et par la meme bordure en
   sombre. En sombre, une bordure claire sur une surface sombre cerne la carte
   au lieu de la poser : l'ombre porte mieux. */
.sf-card { box-shadow: var(--shadow); }

@media (prefers-color-scheme: dark) {
  .sf-card { border-color: transparent; }
  .sf-share-panel { box-shadow: 0 16px 40px -8px rgba(0, 0, 0, .7); }
  /* Le noir pur des reseaux disparait sur un fond sombre. */
  .sf-share-link.is-x { background: #2F3336; }
}

/* ---------- Apercus dans les reglages du commercant ----------
   Ils vivent dans la feuille de la vitrine parce qu'ils montrent la vitrine :
   les garder ensemble evite que l'apercu et le rendu divergent. */
.cat-logo-preview {
  width: 72px; height: 72px; flex-shrink: 0;
  border-radius: 16px;
  display: grid; place-items: center;
  overflow: hidden;
  background: rgba(16, 185, 129, .12);
  border: 1px solid rgba(16, 185, 129, .22);
  color: #10B981; font-size: 1.6rem; font-weight: 700;
}
.cat-logo-preview img { width: 100%; height: 100%; object-fit: cover; }

.cat-banner-preview {
  aspect-ratio: 16 / 7;
  border-radius: 14px;
  overflow: hidden;
  background: rgba(255, 255, 255, .04);
  border: 1px dashed rgba(16, 185, 129, .28);
  display: grid; place-items: center;
}
.cat-banner-preview img { width: 100%; height: 100%; object-fit: cover; }

.cat-banner-fallback { text-align: center; padding: 12px; }
.cat-banner-fallback strong { display: block; font-size: 1.35rem; color: #E2E8F0; }
.cat-banner-fallback span { display: block; margin-top: 4px; font-size: .74rem; color: #94A3B8; }


/* =========================================================================
   APERCU RAPIDE ET BOUTON WHATSAPP
   ========================================================================= */

/* ---------- Declencheur sur la carte ----------
   Cache par defaut : sans JavaScript il serait mort. Le script pose
   `.sf-has-quick-view` sur <html> une fois qu'il sait pouvoir l'honorer. */
.sf-qv-open { display: none; }

.sf-has-quick-view .sf-qv-open {
  display: grid;
  place-items: center;
  position: absolute;
  top: 14px; right: 14px;
  width: 34px; height: 34px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  border: var(--border-w) solid var(--border);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .12);
  cursor: pointer;
  z-index: 3;
  /* Sur telephone il n'y a pas de survol : le bouton reste visible. Sur
     ordinateur il s'efface jusqu'au survol de la carte, pour ne pas encombrer
     une grille de vingt-quatre vignettes. */
  opacity: 1;
  transition: opacity .2s ease, transform .2s ease;
}

@media (hover: hover) {
  .sf-has-quick-view .sf-qv-open { opacity: 0; transform: scale(.9); }
  .sf-has-quick-view .sf-card:hover .sf-qv-open,
  .sf-has-quick-view .sf-qv-open:focus-visible { opacity: 1; transform: scale(1); }
}

/* La carte doit etre le repere de positionnement du bouton. */
.sf-card { position: relative; }

/* ---------- Panneau ---------- */
.sf-qv-dialog {
  width: min(680px, calc(100vw - 24px));
  max-height: 88vh;
  padding: 0;
  border: none;
  border-radius: calc(var(--radius) + 6px);
  background: var(--surface);
  color: var(--ink);
  overflow: auto;
  box-shadow: 0 24px 60px -12px rgba(0, 0, 0, .4);
}
.sf-qv-dialog::backdrop { background: rgba(0, 0, 0, .55); }

.sf-qv-close {
  position: absolute; top: 8px; right: 10px; z-index: 2;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  font-size: 1.5rem; line-height: 1;
  border: none; border-radius: 999px;
  background: var(--surface-2); color: var(--ink-2);
  cursor: pointer;
}

.sf-qv { display: grid; grid-template-columns: 1fr; }
@media (min-width: 640px) { .sf-qv { grid-template-columns: 300px 1fr; } }

.sf-qv-media {
  position: relative;
  aspect-ratio: 1 / 1;
  background-color: hsl(var(--tint, 200) 26% 91%);
}
.sf-qv-media img { width: 100%; height: 100%; object-fit: cover; }
.sf-qv-media .ph { width: 100%; height: 100%; display: grid; place-items: center; color: var(--ink-3); }

.sf-qv-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; }
.sf-qv-name { font-size: 1.15rem; font-weight: 700; line-height: 1.25; margin: 0; }
.sf-qv-price { font-size: 1.25rem; font-weight: 700; color: var(--accent-dark); margin: 0; }
.sf-qv-desc { font-size: .86rem; line-height: 1.55; color: var(--ink-2); margin: 0; }
.sf-qv-out { font-size: .86rem; color: var(--danger); margin: 4px 0 0; }

.sf-qv-actions { display: flex; gap: 8px; margin-top: 6px; }
.sf-qv-qty { width: 72px; flex: none; text-align: center; }
.sf-qv-actions .sf-btn { flex: 1; }

.sf-qv-links { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; font-size: .83rem; }
.sf-qv-links a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; }
.sf-qv-links a:hover { color: var(--accent-dark); }
.sf-qv-wa { color: #128C7E !important; }

.sf-qv-loading { padding: 40px 20px; text-align: center; color: var(--ink-2); font-size: .88rem; }

/* ---------- Bouton WhatsApp flottant ----------
   Il se pose au-dessus de la barre de navigation basse, jamais dessus : sur
   telephone, `--bn-h` est la hauteur de cette barre, et l'ignorer mettrait le
   bouton par-dessus le panier. */
.sf-wa-fab {
  position: fixed;
  bottom: calc(var(--bn-h, 0px) + 16px);
  z-index: 60;
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: 999px;
  background: #25D366;
  color: #fff;
  box-shadow: 0 6px 18px rgba(37, 211, 102, .38);
  transition: transform .18s ease, box-shadow .18s ease;
}
.sf-wa-fab.is-right { right: 16px; }
.sf-wa-fab.is-left  { left: 16px; }
.sf-wa-fab:hover { transform: scale(1.06); box-shadow: 0 8px 24px rgba(37, 211, 102, .5); }

/* Le vert de WhatsApp est une couleur de marque : elle ne suit pas l'ambiance
   de la boutique, sous peine de ne plus etre reconnue. On l'assombrit
   seulement d'un cran en mode sombre, ou le vert vif brule. */
@media (prefers-color-scheme: dark) {
  .sf-wa-fab { background: #1FAF54; box-shadow: 0 6px 18px rgba(0, 0, 0, .5); }
  .sf-qv-open { background: var(--surface-2); }
  .sf-qv-dialog { box-shadow: 0 24px 60px -12px rgba(0, 0, 0, .8); }
  .sf-qv-media { background-color: hsl(var(--tint, 200) 14% 18%); }
  .sf-qv-wa { color: #4ADE80 !important; }
}

/* Le mouvement reduit ne doit pas figer le panneau hors de l'ecran. */
@media (prefers-reduced-motion: reduce) {
  .sf-has-quick-view .sf-qv-open { opacity: 1 !important; transform: none !important; }
}


/* =========================================================================
   ORANGE EN MODE SOMBRE — PRIX ET BOUTONS
   =========================================================================
   Meme regle que le panneau de gestion, meme mesure.

   L'orange n'est PAS pris dans `--accent` : ce jeton porte la couleur choisie
   par le commercant, qui peut etre bleue ou rouge. Le prix en orange est une
   decision de charte CLARIO, pas une teinte de boutique — on l'ecrit donc en
   dur, sans quoi elle suivrait la couleur du commercant et disparaitrait.
   ========================================================================= */

@media (prefers-color-scheme: dark) {
  :root {
    --price-ink: #FF8800;
    --orange: #FF6B00;
    /* 6,61:1 sur l'orange de marque. Le blanc n'y atteint que 2,86:1. */
    --orange-ink: #1A0E02;
  }

  .sf-card-price,
  .sf-qv-price,
  .sf-price,
  .sf-total-row strong,
  .sf-product-price {
    color: var(--price-ink) !important;
  }

  /* Le prix barre reste discret : deux oranges cote a cote, l'un barre, se
     lisent comme une erreur d'affichage. */
  .sf-price-was { color: var(--ink-3) !important; }

  /* Les boutons d'action. `.sf-btn-ghost` est volontairement exclu : c'est le
     bouton secondaire, et le repeindre supprimerait la hierarchie qui dit
     lequel des deux est l'action principale. */
  .sf-btn:not(.sf-btn-ghost):not(.sf-share-link) {
    background: var(--orange) !important;
    border-color: var(--orange) !important;
    color: var(--orange-ink) !important;
    font-weight: 700;
  }
  .sf-btn:not(.sf-btn-ghost):not(.sf-share-link):hover {
    background: #FF8800 !important;
    border-color: #FF8800 !important;
  }

  .sf-btn:not(.sf-btn-ghost) svg { color: var(--orange-ink); }

  .sf-btn:disabled,
  .sf-btn[aria-disabled="true"] {
    background: rgba(255, 107, 0, .26) !important;
    border-color: rgba(255, 107, 0, .26) !important;
    color: rgba(255, 255, 255, .55) !important;
  }

  /* Le bouton WhatsApp garde le vert de WhatsApp : c'est une couleur de
     marque tierce, la repeindre en orange la rendrait meconnaissable. */
  .sf-wa-fab { background: #1FAF54 !important; color: #fff !important; }
}
