/* ─────────────────────────────────────────────────────────────────────────────
   base.css · le design system

   PORT STRICT de la feuille `base.css` de la documentation de référence
   (documentation-sey.html, bloc `#css-base`). Les tokens, les métriques, les
   composants et les animations sont repris valeur par valeur. On reprend
   l'esthétique, jamais l'identité : le motif de fond est un E, pas le « S » de
   la référence.

   ── La seule substitution, assumée et systématique ──
   La doc est monochrome absolu. L'emphase s'y fait par trois moyens, dans cet
   ordre : opacité → INVERSION (pavé blanc) → FILET lumineux (trait blanc +
   bloom en plus-lighter). EnoPVP garde ces trois moyens et leur ordre, mais
   l'inversion et le filet passent du blanc au JAUNE `#ffd400`, celui du logo et
   du bandeau du serveur.
   Tout le reste est inchangé : la rampe d'encre reste blanche, les surfaces
   restent noires, et il n'y a AUCUNE teinte décorative. La couleur n'existe
   qu'à deux endroits, comme dans la doc : les pastilles d'état et les jetons
   de type.

   Ce fichier ne contient que le design system. La mise en page des pages
   d'EnoPVP vit dans site.css, chargé après.

   Les polices sont hébergées ici : la CSP du site est en `'self'`, aucune
   requête tierce, rien à déclarer côté RGPD.
   ───────────────────────────────────────────────────────────────────────────── */

/* Les deux RightGrotesk de la doc sont des polices commerciales. La doc prescrit
   elle-même les substituts : Archivo Black pour la display, Inter en
   letter-spacing élargi pour la wide. Inter et JetBrains Mono sont libres. */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-weight: 400 900;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('/fonts/jetbrains-mono.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo Black';
  src: url('/fonts/archivo-black.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}

:root {
  /* base */
  --lum: 255, 255, 255;
  --acc-lum: 255, 212, 0;
  --base: #0a0a0a;
  --card: #0d0d0f;

  /* encre : une seule couleur, du blanc, décliné en opacités.
     L'usage de chaque niveau est fixé par la doc, section 02. */
  --ink: #fff;              /* blanc pur : titre principal, lien actif */
  --ink-hi: #ffffffe0;      /* titres, valeurs fortes */
  --ink-strong: #ffffffd6;  /* libellés de bouton */
  --ink-on-media: #ffffffd1;/* texte posé sur une photo */
  --ink-body: #ffffffa8;    /* texte courant */
  --ink-mid: #ffffff80;     /* descriptions, sous-titres */
  --ink-meta: #ffffff75;    /* mono, métadonnées */
  --ink-nav: #fff9;         /* liens de nav au repos */
  --ink-decor: #ffffff4d;   /* décor, placeholders */
  --ink-ghost: #ffffff29;   /* états vides */

  /* bordures */
  --line-0: #ffffff0f;      /* séparateurs internes */
  --line-1: #ffffff1f;      /* bordure standard */
  --line-2: #fff3;          /* bordure au survol */
  --line-3: #ffffff57;      /* contour du bouton secondaire */
  --line-edge: #ffffff38;   /* arête du panneau */
  --line-edge-hi: #ffffff8c;/* arête vive, focus de bordure */

  /* surfaces */
  --surface-1: #ffffff08;   /* tuiles, chips */
  --surface-2: #0006;       /* cartes */
  --surface-3: #00000085;   /* panneaux */
  --hover: #ffffff12;       /* survol */

  /* inversion : le pavé plein sert de « couleur primaire ».
     Doc : blanc. EnoPVP : le jaune de la marque. */
  --invert: #ffd400;
  --invert-hover: #ffdd33;
  --invert-down: #e0ba00;
  --on-invert: #0a0a0a;
  --on-invert-2: #0a0a0a9e;
  --on-invert-line: #0a0a0a2e;

  /* filet lumineux : la signature. Doc : blanc. EnoPVP : jaune. */
  --fil: #ffd400;
  --fil-bloom: 0 0 10px rgba(var(--acc-lum), .45), 0 0 22px rgba(var(--acc-lum), .18);
  --glow-mid: rgba(var(--acc-lum), .1);

  /* champs « creusés » */
  --groove-fill: #0000006b;
  --groove-rim: rgba(var(--lum), .07);
  --groove-rim-strong: rgba(var(--lum), .2);
  --groove-in: inset 0 1px 3px #0009, inset 0 -1px 0 rgba(var(--lum), .05);

  /* focus : anneau + tampon noir. Sur pavé plein, les deux s'inversent. */
  --focus-ring: rgba(var(--acc-lum), .85);
  --focus-pad: 0 0 0 6px #000000bf;
  --focus-ring-on-invert: #0a0a0a;
  --focus-pad-on-invert: 0 0 0 7px rgba(var(--acc-lum), .9);

  /* typo */
  --font-display: 'Archivo Black', 'Arial Black', sans-serif;
  --font-wide: 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  /* divers */
  --pattern-url: url('/img/pattern-logo.png');
  --transition-fast: .15s ease;
  --max-content: 1280px;

  /* états : la seule couleur admise, avec les jetons de type */
  --ok: #34d399;
  --warn: #fbbf24;
  --bad: #f87171;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; color-scheme: dark; }
body { margin: 0; background: var(--base); color: var(--ink-body); font-family: var(--font-sans); font-size: 15px; line-height: 1.6; -webkit-font-smoothing: antialiased; overflow-x: hidden; }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
button, input, select { font: inherit; color: inherit; }
[hidden] { display: none !important; }

/* ---------- Fond : la marque tuilée à 3 % ----------
   Tuile de 80 px. Au-delà de 0.03 elle relève le noir de fond et écrase la
   rampe d'encre : la limite est dans la doc, elle n'est pas négociable.

   ⚠️ LES 3 % SONT CUITS DANS `img/pattern-logo.png`, exactement comme la tuile de la
   doc porte son `opacity="0.03"`. C'est ce qui rend les `opacity` ci-dessous
   lisibles telles quelles : une bande à `.6` donne 1,8 % de glyphe, pas 60 %.
   Ne JAMAIS réappliquer l'opacité ici, et ne pas la retirer du fichier. */
.pattern-section { background: var(--pattern-url) repeat, #0a0a0a; background-size: 80px 80px, 100%; }
.pattern-bg { background: linear-gradient(to bottom, #0a0a0a 0%, transparent 150px), var(--pattern-url) repeat, #0a0a0a; background-size: 100% 100%, 80px 80px, 100%; }
.pattern-hero { background: linear-gradient(to bottom, #0a0a0a 0%, #0a0a0ab3 40%, #0a0a0a4d 100%), var(--pattern-url) repeat, #0a0a0a; background-size: 100% 100%, 80px 80px, 100%; }
.menu-box { position: relative; }
.menu-box::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: var(--pattern-url); background-repeat: repeat; background-size: 40px 40px; opacity: .06; }

/* ---------- Typographie ---------- */
.eyebrow { margin: 0 0 18px; font-family: var(--font-wide); font-size: .7rem; font-weight: 500; letter-spacing: .35em; text-transform: uppercase; color: var(--ink-meta); }
.ghost-num { font-family: var(--font-display); font-size: clamp(3.75rem, 7vw, 5.5rem); line-height: 1; color: transparent; -webkit-text-stroke: 1.5px #ffffff21; }
.mark--soft { background: #ffffff24; color: #fff; font-weight: 600; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
/* Numéro de section, mono en majuscules très espacées. */
.doc-num { margin: 0; font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-decor); }

/* ---------- Cartes & panneaux ----------
   Trois ingrédients de profondeur : surface translucide floutée, liseré interne
   blanc à 6 % qui simule l'arête éclairée, ombre très large et diffuse.
   Détail signature : le filet horizontal de 1 px en haut, à opacity .4, qui
   monte à 1 au survol d'une carte. C'est tout le mouvement du composant. */
.s-card { position: relative; overflow: hidden; border: 1px solid var(--line-1); border-radius: 1rem; background: var(--surface-2); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); box-shadow: inset 0 1px #ffffff0f, 0 16px 44px #00000052; transition: border-color .25s, box-shadow .25s; }
.s-panel { position: relative; overflow: hidden; border: 1px solid var(--line-1); border-radius: 1rem; background: var(--surface-3); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); box-shadow: inset 0 1px #ffffff0f, 0 20px 60px #0006; }
.s-panel--overflow { overflow: visible; }
.s-card::before, .s-panel::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; z-index: 2; pointer-events: none; opacity: .4; transition: opacity .25s; background: linear-gradient(90deg, transparent 4%, var(--line-edge-hi) 50%, transparent 96%); }
.s-card:hover { border-color: var(--line-2); box-shadow: inset 0 1px 0 rgba(var(--lum), .1), 0 22px 60px #00000075; }
.s-card:hover::before { opacity: 1; }
.s-divider { position: relative; height: 1px; background: linear-gradient(90deg, #0000, #ffffff1a 20% 80%, #0000); }
.s-divider::after { content: ""; position: absolute; top: -1px; left: 50%; transform: translateX(-50%); width: 110px; height: 3px; border-radius: 9999px; opacity: .45; background: linear-gradient(to right, transparent, rgba(var(--acc-lum), .8), transparent); }

/* ---------- Boutons ----------
   Un seul bouton plein par écran. Le plein est le pavé inversé, avec une ombre
   portée noire très marquée qui le décolle du fond. Vert et rouge sont réservés
   aux actions destructives ou de confirmation, jamais aux pages vitrines. */
.s-button { display: inline-flex; align-items: center; justify-content: center; gap: .5rem; padding: .55rem 1.1rem; border: 1px solid transparent; border-radius: .5rem; font-family: var(--font-sans); font-size: .875rem; font-weight: 500; white-space: nowrap; cursor: pointer; user-select: none; transition: all var(--transition-fast); background: none; color: var(--ink-strong); }
.s-button:active { transform: translateY(1px); }
.s-button--primary, .s-button--fivem { background: var(--invert); color: var(--on-invert); font-weight: 600; box-shadow: 0 10px 24px -8px #000000e6; }
.s-button--primary:hover, .s-button--fivem:hover { background: var(--invert-hover); box-shadow: 0 5px 14px -8px #000000f2; }
.s-button--primary:active, .s-button--fivem:active { background: var(--invert-down); transform: translateY(1px); }
.s-button--secondary { background: 0 0; border-color: var(--line-3); color: var(--ink-strong); }
.s-button--secondary:hover { background: var(--hover); border-color: var(--line-edge-hi); color: var(--ink); }
.s-button--ghost { background: 0 0; border-color: transparent; color: var(--ink-meta); }
.s-button--ghost:hover { background: var(--surface-1); color: var(--ink); }
.s-button--success { background: #10b981; color: #fff; }
.s-button--success:hover { background: #10b981e6; }
.s-button--danger { background: #ef4444e6; color: #fff; }
.s-button--danger:hover { background: #ef4444bf; }
.s-button--lg { padding: .9rem 2rem; border-radius: .625rem; font-size: 1rem; }
.s-button--sm { padding: .4rem .8rem; font-size: .8125rem; }
.s-button:disabled, .s-button[aria-disabled="true"] { opacity: .5; pointer-events: none; }
.s-button:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; box-shadow: var(--focus-pad); }
.s-button--primary:focus-visible, .s-button--fivem:focus-visible { outline-color: var(--focus-ring-on-invert); box-shadow: var(--focus-pad-on-invert), 0 10px 24px -8px #000000e6; }
/* Icônes : trait 1.8, 13 à 17 px, opacité .7 quand elles accompagnent un texte. */
.s-button svg { width: 15px; height: 15px; opacity: .7; flex: none; }

/* ---------- Champs « creusés » ----------
   À l'inverse des cartes qui sortent du fond, les champs y RENTRENT. Aucune
   couleur au focus : la bordure passe simplement à `--line-3`. */
.s-label { display: block; margin-bottom: .4rem; font-size: .8125rem; font-weight: 500; color: #ffffffb3; }
.s-input { width: 100%; padding: .6rem .9rem; border: 1px solid var(--groove-rim); border-radius: .5rem; background: var(--groove-fill); box-shadow: var(--groove-in); color: var(--ink); font-family: var(--font-sans); font-size: .9rem; outline: none; transition: all var(--transition-fast); }
.s-input:focus { border-color: var(--line-3); }
.s-input:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; box-shadow: var(--groove-in), var(--focus-pad); }
.s-input::placeholder { color: var(--ink-mid); }
.wks-field { display: flex; align-items: center; gap: 14px; height: 64px; padding: 0 12px 0 20px; border: 1px solid var(--groove-rim-strong); border-radius: 14px; background: var(--groove-fill); box-shadow: var(--groove-in), 0 18px 50px #0000008c; }
/* La chip active applique la même inversion que le bouton principal, et son
   compteur passe sur la rampe d'encre du pavé. */
.wks-chip { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; border: 1px solid var(--line-1); border-radius: 9999px; background: var(--surface-1); color: var(--ink-nav); font-size: 13px; cursor: pointer; transition: all var(--transition-fast); }
.wks-chip:hover { background: var(--hover); color: var(--ink-hi); }
.wks-chip--on { background: var(--invert); border-color: transparent; color: var(--on-invert); font-weight: 600; }
.wks-chip--on:hover { background: var(--invert-hover); color: var(--on-invert); border-color: transparent; }
.wks-chip-n { padding-left: 8px; border-left: 1px solid var(--line-1); font-family: var(--font-mono); font-size: 11px; }
.wks-chip--on .wks-chip-n { color: var(--on-invert-2); border-left-color: var(--on-invert-line); }

/* ---------- Navigation : capsule flottante ----------
   Fixe, centrée, détachée du haut de 24 px, large de 95 % et plafonnée à
   1280 px. Au repos 40 % d'opacité et bordure quasi invisible ; au-delà de
   20 px de défilement, 80 % et bordure renforcée.
   L'actif n'est PAS mis en avant par un fond : il passe en encre pleine et
   reçoit le filet lumineux sous le texte. */
.nav { position: fixed; left: 50%; top: 1.5rem; z-index: 50; width: 95%; max-width: var(--max-content); transform: translateX(-50%); }
.nav-in { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: .75rem 1.25rem; border: 1px solid var(--line-0); border-radius: 1rem; background: rgba(0,0,0,.4); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); transition: background .3s, border-color .3s; }
.nav.scrolled .nav-in, .nav.open .nav-in { background: rgba(0,0,0,.8); border-color: var(--line-1); }
.nav-links { display: flex; align-items: center; gap: .125rem; }
.nav-link { position: relative; display: flex; align-items: center; gap: .375rem; padding: .375rem .625rem; border: 1px solid transparent; border-radius: .5rem; font-size: .875rem; font-weight: 500; white-space: nowrap; color: var(--ink-nav); transition: all var(--transition-fast); }
.nav-link svg { width: 14px; height: 14px; opacity: .7; flex: none; }
.nav-link:hover { border-color: var(--line-2); background: var(--hover); color: var(--ink-hi); }
.nav-link[aria-current="page"] { color: var(--ink); }
/* le filet : dégradé jaune + bloom, en plus-lighter. Le mode de fusion est
   non négociable : en couleur pleine, il grillerait les bords. */
.nav-link[aria-current="page"]::after { content: ""; position: absolute; left: .625rem; right: .625rem; bottom: -.25rem; height: 2px; border-radius: 9999px; pointer-events: none; background: linear-gradient(to right, transparent, var(--fil), transparent); box-shadow: var(--fil-bloom); mix-blend-mode: plus-lighter; }
.nav-badge { padding: .125rem .375rem; border-radius: 9999px; background: var(--invert); color: var(--on-invert); font-size: 10px; font-weight: 700; line-height: 1; font-family: var(--font-mono); }
.nav-mobile { margin-top: .5rem; padding: 1rem; border: 1px solid var(--line-1); border-radius: 1rem; background: rgba(0,0,0,.95); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); }
.nav-mobile a { display: flex; align-items: center; gap: .75rem; padding: .75rem 1rem; border-left: 2px solid transparent; border-radius: 0 .5rem .5rem 0; font-size: .875rem; color: var(--ink-nav); }
/* rail vertical lumineux : le même filet, redressé. */
.fil-rail { position: relative; border-left-color: var(--fil); background: var(--surface-1); color: var(--ink); font-weight: 600; }
.fil-rail::before { content: ""; position: absolute; top: 0; bottom: 0; left: -2px; width: 2px; box-shadow: var(--fil-bloom); mix-blend-mode: plus-lighter; pointer-events: none; }

/* ---------- Pastilles d'état : la seule couleur admise ----------
   Une seule construction : texte coloré, fond de la même teinte à 12 %,
   bordure à 30 %, point de 6 px en currentColor. */
.status-pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border: 1px solid var(--line-1); border-radius: 9999px; font-size: 11.5px; font-weight: 500; white-space: nowrap; }
.status-pill__dot { width: 6px; height: 6px; border-radius: 9999px; background: currentColor; flex: none; }
.status-pill--positive { color: #34d399; background: #10b9811f; border-color: #10b9814d; }
.status-pill--warning { color: #fbbf24; background: #f59e0b1f; border-color: #f59e0b4d; }
.status-pill--negative { color: #f87171; background: #ef44441f; border-color: #ef44444d; }
.status-pill--neutral { color: #fff9; background: #ffffff0f; border-color: #ffffff1f; }
/* Variante d'emphase : la doc la fait en blanc, EnoPVP la fait sur le jaune. */
.status-pill--emphasis { background: rgba(var(--acc-lum), .12); border-color: rgba(var(--acc-lum), .28); color: var(--ink); font-weight: 600; }

/* ---------- Carte « fichier » : la pièce maîtresse ----------
   Le contenu présenté comme un fichier Markdown ouvert dans un éditeur.
   Les entrées sont une grille `14px max-content 1fr` : tiret mono, jeton de
   type, texte. Chaque ligne entre avec 50 ms de décalage sur la précédente et
   s'éclaircit au survol par `filter`, jamais par un changement de teinte. */
.patch-hero__panel { position: relative; overflow: hidden; border: 1px solid var(--line-1); border-radius: 16px; background: var(--surface-3); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); box-shadow: inset 0 1px #ffffff0f, 0 24px 70px #0000008c, 0 4px 18px #0006; animation: patch-hero-rise .7s cubic-bezier(.22,1,.36,1) both; }
.patch-hero__panel::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px; z-index: 2; pointer-events: none; background: linear-gradient(90deg, transparent 4%, var(--line-edge) 50%, transparent 96%); }
.patch-hero__tabbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; height: 46px; padding: 0 18px 0 14px; border-bottom: 1px solid #ffffff14; background: #ffffff04; }
.patch-hero__tabs { display: flex; align-items: flex-end; gap: 4px; min-width: 0; }
.patch-hero__tab { position: relative; display: flex; align-items: center; gap: 8px; height: 36px; margin-bottom: -1px; padding: 0 15px; border: 1px solid #ffffff14; border-bottom: none; border-radius: 7px 7px 0 0; background: #ffffff0b; font-family: var(--font-mono); font-size: 12px; letter-spacing: .01em; color: #ffffffc7; white-space: nowrap; }
.patch-hero__tab::after { content: ""; position: absolute; bottom: 0; left: 0; right: 0; height: 2px; border-radius: 2px 2px 0 0; background: linear-gradient(90deg, rgba(var(--acc-lum), .75), rgba(var(--acc-lum), .1)); }
.patch-hero__tab--off { background: transparent; border-color: transparent; color: var(--ink-decor); cursor: pointer; transition: all var(--transition-fast); }
.patch-hero__tab--off::after { display: none; }
.patch-hero__tab--off:hover { color: var(--ink-hi); background: #ffffff06; }
.patch-hero__tab svg { width: 13px; height: 13px; opacity: .45; flex: none; }
/* Le logo EnoPVP tient lieu d'icone de fichier dans l'onglet, comme dans le HUD
   du jeu. Hauteur imposee, largeur libre : la marque n'est pas carree. */
.patch-hero__tab img { height: 14px; width: auto; opacity: .75; flex: none; transition: opacity .25s, filter .25s; }
.patch-hero__panel:hover .patch-hero__tab img { opacity: 1; filter: brightness(1.15); }
.patch-hero__tab-ext { color: #ffffff61; }
.patch-hero__tabmeta { padding-bottom: 12px; font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em; color: var(--ink-meta); white-space: nowrap; }
.patch-hero__cover { position: relative; aspect-ratio: 21 / 8; overflow: hidden; border-bottom: 1px solid var(--line-1); }
.patch-hero__cover img { width: 100%; height: 100%; object-fit: cover; }
.patch-hero__cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,.55), transparent 60%); }
.patch-hero__content { padding: 24px 28px 26px; }
.patch-hero__eyebrow { display: flex; align-items: center; gap: 10px; animation: patch-hero-line .55s cubic-bezier(.22,1,.36,1) 80ms both; }
.patch-hero__version { padding: 2px 6px; border-radius: 4px; background: var(--invert); color: var(--on-invert); font-family: var(--font-mono); font-size: 11px; font-weight: 600; line-height: 1.3; }
.patch-hero__label { font-size: 10.5px; font-weight: 600; letter-spacing: .15em; text-transform: uppercase; color: var(--ink-meta); }
.patch-hero__title { display: flex; align-items: baseline; gap: 10px; margin: 13px 0 0; font-size: 25px; font-weight: 700; line-height: 1.2; letter-spacing: -.02em; color: var(--ink-hi); animation: patch-hero-line .55s cubic-bezier(.22,1,.36,1) .13s both; }
.patch-hero__md-mark { font-family: var(--font-mono); font-size: 15px; font-weight: 500; color: #fff3; transform: translateY(-1px); }
.patch-hero__summary { margin: 14px 0 0; padding: 2px 0 2px 14px; border-left: 2px solid #ffffff21; font-size: 14px; font-style: italic; line-height: 1.55; color: #ffffff94; animation: patch-hero-line .55s cubic-bezier(.22,1,.36,1) .18s both; }
.patch-hero__entries { margin: 20px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; }
.patch-hero__entries li { display: grid; grid-template-columns: 14px max-content 1fr; align-items: baseline; column-gap: 10px; margin: 0 -10px; padding: 8px 10px; border-radius: 8px; transition: background .18s; animation: patch-hero-line .5s cubic-bezier(.22,1,.36,1) both; }
.patch-hero__entries li:nth-child(1) { animation-delay: .24s; }
.patch-hero__entries li:nth-child(2) { animation-delay: .29s; }
.patch-hero__entries li:nth-child(3) { animation-delay: .34s; }
.patch-hero__entries li:nth-child(4) { animation-delay: .39s; }
.patch-hero__entries li:nth-child(5) { animation-delay: .44s; }
.patch-hero__entries li:hover { background: var(--hover); }
.patch-hero__dash { font-family: var(--font-mono); font-size: 13px; color: #ffffff38; user-select: none; }
.patch-hero__token { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; letter-spacing: .02em; transition: filter .18s; }
.patch-hero__entries li:hover .patch-hero__token { filter: brightness(1.18); }
.patch-hero__token--added { color: #34d399; }
.patch-hero__token--changed { color: #c9ccd4; }
.patch-hero__token--balanced { color: #a78bfa; }
.patch-hero__token--fixed { color: #fbbf24; }
.patch-hero__token--optimized { color: #38bdf8; }
.patch-hero__token--removed { color: #f87171; }
.patch-hero__text { font-size: 13.5px; line-height: 1.5; color: #fffc; }
.patch-hero__text b, .patch-hero__text strong { color: var(--ink-hi); font-weight: 600; }
.patch-hero__token--removed ~ .patch-hero__text { color: #ffffff73; text-decoration: line-through #ffffff38; text-decoration-thickness: 1px; }
.patch-hero__rule { height: 1px; margin: 22px 0 20px; background: linear-gradient(90deg, #ffffff17, #ffffff0a 70%, #0000); animation: patch-hero-line .5s .5s both; }
.patch-hero__actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; animation: patch-hero-line .55s cubic-bezier(.22,1,.36,1) .55s both; }
.patch-hero__more { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: #ffffff85; transition: color .18s; }
.patch-hero__more svg { width: 14px; height: 14px; opacity: .6; transition: transform .18s, opacity .18s; }
.patch-hero__more:hover { color: #ffffffe6; }
.patch-hero__more:hover svg { opacity: 1; transform: translateX(2px); }

/* ---------- Bandeau défilant ---------- */
.marquee { overflow: hidden; mask-image: linear-gradient(90deg, #0000, #000 10% 90%, #0000); -webkit-mask-image: linear-gradient(90deg, #0000, #000 10% 90%, #0000); }
.marquee__track { display: flex; align-items: center; gap: 3.5rem; width: max-content; padding-right: 3.5rem; animation: marquee 32s linear infinite; }
.marquee__item { font-family: var(--font-wide); font-size: .72rem; font-weight: 500; letter-spacing: .3em; text-transform: uppercase; white-space: nowrap; color: #ffffff47; }

/* ---------- Invite de défilement ---------- */
.hero-scroll__mouse { display: flex; justify-content: center; width: 26px; height: 42px; padding-top: 7px; border: 2px solid #ffffff80; border-radius: 9999px; }
.hero-scroll__dot { width: 3px; height: 8px; border-radius: 9999px; background: var(--ink); animation: hero-scroll-dot 1.8s cubic-bezier(.22,1,.36,1) infinite; }
.hero-wordmark { filter: drop-shadow(0 8px 30px #000000d9); animation: fade-up .7s cubic-bezier(.22,1,.36,1) forwards, hero-float 7s ease-in-out 1s infinite; animation-delay: var(--d, 0s), 1s; }

/* ---------- Encadré de note : un pavé barré du filet lumineux ---------- */
.note { position: relative; margin: 18px 0; padding: 16px 18px 16px 22px; border-radius: .5rem; background: var(--surface-1); }
.note::before { content: ""; position: absolute; left: 8px; top: 16px; bottom: 16px; width: 2px; border-radius: 9999px; background: var(--fil); box-shadow: var(--fil-bloom); mix-blend-mode: plus-lighter; }
.note p { margin: 0; font-size: 14px; color: var(--ink-body); }
.note p + p { margin-top: 8px; }
.note b, .note strong { color: var(--ink); }
.note.no::before { background: #ffffff2e; box-shadow: none; }

/* ---------- Tableau de règles ---------- */
.rules { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-top: 10px; }
.rules th { text-align: left; padding: 9px 14px; font: 600 10.5px var(--font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-decor); border-bottom: 1px solid var(--line-1); }
.rules td { padding: 11px 14px; border-bottom: 1px solid var(--line-0); vertical-align: top; color: var(--ink-mid); }
.rules td:first-child { color: var(--ink-hi); font-weight: 600; white-space: nowrap; }

code { font-family: var(--font-mono); font-size: .86em; color: var(--ink-hi); background: var(--surface-1); padding: 1px 6px; border-radius: 4px; }

/* ---------- Apparitions ----------
   Un seul easing, durées courtes, cascades de 50 ms. Les survols passent par
   `filter: brightness()`, jamais par un changement de teinte. */
.reveal, .hero-enter { opacity: 0; animation: fade-up .7s cubic-bezier(.22,1,.36,1) both; animation-delay: var(--d, 0s); }
@keyframes fade-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* Fondu d'arrivée de page. La doc définit ce mouvement sans s'en servir : il
   relie les pages entre elles au lieu de les faire claquer d'un coup.
   ⚠️ Uniquement de l'OPACITÉ. Une transformation ici ferait de `body` un bloc
   conteneur et la capsule de navigation, qui est en `position: fixed`, se
   mettrait à défiler avec la page. */
body { animation: page-fade-in .4s ease both; }
@keyframes page-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes marquee { to { transform: translateX(-50%); } }
@keyframes hero-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@keyframes hero-scroll-dot { 0% { opacity: 0; transform: translateY(0); } 40% { opacity: 1; } 100% { opacity: 0; transform: translateY(12px); } }
@keyframes patch-hero-rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes patch-hero-line { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* Décalages de cascade en CLASSES et non en `style="--d:…"` : la CSP du site
   est en `style-src 'self'`, un attribut style inline serait purement ignoré.
   Seule /boutique autorise l'inline, pour la caisse Tebex. */
.d1 { --d: .05s; } .d2 { --d: .1s; } .d3 { --d: .15s; } .d4 { --d: .2s; }
.d5 { --d: .25s; } .d6 { --d: .3s; } .d7 { --d: .35s; } .d8 { --d: .4s; }

/* ---------- Accessibilité : le mouvement est coupé si demandé ----------
   Choix assumé du système d'origine, reproduit tel quel. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body { animation: none; }
  .hero-enter, .reveal { opacity: 1; transition: none; animation: none; transform: none; }
  .marquee__track, .hero-wordmark, .hero-scroll__dot,
  .patch-hero__panel, .patch-hero__eyebrow, .patch-hero__title, .patch-hero__summary,
  .patch-hero__entries li, .patch-hero__rule, .patch-hero__actions { animation: none; }
  .hero-wordmark { filter: none; }
}
