/* ============================================================
   LightCracked UEFN — Design system + composants
   ============================================================ */

/* Les polices sont chargées par une balise <link> dans le HTML.
   Un @import ici obligerait le navigateur à télécharger puis lire
   cette feuille AVANT de découvrir les polices : trois allers-retours
   en série avant le moindre texte affiché, très pénalisant sur mobile. */

/* ---------- Tokens ---------- */
:root{
  --bg:            #06070A;
  --surface:       #0E1118;
  --surface-2:     #12161F;
  --line:          rgba(255,255,255,.07);
  --line-strong:   rgba(255,255,255,.14);

  --text:          #ECEEF4;
  --text-dim:      #9AA1B4;
  --text-faint:    #626A7E;

  --violet:        #7C5CFF;
  --violet-soft:   #A78BFF;
  --cyan:          #22E0FF;
  --pink:          #FF4D8D;
  --green:         #34E5A0;
  --amber:         #FFB020;

  --grad:          linear-gradient(120deg, #7C5CFF 0%, #22E0FF 100%);
  --grad-text:     linear-gradient(100deg,#FFFFFF 0%,#C7C4FF 42%,#7CE9FF 100%);

  --r:    16px;
  --r-lg: 22px;
  --r-xl: 30px;

  --shadow:      0 20px 60px -20px rgba(0,0,0,.8);
  --shadow-glow: 0 0 0 1px rgba(124,92,255,.25), 0 20px 70px -25px rgba(124,92,255,.55);

  --nav-h: 72px;
  --maxw: 1240px;
  --ease: cubic-bezier(.22,1,.36,1);
}

/* ---------- Reset ---------- */
*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; scroll-padding-top:calc(var(--nav-h) + 24px); -webkit-text-size-adjust:100%; }
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:15px; line-height:1.65; -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
body.no-scroll{ overflow:hidden; }
img,svg,video,iframe{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
input,select,textarea{ font:inherit; color:inherit; }
h1,h2,h3,h4,h5{ font-family:'Sora',sans-serif; font-weight:700; line-height:1.12; letter-spacing:-.025em; margin:0; }
p{ margin:0; }
ul{ margin:0; padding:0; list-style:none; }
::selection{ background:rgba(124,92,255,.4); }

::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-track{ background:var(--bg); }
::-webkit-scrollbar-thumb{ background:#20242F; border-radius:20px; border:2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover{ background:#2C3140; }

/* ---------- Layout ---------- */
/* Les enfants de grille/flex valent min-width:auto par défaut : un contenu
   large (bloc de code, adresse crypto…) élargirait la colonne au lieu de
   défiler dans sa boîte. On les autorise à rétrécir.                        */
.hero__grid > *, .stats > *, .feat-grid > *, .steps > *, .reviews > *,
.footer__grid > *, .grid > *, .pv > *, .pv__specs > *, .pay-opts > *,
.field-2 > *, .row > *{ min-width:0; }

.wrap{ width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:24px; }
.section{ position:relative; padding:104px 0; }
.section--tight{ padding:76px 0; }

.sec-head{ max-width:640px; margin-bottom:48px; }
.sec-head.center{ margin-inline:auto; text-align:center; }
.sec-title{ font-size:clamp(30px,4.2vw,46px); margin:0 0 14px; }
.sec-sub{ color:var(--text-dim); font-size:16px; }

.grad-text{ background:var(--grad-text); -webkit-background-clip:text; background-clip:text; color:transparent; }

/* ---------- Boutons ---------- */
.btn{
  position:relative; display:inline-flex; align-items:center; justify-content:center; gap:9px;
  padding:0 22px; height:46px; border-radius:12px; font-weight:600; font-size:14.5px;
  white-space:nowrap; border:1px solid transparent;
  transition:transform .25s var(--ease), box-shadow .25s var(--ease), background .2s, border-color .2s, opacity .2s;
}
.btn:active{ transform:translateY(1px) scale(.99); }
.btn svg{ width:17px; height:17px; flex-shrink:0; }

.btn--primary{ background:var(--grad); color:#08090C; box-shadow:0 10px 30px -10px rgba(124,92,255,.7); font-weight:700; }
.btn--primary:hover{ transform:translateY(-2px); box-shadow:0 16px 40px -12px rgba(124,92,255,.9); }

.btn--ghost{ background:rgba(255,255,255,.04); border-color:var(--line-strong); color:var(--text); }
.btn--ghost:hover{ background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.25); transform:translateY(-2px); }

.btn--discord{ background:#5865F2; color:#fff; box-shadow:0 10px 30px -12px rgba(88,101,242,.8); }
.btn--discord:hover{ background:#6875ff; transform:translateY(-2px); }

.btn--lg{ height:54px; padding:0 30px; font-size:15.5px; border-radius:14px; }
.btn--sm{ height:38px; padding:0 16px; font-size:13.5px; border-radius:10px; }
.btn--block{ width:100%; }
.btn:disabled{ opacity:.5; cursor:not-allowed; transform:none !important; }

.is-loading{ pointer-events:none; }
.is-loading::after{
  content:''; position:absolute; inset:0; margin:auto; width:18px; height:18px;
  border:2px solid rgba(8,9,12,.35); border-top-color:#08090C; border-radius:50%;
  animation:spin .7s linear infinite;
}
.is-loading > *{ opacity:0; }
@keyframes spin{ to{ transform:rotate(360deg) } }

/* ---------- Fond animé ---------- */
.bg-fx{ position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
.bg-grid{
  position:absolute; inset:-2px;
  background-image:
    linear-gradient(rgba(255,255,255,.028) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.028) 1px, transparent 1px);
  background-size:64px 64px;
  -webkit-mask-image:radial-gradient(ellipse 90% 60% at 50% 0%, #000 20%, transparent 75%);
  mask-image:radial-gradient(ellipse 90% 60% at 50% 0%, #000 20%, transparent 75%);
}
/* Les halos colorés du fond.
   Ils étaient obtenus avec filter:blur(120px) sur un disque plein — c'est
   l'opération la plus coûteuse qui soit pour un GPU de téléphone, recalculée
   à chaque image tant que le halo bouge. Un dégradé radial donne le même
   rendu et ne coûte rien : il est peint une fois, comme une image. */
/* Chaque halo remplaçait un disque de rayon R flouté à 120 px. Un flou
   gaussien garde la couleur pleine jusqu'à R−2σ, tombe à 50 % pile sur R,
   et s'éteint vers R+2σ. Les paliers ci-dessous reproduisent ce profil,
   et la taille de l'élément vaut le diamètre total ainsi étalé. */
.orb{ position:absolute; border-radius:50%; opacity:.45; }
.orb--1{                                    /* R 310 · σ 120 → rayon utile 550 */
  width:1100px; height:1100px; top:-500px; left:-380px;
  background:radial-gradient(closest-side,
    rgba(75,47,207,1) 0%, rgba(75,47,207,1) 13%,
    rgba(75,47,207,.5) 56%, rgba(75,47,207,.12) 80%, transparent 100%);
  animation:float1 22s ease-in-out infinite;
}
.orb--2{                                    /* R 260 · σ 120 → rayon utile 500 */
  width:1000px; height:1000px; top:-380px; right:-400px;
  background:radial-gradient(closest-side,
    rgba(14,124,155,1) 0%, rgba(14,124,155,1) 4%,
    rgba(14,124,155,.5) 52%, rgba(14,124,155,.12) 78%, transparent 100%);
  animation:float2 26s ease-in-out infinite;
}
.orb--3{                                    /* R 230 · σ 120 → rayon utile 470 */
  width:940px; height:940px; top:calc(52% - 240px); left:calc(38% - 240px); opacity:.22;
  background:radial-gradient(closest-side,
    rgba(91,30,119,.97) 0%,
    rgba(91,30,119,.5) 49%, rgba(91,30,119,.12) 76%, transparent 100%);
  animation:float1 30s ease-in-out infinite reverse;
}
@keyframes float1{ 0%,100%{ transform:translate(0,0) } 50%{ transform:translate(70px,50px) } }
@keyframes float2{ 0%,100%{ transform:translate(0,0) } 50%{ transform:translate(-60px,70px) } }
.noise{ position:absolute; inset:0; opacity:.03; mix-blend-mode:overlay; background-image:var(--noise-url); }

main,header,footer{ position:relative; z-index:1; }

/* ---------- Nav ---------- */
.nav{
  position:fixed; top:0; left:0; right:0; height:var(--nav-h); z-index:900;
  display:flex; align-items:center; border-bottom:1px solid transparent;
  transition:background .35s, border-color .35s, height .35s;
}
.nav.scrolled{
  background:rgba(6,7,10,.75); backdrop-filter:blur(18px) saturate(160%);
  -webkit-backdrop-filter:blur(18px) saturate(160%);
  border-bottom-color:var(--line); height:64px;
}
.nav__inner{ display:flex; align-items:center; gap:26px; width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:24px; }
.logo{ display:flex; align-items:center; gap:11px; font-family:'Sora'; font-weight:800; font-size:17.5px; letter-spacing:-.03em; flex-shrink:0; }
.logo__mark{
  width:34px; height:34px; border-radius:10px; background:var(--grad);
  display:grid; place-items:center; box-shadow:0 6px 20px -6px rgba(124,92,255,.9); flex-shrink:0;
}
.logo__mark svg{ width:19px; height:19px; }
.logo em{ display:block; font-style:normal; font-family:'JetBrains Mono'; font-size:9px; letter-spacing:.22em; color:var(--text-faint); font-weight:400; margin-top:-4px; }

.nav__links{ display:flex; align-items:center; gap:2px; margin-right:auto; }
.nav__links a{ padding:8px 13px; border-radius:9px; font-size:14px; font-weight:500; color:var(--text-dim); transition:color .2s, background .2s; }
.nav__links a:hover{ color:var(--text); background:rgba(255,255,255,.05); }

.nav__actions{ display:flex; align-items:center; gap:10px; margin-left:auto; }

.lang{ display:flex; align-items:center; gap:2px; padding:3px; border:1px solid var(--line); border-radius:9px; background:rgba(255,255,255,.03); flex-shrink:0; }
.lang button{ padding:5px 9px; border-radius:6px; font-size:11.5px; font-weight:700; font-family:'JetBrains Mono'; color:var(--text-faint); transition:.2s; }
.lang button.on{ background:rgba(255,255,255,.1); color:var(--text); }


.burger{ display:none; width:42px; height:42px; border-radius:11px; border:1px solid var(--line-strong); place-items:center; flex-shrink:0; }
.burger span{ display:block; width:17px; height:1.8px; background:var(--text); border-radius:2px; transition:.3s var(--ease); }
.burger span+span{ margin-top:4px; }
.burger.open span:nth-child(1){ transform:translateY(5.8px) rotate(45deg); }
.burger.open span:nth-child(2){ opacity:0; }
.burger.open span:nth-child(3){ transform:translateY(-5.8px) rotate(-45deg); }

.mobile-menu{
  position:fixed; inset:var(--nav-h) 0 0; z-index:880; background:rgba(6,7,10,.98);
  backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);
  padding:28px 24px; display:flex; flex-direction:column; gap:6px;
  transform:translateX(100%); transition:transform .4s var(--ease); visibility:hidden;
}
.mobile-menu.open{ transform:none; visibility:visible; }
.mobile-menu a{ padding:16px 4px; font-size:20px; font-family:'Sora'; font-weight:600; border-bottom:1px solid var(--line); }

/* ---------- Hero ---------- */
.hero{ padding-top:calc(var(--nav-h) + 72px); padding-bottom:80px; }
.hero__grid{ display:grid; grid-template-columns:1.05fr .95fr; gap:60px; align-items:center; }
.hero h1{ font-size:clamp(36px,5.4vw,64px); margin:0 0 22px; font-weight:800; }
.hero h1 .line{ display:block; }
.hero__sub{ font-size:17.5px; color:var(--text-dim); max-width:520px; margin-bottom:34px; }
.hero__cta{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:40px; }

.hero__trust{ display:flex; align-items:center; gap:16px; }
.avatars{ display:flex; }
.avatars span{
  width:34px; height:34px; border-radius:50%; border:2px solid var(--bg); margin-left:-11px;
  display:grid; place-items:center; font-size:12px; font-weight:800; font-family:'Sora'; color:#0a0b0e;
}
.avatars span:first-child{ margin-left:0; }
.hero__trust small{ color:var(--text-dim); font-size:13.5px; line-height:1.45; display:block; }
.hero__trust b{ color:var(--text); }
.stars{ color:var(--amber); font-size:12px; letter-spacing:2px; }

.hero__visual{ position:relative; }
.code-card{
  border-radius:var(--r-lg); border:1px solid var(--line-strong);
  background:linear-gradient(160deg, rgba(20,24,34,.92), rgba(10,12,18,.95));
  box-shadow:var(--shadow); overflow:hidden;
  transform:perspective(1400px) rotateY(-7deg) rotateX(3deg);
  transition:transform .7s var(--ease);
}
.code-card:hover{ transform:perspective(1400px) rotateY(-2deg) rotateX(1deg); }
.code-card__bar{ display:flex; align-items:center; gap:8px; padding:13px 16px; border-bottom:1px solid var(--line); background:rgba(255,255,255,.025); }
.dot{ width:11px; height:11px; border-radius:50%; flex-shrink:0; }
.code-card__bar em{ font-style:normal; font-family:'JetBrains Mono'; font-size:11.5px; color:var(--text-faint); margin-left:10px; }
.code-card pre{ margin:0; padding:20px 18px; font-family:'JetBrains Mono',monospace; font-size:12.5px; line-height:1.85; overflow-x:auto; max-width:100%; color:#C3C9DA; }
.k{ color:#FF7BC0; } .t{ color:#7CE9FF; } .s{ color:#B4FF3A; } .n{ color:#FFB020; } .fn{ color:#A78BFF; }

.code-badge{
  position:absolute; padding:9px 14px; border-radius:12px; z-index:3;
  background:rgba(14,17,24,.92); border:1px solid var(--line-strong);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  font-size:12.5px; font-weight:600; display:flex; align-items:center; gap:8px;
  box-shadow:var(--shadow); animation:bob 5s ease-in-out infinite; white-space:nowrap;
}
.code-badge i{ width:7px; height:7px; border-radius:50%; display:block; flex-shrink:0; }
.code-badge--1{ top:-18px; right:-14px; }
.code-badge--2{ bottom:-20px; left:-24px; animation-delay:-2.5s; }
@keyframes bob{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-9px) } }

/* ---------- Stats ---------- */
.stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r-lg); overflow:hidden; }
.stat{ background:linear-gradient(180deg,rgba(14,17,24,.9),rgba(8,10,14,.9)); padding:28px 18px; text-align:center; transition:background .3s; }
.stat:hover{ background:linear-gradient(180deg,rgba(24,28,40,.9),rgba(12,14,20,.9)); }
.stat b{ display:block; font-family:'Sora'; font-size:clamp(26px,3.4vw,34px); font-weight:800; letter-spacing:-.04em; }
.stat b.stat--word{ font-size:clamp(19px,2.4vw,25px); }
.stat > span{ font-size:11.5px; color:var(--text-dim); font-family:'JetBrains Mono'; letter-spacing:.08em; text-transform:uppercase; }

/* ---------- Boutique ---------- */
.shop__bar{ display:flex; gap:14px; align-items:center; margin-bottom:30px; flex-wrap:wrap; }
.shop__tools{ display:flex; gap:10px; align-items:center; margin-left:auto; }
.filters{ display:flex; gap:7px; flex-wrap:wrap; }
.chip{
  padding:9px 16px; border-radius:100px; border:1px solid var(--line);
  background:rgba(255,255,255,.03); font-size:13.5px; font-weight:500; color:var(--text-dim);
  transition:.22s var(--ease); display:inline-flex; align-items:center; gap:7px; white-space:nowrap;
}
.chip:hover{ border-color:var(--line-strong); color:var(--text); background:rgba(255,255,255,.06); }
.chip.on{ background:var(--grad); color:#08090C; border-color:transparent; font-weight:700; box-shadow:0 8px 24px -10px rgba(124,92,255,.8); }
.chip em{ font-style:normal; opacity:.65; font-size:11.5px; font-family:'JetBrains Mono'; }

.search{ position:relative; min-width:220px; }
.search svg{ position:absolute; left:14px; top:50%; transform:translateY(-50%); width:16px; height:16px; color:var(--text-faint); pointer-events:none; }
.search input{
  width:100%; height:42px; padding:0 14px 0 40px; border-radius:11px;
  background:rgba(255,255,255,.04); border:1px solid var(--line); outline:none; font-size:14px; transition:.22s;
}
.search input::placeholder{ color:var(--text-faint); }
.search input:focus{ border-color:rgba(124,92,255,.55); background:rgba(124,92,255,.06); box-shadow:0 0 0 4px rgba(124,92,255,.1); }

.sort{
  height:42px; padding:0 34px 0 14px; border-radius:11px; border:1px solid var(--line);
  background-color:rgba(255,255,255,.04); outline:none; font-size:14px; appearance:none; cursor:pointer;
  background-image:var(--chevron-url); background-repeat:no-repeat; background-position:right 12px center; background-size:14px;
}
.sort option{ background:#12161F; color:#ECEEF4; }

.grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(288px,1fr)); gap:22px; }

/* ---------- Visuels produits ---------- */
.art{ position:absolute; inset:0; transition:transform .6s var(--ease); }
.art__pattern{ position:absolute; inset:0; width:100%; height:100%; }
.art__icon{ position:absolute; inset:0; display:grid; place-items:center; opacity:.5; }
.art--img img{ width:100%; height:100%; object-fit:cover; }

/* ---------- Carte produit ---------- */
.card{
  position:relative; border-radius:var(--r-lg); border:1px solid var(--line);
  background:linear-gradient(170deg, rgba(16,19,27,.9), rgba(9,11,16,.9));
  overflow:hidden; display:flex; flex-direction:column; cursor:pointer;
  transition:transform .4s var(--ease), border-color .35s, box-shadow .4s;
  animation:cardIn .5s var(--ease) both;
}
/* « translate » et non « transform » : l'animation d'entrée est déclarée
   avec fill-mode:both, sa valeur finale reste donc appliquée pour toujours,
   et une animation l'emporte sur toute déclaration CSS. En passant par la
   propriété distincte « translate », le transform reste libre pour
   l'inclinaison sous la souris et le soulèvement au survol. */
@keyframes cardIn{ from{ opacity:0; translate:0 18px } to{ opacity:1; translate:0 0 } }
.card:hover{ transform:translateY(-6px); border-color:rgba(124,92,255,.4); box-shadow:var(--shadow-glow); }
.card:hover .art{ transform:scale(1.06); }

.card__media{ position:relative; aspect-ratio:16/10; overflow:hidden; background:#0B0D13; }
.card__media::after{ content:''; position:absolute; inset:0; background:linear-gradient(to top, rgba(9,11,16,.95) 2%, transparent 58%); pointer-events:none; }
.card__tags{ position:absolute; top:12px; left:12px; display:flex; gap:6px; z-index:2; flex-wrap:wrap; }
.tag{ padding:4px 9px; border-radius:7px; font-size:10.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; font-family:'JetBrains Mono'; backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); }
.tag--new{ background:rgba(52,229,160,.16); color:var(--green); border:1px solid rgba(52,229,160,.3); }
.tag--hot{ background:rgba(255,77,141,.16); color:var(--pink); border:1px solid rgba(255,77,141,.3); }
.tag--sale{ background:rgba(255,176,32,.16); color:var(--amber); border:1px solid rgba(255,176,32,.3); }
.tag--cat{ background:rgba(255,255,255,.08); color:var(--text-dim); border:1px solid var(--line-strong); }

.card__vbadge{
  position:absolute; top:12px; right:12px; z-index:2; display:inline-flex; align-items:center; gap:5px;
  padding:4px 9px; border-radius:7px; font-size:10.5px; font-weight:700; text-transform:uppercase;
  font-family:'JetBrains Mono'; letter-spacing:.06em;
  background:rgba(255,77,141,.16); color:var(--pink); border:1px solid rgba(255,77,141,.3);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
}
.card__vbadge svg{ width:10px; height:10px; }

.card__preview{
  position:absolute; bottom:12px; right:12px; z-index:2; height:32px; padding:0 12px;
  border-radius:9px; font-size:12.5px; font-weight:600; background:rgba(6,7,10,.72);
  border:1px solid var(--line-strong); backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  display:inline-flex; align-items:center; gap:6px; opacity:0; transform:translateY(6px); transition:.3s var(--ease);
}
.card:hover .card__preview{ opacity:1; transform:none; }
.card__preview svg{ width:13px; height:13px; }

.card__body{ padding:18px; display:flex; flex-direction:column; flex:1; gap:10px; }
.card__title{ font-size:16.5px; font-family:'Sora'; font-weight:600; letter-spacing:-.02em; }
.card__desc{ font-size:13.5px; color:var(--text-dim); line-height:1.6; flex:1; }
.card__meta{ display:flex; gap:14px; font-size:11.5px; color:var(--text-faint); font-family:'JetBrains Mono'; flex-wrap:wrap; }
.card__meta span{ display:flex; align-items:center; gap:5px; }
.card__meta svg{ width:12px; height:12px; }

.card__foot{ display:flex; align-items:center; gap:12px; padding-top:14px; border-top:1px solid var(--line); }
.price{ display:flex; align-items:baseline; gap:7px; margin-right:auto; flex-wrap:wrap; }
.price b{ font-family:'Sora'; font-size:22px; font-weight:700; letter-spacing:-.03em; }
.price del{ font-size:13px; color:var(--text-faint); }

.add-btn{
  width:40px; height:40px; border-radius:11px; background:var(--grad); color:#08090C;
  display:grid; place-items:center; transition:.25s var(--ease); flex-shrink:0;
  box-shadow:0 8px 22px -10px rgba(124,92,255,.8);
}
/* Le bouton pivotait de 90° au survol : trop démonstratif, et on perdait
   de vue l'icône. Un simple relief suffit à montrer qu'il est cliquable. */
.add-btn:hover{ transform:translateY(-2px); box-shadow:0 12px 26px -10px rgba(124,92,255,.95); }
.add-btn:active{ transform:translateY(0) scale(.96); }
.add-btn svg{ width:18px; height:18px; }
.add-btn.done{ background:var(--green); transform:none; }
.add-btn.done svg{ animation:pop .4s var(--ease); }
@keyframes pop{ 0%{ transform:scale(0) } 60%{ transform:scale(1.3) } 100%{ transform:scale(1) } }

.empty{ grid-column:1/-1; text-align:center; padding:70px 20px; color:var(--text-faint); }
.empty svg{ width:44px; height:44px; margin:0 auto 16px; opacity:.4; }

/* ---------- Pourquoi nous ---------- */
.feat-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:20px; }
.feat{
  padding:30px 26px; border-radius:var(--r-lg); border:1px solid var(--line);
  background:linear-gradient(170deg,rgba(16,19,27,.8),rgba(9,11,16,.8));
  transition:.4s var(--ease);
}
.feat:hover{ border-color:var(--line-strong); transform:translateY(-4px); }
.feat__ico{
  width:46px; height:46px; border-radius:13px; display:grid; place-items:center; margin-bottom:18px;
  background:rgba(124,92,255,.12); border:1px solid rgba(124,92,255,.25); color:var(--violet-soft);
}
.feat__ico svg{ width:21px; height:21px; }
.feat h3{ font-size:18px; margin-bottom:9px; }
.feat p{ font-size:14px; color:var(--text-dim); }

/* ---------- Étapes ---------- */
.steps{ display:grid; grid-template-columns:repeat(4,1fr); gap:20px; position:relative; }
.steps::before{ content:''; position:absolute; top:26px; left:8%; right:8%; height:1px; background:linear-gradient(90deg,transparent,var(--line-strong) 15%,var(--line-strong) 85%,transparent); }
.step{ text-align:center; position:relative; }
.step__n{
  width:52px; height:52px; margin:0 auto 18px; border-radius:16px; display:grid; place-items:center;
  font-family:'Sora'; font-weight:800; font-size:19px; background:var(--surface-2);
  border:1px solid var(--line-strong); position:relative; z-index:1; transition:.35s var(--ease);
}
.step:hover .step__n{ background:var(--grad); color:#08090C; border-color:transparent; transform:scale(1.08); box-shadow:0 12px 30px -12px rgba(124,92,255,.9); }
.step h4{ font-size:16px; margin-bottom:8px; }
.step p{ font-size:13.5px; color:var(--text-dim); }

/* ---------- Avis ---------- */
.reviews{ display:grid; grid-template-columns:repeat(3,1fr); gap:20px; }
.review{
  padding:26px; border-radius:var(--r-lg); border:1px solid var(--line);
  background:linear-gradient(170deg,rgba(16,19,27,.8),rgba(9,11,16,.8));
  display:flex; flex-direction:column; gap:16px; transition:.35s var(--ease);
}
.review:hover{ border-color:var(--line-strong); transform:translateY(-4px); }
.review p{ font-size:14.5px; color:var(--text-dim); line-height:1.7; flex:1; }
.review__who{ display:flex; align-items:center; gap:12px; }
.review__av{ width:40px; height:40px; border-radius:12px; display:grid; place-items:center; font-family:'Sora'; font-weight:800; color:#08090C; font-size:15px; flex-shrink:0; }
.review__who b{ display:block; font-size:14px; }
.review__who small{ color:var(--text-faint); font-size:12px; font-family:'JetBrains Mono'; }

/* ---------- FAQ ---------- */
.faq{ max-width:820px; margin-inline:auto; display:flex; flex-direction:column; gap:10px; }
.q{ border:1px solid var(--line); border-radius:var(--r); background:rgba(16,19,27,.6); overflow:hidden; transition:border-color .3s, background .3s; }
.q.open{ border-color:rgba(124,92,255,.4); background:rgba(124,92,255,.045); }
.q__head{ width:100%; display:flex; align-items:center; gap:16px; padding:19px 22px; text-align:left; font-weight:600; font-size:15.5px; font-family:'Sora'; }
.q__head i{ margin-left:auto; width:20px; height:20px; flex-shrink:0; position:relative; }
.q__head i::before,.q__head i::after{ content:''; position:absolute; background:var(--text-dim); border-radius:2px; top:50%; left:50%; transform:translate(-50%,-50%); }
.q__head i::before{ width:12px; height:1.8px; }
.q__head i::after{ width:1.8px; height:12px; transition:transform .35s var(--ease); }
.q.open .q__head i::after{ transform:translate(-50%,-50%) scaleY(0); }
.q__body{ max-height:0; overflow:hidden; transition:max-height .4s var(--ease); }
.q__body p{ padding:0 22px 20px; color:var(--text-dim); font-size:14.5px; }

/* ---------- CTA ---------- */
.cta{
  position:relative; border-radius:var(--r-xl); padding:60px 40px; text-align:center; overflow:hidden;
  border:1px solid rgba(124,92,255,.28);
  background:linear-gradient(150deg, rgba(35,25,80,.7), rgba(12,14,22,.85) 55%, rgba(10,40,60,.6));
}
.cta::before{
  content:''; position:absolute; inset:0;
  background-image:linear-gradient(rgba(255,255,255,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.03) 1px,transparent 1px);
  background-size:40px 40px;
  -webkit-mask-image:radial-gradient(ellipse at center, #000, transparent 70%);
  mask-image:radial-gradient(ellipse at center, #000, transparent 70%);
}
.cta > *{ position:relative; }
.cta h2{ font-size:clamp(26px,4vw,42px); margin:0 0 14px; }
.cta p{ color:var(--text-dim); max-width:520px; margin:0 auto 30px; font-size:16px; }
.cta__btns{ display:flex; gap:12px; justify-content:center; flex-wrap:wrap; }
.live{ display:inline-flex; align-items:center; gap:8px; font-size:13px; color:var(--text-dim); margin-top:24px; font-family:'JetBrains Mono'; flex-wrap:wrap; justify-content:center; }
.live i{ width:8px; height:8px; border-radius:50%; background:var(--green); box-shadow:0 0 0 0 rgba(52,229,160,.7); animation:pulse 2s infinite; flex-shrink:0; }
@keyframes pulse{ 70%{ box-shadow:0 0 0 9px rgba(52,229,160,0) } 100%{ box-shadow:0 0 0 0 rgba(52,229,160,0) } }

/* ---------- Footer ---------- */
.footer{ border-top:1px solid var(--line); padding:64px 0 30px; margin-top:40px; background:rgba(8,9,13,.6); }
.footer__grid{ display:grid; grid-template-columns:1.6fr 1fr 1fr 1fr; gap:44px; margin-bottom:48px; }
.footer__about p{ color:var(--text-dim); font-size:14px; margin:16px 0 20px; max-width:300px; }
.socials{ display:flex; gap:9px; }
.socials a{ width:38px; height:38px; border-radius:11px; border:1px solid var(--line); background:rgba(255,255,255,.03); display:grid; place-items:center; color:var(--text-dim); transition:.25s var(--ease); }
.socials a:hover{ color:var(--text); border-color:var(--line-strong); transform:translateY(-3px); background:rgba(255,255,255,.07); }
.socials svg{ width:17px; height:17px; }
.footer h5{ font-size:13px; text-transform:uppercase; letter-spacing:.12em; color:var(--text-faint); margin:0 0 18px; font-weight:600; }
.footer li+li{ margin-top:11px; }
.footer li a{ color:var(--text-dim); font-size:14px; transition:color .2s; }
.footer li a:hover{ color:var(--violet-soft); }
.footer__bot{ border-top:1px solid var(--line); padding-top:24px; display:flex; justify-content:space-between; align-items:center; gap:20px; flex-wrap:wrap; font-size:13px; color:var(--text-faint); }
.disclaimer{ font-size:11.5px; color:var(--text-faint); text-align:center; margin-top:20px; opacity:.7; max-width:800px; margin-inline:auto; line-height:1.6; }

/* ============================================================
   Overlays
   ============================================================ */
.scrim{
  position:fixed; inset:0; z-index:950; background:rgba(3,4,6,.74);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  opacity:0; visibility:hidden; transition:opacity .35s, visibility .35s;
}
.scrim.open{ opacity:1; visibility:visible; }

/* Bouton de fermeture des panneaux */
.x-btn{
  width:34px; height:34px; border-radius:9px; border:1px solid var(--line);
  display:grid; place-items:center; color:var(--text-dim); transition:.2s; flex-shrink:0;
}
.x-btn:hover{ background:rgba(255,255,255,.07); color:var(--text); }
.x-btn svg{ width:15px; height:15px; }
.x-btn--float{
  position:absolute; top:14px; right:14px; z-index:6;
  background:rgba(8,10,16,.85); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-color:var(--line-strong);
}

/* Lignes de totaux */
.rows{ display:flex; flex-direction:column; gap:9px; }
.row{ display:flex; justify-content:space-between; gap:12px; font-size:13.5px; color:var(--text-dim); }
.row.total{ font-size:19px; color:var(--text); font-family:'Sora'; font-weight:700; padding-top:12px; border-top:1px solid var(--line); }
.row .disc{ color:var(--green); }

/* Modales */
.modal{
  position:fixed; top:50%; left:50%; transform:translate(-50%,-46%) scale(.97); z-index:970;
  width:min(940px,calc(100% - 32px)); max-height:88vh; border-radius:var(--r-xl);
  background:linear-gradient(165deg,#101420,#08090E); border:1px solid var(--line-strong);
  box-shadow:0 40px 120px -30px rgba(0,0,0,.95); overflow:hidden;
  opacity:0; visibility:hidden; transition:opacity .35s var(--ease), transform .35s var(--ease), visibility .35s;
  display:flex; flex-direction:column;
}
.modal.open{ opacity:1; visibility:visible; transform:translate(-50%,-50%) scale(1); }
.modal--sm{ width:min(580px,calc(100% - 32px)); }
.modal__scroll{ overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain; }

/* Fiche produit */
.pv{ display:grid; grid-template-columns:1.15fr 1fr; }
.pv__media{ position:relative; min-height:320px; background:#0A0C12; overflow:hidden; }
.pv__media::after{ content:''; position:absolute; inset:0; background:linear-gradient(to top, rgba(9,11,16,.55), transparent 50%); pointer-events:none; }
.pv__media--playing{ background:#000; display:grid; place-items:center; }
.pv__media--playing::after{ display:none; }
.media__video{ width:100%; height:100%; min-height:320px; border:0; background:#000; object-fit:contain; }

.pv__play{
  position:absolute; left:50%; bottom:20px; transform:translateX(-50%); z-index:4;
  display:inline-flex; align-items:center; gap:9px; height:42px; padding:0 20px; border-radius:12px;
  background:rgba(6,7,10,.78); border:1px solid var(--line-strong); color:var(--text);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  font-weight:600; font-size:14px; transition:.25s var(--ease); white-space:nowrap;
}
.pv__play:hover{ background:var(--grad); color:#08090C; border-color:transparent; transform:translateX(-50%) translateY(-2px); }
.pv__play svg{ width:16px; height:16px; }
.pv__play--close{ bottom:14px; }
.pv__soon{
  position:absolute; left:50%; bottom:20px; transform:translateX(-50%); z-index:4;
  display:inline-flex; align-items:center; gap:8px; padding:7px 14px; border-radius:10px;
  background:rgba(6,7,10,.7); border:1px solid var(--line); color:var(--text-faint);
  font-size:12.5px; backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); white-space:nowrap;
}
.pv__soon svg{ width:14px; height:14px; }

.pv__side{ padding:32px 30px; display:flex; flex-direction:column; gap:16px; }
.pv__side h2{ font-size:25px; }
.pv__side .lead{ color:var(--text-dim); font-size:14.5px; }
.pv__h{ font-size:12px; text-transform:uppercase; letter-spacing:.12em; color:var(--text-faint); margin:0 0 12px; font-weight:600; }
.pv__feats{ display:flex; flex-direction:column; gap:9px; }
.pv__feats li{ display:flex; gap:10px; font-size:13.5px; color:var(--text-dim); align-items:flex-start; }
.pv__feats svg{ width:15px; height:15px; color:var(--green); flex-shrink:0; margin-top:3px; }
.pv__specs{ display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--line); border:1px solid var(--line); border-radius:var(--r); overflow:hidden; }
.pv__specs div{ background:rgba(14,17,24,.9); padding:12px 14px; }
.pv__specs small{ display:block; font-size:10.5px; text-transform:uppercase; letter-spacing:.1em; color:var(--text-faint); font-family:'JetBrains Mono'; margin-bottom:3px; }
.pv__specs b{ font-size:13.5px; font-weight:600; }
.pv__buy{ margin-top:auto; display:flex; align-items:center; gap:14px; padding-top:18px; border-top:1px solid var(--line); flex-wrap:wrap; }
.pv__buy .btn{ margin-left:auto; }

/* ---------- Checkout ---------- */
.co{ padding:30px; }
.co__title{ font-size:23px; margin-bottom:22px; padding-right:40px; }
.co__h{ font-size:12px; text-transform:uppercase; letter-spacing:.12em; color:var(--text-faint); margin:0 0 12px; font-weight:600; }
.co__terms{ font-size:11.5px; color:var(--text-faint); text-align:center; margin:16px 0 14px; }

.co__steps{ display:flex; align-items:center; gap:10px; margin-bottom:24px; }
.co__step{ display:flex; align-items:center; gap:9px; font-size:13px; color:var(--text-faint); font-weight:600; }
.co__step i{ width:26px; height:26px; border-radius:9px; display:grid; place-items:center; border:1px solid var(--line-strong); font-family:'JetBrains Mono'; font-size:12px; font-style:normal; transition:.3s; flex-shrink:0; }
.co__step i svg{ width:13px; height:13px; }
.co__step.on{ color:var(--text); }
.co__step.on i{ background:var(--grad); color:#08090C; border-color:transparent; }
.co__step.done i{ background:rgba(52,229,160,.15); color:var(--green); border-color:rgba(52,229,160,.35); }
.co__line{ flex:1; height:1px; background:var(--line-strong); min-width:8px; }

.field{ margin-bottom:14px; }
.field label{ display:block; font-size:12.5px; color:var(--text-dim); margin-bottom:7px; font-weight:500; }
.field label span{ color:var(--pink); }
.field input, .field select{
  width:100%; height:46px; padding:0 14px; border-radius:12px; background:rgba(255,255,255,.04);
  border:1px solid var(--line); outline:none; font-size:16px; transition:.22s;
}
.field input::placeholder{ color:var(--text-faint); }
.field input:focus,.field select:focus{ border-color:rgba(124,92,255,.55); background:rgba(124,92,255,.06); box-shadow:0 0 0 4px rgba(124,92,255,.1); }
.field input.err{ border-color:var(--pink); box-shadow:0 0 0 4px rgba(255,77,141,.12); }
.hint{ font-size:11.5px; color:var(--text-faint); margin-top:6px; }
.hint--block{ margin:-4px 0 18px; }
.field-2{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }

.pay-opts{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:18px; }
.pay-opt{
  padding:18px; border-radius:var(--r); border:1.5px solid var(--line); background:rgba(255,255,255,.025);
  text-align:left; transition:.25s var(--ease); position:relative;
}
.pay-opt:hover{ border-color:var(--line-strong); background:rgba(255,255,255,.05); }
.pay-opt.on{ border-color:var(--violet); background:rgba(124,92,255,.09); box-shadow:0 0 0 4px rgba(124,92,255,.1); }
.pay-opt{ display:flex; align-items:center; gap:11px; }
.pay-opt__logo{ width:26px; height:26px; flex:0 0 26px; display:block; }
.pay-opt__logo svg{ width:100%; height:100%; }
.pay-opt__logo--ico{ color:var(--violet-soft); }
.pay-opt b{ font-family:'Sora'; font-size:15px; }
.pay-opt .badge{ position:absolute; top:12px; right:12px; font-size:10px; font-family:'JetBrains Mono'; padding:3px 7px; border-radius:6px; background:rgba(52,229,160,.15); color:var(--green); font-weight:700; }

.coins{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:16px; }
.coin{ padding:9px 14px; border-radius:11px; border:1px solid var(--line); background:rgba(255,255,255,.03); font-size:13px; font-weight:600; display:flex; align-items:center; gap:8px; transition:.22s; }
.coin:hover{ border-color:var(--line-strong); }
.coin.on{ border-color:var(--violet); background:rgba(124,92,255,.1); }
.coin i{ width:22px; height:22px; border-radius:50%; display:grid; place-items:center; font-size:10px; font-weight:800; font-family:'Sora'; color:#08090C; font-style:normal; flex-shrink:0; }
.coin small{ color:var(--text-faint); font-family:'JetBrains Mono'; font-size:11px; }

.crypto-box{ border:1px solid var(--line); border-radius:var(--r); padding:20px; background:rgba(255,255,255,.02); }
.crypto-box--live{ border-color:rgba(124,92,255,.3); background:rgba(124,92,255,.04); }

.cw__head{ display:flex; align-items:center; gap:10px; padding-bottom:16px; margin-bottom:16px; border-bottom:1px solid var(--line); }
.cw__head b{ font-family:'Sora'; font-size:14px; font-weight:600; }
.cw__dot{ width:9px; height:9px; border-radius:50%; background:var(--amber); box-shadow:0 0 0 0 rgba(255,176,32,.7); animation:pulse2 2s infinite; flex-shrink:0; }
@keyframes pulse2{ 70%{ box-shadow:0 0 0 8px rgba(255,176,32,0) } 100%{ box-shadow:0 0 0 0 rgba(255,176,32,0) } }
.cw__head.is-seen .cw__dot{ background:var(--cyan); }
.cw__head.is-paid .cw__dot{ background:var(--green); animation:none; }
.cw__head.is-paid b{ color:var(--green); }
.cw__timer{ margin-left:auto; font-family:'JetBrains Mono'; font-size:13px; color:var(--text-faint); }
.cw__leave{ font-size:11.5px; color:var(--text-faint); text-align:center; margin-top:14px; line-height:1.6; }

.crypto-amt{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-bottom:16px; }
.crypto-amt__lbl{ font-size:12.5px; color:var(--text-dim); }
.crypto-amt b{ font-family:'JetBrains Mono'; font-size:21px; font-weight:700; letter-spacing:-.02em; word-break:break-all; }
.crypto-amt small{ color:var(--text-faint); font-size:12.5px; }
.crypto-amt--big{ align-items:center; }
.crypto-amt--big b{ font-size:23px; }

.qr{ width:152px; height:152px; border-radius:14px; background:#fff; padding:10px; margin:0 auto 16px; display:grid; place-items:center; }
.qr img, .qr canvas{ width:100% !important; height:100% !important; }
.qr--none{ background:rgba(255,255,255,.05); color:var(--text-faint); font-family:'JetBrains Mono'; font-size:12px; }

.addr__lbl{ font-size:12px; color:var(--text-dim); margin-bottom:8px; }
.addr__lbl b{ color:var(--text); }
.addr{ display:flex; gap:8px; align-items:center; padding:12px 14px; border-radius:11px; background:rgba(0,0,0,.45); border:1px solid var(--line); }
.addr code{ font-family:'JetBrains Mono'; font-size:11.5px; word-break:break-all; flex:1; min-width:0; color:var(--cyan); }
.copy{ width:32px; height:32px; border-radius:8px; border:1px solid var(--line-strong); display:grid; place-items:center; flex-shrink:0; transition:.2s; }
.copy:hover{ background:rgba(255,255,255,.08); }
.copy svg{ width:14px; height:14px; }
.copy.ok{ background:rgba(52,229,160,.2); border-color:rgba(52,229,160,.4); color:var(--green); }
.copy--sm{ width:28px; height:28px; margin-left:auto; }

.notice{ display:flex; gap:11px; padding:14px; border-radius:12px; font-size:12.5px; line-height:1.6; margin-top:14px; }
.notice svg{ width:16px; height:16px; flex-shrink:0; margin-top:1px; }
.notice--info{ background:rgba(34,224,255,.07); border:1px solid rgba(34,224,255,.2); color:#A9E9F7; }
.notice--warn{ background:rgba(255,176,32,.07); border:1px solid rgba(255,176,32,.22); color:#F2D9A8; }



/* Succès */
.success{ text-align:center; padding:44px 30px calc(38px + env(safe-area-inset-bottom)); }
.success__ico{ width:74px; height:74px; border-radius:50%; margin:0 auto 22px; display:grid; place-items:center; background:rgba(52,229,160,.14); border:1px solid rgba(52,229,160,.35); color:var(--green); animation:pop .5s var(--ease); }
.success__ico svg{ width:32px; height:32px; }
.success h2{ font-size:25px; margin-bottom:12px; }
.success p{ color:var(--text-dim); font-size:14.5px; }
.success__p{ margin-top:8px; }
.success__mail{ color:var(--text); word-break:break-all; }
.order-id{ display:inline-block; font-family:'JetBrains Mono'; font-size:13px; padding:8px 14px; border-radius:10px; background:rgba(124,92,255,.1); border:1px solid rgba(124,92,255,.3); color:var(--violet-soft); margin:14px 0 20px; }
.success__help{ text-align:left; margin-top:20px; }
.success__btns{ display:flex; gap:10px; justify-content:center; margin-top:24px; flex-wrap:wrap; }

/* Toasts */
.toasts{ position:fixed; bottom:22px; right:22px; z-index:999; display:flex; flex-direction:column; gap:10px; pointer-events:none; }
.toast{
  display:flex; align-items:center; gap:11px; padding:13px 17px; border-radius:13px; font-size:13.5px; font-weight:500;
  background:rgba(16,19,27,.97); border:1px solid var(--line-strong);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  box-shadow:var(--shadow); animation:toastIn .4s var(--ease); max-width:330px;
}
.toast.out{ animation:toastOut .3s var(--ease) forwards; }
.toast svg{ width:17px; height:17px; flex-shrink:0; }
.toast--ok svg{ color:var(--green); }
.toast--err svg{ color:var(--pink); }
@keyframes toastIn{ from{ opacity:0; transform:translateX(40px) } }
@keyframes toastOut{ to{ opacity:0; transform:translateX(40px) } }

/* Apparition au scroll */
.reveal{ opacity:0; transform:translateY(24px); transition:opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.in{ opacity:1; transform:none; }

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width:1024px){
  .hero__grid{ grid-template-columns:1fr; gap:48px; }
  .code-card{ transform:none; }
  .code-badge--2{ left:0; }
  .feat-grid, .reviews{ grid-template-columns:repeat(2,1fr); }
  .steps{ grid-template-columns:repeat(2,1fr); gap:32px; }
  .steps::before{ display:none; }
  .footer__grid{ grid-template-columns:1fr 1fr; gap:34px; }
  .nav__links{ display:none; }
  .burger{ display:grid; }
  .pv{ grid-template-columns:1fr; }
  .pv__media{ min-height:0; aspect-ratio:16/9; }
  .media__video{ min-height:0; aspect-ratio:16/9; height:auto; }
  .pv__media--playing{ aspect-ratio:16/9; }
}

@media (max-width:680px){
  .section{ padding:70px 0; }
  .section--tight{ padding:60px 0; }
  .wrap{ padding-inline:18px; }
  .sec-head{ margin-bottom:32px; }

  .hero{ padding-top:calc(var(--nav-h) + 40px); padding-bottom:56px; }
  .hero h1{ font-size:clamp(31px,8.4vw,42px); }
  .hero__sub{ font-size:16px; margin-bottom:28px; }
  .hero__cta{ gap:10px; }
  .hero__cta .btn{ flex:1 1 100%; }
  .code-badge--1{ top:-14px; right:0; font-size:11.5px; padding:7px 11px; }
  .code-badge--2{ bottom:-16px; left:0; font-size:11.5px; padding:7px 11px; }
  .code-card pre{ font-size:11px; padding:16px 14px; }

  .stats{ grid-template-columns:1fr 1fr; }
  .stat{ padding:22px 14px; }

  .feat-grid, .reviews, .steps, .footer__grid, .grid{ grid-template-columns:1fr; }
  .feat{ padding:24px 22px; }
  .cta{ padding:44px 20px; }

  .shop__bar{ gap:12px; }
  .shop__tools{ width:100%; margin-left:0; }
  .search{ flex:1; min-width:0; }
  .filters{ width:100%; overflow-x:auto; flex-wrap:nowrap; padding-bottom:4px; scrollbar-width:none; }
  .filters::-webkit-scrollbar{ display:none; }

  .card__preview{ opacity:1; transform:none; }

  /* Modales : feuille depuis le bas */
  .modal{
    top:auto; bottom:0; left:0; right:auto;
    width:100%; max-width:none; max-height:92vh;
    transform:translateY(100%); border-radius:24px 24px 0 0;
    border-left:0; border-right:0; border-bottom:0;
  }
  .modal.open{ transform:translateY(0); }
  .modal--sm{ width:100%; max-width:none; }
  .modal::before{
    content:''; position:absolute; top:9px; left:50%; transform:translateX(-50%);
    width:38px; height:4px; border-radius:4px; background:rgba(255,255,255,.18); z-index:7;
  }
  .x-btn--float{ top:18px; right:14px; }

  .co{ padding:26px 18px calc(24px + env(safe-area-inset-bottom)); }
  .co__title{ font-size:20px; margin-top:6px; }
  .co__step span{ display:none; }
  .co__steps{ gap:8px; }
  .pay-opts{ grid-template-columns:1fr; }
  .field-2{ grid-template-columns:1fr; }
  .crypto-box{ padding:16px; }
  .crypto-amt--big b{ font-size:20px; }
  .qr{ width:140px; height:140px; }
  .addr code{ font-size:10.5px; }

  .pv__side{ padding:24px 20px calc(24px + env(safe-area-inset-bottom)); }
  .pv__side h2{ font-size:21px; }
  .pv__buy .btn{ margin-left:0; width:100%; }
  .pv__specs{ grid-template-columns:1fr 1fr; }

  .success{ padding:36px 20px calc(32px + env(safe-area-inset-bottom)); }
  .success__btns .btn{ flex:1 1 100%; }

  /* En bas, les toasts masqueraient le bouton de paiement : on les remonte. */
  .toasts{ left:14px; right:14px; bottom:auto; top:calc(var(--nav-h) + 8px); }
  .toast{ max-width:none; }

  .footer{ padding-top:52px; }
  .footer__bot{ flex-direction:column; align-items:flex-start; gap:14px; }
}

/* ============================================================
   Téléphones et tablettes : allègement du rendu
   ------------------------------------------------------------
   Deux effets coûtent très cher sur un GPU de téléphone et sont
   recalculés en permanence :

     • backdrop-filter (le « verre dépoli ») — le navigateur doit
       relire et flouter ce qu'il y a derrière à chaque défilement ;
     • mix-blend-mode (le grain) — il force la page entière dans
       une couche de composition séparée.

   On les retire ici et on rend les fonds franchement opaques à la
   place : à l'œil la différence est invisible, mais le défilement
   redevient fluide.
   ============================================================ */
@media (max-width:1024px){
  /* Sur mobile le lien Discord est déjà dans le menu ☰ : ce bouton
     n'y tenait pas et se retrouvait coupé. */
  .nav__discord{ display:none; }

  .nav.scrolled, .mobile-menu, .code-badge, .card__vbadge, .card__preview,
  .scrim, .x-btn--float, .pv__play, .pv__soon, .toast, .tag{
    backdrop-filter:none; -webkit-backdrop-filter:none;
  }
  .nav.scrolled  { background:rgba(6,7,10,.95); }
  .mobile-menu   { background:rgba(6,7,10,1); }
  .scrim         { background:rgba(3,4,6,.88); }
  .card__vbadge  { background:rgba(48,16,31,.94); }
  .card__preview { background:rgba(6,7,10,.93); }
  .pv__play      { background:rgba(6,7,10,.95); }
  .pv__soon      { background:rgba(6,7,10,.93); }
  .x-btn--float  { background:rgba(8,10,16,.95); }
  .toast         { background:rgba(16,19,27,1); }

  /* Fonds animés : plus rien à repeindre pendant la lecture. */
  .orb{ animation:none; }
  .code-badge{ animation:none; }
  .noise{ display:none; }
}

@media (max-width:560px){
  .shop__tools{ flex-wrap:wrap; }
  .search{ flex:1 1 100%; }
  .sort{ flex:1 1 100%; }
  .nav__inner{ gap:12px; padding-inline:18px; }
  .nav__actions{ gap:8px; }
  .logo span{ font-size:16px; }

  /* Un halo de moins à peindre sur les petits écrans. */
  .orb--3{ display:none; }
}

@media (max-width:380px){
  .lang button{ padding:5px 7px; }
}

@media (hover:none){
  .card:hover{ transform:none; box-shadow:none; border-color:var(--line); }
  .card:hover .art{ transform:none; }
  .feat:hover, .review:hover{ transform:none; }
  .btn:hover{ transform:none; }
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }
  html{ scroll-behavior:auto; }
}

/* Monnaie non configurée */
.coin--off{ opacity:.4; cursor:not-allowed; filter:grayscale(1); }
.coin--off:hover{ border-color:var(--line); }

/* ============================================================
   Produits gratuits
   ============================================================ */
.tag--free{ background:rgba(52,229,160,.18); color:var(--green); border:1px solid rgba(52,229,160,.35); }
.chip--free.on{ background:linear-gradient(120deg,#34E5A0,#B4FF3A); }
.chip--free:not(.on){ color:var(--green); border-color:rgba(52,229,160,.3); }

.card--free:hover{ border-color:rgba(52,229,160,.45); box-shadow:0 0 0 1px rgba(52,229,160,.25), 0 20px 70px -25px rgba(52,229,160,.5); }
.price--free{ background:linear-gradient(120deg,#34E5A0,#B4FF3A); -webkit-background-clip:text; background-clip:text; color:transparent; font-size:20px; }

.add-btn--free{ background:linear-gradient(120deg,#34E5A0,#B4FF3A); box-shadow:0 8px 22px -10px rgba(52,229,160,.9); }
.add-btn--free:hover{ transform:translateY(-2px); box-shadow:0 12px 26px -10px rgba(52,229,160,.95); }
.add-btn.is-busy{ opacity:.6; pointer-events:none; }

/* ============================================================
   Avis — avatars Discord et étoiles partielles
   ============================================================ */
.review__av{ position:relative; overflow:hidden; }
.review__av--img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }

/* Photos de profil Discord dans les pastilles du hero. L'initiale et son
   dégradé restent dessous : si l'image ne charge pas, ils reprennent la main. */
.avatars span{ position:relative; overflow:hidden; }
.avatars img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.stars--off{ color:rgba(255,255,255,.16); }

/* ============================================================
   Commande par ticket Discord
   ============================================================ */
.success__ico--tk{ background:rgba(88,101,242,.16); border-color:rgba(88,101,242,.4); color:#8A94FF; }

.tk{ text-align:left; max-width:440px; margin:24px auto 4px; display:flex; flex-direction:column; gap:16px; }
.tk__step{ display:flex; gap:13px; align-items:flex-start; }
.tk__step i{
  width:26px; height:26px; flex-shrink:0; border-radius:9px; display:grid; place-items:center;
  background:rgba(88,101,242,.16); border:1px solid rgba(88,101,242,.35); color:#A8B0FF;
  font-family:'JetBrains Mono'; font-size:12.5px; font-weight:700; font-style:normal; margin-top:1px;
}
.tk__step > div{ flex:1; min-width:0; }
.tk__step span{ font-size:14px; color:var(--text-dim); line-height:1.6; }
.order-id--tk{ display:inline-flex; align-items:center; gap:8px; margin:10px 0 0; font-size:14px; }

/* Logo remplaçable */
.logo__mark--img{ background:none !important; box-shadow:none !important; overflow:hidden; }
.logo__mark--img img{ width:100%; height:100%; object-fit:contain; }

/* ============================================================
   Paiement carte / PayPal — articles sur la plateforme externe
   ============================================================ */
.sa{ display:flex; flex-direction:column; gap:9px; margin:14px 0 0; }
.sa__row{
  display:flex; align-items:center; gap:12px; padding:10px 12px; border-radius:var(--r);
  border:1px solid var(--line); background:rgba(255,255,255,.025); transition:border-color .2s;
}
.sa__row:hover{ border-color:var(--line-strong); }
.sa__row--off{ opacity:.55; }
.sa__art{ width:52px; height:36px; border-radius:8px; overflow:hidden; position:relative; flex-shrink:0; background:#0B0D13; }
.sa__info{ flex:1; min-width:0; }
.sa__info b{ display:block; font-size:13.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sa__info small{ color:var(--text-faint); font-size:12px; font-family:'JetBrains Mono'; }
.sa__row .btn{ flex-shrink:0; }

.sa__shop{
  display:inline-flex; align-items:center; gap:7px; margin-top:14px;
  font-size:12.5px; color:var(--text-faint); transition:color .2s;
}
.sa__shop:hover{ color:var(--violet-soft); }
.sa__shop svg{ width:13px; height:13px; }

@media (max-width:680px){
  .sa__row{ flex-wrap:wrap; }
  .sa__row .btn{ width:100%; }
}

/* ============================================================
   Achat d'un article — récapitulatif
   ============================================================ */
.co__prod{
  display:flex; align-items:center; gap:13px; padding:12px; margin-bottom:20px;
  border-radius:var(--r); border:1px solid var(--line); background:rgba(255,255,255,.025);
}
.co__prod-art{ width:64px; height:44px; border-radius:9px; overflow:hidden; position:relative; flex-shrink:0; background:#0B0D13; }
.co__prod-info{ flex:1; min-width:0; }
.co__prod-info b{ display:block; font-size:14px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.co__prod-info small{ display:block; color:var(--text-faint); font-size:11.5px; font-family:'JetBrains Mono'; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.co__prod-price{ font-family:'Sora'; font-weight:700; font-size:17px; white-space:nowrap; }
.co__rows{ margin:-8px 0 20px; }

/* Méthode de paiement : carte compacte, sans texte descriptif */
.pay-opt b{ font-family:'Sora'; font-size:15px; }
.pay-opt .badge{ top:9px; right:9px; }
/* ============================================================
   Animations & finitions — identité « code »
   ------------------------------------------------------------
   Tout ce qui suit est décoratif : si une animation ne démarre
   pas, la page reste parfaitement lisible et utilisable.

   Règle suivie partout : on n'anime que `transform` et `opacity`
   (le navigateur les traite sur le processeur graphique, sans
   recalculer la mise en page), et les effets coûteux sont
   réservés aux écrans larges avec une vraie souris.
   ============================================================ */

/* ---------- Barre de progression de lecture ---------- */
.progress{
  position:absolute; left:0; right:0; bottom:-1px; height:2px;
  background:transparent; pointer-events:none; overflow:hidden;
}
.progress i{
  display:block; height:100%; width:100%;
  background:var(--grad);
  transform:scaleX(var(--p, 0)); transform-origin:0 50%;
  box-shadow:0 0 12px rgba(124,92,255,.7);
}

/* ---------- Bloc de code : frappe ligne à ligne ---------- */
.code-card pre .ln{
  display:block; min-height:1.55em;
}
/* L'animation n'est armée qu'une fois le bloc à l'écran (classe posée par
   app.js), sinon elle se jouerait pendant que le visiteur regarde ailleurs. */
.code-card.typing pre .ln{
  opacity:0; transform:translateY(6px);
  animation:lnIn .34s var(--ease) forwards;
  animation-delay:calc(var(--i) * 55ms);
}
@keyframes lnIn{ to{ opacity:1; transform:none } }

/* Curseur clignotant, comme dans un éditeur */
.code-card pre::after{
  content:''; display:inline-block; vertical-align:text-bottom;
  width:7px; height:1.05em; margin-left:2px;
  background:var(--cyan); box-shadow:0 0 10px rgba(34,224,255,.8);
  animation:caret 1.05s steps(1) infinite;
}
@keyframes caret{ 0%,49%{ opacity:1 } 50%,100%{ opacity:0 } }

/* Balayage lumineux très discret sur l'encart de code */
.code-card{ position:relative; overflow:hidden; }
.code-card::after{
  content:''; position:absolute; inset:0; pointer-events:none; z-index:2;
  background:linear-gradient(180deg, transparent 0%, rgba(124,92,255,.09) 46%, transparent 92%);
  transform:translateY(-100%);
  animation:scan 7s linear infinite;
}
@keyframes scan{ 0%{ transform:translateY(-100%) } 60%,100%{ transform:translateY(120%) } }

/* ---------- Titres de section : décodage ---------- */
/* Pendant l'effet, les caractères de remplissage sont atténués pour qu'on
   distingue le texte qui se fixe de celui qui cherche encore. */
/* (l effet de décodage a été retiré : simple fondu + montée) */

/* ---------- Apparition en cascade ---------- */
/* Les enfants d'une grille arrivent l'un après l'autre plutôt qu'en bloc. */
.cascade > *{
  opacity:0; transform:translateY(18px);
  transition:opacity .6s var(--ease), transform .6s var(--ease);
}
.cascade.in > *{ opacity:1; transform:none; }
.cascade.in > *:nth-child(1){ transition-delay:0ms }
.cascade.in > *:nth-child(2){ transition-delay:70ms }
.cascade.in > *:nth-child(3){ transition-delay:140ms }
.cascade.in > *:nth-child(4){ transition-delay:210ms }
.cascade.in > *:nth-child(5){ transition-delay:280ms }
.cascade.in > *:nth-child(6){ transition-delay:350ms }
.cascade.in > *:nth-child(n+7){ transition-delay:420ms }

/* ---------- Bouton principal : anneau dégradé tournant ---------- */
@property --ang{ syntax:'<angle>'; initial-value:0deg; inherits:false; }

.btn--primary{ isolation:isolate; }
.btn--primary::before{
  content:''; position:absolute; inset:-1.5px; border-radius:inherit; z-index:-1;
  background:conic-gradient(from var(--ang), #7C5CFF, #22E0FF, #FF4D8D, #7C5CFF);
  animation:tourne 4.5s linear infinite;
  opacity:0; transition:opacity .3s;
}
.btn--primary:hover::before{ opacity:.95; }
@keyframes tourne{ to{ --ang:360deg } }

/* ---------- Cartes : lueur qui suit le curseur ---------- */
/* --mx / --my sont posées par app.js à chaque mouvement de souris. */
.card{ position:relative; }
.card__glow{
  position:absolute; inset:0; z-index:3; border-radius:inherit; pointer-events:none;
  opacity:0; transition:opacity .25s;
  background:radial-gradient(320px circle at var(--mx,50%) var(--my,50%),
             rgba(124,92,255,.16), transparent 62%);
}

/* Souris véritable et écran large uniquement : sur un écran tactile ces
   effets ne servent à rien et coûteraient cher. */
@media (hover:hover) and (pointer:fine) and (min-width:1025px){
  .card:hover .card__glow{ opacity:1; }
  .card{
    transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(var(--ty,0));
    transition:transform .35s var(--ease), box-shadow .35s var(--ease), border-color .3s;
  }
  .card:hover{ --ty:-4px; }
}

/* ---------- Réglage système « réduire les animations » ---------- */
/* Le bloc générique plus haut neutralise déjà les durées ; on remet ici les
   éléments concernés dans leur état final, sinon ils resteraient invisibles. */
@media (prefers-reduced-motion:reduce){
  .code-card.typing pre .ln{ opacity:1; transform:none; animation:none; }
  .code-card pre::after,
  .code-card::after{ display:none; }
  .cascade > *{ opacity:1; transform:none; }
  .btn--primary::before{ animation:none; }
  .progress i{ transition:none; }
}

/* ---------- Téléphones : on garde le décor, on retire le coûteux ---------- */
@media (max-width:1024px){
  .code-card::after{ display:none; }          /* balayage : repeint tout le bloc */
  .btn--primary::before{ display:none; }      /* dégradé conique animé */
  .card__glow{ display:none; }
}

/* ============================================================
   Bandeau des chiffres : les 4 cases sur la même ligne
   ------------------------------------------------------------
   « Instantanée » est un mot, pas un nombre : sa police est plus
   petite, donc sa ligne était moins haute et son libellé tombait
   plus bas que les trois autres. On fixe la hauteur de la zone
   du haut sur la plus grande des deux tailles, et tout s'aligne.
   ============================================================ */
.stat{
  display:flex; flex-direction:column; justify-content:center; align-items:center; gap:7px;
}
.stat b{
  display:flex; align-items:center; justify-content:center;
  min-height:calc(clamp(26px, 3.4vw, 34px) * 1.12);
  line-height:1.12; margin:0;
}
.stat > span{ line-height:1.3; }

/* ---------- « Instantanée » : une lumière traverse le mot ----------
   Pas de découpe en lettres : sur iOS, background-clip:text cesse de
   peindre dès qu on met des enfants inline-block dedans, et le mot
   devenait invisible. On fait plutôt glisser le dégradé lui-même. */
.stat--word{
  background-image:linear-gradient(100deg,
    #FFFFFF 0%, #C7C4FF 26%, #7CE9FF 42%, #FFFFFF 58%, #C7C4FF 74%, #7CE9FF 100%);
  background-size:260% 100%;
  animation:lueurMot 4.2s cubic-bezier(.5,0,.5,1) infinite;
}
@keyframes lueurMot{
  0%, 55%  { background-position:100% 50% }
  85%, 100%{ background-position:0% 50% }
}

/* ============================================================
   Les 4 étapes : une séquence qui se déroule au défilement
   ------------------------------------------------------------
   La ligne se trace de gauche à droite, et chaque numéro s'allume
   au moment où elle l'atteint — comme une progression qui se
   remplit. Rapide à dessein : 1,1 s du début à la fin.
   ============================================================ */

/* La ligne grise de fond reste ; celle-ci se dessine par-dessus. */
.steps::after{
  content:''; position:absolute; top:26px; left:8%; right:8%; height:1px;
  background:var(--grad);
  box-shadow:0 0 14px rgba(124,92,255,.55);
  transform:scaleX(0); transform-origin:0 50%;
  transition:transform 1.05s cubic-bezier(.45,0,.15,1);
}
.steps.in::after{ transform:scaleX(1); }
/* Empilées sur mobile : une ligne horizontale ne relierait rien. */
@media (max-width:1024px){ .steps::after{ display:none; } }

.steps .step{
  opacity:0; transform:translateY(16px);
  transition:opacity .38s var(--ease), transform .38s var(--ease);
}
.steps.in .step{ opacity:1; transform:none; }
.steps.in .step:nth-child(1){ transition-delay:.05s }
.steps.in .step:nth-child(2){ transition-delay:.29s }
.steps.in .step:nth-child(3){ transition-delay:.53s }
.steps.in .step:nth-child(4){ transition-delay:.77s }

/* Le numéro passe du gris au dégradé.
   Deux dégradés de même type et de même nombre d'étapes : la transition
   est fluide, là où gris → dégradé ne s'interpolerait pas du tout. */
.step__n{
  background:linear-gradient(120deg, var(--surface-2) 0%, var(--surface-2) 100%);
  transition:background-image .45s var(--ease), color .45s var(--ease),
             border-color .45s var(--ease), box-shadow .45s var(--ease),
             transform .35s var(--ease);
}
.steps.in .step__n{
  background-image:var(--grad);
  color:#08090C; border-color:transparent;
  box-shadow:0 12px 30px -14px rgba(124,92,255,.9);
  animation:pastille .5s var(--ease) both;
}
.steps.in .step:nth-child(1) .step__n{ transition-delay:.12s; animation-delay:.12s }
.steps.in .step:nth-child(2) .step__n{ transition-delay:.36s; animation-delay:.36s }
.steps.in .step:nth-child(3) .step__n{ transition-delay:.60s; animation-delay:.60s }
.steps.in .step:nth-child(4) .step__n{ transition-delay:.84s; animation-delay:.84s }

@keyframes pastille{
  0%  { transform:scale(1) }
  45% { transform:scale(1.16) }
  100%{ transform:scale(1) }
}

/* Petit halo qui s'échappe de la pastille au moment où elle s'allume. */
.step__n::after{
  content:''; position:absolute; inset:0; border-radius:inherit;
  border:1px solid var(--violet-soft); opacity:0; pointer-events:none;
}
.steps.in .step__n::after{ animation:halo .75s var(--ease) both; }
.steps.in .step:nth-child(1) .step__n::after{ animation-delay:.12s }
.steps.in .step:nth-child(2) .step__n::after{ animation-delay:.36s }
.steps.in .step:nth-child(3) .step__n::after{ animation-delay:.60s }
.steps.in .step:nth-child(4) .step__n::after{ animation-delay:.84s }

@keyframes halo{
  0%  { opacity:.9; transform:scale(1) }
  100%{ opacity:0;  transform:scale(1.75) }
}

/* Le survol garde la main une fois la séquence terminée. */
.step:hover .step__n{ transform:scale(1.08); }

@media (prefers-reduced-motion:reduce){
  .steps::after{ transform:scaleX(1); transition:none; }
  .steps .step{ opacity:1; transform:none; }
  .steps.in .step__n{ animation:none; }
  .steps.in .step__n::after{ animation:none; opacity:0; }
  .stat--word{ animation:none; }
}

/* ============================================================
   Trois moyens de paiement
   ============================================================ */
.pay-opts--3{ grid-template-columns:repeat(3, 1fr); }

/* En dessous de 560 px, trois colonnes deviennent illisibles :
   carte et PayPal côte à côte, crypto sur toute la largeur. */
@media (max-width:560px){
  .pay-opts--3{ grid-template-columns:1fr 1fr; }
  .pay-opts--3 .pay-opt:last-child{ grid-column:1 / -1; }
  .pay-opt{ padding:14px; }
}

/* Mention Apple Pay / Google Pay sous l'encadré carte. */
.co__wallets{
  margin:10px 2px 0; font-size:12.5px; color:var(--text-faint);
  font-family:'JetBrains Mono'; line-height:1.5;
}

/* ---------- Attente de la confirmation Stripe ---------- */
.success__ico--wait{
  background:rgba(124,92,255,.14); border-color:rgba(124,92,255,.35);
  position:relative;
}
.success__ico--wait::after{
  content:''; position:absolute; inset:0; border-radius:50%;
  border:2px solid transparent; border-top-color:var(--violet-soft);
  animation:spin .8s linear infinite;
}

/* ---------- Fichiers livrés après paiement ---------- */
.dl-list{ margin:22px 0 4px; text-align:left; }
.dl-list .co__h{ margin-bottom:10px; }
.dl-list .btn + .btn{ margin-top:10px; }

/* ============================================================
   Panier
   ============================================================ */
.cart-btn{
  position:relative; width:42px; height:42px; border-radius:11px;
  border:1px solid var(--line-strong); display:grid; place-items:center;
  color:var(--text); transition:.25s var(--ease); flex-shrink:0;
}
.cart-btn:hover{ background:rgba(255,255,255,.06); border-color:rgba(255,255,255,.25); }
.cart-btn svg{ width:19px; height:19px; }
.cart-btn em{
  position:absolute; top:-5px; right:-5px; min-width:19px; height:19px; padding:0 5px;
  border-radius:10px; background:var(--grad); color:#08090C;
  font-family:'Sora'; font-size:11px; font-weight:800; font-style:normal;
  display:grid; place-items:center; box-shadow:0 4px 12px -4px rgba(124,92,255,.9);
  animation:pop .35s var(--ease);
}

/* ---------- Tiroir ---------- */
.drawer{
  position:fixed; top:0; right:0; bottom:0; width:min(420px, 100%); z-index:960;
  background:var(--surface); border-left:1px solid var(--line);
  display:flex; flex-direction:column;
  transform:translateX(100%); transition:transform .4s var(--ease);
  visibility:hidden;
}
.drawer.open{ transform:none; visibility:visible; }

.drawer__head{
  display:flex; align-items:center; justify-content:space-between;
  padding:22px 22px 16px; border-bottom:1px solid var(--line); flex-shrink:0;
}
.drawer__head h3{ font-size:19px; }

.drawer__body{ flex:1; overflow-y:auto; padding:18px 22px; }
.drawer__foot{ padding:18px 22px calc(20px + env(safe-area-inset-bottom)); border-top:1px solid var(--line); flex-shrink:0; }

/* ---------- Une ligne du panier ---------- */
.citem{
  display:grid; grid-template-columns:64px 1fr auto; gap:13px; align-items:center;
  padding:13px 0; border-bottom:1px solid var(--line);
}
.citem:last-child{ border-bottom:0; }
.citem__art{ width:64px; height:48px; border-radius:10px; overflow:hidden; position:relative; }
.citem__art .art{ position:absolute; inset:0; }
.citem__info b{ display:block; font-family:'Sora'; font-size:14.5px; font-weight:600; line-height:1.3; }
.citem__info small{ color:var(--text-faint); font-size:12px; font-family:'JetBrains Mono'; }
.citem__right{ display:flex; flex-direction:column; align-items:flex-end; gap:6px; }
.citem__price{ font-family:'Sora'; font-weight:700; font-size:15px; white-space:nowrap; }
.citem__rm{
  width:26px; height:26px; border-radius:8px; display:grid; place-items:center;
  color:var(--text-faint); border:1px solid var(--line); transition:.2s;
}
.citem__rm:hover{ color:var(--pink); border-color:rgba(255,77,141,.4); background:rgba(255,77,141,.1); }
.citem__rm svg{ width:13px; height:13px; }

/* ---------- Panier vide ---------- */
.cart-empty{ text-align:center; padding:56px 10px; color:var(--text-faint); }
.cart-empty svg{ width:42px; height:42px; margin:0 auto 16px; opacity:.35; }
.cart-empty b{ display:block; color:var(--text-dim); font-family:'Sora'; font-size:15px; margin-bottom:6px; }
.cart-empty small{ font-size:13px; }

/* ---------- Code promo ---------- */
.promo-row{ display:flex; gap:8px; margin-bottom:14px; }
.promo-row input{
  flex:1; min-width:0; height:42px; padding:0 13px; border-radius:11px;
  border:1px solid var(--line); background:rgba(255,255,255,.03);
  font-size:14px; text-transform:uppercase; letter-spacing:.04em;
}
.promo-row input:focus{ outline:none; border-color:rgba(124,92,255,.5); background:rgba(124,92,255,.06); }
.promo-row button{
  height:42px; padding:0 16px; border-radius:11px; font-size:13.5px; font-weight:600;
  border:1px solid var(--line-strong); color:var(--text); transition:.2s; white-space:nowrap;
}
.promo-row button:hover{ background:rgba(255,255,255,.07); }

@media (max-width:560px){
  .drawer{ width:100%; }
  .cart-btn{ width:38px; height:38px; }
}


/* ---------- Systèmes gratuits : on demande l'adresse ---------- */
.free__sub{ color:var(--text-dim); font-size:14px; line-height:1.6; margin:-14px 0 20px; }
.free__field{ margin-top:2px; }
.free__go{ margin-top:4px; }
.free__go svg{ width:18px; height:18px; }

/* ============================================================
   Retouches — septembre 2026
   ------------------------------------------------------------
   Ce bloc vient après tout le reste, donc il gagne. On y trouve :
     1. le renvoi vers la boutique complète, et la page qui la porte
     2. le bouton « Partager » d'une fiche
     3. la barre du haut sur téléphone : menu et panier enfin visibles
     4. la croix du panier, qui ne se voyait plus du tout
     5. les étiquettes, allégées
   ============================================================ */

/* ------------------------------------------------------------
   1. « Voir tous les systèmes »
   ------------------------------------------------------------ */
.shop__more{
  display:flex; flex-direction:column; align-items:center; gap:10px;
  margin-top:38px;
}
/* Un display explicite annule l'attribut hidden : il faut le lui redire. */
.shop__more[hidden]{ display:none; }

/* Cartes en attente : la place est tenue, rien n'est annoncé. */
.card--attente{
  min-height:340px;
  background:rgba(255,255,255,.02);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  animation:attente 1.5s ease-in-out infinite;
  pointer-events:none;
}
@keyframes attente{ 0%,100%{ opacity:.45; } 50%{ opacity:.8; } }
@media (prefers-reduced-motion:reduce){ .card--attente{ animation:none; } }
.shop__all{
  display:inline-flex; align-items:center; gap:12px;
  padding-inline:30px;
  border-color:var(--line-strong);
  background:rgba(255,255,255,.03);
}
.shop__all svg{ width:17px; height:17px; transition:transform .3s var(--ease); }
.shop__all:hover svg{ transform:translateX(4px); }
.shop__rest{ font-size:12.5px; color:var(--text-faint); }

/* La page qui les montre tous */
.shop-page{ padding-top:calc(var(--nav-h) + 46px); }
.backlink{
  display:inline-flex; align-items:center; gap:9px; margin-bottom:26px;
  font-size:14px; color:var(--text-dim); transition:.2s;
}
.backlink:hover{ color:var(--text); }
.backlink:hover svg{ transform:translateX(-4px); }
.backlink svg{ width:17px; height:17px; transition:transform .25s var(--ease); }

/* ------------------------------------------------------------
   2. Partager une fiche
   ------------------------------------------------------------ */
.pv__share{
  display:inline-flex; align-items:center; gap:9px; margin-top:14px;
  padding:9px 0; font-size:13.5px; color:var(--text-faint);
  transition:color .2s;
}
.pv__share:hover{ color:var(--text); }
.pv__share svg{ width:15px; height:15px; }

/* ------------------------------------------------------------
   3. La barre du haut sur téléphone
   ------------------------------------------------------------
   Les deux boutons étaient collés au bord et se voyaient à peine.
   Ils sont maintenant plus grands, décollés du bord, cerclés d'un
   filet dégradé, et le menu s'ouvre avec deux barres qui se croisent
   en dépassant légèrement — c'est ce petit dépassement qui donne
   l'impression que le bouton répond au doigt.
   ------------------------------------------------------------ */
@media (max-width:1024px){
  /* env(safe-area-inset-*) : la page est en viewport-fit=cover, donc sans
     ça le bouton se retrouve sous le coin arrondi de l'écran. */
  .nav__inner{
    gap:14px;
    padding-left:calc(18px + env(safe-area-inset-left));
    padding-right:calc(18px + env(safe-area-inset-right));
  }
  .nav__actions{ gap:9px; }

  .burger, .cart-btn{
    width:46px; height:46px; border-radius:15px;
    border:1px solid transparent;
    background:
      linear-gradient(rgba(18,20,28,.92), rgba(18,20,28,.92)) padding-box,
      linear-gradient(135deg, rgba(124,92,255,.75), rgba(34,224,255,.75)) border-box;
    box-shadow:0 6px 22px -10px rgba(124,92,255,.75);
  }

  .burger{ display:grid; place-items:center; position:relative; }

  /* Deux barres suffisent : trois font « gabarit ». */
  .burger span{
    width:19px; height:2.4px; border-radius:3px; background:var(--text);
    transition:transform .42s cubic-bezier(.62,-0.3,.3,1.4), opacity .18s;
  }
  .burger span:nth-child(2){ display:none; }
  .burger span:nth-child(1){ margin-bottom:3px; }
  .burger span+span{ margin-top:3px; }
  .burger.open span:nth-child(1){ transform:translateY(4.2px) rotate(45deg); }
  .burger.open span:nth-child(3){ transform:translateY(-4.2px) rotate(-45deg); }

  /* Un halo qui bat deux fois au chargement : l'œil le trouve tout seul,
     puis on le laisse tranquille. */
  .burger::after{
    content:''; position:absolute; inset:-3px; border-radius:18px;
    border:1.5px solid rgba(124,92,255,.55);
    opacity:0; pointer-events:none;
    animation:halo-menu 2.4s var(--ease) .9s 2;
  }
  .burger.open::after{ animation:none; opacity:0; }

  .cart-btn svg{ width:21px; height:21px; }
  .cart-btn em{
    top:-6px; right:-6px; min-width:21px; height:21px; font-size:11.5px;
    border:2px solid #0B0D14;
    box-shadow:0 4px 14px -3px rgba(124,92,255,1);
  }
}

@keyframes halo-menu{
  0%   { opacity:0;   transform:scale(.9); }
  18%  { opacity:.95; transform:scale(1); }
  55%  { opacity:0;   transform:scale(1.28); }
  100% { opacity:0;   transform:scale(1.28); }
}

@media (max-width:560px){
  .nav__inner{
    padding-left:calc(16px + env(safe-area-inset-left));
    padding-right:calc(16px + env(safe-area-inset-right));
  }
  .cart-btn{ width:46px; height:46px; }
  .lang{ padding:2px; }
  .lang button{ padding:5px 7px; font-size:11px; }
}

/* Très petits écrans : le sélecteur de langue passe dans le menu,
   pour que le menu et le panier gardent leur place. La règle de base vient
   AVANT la requête média — sinon elle la recouvrirait. */
.mobile-menu .lang{ display:none; }
@media (max-width:400px){
  .nav__actions .lang{ display:none; }
  .mobile-menu .lang{ display:flex; align-self:flex-start; margin-top:18px; }
}

/* ------------------------------------------------------------
   4. La croix du panier
   ------------------------------------------------------------
   Le bouton était vide : aucune icône dedans, donc rien à voir.
   Il est maintenant rouge, rond et franc.
   ------------------------------------------------------------ */
.drawer__head .x-btn{
  width:40px; height:40px; border-radius:50%;
  background:rgba(255,77,141,.14);
  border:1px solid rgba(255,77,141,.45);
  color:#FF6B9D;
}
.drawer__head .x-btn:hover{
  background:rgba(255,77,141,.24);
  border-color:rgba(255,77,141,.7);
  color:#fff;
}
.drawer__head .x-btn svg{ width:17px; height:17px; stroke-width:2.6; }

@media (max-width:560px){
  .drawer__head{
    padding:18px calc(18px + env(safe-area-inset-right)) 14px calc(18px + env(safe-area-inset-left));
  }
  .drawer__head .x-btn{ width:44px; height:44px; }
  .drawer__head .x-btn svg{ width:19px; height:19px; }
}

/* ------------------------------------------------------------
   5. Étiquettes et petites capitales
   ------------------------------------------------------------
   Les pastilles en monospace majuscule sur fond fluo, partout,
   c'est la signature des gabarits. On garde la couleur là où elle
   informe (gratuit, promo) et on calme le reste.
   ------------------------------------------------------------ */
.tag{
  font-family:'Inter', sans-serif;
  text-transform:none;
  letter-spacing:0;
  font-size:11.5px;
  font-weight:600;
  padding:4px 10px;
  border-radius:8px;
}
.tag--cat{
  background:rgba(10,12,18,.72);
  color:var(--text-dim);
  border:1px solid rgba(255,255,255,.14);
}
.tag--new{ background:rgba(52,229,160,.14); color:var(--green); border-color:rgba(52,229,160,.28); }
.tag--hot{ background:rgba(255,77,141,.14); color:var(--pink); border-color:rgba(255,77,141,.28); }
.tag--sale{ background:rgba(255,176,32,.15); color:var(--amber); border-color:rgba(255,176,32,.3); }
.tag--free{ background:rgba(52,229,160,.16); color:var(--green); border-color:rgba(52,229,160,.34); }

.card__vbadge{
  font-family:'Inter', sans-serif; text-transform:none; letter-spacing:0;
  font-size:11.5px; font-weight:600; padding:4px 10px; border-radius:8px;
  background:rgba(10,12,18,.72); color:var(--text-dim);
  border:1px solid rgba(255,255,255,.14);
}
.card__vbadge svg{ width:11px; height:11px; }

/* Les libellés des compteurs : lisibles plutôt que « techniques ». */
.stat > span{
  font-family:'Inter', sans-serif;
  text-transform:none;
  letter-spacing:0;
  font-size:13px;
  color:var(--text-faint);
}

/* Les filtres de la boutique */
.chip em{ font-family:'Inter', sans-serif; font-size:12px; }

/* Le sous-titre du logo reste en monospace : c'est une signature,
   pas une étiquette — mais il respire un peu plus. */
.logo em{ letter-spacing:.16em; }

/* ============================================================
   Effets — septembre 2026
     1. la lueur : sur le titre, et une seule qui traverse les chiffres
     2. les cartes de la boutique s'inclinent sous la souris
     3. les étapes avancent avec le défilement, et reculent aussi
   ============================================================ */

/* ------------------------------------------------------------
   1. La lueur
   ------------------------------------------------------------ */

/* La lueur quitte le dernier chiffre — elle est passée sur le titre — mais
   il garde le dégradé du site, comme les trois autres. */
.stat--word{
  animation:none;
  background-image:var(--grad-text);
  background-size:100% 100%;
  background-position:0 0;
}

/* Elle passe sur le titre du site. Deux lignes, un léger décalage entre
   elles : on lit une seule vague qui traverse la phrase, pas deux effets.
   On fait glisser le dégradé lui-même — appliquer background-clip:text à un
   élément qui contient d'autres balises casse l'affichage sur iPhone. */
/* Deux couches superposées, toutes deux découpées sur le texte :
     • dessous, la couleur du site, fixe ;
     • dessus, une bande blanche qui traverse.
   C'est donc la lueur qui est blanche, et le titre garde sa couleur. */
.hero h1 .line{
  background-image:
    linear-gradient(100deg, transparent 42%, rgba(255,255,255,.98) 50%, transparent 58%),
    linear-gradient(120deg, #C9C4FF 0%, #A78BFF 32%, #7CE9FF 68%, #C9C4FF 100%);
  background-size:280% 100%, 100% 100%;
  background-position:130% 0, 0 0;
  background-repeat:no-repeat;
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; color:transparent;
  animation:lueurTitre 6.5s cubic-bezier(.55,0,.45,1) infinite;
}
.hero h1 .line:nth-child(2){ animation-delay:.18s; }

@keyframes lueurTitre{
  0%, 12%   { background-position:130% 0, 0 0; }
  48%, 100% { background-position:-30% 0, 0 0; }
}

/* Une seule lueur traverse toute la rangée de chiffres, de « 450+ »
   jusqu'à « En 2 minutes ». C'est la rangée entière qui la porte, pas
   chaque case : le regard suit une bande unique qui balaie la ligne. */
.stats{ position:relative; overflow:hidden; }
.stats::after{
  content:''; position:absolute; inset:0; pointer-events:none; z-index:4;
  background:linear-gradient(105deg,
    transparent 42%,
    rgba(199,196,255,.16) 47%,
    rgba(124,233,255,.30) 50%,
    rgba(199,196,255,.16) 53%,
    transparent 58%);
  background-size:250% 100%;
  background-position:100% 0;
  animation:lueurRangee 6.5s cubic-bezier(.55,0,.45,1) infinite;
  mix-blend-mode:screen;
}
@keyframes lueurRangee{
  0%, 12%   { background-position:130% 0; }
  48%, 100% { background-position:-30% 0; }
}

@media (prefers-reduced-motion:reduce){
  .hero h1 .line{ animation:none; background-position:-30% 0, 0 0; }
  .stats::after{ animation:none; opacity:0; }
}

/* ------------------------------------------------------------
   2. Les cartes de la boutique en volume
   ------------------------------------------------------------
   Au repos elles sont plates. Dès que la souris entre, la carte
   s'incline vers elle et l'image se décolle légèrement : c'est ce
   décalage entre les deux plans qui donne le relief.
   ------------------------------------------------------------ */
@media (hover:hover) and (pointer:fine) and (min-width:1025px){
  .grid{ perspective:1100px; }

  .card{
    transform-style:preserve-3d;
    transform:
      perspective(1100px)
      rotateX(var(--rx,0deg))
      rotateY(var(--ry,0deg))
      translateY(var(--ty,0))
      scale(var(--sc,1));
    transition:transform .55s var(--ease), box-shadow .4s, border-color .3s;
  }

  /* Pendant que la souris se déplace, la carte doit coller au doigt :
     aucune transition, sinon elle traîne derrière. */
  .card.card--suivi{ transition:box-shadow .4s, border-color .3s; }
  .card:hover{ --ty:-6px; --sc:1.012; z-index:2; }

  /* Les plans intérieurs se décalent : c'est là que naît le volume. */
  .card__media{ transform:translateZ(26px); transition:transform .55s var(--ease); }
  .card--suivi .card__media{ transition:none; }
  .card__tags, .card__vbadge{ transform:translateZ(42px); }
  .card__body{ transform:translateZ(14px); transition:transform .55s var(--ease); }
  .card--suivi .card__body{ transition:none; }
  .card__foot{ transform:translateZ(10px); }

  /* Un reflet qui suit la souris, comme sur une surface vernie. */
  .card__glow{
    background:
      radial-gradient(340px circle at var(--mx,50%) var(--my,50%),
        rgba(124,92,255,.20), transparent 60%),
      linear-gradient(var(--refl,120deg),
        transparent 40%, rgba(255,255,255,.055) 50%, transparent 60%);
  }
  .card:hover .card__glow{ opacity:1; }
}

/* ------------------------------------------------------------
   3. Les étapes suivent le défilement
   ------------------------------------------------------------
   Chaque étape a son avancement propre, de 0 à 1, calculé à partir
   de la position du bloc dans la fenêtre. Aucune transition : la
   valeur EST la position du doigt sur la molette. On remonte, tout
   revient en arrière, exactement au même endroit.
   ------------------------------------------------------------ */
.steps{ --avance:0; }

.steps.defilement::after{
  transform:scaleX(var(--avance,0));
  transition:none;
}
.steps.defilement .step{
  --e:0;
  opacity:calc(.18 + var(--e) * .82);
  transform:translateY(calc((1 - var(--e)) * 22px));
  transition:none;
}
/* Les délais d'origine n'ont plus lieu d'être : c'est le défilement
   qui décide, plus une file d'attente. */
.steps.defilement .step,
.steps.defilement .step__n{ transition-delay:0s !important; }

.steps.defilement .step__n{
  background:transparent;
  border-color:transparent;
  isolation:isolate;
  animation:none;
  box-shadow:0 12px 30px -16px rgba(124,92,255,calc(var(--e) * .9));
  color:var(--text);
  color:color-mix(in srgb, #08090C calc(var(--e) * 100%), var(--text));
  transition:color .25s linear;
}
.steps.defilement .step__n::before{
  content:''; position:absolute; inset:0; border-radius:inherit; z-index:-1;
  background:var(--surface-2);
  box-shadow:inset 0 0 0 1px var(--line-strong);
}
.steps.defilement .step__n::after{
  content:''; position:absolute; inset:0; border-radius:inherit; z-index:-1;
  background:var(--grad);
  opacity:var(--e);
}

/* Un halo bref au moment précis où l'étape s'allume. */
.steps.defilement .step.on .step__n{
  box-shadow:0 12px 34px -14px rgba(124,92,255,.95);
}

/* Le trait qui relie les étapes n'existe qu'en ligne : empilées sur
   téléphone, chaque étape avance pour elle-même. */
@media (max-width:1024px){
  .steps.defilement .step{ transform:translateY(calc((1 - var(--e)) * 14px)); }
}

@media (prefers-reduced-motion:reduce){
  .steps.defilement .step{ opacity:1; transform:none; }
  .steps::after{ transform:scaleX(1); }
  .steps.defilement .step__n::after{ opacity:1; }
}

/* ============================================================
   Les étapes, en vertical
   ------------------------------------------------------------
   Une colonne, un trait qui descend, et chaque étape qui s'allume
   au passage. Le trait est le fil du texte : on le suit de haut en
   bas comme on lit. C'est aussi ce qui marche sur téléphone sans
   rien changer, là où quatre colonnes ne tenaient pas.
   ============================================================ */
.steps{
  display:block;
  max-width:820px;
  margin-inline:auto;
  padding-left:0;
  position:relative;
}

/* Le rail, et la part déjà parcourue. Tous deux verticaux. */
.steps::before,
.steps.defilement::after{
  content:'';
  position:absolute;
  left:31px; top:14px; bottom:14px;
  width:3px; height:auto; right:auto;
  border-radius:3px;
  transform:none;
}
.steps::before{
  background:linear-gradient(180deg, transparent, var(--line-strong) 8%, var(--line-strong) 92%, transparent);
}
.steps.defilement::after{
  background:linear-gradient(180deg, #7C5CFF, #22E0FF);
  box-shadow:0 0 20px rgba(124,92,255,.55);
  transform-origin:50% 0;
  transform:scaleY(var(--avance,0));
  transition:none;
}

.steps .step{
  display:grid;
  grid-template-columns:64px 1fr;
  grid-template-areas:
    "pastille titre"
    "pastille texte";
  column-gap:26px;
  row-gap:6px;
  text-align:left;
  padding:26px 0;
  align-items:start;
}
.steps .step:first-child{ padding-top:0; }
.steps .step:last-child{ padding-bottom:0; }

.steps .step__n{
  grid-area:pastille;
  width:64px; height:64px; margin:0;
  border-radius:20px;
  font-size:23px;
}
.steps .step h4{
  grid-area:titre;
  font-size:20px; line-height:1.25; margin:0;
  padding-top:16px;
}
.steps .step p{
  grid-area:texte;
  font-size:15px; line-height:1.68; margin:0;
  max-width:56ch;
}

/* Le trait de liaison de l'ancienne mise en page horizontale n'a plus
   lieu d'être : il traversait le titre. */
@media (max-width:1024px){
  .steps::before, .steps.defilement::after{ display:block; }
}

@media (max-width:560px){
  .steps .step{ grid-template-columns:52px 1fr; column-gap:18px; padding:20px 0; }
  .steps .step__n{ width:52px; height:52px; border-radius:16px; font-size:19px; }
  .steps .step h4{ font-size:17.5px; padding-top:12px; }
  .steps .step p{ font-size:14.5px; }
  .steps::before, .steps.defilement::after{ left:25px; }
}

/* Chaque étape glisse depuis la gauche, dans le sens de la lecture. */
.steps.defilement .step{
  transform:translateX(calc((1 - var(--e,0)) * 26px));
}
@media (max-width:560px){
  .steps.defilement .step{ transform:translateX(calc((1 - var(--e,0)) * 14px)); }
}

/* ============================================================
   Immersion — ce qui se révèle au fil du défilement
   ------------------------------------------------------------
   Le principe repris des vitrines de marque : rien n'apparaît d'un
   coup. Chaque bloc entre lentement pendant qu'on descend, et
   ressort si l'on remonte. La valeur --vue va de 0 à 1 et vient
   directement de la position du bloc dans la fenêtre.
   ============================================================ */
[data-immersion]{
  opacity:calc(.25 + var(--vue,1) * .75);
  transform:translateY(calc((1 - var(--vue,1)) * 34px));
  will-change:transform, opacity;
}

/* Les titres de section montent un peu plus : c'est eux qu'on voit venir. */
.sec-head[data-immersion]{
  transform:translateY(calc((1 - var(--vue,1)) * 46px));
}

/* Le visuel de l'accueil se déplace plus lentement que le texte à côté :
   ce décalage suffit à donner de la profondeur. */
.hero__visual[data-parallaxe]{
  transform:translateY(calc(var(--defile,0) * -42px));
  will-change:transform;
}

/* Le fond réagit lui aussi, très légèrement. */
.orb--1{ transform:translate3d(0, calc(var(--defileGlobal,0) * -60px), 0); }
.orb--2{ transform:translate3d(0, calc(var(--defileGlobal,0) *  40px), 0); }

@media (prefers-reduced-motion:reduce){
  [data-immersion], .sec-head[data-immersion]{ opacity:1; transform:none; }
  .hero__visual[data-parallaxe]{ transform:none; }
  .orb--1, .orb--2{ transform:none; }
}

/* ============================================================
   Corrections — les quatre points relevés
     1. les pastilles des étapes : lisibles, et devant le trait
     2. la lueur passe dès le chargement
     3. les couleurs du titre respirent
     4. l'inclinaison des cartes s'applique VRAIMENT au survol
   ============================================================ */

/* ------------------------------------------------------------
   1. Les étapes
   ------------------------------------------------------------
   Le trait passait devant les pastilles : un ::after de .steps se
   peint après tout le contenu. On ordonne donc explicitement les
   plans. Et la pastille redevient un simple bloc sombre dont le
   dégradé monte dans le fond — plus de pseudo-éléments empilés en
   z-index négatif, c'est là que le chiffre se perdait.
   ------------------------------------------------------------ */
.steps{ position:relative; z-index:0; }
.steps::before{ z-index:0; }
.steps.defilement::after{ z-index:1; }
.steps .step{ position:relative; z-index:2; }

/* La pastille : fond sombre constant, dégradé qui monte par-dessus,
   chiffre toujours lisible. Deux couches de fond sur l'élément
   lui-même : le texte se peint forcément au-dessus. */
.steps.defilement .step__n{
  background-image:
    linear-gradient(125deg, rgba(124,92,255,var(--e,0)), rgba(34,224,255,var(--e,0))),
    linear-gradient(180deg, #171B26, #10131C);
  background-color:transparent;
  border:1px solid rgba(255,255,255,.10);
  color:rgba(255,255,255,calc(.5 + var(--e,0) * .5));
  isolation:auto;
  box-shadow:0 10px 30px -18px rgba(124,92,255,calc(var(--e,0) * .95));
  transition:color .2s linear, border-color .2s linear;
}
/* Le liseré s'allume avec l'étape. */
.steps.defilement .step.on .step__n{ border-color:rgba(124,92,255,.55); }

/* Les deux pseudo-éléments de la version précédente n'ont plus lieu d'être :
   c'est eux qui cachaient le chiffre. */
.steps.defilement .step__n::before,
.steps.defilement .step__n::after{ content:none; }

/* Le trait s'arrête au centre des pastilles du haut et du bas, au lieu de
   dépasser dans le vide. */
.steps::before,
.steps.defilement::after{ top:32px; bottom:32px; }
@media (max-width:560px){
  .steps::before,
  .steps.defilement::after{ top:26px; bottom:26px; }
}

/* ------------------------------------------------------------
   2 et 3. Le titre : la lueur passe tout de suite,
   et la couleur respire
   ------------------------------------------------------------
   Deux effets indépendants, sur deux propriétés différentes :
     • background-position fait passer la bande blanche ;
     • un léger décalage de teinte fait respirer la couleur.
   Les mêler dans une seule série d'images-clés obligerait la bande
   à revenir en arrière à chaque tour.
   ------------------------------------------------------------ */
.hero h1 .line{
  background-image:
    linear-gradient(100deg, transparent 42%, rgba(255,255,255,.98) 50%, transparent 58%),
    linear-gradient(120deg, #E4E0FF 0%, #A78BFF 26%, #7CE9FF 52%, #A78BFF 78%, #E4E0FF 100%);
  background-size:280% 100%, 100% 100%;
  background-position:130% 0, 0 0;
  animation:
    lueurTitre 7s cubic-bezier(.55,0,.45,1) infinite,
    respireTitre 11s ease-in-out infinite alternate;
}
/* La bande part dès la première seconde, puis laisse respirer. */
@keyframes lueurTitre{
  0%   { background-position:130% 0, 0 0; }
  34%  { background-position:-30% 0, 0 0; }
  100% { background-position:-30% 0, 0 0; }
}
/* La couleur glisse lentement d'un bout du cercle chromatique à l'autre.
   Douze degrés : on le sent, on ne le voit pas travailler. */
@keyframes respireTitre{
  from{ filter:hue-rotate(-10deg) saturate(1); }
  to  { filter:hue-rotate(14deg)  saturate(1.12); }
}

.hero h1 .line:nth-child(2){ animation-delay:.22s, -3s; }

/* La rangée de chiffres part elle aussi tout de suite. */
@keyframes lueurRangee{
  0%   { background-position:130% 0; }
  34%  { background-position:-30% 0; }
  100% { background-position:-30% 0; }
}
.stats::after{ animation-duration:7s; }

/* ------------------------------------------------------------
   4. Les cartes : le survol doit porter l'inclinaison
   ------------------------------------------------------------
   .card:hover{ transform:translateY(-6px) } plus haut dans la
   feuille a une précision supérieure à .card — et la précision
   l'emporte sur l'ordre. Au survol, c'est donc lui qui gagnait et
   l'inclinaison était jetée. Or c'est justement au survol qu'elle
   sert. On redéclare donc l'état survolé ici, au complet.
   ------------------------------------------------------------ */
@media (hover:hover) and (pointer:fine) and (min-width:1025px){
  .grid{ perspective:900px; perspective-origin:50% 40%; }

  /* La perspective vient de la grille : les cartes voisines partagent
     alors le même point de fuite, comme des objets dans une même scène. */
  .card{
    transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
    transition:transform .5s var(--ease), box-shadow .4s, border-color .3s;
  }

  .card:hover{
    transform:
      rotateX(var(--rx,0deg))
      rotateY(var(--ry,0deg))
      translateY(-10px)
      scale(1.025);
    border-color:rgba(124,92,255,.45);
    /* L'ombre se décale à l'opposé de l'inclinaison : c'est elle qui pose
       la carte dans l'espace. */
    /* Les décalages viennent tout faits du script : diviser des degrés
       pour en tirer des pixels n'est pas permis en calc(). */
    box-shadow:
      var(--ox,0px)
      calc(var(--oy,0px) + 26px)
      58px -18px rgba(0,0,0,.85),
      0 0 0 1px rgba(124,92,255,.22),
      0 24px 70px -30px rgba(124,92,255,.75);
  }

  /* Pendant que la souris bouge, plus aucune transition : la carte suit
     le doigt. Elle ne revient en douceur qu'au moment de la quitter. */
  .card.card--suivi,
  .card.card--suivi:hover{ transition:box-shadow .25s, border-color .3s; }

  /* L'image accompagne le mouvement, très légèrement. */
  .card:hover .art{ transform:scale(1.08); }

  .card__glow{
    background:
      radial-gradient(360px circle at var(--mx,50%) var(--my,50%),
        rgba(255,255,255,.10), transparent 55%),
      radial-gradient(420px circle at var(--mx,50%) var(--my,50%),
        rgba(124,92,255,.22), transparent 62%);
  }
  .card:hover .card__glow{ opacity:1; }
}

/* ============================================================
   Les couleurs vivent
   ------------------------------------------------------------
   Le décalage de teinte était trop timide pour se voir. On fait
   maintenant GLISSER le dégradé lui-même à travers le texte : les
   couleurs traversent les lettres, lentement, en aller-retour —
   donc sans jamais sauter en fin de cycle.

   Une difficulté : la bande blanche du titre glisse elle aussi par
   background-position, et deux animations ne peuvent pas se
   partager la même propriété. La bande passe donc sur une copie du
   texte posée par-dessus (::after), et l'élément garde ses couleurs
   pour lui seul. Chacun son plan, chacun son animation.
   ============================================================ */

/* ------------------------------------------------------------
   Le titre : les couleurs traversent, la bande blanche par-dessus
   ------------------------------------------------------------ */
.hero h1 .line{
  position:relative;
  background-image:
    linear-gradient(115deg,
      #E9E5FF 0%, #A78BFF 18%, #7CE9FF 36%, #C9B8FF 54%,
      #7CE9FF 72%, #A78BFF 88%, #E9E5FF 100%);
  background-size:260% 100%;
  background-position:0% 50%;
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; color:transparent;
  /* aller-retour : la fin rejoint le début, il n'y a jamais de saut */
  animation:couleursQuiGlissent 15s ease-in-out infinite alternate;
  filter:none;
}

/* La copie du texte qui porte la lueur. Elle se superpose au caractère
   près : même police, même graisse, même interlignage. */
.hero h1 .line::after{
  content:attr(data-texte);
  position:absolute; inset:0;
  pointer-events:none;
  background-image:linear-gradient(100deg,
    transparent 42%, rgba(255,255,255,.98) 50%, transparent 58%);
  background-size:280% 100%;
  background-position:130% 0;
  background-repeat:no-repeat;
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; color:transparent;
  animation:lueurTitre 7s cubic-bezier(.55,0,.45,1) infinite;
}
/* La bande n'est plus portée par l'élément : ses images-clés à deux
   couches ne s'appliquent qu'à la copie, qui n'en a qu'une. */
@keyframes lueurTitre{
  0%   { background-position:130% 0; }
  34%  { background-position:-30% 0; }
  100% { background-position:-30% 0; }
}

.hero h1 .line:nth-child(2){ animation-delay:-5s; }
.hero h1 .line:nth-child(2)::after{ animation-delay:.22s; }

@keyframes couleursQuiGlissent{
  from{ background-position:0% 50%; }
  to  { background-position:100% 50%; }
}

/* ------------------------------------------------------------
   Les chiffres : mêmes couleurs qui glissent, rien d'autre
   ------------------------------------------------------------
   Seul le texte bouge ; le cadre et les libellés ne changent pas.
   ------------------------------------------------------------ */
.stat b.grad-text,
.stat b.stat--word{
  background-image:linear-gradient(115deg,
    #FFFFFF 0%, #C7C4FF 22%, #7CE9FF 44%, #C7C4FF 66%, #FFFFFF 88%, #C7C4FF 100%);
  background-size:260% 100%;
  background-position:0% 50%;
  -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; color:transparent;
  animation:couleursQuiGlissent 15s ease-in-out infinite alternate;
}
/* Chacun démarre à un moment différent : la rangée respire, elle ne
   clignote pas d'un seul bloc. */
.stats .stat:nth-child(1) b{ animation-delay:0s; }
.stats .stat:nth-child(2) b{ animation-delay:-3.7s; }
.stats .stat:nth-child(3) b{ animation-delay:-7.4s; }
.stats .stat:nth-child(4) b{ animation-delay:-11.1s; }

@media (prefers-reduced-motion:reduce){
  .hero h1 .line,
  .hero h1 .line::after,
  .stat b.grad-text,
  .stat b.stat--word{ animation:none; background-position:0% 50%; }
  .hero h1 .line::after{ opacity:0; }
}
