/* ============================================================
   ALYRIAZ - PREMIUM LAYER  ·  "Award-winning" overhaul
   Chargé APRÈS main.css + mobile.css : surcharge l'esthétique
   sans toucher au backend (Supabase / auth / rendu articles).
   ============================================================ */

/* ── Tokens premium ──────────────────────────────────────── */
:root {
  --ink:        #040409;
  --ink-2:      #07060f;
  --bg:         #050510;
  --surface:    #0a0a18;
  --surface2:   #11112a;
  --violet:     #7C3AED;
  --violet-lt:  #A78BFA;
  --cyan:       #22D3EE;
  --accent:     #7C3AED;
  --accent2:    #22D3EE;
  --text:       #F4F6FF;
  --muted:      #8A8FB0;
  --hair:       rgba(255,255,255,0.08);
  --hair-2:     rgba(255,255,255,0.04);
  --border:     rgba(124, 58, 237, 0.20);
  --glow:       rgba(124, 58, 237, 0.45);
  --radius:     14px;
  --radius-lg:  24px;
  --ease:       cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io:    cubic-bezier(0.83, 0, 0.17, 1);
  /* Largeur de contenu. Plafonnée à 1320 px, elle laissait deux marges
     vides énormes sur un écran très large — la grille d'articles restait
     au milieu avec trois cartes. On la laisse respirer jusqu'à 1760 px,
     ce qui donne 4 puis 5 colonnes, sans jamais toucher la ligne de
     lecture des articles (qui a sa propre largeur, bien plus étroite). */
  --maxw:       min(1760px, 92vw);
  --font-display: 'Syne', sans-serif;
  --font-body:    'Inter', sans-serif;
  --font-mono:    'JetBrains Mono', monospace;
}

html { scroll-behavior: smooth; }               /* scroll natif lisse (Lenis désactivé) */

body {
  background: var(--ink);
  color: var(--text);
  font-feature-settings: "ss01" on, "cv01" on;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Vignette + grain plus fin */
body::after {
  content: '';
  position: fixed; inset: 0;
  pointer-events: none; z-index: 9998;
  background: radial-gradient(130% 90% at 50% 0%, transparent 55%, rgba(0,0,0,0.55) 100%);
}

::selection { background: rgba(124,58,237,0.45); color: #fff; }
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(var(--violet), var(--cyan));
  border-radius: 8px;
}

/* Curseur "spotlight" optionnel (desktop) */
.cursor-glow {
  position: fixed; top: 0; left: 0;
  width: 420px; height: 420px; border-radius: 50%;
  background: radial-gradient(circle, rgba(124,58,237,0.16), transparent 60%);
  transform: translate(-50%, -50%);
  pointer-events: none; z-index: 5; mix-blend-mode: screen;
  transition: opacity .4s; opacity: 0;
}

/* Barre de progression de lecture */
.scroll-progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 1001;
  background: linear-gradient(90deg, var(--violet), var(--cyan));
  box-shadow: 0 0 14px var(--glow);
}

/* Couches de profondeur du hero (parallaxe) */
.hero-depth { position: absolute; inset: 0; z-index: 2; pointer-events: none; overflow: hidden; }
.h-orb { position: absolute; border-radius: 50%; filter: blur(70px); opacity: .55; mix-blend-mode: screen; will-change: transform; }
.h-orb-1 { width: 46vw; height: 46vw; left: -10vw; top: -12vw;
  background: radial-gradient(circle, rgba(124,58,237,0.55), transparent 65%); }
.h-orb-2 { width: 38vw; height: 38vw; right: -8vw; bottom: -10vw;
  background: radial-gradient(circle, rgba(34,211,238,0.45), transparent 65%); }
.h-orb-3 { width: 24vw; height: 24vw; right: 16vw; top: 6vw;
  background: radial-gradient(circle, rgba(167,139,250,0.42), transparent 60%); }

/* ════════════════════════════════════════════════════════════
   NAVBAR - top-bar premium
   ════════════════════════════════════════════════════════════ */
#navbar {
  height: 76px;
  padding: 0 clamp(18px, 4vw, 56px);
  mix-blend-mode: normal;
}
#navbar::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(4,4,9,0.55), transparent);
  opacity: 1; transition: opacity .4s; pointer-events: none;
}
#navbar.scrolled {
  height: 64px;
  background: rgba(6,6,16,0.72);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  border-bottom: 1px solid var(--hair);
}
#navbar.scrolled::before { opacity: 0; }

.nav-logo {
  font-size: 1.5rem; font-weight: 800; letter-spacing: -0.04em;
  background: none; -webkit-text-fill-color: currentColor; color: #fff;
  display: inline-flex; align-items: center; gap: 2px;
  transition: opacity .3s;
}
.nav-logo span { color: var(--violet-lt); -webkit-text-fill-color: var(--violet-lt); }
.nav-logo:hover { opacity: .85; }

.nav-links { gap: 6px; }
.nav-links a {
  position: relative;
  font-family: var(--font-mono);
  font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted);
  padding: 8px 14px; border-radius: 999px;
  transition: color .25s, background .25s;
  display: inline-flex; align-items: center; gap: 7px;
}
.nav-links a:hover { color: #fff; background: rgba(255,255,255,0.04); }
.nav-links a.active { color: #fff; }
.nav-links a.active::after {
  content: ''; position: absolute; left: 14px; right: 14px; bottom: 2px; height: 1px;
  background: linear-gradient(90deg, var(--violet), var(--cyan));
}

/* badge SOON sur l'onglet Lyriaz */
.nav-soon {
  font-family: var(--font-mono); font-size: 0.56rem; font-weight: 700;
  letter-spacing: 0.16em; padding: 3px 7px; border-radius: 6px;
  background: linear-gradient(120deg, var(--violet), var(--cyan));
  color: #fff; line-height: 1; transform: translateY(-1px);
  box-shadow: 0 0 14px rgba(124,58,237,0.55);
}

.nav-actions { gap: 12px; }
.nav-search-btn {
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--hair); background: rgba(255,255,255,0.02);
  color: var(--muted); display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all .25s;
}
.nav-search-btn:hover { color: #fff; border-color: var(--violet); box-shadow: 0 0 18px var(--glow); }

.nav-cta {
  font-family: var(--font-mono);
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em;
  padding: 10px 20px; border-radius: 999px;
  border: 1px solid transparent;
  background: linear-gradient(120deg, var(--violet), var(--cyan));
  color: #fff; position: relative; overflow: hidden;
}
.nav-cta::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(120deg, var(--cyan), var(--violet));
  opacity: 0; transition: opacity .3s;
}
.nav-cta span, .nav-cta { z-index: 1; }
.nav-cta:hover { box-shadow: 0 8px 30px rgba(124,58,237,0.5); transform: translateY(-1px); }

/* ════════════════════════════════════════════════════════════
   HERO CINÉMATIQUE
   ════════════════════════════════════════════════════════════ */
.hero {
  height: 100vh; min-height: 680px;
  align-items: flex-end;
  padding-bottom: clamp(48px, 9vh, 110px);
  justify-content: flex-start;
}

/* Vidéo / image de fond */
.hero-media {
  position: absolute; inset: 0; z-index: 0; overflow: hidden;
}
.hero-media video,
.hero-media img {
  position: absolute; inset: 0; width: 100%; height: 120%;
  object-fit: cover; object-position: center;
  will-change: transform;
}
.hero-media::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(to top, var(--ink) 2%, rgba(5,5,16,0.30) 45%, rgba(5,5,16,0.55) 100%),
    linear-gradient(to right, rgba(5,5,16,0.85) 0%, rgba(5,5,16,0.10) 55%, transparent 100%);
}
/* on garde le canvas neural mais discret, par-dessus la vidéo */
#neural-canvas { z-index: 1; opacity: 0.35; mix-blend-mode: screen; }
.hero-overlay { z-index: 1; background:
  radial-gradient(ellipse 70% 55% at 30% 60%, transparent 40%, var(--ink) 100%); }

.hero-content {
  text-align: left; z-index: 3;
  max-width: min(1100px, 92vw);
  margin: 0; width: 100%;
  padding: 0 clamp(18px, 5vw, 56px);
  margin-left: auto; margin-right: auto;
  will-change: transform, opacity;
}

.hero-eyebrow {
  font-size: 0.7rem; letter-spacing: 0.22em; color: var(--cyan);
  background: rgba(34,211,238,0.06); border-color: rgba(34,211,238,0.28);
  padding: 7px 16px; backdrop-filter: blur(6px);
}

.hero-title {
  font-size: clamp(2.9rem, 8.2vw, 7.6rem);
  font-weight: 800; letter-spacing: -0.045em; line-height: 0.96;
  margin: 22px 0 26px; max-width: 14ch;
}
.hero-title .line-accent {
  background: linear-gradient(100deg, var(--violet) 0%, var(--cyan) 60%, #fff 130%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
/* mots révélés par GSAP : masque */
.reveal-mask { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.08em; }
.reveal-mask > span { display: inline-block; will-change: transform; }

.hero-sub {
  font-size: clamp(1rem, 1.5vw, 1.22rem); color: var(--muted);
  max-width: 52ch; margin: 0 0 38px; line-height: 1.7;
}
.hero-cta-group { justify-content: flex-start; }

.btn-primary {
  border-radius: 999px; padding: 16px 34px; font-size: 0.92rem;
  background: linear-gradient(120deg, var(--violet), var(--cyan));
  box-shadow: 0 10px 40px rgba(124,58,237,0.45);
}
.btn-primary:hover { transform: translateY(-3px) scale(1.01); box-shadow: 0 16px 56px rgba(124,58,237,0.6); }
.btn-ghost {
  border-radius: 999px; padding: 16px 30px; border-color: var(--hair);
  backdrop-filter: blur(8px); background: rgba(255,255,255,0.02);
}
.btn-ghost:hover { border-color: var(--cyan); background: rgba(34,211,238,0.06); }

.hero-scroll {
  left: auto; right: clamp(18px, 5vw, 56px); bottom: 40px; transform: none;
  font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.2em;
  align-items: flex-end;
}
.hero-scroll::after { background: linear-gradient(to bottom, var(--cyan), transparent); height: 56px; }

/* ════════════════════════════════════════════════════════════
   TICKER kinétique
   ════════════════════════════════════════════════════════════ */
.ticker-wrap {
  border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair);
  background: linear-gradient(90deg, var(--ink), var(--surface), var(--ink));
  overflow: hidden;
}
.ticker-label {
  background: linear-gradient(120deg, var(--violet), var(--cyan)) !important;
  color: #fff !important; font-family: var(--font-mono);
  letter-spacing: 0.18em; font-weight: 700;
}
.ticker-item {
  font-family: var(--font-display); font-weight: 700; letter-spacing: -0.01em;
  text-transform: none;
}
.ticker-item::before { color: var(--violet-lt) !important; }

/* ════════════════════════════════════════════════════════════
   SHOWCASE / sections parallaxe sur-mesure
   ════════════════════════════════════════════════════════════ */
.px-section { position: relative; padding: clamp(90px, 14vh, 200px) 0; overflow: hidden; }
.px-inner { max-width: var(--maxw); margin: 0 auto; padding: 0 clamp(18px, 5vw, 56px); }

.eyebrow-line {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--cyan); margin-bottom: 22px;
}

.display-h2 {
  font-size: clamp(2rem, 5vw, 4.2rem); font-weight: 800;
  letter-spacing: -0.04em; line-height: 1.02; margin-bottom: 26px;
}
.display-h2 em {
  font-style: normal;
  background: linear-gradient(100deg, var(--violet), var(--cyan));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.lead { font-size: clamp(1.02rem, 1.5vw, 1.22rem); color: var(--muted); max-width: 56ch; line-height: 1.75; }

/* Section "Intelligence" : orbe pinné + texte */
.orb-stage { position: relative; min-height: 100vh; display: grid; place-items: center; }
.orb-wrap {
  position: relative; width: clamp(280px, 42vw, 620px); aspect-ratio: 1;
  will-change: transform;
}
.orb-wrap img {
  width: 100%; height: 100%; object-fit: contain;
  mix-blend-mode: screen;          /* le fond noir du rendu devient transparent */
  filter: drop-shadow(0 0 80px rgba(124,58,237,0.5)) saturate(1.1);
}
.orb-halo {
  position: absolute; inset: -12%; border-radius: 50%;
  background: radial-gradient(circle, rgba(34,211,238,0.18), transparent 62%);
  filter: blur(40px); z-index: -1;
}
.orb-caption {
  position: absolute; max-width: 30ch; z-index: 4;
}
.orb-caption.tl { top: 8%; left: 0; text-align: left; }
.orb-caption.br { bottom: 8%; right: 0; text-align: right; }
.orb-caption h4 { font-size: 1.15rem; margin-bottom: 6px; }
.orb-caption p { font-size: 0.9rem; color: var(--muted); }

/* Pellicule de chiffres (stats) */
.stat-strip {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(12px, 2vw, 28px); margin-top: 64px;
}
.stat-cell {
  border: 1px solid var(--hair); border-radius: var(--radius);
  padding: 26px 22px; background: rgba(255,255,255,0.015);
  backdrop-filter: blur(6px);
}
.stat-cell .num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 4vw, 3.4rem); letter-spacing: -0.03em; line-height: 1;
  background: linear-gradient(120deg, #fff, var(--violet-lt));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.stat-cell .lbl {
  margin-top: 10px; font-family: var(--font-mono); font-size: 0.68rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}

/* Bandes "manifeste" défilant horizontalement (pin) */
.manifesto-track {
  display: flex; gap: clamp(24px, 4vw, 80px); white-space: nowrap;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.4rem, 7vw, 6rem); letter-spacing: -0.03em;
  will-change: transform;
}
.manifesto-track span { color: transparent; -webkit-text-stroke: 1px rgba(255,255,255,0.22); }
.manifesto-track span.fill {
  -webkit-text-stroke: 0;
  background: linear-gradient(100deg, var(--violet), var(--cyan));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}

/* ════════════════════════════════════════════════════════════
   PRINCIPES - cartes premium (réutilise .principles-bar markup)
   ════════════════════════════════════════════════════════════ */
.principles-bar {
  grid-template-columns: repeat(4, 1fr); gap: 18px;
  border: none; background: transparent;
  max-width: var(--maxw); margin: 0 auto; padding: 0 clamp(18px,5vw,56px) 40px;
}
.principle-item {
  flex-direction: column; gap: 16px; border: 1px solid var(--hair);
  border-radius: var(--radius); padding: 30px 26px;
  background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent);
  transition: transform .5s var(--ease), border-color .4s, background .4s;
}
.principle-item:hover {
  transform: translateY(-8px); border-color: var(--border);
  background: linear-gradient(180deg, rgba(124,58,237,0.10), transparent);
}
.principle-icon { font-size: 2.2rem; }
.principle-text h3 { font-size: 1.05rem; }

/* ════════════════════════════════════════════════════════════
   SECTION ARTICLES - restylage premium des cartes (app.js)
   ════════════════════════════════════════════════════════════ */
.section-title { font-family: var(--font-mono); letter-spacing: 0.18em; }
.section-title span { background: linear-gradient(120deg,#fff,var(--violet-lt));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent; }

.filter-btn { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em; }
.filter-btn.active { background: linear-gradient(120deg, var(--violet), var(--cyan)); border-color: transparent; }

#articles-grid { gap: 22px; }

.article-card {
  background: var(--surface); border: 1px solid var(--hair);
  border-radius: var(--radius-lg);
}
.article-card::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  padding: 1px; background: linear-gradient(130deg, var(--violet), transparent 40%, var(--cyan));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity .4s;
}
.article-card:hover::after { opacity: .9; }
.article-card:hover {
  border-color: transparent;
  box-shadow: 0 24px 60px rgba(0,0,0,0.55), 0 0 40px rgba(124,58,237,0.18);
}
/* Hauteur PROPORTIONNELLE et non figee : a 188 px de haut dans une
   carte large de 821 px, la vignette devenait un bandeau de 3,4:1
   pendant que ses voisines etaient en 16:9. Avec `aspect-ratio` la
   vignette suit la largeur de sa carte, quel que soit le nombre de
   colonnes que la grille decide de faire. */
.card-thumb { aspect-ratio: 16 / 9; height: auto; }
.article-card.wide .card-thumb { aspect-ratio: 21 / 9; height: auto; }
.card-title { letter-spacing: -0.02em; }

.featured-card {
  border-radius: var(--radius-lg); border: 1px solid var(--hair); overflow: hidden;
  background: var(--surface);
}
.featured-title { font-size: clamp(2rem, 4vw, 3.4rem); letter-spacing: -0.03em; }

/* ════════════════════════════════════════════════════════════
   FOOTER premium
   ════════════════════════════════════════════════════════════ */
footer {
  border-top: 1px solid var(--hair);
  background: linear-gradient(180deg, transparent, rgba(124,58,237,0.05));
  margin-top: 40px;
}
.footer-cta {
  max-width: var(--maxw); margin: 0 auto; padding: clamp(70px,10vh,140px) clamp(18px,5vw,56px) 60px;
  text-align: center;
}
.footer-cta h2 {
  font-size: clamp(2.4rem, 6vw, 5.4rem); font-weight: 800; letter-spacing: -0.04em; line-height: 1;
}
.footer-cta h2 em { font-style: normal;
  background: linear-gradient(100deg, var(--violet), var(--cyan));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent; }
.footer-cta p { color: var(--muted); margin: 22px auto 36px; max-width: 50ch; }

/* ════════════════════════════════════════════════════════════
   REVEAL utilitaires (GSAP ajoute .is-in)
   ════════════════════════════════════════════════════════════ */
[data-reveal] { opacity: 0; transform: translateY(40px); }
.no-motion [data-reveal] { opacity: 1 !important; transform: none !important; }

/* ════════════════════════════════════════════════════════════
   PAGE LYRIAZ - teaser SOON
   ════════════════════════════════════════════════════════════ */
.lyriaz-stage {
  position: relative; min-height: 100vh; display: grid; place-items: center;
  overflow: hidden; text-align: center;
}
.lyriaz-bg { position: absolute; inset: 0; z-index: 0; }
.lyriaz-bg img { width: 100%; height: 100%; object-fit: cover; opacity: .55; }
.lyriaz-bg::after { content:''; position:absolute; inset:0;
  background: radial-gradient(ellipse 60% 60% at 50% 45%, transparent 30%, var(--ink) 85%); }
.lyriaz-inner { position: relative; z-index: 2; padding: 0 24px; }
/* voile sombre doux derrière le texte pour la lisibilité sur le visuel lumineux */
.lyriaz-inner::before {
  content: ''; position: absolute; left: 50%; top: 52%; transform: translate(-50%, -50%);
  width: min(760px, 94vw); height: 118%; z-index: -1; pointer-events: none;
  background: radial-gradient(ellipse 60% 52% at 50% 50%, rgba(4,4,9,0.86), rgba(4,4,9,0) 72%);
  filter: blur(22px);
}
.lyriaz-kicker {
  font-family: var(--font-mono); letter-spacing: 0.4em; text-transform: uppercase;
  font-size: 0.74rem; color: var(--cyan); margin-bottom: 28px;
}
.lyriaz-word {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(3.4rem, 16vw, 13rem); letter-spacing: -0.04em; line-height: 0.9;
  background: linear-gradient(100deg, #fff 0%, var(--violet-lt) 50%, var(--cyan) 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.lyriaz-soon {
  display: inline-block; margin-top: 22px; padding: 8px 22px; border-radius: 999px;
  font-family: var(--font-mono); letter-spacing: 0.3em; font-size: 0.78rem; font-weight: 700;
  border: 1px solid var(--border); background: rgba(124,58,237,0.1); color: #fff;
}
.lyriaz-sub {
  color: #DCE0F0; max-width: 46ch; margin: 30px auto 0; line-height: 1.75;
  font-size: 1.02rem; text-shadow: 0 2px 26px rgba(0,0,0,0.9);
}
.lyriaz-form { display:flex; gap:10px; justify-content:center; margin-top:34px; flex-wrap:wrap; }
.lyriaz-form input {
  background: rgba(8,8,18,0.62); border: 1px solid rgba(255,255,255,0.18); color: #fff;
  padding: 14px 20px; border-radius: 999px; min-width: 280px; font-size: 0.95rem; outline: none;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.lyriaz-form input::placeholder { color: rgba(226,230,246,0.62); }
.lyriaz-form input:focus { border-color: var(--cyan); background: rgba(8,8,18,0.78); }

/* ════════════════════════════════════════════════════════════
   PAGE ACTUALITÉ - hero cinématique + timeline lumineuse
   ════════════════════════════════════════════════════════════ */
.actu-hero {
  position: relative; min-height: 88vh; display: flex; align-items: flex-end;
  overflow: hidden; padding: 0 clamp(18px,5vw,56px) clamp(100px,17vh,210px);
}
/* Réseau neuronal animé PAR-DESSUS la vidéo du hero */
.actu-hero .actu-hero-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1;
  opacity: .5; mix-blend-mode: screen; pointer-events: none;
}
.actu-hero .actu-bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.actu-hero .actu-bg img,
.actu-hero .actu-bg video { width: 100%; height: 116%; object-fit: cover; opacity: 1; will-change: transform; }
/* Dégradé : sombre à gauche (sous le texte) + bas, mais DROITE claire (vidéo visible). */
.actu-hero::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to top, var(--ink) 0%, rgba(5,5,16,0.18) 42%, transparent 72%),
    linear-gradient(to right, rgba(5,5,16,0.82) 0%, rgba(5,5,16,0.20) 50%, transparent 82%);
}
.actu-hero #neural-canvas { z-index: 1; opacity: .35; mix-blend-mode: screen; }
.actu-hero-inner { position: relative; z-index: 3; max-width: var(--maxw); margin: 0 auto; width: 100%; }

.actu-live {
  display: inline-flex; align-items: center; gap: 11px; margin-bottom: 24px;
  font-family: var(--font-mono); letter-spacing: 0.24em; text-transform: uppercase;
  font-size: 0.72rem; color: var(--cyan);
}
.actu-live .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--cyan);
  box-shadow: 0 0 0 0 rgba(34,211,238,0.6); animation: livePulse 2.2s infinite; }
@keyframes livePulse {
  0%   { box-shadow: 0 0 0 0 rgba(34,211,238,0.55); }
  70%  { box-shadow: 0 0 0 15px rgba(34,211,238,0); }
  100% { box-shadow: 0 0 0 0 rgba(34,211,238,0); }
}
.actu-hero h1 {
  font-size: clamp(2.9rem, 9vw, 7rem); font-weight: 800; letter-spacing: -0.045em; line-height: 0.94;
}
.actu-hero h1 em { font-style: normal;
  background: linear-gradient(100deg, var(--violet), var(--cyan) 60%, #fff 130%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.actu-hero .actu-sub {
  color: #C9CEE6; max-width: 54ch; margin-top: 24px; font-size: clamp(1rem,1.4vw,1.15rem);
  line-height: 1.7; text-shadow: 0 2px 24px rgba(0,0,0,0.7);
}
.actu-scroll {
  position: absolute; right: clamp(18px,5vw,56px); bottom: 38px; z-index: 3;
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted); display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
.actu-scroll::after { content: ''; width: 1px; height: 52px; background: linear-gradient(var(--cyan), transparent);
  animation: bounce 2.5s ease infinite; }

/* Section feed avec fond "réseaux neuronaux animés" */
.news-section { position: relative; overflow: visible; }
/* Bande de flou qui fond la vidéo (hero) et l'image (feed) au raccord */
.news-section::before {
  content: ''; position: absolute; left: 0; right: 0; top: -72px; height: 150px; z-index: 4;
  pointer-events: none;
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  -webkit-mask: linear-gradient(to bottom, transparent, #000 38%, #000 62%, transparent);
          mask: linear-gradient(to bottom, transparent, #000 38%, #000 62%, transparent);
}
.news-bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.news-bg img { width: 100%; height: 100%; object-fit: cover; opacity: .3; }
.news-bg video { width: 100%; height: 100%; object-fit: cover; opacity: .6; }
.news-bg #neural-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: .6; mix-blend-mode: screen;
}
.news-bg::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, transparent 0%, rgba(5,5,16,0.30) 14%, rgba(5,5,16,0.30) 86%, var(--ink) 100%);
}
.news-wrap { position: relative; z-index: 1; max-width: var(--maxw); margin: 0 auto; padding: clamp(40px,7vh,90px) clamp(18px,5vw,56px) 130px; }

/* Carte "à la une" (actu la plus récente) */
.news-featured {
  position: relative; display: grid; grid-template-columns: 220px 1fr; gap: clamp(24px,4vw,56px);
  align-items: center; border: 1px solid var(--hair); border-radius: var(--radius-lg);
  padding: clamp(28px,4vw,52px); margin-bottom: 56px; overflow: hidden;
  background: radial-gradient(120% 140% at 0% 0%, rgba(124,58,237,0.16), transparent 55%),
              radial-gradient(120% 140% at 100% 100%, rgba(34,211,238,0.12), transparent 55%),
              var(--surface);
  transition: transform .5s var(--ease), box-shadow .4s;
}
.news-featured:hover { transform: translateY(-6px); box-shadow: 0 30px 80px rgba(0,0,0,0.55), 0 0 50px rgba(124,58,237,0.2); }
.news-featured .nf-date {
  font-family: var(--font-mono); color: var(--cyan); font-size: 0.8rem; letter-spacing: 0.08em;
}
.news-featured .nf-date .day {
  display: block; font-family: var(--font-display); font-weight: 800;
  font-size: clamp(3.5rem,7vw,5.5rem); line-height: 0.9; margin-top: 6px;
  background: linear-gradient(120deg,#fff,var(--violet-lt));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.news-featured h2 { font-size: clamp(1.8rem,3.4vw,2.8rem); letter-spacing: -0.03em; margin: 14px 0 14px; line-height: 1.05; }
.news-featured p { color: var(--muted); line-height: 1.75; font-size: 1.02rem; max-width: 60ch; }

/* Timeline */
.news-timeline { position: relative; padding-left: 42px; }
.news-timeline::before {
  content: ''; position: absolute; left: 12px; top: 14px; bottom: 14px; width: 2px;
  background: linear-gradient(180deg, var(--violet), var(--cyan) 60%, transparent);
  opacity: .55;
}
.news-row {
  position: relative; border: 1px solid var(--hair); border-radius: var(--radius-lg);
  padding: 26px 30px; background: var(--surface); margin-bottom: 18px; overflow: hidden;
  transition: transform .5s var(--ease), border-color .4s, box-shadow .4s;
}
.news-row::before {
  content: ''; position: absolute; left: -36px; top: 30px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--ink); border: 2px solid var(--cyan); box-shadow: 0 0 16px rgba(34,211,238,0.7);
}
.news-row::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; padding: 1px;
  background: linear-gradient(130deg, var(--violet), transparent 45%, var(--cyan));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity .4s;
}
.news-row:hover { transform: translateX(6px); box-shadow: 0 20px 50px rgba(0,0,0,0.5); }
.news-row:hover::after { opacity: .9; }
.news-row .nr-date { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.08em; color: var(--cyan); margin-bottom: 6px; }
.news-row h3 { font-size: 1.4rem; letter-spacing: -0.02em; margin-bottom: 8px; }
.news-row p { color: var(--muted); line-height: 1.7; }

.news-tag {
  display:inline-block; margin-bottom:12px; padding: 4px 12px; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.12em; text-transform: uppercase;
  border: 1px solid var(--border); color: var(--violet-lt); background: rgba(124,58,237,0.08);
}
.news-link {
  display:inline-flex; align-items:center; gap:7px; margin-top:16px;
  font-weight:700; font-size:0.86rem; color: var(--cyan);
}
.news-link .arrow { transition: transform .25s; }
.news-row:hover .news-link .arrow, .news-featured:hover .news-link .arrow { transform: translateX(5px); }

@media (max-width: 760px) {
  .actu-hero { min-height: 78vh; padding-bottom: clamp(40px,7vh,80px); }
  .actu-hero h1 {
    font-size: clamp(2.1rem, 10.5vw, 4rem);
    word-break: normal; overflow-wrap: normal; hyphens: none;
  }
  .actu-scroll { display: none; }
  .news-featured { grid-template-columns: 1fr; gap: 14px; }
  .news-featured .nf-date { display: flex; align-items: baseline; gap: 12px; }
  .news-featured .nf-date .day { font-size: 2.4rem; margin: 0; }
  .news-timeline { padding-left: 30px; }
  .news-row::before { left: -24px; }
}

/* ════════════════════════════════════════════════════════════
   RESPONSIVE
   ════════════════════════════════════════════════════════════ */
@media (max-width: 980px) {
  .stat-strip { grid-template-columns: repeat(2, 1fr); }
  .orb-caption { position: static; text-align: center !important; max-width: none; margin: 18px auto; }
  .orb-stage { gap: 10px; }
}
@media (max-width: 860px) {
  /* la nav top-bar : on cache les liens, hamburger prend le relais (déjà géré par mobile.css) */
  .hero { align-items: center; padding-bottom: 0; text-align: center; }
  .hero-content { text-align: center; }
  .hero-title { max-width: none; }
  .hero-sub { margin-left: auto; margin-right: auto; }
  .hero-cta-group { justify-content: center; }
  .hero-media video, .hero-media img { height: 100%; }
  .news-card { grid-template-columns: 1fr; gap: 14px; }
  .news-date { border-right: none; border-bottom: 1px solid var(--hair); padding: 0 0 14px;
    display:flex; align-items:baseline; gap: 12px; }
  .news-date .day { font-size: 1.8rem; margin: 0; }
  .principles-bar { grid-template-columns: repeat(2,1fr); }
}
@media (max-width: 600px) {
  .hero-title {
    font-size: clamp(1.55rem, 8.2vw, 3rem);
    word-break: normal; overflow-wrap: normal; hyphens: none;
    line-height: 1.02;
  }
  .reveal-mask { white-space: nowrap; }
  .stat-strip { grid-template-columns: 1fr 1fr; }
  .manifesto-track { font-size: clamp(2rem, 11vw, 3.4rem); }
}

/* ════════════════════════════════════════════════════════════
   ACCUEIL v3 - sections immersives (parallaxe multi-couches)
   ════════════════════════════════════════════════════════════ */
.immersive {
  position: relative; min-height: 100vh; display: flex; align-items: center;
  justify-content: center; overflow: hidden; text-align: center;
  perspective: 1300px;                 /* profondeur Z réelle pour le scroll-jacking */
}
.immersive-bg, .immersive-inner { transform-style: preserve-3d; will-change: transform, opacity; }
.immersive-tall { min-height: 110vh; }
.immersive-bg { position: absolute; inset: -14% 0; z-index: 0; }
.immersive-bg img,
.immersive-bg video { width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.immersive-veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(ellipse 78% 70% at 50% 50%, transparent 28%, rgba(4,4,9,0.80) 100%),
    linear-gradient(to bottom, var(--ink), transparent 22%, transparent 78%, var(--ink));
}
.immersive-veil.strong {
  background:
    radial-gradient(ellipse 85% 75% at 50% 50%, rgba(4,4,9,0.30) 18%, rgba(4,4,9,0.82) 100%),
    linear-gradient(to bottom, var(--ink), transparent 18%, transparent 74%, var(--ink));
}
.immersive-inner { position: relative; z-index: 2; max-width: 1000px; padding: 0 24px; }
.immersive-inner.wide { max-width: var(--maxw); }
.immersive-title {
  font-size: clamp(2.1rem, 6.6vw, 5.8rem); font-weight: 800; letter-spacing: -0.04em; line-height: 1.0;
  text-shadow: 0 4px 50px rgba(0,0,0,0.5);
}
.immersive-title em {
  font-style: normal;
  background: linear-gradient(100deg, var(--violet), var(--cyan));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
/* lettres assemblées (split JS) - mots insécables */
.immersive-title .word { display: inline-block; white-space: nowrap; }
.immersive-title .ltr { display: inline-block; will-change: transform, opacity; }
.immersive-title .ltr-grad {
  background: linear-gradient(100deg, var(--violet), var(--cyan));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.immersive-lead {
  color: #C9CEE6; max-width: 50ch; margin: 22px auto 0;
  font-size: clamp(1rem, 1.4vw, 1.2rem); line-height: 1.7; text-shadow: 0 2px 24px rgba(0,0,0,0.7);
}
.immersive .stat-strip { margin-top: 52px; }
.immersive .stat-cell { background: rgba(8,8,18,0.5); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }

/* eyebrow centré (avec tiret de chaque côté) */
.eyebrow-line.center { justify-content: center; }

/* En-tête "bibliothèque" de la section articles */
.articles-intro { text-align: center; margin-bottom: 52px; }
.articles-intro .eyebrow-line { justify-content: center; margin-bottom: 18px; }
.articles-intro .display-h2 { margin: 0 auto; }

@media (max-width: 600px) {
  .immersive-title { font-size: clamp(2rem, 9.5vw, 4rem); word-break: normal; overflow-wrap: normal; }
  .immersive { min-height: 84vh; }
  .immersive-tall { min-height: auto; padding: clamp(70px,12vh,120px) 0; }
}

/* ════════════════════════════════════════════════════════════
   HERO - plongée vortex (perspective 3D) + typo glow/sheen
   ════════════════════════════════════════════════════════════ */
/* Le voyage a sa propre section, tout en bas de ce fichier. */

.hero { perspective: 1300px; }
.hero-content { transform-style: preserve-3d; }
/* Le poster du vortex EST le fond : il s'affiche pendant que la vidéo
   charge, et reste seul sur mobile, où la vidéo n'est jamais demandée.
   Le dégradé sous-jacent couvre le tout premier instant. */
.hero-media {
  transform-origin: 50% 50%;
  background: radial-gradient(ellipse at 60% 42%, #160a2e, var(--ink) 72%);
}
.hero-media::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: url('../assets/home-vortex.webp?v=54dbca7e') center center / cover no-repeat;
}
.hero-media video { z-index: 1; }

/* Masque de révélation par mot (voir splitMots dans premium.js). Le mot
   monte depuis sous sa propre ligne ; sans `overflow: hidden` sur le
   masque, on le verrait arriver de plus bas au lieu de le voir surgir. */
.mot-masque { display: inline-block; overflow: hidden; vertical-align: bottom; }
.mot { display: inline-block; will-change: transform; }
.hero-title { text-shadow: 0 0 70px rgba(124,58,237,0.40); }
.hero-title .reveal-mask.glow-on { overflow: visible; }   /* glow visible après reveal */
.hero-title .line-accent {
  background: linear-gradient(100deg, var(--violet) 0%, var(--cyan) 38%, #ffffff 58%, var(--violet-lt) 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 26px rgba(124,58,237,0.65));
  animation: heroSheen 5.5s linear infinite;
}
@keyframes heroSheen { to { background-position: -250% 0; } }

/* ════════════════════════════════════════════════════════════
   WORD-STACK cinétique (mot central géant qui glow)
   ════════════════════════════════════════════════════════════ */
.wordstack {
  position: relative; min-height: 92vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 34px; overflow: hidden;
  padding: clamp(60px,10vh,120px) 0;
}
.wordstack-eyebrow {
  font-family: var(--font-mono); letter-spacing: 0.32em; text-transform: uppercase;
  font-size: 0.74rem; color: var(--cyan);
}
.wordstack-viewport {
  position: relative; width: 100%; height: 1.25em; overflow: hidden;
  font-size: clamp(2.8rem, 12vw, 10rem);
  display: flex; align-items: center; justify-content: center;
}
.wordstack-word {
  display: inline-block; line-height: 1.1; text-align: center;
  font-family: var(--font-display); font-weight: 800; letter-spacing: -0.03em;
  background: linear-gradient(100deg, #fff 0%, var(--violet-lt) 45%, var(--cyan) 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 50px rgba(124,58,237,0.7));
  will-change: transform, opacity;
}

/* Respect prefers-reduced-motion - on garde la vidéo de fond (mouvement doux
   voulu), on neutralise seulement les animations CSS agressives. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* ════════════════════════════════════════════════════════════
   MOBILE - hamburger, menu, barre du bas (raccord avec la DA)
   ════════════════════════════════════════════════════════════ */
/* Hamburger : pastille ronde en verre, ligne → croix */
.hamburger {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--hair); background: rgba(255,255,255,0.04);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  padding: 0;
}
.hamburger span { display:block; width: 18px; height: 2px; border-radius: 2px;
  background: var(--text); transition: transform .3s var(--ease), opacity .25s; }
.hamburger.open { background: linear-gradient(120deg, var(--violet), var(--cyan)); border-color: transparent; }
.hamburger.open span { background: #fff; }
.hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger.open span:nth-child(2) { opacity: 0; }
.hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ── Menu burger : verre liquide ──────────────────────────────
   Repris de l'application mobile, dont la matière est meilleure que ce
   que le site avait ici : un aplat sombre, des filets gris, et rien qui
   rappelait le violet et le cyan du reste du site.

   Ce qui fait le verre, et qu'il ne faut pas simplifier :
   1. un dégradé à TROIS arrêts, clair en haut, presque nul au milieu,
      légèrement repris en bas. C'est lui qui donne la courbure ;
   2. une teinte violet→cyan par-dessus, très basse en opacité ;
   3. un liseré blanc d'un pixel à l'intérieur du bord (inset box-shadow),
      qui simule l'arête éclairée ;
   4. un reflet spéculaire qui balaie UNE FOIS à l'ouverture.

   Le flou reste modéré. L'application porte cet avertissement, et il
   vaut ici : trop de flou moyenne tout le fond en une teinte unie, la
   surface paraît OPAQUE alors qu'elle est floutée. Un verre qu'on
   reconnaît laisse deviner ce qui bouge derrière. */

/* Le voile derrière le panneau s'assombrit un peu, et floute davantage.
   Le panneau étant devenu presque transparent, c'est ce voile qui fait
   maintenant le contraste : sans lui, le site continuerait de se lire à
   travers le menu au lieu de passer au second plan. */
.mobile-menu-backdrop {
  background:
    radial-gradient(120% 80% at 100% 0%, rgba(124,58,237,0.24), transparent 60%),
    rgba(4,4,9,0.72);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}

.mobile-menu-panel {
  /* Le fond sombre est passé de 0,90 à 0,34 puis à 0,12.

     C'est la composition de l'application, relue dans son composant
     Glass : il n'y a AUCUNE couche opaque. Le verre y est fait d'un
     flou, d'un voile blanchâtre à très basse opacité et d'une bordure.
     Rien d'autre. Un fond sombre, même à 0,34, transforme la surface en
     mur peint pour ressembler à du verre.

     Ce qui rend lisible ici, ce n'est donc pas un aplat, c'est le FLOU :
     à 40 px, ce qui passe derrière est réduit à des taches de couleur.
     Les liens, eux, portent leur propre fond, un cran plus dense — c'est
     sur eux que le texte se lit, pas sur le panneau. */
  background:
    linear-gradient(160deg, rgba(124,58,237,0.26) 0%, rgba(124,58,237,0.06) 42%, rgba(6,182,212,0.13) 100%),
    linear-gradient(180deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0.035) 46%, rgba(255,255,255,0.07) 100%),
    linear-gradient(180deg, rgba(12,10,26,0.12), rgba(6,6,16,0.18));
  backdrop-filter: blur(40px) saturate(180%); -webkit-backdrop-filter: blur(40px) saturate(180%);
  border-left: 1px solid rgba(167,139,250,0.30);
  border-radius: 26px 0 0 26px;
  box-shadow:
    inset 1px 0 0 rgba(255,255,255,0.16),
    inset 0 1px 0 rgba(255,255,255,0.10),
    -26px 0 70px rgba(0,0,0,0.55);
  padding: 88px 22px 32px;
  overflow: hidden;
}

/* Le reflet : un seul passage, à l'ouverture. Pas de boucle — une
   animation permanente sur un élément fixe se recompose indéfiniment. */
.mobile-menu-panel::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(112deg, transparent 34%, rgba(255,255,255,0.13) 50%, transparent 66%);
  transform: translateX(-140%);
}
.mobile-menu.open .mobile-menu-panel::after {
  animation: menuReflet 1.15s cubic-bezier(.22,1,.36,1) .12s both;
}
@keyframes menuReflet { to { transform: translateX(140%); } }

.mobile-menu-label {
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--violet-lt); opacity: .9;
  margin-bottom: 12px; padding-left: 8px;
  /* Ces libellés sont le seul texte posé DIRECTEMENT sur le verre, sans
     surface derrière. Le panneau étant devenu très transparent, une
     ombre portée les décolle de ce qui défile dessous. */
  text-shadow: 0 1px 6px rgba(0,0,0,0.55);
}

/* Chaque lien est une petite surface, pas une ligne séparée d'un filet.
   C'est la différence de rendu la plus visible avec l'application. */
.mobile-menu-link {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  padding: 13px 14px; margin-bottom: 7px;
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 15px;
  /* Un cran plus dense que le panneau. Celui-ci étant devenu très
     transparent, des liens aussi transparents que lui se perdraient
     dans ce qui défile derrière : c'est le contraste entre les deux
     surfaces qui rend le menu lisible. */
  background: linear-gradient(180deg, rgba(255,255,255,0.09), rgba(255,255,255,0.028));
  font-family: var(--font-display); font-weight: 700; font-size: 1.16rem;
  letter-spacing: -0.02em; color: var(--text);
  transition: transform .22s cubic-bezier(.22,1,.36,1), border-color .22s, background .22s;
}
.mobile-menu-link:hover, .mobile-menu-link:active {
  color: #fff;
  border-color: rgba(167,139,250,0.44);
  background: linear-gradient(180deg, rgba(124,58,237,0.24), rgba(124,58,237,0.06));
  transform: translateX(-3px);
}
.mobile-menu-link .link-icon {
  font-size: 1rem; width: 30px; height: 30px; flex: 0 0 30px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9px; opacity: .95;
  background: rgba(124,58,237,0.16);
  border: 1px solid rgba(167,139,250,0.24);
}
.mobile-user-section .mobile-menu-link { font-size: 1rem; font-family: var(--font-body); font-weight: 600; }

/* Entrée en cascade : les liens arrivent APRÈS le panneau, l'un après
   l'autre. Sans cela le menu apparaît d'un bloc, ce qui est exactement
   le reproche fait à l'ouverture de Mnémosyne. */
.mobile-menu .mobile-menu-link,
.mobile-menu .mobile-menu-label {
  opacity: 0; transform: translateX(16px);
  transition: opacity .32s ease, transform .32s cubic-bezier(.22,1,.36,1);
}
.mobile-menu.open .mobile-menu-link,
.mobile-menu.open .mobile-menu-label { opacity: 1; transform: none; }
/* Les délais portent sur la position DANS la section, sans supposer
   qu'un libellé occupe la première place : la section du compte en a un,
   celle de la navigation non. On couvre donc les deux cas avec la même
   série, et une section absente ne coûte rien. */
.mobile-menu.open .mobile-menu-link:nth-child(1) { transition-delay: .10s; }
.mobile-menu.open .mobile-menu-link:nth-child(2) { transition-delay: .145s; }
.mobile-menu.open .mobile-menu-link:nth-child(3) { transition-delay: .19s; }
.mobile-menu.open .mobile-menu-link:nth-child(4) { transition-delay: .235s; }
.mobile-menu.open .mobile-menu-link:nth-child(5) { transition-delay: .28s; }
.mobile-menu.open .mobile-menu-link:nth-child(6) { transition-delay: .325s; }
.mobile-menu.open .mobile-menu-link:nth-child(7) { transition-delay: .37s; }
.mobile-menu.open .mobile-menu-link:nth-child(8) { transition-delay: .415s; }
/* La section du compte vient en dernier visuellement : on la retarde
   d'un cran pour qu'elle se pose après la navigation. */
.mobile-menu.open .mobile-user-section .mobile-menu-link { transition-delay: .46s; }

@media (prefers-reduced-motion: reduce) {
  .mobile-menu .mobile-menu-link,
  .mobile-menu .mobile-menu-label { opacity: 1; transform: none; transition: none; }
  .mobile-menu.open .mobile-menu-panel::after { animation: none; }
}

/* Barre du bas : verre + bulle dégradée */
.bottom-nav {
  background: rgba(8,8,18,0.72); backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%); border-top: 1px solid var(--hair);
}
.bottom-nav-item { color: var(--muted); transition: color .25s; }
.bottom-nav-item span { font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.08em; }
.bottom-nav-item.active { color: #fff; }
.bottom-nav-item.active svg { filter: drop-shadow(0 0 8px var(--glow)); }
.bnav-bubble {
  background: linear-gradient(120deg, var(--violet), var(--cyan)) !important;
  box-shadow: 0 8px 26px var(--glow); border: none;
}

/* ── Réglages MOBILE de l'accueil ────────────────────────────── */
@media (max-width: 760px) {
  /* Chiffres compacts (pour tenir dans l'écran) */
  .immersive .stat-strip { margin-top: 18px; gap: 10px; grid-template-columns: 1fr 1fr; }
  .immersive .stat-cell { padding: 12px 10px; }
  .stat-cell .num { font-size: clamp(1.6rem, 7vw, 2.3rem) !important; }
  .stat-cell .lbl { font-size: 0.58rem; }
  /* sous-texte de la vague RÉ-AFFICHÉ sur mobile (compact pour tenir avec les chiffres) */
  #scene-2 .immersive-lead { display: block; margin: 12px auto 0; font-size: 0.86rem; max-width: 92vw; }

  /* anti-coupure : on réduit les très gros titres pour que les mots tiennent */
  .immersive-title { font-size: clamp(1.9rem, 8.5vw, 3.4rem); line-height: 1.04; }
  .wordstack-viewport { font-size: clamp(2.2rem, 13vw, 4.4rem); }
  .wordstack-word { word-break: normal; overflow-wrap: normal; hyphens: none; }
  .immersive-lead { font-size: 1rem; max-width: 90vw; }
  .display-h2 { font-size: clamp(1.9rem, 8vw, 3.2rem); }

  /* hamburger un peu plus présent */
  .hamburger { display: inline-flex; }

  /* ════ PERF MOBILE : suppression des effets GPU coûteux pendant le scroll ════ */
  /* 3 orbes en blur(70px)+mix-blend qui bougent en parallaxe = compositing très lourd.
     Le vortex fournit déjà le halo → on les retire entièrement. */
  .hero-depth { display: none !important; }

  /* backdrop-filter sur des éléments FIXES = re-flou de tout l'arrière-plan À CHAQUE frame
     de scroll (l'un des effets les plus chers sur mobile) → fond opaque à la place. */
  #navbar { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: rgba(8,8,18,0.92) !important; }
  .bottom-nav { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: rgba(8,8,18,0.95) !important; }
  .immersive .stat-cell { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: rgba(8,8,18,0.72) !important; }
  .hero-eyebrow, .btn-ghost { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }

  /* ════ LES TROIS VRAIS COUPABLES DU SCROLL SACCADE ════
     Mesurés sur l'accueil en 412 px de large, 138 articles chargés. */

  /* 1. 276 backdrop-filter. Chaque carte porte deux boutons (aimer,
        partager) en blur(8px) : le compositeur doit ré-échantillonner
        et reflouter l'arrière-plan de CHACUN à chaque image de scroll.
        C'est l'effet le plus cher qui existe sur mobile, et il est ici
        invisible — les boutons sont déjà posés sur du sombre. Fond
        opaque à la place : le rendu ne bouge pas. */
  .article-card .social-btn,
  .card-social-bar {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    background: rgba(10, 10, 20, 0.78) !important;
  }

  /* 2. 138 couches GPU permanentes. `will-change: transform` sur chaque
        carte sert à fluidifier l'animation de SURVOL, qui n'existe pas
        au doigt. Sur téléphone ce sont donc 138 textures gardées en
        mémoire graphique pour rien. */
  .article-card { will-change: auto !important; }

  /* 3. Les 138 cartes sont toutes mises en page et peintes, y compris
        les ~130 hors écran. `content-visibility` laisse le navigateur
        sauter ce travail tant qu'une carte n'approche pas du viewport ;
        `contain-intrinsic-size` lui donne la hauteur à réserver en
        attendant (vignette 16:9 + corps), sans quoi la position de
        défilement sauterait. */
  .article-card {
    content-visibility: auto;
    contain-intrinsic-size: auto 360px;
  }

  /* suppression des filtres lourds restants (vortex/orbes/titres) */
  .orb-halo { filter: none !important; display: none !important; }
  .orb-wrap img { filter: none !important; }
  .hero-title .line-accent { filter: none !important; }
  .wordstack-word { filter: none !important; }
  /* Le flou est trop cher sur mobile, mais un fond plein le remplaçait par un gros bloc opaque
     qui masquait l'image. À la place : un vignettage radial (sans flou) qui assombrit derrière
     le texte tout en laissant respirer l'image autour. */
  .lyriaz-inner::before {
    filter: none !important;
    width: min(680px, 92vw) !important; height: 96% !important;
    background: radial-gradient(ellipse 66% 56% at 50% 48%, rgba(4,4,9,0.82) 0%, rgba(4,4,9,0.5) 46%, rgba(4,4,9,0) 78%) !important;
  }

  /* INVISIBLE : will-change sur ~52 lettres = 52 couches GPU permanentes que le mobile
     doit composer en continu. En 'auto', l'anim est IDENTIQUE mais le compositing est allégé. */
  .immersive-title .ltr { will-change: auto !important; }

  /* Même raison, un cran au-dessus : .immersive-inner ne bouge PAS lui-même
     (ce sont ses lettres et ses chiffres qui sont animés), mais son will-change
     le promeut quand même en couche GPU plein écran, gardée en mémoire du début
     à la fin. Deux scènes = deux couches inutiles à composer à chaque frame. */
  .immersive-inner { will-change: auto !important; }

  /* Le fond, lui, EST animé (ken-burns) : on garde sa promotion, mais on retire
     `opacity` du will-change — c'est .jplan qui porte le fondu, pas le fond. */
  .immersive-bg { will-change: transform !important; }

  /* GROS GAIN INVISIBLE : en portrait, `cover` n'affiche déjà QUE la bande
     centrale de ces posters 1600x905 — tout le reste est décodé puis jeté.
     On sert donc directement cette bande, découpée depuis le JPG d'origine :
     à l'écran c'est identique, mais 2,2x moins de pixels à décoder et à
     composer pendant le scroll, sur les DEUX scènes.
     (!important : la valeur d'origine est en style inline dans index.html.) */
  #scene-1 .immersive-bg { background-image: url('../assets/home-monolith-mobile.webp?v=7a074293') !important; }
  #scene-2 .immersive-bg { background-image: url('../assets/home-wave-mobile.webp?v=7648d018') !important; }
  /* Même raison pour le vortex du hero, qui ne charge jamais sa vidéo ici. */
  .hero-media::before { background-image: url('../assets/home-vortex-mobile.webp?v=396b2565'); }

  /* INVISIBLE : le fond était surdimensionné (-14% => ~28% de pixels en trop) pour une parallaxe
     yPercent inexistante ici. Le ken-burns part du centre (object-fit:cover) => inset:0 = identique
     à l'écran mais bien moins de pixels à décoder/composer. */
  .immersive-bg { inset: 0 !important; }

  /* INVISIBLE & GROS GAIN : les scènes ont perspective + preserve-3d, mais leurs titres n'utilisent
     QUE des transforms 2D (x, y, rotation 2D, scale) - aucun enfant n'a de profondeur Z. Ce contexte
     3D ne change donc RIEN à l'écran mais oblige le GPU mobile à composer 2 plans 3D plein écran en
     continu. On l'aplatit POUR LES SCÈNES UNIQUEMENT (le hero garde sa 3D => plongée intacte). */
  .immersive { perspective: none !important; }
  .immersive-bg, .immersive-inner { transform-style: flat !important; }

  /* La vidéo du vortex faisait 120 % de la hauteur du cadre, pour une
     parallaxe verticale qui n'existe plus. Combiné au zoom de la
     plongée, cela donnait la plus grosse texture de toute la page. */
  .hero-media video, .hero-media img { height: 100%; }

  /* Une ombre portée de 50 px de flou est héritée par CHAQUE lettre du
     titre. Au moment où les vingt-huit se rassemblent, ce sont
     vingt-huit rendus de glyphe ET de flou large à produire d'un coup,
     et c'est là que l'à-coup se sent. Une ombre courte et franche est
     tout aussi lisible sur un fond vidéo sombre, pour une fraction du
     prix. */
  .immersive-title, .immersive-title .ltr, .immersive-title .word {
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.85) !important;
  }

  /* LE RETRAIT DU POSTER DOIT ÊTRE RÉÉCRIT ICI, AVEC LE MÊME POIDS.

     Les deux règles au-dessus visent `#scene-1` et `#scene-2` par
     identifiant, et en `!important`. Une règle de classe, même en
     `!important`, ne peut pas les battre : l'identifiant l'emporte. La
     classe `sans-poster` était donc bien posée, et le poster restait
     affiché quand même — sans que rien ne le signale.

     C'est exactement le piège déjà noté dans A-DEPLOYER.md : vérifier
     la valeur CALCULÉE avant de conclure qu'une règle s'applique. */
  #scene-1 .immersive-bg.sans-poster,
  #scene-2 .immersive-bg.sans-poster { background-image: none !important; }
}

/* Le poster sous une vidéo qui tourne ne sert plus à rien, et il
   occupe une texture pleine page par plan. On le retire dès que la
   première image de la vidéo est arrivée — et lui seul, pas la couleur
   de fond, qui reste utile si la vidéo se met en pause. La classe est
   posée par `load()` dans js/premium.js. */
.immersive-bg.sans-poster { background-image: none !important; }
.hero-media.sans-poster::before { display: none; }

/* ════════════════════════════════════════════════════════════
   DOSSIERS THÉMATIQUES · bandeau accueil (injecté par js/dossiers.js,
   absent tant que la table Supabase est vide)
   ════════════════════════════════════════════════════════════ */
.dossier-strip-wrap { max-width: var(--maxw); margin: 34px auto 10px; padding: 0 24px; }
.dossier-strip-head {
  font-size: 0.9rem; color: var(--muted); margin-bottom: 16px;
  display: flex; align-items: center; gap: 12px;
}
.dossier-strip-head .k {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--cyan); border: 1px solid rgba(34,211,238,0.35); border-radius: 999px; padding: 5px 13px;
}
.dossier-strip {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
}
.dossier-chip {
  display: flex; flex-direction: column; gap: 8px; text-decoration: none; color: var(--text);
  padding: 20px 22px; border-radius: 18px;
  background: linear-gradient(160deg, color-mix(in srgb, var(--dc) 10%, transparent), rgba(255,255,255,0.015));
  border: 1px solid color-mix(in srgb, var(--dc) 30%, transparent);
  transition: transform .22s var(--ease), border-color .22s, box-shadow .22s;
}
.dossier-chip:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--dc) 60%, transparent);
  box-shadow: 0 18px 46px rgba(0,0,0,0.4), 0 0 30px color-mix(in srgb, var(--dc) 14%, transparent);
}
.dossier-chip .t { font-family: var(--font-display); font-size: 1.08rem; font-weight: 800; letter-spacing: -0.01em; line-height: 1.25; }
.dossier-chip .d {
  font-size: 0.82rem; color: var(--muted); line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.dossier-chip .m {
  margin-top: auto; padding-top: 6px; font-family: var(--font-mono); font-size: 0.64rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: color-mix(in srgb, var(--dc) 85%, #fff);
}
/* ── Le dossier en fin d'article ─────────────────────────────
   Une seule carte, pleine largeur, à l'endroit où le lecteur vient de
   finir et se demande quoi lire ensuite. C'est le remplacement du
   bandeau d'accueil, qui coûtait de la hauteur à tout le monde pour
   ne servir qu'à quelques-uns. */
.dossier-fin { max-width: 880px; margin: 40px auto 0; padding: 0 clamp(16px, 4vw, 48px); }
.dossier-fin .dossier-chip { padding: 22px 24px; gap: 9px; }
.dossier-fin .dossier-chip .k {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: color-mix(in srgb, var(--dc) 85%, #fff);
}
.dossier-fin .dossier-chip .t { font-size: 1.25rem; }
.dossier-fin .dossier-chip .d { -webkit-line-clamp: 3; }
@media (max-width: 640px) {
  .dossier-fin { margin-top: 30px; }
  .dossier-fin .dossier-chip { padding: 18px 18px; }
  .dossier-fin .dossier-chip .t { font-size: 1.08rem; }
  /* Pas de survol au doigt : cette transform ne ferait que promouvoir
     la carte en couche GPU. */
  .dossier-fin .dossier-chip:hover { transform: none; box-shadow: none; }
}

/* Sur mobile, trois cartes empilées de 130 px chacune s'intercalaient
   entre l'en-tête « bibliothèque » et les articles : près de 500 px à
   faire défiler avant d'atteindre le premier article, pour trois
   collections de six articles. Verdict du propriétaire : « leur place
   dans le site bof, sur mobile encore moins ».
   On passe donc en RAIL HORIZONTAL : une carte et demie visible, le
   reste se fait glisser au doigt. La section garde sa visibilité mais
   ne coûte plus qu'une seule hauteur de carte. */
@media (max-width: 860px) {
  .dossier-strip-wrap { margin: 22px auto 4px; padding: 0; }
  .dossier-strip-head { padding: 0 20px; margin-bottom: 12px; font-size: 0.84rem; }

  .dossier-strip {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding: 2px 20px 6px;
    /* La barre de défilement horizontale ferait tache sous les cartes. */
    scrollbar-width: none;
  }
  .dossier-strip::-webkit-scrollbar { display: none; }

  .dossier-chip {
    flex: 0 0 76%;            /* la carte suivante dépasse : on voit qu'il y en a d'autres */
    scroll-snap-align: start;
    padding: 15px 17px;
    gap: 6px;
  }
  .dossier-chip .t { font-size: 0.98rem; }
  .dossier-chip .d { font-size: 0.78rem; -webkit-line-clamp: 2; }
  /* Le survol n'existe pas au doigt : cette transform ne sert qu'à
     promouvoir la carte en couche GPU pour rien. */
  .dossier-chip:hover { transform: none; box-shadow: none; }
}

/* ============================================================
   RECHERCHE UNIVERSELLE (js/search.js)
   Palette cosmique, panneau centré au bureau, plein écran mobile.
   ============================================================ */
html.aq-lock, html.aq-lock body { overflow: hidden; }

.aq {
  position: fixed; inset: 0; z-index: 9995;
  display: flex; align-items: flex-start; justify-content: center;
  padding: min(12vh, 110px) 20px 20px;
}
.aq[hidden] { display: none; }
.aq-backdrop {
  position: absolute; inset: 0;
  background: radial-gradient(1200px 600px at 50% -10%, rgba(124,58,237,0.16), transparent 62%), rgba(4,4,12,0.86);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  opacity: 0; transition: opacity .22s ease;
}
.aq.on .aq-backdrop { opacity: 1; }

.aq-panel {
  position: relative; width: min(720px, 100%);
  max-height: min(72vh, 680px);
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, rgba(18,16,42,0.98), rgba(9,9,20,0.99));
  border: 1px solid rgba(124,58,237,0.34);
  border-radius: 22px;
  box-shadow: 0 40px 120px rgba(0,0,0,0.65), 0 0 60px rgba(124,58,237,0.14);
  overflow: hidden;
  opacity: 0; transform: translateY(-14px) scale(0.98);
  transition: opacity .24s ease, transform .28s cubic-bezier(0.23,1,0.32,1);
}
.aq.on .aq-panel { opacity: 1; transform: translateY(0) scale(1); }

.aq-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid rgba(124,58,237,0.18);
  flex-shrink: 0;
}
.aq-loupe { width: 20px; height: 20px; color: #8B5CF6; flex-shrink: 0; }
#aq-input {
  flex: 1; min-width: 0; background: none; border: none; outline: none;
  color: var(--text); font-family: var(--font-body); font-size: 1.06rem; padding: 6px 0;
}
#aq-input::placeholder { color: #5A5F7D; }
#aq-input::-webkit-search-cancel-button { -webkit-appearance: none; }
.aq-x {
  background: rgba(124,58,237,0.12); border: 1px solid rgba(124,58,237,0.28);
  color: #C4B5FD; font-family: var(--font-mono); font-size: 0.7rem;
  padding: 7px 12px; border-radius: 9px; cursor: pointer; flex-shrink: 0;
  transition: background .2s, color .2s;
}
.aq-x:hover { background: rgba(124,58,237,0.24); color: #fff; }

.aq-results { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 8px; }
.aq-group {
  padding: 12px 12px 6px; font-family: var(--font-mono); font-size: 0.62rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: #6B7194;
}
.aq-item {
  display: flex; align-items: center; gap: 13px;
  padding: 11px 12px; border-radius: 13px; text-decoration: none;
  color: var(--text); border: 1px solid transparent;
  -webkit-tap-highlight-color: transparent;
}
.aq-item.on, .aq-item:hover {
  background: rgba(124,58,237,0.13);
  border-color: rgba(124,58,237,0.32);
}
.aq-ic {
  width: 34px; height: 34px; flex-shrink: 0; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--c) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--c) 34%, transparent);
  color: var(--c);
}
.aq-ic svg { width: 17px; height: 17px; }
.aq-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.aq-t {
  font-weight: 650; font-size: 0.93rem; line-height: 1.35;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.aq-d {
  font-size: 0.78rem; color: #8A90AE; line-height: 1.45;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.aq-item mark { background: rgba(124,58,237,0.34); color: #EDE9FE; border-radius: 3px; padding: 0 1px; }
.aq-meta {
  flex-shrink: 0; font-family: var(--font-mono); font-size: 0.62rem;
  color: #6B7194; letter-spacing: 0.04em; max-width: 34%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.aq-hint, .aq-empty {
  padding: 40px 24px; text-align: center; color: var(--muted); font-size: 0.88rem;
  display: flex; flex-direction: column; gap: 8px;
}
.aq-empty strong { color: var(--text); font-size: 0.95rem; font-weight: 650; }
.aq-empty a { color: #A78BFA; }

.aq-foot {
  display: flex; align-items: center; gap: 18px; flex-shrink: 0;
  padding: 10px 18px; border-top: 1px solid rgba(124,58,237,0.16);
  font-size: 0.7rem; color: #6B7194;
}
.aq-foot kbd {
  display: inline-block; min-width: 18px; text-align: center;
  padding: 2px 5px; margin-right: 3px; border-radius: 5px;
  background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1);
  font-family: var(--font-mono); font-size: 0.66rem; color: #A5ABCB;
}
.aq-count { margin-left: auto; font-family: var(--font-mono); }

@media (max-width: 760px) {
  .aq { padding: 0; align-items: stretch; }
  .aq-panel {
    width: 100%; max-height: 100%; height: 100%;
    border-radius: 0; border: none; transform: translateY(18px);
  }
  .aq-bar { padding: 14px 16px; padding-top: max(14px, env(safe-area-inset-top)); }
  .aq-foot { display: none; }
  .aq-meta { display: none; }
  .aq-item { padding: 12px 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .aq-panel, .aq-backdrop { transition: none; }
}

/* ── Verre liquide ─────────────────────────────────────────────────
   Transposition de la surface `Glass` de l'application mobile
   (`src/components/Glass.tsx` et `src/theme.ts`) : même dégradé violet
   vers cyan, même bordure, même reflet spéculaire qui balaie.

   Le flou reste modéré, et c'est délibéré. Poussé plus haut, il moyenne
   tout le fond en une teinte unie : la surface paraît alors OPAQUE alors
   qu'elle est bel et bien floutée. Le thème de l'application le note noir
   sur blanc après s'être fait prendre ; le piège est identique ici. */
.verre {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(167, 139, 250, 0.38);
  background: linear-gradient(135deg,
    rgba(124, 58, 237, 0.22) 0%,
    rgba(124, 58, 237, 0.05) 55%,
    rgba(6, 182, 212, 0.10) 100%);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), 0 8px 26px rgba(4, 4, 12, 0.5);
}
/* Le reflet qui balaie. En `::after` et non en élément : la surface doit
   rester posable telle quelle sur n'importe quelle balise. */
.verre::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.16) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: verre-reflet 7s ease-in-out 1.5s infinite;
}
@keyframes verre-reflet {
  0%, 72%   { transform: translateX(-120%); }
  86%, 100% { transform: translateX(120%); }
}
@media (prefers-reduced-motion: reduce) {
  .verre::after { animation: none; opacity: 0; }
}
/* Un flou en temps réel coûte cher sur téléphone, et il y est de toute
   façon presque invisible : fond plein à la place. */
@media (max-width: 760px) {
  .verre {
    -webkit-backdrop-filter: none; backdrop-filter: none;
    background: linear-gradient(135deg, rgba(58, 31, 118, 0.92), rgba(14, 16, 34, 0.92));
  }
}

/* L'onglet de l'application. Il ne ressemble pas aux autres entrées du
   menu, et c'est le but : ce n'est pas une section de plus du site, c'est
   quelque chose à installer. */
.nav-app {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 14px; border-radius: 999px;
  color: #EDE9FE !important; font-weight: 600;
}
.nav-app svg { width: 14px; height: 14px; flex: none; }
.nav-app:hover { color: #fff !important; }
.mobile-menu-link.nav-app { justify-content: center; margin-top: 6px; }

/* Plusieurs liens sur une même actu : ils passent en ligne et se
   replient si l'écran est étroit, au lieu de s'empiler en colonne. */
.news-links { display: flex; flex-wrap: wrap; gap: 10px 22px; }

/* ── Dossiers de l'Académie ───────────────────────────────────
   Quatre portes au lieu de vingt et une cartes. Les cartes sont larges
   et respirent : ce sont des décisions, pas des articles qu'on parcourt
   du regard. */
.ac-dossiers {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
  gap: 16px; margin-bottom: 22px;
}
.ac-dossier {
  position: relative; display: flex; flex-direction: column; gap: 10px;
  padding: 26px 28px 22px; border-radius: 20px; text-decoration: none; color: var(--text);
  background:
    linear-gradient(165deg, color-mix(in srgb, var(--cc) 11%, transparent), rgba(255,255,255,0.015));
  border: 1px solid color-mix(in srgb, var(--cc) 26%, transparent);
  transition: transform .25s var(--ease), border-color .25s, box-shadow .25s;
}
.ac-dossier:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--cc) 55%, transparent);
  box-shadow: 0 18px 50px rgba(0,0,0,0.4), 0 0 34px color-mix(in srgb, var(--cc) 16%, transparent);
}
.ac-dossier h3 {
  font-family: var(--font-display); font-size: 1.42rem; font-weight: 800;
  letter-spacing: -0.025em; color: #fff;
}
.ac-dossier p { color: #B7BDD8; font-size: 0.89rem; line-height: 1.65; margin: 0; }
.ac-dossier .niveaux { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.ac-dossier .niveaux span {
  padding: 3px 10px; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.56rem; letter-spacing: 0.1em;
  text-transform: uppercase; font-weight: 700;
  color: var(--cc); background: color-mix(in srgb, var(--cc) 14%, transparent);
}
.ac-dossier .chiffres { font-family: var(--font-mono); font-size: 0.68rem; color: var(--muted); }
.ac-dossier .chiffres b { color: #fff; }
.ac-dossier .cta {
  margin-top: auto; padding-top: 8px;
  font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.12em;
  text-transform: uppercase; font-weight: 700; color: var(--cc);
}

/* En-tête à l'intérieur d'un dossier */
.ac-dossier-head { max-width: 62ch; margin: 0 0 30px; }
.ac-dossier-head h2 {
  font-family: var(--font-display); font-size: clamp(1.7rem, 4vw, 2.3rem);
  font-weight: 800; letter-spacing: -0.03em; margin-bottom: 8px;
}
.ac-dossier-head p { color: #B7BDD8; font-size: 0.96rem; line-height: 1.7; margin-bottom: 10px; }
.ac-dossier-head .chiffres {
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--cc);
}

/* Séparateur de niveau, à l'intérieur du dossier « Apprendre l'IA ».
   Plus fort que l'intertitre de thème : le niveau est une marche, le
   thème n'est qu'un chemin à l'intérieur d'une marche. */
.ac-niveau {
  grid-column: 1 / -1; display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 34px 0 4px; padding: 14px 20px; border-radius: 14px;
  background: color-mix(in srgb, var(--cc) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--cc) 24%, transparent);
}
.ac-niveau:first-child { margin-top: 0; }
.ac-niveau h3 {
  font-family: var(--font-display); font-size: 1.3rem; font-weight: 800;
  letter-spacing: -0.02em; color: #fff; margin: 0;
}
.ac-niveau .cert {
  margin-left: auto; flex-shrink: 0; text-decoration: none;
  padding: 8px 16px; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.1em;
  text-transform: uppercase; font-weight: 700; color: var(--cc);
  border: 1px solid color-mix(in srgb, var(--cc) 40%, transparent);
  background: rgba(0,0,0,0.2); transition: background .2s;
}
.ac-niveau .cert:hover { background: color-mix(in srgb, var(--cc) 22%, transparent); }
@media (max-width: 600px) { .ac-niveau .cert { margin-left: 0; } }

/* Intertitre de thème dans le catalogue de l'Académie. Il occupe toute
   la largeur de la grille : c'est lui qui découpe une longue liste de
   cartes en parcours lisibles. */
.ac-theme {
  grid-column: 1 / -1;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin: 26px 0 2px; padding-bottom: 10px;
  border-bottom: 1px solid var(--hair);
  font-family: var(--font-display); font-size: 1.18rem; font-weight: 800;
  letter-spacing: -0.02em; color: #fff;
}
.ac-theme:first-child { margin-top: 0; }
.ac-theme .niv {
  font-family: var(--font-mono); font-size: 0.58rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px;
  color: var(--cc); background: color-mix(in srgb, var(--cc) 13%, transparent);
}
/* Quiz de révision du thème, à droite de l'intertitre. Poussé au bout de
   la ligne par `margin-left:auto` : c'est une porte de sortie, pas un
   titre, et il ne doit pas concurrencer le nom du thème. */
.ac-theme .rev {
  margin-left: auto; flex-shrink: 0;
  font-family: var(--font-mono); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  padding: 6px 14px; border-radius: 999px; color: var(--cc);
  border: 1px solid color-mix(in srgb, var(--cc) 34%, transparent);
  background: color-mix(in srgb, var(--cc) 8%, transparent);
  transition: background .18s, transform .18s;
}
.ac-theme .rev:hover {
  background: color-mix(in srgb, var(--cc) 20%, transparent);
  transform: translateY(-1px);
}
@media (max-width: 600px) { .ac-theme .rev { margin-left: 0; } }

/* Bilan d'un quiz de révision : les leçons à revoir. C'est la seule
   partie qui compte vraiment, un score sans « où j'ai raté » n'apprend
   rien à personne. */
.rv-revoir { margin-top: 20px; text-align: left; }
.rv-revoir h5 {
  font-family: var(--font-mono); font-size: 0.66rem; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--cyan); margin-bottom: 10px;
}
.rv-revoir a {
  display: block; padding: 11px 15px; margin-bottom: 8px; border-radius: 12px;
  color: #CBB6F7; font-size: 0.87rem; text-decoration: none;
  background: rgba(124,58,237,0.08); border: 1px solid rgba(124,58,237,0.22);
  transition: background .2s;
}
.rv-revoir a:hover { background: rgba(124,58,237,0.18); }
.rv-revoir a span { display: block; color: var(--muted); font-size: 0.76rem; margin-top: 3px; }

/* ── Examen de certification ──────────────────────────────────
   Volontairement plus sobre que le reste de l'Académie : ici on peut
   échouer, et un décor festif au-dessus d'une épreuve sonne faux. */
.ex-head { max-width: 640px; margin: 0 auto 22px; text-align: center; }
.ex-head .crumb {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--cc); margin-bottom: 8px;
}
.ex-head h2 { font-family: var(--font-display); font-size: 1.7rem; font-weight: 800; letter-spacing: -0.02em; }
.ex-head .m { color: var(--muted); font-size: 0.85rem; margin-top: 6px; }
.ex-bar {
  max-width: 640px; margin: 0 auto 20px; height: 4px; border-radius: 999px;
  background: rgba(255,255,255,0.07); overflow: hidden;
}
.ex-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--violet), var(--cyan)); transition: width .35s ease; }
.ex-intro {
  max-width: 640px; margin: 0 auto; padding: 26px 28px; border-radius: 18px;
  background: rgba(255,255,255,0.02); border: 1px solid var(--hair);
}
.ex-intro ul { list-style: none; margin: 0 0 22px; padding: 0; }
.ex-intro li {
  position: relative; padding: 0 0 0 22px; margin-bottom: 12px;
  color: #C9CEE6; font-size: 0.9rem; line-height: 1.6;
}
.ex-intro li::before { content: ''; position: absolute; left: 0; top: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--cyan); }
.ex-intro li b { color: #fff; }
.ex-intro .deja {
  padding: 13px 17px; border-radius: 12px; margin-bottom: 20px; font-size: 0.86rem; line-height: 1.6;
  background: rgba(16,185,129,0.1); border: 1px solid rgba(16,185,129,0.32); color: #C9F3E4;
}
.ex-note { color: var(--muted); font-size: 0.78rem; text-align: center; margin-top: 4px; }
/* Ce que la certification vaut. Volontairement sobre et non alarmiste :
   ce n'est pas un avertissement, c'est une information. */
.ex-vaut {
  padding: 14px 18px; border-radius: 12px; margin-bottom: 20px;
  font-size: 0.85rem; line-height: 1.65; color: #B7BDD8;
  background: rgba(255,255,255,0.03); border: 1px solid var(--hair);
}
.ex-vaut b { color: #fff; }
.pg-avert {
  max-width: 66ch; margin: -6px 0 20px; padding: 15px 19px; border-radius: 12px;
  font-size: 0.86rem; line-height: 1.7; color: #B7BDD8;
  background: rgba(255,255,255,0.03); border: 1px solid var(--hair);
}
.pg-avert b { color: #fff; }
.ex-redac { max-width: 640px; margin: 0 auto; }
.ex-redac .sujet {
  padding: 20px 22px; border-radius: 16px; margin-bottom: 16px; font-size: 0.98rem; line-height: 1.7;
  background: rgba(124,58,237,0.09); border: 1px solid rgba(124,58,237,0.28); color: #E4E7F5;
}
.ex-redac .sujet .lab {
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--violet); margin-bottom: 8px;
}
.ex-redac textarea {
  width: 100%; padding: 15px 17px; border-radius: 14px; resize: vertical; outline: none;
  background: rgba(255,255,255,0.04); border: 1px solid var(--hair); color: var(--text);
  font-family: inherit; font-size: 0.94rem; line-height: 1.65; margin-bottom: 14px;
}
.ex-redac textarea:focus { border-color: var(--violet); box-shadow: 0 0 0 3px rgba(124,58,237,0.14); }
.ex-err { color: #F5C9C9; font-size: 0.85rem; margin-bottom: 12px; }
.ex-res {
  max-width: 640px; margin: 0 auto; padding: 30px 28px; border-radius: 20px; text-align: center;
}
.ex-res.win { background: rgba(16,185,129,0.1); border: 1px solid rgba(16,185,129,0.4); }
.ex-res.lose { background: rgba(255,255,255,0.02); border: 1px solid var(--hair); }
.ex-res .sc { font-family: var(--font-display); font-size: 3.4rem; font-weight: 800; line-height: 1; color: #fff; }
.ex-res .sc span { font-size: 1.5rem; color: var(--muted); }
.ex-res .pc { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-top: 8px; }
.ex-res p { color: #C9CEE6; font-size: 0.92rem; line-height: 1.7; margin: 16px 0 20px; }
.ex-retour {
  max-width: 640px; margin: 22px auto 0; padding: 22px 24px; border-radius: 18px;
  background: rgba(255,255,255,0.02); border: 1px solid var(--hair); font-size: 0.93rem; line-height: 1.75;
}
.ex-retour .lab {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.15em;
  text-transform: uppercase; color: #F0A53C; margin-bottom: 12px;
}
.ex-retour p { margin-bottom: 11px; }
.ex-retour b { color: #fff; }
.ex-retour .pied { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--hair); color: var(--muted); font-size: 0.78rem; line-height: 1.55; }

/* Cartes de certification, dans Ma progression */
.pg-intro { color: var(--muted); font-size: 0.88rem; line-height: 1.65; max-width: 60ch; margin: -8px 0 18px; }
.pg-certs { display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); gap: 12px; margin-bottom: 34px; }
.pg-cert-card {
  display: flex; flex-direction: column; gap: 6px; padding: 18px 20px; border-radius: 16px;
  text-decoration: none; color: var(--text);
  background: rgba(255,255,255,0.02); border: 1px solid var(--hair);
  transition: transform .2s var(--ease), border-color .2s;
}
.pg-cert-card:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--cc) 50%, transparent); }
.pg-cert-card.obtenue { background: color-mix(in srgb, var(--cc) 9%, transparent); border-color: color-mix(in srgb, var(--cc) 38%, transparent); }
.pg-cert-card .niv { font-family: var(--font-display); font-weight: 800; font-size: 1.02rem; color: #fff; }
.pg-cert-card .st { font-size: 0.82rem; color: var(--muted); }
.pg-cert-card.obtenue .st { color: var(--cc); font-weight: 600; }
.pg-cert-card .go { margin-top: 4px; font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--cc); }
/* Le code de vérification : à espacement fixe et bien détaché, parce
   qu'il se recopie caractère par caractère. */
.pg-cert-card .code {
  font-family: var(--font-mono); font-size: 0.82rem; letter-spacing: 0.14em;
  color: #fff; padding: 7px 11px; border-radius: 9px; margin-top: 2px;
  background: rgba(0,0,0,0.28); border: 1px solid rgba(255,255,255,0.1);
  overflow-wrap: anywhere;
}
.pg-cert-card .actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.pg-cert-card .actions button, .pg-cert-card .actions a {
  padding: 7px 14px; border-radius: 999px; cursor: pointer; text-decoration: none;
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.1em;
  text-transform: uppercase; font-weight: 700; color: var(--cc);
  border: 1px solid color-mix(in srgb, var(--cc) 40%, transparent);
  background: rgba(0,0,0,0.22); transition: background .18s;
}
.pg-cert-card .actions button:hover, .pg-cert-card .actions a:hover {
  background: color-mix(in srgb, var(--cc) 22%, transparent);
}
.pg-cert-card.obtenue:hover { transform: none; }

/* Code affiché sur l'écran de résultat, juste après l'examen */
.ex-code {
  margin-top: 20px; padding: 18px 20px; border-radius: 14px; text-align: left;
  background: rgba(0,0,0,0.24); border: 1px solid rgba(255,255,255,0.12);
}
.ex-code .lab {
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 7px;
}
.ex-code .val {
  font-family: var(--font-mono); font-size: 1.28rem; letter-spacing: 0.22em;
  font-weight: 700; color: #fff; margin-bottom: 12px; overflow-wrap: anywhere;
}
.ex-code p { color: #B7BDD8; font-size: 0.83rem; line-height: 1.65; margin: 0; }
.ex-code a { color: var(--cyan); }

/* ══════════════════════════════════════════════════════════════
   LE FIL MOBILE, REPRIS DE L'APPLICATION
   ──────────────────────────────────────────────────────────────
   L'application affiche une carte aérée : une vignette 16:9 posée
   seule, sa pastille de catégorie, le titre, deux lignes de résumé.
   Pas de conteneur autour, pas de cadre dans un cadre. Le site,
   lui, empilait des boîtes bordées et remplies, ce qui charge un
   écran de 375 px et fait paraître les cartes plus petites qu'elles
   ne sont.

   Un défaut au passage : `css/mobile.css` remet `height: 180px` sur
   la vignette, ce qui annule l'`aspect-ratio` posé plus haut dans ce
   fichier — et dont le commentaire explique justement pourquoi il
   avait été mis. Sur mobile, les vignettes n'étaient donc plus en
   16:9. On le rétablit ici, `premium.css` étant chargé en dernier.
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 760px) {
  /* `!important` obligatoire : `main.css` pose `gap: 14px !important`
     sous 640 px. C'est le deuxième endroit où un `!important` de
     `main.css` écrase silencieusement cette couche, après le rayon des
     vignettes. Vérifier ce point avant de conclure qu'une règle d'ici
     « ne s'applique pas ». */
  #articles-grid { gap: 28px !important; }

  .article-card {
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
  }
  /* Le liseré dégradé suivait le bord de la carte. Sans carte, il n'a
     plus de bord à suivre et dessinerait un rectangle dans le vide. */
  .article-card::after { display: none; }
  .article-card:active { transform: none !important; }
  .article-card:active .card-thumb {
    transform: scale(0.985);
    border-color: rgba(167,139,250,0.5);
  }

  /* `!important` et sélecteur à deux niveaux : `css/main.css` pose
     `border-radius: 0 !important` sur ces vignettes en mobile. C'était
     juste tant que la carte portait le cadre arrondi et que la vignette
     s'y encastrait à ras. Le cadre ayant disparu, c'est la vignette qui
     doit porter l'arrondi, sinon on obtient un rectangle net posé sur
     rien. */
  .article-card .card-thumb,
  .article-card.wide .card-thumb {
    aspect-ratio: 16 / 9;
    height: auto;
    border-radius: 16px !important;
    border: 1px solid rgba(255,255,255,0.10);
    overflow: hidden;
    transition: transform .12s, border-color .12s;
  }
  .article-card .card-thumb-gradient { height: auto !important; aspect-ratio: 16 / 9; }

  .card-body { padding: 11px 2px 0; }
  .cat-badges { margin-bottom: 8px; }
  .card-title {
    font-size: 1.08rem;
    line-height: 1.34;
    letter-spacing: -0.015em;
  }
  /* Deux lignes, pas plus : au-delà, le résumé prend la place de la
     carte suivante et le fil cesse de se parcourir d'un pouce. */
  .card-excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 6px;
    font-size: 0.86rem;
    line-height: 1.5;
  }
  .article-meta { margin-top: 9px; font-size: 0.73rem; }

  /* La carte à la une garde son cadre : c'est ce qui la distingue du
     reste du fil, et l'application fait pareil. */
  .featured-card { border-radius: 18px; }
}

/* Carte d'identité du menu : une information, pas un bouton.
   Elle était un lien vers le compte sans que rien ne le dise. */
.mobile-user-carte {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; margin-bottom: 10px;
  border-radius: 15px;
  border: 1px solid rgba(255,255,255,0.08);
  background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.015));
}
.mobile-compte-btn {
  width: 100%; text-align: left; cursor: pointer;
  font-family: var(--font-display); font-weight: 700;
  border-color: rgba(167,139,250,0.40) !important;
  background: linear-gradient(180deg, rgba(124,58,237,0.26), rgba(124,58,237,0.08)) !important;
  color: #fff !important;
}
.mobile-compte-btn .link-icon { background: rgba(167,139,250,0.22); }
.mobile-compte-btn svg, .mobile-deco-btn svg { width: 16px; height: 16px; }
.mobile-deco-btn {
  width: 100%; text-align: left; cursor: pointer;
  font-family: var(--font-body); font-weight: 600; font-size: 0.95rem !important;
  color: var(--muted) !important;
}

/* ══════════════════════════════════════════════════════════════
   MON COMPTE
   ──────────────────────────────────────────────────────────────
   Cette page n'avait AUCUN style à elle : deux lignes dans
   `main.css` pour le mobile, et tout le reste en attributs `style`
   posés par le JavaScript. Elle ne pouvait donc pas suivre les
   refontes du site, et se retrouvait plusieurs mois en arrière
   pendant que tout le reste avançait.

   Elle parle maintenant la même langue que le menu et les cartes :
   du verre, des tuiles, des pastilles.
   ══════════════════════════════════════════════════════════════ */

.account-hero { padding: 116px 0 8px; }

.account-header-profile {
  display: flex; align-items: center; gap: 20px;
  padding: 20px 22px;
  border-radius: 22px;
  border: 1px solid rgba(255,255,255,0.10);
  background:
    linear-gradient(160deg, rgba(124,58,237,0.16) 0%, rgba(124,58,237,0.03) 46%, rgba(6,182,212,0.08) 100%),
    linear-gradient(180deg, rgba(255,255,255,0.07), rgba(255,255,255,0.02));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), 0 20px 50px rgba(0,0,0,0.35);
}
.account-avatar-lg {
  width: 84px; height: 84px; border-radius: 50%;
  object-fit: cover; border: 2px solid; flex-shrink: 0;
}
.account-identite { min-width: 0; }
.account-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.5rem, 5vw, 2.1rem); line-height: 1.1;
  letter-spacing: -0.03em; margin: 0 0 6px;
  background: linear-gradient(135deg, var(--badge, var(--violet-lt)), var(--cyan));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.account-email-lg {
  font-family: var(--font-mono); font-size: 0.78rem;
  color: var(--muted); overflow: hidden; text-overflow: ellipsis;
}
.account-bio {
  margin: 10px 0 0; color: var(--text);
  font-size: 0.92rem; line-height: 1.55; max-width: 560px;
}

/* Les chiffres : mêmes tuiles que l'Académie et l'application. */
.account-stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px; margin-top: 14px;
}
.account-stat {
  text-align: center; padding: 14px 8px; border-radius: 16px;
  border: 1px solid rgba(255,255,255,0.08);
  background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.015));
}
.account-stat-val { font-family: var(--font-display); font-weight: 800; font-size: 1.5rem; line-height: 1; }
.account-stat-lab {
  margin-top: 5px; font-size: 0.66rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.09em;
}

/* Onglets : un sélecteur segmenté, posé sur du verre. C'étaient trois
   mots nus, sans rien pour dire lequel était actif ni qu'ils étaient
   cliquables. */
.account-tabs {
  display: flex; gap: 4px; margin: 26px 0 22px;
  padding: 4px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.09);
  background: rgba(255,255,255,0.035);
  overflow-x: auto; scrollbar-width: none;
}
.account-tabs::-webkit-scrollbar { display: none; }
.account-tab {
  flex: 1 0 auto; text-align: center; white-space: nowrap;
  padding: 10px 16px; border-radius: 999px; cursor: pointer;
  font-family: var(--font-display); font-weight: 700; font-size: 0.92rem;
  color: var(--muted); border: 1px solid transparent;
  transition: color .2s, background .2s, border-color .2s;
}
.account-tab:hover { color: var(--text); }
.account-tab.active {
  color: #fff;
  border-color: rgba(167,139,250,0.42);
  background: linear-gradient(180deg, rgba(124,58,237,0.30), rgba(124,58,237,0.10));
}

.empty-state {
  text-align: center; padding: 48px 20px;
  border-radius: 20px;
  border: 1px dashed rgba(255,255,255,0.12);
  background: rgba(255,255,255,0.02);
  color: var(--muted);
}
.empty-state p { margin: 0 0 16px; }

/* Zone rouge : elle doit se voir sans hurler, et surtout ne pas
   ressembler au reste de la page. */
.danger-zone {
  margin-top: 40px; padding: 20px; border-radius: 18px;
  border: 1px solid rgba(248,113,113,0.28);
  background: linear-gradient(180deg, rgba(248,113,113,0.07), rgba(248,113,113,0.02));
}
.danger-zone h3 {
  margin: 0 0 8px; font-family: var(--font-display);
  font-size: 1.05rem; color: #FCA5A5;
}
.danger-btn {
  padding: 10px 16px; border-radius: 12px; cursor: pointer;
  border: 1px solid rgba(248,113,113,0.45);
  background: rgba(248,113,113,0.12); color: #FCA5A5;
  font-family: var(--font-body); font-weight: 600; font-size: 0.9rem;
}
.danger-btn:disabled { opacity: .45; cursor: not-allowed; }
.ghost-btn {
  padding: 10px 16px; border-radius: 12px; cursor: pointer;
  border: 1px solid rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.04); color: var(--text);
  font-family: var(--font-body); font-weight: 600; font-size: 0.9rem;
}

@media (max-width: 760px) {
  .account-hero { padding: 96px 0 4px; }
  .account-header-profile { gap: 15px; padding: 16px; border-radius: 20px; }
  .account-avatar-lg { width: 62px; height: 62px; }
  .account-stat { padding: 12px 6px; }
  .account-stat-val { font-size: 1.28rem; }
  .account-tabs { margin: 20px 0 18px; }
  .account-tab { font-size: 0.85rem; padding: 9px 12px; }
}

/* ══════════════════════════════════════════════════════════════
   LE VOYAGE — trois plans, un seul cadre
   ──────────────────────────────────────────────────────────────
   Refait de zéro le 11/08/2026, après trois tentatives ratées :
   épinglage GSAP en `fixed`, épinglage en `transform`, puis plus
   d'épinglage du tout. Aucune ne tenait sur téléphone.

   Ce qui tient le cadre ici n'est plus du JavaScript, c'est
   `position: sticky`. Le navigateur le gère lui-même, sans rien
   recalculer, et il survit à la barre d'adresse qui monte et descend.

   Ce fichier ne fait donc que POSER LE DÉCOR. Le mouvement — quel
   plan est visible, à quelle échelle — est écrit image par image en
   style en ligne par `initVoyage()` (js/premium.js). Ne rien animer
   ici : une animation CSS l'emporterait sur ces styles en ligne, et
   les deux mécaniques se battraient sans qu'on le voie.

   ATTENTION : aucun ancêtre de `.journey-cadre` ne doit porter
   `overflow: hidden`. Ce serait lui, et non la page, qui deviendrait
   le conteneur de défilement — et le collage ne prendrait jamais.
   ══════════════════════════════════════════════════════════════ */

/* Sans JavaScript, `.cine` n'est jamais posée et les trois plans
   s'empilent verticalement, comme trois sections ordinaires. La page
   reste lisible ; elle est seulement moins jolie. */
.journey { position: relative; }

/* La piste : une colonne vide, haute de plusieurs écrans. C'est ELLE
   qu'on fait défiler. Sa hauteur définitive est posée en pixels par le
   JavaScript (`calibre()`), à partir de la hauteur réelle du cadre ;
   la valeur ci-dessous n'est là que pour le tout premier affichage. */
.journey.cine .journey-piste { position: relative; height: 380vh; }

/* Le cadre : il reste collé en haut pendant toute la traversée de la
   piste. Sa hauteur définitive est FIGÉE EN PIXELS par `calibre()`, à
   la plus grande hauteur de viewport observée. La valeur ci-dessous ne
   sert qu'au tout premier affichage.

   Ni `svh` ni `dvh` ici, et c'est délibéré. `dvh` suit la barre
   d'adresse qui va et vient, donc recalcule la mise en page en plein
   geste. `svh` fige la petite hauteur, mais laisse alors une bande de
   page visible sous le cadre dès que la barre se rétracte. La grande
   hauteur figée est la seule qui ne bouge jamais et ne laisse jamais
   de trou : quand la barre revient, elle rogne le bas du cadre, et
   c'est tout. */
.journey.cine .journey-cadre {
  position: sticky; top: 0;
  height: 100vh;
  overflow: hidden;
  perspective: 1300px;
}

/* Sur téléphone, pas de perspective sur le cadre. Elle fabrique un
   contexte de rendu 3D pour trois calques plein écran, et son seul
   effet visible ici — la profondeur de la plongée dans le vortex — se
   joue à l'intérieur du hero, qui garde la sienne. */
@media (max-width: 760px) {
  .journey.cine .journey-cadre { perspective: none; }
}

/* Les trois plans, superposés dans le cadre. `min-height: 0` annule le
   `min-height: 680px` du hero et le `100vh` des sections immersives,
   qui déborderaient du cadre sur un petit écran. */
.journey.cine .jplan {
  position: absolute; inset: 0;
  height: 100%; min-height: 0;
  pointer-events: none;
  backface-visibility: hidden;
}

/* État de départ, le temps que le moteur écrive ses premiers styles en
   ligne : seul le vortex est visible. Sans cette règle, la vague — le
   dernier plan du document, donc le plus haut dans la pile — s'affiche
   en plein écran pendant une image ou deux à l'ouverture de la page. */
.journey.cine .jplan[data-plan="1"],
.journey.cine .jplan[data-plan="2"] { opacity: 0; }

/* Seul le plan au premier plan reçoit les clics. Sans cette règle, les
   boutons du hero restent cliquables sous le monolithe, à l'aveugle. */
.journey.cine .jplan.actif { pointer-events: auto; }

/* `will-change` seulement pendant la traversée : le garder en
   permanence réserve trois calques pleine page en mémoire vidéo, sur
   un appareil qui n'en a pas de trop. */
.journey.cine.en-vue .jplan { will-change: opacity, transform; }

/* LES LETTRES DU PLAN EN COURS SONT PROMUES AVANT DE BOUGER.

   Quand une scène bascule, soixante-cinq transitions démarrent dans la
   même image — trente-quatre éléments, deux propriétés chacun. Sans
   promotion préalable, le navigateur doit créer ces trente-quatre
   couches à cet instant précis, c'est-à-dire au pire moment possible :
   celui où l'animation commence. C'est un à-coup, et il se voit.

   Le coût est ici négligeable, contrairement aux calques plein écran
   des plans : une lettre fait quinze pixels de côté, sa couche pèse
   quelques kilo-octets. On ne promeut que le plan au premier plan, et
   seulement pendant la traversée.

   `!important` est nécessaire : le bloc mobile plus bas remet
   `will-change: auto !important` sur `.immersive-title .ltr` — règle
   posée quand ces lettres étaient animées image par image en
   JavaScript, ce qui n'est plus le cas. */
.journey.cine.en-vue .jplan.actif .immersive-title .ltr,
.journey.cine.en-vue .jplan.actif .immersive-lead,
.journey.cine.en-vue .jplan.actif .eyebrow-line,
.journey.cine.en-vue .jplan.actif .stat-cell {
  will-change: transform, opacity !important;
}

/* ══════════════════════════════════════════════════════════════
   LE CONTENU DES PLANS — tout est ici, rien n'est en JavaScript
   ──────────────────────────────────────────────────────────────
   Les lettres se rassemblent, le chapô monte, les chiffres se posent,
   puis tout repart. Ces animations sont des TRANSITIONS CSS, et le
   JavaScript ne fait que poser deux classes sur le plan : `assemble`
   quand on y arrive, `disperse` quand on le quitte.

   Deux raisons, et elles comptent toutes les deux.

   1. LE COÛT. La version précédente animait ces mêmes lettres en les
      liant au doigt : cinq propriétés écrites sur cinquante-six
      éléments À CHAQUE IMAGE de défilement. C'est ce qui avait obligé à
      les retirer du téléphone. Ici, le coût pendant le défilement est
      strictement nul — le compositeur joue les transitions tout seul.

   2. LE RYTHME. Une animation liée au doigt se termine à la vitesse du
      doigt : un geste vif la fait passer avant qu'on l'ait vue. C'est
      littéralement le « il n'y a aucune animation » du 11/08/2026,
      alors qu'elle jouait bel et bien. Déclenchée, elle se joue en
      entier, quelle que soit la vitesse du geste.

   Les directions de départ et d'arrivée de chaque lettre sont tirées
   au sort une fois pour toutes et posées en variables CSS par
   `disperseLettres()` (js/premium.js).
   ══════════════════════════════════════════════════════════════ */

/* Au repos : dispersées, réduites, invisibles.

   LES DURÉES SONT LONGUES, ET C'EST VOULU. La première version tenait
   en une seconde, décalages compris, et le retour a été « le texte
   apparaît beaucoup trop vite ». Il avait raison : un mot qui se
   rassemble est quelque chose qu'on REGARDE, pas un fondu qu'on
   traverse. Il faut lui laisser près de deux secondes pour qu'on ait
   le temps de voir les lettres arriver une à une.

   Rien de tout cela ne coûte quoi que ce soit pendant le défilement :
   ce sont des transitions, jouées par le compositeur, déclenchées une
   fois. Allonger une durée ici est gratuit. */
/* LA DURÉE EST PORTÉE PAR L'ÉTAT D'ARRIVÉE, PAS PAR L'ÉTAT DE DÉPART.

   Une transition CSS lit sa durée sur la règle qui s'applique APRÈS le
   changement. Mettre la longue durée d'entrée sur cette règle de base
   revenait donc à l'appliquer aussi au retour vers elle — c'est-à-dire
   à la SORTIE quand on remonte. Les lettres attendaient jusqu'à 0,62 s
   avant de bouger, puis mettaient 1,3 s à s'écarter : de l'extérieur,
   elles ne partaient pas.

   Chaque règle porte donc sa propre durée : celle-ci est une sortie
   (rapide), `.assemble` est une entrée (lente). Quel que soit le sens
   dans lequel on traverse, arriver prend son temps et partir est net. */
.journey.cine .immersive-title .ltr {
  opacity: 0;
  transform: translate3d(var(--dx, 0), var(--dy, 0), 0) rotate(var(--dr, 0deg)) scale(0.3);
  transition: opacity .34s ease-in var(--dd, 0s),
              transform .62s cubic-bezier(.6, 0, .9, .3) var(--dd, 0s);
}
/* Elles convergent vers leur place, et c'est ce qu'on regarde : c'est
   le seul mouvement de toute la traversée qui a le droit d'être lent. */
.journey.cine .jplan.assemble .immersive-title .ltr {
  opacity: 1;
  transform: none;
  /* L'OPACITE ARRIVE AVANT LA POSITION, ET C'EST DELIBERE.

     Les deux etaient calees sur le meme retard, si bien que la
     derniere lettre n'etait pleinement lisible qu'a 1,32 s. Quelqu'un
     qui descend vite ne dispose pas de ce temps-la : il voyait des
     lettres a moitie transparentes partir avant d'etre arrivees.

     On separe donc les deux. L'opacite prend un retard reduit (55 %)
     et une duree plus courte : le mot est LISIBLE des 0,84 s. La
     position, elle, garde toute sa lenteur — les lettres continuent de
     glisser en place pendant une demi-seconde de plus. On lit tot, et
     ca continue de bouger : c'est ce qui donne l'impression de calme
     sans faire attendre. */
  transition: opacity .50s ease-out calc(var(--d, 0s) * 0.55),
              transform 1.30s cubic-bezier(.16, 1, .3, 1) var(--d, 0s);
}
/* Puis elles repartent, ailleurs, et plus vite qu'elles ne sont venues :
   une sortie qui traîne donne l'impression d'un site lent, et à ce
   moment-là on cherche déjà la suite. */
.journey.cine .jplan.disperse .immersive-title .ltr {
  opacity: 0;
  transform: translate3d(var(--ox, 0), var(--oy, 0), 0) rotate(var(--or, 0deg)) scale(0.3);
  transition: opacity .34s ease-in var(--dd, 0s),
              transform .62s cubic-bezier(.6, 0, .9, .3) var(--dd, 0s);
}

/* Le reste du contenu : même principe, sans dispersion. Il monte, il
   se pose, il repart par le haut. */
/* État de départ, avant la toute première arrivée. On n'y revient
   jamais : `fenetre()` bascule sur `disperse` dès qu'on a vu la scène
   une fois, dans les deux sens. */
.journey.cine .jplan .eyebrow-line,
.journey.cine .jplan .immersive-lead,
.journey.cine .jplan .stat-cell {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  transition: opacity .34s ease-in, transform .46s cubic-bezier(.6, 0, .9, .3);
}
.journey.cine .jplan.assemble .eyebrow-line,
.journey.cine .jplan.assemble .immersive-lead,
.journey.cine .jplan.assemble .stat-cell {
  opacity: 1;
  transform: none;
  transition: opacity .80s ease-out, transform 1.00s cubic-bezier(.16, 1, .3, 1);
}

/* Les retards font l'ordre de lecture : l'accroche d'abord, le titre
   qui se rassemble pendant ce temps, puis le chapô une fois le titre
   posé, puis les chiffres l'un après l'autre. */
.journey.cine .jplan.assemble .eyebrow-line  { transition-delay: .05s; }
.journey.cine .jplan.assemble .immersive-lead { transition-delay: .95s; }
.journey.cine .jplan.assemble .stat-cell:nth-child(1) { transition-delay: 1.18s; }
.journey.cine .jplan.assemble .stat-cell:nth-child(2) { transition-delay: 1.31s; }
.journey.cine .jplan.assemble .stat-cell:nth-child(3) { transition-delay: 1.44s; }
.journey.cine .jplan.assemble .stat-cell:nth-child(4) { transition-delay: 1.57s; }

.journey.cine .jplan.disperse .eyebrow-line,
.journey.cine .jplan.disperse .immersive-lead,
.journey.cine .jplan.disperse .stat-cell {
  opacity: 0;
  transform: translate3d(0, -28px, 0);
  transition-delay: 0s;
  transition-duration: .42s;
}

/* ── Menu burger ouvert : on efface ce qui flotte par-dessus ──
   La bulle Mnémosyne (ai.js) et le bouton de langue (i18n.js) sont
   posés en `position: fixed`, hors du panneau. Ils restaient donc
   affichés par-dessus le menu, où ils n'ont rien à faire.

   `visibility` en plus de l'opacité : sans elle, ils restent
   cliquables une fois transparents, ce qui est pire qu'avant. La
   classe est posée par `openMenu()` dans js/mobile.js. */
body.menu-ouvert .ai-fab,
body.menu-ouvert .alyriaz-lang-btn,
body.menu-ouvert .alyriaz-lang-menu {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s ease, visibility 0s linear .18s;
}

/* ══════════════════════════════════════════════════════════════
   LE COMPTE — menu déroulant et formulaire de profil
   ──────────────────────────────────────────────────────────────
   Les deux écrans étaient entièrement habillés en attributs `style`
   posés dans le JavaScript : chaque champ y redéfinissait son fond,
   sa bordure et son rayon à la main, et aucun ne partageait rien avec
   le reste du site. C'est ce qui les faisait ressortir comme venus
   d'un autre projet, alors que rien n'y était laid en soi.

   Tout est donc rassemblé ici, dans le langage du site : verre
   liquide, violet et cyan, Syne pour les titres, et des icônes
   dessinées au trait plutôt que des émojis — un émoji ne suit ni la
   couleur du texte ni son épaisseur, et ne se dessine pas de la même
   façon d'un système à l'autre.
   ══════════════════════════════════════════════════════════════ */

/* ── Le menu déroulant de la navbar ─────────────────────────── */
.user-avatar {
  width: 36px; height: 36px;
  border: 0;
  padding: 2px;
  background: linear-gradient(135deg, var(--violet), var(--cyan));
  box-shadow: 0 0 0 1px rgba(255,255,255,0.10), 0 4px 14px rgba(0,0,0,0.45);
}
.user-avatar:hover {
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18), 0 0 22px rgba(124,58,237,0.55);
}

.user-dropdown {
  min-width: 262px;
  padding: 7px;
  border-radius: 18px;
  border: 1px solid rgba(255,255,255,0.10);
  /* Le même verre que le menu burger : un dégradé à trois arrêts, pour
     que le panneau ait un haut et un bas plutôt qu'une teinte plate. */
  background: linear-gradient(165deg,
    rgba(14,14,30,0.92) 0%, rgba(10,10,22,0.72) 46%, rgba(8,8,18,0.52) 100%);
  backdrop-filter: blur(34px) saturate(150%);
  -webkit-backdrop-filter: blur(34px) saturate(150%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.13),
    0 24px 60px rgba(0,0,0,0.62);
  transform: translateY(-10px) scale(0.97);
  transform-origin: top right;
  transition: opacity .2s ease, transform .28s cubic-bezier(.16,1,.3,1), visibility 0s linear .2s;
}
.user-dropdown.visible {
  transform: translateY(0) scale(1);
  transition-delay: 0s;
}

.user-dropdown-header { gap: 11px; padding: 11px 12px 13px; }
.user-dropdown-avatar {
  width: 42px; height: 42px;
  padding: 2px;
  background: linear-gradient(135deg, var(--violet), var(--cyan));
}
.user-dropdown-name {
  font-family: var(--font-display);
  font-weight: 800; font-size: 0.98rem; letter-spacing: -0.02em;
}
.user-dropdown-email {
  font-size: 0.72rem;
  color: var(--muted);
  letter-spacing: 0.02em;
  /* Une adresse longue ne doit ni élargir le panneau ni déborder. */
  max-width: 168px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.user-dropdown-divider {
  margin: 2px 8px 6px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.14), transparent);
}

.user-dropdown-item {
  position: relative;
  gap: 11px;
  padding: 10px 12px;
  margin: 1px 0;
  border-radius: 12px;
  font-size: 0.88rem;
  font-weight: 550;
  transition: background .16s ease, color .16s ease, transform .16s ease;
}
.user-dropdown-item svg {
  width: 17px; height: 17px; flex: 0 0 auto;
  fill: none; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
  opacity: 0.86;
}
.user-dropdown-item:hover {
  background: linear-gradient(90deg, rgba(124,58,237,0.24), rgba(124,58,237,0.06));
  transform: translateX(2px);
}
.user-dropdown-item:hover svg { opacity: 1; }
.user-dropdown-logout:hover {
  background: linear-gradient(90deg, rgba(220,38,38,0.22), rgba(220,38,38,0.05));
}

/* ── Le formulaire de profil ────────────────────────────────── */
.pf-carte {
  border-radius: 24px;
  padding: clamp(22px, 4vw, 36px);
  border: 1px solid rgba(255,255,255,0.09);
  background:
    radial-gradient(120% 90% at 50% -20%, rgba(124,58,237,0.13), transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0.012));
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.09), 0 24px 60px rgba(0,0,0,0.4);
}
.pf-titre {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 3vw, 1.6rem); font-weight: 800;
  letter-spacing: -0.03em; margin: 0 0 4px;
}
.pf-sous { color: var(--muted); font-size: 0.86rem; margin-bottom: 26px; }

.pf-identite { display: flex; align-items: center; gap: 18px; margin-bottom: 28px; flex-wrap: wrap; }
.pf-avatar {
  width: 84px; height: 84px; border-radius: 50%;
  padding: 3px; object-fit: cover;
  background: linear-gradient(135deg, var(--violet), var(--cyan));
  box-shadow: 0 0 26px rgba(124,58,237,0.34);
}
.pf-photo-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px; border-radius: 11px; cursor: pointer;
  font-size: 0.86rem; font-weight: 600; color: var(--text);
  border: 1px solid rgba(255,255,255,0.13);
  background: linear-gradient(180deg, rgba(255,255,255,0.075), rgba(255,255,255,0.02));
  transition: border-color .18s, background .18s, transform .18s;
}
.pf-photo-btn:hover {
  border-color: rgba(167,139,250,0.55);
  background: linear-gradient(180deg, rgba(124,58,237,0.22), rgba(124,58,237,0.06));
  transform: translateY(-1px);
}
.pf-photo-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.pf-aide { font-size: 0.76rem; color: var(--muted); margin-top: 7px; }

.pf-champs { display: flex; flex-direction: column; gap: 20px; }
.pf-label {
  display: block; margin-bottom: 7px;
  font-family: var(--font-mono); font-size: 0.7rem;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted);
}
.pf-saisie {
  width: 100%; padding: 12px 14px;
  border-radius: 12px; color: var(--text);
  font-family: var(--font-body); font-size: 0.94rem;
  border: 1px solid rgba(255,255,255,0.10);
  background: rgba(4,4,12,0.55);
  transition: border-color .18s, box-shadow .18s, background .18s;
}
.pf-saisie::placeholder { color: rgba(148,163,184,0.55); }
.pf-saisie:focus {
  outline: none;
  border-color: var(--violet);
  background: rgba(4,4,12,0.75);
  box-shadow: 0 0 0 3px rgba(124,58,237,0.18);
}
textarea.pf-saisie { resize: vertical; min-height: 92px; line-height: 1.6; }

/* Les pastilles de couleur. La sélection se voit par un anneau qui NE
   CHANGE PAS la taille de la pastille : une bordure qui s'épaissit
   ferait sauter toute la rangée d'un cran à chaque clic. */
.pf-couleurs { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; }
.pf-pastille {
  width: 30px; height: 30px; border-radius: 50%;
  border: 0; cursor: pointer; padding: 0;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.16);
  transition: transform .18s cubic-bezier(.16,1,.3,1), box-shadow .18s;
}
.pf-pastille:hover { transform: scale(1.14); }
.pf-pastille.choisie {
  /* La selection se lit UNIQUEMENT a l'anneau, pas a la taille. Une
     pastille qui grandit en meme temps que les autres restent petites
     decale toute la rangee, et l'anneau suffit largement a dire
     laquelle est prise. Le grossissement reste au survol, ou il n'a
     rien a decaler puisqu'il ne concerne qu'une pastille a la fois. */
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px currentColor, 0 0 16px currentColor;
}
.pf-couleur-libre {
  width: 46px; height: 34px; padding: 2px; cursor: pointer;
  border-radius: 10px; border: 1px solid rgba(255,255,255,0.13);
  background: rgba(4,4,12,0.55);
}

.pf-section { border-top: 1px solid rgba(255,255,255,0.08); padding-top: 22px; }
.pf-grille { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pf-mini { display: block; font-size: 0.74rem; color: var(--muted); margin-bottom: 5px; }

.pf-barre { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.pf-etat { font-size: 0.85rem; color: var(--muted); }
.pf-etat.ok { color: #34D399; }
.pf-etat.ko { color: #F87171; }

.pf-pied {
  border-top: 1px solid rgba(255,255,255,0.08);
  padding-top: 20px; margin-top: 4px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}
.pf-pied-info { font-size: 0.83rem; color: var(--muted); }
.pf-pied-info b { color: var(--text); font-weight: 650; }
.pf-deco {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 15px; border-radius: 11px; cursor: pointer;
  font-family: var(--font-body); font-size: 0.85rem; font-weight: 600;
  color: #F87171; background: transparent;
  border: 1px solid rgba(248,113,113,0.28);
  transition: background .18s, color .18s, border-color .18s;
}
.pf-deco:hover { background: rgba(220,38,38,0.16); border-color: rgba(248,113,113,0.6); color: #FCA5A5; }
.pf-deco svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

@media (max-width: 560px) {
  .pf-grille { grid-template-columns: 1fr; }
  .pf-identite { gap: 14px; }
  .pf-avatar { width: 68px; height: 68px; }
  .pf-pied { flex-direction: column; align-items: flex-start; }
}

/* ── Aperçu du badge ─────────────────────────────────────────
   La couleur du compte ne peint pas un rond : elle peint un dégradé
   sur le pseudo et l'anneau de l'avatar. C'est très exactement ce que
   fait `.account-title` plus haut dans ce fichier, et l'aperçu reprend
   la même formule — sinon il montrerait autre chose que le résultat,
   ce qui est pire que de ne rien montrer. */
.pf-apercu {
  --badge: var(--violet);
  display: flex; align-items: center; gap: 13px;
  padding: 13px 15px; margin-bottom: 14px;
  border-radius: 15px;
  border: 1px solid rgba(255,255,255,0.09);
  background: rgba(4,4,12,0.5);
}
.pf-apercu-ava {
  width: 46px; height: 46px; border-radius: 50%; object-fit: cover;
  padding: 2px;
  background: linear-gradient(135deg, var(--badge), var(--cyan));
  box-shadow: 0 0 22px color-mix(in srgb, var(--badge) 42%, transparent);
  transition: background .22s ease, box-shadow .22s ease;
}
.pf-apercu-nom {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.24rem; line-height: 1.15; letter-spacing: -0.03em;
  background: linear-gradient(135deg, var(--badge), var(--cyan));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  /* Un pseudo à rallonge ne doit pas faire grandir l'encadré. */
  max-width: 15ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pf-apercu-lab {
  font-family: var(--font-mono); font-size: 0.62rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
  margin-top: 2px;
}

/* ── Choix du thème ──────────────────────────────────────────
   Plus d'icône de météo. Chaque volet montre une miniature peinte avec
   les vraies couleurs de son thème : on choisit en voyant, pas en
   interprétant un pictogramme. */
.pf-themes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pf-theme {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 13px; cursor: pointer;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.09);
  background: rgba(4,4,12,0.5);
  font-family: var(--font-body); font-size: 0.9rem; font-weight: 600;
  color: var(--muted);
  transition: border-color .18s, color .18s, background .18s;
}
.pf-theme:hover { color: var(--text); border-color: rgba(167,139,250,0.4); }
.pf-theme.actif {
  color: var(--text);
  border-color: var(--violet);
  background: linear-gradient(180deg, rgba(124,58,237,0.20), rgba(124,58,237,0.05));
  box-shadow: 0 0 0 1px rgba(124,58,237,0.35);
}
.pf-vignette {
  position: relative; flex: 0 0 auto;
  width: 40px; height: 30px; border-radius: 7px; overflow: hidden;
  border: 1px solid rgba(255,255,255,0.14);
}
/* La barre du haut et le bloc de contenu, en réduction. */
.pf-vignette i, .pf-vignette b { position: absolute; display: block; }
.pf-vignette i { top: 5px; left: 5px; right: 15px; height: 3px; border-radius: 2px; }
.pf-vignette b { bottom: 5px; left: 5px; right: 8px; height: 10px; border-radius: 3px; }
.pf-vignette-sombre { background: #06060F; }
.pf-vignette-sombre i { background: linear-gradient(90deg, var(--violet), var(--cyan)); }
.pf-vignette-sombre b { background: rgba(255,255,255,0.13); }
.pf-vignette-clair { background: #F4F3F9; }
.pf-vignette-clair i { background: linear-gradient(90deg, #6D28D9, #0E7490); }
.pf-vignette-clair b { background: rgba(23,17,44,0.14); }

@media (max-width: 420px) {
  .pf-themes { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════════════════════
   ACADÉMIE — les niveaux comme sous-dossiers
   ──────────────────────────────────────────────────────────────
   Le dossier « Apprendre l'IA » portait seize des vingt-trois cours et
   les déroulait d'un bloc. On tombait sur seize cartes à la suite,
   coupées d'intertitres qui proposaient de passer un examen avant même
   d'avoir vu ce qu'il y avait à apprendre.

   Une marche de plus règle les deux problèmes :
       tous les dossiers → Apprendre l'IA → Grand débutant → cours
   Le niveau devient une porte, et la certification quitte l'intertitre
   pour fermer le niveau, après les cours.
   ══════════════════════════════════════════════════════════════ */

/* ── La porte d'un niveau ─────────────────────────────────────
   Même vocabulaire que la carte de dossier au-dessus : c'est le même
   geste, un cran plus bas. */
.ac-porte {
  --cc: var(--cyan);
  display: flex; flex-direction: column; gap: 10px;
  padding: 22px 22px 20px;
  border-radius: 18px;
  border: 1px solid rgba(255,255,255,0.09);
  background:
    radial-gradient(130% 100% at 0% 0%, color-mix(in srgb, var(--cc) 16%, transparent), transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0.012));
  text-decoration: none; color: inherit;
  transition: border-color .2s, transform .2s cubic-bezier(.16,1,.3,1), box-shadow .2s;
}
.ac-porte:hover {
  border-color: color-mix(in srgb, var(--cc) 55%, transparent);
  transform: translateY(-2px);
  box-shadow: 0 18px 44px rgba(0,0,0,0.34);
}
.ac-porte h3 {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.32rem; letter-spacing: -0.03em; line-height: 1.1;
  margin: 0; color: var(--cc);
}
.ac-porte .chiffres {
  font-family: var(--font-mono); font-size: 0.74rem;
  letter-spacing: 0.05em; color: var(--muted);
}
.ac-porte .chiffres b { color: var(--text); font-weight: 600; }
.ac-porte .cta {
  margin-top: 2px;
  font-size: 0.86rem; font-weight: 600; color: var(--cc);
  display: inline-flex; align-items: center; gap: 7px;
}
.ac-porte:hover .cta span { transform: translateX(3px); }
.ac-porte .cta span { transition: transform .2s; }
.ac-obtenue {
  align-self: flex-start;
  font-family: var(--font-mono); font-size: 0.66rem;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: #34D399;
  border: 1px solid rgba(52,211,153,0.35);
  border-radius: 999px; padding: 3px 10px;
}

/* ── La certification, en fin de niveau ───────────────────────
   Elle ne se présente plus comme un intertitre au milieu des cours
   mais comme la porte de sortie du niveau. Le libellé dit où on en
   est : proposer l'examen à quelqu'un qui n'a rien validé, c'est lui
   promettre un échec. */
.ac-certif {
  --cc: var(--cyan);
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  margin-top: 30px; padding: 22px 24px;
  border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--cc) 34%, transparent);
  background:
    radial-gradient(120% 130% at 100% 0%, color-mix(in srgb, var(--cc) 15%, transparent), transparent 64%),
    linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.01));
}
.ac-certif .t {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.12rem; letter-spacing: -0.02em; color: var(--cc);
  margin-bottom: 5px;
}
.ac-certif p {
  margin: 0; color: var(--muted); font-size: 0.9rem; line-height: 1.6;
  max-width: 52ch;
}
.ac-certif p b { color: var(--text); font-weight: 650; }
.ac-certif .go {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 20px; border-radius: 999px;
  font-size: 0.9rem; font-weight: 650; text-decoration: none;
  color: #05060F;
  background: linear-gradient(120deg, var(--cc), var(--violet-lt, #A78BFA));
  transition: transform .2s cubic-bezier(.16,1,.3,1), box-shadow .2s;
}
.ac-certif .go:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 30px color-mix(in srgb, var(--cc) 40%, transparent);
}

@media (max-width: 600px) {
  .ac-certif { flex-direction: column; align-items: flex-start; padding: 20px; }
  .ac-porte { padding: 18px; }
}

/* ── Résultat du test d'orientation ───────────────────────────
   Il répondait par un cours, un seul, sans dire où il se situait dans
   un catalogue de vingt-trois. On montre maintenant deux choses : la
   PORTE où aller, et le premier pas une fois arrivé. La séparation
   entre les deux est explicite — c'est elle qui rend le résultat
   compréhensible. */
.ac-reco-wrap { max-width: 620px; margin: 0 auto; text-align: center; }
.ac-reco-titre {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.35rem, 4vw, 1.7rem); letter-spacing: -0.03em;
  margin: 0 0 20px;
}
.ac-reco-sous {
  color: var(--muted); font-size: 0.92rem; line-height: 1.6;
  margin: 8px 0 16px; max-width: 44ch; margin-inline: auto;
}
.ac-reco-porte {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 20px; border-radius: 999px;
  font-size: 0.9rem; font-weight: 650; text-decoration: none;
  color: var(--cc);
  border: 1px solid color-mix(in srgb, var(--cc) 48%, transparent);
  background: color-mix(in srgb, var(--cc) 12%, transparent);
  transition: background .2s, transform .2s;
}
.ac-reco-porte:hover {
  background: color-mix(in srgb, var(--cc) 22%, transparent);
  transform: translateY(-1px);
}
/* Le trait de séparation porte son propre libellé : sans lui, on ne
   comprend pas pourquoi il y a deux boutons. */
.ac-reco-sep {
  display: flex; align-items: center; gap: 12px;
  margin: 22px 0 14px;
  font-family: var(--font-mono); font-size: 0.64rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
}
.ac-reco-sep::before, .ac-reco-sep::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.14), transparent);
}
.ac-reco-chiffres {
  font-family: var(--font-mono); font-size: 0.66rem;
  color: var(--muted); margin-bottom: 18px;
}
.ac-reco-actions {
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 22px;
}
.ac-reco-2 { background: rgba(255,255,255,0.06); color: var(--text); }
