/* =====================================================================
   Superviseur Speuz — couche thematique. Chargee APRES style.css.
   Elle ne remplace rien : elle repeint. Trois mecanismes, pas plus.

   1. Chaque vue pose `data-vue` sur <body> et redefinit --accent.
      Tout ce qui s'en sert suit sans le savoir — jusqu'aux courbes,
      puisque `couleurNiveau()` rend la chaine "var(--accent)".
   2. Un fond d'ambiance par vue, pose sur .principal::before/::after :
      hors du flux, sans pointer-events, un seul element. Il ne scrolle
      pas et se moque du DOM rebati toutes les deux secondes.
   3. Un bandeau par vue, construit par bandeaux.js HORS de #vues —
      dedans, ses animations repartiraient de zero a chaque releve.

   Les jetons derives (fond, bord, lueur, halo) sont calcules une fois
   par color-mix : redefinir --accent suffit a deplacer toute la palette.
   ===================================================================== */

/* ------------------------------------------------------- jetons par vue */
body[data-vue]{
  --accent-fond: color-mix(in srgb, var(--accent) 11%, transparent);
  --accent-bord: color-mix(in srgb, var(--accent) 40%, transparent);
  --lueur:       color-mix(in srgb, var(--accent) 32%, transparent);
  --halo:        color-mix(in srgb, var(--accent) 15%, transparent);
  --halo-2:      color-mix(in srgb, var(--accent-2, var(--accent)) 13%, transparent);
  --motif-opacite:1;
}

/* Clair — accents assombris pour tenir le contraste sur fond blanc. */
body[data-vue="apercu"]   { --accent:#0B8C7A; --accent-2:#3B5BDB; }
body[data-vue="systeme"]  { --accent:#6D4AC4; --accent-2:#0E7490; }
body[data-vue="thermique"]{ --accent:#B45309; --accent-2:#BE123C; }
body[data-vue="stockage"] { --accent:#1D4ED8; --accent-2:#0F766E; }
body[data-vue="reseau"]   { --accent:#0369A1; --accent-2:#6D28D9; }
body[data-vue="services"] { --accent:#047857; --accent-2:#1D4ED8; }
body[data-vue="roms"]     { --accent:#BE1568; --accent-2:#0E7490; }
body[data-vue="journal"]  { --accent:#475569; --accent-2:#1D4ED8; }

/* Sombre — la vraie maison. `appliquerTheme()` ecrit toujours data-theme,
   le second selecteur ne sert qu'a survivre a un chargement anticipe. */
html[data-theme="sombre"] body[data-vue="apercu"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="apercu"]   { --accent:#2FD4BC; --accent-2:#7C9BFF; }
html[data-theme="sombre"] body[data-vue="systeme"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="systeme"]  { --accent:#A78BFA; --accent-2:#63E0FF; }
html[data-theme="sombre"] body[data-vue="thermique"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="thermique"]{ --accent:#FF9F45; --accent-2:#FF5470; }
html[data-theme="sombre"] body[data-vue="stockage"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="stockage"] { --accent:#56A8FF; --accent-2:#34E0C8; }
html[data-theme="sombre"] body[data-vue="reseau"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="reseau"]   { --accent:#35DCFF; --accent-2:#A78BFA; }
html[data-theme="sombre"] body[data-vue="services"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="services"] { --accent:#45E39B; --accent-2:#56A8FF; }
html[data-theme="sombre"] body[data-vue="roms"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="roms"]     { --accent:#FF4FA3; --accent-2:#37E8FF; }
html[data-theme="sombre"] body[data-vue="journal"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="journal"]  { --accent:#9DB4C8; --accent-2:#56A8FF; }

/* ---------------------------------------------------- motif de fond par vue
   Tout est en gradients CSS : aucune image, aucun octet a telecharger, et le
   motif suit l'accent puisqu'il est ecrit en color-mix. */
body[data-vue="apercu"]{
  --motif:
    radial-gradient(circle at center, color-mix(in srgb,var(--accent) 26%,transparent) 1px, transparent 1.6px);
  --motif-taille:26px 26px;
  --motif-opacite:.30;
}
body[data-vue="systeme"]{                        /* pistes de circuit imprime */
  --motif:
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 15%,transparent) 0 1px, transparent 1px 64px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 15%,transparent) 0 1px, transparent 1px 64px),
    radial-gradient(circle at center, color-mix(in srgb,var(--accent) 40%,transparent) 1.4px, transparent 2px);
  --motif-taille:64px 64px, 64px 64px, 64px 64px;
  --motif-opacite:.34;
}
body[data-vue="thermique"]{                      /* stries de chaleur */
  --motif:
    repeating-linear-gradient(52deg,
      color-mix(in srgb,var(--accent) 13%,transparent) 0 2px, transparent 2px 22px);
  --motif-taille:auto;
  --motif-opacite:.30;
}
body[data-vue="stockage"]{                       /* plateaux concentriques */
  --motif:
    repeating-radial-gradient(circle at 82% 18%,
      color-mix(in srgb,var(--accent) 14%,transparent) 0 1px, transparent 1px 26px);
  --motif-taille:auto;
  --motif-opacite:.42;
}
body[data-vue="reseau"]{                         /* portee radar */
  --motif:
    repeating-radial-gradient(circle at 50% 120%,
      color-mix(in srgb,var(--accent) 13%,transparent) 0 1px, transparent 1px 58px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 9%,transparent) 0 1px, transparent 1px 120px);
  --motif-taille:auto;
  --motif-opacite:.40;
}
body[data-vue="services"]{                       /* piles de conteneurs */
  --motif:
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 12%,transparent) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 12%,transparent) 0 1px, transparent 1px 78px);
  --motif-taille:78px 34px;
  --motif-opacite:.32;
}
body[data-vue="roms"]{                           /* grille de pixels + balayage */
  --motif:
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent-2) 18%,transparent) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 14%,transparent) 0 1px, transparent 1px 32px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 14%,transparent) 0 1px, transparent 1px 32px);
  --motif-taille:auto, 32px 32px, 32px 32px;
  --motif-opacite:.34;
}
body[data-vue="journal"]{                        /* bande perforee */
  --motif:
    repeating-linear-gradient(0deg, color-mix(in srgb,var(--accent) 16%,transparent) 0 1px, transparent 1px 30px);
  --motif-taille:auto;
  --motif-opacite:.34;
}

/* ------------------------------------------------------------- ambiance */
body{background:var(--fond)}
.principal{position:relative;isolation:isolate}
.principal::before,
.principal::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0}
.principal::before{
  background:var(--motif,none);
  background-size:var(--motif-taille,auto);
  opacity:var(--motif-opacite,1);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 100%);
}
.principal::after{
  background:
    radial-gradient(78% 62% at 8% -14%, var(--halo), transparent 68%),
    radial-gradient(56% 50% at 98% 2%,  var(--halo-2), transparent 70%);
}
header,main{position:relative;z-index:1}

/* --------------------------------------------------------------- chrome */
header{
  background:color-mix(in srgb, var(--carte) 76%, transparent);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
          backdrop-filter:blur(14px) saturate(1.3);
  border-bottom-color:color-mix(in srgb, var(--bord) 80%, var(--accent));
}
header h1{
  font-size:18px;font-weight:700;letter-spacing:-.02em;
  display:flex;align-items:center;gap:10px;
}
header h1::before{                               /* pastille d'accent de la vue */
  content:"";width:7px;height:18px;border-radius:3px;flex:0 0 auto;
  background:linear-gradient(180deg,var(--accent),var(--accent-2,var(--accent)));
  box-shadow:0 0 14px var(--lueur);
}

.rail{
  background:
    linear-gradient(180deg, var(--halo), transparent 34%),
    var(--fond-2);
  border-right-color:color-mix(in srgb, var(--bord) 78%, var(--accent));
}
.marque .logo{
  background:linear-gradient(140deg,var(--accent),var(--accent-2,var(--violet)));
  box-shadow:0 4px 18px var(--lueur), inset 0 1px 0 #fff5;
  border-radius:10px;
}
nav .groupe{display:flex;align-items:center;gap:8px}
nav .groupe::after{
  content:"";flex:1;height:1px;
  background:linear-gradient(90deg,var(--bord),transparent);
}
nav a{transition:background .14s,color .14s,box-shadow .14s,transform .14s}
nav a:hover{transform:translateX(1px)}
nav a.actif{
  background:linear-gradient(90deg,var(--accent-fond),transparent 88%);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--accent) 22%,transparent);
}
nav a.actif svg{opacity:1;filter:drop-shadow(0 0 6px var(--lueur))}
nav a.actif::before{box-shadow:0 0 12px var(--accent);height:22px}

/* ---------------------------------------------------------------- cartes */
.carte{
  border-radius:14px;
  background:
    linear-gradient(180deg, color-mix(in srgb,var(--accent) 5%,transparent), transparent 46%),
    color-mix(in srgb, var(--carte) 92%, transparent);
  box-shadow:var(--ombre);
  transition:border-color .16s, box-shadow .16s, transform .16s;
}
/* Filet d'accent en tete de carte : c'est lui qui fait que huit vues
   n'ont pas la meme carte, sans toucher a une seule regle de mise en page. */
.carte::before{
  content:"";position:absolute;inset:0 0 auto;height:1px;pointer-events:none;
  border-radius:14px 14px 0 0;
  background:linear-gradient(90deg,transparent,var(--accent-bord) 18%,var(--accent-bord) 82%,transparent);
}
.carte:hover{
  border-color:color-mix(in srgb,var(--accent) 26%,var(--bord));
  box-shadow:var(--ombre), 0 0 0 1px color-mix(in srgb,var(--accent) 10%,transparent);
}
.carte.souci{box-shadow:0 0 0 1px var(--crit-fond), 0 0 26px -8px var(--crit), var(--ombre)}
.carte.souci::before{background:linear-gradient(90deg,transparent,var(--crit) 18%,var(--crit) 82%,transparent)}
.carte h3{color:var(--texte-3);letter-spacing:.09em;font-size:10.5px}

/* ---------------------------------------------------------------- vitaux */
.vital{overflow:hidden}
.vital::after{                                   /* halo d'accent en fond */
  content:"";position:absolute;right:-30px;top:-40px;width:150px;height:150px;
  border-radius:50%;background:var(--halo);pointer-events:none;filter:blur(22px);
}
.vital .val{
  position:relative;font-size:33px;letter-spacing:-.045em;margin-top:8px;
  text-shadow:0 0 30px var(--lueur);
}
.vital.ok .val{
  background:linear-gradient(170deg,var(--texte) 22%,color-mix(in srgb,var(--accent) 62%,var(--texte)));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.vital.alerte .val,.vital.critique .val{background:none;-webkit-text-fill-color:currentColor}
.vital.critique{border-color:color-mix(in srgb,var(--crit) 45%,var(--bord))}
.vital.critique::after{background:var(--crit-fond)}
.vital h3{position:relative}
.vital .sub{position:relative}
.vital .spark{position:relative}

/* -------------------------------------------------------------- boutons */
.bouton{border-radius:9px;transition:.14s}
.bouton:hover:not(:disabled){box-shadow:0 0 0 3px var(--accent-fond)}
.bouton.plein{
  background:linear-gradient(180deg,var(--accent),color-mix(in srgb,var(--accent) 78%,#000));
  color:#06110f;box-shadow:0 4px 14px var(--lueur);
}
.segment{border-radius:9px;background:color-mix(in srgb,var(--creux) 70%,transparent)}
.segment button.actif{
  background:var(--carte);color:var(--accent);
  box-shadow:0 1px 3px #0004, inset 0 0 0 1px var(--accent-bord);
}
.pilule{border:1px solid transparent;backdrop-filter:none}
.pilule.ok{border-color:color-mix(in srgb,var(--ok) 28%,transparent)}
.pilule.alerte{border-color:color-mix(in srgb,var(--warn) 34%,transparent)}
.pilule.critique{border-color:color-mix(in srgb,var(--crit) 40%,transparent);box-shadow:0 0 14px -4px var(--crit)}
.pilule.info,.pilule.encours{border-color:var(--accent-bord)}

.sante{border:1px solid transparent;transition:.15s}
.sante.ok{border-color:color-mix(in srgb,var(--ok) 26%,transparent)}
.sante.alerte{border-color:color-mix(in srgb,var(--warn) 34%,transparent)}
.sante.critique{border-color:color-mix(in srgb,var(--crit) 44%,transparent);box-shadow:0 0 18px -6px var(--crit)}
.sante .point{box-shadow:0 0 8px currentColor}

/* -------------------------------------------------------------- tableaux */
.tw{border-radius:11px;background:color-mix(in srgb,var(--carte) 60%,transparent)}
thead th{
  background:color-mix(in srgb,var(--carte-2) 96%,var(--accent));
  border-bottom-color:color-mix(in srgb,var(--bord) 70%,var(--accent));
  backdrop-filter:blur(6px);
}
tbody tr{transition:background .1s}
tbody tr:hover{background:var(--accent-fond)}
tbody tr.choisi{
  background:var(--accent-fond);
  box-shadow:inset 3px 0 0 var(--accent);
}

/* --------------------------------------------------------------- jauges */
.barre{background:color-mix(in srgb,var(--creux) 84%,transparent);box-shadow:inset 0 0 0 1px #0000000f}
.barre i.a{background:linear-gradient(90deg,color-mix(in srgb,var(--accent) 62%,transparent),var(--accent))}
.barre i.w{background:linear-gradient(90deg,color-mix(in srgb,var(--warn) 62%,transparent),var(--warn))}
.barre i.c{background:linear-gradient(90deg,color-mix(in srgb,var(--crit) 62%,transparent),var(--crit))}
.barre i.a,.barre i.w,.barre i.c{box-shadow:0 0 12px -2px currentColor}

.coeur{border-radius:7px;overflow:hidden}
.coeur .jauge{opacity:.3;box-shadow:0 0 12px var(--accent)}
.coeur.chaud .jauge,.coeur.tres-chaud .jauge{opacity:.42}

/* -------------------------------------------------------------- alertes */
.alerte-l{border-radius:11px;transition:transform .14s}
.alerte-l:hover{transform:translateX(2px)}
.alerte-l.critique{box-shadow:inset 3px 0 0 var(--crit), 0 0 24px -12px var(--crit)}
.alerte-l.alerte{box-shadow:inset 3px 0 0 var(--warn)}
.alerte-l .ic{box-shadow:0 0 14px -3px currentColor}
.alerte-l .dom{
  font-size:10px;text-transform:uppercase;letter-spacing:.08em;
  padding:2px 8px;border-radius:100px;border:1px solid var(--bord);
  background:color-mix(in srgb,var(--carte) 70%,transparent);
}
.alerte-l .dom:hover{border-color:var(--accent-bord);color:var(--accent)}

/* ------------------------------------------------------------ graphiques */
.graph svg{filter:drop-shadow(0 2px 10px color-mix(in srgb,var(--accent) 14%,transparent))}
.bulle{border-radius:10px;background:color-mix(in srgb,var(--carte) 94%,transparent);backdrop-filter:blur(8px)}
.legende span{
  padding:2px 9px 2px 7px;border-radius:100px;
  background:color-mix(in srgb,var(--creux) 62%,transparent);
  border:1px solid color-mix(in srgb,var(--bord) 60%,transparent);
}
.legende i{box-shadow:0 0 8px currentColor}

/* ---------------------------------------------------------- divers reglages */
.filtre{border-radius:9px;transition:.14s}
.filtre:focus{box-shadow:0 0 0 3px var(--accent-fond)}
details summary::before{color:var(--accent)}
.meta{font-size:11px;opacity:.9}
::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--bord-fort) 80%,var(--accent))}
::selection{background:var(--accent-bord);color:var(--texte)}

/* =====================================================================
   BANDEAU — l'identite de chaque vue, en tete de page.
   Il vit hors de #vues : le DOM des vues est rebati toutes les deux
   secondes, et une animation rebatie ne s'anime jamais. bandeaux.js ne
   reconstruit ce bloc qu'au changement de vue, et se contente ensuite
   d'ecrire les chiffres dans les puces.
   ===================================================================== */
.bandeau{
  position:relative;overflow:hidden;margin-bottom:16px;
  border:1px solid color-mix(in srgb,var(--accent) 20%,var(--bord));
  border-radius:18px;padding:16px 22px;min-height:112px;
  display:flex;align-items:center;gap:22px;flex-wrap:wrap;
  background:
    radial-gradient(120% 180% at 0% 0%, color-mix(in srgb,var(--accent) 16%,transparent), transparent 58%),
    radial-gradient(90% 160% at 100% 100%, color-mix(in srgb,var(--accent-2,var(--accent)) 13%,transparent), transparent 60%),
    linear-gradient(160deg, var(--carte-2), var(--carte));
  box-shadow:var(--ombre), inset 0 1px 0 color-mix(in srgb,#fff 8%,transparent);
}
.bandeau::before{                                /* trait de neon superieur */
  content:"";position:absolute;inset:0 0 auto;height:2px;
  background:linear-gradient(90deg,transparent,var(--accent) 20%,var(--accent-2,var(--accent)) 70%,transparent);
  opacity:.85;
}
.bandeau::after{                                 /* voile de motif */
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background:var(--motif,none);background-size:var(--motif-taille,auto);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 55%);
          mask-image:linear-gradient(90deg,transparent,#000 55%);
}

.bandeau .art{
  position:relative;z-index:1;flex:0 0 auto;width:104px;height:82px;
  color:var(--accent);
}
.bandeau .art svg{width:100%;height:100%;overflow:visible;display:block}
.bandeau .txt{position:relative;z-index:1;min-width:0;flex:1 1 260px}
.bandeau .kicker{
  font-family:var(--fm);font-size:10px;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--accent);opacity:.95;
  display:flex;align-items:center;gap:8px;
}
.bandeau .kicker::after{
  content:"";flex:0 1 90px;height:1px;
  background:linear-gradient(90deg,var(--accent-bord),transparent);
}
.bandeau h2{
  margin:4px 0 5px;font-size:27px;line-height:1.08;font-weight:800;letter-spacing:-.03em;
  background:linear-gradient(100deg,var(--texte) 8%,var(--accent) 62%,var(--accent-2,var(--accent)));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.bandeau .ligne{
  margin:0;font-size:13px;color:var(--texte-2);max-width:62ch;
}
.bandeau .ligne b{color:var(--texte);font-weight:600;font-variant-numeric:tabular-nums}

.bandeau .chips{
  position:relative;z-index:1;display:flex;gap:10px;flex-wrap:wrap;margin-left:auto;
}
.bandeau .chip{
  min-width:96px;padding:8px 13px 9px;border-radius:12px;
  border:1px solid color-mix(in srgb,var(--accent) 18%,var(--bord));
  background:color-mix(in srgb,var(--carte) 55%,transparent);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
}
.bandeau .chip .n{
  font-family:var(--fm);font-size:19px;font-weight:650;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;line-height:1.15;color:var(--texte);
  white-space:nowrap;
}
.bandeau .chip .n .u{font-size:12px;color:var(--texte-3);margin-left:2px;font-weight:500}
.bandeau .chip .e{
  font-size:10px;text-transform:uppercase;letter-spacing:.1em;color:var(--texte-3);
  margin-top:3px;white-space:nowrap;
}
.bandeau .chip.ok .n{color:var(--ok)}
.bandeau .chip.alerte .n{color:var(--warn)}
.bandeau .chip.alerte{border-color:color-mix(in srgb,var(--warn) 40%,transparent);background:var(--warn-fond)}
.bandeau .chip.critique .n{color:var(--crit)}
.bandeau .chip.critique{border-color:color-mix(in srgb,var(--crit) 45%,transparent);background:var(--crit-fond)}
.bandeau .chip.phare .n{color:var(--accent);text-shadow:0 0 22px var(--lueur)}

/* --------------------------------------------------- animations du dessin */
@keyframes derive     {to{stroke-dashoffset:-260}}
@keyframes battement  {0%,100%{opacity:.35;transform:scale(.85)}50%{opacity:1;transform:scale(1.12)}}
@keyframes balayage   {to{transform:rotate(360deg)}}
@keyframes montee     {0%{transform:translateY(4px);opacity:0}30%{opacity:.9}100%{transform:translateY(-16px);opacity:0}}
@keyframes glissement {to{transform:translateX(-24px)}}
@keyframes clignote   {0%,44%,54%,100%{opacity:1}48%,52%{opacity:.25}}
@keyframes flotte     {0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}

.art .trace{stroke-dasharray:14 10;animation:derive 6s linear infinite}
.art .pouls{transform-origin:center;animation:battement 2.4s ease-in-out infinite}
.art .sweep{transform-origin:50% 50%;animation:balayage 4s linear infinite}
.art .vapeur{animation:montee 3s ease-out infinite}
.art .vapeur:nth-of-type(2){animation-delay:.9s}
.art .vapeur:nth-of-type(3){animation-delay:1.8s}
.art .bande{animation:glissement 1.6s linear infinite}
.art .neon{animation:clignote 3.4s ease-in-out infinite}
.art .flotte{animation:flotte 3s ease-in-out infinite}

/* ------------------------------------------------ variantes par bandeau */
.bandeau[data-vue="thermique"]{
  background:
    radial-gradient(120% 200% at 0% 120%, color-mix(in srgb,var(--accent) 22%,transparent), transparent 55%),
    radial-gradient(80% 150% at 100% -20%, color-mix(in srgb,var(--accent-2) 18%,transparent), transparent 60%),
    linear-gradient(160deg, var(--carte-2), var(--carte));
}
.bandeau[data-vue="reseau"] .art{filter:drop-shadow(0 0 10px var(--lueur))}
.bandeau[data-vue="journal"] h2{background:linear-gradient(100deg,var(--texte),var(--texte-2))
  ;-webkit-background-clip:text;background-clip:text}

/* =====================================================================
   COLLECTION ROMs — la vue arcade. Bandeau-fronton, cartouches, ecrans.
   Le fronton reste sombre dans les deux themes : un fronton d'arcade
   eclaire, c'est du neon sur du noir. Les jetons de texte sont donc
   redefinis a l'interieur, sinon le theme clair y ecrirait en gris.
   ===================================================================== */
.bandeau[data-vue="roms"]{
  --texte:#F6F7FF; --texte-2:#BCC5DC; --texte-3:#8B94AC;
  border-color:color-mix(in srgb,var(--accent) 40%,#000);
  background:
    radial-gradient(110% 190% at 10% 0%,  color-mix(in srgb,var(--accent) 30%,transparent), transparent 56%),
    radial-gradient(95% 170% at 94% 110%, color-mix(in srgb,var(--accent-2) 26%,transparent), transparent 58%),
    linear-gradient(150deg,#1A0C1B 0%, #0C0F1D 62%, #08090F 100%);
  box-shadow:0 18px 44px -22px var(--accent), inset 0 1px 0 #ffffff14;
}
.bandeau[data-vue="roms"]::after{
  opacity:.6;
  -webkit-mask-image:none;mask-image:none;
  background:
    repeating-linear-gradient(0deg, #ffffff10 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 12%,transparent) 0 1px, transparent 1px 34px);
}
.bandeau[data-vue="roms"] h2{
  font-family:var(--fm);font-size:25px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;background:none;color:#fff;-webkit-text-fill-color:#fff;
  text-shadow:
    0 0 5px #ffffffcc,
    0 0 16px var(--accent),
    0 0 42px var(--accent),
    0 0 74px color-mix(in srgb,var(--accent) 55%,transparent);
}
.bandeau[data-vue="roms"] .kicker{color:var(--accent-2);text-shadow:0 0 12px var(--accent-2)}
.bandeau[data-vue="roms"] .chip{
  background:#ffffff0d;border-color:color-mix(in srgb,var(--accent) 26%,#ffffff1a);
}
.bandeau[data-vue="roms"] .chip.phare .n{color:var(--accent-2);text-shadow:0 0 20px var(--accent-2)}

/* ------------------------------------------------------- onglets-boutons */
body[data-vue="roms"] .onglets{
  border-bottom:0;gap:6px;padding:5px;width:max-content;max-width:100%;
  border:1px solid var(--bord);border-radius:13px;
  background:color-mix(in srgb,var(--carte-2) 80%,transparent);
  box-shadow:var(--ombre);
}
body[data-vue="roms"] .onglets button{
  border-radius:9px;margin:0;padding:7px 15px;border-bottom:0;
  font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  transition:.14s;
}
body[data-vue="roms"] .onglets button:hover{background:var(--accent-fond);color:var(--accent)}
body[data-vue="roms"] .onglets button.actif{
  background:linear-gradient(180deg,var(--accent),color-mix(in srgb,var(--accent) 72%,#000));
  color:#12040d;box-shadow:0 5px 18px -6px var(--accent), inset 0 1px 0 #ffffff55;
}
body[data-vue="roms"] .onglets button.actif .cpt{background:#00000026;color:#12040d}

/* ----------------------------------------------------------- cartouches
   Une tuile de systeme est dessinee comme une cartouche : bandeau de
   couleur du constructeur en tete, contacts dores en pied. La couleur
   vient de `data-marque`, pose par app.js — pas d'une liste en dur ici. */
.systemes{gap:10px;grid-template-columns:repeat(auto-fill,minmax(168px,1fr))}
.sys{
  position:relative;overflow:hidden;border-radius:11px 11px 5px 5px;
  padding:14px 13px 15px;
  background:
    linear-gradient(180deg, color-mix(in srgb,var(--marque,var(--accent)) 14%,transparent), transparent 62%),
    var(--carte-2);
  transition:transform .15s, box-shadow .15s, border-color .15s, background .15s;
}
.sys::before{
  content:"";position:absolute;inset:0 0 auto;height:5px;
  background:linear-gradient(90deg,var(--marque,var(--accent)),color-mix(in srgb,var(--marque,var(--accent)) 45%,transparent));
}
.sys::after{                                     /* contacts de la cartouche */
  content:"";position:absolute;inset:auto 12px 0 12px;height:4px;opacity:.32;
  background:repeating-linear-gradient(90deg,
    color-mix(in srgb,var(--marque,var(--accent)) 70%,transparent) 0 4px, transparent 4px 9px);
}
.sys b{font-size:14px;letter-spacing:.01em}
.sys span{font-size:11px;opacity:.85}
.sys:hover{
  transform:translateY(-3px);
  border-color:color-mix(in srgb,var(--marque,var(--accent)) 55%,transparent);
  box-shadow:0 14px 26px -16px var(--marque,var(--accent)), 0 0 0 1px color-mix(in srgb,var(--marque,var(--accent)) 22%,transparent);
}
.sys.actif{
  border-color:var(--marque,var(--accent));
  background:
    linear-gradient(180deg, color-mix(in srgb,var(--marque,var(--accent)) 26%,transparent), transparent 70%),
    var(--carte-2);
  box-shadow:0 0 0 1px var(--marque,var(--accent)), 0 12px 28px -18px var(--marque,var(--accent));
}
.sys.actif::after{opacity:.7}

/* Couleurs de constructeur. Elles ne servent qu'a se reperer d'un coup
   d'oeil dans 66 tuiles : ce sont les couleurs de boitier, pas des etats. */
[data-marque="nintendo"] {--marque:#E4353F}
[data-marque="sega"]     {--marque:#3B82F6}
[data-marque="sony"]     {--marque:#9AA6C8}
[data-marque="atari"]    {--marque:#F0724A}
[data-marque="nec"]      {--marque:#F5A524}
[data-marque="snk"]      {--marque:#EFCB4B}
[data-marque="microsoft"]{--marque:#6FD44F}
[data-marque="commodore"]{--marque:#9A7BE8}
[data-marque="arcade"]   {--marque:#FF4FA3}
[data-marque="micro"]    {--marque:#4FD8CE}
[data-marque="autre"]    {--marque:#7C8D98}

.grille-sys{
  -webkit-mask-image:linear-gradient(180deg,#000 0 88%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 0 88%,transparent 100%);
}

/* -------------------------------------------------------------- ecrans
   Les captures sont des ecrans, pas des images : cadre noir, halo, et
   un voile de lignes horizontales pose sur la cellule (pas sur l'image,
   qui n'a pas de conteneur a elle). */
td.vign{position:relative}
td.vign::after{
  content:"";position:absolute;inset:5px 8px;pointer-events:none;border-radius:5px;
  background:repeating-linear-gradient(0deg, #00000024 0 1px, transparent 1px 3px);
  opacity:.55;
}
.vignette{
  border-radius:5px;border-color:color-mix(in srgb,var(--bord) 70%,#000);
  background:#05070a;
  box-shadow:inset 0 0 26px #000000a6, 0 2px 8px #00000059;
  transition:transform .16s, box-shadow .16s, border-color .16s;
}
.vignette:hover{
  transform:scale(1.04);border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent), 0 10px 26px -10px var(--accent), inset 0 0 26px #0009;
}
.grande-vignette{
  box-shadow:0 0 0 1px color-mix(in srgb,var(--accent) 30%,transparent), 0 30px 70px -30px var(--accent), inset 0 0 60px #000a;
  background:#05070a;
}

/* ------------------------------------------------------- barre de selection */
.barre-sel{
  border-radius:12px;
  background:linear-gradient(180deg, color-mix(in srgb,var(--accent) 16%,transparent), color-mix(in srgb,var(--carte) 82%,transparent));
  border-color:var(--accent-bord);
  box-shadow:0 -8px 26px -18px var(--accent), var(--ombre-forte);
}
.alpha button{border-radius:6px;font-weight:600}
.alpha button:hover:not(:disabled){background:var(--accent-fond);box-shadow:0 0 0 1px var(--accent-bord)}

/* --------------------------------------------------- icones des controles */
.carte[data-ctrl] h3::before{
  content:"";width:14px;height:14px;flex:0 0 auto;background:var(--accent);
  -webkit-mask:var(--ic) center/contain no-repeat;mask:var(--ic) center/contain no-repeat;
}
.carte[data-ctrl="liens"]{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M9.5 14.5l5-5M10.5 6.6l1.8-1.8a4 4 0 015.7 5.7l-1.8 1.8M7.8 12.7l-1.8 1.8a4 4 0 105.7 5.7l1.8-1.8'/%3E%3C/svg%3E")}
.carte[data-ctrl="m3u"]{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M3 6h11M3 12h11M3 18h7'/%3E%3Cpath d='M17 8l5 4-5 4z' fill='%23000'/%3E%3C/svg%3E")}
.carte[data-ctrl="tsv"]{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Crect x='3' y='4' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M10 10v10'/%3E%3C/svg%3E")}
.carte[data-ctrl="multidisc"]{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Ccircle cx='9' cy='12' r='6.4'/%3E%3Ccircle cx='15' cy='12' r='6.4'/%3E%3C/svg%3E")}
.carte[data-ctrl="systemes"]{--ic:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Crect x='2' y='6' width='20' height='12' rx='5'/%3E%3Cpath d='M6.5 10.5v3M5 12h3M16 11h.01M18.5 13.5h.01'/%3E%3C/svg%3E")}

/* =====================================================================
   Touches propres a chaque autre vue. Rien de structurel : la palette
   fait deja l'essentiel du travail, on n'ajoute ici que ce qui parle
   du sujet traite.
   ===================================================================== */

/* --- Systeme : la grille des coeurs se lit comme un die de processeur. */
body[data-vue="systeme"] .coeurs{gap:5px}
body[data-vue="systeme"] .coeur{
  background:linear-gradient(180deg,var(--creux),color-mix(in srgb,var(--accent) 6%,var(--creux)));
  border-color:color-mix(in srgb,var(--accent) 16%,var(--bord));
}
body[data-vue="systeme"] .coeur .jauge{box-shadow:0 0 16px var(--accent)}

/* --- Thermique : le chiffre chauffe avec la mesure. */
body[data-vue="thermique"] .vital.ok .val{
  background:linear-gradient(170deg,var(--texte) 10%,var(--accent) 95%);
  -webkit-background-clip:text;background-clip:text;
}
body[data-vue="thermique"] .barre i.a{
  background:linear-gradient(90deg,#F0B429,var(--accent))
}
body[data-vue="thermique"] .carte:hover{box-shadow:var(--ombre),0 0 34px -18px var(--accent)}

/* --- Stockage : jauges plus epaisses, on y lit un remplissage. */
body[data-vue="stockage"] .barre{height:9px;border-radius:6px}
body[data-vue="stockage"] .barre i{border-radius:6px}

/* --- Reseau : les cartes portent une lueur de porteuse. */
body[data-vue="reseau"] .carte::before{
  height:2px;
  background:linear-gradient(90deg,transparent,var(--accent) 30%,var(--accent-2) 60%,transparent);
  opacity:.5;
}

/* --- Services : chaque ligne de conteneur porte son quai. */
body[data-vue="services"] tbody tr:hover{box-shadow:inset 3px 0 0 var(--accent)}

/* --- Journal : une console, pas un tableau. */
body[data-vue="journal"] .journal{border-radius:11px}
body[data-vue="journal"] .journal .e{
  font-family:var(--fm);font-size:12px;transition:background .1s;
}
body[data-vue="journal"] .journal .e:hover{background:var(--carte-2)}
body[data-vue="journal"] .journal .e .n{box-shadow:0 0 8px currentColor}
body[data-vue="journal"] .journal .e.critique{box-shadow:inset 3px 0 0 var(--crit)}
body[data-vue="journal"] .journal .e.alerte{box-shadow:inset 3px 0 0 var(--warn)}

/* --------------------------------------------------------------- modale */
.modale{border-radius:16px;box-shadow:0 40px 90px -30px #000, var(--ombre-forte)}
.modale > header{
  background:
    linear-gradient(90deg,var(--accent-fond),transparent 70%),
    var(--carte-2);
}
.voile{background:#000c;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}

/* ------------------------------------------------------------ mouvement */
.vue.neuve{animation:entre .26s cubic-bezier(.22,.9,.3,1)}
@media (prefers-reduced-motion: reduce){
  .art .trace,.art .pouls,.art .sweep,.art .vapeur,.art .bande,.art .neon,.art .flotte,
  .vue.neuve,nav a .pastille.critique,.sante.critique .point{animation:none !important}
  *{transition-duration:.01ms !important}
}

/* ------------------------------------------------------------ etroitesse */
@media(max-width:1100px){
  .bandeau .chips{margin-left:0;width:100%}
}
@media(max-width:820px){
  .bandeau{padding:14px 16px;gap:14px}
  .bandeau .art{display:none}
  .bandeau h2{font-size:22px}
}

/* La tuile-cartouche est plus haute que l'ancienne : sans ce recalage, la
   grille repliable ne montrait plus que trois rangees au lieu de quatre. */
.grille-sys{max-height:352px}

/* Reflet lent qui traverse le bandeau. Il ne survit qu'a cet endroit : le
   bandeau n'est pas rebati a chaque releve, contrairement aux vues. */
.bandeau .lustre{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background:linear-gradient(104deg,transparent 34%,#ffffff14 46%,#ffffff05 52%,transparent 64%);
  animation:lustre 13s ease-in-out infinite;
}
@keyframes lustre{0%,68%{transform:translateX(-130%)}100%{transform:translateX(130%)}}

/* Le neon respire. Deux etats, pas de scintillement : un fronton qui clignote
   fatigue en dix secondes, un fronton qui respire se remarque a peine. */
@keyframes neon-respire{
  0%,100%{text-shadow:0 0 5px #ffffffcc,0 0 16px var(--accent),0 0 42px var(--accent),
                      0 0 74px color-mix(in srgb,var(--accent) 55%,transparent)}
  50%    {text-shadow:0 0 4px #ffffff99,0 0 12px var(--accent),0 0 30px var(--accent),
                      0 0 52px color-mix(in srgb,var(--accent) 38%,transparent)}
}
.bandeau[data-vue="roms"] h2{animation:neon-respire 5s ease-in-out infinite}

/* Un bandeau sans definition reste cache : `.bandeau` est en display:flex,
   qui gagnerait sur l'attribut `hidden` du navigateur. */
.bandeau[hidden]{display:none}

@media (prefers-reduced-motion: reduce){
  .bandeau .lustre,.bandeau[data-vue="roms"] h2{animation:none !important}
}

/* Le rail replie : `nav .groupe` reprend ici son display:none. La regle
   d'origine vit dans une media query de style.css, et la mienne — posee
   plus tard, a specificite egale — la couvrait : les intitules de groupe
   debordaient du rail a 64 px. */
@media(max-width:940px){
  nav .groupe{display:none}
  .bandeau{padding:14px 16px}
}

/* =====================================================================
   GALERIE DE JAQUETTES — l'autre affichage de l'onglet Parcourir.

   Le cadre est fixe, l'image est `contain` dedans : les jaquettes n'ont
   pas de format commun (0,54 pour une boîte 3D, 1,85 pour une boîte
   SNES — mesuré le 2026-08-22), et une tuile au format fixe rognerait
   forcément l'une ou l'autre. Le fond noir du cadre fait le reste.
   ===================================================================== */
.galerie{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--jaq,174px),1fr));
  gap:16px;margin-top:12px;padding:14px;overflow-y:auto;
  max-height:calc(100vh - 372px);min-height:320px;
  border:1px solid var(--bord);border-radius:14px;
  background:
    radial-gradient(120% 60% at 50% 0%, color-mix(in srgb,var(--accent) 7%,transparent), transparent 70%),
    color-mix(in srgb,var(--creux) 60%,transparent);
}

.jaq{
  position:relative;min-width:0;border-radius:11px;
  transition:transform .16s cubic-bezier(.22,.9,.3,1), filter .16s;
}
.jaq:hover{transform:translateY(-5px)}

/* L'écran : cadre noir, l'image dedans, tout le reste par-dessus. */
.jaq .ecran{
  position:relative;aspect-ratio:3/4;overflow:hidden;cursor:zoom-in;
  border-radius:10px;background:#05070a;
  border:1px solid color-mix(in srgb,var(--bord) 70%,#000);
  box-shadow:inset 0 0 34px #000000b3, 0 6px 16px -8px #000000a6;
  display:grid;place-items:center;
  transition:box-shadow .16s, border-color .16s;
}
.jaq:hover .ecran{
  border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent), 0 18px 36px -18px var(--accent), inset 0 0 34px #000000b3;
}
.jaq .jaquette{width:100%;height:100%;object-fit:contain;display:block}
/* `pixelated` UNIQUEMENT sur les captures : elles font 320x240 natifs et le
   lissage les transforme en bouillie. Une jaquette scannée fait 680 px de
   large — la même règle la rendrait crénelée. */
.galerie.pixel .jaquette{image-rendering:pixelated}

/* Reflet de vitrine, et voile de lignes : la tuile est un écran, pas une
   vignette de catalogue. */
.jaq .ecran::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:9px;
  background:linear-gradient(196deg,#ffffff12 0 18%,transparent 42%);
}
/* Les lignes de balayage ne se posent QUE sur les captures. Une jaquette est
   un carton imprimé, pas un écran : la voiler de scanlines la salit sans rien
   raconter, et ça se voit sur un scan de 680 px. */
.galerie.pixel .jaq .ecran::after{
  background:
    linear-gradient(196deg,#ffffff12 0 18%,transparent 42%),
    repeating-linear-gradient(0deg,#00000026 0 1px,transparent 1px 3px);
}

/* Pas d'image de ce type : l'initiale, pas une icône cassée. */
.jaq .initiale{
  position:absolute;font-family:var(--fm);font-size:calc(var(--jaq,174px) * .34);
  font-weight:700;color:color-mix(in srgb,var(--accent) 34%,transparent);
  text-shadow:0 0 30px var(--lueur);display:none;user-select:none;
}
/* Une <img> sans `src` garde le petit cadre casse du navigateur dans le
   coin : c'est ce qu'on voulait eviter en basculant sur l'initiale. */
.jaq.sans .jaquette{display:none}
.jaq.sans .initiale{display:block}
.jaq.sans .ecran{background:linear-gradient(160deg,#0b0d14,#05070a)}

/* Le nom de fichier — l'identité réelle — révélé au survol. En absolu :
   l'afficher en permanence ajouterait une ligne à 729 tuiles, et le titre
   de la gamelist suffit à reconnaître un jeu. */
.jaq .fichier{
  position:absolute;left:0;right:0;bottom:0;padding:14px 8px 6px;
  font-family:var(--fm);font-size:10.5px;line-height:1.3;color:#E8EDF5;
  background:linear-gradient(0deg,#000000e6 30%,transparent);
  opacity:0;transform:translateY(6px);transition:.16s;
  word-break:break-all;max-height:4.6em;overflow:hidden;
}
.jaq:hover .fichier{opacity:1;transform:none}

.jaq .badges{position:absolute;top:6px;left:6px;display:flex;flex-wrap:wrap;gap:4px;max-width:calc(100% - 40px)}
.jaq .bg{
  font-size:9.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  padding:2px 6px;border-radius:5px;color:#0a0d12;background:var(--accent);
  box-shadow:0 2px 8px #0009;
}
.jaq .bg.fav{background:#F5C542;font-size:11px;padding:1px 6px;letter-spacing:0}
.jaq .bg.mauvais{background:var(--crit);color:var(--sur-plein,#fff)}

.jaq .note-jaq{
  position:absolute;right:6px;bottom:6px;font-family:var(--fm);font-size:11px;
  font-weight:650;padding:2px 7px;border-radius:100px;color:var(--texte);
  background:#000000a6;border:1px solid #ffffff26;
}

.jaq .pick{
  position:absolute;top:7px;right:7px;width:18px;height:18px;z-index:2;
  box-shadow:0 2px 10px #000c;border-radius:4px;
}
.jaq .pick:disabled{opacity:.3}

.jaq.choisi .ecran{
  border-color:var(--accent);
  box-shadow:0 0 0 2px var(--accent), 0 14px 30px -16px var(--accent), inset 0 0 34px #000000b3;
}
.jaq.choisi .lg b{color:var(--accent)}
.jaq.bloque{filter:saturate(.35) brightness(.82)}
.jaq.bloque:hover{filter:none}

.jaq .lg{padding:8px 3px 0;min-width:0}
.jaq .lg b{
  display:block;font-size:12.5px;font-weight:600;line-height:1.28;color:var(--texte);
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;
}
.jaq .lg span{
  display:block;margin-top:2px;font-family:var(--fm);font-size:10.5px;
  color:var(--texte-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

@media (prefers-reduced-motion: reduce){
  .jaq:hover{transform:none}
}

/* Message bref, en bas à droite. Il vit hors du DOM des vues — comme le
   bandeau et la modale — parce qu'un rendu le détruirait à l'instant même
   où il apparaît. */
.signal{
  position:fixed;right:20px;bottom:20px;z-index:60;max-width:min(90vw,420px);
  display:flex;align-items:center;gap:9px;padding:11px 15px;
  border-radius:12px;font-size:13px;font-weight:550;
  color:var(--texte);background:color-mix(in srgb,var(--carte) 92%,transparent);
  border:1px solid var(--accent-bord);
  box-shadow:var(--ombre-forte), 0 0 30px -14px var(--accent);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity .2s, transform .2s;
}
.signal.vu{opacity:1;transform:none}
.signal .point{
  width:8px;height:8px;border-radius:50%;flex:0 0 auto;background:var(--accent);
  box-shadow:0 0 10px var(--accent);
}
@media (prefers-reduced-motion: reduce){ .signal{transition:none} }

/* ============================================================ pages de jeu

   Chaque serveur a sa teinte, prise dans l'identite visuelle du jeu, et non
   dans la palette de supervision : passer de « Stockage » a « Palworld » doit
   se voir avant meme de lire le titre. Meme mecanique que les vues du haut de
   ce fichier — `body[data-vue]` redefinit --accent, tout le reste suit.        */

body[data-vue="jeu-palworld"]    { --accent:#0E7C86; --accent-2:#D97706; }
body[data-vue="jeu-ark"]         { --accent:#B45309; --accent-2:#15803D; }
body[data-vue="jeu-valheim"]     { --accent:#1E5F8C; --accent-2:#8A5A2B; }
body[data-vue="jeu-terraria"]  { --accent:#7B1FA2; --accent-2:#2E7D32; }
body[data-vue="jeu-core-keeper"] { --accent:#A16207; --accent-2:#5B21B6; }
body[data-vue="jeu-necesse"]     { --accent:#3730A3; --accent-2:#A16207; }
body[data-vue="jeu-minecraft"]   { --accent:#3B7A2A; --accent-2:#7A5230; }

html[data-theme="sombre"] body[data-vue="jeu-palworld"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-palworld"]
  { --accent:#3AD8E6; --accent-2:#FFB347; }
html[data-theme="sombre"] body[data-vue="jeu-ark"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-ark"]
  { --accent:#FFA94D; --accent-2:#6EE7A8; }
html[data-theme="sombre"] body[data-vue="jeu-valheim"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-valheim"]
  { --accent:#5FB2E8; --accent-2:#D9A15B; }
html[data-theme="sombre"] body[data-vue="jeu-terraria"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-terraria"]
  { --accent:#C77DFF; --accent-2:#6FD86F; }
html[data-theme="sombre"] body[data-vue="jeu-core-keeper"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-core-keeper"]
  { --accent:#FBBF24; --accent-2:#A78BFA; }
html[data-theme="sombre"] body[data-vue="jeu-necesse"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-necesse"]
  { --accent:#8B93FF; --accent-2:#F4C15D; }
html[data-theme="sombre"] body[data-vue="jeu-minecraft"],
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-minecraft"]
  { --accent:#7BC96F; --accent-2:#C9915C; }

/* Les neuf elements de Palworld. Les teintes suivent celles du jeu ; le fond
   est la meme couleur a 18 % pour rester lisible sur les deux themes.        */
.pilule.el-normal      { background:#8A93A622; color:#8A93A6; }
.pilule.el-fire        { background:#E2542722; color:#E25427; }
.pilule.el-water       { background:#2A8FE022; color:#2A8FE0; }
.pilule.el-leaf        { background:#3FA34022; color:#3FA340; }
.pilule.el-electricity { background:#D9A70622; color:#B98B05; }
.pilule.el-ice         { background:#38B6C822; color:#2A93A3; }
.pilule.el-earth       { background:#A0703022; color:#8A5F28; }
.pilule.el-dark        { background:#7B4FB022; color:#7B4FB0; }
.pilule.el-dragon      { background:#C2418C22; color:#C2418C; }

html[data-theme="sombre"] .pilule.el-normal,
html:not([data-theme="clair"]) body.auto-sombre .pilule.el-normal      { color:#AAB4C6; }
html[data-theme="sombre"] .pilule.el-electricity,
html:not([data-theme="clair"]) body.auto-sombre .pilule.el-electricity { color:#F2C93B; }
html[data-theme="sombre"] .pilule.el-ice,
html:not([data-theme="clair"]) body.auto-sombre .pilule.el-ice         { color:#5FD8E8; }
html[data-theme="sombre"] .pilule.el-earth,
html:not([data-theme="clair"]) body.auto-sombre .pilule.el-earth       { color:#C79A5E; }
html[data-theme="sombre"] .pilule.el-dark,
html:not([data-theme="clair"]) body.auto-sombre .pilule.el-dark        { color:#A98BE0; }

/* ---------------------------------------------------------------------
 * GEOMETRIE ET TRAME PAR JEU
 *
 * Chaque page de jeu porte deja son accent (lignes 843-870) ; elle porte
 * desormais aussi son rayon et sa trame de fond. Les rayons passent par des
 * jetons pour qu'une vue puisse les redefinir d'un bloc : Minecraft est
 * carre, Palworld genereusement arrondi, et les cinq autres s'echelonnent
 * entre les deux. Les valeurs de `:root` sont celles qui etaient codees en
 * dur avant ce bloc — hors page de jeu, rien ne bouge d'un pixel.
 *
 * La trame est un gradient CSS derive de l'accent : aucune image, aucun
 * telechargement. `.principal::before` la peint et la masque a 62 % de la
 * hauteur, elle est donc franche en haut de page et absente en bas.
 * --------------------------------------------------------------------- */
:root{ --r-carte:14px; --r-bouton:9px; --r-tw:11px; --r-modale:16px }
.carte        { border-radius:var(--r-carte) }
.carte::before{ border-radius:var(--r-carte) var(--r-carte) 0 0 }
.bouton       { border-radius:var(--r-bouton) }
.segment      { border-radius:var(--r-bouton) }
.filtre       { border-radius:var(--r-bouton) }
.tw           { border-radius:var(--r-tw) }
.alerte-l     { border-radius:var(--r-tw) }
.bulle        { border-radius:calc(var(--r-tw) - 1px) }
.coeur        { border-radius:calc(var(--r-bouton) - 2px) }
.modale       { border-radius:var(--r-modale) }
.barre-sel    { border-radius:calc(var(--r-modale) - 4px) }

body[data-vue="jeu-palworld"]{
  --r-carte:18px;
  --r-bouton:14px;
  --r-tw:14px;
  --r-modale:20px;
  --motif:
    radial-gradient(circle at 50% 50%, color-mix(in srgb,var(--accent-2) 34%,transparent) 0 1.6px, transparent 2px),
    radial-gradient(circle at 50% 50%, transparent 7px, color-mix(in srgb,var(--accent) 26%,transparent) 7px 8.2px, transparent 9px);
  --motif-taille:44px 44px, 44px 44px;
  --motif-opacite:.34;
}
body[data-vue="jeu-ark"]{
  --r-carte:5px;
  --r-bouton:5px;
  --r-tw:5px;
  --r-modale:6px;
  --motif:
    repeating-linear-gradient(174deg,
      color-mix(in srgb,var(--accent) 15%,transparent) 0 2px,
      transparent 2px 9px,
      color-mix(in srgb,var(--accent-2) 10%,transparent) 9px 10px,
      transparent 10px 26px);
  --motif-taille:auto;
  --motif-opacite:.4;
}
body[data-vue="jeu-valheim"]{
  --r-carte:3px;
  --r-bouton:3px;
  --r-tw:3px;
  --r-modale:4px;
  --motif:
    repeating-linear-gradient(45deg,  color-mix(in srgb,var(--accent) 14%,transparent) 0 1.2px, transparent 1.2px 18px),
    repeating-linear-gradient(-45deg, color-mix(in srgb,var(--accent-2) 12%,transparent) 0 1.2px, transparent 1.2px 18px);
  --motif-taille:auto;
  --motif-opacite:.44;
}
body[data-vue="jeu-terraria"]{
  --r-carte:4px;
  --r-bouton:4px;
  --r-tw:4px;
  --r-modale:4px;
  --motif:
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 11%,transparent) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 11%,transparent) 0 1px, transparent 1px 4px),
    radial-gradient(circle at 30% 70%, color-mix(in srgb,var(--accent-2) 28%,transparent) 0 1.4px, transparent 2px);
  --motif-taille:auto, auto, 24px 24px;
  --motif-opacite:.36;
}
body[data-vue="jeu-core-keeper"]{
  --r-carte:13px;
  --r-bouton:11px;
  --r-tw:12px;
  --r-modale:15px;
  --motif:
    radial-gradient(circle at 20% 30%, color-mix(in srgb,var(--accent) 42%,transparent) 0 1.8px, transparent 2.4px),
    radial-gradient(circle at 70% 80%, color-mix(in srgb,var(--accent-2) 36%,transparent) 0 1.4px, transparent 2px),
    radial-gradient(circle at 46% 8%,  color-mix(in srgb,var(--accent) 24%,transparent) 0 1.1px, transparent 1.6px);
  --motif-taille:58px 58px, 74px 74px, 39px 39px;
  --motif-opacite:.5;
}
body[data-vue="jeu-necesse"]{
  --r-carte:9px;
  --r-bouton:8px;
  --r-tw:9px;
  --r-modale:10px;
  --motif:
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 13%,transparent) 0 1px, transparent 1px 27px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent-2) 9%,transparent) 0 1px, transparent 1px 27px);
  --motif-taille:auto;
  --motif-opacite:.3;
}
body[data-vue="jeu-minecraft"]{
  --r-carte:0px;
  --r-bouton:0px;
  --r-tw:0px;
  --r-modale:0px;
  --motif:
    repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent-2) 11%,transparent) 0 1px, transparent 1px 16px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent-2) 11%,transparent) 0 1px, transparent 1px 16px),
    conic-gradient(from 90deg at 50% 50%,
      color-mix(in srgb,var(--accent) 13%,transparent) 0 25%, transparent 0 50%,
      color-mix(in srgb,var(--accent) 13%,transparent) 0 75%, transparent 0);
  --motif-taille:auto, auto, 64px 64px;
  --motif-opacite:.46;
}

/* ---------------------------------------------------------------------
 * CALQUE D'AMBIANCE DES PAGES DE JEU
 *
 * Une page de jeu peut porter une image de fond. Elle est posee sur `.app`,
 * donc sur TOUTE la fenetre, rail et en-tete compris : posee sur
 * `.principal`, une bande opaque de 236 px coupait l'image en deux. Les deux
 * pseudo-elements de `.principal` (trame et halos d'accent) restent ou ils
 * sont et se posent par-dessus. `.app` ne defile pas — c'est `main` qui
 * defile a l'interieur — donc l'image tient le cadre sans
 * `background-attachment`.
 *
 * ⚠ LA MECANIQUE VAUT POUR LES SEPT JEUX, L'IMAGE POUR CEUX QUI EN ONT UNE.
 * Un seul jeton la porte : --calque. Sans lui, `background-image` reference
 * une variable indefinie, la propriete entiere devient invalide et retombe a
 * `none` — le jeu n'a pas de fond, et tout le reste (verre, rail, en-tete,
 * encres) s'applique quand meme. Donner un fond a un jeu = UNE ligne, son
 * --calque, dans chacun des deux themes.
 *
 * Les reglages, tous portes par `.app` et donc herites par tout ce qui est
 * dessous : le voile (--voile-h en haut, --voile-b en bas), quatre opacites
 * de surface (--verre-op les cartes, --verre-creux les tuiles, --verre-rail
 * le rail, --verre-entete l'en-tete) et le filtre d'arriere-plan
 * (--verre-lumi, --verre-sat).
 *
 * ⚠ AUCUN FLOU. C'etait un `blur(14px)` au premier jet, pour aplatir le
 * contraste local de la photo avant qu'elle n'arrive sous les lettres. Mais
 * la constellation de l'image — noeuds et traits d'un ou deux pixels — est
 * exactement ce qu'un flou de 14 px efface : meme a 34 % d'opacite elle
 * restait invisible. C'etait le flou qu'il fallait retirer, pas l'opacite
 * qu'il fallait baisser. Retenir : sur un calque photo, le flou coute le
 * DETAIL et ne rend presque rien en lisibilite — ce sont les opacites et
 * brightness() qui la rendent. Ne pas le reintroduire.
 *
 * ⚠ LES DEUX THEMES SONT DEUX PROBLEMES DIFFERENTS, PAS DEUX INTENSITES.
 * En sombre, texte clair sur image sombre : le verre peut disparaitre
 * completement (opacites a 0), il suffit d'assombrir ce qui passe dessous
 * (brightness .32) et de resaturer (1.5) ce que la luminosite retire.
 * En clair, texte sombre sur image claire, l'inverse ne marche PAS : mesure
 * a l'appui, a 50 % d'opacite le titre a l'accent tombe a 1,75:1, parce que
 * l'accent de Palworld EST le turquoise de l'image. Deux consequences :
 *   · le verre ECLAIRCIT (1.35) et DESATURE (.45) — c'est la desaturation
 *     qui separe l'encre turquoise du fond turquoise, pas l'opacite ;
 *   · les encres sont recalees plus bas (voir ci-dessous), ce qui permet de
 *     descendre les cartes a 58 % au lieu de 82 %.
 *
 * ⚠ TROIS ENCRES SONT RECALEES sur `.app`, donc sur la page de jeu seule :
 * --texte-3 dans les deux themes, --accent et --ok en clair. Ce sont les
 * trois jetons du systeme sans marge (--texte-3 vaut 4,00:1 en sombre et
 * 2,94 a 3,41:1 en clair sur la page NUE, deja sous le seuil AA de 4,5 ;
 * --ok des pastilles est a 3,70). Sans recalage le calque les faisait
 * tomber a 2,53 / 1,91 / 2,26.
 *
 * Mesure : contraste sous CHAQUE noeud de texte de la page, pire pixel de
 * l'image sous le rectangle des glyphes (Range.getClientRects, pas la boite
 * de l'element — une ligne de `<summary>` occupe toute la largeur, son texte
 * non), en composant toute la chaine des fonds traversee, filtre du verre
 * compris (matrice CSS `saturate()`, en sRGB). Onglet Apercu :
 *   sombre  pire noeud 5,36:1   aucun sous 4,5   (page nue : 4,00)
 *   clair   pire noeud 3,30:1   aucun sous 3     (page nue : 2,94)
 * Sur les autres onglets le calque AMELIORE le compte en clair — Passifs
 * 140 noeuds sous 4,5 sans lui, 100 avec — parce que --texte-3 y gagne plus
 * que le fond ne lui coute. Les pastilles d'element du Paldeck restent le
 * point faible du theme clair : 60 noeuds sous 3:1 SANS calque, 52 avec.
 * C'est un defaut de la charte, pas du calque.
 * --------------------------------------------------------------------- */
body[data-vue^="jeu-"] .app{
  --voile-h:8%; --voile-b:26%;                         /* clair */
  --verre-op:58%; --verre-creux:0%; --verre-rail:62%; --verre-entete:62%;
  --verre-onglets:92%;                 /* la barre collante, voir plus bas */
  --verre-lumi:1.15; --verre-sat:.95;
  --creux:color-mix(in srgb, var(--creux-pur) var(--verre-creux), transparent);
  background-image:
    linear-gradient(180deg,
      color-mix(in srgb, var(--fond) calc(var(--voile-h) + 8%), transparent) 0,
      color-mix(in srgb, var(--fond) var(--voile-h), transparent) 38%,
      color-mix(in srgb, var(--fond) var(--voile-b), transparent) 100%),
    var(--calque);
  background-size:cover;
  background-position:50% 38%;
  background-repeat:no-repeat;
}
/* Les encres du verre, CLAIR SEUL — et il faut vraiment un selecteur propre
   au clair, pas la regle de base. Un jeton pose dans la regle de base ne
   redevient PAS lui-meme dans le theme sombre : il y fuit, parce que la regle
   sombre n'ecrase que ce qu'elle redeclare. Mis dans la base, --accent
   teintait aussi le sombre — encre foncee sur fond noir, 1,01:1 sur
   128 noeuds, sur des onglets qu'aucune capture d'ecran de l'Apercu ne montre.

   ⚠ ET --accent NE SE MET PAS ICI NON PLUS : il vaut une couleur PAR JEU.
   Ecrit dans cette regle commune, il donnait le turquoise de Palworld a ARK,
   Valheim et les quatre autres — l'identite par jeu, tout le sujet de
   `theme.css` lignes 843-870, effacee en theme clair. Il est donc recale
   jeu par jeu, plus bas, avec le calque de chacun. --texte-3 et --ok, eux,
   ne dependent pas du jeu et restent ici. */
html[data-theme="clair"] body[data-vue^="jeu-"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue^="jeu-"] .app{
  /* --texte-2 et --warn ont rejoint la liste le 26 aout, quand Terraria et
     Valheim ont montre ce que la mesure precedente cachait : ces deux-la
     portaient a eux seuls 7 des 8 echecs de la page (les noms de jeux du rail
     et la pastille « arrete »). Comme --texte-3 et --ok, ils ne dependent pas
     du jeu et se recalent donc ici. Ce sont des ENCRES SUR FOND CLAIR : les
     assombrir ne peut qu'ameliorer, y compris chez les jeux qui passaient. */
  --texte-3:#232C33; --ok:#08432A; --texte-2:#1F2A32; --warn:#6B4400;
  /* --violet et --info sont l'echelle de rang des Optimums de Palworld
     (`.pw-r4`/`.pw-r3` de jeux.css) : ils tenaient le contraste sur une carte
     blanche, pas sur une tuile a moitie transparente posee sur une photo. */
  --violet:#452B85; --info:#17407F;
  /* ⚠ --ok-fond, --accent-fond et --warn-fond ne suivent PAS leur encre :
     ce sont des constantes de style.css, en #RRGGBBAA. Les etiquettes
     `.nc-etq` et les pastilles de la charte posent l'encre sur ce fond-la,
     qui est quasi transparent — donc sur le calque. C'est `.nc-etq.-mesure`
     (« MESURÉ ») qui plafonnait la page Objets a 2,97:1 : l'encre a ete
     assombrie (#0D5836 -> #08432A), pas le fond. */

  /* ⚠ LES SURFACES SONT TEINTEES, PAS BLANCHES — sa demande du 26 aout :
     « le fond quasi blanc pur des tuiles ... ca eclate trop les yeux, on voit
     plus le fond quasiment partout ». Deux causes, pas une :
       · --carte valait #FFFFFF et --fond #F2F5F7, du blanc a peine casse ;
       · et --verre-sat:.45 DESATURAIT la photo sous les surfaces, ce qui la
         rendait grise. C'etait pose pour separer le turquoise de Palworld du
         turquoise de son image ; le prix etait un thema clair sans couleur.
     Les jetons sont donc melanges A L'ACCENT DU JEU. `var(--accent)` se
     resout ici a l'accent recale plus bas, jeu par jeu : une page de jeu porte
     sa propre couleur jusque dans ses surfaces, sans qu'aucune teinte soit
     ecrite sept fois. */
  --carte:     color-mix(in srgb, var(--accent) 20%, #FFFFFF);
  --carte-2:   color-mix(in srgb, var(--accent) 27%, #FBFDFE);
  --fond:      color-mix(in srgb, var(--accent) 22%, #F2F5F7);
  --fond-2:    color-mix(in srgb, var(--accent) 28%, #E9EEF2);
  --creux-pur: color-mix(in srgb, var(--accent) 26%, #EDF2F5);
  --bord:      color-mix(in srgb, var(--accent) 34%, #DDE5EA);
  --bord-fort: color-mix(in srgb, var(--accent) 42%, #C6D2DA);
  /* Le creux n'est plus a zero. Il l'etait pour laisser passer le calque, mais
     c'est LUI le fond des champs de saisie (`.saisie`) et des pastilles : a
     0 % le champ de recherche de l'onglet Objets n'avait plus de boite du
     tout, juste une bordure sur la photo. */
  --verre-creux:70%;

  /* ⚠ LES QUATRE FONDS SEMANTIQUES SONT DES CONSTANTES QUASI TRANSPARENTES.
     `--ok-fond` et compagnie valent #RRGGBBAA avec AA a 0x14-0x18 dans
     style.css : sur une page normale ils posent une teinte sur du blanc, mais
     ICI il n'y a pas de blanc dessous — il y a la photo. Toutes les pastilles
     de la charte et les etiquettes `.nc-etq` posaient donc leur encre de
     couleur A MEME LE CALQUE. C'est ce qui mettait `.pilule.alerte` a 2,98:1,
     `.pilule.critique` a 2,67 et l'entree active du rail (qui prend
     `--accent-fond`) a 3,01 sur HUIT onglets sur neuf.
     Reconstruits sur --carte, ils redeviennent des fonds. */
  /* ⚠ 12 %, ET C'EST UN PLAFOND, PAS UN GOUT. A 15/18 % Core Keeper rendait
     1690 mesures sous 4,5 — toutes a 4,23, un manque uniforme et faible et
     non un trou. La cause : l'encre d'une pastille EST la couleur mêlée dans
     son sol, donc plus le sol est teinte, plus il se rapproche de son propre
     texte. Core Keeper le revele parce que son accent est un brun sombre
     (#7A4A05) la ou les autres ont des accents plus clairs — mais le defaut
     etait la pour les sept. 12 % rend 4,62 ; 9 % rendrait 4,82 et 6 % 4,98,
     au prix de pastilles de plus en plus pales. */
  --ok-fond:     color-mix(in srgb, var(--ok)     12%, var(--carte));
  --warn-fond:   color-mix(in srgb, var(--warn)   12%, var(--carte));
  --crit-fond:   color-mix(in srgb, var(--crit)   12%, var(--carte));
  --accent-fond: color-mix(in srgb, var(--accent) 12%, var(--carte));
  --crit:#8E1F14;
}

/* ⚠ UNE PASTILLE DONT L'ENCRE EST UNE COULEUR DU JEU A BESOIN D'UN FOND
   SOMBRE EN THEME CLAIR. Les raretes de Terraria (Yellow #FFE14F, Cyan, Lime)
   sont posees EN LIGNE par le module, depuis les donnees du jeu : aucun jeton
   ne peut les corriger, et sur le fond clair de `.pilule` elles tombaient a
   1,17:1 — dix pastilles sous 3. On ne les assombrit pas (Yellow deviendrait
   un olive qui ne veut plus rien dire) : on leur donne le fond sombre sur
   lequel elles ont ete concues.
   Le crochet est `[style*="color"]` — c'est ce qui distingue une pastille
   teintee par les donnees d'une pastille de la charte (.ok, .alerte...), qui
   elles doivent garder leur propre fond.
   ⚠ Le crochet vise `color: rgb`, PAS `color` tout court. Mon premier jet
   attrapait aussi les `<span style="color: var(--accent)">` — des glyphes
   d'alerte du Paldeck, qui ne sont pas des couleurs de donnees. Ils se
   retrouvaient avec une puce sombre sous une encre deja tres foncee : 1,73:1,
   un echec que la regle avait CREE. Une couleur de jeu est litterale ; un
   jeton ne l'est pas, et c'est exactement ce qui les separe.
   ⚠ Et il faut viser les `span` AUSSI, pas seulement `.pilule` :
   le meme module rend la meme rarete tantot en pastille, tantot en mot nu.
   Le mot nu sortait a 1,01:1 dans l'onglet Equipement, la ou la pastille
   etait deja corrigee — un correctif qui ne couvre qu'une des deux formes
   donne un onglet propre et un onglet casse. */
/* ⚠ ET CETTE PUCE VAUT POUR LES DEUX THEMES, pas seulement le clair. Je
   n'avais traite que le clair, et le sombre souffrait du meme mal pour la
   meme raison : le fond `#RRGGBB22` n'a rien sous lui la non plus, c'est le
   calque. `el-dragon` y sortait a 2,97:1. La puce etant sombre, elle
   convient aux deux — c'est en clair qu'elle DETONNE le moins, pas
   l'inverse. */
body[data-vue^="jeu-"] .pilule[style*="color: rgb"],
body[data-vue^="jeu-"] span[style*="color: rgb"],
body[data-vue^="jeu-"] .pilule[class*="el-"]{
  background:#141C21; border-radius:100px; padding:1px 7px;
}

/* ⚠ ET LES NEUF PASTILLES D'ELEMENT DU PALDECK SONT LE MEME CAS, par une
   autre porte. Elles ne posent pas leur couleur en ligne mais par classe
   (`.pilule.el-leaf` etc., plus haut dans ce fichier), avec un fond
   `#RRGGBB22` — 13 % d'alpha. Sur une page de jeu il n'y a rien sous ces
   13 % : l'element est peint a meme le calque, et les neuf couleurs
   tombaient entre 1,62 et 1,69:1 en thema clair. Vingt-cinq nœuds sous 3 sur
   le seul onglet Paldeck.
   C'est le defaut que j'avais releve le 25 aout en le classant « defaut de
   charte, pas du calque » et laisse tel quel. Il etait deja la avant le
   calque ; le calque l'a rendu deux fois pire.

   ⚠ ET LA PUCE SOMBRE NE SUFFIT PAS SEULE. Cinq des neuf elements ont une
   encre CLAIRE deja foncee (`el-dark` #7B4FB0, `el-earth` #8A5F28...) : sur
   un fond sombre elles retombent a 2,95:1. Or le thema sombre possede deja,
   pour ces cinq-la exactement, une variante eclaircie. On la reprend ici :
   puce sombre + encre de sombre, c'est cohérent et ca ne cree aucune
   couleur nouvelle. Les quatre autres (#8A93A6, #2A8FE0, #3FA340, #B98B05)
   passent deja au-dessus de 5:1 sur cette puce et ne bougent pas. */
body[data-vue^="jeu-"] .pilule.el-normal { color:#AAB4C6; }
body[data-vue^="jeu-"] .pilule.el-electricity { color:#F2C93B; }
body[data-vue^="jeu-"] .pilule.el-ice { color:#5FD8E8; }
body[data-vue^="jeu-"] .pilule.el-earth { color:#C79A5E; }
body[data-vue^="jeu-"] .pilule.el-dark { color:#A98BE0; }
/* el-dragon n'a pas de variante en sombre — il n'en avait pas besoin la-bas.
   Sur la puce sombre du clair il sortait a 3,64 : on l'eclaircit ici seulement. */
body[data-vue^="jeu-"] .pilule.el-dragon { color:#E87BB8; }
html[data-theme="sombre"] body[data-vue^="jeu-"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue^="jeu-"] .app{
  --voile-h:6%; --voile-b:28%;
  --verre-op:0%; --verre-creux:0%; --verre-rail:0%; --verre-entete:0%;
  --verre-onglets:58%;
  --verre-lumi:.32; --verre-sat:1.5;
  --texte-3:#B4C2CC;
  /* --accent et --ok ne sont pas recales ici : ils sont deja vifs en sombre,
     et c'est le fond qu'on assombrit. Voir la regle du clair ci-dessus.

     ⚠ MAIS LES QUATRE FONDS SEMANTIQUES, SI. Je les avais reconstruits pour
     le clair seulement, et le sombre a exactement le meme mal : `--*-fond`
     vaut `#RRGGBB14` a la racine, soit 8 % d'alpha. Huit pour cent ne sont
     pas un fond quand il y a une PHOTO dessous — et en sombre les cartes
     sont a `--verre-op:0%`, donc il n'y a rien d'autre entre l'encre et
     l'image. Terraria le montrait a 2,66:1 sur `.pilule.info`, parce que son
     image sombre porte des hautes lumieres a 0,83 : assombrir a .32 ne les
     descend qu'a 0,27. Une pastille doit porter son propre sol. */
  --ok-fond:     color-mix(in srgb, var(--ok)     22%, var(--carte));
  --warn-fond:   color-mix(in srgb, var(--warn)   22%, var(--carte));
  --crit-fond:   color-mix(in srgb, var(--crit)   22%, var(--carte));
  --accent-fond: color-mix(in srgb, var(--accent) 22%, var(--carte));
}

/* Les quatre surfaces. A 92 % d'opaque — la valeur de la maison — l'image ne
   passait pas : sur l'onglet Apercu les cartes couvrent tout, et un calque
   qu'aucune carte ne laisse voir n'existe que dans les marges. */
body[data-vue^="jeu-"] .carte,
body[data-vue^="jeu-"] .onglets,
body[data-vue^="jeu-"] .rail,
body[data-vue^="jeu-"] header{
  -webkit-backdrop-filter:saturate(var(--verre-sat)) brightness(var(--verre-lumi));
          backdrop-filter:saturate(var(--verre-sat)) brightness(var(--verre-lumi));
}
body[data-vue^="jeu-"] .carte{
  background:
    linear-gradient(180deg, color-mix(in srgb,var(--accent) 5%,transparent), transparent 46%),
    color-mix(in srgb, var(--carte) var(--verre-op), transparent);
}
body[data-vue^="jeu-"] .onglets{
  background:color-mix(in srgb, var(--fond) 52%, transparent);
  border-radius:var(--r-bouton) var(--r-bouton) 0 0;
}

/* ── LA BARRE D'ONGLETS SUIT LE DEFILEMENT ────────────────────────────────
 *
 * Sans ca il faut remonter toute la page pour changer d'onglet, et certaines
 * listes font plusieurs milliers de lignes.
 *
 * ⚠ `#vues > .onglets` et surtout PAS `.onglets` : la meme classe habille les
 * sous-onglets qui vivent DANS une carte (`.jx-sous-onglets`, voir
 * barreChoix() dans jeux.js). Figer ceux-la collerait une barre au milieu de
 * la page a chaque carte qui en porte une.
 *
 * Le conteneur qui defile est `main`, pas la fenetre : `top:0` colle donc au
 * haut de SA zone visible. La marge negative LATERALE fait deborder la barre
 * sur les 22 px de marge de `main`, sans quoi le contenu defile dans ces deux
 * bandes, a cote de la barre, et on le voit passer.
 *
 * ⚠ Il n'en faut AUCUNE en vertical : tout ce qui precede la barre (la marge
 * haute de `main`, le bandeau du superviseur) a deja defile quand elle se fige.
 * J'en avais mis une, et elle figeait la barre 20 px trop BAS — la contrainte
 * de `sticky` porte sur la boite de MARGE.
 *
 * ⚠ ET `top` N'EST PAS 0, IL EST L'OPPOSE DE LA MARGE HAUTE DE `main`.
 * Chrome mesure l'offset depuis la boite de CONTENU du conteneur qui defile,
 * pas depuis sa boite de remplissage : avec `main{padding:20px 22px 40px}`,
 * `top:0` fige la barre a y=20 et le contenu passe dans la bande au-dessus.
 * Mesure : top:0 -> 20 px · top:-20px -> 0 px · top:-26px -> -6 px. D'ou le
 * -20px ici et le -14px sous 940 px, ou `main` passe a 14 px de marge. Les
 * deux valeurs SUIVENT `main` : la changer sans changer celle-ci laisse
 * reapparaitre la bande, et rien ne le signale.
 *
 * ⚠ ET ICI, IL FAUT UN FLOU — a l'inverse de tout le reste de ce bloc. Ce
 * n'est pas une contradiction : ailleurs le flou coute la constellation du
 * calque et ne rend presque rien, parce que ce qui passe dessous est une image
 * FIXE. Sous cette barre-ci, ce qui passe est le TEXTE DE LA PAGE, en
 * mouvement ; a 52 % il se lit a travers les onglets et la barre parait
 * cassee. Le flou le rend en lavis. Il ne coute que la bande de la barre, pas
 * la page. */

/* ⚠ UN TEXTE HORS CARTE N'A PAS DE SOL. Un seul noeud du site est dans ce
   cas — la note de tri de l'onglet Optimums de Palworld — et il rendait
   1,36:1 en clair : son encre `--texte-3` tombait droit sur une zone bleu
   sombre de la photo, sans la moindre couche entre les deux. Le voile ne le
   rattrape pas (8 % en haut, 26 % en bas), et le RELEVER degrade les cartes,
   ce qui est mesure plus haut.
   Le verre de la barre d'onglets est deja calibre pour porter du texte sur la
   photo dans les deux themes : la note le reprend, plutot que d'inventer une
   quatrieme opacite. `:not(.carte *)` laisse tranquilles les notes deja dans
   une carte, qui ont leur sol.
   ⚠ Ce noeud n'a ete VU qu'une fois le harnais capable de defiler : il est
   au troisieme ecran de son onglet. */
body[data-vue^="jeu-"] .note:not(.carte *){
  background:color-mix(in srgb, var(--fond) var(--verre-onglets), transparent);
  -webkit-backdrop-filter:saturate(var(--verre-sat)) brightness(var(--verre-lumi));
          backdrop-filter:saturate(var(--verre-sat)) brightness(var(--verre-lumi));
  padding:6px 10px; border-radius:var(--r-s);
}

/* ⚠ DEUX FORMES, PARCE QU'IL Y A DEUX HOTES. Le site pose la barre en
   `#vues > .onglets` ; le superviseur, qui sert les MEMES pages, l'enveloppe
   d'une `.vue.actif` et la met donc un cran plus bas. Un seul des deux
   sélecteurs, et la barre ne colle que sur l'un des deux — c'est ce qui s'est
   passé jusqu'au 27 août, sans que rien ne le signale : elle a simplement
   l'air normale, en haut, quand on ne défile pas.
   ⚠ ET SURTOUT PAS UN DESCENDANT (`#vues .onglets`) : l'onglet Optimums de
   Palworld porte une SECONDE barre d'onglets dans une carte, qu'un descendant
   collerait aussi. Deux sélecteurs d'enfant, à profondeur exacte. */
body[data-vue^="jeu-"] #vues > .onglets,
body[data-vue^="jeu-"] #vues > .vue > .onglets{
  position:sticky; top:-20px; z-index:12;
  margin:0 -22px 16px; padding:6px 22px 0;
  border-radius:0;
  background:color-mix(in srgb, var(--fond) var(--verre-onglets), transparent);
  -webkit-backdrop-filter:blur(12px) saturate(var(--verre-sat)) brightness(var(--verre-lumi));
          backdrop-filter:blur(12px) saturate(var(--verre-sat)) brightness(var(--verre-lumi));
}
@media(max-width:940px){
  /* `main` passe a padding:14px : le debord lateral doit suivre, sinon la
     barre laisse une bande de 8 px de chaque cote ou le contenu defile. */
  /* Et ils passent a la ligne. Sans ca, `display:flex` sans repli poussait les
     derniers onglets HORS de l'ecran, sans defilement ni indice : sur une
     fenetre de 800 px, « Effets », « Mods » et « Serveur » etaient simplement
     inatteignables. Meme parti que `.jx-sous-onglets`, qui replie deja. */
  body[data-vue^="jeu-"] #vues > .onglets,
  body[data-vue^="jeu-"] #vues > .vue > .onglets{
    top:-14px; margin:0 -14px 16px; padding:6px 14px 0; flex-wrap:wrap;
  }
}
body[data-vue^="jeu-"] .rail{
  background:
    linear-gradient(180deg, var(--halo), transparent 34%),
    color-mix(in srgb, var(--fond-2) var(--verre-rail), transparent);
}
body[data-vue^="jeu-"] header{
  background:color-mix(in srgb, var(--carte) var(--verre-entete), transparent);
}

/* Les jeux qui ont leurs images, au 25 aout 2026 : Palworld, ARK et
   Valheim. Chacun
   pose trois choses et pas une de plus —
     · ses deux --calque, un par theme ;
     · --motif-opacite, parce que la trame de points n'a plus a texturer un
       fond qui porte deja son grain (ca n'a de sens que s'il Y A une image) ;
     · son --accent de verre en CLAIR, l'accent du jeu assombri de facon a
       tenir sur sa propre photo. Mesure sous chaque noeud de texte : sans lui
       le titre a l'accent tombe a 1,75:1 chez Palworld, parce que l'accent du
       jeu EST une couleur de son image.
   En sombre l'accent ne bouge pas : il y est deja vif et c'est le fond qu'on
   assombrit. */
body[data-vue="jeu-palworld"] .app{
  --calque:url("/donnees/fond-palworld-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-palworld"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-palworld"] .app{
  --calque:url("/donnees/fond-palworld-sombre.jpg");
}
html[data-theme="clair"] body[data-vue="jeu-palworld"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-palworld"] .app{
  --accent:#063A40;                                  /* turquoise assombri */
  --verre-op:66%;
  /* ⚠ 66 % ET PAS 82 %, ET C'EST MESURE. A 58 % l'accent tombait a 3,24:1
     sur les cartes : ce n'est pas la teinte qui echouait, c'est la PHOTO qui
     passait au travers (fond compose a [139,150,144]). Trois leviers ont ete
     balayes, deux vont dans le mauvais sens :
       · voiler plus     26/42 % -> 103 echecs, 40/55 % -> 175. Le voile mele
         `--fond`, qui est plus sombre que les hautes lumieres de la photo :
         il ASSOMBRIT le fond au lieu de l'eclaircir.
       · teindre plus    accent a 32 % dans --carte -> 342 echecs, a 44 % ->
         588. Une tuile plus coloree est plus sombre, donc plus proche d'une
         encre sombre. C'est la tension de fond du theme clair : il veut de la
         couleur, l'encre veut du clair.
       · assombrir l'encre  plafonne a 3,69:1 des #063A40 — au-dela une AUTRE
         encre borne, et on assombrit pour rien.
     82 % d'opacite seule donnait aussi 0, mais en effacant l'image — ce qui
     est precisement la seconde plainte. 66 % + encre a peine assombrie :
     0 sous 4,5, et la photo reste lisible entre et sous les cartes. */
}

body[data-vue="jeu-ark"] .app{
  --calque:url("/donnees/fond-ark-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-ark"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-ark"] .app{
  --calque:url("/donnees/fond-ark-sombre.jpg");
  /* L'image d'ARK est quasi noire : luminance moyenne 0,016 contre 0,10 chez
     Palworld. Le brightness(.32) partage l'ecrase en un aplat noir — les deux
     obelisques et les silhouettes de dinosaures disparaissent. Releve a .42,
     ou le pire noeud (.nc-note, un paragraphe pleine largeur qui traverse le
     halo ambre) descend a 4,01:1 ; l'encre tertiaire eclaircie le ramene a
     4,55 et la page repasse entierement au-dessus de 4,5. Balayage :
     .32 -> 5,54 · .36 -> 4,87 · .42 -> 4,55 · .48 -> 3,31 · .60 -> 2,31. */
  --verre-lumi:.42;
  --texte-3:#C2CED6;
}
html[data-theme="clair"] body[data-vue="jeu-ark"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-ark"] .app{
  --accent:#7A3806;                                  /* ambre assombri */
}

body[data-vue="jeu-valheim"] .app{
  --calque:url("/donnees/fond-valheim-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-valheim"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-valheim"] .app{
  --calque:url("/donnees/fond-valheim-sombre.jpg");
  /* Il l'a demande explicitement : ON DOIT VOIR L'AURORE BOREALE. Elle occupe
     la bande haute de l'image, qui ne pese que 0,052 de luminance — sous le
     brightness(.32) partage elle tombe a ~0,003, soit rien. Le releve dit
     qu'ici on peut monter tres haut : l'image est sombre PARTOUT (0,020 de
     moyenne) et sans point chaud, contrairement a ARK dont le halo ambre
     limitait a .42. Mesure sur les DIX onglets a brightness(.90) : 32 a 253
     noeuds chacun, pire 4,51:1, aucun sous 4,5 — et pareil a 1073 px de large,
     ou le recadrage `cover` ramene la lune vers l'en-tete.

     ⚠ CE BALAYAGE ETAIT FAUX, et .85 est parti en production avec. Le harnais
     s'arretait sur `body`, opaque, et n'echantillonnait donc JAMAIS le calque
     peint sur `.app` : il mesurait la page SANS image. Corrige le 26 aout, le
     meme balayage donne .85 -> 4,32 (1 noeud sous 4,5) · .72 -> 4,99 (aucun) ·
     .62 -> 5,56. On prend .72, et l'aurore reste franche.

     ⚠ ET IL ETAIT ENCORE FAUX, une seconde fois : le harnais ne DEFILAIT pas
     (`scroll-behavior:smooth` ne demarre jamais dans un onglet pilote), donc
     il notait le premier ecran de chaque onglet et rien d'autre. Une fois
     capable de descendre, il a trouve l'onglet Mods a 2,35:1. La cause tient
     au fait que le calque est FIXE alors que la liste defile : une ligne
     lisible au milieu de l'ecran repasse, trois tours de molette plus haut,
     sur la bande claire de l'aurore. Un contraste qui depend de la position
     de defilement ne se voit qu'en defilant.
     On corrige par le voile des cartes, PAS par la luminosite : baisser a .42
     rendait zero aussi, en eteignant justement l'aurore qu'il a demande a
     voir. `--verre-op` ne pose de matiere que SOUS le texte — entre les
     cartes, l'aurore garde ses .72 intacts. */
  --verre-lumi:.72;
  --verre-op:72%;   /* 62 % rendait 0 sur une passe et 3 sur la suivante : la
                       liste des mods ne se recompose pas a l'identique, donc
                       le pire pixel change d'un releve a l'autre. Une valeur
                       qui passe JUSTE ne passe pas. */
}
html[data-theme="clair"] body[data-vue="jeu-valheim"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-valheim"] .app{
  --accent:#184C73;                                  /* bleu assombri */
  /* Son image CLAIRE ne pese que 0,139 de luminance moyenne — c'est une foret
     sombre, plus sombre que le fond clair de la charte. A 58/62 elle sortait a
     2,33:1 au pire, 16 noeuds sous 4,5. Le verre est donc plus dense ICI, chez
     les deux jeux dont l'image claire est sombre, et pas chez tout le monde :
     Palworld et ARK tiennent a 58/62 et garderaient leur image moins visible
     pour rien. Resultat : 4,62:1, aucun noeud sous 4,5. */
  --verre-op:70%; --verre-rail:86%; --verre-entete:86%;
}

body[data-vue="jeu-terraria"] .app{
  --calque:url("/donnees/fond-terraria-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-terraria"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-terraria"] .app{
  --calque:url("/donnees/fond-terraria-sombre.jpg");
  /* Image tres sombre (0,023 de moyenne) MAIS avec des points chauds a 0,83 —
     lanternes et oeil de Cthulhu. C'est le cas d'ARK, pas celui de Valheim :
     le plafond vient du point chaud, pas de la moyenne. Balayage :
     .42 -> 4,92 · .46 -> 4,68 · .50 -> 4,44 (1 sous 4,5) · .62 -> 3,72 (5). */
  --verre-lumi:.46;
}
html[data-theme="sombre"] body[data-vue="jeu-terraria"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-terraria"] .app{
  /* ⚠ Terraria est le SEUL jeu dont l'image sombre a besoin d'un voile de
     carte. Sa luminance moyenne est basse (0,023) mais elle porte des hautes
     lumieres a 0,83 : la moyenne ne dit rien du pire pixel, et c'est le pire
     pixel que lit un oeil. Assombrir a .32 n'y descend qu'a 0,27, et le texte
     des mods y tombait a 2,66:1.
     Deux reglages rendent 0 sous 4,5 ; celui-ci n'est pas le plus simple mais
     c'est le bon : `--verre-lumi:.28` seul marche aussi, en eteignant l'image
     PARTOUT. A .34 avec 14 % de voile sur les cartes, l'image garde sa
     luminosite dans les espaces libres — la ou on la regarde — et ne
     s'assombrit que sous le texte. */
  --verre-lumi:.34;
  --verre-op:40%;   /* 14 % au premier jet — voir la note de Valheim sombre :
                       le harnais ne defilait pas encore, et un calque FIXE
                       sous une liste qui defile ne se juge pas sur un ecran.
                       En descendant, 5 mesures restaient a 4,00. */
}
html[data-theme="clair"] body[data-vue="jeu-terraria"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-terraria"] .app{
  /* Meme traitement que Valheim, et pour la meme raison : son image claire est
     la plus sombre recue (0,102). A 58/62 : 2,02:1 au pire, 17 noeuds sous 4,5
     dont 7 sous 3. Essayé AVANT d'en arriver la, et ecarté : relever la courbe
     tonale de l'image (gamma 0,34 la porte de 0,102 a 0,335) ne rendait que
     3,21:1 — le defaut n'etait pas dans l'image mais dans DEUX encres, qui
     portaient 7 des 8 echecs. Recalees plus haut, elles font le gros du
     chemin ; le verre plus dense fait le reste. */
  --accent:#6B1B8D;                                  /* violet assombri */
  --verre-op:70%; --verre-rail:86%; --verre-entete:86%;
}

/* Core Keeper et Minecraft n'ont PAS d'image, et ont quand meme besoin du
   recalage. La cause n'est pas la photo mais le verre lui-meme : une carte a
   58 % au lieu de 92 %, sur un fond eclairci a 1.35, ne porte plus les accents
   moyens de la charte. Mesure page entiere en clair, avant / apres :
     · Core Keeper  33 noeuds sous 4,5 -> 0   (pire 3,17 -> 4,81)
     · Minecraft     7 noeuds sous 4,5 -> 1   (le reste est .warn, pas l'accent)
   Les 33 de Core Keeper portaient TOUTES la meme encre, #A16207 : un seul
   jeton les a corrigees d'un coup. C'est ce qui distingue un defaut d'encre
   d'un defaut de fond — un defaut de fond frappe des couleurs melangees.
   Terraria (#7B1FA2) et Necesse (#3730A3) passent deja et ne sont PAS
   recales : leur pire noeud est la pastille semantique, qui ne depend pas de
   l'accent. On ne recale que ce que la mesure condamne. */
/* Core Keeper recoit son calque le 26 aout. Les valeurs ci-dessous sont
   posees d'apres les deux images (sombre 0,035 de moyenne mais un point chaud
   a 0,839 — la lueur du foyer au centre ; claire 0,104, soit aussi sombre que
   celle de Terraria) et VERIFIEES par le harnais juste apres. */
body[data-vue="jeu-core-keeper"] .app{
  --calque:url("/donnees/fond-core-keeper-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-core-keeper"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-core-keeper"] .app{
  --calque:url("/donnees/fond-core-keeper-sombre.jpg");
  /* Le foyer au centre de la grotte monte a 0,839 malgre une moyenne de
     0,035 : meme cas que Terraria, et meme remede — un voile de carte, pas
     une baisse de luminosite qui eteindrait les champignons luminescents.
     30 % rend deja 0 sous 4,5 (4,79) ; on prend cette valeur, la plus basse
     qui passe, pour garder l'image franche entre les cartes. */
  --verre-op:30%;
}
html[data-theme="clair"] body[data-vue="jeu-core-keeper"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-core-keeper"] .app{
  /* ⚠ #7A4A05 etait cale AVANT que ce jeu ait une image, sur le verre nu.
     Avec le calque il rendait 76 noeuds sous 4,5 — TOUS sur cette encre, et
     le verre n'y pouvait rien : de 70 a 78 % d'opacite et de 1,15 a 1,55 de
     luminosite, le compte restait bloque a 76. Un palier que le fond ne fait
     pas bouger est un defaut d'encre, pas un defaut de fond. */
  --accent:#4E2F03;                                  /* ambre assombri */
  --verre-op:74%; --verre-rail:86%; --verre-entete:86%;
}
/* Minecraft, le dernier des sept, le 26 aout. Son image claire est de LOIN
   la plus claire recue (0,241 de moyenne, p95 a 0,669) et la sombre porte un
   point chaud a 0,874 — le clair de lune sur la fleche du chateau. Les deux
   extremes de la serie dans une seule paire. */
body[data-vue="jeu-minecraft"] .app{
  --calque:url("/donnees/fond-minecraft-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-minecraft"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-minecraft"] .app{
  --calque:url("/donnees/fond-minecraft-sombre.jpg");
  /* Le clair de lune sur la fleche du chateau monte a 0,874 : meme cas que
     Core Keeper et Terraria, meme remede — un voile de carte a 30 %, la plus
     basse valeur qui rende 0 sous 4,5 (3,72 -> 4,66). */
  --verre-op:30%;
}
html[data-theme="clair"] body[data-vue="jeu-minecraft"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-minecraft"] .app{
  /* ⚠ #2C5C1F etait cale sur le verre nu, comme ceux de Core Keeper et
     Necesse — et comme eux il ne tient plus des que le jeu a une image. Ici
     les 19 fautes se concentraient sur l'onglet ACTIF de la barre collante,
     et le verre n'y pouvait rien : 70 comme 78 % d'opacite, et meme une barre
     entierement opaque, laissaient le compte a 19. Encore un palier que le
     fond ne fait pas bouger, donc encore un defaut d'encre. */
  --accent:#1F4415;                                  /* vert assombri */
  --verre-op:74%;
}

/* Necesse recoit son calque le 26 aout. Ses deux images sont la MEME vue en
   pixel-art de jour et de nuit — donc, contrairement aux autres jeux, elles
   partagent leur composition : ce qui marche sur l'une se transpose sur
   l'autre, et seuls les niveaux changent (0,037 en sombre, 0,174 en clair,
   la plus CLAIRE des sept images de theme clair). */
body[data-vue="jeu-necesse"] .app{
  --calque:url("/donnees/fond-necesse-clair.jpg");
  --motif-opacite:.08;
}
html[data-theme="sombre"] body[data-vue="jeu-necesse"] .app,
html:not([data-theme="clair"]) body.auto-sombre[data-vue="jeu-necesse"] .app{
  --calque:url("/donnees/fond-necesse-sombre.jpg");
  /* Rien d'autre : la nuit en pixel-art n'a aucun point chaud (0,424 au
     maximum, contre 0,839 chez Core Keeper et Terraria), donc le voile
     partage suffit. Mesure : 0 sous 4,5 des le premier essai. */
}
html[data-theme="clair"] body[data-vue="jeu-necesse"] .app,
html:not([data-theme="sombre"]) body:not(.auto-sombre)[data-vue="jeu-necesse"] .app{
  /* ⚠ #3730A3 etait explicitement declare « passe deja, PAS recale » dans la
     note du bloc partage — c'etait vrai sur le verre nu, et faux des que le
     jeu a eu une image : 134 noeuds sous 4,5, dont le pire a 2,65.
     ⚠ Et assombrir l'encre SEULE aggrave le compte : #2B2582 le fait passer
     de 134 a 164, #221D68 a 186. Le pire remonte (2,65 -> 3,23) mais il y a
     PLUS de fautifs, parce qu'une encre plus foncee entraine avec elle les
     surfaces derivees de l'accent. Il faut les deux leviers ensemble, et
     c'est l'opacite qui fait le gros du travail. */
  --accent:#2B2582;                                  /* indigo assombri */
  --verre-op:74%;
}

/* ═══ jumeaux [data-jeu] — DÉRIVÉS, ne pas éditer à la main ═══
 *
 * Écrits par site-jeux/design-system/derives-data-jeu.py depuis les blocs
 * `body[data-vue="jeu-x"]` ci-dessus. Un <div> ne peut pas être un <body> :
 * ces jumeaux permettent de teinter un fragment — une tuile de la console
 * d'administration, un aperçu du design system — avec l'identité de son jeu.
 * ═══════════════════════════════════════════════════════════════════════ */
[data-jeu="ark"] { --accent:#B45309; --accent-2:#15803D; --motif:repeating-linear-gradient(174deg,
      color-mix(in srgb,var(--accent) 15%,transparent) 0 2px,
      transparent 2px 9px,
      color-mix(in srgb,var(--accent-2) 10%,transparent) 9px 10px,
      transparent 10px 26px); --motif-opacite:.4; --motif-taille:auto; }
[data-jeu="core-keeper"] { --accent:#A16207; --accent-2:#5B21B6; --motif:radial-gradient(circle at 20% 30%, color-mix(in srgb,var(--accent) 42%,transparent) 0 1.8px, transparent 2.4px),
    radial-gradient(circle at 70% 80%, color-mix(in srgb,var(--accent-2) 36%,transparent) 0 1.4px, transparent 2px),
    radial-gradient(circle at 46% 8%,  color-mix(in srgb,var(--accent) 24%,transparent) 0 1.1px, transparent 1.6px); --motif-opacite:.5; --motif-taille:58px 58px, 74px 74px, 39px 39px; }
[data-jeu="minecraft"] { --accent:#3B7A2A; --accent-2:#7A5230; --motif:repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent-2) 11%,transparent) 0 1px, transparent 1px 16px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent-2) 11%,transparent) 0 1px, transparent 1px 16px),
    conic-gradient(from 90deg at 50% 50%,
      color-mix(in srgb,var(--accent) 13%,transparent) 0 25%, transparent 0 50%,
      color-mix(in srgb,var(--accent) 13%,transparent) 0 75%, transparent 0); --motif-opacite:.46; --motif-taille:auto, auto, 64px 64px; }
[data-jeu="necesse"] { --accent:#3730A3; --accent-2:#A16207; --motif:repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 13%,transparent) 0 1px, transparent 1px 27px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent-2) 9%,transparent) 0 1px, transparent 1px 27px); --motif-opacite:.3; --motif-taille:auto; }
[data-jeu="palworld"] { --accent:#0E7C86; --accent-2:#D97706; --motif:radial-gradient(circle at 50% 50%, color-mix(in srgb,var(--accent-2) 34%,transparent) 0 1.6px, transparent 2px),
    radial-gradient(circle at 50% 50%, transparent 7px, color-mix(in srgb,var(--accent) 26%,transparent) 7px 8.2px, transparent 9px); --motif-opacite:.34; --motif-taille:44px 44px, 44px 44px; }
[data-jeu="terraria"] { --accent:#7B1FA2; --accent-2:#2E7D32; --motif:repeating-linear-gradient(0deg,  color-mix(in srgb,var(--accent) 11%,transparent) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, color-mix(in srgb,var(--accent) 11%,transparent) 0 1px, transparent 1px 4px),
    radial-gradient(circle at 30% 70%, color-mix(in srgb,var(--accent-2) 28%,transparent) 0 1.4px, transparent 2px); --motif-opacite:.36; --motif-taille:auto, auto, 24px 24px; }
[data-jeu="valheim"] { --accent:#1E5F8C; --accent-2:#8A5A2B; --motif:repeating-linear-gradient(45deg,  color-mix(in srgb,var(--accent) 14%,transparent) 0 1.2px, transparent 1.2px 18px),
    repeating-linear-gradient(-45deg, color-mix(in srgb,var(--accent-2) 12%,transparent) 0 1.2px, transparent 1.2px 18px); --motif-opacite:.44; --motif-taille:auto; }

html[data-theme="sombre"] [data-jeu="ark"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="ark"]
  { --accent:#FFA94D; --accent-2:#6EE7A8; }
html[data-theme="sombre"] [data-jeu="core-keeper"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="core-keeper"]
  { --accent:#FBBF24; --accent-2:#A78BFA; }
html[data-theme="sombre"] [data-jeu="minecraft"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="minecraft"]
  { --accent:#7BC96F; --accent-2:#C9915C; }
html[data-theme="sombre"] [data-jeu="necesse"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="necesse"]
  { --accent:#8B93FF; --accent-2:#F4C15D; }
html[data-theme="sombre"] [data-jeu="palworld"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="palworld"]
  { --accent:#3AD8E6; --accent-2:#FFB347; }
html[data-theme="sombre"] [data-jeu="terraria"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="terraria"]
  { --accent:#C77DFF; --accent-2:#6FD86F; }
html[data-theme="sombre"] [data-jeu="valheim"],
html:not([data-theme="clair"]) body.auto-sombre [data-jeu="valheim"]
  { --accent:#5FB2E8; --accent-2:#D9A15B; }
