/* Black High Society — Mini App Telegram
   Thème sombre / néon / glassmorphism (palette fixe, non liée au thème Telegram). */

:root {
  --bg-0: #0b0713;
  --bg-1: #17102b;
  --bg-2: #1f1440;

  --glass: rgba(26, 19, 48, 0.62);
  --glass-strong: rgba(30, 22, 56, 0.9);
  --stroke: rgba(255, 255, 255, 0.09);
  --stroke-strong: rgba(255, 255, 255, 0.16);

  --pink: #ff2d8e;
  --violet: #b026ff;
  --gold: #f5b400;
  --blue: #2f6bff;
  --cyan: #3fe6d2;
  --green: #37d67a;

  --accent: linear-gradient(135deg, #b026ff 0%, #ff2d8e 100%);
  --accent-soft: linear-gradient(135deg, rgba(176, 38, 255, 0.22), rgba(255, 45, 142, 0.22));

  --text: #f4f1ff;
  --text-muted: #a89fc9;
  --text-dim: #7b7098;

  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 24px;
  --r-pill: 999px;

  --glow: 0 10px 34px rgba(176, 38, 255, 0.28);
  --shadow: 0 12px 30px rgba(0, 0, 0, 0.45);

  --font-display: "Sora", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --nav-h: 62px;
  --nav-gap: 12px;   /* espace entre la pilule et le bas de l'ecran */
  --nav-side: 14px;  /* marge laterale de la pilule */
  /* Zones de securite. Sur les clients recents, la barre d'etat du telephone et
     l'en-tete Telegram (« Fermer », chevron, « ... ») flottent AU-DESSUS de la page.
     Telegram (Bot API 8.0+) renseigne --tg-*-inset-* ; sinon on retombe sur env(). */
  --safe-t: max(env(safe-area-inset-top, 0px),
                calc(var(--tg-safe-area-inset-top, 0px) + var(--tg-content-safe-area-inset-top, 0px)));
  --safe-b: max(env(safe-area-inset-bottom, 0px),
                calc(var(--tg-safe-area-inset-bottom, 0px) + var(--tg-content-safe-area-inset-bottom, 0px)));
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font-family: var(--font-body);
  color: var(--text);
  background: var(--bg-0);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  min-height: 100dvh;
}

/* Fond dégradé + halo aurora */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(47, 107, 255, 0.35), transparent 60%),
    radial-gradient(90% 50% at 90% 0%, rgba(176, 38, 255, 0.28), transparent 55%),
    linear-gradient(180deg, var(--bg-1) 0%, var(--bg-0) 45%, #070510 100%);
}

.app {
  max-width: 480px;
  margin: 0 auto;
  padding: calc(var(--safe-t) + 16px) 14px calc(var(--nav-h) + var(--nav-gap) + var(--safe-b) + 24px);
  position: relative;
}

img { max-width: 100%; display: block; }

/* ---------- Primitives ---------- */

.glass {
  background: var(--glass);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cyan);
  margin: 0 0 6px;
}

h1 {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
  font-size: 1.5rem;
}

.lead {
  color: var(--text-muted);
  font-size: 0.92rem;
  line-height: 1.5;
  margin: 0 0 18px;
}

.screen-title {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 800;
  margin: 6px 4px 16px;
}

.screen[hidden] { display: none; }
.screen--plain {
  min-height: calc(78vh - var(--safe-t));
  min-height: calc(78dvh - var(--safe-t));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
}

.empty {
  text-align: center;
  color: var(--text-dim);
  font-size: 0.9rem;
  padding: 28px 12px;
}

/* ---------- Boutons & champs ---------- */

.btn {
  width: 100%;
  border: none;
  border-radius: var(--r-pill);
  padding: 14px 18px;
  font-family: var(--font-body);
  font-size: 0.98rem;
  font-weight: 700;
  color: #fff;
  cursor: pointer;
  transition: transform 0.08s ease, filter 0.15s ease;
}
.btn:active { transform: scale(0.97); }

.btn--accent { background-image: var(--accent); box-shadow: var(--glow); }
.btn--gold { background: var(--gold); color: #201500; }
.btn--ghost {
  background: transparent;
  border: 1px solid var(--stroke-strong);
  color: var(--text);
  font-weight: 600;
}
.btn--lg { padding: 16px 20px; font-size: 1.05rem; }
.btn--sm { width: auto; padding: 8px 14px; font-size: 0.85rem; }

.field {
  width: 100%;
  padding: 13px 15px;
  border-radius: var(--r-sm);
  border: 1px solid var(--stroke-strong);
  background: rgba(0, 0, 0, 0.28);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
}
.field:focus-visible { outline: 2px solid var(--violet); outline-offset: 1px; }
textarea.field { resize: vertical; }


.field-label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-muted);
  margin: 12px 0 6px;
}

.field-error {
  color: #ff6b8a;
  font-size: 0.85rem;
  font-weight: 600;
  margin: 8px 0 0;
}

/* ---------- Onboarding ---------- */


/* ---------- Hero ---------- */

.hero {
  position: relative;
  padding: 0;
  overflow: hidden;
  border-radius: var(--r-lg);
  min-height: 208px;
  display: block;
}
/* L'image est dans le flux : la hauteur du hero suit son ratio, donc elle est
   affichee entiere (aucun recadrage) au lieu d'etre rognee en cover. */
.hero__media {
  position: relative;
  z-index: 0;
  min-height: 208px;
  background: linear-gradient(135deg, #2a1650 0%, #140c28 60%, #1c0f3a 100%);
}
.hero__media img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 62vh;
  max-height: 62dvh;
  object-fit: contain;
}
.hero__media img.is-broken { display: none; }
.hero__title { color: #fff; }
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(11, 7, 19, 0) 40%, rgba(11, 7, 19, 0.78) 100%);
}
.hero__overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 18px;
}
.hero__eyebrow {
  color: var(--cyan);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 10px 0 2px;
}
.hero__title {
  font-size: 1.9rem;
  line-height: 1;
  margin: 0;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.6);
}
.hero__accroche { color: var(--text-muted); font-size: 0.85rem; margin: 6px 0 0; }

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text);
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid var(--stroke);
  padding: 5px 10px;
  border-radius: var(--r-pill);
}
.status-pill .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 8px var(--green);
}
.status-pill--ok { background: rgba(55, 214, 122, 0.14); border-color: rgba(55, 214, 122, 0.4); }

/* ---------- Bandeau stats ---------- */

.stat-band {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  text-align: center;
  padding: 14px 8px;
  margin-top: 12px;
}
.stat-band > div { display: flex; flex-direction: column; gap: 2px; }
.stat-band > div + div { border-left: 1px solid var(--stroke); }
/* display:flex ci-dessus l'emportait sur hidden : sans avis, la colonne
   restait affichee avec un « — ». */
.stat-band > div[hidden] { display: none; }
.stat-band b { font-family: var(--font-display); font-size: 1.2rem; font-weight: 800; }
.stat-band__value { display: flex; align-items: center; justify-content: center; gap: 5px; }
.stat-band__emoji { font-size: 0.95rem; line-height: 1; }
.stat-band__label { font-size: 0.7rem; color: var(--text-dim); letter-spacing: 0.06em; }

/* Sans avis saisi, la colonne « Avis » disparait et la bande se reequilibre :
   afficher une note par defaut reviendrait a en inventer une. */
.stat-band--2 { grid-template-columns: repeat(2, 1fr); }

/* ---------- Bande d'avis ---------- */

.avis-bande {
  margin-top: 10px;
  overflow: hidden;
  /* Les cartes entrent et sortent en fondu plutot que d'etre tranchees net. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.avis-piste {
  display: flex;
  gap: 10px;
  width: max-content;
  /* Duree posee par le JS : elle depend du nombre de cartes, pour que la
     vitesse de defilement reste la meme quel que soit le nombre d'avis. */
  animation: avis-defile var(--avis-duree, 24s) linear infinite;
}
/* Un seul avis : rien ne defile, la carte occupe la largeur. */
.avis-piste--fixe { width: auto; animation: none; }
.avis-piste--fixe .avis-carte { width: auto; flex: 1 1 auto; }

@keyframes avis-defile {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.avis-carte {
  flex: 0 0 auto;
  width: 228px;
  background: var(--glass);
  border: 1px solid var(--stroke);
  border-radius: var(--r-sm);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.avis-tete { display: flex; align-items: center; gap: 7px; }
.avis-etoiles { color: var(--gold); font-size: 0.7rem; letter-spacing: 1px; }
.avis-auteur { font-size: 0.72rem; color: var(--text-muted); font-weight: 600; }
.avis-texte { font-size: 0.75rem; line-height: 1.38; }

@media (prefers-reduced-motion: reduce) {
  /* Fige la bande sur les premieres cartes, lisibles a l'arret. */
  .avis-piste { animation: none; }
}

/* ---------- En-têtes de section ---------- */

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 22px 4px 12px;
}
.section-head span {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
}
.section-head i {
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--cyan);
}

/* ---------- Carrousel catégories ---------- */

.cat-carousel {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding: 2px 4px 6px;
  -ms-overflow-style: none;
  scrollbar-width: none;
}
.cat-carousel::-webkit-scrollbar { display: none; }
.cat-card {
  scroll-snap-align: start;
  flex: 0 0 46%;
  border-radius: var(--r-md);
  padding: 12px;
  min-height: 118px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 4px;
  background: var(--accent-soft), var(--glass);
  border: 1px solid var(--stroke);
  color: var(--text);
  text-align: left;
  position: relative;
  overflow: hidden;
  cursor: pointer;
}
.cat-card__img {
  position: absolute; inset: 0;
  object-fit: cover; opacity: 0.5;
}
.cat-card__body { position: relative; }
.cat-card__name { font-family: var(--font-display); font-weight: 700; font-size: 0.98rem; }
.cat-card__count { font-size: 0.72rem; color: var(--text-muted); }
.cat-card.is-active { border-color: var(--pink); box-shadow: 0 0 0 1px var(--pink); }

/* ---------- Grille produits ---------- */

.product-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
.product-grid--scroll {
  display: flex;
  overflow-x: auto;
  scrollbar-width: none;
  /* Les cartes s'arretent une par une au lieu de rester a moitie coupees. */
  scroll-snap-type: x mandatory;
  scroll-padding-left: 4px;
}
.product-grid--scroll::-webkit-scrollbar { display: none; }
.product-grid--scroll .product-card { flex: 0 0 62%; scroll-snap-align: start; }

.product-card {
  background: var(--glass);
  border: 1px solid var(--stroke);
  border-radius: var(--r-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  cursor: pointer;
}
.product-card__media {
  position: relative;
  aspect-ratio: 1 / 1;
  background: linear-gradient(135deg, #241640, #120c24);
}
.product-card__media img { width: 100%; height: 100%; object-fit: cover; }
.media-badge {
  position: absolute;
  top: 8px; left: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.68rem;
  font-weight: 700;
  color: #06231f;
  background: var(--cyan);
  padding: 3px 8px;
  border-radius: var(--r-pill);
}
.promo-badge {
  position: absolute;
  right: 8px; bottom: 8px;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 800;
  color: #fff;
  background: var(--pink);
  padding: 3px 8px;
  border-radius: var(--r-pill);
  box-shadow: 0 4px 14px rgba(255, 45, 142, 0.45);
}
.prix-barre {
  font-size: 0.75rem;
  color: var(--text-dim);
  text-decoration: line-through;
}
.product-card__price { flex-wrap: wrap; column-gap: 5px; row-gap: 0; }
.product-card__price b.is-promo { color: var(--pink); }
.variant-chip .prix-barre { margin-left: 4px; }
.promo-meetup {
  align-self: flex-start;
  margin-top: 6px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 45, 142, 0.5);
  background: rgba(255, 45, 142, 0.14);
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.3;
  color: #ff8cc3;
}
.prix-condition { font-size: 0.66rem; font-weight: 600; color: var(--pink); margin-top: 2px; }
.sheet .prix-condition { font-size: 0.8rem; margin: -4px 0 10px; }
.cart-promo {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(255, 45, 142, 0.4);
  background: rgba(255, 45, 142, 0.1);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
}
.cart-promo.is-appliquee { border-color: rgba(55, 214, 122, 0.45); background: rgba(55, 214, 122, 0.1); }
.fav-heart {
  position: absolute;
  top: 6px; right: 6px;
  width: 30px; height: 30px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  cursor: pointer;
}
.fav-heart svg { width: 16px; height: 16px; fill: none; stroke: #fff; stroke-width: 2; }
.fav-heart.is-on svg { fill: var(--pink); stroke: var(--pink); }

.quality-badge {
  position: absolute;
  left: 8px; bottom: 8px;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--gold);
  background: rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(245, 180, 0, 0.4);
  padding: 3px 7px;
  border-radius: var(--r-pill);
}

.product-card__body { padding: 10px 11px 12px; display: flex; flex-direction: column; gap: 3px; flex: 1; }
.product-card__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.92rem;
  line-height: 1.2;
}
.product-card__farm {
  font-size: 0.7rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.product-card__price {
  margin-top: auto;
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding-top: 6px;
}
.product-card__price small { font-size: 0.6rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.08em; }
.product-card__price b {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
  color: #fff;
}
.product-card__cta {
  margin-top: 8px;
  align-self: flex-start;
  font-size: 0.72rem;
  font-weight: 700;
  color: #fff;
  background-image: var(--accent);
  border: none;
  border-radius: var(--r-pill);
  padding: 6px 14px;
  cursor: pointer;
}

/* ---------- Bottom sheet fiche produit ---------- */

.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(4, 2, 10, 0.6);
  backdrop-filter: blur(2px);
  z-index: 40;
}
.sheet-backdrop[hidden] { display: none; }

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  max-width: 480px;
  margin: 0 auto;
  max-height: calc(88vh - var(--safe-t));
  max-height: calc(88dvh - var(--safe-t));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--glass-strong);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  backdrop-filter: blur(18px);
  animation: sheet-up 0.22s ease;
}
.sheet[hidden] { display: none; }

/* La barre du haut ne defile pas : la croix reste toujours accessible, et la
   poignee sert de prise pour glisser la fiche vers le bas. */
.sheet__barre {
  position: relative;
  flex: none;
  padding: 10px 16px 4px;
  touch-action: none;
}
.sheet__fermer {
  position: absolute;
  top: 6px; right: 10px;
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 1px solid var(--stroke-strong);
  background: rgba(0, 0, 0, 0.35);
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}
/* Agrandit la zone tactile a 44 px sans grossir le rond. */
.sheet__fermer::after { content: ""; position: absolute; inset: -4px; }
.sheet__corps {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 8px 16px 16px;
}
.sheet__pied {
  flex: none;
  padding: 12px 16px calc(var(--safe-b) + 14px);
  border-top: 1px solid var(--stroke);
  background: rgba(16, 11, 30, 0.92);
}
/* Sans pied (fiche indisponible), le corps garde la marge du bas d'ecran. */
.sheet__corps:last-child { padding-bottom: calc(var(--safe-b) + 20px); }
.sheet__action { display: flex; align-items: center; gap: 12px; }
.sheet__action .qty-row { margin: 0; gap: 8px; flex: none; }
.sheet__action .btn { flex: 1; min-width: 0; white-space: nowrap; padding-left: 14px; padding-right: 14px; }
/* Petits ecrans : quantite au-dessus du bouton, sinon le montant debordait. */
@media (max-width: 359px) {
  .sheet__action { flex-direction: column; align-items: stretch; gap: 10px; }
  .sheet__action .qty-row { justify-content: center; }
}
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }

.sheet__grip {
  width: 40px; height: 4px;
  border-radius: 4px;
  background: var(--stroke-strong);
  margin: 4px auto 10px;
}
.sheet__gallery {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  border-radius: var(--r-md);
  margin-bottom: 12px;
  /* Sans cela, les vignettes s'etirent toutes a la hauteur de la plus grande
     et retrouvent une boite commune : chacune doit garder sa propre hauteur. */
  align-items: flex-start;
}
.sheet__gallery::-webkit-scrollbar { display: none; }
.sheet__gallery > * {
  flex: 0 0 78%;
  /* --ratio est pose par le JS des que les dimensions reelles du media sont
     connues. Le repli 4/3 ne sert que le temps du chargement. */
  aspect-ratio: var(--ratio, 4 / 3);
  /* contain et non cover : une video verticale (9/16) dans une boite paysage
     perdait 58 % de sa hauteur, coupee moitie en haut moitie en bas. */
  object-fit: contain;
  /* Un media tres allonge ne doit pas prendre tout l'ecran. */
  max-height: 62vh;
  max-height: 62dvh;
  border-radius: var(--r-md);
  background: #160f2b;
  scroll-snap-align: center;
}
.sheet__gallery--empty {
  height: 150px;
  background: linear-gradient(135deg, #241640, #120c24);
  display: grid; place-items: center;
  color: var(--text-dim);
  font-size: 0.8rem;
}
.sheet__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
/* Dans la fiche, le coeur se place a cote du nom : en absolu, il se posait sur
   la croix de fermeture. */
.sheet__head .fav-heart { position: relative; top: auto; right: auto; flex: none; width: 40px; height: 40px; }
.sheet__head .fav-heart svg { width: 20px; height: 20px; }
.sheet h2 { font-family: var(--font-display); font-size: 1.3rem; margin: 0; }
.sheet__farm { color: var(--text-dim); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; }
.sheet__desc { color: var(--text-muted); font-size: 0.9rem; line-height: 1.5; margin: 10px 0 4px; }

.variant-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.variant-chip {
  border: 1px solid var(--stroke-strong);
  background: rgba(0, 0, 0, 0.25);
  color: var(--text);
  border-radius: var(--r-pill);
  padding: 8px 13px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}
.variant-chip b { font-family: var(--font-display); margin-left: 6px; }
.variant-chip.is-active { border-color: var(--pink); background: var(--accent-soft); }

.qty-row { display: flex; align-items: center; gap: 14px; margin: 12px 0 16px; }
.qty-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid var(--stroke-strong);
  background: rgba(255, 255, 255, 0.05);
  color: #fff;
  font-size: 1.2rem;
  font-weight: 700;
  cursor: pointer;
}
.qty-val { font-family: var(--font-display); font-weight: 800; min-width: 1.5em; text-align: center; }

/* ---------- Panier ---------- */

.cart-lines { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.cart-line {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: var(--r-md);
  background: var(--glass);
  border: 1px solid var(--stroke);
}
.cart-line__thumb {
  width: 52px; height: 52px;
  border-radius: 12px;
  object-fit: cover;
  background: #160f2b;
  flex: none;
}
.cart-line__info { flex: 1; min-width: 0; }
.cart-line__name { font-weight: 600; font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cart-line__meta { font-size: 0.75rem; color: var(--text-dim); }
.cart-line__stepper { display: flex; align-items: center; gap: 4px; flex: none; }
.cart-line__stepper button {
  width: 44px; height: 44px;
  font-size: 1.05rem;
  border-radius: 50%;
  border: 1px solid var(--stroke-strong);
  background: rgba(255,255,255,0.05);
  color: #fff; font-weight: 700; cursor: pointer;
}
.cart-line__stepper button.is-retirer { font-size: 0.95rem; border-color: rgba(255, 107, 138, 0.45); }
.cart-line__stepper b { font-family: var(--font-display); min-width: 1.2em; text-align: center; }

.cart-summary { padding: 16px; }
.cart-row { display: flex; justify-content: space-between; align-items: baseline; padding: 5px 0; font-size: 0.92rem; color: var(--text-muted); }
.cart-row b { font-family: var(--font-display); color: var(--text); }
.cart-row--total { border-top: 1px dashed var(--stroke-strong); margin-top: 6px; padding-top: 12px; font-size: 1.05rem; }
.cart-row--total b { font-size: 1.25rem; color: var(--cyan); }
.cart-note { font-size: 0.8rem; color: var(--text-dim); margin: 8px 0 4px; }
.cart-summary .btn { margin-top: 14px; }

.retrait-choix { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.retrait-option {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  min-height: 56px;
  padding: 10px 12px;
  border: 1px solid var(--stroke-strong);
  border-radius: var(--r-sm);
  background: rgba(0, 0, 0, 0.25);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.retrait-option.is-active { border-color: var(--pink); background: var(--accent-soft); }
.retrait-option:focus-visible { outline: 2px solid var(--violet); outline-offset: 1px; }
.retrait-option__titre { font-family: var(--font-display); font-weight: 700; font-size: 0.92rem; }
.retrait-option__detail { font-size: 0.75rem; color: var(--text-muted); }

.meetup-info {
  margin-top: 12px;
  padding: 12px;
  border: 1px dashed var(--stroke-strong);
  border-radius: var(--r-sm);
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.45;
}
.meetup-info p { margin: 0; }
.meetup-info b { color: var(--text); }
.meetup-info .btn {
  display: block;
  box-sizing: border-box;
  width: 100%;
  margin-top: 10px;
  text-align: center;
  text-decoration: none;
}
.cart-row[hidden] { display: none; }
.confirm-card .meetup-info { margin: 0 0 14px; text-align: left; }

/* ---------- Profil ---------- */

.profil-card { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.profil-id { display: flex; align-items: center; gap: 12px; }
.profil-avatar {
  width: 48px; height: 48px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: 800;
  background-image: var(--accent);
  color: #fff;
}
.profil-id b { font-family: var(--font-display); font-size: 1.05rem; display: block; margin-bottom: 4px; }

.orders { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.order {
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: var(--glass);
  border: 1px solid var(--stroke);
}
.order__top { display: flex; justify-content: space-between; align-items: baseline; }
.order__id { font-family: var(--font-display); font-weight: 700; }
.order__total { font-family: var(--font-display); color: var(--cyan); }
.order__meta { font-size: 0.76rem; color: var(--text-dim); margin-top: 3px; }
.order__status {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--text);
}

/* ---------- Confirmation ---------- */

.confirm-card { padding: 28px 22px; text-align: center; }
.stamp {
  display: inline-block;
  border: 3px solid var(--green);
  color: var(--green);
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding: 8px 18px;
  border-radius: 8px;
  transform: rotate(-4deg);
  margin-bottom: 16px;
}
.confirm-card .btn { margin-top: 18px; }

/* ---------- Admin ---------- */

.admin-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.admin-tabs { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin-bottom: 14px; }
.admin-tabs::-webkit-scrollbar { display: none; }
.admin-tabs button {
  flex: none;
  border: 1px solid var(--stroke-strong);
  background: transparent;
  color: var(--text-muted);
  border-radius: var(--r-pill);
  padding: 8px 14px;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}
.admin-tabs button.is-active { background-image: var(--accent); color: #fff; border-color: transparent; }
.admin-panel { display: flex; flex-direction: column; gap: 12px; }
.admin-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: var(--glass);
  border: 1px solid var(--stroke);
}
.admin-row__name { font-weight: 600; }
.admin-row__meta { font-size: 0.75rem; color: var(--text-dim); }
.admin-actions { display: flex; gap: 6px; }
.admin-form { display: flex; flex-direction: column; gap: 10px; padding: 14px; }
.admin-form .field { font-size: 0.92rem; }
.admin-variantes { display: flex; flex-direction: column; gap: 8px; }
.admin-variante-row { display: flex; gap: 8px; }
.admin-variante-row .field { flex: 1; }

/* Un avis tient sur une colonne : quatre champs cote a cote seraient illisibles
   sur un telephone, et le texte a besoin de toute la largeur. */
.admin-avis-liste { display: flex; flex-direction: column; gap: 14px; }
.admin-avis-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--stroke);
  border-radius: var(--r-sm);
  background: rgba(0, 0, 0, 0.18);
}
.admin-avis-row .admin-actions { margin-top: 2px; }
.chip-add {
  align-self: flex-start;
  background: transparent;
  border: 1px dashed var(--stroke-strong);
  color: var(--text-muted);
  border-radius: var(--r-pill);
  padding: 7px 14px;
  font-size: 0.8rem;
  cursor: pointer;
}
.admin-media-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.admin-media-grid figure { position: relative; margin: 0; }
.admin-media-grid img, .admin-media-grid video {
  width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 10px; background: #160f2b;
}
.admin-media-grid button {
  position: absolute; top: 3px; right: 3px;
  width: 22px; height: 22px; border-radius: 50%;
  border: none; background: rgba(0,0,0,0.6); color: #fff; cursor: pointer;
}
.admin-hint { font-size: 0.78rem; color: var(--text-dim); }

/* Codes d'invitation */
.code-generator { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.code-generator .field { flex: 1; }
.code-generator .btn { white-space: nowrap; }
.code-fresh {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 12px;
}
.code-fresh > div { flex: 1; min-width: 0; }
.code-fresh__value {
  font-family: var(--font-display);
  font-size: 1.5rem;
  letter-spacing: 0.16em;
  color: #fff;
}

/* ---------- Barre d'onglets ---------- */

/* Verre liquide : la pilule laisse passer l'aurora du fond, la lentille glisse
   d'un onglet a l'autre en se deformant comme une goutte. */
.bottom-nav {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--safe-b) + var(--nav-gap));
  z-index: 30;
  width: min(480px, calc(100% - var(--nav-side) * 2));
  margin: 0 auto;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 0 14px;
  border-radius: var(--r-pill);
  isolation: isolate;
  background: rgba(12, 8, 22, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.05);
  -webkit-backdrop-filter: blur(22px) saturate(1.9) brightness(1.06);
  backdrop-filter: blur(22px) saturate(1.9) brightness(1.06);
  box-shadow:
    0 18px 40px rgba(0, 0, 0, 0.55),
    0 4px 12px rgba(0, 0, 0, 0.32),
    inset 0 -8px 20px rgba(176, 38, 255, 0.10);
}

/* Teinte + reflet specular : le verre prend la couleur de ce qu'il y a derriere */
.bottom-nav::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(130% 180% at 10% -40%, rgba(176, 38, 255, 0.30), transparent 62%),
    radial-gradient(130% 180% at 90% -40%, rgba(47, 107, 255, 0.24), transparent 62%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0) 44%);
}

/* Rim refractif : la lumiere se concentre sur deux arcs opposes, pas sur tout le tour */
.bottom-nav::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  pointer-events: none;
  padding: 1px;
  background: linear-gradient(
    140deg,
    rgba(255, 255, 255, 0.52) 0%,
    rgba(255, 255, 255, 0.06) 34%,
    rgba(255, 255, 255, 0.03) 62%,
    rgba(255, 255, 255, 0.34) 100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}

/* Repli si le flou n'est pas supporte : fond opaque, sinon les icones deviennent illisibles */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bottom-nav { background: rgba(12, 8, 22, 0.97); }
  .nav-lens__drop { background: rgba(255, 255, 255, 0.14); }
}

.bottom-nav[hidden] { display: none; }

/* ---- La lentille qui glisse ---- */
.nav-lens {
  position: absolute;
  top: 50%;
  left: 0;
  z-index: 1;
  width: var(--lens-w, 56px);
  height: 44px;
  margin-top: -22px;
  border-radius: var(--r-pill);
  transform: translateX(var(--lens-x, 0px));
  opacity: 0;
  pointer-events: none;
  transition:
    transform 0.52s cubic-bezier(0.32, 1.28, 0.42, 1),
    width 0.52s cubic-bezier(0.32, 1.28, 0.42, 1),
    opacity 0.22s ease;
}
.bottom-nav.lentille-visible .nav-lens { opacity: 1; }

.nav-lens__drop {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: linear-gradient(
    155deg,
    rgba(255, 255, 255, 0.34) 0%,
    rgba(255, 255, 255, 0.10) 42%,
    rgba(255, 45, 142, 0.26) 100%
  );
  -webkit-backdrop-filter: blur(3px) saturate(1.9) brightness(1.42);
  backdrop-filter: blur(3px) saturate(1.9) brightness(1.42);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -8px 16px rgba(176, 38, 255, 0.34),
    0 6px 20px rgba(176, 38, 255, 0.40);
}

/* Ecrasement pendant le trajet : c'est ce qui fait « liquide » plutot que « bloc qui coulisse » */
@keyframes lens-goutte {
  0%   { transform: scale(1, 1); }
  32%  { transform: scale(1.26, 0.84); }
  68%  { transform: scale(0.94, 1.06); }
  100% { transform: scale(1, 1); }
}
.bottom-nav.is-gliding .nav-lens__drop {
  animation: lens-goutte 0.52s cubic-bezier(0.32, 1.12, 0.5, 1);
}

/* Posee sur le SHOP, la lentille n'a que ses bords visibles : on renforce le halo
   pour que l'arrivee se lise quand meme. */
.bottom-nav.lentille-shop .nav-lens__drop {
  border-color: rgba(255, 255, 255, 0.28);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    0 3px 16px rgba(255, 45, 142, 0.38);
}

.bottom-nav button {
  position: relative;
  z-index: 2;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-dim);
  padding: 0 8px;
  cursor: pointer;
  transition: color 0.28s ease;
}
.bottom-nav svg {
  width: 24px;
  height: 24px;
  display: block;
  /* Icones au trait : sous le verre depoli, des silhouettes pleines forment une
     seconde masse opaque et le SHOP magenta cesse d'etre le seul bloc plein. */
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.bottom-nav button:not(.nav-center) {
  flex-direction: column;
  gap: 2px;
  height: 44px;
}
.bottom-nav button:not(.nav-center) svg { width: 21px; height: 21px; }
.nav-label {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
}
.bottom-nav button.is-active { color: #fff; }
.bottom-nav button.is-active svg { filter: drop-shadow(0 0 8px var(--pink)); }
.bottom-nav button:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  border-radius: var(--r-pill);
}

@media (prefers-reduced-motion: reduce) {
  .nav-lens { transition: opacity 0.22s ease; }
  .bottom-nav.is-gliding .nav-lens__drop { animation: none; }
}

/* SHOP : meme hauteur et meme arrondi que les autres onglets, juste plus large
   et rempli de magenta. Plus de cercle sureleve : la lentille le traite comme
   les quatre autres. */
.nav-center {
  padding: 0 18px;
  background-image: var(--accent) !important;
  color: #fff !important;
  box-shadow: 0 2px 10px rgba(176, 38, 255, 0.28);
}
.nav-center span {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
}

.nav-badge {
  position: absolute;
  top: 0; right: 0;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: var(--r-pill);
  background: var(--pink);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 800;
  display: grid;
  place-items: center;
}
.nav-badge[hidden] { display: none; }

/* ---------- Accessibilité ---------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .sheet { animation: none; }
  .btn:active { transform: none; }
}

/* ---------- Ecran de chargement ---------- */
/* Present dans le HTML, donc peint avant meme que les modules JS soient parses :
   le client voit la marque, jamais une page blanche. */

.loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  padding: 32px;
  background:
    radial-gradient(120% 80% at 50% 0%, var(--bg-2) 0%, var(--bg-1) 45%, var(--bg-0) 100%);
  opacity: 1;
  transition: opacity 0.35s ease;
}
.loader.is-parti { opacity: 0; pointer-events: none; }
.loader__mark {
  text-align: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.7rem;
  line-height: 1.05;
  letter-spacing: 0.02em;
  color: #fff;
  text-shadow: 0 0 24px rgba(176, 38, 255, 0.55);
}
.loader__mark span { display: block; color: var(--gold); }
.loader__barre {
  width: min(180px, 60vw);
  height: 3px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}
/* Barre indeterminee : la duree du chargement depend du reseau, on ne peut pas
   promettre un pourcentage. */
.loader__barre span {
  display: block;
  width: 40%;
  height: 100%;
  border-radius: inherit;
  background-image: var(--accent);
  animation: loader-glisse 1.1s ease-in-out infinite;
}
@keyframes loader-glisse {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
.loader__texte { margin: 0; font-size: 0.85rem; color: var(--text-dim); }

/* ---------- Admin : tableau de bord ---------- */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.stat-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px;
  text-align: left;
  border-radius: var(--r-md);
  background: var(--glass);
  border: 1px solid var(--stroke);
  color: var(--text);
  font: inherit;
}
.stat-tile--clic { cursor: pointer; }
.stat-tile--clic:hover { border-color: var(--stroke-strong); }
.stat-tile__valeur {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.45rem;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.stat-tile__label { font-size: 0.72rem; color: var(--text-dim); }

.stock-pastille {
  padding: 4px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--stroke-strong);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.stock-pastille.is-epuise { color: #ff6b8a; border-color: rgba(255, 107, 138, 0.45); }

/* ---------- Admin : commandes ---------- */

.cmd-filtres { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.cmd-filtres::-webkit-scrollbar { display: none; }
.cmd-filtre {
  flex: none;
  border: 1px solid var(--stroke-strong);
  background: transparent;
  color: var(--text-muted);
  border-radius: var(--r-pill);
  padding: 7px 13px;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}
.cmd-filtre.is-active { background-image: var(--accent); color: #fff; border-color: transparent; }

.cmd-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  /* Le liseré porte le statut : la couleur se lit avant le texte quand on
     parcourt une liste de commandes. */
  border-left: 3px solid var(--text-dim);
}
.cmd-card[data-statut="nouvelle"] { border-left-color: var(--pink); }
.cmd-card[data-statut="en_preparation"] { border-left-color: var(--gold); }
.cmd-card[data-statut="en_livraison"] { border-left-color: var(--blue); }
.cmd-card[data-statut="livree"] { border-left-color: var(--green); }
.cmd-card[data-statut="annulee"] { border-left-color: var(--text-dim); opacity: 0.62; }

.cmd-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.cmd-card__titre { font-weight: 600; }
.cmd-card__meta { font-size: 0.75rem; color: var(--text-dim); }
.cmd-card__total {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: #fff;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.cmd-card__lignes { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.cmd-card__lignes li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.cmd-card__lignes b { color: var(--text); font-variant-numeric: tabular-nums; }
.cmd-card__adresse { margin: 0; font-size: 0.8rem; color: var(--text-dim); }
.cmd-card__decision { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.cmd-card__decision .btn { width: 100%; }

/* ---------- Admin : erreurs de chargement ---------- */

.admin-erreur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: rgba(255, 107, 138, 0.08);
  border: 1px solid rgba(255, 107, 138, 0.3);
}
.admin-erreur__texte { margin: 0; font-size: 0.84rem; color: #ff9db2; }

/* ---------- Stock cote client ---------- */

.admin-variante-row__stock { max-width: 92px; }

.variant-chip__stock {
  display: block;
  margin-top: 2px;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--gold);
}
.variant-chip__stock.is-epuise { color: var(--text-dim); }
.variant-chip.is-epuise {
  opacity: 0.5;
  cursor: not-allowed;
  text-decoration: line-through;
}
.variant-chip.is-epuise b { text-decoration: line-through; }
.btn.is-disabled { opacity: 0.45; cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
  .loader__barre span { animation: none; width: 100%; }
  .loader { transition: none; }
}

/* Message d'erreur sous une ligne admin : il passe a la ligne au lieu de
   s'intercaler entre le nom et les boutons. */
.admin-row { flex-wrap: wrap; }
.admin-row .field-error { flex-basis: 100%; margin: 4px 0 0; }

/* ---------- Image de categorie ---------- */

.cat-choix {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.cat-choix .admin-hint { margin: 0; }
.cat-apercu {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--r-sm);
  object-fit: cover;
  border: 1px solid var(--stroke-strong);
  background: #160f2b;
}

/* ---------- Corrections issues de l'audit ---------- */

/* Erreur de chargement cote client : distingue une panne d'une liste vide. */
.bandeau-erreur {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  grid-column: 1 / -1;
  padding: 14px 16px;
  border-radius: var(--r-md);
  background: rgba(255, 107, 138, 0.08);
  border: 1px solid rgba(255, 107, 138, 0.3);
}
.bandeau-erreur__texte { margin: 0; font-size: 0.86rem; color: #ff9db2; }

.sheet__erreur { padding: 8px 0 4px; }
.sheet__erreur h2 { font-family: var(--font-display); font-size: 1.2rem; margin: 0 0 8px; }

/* Le stock se regle a part du reste du formulaire : la ligne porte son propre
   message d'erreur sous les champs. */
.admin-variante { display: flex; flex-direction: column; gap: 6px; }
.admin-variante .field-error { margin: 0; }
.admin-variante-promo { display: flex; align-items: center; gap: 8px; }
.admin-variante-promo .field { flex: 1; }
.admin-variante-promo__label { font-size: 0.78rem; font-weight: 700; color: var(--pink); white-space: nowrap; }
.admin-variante-promo__remise { min-width: 3.2em; font-family: var(--font-display); font-weight: 800; color: var(--pink); }
.admin-variante-promo__remise.is-erreur { font-family: var(--font-body); font-size: 0.72rem; font-weight: 600; color: #ff6b8a; }

/* Cibles tactiles : 44 px est le minimum confortable au doigt. L'audit a
   releve des boutons a 22, 30 et 38 px sur une application 100 % mobile. */
.qty-btn { width: 44px; height: 44px; }
.bottom-nav button { min-height: 44px; min-width: 44px; }
.variant-chip { min-height: 44px; }
.btn--sm { min-height: 40px; }
.admin-tabs button { min-height: 40px; }
.cmd-filtre { min-height: 40px; }

/* Le coeur et la croix gardent leur taille visuelle mais gagnent une zone de
   tap : rater le coeur ouvrait la fiche produit.
   Surtout ne pas toucher a leur `position` : les deux sont deja `absolute`,
   epingles dans un coin de leur carte. Les passer en `relative` les decrochait
   de ce coin — et c'etait inutile, un element `absolute` est deja un contexte
   de positionnement pour son pseudo-element. */
.fav-heart::after,
.admin-media-grid button::after {
  content: "";
  position: absolute;
  inset: -8px;
}

/* Contraste : #7b7098 tombait a 4,12:1 sur le verre, sous le seuil AA de 4,5
   pour du petit texte — or les 18 usages sont tous en petit texte. */
:root { --text-dim: #9a8fb8; }

/* Une variante epuisee doit rester lisible : opacite 0.5 sur du texte deja
   fonce donnait 1,92:1, illisible. */
.variant-chip.is-epuise { opacity: 1; color: var(--text-dim); border-style: dashed; }
.variant-chip.is-epuise b { color: var(--text-dim); }
.variant-chip__stock.is-epuise { color: #ff9db2; }


/* ══════════════════════════════════════════════════════════════
   ECRAN D'ACCES — style repris tel quel de la mini app Chocolat
   (static/style.css : #gate-screen, .bhs-*, .halftone).
   Les variables de cette app y sont redeclarees a l'identique et
   restent confinees a ces deux ecrans : le reste de la boutique
   garde ses propres jetons.
   ══════════════════════════════════════════════════════════════ */

.gate-screen {
  --void: #0B0512;
  --magenta: #F5186B;
  --magenta-lt: #FF4D8D;
  --gold: #FFB020;
  --electric: #2D6BFF;
  --chalk: #FFFFFF;
  --bg: #0B0512;
  --bg2: #150A22;
  --bg3: #241038;
  --text: #F6F0FF;
  --text2: #E4D4FF;
  --hint: #A99AC4;
  --accent: #F5186B;
  --accent2: #FF4D8D;
  --border-md: rgba(245, 24, 107, 0.26);
  --danger: #FF3B5C;
  --radius-sm: 12px;
  --t: 0.15s ease;
  --t-fast: 0.1s ease;

  position: relative;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100dvh - var(--safe-t));
  padding: 32px 24px;
  background: var(--bg);
  font-family: "Rubik", -apple-system, BlinkMacSystemFont, sans-serif;
  color: var(--text);
  /* Annule la gouttiere de .app : la trame doit atteindre les bords. */
  margin: calc((var(--safe-t) + 16px) * -1) -14px
    calc((var(--nav-h) + var(--nav-gap) + var(--safe-b) + 24px) * -1);
}
.gate-screen:not([hidden]) { display: flex; }

.gate-wrapper {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 13px;
  width: 100%;
  max-width: 320px;
}
.gate-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2.6px;
  text-transform: uppercase;
  color: var(--gold);
  margin-top: 6px;
  text-align: center;
}
.gate-subtitle {
  font-size: 14px;
  color: var(--hint);
  text-align: center;
  line-height: 1.6;
}
.gate-screen input {
  width: 100%;
  padding: 13px 14px;
  border: 1.5px solid var(--border-md);
  border-radius: var(--radius-sm);
  background: var(--bg3);
  color: var(--text);
  font-size: 15px;
  font-family: inherit;
  outline: none;
  transition: border-color var(--t), background var(--t);
  -webkit-appearance: none;
  min-height: 50px;
}
.gate-screen input:focus {
  border-color: var(--accent);
  background: rgba(245, 24, 107, 0.06);
}
#champ-code {
  text-align: center;
  font-family: "Rubik", inherit;
  font-size: 28px;
  font-weight: 700;
  letter-spacing: 8px;
  text-transform: uppercase;
  padding: 16px 12px;
  margin-top: 6px;
}
#champ-code::placeholder {
  letter-spacing: 8px;
  color: var(--hint);
  opacity: 0.4;
  font-weight: 600;
}
.gate-error {
  font-size: 13px;
  color: var(--danger);
  text-align: center;
  min-height: 1em;
  font-weight: 600;
}
.gate-screen .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 13px 18px;
  border: 1.5px solid transparent;
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 600;
  font-family: "Rubik", inherit;
  cursor: pointer;
  transition: opacity var(--t), transform var(--t-fast), background var(--t);
  min-height: 50px;
  letter-spacing: 0.1px;
}
.gate-screen .btn:active { opacity: 0.75; transform: scale(0.97); }
.gate-screen .btn:disabled { opacity: 0.4; pointer-events: none; }
.gate-screen .btn-primary {
  background: var(--accent);
  color: #fff;
  width: 100%;
  border-color: var(--accent);
}
.gate-screen .btn-primary:active { background: var(--accent2); }

.gate-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  background: var(--bg3);
  border: 1px solid var(--border-md);
  color: var(--text2);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--t);
}
.gate-link:active { background: var(--bg2); }
.gate-id { font-size: 11px; color: var(--hint); margin-top: 4px; }

@keyframes gate-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}
.gate-wrapper.shake { animation: gate-shake 0.45s ease; }

/* Lettrage sticker repris du logo : contour blanc, relief bleu,
   trois couleurs (noir / or / magenta). */
.bhs-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 0.88;
  transform: rotate(-2deg);
}
.bhs-word {
  font-family: "Bowlby One", "Rubik", sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  paint-order: stroke fill;
  -webkit-text-stroke: 7px var(--chalk);
  text-shadow: 0 5px 0 var(--electric), 0 8px 12px rgba(0, 0, 0, 0.55);
  font-size: clamp(30px, 10.5vw, 44px);
}
.bhs-word.w-black { color: #120716; }
.bhs-word.w-high { color: var(--gold); }
.bhs-word.w-society { color: var(--magenta); font-size: clamp(26px, 9vw, 38px); }
.bhs-crown { color: var(--gold); filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5)); }

/* Trame halftone — la texture dominante du logo. */
.halftone::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle, rgba(245, 24, 107, 0.55) 1.7px, transparent 1.8px),
    radial-gradient(circle, rgba(255, 176, 32, 0.42) 1.7px, transparent 1.8px);
  background-size: 11px 11px, 11px 11px;
  background-position: 0 0, 5.5px 5.5px;
  -webkit-mask-image: radial-gradient(ellipse 80% 90% at 18% 0%, #000 0%, transparent 70%);
  mask-image: radial-gradient(ellipse 80% 90% at 18% 0%, #000 0%, transparent 70%);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .gate-wrapper.shake { animation: none; }
}


/* ---------- Images introuvables ---------- */

/* Voir app.js : la case reste en place avec son fond, sans l'icone d'image cassee. */
img.is-broken { visibility: hidden; }

/* ---------- Confort tactile ---------- */

/* Pas de flash gris a chaque appui : les boutons ont leur propre retour visuel. */
html { -webkit-tap-highlight-color: transparent; }
.product-card, .cat-card, .variant-chip, .qty-btn, .cart-line__stepper button, .retrait-option {
  transition: transform 0.1s ease, opacity 0.1s ease;
}
.product-card:active, .cat-card:active { transform: scale(0.98); }
.variant-chip:active, .qty-btn:active, .cart-line__stepper button:active,
.retrait-option:active, .sheet__fermer:active { opacity: 0.7; }

/* Bouton bloque pendant un envoi */
.btn.is-busy { opacity: 0.7; pointer-events: none; }

/* Fiche ouverte : la page derriere ne defile plus. */
html.sheet-ouverte, html.sheet-ouverte body { overflow: hidden; }

/* Clavier ouvert : la barre d'onglets fixe remontait au-dessus du clavier et
   cachait le champ en cours de saisie. */
html.clavier-ouvert .bottom-nav { display: none; }

/* Le titre de la grille, cible du defilement apres un filtre, ne doit pas
   finir sous l'en-tete Telegram. */
#tete-grille { scroll-margin-top: calc(var(--safe-t) + 12px); }

@media (prefers-reduced-motion: reduce) {
  .product-card:active, .cat-card:active { transform: none; }
}
