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

:root {
  color-scheme: dark;

  /* --- fonds et matières --- */
  --bg:#07080B;
  --surface:#11141A;
  --surface-2:#171B22;
  /* Le survol d'une ligne de tableau : plus clair que --surface-2, jamais rouge. */
  --surface-3:#1D222B;

  /* --- rouge NRV ---
     Il ne borde PAS chaque composant : appels à l'action, information
     importante, état actif, priorité, progression. Partout ailleurs, --line. */
  --red:#D20A2E;
  --red-dark:#750719;
  /* Le rouge de la palette est fait pour être un FOND. En petit texte sur le
     fond sombre il plafonne à 3,6:1 — sous le minimum lisible (4,5:1) : les
     surtitres étaient à la limite du déchiffrable, constaté à l'écran. Cette
     variante n'est QUE pour du texte rouge ; les aplats gardent --red. */
  --red-text:#FF4A63;
  /* Le même rouge en translucide : liserés, halos et fonds d'état actif, sans
     ajouter une teinte de plus à tenir à jour. */
  --red-soft:rgba(210,10,46,.14);
  --red-line:rgba(210,10,46,.38);

  /* --- doré : distinctions et progression, rien d'autre --- */
  --gold:#C9A227;
  --gold-soft:rgba(201,162,39,.14);

  /* --- texte --- */
  --text:#F1F2F4;
  --muted:#9299A5;
  /* Le troisième niveau : mentions légales, unités, méta. Sous --muted. */
  --faint:#6B7280;

  /* --- traits --- */
  --line:#232833;
  --line-strong:#2E3542;

  /* --- signaux (hors identité : ils doivent rester lisibles comme signaux) --- */
  --ok:#2FA36B;
  --warn:#D98A2B;

  /* --- typographie --- */
  --font-title:'Rajdhani','Barlow Condensed',system-ui,sans-serif;
  --font-body:'Inter',system-ui,'Segoe UI',Arial,sans-serif;
  /* 38px sur un 360, 76px à partir de ~1400 : les bornes du cahier des charges. */
  --h1:clamp(2.375rem,1.05rem + 5.9vw,4.75rem);
  --h2:clamp(1.75rem,1.05rem + 2.4vw,2.75rem);
  --h3:clamp(1.15rem,1.05rem + .4vw,1.35rem);
  --body:clamp(1rem,.96rem + .18vw,1.125rem);
  --small:.875rem;
  /* Rajdhani est étroite : elle supporte — et demande — d'être resserrée. */
  --track-title:-.01em;
  --track-eyebrow:.28em;

  /* --- rythme --- */
  --wrap:1240px;
  --gutter:clamp(20px,5vw,64px);
  --nav-h:76px;
  --section-y:clamp(48px,5vw,76px);
  --gap:clamp(20px,2.4vw,32px);

  /* --- formes ---
     Le logo est fait d'angles coupés. On les reprend par petites touches
     (boutons, badges, séparateurs) et surtout PAS en transformant tout en
     hexagones : les cartes restent des rectangles arrondis. */
  --r-sm:8px;
  --r:14px;
  --r-lg:18px;
  --notch:10px;
  /* ⚠️ **38 px, et c'est la mesure de TOUT le site** (Kevin, 2026-07-28 : « si
     tous les boutons du site pouvaient être du même style, dimension, car ils
     sont en général tous trop gros »). Le repère est la pastille du QG, qu'il a
     validée : elle tient en 36 px là où le bouton en prenait **52** (48 sur
     mobile), soit une différence d'un tiers sur chaque appel à l'action.
     38 laisse 2 px au-dessus de la barre tactile du site (36 px, verrouillée par
     l'audit) — jamais moins, sous peine de rater la cible au doigt.
     ⚠️ Plus de valeur mobile distincte : un bouton de 38 px se touche aussi bien
     sur un téléphone, et deux tailles à tenir en phase, c'est deux occasions de
     diverger. */
  --btn-h:38px;
  /* Le plancher, pour les boutons enfouis dans une ligne de tableau ou une
     barre d'outils. Il ne descend PAS plus bas. */
  --btn-h-sm:36px;
  /* ⚠️ **Un champ et le bouton qui l'accompagne ont la MÊME hauteur.** Ils
     partagent une ligne (`.signup-form`, `.armory-filters`, la barre de spé) :
     un menu de 44 px à côté d'un bouton de 38 px, c'est un décalage de 6 px que
     l'œil relève même quand il ne sait pas le nommer. Les champs étaient à 44,
     40 et 38 px selon l'écran — trois valeurs pour la même chose. */
  --field-h:var(--btn-h);

  /* --- mouvement ---
     ⚠️⚠️ **Kevin a LEVÉ sa propre interdiction le 2026-07-28** : « je veux de
     l'animation sur le site, des effets visuels, des couleurs qui rappellent le
     logo, que ce soit agressif, attractif ». Son brief du 26/07 interdisait les
     particules permanentes et les animations continues ; il l'a annulé
     explicitement. Ce qui reste vrai, et qui n'est pas du goût :
     **`prefers-reduced-motion` coupe tout** (WCAG 2.3.3, et l'accessibilité
     est dans ses exigences permanentes), et **seuls `transform` et `opacity`
     s'animent** — le reste fait repeindre la page à chaque image.
     --t-slow : les mouvements de fond, ceux qu'on ne doit pas regarder. */
  --t:.45s cubic-bezier(.4,0,.2,1);
  --t-fast:.4s cubic-bezier(.4,0,.2,1);
  /* Les mouvements de fond, ceux qu'on ne doit PAS regarder. 14 s et non 7 :
     à 7 s le balayage se remarquait (retour de Kevin, 2026-07-28). */
  --t-slow:14s cubic-bezier(.4,0,.2,1);
  --lift:-4px;

  /* --- ⚔️ L'ANGLE DU LOGO : le motif dont tout le mouvement dérive ---
     Le sigle NRV est fait d'**entailles obliques**. Une seule valeur les
     gouverne toutes — balayages de survol, ouverture des cartes, traits
     lumineux, coins coupés. C'est ce qui fait qu'un bouton, une carte et un
     séparateur ont l'air de venir du même endroit : ils penchent pareil.
     ⚠️ Ne pas la faire varier par composant. Un site où chaque effet a son
     angle n'a pas de style, il a des effets. */
  --biais:-24deg;
  --biais-t:skewX(-24deg);

  --shadow:0 18px 40px -24px rgba(0,0,0,.9);
}

@media (max-width:820px) {
  :root { --nav-h:64px; --section-y:clamp(36px,7vw,56px); }
}

*,*::before,*::after { box-sizing:border-box; }
html { scroll-behavior:smooth; }
/* Une ancre ne doit pas glisser sous la barre collante. */
:target { scroll-margin-top:calc(var(--nav-h) + 16px); }
body {
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--font-body); font-size:var(--body); line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img { max-width:100%; }
a { color:inherit; text-decoration:none; }

h1,h2,h3,h4 {
  font-family:var(--font-title); font-weight:700; line-height:1.04;
  letter-spacing:var(--track-title); margin:0;
  /* Rajdhani en capitales : c'est là qu'elle ressemble au logo. */
  text-transform:uppercase;
}
h1 { font-size:var(--h1); }
h2 { font-size:var(--h2); }
h3 { font-size:var(--h3); line-height:1.2; }
/* Le rouge dans un titre souligne UN mot — celui qui porte le sens. */
h1 span.hl, h2 span.hl, h3 span.hl { color:var(--red); }

/* Le surtitre : il situe la section avant qu'on lise le titre. Petit et très
   espacé, donc en --red-text : le rouge d'aplat n'y serait pas lisible. */
/* ⚠️ **700 et non 600, et c'est une optimisation** (2026-07-28). Le surtitre
   était le seul usage de la graisse 600 sur les pages publiques — il faisait
   donc télécharger `rajdhani-latin-600.woff2` (**15,4 Ko**) partout. Comparé à
   l'écran en 600 et en 700 sur des capitales de 13 px très espacées : **aucune
   différence perceptible**. La graisse 600 reste chargée, mais seulement là où
   elle se voit vraiment — le « Bonjour X » du QG (`.qg-hello`), où la nuance
   avec le nom en gras, elle, se lit nettement. */
.eyebrow {
  font-family:var(--font-title); font-weight:700; font-size:.82rem;
  text-transform:uppercase; letter-spacing:var(--track-eyebrow);
  color:var(--red-text); margin:0 0 12px;
}
.lead { color:#C9CDD5; font-size:clamp(1.02rem,.98rem + .35vw,1.22rem); }
.muted { color:var(--muted); }
.faint { color:var(--faint); }
.num { font-variant-numeric:tabular-nums; }

/* --- Accessibilité : le focus se voit ---
   Relevé à l'audit : au clavier, rien n'indiquait où on était. Le rouge sert
   ici parce que c'est exactement son emploi — un état actif. */
:focus-visible {
  outline:2px solid var(--red); outline-offset:3px; border-radius:2px;
}
/* Le lien d'évitement : premier tabulé de la page, invisible à la souris. */
.skip {
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--red); color:#fff; padding:.7rem 1.1rem; font-weight:600;
}
.skip:focus { left:12px; top:12px; }
.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* --- Boutons : UNE seule famille pour tout le site ---
   ⚠️⚠️ **Refonte du 2026-07-28.** Le bouton pesait 52 px, en Rajdhani capitales
   de 16 px, avec un coin coupé — pendant que le QG servait ses raccourcis en
   pastilles de 36 px, en Inter, en casse normale. Deux familles pour un même
   geste, souvent **dans la même page** : la barre d'actions du QG et le « Voir
   l'événement » juste dessous. Kevin l'a tranché en regardant : « la taille des
   boutons me plaît mieux [sur les pastilles], si tous les boutons du site
   pouvaient être du même style, dimension, car ils sont en général tous trop
   gros. »

   Ce qui change, et pourquoi :
   - **la hauteur** : `--btn-h`, une seule valeur pour le bouton et la pastille ;
   - **la casse** : Rajdhani en capitales est superbe en titre et pénible à lire
     à 14 px sur deux mots ; le libellé reprend la police de texte, en casse
     normale, comme la pastille ;
   - **le coin coupé disparaît** : à 52 px l'entaille de 10 px était un détail,
     à 38 px elle mange le quart de la hauteur et le bouton penche. Les angles du
     logo restent portés par les badges, les séparateurs et le héros — ils ne
     tenaient pas à ce seul biseau.

   ⚠️ **La hiérarchie tient donc à la COULEUR, plus à la taille** — exactement la
   règle des pastilles du QG. Trois niveaux : `primary` (rouge, l'action qu'on
   veut), la base (l'alternative), `ghost` (le geste de service, sans aplat). */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  min-height:var(--btn-h); padding:0 18px;
  font-family:var(--font-body); font-weight:600; font-size:.875rem;
  letter-spacing:.01em; line-height:1.2; text-align:center;
  border:1px solid var(--line-strong); background:var(--surface-2);
  color:var(--text); cursor:pointer;
  border-radius:var(--r-sm);
  transition:background var(--t-fast),border-color var(--t-fast),
             transform var(--t-fast),color var(--t-fast);
}
.btn:hover { border-color:var(--red-line); background:#212734;
             transform:translateY(var(--lift)); }
.btn.primary {
  background:linear-gradient(135deg,var(--red),var(--red-dark));
  border-color:var(--red); color:#fff;
}
.btn.primary:hover { filter:brightness(1.1); border-color:var(--red); }
/* 🐞 **`ghost` était utilisé cinq fois dans le QG sans exister dans la
   feuille** : le bouton rendait comme la base, et la nuance annoncée par le nom
   de classe n'existait qu'en intention. Elle existe maintenant — fond
   transparent, trait discret : le geste de service se lit comme tel. */
.btn.ghost { background:transparent; border-color:var(--line); color:var(--muted); }
.btn.ghost:hover { background:var(--surface-2); border-color:var(--red-line);
                   color:var(--text); }
/* ⚠️ Les trois variantes de taille ne changent plus la HAUTEUR — elles
   resserrent. Depuis que la base est à 38 px, un « petit » bouton à 30 px
   repasserait sous la barre tactile, et un site à quatre tailles de bouton est
   précisément ce que cette refonte enlève. Elles restent parce que le HTML les
   porte à ~20 endroits et qu'elles disent quelque chose de vrai : ce bouton-là
   vit dans une ligne serrée. */
.btn.sm, .btn.small, .btn.tiny {
  min-height:var(--btn-h-sm); padding:0 14px; font-size:.82rem;
}

/* --- Cartes --- */
.card {
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r); padding:clamp(18px,2.4vw,26px);
}

/* --- Badges --- */
.badge {
  display:inline-flex; align-items:center; gap:.35rem;
  padding:.2rem .6rem; font-size:.76rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.05em;
  background:var(--surface-2); border:1px solid var(--line); color:var(--muted);
  border-radius:var(--r-sm);
  clip-path:polygon(0 0,calc(100% - 6px) 0,100% 6px,100% 100%,6px 100%,0 calc(100% - 6px));
}
.badge.hot { background:var(--red-soft); border-color:var(--red-line); color:#FF6B84; }
.badge.gold { background:var(--gold-soft); border-color:rgba(201,162,39,.4); color:var(--gold); }

/* --- Contenu plus large que l'écran ---
   Il défile DANS son cadre ; la page, jamais. Sans ça, le tableau 5 colonnes de
   l'armurerie (largeur minimale mesurée à ~443 px) pousse toute la mise en page
   de côté sur un 360 — le point que l'audit signalait comme non vérifié.
   `tabindex` : une zone qui défile doit être atteignable au clavier. */
.scroll-x {
  overflow-x:auto; -webkit-overflow-scrolling:touch;
  scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent;
}
.scroll-x > table { min-width:30rem; }

/* --- Séparateur : un trait qui s'éteint, pas une règle pleine largeur --- */
.sep {
  height:1px; border:0; margin:0;
  background:linear-gradient(90deg,transparent,var(--line-strong) 20%,
             var(--line-strong) 80%,transparent);
}

/* --- Apparition au scroll ---
   L'état de départ n'est posé que si le JS a pris la main (`.js` sur <html>) :
   sans JavaScript, le contenu doit rester visible, pas transparent à jamais. */
.js .reveal { opacity:0; transform:translateY(14px);
              transition:opacity var(--t),transform var(--t); }
.js .reveal.seen { opacity:1; transform:none; }

/* --- États de chargement ---
   Un squelette, pas un sablier : le cadre garde **la taille et la forme** de ce
   qui arrive, donc rien ne saute quand la donnée s'affiche. Un sablier centré
   dit « attends » ; un squelette dit « voilà ce qui vient ». C'est le relevé
   n°10 de l'audit (aucun état de chargement), traité une fois pour toutes les
   pages plutôt que dans le coin d'un composant.
   `--skel-h` laisse chaque écran dimensionner ses barres sans redéfinir la règle. */
.skel {
  display:block; height:var(--skel-h,14px); border-radius:6px;
  background:linear-gradient(90deg,var(--surface-2) 25%,var(--line-strong) 37%,
             var(--surface-2) 63%);
  background-size:400% 100%; animation:skel 1.4s ease infinite;
}
@keyframes skel { from { background-position:100% 50%; }
                  to   { background-position:0 50%; } }

/* ═══════════════════════════════════════════════════════════════════════════
   ⚔️  LE SYSTÈME DE MOUVEMENT — « l'entaille »
   ═══════════════════════════════════════════════════════════════════════════
   Kevin, 2026-07-28 : « je veux de l'animation, des effets visuels, des
   couleurs qui rappellent le logo, que ce soit agressif et attractif ».

   **Le parti pris, en une phrase** : tout le mouvement du site est une
   **entaille** — un trait oblique qui passe. Jamais une pulsation ronde, jamais
   un halo qui respire. Le sigle NRV est fait de lacérations ; le site bouge
   comme lui. Un seul angle (`--biais`) gouverne les balayages de survol,
   l'ouverture des cartes, les traits lumineux et les coins coupés : c'est ce
   qui fait qu'un bouton, une carte et un séparateur ont l'air de venir du même
   endroit.

   ⚠️ **Trois règles techniques, non négociables** :
   1. **`transform` et `opacity` seulement.** Animer une largeur, une couleur ou
      un `box-shadow` fait recalculer et repeindre la page à chaque image ; sur
      un portable, c'est là que le site devient poussif. Ces deux propriétés-là
      sont traitées par la carte graphique.
   2. **Rien qui tourne en boucle au-dessus de 8 s.** Un mouvement lent se
      **remarque** au lieu de se ressentir. Les balayages de fond sont à 7 s et
      à moins de 8 % d'opacité : on les voit du coin de l'œil, jamais en face.
   3. **`prefers-reduced-motion` coupe tout** (bloc en bas de fichier). Ce n'est
      pas du goût, c'est WCAG 2.3.3, et l'accessibilité est une exigence
      permanente du brief. */

/* --- 1. L'apparition : une lame qui découvre ---
   L'ancien `.reveal` montait de 14 px en fondu. Il garde ce mouvement, et
   gagne l'entaille : le bloc se dévoile derrière un bord oblique, comme si on
   l'avait tranché. `clip-path` s'anime sur le compositeur, donc gratuitement.
   ⚠️ `--i` (posé par le script) décale chaque carte d'une rangée : une grille
   qui apparaît d'un bloc paraît figée, une grille qui se dévoile de gauche à
   droite paraît vivante. Plafonné à 6 crans — au-delà, on attend. */
.js .reveal {
  opacity:0; transform:translateY(14px);
  clip-path:polygon(0 0,100% 0,100% 100%,0 100%);
  transition:opacity var(--t),transform var(--t),clip-path var(--t);
  transition-delay:calc(var(--i,0) * 70ms);
}
.js .reveal.seen { opacity:1; transform:none; }

/* --- 2. Le balayage : la signature du survol, **sur les BOUTONS seulement** ---
   Un éclat oblique traverse l'élément une fois, de gauche à droite. Il ne
   revient pas et ne boucle pas : c'est une réponse au geste, pas une
   décoration.

   ⚠️⚠️ **RETIRÉ DES CARTES le 2026-07-28** (Kevin : « l'animation flash du
   survol de la souris sur une fenêtre »). Adoucir ne suffisait pas, parce que
   le défaut n'était pas l'intensité mais **l'échelle** : le même éclat qui fait
   une seconde de vie sur un bouton de 38 sur 190 px traverse une carte de
   700 sur 350 px comme un projecteur. Et sur un tableau de bord, la souris
   survole **une carte après l'autre** en cherchant l'information — on
   déclenchait donc une lumière à chaque passage, pour un élément qu'on ne
   clique même pas la plupart du temps.
   ➡️ Une carte répond autrement, et c'est **plus précis** : son trait passe au
   rouge, elle monte de 2 px, et l'entaille apparaît dans son angle. Trois
   signaux localisés valent mieux qu'un éclairage général.
   💡 **La règle qui en sort** : le balayage appartient à ce qu'on **clique
   volontairement** (un bouton), jamais à ce qu'on **traverse** (une carte).
   ⚠️ `overflow:hidden` + `isolation` : sans quoi l'éclat déborde du rayon. */
.btn { position:relative; overflow:hidden; isolation:isolate; }
.lame { position:relative; overflow:hidden; }
/* ⚠️⚠️ **Adouci le 2026-07-28** (Kevin : « l'animation flash est un peu trop
   pétante et flash rapide »). Il avait raison, et le défaut était double :
   - **le blanc pur** à 13 % (28 % sur le bouton rouge) sur un fond noir, c'est
     un éclair d'appareil photo, pas un reflet — et il ne vient d'aucune couleur
     du site ;
   - **0,55 s en `ease-in-out`**, c'est un aller-retour qui *claque* : la lueur
     accélère au milieu, là où l'œil la suit.
   ➡️ Elle passe à **0,95 s en décélération** (`ease-out` : elle entre vite et
   s'éteint doucement, comme une lame qu'on retire), le blanc devient un
   **reflet teinté du rouge NRV** à 6 %, et les bords du dégradé sont **étalés**
   (20 %/50 %/80 % au lieu de trois arrêts serrés) pour qu'il n'y ait aucune
   arête franche à voir passer. */
.btn::after {
  content:""; position:absolute; z-index:-1; inset:-2px -40%;
  background:linear-gradient(90deg,transparent 18%,
             rgba(255,214,222,.06) 50%,transparent 82%);
  transform:translateX(-120%) var(--biais-t);
  transition:transform .95s cubic-bezier(.16,.84,.44,1);
  pointer-events:none;
}
.btn:hover::after { transform:translateX(120%) var(--biais-t); }
/* Sur le bouton rouge, le reflet est un peu plus présent — c'est l'action
   qu'on veut — mais il reste très en dessous de l'ancien blanc à 28 %. */
.btn.primary::after {
  background:linear-gradient(90deg,transparent 18%,
             rgba(255,255,255,.11) 50%,transparent 82%);
}

/* --- 3. La carte qui répond ---
   Au survol : elle monte de 2 px (pas 4 — une carte n'est pas un bouton), son
   trait passe au rouge, et une **entaille rouge** apparaît dans l'angle haut
   droit. C'est le clin d'œil au logo, et il ne coûte qu'un pseudo-élément. */
.lame { transition:transform var(--t-fast),border-color var(--t-fast); }
.lame:hover { transform:translateY(-2px); border-color:var(--red-line); }
.lame::before {
  content:""; position:absolute; top:0; right:0; width:34px; height:34px;
  background:linear-gradient(var(--biais),transparent 48%,var(--red) 48%,
             var(--red) 56%,transparent 56%);
  opacity:0; transition:opacity var(--t-fast); pointer-events:none;
}
.lame:hover::before { opacity:.85; }

/* --- 4. Le trait qui vit ---
   Le séparateur `.sep` portait un dégradé fixe. Un éclat le parcourt
   maintenant, très lentement et très discrètement : c'est ce qui donne
   l'impression que la page est sous tension plutôt qu'imprimée. */
.sep { position:relative; overflow:hidden; }
/* ⚠️ **Deux fois plus lent et deux fois plus discret** (même retour). Un éclat
   vif qui traverse toutes les 7 s se **remarque** — donc on le regarde, donc il
   coûte l'attention qu'on voulait mettre ailleurs. À 14 s et 32 %, il se
   ressent : on sait que la page est sous tension sans savoir pourquoi.
   Le trait est aussi plus **large** (34 % au lieu de 22 %) : plus il est étalé,
   moins son passage a d'arête. */
.sep::after {
  content:""; position:absolute; inset:0; width:34%;
  background:linear-gradient(90deg,transparent,var(--red),transparent);
  animation:balayage var(--t-slow) linear infinite;
  opacity:.32;
}
@keyframes balayage {
  from { transform:translateX(-120%); }
  to   { transform:translateX(560%); }
}

/* --- 5. Le titre qui se pose ---
   Le mot rouge d'un titre (`span.hl`) est souligné d'une entaille qui se
   déploie quand la section apparaît. Elle part de zéro et s'ouvre : le titre
   « se signe » lui-même. */
h1 span.hl, h2 span.hl { position:relative; }
h1 span.hl::after, h2 span.hl::after {
  content:""; position:absolute; left:0; right:0; bottom:-.12em; height:3px;
  background:linear-gradient(90deg,var(--red),transparent);
  transform:scaleX(0) var(--biais-t); transform-origin:left;
  transition:transform .7s cubic-bezier(.4,0,.2,1) .2s;
}
.reveal.seen h1 span.hl::after, .reveal.seen h2 span.hl::after,
h1.seen span.hl::after, h2.seen span.hl::after { transform:scaleX(1) var(--biais-t); }

/* --- 6. Le focus clavier, lui aussi ---
   Le contour rouge arrive maintenant avec une très courte impulsion : au
   clavier, on veut *voir* où l'on vient d'atterrir, pas le déduire. */
/* ⚠️ Le contour de focus se **pose**, il ne claque pas : 0,35 s en
   décélération et un écart de départ réduit (6 px au lieu de 9). Il doit dire
   « tu es ici », pas attirer le regard comme une alerte. */
:focus-visible { animation:atterrissage .35s cubic-bezier(.16,.84,.44,1); }
@keyframes atterrissage {
  from { outline-offset:6px; }
  to   { outline-offset:3px; }
}

/* --- Le mouvement est une option, pas un dû --- */
@media (prefers-reduced-motion:reduce) {
  html { scroll-behavior:auto; }
  *,*::before,*::after {
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
  .js .reveal { opacity:1; transform:none; clip-path:none; }
  .btn:hover, .lame:hover { transform:none; }
  /* Le squelette redevient un aplat : sa **présence** dit déjà « ça charge »,
     le scintillement n'y ajoute rien pour qui a demandé le calme. */
  .skel { animation:none; background:var(--surface-2); }
  /* ⚠️⚠️ **Tout le système d'entailles s'éteint ici**, et il faut le faire
     élément par élément : `animation-duration:.01ms` (la règle globale
     au-dessus) accélère les boucles mais laisse un balayage traverser l'écran
     en un éclair — pire qu'une animation lente pour quelqu'un qui a demandé le
     calme. On les **supprime**, on ne les précipite pas. */
  .sep::after { animation:none; display:none; }
  .btn::after { display:none; }
  .lame::before { transition:none; }
  h1 span.hl::after, h2 span.hl::after { transform:scaleX(1) var(--biais-t);
                                         transition:none; }
  :focus-visible { animation:none; }
}

body{background:radial-gradient(1100px 620px at 50% -12%,#141821,var(--bg) 62%)
      no-repeat,var(--bg)}

/* ===================== Barre de navigation collante =====================
   Une seule barre pour TOUTES les pages publiques (avant, l'accueil avait la
   sienne dans le héros et les autres pages une autre : deux navigations à
   tenir à jour, et le lien actif ne se voyait pas pareil). */
.topbar{
  position:sticky; top:0; z-index:50;
  height:var(--nav-h); display:flex; align-items:center; gap:1rem;
  padding:0 var(--gutter);
  border-bottom:1px solid var(--line);
  background:rgba(7,8,11,.88);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  backdrop-filter:blur(14px) saturate(140%);
  transition:background var(--t-fast),border-color var(--t-fast);
}
/* Sur l'accueil, la barre flotte AU-DESSUS du héros : la marge négative fait
   remonter le héros sous elle, sans le pousser de 76 px vers le bas. */
.topbar.over{
  margin-bottom:calc(-1 * var(--nav-h));
  background:linear-gradient(rgba(0,0,0,.55),transparent);
  border-bottom-color:transparent; backdrop-filter:none;
}
/* Dès qu'on a scrollé, elle redevient une barre : sinon les liens se perdent
   dans l'image. Classe posée par le JS ; sans JS elle reste translucide, ce
   qui est le pire cas acceptable. */
.topbar.over.solid{
  background:rgba(7,8,11,.92); border-bottom-color:var(--line);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  backdrop-filter:blur(14px) saturate(140%);
}
.brand{display:flex;align-items:center;gap:12px;font-family:var(--font-title);
  font-weight:700;font-size:1.4rem;text-transform:uppercase;letter-spacing:.06em;
  line-height:1}
.brand img{height:40px;width:40px;display:block}
.brand small{display:block;margin-top:2px;font-family:var(--font-body);
  font-size:.75rem;color:var(--muted);letter-spacing:.16em;font-weight:600;
  text-transform:uppercase}
.links{margin-left:auto;display:flex;gap:clamp(14px,1.8vw,26px);align-items:center}
.links a{position:relative;color:#C9CDD5;font-weight:600;font-size:.95rem;
  padding:6px 0;transition:color var(--t-fast)}
.links a:hover{color:#fff}
/* L'état actif : un trait rouge sous le lien. Le rouge sert ici à ce pour quoi
   il est fait — dire où l'on est. */
.links a.on{color:#fff}
.links a.on:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--red)}
.links a.staff{
  padding:0 16px;height:38px;display:inline-flex;align-items:center;color:#fff;
  border:1px solid var(--red-line);background:var(--red-soft);
  border-radius:var(--r-sm);
  clip-path:polygon(0 0,calc(100% - 8px) 0,100% 8px,100% 100%,0 100%);
  transition:background var(--t-fast),border-color var(--t-fast);
}
.links a.staff:hover{background:var(--red);border-color:var(--red)}
.links a.staff:after{display:none}
/* ⚠️ `min-height:36px` : mesuré à **33 px** le 2026-07-28, le dernier lien
   de la barre sous la cible tactile du site. La hauteur vient d'un
   remplissage — le texte garde sa taille et sa place. */
.links a.logout{color:var(--muted);font-size:.82rem;
  display:inline-flex;align-items:center;min-height:36px}
.links a.logout:hover{color:var(--red)}
/* La pastille des nouveautés. Le rouge sert ici à ce pour quoi la palette le
   réserve : signaler quelque chose qui demande une attention — pas décorer.
   ⚠️ `min-width` et non `width` : à deux chiffres, un cercle fixe rognerait le
   nombre. Elle grandit, elle ne tronque pas. */
.links .pastille{display:inline-flex;align-items:center;justify-content:center;
  min-width:19px;height:19px;margin-left:7px;padding:0 5px;border-radius:999px;
  background:var(--red);color:#fff;font-family:var(--font-title);font-weight:700;
  font-size:.75rem;line-height:1;vertical-align:middle}

/* Le bouton du menu mobile : trois traits qui deviennent une croix. */
.burger{display:none;margin-left:auto;width:44px;height:44px;padding:0;
  background:transparent;border:1px solid var(--line);border-radius:var(--r-sm);
  cursor:pointer;place-items:center;gap:5px;grid-auto-rows:2px}
.burger span{display:block;width:20px;height:2px;background:var(--text);
  transition:transform var(--t-fast),opacity var(--t-fast)}
.topbar.open .burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.topbar.open .burger span:nth-child(2){opacity:0}
.topbar.open .burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ============================== Héros ============================== */
/* ⚠️ **Hauteur revue le 2026-07-27** (Kevin : « la bannière est grande et vite
   vide »). Elle valait `min(88vh,760px)` : sur un écran large, ça faisait un
   grand aplat vide autour de trois lignes de texte, et la barre de chiffres —
   la vraie substance — passait sous la ligne de flottaison. Désormais la
   hauteur suit le contenu (`min-height` plancher, pas consigne), plafonnée à
   58vh : le titre reste grand, et on voit les chiffres sans faire défiler. */
.hero{position:relative;overflow:hidden;
  min-height:min(58vh,520px);display:flex;align-items:flex-end}
/* ⚠️ `banner-nrv.jpg` N'EST PAS le fond du héros, et ne doit pas le redevenir :
   elle porte « NET REALISABLE VALUE » **peint dessus**. Derrière un H1 qui dit
   la même chose, on lisait le nom deux fois, en travers l'un de l'autre — vu à
   l'écran, invisible dans le code, et c'est la redondance que Kevin a signalée.
   Assez floutée pour disparaître, elle laissait un rectangle noir (« trop
   sombre », qu'il exclut). Elle garde donc son vrai emploi : l'aperçu social
   (og:image), où ce texte est un atout.
   Le décor est fabriqué ici : une lueur rouge, deux entailles obliques dans la
   grammaire du logo, et le loup en filigrane. Aucune image lourde, aucun mot
   répété. */
.hero-media{position:absolute;inset:0;
  background:
    /* La lueur est **calée sur le loup** (70 %, à mi-hauteur) : c'est elle qui
       le pose sur le fond au lieu de le laisser flotter. */
    radial-gradient(720px 520px at 70% 48%,rgba(210,10,46,.20),transparent 68%),
    radial-gradient(900px 620px at 8% 104%,rgba(117,7,25,.26),transparent 72%),
    linear-gradient(180deg,#0B0E14,var(--bg) 80%)}
/* Les entailles : trois traits obliques, dont un seul franchement rouge. Le
   logo est fait de coups de lame ; on en reprend l'idée, pas le dessin.
   ⚠️ **Elles s'éteignent avant le loup** (masque à droite, 2026-07-27). Kevin :
   « je le trouve cassé / caché par le design barré rouge du fond ». Les traits
   traversaient le filigrane de part en part et le hachaient. Ils gardent donc
   la moitié gauche — celle du titre, où ils font le mouvement — et libèrent la
   droite, où le loup a besoin d'un fond calme. */
.hero-media:after{content:"";position:absolute;inset:0;
  background:
    linear-gradient(104deg,transparent 47.6%,rgba(210,10,46,.55) 47.9%,transparent 48.3%),
    linear-gradient(104deg,transparent 53.4%,rgba(241,242,244,.07) 53.6%,transparent 53.9%),
    linear-gradient(104deg,transparent 61.2%,rgba(210,10,46,.18) 61.6%,transparent 62.1%);
  -webkit-mask-image:linear-gradient(90deg,#000 0 42%,transparent 66%);
  mask-image:linear-gradient(90deg,#000 0 42%,transparent 66%)}

/* ---------------------- La vallée animée (WebGL) ----------------------
   Un canvas plein cadre, purement décoratif, dessiné par `_HERO_JS`. Il
   couvre `.hero-media` quand WebGL répond, et disparaît sinon.
   La classe `gl` n'est posée QUE si le rendu a démarré : tout ce qui
   suppose la vallée est accroché à elle, jamais au canvas seul. */
#hero-canvas{position:absolute;inset:0;width:100%;height:100%;display:block;
  opacity:0;transition:opacity .9s ease;pointer-events:none;z-index:0}
.hero.gl #hero-canvas{opacity:1}
/* ⚠️ Le loup passe de filigrane (0,16) à SUJET (0,92) — et seulement ici.
   Le commentaire de `.hero-mark` dit qu'un filigrane lisible devient un
   fond : c'était juste tant que le fond était un aplat CSS. Avec une
   vallée derrière lui, le loup n'est plus le fond, il est ce qui s'y
   tient — et à 0,16 il redevenait invisible. Sans WebGL, il reprend
   0,16 tout seul, la règle d'origine n'est pas touchée. */
.hero.gl .hero-mark{opacity:.92}
/* Le texte est désormais posé sur une image, plus sur un aplat : sans ces
   ombres portées il perd son contraste dès que la brume passe derrière. */
.hero.gl h1{text-shadow:0 2px 30px rgba(0,0,0,.85)}
.hero.gl .eyebrow,.hero.gl .lead{text-shadow:0 1px 16px rgba(0,0,0,.9)}
/* Le loup : l'identité sans un mot de plus.
   ⚠️ **Ramené vers le centre et agrandi le 2026-07-27** (Kevin : « plus ramené
   vers le centre, peut-être plus gros, pour donner du relief »). Il était collé
   au bord droit (`right:-1%`), donc quasi hors champ sur un écran large — il
   décorait le vide au lieu d'habiller le titre. Ancré à **62 %** : il tient
   compagnie au H1 sans passer dessous (mesuré à 1440 : à 62 % il
   chevauchait le titre, à 70 % il s'arrête juste après).
   La lueur rouge derrière lui fait le relief demandé ; l'opacité reste basse
   (0,11) parce qu'un filigrane qui se lit devient un fond, et le fond du héros
   est fabriqué en CSS, pas en image (voir plus haut). */
/* ⚠️ **Ancré au bord droit de la zone de contenu**, pas à un pourcentage de
   l'écran : c'est ce qui garantit qu'il ne touche jamais le titre, quelle que
   soit la largeur (le titre, lui, s'arrête forcément avant ce bord). Mesuré à
   1024, 1440 et 1920 : l'écart ne descend jamais sous 100 px. */
.hero-mark{position:absolute;top:50%;left:auto;
  right:calc((100vw - min(var(--wrap),92vw)) / 2 - 90px);transform:translateY(-50%);
  width:clamp(240px,24vw,420px);height:auto;opacity:.16;pointer-events:none;
  /* Un contre-jour, pas un halo : la lueur sort du dessin et retombe, ce qui
     donne le relief demandé sans allumer la page. */
  filter:drop-shadow(0 22px 46px rgba(0,0,0,.85))
         drop-shadow(0 0 90px rgba(210,10,46,.45));
  -webkit-user-select:none;user-select:none}
/* Sous 1024 px, le titre occupe toute la largeur : le loup repart sur le bord
   et rapetit, sinon il passe derrière le texte au lieu de l'accompagner. */
/* Sous 1024 px le titre prend toute la largeur : le loup ne peut plus être à
   côté. Il passe **derrière, plus haut et plus effacé** — un filigrane, pas un
   voisin. C'est le seul cas où il se superpose au texte, et à 6 % il ne le
   gêne pas. */
@media(max-width:1024px){
  .hero-mark{top:34%;right:-10%;width:clamp(220px,44vw,340px);opacity:.06}
}
/* Le liseré rouge du bas, qui accroche la barre de chiffres. */
.hero:after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:linear-gradient(90deg,var(--red),var(--red-dark) 40%,transparent 80%)}

/* ---------------------------- MODE CINÉMA -----------------------------
   La vallée animée mérite mieux qu'un bandeau de 58vh : ce mode lui donne
   l'écran entier, efface tout le reste, et fait défiler les chiffres RÉELS
   de la guilde par-dessus. Une bande-annonce dont rien n'est inventé.

   ⚠️ **Il n'y a AUCUN bouton pour l'ouvrir** (Kevin, 2026-07-27 : « enlève le
   bouton mode cinéma, par contre l'affichage en mode cinéma pourrait servir
   d'entrée de page »). C'est devenu l'entrée du site : elle s'ouvre seule à la
   première arrivée, puis s'efface. Personne ne clique sur « mode cinéma » ;
   tout le monde passe par l'entrée.

   ⚠️ Tout est accroché à `.hero.gl` : sans WebGL, pas d'intro. Passer un aplat
   CSS en plein écran n'aurait rien de spectaculaire — et l'intro serait alors
   un temps d'attente offert à personne. */
/* Le héros quitte le flux et prend tout : `fixed`, pas `absolute` — il doit
   rester en place même si la page avait été défilée avant. */
body.cinema{overflow:hidden}
body.cinema .hero{position:fixed;inset:0;height:100dvh;z-index:9999;
  border:0;margin:0}
body.cinema .hero:after{display:none}
/* Le reste de la page ne se contente pas d'être caché derrière : il est retiré
   du rendu, sinon la barre collante reste au-dessus de tout. */
body.cinema .topbar,body.cinema main,body.cinema .site-footer,
body.cinema .stats{display:none}
/* Le loup, en grand et centré : c'est lui l'affiche.
   ⚠️ **Opacité 0,22 et non 0,42** : à 0,42 son blanc passait à travers les
   cartons de chiffres et « 4 105 » devenait illisible (vu à l'écran). En mode
   cinéma il redevient ce qu'il était sur la page — un filigrane, pas un
   concurrent du texte posé dessus. */
/* ⚠️ **`.hero.gl` dans le sélecteur, sinon la règle ne s'applique pas.**
   `.hero.gl .hero-mark` pèse trois classes et gagnait contre `body.cinema
   .hero-mark` (deux classes) : le loup restait à 0,92 et écrasait les chiffres.
   Vu à l'écran — la valeur était juste, elle n'était simplement jamais lue. */
body.cinema .hero.gl .hero-mark{top:50%;right:auto;left:50%;
  transform:translate(-50%,-50%);width:clamp(300px,42vw,620px);opacity:.22}
/* Le texte est posé sur une image : sans ombre portée il perd tout contraste
   dès qu'il croise le loup ou une balafre. */
body.cinema .hero-inner .eyebrow,body.cinema .cine-carton b,
body.cinema .cine-carton span,body.cinema .hero .lead{
  text-shadow:0 2px 18px rgba(0,0,0,.95)}
body.cinema .hero-inner{position:absolute;inset:0;display:grid;
  place-content:center;text-align:center;padding:0 24px;width:100%}
body.cinema .hero h1{font-size:clamp(2.2rem,7vw,5.6rem)}
/* Les cartons de chiffres, sous le titre. Ils apparaissent l'un après l'autre
   puis restent : une bande-annonce qui efface ses informations oblige à la
   regarder deux fois. */
.cine-cartons{display:flex;flex-wrap:wrap;gap:clamp(18px,4vw,52px);
  justify-content:center;margin-top:clamp(24px,4vw,44px)}
.cine-carton{opacity:0;animation:cine-entree .9s ease forwards}
.cine-carton b{display:block;font-family:var(--font-title);font-weight:700;
  font-size:clamp(1.8rem,4.4vw,3.4rem);line-height:1;color:var(--text)}
.cine-carton span{display:block;margin-top:6px;font-size:.75rem;color:var(--muted);
  text-transform:uppercase;letter-spacing:.1em}
@keyframes cine-entree{from{opacity:0;transform:translateY(14px)}
  to{opacity:1;transform:none}}
.cine-sortie{position:fixed;top:20px;right:20px;z-index:10000;
  padding:9px 16px;border-radius:999px;cursor:pointer;
  background:rgba(8,9,12,.62);border:1px solid var(--line);color:var(--text);
  font-family:var(--font-title);font-weight:700;font-size:.76rem;
  text-transform:uppercase;letter-spacing:.07em}
.cine-sortie:hover{border-color:var(--red)}
/* ⚠️ Animations réduites : les cartons apparaissent d'un coup plutôt que de
   monter. Le mode reste utilisable — c'est l'effet qu'on retire, pas la
   fonction. */
@media (prefers-reduced-motion:reduce){
  .cine-carton{animation:none;opacity:1}
}
.hero-inner{position:relative;z-index:1;
  width:min(var(--wrap),92vw);margin:0 auto;
  padding:calc(var(--nav-h) + clamp(28px,5vw,56px)) 0 clamp(32px,5vw,56px)}
/* ⚠️ **Le nom tient sur UNE ligne** (Kevin, 2026-07-27 : « écrire le nom entier
   dans sa largeur »). Il était plafonné à 16 caractères et cassait en deux —
   « NET REALISABLE / VALUE », ce qui coupait le nom en son milieu.
   La taille est donc pilotée par la **largeur de la fenêtre** (`vw`) et non par
   le pas typographique commun : c'est la seule façon qu'une ligne de 20
   caractères reste entière de 360 px à un ultrawide. Mesuré aux deux bouts. */
.hero .eyebrow{margin-bottom:14px;font-size:.8rem;letter-spacing:.3em}
/* ⚠️ **Plafonné à 4,6rem, et ce plafond n'est pas cosmétique** : sans lui, un
   titre en `vw` continue de grandir alors que la zone de contenu, elle, est
   bloquée à 1240 px — sur un ultrawide il sortait du cadre et venait toucher
   le loup (signalé par Kevin le 2026-07-27). Les deux sont désormais calés sur
   la **même** zone de contenu, avec un écart garanti (voir `.hero-mark`). */
.hero h1{max-width:none;white-space:nowrap;font-size:clamp(1.6rem,5.6vw,4.6rem);
  line-height:1.04}
/* Le sous-titre remonte d'un cran : c'est lui qui dit ce qu'on joue, il ne doit
   pas être une note de bas de page sous un titre géant. */
.hero .lead{max-width:52ch;margin:18px 0 0;font-size:clamp(1rem,.9rem + .5vw,1.3rem);
  color:#C9CED8}
.cta-row{display:flex;gap:14px;flex-wrap:wrap;margin-top:clamp(26px,3vw,36px)}

/* ====================== Barre de chiffres ======================
   Sous le héros, quatre faits. Tous viennent de la base : aucun n'est écrit
   en dur, et la barre disparaît entièrement quand il n'y a rien à dire. */
.stats{border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,var(--surface),rgba(17,20,26,0))}
/* Le nombre de cases VARIE (3, 4 ou 5) : une case n'apparaît que si la base a
   de quoi la remplir. D'où `grid-auto-flow:column` plutôt qu'un nombre de
   colonnes figé — c'était `repeat(4,1fr)`, et la cinquième passait à la ligne
   toute seule au milieu de la barre. */
.stats-wrap{width:min(var(--wrap),92vw);margin:0 auto;
  display:grid;grid-auto-flow:column;grid-auto-columns:1fr}
/* ⚠️ **Barre resserrée le 2026-07-27** (Kevin : « la réduire, plus en mode
   détails, toujours sur la largeur de page, mais plus petite »). Elle garde
   ses cinq colonnes sur toute la largeur ; ce sont la hauteur et la taille des
   chiffres qui baissent — c'est une ligne de faits, pas une affiche. */
.stat{position:relative;padding:clamp(14px,1.7vw,20px) clamp(8px,1.6vw,18px);
  text-align:center}
.stat + .stat:before{content:"";position:absolute;left:0;top:24%;bottom:24%;
  width:1px;background:var(--line)}
.stat-n{display:block;font-family:var(--font-title);font-weight:700;line-height:1;
  font-size:clamp(1.35rem,.9rem + 1.3vw,1.9rem);letter-spacing:var(--track-title)}
/* Le doré, exactement pour ce à quoi il est réservé : une distinction. */
.stat-n.gold{color:var(--gold)}
.stat-n.txt{font-size:clamp(1.1rem,.85rem + .8vw,1.5rem)}
.stat-l{display:block;margin-top:6px;font-size:.75rem;text-transform:uppercase;
  letter-spacing:.14em;color:var(--muted)}
.stat-note{display:block;margin-top:3px;font-size:.75rem;color:var(--faint)}

/* ============================ Sections ============================ */
.section{width:min(var(--wrap),92vw);margin:0 auto;padding:var(--section-y) 0;
  position:relative}
/* --- Le trait de séparation entre deux sections ---
   Demandé par Kevin le 2026-07-27 (« un p'tit trait lissé, laser, en
   décoration pour indiquer la séparation »). Un **trait qui s'allume au
   centre et s'éteint aux bords** : une règle pleine largeur couperait la page
   en morceaux, alors qu'on veut seulement marquer le passage.
   Il ne se pose qu'ENTRE deux sections (`+`), jamais au-dessus de la
   première ni sous la dernière. */
.section + .section:before{content:"";position:absolute;top:0;left:8%;right:8%;
  height:1px;background:linear-gradient(90deg,transparent,
    rgba(210,10,46,.55) 35%,rgba(255,74,99,.85) 50%,rgba(210,10,46,.55) 65%,
    transparent)}
/* La lueur, très basse : elle se voit sur du noir, sans éclairer la page. */
.section + .section:after{content:"";position:absolute;top:-2px;left:26%;right:26%;
  height:5px;background:radial-gradient(60% 100% at 50% 50%,
    rgba(210,10,46,.22),transparent 70%);pointer-events:none}
.section h2{margin:0 0 16px}
.section h2 span,.hero h1 span,.armory h1 span,
.recruit h1 span,.recruit h2 span{color:var(--red)}
.section > p{color:var(--muted);max-width:66ch}

/* --- Présentation + aperçu Discord --- */
/* ⚠️ Kevin, 2026-07-27, en deux temps : la carte était « un peu petite », je
   l'ai élargie (1fr/1fr), et il a tranché — « plus haut, pas forcément plus
   large, je voudrais voir plus de chans, tu peux réduire la largeur », puis
   « encore un peu moins large », deux fois. Mesuré à 1440 : 1fr/1fr → 604 px,
   1,35fr → 514, 1,6fr → 465, **1,9fr → 414**, la valeur retenue. Tout
   l'agrandissement passe donc par la **hauteur** (voir `.live`). */
.about{display:grid;grid-template-columns:1.9fr 1fr;gap:var(--gap);align-items:start}
.widget-card{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden}
.widget-head{display:flex;align-items:center;gap:8px;padding:14px 18px;
  font-family:var(--font-title);font-weight:700;font-size:1rem;
  text-transform:uppercase;letter-spacing:.06em;
  border-bottom:1px solid var(--line);background:var(--surface-2)}
.widget-head b{color:var(--red)}
.widget-empty{padding:40px 20px;text-align:center;color:var(--muted);font-size:.9rem}
.widget-foot{margin:0;padding:12px 18px;font-size:.78rem;color:var(--muted);
  border-top:1px solid var(--line)}

/* --- Le widget maison (remplace l'iframe de Discord) ---
   Hauteur minimale : le cadre occupe sa place AVANT que les chiffres arrivent,
   sinon la section « Qui sommes-nous » sauterait au moment de la réponse.
   ⚠️ **750 px** : demandé par Kevin (« plus haut, je voudrais voir plus de
   chans »), et la place existe — la section « Qui sommes-nous » laissait un
   grand vide sous la carte. La hauteur est **réservée d'avance** parce qu'une
   carte qui grandit à l'arrivée de la réponse fait sauter toute la page
   (mesuré : 190 px de saut quand elle ne l'était pas). C'est aussi pourquoi
   l'arborescence est plafonnée : sans plafond, la hauteur finale dépendrait du
   nombre de salons, donc de qui regarde. */
.live{padding:20px;min-height:750px}
/* Les squelettes n'existent que si le JavaScript répond : sans lui, ils
   attendraient une donnée qui n'arrivera jamais. */
.live-skel{display:none;gap:12px}
.js .live-skel{display:grid}
.live-skel .skel-n{--skel-h:34px;width:52%}
.live-skel .skel-l{--skel-h:12px;width:72%}
.live-skel .skel-p{--skel-h:12px;width:88%}
/* Sans JavaScript, les squelettes ne se rempliraient jamais : on montre la
   phrase à la place. Même règle que les filtres de l'armurerie. */
.js .live-noscript{display:none}
.live-noscript{margin:0;color:var(--muted);font-size:.92rem}
.live-top{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.live-n{font-family:var(--font-title);font-weight:700;line-height:1;
  font-size:clamp(2rem,1.2rem + 1.8vw,2.6rem);font-variant-numeric:tabular-nums}
.live-lab{color:var(--muted);font-size:.95rem}
.live-tags{list-style:none;display:flex;flex-wrap:wrap;gap:8px 16px;
  margin:14px 0 0;padding:0;font-size:.86rem;color:var(--muted)}
.live-tags li{display:flex;align-items:center;gap:7px}
/* La pastille ne porte PAS l'information à elle seule : le mot est écrit à
   côté (même correctif que les couleurs de classe de l'armurerie). */
.pt{width:9px;height:9px;border-radius:50%;display:inline-block;flex:none}
.pt.on{background:#3ba55d}.pt.idle{background:#faa81a}.pt.dnd{background:#ed4245}
.live-game{margin:14px 0 0;font-size:.9rem}
.live-game b{color:var(--red-text)}
/* Les deux blocs sont EMPILÉS, jamais côte à côte : la carte est étroite par
   choix, et deux colonnes de 180 px n'auraient été lisibles ni l'une ni
   l'autre. « En ligne » d'abord (c'est ce qui bouge), les salons ensuite (c'est
   ce qui est long). Chacun sa fenêtre de défilement, donc une hauteur qui ne
   dépend ni du nombre de connectés ni du nombre de salons. */
.live-cols{display:grid;grid-template-columns:1fr;gap:14px;
  margin:16px 0 0;padding:14px 0 0;border-top:1px solid var(--line)}
.live-tree{max-height:560px}

/* L'arborescence du serveur, telle que le grade du visiteur l'autorise.
   Elle défile DANS la carte : un Discord fourni ferait une page d'accueil
   interminable (même principe que `.scroll-x` pour les tableaux). */
.live-tree{overflow-y:auto;scrollbar-width:thin;
  scrollbar-color:var(--line-strong) transparent}
/* Qui est dans un salon vocal — en retrait sous le salon, comme dans Discord.
   La liste n'existe que pour les visiteurs reconnus : le serveur ne l'envoie
   pas aux autres. Rien à masquer en CSS, donc rien à contourner. */
.live-in{list-style:none;margin:2px 0 6px;padding:0 0 0 26px;display:grid;gap:3px}
.live-in li{display:flex;align-items:center;gap:8px;font-size:.82rem;
  color:var(--text);padding:1px 0}
.live-in .vname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.live-in .pt{width:7px;height:7px}
.live-cat{margin:12px 0 6px;font-size:.75rem;text-transform:uppercase;
  letter-spacing:.12em;color:var(--faint)}
.live-cat:first-child{margin-top:0}
.live-rooms{list-style:none;margin:0;padding:0;display:grid;gap:4px}
.live-rooms li{display:flex;align-items:center;gap:8px;font-size:.88rem;
  color:var(--muted);padding:2px 0}
/* Un salon vocal occupé remonte en couleur pleine : c'est là que ça se passe. */
.live-rooms li.ici{color:var(--text)}
.live-rooms .ric{color:var(--faint);width:1.1em;text-align:center;flex:none}
.live-rooms li.ici .ric{color:var(--red-text)}
.live-rooms .vn{margin-left:auto;color:var(--muted);font-size:.82rem;
  font-variant-numeric:tabular-nums;background:var(--surface-2);
  border:1px solid var(--line);border-radius:999px;padding:1px 8px}
.live-rooms .vname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.live-note{margin:14px 0 0;font-size:.78rem;color:var(--faint)}
.live-note a{color:var(--red-text)}
.live-none{margin:16px 0 0;padding-top:14px;border-top:1px solid var(--line);
  color:var(--faint);font-size:.86rem}
/* L'état d'erreur : ce qui s'est passé, et de quoi y revenir. */
.live-err{margin:0;color:var(--muted);font-size:.92rem}
.live-err .btn{margin-top:14px}

/* --- La chaîne Twitch ---
   Trois vignettes en ligne, une seule sur mobile. Le violet de Twitch n'entre
   pas dans la page : seul le badge « EN DIRECT » a le droit au rouge NRV, qui
   est justement la couleur des états actifs. */
.tw-bloc{margin-top:clamp(28px,3vw,40px)}
.tw-h{margin:0 0 14px;font-size:1.15rem;text-transform:uppercase;
  letter-spacing:.04em}
.tw-h span{color:var(--red)}
/* Deux vignettes de front : la colonne fait la moitié de la page, trois
   auraient donné des cartes trop petites pour qu'on distingue quoi que ce
   soit. La troisième vidéo passe simplement à la ligne. */
.tw{min-height:200px}
.tw-skel{display:none;grid-template-columns:repeat(2,1fr);gap:16px}
.js .tw-skel{display:grid}
.tw-skel .skel-v{--skel-h:170px;border-radius:var(--r)}
.tw-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
.tw-card{display:block;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden;color:inherit;text-decoration:none;
  transition:transform var(--t),border-color var(--t)}
.tw-card:hover{transform:translateY(var(--lift));border-color:var(--line-strong)}
.tw-vig{position:relative;aspect-ratio:16/9;background:var(--surface-2);display:block}
.tw-vig img{width:100%;height:100%;object-fit:cover;display:block}
.tw-dur{position:absolute;right:8px;bottom:8px;background:rgba(7,8,11,.82);
  border-radius:4px;padding:2px 7px;font-size:.75rem;font-variant-numeric:tabular-nums}
.tw-txt{padding:12px 14px}
.tw-titre{margin:0;font-size:.95rem;line-height:1.35;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.tw-meta{margin:6px 0 0;font-size:.78rem;color:var(--muted)}
/* Le live prend toute la largeur : c'est l'information du moment. */
.tw-direct{grid-column:1/-1;display:grid;grid-template-columns:1.1fr 1fr;
  gap:var(--gap);align-items:center}
.tw-direct .tw-vig{border-radius:var(--r)}
.tw-badge{display:inline-flex;align-items:center;gap:7px;background:var(--red);
  color:#fff;border-radius:999px;padding:3px 11px;font-size:.75rem;font-weight:700;
  text-transform:uppercase;letter-spacing:.1em}
.tw-badge i{width:7px;height:7px;border-radius:50%;background:#fff;display:block}
.tw-direct h3{margin:12px 0 6px;font-size:1.25rem}
.tw-none{color:var(--muted)}
/* Les chaînes amies : un intertitre discret, et le nom SUR la carte — une
   vignette de plus ne dit pas à qui elle appartient. */
.tw-part{margin:22px 0 12px;font-size:.75rem;text-transform:uppercase;
  letter-spacing:.14em;color:var(--faint)}
/* Le décompte par rôle sur une carte de soirée. Les quatre sont toujours là ;
   une case à zéro s'efface sans disparaître — c'est elle qui appelle du monde.
   ⚠️⚠️ **Ne PAS l'appeler `.roles`** : ce nom est déjà pris par la grille des
   rôles de la page recrutement (`repeat(auto-fit,minmax(260px,1fr))`, plus bas
   dans cette même feuille). Les deux façades partagent un seul fichier de
   style : une classe générique réutilisée, et la règle la plus basse gagne.
   Constaté à l'écran par Kevin — quatre barres de 260 px empilées au lieu de
   quatre pastilles — alors que le HTML et le flex étaient justes. */
.ev-roles{display:inline-flex;flex:0 0 auto;flex-wrap:nowrap;gap:7px}
/* Une largeur MINIMALE identique pour les quatre : les pastilles s'alignent
   alors d'une carte à l'autre, et « 12 » ne fait pas sauter la rangée. */
.ev-roles .rl{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  flex:0 0 auto;min-width:62px;white-space:nowrap;font-size:1.02rem;line-height:1.85;
  background:var(--surface-2);border:1px solid var(--line);border-radius:999px;
  padding:0 12px;font-variant-numeric:tabular-nums}
.ev-roles .rl.zero{color:var(--faint);opacity:.6}

.tw-fiche{display:flex;align-items:center;gap:14px;padding:14px}
.tw-ava{width:64px;height:64px;border-radius:50%;flex:none;object-fit:cover;
  border:1px solid var(--line-strong)}
.tw-fiche .tw-txt{padding:0;min-width:0}
.tw-chaine{margin:0 0 4px;font-size:.76rem;font-weight:700;color:var(--red-text);
  text-transform:uppercase;letter-spacing:.06em}
/* Le lecteur ne remplace la vignette qu'au clic (voir `_twitch_section`). */
.tw-player{width:100%;aspect-ratio:16/9;border:0;border-radius:var(--r);display:block}
.tw-play{position:absolute;inset:0;display:grid;place-items:center;
  background:linear-gradient(180deg,rgba(7,8,11,.15),rgba(7,8,11,.6));border:0;
  color:var(--text);cursor:pointer;font-size:2.4rem}
@media(max-width:640px){
  .tw-grid,.tw-skel{grid-template-columns:1fr}
}
/* Sur mobile la carte s'empile : la rangée de rôles passe sous le titre et
   s'étale sur toute la largeur, plutôt que d'être écrasée en bout de ligne. */
@media(max-width:820px){
  .ev{grid-template-columns:1fr}
  .ev-side{justify-self:start;flex-wrap:wrap}
  .ev-roles .rl{min-width:46px}
}
@media(max-width:900px){
  .tw-direct{grid-template-columns:1fr}
}

/* --- Les actions de « Mon profil » ---
   ⚠️ **Une barre de raccourcis, pas un tableau de bord** (Kevin, 2026-07-27 :
   « je ne veux pas que le panel soit énorme, volumineux… plus simpliste,
   pratique, intuitif »). Les formulaires sont partis sur leur propre page ; il
   ne reste ici que la porte d'entrée, en deux lignes de texte. */
.pan{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:12px;margin:0 0 clamp(24px,3vw,36px)}
.pan-tuile{display:block;background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--red);border-radius:var(--r-sm);padding:12px 16px;
  text-decoration:none;color:inherit;
  transition:transform var(--t-fast),background var(--t-fast)}
.pan-tuile:hover{transform:translateY(var(--lift));background:var(--surface-2)}
.pan-t{display:block;font-weight:700;font-size:.98rem}
.pan-s{display:block;margin-top:2px;font-size:.8rem;color:var(--muted)}
/* 🐞 La tuile « Synchro » est un bouton d'envoi enveloppé : l'enveloppe était la
   case de la grille, et le bouton flottait dedans, centré, pendant que les deux
   autres tuiles étaient alignées à gauche (vu à l'écran le 2026-07-28).
   `display:contents` retire l'enveloppe de la mise en page : c'est le bouton
   lui-même qui devient la case, comme les liens voisins.
   ⚠️ Ne pas écrire de balise HTML dans ce commentaire : la feuille de style part
   avec chaque page, et un test vérifie qu'aucun formulaire n'apparaît sur les
   pages publiques — il attrapait le commentaire. */
.pan-form{display:contents}
.pan-tuile{width:100%;text-align:left;font:inherit;cursor:pointer}
/* --- Les catégories repliables de « Mon profil » ---
   Même composant que les fiches de perso : `<details>` natif, donc utilisable
   sans JavaScript et au clavier. Le titre porte le compte quand il y en a un
   (« Mes personnages 3 ») : on sait ce qu'il y a dedans avant d'ouvrir. */
.cat{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  margin-bottom:14px;overflow:hidden}
.cat > summary{display:flex;align-items:center;gap:10px;cursor:pointer;
  padding:14px 18px;list-style:none;background:var(--surface-2);
  transition:background var(--t-fast)}
.cat > summary::-webkit-details-marker{display:none}
.cat > summary:hover{background:var(--surface-3)}
/* Le chevron est écrit en CSS : rien à charger, et il tourne à l'ouverture. */
.cat > summary:after{content:"⌄";margin-left:auto;color:var(--muted);
  font-size:1.1rem;line-height:1;transition:transform var(--t-fast)}
.cat[open] > summary:after{transform:rotate(180deg)}
.cat-t{font-family:var(--font-title);font-weight:700;font-size:1.05rem;
  text-transform:uppercase;letter-spacing:.04em}
.cat-n{background:var(--surface);border:1px solid var(--line);border-radius:999px;
  padding:0 9px;font-size:.78rem;color:var(--muted);font-variant-numeric:tabular-nums}
.cat-in{padding:16px 18px}
.cat-in .pan{margin:0}

/* La semaine à cocher. Trois états qui s'excluent, donc des radios — et la
   couleur n'est PAS seule à parler : le mot est écrit dans chaque bouton. */
.dispos{display:grid;gap:8px}
.dj{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dj-n{width:96px;flex:none;font-size:.9rem;color:var(--muted)}
.dj-o{display:inline-flex;align-items:center;cursor:pointer}
.dj-o input{position:absolute;opacity:0;width:0;height:0}
.dj-o span{display:inline-block;border:1px solid var(--line);background:var(--surface-2);
  border-radius:999px;padding:4px 12px;font-size:.82rem;color:var(--muted);
  transition:background var(--t-fast),color var(--t-fast),border-color var(--t-fast)}
.dj-o + .dj-o{margin-left:6px}
.dj-o input:focus-visible + span{outline:2px solid var(--red-text);outline-offset:2px}
.dj-o.oui input:checked + span{background:rgba(47,163,107,.18);border-color:var(--ok);
  color:#8FE3B8}
.dj-o.peut input:checked + span{background:rgba(217,138,43,.18);border-color:var(--warn);
  color:#F0C089}
.dj-o.non input:checked + span{background:var(--red-soft);border-color:var(--red-line);
  color:var(--red-text)}
.dispos .btn{margin-top:8px;justify-self:start}
@media(max-width:520px){.dj-n{width:100%}}

/* Les actions d'une fiche, sous elle : un geste, à l'endroit où on le pense. */
.char-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  padding:10px 14px 14px}
.prof-form{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:clamp(16px,2vw,24px)}
/* Sur sa propre page, le formulaire ne s'étale pas sur 1240 px : un champ de
   saisie large n'est pas plus facile à remplir, il est plus dur à viser. */
.prof-form.solo{max-width:560px}
.prof-form h3{margin:0 0 14px;font-size:1.05rem}
.prof-h3{margin:20px 0 10px;font-size:.95rem;color:var(--muted)}
.prof-form .f{display:grid;gap:6px;margin-bottom:12px}
.prof-form label{font-size:.8rem;color:var(--muted)}
.prof-form input,.prof-form select{background:var(--surface-2);color:var(--text);
  border:1px solid var(--line);border-radius:var(--r-sm);
  height:var(--field-h);padding:0 12px;
  font:inherit;font-size:.92rem;width:100%}
/* ⚠️ **`:not(:focus-visible)` et non `:focus` tout court.** Ces trois règles
   posaient `outline:none` sur `:focus` : au **clavier** aussi, le contour
   disparaissait, et il ne restait qu'un changement de **couleur** de bordure
   pour dire où l'on se trouve. C'est précisément ce que la règle du site
   interdit — ne jamais faire porter une information par la seule couleur — et
   ça touchait les champs qui **écrivent** (s'inscrire à une soirée, changer de
   spé, rejoindre une clé). Avec `:not(:focus-visible)`, le contour ne saute
   qu'au clic souris ; au clavier, le `:focus-visible` global reprend la main. */
.prof-form input:focus,.prof-form select:focus{border-color:var(--red-line)}
.prof-form input:focus:not(:focus-visible),
.prof-form select:focus:not(:focus-visible){outline:none}
.prof-mains{display:flex;flex-wrap:wrap;gap:8px}
/* ⛔ La règle `.btn.small` qui vivait ici a été SUPPRIMÉE le 2026-07-28, même
   motif que `.btn.tiny` : la taille des boutons se décide dans `design.py`, une
   fois, pour les deux façades. */
/* Changer la spé : le menu et son bouton sur une même ligne, alignés avec les
   autres actions de la fiche. */
.char-spec-form{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.char-spec-form select{background:var(--surface-2);color:var(--text);
  border:1px solid var(--line);border-radius:var(--r-sm);padding:0 10px;
  height:var(--field-h);font:inherit;font-size:.82rem}
.char-spec-form select:focus{border-color:var(--red-line)}
.char-spec-form select:focus:not(:focus-visible){outline:none}
/* ⚠️ Le retrait est REPLIÉ et discret : c'est irréversible, ça ne doit pas se
   cliquer par mégarde ni attirer l'œil autant qu'une action courante. Le rouge
   n'arrive qu'une fois le pli ouvert, sur le bouton qui agit vraiment. */
.char-danger{margin:0 14px 14px;border-top:1px solid var(--line);padding-top:10px}
.char-danger > summary{cursor:pointer;list-style:none;color:var(--faint);
  font-size:.8rem}
.char-danger > summary:hover{color:var(--red-text)}
.char-danger > summary::-webkit-details-marker{display:none}
/* Cette phrase-là dit ce qu'on va perdre en supprimant un personnage : c'est du
   texte courant, pas une mention — 14 px au minimum. */
.char-danger p{color:var(--muted);font-size:.875rem;margin:10px 0}
.btn.danger{background:var(--red);border-color:var(--red);color:#fff}
.btn.danger:hover{background:var(--red-dark);border-color:var(--red-dark)}

/* ================== Mon QG : le tableau de bord du membre ==================
   Refondu le 2026-07-27 au soir sur le retour de Kevin (« le panneau devient
   énorme et pas ergonomique »). La version d'avant empilait sept cadres de même
   poids sur 2 210 px : rien ne se détachait.

   **Trois principes** tiennent toute cette feuille :
   1. **une seule chose en avant** — la prochaine sortie ; le reste se range
      autour, en colonne principale et en rail latéral ;
   2. **des espacements sur une trame de 8 px** (8 · 16 · 24 · 32) : les
      valeurs libres d'avant faisaient vibrer les alignements d'une carte à
      l'autre ;
   3. **le rouge ne décore pas** — appel à l'action, non-lu, manque. Le doré
      reste au classement, la couleur de classe au nom d'un personnage. */
.qg-page{max-width:1320px;margin:0 auto;padding:clamp(24px,3.5vw,40px) 20px}

/* --- A. L'en-tête compact ---
   ⚠️⚠️ **Refonte du 2026-07-28 (maquette E, retenue par Kevin).** Le bandeau
   précédent mesurait **482 px** : identité, cinq chiffres, panel d'actions et
   toute la carte « Ma progression » empilés avant la première information
   utile. Il devient une **barre d'identité de ~120 px** :
   à gauche qui je suis, à droite mes trois chiffres, et **un seul bouton** qui
   ouvre le menu des actions. Le reste redescend dans les cartes, où chaque
   information a désormais un endroit et un seul.

   La lueur rouge et le loup en filigrane sont **partis avec le bandeau** :
   c'étaient des effets de héros, et cette barre n'en est plus un. */
.qg-tete{display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:14px clamp(14px,2vw,20px);margin-bottom:16px}
.qg-tete-id{display:flex;align-items:center;gap:14px;min-width:0}
.qg-ava{width:56px;height:56px;flex:none;border-radius:50%;
  border:2px solid var(--red-line);object-fit:cover;background:var(--surface-2)}
.qg-ava-txt{display:grid;place-items:center;font-family:var(--font-title);
  font-size:1.25rem;font-weight:700;color:var(--muted)}
.qg-nom{margin:0;font-family:var(--font-title);font-size:clamp(1.2rem,2.4vw,1.5rem);
  line-height:1.1;font-weight:700;text-transform:uppercase;
  letter-spacing:var(--track-title)}
/* Le personnage principal sous le pseudo : classe, spé et royaume tiennent en
   une ligne grise, là où le bandeau leur donnait un paragraphe à part. */
.qg-tete-sous{margin:3px 0 0;color:var(--muted);font-size:.85rem}
.qg-badges{display:flex;flex-wrap:wrap;gap:6px;margin:7px 0 0}
/* Les trois chiffres : ce sont les valeurs **actuelles**, et elles ne sont
   répétées nulle part ailleurs — « Ma progression » ne montre que ce que ces
   chiffres ne peuvent pas dire (l'évolution, le rang, la meilleure clé). */
.qg-tete-chiffres{margin-left:auto;display:flex;align-items:stretch}
.qg-tete-chiffres > div{padding:0 clamp(12px,1.6vw,22px);text-align:center;
  border-left:1px solid var(--line)}
.qg-tete-chiffres > div:first-child{border-left:0}
.qg-tete-chiffres b{display:block;font-family:var(--font-title);
  font-size:clamp(1.25rem,2.2vw,1.6rem);line-height:1.1;
  font-variant-numeric:tabular-nums}
/* 0,75 rem = 12 px pile : le plancher du site, verrouillé par `test_lisibilite`. */
.qg-tete-chiffres span{display:block;font-size:.75rem;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;margin-top:2px}
/* --- Le menu « Action rapide » ---
   ⚠️ **Un `<details>`, donc aucun JavaScript** : il s'ouvre au clic et au
   clavier, se ferme à Échap, et fonctionne script bloqué. Un menu maison aurait
   demandé du JS, des `aria-expanded` à tenir et une gestion du clic extérieur.
   ⚠️ Il remplace le panel de cinq pastilles : Kevin a fait retirer
   « Mes disponibilités », « Événements à venir » et « Ajouter un personnage »
   parce que les trois sont déjà dans leur carte. Repliés dans un menu, ils ne
   coûtent plus une ligne de page — et l'action principale garde le rouge. */
.qg-menu{position:relative;flex:none}
.qg-menu > summary{list-style:none;cursor:pointer}
.qg-menu > summary::-webkit-details-marker{display:none}
.qg-menu ul{position:absolute;right:0;top:calc(var(--btn-h) + 6px);z-index:30;
  list-style:none;margin:0;padding:6px;min-width:240px;
  background:var(--surface-2);border:1px solid var(--line-strong);
  border-radius:var(--r-sm);box-shadow:var(--shadow);display:grid;gap:2px}
.qg-menu li a{display:flex;align-items:center;gap:10px;
  min-height:var(--btn-h-sm);padding:0 10px;border-radius:6px;font-size:.9rem}
.qg-menu li a:hover{background:var(--surface-3)}
@media(max-width:620px){
  /* Sur un téléphone la barre s'empile : le menu prend alors la largeur, et
     s'ouvre **dans le flux** plutôt qu'en surimpression au-dessus du contenu. */
  .qg-tete{gap:14px}
  .qg-tete-chiffres{margin-left:0;width:100%}
  .qg-tete-chiffres > div{flex:1}
  .qg-menu{width:100%}
  .qg-menu > summary{width:100%}
  .qg-menu ul{position:static;width:100%;margin-top:8px}
}
/* ⚠️ `min-height:36px` : mesuré à **15 px** le 2026-07-28 dans la nouvelle
   carte de progression. C'est un lien de service isolé au bas d'une carte, donc
   une vraie cible tactile — la hauteur vient d'un remplissage, le texte ne
   bouge pas. Même correctif que les « Tout voir » (`.qg-plus`). */
.qg-prog-lien{margin:12px 0 0;font-size:.8rem}
.qg-prog-lien a{display:inline-flex;align-items:center;min-height:36px;
  color:var(--muted);text-decoration:underline}
.qg-prog-lien a:hover{color:var(--red-text)}
/* Un badge de grade : l'icône que Kevin a posée sur le rôle Discord, **et** le
   mot. L'icône seule ne dirait rien à un lecteur d'écran ni à un nouveau venu —
   même règle que la classe, écrite sous le nom d'un personnage. */
.qg-badge{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;
  border-radius:999px;background:var(--surface-2);
  border:1px solid var(--line);font-size:.78rem;font-weight:600;
  letter-spacing:.04em;color:var(--muted)}
.qg-badge-ic{width:20px;height:20px;display:block;object-fit:contain}
/* Les mêmes badges sur la fiche publique d'un membre (armurerie). */
.grades{display:flex;flex-wrap:wrap;gap:8px;margin:-8px 0 24px}
/* Le staff est le seul grade qui change ce qu'on peut FAIRE sur le site : il
   est le seul à porter le rouge. Les autres se distinguent sans crier. */
.qg-badge.staff{border-color:var(--red-line);color:var(--red-text)}
.qg-badge.membre{color:var(--text)}
.qg-badge.principal{border-color:var(--gold);color:var(--gold)}
/* ⛔ **SUPPRIMÉ le 2026-07-28 avec le bandeau** : les règles `.qg-hero-actions`,
   `.qg-main*` et `.qg-stats*`. Elles décrivaient la ligne d'actions, le
   paragraphe « Personnage principal : » et la rangée de chiffres du héros —
   trois blocs que l'en-tête compact absorbe désormais dans sa seule barre.
   Aucune n'a de HTML qui la produise encore. */

/* --- La barre d'état ---
   ⚠️⚠️ **Elle n'apparaît que si elle a quelque chose à signaler.** Une barre qui
   dit toujours « tout va bien » devient un décor qu'on cesse de lire au bout de
   trois visites, et elle aura alors coûté 34 px à chaque page. Quand rien ne
   cloche, elle n'existe pas. */
.qg-etats{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.qg-etats span{display:inline-flex;align-items:center;gap:7px;min-height:32px;
  padding:0 12px;border-radius:999px;font-size:.82rem;
  background:var(--surface);border:1px solid var(--line);color:var(--muted)}
/* ⚠️ L'icône ne porte jamais l'information seule : le mot est écrit à côté.
   La couleur ne fait que **renforcer** ce que la phrase dit déjà. */
.qg-etats .att{color:var(--warn);border-color:rgba(217,138,43,.35)}

/* --- Mes priorités ---
   ⚠️ **Trois niveaux, et ils se voient.** Quatre lignes de même poids ne sont
   pas des priorités, c'est une liste. Le liseré gauche porte le rang : rouge
   pour ce qui bloque, orange pour la semaine, gris pour le facultatif. Le mot
   (« Urgent », « Cette semaine », « Optionnel ») est écrit à droite — la
   couleur seule ne dirait rien à un daltonien. */
.qg-prio{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.qg-prio a{display:flex;align-items:center;gap:12px;padding:9px 12px;
  border-radius:var(--r-sm);background:var(--surface-2);color:inherit;
  border:1px solid var(--line);border-left:3px solid var(--line-strong);
  transition:background var(--t-fast),border-color var(--t-fast)}
.qg-prio a:hover{background:var(--surface-3);border-color:var(--line-strong)}
.qg-prio .n1 a{border-left-color:var(--red);background:var(--red-soft)}
.qg-prio .n2 a{border-left-color:var(--warn)}
.qg-prio .n3 a{border-left-color:var(--line-strong)}
.qg-prio-ic{font-size:1.05rem;line-height:1;flex:none}
.qg-prio b{display:block;font-size:.9rem}
.qg-prio em{display:block;font-style:normal;color:var(--muted);font-size:.8rem}
.qg-prio-q{margin-left:auto;font-size:.75rem;text-transform:uppercase;
  letter-spacing:.05em;color:var(--muted);white-space:nowrap}
.qg-prio .n1 .qg-prio-q{color:var(--red-text)}
.qg-prio .n2 .qg-prio-q{color:var(--warn)}

/* --- Ma progression, en carte ---
   ⚠️ Elle **ne répète pas** les trois chiffres de l'en-tête : elle dit ce qu'ils
   ne peuvent pas dire — l'évolution, la meilleure clé, le rang, la synchro. */
.qg-prog-lignes{display:grid;margin-top:14px}
.qg-prog-ligne{display:flex;align-items:baseline;gap:12px;margin:0;
  padding:8px 0;border-top:1px solid var(--line);font-size:.86rem}
.qg-prog-ligne > span{color:var(--muted)}
.qg-prog-ligne > b{margin-left:auto;font-variant-numeric:tabular-nums;
  text-align:right}

/* --- Trois personnages en cartes ---
   ⚠️ Trois au plus dans l'aperçu, la liste complète est l'onglet : à sept
   personnages, le résumé devenait la moitié de la page. */
.qg-pcards{display:grid;gap:12px;
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.qg-pcard{display:grid;gap:8px;padding:12px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid var(--line);color:inherit;
  transition:border-color var(--t-fast),background var(--t-fast)}
.qg-pcard:hover{border-color:var(--red-line);background:var(--surface-3)}
.qg-pcard-t{display:flex;align-items:center;gap:9px;min-width:0}
.qg-pcard-t b{font-size:.98rem;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.qg-pcard-s{color:var(--muted);font-size:.8rem;margin:0}
.qg-pcard-n{display:flex;gap:18px;font-variant-numeric:tabular-nums}
.qg-pcard-n b{display:block;font-size:1.05rem}
.qg-pcard-n span span{color:var(--muted);font-size:.75rem}

/* --- Le fil d'activité, groupé par jour ---
   ⚠️ **Un fil vertical, pas un carrousel** : cinq cartes qui défilent
   horizontalement cachent quatre lignes sur cinq et ne se lisent pas au
   clavier. */
.qg-fil{margin:0;padding:0}
.qg-fil dt{font-size:.75rem;text-transform:uppercase;letter-spacing:.07em;
  color:var(--muted);font-weight:700;margin:14px 0 6px}
.qg-fil dt:first-child{margin-top:0}
.qg-fil dd{margin:0 0 4px;display:flex;align-items:center;gap:10px;
  padding:8px 10px;border-radius:6px;background:var(--surface-2);
  font-size:.88rem}
.qg-fil dd .qg-fil-h{margin-left:auto;color:var(--faint);font-size:.8rem;
  font-variant-numeric:tabular-nums;white-space:nowrap}

/* --- La sous-navigation --- */
/* ⚠️ **Des ancres, pas des onglets.** Kevin a déjà refusé le masquage sur la
   fiche de perso (« je préférais l'affichage juste avant »), et un test
   verrouille ce refus. Ici on fait défiler : rien n'est caché.
   `scroll-margin-top` sur les sections, sinon la barre collante du site
   recouvre le titre où l'on vient d'atterrir. */
/* ⚠️ `scroll-margin-top` : sans lui, `scrollIntoView` amène la barre d'onglets
   **sous** la barre collante du site, qui lui mange 76 px. */
.qg-nav{position:sticky;top:var(--nav-h);scroll-margin-top:var(--nav-h);
  z-index:20;margin:0 -20px 16px;
  padding:0 20px;background:rgba(7,8,11,.92);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line)}
.qg-nav ul{list-style:none;display:flex;gap:24px;margin:0;padding:0;
  overflow-x:auto;scrollbar-width:none}
.qg-nav ul::-webkit-scrollbar{display:none}
.qg-nav a{display:block;padding:12px 0;font-size:.88rem;font-weight:600;
  color:var(--muted);white-space:nowrap;border-bottom:2px solid transparent;
  transition:color var(--t-fast),border-color var(--t-fast)}
.qg-nav a:hover{color:var(--text);border-bottom-color:var(--red)}

/* --- Les onglets ---
   ⚠️ **Le CSS ne cache RIEN** : c'est le script qui pose `hidden` sur les
   panneaux. Sans JavaScript, les cinq s'affichent à la suite et les liens
   redeviennent des ancres — aucun contenu ne devient inatteignable. */
.qg-nav a[aria-selected="true"]{color:var(--text);border-bottom-color:var(--red)}
.qg-panneau[hidden]{display:none}
.qg-panneau + .qg-panneau{margin-top:24px}

/* --- B. Actions rapides ---
   ⚠️ **Trois niveaux, un seul rouge.** Cinq tuiles identiques ne hiérarchisent
   rien : l'action principale prend toute la largeur, les deux courantes se
   partagent la ligne suivante, les deux secondaires sont plus petites et sans
   description — on ne les cherche qu'une fois par mois. */
/* ⛔ **Les règles de grille des anciennes tuiles ont été SUPPRIMÉES** le
   2026-07-28 (3ᵉ passe). Elles décrivaient `.qg-act`, `.qg-act-courantes` et
   `.qg-act-secondaires`, classes que le HTML ne produit plus depuis que les
   raccourcis sont des pastilles.
   🐞 **Et elles n'étaient pas inoffensives** : l'ancienne grille de trois
   colonnes posée sur le conteneur survivait à la refonte et rangeait le titre
   et la liste dans deux de ses cellules — les cinq pastilles tombaient alors
   **une par ligne** (mesuré : 240 px de haut,
   soit plus que les tuiles qu'elles remplaçaient). Le style vit plus bas,
   section « panel d'actions rapides ». */

/* --- Les outils de l'onglet Personnages (recherche, filtres, tri) --- */
.persos-outils{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
.persos-outils input,.persos-outils select{height:var(--field-h);padding:0 12px;
  background:var(--surface-2);color:var(--text);border:1px solid var(--line);
  border-radius:var(--r-sm);font:inherit;font-size:.9rem}
.persos-outils input{flex:1;min-width:200px}
.persos-outils input:focus-visible,.persos-outils select:focus-visible{
  outline:2px solid var(--red-line);outline-offset:1px}
.liste-persos .char-fold[hidden]{display:none}

/* --- Le résumé des personnages (vue d'ensemble) --- */
.resume-persos{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.resume-persos li{display:block}
/* La ligne ENTIÈRE est le lien vers la fiche du personnage (Kevin, 2026-07-28).
   ⚠️ `color:inherit` : sans lui, le nom coloré par classe passerait au rouge des
   liens et on perdrait le repère visuel le plus utile de la ligne. */
.rp-ligne{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:10px 12px;border-radius:var(--r-sm);background:var(--surface-2);
  color:inherit;text-decoration:none;border:1px solid transparent;
  transition:background var(--t-fast),border-color var(--t-fast)}
.rp-ligne:hover{background:var(--surface);border-color:var(--red-line)}
.rp-ligne:hover .rp-fleche{transform:translateX(3px)}
.rp-nom{display:inline-flex;align-items:center;gap:8px}
.rp-meta{color:var(--muted);font-size:.82rem}
.rp-chiffres{margin-left:auto;font-size:.85rem;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.rp-chiffres b{color:var(--text)}
/* Le chevron : il dit que la ligne mène quelque part. ⚠️ Il ne porte pas
   l'information à lui seul — le survol, le focus et le curseur le disent aussi. */
.rp-fleche{width:7px;height:7px;flex:none;border-right:2px solid var(--muted);
  border-bottom:2px solid var(--muted);transform:rotate(-45deg);
  transition:transform var(--t-fast)}
@media(max-width:560px){.rp-chiffres{margin-left:0;width:100%}}
/* ⛔⛔ **LE PANEL DE PASTILLES A ÉTÉ SUPPRIMÉ le 2026-07-28** (maquette E).
   Ses règles `.qg-actions`, `.qg-actions-t`, `.qg-actions-liste`, `.qg-chip` et
   `.qg-chip.primaire` ne décrivaient plus aucun HTML : les cinq raccourcis sont
   devenus le menu « Action rapide » de l'en-tête (`.qg-menu`).
   Kevin l'avait d'ailleurs demandé avant la refonte : « enlève Mes dispos,
   Ajouter un perso et Événements à venir » — les trois sont déjà dans leur
   carte. Repliés dans un menu, ils ne coûtent plus une ligne de page.
   ⚠️ C'est cette pastille qui a servi de **repère de taille** pour tout le
   site : sa hauteur vit maintenant dans `--btn-h` (`design.py`), elle ne s'est
   pas perdue avec la classe. */
/* --- C. La grille : DOUZE colonnes ---
   ⚠️⚠️ **Remplace la grille 65/35 le 2026-07-28** (maquette E). L'ancienne était
   une colonne principale et un rail : deux largeurs possibles, donc deux
   familles de cartes, et tout ce qui ne rentrait dans aucune des deux tombait
   en pleine largeur sous la grille. Les douze colonnes donnent quatre rangées
   qui respectent l'ordre de lecture demandé :
   progression 7 / priorités 5 · activité 7 / semaine 5 · personnages 12 ·
   clé 4 / activité récente 8.

   ⚠️ **Deux paliers, pas cinq.** Sous 1100 px toute carte prend la moitié
   (span 6), sous 760 px toute la largeur : une carte de 5/12 sur une tablette
   fait 300 px, où la semaine de dispos et les cartes de personnage se cassent.
   Vérifié à 1440, 1280, 1024, 768 et 390. */
.qg-grille{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));
  gap:24px;align-items:start;margin-bottom:24px}
.qg-grille > *{margin:0;min-width:0}
.c4{grid-column:span 4}
.c5{grid-column:span 5}
.c7{grid-column:span 7}
.c8{grid-column:span 8}
.c12{grid-column:span 12}
@media(max-width:1100px){.c4,.c5,.c7,.c8{grid-column:span 6}}
@media(max-width:760px){.c4,.c5,.c7,.c8{grid-column:span 12}}

/* --- Le cadre commun d'une section --- */
.qg-sec{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:16px clamp(16px,2vw,24px) 24px;
  scroll-margin-top:calc(var(--nav-h) + 56px)}
.qg-sec-tete{display:flex;align-items:baseline;gap:16px;margin-bottom:16px}
.qg-sec-tete h2{margin:0;font-size:1.05rem;letter-spacing:.02em}
/* ⚠️ `min-height:36px` : mesurés à **20 px** dans le navigateur (2026-07-28),
   très en dessous de la barre du site. Ce sont de petits liens de service
   (« Tout voir »), mais sur un téléphone une cible de 20 px se rate. La hauteur
   vient d'un remplissage vertical, donc **rien ne bouge visuellement** : le
   texte garde sa taille et sa place, la zone cliquable seule grandit. */
.qg-plus{margin-left:auto;font-size:.8rem;color:var(--muted);font-weight:400;
  display:inline-flex;align-items:center;min-height:36px}
a.qg-plus:hover{color:var(--red-text)}
/* La section « prochaine activité » est la seule à porter un liseré rouge :
   c'est elle qu'on vient lire. */
.qg-sec-fort{border-left:3px solid var(--red)}
/* Les grandes sections hors grille s'espacent comme la grille elle-même. */
#persos,#dispos,#activite,#compte{margin-bottom:24px}

/* --- Ma prochaine activité --- */
.qg-next-head h3{margin:4px 0 0;font-size:clamp(1.15rem,2vw,1.5rem);line-height:1.2}
.qg-next-meta{display:flex;flex-wrap:wrap;gap:16px;margin-top:8px;
  font-size:.85rem;color:var(--muted)}
.qg-quand{color:var(--text);font-weight:600}
.qg-roles{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.qg-role{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;
  border-radius:999px;background:var(--surface-2);border:1px solid var(--line);
  font-size:.85rem;font-variant-numeric:tabular-nums}
/* Un rôle à zéro est précisément ce qui fait venir quelqu'un : on le signale
   au lieu de le noyer avec les autres. */
.qg-role.vide{color:var(--red-text);border-color:var(--red-line)}
.qg-next-pied{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  margin-top:24px;padding-top:16px;border-top:1px solid var(--line)}
.qg-etat{font-size:.85rem;color:var(--muted)}
.qg-etat.ok{color:var(--ok)}
.qg-etat.peut{color:var(--gold)}
.qg-etat.non{color:var(--faint)}
.qg-mine{font-size:.85rem;color:var(--muted)}
.qg-next-pied .cta-row{margin-left:auto;margin-top:0}

/* --- Mes sorties à venir --- */
.qg-minis{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:8px}
.qg-mini{display:grid;gap:4px;padding:12px 16px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid transparent;
  transition:border-color var(--t-fast),transform var(--t-fast)}
.qg-mini:hover{border-color:var(--red-line);transform:translateY(var(--lift))}
.qg-mini .qg-quand{font-size:.75rem;color:var(--muted);font-weight:400}
.qg-mini .qg-roles{margin-top:8px}
.qg-mini .qg-role{padding:2px 8px;font-size:.78rem}

/* --- Clés M+ --- */
.qg-cles{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.qg-cles a{display:flex;align-items:center;gap:16px;padding:12px;
  border-radius:var(--r-sm);background:var(--surface-2);
  border:1px solid transparent;transition:border-color var(--t-fast)}
.qg-cles a:hover{border-color:var(--red-line)}
/* Le niveau en gros : c'est la première chose qu'on cherche sur une clé. */
.qg-lvl{flex:none;min-width:56px;padding:8px;text-align:center;
  border-radius:var(--r-sm);background:var(--red-soft);
  border:1px solid var(--red-line);font-family:var(--font-title);
  font-weight:700;font-size:1.1rem;color:#fff}
.qg-cle-corps{display:grid;gap:2px;min-width:0}
.qg-cle-corps strong{font-size:.95rem}
.qg-cle-meta{font-size:.78rem;color:var(--muted)}
.qg-cle-meta .manque{color:var(--red-text)}

/* --- Ma progression --- */
.qg-chiffres{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;text-align:center}
.qg-chiffres b{display:block;font-family:var(--font-title);font-size:1.6rem;line-height:1.1}
.qg-chiffres span{font-size:.78rem;color:var(--muted);letter-spacing:.04em}
.qg-prog-perso{margin:16px 0 0;text-align:center}
.qg-prog-plus{margin:16px 0 0;display:grid;gap:8px;font-size:.85rem}
.qg-prog-plus > div{display:flex;gap:16px;padding-top:8px;
  border-top:1px solid var(--line)}
.qg-prog-plus dt{color:var(--muted)}
.qg-prog-plus dd{margin:0 0 0 auto;font-weight:600;text-align:right}
/* --- La tendance : est-ce que ça monte ? ---
   ⚠️ La couleur ne porte JAMAIS l'information seule : la phrase dit « +120 en
   7 jours » et la flèche double le signe. Le vert et le rouge ne font que
   souligner — ils ne disent rien à un daltonien ni à un lecteur d'écran. */
.tendance{display:inline-flex;align-items:center;gap:4px;font-size:.75rem;
  font-weight:600;color:var(--muted);white-space:nowrap}
/* ⚠️ En `rem`, pas en `em` : dans un bloc déjà réduit (`.qg-chiffres`, un pied
   de fiche), une flèche en `em` retombait à 10 px. Un `rem` la tient au même
   plancher partout, quel que soit son voisinage. */
.tendance i{font-style:normal;font-size:.75rem;line-height:1}
.tendance.monte{color:var(--ok)}
.tendance.baisse{color:var(--red-text)}
.tendance.plat{color:var(--faint)}
.qg-chiffres .tendance{margin-top:4px}
/* --- La barre de progression de raid ---
   « 6/8 » se lit, une barre aux trois quarts pleine se **voit**. ⚠️ Le chiffre
   et la difficulté restent écrits dessous : une barre seule ne dit ni combien
   de boss ni à quelle difficulté, et ne dit rien du tout à un lecteur d'écran
   (d'où le `role="img"` et son libellé complet côté HTML). */
.barre-raid{position:relative;height:8px;margin-top:16px;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--line);overflow:hidden}
.barre-raid > span{display:block;height:100%;
  background:linear-gradient(90deg,var(--red-dark),var(--red))}
.barre-legende{margin:8px 0 0;font-size:.78rem;color:var(--muted);text-align:center}
.barre-legende b{color:var(--text)}
/* --- La fiche en deux colonnes : les tableaux, puis l'évolution ---
   Les clés et le raid n'ont pas besoin de 1200 px ; l'évolution, elle, se lit
   mieux dans une colonne étroite à côté que sous un tableau qu'on vient de
   parcourir. Sous 900 px, tout s'empile dans l'ordre de lecture. */
/* 380 px (et non 300) : la courbe doit occuper la place disponible, pas s'y
   serrer (Kevin, 2026-07-27 : « agrandis un peu les graphiques, qu'ils prennent
   la largeur de la fiche perso »). Les tableaux gardent largement leur compte —
   mesuré à 1440 : 783 px pour les clés, ce qui reste sans coupure. */
.char-corps{display:grid;grid-template-columns:minmax(0,1fr) 380px;
  gap:clamp(16px,2vw,32px);align-items:start}
.char-tables{min-width:0}
.char-cote{position:sticky;top:calc(var(--nav-h) + 16px);display:grid;gap:16px;
  padding:16px;border-radius:var(--r-sm);background:var(--surface-2);
  border:1px solid var(--line)}
.char-cote .barre-raid{margin-top:0}
.char-cote .courbe-cadre{margin:0;padding:0;border:0}
/* Plus haute ici qu'en pied de bloc : c'est la seule chose que cette colonne a
   à montrer, autant qu'elle se lise. Une sparkline écrasée à 24 px transforme
   +250 points en un frémissement. */
.char-cote .courbe{height:132px}
.char-cote .courbe-echelle{display:flex;justify-content:space-between;
  margin-top:4px;font-size:.78rem;color:var(--faint);
  font-variant-numeric:tabular-nums}
/* Dans le rail du QG, la même courbe reste plus basse : la colonne y porte
   aussi les chiffres et le rang, elle ne peut pas s'offrir 132 px. */
.courbe-echelle{display:flex;justify-content:space-between;margin-top:4px;
  font-size:.78rem;color:var(--faint);font-variant-numeric:tabular-nums}
@media(max-width:900px){
  .char-corps{grid-template-columns:1fr}
  .char-cote{position:static}
}
/* La courbe : un SVG écrit à la main, 12 points au plus. Elle **répète** le
   chiffre — d'où `aria-hidden` côté HTML, et une couleur discrète ici. */
.courbe{display:block;color:var(--red-text);opacity:.85;width:100%;height:24px}
.courbe-cadre{margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
/* ⚠️ Une légende doit se lire APRÈS la courbe, pas avant elle. Mesurée à
   **17,4 px en blanc plein** (2026-07-28) : elle passait pour un titre. Elle
   était noyée dans une phrase longue tant qu'elle disait « Score M+ · 12
   derniers relevés · ▲ +256 » ; réduite à sa part utile, elle criait. */
.courbe-cadre figcaption{font-size:.8rem;color:var(--muted);margin-bottom:6px}
.qg-perso-tend{margin:8px 0 0;text-align:center}
/* Sur la fiche publique d'un membre, sous les badges de grade. */
.tendances{display:flex;align-items:center;gap:16px;margin:-8px 0 24px;max-width:320px}

/* Ma ligne dans le classement : reconnaissable sans être criarde, et repérable
   autrement que par la couleur (le liseré à gauche). */
.hof-liste li.moi{background:var(--surface-2);border-left:2px solid var(--red);
  margin-left:-8px;padding-left:6px;border-radius:2px}

/* --- D. Mes personnages ---
   ⚠️⚠️ **Une liste pleine largeur, pas des cartes en colonnes.** Les cartes de
   300 px ont été essayées puis retirées le 2026-07-27 : le tableau des clés M+
   se coupait au milieu du niveau (« +1… » pour « +18 »), la progression de raid
   défilait de côté, et trois cartes de hauteurs différentes laissaient de grands
   vides. Une fiche de personnage a besoin de toute la largeur.
   Le composant est celui de l'armurerie (`.char-fold`), déjà validé : le nom en
   couleur de classe, la fiche entière au clic. */
#persos .char-fold{background:var(--surface-2)}
#persos .char-fold:first-of-type{border-color:var(--red-line)}
/* Le bandeau entre le résumé et la fiche : quand la donnée a été relue, si ça
   monte, et où aller voir. */
.qg-perso-pied{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;
  margin:0;padding:12px 18px;border-bottom:1px solid var(--line);
  font-size:.78rem;color:var(--faint)}
.qg-synchro{color:var(--muted)}
/* « Jamais synchronisé » explique un score absent : c'est une information, pas
   une erreur — d'où le doré (attention) et non le rouge (problème). */
.qg-synchro.alerte{color:var(--gold)}
.qg-perso-liens{margin-left:auto;display:flex;align-items:center;gap:16px}
/* Idem, et c'est ici que ça compte le plus : ces deux liens se répètent sur
   CHAQUE personnage (14 cibles de 20 px collées les unes aux autres sur une
   fiche à sept persos). `align-items:center` sur le conteneur garde
   l'alignement de la barre inchangé. */
.qg-perso-liens a{color:var(--muted);text-decoration:underline;
  display:inline-flex;align-items:center;min-height:36px}
.qg-perso-liens a:hover{color:var(--red-text)}
/* --- Le main, dans la barre --- */
/* Kevin, 2026-07-27 : « plus pratique d'un coup d'œil de faire un changement de
   main ou de reroll ». Avant, il fallait déplier chaque reroll pour trouver le
   bouton.
   🐞 **Les boutons ne s'alignaient pas** (signalé le 2026-07-27) : le chevron du
   dépliant porte DÉJÀ `margin-left:auto`, et deux marges automatiques dans un
   même flex **se partagent** l'espace libre — chaque bouton se posait donc juste
   après un texte de longueur variable, en escalier. La marge automatique doit
   rester sur **un seul** élément ; le chevron reprend un écart fixe.
   ⚠️ Une largeur minimale identique pour les deux : sans elle, la pastille
   « ★ Principal » et le bouton « Définir principal » caleraient leur bord droit
   au même endroit mais donneraient deux colonnes de largeurs différentes. */
#persos .char-fold > summary .qg-badge,
#persos .char-fold > summary .fold-main{margin-left:auto;flex:none;
  min-width:150px;justify-content:center}
#persos .char-fold > summary:after{margin-left:16px}
#persos .char-fold > summary .fold-main .btn{width:100%}
#persos .char-fold > summary .qg-badge{font-size:.78rem;color:var(--gold);
  border-color:var(--gold)}
/* La méta prend la place qui reste : c'est elle qui doit céder quand le nom est
   long, pas la colonne de droite. */
#persos .char-fold > summary .fold-meta{flex:1;min-width:0}
.fold-main{display:flex}
/* ⛔ La règle `.btn.tiny` qui vivait ici a été SUPPRIMÉE le 2026-07-28 : elle
   redéfinissait une hauteur et une taille de texte que le socle porte désormais
   pour toute la famille (voir `design.py`). Deux endroits qui décident de la
   taille d'un bouton, c'est celui d'en bas qui gagne — et personne ne sait
   lequel c'est. */

/* --- E. Mes disponibilités --- */
/* Lisible d'abord, modifiable ensuite : avant, la semaine était enfermée dans
   un accordéon fermé — il fallait l'ouvrir pour savoir ce qu'on avait déclaré. */
/* 🐞 **`minmax(0,1fr)` et non `1fr`** (2026-07-28). Un `1fr` garde un plancher
   implicite à `min-content` : la case la plus large — « Pas dispo » — imposait
   sa largeur aux sept, et la semaine réclamait **416 px dans une colonne de
   361**. Mesuré en essayant la carte des dispos dans une colonne de tiers de
   page : elle débordait. Avec `minmax(0,1fr)` les cases acceptent de rétrécir et
   le mot passe à la ligne. Vaut aussi pour le téléphone. */
.qg-semaine{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(7,minmax(0,1fr));gap:8px}
.qg-semaine li{display:grid;gap:4px;padding:8px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid var(--line);
  border-top:2px solid var(--line);text-align:center;font-size:.75rem}
.qg-jour{font-weight:700;font-size:.8rem}
/* L'horaire sous les jours où l'on vient (2ᵉ passe : « le créneau horaire »).
   Gris : c'est une précision, pas l'état — l'état est le mot au-dessus. */
.qg-heures{display:block;margin-top:2px;font-size:.75rem;color:var(--faint);
  font-variant-numeric:tabular-nums}
/* --- Le créneau habituel, en tête du formulaire --- */
.dispo-creneau{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin:0 0 16px;padding:12px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid var(--line)}
.dispo-creneau-t{font-weight:600;font-size:.88rem;margin-right:8px}
.dispo-creneau input[type=time]{height:var(--field-h);padding:0 10px;background:var(--surface);
  color:var(--text);border:1px solid var(--line);border-radius:var(--r-sm);
  font:inherit;font-size:.9rem}
.dispo-creneau input[type=time]:focus-visible{outline:2px solid var(--red-line);
  outline-offset:1px}
.dispo-creneau .btn{margin-left:auto}
/* Trois états, trois couleurs — **et le mot est écrit dans la case** : la
   couleur seule ne dit rien à un daltonien. */
.qg-semaine li.oui{border-top-color:var(--ok);color:var(--ok)}
.qg-semaine li.peut{border-top-color:var(--gold);color:var(--gold)}
.qg-semaine li.non{border-top-color:var(--red);color:var(--red-text)}
.qg-semaine li.vide{color:var(--faint)}
.qg-dispo-libre{margin:0;color:var(--muted)}
.qg-suite{margin-top:16px}
.qg-suite > summary{cursor:pointer;font-weight:600;font-size:.88rem;
  color:var(--red-text);list-style:none}
.qg-suite > summary::-webkit-details-marker{display:none}
.qg-suite > summary:hover{color:#fff}
.qg-suite[open] > summary{margin-bottom:16px}

/* --- F. Activité récente --- */
.qg-filtres{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:8px}
.notifs{list-style:none;margin:0;padding:0;display:grid}
.notifs li{border-top:1px solid var(--line)}
.notifs li:first-child{border-top:0}
.notifs a,.notifs .no-lien{display:grid;grid-template-columns:auto 1fr auto;
  align-items:baseline;gap:16px;padding:12px 8px;
  transition:background var(--t-fast)}
.notifs a:hover{background:var(--surface-2)}
.notifs .nt-icone{font-size:1rem;line-height:1.3}
.notifs .nt-corps{min-width:0}
.notifs .nt-titre{font-size:.9rem;color:var(--text)}
.notifs .nt-detail{display:block;margin-top:2px;font-size:.78rem;color:var(--muted)}
.notifs .nt-quand{font-size:.75rem;color:var(--faint);white-space:nowrap}
/* ⚠️ Le non-lu se dit **trois fois** : un liseré, un fond à peine plus clair, et
   le mot « Non lu » pour les lecteurs d'écran. Kevin : plus de ligne entièrement
   rouge — le rouge ici ne fait que pointer. */
.notifs li.neuf{border-left:2px solid var(--red);background:rgba(210,10,46,.05)}
.notifs li.neuf .nt-titre{color:#fff;font-weight:600}

/* --- G. Mon compte --- */
/* Les deux sujets du panneau « Compte », côte à côte (Kevin, 2026-07-28 :
   « trop d'espace perdu »). `align-items:start` : chaque bloc se règle sur SON
   contenu — étirés, celui de gauche traînait du vide sous son bouton. */
.compte-duo{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:clamp(20px,3vw,36px);align-items:start;margin-top:8px}
.compte-duo > section{min-width:0}
.compte-duo h3{margin:0 0 10px;font-size:1.02rem}
.compte-duo p{margin:0 0 14px;max-width:60ch}
.qg-compte-note{margin:0 0 14px;font-size:.85rem;color:var(--muted);max-width:60ch}
.qg-compte-note b{color:var(--text)}
.qg-sec .pan{margin:0}

/* --- États vides : ils disent quoi faire ensuite, jamais juste « rien » ---
   ⚠️ **Et ils ne gardent pas la hauteur d'une section pleine** (2ᵉ passe) : une
   ligne suffit à dire qu'il n'y a rien, et le lien dit quoi faire. */
.vide-ligne{margin:0;padding:4px 0;color:var(--muted);font-size:.88rem}
.vide-ligne a{color:var(--red-text);text-decoration:underline}
.qg-vide{padding:8px 0}
.qg-vide p{margin:0 0 8px;color:var(--muted)}
.qg-vide p b{color:var(--text)}

/* --- Responsive ---
   ⛔ Les règles `.qg-stats`, `.qg-hero-actions` et `.qg-hero` de ces deux
   paliers ont disparu avec le bandeau (2026-07-28) : elles rangeaient une
   rangée de chiffres et une ligne de boutons que l'en-tête compact n'a plus.
   ⚠️ **Une règle responsive qui en contredit une autre l'emporte par sa place
   dans le fichier, pas par son intention** — leçon payée sur les anciennes
   tuiles d'actions, à garder en tête en ajoutant ici. */
@media(max-width:768px){
  .qg-next-pied .cta-row{margin-left:0;width:100%}
  .qg-semaine{grid-template-columns:repeat(4,1fr)}
}
@media(max-width:560px){
  .qg-ava{width:48px;height:48px}
  .qg-chiffres{grid-template-columns:repeat(3,1fr);gap:4px}
  .qg-chiffres b{font-size:1.25rem}
  .qg-perso-liens{margin-left:0}
  .qg-semaine{grid-template-columns:repeat(3,1fr)}
  .notifs a,.notifs .no-lien{grid-template-columns:auto 1fr;row-gap:4px}
  .notifs .nt-quand{grid-column:2}
}

/* --- Palmarès (Hall of Fame) --- */
/* Quatre blocs égaux qui se replient tout seuls : le nombre de classements
   varie (un tableau sans donnée disparaît), donc pas de grille figée — le
   piège déjà payé sur la barre de chiffres de l'accueil. */
.hof{margin:0 0 clamp(28px,4vw,44px)}
.hof-grille{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:var(--gap)}
.hof-bloc{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:18px 20px;border-top:3px solid var(--gold)}
.hof-bloc h3{margin:0 0 6px;font-size:.95rem}
.hof-p{color:var(--faint);font-size:.78rem;margin:0 0 12px;line-height:1.45}
.hof-liste{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.hof-liste li{display:flex;align-items:center;gap:10px;font-size:.92rem}
/* Le rang en doré : la palette réserve cette couleur aux distinctions, et
   c'est exactement ce dont il s'agit ici. */
.hof-rang{width:20px;flex:none;text-align:center;font-family:var(--font-title);
  font-weight:700;color:var(--gold)}
.hof-liste li:first-child .hof-rang{font-size:1.15rem}
.hof-val{margin-left:auto;font-family:var(--font-title);font-weight:700;
  font-size:.95rem;white-space:nowrap}
/* Version resserrée pour le tableau de bord : pas de titre ni d'explication,
   la place y est comptée. */
.hof-compact .hof-grille{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.hof-compact .hof-bloc{padding:14px 16px}

/* --- « Je participe » : s'inscrire à une soirée depuis sa fiche --- */
/* Encadré et détaché : c'est l'action de la page, elle ne doit pas se lire
   comme un paragraphe de plus entre la description et la compo. */
.signup-box{background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--red);border-radius:var(--r);
  padding:clamp(18px,2.2vw,26px);margin:26px 0}
.signup-box h2{margin:0 0 14px;font-size:1.15rem}
.signup-box > p{color:var(--muted);margin:0 0 14px}
.signup-form{display:flex;flex-wrap:wrap;gap:16px;align-items:flex-end}
.signup-form .f{display:grid;gap:6px;min-width:min(260px,100%)}
.signup-form label{font-size:.8rem;color:var(--muted)}
.signup-form select{background:var(--surface-2);color:var(--text);
  border:1px solid var(--line);border-radius:var(--r-sm);padding:0 12px;
  height:var(--field-h);font:inherit;font-size:.92rem;width:100%}
.signup-form select:focus{border-color:var(--red-line)}
.signup-form select:focus:not(:focus-visible){outline:none}
.signup-actions{display:flex;gap:10px;flex-wrap:wrap}
/* L'état actuel se lit AVANT les champs : « tu es déjà inscrit » change le
   sens des deux boutons. */
.signup-etat{margin:0 0 14px;font-size:.92rem}
.signup-etat.ok{color:var(--ok)}
.signup-etat.ko{color:var(--red-text)}
/* Les conflits (roadmap n°4) : ce qu'on a déjà dit de sa semaine et qui colle
   mal avec cette sortie. Encadré SOBRE et non rouge — c'est une remarque, pas
   une erreur, et les boutons juste dessous restent parfaitement actifs.
   Le liseré à gauche et le pictogramme portent le sens autant que la teinte :
   la couleur seule ne dit jamais rien ici. */
.signup-avert{border-left:3px solid var(--warn);background:rgba(217,138,43,.10);
  border-radius:6px;padding:10px 14px;margin:0 0 16px}
.signup-avert-t{margin:0;font-size:.88rem;font-weight:600}
.signup-avert ul{margin:6px 0 0;padding-left:20px;color:var(--muted);font-size:.88rem}
.signup-avert li+li{margin-top:3px}
@media(max-width:640px){
  .signup-form{flex-direction:column;align-items:stretch}
  .signup-actions .btn{flex:1}
}
/* Le retour d'une action : vert discret ou rouge, jamais une pop-up. */
.flash{margin:0 0 22px;padding:12px 16px;border-radius:var(--r-sm);
  border:1px solid var(--line);background:var(--surface);font-size:.92rem}
.flash.ok{border-left:3px solid var(--ok)}
.flash.ko{border-left:3px solid var(--red);color:var(--text)}
@media(max-width:820px){.prof-actions{grid-template-columns:1fr}}

/* --- Recrutement --- */
.needs{list-style:none;padding:0;margin:26px 0;display:flex;flex-wrap:wrap;gap:12px}
.need{display:flex;align-items:center;gap:10px;background:var(--surface);
  border:1px solid var(--line);border-left:3px solid var(--red);
  border-radius:var(--r-sm);padding:10px 18px}
.need-ic{width:26px;height:26px;border-radius:5px;display:block}
.need-role{font-weight:700;font-size:1.02rem}
.need-count{color:var(--muted);font-weight:800;font-variant-numeric:tabular-nums;font-size:1rem}
.needs-none{color:var(--muted)}

/* --- Charte --- */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.cards article{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:clamp(20px,2.4vw,28px);
  border-top:3px solid var(--red);transition:transform var(--t),border-color var(--t)}
.cards article:hover{transform:translateY(var(--lift))}
.cards h3{margin:0 0 8px}
.cards p{color:var(--muted);margin:0}

/* --- « Discord, le bot et le site » --- */
/* ⚠️ Préfixées `fonc-` : une seule feuille sert tout le site, et un nom
   générique s'y télescope avec une autre page (le `.roles` du recrutement a
   déjà déformé les pastilles de l'accueil). */
.cards.fonc article{border-top-color:var(--line);border-left:3px solid var(--red)}
.cards.fonc h3{font-size:.98rem;color:var(--red-text);letter-spacing:.03em}
.fonc-cta{align-items:center;flex-wrap:wrap;gap:14px}
.fonc-etat{color:var(--muted);font-size:.9rem}

/* --- Pied de page multi-colonnes --- */
/* Trois colonnes qui répondent à trois questions (qui êtes-vous / où aller /
   comment vous rejoindre), et non un bloc centré décoratif. La première est
   plus large : elle porte le texte, les deux autres des listes. */
/* ⚠️⚠️ **La décoration du pied de page** (Kevin, 2026-07-28 : « je voudrais un
   effet visuel, quelque chose qui embellit le bas de page »). Trois couches,
   **toutes en CSS et toutes immobiles** :
   1. un **trait laser** rouge sur l'arête haute — le même motif que les
      séparateurs entre sections, donc rien de neuf à apprendre à l'œil ;
   2. le **loup du logo en filigrane** à 3,5 %, centré derrière la marque : à
      cette opacité il se devine sans se regarder. Il avait cet emploi dans
      l'ancien bandeau du QG, qui a disparu — c'est sa vraie place, sur la
      dernière chose qu'on voit d'une page ;
   3. une **lueur rouge très basse et très large** derrière le logo, qui donne
      au sombre la profondeur qu'un aplat n'a pas.
   ⚠️ **Rien ne bouge, et c'est voulu** : sa propre règle interdit les
   particules permanentes et les effets qui n'expliquent rien. Une décoration
   qui s'anime en boucle en bas de page est un aimant à regard placé exactement
   là où on n'a plus rien à dire.
   ⚠️ **Zéro octet de plus** : le loup est `logo.png`, déjà chargé par la
   marque juste au-dessus et gardé 30 jours en cache. Aucune image neuve,
   aucun script. */
.site-footer{position:relative;overflow:hidden;
  border-top:1px solid var(--line);background:#050608;
  padding:clamp(40px,5vw,64px) 20px 0}
.site-footer:before{content:"";position:absolute;top:-1px;left:0;right:0;
  height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--red) 28%,
             var(--red) 72%,transparent);opacity:.6}
/* ⚠️ **Vu à l'écran, pas calculé** : à 3,5 % sur 560 px, le loup se lisait
   nettement et passait derrière les trois colonnes de liens — une illustration
   envahissante, exactement ce que le brief interdit. Ramené à 2,2 % et à
   340 px, il reste **dans la zone de la marque** (qui n'a pas de texte à sa
   droite) et se devine au lieu de se regarder. */
.site-footer:after{content:"";position:absolute;top:-46px;left:50%;
  width:min(340px,70vw);height:min(340px,70vw);transform:translateX(-50%);
  background:url("/static/logo.png") center top/contain no-repeat;
  opacity:.022;pointer-events:none}
/* ⚠️ Les contenus repassent AU-DESSUS du filigrane : sans ce `z-index`, le
   pseudo-élément se poserait par-dessus les liens et les rendrait ternes. */
.site-footer > *{position:relative;z-index:1}
/* La lueur : ancrée sur le bloc de marque, donc centrée quoi qu'il arrive. */
.foot-tete{position:relative}
.foot-tete:before{content:"";position:absolute;left:50%;top:-30px;
  width:min(760px,100%);height:220px;transform:translateX(-50%);
  background:radial-gradient(closest-side,rgba(210,10,46,.16),transparent 72%);
  pointer-events:none;z-index:-1}
/* ⚠️⚠️ **Réagencé le 2026-07-28** (Kevin : « mieux agencé, plus centré, mieux
   organisé, mieux présenté »). Ce qui n'allait pas, mesuré à 1440 :
   - **trois colonnes de largeurs 1,6 / 1 / 1** — la marque s'étalait sur 620 px
     pendant que « Le site » et « Nous rejoindre » se serraient sur 180 ;
   - **des hauteurs sans rapport** : cinq liens d'un côté, un paragraphe et deux
     liens de l'autre, donc trois colonnes qui ne finissaient pas ensemble ;
   - **le bloc légal aligné à gauche** tout en bas, en trois lignes empilées.
   La marque monte donc **en tête, centrée** — c'est elle qui referme la page —
   et les liens passent en **trois colonnes égales** dessous. */
.foot-tete{max-width:var(--wrap);margin:0 auto clamp(28px,4vw,40px);
  display:grid;justify-items:center;text-align:center;gap:14px}
.foot-tete p{color:var(--muted);font-size:.92rem;margin:0;max-width:56ch}
.foot-grid{max-width:900px;margin:0 auto;display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(20px,3vw,40px);
  text-align:center}
.foot-col h2{font-size:.82rem;text-transform:uppercase;letter-spacing:.08em;
  color:var(--text);margin:0 0 10px}
.foot-col ul{list-style:none;margin:0;padding:0;display:grid;gap:2px;
  justify-items:center}
/* ⚠️ `min-height:36px` : mesurés à **17 px** le 2026-07-28. Ce sont les seuls
   chemins vers les pages obligatoires (LCEN) depuis la moitié des pages du
   site — ils doivent s'atteindre au doigt du premier coup. La hauteur vient
   d'un remplissage : le texte garde sa taille et sa place. */
.foot-col a{display:inline-flex;align-items:center;min-height:36px;
  padding:0 8px;color:var(--muted);font-size:.9rem}
.foot-col a:hover{color:var(--text)}
.foot-brand{display:flex;align-items:center;gap:12px;font-family:var(--font-title);
  font-weight:700;font-size:1.35rem;text-transform:uppercase;letter-spacing:.06em}
.foot-brand img{height:44px;width:44px}
.socials{display:flex;gap:14px;flex-wrap:wrap;justify-content:center}
/* Le bas de page : séparé par un trait, centré, en retrait — c'est de la
   mention légale, pas du contenu. */
.foot-bas{max-width:var(--wrap);margin:clamp(28px,4vw,44px) auto 0;
  border-top:1px solid var(--line);padding:18px 0 28px;
  display:grid;gap:6px;justify-items:center;text-align:center}
.foot-legal{margin:0;color:var(--faint);font-size:.76rem;max-width:70ch}
/* Les pages légales : du texte long, donc une mesure courte et de l'air. */
.legal h2{margin:34px 0 10px}
.legal p,.legal li{max-width:72ch;color:#C9CDD5}
.legal ul{padding-left:20px}
.legal li{margin:4px 0}
.legal table td{white-space:normal;vertical-align:top}
.legal table{font-size:.9rem}
/* ⚠️ **Trois colonnes tiennent jusqu'à 560 px** parce qu'elles ne portent plus
   que des liens courts, centrés. C'est tout l'intérêt d'avoir sorti la marque
   et le paragraphe de la grille : plus rien dedans n'a besoin de largeur. */
@media(max-width:560px){.foot-grid{grid-template-columns:1fr;gap:8px}}
.soc{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;
  border:1px solid var(--line);color:var(--muted);background:var(--surface);
  transition:color var(--t-fast),border-color var(--t-fast),
             background var(--t-fast),transform var(--t-fast)}
.soc:hover{color:#fff;border-color:var(--red);background:var(--red);
  transform:translateY(var(--lift))}
.foot-copy{margin:0;color:var(--faint);font-size:.82rem}

/* --- Le mode d'emploi du Discord ---
   ⚠️ Une page de **lecture** : mesure courte, gros numéros, et rien qui
   clignote. Elle s'adresse à quelqu'un qui hésite encore à cliquer. */
.tuto{width:min(var(--wrap),92vw);margin:0 auto;padding:clamp(28px,5vw,56px) 0 80px}
.tuto h1{font-size:clamp(2rem,1.2rem + 2.6vw,3.25rem);margin:0 0 12px}
.tuto > .lead{max-width:64ch;margin:0 0 clamp(32px,4vw,48px)}
.tuto-etapes{display:grid;gap:16px;margin-bottom:clamp(40px,5vw,64px)}
.tuto-etape{display:flex;gap:clamp(16px,2vw,24px);background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(18px,2.4vw,26px)}
/* Le numéro : gros, en rouge, c'est le seul repère de progression de la page. */
.tuto-num{flex:none;width:44px;height:44px;display:grid;place-items:center;
  border-radius:50%;background:var(--red-soft);border:1px solid var(--red-line);
  color:var(--red-text);font-family:var(--font-title);font-size:1.4rem;
  font-weight:700}
.tuto-etape h2{font-size:1.25rem;margin:0 0 8px}
.tuto-etape p{margin:0;color:#C9CDD5;max-width:70ch}
.tuto-liste{margin:14px 0 0;padding-left:20px;display:grid;gap:7px;
  color:var(--muted);font-size:.94rem;max-width:70ch}
.tuto-liste li{margin:0}
.tuto-liste b{color:var(--text)}
.tuto-bloc{margin-bottom:clamp(40px,5vw,64px)}
.tuto-bloc > h2{margin:0 0 14px}
.tuto-bloc > p{color:var(--muted);max-width:70ch;margin:0 0 20px}
.tuto-bloc table{width:100%;border-collapse:collapse;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.tuto-bloc th,.tuto-bloc td{padding:12px 14px;border-bottom:1px solid var(--line);
  font-size:.92rem}
.tuto-bloc th{background:var(--surface-2);color:var(--muted);font-size:.8rem;
  text-transform:uppercase;letter-spacing:.06em}
.tuto-bloc tr:last-child td{border-bottom:0}
.tuto-bloc td a{color:var(--red-text);text-decoration:underline;
  display:inline-flex;align-items:center;min-height:36px}
/* Les questions : repliées, parce qu'on n'en lit qu'une — la sienne. */
.tuto-q{background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-sm);margin-bottom:8px}
.tuto-q > summary{cursor:pointer;list-style:none;padding:12px 16px;
  font-weight:600;font-size:.95rem;min-height:36px;display:flex;
  align-items:center;gap:10px}
.tuto-q > summary::-webkit-details-marker{display:none}
/* ⚠️ Le chevron est décoratif : c'est `<details>` qui annonce l'état ouvert ou
   fermé au lecteur d'écran, pas ce caractère. */
.tuto-q > summary:before{content:"+";color:var(--red-text);font-weight:700;
  font-size:1.1rem;line-height:1}
/* Le vrai signe « moins » (U+2212) ferait échouer ruff (RUF001, caractère
   ambigu) : on l'écrit en échappement CSS, ce que le navigateur lit pareil. */
.tuto-q[open] > summary:before{content:"2"}
.tuto-q > summary:hover{color:var(--red-text)}
.tuto-q p{margin:0;padding:0 16px 16px 40px;color:#C9CDD5;max-width:70ch;
  font-size:.94rem}
.tuto-q a{color:var(--red-text);text-decoration:underline}
@media(max-width:560px){
  .tuto-etape{flex-direction:column;gap:12px}
  .tuto-q p{padding-left:16px}
}

/* --- Armurerie --- */
.armory{width:min(var(--wrap),92vw);margin:0 auto;padding:clamp(28px,5vw,56px) 0 80px}
.armory h1{font-size:clamp(2rem,1.2rem + 2.6vw,3.25rem);margin:0 0 6px}
.armory .sub{color:var(--muted);margin:0 0 26px;max-width:640px}
.armory table{width:100%;border-collapse:collapse;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin-bottom:16px}
/* 🐞 **L'alignement des en-têtes est GLOBAL, pas réservé à l'armurerie.**
   Mesuré dans le QG le 2026-07-28 : les **42 en-têtes** de la page étaient
   centrés (le défaut du navigateur pour `th`) pendant que **toutes** les
   cellules étaient à gauche — « Donjon » flottait au milieu au-dessus d'une
   colonne de noms alignés. La règle existait, mais accrochée à `.armory` : le
   QG a une autre classe de `main`, il ne l'héritait pas.
   ⚠️ Un style de tableau ne doit pas dépendre de la classe de la page. */
th{text-align:start}
.armory th,.armory td{text-align:left;padding:.7rem .9rem;border-bottom:1px solid var(--line)}
.armory th{color:var(--muted);font-size:.75rem;text-transform:uppercase;letter-spacing:.06em}
.armory tbody tr:last-child td{border-bottom:0}
.armory tbody tr:hover td{background:var(--surface-3)}
.wow{display:inline-flex;align-items:center;gap:.45rem}
.ic{width:24px;height:24px;border-radius:5px;display:block}
/* ⚠️ `min-height:36px` : mesuré à 29 px. C'est le lien qui mène à la fiche
   d'un membre depuis la liste de l'armurerie — la cible la plus cliquée de
   la page. */
.rowlink{display:inline-flex;align-items:center;min-height:36px}
/* La classe et la spé, écrites sous le nom : la couleur seule ne dit rien à un
   daltonien ni à un lecteur d'écran (relevé à l'audit). */
.char-spec{display:block;margin-top:2px;font-size:.78rem;color:var(--muted)}
.back{display:inline-block;color:var(--muted);margin-bottom:16px;font-weight:600}
.back:hover{color:#fff}
/* --- Filtres de l'armurerie ---
   `js-only` : cachés tant que le script n'a pas pris la main. Des filtres qui
   ne filtrent pas seraient pires que pas de filtres du tout. */
.js-only{display:none}
.js .js-only{display:flex}
.armory-filters{flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 18px}
.armory-filters input,.armory-filters select{
  background:var(--surface);color:var(--text);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:0 14px;height:var(--field-h);font:inherit;font-size:.95rem;
  transition:border-color var(--t-fast)}
.armory-filters input{min-width:min(240px,100%)}
.armory-filters input:hover,.armory-filters select:hover{border-color:var(--line-strong)}
.f-compte{margin-left:auto;color:var(--muted);font-size:.85rem}

/* --- En-têtes triables ---
   Le bouton est posé par le JS : sans script, l'en-tête reste un titre, et
   rien ne promet un tri qui n'aurait pas lieu. */
/* ⚠️ `min-height:36px` : mesuré à **19 px** le 2026-07-28, la plus petite cible
   du site. Trier une colonne de l'armurerie au doigt était un pari. La hauteur
   vient d'un remplissage vertical : l'en-tête ne bouge pas, seule la zone
   cliquable grandit. */
th button.tri{background:none;border:0;padding:0;font:inherit;color:inherit;
  text-transform:inherit;letter-spacing:inherit;cursor:pointer;
  min-height:36px;
  display:inline-flex;align-items:center;gap:.35rem;transition:color var(--t-fast)}
th button.tri:hover{color:var(--text)}
/* La flèche n'apparaît que sur la colonne qui trie : trois chevrons gris
   permanents ajouteraient du bruit sans rien dire. */
th button.tri:after{content:"";opacity:0;width:0;height:0;
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-bottom:5px solid var(--red-text);transition:opacity var(--t-fast)}
th[aria-sort="ascending"] button.tri:after{opacity:1}
th[aria-sort="descending"] button.tri:after{opacity:1;transform:rotate(180deg)}
th[aria-sort="ascending"] button.tri,th[aria-sort="descending"] button.tri{color:var(--text)}
.chips{display:flex;flex-wrap:wrap;gap:8px}
.pill{display:inline-block;padding:.15rem .6rem;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--line);font-size:.82rem;color:var(--text)}
/* ⚠️ La puce qui porte une heure de rendez-vous : c'est la seule information de
   la ligne qui engage à être là à un moment précis. Le rouge est ici à son
   emploi — une information prioritaire, pas une décoration. */
.pill.fort{border-color:var(--red-line);background:var(--red-soft);
  color:var(--red-text);font-weight:600}
/* Le départ, sur la carte d'une clé dans l'agenda. */
.key-depart{margin:8px 0 0;font-size:.85rem;color:var(--red-text);font-weight:600}

/* --- Fiche perso --- */
.char-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(16px,3vw,26px);margin-bottom:20px}
.char-head{display:flex;align-items:center;gap:12px;font-size:1.3rem;margin-bottom:14px;flex-wrap:wrap}
.char-head .realm{color:var(--muted);font-size:.9rem;font-weight:500}
.char-card h3{font-size:.9rem;letter-spacing:.05em;color:var(--muted);margin:20px 0 8px}
.dg-wrap{display:inline-flex;align-items:center;gap:.6rem}
.dg{width:56px;height:32px;border-radius:5px;object-fit:cover;display:block;
  border:1px solid var(--line)}
.facts{display:flex;gap:2rem;flex-wrap:wrap}
.fact{display:flex;flex-direction:column;gap:2px}
.fact span{font-size:.78rem;text-transform:uppercase;letter-spacing:.06em;color:var(--faint)}
.fact strong{font-size:1.05rem}

/* --- Event & M+ --- */
.armory h2{font-size:1.3rem;margin:0 0 14px;letter-spacing:.04em}
.agenda-block{margin-bottom:34px}
.filters{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 18px}
/* `min-height:36px` : mesurés à 35 px, ces filtres passaient sous le plancher
   tactile fixé à la 2ᵉ passe. Un pixel de moins ne se voit pas, mais au doigt
   ça compte — et c'est un seuil, pas une moyenne. */
.filter{border:1px solid var(--line);background:var(--surface);color:var(--muted);
  border-radius:999px;padding:.35rem .9rem;min-height:36px;font:inherit;
  font-size:.85rem;font-weight:600;
  cursor:pointer;transition:color var(--t-fast),border-color var(--t-fast)}
.filter:hover{color:#fff;border-color:var(--line-strong)}
.filter.on{background:var(--red);border-color:var(--red);color:#fff}
.evs{display:grid;gap:12px;margin-bottom:8px}
/* La carte est un <a> : elle mène à sa fiche (compo + description). */
.ev{display:grid;grid-template-columns:170px 1fr minmax(280px,auto);gap:16px;
  align-items:center;
  background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--c);
  border-radius:var(--r);padding:14px 18px;
  transition:transform var(--t),border-color var(--t),background var(--t)}
.ev:hover{transform:translateY(var(--lift));background:var(--surface-2)}
.ev-when{display:flex;flex-direction:column;gap:4px}
.ev-when .num{font-weight:700}
.ev .cat{align-self:flex-start;font-size:.75rem;font-weight:700;text-transform:uppercase;
  letter-spacing:.04em;color:var(--c)}
.ev-body h3{margin:0 0 4px;font-size:1.05rem;text-transform:none;letter-spacing:0;color:var(--text)}
.ev-meta{display:flex;align-items:center;gap:10px;flex-wrap:wrap;color:var(--muted);font-size:.85rem}
.ev-meta .type{font-weight:600;color:#CFD2D9}
.tg{background:var(--surface-2);border:1px solid var(--line);border-radius:6px;
  padding:.05rem .45rem;font-size:.75rem;color:var(--text)}
/* Centrée dans sa colonne (Kevin, 2026-07-27) : les rangées s'alignent d'une
   carte à l'autre au lieu de se coller au bord droit. */
.ev-side{display:flex;align-items:center;gap:12px;justify-self:center}
.ev-side .who{color:var(--muted);font-size:1rem;font-variant-numeric:tabular-nums}
.keys{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px}
.key{display:block;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:14px 16px;
  transition:transform var(--t),border-color var(--t),background var(--t)}
.key:hover{transform:translateY(var(--lift));background:var(--surface-2)}

/* --- Fiches d'un événement / d'une clé --- */
.detail-head{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 18px}
.detail-desc{color:#C9CDD5;white-space:pre-wrap;margin:0 0 26px;max-width:70ch}
.roster{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--gap)}
.slot{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  border-top:3px solid var(--line-strong);padding:16px 18px}
.slot.filled{border-top-color:var(--red)}
.slot h3{margin:0 0 12px;font-size:1.05rem;display:flex;justify-content:space-between;gap:8px}
.slot h3 b{color:var(--muted);font-weight:600;font-variant-numeric:tabular-nums}
.slot ul{margin:0;padding:0;list-style:none;display:grid;gap:8px}
.slot li{display:flex;align-items:center;gap:.5rem}
.slot .empty{color:var(--faint);font-size:.88rem;margin:0}
/* Les groupes formés. `filled` y veut dire « complet » (et non « non vide »
   comme sur la compo) : c'est le liseré rouge qui dit « celui-ci peut partir ». */
/* `align-items:start` : une carte se règle sur SON contenu. Étirées à la même
   hauteur, celles qui comptent deux joueurs traînaient 100 px de vide dessous. */
.groupes{align-items:start}
.groupes .slot-emoji{flex:0 0 auto;font-size:.9rem;line-height:1}
.groupes .manque{color:var(--red);font-size:.85rem;margin:12px 0 0}
/* La clé du porteur, dans le groupe d'une recherche M+. */
.porteur{flex:0 0 auto;font-size:.85rem}
/* Un filet entre les cases (Kevin, 2026-07-28). Sur `+ .case` et non sur toutes :
   un trait au-dessus de la première ferait doublon avec le titre de la carte. */
.groupes .case + .case{margin-top:11px;padding-top:11px;border-top:1px solid var(--line)}
.empty{color:var(--muted)}
.mine{list-style:none;padding:0;margin:0;display:grid;gap:10px}
.mine li{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);
  border-left:3px solid var(--red);padding:12px 16px}

/* --- Personnage repliable (<details> natif, sans JavaScript) --- */
.char-fold{border:1px solid var(--line);border-radius:var(--r);background:var(--surface);
  margin-bottom:12px;overflow:hidden}
.char-fold > summary{display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:14px 18px;cursor:pointer;list-style:none;font-size:1.1rem;
  transition:background var(--t-fast)}
.char-fold > summary::-webkit-details-marker{display:none}
.char-fold > summary:hover{background:var(--surface-2)}
/* Le chevron : dessiné en CSS, il tourne quand le bloc s'ouvre. */
.char-fold > summary:after{content:"";margin-left:auto;width:9px;height:9px;
  border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);
  transform:rotate(45deg);transition:transform var(--t-fast)}
.char-fold[open] > summary{border-bottom:1px solid var(--line)}
.char-fold[open] > summary:after{transform:rotate(-135deg)}
/* ⚠️ Le nom du perso est un `<h2>` (accessibilité : il structure la page), mais
   il ne doit RIEN changer à l'apparence — il hérite donc de la barre. Sans ces
   remises à zéro, un titre de niveau 2 y apporterait sa taille et ses marges. */
.char-fold > summary > .fold-nom{margin:0;font-size:inherit;font-weight:inherit;
  line-height:inherit;letter-spacing:inherit;text-transform:none;display:contents}
.fold-meta{color:var(--muted);font-size:.82rem;font-weight:500}
/* ⚠️ Le marqueur « hors guilde » : doré (attention), pas rouge (problème). Un
   reroll dans une autre guilde n'est pas une faute — c'est un fait qui explique
   pourquoi il ne compte pas pour l'effectif. Et il porte du TEXTE, pas
   seulement une couleur : la règle du site interdit de confier une information
   à la seule teinte. */
.hors-guilde{margin-left:8px;padding:2px 8px;border-radius:999px;
  background:rgba(230,180,80,.14);border:1px solid rgba(230,180,80,.4);
  color:var(--gold);font-size:.75rem;font-weight:600;white-space:nowrap}
/* Dépliée, la fiche n'a plus besoin de son propre cadre : il ferait doublon. */
.char-fold .char-card{border:0;background:transparent;margin:0;padding:4px 18px 18px}
.key-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.key-head .lvl{font-family:var(--font-title);font-weight:700;font-size:1.2rem;
  color:var(--red-text);font-variant-numeric:tabular-nums}
.key-note{color:var(--muted);font-size:.85rem;margin:.4rem 0 0}
.key-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:12px}
.key-foot .spots{color:var(--muted);font-size:.82rem}
.key-foot .icons{display:inline-flex;gap:4px}

/* ========================= Page Recrutement =========================
   Elle répond, dans l'ordre, aux trois questions d'un candidat : « est-ce
   qu'il y a une place pour moi ? », « qu'est-ce que je dois faire ? », et
   « est-ce que je vais m'y plaire ? ». Le reste est du décor. */
.recruit{width:min(var(--wrap),92vw);margin:0 auto;padding:clamp(28px,5vw,56px) 0 80px}
.recruit h1{font-size:clamp(2rem,1.2rem + 2.6vw,3.25rem);margin:0 0 8px}
.recruit .sub{color:var(--muted);margin:0 0 clamp(32px,5vw,56px);max-width:70ch}
.rec-block{margin:0 0 clamp(44px,6vw,80px)}
.rec-block h2{margin:0 0 20px}
.rec-note{color:var(--faint);font-size:.84rem;margin:18px 0 0}

/* --- Les trois rôles. Toujours les trois, même fermés : « Fermé » est une
       réponse utile, un rôle escamoté n'en est pas une. --- */
.roles{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:var(--gap)}
.role{display:flex;flex-direction:column;gap:12px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  border-top:3px solid var(--line-strong);padding:clamp(18px,2.4vw,26px);
  transition:transform var(--t),border-color var(--t)}
/* Le rouge dit « il y a une place ici » — une information, pas une décoration. */
.role.open{border-top-color:var(--red)}
.role.open:hover{transform:translateY(var(--lift))}
.role.closed{opacity:.7}
.role-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
.role-head h3{margin:0;font-size:1.35rem}
.role-hint{margin:0;color:var(--muted);font-size:.92rem}
.role .needs{margin:0;flex-direction:column;align-items:stretch;gap:8px}
.role .need{padding:8px 14px}
.role-total{margin:auto 0 0;padding-top:4px;color:var(--faint);font-size:.75rem;
  text-transform:uppercase;letter-spacing:.12em}

/* --- Le parcours de candidature --- */
.steps{list-style:none;padding:0;margin:0;display:grid;gap:12px}
.step{display:grid;grid-template-columns:52px 1fr;gap:16px;align-items:start;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  border-left:3px solid var(--red-line);padding:18px 20px}
.step-n{font-family:var(--font-title);font-weight:700;font-size:1.7rem;line-height:1;
  color:var(--red-text);font-variant-numeric:tabular-nums}
.step h3{margin:0 0 4px;font-size:1.1rem}
.step p{margin:0;color:var(--muted)}

/* --- « Pour toi si » / « pas pour toi si » : deux colonnes franches ---
       Le vert et l'orange sont des SIGNAUX (--ok / --warn), pas l'identité :
       ici il faut lire « oui » et « non » d'un coup d'œil, et le rouge NRV ne
       peut pas dire les deux. */
.fit{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap)}
.fit-col{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(18px,2.4vw,26px)}
.fit-col.yes{border-top:3px solid var(--ok)}
.fit-col.no{border-top:3px solid var(--warn)}
.fit-col h3{margin:0 0 14px;font-size:1.15rem}
.fit-col ul{margin:0;padding:0;list-style:none;display:grid;gap:10px}
.fit-col li{display:grid;grid-template-columns:20px 1fr;gap:10px;color:var(--muted)}
.fit-col li:before{font-weight:700;line-height:1.6}
.fit-col.yes li:before{content:"✓";color:var(--ok)}
.fit-col.no li:before{content:"✕";color:var(--warn)}

/* --- L'appel à l'action, une seule fois, tout en bas --- */
.rec-cta{text-align:center;border:1px solid var(--red-line);border-radius:var(--r-lg);
  padding:clamp(26px,4vw,48px) 20px;
  background:radial-gradient(700px 300px at 50% 0%,rgba(210,10,46,.16),transparent 70%),
             var(--surface)}
.rec-cta h2{margin:0 0 10px}
.rec-cta p{color:var(--muted);margin:0 auto 26px;max-width:56ch}

/* ============================ Adaptations ============================ */
@media(max-width:1024px){
  .about{grid-template-columns:1fr}
  .cards{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:820px){
  .fit{grid-template-columns:1fr}
}
@media(max-width:900px){
  .burger{display:grid}
  /* Le menu descend sous la barre au lieu de s'entasser dedans. */
  .links{position:absolute;top:var(--nav-h);left:0;right:0;margin:0;
    display:none;flex-direction:column;align-items:stretch;gap:0;
    padding:8px var(--gutter) 18px;
    background:rgba(9,11,15,.98);border-bottom:1px solid var(--line)}
  .topbar.open .links{display:flex}
  .links a{padding:13px 0;border-bottom:1px solid var(--line);font-size:1rem}
  .links a.on:after{display:none}
  .links a.on{color:var(--red)}
  .links a.staff{margin-top:14px;justify-content:center;height:46px;border-bottom:0}
  .links a.logout{border-bottom:0}
  /* Deux par ligne. On repasse en flux de lignes, sinon les cases resteraient
     sur une seule ligne et se compresseraient à l'illisible. */
  .stats-wrap{grid-auto-flow:row;grid-template-columns:repeat(2,1fr)}
  /* Le trait de séparation ne se met qu'ENTRE deux cases d'une même ligne :
     sur deux colonnes, ce sont les cases impaires qui ouvrent une ligne. */
  .stat:nth-child(odd):before{display:none}
  .stat:nth-child(n+3){border-top:1px solid var(--line)}
}
@media(max-width:640px){
  .cards{grid-template-columns:1fr}
  .brand small{display:none}
  .cta-row .btn{flex:1 1 100%}
  .ev{grid-template-columns:1fr}
  .step{grid-template-columns:38px 1fr;gap:12px;padding:16px}
}
