/* Boutique Reliatech — design system.
   Registre produit : familiarité gagnée, sobriété, confiance retail.
   Palette de marque (CHARTE-VISUELLE.md, extraite du logo) : bleu nuit + bleu royal.
   1 seul accent, 3 niveaux d'ombre, motion = état uniquement. */
@font-face{
  font-family:'Inter';
  src:url('/assets/fonts/InterVariable.62a57bf92c.woff2') format('woff2');
  font-weight:100 900;font-style:normal;font-display:swap;
}
/* Montserrat, pour les TITRES uniquement (charte : « sans-serif geometrique
   grasse, facon logo »). Elle n'est PAS prechargee : elle ne porte jamais le
   texte courant, donc jamais le plus gros element affiche. `font-display:swap`
   fait afficher le titre en Inter le temps qu'elle arrive — le texte est lisible
   tout de suite, il change juste de dessin. */
@font-face{
  font-family:'Montserrat';
  src:url('/assets/fonts/Montserrat.a700da9fde.woff2') format('woff2');
  font-weight:500 900;font-style:normal;font-display:swap;
}
:root{
  /* ---- palette de marque, alignee sur CHARTE-VISUELLE.md le 29/07 ----
     Les couleurs sont celles EXTRAITES DU LOGO. Le site tournait jusqu'ici sur un
     indigo et un orange qui ne figuraient ni dans la charte ni dans le logo.
     Chaque valeur ci-dessous a ete verifiee au ratio WCAG avant d'etre posee. */
  --blue:#1A5FD0;            /* bleu royal — accent, liens, boutons, le « TECH » */
  --blue-deep:#0E1B2E;       /* bleu nuit — fonds sombres */
  --blue-hover:#1550BC;
  --blue-soft:#EAF1FE;
  --blue-soft2:#D8E5FD;
  /* ⚠️ Le bleu royal sur le bleu nuit ne donne que 2,96:1 : il est ILLISIBLE en
     accent sur fond sombre. Toute accentuation sur du sombre passe par cette
     variante claire (6,29:1). Ne jamais y remettre --blue. */
  --blue-clair:#5B9CFF;
  /* Accent en TEXTE sur fond clair (economies, numeros, puces) : 6,6:1 sur perle. */
  --accent-txt:#1550BC;
  /* Erreurs et actions destructrices. L'ancien orange de marque servait AUSSI a
     dire « erreur » : une couleur d'identite ne doit jamais porter ce sens. */
  --danger:#B3261E;
  --danger-fond:#FDECEA;
  --ink:#0E1B2E;
  --ink-2:#33445B;
  --muted:#5B6B7E;           /* gris ardoise de la charte */
  --line:#DDE4EE;
  --line-2:#C8D3E2;
  --line-strong:#8A98AA;
  --bg:#F2F5F9;              /* gris perle de la charte */
  --vert:#12653d;
  --vert-fond:#e9f6ee;
  /* ombres empilées : une passe de contact + une passe de diffusion, jamais un flou seul */
  --shadow-sm:0 1px 2px rgba(16,22,79,.06),0 2px 6px rgba(16,22,79,.05);
  --shadow:0 2px 6px rgba(16,22,79,.06),0 12px 28px rgba(16,22,79,.10);
  --shadow-lg:0 4px 12px rgba(16,22,79,.08),0 28px 56px rgba(16,22,79,.16);
  --r:16px;
  --r-sm:10px;
  --ease:cubic-bezier(.22,1,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --t-court:.14s;
  --t-moyen:.22s;
  --z-nav:40;--z-head:50;--z-barre:60;--z-fond:70;--z-modal:80;--z-toast:90;
}
/* Variables de la derive des cartes du hero. Une variable non declaree ici ne
   s'INTERPOLE pas : elle sauterait d'un coup de sa valeur de depart a celle
   d'arrivee. `@property` lui donne un type, donc une trajectoire.
   Un navigateur qui ignore la regle ignore aussi l'animation : les cartes restent
   a leur position de repos, ce qui est exactement le repli voulu. */
@property --fy{syntax:'<length>';inherits:false;initial-value:0px}
@property --fr{syntax:'<angle>';inherits:false;initial-value:0deg}
/* Derive des cartes de banniere (meme raison : sans type, pas d'interpolation). */
@property --by{syntax:'<length>';inherits:false;initial-value:0px}
@property --bd{syntax:'<angle>';inherits:false;initial-value:0deg}
*{box-sizing:border-box;margin:0;padding:0}
/* [hidden] doit gagner sur les display: des composants (contrôles révélés par JS) */
[hidden]{display:none !important}
html{scroll-behavior:smooth}
body{font-family:Inter,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;color:var(--ink);background:var(--bg);line-height:1.55;-webkit-font-smoothing:antialiased;font-optical-sizing:auto}
img{max-width:100%;display:block}
a{color:var(--blue);text-decoration:none}
/* Les titres passent en Montserrat, le corps reste en Inter. Le `letter-spacing`
   est repris a -.02 : Montserrat est plus large qu'Inter a taille egale, sans ce
   resserrement les titres longs passent a la ligne la ou ils tenaient. */
h1,h2,h3,.sec-h,.hero-promesse,.ban-h,.cc-carte h3{
  font-family:'Montserrat',Inter,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;
  text-wrap:balance;letter-spacing:-.02em}
.prose{max-width:53ch;text-wrap:pretty}
.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
.narrow{max-width:720px}
:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.annonce :focus-visible,.hero :focus-visible,.site-foot :focus-visible,
.cmp-bar :focus-visible,.toast :focus-visible,.masc-fab:focus-visible,
.pro-bloc :focus-visible,.bp-hero :focus-visible,.res-haut :focus-visible,
.bande-packs :focus-visible{outline-color:#fff}

.nowrap{white-space:nowrap}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* skip link */
.skip{position:absolute;left:-999px;top:0;background:#fff;color:var(--blue);font-weight:700;padding:10px 18px;border-radius:0 0 var(--r-sm) 0;z-index:100}
.skip:focus{left:0}

/* bandeau annonce */
.annonce{background:var(--blue-deep);color:#d5daf7;font-size:.8rem;overflow:hidden}
/* Bandeau défilant : la piste porte DEUX fois la même série et se translate de
   moitié, donc la seconde prend exactement la place de la première — la boucle est
   invisible. L'animation est sur `transform` seul (aucun reflow), et s'arrête au
   survol comme au focus clavier : une information qui défile doit pouvoir être
   arrêtée pour être lue. */
.annonce-piste{display:flex;width:max-content;animation:annonce-defile 45s linear infinite}
.annonce-serie{display:flex;gap:10px;align-items:center;padding:8px 20px}
.annonce:hover .annonce-piste,.annonce:focus-within .annonce-piste{animation-play-state:paused}
@keyframes annonce-defile{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.annonce-in{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;align-items:center;padding:8px 20px}
.annonce-sep{opacity:.5}
.annonce-fort{color:#fff;font-weight:700;position:relative;padding-left:19px}
.annonce-fort::before{content:"";position:absolute;left:0;top:50%;width:11px;height:11px;margin-top:-5px;border-radius:50%;background:var(--blue-clair);box-shadow:0 0 0 3px rgba(91,156,255,.28)}
@media (max-width:760px){.annonce-in span:nth-child(n+2){display:none}.annonce-in{justify-content:center}}

/* header */
.site-head{background:#fff;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:var(--z-head)}
/* min-width:0 est indispensable sur un conteneur flex : sans lui, la navigation
   refuse de retrecir et l'en-tete depassait de 7 px a 1280 px, cassant
   « Bons plans » et « Devis pro » sur deux lignes. */
.head-in{display:flex;align-items:center;gap:22px;height:64px;position:relative;min-width:0}
.brand{display:flex;align-items:center;gap:10px;font-weight:900;letter-spacing:.05em;font-size:1.06rem;color:var(--blue)}
.brand img{border-radius:8px}
/* `min-width:0` autorisait la navigation à se comprimer sous la largeur de son
   propre contenu : mesuré le 28/07 à 1239 px, elle occupait 569 px pour 609 px de
   liens, et le bouton « Devis pro » débordait de 40 px PAR-DESSUS le numéro de
   téléphone. Le débordement était silencieux — rien ne déclenche de barre de
   défilement quand c'est un enfant qui sort de son parent flex. */
/* 11/08 (Samuel) : « RELIATECH » et l onglet « Catalogue » se touchaient, au point que
   le fond de survol du premier onglet venait mordre le nom. Le gap de .head-in (22 px) est
   un écart entre voisins, pas une garantie : quand la nav grossit, elle vient au contact.
   On impose donc une marge propre à la navigation, qui ne dépend pas de la place restante. */
.main-nav{display:flex;gap:2px;align-items:center;margin-left:auto;flex:none;padding-left:26px}
.main-nav>a{white-space:nowrap}
.main-nav a{padding:9px 11px;border-radius:var(--r-sm);font-weight:600;font-size:.93rem;color:var(--ink);transition:background .16s var(--ease),color .16s var(--ease)}
.main-nav a:hover{background:var(--blue-soft);color:var(--blue)}
.main-nav a.on{background:var(--blue);color:#fff}
.nav-cta{background:var(--blue);color:#fff !important;margin-left:8px;font-weight:700}
.nav-cta:hover{background:var(--blue-hover) !important;color:#fff}
.head-actions{display:flex;align-items:center;gap:10px;margin-left:14px;flex:none}
/* panier : la seule action permanente du header, toujours visible, même sur mobile */
.panier-lien{display:flex;align-items:center;gap:8px;position:relative;padding:9px 15px 9px 13px;border-radius:var(--r-sm);font-weight:700;font-size:.93rem;color:var(--blue) !important;background:var(--blue-soft);border:1px solid transparent;transition:background var(--t-court) var(--ease),border-color var(--t-court) var(--ease)}
.panier-lien:hover{background:var(--blue-soft2);border-color:var(--line-2)}
.panier-lien.on{background:var(--blue);color:#fff !important}
.panier-ico{flex:none}
.panier-compte{position:absolute;top:-6px;right:-6px;min-width:21px;height:21px;padding:0 5px;border-radius:11px;background:var(--blue-clair);color:#fff;font-size:.72rem;font-weight:800;display:flex;align-items:center;justify-content:center;box-shadow:0 0 0 2px #fff}
.panier-compte.pulse{animation:badge .42s var(--ease-out)}
@keyframes badge{0%{transform:scale(.6)}55%{transform:scale(1.22)}100%{transform:scale(1)}}
/* `order` remet le bouton de menu tout à droite alors qu'il précède la
   navigation dans le document : l'ordre visuel est celui qu'on attend, et
   l'ordre de tabulation devient enfin cohérent (bouton, puis le menu qu'il
   ouvre). Les autres enfants restent à order:0 et gardent leur ordre naturel. */
.nav-btn{display:none;order:9;margin-left:10px;background:none;border:1px solid var(--line-2);border-radius:var(--r-sm);width:44px;height:40px;cursor:pointer;padding:10px 11px;flex-direction:column;justify-content:space-between}
.nav-btn span{display:block;height:2px;background:var(--ink);border-radius:2px;transition:transform .2s var(--ease),opacity .2s}
.nav-btn[aria-expanded="true"] span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.nav-btn[aria-expanded="true"] span:nth-child(2){opacity:0}
.nav-btn[aria-expanded="true"] span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
/* catalogue en <details> natif : fonctionne sans JS et encaisse l'ajout de catégories */
.nav-drop{position:relative}
.nav-drop>summary{list-style:none;padding:9px 13px;border-radius:var(--r-sm);font-weight:600;font-size:.93rem;color:var(--ink);cursor:pointer;display:flex;align-items:center;gap:7px;transition:background .16s var(--ease),color .16s var(--ease)}
.nav-drop>summary::-webkit-details-marker{display:none}
.nav-drop>summary::after{content:"";width:6px;height:6px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform .18s var(--ease)}
.nav-drop[open]>summary::after{transform:translateY(1px) rotate(-135deg)}
.nav-drop>summary:hover{background:var(--blue-soft);color:var(--blue)}
.nav-drop>summary.on{background:var(--blue);color:#fff}
.nav-panel{position:absolute;top:calc(100% + 9px);left:0;min-width:252px;background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-lg);padding:8px;display:flex;flex-direction:column;z-index:var(--z-nav)}
.nav-panel a{padding:10px 12px;border-radius:var(--r-sm);font-weight:600;font-size:.93rem;color:var(--ink);white-space:nowrap;transition:background .16s var(--ease),color .16s var(--ease)}
.nav-panel a:hover{background:var(--blue-soft);color:var(--blue)}
.nav-panel a.on{background:var(--blue);color:#fff}
@media (max-width:1050px){
  .panier-lib{display:none}
  .panier-lien{padding:9px 11px}
}
/* Le menu passait en bouton à 900 px, mais la barre complète (marque + 7 liens +
   compte + panier) réclame 960 px : entre 900 et 1080, elle tenait uniquement
   parce que la navigation se comprimait par-dessus le reste. Le seuil suit
   désormais la mesure. */
/* 11/08 : un onglet de plus (Marques) dans la barre. Le seuil de bascule en menu
   compact suit la mesure, sinon la navigation se serre à nouveau contre le nom. */
@media (max-width:1180px){
  .nav-btn{display:flex}
  .main-nav{display:none;position:absolute;top:64px;left:-20px;right:-20px;background:#fff;flex-direction:column;align-items:stretch;padding:10px 20px 16px;border-bottom:1px solid var(--line);box-shadow:var(--shadow);z-index:var(--z-nav)}
  .main-nav.open{display:flex}
  .main-nav{padding-left:20px}
  .main-nav a{padding:13px 12px;font-size:1rem}
  .nav-cta{margin-left:0;margin-top:6px;text-align:center}
  .nav-drop>summary{padding:13px 12px;font-size:1rem}
  .nav-panel{position:static;min-width:0;border:0;border-radius:0;box-shadow:none;padding:0 0 6px 12px;border-left:1px solid var(--line);margin-left:12px}
}

/* boutons */
/* ---------- boutons ----------
   Refonte du 29/07. Ils etaient plats : un aplat de couleur, un coin arrondi, une
   ombre floue. Ce qui manquait n'est pas de la decoration, ce sont les indices
   qu'un bouton donne quand on peut le presser — un bord clair en haut (la lumiere
   vient d'en haut), un bord sombre en bas, et une ombre qui se RAPPROCHE quand on
   enfonce au lieu de disparaitre.
   `min-height:44px` partout : c'est le minimum tactile, et plusieurs boutons
   secondaires passaient dessous.
   La transition ne liste que des proprietes composees — jamais `all`. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;min-height:44px;
  padding:13px 26px;border-radius:13px;font-weight:700;font-size:.98rem;border:0;cursor:pointer;
  text-align:center;text-decoration:none;touch-action:manipulation;
  transition:background var(--t-moyen) var(--ease),border-color var(--t-moyen) var(--ease),
    box-shadow var(--t-moyen) var(--ease),transform var(--t-court) var(--ease),color var(--t-court) var(--ease)}
.btn:active{transform:translateY(1px) scale(.994)}

.btn-hero{background:#fff;color:var(--blue);
  box-shadow:inset 0 1px 0 #fff,0 1px 2px rgba(4,8,42,.2),0 12px 28px rgba(4,8,42,.34)}
.btn-hero:hover{background:#f2f4ff;transform:translateY(-2px);
  box-shadow:inset 0 1px 0 #fff,0 2px 4px rgba(4,8,42,.22),0 18px 36px rgba(4,8,42,.4)}
.btn-hero:active{box-shadow:inset 0 1px 0 #fff,0 1px 2px rgba(4,8,42,.24),0 6px 14px rgba(4,8,42,.3)}

.btn-ghost{background:rgba(255,255,255,.07);color:#fff;border:1.5px solid rgba(255,255,255,.5);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18)}
.btn-ghost:hover{border-color:#fff;background:rgba(255,255,255,.16);transform:translateY(-2px)}

/* Le degrade est tres court (4 %) : il ne se lit pas comme un degrade, il se lit
   comme du volume. Un aplat parait imprime, celui-ci parait pressable. */
.btn-buy{background:linear-gradient(180deg,#212a90,var(--blue));color:#fff;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 1px 2px rgba(16,22,79,.24),0 6px 16px rgba(16,22,79,.22)}
.btn-buy:hover{background:linear-gradient(180deg,#2b36ab,var(--blue-hover));transform:translateY(-2px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.26),0 2px 4px rgba(16,22,79,.26),0 12px 26px rgba(16,22,79,.3)}
.btn-buy:active{box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 1px 2px rgba(16,22,79,.28),0 3px 8px rgba(16,22,79,.24)}

.btn-second{background:#fff;color:var(--blue);border:1px solid var(--line-strong);
  box-shadow:0 1px 2px rgba(16,22,79,.05)}
.btn-second:hover{border-color:var(--blue);background:var(--blue-soft);transform:translateY(-1px);
  box-shadow:0 2px 6px rgba(16,22,79,.1)}

.btn-second:disabled,.btn-buy:disabled{opacity:.5;cursor:default;transform:none;box-shadow:none;background:var(--blue)}
/* La fleche avance quand on survole : elle dit « ca continue par la », ce qu'un
   chevron immobile ne dit pas. Elle est purement decorative, donc en pseudo. */
.btn-fleche::after{content:"→";font-weight:700;transition:transform var(--t-moyen) var(--ease)}
.btn-fleche:hover::after{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){ .btn-fleche:hover::after{transform:none} }

/* ==================================================================
   HERO D'ACCUEIL — refonte du 29/07
   « Ca fait pas beau du tout, on dirait toujours pas une page d'accueil. Il faut
   quelque chose qui claque. » (Samuel, capture telephone a l'appui.)

   Ce qui n'allait pas, mesure sur un ecran de 412 x 825 px :
   - le premier ecran etait 100 % bleu. Titre sur trois lignes, sous-titre sur
     trois lignes, deux boutons, une carte d'engagements, un numero de telephone.
     Pas un produit, pas un prix avant d'avoir fait defiler. Le carrefour de
     rayons corrige le 28/07 tombait entierement sous la ligne de flottaison :
     le probleme d'origine n'etait donc regle que sur ordinateur ;
   - la carte d'engagements se lisait comme une mention legale posee la « histoire
     de faire legal » — supprimee, ces promesses sont dites sur la fiche produit
     et dans le pied de page, la ou elles decident vraiment ;
   - rien ne bougeait.

   Le hero porte maintenant TROIS plans de profondeur (halos derivants, sol en
   perspective, cartes de rayon en 3D) et se termine par la bande des rayons, en
   cartes blanches sur le bleu : le premier ecran montre donc des rayons et des
   prix reels. Tout est en CSS pur, transform/opacity uniquement, et
   `prefers-reduced-motion` neutralise l'integralite du mouvement.
   ================================================================== */
.hero{position:relative;isolation:isolate;background:linear-gradient(152deg,#0a0f42 0%,var(--blue-deep) 46%,#1d2792 100%);color:#fff;overflow:hidden}
.hero::before{content:"";position:absolute;inset:0;z-index:-2;background:radial-gradient(90% 120% at 8% 0%,rgba(90,104,231,.4),rgba(90,104,231,0) 58%),radial-gradient(55% 70% at 92% 18%,rgba(91,156,255,.26),rgba(91,156,255,0) 72%)}

/* --- plan 1 : halos derivants ---
   Des cercles en degrade radial, PAS des elements floutes : un `filter:blur()`
   sur une surface de cette taille repeint a chaque image et fait tomber le
   defilement a 30 im/s sur telephone. Le degrade, lui, est peint une fois et
   seul son `transform` change. */
.hero-deco{position:absolute;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
.hero-blob{position:absolute;border-radius:50%;will-change:transform}
.hb1{width:70vw;height:70vw;max-width:760px;max-height:760px;top:-26%;left:-14%;
  background:radial-gradient(circle at 50% 50%,rgba(104,120,255,.42),rgba(104,120,255,0) 68%)}
.hb2{width:56vw;height:56vw;max-width:620px;max-height:620px;top:-10%;right:-16%;
  background:radial-gradient(circle at 50% 50%,rgba(214,96,52,.34),rgba(214,96,52,0) 66%)}
.hb3{width:48vw;height:48vw;max-width:540px;max-height:540px;bottom:-24%;left:34%;
  background:radial-gradient(circle at 50% 50%,rgba(72,196,232,.2),rgba(72,196,232,0) 68%)}

/* --- plan 2 : le sol en perspective ---
   Une grille couchee a 68 degres qui file vers l'horizon, estompee par un masque.
   C'est ce plan qui donne la profondeur : sans lui le hero reste un aplat.
   La grille defile par `transform` sur un pseudo-element deux fois plus haut que
   son cadre, jamais par `background-position` (qui repeint). */
.hero-sol{position:absolute;left:-30%;right:-30%;bottom:-8%;height:58%;overflow:hidden;
  transform:perspective(560px) rotateX(68deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(to top,#000 4%,rgba(0,0,0,.55) 34%,transparent 82%);
  mask-image:linear-gradient(to top,#000 4%,rgba(0,0,0,.55) 34%,transparent 82%)}
.hero-sol::before{content:"";position:absolute;left:0;right:0;top:-100%;bottom:-100%;
  background-image:linear-gradient(rgba(255,255,255,.13) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.10) 1px,transparent 1px);
  background-size:70px 70px;will-change:transform}

/* Deux colonnes sur grand ecran : le discours a gauche, la SCENE a droite.
   La moitie droite portait une photo unique de produit jusqu'au 28/07, ce qui
   donnait a l'accueil l'allure d'une fiche. La retirer a regle ce probleme et en
   a cree un autre : un demi-hero vide. Ni l'un ni l'autre — quatre petites cartes
   de rayons differents, en profondeur, qui derivent doucement. */
/* 1,14 / 0,86 et non 1 / 1 : la rangee d'actions fait 577 px a elle seule, une
   colonne a parts egales la faisait passer sur deux lignes a 1140 px. */
/* Les blocs se touchaient : on croyait que « RELIATECH » nommait l'ordinateur
   juste en dessous. Les respirations sont doublees, le titre est centre. */
.hero-in{display:grid;grid-template-columns:minmax(0,1.14fr) minmax(0,.86fr);
  grid-template-areas:"tete vedette" "corps vedette";
  grid-template-rows:auto auto;
  column-gap:52px;row-gap:34px;align-items:center;
  padding-top:66px;padding-bottom:48px}
.hero-tete{grid-area:tete;align-self:end}
.hero-txt{grid-area:corps;align-self:start}
.hero-vedette{grid-area:vedette}
.hero-scene{grid-area:vedette}
/* ==================================================================
   LE NOM EN RELIEF — refonte du 29/07 au soir
   Etude demandee par Samuel, faite sur Apple, Nothing et Back Market. Deux
   constats qui ont decide de tout :
   1. Les trois marques ouvrent sur UN sujet unique et enorme. Aucune sur une
      mosaique. Nos trois vignettes de rayon ne donnaient a l'oeil aucun endroit
      ou se poser.
   2. Nothing est partie de ZERO notoriete en 2021 et passe pour premium
      aujourd'hui : sa difference est TYPOGRAPHIQUE, pas technique. Aucune 3D,
      aucun effet — une typo reconnaissable et une couleur franche.
   D'ou ce parti : le nom d'abord, tres grand, avec une vraie extrusion.
   ⛔ Ce qui a ete ECARTE, et pourquoi : WebGL et scenes Spline. Une seule scene
   charge 800 ko a 2 Mo de JavaScript avant le premier pixel, effondre les Core
   Web Vitals et fait fuir le visiteur en 4G. La pratique de 2026 est de n'en
   mettre que si la marque EST l'experience — ce n'est pas le cas d'un marchand
   chez qui on vient chercher un prix et un delai. Ici l'extrusion coute ZERO
   octet : ce sont des ombres portees empilees.
   ================================================================== */
.hero-h1{display:flex;flex-direction:column;align-items:center;gap:30px;max-width:none;text-align:center}
/* Le wordmark est SON logo, en image — plus une reconstitution en CSS.
   J'avais retape « RELIATECH » en graisse 900, lettres resserrees ; le vrai est
   une geometrique FINE, tres espacee. Autant dire l'inverse. Un logo ne se
   retape pas, il se pose.
   La version fond sombre (RELIA blanc, TECH bleu clair) est fabriquee par
   engine/wordmark_blanc.py a partir du fichier d'origine — la charte la
   prevoyait explicitement et elle n'existait pas. */
/* 02/08 — c'est le LOGO ENTIER qui est posé ici, symbole compris, plus le seul mot.
   Constat de Samuel sur mobile : « c'est juste une écriture basique aux couleurs de
   Reliatech ». Il avait raison — le R et ses trois pistes de circuit, c'est-à-dire
   tout ce qui fait reconnaître la marque, n'étaient nulle part sur la page d'accueil.
   Le rapport largeur/hauteur passe de 11,6 à 2,4 : le bloc est donc quatre fois plus
   haut, d'où une largeur d'affichage réduite (340 px au lieu de 420) pour qu'il tienne
   au-dessus de la ligne de flottaison. La hauteur est réservée par width/height dans
   le HTML, donc rien ne saute au chargement. */
   Depuis le 02/08 c'est le SVG vectoriel fourni par Samuel : ratio 1,99, signature
   comprise dans le fichier. */
.hero-logo{display:block;width:min(64vw,320px);height:auto;
  filter:drop-shadow(0 12px 30px rgba(2,5,32,.55))}
.hero-promesse{display:block;font-size:clamp(1.55rem,3.2vw,2.15rem);font-weight:800;
  line-height:1.1;letter-spacing:-.02em;color:#E6EDFB;max-width:20ch}
/* ------------------------------------------------------------------
   RELY DANS LE PREMIER ÉCRAN (02/08)
   Version « discrète, à côté du contenu » demandée par Samuel, à faire tester avant
   d'envisager une présence plus large. Une carte basse, pas un encadré publicitaire :
   un visage, une phrase à la première personne, une flèche. Elle ne prend pas la
   place du produit, elle referme la colonne de gauche.
   ------------------------------------------------------------------ */
.hero-rely{display:flex;align-items:center;gap:12px;width:100%;margin-top:16px;
  padding:11px 14px;text-align:left;cursor:pointer;
  background:rgba(255,255,255,.055);border:1px solid rgba(150,180,235,.22);
  border-radius:15px;color:#DCE7FA;font:inherit;
  transition:background .18s ease,border-color .18s ease,transform .18s ease}
.hero-rely:hover,.hero-rely:focus-visible{background:rgba(255,255,255,.1);
  border-color:rgba(150,180,235,.42);transform:translateY(-2px)}
.hero-rely-face{flex:0 0 auto;width:42px;height:42px;display:grid;place-items:center}
.hero-rely-face img,.hero-rely-face svg{width:42px;height:42px;display:block}
.hero-rely-txt{flex:1 1 auto;font-size:.85rem;line-height:1.35;color:rgba(214,228,250,.86)}
.hero-rely-txt b{display:block;font-size:.9rem;font-weight:800;color:#fff;letter-spacing:.01em}
.hero-rely-fleche{flex:0 0 auto;font-size:1.05rem;color:var(--blue-clair);
  transition:transform .18s ease}
.hero-rely:hover .hero-rely-fleche{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){
  .hero-rely,.hero-rely-fleche{transition:none}
  .hero-rely:hover,.hero-rely:focus-visible{transform:none}
  .hero-rely:hover .hero-rely-fleche{transform:none}
}
.hero h1{font-size:inherit;font-weight:800;line-height:1.02;letter-spacing:-.03em;max-width:none}
/* Le surlignage de « au bon prix » : c'est le geste qui fait claquer le titre.
   `isolation` garde le trait derriere le texte sans le faire passer sous le fond
   du hero, qui est lui-meme un contexte d'empilement. */
/* `nowrap` n'est pas cosmétique : le trait est un pseudo-élément posé sur la boîte
   du span. Si le span se coupe sur deux lignes, sa boîte englobe les deux et le
   trait se dessine en travers, décalé et trop large. Vu à la première recette. */
.hero-mark{position:relative;isolation:isolate;display:inline-block;white-space:nowrap}
/* Le trait passe SOUS la ligne de base, pas au travers des lettres : posé sur les
   glyphes il se lisait comme un texte barré. `z-index:-1` le laisse passer derrière
   la descendante du « p » au lieu de la couper. */
.hero-mark::after{content:"";position:absolute;z-index:-1;left:.02em;right:-.02em;bottom:-.04em;height:.13em;
  border-radius:999px;background:linear-gradient(96deg,#3D7CE0,var(--blue-clair) 58%,#AED2FF);
  box-shadow:0 4px 16px rgba(91,156,255,.5);transform-origin:0 50%}
.hero-sous{max-width:46ch;margin:0;color:#C6D2EE;font-size:1.04rem}
.hero-cta{margin-top:26px;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.hero .btn-hero{font-size:1.01rem;padding:15px 28px}

/* Le telephone : une pastille dans la rangee d'actions, pas une ligne sous elle.
   Il reste le seul moyen d'obtenir une reponse immediate, il doit se voir sans
   coûter une ligne entiere de hauteur au premier ecran. */
.hero-tel{display:inline-flex;align-items:center;gap:9px;padding:9px 18px 9px 14px;
  border-radius:999px;background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.22);color:#fff;
  transition:background var(--t-moyen) var(--ease),border-color var(--t-moyen) var(--ease),transform var(--t-court) var(--ease)}
.hero-tel:hover{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.45);transform:translateY(-1px)}
.hero-tel-ico{width:17px;height:17px;flex:none;color:#9FC6FF}
.hero-tel-num{font-weight:800;font-size:1.02rem;font-variant-numeric:tabular-nums;white-space:nowrap}
.hero-tel-note{font-size:.78rem;color:#bcc4f0;white-space:nowrap}

/* --- les puces d'intention ---
   Quatre entrees par le BESOIN, pas par le rayon. C'est ce que fait Dell depuis
   sa refonte, et c'est ce qui distingue un marchand qui conseille d'un catalogue. */
/* Banderole de reassurance : elle ouvrait la page, elle la suit desormais.
   Trois faits, pas une phrase — on la lit d'un coup d'oeil. */
.hero-banderole{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;
  gap:10px 26px;margin:18px 0 0;padding:0;font-size:.86rem;color:#B9C6E4}
.hero-banderole b{color:#fff;font-weight:800}
/* Le logo Dell vaut mieux qu'un mot : c'est la marque qu'on revendique, autant
   la montrer. Il est fourni en SVG monochrome, on le passe en blanc. */
.hb-dell{display:inline-flex;align-items:center;gap:9px}
.hb-dell img{height:22px;width:auto;filter:brightness(0) invert(1);opacity:.95}
.hb-dell span{color:#fff;font-weight:700}
.hero-banderole li{position:relative}
.hero-banderole li+li::before{content:"";position:absolute;left:-14px;top:50%;
  width:4px;height:4px;margin-top:-2px;border-radius:50%;background:var(--blue-clair)}
.hero-puces{list-style:none;display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:22px 0 0;padding:0}
.hero-puces a{display:inline-block;padding:7px 15px;border-radius:999px;font-size:.85rem;font-weight:600;
  color:#dfe3ff;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.16);
  transition:background var(--t-court) var(--ease),border-color var(--t-court) var(--ease),transform var(--t-court) var(--ease)}
.hero-puces a:hover{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.42);color:#fff;transform:translateY(-1px)}

/* --- la scene : quatre cartes en profondeur ---
   `perspective` sur le conteneur, `translateZ` different par carte : les cartes
   du fond sont reellement plus loin, elles ne sont pas juste plus petites. C'est
   ce qui separe un vrai relief d'un empilement d'images. */
/* `.hero-scene` porte la PERSPECTIVE, `.hero-scene-in` porte la ROTATION.
   Les deux sur le meme element ne marchent pas : `perspective` s'applique aux
   enfants, `transform` s'applique a l'element dans le repere de son parent, qui
   est plat. La scene aurait pivote comme une image, sans relief. */
.hero-scene{position:relative;height:340px;perspective:1150px;perspective-origin:50% 50%}
.hero-scene-in{position:absolute;inset:0;transform-style:preserve-3d}
.hs-c{position:absolute;margin:0;width:166px;background:#fff;border-radius:16px;padding:10px 11px 9px;
  box-shadow:0 12px 30px rgba(4,8,42,.42),0 34px 70px rgba(4,8,42,.4);
  transform-style:preserve-3d;will-change:transform}
.hs-c img{width:100%;height:88px;object-fit:contain;margin-bottom:8px}
.hs-c figcaption{display:flex;flex-direction:column;gap:1px;border-top:1px solid var(--line);padding-top:8px}
.hs-c figcaption b{font-size:.86rem;font-weight:700;color:var(--ink);line-height:1.2}
.hs-c figcaption span{font-size:.83rem;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
/* Positions et profondeurs. Ecrites une fois ici, jamais dans le HTML : la
   politique de securite du site interdit les styles en ligne.
   La derive est composee par variables plutot que reecrite dans quatre jeux de
   keyframes : la position de repos et le flottement restent separes, et un
   navigateur qui ne sait pas animer une variable retombe simplement sur la
   position de repos — d'ou les valeurs de repli dans chaque `var()`. */
.hs-c{transform:translateZ(var(--z,0px)) rotate(calc(var(--r,0deg) + var(--fr,0deg)))
  translateY(var(--fy,0px)) scale(var(--s,1))}
/* Diagonale : haut-gauche au premier plan, milieu-droite en retrait, bas-centre
   entre les deux. Les zones de recouvrement sont volontairement faibles — juste
   assez pour que l'oeil lise une profondeur, jamais assez pour cacher un prix. */
.hs-c1{top:0;left:0;--z:56px;--r:-5deg}
.hs-c2{top:88px;right:2%;--z:2px;--r:4.5deg}
.hs-c3{bottom:0;left:24%;--z:-36px;--r:3deg;--s:.96}

/* --- LE PRODUIT VEDETTE ---
   Detoure, en grand, il levite au-dessus de son ombre portee. C'est le geste
   d'Apple avec nos moyens : nos photos sont des cliches fournisseur sur fond
   blanc, inutilisables tels quels sur du navy (halo blanc garanti). Le fond a
   donc ete retire, et l'ombre est REDESSINEE en CSS — une ellipse floutee, qui
   suit la levitation. C'est elle qui pose l'objet au lieu de le faire flotter
   dans le vide. */
.hero-vedette{display:flex;flex-direction:column;align-items:center;gap:16px;color:#fff;
  text-decoration:none;transition:transform var(--t-moyen) var(--ease)}
/* ⚠️ PAS de `perspective` ici. Elle y avait ete mise par reflexe, elle ne sert
   a rien (la levitation est un simple translateY) et surtout : combinee au
   `drop-shadow` de l'image et a son animation, elle creait un contexte de
   composition dans lequel Chrome ne peignait tout simplement PAS l'image.
   Elle etait chargee, `visible`, opacite 1, a la bonne place — et invisible. */
.hero-vedette-scene{position:relative;display:block;width:100%}
.hero-vedette-img{position:relative;z-index:1;width:100%;height:auto;display:block;
  filter:drop-shadow(0 26px 40px rgba(2,5,32,.55))}
.hero-vedette-ombre{position:absolute;z-index:0;left:12%;right:12%;bottom:-2%;height:26px;
  border-radius:50%;background:radial-gradient(closest-side,rgba(2,5,32,.62),rgba(2,5,32,0) 78%)}
.hero-vedette-lib{display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:11px 22px;border-radius:16px;background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.18);text-align:center;max-width:min(100%,320px)}
/* Nom sur une ligne, prix en dessous. Cote a cote, un nom de reference Dell fait
   deux lignes et le prix se retrouvait desaxe, colle en bas a droite. */
.hero-vedette-nom{display:block;font-size:.85rem;font-weight:600;color:#DDE6F7;
  line-height:1.3;letter-spacing:.01em}
.hero-vedette-prix{display:block;font-size:1.12rem;font-weight:800;color:#fff;
  font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.hero-vedette:hover{transform:translateY(-3px)}
.hero-vedette:hover .hero-vedette-lib{background:rgba(255,255,255,.17);border-color:rgba(255,255,255,.42)}

/* --- plan 3 : la bande des rayons, DANS le hero ---
   C'est elle qui fait qu'on est sur une page d'accueil de marchand et non sur une
   fiche : des rayons, un nombre de references et un prix de depart reel, visibles
   sans defiler. */
.hero-rayons{position:relative;padding-bottom:38px}
.hero-rayons-tete{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:13px}
.hero-rayons-h{font-size:1.02rem;font-weight:700;color:#e9ecff;letter-spacing:0}
.hero-rayons-lien{color:#c6cdff;font-size:.87rem;font-weight:600;white-space:nowrap}
.hero-rayons-lien:hover{color:#fff}
/* Six colonnes exactement, jamais `auto-fit` : en colonnes automatiques la grille
   en calait sept, et les onze rayons laissaient trois cases vides au bout de la
   seconde rangée. Six colonnes plus la case « Bons plans » font douze : deux
   rangées pleines. */
.hero-rail{list-style:none;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px;
  margin:0;padding:0;perspective:1000px}
.hero-rail>li{display:flex}
/* Le prix de départ passe à la ligne systématiquement : sinon il se replie sur
   les tuiles étroites et pas sur les larges, et les deux rangées ne s'alignent
   plus. Une règle qui vaut pour tous vaut mieux qu'un repli qui dépend du mot. */
.hero-rail .univ-des{display:block}
.hero-rail-note{margin:13px 0 0;font-size:.79rem;color:#9aa4e6}
/* La case « Bons plans » : même gabarit, registre accentué. */
.hero-rail .univ--plus{background:linear-gradient(158deg,#2c1b12,#3d2216);border-color:rgba(255,163,116,.38);color:#ffd9c4}
.univ--plus .univ-vis{color:#7FB2FF}
.univ--plus .univ-vis svg{width:52px;height:52px}
.univ--plus .univ-nom{color:#fff}
.univ--plus .univ-meta{color:#e7c3ad}
.univ--plus .univ-des{color:#ffb287}
@media (max-width:1023px){ .hero-rail{grid-template-columns:repeat(4,minmax(0,1fr))} }
/* Les tuiles basculent legerement vers l'arriere au repos et se redressent au
   survol : le mouvement n'est pas decoratif, il dit « c'est pris en main ». */
.hero-rail .univ{width:100%;border-color:transparent;box-shadow:0 10px 26px rgba(5,9,45,.4);
  transform:rotateX(4deg);transform-style:preserve-3d}
.hero-rail .univ:hover{transform:translateY(-7px) rotateX(0deg) scale(1.025);
  box-shadow:0 22px 46px rgba(5,9,45,.55);border-color:transparent}
.hero-rail .univ:active{transform:translateY(-3px) scale(1.005)}

/* Au-dela de 1200 px l'en-tete affiche deja le numero en gros et en permanence :
   la pastille du hero ferait le meme numero deux fois a 400 px d'intervalle. */
@media (min-width:1201px){ .hero-cta .hero-tel{display:none} }
/* ------------------------------------------------------------------
   LA SCENE SUR TELEPHONE — correction du 29/07
   Elle etait purement et simplement MASQUEE sous 1024 px, au motif que trois
   cartes de 166 px ne tiendraient pas cote a cote. Consequence : sur telephone,
   le premier ecran ne montrait rien de la mise en scene — c'est exactement ce
   que Samuel a vu, et il avait raison de dire que la page d'accueil n'avait pas
   ete travaillee de son cote.
   Elle revient donc, en composition ETAGEE plutot que juxtaposee : les cartes se
   chevauchent en escalier, ce qui demande peu de largeur et lit tres bien la
   profondeur. Et elle PIVOTE au defilement (voir le bloc MOUVEMENT), donc elle
   repond au doigt de celui qui lit.
   ------------------------------------------------------------------ */
@media (max-width:1023px){
  /* Samuel l'a signale deux fois : le nom, la promesse et le produit se
     touchaient, au point qu'on lisait « RELIATECH » comme le nom de la machine.
     44 px entre blocs, et une marge propre autour du produit. */
  .hero-in{grid-template-columns:minmax(0,1fr);row-gap:44px}
  /* `order:-1` : sur telephone la scene passe AVANT le texte. Dans le flux
     naturel elle arrivait apres les boutons, donc au pixel 551 — autant dire
     jamais vue. C'est le premier ecran d'un visiteur mobile : il doit y voir du
     materiel et des prix tout de suite, et quelque chose qui bouge.
     Elle porte elle-meme trois prix reels, ce qui remplit la promesse « on voit
     qu'on vend quelque chose » sans attendre la bande de rayons. */
  .hero-scene{order:-1;height:194px;margin:0;perspective:760px;perspective-origin:52% 44%}
  /* Le produit vedette passe AVANT le texte : c'est le premier ecran d'un
     visiteur mobile, il doit y voir du materiel tout de suite. */
  /* Le NOM d'abord, le produit ensuite (demande de Samuel, 29/07) : quand
     personne ne vous connait, c'est le nom qu'il faut planter en premier.
     Une seule colonne et les zones sont neutralisees : l'ordre affiche redevient
     l'ordre du document, soit nom, produit, reste. Aucun `order` a arbitrer. */
  .hero-in{grid-template-areas:none}
  .hero-tete,.hero-txt,.hero-vedette,.hero-scene{grid-area:auto}
  /* Nom, PUIS produit, puis le reste. Le produit est ecrit apres le corps dans le
     document (c'est ce que veut la mise en page a deux colonnes du bureau) : ici
     `order` le remonte. Il ne peut le faire que parce que les trois blocs sont
     desormais freres — c'etait tout l'objet de sortir l'accroche de hero-txt.
     Compromis assume : a la lecture au clavier, le produit vient apres les
     boutons. C'est UN lien, et l'ordre entendu reste logique (nom, promesse,
     actions, produit). */
  /* 02/08 — le produit vedette passait AVANT le texte sur téléphone. Constat de
     Samuel : « on voit un écran à 1500 euros, ça fait peur ». C'est vrai, et c'est
     un contresens commercial : la vedette est une machine professionnelle à
     1 469,90 €, soit le haut du panier, montrée à quelqu'un qui ne sait pas encore
     ce qu'on vend. Le premier prix qu'un visiteur doit voir est un prix d'entrée.
     La vedette passe donc APRÈS le texte et les puces d'intention ; juste en
     dessous, la bande des rayons annonce chaque univers « dès X € », avec des
     montants à deux chiffres. On ne cache pas la machine chère, on cesse de la
     mettre en devanture. */
  .hero-tete{order:1}
  .hero-txt{order:2}
  .hero-vedette,.hero-scene{order:3}
  .hero-vedette{gap:18px;margin:6px 0}
  /* Plafond ABSOLU en plus du pourcentage : a 1005 px (tablette, sous le seuil
     de la mise en page a deux colonnes), 88 % faisaient un produit de 849 px
     et un hero de 1130 px de haut. Un pourcentage seul ne borne rien. */
  .hero-vedette-scene{max-width:min(88%,400px);margin:0 auto}
  .hero-h1{gap:10px}
  .hero-promesse{max-width:none}
  /* Le logo entier est haut : sur téléphone il prend la largeur qu'il faut pour être
     reconnaissable sans repousser le produit sous la ligne de flottaison. */
  .hero-logo{width:min(58vw,240px)}
  .hs-c{width:132px;padding:8px 9px 7px;border-radius:13px}
  .hs-c img{height:66px;margin-bottom:6px}
  .hs-c figcaption{padding-top:6px}
  .hs-c figcaption b{font-size:.79rem}
  .hs-c figcaption span{font-size:.79rem}
  .hs-c1{top:0;left:1%;--z:44px;--r:-6deg}
  .hs-c2{top:34px;right:2%;--z:0px;--r:5deg}
  .hs-c3{bottom:0;left:29%;--z:-30px;--r:3deg;--s:.95}
}
@media (max-width:860px){
  .hero-in{padding-top:34px;padding-bottom:24px}
  .hero h1{max-width:none}
  .hero-sous{max-width:none}
  .hero-cta .btn{flex:1 1 100%}
  .hero-sous{font-size:.97rem;margin-top:14px}
  .hero-puces{margin-top:16px;gap:7px}
  .hero-puces a{font-size:.81rem;padding:6px 13px}
  /* La bande devient un rayonnage qu'on fait glisser au doigt. Deux tuiles et
     demie visibles : la troisieme coupee est ce qui dit qu'il y en a d'autres. */
  /* `overscroll-behavior-x:contain` empeche le geste horizontal de deborder sur la
     page (et sur le retour arriere du navigateur) quand on arrive au bout du rayon.
     `touch-action:manipulation` supprime le delai de 300 ms du double-tap. */
  .hero-rail{display:flex;overflow-x:auto;gap:10px;scroll-snap-type:x proximity;
    overscroll-behavior-x:contain;touch-action:pan-x pan-y;
    margin-inline:-20px;padding:2px 20px 8px;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .hero-rail .univ{touch-action:manipulation}
  .hero-rail::-webkit-scrollbar{display:none}
  .hero-rail>li{flex:0 0 43%;scroll-snap-align:start}
  .hero-rail .univ{transform:none}
  .hero-rayons{padding-bottom:30px}
}
@media (max-width:560px){
  .hero h1{font-size:clamp(2rem,8.4vw,2.5rem)}
  .hero-tel-note{display:none}
  .hero-rail>li{flex-basis:46%}
  /* Le titre de la bande et son lien se disputaient la ligne : le titre passait
     sur deux lignes pour laisser tenir « Comparer des produits ». Le lien perd
     son complément, la cible reste la même. */
  .hero-rayons-h{font-size:.95rem}
  .hero-rayons-lien{font-size:.83rem}
  .hero-rayons-lien .lien-long{display:none}
}
@media (max-width:380px){
  .hero-rail>li{flex-basis:54%}
}

/* Un rayon = une vignette, un nombre de références, un prix de départ réel.
   La classe sert dans la bande du hero (cartes blanches sur le bleu) ; elle reste
   autonome pour pouvoir resservir sur fond clair ailleurs. */
.hero-eyebrow{margin:0 0 13px;font-size:.79rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#aab4f2}
.univers{display:grid;grid-template-columns:repeat(auto-fill,minmax(174px,1fr));gap:14px}
.univ{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:14px 15px 13px;
  transition:border-color var(--t-moyen) var(--ease),box-shadow var(--t-moyen) var(--ease),transform var(--t-moyen) var(--ease)}
.univ:hover{border-color:var(--line-2);box-shadow:var(--shadow);transform:translateY(-2px)}
.univ-vis{display:flex;align-items:center;justify-content:center;height:100px;margin-bottom:11px}
.univ-vis img{max-height:100px;width:auto;height:auto;max-width:100%;object-fit:contain}
.univ-nom{font-weight:700;font-size:.97rem;color:var(--ink);line-height:1.25}
.univ-meta{margin-top:4px;margin-bottom:0;font-size:.82rem;color:var(--muted)}
.univ-des{color:var(--blue);font-weight:800;white-space:nowrap}
@media (max-width:560px){
  .univers{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
  .univ{padding:11px 12px 10px}
  .univ-vis{height:80px;margin-bottom:8px}
  .univ-vis img{max-height:80px}
  .univ-nom{font-size:.9rem}
}

/* sections
   L'echelle sautait de 53 px (titre du hero) a 22 px (titre de section), puis
   ecrasait six niveaux d'information entre 15 et 23 px. Sous le hero, plus rien
   n'avait de voix : un titre de section pesait moins que les quatre prix qui
   l'entouraient. C'est la cause typographique du « on dirait un menu ».
   Le niveau intermediaire manquant est retabli ici. */
.sec-h{font-size:clamp(1.6rem,2.4vw,1.9rem);font-weight:800;margin:56px 0 6px;letter-spacing:-.02em}
.sub{color:var(--muted);margin:0 0 26px;max-width:52ch;text-wrap:pretty}
main.wrap h1{margin-top:36px;font-size:clamp(1.75rem,3vw,2.1rem);letter-spacing:-.02em}
/* Quand le titre ouvre sa section, c'est la section qui porte la respiration :
   sinon les deux marges s'additionnent et le rythme part en vrille. */
main>section>.sec-h:first-child,.sec-tete .sec-h{margin-top:0}
/* Rythme de la page d'accueil. Avant, les huit sections se suivaient a
   48-54 px d'intervalle : une bande de trois packs respirait exactement comme
   une bande de vingt cartes, donc rien ne disait au lecteur ce qui compte. */
main>section+section{margin-top:72px}
main>section.sec--majeure{margin-top:96px}
main>section.sec--mineure{margin-top:52px}
@media (max-width:760px){
  main>section+section{margin-top:48px}
  main>section.sec--majeure{margin-top:60px}
  main>section.sec--mineure{margin-top:38px}
}

/* cartes catégorie */
.cat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:18px;perspective:1400px}
.cat-card{background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-sm);transition:box-shadow .2s var(--ease),border-color .2s var(--ease);color:var(--ink)}
.cat-card:hover{box-shadow:var(--shadow);border-color:#c9d0e8}
.cat-card img{height:150px;width:100%;object-fit:contain;padding:18px;background:#fff;transition:transform .25s var(--ease)}
.cat-card:hover img{transform:scale(1.04)}
.cat-card div{padding:12px 16px 16px;border-top:1px solid var(--line)}
.cat-name{font-weight:700}
.cat-n{color:var(--muted);font-size:.85rem}

/* grille + cartes produit */
/* `perspective` sur la grille : la carte survolee se redresse vers le lecteur au
   lieu de simplement grandir. C'est un degre de plus que le `translateY` de tout
   le monde, et ca ne coute rien — la propriete animee reste `transform`. */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:18px}
.card{background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-sm);transition:box-shadow .2s var(--ease),border-color .2s var(--ease);display:flex;flex-direction:column;color:var(--ink)}
.card:hover{box-shadow:var(--shadow);border-color:#c9d0e8}
.card-media{position:relative;height:190px;display:flex;align-items:center;justify-content:center;padding:18px;background:#fff;overflow:hidden}
.card-media img{width:100%;height:100%;object-fit:contain;transition:transform .25s var(--ease)}
.card:hover .card-media img{transform:scale(1.045)}
/* Date de livraison estimée, au moment de commander. Discrète — elle rassure, elle
   ne vend pas — mais lisible : c'est la seule information de la page qui parle de
   week-ends et de jours fériés. */
.panier-livraison-estimee{margin:10px 0 0;padding:10px 13px;border-left:3px solid var(--blue-clair);background:color-mix(in srgb, var(--blue-clair) 8%, transparent);border-radius:0 8px 8px 0;font-size:.9rem;line-height:1.45}

/* Le pourcentage porte SA RÉFÉRENCE avec lui. Un « -26 % » nu se lit comme une remise
   que nous aurions consentie sur notre propre prix antérieur (art. L112-1-1) — ce qui
   serait faux, nous n'avons pas de prix antérieur. « vs conseillé » garde l'impact du
   chiffre et dit d'où il vient, en cohérence avec la mention sous le prix. */
.badge-promo{position:absolute;top:10px;left:10px;background:var(--blue-clair);color:#fff;font-weight:700;font-size:.72rem;border-radius:8px;padding:4px 8px;line-height:1.15;text-align:center}
.badge-promo small{display:block;font-size:.58rem;font-weight:600;opacity:.92;letter-spacing:.01em}
.card-body{padding:14px 16px 16px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:4px;flex:1}
.card-brand{color:var(--muted);font-size:.73rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em}
/* Titre et ligne technique sont bornés à deux lignes ET réservent ces deux
   lignes. C'est ce qui fait que le PRIX tombe exactement à la même hauteur sur
   toutes les cartes d'une même rangée. Avant, `flex:1` était porté par les deux
   paragraphes `.card-tech` du corps de carte : l'espace restant se partageait
   entre eux, et le prix se décalait jusqu'à 66 px d'une carte à l'autre. Rien
   ne trahit plus vite un site fait à la va-vite qu'une rangée de prix en
   escalier. */
.card-title{font-weight:700;font-size:.95rem;line-height:1.32;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.64em}
.card-tech{color:var(--muted);font-size:.83rem;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.8em}
.card-price{margin-top:8px}
/* Classe énergie et mentions d'offre restent collées au bas de la carte. */
.card-bas{margin-top:auto;padding-top:6px;display:flex;flex-direction:column;gap:4px}
.card-bas:empty{display:none}
.card-meta{color:var(--muted);font-size:.83rem;line-height:1.4}
.card-price strong{color:var(--blue);font-size:1.2rem;font-weight:800;font-variant-numeric:tabular-nums}
.card-price-demande strong{font-size:.98rem;font-weight:700;color:var(--ink)}
.card-price small{color:var(--muted);font-weight:700;margin-left:5px;font-size:.72rem}
.card-price del{color:var(--muted);font-size:.88rem;margin-right:6px}
.card-tier{position:absolute;top:10px;right:10px;background:var(--blue-soft);color:var(--blue);font-weight:700;font-size:.7rem;border-radius:8px;padding:4px 8px}
/* MOBILE : une seule colonne, et la carte passe en LIGNE (photo a gauche, texte a
   droite). Deux colonnes sur un ecran de 375 px donnaient des cartes de 162 px :
   titre tronque, ligne technique illisible, et les deux boutons debordaient de
   l'ecran (19 px de defilement horizontal). Le format ligne montre autant de
   produits par ecran, mais chacun se lit vraiment. */
@media (max-width:560px){
  .grid{grid-template-columns:1fr;gap:12px}
  .card{flex-direction:row;align-items:stretch}
  .card-media{width:122px;flex:none;height:auto;min-height:122px;padding:10px;border-right:1px solid var(--line)}
  /* 🚨 02/08 — la multiprise Belkin s'affichait deux fois plus haute que ses voisines
     (constat de Samuel sur téléphone). Cause : en format ligne la boîte image passe en
     `height:auto`, et `height:100%` sur une image dont le parent n'a pas de hauteur
     déterminée ne contraint plus rien. La photo reprenait alors ses proportions
     naturelles — 532 × 1200, soit 232 px de haut dans une boîte de 122.
     12 produits sur 178 ont une photo en portrait (jusqu'à 340 × 1200 sur un Dell Pro
     Micro), donc le problème était général, pas propre à cette référence.
     On borne la HAUTEUR de l'image plutôt que de forcer celle de la boîte : la carte
     en ligne doit rester libre de s'étirer si son texte est long. */
  .card-media img{height:auto;max-height:102px}
  .card-body{border-top:0;padding:12px 14px;justify-content:center;gap:2px;min-width:0}
  /* En format ligne, la carte se lit de haut en bas sans voisine a aligner :
     les hauteurs reservees n'ont plus de raison d'etre et ne feraient
     qu'etirer inutilement les cartes courtes. */
  .card-title{font-size:.92rem;min-height:0}
  .card-tech{font-size:.79rem;min-height:0}
  .card-price{margin-top:6px}
  .card-bas{margin-top:2px;padding-top:0}
  .card-price strong{font-size:1.15rem}
  .card-tier{top:6px;right:6px;font-size:.64rem;padding:3px 6px}
  /* 🚨 12/08 (Samuel) : « les étiquettes Accessible et tout chevauchent les pourcentages
     de remise ». Les deux badges sont posés dans les coins opposés du visuel : à pleine
     largeur ils ne se touchent jamais, mais sur une carte de téléphone en promo — donc
     avec le pourcentage de remise À GAUCHE et la gamme À DROITE — la place manque et ils
     se recouvrent. La remise prime : c'est l'information commerciale. Sur une carte qui
     porte une promo, la gamme descend sous elle, alignée à droite, et rétrécit. */
  .card--promo .card-tier,
  .card:has(.badge-promo) .card-tier{top:auto;bottom:6px;right:6px;font-size:.6rem;padding:2px 5px;opacity:.9}
  .badge-promo{max-width:58%}
  /* Les actions occupent toute la largeur du bloc et se partagent la place a
     parts egales : plus rien ne depasse, et chaque cible reste large au doigt. */
  .card-actions{gap:8px}
  .card-actions>.btn{flex:1 1 0;min-width:0}
  .card-actions .cmp-add{flex:1 1 0;min-width:0;justify-content:center;padding:9px 8px}
}

/* ---------- sélection « Comparer » ---------- */
/* La case vit hors du <a> : la carte est enveloppée dans .card-slot. */
/* La perspective est portee par le PARENT DIRECT de la carte, jamais par la
   grille : entre les deux il y a `.card-slot` (l'enveloppe qui sort la case de
   comparaison du lien), et une perspective posee sur un grand-parent ne
   s'applique pas. Posee sur la grille, le `rotateX` du survol s'aplatissait
   sans rien casser ni rien produire — le pire des cas, celui qu'on ne voit pas. */
.card-slot{display:flex;flex-direction:column;min-width:0;perspective:1400px}
/* `.pack-card` autant que `.card` : la règle ne visait que les cartes produit, si
   bien qu'un pack dont la composition tient sur trois lignes poussait son bouton
   « Ajouter ce pack au panier » 20 px plus bas que ses voisins. Mesuré le 28/07 sur
   l'accueil, où les trois packs sont côte à côte. */
.card-slot>.card,.card-slot>.pack-card{flex:1}
.cmp-add{display:flex;align-items:center;gap:9px;margin-top:9px;padding:9px 12px;min-height:44px;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);font-size:.84rem;font-weight:600;color:var(--muted);cursor:pointer;transition:border-color .16s var(--ease),color .16s var(--ease),background .16s var(--ease)}
.cmp-add:hover{border-color:var(--blue);color:var(--blue)}
.cmp-add input{width:18px;height:18px;accent-color:var(--blue);cursor:pointer;flex:none}
.cmp-add.on{border-color:var(--blue);background:var(--blue-soft);color:var(--blue)}
.cmp-add.sature{opacity:.5;cursor:not-allowed}
.cmp-add.sature input{cursor:not-allowed}
.cmp-add-pdp{margin:16px 0 0;align-self:flex-start;padding:11px 16px}

/* barre flottante de sélection */
.cmp-bar{position:fixed;left:50%;transform:translateX(-50%);bottom:16px;z-index:60;display:flex;align-items:center;gap:14px;background:var(--blue-deep);color:#fff;border-radius:14px;padding:11px 14px 11px 20px;box-shadow:var(--shadow-lg);max-width:calc(100vw - 24px)}
.cmp-bar-txt{font-size:.88rem;font-weight:600}
.cmp-bar .btn{padding:9px 18px;font-size:.88rem}
.cmp-bar-go{background:#fff;color:var(--blue)}
.cmp-bar-go:hover{background:#eef1ff}
.cmp-bar-off{opacity:.55;pointer-events:none}
.cmp-bar-vider{background:transparent;color:#d5daf7;border:1px solid rgba(255,255,255,.45)}
.cmp-bar-vider:hover{border-color:#fff;color:#fff}
body.cmp-bar-on{padding-bottom:88px}
@media (max-width:560px){
  .cmp-bar{left:12px;right:12px;transform:none;bottom:12px;gap:8px;padding:10px 12px}
  .cmp-bar-txt{font-size:.8rem;flex:1}
  .cmp-bar .btn{padding:9px 12px;font-size:.82rem}
}

/* ---------- packs ---------- */
.pack-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:18px;perspective:1600px}
.pack-card{background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;color:var(--ink);transition:box-shadow .2s var(--ease),border-color .2s var(--ease)}
.pack-card:hover{box-shadow:var(--shadow);border-color:#c9d0e8}
.pack-card-visuels{position:relative;display:flex;align-items:center;justify-content:center;gap:6px;height:176px;padding:16px;background:#fff}
.pack-card-visuels img{width:33%;height:100%;object-fit:contain}
.pack-card-body{padding:14px 16px 16px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:4px;flex:1}
.pack-card-nom{font-weight:700;font-size:1.02rem}
.pack-card-compo{color:var(--muted);font-size:.82rem;flex:1}
.pack-card-prix{margin-top:8px}
.pack-card-prix strong{color:var(--blue);font-size:1.3rem;font-weight:800;font-variant-numeric:tabular-nums}
.pack-card-prix del{color:var(--muted);font-size:.9rem;margin-right:6px}
.pack-card-prix small{color:var(--muted);font-weight:700;margin-left:5px;font-size:.72rem}
.pack-card-eco{color:var(--accent-txt);font-weight:700;font-size:.82rem}
.pack-pdp .pdp-media{display:flex;align-items:center}
.pack-visuels{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:14px;width:100%}
.pack-visuels figure{text-align:center}
.pack-visuels img{height:150px;width:100%;object-fit:contain}
.pack-visuels figcaption{margin-top:8px;font-size:.78rem;color:var(--muted);font-weight:600}
.pack-eco{margin:6px 0 10px;font-size:.92rem}
.pack-eco strong{color:var(--accent-txt);font-size:1.02rem}
.pack-eco span{color:var(--muted);display:block;font-size:.85rem}
.pack-compo{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:2px}
.pack-compo li{display:flex;align-items:center;gap:16px;padding:12px;border-radius:var(--r-sm)}
.pack-compo li:nth-child(odd){background:#f4f6fc}
.pack-compo-visu{flex:none;width:76px;height:76px;display:flex;align-items:center;justify-content:center;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm)}
.pack-compo-visu img{max-width:100%;max-height:64px;object-fit:contain}
.pack-compo-txt{flex:1;min-width:0}
.pack-compo-nom{font-weight:700;font-size:.95rem;margin:2px 0}
.pack-compo-nom a{color:var(--ink)}
.pack-compo-nom a:hover{color:var(--blue);text-decoration:underline}
.pack-compo-prix{flex:none;text-align:right;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.pack-compo-prix small{display:block;color:var(--muted);font-weight:600;font-size:.7rem}
.pack-total{margin-top:18px;padding-top:14px;border-top:1px solid var(--line);font-size:.92rem;color:var(--muted)}
.pack-total strong{color:var(--ink);font-variant-numeric:tabular-nums}
@media (max-width:560px){
  .pack-grid{grid-template-columns:1fr}
  .pack-compo li{gap:12px;padding:10px 8px}
  .pack-compo-visu{width:60px;height:60px}
  .pack-compo-prix{font-size:.9rem}
}

/* renvoi vers les packs depuis une fiche produit */
.pdp-packs{margin-top:22px;background:#f4f6fc;border:1px solid var(--line);border-radius:var(--r-sm);padding:14px 16px}
.pdp-packs-h{font-weight:700;font-size:.9rem;margin-bottom:6px}
.pdp-packs ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:4px}
.pdp-packs li{font-size:.9rem}
.pdp-packs a{font-weight:600;text-decoration:underline}
.pdp-packs-eco{color:var(--accent-txt);font-weight:700}

/* ---------- comparateur ---------- */
.cmp-out{margin:8px 0 10px}
.cmp-vide{color:var(--muted);background:#fff;border:1px dashed var(--line-strong);border-radius:var(--r);padding:26px 24px;text-align:center;font-size:.94rem}
.cmp-table-wrap{overflow-x:auto;background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-sm);-webkit-overflow-scrolling:touch}
.cmp-table{border-collapse:collapse;width:100%;min-width:520px}
.cmp-table caption{text-align:left}
.cmp-table th,.cmp-table td{padding:12px 14px;text-align:left;font-size:.9rem;border-bottom:1px solid var(--line);vertical-align:middle}
.cmp-col-lab{width:170px;min-width:150px}
.cmp-col-prod{min-width:190px;vertical-align:top;padding-top:16px}
.cmp-col-lien{display:block;color:var(--ink)}
.cmp-col-lien img{height:90px;width:auto;max-width:100%;object-fit:contain;margin:0 auto 8px}
.cmp-col-nom{display:block;font-weight:700;font-size:.88rem;line-height:1.3}
.cmp-col-lien:hover .cmp-col-nom{color:var(--blue);text-decoration:underline}
.cmp-col-retirer{margin-top:9px;background:#fff;border:1px solid var(--line-strong);border-radius:var(--r-sm);color:var(--muted);font:inherit;font-size:.78rem;font-weight:600;padding:7px 12px;cursor:pointer;transition:border-color .16s var(--ease),color .16s var(--ease)}
.cmp-col-retirer:hover{border-color:var(--danger);color:var(--danger)}
.cmp-row-lab{color:var(--muted);font-weight:600;background:#fff;position:sticky;left:0;box-shadow:1px 0 0 var(--line)}
.cmp-table tbody tr:nth-child(even) td{background:#f7f8fc}
.cmp-table tbody tr:nth-child(even) .cmp-row-lab{background:#f7f8fc}
.cmp-prix{font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.cmp-na{color:var(--muted)}
.cmp-table tbody tr td.cmp-best{background:#e9f6ee;font-weight:700}
.cmp-table tbody tr td.cmp-best::before{content:"✓";color:#12653d;font-weight:800;margin-right:7px}
.cmp-legende{margin:12px 0 6px;color:var(--muted);font-size:.83rem;max-width:60ch}
.cmp-legende-pastille{background:#e9f6ee;color:var(--ink);border-radius:6px;padding:2px 8px;font-weight:700}
.cmp-legende-pastille::before{content:"✓";color:#12653d;margin-right:6px}
.cmp-filtres{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:0 0 16px}
.cmp-filtres input[type=search],.cmp-filtres select{padding:10px 14px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;color:var(--ink);background:#fff;min-width:150px}
.cmp-filtres input[type=search]{flex:1;min-width:190px}
.cmp-prix-lab{display:flex;align-items:center;gap:7px;font-size:.86rem;color:var(--muted);font-weight:600}
.cmp-prix-lab input{width:96px;padding:10px 12px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;color:var(--ink);background:#fff}
.cmp-reset{padding:10px 16px;font-size:.86rem}
.cmp-pick{list-style:none;padding:0;margin:0 0 30px;background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-sm);overflow:hidden}
.cmp-pick-item{display:flex;align-items:center;gap:12px;padding:10px 16px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.cmp-pick-item:last-child{border-bottom:0}
.cmp-pick-lab{display:flex;align-items:center;justify-content:center;width:44px;height:44px;margin-left:-10px;flex:none;cursor:pointer;border-radius:var(--r-sm)}
.cmp-pick-lab:hover{background:var(--blue-soft)}
.cmp-pick-lab input{width:19px;height:19px;accent-color:var(--blue);cursor:pointer}
.cmp-pick-lab.sature{opacity:.45;cursor:not-allowed}
.cmp-pick-nom{flex:1;min-width:190px;font-weight:600;font-size:.92rem;color:var(--ink)}
.cmp-pick-nom:hover{color:var(--blue);text-decoration:underline}
.cmp-pick-meta{color:var(--muted);font-size:.82rem}
.cmp-pick-prix{font-weight:700;color:var(--blue);font-variant-numeric:tabular-nums;min-width:96px;text-align:right;font-size:.9rem}
@media (max-width:560px){
  .cmp-pick-item{gap:8px;padding:10px 12px}
  .cmp-pick-nom{min-width:0;flex-basis:100%;order:2}
  .cmp-pick-lab{order:1}
  .cmp-pick-prix{order:3;margin-left:auto;min-width:0}
  .cmp-pick-meta{order:4;flex-basis:100%;padding-left:34px}
  .cmp-filtres input[type=search]{min-width:0;flex-basis:100%}
  .cmp-table{min-width:460px}
  .cmp-col-lab{width:120px;min-width:110px}
  .cmp-col-prod{min-width:150px}
  .cmp-table th,.cmp-table td{padding:10px;font-size:.84rem}
}

/* récapitulatif pack sur la page commander */
.order-pack{display:flex;gap:16px;align-items:flex-start;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:16px;margin:18px 0;box-shadow:var(--shadow-sm)}
.order-pack img{width:96px;height:96px;object-fit:contain;flex:none}
.order-pack-compo{list-style:none;padding:0;margin:6px 0;color:var(--muted);font-size:.86rem}
.order-pack-compo li{padding:2px 0}

/* toolbar catalogue */
.toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:0 0 20px}
.toolbar input,.toolbar select{padding:10px 14px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;color:var(--ink);background:#fff;min-width:150px}
.toolbar input::placeholder{color:var(--muted)}
.toolbar input{flex:1;min-width:210px}
.toolbar-count{color:var(--muted);font-size:.88rem;font-weight:600;margin-left:auto}
.empty{color:var(--muted);padding:30px 0}
.empty a{text-decoration:underline;font-weight:700}

/* fil d'ariane */
.crumbs{font-size:.85rem;color:var(--muted);margin:22px 0}
.crumbs a{color:var(--blue);font-weight:600}
.crumbs a:hover{text-decoration:underline}
.crumbs span[aria-hidden]{margin:0 4px;opacity:.6}

/* fiche produit */
.pdp{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:40px;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:30px;box-shadow:var(--shadow-sm)}
.gallery{min-height:320px;display:flex;align-items:center}
.gallery img{display:none;max-height:400px;margin:0 auto;object-fit:contain}
.gallery img.on{display:block}
.thumbs{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
.thumbs button{width:66px;height:66px;border:1px solid var(--line-strong);border-radius:var(--r-sm);background:#fff;cursor:pointer;padding:6px;transition:border-color .16s var(--ease)}
.thumbs button:hover{border-color:var(--blue)}
.thumbs button.on{border:2px solid var(--blue)}
.thumbs img{max-height:100%;object-fit:contain;margin:0 auto}
/* `main.wrap h1` (0,1,2) l'emportait sur `.pdp-info h1` (0,1,1) : cette regle
   etait du code mort et les 201 fiches heritaient d'un `margin-top:36px`, soit
   un trou de 36 px entre la marque et le nom du produit. Le selecteur est
   maintenant assez specifique pour gagner. */
main.wrap .pdp-info h1{font-size:1.75rem;margin:2px 0 6px;line-height:1.22}
.pdp-tech{color:var(--muted);font-size:.93rem}
.pdp-price{margin:20px 0 2px}
.pdp-price strong{color:var(--blue);font-size:2.1rem;font-weight:800;font-variant-numeric:tabular-nums}
.pdp-price del{color:var(--muted);font-size:1.1rem;margin-right:8px}
.pdp-price small{color:var(--muted);font-weight:700;margin-left:6px}
.pdp-price-demande strong{font-size:1.4rem}
.pdp-eco{color:var(--muted);font-size:.85rem;margin-bottom:8px}
.pdp-dispo{font-size:.86rem;color:var(--muted);margin-bottom:18px}
.pdp-dispo.ok{color:#157347;font-weight:600}
.cta-note{color:var(--muted);font-size:.83rem;margin-top:8px}
.bullets{margin:22px 0 0;padding:0;list-style:none}
.bullets li{padding:7px 0 7px 26px;position:relative;font-size:.94rem}
.bullets li::before{content:"✓";position:absolute;left:2px;color:var(--accent-txt);font-weight:700}
.reassurance{margin-top:26px;border-top:1px solid var(--line);padding-top:16px;display:flex;flex-direction:column;gap:8px}
.reassurance p{font-size:.88rem;color:var(--muted)}
.reassurance strong{color:var(--ink)}
.reassurance a{text-decoration:underline}
.pdp-detail{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:30px;margin-top:22px;box-shadow:var(--shadow-sm)}
.pdp-detail h2{font-size:1.12rem;margin:22px 0 10px}
.pdp-detail section:first-child h2{margin-top:0}
.specs{list-style:none;padding:0;margin:0;columns:2;column-gap:36px}
.specs li{display:flex;justify-content:space-between;gap:14px;padding:9px 12px;font-size:.93rem;break-inside:avoid;border-radius:8px}
.specs li:nth-child(even){background:#f4f6fc}
.specs span{color:var(--muted)}
.specs strong{text-align:right}
@media (max-width:860px){
  .pdp{grid-template-columns:1fr;padding:20px;gap:24px}
  .specs{columns:1}
  .gallery{min-height:220px}
  .gallery img{max-height:280px}
}

/* pourquoi nous */
.why{margin-top:54px;background:#fff;border-top:1px solid var(--line);padding:48px 0 42px}
.why-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:28px}
.why h3{font-size:1rem;margin-bottom:6px;color:var(--blue);min-height:1.55em}
.why p{color:var(--muted);font-size:.9rem;text-wrap:pretty}

/* bloc éditorial catégorie */
.cat-seo{margin:52px auto 20px;max-width:58ch;color:var(--ink)}
.cat-seo h2{font-size:1.15rem;margin-bottom:10px}
.cat-seo p{color:var(--muted);font-size:.93rem;margin-bottom:12px;text-wrap:pretty}

/* pages éditoriales (à propos, guides) */
.prose-page{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:28px;box-shadow:var(--shadow-sm);margin-bottom:30px}
.prose-page p,.prose-page li{font-size:.95rem;max-width:56ch;margin-bottom:12px}
.prose-page h2{font-size:1.12rem;margin:20px 0 8px}
.prose-page ul{padding-left:20px;margin-bottom:12px}
.prose-page .grid{margin:10px 0 6px}
.guide-others{margin-bottom:40px}
.guide-others a{text-decoration:underline}

/* FAQ */
.faq-list{margin-bottom:26px}
.faq-item{background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);margin-bottom:10px;box-shadow:var(--shadow-sm)}
.faq-item summary{cursor:pointer;font-weight:600;padding:14px 18px;list-style-position:inside}
.faq-item summary:hover{color:var(--blue)}
.faq-item p{padding:0 18px 16px;color:var(--muted);font-size:.93rem;max-width:56ch}
.faq-item a{text-decoration:underline}

/* 404 */
.notfound-links{display:flex;gap:12px;flex-wrap:wrap;margin:22px 0 26px}

/* commander */
.order-prod{display:flex;gap:16px;align-items:center;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:16px;margin:18px 0;box-shadow:var(--shadow-sm)}
.order-prod img{width:84px;height:84px;object-fit:contain}
.order-form{display:flex;flex-direction:column;gap:14px;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:26px;box-shadow:var(--shadow-sm);margin-bottom:40px}
.order-form label{font-weight:700;font-size:.9rem;display:flex;flex-direction:column;gap:6px}
.order-form input,.order-form textarea{padding:11px 14px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;color:var(--ink)}
.order-form input::placeholder,.order-form textarea::placeholder{color:var(--muted)}
.contact-big{margin:22px 0 34px}

/* confirmation formulaire commander */
.form-ok{background:#fff;border:1px solid #b7dfc9;border-radius:var(--r);padding:24px 26px;margin-bottom:40px;box-shadow:var(--shadow-sm)}
.form-ok h2{color:#157347;font-size:1.15rem;margin-bottom:8px}
.form-ok p{font-size:.93rem;margin-bottom:10px;max-width:56ch}
.form-ok-fallback{color:var(--muted)}
.form-ok a{text-decoration:underline}
.form-recap{background:var(--bg);border:1px solid var(--line);border-radius:var(--r-sm);padding:14px 16px;font-size:.83rem;white-space:pre-wrap;word-break:break-word;margin-bottom:12px;font-family:ui-monospace,Consolas,monospace}
.btn-ghost2{background:#fff;color:var(--blue);border:1px solid var(--line-strong)}
.btn-ghost2:hover{border-color:var(--blue)}

/* légal */
/* encarts des CGV : classes (et non style= inline) pour rester compatibles
   avec une CSP stricte style-src 'self' */
.legal .legal-notice{border:1px solid #dbe3f5;border-radius:12px;padding:16px 18px;background:#f8fafc;margin-top:12px}
.legal .legal-encart{white-space:pre-line;background:#f8fafc;border:1px solid #dbe3f5;border-radius:12px;padding:16px 18px}
.legal h1{font-size:1.6rem;margin:12px 0 8px}
.legal .legal-hero{margin:32px 0 10px}
.legal .eyebrow{color:var(--accent-txt);font-weight:700;text-transform:uppercase;font-size:.76rem;letter-spacing:.08em}
.legal article{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:28px;margin:16px 0;box-shadow:var(--shadow-sm)}
.legal h2{font-size:1.1rem;margin:16px 0 8px}
.legal p,.legal li{font-size:.93rem;max-width:56ch}
.legal ul{padding-left:20px}
.legal a{text-decoration:underline}

/* footer */
.site-foot{background:var(--blue-deep);color:#c6cced;margin-top:64px;padding:0 0 0;font-size:.89rem}
.foot-reassurance{display:flex;gap:10px 30px;flex-wrap:wrap;justify-content:center;padding:18px 20px;border-bottom:1px solid rgba(255,255,255,.15);font-size:.82rem;color:#d5daf7}
.foot-reassurance span{position:relative;padding-left:20px}
/* #5B9CFF sur le navy du pied de page ne faisait que 3,68:1. Cette teinte-ci,
   claire, monte a 7,0:1 tout en restant la couleur d accent de la marque. */
.foot-reassurance span::before{content:"✓";position:absolute;left:0;color:#9FC6FF;font-weight:700}
.foot-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:32px;padding-top:40px;padding-bottom:32px}
.foot-brand{color:#fff;font-weight:800;letter-spacing:.05em;margin-bottom:8px}
.foot-h{color:#fff;font-weight:700;margin-bottom:8px}
.site-foot ul{list-style:none;padding:0;margin:0}
.site-foot li a{display:inline-block;padding:4px 0}
.site-foot a{color:#c6cced;text-decoration:none}
.site-foot a:hover{color:#fff;text-decoration:underline}
.foot-legal{border-top:1px solid rgba(255,255,255,.15);padding:15px 20px;text-align:center;font-size:.78rem}

/* ---------- actions sur les cartes (panier + comparateur) ---------- */
/* La barre d'actions ne prend AUCUNE place tant que ses boutons sont masqués
   (sans JavaScript, la carte reste exactement comme avant). */
/* La hauteur de la ligne d'actions est réservée en dur : les deux contrôles
   sont livrés `hidden` et révélés par JS, et sans réservation CHAQUE carte
   grandissait de 44 px après le chargement des scripts. Sur une grille, c'est
   toute la page qui sursaute rangée par rangée — le plus gros contributeur au
   décalage de mise en page du site. */
.card-actions{display:flex;gap:8px;align-items:stretch;min-height:44px}
/* Cette règle était en conflit direct avec sa jumelle mobile (même
   spécificité, mais déclarée plus haut dans le fichier, donc perdante) : sur
   téléphone « Comparer » restait collé au bord droit, à l'endroit exact du
   bouton flottant de Rely, qui en recouvrait 40 %. Elle est maintenant bornée
   au grand écran, où elle a un sens. */
@media (min-width:561px){
  .card-actions .cmp-add{flex:none}
}
.btn-panier{font:inherit;font-weight:700;cursor:pointer;border-radius:var(--r-sm);border:1px solid var(--blue);background:var(--blue);color:#fff;transition:background var(--t-court) var(--ease),box-shadow var(--t-court) var(--ease),transform var(--t-court) var(--ease)}
.btn-panier:hover{background:var(--blue-hover);border-color:var(--blue-hover);box-shadow:var(--shadow-sm)}
.btn-panier:active{transform:translateY(1px)}
.btn-panier.ok{background:var(--vert);border-color:var(--vert)}
.btn-panier-mini{flex:1;min-height:44px;margin-top:9px;padding:9px 12px;font-size:.86rem}
.btn-panier-pdp{width:100%}
.btn-panier-sug{width:100%;min-height:44px;padding:10px 14px;font-size:.88rem;margin-top:10px}
.pdp-cta{display:flex;flex-direction:column;gap:10px;align-items:stretch}
.pdp-cta .btn{width:100%}
/* entrée « pro » (volume / sur mesure) sur chaque fiche */
.pdp-volume{margin:14px 0 0;padding:11px 14px;background:var(--blue-soft);border-radius:var(--r-sm);font-size:.86rem;color:var(--ink-2)}
.pdp-volume a{font-weight:700;text-decoration:underline;white-space:nowrap}
/* La note de l'asterisque : elle porte la seule precision juridique de la colonne
   d'achat, une fois, en bas, au lieu de repeter « ouvrés » a chaque ligne. */
.pdp-ast{margin:10px 0 0;font-size:.76rem;color:var(--muted)}

/* ---------- upsell « pour un peu plus » ---------- */
.upsell{display:flex;align-items:center;gap:14px;margin-top:16px;padding:13px 16px;border:1px solid var(--line-2);border-radius:var(--r-sm);background:linear-gradient(#fff,#fbfcff);color:var(--ink);transition:border-color var(--t-moyen) var(--ease),box-shadow var(--t-moyen) var(--ease),transform var(--t-moyen) var(--ease)}
.upsell:hover{border-color:var(--blue);box-shadow:var(--shadow-sm);transform:translateY(-1px)}
.upsell-txt{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}
.upsell-txt strong{font-size:.92rem;font-weight:700;line-height:1.35}
.upsell-gain{font-size:.83rem;color:var(--muted)}
.upsell-prix{font-weight:800;color:var(--blue);white-space:nowrap;font-variant-numeric:tabular-nums}
.upsell-prix small{font-weight:700;color:var(--muted);font-size:.7rem;margin-left:4px}
.upsell-res{margin:22px 0 0;padding:16px 18px}

/* ---------- suggestions « Complétez votre poste » ---------- */
.sug-bloc{margin-top:8px}
.sug-sous{margin-top:-8px}
.sug-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px}
.sug{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-sm);transition:box-shadow var(--t-moyen) var(--ease),border-color var(--t-moyen) var(--ease),transform var(--t-moyen) var(--ease)}
.sug:hover{box-shadow:var(--shadow);border-color:var(--line-2);transform:translateY(-2px)}
.sug-visu{display:flex;align-items:center;justify-content:center;height:150px;padding:16px;background:linear-gradient(#fff,#f6f8fd)}
.sug-visu img{max-height:100%;width:auto;object-fit:contain;transition:transform .3s var(--ease)}
.sug:hover .sug-visu img{transform:scale(1.05)}
.sug-corps{display:flex;flex-direction:column;gap:5px;padding:14px 16px 16px;border-top:1px solid var(--line);flex:1}
.sug-role{font-size:.72rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent-txt)}
.sug-nom{font-weight:700;font-size:.94rem;line-height:1.32}
.sug-nom a{color:var(--ink)}
.sug-nom a:hover{color:var(--blue);text-decoration:underline}
.sug-arg{font-size:.83rem;color:var(--muted)}
.sug-accroche{font-size:.86rem;color:var(--ink-2);border-top:1px dashed var(--line-2);padding-top:8px;margin-top:3px;flex:1}
.sug-bas{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-top:6px}
.sug-prix{font-weight:800;color:var(--blue);font-size:1.1rem;font-variant-numeric:tabular-nums}
.sug-prix small{font-size:.7rem;color:var(--muted);font-weight:700;margin-left:4px}
.sug-urgence{font-size:.76rem;font-weight:700;color:var(--accent-txt);background:#EAF1FE;border-radius:6px;padding:3px 8px}
.sug-fiche{font-size:.82rem;font-weight:600;text-align:center;margin-top:8px;text-decoration:underline}

/* ---------- bloc pro (volume, sur mesure) ---------- */
.pro-bloc{margin-top:52px;background:var(--blue-deep);color:#d7dcfa;border-radius:var(--r);padding:36px 38px;position:relative;overflow:hidden;isolation:isolate}
.pro-bloc::before{content:"";position:absolute;inset:0;z-index:-1;background:radial-gradient(70% 120% at 100% 0%,rgba(91,156,255,.3),rgba(91,156,255,0) 65%)}
/* Même sol qu'au premier écran, en plus discret : ici il accompagne un
   argumentaire, il ne doit pas concurrencer le texte qui est dessus. */
.pro-sol{position:absolute;left:-25%;right:-25%;bottom:-6%;height:52%;z-index:-1;overflow:hidden;pointer-events:none;
  transform:perspective(600px) rotateX(70deg);transform-origin:50% 100%;
  -webkit-mask-image:linear-gradient(to top,#000 2%,rgba(0,0,0,.45) 30%,transparent 76%);
  mask-image:linear-gradient(to top,#000 2%,rgba(0,0,0,.45) 30%,transparent 76%)}
.pro-sol::before{content:"";position:absolute;left:0;right:0;top:-100%;bottom:-100%;
  background-image:linear-gradient(rgba(255,255,255,.1) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.08) 1px,transparent 1px);
  background-size:64px 64px}
@media (prefers-reduced-motion:reduce){ .pro-sol{display:none} }
.pro-bloc h2{color:#fff;font-size:1.45rem;margin-bottom:10px}
.pro-txt>p{max-width:53ch;font-size:.97rem}
.pro-points{list-style:none;padding:0;margin:20px 0 24px;display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px 30px}
.pro-points li{position:relative;padding-left:22px;font-size:.92rem;text-wrap:pretty}
.pro-points li::before{content:"→";position:absolute;left:0;color:#9FC6FF;font-weight:800}
.pro-points strong{color:#fff}
.pro-cta{display:flex;gap:12px;flex-wrap:wrap}
@media (max-width:560px){.pro-bloc{padding:26px 20px}.pro-cta .btn{flex:1 1 100%}}

/* ---------- panier ---------- */
.panier-vide{background:#fff;border:1px dashed var(--line-strong);border-radius:var(--r);padding:34px 28px;margin-bottom:34px;max-width:53ch}
.panier-vide-h{font-weight:800;font-size:1.1rem;margin-bottom:6px}
.panier-vide p{color:var(--muted);text-wrap:pretty}
.panier-vide-cta{display:flex;gap:12px;flex-wrap:wrap;margin-top:20px}
.panier-noscript{margin-top:16px;padding-top:14px;border-top:1px solid var(--line);font-size:.88rem}
.panier-layout{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:26px;align-items:start;margin-bottom:34px}
.panier-lignes{display:flex;flex-direction:column;gap:12px}
.pl{display:grid;grid-template-columns:110px minmax(0,1fr) auto;gap:18px;align-items:center;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:14px 18px;box-shadow:var(--shadow-sm)}
.pl-visu{display:flex;align-items:center;justify-content:center;height:88px}
.pl-visu img{max-height:100%;width:auto;object-fit:contain}
.pl-txt{min-width:0}
.pl-nom{font-weight:700;font-size:1rem;line-height:1.3;margin-bottom:3px}
.pl-nom a{color:var(--ink)}
.pl-nom a:hover{color:var(--blue);text-decoration:underline}
.pl-tech{font-size:.85rem;color:var(--muted)}
.pl-compo{list-style:none;padding:0;margin:4px 0 0;font-size:.83rem;color:var(--muted)}
.pl-compo li{padding:1px 0 1px 14px;position:relative}
.pl-compo li::before{content:"·";position:absolute;left:4px}
.pl-infos{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:7px;font-size:.8rem;color:var(--muted);align-items:center}
.pl-eco{color:var(--accent-txt);font-weight:700}
.pl-actions{display:flex;flex-direction:column;align-items:flex-end;gap:9px}
.qte{display:flex;align-items:center;border:1px solid var(--line-strong);border-radius:var(--r-sm);overflow:hidden;background:#fff}
.qte-b{width:44px;height:44px;border:0;background:#fff;color:var(--blue);font-size:1.1rem;font-weight:800;cursor:pointer;transition:background var(--t-court) var(--ease)}
.qte-b:hover{background:var(--blue-soft)}
.qte-n{width:52px;height:44px;border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);text-align:center;font:inherit;font-weight:700;color:var(--ink);-moz-appearance:textfield}
.qte-n::-webkit-outer-spin-button,.qte-n::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.pl-prix{text-align:right}
.pl-prix strong{font-size:1.15rem;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.pl-prix small{display:block;font-size:.74rem;color:var(--muted);font-weight:600}
.pl-sup{background:none;border:0;color:var(--muted);font:inherit;font-size:.82rem;text-decoration:underline;cursor:pointer;padding:4px 8px;min-height:44px}
.pl-sup:hover{color:var(--danger)}
.panier-recap{position:sticky;top:88px;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:22px 22px 24px;box-shadow:var(--shadow-sm)}
.recap-h{font-size:1.05rem;margin-bottom:14px}
.recap-l{display:grid;grid-template-columns:1fr auto;gap:9px 12px;font-size:.92rem;margin:0 0 14px}
.recap-l dt{color:var(--muted)}
.recap-l dd{text-align:right;font-weight:700;font-variant-numeric:tabular-nums}
.recap-eco{color:var(--accent-txt) !important}
.recap-offert{color:var(--vert) !important;font-weight:800}
.recap-total{display:flex;justify-content:space-between;align-items:baseline;gap:12px;border-top:1px solid var(--line);padding-top:14px;margin-bottom:8px}
.recap-total span{font-weight:700}
.recap-total strong{font-size:1.6rem;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.recap-note{font-size:.79rem;color:var(--muted);margin-bottom:16px;text-wrap:pretty}
.recap-seuil{background:var(--blue-soft);border-radius:var(--r-sm);padding:13px 15px;margin-bottom:16px}
.recap-seuil-h{font-weight:800;font-size:.92rem;color:var(--blue);margin-bottom:9px}
.recap-jauge{display:block;height:7px;border-radius:4px;background:#fff;overflow:hidden;box-shadow:inset 0 0 0 1px var(--line-2)}
.recap-jauge-in{display:block;height:100%;background:var(--blue-clair);border-radius:4px;transition:width var(--t-moyen) var(--ease)}
.recap-seuil-p{font-size:.79rem;color:var(--ink-2);margin-top:9px}
.recap-cta{width:100%;font-size:1rem}
.recap-vider{display:block;width:100%;margin-top:10px;background:none;border:0;color:var(--muted);font:inherit;font-size:.83rem;text-decoration:underline;cursor:pointer;min-height:44px}
.recap-vider:hover{color:var(--danger)}
.panier-commande{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:26px 28px;box-shadow:var(--shadow-sm);margin-bottom:44px}
.panier-commande h2{font-size:1.2rem;margin-bottom:6px}
.panier-commande-sous{color:var(--muted);font-size:.92rem;margin-bottom:18px;max-width:56ch;text-wrap:pretty}
.panier-commande .order-form{border:0;padding:0;box-shadow:none;margin-bottom:0}
.order-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px}
.lab-opt{font-weight:500;color:var(--muted)}
/* Adresse de livraison : un groupe visuellement distinct, sans bordure lourde —
   le formulaire de commande reste une seule colonne lisible. */
.order-adr{border:0;padding:0;margin:0;display:flex;flex-direction:column;gap:14px}
.order-adr legend{font-weight:700;font-size:.9rem;padding:0;margin-bottom:2px}
.order-adr .cta-note{margin:0}
.form-erreur{background:#EAF1FE;border:1px solid #BFD8FB;color:#8f3a1f;border-radius:var(--r-sm);padding:11px 14px;font-size:.88rem;font-weight:600}
.form-ok-actions{display:flex;gap:10px;flex-wrap:wrap}
textarea.form-recap{width:100%;resize:vertical;font-family:ui-monospace,Consolas,monospace}
@media (max-width:940px){
  .panier-layout{grid-template-columns:1fr}
  .panier-recap{position:static}
}
@media (max-width:620px){
  .pl{grid-template-columns:72px minmax(0,1fr);gap:12px;padding:12px}
  .pl-visu{height:64px}
  .pl-actions{grid-column:1 / -1;flex-direction:row;align-items:center;justify-content:space-between;border-top:1px solid var(--line);padding-top:11px;width:100%}
  .pl-prix{order:-1}
  .panier-commande{padding:20px 16px}
}

/* ---------- confirmation d'ajout (toast) ---------- */
.toast{position:fixed;left:50%;bottom:22px;transform:translate(-50%,14px);z-index:var(--z-toast);display:flex;align-items:center;gap:12px;background:var(--blue-deep);color:#fff;border-radius:14px;padding:12px 16px;box-shadow:var(--shadow-lg);max-width:calc(100vw - 24px);opacity:0;transition:opacity var(--t-moyen) var(--ease-out),transform var(--t-moyen) var(--ease-out)}
.toast.on{opacity:1;transform:translate(-50%,0)}
.toast-ico{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:#2ea56f;font-weight:800;font-size:.85rem;flex:none}
.toast-txt{font-size:.9rem;min-width:0}
.toast-lien{color:#fff;font-weight:700;font-size:.86rem;text-decoration:underline;white-space:nowrap}
body.cmp-bar-on .toast{bottom:92px}
@media (max-width:560px){.toast{left:12px;right:12px;transform:translateY(14px);max-width:none}.toast.on{transform:translateY(0)}}

/* ---------- fenêtre de suggestions (1 par session, jamais à l'arrivée) ---------- */
.modal-fond{position:fixed;inset:0;z-index:var(--z-fond);display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(16,22,79,.55);opacity:0;transition:opacity var(--t-moyen) var(--ease)}
.modal-fond.on{opacity:1}
.modal{position:relative;z-index:var(--z-modal);background:#fff;border-radius:20px;box-shadow:var(--shadow-lg);width:min(640px,100%);max-height:calc(100vh - 40px);overflow-y:auto;padding:28px 30px 24px;transform:translateY(10px) scale(.985);transition:transform var(--t-moyen) var(--ease-out)}
.modal-fond.on .modal{transform:none}
.modal-titre{font-size:1.3rem;margin-bottom:6px}
.modal-sous{color:var(--muted);font-size:.92rem;margin-bottom:18px;text-wrap:pretty}
.modal-liste{display:flex;flex-direction:column;gap:10px;margin-bottom:22px}
.modal-item{display:grid;grid-template-columns:84px minmax(0,1fr) auto;gap:14px;align-items:center;border:1px solid var(--line);border-radius:var(--r-sm);padding:11px 13px}
.modal-item img{width:84px;height:64px;object-fit:contain}
.modal-item-nom{font-weight:700;font-size:.92rem;line-height:1.3}
.modal-item-arg{font-size:.83rem;color:var(--muted);margin-top:3px;text-wrap:pretty}
.modal-item-bas{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:5px}
.modal-item-prix{font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.modal-item-btn{padding:10px 16px;min-height:44px;font-size:.86rem;white-space:nowrap}
.modal-item-btn.ok{background:var(--vert-fond);border-color:var(--vert);color:var(--vert)}
.modal-bas{display:flex;gap:12px;justify-content:flex-end;flex-wrap:wrap;border-top:1px solid var(--line);padding-top:18px}
.modal-fermer{position:absolute;top:12px;right:12px;width:38px;height:38px;border:0;background:none;color:var(--muted);font-size:1.6rem;line-height:1;cursor:pointer;border-radius:50%;transition:background var(--t-court) var(--ease),color var(--t-court) var(--ease)}
.modal-fermer:hover{background:var(--blue-soft);color:var(--blue)}
body.modal-ouvert{overflow:hidden}
@media (max-width:560px){
  .modal{padding:22px 16px 18px;border-radius:16px}
  .modal-item{grid-template-columns:60px minmax(0,1fr);gap:10px}
  .modal-item img{width:60px;height:52px}
  .modal-item-btn{grid-column:1 / -1;width:100%}
  .modal-bas .btn{flex:1 1 100%}
}

/* ---------- conseiller ---------- */
.quiz{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:28px 30px 24px;box-shadow:var(--shadow-sm);margin-bottom:30px;max-width:860px}
.quiz-progres{display:flex;align-items:center;gap:14px;margin-bottom:22px}
.quiz-barre{flex:1;height:6px;border-radius:4px;background:var(--blue-soft);overflow:hidden}
.quiz-barre-in{display:block;height:100%;width:0;background:var(--blue);border-radius:4px;transition:width .35s var(--ease-out)}
.quiz-etape{font-size:.82rem;font-weight:700;color:var(--muted);white-space:nowrap}
.q{border:0;padding:0;margin:0}
/* :not(.sr-only) est indispensable : sans lui, cette regle (meme specificite que
   .sr-only mais declaree plus loin) rendait le libelle invisible large de 100%,
   ce qui faisait defiler toute la page horizontalement sur mobile. */
.q legend:not(.sr-only){display:block;width:100%;margin-bottom:6px}
.q-num{display:block;font-size:.78rem;font-weight:700;color:var(--accent-txt);margin-bottom:4px}
.q-t{display:block;font-size:1.32rem;font-weight:800;letter-spacing:-.015em;text-wrap:balance}
.q-aide{color:var(--muted);font-size:.9rem;margin-bottom:16px;max-width:50ch}
.q-choix{display:grid;gap:10px;margin-top:14px}
.q-opt{display:block;cursor:pointer}
.q-opt input{position:absolute;opacity:0;width:0;height:0}
.q-opt-in{display:flex;flex-direction:column;gap:3px;border:1.5px solid var(--line-2);border-radius:var(--r-sm);padding:14px 18px 14px 46px;position:relative;transition:border-color var(--t-court) var(--ease),background var(--t-court) var(--ease),transform var(--t-court) var(--ease)}
.q-opt-in::before{content:"";position:absolute;left:17px;top:50%;margin-top:-9px;width:18px;height:18px;border-radius:50%;border:2px solid var(--line-strong);transition:border-color var(--t-court) var(--ease),box-shadow var(--t-court) var(--ease)}
.q-opt:hover .q-opt-in{border-color:var(--blue);background:var(--blue-soft);transform:translateX(2px)}
.q-opt input:focus-visible+.q-opt-in{outline:2px solid var(--blue);outline-offset:2px}
.q-opt input:checked+.q-opt-in{border-color:var(--blue);background:var(--blue-soft)}
.q-opt input:checked+.q-opt-in::before{border-color:var(--blue);box-shadow:inset 0 0 0 4px var(--blue)}
.q-opt-lab{font-weight:700;font-size:1rem}
.q-opt-sous{font-size:.85rem;color:var(--muted)}
.quiz-nav{display:flex;gap:12px;margin-top:22px;flex-wrap:wrap}
.quiz-nav .btn{padding:10px 18px;font-size:.88rem}
.quiz-nav .btn:disabled{opacity:.45;cursor:default}
.res{background:#fff;border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden}
.res-haut{padding:24px 28px 18px;background:linear-gradient(135deg,var(--blue-deep),var(--blue));color:#fff}
.res-eyebrow{font-size:.78rem;font-weight:700;color:#b9c2f4;margin-bottom:5px}
.res-titre{font-size:1.6rem;font-weight:800;color:#fff;letter-spacing:-.02em;text-wrap:balance}
.res-tech{color:#d7dcfa;font-size:.95rem;margin-top:5px}
.res-corps{display:grid;grid-template-columns:320px minmax(0,1fr);gap:30px;padding:26px 28px 28px;align-items:start}
.res-visu{display:flex;align-items:center;justify-content:center;background:linear-gradient(#fff,#f4f6fd);border:1px solid var(--line);border-radius:var(--r-sm);padding:18px;min-height:240px}
.res-visu img{max-height:220px;width:auto;object-fit:contain}
.res-prix strong{font-size:2.1rem;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.res-prix small{color:var(--muted);font-weight:700;margin-left:6px}
.res-pourquoi{list-style:none;padding:0;margin:16px 0 22px;display:flex;flex-direction:column;gap:9px}
.res-pourquoi li{position:relative;padding-left:26px;font-size:.95rem;text-wrap:pretty}
.res-pourquoi li::before{content:"✓";position:absolute;left:2px;color:var(--vert);font-weight:800}
.res-actions{display:flex;gap:12px;flex-wrap:wrap}
.res-actions .btn{flex:1 1 200px}
.res-tout{margin-top:20px;text-align:center}
.res-tout .btn{max-width:520px;width:100%}
.res-autres{margin-top:14px}
.res-autres-l{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px}
.res-autre{display:flex;gap:14px;align-items:center;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);padding:12px 14px;color:var(--ink);transition:border-color var(--t-court) var(--ease),box-shadow var(--t-court) var(--ease)}
.res-autre:hover{border-color:var(--blue);box-shadow:var(--shadow-sm)}
.res-autre img{width:90px;height:70px;object-fit:contain;flex:none}
.res-autre-nom{font-weight:700;font-size:.9rem;line-height:1.3}
.res-autre-tech{font-size:.8rem;color:var(--muted);margin:2px 0 4px}
.res-autre-prix{font-weight:800;color:var(--blue);font-size:.95rem}
.res-rien{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:28px;box-shadow:var(--shadow-sm);max-width:53ch}
.res-rien h2{font-size:1.25rem;margin-bottom:10px}
.res-rien p{color:var(--muted);margin-bottom:18px;text-wrap:pretty}
.res-pied{margin:26px 0 44px;color:var(--muted);font-size:.92rem}
.res-pied a{font-weight:700;text-decoration:underline}
@media (max-width:760px){
  .quiz{padding:22px 18px}
  .res-corps{grid-template-columns:1fr;gap:20px;padding:20px 18px 24px}
  .res-haut{padding:20px 18px 16px}
  .res-titre{font-size:1.3rem}
  .res-visu{min-height:180px}
  .res-actions .btn{flex:1 1 100%}
}

/* ==================== bons plans ==================== */
/* La page où l'envie d'acheter est la plus forte : elle doit se lire en diagonale.
   Trois vedettes chiffrées en euros (plus parlant qu'un pourcentage), puis les
   remises démontrées, puis les baisses non démontrables, rangées par rayon. */
.bp-hero{background:var(--blue-deep);border-radius:var(--r);padding:24px 26px;margin:22px 0 34px;color:#fff}
.bp-hero-h{font-size:1.15rem;color:#fff;margin-bottom:18px}
.bp-hero-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.bp-vedette{display:flex;flex-direction:column;gap:6px;background:#fff;border-radius:var(--r-sm);padding:16px;color:var(--ink);transition:transform var(--t-moyen) var(--ease),box-shadow var(--t-moyen) var(--ease)}
.bp-vedette:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg)}
.bp-vedette img{height:120px;width:100%;object-fit:contain}
.bp-vedette-eco{align-self:flex-start;background:var(--blue-clair);color:#fff;font-weight:800;font-size:1.05rem;border-radius:8px;padding:3px 10px;font-variant-numeric:tabular-nums}
.bp-vedette-nom{font-weight:700;font-size:.92rem;line-height:1.35;flex:1}
.bp-vedette-prix{font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.bp-vedette-prix small{font-size:.68rem;color:var(--muted);margin-left:3px}
.bp-vedette-ref{font-size:.76rem;color:var(--muted);font-weight:600}
.bp-vedette-ref del{font-variant-numeric:tabular-nums}
.bp-sec{margin-bottom:44px}
.bp-compte{display:inline-block;background:var(--blue-soft);color:var(--blue);font-size:.78rem;font-weight:800;border-radius:20px;padding:2px 10px;vertical-align:middle;margin-left:8px}
.bp-intro{color:var(--muted);font-size:.94rem;max-width:56ch;margin:-6px 0 20px;line-height:1.55}
.bp-intro strong{color:var(--ink)}
.bp-sommaire{font-size:.9rem;color:var(--muted);margin-bottom:22px}
.bp-sommaire a{font-weight:600;text-decoration:underline}
.bp-rayon{font-size:1.02rem;margin:30px 0 14px;scroll-margin-top:90px}
.bp-pied{background:var(--bg);border:1px solid var(--line);border-radius:var(--r);padding:18px 20px;font-size:.95rem;color:var(--ink-2);max-width:60ch}
.bp-pied a{font-weight:700;text-decoration:underline}
@media (max-width:820px){ .bp-hero-grid{grid-template-columns:1fr} .bp-hero{padding:18px} }

/* ==================== garantie ==================== */
/* Première question d'un acheteur pro. Le bloc dit d'abord ce qu'on lui doit
   nous (garantie légale), ensuite ce que le fabricant annonce, et seulement
   après ce qu'il peut acheter en plus. Jamais l'inverse. */
.gar-liste{list-style:none;display:flex;flex-direction:column;gap:14px;margin-bottom:18px}
.gar-liste li{display:flex;flex-direction:column;gap:3px;padding-left:26px;position:relative}
.gar-liste li::before{content:"";position:absolute;left:0;top:3px;width:16px;height:16px;border-radius:50%;background:var(--vert-fond);border:2px solid var(--vert)}
.gar-liste strong{font-size:.98rem;color:var(--ink)}
.gar-liste span{color:var(--muted);font-size:.9rem;max-width:53ch;line-height:1.5}
.gar-ext{background:var(--blue-soft);border:1px solid var(--blue-soft2);border-radius:var(--r);padding:18px 20px;margin-bottom:16px}
.gar-ext-h{font-weight:800;font-size:1.02rem;color:var(--blue);margin-bottom:6px}
.gar-ext-txt{font-size:.92rem;color:var(--ink-2);max-width:53ch;margin-bottom:8px}
.gar-ext-note{font-size:.85rem;color:var(--muted);max-width:53ch;margin-bottom:14px}
.gar-ext-bas{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.gar-ext-prix{font-size:1.3rem;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums;white-space:nowrap}
.gar-ext-prix small{font-size:.68rem;color:var(--muted);margin-left:4px;font-weight:700}
.btn-gar[data-ajoute="1"]{background:var(--vert-fond);border-color:var(--vert);color:var(--vert)}
.gar-legal{font-size:.82rem;color:var(--muted);max-width:56ch;line-height:1.5}
.gar-legal a{text-decoration:underline}
@media (max-width:620px){
  .gar-ext{padding:16px}
  .gar-ext-bas{gap:10px}
  .gar-ext-bas .btn{width:100%;justify-content:center}
}
/* Ligne de garantie dans le panier : rattachée visuellement à sa machine. */
.pan-gar{font-size:.85rem;color:var(--muted)}

/* ==================== téléphone ==================== */
/* Dans l'en-tête : visible sur grand écran, où il y a la place. Sur mobile le
   numéro reste joignable par le pied de page et la page contact, et le pouce a
   mieux à faire que d'éviter un lien de plus à côté du panier. */
.head-tel{display:flex;flex-direction:column;line-height:1.15;margin-right:14px;color:var(--ink);white-space:nowrap}
.head-tel-num{font-weight:800;font-size:1rem;font-variant-numeric:tabular-nums;letter-spacing:.01em}
.head-tel-note{font-size:.7rem;color:var(--muted);font-weight:600}
.head-tel:hover .head-tel-num{color:var(--blue)}
/* 1200 et non 1050 : à 1239 px le téléphone était encore affiché alors qu'il ne
   restait pas la place, et c'est lui que le bouton « Devis pro » recouvrait.
   Il reste joignable partout ailleurs — hero, pied de page, page contact. */
@media (max-width:1200px){ .head-tel{display:none} }
.foot-tel{display:block;font-weight:800;font-size:1.05rem;font-variant-numeric:tabular-nums;margin-bottom:4px}
/* Sur la page contact, le téléphone est une vraie porte d'entrée, pas une ligne perdue. */
.contact-tel{display:flex;flex-direction:column;gap:4px;background:var(--blue-soft);border:1px solid var(--blue-soft2);border-radius:var(--r);padding:18px 22px;margin:20px 0 6px;color:var(--blue);transition:border-color var(--t-court) var(--ease),background var(--t-court) var(--ease)}
.contact-tel:hover{background:var(--blue-soft2);border-color:var(--blue)}
.contact-tel-num{font-size:1.6rem;font-weight:800;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.contact-tel-note{color:var(--ink-2);font-size:.9rem;font-weight:500}
@media (max-width:620px){ .contact-tel-num{font-size:1.35rem} }

/* contact : liste de cadrage */
.contact-liste{margin:0 0 18px 20px;color:var(--muted);font-size:.95rem}
.contact-liste li{margin-bottom:6px;max-width:53ch}

/* ==================== formulaire de demande (/contact.html) ==================== */
/* Le seul endroit du site où un visiteur écrit : il doit se remplir vite, au
   clavier comme au pouce. Deux colonnes tant que ça reste lisible, une seule
   dès que la place manque. */
.dem{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:26px;box-shadow:var(--shadow-sm);margin:22px 0 34px}
.dem-h{font-size:1.2rem;margin-bottom:6px}
.dem-intro{color:var(--muted);font-size:.92rem;max-width:53ch;margin-bottom:20px}
.dem-form{display:flex;flex-direction:column;gap:16px}
.dem-ligne{display:flex;gap:16px;flex-wrap:wrap}
.dem-champ{flex:1 1 240px;display:flex;flex-direction:column;gap:6px;font-weight:700;font-size:.9rem;color:var(--ink)}
.dem-champ.dem-large{flex-basis:100%}
.dem-champ.dem-court{flex:0 1 140px}
.dem-lib abbr{color:var(--accent-txt);text-decoration:none;font-weight:800}
.dem-champ input,.dem-champ select,.dem-champ textarea{padding:11px 14px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;font-weight:400;color:var(--ink);background:#fff;width:100%;transition:border-color var(--t-court) var(--ease),box-shadow var(--t-court) var(--ease)}
.dem-champ textarea{resize:vertical;min-height:120px;line-height:1.5}
.dem-champ input::placeholder,.dem-champ textarea::placeholder{color:var(--muted)}
.dem-champ input:focus,.dem-champ select:focus,.dem-champ textarea:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft2)}
.dem-champ [aria-invalid="true"]{border-color:var(--danger);box-shadow:0 0 0 3px rgba(179,38,30,.16)}
/* Champ piège anti-robots : hors flux et hors tabulation, jamais lu à voix haute
   (aria-hidden dans le HTML). display:none serait détecté par les robots sérieux. */
.dem-piege{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.dem-erreur{background:var(--danger-fond);border:1px solid #F0C2BD;border-left-width:1px;color:var(--danger);border-radius:var(--r-sm);padding:11px 14px;font-size:.9rem;font-weight:600}
.dem-envoi{display:flex;flex-direction:column;gap:12px;align-items:flex-start}
.dem-envoi .btn{min-width:220px;justify-content:center}
.dem-rgpd{color:var(--muted);font-size:.82rem;max-width:53ch;line-height:1.5}
.dem-rgpd a{text-decoration:underline}
.dem-noscript{margin-top:16px;color:var(--muted);font-size:.9rem}
.dem-noscript a{text-decoration:underline}
/* Confirmation : Rely accueille la demande, le message dit ce qui se passe ensuite. */
.dem-ok{display:flex;gap:18px;align-items:flex-start;background:var(--vert-fond);border:1px solid #b7dfc9;border-radius:var(--r);padding:22px 24px}
.dem-ok h2{color:var(--vert);font-size:1.15rem;margin-bottom:8px}
.dem-ok p{font-size:.94rem;max-width:53ch;color:var(--ink-2)}
.dem-ok-suite{margin-top:16px}
.dem-mail{background:var(--bg);border:1px solid var(--line-2);border-radius:var(--r);padding:22px 24px}
.dem-mail h2{font-size:1.12rem;margin-bottom:8px}
.dem-mail p{font-size:.94rem;margin-bottom:10px;max-width:53ch}
.dem-mail-secours{color:var(--muted)}
.dem-mail a{text-decoration:underline}
@media (max-width:620px){
  .dem{padding:20px 18px}
  .dem-champ,.dem-champ.dem-court{flex-basis:100%}
  .dem-envoi .btn{width:100%}
  .dem-ok{flex-direction:column;gap:12px}
}

/* ==================== mascotte : le robot Reliatech ==================== */
/* Avatar rond « vivant » : image de base + calque yeux fermés (clignement JS).
   Les transitions n'animent QUE transform/opacity : aucune reflow, CSP intacte. */
/* Rely est peint en bleu marine (#1e2f5e) sur un fond marine cuit dans l'image
   (#1b2944) : 1,31:1, il se fond dans son propre disque. En attendant une image
   detouree, un anneau blanc franc lui redonne au moins une silhouette nette sur
   la page pale, au lieu d'une tache sombre aux bords flous. */
.masc-avatar{position:relative;display:inline-block;flex:none;border-radius:50%;overflow:hidden;box-shadow:0 0 0 2px #fff,0 0 0 3px var(--line-2),var(--shadow-sm);background:var(--blue-deep)}
.masc-avatar img{display:block;width:100%;height:100%;object-fit:cover}
.masc-avatar .masc-cligne{position:absolute;inset:0;opacity:0;transition:opacity .07s linear}
.masc-avatar.cligne .masc-cligne{opacity:1}
.masc-a44{width:44px;height:44px}
.masc-a56{width:56px;height:56px}
.masc-a64{width:64px;height:64px}
.masc-a80{width:80px;height:80px}

/* respiration : flottement très léger, réservé aux présences « ambiantes » */
@keyframes masc-flotte{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
.masc-idle{animation:masc-flotte 5.4s ease-in-out infinite}

/* bulle de dialogue : c'est LUI qui parle */
.masc-dial{display:flex;gap:14px;align-items:flex-start}
/* La bulle etait en --blue-soft (#eef1fb) sur un fond de page #f7f8fc : 1,06:1 de
   contraste, autrement dit invisible. Fond blanc + contour : la bulle se lit enfin
   comme une bulle, et Rely se detache de ce qu'il dit. */
.masc-bulle{position:relative;background:#fff;border:1px solid var(--line-2);border-radius:14px;padding:12px 16px;flex:1;min-width:0;box-shadow:var(--shadow-sm)}
.masc-bulle::before{content:"";position:absolute;left:-7px;top:20px;width:12px;height:12px;background:#fff;border-left:1px solid var(--line-2);border-bottom:1px solid var(--line-2);transform:rotate(45deg);border-radius:0 0 0 3px}
.masc-bulle p{margin:0}

/* ----- bouton flottant (futur bot IA : il en portera l'identité) ----- */
.masc-fab{position:fixed;right:18px;bottom:18px;z-index:var(--z-barre);width:58px;height:58px;padding:0;border:0;border-radius:50%;background:var(--blue-deep);cursor:pointer;box-shadow:0 2px 6px rgba(16,22,79,.2),0 10px 26px rgba(16,22,79,.3);transition:transform var(--t-moyen) var(--ease-out),box-shadow var(--t-moyen) var(--ease)}
.masc-fab:hover{transform:translateY(-2px);box-shadow:0 4px 10px rgba(16,22,79,.22),0 16px 34px rgba(16,22,79,.34)}
.masc-fab:active{transform:translateY(0) scale(.97)}
.masc-fab .masc-fab-visage{width:100%;height:100%;box-shadow:inset 0 0 0 2px rgba(255,255,255,.22)}
@keyframes masc-hop{0%{transform:translateY(0)}38%{transform:translateY(-9px)}62%{transform:translateY(-9px) scale(1.03)}100%{transform:translateY(0)}}
.masc-fab.hop{animation:masc-hop .5s var(--ease-out)}
body.cmp-bar-on .masc-fab{bottom:92px}
body.modal-ouvert .masc-fab{visibility:hidden}

.masc-panneau{position:fixed;right:18px;bottom:88px;z-index:var(--z-barre);width:min(330px,calc(100vw - 36px));background:#fff;border:1px solid var(--line);border-radius:18px;padding:18px 18px 16px;box-shadow:var(--shadow-lg);opacity:0;transform:translateY(10px) scale(.98);transition:opacity var(--t-moyen) var(--ease-out),transform var(--t-moyen) var(--ease-out)}
.masc-panneau.on{opacity:1;transform:none}
.masc-panneau-haut{display:flex;gap:12px;align-items:center;margin-bottom:12px}
.masc-panneau-nom{font-weight:800;font-size:.98rem}
.masc-panneau-role{color:var(--muted);font-size:.8rem}
.masc-panneau-txt{font-size:.9rem;color:var(--ink-2);background:var(--blue-soft);border-radius:12px;padding:11px 14px;margin-bottom:12px;text-wrap:pretty}
.masc-panneau-cta{display:block;width:100%}
.masc-panneau-note{margin-top:10px;font-size:.78rem;color:var(--muted);text-wrap:pretty}

/* ==================================================================
   RELY CONSEILLER — la conversation dans le panneau (29/07)
   Le panneau ne fait plus 330 px de large avec un bouton : il porte un fil de
   discussion. Il grandit donc, et se cale en hauteur sur le viewport plutot que
   sur son contenu — sinon une conversation de dix messages sort de l'ecran par
   le haut, sous l'en-tete, et on ne peut plus la remonter.
   Sur telephone il prend toute la largeur utile : un fil de discussion dans
   294 px est illisible.
   ================================================================== */
.masc-panneau--chat{width:min(392px,calc(100vw - 24px));padding:16px 16px 14px;
  display:flex;flex-direction:column;max-height:min(620px,calc(100vh - 130px))}
.rely-fil{flex:1;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:9px;
  padding:2px 2px 6px;margin:2px -2px 10px;scrollbar-width:thin}
.rely-msg{max-width:88%;font-size:.89rem;line-height:1.45}
.rely-msg p{text-wrap:pretty}
.rely-bot{align-self:flex-start;background:var(--blue-soft);color:var(--ink-2);
  border-radius:14px 14px 14px 5px;padding:10px 13px}
.rely-moi{align-self:flex-end;background:var(--blue);color:#fff;
  border-radius:14px 14px 5px 14px;padding:10px 13px}

/* Les puces de reponse rapide : de vrais boutons, donc atteignables au clavier. */
.rely-puces{display:flex;flex-wrap:wrap;gap:6px;margin:1px 0 2px}
.rely-puce{font:inherit;font-size:.82rem;font-weight:600;cursor:pointer;
  padding:7px 13px;min-height:34px;border-radius:999px;border:1px solid var(--line-2);
  background:#fff;color:var(--blue);touch-action:manipulation;
  transition:background var(--t-court) var(--ease),border-color var(--t-court) var(--ease)}
.rely-puce:hover{background:var(--blue-soft);border-color:var(--blue)}

/* Une proposition de produit est un LIEN vers la fiche : le prix affiche vient
   du catalogue public, jamais d'un texte ecrit a la main. */
.rely-prods{display:flex;flex-direction:column;gap:7px}
.rely-prod{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);
  border-radius:11px;padding:8px 10px;color:var(--ink);
  transition:border-color var(--t-court) var(--ease),box-shadow var(--t-court) var(--ease)}
.rely-prod:hover{border-color:var(--blue);box-shadow:var(--shadow-sm)}
.rely-prod img{width:44px;height:44px;object-fit:contain;flex:none}
.rely-prod-txt{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.rely-prod-txt strong{font-size:.85rem;line-height:1.25}
.rely-prod-tech{font-size:.76rem;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rely-prod-prix{font-weight:800;font-size:.86rem;color:var(--blue);white-space:nowrap;flex:none;
  font-variant-numeric:tabular-nums}

/* La barre de saisie reste collee en bas, hors du fil qui defile. */
.rely-bas{display:flex;gap:7px;align-items:center}
.rely-saisie{flex:1;min-width:0;font:inherit;font-size:.88rem;padding:10px 13px;min-height:42px;
  border:1px solid var(--line-2);border-radius:999px;background:#fff;color:var(--ink)}
.rely-saisie:focus{border-color:var(--blue);outline:none;box-shadow:0 0 0 3px rgba(23,31,120,.14)}
.rely-go{flex:none;width:42px;height:42px;border-radius:50%;border:0;cursor:pointer;
  background:var(--blue);color:#fff;font-size:1.05rem;font-weight:700;line-height:1;
  touch-action:manipulation;transition:background var(--t-court) var(--ease)}
.rely-go:hover{background:var(--blue-hover)}

/* Formulaire de passage a un humain. */
.rely-form{display:flex;flex-direction:column;gap:8px;width:100%}
.rely-lab{display:flex;flex-direction:column;gap:3px;font-size:.79rem;font-weight:700;color:var(--ink-2)}
.rely-in{font:inherit;font-size:.86rem;padding:9px 11px;min-height:40px;border:1px solid var(--line-2);
  border-radius:9px;background:#fff;color:var(--ink);width:100%}
.rely-in:focus{border-color:var(--blue);outline:none;box-shadow:0 0 0 3px rgba(23,31,120,.14)}
.rely-ta{min-height:66px;resize:vertical}
/* Champ piege : hors du flux ET hors du parcours clavier. `display:none` le
   rendrait invisible aux robots aussi, ce qui le priverait de son role. */
.rely-piege{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
.rely-envoi{width:100%;margin-top:2px}
.rely-etat{font-size:.79rem;color:var(--muted);min-height:1em}
.rely-etat.rely-ko{color:#B3261E;font-weight:600}
.rely-cnil{font-size:.72rem;color:var(--muted);text-wrap:pretty}

@media (max-width:560px){
  .masc-panneau--chat{width:calc(100vw - 20px);right:10px;bottom:80px;
    max-height:min(70vh,calc(100vh - 120px))}
  .rely-msg{max-width:92%;font-size:.87rem}
}
.masc-panneau-fermer{position:absolute;top:8px;right:8px;width:36px;height:36px;border:0;background:none;color:var(--muted);font-size:1.4rem;line-height:1;cursor:pointer;border-radius:50%;transition:background var(--t-court) var(--ease),color var(--t-court) var(--ease)}
.masc-panneau-fermer:hover{background:var(--blue-soft);color:var(--blue)}

/* ----- « coucou » ambiant : il jette un œil depuis le coin bas gauche ----- */
.masc-peek{position:fixed;left:16px;bottom:0;z-index:var(--z-barre);pointer-events:none}
.masc-peek-img{width:150px;height:auto;display:block;transform:translateY(105%);transition:transform .55s var(--ease-out)}
.masc-peek.on .masc-peek-img{transform:translateY(16%)}
/* 🚨 La place de la croix est RÉSERVÉE dans la bulle, elle n'est pas posée par-dessus.
   Elle était ancrée à top:-8px / right:-10px, ce qui la sortait du cadre — sauf sur
   écran tactile, où la règle d'accessibilité l'agrandit à 44×44 px : elle retombait
   alors DANS la bulle et masquait le début de la phrase de Rely (signalé par Samuel
   le 07/08, page d'accueil sur téléphone). Un bouton dont la taille dépend du
   pointeur ne peut pas être positionné en débord : il faut lui garder sa place. */
.masc-peek-bulle{position:relative;pointer-events:auto;background:#fff;border:1px solid var(--line);border-radius:14px;padding:10px 14px;padding-right:34px;margin:0 0 10px 34px;max-width:240px;box-shadow:var(--shadow);font-size:.85rem;color:var(--ink-2);opacity:0;transform:translateY(6px);transition:opacity .4s var(--ease-out) .25s,transform .4s var(--ease-out) .25s}
.masc-peek.on .masc-peek-bulle{opacity:1;transform:none}
.masc-peek-bulle::after{content:"";position:absolute;left:26px;bottom:-6px;width:12px;height:12px;background:#fff;border-right:1px solid var(--line);border-bottom:1px solid var(--line);transform:rotate(45deg)}
.masc-peek-bulle p{margin:0 0 6px}
.masc-peek-off{border:0;background:none;padding:0;color:var(--muted);font:inherit;font-size:.76rem;text-decoration:underline;cursor:pointer}
.masc-peek-off:hover{color:var(--danger)}
/* La cible tactile fait 44 px, le DESSIN en fait 20. C'est la bonne façon de tenir
   les deux exigences à la fois : le doigt vise large, l'œil voit un détail discret.
   Sans fond ni bordure, la croix ne concurrence plus la phrase de Rely ; elle
   s'affirme seulement au survol et au focus, quand on la cherche vraiment. */
.masc-peek-fermer{position:absolute;top:0;right:0;pointer-events:auto;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border:0;background:none;color:var(--muted);font-size:1.05rem;line-height:1;cursor:pointer;border-radius:50%;opacity:0;transition:opacity .3s var(--ease) .3s,background var(--t-court) var(--ease),color var(--t-court) var(--ease)}
.masc-peek-fermer:hover,.masc-peek-fermer:focus-visible{background:var(--blue-soft);color:var(--ink)}
.masc-peek.on .masc-peek-fermer{opacity:1}
.masc-peek-fermer:hover{color:var(--danger)}
@media (max-width:560px){.masc-peek-img{width:118px}.masc-peek-bulle{max-width:200px;margin-left:22px}}

/* ----- il vit aussi dans les pages ----- */
/* panier vide */
.panier-vide-masc{display:flex;gap:22px;align-items:center}
.panier-vide-masc>img{width:120px;height:auto;flex:none}
@media (max-width:560px){.panier-vide-masc{gap:14px}.panier-vide-masc>img{width:86px}}
/* jauge livraison offerte : c'est lui qui encourage */
.recap-seuil-masc{display:flex;gap:10px;align-items:flex-start}
.recap-seuil-masc .masc-avatar{margin-top:2px}
.recap-seuil-masc>div{flex:1;min-width:0}
/* popup « on complète le poste ? » : il en est le messager */
.modal-masc{display:flex;gap:14px;align-items:flex-start}
.modal-masc>.masc-avatar{margin-top:4px}
.modal-masc>div{flex:1;min-width:0}
/* 404 et états vides */
.notfound-masc{display:flex;gap:26px;align-items:center;margin:26px 0 6px}
.notfound-masc>img{width:150px;height:auto;flex:none}
.notfound-masc-bulle{font-size:1.02rem;color:var(--ink-2);max-width:46ch;text-wrap:pretty}
@media (max-width:560px){.notfound-masc{gap:16px}.notfound-masc>img{width:104px}}
.empty-masc{display:flex;gap:14px;align-items:center;background:#fff;border:1px dashed var(--line-strong);border-radius:var(--r);padding:18px 20px;margin:10px 0;color:var(--muted);max-width:53ch}
.empty-masc p{margin:0}
.empty-masc a{text-decoration:underline;font-weight:700}
/* conseiller : sa page */
.conseil-masc{display:flex;gap:16px;align-items:flex-start;margin:20px 0 26px;max-width:860px}
.conseil-masc .masc-bulle{font-size:.98rem;color:var(--ink-2)}
.q .masc-dial{margin-bottom:16px}
.q .masc-bulle .q-t{margin-top:2px}
.q .masc-bulle .q-aide{margin:6px 0 0;font-size:.88rem;color:var(--muted)}
.res-haut-masc{display:flex;gap:16px;align-items:center}
.res-haut-masc .masc-avatar{box-shadow:inset 0 0 0 2px rgba(255,255,255,.3)}
.res-haut-masc>div{flex:1;min-width:0}
.upsell-masc{display:flex;gap:10px;align-items:center;margin:24px 0 -6px;font-weight:700;font-size:.95rem;color:var(--ink-2)}
.res-rien-masc{display:flex;gap:16px;align-items:flex-start}
.res-rien-masc>div{flex:1;min-width:0}

/* bulle de réaction du bouton flottant : Rely commente, sans jamais bloquer
   (pointer-events:none : elle ne capte ni clic ni focus, et s'ignore d'un scroll) */
.masc-fab-bulle{position:fixed;right:24px;bottom:88px;z-index:var(--z-barre);max-width:min(300px,calc(100vw - 48px));background:#fff;border:1px solid var(--line);border-radius:14px;padding:10px 14px;box-shadow:var(--shadow-lg);font-size:.88rem;color:var(--ink-2);pointer-events:none;opacity:0;transform:translateY(8px);transition:opacity .35s var(--ease-out),transform .35s var(--ease-out)}
.masc-fab-bulle.on{opacity:1;transform:none}
.masc-fab-bulle::after{content:"";position:absolute;right:22px;bottom:-6px;width:12px;height:12px;background:#fff;border-right:1px solid var(--line);border-bottom:1px solid var(--line);transform:rotate(45deg)}
.masc-fab-bulle p{margin:0}
body.cmp-bar-on .masc-fab-bulle{bottom:162px}
body.modal-ouvert .masc-fab-bulle{visibility:hidden}

/* l'avis de Rely au comparateur : uniquement quand un produit gagne ou égale
   TOUTES les lignes objectivement comparables (sinon, il se tait) */
.cmp-verdict{margin:16px 0 4px;max-width:680px}
.cmp-verdict-note{margin-top:6px;font-size:.78rem;color:var(--muted);text-wrap:pretty}

/* réglage « Assistant Rely » : lien discret du pied de page + option du panneau */
.foot-rely{border:0;background:none;padding:0;margin-left:10px;color:inherit;font:inherit;text-decoration:underline;cursor:pointer;opacity:.85}
.foot-rely:hover{opacity:1}
.masc-panneau-off{display:block;margin-top:10px;border:0;background:none;padding:0;color:var(--muted);font:inherit;font-size:.78rem;text-decoration:underline;cursor:pointer}
.masc-panneau-off:hover{color:var(--danger)}

/* assistant désactivé (localStorage RT_MASC_OFF) : plus AUCUNE apparition ni
   animation ; Rely ne subsiste qu'en statique là où il porte une fonction
   (la page conseiller, qui ne reçoit jamais cette classe) */
body.masc-off .masc-fab,body.masc-off .masc-peek,body.masc-off .masc-fab-bulle{display:none}
body.masc-off .masc-avatar,body.masc-off .panier-vide-masc>img,body.masc-off .notfound-masc>img{display:none}
body.masc-off .masc-idle{animation:none}
body.masc-off .cmp-verdict{display:none}
body.masc-off .masc-dial .masc-bulle::before{display:none}

/* motion réduite */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition:none !important;animation:none !important}
  html{scroll-behavior:auto}
  /* la mascotte devient sage : tout est statique, rien ne flotte ni ne cligne */
  .masc-peek .masc-peek-img{transform:translateY(16%)}
  .masc-peek{display:none}
  .masc-peek.on{display:block}
}

/* ==================== espace client ==================== */
/* Lien du header : même famille que le lien panier, en version discrète. */
.compte-lien{display:flex;align-items:center;gap:8px;padding:9px 13px;border-radius:var(--r-sm);font-weight:700;font-size:.93rem;color:var(--ink);border:1px solid transparent;transition:background var(--t-court) var(--ease),color var(--t-court) var(--ease),border-color var(--t-court) var(--ease)}
.compte-lien:hover{background:var(--blue-soft);color:var(--blue)}
.compte-lien.on{background:var(--blue);color:#fff}
@media (max-width:1050px){
  .compte-lib{display:none}
  .compte-lien{padding:9px 11px}
}

/* ----- panneau « Ouverture prochaine » (état honnête par défaut) ----- */
.cc-attente-in{display:flex;gap:30px;align-items:center;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:30px 34px;box-shadow:var(--shadow-sm);margin:8px 0 10px}
.cc-attente-in>img{width:150px;height:auto;flex:none}
.cc-attente-badge{display:inline-block;background:var(--blue-soft);color:var(--blue);font-weight:800;font-size:.74rem;letter-spacing:.07em;text-transform:uppercase;border-radius:8px;padding:5px 11px;margin-bottom:10px}
.cc-attente h2{font-size:1.32rem;margin-bottom:8px}
.cc-attente-txt{color:var(--ink-2);max-width:50ch;text-wrap:pretty}
.cc-points{list-style:none;padding:0;margin:16px 0;display:grid;gap:8px}
.cc-points li{position:relative;padding-left:25px;font-size:.93rem;text-wrap:pretty}
.cc-points li::before{content:"✓";position:absolute;left:2px;color:var(--vert);font-weight:800}
.cc-attente-note{color:var(--muted);font-size:.88rem}
.cc-attente-note a{font-weight:700;text-decoration:underline}
@media (max-width:700px){
  .cc-attente-in{flex-direction:column;align-items:flex-start;gap:16px;padding:22px 18px}
  .cc-attente-in>img{width:104px}
}

/* ----- bandeau et badges du mode Aperçu (données fictives) ----- */
.cc-demo-bandeau{display:flex;gap:14px;align-items:flex-start;background:#EAF1FE;border:1.5px solid #BFD8FB;border-radius:var(--r);padding:16px 18px;margin:22px 0 6px}
.cc-demo-bandeau p{font-size:.92rem;color:#6b2d17;text-wrap:pretty;margin:2px 0 0}
.cc-demo-badge{flex:none;background:var(--blue-clair);color:#fff;font-weight:800;font-size:.76rem;letter-spacing:.06em;text-transform:uppercase;border-radius:8px;padding:6px 12px}
.cc-badge-ex{display:inline-block;background:#EAF1FE;color:var(--accent-txt);border:1px solid #BFD8FB;border-radius:6px;font-size:.66rem;font-weight:800;letter-spacing:.05em;text-transform:uppercase;padding:2px 7px;margin-left:9px;vertical-align:2px}
.cc-demo-corps{margin-bottom:26px}

/* ----- connexion par lien magique ----- */
.cc-login{max-width:600px}
.cc-login-form{display:flex;flex-direction:column;gap:14px;margin:18px 0 4px}
.cc-login-form label{font-weight:700;font-size:.9rem;display:flex;flex-direction:column;gap:6px}
.cc-login-form input{padding:12px 14px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;color:var(--ink)}
.cc-login-form input::placeholder{color:var(--muted)}
.cc-login-note{color:var(--muted);font-size:.83rem;margin-top:14px;text-wrap:pretty}
.cc-login-note a{text-decoration:underline}
.cc-info{background:var(--blue-soft);border:1px solid var(--blue-soft2);color:var(--ink-2);border-radius:var(--r-sm);padding:11px 14px;font-size:.88rem;font-weight:600;margin:14px 0 0}
.cc-login .form-erreur{margin-top:12px}
.cc-login .form-ok{margin:14px 0 0;padding:18px 20px}
.cc-login .form-ok h3{color:#157347;font-size:1.05rem;margin-bottom:6px}

/* ----- entête de l'application (bonjour + déconnexion) ----- */
.cc-app-tete{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;margin:20px 0 2px}
.cc-bonjour{display:flex;gap:12px;align-items:center;font-size:1.02rem}
.cc-bonjour-sous{display:block;color:var(--muted);font-size:.86rem}
.cc-deco{background:none;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;font-size:.85rem;font-weight:600;color:var(--muted);padding:10px 16px;min-height:44px;cursor:pointer;transition:border-color var(--t-court) var(--ease),color var(--t-court) var(--ease)}
.cc-deco:hover{border-color:var(--danger);color:var(--danger)}

/* ----- onglets ----- */
.cc-tabs{display:flex;gap:4px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin:16px 0 22px}
.cc-tab{font:inherit;font-weight:700;font-size:.92rem;background:none;border:0;border-bottom:3px solid transparent;padding:12px 15px;min-height:44px;color:var(--muted);cursor:pointer;border-radius:var(--r-sm) var(--r-sm) 0 0;transition:color var(--t-court) var(--ease),background var(--t-court) var(--ease),border-color var(--t-court) var(--ease)}
.cc-tab:hover{color:var(--blue);background:var(--blue-soft)}
.cc-tab.on{color:var(--blue);border-bottom-color:var(--blue)}
.cc-panel{margin-bottom:36px}

/* ----- cartes et contenus ----- */
.cc-carte{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:20px 24px;box-shadow:var(--shadow-sm);margin-bottom:14px}
.cc-carte-h{font-size:1.05rem;margin-bottom:12px}
.cc-sous-titre{font-size:1.05rem;margin:26px 0 12px}
.cc-intro{color:var(--muted);font-size:.9rem;max-width:56ch;margin-bottom:16px;text-wrap:pretty}
.cc-vide{background:#fff;border:1px dashed var(--line-strong);border-radius:var(--r);padding:26px 24px;max-width:53ch}
.cc-vide-h{font-weight:800;margin-bottom:6px}
.cc-vide p{color:var(--muted);text-wrap:pretty}
.cc-vide a{font-weight:700;text-decoration:underline}
.cc-chargement{color:var(--muted);padding:18px 0}

/* tuiles du tableau de bord */
.cc-tuiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:8px}
.cc-tuile{font:inherit;text-align:left;display:flex;flex-direction:column;gap:2px;background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:16px 18px;min-height:44px;cursor:pointer;box-shadow:var(--shadow-sm);transition:border-color var(--t-court) var(--ease),box-shadow var(--t-court) var(--ease),transform var(--t-court) var(--ease)}
.cc-tuile:hover{border-color:var(--blue);box-shadow:var(--shadow);transform:translateY(-1px)}
.cc-tuile strong{font-size:1.75rem;font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.cc-tuile span{color:var(--muted);font-size:.86rem}

/* carte commande */
.cc-cmd-tete{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;flex-wrap:wrap}
.cc-cmd-ref{font-size:1rem}
.cc-cmd-date{color:var(--muted);font-size:.85rem;margin-top:2px}
.cc-cmd-tete-droite{display:flex;flex-direction:column;gap:5px;align-items:flex-end;text-align:right}
.cc-cmd-total{font-weight:800;color:var(--blue);font-variant-numeric:tabular-nums}
.cc-cmd-suivi{font-size:.88rem;color:var(--ink-2);margin:2px 0 0}
.cc-cmd-suivi a{font-weight:700;text-decoration:underline}
.cc-cmd-note{font-size:.88rem;color:var(--muted);background:var(--blue-soft);border-radius:var(--r-sm);padding:10px 13px;margin-top:10px}
.cc-cmd-lignes{list-style:none;padding:12px 0 0;margin:12px 0 0;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:6px}
.cc-cmd-lignes li{display:flex;justify-content:space-between;gap:14px;font-size:.9rem}
.cc-l-des{min-width:0}
.cc-l-prix{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}

/* badges de statut */
.cc-statut{display:inline-block;font-size:.75rem;font-weight:800;border-radius:8px;padding:4px 10px;letter-spacing:.02em}
.cc-statut-recue{background:var(--blue-soft);color:var(--blue)}
.cc-statut-confirmee{background:var(--blue);color:#fff}
.cc-statut-expediee{background:#EAF1FE;color:var(--accent-txt)}
.cc-statut-livree{background:var(--vert-fond);color:var(--vert)}
.cc-statut-annulee{background:#eef0f6;color:var(--muted)}
.cc-statut-devis-envoye{background:var(--blue-soft);color:var(--blue)}
.cc-statut-devis-accepte{background:var(--vert-fond);color:var(--vert)}
.cc-statut-devis-refuse,.cc-statut-devis-expire{background:#eef0f6;color:var(--muted)}

/* frise d'avancement d'une commande */
.cc-etapes{list-style:none;display:flex;padding:0;margin:18px 0 4px}
.cc-etape{flex:1;position:relative;text-align:center;font-size:.78rem;color:var(--muted)}
.cc-etape+.cc-etape::before{content:"";position:absolute;top:8px;right:50%;width:100%;height:3px;background:var(--line-2)}
.cc-etape.fait+.cc-etape::before{background:var(--vert)}
.cc-etape-point{position:relative;z-index:1;display:block;width:19px;height:19px;margin:0 auto 6px;border-radius:50%;background:#fff;border:3px solid var(--line-2)}
.cc-etape.fait .cc-etape-point{background:var(--vert);border-color:var(--vert)}
.cc-etape.encours .cc-etape-point{border-color:var(--blue);background:var(--blue-soft)}
.cc-etape.fait{color:var(--vert)}
.cc-etape.encours{color:var(--blue);font-weight:800}
.cc-etape-annulee{text-align:left;color:var(--muted);font-weight:700;font-size:.88rem}
@media (max-width:560px){.cc-etape{font-size:.66rem}.cc-etape-point{width:15px;height:15px}}

/* factures */
.cc-fact-liste{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:10px}
.cc-fact{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);padding:14px 18px;box-shadow:var(--shadow-sm)}
.cc-fact-num{font-size:.95rem}
.cc-fact-meta{color:var(--muted);font-size:.84rem;margin-top:2px}
.cc-fact-btn{padding:10px 16px;font-size:.88rem;min-height:44px}

/* devis */
.cc-devis-v{color:var(--muted);font-weight:600;font-size:.82rem;margin-left:8px}
.cc-devis-versions{margin-top:10px}
.cc-devis-versions summary{cursor:pointer;font-weight:600;font-size:.86rem;color:var(--muted);min-height:44px;display:flex;align-items:center}
.cc-devis-versions summary:hover{color:var(--blue)}
.cc-devis-versions ul{list-style:none;padding:4px 0 0;margin:0;color:var(--muted);font-size:.85rem;display:flex;flex-direction:column;gap:4px}

/* mon compte */
.cc-form{display:flex;flex-direction:column;align-items:stretch}
.cc-form label{font-weight:700;font-size:.9rem;display:flex;flex-direction:column;gap:6px}
.cc-form input[type=text],.cc-form input[type=tel],.cc-form input[type=email]{padding:11px 14px;border:1px solid var(--line-strong);border-radius:var(--r-sm);font:inherit;color:var(--ink);width:100%}
.cc-duo{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;margin-bottom:2px}
.cc-duo>label,.cc-duo>fieldset{min-width:0}
.cc-form .cc-carte>label{margin-top:12px}
.cc-email{color:var(--muted);font-size:.9rem;margin-bottom:14px}
.cc-adresse{border:1px solid var(--line);border-radius:var(--r-sm);padding:14px 16px 16px;display:flex;flex-direction:column;gap:12px;min-width:0;margin:0}
.cc-adresse legend{font-weight:800;font-size:.92rem;padding:0 6px}
.cc-pref{display:flex;gap:12px;align-items:flex-start;padding:9px 0;cursor:pointer;font-weight:400}
.cc-pref input{width:19px;height:19px;accent-color:var(--blue);margin-top:2px;flex:none;cursor:pointer}
.cc-pref-aide{display:block;color:var(--muted);font-size:.83rem}
.cc-ok{background:var(--vert-fond);border:1px solid #b7dfc9;color:var(--vert);border-radius:var(--r-sm);padding:11px 14px;font-size:.9rem;font-weight:700;margin-bottom:12px}
.cc-form>.btn{align-self:flex-start}

/* zone de suppression RGPD */
.cc-danger{border-color:#BFD8FB;margin-top:20px}
.cc-danger p{color:var(--muted);font-size:.9rem;max-width:56ch;margin-bottom:14px;text-wrap:pretty}
.cc-btn-danger{background:#fff;color:#8f3a1f;border:1.5px solid #d97a54}
.cc-btn-danger:hover{background:#EAF1FE;border-color:#8f3a1f}
.cc-danger-confirm p{color:#8f3a1f;font-weight:700}
.cc-danger-actions{display:flex;gap:12px;flex-wrap:wrap}
@media (max-width:560px){
  .cc-carte{padding:16px}
  .cc-cmd-tete-droite{align-items:flex-start;text-align:left}
  .cc-fact-btn{flex:1 1 100%}
  .cc-danger-actions .btn{flex:1 1 100%}
  .cc-tabs{gap:0}
  .cc-tab{padding:12px 10px;font-size:.85rem}
}

/* En-tête de section avec action à droite (accueil : meilleures remises).
   La colonne texte reste prioritaire ; le bouton passe dessous en mobile. */
.sec-tete{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap}
.sec-tete .sec-h{margin-bottom:0}
.sec-tete .sub{margin-bottom:0}
.sec-tete-cta{flex:0 0 auto;margin-bottom:4px}
@media (max-width:640px){
  .sec-tete{align-items:stretch}
  .sec-tete-cta{width:100%;text-align:center}
}

/* Étiquette énergie (règlement UE 2017/1369) : classe A à G + lien EPREL.
   Codes couleur proches de l'étiquette officielle, contraste vérifié sur blanc. */
.nrj-bloc{margin-top:28px}
.nrj-ligne{display:flex;align-items:flex-start;gap:14px;margin:0 0 10px}
.nrj-classe{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;height:36px;padding:0 12px;border-radius:6px;
  font-weight:800;font-size:1.15rem;color:#fff;letter-spacing:.02em}
.nrj-a,.nrj-b{background:#0d7a3d}
.nrj-c{background:#4d9a1f}
.nrj-d{background:#b39000}
.nrj-e{background:#c26a00}
.nrj-f{background:#c74e00}
.nrj-g{background:#a81f1f}
.nrj-txt{color:var(--ink);text-wrap:pretty}
.nrj-lien{margin:0}
.nrj-lien a{color:var(--navy);text-underline-offset:3px}
@media (max-width:520px){
  .nrj-ligne{flex-direction:column;gap:8px}
}

/* ---------- filet de securite : masquage lecteur d'ecran ----------
   Une regle declaree plus bas dans ce fichier avec la meme specificite peut
   reprendre la main sur .sr-only et rendre un element invisible... large de
   toute la page. C'est exactement ce qui est arrive au libelle des questions
   du conseiller (defilement horizontal sur mobile, 27/07/2026).
   Cette re-affirmation en fin de feuille, de specificite superieure, verrouille
   le comportement quoi qu'on ajoute au-dessus. */
.sr-only:not(:focus):not(:active){
  position:absolute;width:1px;height:1px;max-width:1px;max-height:1px;
  padding:0;margin:-1px;overflow:hidden;white-space:nowrap;border:0;
  clip:rect(0 0 0 0);clip-path:inset(50%)
}

/* ---------- encadres des pages legales ----------
   Ces blocs utilisaient des attributs style="" en ligne, que la CSP du site
   (style-src 'self', sans 'unsafe-inline') bloque : ils s'affichaient donc sans
   aucune mise en forme en production, dont le bloc du mediateur de la
   consommation. Une classe passe la CSP, un attribut style ne passe jamais. */
.legal-encadre{background:#f8fafc;border:1px solid #dbe3f5;border-radius:12px;padding:16px 18px;margin-top:12px}
.legal-preforme{white-space:pre-line}

/* Classe energie sur les cartes de liste : obligatoire a proximite du prix en
   vente a distance (reglement delegue UE 2019/2013 annexe VIII). Discret mais
   toujours present, y compris sur mobile ou la carte est en ligne. */
.card-nrj{display:flex;align-items:center;gap:7px;margin:4px 0 0}
.card-nrj .nrj-classe{width:22px;height:22px;font-size:.78rem;border-radius:5px}
.card-nrj-txt{color:var(--muted);font-size:.76rem;font-weight:600}

/* ---------- bascule d'affichage de la liste (Liste · Grille · Compact) ---------- */
.vue-bascule{display:flex;gap:6px;margin:0 0 14px;padding:4px;background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);width:fit-content}
.vue-btn{appearance:none;border:0;background:transparent;color:var(--muted);font:inherit;font-size:.85rem;font-weight:700;
  padding:8px 14px;min-height:40px;border-radius:8px;cursor:pointer;transition:background .16s var(--ease),color .16s var(--ease)}
.vue-btn:hover{color:var(--blue)}
.vue-btn.on{background:var(--blue);color:#fff}

/* Grille : deux colonnes, pour balayer visuellement. */
/* « Grille » doit VRAIMENT differer de « Liste ». Les deux rendaient exactement
   la meme chose au-dessus de 560 px : meme grille, meme carte. La grille est
   maintenant plus dense (vignettes plus petites, plus de colonnes), la liste
   reste le mode confortable. */
.grid.vue-grille{grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:12px}
.grid.vue-grille .card-media{height:150px;padding:12px}
.grid.vue-grille .card-body{padding:10px 12px 12px}
.grid.vue-grille .card-title{font-size:.86rem}
.grid.vue-grille .card-tech{font-size:.77rem}
.grid.vue-grille .card-price strong{font-size:1.05rem}
.grid.vue-grille .card-actions{flex-direction:column;gap:6px}
.grid.vue-grille .card-actions>*{width:100%}

/* Compact : sans photo, dense. Sur du materiel informatique les photos se
   ressemblent toutes ; ce qui decide, c'est la ligne technique et le prix.
   On passe de 4 a une dizaine de produits visibles par ecran. */
.grid.vue-compact{grid-template-columns:1fr;gap:0}
.grid.vue-compact .card-slot{border-bottom:1px solid var(--line)}
.grid.vue-compact .card{flex-direction:row;align-items:center;border:0;border-radius:0;box-shadow:none;background:transparent;padding:12px 2px;gap:12px}
.grid.vue-compact .card:hover{box-shadow:none;border-color:transparent;background:var(--blue-soft)}
.grid.vue-compact .card-media{display:none}
.grid.vue-compact .card-body{border-top:0;padding:0;flex:1;min-width:0;gap:1px}
.grid.vue-compact .card-brand{font-size:.68rem}
.grid.vue-compact .card-title{font-size:.9rem;line-height:1.25}
.grid.vue-compact .card-tech{font-size:.78rem}
.grid.vue-compact .card-price{margin:2px 0 0}
.grid.vue-compact .card-price strong{font-size:1.02rem}
.grid.vue-compact .card-nrj{margin:2px 0 0}
.grid.vue-compact .card-actions{padding-bottom:10px}

@media (max-width:560px){
  /* En mode grille sur telephone on assume les 2 colonnes : c'est un choix
     explicite du visiteur, pas la valeur par defaut qu'on lui impose. */
  .grid.vue-grille{grid-template-columns:repeat(2,1fr);gap:12px}
  .grid.vue-grille .card{flex-direction:column}
  .grid.vue-grille .card-media{width:auto;min-height:0;height:130px;border-right:0}
  .grid.vue-grille .card-body{border-top:1px solid var(--line);padding:10px 12px 12px}
  .grid.vue-grille .card-title{font-size:.85rem}
  .grid.vue-grille .card-tech{font-size:.76rem}
  .grid.vue-grille .card-actions{flex-direction:column}
}


/* iOS Safari zoome automatiquement sur un champ dont la police est sous 16 px.
   Tous nos champs heritaient de 14,4 px : la page sautait a chaque mise au point,
   ce qui rend un formulaire penible a remplir au telephone. */
@media (max-width:820px){
  .order-form input,.order-form textarea,.order-form select,
  .cc-login-form input,.cc-form input,.cc-form textarea,
  .toolbar input,.toolbar select,
  .dem-form input,.dem-form textarea,.dem-form select{font-size:16px}
}

/* ---------- rayons par marque ---------- */
.marques-mur{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:14px;margin:8px 0 32px}
.marque-tuile{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  min-height:112px;padding:18px 14px;background:#fff;border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--shadow-sm);color:var(--ink);text-align:center;
  transition:box-shadow .18s var(--ease),border-color .18s var(--ease),transform .18s var(--ease-out)}
.marque-tuile:hover{box-shadow:var(--shadow);border-color:#c9d0e8;transform:translateY(-2px)}
/* Dimensions EXPLICITES : un SVG sans width/height intrinseques rendu avec
   width:auto s'effondre a 0x0. Les logos etaient invisibles pour cette raison.
   object-fit:contain conserve les proportions dans la boite imposee. */
.marque-tuile img{height:40px;width:auto;max-width:120px;object-fit:contain}
.marque-nom{font-weight:800;font-size:1.05rem;letter-spacing:-.01em;color:var(--blue)}
.marque-compte{font-size:.74rem;font-weight:600;color:var(--muted)}
.marques-autres{display:flex;flex-wrap:wrap;gap:8px;margin:6px 0 30px}
.marques-autres a{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;min-height:40px;
  background:#fff;border:1px solid var(--line);border-radius:999px;font-size:.88rem;font-weight:600;color:var(--ink)}
.marques-autres a:hover{border-color:var(--blue);color:var(--blue)}
.marques-autres a span{color:var(--muted);font-weight:700;font-size:.78rem}
@media (max-width:560px){
  .marques-mur{grid-template-columns:repeat(2,1fr);gap:10px}
  .marque-tuile{min-height:96px;padding:14px 10px}
}

/* ---------- bannieres editoriales (accueil) ----------
   Composition en « bento » : une grande a gauche, deux plus petites a droite.
   Trois blocs de meme taille se lisent comme un menu de plus — c'etait justement
   le reproche fait a l'ancien accueil.
   Le visuel produit est en fond, decale et rogne : il donne la matiere sans
   pretendre etre le sujet. Le texte reste sur un aplat sombre, donc lisible quelle
   que soit la photo. */
.bannieres{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);
  grid-template-areas:"grande pro" "grande deals";gap:16px}
.ban--grande{grid-area:grande}
.ban--pro{grid-area:pro}
.ban--deals{grid-area:deals}
.ban{position:relative;isolation:isolate;overflow:hidden;border-radius:var(--r);
  display:flex;align-items:flex-end;min-height:186px;padding:24px 26px;color:#fff;
  background:linear-gradient(148deg,#141c66,var(--blue-deep) 58%,#0a0e3c);
  box-shadow:0 2px 6px rgba(16,22,79,.1),0 14px 34px rgba(16,22,79,.16);
  transition:box-shadow var(--t-moyen) var(--ease),transform var(--t-moyen) var(--ease)}
.ban:hover{transform:translateY(-4px);box-shadow:0 4px 10px rgba(16,22,79,.14),0 24px 50px rgba(16,22,79,.26)}
.ban--grande{min-height:300px;background:linear-gradient(142deg,#1b2483,#10164f 56%,#2a1a3f)}
.ban--deals{background:linear-gradient(148deg,#3a1e12,#1a1030 62%,#10164f)}
/* Le visuel est pose dans une CARTE BLANCHE inclinee qui deborde du cadre, et non
   pose a nu sur le fond sombre.
   Premiere tentative (29/07) : la photo directement sur le degrade, en
   `mix-blend-mode:screen`. Nos visuels produit sont sur fond BLANC — en fusion
   « screen », un fond blanc reste blanc et mange le produit ; le resultat allait du
   rectangle blanc a l'invisible selon la photo. Detourer 638 visuels n'est pas une
   option, et une photo sur fond blanc collee sur un aplat sombre garde de toute
   facon un halo d'amateur.
   La carte blanche resout les deux : le fond blanc de la photo DEVIENT la carte.
   C'est aussi le langage de la scene du hero, donc le site parle d'une seule voix. */
.ban-fond{position:absolute;z-index:-1;right:-6%;bottom:-22%;width:34%;max-width:146px;
  display:flex;align-items:center;justify-content:center;pointer-events:none;
  background:#fff;border-radius:14px;padding:11px;
  transform:rotate(calc(var(--br,-6deg) + var(--bd,0deg))) translateY(var(--by,0px));
  box-shadow:0 10px 26px rgba(2,5,30,.45),0 30px 60px rgba(2,5,30,.4)}
.ban-fond img{width:100%;height:auto;object-fit:contain}
.ban--grande .ban-fond{width:38%;max-width:244px;right:-5%;bottom:-13%;--br:-7deg;padding:14px;border-radius:16px}
.ban--deals .ban-fond{--br:5deg}
/* Le texte des petites bannieres s'arrete AVANT la carte : sans cette borne, la
   ligne « Remise quantite des 10 unites » passait derriere elle. */
.ban--pro .ban-txt,.ban--deals .ban-txt{max-width:25ch;padding-right:6px}
/* Un voile sombre entre le visuel et le texte : la lisibilite ne doit dependre
   d'aucune photo en particulier. C'est ce qui permet de changer de vignette sans
   rien reverifier. */
.ban::before{content:"";position:absolute;inset:0;z-index:-2;
  background:linear-gradient(88deg,rgba(8,12,52,.9) 30%,rgba(8,12,52,.3) 74%,rgba(8,12,52,0))}
.ban-txt{position:relative;display:flex;flex-direction:column;gap:7px;max-width:31ch}
.ban--grande .ban-txt{max-width:34ch;gap:9px}
.ban-sur{font-size:.75rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:#9fa9f0}
.ban--deals .ban-sur{color:#8FBCFF}
.ban-h{font-size:1.32rem;font-weight:800;line-height:1.12;letter-spacing:-.02em}
.ban--grande .ban-h{font-size:clamp(1.6rem,2.3vw,2.15rem)}
.ban-sous{font-size:.88rem;color:#c3cbf2;text-wrap:pretty}
.ban--grande .ban-sous{font-size:.95rem}
.ban-cta{margin-top:5px;font-weight:700;font-size:.92rem;color:#fff;display:inline-flex;align-items:center;gap:7px}
.ban-cta::after{content:"→";transition:transform var(--t-moyen) var(--ease)}
.ban:hover .ban-cta::after{transform:translateX(4px)}
.ban-sec{margin-bottom:8px}
@media (max-width:860px){
  .bannieres{grid-template-columns:minmax(0,1fr);grid-template-areas:"grande" "pro" "deals";gap:12px}
  .ban{min-height:156px;padding:20px 20px}
  .ban--grande{min-height:224px}
  .ban-txt,.ban--grande .ban-txt{max-width:23ch}
  .ban-fond,.ban--grande .ban-fond{width:40%;max-width:132px;right:-8%;bottom:-16%;padding:10px;border-radius:13px}
  .ban::before{background:linear-gradient(86deg,rgba(8,12,52,.94) 40%,rgba(8,12,52,.5) 84%,rgba(8,12,52,.1))}
}
@media (prefers-reduced-motion:reduce){ .ban:hover .ban-cta::after{transform:none} }

/* ---------- bande de marques defilante (accueil) ----------
   En grille, 39 marques prenaient trois rangees de tuiles identiques pour une
   information qui se lit d'un coup d'oeil. En bande, elles en prennent une, et le
   mouvement dit « il y en a d'autres » mieux qu'un compteur.
   Le masque de bord evite la coupe nette a droite et a gauche : sans lui, la bande
   a l'air cassee plutot qu'infinie. */
.mq{position:relative;overflow:hidden;margin:8px 0 30px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent)}
.mq-piste{display:flex;width:max-content}
.mq-lot{display:flex;gap:14px;padding-right:14px}
/* En bande, la tuile est plus basse et plus serree qu'en grille : elle est vue en
   mouvement, on n'y lit qu'un logo et un nombre. */
.mq .marque-tuile{width:152px;flex:none;min-height:0;padding:16px 12px;gap:7px}
.mq .marque-tuile img{height:32px}
.mq .marque-nom{font-size:.98rem}
@media (prefers-reduced-motion:no-preference){
  .mq-piste{animation:defile-marques 52s linear infinite;will-change:transform}
  /* Un lien qui se derobe sous le curseur n'est pas un lien. */
  .mq:hover .mq-piste,.mq:focus-within .mq-piste{animation-play-state:paused}
  /* Dès que marques.js prend la main, l'animation CSS s'efface : le défilement passe
     par le scroll réel du conteneur, ce qui rend la bande saisissable au doigt
     (demande de Samuel, 02/08). L'animation reste le repli sans JavaScript. */
  .mq--js .mq-piste{animation:none;will-change:auto}
}
/* Bande poussable : défilement horizontal natif, donc inertie du système au doigt.
   La barre de défilement est masquée — elle doublerait le masque de bord et ferait
   sale sous une rangée de logos. */
.mq--js{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;
  -ms-overflow-style:none;touch-action:pan-x}
.mq--js::-webkit-scrollbar{display:none}
@keyframes defile-marques{to{transform:translateX(-50%)}}
/* Sans mouvement, la bande redevient une grille : sinon `overflow:hidden` sur une
   piste immobile masquerait definitivement les trois quarts des marques. */
@media (prefers-reduced-motion:reduce){
  .mq{overflow:visible;-webkit-mask-image:none;mask-image:none}
  .mq-piste{width:auto;flex-wrap:wrap}
  .mq-lot{flex-wrap:wrap;gap:12px;padding-right:0}
  .mq-lot+.mq-lot{display:none}
}
@media print{
  .mq{overflow:visible;-webkit-mask-image:none;mask-image:none}
  .mq-piste{width:auto;flex-wrap:wrap}
  .mq-lot+.mq-lot{display:none}
}

/* ---------- pied de page repliable sur mobile ----------
   Il mesurait 1511 px sur un ecran de 812 px, dont 1252 px de colonnes de liens :
   deux ecrans pleins de navigation que personne ne lit. Les listes sont livrees
   OUVERTES (donc completes sans JavaScript, et pour les moteurs), et refermees
   sur telephone par nav.js. */
.foot-acc>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;gap:10px}
.foot-acc>summary::-webkit-details-marker{display:none}
.foot-acc>summary::after{content:"";width:9px;height:9px;flex:none;border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);opacity:.55;transition:transform .18s var(--ease);display:none}
.foot-acc[open]>summary::after{transform:rotate(-135deg) translate(-3px,-3px)}
@media (max-width:860px){
  .foot-acc>summary{min-height:48px;margin:0;border-top:1px solid rgba(255,255,255,.12)}
  .foot-acc>summary::after{display:block}
  .foot-acc>ul{padding-bottom:10px}
  /* Le bandeau de reassurance passe sur deux colonnes : 189 px au lieu de pres
     de 200 px empiles, et surtout un bloc qui se lit d'un coup d'oeil. */
  .foot-reassurance{display:grid;grid-template-columns:1fr 1fr;gap:8px 14px;text-align:left}
}

/* Reference du prix barre dans les blocs de suggestion (regle Omnibus). */
.sug-ref{color:var(--muted);font-size:.74rem;font-weight:600;margin:2px 0 0}
.sug-bas del{color:var(--muted);font-size:.85rem;margin-right:6px}
.modal-item-bas del{color:var(--muted);font-size:.85rem;margin-right:6px}

/* ---------- confort tactile (revue 27/07) ---------- */
@media (max-width:560px){
  /* Le bouton flottant de Rely recouvrait le libelle « Comparer » des cartes.
     Plus petit et plus dans l'angle, il degage la colonne d'actions ; le bas de
     page laisse de quoi faire defiler la derniere carte au-dessus de lui. */
  .masc-fab{width:52px;height:52px;right:12px;bottom:12px}
  .masc-fab-bulle{right:14px;bottom:74px;max-width:min(280px,calc(100vw - 32px))}
  main{padding-bottom:14px}
}
/* Liens de navigation en prose : 17-19 px espaces de 5 px, impossibles a viser
   au doigt. On leur donne une vraie surface sans changer l'apparence du texte. */
/* ⚠️ `.marques-autres a` a été RETIRÉ de cette liste le 02/08. Cette règle agrandit la
   zone tactile des liens en PROSE, où ils n'ont aucun rembourrage ; appliquée aux
   pastilles de marque, elle écrasait leur `padding:8px 13px` par `6px 2px` et le texte
   sortait de la bulle (constat de Samuel en bas de la page Marques). Les pastilles
   n'en ont pas besoin : elles font déjà 44 px de haut, donc au-dessus de la cible
   tactile recommandée. */
.prose a,.bp-sommaire a,.sub a{display:inline-block;padding:6px 2px;margin:-6px 0}
.bp-sommaire{display:flex;flex-wrap:wrap;gap:4px 14px;align-items:center}
.sub a{padding:5px 2px;margin:-5px 0}

/* ==================================================================
   MOUVEMENT — revue du 27/07
   Trois regles tenues partout dans ce bloc :
   1. Aucun contenu n'est jamais masque par defaut. Les revelations passent par
      des animations pilotees par le defilement (`animation-timeline`), gardees
      derriere un @supports : la ou le navigateur ne connait pas la regle, la
      page s'affiche simplement, complete. C'est le defaut classique des
      revelations en JavaScript (un script qui tombe = une section blanche)
      et il est structurellement impossible ici.
   2. On n'anime que `transform`, `opacity`, `box-shadow` et les filtres.
      Jamais une propriete qui declenche un recalcul de mise en page.
   3. `prefers-reduced-motion` neutralise tout, y compris les transitions de
      page, qui vivent dans un arbre de pseudo-elements que le `*` global
      n'atteint pas.
   ================================================================== */

/* ---------- transitions de page natives (cross-document) ----------
   La navigation d'une page a l'autre fond au lieu de clignoter en blanc.
   Zero JavaScript, zero dependance. Les navigateurs qui ignorent la regle
   naviguent normalement : c'est une amelioration, jamais un prerequis. */
@view-transition{navigation:auto}

::view-transition-old(root){animation:vt-sortie .14s linear both}
::view-transition-new(root){animation:vt-entree .26s var(--ease-out) both}
@keyframes vt-sortie{to{opacity:0}}
@keyframes vt-entree{from{opacity:0}}

/* L'en-tete et le bandeau d'annonce sont identiques d'une page a l'autre :
   on les sort du cliche de la racine pour qu'ils restent parfaitement fixes
   pendant le fondu. Sans ca, la barre de navigation « clignote » elle aussi. */
.annonce{view-transition-name:vt-annonce}
.site-head{view-transition-name:vt-tete}
::view-transition-old(vt-tete),::view-transition-new(vt-tete),
::view-transition-old(vt-annonce),::view-transition-new(vt-annonce){animation:none;mix-blend-mode:normal}

/* Morphing de la vignette produit vers la fiche : le nom n'est porte que par
   l'image cliquee (pose par anim.js) et par l'image de la fiche d'arrivee.
   Si l'un des deux manque, on retombe sur le fondu de la racine. */
.vt-produit{view-transition-name:vt-produit}
::view-transition-group(vt-produit){animation-duration:.34s;animation-timing-function:var(--ease-out)}
::view-transition-old(vt-produit),::view-transition-new(vt-produit){mix-blend-mode:normal;height:100%;object-fit:contain}

/* ---------- entree du premier ecran ----------
   Le hero est toujours visible au chargement : il merite une vraie entree,
   pas une revelation au defilement. Cascade courte, jamais rejouee. */
@media (prefers-reduced-motion:no-preference){
  .hero-txt>*{animation:entre-haut .62s var(--ease-out) backwards}
  .hero-txt>h1{animation-delay:.04s}
  .hero-txt>.hero-sous{animation-delay:.12s}
  .hero-txt>.hero-cta{animation-delay:.18s}
  .hero-txt>.hero-tel{animation-delay:.24s}
  .hero-txt>.hero-puces{animation-delay:.26s}
  /* Les quatre cartes de la scene derivent, chacune a son rythme. Les durees sont
     volontairement sans rapport entre elles et les departs sont decales dans le
     passe (delai negatif) : sinon les cartes montent et descendent ensemble, ce
     qui donne un balancement de bateau au lieu d'une suspension.
     L'entree ne joue QUE sur l'opacite — le `transform` appartient a la derive, et
     deux animations qui se disputent la meme propriete, c'est la derniere qui
     gagne et l'autre qui ne sert a rien. */
  .hs-c{animation:parait .9s var(--ease-out) backwards,flotte 7.6s ease-in-out infinite alternate}
  /* Le produit vedette levite lentement, et son ombre se resserre quand il
     monte : sans ce couplage, l'objet a l'air de glisser sur une vitre au
     lieu de s'elever. C'est le detail qui fait la difference entre « ca
     bouge » et « c'est en l'air ». */
  .hero-vedette-img{animation:vedette-flotte 6.4s ease-in-out infinite alternate}
  .hero-vedette-ombre{animation:vedette-ombre 6.4s ease-in-out infinite alternate}
  .hero-txt>.hero-h1{animation-delay:.04s}
  .hs-c1{animation-delay:.18s,-0.4s}
  .hs-c2{animation-delay:.28s,-2.9s;animation-duration:.9s,9.4s}
  .hs-c3{animation-delay:.38s,-1.7s;animation-duration:.9s,11.1s}
  /* Le trait de surlignage se trace de gauche a droite, juste apres le titre.
     C'est le seul mouvement du premier ecran qu'on remarque vraiment, et il
     designe exactement l'argument : « au bon prix ». */
  .hero-mark::after{animation:trace-mark .5s var(--ease-out) .34s backwards}
  /* La bande des rayons arrive en dernier, tuile par tuile, en se redressant.
     40 ms d'ecart : assez pour lire une vague, trop peu pour attendre. */
  .hero-rail>li{animation:entre-tuile .55s var(--ease-out) backwards;
    animation-delay:calc(.34s + var(--i,0)*.04s)}
  /* Le rang vient de `:nth-child` et non d'un `style="--i:…"` sur chaque <li> :
     la politique de securite de contenu du site interdit les styles en ligne, et
     le build refuse de livrer une page qui en contient. */
  .hero-rail>li:nth-child(2){--i:1}
  .hero-rail>li:nth-child(3){--i:2}
  .hero-rail>li:nth-child(4){--i:3}
  .hero-rail>li:nth-child(5){--i:4}
  .hero-rail>li:nth-child(6){--i:5}
  .hero-rail>li:nth-child(7){--i:6}
  .hero-rail>li:nth-child(8){--i:7}
  .hero-rail>li:nth-child(9){--i:8}
  .hero-rail>li:nth-child(10){--i:9}
  .hero-rail>li:nth-child(11){--i:10}
  .hero-rail>li:nth-child(n+12){--i:11}
  .hero-rayons-tete,.hero-rail-note{animation:entre-haut .6s var(--ease-out) .28s backwards}
  /* Les halos derivent lentement et sans fin. Rien ne les rattache a un contenu,
     c'est de l'atmosphere : durees longues, amplitudes faibles, aucune boucle
     visible a l'oeil. Trois periodes premieres entre elles pour que le motif ne
     se repete jamais a l'identique. */
  .hb1{animation:derive-a 29s ease-in-out infinite alternate}
  .hb2{animation:derive-b 37s ease-in-out infinite alternate}
  .hb3{animation:derive-c 43s ease-in-out infinite alternate}
  /* Le sol file vers l'horizon. Une seule maille de deplacement, donc la boucle
     est rigoureusement invisible. */
  .hero-sol::before{animation:sol-file 9s linear infinite}
  /* Un reflet traverse le bouton principal toutes les six secondes. Il ne
     clignote pas, il passe : c'est ce qui ramene l'oeil sans agresser. */
  /* Le reflet vit sur `::before` et NON sur `::after` : `::after` porte la fleche de
     `.btn-fleche`, et un element n'a qu'un seul `::after`. Ecrit ici en second, le
     reflet ecrasait la fleche et la faisait disparaitre sans rien signaler. */
  .hero .btn-hero{position:relative;overflow:hidden}
  .hero .btn-hero::before{content:"";position:absolute;top:-20%;bottom:-20%;left:-40%;width:34%;
    background:linear-gradient(100deg,rgba(23,31,120,0),rgba(23,31,120,.13),rgba(23,31,120,0));
    animation:reflet 6s var(--ease) 1.4s infinite}
}
@keyframes entre-haut{from{opacity:0;transform:translateY(14px)}}
@keyframes entre-tuile{from{opacity:0;transform:translateY(20px) rotateX(-14deg)}}
@keyframes parait{from{opacity:0}}
/* Registres des variables de derive : sans `@property` une variable ne
   s'interpole pas, elle saute de la valeur de depart a celle d'arrivee. */
@keyframes flotte{to{--fy:-15px;--fr:1.1deg}}
@keyframes vedette-flotte{from{transform:translateY(6px)}to{transform:translateY(-12px)}}
@keyframes vedette-ombre{from{transform:scale(1.04);opacity:.95}to{transform:scale(.86);opacity:.6}}
@keyframes trace-mark{from{transform:scaleX(0)}}
@keyframes derive-a{to{transform:translate3d(7%,5%,0) scale(1.1)}}
@keyframes derive-b{to{transform:translate3d(-9%,8%,0) scale(1.14)}}
@keyframes derive-c{to{transform:translate3d(6%,-7%,0) scale(1.08)}}
@keyframes sol-file{to{transform:translateY(70px)}}
@keyframes reflet{0%,72%{transform:translateX(0) skewX(-16deg)}100%{transform:translateX(430%) skewX(-16deg)}}

/* Filet de sécurité de l'entrée du hero.
   Une animation CSS est cadencée par l'horloge du document, et cette horloge
   est GELÉE tant que la page n'est pas rendue : onglet ouvert en arrière-plan,
   impression, moteur de rendu sans affichage. L'entrée resterait alors bloquée
   sur son image de départ, c'est-à-dire un premier écran vide. `anim.js` pose
   `.sans-entree` quand la page démarre masquée, et l'impression est traitée
   ici. Dans les deux cas l'animation est simplement annulée : le contenu est
   là, tout de suite. Le sens du garde-fou compte, il ne peut que rendre
   visible, jamais masquer. */
.sans-entree .hero-txt>*,.sans-entree .hero-rail>li,
.sans-entree .hero-rayons-tete,.sans-entree .hero-rail-note,
.sans-entree .hero-mark::after{animation:none}
@media print{
  .hero-txt>*,.hero-rail>li,.hero-rayons-tete,.hero-rail-note{animation:none !important;opacity:1 !important;transform:none !important}
  .hero-deco{display:none !important}
  .grid>*,.cat-grid>*,.pack-grid>*,.marques-mur>*,
  .why-grid>div,.bp-vedette,.pro-bloc,.sug,.sec-h,.sec-tete,.sec-h+.sub{animation:none !important;opacity:1 !important;transform:none !important}
}

/* ---------- revelations au defilement ----------
   `view()` cale l'animation sur la position de l'element dans le viewport.
   Un element deja visible au chargement est deja au bout de sa plage : il
   s'affiche net, sans entree parasite. Un element insere plus tard par un
   script (suggestions du panier, resultats du comparateur) est traite comme
   les autres, sans qu'on ait a le declarer nulle part. */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .grid>*,.cat-grid>*,.pack-grid>*,.marques-mur>*,
    .why-grid>div,.bp-vedette,.pro-bloc,.sug{
      animation:surgit .5s var(--ease-out) both;
      animation-timeline:view();
      animation-range:entry 5% cover 25%;
    }
    /* Les titres de section arrivent juste avant leur grille : la section se
       presente, puis se remplit. C'est ce decalage qui fait la difference
       entre « ca bouge » et « c'est mis en scene ». */
    .sec-h,.sec-tete{
      animation:surgit-titre .55s var(--ease-out) both;
      animation-timeline:view();
      animation-range:entry 0% cover 20%;
    }
    /* La ligne d'accroche suit son titre d'un cheveu. */
    .sec-h+.sub{
      animation:surgit-titre .55s var(--ease-out) both;
      animation-timeline:view();
      animation-range:entry 4% cover 24%;
    }
  }
}
/* ---------- la scene du hero pivote au defilement ----------
   « Une image 3D qui bouge avec toi » : la scene tourne a mesure qu'on descend,
   pilotee par le defilement lui-meme. Aucun ecouteur, aucun `requestAnimationFrame`,
   rien qui puisse saccader — et rien a demander comme autorisation, contrairement
   au capteur d'inclinaison, qui exige un geste de l'utilisateur sur iOS et ne
   marche pas sur ordinateur.
   La plage s'arrete a `cover 55%` : au-dela le hero est deja sorti de l'ecran, et
   continuer a tourner ne se verrait pas tout en continuant a couter des images.
   Les amplitudes sont faibles (10 degres au total) : au-dela, les cartes du fond
   passent devant celles du premier plan et la composition se casse. */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .hero-scene-in{
      animation:scene-pivote linear both;
      animation-timeline:view();
      animation-range:entry 0% cover 55%;
      will-change:transform;
    }
  }
}
@keyframes scene-pivote{
  from{transform:rotateX(7deg) rotateY(-6deg)}
  to{transform:rotateX(-3deg) rotateY(5deg)}
}
/* ---------- parallaxe des bannieres editoriales ----------
   La carte blanche de chaque banniere derive et se redresse pendant que la
   banniere traverse l'ecran. C'est ce qui separe un bloc IMPRIME d'un bloc
   compose : les deux plans ne bougent pas a la meme vitesse, donc l'oeil lit une
   profondeur au lieu d'un aplat.
   Amplitude volontairement faible (24 px et 4 degres) : au-dela, la carte sort
   de son cadre en bas d'ecran et le mouvement se remarque plus que le message. */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .ban-fond{
      animation:ban-derive linear both;
      animation-timeline:view();
      animation-range:entry 10% exit 90%;
      will-change:transform;
    }
    /* Le bloc Pros ferme la page comme le hero l'ouvre : meme sol en
       perspective, meme lecture. Il file dans l'autre sens, sinon les deux
       paraissent etre le meme element vu deux fois. */
    .pro-sol::before{
      animation:pro-file linear both;
      animation-timeline:view();
      animation-range:entry 0% exit 100%;
    }
  }
}
/* La derive est composee par VARIABLES, pas ecrite en dur dans les keyframes :
   chaque banniere a sa propre inclinaison de repos (`--br`), et des keyframes
   absolues les auraient toutes ramenees au meme angle. Sans mouvement, chaque
   carte garde exactement l'allure qu'elle a aujourd'hui. */
@keyframes ban-derive{
  from{--by:22px;--bd:-3deg}
  to{--by:-14px;--bd:3deg}
}
@keyframes pro-file{from{transform:translateY(-70px)}to{transform:translateY(70px)}}
@keyframes surgit{from{opacity:0;transform:translateY(18px)}}
@keyframes surgit-titre{from{opacity:0;transform:translateY(10px)}}

/* ---------- elevation de l'en-tete ----------
   L'ombre apparait a mesure qu'on quitte le haut de page, proportionnellement
   au defilement. Pilote par le defilement lui-meme : aucun ecouteur, aucun
   recalcul, rien qui puisse saccader. */
@supports (animation-timeline:scroll()){
  .site-head{
    animation:tete-ombre linear both;
    animation-timeline:scroll();
    animation-range:0 90px;
  }
}
@keyframes tete-ombre{
  from{box-shadow:0 1px 0 rgba(16,22,79,0)}
  to{box-shadow:0 1px 0 rgba(16,22,79,.04),0 8px 24px rgba(16,22,79,.09)}
}

/* ---------- finitions d'interaction ---------- */
/* Les cartes se soulevent au survol : l'ombre seule ne suffit pas a donner la
   sensation d'un objet qu'on peut prendre. */
.card,.cat-card,.pack-card{transition:box-shadow .22s var(--ease),border-color .22s var(--ease),transform .22s var(--ease)}
/* La carte ne monte plus seulement, elle se REDRESSE vers le lecteur : la grille
   porte une `perspective`, donc le `rotateX` produit un vrai basculement et non un
   aplatissement. C'est le meme geste que sur les tuiles de rayon du hero, pour que
   tout le site reponde de la meme facon.
   ⚠️ Cette regle est la SEULE qui doit porter le survol des cartes. Une seconde,
   ecrite plus haut a cote de `.card`, avait ete ajoutee le 29/07 puis retiree :
   celle-ci gagnait de toute facon par l'ordre de cascade, et l'autre ne servait
   qu'a faire croire que le reglage etait ailleurs. */
@media (hover:hover){
  .card:hover,.cat-card:hover,.pack-card:hover{transform:translateY(-4px) rotateX(2.2deg) scale(1.005)}
}
/* Au doigt, il n'y a pas de survol : on repond a l'appui. */
@media (hover:none){
  .card:active,.cat-card:active,.pack-card:active{transform:scale(.985)}
}

/* Le lien du panier reagit quand on y ajoute quelque chose (voir panier.js). */
.panier-lien{transition:background var(--t-court) var(--ease),border-color var(--t-court) var(--ease),transform var(--t-court) var(--ease)}
.panier-lien:hover{transform:translateY(-1px)}

/* Selection de texte aux couleurs de la marque : detail minuscule, mais c'est
   exactement ce genre de chose qui separe un site fait vite d'un site fini. */
::selection{background:var(--blue);color:#fff}

/* Les ancres ne doivent plus se glisser sous l'en-tete collant. */
:target{scroll-margin-top:88px}
h2[id],h3[id],section[id],[id].sec-h{scroll-margin-top:88px}

/* ---------- motion reduite : on coupe aussi les transitions de page ----------
   Le selecteur universel du bloc `prefers-reduced-motion` plus haut n'atteint
   pas l'arbre des pseudo-elements de transition : il faut les nommer. */
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none !important}
  .hero-txt>*,.hero-rail>li,.hero-rayons-tete,.hero-rail-note{animation:none !important;opacity:1 !important;transform:none !important}
  /* Le decor du hero n'a plus rien a apporter s'il ne bouge pas : trois halos
     figes et une grille couchee ne sont que du bruit visuel. On le retire, le
     degrade de fond suffit. Le contenu, lui, ne depend d'aucune de ces regles. */
  /* Le décor disparaît parce qu'il est fait de halos qui dérivent. Le filigrane des
     marques, lui, est parfaitement immobile : le masquer priverait de l'habillage du
     premier écran des gens qui ont seulement demandé moins de mouvement, pas moins
     d'images. On le rétablit donc explicitement (02/08). */
  .hero-deco{display:none}
  .hero-deco:has(.hero-filigrane){display:block}
  .hero-deco:has(.hero-filigrane)>:not(.hero-filigrane){display:none}
  /* 07/08 : le filigrane et le bandeau d'annonces bougent désormais. Ils sont FIGÉS
     ici, pas masqués — c'est toute la nuance de cette préférence : moins de
     mouvement, pas moins de contenu. Le bandeau figé montre la première série,
     qui porte la mention de livraison ; rien d'informatif ne disparaît. */
  .hero-filigrane,.hero-filigrane img,.annonce-piste{animation:none !important;transform:none !important}
  /* Le trait de surlignage se dessine par un scaleX : sans animation il doit
     etre a sa taille pleine, pas a zero. C'est la seule regle de ce bloc qui
     RETABLIT quelque chose au lieu de l'annuler. */
  .hero-mark::after{transform:none !important}
  .hero-rail .univ{transform:none}
  /* La scene garde son relief — c'est de la composition, pas du mouvement. Seule
     la derive s'arrete, et le `*{animation:none}` global s'en charge deja. Il faut
     en revanche retablir l'opacite, que l'entree mettait a zero. */
  .hs-c{opacity:1}
}

/* ==================================================================
   BANDE DE RAYONS + BANDE PACKS (refonte de l'accueil, 27/07)
   ================================================================== */
.rayons-bande-hote{margin-top:26px}
.rayons-bande{display:flex;flex-wrap:wrap;gap:9px}
.rayon-pil{display:flex;align-items:center;gap:9px;flex:none;background:#fff;border:1px solid var(--line);border-radius:999px;padding:6px 15px 6px 6px;color:var(--ink);font-weight:700;font-size:.92rem;box-shadow:var(--shadow-sm);transition:border-color .18s var(--ease),box-shadow .18s var(--ease),transform .18s var(--ease)}
.rayon-pil img{width:34px;height:34px;object-fit:contain;border-radius:50%;background:var(--bg);flex:none;padding:3px}
.rayon-pil-n{color:var(--muted);font-weight:600;font-size:.8rem;font-variant-numeric:tabular-nums}
.rayon-pil:hover{border-color:var(--blue);box-shadow:var(--shadow);transform:translateY(-2px)}
@media (hover:none){.rayon-pil:active{transform:scale(.97)}}
/* Sur téléphone la bande défile à l'horizontale plutôt que d'empiler dix
   pastilles sur cinq lignes : un geste naturel, et le contenu marchand reste
   à portée de pouce juste en dessous. */
@media (max-width:760px){
  .rayons-bande{flex-wrap:nowrap;overflow-x:auto;scroll-snap-type:x proximity;padding-bottom:8px;-webkit-overflow-scrolling:touch;scrollbar-width:thin}
  .rayon-pil{scroll-snap-align:start;min-height:46px}
  /* la bande file d'un bord à l'autre de l'écran, sans marge morte à droite */
  .rayons-bande-hote{padding-right:0}
  .rayons-bande::after{content:"";flex:none;width:8px}
}

/* Bande packs : rupture de fond pleine largeur. */
.bande-packs{background:#fff;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:56px 0 60px}
.bande-packs .sec-h{margin-top:0}
.bande-packs-lien{margin-top:20px;font-weight:700}

/* Composition a deux colonnes quand il y a moins de trois packs.
   Le 29/07, l'expiration des tarifs TD a fait tomber le nombre de packs publiables
   de 3 a 1 : la grille laissait une carte au bord gauche et 770 px de blanc a sa
   droite, sur la section qui porte le produit le plus differenciant du site.
   Les quatre elements sont deja freres dans le `.wrap` : on les replace par zones
   plutot que de changer le HTML selon le nombre de packs. */
.bande-packs--duo .wrap{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1fr);
  column-gap:52px;align-items:center;
  grid-template-areas:"titre packs" "sous packs" "lien packs"}
.bande-packs--duo .sec-h{grid-area:titre;align-self:end}
.bande-packs--duo .sub{grid-area:sous;margin-bottom:0}
/* 240 px de minimum, pas `minmax(0,1fr)` : avec un minimum nul, `auto-fit` ne peut
   plus calculer combien de colonnes tiennent et n'en pose qu'une — deux packs se
   retrouveraient empiles alors que la place est la. */
.bande-packs--duo .pack-grid{grid-area:packs;grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.bande-packs--duo .bande-packs-lien{grid-area:lien;align-self:start}
@media (max-width:860px){
  .bande-packs--duo .wrap{grid-template-columns:minmax(0,1fr);row-gap:8px;
    grid-template-areas:"titre" "sous" "packs" "lien"}
  .bande-packs--duo .sub{margin-bottom:18px}
  .bande-packs--duo .pack-grid{margin-top:6px}
}
@media (max-width:760px){.bande-packs{padding:38px 0 40px}}

/* ==================================================================
   CONFORT TACTILE — passe du 27/07
   Toutes les cibles secondaires montent à 44 px. Aucune n'a changé
   d'apparence : c'est de la surface, pas du dessin.
   ================================================================== */
@media (max-width:900px){
  .site-foot li a{padding:11px 0;display:inline-block}
  .crumbs a{display:inline-block;padding:11px 4px;margin:-11px 0}
  .compte-lien,.panier-lien{padding-top:12px;padding-bottom:12px}
  .nav-btn{height:44px}
  .vue-btn,.marques-autres a{min-height:44px}
  .cmp-pick-nom{padding:11px 0}
  .cmp-col-retirer,.cmp-reset,.quiz-nav .btn,.cmp-bar .btn{min-height:44px}
  .sug-fiche{display:inline-block;padding:12px 0}
  .modal-fermer,.masc-panneau-fermer{width:44px;height:44px}
  /* La croix de Rely est déjà à 38 px de zone cliquable pour un dessin de 20 : au
     doigt elle passe à 44, et la bulle réserve juste ce qu'il faut — pas plus, sinon
     c'est le texte qui se retrouve à l'étroit sur un écran de 360 px. */
  .masc-peek-fermer{width:44px;height:44px}
  .masc-peek-bulle{padding-right:40px}
  .foot-tel,.foot-rely{display:inline-block;padding:10px 0}
  .site-foot a[href^="mailto:"]{display:inline-block;padding:10px 0}
  /* La règle de rattrapage des liens en prose ne couvrait que quatre familles.
     Elle en oubliait autant, dont les liens des blocs de réassurance et les
     pages légales. */
  .reassurance a,.pdp-packs a,.legal a,.faq-item a,.cat-seo a,.prose-page a,
  .gar-legal a,.dem-rgpd a,.cc-intro a{display:inline-block;padding:11px 2px;margin:-11px 0}
}

/* ==================================================================
   DÉCALAGE DE MISE EN PAGE (CLS)
   Les commandes livrées `hidden` et révélées par JS poussaient la page vers
   le bas au moment où les scripts s'exécutaient. On réserve leur hauteur au
   premier rendu : invisible et inerte sans JS, mais la place est prise.
   ================================================================== */
.toolbar[hidden],.vue-bascule[hidden]{display:flex !important;visibility:hidden;pointer-events:none}
.pdp-cta{min-height:52px}
.quiz-nav{min-height:44px}

/* ==================================================================
   BOUTON FLOTTANT RELY — plus de recouvrement
   Il chevauchait « Comparer » sur les cartes, et le toast le recouvrait
   entièrement pendant ses trois secondes d'affichage.
   ================================================================== */
@media (max-width:560px){
  /* le contenu de fin de page ne passe plus sous le bouton */
  main{padding-bottom:80px}
  /* quand un toast est à l'écran, le bouton s'efface : deux cibles au même
     endroit, c'est une de trop */
  body.toast-on .masc-fab{opacity:0;transform:translateY(8px) scale(.9);pointer-events:none}
}
.masc-fab{transition:transform var(--t-moyen) var(--ease-out),box-shadow var(--t-moyen) var(--ease),opacity var(--t-moyen) var(--ease)}

/* ==================================================================
   ÉQUILIBRE DU BLOC « POURQUOI NOUS »
   La première colonne énumérait 37 marques en clair : 268 px de haut contre
   45 px pour sa voisine, dans une grille censée aligner quatre promesses.
   ================================================================== */
.why-grid>div{align-content:start}
.why p{max-width:38ch}

/* Sécurité de césure : une référence produit sans tiret plus longue que la
   colonne déborderait de sa carte. Le catalogue actuel passe, mais il suffit
   d'une nouvelle référence pour que ça casse. */
.card-title,.cmp-col-nom,.pl-nom,.sug-nom{overflow-wrap:anywhere}

/* Marque cliquable sur la fiche produit. */
.lien-marque{color:var(--muted);display:inline-block;padding:4px 0}
.lien-marque:hover{color:var(--blue)}
.lien-marque-suite{text-transform:none;letter-spacing:0;font-weight:600;color:var(--blue);opacity:0;transition:opacity .18s var(--ease)}
.lien-marque:hover .lien-marque-suite,.lien-marque:focus-visible .lien-marque-suite{opacity:1}
/* Au doigt il n'y a pas de survol : la mention reste lisible en permanence. */
@media (hover:none){.lien-marque-suite{opacity:1}}

/* ==================================================================
   PREMIER ÉCRAN MOBILE — passe du 27/07
   Mesuré à 375 × 812 : bandeau 56 px + en-tête 65 + hero 719 = 840 px.
   Le premier écran ne contenait donc RIEN d'autre que le hero, et le premier
   prix du catalogue n'apparaissait qu'au pixel 1 273. Un visiteur qui arrive
   sur une boutique doit voir qu'on y vend quelque chose.
   Tout ce qui suit est de la compression, pas de la suppression : aucun mot
   ni aucune promesse n'est retiré.
   ================================================================== */
@media (max-width:560px){
  /* Le bandeau passait sur deux lignes à 375 px pour une seule phrase. */
  .annonce{font-size:.76rem}
  .annonce-in{padding:7px 16px}
  .annonce-fort{padding-left:16px}
  .annonce-fort::before{width:9px;height:9px;margin-top:-4px;box-shadow:0 0 0 2px rgba(91,156,255,.28)}

  .hero-in{padding-top:24px;padding-bottom:22px;gap:20px}
  /* Les deux boutons avaient été mis côte à côte le 27/07 pour économiser 65 px
     de hauteur, à une époque où le hero en pesait 719. Depuis le 29/07 il n'y a
     plus de carte d'engagements et la place est revenue : à 430 px les deux
     libellés passaient chacun sur DEUX lignes, ce qui coûte finalement la même
     hauteur en ayant l'air d'un accident. L'action principale reprend donc toute
     la largeur, la secondaire suit. */
  .hero-cta{margin-top:20px;gap:10px;flex-wrap:wrap}
  .hero-cta .btn-hero{flex:1 1 100%;min-width:0;padding:15px 16px;font-size:.97rem}
  /* Deuxième rangée : le devis pro et le téléphone se partagent la largeur. Deux
     actions de même poids, donc deux moitiés — et une ligne de gagnée. */
  .hero-cta .btn-ghost{flex:1 1 46%;min-width:0;padding:13px 8px;font-size:.88rem}
  .hero-cta .hero-tel{flex:0 0 auto;padding:9px 13px 9px 11px}
  .hero-tel-num{font-size:.97rem}
  .hero-sous{margin-top:12px;font-size:.95rem;line-height:1.5}

  /* La bande de rayons remonte contre le hero : elle sert de transition entre
     la promesse et le catalogue, elle n'a pas besoin de respirer. */
  .rayons-bande-hote{margin-top:14px}
}

/* ==================================================================
   COMPARATEUR AU DOIGT — passe du 27/07
   Mesuré à 375 px : le tableau faisait 572 px dans un conteneur de 350, la
   colonne de libellés en prenait 122, et il restait 228 px pour trois colonnes
   produit de 150. Autant dire une colonne et demie visible : comparer trois
   produits au téléphone était impossible, alors que c'est toute la promesse
   de la page.

   Plutôt que d'entasser, on assume le geste : une colonne produit occupe
   exactement la place disponible à côté des libellés, et le défilement
   horizontal s'aimante d'un produit à l'autre. Les critères restent sous les
   yeux en permanence, on fait glisser pour passer au produit suivant.
   Aucun changement de JavaScript, aucune structure de tableau cassée : les
   lecteurs d'écran continuent de lire un vrai tableau de comparaison.
   ================================================================== */
.cmp-astuce{display:none;margin:10px 0 0;color:var(--muted);font-size:.85rem}
@media (max-width:620px){
  .cmp-table-wrap{scroll-snap-type:x mandatory;overscroll-behavior-x:contain}
  /* min-width:auto laisse les colonnes commander la largeur : sans ça, le
     min-width du tableau reprend la main et l'aimantation ne tombe jamais
     juste. */
  .cmp-table{min-width:0}
  .cmp-col-lab{width:112px;min-width:112px;max-width:112px}
  /* 112 px de libellés + 24 px de marges du conteneur : le reste pour UNE
     colonne produit, entièrement lisible. */
  .cmp-col-prod{min-width:calc(100vw - 112px - 26px);width:calc(100vw - 112px - 26px);scroll-snap-align:start}
  .cmp-row-lab{scroll-snap-align:none}
  .cmp-table th,.cmp-table td{padding:11px 12px;font-size:.86rem}
  .cmp-col-lien img{height:110px}
  /* On dit ce qui se passe, sinon le geste ne s'invente pas. */
  .cmp-table-wrap+.cmp-astuce,.cmp-astuce{display:block}
}
.cmp-astuce::before{content:"↔";margin-right:7px;font-weight:800;color:var(--blue)}

/* Bouton « afficher les N autres produits » du sélecteur du comparateur. */
.cmp-plus{display:block;width:calc(100% - 32px);margin:14px 16px 4px}

/* ==================================================================
   PAGES LÉGALES — lisibilité (27/07)
   Les CGV faisaient 12,7 écrans de prose pleine sur téléphone, sans un seul
   repère : 14 sections, aucun sommaire, jusqu'à 26 lignes d'un seul
   paragraphe. Le texte contractuel n'est pas touché — on ne réécrit pas des
   CGV pour faire joli — mais on donne des points d'entrée et de l'air.
   ================================================================== */
.legal-sommaire{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:18px 22px 20px;margin:22px 0 30px;box-shadow:var(--shadow-sm)}
.legal-sommaire-h{font-weight:800;font-size:.95rem;margin-bottom:10px}
.legal-sommaire ol{margin:0;padding-left:20px;columns:2;column-gap:34px}
.legal-sommaire li{margin-bottom:6px;font-size:.92rem;break-inside:avoid}
.legal-sommaire a{color:var(--ink-2)}
.legal-sommaire a:hover{color:var(--blue);text-decoration:underline}
@media (max-width:760px){
  .legal-sommaire ol{columns:1}
  .legal-sommaire li{margin-bottom:2px}
  .legal-sommaire a{display:inline-block;padding:9px 0}
}
/* Les sections doivent respirer et se repérer d'un coup d'œil au défilement. */
.legal h2{margin-top:40px;padding-top:18px;border-top:1px solid var(--line);scroll-margin-top:88px}
.legal h2:first-of-type{border-top:0;padding-top:0}
.legal p{line-height:1.68;margin-bottom:14px}
.legal li{line-height:1.6;margin-bottom:7px}

/* Le logo de l'en-tête était la dernière cible sous 44 px (34 px de haut, la
   hauteur de l'image). L'en-tête en fait 64 : le rembourrage ne déplace rien. */
.brand{padding:5px 0}

/* Prix hors taxes sous le prix TTC (fiche produit). */
.pdp-ht{color:var(--ink-2);font-size:.92rem;font-weight:700;margin:2px 0 4px}
.pdp-ht span{color:var(--muted);font-weight:400;font-size:.86rem}
@media (max-width:560px){.pdp-ht span{display:block}}

/* Panier : catalogue temporairement illisible (le panier est conservé). */
.panier-hs{background:#EAF1FE;border:1px solid #f0c9b8;border-radius:var(--r-sm);padding:14px 16px;margin:0 0 18px;color:var(--ink-2);font-size:.94rem;text-wrap:pretty}
.panier-hs a{font-weight:700;text-decoration:underline}
/* Commande : référence introuvable. */
.cmd-introuvable{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:22px 24px;margin:6px 0 20px;box-shadow:var(--shadow-sm)}
.cmd-introuvable p{margin-bottom:14px;text-wrap:pretty}
.cmd-introuvable p:last-child{margin-bottom:0;display:flex;gap:10px;flex-wrap:wrap}

/* ---------- garder un panier (espace client, 29/07) ---------- */
.panier-garder{margin-top:34px;padding:22px 24px;background:var(--blue-soft);border-radius:var(--r)}
.panier-garder .sec-h{margin-top:0;font-size:1.25rem}
.panier-garder .sub{margin-bottom:16px}
.garder-form{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
.garder-lab{display:flex;flex-direction:column;gap:4px;font-size:.82rem;font-weight:700;color:var(--ink-2);flex:1 1 240px}
.garder-lab input{font:inherit;font-size:.92rem;padding:10px 13px;min-height:44px;border:1px solid var(--line-2);
  border-radius:var(--r-sm);background:#fff;color:var(--ink);width:100%}
.garder-lab input:focus{border-color:var(--blue);outline:none;box-shadow:0 0 0 3px rgba(23,31,120,.14)}
.panier-garder-anon{margin-top:22px}
/* Les deux actions d'un panier gardé, dans l'espace client. */
.cc-actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:12px}
.cc-btn-mini{font-size:.87rem;padding:10px 16px;min-height:42px}
.cc-lignes{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:5px}
.cc-lignes li{display:flex;justify-content:space-between;gap:14px;font-size:.87rem;color:var(--ink-2)}
.cc-ligne-prix{font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink)}
.cc-ligne-plus{color:var(--muted);font-style:italic}
@media (max-width:560px){
  .panier-garder{padding:18px 16px}
  .garder-form{flex-direction:column;align-items:stretch}
  .garder-form .btn{width:100%}
}

/* ==================================================================
   PAGE DE RETOUR APRÈS PAIEMENT (02/08)
   Le moment le plus anxieux d'un achat en ligne : la carte est partie, et le client
   ne sait pas encore si ça a marché. La page répond dans l'ordre à ses trois
   questions — c'est bon, voilà ce qui va se passer, voilà qui appeler si rien
   n'arrive. Pas de confettis, pas de bandeau promo : on ne lui vend rien de plus.
   ================================================================== */
.merci{max-width:640px;margin:0 auto;padding:8px 0 12px}
.merci-tete{text-align:center;margin-bottom:30px}
.merci-coche{display:grid;place-items:center;width:66px;height:66px;margin:0 auto 18px;
  border-radius:50%;background:rgba(26,95,208,.12);color:var(--blue);
  border:1.5px solid rgba(26,95,208,.3)}
.merci-coche svg{width:32px;height:32px}
.merci h1{margin:0 0 10px;font-size:clamp(1.5rem,4vw,2rem)}
.merci-sous{margin:0;color:var(--gris-txt);font-size:1.02rem;line-height:1.5}
.merci-suite{list-style:none;margin:0 0 26px;padding:0;display:grid;gap:2px;
  border:1px solid var(--bord);border-radius:16px;overflow:hidden;background:var(--fond-2)}
.merci-suite li{display:grid;grid-template-columns:minmax(0,1fr);gap:3px;
  padding:15px 18px;background:#fff}
.merci-suite li+li{border-top:1px solid var(--bord)}
.merci-suite b{font-size:.82rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--blue)}
.merci-suite span{color:var(--gris-txt);line-height:1.45}
.merci-note{font-size:.92rem;line-height:1.55;color:var(--gris-txt);
  padding:14px 16px;border-radius:13px;background:var(--fond-2);border:1px solid var(--bord)}
.merci-liens{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.merci-liens .btn{flex:1 1 200px;text-align:center}
@media (min-width:640px){
  .merci-suite li{grid-template-columns:180px minmax(0,1fr);gap:14px;align-items:baseline}
}

/* Bascule de la voix de Rely (02/08). Discrète, à gauche du champ de saisie : c'est
   une option, pas une fonctionnalité vedette. Elle s'allume quand la voix est active,
   pour qu'on sache d'un coup d'œil si le site va parler. */
.rely-voix{flex:0 0 auto;width:38px;height:38px;border:1px solid var(--line);
  background:#fff;border-radius:50%;font-size:1.05rem;line-height:1;cursor:pointer;
  color:var(--muted);transition:background var(--t-court) var(--ease),
  border-color var(--t-court) var(--ease),color var(--t-court) var(--ease)}
.rely-voix:hover{border-color:var(--blue);color:var(--blue)}
.rely-voix.on{background:var(--blue-soft);border-color:var(--blue);color:var(--blue)}

/* ------------------------------------------------------------------
   FILIGRANE DES MARQUES DANS LE HERO (essai, 02/08)
   « Le gros RELIATECH est plus joli, mais du coup un peu vide » (Samuel). Plutôt
   qu'un motif abstrait, on pose les logos des marques réellement distribuées : la
   matière ainsi obtenue DIT quelque chose de vrai sur la boutique.
   Trois précautions :
   · opacité très basse et logos ramenés au blanc — à ce niveau ils ne concurrencent
     ni le nom ni les prix, et aucun contraste de texte n'est dégradé ;
   · masque qui les efface vers le centre et vers le bas, là où vivent le titre et
     les boutons : un filigrane ne doit jamais passer DERRIÈRE un mot qu'on lit ;
   · purement décoratif — non cliquable, hors du flux, alternative vide. La liste
     cliquable des marques reste la bande, plus bas dans la page.
   ------------------------------------------------------------------ */
/* MAJ 02/08 : le filigrane couvre tout le premier écran, pas seulement le haut
   (« quitte à mettre plusieurs fois la même marque que ça remplisse le fond »).
   La série est répétée cinq fois côté HTML, décalée à chaque tour. Le masque ne sert
   plus à effacer le bas mais à CREUSER le centre, là où se lisent le nom, la promesse
   et les boutons : la matière reste partout, elle s'efface seulement sous les mots. */
/* MAJ 07/08 : le filigrane respire (« regarde si on peut les faire bouger un peu que
   ça rende un peu plus vivant », Samuel). Deux précautions qui expliquent la forme
   exacte de l'animation :
   · elle porte sur le CONTENEUR, pas sur les 55 logos. Une seule couche composite au
     lieu de 55 : sur téléphone, la différence n'est pas théorique ;
   · le déplacement (10 px) est toujours plus petit que l'agrandissement (4,5 % d'une
     largeur d'écran, soit des dizaines de pixels). C'est ce qui garantit qu'aucun
     bord ne se découvre pendant la dérive, sans avoir à faire déborder le bloc.
   Le rythme est volontairement très lent : à 46 s l'aller simple, l'œil ne suit pas
   le mouvement, il perçoit seulement que le fond n'est pas mort. */
.hero-filigrane{position:absolute;inset:0;display:flex;flex-wrap:wrap;
  align-content:space-around;justify-content:space-around;gap:30px 46px;padding:26px 18px;
  pointer-events:none;opacity:.075;overflow:hidden;will-change:transform,opacity;
  animation:filigrane-vie 46s ease-in-out infinite alternate;
  -webkit-mask-image:radial-gradient(58% 46% at 50% 46%,transparent 0%,transparent 42%,#000 88%);
  mask-image:radial-gradient(58% 46% at 50% 46%,transparent 0%,transparent 42%,#000 88%)}
@keyframes filigrane-vie{
  from{transform:scale(1.005) translate3d(0,0,0);opacity:.062}
  to{transform:scale(1.045) translate3d(-10px,-6px,0);opacity:.092}}
.hero-filigrane img{height:26px;width:auto;filter:brightness(0) invert(1)}
/* MAJ 11/08 : « pas spécialement de droite vers la gauche, un peu dans tous les sens »
   (Samuel). La respiration du conteneur ci-dessus donnait UN seul vecteur : tout le
   fond partait vers le même coin, ce qui se lit comme un défilement. Chaque logo reçoit
   donc sa propre dérive, dans une direction différente — diagonales montantes et
   descendantes, verticales, horizontales, et deux orbites qui ne repassent pas par le
   même point. Six trajectoires réparties par nth-child, avec des durées premières entre
   elles (29 à 47 s) et des délais négatifs : la boucle commune ne se reforme jamais à
   l'œil, et rien ne démarre en même temps au chargement.
   Le coût est maîtrisé : `transform` seule, donc composition GPU, aucune reprise de mise
   en page ; amplitudes de 7 à 13 px, sous l'agrandissement du conteneur, donc aucun bord
   ne se découvre. Sur mobile, où le filigrane est plus dense et l'écran plus petit, ces
   dérives individuelles sont coupées : la respiration d'ensemble suffit. */
/* Les deux orbites passent par quatre points : elles tournent au lieu d'aller et venir,
   ce qui casse la symétrie des aller-retours des quatre premières. */
/* Logos dont le NOM est posé en clair SUR une forme pleine (l'ovale de Samsung, les
   carrés de Microsoft). Les repeindre en blanc fusionne le nom et la forme : il ne
   reste qu'un pavé. On les inverse plutôt : la forme sombre s'éclaircit, le nom clair
   devient sombre, et le nom se relit en négatif à l'intérieur de la forme.
   L'opacité propre compense le fait qu'un aplat inversé, lui, n'est pas blanc pur. */
.hero-filigrane img.fil-plein{filter:grayscale(1) invert(1) brightness(1.12);opacity:.82}
@media (max-width:1023px){
  .hero-filigrane{gap:22px 30px;padding:14px 10px;opacity:.07}
  .hero-filigrane img{animation:none;transform:none;will-change:auto}
  .hero-filigrane img{height:19px}
}

/* Mention de référence d'un prix barré : obligatoire, mais ce n'est pas un argument
   de vente. Elle passe donc en note discrète sous le titre de section, au lieu du
   paragraphe explicatif qui décrivait notre méthode de calcul (02/08). */
.bp-mention{font-size:.84rem;color:var(--muted);margin:-4px 0 14px;max-width:62ch}

/* Espace client — les deux portes attendues (11/08, Samuel). Elles ne mènent qu'à un
   seul formulaire, et c'est écrit : sans mot de passe, « se connecter » et « s'inscrire »
   sont le même geste. Les afficher séparément sans le dire ferait chercher un bouton
   d'inscription qui n'existe pas ; ne rien afficher laissait le visiteur dans le flou. */
.cc-portes{display:flex;gap:12px;flex-wrap:wrap;margin:0 0 18px}
.cc-porte{flex:1 1 240px;margin:0;padding:14px 16px;border:1px solid var(--line);
  border-radius:var(--r);background:#fff;display:flex;flex-direction:column;gap:3px}
.cc-porte--on{border-color:var(--blue);box-shadow:0 0 0 3px var(--blue-soft)}
.cc-porte strong{font-size:1.02rem;color:var(--ink)}
.cc-porte span{font-size:.9rem;color:var(--muted)}

/* Pied de page — moyens de paiement et transporteurs (11/08). Remplace quatre phrases de
   réassurance qui n'apprenaient rien (« Retour 14 jours », « Facture avec TVA »…) par ce
   que le visiteur cherche vraiment à cet endroit : peut-il payer comme d'habitude, et qui
   livre. C'est ce que font Materiel.net et Grosbill au même emplacement. */
.foot-moyens{display:flex;flex-wrap:wrap;gap:26px 54px;padding:18px 0 4px;border-top:1px solid var(--line-soft,#e8ecf5)}
.foot-moyens-h{margin:0 0 8px;font-size:.78rem;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.foot-logos{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0;padding:0}
.foot-logos img{display:block;height:24px;width:auto}
@media (max-width:640px){.foot-moyens{gap:18px 28px}}

/* Bande des marques sans titre visible (11/08) : le bouton se retrouve seul sur sa ligne,
   il doit s'aligner à droite sans laisser un vide en haut de section. */
.sec-tete--nue{justify-content:flex-end;margin-bottom:10px}

/* Dépôt d'avis (11/08). Les étoiles sont de vrais boutons radio : le clavier et les
   lecteurs d'écran passent dessus normalement, et la note part avec le formulaire même
   si le JavaScript ne se charge pas. */
.avis-note{border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;margin:0 0 18px}
.avis-note legend{font-weight:700;padding:0 6px}
.avis-etoile{display:flex;align-items:center;gap:10px;padding:7px 8px;border-radius:var(--r-sm);cursor:pointer}
.avis-etoile:hover{background:var(--blue-soft)}
.avis-etoile span{font-size:1.15rem;letter-spacing:2px;color:#e8a33d}
.avis-etoile small{color:var(--muted)}
.avis-etoile input{accent-color:var(--blue)}
.avis-verifie{background:#eaf6ee;border:1px solid #bfe0c9;border-radius:var(--r-sm);
  padding:10px 14px;margin:0 0 16px;font-size:.94rem}
.avis-regles{margin-top:38px;padding-top:22px;border-top:1px solid var(--line)}
.avis-regles h2{font-size:1.06rem}
.avis-regles p{color:var(--muted);font-size:.94rem;margin:.5em 0}
.dem-piege{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* Le VRAI R de RELIATECH dans le slogan (11/08, Samuel : « on pousse le truc au max »).
   Ce n'est plus la lettre du mot-logo mais le SYMBOLE de la marque, avec ses lignes de
   circuit. Il est plus large qu'une lettre (ratio 1,4) et son dessin déborde volontairement
   au-dessus de la hauteur d'x : on le cale donc sur la hauteur de capitale et on resserre
   les approches, faute de quoi « pro » s'écarterait comme un mot mal espacé.
   Le corps du R suit la couleur du texte, les circuits gardent le bleu de la charte : le
   symbole reste reconnaissable sur fond sombre comme sur fond clair. */
.hero-r{height:1.34em;width:auto;display:inline-block;vertical-align:-.36em;
  margin:0 -.08em 0 -.05em;color:currentColor}
/* Le symbole est nettement plus grand que la lettre qu'il remplace : c'est voulu. À taille
   de texte, ses lignes de circuit se refermaient en un pâté illisible — il faut de la place
   pour qu'on reconnaisse la marque. Il déborde donc sous la ligne de base, et l'interligne
   du slogan est ouvert d'autant pour que la seconde ligne ne vienne pas le toucher. */
.hero-promesse{line-height:1.34}

/* Déroulant des marques (11/08) : deux colonnes, sinon dix entrées font une colonne trop
   haute qui dépasse sous la barre. Le compteur dit combien de références on a par marque —
   c'est ce qui aide à cliquer, plutôt qu'une liste de noms nus. */
.nav-panel--marques{display:grid;grid-template-columns:1fr 1fr;gap:2px 6px;min-width:340px}
.nav-panel--marques a{display:flex;align-items:center;justify-content:space-between;gap:10px}
.nav-compte{font-size:.78rem;font-weight:700;color:var(--muted);background:var(--blue-soft);
  border-radius:999px;padding:1px 7px}
.nav-panel-tout{grid-column:1 / -1;margin-top:4px;border-top:1px solid var(--line);
  padding-top:9px !important;font-weight:700;color:var(--blue) !important}

/* Filigrane en mouvement libre (11/08). Le flex place les logos une première fois — c'est
   la disposition de repli si le JavaScript ne se charge pas —, puis le script les passe en
   absolu et prend la main. `position:relative` sur le conteneur donne le référentiel des
   coordonnées ; sans lui, les logos se placeraient par rapport à la page entière. */
.hero-filigrane.fil-libre{display:block;position:absolute;overflow:hidden}
.hero-filigrane.fil-libre img{position:absolute;top:0;left:0;will-change:transform}

/* Éco-participation : information légale, mais ce n'est pas un argument. Elle se lit sous
   le prix, en petit, et ne partage plus sa ligne avec la livraison offerte (11/08). */
.pdp-ecopart{margin:2px 0 6px;font-size:.78rem;color:var(--muted)}

/* Logo du constructeur sur la fiche produit (11/08). Hauteur bridée et largeur libre :
   les logos n'ont pas tous le même rapport, et un Dell carré ne doit pas écraser un
   Logitech allongé. Le nom reste, pour les lecteurs d'écran et les marques sans fichier. */
.pdp-marque-logo{height:26px;width:auto;max-width:110px;object-fit:contain;vertical-align:middle;margin-right:9px}
.card-brand .lien-marque{display:inline-flex;align-items:center;flex-wrap:wrap}
.lien-marque-nom{font-weight:700}

/* Montée en gamme (11/08) : photo + marque, comme sur les grandes places de marché.
   L'image porte la moitié
   du message — « pour 85 € de plus » ne veut rien dire tant qu'on ne voit pas quoi. */
.upsell{display:flex;align-items:center;gap:14px}
.upsell-img{flex:none;width:86px;height:66px;object-fit:contain;background:#fff;border-radius:var(--r-sm)}
.upsell-sur{display:flex;align-items:center;gap:8px;font-size:.82rem;font-weight:700;
  text-transform:uppercase;letter-spacing:.04em;color:var(--blue)}
.upsell-marque{font-weight:800;margin-right:6px}
.upsell-meme{font-size:.7rem;font-weight:700;text-transform:none;letter-spacing:0;
  background:var(--blue-soft);color:var(--blue);border-radius:999px;padding:1px 8px}
@media (max-width:560px){.upsell-img{width:64px;height:52px}}

/* Commande : cases de bascule (pro / même adresse) — 11/08. Une case qui commande
   l'affichage d'un bloc doit se voir comme un choix, pas comme une ligne de formulaire. */
.order-case{display:flex;align-items:center;gap:10px;margin:14px 0;padding:12px 14px;
  border:1px solid var(--line);border-radius:var(--r);background:#fff;font-weight:600;cursor:pointer}
.order-case input{accent-color:var(--blue);width:17px;height:17px}
.order-pro{border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;margin:0 0 6px}
.order-pro legend{font-weight:700;padding:0 6px}

/* Filigrane : taille par palier selon la forme du logo (11/08). Une hauteur unique donnait
   un Dell riquiqui à côté d'un SanDisk qui traversait l'écran — leurs rapports vont de 1
   à 9. On vise une surface d'encre comparable, pas une hauteur commune. */
.hero-filigrane img.fil-xl{height:46px}
.hero-filigrane img.fil-l{height:36px}
.hero-filigrane img.fil-m{height:28px}
.hero-filigrane img.fil-s{height:23px}
.hero-filigrane img.fil-xs{height:19px}
@media (max-width:1023px){
  .hero-filigrane img.fil-xl{height:32px}
  .hero-filigrane img.fil-l{height:26px}
  .hero-filigrane img.fil-m{height:21px}
  .hero-filigrane img.fil-s{height:18px}
  .hero-filigrane img.fil-xs{height:15px}
}

/* ---------- avis clients sur l'accueil (12/08) ----------
   Meme principe que la bande de marques : une rangee qui se pousse au doigt plutot
   qu'une grille qui pousse tout le reste vers le bas. La section entiere est livree
   `hidden` par le build et n'apparait que si des avis existent vraiment. */
.sec-avis{margin-top:6px}
.avis-defile{display:flex;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;
  -ms-overflow-style:none;touch-action:pan-x;margin:8px 0 30px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 3%,#000 97%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 3%,#000 97%,transparent)}
.avis-defile::-webkit-scrollbar{display:none}
.avis-piste{display:flex;gap:14px;padding:2px 0 6px}
.avis-carte{flex:none;width:300px;display:flex;flex-direction:column;gap:7px;
  padding:18px 18px 16px;border:1px solid var(--line);border-radius:14px;background:#fff}
.avis-tete{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.avis-etoiles{color:#E8A21B;letter-spacing:1px;font-size:1rem;line-height:1}
.avis-badge{font-size:.74rem;font-weight:700;color:var(--blue);
  background:rgba(26,95,208,.08);border-radius:999px;padding:3px 9px}
.avis-titre{font-weight:700;font-size:.98rem;margin:0}
.avis-texte{margin:0;font-size:.92rem;line-height:1.5;color:var(--ink)}
.avis-pied{margin:0;font-size:.8rem;color:var(--muted)}
.avis-produit{font-size:.82rem;color:var(--blue);text-decoration:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.avis-produit:hover{text-decoration:underline}
@media (max-width:600px){.avis-carte{width:264px}}
