/* ═══════════════════════════════════════════════════════════
   UI v2 — WANILO EXPRESS+
   Composants génériques (DESIGN.md §5). Partagé par toutes les pages v2 —
   rien de spécifique à la boutique ici (ça vit dans shop/boutique.css).
   Nécessite css/v2/tokens.css chargé avant ce fichier.
   ═══════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

/* ── Barre de navigation translucide — §5 « Barre de navigation » ── */
.v2-nav{
  height: var(--h-nav);
  display: flex; align-items: center; justify-content: space-between;
  background: var(--bar-bg);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--hairline);
  position: sticky; top: 0; z-index: 20;
}
.v2-nav__logo{ display: flex; align-items: center; gap: var(--sp-2); text-decoration: none; }
.v2-nav__mark{
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--brand-fill); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font: 700 12px/1 var(--font); letter-spacing: -0.02em;
  flex-shrink: 0;
}
.v2-nav__name{ font: 700 15px/1 var(--font); color: var(--brand-ink); letter-spacing: -0.2px; }
.v2-nav__links{ display: flex; align-items: center; gap: var(--sp-6); }
.v2-nav__links a{ font: 400 15px/1 var(--font); color: var(--ink-2); text-decoration: none; }
.v2-nav__cart{
  position: relative; width: 24px; height: 24px; color: var(--brand-ink);
  background: none; border: none; padding: 0; cursor: pointer;
}
.v2-nav__cart svg{ width: 24px; height: 24px; }
.v2-cart-badge{
  position: absolute; top: -6px; right: -8px;
  background: var(--gold-500); color: var(--navy-900);
  font: 700 11px/1 var(--font);
  width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
/* [hidden] est un attribut HTML natif, mais notre display:flex ci-dessus a la
   même spécificité et gagne quand même la cascade (règle d'auteur) : sans ce
   correctif la pastille panier reste visible à 0 malgré badge.hidden = true. */
.v2-cart-badge[hidden]{ display: none; }

/* ── Bandeau d'annonces — §5 ── */
.v2-ann{
  background: var(--navy-900); color: #fff;
  padding: 10px var(--container-pad);
  display: flex; align-items: center; gap: var(--sp-2);
  font: 400 13px/18px var(--font);
  white-space: nowrap; overflow: hidden;
}
.v2-ann > span:not(.v2-ann__pill){ overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.v2-ann__pill{
  background: var(--promo); color: var(--on-promo);
  font: 700 12px/16px var(--font);
  padding: 2px 8px; border-radius: var(--r-xs);
  flex-shrink: 0; white-space: nowrap;
}

/* ── Boutons — §5 ── */
.v2-btn{
  height: var(--h-btn); border-radius: var(--r-btn);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font: 500 17px/1 var(--font);
  border: none; cursor: pointer; padding: 0 28px;
  text-decoration: none; white-space: nowrap;
}
.v2-btn--primary{ background: var(--brand-fill); color: #fff; }
.v2-btn--primary:hover{ background: var(--navy-700); }
.v2-btn--secondary{
  height: var(--h-btn-sm); background: var(--canvas);
  border: 1px solid var(--brand-ink); color: var(--brand-ink);
  padding: 0 22px; font: 400 17px/1 var(--font);
}
/* Sur bande navy (hero) : inversion — §5 */
.v2-on-navy .v2-btn--primary{ background: #fff; color: var(--navy-900); }
.v2-on-navy .v2-btn--secondary{ background: transparent; border-color: #fff; color: #fff; }
.v2-btn--block{ width: 100%; }
.v2-btn:disabled{ opacity: .5; cursor: not-allowed; }

/* ── Badge — §5 « Badge remise » ── */
.v2-badge{
  display: inline-flex; align-items: center;
  background: var(--gold-500); color: var(--navy-900);
  font: 700 12px/16px var(--font);
  padding: 2px 8px; border-radius: var(--r-xs);
}
.v2-badge--navy{ background: var(--navy-900); color: #fff; }
.v2-badge--on-gold{ background: var(--navy-900); color: var(--gold-500); }

/* ── Étoiles — §5 ── */

/* ── Titre de section — §5 : 24/600 + trait or ── */
.v2-sec-title{
  font: 600 24px/27px var(--font); color: var(--ink);
  margin: 0 0 4px;
}
.v2-sec-title__bar{
  display: block; width: var(--gold-bar-w); height: var(--gold-bar-h);
  border-radius: 2px; background: var(--gold-500); margin-bottom: 10px;
}
.v2-sec-sub{ font: 400 15px/20px var(--font); color: var(--ink-3); margin: 0; }
.v2-on-navy .v2-sec-sub{ color: rgba(255, 255, 255, .7); }

/* ── Chips catégories — §5 : jamais de fond navy plein ── */
.v2-chips{ display: flex; gap: var(--sp-2); overflow-x: auto; padding-bottom: 2px; }
.v2-chip{
  flex-shrink: 0; appearance: none;
  background: var(--surface-pearl); color: var(--brand-ink);
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  font: 500 14px/1 var(--font);
  padding: 10px 16px; white-space: nowrap; cursor: pointer;
}
/* Actif = navy plein, texte blanc (choix propriétaire 02/09/2026). */
.v2-chip.is-active{ font-weight: 600; background: var(--brand-fill); color: #fff; border-color: var(--brand-fill); }

/* ── Carte produit — §5 ── */
.v2-card{ background: var(--canvas); border-radius: var(--r-lg); overflow: hidden; position: relative; cursor: pointer; text-decoration: none; color: inherit; }
.v2-card__img{
  aspect-ratio: 1 / 1; background: var(--canvas); border-radius: var(--r-lg);
  position: relative; padding: 16px;
}
.v2-card__img img{ display: block; width: 100%; height: 100%; object-fit: contain; }
.v2-card__badge{
  position: absolute; top: 10px; left: 10px; z-index: 1;
  font: 700 11px/1 var(--font);
  padding: 3px 8px; border-radius: var(--r-xs);
  background: var(--navy-900); color: #fff;
}
.v2-card__badge--promo{ background: var(--navy-900); color: var(--gold-500); }
.v2-card__body{ padding: 12px 4px; }
.v2-card__name{ font: 600 17px/22px var(--font); color: var(--ink); margin: 0 0 2px; min-height: 44px; }
.v2-card__spec{ font: 400 14px/18px var(--font); color: var(--ink-3); margin: 0 0 6px; }
.v2-card__price-row{ display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.v2-card__price{ font: 700 17px/1 var(--font); color: var(--brand-ink); font-variant-numeric: tabular-nums; }
.v2-card__old{ font: 400 12px/1 var(--font); color: var(--ink-3); text-decoration: line-through; font-variant-numeric: tabular-nums; }
.v2-card__cta{ font: 600 14px/1 var(--font); color: var(--action); display: inline-flex; align-items: center; gap: 4px; text-decoration: none; }
.v2-card__cta svg{ width: 14px; height: 14px; }

/* ── Champ de saisie — §5 ── */
.v2-field-label{ display: block; font: 400 14px/20px var(--font); color: var(--ink-2); margin-bottom: var(--sp-1); }
.v2-field{
  width: 100%; height: var(--h-field); border-radius: var(--r-sm);
  border: 1px solid var(--hairline); padding: 0 14px;
  font: 400 16px/1 var(--font); color: var(--ink); background: var(--canvas);
}
.v2-field:focus{ outline: none; border-color: var(--action); }
textarea.v2-field{ height: auto; min-height: 96px; padding: 12px 14px; resize: vertical; }
.v2-field--error{ border-color: var(--err); }
.v2-field-err{ font: 400 14px/20px var(--font); color: var(--err); margin-top: var(--sp-1); }

/* ── Statuts — §5 : pilule 12/700 ── */
.v2-status{
  display: inline-flex; align-items: center;
  font: 700 12px/16px var(--font);
  padding: 4px 10px; border-radius: var(--r-pill);
}
.v2-status--ok{ color: var(--ok); background: #E8F7EE; }
.v2-status--warn{ color: var(--warn); background: var(--warn-bg); }
.v2-status--err{ color: var(--err); background: #FDECEC; }

/* ── Panier tiroir / feuille — §5 ── */
.v2-sheet-veil{
  position: fixed; inset: 0; background: rgba(7, 29, 63, .45);
  opacity: 0; visibility: hidden; transition: opacity .25s ease;
  z-index: 40;
}
.v2-sheet-veil.is-open{ opacity: 1; visibility: visible; }
.v2-sheet{
  position: fixed; z-index: 41; background: var(--canvas);
  display: flex; flex-direction: column;
  /* Mobile : feuille du bas, coins hauts, hauteur 88dvh */
  left: 0; right: 0; bottom: 0; height: 88dvh; max-height: 88dvh;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: var(--shadow-sheet);
  transform: translateY(100%);
  transition: transform .3s ease;
}
.v2-sheet.is-open{ transform: translateY(0); }
@media (min-width: 768px){
  /* Desktop : panneau droit 420px */
  .v2-sheet{
    left: auto; top: 0; bottom: 0; right: 0; width: 420px; height: 100dvh; max-height: none;
    border-radius: 0; border-left: 1px solid var(--hairline);
    box-shadow: none;
    transform: translateX(100%);
  }
  .v2-sheet.is-open{ transform: translateX(0); }
}
.v2-sheet__hd{
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--hairline); flex-shrink: 0;
}
.v2-sheet__title{ font: 600 19px/24px var(--font); color: var(--ink); }
.v2-sheet__close{ background: none; border: none; color: var(--ink-2); cursor: pointer; padding: 4px; }
.v2-sheet__close svg{ width: 22px; height: 22px; }
.v2-sheet__body{ flex: 1; overflow-y: auto; padding: var(--sp-5); }
.v2-sheet__ft{
  flex-shrink: 0; padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--hairline);
  box-shadow: var(--shadow-sheet);
}

/* ── Icônes — §5 : trait 1.75, grille 24, currentColor ── */
.v2-ico{ width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }

/* ═══════════ BOUTON DE CONTACT FLOTTANT (js/contact-fab.js) ═══════════
   Porté depuis index.html, qui l'avait seul. Aucune couleur inventée : la
   pastille reprend le navy de la marque, chaque canal garde la couleur à
   laquelle on le reconnaît (WhatsApp, Telegram), et l'appel reprend l'or.
   --cfab-bottom laisse chaque page le remonter au-dessus de SA barre
   collante : 69 px sur la fiche produit, 64 px de navigation basse sur
   /services, rien sur la boutique. */
.cfab{ --cfab-bottom: var(--sp-4); }
.cfab__fab{
  /* Au-dessus de .svc-cta (z-index 150) : en dessous, un appui sur l'aide
     atteignait le bouton d'envoi place derriere. */
  position: fixed; z-index: 160;
  right: var(--sp-4); bottom: calc(env(safe-area-inset-bottom, 0px) + var(--cfab-bottom));
  width: 52px; height: 52px; border: 0; border-radius: var(--r-pill); cursor: pointer;
  background: var(--navy-900); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 20px rgba(7, 29, 63, .32);
  transition: transform .2s var(--ease, ease);
}
.cfab__fab svg{ width: 24px; height: 24px; }
.cfab__fab:hover{ transform: scale(1.06); }
.cfab__veil{ position: fixed; inset: 0; z-index: 159; background: rgba(7, 29, 63, .28); opacity: 0; transition: opacity .2s; }
.cfab__veil.is-open{ opacity: 1; }
.cfab__menu{
  position: fixed; z-index: 160;
  right: var(--sp-4); bottom: calc(env(safe-area-inset-bottom, 0px) + var(--cfab-bottom) + 64px);
  display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2);
  opacity: 0; transform: translateY(8px); transition: opacity .18s, transform .18s;
}
.cfab__menu.is-open{ opacity: 1; transform: none; }
.cfab__opt{ display: flex; align-items: center; gap: var(--sp-2); }
.cfab__label{
  background: var(--canvas); color: var(--ink);
  font: 600 13px/1 var(--font); padding: 8px 12px; border-radius: var(--r-md);
  box-shadow: 0 4px 14px rgba(7, 29, 63, .16); white-space: nowrap;
}
.cfab__btn{
  width: 44px; height: 44px; border: 0; border-radius: var(--r-pill); cursor: pointer;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  color: #fff; box-shadow: 0 4px 14px rgba(7, 29, 63, .2);
}
.cfab__btn svg{ width: 22px; height: 22px; }
.cfab__btn--chat{ background: var(--brand-fill); }
.cfab__btn--wa{ background: #25D366; }
.cfab__btn--tg{ background: #0088CC; }
.cfab__btn--call{ background: var(--gold-500); color: var(--navy-900); }
@media (prefers-reduced-motion: reduce){
  .cfab__fab, .cfab__veil, .cfab__menu{ transition: none; }
}

/* ═══════════ EXTRAS /services (services/js/extras.js) ═══════════
   Bandeaux promotionnels, questions fréquentes, signalement d'un problème,
   invitation à installer l'application. Quatre fonctions qu'index.html avait
   seul et qui n'ont aucun HTML dans services/index.html : le module les
   construit en JavaScript, ces règles les habillent.

   Sourcing (DESIGN.md §8) :
   | Bloc         | Référence                        | Tokens                                   |
   |--------------|----------------------------------|------------------------------------------|
   | .we-ads      | carte produit v2 (.v2-card)      | --canvas, --hairline, --r-lg, --r-md     |
   | .we-ads__dot | trait or sous les titres (§4)    | --gold-500, --r-pill                     |
   | .we-ads__nav | onglet bas (.bottom-nav__item)   | --h-btn-sm 44, --r-btn, --canvas-2       |
   | .we-faq      | liste à séparateur (.svc-row)    | --divider, --ink, --ink-2                |
   | .we-report   | champs et bouton de services.css | --err, --sp-4, --sp-5                    |
   | .we-inst     | bande d'annonces (.ann)          | --canvas-2, --navy-900, --h-btn-sm       |

   Aucune couleur inventée : #fff sur navy est le seul littéral, comme dans
   .v2-btn--primary et .cfab. index.html habillait son bouton d'installation
   d'un dégradé teal en pilule (index.html:124) : abandonné avec le v1. */

/* ── Bandeaux promotionnels ── */
.we-ads{ margin-bottom: var(--sp-5); }
.we-ads__win{
  overflow: hidden;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  background: var(--canvas);
}
.we-ads__track{ display: flex; transition: transform .45s cubic-bezier(.4, 0, .2, 1); }
.we-ads__slide{
  min-width: 100%; height: 88px;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 0 var(--sp-4);
  text-decoration: none; color: var(--ink);
}
.we-ads__slide--img{ padding: 0; }
.we-ads__slide--img img{ display: block; width: 100%; height: 100%; object-fit: cover; }
.we-ads__mark{
  width: 52px; height: 52px; flex-shrink: 0;
  border-radius: var(--r-md); color: #fff;
  font: 700 20px/1 var(--font);
  display: flex; align-items: center; justify-content: center;
}
.we-ads__txt{ min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.we-ads__t{
  font: 600 15px/20px var(--font); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.we-ads__s{
  font: 400 13px/18px var(--font); color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Rangée de commande sous le cadre plutôt qu'en surimpression : sur 393 px
   deux flèches posées sur la vignette mangeraient le titre. */
.we-ads__ctrl{ display: flex; align-items: center; justify-content: center; gap: var(--sp-2); }
.we-ads__nav{
  width: var(--h-btn-sm); height: var(--h-btn-sm); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--r-btn);
  color: var(--ink-2); cursor: pointer;
}
.we-ads__nav:hover{ background: var(--canvas-2); }
/* Points indicateurs, jamais cliquables : à dix bandeaux, dix cibles de 44 px
   ne tiennent pas sur la largeur. Les deux flèches portent la navigation. */
.we-ads__dots{ display: flex; align-items: center; gap: 6px; }
.we-ads__dot{
  width: 6px; height: 6px; border-radius: var(--r-pill);
  background: var(--hairline);
  transition: width .25s ease, background-color .25s ease;
}
.we-ads__dot.is-on{ width: 18px; background: var(--gold-500); }

/* ── Questions fréquentes ── */
.we-faq-list{ padding: var(--sp-2) 0 var(--sp-5); }
.we-faq{ border-bottom: 1px solid var(--divider); }
.we-faq:last-child{ border-bottom: none; }
.we-faq__q{
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  min-height: var(--h-btn-sm); padding: var(--sp-3) 0;
  font: 500 15px/21px var(--font); color: var(--ink);
  cursor: pointer; list-style: none;
}
/* Le triangle natif de <summary> double le chevron et casse l'alignement. */
.we-faq__q::-webkit-details-marker{ display: none; }
.we-faq__chev{ color: var(--ink-3); transition: transform .2s ease; }
.we-faq[open] .we-faq__chev{ transform: rotate(180deg); }
.we-faq__a{ font: 400 14px/20px var(--font); color: var(--ink-2); padding-bottom: var(--sp-4); }

/* ── Signalement d'un problème ── */
.we-report__lead{ font: 400 14px/20px var(--font); color: var(--ink-3); margin: var(--sp-4) 0; }
.we-report__row{ margin-bottom: var(--sp-4); }
/* .field impose --h-field ; services.css est chargé APRÈS cette feuille et
   gagnerait à égalité de spécificité, d'où le sélecteur d'élément. */
textarea.we-report__area{ height: auto; min-height: 96px; padding: 12px 14px; resize: vertical; }
.field.we-field--err{ border-color: var(--err); }
.we-report__send{ margin-bottom: var(--sp-5); }

/* ── Mode d'emploi iOS ── */
.we-steps{ list-style: none; margin: var(--sp-4) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
.we-steps__i{ display: flex; align-items: flex-start; gap: var(--sp-3); }
.we-steps__n{
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: var(--r-pill); background: var(--brand-fill); color: #fff;
  font: 700 13px/1 var(--font);
  display: flex; align-items: center; justify-content: center;
}
.we-steps__t{ font: 400 15px/21px var(--font); color: var(--ink-2); }

/* ── Invitation à installer l'application ──
   Dans le flux, sous l'en-tête, et non en barre fixe basse : /services occupe
   déjà le bas de l'écran avec sa navigation de 64 px et le bouton de contact
   que js/contact-fab.js place à partir d'elle. */
.we-inst{
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--canvas-2);
  border-bottom: 1px solid var(--hairline);
  animation: we-inst-in .28s ease;
}
.we-inst__ico{ width: 40px; height: 40px; border-radius: var(--r-md); flex-shrink: 0; }
.we-inst__txt{ flex: 1; min-width: 0; display: flex; flex-direction: column; }
.we-inst__t{
  font: 600 15px/20px var(--font); color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.we-inst__s{
  font: 400 13px/18px var(--font); color: var(--ink-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.we-inst__go{
  flex-shrink: 0; height: var(--h-btn-sm); padding: 0 var(--sp-3);
  display: inline-flex; align-items: center;
  border: 0; border-radius: var(--r-btn);
  background: var(--navy-900); color: #fff;
  font: 500 15px/1 var(--font); text-decoration: none; cursor: pointer;
}
.we-inst__go:hover{ background: var(--navy-700); }
.we-inst__x{
  flex-shrink: 0; width: var(--h-btn-sm); height: var(--h-btn-sm);
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; color: var(--ink-3); cursor: pointer;
}
.we-inst__x svg{ width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }
@keyframes we-inst-in{ from{ opacity: 0; transform: translateY(-6px); } to{ opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce){
  .we-ads__track, .we-ads__dot, .we-faq__chev{ transition: none; }
  .we-inst{ animation: none; }
}

/* ── Sélecteur d'apparence (js/theme.js) ──
   Trois puces dans le tiroir des réglages. Réutilise .chips/.chip : aucun
   composant nouveau pour un réglage secondaire. */
.theme-pick{ padding: var(--sp-4) 0 0; }
.theme-pick__lbl{ display: block; font: 400 14px/20px var(--font); color: var(--ink-3); margin-bottom: var(--sp-2); }
.theme-pick .chips{ display: flex; gap: var(--sp-2); }
