/* ============================================================
   DIGISOVIA — Design system
   Direction : COMMERCE CLAIR, corps blanc / surfaces profondes quasi-noires.
   Ordre : tokens -> reset -> typographie -> primitives
   -> navigation -> sections -> composants -> pages -> responsive.

   Changement de direction du 2026-08-28, sur brief client : un melange de
   microcodes.ma (le hero grand, la navigation) et de keyswholesale.net (le
   style marchand). La direction editoriale claire du 18 aout — papier, encre,
   laiton, Cormorant — est remplacee ici ; rien n'est supprime ailleurs.

   LES JETONS SONT RENOMMES PAR LEUR ROLE, PAS PAR LEUR VALEUR.
   --brass tenait un laiton qui n'existe plus, --serif tenait desormais une
   linerale : deux noms qui mentaient sur leur contenu. C'est le defaut deja
   paye une fois sur ce projet, quand --ink servait a peindre une ombre et
   donnait des ombres BLANCHES sur la rampe sombre. Ils deviennent donc
   --accent, --font-display, --font-body, --success.
   ============================================================ */

/* ---------- 1. TOKENS ---------- */

/*
   DEUX THEMES, UN SEUL JEU DE NOMS.

   Le sombre est le DEFAUT : il vit sur `:root`. Le clair est une surcharge
   posee sur `:root[data-theme="light"]`. Aucun composant plus bas ne connait
   la couleur qu'il peint — il ne connait que le ROLE : surface de carte,
   encre secondaire, lavis de survol. Basculer un theme ne demande donc de
   toucher qu'a ce bloc.

   POURQUOI DES JETONS SUPPLEMENTAIRES (--nav-bg, --hover, --shadow-*,
   --accent-wash). Les couches precedentes ecrivaient ces valeurs en dur :
   `background:#fff` pour une carte, `rgba(15,27,42,.05)` pour un survol,
   une ombre noire pour un relief. Aucune ne pouvait suivre un changement de
   theme — un lavis noir a 5 % sur fond sombre ne se voit pas, une ombre
   noire non plus. Chacune devient un jeton, avec sa valeur propre de chaque
   cote.

   `prefers-color-scheme` N'EST PAS CONSULTE. La consigne est « le site en
   sombre, avec la possibilite de passer en clair » : le sombre s'applique
   donc a tout le monde, et seul un choix explicite du visiteur le change.
   Suivre le reglage du systeme aurait servi du clair a une partie des
   visiteurs sans que personne l'ait demande.
*/

:root{
  /* --white NE BASCULE PAS. Il ne designe pas une surface mais l'encre la
     plus claire : le texte pose sur un aplat colore (bouton plein, badge de
     remise). Le repointer donnerait du texte sombre sur un bouton violet. */
  --white:#FFFFFF;

  /* --- SOMBRE (defaut) --- */
  --paper:#0B0F16;
  --shade:#121722;
  --surface:#151B26;
  --surface-2:#1B2230;
  --line:rgba(255,255,255,.09);
  --line-strong:rgba(255,255,255,.17);

  --ink:#EDF1F7;
  --ink-2:#C2CAD8;
  --ink-3:#94A0B3;
  --ink-4:#94A0B3;

  --ground:#080B11;
  --ground-2:#0B0F16;
  --ground-lift:#151B26;
  --on-ground:#C2CAD8;

  /* Accents : le bleu et le violet de la spec, ECLAIRCIS pour le fond
     sombre. #4F46E5 mesure 3,0:1 sur #0B0F16 — sous le seuil. Les valeurs
     ci-dessous passent AA. */
  --accent:#8B93FF;
  --accent-dark:#A5ABFF;
  --accent-2:#A78BFA;
  --violet:#A78BFA;
  --grad:linear-gradient(135deg,#6366F1 0%,#8B5CF6 100%);

  --price:#FFFFFF;
  --success:#4ADE80;
  --warning:#FBBF24;
  --error:#F87171;

  /* Surfaces derivees, jusqu'ici ecrites en dur. */
  --nav-bg:rgba(11,15,22,.86);
  --hover:rgba(255,255,255,.06);
  --accent-wash:rgba(139,147,255,.14);
  --accent-line:rgba(139,147,255,.42);
  --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --shadow-md:0 12px 28px -16px rgba(0,0,0,.7);
  --shadow-lg:0 24px 48px -20px rgba(0,0,0,.8);
  --hero-wash-1:rgba(139,92,246,.16);
  --hero-wash-2:rgba(99,102,241,.16);

  /* LE FOND D'UN CHAMP DE SAISIE — jeton ajoute le 2026-08-30 apres mesure.
     Les champs portaient `background:var(--white)`, alors que --white est
     documente trois lignes plus haut comme « l'encre la plus claire », pas
     une surface. En theme sombre, l'encre du texte saisi (#EDF1F7) tombait
     donc sur un champ #FFFFFF : contraste mesure au navigateur sur
     /checkout/ = 1,13:1. Le client ne voyait PAS ce qu'il tapait dans son
     adresse e-mail — celle a laquelle sa licence doit etre envoyee.
     Le defaut ne se voyait qu'en tapant, ce que ni l'audit ni une relecture
     de maquette ne font. */
  --field:#0E141F;
  --field-ring:rgba(139,147,255,.28);
}

:root[data-theme="light"]{
  --paper:#FFFFFF;
  --shade:#F7F8FC;
  --surface:#FFFFFF;
  --surface-2:#F7F8FC;
  --line:#E5E7EB;
  --line-strong:#D1D5DB;

  --ink:#111827;
  --ink-2:#374151;
  --ink-3:#64748B;
  --ink-4:#64748B;

  --ground:#F7F8FC;
  --ground-2:#FFFFFF;
  --ground-lift:#F7F8FC;
  --on-ground:#64748B;

  --accent:#4F46E5;
  --accent-dark:#4338CA;
  --accent-2:#6366F1;
  --violet:#7C3AED;
  --grad:linear-gradient(135deg,#4F46E5 0%,#7C3AED 100%);

  --price:#111827;
  --success:#16A34A;
  --warning:#F59E0B;
  --error:#DC2626;

  --nav-bg:#FFFFFF;
  --hover:rgba(17,24,39,.05);
  --accent-wash:rgba(79,70,229,.08);
  --accent-line:rgba(79,70,229,.35);
  --shadow-sm:0 1px 2px rgba(17,24,39,.05);
  --shadow-md:0 12px 28px -18px rgba(17,24,39,.25);
  --shadow-lg:0 24px 48px -24px rgba(17,24,39,.3);
  --hero-wash-1:rgba(124,58,237,.07);
  --hero-wash-2:rgba(79,70,229,.07);

  /* En rampe claire le champ est blanc — c'est ce qu'il etait deja, donc
     ce theme ne change pas d'aspect. Seul le sombre est repare. */
  --field:#FFFFFF;
  --field-ring:rgba(79,70,229,.18);
}

:root{
  /* La marque, reprise de hero.mp4 : degrade cyan -> violet. */
  --mark-1:#5CC8F5;
  --mark-2:#9B7BEA;
  --mark-glow:#7FE3FF;

  /* Typographie */
  --font-display:'Fira Sans', 'Segoe UI', system-ui, sans-serif;
  --font-body:'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
  --font-mono:'IBM Plex Mono', ui-monospace, monospace;
  --font-wordmark:'Montserrat', 'Fira Sans', sans-serif;

  /* ECHELLE RABATTUE le 2026-08-29, sur demande client : « pas tres grandes ».
     Les valeurs precedentes venaient de la direction editoriale, ou un titre
     de 8,5rem etait le sujet de la page. Sur une boutique, le sujet est le
     produit : le titre doit ceder la place a la grille. Le display perd 40 %,
     le h1 un tiers, et le corps monte d'un demi-point parce qu'un texte de
     lecture ne se reduit pas avec les titres — c'est le contraire. */
  --fs-display:clamp(2.4rem, 5vw, 4.2rem);
  --fs-h1:clamp(2rem, 3.6vw, 3.2rem);
  --fs-h2:clamp(1.6rem, 2.6vw, 2.3rem);
  --fs-h3:clamp(1.15rem, 1.5vw, 1.4rem);
  --fs-lead:clamp(1rem, 1.1vw, 1.125rem);
  --fs-body:1.0625rem;
  --fs-small:0.875rem;
  --fs-micro:0.75rem;

  /* Rythme */
  --gutter:clamp(1.25rem, 3.5vw, 3rem);
  --section:clamp(3.25rem, 6vw, 5.5rem);
  --max:1320px;
  --measure:64ch;

  /* Mouvement */
  --ease:cubic-bezier(.22,1,.36,1);
  --ease-soft:cubic-bezier(.4,0,.2,1);
  --dur:.6s;

  /* L'en-tete a deux rangs depuis le 2026-08-28.
     --nav-h reste la HAUTEUR TOTALE de l'en-tete, parce que huit regles s'en
     servent deja pour decaler les pages et caler les elements collants
     (.page-head, .shop-bar, .pdp__panel, .cart-summary...). Redefinir ce
     jeton plutot que corriger huit decalages evite d'oublier le huitieme.
     Le rang du haut prend son propre jeton. */
  --nav-row:76px;
  /* 50px de barre + le 1px de bordure basse de l'en-tete. Mesure a l'ecran :
     le total valait 127 quand le jeton en annoncait 125, et deux pixels de
     moins suffisent a faire passer un titre de page sous la barre. */
  --catbar-h:51px;
  --nav-h:calc(var(--nav-row) + var(--catbar-h));
}
/* La barre d'univers disparait sous 900px : la hauteur totale redevient
   celle du seul rang du haut. */
@media (max-width:900px){:root{--catbar-h:0px}}

/* ---------- 2. RESET ---------- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  font-family:var(--font-body);
  font-size:var(--fs-body);
  line-height:1.6;
  color:var(--ink);
  background:var(--paper);
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
img,svg,video{display:block;max-width:100%;height:auto}
button,input,select,textarea{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
a{color:inherit;text-decoration:none}
ul,ol{list-style:none}
table{border-collapse:collapse;width:100%}
::selection{background:var(--ink);color:var(--paper)}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:2px}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}

.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip-link{position:absolute;top:-100px;left:var(--gutter);z-index:9999;background:var(--ink);color:var(--paper);padding:.75rem 1.25rem;font-size:var(--fs-small)}
.skip-link:focus{top:1rem}

/* ---------- 3. TYPOGRAPHIE ---------- */
/* La graisse passe de 300 a 600/700 : une lineale en 300 a la taille d'un
   titre de hero se delave, la ou un Cormorant 300 tenait par son contraste
   de plein et delie. Changer la police sans changer la graisse aurait donne
   un titre fantome. */
.display,.h1,.h2,.h3{font-family:var(--font-display);font-weight:700;letter-spacing:-.03em;line-height:1.06}
.display{font-size:var(--fs-display);line-height:1.02}
.h1{font-size:var(--fs-h1)}
.h2{font-size:var(--fs-h2);line-height:1.1;font-weight:600}
.h3{font-size:var(--fs-h3);line-height:1.2;letter-spacing:-.015em;font-weight:600}
.serif-italic{font-style:normal;color:var(--accent)}

.eyebrow{font-family:var(--font-mono);font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.14em;font-weight:500;color:var(--accent)}
.eyebrow--accent{color:var(--accent)}
.lead{font-size:var(--fs-lead);line-height:1.6;color:var(--ink-3);font-weight:400;max-width:54ch}
.body-text{color:var(--ink-2);max-width:var(--measure)}
.body-text p+p{margin-top:1.1em}
/* Le soulignement des liens de prose NE DOIT PAS ATTEINDRE LES BOUTONS.
   `.body-text a` pese (0,1,1) et l'emporte donc sur `.btn--primary` (0,1,0) :
   la propriete `background-image` du bouton etait remplacee par ce degrade de
   `currentColor`, et comme la forme abregee `background:var(--grad)` avait
   deja mis la couleur de fond a transparent, il restait un bouton
   TRANSPARENT AVEC DU TEXTE BLANC — invisible. Constate sur la page de
   confirmation de commande, ou le bouton « View my orders » ne se voyait pas.
   Le defaut touchait tout bouton place dans du contenu de page. */
.body-text a:not(.btn):not(.link-underline){background-image:linear-gradient(currentColor,currentColor);background-size:100% 1px;background-position:0 100%;background-repeat:no-repeat}
.small{font-size:var(--fs-small);color:var(--ink-3)}
.num{font-variant-numeric:tabular-nums;letter-spacing:-.01em}

/* ---------- 4. PRIMITIVES ---------- */
.shell{max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter);width:100%}
.shell--narrow{max-width:1180px}
.shell--text{max-width:780px}
.section{padding-block:var(--section)}
.section--tight{padding-block:clamp(3.5rem,7vw,6rem)}
.section--shade{background:var(--shade)}
.section--white{background:var(--white)}
.section--deep{background:var(--ground);color:var(--white)}
.section--deep .lead,.section--deep .small,.section--deep .eyebrow,.section--deep .body-text{color:rgba(255,255,255,.66)}
.rule{height:1px;background:var(--line);border:0}

.section-head{display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;margin-bottom:clamp(2.5rem,5vw,4.5rem);flex-wrap:wrap}
.section-head__title{max-width:20ch}
.section-head .lead{max-width:38ch}

/* Boutons */
/* BOUTONS — l'action passe de l'encre au bleu.
   Les capitales et le .12em d'interlettrage venaient de la direction
   editoriale ; sur une boutique ils ralentissent la lecture d'un bouton
   qu'on doit reconnaitre sans le lire. Casse normale, graisse 600. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  padding:.95rem 1.9rem;
  font-family:var(--font-display);
  font-size:.9375rem;font-weight:600;
  letter-spacing:0;text-transform:none;
  border:1.5px solid var(--accent);border-radius:6px;
  background:var(--accent);color:var(--white);
  position:relative;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.btn:hover{background:var(--accent-dark);border-color:var(--accent-dark);color:var(--white)}
.btn--ghost{background:transparent;color:var(--accent)}
.btn--ghost:hover{background:var(--accent);color:var(--white)}
/* Sur le sol profond du hero : fond blanc, texte quasi-noir. Le bleu de
   l'action ne se detache pas assez sur un fond sombre pour porter le CTA
   principal ; le blanc plein, si. */
.btn--light{background:var(--white);color:var(--ground);border-color:var(--white)}
.btn--light:hover{background:transparent;color:var(--white);border-color:var(--white)}
.btn--outline-light{background:transparent;color:var(--paper);border-color:rgba(255,255,255,.4)}
.btn--outline-light:hover{background:var(--paper);color:var(--ink);border-color:var(--paper)}
.btn--block{width:100%}
.btn[disabled]{opacity:.4;pointer-events:none}
.btn svg{width:16px;height:16px;flex-shrink:0}

.link-underline{
  display:inline-flex;align-items:center;gap:.6rem;
  font-size:var(--fs-small);letter-spacing:.1em;text-transform:uppercase;font-weight:500;
  padding-bottom:.35rem;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:100% 1px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size .5s var(--ease);
}
.link-underline:hover{background-size:0% 1px}
.link-underline svg{width:14px;height:14px;transition:transform .5s var(--ease)}
.link-underline:hover svg{transform:translateX(5px)}

.tag{display:inline-flex;align-items:center;gap:.5rem;font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.18em;color:var(--ink-3)}
.tag__dot{width:5px;height:5px;border-radius:50%;background:var(--success);flex-shrink:0}
.badge{
  position:absolute;top:1rem;left:1rem;z-index:2;
  font-size:var(--fs-micro);text-transform:uppercase;letter-spacing:.16em;font-weight:500;
  background:var(--paper);color:var(--ink);padding:.4rem .7rem;
}
.badge--ink{background:var(--ink);color:var(--paper)}

/* Media */
.media{position:relative;overflow:hidden;background:var(--shade)}
.media img,.media video{width:100%;height:100%;object-fit:cover;display:block}
.media--4x5{aspect-ratio:4/5}
.media--1x1{aspect-ratio:1/1}
.media--3x4{aspect-ratio:3/4}
.media--16x9{aspect-ratio:16/9}
.media--16x10{aspect-ratio:16/10}
.media__zoom{transition:transform 1.2s var(--ease)}
a:hover .media__zoom,.card:hover .media__zoom,.product-card:hover .media__zoom{transform:scale(1.04)}

/* ---------- 5. CHROME ---------- */
.scroll-progress{position:fixed;top:0;left:0;height:1px;width:100%;background:var(--ink);z-index:200;transform:scaleX(0);transform-origin:0 50%}

.toast{
  position:fixed;left:50%;bottom:2rem;z-index:9999;
  transform:translate(-50%,180%);
  background:var(--ink);color:var(--paper);
  padding:1rem 1.75rem;font-size:var(--fs-small);
  display:flex;align-items:center;gap:.75rem;
  transition:transform .6s var(--ease);
  max-width:calc(100vw - 2rem);
}
.toast.is-visible{transform:translate(-50%,0)}
.toast svg{width:16px;height:16px}

/* ---------- 6. NAVIGATION ---------- */
/* L'en-tete tient DEUX rangs : l'entete proprement dite et la barre d'univers.
   La barre est a l'interieur du <header> fixe, pas apres lui : posee dans le
   flux sous un en-tete `position:fixed`, elle se serait glissee DERRIERE lui,
   puisqu'un element fixe ne reserve aucune place dans le flux. */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:120;
  display:block;
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background .5s var(--ease-soft),border-color .5s var(--ease-soft),color .5s var(--ease-soft),transform .5s var(--ease);
}
.nav__inner{height:var(--nav-row);display:flex;align-items:center;justify-content:space-between;gap:2rem;width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter)}

/* ---------- barre d'univers ---------- */
.catbar{border-top:1px solid rgba(255,255,255,.16)}
.catbar__inner{display:flex;gap:.25rem;width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter);overflow-x:auto;scrollbar-width:none}
.catbar__inner::-webkit-scrollbar{display:none}
.catbar__link{display:flex;align-items:center;gap:.55rem;padding:.85rem 1rem;font-size:var(--fs-small);font-weight:500;white-space:nowrap;border-bottom:2px solid transparent}
.catbar__link svg{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.5}
.catbar__link:hover,.catbar__link[aria-current]{color:var(--accent);border-bottom-color:var(--accent)}
.nav.is-over-dark .catbar__link:hover,.nav.is-over-dark .catbar__link[aria-current]{color:var(--mark-glow);border-bottom-color:var(--mark-glow)}
.nav:not(.is-scrolled):not(.is-over-dark) .catbar{border-top-color:var(--line)}
@media (max-width:900px){.catbar{display:none}}
.nav.is-scrolled{background:rgba(255,255,255,.88);backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);border-bottom-color:var(--line)}
.nav.is-hidden{transform:translateY(-100%)}
.nav.is-over-dark{color:var(--white)}
.nav.is-over-dark.is-scrolled{background:rgba(7,9,13,.82);border-bottom-color:rgba(255,255,255,.12);color:var(--white)}

/* La marque porte son propre degrade. La regle qui suivait forcait
   `stroke:currentColor; fill:none` sur tous ses `path` : elle aurait repeint
   le degrade en encre unie et efface la fleche pleine. Elle est retiree, pas
   surchargee — une regle qu'on neutralise ailleurs revient toujours. */
.logo{display:inline-flex;align-items:center;gap:.62rem;font-family:var(--font-wordmark);font-weight:800;font-size:1.3rem;letter-spacing:.05em;text-transform:uppercase;line-height:1}
.logo__mark{width:30px;height:30px;flex-shrink:0}

.nav__menu{display:flex;align-items:center;gap:clamp(1rem,2.2vw,2.4rem)}
.nav__link{
  font-size:var(--fs-small);letter-spacing:.06em;position:relative;padding:.4rem 0;
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size .45s var(--ease),opacity .3s;
}
.nav__link:hover,.nav__link[aria-current="page"]{background-size:100% 1px}
.nav__actions{display:flex;align-items:center;gap:1.25rem}
.nav__icon{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;position:relative}
.nav__icon svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.4}
.nav__count{
  position:absolute;top:1px;right:0;
  min-width:16px;height:16px;padding:0 4px;
  background:var(--ink);color:var(--paper);
  border-radius:9px;font-size:10px;font-weight:600;
  display:flex;align-items:center;justify-content:center;
  transform:scale(0);transition:transform .4s var(--ease);
}
.nav.is-over-dark .nav__count{background:var(--paper);color:var(--ink)}
.nav__count.is-visible{transform:scale(1)}
.nav__burger{display:none;width:34px;height:34px;flex-direction:column;justify-content:center;gap:5px;align-items:center}
.nav__burger span{display:block;width:19px;height:1px;background:currentColor;transition:transform .4s var(--ease),opacity .3s}
body.menu-open .nav__burger span:nth-child(1){transform:translateY(3px) rotate(45deg)}
body.menu-open .nav__burger span:nth-child(2){opacity:0}
body.menu-open .nav__burger span:nth-child(3){transform:translateY(-3px) rotate(-45deg)}

/* Menu plein écran */
.menu{
  position:fixed;inset:0;z-index:110;
  background:var(--paper);
  display:flex;flex-direction:column;
  padding:calc(var(--nav-h) + 2rem) var(--gutter) 2.5rem;
  clip-path:inset(0 0 100% 0);
  transition:clip-path .8s var(--ease);
  overflow-y:auto;
  visibility:hidden;
}
.menu.is-open{clip-path:inset(0 0 0 0);visibility:visible}
.menu__list{margin-top:auto;margin-bottom:auto}
.menu__item{overflow:hidden;border-bottom:1px solid var(--line)}
.menu__link{
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  font-family:var(--font-display);font-weight:300;
  font-size:clamp(2.2rem,10vw,3.4rem);line-height:1;
  padding:.55em 0;
  transform:translateY(110%);
}
.menu.is-open .menu__link{transform:translateY(0);transition:transform .8s var(--ease)}
.menu__link span{font-family:var(--font-body);font-size:var(--fs-micro);letter-spacing:.2em;color:var(--ink-3);text-transform:uppercase}
.menu__foot{display:flex;justify-content:space-between;gap:1.5rem;flex-wrap:wrap;padding-top:2rem;border-top:1px solid var(--line)}

/* Recherche */
.search-panel{
  position:fixed;inset:0;z-index:130;background:rgba(255,255,255,.97);
  backdrop-filter:blur(10px);
  padding:calc(var(--nav-h) + 8vh) var(--gutter) 2rem;
  opacity:0;visibility:hidden;transition:opacity .4s var(--ease-soft),visibility .4s;
}
.search-panel.is-open{opacity:1;visibility:visible}
.search-panel__form{max-width:900px;margin-inline:auto;border-bottom:1px solid var(--ink);display:flex;align-items:center;gap:1rem;padding-bottom:1rem}
.search-panel__input{flex:1;border:0;background:none;font-family:var(--font-display);font-size:clamp(1.8rem,5vw,3rem);font-weight:300;outline:none}
.search-panel__results{max-width:900px;margin:2.5rem auto 0;display:grid;gap:.25rem}
.search-result{display:flex;justify-content:space-between;gap:1rem;padding:1rem 0;border-bottom:1px solid var(--line);align-items:center}
.search-result:hover{padding-inline:.5rem;transition:padding .35s var(--ease)}
.search-close{position:absolute;top:calc(var(--nav-row)/2);right:var(--gutter);transform:translateY(-50%)}

/* ---------- 7. HERO ---------- */
/* HERO — grand, sur sol profond quasi-noir, en deux colonnes.
   Le plein ecran est conserve mais PLAFONNE a 860 px : sur un ecran 27 pouces
   un hero de 1440 px de haut repousse le premier produit sous la ligne de
   flottaison, ce qu'une boutique ne peut pas se permettre. */
.hero{position:relative;min-height:min(82svh,640px);display:flex;align-items:center;overflow:hidden;
  background:radial-gradient(120% 100% at 78% 20%,var(--ground-lift) 0%,rgba(7,9,13,0) 62%),var(--ground)}
.hero__media{position:absolute;inset:0;z-index:0}
.hero__media img,.hero__media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.30}
.hero__media video{z-index:1}
/* Quand un film est present, il devient le sujet du fond : opacite relevee
   et voile allege a droite, la ou le texte ne passe pas. A 30 % sous un
   voile a 92 %, on payait un film pour ne pas le voir. */
.hero.has-film .hero__media img,.hero.has-film .hero__media video{opacity:.62}
.hero.has-film .hero__media::after{background:linear-gradient(90deg,rgba(7,9,13,.90) 0%,rgba(7,9,13,.62) 38%,rgba(7,9,13,.22) 72%,rgba(7,9,13,.10) 100%)}
/* Le decor de circuit s'efface : film, traces et carte se disputaient le
   meme cadre. La carte reste, elle porte le produit. */
.hero.has-film .hero__decor{display:none}
/* La carte de licence disparait aussi : le film porte deja la marque et le
   mot DIGISOVIA en grand a droite, exactement la ou la carte se posait. Deux
   fois le meme logo dans le meme cadre, c'est une redondance, pas un rappel.
   Le hero repasse donc sur une colonne, le texte a gauche, le film derriere. */
.hero.has-film .hero__art{display:none}
.hero.has-film .hero__inner{grid-template-columns:minmax(0,1fr);max-width:min(var(--max),980px)}
.hero.has-film .hero__title{max-width:18ch}
.hero__media::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(7,9,13,.92) 0%,rgba(7,9,13,.55) 55%,rgba(7,9,13,.3) 100%)}
/* Decor anime : les traces de circuit qui convergent vers la marque.
   Il remplace hero.mp4 tant que le quota de generation n'est pas retabli,
   et reste dessous quand la video revient. */
.hero__decor{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1}
.hero__inner{position:relative;z-index:2;width:100%;max-width:var(--max);margin-inline:auto;
  padding:clamp(2.75rem,6vh,4.25rem) var(--gutter);color:var(--white);
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:clamp(2rem,5vw,4.5rem);align-items:center}
.hero__eyebrow{color:var(--mark-glow);margin-bottom:clamp(1rem,2.4vw,1.5rem)}
.hero__title{color:var(--white);max-width:15ch}
.hero__title .accent{color:var(--mark-glow)}
.hero__row{display:flex;flex-direction:column;align-items:flex-start;gap:2rem;margin-top:clamp(1.25rem,3vw,2rem)}
.hero__lead{color:var(--on-ground);max-width:46ch}
.hero__cta{display:flex;gap:1rem;flex-wrap:wrap;align-items:center}
.hero__art{display:grid;place-items:center}
.hero__art svg{width:min(100%,360px);height:auto;filter:drop-shadow(0 40px 60px rgba(0,0,0,.45))}
.hero__points{display:flex;flex-wrap:wrap;gap:.6rem 1.8rem;margin-top:.5rem;font-size:var(--fs-small);color:var(--on-ground)}
.hero__points li{display:flex;gap:.55rem;align-items:center}
.hero__points svg{width:16px;height:16px;flex:none;stroke:var(--mark-glow);fill:none;stroke-width:2}
@media (max-width:900px){
  .hero__inner{grid-template-columns:1fr}
  .hero__art{order:-1}
  .hero__art svg{width:min(72%,320px)}
}
.hero__scroll{position:absolute;bottom:clamp(3rem,7vh,6rem);right:var(--gutter);z-index:2;display:flex;flex-direction:column;align-items:center;gap:.75rem;color:rgba(255,255,255,.7);font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase}
.hero__scroll-line{width:1px;height:56px;background:rgba(255,255,255,.3);position:relative;overflow:hidden}
.hero__scroll-line::after{content:'';position:absolute;inset:0;background:var(--paper);transform:translateY(-100%);animation:scrollLine 2.4s var(--ease-soft) infinite}
@keyframes scrollLine{0%{transform:translateY(-100%)}55%{transform:translateY(0)}100%{transform:translateY(100%)}}

/* Masque de révélation ligne par ligne */
.line-mask{display:block;overflow:hidden}
.line-mask>span{display:block;will-change:transform}

/* ---------- 8. SCROLL CINÉMATIQUE ---------- */
.scrollstage{position:relative;background:var(--ground-2);color:var(--white)}
.scrollstage__sticky{position:sticky;top:0;height:100svh;overflow:hidden;display:flex;align-items:center;justify-content:center}
.scrollstage__media{position:absolute;inset:0}
.scrollstage__media video,.scrollstage__media canvas,.scrollstage__media img{width:100%;height:100%;object-fit:cover}
.scrollstage__media::after{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at 50% 50%,rgba(7,9,13,.15),rgba(7,9,13,.78))}
.scrollstage__captions{position:relative;z-index:2;text-align:center;max-width:900px;padding-inline:var(--gutter)}
.scrollstage__caption{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:100%;opacity:0}
.scrollstage__caption:first-child{position:relative;left:auto;top:auto;transform:none}
.scrollstage__caption h2{color:var(--paper)}
.scrollstage__caption p{color:rgba(255,255,255,.7);margin-top:1.25rem;font-size:var(--fs-lead);font-weight:300}
.scrollstage__spacer{height:300vh}
.scrollstage__progress{position:absolute;bottom:clamp(2rem,5vh,4rem);left:50%;transform:translateX(-50%);width:min(320px,40vw);height:1px;background:rgba(255,255,255,.22);z-index:3}
.scrollstage__progress span{display:block;height:100%;background:var(--paper);transform-origin:0 50%;transform:scaleX(0)}

/* ---------- 9. GRILLE ÉDITORIALE / CATÉGORIES ---------- */
.editorial-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(1rem,2vw,2rem) clamp(1rem,2vw,2rem)}
.tile{position:relative;display:block;overflow:hidden}
.tile__media{position:relative;overflow:hidden;background:var(--shade)}
.tile__media img{width:100%;height:100%;object-fit:cover;transition:transform 1.2s var(--ease)}
.tile:hover .tile__media img{transform:scale(1.045)}
.tile__body{padding-top:1.1rem;display:flex;justify-content:space-between;align-items:baseline;gap:1rem;border-top:1px solid var(--line);margin-top:1.1rem}
.tile__title{font-family:var(--font-display);font-size:clamp(1.5rem,2.6vw,2.3rem);font-weight:300;line-height:1.05}
.tile__meta{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
.tile--half{grid-column:span 6}
.tile--third{grid-column:span 4}
.tile--quarter{grid-column:span 3}
.tile--wide{grid-column:span 8}
.tile--offset{margin-top:clamp(2rem,7vw,6rem)}
.tile--half .tile__media{aspect-ratio:4/3}
.tile--third .tile__media{aspect-ratio:4/3}
.tile--quarter .tile__media{aspect-ratio:4/3}
.tile--wide .tile__media{aspect-ratio:16/9}

/* ---------- 10. CARTE PRODUIT ---------- */
.product-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:clamp(1.5rem,3vw,3rem) clamp(1rem,2vw,2rem)}
.product-card{position:relative;display:flex;flex-direction:column}
.product-card__media{position:relative;overflow:hidden;background:var(--shade);aspect-ratio:1/1}
.product-card__media img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--ease),opacity .6s var(--ease)}
.product-card__media img.is-alt{position:absolute;inset:0;opacity:0}
.product-card:hover .product-card__media img.is-main{opacity:0}
.product-card:hover .product-card__media img.is-alt{opacity:1;transform:scale(1.04)}
.product-card__quick{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  background:var(--ink);color:var(--paper);
  font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;font-weight:500;
  padding:1rem;text-align:center;
  transform:translateY(101%);
  transition:transform .5s var(--ease);
}
.product-card:hover .product-card__quick,.product-card:focus-within .product-card__quick{transform:translateY(0)}
.product-card__body{padding-top:1.1rem;display:flex;flex-direction:column;gap:.35rem}
.product-card__cat{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3)}
.product-card__name{font-size:1rem;font-weight:500;letter-spacing:-.01em}
.product-card__name a::after{content:'';position:absolute;inset:0;z-index:2}
.product-card__price{display:flex;align-items:baseline;gap:.6rem;margin-top:.15rem}
.product-card__price .now{font-size:1.15rem;font-weight:700;font-family:var(--font-display);color:var(--price);font-variant-numeric:tabular-nums}
.product-card__price .was{font-size:var(--fs-small);color:var(--ink-4);text-decoration:line-through}
.product-card__price .off{font-size:var(--fs-micro);letter-spacing:.08em;color:var(--white);background:var(--price);padding:.15rem .4rem;border-radius:3px;text-transform:uppercase}

/* ---------- 11. PILIERS / VALEURS ---------- */
.pillars{display:grid;grid-template-columns:repeat(4,1fr);gap:0;border-top:1px solid var(--line)}
.pillar{padding:clamp(2rem,3.5vw,3.5rem) clamp(1.25rem,2.5vw,2.5rem);border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
.pillar:last-child{border-right:0}
.pillar__num{font-size:var(--fs-micro);letter-spacing:.2em;color:var(--ink-4);margin-bottom:2.5rem;display:block}
.pillar__icon{width:26px;height:26px;stroke:var(--ink);fill:none;stroke-width:1.1;margin-bottom:1.5rem}
.pillar h3{font-family:var(--font-display);font-size:1.5rem;font-weight:400;margin-bottom:.6rem;line-height:1.15}
.pillar p{font-size:var(--fs-small);color:var(--ink-3);line-height:1.65}

/* ---------- 12. STORYTELLING ---------- */
.split{display:grid;grid-template-columns:1.05fr .95fr;align-items:center;gap:clamp(2rem,6vw,7rem)}
.split--reverse .split__media{order:2}
.split__media{position:relative;overflow:hidden}
.split__body{max-width:46ch}
.split__body .h2{margin-bottom:1.75rem}
.reveal-clip{clip-path:inset(0 0 100% 0)}

/* ---------- 13. BANNIÈRE PLEIN ÉCRAN ---------- */
.statement{position:relative;min-height:56svh;display:flex;align-items:center;justify-content:center;text-align:center;overflow:hidden;background:var(--ground-2);color:var(--white)}
.statement__media{position:absolute;inset:0}
.statement__media img,.statement__media video{width:100%;height:100%;object-fit:cover;opacity:.62}
.statement__inner{position:relative;z-index:2;padding:var(--section) var(--gutter)}
.statement__title{color:var(--paper);font-size:clamp(2.6rem,7.5vw,6.5rem);max-width:16ch;margin-inline:auto}

/* ---------- 14. AVIS ---------- */
.reviews-rail{display:flex;gap:clamp(1.25rem,2.5vw,2.5rem);overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:1.5rem;scrollbar-width:none;-ms-overflow-style:none}
.reviews-rail::-webkit-scrollbar{display:none}
.review{flex:0 0 min(420px,82vw);scroll-snap-align:start;border-top:1px solid var(--line);padding-top:1.5rem;display:flex;flex-direction:column;gap:1.1rem}
.review__stars{display:flex;gap:3px}
.review__stars svg{width:13px;height:13px;fill:var(--ink)}
.review__text{font-family:var(--font-display);font-size:clamp(1.25rem,2vw,1.6rem);font-weight:300;line-height:1.35}
.review__who{margin-top:auto;font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3)}
.rail-nav{display:flex;gap:.6rem}
.rail-nav button{width:44px;height:44px;border:1px solid var(--line-strong);display:flex;align-items:center;justify-content:center;transition:background .4s var(--ease),color .4s var(--ease),border-color .4s}
.rail-nav button:hover{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.rail-nav svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.5}
.demo-note{font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-4);border:1px dashed var(--line-strong);padding:.5rem .8rem;display:inline-block}

/* ---------- 15. ACCORDÉON / FAQ ---------- */
.accordion{border-top:1px solid var(--line)}
.accordion__item{border-bottom:1px solid var(--line)}
.accordion__trigger{
  width:100%;display:flex;justify-content:space-between;align-items:center;gap:2rem;
  padding:clamp(1.35rem,2.5vw,2rem) 0;text-align:left;
  font-family:var(--font-display);font-size:clamp(1.2rem,2vw,1.65rem);font-weight:300;line-height:1.25;
  transition:padding-left .45s var(--ease);
}
.accordion__trigger:hover{padding-left:.6rem}
.accordion__sign{position:relative;width:14px;height:14px;flex-shrink:0}
.accordion__sign::before,.accordion__sign::after{content:'';position:absolute;background:var(--ink);transition:transform .45s var(--ease)}
.accordion__sign::before{top:50%;left:0;width:14px;height:1px;transform:translateY(-50%)}
.accordion__sign::after{left:50%;top:0;width:1px;height:14px;transform:translateX(-50%)}
.accordion__item.is-open .accordion__sign::after{transform:translateX(-50%) scaleY(0)}
.accordion__panel{overflow:hidden;height:0}
.accordion__panel-inner{padding-bottom:2rem;max-width:64ch;color:var(--ink-2);font-size:.95rem;line-height:1.75}

/* ---------- 16. FOOTER ---------- */
/* GARDE-FOU DE CONTRASTE, pose le 2026-08-30 avec la bascule en quasi-noir.

   La classe .eyebrow est peinte en --accent (#2252D1). Mesure sur le sol :
   3,03:1 sur --ground et 2,88:1 sur --ground-2, pour un texte de 0,75rem en
   majuscules — donc sous le seuil AA, et sous le seuil tout court pour du
   petit texte. Aucun eyebrow ne se trouve aujourd'hui dans une section
   sombre (verifie gabarit par gabarit : celui du hero et celui du statement
   sont deja surcharges). Cette regle existe pour le PROCHAIN, celui qu'on
   ajoutera sans repenser au contraste.

   --mark-glow mesure 13,60:1 sur --ground. */
.section--deep .eyebrow,
.statement .eyebrow,
.scrollstage .eyebrow,
.footer .eyebrow{color:var(--mark-glow)}

.footer{background:var(--ground);color:var(--white);padding-top:clamp(4rem,8vw,7rem)}
.footer a{color:rgba(255,255,255,.72);transition:color .35s}
.footer a:hover{color:var(--paper)}
/* QUATRE colonnes de liens, plus la marque : la colonne « Legal » ajoutee
   pour l'audit portait le total a cinq, et la grille en annoncait quatre.
   Une colonne de trop dans une grille figee ne deborde pas — elle se
   tasse en silence et le dernier lien passe a la ligne mot par mot. */
.footer__top{display:grid;grid-template-columns:1.4fr repeat(4,1fr);gap:clamp(1.5rem,3vw,3rem);padding-bottom:clamp(3rem,6vw,5rem)}
.footer__brand .logo{margin-bottom:1.5rem}
.footer__brand p{color:rgba(255,255,255,.55);font-size:var(--fs-small);max-width:34ch;line-height:1.7}
.footer__col h4{font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.45);margin-bottom:1.5rem;font-weight:500}
.footer__col li+li{margin-top:.85rem}
.footer__col a{font-size:var(--fs-small)}
.newsletter{border-top:1px solid rgba(255,255,255,.12);border-bottom:1px solid rgba(255,255,255,.12);padding-block:clamp(2.5rem,5vw,4rem);display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,5rem);align-items:center}
.newsletter h3{font-family:var(--font-display);font-size:clamp(1.8rem,3.5vw,2.8rem);font-weight:300;line-height:1.1;color:var(--paper)}
.newsletter__form{display:flex;gap:1rem;border-bottom:1px solid rgba(255,255,255,.3);padding-bottom:.9rem;align-items:center}
.newsletter__form input{flex:1;background:none;border:0;color:var(--paper);font-size:.95rem;outline:none}
.newsletter__form input::placeholder{color:rgba(255,255,255,.4)}
.newsletter__form button{font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;color:var(--paper);white-space:nowrap}
.footer__bottom{display:flex;justify-content:space-between;gap:1.5rem;flex-wrap:wrap;padding-block:2rem;font-size:var(--fs-micro);letter-spacing:.1em;color:rgba(255,255,255,.45);text-transform:uppercase}
.footer__social{display:flex;gap:1.5rem}

/* ---------- Moyens de paiement acceptes ---------- */
/* LA PLAQUE EST CLAIRE DANS LES DEUX THEMES, ET C'EST VOULU. Visa,
   Mastercard et Amex sont dessines pour un fond blanc : poses directement
   sur le pied sombre ils perdent leur lisibilite et, pour Mastercard, leurs
   couleurs officielles. Chaque marque recoit donc sa propre plaque, ce qui
   transforme l'accident en intention — le meme raisonnement que --ds-plate
   dans l'ancien theme. */
.footer__pay{display:flex;align-items:center;gap:1rem 1.5rem;flex-wrap:wrap;
  padding-block:1.75rem;border-top:1px solid rgba(255,255,255,.12)}
.footer__pay-label{font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.45)}
.footer__pay-list{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin:0;padding:0;list-style:none}
.footer__pay-list li{display:flex}
.footer__pay-list img{display:block;height:26px;width:auto;border-radius:4px;
  background:#FFFFFF;padding:3px 5px;box-shadow:0 1px 2px rgba(0,0,0,.18)}
.footer__pay-note{display:inline-flex;align-items:center;gap:.5rem;margin-left:auto;
  font-size:var(--fs-micro);letter-spacing:.06em;text-transform:none;color:rgba(255,255,255,.55)}
.footer__pay-note svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
@media (max-width:640px){
  .footer__pay-note{margin-left:0;flex-basis:100%}
}

/* ---------- 17. FIL D'ARIANE / EN-TÊTES DE PAGE ---------- */
.page-head{padding-top:calc(var(--nav-h) + clamp(3rem,8vw,7rem));padding-bottom:clamp(2.5rem,5vw,4.5rem)}
.page-head--center{text-align:center}
.page-head--center .lead{margin-inline:auto}
.page-head__title{margin-block:1.25rem}
.breadcrumb{display:flex;gap:.6rem;align-items:center;font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-4);flex-wrap:wrap}
.breadcrumb a:hover{color:var(--ink)}
.breadcrumb span[aria-current]{color:var(--ink-2)}

/* ---------- 18. BOUTIQUE : filtres et tri ---------- */
.shop-bar{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap;padding-block:1.25rem;border-block:1px solid var(--line);position:sticky;top:var(--nav-h);background:var(--paper);z-index:60}
.filter-row{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}
.chip{
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  padding:.55rem 1.05rem;border:1px solid var(--line-strong);color:var(--ink-3);
  transition:background .35s var(--ease),color .35s var(--ease),border-color .35s var(--ease);
  white-space:nowrap;
}
.chip:hover{border-color:var(--ink);color:var(--ink)}
.chip.is-active{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.select-wrap{position:relative;display:inline-flex;align-items:center}
.select-wrap select{appearance:none;background:none;border:0;border-bottom:1px solid var(--line-strong);padding:.5rem 1.75rem .5rem 0;font-size:var(--fs-small);cursor:pointer;outline:none}
.select-wrap svg{position:absolute;right:0;width:12px;height:12px;stroke:var(--ink-3);fill:none;stroke-width:1.5;pointer-events:none}
.shop-count{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.shop-empty{padding:clamp(3rem,8vw,6rem) 0;text-align:center;color:var(--ink-3)}
.load-more-wrap{display:flex;justify-content:center;margin-top:clamp(3rem,6vw,5rem)}

/* ---------- 19. PAGE PRODUIT ---------- */
.pdp{display:grid;grid-template-columns:1.25fr .75fr;gap:clamp(2rem,5vw,6rem);align-items:start;padding-top:1rem}
.pdp__gallery{display:grid;gap:clamp(.75rem,1.5vw,1.25rem)}
.pdp__figure{position:relative;overflow:hidden;background:var(--white);cursor:zoom-in}
.pdp__figure img{width:100%;height:100%;object-fit:cover}
.pdp__figure--main{aspect-ratio:1/1}
.pdp__thumbs{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(.75rem,1.5vw,1.25rem)}
.pdp__thumbs .pdp__figure{aspect-ratio:1/1}
.pdp__panel{position:sticky;top:calc(var(--nav-h) + 2rem)}
.pdp__title{margin-block:.75rem 1rem}
.pdp__price{display:flex;align-items:baseline;gap:1rem;flex-wrap:wrap;margin-bottom:.5rem}
.pdp__price .now{font-size:2.25rem;font-family:var(--font-display);font-weight:700;color:var(--price);font-variant-numeric:tabular-nums}
.pdp__price .was{color:var(--ink-4);text-decoration:line-through}
.pdp__price .off{font-size:var(--fs-micro);letter-spacing:.08em;text-transform:uppercase;color:var(--white);background:var(--price);padding:.2rem .5rem;border-radius:3px}
.pdp__vat{font-size:var(--fs-micro);color:var(--ink-4);letter-spacing:.1em;text-transform:uppercase}
.pdp__options{margin-top:2rem;display:grid;gap:1.5rem}
.option__label{display:flex;justify-content:space-between;font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);margin-bottom:.75rem}
.option__row{display:flex;gap:.5rem;flex-wrap:wrap}
.option__btn{border:1px solid var(--line-strong);padding:.75rem 1.1rem;font-size:var(--fs-small);transition:border-color .35s,background .35s,color .35s}
.option__btn:hover{border-color:var(--ink)}
.option__btn.is-active{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.qty{display:inline-flex;align-items:center;border:1px solid var(--line-strong)}
.qty button{width:44px;height:46px;font-size:1rem;color:var(--ink-3);transition:color .3s}
.qty button:hover{color:var(--ink)}
.qty input{width:44px;height:46px;text-align:center;border:0;background:none;font-variant-numeric:tabular-nums;outline:none}
.pdp__buy{margin-top:2rem;display:grid;gap:.75rem}
.pdp__assurances{margin-top:2rem;border-top:1px solid var(--line);padding-top:1.5rem;display:grid;gap:.9rem}
.assurance{display:flex;gap:.75rem;align-items:flex-start;font-size:var(--fs-small);color:var(--ink-2)}
.assurance svg{width:16px;height:16px;stroke:var(--ink);fill:none;stroke-width:1.3;flex-shrink:0;margin-top:.25rem}

.tabs__nav{display:flex;gap:2.5rem;border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
.tabs__nav::-webkit-scrollbar{display:none}
.tabs__btn{
  padding:1.1rem 0;font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);
  position:relative;white-space:nowrap;transition:color .35s;
}
.tabs__btn::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background:var(--ink);transform:scaleX(0);transform-origin:0 50%;transition:transform .5s var(--ease)}
.tabs__btn:hover{color:var(--ink)}
.tabs__btn.is-active{color:var(--ink)}
.tabs__btn.is-active::after{transform:scaleX(1)}
.tabs__panel{display:none;padding-top:clamp(2.5rem,5vw,4rem)}
.tabs__panel.is-active{display:block}
.specs-table td{padding:1.15rem 0;border-bottom:1px solid var(--line);font-size:.95rem;vertical-align:top}
.specs-table td:first-child{color:var(--ink-3);width:38%;font-size:var(--fs-small);letter-spacing:.06em}
.feature-list{display:grid;gap:1rem}
.feature-list li{display:flex;gap:.85rem;align-items:flex-start;color:var(--ink-2);font-size:.95rem}
.feature-list svg{width:15px;height:15px;stroke:var(--ink);fill:none;stroke-width:1.6;flex-shrink:0;margin-top:.35rem}
.score{display:flex;align-items:baseline;gap:.5rem}
.score__value{font-family:var(--font-display);font-size:3.5rem;font-weight:300;line-height:1}
.bar{display:flex;align-items:center;gap:.9rem;margin-bottom:.6rem}
.bar__label{font-size:var(--fs-micro);color:var(--ink-3);width:22px}
.bar__track{flex:1;height:2px;background:var(--line)}
.bar__fill{height:100%;background:var(--ink);transform-origin:0 50%}
.bar__count{font-size:var(--fs-micro);color:var(--ink-4);width:32px;text-align:right}

/* Lightbox */
.lightbox{position:fixed;inset:0;z-index:9997;background:rgba(255,255,255,.98);display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:opacity .45s var(--ease-soft),visibility .45s}
.lightbox.is-open{opacity:1;visibility:visible}
.lightbox__img{max-width:min(92vw,1100px);max-height:86vh;object-fit:contain}
.lightbox__close{position:absolute;top:2rem;right:var(--gutter)}
.lightbox__nav{position:absolute;top:50%;transform:translateY(-50%);width:48px;height:48px;border:1px solid var(--line-strong);display:flex;align-items:center;justify-content:center;background:var(--paper)}
.lightbox__nav svg{width:16px;height:16px;stroke:var(--ink);fill:none;stroke-width:1.4}
.lightbox__nav.prev{left:var(--gutter)}
.lightbox__nav.next{right:var(--gutter)}

/* ---------- 20. PANIER ---------- */
.cart-layout{display:grid;grid-template-columns:1.5fr .8fr;gap:clamp(2rem,5vw,5rem);align-items:start}
.cart-line{display:grid;grid-template-columns:96px 1fr auto;gap:1.5rem;padding-block:1.75rem;border-bottom:1px solid var(--line);align-items:center}
.cart-line__media{width:96px;aspect-ratio:4/5;overflow:hidden;background:var(--white)}
.cart-line__media img{width:100%;height:100%;object-fit:cover}
.cart-line__cat{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);margin-bottom:.35rem}
.cart-line__name{font-weight:500;margin-bottom:.75rem}
.cart-line__tools{display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap}
.cart-line__remove{font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);border-bottom:1px solid var(--line-strong);padding-bottom:2px;transition:color .3s,border-color .3s}
.cart-line__remove:hover{color:var(--ink);border-color:var(--ink)}
.cart-line__price{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.cart-summary{border:1px solid var(--line);padding:clamp(1.5rem,3vw,2.25rem);background:var(--surface);position:sticky;top:calc(var(--nav-h) + 2rem)}
.summary-row{display:flex;justify-content:space-between;gap:1rem;padding-block:.7rem;font-size:.95rem;color:var(--ink-2)}
.summary-row--total{border-top:1px solid var(--line);margin-top:.75rem;padding-top:1.15rem;font-size:1.2rem;color:var(--ink);font-weight:500}
.empty-state{text-align:center;padding:clamp(3rem,10vw,7rem) 0;display:grid;gap:1.5rem;justify-items:center}

/* ---------- 21. CHECKOUT ---------- */
.steps{display:flex;gap:2rem;flex-wrap:wrap;margin-bottom:clamp(2.5rem,5vw,4rem)}
.step{display:flex;align-items:center;gap:.75rem;font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-4)}
.step__num{width:26px;height:26px;border:1px solid var(--line-strong);display:flex;align-items:center;justify-content:center;border-radius:50%}
.step.is-active{color:var(--ink)}
.step.is-active .step__num{border-color:var(--ink);background:var(--ink);color:var(--paper)}
.field{display:grid;gap:.5rem}
.field label{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.field input,.field textarea,.field select{
  width:100%;background:var(--field);color:var(--ink);border:1px solid var(--line-strong);
  padding:.95rem 1rem;font-size:.95rem;outline:none;transition:border-color .3s;
}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--ink)}
.field textarea{min-height:130px;resize:vertical}
.field--half{grid-column:span 6}
.field--full{grid-column:span 12}
.form-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:1.25rem}
.notice{border:1px solid var(--line);background:var(--surface);padding:1.15rem 1.35rem;font-size:var(--fs-small);color:var(--ink-2);display:flex;gap:.85rem;align-items:flex-start}
.notice svg{width:16px;height:16px;stroke:var(--ink);fill:none;stroke-width:1.3;flex-shrink:0;margin-top:.2rem}
.notice--dev{border-style:dashed}

/* ---------- 22. CONFIRMATION ---------- */
.confirm-mark{width:64px;height:64px;border:1px solid var(--ink);border-radius:50%;display:flex;align-items:center;justify-content:center;margin-inline:auto}
.confirm-mark svg{width:24px;height:24px;stroke:var(--ink);fill:none;stroke-width:1.4;stroke-dasharray:40;stroke-dashoffset:40}
.order-meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1.5rem;border-block:1px solid var(--line);padding-block:2rem;margin-block:3rem}
.order-meta dt{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);margin-bottom:.5rem}
.order-meta dd{font-size:.95rem}

/* ---------- 23. TIMELINE (livraison) ---------- */
.timeline{position:relative;display:grid;gap:0}
.timeline__item{display:grid;grid-template-columns:80px 1fr;gap:clamp(1.5rem,3vw,3rem);padding-block:clamp(2rem,4vw,3rem);border-bottom:1px solid var(--line);align-items:start}
.timeline__item:first-child{border-top:1px solid var(--line)}
.timeline__num{font-family:var(--font-display);font-size:2.5rem;font-weight:300;color:var(--ink-4);line-height:1}
.timeline__body h3{font-family:var(--font-display);font-size:clamp(1.3rem,2.2vw,1.9rem);font-weight:300;margin-bottom:.6rem}
.timeline__body p{color:var(--ink-3);max-width:56ch;font-size:.95rem}

/* ---------- 24. CONTENU LÉGAL ---------- */
.legal{max-width:760px}
.legal h2{font-family:var(--font-display);font-size:clamp(1.5rem,2.6vw,2.1rem);font-weight:300;margin-top:3rem;margin-bottom:1rem}
.legal h3{font-size:1rem;font-weight:600;margin-top:2rem;margin-bottom:.6rem}
.legal p,.legal li{color:var(--ink-2);font-size:.95rem;line-height:1.8}
.legal p+p{margin-top:1rem}
.legal ul{margin-top:1rem;display:grid;gap:.6rem}
.legal li{padding-left:1.2rem;position:relative}
.legal li::before{content:'';position:absolute;left:0;top:.75em;width:5px;height:1px;background:var(--ink-3)}
.placeholder-block{border:1px dashed var(--accent);color:var(--accent);padding:1.25rem;font-size:var(--fs-small);letter-spacing:.06em;margin-block:1.5rem}

/* ---------- 25. CONTACT / A PROPOS ---------- */
.contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2.5rem,6vw,6rem);align-items:start}
.info-list{display:grid;gap:2rem}
.info-list dt{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);margin-bottom:.5rem}
.info-list dd{font-size:1.05rem}
.stat-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:2rem;border-top:1px solid var(--line);padding-top:2.5rem}
.stat__value{font-family:var(--font-display);font-size:clamp(2.2rem,4vw,3.2rem);font-weight:300;line-height:1}
.stat__label{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);margin-top:.6rem}

/* ---------- 26. ÉTATS D'ANIMATION ---------- */
[data-reveal]{opacity:0}
[data-reveal-line] .line-mask>span{transform:translateY(105%)}
.no-motion [data-reveal],.no-motion [data-reveal-line] .line-mask>span{opacity:1!important;transform:none!important;clip-path:none!important}

/* ---------- 27. RESPONSIVE ---------- */
@media(max-width:1200px){
  .tile--quarter{grid-column:span 6}
  .footer__top{grid-template-columns:1fr 1fr 1fr}
  .footer__brand{grid-column:span 3}
}
@media(max-width:1024px){
  :root{--nav-h:64px}
  .nav__menu{display:none}
  .nav__burger{display:flex}
  .pdp{grid-template-columns:1fr;gap:2.5rem}
  .pdp__panel{position:static}
  .cart-layout{grid-template-columns:1fr}
  .cart-summary{position:static}
  .split{grid-template-columns:1fr;gap:2.5rem}
  .split--reverse .split__media{order:0}
  .pillars{grid-template-columns:1fr 1fr}
  .pillar:nth-child(2n){border-right:0}
  .contact-grid{grid-template-columns:1fr}
  .newsletter{grid-template-columns:1fr;gap:2rem}
}
@media(max-width:768px){
  .tile--half,.tile--third,.tile--quarter,.tile--wide{grid-column:span 12}
  .tile--offset{margin-top:0}
  .tile--half .tile__media,.tile--third .tile__media,.tile--quarter .tile__media{aspect-ratio:4/3}
  .product-grid{grid-template-columns:repeat(2,1fr);gap:2rem 1rem}
  .footer__top{grid-template-columns:1fr 1fr}
  .footer__brand{grid-column:span 2}
  .cart-line{grid-template-columns:72px 1fr;gap:1rem}
  .cart-line__media{width:72px}
  .cart-line__price{grid-column:2;text-align:left;margin-top:.5rem}
  .field--half{grid-column:span 12}
  .shop-bar{position:static}
  .hero{height:92svh}
  .timeline__item{grid-template-columns:1fr;gap:.75rem}
  .timeline__num{font-size:1.6rem}
  .scrollstage__spacer{height:250vh}
  .pdp__thumbs{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:520px){
  .pillars{grid-template-columns:1fr}
  .pillar{border-right:0}
  .product-grid{grid-template-columns:1fr;gap:2.5rem}
  .footer__top{grid-template-columns:1fr}
  .footer__brand{grid-column:span 1}
  .order-meta{grid-template-columns:1fr}
}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  [data-reveal],[data-reveal-line] .line-mask>span{opacity:1!important;transform:none!important}
  .hero__scroll-line::after{display:none}
}

@media print{
  .nav,.footer,.cursor,.scroll-progress,.toast{display:none}
  body{background:#fff}
}

/* ============================================================
   28. WOOCOMMERCE — habillage du balisage natif
   Les feuilles de style de WooCommerce sont desactivees dans
   functions.php : tout ce que WC rend lui-meme (quantite, bouton
   d'ajout, variations, notices, tableau du panier, paiement,
   pagination) est repris ici, dans la meme langue graphique.
   Ce bloc est sans effet sur le prototype statique.
   ============================================================ */

/* ---------- Recapitulatif replie, mobile uniquement ----------
   Masque par defaut : au-dessus de 900 px la colonne de droite fait deja ce
   travail, et deux recapitulatifs sur le meme ecran se contrediraient a la
   premiere divergence. Voir digisovia_mobile_order_preview(). */
.checkout-preview{display:none}
@media (max-width:900px){
  .checkout-preview{display:block;border:1px solid var(--line);border-radius:12px;
    background:var(--surface);margin-bottom:1.5rem;overflow:hidden}
  .checkout-preview__summary{cursor:pointer;list-style:none;display:flex;align-items:center;
    justify-content:space-between;gap:1rem;padding:1rem 1.15rem;font-size:.95rem;color:var(--ink)}
  .checkout-preview__summary::-webkit-details-marker{display:none}
  .checkout-preview__summary::after{content:"+";font-size:1.25rem;line-height:1;color:var(--ink-3);margin-left:.25rem}
  .checkout-preview[open] .checkout-preview__summary::after{content:"\2212"}
  .checkout-preview__total{font-weight:600;font-variant-numeric:tabular-nums;margin-left:auto}
  .checkout-preview__list{list-style:none;margin:0;padding:0 1.15rem 1rem;display:grid;gap:.6rem}
  .checkout-preview__list li{display:grid;grid-template-columns:1fr auto auto;gap:.75rem;
    align-items:baseline;font-size:.875rem;color:var(--ink-2);
    border-top:1px solid var(--line);padding-top:.6rem}
  .checkout-preview__qty{color:var(--ink-3);font-variant-numeric:tabular-nums}
  .checkout-preview__price{font-variant-numeric:tabular-nums;color:var(--ink)}
}

/* ---------- En-tete minimal du paiement ----------
   IL N'EXISTAIT AUCUNE REGLE POUR `.nav__secure`, et cela se voyait : le
   cadenas SVG, sans largeur imposee, se dimensionnait sur son conteneur et
   sortait a 129 x 129 px — un carre noir debordant de la barre, en haut a
   droite de LA page ou le client sort sa carte. Mesure au navigateur le
   2026-08-30 (getBoundingClientRect : w=129, h=129, y=-44).
   Un SVG sans dimension est toujours ce piege : il n'a pas de taille
   intrinseque, il prend ce qu'on lui laisse. */
.nav--checkout .nav__inner{justify-content:space-between}
.nav__secure{display:inline-flex;align-items:center;gap:.5rem;
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap}
.nav__secure svg{width:16px;height:16px;flex:none;fill:none;stroke:var(--success);
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

/* Notices */
/* `--white` ETAIT UTILISE COMME SURFACE, ET C'EST PRECISEMENT CE QUE SON
   PROPRE COMMENTAIRE INTERDIT : « --white NE BASCULE PAS. Il ne designe pas
   une surface mais l'encre la plus claire. » Resultat mesure au navigateur
   sur /checkout/ en theme sombre : fond #FFFFFF et texte #C2CAD8, soit
   1,9:1 — les bandeaux « Returning customer? » et « Have a coupon? »
   etaient illisibles. Et comme .woocommerce-info sert TOUTES les notices de
   WooCommerce, le defaut suivait le client sur le panier et le compte.
   `--surface` est la surface de carte : elle bascule, elle. */
.woocommerce-message,.woocommerce-info,.woocommerce-error,.woocommerce-noreviews{
  list-style:none;border:1px solid var(--line);background:var(--surface);
  border-radius:10px;
  padding:1.15rem 1.35rem;font-size:var(--fs-small);color:var(--ink-2);
  display:flex;gap:1rem;align-items:center;flex-wrap:wrap;margin-bottom:1.5rem;
}
/* Le lien d'action d'une notice doit se distinguer du texte qui l'entoure. */
.woocommerce-message a,.woocommerce-info a,.woocommerce-error a{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
.woocommerce-message a:hover,.woocommerce-info a:hover,.woocommerce-error a:hover{color:var(--accent-dark)}
.woocommerce-error{border-color:var(--ink);border-left-width:2px}
.woocommerce-message .button,.woocommerce-info .button{margin-left:auto}

/* Quantite */
.quantity{display:inline-flex;align-items:center;border:1px solid var(--line-strong)}
.quantity .qty{width:64px;height:46px;text-align:center;border:0;background:none;font-variant-numeric:tabular-nums;outline:none;appearance:textfield}
.quantity input::-webkit-outer-spin-button,.quantity input::-webkit-inner-spin-button{appearance:none;margin:0}

/* Boutons WooCommerce, alignes sur .btn */
.woocommerce button.button,.woocommerce a.button,.woocommerce input.button,
.woocommerce .button.alt,.wc-block-components-button{
  display:inline-flex;align-items:center;justify-content:center;gap:.65rem;
  padding:1.05rem 2.2rem;border:1px solid var(--ink);border-radius:0;
  background:var(--ink);color:var(--paper);
  font-size:var(--fs-small);font-weight:500;letter-spacing:.12em;text-transform:uppercase;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease);
}
.woocommerce button.button:hover,.woocommerce a.button:hover,.woocommerce input.button:hover{background:transparent;color:var(--ink)}
.woocommerce button.button:disabled,.woocommerce button.button.disabled{opacity:.4;pointer-events:none}
.single_add_to_cart_button{width:100%;margin-top:1rem}
form.cart{display:grid;gap:1rem;margin-bottom:0}
form.cart .quantity{justify-self:start}

/* Variations */
.variations{width:100%;border-collapse:collapse;margin-bottom:1rem}
.variations th{text-align:left;padding:.75rem 0;font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);font-weight:500;vertical-align:middle;width:35%}
.variations td{padding:.5rem 0}
.variations select{width:100%;appearance:none;background:var(--field);color:var(--ink);border:1px solid var(--line-strong);padding:.85rem 1rem;font-size:.95rem;outline:none}
.variations select:focus{border-color:var(--ink)}
.reset_variations{font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.woocommerce-variation-price{margin-bottom:1rem;font-size:1.25rem}

/* Tri et pagination */
.woocommerce-ordering select{appearance:none;background:none;border:0;border-bottom:1px solid var(--line-strong);padding:.5rem 1.5rem .5rem 0;font-size:var(--fs-small);cursor:pointer;outline:none}
.woocommerce-pagination ul,.pagination .nav-links{display:flex;gap:.5rem;list-style:none;justify-content:center;flex-wrap:wrap}
.woocommerce-pagination a,.woocommerce-pagination span,.nav-links .page-numbers{
  display:flex;align-items:center;justify-content:center;min-width:44px;height:44px;padding:0 .75rem;
  border:1px solid var(--line-strong);font-size:var(--fs-small);
  transition:background .35s var(--ease),color .35s var(--ease),border-color .35s;
}
.woocommerce-pagination .current,.nav-links .page-numbers.current{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.woocommerce-pagination a:hover,.nav-links a.page-numbers:hover{border-color:var(--ink)}

/* Prix et notation dans les gabarits WC */
.woocommerce .price{font-size:1rem}
.woocommerce .price del{color:var(--ink-4);opacity:1;margin-right:.5rem}
.woocommerce .price ins{text-decoration:none;font-weight:500}
.star-rating{display:inline-block;font-size:.75rem;letter-spacing:.15em;color:var(--ink)}

/* Panier WooCommerce */
.woocommerce-cart-form__contents{width:100%;border-collapse:collapse}
.woocommerce-cart-form__contents th{
  text-align:left;padding:1rem 0;border-bottom:1px solid var(--line);
  font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);font-weight:500;
}
.woocommerce-cart-form__contents td{padding:1.75rem 0;border-bottom:1px solid var(--line);vertical-align:middle}
.woocommerce-cart-form__contents .product-thumbnail img{width:96px;aspect-ratio:4/5;object-fit:cover}
.woocommerce-cart-form__contents .product-remove a{
  font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);
  border-bottom:1px solid var(--line-strong);padding-bottom:2px;
}
.woocommerce-cart-form__contents .product-remove a:hover{color:var(--ink);border-color:var(--ink)}
.cart_totals{border:1px solid var(--line);padding:clamp(1.5rem,3vw,2.25rem);background:var(--surface)}
.cart_totals h2{font-family:var(--font-display);font-weight:300;font-size:1.5rem;margin-bottom:1.25rem}
.cart_totals table{width:100%}
.cart_totals th,.cart_totals td{padding:.7rem 0;font-size:.95rem;text-align:left}
.cart_totals th{color:var(--ink-3);font-weight:400}
.cart_totals td{text-align:right}
.cart_totals .order-total th,.cart_totals .order-total td{border-top:1px solid var(--line);padding-top:1.15rem;font-size:1.15rem;font-weight:500;color:var(--ink)}
.wc-proceed-to-checkout{margin-top:1.5rem}
.wc-proceed-to-checkout .button{width:100%}

/* Paiement */
.woocommerce-checkout .col2-set{display:grid;grid-template-columns:1fr;gap:2rem}
.woocommerce-billing-fields__field-wrapper{display:grid;grid-template-columns:repeat(12,1fr);gap:1.25rem}
.woocommerce-checkout .form-row{grid-column:span 12;display:grid;gap:.5rem;margin:0}
.woocommerce-checkout .form-row-first,.woocommerce-checkout .form-row-last{grid-column:span 6}
.woocommerce-checkout label{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.woocommerce-checkout .input-text,.woocommerce-checkout select,.select2-selection{
  width:100%;background:var(--field);color:var(--ink);border:1px solid var(--line-strong)!important;
  padding:.95rem 1rem;font-size:.95rem;outline:none;border-radius:0!important;height:auto!important;
}
/* L'ETAT DE FOCUS DEMANDE PAR LE BRIEF : bordure violette et halo doux,
   jamais le contour bleu du navigateur. Le halo porte l'information a
   distance, la bordure la porte de pres — un seul des deux ne suffit pas
   sur un champ deja borde. */
.woocommerce-checkout .input-text:focus,
.woocommerce-checkout select:focus,
.woocommerce-checkout textarea:focus,
.field input:focus,.field textarea:focus,.field select:focus{
  border-color:var(--accent)!important;
  box-shadow:0 0 0 3px var(--field-ring);
  outline:none;
}
/* Champ en erreur : WooCommerce pose .woocommerce-invalid en JS. La couleur
   seule ne suffit pas (daltonisme) — la bordure change d'epaisseur aussi. */
.woocommerce-invalid .input-text,
.woocommerce-invalid select{border-color:var(--error)!important;border-left-width:3px!important}
.woocommerce-invalid label{color:var(--error)}
.woocommerce-validated .input-text{border-color:var(--success)!important}
.woocommerce-checkout-review-order{border:1px solid var(--line);background:var(--surface);padding:clamp(1.5rem,3vw,2.25rem);margin-top:2rem}
.woocommerce-checkout-review-order table{width:100%}
.woocommerce-checkout-review-order th,.woocommerce-checkout-review-order td{padding:.7rem 0;font-size:.95rem;text-align:left}
.woocommerce-checkout-review-order td{text-align:right}

/* ---------- Le recapitulatif : le nom du produit se lit a gauche ----------
   L'AUDIT DISAIT « colonne trop etroite », LA MESURE DIT AUTRE CHOSE.
   Elargie, la colonne fait 493 px sur 1224 — 40,3 %, dans la cible. Le texte
   continuait pourtant a se casser mot par mot, parce que la cause n'etait pas
   la largeur : la regle generique `td{text-align:right}` ci-dessus attrape
   AUSSI la cellule du nom de produit. Un nom long, sa quantite et sa liste
   « Platform / Region » alignes a droite produisent un bord gauche en
   dents de scie qu'on lit comme un defaut de largeur.
   Les prix restent a droite — c'est leur place, en chiffres tabulaires pour
   que les decimales s'empilent. Seul le NOM repasse a gauche. */
.woocommerce-checkout-review-order td.product-name{text-align:left;padding-right:1rem;line-height:1.45}
.woocommerce-checkout-review-order td.product-total,
.woocommerce-checkout-review-order .cart-subtotal td,
.woocommerce-checkout-review-order .order-total td{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.woocommerce-checkout-review-order .product-quantity{color:var(--ink-3);font-weight:500;white-space:nowrap}

/* Platform / Region : deux etiquettes, pas une definition list par defaut.
   WooCommerce sort un <dl> dont le <dt> et le <dd> tombent l'un sous l'autre,
   ce qui donnait « Platform: » seul sur sa ligne. */
.woocommerce-checkout-review-order .variation{display:grid;grid-template-columns:auto 1fr;gap:.15rem .5rem;margin:.5rem 0 0;
  font-size:var(--fs-micro);line-height:1.5}
.woocommerce-checkout-review-order .variation dt{color:var(--ink-3);font-weight:500;margin:0}
.woocommerce-checkout-review-order .variation dd{color:var(--ink-2);margin:0}
.woocommerce-checkout-review-order .variation dd p{margin:0}

/* La vignette du produit dans le recapitulatif. Plaque claire fixe : les
   visuels sont detoures sur blanc (voir la note du pied de page). */
.checkout-line{display:flex;gap:.75rem;align-items:flex-start}
.checkout-line__thumb{flex:none;width:48px;height:48px;border-radius:8px;background:#F1F5F9;
  object-fit:contain;padding:4px;border:1px solid var(--line)}
.woocommerce-checkout-review-order .order-total th,.woocommerce-checkout-review-order .order-total td{border-top:1px solid var(--line);padding-top:1.15rem;font-size:1.15rem;font-weight:500}
#payment ul.payment_methods{list-style:none;border-bottom:1px solid var(--line);padding-bottom:1.25rem;margin-bottom:1.25rem}
#payment ul.payment_methods li{padding:.6rem 0;font-size:.95rem}
#payment .payment_box{background:var(--shade);padding:1rem 1.25rem;font-size:var(--fs-small);color:var(--ink-2);margin-top:.75rem}
/* LE BOUTON « PLACE ORDER » N'OBEISSAIT PAS A SON PROPRE width:100%.
   Mesure du 2026-08-30 : 137 x 80 px, libelle casse sur deux lignes, dans un
   conteneur de 342 px — sur LE bouton qui declenche le paiement.
   Cause : la regle generique `.woocommerce-checkout .form-row{display:grid}`
   attrape aussi le `div.form-row.place-order` de WooCommerce, qui contient le
   bouton ET plusieurs noeuds voisins (champs caches, texte). La grille leur
   fabrique des pistes — `grid-template-columns` calcule y valait
   `137.2px 10.65px 10.65px 10.65px 10.65px` — et le bouton se retrouve
   dimensionne sur son contenu au lieu de la largeur disponible.
   Un `width:100%` dans une piste de 137 px vaut 137 px : la regle etait juste,
   la piste ne l'etait pas. On rend donc sa ligne au flux normal. */
.woocommerce-checkout .form-row.place-order{display:block}
#place_order{width:100%;min-height:54px;white-space:nowrap;font-size:1rem}

/* Confirmation de commande */
.woocommerce-order{max-width:780px;margin-inline:auto}
.woocommerce-order-overview{
  list-style:none;display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:1.5rem;
  border-block:1px solid var(--line);padding-block:2rem;margin-block:3rem;
}
.woocommerce-order-overview li{font-size:.95rem}
.woocommerce-order-overview strong{display:block;margin-top:.5rem;font-weight:500}
.woocommerce-order-details__title,.woocommerce-column__title{font-family:var(--font-display);font-weight:300;font-size:1.5rem;margin-bottom:1rem}
.woocommerce-table--order-details{width:100%}
.woocommerce-table--order-details th,.woocommerce-table--order-details td{padding:.9rem 0;border-bottom:1px solid var(--line);text-align:left;font-size:.95rem}

/* Compte client */
.woocommerce-MyAccount-navigation ul{display:flex;gap:1.5rem;flex-wrap:wrap;border-bottom:1px solid var(--line);padding-bottom:1rem;margin-bottom:2.5rem}
.woocommerce-MyAccount-navigation a{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.woocommerce-MyAccount-navigation .is-active a{color:var(--ink)}

@media(min-width:1025px){
  .woocommerce-checkout .col2-set{grid-template-columns:1.5fr .8fr}
}

/* ============================================================
   29. ARCHITECTURE 2026-08-30 — en-tete a une rangee, deroulant
   boutique, cartes de categorie, FAQ, barre laterale boutique.

   Ce bloc est ajoute EN FIN DE FICHIER et non fondu dans les
   sections d'origine : il surcharge deliberement des regles plus
   haut (le hero, la grille de categories) et doit donc passer
   apres elles. Les fondre aurait demande de reecrire 900 lignes
   pour un gain nul.
   ============================================================ */

/* ---------- En-tete : une seule rangee ---------- */
/* --nav-h redevient une hauteur SIMPLE. Huit regles ailleurs s'en
   servent pour decaler les pages et caler les elements collants ;
   la barre d'univers disparue, la valeur tombe de 130 a 68 px et
   tout suit sans qu'on touche a ces huit regles. */
:root{--nav-h:68px}

.nav{position:fixed;top:0;left:0;right:0;z-index:50;height:var(--nav-h);
  background:rgba(10,13,20,.72);backdrop-filter:saturate(160%) blur(14px);
  -webkit-backdrop-filter:saturate(160%) blur(14px);
  border-bottom:1px solid var(--line);transition:background .3s var(--ease-soft)}
.nav__inner{max-width:var(--max);margin-inline:auto;height:100%;padding-inline:var(--gutter);
  display:flex;align-items:center;gap:clamp(1rem,3vw,2.5rem)}
.nav__brand{flex:none;text-decoration:none}
.nav__menu{display:flex;align-items:center;gap:.25rem;margin-inline-start:.5rem}
.nav__link{display:inline-flex;align-items:center;gap:.3rem;padding:.5rem .75rem;border-radius:6px;
  font-size:.9375rem;font-weight:500;color:var(--ink-2);text-decoration:none;
  transition:color .2s,background .2s}
.nav__link:hover{color:var(--ink);background:rgba(255,255,255,.05)}
.nav__link.is-current{color:var(--ink)}
.nav__caret{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;
  transition:transform .25s var(--ease-soft)}
.nav__actions{margin-inline-start:auto;display:flex;align-items:center;gap:.35rem}
.nav__locale{font-size:.8125rem;color:var(--ink-3);padding:.4rem .6rem;border:1px solid var(--line);
  border-radius:6px;white-space:nowrap;cursor:default}
.nav__icon{position:relative;width:38px;height:38px;display:grid;place-items:center;border-radius:8px;
  background:transparent;border:0;color:var(--ink-2);cursor:pointer;transition:color .2s,background .2s}
.nav__icon:hover{color:var(--ink);background:rgba(255,255,255,.06)}
.nav__icon svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}

/* ---------- Deroulant Shop ---------- */
.nav__has-drop{position:relative}
.drop{position:absolute;top:calc(100% + 10px);left:50%;transform:translate(-50%,8px);
  min-width:min(680px,88vw);opacity:0;visibility:hidden;pointer-events:none;
  background:var(--surface);border:1px solid var(--line-strong);border-radius:12px;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.75);
  transition:opacity .2s var(--ease-soft),transform .2s var(--ease-soft),visibility .2s}
/* Ouverture au survol ET au focus clavier : un menu qui ne s'ouvre qu'a la
   souris est inatteignable a la tabulation. */
.nav__has-drop:hover .drop,
.nav__has-drop:focus-within .drop{opacity:1;visibility:visible;pointer-events:auto;transform:translate(-50%,0)}
.nav__has-drop:hover .nav__caret,
.nav__has-drop:focus-within .nav__caret{transform:rotate(180deg)}
.drop__inner{padding:1.1rem}
.drop__all{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.7rem .9rem;margin-bottom:.9rem;border-radius:8px;text-decoration:none;
  background:rgba(109,139,255,.10);border:1px solid rgba(109,139,255,.28);
  color:var(--ink);font-weight:600;font-size:.9375rem}
.drop__all:hover{background:rgba(109,139,255,.18)}
.drop__all svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.drop__cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:1.1rem 1.5rem}
.drop__head{display:block;font-size:.75rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);text-decoration:none;margin-bottom:.5rem}
.drop__head:hover{color:var(--accent)}
.drop__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.15rem}
.drop__list a{display:block;padding:.35rem .5rem;margin-inline:-.5rem;border-radius:6px;
  font-size:.9rem;color:var(--ink-2);text-decoration:none}
.drop__list a:hover{color:var(--ink);background:rgba(255,255,255,.05)}

/* ---------- Boutons ---------- */
.btn--primary{background:var(--grad);color:#fff;border:0;box-shadow:0 8px 24px -10px rgba(109,139,255,.7)}
.btn--primary:hover{filter:brightness(1.08);color:#fff}
.btn--glass{background:rgba(255,255,255,.06);color:var(--ink);border:1px solid var(--line-strong);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.btn--glass:hover{background:rgba(255,255,255,.11);color:var(--ink)}

/* ---------- Hero : plus court, plus dense ---------- */
/* 78svh plafonne a 620px. L'ancien hero montait a 92svh sur mobile — presque
   un ecran entier avant le premier produit. Le brief demande un hero
   « puissant mais pas excessivement haut ». */
.hero{min-height:min(78svh,620px);padding-block:calc(var(--nav-h) + 3rem) 3rem;display:flex;align-items:center}
.hero__inner{position:relative;z-index:2;max-width:var(--max);margin-inline:auto;width:100%;
  padding-inline:var(--gutter);display:flex;flex-direction:column;align-items:flex-start;
  gap:1rem;text-align:left;grid-template-columns:none}
.hero__title{font-size:clamp(2.2rem,4.6vw,3.6rem);line-height:1.05;letter-spacing:-.02em;
  color:var(--white);max-width:16ch;margin:0}
.hero__lead{color:var(--on-ground);max-width:52ch;font-size:var(--fs-lead);margin:0}
.hero__cta{display:flex;gap:.75rem;flex-wrap:wrap;margin-top:.75rem}
.hero__media::after{background:linear-gradient(100deg,rgba(7,9,13,.94) 0%,rgba(7,9,13,.72) 46%,rgba(10,13,20,.55) 100%)}

/* ---------- Rythme de section ---------- */
/* Un seul jeton pilote l'espace entre TOUTES les sections : c'est ce qui rend
   l'espacement previsible, exigence 4 du brief. */
.section{padding-block:var(--section)}
.section--tight{padding-block:calc(var(--section) * .72)}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1.5rem;
  margin-bottom:clamp(1.5rem,3vw,2.25rem);flex-wrap:wrap}
.sec-head--center{justify-content:center;text-align:center}
.sec-title{font-size:clamp(1.5rem,2.6vw,2.1rem);line-height:1.15;letter-spacing:-.015em;
  color:var(--ink);margin:.35rem 0 0}
.link-arrow{display:inline-flex;align-items:center;gap:.4rem;font-size:.9375rem;font-weight:500;
  color:var(--accent);text-decoration:none;white-space:nowrap}
.link-arrow svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.link-arrow:hover{color:var(--accent-dark)}
.shell--narrow{max-width:840px}

/* ---------- Cartes de categorie ---------- */
.cat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:1rem}
.cat-card{display:flex;flex-direction:column;border-radius:12px;overflow:hidden;text-decoration:none;
  background:var(--surface);border:1px solid var(--line);
  transition:border-color .25s,transform .25s var(--ease-soft),background .25s}
.cat-card:hover{border-color:rgba(109,139,255,.5);transform:translateY(-3px);background:var(--surface-2)}
.cat-card__media{display:block;aspect-ratio:4/3;overflow:hidden;background:var(--ground-2)}
.cat-card__media img{width:100%;height:100%;object-fit:cover;opacity:.85;transition:opacity .25s,transform .4s var(--ease-soft)}
.cat-card:hover .cat-card__media img{opacity:1;transform:scale(1.04)}
.cat-card__body{padding:.85rem 1rem 1rem;display:flex;flex-direction:column;gap:.15rem}
.cat-card__name{font-weight:600;color:var(--ink);font-size:1rem}
.cat-card__count{font-size:.8125rem;color:var(--ink-3)}

/* ---------- Bandeau promotions ---------- */
.section--deals{position:relative;background:
  radial-gradient(90% 120% at 10% 0%,rgba(168,123,255,.13) 0%,rgba(168,123,255,0) 60%),
  radial-gradient(80% 120% at 90% 100%,rgba(109,139,255,.13) 0%,rgba(109,139,255,0) 60%),
  var(--shade);
  border-block:1px solid var(--line)}

/* ---------- Why DIGISOVIA ---------- */
.section--why{background:var(--shade);border-block:1px solid var(--line)}
.why{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(2rem,5vw,4rem);align-items:start}
.why__text{color:var(--ink-2);margin:.9rem 0 1.5rem;max-width:46ch}
.why__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.why__list li{background:var(--surface);padding:1.15rem 1.35rem}
.why__list h3{font-size:1rem;margin:0 0 .3rem;color:var(--ink)}
.why__list p{margin:0;font-size:.9375rem;color:var(--ink-3);line-height:1.55}

/* ---------- FAQ ---------- */
.faq{display:flex;flex-direction:column;gap:.6rem}
.faq__item{background:var(--surface);border:1px solid var(--line);border-radius:10px;overflow:hidden}
.faq__item[open]{border-color:var(--line-strong)}
.faq__q{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:1rem 1.25rem;cursor:pointer;list-style:none;font-weight:600;color:var(--ink);font-size:1rem}
.faq__q::-webkit-details-marker{display:none}
.faq__q svg{width:18px;height:18px;flex:none;fill:none;stroke:var(--ink-3);stroke-width:2;
  stroke-linecap:round;transition:transform .25s var(--ease-soft)}
.faq__item[open] .faq__q svg{transform:rotate(45deg)}
.faq__a{padding:0 1.25rem 1.15rem}
.faq__a p{margin:0;color:var(--ink-2);font-size:.9375rem;line-height:1.65;max-width:70ch}
.faq__more{text-align:center;margin-top:1.5rem;color:var(--ink-3);font-size:.9375rem}

/* ---------- Tiroir mobile ---------- */
.menu__list{display:flex;flex-direction:column;gap:.1rem}
.menu__link{display:block;padding:.7rem .25rem;font-size:1.05rem;color:var(--ink);text-decoration:none;
  border-bottom:1px solid var(--line)}
.menu__link--cat{margin-top:.75rem;font-size:.75rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);border-bottom:0;padding-bottom:.2rem}
.menu__link--sub{padding-left:1rem;font-size:.95rem;color:var(--ink-2)}

/* ---------- Boutique : barre laterale ---------- */
.shop-layout{display:grid;grid-template-columns:236px minmax(0,1fr);gap:clamp(1.5rem,3vw,2.5rem);align-items:start}
.shop-side{position:sticky;top:calc(var(--nav-h) + 1.5rem);
  background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:1.1rem}
.shop-side__title{font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 .7rem}
.shop-side__list{list-style:none;margin:0 0 1.25rem;padding:0;display:flex;flex-direction:column;gap:.1rem}
.shop-side__list:last-child{margin-bottom:0}
.shop-side__list a{display:flex;justify-content:space-between;gap:.5rem;padding:.45rem .6rem;
  margin-inline:-.6rem;border-radius:6px;font-size:.9rem;color:var(--ink-2);text-decoration:none}
.shop-side__list a:hover{background:rgba(255,255,255,.05);color:var(--ink)}
.shop-side__list a[aria-current]{background:rgba(109,139,255,.14);color:var(--ink);font-weight:600}
.shop-side__list .n{color:var(--ink-4);font-size:.8125rem}
.shop-side__list--sub{margin-left:.7rem;border-left:1px solid var(--line);padding-left:.5rem}

.shop-toolbar{display:flex;gap:.75rem;align-items:center;flex-wrap:wrap;margin-bottom:1.25rem}
.shop-search{flex:1 1 240px;display:flex;align-items:center;gap:.55rem;
  background:var(--surface);border:1px solid var(--line);border-radius:9px;padding:.55rem .85rem}
.shop-search:focus-within{border-color:rgba(109,139,255,.55)}
.shop-search svg{width:18px;height:18px;flex:none;fill:none;stroke:var(--ink-3);stroke-width:1.8;stroke-linecap:round}
.shop-search input{flex:1;background:none;border:0;outline:0;color:var(--ink);font-size:.9375rem;min-width:0}
.shop-search input::placeholder{color:var(--ink-4)}
.shop-toolbar select,.shop-toolbar .orderby{background:var(--surface);border:1px solid var(--line);
  border-radius:9px;padding:.55rem .85rem;color:var(--ink-2);font-size:.9rem}
.shop-filter-btn{display:none}
.shop-count{color:var(--ink-3);font-size:.875rem}

/* ---------- Fil d'Ariane ---------- */
.crumbs{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center;font-size:.8125rem;color:var(--ink-4);margin-bottom:1.25rem}
.page-top{padding-top:calc(var(--nav-h) + 1.5rem)}
.shop-lede{color:var(--ink-3);font-size:.9375rem;max-width:62ch;margin:0 0 1.25rem}
.shop-lede p{margin:0}
.crumbs a{color:var(--ink-3);text-decoration:none}
.crumbs a:hover{color:var(--accent)}
.crumbs [aria-current]{color:var(--ink-2)}

/* ---------- Cartes produit sur fond sombre ---------- */
.product-card{background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden;
  transition:border-color .25s,transform .25s var(--ease-soft)}
.product-card:hover{border-color:rgba(109,139,255,.45);transform:translateY(-3px)}
.product-card__media{background:var(--ground-2)}
.product-card__body{padding:.9rem 1rem 1.1rem}
.product-card__name a{color:var(--ink);text-decoration:none}
.product-card__cat{color:var(--ink-4)}

/* ---------- Responsive ---------- */
@media (max-width:1024px){
  .why{grid-template-columns:1fr}
  .shop-layout{grid-template-columns:1fr}
  /* La barre laterale devient un tiroir : sur tablette et mobile une colonne
     figee mange la moitie de la largeur utile pour la grille produit. */
  .shop-side{display:none;position:static}
  .shop-side.is-open{display:block;margin-bottom:1.25rem}
  .shop-filter-btn{display:inline-flex;align-items:center;gap:.45rem;padding:.55rem .9rem;
    background:var(--surface);border:1px solid var(--line);border-radius:9px;
    color:var(--ink-2);font-size:.9rem;cursor:pointer}
  .shop-filter-btn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.8}
}
@media (max-width:900px){
  .nav__menu,.nav__locale{display:none}
  .nav__burger{display:flex}
  .hero{min-height:auto;padding-block:calc(var(--nav-h) + 2.5rem) 2.5rem}
  .hero__title{font-size:clamp(2rem,7vw,2.6rem)}
  .cat-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.75rem}
  .sec-head{align-items:flex-start}
}
@media (max-width:600px){
  .cat-grid{grid-template-columns:1fr 1fr}
  .cat-card__body{padding:.7rem .8rem .85rem}
  .cat-card__name{font-size:.9375rem}
  .hero__cta{width:100%}
  .hero__cta .btn{flex:1;justify-content:center;min-height:46px}
}

/* Grille produit sur petit ecran : DEUX colonnes, pas une.
   Mesure avant correction : la boutique faisait 9 715 px sur un ecran de
   812 px, soit douze ecrans de defilement pour seize produits. La regle
   d origine, minmax(260px,1fr), retombe a une seule colonne des que la
   largeur utile passe sous 520 px. Deux colonnes ramenent la page a six
   ecrans et correspondent a ce que fait n importe quelle place de marche. */
@media (max-width:640px){
  .product-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.25rem .75rem}
  .product-card__body{padding:.7rem .75rem .9rem}
  .product-card__name{font-size:.9rem;line-height:1.3}
  .product-card .dgs-badges{min-height:0}
  .product-card .dgs-badge{font-size:.5625rem;padding:.15em .4em}
}

/* Plaque de repli quand une categorie n a pas de visuel. */
.cat-card__media--blank{display:grid;place-items:center;
  background:radial-gradient(120% 120% at 30% 20%,rgba(109,139,255,.28) 0%,rgba(168,123,255,.14) 45%,rgba(10,13,20,0) 75%),var(--ground-2)}
.cat-card__initial{font-family:var(--font-display);font-size:2.75rem;font-weight:700;
  color:rgba(255,255,255,.28);line-height:1}
/* L eyebrow du hero suivait le cyan de l ancienne marque ; il passe au bleu
   d accent pour ne pas etre la seule note froide de la palette. */
.hero__eyebrow{color:var(--accent)}


/* ============================================================
   31. HABILLAGE BITHEME.

   Remplace les anciennes couches 31 et 32, qui etaient deux jeux
   de surcharges CLAIRES posees sur une base ECRITE POUR LE
   SOMBRE. Elles ne pouvaient pas basculer : leurs blancs, leurs
   lavis et leurs ombres etaient litteraux.

   Ici, plus une seule couleur en dur. Chaque regle lit un jeton,
   et les deux themes sont definis en tete de fichier. Une bascule
   ne touche donc qu'a `data-theme` sur <html>.
   ============================================================ */

/* ---------- En-tete ---------- */
.nav{background:var(--nav-bg);border-bottom:1px solid var(--line);box-shadow:none;
  backdrop-filter:saturate(160%) blur(14px);-webkit-backdrop-filter:saturate(160%) blur(14px)}
.nav.is-scrolled{box-shadow:var(--shadow-sm)}
.nav__link{color:var(--ink-2)}
.nav__link:hover{color:var(--accent);background:var(--accent-wash)}
.nav__link.is-current{color:var(--accent)}
.nav__icon{color:var(--ink-2)}
.nav__icon:hover{color:var(--accent);background:var(--accent-wash)}
.nav__locale{color:var(--ink-3);border-color:var(--line)}
.logo{color:var(--ink)}

/* Le hero n'est plus une section sombre distincte : la navigation ne bascule
   donc plus en mode « au-dessus du sombre ». Les regles heritees sont
   neutralisees ici plutot que supprimees plus haut, pour garder un seul
   endroit a relire. */
.nav.is-over-dark,
.nav.is-over-dark.is-scrolled{background:var(--nav-bg);color:var(--ink);border-bottom-color:var(--line)}
.nav.is-over-dark .nav__link,
.nav.is-over-dark.is-scrolled .nav__link,
.nav.is-over-dark .nav__icon,
.nav.is-over-dark.is-scrolled .nav__icon{color:var(--ink-2)}
.nav.is-over-dark .nav__link:hover,
.nav.is-over-dark.is-scrolled .nav__link:hover,
.nav.is-over-dark .nav__icon:hover,
.nav.is-over-dark.is-scrolled .nav__icon:hover{color:var(--accent);background:var(--accent-wash)}
.nav.is-over-dark .nav__locale,
.nav.is-over-dark.is-scrolled .nav__locale{color:var(--ink-3);border-color:var(--line)}
.nav.is-over-dark .logo,
.nav.is-over-dark.is-scrolled .logo{color:var(--ink)}

/* ---------- Bouton de theme ---------- */
.theme-toggle{position:relative;width:38px;height:38px;display:grid;place-items:center;
  border-radius:8px;background:transparent;border:0;color:var(--ink-2);cursor:pointer;
  transition:color .2s,background .2s}
.theme-toggle:hover{color:var(--accent);background:var(--accent-wash)}
.theme-toggle svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
/* Une seule icone visible a la fois : le soleil propose le clair, la lune
   propose le sombre. On montre CE QUE LE CLIC DONNERA, pas l'etat courant —
   c'est la convention que suivent les navigateurs et les systemes. */
.theme-toggle .i-sun{display:block}
.theme-toggle .i-moon{display:none}
:root[data-theme="light"] .theme-toggle .i-sun{display:none}
:root[data-theme="light"] .theme-toggle .i-moon{display:block}

/* ---------- Hero ---------- */
.hero,.hero--light{background:
  radial-gradient(70% 90% at 88% 8%,var(--hero-wash-1) 0%,transparent 60%),
  radial-gradient(60% 80% at 4% 100%,var(--hero-wash-2) 0%,transparent 60%),
  var(--paper);
  min-height:0;padding-block:calc(var(--nav-h) + clamp(2.5rem,5vw,4rem)) clamp(2.5rem,5vw,4rem)}
.hero__media{display:none}
.hero__inner{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(2rem,5vw,4rem);align-items:center;text-align:left}
.hero__text{display:flex;flex-direction:column;align-items:flex-start;gap:1rem}
.hero__eyebrow{color:var(--accent);margin:0}
.hero__title{color:var(--ink);font-size:clamp(2.1rem,4.2vw,3.35rem);line-height:1.08;
  letter-spacing:-.025em;max-width:16ch;margin:0}
.hero__accent{color:var(--accent);
  background:var(--grad);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent}
.hero__lead{color:var(--ink-3);max-width:50ch;font-size:var(--fs-lead);margin:0}
.hero__cta{display:flex;gap:.75rem;flex-wrap:wrap;margin-top:.5rem}
.hero__visual{position:relative}
.hero__frame{position:relative;border-radius:14px;overflow:hidden;
  border:1px solid var(--line);background:var(--shade);box-shadow:var(--shadow-lg)}
.hero__frame video{display:block;width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;
  position:static;opacity:1}
.hero__visual::before{content:'';position:absolute;inset:8% -6% -10% 4%;z-index:-1;border-radius:24px;
  background:var(--grad);opacity:.16;filter:blur(38px)}

/* ---------- Sections ---------- */
.section--deep,.statement,.scrollstage{background:var(--shade);color:var(--ink)}
.section--deep .eyebrow,.statement .eyebrow,.scrollstage .eyebrow,.footer .eyebrow{color:var(--accent)}

/* ---------- Boutons ---------- */
.btn{border-radius:9px;font-weight:600}
.btn--primary{background:var(--grad);color:var(--white);border:0;box-shadow:var(--shadow-md)}
.btn--primary:hover{filter:brightness(1.08);color:var(--white)}
.btn--outline,.btn--glass{background:var(--surface);color:var(--ink);border:1px solid var(--line-strong);
  backdrop-filter:none;-webkit-backdrop-filter:none}
.btn--outline:hover,.btn--glass:hover{background:var(--surface-2);color:var(--accent);border-color:var(--accent)}
.hero .btn--glass,.hero .btn--outline{background:var(--surface);color:var(--ink);border-color:var(--line-strong)}
.hero .btn--glass:hover,.hero .btn--outline:hover{background:var(--surface-2);color:var(--accent);border-color:var(--accent)}

/* ---------- Cartes ---------- */
.cat-card,.product-card,.faq__item,.shop-side,.why__list li,.dgs-trust__item{background:var(--surface)}
.cat-card,.product-card{border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-sm)}
.cat-card:hover,.product-card:hover{border-color:var(--accent-line);transform:translateY(-2px);
  box-shadow:var(--shadow-md)}
.cat-card__media,.product-card__media{background:var(--shade)}
.cat-card__media--blank{display:grid;place-items:center;background:
  radial-gradient(120% 120% at 30% 20%,var(--accent-wash) 0%,transparent 70%),var(--shade)}
.cat-card__initial{font-family:var(--font-display);font-size:2.75rem;font-weight:700;
  color:var(--accent);opacity:.45;line-height:1}

.dgs-trust{background:var(--shade);border-block:1px solid var(--line)}
.dgs-trust__grid{gap:1rem}
.dgs-trust__item{border:1px solid var(--line);border-radius:12px;padding:1.15rem 1.25rem;
  box-shadow:var(--shadow-sm)}
.dgs-trust__item svg{color:var(--accent)}
.dgs-trust__title{color:var(--ink)}
.dgs-trust__text{color:var(--ink-3)}

/* ---------- Deroulant ---------- */
.drop{background:var(--surface);border-color:var(--line);border-radius:12px;box-shadow:var(--shadow-lg)}
.drop__all{background:var(--accent-wash);border-color:var(--accent-line);color:var(--ink)}
.drop__all:hover{background:var(--accent-wash);filter:brightness(1.15)}
.drop__list a:hover{background:var(--hover);color:var(--accent)}
.drop__head:hover{color:var(--accent)}

/* ---------- Boutique ---------- */
.shop-side{border-radius:12px;box-shadow:var(--shadow-sm)}
.shop-side__list a:hover{background:var(--hover);color:var(--accent)}
.shop-side__list a[aria-current]{background:var(--accent-wash);color:var(--accent)}
.shop-search{background:var(--surface);border-radius:9px}
.shop-search:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
.shop-toolbar select,.shop-toolbar .orderby{background:var(--surface);border-radius:9px;color:var(--ink-2)}

/* ---------- Pied de page ---------- */
.footer{background:var(--shade);color:var(--ink-2);border-top:1px solid var(--line)}
.footer a{color:var(--ink-2)}
.footer a:hover{color:var(--accent)}
.footer h4{color:var(--ink)}
.footer .logo{color:var(--ink)}
.footer__bottom,.footer__top{border-color:var(--line)}
.footer .small,.footer__entity,.footer__legal{color:var(--ink-3)}
/* Le bandeau de paiement suit la rampe claire. Les plaques blanches sous les
   marques restent blanches — c'est le fond de la carte, pas une surface de
   page (voir le commentaire de .footer__pay-list img). */
.footer__pay{border-color:var(--line)}
/* --ink-3 (#64748B) sur le pied clair (#F7F8FC) mesure 4,48:1 — sous les
   4,5:1 exiges pour du petit texte, et ces deux libelles sont en 11 px
   capitales. --ink-2 les repasse au-dessus du seuil. Mesure au navigateur,
   pas a l'oeil. */
.footer__pay-label{color:var(--ink-2)}
.footer__pay-note{color:var(--ink-2)}
.footer__pay-list img{box-shadow:0 1px 2px rgba(17,24,39,.12);border:1px solid var(--line)}

/* ---------- Panier et paiement ---------- */
body.woocommerce-cart,body.woocommerce-checkout{background:var(--shade)}
.cart-summary,.cart_totals,.woocommerce-checkout-review-order,
.woocommerce-billing-fields,.woocommerce-checkout #payment{
  background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-sm)}
.woocommerce-checkout #payment{padding:clamp(1.25rem,3vw,1.75rem)}
.dgs-digital-notice{background:var(--surface);border-color:var(--line);
  border-left:3px solid var(--accent);border-radius:9px;color:var(--ink-2)}
.dgs-digital-notice svg{color:var(--accent)}
.cart-trust{background:var(--surface);border-color:var(--line)}
.cart-trust span{color:var(--ink-2)}

/* ---------- Champs ---------- */
input[type=text],input[type=email],input[type=tel],input[type=search],
input[type=password],input[type=number],textarea,select{border-radius:9px;
  background:var(--surface);color:var(--ink);border-color:var(--line-strong)}
input:focus,textarea:focus,select:focus{border-color:var(--accent);outline:none;
  box-shadow:0 0 0 3px var(--accent-wash)}
input::placeholder,textarea::placeholder{color:var(--ink-4)}

/* ---------- Prix, badges ---------- */
.product-card__price .now,.pdp__price .now{color:var(--ink);font-weight:700}
.product-card__price .was,.pdp__price .was{color:var(--ink-4)}
.product-card__price .off,.pdp__price .off{background:var(--error);color:var(--white);border-radius:4px}
.dgs-badge{border-radius:6px;background:var(--surface);color:var(--ink-3);border-color:var(--line)}
.dgs-badge--platform{border-color:var(--accent-line);color:var(--accent)}
.dgs-badge--region{border-color:var(--line-strong);color:var(--ink-2)}
.dgs-badge--region.is-unconfirmed{border-color:var(--error);color:var(--error)}
.badge{background:var(--grad);color:var(--white);border:0;border-radius:6px}

/* ---------- Promotions ---------- */
.section--deals{background:
  radial-gradient(90% 120% at 10% 0%,var(--hero-wash-1) 0%,transparent 60%),
  radial-gradient(80% 120% at 90% 100%,var(--hero-wash-2) 0%,transparent 60%),
  var(--shade)}
.section--why{background:var(--shade);border-block:1px solid var(--line)}
.why__list{background:var(--line)}
.why__list li{background:var(--surface)}

/* ---------- Fiche produit ---------- */
.dgs-facts{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:.35rem 1.1rem}
.dgs-facts th{color:var(--ink-3)}
.dgs-facts td{color:var(--ink)}
.dgs-included{background:var(--shade);border-color:var(--line);border-radius:12px}
.dgs-included__list svg{color:var(--success)}
.pdp__figure{background:var(--shade)}
.faq__q{color:var(--ink)}
.faq__a p{color:var(--ink-2)}

/* ---------- Confirmation ---------- */
.dgs-confirm{background:var(--surface);border-color:var(--line);box-shadow:var(--shadow-md)}
.dgs-confirm__brand{color:var(--ink)}
.dgs-confirm__facts{border-block-color:var(--line)}
.dgs-confirm__facts dd{color:var(--ink)}

/* ---------- Responsive ---------- */
@media (max-width:900px){
  .hero__inner{grid-template-columns:1fr;gap:2rem}
  .hero__title{max-width:none}
  .hero__visual{order:2}
  .hero__text{order:1}
}

/* ============================================================
   33. PAIEMENT ET PANIER — mise en page deux colonnes.
   ============================================================ */

/* Titre ramene a une taille de page, pas de banniere. Mesure avant :
   64 px pour le mot « Checkout », soit un tiers d ecran occupe par un mot
   que la barre de securite annonce deja. */
.woocommerce-checkout .page-head__title,
.woocommerce-checkout h1.display,
.woocommerce-cart .page-head__title,
.woocommerce-cart h1.display{font-size:clamp(1.6rem,2.6vw,2.1rem);margin-block:.25rem 1.25rem}
.woocommerce-checkout .page-head,.woocommerce-cart .page-head{padding-top:1.5rem;padding-bottom:0}

/* Le formulaire occupait 653 px centres dans une coquille de 1265 : la
   moitie de la largeur perdue, et le recapitulatif rejete tout en bas.
   Deux colonnes : saisie a gauche, recapitulatif colle a droite. */
.woocommerce-checkout form.checkout{width:100%;max-width:none;margin:0;
  display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);
  gap:clamp(1.5rem,3vw,2.5rem);align-items:start}
.woocommerce-checkout form.checkout>#customer_details{grid-column:1;grid-row:1 / span 2}
.woocommerce-checkout form.checkout>#order_review_heading{grid-column:2;grid-row:1;margin:0 0 .75rem}
.woocommerce-checkout form.checkout>#order_review{grid-column:2;grid-row:2;
  position:sticky;top:1.5rem}
/* Les avis et le bloc « client de retour » restent pleine largeur au-dessus. */
.woocommerce-checkout form.checkout>.woocommerce-NoticeGroup,
.woocommerce-checkout form.checkout>.woocommerce-form-login,
.woocommerce-checkout form.checkout>.woocommerce-form-coupon{grid-column:1 / -1}

/* Dans la colonne de gauche, adresse et notes se posent lune sous lautre :
   deux sous-colonnes dans une colonne deja etroite donnaient des champs de
   216 px, trop courts pour une adresse. */
.woocommerce-checkout #customer_details{display:block}
.woocommerce-checkout #customer_details .col-1,
.woocommerce-checkout #customer_details .col-2{width:100%;max-width:none;float:none}
.woocommerce-checkout #customer_details .col-2{margin-top:1.5rem}

@media (max-width:900px){
  .woocommerce-checkout form.checkout{grid-template-columns:1fr}
  .woocommerce-checkout form.checkout>#customer_details,
  .woocommerce-checkout form.checkout>#order_review_heading,
  .woocommerce-checkout form.checkout>#order_review{grid-column:1;grid-row:auto}
  .woocommerce-checkout form.checkout>#order_review{position:static}
}

/* Le panier et le paiement sont des pages WordPress ordinaires : page.php
   les enroule donc dans la coquille etroite prevue pour de la PROSE (840 px)
   et dans un conteneur .body-text a la mesure de lecture. Resultat mesure :
   un formulaire de paiement de 653 px centre dans une page de 1265, avec le
   recapitulatif tasse sur 256 px. Une page de tunnel n est pas un article :
   elle reprend la pleine largeur. */
.woocommerce-checkout .shell--narrow,
.woocommerce-cart .shell--narrow{max-width:var(--max)}
.woocommerce-checkout .body-text,
.woocommerce-cart .body-text{max-width:none}

/* Debordement mesure sur le paiement : 41 px, causes par le champ de code
   promo. WooCommerce lui donne une largeur propre qui ignore la colonne ou
   il se trouve. On borne TOUS les champs du tunnel a leur conteneur plutot
   que de viser ce champ-la : le prochain que WooCommerce ajoutera aura le
   meme defaut. */
.woocommerce-checkout input,.woocommerce-checkout select,.woocommerce-checkout textarea,
.woocommerce-cart input,.woocommerce-cart select,.woocommerce-cart textarea{
  max-width:100%;box-sizing:border-box}
.woocommerce-checkout .form-row,.woocommerce-cart .form-row{min-width:0}
.woocommerce-form-coupon .form-row-first,.woocommerce-form-coupon .form-row-last{width:auto;min-width:0}

/* Le champ sonde de la passerelle Stripe.

   L element #wc-stripe-hidden-style-input est injecte par la passerelle
   woocommerce-gateway-stripe pour MESURER l apparence de nos champs (police,
   couleur, bordure, rayon) et l appliquer a son propre element de carte. Il
   ne doit rien afficher — mais il restait dans le flux, large de 472 px, et
   debordait la page de 41 px sur les trois largeurs testees.

   On le sort du flux avec visibility:hidden et NON avec display:none :
   un element en display:none n a pas de styles calcules exploitables, et
   Stripe copierait alors une apparence vide. La sonde continue donc de
   mesurer ce qu elle doit mesurer, sans peser sur la mise en page. */
#wc-stripe-hidden-style-input{position:absolute!important;top:0;left:0;
  width:auto!important;visibility:hidden;pointer-events:none}

/* ---------- Confirmation de commande ---------- */
/* CORRIGE LE 2026-08-30 — `background:#fff` etait ecrit en dur ici.
   C'est le meme defaut que les champs de paiement, mesure a 1,13:1 le meme
   jour : sur la rampe SOMBRE, `.dgs-confirm__brand` et `.dgs-confirm__facts dd`
   peignent `var(--ink)` = #EDF1F7 sur un fond #FFFFFF. La page de confirmation
   de commande — celle que le client imprime et garde — affichait donc son
   numero de commande en blanc sur blanc. Le jeton `--surface` bascule ; #fff
   ne bascule pas. */
.dgs-confirm{background:var(--surface);border:1px solid var(--line);border-radius:14px;
  padding:clamp(1.5rem,4vw,2.5rem);margin-bottom:2rem;
  box-shadow:0 1px 2px rgba(17,24,39,.04),0 18px 36px -28px rgba(17,24,39,.25)}
.dgs-confirm__brand{display:flex;align-items:center;gap:.55rem;margin-bottom:1.25rem;
  font-weight:700;letter-spacing:.02em;color:var(--ink)}
.dgs-confirm__brand .logo__mark{width:30px;height:30px;flex:none}
.dgs-confirm__status{display:inline-flex;align-items:center;gap:.55rem;
  font-size:clamp(1.25rem,2.4vw,1.6rem);font-weight:700;color:var(--success);line-height:1.2}
.dgs-confirm__status svg{width:26px;height:26px;flex:none;fill:none;stroke:currentColor;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.dgs-confirm__status.is-pending{color:var(--warning)}
.dgs-confirm__lede{margin:.5rem 0 1.5rem;color:var(--ink-3)}
.dgs-confirm__facts{display:flex;flex-wrap:wrap;gap:1rem 2.5rem;margin:0 0 1.5rem;
  padding:1.1rem 0;border-block:1px solid var(--line)}
.dgs-confirm__facts dt{font-size:.75rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);margin:0 0 .2rem}
.dgs-confirm__facts dd{margin:0;font-size:1.0625rem;font-weight:600;color:var(--ink)}
.dgs-confirm__actions{display:flex;flex-wrap:wrap;gap:.7rem}
@media(max-width:600px){
  .dgs-confirm__facts{gap:.9rem 1.5rem}
  .dgs-confirm__actions .btn{flex:1;justify-content:center;min-height:46px}
}

/* ============================================================
   30. BRIEF DU 2026-08-30 — P1-7, P1-8, P2-9, P2-10, P5-17
   En-tete qui se retracte, fil d'Ariane, animations, mesh du hero,
   anneau de focus. Rien ici ne redefinit un jeton : tout passe par ceux
   du bloc 1, donc les deux rampes suivent sans variante a maintenir.
   ============================================================ */

/* ---------- P1-7 En-tete : retraction au defilement ---------- */

/*
   LE BRIEF DEMANDE « padding 24px -> 12px ». Cet en-tete n'a pas de padding
   vertical : il a une HAUTEUR, `--nav-h`, et huit regles s'alignent dessus
   (le decalage `page-top`, le hero, le tiroir mobile). Reduire un padding
   inexistant n'aurait rien fait ; on reduit donc la hauteur, qui est la
   traduction exacte de la demande dans ce theme.

   68px -> 52px, soit les 16px de difference demandes. La transition porte
   sur `height` et non sur `transform` : un `scaleY` ecraserait le logo et le
   compteur de panier.

   L'ombre portee arrive avec la retraction. Elle existait deja
   (`.nav.is-scrolled{box-shadow:var(--shadow-sm)}`, bloc 29) ; elle est
   renforcee ici parce qu'un en-tete plus bas a besoin de se detacher
   davantage du contenu qui defile dessous.
*/
.nav{transition:height .25s var(--ease-soft),background .3s var(--ease-soft),
  box-shadow .25s var(--ease-soft),transform .4s var(--ease-soft)}
.nav.is-scrolled{height:52px;box-shadow:var(--shadow-md)}
.nav.is-scrolled .logo__mark{transform:scale(.88)}
.nav .logo__mark{transition:transform .25s var(--ease-soft)}

/* La retraction est une animation : elle disparait avec le mouvement reduit,
   sinon l'en-tete saute de 16px sous le curseur de quelqu'un qui a demande
   qu'on arrete de bouger. */
@media(prefers-reduced-motion:reduce){
  .nav{transition:none}
  .nav.is-scrolled{height:var(--nav-h)}
  .nav.is-scrolled .logo__mark{transform:none}
}

/* ---------- P1-8 Fil d'Ariane ---------- */

.crumbs a{position:relative;padding:.1rem .15rem;border-radius:3px;
  transition:color .2s,background .2s}
.crumbs a:hover{color:var(--accent);background:var(--accent-wash)}
/* Le separateur etait de la meme encre que les liens : trois mots et deux
   barres obliques se lisaient comme une seule chaine. Il recule d'un cran. */
.crumbs [aria-hidden="true"]{color:var(--ink-4);opacity:.55;user-select:none}
.crumbs [aria-current]{color:var(--ink-2);font-weight:500}

/* ---------- P2-9 Survol des boutons et des cartes ---------- */

/*
   `scale(1.02)` et 200ms, comme le brief. Sur `transform` uniquement : c'est
   la seule propriete, avec `opacity`, qu'un navigateur anime sans recalculer
   la mise en page — animer `width` ou `padding` ferait sauter la ligne de
   boutons entiere a chaque survol.

   `:active` ramene a 1 : sans cela, le bouton reste gonfle sous le doigt sur
   mobile, ou `:hover` colle apres le toucher.
*/
.btn{transition:background .25s var(--ease-soft),border-color .25s var(--ease-soft),
  color .25s var(--ease-soft),transform .2s ease}
.btn:hover{transform:scale(1.02)}
.btn:active{transform:scale(.99)}
@media(prefers-reduced-motion:reduce){
  .btn:hover,.btn:active{transform:none}
}

/* ---------- P2-9 Squelette de chargement de la grille ---------- */

/*
   LE SQUELETTE EST DERRIERE L'IMAGE, PAS DEVANT. C'est ce qui le rend sur.
   S'il etait pose par-dessus et retire par JavaScript, une erreur de script
   laisserait un rectangle gris a la place de chaque produit. Ici l'image
   couvre le squelette des qu'elle est peinte, script ou pas — la classe
   `is-loaded` ne fait qu'eteindre l'animation.

   `aspect-ratio` reprend le format carre de `digisovia-card` : le squelette
   occupe donc exactement la place que l'image prendra, ce qui supprime le
   saut de mise en page au chargement.
*/
.product-card__media::before{content:'';position:absolute;inset:0;z-index:0;
  background:linear-gradient(90deg,var(--shade) 0%,var(--hover) 50%,var(--shade) 100%);
  background-size:200% 100%;
  /* SIX ITERATIONS, PAS `infinite`. Une image transparente laisserait sinon
     scintiller le fond pour toujours si le script qui pose `is-loaded` ne
     s'executait pas. Au bout de ~8 s l'animation s'arrete d'elle-meme sur un
     aplat neutre : le pire cas est un fond fixe, jamais un clignotement. */
  animation:dgs-shimmer 1.4s linear 6}
.product-card__media.is-loaded::before{display:none}
.product-card__media img{position:relative;z-index:1}
@keyframes dgs-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}
@media(prefers-reduced-motion:reduce){
  .product-card__media::before{animation:none}
}

/* ---------- P2-10 Le mesh du hero ---------- */

/*
   Le degrade du brief — 135deg, #8B5CF6 vers #6366F1 — pose DERRIERE le
   titre, entre le film et le texte (z-index 1 ; `.hero__inner` est a 2).

   IL EST FAIBLE, ET C'EST MESURE. Le titre du hero est blanc sur un fond
   quasi noir : 16,9:1. Deux lavis radiaux a 16 % d'opacite laissent ce
   rapport au-dessus de 14:1, la ou un aplat du degrade a pleine opacite
   ferait tomber le blanc sur violet a 3,6:1 — sous le seuil AA. Les valeurs
   viennent des jetons `--hero-wash-*`, qui ont deja les deux rampes.

   `pointer-events:none` : le mesh ne doit intercepter aucun clic sur les
   boutons d'appel a l'action qu'il recouvre.
*/
.hero::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(60% 70% at 18% 22%,var(--hero-wash-1) 0%,transparent 68%),
    radial-gradient(52% 62% at 82% 78%,var(--hero-wash-2) 0%,transparent 66%),
    linear-gradient(135deg,rgba(139,92,246,.10) 0%,rgba(99,102,241,.10) 100%)}
/* Sur le hero filme, le film porte deja sa propre lumiere : le mesh
   s'efface pour ne pas laver l'image. */
.hero.has-film::before{opacity:.45}

/* ---------- P5-17 Anneau de focus ---------- */

/*
   LE BRIEF DEMANDE `outline:2px solid #8B5CF6`. MESURE AVANT D'APPLIQUER :

     #8B5CF6 sur #0B0F16 (fond)          4,53:1
     #8B5CF6 sur #151B26 (carte)         4,08:1
     #8B5CF6 sur #FFFFFF (theme clair)   4,23:1
     var(--accent) sur #0B0F16           7,05:1
     var(--accent) sur #FFFFFF           6,29:1

   Un indicateur de focus doit atteindre 3:1 : le violet du brief passe donc,
   partout. Mais `--accent` — qui EST ce violet, eclairci pour la rampe
   sombre — fait mieux dans les deux themes, et il bascule. On garde donc le
   jeton plutot que la valeur figee, ce qui est aussi la regle du bloc 1.

   L'anneau interieur blanc/sombre en `box-shadow` est ce qui rend le focus
   visible sur un bouton DEJA violet, cas ou une bordure violette sur fond
   violet ne se voit pas du tout. C'est le defaut classique d'un anneau a une
   seule couleur.
*/
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px;
  box-shadow:0 0 0 1px var(--paper)}
.btn:focus-visible,.product-card__quick:focus-visible{outline-offset:2px}
/* Le lien d'evitement doit rester lisible : il apparait sur le fond de page,
   pas sur une surface. */
.skip-link:focus-visible{box-shadow:none}

/* ---------- P1-5 Suggestions de recherche ---------- */

/* La vignette et le prix rejoignent le resultat : c'est ce que le brief
   demande, et c'est ce qui permet de reconnaitre « Office 2019 » de
   « Office 2021 » sans lire la ligne entiere. */
.search-result{gap:1rem;text-decoration:none;color:inherit}
.search-result img{width:48px;height:48px;flex:none;object-fit:cover;background:var(--shade)}
.search-result__text{flex:1;min-width:0;display:flex;flex-direction:column;gap:.15rem;text-align:left}
.search-result__name{font-size:1rem;line-height:1.3;color:var(--ink)}
.search-result:hover .search-result__name{color:var(--accent)}
.search-result .num{white-space:nowrap;color:var(--ink-2)}
.search-result--all{justify-content:center;font-size:.875rem;color:var(--accent);border-bottom:0}
.search-panel__results[aria-busy="true"]{opacity:.5;transition:opacity .2s}

/* ---------- P4-16 Page « Why DIGISOVIA » ---------- */

.why-figures{list-style:none;margin:1.5rem 0 0;padding:0;display:grid;gap:1.5rem;
  grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.why-figures li{padding:1.25rem;border:1px solid var(--line);background:var(--surface)}
.why-figures__value{display:block;font-size:clamp(1.5rem,3vw,2.1rem);font-weight:700;
  line-height:1.1;color:var(--ink);font-variant-numeric:tabular-nums}
.why-figures__label{display:block;margin-top:.35rem;font-size:.8125rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-3)}
.why-figures__note{display:block;margin-top:.75rem;font-size:.875rem;line-height:1.5;color:var(--ink-2)}

/* Le tableau defile dans SON PROPRE conteneur, jamais la page.
   Deux colonnes de texte sous 480 px depassent forcement ; sans ce conteneur,
   c'est le document entier qui defile horizontalement — le defaut le plus
   visible d'un tableau sur mobile. */
.why-table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.why-table{width:100%;border-collapse:collapse;min-width:34rem;text-align:left}
.why-table th,.why-table td{padding:.9rem 1rem;border-bottom:1px solid var(--line);
  vertical-align:top;font-size:.9375rem;line-height:1.5}
.why-table thead th{font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3);border-bottom-color:var(--line-strong)}
.why-table tbody th{font-weight:600;color:var(--ink);width:34%}
.why-table td{color:var(--ink-2)}

.why-steps{list-style:none;margin:0;padding:0;display:grid;gap:.75rem;counter-reset:none}
.why-steps li{display:flex;align-items:center;gap:1rem;padding:.9rem 1rem;
  border:1px solid var(--line);background:var(--surface)}
.why-steps__n{flex:none;width:2rem;height:2rem;display:grid;place-items:center;border-radius:50%;
  font-size:.8125rem;font-weight:700;color:var(--white);background:var(--accent)}
.why-steps__label{font-size:.9375rem;color:var(--ink)}


/* ==========================================================================
   RECHERCHE ET PAIEMENT — RECOMPOSITION DU 2026-08-31
   ==========================================================================

   Refonte visuelle de deux ecrans seulement. Aucune regle ici ne touche a la
   grille produit, au pied de page, a l'accueil ni au reste du theme.

   TROIS CONTRAINTES TENUES PARTOUT DANS CE BLOC :

   1. JETONS UNIQUEMENT. Pas une couleur litterale. Les deux themes definissent
      --surface, --line, --ink*, --accent, --field et --success ; une regle
      ecrite avec un #hex ne basculerait que dans un sens. Le projet a deja
      paye ce defaut : un champ peint en --white donnait 1,13:1 de contraste
      en theme sombre, et le client ne voyait pas ce qu'il tapait.

   2. RAYON CONSTANT. --r-ctl pour les commandes, --r-box pour les blocs. Les
      rayons melanges (9 px ici, 12 px la, 0 ailleurs) sont l'une des causes
      du « pas assez premium » : l'oeil lit l'incoherence avant de lire la
      page.

   3. LES HAUTEURS DE COMMANDES SONT EGALES. --ctl-h partout. Une rangee ou le
      champ fait 43 px et le compteur 22 px n'a pas de ligne de base commune.
   ========================================================================== */

:root{
  --r-ctl:10px;
  --r-box:14px;
  --ctl-h:44px;
}

/* ==========================================================================
   1. BARRE D'OUTILS DE LA BOUTIQUE
   ==========================================================================
   Mesure avant : rangee de 901 px, contenu arrete a 749 px, ordre
   [recherche][tri][compteur] tasse a gauche. Apres : le compteur tient le
   bord gauche, les commandes tiennent le bord droit, et le vide devient une
   respiration entre deux groupes au lieu d'une fin de ligne ratee.
   ------------------------------------------------------------------------- */
.shop-toolbar{
  display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;
  margin-bottom:1.75rem;padding-bottom:1.1rem;
  border-bottom:1px solid var(--line);
}
/* Le seul separateur de la rangee : un filet sous la barre, plutot qu'un
   cadre autour de chaque commande. */
.shop-count{
  order:1;font-size:.875rem;color:var(--ink-3);
  font-variant-numeric:tabular-nums;line-height:var(--ctl-h);
}
.shop-toolbar__controls{
  order:2;margin-left:auto;               /* l'ancre du bord droit */
  display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;
}

/* Le declencheur de recherche et le tri : meme hauteur, meme rayon, meme
   grammaire. Ils se lisent comme une paire, pas comme deux accidents. */
.shop-search-btn,
.shop-toolbar select,
.shop-toolbar .orderby{
  height:var(--ctl-h);border-radius:var(--r-ctl);
  border:1px solid var(--line);background:var(--surface);
  font-size:.9rem;color:var(--ink-2);
}
.shop-search-btn{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:.5rem;
  padding:0 1rem;text-decoration:none;max-width:min(16rem,52vw);
  transition:border-color .18s var(--ease),color .18s var(--ease),background-color .18s var(--ease);
}
.shop-search-btn svg{
  width:16px;height:16px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.8;stroke-linecap:round;
}
.shop-search-btn span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.shop-search-btn:hover{border-color:var(--line-strong);color:var(--ink);background:var(--hover)}
.shop-search-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Sur une page de resultats le declencheur porte la requete : il cesse d'etre
   une invitation et devient l'etat courant, donc il se signale. */
.shop-search-btn.is-active{border-color:var(--accent-line);color:var(--ink);background:var(--accent-wash)}
.shop-toolbar select,.shop-toolbar .orderby{padding:0 2.25rem 0 .9rem}
.shop-toolbar .woocommerce-ordering{margin:0}

/* Le champ permanent n'existe plus dans le gabarit ; la regle reste le temps
   que le cache LiteSpeed se vide. */
.shop-search{flex:0 1 auto;max-width:20rem}

/* ==========================================================================
   2. PANNEAU DE RECHERCHE
   ==========================================================================
   Mesure avant : un champ de 36 px de police pose sur du vide, puis des
   lignes de 900 px ou le nom et le prix etaient separes par 800 px de rien.
   Avant la troisieme lettre, l'ecran ne montrait RIEN — un panneau modal vide
   se lit comme une panne.

   La colonne passe a 640 px : a 900 px, une ligne de resultat force l'oeil a
   traverser tout l'ecran pour relier un nom a son prix.
   ------------------------------------------------------------------------- */
.search-panel{
  position:fixed;inset:0;z-index:130;
  background:color-mix(in srgb,var(--paper) 94%,transparent);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  padding:0;display:grid;align-items:start;
  opacity:0;visibility:hidden;
  transition:opacity .22s var(--ease-soft),visibility .22s;
}
.search-panel.is-open{opacity:1;visibility:visible}

.search-panel__body{
  width:min(640px,100%);margin-inline:auto;
  padding:clamp(1rem,6vh,4.5rem) var(--gutter) 0;
  display:flex;flex-direction:column;min-height:0;max-height:100vh;
}

/* --- La barre : champ et fermeture dans la MEME rangee ---
   Le bouton de fermeture etait en position absolue dans le coin de l'ecran,
   sans rapport visuel avec le champ qu'il ferme. */
.search-panel__bar{display:flex;align-items:center;gap:.6rem;flex:none}
.search-panel__form{
  flex:1;min-width:0;display:flex;align-items:center;gap:.7rem;
  height:56px;padding:0 1rem;margin:0;max-width:none;
  background:var(--field);border:1px solid var(--line-strong);
  border-radius:var(--r-ctl);
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
.search-panel__form:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
.search-panel__icon{flex:none;display:flex;color:var(--ink-3)}
.search-panel__icon svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
.search-panel__input{
  flex:1;min-width:0;border:0;background:none;outline:none;
  font-family:inherit;font-size:1.0625rem;font-weight:400;color:var(--ink);
  height:100%;
}
.search-panel__input::placeholder{color:var(--ink-4)}
.search-panel__input::-webkit-search-cancel-button{display:none}

.search-close{
  flex:none;display:inline-flex;align-items:center;gap:.4rem;
  height:56px;padding:0 .85rem;border-radius:var(--r-ctl);
  background:none;border:1px solid transparent;color:var(--ink-3);cursor:pointer;
  transition:color .18s var(--ease),border-color .18s var(--ease);
}
.search-close svg{width:18px;height:18px}
.search-close__key{
  font-size:.6875rem;letter-spacing:.06em;text-transform:uppercase;
  border:1px solid var(--line-strong);border-radius:5px;padding:.1rem .35rem;
}
.search-close:hover{color:var(--ink);border-color:var(--line)}
.search-close:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* --- La zone defilante ---
   Le panneau occupe l'ecran ; seule la liste defile. Sans cela, une longue
   liste pousse la barre de recherche hors de vue. */
.search-panel__scroll{
  flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:1.5rem 0 2rem;margin-top:.25rem;
}

/* --- Etiquettes de section --- */
.search-section{
  font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-4);margin:0 0 .85rem;font-weight:500;
}
.search-hint{font-size:.8125rem;color:var(--ink-4);margin:1.25rem 0 0}

/* --- Etat d'attente : les rayons reels du catalogue --- */
.search-chips{display:flex;flex-wrap:wrap;gap:.5rem}
.search-chip{
  display:inline-flex;align-items:center;height:36px;padding:0 .9rem;
  border:1px solid var(--line);border-radius:999px;background:var(--surface);
  font-size:.875rem;color:var(--ink-2);text-decoration:none;
  transition:border-color .18s var(--ease),color .18s var(--ease),background-color .18s var(--ease);
}
.search-chip:hover{border-color:var(--accent-line);color:var(--accent);background:var(--accent-wash)}
.search-chip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* --- Un resultat ---
   Grille en trois colonnes plutot que `space-between` : la vignette, le texte
   et le prix ont chacun leur piste, et le prix ne part plus a 800 px du nom.
   Plus de filet entre les lignes non plus — c'est le survol qui separe. */
.search-result{
  display:grid;grid-template-columns:56px minmax(0,1fr) auto;
  align-items:center;gap:.95rem;
  padding:.7rem;border:0;border-radius:var(--r-box);
  text-decoration:none;color:inherit;
  transition:background-color .16s var(--ease);
}
.search-result+.search-result{margin-top:.15rem}
.search-result:hover,.search-result:focus-visible{background:var(--hover);padding-inline:.7rem}
.search-result:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.search-result__img{
  width:56px;height:56px;border-radius:9px;object-fit:cover;
  background:var(--shade);border:1px solid var(--line);
}
.search-result__text{display:flex;flex-direction:column;gap:.2rem;min-width:0}
.search-result__name{
  font-size:.9375rem;font-weight:500;line-height:1.35;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.search-result__meta{
  font-size:.78125rem;color:var(--ink-4);line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.search-result__price{
  font-size:.9375rem;font-weight:600;color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right;
}
/* Un produit indisponible ne porte PAS un prix : il porte son etat. La regle
   du projet est que rien d'achetable ne s'affiche pour ce qui ne l'est pas. */
.search-result__soon{
  font-size:.75rem;font-weight:500;letter-spacing:.02em;
  color:var(--warning);background:color-mix(in srgb,var(--warning) 14%,transparent);
  border-radius:999px;padding:.2rem .55rem;white-space:nowrap;
}
.search-result.is-soon .search-result__img{opacity:.62}

/* --- Voir tous les resultats --- */
.search-all{
  display:flex;align-items:center;justify-content:center;gap:.45rem;
  margin-top:.9rem;height:var(--ctl-h);border-radius:var(--r-ctl);
  border:1px solid var(--line);background:var(--surface);
  font-size:.875rem;font-weight:500;color:var(--ink-2);text-decoration:none;
  transition:border-color .18s var(--ease),color .18s var(--ease);
}
.search-all svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.search-all:hover{border-color:var(--accent-line);color:var(--accent)}
.search-all:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* --- Chargement : la hauteur exacte d'un resultat, pour que rien ne saute --- */
.search-skeleton{
  display:grid;grid-template-columns:56px minmax(0,1fr);align-items:center;
  gap:.95rem;padding:.7rem;
  animation:dgs-pulse 1.4s ease-in-out infinite;
}
.search-skeleton__img{width:56px;height:56px;border-radius:9px;background:var(--hover)}
.search-skeleton__lines{display:flex;flex-direction:column;gap:.45rem}
.search-skeleton__lines span{height:10px;border-radius:5px;background:var(--hover)}
.search-skeleton__lines span:first-child{width:58%}
.search-skeleton__lines span:last-child{width:34%}
@keyframes dgs-pulse{0%,100%{opacity:1}50%{opacity:.55}}

/* --- Aucun resultat --- */
.search-empty{padding:1.5rem 0}
.search-empty__title{font-size:1rem;color:var(--ink);margin:0}
.search-panel__results[aria-busy="true"]{opacity:.6;transition:opacity .2s}

/* ==========================================================================
   3. PAIEMENT
   ==========================================================================
   Mesure avant : colonne gauche 661 px, colonne droite 1637 px, soit
   1090 px de colonne gauche VIDE pendant que la droite continuait seule. Le
   bouton « Place order » tombait a 2248 px du haut — mille pixels sous la
   ligne de flottaison — et les garanties a 2497 px, apres tout le reste.

   CE QUI N'EST PAS FAIT, ET POURQUOI. Le bloc de paiement n'est PAS deplace
   vers la colonne gauche. Il est rendu par `woocommerce_checkout_order_review`,
   action a laquelle l'extension PayPal accroche aussi ses propres noeuds
   (.ppcp-messages, .ppc-button-wrapper, les boutons Apple Pay et Google Pay).
   Les separer disperserait le bouton PayPal loin de son bouton radio, et la
   consigne interdit de rejouer une transaction reelle pour le verifier.

   CE QUI EST FAIT A LA PLACE : la colonne de gauche devient un rail COLLANT.
   Le vide n'existe plus parce que le formulaire de contact reste en vue
   pendant tout le defilement de la colonne de paiement. Les garanties
   remontent entre le total et les moyens de paiement (voir checkout-trust.php).
   ------------------------------------------------------------------------- */
@media (min-width:1024px){
  .woocommerce-checkout form.checkout{
    display:grid;
    /* La colonne de paiement recoit la part large : c'est elle qui porte le
       formulaire de carte, et a 474 px il se comprimait en hauteur. */
    grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
    column-gap:clamp(2rem,4vw,3.5rem);
    align-items:start;
  }
  .woocommerce-checkout form.checkout #customer_details{
    position:sticky;top:calc(var(--nav-h) + 1.25rem);
  }
}

/* --- Colonne gauche : contact et facturation ---
   Pas de cartes. Des sections separees par un filet et de l'espace : le brief
   demande moins de boites, pas d'autres boites. */
.woocommerce-checkout form.checkout h3{
  font-size:.9375rem;font-weight:600;letter-spacing:.01em;color:var(--ink);
  margin:0 0 1.1rem;padding-bottom:.7rem;border-bottom:1px solid var(--line);
}
.woocommerce-checkout .col2-set{display:grid;grid-template-columns:1fr;gap:2.25rem}
.woocommerce-checkout .woocommerce-billing-fields__field-wrapper,
.woocommerce-checkout .woocommerce-additional-fields__field-wrapper{
  display:grid;grid-template-columns:repeat(12,1fr);gap:1rem .9rem;
}
.woocommerce-checkout .form-row{margin:0;display:grid;gap:.4rem}
.woocommerce-checkout label{
  font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3);font-weight:500;
}
.woocommerce-checkout .input-text,
.woocommerce-checkout select,
.woocommerce-checkout textarea,
.select2-container .select2-selection{
  height:var(--ctl-h);border-radius:var(--r-ctl);
  background:var(--field);border:1px solid var(--line-strong);
  color:var(--ink);font-size:.9375rem;padding:0 .9rem;width:100%;
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease);
}
.woocommerce-checkout textarea{height:auto;min-height:96px;padding:.75rem .9rem;line-height:1.5}
.woocommerce-checkout .input-text:focus,
.woocommerce-checkout select:focus,
.woocommerce-checkout textarea:focus{
  border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash);outline:none;
}
/* L'erreur se voit sur le champ, pas seulement dans une liste en haut de
   page : c'est la difference entre « il y a une erreur » et « c'est ici ». */
.woocommerce-checkout .woocommerce-invalid input.input-text,
.woocommerce-checkout .woocommerce-invalid select{
  border-color:var(--error);box-shadow:0 0 0 3px color-mix(in srgb,var(--error) 16%,transparent);
}
.woocommerce-checkout .woocommerce-validated input.input-text{border-color:var(--line-strong)}

/* --- Colonne droite : le recapitulatif est l'ancre visuelle ---
   Un seul bloc, un seul cadre. Avant : un cadre autour du recapitulatif, un
   autre autour des garanties, un troisieme autour du paiement. */
.woocommerce-checkout-review-order{
  border:1px solid var(--line);border-radius:var(--r-box);
  background:var(--surface);padding:clamp(1.25rem,2.4vw,1.75rem);margin-top:0;
}
.woocommerce-checkout-review-order table{width:100%;border-collapse:collapse}
.woocommerce-checkout-review-order th,
.woocommerce-checkout-review-order td{
  padding:.55rem 0;font-size:.9rem;text-align:left;border:0;
}
.woocommerce-checkout-review-order thead th{
  font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-4);font-weight:500;padding-bottom:.9rem;
}
.woocommerce-checkout-review-order .cart_item td{padding:.75rem 0;vertical-align:top}
.woocommerce-checkout-review-order td.product-name{color:var(--ink);line-height:1.45;padding-right:1rem}
.woocommerce-checkout-review-order .product-quantity{color:var(--ink-3);font-weight:500}
.woocommerce-checkout-review-order td.product-total,
.woocommerce-checkout-review-order .cart-subtotal td{
  text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink-2);
}
.woocommerce-checkout-review-order .cart-subtotal th{color:var(--ink-3);font-weight:400}
.woocommerce-checkout-review-order tfoot tr:not(.order-total) th,
.woocommerce-checkout-review-order tfoot tr:not(.order-total) td{
  padding:.4rem 0;font-size:.875rem;
}
/* Le total : le seul chiffre de la page qui doit se lire sans chercher. */
.woocommerce-checkout-review-order .order-total th,
.woocommerce-checkout-review-order .order-total td{
  border-top:1px solid var(--line);padding-top:1.05rem;
}
.woocommerce-checkout-review-order .order-total th{font-size:.9375rem;font-weight:600;color:var(--ink)}
.woocommerce-checkout-review-order .order-total td{
  text-align:right;font-size:1.5rem;font-weight:600;color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.01em;
}
.woocommerce-checkout-review-order .order-total td small{
  display:block;font-size:.75rem;font-weight:400;color:var(--ink-4);letter-spacing:0;margin-top:.15rem;
}
.checkout-line{display:flex;gap:.75rem;align-items:flex-start}
.checkout-line__thumb{
  flex:none;width:44px;height:44px;border-radius:8px;object-fit:cover;
  /* etait #F1F5F9 en dur : une vignette blanche dans un theme sombre. */
  background:var(--shade);border:1px solid var(--line);
}

/* --- Les garanties : de la reassurance, pas des cartes ---
   Elles remontent entre le total et les moyens de paiement. Sans cadre, sans
   fond : une liste sobre qui accompagne le total au lieu de le concurrencer. */
.dgs-checkout-trust{
  margin:1.25rem 0 0;padding:1.15rem 0 0;border-top:1px solid var(--line);
  border-radius:0;background:none;display:grid;gap:.7rem;list-style:none;
}
.dgs-checkout-trust li{
  display:flex;align-items:flex-start;gap:.6rem;margin:0;list-style:none;
  font-size:.8125rem;line-height:1.45;color:var(--ink-3);
}
.dgs-checkout-trust svg{
  width:15px;height:15px;flex:none;margin-top:.15rem;
  fill:none;stroke:var(--success);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;
}
.dgs-checkout-trust strong{display:block;color:var(--ink-2);font-weight:500;font-size:.84375rem}
.dgs-checkout-trust a{color:var(--ink-2);text-underline-offset:2px}
.dgs-checkout-trust a:hover{color:var(--accent)}

/* --- Moyens de paiement : des rangees, pas des cartes --- */
.woocommerce-checkout #payment{background:none;border:0;border-radius:0;margin-top:1.5rem}
.woocommerce-checkout #payment ul.payment_methods{
  padding:0;margin:0 0 1.25rem;border:0;list-style:none;
  display:grid;gap:.5rem;
}
.woocommerce-checkout #payment ul.payment_methods li{
  padding:0;margin:0;list-style:none;
  border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--surface);
  transition:border-color .16s var(--ease);
}
.woocommerce-checkout #payment ul.payment_methods li>label{
  display:flex;align-items:center;gap:.6rem;cursor:pointer;
  padding:.9rem 1rem;margin:0;
  font-size:.9375rem;letter-spacing:0;text-transform:none;
  color:var(--ink);font-weight:500;
}
.woocommerce-checkout #payment ul.payment_methods li>input[type=radio]{margin:0 0 0 1rem}
.woocommerce-checkout #payment div.payment_box{
  background:none;border:0;border-top:1px solid var(--line);
  margin:0;padding:1rem;font-size:.875rem;color:var(--ink-3);border-radius:0;
}
.woocommerce-checkout #payment div.payment_box::before{display:none}

/* --- Conditions et bouton --- */
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper{
  margin:0 0 1.15rem;font-size:.8125rem;color:var(--ink-3);
}
.woocommerce-checkout .woocommerce-terms-and-conditions{
  max-height:150px;border:1px solid var(--line);border-radius:var(--r-ctl);
  padding:.9rem 1rem;background:var(--surface);
}
.woocommerce-checkout .form-row.place-order{margin:0;padding:0}
.woocommerce-checkout #place_order{
  width:100%;height:54px;border-radius:var(--r-ctl);
  font-size:1rem;font-weight:600;letter-spacing:.01em;
  background:var(--accent);color:var(--white);border:0;cursor:pointer;
  transition:filter .16s var(--ease),transform .16s var(--ease);
}
.woocommerce-checkout #place_order:hover{filter:brightness(1.08)}
.woocommerce-checkout #place_order:active{transform:translateY(1px)}
.woocommerce-checkout #place_order:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.woocommerce-checkout form.checkout.processing #place_order{opacity:.6;cursor:progress}

/* ==========================================================================
   4. MOBILE — 375 / 390 px
   ==========================================================================
   Une seule colonne, dans l'ordre ou la decision se prend : ce que j'achete,
   ou ca va, comment je paie.
   ------------------------------------------------------------------------- */
@media (max-width:1023px){
  .woocommerce-checkout form.checkout{display:block}
  .woocommerce-checkout-review-order{margin-top:1.5rem}
  .woocommerce-checkout form.checkout #customer_details{position:static}
}

@media (max-width:640px){
  .search-panel__body{padding-inline:1.15rem;padding-top:.85rem}
  .search-panel__form{height:52px}
  .search-panel__input{font-size:16px} /* 16px : en dessous, iOS zoome au focus */
  .search-close{height:52px;padding:0 .6rem}
  .search-close__key{display:none}
  .search-panel__scroll{padding-top:1.15rem}
  .search-result{grid-template-columns:48px minmax(0,1fr) auto;gap:.75rem;padding:.6rem}
  .search-result__img{width:48px;height:48px}
  .search-skeleton{grid-template-columns:48px minmax(0,1fr);gap:.75rem;padding:.6rem}
  .search-skeleton__img{width:48px;height:48px}

  .shop-toolbar{gap:.6rem}
  .shop-toolbar__controls{width:100%;margin-left:0}
  .shop-search-btn{flex:1 1 auto;max-width:none;justify-content:center}
  .shop-toolbar .woocommerce-ordering,.shop-toolbar select{flex:1 1 auto}
  .shop-count{order:0;width:100%;line-height:1.4}

  .woocommerce-checkout-review-order{padding:1.15rem}
  .woocommerce-checkout-review-order .order-total td{font-size:1.35rem}
  .woocommerce-checkout #place_order{height:52px}
  /* Le bouton reste dans le flux : une barre fixe en bas masquerait le total
     sur un ecran de 375 px, qui est precisement ce qu'on veut lire avant. */
}

@media (prefers-reduced-motion:reduce){
  .search-panel,.search-result,.search-chip,.shop-search-btn,.search-all,
  .woocommerce-checkout #place_order{transition:none}
  .search-skeleton{animation:none}
}

/* --- Deux portees a corriger, trouvees en relisant le rendu reel ---

   1. LES CONDITIONS GENERALES SONT RENDUES DANS LE FORMULAIRE. WooCommerce
      injecte le contenu entier de la page CGV dans la boite deroulante du
      paiement : « Who we are », « What we sell », « Tax », « Governing law »…
      quatorze titres. La regle de section ci-dessus leur aurait pose a chacun
      un filet et une marge de 1,1 rem a l'interieur d'une boite de 150 px de
      haut, qui serait devenue illisible.

   2. LES CASES A COCHER NE SONT PAS DES ETIQUETTES DE CHAMP. L'etiquette
      capitale espacee convient a « EMAIL » au-dessus d'un champ ; appliquee a
      « J'accepte les conditions generales », elle donne une phrase entiere en
      majuscules a cote d'une case. */
.woocommerce-checkout .woocommerce-terms-and-conditions h2,
.woocommerce-checkout .woocommerce-terms-and-conditions h3,
.woocommerce-checkout .woocommerce-terms-and-conditions h4{
  font-size:.875rem;font-weight:600;color:var(--ink);
  margin:1rem 0 .35rem;padding:0;border:0;letter-spacing:0;
}
.woocommerce-checkout .woocommerce-terms-and-conditions h2:first-child,
.woocommerce-checkout .woocommerce-terms-and-conditions h3:first-child{margin-top:0}
.woocommerce-checkout .woocommerce-terms-and-conditions p{font-size:.8125rem;line-height:1.55;margin:0 0 .5rem}

.woocommerce-checkout label.woocommerce-form__label-for-checkbox,
.woocommerce-checkout .form-row label.checkbox,
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper label{
  display:flex;align-items:flex-start;gap:.55rem;
  font-size:.8125rem;letter-spacing:0;text-transform:none;
  color:var(--ink-3);font-weight:400;line-height:1.45;cursor:pointer;
}
.woocommerce-checkout label.woocommerce-form__label-for-checkbox input[type=checkbox],
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper input[type=checkbox]{
  flex:none;width:16px;height:16px;margin:.15rem 0 0;accent-color:var(--accent);
}

/* Le champ de commentaire de commande porte son etiquette au-dessus comme les
   autres, mais sa hauteur est libre : la regle de hauteur fixe des commandes
   ne doit pas l'ecraser. */
.woocommerce-checkout #order_comments{height:auto}

/* --- Les garanties en deux colonnes ---

   Empilees, les quatre lignes occupaient 301 px entre le total et les moyens
   de paiement : assez pour repousser le choix du moyen de paiement hors de
   l'ecran sur un portable. En deux colonnes elles tiennent en deux rangees,
   et se lisent d'un coup d'oeil — ce qu'on attend d'une reassurance, qu'on
   parcourt, par opposition a un argumentaire, qu'on lit.

   Une seule colonne en dessous de 560 px : a cette largeur, deux colonnes
   couperaient « Instant digital delivery » en trois lignes. */
@media (min-width:560px){
  .dgs-checkout-trust{grid-template-columns:1fr 1fr;gap:.85rem 1.5rem}
}

/* Le bloc de paiement ne porte plus son propre retrait interieur.

   Il gardait `padding:20px` de WooCommerce alors que le recapitulatif qui le
   precede en a deja un : le contenu du paiement se retrouvait rentre de 38 px
   quand le tableau de commande l'etait de 18 px. Deux retraits emboites, deux
   bords gauches differents dans une meme colonne — c'est precisement ce que
   le brief appelle « boites imbriquees ». Le bouton reprend du meme coup la
   pleine largeur de la colonne. */
.woocommerce-checkout #payment{padding:0}

/* La pastille « Coming soon » : le texte se melange vers l'encre.

   MESURE : `var(--warning)` pose tel quel donnait **2,15:1** en theme clair —
   de l'ambre sur du blanc. C'est sous le seuil AA (4,5:1), et c'est l'etiquette
   qui porte l'information la plus importante d'un resultat non achetable.
   En theme sombre le meme jeton passait, ce qui est exactement le piege des
   couleurs semantiques : elles sont concues pour une seule rampe.

   `color-mix` avec `--ink` corrige dans les DEUX SENS sans coder de couleur :
   l'encre est sombre en theme clair (l'ambre fonce) et claire en theme sombre
   (l'ambre s'eclaircit). Un jeton fige aurait casse l'autre theme. */
.search-result__soon{
  color:color-mix(in srgb,var(--warning) 55%,var(--ink));
  background:color-mix(in srgb,var(--warning) 16%,transparent);
}

/* --- Deux echecs de contraste mesures le 2026-08-31, corriges par jetons ---

   1. LE BOUTON DE PAIEMENT ETAIT A 2,72:1 EN THEME SOMBRE.
      `color:var(--white)` sur `background:var(--accent)` : en theme clair
      l'accent est un indigo profond (#4F46E5) et le blanc passe a 6,29:1 ; en
      theme sombre l'accent est un periwinkle CLAIR (#8B93FF) et le blanc
      dessus devient illisible. Le bouton le plus important de la boutique
      echouait AA dans le theme qui est l'identite principale du site.

      `var(--paper)` est le fond de page : sombre en theme sombre, blanc en
      theme clair. Pose sur l'accent, il contraste donc TOUJOURS, sans qu'on
      ait a ecrire deux regles ni une seule couleur.

   2. LES ETIQUETTES DE CHAMP ETAIENT A 4,48:1 EN THEME CLAIR — sous le seuil
      AA de 4,5:1, de justesse. Elles passent a `--ink-2`. La hierarchie tient
      quand meme : ce sont les capitales de 12 px espacees qui les designent
      comme etiquettes, pas leur paleur. */
.woocommerce-checkout #place_order{color:var(--paper)}

.woocommerce-checkout label{color:var(--ink-2)}
/* Les etiquettes de case a cocher gardent leur ton secondaire : ce sont des
   phrases, pas des etiquettes de champ, et elles sont a 4,76:1. */
.woocommerce-checkout label.woocommerce-form__label-for-checkbox,
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper label{color:var(--ink-3)}

/* La ligne de consentement passe elle aussi a `--ink-2`.

   Mesuree a 4,48:1 en theme clair, soit deux centiemes sous AA. C'est du
   texte courant de 13 px, et c'est la phrase par laquelle le client accepte
   les conditions generales : la derniere du formulaire a pouvoir rester pale.
   Le ton secondaire vient desormais de sa taille, pas de son contraste. */
.woocommerce-checkout label.woocommerce-form__label-for-checkbox,
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper label{color:var(--ink-2)}

/* ==========================================================================
   PAIEMENT — RECOMPOSITION EDITORIALE, 2026-08-31 (2e passe)
   ==========================================================================

   La premiere passe avait corrige les MESURES (colonnes, positions, hauteurs)
   sans corriger la COMPOSITION. Les captures d'ecran du client montrent ce
   que les mesures ne disaient pas : un empilement de cadres, une ligne
   produit dont la quantite flotte sous la vignette, des metadonnees en
   « Platform: » / « Region: » comme un tableau de base de donnees, et un
   recapitulatif qui ressemble a du WooCommerce habille.

   PRINCIPE DE CETTE PASSE : typographie, blanc, alignement, filets.
   Pas de carte dans une carte. Un seul cadre sur toute la page — aucun, en
   fait : le recapitulatif se tient par ses filets et son alignement.

   CE QUI N'EST PAS TOUCHE, et c'est verifie apres coup : aucun hook
   WooCommerce, aucun gabarit, aucun composant Stripe ou PayPal. Le
   deplacement du bloc de paiement vers la colonne de gauche — demande par le
   brief — se fait en CSS pure via `display:contents`, qui promeut les enfants
   de `#order_review` au rang d'elements de la grille du formulaire. Le DOM
   est rigoureusement identique ; seule la place a l'ecran change. Les
   fragments AJAX de WooCommerce ciblent des CLASSES
   (`.woocommerce-checkout-review-order-table`, `.woocommerce-checkout-payment`)
   et continuent donc de les retrouver ou qu'elles soient.
   ========================================================================== */

/* ---------- La grille : formulaire + paiement a gauche, resume a droite --- */
@media (min-width:1024px){
  .woocommerce-checkout form.checkout{
    display:grid;
    /* 1,5 / 1 = 60 % / 40 %, la proportion demandee au 2026-09-01.
       L'etat precedent (1,15 / 0,85) mesurait 57,5 % / 42,5 % sur la page
       reelle a 1440 px : le recapitulatif prenait plus de place que la saisie
       alors qu'il ne se lit qu'une fois. */
    grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
    column-gap:clamp(2.5rem,5vw,4.5rem);
    align-items:start;
  }

  /* La promotion. Sans elle, le bloc de paiement resterait prisonnier de
     `#order_review` et donc de la colonne de droite. */
  .woocommerce-checkout #order_review{display:contents}

  /* Colonne 1 — ce que le client remplit, dans l'ordre ou il le remplit.
     `1/4` : le formulaire couvre la hauteur des trois rangees du resume. S'il
     est plus court, il reste cale en haut ; s'il est plus long, les rangees
     s'etirent. Aucun des deux cas ne casse quoi que ce soit. */
  .woocommerce-checkout form.checkout #customer_details{
    grid-column:1;grid-row:1/4;position:static;
  }
  .woocommerce-checkout form.checkout .dgs-checkout-trust{grid-column:1;grid-row:4}
  .woocommerce-checkout form.checkout .ppcp-messages{grid-column:1;grid-row:5}
  .woocommerce-checkout form.checkout #payment{grid-column:1;grid-row:6}
  .woocommerce-checkout form.checkout .ppc-button-wrapper,
  .woocommerce-checkout form.checkout #ppc-button-ppcp-applepay,
  .woocommerce-checkout form.checkout #ppc-button-ppcp-googlepay{grid-column:1}

  /* Colonne 2 — le resume, et il SUIT LE DEFILEMENT.
     `grid-row:2/-1` lui donne toute la hauteur restante de la colonne ; le
     `sticky` epingle son contenu a l'interieur. C'est ce qui supprime le vide
     de 1090 px mesure a la passe precedente sans deplacer une seule ligne de
     PHP. Il ne peut pas chevaucher le pied de page : un element colle reste
     borne par sa zone de grille, qui s'arrete avec le formulaire. */
  .woocommerce-checkout form.checkout #order_review_heading{grid-column:2;grid-row:1}
  .woocommerce-checkout .woocommerce-checkout-review-order-table{
    grid-column:2;grid-row:2/-1;align-self:start;
    position:sticky;top:calc(var(--nav-h) + 1.5rem);
  }
}

/* ---------- Le resume : plus de carte ----------
   Il portait un cadre, un fond et 28 px de retrait, et contenait lui-meme le
   paiement encadre. Deux boites imbriquees pour une information qui tient sur
   quatre lignes. */
.woocommerce-checkout-review-order{border:0;background:none;padding:0;border-radius:0;margin:0}

.woocommerce-checkout form.checkout #order_review_heading{
  font-family:var(--font-display,inherit);
  font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
  font-weight:600;color:var(--ink-4);
  margin:0 0 1.1rem;padding:0 0 .9rem;border-bottom:1px solid var(--line-strong);
}

.woocommerce-checkout-review-order-table{width:100%;border-collapse:collapse;margin:0}
/* L'en-tete « Product | Subtotal » ne dit rien qu'un client ne sache deja en
   regardant une image, un nom et un prix. Il part. */
.woocommerce-checkout-review-order-table thead{display:none}

/* ---------- La ligne produit ----------

   CE QUI N'ALLAIT PAS, releve dans le DOM rendu :

     <td class="product-name">
       <span class="checkout-line"><img><span>Nom</span></span>
       <strong class="product-quantity">× 1</strong>     <-- HORS du flex
       <dl class="variation"><dt>Platform:</dt><dd>…</dd></dl>
     </td>
     <td class="product-total">$2.00</td>

   La quantite tombait donc SOUS la vignette, detachee du nom comme du prix,
   et le prix vivait dans une cellule a part, aligne en haut a droite, sans
   rapport visuel avec la ligne. D'ou l'impression de casse sur les captures.

   `display:contents` sur la cellule et sur `.checkout-line` remet les cinq
   morceaux — vignette, nom, prix, quantite, metadonnees — dans UNE grille
   commune. Rien n'est masque, rien n'est duplique, chaque donnee reste celle
   de WooCommerce : seule leur place change.

   La composition suit la reference fournie par le client : nom et prix sur la
   meme ligne, le reste en gris dessous. */
.woocommerce-checkout-review-order-table .cart_item{
  display:grid;
  grid-template-columns:64px minmax(0,1fr) auto;
  column-gap:1rem;row-gap:.2rem;
  align-items:start;
  padding:1.15rem 0;border-bottom:1px solid var(--line);
}
.woocommerce-checkout-review-order-table .cart_item:first-child{padding-top:0}
.woocommerce-checkout-review-order-table .cart_item .product-name{display:contents}
.woocommerce-checkout-review-order-table .checkout-line{display:contents}

.woocommerce-checkout-review-order-table .checkout-line__thumb{
  grid-column:1;grid-row:1/span 3;
  width:64px;height:64px;border-radius:10px;object-fit:cover;
  background:var(--shade);border:1px solid var(--line);
}
.woocommerce-checkout-review-order-table .checkout-line__text{
  grid-column:2;grid-row:1;
  font-size:.9375rem;font-weight:500;line-height:1.35;color:var(--ink);
}
.woocommerce-checkout-review-order-table .cart_item .product-total{
  grid-column:3;grid-row:1;
  text-align:right;font-size:.9375rem;font-weight:600;color:var(--ink);
  font-variant-numeric:tabular-nums;white-space:nowrap;padding:0;border:0;
}
.woocommerce-checkout-review-order-table .product-quantity{
  grid-column:2/-1;grid-row:2;
  font-size:.8125rem;font-weight:400;color:var(--ink-3);
  font-variant-numeric:tabular-nums;
}

/* Les metadonnees : les valeurs, pas les etiquettes.
   « Windows / macOS / Web » et « Global » se comprennent seuls ; « Platform: »
   devant chacun ajoute deux mots et une colonne pour rien. Les `<dt>` restent
   dans le DOM pour les lecteurs d'ecran — l'information ne disparait pas,
   elle cesse seulement d'etre peinte. */
.woocommerce-checkout-review-order-table .variation{
  grid-column:2/-1;grid-row:3;
  display:flex;flex-wrap:wrap;gap:0 .45rem;margin:.1rem 0 0;
  font-size:.8125rem;line-height:1.4;color:var(--ink-4);
}
.woocommerce-checkout-review-order-table .variation dt{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.woocommerce-checkout-review-order-table .variation dd{margin:0;padding:0}
.woocommerce-checkout-review-order-table .variation dd p{margin:0}
.woocommerce-checkout-review-order-table .variation dd:not(:first-of-type)::before{
  content:"·";margin-right:.45rem;color:var(--ink-4);
}

/* ---------- Totaux : la typographie fait la hierarchie, pas un cadre ---- */
.woocommerce-checkout-review-order-table tfoot{display:block;padding-top:1.1rem}
.woocommerce-checkout-review-order-table tfoot tr{
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
}
.woocommerce-checkout-review-order-table tfoot th,
.woocommerce-checkout-review-order-table tfoot td{
  padding:.3rem 0;border:0;text-align:left;font-size:.875rem;
}
.woocommerce-checkout-review-order-table tfoot th{color:var(--ink-3);font-weight:400}
.woocommerce-checkout-review-order-table tfoot td{
  color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right;
}
.woocommerce-checkout-review-order-table .order-total{
  margin-top:.85rem;padding-top:1rem;border-top:1px solid var(--line-strong);
}
.woocommerce-checkout-review-order-table .order-total th{
  font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
  font-weight:600;color:var(--ink-3);
}
.woocommerce-checkout-review-order-table .order-total td{
  font-size:1.75rem;font-weight:600;color:var(--ink);letter-spacing:-.02em;line-height:1.1;
}
.woocommerce-checkout-review-order-table .order-total td small{
  display:block;font-size:.75rem;font-weight:400;color:var(--ink-4);
  letter-spacing:0;margin-top:.2rem;
}

/* ---------- Les garanties : une bande, pas des cartes ---- */
.dgs-checkout-trust{
  margin:2.25rem 0 0;padding:1.15rem 0 0;
  border-top:1px solid var(--line);border-bottom:0;border-radius:0;background:none;
  display:grid;grid-template-columns:1fr 1fr;gap:.8rem 1.5rem;list-style:none;
}
.dgs-checkout-trust li{
  display:flex;align-items:flex-start;gap:.55rem;margin:0;
  font-size:.78125rem;line-height:1.4;color:var(--ink-4);
}
.dgs-checkout-trust svg{
  width:14px;height:14px;flex:none;margin-top:.2rem;
  stroke:var(--success);stroke-width:2.6;fill:none;stroke-linecap:round;stroke-linejoin:round;
}
.dgs-checkout-trust strong{
  display:block;color:var(--ink-2);font-weight:500;font-size:.8125rem;margin-bottom:.05rem;
}

/* ---------- Paiement ----------
   Stripe garde exactement la place qu'il demande : aucun retrait ajoute
   autour de ses composants, aucun style pose sur ses iframes. */
.woocommerce-checkout #payment{
  background:none;border:0;border-radius:0;padding:0;margin:2.25rem 0 0;
}
.woocommerce-checkout #payment>ul.payment_methods{
  padding:0;margin:0 0 1.5rem;border:0;list-style:none;display:grid;gap:.5rem;
}
.woocommerce-checkout #payment ul.payment_methods>li{
  padding:0;margin:0;list-style:none;background:none;
  border:1px solid var(--line);border-radius:var(--r-ctl);
  transition:border-color .16s var(--ease);
}
.woocommerce-checkout #payment ul.payment_methods>li>label{
  display:flex;align-items:center;gap:.6rem;cursor:pointer;margin:0;
  padding:.85rem 1rem;font-size:.9375rem;font-weight:500;
  letter-spacing:0;text-transform:none;color:var(--ink);
}
.woocommerce-checkout #payment ul.payment_methods>li>input[type=radio]{
  margin:0 0 0 1rem;accent-color:var(--accent);
}
.woocommerce-checkout #payment div.payment_box{
  background:none;border:0;border-top:1px solid var(--line);border-radius:0;
  margin:0;padding:1rem;font-size:.875rem;color:var(--ink-3);
}
.woocommerce-checkout #payment div.payment_box::before{display:none}

/* ---------- Conditions et bouton ---- */
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper{margin:0 0 1.25rem}
.woocommerce-checkout .woocommerce-terms-and-conditions{
  max-height:130px;border:1px solid var(--line);border-radius:var(--r-ctl);
  padding:.9rem 1rem;background:var(--surface);
}
.woocommerce-checkout #place_order{
  width:100%;height:56px;border-radius:var(--r-ctl);
  font-size:1rem;font-weight:600;letter-spacing:.01em;
  background:var(--accent);color:var(--paper);border:0;cursor:pointer;
}

/* ---------- Fin de page ----------
   La transition vers le pied de page etait abrupte : le bouton finissait, le
   pied de page commencait. Une respiration et un filet separent desormais les
   deux, sans creer un vide. */
.woocommerce-checkout .site-main,
.woocommerce-checkout main{padding-bottom:clamp(3.5rem,7vw,6rem)}
.woocommerce-checkout form.checkout{padding-bottom:2rem;border-bottom:1px solid var(--line)}

/* ==========================================================================
   MOBILE
   ==========================================================================
   Une colonne. `display:contents` est retire pour que le resume redevienne un
   bloc simple dans le flux : contact, resume, garanties, paiement, bouton.
   ------------------------------------------------------------------------- */
@media (max-width:1023px){
  .woocommerce-checkout form.checkout{display:block}
  .woocommerce-checkout #order_review{display:block;margin-top:2.25rem}
  .woocommerce-checkout .woocommerce-checkout-review-order-table{position:static}
  .woocommerce-checkout form.checkout #order_review_heading{margin-top:2.25rem}
  .dgs-checkout-trust{margin-top:1.75rem}
}

@media (max-width:640px){
  .woocommerce-checkout-review-order-table .cart_item{
    grid-template-columns:56px minmax(0,1fr) auto;column-gap:.85rem;padding:1rem 0;
  }
  .woocommerce-checkout-review-order-table .checkout-line__thumb{width:56px;height:56px}
  .woocommerce-checkout-review-order-table .order-total td{font-size:1.5rem}
  /* Une seule colonne de garanties : a 375 px, deux colonnes coupent
     « Instant digital delivery » en trois lignes. */
  .dgs-checkout-trust{grid-template-columns:1fr;gap:.7rem}
  .woocommerce-checkout #place_order{height:54px}
}

/* `grid-row:2/-1` NE MARCHE PAS ICI, et le rendu le prouve : le tableau se
   retrouvait a la meme ordonnee que son titre (y=504 pour les deux), donc
   par-dessus.

   Pourquoi : `-1` designe la derniere ligne de la grille EXPLICITE. Cette
   grille n'a pas de `grid-template-rows` — toutes ses lignes sont implicites —
   donc la grille explicite ne compte qu'une seule ligne, `-1` vaut 1, et
   `2 / -1` se normalise en `1 / 2`. Le tableau retombait en rangee 1.

   `span 5` couvre les rangees 2 a 6, c'est-a-dire jusqu'au bloc de paiement.
   Le tableau dispose ainsi d'une zone haute ou son `position:sticky` a de
   quoi glisser — sans zone plus haute que lui, un element colle ne colle a
   rien. */
@media (min-width:1024px){
  .woocommerce-checkout .woocommerce-checkout-review-order-table{grid-row:2/span 5}
}

/* UN SEUL TON SOURD, ACCESSIBLE DANS LES DEUX THEMES.

   `--ink-3` mesure **4,48:1** sur le fond de page en theme clair — deux
   centiemes sous AA, et il portait quatre elements du paiement : la quantite,
   l'intitule du total, le titre du recapitulatif et le corps des garanties.
   Aucun n'est du texte large au sens WCAG (11 a 13 px), donc aucun n'echappe
   au seuil de 4,5.

   Plutot que de corriger quatre selecteurs avec quatre valeurs, un jeton
   local : `--ink-3` legerement ramene vers l'encre. Le melange va vers
   `--ink`, donc il fonce en theme clair et s'eclaircit en theme sombre — les
   deux dans le bon sens, sans ecrire une seule couleur.

   La hierarchie ne repose plus sur la paleur mais sur la taille, la graisse
   et les capitales : c'est ce que le brief demande — « typography rather than
   containers ». */
.woocommerce-checkout{--muted:color-mix(in srgb,var(--ink-3) 84%,var(--ink))}

.woocommerce-checkout .product-quantity,
.woocommerce-checkout .woocommerce-checkout-review-order-table tfoot th,
.woocommerce-checkout .woocommerce-checkout-review-order-table .order-total th,
.woocommerce-checkout form.checkout #order_review_heading,
.woocommerce-checkout .dgs-checkout-trust li{color:var(--muted)}

/* ==========================================================================
   CORRECTIFS TROUVES EN REGARDANT LA PAGE — 2026-08-31, 3e passe
   ==========================================================================
   Les trois defauts ci-dessous ne se voyaient dans AUCUNE des mesures
   precedentes. Il a fallu une capture d'ecran. C'est la lecon de cette passe :
   la geometrie dit ou sont les boites, elle ne dit pas a quoi la page
   ressemble.
   ------------------------------------------------------------------------- */

/* --- 1. « Global » passait a la ligne, sous le point median ---------------

   Mesure : le `dd` « Global » fait 38 px de large — la largeur de son TEXTE
   SEUL. Son separateur `::before` (« · ») n'est pas compte dans le
   dimensionnement de l'element flex, donc il deborde, et le texte se replie
   sous lui. A l'ecran : « Windows / macOS / Web · » puis « Global » seul a la
   ligne, decale. Le DOM, lui, annoncait les deux `dd` sur la meme ligne — ils
   le sont : c'est l'INTERIEUR du second qui se coupait.

   Un separateur ne doit pas etre un `::before` sur un element flex. Le texte
   redevient donc du texte : conteneur en bloc, `dd` en ligne. Le point median
   se comporte alors comme un mot ordinaire, et l'ensemble se replie comme une
   phrase quand la colonne est etroite — ce qui est le comportement voulu. */
.woocommerce-checkout-review-order-table .variation{
  display:block;margin:.15rem 0 0;
  font-size:.8125rem;line-height:1.45;color:var(--ink-4);
}
.woocommerce-checkout-review-order-table .variation dd{
  display:inline;margin:0;padding:0;
}
.woocommerce-checkout-review-order-table .variation dd:not(:first-of-type)::before{
  content:" · ";margin:0;color:var(--ink-4);
}

/* --- 2. DEUX cartes autour du formulaire ---------------------------------

   `#contact_details.woocommerce-billing-fields` et
   `.woocommerce-billing-fields` portaient chacune un fond `--surface`, un
   filet et 12 px de rayon. Deux panneaux empiles au-dessus de champs qui ont
   deja leur propre cadre : exactement le « card + card + card » que le brief
   refuse. Et la premiere n'enveloppait que 108 px de haut, ce qui donnait un
   demi-panneau qui s'arretait au milieu du formulaire.

   Ce qui separe les sections desormais : le titre souligne et le blanc. */
.woocommerce-checkout .woocommerce-billing-fields,
.woocommerce-checkout #contact_details{
  background:none;border:0;border-radius:0;padding:0;box-shadow:none;
}
.woocommerce-checkout #contact_details{margin-bottom:2.25rem}

/* --- 3. Le cadre de navigateur autour du formulaire Stripe ---------------

   `fieldset#wc-stripe-upe-form` affichait 1,6 px de bordure : c'est le style
   PAR DEFAUT du navigateur pour `<fieldset>`, pas une decision de Stripe. Il
   ajoutait une quatrieme boite autour des champs de carte, deja encadres.

   On neutralise le defaut du navigateur SUR LE FIELDSET UNIQUEMENT. Aucun
   composant Stripe, aucun iframe, aucune classe `.wc-stripe-*` interne n'est
   touche — la consigne est respectee a la lettre. */
.woocommerce-checkout .wc-payment-form,
.woocommerce-checkout fieldset#wc-stripe-upe-form{
  border:0;margin:0;padding:0;min-inline-size:0;
}

/* Le vrai coupable du retour a la ligne : WooCommerce enveloppe chaque valeur
   dans un `<p>`.

   `<dd><p>Global</p></dd>` — le `dd` a beau etre passe en `inline`, le `<p>`
   qu'il contient reste un bloc, et un bloc force un retour a la ligne. D'ou
   les trois lignes mesurees (57 px de haut) : « Windows / macOS / Web », puis
   le point median seul, puis « Global ». Le separateur se retrouvait orphelin
   entre deux blocs.

   Passer ce `<p>` en `inline` rend la sequence entiere a un flux de texte
   normal. C'est la troisieme tentative sur ce detail, et la difference est
   qu'ici la cause est identifiee au lieu d'etre contournee : les deux
   precedentes traitaient le conteneur, alors que la coupure venait de son
   contenu. */
.woocommerce-checkout-review-order-table .variation dd p{display:inline;margin:0}

/* ==========================================================================
   DEUX REGRESSIONS VUES A L'ECRAN, PAS DANS LES MESURES — 4e passe
   ==========================================================================

   1. `display:flex` SUR UNE ETIQUETTE QUI CONTIENT UNE PHRASE.

   C'est ma regression, introduite pour aligner la case a cocher avec son
   texte. Un conteneur flex transforme CHACUN de ses enfants en element flex —
   y compris les noeuds de texte anonymes et les `<a>`. La phrase des
   conditions generales, qui contient deux liens, s'est donc brisee en
   morceaux places cote a cote : a l'ecran, « refund » et « policy » se
   retrouvaient seuls, alignes a droite, au milieu de la phrase.

   Une phrase doit rester du texte en ligne. La case a cocher est donc sortie
   du flux et le texte recoit un retrait a gauche : l'alignement voulu, sans
   toucher au flux des mots.

   2. LE BOUTON RADIO ETAIT AU-DESSUS DE SON LIBELLE.

   `<li>` est `display:list-item`, l'`<input type=radio>` est en ligne, et le
   `<label>` que j'avais passe en `flex` devenait un bloc — donc une ligne a
   lui seul. « Payment options » s'affichait sous son propre bouton radio, et
   « PayPal » aussi. La grille remet les deux sur une rangee et laisse le
   panneau de paiement occuper toute la largeur en dessous.
   ------------------------------------------------------------------------- */

/* --- 1. Les etiquettes a case a cocher --- */
.woocommerce-checkout label.woocommerce-form__label-for-checkbox,
.woocommerce-checkout .form-row label.checkbox,
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper label{
  display:block;position:relative;padding-left:1.75rem;margin:0;
  font-size:.8125rem;letter-spacing:0;text-transform:none;
  color:var(--ink-2);font-weight:400;line-height:1.5;cursor:pointer;
}
.woocommerce-checkout label.woocommerce-form__label-for-checkbox input[type=checkbox],
.woocommerce-checkout .form-row label.checkbox input[type=checkbox],
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper input[type=checkbox]{
  position:absolute;left:0;top:.22em;
  width:16px;height:16px;margin:0;accent-color:var(--accent);
}
/* Les liens de la phrase redeviennent des liens dans une phrase. */
.woocommerce-checkout .woocommerce-terms-and-conditions-wrapper label a{
  color:var(--accent);text-decoration:underline;text-underline-offset:2px;
}

/* --- 2. Radio et libelle sur la meme rangee --- */
.woocommerce-checkout #payment ul.payment_methods>li{
  display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;
}
.woocommerce-checkout #payment ul.payment_methods>li>input[type=radio]{
  grid-column:1;grid-row:1;justify-self:center;
  width:15px;height:15px;margin:0 0 0 1rem;accent-color:var(--accent);
}
.woocommerce-checkout #payment ul.payment_methods>li>label{
  grid-column:2;grid-row:1;display:block;
  padding:.9rem 1rem;margin:0;
  font-size:.9375rem;font-weight:500;letter-spacing:0;text-transform:none;color:var(--ink);
}
/* Le panneau de paiement passe sous les deux, sur toute la largeur. */
.woocommerce-checkout #payment ul.payment_methods>li>.payment_box{
  grid-column:1/-1;grid-row:2;
}

/* ==========================================================================
   PANIER — MEME LANGAGE QUE LE PAIEMENT, 2026-08-31 (5e passe)
   ==========================================================================

   Le panier n'avait jamais ete repris : il servait encore le tableau brut de
   WooCommerce. Releve a l'ecran et a la mesure :

   - vignette de 96 x 120 px — DEFORMEE, l'image source est carree — posee
     dans une colonne de 200 px de large ;
   - bouton « supprimer » de 19 px colle a l'extreme GAUCHE, avant meme
     l'image, ou personne ne le cherche et ou tout le monde peut le cliquer
     par accident ;
   - plateforme et region empilees sur QUATRE lignes avec leurs libelles
     (« Platform: » / « Windows / macOS / Web » / « Region: » / « Global »),
     parce que le correctif de la 3e passe ne visait que le tableau du
     paiement ;
   - « Proceed to checkout » en clair sur fond sombre, alors que le bouton de
     paiement est en accent : deux boutons primaires de deux couleurs
     differentes dans un meme parcours ;
   - totaux dans une carte de 1175 px de large, soit toute la page, pour
     quatre lignes de chiffres.

   L'ordre des colonnes est corrige par `order` plutot qu'en touchant au
   gabarit : le DOM de WooCommerce reste intact, seule la position a l'ecran
   change. L'en-tete recoit EXACTEMENT le meme ordre, sans quoi les intitules
   ne tomberaient plus au-dessus de leurs colonnes.
   ------------------------------------------------------------------------- */

@media (min-width:768px){
  .woocommerce-cart .woocommerce-cart-form__contents{
    display:block;width:100%;border:0;border-collapse:collapse;
  }
  .woocommerce-cart .woocommerce-cart-form__contents thead,
  .woocommerce-cart .woocommerce-cart-form__contents tbody{display:block}

  .woocommerce-cart .woocommerce-cart-form__contents thead tr,
  .woocommerce-cart .woocommerce-cart-form__cart-item{
    display:grid;
    grid-template-columns:64px minmax(0,1fr) 96px 116px 96px 36px;
    column-gap:1rem;align-items:center;
  }

  /* L'ordre voulu : vignette, produit, prix, quantite, sous-total, supprimer. */
  .woocommerce-cart .product-thumbnail{order:1}
  .woocommerce-cart .product-name{order:2}
  .woocommerce-cart .product-price{order:3}
  .woocommerce-cart .product-quantity{order:4}
  .woocommerce-cart .product-subtotal{order:5}
  .woocommerce-cart .product-remove{order:6}

  .woocommerce-cart .woocommerce-cart-form__contents thead tr{
    padding-bottom:.85rem;border-bottom:1px solid var(--line-strong);
  }
  .woocommerce-cart .woocommerce-cart-form__contents thead th{
    padding:0;border:0;text-align:left;background:none;
    font-size:.6875rem;letter-spacing:.14em;text-transform:uppercase;
    font-weight:600;color:var(--ink-4);
  }
  /* Deux intitules ne servent qu'aux lecteurs d'ecran ; les afficher
     mettrait « Thumbnail image » au-dessus d'une image. */
  .woocommerce-cart .woocommerce-cart-form__contents thead th.product-thumbnail,
  .woocommerce-cart .woocommerce-cart-form__contents thead th.product-remove{
    font-size:0;
  }
  .woocommerce-cart .woocommerce-cart-form__contents thead th.product-price,
  .woocommerce-cart .woocommerce-cart-form__contents thead th.product-subtotal{text-align:right}
  .woocommerce-cart .woocommerce-cart-form__contents thead th.product-quantity{text-align:center}

  .woocommerce-cart .woocommerce-cart-form__cart-item{
    padding:1.15rem 0;border-bottom:1px solid var(--line);
  }
  .woocommerce-cart .woocommerce-cart-form__cart-item td{padding:0;border:0}
  .woocommerce-cart .product-price,
  .woocommerce-cart .product-subtotal{text-align:right;font-variant-numeric:tabular-nums}
  .woocommerce-cart .product-quantity{justify-self:center}
}

/* --- La vignette : carree, et de la taille d'une vignette --- */
.woocommerce-cart .product-thumbnail img{
  width:64px;height:64px;aspect-ratio:1;object-fit:cover;
  border-radius:10px;border:1px solid var(--line);background:var(--shade);
  display:block;
}
.woocommerce-cart .product-thumbnail a{display:block;width:64px}

/* --- Nom et metadonnees, comme au paiement --- */
.woocommerce-cart .product-name>a{
  font-size:.9375rem;font-weight:500;color:var(--ink);text-decoration:none;line-height:1.35;
}
.woocommerce-cart .product-name>a:hover{color:var(--accent)}
.woocommerce-cart .product-name .variation{
  display:block;margin:.2rem 0 0;
  font-size:.8125rem;line-height:1.45;color:var(--ink-4);
}
.woocommerce-cart .product-name .variation dt{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.woocommerce-cart .product-name .variation dd{display:inline;margin:0;padding:0}
.woocommerce-cart .product-name .variation dd p{display:inline;margin:0}
.woocommerce-cart .product-name .variation dd:not(:first-of-type)::before{
  content:" · ";color:var(--ink-4);
}

/* --- Supprimer : a droite, et assez grand pour etre vise --- */
.woocommerce-cart .product-remove a.remove{
  display:grid;place-items:center;width:32px;height:32px;
  border-radius:8px;font-size:1.15rem;line-height:1;
  color:var(--ink-4);background:none;text-decoration:none;
  transition:color .16s var(--ease),background-color .16s var(--ease);
}
.woocommerce-cart .product-remove a.remove:hover{color:var(--error);background:var(--hover)}
.woocommerce-cart .product-remove a.remove:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* --- Quantite --- */
.woocommerce-cart .quantity input.qty{
  width:72px;height:40px;text-align:center;border-radius:var(--r-ctl);
  background:var(--field);border:1px solid var(--line-strong);color:var(--ink);
  font-variant-numeric:tabular-nums;
}

/* --- Coupon et mise a jour : une rangee, alignee ---
   Le champ faisait 1175 px de large — toute la page pour un code de huit
   caracteres — et « Update cart » tombait dessous, decale. */
.woocommerce-cart .actions{
  display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;
  padding:1.35rem 0 0;border:0;
}
.woocommerce-cart .actions .coupon{
  display:flex;gap:.6rem;align-items:center;flex:0 1 auto;margin:0;padding:0;border:0;
}
.woocommerce-cart .actions .coupon input#coupon_code{
  width:190px;height:44px;border-radius:var(--r-ctl);
  background:var(--field);border:1px solid var(--line-strong);color:var(--ink);
  padding:0 .9rem;font-size:.9rem;
}
.woocommerce-cart .actions .coupon button,
.woocommerce-cart .actions button[name=update_cart]{
  height:44px;padding:0 1.1rem;border-radius:var(--r-ctl);
  background:none;border:1px solid var(--line-strong);color:var(--ink-2);
  font-size:.8125rem;letter-spacing:.06em;text-transform:uppercase;font-weight:600;cursor:pointer;
  transition:border-color .16s var(--ease),color .16s var(--ease);
}
.woocommerce-cart .actions .coupon button:hover,
.woocommerce-cart .actions button[name=update_cart]:not(:disabled):hover{
  border-color:var(--accent);color:var(--accent);
}
.woocommerce-cart .actions button[name=update_cart]{margin-left:auto}
.woocommerce-cart .actions button[name=update_cart]:disabled{opacity:.45;cursor:default}

/* --- Totaux : un bloc a droite, pas une banderole ---
   452 px de haut sur 1175 de large pour quatre lignes. Il devient une colonne
   de 380 px alignee a droite, comme le recapitulatif du paiement. */
.woocommerce-cart .cart-collaterals{display:flex;justify-content:flex-end;margin-top:2.5rem}
.woocommerce-cart .cart_totals{
  width:min(380px,100%);background:none;border:0;border-top:1px solid var(--line-strong);
  border-radius:0;padding:1.35rem 0 0;
}
.woocommerce-cart .cart_totals h2{
  font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;
  font-weight:600;color:var(--ink-4);margin:0 0 1rem;
}
.woocommerce-cart .cart_totals table{width:100%;border-collapse:collapse}
.woocommerce-cart .cart_totals th,
.woocommerce-cart .cart_totals td{
  padding:.4rem 0;border:0;font-size:.875rem;background:none;
}
.woocommerce-cart .cart_totals th{text-align:left;color:var(--ink-3);font-weight:400}
.woocommerce-cart .cart_totals td{text-align:right;color:var(--ink-2);font-variant-numeric:tabular-nums}
.woocommerce-cart .cart_totals .order-total th{
  font-size:.6875rem;letter-spacing:.16em;text-transform:uppercase;font-weight:600;color:var(--ink-3);
}
.woocommerce-cart .cart_totals .order-total th,
.woocommerce-cart .cart_totals .order-total td{
  border-top:1px solid var(--line);padding-top:.95rem;
}
.woocommerce-cart .cart_totals .order-total td{
  font-size:1.5rem;font-weight:600;color:var(--ink);letter-spacing:-.02em;
}

/* --- Le bouton principal : le MEME que « Place order » ---
   Il etait clair sur fond sombre, donc different du bouton de paiement.
   Deux boutons primaires de deux couleurs dans un meme parcours obligent le
   client a redecouvrir a chaque etape ou se trouve l'action. */
.woocommerce-cart .wc-proceed-to-checkout{padding:1.25rem 0 0;margin:0}
.woocommerce-cart .wc-proceed-to-checkout a.checkout-button{
  display:grid;place-items:center;width:100%;height:54px;margin:0;
  border-radius:var(--r-ctl);border:0;
  background:var(--accent);color:var(--paper);
  font-size:1rem;font-weight:600;letter-spacing:.01em;text-transform:none;text-decoration:none;
  transition:filter .16s var(--ease);
}
.woocommerce-cart .wc-proceed-to-checkout a.checkout-button:hover{filter:brightness(1.08)}
.woocommerce-cart .wc-proceed-to-checkout a.checkout-button:focus-visible{
  outline:2px solid var(--accent);outline-offset:3px;
}

/* ==========================================================================
   PANIER — MOBILE
   ==========================================================================
   Le tableau devient une liste. Chaque article tient sur trois lignes, et le
   bouton supprimer se range en haut a droite de sa propre carte-ligne.
   ------------------------------------------------------------------------- */
@media (max-width:767px){
  .woocommerce-cart .woocommerce-cart-form__contents thead{display:none}
  .woocommerce-cart .woocommerce-cart-form__cart-item{
    display:grid;grid-template-columns:56px minmax(0,1fr) auto;
    column-gap:.85rem;row-gap:.3rem;align-items:start;
    padding:1.1rem 0;border-bottom:1px solid var(--line);
  }
  .woocommerce-cart .woocommerce-cart-form__cart-item td{padding:0;border:0;display:block}
  .woocommerce-cart .product-thumbnail{grid-column:1;grid-row:1/span 3}
  .woocommerce-cart .product-thumbnail img,
  .woocommerce-cart .product-thumbnail a{width:56px}
  .woocommerce-cart .product-thumbnail img{height:56px}
  .woocommerce-cart .product-name{grid-column:2;grid-row:1}
  .woocommerce-cart .product-remove{grid-column:3;grid-row:1;justify-self:end}
  .woocommerce-cart .product-quantity{grid-column:2;grid-row:2;justify-self:start}
  .woocommerce-cart .product-subtotal{grid-column:3;grid-row:2;justify-self:end;
    font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
  /* Le prix unitaire disparait sur mobile : avec le sous-total et la
     quantite affiches, il est deductible, et trois chiffres sur une ligne de
     375 px se marchent dessus. */
  .woocommerce-cart .product-price{display:none}

  .woocommerce-cart .actions{flex-direction:column;align-items:stretch}
  .woocommerce-cart .actions .coupon{width:100%}
  .woocommerce-cart .actions .coupon input#coupon_code{flex:1;width:auto}
  .woocommerce-cart .actions button[name=update_cart]{margin-left:0;width:100%}
  .woocommerce-cart .cart-collaterals{margin-top:1.75rem}
  .woocommerce-cart .cart_totals{width:100%}
}

/* ==========================================================================
   `.cart-trust` — LE BLOC QUI N'AVAIT JAMAIS EU DE MISE EN PAGE
   ==========================================================================

   LE DEFAUT LE PLUS VISIBLE DE TOUTE CETTE SERIE, et le seul qu'aucune mesure
   n'aurait signale parce que la page « fonctionnait ».

   `storefront.php` emet trois `<span>` contenant chacun un `<svg
   viewBox="0 0 24 24">` sans attribut `width` ni `height`. La feuille de
   style ne contenait pour ce bloc que DEUX lignes, et toutes deux des
   couleurs (`background`, `border-color`) — aucune dimension, aucun trace.

   Deux consequences se cumulaient :

   1. UN SVG SANS DIMENSION PREND 100 % DE SON CONTENEUR. Mesure : 1175 x
      1175 px chacun, soit l'icone agrandie 49 fois, et un bloc de 3607 px de
      haut pour trois mots.

   2. UN `<path>` SANS `fill:none` EST REMPLI EN NOIR. Le trace du crochet
      (`M4 12.5l5 5L20 6.5`) n'est pas une coche mais un triangle une fois
      rempli. D'ou les grandes formes noires sous le panier, visibles sur les
      captures du client.

   La lecon a retenir : dans ce theme, TOUT `<svg>` en ligne doit recevoir sa
   taille ET `fill:none; stroke:currentColor`. L'oubli ne casse pas la page —
   il la remplit.
   ------------------------------------------------------------------------- */
.cart-trust{
  display:flex;flex-wrap:wrap;gap:.75rem 2rem;
  margin:1.75rem 0 0;padding:1.15rem 0 0;
  background:none;border:0;border-top:1px solid var(--line);border-radius:0;
}
.cart-trust span{
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:.8125rem;line-height:1.4;color:var(--ink-3);
}
.cart-trust svg{
  /* Les deux declarations qui manquaient. */
  width:15px;height:15px;flex:none;
  fill:none;stroke:var(--success);stroke-width:2.6;
  stroke-linecap:round;stroke-linejoin:round;
}

/* Meme garde-fou pour tout SVG en ligne du theme qui aurait ete oublie :
   sans taille, il ne pourra plus depasser une ligne de texte. C'est une
   ceinture en plus de la bretelle ci-dessus, et elle coute une regle. */
.woocommerce svg:not([width]):not([class]){max-width:1.5em;max-height:1.5em}

/* Le prix unitaire restait visible sur mobile : une erreur de SPECIFICITE de
   ma part, pas d'intention.

   `.woocommerce-cart .woocommerce-cart-form__cart-item td` vaut (0,2,1) parce
   qu'il finit par un selecteur d'element, et il posait `display:block`. Ma
   regle `.woocommerce-cart .product-price` ne vaut que (0,2,0) : elle perdait,
   quelle que soit sa position dans le fichier. Resultat a l'ecran : « $1.00 »
   sous la quantite ET « $1.00 » a droite en sous-total — deux fois le meme
   chiffre pour un article de quantite 1.

   En qualifiant l'element (`td.product-price`), on passe a (0,3,1). */
@media (max-width:767px){
  .woocommerce-cart .woocommerce-cart-form__cart-item td.product-price{display:none}
}

/* Le panier n'heritait pas du ton sourd accessible : le jeton `--muted` etait
   declare sur `.woocommerce-checkout` uniquement. Mesure en theme clair :
   metadonnees produit et ligne de garanties a **4,48:1**, soit le meme
   echec marginal que le paiement avant correction.

   Meme remede, meme raison : `--ink-3` ramene vers l'encre, donc plus fonce
   en clair et plus clair en sombre. */
.woocommerce-cart{--muted:color-mix(in srgb,var(--ink-3) 84%,var(--ink))}
.woocommerce-cart .product-name .variation,
.woocommerce-cart .cart-trust span,
.woocommerce-cart .cart_totals th,
.woocommerce-cart .cart_totals h2,
.woocommerce-cart .woocommerce-cart-form__contents thead th{color:var(--muted)}

/* ==========================================================================
   PIED DE PAGE — VARIABLES DE THEME, 2026-09-01
   ==========================================================================

   LE DEFAUT, MESURE AVANT CORRECTION, PAS DEDUIT.

   Le pied de page portait DEUX couches concurrentes. La couche editoriale
   d'origine peignait sur un fond sombre et ecrivait ses couleurs EN DUR :

     .footer__brand p { color: rgba(255,255,255,.55) }   (specificite 0,1,1)
     .footer__bottom  { color: rgba(255,255,255,.45) }   (specificite 0,1,0)

   La couche commerce ajoutee plus tard a bascule le FOND sur `--shade`, qui
   suit la rampe — #121722 en sombre, #F7F8FC en clair — mais elle n'a
   redefini que `.footer`, `.footer a`, `.footer h4`. Les deux regles
   ci-dessus survivent : `.footer__brand p` par une specificite superieure,
   `.footer__bottom` parce qu'une couleur posee sur l'enfant bat la couleur
   heritee du parent.

   MESURE AU NAVIGATEUR SUR LA PRODUCTION, EN THEME CLAIR (2026-09-01),
   contraste calcule apres composition de l'alpha sur #F7F8FC :

     .footer__brand p   rgba(255,255,255,.55) sur #F7F8FC  ->  1,03:1
     .footer__bottom    rgba(255,255,255,.45) sur #F7F8FC  ->  1,03:1

   1,03:1 n'est pas « peu lisible » : c'est du blanc sur du blanc. La ligne
   de copyright, les liens legaux et la description de la marque etaient
   absents de l'ecran. En theme sombre les memes regles donnent un resultat
   correct, ce qui explique que le defaut ait pu vivre : il ne se voit que
   dans une rampe sur deux.

   LA CORRECTION EST AU NIVEAU DU SYSTEME, PAS DU SYMPTOME. Cinq variables
   nommees par role portent desormais toutes les couleurs du pied de page.
   Repeindre une valeur en dur redevient impossible sans passer par elles, et
   la prochaine bascule de rampe les emmene automatiquement.

   POURQUOI DES VALEURS PLEINES ET NON DES ALPHA. Un alpha se compose avec le
   fond : la meme declaration donne deux contrastes selon la surface, et c'est
   exactement le piege qui a produit ce defaut. Les valeurs ci-dessous sont
   opaques et mesurees contre `--shade` de leur propre rampe.

   Contrastes obtenus, calcules contre --shade (sombre #121722, clair #F7F8FC) :

                        | sombre   | clair
     --footer-heading   | 15,82:1  | 16,72:1
     --footer-text      | 10,87:1  |  9,71:1
     --footer-muted     |  7,10:1  |  5,49:1
     --footer-link-hover|  8,43:1  |  7,45:1

   Tous au-dessus de 4,5:1, y compris `--footer-muted` qui porte du texte de
   11 px en capitales — c'est la que l'ancien `--ink-3` (4,48:1) echouait
   deja, et la raison pour laquelle il n'est pas reutilise tel quel ici.
   ========================================================================== */

:root{
  --footer-heading:#EDF1F7;
  --footer-text:#C2CAD8;
  --footer-muted:#98A4B6;
  --footer-link-hover:#A5ABFF;
  --footer-border:rgba(255,255,255,.09);
}

:root[data-theme="light"]{
  --footer-heading:#111827;
  --footer-text:#374151;
  --footer-muted:#5B6675;
  --footer-link-hover:#4338CA;
  --footer-border:#E5E7EB;
}

/* Le fond et l'encre par defaut. `--shade` bascule deja ; ce qui manquait
   etait que TOUT le contenu suive. */
.footer{background:var(--shade);color:var(--footer-text);border-top:1px solid var(--footer-border)}

.footer h4,
.footer .footer__col h4{color:var(--footer-heading)}
.footer .logo{color:var(--footer-heading)}

.footer a{color:var(--footer-text);transition:color .35s}
.footer a:hover,
.footer a:focus-visible{color:var(--footer-link-hover)}

/* LES DEUX REGLES QUI PORTAIENT LE DEFAUT.
   La specificite est alignee sur celle de la regle d'origine — sans quoi
   `.footer__brand p` (0,1,1) continuerait de gagner contre `.footer` (0,1,0)
   et le blanc en dur resterait. */
.footer .footer__brand p{color:var(--footer-muted)}
.footer .footer__bottom{color:var(--footer-muted)}

/* Le reste du pied : memes roles, meme rampe. */
.footer .small,
.footer__entity,
.footer__legal{color:var(--footer-muted)}
.footer__bottom a,
.footer__legal a,
.footer__social a{color:var(--footer-text)}
.footer__bottom a:hover,
.footer__legal a:hover,
.footer__social a:hover{color:var(--footer-link-hover)}

.footer__bottom,
.footer__top{border-color:var(--footer-border)}

/* Bandeau des moyens de paiement. Les plaques des marques restent blanches :
   c'est le fond de la carte bancaire, pas une surface de page. */
.footer__pay{border-color:var(--footer-border)}
.footer__pay-label{color:var(--footer-text)}
.footer__pay-note{color:var(--footer-text)}

/* L'accroche du pied suivait `--mark-glow`, une couleur pensee pour le fond
   le plus sombre du site. Sur le pied clair elle tombait a 1,9:1. */
.footer .eyebrow{color:var(--accent)}

/* Les icones sociales sont des traces, pas du texte : elles heritent de
   `currentColor` et suivent donc les memes variables. Sans `stroke`, un SVG
   sans remplissage reste invisible quelle que soit la couleur du texte. */
.footer__social svg{fill:none;stroke:currentColor}


/* ==========================================================================
   RECHERCHE DANS L'EN-TETE — CHAMP VISIBLE, 2026-09-01
   ==========================================================================

   Le declencheur etait une loupe de 40 px, quatrieme icone d'une rangee de
   quatre. Il devient un champ : meme panneau, meme script, mais une cible
   qui se lit et qui s'atteint.

   POURQUOI PAS PLUS LARGE. Le champ est plafonne a 260 px et ne pousse pas
   le menu : `flex:0 1 auto` avec `min-width:0` le laisse retrecir avant que
   quoi que ce soit ne deborde. Un champ elastique aurait chasse « Support »
   de la barre entre 1024 et 1180 px — c'est la premiere chose qu'on casse en
   ajoutant un element a une barre deja pleine.

   LE FAUX PLACEHOLDER EST DU TEXTE, PAS UN ATTRIBUT. Il vit dans un <span>
   et prend une couleur mesuree, la ou un vrai `::placeholder` heriterait
   d'un gris systeme non contraste. Mesure contre `--surface` :
   #98A4B6 sur #151B26 = 6,84:1 en sombre, #5B6675 sur #FFFFFF = 5,83:1 en
   clair. Au-dessus de 4,5:1 dans les deux rampes.
   ========================================================================== */

.nav__search{
  display:none;                 /* la loupe tient le mobile ; voir plus bas */
  align-items:center;
  gap:.6rem;
  flex:0 1 auto;
  min-width:0;
  width:100%;
  max-width:260px;
  height:42px;
  padding:0 .9rem;
  border:1px solid var(--line-strong);
  border-radius:9px;
  background:var(--surface);
  color:var(--search-placeholder,#98A4B6);
  font-family:inherit;
  font-size:var(--fs-small);
  text-align:left;
  cursor:text;                  /* il se comporte comme un champ, il le dit */
  transition:border-color .25s, background .25s, box-shadow .25s;
}

.nav__search:hover{border-color:var(--accent-line);background:var(--surface-2)}

/* L'anneau de focus est celui d'un champ, pas d'un bouton : c'est l'etat que
   le visiteur verra apres un Tab, et il doit ressembler a ce qui va s'ouvrir. */
.nav__search:focus-visible{
  outline:none;
  border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-wash);
}

.nav__search-icon{
  width:17px;height:17px;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;
}

.nav__search-text{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

:root{--search-placeholder:#98A4B6}
:root[data-theme="light"]{--search-placeholder:#5B6675}

/* Le champ apparait quand la barre a la place de le porter, et la loupe
   disparait au meme instant : jamais les deux, jamais aucun. */
@media (min-width:1024px){
  .nav__search{display:inline-flex}
  .nav__icon--search{display:none}
}


/* ==========================================================================
   PAIEMENT — REPERES DE PROGRESSION, MARQUES, ETAT D'ENVOI (2026-09-01)
   ==========================================================================

   Trois ajouts, aucune reprise de la mise en page a deux colonnes posee le
   2026-08-31 : elle mesure deja juste, et la refaire aurait ete du travail
   qui ne se voit pas.

   PAS DE VERRE, PAS D'OMBRE PORTEE, PAS DE DEGRADE. Les reperes se tiennent
   par un filet, un chiffre et une couleur d'accent. Sur un tunnel d'achat,
   tout ce qui brille au-dessus du formulaire deplace l'attention de ce que le
   visiteur doit lire.
   ========================================================================== */

.dgs-steps{margin:0 0 clamp(1.5rem,3vw,2.25rem)}

.dgs-steps__list{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:.5rem;
  margin:0;
  padding:0;
  list-style:none;
  counter-reset:none;
}

.dgs-steps__item{position:relative;min-width:0}

/* Le filet de progression. Il est SOUS l'etape, pas entre deux pastilles :
   une ligne qui relie des cercles se casse des que les libelles passent sur
   deux lignes, ce qui arrive a 768 px avec « Billing details ». */
.dgs-steps__item::after{
  content:'';
  position:absolute;
  left:0;right:0;bottom:0;
  height:2px;
  background:var(--line);
  transition:background .3s;
}
.dgs-steps__item.is-current::after{background:var(--accent)}
.dgs-steps__item.is-done::after{background:var(--success)}

.dgs-steps__link{
  display:flex;
  align-items:center;
  gap:.6rem;
  padding:.55rem .25rem .8rem;
  color:var(--ink-3);
  text-decoration:none;
  font-size:var(--fs-small);
  transition:color .3s;
  min-width:0;
}
.dgs-steps__link:hover{color:var(--ink-2)}
.dgs-steps__item.is-current .dgs-steps__link{color:var(--ink)}
.dgs-steps__item.is-done .dgs-steps__link{color:var(--ink-2)}

/* Le numero et la coche ont la MEME boite : l'un remplace l'autre quand
   l'etape se valide, et la ligne ne bouge pas d'un pixel. Ils ne coexistent
   jamais — inutile de les superposer, il suffit qu'ils mesurent pareil. */
.dgs-steps__n,
.dgs-steps__check{
  width:26px;height:26px;
  flex:none;
  display:grid;place-items:center;
  border-radius:50%;
  font-family:var(--font-mono);
  font-size:var(--fs-micro);
  font-weight:600;
  letter-spacing:.02em;
  transition:background .3s, color .3s, border-color .3s;
}

.dgs-steps__n{
  border:1px solid var(--line-strong);
  color:var(--ink-3);
  background:transparent;
}
.dgs-steps__item.is-current .dgs-steps__n{
  border-color:var(--accent);
  background:var(--accent);
  color:var(--white);
}

.dgs-steps__check{display:none;background:var(--success);color:var(--white)}
.dgs-steps__check svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round}

/* Une etape faite montre la coche A LA PLACE du chiffre. */
.dgs-steps__item.is-done .dgs-steps__n{display:none}
.dgs-steps__item.is-done .dgs-steps__check{display:grid}

.dgs-steps__label{
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
  font-weight:500;
}

/* Sous 560 px, le libelle de l'etape non courante disparait et laisse le
   chiffre : trois libelles complets sur 375 px se chevauchent. L'etape
   courante garde le sien — c'est la seule dont le nom compte. */
@media (max-width:560px){
  .dgs-steps__list{gap:.35rem}
  .dgs-steps__label{display:none}
  .dgs-steps__item.is-current .dgs-steps__label{display:block}
  .dgs-steps__link{justify-content:center;padding-inline:0}
  .dgs-steps__item.is-current .dgs-steps__link{justify-content:flex-start}
}

/* ---------- Les marques de paiement, sous le bouton ---------- */

.dgs-paymarks{
  display:flex;
  align-items:center;
  gap:.6rem .9rem;
  flex-wrap:wrap;
  margin-top:1.1rem;
  padding-top:1.1rem;
  border-top:1px solid var(--line);
}
.dgs-paymarks__label{
  font-size:var(--fs-micro);
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--ink-2);
}
.dgs-paymarks__list{display:flex;align-items:center;gap:.45rem;flex-wrap:wrap;
  margin:0;padding:0;list-style:none}
.dgs-paymarks__list li{display:flex}
/* Les plaques restent blanches dans les DEUX rampes : c'est le fond de la
   carte bancaire, impose par les chartes de Visa et Mastercard, pas une
   surface de page. Le filet les detache du fond sombre. */
.dgs-paymarks__list img{
  display:block;height:24px;width:auto;border-radius:3px;
  background:#FFFFFF;border:1px solid var(--line);
}

/* ---------- L'etat d'envoi du bouton ---------- */

/* Le bouton garde sa taille : remplacer son texte par « Processing… » ferait
   sauter la colonne au moment le plus sensible de la page. On ajoute un
   temoin, on ne retire rien. */
#place_order{position:relative;transition:opacity .25s}

.dgs-busy #place_order{
  opacity:.72;
  cursor:progress;
  /* `pointer-events` bloque le clic sans desactiver le bouton : un bouton
     `disabled` sort de la soumission et casserait le paiement. */
  pointer-events:none;
}

.dgs-busy #place_order::after{
  content:'';
  position:absolute;
  top:50%;right:1.1rem;
  width:16px;height:16px;
  margin-top:-8px;
  border:2px solid currentColor;
  border-right-color:transparent;
  border-radius:50%;
  animation:dgs-spin .7s linear infinite;
}

@keyframes dgs-spin{to{transform:rotate(360deg)}}

/* Le mouvement est un ornement : qui le refuse garde un temoin fixe, et le
   bouton reste manifestement occupe par son opacite et son curseur. */
@media (prefers-reduced-motion:reduce){
  .dgs-busy #place_order::after{animation:none}
}

/* ==========================================================================
   EN-TETE MOBILE — LE BOUTON DE MENU SORTAIT DE L'ECRAN (2026-09-01)
   ==========================================================================

   DEFAUT PREEXISTANT, TROUVE EN MESURANT LA BARRE APRES Y AVOIR TOUCHE.
   Il ne vient pas du champ de recherche ajoute ce jour-la : mesure faite en
   retirant ce champ du document, la largeur de defilement de `.nav__inner`
   ne bouge pas d'un pixel (411 px dans les deux cas).

   CE QUI A ETE MESURE, a 360 px de largeur utile (iframe a 375 px moins la
   barre de defilement) :

     .nav__inner  scrollWidth 411  /  clientWidth 360   -> 51 px de trop
     .nav__brand      166 px
     .nav__actions    208 px  (5 commandes de 38 px + interlignes)
     padding          20 + 20   gap 16

     166 + 208 + 56 = 430 pour 360 disponibles.

   CONSEQUENCE REELLE : `.nav__burger` se posait de 377 a 411 px, donc
   ENTIEREMENT HORS DE L'ECRAN, et l'icone du panier etait coupee. Comme
   `body` porte `overflow-x:hidden`, rien ne debordait visiblement et la page
   ne defilait pas horizontalement — le defaut ne se voyait pas, il se
   mesurait. Sur un telephone de 375 px sans barre de defilement, le bouton
   restait a une vingtaine de pixels dehors.

   Autrement dit : le menu mobile n'etait pas atteignable sur les petits
   telephones, et c'est la seule facon d'ouvrir la navigation a cette taille.

   POURQUOI ON NE MASQUE AUCUNE COMMANDE. La solution habituelle — pousser le
   compte, le theme et la recherche dans le menu — supposerait qu'ils s'y
   trouvent. Releve du contenu de `#site-menu` : il ne contient ni compte, ni
   recherche, ni bascule de theme. Les masquer les SUPPRIMERAIT, ce que le
   brief interdit explicitement.

   On reduit donc les dimensions, sans rien retirer. Resultat vise a 360 px
   utiles : 134 + 186 + 38 = 358, soit deux pixels de marge.
   ========================================================================== */

@media (max-width:560px){

  /* 14 px de marge laterale au lieu de 20, et un interligne de 10 au lieu de
     16 : 18 px recuperes sans que rien ne se touche. */
  .nav__inner{
    padding-inline:14px;
    gap:10px;
    min-width:0;
  }

  /* La marque peut retrecir. Sans `min-width:0`, un element de grille ou de
     flexbox refuse de passer sous la largeur de son contenu — c'est la raison
     pour laquelle elle poussait les icones dehors au lieu de ceder. */
  .nav__brand{min-width:0;flex:0 1 auto;overflow:hidden}
  .nav__brand .logo{
    font-size:1rem;
    letter-spacing:.03em;
    gap:.45rem;
    min-width:0;
    white-space:nowrap;
  }

  /* Les commandes gardent leur nombre et leur ordre ; elles perdent 4 px
     chacune. 34 px reste au-dessus de la cible tactile confortable une fois
     compte l'espacement, et le burger conserve ses 34 px d'origine. */
  .nav__actions{flex:none;gap:.25rem}
  .nav__icon{width:34px;height:34px}
  .theme-toggle{width:34px;height:34px}
}


/* ==========================================================================
   PIED DE PAGE — LE BLOC INFOLETTRE, INVISIBLE DANS LES DEUX RAMPES
   2026-09-01, seconde passe
   ==========================================================================

   SIGNALE PAR LE CLIENT : « il reste pied de page invisible, le blanc sur
   blanc ou dans le sombre noir sur noir ». Les deux a la fois, et c'est la
   description exacte du defaut — pas une exageration.

   MESURE, en auditant CHAQUE element du pied porteur de texte, dans les deux
   themes demarres nativement (et non bascules apres coup) :

     .newsletter h3            « Get new arrivals... »   1,07:1 sombre / 1,06:1 clair
     .newsletter__form button  « Sign up »               1,07:1 sombre / 1,06:1 clair

   Ce sont les DEUX SEULS elements du pied encore sous 4,5:1 — la premiere
   passe avait traite tout le reste. Ils avaient echappe a l'audit precedent
   parce que celui-ci verifiait des selecteurs connus (`.footer__*`) au lieu
   de parcourir le pied element par element.

   LA CAUSE, ET ELLE EXPLIQUE POURQUOI LE DEFAUT EXISTE DANS LES DEUX RAMPES :
   ces regles ecrivaient `color:var(--paper)`.

   `--paper` est le FOND DE LA PAGE, pas une encre : #0B0F16 en sombre,
   #FFFFFF en clair. Le pied, lui, est peint en `--shade` (#121722 / #F7F8FC).
   Un fond pose comme une encre sur un fond voisin donne donc du noir sur noir
   en sombre et du blanc sur blanc en clair — le jeton bascule bien, et c'est
   precisement pour cela que le texte reste invisible des deux cotes. Le bloc
   avait ete ecrit quand l'infolettre reposait sur un fond inverse, ou
   « paper » designait effectivement l'encre claire.

   C'est le defaut SYMETRIQUE de celui deja documente plus haut pour
   `--white` : la-bas une encre servait de surface, ici une surface sert
   d'encre. Meme lecon — un jeton nomme d'apres ce qu'il EST, pas d'apres ce
   a quoi il ressemble un jour donne.

   LE CHAMP DE SAISIE PORTAIT LA MEME FAUTE, et elle ne se voyait pas dans
   l'audit parce qu'un champ vide n'a pas de texte a mesurer :
   `.newsletter__form input{color:var(--paper)}` rendait invisible CE QUE LE
   VISITEUR TAPE, en theme clair. Le projet a deja paye exactement ce
   defaut sur /checkout/ (note en tete de ce fichier, 1,13:1). Le
   marque-place, lui, etait en `rgba(255,255,255,.4)` : illisible sur le pied
   clair.

   Tout le bloc passe donc aux variables du pied. Contrastes obtenus,
   mesures contre --shade :

                      | sombre  | clair
     titre / saisie   | 15,82:1 | 16,72:1   (--footer-heading)
     marque-place     |  7,10:1 |  5,49:1   (--footer-muted)
     bouton           |  6,59:1 |  5,92:1   (--accent)
   ========================================================================== */

.footer .newsletter{
  border-top:1px solid var(--footer-border);
  border-bottom:1px solid var(--footer-border);
}

.footer .newsletter h3{color:var(--footer-heading)}

/* Le filet du formulaire doit rester perceptible : c'est la seule chose qui
   dit « ceci est un champ ». `--line-strong` bascule, contrairement au
   rgba(255,255,255,.3) qu'il remplace. */
.footer .newsletter__form{border-bottom:1px solid var(--line-strong)}

/* Ce que le visiteur tape prend l'encre la plus lisible du pied. */
.footer .newsletter__form input{color:var(--footer-heading)}
.footer .newsletter__form input::placeholder{color:var(--footer-muted);opacity:1}

/* Le champ dit qu'il a le focus. Sans cela, la seule zone de saisie du pied
   ne signale rien au clavier. */
.footer .newsletter__form:focus-within{border-bottom-color:var(--accent)}

/* « Sign up » est une action : elle prend l'accent, pas la couleur du texte
   courant, pour se distinguer de la phrase qui la precede. */
.footer .newsletter__form button{color:var(--accent);cursor:pointer;background:none;border:0}
.footer .newsletter__form button:hover,
.footer .newsletter__form button:focus-visible{color:var(--footer-link-hover)}


/* ==========================================================================
   PAIEMENT — LE TUNNEL EN TROIS ETAPES (2026-09-01, seconde passe)
   ==========================================================================

   La barre 01/02/03 existait deja mais ne commandait rien : les trois
   sections s'empilaient sous l'etape 01. Ces regles donnent a la barre le
   pouvoir qu'elle annoncait.

   UNE SEULE REGLE MASQUE, ET ELLE NE S'APPLIQUE QUE PAR JAVASCRIPT.
   `.dgs-hidden-step` n'est jamais ecrit dans le HTML : c'est le module du
   runtime qui la pose. Sans JavaScript, aucune section n'est masquee et le
   formulaire reste utilisable d'un bloc — le paiement ne depend jamais d'un
   script pour etre atteignable.
   ========================================================================== */

.dgs-hidden-step{display:none !important}

/* ---------- La navigation entre etapes ---------- */

.dgs-stepnav{
  display:flex;
  align-items:center;
  gap:1rem;
  flex-wrap:wrap;
  margin-top:1.75rem;
  padding-top:1.5rem;
  border-top:1px solid var(--line);
}

/* « Continuer » pousse a droite ; « Retour » reste a gauche. Quand le retour
   est absent (etape 01), la marge automatique garde le bouton principal a sa
   place plutot que de le faire sauter d'un cote a l'autre. */
.dgs-stepnav__next{margin-left:auto}

.dgs-stepnav__back,
.dgs-stepnav__next{
  display:inline-flex;
  align-items:center;
  gap:.55rem;
  font-family:inherit;
  font-size:.9375rem;
  font-weight:600;
  line-height:1;
  cursor:pointer;
  border-radius:9px;
  transition:background .25s, color .25s, border-color .25s;
}

.dgs-stepnav__back{
  background:none;
  border:0;
  padding:.85rem .25rem;
  color:var(--ink-3);
}
.dgs-stepnav__back:hover{color:var(--ink)}

.dgs-stepnav__next{
  background:var(--accent);
  border:1.5px solid var(--accent);
  color:var(--white);
  padding:.95rem 1.5rem;
  min-height:50px;
}
.dgs-stepnav__next:hover{background:var(--accent-dark);border-color:var(--accent-dark)}

.dgs-stepnav__back svg,
.dgs-stepnav__next svg{
  width:17px;height:17px;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;
}

/* `hidden` sur un element `display:flex` ne fait rien : la propriete
   d'affichage gagne contre l'attribut. Sans cette regle, le bouton
   « Retour » resterait visible a l'etape 01. */
.dgs-stepnav__back[hidden],
.dgs-stepnav__next[hidden]{display:none}

/* ---------- Les erreurs de champ ---------- */

.woocommerce-checkout .form-row.dgs-invalid .input-text,
.woocommerce-checkout .form-row.dgs-invalid select{
  border-color:var(--error,#EF4444);
}

.dgs-field-error{
  display:block;
  margin-top:.4rem;
  font-size:var(--fs-small);
  line-height:1.4;
  color:var(--error,#EF4444);
}

/* ---------- La barre d'etapes devient cliquable ---------- */

/* Elle pilote desormais le formulaire : le curseur doit le dire. */
.dgs-steps__link{cursor:pointer}

/* Une etape a venir se lit comme telle — atteignable, mais pas encore
   franchie. On ne la desactive pas : le client peut vouloir regarder plus
   loin, et la validation l'arretera s'il n'a pas rempli ce qu'il faut. */
.dgs-steps__item:not(.is-current):not(.is-done) .dgs-steps__link{color:var(--ink-4)}

/* ---------- Mobile ----------
   A l'etape 03, la colonne de gauche ne contient plus que la navigation et le
   paiement : le bouton « Retour » ne doit pas se retrouver seul sur une ligne
   perdue au-dessus. Il reste compact et aligne a gauche. */
@media (max-width:1023px){
  .dgs-stepnav{margin-top:1.25rem;padding-top:1.25rem}
  .dgs-stepnav__next{flex:1;justify-content:center}
}


/* ==========================================================================
   PAIEMENT — AUCUNE MARQUE DE PAIEMENT AVANT L'ETAPE 03 (2026-09-01)
   ==========================================================================

   SIGNALE PAR LE CLIENT : « les logos de paiement normalement ne doivent
   s'afficher qu'a la 3eme etape qui est payment ».

   CE QUE LA MESURE A MONTRE. Le bloc du tunnel (`.dgs-paymarks`) etait bien
   masque hors de l'etape 03 — verifie : hauteur 0 a l'etape 01. Les logos que
   le client voyait venaient d'AILLEURS : du PIED DE PAGE, qui porte sa propre
   bande « Accepted payment methods » avec Visa, Mastercard, American Express
   et PayPal, et qui s'affiche sur toutes les pages, paiement compris.

   Ma premiere verification avait conclu trop vite parce qu'elle testait la
   classe posee sur l'element lui-meme, sans remonter ses ancetres ni mesurer
   sa hauteur. Elle repondait « masque » pour le bon bloc et ne regardait pas
   le second.

   Sur le tunnel, la bande du pied part donc. Elle ne disparait que sur
   /checkout/ : ailleurs elle reste utile, c'est meme la reponse a la question
   « est-ce que je peux payer ici », posee AVANT d'entrer dans le tunnel.
   ========================================================================== */

body.woocommerce-checkout .footer__pay{display:none}
