/* ==========================================================================
   NUMERI — SYSTEME DE DESIGN
   numeri-video.com · edite par Odratta · marche international (EN)

   Style : « Prisme » — la maquette de Joseph (Claude Design, 30/08/2026)
   portee en ultra-tech : papier blanc, halos de degrade, angles ronds,
   bandeaux de rendus qui defilent, et LA VIDEO COMME MATIERE DE FOND.

   TOUT est pilote par des variables --n-*. Changer la charte = changer les
   valeurs du bloc :root, jamais le reste du fichier.

   ⚠️ CSP SANS 'unsafe-inline' : aucun style en ligne nulle part dans les
   pages. Un style="" y est ignore SANS erreur — la page se decompose en
   silence et le defaut ne se voit qu'en production. Tout ce qui aurait ete
   ecrit en ligne est une classe, section 21 comprise.

   Sommaire
     01  Polices (Poppins + IBM Plex Mono, auto-hebergees)
     02  Jetons — theme CLAIR (defaut)
     03  Jetons — theme SOMBRE (secours)
     04  Reset
     05  Typographie
     06  Grille & conteneurs
     07  Bouton
     08  Champ de formulaire
     09  En-tete collant
     10  Heros & fond video
     11  Bandeaux de rendus qui defilent
     12  Etapes
     13  Formats
     14  Mur de rendus
     15  Panneau video documente
     16  Specifications
     17  Paliers
     18  Appel final
     19  Pied de page
     20  Composants de l'application (/app)
     21  Animations & prefers-reduced-motion
     22  Utilitaires (le remplacement des styles en ligne)
   ========================================================================== */

/* == 01 · POLICES ==========================================================
   Poppins pour le texte — c'est le choix de Joseph, redit deux fois.
   IBM Plex Mono pour les etiquettes techniques, les identifiants et les
   chiffres — c'est la mono de sa maquette, et c'est elle qui donne le ton
   « instrument » sans que le reste devienne froid.

   14 fichiers woff2, 208 Ko au total, decoupes par plage Unicode : un
   visiteur francais ou anglais ne telecharge que « latin ».

   ⚠️ Jamais de Google Fonts en CDN. La maquette d'origine les appelait ;
   la CNIL y voit un transfert de donnees non consenti, et la CSP du vhost
   les bloquerait de toute facon. Zero requete tierce = aucun bandeau.
   ========================================================================== */

@font-face { font-family:"Poppins"; font-style:normal; font-weight:300; font-display:swap;
  src:url("../fonts/poppins-300-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/poppins-400-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/poppins-500-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:600; font-display:swap;
  src:url("../fonts/poppins-600-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:700; font-display:swap;
  src:url("../fonts/poppins-700-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }

@font-face { font-family:"Poppins"; font-style:normal; font-weight:300; font-display:swap;
  src:url("../fonts/poppins-300-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/poppins-400-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/poppins-500-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:600; font-display:swap;
  src:url("../fonts/poppins-600-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:"Poppins"; font-style:normal; font-weight:700; font-display:swap;
  src:url("../fonts/poppins-700-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

@font-face { font-family:"IBM Plex Mono"; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/plexmono-400-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:"IBM Plex Mono"; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/plexmono-500-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family:"IBM Plex Mono"; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/plexmono-400-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family:"IBM Plex Mono"; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/plexmono-500-latinext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

/* Police de secours calee sur les metriques de Poppins : pendant le swap le
   texte est deja a la bonne largeur, la bascule ne fait pas sauter la page. */
@font-face {
  font-family: "Poppins secours";
  src: local("Helvetica Neue"), local("Arial"), local("Segoe UI"), local("Roboto");
  size-adjust: 112%; ascent-override: 93.75%; descent-override: 31.25%; line-gap-override: 0%;
}

/* == 02 · JETONS — THEME CLAIR (DEFAUT) ===================================
   Les valeurs viennent de la maquette. Deux corrections, mesurees :

   1. --n-faint etait #7A7A85 (4,24:1) → sous le minimum AA. Passe a #71717C.
   2. LA RAMPE. Celle de la maquette (#FF6E7F → #C58BF2 → #7A6CF0) ne tient
      PAS sous du texte : blanc sur #C58BF2 = 2,52:1, et le titre en degrade
      tombe a 2,52 lui aussi. Un degrade se juge sur son arret le plus pale,
      jamais sur sa moyenne.
      → --n-grad garde les teintes EXACTES de la maquette et ne sert qu'au
        DECOR : halos, rectangles de format, pastilles, filets, lueurs.
      → --n-grad-ink est la meme rampe descendue d'un cran, verifiee arret
        par arret (5,46 · 4,79 · 5,54). C'est elle qui porte le texte en
        degrade et les aplats a libelle blanc. Meme identite a l'oeil.
   ========================================================================= */

:root {
  color-scheme: light;

  /* --- Fonds ------------------------------------------------------------ */
  --n-bg:            #FFFFFF;
  --n-bg-soft:       #FBFAFF;   /* bande de section, degrade tres pale */
  --n-bg-deep:       #0B0B0F;   /* le puits : interieur d'un caisson video */
  --n-well:          #08080B;   /* le noir de salle */
  --n-bg-overlay:    rgba(255, 255, 255, 0.72); /* voile de l'en-tete */

  /* --- Surfaces --------------------------------------------------------- */
  --n-surface-1:     #FFFFFF;
  --n-surface-2:     #F7F6FC;
  --n-surface-3:     #F1EFF9;
  --n-surface-4:     #E6E3F2;

  /* --- Encre ------------------------------------------------------------ */
  --n-text:          #0B0B0F;   /* 19.64:1  (AAA) */
  --n-text-strong:   #000000;   /* 21.00:1  (AAA) */
  --n-text-muted:    #55555F;   /*  7.37:1  (AAA) */
  --n-text-faint:    #6B6B76;   /*  5.26:1  (AA)  */
  --n-text-dim:      #71717C;   /*  4.82:1  (AA)  — corrige de #7A7A85 */
  --n-text-disabled: #A3A3AE;   /* desactive seulement, exempte 1.4.3 */
  --n-text-on-accent:#FFFFFF;

  /* --- L'accent, en trois etats ---------------------------------------- */
  --n-accent:        #6152E0;   /*  5.54:1 — liens, focus, petit texte */
  --n-accent-hi:     #5140CF;   /*  7.04:1 — survol */
  --n-accent-lo:     #7A6CF0;   /*  4.01:1 — LE violet exact de la maquette,
                                   bordures et decor seulement, jamais texte */
  --n-accent-up:     #B9AEFF;   /* la seule version lisible sur le puits noir */
  --n-accent-soft:   rgba(97, 82, 224, 0.08);
  --n-accent-veil:   rgba(97, 82, 224, 0.04);

  /* --- Les deux rampes -------------------------------------------------- */
  --n-grad:      linear-gradient(115deg, #FF6E7F 0%, #C58BF2 52%, #7A6CF0 100%);
  --n-grad-ink:  linear-gradient(115deg, #C92646 0%, #9E4AD4 52%, #6152E0 100%);
  --n-grad-ink-hi: linear-gradient(115deg, #B81A3A 0%, #8A38C4 52%, #5140CF 100%);
  --n-grad-text: linear-gradient(105deg, #C92646 0%, #9E4AD4 48%, #6152E0 100%);

  /* --- Halos : le fond vivant de la maquette --------------------------- */
  --n-blob-a:    #FFC9CF;
  --n-blob-b:    #D9C8FF;

  /* --- Etats ------------------------------------------------------------ */
  --n-ok:            #0E7A46;   --n-ok-soft:     rgba(14, 122, 70, 0.10);
  --n-warn:          #8A5B00;   --n-warn-soft:   rgba(138, 91, 0, 0.10);
  --n-danger:        #C01F3F;   --n-danger-soft: rgba(192, 31, 63, 0.10);
  --n-info:          #175680;   --n-info-soft:   rgba(23, 86, 128, 0.10);

  /* --- Filets ------------------------------------------------------------
     Deux familles. Les DECORATIFS peuvent s'effacer sans coût ; le
     FONCTIONNEL (--n-line-strong) borde un controle et doit tenir 3:1 sur
     les quatre surfaces du systeme, pas seulement sur blanc. */
  --n-line:          rgba(11, 11, 15, 0.07);
  --n-line-2:        rgba(11, 11, 15, 0.12);
  --n-line-3:        rgba(11, 11, 15, 0.16);
  --n-line-strong:   #78787F;   /* 4.08 sur blanc · 3.24 sur surface-4 */
  --n-line-accent:   rgba(122, 108, 240, 0.42);
  --n-line-bevel:    rgba(255, 255, 255, 0.85);
  --n-line-grid:     rgba(11, 11, 15, 0.045);

  /* --- Focus : jamais discret ------------------------------------------- */
  --n-focus:         #6152E0;
  --n-focus-w:       2px;
  --n-focus-offset:  2px;

  /* --- Rayons : ceux de la maquette, ronds et assumes ------------------- */
  --n-r-xs:    6px;
  --n-r-sm:    9px;
  --n-r-md:   12px;
  --n-r-lg:   16px;
  --n-r-xl:   18px;
  --n-r-2xl:  22px;
  --n-r-3xl:  28px;
  --n-r-pill: 999px;

  /* --- Ombres : basses et colorees, jamais grises ---------------------- */
  --n-shadow-1: 0 1px 2px rgba(11, 11, 15, 0.04);
  --n-shadow-2: 0 6px 18px -12px rgba(97, 82, 224, 0.45);
  --n-shadow-3: 0 20px 50px -34px rgba(97, 82, 224, 0.55);
  --n-shadow-4: 0 34px 70px -50px rgba(97, 82, 224, 0.90);
  --n-bevel:    inset 0 1px 0 var(--n-line-bevel);
  --n-glow:     0 12px 30px -16px rgba(97, 82, 224, 0.85);

  /* --- Durees ------------------------------------------------------------ */
  --n-dur-1: 120ms; --n-dur-2: 180ms; --n-dur-3: 300ms;
  --n-dur-4: 480ms; --n-dur-5: 800ms; --n-dur-6: 1200ms;

  /* --- Courbes ---------------------------------------------------------- */
  --n-ease-out:   cubic-bezier(0.2, 0.7, 0.2, 1);
  --n-ease-in:    cubic-bezier(0.55, 0.06, 0.68, 0.19);
  --n-ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --n-ease-emph:  cubic-bezier(0.2, 0.7, 0.2, 1);

  /* --- Espacement -------------------------------------------------------- */
  --n-sp-0:0; --n-sp-1:2px; --n-sp-2:4px; --n-sp-3:6px; --n-sp-4:8px;
  --n-sp-5:12px; --n-sp-6:16px; --n-sp-7:20px; --n-sp-8:24px; --n-sp-9:32px;
  --n-sp-10:40px; --n-sp-11:48px; --n-sp-12:64px; --n-sp-13:80px;
  --n-sp-14:96px; --n-sp-15:128px; --n-sp-16:160px;
  --n-sp-section: clamp(5rem, 3.2rem + 7.4vw, 7.5rem);
  --n-sp-gutter:  clamp(1.25rem, 0.75rem + 2.2vw, 2rem);
  --n-sp-stack:   clamp(2.5rem, 1.83rem + 2.96vw, 4.5rem);

  /* --- Familles ---------------------------------------------------------- */
  --n-font-sans: "Poppins", "Poppins secours", ui-sans-serif, system-ui,
                 -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --n-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono",
                 Menlo, Consolas, "Liberation Mono", monospace;

  --n-fw-light:300; --n-fw-normal:400; --n-fw-medium:500;
  --n-fw-semi:600; --n-fw-bold:700;

  /* --- Echelle typographique (fluide 360 → 1440) ------------------------ */
  --n-fs-3xs: clamp(0.625rem,  0.615rem + 0.046vw, 0.6875rem);
  --n-fs-2xs: clamp(0.6875rem, 0.677rem + 0.046vw, 0.71875rem);
  --n-fs-xs:  clamp(0.75rem,   0.729rem + 0.093vw, 0.8125rem);
  --n-fs-sm:  clamp(0.8125rem, 0.792rem + 0.093vw, 0.875rem);
  --n-fs-md:  clamp(0.9375rem, 0.917rem + 0.093vw, 1rem);
  --n-fs-lg:  clamp(1rem,      0.969rem + 0.139vw, 1.0938rem);
  --n-fs-xl:  clamp(1.0625rem, 1.021rem + 0.185vw, 1.1875rem);
  --n-fs-2xl: clamp(1.25rem,   1.167rem + 0.37vw,  1.5625rem);
  --n-fs-3xl: clamp(1.5rem,    1.354rem + 0.65vw,  1.9375rem);
  --n-fs-4xl: clamp(1.875rem,  1.625rem + 1.11vw,  2.625rem);
  --n-fs-5xl: clamp(2.25rem,   1.833rem + 1.85vw,  3.5rem);
  --n-fs-6xl: clamp(2.5rem,    1.75rem + 3.33vw,   4.75rem);
  --n-fs-7xl: clamp(3.2rem,    1.6rem + 7.1vw,     8.6rem);

  --n-lh-tight:0.9; --n-lh-snug:1.04; --n-lh-normal:1.4;
  --n-lh-body:1.6; --n-lh-loose:1.7;
  --n-ls-display:-0.05em; --n-ls-title:-0.04em; --n-ls-h3:-0.03em;
  --n-ls-normal:0; --n-ls-wide:0.1em; --n-ls-caps:0.16em; --n-ls-caps-lg:0.18em;

  /* --- Grille ------------------------------------------------------------ */
  --n-container:      1320px;
  --n-container-wide: 1440px;
  --n-container-text: 68ch;
  --n-grid-gap:       clamp(1rem, 0.6rem + 1.8vw, 1.25rem);
  --n-header-h:       67px;

  /* --- Plans -------------------------------------------------------------- */
  --n-z-base:0; --n-z-raised:10; --n-z-sticky:20; --n-z-nav:50;
  --n-z-overlay:60; --n-z-modal:70; --n-z-toast:80;
}

/* == 03 · JETONS — THEME SOMBRE (SECOURS) =================================
   Le clair est la charte. Le sombre ne sert qu'a qui l'a demande. La rampe
   remonte : sur du noir, ce sont les teintes CLAIRES qui deviennent lisibles.
   ========================================================================= */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --n-bg:#0B0B0F; --n-bg-soft:#101017; --n-bg-deep:#07070A; --n-well:#050508;
    --n-bg-overlay:rgba(11,11,15,0.72);
    --n-surface-1:#141420; --n-surface-2:#1A1A28; --n-surface-3:#222232; --n-surface-4:#2C2C40;
    --n-text:#F2F1F8; --n-text-strong:#FFFFFF; --n-text-muted:#B3B2C2;
    --n-text-faint:#9A99AA; --n-text-dim:#8E8D9E; --n-text-disabled:#5A5A68;
    --n-text-on-accent:#FFFFFF;
    --n-accent:#B9AEFF; --n-accent-hi:#D2CBFF; --n-accent-lo:#7A6CF0; --n-accent-up:#B9AEFF;
    --n-accent-soft:rgba(185,174,255,0.14); --n-accent-veil:rgba(185,174,255,0.06);
    --n-grad:linear-gradient(115deg,#FF8A99 0%,#D3A5F7 52%,#9E92FF 100%);
    --n-grad-ink:linear-gradient(115deg,#FF8A99 0%,#D3A5F7 52%,#9E92FF 100%);
    --n-grad-ink-hi:linear-gradient(115deg,#FFA3AE 0%,#DFBAFA 52%,#B3A9FF 100%);
    --n-grad-text:linear-gradient(105deg,#FF8A99 0%,#D3A5F7 48%,#9E92FF 100%);
    --n-blob-a:#5B2740; --n-blob-b:#2E2A62;
    --n-ok:#4ED396; --n-warn:#F0B95C; --n-danger:#FF8480; --n-info:#8FBEE6;
    --n-line:rgba(255,255,255,0.09); --n-line-2:rgba(255,255,255,0.14);
    --n-line-3:rgba(255,255,255,0.20); --n-line-strong:#8E8DA0;
    --n-line-accent:rgba(185,174,255,0.45); --n-line-bevel:rgba(255,255,255,0.05);
    --n-line-grid:rgba(255,255,255,0.045);
    --n-focus:#B9AEFF;
    --n-shadow-1:0 1px 2px rgba(0,0,0,0.5);
    --n-shadow-2:0 6px 18px -12px rgba(0,0,0,0.7);
    --n-shadow-3:0 20px 50px -34px rgba(0,0,0,0.8);
    --n-shadow-4:0 34px 70px -50px rgba(0,0,0,0.9);
    --n-glow:0 12px 30px -16px rgba(185,174,255,0.4);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --n-bg:#0B0B0F; --n-bg-soft:#101017; --n-bg-deep:#07070A; --n-well:#050508;
  --n-bg-overlay:rgba(11,11,15,0.72);
  --n-surface-1:#141420; --n-surface-2:#1A1A28; --n-surface-3:#222232; --n-surface-4:#2C2C40;
  --n-text:#F2F1F8; --n-text-strong:#FFFFFF; --n-text-muted:#B3B2C2;
  --n-text-faint:#9A99AA; --n-text-dim:#8E8D9E; --n-text-disabled:#5A5A68;
  --n-text-on-accent:#FFFFFF;
  --n-accent:#B9AEFF; --n-accent-hi:#D2CBFF; --n-accent-lo:#7A6CF0; --n-accent-up:#B9AEFF;
  --n-accent-soft:rgba(185,174,255,0.14); --n-accent-veil:rgba(185,174,255,0.06);
  --n-grad:linear-gradient(115deg,#FF8A99 0%,#D3A5F7 52%,#9E92FF 100%);
  --n-grad-ink:linear-gradient(115deg,#FF8A99 0%,#D3A5F7 52%,#9E92FF 100%);
  --n-grad-ink-hi:linear-gradient(115deg,#FFA3AE 0%,#DFBAFA 52%,#B3A9FF 100%);
  --n-grad-text:linear-gradient(105deg,#FF8A99 0%,#D3A5F7 48%,#9E92FF 100%);
  --n-blob-a:#5B2740; --n-blob-b:#2E2A62;
  --n-ok:#4ED396; --n-warn:#F0B95C; --n-danger:#FF8480; --n-info:#8FBEE6;
  --n-line:rgba(255,255,255,0.09); --n-line-2:rgba(255,255,255,0.14);
  --n-line-3:rgba(255,255,255,0.20); --n-line-strong:#8E8DA0;
  --n-line-accent:rgba(185,174,255,0.45); --n-line-bevel:rgba(255,255,255,0.05);
  --n-line-grid:rgba(255,255,255,0.045);
  --n-focus:#B9AEFF;
  --n-shadow-1:0 1px 2px rgba(0,0,0,0.5);
  --n-shadow-2:0 6px 18px -12px rgba(0,0,0,0.7);
  --n-shadow-3:0 20px 50px -34px rgba(0,0,0,0.8);
  --n-shadow-4:0 34px 70px -50px rgba(0,0,0,0.9);
  --n-glow:0 12px 30px -16px rgba(185,174,255,0.4);
}
:root[data-theme="light"] { color-scheme: light; }

/* == 04 · RESET =========================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--n-header-h) + 24px);
}
html, body { max-inline-size: 100%; overflow-x: clip; }

body {
  margin: 0;
  background: var(--n-bg);
  color: var(--n-text);
  font-family: var(--n-font-sans);
  font-size: var(--n-fs-md);
  line-height: var(--n-lh-body);
  font-weight: var(--n-fw-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1,h2,h3,h4,h5,h6,p,figure,blockquote,dl,dd { margin: 0; }
ul, ol { margin: 0; padding: 0; }
img, video, svg, canvas { display: block; max-inline-size: 100%; }
img, video { block-size: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
table { border-collapse: collapse; inline-size: 100%; }
::selection { background: #F2D9FF; color: #0B0B0F; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: var(--n-focus-w) solid var(--n-focus);
  outline-offset: var(--n-focus-offset);
  border-radius: var(--n-r-xs);
}

.n-skip {
  position: absolute; inset-block-start: -100%; inset-inline-start: var(--n-sp-6);
  z-index: var(--n-z-toast);
  padding: var(--n-sp-5) var(--n-sp-8);
  background: var(--n-text); color: var(--n-bg);
  border-radius: var(--n-r-pill); font-size: var(--n-fs-sm); font-weight: var(--n-fw-medium);
}
.n-skip:focus { inset-block-start: var(--n-sp-6); }

.n-sr-only {
  position: absolute; inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* == 05 · TYPOGRAPHIE =====================================================
   Poppins est large : plus le corps grandit, plus l'interlettrage se
   resserre. Le display descend a -0,05em, comme dans la maquette.
   ========================================================================= */

.n-display, .n-h1, .n-h2, .n-h3, .n-h4 {
  font-family: var(--n-font-sans);
  color: var(--n-text);
  font-weight: var(--n-fw-medium);
  text-wrap: balance;
  font-synthesis-weight: none;
}
.n-display { font-size: var(--n-fs-7xl); line-height: var(--n-lh-tight);
             letter-spacing: var(--n-ls-display); }
.n-h1      { font-size: var(--n-fs-6xl); line-height: 0.98;
             letter-spacing: var(--n-ls-display); }
.n-h2      { font-size: var(--n-fs-5xl); line-height: var(--n-lh-snug);
             letter-spacing: var(--n-ls-title); }
.n-h3      { font-size: var(--n-fs-2xl); line-height: 1.12;
             letter-spacing: var(--n-ls-h3); }
.n-h4      { font-size: var(--n-fs-lg);  line-height: var(--n-lh-normal);
             letter-spacing: var(--n-ls-normal); font-weight: var(--n-fw-semi); }

.n-lead { font-size: var(--n-fs-xl); line-height: 1.55; color: var(--n-text-muted);
          max-inline-size: 54ch; text-wrap: pretty; }
.n-body { font-size: var(--n-fs-md); line-height: var(--n-lh-body);
          color: var(--n-text-muted); max-inline-size: var(--n-container-text);
          text-wrap: pretty; }
.n-small{ font-size: var(--n-fs-sm); line-height: 1.6; color: var(--n-text-muted); }
.n-tiny { font-size: var(--n-fs-xs); line-height: 1.65; color: var(--n-text-dim); }

/* Deux paragraphes qui se suivent respirent. La marge est posee sur la
   SUITE : un premier paragraphe ne doit pas pousser le titre qui le precede. */
.n-body + .n-body, .n-body + .n-small, .n-small + .n-body,
.n-lead + .n-body, .n-tiny + .n-tiny { margin-block-start: var(--n-sp-6); }

/* La mono : toutes les etiquettes techniques du systeme passent par la. */
.n-meta, .n-eyebrow, .n-tag, .n-mono {
  font-family: var(--n-font-mono);
  font-variant-numeric: tabular-nums;
}
.n-eyebrow {
  display: block;
  font-size: var(--n-fs-2xs); font-weight: var(--n-fw-normal);
  letter-spacing: var(--n-ls-caps-lg); text-transform: uppercase;
  color: var(--n-text-faint);
}
.n-meta { font-size: var(--n-fs-2xs); letter-spacing: var(--n-ls-caps);
          text-transform: uppercase; color: var(--n-text-faint); }
.n-num  { font-family: var(--n-font-mono); font-variant-numeric: tabular-nums; }

/* Le texte en degrade : LA signature de la maquette.
   Il utilise --n-grad-text, la rampe assombrie — la rampe d'origine tombe a
   2,52:1 et un titre illisible n'est pas un titre. Repli en couleur pleine
   pour les navigateurs sans background-clip. */
.n-grad-text {
  color: var(--n-accent);
  background: var(--n-grad-text);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  /* Safari perd le degrade en impression : on lui rend une encre. */
}
@media print { .n-grad-text { -webkit-text-fill-color: currentColor; color: var(--n-text); } }
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .n-grad-text { -webkit-text-fill-color: currentColor; color: var(--n-accent); }
}

.n-link {
  color: var(--n-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.25em;
  text-decoration-color: var(--n-line-accent);
  transition: color var(--n-dur-1) var(--n-ease-out),
              text-decoration-color var(--n-dur-1) var(--n-ease-out);
}
.n-link:hover { color: var(--n-accent-hi); text-decoration-color: currentColor; }

/* == 06 · GRILLE & CONTENEURS ============================================= */

.n-container {
  inline-size: 100%;
  max-inline-size: calc(var(--n-container) + 2 * var(--n-sp-gutter));
  margin-inline: auto;
  padding-inline: var(--n-sp-gutter);
}
.n-container--wide { max-inline-size: calc(var(--n-container-wide) + 2 * var(--n-sp-gutter)); }
.n-container--text { max-inline-size: calc(var(--n-container-text) + 2 * var(--n-sp-gutter)); }
.n-container--full { max-inline-size: none; }

.n-section { padding-block: var(--n-sp-section); position: relative; }
.n-section--line { border-block-start: 1px solid var(--n-line); }
.n-section--soft { background: linear-gradient(180deg, var(--n-bg-soft) 0%, var(--n-bg) 100%); }
.n-section--soft-mid {
  background: linear-gradient(180deg, var(--n-bg) 0%, var(--n-bg-soft) 60%, var(--n-bg) 100%);
}

.n-stack > * + * { margin-block-start: var(--n-sp-6); }
.n-stack-lg > * + * { margin-block-start: var(--n-sp-stack); }
.n-cluster { display: flex; flex-wrap: wrap; gap: var(--n-sp-5); align-items: center; }
.n-rule { border-block-start: 1px solid var(--n-line); }

/* L'en-tete de section de la maquette : titre a gauche, phrase a droite,
   alignes sur leur ligne de base, qui passent l'un sous l'autre au besoin. */
.n-shead {
  display: flex; align-items: end; justify-content: space-between;
  gap: var(--n-sp-10); flex-wrap: wrap;
}
.n-shead__side { max-inline-size: 38ch; margin: 0; }

/* Les deux colonnes a colonne collante (« comment ca marche », « specs ») */
.n-split { display: grid; gap: var(--n-sp-11); }
@media (min-width: 960px) {
  .n-split { grid-template-columns: minmax(280px, 0.85fr) minmax(0, 1.15fr);
             gap: clamp(3rem, 5vw, 5rem); }
  .n-split__sticky { position: sticky; inset-block-start: calc(var(--n-header-h) + 32px);
                     align-self: start; }
}
.n-split--specs { }
@media (min-width: 960px) {
  .n-split--specs { grid-template-columns: minmax(260px, .8fr) minmax(0, 1.2fr); }
}

/* Deux colonnes egales, centrees (« pourquoi la montre ») */
.n-duo { display: grid; gap: var(--n-sp-11); align-items: center; }
@media (min-width: 960px) { .n-duo { grid-template-columns: 1fr 1fr;
                                     gap: clamp(3rem, 4.5vw, 4.4rem); } }

/* == 07 · BOUTON ==========================================================
   Pastille, comme la maquette. Cinq etats, cible tactile 44 px.
   La variante primaire porte --n-grad-ink : blanc lisible d'un bout a
   l'autre de la rampe (4,79 au pire arret).
   ========================================================================= */

.n-btn {
  --n-btn-h: 44px;
  --n-btn-px: var(--n-sp-8);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--n-sp-4);
  min-block-size: var(--n-btn-h);
  padding-inline: var(--n-btn-px);
  border: 1px solid transparent;
  border-radius: var(--n-r-pill);
  font-size: var(--n-fs-sm);
  font-weight: var(--n-fw-medium);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer; user-select: none; text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--n-dur-1) var(--n-ease-out),
              border-color var(--n-dur-1) var(--n-ease-out),
              color var(--n-dur-1) var(--n-ease-out),
              box-shadow var(--n-dur-2) var(--n-ease-out),
              transform var(--n-dur-1) var(--n-ease-out);
}
.n-btn > svg { inline-size: 16px; block-size: 16px; flex: none; }
.n-btn--sm { --n-btn-h: 38px; --n-btn-px: var(--n-sp-7); font-size: var(--n-fs-xs); }
.n-btn--lg { --n-btn-h: 52px; --n-btn-px: var(--n-sp-10); font-size: var(--n-fs-md); }
.n-btn--block { display: flex; inline-size: 100%; }

.n-btn--primary {
  background-image: var(--n-grad-ink);
  color: #FFFFFF;
  box-shadow: var(--n-glow);
}
.n-btn--primary:hover  { background-image: var(--n-grad-ink-hi); }
.n-btn--primary:active { transform: translateY(1px); box-shadow: var(--n-shadow-2); }

.n-btn--ghost {
  background: transparent; color: var(--n-text);
  border-color: var(--n-line-3);
}
.n-btn--ghost:hover  { border-color: var(--n-accent-lo); color: var(--n-accent-hi);
                       background: var(--n-accent-veil); }
.n-btn--ghost:active { transform: translateY(1px); }

.n-btn--quiet {
  background: transparent; color: var(--n-text-muted);
  --n-btn-px: var(--n-sp-6);
}
.n-btn--quiet:hover  { color: var(--n-text); background: var(--n-surface-2); }
.n-btn--quiet:active { transform: translateY(1px); }

.n-btn--danger { background: transparent; color: var(--n-danger); border-color: var(--n-danger); }
.n-btn--danger:hover { background: var(--n-danger-soft); }

.n-btn:disabled, .n-btn[aria-disabled="true"] {
  background: var(--n-surface-3); background-image: none;
  color: var(--n-text-disabled); border-color: var(--n-line-2);
  cursor: not-allowed; transform: none; box-shadow: none;
}
.n-btn[data-loading="true"] { color: transparent; pointer-events: none; }
.n-btn[data-loading="true"]::after {
  content: ""; position: absolute;
  inset-block-start: 50%; inset-inline-start: 50%;
  inline-size: 16px; block-size: 16px; margin: -8px 0 0 -8px;
  border: 1.5px solid currentColor; border-block-start-color: transparent;
  border-radius: 50%; color: #FFFFFF;
  animation: n-spin 700ms linear infinite;
}
.n-btn--ghost[data-loading="true"]::after,
.n-btn--quiet[data-loading="true"]::after { color: var(--n-text); }
.n-btn--icon { --n-btn-px: 0; inline-size: var(--n-btn-h); }

/* == 08 · CHAMP =========================================================== */

.n-field { display: flex; flex-direction: column; gap: var(--n-sp-4); }
.n-field__label { font-size: var(--n-fs-xs); font-weight: var(--n-fw-medium);
                  color: var(--n-text-muted); }
.n-field__label .n-req { color: var(--n-accent); margin-inline-start: 2px; }

.n-input, .n-textarea, .n-select {
  inline-size: 100%; min-block-size: 44px;
  padding: var(--n-sp-5) var(--n-sp-7);
  background: var(--n-surface-1); color: var(--n-text);
  border: 1px solid var(--n-line-3);
  border-radius: var(--n-r-md);
  font-size: var(--n-fs-sm); line-height: 1.4;
  transition: border-color var(--n-dur-1) var(--n-ease-out),
              box-shadow var(--n-dur-2) var(--n-ease-out);
}
.n-textarea { min-block-size: 120px; resize: vertical; }
.n-select {
  appearance: none; padding-inline-end: var(--n-sp-11);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%236B6B76' stroke-width='1.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--n-sp-6) center;
}
.n-input::placeholder, .n-textarea::placeholder { color: var(--n-text-dim); }
.n-input:hover, .n-textarea:hover, .n-select:hover { border-color: var(--n-line-strong); }
.n-input:focus-visible, .n-textarea:focus-visible, .n-select:focus-visible {
  outline: none; border-color: var(--n-accent);
  box-shadow: 0 0 0 3px var(--n-accent-soft);
}
.n-input:disabled, .n-textarea:disabled, .n-select:disabled {
  background: var(--n-surface-2); color: var(--n-text-disabled);
  border-color: var(--n-line-2); cursor: not-allowed;
}
.n-field__hint  { font-size: var(--n-fs-2xs); color: var(--n-text-dim); }
.n-field__error { font-size: var(--n-fs-2xs); color: var(--n-danger);
                  display: flex; align-items: center; gap: var(--n-sp-3); }
.n-field__error::before {
  content: ""; inline-size: 12px; block-size: 12px; flex: none;
  border: 1px solid currentColor; border-radius: 50%;
  /* la couleur n'est jamais le seul indicateur : pastille + texte */
}
.n-field[data-invalid="true"] .n-input,
.n-field[data-invalid="true"] .n-textarea,
.n-field[data-invalid="true"] .n-select { border-color: var(--n-danger); }

/* == 09 · EN-TETE COLLANT =================================================
   Fixe, voile translucide, filet en bas. Comme la maquette.
   ========================================================================= */

.n-nav {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: var(--n-z-nav);
  background: var(--n-bg-overlay);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-block-end: 1px solid var(--n-line);
}
.n-nav__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--n-sp-8);
  min-block-size: var(--n-header-h);
  padding-block: var(--n-sp-5);
}
.n-nav__brand { display: inline-flex; align-items: center; gap: 11px; flex: none; }
.n-nav__brand img, .n-nav__brand .n-brandmark {
  inline-size: 30px; block-size: 30px; border-radius: var(--n-r-sm);
  display: block; box-shadow: 0 1px 0 rgba(11,11,15,.06); flex: none;
}
.n-nav__brand span {
  font-size: var(--n-fs-sm); font-weight: var(--n-fw-semi);
  letter-spacing: var(--n-ls-caps); text-transform: uppercase;
  color: var(--n-text);
}
.n-nav__links { display: none; align-items: center; gap: var(--n-sp-9);
                font-size: var(--n-fs-xs); }
@media (min-width: 900px) { .n-nav__links { display: flex; } }
.n-nav__link {
  position: relative; color: var(--n-text-muted); padding-block: var(--n-sp-4);
  transition: color var(--n-dur-1) var(--n-ease-out);
}
.n-nav__link:hover, .n-nav__link[aria-current="page"] { color: var(--n-accent-hi); }
.n-nav__link::after {
  content: ""; position: absolute; inset-inline: 0; inset-block-end: 2px;
  block-size: 1.5px; border-radius: 2px; background-image: var(--n-grad);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--n-dur-3) var(--n-ease-emph);
}
.n-nav__link:hover::after, .n-nav__link[aria-current="page"]::after { transform: scaleX(1); }
.n-nav__side { display: flex; align-items: center; gap: var(--n-sp-5); }
.n-nav__login { display: none; font-size: var(--n-fs-xs); color: var(--n-text-muted);
                padding: var(--n-sp-4) var(--n-sp-2); }
@media (min-width: 640px) { .n-nav__login { display: inline-flex; } }
.n-nav__login:hover { color: var(--n-accent-hi); }
.n-nav__toggle { display: grid; place-items: center; inline-size: 44px; block-size: 44px;
                 color: var(--n-text); border-radius: var(--n-r-sm); }
@media (min-width: 900px) { .n-nav__toggle { display: none; } }

.n-navpanel {
  position: fixed; inset: 0; z-index: var(--n-z-overlay);
  display: flex; flex-direction: column; gap: var(--n-sp-6);
  padding: var(--n-sp-13) var(--n-sp-gutter) var(--n-sp-9);
  background: var(--n-bg);
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity var(--n-dur-3) var(--n-ease-out),
              transform var(--n-dur-3) var(--n-ease-out),
              visibility 0s linear var(--n-dur-3);
}
.n-navpanel[data-open="true"] {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--n-dur-3) var(--n-ease-out),
              transform var(--n-dur-3) var(--n-ease-emph), visibility 0s;
}
.n-navpanel__link {
  display: flex; align-items: center; justify-content: space-between;
  min-block-size: 56px; font-size: var(--n-fs-2xl); font-weight: var(--n-fw-medium);
  letter-spacing: var(--n-ls-h3); color: var(--n-text);
  border-block-end: 1px solid var(--n-line);
}
.n-navpanel__close {
  position: absolute; inset-block-start: var(--n-sp-5); inset-inline-end: var(--n-sp-gutter);
  inline-size: 44px; block-size: 44px; display: grid; place-items: center; color: var(--n-text);
}
.n-themetoggle {
  display: grid; place-items: center; inline-size: 38px; block-size: 38px;
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-pill);
  color: var(--n-text-muted); background: transparent;
}
.n-themetoggle:hover { color: var(--n-accent-hi); border-color: var(--n-accent-lo); }
.n-themetoggle svg { inline-size: 16px; block-size: 16px; }

/* == 10 · HEROS & FOND VIDEO ==============================================
   La demande de Joseph : « toutes les videos en fond ». Le heros porte donc
   un clip plein cadre, en boucle et muet, sous TROIS couches :
     1. le clip lui-meme, legerement desature ;
     2. un voile blanc — c'est lui qui rend le texte lisible. Sans voile, du
        texte encre sur une video claire tombe sous 2:1 par endroits, et le
        contraste d'un texte sur image mouvante se juge sur son pire cadre,
        jamais sur son affiche ;
     3. les halos de degrade de la maquette, qui redonnent la couleur.
   Le clip ne peint jamais le premier rendu : c'est l'affiche qui le fait,
   et la video ne se charge qu'a l'entree dans le champ.
   ========================================================================= */

.n-hero {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  min-block-size: 100svh;
  padding: calc(var(--n-header-h) + var(--n-sp-14)) var(--n-sp-gutter) var(--n-sp-13);
  isolation: isolate;
  overflow: clip;
}
.n-hero__bg { position: absolute; inset: 0; z-index: -3; overflow: hidden; }

/* LA MOSAIQUE. Un seul clip plein cadre se recadre mal : sur un ecran haut
   il ne reste qu'un detail agrandi, qui se lit comme une erreur. Une grille
   de clips, elle, garde chaque plan a sa proportion, remplit n'importe quel
   format d'ecran, et c'est litteralement ce qui etait demande — toutes les
   videos en fond. Elle derive tres lentement pour rester vivante sans
   attirer l'oeil : le sujet de la page reste le titre. */
.n-mosaic {
  position: absolute; inset: -8% -4%;
  display: grid; gap: 10px;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 1fr;
  transform: scale(1.06);
  animation: n-drift 90s linear infinite alternate;
  will-change: transform;
}
@media (min-width: 700px)  { .n-mosaic { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1100px) { .n-mosaic { grid-template-columns: repeat(4, 1fr); } }
.n-mos {
  position: relative; overflow: hidden; border-radius: var(--n-r-lg);
  background: var(--n-surface-3);
}
.n-mos > img, .n-mos > video {
  inline-size: 100%; block-size: 100%; object-fit: cover;
  filter: saturate(1.06);
}
.n-mos > video { position: absolute; inset: 0; opacity: 0;
                 transition: opacity var(--n-dur-5) var(--n-ease-out); }
.n-mos[data-playing="true"] > video { opacity: 1; }
/* les cellules qui debordent en bas ne servent qu'a remplir : on les cache
   sur les petits ecrans plutot que de faire decoder douze clips pour rien */
@media (max-width: 699.98px) { .n-mos:nth-child(n+9) { display: none; } }
/* LE VOILE, et le calcul qui le fixe.
   Un texte pose sur une image qui bouge se juge sur son PIRE cadre, jamais
   sur son affiche. Le pire cadre possible est un plan noir. Un voile blanc
   a 0,55 sur du noir compose un #8C8C8C : l'encre #0B0B0F y tient 5,84:1.
   C'est donc le reglage le plus GENEREUX qui reste demontrable — la video
   se voit a 45 %, et la lisibilite est garantie quel que soit le clip.
   Conséquence assumee : dans le heros TOUT le texte est en encre pleine,
   la hierarchie se fait a l'echelle et au poids, jamais au gris. */
.n-hero__veil {
  position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background:
    /* le halo central : il pose la colonne de texte sans fermer la mosaique
       sur les bords. Il s'AJOUTE au voile, donc le pire cas reste meilleur
       que le 0,55 calcule — la garantie de lisibilite ne bouge pas. */
    radial-gradient(58% 46% at 50% 42%, rgba(255,255,255,.62) 0%,
                                        rgba(255,255,255,.28) 55%, transparent 100%),
    linear-gradient(180deg, rgba(255,255,255,.55) 0%, rgba(255,255,255,.55) 62%,
                            rgba(255,255,255,.82) 86%, var(--n-bg) 100%);
}
.n-hero .n-lead,
.n-hero__hint,
.n-hero__pill { color: var(--n-text); }
.n-hero .n-lead { font-weight: var(--n-fw-normal); }
:root[data-theme="dark"] .n-hero__veil,
.n-hero__veil { }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .n-hero__veil {
    background:
      radial-gradient(58% 46% at 50% 42%, rgba(11,11,15,.66) 0%,
                                          rgba(11,11,15,.30) 55%, transparent 100%),
      linear-gradient(180deg, rgba(11,11,15,.62) 0%, rgba(11,11,15,.62) 62%,
                              rgba(11,11,15,.86) 86%, var(--n-bg) 100%);
  }
  :root:not([data-theme="light"]) .n-hero .n-lead,
  :root:not([data-theme="light"]) .n-hero__hint { color: #FFFFFF; }
}
:root[data-theme="dark"] .n-hero__veil {
  background:
    radial-gradient(58% 46% at 50% 42%, rgba(11,11,15,.66) 0%,
                                        rgba(11,11,15,.30) 55%, transparent 100%),
    linear-gradient(180deg, rgba(11,11,15,.62) 0%, rgba(11,11,15,.62) 62%,
                            rgba(11,11,15,.86) 86%, var(--n-bg) 100%);
}
:root[data-theme="dark"] .n-hero .n-lead,
:root[data-theme="dark"] .n-hero__hint { color: #FFFFFF; }

/* Les halos de la maquette : deux degrades radiaux flous qui respirent. */
.n-blob {
  position: absolute; z-index: -1; pointer-events: none;
  border-radius: 50%; filter: blur(90px); opacity: .5;
  background:
    radial-gradient(45% 55% at 35% 45%, var(--n-blob-a) 0%, transparent 70%),
    radial-gradient(45% 55% at 68% 55%, var(--n-blob-b) 0%, transparent 70%);
  animation: n-float 18s var(--n-ease-inout) infinite;
}
.n-blob--top { inset-block-start: -260px; inset-inline-start: 50%;
               inline-size: min(1100px, 130vw); block-size: 700px;
               margin-inline-start: min(-550px, -65vw); }
.n-blob--bottom { inset-block-end: -340px; inset-inline-start: 50%;
                  inline-size: min(1200px, 140vw); block-size: 700px;
                  margin-inline-start: min(-600px, -70vw); filter: blur(100px); opacity: .55; }

/* La trame technique du heros : une grille de 32 px, a peine la. C'est elle
   qui fait basculer la maquette du cote « instrument ». */
.n-hero__grid {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(to right,  var(--n-line-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--n-line-grid) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(120% 80% at 50% 40%, #000 30%, transparent 100%);
          mask-image: radial-gradient(120% 80% at 50% 40%, #000 30%, transparent 100%);
}

.n-hero__pill {
  display: inline-flex; align-items: center; gap: var(--n-sp-5);
  padding: 7px 8px 7px 14px;
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-pill);
  background: rgba(255,255,255,.6);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-caps); text-transform: uppercase;
  color: var(--n-text-muted);
}
:root[data-theme="dark"] .n-hero__pill { background: rgba(20,20,32,.6); }
.n-hero__pill b {
  padding: 3px 9px; border-radius: var(--n-r-pill);
  color: #FFFFFF; background-image: var(--n-grad-ink);
  font-weight: var(--n-fw-medium); letter-spacing: var(--n-ls-wide);
}
.n-hero__title { margin-block-start: var(--n-sp-9); max-inline-size: 15ch; }
.n-hero__lead  { margin-block-start: var(--n-sp-9); max-inline-size: 54ch;
                 margin-inline: auto; }

/* La barre de dépôt : la maquette en fait une pastille blanche posee sur
   le heros. C'est le point de conversion, il ne doit rien avoir de mou. */
.n-catch {
  display: flex; align-items: center; gap: var(--n-sp-4);
  margin-block-start: var(--n-sp-10); padding: 6px;
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-pill);
  background: var(--n-surface-1);
  box-shadow: var(--n-shadow-3);
  max-inline-size: 100%;
}
.n-catch input {
  inline-size: min(300px, 52vw); padding: 12px var(--n-sp-7);
  border: 0; outline: none; background: transparent;
  font-size: var(--n-fs-sm); color: var(--n-text);
}
.n-catch input::placeholder { color: var(--n-text-dim); }
.n-catch input:focus-visible { outline: none; }
.n-catch:focus-within { border-color: var(--n-accent-lo);
                        box-shadow: 0 0 0 3px var(--n-accent-soft), var(--n-shadow-3); }
.n-catch__note {
  min-block-size: 22px; margin-block-start: var(--n-sp-6);
  font-family: var(--n-font-mono); font-size: var(--n-fs-2xs);
  letter-spacing: var(--n-ls-wide); text-transform: uppercase;
  color: var(--n-accent);
}

.n-hero__hint {
  display: flex; flex-direction: column; align-items: center; gap: var(--n-sp-4);
  margin-block-start: auto; padding-block-start: var(--n-sp-12);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--n-text-faint);
}
.n-hero__hint span { animation: n-hint 2s var(--n-ease-inout) infinite; }

/* La reglette de telemetrie sous le heros : ce que le clip de fond EST. */
.n-telemetry {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--n-sp-6); flex-wrap: wrap;
  padding-block: var(--n-sp-6) var(--n-sp-7);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-caps); text-transform: uppercase;
  color: var(--n-text-faint);
}
.n-telemetry b { color: var(--n-text-muted); font-weight: var(--n-fw-normal); }
.n-telemetry__live { display: inline-flex; align-items: center; gap: var(--n-sp-4); }
.n-telemetry__live::before {
  content: ""; inline-size: 6px; block-size: 6px; border-radius: 50%;
  background: var(--n-ok); animation: n-pulse 1.8s var(--n-ease-inout) infinite;
}

/* == 11 · BANDEAUX DE RENDUS QUI DEFILENT =================================
   Le coeur de la demande : deux bandes de clips qui traversent la page,
   l'une vers la gauche, l'autre vers la droite. Chaque tuile porte une
   VIDEO, pas une image — l'affiche tient la place, la boucle prend le
   relais quand la bande entre dans le champ.
   Le masque en degrade fait disparaitre les bords : la bande n'a ni debut
   ni fin, elle passe.
   ========================================================================= */

.n-band { overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.n-band + .n-band { margin-block-start: var(--n-sp-6); }
.n-band__rail {
  display: flex; gap: var(--n-sp-6); inline-size: max-content;
  animation: n-marquee 64s linear infinite;
  will-change: transform;
}
.n-band--rev .n-band__rail { animation-name: n-marquee-rev; animation-duration: 78s; }
/* la bande s'arrete quand on la survole : on veut pouvoir regarder un clip */
.n-band:hover .n-band__rail, .n-band:focus-within .n-band__rail { animation-play-state: paused; }

.n-slab {
  position: relative; flex: none; margin: 0;
  inline-size: 340px; aspect-ratio: 16 / 9;
  overflow: hidden; border-radius: var(--n-r-lg);
  background: var(--n-bg-deep);
  border: 1px solid var(--n-line-2);
}
.n-slab--tall { inline-size: 200px; aspect-ratio: 9 / 16; }
.n-slab > img, .n-slab > video {
  inline-size: 100%; block-size: 100%; object-fit: cover;
}
.n-slab > video { position: absolute; inset: 0; opacity: 0;
                  transition: opacity var(--n-dur-3) var(--n-ease-out); }
.n-slab[data-playing="true"] > video { opacity: 1; }
.n-slab__id {
  position: absolute; inset-block-end: 11px; inset-inline-start: 12px;
  padding: 5px 10px; border-radius: var(--n-r-pill);
  background: rgba(255,255,255,.88);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); color: #33333B;
}

/* == 12 · ETAPES ========================================================== */

.n-steps-list { display: flex; flex-direction: column; gap: var(--n-sp-6); }
.n-move {
  display: grid; grid-template-columns: 1fr; gap: var(--n-sp-6);
  padding: var(--n-sp-10);
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-2xl);
  background: var(--n-surface-1);
  transition: border-color var(--n-dur-3) var(--n-ease-out),
              box-shadow var(--n-dur-3) var(--n-ease-out);
}
@media (min-width: 640px) { .n-move { grid-template-columns: 82px minmax(0,1fr);
                                      gap: var(--n-sp-9); } }
.n-move:hover { border-color: var(--n-line-accent); box-shadow: var(--n-shadow-4); }
.n-move__num {
  font-family: var(--n-font-mono); font-size: var(--n-fs-xs);
  letter-spacing: var(--n-ls-wide); line-height: 1.7;
  color: var(--n-accent);
  background-image: var(--n-grad-text);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  text-transform: uppercase;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .n-move__num { -webkit-text-fill-color: currentColor; }
}
.n-move__title { font-size: var(--n-fs-2xl); font-weight: var(--n-fw-medium);
                 letter-spacing: var(--n-ls-h3); color: var(--n-text); }
.n-move__body  { margin-block-start: var(--n-sp-5); font-size: var(--n-fs-sm);
                 line-height: 1.62; color: var(--n-text-muted); text-wrap: pretty; }

/* == 13 · FORMATS =========================================================
   Six cartes, chacune montrant son ratio A SA VRAIE PROPORTION. Le
   rectangle porte la rampe de DECOR — aucun texte ne se pose dessus.
   ========================================================================= */

.n-formats {
  display: grid; gap: var(--n-sp-6);
  grid-template-columns: repeat(2, minmax(0,1fr));
  align-items: end;
}
@media (min-width: 560px) { .n-formats { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 960px) { .n-formats { grid-template-columns: repeat(6, minmax(0,1fr)); } }
.n-format {
  padding: var(--n-sp-7);
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-xl);
  background: var(--n-surface-1);
  transition: transform var(--n-dur-3) var(--n-ease-out),
              border-color var(--n-dur-3) var(--n-ease-out);
}
.n-format:hover { transform: translateY(-6px); border-color: var(--n-line-accent); }
.n-format__box { block-size: 96px; display: flex; align-items: center; justify-content: center; }
.n-format__box i {
  display: block; border-radius: var(--n-r-xs);
  background-image: var(--n-grad); opacity: .9;
  inline-size: var(--n-fw, 88px); block-size: var(--n-fh, 50px);
}
.n-format b { display: block; margin-block-start: var(--n-sp-6);
              font-size: var(--n-fs-lg); font-weight: var(--n-fw-medium);
              letter-spacing: -0.02em; color: var(--n-text); }
.n-format small { display: block; margin-block-start: 5px;
                  font-size: var(--n-fs-2xs); color: var(--n-text-dim); }

/* == 14 · MUR DE RENDUS ===================================================
   Deux grilles, comme la maquette : neuf 16:9 puis six 9:16. Chaque tuile
   joue sa boucle au survol, au focus clavier et a l'appui.
   ========================================================================= */

.n-wall { display: grid; gap: var(--n-sp-6); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 720px) { .n-wall { grid-template-columns: repeat(3, minmax(0,1fr)); } }
.n-wall--tall { grid-template-columns: repeat(3, minmax(0,1fr)); margin-block-start: var(--n-sp-6); }
@media (min-width: 720px) { .n-wall--tall { grid-template-columns: repeat(6, minmax(0,1fr)); } }

.n-tile {
  position: relative; display: block; inline-size: 100%;
  margin: 0; aspect-ratio: 16 / 9;
  overflow: hidden; border-radius: var(--n-r-xl);
  background: var(--n-bg-deep);
  border: 1px solid var(--n-line-2);
  cursor: pointer;
  transition: border-color var(--n-dur-2) var(--n-ease-out),
              box-shadow var(--n-dur-3) var(--n-ease-out);
}
.n-tile--tall { aspect-ratio: 9 / 16; }
.n-tile > img, .n-tile > video { inline-size: 100%; block-size: 100%; object-fit: cover; }
.n-tile > img { transition: transform var(--n-dur-5) var(--n-ease-emph); }
.n-tile > video { position: absolute; inset: 0; opacity: 0;
                  transition: opacity var(--n-dur-3) var(--n-ease-out); }
.n-tile[data-playing="true"] > video { opacity: 1; }
.n-tile:hover, .n-tile:focus-visible { border-color: var(--n-accent-lo);
                                        box-shadow: var(--n-shadow-4); }
.n-tile:hover > img { transform: scale(1.06); }
.n-tile__cap {
  position: absolute; inset: auto 12px 12px 12px;
  display: flex; align-items: center; justify-content: space-between; gap: var(--n-sp-5);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); color: #33333B;
  pointer-events: none;
}
.n-tile__cap span {
  padding: 5px 10px; border-radius: var(--n-r-pill);
  background: rgba(255,255,255,.9);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.n-tile--tall .n-tile__cap { inset: auto 10px 10px 10px; }
.n-tile--tall .n-tile__cap span:last-child { display: none; }
.n-tile[hidden] { display: none; }

.n-filters { display: flex; flex-wrap: wrap; gap: var(--n-sp-4); border: 0; padding: 0; margin: 0; }
.n-filters legend { position: absolute; inline-size: 1px; block-size: 1px;
                    overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.n-filter { position: relative; }
.n-filter input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.n-filter span {
  display: inline-flex; align-items: center; gap: var(--n-sp-3);
  min-block-size: 36px; padding-inline: var(--n-sp-7);
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-pill);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-caps); text-transform: uppercase;
  color: var(--n-text-muted); background: var(--n-surface-1);
  transition: color var(--n-dur-1) var(--n-ease-out),
              border-color var(--n-dur-1) var(--n-ease-out);
}
.n-filter input:hover + span { border-color: var(--n-line-strong); color: var(--n-text); }
.n-filter input:focus-visible + span { outline: var(--n-focus-w) solid var(--n-focus);
                                        outline-offset: var(--n-focus-offset); }
.n-filter input:checked + span {
  color: #FFFFFF; background-image: var(--n-grad-ink); border-color: transparent;
}
.n-filter b { font-weight: var(--n-fw-normal); opacity: .75; }

/* == 15 · PANNEAU VIDEO DOCUMENTE =========================================
   Le grand cadre de la section « pourquoi la montre ». La maquette y met
   une image ; on y met le clip, avec son cartouche technique — c'est la
   piece qui dit « ceci est un rendu, pas une photo de stock ».
   ========================================================================= */

.n-panel {
  position: relative; margin: 0;
  aspect-ratio: 16 / 10; overflow: hidden;
  border-radius: var(--n-r-3xl);
  background: var(--n-bg-deep);
  border: 1px solid var(--n-line-2);
  box-shadow: var(--n-shadow-4);
}
.n-panel--portrait { aspect-ratio: 9 / 16; max-inline-size: 420px; margin-inline: auto; }
.n-panel > img, .n-panel > video { inline-size: 100%; block-size: 100%; object-fit: cover; }
.n-panel > video { position: absolute; inset: 0; opacity: 0;
                   transition: opacity var(--n-dur-4) var(--n-ease-out); }
.n-panel[data-playing="true"] > video { opacity: 1; }

/* les quatre equerres : le cadre du plateau, pose sur le clip */
.n-panel__marks { position: absolute; inset: 16px; pointer-events: none; }
.n-panel__marks span {
  position: absolute; inline-size: 16px; block-size: 16px;
  border: 0 solid rgba(255,255,255,.7);
}
.n-panel__marks span:nth-child(1){inset-block-start:0;inset-inline-start:0;border-block-start-width:1.5px;border-inline-start-width:1.5px}
.n-panel__marks span:nth-child(2){inset-block-start:0;inset-inline-end:0;border-block-start-width:1.5px;border-inline-end-width:1.5px}
.n-panel__marks span:nth-child(3){inset-block-end:0;inset-inline-start:0;border-block-end-width:1.5px;border-inline-start-width:1.5px}
.n-panel__marks span:nth-child(4){inset-block-end:0;inset-inline-end:0;border-block-end-width:1.5px;border-inline-end-width:1.5px}

.n-panel__cap {
  position: absolute; inset: auto 16px 16px 16px;
  display: flex; justify-content: space-between; gap: var(--n-sp-5); flex-wrap: wrap;
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); color: #33333B;
}
.n-panel__cap span {
  padding: 5px 10px; border-radius: var(--n-r-pill);
  background: rgba(255,255,255,.9);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.n-panel__play {
  position: absolute; inset-block-start: 50%; inset-inline-start: 50%;
  transform: translate(-50%,-50%);
  inline-size: 64px; block-size: 64px;
  display: grid; place-items: center;
  border-radius: 50%; background: rgba(255,255,255,.94);
  color: #0B0B0F; cursor: pointer;
  box-shadow: var(--n-shadow-3);
  transition: transform var(--n-dur-2) var(--n-ease-out), opacity var(--n-dur-3) var(--n-ease-out);
}
.n-panel__play svg { inline-size: 20px; block-size: 20px; margin-inline-start: 3px; }
.n-panel__play:hover { transform: translate(-50%,-50%) scale(1.07); }
.n-panel[data-sound="true"] .n-panel__play { opacity: 0; pointer-events: none; }

/* == 16 · SPECIFICATIONS ================================================== */

.n-spec { margin: 0; display: grid; grid-template-columns: 1fr; }
.n-spec__row {
  display: grid; grid-template-columns: 1fr; gap: var(--n-sp-3);
  padding-block: var(--n-sp-7);
  border-block-start: 1px solid var(--n-line-2);
}
@media (min-width: 600px) {
  .n-spec__row { grid-template-columns: minmax(0,.7fr) minmax(0,1.3fr); gap: var(--n-sp-8);
                 align-items: baseline; }
}
.n-spec__label {
  font-family: var(--n-font-mono); font-size: var(--n-fs-2xs);
  letter-spacing: var(--n-ls-caps); text-transform: uppercase;
  color: var(--n-text-faint); margin: 0;
}
.n-spec__value { margin: 0; font-size: var(--n-fs-lg); letter-spacing: -0.015em;
                 color: var(--n-text); overflow-wrap: anywhere; }
/* ce qui n'est pas mesure se voit : c'est une dette, pas un ornement */
.n-spec__value[data-todo] {
  color: var(--n-warn); font-family: var(--n-font-mono);
  font-size: var(--n-fs-sm); border-block-end: 1px dashed var(--n-warn);
  display: inline-block;
}
.n-todo {
  display: inline-flex; align-items: baseline; gap: var(--n-sp-3);
  padding: 2px var(--n-sp-4); border: 1px dashed var(--n-warn);
  border-radius: var(--n-r-xs); background: var(--n-warn-soft);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); color: var(--n-warn);
}

/* == 17 · PALIERS =========================================================
   Quatre cartes, comme la maquette. Le drapeau du palier vedette est pose
   en absolu : il ne doit pas pousser sa colonne, sinon les quatre prix ne
   s'alignent plus et la grille cesse d'etre comparable.
   ========================================================================= */

.n-plans { display: grid; gap: var(--n-sp-6); grid-template-columns: 1fr; }
@media (min-width: 620px)  { .n-plans { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1080px) { .n-plans { grid-template-columns: repeat(4, minmax(0,1fr)); } }

.n-card-plan {
  position: relative; display: flex; flex-direction: column;
  padding: var(--n-sp-13) var(--n-sp-9) var(--n-sp-9);
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-2xl);
  background: var(--n-surface-1);
  transition: border-color var(--n-dur-3) var(--n-ease-out),
              box-shadow var(--n-dur-3) var(--n-ease-out);
}
.n-card-plan:hover { border-color: var(--n-line-accent); box-shadow: var(--n-shadow-4); }
.n-card-plan--featured { border-color: var(--n-line-accent); }
.n-card-plan__flag {
  position: absolute; inset-block-start: var(--n-sp-9); inset-inline-start: var(--n-sp-9);
  padding: 4px 9px; border-radius: var(--n-r-pill);
  color: #FFFFFF; background-image: var(--n-grad-ink);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); text-transform: uppercase;
}
.n-card-plan__name  { font-size: var(--n-fs-lg); font-weight: var(--n-fw-medium);
                      letter-spacing: -0.02em; color: var(--n-text); }
.n-card-plan__price { display: flex; align-items: baseline; gap: var(--n-sp-4);
                      margin-block: var(--n-sp-7) var(--n-sp-2); }
.n-card-plan__amount{ font-size: var(--n-fs-4xl); font-weight: var(--n-fw-medium);
                      letter-spacing: -0.045em; line-height: 1; color: var(--n-text); }
.n-card-plan__cycle { font-family: var(--n-font-mono); font-size: var(--n-fs-2xs);
                      letter-spacing: var(--n-ls-wide); text-transform: uppercase;
                      color: var(--n-text-faint); }
.n-card-plan__pitch { margin-block: var(--n-sp-7) var(--n-sp-8);
                      font-size: var(--n-fs-sm); line-height: 1.6;
                      color: var(--n-text-muted); text-wrap: pretty; }
.n-card-plan__features { display: flex; flex-direction: column; gap: var(--n-sp-5);
                         list-style: none; padding: 0; margin: 0 0 var(--n-sp-9); }
.n-card-plan__feature { display: flex; gap: var(--n-sp-5); align-items: flex-start;
                        font-size: var(--n-fs-sm); color: var(--n-text); }
.n-card-plan__feature svg { inline-size: 14px; block-size: 14px; flex: none;
                            margin-block-start: 4px; color: var(--n-accent); }
.n-card-plan__feature[data-included="false"] { color: var(--n-text-dim); }
.n-card-plan__feature[data-included="false"] svg { color: var(--n-text-disabled); }
.n-card-plan__cta { margin-block-start: auto; }
/* la jauge : ce que le palier achete, d'un coup d'oeil */
.n-quota { display: flex; flex-direction: column; gap: var(--n-sp-4);
           margin-block-end: var(--n-sp-8); }
.n-quota__label { display: flex; justify-content: space-between; gap: var(--n-sp-5);
                  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
                  letter-spacing: var(--n-ls-wide); text-transform: uppercase;
                  color: var(--n-text-faint); }
.n-quota__label b { color: var(--n-text); font-weight: var(--n-fw-medium); }
.n-quota__track { block-size: 3px; border-radius: 2px; background: var(--n-surface-3); }
.n-quota__bar   { block-size: 100%; border-radius: 2px; inline-size: var(--n-quota, 25%);
                  background-image: var(--n-grad); }
.n-quota--open .n-quota__bar {
  inline-size: 100%;
  background: repeating-linear-gradient(135deg, var(--n-line-3) 0 2px, transparent 2px 6px);
}

/* == 18 · APPEL FINAL & 19 · PIED DE PAGE ================================= */

.n-cta { position: relative; overflow: hidden; text-align: center;
         padding-block: var(--n-sp-15) var(--n-sp-16); isolation: isolate; }
.n-cta__inner { position: relative; max-inline-size: 900px; margin-inline: auto; }

.n-footer { padding-block: var(--n-sp-12) var(--n-sp-11);
            border-block-start: 1px solid var(--n-line); background: var(--n-bg); }
.n-footer__grid { display: grid; gap: var(--n-sp-10); grid-template-columns: 1fr; }
@media (min-width: 640px)  { .n-footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .n-footer__grid { grid-template-columns: minmax(0,1.4fr) repeat(3, minmax(0,.6fr)); } }
.n-footer__brand { display: flex; flex-direction: column; align-items: flex-start;
                   gap: var(--n-sp-6); }
.n-footer__pitch { max-inline-size: 38ch; font-size: var(--n-fs-xs); line-height: 1.6;
                   color: var(--n-text-dim); }
.n-footer__title { font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
                   letter-spacing: var(--n-ls-caps); text-transform: uppercase;
                   color: var(--n-text-faint); margin-block-end: var(--n-sp-6); }
.n-footer__list  { display: flex; flex-direction: column; gap: var(--n-sp-5); }
.n-footer__link  { font-size: var(--n-fs-xs); color: var(--n-text-muted); min-block-size: 24px;
                   transition: color var(--n-dur-1) var(--n-ease-out); }
.n-footer__link:hover { color: var(--n-accent-hi); }
.n-footer__bottom {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--n-sp-8); flex-wrap: wrap;
  margin-block-start: var(--n-sp-11); padding-block-start: var(--n-sp-8);
  border-block-start: 1px solid var(--n-line);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); text-transform: uppercase;
  color: var(--n-text-faint);
}
/* La signature de la maison : Numeri est un LOGICIEL edite par Odratta,
   donc « Developed by », jamais « Realise par ». */
.n-footer__by {
  display: inline-flex; align-items: baseline; gap: .45em;
  color: var(--n-text-faint); text-transform: none; letter-spacing: var(--n-ls-wide);
  transition: color var(--n-dur-1) var(--n-ease-out);
}
.n-footer__by:hover { color: var(--n-text); }
.n-footer__by svg { block-size: .85em; inline-size: auto; flex: none; opacity: .85; }
.n-footer__by:hover svg { opacity: 1; }

/* == 20 · COMPOSANTS DE L'APPLICATION (/app) ==============================
   Ils ne servent pas au vitrine mais app.css importe cette feuille et
   compte dessus. Les retirer casserait l'application.
   ========================================================================= */

.n-card { position: relative; background: var(--n-surface-1);
          border: 1px solid var(--n-line-2); border-radius: var(--n-r-2xl); overflow: hidden; }

.n-typeselect { border: 0; margin: 0; padding: 0; }
.n-typeselect__legend { padding: 0; margin-block-end: var(--n-sp-7);
  font-size: var(--n-fs-xs); font-weight: var(--n-fw-medium); color: var(--n-text-muted);
  letter-spacing: var(--n-ls-wide); text-transform: uppercase; }
.n-typeselect__grid { display: grid; gap: var(--n-sp-5); grid-template-columns: repeat(2, minmax(0,1fr)); }
@media (min-width: 768px) { .n-typeselect__grid { grid-template-columns: repeat(4, minmax(0,1fr)); } }
.n-typeopt { position: relative; }
.n-typeopt input { position: absolute; inset: 0; inline-size: 100%; block-size: 100%;
                   opacity: 0; margin: 0; cursor: pointer; }
.n-typeopt__face { position: relative; display: flex; flex-direction: column; gap: var(--n-sp-5);
  padding: var(--n-sp-8) var(--n-sp-7) var(--n-sp-7); min-block-size: 44px;
  background: var(--n-surface-1); border: 1px solid var(--n-line-2);
  border-radius: var(--n-r-xl);
  transition: border-color var(--n-dur-2) var(--n-ease-out),
              background-color var(--n-dur-2) var(--n-ease-out); }
.n-typeopt__icon { inline-size: 28px; block-size: 28px; color: var(--n-text-faint); }
.n-typeopt__name { font-size: var(--n-fs-sm); font-weight: var(--n-fw-medium); color: var(--n-text); }
.n-typeopt__note { font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
                   letter-spacing: var(--n-ls-wide); color: var(--n-text-faint);
                   text-transform: uppercase; }
.n-typeopt input:hover + .n-typeopt__face { border-color: var(--n-line-strong); }
.n-typeopt input:focus-visible + .n-typeopt__face { outline: var(--n-focus-w) solid var(--n-focus);
                                                    outline-offset: var(--n-focus-offset); }
.n-typeopt input:checked + .n-typeopt__face { border-color: var(--n-accent);
  box-shadow: inset 0 0 0 1px var(--n-accent); background: var(--n-accent-veil); }
.n-typeopt input:checked + .n-typeopt__face .n-typeopt__icon,
.n-typeopt input:checked + .n-typeopt__face .n-typeopt__note { color: var(--n-accent); }
.n-typeopt input:disabled + .n-typeopt__face { opacity: .45; cursor: not-allowed; }
/* la coche est un trait, pas une pastille : la selection ne repose jamais
   sur la seule couleur */
.n-typeopt input:checked + .n-typeopt__face::after {
  content: ""; position: absolute;
  inset-block-start: var(--n-sp-6); inset-inline-end: var(--n-sp-6);
  inline-size: 10px; block-size: 6px;
  border-inline-start: 1.5px solid var(--n-accent);
  border-block-end: 1.5px solid var(--n-accent);
  transform: rotate(-45deg);
}

.n-drop { position: relative; display: grid; place-items: center; gap: var(--n-sp-6);
  min-block-size: 260px; padding: var(--n-sp-11) var(--n-sp-7); text-align: center;
  background: var(--n-surface-1); border: 1px dashed var(--n-line-3);
  border-radius: var(--n-r-3xl);
  transition: border-color var(--n-dur-2) var(--n-ease-out),
              background-color var(--n-dur-2) var(--n-ease-out); }
.n-drop__input { position: absolute; inset: 0; inline-size: 100%; block-size: 100%;
                 opacity: 0; cursor: pointer; }
.n-drop__icon  { inline-size: 32px; block-size: 32px; color: var(--n-text-faint); }
.n-drop__title { font-size: var(--n-fs-lg); font-weight: var(--n-fw-medium); color: var(--n-text); }
.n-drop__hint  { font-family: var(--n-font-mono); font-size: var(--n-fs-2xs);
                 color: var(--n-text-dim); letter-spacing: var(--n-ls-wide); }
.n-drop:hover, .n-drop:focus-within { border-color: var(--n-accent-lo);
                                       background: var(--n-accent-veil); }
.n-drop[data-state="over"]  { border-color: var(--n-accent); background: var(--n-accent-soft); }
.n-drop[data-state="over"] .n-drop__icon { color: var(--n-accent); }
.n-drop[data-state="error"] { border-color: var(--n-danger); }
.n-drop[data-state="filled"]{ padding: var(--n-sp-6); min-block-size: 0; border-style: solid; }
.n-drop__preview { display: flex; gap: var(--n-sp-6); align-items: center;
                   inline-size: 100%; text-align: start; }
.n-drop__thumb { inline-size: 72px; block-size: 72px; flex: none; object-fit: cover;
                 border-radius: var(--n-r-md); background: var(--n-bg-deep);
                 border: 1px solid var(--n-line-2); }

.n-progress { display: flex; flex-direction: column; gap: var(--n-sp-5); }
.n-progress__head { display: flex; justify-content: space-between; align-items: baseline;
                    gap: var(--n-sp-6); }
.n-progress__step { font-size: var(--n-fs-sm); color: var(--n-text); }
.n-progress__pct  { font-family: var(--n-font-mono); font-size: var(--n-fs-sm);
                    color: var(--n-accent); font-variant-numeric: tabular-nums; }
.n-progress__track { position: relative; block-size: 3px; inline-size: 100%;
                     background: var(--n-surface-3); border-radius: 2px; overflow: hidden; }
.n-progress__bar { position: absolute; inset-block: 0; inset-inline-start: 0; inline-size: 100%;
                   background-image: var(--n-grad); transform-origin: left center;
                   transform: scaleX(var(--n-progress, 0));
                   transition: transform var(--n-dur-4) var(--n-ease-out); }
.n-progress[data-state="indeterminate"] .n-progress__bar {
  inline-size: 32%; transform: none; animation: n-sweep var(--n-dur-6) var(--n-ease-inout) infinite; }
.n-progress[data-state="done"]   .n-progress__bar { background: var(--n-ok); background-image: none; }
.n-progress[data-state="failed"] .n-progress__bar { background: var(--n-danger); background-image: none; }
.n-progress[data-state="done"]   .n-progress__pct { color: var(--n-ok); }
.n-progress[data-state="failed"] .n-progress__pct { color: var(--n-danger); }
.n-progress__foot { display: flex; justify-content: space-between; gap: var(--n-sp-6); }

.n-steps { display: flex; gap: var(--n-sp-5); flex-wrap: wrap; }
.n-step { display: flex; align-items: center; gap: var(--n-sp-4);
  font-family: var(--n-font-mono); font-size: var(--n-fs-3xs);
  letter-spacing: var(--n-ls-wide); text-transform: uppercase; color: var(--n-text-faint); }
.n-step::before { content: ""; inline-size: 6px; block-size: 6px; border-radius: 50%;
                  border: 1px solid currentColor; }
.n-step[data-state="active"] { color: var(--n-accent); }
.n-step[data-state="active"]::before { background: currentColor; }
.n-step[data-state="done"] { color: var(--n-ok); }
.n-step[data-state="done"]::before { background: currentColor; }

.n-player { position: relative; background: var(--n-bg-deep);
  border: 1px solid var(--n-line-2); border-radius: var(--n-r-2xl);
  overflow: hidden; aspect-ratio: 16 / 9; isolation: isolate; }
.n-player--portrait { aspect-ratio: 9 / 16; max-inline-size: 420px; }
.n-player--square   { aspect-ratio: 1 / 1; }
.n-player video { inline-size: 100%; block-size: 100%; object-fit: contain;
                  background: var(--n-bg-deep); }

.n-skeleton { position: relative; overflow: hidden; background: var(--n-surface-2);
              border-radius: var(--n-r-md); }
.n-skeleton::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(11,11,15,.05), transparent);
  transform: translateX(-100%); animation: n-sweep 1.4s var(--n-ease-inout) infinite; }

/* == 21 · ANIMATIONS ======================================================
   Regle unique : transform et opacity, rien d'autre. Une animation de
   width, top ou box-shadow ne passe pas par le compositeur et fait tomber
   sous 60 fps sur telephone.
   ========================================================================= */

@keyframes n-spin { to { transform: rotate(360deg); } }
@keyframes n-sweep { 0% { transform: translateX(-110%); } 100% { transform: translateX(360%); } }
@keyframes n-rise { from { opacity: 0; transform: translate3d(0,26px,0); } to { opacity: 1; transform: none; } }
@keyframes n-float { 0%,100% { transform: translate3d(0,0,0) scale(1); }
                     50% { transform: translate3d(0,-24px,0) scale(1.05); } }
@keyframes n-hint { 0%,100% { transform: translateY(0); opacity: .55; }
                    50% { transform: translateY(7px); opacity: 1; } }
@keyframes n-pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
@keyframes n-drift {
  from { transform: scale(1.06) translate3d(0, 0, 0); }
  to   { transform: scale(1.06) translate3d(0, -3.5%, 0); }
}
@keyframes n-marquee { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%,0,0); } }
@keyframes n-marquee-rev { from { transform: translate3d(-50%,0,0); } to { transform: translate3d(0,0,0); } }

/* Apparition au defilement. Le h1 du heros n'est JAMAIS anime : un titre
   anime plombe le LCP — mesure une fois a 1,3 s au lieu de 0,14 s. */
.n-reveal { opacity: 0; }
.n-reveal.is-in { animation: n-rise var(--n-dur-5) var(--n-ease-emph) both; }
.n-reveal[data-delay="1"].is-in { animation-delay: 70ms; }
.n-reveal[data-delay="2"].is-in { animation-delay: 140ms; }
.n-reveal[data-delay="3"].is-in { animation-delay: 210ms; }
.n-reveal[data-delay="4"].is-in { animation-delay: 280ms; }
.n-reveal[data-delay="5"].is-in { animation-delay: 350ms; }
.n-hero .n-h1, h1.n-reveal { opacity: 1; animation: none; }
/* l'entree du heros, elle, se joue en CSS pur : rien a attendre du JS */
.n-hero__pill  { animation: n-rise var(--n-dur-5) var(--n-ease-emph) both; }
.n-hero__lead  { animation: n-rise var(--n-dur-5) 120ms var(--n-ease-emph) both; }
.n-catch       { animation: n-rise var(--n-dur-5) 180ms var(--n-ease-emph) both; }

/* sans JavaScript, rien ne doit rester invisible */
.no-js .n-reveal { opacity: 1; animation: none; }

/* == 22 · PREFERS-REDUCED-MOTION ==========================================
   Tout s'eteint, rien ne disparait. Les bandeaux s'arretent, les videos ne
   partent pas seules, les etats de depart deviennent l'etat final.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    animation-delay: 0s !important; transition-duration: .001ms !important;
    transition-delay: 0s !important; scroll-behavior: auto !important;
  }
  .n-reveal, .n-reveal.is-in,
  .n-hero__pill, .n-hero__lead, .n-catch { opacity: 1; transform: none; animation: none; }
  .n-band__rail { animation: none; transform: none; }
  .n-mosaic { animation: none; }
  .n-band { -webkit-mask-image: none; mask-image: none; overflow-x: auto; }
  .n-blob { animation: none; }
  .n-hero__hint span { animation: none; }
  .n-telemetry__live::before { animation: none; }
  .n-progress[data-state="indeterminate"] .n-progress__bar {
    animation: none; inline-size: 100%; opacity: .5; }
  .n-btn[data-loading="true"]::after { animation: none; border-block-start-color: currentColor; }
  .n-tile:hover > img, .n-format:hover { transform: none; }
  .n-panel__play:hover { transform: translate(-50%,-50%); }
}

/* == 23 · UTILITAIRES ====================================================
   Ils existent pour UNE raison : la CSP du vhost refuse 'unsafe-inline',
   et un attribut style="" y est ignore SANS erreur — la page se decompose
   en silence et le defaut ne se voit qu'en production.
   Les valeurs d'INSTANCE (proportion d'un format, remplissage d'une jauge)
   passent donc aussi par une classe qui pose la variable.
   ========================================================================= */

.n-mt-5{margin-block-start:var(--n-sp-5)} .n-mt-6{margin-block-start:var(--n-sp-6)}
.n-mt-7{margin-block-start:var(--n-sp-7)} .n-mt-8{margin-block-start:var(--n-sp-8)}
.n-mt-9{margin-block-start:var(--n-sp-9)} .n-mt-10{margin-block-start:var(--n-sp-10)}
.n-mt-11{margin-block-start:var(--n-sp-11)} .n-mt-12{margin-block-start:var(--n-sp-12)}
.n-mt-auto{margin-block-start:auto}
.n-mb-6{margin-block-end:var(--n-sp-6)} .n-mb-7{margin-block-end:var(--n-sp-7)}
.n-mb-9{margin-block-end:var(--n-sp-9)} .n-mb-11{margin-block-end:var(--n-sp-11)}
.n-my-6{margin-block:var(--n-sp-6)} .n-my-7-9{margin-block:var(--n-sp-7) var(--n-sp-9)}
.n-my-6-9{margin-block:var(--n-sp-6) var(--n-sp-9)}
.n-my-6-11{margin-block:var(--n-sp-6) var(--n-sp-11)}
.n-m0{margin:0}
.n-measure-15{max-inline-size:15ch} .n-measure-20{max-inline-size:20ch}
.n-measure-24{max-inline-size:24ch} .n-measure-30{max-inline-size:30ch}
.n-measure-34{max-inline-size:34ch} .n-measure-38{max-inline-size:38ch}
.n-measure-48{max-inline-size:48ch} .n-measure-78{max-inline-size:78ch}
.n-center{text-align:center} .n-mx-auto{margin-inline:auto}
.n-hide{display:none!important}
@media (max-width:639.98px){ .n-only\@sm{display:none!important} }
.n-symbols{position:absolute;inline-size:0;block-size:0;overflow:hidden}
.n-honeypot{position:absolute;inset-inline-start:-9999px;inline-size:1px;block-size:1px;
            opacity:0;pointer-events:none}
.n-note{padding:var(--n-sp-9);margin-block-end:var(--n-sp-7)}
.n-note--ok{border-color:var(--n-ok)} .n-note--danger{border-color:var(--n-danger)}
.n-t-ok{color:var(--n-ok)} .n-t-danger{color:var(--n-danger)}
.n-grid-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--n-sp-6)}
.n-span-all{grid-column:1/-1}
.n-plain-list{list-style:none;padding:0;margin:0}

/* proportions vraies des six formats */
.n-ar-21x9{--n-fw:88px;--n-fh:38px} .n-ar-16x9{--n-fw:88px;--n-fh:50px}
.n-ar-4x3 {--n-fw:80px;--n-fh:60px} .n-ar-1x1 {--n-fw:68px;--n-fh:68px}
.n-ar-3x4 {--n-fw:58px;--n-fh:78px} .n-ar-9x16{--n-fw:50px;--n-fh:89px}
/* remplissage des jauges de palier */
.n-quota-25{--n-quota:25%} .n-quota-50{--n-quota:50%} .n-quota-100{--n-quota:100%}
