/* notus.css — single design-system stylesheet for the redesign.
   Source: _design/site-complet.html (visual reference), plus the editorial,
   legal, order-page and consent-banner blocks retyped onto the same tokens.
   One token per line in :root by design (R1) — lets a duplicate token show
   up as two hits instead of silently overriding. */

/* ───────── 0. Fonts (self-hosted — no request ever leaves for Google) ───────── */
@font-face{
  font-family:'Inter'; font-style:normal; font-weight:400; font-display:swap;
  src:url("/assets/fonts/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfAZ9hiJ-Ek-_EeA.woff2") format("woff2");
}
@font-face{
  font-family:'Inter'; font-style:normal; font-weight:500; font-display:swap;
  src:url("/assets/fonts/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuI6fAZ9hiJ-Ek-_EeA.woff2") format("woff2");
}
@font-face{
  font-family:'Inter'; font-style:normal; font-weight:600; font-display:swap;
  src:url("/assets/fonts/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuGKYAZ9hiJ-Ek-_EeA.woff2") format("woff2");
}
@font-face{
  font-family:'Inter Tight'; font-style:normal; font-weight:400; font-display:swap;
  src:url("/assets/fonts/NGSnv5HMAFg6IuGlBNMjxJEL2VmU3NS7Z2mjDw-aWy5SgqoUP_C5.woff2") format("woff2");
}
@font-face{
  font-family:'Inter Tight'; font-style:normal; font-weight:500; font-display:swap;
  src:url("/assets/fonts/NGSnv5HMAFg6IuGlBNMjxJEL2VmU3NS7Z2mjPQ-aWy5SgqoUP_C5.woff2") format("woff2");
}
@font-face{
  font-family:'Inter Tight'; font-style:normal; font-weight:600; font-display:swap;
  src:url("/assets/fonts/NGSnv5HMAFg6IuGlBNMjxJEL2VmU3NS7Z2mj0QiaWy5SgqoUP_C5.woff2") format("woff2");
}
@font-face{
  font-family:'Inter Tight'; font-style:normal; font-weight:700; font-display:swap;
  src:url("/assets/fonts/NGSnv5HMAFg6IuGlBNMjxJEL2VmU3NS7Z2mj6AiaWy5SgqoUP_C5.woff2") format("woff2");
}

/* ───────── 1. Tokens ───────── */
:root{
  --paper:#F2EEE7;
  --paper-2:#ECE7DE;
  --ink:#111111;
  --ink-strong:#000000;
  --ink-soft:#2A2724;
  --muted:#6B6660;
  --muted-2:#8E8881;
  --line:#D6D3CD;
  --line-soft:#E3DFD6;
  --card:#FBF8F2;
  --card-2:#E9E4DA;
  --ok:#2F6B4F;
  --ok-bg:#E0EBE4;
  --warn:#8A5514;
  --warn-bg:#F2E8D9;
  --mark:#DCD5C6;
  --on-dark:#FFFFFF;
  --on-dark-dim:#A8A29A;
  --on-dark-soft:#D6D2CB;
  --dark-line:#2C2926;
  --disp:'Inter Tight',system-ui,sans-serif;
  --sans:'Inter',system-ui,sans-serif;
  --measure:780px;
  --r-card:16px;
  --r-panel:24px;
  --r-btn:12px;
  --shadow-md:0 10px 30px -18px rgba(17,17,17,.18), 0 2px 6px rgba(17,17,17,.04);
}

/* ───────── 2. Reset & base ───────── */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:16px;
  line-height:1.55;-webkit-font-smoothing:antialiased;letter-spacing:-.006em}
img{max-width:100%;display:block}
[hidden]{display:none!important}
a{color:inherit;text-decoration:none}
.wrap{max-width:1080px;margin:0 auto;padding:0 clamp(18px,4vw,32px)}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:4px}
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto} }

/* ───────── 3. Nav ───────── */
.nav{position:fixed;top:0;left:0;right:0;z-index:50;padding:14px clamp(16px,4vw,32px);display:flex;align-items:center;gap:12px}
.pill{border:1px solid var(--line);background:rgba(251,248,242,.9);backdrop-filter:blur(12px);border-radius:999px;display:flex;align-items:center}
.pill.logo{padding:9px 18px;font-family:var(--disp);font-weight:600;font-size:15px;letter-spacing:-.01em}
.pill.menu{margin:0 auto;padding:5px 6px;gap:2px}
.pill.menu a{display:flex;align-items:center;gap:7px;padding:7px 13px;border-radius:999px;font-size:13.5px;color:var(--muted);font-weight:500}
.pill.menu a:hover{background:var(--card-2);color:var(--ink)}
.pill.menu svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:1.6}
.lang{display:flex;align-items:center;gap:4px;padding:0 10px;font-size:12px;color:var(--muted-2)}
.lang b{color:var(--ink);font-weight:600}
.lang a{padding:0}
.cta-pill{background:var(--ink);color:var(--on-dark);border-radius:999px;padding:11px 20px;font-size:13.5px;font-weight:500;white-space:nowrap;transition:opacity .25s ease}
.cta-pill:hover{background:var(--ink-strong)}

/* ───────── 4. Hero ───────── */
/* 118svh : le hero reste sticky (100svh) pendant que les 18svh de surplus
   font defiler la rotation du boitier (notus3d.js:mountHeroDiagram). Le
   fondu du titre/CTA est repousse a s=.9+ pour que ce surplus ne soit jamais
   une zone morte, et `inert` retire le CTA du clic/focus une fois invisible.
   Le vol vers #how prend ensuite le relai sans temps mort (meme fonction de
   progression, cf. releaseY/arriveY dans le JS) : pas besoin d'un gros
   surplus ici pour "occuper" le scroll, la descente s'en charge. */
.heroScroll{position:relative;height:118svh}
.hero{position:sticky;top:0;height:100svh;min-height:560px;overflow:hidden;
  display:grid;place-items:center;background:var(--paper-2)}
.markw{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  font-family:var(--disp);font-weight:700;white-space:nowrap;line-height:.8;
  font-size:clamp(150px,34vw,560px);letter-spacing:-.05em;color:var(--mark);
  user-select:none;pointer-events:none;z-index:0;will-change:transform,opacity}
#v3d{position:absolute;inset:0;z-index:1}
#v3d canvas{display:block;width:100%;height:100%}
.fallback{position:absolute;z-index:1;height:46vh;filter:drop-shadow(0 30px 50px rgba(17,17,17,.28))}
/* .copy et .cue vivent HORS de .hero (voir markup) et passent en
   position:fixed, pas absolute, une fois .hero3d confirme (pose par
   mountHeroDiagram() elle-meme, cf. notus3d.js) : .hero est sticky, ce qui
   lui cree — meme sans z-index — son propre contexte d'empilement.
   z-index:45 pose dessus n'aurait alors jamais pu depasser le canvas
   flottant du boitier (notus3d.js, ajoute au body, z-index:40) : un enfant
   ne sort jamais du contexte d'empilement de son parent, quel que soit son
   z-index local. En sortant .copy/.cue de .hero, ils entrent en
   concurrence de z-index directement au niveau racine avec ce canvas et le
   dominent enfin. Le calage bottom/left/right reste identique : .hero,
   sticky top:0 100svh, coincide avec le viewport pendant toute la duree ou
   .copy est visible (le fondu JS le fait disparaitre avant qu'il ne se
   decolle du haut).
   Le fixed est conditionne a .hero3d, PAS a .js (cf. index.html) : .js est
   pose par un script inline qui reussit toujours des lors que JS tourne,
   meme si ce module-ci echoue a charger/parser derriere — auquel cas
   mountHeroDiagram() ne s'executerait jamais et rien ne remettrait .copy
   dans un etat sur. .hero3d n'est ajoutee que depuis l'interieur de la
   fonction elle-meme, une fois qu'on est sur qu'elle ira au moins jusqu'a
   staticHeroFallback(). */
.copy{padding:0 clamp(16px,4vw,32px);display:flex;align-items:flex-end;justify-content:space-between;
  gap:22px;flex-wrap:wrap;will-change:transform,opacity}
.hero3d .copy{position:fixed;z-index:45;left:0;right:0;bottom:clamp(34px,7vh,68px)}
.copy h1{font-family:var(--disp);font-weight:600;font-size:clamp(23px,2.6vw,36px);
  line-height:1.08;letter-spacing:-.03em;max-width:13ch}
/* Les deux chiffres (100% / 0) en vis-a-vis plutot qu'en phrase continue : ce
   qui les rend comparables d'un coup d'œil, comme deux stats de fiche
   produit, plutot que la deuxieme noyee en fin de paragraphe. */
.copy h1.stats{max-width:none;display:flex;flex-direction:column;gap:9px}
.copy .stat{display:block;font-weight:500;font-size:clamp(19px,2.6vw,26px);
  color:var(--muted);letter-spacing:-.01em}
.copy .stat b{display:block;font-family:var(--disp);font-weight:600;color:var(--ink);
  font-size:clamp(30px,4.2vw,52px);letter-spacing:-.03em;line-height:1.05}
.copy p{color:var(--muted);font-size:14.5px;max-width:38ch;margin-top:9px}
.copy .note{font-size:12.5px;color:var(--muted-2);margin-top:8px}
.cue{display:flex;align-items:center;gap:9px;
  font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2)}
.hero3d .cue{position:fixed;z-index:45;left:50%;bottom:12px;transform:translateX(-50%)}
.cue svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:1.7}

/* ───────── 5. Sections ───────── */
h2{font-family:var(--disp);font-weight:600;font-size:clamp(30px,4.2vw,44px);line-height:1.08;letter-spacing:-.032em}
.sec{padding:clamp(56px,8vw,104px) 0}
.sec.tight{padding-top:0}
.sec[id],[id].heroScroll{scroll-margin-top:88px}
.head{margin-bottom:clamp(26px,4vw,40px)}
.head p{color:var(--muted);font-size:16px;max-width:56ch;margin-top:12px;line-height:1.6}
/* Trois boites de confiance, en repere sur l'appareil (#how) : fond + bordure,
   volontairement plus affirmees qu'une simple liste — elles portent seules
   tout ce que la page dit sur la facilite d'usage et la confidentialite,
   depuis la fusion avec l'ancienne section "L'objet". Leur position (le trait
   qui pointe vers le boitier) est definie par .diagram .note, plus bas. */
.card{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);
  padding:clamp(18px,2.2vw,22px)}
.card h3{font-family:var(--disp);font-weight:600;font-size:16.5px;letter-spacing:-.02em;margin-bottom:8px}
.card p{color:var(--muted);font-size:13.5px;line-height:1.55}
.final{background:var(--ink);border-radius:var(--r-panel);padding:clamp(26px,4vw,40px);
  display:flex;align-items:center;justify-content:space-between;gap:26px;flex-wrap:wrap;color:var(--on-dark)}
.final h3{font-family:var(--disp);font-weight:600;font-size:clamp(21px,2.6vw,27px);letter-spacing:-.025em}
.final p{color:var(--on-dark-dim);font-size:14.5px;margin-top:6px}
.final .b{display:flex;gap:10px;flex-wrap:wrap}
.final .btn{background:var(--on-dark);color:var(--ink);border-color:var(--on-dark)}
.final .btn.ghost{background:transparent;color:var(--on-dark);border-color:var(--dark-line)}

/* ───────── 5b. Reveal au scroll (JS ajoute .in, cf. site.js) ───────── */
/* Fondu + leger glissement pour tout [data-reveal] : titres de section,
   cartes, plans. --stagger echelonne l'apparition d'un cran (pose en style
   inline sur les elements concernes ; .plans le derive de nth-child puisque
   ses seuls enfants sont des .plan). Scope a .js (cf. index.html, tout premier
   script du <head>) : si le JS ne s'execute jamais (bloque, coupe, module en
   echec), rien ne viendra jamais ajouter .in, et [data-reveal] resterait a
   opacity:0 pour de bon. Sans .js, la regle ne s'applique pas du tout : le
   contenu est visible par defaut, le reveal est une amelioration qui s'ajoute
   plutot qu'un etat dont on espere sortir. */
.js [data-reveal]{transition:opacity .6s ease,transform .6s ease;transition-delay:calc(var(--stagger,0) * .1s)}
.js [data-reveal]:not(.in){opacity:0;transform:translateY(16px)}
.plans [data-reveal]:nth-child(1){--stagger:0}
.plans [data-reveal]:nth-child(2){--stagger:1}
.plans [data-reveal]:nth-child(3){--stagger:2}
@media(prefers-reduced-motion:reduce){ .js [data-reveal]:not(.in){opacity:1;transform:none} }

/* ───────── 6. Boutons ───────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;background:var(--ink);color:var(--on-dark);
  border:1px solid var(--ink);border-radius:var(--r-btn);padding:14px 24px;font-size:15px;font-weight:500;
  cursor:pointer;font-family:var(--sans);white-space:nowrap}
.btn:hover{background:var(--ink-strong)}
.btn.light{background:var(--card);color:var(--ink);border-color:var(--line)}
.btn.light:hover{background:var(--card-2)}
.btn.block{width:100%;padding:16px}

/* ───────── 7. Commande ───────── */
.order{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.order .visual{background:var(--card-2);border:1px solid var(--line-soft);border-radius:var(--r-card);
  display:grid;place-items:center;padding:36px;min-height:440px;--fig:clamp(280px,32vw,400px)}
.order .visual .dev{height:var(--fig);width:auto;filter:drop-shadow(0 24px 40px rgba(17,17,17,.22))}
/* Ratio par defaut identique a celui de la vitrine #how : corrige a la vraie
   proportion du modele une fois charge (notus3d.js:mountOrderShowcase). */
.order .visual .dev3d{height:var(--fig);aspect-ratio:298/898;filter:drop-shadow(0 24px 40px rgba(17,17,17,.22))}
.order .visual .dev3d canvas{display:block;width:100%;height:100%}
.conf{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);padding:22px}
.prod{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  border:1px solid var(--line);border-radius:var(--r-btn);background:var(--paper);padding:15px 16px;margin-bottom:20px}
.prod .t{font-weight:600;font-size:15px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.prod .ed{font-size:10.5px;font-weight:500;padding:3px 9px;border-radius:999px;background:var(--ink);color:var(--on-dark)}
.prod .s{font-size:12.5px;color:var(--muted-2);margin-top:4px}
.prod .pr{font-family:var(--disp);font-weight:600;font-size:22px;letter-spacing:-.025em;white-space:nowrap}
.prod .was{font-size:13px;font-weight:400;color:var(--muted-2);text-decoration:line-through;margin-right:7px}
.qrow{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:20px}
.qrow .lbl{font-weight:500;font-size:14.5px}
.qrow .hint{font-size:12.5px;color:var(--muted-2);margin-top:2px}
.step{display:flex;align-items:center;border:1px solid var(--line);border-radius:999px;background:var(--paper)}
.step button{width:34px;height:34px;border:none;background:none;cursor:pointer;font-size:16px;color:var(--ink);line-height:1}
.step button:disabled{color:var(--line);cursor:not-allowed}
.step span{width:34px;text-align:center;font-size:14.5px;font-weight:500}
.lines{border-top:1px solid var(--line-soft);padding-top:14px}
.li{display:flex;justify-content:space-between;font-size:14px;padding:5px 0;color:var(--ink-soft)}
.li.dep{margin:-8px 0 16px}
.notes{margin:14px 0}
.notes .note{display:flex;align-items:flex-start;gap:9px;font-size:13px;color:var(--muted);padding:7px 0}
.notes .note b{color:var(--ink);font-weight:500}
.notes .note .ic{flex:0 0 auto;width:14px;text-align:center;color:var(--ink)}
.totrow{display:flex;align-items:baseline;justify-content:space-between;border-top:1px solid var(--line-soft);padding-top:16px;margin-bottom:16px}
.totrow .k{font-size:14.5px;color:var(--muted)}
.totrow .v{font-family:var(--disp);font-weight:600;font-size:34px;letter-spacing:-.03em}
/* site.js insere le message d'erreur de /api/checkout avec cette classe. */
.fineprint{font-size:13px;line-height:1.5;color:var(--muted);margin-top:12px}
.ship{text-align:center;font-size:12.5px;color:var(--muted-2);margin-top:12px}
.ship.refund{color:var(--muted);font-weight:500;margin-top:14px}

/* ───────── 7b. Grilles de contenu (chain, plans, FAQ) ───────── */

.chain{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);padding:8px 22px}
.chain .r,.chain .src{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:17px 0;border-bottom:1px solid var(--line-soft)}
.chain .r:last-child{border-bottom:none}
.chain .l{display:flex;align-items:center;gap:11px;font-weight:500;font-size:15px}
.chain .l i{width:26px;height:26px;border-radius:7px;background:var(--ink);display:grid;place-items:center;
  color:var(--on-dark);font-size:10px;font-weight:600;flex:0 0 auto;font-style:normal}
.chain .v{color:var(--muted);font-size:14px;text-align:right}
.chain .t{font-size:12px;color:var(--muted-2)}

/* Bandeau materiel : rend "l'objet une fois" concret par une photo plutot que
   par la seule mention "inclus avec l'objet" glissee dans la carte Free — sans
   lui, la section ne montre que des abonnements, jamais le boitier lui-meme. */
.hw-strip{display:flex;align-items:center;gap:20px;background:var(--card);border:1px solid var(--line-soft);
  border-radius:var(--r-card);padding:16px 22px;margin-bottom:20px;flex-wrap:wrap}
.hw-strip img{height:56px;width:auto;flex:0 0 auto}
.hw-strip .hw-info{flex:1 1 220px}
.hw-strip b{display:block;font-family:var(--disp);font-weight:600;font-size:15px;margin-bottom:3px}
.hw-strip span{display:block;font-size:13.5px;color:var(--muted);line-height:1.5}
/* Prix et reduction remontes ici : c'est le seul endroit ou le boitier lui-meme
   (par opposition a l'abonnement) a un prix affiche, autant y mettre le -20%
   en avant plutot que de le laisser seulement dans la section #order. */
.hw-strip .hw-price{font-family:var(--disp);font-weight:600;font-size:19px;letter-spacing:-.02em;
  white-space:nowrap;flex:0 0 auto}
.hw-strip .hw-price small{font-family:var(--sans);font-weight:500;font-size:12px;color:var(--muted-2);letter-spacing:0}
.hw-strip .hw-price .was{font-size:14px;font-weight:400;color:var(--muted-2);text-decoration:line-through;margin-right:5px}
.hw-strip .btn{flex:0 0 auto;padding:11px 20px;font-size:13.5px}

.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.plan{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);padding:24px 22px}
.plan.on{background:var(--ink);border-color:var(--ink);color:var(--on-dark)}
.plan .badge{display:inline-block;font-size:10.5px;padding:3px 9px;border-radius:999px;background:var(--paper);color:var(--ink);margin-bottom:14px;font-weight:500}
.plan h3{font-family:var(--disp);font-weight:600;font-size:19px;letter-spacing:-.02em}
.plan .p{font-family:var(--disp);font-weight:600;font-size:34px;letter-spacing:-.03em;margin:8px 0 2px}
.plan .p small{font-size:14px;font-weight:400;color:var(--muted-2);letter-spacing:0}
.plan.on .p small{color:var(--on-dark-dim)}
.plan .d{font-size:13.5px;color:var(--muted);margin-bottom:16px;min-height:38px}
.plan.on .d{color:var(--on-dark-dim)}
.plan ul{list-style:none;border-top:1px solid var(--line-soft);padding-top:14px}
.plan.on ul{border-color:var(--dark-line)}
.plan li{font-size:13.5px;padding:5px 0;display:flex;gap:9px;color:var(--ink-soft)}
.plan.on li{color:var(--on-dark-soft)}
.plan li::before{content:'•';color:var(--muted-2)}

.faq{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);overflow:hidden}
.faq details{border-bottom:1px solid var(--line-soft)}
.faq details:last-child{border-bottom:none}
.faq summary{list-style:none;cursor:pointer;padding:18px 22px;display:flex;justify-content:space-between;
  align-items:center;gap:18px;font-size:15px;font-weight:500}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:'+';color:var(--muted-2);font-size:17px;flex:0 0 auto}
.faq details[open] summary::after{content:'×'}
.faq .a{padding:0 22px 20px;color:var(--muted);font-size:14.5px;line-height:1.65;max-width:74ch}

/* Le champ quantité reste un vrai champ soumis et validé par le navigateur :
   le stepper n'est que sa façade visible. Jamais type="hidden" — cela
   désactiverait la validation de contrainte. */
.vis-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ───────── 7c. L'équipe derrière Notus ───────── */
.founders{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.founder{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);
  padding:clamp(24px,3.4vw,32px);display:flex;flex-direction:column;
  transition:transform .2s ease, box-shadow .2s ease}
.founder:hover{transform:translateY(-2px);box-shadow:var(--shadow-md)}
.founder .portrait{width:clamp(112px,13vw,148px);aspect-ratio:1;border-radius:50%;
  background:var(--ink);border:1px solid var(--ink);display:grid;place-items:center;
  overflow:hidden;margin-bottom:20px;flex:0 0 auto}
.founder .portrait img{width:100%;height:100%;object-fit:cover}
.founder h3{font-family:var(--disp);font-weight:600;font-size:20px;letter-spacing:-.02em}
.founder .role{font-size:12.5px;color:var(--muted-2);margin-top:4px}
.founder .bio{color:var(--muted);font-size:14.5px;line-height:1.65;margin-top:14px;max-width:46ch}
.founder .flink{margin-top:auto;padding-top:20px;font-size:13px;color:var(--muted);
  display:inline-flex;align-items:center;gap:7px;align-self:flex-start}
.founder .flink svg{width:14px;height:14px;fill:currentColor}
.founder .flink:hover{color:var(--ink)}

/* Le recit d'origine, apres les deux cartes : colonne etroite, respiration large. */
.origin{max-width:68ch;margin:clamp(36px,5vw,56px) auto 0;
  padding-top:clamp(30px,4vw,44px);border-top:1px solid var(--line-soft)}
.origin p{color:var(--muted);font-size:15px;line-height:1.75}
.origin p + p{margin-top:14px}
.origin .lead{font-family:var(--disp);font-weight:600;font-size:clamp(22px,2.8vw,29px);
  line-height:1.2;letter-spacing:-.025em;color:var(--ink)}
.origin .lead + p{margin-top:18px}
.origin .close{color:var(--ink);font-weight:500}

/* ───────── 7d. Vitrine du boitier (#how) ───────── */
/* Pas de carte bordee : l'objet flotte directement sur le papier de la page,
   comme dans le hero — une bordure + un fond distinct l'auraient fait lire
   comme un widget encadre plutot que comme la suite du meme objet qui vient
   de s'y poser. */
.diagram{padding:clamp(8px,2vw,20px) 0 clamp(20px,3.5vw,40px);
  --fig:clamp(360px,50vw,560px)}
/* Invariant : le boitier fait exactement la hauteur du .stage — d'ou la
   variable partagee plutot qu'un height:100%, qui ne resout pas sur un
   element de grille centre (align-items != stretch). */
.diagram .stage{position:relative;height:var(--fig);display:grid;place-items:center}
.diagram .dev{height:var(--fig);width:auto;filter:drop-shadow(0 22px 38px rgba(17,17,17,.22))}
/* Le ratio (298x898, celui de la photo remplacee) n'est qu'un defaut : JS le
   corrige a la vraie proportion du modele une fois charge (notus3d.js). */
.diagram .dev3d{height:var(--fig);aspect-ratio:298/898;filter:drop-shadow(0 22px 38px rgba(17,17,17,.22))}
.diagram .dev3d canvas{display:block;width:100%;height:100%}

/* Reperes : une boite de confiance par cote, reliee au boitier par un trait
   fin plutot qu'empilees dessous — l'idee du premier jet (bouton/ecran/micro
   annotes) mais avec les 3 arguments de confiance a la place du texte nu.
   Les trois positions (--y) sont celles, deja calibrees, du premier schema. */
/* --lead doit depasser la demi-largeur reelle du boitier (~.195 * --fig, vu
   sa proportion 0.39 une fois charge, cf. notus3d.js) sans quoi le boitier
   deborde par dessus le trait — verifie a chaque breakpoint plutot que repris
   tel quel de l'ancien schema, plus etroit (photo a 0.33, --fig plus petit).
   --gap va plus loin : le trait et le repere s'arretent avant d'atteindre le
   boitier (au lieu de venir mourir pile sur son bord), pour ne jamais sembler
   poses direct sur l'objet. */
.diagram .note{position:absolute;top:var(--y);transform:translateY(-50%);
  width:min(460px,40%);--lead:clamp(64px,13vw,168px);--gap:calc(var(--fig) * .2 + 14px);z-index:41}
.diagram .note.l{right:50%;padding-right:var(--lead)}
.diagram .note.r{left:50%;padding-left:var(--lead)}
/* Le trait s'arrete a --gap du centre (pas directement sur le boitier) et
   s'estompe vers la boite plutot qu'un trait plat, pour que l'œil le lise
   du repere vers l'objet. Ton sombre (et non --line, trop clair) : c'etait
   le premier retour, le trait etait quasi invisible. */
.diagram .note::after{content:'';position:absolute;top:50%;height:1.5px;
  width:calc(var(--lead) - var(--gap))}
.diagram .note.l::after{right:var(--gap);background:linear-gradient(to left,var(--ink-soft),transparent)}
.diagram .note.r::after{left:var(--gap);background:linear-gradient(to right,var(--ink-soft),transparent)}
.diagram .note::before{content:'';position:absolute;top:50%;width:6px;height:6px;border-radius:50%;
  background:var(--ink-soft);box-shadow:0 0 0 4px var(--paper);z-index:1}
.diagram .note.l::before{right:var(--gap);transform:translate(50%,-50%)}
.diagram .note.r::before{left:var(--gap);transform:translate(-50%,-50%)}
/* Coordonnees relevees sur notus-device.png (298x898) */
.diagram .n-btn{--y:22.4%}
.diagram .n-scr{--y:54%}
.diagram .n-mic{--y:86.2%}

@media(max-width:760px){
  .diagram{--fig:clamp(260px,62vw,360px)}
}
@media(max-width:900px){
  .diagram .stage{height:auto;display:block;padding-bottom:8px}
  .diagram .dev,.diagram .dev3d{margin:0 auto 28px}
  /* Specificite egale a .note.l/.note.r (2 classes) : sans repeter .l/.r ici,
     ces regles plus specifiques gagneraient et l'empilement mobile ne
     s'appliquerait jamais. */
  .diagram .note.l,.diagram .note.r{position:relative;top:auto;left:auto;right:auto;
    transform:none;width:auto;padding:0;margin-top:16px}
  .diagram .note::after,.diagram .note::before{display:none}
}

/* ───────── 7e. Pied de page ───────── */
footer{padding:44px 0 34px;border-top:1px solid var(--line-soft);margin-top:clamp(48px,7vw,88px)}
.fgrid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:26px}
.fgrid h5{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted-2);margin-bottom:12px;font-weight:500}
.fgrid a{display:block;font-size:13.5px;color:var(--muted);padding:4px 0}
.fgrid a:hover{color:var(--ink)}
.fgrid .brand{font-family:var(--disp);font-weight:600;font-size:19px;margin-bottom:10px}
.fgrid .brand + p{font-size:13.5px;color:var(--muted);max-width:34ch}
.fbot{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-top:34px;
  padding-top:20px;border-top:1px solid var(--line-soft);font-size:12.5px;color:var(--muted-2)}

/* ───────── 8. Éditorial (ex content.css, retypé sur Inter) ───────── */
.article{max-width:var(--measure);padding:clamp(40px,7vw,72px) 0 96px}
.eyebrow{
  font-size:12px;font-weight:500;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted-2);margin:0 0 14px;
}
.title{
  font-family:var(--disp);font-weight:600;font-size:clamp(36px,6vw,58px);
  line-height:1.05;letter-spacing:-.02em;margin:0 0 18px;text-wrap:balance;
}
.updated{font-size:14px;color:var(--muted-2);margin:0 0 6px}
.byline{font-size:14px;color:var(--muted);margin:0 0 32px}
.article h2{
  font-family:var(--disp);font-weight:600;font-size:clamp(26px,3.6vw,34px);
  line-height:1.18;letter-spacing:-.015em;margin:52px 0 14px;text-wrap:balance;
}
.article h3{font-size:18px;font-weight:600;margin:32px 0 8px;letter-spacing:-.01em}
.article p{margin:0 0 16px;color:var(--ink-soft)}
.article ul,.article ol{margin:0 0 16px;padding-left:22px;color:var(--ink-soft)}
.article li{margin-bottom:7px}
.article strong{font-weight:600}
.lede{font-family:var(--disp);font-size:21px;line-height:1.35;margin-bottom:12px;color:var(--ink)}
/* Simple editorial chrome (article/comparatif pages) — deliberately distinct
   from the landing page's .nav pill header/.fgrid footer: an article doesn't
   need the same chrome as a sales page. Ported from content.css. */
header.site{border-bottom:1px solid var(--line-soft);padding:20px 0}
header.site .row,footer.site .row{
  max-width:var(--measure);margin:0 auto;padding:0 clamp(18px,4vw,32px);
  display:flex;align-items:center;gap:20px;
}
header.site .row{justify-content:space-between}
header.site .logo{font-family:var(--disp);font-weight:600;font-size:18px;letter-spacing:-.01em;color:var(--ink)}
header.site .logo .dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--ink);margin-left:2px}
.back{font-size:14px;color:var(--muted)}
.back:hover{color:var(--ink)}
footer.site{border-top:1px solid var(--line-soft);padding:28px 0 40px;margin-top:64px}
footer.site .row{flex-wrap:wrap;gap:10px 22px;justify-content:space-between;font-size:13.5px;color:var(--muted-2)}
footer.site a{color:var(--muted)}
footer.site a:hover{color:var(--ink);text-decoration:underline}
/* Data tables (article + comparatif) and the "qui choisir" grid. */
.scroll{overflow-x:auto;margin:22px 0;border:1px solid var(--line);border-radius:var(--r-btn)}
table{border-collapse:collapse;width:100%;font-size:14.5px;background:var(--card)}
th,td{padding:11px 15px;text-align:left;border-bottom:1px solid var(--line-soft);vertical-align:top}
th{
  font-size:11px;font-weight:500;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted-2);white-space:nowrap;
}
tr:last-child td{border-bottom:none}
td.num{font-variant-numeric:tabular-nums;white-space:nowrap}
caption{caption-side:bottom;font-size:13px;color:var(--muted-2);padding:10px 15px;text-align:left}
.choose{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin:24px 0}
.choose>div{background:var(--card);border:1px solid var(--line);border-radius:var(--r-btn);padding:18px 20px}
.choose h3{margin:0 0 8px;font-size:16px}
.choose ul{margin:0;padding-left:20px;font-size:15px;color:var(--ink-soft)}
.disclosure{
  background:var(--warn-bg);border-radius:var(--r-card);
  padding:14px 18px;margin:0 0 32px;font-size:14.5px;color:var(--ink-soft);
}
.disclosure strong{color:var(--ink)}
.verdict{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  padding:22px 24px;margin:28px 0;
}
.verdict h2,.verdict h3{margin-top:0}
.verdict p:last-child{margin-bottom:0}
.source{font-size:13.5px;color:var(--muted-2);margin:-8px 0 22px}
.cta{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  padding:26px 28px;margin:44px 0 0;text-align:center;
}
.cta p{margin:0 0 16px;color:var(--ink-soft)}
.crumbs{display:flex;gap:6px;flex-wrap:wrap;font-size:13px;color:var(--muted-2);margin:0 0 24px}
.article .crumbs a{color:var(--muted);text-decoration:none}
.crumbs a:hover{color:var(--ink);text-decoration:underline}
.posts{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px}
.post{background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);padding:22px;display:flex;flex-direction:column;gap:8px}
.post .eyebrow{margin:0}
.post h2{font-family:var(--disp);font-weight:600;font-size:18px;letter-spacing:-.02em;margin:0}
.post time{font-size:13px;color:var(--muted-2)}
.post a.more{font-size:14.5px;font-weight:500;color:var(--ink)}
.post p{color:var(--muted);font-size:14.5px;line-height:1.55;margin:0}

@media (max-width:560px){
  header.site .row{gap:12px}
}

/* ───────── 9. Légal (ex legal.css, mêmes tokens) ───────── */
/* .legal n'avait pas de max-width propre : sans ce token elle retombe sur
   .wrap (1080px) alors que header.site/footer.site sont contraints à
   --measure (780px) depuis la tâche 6 — chrome plus étroit que le corps. */
.legal{max-width:var(--measure)}
main.legal{padding-top:clamp(60px,8vw,96px);padding-bottom:clamp(80px,10vw,140px)}
.legal article h2{
  font-family:var(--disp);font-weight:600;font-size:clamp(24px,2.6vw,30px);
  line-height:1.15;letter-spacing:-.015em;margin:56px 0 10px;text-wrap:balance;
}
.legal article h2 .num{color:var(--muted);font-style:italic;margin-right:10px}
.legal article p{margin:0 0 14px;color:var(--ink-soft)}
.legal article ul,.legal article ol{margin:0 0 18px;padding-left:22px;color:var(--ink-soft)}
.legal article li{margin-bottom:6px}
.legal article strong{color:var(--ink);font-weight:500}
.legal .toc{
  background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);
  padding:24px 28px;margin-bottom:40px;
}
.legal .toc h4{
  font-family:var(--sans);font-weight:500;font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted);margin:0 0 12px;
}
.legal .toc ol{margin:0;padding-left:22px;font-size:14.5px;color:var(--ink-soft);display:flex;flex-direction:column;gap:4px}
.legal .toc a{text-decoration:none}
.legal .toc a:hover{text-decoration:underline}
.legal article dl{
  display:grid;grid-template-columns:1fr 2fr;gap:12px 24px;margin:18px 0 24px;
  font-size:14.5px;border-top:1px solid var(--line-soft);padding-top:16px;
}
.legal article dt{color:var(--muted);font-size:13px;letter-spacing:.04em}
.legal article dd{margin:0;color:var(--ink-soft)}
.legal .callout{
  background:var(--card);border:1px solid var(--line-soft);border-radius:var(--r-card);
  padding:20px 22px;margin:22px 0;font-size:14.5px;color:var(--ink-soft);
}
.legal .callout strong{display:block;margin-bottom:4px;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:500}
/* Dropped in the legal.css/content.css merge: footer.site .links (legal.css:210)
   was how the 3–4 footer links on legal pages visually separated — no " · " glyph
   like the blog/comparatif footers, so without this they run together. */
footer.site .links{display:flex;gap:22px;flex-wrap:wrap}
/* Also dropped: both legal.css and content.css defaulted `a` to underlined
   (only .btn/.crumbs/.toc/footer.site a opted out). notus.css's base reset
   (§2) is underline:none, so inline prose links in article bodies lost their
   only visual affordance. Scoped to p/li/dd descendants so .btn/.crumbs/.toc/
   footer.site a — none of which sit inside a p/li/dd — are unaffected. */
.article p a,.article li a,.legal article p a,.legal article li a,.legal article dd a{
  text-decoration:underline;text-underline-offset:2px;text-decoration-color:var(--line);
}
.article p a:hover,.article li a:hover,.legal article p a:hover,.legal article li a:hover,.legal article dd a:hover{
  text-decoration-color:var(--muted);
}
@media (max-width:540px){
  .legal article dl{grid-template-columns:1fr;gap:4px 0}
  .legal article dt{margin-top:10px}
}

/* ───────── 10. Pages de commande (ex orderPage() inline style) ───────── */
.order-body{padding:64px 24px}
.order-wrap{max-width:640px;margin:0 auto;text-align:center}
.order-wrap h1{font-family:var(--disp);font-weight:600;font-size:40px;margin:0 0 16px}
.order-wrap p{color:var(--muted);font-size:17px;line-height:1.6}

/* ───────── 11. Admin (waitlist, orders, login) ───────── */
.admin-body{padding:48px}
.admin-wrap{max-width:900px;margin:0 auto}
.admin-wrap.orders{max-width:1000px}
.admin-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:32px}
.admin-head h1{font-family:var(--disp);font-size:40px;margin:0}
.admin-wrap table{width:100%;border-collapse:collapse;font-size:14px;background:var(--card);
  border:1px solid var(--line-soft);border-radius:var(--r-card);overflow:hidden}
.admin-wrap th,.admin-wrap td{text-align:left;padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.admin-wrap th{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)}
.admin-wrap tr:last-child td{border-bottom:none}
.admin-wrap td .sub{font-size:12px;color:var(--muted);margin-top:2px}
.admin-wrap td .sub.biz{color:var(--ink-soft)}
.admin-actions{display:flex;gap:14px;align-items:center}
.admin-tabs{display:flex;gap:6px;margin:0 0 24px}
.admin-tabs a{padding:9px 18px;border-radius:999px;font-size:13px;font-weight:500;color:var(--muted);text-decoration:none;border:1px solid transparent;transition:color .2s,background .2s,border-color .2s}
.admin-tabs a:hover{color:var(--ink)}
.admin-tabs a.active{color:var(--ink);background:var(--card);border-color:var(--line-soft)}
/* .btn already renders the filled/ink treatment; .btn-primary is an explicit
   alias for markup ported from styles.css, where .btn was treatment-neutral. */
.btn-primary{background:var(--ink);color:var(--on-dark);border-color:var(--ink)}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn-ghost:hover{border-color:var(--ink)}
.btn-lg{font-size:15px;padding:18px 26px}
.login-body{display:flex;align-items:center;justify-content:center;min-height:100vh}
.login{width:320px;display:flex;flex-direction:column;gap:16px}
.login h1{font-family:var(--disp);font-size:32px;margin:0 0 8px}
.login input{padding:12px 14px;border:1px solid var(--line);border-radius:10px;
  font:inherit;background:var(--card)}
.login .err{color:#7A2B2B;font-size:13px;min-height:1em}

/* ───────── 12. Bannière de consentement ───────── */
/* Refuser et Accepter gardent la même taille, la même place, un clic chacun,
   aucun des deux rempli : refuser doit être aussi simple qu'accepter. */
.consent{
  position:fixed;left:50%;bottom:clamp(12px,2vw,24px);transform:translate(-50%,14px);
  z-index:60;width:min(720px, calc(100vw - 32px));
  display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  padding:16px 20px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);
  box-shadow:var(--shadow-md);
  opacity:0;transition:opacity .22s ease, transform .22s ease;
}
.consent.in{opacity:1;transform:translate(-50%,0)}
.consent-text{
  flex:1 1 340px;margin:0;
  font-family:var(--sans);font-size:13px;font-weight:300;line-height:1.5;color:var(--muted);
}
.consent-text a{color:var(--ink-soft);text-decoration:underline;text-underline-offset:2px}
.consent-actions{display:flex;gap:8px;flex:0 0 auto}
.consent-btn{
  font-family:var(--sans);font-size:13px;font-weight:500;cursor:pointer;
  padding:9px 18px;border-radius:999px;white-space:nowrap;
  border:1px solid var(--line);background:transparent;color:var(--ink-soft);
  transition:background .15s ease, border-color .15s ease;
}
.consent-btn:hover{background:rgba(17,17,17,.04);border-color:var(--muted)}
.consent-btn-accept{border-color:var(--muted);color:var(--ink)}
.consent-btn-accept:hover{background:rgba(17,17,17,.06);border-color:var(--ink)}
.consent-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
@media (max-width:560px){
  .consent{gap:14px;padding:16px}
  .consent-actions{width:100%}
  .consent-btn{flex:1}
}
@media (prefers-reduced-motion:reduce){
  .consent{transition:none;transform:translate(-50%,0)}
}

/* ───────── 13. Media queries ───────── */
@media(max-width:900px){
  .order,.plans,.founders{grid-template-columns:1fr}
  .fgrid{grid-template-columns:1fr 1fr}
  .pill.menu{display:none}
  .final{flex-direction:column;align-items:flex-start}
  /* En colonne étroite l'objet passe derriere le texte : sans ce voile, le h1
     (--ink) se perd sur le noir du boitier — un pur probleme de CONTRASTE
     (texte sombre sur boitier sombre). Le veritable bug d'empilement qui
     empechait meme un fond opaque de suffire est corrige plus haut (.copy
     est maintenant fixed, hors de .hero — cf. commentaire section 4) ; ce
     fond plein ici ne sert plus qu'a la lisibilite. */
  .hero3d .copy{flex-direction:column;align-items:flex-start;bottom:0;
    padding-top:64px;padding-bottom:clamp(34px,7vh,68px);
    background:var(--paper-2)}
}
@media(max-width:560px){
  .posts{grid-template-columns:1fr}
  .fgrid{grid-template-columns:1fr}
}
